view src/progctrl.s @ 136:e49bd0493baf

Checkpoint updates to immediate mode program editing and some memory handling
author William Astle <lost@l-w.ca>
date Fri, 12 Jul 2024 23:29:45 -0600
parents 917b4893bb3d
children
line wrap: on
line source

                *pragmapush list
                *pragma list
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The END command.
cmd_end         bne SNERROR                     ; error out if there is an argument
                ;jsr closeall                    ; close all files for END
                clra                            ; flag END (clear carry)
                bra cmd_stop0                   ; go do the stop/end
cmd_stop        bne SNERROR                     ; raise error if there was an argument
                coma                            ; flag STOP - set carry
cmd_stop0       ror endflag                     ; set stop/end flag
cmd_stop1       clr filenum                     ; reset I/O to console
                ldx curline                     ; in immediate mode?
                beq cmd_stop2                   ; brif so - don't save the continue pointers
                stx contline                    ; save pointer to current line for CONT
                ldx curstmt                     ; get current statement address
                stx contstmt                    ; save it for CONT
cmd_stop2       rol endflag                     ; get STOP/END to C (1=STOP)
                bcc cmd_stop3                   ; brif END - don't do message
                ldx #breakmsg                   ; do "BREAK IN"
                jmp ERROR2                      ; the bottom half of the error handler can deal with the details
cmd_stop3       puls x,pc                       ; lose return address and return to caller of interpretation loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The NEW command.
;
; This also includes several useful entry points:
;
; cmd_newraw: does the whole NEW but without any syntax checks
; cmd_newinptr: skips clearing the program text
; cmd_newvars: clears variables and resets the stack and other misc state
; cmd_newstack: just reset the stack and other misc state
cmd_new         bne cmd_new0                    ; brif there was an argument - don't wipe things out on syntax error
cmd_newraw      ldx prog_linetab                ; get start of program line table
                stx prog_linetabp               ; clear out all line entries
                leax linetabent_size*(linetab_stride+1),x ; make room for default program line entries and one extra
                stx [prog_linetabp]             ; set the pointer for the dummy ending entry
                stx prog_text                   ; set end of program line table
                stx vartab                      ; set start of variables after that
cmd_newinptr    ldx zero                        ; blank out current line pointer - we'll fall back to immediate mode
                stx curline
                ldx #zero                       ; point to a zero input byte - will read as end of line
                stx inputptr
cmd_newvars     ldx memsize                     ; get top of memory
                stx stringtab                   ; clear out string space
                ldx vartab                      ; get start of variables
                stx objecttab                   ; set start of large objects (arrays) there too (clear vars)
                stx freestart                   ; set start of free memory (end of large objects) (clear arrays)
cmd_newstack    ldx #stringstackend             ; reset string stack (string stack counts down)
                stx stringstackptr
                ldx ,s                          ; get return address
                lds freetop                     ; reset stack to top of memory
                clr ,-s                         ; put a flag to stop stack searches (NEXT, RETURN)
                sts cstackptr                   ; reset pointer for call stack
                clr contstmt                    ; clear "CONT" destination
                clr contstmt+1
                jmp ,x                          ; return to caller
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; REM and ' commands; also ELSE comes here since it needs to skip the rest of the line in that case.
cmd_else
cmd_apos
cmd_rem         clra                            ; clear carry
                ldx curline                     ; get start of current line
                beq cmd_stop3                   ; brif immediate mode - fall back to caller
                ldx ,x                          ; get address of next line
                leax -1,x                       ; move back one
                stx inputptr                    ; put input pointer there
cmd_new0        rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DATA command
;
; need to skip to the end of the current statement, which is either the end of the line OR a colon not included inside
; a quoted string
cmd_data        ldx inputptr                    ; get input pointer
cmd_data0       lda ,x+                         ; get character at pointer
                beq cmd_data1                   ; brif end of line
                cmpa #':                        ; end of statement?
                bne cmd_data2                   ; brif not
cmd_data1       leax -1,x                       ; move back to the NUL or colon
                stx inputptr                    ; reset input pointer for interpreter
                rts
cmd_data2       cmpa #'"                        ; start of constant string?
                bne cmd_data0                   ; brif not - process more characters
cmd_data3       lda ,x+                         ; get next string character
                beq cmd_data1                   ; brif end of line
                cmpa #'"                        ; string delimiter?
                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 prog_text                   ; 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
cmd_gosub0      jsr prog_findline               ; 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       jsr parse_lineno                ; parse the destination line so return location is after the line number
                ldd #token_gosub*256+4          ; stack frame details
                jsr cstack_alloc                ; make a stack frame
                ldx curline                     ; save current line pointer
                stx ,u
                ldx inputptr                    ; save current input pointer
                stx 2,u
                bra cmd_gosub0                  ; go finish up as a GOTO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; RETURN command
; POP command
;
; RETURN will search the call stack for the first GOSUB frame and remove all other placeholders it finds. A frame type
; of 0 will cause it to stop.
cmd_pop         skip1lda                        ; set nonzero for POP
cmd_return      clra                            ; set zero for RETURN
                pshs a                          ; save operation type
                jsr cstack_first                ; get first entry on call stack
                bne cmd_return1                 ; brif there's a frame - don't error
RG_ERROR        ldb #err_rg                     ; raise RETURN without GOSUB
                jmp ERROR
cmd_return0     jsr cstack_next                 ; move to next entry
                beq RG_ERROR                    ; brif end of stack - raise error
cmd_return1     cmpb #token_gosub               ; do we have a GOSUB frame?
                bne cmd_return0                 ; brif not - try again
                lda ,s+                         ; is it "POP"?
                bne cmd_return2                 ; brif so - don't change flow control but clear stack frame
                ldx ,u                          ; get back saved line pointer
                stx curline
                ldx 2,u                         ; get back saved input pointer
                stx inputptr
cmd_return2     jsr cstack_popto                ; clean up call stack
                bra cmd_data                    ; move to end of statement (move past any "ON GOSUB" entries
                *pragmapop list