Page 1 of 4
Porting EhBASIC to a new system
Posted: Mon May 29, 2017 9:37 pm
by bluesky6
I'm porting EhBASIC to a new system (a 6502 CPU board for the RC2014) and am hitting Syntax Errors. I'm using the files in source.zip from Jeff Tranter's github repo.
I've set up V_INPT and V_OUTP along with Ram_base, Ram_top and Ibuffs.
The BASIC code is at $1000 in RAM and Ram_base points to $4000 with Ram_top at $8000.
I can get to the first Ready prompt. Typing in anything (e.g. LIST, NEW) will result in a syntax error.
After some tracing, the errors comes from LAB_1609.
Other than the I/O reconfiguration and memory settings, what else is needed for a port?
Do I need to do anything with IRQ/NMI? The hardware does have any interrupts running or enabled. I'm using a serial teminal so don't know if Twidth is something that needs to be preconfigured.
I've done similar ports of other BASICs (IMSAI 8K and PA Tiny) so I'm not lost (yet

).
Thanks!
Re: Porting EhBASIC to a new system
Posted: Mon May 29, 2017 11:00 pm
by Rob Finch
It sounds like you've got everything set that should be. Try moving IBuffs below Ram_base if it isn't already.
The V_INPT needs to have the carry and zero flag set appropriately.
I got a copy of EhBASIC from Klaus's page on GitHub. It seems to work. Maybe you could compare the two and see if there are any differences.
Re: Porting EhBASIC to a new system
Posted: Mon May 29, 2017 11:58 pm
by bluesky6
Thanks, Rob.
The files are the same.
On a hunch, I tweaked the memory locations a little bit. I had previously assembled the code to reside at $1000 and the Ram_base at $4000.
When I reversed it i.e. code at $4000 and Ram_base at $1000, I no longer get a Syntax error with LIST (or NEW ...).
Weird.
However, I'm not able to enter a program. Typing in "10 A=0" and then typing in LIST does not show anything. Then typing in "20 PRINT A" followed by "LIST" will give me a syntax error for line 20. Typing in NEW will give me the same syntax error message.
Is there a requirement for the BASIC code to be in ROM?
I know, for example, that the Z80 MS BASIC that comes with the RC2014 cannot run reliably in RAM.
Re: Porting EhBASIC to a new system
Posted: Tue May 30, 2017 1:46 am
by Rob Finch
Is there a requirement for the BASIC code to be in ROM?
As far as I know no. I think it should be able to run from RAM. I've browsed the code a fair bit and I haven't seen anything that writes to the area the code is in.
The only self modifying code is for the BASIC char get routine, which gets copied to zero page.
Is the CPU board an ordinary 6502 or is it a custom chip ? Does it have a cache memory ? Does it share zero page memory with anything else ? EhBASIC uses most of zero page memory.
Can you try running Klaus's test suite on the 6502 ? Maybe it's a hardware problem of some sort.
Re: Porting EhBASIC to a new system
Posted: Tue May 30, 2017 2:28 am
by 8BIT
I have run EhBASIC from RAM without problems.
Here is my typical setup:
Code: Select all
; Ibuffs can now be anywhere in RAM, ensure that the max length is < $80
Ibuffs = VEC_SV+2 ; ***changed for SBC-2
; start of input buffer after IRQ/NMI code
Ibuffe = Ibuffs+$47; end of input buffer
Ram_base = $0400 ; start of user RAM (set as needed, should be page aligned)
Ram_top = $8000 ; end of user RAM+1 (set as needed, should be page aligned)
My SBC Monitor uses page 3 for Input buffer and other pointers, so I have Ram_base set to $400.
I initialize the V_INPT and V_OUTP variable then call LAB_COLD. Make sure your caps lock is on, as EhBASIC does not like lower case except inside of string variables.
Daryl
Re: Porting EhBASIC to a new system
Posted: Tue May 30, 2017 2:51 am
by Dr Jefyll
Maybe it's a hardware problem of some sort.
Hmm, how do you generate the WE signal that's sent from the CPU card to the backplane? With 65xx processors (unlike Z80) there needs to be an external gate that forces the WE signal false except during the latter half (Phase2 high) of each cycle.
Sorry if I'm stating what you already know. Without such a gate the sytem might be totally DOA, or it
might kinda-sorta work -- but its behavior would be weird. Hardware problems can certainly present that way.
Another scenario that can kinda-sorta work is when there's a flaky connection, or when a pin is supposed to be tied high or low but has been left unconnected instead. (BTW on
this page Garth outlines how the CPU pins need to be tied.)
best of luck, and keep us posted,
Jeff
[edit: fix link]
Re: Porting EhBASIC to a new system
Posted: Tue May 30, 2017 4:22 am
by rwiker
I seem to remember that somebody had problems with EhBasic that were caused by having the Decimal Mode flag set... does this ring a bell?
Re: Porting EhBASIC to a new system
Posted: Tue May 30, 2017 6:21 am
by Klaus2m5
Decimal mode is only a problem in HEX$() producing a false result. Running EHBasic below Basic program RAM has a bug. Please see
https://github.com/Klaus2m5/6502_EhBASI ... quirks.txt #2.
The only thing, that would cause EHBasic to overwrite itself is an address collision between RAM settings and EHBasic's location.
Re: Porting EhBASIC to a new system
Posted: Wed May 31, 2017 1:55 am
by bluesky6
Thanks everyone for your suggestions etc.
I finally figured it out.
The main problem is where Ibuffs (and subsequently Ibuffe) is located. I had placed it at $400. With everything being equal, this will result in EhBASIC not recognizing anything you type. It will see your entry and echo it back, but will not be able to do anything with it and in some cases, will complain of a syntax error.
Now, if you reference Ibuffs in relation to IRQ_vec (copy it over from min_mon.asm), then things work.
So the following works:
Code: Select all
; 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:
Code: Select all
; Ibuffs can now be anywhere in RAM, ensure that the max length is < $80
Ibuffs = $0400
Ibuffe = Ibuffs + $47 ; end of input buffer
I am of course careful to make sure that Ram_base is quite faraway from Ibuffs.
I don't know why this is so. 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.
I suggest documenting this in bugsnquirks....

Re: Porting EhBASIC to a new system
Posted: Wed May 31, 2017 6:16 am
by BigEd
Glad you figured it out! And, by the way, welcome.
Re: Porting EhBASIC to a new system
Posted: Wed May 31, 2017 6:31 pm
by whartung
Code: Select all
; Ibuffs can now be anywhere in RAM, ensure that the max length is < $80
Ibuffs = $0400
Ibuffe = Ibuffs + $47 ; end of input buffer
So, Ibuffs can be anywhere in RAM that's not $0400??
Any reason $0400 is magical?
Re: Porting EhBASIC to a new system
Posted: Thu Jun 01, 2017 12:48 am
by bluesky6
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.
So again, someone somewhere made an assumption

Re: Porting EhBASIC to a new system
Posted: Thu Jun 01, 2017 3:47 pm
by 8BIT
I did a little experimenting this morning. This is on v2.22
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 do not have time to research why this is happening, or if there are any other limitations to Ibuffs, but it appears that the low byte of the Ibuffs address cannot be $00. I'm not sure how to interpret the differences in results based on where Ram_base is in relation to Ibuffs, but there is some connection when its 1 page apart.
Daryl
Re: Porting EhBASIC to a new system
Posted: Thu Jun 01, 2017 6:26 pm
by 8BIT
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:
Code: Select all
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:
Code: Select all
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:
Code: Select all
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:
Code: Select all
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:
Code: Select all
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.
Daryl
Edited - Changed BIT to LDA in my patched code....can't use BIT to test ZP=0 unless A is already 0.
Re: Porting EhBASIC to a new system
Posted: Thu Jun 01, 2017 6:41 pm
by GaBuZoMeu
Thumbs Up !
edit(1):
Now that A is changed (LDA Bpntrl; test for $00) it is perhaps saver to preserve A by adding a PHA past STA IBuffs,Y and unstacking A before DEC Bpntrl .