Five Column Mode!

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Five Column Mode!

Post by chysn »

Screen Shot 2021-07-14 at 9.35.10 PM.png
Here's a super-simple 5-column display routine. I haven't gone through all the special character handling that CHROUT does, but that's because I don't know what, if anything, I'll ever use this for.

This idea sort of arose from some code I wrote for another topic (viewtopic.php?f=10&t=10135#p113451), for using the 4x4 pixel "chunky" PETSCII bitmap.

It can be used to list programs (SYS6144:LIST) and stuff, because it scrolls the screen. (Note: This newer version sets color):

Code: Select all

; Five Column Mode
; Usage
;     jsr Init5x5               ; Set up 5 column mode, reset to top left
;     lda #"*"                  ; Normal invocation of
;     jsr $ffd2                 ; CHROUT
; Or...
;     ldx #ROW                  ; 0-4
;     ldy #COLUMN               ; 0-4
;     jsr BigPlot
;     lda #"*"
;     jsr $ffd2
; Or...
;     jsr BigHome
;     etc...

; Memory
SCR_PAGE  = $0288               ; Holds screen page
CHAR_PAGE = $80                 ; Character data page
LAST_CHAR = $d7                 ; Character to print
CHAR      = $d3                 ; Address of character data (2 bytes)
SCR_PTR   = $d1                 ; Address of character draw (2 bytes)
BYTE1     = $c3                 ; First bitmap byte in pair
BYTE2     = $c4                 ; Second bitmap byte in pair
IX        = $07                 ; Index to bitmap character
COL_COUNT = $f9                 ; Columns left before next row
ROW_COUNT = $fa                 ; Rows left before scroll
COL_PTR   = $f3                 ; Screen color pointer
CURR_COL  = $0286               ; Current color code
SCROLL    = $e975               ; Scroll routine
CLSR      = $e55f               ; Clear screen
SET_COL   = $eab2               ; Calculate color pointer

* = $1800

; Initialize 5 Column Mode
Init5x5:    jsr CLSR            ; Clear screen
            lda #<BigCharOut    ; Set CHROUT vector
            sta $0326           ; ,,
            lda #>BigCharOut    ; ,,
            sta $0327           ; ,,
BigHome:    ldx #0              ; Home character position
            ldy #0              ; ,,
            ; Fall through to BigPlot
                      
; Position Big Character
; Y is the COLUMN
; X is the ROW
; Backwards, like PLOT  
BigPlot:    sty COL_COUNT       ; Set row and column counts to keep
            stx ROW_COUNT       ;   track of scrolling and linefeeds
            lda #0              ; Initialize screen pointer to top
            sta SCR_PTR         ; ,,
            lda SCR_PAGE        ; ,,
            sta SCR_PTR+1       ; ,,
            cpx #0              ; If plotting to first row, only do columns
            beq just_col        ; ,,
-loop:      lda #88             ; Drop four lines down for each row
            jsr ScreenAdd       ; ,,
            dex                 ; ,,
            bne loop            ; ,,
just_col:   tya                 ; Add 4 for each column
            asl
            asl
            ; Fall through to ScreenAdd
            
; Add A to Screen Pointer
ScreenAdd:  clc
            adc SCR_PTR
            sta SCR_PTR
            bcc add_r
            inc SCR_PTR+1
add_r:      rts            

; Write Big Char to Screen
; In A
BigCharOut: sta LAST_CHAR       ; Store last character       
            pha                 ; Store registers, because that is
            txa                 ;   what's expected of a CHROUT
            pha                 ;   handler
            tya                 ;   ,,
            pha                 ;   ,,
            lda LAST_CHAR       ; Get character to print
            cmp #$0d            ; Handle linefeed character
            bne non_lf          ; ,,
            ldy #0
            ldx ROW_COUNT
            inx
            jsr BigPlot         
            jmp ch_row          ; Advance to next row
non_lf:     cmp #$20            ; Ignore everything else below space
            bcs write           ; ,,
            jmp $e6dc           ; Finish CHROUT
write:      and #$bf            ; Convert provided PETSCII value into a
            bpl BigCode         ;   screen code, for character image lookup.
            and #$7f            ;   ,,
            ora #$40            ;   ,,
BigCode:    sta CHAR            ; Set the character code in the screen
            lda #$00            ;   address
            sta CHAR+1          ;   ,,
            ldy #3              ; Now multiply it by 8 (code x character size)
-loop:      asl CHAR            ;   to get the character image offset address
            rol CHAR+1          ;   ,,
            dey                 ;   ,,
            bne loop            ;   ,,
            lda #CHAR_PAGE      ; Then, get the full character image address
            clc                 ;   into CHAR by adding the character set
            adc CHAR+1          ;   page to the high byte
            sta CHAR+1          ;   ,,
            ldx #3              ; Initialize X as row iterator
row_loop:   ldy #0              ; BYTE 1 and BYTE2 are the next two bytes of
            lda (CHAR),y        ;   character memory. We'll deal with all 8
            sta BYTE1           ;   rows of the character, two at a time
            iny                 ;   ,,
            lda (CHAR),y        ;   ,,
            sta BYTE2           ;   ,,
            txa                 ; (Store X, the iterator for rows, during
            pha                 ;   the column loop)
            ldy #3              ; Likewise, we deal with 8 columns of each
-loop:      lda BYTE2           ;   pair of rows, two at a time.
            and #%00000011      ;   ,,
            asl                 ;   ,,
            asl                 ;   ,,
            sta IX              ; IX is the bitmap table index
            lda BYTE1           ; The low two bits of the indexare in BYTE1
            and #%00000011      ;   ,,
            ora IX              ; Combine low and high two bits
            tax                 ; Move the index to X
            lda Bitmaps,x       ; Get the proper chunky graphic character
            sta (SCR_PTR),y     ; Put it on the screen
            jsr SET_COL         ; Set the color pointer
            lda CURR_COL        ; Get the current color
            sta (COL_PTR),y     ; Set the color
            lsr BYTE1           ; Shift bytes to get next pairs
            lsr BYTE1           ; ,,
            lsr BYTE2           ; ,,
            lsr BYTE2           ; ,,
            dey                 ; Iterator for columns
            bpl loop            ; ,,
            lda #22             ; Drop pointer to next screen row for next
            jsr ScreenAdd       ;   pair of rows
next_row:   lda CHAR            ; Advance character data pointer to the next
            clc                 ;   pair of rows
            adc #2              ;   ,,
            sta CHAR            ;   ,,
            bne dec_row         ;   ,,
            inc CHAR+1          ;   ,,
dec_row:    pla                 ; Get the row iterator back and decrement
            tax                 ; ,,
            dex                 ; ,,
            bpl row_loop        ; ,,
            lda SCR_PTR         ; Advance the character pointer by subtracting
            sec                 ; 88 characters (3 rows up = 88 - 5
            sbc #84             ;   characters to the right = 83)
            sta SCR_PTR         ;   ,,
            bcs in_col          ;   ,,
            dec SCR_PTR+1       ;   ,,
in_col:     inc COL_COUNT       ; Do we need linefeed?
ch_col:     lda COL_COUNT       ; ,,
            cmp #5              ; ,,
            bcc charout_r       ; ,,
            lda #0              ; If so, reset column count
            sta COL_COUNT       ; ,,
            lda #68             ; Increment screen pointer by 68
            jsr ScreenAdd       ;   (3 rows down = 66 + 2 to right = 68)
ch_row:     inc ROW_COUNT       ; Do we need to scroll?
            lda ROW_COUNT       ; ,,
            cmp #5              ; ,,
            bcc charout_r       ; ,,
            dec ROW_COUNT       ; Set row count back to 4
            jsr SCROLL          ;   Scroll 4 lines
            jsr SCROLL          ;   ,,
            jsr SCROLL          ;   ,,
            jsr SCROLL          ;   ,,
            lda SCR_PTR         ; Back up 6 rows
            sec                 ; ,,
            sbc #132            ; ,,
            sta SCR_PTR         ; ,,
            bcs charout_r       ; ,,
            dec SCR_PTR+1       ; ,,
charout_r:  jmp $e6dc           ; Finish CHROUT

; Character at Index N
; N bit 0 = Upper Right (y=even, x=odd)
; N bit 1 = Upper Left  (y=even, x=even)
; N bit 2 = Lower Right (y=odd, x=odd)
; N bit 3 = Lower Left  (y=odd, x=even)          
Bitmaps:    .byte 32,124,126,226,108,225,127,251
            .byte 123,255,97,236,98,254,252,160
And the usage from BASIC can be something like this (which produced the output at the top of the post):
Screen Shot 2021-07-14 at 9.36.29 PM.png
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Victragic
Frogger '07
Posts: 605
Joined: Tue Nov 14, 2006 5:56 pm
Location: South Australia

Re: Five Column Mode!

Post by Victragic »

Finally, a large-print version of the Vic for those of us with failing eyesight..!
3^4 is 81.0000001
Post Reply