1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
|
;;; Author: Leon Bottou
;;; Public Domain.
; Beginnings of a forth kernel.
; Good test for macros.
;
; http://www.forth.org/
; http://www.zetetics.com/bj/papers/moving1.htm
cpu 6801
mlist off
page 0,132
* = $1000
smudge = 1<<7
precedence = 1<<6
keep = 1<<5
;; **********************************
;; -- create INVOCNAME, WORDNAME [, FLAGS]
;; Create a forth word WORDNAME into vocabulary INVOCNAME
;; This macro outputs the word header and defines useful labels
;; nfa_WORDNAME - address of header
;; lfa_WORDNAME - address of pointer to previous word in vocabulary
;; cfa_WORDNAME - address of executable data (just after header)
create macro
.start = *
if \3
nfa_\2 db .len | smudge | \3
else
nfa_\2 db .len | smudge
endc
asc "\2"
lfa_\2 dw lstw_\1
lstw_\1 = .start
cfa_\2 = *
.len = lfa_\2-nfa_\2
endm
;; **********************************
;; -- createvoc INVOCNAME,VOCNAME
;; Create a forth vocabulary VOCNAME in vocabulary INVOCNAME
;; This macro outputs the word header and defines useful labels
;; nfa_VOCNAME - address of word header
;; lfa_VOCNAME - address of pointer to previous word in voc INVOCNAME
;; cfa_VOCNAME - address of word executable data (jsr dovoc)
;; pfa_VOCNAME - address of vocabulary data for VOCNAME
;; lst_VOCNAME - address of pointer to last word in vocabulary
;; vlnk_VOCNAME - address of pointer to parent vocabulary.
;; The following symbol is modified whenever
;; a word is added into the vocabulary VOCNAME
;; lstw_VOCNAME - address of last word in vocabulary VOCNAME
;; until one calls endvoc
createvoc macro
lstw_\2 = pfa_\1
create \1,\2
jsr dovoc
pfa_\2 db smudge|1,' '
lst_\2 dw 0
vlnk_\2 dw pfa_\1
endm
;; **********************************
;; -- endvoc VOCNAME
;; Terminates definition of vocabulary VOCNAME
;; This sets the value of pointer at address lst_VOCNAME
;; No words should be added to the vocabulary.
endvoc macro
asc "LYB Forth."
.loc = *
* = lst_\1
dw lstw_\1
* = .loc
endm
;; **********************************
;; -- createforth
;; Creates the initial vocabulary named FORTH.
createforth macro
lstw_forth = 0
nfa_forth db 6|smudge
asc "forth"
lfa_forth = 0
cfa_forth jsr dovoc
pfa_forth db smudge|1,' '
lst_forth db 0
vlnk_forth dw 0
endm
;; **********************************
;; -- start, end, compile
;; These macros are used to define a forth word.
;; Usage:
;; create INVOCNAME, WORDNAME
;; start
;; compile WORDNAME
;; compile WORDNAME
;; ...
;; end
;; What about constants...
start macro
jsr docol
endm
end macro
dw endcol
endm
compile macro
dw cfa_\1
endm
;; **********************************
;; -- docol, endcol, next
;; The forth interpreter engine.
;; The forth data stack is the 6801 stack.
ip = $80 ; instruction pointer
rp = $82 ; return stack pointer
dp = $84 ; used to save the data stack pointer
;; docol - start interpreting a forth thread
docol ldd ip
ldx rp
std 0,x
dex
dex
stx rp
pulx
stx ip
ldx ,x
jmp ,x
;; endcol -- return from interpreting a forth thread
endcol ldx rp
inx
inx
stx rp
ldx ,x
inx
inx
stx ip
ldx ,x
jmp ,x
;; next -- return from assembly code primitive
next ldx ip
inx
inx
stx ip
ldx ,x
jmp ,x
;; dovoc -- undefined yet
dovoc rts
;; **********************************
;; Forth words
code
createforth
code
create forth,dup
pulx
pshx
pshx
jmp next
code
create forth,drop
pulx
jmp next
code
create forth,ndrop
pulx
.1 beq .2
pula
pula
dex
bra .1
.2 jmp next
code
create forth,swap
pulx
pula
pulb
pshx
pshb
psha
jmp next
code
create forth,pick
pula
pulb
lsrd
sts dp
addd dp
std dp
ldx dp
ldx ,x
pshx
jmp next
code
create forth,over
pula
pulb
pulx
pshx
pshb
psha
pshx
jmp next
code
create forth,rot
pulx
stx dp
pulx
pula
pulb
pshx
ldx dp
pshx
pshb
psha
jmp next
;; USER VOCABULARY
code
createvoc forth,uservoc
code
create uservoc,dupdrop,precedence
start
compile dup
compile drop
end
endvoc uservoc ; Terminate vocabulary USERVOC
endvoc forth ; Terminate vocabulry FORTH
|