Compare commits
6 Commits
8f615e1bd8
...
f68fa4c0a6
Author | SHA1 | Date | |
---|---|---|---|
f68fa4c0a6
|
|||
d92b8f6ba4
|
|||
96a5804467
|
|||
9ab92eb8a5
|
|||
a6a93e656a
|
|||
b5cfd501c5
|
@@ -49,24 +49,29 @@ listed in alphabetical order. Below in @if-table is a list of available IFs.
|
|||||||
|
|
||||||
#figure(
|
#figure(
|
||||||
table(
|
table(
|
||||||
columns: (1fr, auto),
|
columns: (auto, auto, 1fr),
|
||||||
inset: 10pt,
|
inset: 10pt,
|
||||||
align: center,
|
align: center,
|
||||||
fill: (_, y) =>
|
fill: (_, y) =>
|
||||||
if calc.odd(y) { luma(250) }
|
if calc.odd(y) { luma(250) }
|
||||||
else { white },
|
else { white },
|
||||||
table.header(
|
table.header(
|
||||||
[*Name* (pg. no.)], [*Description*]
|
[*Name* (pg. no.)], [*Command Token*], [*Description*]
|
||||||
),
|
),
|
||||||
[`CALL` (#ref(<if-call>, form: "page"))],
|
[`CALL` (#ref(<if-call>, form: "page"))],
|
||||||
|
[`$00`],
|
||||||
[Call a resident routine in the MPU's address space.],
|
[Call a resident routine in the MPU's address space.],
|
||||||
[`HELP` (#ref(<if-help>, form: "page"))],
|
[`HELP` (#ref(<if-help>, form: "page"))],
|
||||||
|
[`$01`],
|
||||||
[Display a summary of known commands.],
|
[Display a summary of known commands.],
|
||||||
[`PEEK` (#ref(<if-peek>, form: "page"))],
|
[`PEEK` (#ref(<if-peek>, form: "page"))],
|
||||||
|
[`$02`],
|
||||||
[Dumps memory from the MPU's address space to the terminal.],
|
[Dumps memory from the MPU's address space to the terminal.],
|
||||||
[`POKE` (#ref(<if-poke>, form: "page"))],
|
[`POKE` (#ref(<if-poke>, form: "page"))],
|
||||||
|
[`$03`],
|
||||||
[Overwrites memory in the MPU's address space.],
|
[Overwrites memory in the MPU's address space.],
|
||||||
[`SREC` (#ref(<if-srec>, form: "page"))],
|
[`SREC` (#ref(<if-srec>, form: "page"))],
|
||||||
|
[`$04`],
|
||||||
[Switches into Motorola S-Record receive mode.],
|
[Switches into Motorola S-Record receive mode.],
|
||||||
),
|
),
|
||||||
caption: [Table of IFs],
|
caption: [Table of IFs],
|
||||||
@@ -75,8 +80,7 @@ listed in alphabetical order. Below in @if-table is a list of available IFs.
|
|||||||
In the following pages these IFs are described in specific.
|
In the following pages these IFs are described in specific.
|
||||||
|
|
||||||
IFs are tokenized from their textual form into a binary "bytecode" form. This
|
IFs are tokenized from their textual form into a binary "bytecode" form. This
|
||||||
bytecode is not reliably stable between versions, so it isn't described here in
|
bytecode is described in @internals.
|
||||||
specific, but a general breakdown is provided.
|
|
||||||
|
|
||||||
First the text command name (eg. `CALL`) is hashed in some way into a token.
|
First the text command name (eg. `CALL`) is hashed in some way into a token.
|
||||||
Then conditional processing on the remainder of the line occurs. Values given in
|
Then conditional processing on the remainder of the line occurs. Values given in
|
||||||
@@ -147,12 +151,12 @@ BIOS routine.
|
|||||||
syntax: [`PEEK <BASE> [<HIGH>]`],
|
syntax: [`PEEK <BASE> [<HIGH>]`],
|
||||||
params: (
|
params: (
|
||||||
base: [
|
base: [
|
||||||
The address of the byte to dump or the base (lower bound) address of the
|
The address (two bytes) of the byte to dump or the base (lower bound)
|
||||||
byte to start dumping from if `<HIGH>` is specified.
|
address of the byte to start dumping from if `<HIGH>` is specified.
|
||||||
],
|
],
|
||||||
high: [
|
high: [
|
||||||
An optional operand given as the upper bound of the range to dump. Forms
|
An optional operand given as the upper bound of the range to dump. Forms
|
||||||
a range together with `<BASE>`.
|
a range together with `<BASE>`. (two bytes)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -160,8 +164,6 @@ BIOS routine.
|
|||||||
Peeking memory causes the MPU to read the requested bytes and dump them to the
|
Peeking memory causes the MPU to read the requested bytes and dump them to the
|
||||||
screen.
|
screen.
|
||||||
|
|
||||||
#lorem(120)
|
|
||||||
|
|
||||||
#pagebreak()
|
#pagebreak()
|
||||||
|
|
||||||
=== IF: `POKE` <if-poke>
|
=== IF: `POKE` <if-poke>
|
||||||
@@ -170,12 +172,13 @@ screen.
|
|||||||
desc: "Writes values to the MPU's address space.",
|
desc: "Writes values to the MPU's address space.",
|
||||||
syntax: [`POKE <ADDR> <BYTES>`],
|
syntax: [`POKE <ADDR> <BYTES>`],
|
||||||
params: (
|
params: (
|
||||||
addr: "The base (low) address to start writing bytes from.",
|
addr: "The base (low) address (two bytes) to start writing bytes from.",
|
||||||
bytes: "The bytes to write into memory separated by whitespace.",
|
bytes: "The bytes to write into memory separated by whitespace.",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
#lorem(120)
|
Poking memory causes the MPU to overwrite the bytes at `<ADDR>` with the bytes
|
||||||
|
given in `<BYTES>`.
|
||||||
|
|
||||||
#pagebreak()
|
#pagebreak()
|
||||||
|
|
||||||
@@ -187,7 +190,7 @@ screen.
|
|||||||
params: (),
|
params: (),
|
||||||
)
|
)
|
||||||
|
|
||||||
#lorem(120)
|
Motorola S-Record mode is currently a stub.
|
||||||
|
|
||||||
#pagebreak()
|
#pagebreak()
|
||||||
|
|
||||||
@@ -273,7 +276,9 @@ Building the documentation can also be accomplished using `make docs`, provided
|
|||||||
= BUZBEE Internals and Modding <internals>
|
= BUZBEE Internals and Modding <internals>
|
||||||
|
|
||||||
BUZBEE's interpreter works by "compiling" textual user commands into bytecode
|
BUZBEE's interpreter works by "compiling" textual user commands into bytecode
|
||||||
for more simply passing parameters to IFs (see @if-top).
|
for more simply passing parameters to IFs (see @if-top). The way that works is
|
||||||
|
the implementation dependent, but each hash is one byte (1B) in size, and
|
||||||
|
corresponds to an IF token, which is the index of the hash.
|
||||||
|
|
||||||
BUZBEE's source, and the surrounding BIOS source is well commented, but a
|
BUZBEE's source, and the surrounding BIOS source is well commented, but a
|
||||||
general summary of the control flow is provided here.
|
general summary of the control flow is provided here.
|
||||||
|
134
src/buzbee.s
134
src/buzbee.s
@@ -42,11 +42,11 @@ BBVAR tagbbvar
|
|||||||
BUZBEE
|
BUZBEE
|
||||||
lbsr NEWLINE ; Setup the new input line and handle display.
|
lbsr NEWLINE ; Setup the new input line and handle display.
|
||||||
bsr INPLOOP ; Fill input buffer.
|
bsr INPLOOP ; Fill input buffer.
|
||||||
cmpy #$0000 ; No data?
|
cmpy #0 ; No data?
|
||||||
beq BUZBEE ; Try again...
|
beq BUZBEE ; Try again...
|
||||||
; TODO: Parse the input buffer into tokens
|
lbsr TOKENIZE ; Try to tokenize the input buffer
|
||||||
lbsr RUNIF
|
lbsr RUNIF ; Execute token buffer, handling any errors
|
||||||
bra BUZBEE
|
bra BUZBEE ; Repeat
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;
|
;;
|
||||||
@@ -58,7 +58,7 @@ BUZBEE
|
|||||||
; offset in the input buffer of the last char read.
|
; offset in the input buffer of the last char read.
|
||||||
INPLOOP
|
INPLOOP
|
||||||
jsr PINCHAR ; Try to read a char
|
jsr PINCHAR ; Try to read a char
|
||||||
cmpd #$0000 ; If no char keep waitin'
|
cmpd #0 ; If no char keep waitin'
|
||||||
beq INPLOOP
|
beq INPLOOP
|
||||||
bitb #UARTF_LSR_DR ; Is there a char in A?
|
bitb #UARTF_LSR_DR ; Is there a char in A?
|
||||||
beq NOCHAR@
|
beq NOCHAR@
|
||||||
@@ -101,7 +101,7 @@ HCR@
|
|||||||
HESC@
|
HESC@
|
||||||
lda #'^ ; Print a char that signifies that ESC was pressed
|
lda #'^ ; Print a char that signifies that ESC was pressed
|
||||||
jsr POUTCHAR
|
jsr POUTCHAR
|
||||||
ldy #$0000 ; On return we cmpy #$0000 and if eq then newline.
|
ldy #0 ; On return we cmpy #0 and if eq then newline
|
||||||
rts
|
rts
|
||||||
HBACKSPC@
|
HBACKSPC@
|
||||||
clrb ; Clear last char
|
clrb ; Clear last char
|
||||||
@@ -118,13 +118,13 @@ NEWLINE
|
|||||||
PZSTR PROMPTLINE ; Print prompt line
|
PZSTR PROMPTLINE ; Print prompt line
|
||||||
CLRIN ; Label to just clear input buffer without newline
|
CLRIN ; Label to just clear input buffer without newline
|
||||||
clra ; Init A and X
|
clra ; Init A and X
|
||||||
ldx #$0000
|
ldx #0
|
||||||
NEXT@
|
NEXT@
|
||||||
sta BBVAR.input,x ; Clear input buffer
|
sta BBVAR.input,x ; Clear input buffer
|
||||||
leax 1,x
|
leax 1,x
|
||||||
cmpx #BBIN_DEPTH
|
cmpx #BBIN_DEPTH
|
||||||
blo NEXT@
|
blo NEXT@
|
||||||
ldy #$0000 ; Reset buffer fill pointer
|
ldy #0 ; Reset buffer fill pointer
|
||||||
rts
|
rts
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@@ -143,24 +143,22 @@ PBYTE
|
|||||||
asra
|
asra
|
||||||
asra
|
asra
|
||||||
asra
|
asra
|
||||||
bsr NYB2HEX ; Print A
|
|
||||||
jsr POUTCHAR
|
|
||||||
tfr b,a ; Print B next
|
|
||||||
bsr NYB2HEX ; Print B
|
|
||||||
jsr POUTCHAR
|
|
||||||
puls b
|
|
||||||
rts
|
|
||||||
|
|
||||||
; Converts a nybble into a valid hex digit
|
|
||||||
; @param A: nybble to convert to a char
|
|
||||||
; @return A: resulting char
|
|
||||||
NYB2HEX
|
|
||||||
anda #$0F
|
anda #$0F
|
||||||
ora #'0 ; Add "0"
|
ora #'0 ; Add '0' to offset to digits
|
||||||
cmpa #$3A ; ":" "9"+1
|
cmpa #$3A ; Hex? ':' '9'+1
|
||||||
blo SKIP@
|
blo SKIPA@
|
||||||
adca #6 ; Add offset to "A" in ascii
|
adca #6 ; Hex offset
|
||||||
SKIP@
|
SKIPA@
|
||||||
|
jsr POUTCHAR ; Print char in A
|
||||||
|
andb #$0F
|
||||||
|
orb #'0 ; Add '0' to offset to digits
|
||||||
|
cmpb #$3A ; Hex? ':' '9'+1
|
||||||
|
blo SKIPB@
|
||||||
|
adcb #6 ; Hex offset
|
||||||
|
SKIPB@
|
||||||
|
tfr b,a ; Print char in B
|
||||||
|
jsr POUTCHAR
|
||||||
|
puls b ; Restore B
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Converts a hexadecimal sequence into a byte value
|
; Converts a hexadecimal sequence into a byte value
|
||||||
@@ -203,19 +201,77 @@ BADHEX@
|
|||||||
;;
|
;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
; Attempts to parse the input buffer into tokens depending on the command
|
||||||
|
TOKENIZE
|
||||||
|
ldd BBVAR.cchinput ; Do we have input to work with?
|
||||||
|
cmpd #4 ; Do we have even enough space for a string command
|
||||||
|
blo TOKFAIL@ ; No? GTFO
|
||||||
|
ldy #0 ; Initialize Y; used to track current position in BBVAR.input
|
||||||
|
ldx #0 ; Initialize X; used to track position in BBVAR.tokens
|
||||||
|
bsr SKIPTONEXTC ; Get the next non-whitespace char
|
||||||
|
bsr MKCMDSUM ; Hash the first four non-whitespace chars
|
||||||
|
bsr HASH2TOKEN ; Try to turn that hash into a proper token
|
||||||
|
bcs TOKFAIL@
|
||||||
|
bra STTOK@ ; Store token
|
||||||
|
NEXTHEX@ ; Next hex token
|
||||||
|
bsr SKIPTONEXTC ; Skip to next whitespace
|
||||||
|
ldd BBVAR.input,y ; Get hex value (two digits)
|
||||||
|
bsr HEX2BYT ; Convert hex value to byte value
|
||||||
|
STTOK@
|
||||||
|
sta BBVAR.tokens,x ; Store curent token
|
||||||
|
leax 1,x ; Advance to next token
|
||||||
|
cmpx #BBTOKENS_DEPTH ; Is this next token in bounds?
|
||||||
|
beq FULLBUF@ ; No? handle a full buffer
|
||||||
|
bra NEXTHEX@ ; Try to turn the next character into a hex value
|
||||||
|
FULLBUF@
|
||||||
|
PZSTR EM_FULLTOKBUF ; Print an error message
|
||||||
|
clrd ; Say we wrote no tokens
|
||||||
|
std BBVAR.cbtokens
|
||||||
|
rts
|
||||||
|
TOKFAIL@
|
||||||
|
PZSTR EM_TOKFAIL ; Print tokenization fail
|
||||||
|
clrd ; Say we wrote no tokens
|
||||||
|
std BBVAR.cbtokens
|
||||||
|
rts
|
||||||
|
|
||||||
|
; Converts a runtime command hash into a portable token. Command tokens are
|
||||||
|
; indexes into BBCHT, which is generated at compile-time
|
||||||
|
; @param A: runtime hash
|
||||||
|
; @return A: output token
|
||||||
|
; @return CC.C: set if error state, cleared otherwise
|
||||||
|
HASH2TOKEN
|
||||||
|
pshs x ; Preserve & init X; other routines in this group use it
|
||||||
|
ldx #0
|
||||||
|
NEXTHASH@
|
||||||
|
cmpa BBCHT,x ; Is this hash our hash?
|
||||||
|
beq THISHASH@ ; Yes? turn it into a token
|
||||||
|
leax 1,x ; Begin considering next hash
|
||||||
|
cmpx BBCHTC ; Is the next hash even in the table?
|
||||||
|
blo NEXTHASH@ ; Yes? try this next hash, No? fall through
|
||||||
|
PZSTR EM_BADHASH CALL; Print an error message to the user
|
||||||
|
puls x
|
||||||
|
orcc #1 ; Set CC.C to indicate error
|
||||||
|
rts
|
||||||
|
THISHASH@
|
||||||
|
puls x
|
||||||
|
andcc #$FE ; Clear CC.C to indicate success
|
||||||
|
rts
|
||||||
|
|
||||||
; Makes a hash of four chars in BBIN starting at offset X
|
; Makes a hash of four chars in BBIN starting at offset X
|
||||||
; @param X: offset in BBIN to read the four chars from
|
; @param Y: offset in BBIN to read the four chars from
|
||||||
; @return A: resulting hash
|
; @return A: resulting hash
|
||||||
|
; @return Y: offset after hash processing
|
||||||
MKCMDSUM
|
MKCMDSUM
|
||||||
pshs b
|
pshs b
|
||||||
ldb #4 ; Loop over four chars
|
ldb #4 ; Loop over four chars
|
||||||
clra ; Initialize accumulator
|
clra ; Initialize accumulator
|
||||||
NEXTC@
|
NEXTC@
|
||||||
suba BBVAR.input,x ; Subtract current char from accumulator
|
suba BBVAR.input,y ; Subtract current char from accumulator
|
||||||
leax 1,x ; Next char
|
leax 1,y ; Next char
|
||||||
decb ; Reduce count
|
decb ; Reduce count
|
||||||
cmpb #0 ; Are we at the end?
|
cmpb #0 ; Are we at the end?
|
||||||
bne NEXTC@ ; No? loop
|
bne NEXTC@ ; No? loop
|
||||||
|
puls b
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; Skips "whitespace" to the next semantic char
|
; Skips "whitespace" to the next semantic char
|
||||||
@@ -245,24 +301,15 @@ RUNIF
|
|||||||
beq NOTOK@
|
beq NOTOK@
|
||||||
ldx #0 ; Counting up from zero
|
ldx #0 ; Counting up from zero
|
||||||
lda BBVAR.tokens ; Load token
|
lda BBVAR.tokens ; Load token
|
||||||
NEXTHASH@
|
tfr a,b ; Get the index in D
|
||||||
cmpa BBCHT,x ; Is this hash our hash?
|
|
||||||
beq CALCPTR@ ; Yes? skip to next step to put ptr in x
|
|
||||||
leax 1,x ; Begin considering next hash
|
|
||||||
cmpx BBCHTC ; Is this the last byte?
|
|
||||||
blo NEXTHASH@ ; No? try next hash, Yes? fall through
|
|
||||||
PZSTR EM_BADHASH ; Print an error message
|
|
||||||
lbra IFHELP ; Proceed to call "HELP"
|
|
||||||
CALCPTR@
|
|
||||||
tfr x,d ; Swap into d to do a cheap multiply
|
|
||||||
asld ; Cheaply << to get *2, pointer size
|
asld ; Cheaply << to get *2, pointer size
|
||||||
tfr d,x ; Restore x from d and jump to function at index
|
tfr d,x ; Move to X so we can use indexed mode with the offset
|
||||||
jmp [BBCMDPTRTBL,x]
|
jmp [IFPTRTBL,x] ; Select IF
|
||||||
NOTOK@
|
NOTOK@
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; IF pointer table
|
; IF pointer table
|
||||||
BBCMDPTRTBL
|
IFPTRTBL
|
||||||
fdb IFCALL
|
fdb IFCALL
|
||||||
fdb IFHELP
|
fdb IFHELP
|
||||||
fdb IFPEEK
|
fdb IFPEEK
|
||||||
@@ -388,5 +435,8 @@ EM_TOKFAIL
|
|||||||
fcc "!!! Tokenization Failure !!!"
|
fcc "!!! Tokenization Failure !!!"
|
||||||
fcb $0D,$0A,$00
|
fcb $0D,$0A,$00
|
||||||
EM_BADHEX
|
EM_BADHEX
|
||||||
fcc "!!! Maleformed Hex Value !!!"
|
fcc "!!! Malformed Hex Value !!!"
|
||||||
|
fcb $0D,$0A,$00
|
||||||
|
EM_FULLTOKBUF
|
||||||
|
fcc "!!! Token Buffer Overrun !!!"
|
||||||
fcb $0D,$0A,$00
|
fcb $0D,$0A,$00
|
||||||
|
12
src/reset.s
12
src/reset.s
@@ -24,7 +24,7 @@ RESET
|
|||||||
CLRSTACK
|
CLRSTACK
|
||||||
; Initialize the system stack
|
; Initialize the system stack
|
||||||
clra ; Init A & X to zero out the stack
|
clra ; Init A & X to zero out the stack
|
||||||
ldx #$0000
|
ldx #0
|
||||||
NEXT@
|
NEXT@
|
||||||
sta STACK_BOTTOM,x ; Write a zero and progress to the next byte
|
sta STACK_BOTTOM,x ; Write a zero and progress to the next byte
|
||||||
leax 1,x
|
leax 1,x
|
||||||
@@ -36,18 +36,12 @@ BOOTSCR
|
|||||||
lda #13 ; 9600 baud
|
lda #13 ; 9600 baud
|
||||||
ldb #%11 ; 8N1
|
ldb #%11 ; 8N1
|
||||||
jsr INITUART ; Initialize serial console
|
jsr INITUART ; Initialize serial console
|
||||||
ldx #VERMSG ; Print version information
|
PZSTR VERMSG ; Print version information
|
||||||
jsr POUTZSTR
|
|
||||||
|
|
||||||
; Progress to POST
|
|
||||||
POST
|
|
||||||
jsr RAMTEST
|
|
||||||
|
|
||||||
; Hand off control to the BUZBEE monitor and print notification of leaving the
|
; Hand off control to the BUZBEE monitor and print notification of leaving the
|
||||||
; firmware
|
; firmware
|
||||||
ENTERMON
|
ENTERMON
|
||||||
ldx #TXTRUN
|
PZSTR TXTRUN
|
||||||
jsr POUTZSTR
|
|
||||||
jmp BUZBEE
|
jmp BUZBEE
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
Reference in New Issue
Block a user