File: forth.6801.asm

package info (click to toggle)
crasm 1.11-2
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 520 kB
  • sloc: ansic: 4,562; asm: 3,371; makefile: 50
file content (268 lines) | stat: -rw-r--r-- 4,294 bytes parent folder | download | duplicates (5)
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