changeset 7:b898c74f745c

Add console output driver and a greeting message At basic VDG/SG4 console output driver and handle displaying the greeting message on colde start or just clearing the screen on a warm start. This will be replaced by a more capable console driver in a future update. Note that the console treats CR and LF according to their proper definition (return carriage and move one line forward). CR, LF, and BS are all non-destructive. To get a destructive backspace, do "BS SPACE BS". TAB stops are eight spaces and outputing TAB *is* destructive.
author William Astle <lost@l-w.ca>
date Fri, 04 Nov 2022 17:10:38 -0600
parents 80b9b4503bb4
children 6e8bb5223e6a
files src/lwbasic.s
diffstat 1 files changed, 107 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/lwbasic.s	Fri Nov 04 00:33:38 2022 -0600
+++ b/src/lwbasic.s	Fri Nov 04 17:10:38 2022 -0600
@@ -8,6 +8,7 @@
                 *pragmapush list
                 *pragma nolist
                 *pragma noexpandcond
+                *pragma cescapes
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                
 ; Utility macros
 ;
@@ -183,9 +184,11 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Start of memory which has the direct page and other data.
                 org 0
+dpstart         equ *                           ; start of direct page
                 rmb 0x71-*                      ; align RSTFLG/RSTVEC for stock ROM compatibility
 RSTFLG          rmb 1                           ; 0x55 if RSTVEC is valid
 RSTVEC          rmb 2                           ; points to warm start routine (must start with NOP)
+console_curptr  rmb 2                           ; current cursor pointer for console driver
                 rmb 0x100-*                     ; make sure the stuff that isn't direct page is outside of it
 SW3VEC          rmb 3                           ; SWI3 vector (for compatibility)
 SW2VEC          rmb 3                           ; SWI2 vector (for compatibility)
@@ -328,6 +331,8 @@
                 blo initc6                      ; brif not
                 jmp initc7                      ; go back to mainline
 initc7          lds #textscreen                 ; reset stack to somewhere safe
+                lda #0x12                       ; activate ROM warm start handler
+                sta warmstart
                 ldx #INT.FLAG                   ; point to bounce vector destination
                 ldu #int_init                   ; point to initializer for bounce vectors
                 ldb #int_inite-int_init         ; number of bytes to copy
@@ -374,7 +379,108 @@
                 endc
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Cold start handling
-coldstart       
+coldstart       ldx #dpstart                    ; point to start of direct page
+                ldd #0                          ; set up for blanking
+coldstart0      std ,x++                        ; blank a couple of bytes
+                cmpx #textscreen                ; end of low memory?
+                blo coldstart0                  ; brif not
+                ldx #warmstart                  ; set up warm start handler
+                stx RSTVEC
+                lda #0x55                       ; activate warm start handler
+                sta RSTFLG
+                ldx #greeting                   ; display greeting
+                jsr console_outstr
+                bra *
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Warm start handling
+                ifdef COCO3
+warmstart       fcb 0xff                        ; set to 0xff to force ROM/RAM copy on reset
+                else
+warmstart       nop                             ; flag warm start routine as valid
+                endc
+                jsr console_clear                ; clear screen
+                bra *
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; System startup message
+; (start with form feed to clear screen; saves 2 bytes over 'jsr console_clear' in cold start)
+greeting        fcc '\fLWBASIC VERSION 2022.0\r\n'
+                fcc 'COPYRIGHT (C) 2022 BY LOST\r\n'
+                fcc 'WIZARD ENTERPRISES INC.\r\n'
+                fcs '\n'
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Console output driver
+;
+; Clear screen
+console_clear   ldb #0x60                       ; VDG space character
+                ldx #textscreen                 ; point to text screen
+                stx console_curptr              ; set cursor pointer to start of screen
+console_clear0  stb ,x+                         ; blank a character
+                cmpx #textscreen+0x200          ; end of screen?
+                blo console_clear0              ; brif not
+                rts
+; Output NUL terminated string
+console_outstr0 bsr console_outchr              ; output the character
+console_outstr  lda ,x+                         ; get byte from string
+                bne console_outstr0             ; brif not end of string
+                rts
+; Output a single character to the screen; enter with character in A
+console_outchr  pshs d,x                        ; save registers
+                ldx #console_curptr             ; get current cursor pointer
+                cmpa #0x20                      ; printable character?
+                bne console_outchr5             ; brif not
+                tsta                            ; is it a graphics block?
+                beq console_outchr1             ; brif so - don't do anything to it
+                cmpa #0x40                      ; number or most non-alpha characters?
+                blo console_outchr0             ; brif so - will need to flip bit 6
+                cmpa #0x60                      ; upper case?
+                blo console_outchr1             ; brif so - don't need to do anything to it
+                anda #0xdf                      ; clear bit 5 of lower case; moves it to bottom of character set
+console_outchr0 eora #0x40                      ; flip bit 6 - the "inversion" bit
+console_outchr1 sta ,x+                         ; stick it on screen
+console_outchr2 stx console_curptr              ; save new cursor pointer
+                cmpx #textscreen+0x200          ; end of screen?
+                blo console_outchr4             ; brif not
+                leax -32,x                      ; move pointer back one line
+                stx console_curptr
+                ldx #textscreen                 ; point to start of screen
+console_outchr3 ldd 32,x                        ; get bytes from next line
+                std ,x++                        ; stick them here
+                cmpx #textscreen+0x1e0          ; at last row?
+                blo console_outchr3             ; brif not
+                ldb #0x60                       ; space character for VDG screen
+                bsr console_clear0              ; blank out last row (borrowing screen clear loop)
+console_outchr4 puls d,x,pc                     ; restore registers and return
+console_outchr5 cmpa #0x0c                      ; form feed?
+                bne console_outchr6             ; brif not
+                bsr console_clear               ; clear screen
+                puls d,x,pc                     ; restore registers and return
+console_outchr6 cmpa #0x0d                      ; carriage return?
+                bne console_outchr7             ; brif not
+                ldb console_curptr+1            ; get current screen pointer LSB
+                andb #0xe0                      ; reset offset to start of line
+                stb console_curptr+1            ; save new pointer LSB
+                puls d,x,pc                     ; restore registers and return
+console_outchr7 cmpa #0x0a                      ; line feed?
+                bne console_outchr8             ; brif not
+                ldx console_curptr              ; get cursor pointer
+                leax 32,x                       ; move it forward exactly one line
+                bra console_outchr2             ; go update stuff check for scroll
+console_outchr8 cmpa #0x08                      ; backspace?
+                bne console_outchr9             ; brif not
+                cmpx #textscreen                ; at start of screen?
+                beq console_outchr4             ; brif so - backspace does nothing
+                leax -1,x                       ; back up pointer (backspace is non-destructive)
+                bra console_outchr2             ; go update pointers, etc.
+console_outchr9 cmpa #0x09                      ; TAB character?
+                bne console_outchr4             ; brif not
+                ldb console_curptr              ; get LSB of pointer
+                andb #7                         ; 8 space tabs - only keep low 3 bits
+                lda #0x60                       ; space character (tab is destructive)
+console_outchra sta ,x+                         ; put a space out
+                incb                            ; bump counter
+                cmpb #8                         ; at next tab stop?
+                blo console_outchra             ; brif not
+                bra console_outchr2             ; go update details and check for scroll
                 ifndef COCO3
 ; Need to ensure the vectors are at 0xbff2
                 zmb 0xbff2-*                    ; pad ROM up to the vector point