Make tapectl use arguments for input, make the emulator order-agnostic with its arguments, and include running instructions for the included software in the readme

This commit is contained in:
CrazyEttin 2022-09-16 15:04:05 +03:00
parent f0e676facb
commit 5fd7fa707f
3 changed files with 63 additions and 36 deletions

View File

@ -31,7 +31,7 @@ const
{$endif} {$endif}
var var
Hlt, Verbose, Echo: boolean; //Halt, verbose, and echo flags Hlt, Echo: boolean; //Halt and echo flags
Op, Regs: 0 .. $f; //Opcode Op, Regs: 0 .. $f; //Opcode
X, Y: 0 .. 3; //Register arguments X, Y: 0 .. 3; //Register arguments
Addr, IP, RP: word; //Immediate or address argument and instruction and return pointers Addr, IP, RP: word; //Immediate or address argument and instruction and return pointers
@ -43,7 +43,7 @@ var
State: file of Tape; //File storing the states of the tape reader and punch State: file of Tape; //File storing the states of the tape reader and punch
{$endif} {$endif}
Ch, Scan: ansichar; //Character for input and output and scancode for non-ASCII keys Ch, Scan: ansichar; //Character for input and output and scancode for non-ASCII keys
IC, LFX: integer; //Instruction counter for CPU speed Verbose, IC, LFX: integer; //Verbose flag, instruction counter for CPU speed, and line feed position marker
Fetched: byte; //Fetched byte Fetched: byte; //Fetched byte
//Terminal output //Terminal output
@ -288,14 +288,21 @@ begin
halt (1); halt (1);
end; end;
if ParamStr (1) = '-v' then begin if ParamStr (1) = '-v' then begin
Verbose := true; Verbose := 1;
if ParamCount <> 2 then begin
writeln ('Usage: emulator (-v) program (2> verbose_output)');
halt (1);
end;
end
else if ParamStr (2) = '-v' then begin
Verbose := 2;
if ParamCount <> 2 then begin if ParamCount <> 2 then begin
writeln ('Usage: emulator (-v) program (2> verbose_output)'); writeln ('Usage: emulator (-v) program (2> verbose_output)');
halt (1); halt (1);
end; end;
end end
else begin else begin
Verbose := false; Verbose := 0;
if ParamCount <> 1 then begin if ParamCount <> 1 then begin
writeln ('Usage: emulator (-v) program (2> verbose_output)'); writeln ('Usage: emulator (-v) program (2> verbose_output)');
halt (1); halt (1);
@ -304,7 +311,7 @@ begin
//Read a program file and check for errors //Read a program file and check for errors
{$i-} {$i-}
if Verbose = true then assign (Prog, ParamStr (2)) if Verbose = 1 then assign (Prog, ParamStr (2))
else assign (Prog, ParamStr (1)); else assign (Prog, ParamStr (1));
reset (Prog); reset (Prog);
if FileSize (Prog) > LastRAM + 1 then begin if FileSize (Prog) > LastRAM + 1 then begin
@ -329,7 +336,7 @@ begin
while Hlt = false do begin while Hlt = false do begin
//Print the CPU state to StdErr //Print the CPU state to StdErr
if Verbose = true then writeln (StdErr, 'IR: ', IntToHex (Op, 1), IntToHex (Regs, 1), IntToHex (Addr, 4), '; IP: ', IntToHex (IP, 4), ', RP: ', IntToHex (RP, 4), '; R0: ', IntToHex (R[0], 2), ', R1: ', IntToHex (R[1], 2), ', R2: ', IntToHex (R[2], 2), ', R3: ', IntToHex (R[3], 2), ansichar ($d)); if Verbose <> 0 then writeln (StdErr, 'IR: ', IntToHex (Op, 1), IntToHex (Regs, 1), IntToHex (Addr, 4), '; IP: ', IntToHex (IP, 4), ', RP: ', IntToHex (RP, 4), '; R0: ', IntToHex (R[0], 2), ', R1: ', IntToHex (R[1], 2), ', R2: ', IntToHex (R[2], 2), ', R3: ', IntToHex (R[3], 2), ansichar ($d));
//Fetch the instruction and increment the instruction pointer //Fetch the instruction and increment the instruction pointer
//Fetch the opcode and register arguments //Fetch the opcode and register arguments

View File

