changeset 23:4b4806a32701

Add some error handling framework Include the initial routine for handling error messages with a couple of error messages for testing. This includes a routine to convert to upper case if the chosen output device doesn't support actual lower case. This is mostly intended for the VDG screen since graphics displays, T1 VDG screens, and Coco3 screens can all support actual lower case glyphs, as do any non-local or file devices. This routine is mostly used for displaying error messages and other notices the interpreter needs to display.
author William Astle <lost@l-w.ca>
date Wed, 09 Nov 2022 23:07:33 -0700
parents 06417341c50e
children 9586c547fcfa
files src/lwbasic.s
diffstat 1 files changed, 61 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lwbasic.s	Wed Nov 09 18:09:19 2022 -0700
+++ b/src/lwbasic.s	Wed Nov 09 23:07:33 2022 -0700
@@ -201,6 +201,7 @@
 RSTVEC          rmb 2                           ; points to warm start routine (must start with NOP)
 console_curptr  rmb 2                           ; current cursor pointer for console driver
 console_blnkdel rmb 1                           ; cursor blink delay
+console_truelc  rmb 1                           ; set to nonzero if the console supports true lower case (gfx, etc.)
 filenum         rmb 1                           ; current input/output channel
 fileeof         rmb 1                           ; flag for whether last read detected EOF
 keyb_flags      rmb 1                           ; shift flags for the keyboard
@@ -878,12 +879,25 @@
                 bne readlinee0                  ; brif not
                 bsr writechr                    ; echo the character
 readlinee0      rts
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Write a newline if not at left margin. This will unconditinally output a newline for devices where the horizontal
+; position is not knowable.
+writecondnl     lda filenum                     ; get file number
+                bne writenl                     ; brif not screen - we'll do it unconditionally
+                lda console_curptr+1            ; get LSB of cursor pointer
+                anda #0x1f                      ; keep only the low 5 bits (32 characters per line)
+                beq writecondnl0                ; brif no newline is needed
+                ; fallthrough intended
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Write a newline to the chosen device.
+writenl         lda #0x0d                       ; code for carriage return - will serve as newline
+                ; fallthrough intended
 ; Write a character to the active file; all registers preserved but C will be set if the output file cannot handle
 ; an output character (doesn't exist, etc.)
 writechr        tst filenum                     ; is it screen?
                 beq writechr_scr                ; brif writing to screen
                 orcc #1                         ; unknown device flag
-                rts
+writecondnl0    rts
 ; Handle output to the screen. This is where we convert CR to CRLF
 writechr_scr    jsr console_outchr              ; output the character
                 cmpa #0x0d                      ; was it CR?
@@ -913,14 +927,58 @@
                 clrb                            ; clear carry to indicate not eof
                 puls b,pc                       ; restore temp and return
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Write a character to the selected output device. If the device is one that does not support actual lower case, then
+; conver the character to upper case. Otherwise, pass it through as is. Currently, only the console screen falls into
+; this category. This *will* modify the character in A if a change is made.
+writechrconduc  tst filenum                     ; is it screen?
+                bne writechr                    ; brif not - just output it
+                tst console_truelc              ; does the current text screen support actual lower case?
+                beq writechr                    ; brif so - just output character
+                cmpa #'a                        ; is it lower case?
+                blo writechr                    ; brif not
+                cmpa #'z                        ; is it still lower case?
+                bhi writechr                    ; brif not
+                suba #0x20                      ; shift to upper case
+                bra writechr                    ; go output it
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; The error handler
+;
+; Enter with the error number in B. This routine will do some cleanup and handle any ON ERROR GOTO handler that
+; may be active.
+;
+; Note the error message lookup does not need to be efficient which is why the lookup just runs through the list
+; of error messages in sequence looking for NUL terminators. The specific handling of B (error number) below avoids
+; issues if there happen to be error codes above 128.
+ERROR           clr filenum                     ; reset display device to console
+                jsr writecondnl                 ; do a newline if needed (will preserve B)
+                ldx #errormsg                   ; point to error message list
+                incb                            ; account for decb below
+                bra ERROR0                      ; go search for correct message
+ERROR0          lda ,x+                         ; end of message?
+                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
+ERROR3          
+                
+                ; fall through to immediate mode intentional
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Immediate mode handler
-prompt          fcn 'OK'
-immediate       ldx #prompt                     ; point to prompt string
+immediate       jsr writecondnl                 ; do newline if required
+                ldx #prompt                     ; point to prompt string
                 jsr console_outstrn
 immediate0      jsr readline                    ; read input line
                 bcs immediate0                  ; brif ended with BREAK
                 ; handle line
                 bra immediate
+prompt          fcn 'OK'
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Error messages
+errormsg        fcn 'NEXT without FOR'          ; 0
+                fcn 'Syntax error'              ; 1
                 ifndef COCO3
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Need to ensure the vectors are at 0xbff2