Prince-of-Persia-Apple-II/01 POP Source/Source/GRAFIX.S

2132 lines
28 KiB
ArmAsm
Executable File

* grafix
CopyProtect = 1
EditorDisk = 0
org = $400
tr on
lst off
lstdo off
*-------------------------------
*
* PRINCE OF PERSIA
* Copyright 1989 Jordan Mechner
*
*-------------------------------
org org
jmp GR
jmp DRAWALL
jmp CONTROLLER
jmp dispversion
jmp SAVEBLUE
jmp RELOADBLUE
jmp MOVEMEM
jmp BUTTONS ;ed
jmp GTONE
jmp SETCENTER
jmp DIMCHAR
jmp CVTX
jmp ZEROPEEL
jmp ZEROPEELS
jmp PREAD
jmp ADDPEEL
jmp COPYSCRN
jmp SNGPEEL
jmp RND
jmp CLS
jmp LAY
jmp FASTLAY
jmp LAYRSAVE
jmp LRCLS
jmp FASTMASK
jmp FASTBLACK
jmp PEEL
jmp GETWIDTH
jmp COPY2000
jmp COPY2000MA
jmp SETFASTAUX
jmp SETFASTMAIN
jmp LOADLEVEL
jmp ATTRACTMODE
jmp XMINIT
jmp XMPLAY
jmp CUTPRINCESS
jmp XTITLE
jmp COPY2000AM
jmp RELOAD
jmp LOADSTAGE2
jmp RELOAD
jmp GETSELECT
jmp GETDESEL
jmp EDREBOOT ;ed
jmp GOBUILD ;ed
jmp GOGAME ;ed
jmp WRITEDIR ;ed
jmp READDIR ;ed
jmp SAVELEVEL ;ed
jmp SAVELEVELG ;ed
jmp ADDBACK
jmp ADDFORE
jmp ADDMID
jmp ADDMIDEZ
jmp ADDWIPE
jmp ADDMSG
jmp SAVEGAME
jmp LOADGAME
jmp ZEROLSTS
jmp SCREENDUMP
jmp MINIT
jmp MPLAY
jmp SAVEBINFO
jmp RELOADBINFO
jmp INVERTY
jmp NORMSPEED
jmp ADDMIDEZO
jmp CALCBLUE
jmp ZERORED
jmp XPLAYCUT
jmp CHECKIIGS
jmp FASTSPEED
jmp MUSICKEYS
jmp DOSTARTGAME
jmp EPILOG
jmp LOADALTSET
jmp XMOVEMUSIC
jmp WHOOP
VBLvect jmp VBLANK ;changed by InitVBLANK if IIc
jmp VBLI ;VBL interrupt
*-------------------------------
lst
put eq
lst
put gameeq
lst
put soundnames
lst off
*-------------------------------
dum locals
]temp
]dest ds 2
]source ds 2
]endsourc ds 2
index ds 1
dend
*-------------------------------
* Apple soft switches
IOUDISoff = $c07f
IOUDISon = $c07e
DHIRESoff = $c05f
DHIRESon = $c05e
HIRESon = $c057
HIRESoff = $c056
PAGE2on = $c055
PAGE2off = $c054
MIXEDon = $c053
MIXEDoff = $c052
TEXTon = $c051
TEXToff = $c050
ALTCHARon = $c00f
ALTCHARoff = $c00e
ADCOLon = $c00d
ADCOLoff = $c00c
ALTZPon = $c009
ALTZPoff = $c008
RAMWRTaux = $c005
RAMWRTmain = $c004
RAMRDaux = $c003
RAMRDmain = $c002
ADSTOREon = $c001
ADSTOREoff = $c000
RWBANK2 = $c083
RWBANK1 = $c08b
USEROM = $c082
*-------------------------------
* Key equates
CTRL = $60
ESC = $9b
DELETE = $7f
SHIFT = $20
ksound = "s"-CTRL
kmusic = "n"-CTRL
*-------------------------------
* Joystick "center" width (increase for bigger center)
cwidthx = 10 ;15
cwidthy = 15 ;21
*-------------------------------
* Addresses of character image tables
* (Bank: 2 = main, 3 = aux)
chtabbank db 2,2,2,3,2,3,3
chtablist db #>chtable1,#>chtable2,#>chtable3,#>chtable4
db #>chtable5,#>chtable6,#>chtable7
dummy db maxpeel,maxpeel
*-------------------------------
*
* A D D B A C K
*
* Add an image to BACKGROUND image list
*
* In: XCO, YCO, IMAGE (coded), OPACITY
*
* IMAGE bit 7 specifies image table (0 = bgtable1,
* 1 = bgtable2); low 6 bits = image # within table
*
*-------------------------------
ADDBACK ldx bgX ;# images already in list
inx
cpx #maxback
bcs :rts ;list full (shouldn't happen)
lda XCO
sta bgX,x
lda YCO
cmp #192
bcs :rts
sta bgY,X
lda IMAGE
sta bgIMG,X
lda OPACITY
sta bgOP,X
stx bgX
:rts
]rts rts
*-------------------------------
*
* A D D F O R E
*
* Add an image to FOREGROUND image list
*
* In: same as ADDBACK
*
*-------------------------------
ADDFORE ldx fgX
inx
cpx #maxfore
bcs ]rts
lda XCO
sta fgX,X
lda YCO
cmp #192
bcs ]rts
sta fgY,X
lda IMAGE
sta fgIMG,X
lda OPACITY
sta fgOP,X
stx fgX
]rts rts
*-------------------------------
*
* A D D M S G
*
* Add an image to MESSAGE image list (uses bg tables)
*
* In: XCO, OFFSET, YCO, IMAGE (coded), OPACITY (bit 6 coded)
*
*-------------------------------
ADDMSG ldx msgX
inx
cpx #maxmsg
bcs ]rts
lda XCO
sta msgX,X
lda OFFSET
sta msgOFF,X
lda YCO
sta msgY,X
lda IMAGE
sta msgIMG,X
lda OPACITY
sta msgOP,X
stx msgX
]rts rts
*-------------------------------
*
* A D D W I P E
*
* Add image to wipe list
*
* In: XCO, YCO, height, width; A = color
*
*-------------------------------
ADDWIPE ldx wipeX
inx
cpx #maxwipe
bcs ]rts
sta wipeCOL,x
lda blackflag ;TEMP
beq :1 ;
lda #$ff ;
sta wipeCOL,x ;
:1
lda XCO
sta wipeX,x
lda YCO
sta wipeY,x
lda height
sta wipeH,x
lda width
sta wipeW,x
stx wipeX
]rts rts
*-------------------------------
*
* A D D M I D
*
* Add an image to mid table
*
* In: XCO, OFFSET, YCO, IMAGE, TABLE, OPACITY
* FCharFace, FCharCU-CD-CL-CR
* A = midTYP
*
* midTYP bit 7: 1 = char tables, 0 = bg tables
* midTYP bits 0-6:
* 0 = use fastlay (normal for floorpieces)
* 1 = use lay alone
* 2 = use lay with layrsave (normal for characters)
*
* For char tables: IMAGE = image #, TABLE = table #
* For bg tables: IMAGE bits 0-6 = image #, bit 7 = table #
*
*-------------------------------
ADDMID ldx midX
inx
cpx #maxmid
bcs ]rts
sta midTYP,x
lda XCO
sta midX,x
lda OFFSET
sta midOFF,x
lda YCO
sta midY,x
lda IMAGE
sta midIMG,x
lda TABLE
sta midTAB,x
lda FCharFace ;- left, + right
eor #$ff ;+ normal, - mirror
and #$80
ora OPACITY
sta midOP,x
lda FCharCU
sta midCU,x
lda FCharCD
sta midCD,x
lda FCharCL
sta midCL,x
lda FCharCR
sta midCR,x
stx midX
]rts rts
*-------------------------------
*
* ADDMID "E-Z" version
*
* No offset, no mirroring, no cropping
*
* In: XCO, YCO, IMAGE, TABLE, OPACITY
* A = midTYP
*
*-------------------------------
ADDMIDEZ lda #0
sta OFFSET
ADDMIDEZO
ldx midX
inx
cpx #maxmid
bcs ]rts
sta midTYP,x
lda XCO
sta midX,x
lda OFFSET
sta midOFF,x
lda YCO
sta midY,x
lda IMAGE
sta midIMG,x
lda TABLE
sta midTAB,x
lda OPACITY
sta midOP,x
lda #0
sta midCU,x
sta midCL,x
lda #40
sta midCR,x
lda #192
sta midCD,x
stx midX
]rts rts
*-------------------------------
*
* A D D P E E L
*
* (Call immediately after layrsave)
* Add newly generated image to peel list
*
*-------------------------------
ADDPEEL lda PEELIMG+1
beq ]rts ;0 is layersave's signal to skip it
lda PAGE
beq :1
do CopyProtect
ldx purpleflag ;should be 1!
lda dummy,x
else
lda #maxpeel
fin
:1 sta :sm+1 ;self-mod
tax
lda peelX,x ;# of images in peel list
clc
adc #1
cmp #maxpeel
bcs ]rts
sta peelX,x
clc
:sm adc #0 ;0/maxpeel
tax
lda PEELXCO
sta peelX,x
lda PEELYCO
sta peelY,x ;x & y coords of saved image
lda PEELIMG
sta peelIMGL,x
lda PEELIMG+1
sta peelIMGH,x ;2-byte image address (in peel buffer)
]rts rts
*-------------------------------
*
* D R A W A L L
*
* Draw everything in image lists
*
* This is the only routine that calls HIRES routines.
*
*-------------------------------
DRAWALL
jsr DOGEN ;Do general stuff like cls
lda blackflag ;TEMP
bne :1 ;
jsr SNGPEEL ;"Peel off" characters
;(using the peel list we
;set up 2 frames ago)
:1 jsr ZEROPEEL ;Zero just-used peel list
jsr DRAWWIPE ;Draw wipes
jsr DRAWBACK ;Draw background plane images
jsr DRAWMID ;Draw middle plane images
;(& save underlayers to now-clear peel list)
jsr DRAWFORE ;Draw foreground plane images
jmp DRAWMSG ;Draw messages
*-------------------------------
*
* D O G E N
*
* Do general stuff like clear screen
*
*-------------------------------
DOGEN
lda genCLS
beq :1
jsr cls
* purple copy-protection
:1 ldx BGset1
cpx #1
bne ]rts
lda #0
sta dummy-1,x
]rts rts
*-------------------------------
*
* D R A W W I P E
*
* Draw wipe list (using "fastblack")
*
*-------------------------------
DRAWWIPE
lda wipeX ;# of images in list
beq ]rts ;list is empty
lda #1 ;start with image #1
:loop pha
tax
lda wipeH,x
sta IMAGE ;height
lda wipeW,x
sta IMAGE+1 ;width
lda wipeX,X
sta XCO ;x-coord
lda wipeY,X
sta YCO ;y-coord
lda wipeCOL,X
sta OPACITY ;color
jsr fastblack
pla
clc
adc #1
cmp wipeX
bcc :loop
beq :loop
]rts rts
*-------------------------------
*
* D R A W B A C K
*
* Draw b.g. list (using fastlay)
*
*-------------------------------
DRAWBACK lda bgX ;# of images in list
beq ]rts
ldx #1
:loop stx index
lda bgIMG,x
sta IMAGE ;coded image #
jsr setbgimg ;extract TABLE, BANK, IMAGE
lda bgX,x
sta XCO
lda bgY,X
sta YCO
lda bgOP,x
sta OPACITY
jsr fastlay
ldx index
inx
cpx bgX
bcc :loop
beq :loop
]rts rts
*-------------------------------
*
* D R A W F O R E
*
* Draw foreground list (using fastmask/fastlay)
*
*-------------------------------
DRAWFORE lda fgX
beq ]rts
ldx #1
:loop stx index
lda fgIMG,x
sta IMAGE
jsr setbgimg
lda fgX,x
sta XCO
lda fgY,x
sta YCO
lda fgOP,x ;opacity
cmp #mask
bne :1
jsr fastmask
jmp :cont
:1 sta OPACITY ;fastlay for everything else
jsr fastlay
:cont ldx index
inx
cpx fgX
bcc :loop
beq :loop
]rts rts
*-------------------------------
*
* S N G P E E L
*
* Draw peel list (in reverse order) using "peel" (fastlay)
*
*-------------------------------
SNGPEEL
ldx PAGE
beq :1
ldx #maxpeel
:1 stx :sm+1
lda peelX,x ;# of images in list
beq ]rts
:loop pha
clc
:sm adc #0 ;self-mod: 0 or maxpeel
tax
lda peelIMGL,x
sta IMAGE
lda peelIMGH,x
sta IMAGE+1
lda peelX,x
sta XCO
lda peelY,x
sta YCO
lda #sta
sta OPACITY
jsr peel
pla
sec
sbc #1
bne :loop
]rts rts
*-------------------------------
*
* D R A W M I D
*
* Draw middle list (floorpieces & characters)
*
*-------------------------------
DRAWMID
lda midX ;# of images in list
beq ]rts
ldx #1
:loop stx index
lda midIMG,x
sta IMAGE
lda midTAB,x
sta TABLE
lda midX,x
sta XCO
lda midY,x
sta YCO
lda midOP,x
sta OPACITY
lda midTYP,x ;+ use bg tables
bmi :UseChar ;- use char tables
jsr setbgimg ;protects A,X
jmp :GotTable
:UseChar jsr setcharimg ;protects A,X
:GotTable ;A = midTYP,x
and #$7f ;low 7 bits: 0 = fastlay, 1 = lay, 2 = layrsave
beq :fastlay
cmp #1
beq :lay
cmp #2
beq :layrsave
:Done ldx index
inx
cpx midX
bcc :loop
beq :loop
]rts rts
* midTYP values:
* 0 = use fastlay (normal for floorpieces)
* 1 = use lay alone
* 2 = use lay with layrsave (normal for characters)
:fastlay
jsr fastlay
jmp :Done
:layrsave
jsr :setaddl ;set additional params for lay
jsr layrsave ;save underlayer in peel buffer
jsr ADDPEEL ;& add to peel list
jsr lay ;then lay down image
jmp :Done
:lay jsr :setaddl
jsr lay
jmp :Done
:setaddl lda midOFF,x
sta OFFSET
lda midCL,x
sta LEFTCUT
lda midCR,x
sta RIGHTCUT
lda midCU,x
sta TOPCUT
lda midCD,x
sta BOTCUT
rts
*-------------------------------
*
* D R A W M S G
*
* Draw message list (using bg tables & lay)
*
* OPACITY bit 6: 1 = layrsave, 0 = no layrsave
*
*-------------------------------
DRAWMSG
lda msgX
beq ]rts
ldx #1
:loop stx index
lda msgIMG,x
sta IMAGE
jsr setbgimg
lda msgX,x
sta XCO
lda msgOFF,x
sta OFFSET
lda msgY,x
sta YCO
lda #0
sta LEFTCUT
sta TOPCUT
lda #40
sta RIGHTCUT
lda #192
sta BOTCUT
lda msgOP,x
sta OPACITY
and #%01000000
beq :1
lda OPACITY
and #%10111111 ;bit 6 set: use layrsave
sta OPACITY
jsr layrsave
jsr ADDPEEL
:1 jsr lay
ldx index
inx
cpx msgX
bcc :loop
beq :loop
]rts rts
*-------------------------------
*
* S E T B G I M A G E
*
* In: IMAGE = coded image #
* Out: BANK, TABLE, IMAGE set for hires call
*
* Protect A,X
*
*-------------------------------
setbgimg
tay
lda #3 ;auxmem
sta BANK
lda #0
sta TABLE
lda IMAGE ;Bit 7: 0 = bgtable1, 1 = bgtable2
bpl :bg1
and #$7f
sta IMAGE
lda #>bgtable2
bne :ok
:bg1 lda #>bgtable1
:ok sta TABLE+1
tya
rts
*-------------------------------
*
* S E T C H A R I M A G E
*
* In: TABLE = chtable # (0-7)
* Out: BANK, TABLE set for hires call
*
* Protect A,X
*
*-------------------------------
setcharimg
pha
ldy TABLE
lda chtabbank,y
sta BANK
lda #0
sta TABLE
lda chtablist,y
sta TABLE+1
pla
rts
*-------------------------------
*
* D I M C H A R
*
* Get dimensions of character
* (Misc. routine for use by CTRL)
*
* In: A = image #, X = table #
* Out: A = width, X = height
*
*-------------------------------
DIMCHAR
sta IMAGE
stx TABLE
jsr setcharimg
jmp getwidth
*-------------------------------
*
* C V T X
*
* Convert X-coord to byte & offset
* Works for both single & double hires
*
* In: XCO/OFFSET = X-coord (2 bytes)
* Out: XCO/OFFSET = byte/offset
*
* Hires scrn: X-coord range 0-279, byte range 0-39
* Dbl hires scrn: X-coord range 0-559, byte range 0-79
*
* Trashes Y-register
*
* Returns accurate results for all input (-32767 to 32767)
* but wildly offscreen values will slow it down
*
*-------------------------------
]XL = XCO
]XH = OFFSET
range = 36*7 ;largest multiple of 7 under 256
CVTX
lda #0
sta ]temp
lda ]XH
bmi :negative ;X < 0
beq :ok ;0 <= X <= 255
:loop lda ]temp
clc
adc #36
sta ]temp
lda ]XL
sec
sbc #range
sta ]XL
lda ]XH
sbc #0
sta ]XH
bne :loop
:ok ldy ]XL
lda ByteTable,y
clc
adc ]temp
sta XCO
lda OffsetTable,y
sta OFFSET
rts
:negative
lda ]temp
sec
sbc #36
sta ]temp
lda ]XL
clc
adc #range
sta ]XL
lda ]XH
adc #0
sta ]XH
bne :negative
beq :ok
]rts rts
*-------------------------------
*
* Z E R O L I S T S
*
* Zero image lists (except peel lists)
*
*-------------------------------
ZEROLSTS lda #0
sta genCLS
sta wipeX
sta bgX
sta midX
sta objX
sta fgX
sta msgX
rts
*-------------------------------
*
* Zero both peel lists
*
*-------------------------------
ZEROPEELS
lda #0
sta peelX
sta peelX+maxpeel
]rts rts
*-------------------------------
*
* Z E R O P E E L
*
* Zero peel list & buffer for whichever page we're on
*
* (Point PEELBUF to beginning of appropriate peel buffer
* & set #-of-images byte to zero)
*
*-------------------------------
ZEROPEEL
lda #0
ldx PAGE
beq :page1
:page2 sta peelX+maxpeel
lda #peelbuf2
sta PEELBUF
lda #>peelbuf2
sta PEELBUF+1
rts
:page1 sta peelX
lda #peelbuf1
sta PEELBUF
lda #>peelbuf1
sta PEELBUF+1
rts
*-------------------------------
*
* Joystick/keyboard routines
*
*-------------------------------
*
* Get input from selected/deselected device
*
* In: kbdX, kbdY, joyX, joyY, BTN0, BTN1, ManCtrl
*
* Out: JSTKX, JSTKY, btn
*
*-------------------------------
GETSELECT
lda joyon ;joystick selected?
bne getjoy ;yes--use jstk
beq getkbd ;no--use kbd
GETDESEL
lda joyon
bne getkbd
beq getjoy
getjoy lda joyX
sta JSTKX
lda joyY
sta JSTKY
lda BTN1
ldx ManCtrl ;When manual ctrl is on, btn 0 belongs
bmi :1 ;to kbd and btn 1 to jstk. With manual ctrl
ora BTN0 ;off, btns can be used interchangeably.
:1 sta btn
rts
getkbd lda kbdX
sta JSTKX
lda kbdY
sta JSTKY
lda BTN0
ldx ManCtrl
bmi :1
ora BTN1
:1 sta btn
]rts rts
*-------------------------------
*
* Read controller (jstk & buttons)
*
* Out: joyX-Y, BTN0-1
*
*-------------------------------
CONTROLLER
jsr JREAD ;read jstk
jmp BREAD ;& btns
*-------------------------------
*
* Read joystick
*
* Out: joyX-Y
*
* joyX: -1 = left, 0 = center, +1 = right
* joyY: -1 = up, 0 = center, +1 = down
*
*-------------------------------
JREAD
lda joyon
beq ]rts
jsr PREAD ;read game pots
ldx #0
jsr cvtpdl
inx
jsr cvtpdl
* Reverse joyY?
lda jvert
beq :1
lda #0
sec
sbc joyY
sta joyY
* Reverse joyX?
:1 lda jhoriz
beq ]rts
lda #0
sec
sbc joyX
sta joyX
]rts rts
*-------------------------------
*
* Read buttons
*
* Out: BTN0-1
*
*-------------------------------
BREAD
lda jbtns
bne :1 ;buttons switched
lda $c061
ldx $c062
:2 sta BTN0
stx BTN1
rts
:1 ldx $c062
lda $c061
jmp :2
*-------------------------------
*
* (Temp routine--for builder only)
*
*-------------------------------
BUTTONS
do EditorDisk
ldx BTN0 ;"raw"
lda #0
sta BUTT0
lda b0down ;last button value
stx b0down
and #$80
bne :rdbtn1
stx BUTT0
:rdbtn1 ldx BTN1
lda #0
sta BUTT1
lda b1down
stx b1down
and #$80
bne :rdjup
stx BUTT1
:rdjup lda joyY
bmi ]rts
lda #0
sta JSTKUP ;jstk is not up--clear JSTKUP
fin
]rts rts
*-------------------------------
*
* Convert raw counter value (approx. 0-70) to -1/0/1
*
* In: X = paddle # (0 = horiz, 1 = vert)
*
*-------------------------------
cvtpdl
lda joyX,x
cmp jthres1x,x
bcs :1
lda #-1
bne :3
:1 cmp jthres2x,x
bcs :2
lda #0
beq :3
:2 lda #1
:3 sta joyX,x
]rts rts
*-------------------------------
*
* Read game pots
*
* Out: Raw counter values (approx. 0-70) in joyX-Y
*
*-------------------------------
PREAD
lda #0
sta joyX
sta joyY
lda $c070 ;Reset timers
:loop ldx #1
:1 lda $c064,x ;Check timer input
bpl :beat
inc joyX,x ;Still high; increment counter
:nextpdl dex
bpl :1
lda $C064
ora $C065
bpl ]rts ;Both inputs low: we're done
lda joyX
ora joyY
bpl :loop ;Do it again
]rts rts
:beat nop
bpl :nextpdl ;Kill time
*-------------------------------
*
* Select jstk & define current joystick posn as center
*
* Out: jthres1-2x, jthres1-2y
*
*-------------------------------
SETCENTER
jsr normspeed ;IIGS
lda #$ff
sta joyon ;Joystick on
lda #0
sta jvert
sta jhoriz
sta jbtns ;set normal params
jsr PREAD ;get raw jstk values
lda joyX
ora joyY
bmi :nojoy ;No joystick connected
lda joyX
sec
sbc #cwidthx
sta jthres1x
lda joyX
clc
adc #cwidthx
sta jthres2x
lda joyY
sec
sbc #cwidthy
sta jthres1y
lda joyY
clc
adc #cwidthy
sta jthres2y
rts
:nojoy lda #0
sta joyon
]rts rts
*-------------------------------
*
* Move a block of memory
*
* In: A < X.Y
*
* 20 < 40.60 means 2000 < 4000.5fffm
* WARNING: If x >= y, routine will wipe out 64k
*
*-------------------------------
MOVEMEM sta ]dest+1
stx ]source+1
sty ]endsourc+1
ldy #0
sty ]dest
sty ]source
sty ]endsourc
:loop lda (]source),y
sta (]dest),y
iny
bne :loop
inc ]source+1
inc ]dest+1
lda ]source+1
cmp ]endsourc+1
bne :loop
rts
*-------------------------------
*
* G T O N E
*
* Call this routine to confirm special-key presses
* & any other time we want to bypass normal sound interface
*
*-------------------------------
SK1Pitch = 15
SK1Dur = 50
GTONE ldy #SK1Pitch
ldx #>SK1Pitch
lda #SK1Dur
jmp tone
*-------------------------------
*
* Whoop speaker (like RW18)
*
*-------------------------------
WHOOP
ldy #0
:1 tya
bit $c030
:2 sec
sbc #1
bne :2
dey
bne :1
]rts rts
*-------------------------------
*
* Produce tone
*
* In: y-x = pitch lo-hi
* a = duration
*
*-------------------------------
tone
sty :pitch
stx :pitch+1
:outloop bit $c030
ldx #0
:midloop ldy #0
:inloop iny
cpy :pitch
bcc :inloop
inx
cpx :pitch+1
bcc :midloop
sec
sbc #1
bne :outloop
rts
:pitch ds 2
*-------------------------------
*
* Copy one hires page to the other
*
* In: PAGE = dest scrn (00/20)
*
*-------------------------------
COPYSCRN
lda PAGE
clc
adc #$20
sta IMAGE+1 ;dest addr
eor #$60
sta IMAGE ;org addr
jmp copy2000
*-------------------------------
*
* Generate random number
*
* RNDseed := (5 * RNDseed + 23) mod 256
*
*-------------------------------
RND
lda RNDseed
asl
asl
clc
adc RNDseed
clc
adc #23
sta RNDseed
]rts rts
*-------------------------------
*
* Calls to hires & master routines
*
* Hires & master routines are in main lc & use main zp;
* rest of code uses aux lc, zp.
*
*-------------------------------
*
* Master
*
*-------------------------------
LOADLEVEL sta ALTZPoff ;main l.c.
jsr _loadlevel
sta ALTZPon ;aux l.c.
rts
ATTRACTMODE sta ALTZPoff
jsr _attractmode
sta ALTZPon
rts
CUTPRINCESS sta ALTZPoff
jsr _cutprincess
sta ALTZPon
rts
RELOAD sta ALTZPoff
jsr _reload
sta ALTZPon
rts
LOADSTAGE2 sta ALTZPoff
jsr _loadstage2
sta ALTZPon
rts
SAVEGAME sta ALTZPoff
jsr _savegame
sta ALTZPon
rts
LOADGAME sta ALTZPoff
jsr _loadgame
sta ALTZPon
rts
DOSTARTGAME sta ALTZPoff
jmp _dostartgame
EPILOG sta ALTZPoff
jmp _epilog
LOADALTSET sta ALTZPoff
jsr _loadaltset
sta ALTZPon
rts
SCREENDUMP sta ALTZPoff
jsr _screendump
sta ALTZPon
rts
*-------------------------------
*
* Edmaster (editor disk only)
*
*-------------------------------
do EditorDisk
SAVELEVEL sta ALTZPoff
jsr _savelevel
sta ALTZPon
rts
SAVELEVELG sta ALTZPoff
jsr _savelevelg
sta ALTZPon
rts
READDIR sta ALTZPoff
jsr _readdir
sta ALTZPon
rts
WRITEDIR sta ALTZPoff
jsr _writedir
sta ALTZPon
rts
GOBUILD sta ALTZPoff
jsr _gobuild
sta ALTZPon
rts
GOGAME sta ALTZPoff
jsr _gogame
sta ALTZPon
rts
EDREBOOT sta ALTZPoff
jsr _edreboot
sta ALTZPon
rts
else
SAVELEVEL
SAVELEVELG
READDIR
WRITEDIR
GOBUILD
GOGAME
EDREBOOT rts
fin
*-------------------------------
*
* Hires
*
*-------------------------------
CLS jsr prehr
sta ALTZPoff
jsr _cls
sta ALTZPon
rts
LAY jsr prehr
sta ALTZPoff
jsr _lay
sta ALTZPon
rts
FASTLAY jsr prehr
sta ALTZPoff
jsr _fastlay
sta ALTZPon
rts
LAYRSAVE jsr prehr
sta ALTZPoff
jsr _layrsave
sta ALTZPon
jmp posthr
LRCLS sta scrncolor ;In: A = screen color
sta ALTZPoff
jsr _lrcls
sta ALTZPon
rts
FASTMASK jsr prehr
sta ALTZPoff
jsr _fastmask
sta ALTZPon
rts
FASTBLACK jsr prehr
sta ALTZPoff
jsr _fastblack
sta ALTZPon
rts
PEEL jsr prehr
sta ALTZPoff
jsr _peel
sta ALTZPon
rts
GETWIDTH jsr prehr
sta ALTZPoff
jsr _getwidth
sta ALTZPon
rts
COPY2000 jsr prehr
sta ALTZPoff
jsr _copy2000
sta ALTZPon
rts
COPY2000AM jsr prehr
sta ALTZPoff
jsr _copy2000am
sta ALTZPon
rts
COPY2000MA jsr prehr
sta ALTZPoff
jsr _copy2000ma
sta ALTZPon
rts
SETFASTAUX
sta ALTZPoff
jsr _setfastaux
sta ALTZPon
rts
SETFASTMAIN
sta ALTZPoff
jsr _setfastmain
sta ALTZPon
rts
INVERTY
sta ALTZPoff
jsr _inverty
sta ALTZPon
rts
*-------------------------------
*
* Call sound routines (in aux l.c. bank 1)
* Exit with bank 2 switched in
*
*-------------------------------
]bank1in bit RWBANK1
bit RWBANK1
rts
MINIT jsr ]bank1in
jsr CALLMINIT
]bank2in bit RWBANK2
bit RWBANK2
rts
MPLAY jsr ]bank1in
jsr CALLMPLAY
jmp ]bank2in
*-------------------------------
*
* Call aux l.c. routines from MASTER (main l.c.)
*
*-------------------------------
XMINIT sta ALTZPon
jsr MINIT
sta ALTZPoff
rts
XMPLAY sta ALTZPon
jsr MPLAY
sta ALTZPoff
rts
XTITLE sta ALTZPon
jsr titlescreen
sta ALTZPoff
rts
XPLAYCUT sta ALTZPon
jsr playcut ;in subs
sta ALTZPoff
rts
XMOVEMUSIC sta ALTZPon
jsr movemusic ;in misc
sta ALTZPoff
rts
*-------------------------------
*
* Copy hires params from aux to main z.p.
*
* (Enter & exit w/ ALTZP on)
*
*-------------------------------
prehr
ldx #$17
:loop sta ALTZPon ;aux zp
lda $00,x
sta ALTZPoff ;main zp
sta $00,x
dex
bpl :loop
sta ALTZPon
rts
*-------------------------------
*
* Copy hires params from main to aux z.p.
*
* (Enter & exit w/ ALTZP on)
*
*-------------------------------
posthr
ldx #$17
:loop sta ALTZPoff
lda $00,x
sta ALTZPon
sta $00,x
dex
bpl :loop
]rts rts
*-------------------------------
*
* Save master copy of blueprint in l.c. bank 1
*
*-------------------------------
SAVEBLUE
jsr ]bank1in
lda #>$d700
ldx #>$b700
ldy #>$b700+$900
jsr movemem
jmp ]bank2in
SAVEBINFO
jsr ]bank1in
lda #>$d000
ldx #>$a600
ldy #>$a600+$600
jsr movemem
jmp ]bank2in
*-------------------------------
*
* Reload master copy of blueprint from l.c. bank 1
*
*-------------------------------
RELOADBLUE
jsr ]bank1in
lda #>$b700
ldx #>$d700
ldy #>$d700+$900
jsr movemem
jmp ]bank2in
RELOADBINFO
jsr ]bank1in
lda #>$a600
ldx #>$d000
ldy #>$d000+$600
jsr movemem
jmp ]bank2in
*-------------------------------
*
* Display lo-res page 1
*
*-------------------------------
GR jmp gtone ;temp!
*-------------------------------
* The following routines properly belong to FRAMEADV
* but have been moved here for lack of space
*-------------------------------
*
* C A L C B L U E
*
* Given: screen #, 1-24 (in acc)
* Return: start of BLUETYPE table (in BlueType)
* start of BLUESPEC table (in BlueSpec)
*
* If A = 0...
* In game: returns garbage
* In builder: returns menu data
*
*-------------------------------
CALCBLUE
cmp #0
beq calcmenu
sec
sbc #1 ;reduce to 0-23
asl
tax ;x2
lda Mult30,x
clc
adc #blueprnt
sta BlueType
lda Mult30+1,x
adc #>blueprnt
sta BlueType+1
lda BlueType
clc
adc #24*30
sta BlueSpec
lda BlueType+1
adc #>24*30
sta BlueSpec+1
]rts rts
calcmenu
lda #menutype
sta BlueType
lda #>menutype
sta BlueType+1
lda #menuspec
sta BlueSpec
lda #>menuspec
sta BlueSpec+1
rts
*-------------------------------
*
* Z E R O R E D
*
* zero redraw buffers
*
*-------------------------------
ZERORED
lda #0
ldy #29
:loop sta redbuf,y
sta fredbuf,y
sta floorbuf,y
sta halfbuf,y
sta wipebuf,y
sta movebuf,y
sta objbuf,y
dey
bpl :loop
ldy #9
:loop2 sta topbuf,y
dey
bpl :loop2
rts
*-------------------------------
*
* Routines to interface with MSYS (Music System II)
*
*-------------------------------
*
* Switch zero page
*
*-------------------------------
switchzp
ldx #31
:loop ldy savezp,x
lda $00,x
sta savezp,x
tya
sta $00,x
dex
bpl :loop
rts
*-------------------------------
*
* Call MINIT
*
* In: A = song #
*
*-------------------------------
CALLMINIT
pha
jsr switchzp
pla
jsr _minit
jmp switchzp
*-------------------------------
*
* Call MPLAY
*
* Out: A = song #
* (Most songs set song # = 0 when finished)
*
*-------------------------------
CALLMPLAY
lda soundon
and musicon
beq :silent
jsr switchzp
jsr _mplay ;returns INDEX
pha
jsr switchzp
pla
rts
:silent lda #0
]rts rts
*-------------------------------
*
* M U S I C K E Y S
*
* Call while music is playing
*
* Esc to pause, Ctrl-S to turn sound off
* Return A = ASCII value (FF for button)
* Clear hibit if it's a key we've handled
*
*-------------------------------
MUSICKEYS
lda $c000
sta keypress
bpl :nokey
sta $c010
cmp #ESC
bne :cont
:froze lda $c000
sta keypress
bpl :froze
sta $c010
cmp #ESC
bne :cont
and #$7f
rts
:cont cmp #ksound
bne :3
lda soundon
eor #1
sta soundon
:21 beq :2
jsr gtone
:2 lda #0
rts
:3 cmp #kmusic
bne :1
lda musicon
eor #1
sta musicon
jmp :21
:nobtn lda keypress
rts
:1
:nokey lda $c061
ora $c062
bpl :nobtn
lda #$ff
]rts rts
*===============================
vblflag ds 1
*-------------------------------
*
* Wait for vertical blank (IIe/IIGS)
*
*-------------------------------
VBLANK
:loop1 lda $c019
bpl :loop1
:loop lda $c019
bmi :loop ;wait for beginning of VBL interval
]rts rts
*-------------------------------
*
* Wait for vertical blank (IIc)
*
*-------------------------------
VBLANKIIc
cli ;enable interrupts
:loop1 bit vblflag
bpl :loop1 ;wait for vblflag = 1
lsr vblflag ;...& set vblflag = 0
:loop2 bit vblflag
bpl :loop2
lsr vblflag
sei
rts
* Interrupt jumps to ($FFFE) which points back to VBLI
VBLI
bit $c019
sta $c079 ;enable IOU access
sta $c05b ;enable VBL int
sta $c078 ;disable IOU access
sec
ror vblflag ;set hibit
:notvbl rti
*-------------------------------
*
* Initialize VBLANK vector with correct routine
* depending on whether or not machine is IIc
*
*-------------------------------
InitVBLANK
lda $FBC0
bne ]rts ;not a IIc--use VBLANK
sta RAMWRTaux
lda #VBLANKIIc
sta VBLvect+1
lda #>VBLANKIIc
sta VBLvect+2
sei ;disable interrupts
sta $c079 ;enable IOU access
sta $c05b ;enable VBL int
sta $c078 ;disable IOU access
]rts rts
*-------------------------------
*
* Is this a IIGS?
*
* Out: IIGS (0 = no, 1 = yes)
* If yes, set control panel to default settings
* Exit w/RAM bank 2 switched in
*
* Also initializes VBLANK routine
*
*-------------------------------
CHECKIIGS
do EditorDisk
else
bit USEROM
bit USEROM
lda $FBB3
cmp #6
bne * ;II/II+/III--we shouldn't even be here
sec
jsr $FE1F
bcs :notGS
lda #1
bne :set
:notGS lda #0
:set sta IIGS
jsr InitVBLANK
bit RWBANK2
bit RWBANK2
]rts rts
*-------------------------------
*
* Temporarily set fast speed (IIGS)
*
*-------------------------------
xc
FASTSPEED
lda IIGS
beq ]rts
lda #$80
tsb $C036 ;fast speed
]rts rts
*-------------------------------
*
* Restore speed to normal (& bg & border to black)
*
*-------------------------------
NORMSPEED
lda IIGS
beq ]rts
xc
lda $c034
and #$f0
sta $c034 ;black border
lda #$f0
sta $c022 ;black bg, white text
lda #$80
trb $c036 ;normal speed
xc off
rts
*-------------------------------
*
* Read control panel parameter (IIGS)
*
* In: Y = location
* Out: A = current setting
*
*-------------------------------
xc
xc
getparam
lda IIGS
beq ]rts
clc
xce
rep $30
pha
phy
ldx #$0C03
hex 22,00,00,E1 ;jsl E10000
pla
sec
xce
tay
rts
*-------------------------------
*
* Set control panel parameter (IIGS only)
*
* In: A = desired value, Y = location
*
*-------------------------------
setparam
clc
xce
rep $30
and #$ff
pha
phy
ldx #$B03
hex 22,00,00,E1 ;jsl E10000
sec
xce
rts
xc off
*-------------------------------
lst
eof ds 1
usr $a9,4,$0000,*-org
lst off