view src/genio.s @ 74:e74d00ac6b79

Split some code into separate files for easier management (2) Because the source for lwbasic is so large, split it into several different files to make it easier to navigate and modify. This is part two of the split. Also includes fix for dependency tracking related to the split in the make file.
author William Astle <lost@l-w.ca>
date Sun, 06 Aug 2023 00:36:48 -0600
parents
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