@ -92,15 +92,20 @@ implementation has a front panel the IPL is optional. The instruction
and return pointers are initialised as 0 and the first address after RAM and return pointers are initialised as 0 and the first address after RAM
respectively, while other registers and RAM are uninitialised. respectively, while other registers and RAM are uninitialised.
Emulator Emulator and Tapectl
-------- --------------------
Usage:
* emulator (-v) program (2> verbose_output)
* tapectl (-r reader_file) (-p punch_file)
By default the emulator runs at roughly 500 KIPS, has 2 KiB of RAM, and By default the emulator runs at roughly 500 KIPS, has 2 KiB of RAM, and
interacts with memory mapped devices at roughly 1000 B/s. The arguments interacts with memory mapped devices at roughly 1 kB/s. The arguments
-dRAM4, -dRAM8, -dRAM16, -dRAM32, and -dRAM64 can be used to compile -dRAM4, -dRAM8, -dRAM16, -dRAM32, and -dRAM64 can be used to compile
the emulator with 4, 8, 16, 32, or 64 KiB (minus the reserved addresses) the emulator with 4, 8, 16, 32, or 64 KiB (minus the reserved addresses)
of RAM respectively instead and the speed limitations can be removed of RAM respectively instead and the speed limitations can be removed
with the argument -dfast. with the argument -dfast. When run with the argument -v the current
state of the registers is output to stderr before each instruction.
Input and output are handled by an emulated glass teletype terminal with Input and output are handled by an emulated glass teletype terminal with
local echo on by default. Of the control characters bell (^G), local echo on by default. Of the control characters bell (^G),
@ -116,8 +121,23 @@ printer and an emulated punched tape reader and punch with the arguments
-dprinter and -dtape respectively. The printer is mapped to address FFFE -dprinter and -dtape respectively. The printer is mapped to address FFFE
and the tape reader and punch to FFFD. The printer prints into and the tape reader and punch to FFFD. The printer prints into
/dev/usb/lp0 and the tape files read from and punched to are (re)set /dev/usb/lp0 and the tape files read from and punched to are (re)set
using the program tapectl. using the program tapectl with the arguments -r and -p respectively.
The IPL loads a program from a file specified when launching the The IPL loads the program specified as an argument when running the
emulator. emulator.
Assembler and Disassembler
--------------------------
Usage:
* assembler program (< input)
* disassembler program (> output)
Both the assembler and the disassembler are run with a program as their
sole argument: they take their input from and print their output to
stdin and stdout respectively.
An initial gap created with ORG is not included in an assembled program.
All possible interpretations of a disassembled program are included in
its listing, resulting in overlapping information.
 

View File

@ -15,29 +15,33 @@ type
var var
Reader, Punch: Tape; //States of the reader and punch Reader, Punch: Tape; //States of the reader and punch
State: file of Tape; //File storing the states of the reader and punch State: file of Tape; //File storing the states of the reader and punch
DoRead, DoPunch: boolean; //Whether to reset the reader or the punch DoRead, DoPunch: integer; //Whether to (re)set the reader or the punch
begin begin
//Check whether to set the reader, the punch, or both //Check the arguments
if ParamCount <> 1 then begin if ParamCount > 4 then begin
writeln ('Usage: tapectl reader/punch/both'); writeln ('Usage: tapectl (-r reader_file) (-p punch_file)');
halt (1);
end
else if ParamCount mod 2 <> 0 then begin
writeln ('Usage: tapectl (-r reader_file) (-p punch_file)');
halt (1); halt (1);
end; end;
if ParamStr (1) = 'reader' then begin if ParamStr (1) = '-r' then begin
DoRead := true; DoRead := 2;
DoPunch := false; DoPunch := 0;
if ParamStr (3) = '-p' then begin
DoPunch := 4;
end;
end end
else if ParamStr (1) = 'punch' then begin else if ParamStr (1) = '-p' then begin
DoRead := false; DoRead := 0;
DoPunch := true; DoPunch := 2;
end if ParamStr (3) = '-r' then DoRead := 4;
else if ParamStr (1) = 'both' then begin
DoRead := true;
DoPunch := true;
end end
else begin else begin
writeln ('Usage: tapectl reader/punch/both'); writeln ('Usage: tapectl (-r reader_file) (-p punch_file)');
halt (1); halt (1);
end; end;
@ -64,18 +68,14 @@ begin
Punch.Pos := 0; Punch.Pos := 0;
end; end;
//Input the files to be read from or punched to //Get the files to be read from or punched to
if DoRead then begin if DoRead <> 0 then begin
write ('Reader: '); Reader.Path := ExpandFileName (ParamStr (DoRead));
readln (Reader.Path);
Reader.Path := ExpandFileName (Reader.Path);
Reader.Reset := true; Reader.Reset := true;
Reader.Pos := 0; Reader.Pos := 0;
end; end;
if DoPunch then begin if DoPunch <> 0 then begin
write ('Punch: '); Punch.Path := ExpandFileName (ParamStr (DoPunch));
readln (Punch.Path);
Punch.Path := ExpandFileName (Punch.Path);
Punch.Reset := true; Punch.Reset := true;
Punch.Pos := 0; Punch.Pos := 0;
end; end;