changeset 59:9bed204d99b9

Add RUN and GOTO; also IN XXXX for errors
author William Astle <lost@l-w.ca>
date Sun, 19 Feb 2023 22:06:19 -0700
parents 24b123b3e69b
children 1190f66329ab
files src/lwbasic.s
diffstat 1 files changed, 49 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/lwbasic.s	Sun Feb 19 16:06:07 2023 -0700
+++ b/src/lwbasic.s	Sun Feb 19 22:06:19 2023 -0700
@@ -1004,6 +1004,12 @@
                 suba #0x20                      ; shift to upper case
                 bra writechr                    ; go output it
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Write a NUL terminated string at X to the screen. Conditionally convert to upper case based on the screen type.
+writestrconduc0 bsr writechrconduc              ; output the character
+writestrconduc  lda ,x+                         ; fetch character from string
+                bne writestrconduc0             ; brif not end of string
+                rts
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Fetch next input character, skip spaces. This is structured the way it is to avoid burning any register except A
 ; which is used for the returned value. Z will be set if the input character is NUL or a colon. C will be set if the
 ; input character is an ASCII digit. This allows testing Z to identify the end of a command due to either a colon or
@@ -1063,10 +1069,13 @@
                 bne ERROR0                      ; brif not end of message
 ERROR1          decb                            ; at the correct one?
                 bne ERROR0                      ; brif not - skip to next one
-ERROR2          lda ,x+                         ; get character to output
-                beq ERROR3                      ; brif end of message
-                jsr writechrconduc              ; output the character, converted to upper case situationally
-                bra ERROR2                      ; handle another character
+ERROR2          jsr writestrconduc              ; output error message
+                ldu curline                     ; are we in immediate mode?
+                beq ERROR3                      ; brif so
+                ldx #inmsg                      ; point to " in "
+                jsr writestrconduc              ; output " in "
+                ldd 2,u                         ; get line number
+                jsr print_uint16d               ; display the line number
 ERROR3          lds freetop                     ; reset the stack pointer (error routine could be called anywhere)
                 ; fall through to immediate mode intentional
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1150,6 +1159,12 @@
 ; the line had been present, which could be the end of the program. D and U are clobbered. Enter at prog_findlinex to
 ; start searching at the line pointed to by X. Enter at prog_findline to start at the beginning of the program. Enter
 ; with the desired line number in binval.
+prog_findlinecl ldx curline                     ; get current line pointer
+                beq prog_findline               ; brif immediate mode
+                ldd binval                      ; get desired line number
+                cmpd 2,x                        ; is the desired line number >= current line?
+                beq prog_findline2              ; brif this is the right line (optimizes goto self)
+                bhi prog_findlinex              ; brif desired line higher: start here instead of program start
 prog_findline   ldx progtext                    ; point to start of program
 prog_findlinex  ldu binval                      ; get line number to search for
 prog_findline0  ldd ,x                          ; end of program?
@@ -1259,10 +1274,10 @@
                 bne interpret1                  ; brif not
                 clra                            ; clear carry to indicate normal exit
                 rts                             ; return to caller
-interpret1      ldd ,x++                        ; are we at the end of the program?
+interpret1      ldd ,x                          ; are we at the end of the program?
                 beq interpret4                  ; brif so - bail out
                 stx curline                     ; save pointer to current line
-                leax 1,x                        ; set input pointer one before the start of the line text
+                leax 3,x                        ; set input pointer one before the start of the line text
 interpret2      stx inputptr
 interpret3      jsr nextchar                    ; fetch first character of next statement
                 beq interpret                   ; brif end of statement - do the next statement dance
@@ -1338,9 +1353,32 @@
                 bne cmd_data3                   ; brif not - keep going
                 bra cmd_data0                   ; process stuff outside string
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; RUN command
+cmd_run         ;jsr closeall                   ; close all files
+                jsr curchar                     ; what do we have as an argument?
+                bcs cmd_goto                    ; brif a digit - it's a line number (RUN ###); do GOTO
+                lbne SNERROR                    ; brif anything else on the line - not legit command
+                ldx progtext                    ; point to start of program
+                bra cmd_goto0                   ; go transfer control to the start of the program
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; GOTO command
+cmd_goto        jsr parse_lineno                ; parse the line number
+                jsr prog_findlinecl             ; go look up line number
+                bcc cmd_goto0                   ; brif line found
+ULERROR         ldb #err_ul                     ; raise undefined line error
+                jmp ERROR
+cmd_goto0       stx curline                     ; make sure we aren't flagging immediate mode
+                leax -1,x                       ; move input pointer to NUL before destination line
+                stx inputptr                    ; put input pointer there
+                rts                             ; resume interpretation at the new location                
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; GOSUB command
+cmd_gosub       rts
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Miscelaneous strings
 prompt          fcn 'OK'                        ; general prompt
 breakmsg        fcn 'BREAK'                     ; "BREAK" message
+inmsg           fcn ' in '                      ; " in " message
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Print out an unsigned 16 bit value in D to the selected output stream
 print_uint16d   pshs d,x,y,u                    ; save number and make some temporaries on the stack
@@ -1410,6 +1448,8 @@
                 fcn 'NEXT without FOR'
                 deferr sn
                 fcn 'Syntax error'
+                deferr ul
+                fcn 'Undefined line number'
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; The LET command which is the default if no token begins a statement
 cmd_let         jmp SNERROR                     ; not yet implemented
@@ -1706,6 +1746,9 @@
                 defcmd 'NEW',new
                 defcmd 'PRINT',print
                 defcmd 'LIST',list
+                defcmd 'RUN',run
+                defcmd 'GOTO',goto
+                defcmd 'GOSUB',gosub
                 defcmd '-',minus,SNERROR
 primarydict     cmdtab
 secondarydict   functab