a2bejwld/a2bejwld/dbllores.s

1203 lines
20 KiB
ArmAsm

;
; dbllores.s
; a2bejwld
;
; Created by Jeremy Rand on 2016-07-20.
; Copyright © 2016 Jeremy Rand. All rights reserved.
;
.export _showDblLoRes, _clearDblLoRes, _unshowDblLoRes
.export _mixedTextMode
.export _drawGem, _drawBgSquare
.export _drawScore, _selectSquare, _starGem
.export _drawGemAtXY, _drawAndStarGemAtXY
.export _explodeGemFrame1, _explodeGemFrame2
.export _explodeGemFrame3, _explodeGemFrame4
.export _explodeGemFrame5, _explodeGemFrame6
.export _setBuggyDblLoRes
.include "apple2.inc"
SETAN3 := $C05E
SET80VID := $C00D
LINE1 := $400
LINE2 := $480
LINE3 := $500
LINE4 := $580
LINE5 := $600
LINE6 := $680
LINE7 := $700
LINE8 := $780
LINE9 := $428
LINE10 := $4a8
LINE11 := $528
LINE12 := $5a8
LINE13 := $628
LINE14 := $6a8
LINE15 := $728
LINE16 := $7a8
LINE17 := $450
LINE18 := $4d0
LINE19 := $550
LINE20 := $5d0
LINE21 := $650
LINE22 := $6d0
LINE23 := $750
LINE24 := $7d0
; I get a linker error with this so I am hard coding some ZP addresses instead
;.ZEROPAGE
;line1addr: .WORD $0
;line2addr: .WORD $0
;line3addr: .WORD $0
;gemmask: .WORD $0
line1addr := $82
line2addr := $84
line3addr := $86
gemmask := $88
.CODE
.proc _showDblLoRes
lda #0
sta WNDLFT
lda #80
sta WNDWDTH
lda #0
sta WNDTOP
lda #24
sta WNDBTM
lda TXTCLR
lda MIXCLR
lda SETAN3
sta SET80VID
sta SET80COL
rts
.endproc
.proc _unshowDblLoRes
lda #0
sta WNDTOP
lda TXTSET
rts
.endproc
.proc _mixedTextMode
lda MIXSET
sta HISCR
ldx #40
lda #$a0
@L1:
dex
sta LINE21, X
sta LINE22, X
sta LINE23, X
sta LINE24, X
cpx #0
bne @L1
sta LOWSCR
ldx #40
@L2:
dex
sta LINE21, X
sta LINE22, X
sta LINE23, X
sta LINE24, X
cpx #0
bne @L2
lda #0
sta WNDLFT
sta CH
lda #80
sta WNDWDTH
lda #20
sta WNDTOP
sta CV
bit $C082
jsr $FC24 ; Generate text base address
bit $C080
lda #24
sta WNDBTM
rts
.endproc
.proc _clearDblLoRes
sta LOWSCR
ldx #40
lda #0
@L1:
dex
sta LINE1, X
sta LINE2, X
sta LINE3, X
sta LINE4, X
sta LINE5, X
sta LINE6, X
sta LINE7, X
sta LINE8, X
sta LINE9, X
sta LINE10, X
sta LINE11, X
sta LINE12, X
sta LINE13, X
sta LINE14, X
sta LINE15, X
sta LINE16, X
sta LINE17, X
sta LINE18, X
sta LINE19, X
sta LINE20, X
sta LINE21, X
sta LINE22, X
sta LINE23, X
sta LINE24, X
bne @L1
sta HISCR
ldx #40
@L2:
dex
sta LINE1, X
sta LINE2, X
sta LINE3, X
sta LINE4, X
sta LINE5, X
sta LINE6, X
sta LINE7, X
sta LINE8, X
sta LINE9, X
sta LINE10, X
sta LINE11, X
sta LINE12, X
sta LINE13, X
sta LINE14, X
sta LINE15, X
sta LINE16, X
sta LINE17, X
sta LINE18, X
sta LINE19, X
sta LINE20, X
sta LINE21, X
sta LINE22, X
sta LINE23, X
sta LINE24, X
bne @L2
rts
.endproc
.proc _drawBgSquare
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
tax
lda bgColor,X
sta color
lda bgAuxColor,X
sta colorAux
txa
sta square
and #7
sta xPos
lda square
lsr
lsr
lsr
; Get line addrs
tax
lda bgLoLines1,X
sta line1addr
lda bgHiLines1,X
sta line1addr+1
lda bgLoLines2,X
sta line2addr
lda bgHiLines2,X
sta line2addr+1
lda bgLoLines3,X
sta line3addr
lda bgHiLines3,X
sta line3addr+1
; Write the square
lda xPos
asl
asl
tay
ldx #4
@L1:
lda color
sta LOWSCR
sta (line1addr),Y
sta (line2addr),Y
sta (line3addr),Y
lda colorAux
sta HISCR
sta (line1addr),Y
sta (line2addr),Y
sta (line3addr),Y
iny
dex
bne @L1
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
color: .BYTE $0
colorAux: .BYTE $0
.endproc
.proc _drawGemAtXY
stx xPos
cmp #0
bpl @L8
lsr
ora #$80
tax
bcc @L3
bcs @L9
@L8:
lsr
tax
bcc @L3
@L9:
lda maskLoAddrs2,Y
sta gemmask
lda maskHiAddrs2,Y
sta gemmask+1
clc
bcc @L4
@L3:
lda maskLoAddrs,Y
sta gemmask
lda maskHiAddrs,Y
sta gemmask+1
@L4:
lda gemColours,Y
sta gemColour
lda gemAuxColours,Y
sta gemAuxColour
lda #0
sta isAux
lda xPos
lsr
sta xPos
bcs @L5
lda #1
sta isAux
@L5:
; Get line addrs
inx
inx
lda fakeLineLoAddrs,X
clc
adc xPos
sta line1addr
lda fakeLineHiAddrs,X
sta line1addr+1
inx
lda fakeLineLoAddrs,X
clc
adc xPos
sta line2addr
lda fakeLineHiAddrs,X
sta line2addr+1
inx
lda fakeLineLoAddrs,X
clc
adc xPos
sta line3addr
lda fakeLineHiAddrs,X
sta line3addr+1
; Draw the gem
ldy #0
ldx #0
lda #8
sta counter
@L1:
lda isAux
beq @L6
sta HISCR
lda (line1addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemAuxColour
ora square
sta (line1addr,X)
iny
lda (line2addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemAuxColour
ora square
sta (line2addr,X)
iny
lda (line3addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemAuxColour
ora square
sta (line3addr,X)
iny
lda #0
sta isAux
clc
bcc @L7
@L6:
sta LOWSCR
lda (line1addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemColour
ora square
sta (line1addr,X)
iny
lda (line2addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemColour
ora square
sta (line2addr,X)
iny
lda (line3addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemColour
ora square
sta (line3addr,X)
iny
inc line1addr
inc line2addr
inc line3addr
inc isAux
@L7:
dec counter
beq @L2
jmp @L1
@L2:
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
gemColour: .BYTE $0
gemAuxColour: .BYTE $0
isAux: .BYTE $0
counter: .BYTE $0
.endproc
.proc _drawGem
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
asl
tax
lda square
; Need to divide by 8 to get the y square
; and then multiply by 6 to get the y
; position (0-47) on the screen.
lsr
lsr
lsr
sta square
asl
clc
adc square
asl
jmp _drawGemAtXY
; Locals
square: .BYTE $0
.endproc
.proc _selectSquare
ldy #0
jmp _drawGem
.endproc
.proc _starGemAtXY
stx xPos
cmp #0
bpl @L4
lsr
ora #$80
tax
bcc @L1
lda #$f0
clc
bcc @L2
@L4:
lsr
tax
bcc @L1
lda #$f0
clc
bcc @L2
@L1:
lda #$0f
@L2:
sta starVal
inx
sta LOWSCR
lda xPos
lsr
tay
bcc @L3
sta HISCR
iny
@L3:
iny
iny
sty xPos
; Get line addrs
lda lineLoAddrs,X
clc
adc xPos
sta line2addr
lda lineHiAddrs,X
sta line2addr+1
ldx #0
lda starVal
ora (line2addr,X)
sta (line2addr,X)
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
starVal: .BYTE $0
.endproc
.proc _drawAndStarGemAtXY
stx xPos
sta yPos
jsr _drawGemAtXY
ldx xPos
lda yPos
jmp _starGemAtXY
; Locals
xPos: .BYTE $0
yPos: .BYTE $0
.endproc
.proc _starGem
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
asl
tax
lda square
; Need to divide by 8 to get the y square
; and then multiply by 3 to get the y
; position (0-23) on the screen.
lsr
lsr
lsr
sta square
asl
clc
adc square
asl
jmp _starGemAtXY
; Locals
xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _drawScore
; A is a number from 0 to 24
sta score
ldx #24
lda #$dd
ldy #0
sta color
sta LOWSCR
@L1:
dex
bmi @L2
lda score
cmp #0
bne @L3
lda #$22
sta color
@L3:
dec score
lda lineLoAddrs,X
clc
adc #39
sta line1addr
lda lineHiAddrs,X
sta line1addr+1
lda color
sta (line1addr),Y
clc
bcc @L1
@L2:
rts
; Locals
color: .BYTE $0
score: .BYTE $0
.endproc
.proc _explodeGemFrame1
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
sta xPos
lda square
lsr
lsr
lsr
; Get line addrs
tax
lda bgLoLines2,X
clc
adc xPos
sta line2addr
lda bgHiLines2,X
sta line2addr+1
ldy #0
@L1:
; Draw the frame
sta HISCR
lda (line2addr),Y
ora #$0f
sta (line2addr),Y
sta LOWSCR
lda (line2addr),Y
ora #$0f
sta (line2addr),Y
iny
cpy #4
bne @L1
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _explodeGemFrame2
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
sta xPos
lda square
lsr
lsr
lsr
; Get line addrs
tax
lda bgLoLines2,X
clc
adc xPos
sta line2addr
lda bgHiLines2,X
sta line2addr+1
; Draw the frame
lda #$ff
ldy #0
@L1:
sta HISCR
sta (line2addr),Y
sta LOWSCR
sta (line2addr),Y
iny
cpy #4
bne @L1
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _explodeGemFrame3
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
sta xPos
lda square
lsr
lsr
lsr
; Get line addrs
tax
lda bgLoLines1,X
clc
adc xPos
sta line1addr
lda bgHiLines1,X
sta line1addr+1
ldy #0
@L1:
; Draw the frame
sta HISCR
lda (line1addr),Y
ora #$f0
sta (line1addr),Y
sta LOWSCR
lda (line1addr),Y
ora #$f0
sta (line1addr),Y
iny
cpy #4
bne @L1
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _explodeGemFrame4
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
sta xPos
lda square
lsr
lsr
lsr
; Get line addrs
tax
lda bgLoLines3,X
clc
adc xPos
sta line3addr
lda bgHiLines3,X
sta line3addr+1
ldy #0
@L1:
; Draw the frame
sta HISCR
lda (line3addr),Y
ora #$0f
sta (line3addr),Y
sta LOWSCR
lda (line3addr),Y
ora #$0f
sta (line3addr),Y
iny
cpy #4
bne @L1
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _explodeGemFrame5
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
sta xPos
lda square
lsr
lsr
lsr
; Get line addrs
tax
lda bgLoLines1,X
clc
adc xPos
sta line1addr
lda bgHiLines1,X
sta line1addr+1
; Draw the frame
lda #$ff
ldy #0
@L1:
sta HISCR
sta (line1addr),Y
sta LOWSCR
sta (line1addr),Y
iny
cpy #4
bne @L1
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _explodeGemFrame6
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
sta xPos
lda square
lsr
lsr
lsr
; Get line addrs
tax
lda bgLoLines3,X
clc
adc xPos
sta line3addr
lda bgHiLines3,X
sta line3addr+1
; Draw the frame
lda #$ff
ldy #0
@L1:
sta HISCR
sta (line3addr),Y
sta LOWSCR
sta (line3addr),Y
iny
cpy #4
bne @L1
rts
; Locals
xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _setBuggyDblLoRes
; Unfortunately, there is a bug in get_ostype() in cc65 with detecting the Apple //e card.
; There is a version byte in the ROM of the Apple //e card and the tech note describing
; machine detection implies it is 0. The first version of the Mac SW for the card maybe used
; 0 but for sure there are versions 2 and 3 out there also. But cc65 tests for 0 specifically.
; That causes it to detect a Apple //e card with version greater than 0 as an Apple //e
; enhanced.
;
; Combine this with the fact that double lores graphics on the //e card is broken and I have
; a problem. So, rather than use get_ostype() to detect the //e card, I am detecting it myself
; below based on what the tech note says. If I find the game is running on the //e card, then
; I remap the colours used in aux memory to look correct on that HW.
;
; The bug in cc65 has been sent as a pull request back to that project for a fix here:
; https://github.com/cc65/cc65/pull/1013
; Once this is fixed and I adopt a newer version of cc65 in this project, I can clean up the
; HW detection problem.
;
; Next I will need to contact Apple to get a fix for the double lores graphics on the //e card...
bit $c082
lda $fbb3
cmp #$6
bne @L3
lda $fbc0
cmp #$e0
bne @L3
lda $fbdd
cmp #$02
bne @L3
ldx #63
@L1:
lda bgColor,X
sta bgAuxColor,X
dex
bpl @L1
ldx #8
@L2:
lda gemColours,X
sta gemAuxColours,X
dex
bpl @L2
@L3:
bit $c080
rts
.endproc
.DATA
.align 64
; This block of bytes is used for writing to gems "above" the top of the screen.
; Because we draw gems half off the screen, we have two fake lines above the
; top of the screen which points to this buffer of 40 bytes (one line).
FakeLine:
.BYTE $0, $0, $0, $0, $0, $0, $0, $0
.BYTE $0, $0, $0, $0, $0, $0, $0, $0
.BYTE $0, $0, $0, $0, $0, $0, $0, $0
.BYTE $0, $0, $0, $0, $0, $0, $0, $0
.BYTE $0, $0, $0, $0, $0, $0, $0, $0
; Prefix this array with two pointers to "fake lines"
fakeLineLoAddrs:
.LOBYTES FakeLine, FakeLine
lineLoAddrs:
.LOBYTES LINE1, LINE2, LINE3, LINE4, LINE5, LINE6, LINE7, LINE8
.LOBYTES LINE9, LINE10, LINE11, LINE12, LINE13, LINE14, LINE15, LINE16
.LOBYTES LINE17, LINE18, LINE19, LINE20, LINE21, LINE22, LINE23, LINE24
; Prefix this array with two pointers to "fake lines"
fakeLineHiAddrs:
.HIBYTES FakeLine, FakeLine
lineHiAddrs:
.HIBYTES LINE1, LINE2, LINE3, LINE4, LINE5, LINE6, LINE7, LINE8
.HIBYTES LINE9, LINE10, LINE11, LINE12, LINE13, LINE14, LINE15, LINE16
.HIBYTES LINE17, LINE18, LINE19, LINE20, LINE21, LINE22, LINE23, LINE24
; Index this with (xPos << 3) + yPos
bgColor:
.BYTE $0, $55, $0, $55, $0, $55, $0, $55
.BYTE $55, $0, $55, $0, $55, $0, $55, $0
.BYTE $0, $55, $0, $55, $0, $55, $0, $55
.BYTE $55, $0, $55, $0, $55, $0, $55, $0
.BYTE $0, $55, $0, $55, $0, $55, $0, $55
.BYTE $55, $0, $55, $0, $55, $0, $55, $0
.BYTE $0, $55, $0, $55, $0, $55, $0, $55
.BYTE $55, $0, $55, $0, $55, $0, $55, $0
; Index this with (xPos << 3) + yPos
bgAuxColor:
.BYTE $0, $aa, $0, $aa, $0, $aa, $0, $aa
.BYTE $aa, $0, $aa, $0, $aa, $0, $aa, $0
.BYTE $0, $aa, $0, $aa, $0, $aa, $0, $aa
.BYTE $aa, $0, $aa, $0, $aa, $0, $aa, $0
.BYTE $0, $aa, $0, $aa, $0, $aa, $0, $aa
.BYTE $aa, $0, $aa, $0, $aa, $0, $aa, $0
.BYTE $0, $aa, $0, $aa, $0, $aa, $0, $aa
.BYTE $aa, $0, $aa, $0, $aa, $0, $aa, $0
bgLoLines1:
.LOBYTES LINE1, LINE4, LINE7, LINE10, LINE13, LINE16, LINE19, LINE22
bgLoLines2:
.LOBYTES LINE2, LINE5, LINE8, LINE11, LINE14, LINE17, LINE20, LINE23
bgLoLines3:
.LOBYTES LINE3, LINE6, LINE9, LINE12, LINE15, LINE18, LINE21, LINE24
bgHiLines1:
.HIBYTES LINE1, LINE4, LINE7, LINE10, LINE13, LINE16, LINE19, LINE22
bgHiLines2:
.HIBYTES LINE2, LINE5, LINE8, LINE11, LINE14, LINE17, LINE20, LINE23
bgHiLines3:
.HIBYTES LINE3, LINE6, LINE9, LINE12, LINE15, LINE18, LINE21, LINE24
orangeMask:
greenMask:
.BYTE $ff, $ff, $ff
.BYTE $ff, $00, $ff
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $ff, $00, $ff
.BYTE $ff, $ff, $ff
orangeMask2:
greenMask2:
.BYTE $ff, $ff, $ff
.BYTE $ff, $0f, $f0
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $0f, $f0
.BYTE $ff, $ff, $ff
greyMask:
purpleMask:
.BYTE $ff, $ff, $ff
.BYTE $ff, $0f, $f0
.BYTE $ff, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $ff, $00, $f0
.BYTE $ff, $0f, $f0
.BYTE $ff, $ff, $ff
greyMask2:
purpleMask2:
.BYTE $ff, $ff, $ff
.BYTE $ff, $ff, $00
.BYTE $ff, $0f, $00
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $0f, $00
.BYTE $ff, $ff, $00
.BYTE $ff, $ff, $ff
specialMask:
yellowMask:
.BYTE $ff, $ff, $ff
.BYTE $ff, $ff, $ff
.BYTE $ff, $00, $ff
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $ff, $00, $ff
.BYTE $ff, $ff, $ff
.BYTE $ff, $ff, $ff
specialMask2:
yellowMask2:
.BYTE $ff, $ff, $ff
.BYTE $ff, $ff, $ff
.BYTE $ff, $0f, $f0
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $0f, $f0
.BYTE $ff, $ff, $ff
.BYTE $ff, $ff, $ff
blueMask:
.BYTE $ff, $ff, $ff
.BYTE $ff, $f0, $ff
.BYTE $0f, $00, $ff
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $ff
.BYTE $ff, $f0, $ff
.BYTE $ff, $ff, $ff
blueMask2:
.BYTE $ff, $ff, $ff
.BYTE $ff, $0f, $ff
.BYTE $ff, $00, $f0
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $00, $f0
.BYTE $ff, $0f, $ff
.BYTE $ff, $ff, $ff
redMask:
.BYTE $ff, $ff, $ff
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $0f, $00, $f0
.BYTE $ff, $ff, $ff
redMask2:
.BYTE $ff, $ff, $ff
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $00, $00
.BYTE $ff, $ff, $ff
selectMask:
selectMask2:
.BYTE $00, $00, $00
.BYTE $f0, $ff, $0f
.BYTE $f0, $ff, $0f
.BYTE $f0, $ff, $0f
.BYTE $f0, $ff, $0f
.BYTE $f0, $ff, $0f
.BYTE $f0, $ff, $0f
.BYTE $00, $00, $00
; The order of these must match the defines for the gems in types.h.
; I also reuse 0 to mean "select" which isn't a real gem type but I
; draw it like a gem.
maskLoAddrs:
.LOBYTES selectMask, greenMask, redMask, purpleMask, orangeMask
.LOBYTES greyMask, yellowMask, blueMask, specialMask
maskHiAddrs:
.HIBYTES selectMask, greenMask, redMask, purpleMask, orangeMask
.HIBYTES greyMask, yellowMask, blueMask, specialMask
maskLoAddrs2:
.LOBYTES selectMask2, greenMask2, redMask2, purpleMask2, orangeMask2
.LOBYTES greyMask2, yellowMask2, blueMask2, specialMask2
maskHiAddrs2:
.HIBYTES selectMask2, greenMask2, redMask2, purpleMask2, orangeMask2
.HIBYTES greyMask2, yellowMask2, blueMask2, specialMask2
gemColours:
.BYTE $ff ; select "gem" colour
.BYTE $cc ; green gem colour
.BYTE $11 ; red gem colour
.BYTE $33 ; purple gem colour
.BYTE $99 ; orange gem colour
.BYTE $22 ; grey gem colour
.BYTE $dd ; yellow gem colour
.BYTE $66 ; blue gem colour
.BYTE $ff ; special gem colour
gemAuxColours:
.BYTE $ff ; select "gem" colour
.BYTE $66 ; green gem colour
.BYTE $88 ; red gem colour
.BYTE $99 ; purple gem colour
.BYTE $cc ; orange gem colour
.BYTE $11 ; grey gem colour
.BYTE $ee ; yellow gem colour
.BYTE $33 ; blue gem colour
.BYTE $ff ; special gem colour