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}
var
Hlt, Verbose, Echo: boolean; //Halt, verbose, and echo flags
Hlt, Echo: boolean; //Halt and echo flags
Op, Regs: 0 .. $f; //Opcode
X, Y: 0 .. 3; //Register arguments
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
{$endif}
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
//Terminal output
@ -288,14 +288,21 @@ begin
halt (1);
end;
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
writeln ('Usage: emulator (-v) program (2> verbose_output)');
halt (1);
end;
end
else begin
Verbose := false;
Verbose := 0;
if ParamCount <> 1 then begin
writeln ('Usage: emulator (-v) program (2> verbose_output)');
halt (1);
@ -304,7 +311,7 @@ begin
//Read a program file and check for errors
{$i-}
if Verbose = true then assign (Prog, ParamStr (2))
if Verbose = 1 then assign (Prog, ParamStr (2))
else assign (Prog, ParamStr (1));
reset (Prog);
if FileSize (Prog) > LastRAM + 1 then begin
@ -329,7 +336,7 @@ begin
while Hlt = false do begin
//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 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
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
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
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
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
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
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
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.
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
Reader, Punch: Tape; //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
//Check whether to set the reader, the punch, or both
if ParamCount <> 1 then begin
writeln ('Usage: tapectl reader/punch/both');
//Check the arguments
if ParamCount > 4 then begin
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);
end;
if ParamStr (1) = 'reader' then begin
DoRead := true;
DoPunch := false;
if ParamStr (1) = '-r' then begin
DoRead := 2;
DoPunch := 0;
if ParamStr (3) = '-p' then begin
DoPunch := 4;
end;
end
else if ParamStr (1) = 'punch' then begin
DoRead := false;
DoPunch := true;
end
else if ParamStr (1) = 'both' then begin
DoRead := true;
DoPunch := true;
else if ParamStr (1) = '-p' then begin
DoRead := 0;
DoPunch := 2;
if ParamStr (3) = '-r' then DoRead := 4;
end
else begin
writeln ('Usage: tapectl reader/punch/both');
writeln ('Usage: tapectl (-r reader_file) (-p punch_file)');
halt (1);
end;
@ -64,18 +68,14 @@ begin
Punch.Pos := 0;
end;
//Input the files to be read from or punched to
if DoRead then begin
write ('Reader: ');
readln (Reader.Path);
Reader.Path := ExpandFileName (Reader.Path);
//Get the files to be read from or punched to
if DoRead <> 0 then begin
Reader.Path := ExpandFileName (ParamStr (DoRead));
Reader.Reset := true;
Reader.Pos := 0;
end;
if DoPunch then begin
write ('Punch: ');
readln (Punch.Path);
Punch.Path := ExpandFileName (Punch.Path);
if DoPunch <> 0 then begin
Punch.Path := ExpandFileName (ParamStr (DoPunch));
Punch.Reset := true;
Punch.Pos := 0;
end;