1 ; -*- coding: utf-8 -*-
6 ;-------------------------------------------------------------------------------
7 ; RETURN from high level word
8 ;-------------------------------------------------------------------------------
10 ; https://forth-standard.org/standard/core/EXIT
11 ; EXIT -- exit a colon definition; CALL #EXIT performs ASMtoFORTH (10 cycles)
12 ; JMP #EXIT performs EXIT
13 MOV @RSP+,IP ; 2 pop previous IP (or next PC) from return stack
14 MOV @IP+,PC ; 4 = NEXT
17 ;https://forth-standard.org/standard/core/SPACE
18 ;C SPACE -- output a space
25 ;https://forth-standard.org/standard/core/SPACES
26 ;C SPACES n -- output n spaces
36 JNZ SPACE ;25~ ==> 27~ by space ==> 2.963 MBds @ 8 MHz
38 SPACESNEXT2 MOV @PSP+,TOS ; -- drop n
43 ;https://forth-standard.org/standard/core/UMTimes
44 ;C UM* u1 u2 -- ud unsigned 16x16->32 mult.
46 UMSTAR MOV @PSP,&MPY ; Load 1st operand
47 MOV TOS,&OP2 ; Load 2nd operand
48 MOV &RES0,0(PSP) ; low result on stack
49 MOV &RES1,TOS ; high result in TOS
52 ;https://forth-standard.org/standard/core/MTimes
53 ;C M* n1 n2 -- dlo dhi signed 16*16->32 multiply
63 ;https://forth-standard.org/standard/core/MTimes
64 ;C M* n1 n2 -- dlo dhi signed 16*16->32 multiply
66 MSTAR MOV TOS,S ; TOS= n2
67 XOR @PSP,S ; S contains sign of result
68 CMP #0,0(PSP) ; n1 > -1 ?
70 XOR #-1,0(PSP) ; no : n1 --> u1
72 u1n2MSTAR CMP #0,TOS ; n2 <= -1 ?
74 XOR #-1,TOS ; y: n2 --> u2
76 u1u2MSTAR PUSHM #2,IP ; PUSHM IP,S
78 .word UMSTAR ; UMSTAR use S,T,W,X,Y
80 POPM #2,IP ; POPM S,IP
81 CMP #0,S ; result > -1 ?
83 XOR #-1,0(PSP) ; no : ud --> d
91 ;https://forth-standard.org/standard/core/UMDivMOD
92 ; UM/MOD udlo|udhi u1 -- r q unsigned 32/16->r16 q16
94 UMSLASHMOD PUSH #DROP ;3 as return address for MU/MOD
97 ;https://forth-standard.org/standard/core/SMDivREM
98 ;C SM/REM d1lo d1hi n2 -- n3 n4 symmetric signed div
100 SMSLASHREM MOV TOS,S ;1 S=divisor
101 MOV @PSP,T ;2 T=rem_sign
102 CMP #0,TOS ;1 n2 >= 0 ?
103 JGE d1u2SMSLASHREM ;2 yes
106 d1u2SMSLASHREM ; -- d1 u2
107 CMP #0,0(PSP) ;3 d1hi >= 0 ?
108 JGE ud1u2SMSLASHREM ;2 yes
109 XOR #-1,2(PSP) ;4 d1lo
110 XOR #-1,0(PSP) ;4 d1hi
111 ADD #1,2(PSP) ;4 d1lo+1
112 ADDC #0,0(PSP) ;4 d1hi+C
113 ud1u2SMSLASHREM ; -- ud1 u2
114 PUSHM #2,S ;4 PUSHM S,T
117 POPM #2,S ;4 POPM T,S
118 CMP #0,T ;1 -- ur uq T=rem_sign>=0?
119 JGE SMSLASHREMnruq ;2 yes
123 XOR S,T ;1 S=divisor T=quot_sign
124 CMP #0,T ;1 -- nr uq T=quot_sign>=0?
125 JGE SMSLASHREMnrnq ;2 yes
128 SMSLASHREMnrnq ; -- nr nq S=divisor
129 MOV @IP+,PC ;4 34 words
131 ;https://forth-standard.org/standard/core/FMDivMOD
132 ;C FM/MOD d1 n1 -- r q floored signed div'n
137 FMSLASHMOD1 .word $+2 ; -- remainder quotient S=divisor
140 CMP #1,TOS ; quotient < 1 ?
142 QUOTLESSONE ADD S,0(PSP) ; add divisor to remainder
143 SUB #1,TOS ; decrement quotient
148 ;https://forth-standard.org/standard/core/NEGATE
149 ;C NEGATE x1 -- x2 two's complement
153 ;https://forth-standard.org/standard/core/ABS
154 ;C ABS n1 -- +n2 absolute value
160 ;https://forth-standard.org/standard/core/Times
161 ;C * n1 n2 -- n3 signed multiply
164 .word MSTAR,DROP,EXIT
166 ;https://forth-standard.org/standard/core/DivMOD
167 ;C /MOD n1 n2 -- n3 n4 signed divide/rem'dr
170 .word TOR,STOD,RFROM,FMSLASHMOD,EXIT
172 ;https://forth-standard.org/standard/core/Div
173 ;C / n1 n2 -- n3 signed divide
176 .word TOR,STOD,RFROM,FMSLASHMOD,NIP,EXIT
178 ;https://forth-standard.org/standard/core/MOD
179 ;C MOD n1 n2 -- n3 signed remainder
182 .word TOR,STOD,RFROM,FMSLASHMOD,DROP,EXIT
184 ;https://forth-standard.org/standard/core/TimesDivMOD
185 ;C */MOD n1 n2 n3 -- n4 n5 n1*n2/n3, rem"
188 .word TOR,MSTAR,RFROM,FMSLASHMOD,EXIT
190 ;https://forth-standard.org/standard/core/TimesDiv
191 ;C */ n1 n2 n3 -- n4 n1*n2/n3
194 .word TOR,MSTAR,RFROM,FMSLASHMOD,NIP,EXIT
198 ;https://forth-standard.org/standard/core/ALIGNED
199 ;C ALIGNED addr -- a-addr align given addr
205 ;https://forth-standard.org/standard/core/ALIGN
206 ;C ALIGN -- align HERE
208 ALIGNN BIT #1,&DDP ; 3
212 ;https://forth-standard.org/standard/core/CHARS
213 ;C CHARS n1 -- n2 chars->adrs units
217 ;https://forth-standard.org/standard/core/CHARPlus
218 ;C CHAR+ c-addr1 -- c-addr2 add char size
223 ;https://forth-standard.org/standard/core/CELLS
224 ;C CELLS n1 -- n2 cells->adrs units
229 ;https://forth-standard.org/standard/core/CELLPlus
230 ;C CELL+ a-addr1 -- a-addr2 add cell size
235 ;----------------------------------------------------------------------
237 ;----------------------------------------------------------------------
239 ; https://forth-standard.org/standard/core/StoD
240 ; S>D n -- d single -> double prec.
246 ; https://forth-standard.org/standard/core/TwoFetch
247 ; 2@ a-addr -- x1 x2 fetch 2 cells ; the lower address will appear on top of stack
254 ; https://forth-standard.org/standard/core/TwoStore
255 ; 2! x1 x2 a-addr -- store 2 cells ; the top of stack is stored at the lower adr
257 TWOSTORE MOV @PSP+,0(TOS)
262 ; https://forth-standard.org/standard/core/TwoDROP
263 ; 2DROP x1 x2 -- drop 2 cells
269 ; https://forth-standard.org/standard/core/TwoSWAP
270 ; 2SWAP x1 x2 x3 x4 -- x3 x4 x1 x2
272 MOV @PSP,W ; -- x1 x2 x3 x4 W=x3
273 MOV 4(PSP),0(PSP) ; -- x1 x2 x1 x4
274 MOV W,4(PSP) ; -- x3 x2 x1 x4
275 MOV TOS,W ; -- x3 x2 x1 x4 W=x4
276 MOV 2(PSP),TOS ; -- x3 x2 x1 x2 W=x4
277 MOV W,2(PSP) ; -- x3 x4 x1 x2
280 ; https://forth-standard.org/standard/core/TwoOVER
281 ; 2OVER x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2
283 SUB #4,PSP ; -- x1 x2 x3 x x x4
284 MOV TOS,2(PSP) ; -- x1 x2 x3 x4 x x4
285 MOV 8(PSP),0(PSP) ; -- x1 x2 x3 x4 x1 x4
286 MOV 6(PSP),TOS ; -- x1 x2 x3 x4 x1 x2
289 ;https://forth-standard.org/standard/core/CFetch
290 ; C@ c-addr -- char fetch char from memory
292 CFETCH MOV.B @TOS,TOS ;2
295 ;https://forth-standard.org/standard/core/CStore
296 ; C! char c-addr -- store char in memory
298 CSTORE MOV.B @PSP+,0(TOS) ;4
303 ;https://forth-standard.org/standard/core/CComma
304 ; C, char -- append char
312 ;https://forth-standard.org/standard/core/AND
313 ;C AND x1 x2 -- x3 logical AND
318 ;https://forth-standard.org/standard/core/OR
319 ;C OR x1 x2 -- x3 logical OR
324 ;https://forth-standard.org/standard/core/XOR
325 ;C XOR x1 x2 -- x3 logical XOR
330 ;https://forth-standard.org/standard/core/INVERT
331 ;C INVERT x1 -- x2 bitwise inversion
336 ;https://forth-standard.org/standard/core/LSHIFT
337 ;C LSHIFT x1 u -- x2 logical L shift u places
340 AND #1Fh,TOS ; no need to shift more than 16
348 ;https://forth-standard.org/standard/core/RSHIFT
349 ;C RSHIFT x1 u -- x2 logical R shift u places
352 AND #1Fh,TOS ; no need to shift more than 16
354 RSH_1 BIC #1,SR ; CLRC
361 ;https://forth-standard.org/standard/core/TwoTimes
362 ;C 2* x1 -- x2 arithmetic left shift
367 ;https://forth-standard.org/standard/core/TwoDiv
368 ;C 2/ x1 -- x2 arithmetic right shift
373 ;https://forth-standard.org/standard/core/MAX
374 ;C MAX n1 n2 -- n3 signed maximum
376 MAX CMP @PSP,TOS ; n2-n1
381 ;https://forth-standard.org/standard/core/MIN
382 ;C MIN n1 n2 -- n3 signed minimum
384 MIN CMP @PSP,TOS ; n2-n1
389 ;https://forth-standard.org/standard/core/PlusStore
390 ;C +! n/u a-addr -- add to memory
392 PLUSSTORE ADD @PSP+,0(TOS)
396 ;https://forth-standard.org/standard/core/CHAR
397 ;C CHAR -- char parse ASCII character
400 .word FBLANK,WORDD,ONEPLUS,CFETCH,EXIT
402 ;https://forth-standard.org/standard/core/BracketCHAR
403 ;C [CHAR] -- compile character literal
404 FORTHWORDIMM "[CHAR]" ; immediate
410 ;https://forth-standard.org/standard/core/FILL
411 ;C FILL c-addr u char -- fill memory with char
413 FILL MOV @PSP+,X ; count
414 MOV @PSP+,W ; address
417 FILL_1 MOV.B TOS,0(W) ; store char in memory
421 FILL_X MOV @PSP+,TOS ; pop new TOS
424 ;https://forth-standard.org/standard/core/HEX
429 ;https://forth-standard.org/standard/core/DECIMAL
431 DECIMAL MOV #10,&BASE
434 ; https://forth-standard.org/standard/core/HERE
435 ; HERE -- addr returns memory ptr
439 ;https://forth-standard.org/standard/core/p
440 ;C ( \ -- paren ; skip input until )
441 FORTHWORDIMM "\40" ; immediate
443 .word lit,')',WORDD,DROP,EXIT
445 ;https://forth-standard.org/standard/core/Dotp
446 ; .( \ -- dotparen ; type comment immediatly.
447 FORTHWORDIMM ".\40" ; immediate
448 DOTPAREN MOV #0,&CAPS
452 .word FBLANK,LIT,CAPS,STORE
455 ;https://forth-standard.org/standard/core/J
456 ;C J -- n R: 4*sys -- 4*sys
457 ;C get the second loop index
459 JJ SUB #2,PSP ; make room in TOS
461 MOV 4(RSP),TOS ; index = loopctr - fudge
465 ;https://forth-standard.org/standard/core/UNLOOP
466 ;UNLOOP -- R: sys1 sys2 -- drop loop parms
471 ;https://forth-standard.org/standard/core/LEAVE
472 ;C LEAVE -- L: -- adrs
473 FORTHWORDIMM "LEAVE" ; immediate
474 LEAV MOV &DDP,W ; compile three words
475 MOV #UNLOOP,0(W) ; [HERE] = UNLOOP
476 MOV #BRAN,2(W) ; [HERE+2] = BRAN
477 ADD #6,&DDP ; [HERE+4] = After LOOP adr
481 MOV W,0(X) ; leave HERE+4 on LEAVEPTR stack
484 ;https://forth-standard.org/standard/core/RECURSE
485 ;C RECURSE -- recurse to current definition (compile current definition)
486 FORTHWORDIMM "RECURSE" ; immediate
492 ; https://forth-standard.org/standard/core/toBODY
493 ; >BODY -- addr leave BODY of a CREATEd word; also leave default ACTION-OF primary DEFERred word
498 ;https://forth-standard.org/standard/core/SOURCE
499 ;C SOURCE -- adr u of current input buffer
504 MOV &SOURCE_ORG,0(PSP)
507 ;https://forth-standard.org/standard/core/STATE
508 ;C STATE -- a-addr holds compiler state
511 .word STATE ; VARIABLE address in RAM space
513 ;https://forth-standard.org/standard/core/BASE
514 ;C BASE -- a-addr holds conversion radix
517 .word BASE ; VARIABLE address in RAM space
519 ;https://forth-standard.org/standard/core/toIN
520 ;C >IN -- a-addr holds offset in input stream
523 .word TOIN ; VARIABLE address in RAM space
525 ;https://forth-standard.org/standard/core/PAD
531 ; https://forth-standard.org/standard/core/TO
532 ; TO name Run-time: ( x -- )
533 ; Assign the value x to named VALUE.
538 ; https://forth-standard.org/standard/core/VALUE
539 ; ( x "<spaces>name" -- ) define a Forth VALUE
540 ; Skip leading space delimiters. Parse name delimited by a space.
541 ; Create a definition for name with the execution semantics defined below,
542 ; with an initial value equal to x.
544 ; name Execution: ( -- x )
545 ; Place x on the stack. The value of x is that given when name was created,
546 ; until the phrase x TO name is executed, causing a new value of x to be assigned to name.
555 MOV @TOS,TOS ; execute Fetch
557 VALUENEXT BIC #UF9,SR ; clear 'TO' flag
558 MOV @PSP+,0(TOS) ; 4 execute Store