;*** vbmlib 1.10 package - by Craig Bruce - 13-Nov-93

;vdc register values courtesy of Fred Bowen of Commodore

;vdc memory: 00000-21359=even frame, 21360-42719=odd frame
;bm file: 0-3=format ('b,'m,$cb,$02), 4-5=widthLH, 6-7=heightLH, 8-end=bmData

.org $1300
.obj "@0:vbmlib.bin"

vdcStat    = $d600
vdcData    = $d601
evenFrame  = 0
oddFrame   = 21360

chkin  = $ffc6
chrin  = $ffcf
clrchn = $ffcc

        jmp vbmInit     ;()
        jmp vbmFinish   ;()
        jmp vbmFill     ;( .A=fillValue )
        jmp vbmRead     ;( .A=width8, .X=leftMargin8, ($fa)=dispHeight,
                        ;  ($fc)=topMargin )

        .byte $cb,$06,11

vdcWrite = *
        stx vdcStat
-       bit vdcStat
        bpl -
        sta vdcData
        rts

vdcRead = *
        stx vdcStat
-       bit vdcStat
        bpl -
        lda vdcData
        rts

vbmInit = *
        cld
        cli
        ldy #0
-       ldx initRegs,y
        lda initVals,y
        cpx #25
        bne +
        jsr vdcRead
        and #$0f
        ora initVals,y
+       jsr vdcWrite
        iny
        cpy #initVals-initRegs
        bcc -
        lda #$aa
        jmp vbmFill

initRegs = *
        .byte 000,001,002,004,005,006,007,008,009,024,025,027,028,020,021
        .byte 012,013,026,012,013
initVals = *            
        .byte $7e,$50,$66,$4c,006,$4c,$47,003,006,000,$80,000,016,166,224
        .byte 000,000,224,0,0    ;last two = >evenFrame,<evenFrame

vbmFill = *  ;( .A=fillValue )
        pha
        ldx #18
        lda #>evenFrame
        jsr vdcWrite
        ldx #19
        lda #<evenFrame
        jsr vdcWrite
        ldx #31
        pla
        jsr vdcWrite
        ldy #161
-       ldx #30
        lda #$00
        jsr vdcWrite
        dey
        bne -
        rts

vbmFinish = *
        jsr $e179
        jsr $ff62
        lda #147
        jsr $ffd2
        rts

height    = $fa ;(2)
topMargin = $fc ;(2)
lmargin   = $fe ;(1)
rmargin   = $ff ;(1)
dispwidth .buf 1
baseaddr  = $fc ;(2)
evenodd   .buf 1
width     .buf 1

vbmRead = *  ;( .A=width8, .X=leftMargin8, ($fa)=height, ($fc)=topMargin )
        ;** adjust width
        sta width
        stx lmargin
        sec
        sbc lmargin
        cmp #80
        bcs +
        sta dispwidth
        lda #0
        sta rmargin
        jmp adjustHeight
+       sbc #80
        sta rmargin
        lda #80
        sta dispwidth

        ;** adjust height
        adjustHeight = *
        sec
        lda height+0
        sbc topMargin+0
        sta height+0
        lda height+1
        sbc topMargin+1
        sta height+1
        lda height+0
        cmp #<492
        lda height+1
        sbc #>492
        bcc setInput
        lda #<492
        ldy #>492
        sta height+0
        sty height+1

        ;** set input
        setInput = *
        ldx #1
        jsr chkin
        bcc +
        rts
+       nop

        ;** skip top margin
-       lda topMargin+0
        ora topMargin+1
        beq ++
        ldy width
-       jsr chrin
        dey
        bne -
        lda topMargin+0
        bne +
        dec topMargin+1
+       dec topMargin+0
        jmp --
+       nop

        ;** read the lines
        lda #0
        sta baseaddr+0
        sta baseaddr+1
        sta evenodd
-       lda height+0
        ora height+1
        bne +
        jsr clrchn
        rts
+       jsr displayLine
        lda evenodd
        and #$01
        beq +
        clc
        lda baseaddr+0
        adc #80
        sta baseaddr+0
        bcc +
        inc baseaddr+1
+       inc evenodd
        lda height+0
        bne +
        dec height+1
+       dec height+0
        jmp -

displayLine = *
        ;** set line address
        lda evenodd
        and #$01
        bne +
        lda baseaddr+0
        pha
        lda baseaddr+1
        jmp ++
+       clc
        lda baseaddr+0
        adc #<oddFrame
        pha
        lda baseaddr+1
        adc #>oddFrame
+       ldx #18
        jsr vdcWrite
        ldx #19
        pla
        jsr vdcWrite

        ;** poke line
        ldy lmargin
        beq +
-       jsr chrin
        dey
        bne -
+       ldy dispwidth
        beq +
-       jsr chrin
        eor #$ff
        ldx #31
        jsr vdcWrite
        dey
        bne -
+       ldy rmargin
        beq +
-       jsr chrin
        dey
        bne -
+       rts
