diff --git a/emulator.pas b/emulator.pas index 113b23a..11c2c67 100644 --- a/emulator.pas +++ b/emulator.pas @@ -12,7 +12,7 @@ var Addr, IP, RP: word; //Address argument and instruction and return pointers R: array [0 .. 3] of byte; //General-purpose registers Mem: array [0 .. $ffef] of byte; //Memory - Prog: file of byte; //Program file + Prog{$ifdef printer}, Ptr{$endif}: file of byte; //Program file and printer Ch: ansichar; //Character for input and output begin @@ -22,14 +22,6 @@ begin IP := 0; RP := $fff0; - //Initialise the printer - {$ifdef printer} - AssignLst (Lst, '| lpr'); - rewrite (Lst); - Ch := ansichar ($d); - write (Lst, Ch); - {$endif} - //Read a program file and check for errors if ParamCount <> 1 then begin writeln ('Usage: emulator program'); @@ -146,8 +138,10 @@ begin //Printer {$ifdef printer} else if Addr = $fffe then begin - Ch := ansichar (R [X]); - write (Lst, Ch); + assign (Ptr, '/dev/usb/lp0'); + rewrite (Ptr); + write (Ptr, R [X]); + close (Ptr); end {$endif} //Regular store @@ -214,9 +208,4 @@ begin end; - //Close the printer - {$ifdef printer} - close (Lst); - {$endif} - end. diff --git a/examples/ascii.asm b/examples/ascii.asm index 425cbf8..91e511f 100644 --- a/examples/ascii.asm +++ b/examples/ascii.asm @@ -17,24 +17,24 @@ store ffff, r1 store ffff, r1 - ;Get the hexadecimal digit of the high nibble + ;Convert and print the high nibble + ;Convert ror r0 ror r0 ror r0 ror r0 cleq r0, r0, n2hex - - ;Print the digit + ;Print store ffff, r0 ;Re-load the character to r0 xor r0, r0 xor r0, r2 - ;Get the hexadecimal digit of the low nibble + ;Convert and print the low nibble + ;Convert cleq r0, r0, n2hex - - ;Print the digit + ;Print store ffff, r0 ;Print a newline @@ -43,6 +43,8 @@ ;Halt halt + ;*** + ;Print a newline newln: load r1, cr store ffff, r1 @@ -50,79 +52,89 @@ newln: load r1, cr store ffff, r1 ret + ;*** + ;Get the hexadecimal digit of a nibble + ;Extract the low nibble n2hex: load r1, mask and r0, r1 + ;Locate the nibble in the table - load r1, tbl00 + load r1, nbl0 breq r0, r1, dgt0 - load r1, tbl02 + load r1, nbl1 breq r0, r1, dgt1 - load r1, tbl04 + load r1, nbl2 breq r0, r1, dgt2 - load r1, tbl06 + load r1, nbl3 breq r0, r1, dgt3 - load r1, tbl08 + load r1, nbl4 breq r0, r1, dgt4 - load r1, tbl0a + load r1, nbl5 breq r0, r1, dgt5 - load r1, tbl0c + load r1, nbl6 breq r0, r1, dgt6 - load r1, tbl0e + load r1, nbl7 breq r0, r1, dgt7 - load r1, tbl10 + load r1, nbl8 breq r0, r1, dgt8 - load r1, tbl12 + load r1, nbl9 breq r0, r1, dgt9 - load r1, tbl14 + load r1, nbla breq r0, r1, dgta - load r1, tbl16 + load r1, nblb breq r0, r1, dgtb - load r1, tbl18 + load r1, nblc breq r0, r1, dgtc - load r1, tbl1a + load r1, nbld breq r0, r1, dgtd - load r1, tbl1c + load r1, nble breq r0, r1, dgte - load r1, tbl1e + load r1, nblf breq r0, r1, dgtf + ;Load the hexadecimal digit of the nibble -dgt0: load r0, tbl01 +dgt0: load r0, hex0 breq r0, r0, n2hend -dgt1: load r0, tbl03 +dgt1: load r0, hex1 breq r0, r0, n2hend -dgt2: load r0, tbl05 +dgt2: load r0, hex2 breq r0, r0, n2hend -dgt3: load r0, tbl07 +dgt3: load r0, hex3 breq r0, r0, n2hend -dgt4: load r0, tbl09 +dgt4: load r0, hex4 breq r0, r0, n2hend -dgt5: load r0, tbl0b +dgt5: load r0, hex5 breq r0, r0, n2hend -dgt6: load r0, tbl0d +dgt6: load r0, hex6 breq r0, r0, n2hend -dgt7: load r0, tbl0f +dgt7: load r0, hex7 breq r0, r0, n2hend -dgt8: load r0, tbl11 +dgt8: load r0, hex8 breq r0, r0, n2hend -dgt9: load r0, tbl13 +dgt9: load r0, hex9 breq r0, r0, n2hend -dgta: load r0, tbl15 +dgta: load r0, hexa breq r0, r0, n2hend -dgtb: load r0, tbl17 +dgtb: load r0, hexb breq r0, r0, n2hend -dgtc: load r0, tbl19 +dgtc: load r0, hexc breq r0, r0, n2hend -dgtd: load r0, tbl1b +dgtd: load r0, hexd breq r0, r0, n2hend -dgte: load r0, tbl1d +dgte: load r0, hexe breq r0, r0, n2hend -dgtf: load r0, tbl1f +dgtf: load r0, hexf breq r0, r0, n2hend + ;Return n2hend: ret + ;*** + + ;Data + ;Characters cr: data d lf: data a @@ -132,36 +144,38 @@ prompt: data 3e ;Mask mask: data f + ;Nibble table +nbl0: data 0 +nbl1: data 1 +nbl2: data 2 +nbl3: data 3 +nbl4: data 4 +nbl5: data 5 +nbl6: data 6 +nbl7: data 7 +nbl8: data 8 +nbl9: data 9 +nbla: data a +nblb: data b +nblc: data c +nbld: data d +nble: data e +nblf: data f + ;Hexadecimal table -tbl00: data 0 -tbl01: data 30 -tbl02: data 1 -tbl03: data 31 -tbl04: data 2 -tbl05: data 32 -tbl06: data 3 -tbl07: data 33 -tbl08: data 4 -tbl09: data 34 -tbl0a: data 5 -tbl0b: data 35 -tbl0c: data 6 -tbl0d: data 36 -tbl0e: data 7 -tbl0f: data 37 -tbl10: data 8 -tbl11: data 38 -tbl12: data 9 -tbl13: data 39 -tbl14: data a -tbl15: data 41 -tbl16: data b -tbl17: data 42 -tbl18: data c -tbl19: data 43 -tbl1a: data d -tbl1b: data 44 -tbl1c: data e -tbl1d: data 45 -tbl1e: data f -tbl1f: data 46 +hex0: data 30 +hex1: data 31 +hex2: data 32 +hex3: data 33 +hex4: data 34 +hex5: data 35 +hex6: data 36 +hex7: data 37 +hex8: data 38 +hex9: data 39 +hexa: data 41 +hexb: data 42 +hexc: data 43 +hexd: data 44 +hexe: data 45 +hexf: data 46 diff --git a/examples/echo.asm b/examples/echo.asm index 5e51c1a..3521853 100644 --- a/examples/echo.asm +++ b/examples/echo.asm @@ -1,15 +1,19 @@ ;String echo - ;Store the buffer start address in buffst + ;*** + + ;Input + + ;Restore the buffer start address ;High byte - load r0, chstor + 1 - store buffst, r0 +input: load r0, bfstrt + store chstor + 1, r0 ;Low byte - load r0, chstor + 2 - store buffst + 1, r0 + load r0, bfstrt + 1 + store chstor + 2, r0 ;Print a prompt -start: load r0, prompt + load r0, prompt store ffff, r0 load r0, space store ffff, r0 @@ -20,19 +24,18 @@ start: load r0, prompt ;Read a character inloop: load r1, ffff - ;Check for an escape + ;Check for control characters and the buffer end + ;Escape load r2, esc breq r1, r2, escbr - - ;Check for a return + ;Carriage return load r2, cr - breq r1, r2, inend - - ;Check for end of the buffer - load r2, buffsz + breq r1, r2, crbr + ;Buffer end + load r2, bfsize brneq r0, r2, chstor - ;Backtrack if end of the buffer + ;Backtrack if at the buffer end load r2, bs store ffff, r2 breq r0, r0, inloop @@ -40,18 +43,15 @@ inloop: load r1, ffff ;Store the character in the buffer chstor: store buffer, r1 - ;Increment the character counter and load it in r3 + ;Increment the character counter and store it in r3 + ;Increment load r2, one cleq r0, r0, sum + ;Store xor r3, r3 xor r3, r0 ;Increment the buffer address - ;High byte - load r0, chstor + 1 - load r2, one - cleq r0, r0, sum - store chstor + 1, r0 ;Low byte load r0, chstor + 2 load r2, one @@ -72,74 +72,71 @@ chstor: store buffer, r1 breq r0, r0, inloop ;Print a backslash and a newline + ;Backslash escbr: load r0, space store ffff, r0 load r0, bslash store ffff, r0 + ;Newline load r0, cr store ffff, r0 load r0, lf store ffff, r0 - ;Restore the buffer address to its start - ;High byte - load r0, buffst - store chstor + 1, r0 - ;Low byte - load r0, buffst + 1 - store chstor + 2, r0 - ;Start a new input line - breq r0, r0, start + breq r0, r0, input ;Store a string-terminating zero in the buffer -inend: xor r0, r0 - load r1, chstor + 1 + ;Get the buffer address +crbr: load r1, chstor + 1 store endsto + 1, r1 load r1, chstor + 2 store endsto + 2, r1 + ;Store + xor r0, r0 endsto: store 0000, r0 + ;*** + + ;Print + ;Print a line feed and align with the input + ;Line feed load r0, lf store ffff, r0 + ;Align load r0, space store ffff, r0 store ffff, r0 ;Load a character from the buffer -outlop: load r1, buffer +chprnt: load r1, buffer ;Check for string end xor r2, r2 - breq r1, r2, outend + breq r1, r2, end ;Print the character store ffff, r1 ;Increment the buffer address - ;High byte - load r0, outlop + 1 - load r2, one - cleq r0, r0, sum - store outlop + 1, r0 ;Low byte - load r0, outlop + 2 + load r0, chprnt + 2 load r2, one cleq r0, r0, sum - store outlop + 2, r0 + store chprnt + 2, r0 ;Add the overflow to the high byte - load r0, outlop + 1 + load r0, chprnt + 1 xor r2, r2 xor r2, r1 cleq r0, r0, sum - store outlop + 1, r0 + store chprnt + 1, r0 ;Print the next character - breq r0, r0, outlop + breq r0, r0, chprnt ;Print a newline -outend: load r0, cr +end: load r0, cr store ffff, r0 load r0, lf store ffff, r0 @@ -147,34 +144,52 @@ outend: load r0, cr ;Halt halt + ;*** + ;Add r2 to r0 with the overflow stored in r1 + ;Reset overflow sum: xor r1, r1 store ovrflw, r1 + ;Copy the first argument to r1 sumlop: xor r1, r1 xor r1, r0 + ;Calculate the sum and carry and copy the pre-shift carry to r1 + ;Sum xor r0, r2 + ;Carry and r2, r1 + ;Copy the pre-shift carry xor r1, r1 xor r1, r2 + ;Shift the carry shl r2 - ;Check for overflow + + ;Check for and store overflow if any + ;Check rol r1 breq r1, r2, nvrflw - ;Store overflow + ;Store load r1, one store ovrflw, r1 + ;Check for no carry nvrflw: xor r1, r1 breq r1, r2, sumend + ;Loop breq r0, r0, sumlop + ;Load overflow and return sumend: load r1, ovrflw ret + ;*** + + ;Data + ;Constants one: data 1 @@ -191,7 +206,7 @@ bslash: data 5c ovrflw: data 0 ;Buffer -buffst: data 0 - data 0 -buffsz: data f +bfstrt: addr buffer +bfsize: data ff + buffer: diff --git a/readme.md b/readme.md index 9306d72..204190a 100644 --- a/readme.md +++ b/readme.md @@ -91,8 +91,8 @@ address FFFF. The emulator emulates a dumb terminal for this. Arbitrary devices can be mapped to the other reserved addresses. The emulator can be compiled in Linux with support for a dot matrix -printer with the argument -dprinter. The printer must be set as the -default in CUPS and will be mapped to address FFFE in the emulator. +printer at /dev/usb/lp0 with the argument -dprinter. The printer is +mapped to address FFFE in the emulator. Initial Program Loader ----------------------