Porting FIG Forth 6502 to ca65 and UK101

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
Post Reply
v6ops
Posts: 3
Joined: 24 Mar 2026

Porting FIG Forth 6502 to ca65 and UK101

Post by v6ops »

I recently bought a single board clone of a UK101 (I owned an original OSI C1E which was the donor for the clone).

I've ported what I believe to be an original listing of FIG Forth v1.1 (bugs and all) to ca65.

Code is here:https://github.com/v6ops/FIG-Forth-UK101/tree/UK101

This works as far as I can tell on the hardware UK101, but not on the run6502 simulator library. I'm probably doing something wrong there. It prompts and echos the line, but doesn't seem to exec (CR/LF issues??).

Q1. I had to add an extra line to BRAN: to get that working, because the branch offsets weren't being calculated correctly.
Was anyone else impacted by this?

L89 .BYTE $86,'BRANC',$C8
.WORD L75 ; link to EXCECUTE
BRAN .WORD *+2
; Y reg looks undefined. Assume Bug.
LDY #0 ; set offset to IP to 0. Doesn't change C bit.
; end

CLC
LDA (IP),Y
ADC IP
PHA
INY
LDA (IP),Y
ADC IP+1
STA IP+1
PLA
STA IP
JMP NEXT +2
;

Q2. Any idea why the hardware code runs, but the emulated code doesn't? I' normally expect the other way on.

Thanks
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Porting FIG Forth 6502 to ca65 and UK101

Post by Dr Jefyll »

Hello, v6ops, and (belated) welcome. :)
Quote:
Q1. I had to add an extra line to BRAN: to get that working, because the branch offsets weren't being calculated correctly.
Firstly, allow me to suggest you use the Code tags for better clarity (see below).

As for the incorrect the branch offsets, adding the LDY #0 should not have made any difference.

[Edit: remove ill-considered theory]
Quote:
Y reg looks undefined. Assume Bug.
Y is left equal to zero by NEXT. So, Y isn't undefined if BRANCH executes immediately subsequent to NEXT (as is often the case). But BRANCH's code can also get jumped into from 0BRANCH and others, so perhaps one of those has somehow left Y non-zero.

I wonder if the problem may result from corruption in your copy of the FIG assembly source. In support of this idea, I notice the mis-spelled word "EXCECUTE" in one of the comments in the source code you posted. This mis-spelling doesn't appear in my own (ancient, dog-eared :) ) copy of the the FIG assembly source. So, perhaps your copy also includes *other* errors.
Quote:
Q2. Any idea why the hardware code runs, but the emulated code doesn't?
Interesting! But firstly let's answer Q1. Then perhaps we'll be better informed when it comes to Q2.

-- Jeff

Code: Select all

L89 .BYTE $86,'BRANC',$C8
.WORD L75 ; link to EXCECUTE
BRAN .WORD *+2
; Y reg looks undefined. Assume Bug.
LDY #0 ; set offset to IP to 0. Doesn't change C bit.
; end
CLC
LDA (IP),Y
ADC IP
PHA
INY
LDA (IP),Y
ADC IP+1
STA IP+1
PLA
STA IP
JMP NEXT +2
;
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
v6ops
Posts: 3
Joined: 24 Mar 2026

Re: Porting FIG Forth 6502 to ca65 and UK101

Post by v6ops »

Thanks Jeff.

The tip you gave makes a lot of sense. I do see NEXT setting Y to 0. I was unaware that Y had to remain 0 as that's not in any comments, but that also makes sense.

Odd that X (the Forth stack pointer) is protected before calling these routines, but Y isn't.

Code: Select all

; original FIG Forth
XKEY:     STX XSAVE
          JSR INCH       ; might otherwise clobber it while
          LDX XSAVE      ; inputting a char to accumulator
          JMP PUSHOA
;
;         XQTER leaves a boolean representing terminal break
It's simple enough to preserve Y using exactly the same method as X.

I've tried quite a lot of debug but I haven't yet found anything conclusive to feed back.

regards,
Ray
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Porting FIG Forth 6502 to ca65 and UK101

Post by Dr Jefyll »

v6ops wrote:
I was unaware that Y had to remain 0 as that's not in any comments
Apologies, Ray... If you look again you'll see I edited my post. This was promptly after I submitted the erroneous content, but unfortunately you'd already seen it, it seems.

To be clear, Y does not have to remain equal to zero. It is only assumed to be zero initially... that is, immediately following NEXT and thus upon entry to a primitive. It's handy being able to rely on that assumption because it relieves the need for some primitives, including BRANCH, to initialize Y upon entry. But it's OK for Y to be trashed when execution eventually jumps back to NEXT because NEXT makes no assumption; it explicitly reloads Y.

This leaves us with the question of why your system seemingly benefits when you insert a LDY #0 at the entry point for BRANCH. And BRANCH is a joker in the deck because, as I noted upthread, its entry point can be reached not only via NEXT but also by a few other paths: ie, conditional jumps directly from 0BRANCH and 1 or 2 others. Regarding these special cases, Y does needs to be zero when the primitive's exit jump occurs... it's not same as when the primitive exits by jumping to NEXT. So, there could be a problem with 0BRANCH, for example, failing to have Y=0 when it jumps into BRANCH.

But I suggest we set that line of thinking aside and take a wider view. It seems your version of the source code may be problematic, so IMO it's better to consider that overall aspect (rather than worrying about Y this or BRANCH that). How is it possible that the word "EXECUTE" would get transformed into "EXCECUTE"? What other glitches may your assembler have ingested?

Hope this helps,

Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
leepivonka
Posts: 168
Joined: 15 Apr 2016

Re: Porting FIG Forth 6502 to ca65 and UK101

Post by leepivonka »

One place to start tracing is in EXPECT - does it finish when the simulator sends it a carriage return. Or is the simulator sending a line feed instead?

Code: Select all

@1760:	.WORD DUP		; cr?
	.WORD CLit
	.BYTE $0D
	.WORD EQUAL
	.WORD ZBranch,@1772-*
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Porting FIG Forth 6502 to ca65 and UK101

Post by Dr Jefyll »

v6ops wrote:
It prompts and echos the line, but doesn't seem to exec (CR/LF issues??).

Q1. I had to add an extra line to BRAN: to get that working
Ray, to me this "I had to add an extra line" business is too conspicuous to ignore. Why does your system (but no-one else's) need an extra LDY #0? And -- playing the detective! -- what could this anomaly have in common with the "prompts and echos the line, but doesn't seem to exec" problem?

For me what comes to mind is, both symptoms could result from the source code somehow getting altered/corrupted before assembly. And an even plainer example of this suspected corruption is the weird "EXCECUTE" mis-spelling I mentioned upthread! (Yes, the mis-spelled word appeared in a comment, but it fails to match the comment in the original FIG source. And if a comment can go awry, then so too can anything else in the assembly source file, I'd say.)

I think you'd do well to track down the cause of the EXCECUTE business... because when you find that answer, it may well explain all the other trouble as well. :!:

Quote:
Any idea why the hardware code runs, but the emulated code doesn't? I' normally expect the other way on.
One possible explanation for the difference is, an invalid opcode has executed... in which case the emulator may not behave identically to an actual physical CPU.

It's plausible that an actual CPU might ingest an invalid opcode and continue to kinda-sorta run the program (more successfully than the simulator might happen to do). But what is it that led to the execution of the invalid opcode? Again, corrupted source code is one plausible explanation.

(Bad connections and inadequate bypass caps are also potential causes of flaky operation... but they can't be blamed for mis-spellings getting injected into the source code! :) )

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