6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 5:10 pm

All times are UTC




Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Tue Jul 05, 2016 6:22 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
I've begun a port of Tali FORTH from Scott's Ubersquirrel machine to Rich Cini's version of Daryl Rictor's SBC-2. The plan is to support the on board video, a PS/2 keyboard, and an SD2IEC reader for mass storage. Here's the location of the git hub repo containing the fork: https://github.com/Martin-H1/TaliForth

I'm going to document my progress and issues separately from Scott's thread to avoid polluting his thread. Anyway there are bugs, but the initial port went well. Here's one of my CS-101 FORTH exercises:

Code:
: factor? mod 0= ;  ok

: .factor tuck factor?  compiled
if . else drop then ;  ok

: factors dup 2  compiled
do dup i .factor loop drop ;  ok

36 factors 2 3 4 6 9 12 18  ok


Last edited by Martin_H on Tue Jul 05, 2016 7:23 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 05, 2016 6:27 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
So the first post is the good news.

The bad news is that I failed to notice that the high level words (e.g. IF, ELSE, WHILE, etc) that are compiled at load time are missing 100% of the time after a cold start, but present when I hit restart. But during the initial compile there's a syntax error that indicates it is trying to process the high level words on both a cold and warm start. My initial thinking was this was something like an off by 1 errors, so I instrumented the code to print our the line it is parsing. It produces the following output:

Code:
Booting Kernel for the Uberquirrel Mark Zero
Scot W. Stevenson <scot.stevenson@gmail.com>
Kernel Version Alpha 004 (11. Feb 2015)
7: IF POSTPONE 0BRANCH HERE 0 , ; IMMEDIATE COMPILE-ONLY
IF >>>Error<<<
Unknown word


I press restart and get this output:

