;
; Screen Printf Lib
; coded by Duke / napalm
;
; NOTE: this routine only runs inside mode 640x256x32 without doublebuffering
;


; printf code, draws some text to screen, chr(13) moves to next row
; in: a3 = ptr. text
; wastes: at,t0-t6,a3
_ScrPrintf              PROC

                        push    ra
new_char:               lbu     t0, 0(a3)
                        beqz    t0, endprintf                   ; process all letters except 0
                        addiu   a3, 1                           ; move ptr to next char
                        subi    at, t0, 13
                        bnez    at, no_return
                        
                        ; move cursor to next line
                        la      t1, char2vram.xy+4
                        sh      zero, 0(t1)                     ; x pos
                        lh      t0, 2(t1)                       ; y pos
                        addi    t0, 8
                        subi    at, t0, 256
                        bgezl   at, $+8
                        move    t0, zero
                        sh      t0, 2(t1)
                        b       new_char

                        ; address character
no_return:              subiu   t0, 32                          ; no special characters
                        bltz    t0, new_char                    ; jump over 0..31
                        sll     t0, 3                           ; calc character addr: t0*8
                        la      at, font                        ; add base
                        addu    t0, at                          ; now t0 points at char addr.

                        ; convert black/white (1-bit) data to RGBA (32-bit)
                        li      at, font_color                  ; get selected font color
                        lw      t4, 0(at)                       ; front
                        lw      t5, 4(at)                       ; back

                        la      t6, translated_char             ; our destination buffer
                        li      t1, 8                           ; y counter = 8
horz_loop:              li      t2, 8                           ; x counter = 8
                        lbu     t3, 0(t0)                       ; get first byte of src char = 8 b/w pix
                        addi    t0, 1                           ; address next src char line
vert_loop:              andi    at, t3, 80h                     ; keep MSB
                        sll     t3, 1                           ; shift to next pixel of src char

                        bnez    at, not_bgcolor
                        move    at, t4
                        move    at, t5
not_bgcolor:            sw      at, 0(t6)

                        subi    t2, 1                           ; x++
                        bnez    t2, vert_loop                   ; process 8 bits per line
                        addi    t6, 4                           ; and inc dest addr.
                        subi    t1, 1                           ; y++
                        bnez    t1, horz_loop                   ; loop 8 times

                        ; flush
                        SysFlushCache

                        ; print char to vram (send primitive)
                        la      t0, char2vram
                        addiu   t1, zero, char2vram._size/16
                        addiu   t2, zero, 101h
                        jal     Dma02Wait
                        nop
                        li      at, DMA02
                        sw      t0, DMA_MADR(at)
                        sw      t1, DMA_QWC(at)
                        sw      t2, DMA_CHCR(at)
                        la      t0, translated_char
                        li      t1, 16                          ; (8*8*4)/16
                        jal     Dma02Wait
                        nop
                        li      at, DMA02
                        sw      t0, DMA_MADR(at)
                        sw      t1, DMA_QWC(at)
                        sw      t2, DMA_CHCR(at)
                        jal     Dma02Wait
                        nop

                        ; process next char
                        la      at, char2vram.xy+4
                        lh      t0, 0(at)
                        addiu   t0, 8                           ; x_pos += 8
                        sh      t0, 0(at)

                        b       new_char
                        nop

endprintf:              pop     ra
                        jr      ra
                        nop


font:                   INCLUDE BINARY "scrprntf.bin" ALIGN 4

font_color:             DW      0FFFFFFh, 0


char2vram               TABLE ALIGN 16
                          GIF_TAG     4, 1, 0, 0, 0, 1, GIF_AD
                          GIF_DATA    GIF_BITBLTBUF, (640/64)<<48
  xy:                     GIF_DATA    GIF_TRXPOS, 0
                          GIF_DATA    GIF_TRXREG, (8<<32)|8
                          GIF_DATA    GIF_TRXDIR, 0
                          DD          (8<<56)|16, 0
char2vram               ENDT


                        ALIGN   16
translated_char:        DW      0,0,0,0,0,0,0,0
                        DW      0,0,0,0,0,0,0,0
                        DW      0,0,0,0,0,0,0,0
                        DW      0,0,0,0,0,0,0,0
                        DW      0,0,0,0,0,0,0,0
                        DW      0,0,0,0,0,0,0,0
                        DW      0,0,0,0,0,0,0,0
                        DW      0,0,0,0,0,0,0,0

_ScrPrintf              ENDP



; converts a register value into ascii code
; in: t0 = reg to convert to -> reg buffer (ascii(hex))
_ScrPrintfReg2Ascii     PROC

                        la      a3, reg_buffer
                        li      t2, 8
r2a_loop:               andi    t1, t0, 0Fh
                        subi    at, t1, 9
                        blez    at, less_than_a
                        nop
                        addiu   t1, 7
less_than_a:            addiu   t1, 48
                        sb      t1, 7(a3)
                        subi    a3, 1
                        srl     t0, 4
                        subi    t2, 1
                        bnez    t2, r2a_loop
                        nop
                        jr      ra
                        nop

reg_buffer:             DD      0
                        DB      13,0

_ScrPrintfReg2Ascii     ENDP



; dump register and print to screen macro
ScrPrintfReg            MACRO   _reg
                        add     t0, zero, _reg
                        jal     _ScrPrintfReg2Ascii
                        nop
                        la      a3, _ScrPrintfReg2Ascii.reg_buffer
                        jal     _ScrPrintf
                        nop
ScrPrintfReg            ENDM



; set font front color macro
ScrPrintfSetColor       MACRO   _front,_back
                        la      a3, _ScrPrintf.font_color
                        li      at, _front
                        sw      at, 0(a3)
                        li      at, _back
                        sw      at, 4(a3)
ScrPrintfSetColor       ENDM

COLOR_BLACK             EQU     0000000h
COLOR_RED               EQU     0000044h
COLOR_GREEN             EQU     0004400h
COLOR_BLUE              EQU     0440000h
COLOR_WHITE             EQU     0FFFFFFh



; set screen position macro
ScrPrintfLocate         MACRO   _x,_y
                        la      a3, _ScrPrintf.char2vram.xy+4
                        addi    at, zero, (_x)*8                ; x pos
                        sh      at, 0(a3)
                        addi    at, zero, (_y)*8                ; y pos
                        sh      at, 2(a3)
ScrPrintfLocate         ENDM



; Print to screen macro
ScrPrintf               MACRO   _addr
                        la      a3, _addr
                        jal     _ScrPrintf
                        nop
ScrPrintf               ENDM
