I've been working with the fig-FORTH source from the archives. In my limited experience with it, I would have to say that something is not quite right with the source.
For example, I could not find where X was initialized any where before the first call. Next, several constants in the initialization code just did not appear to be right. The number of elements in the initialization data were more than the value loaded into Y for transferring the block from program memory to the user area.
Thus, I have made a few changes to the initialization code:
Code:
;
; equates giving memory assignments, machine
; registers, and disk parameters.
;
ssize =128 ; sector size in bytes
nbuf =8 ; number of buffers desired in ram
; (ssize*nbuf >= 1024 bytes)
sectr =800 ; sector per drive
; forcing high drive to zero
sectl =1600 ; sector limit for two drives
; of 800 per drive.
bmag =(ssize+4)*nbuf ; total buffer magnitude, in bytes
; expressed by (ssize+4)*nbuf
;
bos =$48 ; bottom of data stack, in zero-page.
tos =$B6 ; top of data stack, in zero-page.
n =tos+8 ; scratch workspace.
ip =n+8 ; interpretive pointer.
w =ip+3 ; code field pointer.
up =w+2 ; user area pointer.
xsave =up+2 ; temporary for x register.
;
tibx =$3F00 ; terminal input buffer of 84 bytes.
orig =$0400 ; origin of forth's dictionary.
mem =$3F00 ; top of assigned memory+1 byte.
uarea =mem-128 ; 128 bytes of user area
darea =uarea-bmag ; disk buffer space.
;
BACKSPACE =$08 ; backspace character (Default: $7F)
;
; monitor calls for terminal support
;
putch =$f82d ; output one ascii char. to term.
getch =$f818 ; input one ascii char. to term.
putcrlf =$f8a2 ; terminal return and line feed.
;
; monitor routines needed to trace.
;
putblank =$f8d5 ; print one blank
puthex2 =$f8b3 ; print accum as two hex numbers
;
getkey =$f8e8 ; wait for keystroke, no data returned
;
xw =$40 ; scratch reg. to next code field add
np =$42 ; scratch reg. pointing to name field
;
;
;
; from darea downward to the top of the dictionary is free
; space where the user's applications are compiled.
;
; boot up parameters. this area provides jump vectors
; to boot up code, and parameters describing the system.
;
code
ds orig+2
;
; user cold entry point
enter nop ; vector to cold entry
jmp (cold) ;
reentr nop ; user warm entry point
jmp warm ; vector to warm entry
initblk dw $0004 ; 6502 in radix-36
dw $5ed2 ;
dw ntop ; name address of mon
dw BACKSPACE ; backspace character
up_init dw uarea ; initial user area
psp_ini dw tos ; initial top of stack
rsp_ini dw $1ff ; initial top of return stack
dw tibx ; initial terminal input buffer
;
dw 31 ; initial name field width
dw 0 ; 0=nod disk, 1=disk
dw top ; initial fence address
dw top ; initial top of dictionary
dw vl0 ; initial vocabulary link ptr.
initend =*
initlen =initend-initblk-1 ;; Added symbolic constants, mam, 14L12
rsp_off =rsp_ini-initblk
psp_off =psp_ini-initblk
I labeled some of the elements of the initialization data block and created a few additional labels for offsets and initialization block length. I also applied a couple of mods to the COLD start word.
Code:
;
; cold
; screen 55 line 1
;
L2423 db $84,'COL',$c4
dw L2406 ; Link to abort
cold dw *+2
lda initblk ; from cold start area, added constant
sta forth+6
lda initblk+1 ;; added constant, mam, 14L12
sta forth+7
ldy #initlen ;; added constant, mam, 14L12
bne L2433
warm ldy #initlen-6 ;; added constant, mam, 14L12
L2433 ldx psp_ini ;; added to initialize parameter SP
stx xsave ;; mam, 14L12
lda up_init ;; added reference to label, mam, 14L12
sta up
lda up_init+1 ;; added reference to label, mam, 14L12
sta up+1
L2437 lda initblk,y ;; added label to initialize data block
sta (up),y
dey
bpl L2437
lda #hi abort ; actuaLLy #>(abort+2)
sta ip+1
lda #lo abort+2
sta ip
cld
lda #$6c
sta w-1
jmp (rpsto) ; and off we go !
;; changed to jmp (abs), mam, 14L12
At label L2433, I placed two instructions to initialize the parameter/data stack pointer X and the xsave zero page location. I also incorporated some symbolic labels to remove some of the magic numbers that seemed to have been incorrect. I also changed the jmp rpsto+2 instruction to jmp (rpsto) just to see if still worked. This change should be backed out if running with a 6502 processor or FPGA core. I also changed RP!, rpsto, by making the offset to the rsp initialization value a symbolic constant instead of the magic number 8 which was not correct for the given initialization data block I found in the source.
Code:
;
; rp!
; screen 26 line 8
;
L522 db $83,'RP',$a1
dw L511 ; link to sp!
rpsto dw *+2
stx xsave ; load return stack pointer (machine
ldy #rsp_off ; stack pointer) from silent user
lda (up),y ; variable r0
tax
txs
ldx xsave
jmp next
With the preceding changes I can now get to a prompt and get the ? when I enter a CR. The following is a capture of the terminal session:
Code:
65C02 Monitor Lite v5.1.5 (7-Dec-14) Ready
>0402G
fig-FORTH 1.0a
?
?
65C02 Monitor Lite v5.1.5 (7-Dec-14) Ready
>0000.01FF
0000 - 00 00 B6 00 06 01 B6 00 - 00 00 20 20 20 20 20 20
0010 - 20 20 20 20 20 20 20 20 - 20 20 20 20 20 20 20 20
0020 - 20 20 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0030 - 00 0A 3E 01 17 FC 00 01 - 00 00 3A 00 FF 01 00 00
0040 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0050 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0060 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0070 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0080 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0090 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00A0 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00B0 - 00 00 00 00 00 00 00 00 - 00 20 00 00 00 04 00 00
00C0 - 00 00 40 40 2C 00 63 0F - 6C E3 06 80 3E 06 00 00
00D0 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00E0 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00F0 - 00 00 00 00 00 00 00 00 - F9 11 FA 11 FA 11 00 00
0100 - 22 18 F8 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0110 - 00 00 00 00 30 BA 42 BA - F8 20 72 FA AE F9 0A 00
0120 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0130 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0140 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0150 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0160 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0170 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0180 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0190 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
01A0 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
01B0 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
01C0 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
01D0 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
01E0 - 00 00 00 00 00 00 00 00 - 00 00 00 20 21 18 FE 11
01F0 - FE A4 0E 14 10 12 2B 18 - B6 00 06 01 D1 0F 14 14
>
In locations 0100:0102 is a feature of the M65C02A core which writes to these locations the PSW, PCL, and PCH when Reset is applied to the core. In the case provided above, the core was reset while polling the getch() of the monitor.
I will try further tests later using Brad's suggested test sequence. Would be interested in any additional suggested Forth console tests.