6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed May 22, 2024 2:22 am

All times are UTC




Post new topic Reply to topic  [ 66 posts ]  Go to page 1, 2, 3, 4, 5  Next
Author Message
PostPosted: Tue Dec 09, 2014 4:34 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Looking for some help in bringing up fig-FORTH on my M65C02A core. Think that I've got the latest code base from the repository. Have modified it to connect to the I/O routines in the monitor, and removed the jsr trace and jsr tcolon calls. Display the prompt, but after that it just seems to hang.

Any suggestions in debugging this would be appreciated. I am a complete newbie with FORTH and don't have anything to go on in trying the determine what may be awry with the current program. The embedded trace seems to go South, so I read through the listing and used the monitor to patch the two calls noted above.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 09, 2014 5:18 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1930
Location: Sacramento, CA, USA
It seems that enso was able to post at least the binary of a version to run cleanly on his chochi here, but it looks like you were present in that thread as well, so I may be just blowing smoke up your you-know-what by mentioning it.

Mike


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 09, 2014 5:53 am 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8442
Location: Southern California
If it displayed the prompt, that's a lot. It shows most of the basic stuff is working. When I was getting mine going, I just took a lot of iterations of putting software probes in at various places to see if it got there before crashing, and to see what was in various registers and variables at that point. It's tedious but you get there. When you get to where it can interpret and compile, you'll have the interactiveness to debug stuff much more easily. Good luck.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 09, 2014 4:10 pm 
Offline

Joined: Tue Jan 07, 2014 8:40 am
Posts: 91
GARTHWILSON wrote:
If it displayed the prompt, that's a lot. It shows most of the basic stuff is working.


Indeed! At that point you have character output, a few stack and arithmetic operations, and a looping or branching operation working. I think the next thing I'd check is if character input (KEY and ?TERMINAL) works correctly.

When I am bringing up Forth on a new CPU, my first test is to output a character in assembly language at the end of the reset initialization code. That verifies that the processor is running and that I have configured at least some of the I/O correctly. My second test is to write an assembly language loop that reads a character, modifies it (usually by adding one), and outputs that modified character.

Next I test the Forth threading mechanism and basic control structures, by having the reset code launch this Forth thread: BEGIN KEY 1+ EMIT AGAIN . That verifies that Forth threading is working, character I/O is working, the stack is working (since it's used to pass and modify the character), and the unconditional branch is working.

At that point I usually write some very simple words to output hex numbers -- not using Forth's "." which requires a lot of primitives to be working -- so I can display diagnostic output. And I start working my way through COLD to see where it fails.

Given that your system has already reached the startup prompt, I think I'd instrument the word QUERY to make sure it is receiving and correctly storing characters. If QUERY correctly returns a line of text, the next word to investigate is probably INTERPRET (I may be misremembering the actual fig-Forth word name here). For example, you can verify that it correctly parses a word of text, and correctly finds that word in the dictionary. (Problems with FIND are not uncommon.)

_________________
Because there are never enough Forth implementations: http://www.camelforth.com


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 09, 2014 8:48 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Thanks all for your responses. Will take your recommendations and observations and make an attempt to move past the point where I found myself late last night. If I don't have any success, will attempt to capture some of the built in trace and post that later to see if anyone has any additional suggestions.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 10, 2014 4:20 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
I made a change to one of the built-in trace functions to mask off the msb when using putch to print the ASCII character word name. That cleaned up the trace into an intelligible display. I did remove an extra space in the sign on message, but did not adjust the length so the IP got out of synch and it crashed. I patched it to the correct length, and it continued past the printing of the sign on message.

It appears to be crashing in INTERPRET in the word -FIND.

Looking at the code, and looking for a clue.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 10, 2014 1:42 pm 
Offline

Joined: Tue Jan 07, 2014 8:40 am
Posts: 91
Random thoughts: check that the user variables CURRENT and CONTEXT are correctly initialized. And make sure that the first word in the Forth dictionary has a zero link (to terminate the linked list).

_________________
Because there are never enough Forth implementations: http://www.camelforth.com


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 10, 2014 3:41 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Brad:

Thanks for the additional hint. Will pursue this tack later tonight. What would you consider the correct initialization for these two variables?

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 10, 2014 4:00 pm 
Offline

Joined: Tue Jan 07, 2014 8:40 am
Posts: 91
Ack. I'd have to dig out my fig-Forth books to answer that. If I recall correctly, each one should point somewhere in the data field of a VOCABULARY word, which in turn holds a link to the last (most recent) word in that particular dictionary chain. But my memory on this is weak.

A useful, if voluminous, diagnostic: -FIND compares the parsed text string with the name field of a word in the dictionary. One thing to do is, inside the loop, print the name field address of each word before it is compared. You should see a string of addresses running down to the first word in the dictionary. If it keeps going after that, you don't have a properly null-terminated list. If it just goes all over the map, you probably have an invalid CONTEXT or CURRENT. -FIND will keep following dictionary links forever until it encounters a zero link, or finds a matching word name.

_________________
Because there are never enough Forth implementations: http://www.camelforth.com


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 10, 2014 4:41 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3354
Location: Ontario, Canada
Brad R wrote:
inside the loop, print the name field address of each word before it is compared
With FIG Forth, -FIND calls (FIND) -- that's the actual search loop. As Brad suggests, get inside the loop -- let it run 3 or 4 iterations then stop it to see what it's doing. It should be following the link chain backwards through the dictionary -- ie, MON -> VLIST -> TRIAD -> INDEX -> LIST -> ? -> . -> .R etc.

Check also that the example string -- what the loop is comparing each successive dictionary name with -- is correctly located at the address provided. :)

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Wed Dec 10, 2014 6:43 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Brad/Jeff:

If I remember correctly, in -FIND, first word executed was BL which is followed by :WORD. It is at this point that the VM crashes and returns to the SBC2 OS Lite monitor. Funny thing is that the SBC2 OS Lite monitor prints out the registers and PC is shown to be 0x0000.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 13, 2014 1:17 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
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.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 13, 2014 12:35 pm 
Offline

Joined: Tue Jan 07, 2014 8:40 am
Posts: 91
Once you have it accepting console input, the first three tests are:
1. empty line (which you have done)
2. single Forth word (such as DUP)
3. a number (such as 5)

The fact that empty line is returning "?" suggests a problem within INTERPRET and its termination condition. I vaguely recall that fig-Forth requires a null character to be appended to the input line. (I really need to dig out my fig-Forth references.) One thing to try is something like 50 EMIT <CR> (with a space before the <CR>). If it prints "2 ?" then it's parsing words from the text ok, but failing at end-of-line.

If empty line works ok, and numbers work ok but finding a Forth word does not, the most likely problem is the dictionary search (perhaps the name comparison routine, or a problem with your Forth word headers). If you can find a Forth word, but a number fails, the most likely problem is in the number conversion word (perhaps named CONVERT).

_________________
Because there are never enough Forth implementations: http://www.camelforth.com


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 14, 2014 3:39 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 575
This conversation inspired me to try FigForth. I've downloaded the source and with a few tweaks got it assembling under Tass. One thought occurred to me though.

If I put this in the ROM how does the FORTH dictionary access RAM? Or does FigForth need to be in RAM to allow the dictionary the source defines to expand into RAM as new words are defined?


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 14, 2014 4:24 pm 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
Martin_H wrote:
If I put this in the ROM how does the FORTH dictionary access RAM? Or does FigForth need to be in RAM to allow the dictionary the source defines to expand into RAM as new words are defined?


Right. Forth has a pointer to the last entry in the Dictionary, which is in ROM when you start out. When you define a new word, it is placed in RAM, with the pointer to that entry -- at this point, the Dictionary crosses the RAM/ROM border. Then, Forth remembers where the new last entry lives, so the next word gets chained to that.

Just remember that fig Forth is an ancient dialect by now -- befitting a 6502 machine, if you will, but a lot of the modern examples will not work.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 66 posts ]  Go to page 1, 2, 3, 4, 5  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: