6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 5:46 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Thu Jul 19, 2018 9:31 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
This bug was discovered here:
viewtopic.php?f=1&t=5198&start=150#p61372
Quote:
The "result" for EhBasic using: 40 IF INT(C/D)*D = C THEN NEXT C : GOTO 90
yields: "NEXT without FOR Error in line 40"

This is true not only for a NEXT but also for LOOP and RETURN. All of these keywords need to find their FOR, DO or GOSUB structure on the stack. Since EhBASIC allows for an ELSE the call to interpret a basic statement after THEN must return to IF to be able to skip the program past ELSE. This puts a return address on the stack and breaks the offset to FOR, DO and GOSUB structures on the stack. Interestingly Lee already fixed this for RETURN since there is no need to skip anything after a RETURN.

The fix I have is to simply discard the original call to the "interpret statement" routine (The one that executed the IF) and replace the final RTS with a JMP to the interpreter loop. This also eliminates the need to have a separate fix for RETURN. To my big surprise even nested IFs work correctly.
Code:
; perform IF

LAB_IF
      JSR   LAB_EVEX          ; evaluate the expression
      JSR   LAB_GBYT          ; scan memory
      CMP   #TK_THEN          ; compare with THEN token
      BEQ   LAB_174B          ; if it was THEN go do IF

                              ; wasn't IF .. THEN so must be IF .. GOTO
      CMP   #TK_GOTO          ; compare with GOTO token
      BNE   LAB_16FC          ; if it wasn't GOTO go do syntax error

      LDX   Bpntrl            ; save the basic pointer low byte
      LDY   Bpntrh            ; save the basic pointer high byte
      JSR   LAB_IGBY          ; increment and scan memory
      BCS   LAB_16FC          ; if not numeric go do syntax error

      STX   Bpntrl            ; restore the basic pointer low byte
      STY   Bpntrh            ; restore the basic pointer high byte
LAB_174B
      LDA   FAC1_e            ; get FAC1 exponent
      BEQ   LAB_174E          ; if the result was zero go look for an ELSE

      JSR   LAB_IGBY          ; else increment and scan memory
      BCS   LAB_174D          ; if not numeric go do var or keyword

LAB_174C
      JMP   LAB_GOTO          ; else was numeric so do GOTO n

                              ; is var or keyword
LAB_174D
; *** patch       allow NEXT, LOOP & RETURN to find FOR, DO or GOSUB structure on stack
; *** replace
;      CMP   #TK_RETURN        ; compare the byte with the token for RETURN
;      BNE   LAB_174G          ; if it wasn't RETURN go interpret BASIC code from (Bpntrl)
;                              ; and return to this code to process any following code
;
;      JMP   LAB_1602          ; else it was RETURN so interpret BASIC code from (Bpntrl)
;                              ; but don't return here
;
;LAB_174G
;      JSR   LAB_15FF          ; interpret BASIC code from (Bpntrl)
;
;; the IF was executed and there may be a following ELSE so the code needs to return
;; here to check and ignore the ELSE if present
;
;      LDY   #$00              ; clear the index
;      LDA   (Bpntrl),Y        ; get the next BASIC byte
;      CMP   #TK_ELSE          ; compare it with the token for ELSE
;      BEQ   LAB_DATA          ; if ELSE ignore the following statement
;
;; there was no ELSE so continue execution of IF <expr> THEN <stat> [: <stat>]. any
;; following ELSE will, correctly, cause a syntax error
;
;      RTS                     ; else return to the interpreter inner loop
;
; *** with
      PLA                     ; discard interpreter loop return address
      PLA                     ; so data structures are at the correct stack offset
      JSR   LAB_GBYT          ; restore token or variable
      JSR   LAB_15FF          ; interpret BASIC code from (Bpntrl)

; the IF was executed and there may be a following ELSE so the code needs to return
; here to check and ignore the ELSE if present

      LDY   #$00              ; clear the index
      LDA   (Bpntrl),Y        ; get the next BASIC byte
      CMP   #TK_ELSE          ; compare it with the token for ELSE
      BNE   LAB_no_ELSE       ; no - continue on this line
      JSR   LAB_DATA          ; yes - skip the rest of the line

; there was no ELSE so continue execution of IF <expr> THEN <stat> [: <stat>]. any
; following ELSE will, correctly, cause a syntax error

LAB_no_ELSE
      JMP LAB_15C2            ; return to the interpreter inner loop
; *** end patch  allow NEXT, LOOP & RETURN to find FOR, DO or GOSUB structure on stack

; perform ELSE after IF

LAB_174E

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 19, 2018 2:44 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1207
Location: Soddy-Daisy, TN USA
Klaus,

You are the master at fixing EhBASIC. :-)

Have you ever thought about rolling your own BASIC?

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 19, 2018 4:00 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
Thanks Klaus,

I've added this patch to the EhBasic I'm working with... I'm guessing this would now be Version 2.22p5?

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 20, 2018 10:40 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
I just released the accumulated patches as 2.22p4 on GitHub.

cbmeeks wrote:
Have you ever thought about rolling your own BASIC?
No, I am not looking for a new challenge.

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 20, 2018 11:42 am 
Offline
User avatar

Joined: Wed Mar 01, 2017 8:54 pm
Posts: 660
Location: North-Germany
Thanks Klaus, fine work.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

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