Code:
Booting Kernel for the Uberquirrel Mark Zero
Scot W. Stevenson <scot.stevenson@gmail.com>
Kernel Version Alpha 004 (11. Feb 2015)
7: IF POSTPONE 0BRANCH HERE 0 , ; IMMEDIATE COMPILE-ONLY
C: ELSE POSTPONE BRANCH HERE 0 , HERE ROT ! ; IMMEDIATE COMPILE-ONLY
3: UNTIL POSTPONE 0BRANCH , ; IMMEDIATE COMPILE-ONLY
?: WHILE POSTPONE 0BRANCH HERE 0 , SWAP ; IMMEDIATE COMPILE-ONLY
<: REPEAT POSTPONE AGAIN HERE SWAP ! ; IMMEDIATE COMPILE-ONLY
K: IS STATE @ IF POSTPONE ['] POSTPONE DEFER! ELSE ' DEFER! THEN ; IMMEDIATE
R: ACTION-OF STATE @ IF POSTPONE ['] POSTPONE DEFER@ ELSE ' DEFER@ THEN ; IMMEDIATE


Tali Forth for the 65c02
Version BETA (10. Feb 2015)
Tali Forth comes with absolutely NO WARRANTY
Type 'bye' to exit


So it looks like in both the cold and warm start scenario it is trying to define the word IF (the first in the table), but getting a syntax error. Really odd and I'm unsure of the root cause.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 05, 2016 8:34 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
Another piece of good news is that with some fixes I was able to get a PS/2 keyboard working with Tali FORTH. I used Daryl Rictor's pckybd library and wired it to two pins on my VIA. When using a small Adesso keyboard it locked up on initialization, but a full size keyboard worked. However the KBINPUT function didn't save X and Y which corrupted FORTH's state, so I added the needed phx, phy, ply, and plx to the function and it worked great. Not sure why the Adesso keyboard is incompatible.

Code:
 KBINPUT:
 .scope
                phx                     ; save x and y for zero side effects.
                phy
                jsr   kbtscrl           ; turn off scroll lock (ready to input) 
                bne   kbinput           ; ensure its off
 kbinput1:      jsr   kbget             ; get a code (wait for a key to be pressed)
                jsr   kbcsrch           ; scan for 14 special case codes
 kbcnvt:        beq   kbinput1          ; 0=complete, get next scancode
@@ -262,10 +264,12 @@ kbcnvt4:       lda   asciitbl,x        ; get ascii code
                tax                     ; put new ascii to x reg
 kbdone:        phx                     ; save ascii to stack
 kbdone1:       jsr   kbtscrl           ; turn on scroll lock (not ready to receive)
                beq   kbdone1           ; ensure scroll lock is on
                pla                     ; get ASCII code
                ply
                plx
                rts                     ; return to calling program


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 07, 2016 8:56 am 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
I'm flattered, obviously. Not sure about the IF problem, just tested it again with py65mon and it seems to work (WORD gives complete list in both cases). I'm swamped at the moment - might get a few hours in later today, but nothing serious until Friday - but on an off hunch, might this be a LF/CR problem somewhere in the eval loop? Tali was originally written and run on Linux/OS X machines, which use a different EOL sequence than, say, Windows.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 07, 2016 11:10 am 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
Okay, I can't reproduce the problem with py65mon, I get the complete word list with WORD after COLD. Strange.

One thing I did notice looking over the code again is that COLD does not return STATE to "interpret" - that doesn't happen until QUIT. I can't see how that would be the source of the error, but maybe you could test inserting something like
Code:
                 stz STATE
                 stz STATE+1     ; paranoid, always zero
in the COLD routine just to be sure?


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 07, 2016 6:23 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
On mine, COLD moves into ABORT which has [ which turns STATE off.

_________________
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: Fri Jul 08, 2016 2:02 am 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
@Scott, good news, adding the stz to STATE seemed to resolve the loading high level words problem!

More good news. I got the SBC-2 on board video working, so coupling that with a PS/2 keyboard means no longer needing a host computer for PuTTY. That makes the machine easier to use because previously every EEPROM burn required me to unplug the 6502 console and plug in my EEPROM burner into the serial port. Then switch back after the burn so I could use the system.

Now I just pull the EEPROM, burn new contents, put it back and boot the 6502. Much speedier. Once I get the IEC port working the system could become self-hosting. I think it would also be good to use a jumper on a spare 6522 pin to set the default input and output devices. That way I can use the system either way.

More bad news. I resolved the carriage return problem by setting the assume implicit CR after LF in PuTTY. But now that I'm using the on board video the line wrap is back. So I'll need to append a CR to the prompt output. I tried adding this to the newline macro, but that doesn't seem to have done the trick.

I've also caused a few system panics with bugs, but I haven't noticed a pattern yet.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 08, 2016 2:40 am 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
Besides the newline macro I noticed this block of code which needed the CR added:

Code:
_linefeed:      ; get flag to see if we print a final linefeed or not
                ply
                beq _done
                lda #AscCR
                jsr f_putchr
                lda #AscLF
                bne f_putchr    ; JSR/RTS
_done:          rts
.scend

Once I made this change the output looks good using the on board video.

I also noticed that adding the stz STATE and STATE + 1 wasn't without a side effect. While it does get rid of the undefined word error, the first character you type after a restart caused the Tali Forth welcome message to get printed again. Odd, but more liveable than the prior bug.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 08, 2016 1:18 pm 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
GARTHWILSON wrote:
On mine, COLD moves into ABORT which has [ which turns STATE off.
Yes, and the problem with Tali is that in between those two steps, it defines the high-level commands like IF. No problem on the emulator, but real silicon seems to see things differently.

I need to get the infrastructure stuff done and rewrite Tali, though after the 65816, working with 8-bit again is going to be a pain :shock: .


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 11, 2016 4:15 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
With a local keyboard and video I can move onto adding mass storage. This will allow save and load word definitions, or program data. Rich Cini's SBC modification includes an IEC port, and I purchased an SD2IEC reader, so the electronics are complete. But I'm battling areas where I lack knowledge:

* The most immediate is a lack of detailed knowledge of the IEC protocol. I have a high level overview and Rich's source code for his ehBasic mods, so with code reading I might get somewhere here.

* What syntax and semantics are used by FORTH to access a file system? I know that early FORTH's used block mode I/O and structure is imposed by the programmer. But that low level interaction isn't how things seem to be done with IEC drives. Looking at the command set it looks like your program is talking to a file server rather than a block I/O device.

* When a FORTH programmer saves a program what are they saving? A snapshot of RAM with the compiled words, or FORTH source to be recompiled when the file loads? I suspect the latter would result in better code longevity, but that would see to require a way to output compiled FORTH words in their source versions.

Since this is a big problem I need to break this down into smaller goals to get anywhere.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 11, 2016 4:41 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
scotws wrote:
... No problem on the emulator, but real silicon seems to see things differently ...

Inadvertent use of an un-initialized variable somewhere?!?

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 11, 2016 10:01 pm 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
Martin_H wrote:
What syntax and semantics are used by FORTH to access a file system?
I'd stick to commands that Gforth uses (see http://www.complang.tuwien.ac.at/forth/ ... s-Tutorial) because that is pretty much going to be the standard one way or another.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 11, 2016 10:03 pm 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
barrym95838 wrote:
Inadvertent use of an un-initialized variable somewhere?!?
Very probably. It's got to be something that the emulator clears but remains in hardware ... I should probably test it on a different emulator to help solve the problem.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 11, 2016 10:19 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
Martin_H wrote:
* The most immediate is a lack of detailed knowledge of the IEC protocol. I have a high level overview and Rich's source code for his ehBasic mods, so with code reading I might get somewhere here.


I can't help you here, but what you're looking for is random access to the disk and/or random access to a file on the disk.

Quote:
* What syntax and semantics are used by FORTH to access a file system? I know that early FORTH's used block mode I/O and structure is imposed by the programmer. But that low level interaction isn't how things seem to be done with IEC drives. Looking at the command set it looks like your program is talking to a file server rather than a block I/O device.


There's an ANS standard File word set that can be used. I've not used it, I'm mostly familiar with old school blocks.

In F83, a specific Forth-83 implementation for the PC, they use the OPEN word to open a block file, and then use the normal block words.

Quote:
* When a FORTH programmer saves a program what are they saving? A snapshot of RAM with the compiled words, or FORTH source to be recompiled when the file loads? I suspect the latter would result in better code longevity, but that would see to require a way to output compiled FORTH words in their source versions.


In the past, the disk was used to load Forth source. Any "Save" commands were very implementation specific. For example, on the Atari, you would use their save command to snapshot the existing Forth image so that it would boot off of a floppy.

F83 will let you dump the image as a new executable ala F83.com.

What they didn't have was some kind of facility to save, in a binary format, fragments of the running system. Specifically, you couldn't load in a bunch of Forth source, and save the results as a binary component, and then reload just that binary component. Who knows what a may be possible in a modern Forth. But the old systems you basically started with a virgin image, load in source, then saved the entire thing back out.

Using the Block word set, you only need random access to the disk in some way. If you're talking to an actual filesystem, then you don't want to randomly access sectors of the disk (you can, you just probably don't want to). Doing that will stomp on the existing file system. So, instead, you'll want to access a file on the system, and then have random access to the file.

In Forth, Blocks are 1K bytes long. Blocks are also numbered from 0 to 65535 (16b Forth). Block 0 is "reserved" (since its typically used by the operating system to boot the disk or something else), but for a File based system that's less of a problem.

In any case, to save, say, Block 15, you seek 15 * 1024 bytes in to the disk/file, and write 1024 bytes out. Similarly for reading.

Now, for you work, you only need to learn how to randomly seek and read/write blocks. Your SC2IEC thing can no doubt do this, a disk file system that can not be randomly accessed is almost useless. So the capability is there.

For your system, you can use simply dedicate a hard coded file name (FORTH.DAT) on your drive, and use that, or you can use something like the F83 OPEN command: OPEN FORTH.DAT.

To use block I/O in Forth, you want to focus on the BLOCK command.

12 BLOCK will return the address of the internal buffer that contains Block #12 from mass storage. It will read the disk if necessary. You can the change the contents of that buffer, however you want, it's just memory. When you are done, you issue a 12 UPDATE command. This tells the system that Block 12 has changed.

Now, you can issue a SAVE-BUFFERS command, which will write ALL of the changed blocks back to disk.

The Forth block system is a crude virtual memory system. You load a page, then "use it" (UPDATE), and then…nothing. You're done. As new blocks are loaded, old blocks are flushed back out. The original Forth I/O system is distinctly unlike the modern streaming APIs, where you simply point a block of memory at an open file and say "write this" whether it's 1 byte or 1M bytes.

But it's effective.

So, in the end, you need random access to something -- ideally a file. And you can add a mechanism to your Forth to specify what that file name is at run time, or just use the same name over and over.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 11, 2016 11:42 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
@Scott, thanks for the pointer to the gforth file semantics. I will noodle with them in gforth to get a feel for them.

@whartung, thanks for the response. For the most part I have used FORTH on microcontrollers that don't have a file system at all. You save all sources on the host PC and use terminal software to upload it for interpretation which writes it to flash RAM. So your description about how block mode I/O was used was helpful.

Update: reading the gforth pages the word included looks like a good place to start.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 6 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: