;
.include "zeropage.inc"
+ .include "extzp.inc"
.include "tgi-kernel.inc"
.include "tgi-mode.inc"
.include "tgi-error.inc"
.include "lynx.inc"
- .include "extzp.inc"
.macpack generic
-
; ------------------------------------------------------------------------
; Header. Includes jump table and constants.
.byte 8 ; System font Y size
.res 4, $00 ; Reserved for future extensions
-; Next comes the jump table. All entries must be valid and may point to an RTS
-; for test versions (function not implemented).
+; 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.
.addr INSTALL
.addr UNINSTALL
.addr INIT
.addr DONE
- .addr GETERROR
+ .addr GETERROR
.addr CONTROL
.addr CLEAR
.addr SETVIEWPAGE
.addr CIRCLE
.addr TEXTSTYLE
.addr OUTTEXT
- .addr 0 ; IRQ entry is unused
+ .addr IRQ
+
; ------------------------------------------------------------------------
; Data.
TEXTDIR: .res 1
BGINDEX: .res 1 ; Pen to use for text background
+; Double buffer IRQ stuff
+DRAWPAGE: .res 1
+SWAPREQUEST: .res 1
+
text_bitmap: .res 8*(1+20+1)+1
; 8 rows with (one offset-byte plus 20 character bytes plus one fill-byte) plus one 0-offset-byte
sta TEXTMAGX
sta TEXTMAGY
stz BGINDEX
+ stz DRAWPAGE
+ stz SWAPREQUEST
rts
;
INIT:
+; Enable interrupts for VBL
+ lda #$80
+ tsb VTIMCTLA
+; Set up collision buffer to $A058
+ lda #$58
+ sta COLLBASL
+ lda #$A0
+ sta COLLBASH
+; Put collision index before sprite data
+ lda #$FE
+ sta COLLOFFL
+ lda #$FF
+ sta COLLOFFH
; Done, reset the error code
lda #TGI_ERR_OK
sta ERROR
; To do a flip-screen call tgi_ioctl(1, 0)
;
; To set the background index for text outputs call tgi_ioctl(2, bgindex)
+;
+; To set the frame rate for the display hardware call tgi_ioctl(3, rate)
+;
+; To check if the drawing engine is busy with the previous swap you can
+; call tgi_ioctl(4, 0). It returns 0 if idle and 1 if busy
+;
+; To update displays you can call tgi_ioctl(4, 1) it will wait for the
+; next VBL interrupt and swap draw and view buffers.
+;
+; Activate or deactivate collision detection by calling tgi_ioctl(5, 0/1).
CONTROL:
- cmp #2
+ pha ; Almost all control routines succeed
+ lda #TGI_ERR_OK
+ sta ERROR
+ pla
+
+ cmp #5
+ bne ControlSwap
+ lda ptr1
bne @L0
+ lda __sprsys
+ ora #$20
+ bra @L1
+@L0: lda __sprsys
+ and #$df
+@L1: sta __sprsys
+ sta SPRSYS
+ rts
+
+ControlSwap:
+ cmp #4
+ bne ControlFramerate
+
+ lda ptr1 ; Swap request
+ bne @L0
+ lda SWAPREQUEST
+ rts
+@L0: sta SWAPREQUEST
+ rts
+
+ControlFramerate:
+ cmp #3
+ bne ControlTextBG
+
lda ptr1
- sta BGINDEX
- lda #TGI_ERR_OK
+ cmp #75 ; Set framerate
+ beq rate75
+ cmp #60
+ beq rate60
+ cmp #50
+ beq rate50
+ lda #TGI_ERR_INV_ARG
sta ERROR
rts
-@L0:
+rate50: lda #$bd ; 50 Hz
+ ldx #$31
+ bra setRate
+rate60: lda #$9e ; 60 Hz
+ ldx #$29
+ bra setRate
+rate75: lda #$7e ; 75 Hz
+ ldx #$20
+setRate:
+ sta HTIMBKUP
+ stx PBKUP
+ rts
+
+ControlTextBG:
+ cmp #2
+ bne ControlFlipScreen
+
+ lda ptr1 ; Set text background color
+ sta BGINDEX
+ rts
+
+ControlFlipScreen:
cmp #1
- bne @L2
- lda __sprsys
+ bne ControlDrawSprite
+
+ lda __sprsys ; Flip screen
eor #8
sta __sprsys
sta SPRSYS
-
lda __viddma
eor #2
sta __viddma
ldy VIEWPAGEL
ldx VIEWPAGEH
and #2
- beq @L1
+ beq NotFlipped
clc
tya
adc #<8159
txa
adc #>8159
tax
-@L1:
+NotFlipped:
sty DISPADRL
stx DISPADRH
- lda #TGI_ERR_OK
- sta ERROR
rts
-@L2:
+
+ControlDrawSprite:
lda ptr1 ; Get the sprite address
ldx ptr1+1
lda #1
sta SPRGO
stz SDONEACK
-@L3: stz CPUSLEEP
+@L0: stz CPUSLEEP
lda SPRSYS
lsr
- bcs @L3
+ bcs @L0
stz SDONEACK
lda #TGI_ERR_OK
sta ERROR
; from the new buffer. This is usually noticed by the user.
SETVIEWPAGE:
+ cmp #1
beq @L1 ; page == maxpages-1
- ldy #<$de20 ; page 0
- ldx #>$de20
+ ldy #<$e018 ; page 0
+ ldx #>$e018
bra @L2
@L1:
- ldy #<$be40 ; page 1
- ldx #>$be40
+ ldy #<$c038 ; page 1
+ ldx #>$c038
@L2:
sty VIEWPAGEL ; Save viewpage for getpixel
stx VIEWPAGEH
;
SETDRAWPAGE:
+ cmp #1
beq @L1 ; page == maxpages-1
- lda #<$de20 ; page 0
- ldx #>$de20
+ lda #<$e018 ; page 0
+ ldx #>$e018
bra @L2
@L1:
- lda #<$be40 ; page 1
- ldx #>$be40
+ lda #<$c038 ; page 1
+ ldx #>$c038
@L2:
sta DRAWPAGEL
stx DRAWPAGEH
rts
+; ------------------------------------------------------------------------
+; IRQ: VBL interrupt handler
+;
+
+IRQ:
+ lda INTSET ; Poll all pending interrupts
+ and #VBL_INTERRUPT
+ beq IRQEND ; Exit if not a VBL interrupt
+
+ lda SWAPREQUEST
+ beq @L0
+ lda DRAWPAGE
+ jsr SETVIEWPAGE
+ lda DRAWPAGE
+ eor #1
+ sta DRAWPAGE
+ jsr SETDRAWPAGE
+ stz SWAPREQUEST
+@L0:
+IRQEND:
+ clc
+ rts
+
; ------------------------------------------------------------------------
; SETCOLOR: Set the drawing color (in A). The new color is already checked
; to be in a valid range (0..maxcolor-1).
sta ptr1+1
ldx #0
+ lda #15
+ sta MAPCTL
lda (ptr1),y
+ tay
+ lda #$0c
+ sta MAPCTL
+ tya
plp
bcc @L1
and #$f
; Must set an error code: NO
;
- .data
-
+.data
line_sprite:
.byte 0 ; Will be replaced by the code
.byte %00110000
line_c:
.byte $e
+.code
LINE:
lda DRAWINDEX
sta line_c
lda Y1
ldx Y2
sta Y2
- stx Y1
+ stx Y1
lda Y1+1
ldx Y2+1
sta Y2+1
lda #0
sbc Y2+1
sta Y2+1
- lda #%00010000 ; Vertical flip
+ lda #%00010000 ; Vertical flip
sta line_sprite
@L2:
lda X1
lda X2
sbc X1
ina
- sta MATHF
+ sta MATHF
stz MATHE
@L3:
lda SPRSYS
lda X2
sec
sbc X1
- ina
+ ina
sta bar_sx+1
lda Y2
sec
; To do a circle please add this to your C program
;int sintbl[9] = {
-; 0, // 0 degrees
+; 0, // 0 degrees
; 3196, // 11.25 degrees
; 6270, // 22.5 degrees
; 9102, // 33.75 degrees
lda Y1+1
sta text_y+1
- ldy #-1 ; Calculate string length
+ ldy #-1 ; Calculate string length
@L2:
iny
lda (STRPTR),y
; bit value 0 = foreground, bit value 1 = background / transparent
font:
; VERSAIL
- .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF ;32
- .byte $FF, $E7, $FF, $FF, $E7, $E7, $E7, $E7 ;33
- .byte $FF, $FF, $FF, $FF, $FF, $99, $99, $99 ;34
- .byte $FF, $99, $99, $00, $99, $00, $99, $99 ;35
- .byte $FF, $E7, $83, $F9, $C3, $9F, $C1, $E7 ;36
- .byte $FF, $B9, $99, $CF, $E7, $F3, $99, $9D ;37
- .byte $FF, $C0, $99, $98, $C7, $C3, $99, $C3 ;38
- .byte $FF, $FF, $FF, $FF, $FF, $E7, $F3, $F9 ;39
- .byte $FF, $F3, $E7, $CF, $CF, $CF, $E7, $F3 ;40
- .byte $FF, $CF, $E7, $F3, $F3, $F3, $E7, $CF ;41
- .byte $FF, $FF, $99, $C3, $00, $C3, $99, $FF ;42
- .byte $FF, $FF, $E7, $E7, $81, $E7, $E7, $FF ;43
- .byte $CF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;44
- .byte $FF, $FF, $FF, $FF, $81, $FF, $FF, $FF ;45
- .byte $FF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;46
- .byte $FF, $9F, $CF, $E7, $F3, $F9, $FC, $FF ;47
+ .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF ;32
+ .byte $FF, $E7, $FF, $FF, $E7, $E7, $E7, $E7 ;33
+ .byte $FF, $FF, $FF, $FF, $FF, $99, $99, $99 ;34
+ .byte $FF, $99, $99, $00, $99, $00, $99, $99 ;35
+ .byte $FF, $E7, $83, $F9, $C3, $9F, $C1, $E7 ;36
+ .byte $FF, $B9, $99, $CF, $E7, $F3, $99, $9D ;37
+ .byte $FF, $C0, $99, $98, $C7, $C3, $99, $C3 ;38
+ .byte $FF, $FF, $FF, $FF, $FF, $E7, $F3, $F9 ;39
+ .byte $FF, $F3, $E7, $CF, $CF, $CF, $E7, $F3 ;40
+ .byte $FF, $CF, $E7, $F3, $F3, $F3, $E7, $CF ;41
+ .byte $FF, $FF, $99, $C3, $00, $C3, $99, $FF ;42
+ .byte $FF, $FF, $E7, $E7, $81, $E7, $E7, $FF ;43
+ .byte $CF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;44
+ .byte $FF, $FF, $FF, $FF, $81, $FF, $FF, $FF ;45
+ .byte $FF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;46
+ .byte $FF, $9F, $CF, $E7, $F3, $F9, $FC, $FF ;47
.byte $FF, $C3, $99, $99, $89, $91, $99, $C3 ;48
.byte $FF, $81, $E7, $E7, $E7, $C7, $E7, $E7 ;49
.byte $FF, $81, $9F, $CF, $F3, $F9, $99, $C3 ;50
.byte $FF, $83, $99, $99, $83, $99, $99, $83 ;2
.byte $FF, $C3, $99, $9F, $9F, $9F, $99, $C3 ;3
.byte $FF, $87, $93, $99, $99, $99, $93, $87 ;4
- .byte $FF, $81, $9F, $9F, $87, $9F, $9F, $81 ;5
+ .byte $FF, $81, $9F, $9F, $87, $9F, $9F, $81 ;5
.byte $FF, $9F, $9F, $9F, $87, $9F, $9F, $81 ;6
.byte $FF, $C3, $99, $99, $91, $9F, $99, $C3 ;7
.byte $FF, $99, $99, $99, $81, $99, $99, $99 ;8