;license:MIT ;(c) 2018-2020 by 4am ; ; hi-res font drawing routines ; ; /!\ These live in LC RAM 2 and rely on the font data which is also in LC RAM 2. /!\ ; Code in LC RAM 1 (which is most program code) should call the functions in ui.font ; which handle bank switching for you. ; DrawPageInternal ; A/Y contains address of character buffer ; X contains 0-indexed left margin (HTAB) ; carry bit clear -> draw on page 1 ; carry bit set -> draw on page 2 ; drawing starts at VTAB 0 ; each line starts at column X which was passed in (0-indexed) ; clobbers PTR ; clobbers A/X/Y ; preserves all flags, by a quirk of implementation php stx @leftMargin ldx #0 stx VTAB +STAY PTR @drawLine @leftMargin=*+1 lda #$FD ; SMC sta HTAB ldy #0 @parseLine lda (PTR),y cmp #$5B ; '[' at beginning on line bne + ; ends the parsing tya beq @donePage + cmp #$0A beq @doneParsingLine ldx #3 - cmp @subs_a,x bne @nosub lda @subs_b,x sta (PTR),y @nosub dex bpl - iny bne @parseLine @doneParsingLine sty SAVE tya beq @skip ldx SAVE +LDAY PTR plp php jsr DrawBufferInternal @skip inc SAVE ; skip carriage return lda SAVE ; advance PTR to start of next line clc adc PTR sta PTR bcc + inc PTR+1 + inc VTAB ; this will print 255 lines if you give it bne @drawLine ; 255 lines, so don't do that @donePage plp rts @subs_a !byte $2A,$7E,$3C,$3E @subs_b !byte $10,$11,$08,$15 Draw40CharsInternal ; A/Y contains address of character buffer ; carry bit clear -> draw on page 1 ; carry bit set -> draw on page 2 ; $25 contains textpage line (0..23) (this is the standard VTAB address) ; drawing starts at HTAB 0 ; increments VTAB ; sets HTAB to 0 on exit ; clobbers A/X/Y jsr + ldx #40 jsr DrawBufferInternal inc VTAB + ldx #0 stx HTAB rts DrawCenteredStringInternal ; A/Y contains address of length-prefixed string ; carry bit clear -> draw on page 1 ; carry bit set -> draw on page 2 ; $25 contains textpage line (0..23) (this is the standard VTAB address) ; clobbers A/X/Y ; clobbers PTR/PTR+1 +STAY PTR ldy #0 php lda #40 sec sbc (PTR),y lsr sta HTAB plp beq + DrawStringInternal ; A/Y contains address of length-prefixed string ; carry bit clear -> draw on page 1 ; carry bit set -> draw on page 2 ; $24 contains starting column (0..39) (this is the standard HTAB address) ; $25 contains textpage line (0..23) (this is the standard VTAB address) ; clobbers A/X/Y ; clobbers PTR/PTR+1 +STAY PTR ldy #0 + lda (PTR),y tax inc PTR bne + inc PTR+1 + +LDAY PTR ; /!\ execution falls through here to DrawBufferInternal DrawBufferInternal ; A/Y contains address of character buffer ; X contains buffer length (1..40) ; carry bit clear -> draw on page 1 ; carry bit set -> draw on page 2 ; characters MUST have high bit off (0x00..0x7F) ; special characters (0x00..0x1F) will be drawn ; $24 contains starting column (0..39) (this is the standard HTAB address) ; $25 contains textpage line (0..23) (this is the standard VTAB address) ; all characters are drawn on the same line ; HTAB is incremented for each character ; VTAB is NOT incremented ; clobbers A/X/Y +STAY DBISrc+1 php dex lda VTAB asl asl asl ; routine to calculate memory address within HGR page ; and self-modify addresses within draw loop that follows ; (routine clobbers A and Y but preserves X) asl tay and #$F0 bpl @calc1 ora #$05 @calc1 bcc @calc2 ora #$0A @calc2 asl asl sta @hgrlo+1 tya and #$0E adc #$10 asl @hgrlo+1 rol plp bcc + eor #$60 clc + sta DBIRow0+2 adc #$04 sta DBIRow1+2 adc #$04 sta DBIRow2+2 adc #$04 sta DBIRow3+2 adc #$04 sta DBIRow4+2 adc #$04 sta DBIRow5+2 adc #$04 sta DBIRow6+2 adc #$04 sta DBIRow7+2 @hgrlo lda #$FD clc adc HTAB sta DBIRow0+1 sta DBIRow1+1 sta DBIRow2+1 sta DBIRow3+1 sta DBIRow4+1 sta DBIRow5+1 sta DBIRow6+1 sta DBIRow7+1 DBILoop DBISrc ldy $FDFD,x lda FontDataRow0,y DBIRow0 sta $FDFD,x lda FontDataRow1,y DBIRow1 sta $FDFD,x lda FontDataRow2,y DBIRow2 sta $FDFD,x lda FontDataRow3,y DBIRow3 sta $FDFD,x lda FontDataRow4,y DBIRow4 sta $FDFD,x lda FontDataRow5,y DBIRow5 sta $FDFD,x lda FontDataRow6,y DBIRow6 sta $FDFD,x lda FontDataRow7,y DBIRow7 sta $FDFD,x inc HTAB dex bpl DBILoop rts