]> git.sur5r.net Git - cc65/blobdiff - libsrc/c128/c128-640-200-2.s
same drawing mode extension like for DrawLine
[cc65] / libsrc / c128 / c128-640-200-2.s
index bb96599f7cb50e4ffed29ddca65cec09be3c2513..c43601fbc0b6f47f6da0221d27c1413e2a09b052 100644 (file)
@@ -1,20 +1,14 @@
 ;
 ; Graphics driver for the 640x200x2 mode on the C128 VDC
-; Maciej 'YTM/Elysium' Witkowiak <ytm@friko.onet.pl>
-; 22.12.2002
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 23.12.2002
 ;
 ; NOTES:
+; For any smart monkey that will try to optimize this: PLEASE do tests on real VDC,
+; not only VICE.
 ;
 ; Only DONE routine contains C128-mode specific stuff, everything else will work in
-; C64-mode of C128.
-;
-; All Y-axis calculations are 16-bit, so this driver will support 640x400 (interlaced)
-; mode only with gfx-mode initialization changed.
-; (is the above true? I can't remember if interlace skips lines or takes them from two
-;  different places (same offset, different base))
-;
-; X-axis resolution can be changed by manipulating xres header field so
-; any resolution 8..708 is possible only with gfx-mode initialization and CALC changed.
+; C64-mode of C128 (C64 needs full VDC init then).
 ;
 ; With special initialization and CALC we can get 320x200 double-pixel mode.
 ;
@@ -75,7 +69,7 @@ pages:        .byte   1                       ; Number of screens available
 ; primitives - for example ploting a line by using calls to SETPIXEL.
 
         .word   INSTALL
-        .word   DEINSTALL
+        .word   UNINSTALL
         .word   INIT
         .word   DONE
        .word   GETERROR
@@ -269,19 +263,19 @@ settestadr2:
        jmp     VDCSetSourceAddr
 
 ; ------------------------------------------------------------------------
-; DEINSTALL routine. Is called before the driver is removed from memory. May
+; UNINSTALL routine. Is called before the driver is removed from memory. May
 ; clean up anything done by INSTALL but is probably empty most of the time.
 ;
 ; Must set an error code: NO
 ;
 
-DEINSTALL:
+UNINSTALL:
         rts
 
 
 ; ------------------------------------------------------------------------
 ; INIT: Changes an already installed device from text mode to graphics
-; mode. The number of the graphics mode is passed to the function in A.
+; mode.
 ; Note that INIT/DONE may be called multiple times while the driver
 ; is loaded, while INSTALL is only called once, so any code that is needed
 ; to initializes variables and so on must go here. Setting palette and
@@ -293,16 +287,18 @@ DEINSTALL:
 ; Must set an error code: YES
 ;
 
-INIT:   cmp     #TGI_MODE_640_200_2     ; Correct mode?
-        beq     @L1                     ; Jump if yes
-        lda     #TGI_ERR_INV_MODE       ; ## Error
-        bne     @L9
+INIT:
 
 ; Initialize variables
 
 @L1:    ldx     #$FF
         stx     BITMASK
 
+; Remeber current color value
+       ldx     #VDC_COLORS
+       jsr     VDCReadReg
+       sta     OLDCOLOR
+
 ; Switch into graphics mode (set view page 0)
 
        ldy     #0
@@ -315,15 +311,10 @@ INIT:   cmp     #TGI_MODE_640_200_2     ; Correct mode?
        bne     @L2
 @L3:
 
-; Remeber current color value
-       ldx     #VDC_COLORS
-       jsr     VDCReadReg
-       sta     OLDCOLOR
-
 ; Done, reset the error code
 
         lda     #TGI_ERR_OK
-@L9:    sta     ERROR
+        sta     ERROR
         rts
 
 ; ------------------------------------------------------------------------
@@ -336,7 +327,8 @@ INIT:   cmp     #TGI_MODE_640_200_2     ; Correct mode?
 
 DONE:
        ; This part is C128-mode specific
-       jsr $ce0c               ; reload character set
+       jsr $e179               ; reload character set and setup VDC
+       jsr $ff62
        lda $d7                 ; in 80-columns?
        bne @L01
 @L0:   lda SCN80CLR,y
@@ -354,7 +346,8 @@ DONE:
        jsr VDCWriteReg         ; restore color (background)
        lda #$47
        ldx #VDC_HSCROLL
-       jmp VDCWriteReg         ; switch to text screen
+       jsr VDCWriteReg         ; switch to text screen
+; fall through to GETERROR in order to clear ERROR status
 
 ; ------------------------------------------------------------------------
 ; GETERROR: Return the error code in A and clear it.
