Implement Step-Over functionality
This change adds a new "Step Over" button, which is enabled
when a "JSR" (Jump to Subroutine) instruction is encountered
while stepping through execution one instruction at a time.
Pressing "Step Over" will continue running instructions until a
corresponding "RTS" (Return from Subroutine) is encountered.
While stepping over a subroutine, the call stack depth is tracked
in an attempt to halt only when the *correct* RTS is encountered.
In other words, it should skip over other subroutines nested
inside the call you want to step over:
```
JSR A # Step over here...
...
JSR B
...
RTS # Returns from 'B', doesn't halt
...
RTS # Returns from 'A', halts after return
```
Implements feature request #18.
This commit is contained in:
1 parent
2284535b7f
commit
7268766cd6
39 files changed
+164
-58
No files matched your search
@@ -377,7 +377,7 @@ running.
|
||||
|
||||
## 8.0 Copyright and Acknowledgements
|
||||
|
||||
**Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>**
|
||||
**Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>**
|
||||
|
||||
- Portions Copyright (c) 2014 Maik Merten
|
||||
<maikmerten@googlemail.com>
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.loomcom.symon;
|
||||
|
||||
import com.loomcom.symon.exceptions.MemoryAccessException;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -1699,6 +1699,10 @@ public class Cpu implements InstructionTable {
|
||||
return state.ir;
|
||||
}
|
||||
|
||||
public int getNextIr() {
|
||||
return state.nextIr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @value The value of the Process Status Register bits to be set.
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.loomcom.symon;
|
||||
|
||||
import com.loomcom.symon.util.Utils;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -25,6 +25,10 @@ package com.loomcom.symon;
|
||||
|
||||
public interface InstructionTable {
|
||||
|
||||
int BRK = 0x00;
|
||||
int JSR = 0x20;
|
||||
int RTS = 0x60;
|
||||
|
||||
/**
|
||||
* Enumeration of valid CPU behaviors. These determine what behavior and instruction
|
||||
* set will be simulated, depending on desired version of 6502.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -22,7 +22,6 @@
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package com.loomcom.symon;
|
||||
|
||||
import com.loomcom.symon.machines.*;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyrighi (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -37,6 +37,8 @@ import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
|
||||
import static com.loomcom.symon.InstructionTable.*;
|
||||
|
||||
/**
|
||||
* Symon Simulator Interface and Control.
|
||||
* <p/>
|
||||
@@ -112,6 +114,7 @@ public class Simulator {
|
||||
|
||||
private JButton runStopButton;
|
||||
private JButton stepButton;
|
||||
private JButton stepOverButton;
|
||||
private JComboBox<String> stepCountBox;
|
||||
|
||||
private JFileChooser fileChooser;
|
||||
@@ -188,6 +191,8 @@ public class Simulator {
|
||||
|
||||
runStopButton = new JButton("Run");
|
||||
stepButton = new JButton("Step");
|
||||
stepOverButton = new JButton("Step Over");
|
||||
stepOverButton.setEnabled(false);
|
||||
JButton softResetButton = new JButton("Soft Reset");
|
||||
JButton hardResetButton = new JButton("Hard Reset");
|
||||
|
||||
@@ -209,6 +214,7 @@ public class Simulator {
|
||||
|
||||
buttonContainer.add(runStopButton);
|
||||
buttonContainer.add(stepButton);
|
||||
buttonContainer.add(stepOverButton);
|
||||
buttonContainer.add(stepCountBox);
|
||||
buttonContainer.add(softResetButton);
|
||||
buttonContainer.add(hardResetButton);
|
||||
@@ -232,6 +238,7 @@ public class Simulator {
|
||||
});
|
||||
|
||||
stepButton.addActionListener(actionEvent -> Simulator.this.handleStep(stepsPerClick));
|
||||
stepOverButton.addActionListener(actionEvent -> Simulator.this.handleStepOver());
|
||||
|
||||
softResetButton.addActionListener(actionEvent -> {
|
||||
// If this was a CTRL-click, do a hard reset.
|
||||
@@ -325,11 +332,28 @@ public class Simulator {
|
||||
step();
|
||||
}
|
||||
updateVisibleState();
|
||||
stepOverButton.setEnabled(machine.getCpu().getNextIr() == JSR);
|
||||
} catch (SymonException ex) {
|
||||
logger.error("Exception during simulator step", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Step over a JSR / RTS function. This function is much more like a "run()"
|
||||
* than a "step()", and may enter an infinite loop if no RTS is encountered.
|
||||
*/
|
||||
private void handleStepOver() {
|
||||
if (runLoop != null && runLoop.isRunning()) {
|
||||
// This should really never happen...
|
||||
logger.error("Can't step over when the simulator is already running!");
|
||||
return;
|
||||
}
|
||||
|
||||
runLoop = new RunLoop();
|
||||
runLoop.haltOnRts(true);
|
||||
runLoop.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a single step of the simulated system.
|
||||
*/
|
||||
@@ -398,22 +422,36 @@ public class Simulator {
|
||||
*/
|
||||
class RunLoop extends Thread {
|
||||
private boolean isRunning = false;
|
||||
private boolean haltOnRts = false;
|
||||
// The number of JSR instructions we've seen since being asked to
|
||||
// step over a subroutine. While stepping over, this is incremented
|
||||
// on RTS instructions, and decremented on JSR instructions.
|
||||
private int callStackDepth = 0;
|
||||
|
||||
public boolean isRunning() {
|
||||
return isRunning;
|
||||
return this.isRunning;
|
||||
}
|
||||
|
||||
public void requestStop() {
|
||||
isRunning = false;
|
||||
this.isRunning = false;
|
||||
}
|
||||
|
||||
public void haltOnRts(boolean value) {
|
||||
this.haltOnRts = value;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
logger.debug("Starting main run loop.");
|
||||
isRunning = true;
|
||||
if (this.haltOnRts) {
|
||||
logger.debug("Running until next RTS instruction");
|
||||
} else {
|
||||
logger.debug("Running");
|
||||
}
|
||||
this.isRunning = true;
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// Don't allow step while the simulator is running
|
||||
stepButton.setEnabled(false);
|
||||
stepOverButton.setEnabled(false);
|
||||
stepCountBox.setEnabled(false);
|
||||
menuBar.simulatorDidStart();
|
||||
// Toggle the state of the run button
|
||||
@@ -423,6 +461,17 @@ public class Simulator {
|
||||
try {
|
||||
do {
|
||||
step();
|
||||
if (this.haltOnRts) {
|
||||
var instruction = machine.getCpu().getInstruction();
|
||||
if (instruction == JSR) {
|
||||
this.callStackDepth++;
|
||||
logger.trace("Step-over call stack increased to {}", this.callStackDepth);
|
||||
} else if (this.callStackDepth > 0 && instruction == RTS) {
|
||||
this.callStackDepth--;
|
||||
logger.trace("Step-over call stack decreased to {}", this.callStackDepth);
|
||||
}
|
||||
}
|
||||
|
||||
} while (shouldContinue());
|
||||
} catch (SymonException ex) {
|
||||
logger.error("Exception in main simulator run thread. Exiting run.", ex);
|
||||
@@ -433,6 +482,7 @@ public class Simulator {
|
||||
memoryWindow.updateState();
|
||||
runStopButton.setText("Run");
|
||||
stepButton.setEnabled(true);
|
||||
stepOverButton.setEnabled(machine.getCpu().getNextIr() == JSR);
|
||||
stepCountBox.setEnabled(true);
|
||||
if (traceLog.isVisible()) {
|
||||
traceLog.refresh();
|
||||
@@ -448,9 +498,13 @@ public class Simulator {
|
||||
* @return True if the run loop should proceed to the next step.
|
||||
*/
|
||||
private boolean shouldContinue() {
|
||||
return !breakpoints.contains(machine.getCpu().getProgramCounter()) &&
|
||||
isRunning &&
|
||||
!(preferences.getHaltOnBreak() && machine.getCpu().getInstruction() == 0x00);
|
||||
var instruction = machine.getCpu().getInstruction();
|
||||
|
||||
var stepOverHalt = this.haltOnRts && this.callStackDepth == 0 && instruction == RTS;
|
||||
var breakpointHalt = breakpoints.contains(machine.getCpu().getProgramCounter());
|
||||
var brkHalt = preferences.getHaltOnBreak() && instruction == BRK;
|
||||
|
||||
return isRunning && !(stepOverHalt || breakpointHalt || brkHalt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,7 +978,6 @@ public class Simulator {
|
||||
private void updateVisibleState() {
|
||||
// Immediately update the UI.
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// Now update the state
|
||||
statusPane.updateState();
|
||||
memoryWindow.updateState();
|
||||
if (traceLog.shouldUpdate()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Portions Copyright (c) 2009-2011 Graham Edgecombe
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Chelsea Wilkinson <mail@chelseawilkinson.me>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Chelsea Wilkinson <mail@chelseawilkinson.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -42,9 +42,9 @@ public interface Machine {
|
||||
Memory getRam();
|
||||
|
||||
Acia getAcia();
|
||||
|
||||
|
||||
Pia getPia();
|
||||
|
||||
|
||||
Crtc getCrtc();
|
||||
|
||||
Memory getRom();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
* Maik Merten <maikmerten@googlemail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||
* Copyright (c) 2008-2025 Seth J. Morabito <web@loomcom.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
||||
Reference in new issue
Block a user