• 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ónceaa83536f598f3acf6f1870a131adc21a6c8eda (tree)
Tiempo2014-03-13 19:27:33
AutorJoel Matthew Rees <reiisi@user...>
CommiterJoel Matthew Rees

Log Message

Mostly work on the memory map, getting the various allocation regions defined and bounded for testing.

Cambiar Resumen

Diferencia incremental

--- a/context.inc
+++ b/context.inc
@@ -33,8 +33,12 @@
3333
3434 .cpu sh3
3535
36-; For huge things, like U/ (USLASH) might be cut in half and repeated or something.
37-PRIORITY_SIZE: .DEFINE "1"
36+; For huge things, like U/ (USLASH),
37+; which might be cut in half and repeated or something. But probably not.
38+; PRIORITY_SIZE: .DEFINE "1"
39+
40+; Uncomment this if building for ROM:
41+; BUILD_FOR_ROM: .DEFINE "1"
3842
3943 ; Comment this out when all forward references are resolved,
4044 ; and test stuff is no longer needed.
@@ -94,13 +98,26 @@ BYTE_hHI_bHI: .equ MSBYTEinNAT
9498 ; ******************************************************************************
9599
96100
101+; ******************************************************************************
102+; Setting up the overall memory map:
103+;
97104 ; The SH-3 has modern dev tools, so we don't have to pay much attention
98-; to memory layout,
99-; but we do want to keep the following virtual map in mind:
100-
105+; to memory layout.
106+;
107+; But we do need a map to work with.
108+;
109+; By tradition, the start of object code contained jumps to the initialization code:
110+; COLD entry point (4 byte jump) and
111+; WARM entry point (4 byte jump), followed by the
112+; Init constants table (about 20 natural-width entries).
113+;
114+; The init constants would be followed by the dictionary,
115+; usually starting with the inner interpreter,
116+; and proceeding to higher-level stuff:
117+;
101118 ; ------------
102119 ; low address:
103-; JMP to start (But, no. Handled through the reset code.)
120+; JMP to start (But maybe handled through the reset code?)
104121 ;
105122 ; Global constants table
106123 ;
@@ -118,7 +135,116 @@ BYTE_hHI_bHI: .equ MSBYTEinNAT
118135 ;
119136 ; high address of ROMmable part
120137 ; -----------------------------
138+;
139+; If the object were ROMmable, at the end of the object code (ROM image)
140+; there would be a non-linked definition of "FORTH"
141+; to be copied to RAM, and the RAM part of the dictionary would link to that.
142+;
143+; In modern processors, ROM can be placed above or below RAM,
144+; so we shouldn't concern ourselves too much about where it is
145+; (or even what the map looks like within it).
146+;
147+; What concerns us is the RAM map, which is traditionally not well defined.
148+;
149+; These are the large areas of memory which we need to specify allocation for:
150+;
151+; ------------------------------------------------------------------------------
152+; Prebuilt dictionary (potentially ROMmable).
153+;
154+; Run-time dictionary (starts with the "FORTH" entry).
155+; The un-allocated area of the run-time dictionary
156+; is used as a general purpose text buffer.
157+;
158+; Parameter stack.
159+; fig-FORTH had this growing down towards the dictionary,
160+; which we now know is an invitation for attacks.
161+;
162+; Terminal line input buffer.
163+;
164+; Return, or flow-of-control stack.
165+; fig-FORTH had this growing down toward the input buffer,
166+; which, again, we now know is a recipe for vulnerabilities.
167+;
168+; Per-USER variable table(s).
169+;
170+; Disk buffers.
171+;
172+; ******************************************************************************
173+; The 6800 model modified the map to match customary memory use on the 6800:
174+;
175+; The bottom 128 bytes or so of memory in a 6800 were generally RAM,
176+; because of the direct-page fast-addressing mode.
177+; (ROM at the bottom might have made more sense,
178+; to deal with small integers mistakenly used as pointers.)
179+;
180+; From 0x80 to 0xff was also in the direct page range,
181+; but might be ROM, for fast access to constants.
182+; (And, beginning with the 6801, IIRC, heavily used routines.)
183+;
184+; From 0x100 to 0x1000 might not be populated, or might have RAM.
185+;
186+; The very top of memory, 0xF000 to 0xFFFF, was often populated
187+; with a monitor (debug/BIOS) ROM, to allow the reset and interupt vectors
188+; to be easily read out of ROM.
189+;
190+; The 6800 fig-FORTH model used the following map:
191+;
192+; ------------------------------------------------------------------------------
193+;
194+; 0x00E0: Scratch pad RAM (substitute for CPU temporary registers).
195+; 0x00F0: The virtual machine registers (IP, SP, RP, W).
196+; ...
197+; 0x0100: Run-time dictionary
198+; ...
199+; Parameter stack
200+; 0x0F30: Terminal input buffer
201+; ...
202+; Return stack
203+; 0x1000: Pre-built (ROMmable) dictionary
204+; Including COLD and WARM entry jumps and initialization table at the front.
205+; ...
206+; 0x3000: disk buffers (4*128)
207+; ...
208+; 0x3210: RAM disk (very small)
209+; ...
210+; 0x3FFF: End of RAM
211+;
212+; So, ....
213+;
214+; ******************************************************************************
215+; Some general limits to build within:
216+
217+; Small while debugging, so we don't have to hunt too far.
218+RUNTIME_DICTIONARY_SIZE: .equ h'1000
219+
220+; Small while debugging, so we don't have to hunt too far.
221+PARAMETER_STACK_SIZE: .equ h'60
121222
223+; Keep it small while debugging.
224+CONTROL_STACK_SIZE: .equ h'60
225+
226+; Something to help avoid things bumping into things.
227+ALLOC_GAP: .equ h'10
228+
229+; This can be bigger later.
230+TERMINAL_INPUT_BUFFER_SIZE: .equ h'100
231+
232+; Well, maybe we'll get this far some day.
233+N_USERS: .equ 8
234+
235+; This can be bigger later, too.
236+DISK_BUFFER_SIZE: .equ h'100
237+DISK_BUFFER_RECORD_SIZE: .equ 2*NATURAL_SIZE+DISK_BUFFER_SIZE
238+DISK_BUFFER_COUNT: .equ 4
239+
240+; RAM disk could be useful
241+; even after the full system is running with real (flash?) disks.
242+; So could a "ROM" disk with initial error messages. Maybe. Hmm. Anyway.
243+RAM_DISK_SIZE: .equ h'8000
244+
245+
246+; ******************************************************************************
247+; Mapping the virtual machine registers:
122248
123249 ; r0 must be used for many intermediate values.
124250 ; r0 -- r7 are bank-switched on interrupt.
@@ -146,11 +272,12 @@ fIP: .reg r5 ; virtual Instruction Pointer
146272 ; Defined symbols (objects/routines) are called "WORDs" in classic FORTH.
147273 fW: .reg r4 ; currently executing Word definition pointer
148274 ;
149-; By keeping the FORTH model in registers
150-; that the SH3 bank-switches out during interrupts,
275+; By keeping the FORTH model in banked registers
276+; that the SH3 switches out during interrupts,
151277 ; we can save a lot of time during interrupt processing.
152278
153279
280+; ******************************************************************************
154281 ; Structure of the per-USER variables table:
155282 .section usertable, dummy
156283 .org 0
@@ -215,7 +342,6 @@ IOSTAT: .equ $-UORIG
215342 UTABLESZ: .equ $-UORIG
216343
217344
218-
219345 ; Structure of the symbol table entry:
220346 ; Length byte of the symbol name (NFA)
221347 ; high bit set to flag the start byte
--- a/evaluator.inc
+++ b/evaluator.inc
@@ -500,6 +500,22 @@ myTOGGLE: .DEFINE "1"
500500 HIHEADER PTRWIDTH, PTRWIDTH, DOCON
501501 .data.l NATURAL_SIZE
502502
503+; These should be linear arrays, but there is no linear array in fig-FORTH model.
504+; NBYTEORDER ( --- u )
505+; Offsets of bytes in natural word, high byte is byte 0.
506+; Access as byte array of length NWIDTH.
507+; Not part of the fig-FORTH model, should have been.
508+; HIHEADER NBYTEORDER, NBYTEORDER, DOCON
509+; .data.l h'00010203
510+;
511+; PBYTEORDER ( --- u )
512+; Offsets of bytes in address/pointer, high byte is byte 0.
513+; Access as byte array of length PTRWIDTH.
514+; Not part of the fig-FORTH model, should have been.
515+; HIHEADER PBYTEORDER, PBYTEORDER, DOCON
516+; .data.l h'00010203
517+; But we can define them high-level, so hold them off until we need them.
518+
503519 ; BL ( --- u )
504520 HIHEADER BL, BL, DOCON
505521 .data.l " " ; ascii blank
--- a/initialize.inc
+++ b/initialize.inc
@@ -39,7 +39,7 @@
3939
4040 HEADER COLD, CENT
4141 ; WENT will also move, eventually.
42-WENT:
42+_fWENT:
4343 mov.l #PER_USER, fUP
4444 ;
4545 ; Eventually want to initialize these from the COLD_PARAMETERS table --
--- a/inout.inc
+++ b/inout.inc
@@ -116,3 +116,46 @@
116116
117117
118118
119+; FIRST ( --- adr ) The base of the disk buffer space.
120+; Returns the address of the lowest disk block buffer.
121+;
122+ HIHEADER FIRST, FIRST, DOCON
123+ .data.l DISK_BUFFERS
124+
125+
126+; LIMIT ( --- adr ) The limit of the disk buffer space.
127+; Returns the address one beyond the highest disk block buffer.
128+; In many fig FORTHs, this would mark the end of system memory.
129+; Not so in this SH-3 implementation.
130+;
131+ HIHEADER LIMIT, LIMIT, DOCON
132+ .data.l DISK_BUFFERS_END
133+
134+
135+; B/BUF ( --- size ) The size, in bytes, of a buffer.
136+; Bytes per buffer, or the size of a disk block.
137+;
138+ HIHEADER "B/BUF", BBUF, DOCON
139+ .data.l DISK_BUFFER_SIZE
140+
141+
142+
143+
144+; B/SCR ( --- count ) The size, in buffers, of a screen.
145+; Blocks per screen.
146+; A screen is the traditional unit of disk space in the old FORTH.
147+;
148+; It's a good rule-of-thumb limit on the size of a word definition,
149+; named for the size of a useable small screen --
150+; 16 lines, 64 columns in 20x80.
151+;
152+; Many traditional FORTH text editors organized the screen this way.
153+;
154+ HIHEADER "B/SCR", BSCR, DOCON
155+ .data.l DISK_BUFFER_COUNT
156+
157+
158+
159+
160+
161+
--- a/main.src
+++ b/main.src
@@ -33,7 +33,14 @@
3333 .include "context.inc"
3434
3535
36- .section main, code, locate=h'8c000000
36+; We may have time to move this to flash ROM at h'a0000000 ?
37+ .AIFDEF BUILD_FOR_ROM
38+PREBUILT_DICTIONARY_BASE: .equ h'a0000000
39+ .AELSE
40+PREBUILT_DICTIONARY_BASE: .equ h'8c000000
41+ .AENDI
42+
43+ .section main, code, locate=PREBUILT_DICTIONARY_BASE
3744
3845 .org $
3946
@@ -42,16 +49,19 @@
4249 ;***************************
4350 ; 0 offset into the ROMmable code
4451 ORIG:
45- mov.l #_fCENT, r0
46- jmp @r0
52+ mov.l @(_iCENT-$-NATURAL_SIZE,PC), r0 ; Cold boot, initializes everything.
53+ jmp @r0
54+ nop
55+ nop
56+; Wouldn't hurt to uselessly load the warm entry point as we go,
57+; but we'll assume that the offsets double for 32 bit addressing CPUs.
4758 ;***************************
4859 ;** W A R M E N T R Y **
4960 ;***************************
5061 ;
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
62+ mov.l @(_iWENT-$-NATURAL_SIZE,PC), r0 ; warm-start code, keeps current dictionary intact
5463 jmp @r0
64+ nop ; Can't avoid this no-op.
5565 nop
5666 ;
5767 ;*
@@ -59,7 +69,7 @@ ORIG:
5969 ;*
6070 ; All of this is essentially place-holder values:
6171 COLD_PARAMETERS:
62- .data.l "SH-3" ; cpu
72+ .data.l "SH-3" ; cpu in revision slot.
6373 .data.l 0 ; revision
6474 .data.l 0 ; topmost word in FORTH vocabulary
6575 BACKSP:
@@ -70,19 +80,25 @@ SINIT:
7080 .data.l fSP_BASE ; ORIG-$210 ; initial top of data stack
7181 RINIT:
7282 .data.l fRP_BASE ; ORIG-$10 ; initial top of return stack
73- .data.l fSP_LIMIT-h'200 ; ORIG-$200 ; terminal input buffer
83+ .data.l TERMINAL_INPUT_BUFFER ; ORIG-$200 ; terminal input buffer
7484 .data.l 31 ; initial name field width
7585 .data.l 0 ; initial warning mode (0 = no disc)
7686 FENCIN:
77- .data.l fSP_LIMIT-h'400 ; REND ; initial fence
87+ .data.l REND ; initial fence
7888 DPINIT:
79- .data.l fSP_LIMIT-h'400 ; REND ; cold start value for DP
89+ .data.l REND ; cold start value for DP
8090 VOCINT:
81- .data.l fSP_LIMIT-h'400 ; FORTH+8
91+ .data.l FORTH+4*NATURAL_SIZE
8292 COLINT:
8393 .data.l 132 ; initial terminal carriage width
8494 DELINT:
8595 .data.l 4 ; initial carriage return delay
96+
97+COLD_PARAMETER_SIZE: .equ $
98+_iCENT:
99+ .data.l _fCENT
100+_iWENT:
101+ .data.l _fWENT
86102 ;*
87103 ;****************************************************
88104 ;*
@@ -93,6 +109,7 @@ DELINT:
93109 ; Thus:
94110 ;
95111 .include "teststuff.inc"
112+
96113 .include "initialize.inc"
97114 .include "primitive.inc"
98115 .include "compiler.inc"
@@ -104,26 +121,115 @@ DELINT:
104121 .include "driver.inc"
105122
106123
107- .section user, data, locate=h'8c010000
124+;
125+; ****** Fix this later!
126+;
127+ HIHEADER FORTH, ROMFORTH, DODOES, MIMM
128+ .data.l h'81A0, _sTASK
129+ .data.l 0
130+ .sdata "Copyright Joel Rees, 2014. Parts Copyright David Lion and Forth Interest Group, 1979"
131+
132+ HIHEADER TASK, ROMTASK, DOCOL
133+ .data.l NOOP, SEMIS
134+ERAM:
135+ .sdata "Joel Rees"
136+
137+
138+; The memory map will depart drastically from the fig-FORTH model for many reasons.
139+; The biggest is that a buffer and a stack share allocation space is a recipe for disaster.
140+; The other biggest reason is that we are no longer nearly so memory-constrained.
141+;
142+; Also, we want to clearly mark the ROMmable portion and separate it from stuff in RAM.
143+;
144+
145+
146+ .AIFDEF BUILD_FOR_ROM
147+RUNTIME_DICTIONARY_BASE: .equ h'8c000000
148+ .AELSE
149+ .align 4
150+RUNTIME_DICTIONARY_BASE: .equ $
151+ .AENDI
152+
153+
154+ .section dictionary, data, locate=RUNTIME_DICTIONARY_BASE
155+
156+; ****** Fix this later!
157+;
158+;* These definitions, up through the lable 'REND', are overwritten
159+;* at time of cold load and should have the same contents
160+;* as shown here:
161+;*
162+ HIHEADER FORTH, FORTH, DODOES, MIMM
163+ .data.l h'81A0, _sTASK
164+ .data.l 0
165+;
166+ .sdata "Copyright Joel Rees, 2014. Parts Copyright David Lion and Forth Interest Group, 1979"
167+
168+
169+ HIHEADER TASK, TASK, DOCOL
170+ .data.l NOOP, SEMIS
171+;
172+REND: .equ $ ; ( first empty location in dictionary )
173+;
174+ .res.b RUNTIME_DICTIONARY_SIZE-(REND-RUNTIME_DICTIONARY_BASE)
175+RUNTIME_DICTIONARY_END: .equ $
176+ .res.b ALLOC_GAP
177+ .align 4
178+RUNTIME_DICTIONARY_SPACE_END: .equ $
179+
180+
181+ .section user, data, locate=RUNTIME_DICTIONARY_SPACE_END
182+ .res.b ALLOC_GAP
108183 PER_USER: .equ $
109- .res.b UTABLESZ
110-
111- .section pstack, stack, locate=PER_USER+h'E000
184+ .res.b UTABLESZ*N_USERS
185+PER_USER_END: .equ $
186+ .res.b ALLOC_GAP
187+ .align 4
188+PER_USER_SPACE_END: .equ $
189+
190+
191+; Should be in per-user space, but it's not that way in the fig model:
192+ .section iobuffers, data, locate=PER_USER_SPACE_END
193+IO_SPACE_BASE: .equ $
194+ .res.b ALLOC_GAP
195+TERMINAL_INPUT_BUFFER: .equ $
196+ .res.b TERMINAL_INPUT_BUFFER_SIZE
197+TERMINAL_INPUT_BUFFER_END: .equ $
198+ .res.b ALLOC_GAP
199+ .align 4
200+ .res.b ALLOC_GAP
201+DISK_BUFFERS:
202+ .res.b DISK_BUFFER_RECORD_SIZE*DISK_BUFFER_COUNT
203+DISK_BUFFERS_END: .equ $
204+ .res.b ALLOC_GAP
205+ .align 4
206+ .res.b ALLOC_GAP
207+RAM_DISK_BASE:
208+ .res.b RAM_DISK_SIZE
209+RAM_DISK_END .equ $
210+ .res.b ALLOC_GAP
211+ .align 4
212+IO_SPACE_END: .equ $
213+
214+
215+ .section pstack, stack, locate=IO_SPACE_END
216+ .res.b ALLOC_GAP
112217 fSP_LIMIT: .equ $
113- .res.b h'1F00
218+ .res.b PARAMETER_STACK_SIZE
114219 fSP_BASE: .equ $
220+ .res.b ALLOC_GAP
221+ .align 4
222+fSP_END: .equ $
115223
116- .section rstack, stack, locate=h'8c01FF00
224+ .section rstack, stack, locate=fSP_END
225+ .res.b ALLOC_GAP
117226 fRP_LIMIT: .equ $
118- .res.b h'100
119-fRP_BASE: .equ $
120-
121- .section thevoid, dummy, locate=h'8c020000
122-OUTERSPACE: .equ $
123-
124-
125-
227+ .res.b CONTROL_STACK_SIZE
228+fRP_BASE: .equ h'8c020000-ALLOC_GAP
229+ .res.b ALLOC_GAP
230+ .align 4
231+fRP_END: .equ $
126232
127233
128234
129- .end
\ No newline at end of file
235+ .end
--- a/teststuff.inc
+++ b/teststuff.inc
@@ -56,6 +56,8 @@ COMPIL: .define "NOOP" ; used in SEMI
5656 SMUDGE: .define "NOOP" ; used in SEMI
5757 LBRAK: .define "NOOP" ; used in SEMI
5858 COMMA: .define "NOOP" ; used in CONSTANT
59+DODOES: .define "NOOP" ; used in ROMFORTH
60+DOVOC: .define "NOOP" ; used in ROMFORTH
5961 ; : .define "NOOP"
6062
6163