;
-; Graphics driver for the 640x480x2 mode on the C128 VDC
+; Graphics driver for the 640x480x2 mode on the C128 VDC 64k
; (values for this mode based on Fred Bowen's document)
; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
; 23.12.2002
+; 2004-04-04, Greg King
;
; NOTES:
-; On the real machine there are some additional pixels appearing (probably bad reads)
-; VICE emulator does not show them. Needs further investigation.
+; 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 (C64 needs full VDC init then).
-;
-; 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.
+; Only DONE routine contains C128-mode specific stuff, everything else will
+; work in C64-mode of C128 (C64 needs full VDC init then).
;
; With special initialization and CALC we can get 320x200 double-pixel mode.
;
-; Color translation values for BROWN and GRAY3 are obviously wrong, they could
-; be replaced by equiv. of ORANGE and GRAY2 but this would give only 14 of 16 colors available.
+; Color translation values for BROWN and GRAY3 are obviously wrong, they
+; could be replaced by equiv. of ORANGE and GRAY2 but this would give only
+; 14 of 16 colors available.
;
-; Register 25 ($19) is said to require different value for VDC v1, but I couldn't find what
-; it should be.
+; Register 25 ($19) is said to require different value for VDC v1, but I
+; couldn't find what it should be.
- .include "zeropage.inc"
+ .include "zeropage.inc"
- .include "tgi-kernel.inc"
+ .include "tgi-kernel.inc"
.include "tgi-mode.inc"
.include "tgi-error.inc"
; capabilities of the driver
.byte $74, $67, $69 ; "tgi"
- .byte $00 ; TGI version number
+ .byte TGI_API_VERSION ; TGI version number
xres: .word 640 ; X resolution
yres: .word 480 ; Y resolution
.byte 2 ; Number of drawing colors
pages: .byte 0 ; Number of screens available
.byte 8 ; System font X size
.byte 8 ; System font Y size
- .res 4, $00 ; Reserved for future extensions
+ .word $100 ; Aspect ratio
; Next comes the jump table. Currently all entries must be valid and may point
-; to an RTS for test versions (function not implemented). A future version may
-; allow for emulation: In this case the vector will be zero. Emulation means
-; that the graphics kernel will emulate the function by using lower level
-; primitives - for example ploting a line by using calls to SETPIXEL.
-
- .word INSTALL
- .word DEINSTALL
- .word INIT
- .word DONE
- .word GETERROR
- .word CONTROL
- .word CLEAR
- .word SETVIEWPAGE
- .word SETDRAWPAGE
- .word SETCOLOR
- .word SETPALETTE
- .word GETPALETTE
- .word GETDEFPALETTE
- .word SETPIXEL
- .word GETPIXEL
- .word HORLINE
- .word LINE
- .word BAR
- .word CIRCLE
- .word TEXTSTYLE
- .word OUTTEXT
+; to an RTS for test versions (function not implemented).
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr INIT
+ .addr DONE
+ .addr GETERROR
+ .addr CONTROL
+ .addr CLEAR
+ .addr SETVIEWPAGE
+ .addr SETDRAWPAGE
+ .addr SETCOLOR
+ .addr SETPALETTE
+ .addr GETPALETTE
+ .addr GETDEFPALETTE
+ .addr SETPIXEL
+ .addr GETPIXEL
+ .addr LINE
+ .addr BAR
+ .addr TEXTSTYLE
+ .addr OUTTEXT
+ .addr 0 ; IRQ entry is unused
; ------------------------------------------------------------------------
; Data.
Y1 = ptr2
X2 = ptr3
Y2 = ptr4
-RADIUS = tmp1
ADDR = tmp1 ; (2) CALC
TEMP = tmp3 ; CALC icmp
UB = ptr4 ; (2) LINE
ERR = regsave ; (2) LINE
NX = regsave+2 ; (2) LINE
-; Circle stuff
-XX = ptr3 ; (2) CIRCLE
-YY = ptr4 ; (2) CIRCLE
-MaxO = sreg ; (overwritten by TEMP3+TEMP4, but restored from OG/OU anyway)
-XS = regsave ; (2) CIRCLE
-YS = regsave+2 ; (2) CIRCLE
; Absolute variables used in the code
; Line routine stuff (combined with CIRCLE to save space)
-OGora:
COUNT: .res 2
-OUkos:
NY: .res 2
-Y3:
DX: .res 1
DY: .res 1
+AX: .res 1
AY: .res 1
; Text output stuff
.byte 27, $00
.byte $ff
-SCN80CLR: .byte 27,88,147,27,88,0
+SCN80CLR: .byte 27,88,147,27,88,0
.code
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
; Must set an error code: YES
;
-INIT: cmp #TGI_MODE_640_480_2 ; Correct mode?
- beq @L1 ; Jump if yes
- lda #TGI_ERR_INV_MODE ; ## Error
- bne @L9
-
-@L1: lda pages ; is there enough memory?
+INIT:
+ lda pages ; is there enough memory?
bne @L11 ; Jump if there is one screen
- lda #TGI_ERR_INV_MODE ; ## Error
+ lda #TGI_ERR_INV_MODE ; Error
bne @L9
; Initialize variables
@L11: 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
bne @L2
@L3:
-; Remeber current color value
- ldx #VDC_COLORS
- jsr VDCReadReg
- sta OLDCOLOR
-
; Done, reset the error code
lda #TGI_ERR_OK
; The graphics kernel will never call DONE when no graphics mode is active,
; so there is no need to protect against that.
;
-; Must set an error code: YES
+; Must set an error code: NO
;
DONE:
; This part is C128-mode specific
- jsr $e179 ; reload character set
+ jsr $e179 ; reload character set and setup VDC
jsr $ff62
lda $d7 ; in 80-columns?
bne @L01
jsr VDCWriteReg ; restore color (background)
lda #$47
ldx #VDC_HSCROLL
- jmp VDCWriteReg ; switch to text screen
+ jmp VDCWriteReg ; switch to text screen
; ------------------------------------------------------------------------
; GETERROR: Return the error code in A and clear it.
; Must set an error code: NO
;
-CLEAR:
+CLEAR:
lda #0
tay
jsr VDCSetSourceAddr
ora COLTRANS,y
ldx #VDC_COLORS
- jmp VDCWriteReg
+ jsr VDCWriteReg
+ lda #TGI_ERR_OK ; Clear error code
+ sta ERROR
+ rts
; ------------------------------------------------------------------------
-; GETPALETTE: Return the current palette in A/X. Must return NULL and set an
-; error if palettes are not supported.
+; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
+; set the palette should return the default palette here, so there's no
+; way for this function to fail.
;
-; Must set an error code: YES
+; Must set an error code: NO
;
GETPALETTE:
rts
; ------------------------------------------------------------------------
-; GETDEFPALETTE: Return the default palette for the driver in A/X. Must
-; return NULL and set an error of palettes are not supported.
+; GETDEFPALETTE: Return the default palette for the driver in A/X. All
+; drivers should return something reasonable here, even drivers that don't
+; support palettes, otherwise the caller has no way to determine the colors
+; of the (not changeable) palette.
;
-; Must set an error code: YES
+; Must set an error code: NO (all drivers must have a default palette)
;
GETDEFPALETTE:
; Must set an error code: NO
;
-SETPIXELCLIP:
- lda Y1+1
- bmi @finito ; y<0
- lda X1+1
- bmi @finito ; x<0
- lda xres
- ldx xres+1
- sta ADDR
- stx ADDR+1
- ldx #ADDR
- lda X1
- ldy X1+1
- jsr icmp ; if (xres<x1)
- bcs @cont ; !(xres<x1)
-@finito:rts
-@cont: lda yres
- ldx yres+1
- sta ADDR
- stx ADDR+1
- ldx #ADDR
- lda Y1
- ldy Y1+1
- jsr icmp ; if (yres<y1)
- bcc @finito
-
SETPIXEL:
jsr CALC ; Calculate coordinates
- stx TEMP
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- ldx TEMP
+ stx TEMP
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ ldx TEMP
- sta TEMP
+ sta TEMP
eor BITMASK
and BITTAB,X
- eor TEMP
- pha
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
+ eor TEMP
+ pha
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ pla
+ jsr VDCWriteByte
@L9: rts
ldx #$00 ; Clear high byte
rts
-; ------------------------------------------------------------------------
-; HORLINE: Draw a horizontal line from X1/Y to X2/Y, where X1 = ptr1,
-; Y = ptr2 and X2 = ptr3, using the current drawing color.
-;
-; This is a special line drawing entry used when the line is know to be
-; horizontal, for example by the BAR emulation routine. If the driver does
-; not have special code for horizontal lines, it may just copy Y to Y2 and
-; proceed with the generic line drawing code.
-;
-; Note: Line coordinates will always be sorted (Y1 <= X2) and clipped.
-;
-; Must set an error code: NO
-;
-
-HORLINE:
- lda X1
- pha
- lda X1+1
- pha
- jsr CALC ; get data for LEFT
- lda BITMASKL,x ; remember left address and bitmask
- pha
- lda ADDR
- pha
- lda ADDR+1
- pha
-
- lda X2
- sta X1
- lda X2+1
- sta X1+1
- jsr CALC ; get data for RIGHT
- lda BITMASKR,x
- sta TEMP3
-
- pla ; recall data for LEFT
- sta X1+1
- pla
- sta X1 ; put left address into X1
- pla
-
- cmp #%11111111 ; if left bit <> 0
- beq @L1
- sta TEMP2 ; do left byte only...
- lda X1
- ldy X1+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- sta TEMP
- eor BITMASK
- and TEMP2
- eor TEMP
- pha
- lda X1
- ldy X1+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
- inc X1 ; ... and proceed
- bne @L1
- inc X1+1
-
- ; do right byte (if Y2=0 ++ADDR and skip)
-@L1: lda TEMP3
- cmp #%11111111 ; if right bit <> 7
- bne @L11
- inc ADDR ; right bit = 7 - the next one is the last
- bne @L10
- inc ADDR+1
-@L10: bne @L2
-
-@L11: lda ADDR ; do right byte only...
- ldy ADDR+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- sta TEMP
- eor BITMASK
- and TEMP3
- eor TEMP
- pha
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
-
-@L2: ; do the fill in the middle
- lda ADDR ; calculate offset in full bytes
- sec
- sbc X1
- beq @L3 ; if equal - there are no more bytes
- sta ADDR
-
- lda X1 ; setup for the left side
- ldy X1+1
- jsr VDCSetSourceAddr
- lda BITMASK ; get color
- jsr VDCWriteByte ; put 1st value
- ldx ADDR
- dex
- beq @L3 ; 1 byte already written
-
- stx ADDR ; if there are more bytes - fill them...
- ldx #VDC_VSCROLL
- lda #0
- jsr VDCWriteReg ; setup for fill
- ldx #VDC_COUNT
- lda ADDR
- jsr VDCWriteReg ; ... fill them NOW!
-
-@L3: pla
- sta X1+1
- pla
- sta X1
- rts
-
; ------------------------------------------------------------------------
; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
; X2/Y2 = ptr3/ptr4 using the current drawing color.
;
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
+ ; 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
+ ; dy = 1;
+ lda #1
+ bne @L024B
+ ; else
+ ; dy = -1;
+@L024A: lda #$ff
+@L024B: sta DY
+ ; err = ax = ay = 0;
+ lda #0
+ sta ERR
+ sta ERR+1
+ sta AX
+ sta AY
+
; if (nx<ny) {
ldx #NX
lda NY
ldy NY+1
jsr icmp
- bcs @L041B
+ bcs @L0255
; nx <-> ny
lda NX
ldx NY
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
+ ; ax = dx
+ lda DX
+ sta AX
+ ; ay = dy
+ lda DY
+ 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
bne @L0167
rts
; setpixel(X1,Y1)
-@L0167: jsr SETPIXELCLIP
- ; pb = err - ny
+@L0167: jsr SETPIXEL
+ ; 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
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
jsr abs
ldx #TEMP3
jsr icmp
- bpl @L017B
+ bpl @L027F
; err = pb
lda PB
ldx PB+1
- jmp @L025B
- ; } else { x1 = x1 + ay
-@L017B:
- lda X1
- clc
- adc AY
+ jmp @L0312
+ ; } else { x1 = x1 + ax
+@L027F:
+ ldx #0
+ lda AX
+ 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)
BAR:
inc Y2
- bne @L0
+ bne HORLINE
inc Y2+1
-@L0: jsr HORLINE
- inc Y1
- bne @L1
- inc Y1+1
-@L1: lda Y1
- cmp Y2
- bne @L0
- lda Y1+1
- cmp Y2+1
- bne @L0
- rts
-
-; ------------------------------------------------------------------------
-; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
-; radius in tmp1 and the current drawing color.
-;
-; Must set an error code: NO
-;
-CIRCLE:
- lda RADIUS
- bne @L1
- jmp SETPIXELCLIP ; Plot as a point
+; Original code for a horizontal line
-@L1: sta XX
- ; x = r;
- lda #0
- sta XX+1
- sta YY
- sta YY+1
- sta MaxO
- sta MaxO+1
- ; y =0; mo=0;
- lda X1
- ldx X1+1
- sta XS
- stx XS+1
- lda Y1
- ldx Y1+1
- sta YS
- stx YS+1 ; XS/YS to remember the center
-
- ; while (y<x) {
-@L013B: ldx #YY
- lda XX
- ldy XX+1
- jsr icmp
- bcc @L12
- rts
-@L12: ; plot points in 8 slices...
- lda XS
- clc
- adc XX
- sta X1
- lda XS+1
- adc XX+1
- sta X1+1 ; x1 = xs+x
- lda YS
- clc
- adc YY
- sta Y1
+HORLINE:
+ lda X1
pha
- lda YS+1
- adc YY+1
- sta Y1+1 ; (stack)=ys+y, y1=(stack)
+ lda X1+1
pha
- jsr SETPIXELCLIP ; plot(xs+x,ys+y)
- lda YS
- sec
- sbc YY
- sta Y1
- sta Y3
- lda YS+1
- sbc YY+1
- sta Y1+1 ; y3 = y1 = ys-y
- sta Y3+1
- jsr SETPIXELCLIP ; plot(xs+x,ys-y)
+ jsr CALC ; get data for LEFT
+ lda BITMASKL,x ; remember left address and bitmask
+ pha
+ lda ADDR
+ pha
+ lda ADDR+1
+ pha
+
+ lda X2
+ sta X1
+ lda X2+1
+ sta X1+1
+ jsr CALC ; get data for RIGHT
+ lda BITMASKR,x
+ sta TEMP3
+
+ pla ; recall data for LEFT
+ sta X1+1
pla
- sta Y1+1
+ sta X1 ; put left address into X1
pla
- sta Y1 ; y1 = ys+y
- lda XS
- sec
- sbc XX
- sta X1
- lda XS+1
- sbc XX+1
- sta X1+1
- jsr SETPIXELCLIP ; plot (xs-x,ys+y)
- lda Y3
- sta Y1
- lda Y3+1
- sta Y1+1
- jsr SETPIXELCLIP ; plot (xs-x,ys-y)
- lda XS
- clc
- adc YY
- sta X1
- lda XS+1
- adc YY+1
- sta X1+1 ; x1 = xs+y
- lda YS
- clc
- adc XX
- sta Y1
- pha
- lda YS+1
- adc XX+1
- sta Y1+1 ; (stack)=ys+x, y1=(stack)
+ cmp #%11111111 ; if left bit <> 0
+ beq @L1
+ sta TEMP2 ; do left byte only...
+ lda X1
+ ldy X1+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ sta TEMP
+ eor BITMASK
+ and TEMP2
+ eor TEMP
pha
- jsr SETPIXELCLIP ; plot(xs+y,ys+x)
- lda YS
- sec
- sbc XX
- sta Y1
- sta Y3
- lda YS+1
- sbc XX+1
- sta Y1+1 ; y3 = y1 = ys-x
- sta Y3+1
- jsr SETPIXELCLIP ; plot(xs+y,ys-x)
+ lda X1
+ ldy X1+1
+ jsr VDCSetSourceAddr
pla
- sta Y1+1
+ jsr VDCWriteByte
+ inc X1 ; ... and proceed
+ bne @L1
+ inc X1+1
+
+ ; do right byte (if Y2=0 ++ADDR and skip)
+@L1: lda TEMP3
+ cmp #%11111111 ; if right bit <> 7
+ bne @L11
+ inc ADDR ; right bit = 7 - the next one is the last
+ bne @L10
+ inc ADDR+1
+@L10: bne @L2
+
+@L11: lda ADDR ; do right byte only...
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ sta TEMP
+ eor BITMASK
+ and TEMP3
+ eor TEMP
+ pha
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
pla
- sta Y1 ; y1 = ys+x(stack)
- lda XS
- sec
- sbc YY
- sta X1
- lda XS+1
- sbc YY+1
- sta X1+1
- jsr SETPIXELCLIP ; plot (xs-y,ys+x)
- lda Y3
- sta Y1
- lda Y3+1
- sta Y1+1
- jsr SETPIXELCLIP ; plot (xs-y,ys-x)
+ jsr VDCWriteByte
- ; og = mo+y+y+1
- lda MaxO
- ldx MaxO+1
- clc
- adc YY
- tay
- txa
- adc YY+1
- tax
- tya
- clc
- adc YY
- tay
- txa
- adc YY+1
- tax
- tya
- clc
- adc #1
- bcc @L0143
- inx
-@L0143: sta OGora
- stx OGora+1
- ; ou = og-x-x+1
- sec
- sbc XX
- tay
- txa
- sbc XX+1
- tax
- tya
- sec
- sbc XX
- tay
- txa
- sbc XX+1
- tax
- tya
- clc
- adc #1
- bcc @L0146
- inx
-@L0146: sta OUkos
- stx OUkos+1
- ; ++y
- inc YY
- bne @L0148
- inc YY+1
-@L0148: ; if (abs(ou)<abs(og))
- lda OUkos
- ldy OUkos+1
- jsr abs
- sta TEMP3
- sty TEMP4
- lda OGora
- ldy OGora+1
- jsr abs
- ldx #TEMP3
- jsr icmp
- bpl @L0149
- ; { --x;
+@L2: ; do the fill in the middle
+ lda ADDR ; calculate offset in full bytes
sec
- lda XX
- sbc #1
- sta XX
- bcs @L014E
- dec XX+1
-@L014E: ; mo = ou; }
- lda OUkos
- ldx OUkos+1
- jmp @L014G
- ; else { mo = og }
-@L0149: lda OGora
- ldx OGora+1
-@L014G: sta MaxO
- stx MaxO+1
- ; }
- jmp @L013B
+ sbc X1
+ beq @L3 ; if equal - there are no more bytes
+ sta ADDR
+
+ lda X1 ; setup for the left side
+ ldy X1+1
+ jsr VDCSetSourceAddr
+ lda BITMASK ; get color
+ jsr VDCWriteByte ; put 1st value
+ ldx ADDR
+ dex
+ beq @L3 ; 1 byte already written
+
+ stx ADDR ; if there are more bytes - fill them...
+ ldx #VDC_VSCROLL
+ lda #0
+ jsr VDCWriteReg ; setup for fill
+ ldx #VDC_COUNT
+ lda ADDR
+ jsr VDCWriteReg ; ... fill them NOW!
+
+@L3: pla
+ sta X1+1
+ pla
+ sta X1
+
+; End of horizontal line code
+
+ inc Y1
+ bne @L4
+ inc Y1+1
+@L4: lda Y1
+ cmp Y2
+ bne @L5
+ lda Y1+1
+ cmp Y2+1
+ bne @L5
+ rts
+
+@L5: jmp HORLINE
+
; ------------------------------------------------------------------------
; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
abs:
; a/y := abs(a/y)
- dey
- iny
- bpl @L1
+ cpy #$00
+ bpl absend
; negay
- clc
- eor #$ff
- adc #1
+neg: eor #$ff
+ add #1
pha
tya
eor #$ff
adc #0
tay
pla
-@L1: rts
+absend: rts
icmp:
; compare a/y to zp,x
; 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