@@ -382,7 +375,7 @@ CONTROL:
 ; Must set an error code: NO
 ;
 
-CLEAR:  
+CLEAR:
        lda     #0
        ldy     SCRBASE
        jsr     VDCSetSourceAddr
@@ -428,7 +421,7 @@ SETDRAWPAGE:
        ror
        ror
        sta     SCRBASE
-        rts
+       rts
 
 ; ------------------------------------------------------------------------
 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
@@ -703,63 +696,70 @@ HORLINE:
 ;
 
 LINE:
-       ; if (x2>x1) {
-       ldx     #X1
-       lda     X2
-       ldy     X2+1
-       jsr     icmp
-       bcc     @L0137
-       beq     @L0137
-       ;  x2<->x1 }
-       lda     X1
-       ldx     X2
-       sta     X2
-       stx     X1
-       lda     X1+1
-       ldx     X2+1
-       sta     X2+1
-       stx     X1+1
-@L0137:        ; if (y2>y1) {
-       ldx     #Y1
-       lda     Y2
-       ldy     Y2+1
-       jsr     icmp
-       bcc     @L013F
-       bne     @nequal
-       jmp     HORLINE         ; x1/x2 are sorted, y1==y2 - do faster horizontal line draw
-@nequal:
-       ; y2<->y1 }
-       lda     Y1
-       ldx     Y2
-       sta     Y2
-       stx     Y1
-       lda     Y1+1
-       ldx     Y2+1
-       sta     Y2+1
-       stx     Y1+1
-@L013F:
-       ; nx = x2 - x1
+       ; nx = abs(x2 - x1)
        lda     X2
        sec
        sbc     X1
        sta     NX
        lda     X2+1
        sbc     X1+1
-       sta     NX+1
-       ; ny = y2 - y1
+       tay
+       lda     NX
+       jsr     abs
+       sta     NX
+       sty     NX+1
+       ; ny = abs(y2 - y1)
        lda     Y2
        sec
        sbc     Y1
        sta     NY
        lda     Y2+1
        sbc     Y1+1
-       sta     NY+1
+       tay
+       lda     NY
+       jsr     abs
+       sta     NY
+       sty     NY+1
+       ; if (x2>x1)
+       ldx     #X2
+       lda     X1
+       ldy     X1+1
+       jsr     icmp
+       bcc     @L0243
+       beq     @L0243
+       ; dx = 1;
+       lda     #1
+       bne     @L0244
+       ; else
+       ; dx = -1;
+@L0243:        lda     #$ff
+@L0244:        sta     DX
+       ; if (y2>y1)
+       ldx     #Y2
+       lda     Y1
+       ldy     Y1+1
+       jsr     icmp
+       bcc     @L024A
+       beq     @L024A
+       ; dy = 1;
+       lda     #1
+       bne     @L024B
+       ; else
+       ; dy = -1;
+@L024A:        lda     #$ff
+@L024B:        sta     DY
+       ; err = ay = 0;
+       lda     #0
+       sta     ERR
+       sta     ERR+1
+       sta     AY
+
        ; if (nx<ny) {
        ldx     #NX
        lda     NY
        ldy     NY+1
        jsr     icmp
-       bcs     @L041B
+       bcs     @L0255
        ;  nx <-> ny
        lda     NX
        ldx     NY
@@ -769,21 +769,19 @@ LINE:
        ldx     NY+1
        sta     NY+1
        stx     NX+1
-       ; dx = dy = 0; ax = ay = 1 }
-       ldy     #1
-       sty     AY
-       dey
-       beq     @L025A
-       ; else { dx = dy = 1; ax = ay = 0 }
-@L041B:        ldy     #0
-       sty     AY
-       iny
-@L025A:        sty     DX
-       sty     DY
-       ; err = 0
+       ; ay = dx
+       lda     DX
+       sta     AY
+       ; dx = dy = 0;
        lda     #0
