269 lines
4.7 KiB
Plaintext
269 lines
4.7 KiB
Plaintext
# vim: set sw=3 tw=80:
|
|
|
|
include "include/memory-map.txt"
|
|
|
|
export read_char
|
|
export write_char
|
|
export newline
|
|
export read_hex
|
|
export write_hex
|
|
export puts
|
|
export end_of_monitor
|
|
|
|
import decode_base64
|
|
|
|
start_of_monitor:
|
|
_start:
|
|
jump main
|
|
|
|
include "lib/rs232.txt"
|
|
|
|
to_upper:
|
|
dup; immed 'a'; sub
|
|
jump .not_lc rel lt drop
|
|
dup; immed 'z'; sub
|
|
jump .not_lc rel gt drop
|
|
immed 32
|
|
sub return
|
|
.not_lc:
|
|
return
|
|
|
|
start_str: byte "Stack CPU Monitor Program" 10 0
|
|
prompt_str: byte "> " 0
|
|
error_str: byte "ERROR" 10 0
|
|
access_str: byte "ACCESS DENIED" 10 0
|
|
|
|
# Commands:
|
|
# READ addr
|
|
# WRITE value addr
|
|
# STORE start_addr
|
|
# CALL addr
|
|
main:
|
|
immed start_str
|
|
call puts
|
|
|
|
.prompt:
|
|
immed prompt_str
|
|
call puts
|
|
|
|
.getcmd:
|
|
call read_char
|
|
call to_upper
|
|
|
|
dup; immed ' '; sub
|
|
jump .ignore_sp rel eq drop
|
|
dup; immed 10; sub
|
|
jump .ignore_nl rel eq drop
|
|
|
|
dup; immed 'R'; sub
|
|
jump .read rel eq drop
|
|
dup; immed 'W'; sub
|
|
jump .write rel eq drop
|
|
dup; immed 'S'; sub
|
|
jump .store rel eq drop
|
|
dup; immed 'C'; sub
|
|
jump .call rel eq drop
|
|
dup; immed 35; sub
|
|
jump .comment rel eq drop
|
|
drop
|
|
|
|
.invalid:
|
|
call newline
|
|
immed error_str
|
|
call puts
|
|
jump .prompt
|
|
|
|
.ignore_sp:
|
|
jump .getcmd rel drop
|
|
.ignore_nl:
|
|
jump .prompt rel drop
|
|
|
|
.expect_char:
|
|
call read_char
|
|
call to_upper
|
|
sub
|
|
jump .correct rel eq drop
|
|
rdrop # Don't return to caller
|
|
jump .invalid rel
|
|
.correct:
|
|
return
|
|
|
|
.read:
|
|
drop #R
|
|
immed 'E'; call .expect_char rel
|
|
immed 'A'; call .expect_char rel
|
|
immed 'D'; call .expect_char rel
|
|
immed ' '; call .expect_char rel
|
|
call read_hex
|
|
immed 10; sub
|
|
jump ..invalid rel ne drop
|
|
load
|
|
call write_hex
|
|
call newline
|
|
jump .prompt rel
|
|
..invalid:
|
|
jump .invalid rel drop
|
|
|
|
.write:
|
|
drop #W
|
|
immed 'R'; call .expect_char rel
|
|
immed 'I'; call .expect_char rel
|
|
immed 'T'; call .expect_char rel
|
|
immed 'E'; call .expect_char rel
|
|
immed ' '; call .expect_char rel
|
|
call read_hex
|
|
immed ' '; sub
|
|
jump ..invalid1 rel ne drop
|
|
call read_hex
|
|
immed 10; sub
|
|
jump ..invalid2 rel ne drop
|
|
dup; immed start_of_monitor; sub
|
|
jump ..ok rel lt drop
|
|
dup; immed end_of_monitor; sub
|
|
jump ..denied rel lt drop
|
|
..ok:
|
|
store
|
|
jump .prompt
|
|
..invalid2:
|
|
drop
|
|
..invalid1:
|
|
jump .invalid rel drop
|
|
..denied:
|
|
drop2
|
|
immed access_str
|
|
call puts
|
|
jump .prompt
|
|
|
|
.store:
|
|
drop #S
|
|
immed 'T'; call .expect_char rel
|
|
immed 'O'; call .expect_char rel
|
|
immed 'R'; call .expect_char rel
|
|
immed 'E'; call .expect_char rel
|
|
immed ' '; call .expect_char rel
|
|
call read_hex
|
|
immed 10; sub
|
|
jump ..invalid rel ne drop
|
|
immed read_char
|
|
immed .store_byte
|
|
call decode_base64
|
|
drop2
|
|
jump .prompt rel
|
|
..invalid:
|
|
jump .invalid rel drop
|
|
|
|
.store_byte: # ( buffer byte -- buffer' )
|
|
over
|
|
store byte
|
|
immed 1
|
|
add return
|
|
|
|
.call:
|
|
drop #C
|
|
immed 'A'; call .expect_char rel
|
|
immed 'L'; call .expect_char rel
|
|
immed 'L'; call .expect_char rel
|
|
immed ' '; call .expect_char rel
|
|
call read_hex
|
|
immed 10; sub
|
|
jump ..invalid rel ne drop
|
|
call # expected: ( -- )
|
|
jump .prompt rel
|
|
..invalid:
|
|
jump .invalid rel drop
|
|
|
|
.comment:
|
|
immed 10; sub
|
|
jump .prompt eq drop
|
|
call read_char
|
|
jump .comment
|
|
|
|
|
|
# Reads an arbitrary number of hex digits, returning the last eight as
|
|
# a 32-bit integer along with the following non-hex character.
|
|
read_hex: # ( -- integer last_char )
|
|
immed 0
|
|
call read_char
|
|
call to_upper
|
|
dup; push
|
|
dup; immed '-'; sub
|
|
jump .after_first_char rel ne drop
|
|
.negative:
|
|
drop
|
|
.get_next_char:
|
|
call read_char
|
|
call to_upper
|
|
.after_first_char:
|
|
dup; immed '0'; sub
|
|
jump .not_hex rel lt drop
|
|
dup; immed '9'; sub
|
|
jump .number rel le drop
|
|
dup; immed 'A'; sub
|
|
jump .not_hex rel lt drop
|
|
dup; immed 'F'; sub
|
|
jump .letter rel le drop
|
|
.not_hex:
|
|
swap
|
|
pop; immed '-'; sub
|
|
jump .positive rel ne drop
|
|
immed 0; swap; sub
|
|
.positive:
|
|
swap
|
|
return
|
|
.number:
|
|
immed '0'; sub
|
|
.merge:
|
|
push
|
|
immed -4; rshift
|
|
pop
|
|
or
|
|
jump .get_next_char rel
|
|
.letter:
|
|
immed 55; sub # 55 = 'A'-10
|
|
jump .merge rel
|
|
|
|
# Displays integer as eight hex digits
|
|
write_hex: # ( integer -- )
|
|
immed 8
|
|
.loop:
|
|
push
|
|
dup
|
|
immed -4; rshift
|
|
push
|
|
immed 28; rshift
|
|
dup; immed 10; sub
|
|
jump .letter rel ge drop
|
|
immed '0'
|
|
.common:
|
|
add
|
|
call write_char
|
|
jump .next rel
|
|
.letter:
|
|
immed 10; sub
|
|
immed 'A'
|
|
jump .common rel
|
|
.next:
|
|
pop
|
|
pop
|
|
immed 1; sub
|
|
jump .loop rel gt
|
|
drop2
|
|
return
|
|
|
|
include "lib/base64.txt"
|
|
|
|
# ( addr -- ) [ addr -> null-terminated ASCII string ]
|
|
puts:
|
|
dup
|
|
load byte
|
|
jump .nul rel eq
|
|
call write_char
|
|
immed 1
|
|
add
|
|
jump puts rel
|
|
.nul:
|
|
drop2
|
|
return
|
|
|
|
end_of_monitor:
|