;
; Stefan Haubenthal <polluks@sdf.lonestar.org>
; Oliver Schmidt <ol.sc@web.de>
-; Based on Maciej Witkowiak's line and circle routine
;
.include "zeropage.inc"
.include "tgi-error.inc"
.include "apple2.inc"
- .macpack generic
-
; ------------------------------------------------------------------------
; Zero page stuff
H2 := $2C
+COLOR := $30
; ROM entry points
TEXT := $F399
PLOT := $F800
HLINE := $F819
-CLRSCR := $F832
+CLRSC2 := $F838
SETCOL := $F864
SCRN := $F871
SETGR := $FB40
Y1 := ptr2
X2 := ptr3
Y2 := ptr4
-RADIUS := tmp1
-ADDR := tmp1
TEMP := tmp3
TEMP2 := tmp4
TEMP3 := sreg
ERR := regsave ; (2) LINE
NX := regsave+2 ; (2) LINE
-; Circle routine stuff (must be on zpage)
-
-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
-
; ------------------------------------------------------------------------
.segment "JUMPTABLE"
.byte $74, $67, $69 ; "tgi"
.byte TGI_API_VERSION ; TGI API version number
-xres: .word 40 ; X resolution
-yres: .word 48 ; Y resolution
+ .word 40 ; X resolution
+ .word 48 ; Y resolution
.byte 16 ; Number of drawing colors
.byte 1 ; 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).
+; Next comes the jump table. With the exception of IRQ, all entries must be
+; valid and may point to an RTS for test versions (function not implemented).
.addr INSTALL
.addr UNINSTALL
.addr GETPIXEL
.addr LINE
.addr BAR
- .addr CIRCLE
.addr TEXTSTYLE
.addr OUTTEXT
.addr 0 ; IRQ entry is unused
; Absolute variables used in the code
ERROR: .res 1 ; Error code
+MIX: .res 1 ; 4 lines of text
-; Line routine stuff (combined with circle routine stuff to save space)
+; Line routine stuff
-OGora:
COUNT: .res 2
-OUkos:
NY: .res 2
-Y3:
DX: .res 1
DY: .res 1
AX: .res 1
DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
.byte $08, $09, $0A, $0B, $0C, $0D, $0E, $0F
+MAXY: .byte 47, 39
+
; ------------------------------------------------------------------------
.code
; Done, reset the error code
lda #TGI_ERR_OK
sta ERROR
+ sta MIX
; Fall through
; Must set an error code: NO
CLEAR:
bit $C082 ; Switch in ROM
- jsr CLRSCR
+ lda COLOR ; Save current drawing color
+ pha
+ ldx MIX
+ ldy MAXY,x ; Max Y depends on 4 lines of text
+ jsr CLRSC2
+ pla
+ sta COLOR ; Save current drawing color
bit $C080 ; Switch in LC bank 2 for R/O
rts
; CONTROL: Platform/driver specific entry point.
; Must set an error code: YES
CONTROL:
- ; Fall through
+ ; Check data msb and code to be 0
+ ora ptr1+1
+ bne err
+
+ ; Check data lsb to be [0..1]
+ lda ptr1
+ cmp #1+1
+ bcs err
+ bit $C082 ; Switch in ROM
+
+ ; Switch 4 lines of text
+ tax
+ .assert MIXCLR + 1 = MIXSET, error
+ lda MIXCLR,x ; No BIT absolute,X available
+
+ ; Save current switch setting
+ txa
+ sta MIX
+ bne text
+
+ ; Clear 8 lines of graphics
+ lda COLOR ; Save current drawing color
+ pha
+ lda #39 ; Rightmost column
+ sta H2
+ ldx #40 ; First line
+: txa
+ ldy #$00 ; Leftmost column
+ sty COLOR ; Black
+ jsr HLINE ; Preserves X
+ inx
+ cpx #47+1 ; Last line
+ bcc :-
+ pla
+ sta COLOR ; Save current drawing color
+ bcs :+ ; Branch always
+
+ ; Clear 4 lines of text
+text: jsr HOME
+: bit $C080 ; Switch in LC bank 2 for R/O
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ beq :+ ; Branch always
+
+ ; Done, set the error code
+err: lda #TGI_ERR_INV_ARG
+: sta ERROR
+ rts
; SETPALETTE: Set the palette (not available with all drivers/hardware).
; A pointer to the palette is passed in ptr1. Must set an error if palettes
bit $C080 ; Switch in LC bank 2 for R/O
rts
-SETPIXELCLIP:
- lda Y1+1
- bmi :+ ; y < 0
- lda X1+1
- bmi :+ ; x < 0
- lda X1
- ldx X1+1
- sta ADDR
- stx ADDR+1
- ldx #ADDR
- lda xres
- ldy xres+1
- jsr icmp ; ( x < xres ) ...
- bcs :+
- lda Y1
- ldx Y1+1
- sta ADDR
- stx ADDR+1
- ldx #ADDR
- lda yres
- ldy yres+1
- jsr icmp ; ... && ( y < yres )
- bcc SETPIXEL
-: rts
-
; GETPIXEL: Read the color value of a pixel and return it in A/X. The
; coordinates passed to this function are never outside the visible screen
; area, so there is no need for clipping inside this function.
; Must set an error code: NO
LINE:
; nx = abs (x2 - x1)
+ sec
lda X2
- sub X1
+ sbc X1
sta NX
lda X2+1
sbc X1+1
sty NX+1
; ny = abs (y2 - y1)
+ sec
lda Y2
- sub Y1
+ sbc Y1
sta NY
lda Y2+1
sbc Y1+1
rts
; setpixel (X1, Y1)
-: jsr SETPIXELCLIP
+: jsr SETPIXEL
; pb = err + ny
+ clc
lda ERR
- add NY
+ adc NY
sta PB
lda ERR+1
adc NY+1
tax
; ub = pb + nx
+ clc
lda PB
- add NX
+ adc NX
sta UB
txa
adc NX+1
lda DX
bpl :+
dex
-: add X1
+: clc
+ adc X1
sta X1
txa
adc X1+1
lda AY
bpl :+
dex
-: add Y1
+: clc
+ adc Y1
sta Y1
txa
adc Y1+1
lda AX
bpl :+
dex
-: add X1
+: clc
+ adc X1
sta X1
txa
adc X1+1
lda DY
bpl :+
dex
-: add Y1
+: clc
+ adc Y1
sta Y1
txa
adc Y1+1
; } (--count)
lda COUNT
- sub #$01
+ sec
+ sbc #$01
sta COUNT
bcc :+
jmp for
; Must set an error code: NO
BAR:
bit $C082 ; Switch in ROM
+ lda X2
+ sta H2
inc Y2
- ldx X2
- stx H2
-: ldy X1
- lda Y1
- jsr HLINE
- inc Y1
- lda Y2
- cmp Y1
- bne :-
+ ldx Y1
+: txa
+ ldy X1
+ jsr HLINE ; Preserves X
+ inx
+ cpx Y2
+ bcc :-
bit $C080 ; Switch in LC bank 2 for R/O
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 :+
- jmp SETPIXELCLIP ; Plot as a point
-: sta XX
-
- ; x = r
- lda #$00
- 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) {
-while: ldx #YY
- lda XX
- ldy XX+1
- jsr icmp
- bcc :+
- rts
-
- ; Plot points in 8 slices...
-: lda XS
- add XX
- sta X1
- lda XS+1
- adc XX+1
- sta X1+1 ; x1 = xs + x
- lda YS
- add YY
- sta Y1
- pha
- lda YS+1
- adc YY+1
- sta Y1+1 ; (stack) = ys + y, y1 = (stack)
- pha
- jsr SETPIXELCLIP ; plot (xs + x, ys + y)
- lda YS
- sub 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)
- pla
- sta Y1+1
- pla
- sta Y1 ; y1 = ys + y
- lda XS
- sub 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
- add YY
- sta X1
- lda XS+1
- adc YY+1
- sta X1+1 ; x1 = xs + y
- lda YS
- add XX
- sta Y1
- pha
- lda YS+1
- adc XX+1
- sta Y1+1 ; (stack) = ys + x, y1 = (stack)
- pha
- jsr SETPIXELCLIP ; plot (xs + y, ys + x)
- lda YS
- sub 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)
- pla
- sta Y1+1
- pla
- sta Y1 ; y1 = ys + x(stack)
- lda XS
- sub 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)
-
- ; og = mo + y + y + 1
- lda MaxO
- ldx MaxO+1
- add YY
- tay
- txa
- adc YY+1
- tax
- tya
- add YY
- tay
- txa
- adc YY+1
- tax
- tya
- add #$01
- bcc :+
- inx
-: sta OGora
- stx OGora+1
-
- ; ou = og - x - x + 1
- sub XX
- tay
- txa
- sbc XX+1
- tax
- tya
- sub XX
- tay
- txa
- sbc XX+1
- tax
- tya
- add #$01
- bcc :+
- inx
-: sta OUkos
- stx OUkos+1
-
- ; ++y
- inc YY
- bne :+
- inc YY+1
-
- ; 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 :++
-
- ; --x
- lda XX
- sub #$01
- sta XX
- bcs :+
- dec XX+1
-
- ; mo = ou }
-: lda OUkos
- ldx OUkos+1
- jmp :++
-
- ; else mo = og
-: lda OGora
- ldx OGora+1
-: sta MaxO
- stx MaxO+1
-
- ; }
- jmp while
-
; Copies of some runtime routines
abs:
tax
tya ; X/A - arg1 (a = high)
- sub TEMP2
+ sec
+ sbc TEMP2
bne :++
cpx TEMP
beq :+