-       sta     ERR
-       sta     ERR+1
+       sta     DX
+       sta     DY
+       ; ny = - ny;
+@L0255:        lda     NY
+       ldy     NY+1
+       jsr     neg
+       sta     NY
+       sty     NY+1
        ; for (count=nx;count>0;--count) {
        lda     NX
        ldx     NX+1
@@ -795,13 +793,13 @@ LINE:
        rts
        ;    setpixel(X1,Y1)
 @L0167:        jsr     SETPIXELCLIP
-       ;    pb = err - ny
+       ;    pb = err + ny
        lda     ERR
-       sec
-       sbc     NY
+       clc
+       adc     NY
        sta     PB
        lda     ERR+1
-       sbc     NY+1
+       adc     NY+1
        sta     PB+1
        tax
        ;    ub = pb + nx
@@ -813,21 +811,27 @@ LINE:
        adc     NX+1
        sta     UB+1
        ;    x1 = x1 + dx
-       lda     X1
-       clc
-       adc     DX
+       ldx     #0
+       lda     DX
+       bpl     @L027B
+       dex
+@L027B:        clc
+       adc     X1
        sta     X1
-       bcc     @L0254
-       inc     X1+1
+       txa
+       adc     X1+1
+       sta     X1+1
        ;   y1 = y1 + ay
-@L0254:
-       lda     Y1
-       clc
-       adc     AY
+       ldx     #0
+       lda     AY
+       bpl     @L027E
+       dex
+@L027E:        clc
+       adc     Y1
        sta     Y1
-       bcc     @L0255
-       inc     Y1+1
-@L0255:
+       txa
+       adc     Y1+1
+       sta     Y1+1
        ; if (abs(pb)<abs(ub)) {
        lda     PB
        ldy     PB+1
@@ -839,32 +843,38 @@ LINE:
        jsr     abs
        ldx     #TEMP3
        jsr     icmp
-       bpl     @L017B
+       bpl     @L027F
        ;   err = pb
        lda     PB
        ldx     PB+1
-       jmp     @L025B
+       jmp     @L0312
        ; } else { x1 = x1 + ay
-@L017B:        
-       lda     X1
-       clc
-       adc     AY
+@L027F:
+       ldx     #0
+       lda     AY
+       bpl     @L0288
+       dex
+@L0288:        clc
+       adc     X1
        sta     X1
-       bcc     @L0256
-       inc     X1+1
+       txa
+       adc     X1+1
+       sta     X1+1
        ;       y1 = y1 + dy
-@L0256:
-       lda     Y1
-       clc
-       adc     DY
+       ldx     #0
+       lda     DY
+       bpl     @L028B
+       dex
+@L028B:        clc
+       adc     Y1
        sta     Y1
-       bcc     @L0257
-       inc     Y1+1
+       txa
+       adc     Y1+1
+       sta     Y1+1
        ;       err = ub }
-@L0257:
        lda     UB
        ldx     UB+1
-@L025B:
+@L0312:
        sta     ERR
        stx     ERR+1
        ; } (--count)
@@ -916,7 +926,7 @@ BAR:
 ; Must set an error code: NO
 ;
 
-CIRCLE: 
+CIRCLE:
        lda     RADIUS
         bne     @L1
         jmp     SETPIXELCLIP    ; Plot as a point
@@ -1142,13 +1152,10 @@ OUTTEXT:
         rts
 
 ; ------------------------------------------------------------------------
-; Calculate all variables to plot the pixel at X1/Y1. If the point is out
-; of range, a carry is returned and INRANGE is set to a value !0 zero. If
-; the coordinates are valid, INRANGE is zero and the carry clear.
-
+; Calculate all variables to plot the pixel at X1/Y1.
 ;------------------------
 ;< X1,Y1 - pixel
-;> ADDR - address of card, INRANGE
+;> ADDR - address of card
 ;> X - bit number (X1 & 7)
 CALC:
        lda     Y1+1
@@ -1204,9 +1211,9 @@ abs:
        ; a/y := abs(a/y)
        dey
        iny
-       bpl     @L1
+       bpl     absend
        ; negay
-       clc
+neg:   clc
        eor     #$ff
        adc     #1
        pha
@@ -1215,7 +1222,7 @@ abs:
        adc     #0
        tay
        pla
-@L1:   rts
+absend:        rts
 
 icmp:
        ; compare a/y to zp,x
@@ -1246,16 +1253,13 @@ icmp:
 ; VDC helpers
 
 VDCSetSourceAddr:
-       ldx     #VDC_DATA_LO
-       stx     VDC_ADDR_REG
-@L0:   bit     VDC_ADDR_REG
-       bpl     @L0
-       sta     VDC_DATA_REG
-       dex
+       pha
        tya
-       stx     VDC_ADDR_REG
-       sta     VDC_DATA_REG
-       rts
+       ldx     #VDC_DATA_HI
+       jsr     VDCWriteReg
+       pla
+       ldx     #VDC_DATA_LO
+       bne     VDCWriteReg
 
 VDCReadByte:
        ldx     #VDC_DATA