diff --git a/emulator.pas b/emulator.pas index f226b4e..ce8b4f6 100644 --- a/emulator.pas +++ b/emulator.pas @@ -30,6 +30,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 //Terminal output procedure Output; @@ -38,7 +39,11 @@ begin if Ch <= ansichar ($1f) then begin if Ch = ansichar (7) then write (Ch) //Bell else if Ch = ansichar (8) then write (Ch) //Backspace - else if Ch = ansichar ($a) then write (Ch) //Line feed + else if Ch = ansichar ($a) then begin //Bodge for line feed + LFX := WhereX; + write (Ch); + GotoXY (LFX, WhereY); + end else if Ch = ansichar ($d) then write (Ch) //Carriage return else write (''); //Others end @@ -47,12 +52,21 @@ begin else write (Ch); end; +//Wait to emulate CPU speed of ~500 KIPS +procedure wait; +begin + if IC div 500 = 0 then sleep (1) + else sleep (IC div 500); + IC := 0; +end; + begin - //Initialise the halt flag and the pointers + //Initialise the halt flag, the pointers, and the instruction counter Hlt := false; IP := 0; RP := $fff0; + IC := 0; //Initialise the tape reader and punch {$ifdef tape} @@ -163,6 +177,7 @@ begin else if Op = $a then begin //Terminal input if Addr = IO then begin + wait; //Read a keypress repeat Ch := ReadKey; @@ -209,6 +224,7 @@ begin //Tape reader {$ifdef tape} else if Addr = $fffd then begin + wait; assign (State, ExpandFileName ('~/.tapes.thingamajig')); //Check the reader state if FileExists (ExpandFileName ('~/.tapes.thingamajig')) then begin @@ -250,12 +266,14 @@ begin else if Op = $b then begin //Terminal output if Addr = IO then begin + wait; Ch := ansichar (R [X]); Output; end //Printer {$ifdef printer} else if Addr = $fffe then begin + wait; assign (Prn, '/dev/usb/lp0'); try rewrite (Prn); @@ -268,6 +286,7 @@ begin //Tape punch {$ifdef tape} else if Addr = $fffd then begin + wait; assign (State, ExpandFileName ('~/.tapes.thingamajig')); //Check the punch state if FileExists (ExpandFileName ('~/.tapes.thingamajig')) then begin @@ -322,7 +341,6 @@ begin end; end {$endif} - //Regular store else Mem [Addr] := R [X]; end @@ -385,6 +403,11 @@ begin end; end; + //Increment the instruction counter + IC := IC + 1; + end; + wait; + end. diff --git a/readme.md b/readme.md index bab86aa..06cff61 100644 --- a/readme.md +++ b/readme.md @@ -8,12 +8,18 @@ https://ahti.space/git/crazyettin/Thingamajig. Included Software ----------------- -The repository includes an emulator implementation of Thingamajig, a +The repository includes an emulator implementation of Thingamajig with a control program for the emulated punched tape reader and punch, and an assembler and a disassembler, all written in FreePascal. It also includes couple of simple example programs for Thingamajig written in Assembly. +Speed +----- + +Thingamajig does not have a prescribed speed. The emulator should run at +roughly 500 KIPS. + Registers and Memory -------------------- @@ -86,8 +92,8 @@ reference to or relative to a label. Memory-Mapped Devices --------------------- -Input (when read from) and output (when written to) are mapped to -address FFFF. The emulator emulates a glass teletype with local echo. +Input and output are mapped to address FFFF. The emulator emulates a +glass teletype with local echo. Arbitrary devices can be mapped to the other reserved addresses. @@ -102,7 +108,7 @@ to modify the code yourself. Initial Program Loader ---------------------- -At boot the initial program loader loads a program to the memory +At boot the initial program loader (IPL) loads a program to the memory starting from address 0 after which is cedes control to the CPU. The emulator loads the program from a ROM file.  \ No newline at end of file