view src/genio.s @ 125:0607e4e20702

Correct offset error for keyword table lookup
author William Astle <lost@l-w.ca>
date Sun, 07 Jan 2024 20:35:51 -0700
parents e74d00ac6b79
children
line wrap: on
line source

                *pragmapush list
                *pragma list
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; General I/O handling package
;
; These routines operate on the I/O channel specified by filenum. The defined values of filenum are:
;
; 0: keyboard/screen console
;
; Read a line from the active file into linebuff. The resulting line will be NUL terminated leading to at most
; linbuffsize-1 character input. The trailing CR/LF will not be included. The input will be echoed if linebuffecho is
; enabled. Exit with the length of the input line in B.
readline        ldx #linebuff                   ; point to line input buffer
                clr ,x                          ; make sure buffer is NUL terminated
readline0       bsr readchr                     ; read an input character
                bcs readline1                   ; brif not EOF
                cmpa #0x0d                      ; CR (carriage return)
                beq readline1                   ; brif so - return
                cmpa #0x03                      ; BREAK?
                bne readline3                   ; brif not
                coma                            ; set carry for irregular exit
                skip1
readline1       clra                            ; clear carry for regular exit
                pshs cc                         ; save carry state
                lda readlinenoecho              ; are we echoing?
                bne readline2                   ; brif not
                lda #0x0d                       ; echo carriage return + line feed
                bsr writechr
readline2       tfr x,d                         ; get end address after input
                subd #linebuff                  ; subtract start of buffer; D is now length and C is clear
                clr ,x                          ; make sure line is NUL terminated
                puls cc,pc                      ; restore BREAK flag (C) and return
readline3       cmpa #0x08                      ; backspace?
                bne readline4                   ; brif not
                cmpx #linebuff                  ; at start of buffer?
                beq readline0                   ; brif so - do nothing
                leax -1,x                       ; move back buffer pointer
                bsr readlinee                   ; write a BS
                lda #0x20                       ; write a space
                bsr readlinee
                lda #0x08                       ; and finally a BS
                bsr readlinee
                bra readline0                   ; go process more characters
readline4       cmpa #0x0c                      ; form feed?
                bne readline5                   ; brif not
                bsr readlinee                   ; go echo character if needed
                bra readline                    ; go restart line entry
readline5       cmpa #0x20                      ; is it non-printing?
                blo readline0                   ; brif so - don't store it and continue
                bsr readlines                   ; stash character in buffer and echo if necessary
                bra readline0                   ; go get another character
readlines       cmpx #linebuff+linebuffsize-1   ; is the line buffer full?
                bhs readlinee0                  ; brif so - don't store character OR echo it
                sta ,x+                         ; stash character
readlinee       ldb readlinenoecho              ; are we echoing?
                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
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?
                bne writechr_scr0               ; brif not
                lda #0x0a                       ; ouptut an LF
                jsr console_outchr
                lda #0x0d                       ; restore original value
writechr_scr0   andcc #0xfe                     ; clear error flag
                rts
; Read a character from the active file and return it in A; in the event that EOF is detected, readeof will be nonzero
; and the call will return with carry set.
readchr         clr fileeof                     ; flag not end of file (and clear carry)
                lda filenum                     ; get input file number
                beq readchr_kb                  ; brif keyboard input
                com fileeof                     ; flag end of file (C set and fileeof nonzero)
                rts
; Read character from keyboard; blink cursor while doing so
readchr_kb      pshs b                          ; preserve B as temp storage
                ldb [console_curptr]            ; get character at cursor
                inc console_blnkdel             ; activate cursor blinking (first interrupt will cycle it)
readchr_kb0     jsr keyb_getkey                 ; read keyboard
                bcc readchr_kb1                 ; brif we got a result
                cwai #0xaf                      ; wait for interrupt to scan keyboard
                bra readchr_kb0                 ; see if we have something yet
readchr_kb1     clr console_blnkdel             ; disable cursor blinking
                stb [console_curptr]            ; restore screen character
                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?
                bne 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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
                *pragmapop list