Bug in EhBASIC 2.22 Daryl Rictor et al (from a discusson on 6502.org)
The following works:
; Ibuffs can now be anywhere in RAM, ensure that the max length is < $80 IRQ_vec = VEC_SV+2 ; IRQ code vector Ibuffs = IRQ_vec+$14
Whereas the following doesn’t:
; Ibuffs can now be anywhere in RAM, ensure that the max length is < $80 Ibuffs = $0400 Ibuffe = Ibuffs + $47 ; end of input buffer
Of course be careful to make sure that Ram_base is quite faraway from Ibuffs.
So, Ibuffs can be anywhere in RAM that’s not $0400??
Any reason $0400 is magical?
Nope. $0400 is an example. $0500 gives you the same result: negative.
As long as Ibuffs is in the same page as ccflag and friends, it works. And ccflag can be at $0400.
Now, if you reference Ibuffs in relation to IRQ_vec (copy it over from min_mon.asm), then things work.
Perhaps someone somewhere made some assumptions of the page where Ibuffs need to be e.g. be in the same page as ccflag and friends etc.
The other problem is what I’ve already observed: the EhBASIC binary has to be located in memory higher than Ram_base and Ram_top. Otherwise strange things happen.
With Ibuffs set to $0400 AND Ram_base set to $0500, I did a Cold start and entered this line – 10 PRINT “HELLO WORLD”
I examined the memory at Ram_base and found that the stored line was formatted correctly. However, when I typed LIST, all I got back was HELLO WORLD, as if I had typed RUN. Typing RUN also returned HELLO WORLD. When I ran the SYS command (my added command to return me to my Monitor), it just ignored it and returned to the BASIC input prompt.
Next, I changed Ibuffs to $0401 and reassembled. This time, everything performed as it should.
Next, I set Ram_base to $0600 with Ibuffs set to $0400 and entered the same line. This time, LIST returned nothing. Examining memory at $0600, the stored line is there and is correct. RUN and SYS also return nothing.
Finally, I set Ram_base to $0600 and Ibuffs to $0401 and all worked as it should.
I think I found the problem… and it would explain the issue with Ibuffs and Ram_base being 1 page apart too.
This piece of code is the problem:
LAB_142A INY ; increment pointer INY ; increment pointer (makes it next line pointer high byte) STA Ibuffs,Y ; save [EOL] (marks [EOT] in immediate mode) INY ; adjust for line copy INY ; adjust for line copy INY ; adjust for line copy DEC Bpntrl ; allow for increment (change if buffer starts at $xxFF) RTS
Previously in the code, Bpntrl gets set to Ibuffs. When the DEC instruction gets executed, Bpntrl get set to $FF. Later in the code, we have this:
LAB_15F6 JSR LAB_IGBY ; increment and scan memory LAB_15F9 JSR LAB_15FF
The routine LAB_IGBY is located in zero page (to increase speed). it looks like this:
LAB_2CEE INC Bpntrl ; increment BASIC execute pointer low byte BNE LAB_2CF4 ; branch if no carry ; else INC Bpntrh ; increment BASIC execute pointer high byte ; page 0 initialisation table from $C2 ; scan memory LAB_2CF4 LDA $FFFF ; get byte to scan (addr set by call routine) CMP #TK_ELSE ; compare with the token for ELSE BEQ LAB_2D05 ; exit if ELSE, not numeric, carry set CMP #':' ; compare with ":" BCS LAB_2D05 ; exit if >= ":", not numeric, carry set CMP #' ' ; compare with " " BEQ LAB_2CEE ; if " " go do next SEC ; set carry for SBC SBC #'0' ; subtract "0" SEC ; set carry for SBC SBC #$D0 ; subtract -"0" ; clear carry if byte = "0"-"9" LAB_2D05 RTS
The code at LAB_2CEE will INC Bpntrl, which becomes $00 and then INC’s Bpntrh to $05. Now this pointer is pointing to the wrong page. And depending upon what is stored there, different things will happen.
This note is incorrect:
DEC Bpntrl ; allow for increment (change if buffer starts at $xxFF)
It should read (change if buffer starts at $xx00).
My fix would be to add this:
LAB_142A INY ; increment pointer INY ; increment pointer (makes it next line pointer high byte) STA Ibuffs,Y ; save [EOL] (marks [EOT] in immediate mode) INY ; adjust for line copy INY ; adjust for line copy INY ; adjust for line copy ; add patch for when Ibuffs is $xx00 - Daryl Rictor LDA Bpntrl ; test for $00 BNE LAB_142P ; not $00 DEC Bpntrh ; allow for increment when $xx00 LAB_142P ; end of patch DEC Bpntrl ; allow for increment RTS
I have tested this fix and it worked for me.