;license:MIT ;(c) 2018-2021 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 array of length-prefixed strings ; length #$FF terminates ; 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 $FF ; clobbers A/X/Y ; preserves C, other flags clobbered stx $FF ldx #0 stx VTAB +ST16 PTR @drawLine lda $FF sta HTAB ldy #0 lda (PTR), y ; A = length of line, or #$FF bmi drawLineDone ; if #$FF then we're done php ; C = whatever was passed in pha ; save length jsr DrawStringSuperInternal pla ; A = length of line clc ; advance PTR to start of next line adc PTR sta PTR bcc + inc PTR+1 + plp inc VTAB ; this will print 255 lines if you give bne @drawLine ; it 255 lines, because this is assembly drawLineDone rts Draw40CharsInternal ; A/Y contains address of character buffer ; carry bit clear -> draw on page 1 ;v 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 +ST16 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 +ST16 PTR ldy #0 + lda (PTR),y DrawStringSuperInternal tax inc PTR bne + inc PTR+1 + +LD16 PTR ; /!\ execution falls through here to DrawBufferInternal DrawBufferInternal ; A/Y contains address of character buffer ; X contains buffer length (0..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 +ST16 DBISrc+1 dex bmi drawLineDone ; empty string php 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 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