Reword the readme slightly in Gidubba and convert the readme, license, and example programs to a Gidubba-friendly format
This commit is contained in:
parent
c3151c5113
commit
152d2d107f
4 changed files with 527 additions and 524 deletions
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
47
license.md
47
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.
|
||||
|
216
readme.md
216
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.
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue