• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Implementing figFORTH on SH3 assembler


Commit MetaInfo

Revisióndea0f6fa9cda295be8b1307f79d40c74f0c478ee (tree)
Tiempo2014-03-10 21:11:07
AutorJoel Matthew Rees <reiisi@user...>
CommiterJoel Matthew Rees

Log Message

U/ fixed, more tests, added through definition 26 (or so?)

Cambiar Resumen

Diferencia incremental

--- a/evaluator.inc
+++ b/evaluator.inc
@@ -80,7 +80,7 @@
8080 sts.l mach, @-fSP
8181
8282
83-; Put this close to the test, so that we don't worry about the .AREPEAT
83+; Put this close to the test, so that we don't worry about the .AREPEAT length
8484 PUDIVover:
8585 mov.b #-1, r0 ; Or we could trap this, if we take the time to define traps.
8686 mov.l r0, @fSP
@@ -102,11 +102,12 @@ PUDIVover:
102102 ;
103103 ; ***** FORTH order for double wide is most-significant-first!
104104 ;
105- .AIFDEF PRIORITY_SIZE
106-DIVIDELENGTH: .DEFINE "16" ; repeat count * 2 cycles * count in r3
107- .AELSE
105+; Using a loop that messes with the carry won't work.
106+; .AIFDEF PRIORITY_SIZE
107+;DIVIDELENGTH: .DEFINE "16" ; repeat count * 2 cycles * count in r3
108+; .AELSE
108109 DIVIDELENGTH: .DEFINE "32" ; repeat count * 2 cycles
109- .AENDI
110+; .AENDI
110111 ;
111112 HEADER (UDIV), PUDIV
112113 mov.l @fSP+, r2 ; divisor
@@ -114,19 +115,19 @@ DIVIDELENGTH: .DEFINE "32" ; repeat count * 2 cycles
114115 cmp/hs r2, r0 ; zero divide or overflow?
115116 bt PUDIVover
116117 mov.l @fSP, r1 ; dividend low part
117- .AIFDEF PRIORITY_SIZE
118- mov.b #2, r3 ; Trade speed for size
119- .AENDI
118+; .AIFDEF PRIORITY_SIZE
119+; mov.b #2, r3 ; Trade speed for size
120+; .AENDI
120121 div0u ; Get the flags ready
121-PUDIVloop:
122+;PUDIVloop:
122123 .AREPEAT DIVIDELENGTH
123124 rotcl r1
124125 div1 r2, r0
125126 .AENDR
126- .AIFDEF PRIORITY_SIZE
127- dt r3 ; + 4 cycles * count in r3
128- bf PUDIVloop
129- .AENDI
127+; .AIFDEF PRIORITY_SIZE
128+; dt r3 ; + 4 cycles * count in r3
129+; bf PUDIVloop
130+; .AENDI
130131 rotcl r1
131132 rts
132133 mov.l r1, @fSP
@@ -143,26 +144,72 @@ PUDIVloop:
143144 ; ***** FORTH order for double wide is most-significant-first!
144145 ;
145146 HEADER U/, USLASH
147+ sts.l pr, @-fRP
146148 mov.l @(2*NATURAL_SIZE,fSP), r0
147149 mov.l r0, @-fSP
148150 mov.l @(2*NATURAL_SIZE,fSP), r0
149151 mov.l r0, @-fSP
150152 mov.l @(2*NATURAL_SIZE,fSP), r0
151153 bsr _fPUDIV
152- mov.l r0, @-fSP ; Save the divisor as we go.
154+ mov.l r0, @-fSP ; Push the divisor as we go.
153155 ;
154- mov.l @fSP+, fW ; grab the quotient
155- mov fW, r2
156- mov.l @fSP+, r1 ; grab the divisor
157- dmulu.l r1, r2 ; multiply quotient * divisor
156+ mov.l @fSP+, r0 ; grab the quotient
157+ mov.l @fSP+, r1 ; grab the divisor (unsigned double dividend still on stack)
158+ mov r0, fW ; hold the quotient
159+ and r1, r0
160+ cmp/eq #-1, r0 ; both max unsigned? (fW == r0 == max unsigned)
161+ bf USLASHremainder
162+ bra USLASHexitstore
163+ mov.l r0, @(NATURAL_SIZE,fSP) ; remainder (max) as we go
164+;
165+; The SH-3 manual recommends this approach
166+USLASHremainder:
167+ mov fW, r0
168+ dmulu.l r1, r0 ; multiply quotient by divisor
158169 sts.l macl, @-fSP
159170 bsr _fDSUB
160171 sts.l mach, @-fSP ; Store most significant as we go.
172+; The low part is in the right place for the remainder.
161173 ;
162- mov.l @fSP, r0 ; remainder
163- mov.l r0, @(NATURAL_SIZE,fSP)
174+USLASHexitstore:
175+ lds.l @fRP+, pr
164176 rts
165- mov.l fW, @fSP
177+ mov.l fW, @fSP ; Store the quotient as we go
178+
179+
180+; AND ( n1 n2 --- n )
181+; Bitwise and the top two integers.
182+;
183+ HEADER AND, AND
184+ mov.l @fSP+, r1
185+ mov.l @fSP, r0
186+ and r1, r0
187+ rts
188+ mov.l r0, @fSP
189+
190+
191+; OR ( n1 n2 --- n )
192+; Bitwise or.
193+;
194+ HEADER OR, OR
195+ mov.l @fSP+, r1
196+ mov.l @fSP, r0
197+ or r1, r0
198+ rts
199+ mov.l r0, @fSP
200+
201+
202+; XOR ( n1 n2 --- n )
203+; Bitwise exclusive or.
204+;
205+ HEADER XOR, XOR
206+ mov.l @fSP+, r1
207+ mov.l @fSP, r0
208+ xor r1, r0
209+ rts
210+ mov.l r0, @fSP
211+
212+
166213
167214
168215 ; + ( n1 n2 --- n1+n2 )
--- a/initialize.inc
+++ b/initialize.inc
@@ -37,6 +37,78 @@
3737 ; .section initialize, code
3838
3939
40+ HEADER COLD, CENT
41+; WENT will also move, eventually.
42+WENT:
43+ mov.l #PER_USER, fUP
44+;
45+; Eventually want to initialize these from the COLD_PARAMETERS table --
46+;
47+ mov.l #fSP_BASE, fSP
48+ mov.l fSP, @(XSPZER, fUP)
49+ mov.l #fRP_BASE, fRP
50+ mov.l fRP, @(XRZERO, fUP)
51+;
52+ mov #0, r0
53+ mov.l r0, @(XOUT,fUP) ; clear EMIT count.
54+;
55+ mov.l #TEST_THINGY, fIP
56+ mov.l #NEXT, r0
57+ jmp @r0
58+ nop
4059
4160
4261
62+;COLD FDB *+2
63+;CENT LDS #REND-1 top of destination
64+; LDX #ERAM top of stuff to move
65+;COLD2 DEX
66+; LDA A 0,X
67+; PSH A move TASK & FORTH to ram
68+; CPX #RAM
69+; BNE COLD2
70+;*
71+; LDS #XFENCE-1 put stack at a safe place for now
72+; LDX COLINT
73+; STX XCOLUM
74+; LDX DELINT
75+; STX XDELAY
76+; LDX VOCINT
77+; STX XVOCL
78+; LDX DPINIT
79+; STX XDP
80+; LDX FENCIN
81+; STX XFENCE
82+;
83+;
84+;WENT LDS #XFENCE-1 top of destination
85+; LDX #FENCIN top of stuff to move
86+;WARM2 DEX
87+; LDA A 0,X
88+; PSH A
89+; CPX #SINIT
90+; BNE WARM2
91+;*
92+; LDS SINIT
93+; LDX UPINIT
94+; STX UP init user ram pointer
95+; LDX #ABORT
96+; STX IP
97+; NOP Here is a place to jump to special user
98+; NOP initializations such as I/0 interrups
99+; NOP
100+;*
101+;* For systems with TRACE:
102+; LDX #00
103+; STX TRLIM clear trace mode
104+; LDX #0
105+; STX BRKPT clear breakpoint address
106+; JMP RPSTOR+2 start the virtual machine running !
107+;*
108+;* Here is the stuff that gets copied to ram :
109+;* at address $140:
110+;*
111+;* Thus, MAGIC numbers that initialize USE and PREV, magically! (JMR)
112+;* RAM FDB $3000,$3000,0,0
113+;RAM FDB $4000+132,$4000+132,0,0
114+;
--- a/main.src
+++ b/main.src
@@ -36,14 +36,58 @@
3636 .section main, code, locate=h'8c000000
3737
3838 .org $
39-COLD:
40- mov.l #PER_USER, fUP
41- mov.l #fSP_BASE, fSP
42- mov.l #fRP_BASE, fRP
43- mov.l #TEST_THINGY, fIP
44- mov.l #NEXT, r0
39+
40+;***************************
41+;** C O L D E N T R Y **
42+;***************************
43+; 0 offset into the ROMmable code
44+ORIG:
45+ mov.l #_fCENT, r0
46+ jmp @r0
47+;***************************
48+;** W A R M E N T R Y **
49+;***************************
50+;
51+; 4 offset into the ROMmable code
52+ nop ; Conveniently left over from the COLD entry point.
53+ mov.l #WENT, r0 ; warm-start code, keeps current dictionary intact
4554 jmp @r0
4655 nop
56+;
57+;*
58+;******* startup parmeters **************************
59+;*
60+; All of this is essentially place-holder values:
61+COLD_PARAMETERS:
62+ .data.l "SH-3" ; cpu
63+ .data.l 0 ; revision
64+ .data.l 0 ; topmost word in FORTH vocabulary
65+BACKSP:
66+ .data.l h'7f ; backspace character for editing
67+UPINIT:
68+ .data.l PER_USER ; UORIG ; initial user area
69+SINIT:
70+ .data.l fSP_BASE ; ORIG-$210 ; initial top of data stack
71+RINIT:
72+ .data.l fRP_BASE ; ORIG-$10 ; initial top of return stack
73+ .data.l fSP_LIMIT-h'200 ; ORIG-$200 ; terminal input buffer
74+ .data.l 31 ; initial name field width
75+ .data.l 0 ; initial warning mode (0 = no disc)
76+FENCIN:
77+ .data.l fSP_LIMIT-h'400 ; REND ; initial fence
78+DPINIT:
79+ .data.l fSP_LIMIT-h'400 ; REND ; cold start value for DP
80+VOCINT:
81+ .data.l fSP_LIMIT-h'400 ; FORTH+8
82+COLINT:
83+ .data.l 132 ; initial terminal carriage width
84+DELINT:
85+ .data.l 4 ; initial carriage return delay
86+;****************************************************
87+;*
88+
89+
90+
4791
4892 TEST_THINGY:
4993 .data.l LIT, 1
@@ -73,10 +117,36 @@ LOOP_THINGY:
73117 .data.l LIT, h'f0f0f0f0
74118 .data.l LIT, h'0f0f0f0f
75119 .data.l USTAR
120+ .data.l LIT, h'6A4C2E10, LIT, h'E2C4A68, DSUB, OR
121+ .data.l ZBRAN
122+ mTARGET UPRODUCTOK
123+ .data.l -5
124+UPRODUCTOK:
76125 .data.l LIT, h'10010000
77126 .data.l LIT, h'10011001
78127 .data.l LIT, h'10010
79128 .data.l USLASH
129+ .data.l AND, LIT, -1, SUB
130+ .data.l ZBRAN
131+ mTARGET UOVERFLOWOK
132+ .data.l -1
133+UOVERFLOWOK:
134+ .data.l LIT, h'1000fe76
135+ .data.l LIT, h'00000100
136+ .data.l LIT, h'00010010
137+ .data.l USLASH
138+ .data.l LIT, H'01000000
139+ .data.l SUB
140+ .data.l ZBRAN
141+ mTARGET UQUOTIENTOK
142+ .data.l 1
143+UQUOTIENTOK:
144+ .data.l LIT, H'fe76
145+ .data.l SUB
146+ .data.l ZBRAN
147+ mTARGET UREMAINDEROK
148+ .data.l 3
149+UREMAINDEROK:
80150 .data.l BRAN
81151 mTARGET TEST_THINGY
82152
--- a/primitive.inc
+++ b/primitive.inc
@@ -212,6 +212,45 @@ CMOVEdone:
212212 add #3*NATURAL_SIZE, fSP ; Drop the parameters as we go.
213213
214214
215+; SP@ ( --- adr )
216+; SPAT Fetch the parameter stack pointer (before it is pushed).
217+;
218+ HEADER SP@, SPAT
219+ rts
220+ mov.l fSP, @-fSP
221+
222+
223+; SP! ( whatever --- nothing )
224+; SPSTOR Initialize the parameter stack pointer from the USER variable
225+; S0. Effectively clears the stack.
226+;
227+ HEADER SP!, SPSTOR
228+ mov.l @(XSPZER,fUP), r0
229+ rts
230+ mov.l r0, fSP
231+
232+
233+; RP! ( whatever *** nothing )
234+; RPSTOR Initialize the return stack pointer from the USER variable R0.
235+; Effectively aborts all in process definitions, except the active
236+; one. An emergency measure, to be sure.
237+;
238+; Deferring to the glossary, rather than the 6800 model,
239+; and getting the initializer from the PER_USER table.
240+;
241+ HEADER RP!, RPSTOR
242+ mov.l @(XRZERO,fUP), r0
243+ rts
244+ mov.l r0, fSP
245+
246+
247+; ;S ( ip *** )
248+; SEMIS Pop IP from return stack (return from high-level definition).
249+; Can be used in a screen to force interpretion to terminate.
250+;
251+ HEADER ";S", SEMIS
252+ rts
253+ mov.l @fRP+, fIP
215254
216255
217256