diff --git a/examples/ascii.asm b/examples/ascii.asm index 91e511f..81e24b7 100644 --- a/examples/ascii.asm +++ b/examples/ascii.asm @@ -1,181 +1,182 @@ - ;ASCII code printer - - ;Print a prompt - load r0, prompt - store ffff, r0 - load r0, space - store ffff, r0 - - ;Read a character to r0 and load it to r2 - load r0, ffff - xor r2, r2 - xor r2, r0 - - ;Print a newline and align - cleq r0, r0, newln - load r1, space - store ffff, r1 - store ffff, r1 - - ;Convert and print the high nibble - ;Convert - ror r0 - ror r0 - ror r0 - ror r0 - cleq r0, r0, n2hex - ;Print - store ffff, r0 - - ;Re-load the character to r0 - xor r0, r0 - xor r0, r2 - - ;Convert and print the low nibble - ;Convert - cleq r0, r0, n2hex - ;Print - store ffff, r0 - - ;Print a newline - cleq r0, r0, newln - - ;Halt - halt - - ;*** - - ;Print a newline -newln: load r1, cr - store ffff, r1 - load r1, lf - 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, nbl0 - breq r0, r1, dgt0 - load r1, nbl1 - breq r0, r1, dgt1 - load r1, nbl2 - breq r0, r1, dgt2 - load r1, nbl3 - breq r0, r1, dgt3 - load r1, nbl4 - breq r0, r1, dgt4 - load r1, nbl5 - breq r0, r1, dgt5 - load r1, nbl6 - breq r0, r1, dgt6 - load r1, nbl7 - breq r0, r1, dgt7 - load r1, nbl8 - breq r0, r1, dgt8 - load r1, nbl9 - breq r0, r1, dgt9 - load r1, nbla - breq r0, r1, dgta - load r1, nblb - breq r0, r1, dgtb - load r1, nblc - breq r0, r1, dgtc - load r1, nbld - breq r0, r1, dgtd - load r1, nble - breq r0, r1, dgte - load r1, nblf - breq r0, r1, dgtf - - ;Load the hexadecimal digit of the nibble -dgt0: load r0, hex0 - breq r0, r0, n2hend -dgt1: load r0, hex1 - breq r0, r0, n2hend -dgt2: load r0, hex2 - breq r0, r0, n2hend -dgt3: load r0, hex3 - breq r0, r0, n2hend -dgt4: load r0, hex4 - breq r0, r0, n2hend -dgt5: load r0, hex5 - breq r0, r0, n2hend -dgt6: load r0, hex6 - breq r0, r0, n2hend -dgt7: load r0, hex7 - breq r0, r0, n2hend -dgt8: load r0, hex8 - breq r0, r0, n2hend -dgt9: load r0, hex9 - breq r0, r0, n2hend -dgta: load r0, hexa - breq r0, r0, n2hend -dgtb: load r0, hexb - breq r0, r0, n2hend -dgtc: load r0, hexc - breq r0, r0, n2hend -dgtd: load r0, hexd - breq r0, r0, n2hend -dgte: load r0, hexe - breq r0, r0, n2hend -dgtf: load r0, hexf - breq r0, r0, n2hend - - ;Return -n2hend: ret - - ;*** - - ;Data - - ;Characters -cr: data d -lf: data a -space: data 20 -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 -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 + ;ASCII code printer + + ;Print a prompt + load r0, prompt + store ffff, r0 + load r0, space + store ffff, r0 + + ;Read a character to r0 and load it to r2 + load r0, ffff + xor r2, r2 + xor r2, r0 + + ;Print a newline and align + cleq r0, r0, newln + load r1, space + store ffff, r1 + store ffff, r1 + + ;Convert and print the high nibble + ;Convert + ror r0 + ror r0 + ror r0 + ror r0 + cleq r0, r0, n2hex + ;Print + store ffff, r0 + + ;Re-load the character to r0 + xor r0, r0 + xor r0, r2 + + ;Convert and print the low nibble + ;Convert + cleq r0, r0, n2hex + ;Print + store ffff, r0 + + ;Print a newline + cleq r0, r0, newln + + ;Halt + halt + + ;*** + + ;Print a newline +newln: load r1, cr + store ffff, r1 + load r1, lf + 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, nbl0 + breq r0, r1, dgt0 + load r1, nbl1 + breq r0, r1, dgt1 + load r1, nbl2 + breq r0, r1, dgt2 + load r1, nbl3 + breq r0, r1, dgt3 + load r1, nbl4 + breq r0, r1, dgt4 + load r1, nbl5 + breq r0, r1, dgt5 + load r1, nbl6 + breq r0, r1, dgt6 + load r1, nbl7 + breq r0, r1, dgt7 + load r1, nbl8 + breq r0, r1, dgt8 + load r1, nbl9 + breq r0, r1, dgt9 + load r1, nbla + breq r0, r1, dgta + load r1, nblb + breq r0, r1, dgtb + load r1, nblc + breq r0, r1, dgtc + load r1, nbld + breq r0, r1, dgtd + load r1, nble + breq r0, r1, dgte + load r1, nblf + breq r0, r1, dgtf + + ;Load the hexadecimal digit of the nibble +dgt0: load r0, hex0 + breq r0, r0, n2hend +dgt1: load r0, hex1 + breq r0, r0, n2hend +dgt2: load r0, hex2 + breq r0, r0, n2hend +dgt3: load r0, hex3 + breq r0, r0, n2hend +dgt4: load r0, hex4 + breq r0, r0, n2hend +dgt5: load r0, hex5 + breq r0, r0, n2hend +dgt6: load r0, hex6 + breq r0, r0, n2hend +dgt7: load r0, hex7 + breq r0, r0, n2hend +dgt8: load r0, hex8 + breq r0, r0, n2hend +dgt9: load r0, hex9 + breq r0, r0, n2hend +dgta: load r0, hexa + breq r0, r0, n2hend +dgtb: load r0, hexb + breq r0, r0, n2hend +dgtc: load r0, hexc + breq r0, r0, n2hend +dgtd: load r0, hexd + breq r0, r0, n2hend +dgte: load r0, hexe + breq r0, r0, n2hend +dgtf: load r0, hexf + breq r0, r0, n2hend + + ;Return +n2hend: ret + + ;*** + + ;Data + + ;Characters +cr: data d +lf: data a +space: data 20 +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 +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 + \ No newline at end of file diff --git a/examples/echo.asm b/examples/echo.asm index 3521853..4c4fc4a 100644 --- a/examples/echo.asm +++ b/examples/echo.asm @@ -1,212 +1,213 @@ - ;String echo - - ;*** - - ;Input - - ;Restore the buffer start address - ;High byte -input: load r0, bfstrt - store chstor + 1, r0 - ;Low byte - load r0, bfstrt + 1 - store chstor + 2, r0 - - ;Print a prompt - load r0, prompt - store ffff, r0 - load r0, space - store ffff, r0 - - ;Initialise the character counter - xor r0, r0 - - ;Read a character -inloop: load r1, ffff - - ;Check for control characters and the buffer end - ;Escape - load r2, esc - breq r1, r2, escbr - ;Carriage return - load r2, cr - breq r1, r2, crbr - ;Buffer end - load r2, bfsize - brneq r0, r2, chstor - - ;Backtrack if at the buffer end - load r2, bs - store ffff, r2 - breq r0, r0, inloop - - ;Store the character in the buffer -chstor: store buffer, r1 - - ;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 - ;Low byte - load r0, chstor + 2 - load r2, one - cleq r0, r0, sum - store chstor + 2, r0 - ;Add the overflow to the high byte - load r0, chstor + 1 - xor r2, r2 - xor r2, r1 - cleq r0, r0, sum - store chstor + 1, r0 - - ;Reload the character counter to r0 - xor r0, r0 - xor r0, r3 - - ;Read the next character - 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 - - ;Start a new input line - breq r0, r0, input - - ;Store a string-terminating zero in the buffer - ;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 -chprnt: load r1, buffer - - ;Check for string end - xor r2, r2 - breq r1, r2, end - - ;Print the character - store ffff, r1 - - ;Increment the buffer address - ;Low byte - load r0, chprnt + 2 - load r2, one - cleq r0, r0, sum - store chprnt + 2, r0 - ;Add the overflow to the high byte - load r0, chprnt + 1 - xor r2, r2 - xor r2, r1 - cleq r0, r0, sum - store chprnt + 1, r0 - - ;Print the next character - breq r0, r0, chprnt - - ;Print a newline -end: load r0, cr - store ffff, r0 - load r0, lf - store ffff, r0 - - ;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 and store overflow if any - ;Check - rol r1 - breq r1, r2, nvrflw - ;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 - - ;Characters -bs: data 8 -lf: data a -cr: data d -esc: data 1b -space: data 20 -prompt: data 3e -bslash: data 5c - - ;Variables -ovrflw: data 0 - - ;Buffer -bfstrt: addr buffer -bfsize: data ff - -buffer: + ;String echo + + ;*** + + ;Input + + ;Restore the buffer start address + ;High byte +input: load r0, bfstrt + store chstor + 1, r0 + ;Low byte + load r0, bfstrt + 1 + store chstor + 2, r0 + + ;Print a prompt + load r0, prompt + store ffff, r0 + load r0, space + store ffff, r0 + + ;Initialise the character counter + xor r0, r0 + + ;Read a character +inloop: load r1, ffff + + ;Check for control characters and the buffer end + ;Escape + load r2, esc + breq r1, r2, escbr + ;Carriage return + load r2, cr + breq r1, r2, crbr + ;Buffer end + load r2, bfsize + brneq r0, r2, chstor + + ;Backtrack if at the buffer end + load r2, bs + store ffff, r2 + breq r0, r0, inloop + + ;Store the character in the buffer +chstor: store buffer, r1 + + ;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 + ;Low byte + load r0, chstor + 2 + load r2, one + cleq r0, r0, sum + store chstor + 2, r0 + ;Add the overflow to the high byte + load r0, chstor + 1 + xor r2, r2 + xor r2, r1 + cleq r0, r0, sum + store chstor + 1, r0 + + ;Reload the character counter to r0 + xor r0, r0 + xor r0, r3 + + ;Read the next character + 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 + + ;Start a new input line + breq r0, r0, input + + ;Store a string-terminating zero in the buffer + ;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 +chprnt: load r1, buffer + + ;Check for string end + xor r2, r2 + breq r1, r2, end + + ;Print the character + store ffff, r1 + + ;Increment the buffer address + ;Low byte + load r0, chprnt + 2 + load r2, one + cleq r0, r0, sum + store chprnt + 2, r0 + ;Add the overflow to the high byte + load r0, chprnt + 1 + xor r2, r2 + xor r2, r1 + cleq r0, r0, sum + store chprnt + 1, r0 + + ;Print the next character + breq r0, r0, chprnt + + ;Print a newline +end: load r0, cr + store ffff, r0 + load r0, lf + store ffff, r0 + + ;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 and store overflow if any + ;Check + rol r1 + breq r1, r2, nvrflw + ;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 + + ;Characters +bs: data 8 +lf: data a +cr: data d +esc: data 1b +space: data 20 +prompt: data 3e +bslash: data 5c + + ;Variables +ovrflw: data 0 + + ;Buffer +bfstrt: addr buffer +bfsize: data ff + +buffer: + \ No newline at end of file diff --git a/license.md b/license.md index fabda6a..21283d6 100644 --- a/license.md +++ b/license.md @@ -1,23 +1,24 @@ -MIT License -=========== - -Copyright (c) 2022 - -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. +MIT License +=========== + +Copyright (c) 2022 + +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. + \ No newline at end of file diff --git a/readme.md b/readme.md index 8d5457f..6b16992 100644 --- a/readme.md +++ b/readme.md @@ -1,108 +1,108 @@ -Thingamajig -=========== - -Thingamajig is a RISC-y and MISC-y homebrew computer architecture. Its -git repository can be found at -https://ahti.space/git/crazyettin/Thingamajig. - -Included Software ------------------ - -The repository includes an emulator implementation of Thingamajig, 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. - -Registers and Memory --------------------- - - * 24-bit instruction register IR - * 16-bit instruction and return pointers IP and RP - * 8-bit general-purpose registers R0-R3 - * 8-bit memory locations 0-FFFF - -Multi-byte values are big-endian. Memory addresses FFF0-FFFF are -reserved for memory mapped devices; the instruction and return pointers -cannot have values higher than FFEF and FFF0 respectively to avoid them. -The instruction and return pointers are initialised as 0 and FFF0 -respectively, while other registers and memory are unitialised. - -Instructions ------------- - -Instructions without an address argument are 8-bit and those with one -24-bit. The instruction pointer is incremented before being accessed or -modified. - -0 HALT -1 RET IP = *RP; RP += 2 - -2 SHL RX RX <<= 1 Logical shifts -3 SHR RX RX >>= 1 -4 ROL RX RX <<= 1 Rotating shifts -5 ROR RX RX >>= 1 - -6 NAND RX, RY RX = ~(RX & RY) -7 AND RX, RY RX &= RY -8 OR RX, RY RX |= RY -9 XOR RX, RY RX ^= RY - -A LOAD RX, ADDR RX = *ADDR -B STORE RX, ADDR *ADDR = RX Written as "STORE ADDR, RX" in - assembly for the sake of - consistency. - -C BREQ RX, RY, ADDR if (RX == RY) IP = ADDR -D BRNEQ RX, RY, ADDR if (RX != RY) IP = ADDR -E CLEQ RX, RY, ADDR if (RX == RY) {RP -= 2; *RP = IP; IP = ADDR} -F CLNEQ RX, RY, ADDR if (RX != RY) {RP -= 2; *RP = IP; IP = ADDR} - -Assembly Language ------------------ - -Lines of assembly are of the following form: - -LABEL: OPER ARG1, ARG2, ARG3 ;Comment - -The language is case-insensitive and uses hexadecimal numbers. A label -can consist of any alphanumeric characters as long as it is not -interpretable as a hexadecimal number. The label, instruction, and -comment elements are all optional, as is spacing between the arguments. -For the arguments of each instruction see the previous section. - -Address arguments can be either absolute addresses or references to or -relative to a label. Relative references are of the form LABEL +/- N, -the spacing being optional. Note that the assembler does not check for -addresses or references to reserved addresses. - -In addition to the true instructions there are three -pseudo-instructions. ORG defines the starting address of the program: it -can only occur as the first instruction and cannot have a label, and is -not required if the starting address is 0. DATA introduces a byte of -data. ADDR introduces two bytes of data containing the address of a -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 dumb terminal with local echo for -this. - -Arbitrary devices can be mapped to the other reserved addresses. - -In Linux the emulator can be compiled with support for a line printer -and an emulated punched tape reader and punch with the arguments --dprinter and -dtape respectively. The printer prints into /dev/usb/lp0 -and the tape files read from and punched to are (re)set using the -settape program. The printer is mapped to address FFFE in the emulator -and the tape reader and punch to FFFD. If you wish to use a different -setup you have to modify the code yourself. - -Initial Program Loader ----------------------- - -At boot the initial program loader 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 file. +Thingamajig +=========== + +Thingamajig is a RISC-y and MISC-y homebrew computer architecture. Its +git repository can be found at +https://ahti.space/git/crazyettin/Thingamajig. + +Included Software +----------------- + +The repository includes an emulator implementation of Thingamajig, 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. + +Registers and Memory +-------------------- + + * 24-bit instruction register IR + * 16-bit instruction and return pointers IP and RP + * 8-bit general-purpose registers R0-R3 + * 8-bit memory locations 0-FFFF + +Multi-byte values are big-endian. Memory addresses FFF0-FFFF are +reserved for memory mapped devices; the instruction and return pointers +cannot have values higher than FFEF and FFF0 respectively to avoid them. +The instruction and return pointers are initialised as 0 and FFF0 +respectively, while other registers and memory are unitialised. + +Instructions +------------ + +Instructions without an address argument are 8-bit and those with one +24-bit. The instruction pointer is incremented before being accessed or +modified. + +0 HALT +1 RET IP = *RP; RP += 2 + +2 SHL RX RX <<= 1 Logical shifts +3 SHR RX RX >>= 1 +4 ROL RX RX <<= 1 Rotating shifts +5 ROR RX RX >>= 1 + +6 NAND RX, RY RX = ~(RX & RY) +7 AND RX, RY RX &= RY +8 OR RX, RY RX |= RY +9 XOR RX, RY RX ^= RY + +A LOAD RX, ADDR RX = *ADDR +B STORE RX, ADDR *ADDR = RX Written as "STORE ADDR, RX" in + assembly for the sake of + consistency. + +C BREQ RX, RY, ADDR if (RX == RY) IP = ADDR +D BRNEQ RX, RY, ADDR if (RX != RY) IP = ADDR +E CLEQ RX, RY, ADDR if (RX == RY) {RP -= 2; *RP = IP; IP = ADDR} +F CLNEQ RX, RY, ADDR if (RX != RY) {RP -= 2; *RP = IP; IP = ADDR} + +Assembly Language +----------------- + +Lines of assembly are of the following form: + +LABEL: OPER ARG1, ARG2, ARG3 ;Comment + +The language is case-insensitive and uses hexadecimal numbers. A label +can consist of any alphanumeric characters as long as it is not +interpretable as a hexadecimal number. The label, instruction, and +comment elements are all optional, as is spacing between the arguments. +For the arguments of each instruction see the previous section. + +Address arguments can be either absolute addresses or references to or +relative to a label. Relative references are of the form LABEL +/- N, +the spacing being optional. Note that the assembler does not check for +addresses or references to reserved addresses. + +In addition to the true instructions there are three +pseudo-instructions. ORG defines the starting address of the program: it +can only occur as the first instruction and cannot have a label, and is +not required if the starting address is 0. DATA introduces a byte of +data. ADDR introduces two bytes of data containing the address of a +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 dumb terminal with local echo. + +Arbitrary devices can be mapped to the other reserved addresses. + +In Linux the emulator can be compiled with support for a line 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 settape program. If you wish to use a different setup you have +to modify the code yourself. + +Initial Program Loader +---------------------- + +At boot the initial program loader 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 file. + \ No newline at end of file