1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-06-12 14:29:54 +00:00
PLASMA/src/libsrc/apple/dgrlib.pla

631 lines
14 KiB
Plaintext
Executable File

include "inc/cmdsys.plh"
//
// Apple II hardware constants.
//
const showgraphics = $C050
const showtext = $C051
const showfull = $C052
const showmix = $C053
const showpage1 = $C054
const showpage2 = $C055
const showlores = $C056
const showhires = $C057
const show40 = $C00C
const show80 = $C00D
const mapmain = $C000
const mapaux = $C001
const an3on = $C05E
const an3off = $C05F
const ena80 = $C07E
const dis80 = $C07F
const page1 = 0
const page2 = 1
//
// Screen row address arrays.
//
word[] dgr1row = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8
word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0
word[] dgr2row = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80
word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8
word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
word[] dgrbuff = @dgr1row, @dgr2row
word drawbuff
byte drawpage
//
// Color mapping.
//
byte[] evnclr = $00,$88,$11,$99,$22,$AA,$33,$BB
byte[] = $44,$CC,$55,$DD,$66,$EE,$77,$FF
byte[] oddclr = $00,$11,$22,$33,$44,$55,$66,$77
byte[] = $88,$99,$AA,$BB,$CC,$DD,$EE,$FF
asm dgrInc(buff)
!SOURCE "vmsrc/plvmzp.inc"
GBASL = $26
GBASH = $27
GBASE = GBASL
GCLR = $30
end
//
// Plot pixel
//
export asm dgrPlot(x, y)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA $3001
STA SRCH
STX ESP
LDA ESTKL,X ; Y COORD
AND #$FE
TAY
LDA (SRC),Y
STA GBASL
INY
LDA (SRC),Y
STA GBASH
LDA ESTKL+1,X ; X COORD
LSR ESTKL,X
LDX GCLR ; COLOR
PHP
SEI
end
asm _dgrPlotPix
JSR $3000 ; _dgrSetPix
PLP
LDX ESP
INX
INX
RTS
end
//
// Plot horizontal row of pixels
//
export asm dgrHLin(x1, x2, y)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA $3001
STA SRCH
STX ESP
LDA ESTKL+1,X ; X2 COORD
STA TMPH
LDA ESTKL+0,X ; Y COORD
AND #$FE
TAY
LDA (SRC),Y
STA GBASL
INY
LDA (SRC),Y
STA GBASH
LDY ESTKL+2,X ; X1 COORD
PHP
SEI
- LDA ESTKL+0,X ; Y COORD
LSR
TYA
LDX GCLR ; COLOR
end
asm _dgrHLinPix
JSR $3000 ; _dgrSetPix
LDX ESP
INC ESTKL+2,X ; X1 COORD
LDY ESTKL+2,X
CPY TMPH ; X2 COORD
BCC -
BEQ -
PLP
INX
INX
INX
RTS
end
//
// Plot horizontal row of pixels
//
export asm dgrVLin(y1, y2, x)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA SRCL
LDA $3001
STA SRCH
STX ESP
LDA ESTKL+2,X ; Y1 COORD
PHP
SEI
- AND #$FE
TAY
LDA (SRC),Y
STA GBASL
INY
LDA (SRC),Y
STA GBASH
LDA ESTKL+2,X
LSR
LDA ESTKL+0,X ; X COORD
LDX GCLR ; COLOR
end
asm _dgrVLinPix
JSR $3000 ; _dgrSetPix
LDX ESP
INC ESTKL+2,X ; Y1 COORD
LDA ESTKL+2,X
CMP ESTKL+1,X ; Y2 COORD
BCC -
BEQ -
PLP
INX
INX
INX
RTS
end
//
// Draw sprite
//
export asm dgrBLT(x, y, width, height, src)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA DSTL
LDA $3001
STA DSTH
LDA ESTKL,X ; SPRITE
STA SRCL
LDA ESTKH,X
STA SRCH
LDA ESTKL+4,X ; X1 COORD
CMP #80
BPL ++++
CLC
ADC ESTKL+2,X
BMI ++++
STA ESTKH+2,X ; X2 COORD
LDA ESTKL+3,X ; Y1 COORD
CMP #48
BPL ++++
STA ESTKH+3,X ; Y COORD
CLC
ADC ESTKL+1,X
BMI ++++
STA ESTKH+1,X ; Y2 COORD
STX ESP
LDA ESTKH+3,X
- CMP #48
BCC +
LDA SRCL ; SKIP TO NEXT ROW
CLC
ADC ESTKL+2,X ; WIDTH
STA SRCL
BCC +++
INC SRCH
BNE +++
+ AND #$FE
TAY
LDA (DST),Y
STA GBASL
INY
LDA (DST),Y
STA GBASH
LDA ESTKL+4,X ; X1 COORD
STA ESTKH+4,X ; X COORD
PHP
SEI
-- CMP #80
BCS ++
STA TMP
LDA ESTKH+3,X ; Y COORD
LSR
LDY #$00
LDA (SRC),Y
BMI ++
TAX
LDA TMP
end
asm _dgrBLTPix
JSR $4000 ; _dgrSetPix
LDX ESP
++ INC SRCL
BNE +
INC SRCH
+ INC ESTKH+4,X ; X COORD
LDA ESTKH+4,X
BMI --
CMP ESTKH+2,X ; X2 COORD
BCC --
PLP
+++ INC ESTKH+3,X ; Y COORD
LDA ESTKH+3,X
BMI -
CMP ESTKH+1,X ; Y2 COORD
BCC -
++++ INX
INX
INX
INX
INX
RTS
end
//
// Internal set pixel routine
// - It expects the carry to be set for even or odd scanlines. Bad.
// - ACCUM has horizontal coordinate
// - X_REG has color
// - GBASE points to scanline
//
asm _dgrSetPix
BCS ++
; EVEN ROW
LSR
TAY
BCS +
end
asm _dgrSetEvnEvn
; EVEN PIXEL
LDA $2000,X
AND #$0F
STA TMP
JSR $0100 ; LDA AUX (DST),Y
AND #$F0
ORA TMP
STA $C005 ; WRITE AUX MEM
STA (GBASE),Y
STA $C004 ; WRITE MAIN MEM
RTS
end
asm _dgrSetEvnOdd
; ODD PIXEL
+ LDA $1000,X
AND #$0F
STA TMP
LDA (GBASE),Y
AND #$F0
ORA TMP
STA (GBASE),Y
RTS
; ODD ROW
++ LSR
TAY
BCS +++
end
asm _dgrSetOddEvn
; EVEN PIXEL
LDA $2000,X
AND #$F0
STA TMP
JSR $0100 ; LDA AUX (DST),Y
AND #$0F
ORA TMP
STA $C005 ; WRITE AUX MEM
STA (GBASE),Y
STA $C004 ; WRITE MAIN MEM
RTS
end
asm _dgrSetOddOdd
; ODD PIXEL
+++ LDA $1000,X
AND #$F0
STA TMP
LDA (GBASE),Y
AND #$0F
ORA TMP
STA (GBASE),Y
RTS
end
//
// This gets copied to $0100!!!
//
asm auxRead
STA $C003 ; READ AUX MEM
LDA (GBASE),Y
STA $C002 ; READ MAIN MEM
RTS
end
//
// Draw 8x8 tile (forced to 2x2 block address)
//
export asm dgrTile(x, y, src)#0
; GET ROW BUFFER ADDRESSES
LDA $3000
STA DSTL
LDA $3001
STA DSTH
STX ESP
LDA ESTKL,X ; TILE
STA SRCL
LDA ESTKH,X
STA SRCH
LDA ESTKL+2,X ; X1 COORD
CMP #80
BPL ++++
CLC
ADC #$08
BMI ++++
STA ESTKH+2,X ; X2 COORD
LDA ESTKL+1,X ; Y1 COORD
CMP #48
BPL ++++
STA TMPL ; Y COORD
CLC
ADC #$08
BMI ++++
STA ESTKH+1,X ; Y2 COORD
LDA TMPL ; Y COORD
- CMP #48
BCC +
LDA SRCL ; SKIP TO NEXT ROW
ADC #$07 ; CARRY = 1
STA SRCL
BCC +++
INC SRCH
BNE +++
+ AND #$FE
TAY
LDA (DST),Y
STA GBASL
INY
LDA (DST),Y
STA GBASH
LDA ESTKL+2,X ; X1 COORD
STA TMPH ; X COORD
PHP
SEI
-- LSR
TAY
CMP #40
LDX #$00
LDA (SRC,X)
INC SRCL
BNE +
INC SRCH
+ BCS +
STA $C005 ; WRITE AUX MEM
STA (GBASE),Y
STA $C004 ; WRITE MAIN MEM
+ LDA (SRC,X)
INC SRCL
BNE +
INC SRCH
+ BCS ++
STA (GBASE),Y
++ INC TMPH ; X COORD
INC TMPH ; X COORD
LDA TMPH
BMI --
LDX ESP
CMP ESTKH+2,X ; X2 COORD
BCC --
PLP
+++ INC TMPL ; Y COORD
INC TMPL ; Y COORD
LDA TMPL
BMI -
CMP ESTKH+1,X ; Y2 COORD
BCC -
++++ INX
INX
INX
RTS
end
//
// Draw a string of tiles
//
export asm dgrTileStr(x, y, tilestr, strlen, tilebuff)#0
- DEX
DEX
DEX
LDA ESTKL+7,X ; X COORD
STA ESTKL+2,X
LDA ESTKL+6,X ; Y COORD
STA ESTKL+1,X
LDA ESTKL+3,X ; TILE
STA ESTKL,X
LDA ESTKH+3,X ; TILE
STA ESTKH,X
end
asm _dgrTileTile
JSR $5000
LDA ESTKL+4,X ; UPDATE X COORD
CLC
ADC #$08
CMP #80 ; OFF RIGHT SIDE
BPL +
STA ESTKL+4,X
DEC ESTKL+1,X ; DEC STRLEN
BNE -
+ INX
INX
INX
INX
INX
RTS
end
//
// Fill a buffer with tiles
//
export asm dgrFill(x, y, tile)#0
LDA ESTKL+2,X
AND #$0F
STA ESTKL+2,X
LDA ESTKL+1,X
AND #$0F
STA ESTKL+1,X
LDA #$00
SEC
SBC ESTKL+2,X ; ORIGINAL X
STA ESTKL+2,X
STA ESTKH+2,X
LDA #$00
SEC
SBC ESTKL+1,X
STA ESTKL+1,X
- DEX
DEX
DEX
LDA ESTKL+5,X ; X COORD
STA ESTKL+2,X
LDA ESTKL+4,X ; Y COORD
STA ESTKL+1,X
LDA ESTKL+3,X ; TILE
STA ESTKL,X
LDA ESTKH+3,X ; TILE
STA ESTKH,X
end
asm _dgrFillTile
JSR $5000
LDA ESTKL+2,X ; UPDATE X COORD
CLC
ADC #$08
STA ESTKL+2,X
CMP #80 ; OFF RIGHT SIDE?
BMI -
LDA ESTKH+2,X ; RESTORE X COORD
STA ESTKL+2,X
LDA ESTKL+1,X ; UPDATE Y COORD
CLC
ADC #$08
STA ESTKL+1,X
CMP #48 ; OFF BOTTOM?
BMI -
INX
INX
INX
RTS
end
//
// Wait for VLB
//
export asm dgrVLB#0
PHP
SEI
STA $C079 ; Enable IOU access and reset VBL int on //c
STA $C05B ; Enable VBL int
- LDA $C019
STA $C079 ; Reset VBL int on //c
BMI -
- LDA $C019
BPL -
STA $C05A ; Disable VBL int on //c
STA $C078 ; Disable IOU access on //c
PLP
RTS
end
//
// Clear the buffer
//
export def dgrClear(clr)#0
byte[32] clrtile
clr = evnclr[clr&$0F] | (oddclr[clr&$0F] << 8)
memset(@clrtile, clr, 32)
dgrFill(0, 0, @clrtile)
end
export def dgrMode(mode)#1
when mode
is page1
//
// Set double lores graphics, return draw buffer
//
^showlores
^showfull
^showgraphics
^showpage1
^ena80 = 0
^show80 = 0
^an3on
drawpage = page2
drawbuff = dgrbuff[page2]
break
is page2
//
// Set double lores graphics, return draw buffer
//
^showlores
^showfull
^showgraphics
^showpage1
^ena80 = 0
^show80 = 0
^an3on
drawpage = page1
drawbuff = dgrbuff[page1]
break
otherwise
//
// Set text mode
//
^showtext
^showpage1
^ena80 = 0
^show40 = 0
^mapmain = 0
^an3off
call($FC58, 0, 0, 0, 0) // home()
wend
return mode
end
//
// Set display page, return other page
//
export def dgrShow(page)#1
page = page & 1
^(showpage1 + page)
return page ^ 1
end
export def dgrSwap#0
^(showpage1 + drawpage)
drawpage = drawpage ^ 1
drawbuff = dgrbuff[drawpage]
end
export def dgrDrawBuf(page)#0
drawpage = page
drawbuff = dgrbuff[drawpage]
end
//
// Set color for clear & plot routines
//
export def dgrColor(clr)#0
^$30 = clr & $0F
end
//
// Make sure we are a 128K //e or //c
//
if MACHID & $F0 <> $B0
puts("\n128K required for double-lores.\n")
^$C010
while ^$C000 < 128; loop
return -1
fin
//
// Assembly fixups
//
_dgrPlotPix:1 = @_dgrSetPix
_dgrHLinPix:1 = @_dgrSetPix
_dgrVLinPix:1 = @_dgrSetPix
_dgrBLTPix:1 = @_dgrSetPix
_dgrTileTile:1 = @dgrTile
_dgrFillTile:1 = @dgrTile
_dgrSetEvnEvn:1 = @evnclr
_dgrSetEvnOdd:1 = @oddclr
_dgrSetOddEvn:1 = @evnclr
_dgrSetOddOdd:1 = @oddclr
//
// Fixups for drawbuff
//
dgrPlot:1 = @drawbuff
dgrPlot:6 = @drawbuff+1
dgrHLin:1 = @drawbuff
dgrHLin:6 = @drawbuff+1
dgrVLin:1 = @drawbuff
dgrVLin:6 = @drawbuff+1
dgrBLT:1 = @drawbuff
dgrBLT:6 = @drawbuff+1
dgrTile:1 = @drawbuff
dgrTile:6 = @drawbuff+1
// Put read AUX mem routine in scary location
memcpy($0100, @auxRead, 9)
//
// Keep module in memory
//
return modkeep
done