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
Porting FIG Forth 6502 to ca65 and UK101
Re: Porting FIG Forth 6502 to ca65 and UK101
Hello, v6ops, and (belated) welcome.
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]
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.
Interesting! But firstly let's answer Q1. Then perhaps we'll be better informed when it comes to Q2.
-- Jeff
Quote:
Q1. I had to add an extra line to BRAN: to get that working, because the branch offsets weren't being calculated correctly.
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.
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
Quote:
Q2. Any idea why the hardware code runs, but the emulated code doesn't?
-- 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
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: Porting FIG Forth 6502 to ca65 and UK101
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.
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
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
I've tried quite a lot of debug but I haven't yet found anything conclusive to feed back.
regards,
Ray
Re: Porting FIG Forth 6502 to ca65 and UK101
v6ops wrote:
I was unaware that Y had to remain 0 as that's not in any comments
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
https://laughtonelectronics.com/Arcana/ ... mmary.html