diff --git a/01 POP Source/Source/AUTO.S b/01 POP Source/Source/AUTO.S index cdfee2d..44d6b8d 100755 --- a/01 POP Source/Source/AUTO.S +++ b/01 POP Source/Source/AUTO.S @@ -1 +1,1955 @@ -* auto DemoDisk = 0 org = $5400 tr on lst off *------------------------------- * * PRINCE OF PERSIA * Copyright 1989 Jordan Mechner * *------------------------------- org org jmp AUTOCTRL jmp CHECKSTRIKE jmp CHECKSTAB jmp AUTOPLAYBACK jmp CUTCHECK jmp CUTGUARD jmp ADDGUARD jmp CUT *------------------------------- lst put eq lst put gameeq lst put seqdata lst put soundnames lst put movedata lst off dum $f0 ztemp ds 1 prob ds 1 ]cutdir ds 1 ProgStart ds 2 dend plus1 db -1,1 minus1 db 1,-1 * Thresholds for cut to new screen TopCutEdgePl = ScrnTop+10 TopCutEdgeMi = ScrnTop-16 BotCutEdge = ScrnBottom+24 LeftCutEdge = ScrnLeft-4 RightCutEdge = ScrnRight+4 *------------------------------- * Locations of special objects flaskscrn = 24 flaskx = 3 flasky = 0 mirscrn = 4 mirx = 4 miry = 0 swordscrn = 15 swordx = 1 swordy = 0 mousetimer = 150 ;from topctrl *------------------------------- * Strike/block ranges strikerange1 = 12 strikerange2 = 29 blockrange1 = 0 blockrange2 = 29 ;from TestStrike *------------------------------- * Other constants: swordthres = 90 engardethres = 60 strikethres1 = strikerange1 strikethres2 = strikerange2 blockthres1 = 10 blockthres2 = blockrange2 tooclose = strikethres1 toofar = strikethres2+6 ;min dist at which you can advance safely offguardthres = 8 jumpthres = 50 runthres = 40 blocktime = 4 *------------------------------- * * Fighter params (indexed by guardprog #) * * strikeprob = probability x255 of striking from ready posn * restrikeprob = prob x 255 of restriking after blocking * blockprob = prob x255 of blocking opponent's strike * advprob = of advancing to within striking range * refractimer = length of refractory period after being hit * * 0 1 2 3 4 5 6 7 8 9 10 11 strikeprob db 075,100,075,075,075,050,100,220,000,060,040,060 restrikeprob db 000,000,000,005,005,175,020,010,000,255,255,150 blockprob db 000,150,150,200,200,255,200,250,000,255,255,255 impblockprob db 000,075,075,100,100,145,100,250,000,145,255,175 advprob db 255,200,200,200,255,255,200,000,000,255,100,100 refractimer db 020,020,020,020,010,010,010,010,000,010,000,000 specialcolor db 000,000,000,001,000,001,001,000,000,000,000,001 extrastrength db 000,000,000,000,001,000,000,000,000,000,000,000 numprogs = 12 *------------------------------- * Basic guard strength & uniform color (indexed by level #) basicstrength db 4,3,3,3,3,4,5 ;levels 0-6 db 4,4,5,5,5,4,6 ;levels 7-13 basiccolor db 1,0,0,0,1,1,1 ;0 = blue, 1 = red db 0,0,0,1,1,0,0 shadstrength = 4 *------------------------------- * * 10: kid (demo) * 11: enemy (demo) * *------------------------------- * * Automatic enemy control routine * * In: Char vars reflect position in PRECEDING frame; * Op vars reflect position in UPCOMING frame * guardprog = program # * * (Exception: When used by kid fighting in demo, both * Char & Op vars reflect preceding frame.) * *------------------------------- ]rts rts AUTOCTRL jsr DoRelease lda CharID beq :5 ;control kid in demo lda justblocked beq :jb0 dec justblocked :jb0 lda gdtimer beq :gt0 dec gdtimer :gt0 lda refract ;refractory period after being hit beq :2 dec refract :2 lda CharID cmp #24 ;mouse? beq :6 cmp #4 ;skel? beq :3 cmp #2 ;guard? bcc :1 lda level cmp #13 ;vizier? beq :4 jmp GuardProg :1 jmp ShadowProg :3 jmp SkelProg :4 jmp VizierProg :5 jmp KidProg :6 jmp MouseProg *------------------------------- * M O U S E *------------------------------- MouseProg lda CharFace cmp #86 beq ]rts lda CharAction beq :1 ;already stopped lda CharX cmp #166 bcs ]rts lda #Mleave jsr jumpseq jmp animchar ;sets CharAction = 0 :1 lda CharX cmp #200 bcc ]rts jmp VanishChar *------------------------------- * S H A D O W M A N *------------------------------- do DemoDisk ShadowProg SkelProg VizierProg brk else ShadowProg lda level cmp #4 bne :0 jmp ShadLevel4 :0 cmp #5 bne :1 jmp ShadLevel5 :1 cmp #6 bne :2 jmp ShadLevel6 :2 cmp #12 bne :3 jmp FinalShad :3 ]rts rts *------------------------------- * Level-specific code for: * Level 6 (plunge) *------------------------------- ShadLevel6 lda CharScrn cmp #1 beq Shad6a rts * Level 6, screen 1 * When kid jumps chasm, step on plate Shad6a lda KidPosn cmp #43 bne ]rts lda KidX cmp #$80 bcs ]rts jsr DoPress jmp DoFwd ;step fwd *------------------------------- * Level 5 (THIEF) *------------------------------- ShadLevel5 lda CharScrn cmp #flaskscrn beq Shad5 ]rts rts * Level 5, screen 24 * When gate opens, steal potion Shad5 lda PlayCount bne :1 ;continue playback lda #flaskscrn ldx #1 ;x ldy #0 ;y jsr rdblock ;gate lda (BlueSpec),y cmp #20 bcc ]rts ;begin playback lda #0 sta PreRecPtr :1 lda #ShadProg5 ldx #>ShadProg5 jsr AutoPlayback lda CharX cmp #15 bcs ]rts jmp VanishChar *------------------------------- * Level 4 (mirror) *------------------------------- ShadLevel4 lda CharScrn cmp #4 bne ]rts lda CharX cmp #80 bcc :gone jmp DoFwd ;run o.s. :gone jmp VanishChar *------------------------------- * Level 12 (final battle) *------------------------------- FinalShad * Screen 15: Jump on top of kid lda CharScrn cmp #swordscrn bne :cont lda shadowaction bne :cont ;already did it lda OpX cmp #150 bcs :hold ;hold shad at top until kid arrives lda #1 sta shadowaction bne :cont :hold lda #shadpos12 ldx #>shadpos12 jmp csps ]rts rts * Continue :cont lda CharSword cmp #2 bcs :fight lda OpSword cmp #2 bcs :hostile lda offguard bne :face :hostile lda EnemyAlert cmp #2 bcc :2 jsr getopdist cmp #swordthres bcs :2 ;wait until kid gets close lda CharPosn cmp #15 bne ]rts jmp DoEngarde ;draw on kid * turn to face kid :2 jsr getopdist bpl ]rts jmp DoBack * Normal fighting :fight lda offguard beq :1 ;has kid put up sword? lda refract bne :1 ;yes--wait a moment-- jmp DoDown ;--then lower your guard :1 jmp EnGarde ;normal fighting * Face to face--swords down :face jsr getopdist bmi :merge ;whammo! lda EnemyAlert cmp #2 bne :wait lda OpPosn cmp #3 bcc :wait cmp #15 bcc :go cmp #127 bcc :wait cmp #133 bcs :wait * If kid starts moving towards you, reciprocate * (Accept startrun & stepfwd) :go jmp DoFwd * Kid & shadow reunite :merge lda #$ff ;white sta lightcolor lda #10 sta lightning jsr boostmeter lda #s_Rejoin ldx #85 jsr cuesong lda #42 sta mergetimer lda #0 sta CharID jsr SaveKid ;shadow turns into kid jmp VanishChar :wait ]rts rts *------------------------------- * S K E L E T O N *------------------------------- SkelProg lda #2 sta CharSword jmp GuardProg *------------------------------- * V I Z I E R *------------------------------- VizierProg jmp GuardProg fin ;DemoDisk *------------------------------- * K I D (in demo) *------------------------------- KidProg jmp GuardProg *------------------------------- * G U A R D *------------------------------- GuardProg lda CharSword cmp #2 ;Are you already en garde? bcc Alert ;no jmp EnGarde ;yes ]rts rts *------------------------------- * * Alert (not en garde) * *------------------------------- Alert lda KidLife bpl ]rts ;kid's dead--relax * If kid is behind you, turn to face him jsr getopdist ldx OpBlockY cpx CharBlockY bne :difflevel cmp #-8 ;if kid is right on top of you, go en garde! bcs :eng :difflevel ldx alertguard beq :ok ;otherwise wait for a sound to alert you ldx #0 stx alertguard :alert cmp #128 bcc :eng cmp #-4 bcs :ok ;overlapping--stand still jmp DoTurn ;turn around * If you can see kid, go en garde :ok cmp #128 bcs ]rts ;kid is behind you :eng lda EnemyAlert beq ]rts lda level cmp #13 bne :1 ;Vizier only: wait for music to finish lda SongCue bne ]rts :1 jmp DoEngarde ]rts rts *------------------------------- * * En garde * *------------------------------- EnGarde lda CharPosn cmp #166 beq ]rts cmp #150 bcc ]rts ;wait till you're ready lda EnemyAlert cmp #2 bcs :ea2 cmp #1 ;EnemyAlert = 1: Kid is in sight, but a beq ]rts ;gap or barrier separates you--stay put * Kid is out of sight (EnemyAlert = 0) * If kid has "dropped out" of fight, follow him down lda droppedout ;flag set by CHECKFLOOR beq :1 jmp FollowKid * else return to alert position :1 lda CharID cmp #4 beq ]rts ;(except skeleton) jmp DoDropguard * EnemyAlert = 2: Clear stretch of floor to player * If kid is stunned, let him recover... :ea2 jsr getopdist bmi :norec cmp #12 bcc :norec ;unless he's right on top of you lda OpPosn cmp #102 bcc :norec cmp #118 bcs :norec lda OpAction cmp #5 beq ]rts :norec * Advance to closest safe distance jsr getopdist cmp #toofar bcs :outofrange ldx CharSword cpx #2 bcc :offg cmp #tooclose bcc :tooclose jmp InRange :offg cmp #offguardthres bcc :tooclose jmp InRange ]rts rts * Out of range :outofrange lda refract bne ]rts lda CharFace cmp OpFace beq :nojump ;chase him lda OpPosn cmp #7 bcc :norun cmp #15 bcc :runwait :norun cmp #34 bcc :nojump cmp #44 bcc :jumpwait ;If kid is running towards you, stay put :nojump jsr getinfront jsr cmpspace ;Don't advance unless solid floor beq :gap jsr get2infront jsr cmpspace bne :solid :gap jmp DoRetreat :solid jmp DoAdvance * Kid is trying to get past you--cut him down! :jumpwait jsr getopdist cmp #jumpthres bcs ]rts ;wait jmp DoStrike :runwait jsr getopdist cmp #runthres bcs ]rts :strike jmp DoStrike * Too close to hit him :tooclose lda CharFace cmp OpFace beq :ret jmp DoAdvance :ret jmp DoRetreat *------------------------------- * * Kid has "dropped out" of fight * Advance until you run out of floor-- * then decide whether to jump down after him * *------------------------------- FollowKid lda OpAction cmp #2 beq :hanging cmp #6 beq :hanging ;wait--kid is hanging on ledge jsr getinfront sta ztemp jsr cmpbarr bne :stopped lda ztemp jsr cmpspace beq :atedge jmp DoAdvance * At edge of floor. Follow kid down ONLY if: * (1) it's a 1-story drop to solid floor * (2) kid is still down there :atedge jsr getinfront inc tempblocky jsr rdblock1 sta ztemp ;is it safe? cmp #spikes beq :stopped cmp #loose beq :stopped jsr cmpbarr bne :stopped lda ztemp jsr cmpspace beq :stopped lda CharBlockY clc adc #1 cmp OpBlockY bne :stopped ;kid's not down there * It looks safe--follow him down jmp DoAdvance :stopped lda #0 sta droppedout jmp DoRetreat ;so you can kill him if he climbs up :hanging ]rts rts *------------------------------- * * In range * *------------------------------- InRange lda OpSword ;is opponent armed & en garde? cmp #2 beq :fight ;yes * Opponent is unarmed or off guard--maul him! lda refract bne ]rts jsr getopdist cmp #strikethres2 bcc :1 jmp DoAdvance ;advance until within range... :1 jmp DoStrike ;then strike * Opponent is en garde--use strategy :fight jmp GenFight *------------------------------- * * General Fighting Routine * * (Fighters are en garde, face to face, and too close to * advance safely) * *------------------------------- GenFight jsr getopdist cmp #blockthres1 bcc :outofrange cmp #blockthres2 bcs :outofrange jsr MaybeBlock ;block opponent's strike? lda refract bne ]rts jsr getopdist cmp #strikethres1 bcc :outofrange cmp #strikethres2 bcs :outofrange jmp MaybeStrike ;strike? :outofrange jmp MaybeAdvance ;advance to within strike range? ]rts rts *------------------------------- * * Advance to within strike range? * (Only consider it if gdtimer = 0) * *------------------------------- MaybeAdvance lda guardprog beq :dumb ;Guard #0 is too dumb to care lda gdtimer bne ]rts :dumb jsr rndp cmp advprob,x bcs ]rts jmp DoAdvance *------------------------------- * * Block opponent's strike? * *------------------------------- MaybeBlock lda OpPosn cmp #152 ;guy4 beq :99 cmp #153 ;guy5 beq :99 cmp #162 ;guy22 (block to strike) bne ]rts :99 lda justblocked bne :impaired jsr rndp cmp blockprob,x bcc :block ]rts rts :impaired jsr rndp cmp impblockprob,x bcs ]rts :block jmp DoBlock *------------------------------- * * Strike? * *------------------------------- MaybeStrike ldx OpPosn cpx #169 beq ]rts cpx #151 ;opponent starting to strike? beq ]rts ;yes--don't strike ldx CharPosn cpx #161 ;have I just blocked? beq :restrike cpx #150 beq :restrike ;yes--restrike? jsr rndp cmp strikeprob,x bcs ]rts jmp DoStrike :restrike jsr rndp cmp restrikeprob,x bcs ]rts jmp DoStrike *------------------------------- DoRelease lda #0 sta clrF sta clrB sta clrU sta clrD sta clrbtn sta JSTKX sta JSTKY sta btn rts DoAdvance DoFwd lda #-1 sta clrF sta JSTKX rts DoRetreat DoBack lda #-1 sta clrB lda #1 sta JSTKX rts DoBlock DoUp lda #-1 sta clrU sta JSTKY rts DoTurn DoDown lda #-1 sta clrD lda #1 sta JSTKY rts DoStandup lda #-1 sta clrU jmp DoBack DoDropguard DoRunaway lda #-1 sta clrD jmp DoBack DoEngarde lda #-1 sta clrD jmp DoFwd DoStrike DoPress lda #-1 sta clrbtn sta btn rts DoRelBtn lda #0 sta btn ]rts rts *------------------------------- * * R N D P * * Return X = guardprog, A = rnd # * *------------------------------- rndp ldx guardprog jmp rnd *------------------------------- * * C H E C K S T R I K E * * Check for sword contact * * Going in: Kid & Shad vars represent position in * UPCOMING frame * * Out: Kid & Shad vars * (Return Action = 99 if stabbed) * *------------------------------- CHECKSTRIKE lda KidPosn beq ]rts cmp #219 bcc :noclimb cmp #229 bcc ]rts ;on staircase :noclimb jsr LoadShadwOp jsr TestStrike jsr SaveShadwOp jsr LoadKidwOp jsr TestStrike jsr SaveKidwOp ]rts rts *------------------------------- TestStrike lda CharSword cmp #2 ;in fighting mode? bne ]rts ;no lda CharBlockY cmp OpBlockY bne ]rts * Am I on a test (strike) frame? lda CharPosn cmp #153 ;guy5 (frame before full ext.) beq :test cmp #154 ;guy6 (full ext.) bne ]rts * I'm striking--is opponent blocking? :test jsr getopdist cmp #blockrange1 bcc :nobloc cmp #blockrange2 bcs :nobloc lda OpPosn cmp #161 beq :11 cmp #150 ;blocking? bne :nobloc ;no * Yes -- opponent blocks my strike :1 lda #161 sta OpPosn ;change opp to "successful block" :11 lda CharID beq :12 ;am I a guard? lda #blocktime ;yes--impair my blocking ability for a while sta justblocked :12 lda #blockedstrike jsr jumpseq jmp animchar * Skewer opponent? :nobloc lda CharPosn cmp #154 ;full ext bne ]rts jsr getopdist ldx OpSword cpx #2 bcs :ong cmp #offguardthres bcs :cont1 rts :ong cmp #strikerange1 bcc ]rts :cont1 cmp #strikerange2 bcs ]rts lda #99 "stabbed" sta OpAction ]rts rts *------------------------------- * C H E C K S T A B *------------------------------- CHECKSTAB lda ShadAction cmp #99 bne :1 lda KidAction cmp #99 beq :doublestab :2 jsr LoadShad jsr StabChar jsr SaveShad jsr rndp lda refractimer,x sta refract :1 lda KidAction cmp #99 bne ]rts jsr LoadKid jsr StabChar jmp SaveKid * Both chars finish lunge simultaneously :doublestab lda #1 sta KidAction bne :2 ;player wins a tie ]rts rts *------------------------------- * Change shadowman posn * In: A-X = shadpos L-H * Out: Char data *------------------------------- chgshadposn sta ztemp stx ztemp+1 ldy #6 :loop lda (ztemp),y sta Char,y dey bpl :loop ldy #7 lda (ztemp),y jsr jumpseq lda #1 sta CharID lda #0 sta PlayCount ;zero playback counter rts * ... & save csps jsr chgshadposn lda #3 sta guardprog lda #shadstrength sta MaxOppStr sta OppStrength jmp SaveShad *------------------------------- * (Posn, X, Y, Face, BlockX, BlockY, Action) * 0 1 2 3 4 5 6 shadpos6a hex 0f,51,76,00,00,01,00 db stand shadpos5 hex 0f,37,37,00,ff,00,00 db stand ;just o.s. to L shadpos12 hex 0f,51,f0,00,00,00,00 db stepfall *------------------------------- EndProg = -2 EndDemo = -1 Ctr = 0 Fwd = 1 Back = 2 Up = 3 Down = 4 Upfwd = 5 Press = 6 Release = 7 * Commands: * * -2 - end of programmed sequence * -1 - end of demo * 0 - center jstk & release btn * 1 - jstk fwd * 2 - jstk back * 3 - jstk up * 4 - jstk down * 5 - jstk up & fwd * 6 - press & hold btn * 7 - release btn *------------------------------- * * Prerecorded sequence format: * * 1. Frame # (1 byte) * 2. Command (1 byte) * * 255 frames = approx. 25-30 seconds * *------------------------------- * Level 5 (THIEF): Steal potion ShadProg5 db 0,Ctr db 1,Fwd db 14,Ctr db 18,Press db 29,Release db 45,Back db 49,Fwd db 255,EndProg *------------------------------- * * Play back prerecorded movement sequence * * In: A-X = program start addr * PlayCount = frame # * PreRecPtr = pointer to next command * *------------------------------- AUTOPLAYBACK sta ProgStart stx ProgStart+1 * Inc frame counter lda PlayCount cmp #254 bcs :rts inc PlayCount * Look up time of next command ldy PreRecPtr lda PlayCount cmp (ProgStart),y bcs :next * Not there yet--repeat last command dey lda (ProgStart),y jmp :ex * We're there-- :next iny lda (ProgStart),y ;command iny sty PreRecPtr * Execute command :ex cmp #-1 beq :enddemo cmp #0 beq :ctr cmp #1 beq :fwd cmp #2 beq :back cmp #3 beq :up cmp #4 beq :down cmp #5 beq :upfwd cmp #6 beq :press cmp #7 beq :release :rts ]rts rts * Commands :ctr jmp DoRelease :fwd jmp DoFwd :back jmp DoBack :up jmp DoUp :down jmp DoDown :upfwd jsr DoUp jmp DoFwd :press jmp DoPress :release jmp DoRelBtn :enddemo ; lda autopilot ; bne :endpb jmp attractmode ;Game: end demo :endpb ; lda #0 ;Editor: end playback ; sta autopilot ; rts *------------------------------- * * C U T C H E C K * * Cut with kid * *------------------------------- CUTCHECK lda CUTTIMER beq :ok dec CUTTIMER ]rts rts :ok jsr LoadKid jsr setupchar jsr getedges jsr cutchar ;cut with character bmi ]rts ;no cut sta ]cutdir jsr SaveKid lda CharScrn sta cutscrn lda ShadFace cmp #86 ;is there a guard on old screen? beq ]rts ;no * What to do with guard? Two choices: * * (1) UPDATE -- leave guard behind on old screen (& update * his coords so he'll still be there when we come back) * (2) TRANSFER -- transfer guard to new screen (& delete his * coords from old screen) lda ShadLife bpl :update ;dead guard on old screen--leave him behind lda ShadSword cmp #2 bne :update * Is there a live guard on new screen? ldx KidScrn lda GdStartBlock-1,x cmp #30 bcs :nonew ;no lda GdStartSeqH-1,x beq :update ;yes * If guard is too far o.s., leave him behind :nonew lda ]cutdir beq :left cmp #1 beq :right cmp #2 beq :up :down lda ShadBlockY cmp #3 bcs :transfer bcc :update :up lda ShadBlockY bmi :transfer bpl :update :right lda ShadX cmp #ScrnWidth+25 ;25 is safety factor bcc :update bcs :transfer :left lda ShadX cmp #256-ScrnWidth-25 bcs :update * Take him with us :transfer jmp transferguard * Leave him behind :update jmp updateguard *------------------------------- * * Transfer guard from old screen to new screen * (Also remove any dead guards from new scrn) * *------------------------------- transferguard lda #-1 ldx KidScrn ;new scrn sta GdStartBlock-1,x ldx ShadScrn ;old scrn sta GdStartBlock-1,x jsr LoadShad lda ]cutdir jsr cut jmp SaveShad ]rts rts *------------------------------- * * Leaving guard behind on old screen-- * update guard coords * *------------------------------- updateguard lda ShadFace cmp #86 beq ]rts ;no guard lda ShadID cmp #1 beq ]rts ;not for shadman cmp #24 beq ]rts ;or mouse :gd lda #0 ;arbitrary--ADDGUARD will reconstruct sta tempblockx ;CharBlockX from CharX lda ShadBlockY sta tempblocky jsr indexblock tya ldx ShadScrn sta GdStartBlock-1,x lda ShadX sta GdStartX-1,x lda ShadFace sta GdStartFace-1,x lda guardprog sta GdStartProg-1,x lda ShadLife bpl :ok lda #0 sta GdStartSeqH-1,x beq :cont :ok lda ShadSeq sta GdStartSeqL-1,x lda ShadSeq+1 sta GdStartSeqH-1,x * and deactivate enemy char :cont lda #86 sta ShadFace lda #0 sta OppStrength ]rts rts *------------------------------- * * If enemy has fallen to screen below, catch him before * he wraps around to top of VisScrn * *------------------------------- CUTGUARD lda ShadFace cmp #86 beq ]rts lda ShadY cmp #BotCutEdge bcc ]rts * If guard, remove him altogether lda ShadID cmp #4 beq :skel cmp #1 beq :shad ]RemoveGd jsr deadenemy ;music, etc. ldx VisScrn lda #-1 sta GdStartBlock-1,x lda #86 sta ShadFace lda #0 sta OppStrength lda #-1 sta ChgOppStr ]rts rts * If shad, vanish him :shad lda ShadAction cmp #4 bne ]rts jsr LoadShad jsr VanishChar jmp SaveShad * If skel, change scrn :skel lda ShadScrn jsr getdown sta ShadScrn cmp #3 bne ]RemoveGd * Skel lands on scrn 3 lda #Splat jsr addsound lda #$85 sta ShadX lda #1 sta ShadBlockY lda #0 sta ShadFace lda #-1 sta ShadLife jmp updateguard *------------------------------- * * C U T C H A R * * Is character passing o.s.? If so, cut with him to next scrn * * Change CharX,Y,BlockY,Scrn to reflect posn on new scrn * * Return A = direction of cut, -1 if no cut * *------------------------------- cutchar lda CharY ldx CharAction cpx #5 beq :notup cpx #4 beq :notup ;In freefall--cut only down cpx #3 beq :notup * Cut up/down? cmp #TopCutEdgePl bcc :CUTUP cmp #TopCutEdgeMi bcs :CUTUP :notup cmp #BotCutEdge bcs :CUTDOWN * Cut left/right? ldx CharPosn cpx #135 bcc :nocu cpx #150 bcc :nocut ;don't cut L/R on climbup :nocu cpx #110 bcc :nosu cpx #120 bcc :nocut ;or on standup :nosu cpx #150 bcc :nost cpx #163 bcc :nocut cpx #166 bcc :nost cpx #169 bcc :nocut ;or on strike/block :nost lda CharAction cmp #7 beq :nocut ;or on turning ldx CharFace ;-1=left, 0=right beq :faceR ;facing left lda leftej cmp #LeftCutEdge bcc :CUTLEFT beq :CUTLEFT cmp #ScrnRight+1 bcs :CUTRIGHT bcc :nocut :faceR lda CharScrn ldx #9 ldy CharBlockY jsr rdblock cmp #panelwif beq :nocutr cmp #panelwof beq :nocutr ;don't cut R if a panel blocks view lda rightej cmp #RightCutEdge bcs :CUTRIGHT :nocutr lda rightej cmp #ScrnLeft-1 bcc :CUTLEFT beq :CUTLEFT :nocut lda #-1 rts :CUTLEFT jsr mirrmusic jsr milestone3 lda #0 bpl :cut :CUTRIGHT jsr stealsword jsr jaffmusic lda #1 bpl :cut :CUTUP lda #2 bpl :cut * Level 6 ("Plunge"): Kid falls off screen 1 into next level :CUTDOWN jsr infinity lda level cmp #6 bne :no6 lda CharScrn cmp #1 beq :nocut :no6 lda #3 :cut pha jsr cut pla ]rts rts *------------------------------- * Level 12--fall off into infinity *------------------------------- infinity rts *------------------------------- * Passed Level 3 milestone? *------------------------------- milestone3 lda level cmp #3 bne ]rts lda #7 ;scrn to R of gate ]mcheck cmp CharScrn bne ]rts lda #1 sta milestone lda MaxKidStr sta origstrength rts *------------------------------- * Level 12: Shadow steals sword *------------------------------- stealsword lda level cmp #12 bne ]rts lda CharScrn cmp #18 ;scrn below swordscrn bne ]rts lda #swordscrn ldx #swordx ldy #swordy jsr rdblock lda #floor sta (BlueType),y rts *------------------------------- * Level 13: Play Jaffar's Theme *------------------------------- jaffmusic lda level cmp #13 bne ]rts lda exitopen bne ]rts lda CharScrn cmp #3 bne ]rts lda #s_Jaffar ldx #25 jmp cuesong *------------------------------- * Level 4 ("Mirror"): Play danger theme for mirror *------------------------------- mirrmusic lda exitopen beq :no4 cmp #77 beq :no4 lda level cmp #4 bne :no4 lda CharBlockY cmp #miry bne :no4 lda CharScrn cmp #11 ;scrn to R of mirscrn bne :no4 lda #s_Danger ldx #50 jsr cuesong lda #77 sta exitopen ;so we don't repeat theme :no4 ]rts rts *------------------------------- * * C U T * * Move char from CharScrn to adjacent screen * * In: A = cut dir: 0 = left, 1 = right, 2 = up, 3 = down * *------------------------------- CUT cmp #3 beq Cdown cmp #1 beq Cright cmp #2 beq Cup Cleft lda CharScrn jsr getleft ;get new screen # sta CharScrn lda #140 clc adc CharX sta CharX ldx #1 ;new FromDir rts Cright lda CharScrn jsr getright sta CharScrn lda CharX sec sbc #140 sta CharX ldx #0 rts Cup lda CharScrn jsr getup sta CharScrn lda CharBlockY clc adc #3 sta CharBlockY lda CharY clc adc #189 sta CharY ldx #3 rts Cdown lda CharScrn jsr getdown sta CharScrn lda CharBlockY sec sbc #3 sta CharBlockY lda CharY sec sbc #189 sta CharY ldx #2 ]rts rts *------------------------------- * * A D D G U A R D * * On cut to new screen--if guard is there, bring him to life * Also handles hard-wired shadowman appearances * * In: VisScrn * *------------------------------- ADDGUARD lda #0 sta offguard * Level 12 lda level cmp #12 bne :not12 lda exitopen ;set when shadow drops bne ]rts lda mergetimer bne :1 ;shadow has been reabsorbed lda VisScrn cmp #swordscrn :1 bne ]rts sta CharScrn ldx #swordx ldy #swordy jsr rdblock cmp #sword beq ]rts ;sword is still there lda #0 sta shadowaction lda #1 sta exitopen lda #shadpos12 ldx #>shadpos12 jmp csps * Level 6 (Plunge) :not12 lda level cmp #6 ;plunge bne :not6 lda VisScrn sta CharScrn cmp #1 bne AddNormalGd lda exitopen cmp #77 beq :norepeat lda #s_Danger ldx #50 jsr cuesong lda #77 sta exitopen :norepeat lda #shadpos6a ldx #>shadpos6a jmp csps * Level 5 (Thief) :not6 lda level cmp #5 ;thief bne :not5 lda VisScrn sta CharScrn cmp #flaskscrn bne AddNormalGd ldx #flaskx ldy #flasky jsr rdblock cmp #flask bne ]rts ;potion is gone lda #shadpos5 ldx #>shadpos5 jmp csps ]rts rts :not5 *------------------------------- AddNormalGd ldx VisScrn lda GdStartBlock-1,x cmp #30 bcs ]rts ;no guard on this scrn * Bring guard to life (or death) stx CharScrn jsr unindex ;return A = blockx, X = blocky stx CharBlockY lda FloorY+1,x sta CharY ldx VisScrn lda GdStartX-1,x sta CharX jsr getblockxp sta CharBlockX ldx VisScrn lda GdStartFace-1,x sta CharFace lda level cmp #3 bne :3 lda #4 ;skel bne :4 :3 lda #2 ;guard :4 sta CharID lda GdStartSeqH-1,x bne :1 ;0 is code for fresh start lda CharID cmp #4 bne :5 lda #2 sta CharSword lda #landengarde ;skel (ready) bne :6 :5 lda #0 sta CharSword lda #alertstand ;guard :6 jsr jumpseq jmp :2 :1 sta CharSeq+1 lda GdStartSeqL-1,x sta CharSeq :2 jsr animchar lda CharPosn cmp #185 ;killed beq :dead cmp #177 ;impaled beq :dead cmp #178 ;halved beq :dead * Live guard lda #-1 sta CharLife lda #0 sta alertguard sta refract sta justblocked jsr getgdstrength jmp :cont * Dead guard :dead lda #1 sta CharLife lda #0 sta OppStrength * Continue :cont lda #0 sta CharXVel sta CharYVel lda #1 sta CharAction ldx VisScrn lda GdStartProg-1,x cmp #numprogs bcc :ok lda #3 ;default :ok sta guardprog ldx level lda basiccolor,x ldx guardprog eor specialcolor,x ;0 = normal, 1 = special sta GuardColor ;0 = blue, 1 = red jmp SaveShad ;save ShadVars *------------------------------- * Get guard fighting strength *------------------------------- getgdstrength ldx level lda basicstrength,x ldx guardprog clc adc extrastrength,x sta MaxOppStr sta OppStrength ]rts rts *------------------------------- lst ds 1 usr $a9,17,$800,*-org lst off \ No newline at end of file +* auto +DemoDisk = 0 +org = $5400 + tr on + lst off +*------------------------------- +* +* PRINCE OF PERSIA +* Copyright 1989 Jordan Mechner +* +*------------------------------- + org org + + jmp AUTOCTRL + jmp CHECKSTRIKE + jmp CHECKSTAB + jmp AUTOPLAYBACK + jmp CUTCHECK + + jmp CUTGUARD + jmp ADDGUARD + jmp CUT + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put seqdata + lst + put soundnames + lst + put movedata + lst off + + dum $f0 +ztemp ds 1 +prob ds 1 +]cutdir ds 1 +ProgStart ds 2 + dend + +plus1 db -1,1 +minus1 db 1,-1 + +* Thresholds for cut to new screen + +TopCutEdgePl = ScrnTop+10 +TopCutEdgeMi = ScrnTop-16 +BotCutEdge = ScrnBottom+24 + +LeftCutEdge = ScrnLeft-4 +RightCutEdge = ScrnRight+4 + +*------------------------------- +* Locations of special objects + +flaskscrn = 24 +flaskx = 3 +flasky = 0 + +mirscrn = 4 +mirx = 4 +miry = 0 + +swordscrn = 15 +swordx = 1 +swordy = 0 + +mousetimer = 150 ;from topctrl + +*------------------------------- +* Strike/block ranges + +strikerange1 = 12 +strikerange2 = 29 +blockrange1 = 0 +blockrange2 = 29 ;from TestStrike + +*------------------------------- +* Other constants: + +swordthres = 90 +engardethres = 60 +strikethres1 = strikerange1 +strikethres2 = strikerange2 +blockthres1 = 10 +blockthres2 = blockrange2 +tooclose = strikethres1 +toofar = strikethres2+6 ;min dist at which you can advance safely +offguardthres = 8 +jumpthres = 50 +runthres = 40 +blocktime = 4 + +*------------------------------- +* +* Fighter params (indexed by guardprog #) +* +* strikeprob = probability x255 of striking from ready posn +* restrikeprob = prob x 255 of restriking after blocking +* blockprob = prob x255 of blocking opponent's strike +* advprob = of advancing to within striking range +* refractimer = length of refractory period after being hit +* +* 0 1 2 3 4 5 6 7 8 9 10 11 + +strikeprob + db 075,100,075,075,075,050,100,220,000,060,040,060 +restrikeprob + db 000,000,000,005,005,175,020,010,000,255,255,150 +blockprob + db 000,150,150,200,200,255,200,250,000,255,255,255 +impblockprob + db 000,075,075,100,100,145,100,250,000,145,255,175 +advprob + db 255,200,200,200,255,255,200,000,000,255,100,100 +refractimer + db 020,020,020,020,010,010,010,010,000,010,000,000 +specialcolor + db 000,000,000,001,000,001,001,000,000,000,000,001 +extrastrength + db 000,000,000,000,001,000,000,000,000,000,000,000 + +numprogs = 12 + +*------------------------------- +* Basic guard strength & uniform color (indexed by level #) + +basicstrength + db 4,3,3,3,3,4,5 ;levels 0-6 + db 4,4,5,5,5,4,6 ;levels 7-13 + +basiccolor + db 1,0,0,0,1,1,1 ;0 = blue, 1 = red + db 0,0,0,1,1,0,0 + +shadstrength = 4 + +*------------------------------- +* +* 10: kid (demo) +* 11: enemy (demo) +* +*------------------------------- +* +* Automatic enemy control routine +* +* In: Char vars reflect position in PRECEDING frame; +* Op vars reflect position in UPCOMING frame +* guardprog = program # +* +* (Exception: When used by kid fighting in demo, both +* Char & Op vars reflect preceding frame.) +* +*------------------------------- +]rts rts + +AUTOCTRL + jsr DoRelease + + lda CharID + beq :5 ;control kid in demo + + lda justblocked + beq :jb0 + dec justblocked + +:jb0 lda gdtimer + beq :gt0 + dec gdtimer +:gt0 + lda refract ;refractory period after being hit + beq :2 + dec refract +:2 + lda CharID + cmp #24 ;mouse? + beq :6 + cmp #4 ;skel? + beq :3 + cmp #2 ;guard? + bcc :1 + lda level + cmp #13 ;vizier? + beq :4 + jmp GuardProg +:1 jmp ShadowProg +:3 jmp SkelProg +:4 jmp VizierProg +:5 jmp KidProg +:6 jmp MouseProg + +*------------------------------- +* M O U S E +*------------------------------- +MouseProg + lda CharFace + cmp #86 + beq ]rts + lda CharAction + beq :1 ;already stopped + lda CharX + cmp #166 + bcs ]rts + lda #Mleave + jsr jumpseq + jmp animchar ;sets CharAction = 0 + +:1 lda CharX + cmp #200 + bcc ]rts + jmp VanishChar + +*------------------------------- +* S H A D O W M A N +*------------------------------- + do DemoDisk +ShadowProg +SkelProg +VizierProg + brk + + else +ShadowProg + lda level + cmp #4 + bne :0 + jmp ShadLevel4 + +:0 cmp #5 + bne :1 + jmp ShadLevel5 + +:1 cmp #6 + bne :2 + jmp ShadLevel6 + +:2 cmp #12 + bne :3 + jmp FinalShad +:3 +]rts rts + +*------------------------------- +* Level-specific code for: +* Level 6 (plunge) +*------------------------------- +ShadLevel6 + lda CharScrn + cmp #1 + beq Shad6a + rts + +* Level 6, screen 1 +* When kid jumps chasm, step on plate + +Shad6a + lda KidPosn + cmp #43 + bne ]rts + lda KidX + cmp #$80 + bcs ]rts + jsr DoPress + jmp DoFwd ;step fwd + +*------------------------------- +* Level 5 (THIEF) +*------------------------------- +ShadLevel5 + lda CharScrn + cmp #flaskscrn + beq Shad5 +]rts rts + +* Level 5, screen 24 +* When gate opens, steal potion + +Shad5 + lda PlayCount + bne :1 ;continue playback + + lda #flaskscrn + ldx #1 ;x + ldy #0 ;y + jsr rdblock ;gate + lda (BlueSpec),y + cmp #20 + bcc ]rts +;begin playback + lda #0 + sta PreRecPtr + +:1 lda #ShadProg5 + ldx #>ShadProg5 + jsr AutoPlayback + + lda CharX + cmp #15 + bcs ]rts + jmp VanishChar + +*------------------------------- +* Level 4 (mirror) +*------------------------------- +ShadLevel4 + lda CharScrn + cmp #4 + bne ]rts + lda CharX + cmp #80 + bcc :gone + jmp DoFwd ;run o.s. +:gone jmp VanishChar + +*------------------------------- +* Level 12 (final battle) +*------------------------------- +FinalShad + +* Screen 15: Jump on top of kid + + lda CharScrn + cmp #swordscrn + bne :cont + lda shadowaction + bne :cont ;already did it + lda OpX + cmp #150 + bcs :hold ;hold shad at top until kid arrives + + lda #1 + sta shadowaction + bne :cont + +:hold lda #shadpos12 + ldx #>shadpos12 + jmp csps +]rts rts + +* Continue + +:cont lda CharSword + cmp #2 + bcs :fight + lda OpSword + cmp #2 + bcs :hostile + lda offguard + bne :face +:hostile + lda EnemyAlert + cmp #2 + bcc :2 + jsr getopdist + cmp #swordthres + bcs :2 ;wait until kid gets close + + lda CharPosn + cmp #15 + bne ]rts + jmp DoEngarde ;draw on kid + +* turn to face kid + +:2 jsr getopdist + bpl ]rts + jmp DoBack + +* Normal fighting + +:fight + lda offguard + beq :1 ;has kid put up sword? + lda refract + bne :1 ;yes--wait a moment-- + jmp DoDown ;--then lower your guard + +:1 jmp EnGarde ;normal fighting + +* Face to face--swords down + +:face jsr getopdist + bmi :merge ;whammo! + + lda EnemyAlert + cmp #2 + bne :wait + lda OpPosn + cmp #3 + bcc :wait + cmp #15 + bcc :go + cmp #127 + bcc :wait + cmp #133 + bcs :wait + +* If kid starts moving towards you, reciprocate +* (Accept startrun & stepfwd) + +:go jmp DoFwd + +* Kid & shadow reunite + +:merge + lda #$ff ;white + sta lightcolor + lda #10 + sta lightning + + jsr boostmeter + + lda #s_Rejoin + ldx #85 + jsr cuesong + + lda #42 + sta mergetimer + + lda #0 + sta CharID + jsr SaveKid ;shadow turns into kid + jmp VanishChar +:wait +]rts rts + +*------------------------------- +* S K E L E T O N +*------------------------------- +SkelProg + lda #2 + sta CharSword + jmp GuardProg + +*------------------------------- +* V I Z I E R +*------------------------------- +VizierProg + jmp GuardProg + + fin ;DemoDisk + +*------------------------------- +* K I D (in demo) +*------------------------------- +KidProg + jmp GuardProg + +*------------------------------- +* G U A R D +*------------------------------- +GuardProg + lda CharSword + cmp #2 ;Are you already en garde? + bcc Alert ;no + jmp EnGarde ;yes +]rts rts + +*------------------------------- +* +* Alert (not en garde) +* +*------------------------------- +Alert + lda KidLife + bpl ]rts ;kid's dead--relax + +* If kid is behind you, turn to face him + + jsr getopdist + ldx OpBlockY + cpx CharBlockY + bne :difflevel + cmp #-8 ;if kid is right on top of you, go en garde! + bcs :eng +:difflevel + ldx alertguard + beq :ok ;otherwise wait for a sound to alert you + ldx #0 + stx alertguard +:alert + cmp #128 + bcc :eng + cmp #-4 + bcs :ok ;overlapping--stand still + jmp DoTurn ;turn around + +* If you can see kid, go en garde + +:ok cmp #128 + bcs ]rts ;kid is behind you + +:eng lda EnemyAlert + beq ]rts + + lda level + cmp #13 + bne :1 ;Vizier only: wait for music to finish + lda SongCue + bne ]rts + +:1 jmp DoEngarde +]rts rts + +*------------------------------- +* +* En garde +* +*------------------------------- +EnGarde + lda CharPosn + cmp #166 + beq ]rts + cmp #150 + bcc ]rts ;wait till you're ready + + lda EnemyAlert + cmp #2 + bcs :ea2 + cmp #1 ;EnemyAlert = 1: Kid is in sight, but a + beq ]rts ;gap or barrier separates you--stay put + +* Kid is out of sight (EnemyAlert = 0) +* If kid has "dropped out" of fight, follow him down + + lda droppedout ;flag set by CHECKFLOOR + beq :1 + jmp FollowKid + +* else return to alert position + +:1 lda CharID + cmp #4 + beq ]rts ;(except skeleton) + jmp DoDropguard + +* EnemyAlert = 2: Clear stretch of floor to player + +* If kid is stunned, let him recover... + +:ea2 jsr getopdist + bmi :norec + cmp #12 + bcc :norec ;unless he's right on top of you + lda OpPosn + cmp #102 + bcc :norec + cmp #118 + bcs :norec + lda OpAction + cmp #5 + beq ]rts +:norec + +* Advance to closest safe distance + + jsr getopdist + cmp #toofar + bcs :outofrange + + ldx CharSword + cpx #2 + bcc :offg + + cmp #tooclose + bcc :tooclose + jmp InRange + +:offg cmp #offguardthres + bcc :tooclose + jmp InRange +]rts rts + +* Out of range + +:outofrange + lda refract + bne ]rts + + lda CharFace + cmp OpFace + beq :nojump ;chase him + + lda OpPosn + cmp #7 + bcc :norun + cmp #15 + bcc :runwait +:norun + cmp #34 + bcc :nojump + cmp #44 + bcc :jumpwait ;If kid is running towards you, stay put +:nojump + jsr getinfront + jsr cmpspace ;Don't advance unless solid floor + beq :gap + jsr get2infront + jsr cmpspace + bne :solid + +:gap jmp DoRetreat +:solid jmp DoAdvance + +* Kid is trying to get past you--cut him down! + +:jumpwait + jsr getopdist + cmp #jumpthres + bcs ]rts ;wait + jmp DoStrike + +:runwait + jsr getopdist + cmp #runthres + bcs ]rts +:strike jmp DoStrike + +* Too close to hit him + +:tooclose + lda CharFace + cmp OpFace + beq :ret + jmp DoAdvance +:ret jmp DoRetreat + +*------------------------------- +* +* Kid has "dropped out" of fight +* Advance until you run out of floor-- +* then decide whether to jump down after him +* +*------------------------------- +FollowKid + lda OpAction + cmp #2 + beq :hanging + cmp #6 + beq :hanging ;wait--kid is hanging on ledge + + jsr getinfront + sta ztemp + jsr cmpbarr + bne :stopped + lda ztemp + jsr cmpspace + beq :atedge + jmp DoAdvance + +* At edge of floor. Follow kid down ONLY if: +* (1) it's a 1-story drop to solid floor +* (2) kid is still down there + +:atedge + jsr getinfront + inc tempblocky + jsr rdblock1 + sta ztemp ;is it safe? + cmp #spikes + beq :stopped + cmp #loose + beq :stopped + jsr cmpbarr + bne :stopped + lda ztemp + jsr cmpspace + beq :stopped + + lda CharBlockY + clc + adc #1 + cmp OpBlockY + bne :stopped ;kid's not down there + +* It looks safe--follow him down + + jmp DoAdvance + +:stopped lda #0 + sta droppedout + jmp DoRetreat ;so you can kill him if he climbs up +:hanging +]rts rts + +*------------------------------- +* +* In range +* +*------------------------------- +InRange + lda OpSword ;is opponent armed & en garde? + cmp #2 + beq :fight ;yes + +* Opponent is unarmed or off guard--maul him! + + lda refract + bne ]rts + + jsr getopdist + cmp #strikethres2 + bcc :1 + jmp DoAdvance ;advance until within range... +:1 jmp DoStrike ;then strike + +* Opponent is en garde--use strategy + +:fight + jmp GenFight + +*------------------------------- +* +* General Fighting Routine +* +* (Fighters are en garde, face to face, and too close to +* advance safely) +* +*------------------------------- +GenFight + jsr getopdist + cmp #blockthres1 + bcc :outofrange + cmp #blockthres2 + bcs :outofrange + + jsr MaybeBlock ;block opponent's strike? + + lda refract + bne ]rts + + jsr getopdist + cmp #strikethres1 + bcc :outofrange + cmp #strikethres2 + bcs :outofrange + + jmp MaybeStrike ;strike? + +:outofrange + jmp MaybeAdvance ;advance to within strike range? +]rts rts + +*------------------------------- +* +* Advance to within strike range? +* (Only consider it if gdtimer = 0) +* +*------------------------------- +MaybeAdvance + lda guardprog + beq :dumb ;Guard #0 is too dumb to care + lda gdtimer + bne ]rts + +:dumb jsr rndp + cmp advprob,x + bcs ]rts + + jmp DoAdvance + +*------------------------------- +* +* Block opponent's strike? +* +*------------------------------- +MaybeBlock + lda OpPosn + cmp #152 ;guy4 + beq :99 + cmp #153 ;guy5 + beq :99 + cmp #162 ;guy22 (block to strike) + bne ]rts + +:99 lda justblocked + bne :impaired + jsr rndp + cmp blockprob,x + bcc :block +]rts rts + +:impaired + jsr rndp + cmp impblockprob,x + bcs ]rts +:block jmp DoBlock + +*------------------------------- +* +* Strike? +* +*------------------------------- +MaybeStrike + ldx OpPosn + cpx #169 + beq ]rts + cpx #151 ;opponent starting to strike? + beq ]rts ;yes--don't strike + + ldx CharPosn + cpx #161 ;have I just blocked? + beq :restrike + cpx #150 + beq :restrike ;yes--restrike? + + jsr rndp + cmp strikeprob,x + bcs ]rts + jmp DoStrike + +:restrike + jsr rndp + cmp restrikeprob,x + bcs ]rts + jmp DoStrike + +*------------------------------- +DoRelease + lda #0 + sta clrF + sta clrB + sta clrU + sta clrD + sta clrbtn + sta JSTKX + sta JSTKY + sta btn + rts + +DoAdvance +DoFwd + lda #-1 + sta clrF + sta JSTKX + rts + +DoRetreat +DoBack + lda #-1 + sta clrB + lda #1 + sta JSTKX + rts + +DoBlock +DoUp lda #-1 + sta clrU + sta JSTKY + rts + +DoTurn +DoDown lda #-1 + sta clrD + lda #1 + sta JSTKY + rts + +DoStandup + lda #-1 + sta clrU + jmp DoBack + +DoDropguard +DoRunaway + lda #-1 + sta clrD + jmp DoBack + +DoEngarde + lda #-1 + sta clrD + jmp DoFwd + +DoStrike +DoPress + lda #-1 + sta clrbtn + sta btn + rts + +DoRelBtn + lda #0 + sta btn +]rts rts + +*------------------------------- +* +* R N D P +* +* Return X = guardprog, A = rnd # +* +*------------------------------- +rndp + ldx guardprog + jmp rnd + +*------------------------------- +* +* C H E C K S T R I K E +* +* Check for sword contact +* +* Going in: Kid & Shad vars represent position in +* UPCOMING frame +* +* Out: Kid & Shad vars +* (Return Action = 99 if stabbed) +* +*------------------------------- +CHECKSTRIKE + lda KidPosn + beq ]rts + cmp #219 + bcc :noclimb + cmp #229 + bcc ]rts ;on staircase +:noclimb + jsr LoadShadwOp + jsr TestStrike + jsr SaveShadwOp + + jsr LoadKidwOp + jsr TestStrike + jsr SaveKidwOp + +]rts rts + +*------------------------------- +TestStrike + + lda CharSword + cmp #2 ;in fighting mode? + bne ]rts ;no + + lda CharBlockY + cmp OpBlockY + bne ]rts + +* Am I on a test (strike) frame? + + lda CharPosn + cmp #153 ;guy5 (frame before full ext.) + beq :test + cmp #154 ;guy6 (full ext.) + bne ]rts + +* I'm striking--is opponent blocking? + +:test + jsr getopdist + cmp #blockrange1 + bcc :nobloc + + cmp #blockrange2 + bcs :nobloc + + lda OpPosn + cmp #161 + beq :11 + cmp #150 ;blocking? + bne :nobloc ;no + +* Yes -- opponent blocks my strike + +:1 lda #161 + sta OpPosn ;change opp to "successful block" + +:11 lda CharID + beq :12 ;am I a guard? + lda #blocktime ;yes--impair my blocking ability for a while + sta justblocked + +:12 lda #blockedstrike + jsr jumpseq + jmp animchar + +* Skewer opponent? + +:nobloc + lda CharPosn + cmp #154 ;full ext + bne ]rts + + jsr getopdist + + ldx OpSword + cpx #2 + bcs :ong + cmp #offguardthres + bcs :cont1 + rts +:ong cmp #strikerange1 + bcc ]rts + +:cont1 cmp #strikerange2 + bcs ]rts + + lda #99 "stabbed" + sta OpAction +]rts rts + +*------------------------------- +* C H E C K S T A B +*------------------------------- +CHECKSTAB + lda ShadAction + cmp #99 + bne :1 + + lda KidAction + cmp #99 + beq :doublestab +:2 + jsr LoadShad + jsr StabChar + jsr SaveShad + + jsr rndp + lda refractimer,x + sta refract + +:1 lda KidAction + cmp #99 + bne ]rts + + jsr LoadKid + jsr StabChar + jmp SaveKid + +* Both chars finish lunge simultaneously + +:doublestab + lda #1 + sta KidAction + bne :2 ;player wins a tie +]rts rts + +*------------------------------- +* Change shadowman posn +* In: A-X = shadpos L-H +* Out: Char data +*------------------------------- +chgshadposn + sta ztemp + stx ztemp+1 + ldy #6 +:loop lda (ztemp),y + sta Char,y + dey + bpl :loop + + ldy #7 + lda (ztemp),y + jsr jumpseq + + lda #1 + sta CharID + + lda #0 + sta PlayCount ;zero playback counter + rts + +* ... & save + +csps jsr chgshadposn + + lda #3 + sta guardprog + + lda #shadstrength + sta MaxOppStr + sta OppStrength + + jmp SaveShad + +*------------------------------- +* (Posn, X, Y, Face, BlockX, BlockY, Action) +* 0 1 2 3 4 5 6 + +shadpos6a hex 0f,51,76,00,00,01,00 + db stand + +shadpos5 hex 0f,37,37,00,ff,00,00 + db stand ;just o.s. to L + +shadpos12 hex 0f,51,f0,00,00,00,00 + db stepfall + +*------------------------------- +EndProg = -2 +EndDemo = -1 +Ctr = 0 +Fwd = 1 +Back = 2 +Up = 3 +Down = 4 +Upfwd = 5 +Press = 6 +Release = 7 + +* Commands: +* +* -2 - end of programmed sequence +* -1 - end of demo +* 0 - center jstk & release btn +* 1 - jstk fwd +* 2 - jstk back +* 3 - jstk up +* 4 - jstk down +* 5 - jstk up & fwd +* 6 - press & hold btn +* 7 - release btn + +*------------------------------- +* +* Prerecorded sequence format: +* +* 1. Frame # (1 byte) +* 2. Command (1 byte) +* +* 255 frames = approx. 25-30 seconds +* +*------------------------------- +* Level 5 (THIEF): Steal potion + +ShadProg5 + db 0,Ctr + db 1,Fwd + db 14,Ctr + db 18,Press + db 29,Release + db 45,Back + db 49,Fwd + db 255,EndProg + +*------------------------------- +* +* Play back prerecorded movement sequence +* +* In: A-X = program start addr +* PlayCount = frame # +* PreRecPtr = pointer to next command +* +*------------------------------- +AUTOPLAYBACK + sta ProgStart + stx ProgStart+1 + +* Inc frame counter + + lda PlayCount + cmp #254 + bcs :rts + inc PlayCount + +* Look up time of next command + + ldy PreRecPtr + + lda PlayCount + cmp (ProgStart),y + bcs :next + +* Not there yet--repeat last command + + dey + lda (ProgStart),y + jmp :ex + +* We're there-- + +:next iny + lda (ProgStart),y ;command + iny + sty PreRecPtr + +* Execute command + +:ex cmp #-1 + beq :enddemo + cmp #0 + beq :ctr + cmp #1 + beq :fwd + cmp #2 + beq :back + cmp #3 + beq :up + cmp #4 + beq :down + cmp #5 + beq :upfwd + cmp #6 + beq :press + cmp #7 + beq :release +:rts +]rts rts + +* Commands + +:ctr jmp DoRelease +:fwd jmp DoFwd +:back jmp DoBack +:up jmp DoUp +:down jmp DoDown +:upfwd jsr DoUp + jmp DoFwd +:press jmp DoPress +:release jmp DoRelBtn + +:enddemo ; lda autopilot +; bne :endpb + jmp attractmode ;Game: end demo +:endpb ; lda #0 ;Editor: end playback +; sta autopilot +; rts + +*------------------------------- +* +* C U T C H E C K +* +* Cut with kid +* +*------------------------------- +CUTCHECK + lda CUTTIMER + beq :ok + + dec CUTTIMER +]rts rts + +:ok + jsr LoadKid + jsr setupchar + jsr getedges + jsr cutchar ;cut with character + bmi ]rts ;no cut + sta ]cutdir + + jsr SaveKid + + lda CharScrn + sta cutscrn + + lda ShadFace + cmp #86 ;is there a guard on old screen? + beq ]rts ;no + +* What to do with guard? Two choices: +* +* (1) UPDATE -- leave guard behind on old screen (& update +* his coords so he'll still be there when we come back) +* (2) TRANSFER -- transfer guard to new screen (& delete his +* coords from old screen) + + lda ShadLife + bpl :update ;dead guard on old screen--leave him behind + + lda ShadSword + cmp #2 + bne :update + +* Is there a live guard on new screen? + + ldx KidScrn + lda GdStartBlock-1,x + cmp #30 + bcs :nonew ;no + + lda GdStartSeqH-1,x + beq :update ;yes + +* If guard is too far o.s., leave him behind + +:nonew + lda ]cutdir + beq :left + cmp #1 + beq :right + cmp #2 + beq :up + +:down lda ShadBlockY + cmp #3 + bcs :transfer + bcc :update + +:up lda ShadBlockY + bmi :transfer + bpl :update + +:right lda ShadX + cmp #ScrnWidth+25 ;25 is safety factor + bcc :update + bcs :transfer + +:left lda ShadX + cmp #256-ScrnWidth-25 + bcs :update + +* Take him with us + +:transfer jmp transferguard + +* Leave him behind + +:update jmp updateguard + +*------------------------------- +* +* Transfer guard from old screen to new screen +* (Also remove any dead guards from new scrn) +* +*------------------------------- +transferguard + lda #-1 + ldx KidScrn ;new scrn + sta GdStartBlock-1,x + ldx ShadScrn ;old scrn + sta GdStartBlock-1,x + + jsr LoadShad + + lda ]cutdir + jsr cut + + jmp SaveShad + +]rts rts + +*------------------------------- +* +* Leaving guard behind on old screen-- +* update guard coords +* +*------------------------------- + +updateguard + lda ShadFace + cmp #86 + beq ]rts ;no guard + lda ShadID + cmp #1 + beq ]rts ;not for shadman + cmp #24 + beq ]rts ;or mouse +:gd + lda #0 ;arbitrary--ADDGUARD will reconstruct + sta tempblockx ;CharBlockX from CharX + lda ShadBlockY + sta tempblocky + jsr indexblock + tya + ldx ShadScrn + sta GdStartBlock-1,x + + lda ShadX + sta GdStartX-1,x + + lda ShadFace + sta GdStartFace-1,x + + lda guardprog + sta GdStartProg-1,x + + lda ShadLife + bpl :ok + lda #0 + sta GdStartSeqH-1,x + beq :cont + +:ok lda ShadSeq + sta GdStartSeqL-1,x + lda ShadSeq+1 + sta GdStartSeqH-1,x + +* and deactivate enemy char + +:cont lda #86 + sta ShadFace + + lda #0 + sta OppStrength +]rts rts + +*------------------------------- +* +* If enemy has fallen to screen below, catch him before +* he wraps around to top of VisScrn +* +*------------------------------- +CUTGUARD + lda ShadFace + cmp #86 + beq ]rts + + lda ShadY + cmp #BotCutEdge + bcc ]rts + +* If guard, remove him altogether + + lda ShadID + cmp #4 + beq :skel + cmp #1 + beq :shad + +]RemoveGd + jsr deadenemy ;music, etc. + + ldx VisScrn + lda #-1 + sta GdStartBlock-1,x + lda #86 + sta ShadFace + lda #0 + sta OppStrength + lda #-1 + sta ChgOppStr +]rts rts + +* If shad, vanish him + +:shad lda ShadAction + cmp #4 + bne ]rts + jsr LoadShad + jsr VanishChar + jmp SaveShad + +* If skel, change scrn + +:skel lda ShadScrn + jsr getdown + sta ShadScrn + cmp #3 + bne ]RemoveGd + +* Skel lands on scrn 3 + + lda #Splat + jsr addsound + lda #$85 + sta ShadX + lda #1 + sta ShadBlockY + lda #0 + sta ShadFace + lda #-1 + sta ShadLife + jmp updateguard + +*------------------------------- +* +* C U T C H A R +* +* Is character passing o.s.? If so, cut with him to next scrn +* +* Change CharX,Y,BlockY,Scrn to reflect posn on new scrn +* +* Return A = direction of cut, -1 if no cut +* +*------------------------------- +cutchar + lda CharY + + ldx CharAction + cpx #5 + beq :notup + cpx #4 + beq :notup ;In freefall--cut only down + cpx #3 + beq :notup + +* Cut up/down? + + cmp #TopCutEdgePl + bcc :CUTUP + + cmp #TopCutEdgeMi + bcs :CUTUP +:notup + cmp #BotCutEdge + bcs :CUTDOWN + +* Cut left/right? + + ldx CharPosn + cpx #135 + bcc :nocu + cpx #150 + bcc :nocut ;don't cut L/R on climbup +:nocu cpx #110 + bcc :nosu + cpx #120 + bcc :nocut ;or on standup +:nosu cpx #150 + bcc :nost + cpx #163 + bcc :nocut + cpx #166 + bcc :nost + cpx #169 + bcc :nocut ;or on strike/block +:nost lda CharAction + cmp #7 + beq :nocut ;or on turning + + ldx CharFace ;-1=left, 0=right + beq :faceR +;facing left + lda leftej + cmp #LeftCutEdge + bcc :CUTLEFT + beq :CUTLEFT + + cmp #ScrnRight+1 + bcs :CUTRIGHT + bcc :nocut + +:faceR + lda CharScrn + ldx #9 + ldy CharBlockY + jsr rdblock + + cmp #panelwif + beq :nocutr + cmp #panelwof + beq :nocutr ;don't cut R if a panel blocks view + + lda rightej + cmp #RightCutEdge + bcs :CUTRIGHT + +:nocutr lda rightej + cmp #ScrnLeft-1 + bcc :CUTLEFT + beq :CUTLEFT + +:nocut lda #-1 + rts + +:CUTLEFT jsr mirrmusic + jsr milestone3 + lda #0 + bpl :cut + +:CUTRIGHT jsr stealsword + jsr jaffmusic + lda #1 + bpl :cut + +:CUTUP lda #2 + bpl :cut + +* Level 6 ("Plunge"): Kid falls off screen 1 into next level + +:CUTDOWN + jsr infinity + + lda level + cmp #6 + bne :no6 + lda CharScrn + cmp #1 + beq :nocut +:no6 + lda #3 +:cut pha + jsr cut + pla +]rts rts + +*------------------------------- +* Level 12--fall off into infinity +*------------------------------- +infinity rts + +*------------------------------- +* Passed Level 3 milestone? +*------------------------------- +milestone3 + lda level + cmp #3 + bne ]rts + lda #7 ;scrn to R of gate +]mcheck cmp CharScrn + bne ]rts + lda #1 + sta milestone + lda MaxKidStr + sta origstrength + rts + +*------------------------------- +* Level 12: Shadow steals sword +*------------------------------- +stealsword + lda level + cmp #12 + bne ]rts + lda CharScrn + cmp #18 ;scrn below swordscrn + bne ]rts + lda #swordscrn + ldx #swordx + ldy #swordy + jsr rdblock + lda #floor + sta (BlueType),y + rts + +*------------------------------- +* Level 13: Play Jaffar's Theme +*------------------------------- +jaffmusic + lda level + cmp #13 + bne ]rts + lda exitopen + bne ]rts + lda CharScrn + cmp #3 + bne ]rts + lda #s_Jaffar + ldx #25 + jmp cuesong + +*------------------------------- +* Level 4 ("Mirror"): Play danger theme for mirror +*------------------------------- +mirrmusic + lda exitopen + beq :no4 + cmp #77 + beq :no4 + lda level + cmp #4 + bne :no4 + lda CharBlockY + cmp #miry + bne :no4 + lda CharScrn + cmp #11 ;scrn to R of mirscrn + bne :no4 + lda #s_Danger + ldx #50 + jsr cuesong + lda #77 + sta exitopen ;so we don't repeat theme +:no4 +]rts rts + +*------------------------------- +* +* C U T +* +* Move char from CharScrn to adjacent screen +* +* In: A = cut dir: 0 = left, 1 = right, 2 = up, 3 = down +* +*------------------------------- +CUT + cmp #3 + beq Cdown + cmp #1 + beq Cright + cmp #2 + beq Cup + +Cleft + lda CharScrn + jsr getleft ;get new screen # + sta CharScrn + + lda #140 + clc + adc CharX + sta CharX + + ldx #1 ;new FromDir + rts + +Cright + lda CharScrn + jsr getright + sta CharScrn + + lda CharX + sec + sbc #140 + sta CharX + + ldx #0 + rts + +Cup + lda CharScrn + jsr getup + sta CharScrn + + lda CharBlockY + clc + adc #3 + sta CharBlockY + + lda CharY + clc + adc #189 + sta CharY + + ldx #3 + rts + +Cdown + lda CharScrn + jsr getdown + sta CharScrn + + lda CharBlockY + sec + sbc #3 + sta CharBlockY + + lda CharY + sec + sbc #189 + sta CharY + + ldx #2 +]rts rts + +*------------------------------- +* +* A D D G U A R D +* +* On cut to new screen--if guard is there, bring him to life +* Also handles hard-wired shadowman appearances +* +* In: VisScrn +* +*------------------------------- +ADDGUARD + lda #0 + sta offguard + +* Level 12 + + lda level + cmp #12 + bne :not12 + lda exitopen ;set when shadow drops + bne ]rts + lda mergetimer + bne :1 ;shadow has been reabsorbed + lda VisScrn + cmp #swordscrn +:1 bne ]rts + sta CharScrn + + ldx #swordx + ldy #swordy + jsr rdblock + cmp #sword + beq ]rts ;sword is still there + lda #0 + sta shadowaction + lda #1 + sta exitopen + lda #shadpos12 + ldx #>shadpos12 + jmp csps + +* Level 6 (Plunge) + +:not12 + lda level + cmp #6 ;plunge + bne :not6 + + lda VisScrn + sta CharScrn + cmp #1 + bne AddNormalGd + + lda exitopen + cmp #77 + beq :norepeat + lda #s_Danger + ldx #50 + jsr cuesong + lda #77 + sta exitopen +:norepeat + lda #shadpos6a + ldx #>shadpos6a + jmp csps + +* Level 5 (Thief) + +:not6 lda level + cmp #5 ;thief + bne :not5 + + lda VisScrn + sta CharScrn + cmp #flaskscrn + bne AddNormalGd + + ldx #flaskx + ldy #flasky + jsr rdblock + cmp #flask + bne ]rts ;potion is gone + + lda #shadpos5 + ldx #>shadpos5 + jmp csps +]rts rts +:not5 + +*------------------------------- +AddNormalGd + ldx VisScrn + lda GdStartBlock-1,x + cmp #30 + bcs ]rts ;no guard on this scrn + +* Bring guard to life (or death) + + stx CharScrn + + jsr unindex ;return A = blockx, X = blocky + stx CharBlockY + + lda FloorY+1,x + sta CharY + + ldx VisScrn + lda GdStartX-1,x + sta CharX + jsr getblockxp + sta CharBlockX + + ldx VisScrn + lda GdStartFace-1,x + sta CharFace + + lda level + cmp #3 + bne :3 + + lda #4 ;skel + bne :4 +:3 lda #2 ;guard +:4 sta CharID + + lda GdStartSeqH-1,x + bne :1 ;0 is code for fresh start + + lda CharID + cmp #4 + bne :5 + lda #2 + sta CharSword + lda #landengarde ;skel (ready) + bne :6 +:5 lda #0 + sta CharSword + lda #alertstand ;guard +:6 jsr jumpseq + jmp :2 + +:1 sta CharSeq+1 + lda GdStartSeqL-1,x + sta CharSeq + +:2 jsr animchar + + lda CharPosn + cmp #185 ;killed + beq :dead + cmp #177 ;impaled + beq :dead + cmp #178 ;halved + beq :dead + +* Live guard + + lda #-1 + sta CharLife + + lda #0 + sta alertguard + sta refract + sta justblocked + + jsr getgdstrength + jmp :cont + +* Dead guard + +:dead lda #1 + sta CharLife + lda #0 + sta OppStrength + +* Continue + +:cont lda #0 + sta CharXVel + sta CharYVel + lda #1 + sta CharAction + + ldx VisScrn + lda GdStartProg-1,x + cmp #numprogs + bcc :ok + lda #3 ;default +:ok sta guardprog + + ldx level + lda basiccolor,x + ldx guardprog + eor specialcolor,x ;0 = normal, 1 = special + sta GuardColor ;0 = blue, 1 = red + + jmp SaveShad ;save ShadVars + +*------------------------------- +* Get guard fighting strength +*------------------------------- +getgdstrength + ldx level + lda basicstrength,x + ldx guardprog + clc + adc extrastrength,x + sta MaxOppStr + sta OppStrength +]rts rts + +*------------------------------- + lst + ds 1 + usr $a9,17,$800,*-org + lst off diff --git a/01 POP Source/Source/BGDATA.S b/01 POP Source/Source/BGDATA.S index e1844cd..6b18035 100755 --- a/01 POP Source/Source/BGDATA.S +++ b/01 POP Source/Source/BGDATA.S @@ -1 +1,198 @@ -* bgdata tr on *------------------------------- * Indexed by PIECE ID#: space = 0 floor = 1 spikes = 2 posts = 3 gate = 4 dpressplate = 5 ;down pressplate = 6 ;up panelwif = 7 ;w/floor pillarbottom = 8 pillartop = 9 flask = 10 loose = 11 panelwof = 12 ;w/o floor mirror = 13 rubble = 14 upressplate = 15 exit = 16 exit2 = 17 slicer = 18 torch = 19 block = 20 bones = 21 sword = 22 window = 23 window2 = 24 archbot = 25 archtop1 = 26 archtop2 = 27 archtop3 = 28 archtop4 = 29 *------------------------------- * A & B sections have l.l. of (X = BlockLeft, Y = BlockBot-3) * C & D sections have l.l. of (X = BlockLeft, Y = BlockBot) * All x & y offsets are relative to these values * (Front pieces are relative to A) *------------------------------- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 * 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 maska hex 00,03,03,03,03,03,03,03,03,00,03,03,00,03,03,03 hex 03,00,00,03,00,03,00,03,00,03,00,00,00,00 piecea hex 00,01,05,07,0a,01,01,0a,10,00,01,00,00,14,20,4b hex 01,00,00,01,00,97,00,01,00,a7,a9,aa,ac,ad pieceay hex 00,00,00,00,00,01,00,00,00,00,00,00,00,00,00,00 dfb 00,00,00,00,00,00,00,00,00,00,00,-4,-4,-4 maskb hex 00,04,04,04,04,04,04,00,04,00,04,00,00,04,04,04 hex 00,04,04,04,04,04,04,00,04,04,00,00,00,00 pieceb hex 00,02,06,08,0b,1b,02,9e,1a,1c,02,00,9e,4a,21,1b hex 4d,4e,02,51,84,98,02,91,92,02,00,00,00,00 pieceby dfb 00,00,00,00,00,01,00,03,00,03,00,00,03,00,00,-1 dfb 00,00,00,-1,02,00,00,00,00,00,00,00,00,00 bstripe hex 00,47,47,00,00,47,47,00,00,00,47,47,00,00,47,47 hex 00,00,47,00,00,00,47,00,00,47,00,00,00,00 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 * 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 piecec hex 00,00,00,09,0c,00,00,9f,00,1d,00,00,9f,00,00,00 hex 4f,50,00,00,85,00,00,93,94,00,00,00,00,00 pieced hex 00,15,15,15,15,18,19,16,15,00,15,00,17,15,2e,4c hex 15,15,15,15,86,15,15,15,15,15,ab,00,00,00 fronti hex 00,00,00,45,46,00,00,46,48,49,87,00,46,0f,13,00 hex 00,00,00,00,83,00,00,00,00,a8,00,ae,ae,ae fronty dfb 00,00,00,-1,00,00,00,00,-1,03,-3,00,00,-1,00,00 dfb 00,00,00,00,00,00,00,00,00,-1,0,-36,-36,-36 frontx hex 00,00,00,01,03,00,00,03,01,01,02,00,03,01,00,00 hex 00,00,00,00,00,00,00,00,00,01,00,00,00,00 *------------------------------- * special pieces gatebotSTA = $43 gatebotORA = $44 gateB1 = $37 gatecmask = $0d gate8c hex 2f,30,31,32,33,34,35,36 gate8b hex 3e,3d,3c,3b,3a,39,38,37 *------------------------------- * Climbup masking CUmask = $11 CUpiece = $12 CUpost = $0e *------------------------------- * Exit stairs = $6b door = $6c doormask = $6d toprepair = $6e archtop3sp = $a1 *------------------------------- * Spike animation frames * 0 1 2 3 4 5 6 7 8 9 10 11 spikea hex 00,22,24,26,28,2a,28,24,22,00 spikeb hex 00,23,25,27,29,2b,29,25,23,00 spikeExt = 5 ; spikeRet = 9 ;must match MOVEDATA *------------------------------- * Slicer animation frames * 0 1 2 3 4 5 6 7 8 9 10 11 slicerseq dfb 04,03,01,02,05,04,04 slicerExt = 2 slicerRet = 6 ;must match MOVEDATA slicertop hex 00,58,5a,5c,5e slicerbot hex 57,59,5b,5d,5f slicerbot2 hex 8e,8f,90,5d,5f ;smeared slicergap dfb 00,38,46,53,55 slicerfrnt hex 65,66,67,68,69 *------------------------------- * Loose floor * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 looseb = $1b loosea hex 01,1e,01,1f,1f,01,01,01,1f,1f,1f looseby dfb 00,01,00,-1,-1,00,00,00,-1,-1,-1 loosed hex 15,2c,15,2d,2d,15,15,15,2d,2d,2d Ffalling = 10 ;1st "falling" frame ;must match MOVEDATA *------------------------------- specialflask = $95 swordgleam1 = $b3 swordgleam0 = $99 *------------------------------- * panels panelb0 = $9e panelc0 = $9f numpans = 3 panelb hex 9e,9a,81 panelc hex 9f,9b,82 archpanel = $a1 *------------------------------- * back wall panels for space & floor numbpans = 3 spaceb hex 00,a3,a5,a6 spaceby dfb 0,-20,-20,0 floorb hex 02,a2,a4,a4 floorby dfb 00,00,00,00 *------------------------------- * solid blocks numblox = 2 blockb hex 84,6f blockc hex 85,85 blockd hex 86,86 blockfr hex 83,83 *------------------------------- * moveparams gmaxval = 47*4 gminval = 0 *------------------------------- eof \ No newline at end of file +* bgdata + tr on +*------------------------------- +* Indexed by PIECE ID#: + +space = 0 +floor = 1 +spikes = 2 +posts = 3 +gate = 4 +dpressplate = 5 ;down +pressplate = 6 ;up +panelwif = 7 ;w/floor +pillarbottom = 8 +pillartop = 9 +flask = 10 +loose = 11 +panelwof = 12 ;w/o floor +mirror = 13 +rubble = 14 +upressplate = 15 +exit = 16 +exit2 = 17 +slicer = 18 +torch = 19 +block = 20 +bones = 21 +sword = 22 +window = 23 +window2 = 24 +archbot = 25 +archtop1 = 26 +archtop2 = 27 +archtop3 = 28 +archtop4 = 29 + +*------------------------------- +* A & B sections have l.l. of (X = BlockLeft, Y = BlockBot-3) +* C & D sections have l.l. of (X = BlockLeft, Y = BlockBot) +* All x & y offsets are relative to these values +* (Front pieces are relative to A) + +*------------------------------- +* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +* 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + +maska hex 00,03,03,03,03,03,03,03,03,00,03,03,00,03,03,03 + hex 03,00,00,03,00,03,00,03,00,03,00,00,00,00 + +piecea hex 00,01,05,07,0a,01,01,0a,10,00,01,00,00,14,20,4b + hex 01,00,00,01,00,97,00,01,00,a7,a9,aa,ac,ad + +pieceay hex 00,00,00,00,00,01,00,00,00,00,00,00,00,00,00,00 + dfb 00,00,00,00,00,00,00,00,00,00,00,-4,-4,-4 + +maskb hex 00,04,04,04,04,04,04,00,04,00,04,00,00,04,04,04 + hex 00,04,04,04,04,04,04,00,04,04,00,00,00,00 + +pieceb hex 00,02,06,08,0b,1b,02,9e,1a,1c,02,00,9e,4a,21,1b + hex 4d,4e,02,51,84,98,02,91,92,02,00,00,00,00 + +pieceby dfb 00,00,00,00,00,01,00,03,00,03,00,00,03,00,00,-1 + dfb 00,00,00,-1,02,00,00,00,00,00,00,00,00,00 + +bstripe hex 00,47,47,00,00,47,47,00,00,00,47,47,00,00,47,47 + hex 00,00,47,00,00,00,47,00,00,47,00,00,00,00 + +* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +* 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + +piecec hex 00,00,00,09,0c,00,00,9f,00,1d,00,00,9f,00,00,00 + hex 4f,50,00,00,85,00,00,93,94,00,00,00,00,00 + +pieced hex 00,15,15,15,15,18,19,16,15,00,15,00,17,15,2e,4c + hex 15,15,15,15,86,15,15,15,15,15,ab,00,00,00 + +fronti hex 00,00,00,45,46,00,00,46,48,49,87,00,46,0f,13,00 + hex 00,00,00,00,83,00,00,00,00,a8,00,ae,ae,ae + +fronty dfb 00,00,00,-1,00,00,00,00,-1,03,-3,00,00,-1,00,00 + dfb 00,00,00,00,00,00,00,00,00,-1,0,-36,-36,-36 + +frontx hex 00,00,00,01,03,00,00,03,01,01,02,00,03,01,00,00 + hex 00,00,00,00,00,00,00,00,00,01,00,00,00,00 + +*------------------------------- +* special pieces + +gatebotSTA = $43 +gatebotORA = $44 +gateB1 = $37 +gatecmask = $0d + +gate8c hex 2f,30,31,32,33,34,35,36 +gate8b hex 3e,3d,3c,3b,3a,39,38,37 + +*------------------------------- +* Climbup masking + +CUmask = $11 +CUpiece = $12 +CUpost = $0e + +*------------------------------- +* Exit + +stairs = $6b +door = $6c +doormask = $6d +toprepair = $6e + +archtop3sp = $a1 + +*------------------------------- +* Spike animation frames +* 0 1 2 3 4 5 6 7 8 9 10 11 + +spikea hex 00,22,24,26,28,2a,28,24,22,00 +spikeb hex 00,23,25,27,29,2b,29,25,23,00 + +spikeExt = 5 ; +spikeRet = 9 ;must match MOVEDATA + +*------------------------------- +* Slicer animation frames +* 0 1 2 3 4 5 6 7 8 9 10 11 + +slicerseq dfb 04,03,01,02,05,04,04 + +slicerExt = 2 +slicerRet = 6 ;must match MOVEDATA + +slicertop hex 00,58,5a,5c,5e +slicerbot hex 57,59,5b,5d,5f +slicerbot2 hex 8e,8f,90,5d,5f ;smeared +slicergap dfb 00,38,46,53,55 +slicerfrnt hex 65,66,67,68,69 + +*------------------------------- +* Loose floor +* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + +looseb = $1b + +loosea hex 01,1e,01,1f,1f,01,01,01,1f,1f,1f +looseby dfb 00,01,00,-1,-1,00,00,00,-1,-1,-1 +loosed hex 15,2c,15,2d,2d,15,15,15,2d,2d,2d + +Ffalling = 10 ;1st "falling" frame +;must match MOVEDATA + +*------------------------------- +specialflask = $95 + +swordgleam1 = $b3 +swordgleam0 = $99 + +*------------------------------- +* panels + +panelb0 = $9e +panelc0 = $9f +numpans = 3 + +panelb hex 9e,9a,81 +panelc hex 9f,9b,82 + +archpanel = $a1 + +*------------------------------- +* back wall panels for space & floor + +numbpans = 3 + +spaceb hex 00,a3,a5,a6 +spaceby dfb 0,-20,-20,0 + +floorb hex 02,a2,a4,a4 +floorby dfb 00,00,00,00 + +*------------------------------- +* solid blocks + +numblox = 2 + +blockb hex 84,6f +blockc hex 85,85 +blockd hex 86,86 +blockfr hex 83,83 + +*------------------------------- +* moveparams + +gmaxval = 47*4 +gminval = 0 + +*------------------------------- +eof diff --git a/01 POP Source/Source/BOOT.S b/01 POP Source/Source/BOOT.S index d838e20..e8c5fcf 100755 --- a/01 POP Source/Source/BOOT.S +++ b/01 POP Source/Source/BOOT.S @@ -1 +1,234 @@ -* boot org = $800 lst off *------------------------------- * $800 TS (0,0) boot sector SLOT = $2b sector = $50 text = $fb2f home = $fc58 vtab = $FB5B cout = $FDF0 normal = $fe84 pr0 = $fe93 in0 = $fe89 *------------------------------- org org hex 01 entry lda #$60 sta entry lda #$ff sta $4fb sta $3f3 sta $3f4 sta $c000 ;80store off sta $c002 ;RAMRD main sta $c004 ;RAMWRT main sta $c00c ;80col off sta $c00e ;Altcharset off sta $c081 ;write RAM, read ROM (2nd 4k bank) jsr text jsr home jsr normal jsr pr0 jsr in0 ldx SLOT txa lsr lsr lsr lsr ora #$c0 sta :rdsect+2 lda #$0f sta sector :0 ldy sector lda skewtbl,y sta $3d lda sectaddr,y beq :1 sta $27 :rdsect jsr $005c :1 dec sector bne :0 lda SLOT jmp $900 skewtbl hex 00,0d,0b,09,07,05,03,01 hex 0e,0c,0a,08,06,04,02,0f sectaddr hex 00,09,00,00,00,00,00,00 hex 30,31,32,33,34,00,00,00 *=============================== * boot stage 2 rw18 = $d000 slot = $fd track = $fe lastrack = $ff dum $00 dest ds 2 source ds 2 endsourc ds 2 dend *------------------------------- ds $900-* stage2 stx slot jsr check128k ;check for 128K memory jsr moverw18 ;& move RW18 to D000 lda #0 sta lastrack sta $3f3 sta $3f4 ;zero reset vector jsr rw18 hex 07,a9 ;Bbund ID byte jsr rw18 hex 00,01,00 ;drive 1 on jsr rw18 ;seek track 1 hex 02,00,01 * load & run stage 3 boot * from drive 1 jsr rw18 hex c3,ee jmp $ee00 *------------------------------------------------- * Check for AUX memory routine CHECKER lda #$EE sta $C005 sta $C003 sta $0800 lda $0C00 cmp #$EE bne :0 asl $0C00 lda $0800 cmp $0C00 beq :1 :0 clc :1 sta $C004 sta $C002 rts CHECKEND = *-CHECKER *------------------------------------------------- * * Check to make sure //c or //e * with 128k * *------------------------------- check128k sta $c081 lda $FBB3 ;Apple // family ID byte cmp #6 bne NOT128K ;Must be e/c/GS bit $C017 bmi NOT128K ldx #CHECKEND :0 lda CHECKER,X sta $180,X dex bpl :0 jsr $180 bcs NOT128K rts *------------------------------- * Turn off drive and display message NOT128K ldx SLOT lda $C088,X jsr text jsr home lda #8 jsr vtab ldy #0 :0 lda MEMTEXT,Y beq * jsr cout cmp #$8D bne :1 lda #4 sta $24 :1 iny bne :0 MEMTEXT hex 8D asc "REQUIRES A //C OR //E WITH 128K" hex 00 *------------------------------- * Move RW18 * d0 < 30.40 *------------------------------- moverw18 bit $c08b bit $c08b ;rd/wrt RAM, 1st 4k bank lda #$d0 ldx #$30 ldy #$40 * 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 *------------------------------- sav boot \ No newline at end of file +* boot +org = $800 + lst off +*------------------------------- +* $800 TS (0,0) boot sector + +SLOT = $2b +sector = $50 + +text = $fb2f +home = $fc58 +vtab = $FB5B +cout = $FDF0 +normal = $fe84 +pr0 = $fe93 +in0 = $fe89 + +*------------------------------- + org org + + hex 01 + +entry lda #$60 + sta entry + + lda #$ff + sta $4fb + sta $3f3 + sta $3f4 + sta $c000 ;80store off + sta $c002 ;RAMRD main + sta $c004 ;RAMWRT main + sta $c00c ;80col off + sta $c00e ;Altcharset off + sta $c081 ;write RAM, read ROM (2nd 4k bank) + jsr text + jsr home + jsr normal + jsr pr0 + jsr in0 + + ldx SLOT + txa + lsr + lsr + lsr + lsr + ora #$c0 + sta :rdsect+2 + lda #$0f + sta sector + +:0 ldy sector + lda skewtbl,y + sta $3d + lda sectaddr,y + beq :1 + sta $27 +:rdsect jsr $005c +:1 dec sector + bne :0 + + lda SLOT + jmp $900 + +skewtbl hex 00,0d,0b,09,07,05,03,01 + hex 0e,0c,0a,08,06,04,02,0f + +sectaddr hex 00,09,00,00,00,00,00,00 + hex 30,31,32,33,34,00,00,00 + +*=============================== +* boot stage 2 + +rw18 = $d000 + +slot = $fd +track = $fe +lastrack = $ff + + dum $00 + +dest ds 2 +source ds 2 +endsourc ds 2 + + dend +*------------------------------- + ds $900-* + +stage2 stx slot + + jsr check128k ;check for 128K memory + + jsr moverw18 ;& move RW18 to D000 + + lda #0 + sta lastrack + sta $3f3 + sta $3f4 ;zero reset vector + + jsr rw18 + hex 07,a9 ;Bbund ID byte + + jsr rw18 + hex 00,01,00 ;drive 1 on + + jsr rw18 ;seek track 1 + hex 02,00,01 + +* load & run stage 3 boot +* from drive 1 + + jsr rw18 + hex c3,ee + + jmp $ee00 + +*------------------------------------------------- +* Check for AUX memory routine + +CHECKER lda #$EE + sta $C005 + sta $C003 + sta $0800 + lda $0C00 + cmp #$EE + bne :0 + asl $0C00 + lda $0800 + cmp $0C00 + beq :1 +:0 clc +:1 sta $C004 + sta $C002 + rts + +CHECKEND = *-CHECKER + +*------------------------------------------------- +* +* Check to make sure //c or //e +* with 128k +* +*------------------------------- +check128k + sta $c081 + + lda $FBB3 ;Apple // family ID byte + cmp #6 + bne NOT128K ;Must be e/c/GS + + bit $C017 + bmi NOT128K + + ldx #CHECKEND +:0 lda CHECKER,X + sta $180,X + dex + bpl :0 + + jsr $180 + bcs NOT128K + + rts + +*------------------------------- +* Turn off drive and display message + +NOT128K ldx SLOT + lda $C088,X + + jsr text + jsr home + lda #8 + jsr vtab + + ldy #0 +:0 lda MEMTEXT,Y + beq * + jsr cout + cmp #$8D + bne :1 + lda #4 + sta $24 +:1 iny + bne :0 + +MEMTEXT hex 8D + asc "REQUIRES A //C OR //E WITH 128K" + hex 00 + +*------------------------------- +* Move RW18 +* d0 < 30.40 +*------------------------------- +moverw18 + bit $c08b + bit $c08b ;rd/wrt RAM, 1st 4k bank + + lda #$d0 + ldx #$30 + ldy #$40 + +* 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 + +*------------------------------- + sav boot diff --git a/01 POP Source/Source/COLL.S b/01 POP Source/Source/COLL.S index 0d165f6..4af56ae 100755 --- a/01 POP Source/Source/COLL.S +++ b/01 POP Source/Source/COLL.S @@ -1 +1,1515 @@ -* coll org = $4500 tr on lst off *------------------------------- * * PRINCE OF PERSIA * Copyright 1989 Jordan Mechner * *------------------------------- org org jmp CHECKBARR jmp COLLISIONS jmp GETFWDDIST jmp CHECKCOLL jmp ANIMCHAR jmp CHECKSLICE jmp CHECKSLICE2 jmp markmeters ;temp jmp CHECKGATE jmp firstguard ;temp jmp ENEMYCOLL *------------------------------- lst put eq lst put gameeq lst put seqdata lst put soundnames lst put movedata lst off dum $f0 ztemp ds 1 CollFace ds 1 tempobjid ds 1 tempstate ds 1 dend *------------------------------- * Distance in pixels from either edge of block to barrier * BarL + BarR + BarWidth == 14 * * Indexed by barrier code: * 0 = clear, 1 = panel/gate, 2 = flask, 3 = mirror/slicer * 4 = block BarL db 0,12,2,0,0 BarR db 0,0,9,11,0 *------------------------------- DeathVelocity = 33 OofVelocity = 22 gatemargin = 6 ;higher = more generous ]rts rts *------------------------------- * * C H E C K B A R R I E R * * Check for collisions with vertical barriers * *------------------------------- CHECKBARR lda #-1 ;"no-collision" flag sta collideL sta collideR * Check for situations where character is temporarily * "collision-proof" lda CharAction cmp #7 ;turning? beq ]rts * Initialize CD/SN buffers * (Copy "lastframe" data from "thisframe", "above", or "below"; * init "thisframe" with FF) lda CharBlockY sta BlockYthis jsr initCDbufs lda BlockYthis sta BlockYlast * Get beginning & end of range lda CDRightEj jsr getblockxp clc adc #2 cmp #11 bcc :ok lda #11 ;Last (rightmost) block in range +1 :ok sta endrange lda CDLeftEj jsr getblockxp tax dex ;First (leftmost) block in range stx begrange * Get CD & SN data for every block in range [begrange..endrange] * on this level (BlockYthis) and on levels below & above * This level... lda BlockYthis sta blocky lda #SNthisframe ldx #CDthisframe jsr getCData * Level below... lda BlockYthis clc adc #1 sta blocky lda #SNbelow ldx #CDbelow jsr getCData * ...and level above lda BlockYthis sec sbc #1 sta blocky lda #SNabove ldx #CDabove jsr getCData * Got new data... now compare thisframe with lastframe * If a nybble has changed from 0 to 1, we have a collision. ldx #9 :loop2 lda SNthisframe,x bmi :no ;ff = no data for this frame cmp SNlastframe,x bne :no ;no corresponding data for last frame lda CDlastframe,x and #$0f ;low nybble first (L edge of barr) bne :noL lda CDthisframe,x and #$0f beq :noL stx collideL ;We have collision w/ L edge ;x = block # (0-9) :noL lda CDlastframe,x and #$f0 ;hi nybble (R edge of barr) bne :noR lda CDthisframe,x and #$f0 beq :noR stx collideR ;collision w/ R edge :noR :no dex bpl :loop2 ldx collideL ldy collideR ]rts rts *------------------------------- * * G E T C D A T A * * Get "thisframe" data for specified blocky * *------------------------------- getCData sta :smodSN+1 stx :smodCD+1 lda begrange jsr getblockej ;left edge of block clc adc #angle ;perspective sta blockedge ldx begrange :loop stx bufindex * First compare L edge of barr with R edge of char lda CharScrn ldx bufindex ldy blocky jsr getleftbar ;Get left edge of barrier cmp CDRightEj bcc :RofL ;= means L of L :LofL lda #0 beq :cont1 :RofL lda #$f :cont1 sta ztemp * Now compare R edge of barr with L edge of char lda CharScrn ldx bufindex ldy blocky jsr getrightbar ;Get right edge of barrier cmp CDLeftEj bcc :RofR beq :RofR ;= means R of R :LofR lda #$f0 bne :cont2 :RofR lda #0 :cont2 ora ztemp ldx tempblockx ;guaranteed 0-9 by rdblock :smodCD sta CDthisframe,x lda tempscrn :smodSN sta SNthisframe,x ;screen # lda blockedge clc adc #14 sta blockedge ldx bufindex inx cpx endrange bne :loop ]rts rts *------------------------------- * * I N I T C D B U F S * * Initialize SN and CD buffers * (Take "lastframe" data from "thisframe", "above", or "below"; * init "thisframe" with FF) * *------------------------------- initCDbufs lda BlockYthis cmp BlockYlast ;same BlockY as last frame? beq :usethis ;yes--copy data from "thisframe" clc adc #3 cmp BlockYlast beq :usethis sec sbc #6 cmp BlockYlast beq :usethis * BlockY has changed--copy data from "above" or "below" lda BlockYthis clc adc #1 cmp BlockYlast beq :useabove sec sbc #3 cmp BlockYlast beq :useabove :usebelow lda #SNbelow ldx #CDbelow jmp :cont :useabove lda #SNabove ldx #CDabove jmp :cont :usethis lda #SNthisframe ldx #CDthisframe :cont sta :smodSN+1 stx :smodCD+1 * Copy contents of appropriate SN & CD buffers (thisframe, * below, or above) into lastframe buffers... * and initialize SN buffers with $ff ldx #9 :zloop :smodSN lda SNbelow,x sta SNlastframe,x :smodCD lda CDbelow,x sta CDlastframe,x lda #$ff sta SNthisframe,x sta SNabove,x sta SNbelow,x dex bpl :zloop ]rts rts *------------------------------- * * G E T L E F T B A R * * Get X-coord of left edge of barrier * * In: X/Y/A = blockx/blocky/scrn * blockedge * * Out: A = screen X-coord (140) * Return A = 255 if this block is no barrier * *------------------------------- getleftbar jsr rdblock ;get block ID jsr cmpbarr ;return A = barrier code # beq :clear ;or -1 if clear tay lda blockedge clc adc BarL,y ;barr dist from L edge of block sec rts :clear lda #255 clc rts *------------------------------- * * G E T R I G H T B A R * * Get right edge of barrier, 0 if clear * *------------------------------- getrightbar jsr rdblock jsr cmpbarr beq :clear tay lda blockedge clc adc #13 sec sbc BarR,y ;barr dist from R edge of block sec rts :clear lda #0 clc ]rts rts *------------------------------- * * C O L L I S I O N S * * If a collision was detected, act on it * * In: collideL/R: - if no coll, 0-9 refers to block in * which collision occurred * * (CollideL is collision with LEFT EDGE of barrier * CollideR is collision with RIGHT EDGE of barrier) * *------------------------------- COLLISIONS lda AMtimer ;antimatter timer beq :cont lda $c030 dec AMtimer rts :cont * Check for situations where we let character * pass thru barrier (e.g., climbing up onto ledge) lda CharAction cmp #2 ;hanging? beq ]rts cmp #6 ;hanging? beq ]rts lda CharPosn cmp #135 bcc :cont2 cmp #149 bcc ]rts ;climbing? :cont2 ldx collideL bmi :noL stx collX jmp leftcoll :noL ldx collideR bmi :noR stx collX jmp rightcoll :noR ]rts rts *------------------------------- * * R I G H T C O L L I S I O N * *------------------------------- rightcoll lda CharSword cmp #2 ;if in fighting mode, beq :1 ;waive front-facing requirement lda CharFace bpl ]rts :1 jsr checkcoll1 bcc ]rts lda tempscrn ldx tempblockx ldy tempblocky jsr getrightbar ;edge of barr sec sbc CDLeftEj ;dist to char ldx #0 ;right jmp collide *------------------------------- * * L E F T C O L L I S I O N * *------------------------------- leftcoll lda CharSword cmp #2 beq :1 lda CharFace bne ]rts :1 jsr checkcoll1 bcc ]rts lda tempscrn ldx tempblockx ldy tempblocky jsr getleftbar sec sbc CDRightEj ;- dist to char ldx #-1 ;left jmp collide *------------------------------- * * Call CHECKCOLL for block #X * * In: CD data; X = blockx * *------------------------------- checkcoll1 stx tempblockx lda CharBlockY bpl :2 clc adc #3 bne :1 :2 cmp #3 bcc :1 sec sbc #3 :1 sta tempblocky lda SNthisframe,x sta tempscrn jsr rdblock1 jmp CHECKCOLL *------------------------------- * * C H E C K C O L L * * In: RDBLOCK results (A = objid) * * Out: tempblockx,tempblocky,tempscrn * cs if collision, cc if not * *------------------------------- CHECKCOLL cmp #flask beq :no ;flask is not really a barrier cmp #gate beq :gate cmp #slicer beq :slicer cmp #mirror beq :mirror bne :c1 * You can pass thru mirror from R only if you take a * running jump :mirror lda CharID bne :c1 ;must be kid lda CharPosn cmp #39 bcc :c1 cmp #44 bcs :c1 lda CharFace bpl :c1 jsr smashmirror lda #$ff sta createshad ;set flag clc rts * Is slicer closed? :slicer lda (BlueSpec),y cmp #slicerExt bne :no ;no--pass thru beq :c1 * Is gate low enough to bar you? :gate jsr gatebarr? ;return cc if gate bars you bcc :c1 * no collision--pass thru barrier :no clc rts * Yes, collision--get blockedge & return cs :c1 lda tempblockx jsr getblockej jsr AdjustScrn clc adc #angle sta blockedge :yes sec ]rts rts *------------------------------- * * AdjustScrn * * In: tempscrn, VisScrn * scrnLeft/Right/BelowL/BelowR * A = X-coord on tempscrn * * Out: A = X=coord on VisScrn * *------------------------------- AdjustScrn ldx tempscrn cpx VisScrn beq ]rts cpx scrnLeft beq :osL cpx scrnBelowL beq :osL cpx scrnRight beq :osR cpx scrnBelowR beq :osR rts :osR clc adc #ScrnWidth rts :osL sec sbc #ScrnWidth ]rts rts *------------------------------- * * C O L L I D E * * In: A = distance from barrier to character * X = coll direction (-1 = left, 0 = right) * tempblockx,y,scrn set for collision block * *------------------------------- collide stx CollFace ;temp var ldx CharLife ;dead? bpl ]rts ;yes--let him finish falling (or whatever) ldx CharPosn cpx #177 ;impaled? beq ]rts ;yes--ignore collision clc adc CharX sta CharX * In midair or on the ground? jsr rdblock1 ldx CollFace bpl :faceL cmp #block ;If this block has no floor, beq :2 ;use the one in front of it bne :1 :2 dec tempblockx jmp :3 :faceL cmp #panelwof ;Panelwof is only a problem beq :4 ;when facing L cmp #panelwif beq :4 cmp #block bne :1 :4 inc tempblockx lda tempscrn bne :3 lda tempblockx cmp #10 bne :3 lda CharScrn sta tempscrn lda #0 sta tempblockx ;screen 0 block 10 = CharScrn block 0 :3 jsr rdblock1 :1 jsr cmpspace bne GroundBump *------------------------------- * Bump into barrier w/o floor AirBump lda #-4 jsr addcharx sta CharX lda CharAction cmp #4 ;already falling? bne :3 ;yes--just rebound off wall lda #0 sta CharXVel beq :smackwall :3 lda #bumpfall jsr jumpseq jsr animchar :smackwall BumpSound lda #1 sta alertguard lda #SmackWall jmp addsound *------------------------------- * Bump into barrier w/floor GroundBump ldx CharBlockY lda CharSword cmp #2 beq :skipair ;no airbump if en garde lda FloorY+1,x sec sbc CharY cmp #15 ;constant bcs AirBump :skipair lda FloorY+1,x sta CharY lda CharYVel cmp #OofVelocity bcc :okvel lda #-5 jsr addcharx sta CharX rts ;let checkfloor take care of it :okvel lda #0 sta CharYVel lda CharLife beq :deadbump * Is he en garde? lda CharSword cmp #2 beq :CollideEng ;yes--collide en garde * Should it be a hard or a soft bump? :normal ldx CharPosn ;last frame cpx #24 beq :hard cpx #25 beq :hard ;standjump-->hard cpx #40 bcc :1 cpx #43 bcc :hard ;runjump-->hard :1 cpx #102 bcc :2 cpx #107 bcc :hard ;freefall-->hard :2 :soft lda #bump jsr jumpseq jsr BumpSound ;soft bump sound? jmp animchar :hard lda #hardbump :doit jsr jumpseq jsr animchar jmp BumpSound * dead when he hits the wall :deadbump ]rts rts *------------------------------- * Collide en garde :CollideEng lda CollFace cmp CharFace beq :collback lda #bumpengfwd bne :doit * Char is en garde & trying to back into barrier :collback lda #bumpengback jsr jumpseq jsr animchar ;get new frame lda #1 jsr addcharx sta CharX rts *------------------------------- * * G E T F W D D I S T * * In: Char data * * Out: A = size of "careful step" forward (0-14 pixels) * X = what you're stepping up to * (0 = edge, 1 = barrier, 2 = clear) * RDBLOCK results for that block * *------------------------------- GETFWDDIST * Get edges jsr GetBaseBlock jsr setupchar jsr getedges * If this block contains barrier, get distance jsr getunderft ;read block underfoot sta tempobjid jsr cmpbarr beq :nextb ;This block is clear lda CharBlockX sta tempblockx jsr DBarr ;returns A = dist to barrier tax bpl :tobarr * If next block contains barrier, get distance :nextb jsr getinfront sta tempobjid cmp #panelwof bne :99 ;Panelwof is special case ldx CharFace ;if you're facing R bpl :toEOB :99 jsr cmpbarr beq :nobarr lda infrontx sta tempblockx jsr DBarr tax bpl :tobarr * If next block is dangerous (e.g., empty space) * or sword or potion, step to end of this block :nobarr jsr getinfront ;read block in front sta tempobjid cmp #loose beq :toEOB ;step to end of block cmp #pressplate beq :toEOB1 cmp #sword beq :toEOB1 cmp #flask beq :toEOB1 jsr cmpspace beq :toEOB * All clear--take a full step forward :fullstep lda #11 ;natural step size ldx #2 ;clear bne :done * Step to end of block (no "testfoot") :toEOB1 jsr getdist beq :fullstep ldx #0 beq :done * Step to end of block :toEOB jsr getdist ;returns # pixels to end of block (0-13) ldx #0 ;edge :done ldy tempobjid ]rts rts * Step up to barrier :tobarr cmp #14 bcs :fullstep ldx #1 ;barrier bne :done *------------------------------- * * Get distance to barrier * * In: rdblock results; tempobjid * Must have called setupchar/getedges * Out: A = distance to barrier (- if barr is behind char) * *------------------------------- DBarr lda tempobjid cmp #gate bne :ok ;treat gate as barrier only if down jsr gatebarr? ;returns cs if open bcs :clr :ok lda tempblockx jsr getblockej clc adc #angle sta blockedge ;L edge of this block lda CharFace bmi :checkL * Char facing R -- get distance to barrier :checkR lda tempobjid ;block ID jsr cmpbarr ;return A = barrier code # beq :clr tay lda blockedge clc adc BarL,y sta ztemp ;left edge of barr sec sbc CDRightEj rts ;If -, barr is behind char :clr lda #-1 rts * Char facing L -- get distance to barr :checkL lda tempobjid jsr cmpbarr beq :clr tay lda blockedge clc adc #13 sec sbc BarR,y sta ztemp ;R edge of barr lda CDLeftEj sec sbc ztemp ]rts rts *------------------------------- * * A N I M C H A R * * Get next frame from sequence table; * update char data accordingly. * We're now ready to draw this frame. * *------------------------------- ANIMCHAR :next jsr getseq ;get next byte from seqtab ;& increment CharSeq cmp #chx ;"change x" instruction? bne :no1 jsr getseq ;next byte is delta-x jsr addcharx sta CharX jmp :next *------------------------------- :no1 cmp #chy bne :no2 jsr getseq clc adc CharY sta CharY jmp :next *------------------------------- :no2 cmp #aboutface bne :no3 lda CharFace eor #$ff sta CharFace jmp :next *------------------------------- :no3 cmp #goto bne :no4 :goto jsr getseq ;low byte of address pha jsr getseq ;high byte sta CharSeq+1 pla sta CharSeq jmp :next *------------------------------- :no4 cmp #up bne :no5 dec CharBlockY jsr addslicers jmp :next *------------------------------- :no5 cmp #down bne :no6 inc CharBlockY jsr addslicers jmp :next *------------------------------- :no6 cmp #act bne :no7 jsr getseq sta CharAction jmp :next :no7 cmp #setfall bne :no8 jsr getseq sta CharXVel jsr getseq sta CharYVel jmp :next :no8 cmp #ifwtless bne :no9 lda weightless ;weightless? bne :goto ;yes--branch jsr getseq jsr getseq ;skip 2 bytes jmp :next ;& continue :no9 cmp #die bne :no10 jmp :next :no10 cmp #jaru bne :no11 lda #1 sta jarabove ;jar floorboards above jmp :next :no11 cmp #jard bne :no12 lda #-1 sta jarabove ;jar floorboards below jmp :next *------------------------------- :no12 cmp #tap bne :no13 jsr getseq ;sound # cmp #0 ;0: alert guard beq :0 cmp #1 ;1: footstep bne :1 lda #Footstep :tap jsr addsound :0 lda #1 sta alertguard jmp :next :1 cmp #2 ;2: smack wall bne :2 lda #SmackWall bne :tap :2 jmp :next :no13 cmp #nextlevel bne :no14 jsr GoneUpstairs jmp :next :no14 cmp #effect bne :no15 jsr getseq ;effect # cmp #1 bne :fx0 jsr potioneffect :fx0 jmp :next :no15 *------------------------------- sta CharPosn ;frame # ]rts rts *------------------------------- * Char has gone upstairs * What do we do? *------------------------------- GoneUpstairs lda level cmp #13 beq :ok ;no music for level 13 cmp #4 bne :1 ;mirror level is special :3 lda #s_Shadow bne :2 :1 lda #s_Upstairs :2 ldx #25 jsr cuesong :ok inc NextLevel rts *------------------------------- * * Sliced by slicer? (Does CD buf show char overlapping * with a closed slicer?) * * In: Char data, CD data * *------------------------------- CHECKSLICE lda CharBlockY sta tempblocky ldx #9 :loop stx tempblockx lda CDthisframe,x cmp #$ff ;char overlapping barr? bne :ok ;no * Yes--is it a slicer? lda SNthisframe,x sta tempscrn jsr rdblock1 cmp #slicer bne :ok lda (BlueSpec),y and #$7f cmp #slicerExt ;slicer closed? beq :slice ;yes--slice! * No--keep checking :ok ldx tempblockx dex bpl :loop ]rts rts * Slice! * In: rdblock results for slicer block :slice ]slice lda (BlueSpec),y ora #$80 sta (BlueSpec),y ;set hibit (smear) :cont lda CharPosn cmp #178 ;if already cut in half (e.g. by another slicer), beq ]rts ;leave him alone lda tempblockx jsr getblockej ;edge of slicer block clc adc #7 sta CharX lda #8 jsr addcharx sta CharX ;align char w/slicer ldx CharBlockY inx lda FloorY,x sta CharY ;align char w/floor lda #100 jsr decstr lda #Splat jsr addsound lda #halve jsr jumpseq jmp animchar *------------------------------- * * Sliced by slicer? * * (Use this routine for enemy, who has no CD data) * * In: Char data; GETEDGES results * *------------------------------- CHECKSLICE2 jsr getunderft jsr :slice? ;return cs if sliced bcs ]rts inc tempblockx jsr rdblock1 :slice? cmp #slicer bne :safe lda (BlueSpec),y and #$7f cmp #slicerExt bne :safe ;slicer open lda tempblockx jsr getblockej clc adc #angle sta blockedge lda tempscrn ldx tempblockx ldy tempblocky jsr getleftbar cmp CDRightEj bcs :safe lda tempscrn ldx tempblockx ldy tempblocky jsr getrightbar cmp CDLeftEj bcc :safe beq :safe jsr rdblock1 jsr ]slice sec rts :safe clc ]rts rts *------------------------------- * * Special situation: If char is standing directly under closing * gate, it knocks him aside when it shuts. * * In: Char data, CD data * *------------------------------- CHECKGATE lda CharAction cmp #7 ;turning beq :1 lda CharPosn cmp #15 ;standing? beq :1 cmp #108 bcc ]rts cmp #111 ;crouching? bcs ]rts :1 jsr getunderft cmp #gate beq :check dec tempblockx jsr rdblock1 cmp #gate bne ]rts :check ldx tempblockx lda CDthisframe,x and CDlastframe,x cmp #$ff bne ]rts jsr gatebarr? bcs ]rts jsr BumpSound * bump him left or right? lda tempblockx sta collX jsr getunderft lda tempblockx cmp collX beq :left bcs :right :left lda #-5 bne :10 :right lda #5 :10 clc adc CharX sta CharX ]rts rts *------------------------------- * * Return cc if gate bars you, cs if clear * *------------------------------- gatebarr? lda (BlueSpec),y lsr lsr clc adc #gatemargin cmp imheight ]rts rts *------------------------------- * * Limited collision detection for enemies * (backing into wall or gate while fighting) * *------------------------------- ENEMYCOLL lda AMtimer ;antimatter timer bne ]rts lda CharAction cmp #1 bne ]rts ;must be on ground lda CharLife bpl ]rts ;& alive lda CharSword cmp #2 bcc ]rts ;& en garde jsr getunderft cmp #block beq :collide cmp #panelwif beq :collide cmp #gate bne :1 jsr gatebarr? bcc :collide * If facing R, check block behind too :1 lda CharFace bmi ]rts dec tempblockx jsr rdblock1 cmp #panelwif beq :collide cmp #gate bne ]rts jsr gatebarr? bcc :collide ]rts rts * Char is en garde & trying to back into barrier * Put him right at edge :collide jsr setupchar jsr getedges ;get edges lda tempscrn ldx tempblockx ldy tempblocky jsr rdblock sta tempobjid jsr checkcoll bcc ]rts jsr DBarr2 ;get A = dist to barrier tax bpl ]rts eor #$ff clc adc #1 jsr addcharx sta CharX lda #bumpengback jsr jumpseq jsr animchar ;get new frame jmp rereadblocks *------------------------------- * * Special version of DBarr for enemy collisions * * In: checkcoll results; tempobjid * Must have called setupchar/getedges * Out: A = distance to barrier (- if barr is behind char) * *------------------------------- DBarr2 lda CharFace bpl :checkL ;Note: reversed from DBarr * Char's back facing R -- get distance to barrier :checkR lda tempobjid ;block ID jsr cmpbarr ;return A = barrier code # beq :clr tay lda blockedge clc adc BarL,y sta ztemp ;left edge of barr sec sbc CDRightEj rts ;If -, barr is behind char :clr lda #-1 rts * Char facing L -- get distance to barr :checkL lda tempobjid jsr cmpbarr beq :clr tay lda blockedge clc adc #13 sec sbc BarR,y sta ztemp ;R edge of barr lda CDLeftEj sec sbc ztemp ]rts rts *------------------------------- lst ds 1 usr $a9,16,$b00,*-org lst off \ No newline at end of file +* coll +org = $4500 + tr on + lst off +*------------------------------- +* +* PRINCE OF PERSIA +* Copyright 1989 Jordan Mechner +* +*------------------------------- + org org + + jmp CHECKBARR + jmp COLLISIONS + jmp GETFWDDIST + jmp CHECKCOLL + jmp ANIMCHAR + + jmp CHECKSLICE + jmp CHECKSLICE2 + jmp markmeters ;temp + jmp CHECKGATE + jmp firstguard ;temp + + jmp ENEMYCOLL + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put seqdata + lst + put soundnames + lst + put movedata + lst off + + dum $f0 +ztemp ds 1 +CollFace ds 1 +tempobjid ds 1 +tempstate ds 1 + dend + +*------------------------------- +* Distance in pixels from either edge of block to barrier +* BarL + BarR + BarWidth == 14 +* +* Indexed by barrier code: +* 0 = clear, 1 = panel/gate, 2 = flask, 3 = mirror/slicer +* 4 = block + +BarL db 0,12,2,0,0 +BarR db 0,0,9,11,0 + +*------------------------------- +DeathVelocity = 33 +OofVelocity = 22 + +gatemargin = 6 ;higher = more generous + +]rts rts +*------------------------------- +* +* C H E C K B A R R I E R +* +* Check for collisions with vertical barriers +* +*------------------------------- +CHECKBARR + lda #-1 ;"no-collision" flag + sta collideL + sta collideR + +* Check for situations where character is temporarily +* "collision-proof" + + lda CharAction + cmp #7 ;turning? + beq ]rts + +* Initialize CD/SN buffers +* (Copy "lastframe" data from "thisframe", "above", or "below"; +* init "thisframe" with FF) + + lda CharBlockY + sta BlockYthis + + jsr initCDbufs + + lda BlockYthis + sta BlockYlast + +* Get beginning & end of range + + lda CDRightEj + jsr getblockxp + clc + adc #2 + cmp #11 + bcc :ok + lda #11 + ;Last (rightmost) block in range +1 +:ok sta endrange + + lda CDLeftEj + jsr getblockxp + tax + dex ;First (leftmost) block in range + stx begrange + +* Get CD & SN data for every block in range [begrange..endrange] +* on this level (BlockYthis) and on levels below & above + +* This level... + + lda BlockYthis + sta blocky + + lda #SNthisframe + ldx #CDthisframe + jsr getCData + +* Level below... + + lda BlockYthis + clc + adc #1 + sta blocky + + lda #SNbelow + ldx #CDbelow + jsr getCData + +* ...and level above + + lda BlockYthis + sec + sbc #1 + sta blocky + + lda #SNabove + ldx #CDabove + jsr getCData + +* Got new data... now compare thisframe with lastframe +* If a nybble has changed from 0 to 1, we have a collision. + + ldx #9 +:loop2 + lda SNthisframe,x + bmi :no ;ff = no data for this frame + cmp SNlastframe,x + bne :no ;no corresponding data for last frame + + lda CDlastframe,x + and #$0f ;low nybble first (L edge of barr) + bne :noL + + lda CDthisframe,x + and #$0f + beq :noL + + stx collideL ;We have collision w/ L edge +;x = block # (0-9) + +:noL lda CDlastframe,x + and #$f0 ;hi nybble (R edge of barr) + bne :noR + + lda CDthisframe,x + and #$f0 + beq :noR + + stx collideR ;collision w/ R edge +:noR +:no dex + bpl :loop2 + + ldx collideL + ldy collideR + +]rts rts + +*------------------------------- +* +* G E T C D A T A +* +* Get "thisframe" data for specified blocky +* +*------------------------------- +getCData + sta :smodSN+1 + stx :smodCD+1 + + lda begrange + jsr getblockej ;left edge of block + clc + adc #angle ;perspective + sta blockedge + + ldx begrange +:loop stx bufindex + +* First compare L edge of barr with R edge of char + + lda CharScrn + ldx bufindex + ldy blocky + jsr getleftbar ;Get left edge of barrier + + cmp CDRightEj + bcc :RofL + ;= means L of L +:LofL lda #0 + beq :cont1 + +:RofL lda #$f +:cont1 sta ztemp + +* Now compare R edge of barr with L edge of char + + lda CharScrn + ldx bufindex + ldy blocky + jsr getrightbar ;Get right edge of barrier + + cmp CDLeftEj + bcc :RofR + beq :RofR ;= means R of R + +:LofR lda #$f0 + bne :cont2 + +:RofR lda #0 +:cont2 ora ztemp + + ldx tempblockx ;guaranteed 0-9 by rdblock +:smodCD sta CDthisframe,x + + lda tempscrn +:smodSN sta SNthisframe,x ;screen # + + lda blockedge + clc + adc #14 + sta blockedge + + ldx bufindex + inx + cpx endrange + bne :loop + +]rts rts + +*------------------------------- +* +* I N I T C D B U F S +* +* Initialize SN and CD buffers +* (Take "lastframe" data from "thisframe", "above", or "below"; +* init "thisframe" with FF) +* +*------------------------------- +initCDbufs + lda BlockYthis + cmp BlockYlast ;same BlockY as last frame? + beq :usethis ;yes--copy data from "thisframe" + + clc + adc #3 + cmp BlockYlast + beq :usethis + + sec + sbc #6 + cmp BlockYlast + beq :usethis + +* BlockY has changed--copy data from "above" or "below" + + lda BlockYthis + clc + adc #1 + cmp BlockYlast + beq :useabove + sec + sbc #3 + cmp BlockYlast + beq :useabove + +:usebelow + lda #SNbelow + ldx #CDbelow + jmp :cont + +:useabove lda #SNabove + ldx #CDabove + jmp :cont + +:usethis lda #SNthisframe + ldx #CDthisframe + +:cont sta :smodSN+1 + stx :smodCD+1 + +* Copy contents of appropriate SN & CD buffers (thisframe, +* below, or above) into lastframe buffers... +* and initialize SN buffers with $ff + + ldx #9 +:zloop +:smodSN lda SNbelow,x + sta SNlastframe,x + +:smodCD lda CDbelow,x + sta CDlastframe,x + + lda #$ff + sta SNthisframe,x + sta SNabove,x + sta SNbelow,x + + dex + bpl :zloop + +]rts rts + +*------------------------------- +* +* G E T L E F T B A R +* +* Get X-coord of left edge of barrier +* +* In: X/Y/A = blockx/blocky/scrn +* blockedge +* +* Out: A = screen X-coord (140) +* Return A = 255 if this block is no barrier +* +*------------------------------- +getleftbar + jsr rdblock ;get block ID + + jsr cmpbarr ;return A = barrier code # + beq :clear ;or -1 if clear + tay + + lda blockedge + clc + adc BarL,y ;barr dist from L edge of block + sec + rts + +:clear lda #255 + clc + rts + +*------------------------------- +* +* G E T R I G H T B A R +* +* Get right edge of barrier, 0 if clear +* +*------------------------------- +getrightbar + jsr rdblock + + jsr cmpbarr + beq :clear + tay + + lda blockedge + clc + adc #13 + sec + sbc BarR,y ;barr dist from R edge of block + sec + rts + +:clear lda #0 + clc +]rts rts + +*------------------------------- +* +* C O L L I S I O N S +* +* If a collision was detected, act on it +* +* In: collideL/R: - if no coll, 0-9 refers to block in +* which collision occurred +* +* (CollideL is collision with LEFT EDGE of barrier +* CollideR is collision with RIGHT EDGE of barrier) +* +*------------------------------- +COLLISIONS + lda AMtimer ;antimatter timer + beq :cont + lda $c030 + dec AMtimer + rts +:cont + +* Check for situations where we let character +* pass thru barrier (e.g., climbing up onto ledge) + + lda CharAction + cmp #2 ;hanging? + beq ]rts + cmp #6 ;hanging? + beq ]rts + lda CharPosn + cmp #135 + bcc :cont2 + cmp #149 + bcc ]rts ;climbing? + +:cont2 + ldx collideL + bmi :noL + stx collX + jmp leftcoll + +:noL ldx collideR + bmi :noR + stx collX + jmp rightcoll +:noR +]rts rts + +*------------------------------- +* +* R I G H T C O L L I S I O N +* +*------------------------------- +rightcoll + lda CharSword + cmp #2 ;if in fighting mode, + beq :1 ;waive front-facing requirement + + lda CharFace + bpl ]rts +:1 + jsr checkcoll1 + bcc ]rts + + lda tempscrn + ldx tempblockx + ldy tempblocky + + jsr getrightbar ;edge of barr + sec + sbc CDLeftEj ;dist to char + + ldx #0 ;right + jmp collide + +*------------------------------- +* +* L E F T C O L L I S I O N +* +*------------------------------- +leftcoll + lda CharSword + cmp #2 + beq :1 + + lda CharFace + bne ]rts +:1 + jsr checkcoll1 + bcc ]rts + + lda tempscrn + ldx tempblockx + ldy tempblocky + jsr getleftbar + sec + sbc CDRightEj ;- dist to char + + ldx #-1 ;left + jmp collide + +*------------------------------- +* +* Call CHECKCOLL for block #X +* +* In: CD data; X = blockx +* +*------------------------------- +checkcoll1 + stx tempblockx + + lda CharBlockY + bpl :2 + clc + adc #3 + bne :1 + +:2 cmp #3 + bcc :1 + sec + sbc #3 +:1 sta tempblocky + + lda SNthisframe,x + sta tempscrn + + jsr rdblock1 + + jmp CHECKCOLL + +*------------------------------- +* +* C H E C K C O L L +* +* In: RDBLOCK results (A = objid) +* +* Out: tempblockx,tempblocky,tempscrn +* cs if collision, cc if not +* +*------------------------------- +CHECKCOLL + cmp #flask + beq :no ;flask is not really a barrier + + cmp #gate + beq :gate + + cmp #slicer + beq :slicer + + cmp #mirror + beq :mirror + bne :c1 + +* You can pass thru mirror from R only if you take a +* running jump + +:mirror + lda CharID + bne :c1 ;must be kid + lda CharPosn + cmp #39 + bcc :c1 + cmp #44 + bcs :c1 + lda CharFace + bpl :c1 + + jsr smashmirror + lda #$ff + sta createshad ;set flag + + clc + rts + +* Is slicer closed? + +:slicer lda (BlueSpec),y + cmp #slicerExt + bne :no ;no--pass thru + beq :c1 + +* Is gate low enough to bar you? + +:gate jsr gatebarr? ;return cc if gate bars you + bcc :c1 + +* no collision--pass thru barrier + +:no clc + rts + +* Yes, collision--get blockedge & return cs + +:c1 + lda tempblockx + jsr getblockej + jsr AdjustScrn + clc + adc #angle + sta blockedge +:yes sec +]rts rts + +*------------------------------- +* +* AdjustScrn +* +* In: tempscrn, VisScrn +* scrnLeft/Right/BelowL/BelowR +* A = X-coord on tempscrn +* +* Out: A = X=coord on VisScrn +* +*------------------------------- +AdjustScrn + ldx tempscrn + cpx VisScrn + beq ]rts + cpx scrnLeft + beq :osL + cpx scrnBelowL + beq :osL + cpx scrnRight + beq :osR + cpx scrnBelowR + beq :osR + rts +:osR clc + adc #ScrnWidth + rts +:osL sec + sbc #ScrnWidth +]rts rts + +*------------------------------- +* +* C O L L I D E +* +* In: A = distance from barrier to character +* X = coll direction (-1 = left, 0 = right) +* tempblockx,y,scrn set for collision block +* +*------------------------------- +collide + stx CollFace ;temp var + + ldx CharLife ;dead? + bpl ]rts ;yes--let him finish falling (or whatever) + + ldx CharPosn + cpx #177 ;impaled? + beq ]rts ;yes--ignore collision + + clc + adc CharX + sta CharX + +* In midair or on the ground? + + jsr rdblock1 + + ldx CollFace + bpl :faceL + + cmp #block ;If this block has no floor, + beq :2 ;use the one in front of it + bne :1 + +:2 dec tempblockx + jmp :3 + +:faceL cmp #panelwof ;Panelwof is only a problem + beq :4 ;when facing L + cmp #panelwif + beq :4 + cmp #block + bne :1 + +:4 inc tempblockx + lda tempscrn + bne :3 + lda tempblockx + cmp #10 + bne :3 + lda CharScrn + sta tempscrn + lda #0 + sta tempblockx ;screen 0 block 10 = CharScrn block 0 + +:3 jsr rdblock1 + +:1 jsr cmpspace + bne GroundBump + +*------------------------------- +* Bump into barrier w/o floor + +AirBump + lda #-4 + jsr addcharx + sta CharX + + lda CharAction + cmp #4 ;already falling? + bne :3 +;yes--just rebound off wall + lda #0 + sta CharXVel + beq :smackwall + +:3 lda #bumpfall + jsr jumpseq + jsr animchar + +:smackwall + +BumpSound + lda #1 + sta alertguard + lda #SmackWall + jmp addsound + +*------------------------------- +* Bump into barrier w/floor + +GroundBump + ldx CharBlockY + + lda CharSword + cmp #2 + beq :skipair ;no airbump if en garde + + lda FloorY+1,x + sec + sbc CharY + cmp #15 ;constant + bcs AirBump +:skipair + lda FloorY+1,x + sta CharY + + lda CharYVel + cmp #OofVelocity + bcc :okvel + lda #-5 + jsr addcharx + sta CharX + rts ;let checkfloor take care of it + +:okvel lda #0 + sta CharYVel + + lda CharLife + beq :deadbump + +* Is he en garde? + + lda CharSword + cmp #2 + beq :CollideEng ;yes--collide en garde + +* Should it be a hard or a soft bump? + +:normal + ldx CharPosn ;last frame + + cpx #24 + beq :hard + cpx #25 + beq :hard ;standjump-->hard + + cpx #40 + bcc :1 + cpx #43 + bcc :hard ;runjump-->hard + +:1 cpx #102 + bcc :2 + cpx #107 + bcc :hard ;freefall-->hard + +:2 + +:soft lda #bump + jsr jumpseq + jsr BumpSound ;soft bump sound? + jmp animchar + +:hard lda #hardbump +:doit jsr jumpseq + jsr animchar + + jmp BumpSound + +* dead when he hits the wall + +:deadbump +]rts rts + +*------------------------------- +* Collide en garde + +:CollideEng + lda CollFace + cmp CharFace + beq :collback + + lda #bumpengfwd + bne :doit + +* Char is en garde & trying to back into barrier + +:collback + lda #bumpengback + jsr jumpseq + jsr animchar ;get new frame + + lda #1 + jsr addcharx + sta CharX + rts + +*------------------------------- +* +* G E T F W D D I S T +* +* In: Char data +* +* Out: A = size of "careful step" forward (0-14 pixels) +* X = what you're stepping up to +* (0 = edge, 1 = barrier, 2 = clear) +* RDBLOCK results for that block +* +*------------------------------- +GETFWDDIST + +* Get edges + + jsr GetBaseBlock + jsr setupchar + jsr getedges + +* If this block contains barrier, get distance + + jsr getunderft ;read block underfoot + sta tempobjid + + jsr cmpbarr + beq :nextb ;This block is clear + + lda CharBlockX + sta tempblockx + jsr DBarr ;returns A = dist to barrier + tax + bpl :tobarr + +* If next block contains barrier, get distance + +:nextb + jsr getinfront + sta tempobjid + cmp #panelwof + bne :99 ;Panelwof is special case + ldx CharFace ;if you're facing R + bpl :toEOB + +:99 jsr cmpbarr + beq :nobarr + + lda infrontx + sta tempblockx + jsr DBarr + tax + bpl :tobarr + +* If next block is dangerous (e.g., empty space) +* or sword or potion, step to end of this block + +:nobarr + jsr getinfront ;read block in front + sta tempobjid + + cmp #loose + beq :toEOB ;step to end of block + + cmp #pressplate + beq :toEOB1 + + cmp #sword + beq :toEOB1 + cmp #flask + beq :toEOB1 + + jsr cmpspace + beq :toEOB + +* All clear--take a full step forward + +:fullstep lda #11 ;natural step size + + ldx #2 ;clear + bne :done + +* Step to end of block (no "testfoot") + +:toEOB1 jsr getdist + beq :fullstep + ldx #0 + beq :done + +* Step to end of block + +:toEOB jsr getdist ;returns # pixels to end of block (0-13) + + ldx #0 ;edge + +:done ldy tempobjid +]rts rts + +* Step up to barrier + +:tobarr + cmp #14 + bcs :fullstep + + ldx #1 ;barrier + bne :done + +*------------------------------- +* +* Get distance to barrier +* +* In: rdblock results; tempobjid +* Must have called setupchar/getedges +* Out: A = distance to barrier (- if barr is behind char) +* +*------------------------------- +DBarr + lda tempobjid + cmp #gate + bne :ok +;treat gate as barrier only if down + jsr gatebarr? ;returns cs if open + bcs :clr + +:ok lda tempblockx + jsr getblockej + clc + adc #angle + sta blockedge ;L edge of this block + + lda CharFace + bmi :checkL + +* Char facing R -- get distance to barrier + +:checkR + lda tempobjid ;block ID + + jsr cmpbarr ;return A = barrier code # + beq :clr + tay + + lda blockedge + clc + adc BarL,y + sta ztemp ;left edge of barr + + sec + sbc CDRightEj + rts ;If -, barr is behind char + +:clr lda #-1 + rts + +* Char facing L -- get distance to barr + +:checkL + lda tempobjid + + jsr cmpbarr + beq :clr + tay + + lda blockedge + clc + adc #13 + sec + sbc BarR,y + sta ztemp ;R edge of barr + + lda CDLeftEj + sec + sbc ztemp + +]rts rts + +*------------------------------- +* +* A N I M C H A R +* +* Get next frame from sequence table; +* update char data accordingly. +* We're now ready to draw this frame. +* +*------------------------------- +ANIMCHAR + +:next jsr getseq ;get next byte from seqtab + ;& increment CharSeq + + cmp #chx ;"change x" instruction? + bne :no1 + + jsr getseq ;next byte is delta-x + + jsr addcharx + sta CharX + + jmp :next + +*------------------------------- +:no1 cmp #chy + bne :no2 + + jsr getseq + + clc + adc CharY + sta CharY + + jmp :next + +*------------------------------- +:no2 cmp #aboutface + bne :no3 + + lda CharFace + eor #$ff + sta CharFace + + jmp :next + +*------------------------------- +:no3 cmp #goto + bne :no4 + +:goto jsr getseq ;low byte of address + pha + + jsr getseq ;high byte + + sta CharSeq+1 + pla + sta CharSeq + + jmp :next + +*------------------------------- +:no4 cmp #up + bne :no5 + + dec CharBlockY + + jsr addslicers + + jmp :next + +*------------------------------- +:no5 cmp #down + bne :no6 + + inc CharBlockY + + jsr addslicers + + jmp :next + +*------------------------------- +:no6 cmp #act + bne :no7 + + jsr getseq + sta CharAction + + jmp :next + +:no7 cmp #setfall + bne :no8 + + jsr getseq + sta CharXVel + + jsr getseq + sta CharYVel + + jmp :next + +:no8 cmp #ifwtless + bne :no9 + + lda weightless ;weightless? + bne :goto ;yes--branch + + jsr getseq + jsr getseq ;skip 2 bytes + jmp :next ;& continue + +:no9 cmp #die + bne :no10 + jmp :next + +:no10 cmp #jaru + bne :no11 + + lda #1 + sta jarabove ;jar floorboards above + jmp :next + +:no11 cmp #jard + bne :no12 + + lda #-1 + sta jarabove ;jar floorboards below + jmp :next + +*------------------------------- +:no12 cmp #tap + bne :no13 + + jsr getseq ;sound # + cmp #0 ;0: alert guard + beq :0 + + cmp #1 ;1: footstep + bne :1 + lda #Footstep +:tap jsr addsound +:0 lda #1 + sta alertguard + jmp :next + +:1 cmp #2 ;2: smack wall + bne :2 + lda #SmackWall + bne :tap +:2 jmp :next + +:no13 cmp #nextlevel + bne :no14 + + jsr GoneUpstairs + jmp :next + +:no14 cmp #effect + bne :no15 + + jsr getseq ;effect # + cmp #1 + bne :fx0 + + jsr potioneffect +:fx0 jmp :next + +:no15 +*------------------------------- + sta CharPosn ;frame # + +]rts rts + +*------------------------------- +* Char has gone upstairs +* What do we do? +*------------------------------- +GoneUpstairs + lda level + cmp #13 + beq :ok ;no music for level 13 + cmp #4 + bne :1 ;mirror level is special +:3 lda #s_Shadow + bne :2 + +:1 lda #s_Upstairs +:2 ldx #25 + jsr cuesong + +:ok inc NextLevel + rts + +*------------------------------- +* +* Sliced by slicer? (Does CD buf show char overlapping +* with a closed slicer?) +* +* In: Char data, CD data +* +*------------------------------- +CHECKSLICE + lda CharBlockY + sta tempblocky + + ldx #9 + +:loop stx tempblockx + + lda CDthisframe,x + cmp #$ff ;char overlapping barr? + bne :ok ;no + +* Yes--is it a slicer? + + lda SNthisframe,x + sta tempscrn + + jsr rdblock1 + cmp #slicer + bne :ok + + lda (BlueSpec),y + and #$7f + cmp #slicerExt ;slicer closed? + beq :slice ;yes--slice! + +* No--keep checking + +:ok ldx tempblockx + dex + bpl :loop +]rts rts + +* Slice! +* In: rdblock results for slicer block + +:slice +]slice + lda (BlueSpec),y + ora #$80 + sta (BlueSpec),y ;set hibit (smear) + +:cont lda CharPosn + cmp #178 ;if already cut in half (e.g. by another slicer), + beq ]rts ;leave him alone + + lda tempblockx + jsr getblockej ;edge of slicer block + clc + adc #7 + sta CharX + + lda #8 + jsr addcharx + sta CharX ;align char w/slicer + + ldx CharBlockY + inx + lda FloorY,x + sta CharY ;align char w/floor + + lda #100 + jsr decstr + + lda #Splat + jsr addsound + + lda #halve + jsr jumpseq + jmp animchar + +*------------------------------- +* +* Sliced by slicer? +* +* (Use this routine for enemy, who has no CD data) +* +* In: Char data; GETEDGES results +* +*------------------------------- +CHECKSLICE2 + jsr getunderft + jsr :slice? ;return cs if sliced + bcs ]rts + + inc tempblockx + jsr rdblock1 + +:slice? + cmp #slicer + bne :safe + lda (BlueSpec),y + and #$7f + cmp #slicerExt + bne :safe ;slicer open + + lda tempblockx + jsr getblockej + clc + adc #angle + sta blockedge + + lda tempscrn + ldx tempblockx + ldy tempblocky + jsr getleftbar + cmp CDRightEj + bcs :safe + + lda tempscrn + ldx tempblockx + ldy tempblocky + jsr getrightbar + cmp CDLeftEj + bcc :safe + beq :safe + + jsr rdblock1 + jsr ]slice + sec + rts + +:safe clc +]rts rts + +*------------------------------- +* +* Special situation: If char is standing directly under closing +* gate, it knocks him aside when it shuts. +* +* In: Char data, CD data +* +*------------------------------- +CHECKGATE + lda CharAction + cmp #7 ;turning + beq :1 + lda CharPosn + cmp #15 ;standing? + beq :1 + cmp #108 + bcc ]rts + cmp #111 ;crouching? + bcs ]rts +:1 + jsr getunderft + cmp #gate + beq :check + + dec tempblockx + jsr rdblock1 + cmp #gate + bne ]rts +:check + ldx tempblockx + lda CDthisframe,x + and CDlastframe,x + cmp #$ff + bne ]rts + + jsr gatebarr? + bcs ]rts + + jsr BumpSound + +* bump him left or right? + + lda tempblockx + sta collX + jsr getunderft + lda tempblockx + cmp collX + beq :left + bcs :right + +:left lda #-5 + bne :10 +:right lda #5 +:10 clc + adc CharX + sta CharX +]rts rts + +*------------------------------- +* +* Return cc if gate bars you, cs if clear +* +*------------------------------- +gatebarr? + lda (BlueSpec),y + lsr + lsr + clc + adc #gatemargin + cmp imheight +]rts rts + +*------------------------------- +* +* Limited collision detection for enemies +* (backing into wall or gate while fighting) +* +*------------------------------- +ENEMYCOLL + lda AMtimer ;antimatter timer + bne ]rts + + lda CharAction + cmp #1 + bne ]rts ;must be on ground + lda CharLife + bpl ]rts ;& alive + lda CharSword + cmp #2 + bcc ]rts ;& en garde + + jsr getunderft + cmp #block + beq :collide + cmp #panelwif + beq :collide + cmp #gate + bne :1 + jsr gatebarr? + bcc :collide + +* If facing R, check block behind too + +:1 lda CharFace + bmi ]rts + dec tempblockx + jsr rdblock1 + cmp #panelwif + beq :collide + cmp #gate + bne ]rts + jsr gatebarr? + bcc :collide +]rts rts + +* Char is en garde & trying to back into barrier +* Put him right at edge + +:collide + jsr setupchar + jsr getedges ;get edges + + lda tempscrn + ldx tempblockx + ldy tempblocky + jsr rdblock + sta tempobjid + jsr checkcoll + bcc ]rts + + jsr DBarr2 ;get A = dist to barrier + tax + bpl ]rts + eor #$ff + clc + adc #1 + jsr addcharx + sta CharX + + lda #bumpengback + jsr jumpseq + jsr animchar ;get new frame + jmp rereadblocks + +*------------------------------- +* +* Special version of DBarr for enemy collisions +* +* In: checkcoll results; tempobjid +* Must have called setupchar/getedges +* Out: A = distance to barrier (- if barr is behind char) +* +*------------------------------- +DBarr2 + lda CharFace + bpl :checkL ;Note: reversed from DBarr + +* Char's back facing R -- get distance to barrier + +:checkR + lda tempobjid ;block ID + + jsr cmpbarr ;return A = barrier code # + beq :clr + tay + + lda blockedge + clc + adc BarL,y + sta ztemp ;left edge of barr + + sec + sbc CDRightEj + rts ;If -, barr is behind char + +:clr lda #-1 + rts + +* Char facing L -- get distance to barr + +:checkL + lda tempobjid + + jsr cmpbarr + beq :clr + tay + + lda blockedge + clc + adc #13 + sec + sbc BarR,y + sta ztemp ;R edge of barr + + lda CDLeftEj + sec + sbc ztemp + +]rts rts + +*------------------------------- + lst + ds 1 + usr $a9,16,$b00,*-org + lst off diff --git a/01 POP Source/Source/CTRL.S b/01 POP Source/Source/CTRL.S index b4cea22..3b906cf 100755 --- a/01 POP Source/Source/CTRL.S +++ b/01 POP Source/Source/CTRL.S @@ -1 +1,2168 @@ -* ctrl org = $3a00 tr on lst off *------------------------------- org org jmp PLAYERCTRL jmp CHECKFLOOR jmp SHADCTRL jmp REREADBLOCKS jmp CHECKPRESS jmp DOIMPALE jmp GENCTRL jmp CHECKIMPALE *------------------------------- lst put eq lst put gameeq lst put seqdata lst put soundnames lst put movedata lst off dum $f0 ztemp ds 1 jxtemp ds 1 jytemp ds 1 jbtemp ds 1 atemp ds 1 dend *------------------------------- * Misc. changeable parameters DeathVelocity = 33 OofVelocity = 22 grabreach = -8 grabspeed = 32 ;max Y-vel to grab ledge grablead = 25 ;increase to grab ledge earlier stuntime = 12 jumpupreach = 0 jumpupangle = -6 JumpBackThres = 6 StepOffFwd = 3 StepOffBack = 8 swordthres = 90 ;to go en garde (facing fwd) swordthresN = -10 ;" " (behind you) blockthres = 32 graceperiod = 9 gdpatience = 15 gclimbthres = 6 stairthres = 30 plus1 db -1,1 minus1 db 1,-1 *------------------------------- * * If he's passed thru floor plane, change CharBlockY * If floor is solid, stop him * *------------------------------- falling lda CharY ldx CharBlockY inx cmp FloorY,x bcs :1 jmp fallon ;Hasn't reached floor yet * Character is passing thru floor plane :1 jsr getunderft ;Check if there's ;solid floor underfoot cmp #block bne :2 ;Solid block is special case-- jsr InsideBlock ;reset him to either side of block :2 jsr cmpspace bne hitflr inc CharBlockY ;Fall thru floor plane ]rts rts *------------------------------- * * C H E C K F L O O R * *------------------------------- CHECKFLOOR lda CharAction cmp #6 ;hanging? beq ]rts cmp #5 ;bumped? bne :2 lda CharPosn cmp #109 ;crouched (e.g. on loose floor) beq :ong cmp #185 ;dead bne ]rts :ong jmp onground :2 cmp #4 ;freefall beq falling cmp #3 bne :1 lda CharPosn cmp #102 bcc ]rts cmp #106 bcs ]rts jmp fallon :1 cmp #2 ;hanging beq ]rts jmp onground ;7, 0, or 1: on the ground *------------------------------- * * Floor stops him -- Choose appropriate landing * *------------------------------- hitflr ldx CharBlockY inx lda FloorY,x sta CharY ;align char w/floor jsr getunderft cmp #spikes beq :hitspikes * Has he landed too close to edge? jsr getinfront jsr cmpspace bne :cont ;no jsr getdist ;# pixels to edge cmp #4 ;was 2 bcs :cont ;Yes--move him back a little lda #-3 jsr addcharx sta CharX :cont jsr addslicers ;trigger slicers on this level lda CharLife bpl :hardland ;dead before he hits the ground jsr getdist cmp #12 bcc :nc jsr getbehind cmp #spikes beq :hitspikes ;check block behind if dist>=12 :nc jsr getunderft ;what has he landed on? cmp #spikes bne :notspikes :hitspikes jsr getspikes ;are spikes lethal? bne :impale ;yes :notspikes lda CharYVel cmp #OofVelocity bcc :softland cmp #DeathVelocity bcc :medland :hardland lda #100 jsr decstr :hdland1 lda #Splat jsr addsound lda #hardland bne :doland :medland lda CharID cmp #1 beq :softland ;shad lands easy cmp #2 bcs :hardland ;guards can't survive 2 stories lda #1 jsr decstr beq :hdland1 lda #Splat jsr addsound lda #medland bne :doland :softland lda CharID cmp #2 bcs :gd ;guard always lands en garde lda CharSword cmp #2 bne :1 :gd lda #2 sta CharSword lda #landengarde bne :doland :1 lda #softland bne :doland :impale jmp DoImpale :doland jsr jumpseq jsr animchar lda #0 sta CharYVel ]rts rts *------------------------------- * * Hasn't hit floor yet -- can he grab edge above? * *------------------------------- fallon lda btn ;is button down? and CharLife ;& is he alive? bpl ]rts ;yes--can he grab edge? lda CharYVel cmp #grabspeed bcs ]rts ;no--falling too fast lda CharY clc adc #grablead ldx CharBlockY inx cmp FloorY,x bcc ]rts ;not within grabbing range yet * Char is within vertical range, and button is down * Is there a ledge within reach? lda CharX sta savekidx lda #grabreach jsr addcharx sta CharX jsr rereadblocks jsr :test ;can you grab ledge? bne :ok ;yes--do it lda savekidx sta CharX jmp rereadblocks :ok ;do it! * Align char with block jsr getdist jsr addcharx sta CharX ldx CharBlockY inx lda FloorY,x sta CharY lda #0 sta CharYVel lda #fallhang jsr jumpseq jsr animchar lda #stuntime sta stunned ]rts rts :test jsr getabove sta blockid jsr getaboveinf jmp checkledge *------------------------------- * Is there floor underfoot? If not, start to fall onground lda Fcheck and #fcheckmark beq ]rts ;0--no need to check jsr getunderft cmp #block bne :1 jsr InsideBlock ;If "inside" block, bump him outside :1 jsr cmpspace bne ]rts * Level 12: Phantom bridge lda level cmp #12 bne :no lda mergetimer bpl :no lda CharBlockY bne :no lda CharScrn cmp #2 beq :yes cmp #13 bne :no lda tempblockx cmp #6 bcc :no ;Create floorboards on the fly :yes lda #floor sta (BlueType),y jsr indexblock lda #2 jsr :sub iny :sub jsr markwipe jmp markred :no *------------------------------- * No floor underfoot--commence falling startfall lda #0 sta rjumpflag sta CharSword ;so you can grab on inc CharBlockY ;# of floor just below your feet jsr addslicers lda CharPosn ;upcoming frame ;(the one we're about to replace ;with first frame of falling seq) sta rjumpflag cmp #9 ;run-12 beq :stepfall cmp #13 ;run-16 beq :stepfall2 cmp #26 ;standjump-19 beq :jumpfall cmp #44 ;runjump-11 beq :rjumpfall cmp #81 bcc :2 cmp #86 bcc :hdropfall :2 cmp #150 bcc :1 cmp #180 bcc :fightfall ;from fighting stance :1 :stepfall lda #stepfall bne :doit :stepfall2 lda #stepfall2 bne :doit :jumpfall lda #jumpfall bne :doit :rjumpfall lda #rjumpfall bne :doit :hdropfall lda #5 jsr addcharx sta CharX jsr rereadblocks jmp :stepfall2 ]rts rts :fightfall lda CharID cmp #2 bcc :player lda CharXVel bmi :fb ;did gd step off fwd or bkwd? lda #0 sta droppedout lda #efightfallfwd bne :doit :fb lda #efightfall bne :doit :player lda #1 sta droppedout ;for guard's benefit lda #fightfall bne :doit *------------------------------- :doit jsr jumpseq jsr animchar ;advance 1 frame into fall jsr rereadblocks jsr getunderft jsr cmpwall beq :bump jsr getinfront jsr cmpwall bne ]rts jmp CDpatch :bump jmp InsideBlock ;If "inside" block, bump him outside CDpatch lda rjumpflag cmp #44 ;running jump? bne :patchX jsr getdist cmp #6 bcs :patchX ;dist >= 6...we're OK lda #patchfall jsr jumpseq jsr animchar jmp rereadblocks :patchX lda #-1 :1 jsr addcharx sta CharX jmp rereadblocks *------------------------------- * * Char is "inside" a block--bump him outside * (hopefully the same side from which he entered) * * Change Char X & return rdblock results * *------------------------------- InsideBlock jsr getdist ;to EOB cmp #8 bcs :bumpback :bumpfwd jsr getinfront cmp #block beq :bumpback jsr getdist ;to EOB clc adc #4 :reland jsr addcharx sta CharX jsr rereadblocks ;reposition char jmp getunderft :bumpback jsr getbehind cmp #block bne :1 ;we're screwed ;bump 2 back (what the hell) jsr getdist clc adc #14 eor #$ff clc adc #8 jmp :reland :1 jsr getdist eor #$ff clc adc #8 jmp :reland *------------------------------- * * S H A D O W C O N T R O L * *------------------------------- SHADCTRL lda CharID cmp #24 ;mouse? bne :1 jmp AutoCtrl :1 lda CharLife bpl :dead ;Has char's life run out? lda OppStrength bne :cont lda #0 sta CharLife jsr deadenemy :dead lda CharID cmp #1 ;shadow man? bne :cont jmp VanishChar :cont lda ManCtrl bne :manualctrl jsr AutoCtrl jmp GenCtrl * Manual ctrl: enemy controlled by deselected device :manualctrl jsr LoadDesel jsr getdesel jsr clrjstk jsr UserCtrl jmp SaveDesel *------------------------------- * * P L A Y E R C O N T R O L * *------------------------------- PLAYERCTRL lda CharLife bpl :cont1 ;dead lda KidStrength bne :cont1 lda #0 sta CharLife :cont1 lda stunned beq :cont dec stunned :cont lda level bne :game :demo jsr DemoCtrl jmp GenCtrl * Character controlled by selected device :game jsr LoadSelect ;load jstk-push flags for selected device jsr getselect ;get current input from selected device jsr clrjstk ;clear appropriate jstk-push flags lda #2 jsr UserCtrl jmp SaveSelect ;save updated jstk-push flags *------------------------------- * Player ctrl in demo DemoCtrl lda milestone bne :finish lda CharSword beq :preprog lda #10 sta guardprog jsr AutoCtrl lda #11 sta guardprog rts :preprog jmp demo :finish jsr clrall sta clrbtn lda #-1 sta clrF sta JSTKX ;run o.s. ]rts rts *------------------------------- UserCtrl lda CharFace bpl :faceL jmp GenCtrl * If char is facing right, reverse JSTK & clrF/clrB :faceL jsr facejstk jsr GenCtrl jmp facejstk *------------------------------- clrall lda #0 sta clrB sta clrF sta clrU sta clrD lda #1 ]rts rts *------------------------------- * * G E N E R A L C O N T R O L * * In: Raw input * JSTKX (- fwd, + back, 0 center) * JSTKY (- up, + down, 0 center) * btn (- down, + up) * Smart input * clrF-B-U-D-btn (- = fresh press) * * Set clr = 1 after using a press * *------------------------------- GENCTRL lda CharLife bmi :alive * Dead character (If he's standing, collapse) :dead lda CharPosn cmp #15 beq :drop cmp #166 beq :drop cmp #158 beq :drop cmp #171 bne ]rts :drop lda #dropdead jmp jumpseq * Live character :alive lda CharAction cmp #5 ;is char in mid-bump? beq :clr cmp #4 ;or falling? beq :clr bne :underctrl :clr ]clr jmp clrall :underctrl lda CharSword cmp #2 ;in fighting mode? beq FightCtrl ;yes lda CharID cmp #2 ;kid or shadowman? bcc :cont jmp GuardCtrl ;no * First question: what is char doing now? :cont ldx CharPosn ;previous frame # cpx #15 beq :standing cpx #48 beq :turning cpx #50 bcc :0 cpx #53 bcc :standing ;turn7-8-9/crouch :0 cpx #4 bcc :starting ;run4-5-6 cpx #67 bcc :4 cpx #70 bcc :stjumpup ;starting to jump up :4 cpx #15 bcs :2 jmp :running ;run8-17 :2 cpx #87 bcc :1 cpx #100 bcs :1 jmp :hanging ;jumphang22-34 :1 cpx #109 ;crouching? beq :crouching :3 ]rts rts :standing jmp standing :starting jmp starting :stjumpup jmp stjumpup :running jmp arunning :hanging jmp hanging :turning jmp turning :crouching jmp crouching *------------------------------- * Similar routine for guard GuardCtrl ldx CharPosn cpx #166 ;standing? beq :alert ]rts rts :alert lda clrD bpl ]rts lda clrF bmi :engarde bpl :turn :engarde jmp DoEngarde :turn lda #1 sta clrD lda #alertturn jmp jumpseq *------------------------------- * Char is en garde (CharSword = 2) FightCtrl lda CharAction cmp #2 bcs ]rts ;Must be on level ground (Action = 1) * If Enemy Alert is over, put away your sword jsr getunderft cmp #loose beq :skip ;unless you're standing on loose floor lda EnemyAlert cmp #2 bcc :dropgd * If opponent is behind you, turn to face him :skip jsr getopdist ;fwd distance to opponent cmp #swordthres bcc :onalert cmp #128 bcc :dropgd cmp #-4 bcs :onalert ;overlapping jmp DoTurnEng * Enemy out of range--drop your guard * (kid & shadman only) :dropgd lda CharID bne :1 sta heroic beq :2 :1 cmp #2 bcs :onalert ;guard: remain en garde :2 ldx CharPosn cpx #171 ;wait for ready posn bne ]rts lda #0 sta CharSword lda #resheathe jmp jumpseq ]rts rts *------------------------------- * Remain en garde :onalert ldx CharPosn ;prev frame # cpx #161 ;successful block? bne :nobloc lda clrbtn ;yes--restrike or retreat? bmi :bts lda #retreat jmp jumpseq * Fresh button press to strike :nobloc lda clrbtn bpl :10 :bts lda CharID bne :11 lda #gdpatience sta gdtimer :11 jsr DoStrike lda clrbtn cmp #1 beq ]rts ;struck :10 ;else didn't strike * Down to lower your sword lda clrD bpl :nodrop ldx CharPosn cpx #158 ;ready beq :ready1 cpx #170 beq :ready1 cpx #171 bne ]rts :ready1 lda #1 sta clrD lda #0 sta CharSword lda CharID beq :drop ;for kid cmp #1 beq :sstand ;for shadman :alert lda #goalertstand jmp jumpseq ;for guard :drop lda #1 sta offguard lda #graceperiod sta refract lda #0 sta heroic lda #fastsheathe jmp jumpseq :sstand lda #resheathe jmp jumpseq * Fwd to advance, up to block, back to retreat :nodrop lda clrU bmi :up lda clrF bmi :fwd lda clrB bmi :back ]rts rts :fwd jmp DoAdvance :up jmp DoBlock :back jmp DoRetreat *------------------------------- DoTurnEng lda #turnengarde jmp jumpseq *------------------------------- DoBlock ldx CharPosn cpx #158 ;ready beq :2 cpx #170 beq :2 cpx #171 beq :2 cpx #168 ;guy-2 beq :2 cpx #165 ;adv beq :2 cpx #167 ;blocked strike beq :3 ]rts rts * From ready position: Block if appropriate :2 jsr getopdist cmp #blockthres bcs :blockmiss ;too far lda #readyblock ldx CharID beq :kid ldx OpPosn ;enemy sees kid 1 frame ahead cpx #152 ;guy4 beq :doit ]rts rts :kid ldx OpPosn cpx #168 ;1 frame too early? beq ]rts ;yes--wait 1 frame cpx #151 ;guy3 beq :doit cpx #152 ;guy4 beq :doit cpx #162 ;guy22 beq :doit cpx #153 ;1 frame too late? bne :blockmiss ;yes--skip 1 frame jsr :doit jmp animchar * Strike-to-block :3 lda #strikeblock :doit ldx #1 stx clrU jmp jumpseq :blockmiss lda CharID bne DoRetreat ;enemy doesn't waste blocks lda #readyblock bne :doit *------------------------------- DoStrike cpx #157 beq :1 cpx #158 beq :1 cpx #170 beq :1 cpx #171 beq :1 ;strike from ready posn cpx #165 beq :1 ;from advance cpx #150 beq :2 ;from missed block cpx #161 beq :2 ;from successful block ]rts rts :1 lda CharID bne :slo ;kid is fast, others slow lda #faststrike bne :dostr :slo lda #strike :dostr ldx #1 stx clrbtn jmp jumpseq :2 lda #blocktostrike bne :dostr *------------------------------- DoRetreat ldx CharPosn cpx #158 beq :1 ;strike from ready posn cpx #170 beq :1 cpx #171 beq :1 ]rts rts :1 lda #retreat ldx #1 stx clrB jmp jumpseq *------------------------------- DoAdvance ldx CharPosn cpx #158 beq :1 cpx #170 beq :1 cpx #171 beq :1 ]rts rts :1 lda CharID bne :slo ;kid is faster lda #fastadvance bne :doit :slo lda #advance :doit ldx #1 stx clrF jmp jumpseq *------------------------------- * * S T A N D I N G * *------------------------------- standing * Fresh button click: pick up object? lda clrbtn bpl :noclick lda btn bpl :noclick jsr TryPickup bne ]rts ;yes :noclick * Shadman only: down & fwd to go en garde lda CharID beq :kid lda clrD bpl :1 lda clrF bpl :1 jmp DoEngarde * If opponent is within range, go en garde * (For kid only) :kid lda gotsword beq :1 ;no sword lda offguard beq :notoffg lda btn ;off guard--push btn to draw sword bpl :btnup :notoffg lda EnemyAlert cmp #2 bcc :safe jsr getopdist ;fwd distance to opponent cmp #swordthresN bcs :danger cmp #swordthres bcs :safe :danger ldx #1 stx heroic cmp #-6 bcs :behindyou lda OpID cmp #1 bne :engarde lda OpAction cmp #3 beq :safe lda OpPosn cmp #107 bcc :engarde cmp #118 bcc :safe ;let shadow land :engarde jmp DoEngarde :behindyou jmp DoTurn :safe lda #0 sta offguard :1 lda btn bpl :btnup *------------------------------- * Standing, button down :2 lda clrB bmi :backB lda clrU bmi :up lda clrD bmi :down lda JSTKX bpl :rts lda clrF bmi :fwdB :rts ]rts rts *------------------------------- * Standing, button up :btnup lda clrF bmi :fwd lda clrB bmi :back lda clrU bmi :up lda clrD bmi :down lda JSTKX bmi :fwd ]rts rts :fwd jmp DoStartrun :fwdB jmp DoStepfwd :back jmp DoTurn :backB jmp DoTurn :fwdup jmp DoStandjump *------------------------------- * Standing, joystick up :up * In front of open stairs? jsr getunderft cmp #exit beq :stairs jsr getbehind cmp #exit beq :stairs jsr getinfront cmp #exit bne :nostairs :stairs lda (BlueSpec),y lsr lsr cmp #stairthres bcc :nostairs jmp Stairs * No -- normal control :nostairs lda JSTKX bmi :fwdup * Straight up...jump up & grab ledge if you can jmp DoJumpup *------------------------------- * Standing, joystick down :down lda #1 sta clrD * If you're standing w/back to edge, down * means "climb down & hang from ledge" * If facing edge, "down" means "step off" jsr getinfront jsr cmpspace bne :notfwd ;no cliff in front of you jsr getdist cmp #StepOffFwd bcs :notfwd ;not close enough to edge lda #5 jsr addcharx sta CharX jmp rereadblocks ;move fwd :notfwd jsr getbehind jsr cmpspace bne :no ;no cliff behind you jsr getdist cmp #StepOffBack bcc :no ;not close enough to edge * Climb down & hang from ledge jsr getbehind sta blockid jsr getunderft jsr checkledge beq :no ldx CharFace bpl :succeed jsr getunderft cmp #gate bne :succeed lda (BlueSpec),y lsr lsr cmp #gclimbthres bcc :no :succeed jsr getdist sec sbc #9 jsr addcharx sta CharX lda #climbdown jmp jumpseq * Otherwise "down" means "crouch" :no jmp DoCrouch *------------------------------- * Climb stairs Stairs lda tempblockx ;stairs block jsr getblockej clc adc #10 sta CharX lda #-1 sta CharFace lda #climbstairs jmp jumpseq ]rts rts *------------------------------- * * C R O U C H I N G * *------------------------------- crouching * Fresh button click? lda clrbtn bpl :noclick jsr TryPickup bne ]rts * Still crouching? :noclick lda JSTKY cmp #1 beq :1 lda #standup jmp jumpseq :1 lda clrF bpl ]rts lda #1 sta clrF lda #crawl jmp jumpseq *------------------------------- * * S T A R T I N G * * First few frames of "startrun" * *------------------------------- starting lda JSTKY bmi :jump ]rts rts :jump lda JSTKX bpl ]rts jmp DoStandjump *------------------------------- * First few frames of "jumpup" stjumpup lda JSTKX bmi :fwd lda clrF bmi :fwd ]rts rts :fwd jmp DoStandjump *------------------------------- * * T U R N I N G * *------------------------------- turning lda btn bmi ]rts lda JSTKX bpl ]rts lda JSTKY bmi ]rts * Jstk still fwd--convert turn to turnrun lda #turnrun jmp jumpseq *------------------------------- * * R U N N I N G * *------------------------------- arunning lda JSTKX beq :runstop ;jstk centered...stop running bpl :runturn ;jstk back...turn around * Jstk is forward... keep running * & wait for signal to runjump or diveroll lda JSTKY bmi :runjump ;jstk up... take a running jump lda clrD bmi :diveroll ;jstk down... running dive & roll ]rts rts * Running dive & roll :diveroll lda #1 sta clrD lda #rdiveroll jmp jumpseq * Running jump :runjump lda clrU bpl ]rts jmp DoRunjump * Stop running :runstop lda CharPosn cmp #7 ;run-10 beq :rs cmp #11 ;run-14 bne ]rts :rs jsr ]clr sta clrF lda #runstop jmp jumpseq * Turn around & run the other way :runturn jsr ]clr sta clrB lda #runturn jmp jumpseq *------------------------------- * * H A N G I N G * *------------------------------- hanging lda stunned bne :9 ;can't climb up lda JSTKY bmi :climbup ;jstk up-->climb up :9 lda btn bpl :drop * If hanging on right-hand side of a panel * or either side of block, * switch to "hangstraight" lda CharAction cmp #6 beq :cont ;already hanging straight jsr getunderft cmp #block beq :hangstrt ldx CharFace cpx #-1 ;left bne :cont cmp #panelwif beq :hangstrt cmp #panelwof beq :hangstrt * If ledge crumbles away, fall with it :cont jsr getabove jsr cmpspace ;still there? beq :drop ;no * just keep swinging :rts ]rts rts :hangstrt lda #hangstraight jmp jumpseq *------------------------------- * climb up (if you can) :climbup jsr ]clr sta clrU sta clrbtn jsr getabove cmp #mirror beq :10 cmp #slicer bne :1 :10 ldx CharFace beq :fail bne :succeed ;can only mount mirror facing L :1 cmp #gate bne :2 ldx CharFace beq :succeed ;can only mount closed gate facing R lda (BlueSpec),y lsr lsr cmp #gclimbthres bcc :fail bcs :succeed :2 :succeed lda #climbup jmp jumpseq :fail lda #climbfail jmp jumpseq *------------------------------- :drop jsr ]clr sta clrD ;clrD = 1, all others = 0 jsr getbehind jsr cmpspace bne :hangdrop jsr getunderft jsr cmpspace beq :hangfall :hangdrop jsr getunderft cmp #block beq :sheer ldx CharFace bpl :clear cmp #panelwof beq :sheer cmp #panelwif bne :clear :sheer lda #-7 jsr addcharx sta CharX :clear lda #hangdrop jmp jumpseq :hangfall lda #hangfall jmp jumpseq ]rts rts *------------------------------- * * D o S t a r t r u n * *------------------------------- DoStartrun * If very close to a barrier, do a Stepfwd instead * (Exceptions: slicer & open gate) jsr getfwddist cpx #1 ;barrier? bne :startrun ;no cpy #slicer beq :startrun :solidbarr jsr getfwddist cmp #8 bcs :startrun lda clrF bpl ]rts jmp DoStepfwd :startrun lda #startrun jmp jumpseq ;...start running DoTurn jsr ]clr sta clrB ;if enemy is behind you, draw as you turn lda gotsword beq :1 lda EnemyAlert cmp #2 bcc :1 jsr getopdist bpl :1 jsr getdist ;to EOB cmp #2 bcc :1 lda #2 sta CharSword ;en garde lda #0 sta offguard lda #turndraw bne :2 :1 lda #turn :2 jmp jumpseq ;...turn around DoStandjump lda #1 sta clrU sta clrF lda #standjump jmp jumpseq ;...standing jump DoSdiveroll lda #1 sta clrD lda #sdiveroll jmp jumpseq ;...standing dive & roll DoCrouch lda #stoop jsr jumpseq jsr ]clr sta clrD rts DoEngarde jsr ]clr sta clrF sta clrbtn lda #2 sta CharSword ;en garde lda CharID beq :1 cmp #1 beq :3 ;shad lda #guardengarde bne :2 :1 lda #0 sta offguard :3 lda #engarde :2 jmp jumpseq *------------------------------- * * D o J u m p u p * * & grab ledge if you can * *------------------------------- DoJumpup jsr ]clr sta clrU jsr getabove sta blockid jsr getaboveinf jsr checkledge ;Can you jump up & grab ledge? ;Returns 1 if you can, 0 if you can't bne DoJumphang ;yes--do it jsr getabovebeh sta blockid jsr getabove jsr checkledge ;could you do it if you were 1 space back? bne :jumpback ;yes--move back & do it :jumphi jmp DoJumphigh *------------------------------- * Jump up & back to grab block directly overhead :jumpback jsr getdist ;dist to front of block cmp #JumpBackThres bcc :jumphi ;too far to fudge jsr getbehind jsr cmpspace ;floor behind you? beq DoJumpedge ;no * "Jump back" to block behind you & then proceed as usual jsr getdist sec sbc #14 jsr addcharx sta CharX jsr rereadblocks jmp DoJumphang *------------------------------- * Your back is to ledge -- so do a "jumpbackhang" DoJumpedge jsr getabove * Get all the way back on this block jsr getdist sec sbc #10 jsr addcharx sta CharX * now jump lda #jumpbackhang jmp jumpseq *------------------------------- DoJumphang jsr getaboveinf * Choose the jumphang sequence (Long/Med) that * will bring us closest to edge, then fudge the X-coord * to make it come out exactly jsr getdist ;get distance to front of block sta atemp ;# pixels (0-13) returned in A cmp #4 bcc :Med :Long lda atemp sec ;"Long" will add 4 to CharX sbc #4 jsr addcharx sta CharX lda #jumphangLong jmp jumpseq :Med jsr getfwddist cmp #4 bcs :okMed cpx #1 ;close to wall? beq :Long ;yes--step back & do Long :okMed lda atemp jsr addcharx sta CharX lda #jumphangMed jmp jumpseq ]rts rts *------------------------------- * * D o R u n J u m p * * Calibrate jump so that foot will push off at edge. * *------------------------------- RJChange = 4 ;projected change in CharX RJLookahead = 1 ;# blocks you can look ahead RJLeadDist = 14 ;required leading distance in pixels RJMaxFujBak = 8 ;# pixels we're willing to fudge back RJMaxFujFwd = 2 ;and forward DoRunjump lda CharPosn cmp #7 bcc ]rts ;must be in full run * Count # of blocks to edge * (Use actual CharX) lda #0 sta bufindex ;block counter lda #RJChange jsr addcharx sta ztemp ;projected CharX jsr getblockxp sta blockx :loop lda blockx ldx CharFace inx clc adc plus1,x sta blockx tax ldy CharBlockY lda CharScrn jsr rdblock cmp #spikes beq :done jsr cmpspace beq :done inc bufindex lda bufindex cmp #RJLookahead+1 bcc :loop bcs :noedge ;no edge in sight--jump anyway :done * Calculate # of pixels to end of floor lda ztemp jsr getdist1 ;# pixels to end of block ldx bufindex ;# of blocks to end of floor clc adc Mult7,x clc adc Mult7,x ;# of pixels to end of floor sec sbc #RJLeadDist ;A = difference between actual dist to edge ;and distance covered by RunJump cmp #-RJMaxFujBak bcs :ok ;move back a little & jump cmp #RJMaxFujFwd bcc :ok ;move fwd a little & jump cmp #$80 bcc ]rts ;still too far away--wait till next frame lda #-3 ;He jumped too late; he'll miss edge ;But let's make it look good anyway :ok clc adc #RJChange jsr addcharx sta CharX * No edge in sight -- just do any old long jump :noedge jsr ]clr sta clrU lda #runjump jmp jumpseq ]rts rts *------------------------------- * * D o S t e p F o r w a r d * *------------------------------- DoStepfwd lda #1 sta clrF sta clrbtn jsr getfwddist ;returns A = distance to step (0-13) cmp #0 beq :1 :2 sta CharRepeat ;non-0 value clc adc #stepfwd1-1 jmp jumpseq :1 cpx #1 beq :thru ;If barrier, step thru cmp CharRepeat bne :3 ;First time, test w/foot :thru lda #11 bne :2 ;Second time, step off edge :3 sta CharRepeat ;0 lda #testfoot jmp jumpseq *------------------------------- * * D o J u m p H i g h * *------------------------------- DoJumphigh jsr ]clr sta clrU jsr getfwddist cmp #4 bcs :ok cpx #1 ;barrier? bne :ok ;no sec sbc #3 jsr addcharx sta CharX :ok lda #jumpupreach jsr facedx sta ztemp jsr getbasex ;assume char standing still clc adc #jumpupangle clc adc ztemp ;get X-coord at which hand touches ceiling jsr getblockx tax ldy CharBlockY dey lda CharScrn jsr rdblock ;read this block cmp #block beq :jumpup jsr cmpspace bne :jumpup lda #highjump jmp jumpseq ;no ceiling above :jumpup lda #jumpup jsr jumpseq ;touch ceiling ]rts rts ;& don't forget to crop top *------------------------------- * reread blocks *------------------------------- REREADBLOCKS jsr GetFrameInfo jmp GetBaseBlock *------------------------------- * * Is character stepping on a pressure plate? * or on loose floor? * *------------------------------- CHECKPRESS lda CharPosn cmp #87 bcc :1 cmp #100 bcc :hanging ;87-99: jumphang22-34 cmp #135 bcc :1 cmp #141 bcc :hanging ;135-140: climb up/down :1 lda CharAction cmp #7 beq :ground ;turning cmp #5 beq :ground ;bumped cmp #2 bcs ]rts * Action code 7, 0 or 1: on the ground :ground lda CharPosn cmp #79 ;jumpup/touch ceiling beq :touchceil lda Fcheck and #fcheckmark beq ]rts ;foot isn't touching floor * Standing on a pressplate? jsr getunderft :checkit cmp #upressplate beq :PP cmp #pressplate bne :notPP :PP lda CharLife bmi :push jmp jampp ;dead weight :push jmp pushpp :notPP cmp #loose bne ]rts lda #1 sta alertguard jmp breakloose * Hanging on a pressplate? :hanging jsr getabove jmp :checkit ]rts rts * Jumping up to touch ceiling? :touchceil jsr getabove cmp #loose bne ]rts jmp breakloose *------------------------------- * * C H E C K I M P A L E * * Impalement by running or jumping onto spikes * (Impalement by landing on spikes is covered by * CHECKFLOOR:falling) * *------------------------------- CHECKIMPALE ldx CharBlockX ldy CharBlockY lda CharScrn jsr rdblock cmp #spikes bne ]rts ;not spikes ldx CharPosn cpx #7 bcc ]rts cpx #15 bcs :2 jmp :running :2 cpx #43 ;runjump-10 beq :jumpland cpx #26 ;standjump-19 beq :jumpland ]rts rts :running jsr getspikes cmp #2 bcc ]rts ;must be springing bcs :impale :jumpland jsr getspikes ;are spikes lethal? beq ]rts ;no :impale jmp DoImpale *------------------------------- * Impale char on spikes * * In: rdblock results *------------------------------- DOIMPALE jsr jamspikes ldx CharBlockY inx lda FloorY,x sta CharY ;align char w/floor lda tempblockx jsr getblockej ;edge of spikes clc adc #10 sta CharX lda #8 jsr addcharx sta CharX ;center char on spikes lda #0 sta CharYVel lda #Impaled jsr addsound lda #100 jsr decstr lda #impale jsr jumpseq jmp animchar *------------------------------- * * Pick up object * Return 0 if no result * *------------------------------- TryPickup jsr getunderft cmp #flask beq :2 cmp #sword bne :1 :2 jsr getbehind jsr cmpspace beq :no lda CharX lda #-14 jsr addcharx sta CharX ;move char 1 block back jsr rereadblocks :1 jsr getinfront cmp #flask beq :pickup cmp #sword beq :pickup :no lda #0 rts :pickup jsr PickItUp lda #1 rts *------------------------------- * * Pick something up * * In: rdblock results for object block ("infront") * *------------------------------- PickItUp ldx CharPosn cpx #109 ;crouch first, then pick up obj beq :ok jsr getfwddist cpx #2 beq :0 ;right at edge jsr addcharx sta CharX :0 lda CharFace bmi :1 lda #-2 jsr addcharx sta CharX ;put char within reach of obj :1 jmp DoCrouch :ok cmp #sword beq :PickupSword lda (BlueSpec),y lsr lsr lsr lsr lsr ;potion # (0-7) jsr RemoveObj lda #drinkpotion ;pick up & drink potion jmp jumpseq :PickupSword lda #-1 ;sword jsr RemoveObj lda #pickupsword jmp jumpseq ;pick up, brandish & sheathe sword *------------------------------- lst ds 1 usr $a9,16,$00,*-org lst off \ No newline at end of file +* ctrl +org = $3a00 + tr on + lst off +*------------------------------- + org org + + jmp PLAYERCTRL + jmp CHECKFLOOR + jmp SHADCTRL + jmp REREADBLOCKS + jmp CHECKPRESS + + jmp DOIMPALE + jmp GENCTRL + jmp CHECKIMPALE + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put seqdata + lst + put soundnames + lst + put movedata + lst off + + dum $f0 +ztemp ds 1 +jxtemp ds 1 +jytemp ds 1 +jbtemp ds 1 +atemp ds 1 + dend + +*------------------------------- +* Misc. changeable parameters + +DeathVelocity = 33 +OofVelocity = 22 + +grabreach = -8 +grabspeed = 32 ;max Y-vel to grab ledge +grablead = 25 ;increase to grab ledge earlier +stuntime = 12 + +jumpupreach = 0 +jumpupangle = -6 + +JumpBackThres = 6 +StepOffFwd = 3 +StepOffBack = 8 + +swordthres = 90 ;to go en garde (facing fwd) +swordthresN = -10 ;" " (behind you) +blockthres = 32 +graceperiod = 9 +gdpatience = 15 + +gclimbthres = 6 + +stairthres = 30 + +plus1 db -1,1 +minus1 db 1,-1 + +*------------------------------- +* +* If he's passed thru floor plane, change CharBlockY +* If floor is solid, stop him +* +*------------------------------- +falling + lda CharY + + ldx CharBlockY + inx + cmp FloorY,x + bcs :1 + + jmp fallon ;Hasn't reached floor yet + +* Character is passing thru floor plane + +:1 jsr getunderft ;Check if there's + ;solid floor underfoot + cmp #block + bne :2 ;Solid block is special case-- + jsr InsideBlock ;reset him to either side of block + +:2 jsr cmpspace + bne hitflr + + inc CharBlockY ;Fall thru floor plane + +]rts rts +*------------------------------- +* +* C H E C K F L O O R +* +*------------------------------- + +CHECKFLOOR + lda CharAction + cmp #6 ;hanging? + beq ]rts + + cmp #5 ;bumped? + bne :2 + lda CharPosn + cmp #109 ;crouched (e.g. on loose floor) + beq :ong + cmp #185 ;dead + bne ]rts +:ong jmp onground + +:2 cmp #4 ;freefall + beq falling + cmp #3 + bne :1 + lda CharPosn + cmp #102 + bcc ]rts + cmp #106 + bcs ]rts + jmp fallon + +:1 cmp #2 ;hanging + beq ]rts + jmp onground ;7, 0, or 1: on the ground + +*------------------------------- +* +* Floor stops him -- Choose appropriate landing +* +*------------------------------- +hitflr + ldx CharBlockY + inx + lda FloorY,x + sta CharY ;align char w/floor + + jsr getunderft + cmp #spikes + beq :hitspikes + +* Has he landed too close to edge? + + jsr getinfront + jsr cmpspace + bne :cont ;no + + jsr getdist ;# pixels to edge + cmp #4 ;was 2 + bcs :cont +;Yes--move him back a little + lda #-3 + jsr addcharx + sta CharX + +:cont jsr addslicers ;trigger slicers on this level + + lda CharLife + bpl :hardland ;dead before he hits the ground + + jsr getdist + cmp #12 + bcc :nc + jsr getbehind + cmp #spikes + beq :hitspikes ;check block behind if dist>=12 + +:nc jsr getunderft ;what has he landed on? + cmp #spikes + bne :notspikes + +:hitspikes + jsr getspikes ;are spikes lethal? + bne :impale ;yes + +:notspikes + lda CharYVel + cmp #OofVelocity + bcc :softland + + cmp #DeathVelocity + bcc :medland + +:hardland + lda #100 + jsr decstr +:hdland1 + lda #Splat + jsr addsound + + lda #hardland + bne :doland + +:medland + lda CharID + cmp #1 + beq :softland ;shad lands easy + cmp #2 + bcs :hardland ;guards can't survive 2 stories + + lda #1 + jsr decstr + beq :hdland1 + + lda #Splat + jsr addsound + + lda #medland + bne :doland + +:softland + lda CharID + cmp #2 + bcs :gd ;guard always lands en garde + lda CharSword + cmp #2 + bne :1 +:gd lda #2 + sta CharSword + lda #landengarde + bne :doland + +:1 lda #softland + bne :doland + +:impale jmp DoImpale + +:doland jsr jumpseq + jsr animchar + + lda #0 + sta CharYVel +]rts rts + +*------------------------------- +* +* Hasn't hit floor yet -- can he grab edge above? +* +*------------------------------- +fallon + lda btn ;is button down? + and CharLife ;& is he alive? + bpl ]rts + ;yes--can he grab edge? + lda CharYVel + cmp #grabspeed + bcs ]rts ;no--falling too fast + + lda CharY + clc + adc #grablead + ldx CharBlockY + inx + cmp FloorY,x + bcc ]rts ;not within grabbing range yet + +* Char is within vertical range, and button is down +* Is there a ledge within reach? + + lda CharX + sta savekidx + lda #grabreach + jsr addcharx + sta CharX + jsr rereadblocks + + jsr :test ;can you grab ledge? + bne :ok ;yes--do it + lda savekidx + sta CharX + jmp rereadblocks +:ok ;do it! + +* Align char with block + + jsr getdist + + jsr addcharx + sta CharX + + ldx CharBlockY + inx + lda FloorY,x + sta CharY + + lda #0 + sta CharYVel + + lda #fallhang + jsr jumpseq + jsr animchar + + lda #stuntime + sta stunned +]rts rts + +:test jsr getabove + sta blockid + jsr getaboveinf + jmp checkledge + +*------------------------------- +* Is there floor underfoot? If not, start to fall + +onground + lda Fcheck + and #fcheckmark + beq ]rts ;0--no need to check + + jsr getunderft + cmp #block + bne :1 + jsr InsideBlock ;If "inside" block, bump him outside +:1 + jsr cmpspace + bne ]rts + +* Level 12: Phantom bridge + + lda level + cmp #12 + bne :no + lda mergetimer + bpl :no + lda CharBlockY + bne :no + lda CharScrn + cmp #2 + beq :yes + cmp #13 + bne :no + lda tempblockx + cmp #6 + bcc :no +;Create floorboards on the fly +:yes lda #floor + sta (BlueType),y + jsr indexblock + lda #2 + jsr :sub + iny +:sub jsr markwipe + jmp markred +:no +*------------------------------- +* No floor underfoot--commence falling + +startfall + lda #0 + sta rjumpflag + sta CharSword ;so you can grab on + + inc CharBlockY ;# of floor just below your feet + jsr addslicers + + lda CharPosn ;upcoming frame +;(the one we're about to replace +;with first frame of falling seq) + sta rjumpflag + + cmp #9 ;run-12 + beq :stepfall + cmp #13 ;run-16 + beq :stepfall2 + cmp #26 ;standjump-19 + beq :jumpfall + cmp #44 ;runjump-11 + beq :rjumpfall + cmp #81 + bcc :2 + cmp #86 + bcc :hdropfall +:2 cmp #150 + bcc :1 + cmp #180 + bcc :fightfall ;from fighting stance +:1 + +:stepfall lda #stepfall + bne :doit + +:stepfall2 lda #stepfall2 + bne :doit + +:jumpfall lda #jumpfall + bne :doit + +:rjumpfall lda #rjumpfall + bne :doit + +:hdropfall + lda #5 + jsr addcharx + sta CharX + jsr rereadblocks + jmp :stepfall2 +]rts rts + +:fightfall lda CharID + cmp #2 + bcc :player + lda CharXVel + bmi :fb ;did gd step off fwd or bkwd? + lda #0 + sta droppedout + lda #efightfallfwd + bne :doit +:fb lda #efightfall + bne :doit +:player lda #1 + sta droppedout ;for guard's benefit + lda #fightfall + bne :doit + +*------------------------------- +:doit jsr jumpseq + jsr animchar ;advance 1 frame into fall + + jsr rereadblocks + jsr getunderft + jsr cmpwall + beq :bump + jsr getinfront + jsr cmpwall + bne ]rts + jmp CDpatch + +:bump jmp InsideBlock ;If "inside" block, bump him outside + +CDpatch + lda rjumpflag + cmp #44 ;running jump? + bne :patchX + + jsr getdist + cmp #6 + bcs :patchX ;dist >= 6...we're OK + + lda #patchfall + jsr jumpseq + jsr animchar + jmp rereadblocks + +:patchX lda #-1 +:1 jsr addcharx + sta CharX + jmp rereadblocks + +*------------------------------- +* +* Char is "inside" a block--bump him outside +* (hopefully the same side from which he entered) +* +* Change Char X & return rdblock results +* +*------------------------------- +InsideBlock + jsr getdist ;to EOB + cmp #8 + bcs :bumpback + +:bumpfwd + jsr getinfront + cmp #block + beq :bumpback + + jsr getdist ;to EOB + clc + adc #4 +:reland + jsr addcharx + sta CharX + jsr rereadblocks ;reposition char + jmp getunderft + +:bumpback + jsr getbehind + cmp #block + bne :1 + ;we're screwed +;bump 2 back (what the hell) + jsr getdist + clc + adc #14 + eor #$ff + clc + adc #8 + jmp :reland +:1 + jsr getdist + eor #$ff + clc + adc #8 + jmp :reland + +*------------------------------- +* +* S H A D O W C O N T R O L +* +*------------------------------- +SHADCTRL + lda CharID + cmp #24 ;mouse? + bne :1 + jmp AutoCtrl + +:1 lda CharLife + bpl :dead +;Has char's life run out? + lda OppStrength + bne :cont + lda #0 + sta CharLife + jsr deadenemy + +:dead lda CharID + cmp #1 ;shadow man? + bne :cont + jmp VanishChar + +:cont lda ManCtrl + bne :manualctrl + + jsr AutoCtrl + + jmp GenCtrl + +* Manual ctrl: enemy controlled by deselected device + +:manualctrl + jsr LoadDesel + + jsr getdesel + + jsr clrjstk + + jsr UserCtrl + + jmp SaveDesel + +*------------------------------- +* +* P L A Y E R C O N T R O L +* +*------------------------------- +PLAYERCTRL + lda CharLife + bpl :cont1 ;dead + lda KidStrength + bne :cont1 + lda #0 + sta CharLife +:cont1 + lda stunned + beq :cont + dec stunned + +:cont lda level + bne :game +:demo jsr DemoCtrl + jmp GenCtrl + +* Character controlled by selected device + +:game jsr LoadSelect ;load jstk-push flags for selected device + + jsr getselect ;get current input from selected device + + jsr clrjstk ;clear appropriate jstk-push flags + + lda #2 + jsr UserCtrl + + jmp SaveSelect ;save updated jstk-push flags + +*------------------------------- +* Player ctrl in demo + +DemoCtrl + lda milestone + bne :finish + lda CharSword + beq :preprog + + lda #10 + sta guardprog + jsr AutoCtrl + lda #11 + sta guardprog + rts + +:preprog jmp demo + +:finish jsr clrall + sta clrbtn + lda #-1 + sta clrF + sta JSTKX ;run o.s. +]rts rts + +*------------------------------- +UserCtrl + lda CharFace + bpl :faceL + + jmp GenCtrl + +* If char is facing right, reverse JSTK & clrF/clrB + +:faceL jsr facejstk + + jsr GenCtrl + + jmp facejstk + +*------------------------------- +clrall + lda #0 + sta clrB + sta clrF + sta clrU + sta clrD + lda #1 +]rts rts + +*------------------------------- +* +* G E N E R A L C O N T R O L +* +* In: Raw input +* JSTKX (- fwd, + back, 0 center) +* JSTKY (- up, + down, 0 center) +* btn (- down, + up) +* Smart input +* clrF-B-U-D-btn (- = fresh press) +* +* Set clr = 1 after using a press +* +*------------------------------- +GENCTRL + lda CharLife + bmi :alive + +* Dead character (If he's standing, collapse) + +:dead lda CharPosn + cmp #15 + beq :drop + cmp #166 + beq :drop + cmp #158 + beq :drop + cmp #171 + bne ]rts +:drop lda #dropdead + jmp jumpseq + +* Live character + +:alive lda CharAction + cmp #5 ;is char in mid-bump? + beq :clr + cmp #4 ;or falling? + beq :clr + bne :underctrl +:clr +]clr jmp clrall + +:underctrl + lda CharSword + cmp #2 ;in fighting mode? + beq FightCtrl ;yes + + lda CharID + cmp #2 ;kid or shadowman? + bcc :cont + jmp GuardCtrl ;no + +* First question: what is char doing now? + +:cont ldx CharPosn ;previous frame # + + cpx #15 + beq :standing + + cpx #48 + beq :turning + + cpx #50 + bcc :0 + cpx #53 + bcc :standing ;turn7-8-9/crouch +:0 + cpx #4 + bcc :starting ;run4-5-6 + + cpx #67 + bcc :4 + cpx #70 + bcc :stjumpup ;starting to jump up + +:4 cpx #15 + bcs :2 + jmp :running ;run8-17 + +:2 cpx #87 + bcc :1 + cpx #100 + bcs :1 + jmp :hanging ;jumphang22-34 + +:1 cpx #109 ;crouching? + beq :crouching +:3 +]rts rts + +:standing jmp standing +:starting jmp starting +:stjumpup jmp stjumpup +:running jmp arunning +:hanging jmp hanging +:turning jmp turning +:crouching jmp crouching + +*------------------------------- +* Similar routine for guard + +GuardCtrl + ldx CharPosn + cpx #166 ;standing? + beq :alert +]rts rts + +:alert + lda clrD + bpl ]rts + lda clrF + bmi :engarde + bpl :turn + +:engarde jmp DoEngarde + +:turn lda #1 + sta clrD + lda #alertturn + jmp jumpseq + +*------------------------------- +* Char is en garde (CharSword = 2) + +FightCtrl + lda CharAction + cmp #2 + bcs ]rts ;Must be on level ground (Action = 1) + +* If Enemy Alert is over, put away your sword + + jsr getunderft + cmp #loose + beq :skip ;unless you're standing on loose floor + + lda EnemyAlert + cmp #2 + bcc :dropgd + +* If opponent is behind you, turn to face him + +:skip jsr getopdist ;fwd distance to opponent + cmp #swordthres + bcc :onalert + cmp #128 + bcc :dropgd + cmp #-4 + bcs :onalert ;overlapping + jmp DoTurnEng + +* Enemy out of range--drop your guard +* (kid & shadman only) + +:dropgd lda CharID + bne :1 + sta heroic + beq :2 +:1 cmp #2 + bcs :onalert ;guard: remain en garde +:2 + ldx CharPosn + cpx #171 ;wait for ready posn + bne ]rts + + lda #0 + sta CharSword + + lda #resheathe + jmp jumpseq +]rts rts + +*------------------------------- +* Remain en garde + +:onalert + ldx CharPosn ;prev frame # + cpx #161 ;successful block? + bne :nobloc + lda clrbtn ;yes--restrike or retreat? + bmi :bts + lda #retreat + jmp jumpseq + +* Fresh button press to strike + +:nobloc lda clrbtn + bpl :10 +:bts + lda CharID + bne :11 + lda #gdpatience + sta gdtimer + +:11 jsr DoStrike + + lda clrbtn + cmp #1 + beq ]rts ;struck +:10 ;else didn't strike + +* Down to lower your sword + + lda clrD + bpl :nodrop + + ldx CharPosn + cpx #158 ;ready + beq :ready1 + cpx #170 + beq :ready1 + cpx #171 + bne ]rts +:ready1 + lda #1 + sta clrD + + lda #0 + sta CharSword + + lda CharID + beq :drop ;for kid + cmp #1 + beq :sstand ;for shadman + +:alert lda #goalertstand + jmp jumpseq ;for guard + +:drop lda #1 + sta offguard + lda #graceperiod + sta refract + lda #0 + sta heroic + lda #fastsheathe + jmp jumpseq + +:sstand lda #resheathe + jmp jumpseq + +* Fwd to advance, up to block, back to retreat + +:nodrop + lda clrU + bmi :up + lda clrF + bmi :fwd + lda clrB + bmi :back + +]rts rts + +:fwd jmp DoAdvance +:up jmp DoBlock +:back jmp DoRetreat + +*------------------------------- +DoTurnEng + lda #turnengarde + jmp jumpseq + +*------------------------------- +DoBlock + ldx CharPosn + cpx #158 ;ready + beq :2 + cpx #170 + beq :2 + cpx #171 + beq :2 + cpx #168 ;guy-2 + beq :2 + + cpx #165 ;adv + beq :2 + cpx #167 ;blocked strike + beq :3 + +]rts rts + +* From ready position: Block if appropriate + +:2 jsr getopdist + cmp #blockthres + bcs :blockmiss ;too far + + lda #readyblock + ldx CharID + beq :kid + ldx OpPosn ;enemy sees kid 1 frame ahead + cpx #152 ;guy4 + beq :doit +]rts rts + +:kid ldx OpPosn + cpx #168 ;1 frame too early? + beq ]rts ;yes--wait 1 frame + + cpx #151 ;guy3 + beq :doit + cpx #152 ;guy4 + beq :doit + cpx #162 ;guy22 + beq :doit + + cpx #153 ;1 frame too late? + bne :blockmiss + ;yes--skip 1 frame + jsr :doit + jmp animchar + +* Strike-to-block + +:3 lda #strikeblock +:doit ldx #1 + stx clrU + jmp jumpseq +:blockmiss + lda CharID + bne DoRetreat ;enemy doesn't waste blocks + lda #readyblock + bne :doit + +*------------------------------- +DoStrike + cpx #157 + beq :1 + cpx #158 + beq :1 + cpx #170 + beq :1 + cpx #171 + beq :1 ;strike from ready posn + cpx #165 + beq :1 ;from advance + cpx #150 + beq :2 ;from missed block + cpx #161 + beq :2 ;from successful block + +]rts rts + +:1 lda CharID + bne :slo ;kid is fast, others slow + + lda #faststrike + bne :dostr + +:slo lda #strike +:dostr ldx #1 + stx clrbtn + jmp jumpseq + +:2 lda #blocktostrike + bne :dostr + +*------------------------------- +DoRetreat + ldx CharPosn + cpx #158 + beq :1 ;strike from ready posn + cpx #170 + beq :1 + cpx #171 + beq :1 +]rts rts + +:1 lda #retreat + ldx #1 + stx clrB + jmp jumpseq + +*------------------------------- +DoAdvance + ldx CharPosn + cpx #158 + beq :1 + cpx #170 + beq :1 + cpx #171 + beq :1 +]rts rts + +:1 lda CharID + bne :slo ;kid is faster + lda #fastadvance + bne :doit +:slo lda #advance +:doit ldx #1 + stx clrF + jmp jumpseq + +*------------------------------- +* +* S T A N D I N G +* +*------------------------------- +standing + +* Fresh button click: pick up object? + + lda clrbtn + bpl :noclick + lda btn + bpl :noclick + jsr TryPickup + bne ]rts ;yes +:noclick + +* Shadman only: down & fwd to go en garde + + lda CharID + beq :kid + lda clrD + bpl :1 + lda clrF + bpl :1 + jmp DoEngarde + +* If opponent is within range, go en garde +* (For kid only) + +:kid lda gotsword + beq :1 ;no sword + + lda offguard + beq :notoffg + lda btn ;off guard--push btn to draw sword + bpl :btnup +:notoffg + lda EnemyAlert + cmp #2 + bcc :safe + jsr getopdist ;fwd distance to opponent + cmp #swordthresN + bcs :danger + cmp #swordthres + bcs :safe + +:danger ldx #1 + stx heroic + cmp #-6 + bcs :behindyou + + lda OpID + cmp #1 + bne :engarde + lda OpAction + cmp #3 + beq :safe + lda OpPosn + cmp #107 + bcc :engarde + cmp #118 + bcc :safe ;let shadow land +:engarde jmp DoEngarde + +:behindyou jmp DoTurn + +:safe lda #0 + sta offguard + +:1 lda btn + bpl :btnup + +*------------------------------- +* Standing, button down + +:2 lda clrB + bmi :backB + + lda clrU + bmi :up + + lda clrD + bmi :down + + lda JSTKX + bpl :rts + + lda clrF + bmi :fwdB +:rts +]rts rts + +*------------------------------- +* Standing, button up + +:btnup + lda clrF + bmi :fwd + lda clrB + bmi :back + lda clrU + bmi :up + lda clrD + bmi :down + + lda JSTKX + bmi :fwd + +]rts rts + +:fwd jmp DoStartrun +:fwdB jmp DoStepfwd + +:back jmp DoTurn +:backB jmp DoTurn + +:fwdup jmp DoStandjump + +*------------------------------- +* Standing, joystick up + +:up + +* In front of open stairs? + + jsr getunderft + cmp #exit + beq :stairs + jsr getbehind + cmp #exit + beq :stairs + jsr getinfront + cmp #exit + bne :nostairs + +:stairs lda (BlueSpec),y + lsr + lsr + cmp #stairthres + bcc :nostairs + + jmp Stairs + +* No -- normal control + +:nostairs + lda JSTKX + bmi :fwdup + +* Straight up...jump up & grab ledge if you can + + jmp DoJumpup + +*------------------------------- +* Standing, joystick down + +:down + lda #1 + sta clrD + +* If you're standing w/back to edge, down +* means "climb down & hang from ledge" + +* If facing edge, "down" means "step off" + + jsr getinfront + jsr cmpspace + bne :notfwd ;no cliff in front of you + + jsr getdist + cmp #StepOffFwd + bcs :notfwd ;not close enough to edge + lda #5 + jsr addcharx + sta CharX + jmp rereadblocks ;move fwd + +:notfwd jsr getbehind + jsr cmpspace + bne :no ;no cliff behind you + + jsr getdist + cmp #StepOffBack + bcc :no ;not close enough to edge + +* Climb down & hang from ledge + + jsr getbehind + sta blockid + jsr getunderft + jsr checkledge + beq :no + + ldx CharFace + bpl :succeed + jsr getunderft + cmp #gate + bne :succeed + + lda (BlueSpec),y + lsr + lsr + cmp #gclimbthres + bcc :no + +:succeed jsr getdist + sec + sbc #9 + + jsr addcharx + sta CharX + + lda #climbdown + jmp jumpseq + +* Otherwise "down" means "crouch" + +:no jmp DoCrouch + +*------------------------------- +* Climb stairs + +Stairs + lda tempblockx ;stairs block + jsr getblockej + clc + adc #10 + sta CharX + lda #-1 + sta CharFace + + lda #climbstairs + jmp jumpseq + +]rts rts + +*------------------------------- +* +* C R O U C H I N G +* +*------------------------------- +crouching + +* Fresh button click? + + lda clrbtn + bpl :noclick + + jsr TryPickup + bne ]rts + +* Still crouching? + +:noclick + lda JSTKY + cmp #1 + beq :1 + lda #standup + jmp jumpseq + +:1 lda clrF + bpl ]rts + lda #1 + sta clrF + lda #crawl + jmp jumpseq + +*------------------------------- +* +* S T A R T I N G +* +* First few frames of "startrun" +* +*------------------------------- +starting + lda JSTKY + bmi :jump +]rts rts + +:jump + lda JSTKX + bpl ]rts + + jmp DoStandjump + +*------------------------------- +* First few frames of "jumpup" + +stjumpup + lda JSTKX + bmi :fwd + lda clrF + bmi :fwd +]rts rts +:fwd jmp DoStandjump + +*------------------------------- +* +* T U R N I N G +* +*------------------------------- +turning + lda btn + bmi ]rts + + lda JSTKX + bpl ]rts + + lda JSTKY + bmi ]rts + +* Jstk still fwd--convert turn to turnrun + + lda #turnrun + jmp jumpseq + +*------------------------------- +* +* R U N N I N G +* +*------------------------------- +arunning + lda JSTKX + beq :runstop ;jstk centered...stop running + bpl :runturn ;jstk back...turn around + +* Jstk is forward... keep running +* & wait for signal to runjump or diveroll + + lda JSTKY + bmi :runjump ;jstk up... take a running jump + + lda clrD + bmi :diveroll ;jstk down... running dive & roll + +]rts rts + +* Running dive & roll + +:diveroll lda #1 + sta clrD + + lda #rdiveroll + jmp jumpseq + +* Running jump + +:runjump + lda clrU + bpl ]rts + + jmp DoRunjump + +* Stop running + +:runstop lda CharPosn + cmp #7 ;run-10 + beq :rs + cmp #11 ;run-14 + bne ]rts + +:rs jsr ]clr + sta clrF + + lda #runstop + jmp jumpseq + +* Turn around & run the other way + +:runturn + jsr ]clr + sta clrB + + lda #runturn + jmp jumpseq + +*------------------------------- +* +* H A N G I N G +* +*------------------------------- +hanging + lda stunned + bne :9 ;can't climb up + + lda JSTKY + bmi :climbup ;jstk up-->climb up +:9 + lda btn + bpl :drop + +* If hanging on right-hand side of a panel +* or either side of block, +* switch to "hangstraight" + + lda CharAction + cmp #6 + beq :cont ;already hanging straight + + jsr getunderft + cmp #block + beq :hangstrt + + ldx CharFace + cpx #-1 ;left + bne :cont + + cmp #panelwif + beq :hangstrt + cmp #panelwof + beq :hangstrt + +* If ledge crumbles away, fall with it + +:cont + jsr getabove + + jsr cmpspace ;still there? + beq :drop ;no + +* just keep swinging + +:rts +]rts rts + +:hangstrt lda #hangstraight + jmp jumpseq + +*------------------------------- +* climb up (if you can) + +:climbup + jsr ]clr + sta clrU + sta clrbtn + + jsr getabove + + cmp #mirror + beq :10 + cmp #slicer + bne :1 + +:10 ldx CharFace + beq :fail + bne :succeed ;can only mount mirror facing L + +:1 cmp #gate + bne :2 + + ldx CharFace + beq :succeed +;can only mount closed gate facing R + lda (BlueSpec),y + lsr + lsr + cmp #gclimbthres + bcc :fail + bcs :succeed + +:2 +:succeed lda #climbup + jmp jumpseq + +:fail lda #climbfail + jmp jumpseq + + +*------------------------------- +:drop + jsr ]clr + sta clrD ;clrD = 1, all others = 0 + + jsr getbehind + jsr cmpspace + bne :hangdrop + + jsr getunderft + jsr cmpspace + beq :hangfall + +:hangdrop + jsr getunderft + cmp #block + beq :sheer + + ldx CharFace + bpl :clear + cmp #panelwof + beq :sheer + cmp #panelwif + bne :clear + +:sheer lda #-7 + jsr addcharx + sta CharX + +:clear lda #hangdrop + jmp jumpseq + +:hangfall + lda #hangfall + jmp jumpseq +]rts rts + +*------------------------------- +* +* D o S t a r t r u n +* +*------------------------------- +DoStartrun + +* If very close to a barrier, do a Stepfwd instead +* (Exceptions: slicer & open gate) + + jsr getfwddist + cpx #1 ;barrier? + bne :startrun ;no + + cpy #slicer + beq :startrun + +:solidbarr + jsr getfwddist + cmp #8 + bcs :startrun + + lda clrF + bpl ]rts + + jmp DoStepfwd + +:startrun + lda #startrun + jmp jumpseq ;...start running + +DoTurn jsr ]clr + sta clrB +;if enemy is behind you, draw as you turn + lda gotsword + beq :1 + lda EnemyAlert + cmp #2 + bcc :1 + jsr getopdist + bpl :1 + jsr getdist ;to EOB + cmp #2 + bcc :1 + + lda #2 + sta CharSword ;en garde + lda #0 + sta offguard + lda #turndraw + bne :2 +:1 lda #turn +:2 jmp jumpseq ;...turn around + +DoStandjump lda #1 + sta clrU + sta clrF + + lda #standjump + jmp jumpseq ;...standing jump + +DoSdiveroll lda #1 + sta clrD + + lda #sdiveroll + jmp jumpseq ;...standing dive & roll + +DoCrouch + lda #stoop + jsr jumpseq + + jsr ]clr + sta clrD + rts + +DoEngarde + jsr ]clr + sta clrF + sta clrbtn + + lda #2 + sta CharSword ;en garde + + lda CharID + beq :1 + cmp #1 + beq :3 ;shad + lda #guardengarde + bne :2 +:1 lda #0 + sta offguard +:3 lda #engarde +:2 jmp jumpseq + +*------------------------------- +* +* D o J u m p u p +* +* & grab ledge if you can +* +*------------------------------- +DoJumpup + jsr ]clr + sta clrU + + jsr getabove + sta blockid + + jsr getaboveinf + + jsr checkledge ;Can you jump up & grab ledge? + ;Returns 1 if you can, 0 if you can't + bne DoJumphang ;yes--do it + + jsr getabovebeh + sta blockid + + jsr getabove + + jsr checkledge ;could you do it if you were 1 space back? + bne :jumpback ;yes--move back & do it + +:jumphi jmp DoJumphigh + +*------------------------------- +* Jump up & back to grab block directly overhead + +:jumpback + jsr getdist ;dist to front of block + cmp #JumpBackThres + bcc :jumphi ;too far to fudge + + jsr getbehind + jsr cmpspace ;floor behind you? + beq DoJumpedge ;no + +* "Jump back" to block behind you & then proceed as usual + + jsr getdist + sec + sbc #14 + jsr addcharx + sta CharX + + jsr rereadblocks + + jmp DoJumphang + +*------------------------------- +* Your back is to ledge -- so do a "jumpbackhang" + +DoJumpedge + jsr getabove + +* Get all the way back on this block + + jsr getdist + sec + sbc #10 + + jsr addcharx + sta CharX + +* now jump + + lda #jumpbackhang + jmp jumpseq + +*------------------------------- +DoJumphang + jsr getaboveinf + +* Choose the jumphang sequence (Long/Med) that +* will bring us closest to edge, then fudge the X-coord +* to make it come out exactly + + jsr getdist ;get distance to front of block + sta atemp ;# pixels (0-13) returned in A + + cmp #4 + bcc :Med + +:Long lda atemp + sec ;"Long" will add 4 to CharX + sbc #4 + jsr addcharx + sta CharX + + lda #jumphangLong + jmp jumpseq +:Med + jsr getfwddist + cmp #4 + bcs :okMed + + cpx #1 ;close to wall? + beq :Long ;yes--step back & do Long + +:okMed lda atemp + jsr addcharx + sta CharX + + lda #jumphangMed + jmp jumpseq + +]rts rts + +*------------------------------- +* +* D o R u n J u m p +* +* Calibrate jump so that foot will push off at edge. +* +*------------------------------- +RJChange = 4 ;projected change in CharX +RJLookahead = 1 ;# blocks you can look ahead +RJLeadDist = 14 ;required leading distance in pixels +RJMaxFujBak = 8 ;# pixels we're willing to fudge back +RJMaxFujFwd = 2 ;and forward + +DoRunjump + lda CharPosn + cmp #7 + bcc ]rts ;must be in full run + +* Count # of blocks to edge +* (Use actual CharX) + + lda #0 + sta bufindex ;block counter + + lda #RJChange + jsr addcharx + sta ztemp ;projected CharX + + jsr getblockxp + sta blockx + +:loop lda blockx + ldx CharFace + inx + clc + adc plus1,x + sta blockx + + tax + ldy CharBlockY + lda CharScrn + jsr rdblock + + cmp #spikes + beq :done + + jsr cmpspace + beq :done + + inc bufindex + + lda bufindex + cmp #RJLookahead+1 + bcc :loop + bcs :noedge ;no edge in sight--jump anyway +:done + +* Calculate # of pixels to end of floor + + lda ztemp + jsr getdist1 ;# pixels to end of block + + ldx bufindex ;# of blocks to end of floor + clc + adc Mult7,x + clc + adc Mult7,x ;# of pixels to end of floor + + sec + sbc #RJLeadDist +;A = difference between actual dist to edge +;and distance covered by RunJump + cmp #-RJMaxFujBak + bcs :ok ;move back a little & jump + + cmp #RJMaxFujFwd + bcc :ok ;move fwd a little & jump + + cmp #$80 + bcc ]rts ;still too far away--wait till next frame + + lda #-3 ;He jumped too late; he'll miss edge +;But let's make it look good anyway +:ok clc + adc #RJChange + + jsr addcharx + sta CharX + +* No edge in sight -- just do any old long jump + +:noedge + jsr ]clr + sta clrU + + lda #runjump + jmp jumpseq + +]rts rts + +*------------------------------- +* +* D o S t e p F o r w a r d +* +*------------------------------- + +DoStepfwd + lda #1 + sta clrF + sta clrbtn + + jsr getfwddist ;returns A = distance to step (0-13) + + cmp #0 + beq :1 + +:2 sta CharRepeat ;non-0 value + + clc + adc #stepfwd1-1 + jmp jumpseq + +:1 cpx #1 + beq :thru ;If barrier, step thru + + cmp CharRepeat + bne :3 ;First time, test w/foot + +:thru lda #11 + bne :2 ;Second time, step off edge + +:3 sta CharRepeat ;0 + + lda #testfoot + jmp jumpseq + +*------------------------------- +* +* D o J u m p H i g h +* +*------------------------------- +DoJumphigh + jsr ]clr + sta clrU + + jsr getfwddist + cmp #4 + bcs :ok + cpx #1 ;barrier? + bne :ok ;no + + sec + sbc #3 + jsr addcharx + sta CharX +:ok + lda #jumpupreach + jsr facedx + sta ztemp + + jsr getbasex ;assume char standing still + clc + adc #jumpupangle + clc + adc ztemp ;get X-coord at which hand touches ceiling + + jsr getblockx + tax + + ldy CharBlockY + dey + + lda CharScrn + jsr rdblock ;read this block + + cmp #block + beq :jumpup + jsr cmpspace + bne :jumpup + + lda #highjump + jmp jumpseq ;no ceiling above + +:jumpup lda #jumpup + jsr jumpseq ;touch ceiling +]rts rts ;& don't forget to crop top + +*------------------------------- +* reread blocks +*------------------------------- +REREADBLOCKS + jsr GetFrameInfo + jmp GetBaseBlock + +*------------------------------- +* +* Is character stepping on a pressure plate? +* or on loose floor? +* +*------------------------------- +CHECKPRESS + lda CharPosn + cmp #87 + bcc :1 + cmp #100 + bcc :hanging ;87-99: jumphang22-34 + cmp #135 + bcc :1 + cmp #141 + bcc :hanging ;135-140: climb up/down +:1 + lda CharAction + cmp #7 + beq :ground ;turning + cmp #5 + beq :ground ;bumped + cmp #2 + bcs ]rts + +* Action code 7, 0 or 1: on the ground + +:ground + lda CharPosn + cmp #79 ;jumpup/touch ceiling + beq :touchceil + + lda Fcheck + and #fcheckmark + beq ]rts ;foot isn't touching floor + +* Standing on a pressplate? + + jsr getunderft +:checkit + cmp #upressplate + beq :PP + cmp #pressplate + bne :notPP + +:PP lda CharLife + bmi :push + jmp jampp ;dead weight +:push jmp pushpp + +:notPP cmp #loose + bne ]rts + + lda #1 + sta alertguard + jmp breakloose + +* Hanging on a pressplate? + +:hanging + jsr getabove + jmp :checkit +]rts rts + +* Jumping up to touch ceiling? + +:touchceil + jsr getabove + + cmp #loose + bne ]rts + + jmp breakloose + +*------------------------------- +* +* C H E C K I M P A L E +* +* Impalement by running or jumping onto spikes +* (Impalement by landing on spikes is covered by +* CHECKFLOOR:falling) +* +*------------------------------- +CHECKIMPALE + ldx CharBlockX + ldy CharBlockY + lda CharScrn + jsr rdblock + cmp #spikes + bne ]rts ;not spikes + + ldx CharPosn + + cpx #7 + bcc ]rts + + cpx #15 + bcs :2 + jmp :running + +:2 cpx #43 ;runjump-10 + beq :jumpland + + cpx #26 ;standjump-19 + beq :jumpland + +]rts rts + +:running + jsr getspikes + cmp #2 + bcc ]rts ;must be springing + bcs :impale + +:jumpland + jsr getspikes ;are spikes lethal? + beq ]rts ;no + +:impale jmp DoImpale + +*------------------------------- +* Impale char on spikes +* +* In: rdblock results +*------------------------------- +DOIMPALE + jsr jamspikes + + ldx CharBlockY + inx + lda FloorY,x + sta CharY ;align char w/floor + + lda tempblockx + jsr getblockej ;edge of spikes + clc + adc #10 + sta CharX + lda #8 + jsr addcharx + sta CharX ;center char on spikes + + lda #0 + sta CharYVel + + lda #Impaled + jsr addsound + + lda #100 + jsr decstr + + lda #impale + jsr jumpseq + jmp animchar + +*------------------------------- +* +* Pick up object +* Return 0 if no result +* +*------------------------------- +TryPickup + jsr getunderft + cmp #flask + beq :2 + cmp #sword + bne :1 +:2 jsr getbehind + jsr cmpspace + beq :no + lda CharX + lda #-14 + jsr addcharx + sta CharX ;move char 1 block back + jsr rereadblocks +:1 jsr getinfront + cmp #flask + beq :pickup + cmp #sword + beq :pickup +:no lda #0 + rts + +:pickup jsr PickItUp + lda #1 + rts + +*------------------------------- +* +* Pick something up +* +* In: rdblock results for object block ("infront") +* +*------------------------------- +PickItUp + ldx CharPosn + cpx #109 ;crouch first, then pick up obj + beq :ok + jsr getfwddist + cpx #2 + beq :0 ;right at edge + jsr addcharx + sta CharX +:0 lda CharFace + bmi :1 + lda #-2 + jsr addcharx + sta CharX ;put char within reach of obj +:1 jmp DoCrouch + +:ok cmp #sword + beq :PickupSword + + lda (BlueSpec),y + lsr + lsr + lsr + lsr + lsr ;potion # (0-7) + jsr RemoveObj + + lda #drinkpotion ;pick up & drink potion + jmp jumpseq + +:PickupSword + lda #-1 ;sword + jsr RemoveObj + + lda #pickupsword + jmp jumpseq ;pick up, brandish & sheathe sword + +*------------------------------- + lst + ds 1 + usr $a9,16,$00,*-org + lst off diff --git a/01 POP Source/Source/CTRLSUBS.S b/01 POP Source/Source/CTRLSUBS.S index 5529791..a57b442 100755 --- a/01 POP Source/Source/CTRLSUBS.S +++ b/01 POP Source/Source/CTRLSUBS.S @@ -1 +1,2120 @@ -* ctrlsubs org = $d000 tr on lst off *------------------------------- * * PRINCE OF PERSIA * Copyright 1989 Jordan Mechner * *------------------------------- * * Misc. subroutines relating to character control & movement * *------------------------------- org org jmp GETFRAME jmp GETSEQ jmp GETBASEX jmp GETBLOCKX jmp GETBLOCKXP jmp GETBLOCKY jmp GETBLOCKEJ jmp ADDCHARX jmp GETDIST jmp GETDIST1 jmp GETABOVEBEH jmp RDBLOCK jmp RDBLOCK1 jmp SETUPSWORD jmp GETSCRNS jmp ADDGUARDOBJ jmp OPJUMPSEQ jmp GETEDGES jmp INDEXCHAR jmp QUICKFG jmp CROPCHAR jmp GETLEFT jmp GETRIGHT jmp GETUP jmp GETDOWN jmp CMPSPACE jmp CMPBARR jmp ADDKIDOBJ jmp ADDSHADOBJ jmp ADDREFLOBJ jmp LOADKID jmp LOADSHAD jmp SAVEKID jmp SAVESHAD jmp SETUPCHAR jmp GETFRAMEINFO jmp INDEXBLOCK jmp MARKRED jmp MARKFRED jmp MARKWIPE jmp MARKMOVE jmp MARKFLOOR jmp UNINDEX jmp QUICKFLOOR jmp UNEVENFLOOR jmp MARKHALF jmp ADDSWORDOBJ jmp GETBLOCKYP jmp CHECKLEDGE jmp GET2INFRONT jmp CHECKSPIKES jmp RECHARGEMETER jmp ADDFCHARX jmp FACEDX jmp JUMPSEQ jmp GETBASEBLOCK jmp LOADKIDWOP jmp SAVEKIDWOP jmp GETOPDIST jmp LOADSHADWOP jmp SAVESHADWOP jmp BOOSTMETER jmp GETUNDERFT jmp GETINFRONT jmp GETBEHIND jmp GETABOVE jmp GETABOVEINF jmp CMPWALL *------------------------------- lst put eq lst put gameeq lst put movedata lst put seqdata lst put soundnames lst off *------------------------------- dum locals tempright ds 1 ztemp ds 2 tempstate ds 1 ]cutdir ds 1 dend *------------------------------- * Misc. data plus1 db -1,1 minus1 db 1,-1 maxmaxstr = 10 ;strength meter maximum thinner = 3 *------------------------------- * * R E A D B L O C K * * In: A = screen # * X = block x (0-9 onscreen) * Y = block y (0-2 onscreen) * * Out: A,X = objid * Y = block # (0-29) * BlueType, BlueSpec set * tempscrn,tempblockx,tempblocky = onscreen block coords * * - Offscreen block values are traced to their home screen * - Screen 0 is treated as a solid mass * *------------------------------- RDBLOCK sta tempscrn stx tempblockx sty tempblocky RDBLOCK1 jsr handler ;handle offscreen references lda tempscrn beq :nullscrn ;screen 0 jsr calcblue ;returns BlueType/Spec ldy tempblocky lda Mult10,y clc adc tempblockx tay lda (BlueType),y and #idmask tax ;return result in X & A rts :nullscrn lda #block tax rts *------------------------------- * Handle offscreen block references (recursive) handler lda tempblockx bpl :1 jsr offleft jmp handler :1 cmp #10 bcc :2 jsr offrt jmp handler :2 lda tempblocky bpl :3 jsr offtop jmp handler :3 cmp #3 bcc :rts jsr offbot jmp handler :rts rts offtop clc adc #3 sta tempblocky lda tempscrn jsr GETUP sta tempscrn rts offbot sec sbc #3 sta tempblocky lda tempscrn jsr GETDOWN sta tempscrn rts offleft clc adc #10 sta tempblockx lda tempscrn jsr GETLEFT sta tempscrn rts offrt sec sbc #10 sta tempblockx lda tempscrn jsr GETRIGHT sta tempscrn ]rts rts *------------------------------- * * Get adjacent screen numbers * * In: A = original screen # * Out: A = adjacent screen # * *------------------------------- GETLEFT beq ]rts asl asl tax lda MAP-4,x ]rts rts GETRIGHT beq ]rts asl asl tax lda MAP-3,x rts GETUP beq ]rts asl asl tax lda MAP-2,x rts GETDOWN beq ]rts asl asl tax lda MAP-1,x rts *------------------------------- * * G E T S C R E E N S * * Get VisScrn's 8 surrounding screens from map * (Store in scrnAbove, scrnBelow, etc.) * *------------------------------- GETSCRNS lda VisScrn jsr GETLEFT sta scrnLeft lda VisScrn jsr GETRIGHT sta scrnRight lda VisScrn jsr GETUP sta scrnAbove lda VisScrn jsr GETDOWN sta scrnBelow * and diagonals lda scrnBelow jsr GETLEFT sta scrnBelowL lda scrnBelow jsr GETRIGHT sta scrnBelowR lda scrnAbove jsr GETLEFT sta scrnAboveL lda scrnAbove jsr GETRIGHT sta scrnAboveR ]rts rts *------------------------------- * * G E T B A S E X * * In: Char data; frame data * * Out: A = character's base X-coord * *------------------------------- GETBASEX lda Fcheck and #Ffootmark ;# pixels to count in from left edge of image eor #$ff clc adc #1 ;- Fcheck clc adc Fdx ;Fdx (+ = fwd, - = bkwd) jmp ADDCHARX ;Add to CharX in direction char is facing *------------------------------- * * Add A to CharX in direction char is facing * * In: A = # pixels to add (+ = fwd, - = bkwd) * CharX = original char X-coord * CharFace = direction char is facing * * Out: A = new char X-coord * *------------------------------- ADDCHARX bit CharFace ;-1 = left (normal) bpl :right ;0 = right (mirrored) eor #$ff clc adc #1 ;A := -A :right clc adc CharX rts *------------------------------- * * Add A to FCharX * (A range: -127 to 127) * * In: A; FChar data * Out: FCharX * *------------------------------- ADDFCHARX sta ztemp bpl :1 ;hibit clr lda #0 sec sbc ztemp sta ztemp ;make it posititve lda #$ff ;hibit set :1 eor FCharFace bmi :left lda ztemp clc adc FCharX sta FCharX lda FCharX+1 adc #0 sta FCharX+1 rts :left lda FCharX sec sbc ztemp sta FCharX lda FCharX+1 sbc #0 sta FCharX+1 rts *------------------------------- * * In: CharFace,CharBlockX,CharBlockY,CharScrn * * Out: Results of RDBLOCK for block underfoot/in front/etc. * *------------------------------- GETUNDERFT ldx CharBlockX ldy CharBlockY lda CharScrn jmp RDBLOCK GETINFRONT ldx CharFace inx lda CharBlockX clc adc plus1,x sta infrontx tax ldy CharBlockY lda CharScrn jmp RDBLOCK GET2INFRONT ldx CharFace inx lda CharBlockX clc adc plus1,x clc adc plus1,x tax ldy CharBlockY lda CharScrn jmp RDBLOCK GETBEHIND ldx CharFace inx lda CharBlockX clc adc minus1,x sta behindx tax ldy CharBlockY lda CharScrn jmp RDBLOCK GETABOVE ldy CharBlockY dey sty abovey ldx CharBlockX lda CharScrn jmp RDBLOCK GETABOVEINF ldx CharFace inx lda CharBlockX clc adc plus1,x sta infrontx tax ldy CharBlockY dey sty abovey lda CharScrn jmp RDBLOCK GETABOVEBEH ldx CharFace inx lda CharBlockX clc adc minus1,x sta behindx tax ldy CharBlockY dey sty abovey lda CharScrn jmp RDBLOCK *------------------------------- * * G E T D I S T A N C E * * In: Char data * * Out: A = # of pixels (0-13) to add to CharX to move * char base X-coord to end of current block * *------------------------------- GETDIST jsr GETBASEX ;returns A = base X-coord GETDIST1 jsr GETBLOCKXP ;returns A = block #, OFFSET = pixel # lda CharFace ;0=right, -1=left beq :facingright :facingleft lda OFFSET rts :facingright lda #13 sec sbc OFFSET rts *------------------------------- * * G E T B L O C K E D G E * * In: A = block # (-5 to 14) * Out: A = screen X-coord of left edge * *------------------------------- GETBLOCKEJ clc adc #5 tax lda BlockEdge,x rts *------------------------------- * * G E T B L O C K X * * In: A = X-coord * * Out: A = # of the 14-pixel-wide block within which * this pixel falls (0-9 onscreen) * * OFFSET = pixel within this block * * - Use GETBLOCKXP for objects on center plane * - Use GETBLOCKX for absolute X-coords & foreground plane * *------------------------------- GETBLOCKXP sec sbc #angle GETBLOCKX tay lda PixelTable,y sta OFFSET lda BlockTable,y rts *------------------------------- * * G E T B L O C K Y * * In: A = screen Y-coord (0-255) * * Out: A = block y (3 = o.s.) * * - Use GETBLOCKYP for objects on center plane * - Use GETBLOCKY for absolute Y-coords & foreground plane * *------------------------------- GETBLOCKY ldx #3 :loop cmp BlockTop+1,x bcs :gotY dex bpl :loop :gotY txa rts GETBLOCKYP ldx #3 :loop cmp FloorY+1,x bcs :gotY dex bpl :loop :gotY txa ]rts rts *------------------------------- * * I N D E X B L O C K * * Index (tempblockx,tempblocky) * * Return y = block # (0-29) and cc if block is onscreen * y = 0 to 9 and cs if block is on screen above * y = 30 and cs if block is o.s. * *------------------------------- INDEXBLOCK ldy tempblocky bmi :above cpy #3 bcs :os lda tempblockx cmp #10 bcs :os ;0 <= tempblockx <= 9 clc adc Mult10,y tay ;return y = block # clc ;and carry clr rts :os ldy #30 sec ;and carry set rts :above ldy tempblockx sec ]rts rts *------------------------------- * * U N I N D E X * * In: A = block index (0-29) * Out: A = blockx, X = blocky * *------------------------------- UNINDEX ldx #0 :loop cmp #10 bcc ]rts sec sbc #10 inx bne :loop ]rts rts *------------------------------- * * G E T B A S E B L O C K * * In: Char data * Out: CharBlockX * *------------------------------- GETBASEBLOCK jsr getbasex jsr getblockxp sta CharBlockX ]rts rts *------------------------------- * * F A C E D X * * In: CharFace; A = DX * * Out: DX if char is facing right, -DX if facing left * *------------------------------- FACEDX bit CharFace bmi ]rts eor #$ff clc adc #1 ;negate ]rts rts *------------------------------- * * J U M P S E Q * * Jump to some other point in sequence table * * In: A = sequence # (1-127) * *------------------------------- JUMPSEQ sec sbc #1 asl tax ;x = 2(a-1) lda seqtab,x sta CharSeq lda seqtab+1,x sta CharSeq+1 ]rts rts *------------------------------- * * Similar routine for Opponent * *------------------------------- OPJUMPSEQ sec sbc #1 asl tax ;x = 2(a-1) lda seqtab,x sta OpSeq lda seqtab+1,x sta OpSeq+1 ]rts rts *------------------------------- * * I N D E X C H A R * * In: Char data; GETEDGES results * * Out: FCharIndex = character block index * *------------------------------- INDEXCHAR lda CharAction cmp #1 bne :4 ;If CharAction = 1 (on solid ground) ;use leftblock/bottomblock lda bottomblock sta tempblocky lda leftblock :1 sta tempblockx lda CharPosn cmp #135 bcc :2 cmp #149 bcc :climbup :2 cmp #2 beq :fall cmp #3 beq :fall cmp #4 beq :fall cmp #6 bne :3 :fall :climbup dec tempblockx ;if falling or climbing up :3 jsr indexblock sty FCharIndex rts * else use CharBlockX/Y :4 lda CharBlockY sta tempblocky lda CharBlockX jmp :1 *------------------------------- * * S E T U P C H A R * * Set up character for FRAMEADV * * In: Char data * Out: FChar data * * Translate char data into the form "addchar" expects * (Decode image #; get actual 280 x 192 screen coords) * *------------------------------- SETUPCHAR jsr zerocrop ;(can call cropchar later) jsr GETFRAMEINFO lda CharFace sta FCharFace jsr decodeim ;get FCharImage & Table from ;encoded Fimage & Fsword data lda #0 sta FCharX+1 lda Fdx jsr addcharx ;A := CharX + Fdx sec sbc #ScrnLeft ;different coord system sta FCharX asl FCharX rol FCharX+1 beq :pos lda FCharX cmp #$f0 bcc :pos lda #$ff sta FCharX+1 :pos ;X := 2X lda Fdy clc adc CharY sec sbc #ScrnTop sta FCharY lda Fcheck eor FCharFace ;Look only at the hibits bmi :ok ;They don't match-->even X-coord ;They match-->odd X-coord lda FCharX clc adc #1 sta FCharX bcc :ok inc FCharX+1 :ok ]rts rts *------------------------------- * * S E T U P S W O R D * * In: Char & FChar data * * If character's sword is visible, add it to obj table * *------------------------------- SETUPSWORD lda CharID cmp #2 bne :3 lda CharLife bmi :2 ;live guard's sword is always visible :3 lda CharPosn cmp #229 bcc :1 cmp #238 bcc :2 ;sheathing :1 lda CharSword beq ]rts :2 lda Fsword and #$3f ;frame # beq ]rts ;no sword for this frame jsr getswordframe ldy #0 lda (framepoint),y beq ]rts jsr decodeswim ;get FCharImage & Table iny lda (framepoint),y sta Fdx iny lda (framepoint),y sta Fdy lda Fdx jsr ADDFCHARX ;A := FCharX + Fdx lda Fdy clc adc FCharY sta FCharY jmp ADDSWORDOBJ *------------------------------- * * G E T F R A M E * * In: A = frame # (1-192) * Out: framepoint = 2-byte pointer to frame def table * *------------------------------- GETFRAME ;Kid uses main char set jsr getfindex lda framepoint clc adc #Fdef sta framepoint lda framepoint+1 adc #>Fdef sta framepoint+1 rts *------------------------------- getaltframe1 ;Enemy uses alt set 1 jsr getfindex lda framepoint clc adc #altset1 sta framepoint lda framepoint+1 adc #>altset1 sta framepoint+1 rts *------------------------------- getaltframe2 ;Princess & Vizier use alt set 2 jsr getfindex lda framepoint clc adc #altset2 sta framepoint lda framepoint+1 adc #>altset2 sta framepoint+1 rts *------------------------------- getfindex sec sbc #1 sta ztemp sta framepoint lda #0 sta ztemp+1 sta framepoint+1 asl framepoint rol framepoint+1 asl framepoint rol framepoint+1 ;2-byte multiply by 4 lda framepoint clc adc ztemp sta framepoint lda framepoint+1 adc ztemp+1 sta framepoint+1 ;make it x5 rts *------------------------------- * * getswordframe * * In: A = frame # * Out: framepoint * *------------------------------- getswordframe sec sbc #1 sta ztemp sta framepoint lda #0 sta ztemp+1 sta framepoint+1 asl framepoint rol framepoint+1 ;x2 lda framepoint clc adc ztemp sta framepoint lda framepoint+1 adc ztemp+1 sta framepoint+1 ;+1 is 3 lda framepoint clc adc #swordtab sta framepoint lda framepoint+1 adc #>swordtab sta framepoint+1 rts *------------------------------- * * Decode char image * * In: Fimage, Fsword (encoded) * * Out: FCharImage (image #, 0-127) * FCharTable (table #, 0-7) * *------------------------------- decodeim lda Fimage and #%10000000 ;bit 2 of table # sta ztemp lda Fsword and #%11000000 ;bits 0-1 of table # lsr adc ztemp lsr lsr lsr lsr lsr sta FCharTable lda Fimage and #$7f ora timebomb ;must be 0! sta FCharImage rts *------------------------------- * * Decode sword image * * In: A = image # * * Out: FCharImage, FCharTable * *------------------------------- decodeswim sta FCharImage ;image # lda #2 ;chtable3 sta FCharTable rts *------------------------------- * * G E T E D G E S * * Get edges of character image * * In: FChar data as set by "setframe" * * Out: leftej/rightej/topej = boundaries of image (140-res) * leftblock, rightblock, topblock, bottomblock * CDLeftEj, CDRightEj (for coll detection) * imheight, imwidth * *------------------------------- GETEDGES lda FCharImage ldx FCharTable jsr dimchar ;return A = image width, x = height stx imheight tax ;image width in bytes lda Mult7,x ;in 1/2 pixels clc adc #1 ;add 1/2 pixel lsr ;and divide by 2 sta imwidth ;to get width in pixels lda FCharX+1 lsr lda FCharX ror clc adc #ScrnLeft ;convert back to 140-res * (If facing LEFT, X-coord is leftmost pixel of LEFTMOST byte * of image; if facing RIGHT, leftmost pixel of RIGHTMOST byte.) ldx CharFace bmi :ok ;facing L ;facing R sec sbc imwidth :ok sta leftej clc adc imwidth sta rightej lda FCharY sec sbc imheight clc adc #1 cmp #192 bcc :ok2 lda #0 :ok2 sta topej jsr getblocky cmp #3 bne :1 lda #-1 ;if o.s., call it -1 :1 sta topblock lda FCharY jsr getblocky ;if o.s., call it 3 sta bottomblock lda leftej jsr getblockx ;leftmost affected block sta leftblock lda rightej jsr getblockx ;rightmost affected block sta rightblock * get leading edge (for collision detection) lda #0 sta ztemp lda Fcheck and #Fthinmark beq :nothin lda #thinner ;make character 3 bits thinner sta ztemp ;on both sides :nothin lda leftej clc adc ztemp sta CDLeftEj lda rightej sec sbc ztemp sta CDRightEj ]rts rts *=============================== * * Q U I C K F L O O R * * Mark for redraw whatever floorpieces character might be * impinging on * * In: CharData; GETEDGES results * *------------------------------- QUICKFLOOR lda CharPosn cmp #135 bcc :2 cmp #149 bcc :climbup :2 lda CharAction cmp #1 bne :1 lda CharPosn cmp #78 bcc ]rts cmp #80 bcc :fall ]rts rts :1 cmp #2 beq :fall cmp #3 beq :fall cmp #4 beq :fall cmp #6 bne ]rts :fall lda #markfloor ldx #>markfloor bne :cont1 :climbup lda #markhalf ldx #>markhalf * Mark floorbuf/halfbuf for up to 6 affected blocks * Start with rightblock, work left to leftblock :cont1 sta marksm1+1 sta marksm2+1 stx marksm1+2 stx marksm2+2 lda rightblock :loop sta tempblockx jsr markul lda tempblockx cmp leftblock beq ]rts sec sbc #1 bpl :loop ]rts rts * mark upper & lower blocks for this blockx markul lda bottomblock sta tempblocky jsr indexblock ;lower block lda #2 marksm1 jsr markhalf lda topblock cmp bottomblock beq ]rts sta tempblocky jsr indexblock ;upper block lda #2 marksm2 jmp markhalf *------------------------------- * * Q U I C K F G * * Mark for redraw any f.g. elements char (or his sword) * might be impinging on * * In: Char data; left/right/top/bottomblock * *------------------------------- QUICKFG * Quick fix to cover sword lda CharSword cmp #2 bcc :cont lda CharFace bpl :faceR dec leftblock jmp :cont :faceR inc rightblock * Continue :cont lda bottomblock :outloop sta tempblocky lda rightblock :loop sta tempblockx jsr indexblock lda #3 jsr MARKFRED lda tempblockx cmp leftblock beq :end sec sbc #1 bpl :loop :end lda tempblocky cmp topblock beq ]rts sec sbc #1 bpl :outloop rts ]bug jmp showpage *------------------------------- * * C R O P C H A R A C T E R * * In: FChar data as set by "setframe" * leftej,rightej, etc. as set by "getedges" * * Out: FCharCL/CR/CU/CD * *------------------------------- CROPCHAR * If char is climbing stairs, mask door lda CharPosn cmp #224 bcc :nost cmp #229 bcs :nost lda doortop ;set by drawexitb clc adc #2 cmp FCharY bcs :bug ;temp! sta FCharCU ]rts rts :bug ldy #$F0 jsr showpage :nost * If char is under solid (a&b) floor, crop top ldx leftblock ldy topblock lda CharScrn jsr rdblock cmp #block beq :1 jsr cmpspace beq :not * Special case (more lenient): if char is jumping * up to touch ceiling :1 lda CharAction bne :10 lda CharPosn cmp #79 beq :2 cmp #81 bne :10 beq :2 * Otherwise, both left & right topblocks must be solid :10 ldx rightblock ldy topblock lda CharScrn jsr rdblock cmp #block beq :2 jsr cmpspace beq :not :2 ldx CharBlockY inx cpx #1 beq :ok lda BlockTop,x cmp FCharY bcs :not sec sbc #floorheight cmp topej bcs :not :ok lda BlockTop,x sta FCharCU sta topej :not * If char is standing left of a panel, crop R * Char is considered "left" if CDLeftEj falls within * panel block lda CDLeftEj jsr getblockx sta blockx tax ldy CharBlockY lda CharScrn jsr rdblock cmp #panelwof beq :r cmp #panelwif bne :nor * Char's foot is within panel block * Special case: If character is hanging R, we don't * need to check his head :r lda CharFace bmi :cont lda CharAction cmp #2 beq :r2 ;yes--hanging R * Check block to right of char's head :cont ldx blockx ldy topblock lda CharScrn jsr rdblock cmp #block beq :r2 cmp #panelwof beq :r2 cmp #panelwif bne :nor * Also a panel -- make a wall :r2 lda tempblockx asl asl clc adc #4 sta FCharCR rts * Is char standing to L of solid block? * (i.e. does CDRightEj fall within block?) :nor lda CDRightEj jsr getblockx sta blockx tax ldy CharBlockY lda CharScrn jsr rdblock cmp #block bne :nob * Foot is under block--what about head? ldx blockx ldy topblock lda CharScrn jsr rdblock cmp #block bne :nob * Also a panel -- make a wall :yescrop lda tempscrn cmp CharScrn bne :nob lda tempblockx asl asl sta FCharCR :nob rts *------------------------------- * * Z E R O C R O P * *------------------------------- zerocrop lda #0 sta FCharCU sta FCharCL lda #40 sta FCharCR lda #192 sta FCharCD rts *=============================== * * C O M P A R E S P A C E * * Is it a space (can you pass thru)? * NOTE: Solid block is considered a space (it has no floor) * * In: A = objid * Out: 0 = space, 1 = floor * *------------------------------- CMPSPACE cmp #space beq :space cmp #pillartop beq :space cmp #panelwof beq :space cmp #block beq :space cmp #archtop1 bcs :space lda #1 rts :space lda #0 rts *------------------------------- * * C O M P A R E B A R R I E R * * Is it a barrier? * * Return A = 0 if clear, else A = barrier code # * *------------------------------- CMPBARR cmp #panelwif beq :b1 cmp #panelwof beq :b1 cmp #gate bne :2 :b1 lda #1 ;panel/gate rts :2 cmp #mirror beq :yes3 cmp #slicer bne :3 :yes3 lda #3 ;mirror/slicer rts :3 cmp #block bne :4 lda #4 ;block rts :4 :clear lda #0 :rts rts :barr lda #1 ]rts rts *------------------------------- * * Is it a wall? Return 0 if yes, 1 if no * (Solid block, or panel if you're facing L) * *------------------------------- CMPWALL cmp #block beq :yes ldx CharFace bpl :no cmp #panelwif beq :yes cmp #panelwof beq :yes :no lda #1 rts :yes lda #0 rts *------------------------------- * * Add kid/reflection/shadowman/guard to object table * * In: FChar data * *------------------------------- ADDKIDOBJ lda #TypeKid jmp addcharobj *------------------------------- ADDREFLOBJ lda #TypeReflect jmp addcharobj *------------------------------- ADDSHADOBJ lda #TypeShad jmp addcharobj *------------------------------- ADDGUARDOBJ lda #TypeGd jmp addcharobj *------------------------------- * * Add sword to object table * In: FChar data for character holding sword * *------------------------------- ADDSWORDOBJ lda #TypeSword jmp addcharobj *------------------------------- * * G E T S E Q * * Get next byte from seqtable & advance CharSeq * (2-byte pointer to sequence table) * *------------------------------- GETSEQ ldy #0 lda (CharSeq),y pha inc CharSeq bne :done inc CharSeq+1 :done pla rts *------------------------------- * * G E T F R A M E I N F O * * Get frame info for char (based on CharPosn) * *------------------------------- GETFRAMEINFO lda CharPosn jsr GETFRAME ;set framepoint jsr usealtsets ;if appropriate ldy #0 lda (framepoint),y sta Fimage iny lda (framepoint),y sta Fsword iny lda (framepoint),y sta Fdx iny lda (framepoint),y sta Fdy iny lda (framepoint),y sta Fcheck ]rts rts *------------------------------- * * Use alternate character image sets * (if appropriate) * * In: Char data; framepoint * Out: framepoint * *------------------------------- usealtsets ldx CharID beq ]rts ;kid uses main set, enemy uses alt set 1 cpx #24 beq ]rts ;mouse uses main set cpx #5 bcs :usealt2 ;princess & vizier use alt set 2 lda CharPosn cpx #2 bcc :1 cmp #102 bcc ]rts cmp #107 bcs :1 ;frames 102-106 (falling): substitute 172-176 altset clc adc #70 :1 cmp #150 bcc ]rts cmp #190 bcs ]rts ;frames 150-189: use altset sec sbc #149 jmp getaltframe1 :usealt2 lda CharPosn jmp getaltframe2 *=============================== * * M A R K * * In: A = mark value (usually 2) * Results of INDEXBLOCK: * Y = block #; carry set or clear * * Out: Preserve A, Y, carry * *------------------------------- ]os cpy #10 ;top line from scrn above? bcs ]rts ;no sta topbuf,y sec ;preserve cs ]rts rts MARKRED bcs ]os sta redbuf,y rts MARKFRED bcs ]rts sta fredbuf,y rts MARKWIPE bcs ]rts pha lda wipebuf,y beq :2 lda height cmp whitebuf,y ;if wipebuf is already marked, bcc :1 ;use larger of 2 whitebuf values :2 lda height sta whitebuf,y :1 pla sta wipebuf,y clc ;return with cc rts MARKMOVE bcs ]os sta movebuf,y rts MARKFLOOR bcs ]os sta floorbuf,y rts MARKHALF bcs ]os sta halfbuf,y 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 wipebuf,y sta movebuf,y sta objbuf,y sta halfbuf,y dey bpl :loop ldy #9 :dloop sta topbuf,y dey bpl :dloop rts *------------------------------- * * C H E C K L E D G E * * In: blockid = block that must be clear; * A = RDBLOCK results for block that must be ledge * * Out: A = 1 if grabbable, 0 if not * *------------------------------- CHECKLEDGE sta ztemp lda (BlueSpec),y sta tempstate lda blockid ;must be clear cmp #block beq :no cmp #panelwof ;CMPSPACE considers panel w/o floor bne :cont ;to be clear-- bit CharFace ;but it isn't if char wants to grab bpl :no ;floorpiece to right :cont jsr cmpspace bne :no * Clear above -- is there a ledge in front? lda ztemp ;must be a solid floorpiece ;with exposed ledge cmp #loose bne :notloose bit tempstate bne :no ;floor is already loose :notloose cmp #panelwif bne :cont2 ;panel w/floor can be grabbed ;only if facing right bit CharFace bmi :no :cont2 jsr cmpspace beq :no :yes lda #1 rts :no lda #0 ]rts rts *------------------------------- * * C H E C K S P I K E S * * Spikes spring out when char passes over them (at any * height). * *------------------------------- CHECKSPIKES lda rightej jsr getblockxp bmi ]rts sta tempright * for blockx = leftblock to rightblock lda leftej jsr getblockxp :loop sta blockx jsr sub lda blockx cmp tempright beq ]rts clc adc #1 jmp :loop sub sta tempblockx lda CharBlockY sta tempblocky lda CharScrn sta tempscrn :loop jsr rdblock1 cmp #spikes bne :again jmp trigspikes :again jsr cmpspace bne ]rts lda tempscrn beq ]rts ;null scrn cmp CharScrn bne ]rts ;wait till he's on same screen inc tempblocky jmp :loop ;check 1 level below *=============================== * * Load/save kid/shad vars * *------------------------------- numvars = 16 LOADKID ldx #numvars-1 :loop lda Kid,x sta Char,x dex bpl :loop ]rts rts SAVEKID ldx #numvars-1 :loop lda Char,x sta Kid,x dex bpl :loop ]rts rts LOADSHAD ldx #numvars-1 :loop lda Shad,x sta Char,x dex bpl :loop ]rts rts SAVESHAD ldx #numvars-1 :loop lda Char,x sta Shad,x dex bpl :loop rts * Load kid w/ opponent LOADKIDWOP ldx #numvars-1 :loop lda Kid,x sta Char,x lda Shad,x sta Op,x dex bpl :loop rts SAVEKIDWOP ldx #numvars-1 :loop lda Char,x sta Kid,x lda Op,x sta Shad,x dex bpl :loop rts * Load shadowman w/ opponent LOADSHADWOP ldx #numvars-1 :loop lda Shad,x sta Char,x lda Kid,x sta Op,x dex bpl :loop rts SAVESHADWOP ldx #numvars-1 :loop lda Char,x sta Shad,x lda Op,x sta Kid,x dex bpl :loop rts *------------------------------- * * Recharge strength meter to max * *------------------------------- RECHARGEMETER lda MaxKidStr sec sbc KidStrength sta ChgKidStr ]rts rts *------------------------------- * * Boost strength meter max by 1 and recharge * *------------------------------- BOOSTMETER lda MaxKidStr cmp #maxmaxstr bcs :1 clc adc #1 sta MaxKidStr :1 jmp RECHARGEMETER *------------------------------- * * Get distance between char & opponent * (# pixels char must move fwd to reach opponent) * If dist is greater than 127, return 127 (+ or -) * *------------------------------- estwidth = 13 ;rough est of char width GETOPDIST lda CharScrn cmp OpScrn bne :safe * First, get A = OpX-CharX (abs. value <= 127) lda OpX cmp CharX bcc :neg sec sbc CharX bpl :got lda #127 bpl :got :neg lda CharX sec sbc OpX bpl :1 lda #127 :1 eor #$ff clc adc #1 ;negate * If CharFace = left, negate :got ldx CharFace bpl :cont eor #$ff clc adc #1 * If chars are facing in opposite directions, * adjust by estimate of width of figure :cont tax lda CharFace eor OpFace bpl :done txa cmp #127-estwidth bcs :done2 clc adc #estwidth :done2 tax rts :safe ldx #127 ;arbitrary large dist. :done txa ;return value in A ]rts rts *------------------------------- * * Adjust CharY for uneven floor * *------------------------------- UNEVENFLOOR jsr getunderft cmp #dpressplate bne ]rts inc CharY ]rts rts *------------------------------- lst ds 1 usr $a9,19,$200,*-org lst off \ No newline at end of file +* ctrlsubs +org = $d000 + tr on + lst off +*------------------------------- +* +* PRINCE OF PERSIA +* Copyright 1989 Jordan Mechner +* +*------------------------------- +* +* Misc. subroutines relating to character control & movement +* +*------------------------------- + org org + + jmp GETFRAME + jmp GETSEQ + jmp GETBASEX + jmp GETBLOCKX + jmp GETBLOCKXP + + jmp GETBLOCKY + jmp GETBLOCKEJ + jmp ADDCHARX + jmp GETDIST + jmp GETDIST1 + + jmp GETABOVEBEH + jmp RDBLOCK + jmp RDBLOCK1 + jmp SETUPSWORD + jmp GETSCRNS + + jmp ADDGUARDOBJ + jmp OPJUMPSEQ + jmp GETEDGES + jmp INDEXCHAR + jmp QUICKFG + + jmp CROPCHAR + jmp GETLEFT + jmp GETRIGHT + jmp GETUP + jmp GETDOWN + + jmp CMPSPACE + jmp CMPBARR + jmp ADDKIDOBJ + jmp ADDSHADOBJ + jmp ADDREFLOBJ + + jmp LOADKID + jmp LOADSHAD + jmp SAVEKID + jmp SAVESHAD + jmp SETUPCHAR + + jmp GETFRAMEINFO + jmp INDEXBLOCK + jmp MARKRED + jmp MARKFRED + jmp MARKWIPE + + jmp MARKMOVE + jmp MARKFLOOR + jmp UNINDEX + jmp QUICKFLOOR + jmp UNEVENFLOOR + + jmp MARKHALF + jmp ADDSWORDOBJ + jmp GETBLOCKYP + jmp CHECKLEDGE + jmp GET2INFRONT + + jmp CHECKSPIKES + jmp RECHARGEMETER + jmp ADDFCHARX + jmp FACEDX + jmp JUMPSEQ + + jmp GETBASEBLOCK + jmp LOADKIDWOP + jmp SAVEKIDWOP + jmp GETOPDIST + jmp LOADSHADWOP + + jmp SAVESHADWOP + jmp BOOSTMETER + jmp GETUNDERFT + jmp GETINFRONT + jmp GETBEHIND + + jmp GETABOVE + jmp GETABOVEINF + jmp CMPWALL + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put movedata + lst + put seqdata + lst + put soundnames + lst off + +*------------------------------- + dum locals + +tempright ds 1 +ztemp ds 2 +tempstate ds 1 +]cutdir ds 1 + + dend + +*------------------------------- +* Misc. data + +plus1 db -1,1 +minus1 db 1,-1 + +maxmaxstr = 10 ;strength meter maximum + +thinner = 3 + +*------------------------------- +* +* R E A D B L O C K +* +* In: A = screen # +* X = block x (0-9 onscreen) +* Y = block y (0-2 onscreen) +* +* Out: A,X = objid +* Y = block # (0-29) +* BlueType, BlueSpec set +* tempscrn,tempblockx,tempblocky = onscreen block coords +* +* - Offscreen block values are traced to their home screen +* - Screen 0 is treated as a solid mass +* +*------------------------------- +RDBLOCK + sta tempscrn + stx tempblockx + sty tempblocky + +RDBLOCK1 + jsr handler ;handle offscreen references + + lda tempscrn + beq :nullscrn ;screen 0 + jsr calcblue ;returns BlueType/Spec + + ldy tempblocky + lda Mult10,y + clc + adc tempblockx + tay + lda (BlueType),y + and #idmask + tax ;return result in X & A + rts + +:nullscrn lda #block + tax + rts + +*------------------------------- +* Handle offscreen block references (recursive) + +handler lda tempblockx + bpl :1 + jsr offleft + jmp handler + +:1 cmp #10 + bcc :2 + jsr offrt + jmp handler + +:2 lda tempblocky + bpl :3 + jsr offtop + jmp handler + +:3 cmp #3 + bcc :rts + jsr offbot + jmp handler + +:rts rts + +offtop clc + adc #3 + sta tempblocky + + lda tempscrn + jsr GETUP + sta tempscrn + rts + +offbot sec + sbc #3 + sta tempblocky + + lda tempscrn + jsr GETDOWN + sta tempscrn + rts + +offleft clc + adc #10 + sta tempblockx + + lda tempscrn + jsr GETLEFT + sta tempscrn + rts + +offrt sec + sbc #10 + sta tempblockx + + lda tempscrn + jsr GETRIGHT + sta tempscrn +]rts rts + +*------------------------------- +* +* Get adjacent screen numbers +* +* In: A = original screen # +* Out: A = adjacent screen # +* +*------------------------------- +GETLEFT + beq ]rts + asl + asl + tax + lda MAP-4,x +]rts rts + +GETRIGHT + beq ]rts + asl + asl + tax + lda MAP-3,x + rts + +GETUP + beq ]rts + asl + asl + tax + lda MAP-2,x + rts + +GETDOWN + beq ]rts + asl + asl + tax + lda MAP-1,x + rts + +*------------------------------- +* +* G E T S C R E E N S +* +* Get VisScrn's 8 surrounding screens from map +* (Store in scrnAbove, scrnBelow, etc.) +* +*------------------------------- +GETSCRNS + lda VisScrn + jsr GETLEFT + sta scrnLeft + + lda VisScrn + jsr GETRIGHT + sta scrnRight + + lda VisScrn + jsr GETUP + sta scrnAbove + + lda VisScrn + jsr GETDOWN + sta scrnBelow + +* and diagonals + + lda scrnBelow + jsr GETLEFT + sta scrnBelowL + + lda scrnBelow + jsr GETRIGHT + sta scrnBelowR + + lda scrnAbove + jsr GETLEFT + sta scrnAboveL + + lda scrnAbove + jsr GETRIGHT + sta scrnAboveR +]rts rts + +*------------------------------- +* +* G E T B A S E X +* +* In: Char data; frame data +* +* Out: A = character's base X-coord +* +*------------------------------- +GETBASEX + lda Fcheck + and #Ffootmark + ;# pixels to count in from left edge of image + eor #$ff + clc + adc #1 ;- Fcheck + + clc + adc Fdx ;Fdx (+ = fwd, - = bkwd) + + jmp ADDCHARX ;Add to CharX in direction char is facing + +*------------------------------- +* +* Add A to CharX in direction char is facing +* +* In: A = # pixels to add (+ = fwd, - = bkwd) +* CharX = original char X-coord +* CharFace = direction char is facing +* +* Out: A = new char X-coord +* +*------------------------------- +ADDCHARX + bit CharFace ;-1 = left (normal) + bpl :right ;0 = right (mirrored) + + eor #$ff + clc + adc #1 ;A := -A + +:right clc + adc CharX + rts + +*------------------------------- +* +* Add A to FCharX +* (A range: -127 to 127) +* +* In: A; FChar data +* Out: FCharX +* +*------------------------------- +ADDFCHARX + sta ztemp + bpl :1 ;hibit clr + + lda #0 + sec + sbc ztemp + sta ztemp ;make it posititve + + lda #$ff ;hibit set +:1 eor FCharFace + bmi :left + + lda ztemp + clc + adc FCharX + sta FCharX + + lda FCharX+1 + adc #0 + sta FCharX+1 + rts + +:left lda FCharX + sec + sbc ztemp + sta FCharX + + lda FCharX+1 + sbc #0 + sta FCharX+1 + rts + +*------------------------------- +* +* In: CharFace,CharBlockX,CharBlockY,CharScrn +* +* Out: Results of RDBLOCK for block underfoot/in front/etc. +* +*------------------------------- +GETUNDERFT + ldx CharBlockX + ldy CharBlockY + lda CharScrn + jmp RDBLOCK + +GETINFRONT + ldx CharFace + inx + lda CharBlockX + clc + adc plus1,x + sta infrontx + tax + + ldy CharBlockY + lda CharScrn + jmp RDBLOCK + +GET2INFRONT + ldx CharFace + inx + lda CharBlockX + clc + adc plus1,x + clc + adc plus1,x + tax + + ldy CharBlockY + lda CharScrn + jmp RDBLOCK + +GETBEHIND + ldx CharFace + inx + lda CharBlockX + clc + adc minus1,x + sta behindx + tax + + ldy CharBlockY + lda CharScrn + jmp RDBLOCK + +GETABOVE + ldy CharBlockY + dey + sty abovey + + ldx CharBlockX + lda CharScrn + jmp RDBLOCK + +GETABOVEINF + ldx CharFace + inx + lda CharBlockX + clc + adc plus1,x + sta infrontx + tax + + ldy CharBlockY + dey + sty abovey + + lda CharScrn + jmp RDBLOCK + +GETABOVEBEH + ldx CharFace + inx + lda CharBlockX + clc + adc minus1,x + sta behindx + tax + + ldy CharBlockY + dey + sty abovey + + lda CharScrn + jmp RDBLOCK + +*------------------------------- +* +* G E T D I S T A N C E +* +* In: Char data +* +* Out: A = # of pixels (0-13) to add to CharX to move +* char base X-coord to end of current block +* +*------------------------------- +GETDIST + jsr GETBASEX ;returns A = base X-coord + +GETDIST1 + jsr GETBLOCKXP ;returns A = block #, OFFSET = pixel # + + lda CharFace ;0=right, -1=left + beq :facingright + +:facingleft + lda OFFSET + rts + +:facingright + lda #13 + sec + sbc OFFSET + rts + +*------------------------------- +* +* G E T B L O C K E D G E +* +* In: A = block # (-5 to 14) +* Out: A = screen X-coord of left edge +* +*------------------------------- +GETBLOCKEJ + clc + adc #5 + tax + lda BlockEdge,x + rts + +*------------------------------- +* +* G E T B L O C K X +* +* In: A = X-coord +* +* Out: A = # of the 14-pixel-wide block within which +* this pixel falls (0-9 onscreen) +* +* OFFSET = pixel within this block +* +* - Use GETBLOCKXP for objects on center plane +* - Use GETBLOCKX for absolute X-coords & foreground plane +* +*------------------------------- +GETBLOCKXP + sec + sbc #angle + +GETBLOCKX + tay + + lda PixelTable,y + sta OFFSET + + lda BlockTable,y + rts + +*------------------------------- +* +* G E T B L O C K Y +* +* In: A = screen Y-coord (0-255) +* +* Out: A = block y (3 = o.s.) +* +* - Use GETBLOCKYP for objects on center plane +* - Use GETBLOCKY for absolute Y-coords & foreground plane +* +*------------------------------- +GETBLOCKY + ldx #3 +:loop cmp BlockTop+1,x + bcs :gotY + dex + bpl :loop +:gotY txa + rts + + +GETBLOCKYP + ldx #3 +:loop cmp FloorY+1,x + bcs :gotY + dex + bpl :loop +:gotY txa +]rts rts + +*------------------------------- +* +* I N D E X B L O C K +* +* Index (tempblockx,tempblocky) +* +* Return y = block # (0-29) and cc if block is onscreen +* y = 0 to 9 and cs if block is on screen above +* y = 30 and cs if block is o.s. +* +*------------------------------- +INDEXBLOCK + ldy tempblocky + bmi :above + cpy #3 + bcs :os + + lda tempblockx + cmp #10 + bcs :os ;0 <= tempblockx <= 9 + + clc + adc Mult10,y + + tay ;return y = block # + clc ;and carry clr + rts + +:os ldy #30 + sec ;and carry set + rts + +:above ldy tempblockx + sec +]rts rts + +*------------------------------- +* +* U N I N D E X +* +* In: A = block index (0-29) +* Out: A = blockx, X = blocky +* +*------------------------------- +UNINDEX + ldx #0 +:loop cmp #10 + bcc ]rts + sec + sbc #10 + inx + bne :loop +]rts rts + +*------------------------------- +* +* G E T B A S E B L O C K +* +* In: Char data +* Out: CharBlockX +* +*------------------------------- +GETBASEBLOCK + jsr getbasex + jsr getblockxp + sta CharBlockX +]rts rts + +*------------------------------- +* +* F A C E D X +* +* In: CharFace; A = DX +* +* Out: DX if char is facing right, -DX if facing left +* +*------------------------------- +FACEDX + bit CharFace + bmi ]rts + + eor #$ff + clc + adc #1 ;negate + +]rts rts + +*------------------------------- +* +* J U M P S E Q +* +* Jump to some other point in sequence table +* +* In: A = sequence # (1-127) +* +*------------------------------- +JUMPSEQ + sec + sbc #1 + asl + tax ;x = 2(a-1) + + lda seqtab,x + sta CharSeq + + lda seqtab+1,x + sta CharSeq+1 +]rts rts + +*------------------------------- +* +* Similar routine for Opponent +* +*------------------------------- +OPJUMPSEQ + sec + sbc #1 + asl + tax ;x = 2(a-1) + + lda seqtab,x + sta OpSeq + + lda seqtab+1,x + sta OpSeq+1 +]rts rts + +*------------------------------- +* +* I N D E X C H A R +* +* In: Char data; GETEDGES results +* +* Out: FCharIndex = character block index +* +*------------------------------- +INDEXCHAR + lda CharAction + cmp #1 + bne :4 +;If CharAction = 1 (on solid ground) +;use leftblock/bottomblock + lda bottomblock + sta tempblocky + + lda leftblock +:1 sta tempblockx + + lda CharPosn + cmp #135 + bcc :2 + cmp #149 + bcc :climbup + +:2 cmp #2 + beq :fall + cmp #3 + beq :fall + cmp #4 + beq :fall + cmp #6 + bne :3 +:fall +:climbup dec tempblockx ;if falling or climbing up + +:3 jsr indexblock + sty FCharIndex + rts + +* else use CharBlockX/Y + +:4 lda CharBlockY + sta tempblocky + + lda CharBlockX + jmp :1 + +*------------------------------- +* +* S E T U P C H A R +* +* Set up character for FRAMEADV +* +* In: Char data +* Out: FChar data +* +* Translate char data into the form "addchar" expects +* (Decode image #; get actual 280 x 192 screen coords) +* +*------------------------------- +SETUPCHAR + jsr zerocrop ;(can call cropchar later) + + jsr GETFRAMEINFO + + lda CharFace + sta FCharFace + + jsr decodeim ;get FCharImage & Table from + ;encoded Fimage & Fsword data + lda #0 + sta FCharX+1 + + lda Fdx + jsr addcharx ;A := CharX + Fdx + sec + sbc #ScrnLeft ;different coord system + sta FCharX + + asl FCharX + rol FCharX+1 + beq :pos + + lda FCharX + cmp #$f0 + bcc :pos + lda #$ff + sta FCharX+1 +:pos ;X := 2X + lda Fdy + clc + adc CharY + sec + sbc #ScrnTop + sta FCharY + + lda Fcheck + eor FCharFace ;Look only at the hibits + bmi :ok ;They don't match-->even X-coord +;They match-->odd X-coord + lda FCharX + clc + adc #1 + sta FCharX + bcc :ok + inc FCharX+1 +:ok +]rts rts + +*------------------------------- +* +* S E T U P S W O R D +* +* In: Char & FChar data +* +* If character's sword is visible, add it to obj table +* +*------------------------------- +SETUPSWORD + lda CharID + cmp #2 + bne :3 + lda CharLife + bmi :2 ;live guard's sword is always visible + +:3 lda CharPosn + cmp #229 + bcc :1 + cmp #238 + bcc :2 ;sheathing +:1 lda CharSword + beq ]rts +:2 + lda Fsword + and #$3f ;frame # + beq ]rts ;no sword for this frame + + jsr getswordframe + + ldy #0 + lda (framepoint),y + beq ]rts + + jsr decodeswim ;get FCharImage & Table + + iny + lda (framepoint),y + sta Fdx + + iny + lda (framepoint),y + sta Fdy + + lda Fdx + jsr ADDFCHARX ;A := FCharX + Fdx + + lda Fdy + clc + adc FCharY + sta FCharY + + jmp ADDSWORDOBJ + +*------------------------------- +* +* G E T F R A M E +* +* In: A = frame # (1-192) +* Out: framepoint = 2-byte pointer to frame def table +* +*------------------------------- +GETFRAME ;Kid uses main char set + jsr getfindex + lda framepoint + clc + adc #Fdef + sta framepoint + lda framepoint+1 + adc #>Fdef + sta framepoint+1 + rts + +*------------------------------- +getaltframe1 ;Enemy uses alt set 1 + jsr getfindex + lda framepoint + clc + adc #altset1 + sta framepoint + lda framepoint+1 + adc #>altset1 + sta framepoint+1 + rts + +*------------------------------- +getaltframe2 ;Princess & Vizier use alt set 2 + jsr getfindex + lda framepoint + clc + adc #altset2 + sta framepoint + lda framepoint+1 + adc #>altset2 + sta framepoint+1 + rts + +*------------------------------- +getfindex + sec + sbc #1 + sta ztemp + sta framepoint + + lda #0 + sta ztemp+1 + sta framepoint+1 + + asl framepoint + rol framepoint+1 + asl framepoint + rol framepoint+1 ;2-byte multiply by 4 + + lda framepoint + clc + adc ztemp + sta framepoint + + lda framepoint+1 + adc ztemp+1 + sta framepoint+1 ;make it x5 + rts + +*------------------------------- +* +* getswordframe +* +* In: A = frame # +* Out: framepoint +* +*------------------------------- +getswordframe + sec + sbc #1 + sta ztemp + sta framepoint + + lda #0 + sta ztemp+1 + sta framepoint+1 + + asl framepoint + rol framepoint+1 ;x2 + + lda framepoint + clc + adc ztemp + sta framepoint + + lda framepoint+1 + adc ztemp+1 + sta framepoint+1 ;+1 is 3 + + lda framepoint + clc + adc #swordtab + sta framepoint + + lda framepoint+1 + adc #>swordtab + sta framepoint+1 + + rts + +*------------------------------- +* +* Decode char image +* +* In: Fimage, Fsword (encoded) +* +* Out: FCharImage (image #, 0-127) +* FCharTable (table #, 0-7) +* +*------------------------------- +decodeim + lda Fimage + and #%10000000 ;bit 2 of table # + sta ztemp + + lda Fsword + and #%11000000 ;bits 0-1 of table # + + lsr + adc ztemp + lsr + lsr + lsr + lsr + lsr + sta FCharTable + + lda Fimage + and #$7f + ora timebomb ;must be 0! + sta FCharImage + + rts + +*------------------------------- +* +* Decode sword image +* +* In: A = image # +* +* Out: FCharImage, FCharTable +* +*------------------------------- +decodeswim + sta FCharImage ;image # + + lda #2 ;chtable3 + sta FCharTable + rts + +*------------------------------- +* +* G E T E D G E S +* +* Get edges of character image +* +* In: FChar data as set by "setframe" +* +* Out: leftej/rightej/topej = boundaries of image (140-res) +* leftblock, rightblock, topblock, bottomblock +* CDLeftEj, CDRightEj (for coll detection) +* imheight, imwidth +* +*------------------------------- +GETEDGES + lda FCharImage + ldx FCharTable + jsr dimchar ;return A = image width, x = height + stx imheight + + tax ;image width in bytes + lda Mult7,x ;in 1/2 pixels + clc + adc #1 ;add 1/2 pixel + lsr ;and divide by 2 + sta imwidth ;to get width in pixels + + lda FCharX+1 + lsr + lda FCharX + ror + clc + adc #ScrnLeft ;convert back to 140-res + +* (If facing LEFT, X-coord is leftmost pixel of LEFTMOST byte +* of image; if facing RIGHT, leftmost pixel of RIGHTMOST byte.) + + ldx CharFace + bmi :ok ;facing L +;facing R + sec + sbc imwidth + +:ok sta leftej + clc + adc imwidth + sta rightej + + lda FCharY + sec + sbc imheight + clc + adc #1 + + cmp #192 + bcc :ok2 + lda #0 + +:ok2 sta topej + + jsr getblocky + + cmp #3 + bne :1 + lda #-1 ;if o.s., call it -1 + +:1 sta topblock + + lda FCharY + jsr getblocky ;if o.s., call it 3 + sta bottomblock + + lda leftej + jsr getblockx ;leftmost affected block + sta leftblock + + lda rightej + jsr getblockx ;rightmost affected block + sta rightblock + +* get leading edge (for collision detection) + + lda #0 + sta ztemp + + lda Fcheck + and #Fthinmark + beq :nothin + + lda #thinner ;make character 3 bits thinner + sta ztemp ;on both sides + +:nothin lda leftej + clc + adc ztemp + sta CDLeftEj + + lda rightej + sec + sbc ztemp + sta CDRightEj + +]rts rts + +*=============================== +* +* Q U I C K F L O O R +* +* Mark for redraw whatever floorpieces character might be +* impinging on +* +* In: CharData; GETEDGES results +* +*------------------------------- +QUICKFLOOR + lda CharPosn + cmp #135 + bcc :2 + cmp #149 + bcc :climbup + +:2 lda CharAction + cmp #1 + bne :1 + + lda CharPosn + cmp #78 + bcc ]rts + cmp #80 + bcc :fall +]rts rts + +:1 cmp #2 + beq :fall + cmp #3 + beq :fall + cmp #4 + beq :fall + cmp #6 + bne ]rts + +:fall lda #markfloor + ldx #>markfloor + bne :cont1 + +:climbup + lda #markhalf + ldx #>markhalf + +* Mark floorbuf/halfbuf for up to 6 affected blocks +* Start with rightblock, work left to leftblock + +:cont1 + sta marksm1+1 + sta marksm2+1 + stx marksm1+2 + stx marksm2+2 + + lda rightblock +:loop sta tempblockx + + jsr markul + + lda tempblockx + cmp leftblock + beq ]rts + sec + sbc #1 + bpl :loop + +]rts rts + +* mark upper & lower blocks for this blockx + +markul + lda bottomblock + sta tempblocky + + jsr indexblock ;lower block + lda #2 +marksm1 jsr markhalf + + lda topblock + cmp bottomblock + beq ]rts + sta tempblocky + + jsr indexblock ;upper block + lda #2 +marksm2 jmp markhalf + +*------------------------------- +* +* Q U I C K F G +* +* Mark for redraw any f.g. elements char (or his sword) +* might be impinging on +* +* In: Char data; left/right/top/bottomblock +* +*------------------------------- +QUICKFG + +* Quick fix to cover sword + + lda CharSword + cmp #2 + bcc :cont + + lda CharFace + bpl :faceR + dec leftblock + jmp :cont + +:faceR inc rightblock + +* Continue + +:cont lda bottomblock +:outloop + sta tempblocky + + lda rightblock +:loop sta tempblockx + + jsr indexblock + lda #3 + jsr MARKFRED + + lda tempblockx + cmp leftblock + beq :end + sec + sbc #1 + bpl :loop +:end + lda tempblocky + cmp topblock + beq ]rts + sec + sbc #1 + bpl :outloop + rts + +]bug jmp showpage + +*------------------------------- +* +* C R O P C H A R A C T E R +* +* In: FChar data as set by "setframe" +* leftej,rightej, etc. as set by "getedges" +* +* Out: FCharCL/CR/CU/CD +* +*------------------------------- +CROPCHAR + +* If char is climbing stairs, mask door + + lda CharPosn + cmp #224 + bcc :nost + cmp #229 + bcs :nost + lda doortop ;set by drawexitb + clc + adc #2 + cmp FCharY + bcs :bug ;temp! + sta FCharCU +]rts rts +:bug ldy #$F0 + jsr showpage +:nost + +* If char is under solid (a&b) floor, crop top + + ldx leftblock + ldy topblock + lda CharScrn + jsr rdblock + cmp #block + beq :1 + jsr cmpspace + beq :not + +* Special case (more lenient): if char is jumping +* up to touch ceiling + +:1 lda CharAction + bne :10 + lda CharPosn + cmp #79 + beq :2 + cmp #81 + bne :10 + beq :2 + +* Otherwise, both left & right topblocks must be solid + +:10 ldx rightblock + ldy topblock + lda CharScrn + jsr rdblock + cmp #block + beq :2 + jsr cmpspace + beq :not + +:2 ldx CharBlockY + inx + cpx #1 + beq :ok + + lda BlockTop,x + cmp FCharY + bcs :not + + sec + sbc #floorheight + cmp topej + bcs :not + +:ok lda BlockTop,x + sta FCharCU + sta topej +:not + +* If char is standing left of a panel, crop R +* Char is considered "left" if CDLeftEj falls within +* panel block + + lda CDLeftEj + jsr getblockx + sta blockx + + tax + ldy CharBlockY + lda CharScrn + jsr rdblock + + cmp #panelwof + beq :r + cmp #panelwif + bne :nor + +* Char's foot is within panel block +* Special case: If character is hanging R, we don't +* need to check his head + +:r lda CharFace + bmi :cont + + lda CharAction + cmp #2 + beq :r2 ;yes--hanging R + +* Check block to right of char's head + +:cont + ldx blockx + ldy topblock + lda CharScrn + jsr rdblock + + cmp #block + beq :r2 + cmp #panelwof + beq :r2 + cmp #panelwif + bne :nor + +* Also a panel -- make a wall + +:r2 lda tempblockx + asl + asl + clc + adc #4 + sta FCharCR + rts + +* Is char standing to L of solid block? +* (i.e. does CDRightEj fall within block?) + +:nor + lda CDRightEj + jsr getblockx + sta blockx + + tax + ldy CharBlockY + lda CharScrn + jsr rdblock + + cmp #block + bne :nob + +* Foot is under block--what about head? + + ldx blockx + ldy topblock + lda CharScrn + jsr rdblock + + cmp #block + bne :nob + +* Also a panel -- make a wall + +:yescrop + lda tempscrn + cmp CharScrn + bne :nob + + lda tempblockx + asl + asl + sta FCharCR +:nob + rts + +*------------------------------- +* +* Z E R O C R O P +* +*------------------------------- +zerocrop + lda #0 + sta FCharCU + sta FCharCL + lda #40 + sta FCharCR + lda #192 + sta FCharCD + rts + +*=============================== +* +* C O M P A R E S P A C E +* +* Is it a space (can you pass thru)? +* NOTE: Solid block is considered a space (it has no floor) +* +* In: A = objid +* Out: 0 = space, 1 = floor +* +*------------------------------- +CMPSPACE + cmp #space + beq :space + cmp #pillartop + beq :space + cmp #panelwof + beq :space + cmp #block + beq :space + cmp #archtop1 + bcs :space + + lda #1 + rts + +:space lda #0 + rts + +*------------------------------- +* +* C O M P A R E B A R R I E R +* +* Is it a barrier? +* +* Return A = 0 if clear, else A = barrier code # +* +*------------------------------- +CMPBARR + cmp #panelwif + beq :b1 + cmp #panelwof + beq :b1 + cmp #gate + bne :2 + +:b1 lda #1 ;panel/gate + rts + +:2 cmp #mirror + beq :yes3 + + cmp #slicer + bne :3 + +:yes3 lda #3 ;mirror/slicer + rts + +:3 cmp #block + bne :4 + + lda #4 ;block + rts +:4 +:clear lda #0 +:rts rts + +:barr lda #1 +]rts rts + +*------------------------------- +* +* Is it a wall? Return 0 if yes, 1 if no +* (Solid block, or panel if you're facing L) +* +*------------------------------- +CMPWALL + cmp #block + beq :yes + ldx CharFace + bpl :no + cmp #panelwif + beq :yes + cmp #panelwof + beq :yes +:no lda #1 + rts +:yes lda #0 + rts + +*------------------------------- +* +* Add kid/reflection/shadowman/guard to object table +* +* In: FChar data +* +*------------------------------- +ADDKIDOBJ + lda #TypeKid + jmp addcharobj + +*------------------------------- +ADDREFLOBJ + lda #TypeReflect + jmp addcharobj + +*------------------------------- +ADDSHADOBJ + lda #TypeShad + jmp addcharobj + +*------------------------------- +ADDGUARDOBJ + lda #TypeGd + jmp addcharobj + +*------------------------------- +* +* Add sword to object table +* In: FChar data for character holding sword +* +*------------------------------- +ADDSWORDOBJ + lda #TypeSword + jmp addcharobj + +*------------------------------- +* +* G E T S E Q +* +* Get next byte from seqtable & advance CharSeq +* (2-byte pointer to sequence table) +* +*------------------------------- +GETSEQ + ldy #0 + lda (CharSeq),y + pha + + inc CharSeq + bne :done + inc CharSeq+1 + +:done pla + rts + +*------------------------------- +* +* G E T F R A M E I N F O +* +* Get frame info for char (based on CharPosn) +* +*------------------------------- +GETFRAMEINFO + lda CharPosn + jsr GETFRAME ;set framepoint + + jsr usealtsets ;if appropriate + + ldy #0 + lda (framepoint),y + sta Fimage + + iny + lda (framepoint),y + sta Fsword + + iny + lda (framepoint),y + sta Fdx + + iny + lda (framepoint),y + sta Fdy + + iny + lda (framepoint),y + sta Fcheck + +]rts rts + +*------------------------------- +* +* Use alternate character image sets +* (if appropriate) +* +* In: Char data; framepoint +* Out: framepoint +* +*------------------------------- +usealtsets + ldx CharID + beq ]rts ;kid uses main set, enemy uses alt set 1 + cpx #24 + beq ]rts ;mouse uses main set + cpx #5 + bcs :usealt2 ;princess & vizier use alt set 2 + + lda CharPosn + cpx #2 + bcc :1 + cmp #102 + bcc ]rts + cmp #107 + bcs :1 + ;frames 102-106 (falling): substitute 172-176 altset + clc + adc #70 + +:1 cmp #150 + bcc ]rts + cmp #190 + bcs ]rts +;frames 150-189: use altset + sec + sbc #149 + jmp getaltframe1 + +:usealt2 + lda CharPosn + jmp getaltframe2 + +*=============================== +* +* M A R K +* +* In: A = mark value (usually 2) +* Results of INDEXBLOCK: +* Y = block #; carry set or clear +* +* Out: Preserve A, Y, carry +* +*------------------------------- +]os cpy #10 ;top line from scrn above? + bcs ]rts ;no + sta topbuf,y + sec ;preserve cs +]rts rts + +MARKRED + bcs ]os + sta redbuf,y + rts + +MARKFRED + bcs ]rts + sta fredbuf,y + rts + +MARKWIPE + bcs ]rts + pha + lda wipebuf,y + beq :2 + lda height + cmp whitebuf,y ;if wipebuf is already marked, + bcc :1 ;use larger of 2 whitebuf values +:2 lda height + sta whitebuf,y +:1 pla + sta wipebuf,y + clc ;return with cc + rts + +MARKMOVE + bcs ]os + sta movebuf,y + rts + +MARKFLOOR + bcs ]os + sta floorbuf,y + rts + +MARKHALF + bcs ]os + sta halfbuf,y + 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 wipebuf,y + sta movebuf,y + sta objbuf,y + sta halfbuf,y + + dey + bpl :loop + + ldy #9 +:dloop sta topbuf,y + dey + bpl :dloop + + rts + +*------------------------------- +* +* C H E C K L E D G E +* +* In: blockid = block that must be clear; +* A = RDBLOCK results for block that must be ledge +* +* Out: A = 1 if grabbable, 0 if not +* +*------------------------------- +CHECKLEDGE + sta ztemp + + lda (BlueSpec),y + sta tempstate + + lda blockid ;must be clear + + cmp #block + beq :no + + cmp #panelwof ;CMPSPACE considers panel w/o floor + bne :cont ;to be clear-- + + bit CharFace ;but it isn't if char wants to grab + bpl :no ;floorpiece to right +:cont + jsr cmpspace + bne :no + +* Clear above -- is there a ledge in front? + + lda ztemp ;must be a solid floorpiece +;with exposed ledge + cmp #loose + bne :notloose + + bit tempstate + bne :no ;floor is already loose + +:notloose + cmp #panelwif + bne :cont2 ;panel w/floor can be grabbed +;only if facing right + bit CharFace + bmi :no + +:cont2 jsr cmpspace + beq :no + +:yes lda #1 + rts + +:no lda #0 +]rts rts + +*------------------------------- +* +* C H E C K S P I K E S +* +* Spikes spring out when char passes over them (at any +* height). +* +*------------------------------- +CHECKSPIKES + lda rightej + jsr getblockxp + bmi ]rts + sta tempright + +* for blockx = leftblock to rightblock + + lda leftej + jsr getblockxp +:loop sta blockx + + jsr sub + + lda blockx + cmp tempright + beq ]rts + clc + adc #1 + jmp :loop + +sub sta tempblockx + lda CharBlockY + sta tempblocky + lda CharScrn + sta tempscrn +:loop jsr rdblock1 + + cmp #spikes + bne :again + jmp trigspikes + +:again jsr cmpspace + bne ]rts + + lda tempscrn + beq ]rts ;null scrn + cmp CharScrn + bne ]rts ;wait till he's on same screen + + inc tempblocky + jmp :loop ;check 1 level below + +*=============================== +* +* Load/save kid/shad vars +* +*------------------------------- +numvars = 16 + +LOADKID + ldx #numvars-1 + +:loop lda Kid,x + sta Char,x + + dex + bpl :loop +]rts rts + +SAVEKID + ldx #numvars-1 + +:loop lda Char,x + sta Kid,x + + dex + bpl :loop +]rts rts + +LOADSHAD + ldx #numvars-1 + +:loop lda Shad,x + sta Char,x + + dex + bpl :loop +]rts rts + + +SAVESHAD + ldx #numvars-1 + +:loop lda Char,x + sta Shad,x + + dex + bpl :loop + rts + +* Load kid w/ opponent + +LOADKIDWOP + ldx #numvars-1 + +:loop lda Kid,x + sta Char,x + + lda Shad,x + sta Op,x + + dex + bpl :loop + rts + +SAVEKIDWOP + ldx #numvars-1 + +:loop lda Char,x + sta Kid,x + + lda Op,x + sta Shad,x + + dex + bpl :loop + rts + +* Load shadowman w/ opponent + +LOADSHADWOP + ldx #numvars-1 + +:loop lda Shad,x + sta Char,x + + lda Kid,x + sta Op,x + + dex + bpl :loop + rts + +SAVESHADWOP + ldx #numvars-1 + +:loop lda Char,x + sta Shad,x + + lda Op,x + sta Kid,x + + dex + bpl :loop + rts + +*------------------------------- +* +* Recharge strength meter to max +* +*------------------------------- +RECHARGEMETER + lda MaxKidStr + sec + sbc KidStrength + sta ChgKidStr +]rts rts + +*------------------------------- +* +* Boost strength meter max by 1 and recharge +* +*------------------------------- +BOOSTMETER + lda MaxKidStr + cmp #maxmaxstr + bcs :1 + + clc + adc #1 + sta MaxKidStr + +:1 jmp RECHARGEMETER + +*------------------------------- +* +* Get distance between char & opponent +* (# pixels char must move fwd to reach opponent) +* If dist is greater than 127, return 127 (+ or -) +* +*------------------------------- +estwidth = 13 ;rough est of char width + +GETOPDIST + lda CharScrn + cmp OpScrn + bne :safe + +* First, get A = OpX-CharX (abs. value <= 127) + + lda OpX + cmp CharX + bcc :neg + sec + sbc CharX + bpl :got + lda #127 + bpl :got + +:neg lda CharX + sec + sbc OpX + bpl :1 + lda #127 +:1 eor #$ff + clc + adc #1 ;negate + +* If CharFace = left, negate + +:got ldx CharFace + bpl :cont + eor #$ff + clc + adc #1 + +* If chars are facing in opposite directions, +* adjust by estimate of width of figure + +:cont tax + lda CharFace + eor OpFace + bpl :done + txa + cmp #127-estwidth + bcs :done2 + clc + adc #estwidth +:done2 tax + rts + +:safe ldx #127 ;arbitrary large dist. +:done txa ;return value in A +]rts rts + +*------------------------------- +* +* Adjust CharY for uneven floor +* +*------------------------------- +UNEVENFLOOR + jsr getunderft + cmp #dpressplate + bne ]rts + inc CharY +]rts rts + +*------------------------------- + lst + ds 1 + usr $a9,19,$200,*-org + lst off diff --git a/01 POP Source/Source/EQ.S b/01 POP Source/Source/EQ.S index 08f72e7..7edeb17 100755 --- a/01 POP Source/Source/EQ.S +++ b/01 POP Source/Source/EQ.S @@ -1 +1,494 @@ - tr on lst off * eq *------------------------------- * * Equates * *------------------------------- * Main l.c. rw18 = $d000 peelbuf1 = $d000 peelbuf2 = $d800 hrtables = $e000 unpack = $ea00 ;game only hires = $ee00 master = $f880 * Auxmem grafix = $400 tables = $e00 frameadv = $1290 redbufs = $5e00 menudata = $960f ;ed only imlists = $ac00 endimspace = $b600 blueprnt = $b700 * Aux l.c. bluecopy = $d000 ;bank 1 *------------------------------- * * Jump tables * *------------------------------- dum master _firstboot ds 3 _loadlevel ds 3 _reload ds 3 _loadstage2 ds 3 ds 3 _attractmode ds 3 _cutprincess ds 3 _savegame ds 3 _loadgame ds 3 _dostartgame ds 3 _epilog ds 3 _loadaltset ds 3 ds 3 ;_screendump dum master ;ed ds 15 _edreboot ds 3 _gobuild ds 3 _gogame ds 3 _writedir ds 3 _readdir ds 3 _savelevel ds 3 _savelevelg ds 3 _screendump ds 3 dum hrtables YLO ds $c0 YHI ds $c0 dum hires _boot3 ds 3 _cls ds 3 _lay ds 3 _fastlay ds 3 _layrsave ds 3 _lrcls ds 3 _fastmask ds 3 _fastblack ds 3 _peel ds 3 _getwidth ds 3 _copy2000 ds 3 _copy2000aux ds 3 _setfastaux ds 3 _setfastmain ds 3 _copy2000ma ds 3 _copy2000am ds 3 dum unpack SngExpand ds 3 DblExpand ds 3 DeltaExpPop ds 3 _inverty ds 3 DeltaExpWipe ds 3 purple ds 3 prompt ds 3 blackout ds 3 clr ds 3 text ds 3 setdhires ds 3 fadein ds 3 loadsuper ds 3 fadeout ds 3 dum grafix gr ds 3 drawall ds 3 controller ds 3 ds 3 saveblue ds 3 reloadblue ds 3 movemem ds 3 buttons ds 3 gtone ds 3 setcenter ds 3 dimchar ds 3 cvtx ds 3 zeropeel ds 3 zeropeels ds 3 pread ds 3 addpeel ds 3 copyscrn ds 3 sngpeel ds 3 rnd ds 3 cls ds 3 lay ds 3 fastlay ds 3 layrsave ds 3 lrcls ds 3 fastmask ds 3 fastblack ds 3 peel ds 3 getwidth ds 3 copy2000 ds 3 copy2000ma ds 3 setfastaux ds 3 setfastmain ds 3 loadlevel ds 3 attractmode ds 3 xminit ds 3 xmplay ds 3 cutprincess ds 3 xtitle ds 3 copy2000am ds 3 reload ds 3 loadstage2 ds 3 ds 3 getselect ds 3 getdesel ds 3 edreboot ds 3 ;ed gobuild ds 3 ;ed gogame ds 3 ;ed writedir ds 3 ;ed readdir ds 3 ;ed savelevel ds 3 ;ed savelevelg ds 3 ;ed addback ds 3 addfore ds 3 addmid ds 3 addmidez ds 3 addwipe ds 3 addmsg ds 3 savegame ds 3 loadgame ds 3 zerolsts ds 3 screendump ds 3 minit ds 3 mplay ds 3 savebinfo ds 3 reloadbinfo ds 3 inverty ds 3 normspeed ds 3 addmidezo ds 3 calcblue ds 3 zerored ds 3 xplaycut ds 3 checkIIGS ds 3 fastspeed ds 3 musickeys ds 3 dostartgame ds 3 epilog ds 3 loadaltset ds 3 xmovemusic ds 3 whoop ds 3 vblank ds 3 vbli ds 3 dum redbufs ds 60 ;unused halfbuf ds 30 redbuf ds 30 fredbuf ds 30 floorbuf ds 30 wipebuf ds 30 movebuf ds 30 objbuf ds 30 whitebuf ds 30 topbuf ds 10 dum menudata ;ed only menutype ds 30 menuspec ds 30 menubspec ds 30 dum frameadv sure ds 3 fast ds 3 getinitobj ds 3 dum tables ByteTable ds $100 OffsetTable ds $100 BlockTable ds $100 PixelTable ds $100 Mult10 ds $10 Mult7 ds $10 Mult30 ds $40 BlockEdge ds 20 BlockTop ds 5 BlockBot ds 5 FloorY ds 5 BlockAy ds 5 dum blueprnt BLUETYPE ds 24*30 BLUESPEC ds 24*30 LINKLOC ds 256 LINKMAP ds 256 MAP ds 24*4 INFO ds 256 *------------------------------- * * Blueprint info * *------------------------------- dum INFO ds 64 KidStartScrn ds 1 KidStartBlock ds 1 KidStartFace ds 1 ds 1 SwStartScrn ds 1 SwStartBlock ds 1 ds 1 GdStartBlock ds 24 GdStartFace ds 24 GdStartX ds 24 GdStartSeqL ds 24 GdStartProg ds 24 GdStartSeqH ds 24 *------------------------------- * * Image lists * *------------------------------- maxback = 200 ;x4 maxfore = 100 ;x4 maxwipe = 20 ;x5 maxpeel = 46 ;x4 maxmid = 46 ;x11 maxobj = 20 ;x12 maxmsg = 32 ;x5 dum imlists genCLS ds 1 bgX ds maxback bgY ds maxback bgIMG ds maxback bgOP ds maxback fgX ds maxfore fgY ds maxfore fgIMG ds maxfore fgOP ds maxfore wipeX ds maxwipe wipeY ds maxwipe wipeH ds maxwipe wipeW ds maxwipe wipeCOL ds maxwipe peelX ds maxpeel*2 peelY ds maxpeel*2 peelIMGL ds maxpeel*2 peelIMGH ds maxpeel*2 midX ds maxmid midOFF ds maxmid midY ds maxmid midIMG ds maxmid midOP ds maxmid midTYP ds maxmid midCU ds maxmid midCD ds maxmid midCL ds maxmid midCR ds maxmid midTAB ds maxmid objINDX ds maxobj objX ds maxobj objOFF ds maxobj objY ds maxobj objIMG ds maxobj objFACE ds maxobj objTYP ds maxobj objCU ds maxobj objCD ds maxobj objCL ds maxobj objCR ds maxobj objTAB ds maxobj msgX ds maxmsg msgOFF ds maxmsg msgY ds maxmsg msgIMG ds maxmsg msgOP ds maxmsg *------------------------------- * * Zero page * *------------------------------- * $00-17: Hires parameters *------------------------------- dum $00 PAGE ds 1 XCO ds 1 YCO ds 1 OFFSET ds 1 IMAGE ds 2 OPACITY ds 1 TABLE ds 2 PEELBUF ds 2 PEELIMG ds 2 PEELXCO ds 1 PEELYCO ds 1 TOPCUT ds 1 LEFTCUT ds 1 RIGHTCUT ds 1 BANK ds 1 BOTCUT ds 1 height = IMAGE width = IMAGE+1 *------------------------------- * $18-3f: Global vars *------------------------------- dum $18 JSTKX ds 1 JSTKY ds 1 BTN0 ds 1 BTN1 ds 1 BUTT0 ds 1 BUTT1 ds 1 JSTKUP ds 1 b0down ds 1 b1down ds 1 SINGSTEP ds 1 blackflag ds 1 SCRNUM ds 1 BlueType ds 2 BlueSpec ds 2 CUTTIMER ds 1 PRECED ds 1 spreced ds 1 PREV ds 3 sprev ds 3 scrnLeft ds 1 scrnRight ds 1 scrnAbove ds 1 scrnBelow ds 1 scrnBelowL ds 1 scrnAboveL ds 1 scrnAboveR ds 1 scrnBelowR ds 1 kbdX ds 1 kbdY ds 1 joyX ds 1 joyY ds 1 btn ds 1 butt ds 1 *------------------------------- * * Pages 2-3 * *------------------------------- dum $200 inmenu ds 1 inbuilder ds 1 ineditor ds 1 soundon ds 1 jctr ds 2 jthres1x ds 1 jthres1y ds 1 jthres2x ds 1 jthres2y ds 1 jvert ds 1 jhoriz ds 1 jbtns ds 1 joyon ds 1 develment ds 1 keypress ds 1 keydown ds 1 IIGS ds 1 dum $3c0 sortX ds $10 BELOW ds $10 SBELOW ds $10 dum $3f0 bluepTRK ds 1 bluepREG ds 1 binfoTRK ds 1 binfoREG ds 1 level ds 1 BBundID ds 1 redherring2 ds 1 pausetemp ds 1 recheck0 ds 1 dend *------------------------------- * * Misc. constants * *------------------------------- ScrnWidth = 140 ScrnHeight = 192 ScrnLeft = 58 ScrnRight = ScrnLeft+ScrnWidth-1 ScrnTop = 0 ScrnBottom = ScrnTop+ScrnHeight-1 secmask = %11000000 reqmask = %00100000 idmask = %00011111 and = 0 ora = 1 sta = 2 eor = 3 mask = 4 lst off \ No newline at end of file + tr on + lst off +* eq +*------------------------------- +* +* Equates +* +*------------------------------- +* Main l.c. + +rw18 = $d000 +peelbuf1 = $d000 +peelbuf2 = $d800 +hrtables = $e000 +unpack = $ea00 ;game only +hires = $ee00 +master = $f880 + +* Auxmem + +grafix = $400 +tables = $e00 +frameadv = $1290 +redbufs = $5e00 +menudata = $960f ;ed only +imlists = $ac00 +endimspace = $b600 +blueprnt = $b700 + +* Aux l.c. + +bluecopy = $d000 ;bank 1 + +*------------------------------- +* +* Jump tables +* +*------------------------------- + dum master + +_firstboot ds 3 +_loadlevel ds 3 +_reload ds 3 +_loadstage2 ds 3 + ds 3 + +_attractmode ds 3 +_cutprincess ds 3 +_savegame ds 3 +_loadgame ds 3 +_dostartgame ds 3 + +_epilog ds 3 +_loadaltset ds 3 + ds 3 ;_screendump + + dum master ;ed + + ds 15 + +_edreboot ds 3 +_gobuild ds 3 +_gogame ds 3 +_writedir ds 3 +_readdir ds 3 + +_savelevel ds 3 +_savelevelg ds 3 +_screendump ds 3 + + dum hrtables + +YLO ds $c0 +YHI ds $c0 + + dum hires + +_boot3 ds 3 +_cls ds 3 +_lay ds 3 +_fastlay ds 3 +_layrsave ds 3 + +_lrcls ds 3 +_fastmask ds 3 +_fastblack ds 3 +_peel ds 3 +_getwidth ds 3 + +_copy2000 ds 3 +_copy2000aux ds 3 +_setfastaux ds 3 +_setfastmain ds 3 +_copy2000ma ds 3 + +_copy2000am ds 3 + + + dum unpack + +SngExpand ds 3 +DblExpand ds 3 +DeltaExpPop ds 3 +_inverty ds 3 +DeltaExpWipe ds 3 + +purple ds 3 +prompt ds 3 +blackout ds 3 +clr ds 3 +text ds 3 + +setdhires ds 3 +fadein ds 3 +loadsuper ds 3 +fadeout ds 3 + + dum grafix + +gr ds 3 +drawall ds 3 +controller ds 3 + ds 3 +saveblue ds 3 + +reloadblue ds 3 +movemem ds 3 +buttons ds 3 +gtone ds 3 +setcenter ds 3 + +dimchar ds 3 +cvtx ds 3 +zeropeel ds 3 +zeropeels ds 3 +pread ds 3 + +addpeel ds 3 +copyscrn ds 3 +sngpeel ds 3 +rnd ds 3 +cls ds 3 + +lay ds 3 +fastlay ds 3 +layrsave ds 3 +lrcls ds 3 +fastmask ds 3 + +fastblack ds 3 +peel ds 3 +getwidth ds 3 +copy2000 ds 3 +copy2000ma ds 3 + +setfastaux ds 3 +setfastmain ds 3 +loadlevel ds 3 +attractmode ds 3 +xminit ds 3 + +xmplay ds 3 +cutprincess ds 3 +xtitle ds 3 +copy2000am ds 3 +reload ds 3 + +loadstage2 ds 3 + ds 3 +getselect ds 3 +getdesel ds 3 +edreboot ds 3 ;ed + +gobuild ds 3 ;ed +gogame ds 3 ;ed +writedir ds 3 ;ed +readdir ds 3 ;ed +savelevel ds 3 ;ed + +savelevelg ds 3 ;ed +addback ds 3 +addfore ds 3 +addmid ds 3 +addmidez ds 3 + +addwipe ds 3 +addmsg ds 3 +savegame ds 3 +loadgame ds 3 +zerolsts ds 3 + +screendump ds 3 +minit ds 3 +mplay ds 3 +savebinfo ds 3 +reloadbinfo ds 3 + +inverty ds 3 +normspeed ds 3 +addmidezo ds 3 +calcblue ds 3 +zerored ds 3 + +xplaycut ds 3 +checkIIGS ds 3 +fastspeed ds 3 +musickeys ds 3 +dostartgame ds 3 + +epilog ds 3 +loadaltset ds 3 +xmovemusic ds 3 +whoop ds 3 +vblank ds 3 + +vbli ds 3 + + dum redbufs + + ds 60 ;unused +halfbuf ds 30 +redbuf ds 30 +fredbuf ds 30 +floorbuf ds 30 +wipebuf ds 30 +movebuf ds 30 +objbuf ds 30 +whitebuf ds 30 +topbuf ds 10 + + dum menudata ;ed only + +menutype ds 30 +menuspec ds 30 +menubspec ds 30 + + dum frameadv + +sure ds 3 +fast ds 3 +getinitobj ds 3 + + dum tables + +ByteTable ds $100 +OffsetTable ds $100 +BlockTable ds $100 +PixelTable ds $100 +Mult10 ds $10 +Mult7 ds $10 +Mult30 ds $40 +BlockEdge ds 20 +BlockTop ds 5 +BlockBot ds 5 +FloorY ds 5 +BlockAy ds 5 + + dum blueprnt + +BLUETYPE ds 24*30 +BLUESPEC ds 24*30 +LINKLOC ds 256 +LINKMAP ds 256 +MAP ds 24*4 +INFO ds 256 + +*------------------------------- +* +* Blueprint info +* +*------------------------------- + dum INFO + + ds 64 +KidStartScrn ds 1 +KidStartBlock ds 1 +KidStartFace ds 1 + ds 1 +SwStartScrn ds 1 +SwStartBlock ds 1 + ds 1 +GdStartBlock ds 24 +GdStartFace ds 24 +GdStartX ds 24 +GdStartSeqL ds 24 +GdStartProg ds 24 +GdStartSeqH ds 24 + +*------------------------------- +* +* Image lists +* +*------------------------------- +maxback = 200 ;x4 +maxfore = 100 ;x4 +maxwipe = 20 ;x5 +maxpeel = 46 ;x4 +maxmid = 46 ;x11 +maxobj = 20 ;x12 +maxmsg = 32 ;x5 + + dum imlists + +genCLS ds 1 + +bgX ds maxback +bgY ds maxback +bgIMG ds maxback +bgOP ds maxback + +fgX ds maxfore +fgY ds maxfore +fgIMG ds maxfore +fgOP ds maxfore + +wipeX ds maxwipe +wipeY ds maxwipe +wipeH ds maxwipe +wipeW ds maxwipe +wipeCOL ds maxwipe + +peelX ds maxpeel*2 +peelY ds maxpeel*2 +peelIMGL ds maxpeel*2 +peelIMGH ds maxpeel*2 + +midX ds maxmid +midOFF ds maxmid +midY ds maxmid +midIMG ds maxmid +midOP ds maxmid +midTYP ds maxmid +midCU ds maxmid +midCD ds maxmid +midCL ds maxmid +midCR ds maxmid +midTAB ds maxmid + +objINDX ds maxobj +objX ds maxobj +objOFF ds maxobj +objY ds maxobj +objIMG ds maxobj +objFACE ds maxobj +objTYP ds maxobj +objCU ds maxobj +objCD ds maxobj +objCL ds maxobj +objCR ds maxobj +objTAB ds maxobj + +msgX ds maxmsg +msgOFF ds maxmsg +msgY ds maxmsg +msgIMG ds maxmsg +msgOP ds maxmsg + +*------------------------------- +* +* Zero page +* +*------------------------------- +* $00-17: Hires parameters +*------------------------------- + dum $00 + +PAGE ds 1 +XCO ds 1 +YCO ds 1 +OFFSET ds 1 +IMAGE ds 2 +OPACITY ds 1 +TABLE ds 2 +PEELBUF ds 2 +PEELIMG ds 2 +PEELXCO ds 1 +PEELYCO ds 1 +TOPCUT ds 1 +LEFTCUT ds 1 +RIGHTCUT ds 1 +BANK ds 1 +BOTCUT ds 1 + +height = IMAGE +width = IMAGE+1 + +*------------------------------- +* $18-3f: Global vars +*------------------------------- + dum $18 + +JSTKX ds 1 +JSTKY ds 1 +BTN0 ds 1 +BTN1 ds 1 +BUTT0 ds 1 +BUTT1 ds 1 +JSTKUP ds 1 +b0down ds 1 +b1down ds 1 +SINGSTEP ds 1 +blackflag ds 1 +SCRNUM ds 1 +BlueType ds 2 +BlueSpec ds 2 +CUTTIMER ds 1 +PRECED ds 1 +spreced ds 1 +PREV ds 3 +sprev ds 3 +scrnLeft ds 1 +scrnRight ds 1 +scrnAbove ds 1 +scrnBelow ds 1 +scrnBelowL ds 1 +scrnAboveL ds 1 +scrnAboveR ds 1 +scrnBelowR ds 1 +kbdX ds 1 +kbdY ds 1 +joyX ds 1 +joyY ds 1 +btn ds 1 +butt ds 1 + +*------------------------------- +* +* Pages 2-3 +* +*------------------------------- + dum $200 + +inmenu ds 1 +inbuilder ds 1 +ineditor ds 1 +soundon ds 1 +jctr ds 2 +jthres1x ds 1 +jthres1y ds 1 +jthres2x ds 1 +jthres2y ds 1 +jvert ds 1 +jhoriz ds 1 +jbtns ds 1 +joyon ds 1 +develment ds 1 +keypress ds 1 +keydown ds 1 +IIGS ds 1 + + dum $3c0 + +sortX ds $10 +BELOW ds $10 +SBELOW ds $10 + + dum $3f0 + +bluepTRK ds 1 +bluepREG ds 1 +binfoTRK ds 1 +binfoREG ds 1 +level ds 1 +BBundID ds 1 +redherring2 ds 1 +pausetemp ds 1 +recheck0 ds 1 + + dend + +*------------------------------- +* +* Misc. constants +* +*------------------------------- +ScrnWidth = 140 +ScrnHeight = 192 + +ScrnLeft = 58 +ScrnRight = ScrnLeft+ScrnWidth-1 +ScrnTop = 0 +ScrnBottom = ScrnTop+ScrnHeight-1 + +secmask = %11000000 +reqmask = %00100000 +idmask = %00011111 + +and = 0 +ora = 1 +sta = 2 +eor = 3 +mask = 4 + + lst off diff --git a/01 POP Source/Source/FRAMEADV.S b/01 POP Source/Source/FRAMEADV.S index e16adfb..c94f7de 100755 --- a/01 POP Source/Source/FRAMEADV.S +++ b/01 POP Source/Source/FRAMEADV.S @@ -1 +1,2267 @@ -* frameadv EditorDisk = 0 ;1 = dunj, 2 = palace org = $1290 lst off tr on *------------------------------- org org jmp SURE jmp FAST jmp GETINITOBJ *------------------------------- lst put eq lst put gameeq lst off put bgdata lst off initsettings db gmaxval,gminval dum locals index ds 1 rowno ds 1 colno ds 1 yindex ds 1 objid ds 1 state ds 1 Ay ds 1 Dy ds 1 gateposn ds 1 gatebot ds 1 xsave ds 1 blockxco ds 1 switches ds 1 obj1 ds 1 obj2 ds 1 blockthr ds 1 dend *------------------------------- * * Draw entire 10 x 3 screen from scratch * *------------------------------- SURE lda #1 sta genCLS ;clear screen jsr setback ;draw on bg plane jsr getprev ;get 3 rightmost blocks of screen to left lda SCRNUM jsr calcblue ;get blueprint base addr * Draw 3 rows of 10 blocks (L-R, T-B) ldy #2 :row sty rowno ;0 = top row, 2 = bottom row lda BlockBot+1,y sta Dy ;get Y-coord for bottom of D-section sec sbc #3 sta Ay ;& A-section lda Mult10,y sta yindex ;block # (0-29) lda PREV,y sta PRECED lda sprev,y sta spreced ;get objid & state of preceding block jsr getbelow ;get 10 topmost blocks of screen below lda #0 sta colno ;0 = leftmost column, 9 = rightmost :loop asl asl sta XCO sta blockxco ;get X-coord for A-section ldy yindex jsr getobjid sta objid ;get object id# of current block jsr RedBlockSure ;Redraw entire block lda objid sta PRECED lda state sta spreced ;Move on to next block inc yindex inc colno lda colno cmp #10 bcc :loop ;...until we've done 10 blocks :nextln ldy rowno beq :done dey jmp :row ;...and 3 rows * Now draw bottom row of screen above (D-sections only) :done ldy #2 ;bottom row of scrn above sty rowno lda #2 sta Dy lda #-1 sta Ay ;get screen Y-coords lda Mult10,y sta yindex lda #0 sta PRECED lda scrnBelow pha lda scrnBelowL pha ;save current values on stack lda SCRNUM sta scrnBelow lda scrnLeft sta scrnBelowL ;& pretend we're on screen above * Draw 10 blocks, L-R jsr getbelow lda scrnAbove jsr calcblue lda #0 sta colno :dloop asl asl sta XCO sta blockxco lda scrnAbove bne :1 lda #floor ;If screen above is null screen, bne :2 ;draw a row of solid floorpieces :1 ldy yindex jsr getobjid1 :2 sta objid jsr RedDSure ;Draw D-section lda objid sta PRECED lda state sta spreced inc yindex inc colno lda colno cmp #10 bcc :dloop pla ;Restore original screen values sta scrnBelowL pla sta scrnBelow ]rts rts *------------------------------- * * Fast screen redraw * * Same general structure as SURE, but redraws only those * blocks specified by redraw buffers. * *------------------------------- FAST jsr getprev lda SCRNUM jsr calcblue lda #0 ldy #20 jsr metbufs3 ;If strength meter is in danger of sta redkidmeter ;being overwritten, mark it for redraw lda #0 ldy #28 jsr metbufs2 sta redoppmeter ;opponent meter too lda #30 sta yindex jsr drawobjs ;Draw o.s. characters first * Draw 3 rows of 10 blocks (L-R, T-B) ldy #2 :row sty rowno lda BlockBot+1,y sta Dy sec sbc #3 sta Ay lda Mult10,y sta yindex lda PREV,y sta PRECED lda sprev,y sta spreced jsr getbelow lda #0 sta colno :loop asl asl sta XCO sta blockxco ldy yindex jsr getobjid sta objid jsr RedBlockFast lda objid sta PRECED lda state sta spreced inc yindex inc colno lda colno cmp #10 bcs :nextln jmp :loop :nextln ldy rowno beq :cont dey jmp :row * Now draw bottom row of screen above (D-sections only) :cont jsr setback ldy #2 sty rowno lda #2 sta Dy lda #-1 sta Ay lda Mult10,y sta yindex lda #0 sta PRECED lda scrnBelow pha lda scrnBelowL pha lda SCRNUM sta scrnBelow lda scrnLeft sta scrnBelowL jsr getbelow lda scrnAbove beq :done jsr calcblue lda #0 sta colno :dloop asl asl sta blockxco sta XCO ldy yindex jsr getobjid1 sta objid jsr RedDFast lda objid sta PRECED lda state sta spreced inc yindex inc colno lda colno cmp #10 bcc :dloop :done pla sta scrnBelowL pla sta scrnBelow * Now draw comix (impact stars) & strength meters lda #$ff sta yindex jsr drawobjs ;draw comix (index = -1) do EditorDisk lda inbuilder bne ]rts fin jmp updatemeters *------------------------------- * * Redraw entire block * *------------------------------- RedBlockSure jsr drawc ;C-section of piece below & to left jsr drawmc jsr drawb ;B-section of piece to left jsr drawmb jsr drawd ;D-section jsr drawmd jsr drawa ;A-section jsr drawma jmp drawfrnt ;A-section frontpiece ;(Note: This is necessary in case we do a ;layersave before we get to f.g. plane) *------------------------------- * * Redraw entire D-section * *------------------------------- RedDSure jsr drawc jsr drawmc jsr drawb jsr drawd jsr drawmd jmp drawfrnt *------------------------------- * * Partial block redraw (as specified by redraw buffers) * *------------------------------- RedBlockFast lda wipebuf,y ;is wipebuf marked? beq :skipwipe ;no--skip it sec sbc #1 sta wipebuf,y ;decrement wipebuf jsr wipesq ;& wipe this block! ldy yindex :skipwipe lda redbuf,y beq :skipred sec sbc #1 sta redbuf,y jsr setback jsr RedBlockSure ldy yindex bpl :skipmove :skipred lda movebuf,y beq :skipmove sec sbc #1 sta movebuf,y jsr setback jsr drawmc jsr drawmb jsr drawma ldy yindex :skipmove lda floorbuf,y beq :skipfloor sec sbc #1 sta floorbuf,y jsr setmid jsr drawfloor ldy yindex bpl :skiphalf :skipfloor lda halfbuf,y beq :skiphalf sec sbc #1 sta halfbuf,y jsr setmid jsr drawhalf ldy yindex :skiphalf lda objbuf,y beq :skipobj lda #0 sta objbuf,y jsr drawobjs ;draw all objects in this block lda blockxco sta XCO ldy yindex :skipobj lda fredbuf,y beq :skipfred sec sbc #1 sta fredbuf,y jsr drawfrnt ldy yindex :skipfred ]rts rts *------------------------------- * * Partial D-section redraw * *------------------------------- RedDFast ldy colno lda topbuf,y ;is topbuf marked? beq :skip ;no--skip it sec sbc #1 sta topbuf,y jsr wiped jsr drawc jsr drawmc jsr drawb jsr redrawd ;(both bg and fg) jsr drawmd jsr drawfrnt :skip ]rts rts *------------------------------- * * Draw objects * * Draw object/s with index # = yindex * (Add appropriate images to mid list) * *------------------------------- drawobjs * Go through obj list looking for objINDX = yindex lda objX beq :rts ldy #0 ;y = sort list index ldx #1 ;x = object list index :loop lda objINDX,x cmp yindex bne :next ;Found a match--add object to sort list txa iny sta sortX,y :next inx cpx objX bcc :loop beq :loop cpy #0 beq :rts sty sortX ;# of objects in sort list * Sort them into back-to-front order jsr sortlist * Transfer sorted objects from obj list to mid list ldx #1 :loop2 stx xsave lda sortX,x tax ;obj list index jsr drawobjx ;draw object #x ldx xsave inx cpx sortX bcc :loop2 beq :loop2 ;Done :rts rts *------------------------------- * * Get objids & states of 3 rightmost blocks * of left-neighboring screen * * Out: PREV/sprev [0-2] * *------------------------------- getprev lda SCRNUM beq :null lda scrnLeft beq :blackscrn :cont jsr calcblue ;screen to left ldy #9 jsr getobjid1 sta PREV lda state sta sprev ldy #19 jsr getobjid1 sta PREV+1 lda state sta sprev+1 ldy #29 jsr getobjid1 sta PREV+2 lda state sta sprev+2 rts :null ;this scrn is null screen lda scrnLeft bne :cont :blackscrn ;screen to left is null scrn lda #block sta PREV sta PREV+1 sta PREV+2 lda #0 sta sprev sta sprev+1 sta sprev+2 rts *------------------------------- * * Get objids & states of 10 blocks in row below, * 1 block to left * * In: rowno * Out: BELOW/SBELOW [0-9] * * Use getbelow1 to look at screens other than scrnBelow * (In: A = scrn #) * *------------------------------- getbelow ldx rowno cpx #2 bcc :onscr * Looking below bottom row lda scrnBelow beq :belowblack ;screen below is black jsr calcblue ldy #8 ;skip rmost :loop jsr getobjid sta BELOW+1,y lda state sta SBELOW+1,y dey bpl :loop :cont1 lda scrnBelowL beq :llblack ;screen to l.l. is black jsr calcblue ldy #9 ;u.r. block jsr getobjid sta BELOW lda state sta SBELOW :done lda SCRNUM jsr calcblue ;restore SCRNUM rts * "ONSCREEN": Looking below top or middle row :onscr lda PREV+1,x sta BELOW lda sprev+1,x sta SBELOW lda yindex clc adc #10 tay ldx #1 :loop1 stx xsave jsr getobjid ldx xsave sta BELOW,x lda state sta SBELOW,x iny inx cpx #10 bcc :loop1 rts * Look below null screen :belowblack lda #1 tax :loop2 sta BELOW,x inx cpx #10 bcc :loop2 bcs :cont1 :llblack lda level cmp #12 beq :2 ;sorry Lance! lda #block :1 sta BELOW bpl :done :2 lda #space bpl :1 *------------------------------- * * L O A D O B J E C T * * Load vars with object data * * In: x = object table index * X, OFF, Y, IMG, FACE, TYP, CU, CD, CL, CR, TAB * * Out: XCO, OFFSET, YCO, IMAGE, TABLE * FCharFace, FCharCU-CD-CL-CR * A = objTYP * *------------------------------- loadobj lda objX,x sta FCharX sta XCO lda objOFF,x sta OFFSET lda objY,x sta FCharY sta YCO lda objIMG,x sta IMAGE lda objTAB,x sta TABLE lda objFACE,x sta FCharFace lda objCU,x sta FCharCU lda objCD,x sta FCharCD lda objCL,x sta FCharCL lda objCR,x sta FCharCR lda objTYP,x ]rts rts *------------------------------- * * D R A W F R O N T * *------------------------------- drawfrnt ldx PRECED cpx #gate bne :a jsr DrawGateBF? ;special case :a ldx objid cpx #slicer bne :11 jmp drawslicerf :11 cpx #flask bne :1 lda state and #%11100000 cmp #%10100000 ;5 beq :1 cmp #%01000000 ;2 bcc :1 lda #specialflask bne :12 :1 ldx objid lda fronti,x beq ]rts :12 sta IMAGE lda Ay clc adc fronty,x sta YCO lda blockxco clc adc frontx,x sta XCO cpx #archtop2 bcs :sta do EditorDisk lda #EditorDisk cmp #2 beq :ndunj fin lda BGset1 cmp #1 ;pal beq :ndunj cpx #posts beq :sta ;for dungeon bg set :ndunj cpx #block beq :block jmp maddfore * Special handling for block :block ldy state cpy #numblox bcc :2 ldy #0 :2 lda blockfr,y sta IMAGE * Pieces that go to byte boundaries can be STA'd w/o masking :sta ldx #sta stx OPACITY jmp addfore *------------------------------- * Draw Gate B Front? * (only if kid is to the left of bars) *------------------------------- DrawGateBF? lda rowno cmp KidBlockY bne ]rts ldx colno dex cpx KidBlockX ;is kid in gate block? bne ]rts lda scrnRight cmp KidScrn beq ]rts jmp drawgatebf ;draw gate bars over char *------------------------------- * * D R A W M O V A B L E ' B ' * *------------------------------- drawmb lda PRECED cmp #gate ;check for special cases bne :1 jmp drawgateb ;draw B-section of moving gate :1 cmp #spikes bne :2 jmp drawspikeb :2 cmp #loose bne :3 jmp drawlooseb :3 cmp #torch bne :4 jmp drawtorchb :4 :5 cmp #exit bne :6 jmp drawexitb :6 ]rts rts *------------------------------- * * D R A W M O V A B L E ' C ' * *------------------------------- drawmc lda objid ;is there a piece here? cmp #space beq :ok cmp #panelwof beq :ok cmp #pillartop beq :ok bne ]rts ;if yes, its A-section will cover up ;the C-section of the piece below :ok ldx colno lda BELOW,x ;objid of piece below & to left cmp #gate bne ]rts ;That piece is a gate-- jmp drawgatec ;special case (movable c) *------------------------------- * * Draw C-section (if visible) * *------------------------------- drawc jsr checkc bcc ]rts jsr dodrawc ;OR C-section of piece below & to left jmp domaskb ;Mask B-section of piece to left *------------------------------- * * Return cs if C-section is visible, cc if hidden * *------------------------------- checkc lda objid ;Does this space contain solid floorpiece? beq :vis cmp #pillartop beq :vis cmp #panelwof beq :vis cmp #archtop1 bcs :vis bcc ]rts ;C-section is hidden :vis sec ;C-section is visible ]rts rts *------------------------------- * * Draw C-section of piece below & to left * *------------------------------- dodrawc ldx colno lda BELOW,x ;objid of piece below & to left tax cpx #block beq :block lda piecec,x beq ]rts ;piece has no c-section cmp #panelc0 beq :panel ;special panel handling :cont sta IMAGE lda blockxco sta XCO lda Dy sta YCO lda #ora sta OPACITY jmp add * Special panel handling :panel ldx colno lda SBELOW,x tay cpy #numpans ;# of different panels bcs ]rts lda panelc,y bne :cont rts :block ldx colno lda SBELOW,x tay cpy #numblox bcc :1 ldy #0 :1 lda blockc,y bne :cont ]rts rts *------------------------------- * * Mask B-section of piece to left * *------------------------------- domaskb ldx PRECED lda maskb,x beq ]rts sta IMAGE lda Dy sta YCO lda #and sta OPACITY jmp add *------------------------------- * * Draw B-section of piece to left * *------------------------------- drawb lda objid cmp #block beq ]rts ;B-section hidden by solid block ldx PRECED cpx #space beq :space cpx #floor beq :floor cpx #block beq :block lda pieceb,x beq :stripe cmp #panelb0 beq :panel ;special panel handling * draw regular B-section jsr :cont1 * Add stripe (palace bg set only) :stripe do EditorDisk lda #EditorDisk cmp #2 beq :stripe fin lda BGset1 cmp #1 ;pal bne ]rts :str1 ldx PRECED lda bstripe,x beq ]rts sta IMAGE lda Ay sec sbc #32 jmp :cont2 * Special panel handling :panel ldy spreced cpy #numpans bcs ]rts lda panelb,y bne :cont1 ]rts rts :block ldy spreced cpy #numblox bcc :1 ldy #0 :1 lda blockb,y bne :cont1 :floor ldy spreced cpy #numbpans+1 bcc :3 ldy #0 :3 lda floorb,y beq ]rts sta IMAGE lda floorby,y jmp :cont :space ldy spreced cpy #numbpans+1 bcs ]rts lda spaceb,y beq ]rts sta IMAGE lda spaceby,y jmp :cont * Draw regular B-section :cont1 sta IMAGE lda pieceby,x :cont clc adc Ay :cont2 sta YCO lda blockxco sta XCO lda #ora sta OPACITY jmp add *------------------------------- * * Draw D-section * *------------------------------- redrawd jsr drawd beq ]rts jmp addfore drawd lda #sta sta OPACITY ldx objid cpx #block beq :block cpx #panelwof ;Do we need to mask this D-section? bne :cont ;no :mask lda #ora sta OPACITY :cont lda pieced,x beq ]rts :cont1 sta IMAGE lda blockxco sta XCO lda Dy sta YCO jsr add lda #$ff ]rts rts * Block handling :block ldy state cpy #numblox bcc :1 ldy #0 :1 lda blockd,y bne :cont1 *------------------------------- * * D R A W ' A ' * * (1) If piece to left has intrusive B-section (e.g., panel): * MASK A-section * (2) OR A-section * *------------------------------- drawa lda PRECED cmp #archtop1 beq :special cmp #panelwif beq :needmask cmp #panelwof beq :needmask cmp #pillartop beq :needmask cmp #block bne :nomask :needmask jsr addamask :nomask jmp adda :special ldx objid cpx #panelwof bne :nomask lda #archpanel ;arch ends to L of panel jmp adda1 *------------------------------- addmidezfast lda #UseFastlay jmp addmidez add ]add jmp addback ;self-mod setback lda #addback sta ]add+1 lda #>addback sta ]add+2 rts setmid lda #addmidezfast sta ]add+1 lda #>addmidezfast sta ]add+2 ]rts rts maddfore ldx #mask stx OPACITY jsr addfore ldx #ora stx OPACITY jmp addfore addamask ldx objid lda maska,x beq ]rts sta IMAGE lda blockxco sta XCO lda Ay sta YCO lda #and sta OPACITY jmp add adda ldx objid jsr getpiecea beq ]rts ;nothing here adda1 sta IMAGE lda blockxco sta XCO lda Ay clc adc pieceay,x sta YCO lda #ora sta OPACITY jmp add *------------------------------- * * D R A W M O V A B L E ' A ' * *------------------------------- drawma lda objid cmp #spikes bne :2 jmp drawspikea :2 cmp #slicer bne :3 jmp drawslicera :3 cmp #flask bne :4 jmp drawflaska :4 cmp #sword bne :5 jmp drawsworda :5 ]rts rts *------------------------------- * * D R A W M O V A B L E ' D ' * *------------------------------- drawmd lda objid cmp #loose bne :1 jmp drawloosed :1 ]rts rts *------------------------------- * * D R A W F L O O R * *------------------------------- drawfloor lda PRECED ;empty space to left? bne ]rts ]drawflr jsr addamask jsr adda jsr drawma jmp drawd *------------------------------- * * D R A W H A L F * * Special version of "drawfloor" for climbup * *------------------------------- drawhalf lda PRECED bne ]rts * empty space to left -- mask & draw "A" section ldx objid cpx #floor beq :flr cpx #torch beq :flr cpx #dpressplate beq :flr cpx #exit beq :flr lda BGset1 cmp #1 ;pal? bne ]drawflr ;if there's no halfpiece for this objid, ;redraw full floorpiece cpx #posts beq :post cpx #archbot bne ]drawflr :post jsr :sub lda #CUpost bne :cont :flr jsr :sub lda #CUpiece :cont sta IMAGE lda #ora sta OPACITY jsr add jmp drawd :sub lda #CUmask sta IMAGE lda blockxco sta XCO lda Ay sta YCO ldx objid cpx #dpressplate bne :1 inc YCO ;quick trick for dpressplate :1 lda #and sta OPACITY jmp add *------------------------------- * * S H O R T W I P E * * In: Y = buffer index * *------------------------------- wipesq lda whitebuf,y ]wipe sta height lda #4 sta width lda blockxco sta XCO lda Dy sta YCO lda #$80 jmp addwipe ]rts rts *------------------------------- * * Wipe D-section * *------------------------------- wiped lda objid cmp #pillartop beq ]rts cmp #panelwif beq ]rts cmp #panelwof beq ]rts cmp #block beq ]rts lda #3 jmp ]wipe *------------------------------- * D R A W L O O S E F L O O R " D " *------------------------------- drawloosed lda state jsr getloosey lda loosed,y beq :rts sta IMAGE lda blockxco sta XCO lda Dy sta YCO lda #sta sta OPACITY jmp add ]rts :rts rts *------------------------------- * D R A W L O O S E F L O O R " B " *------------------------------- drawlooseb lda spreced jsr getloosey lda #looseb sta IMAGE lda Ay clc adc looseby,y sta YCO lda #ora sta OPACITY jmp add *------------------------------- * * Get piece "A" * * In: state; X = objid * Out: A = A-section image # * *------------------------------- getpiecea cpx #loose beq :loose lda piecea,x ]rts rts :loose lda state jsr getloosey lda loosea,y rts *------------------------------- * * Get loose floor index * * In: A = state * Out: Y = index * *------------------------------- getloosey do EditorDisk ldy inbuilder beq :1 ldy #1 rts fin :1 tay ;state bpl ]rts and #$7f cmp #Ffalling+1 bcc :ok lda #1 :ok tay ]rts rts *------------------------------- * Draw spikes A *------------------------------- drawspikea ldx state bpl :1 ;hibit clear --> frame # ldx #spikeExt ;hibit set --> spikes extended :1 lda spikea,x beq ]rts sta IMAGE lda blockxco sta XCO lda Ay sec sbc #1 sta YCO lda #ora sta OPACITY jmp add *------------------------------- * Draw spikes B *------------------------------- drawspikeb ldx spreced bpl :1 ;hibit clear --> frame # ldx #spikeExt ;hibit set --> spikes extended :1 lda spikeb,x beq ]rts sta IMAGE lda blockxco sta XCO lda Ay sec sbc #1 sta YCO lda #ora sta OPACITY jmp add *------------------------------- * Draw torch B (flame) *------------------------------- drawtorchb do EditorDisk lda inbuilder bne ]rts fin lda blockxco beq ]rts ;no flame on leftmost torch sta XCO lda Ay sta YCO ldx spreced jsr setupflame ;in gamebg jmp addback ]rts rts *------------------------------- * Draw flask A (bubbles) *------------------------------- drawflaska do EditorDisk lda inbuilder bne ]rts fin lda blockxco sta XCO lda Ay sta YCO ldx state jsr setupflask lda #UseLay jmp addmidezo *------------------------------- * Draw sword A *------------------------------- drawsworda lda #swordgleam0 ldx state cpx #1 bne :0 lda #swordgleam1 :0 sta IMAGE lda blockxco sta XCO lda Ay sta YCO lda #sta sta OPACITY jmp add *------------------------------- * Draw slicer A *------------------------------- drawslicera lda state and #$7f tax cpx #slicerRet bcc :1 ldx #slicerRet ;fully retracted :1 lda slicerseq,x tax dex stx xsave lda blockxco sta XCO lda Ay sta YCO lda state ;hibit set = smeared bpl :clean lda slicerbot2,x bne :3 :clean lda slicerbot,x beq :2 :3 sta IMAGE lda #ora sta OPACITY jsr add ldx xsave :2 lda slicertop,x beq ]rts sta IMAGE lda Ay sec sbc slicergap,x sta YCO lda #ora sta OPACITY jmp add *------------------------------- * Draw slicer front *------------------------------- drawslicerf lda state and #$7f tax cpx #slicerRet bcc :1 ldx #slicerRet ;fully retracted :1 lda slicerseq,x tax dex stx xsave lda blockxco sta XCO lda Ay sta YCO lda slicerfrnt,x beq :2 sta IMAGE jmp maddfore :2 ]rts rts *------------------------------- * Draw exit "b" (stairs) *------------------------------- drawexitb lda #stairs sta IMAGE lda Ay sec sbc #12 sta YCO lda blockxco cmp #36 bcs ]rts ;can't protrude off R clc adc #1 sta XCO lda #sta sta OPACITY lda SCRNUM cmp KidStartScrn beq :nostairs ;assume it's an entrance jsr add :nostairs * draw door, bottom to top lda Dy sec sbc #67 cmp #192 bcs ]rts sta blockthr ;topmost usable line lda spreced lsr lsr sta gateposn ;gateposn := spreced/4 lda Ay sec sbc #14 sbc gateposn sta doortop ;for CROPCHAR :loop sta YCO lda #doormask sta IMAGE lda #and sta OPACITY jsr add lda #door sta IMAGE lda #ora sta OPACITY jsr add lda YCO sec sbc #4 cmp blockthr bcs :loop * repair top lda Ay sec sbc #64 ;Technically part of C-section cmp #192 ;but who cares bcs ]rts sta YCO lda #toprepair sta IMAGE lda #sta sta OPACITY jmp add ]rts rts *------------------------------- * D R A W G A T E " C " *------------------------------- drawgatec lda Dy sta YCO lda #gatecmask sta IMAGE lda #and sta OPACITY jsr add ;mask out triangular area ldx colno lda SBELOW,x ;gate state cmp #gmaxval bcc :1 lda #gmaxval :1 lsr lsr sta gateposn and #$f8 eor #$ff clc adc #1 clc adc gateposn tay ;Y:= (state/4) mod 8 lda gate8c,y sta IMAGE lda #ora sta OPACITY jmp add *------------------------------- * * D R A W G A T E " B " * * Lay down (STA) the gate in sections, bottom * to top. The bottom piece has two blank lines that * erase its trail as the gate rises. * Topmost section has 8 separate shapes, 1-8 pixels high. * *------------------------------- setupdgb lda Dy sec sbc #62 sta blockthr ;topmost line of B-section lda spreced cmp #gmaxval bcc :1 lda #gmaxval :1 lsr lsr clc adc #1 sta gateposn ;gateposn:= state/4 + 1 ;(gatebottom height off floor) lda Ay sec sbc gateposn sta gatebot ;gatebottom YCO ]rts rts *------------------------------- drawgatebf jsr setupdgb * Gate bottom lda #ora sta OPACITY lda gatebot sec sbc #2 sta YCO ;no 2 blank lines at bottom lda #gatebotORA sta IMAGE jsr addfore * Middle pieces :cont lda #gateB1 sta IMAGE lda gatebot sec sbc #12 :loop sta YCO cmp #192 bcs ]rts sec sbc #7 ;grill mid piece is 8 lines high-- bcc :done ;will it stick up out of block area? cmp blockthr bcc :done ;no, we're still safe--keep going jsr addfore lda YCO sec sbc #8 bne :loop :done ;Skip top piece to save a little time ]rts rts *------------------------------- drawgateb jsr setupdgb * First, draw bottom piece clc adc #12 cmp Ay ;over floor/wall boundary? bcc :storit * Bottom piece is partly below floor line -- STA won't work. * We need to redraw b.g., then OR gate bottom on top. :orit jsr restorebot lda gatebot sec sbc #2 sta YCO ;no 2 blank lines at bottom lda #gatebotORA sta IMAGE lda #ora sta OPACITY jsr addback jmp :cont * Gate is above floor line -- STA it :storit lda gatebot sta YCO lda #gatebotSTA sta IMAGE lda #sta sta OPACITY jsr addback * Next, draw as many middle pieces as we need to make * up rest of grill :cont lda #sta sta OPACITY lda #gateB1 sta IMAGE lda gatebot sec sbc #12 :loop sta YCO cmp #192 bcs :rts sec sbc #7 ;grill mid piece is 8 lines high-- bcc :done ;will it stick up out of block area? cmp blockthr bcc :done ;no, we're still safe--keep going jsr addback lda YCO sec sbc #8 bne :loop * now add final piece at top :done lda YCO sec sbc blockthr clc adc #1 ;desired height (0-8 pixels) beq :rts cmp #9 bcs :rts tay lda gate8b-1,y sta IMAGE jsr addback :rts rts *------------------------------- restorebot ldx #gate lda pieceb,x sta IMAGE lda pieceby,x clc adc Ay sta YCO lda blockxco sta XCO lda #sta sta OPACITY jsr add jsr checkc bcc :1 jsr dodrawc :1 jmp drawa *------------------------------- * * Draw object #x * (Add appropriate images to mid table) * * In: x = object table index * *------------------------------- drawobjx jsr loadobj ;Load vars with object data ;A = object type cmp #TypeKid beq :kid cmp #TypeReflect bne :1 :kid jmp DrawKid :1 cmp #TypeShad bne :2 jmp DrawShad :2 cmp #TypeFF bne :3 jmp DrawFF :3 cmp #TypeSword beq :5 cmp #TypeComix bne :4 :5 jmp DrawSword :4 cmp #TypeGd bne :6 jmp DrawGuard :6 ]rts rts *------------------------------- * Draw Falling Floor *------------------------------- DrawFF lda #-1 ;normal sta FCharFace lda IMAGE ;mobframe # sta FCharImage ;use as temp store * A-section lda FCharY sec sbc #3 sta YCO ldx #floor lda maska,x sta IMAGE lda #and sta OPACITY lda #UseLayrsave jsr addmid ldx FCharImage lda loosea,x sta IMAGE lda #ora sta OPACITY lda #UseLay jsr addmid * D-section ldx FCharImage lda loosed,x sta IMAGE lda FCharY sta YCO lda #sta sta OPACITY lda #UseLayrsave jsr addmid * B-section lda FCharX clc adc #4 sta XCO lda FCharY sec sbc #4 sta YCO lda #looseb sta IMAGE lda #ora sta OPACITY lda #UseLayrsave jmp addmid *------------------------------- * * Get objid & state * * In: BlueType/Spec,Y * * Out: A = objid * state = state * * Preserves X & Y * *------------------------------- getobjid lda SCRNUM beq GOnull ;null scrn has no blueprint * Use getobjid1 for screen #s other than SCRNUM getobjid1 do EditorDisk lda inbuilder bne getobjbldr fin lda (BlueSpec),y sta state lda (BlueType),y and #idmask cmp #pressplate beq :plate cmp #upressplate beq :upp rts * Handle depressed pressplate :plate lda state ;LINKLOC index tax lda LINKMAP,x and #%00011111 ;bits 0-4 cmp #2 bcc :up lda #dpressplate ;plate depressed rts :up lda #pressplate ;plate up rts * Handle depressed upressplate :upp lda state tax lda LINKMAP,x and #%00011111 cmp #2 bcc :up1 lda #0 sta state lda #floor ;depressed upp looks just like floor rts :up1 lda #upressplate rts * Null screen is black GOnull do EditorDisk lda inmenu bne getobjbldr fin lda #space rts *------------------------------- * * In builder: BlueSpec contains initial gadget settings * *------------------------------- do EditorDisk getobjbldr lda (BlueType),y and #idmask pha jsr getinitobj1 bcs :ok lda (BlueSpec),y :ok sta state pla rts fin *------------------------------- * * Sort objects in sort list into back-to-front order * (Foremost object should be at bottom of list) * *------------------------------- sortlist :newpass lda #0 sta switches ;no switches yet this pass ldx sortX ;start at bottom of list :loop cpx #1 ;at top of list? beq :attop ;yes--pass complated stx xsave jsr compare ;Is obj[X] in front of obj[X-1]? ldx xsave bcc :ok ;Yes--continue ;No--switch objects lda sortX,x pha lda sortX-1,x sta sortX,x pla sta sortX-1,x ;switch [X] with [X-1] :ok dex bne :loop ;move up in list * At top of list--pass completed :attop lda switches ;Any switches this pass? bne :newpass ;Yes--do it again * No switches made--objects are in order :rts rts *------------------------------- * * Compare object [xsave] with object [xsave-1] * * If X is IN FRONT OF X-1, or if it doesn't matter, return cc; * If X is BEHIND X-1, return cs (switch 'em). * *------------------------------- compare lda sortX,x sta obj1 ;obj index [X] lda sortX-1,x sta obj2 ;obj index [X-1] ldx obj1 ldy obj2 lda objTYP,x cmp #TypeShad beq :xinfront ;enemy is always in front lda objY,x cmp objY,y beq :same bcc :xinfront bcs :yinfront :same :xinfront clc rts :yinfront sec rts *------------------------------- * * Get initial state of object * * In: BlueType, BlueSpec, Y * * Return cs if it matters, else cc * *------------------------------- GETINITOBJ lda (BlueType),y and #idmask ;get objid getinitobj1 cmp #gate beq :okgate cmp #loose beq :okloose cmp #flask beq :okflask bne :skip ;if it isn't a gadget, leave it alone :okgate lda (BlueSpec),y ;1=gate up, 2=gate down, etc. tax lda initsettings-1,x sec rts :okloose lda #0 ;loose floor rts :okflask lda (BlueSpec),y asl asl asl asl asl ;5x sec rts :skip clc ]rts rts *------------------------------- metbufs3 jsr mbsub iny metbufs2 jsr mbsub iny mbsub ora redbuf,y ora floorbuf,y ora halfbuf,y ora fredbuf,y ora wipebuf,y rts *------------------------------- lst ds 1 usr $a9,3,$490,*-org lst off \ No newline at end of file +* frameadv +EditorDisk = 0 ;1 = dunj, 2 = palace +org = $1290 + lst off + tr on +*------------------------------- + org org + + jmp SURE + jmp FAST + jmp GETINITOBJ + +*------------------------------- + lst + put eq + lst + put gameeq + lst off + put bgdata + lst off + +initsettings + db gmaxval,gminval + + dum locals +index ds 1 +rowno ds 1 +colno ds 1 +yindex ds 1 +objid ds 1 +state ds 1 +Ay ds 1 +Dy ds 1 +gateposn ds 1 +gatebot ds 1 +xsave ds 1 +blockxco ds 1 +switches ds 1 +obj1 ds 1 +obj2 ds 1 +blockthr ds 1 + dend + +*------------------------------- +* +* Draw entire 10 x 3 screen from scratch +* +*------------------------------- +SURE + lda #1 + sta genCLS ;clear screen + + jsr setback ;draw on bg plane + + jsr getprev ;get 3 rightmost blocks of screen to left + + lda SCRNUM + jsr calcblue ;get blueprint base addr + +* Draw 3 rows of 10 blocks (L-R, T-B) + + ldy #2 +:row sty rowno ;0 = top row, 2 = bottom row + + lda BlockBot+1,y + sta Dy ;get Y-coord for bottom of D-section + sec + sbc #3 + sta Ay ;& A-section + + lda Mult10,y + sta yindex ;block # (0-29) + + lda PREV,y + sta PRECED + lda sprev,y + sta spreced ;get objid & state of preceding block + + jsr getbelow ;get 10 topmost blocks of screen below + + lda #0 + sta colno ;0 = leftmost column, 9 = rightmost +:loop asl + asl + sta XCO + sta blockxco ;get X-coord for A-section + + ldy yindex + jsr getobjid + sta objid ;get object id# of current block + + jsr RedBlockSure ;Redraw entire block + + lda objid + sta PRECED + lda state + sta spreced ;Move on to next block + + inc yindex + inc colno + + lda colno + cmp #10 + bcc :loop ;...until we've done 10 blocks + +:nextln ldy rowno + beq :done + dey + jmp :row ;...and 3 rows + +* Now draw bottom row of screen above (D-sections only) + +:done ldy #2 ;bottom row of scrn above + sty rowno + + lda #2 + sta Dy + lda #-1 + sta Ay ;get screen Y-coords + + lda Mult10,y + sta yindex + + lda #0 + sta PRECED + + lda scrnBelow + pha + lda scrnBelowL + pha ;save current values on stack + + lda SCRNUM + sta scrnBelow + lda scrnLeft + sta scrnBelowL ;& pretend we're on screen above + +* Draw 10 blocks, L-R + + jsr getbelow + + lda scrnAbove + jsr calcblue + + lda #0 + sta colno +:dloop + asl + asl + sta XCO + sta blockxco + + lda scrnAbove + bne :1 + lda #floor ;If screen above is null screen, + bne :2 ;draw a row of solid floorpieces + +:1 ldy yindex + jsr getobjid1 +:2 sta objid + + jsr RedDSure ;Draw D-section + + lda objid + sta PRECED + lda state + sta spreced + + inc yindex + inc colno + + lda colno + cmp #10 + bcc :dloop + + pla ;Restore original screen values + sta scrnBelowL + pla + sta scrnBelow +]rts rts + +*------------------------------- +* +* Fast screen redraw +* +* Same general structure as SURE, but redraws only those +* blocks specified by redraw buffers. +* +*------------------------------- +FAST + jsr getprev + + lda SCRNUM + jsr calcblue + + lda #0 + ldy #20 + jsr metbufs3 ;If strength meter is in danger of + sta redkidmeter ;being overwritten, mark it for redraw + + lda #0 + ldy #28 + jsr metbufs2 + sta redoppmeter ;opponent meter too + + lda #30 + sta yindex + jsr drawobjs ;Draw o.s. characters first + +* Draw 3 rows of 10 blocks (L-R, T-B) + + ldy #2 +:row sty rowno + + lda BlockBot+1,y + sta Dy + sec + sbc #3 + sta Ay + + lda Mult10,y + sta yindex + + lda PREV,y + sta PRECED + lda sprev,y + sta spreced + + jsr getbelow + + lda #0 + sta colno + +:loop asl + asl + sta XCO + sta blockxco + + ldy yindex + jsr getobjid + sta objid + + jsr RedBlockFast + + lda objid + sta PRECED + lda state + sta spreced + + inc yindex + inc colno + + lda colno + cmp #10 + bcs :nextln + jmp :loop + +:nextln ldy rowno + beq :cont + dey + jmp :row + +* Now draw bottom row of screen above (D-sections only) + +:cont jsr setback + + ldy #2 + sty rowno + + lda #2 + sta Dy + lda #-1 + sta Ay + + lda Mult10,y + sta yindex + + lda #0 + sta PRECED + + lda scrnBelow + pha + lda scrnBelowL + pha + + lda SCRNUM + sta scrnBelow + lda scrnLeft + sta scrnBelowL + + jsr getbelow + + lda scrnAbove + beq :done + jsr calcblue + + lda #0 + sta colno +:dloop + asl + asl + sta blockxco + sta XCO + + ldy yindex + jsr getobjid1 + sta objid + + jsr RedDFast + + lda objid + sta PRECED + lda state + sta spreced + + inc yindex + inc colno + + lda colno + cmp #10 + bcc :dloop + +:done + pla + sta scrnBelowL + pla + sta scrnBelow + +* Now draw comix (impact stars) & strength meters + + lda #$ff + sta yindex + jsr drawobjs ;draw comix (index = -1) + + do EditorDisk + lda inbuilder + bne ]rts + fin + + jmp updatemeters + +*------------------------------- +* +* Redraw entire block +* +*------------------------------- +RedBlockSure + jsr drawc ;C-section of piece below & to left + jsr drawmc + + jsr drawb ;B-section of piece to left + jsr drawmb + + jsr drawd ;D-section + jsr drawmd + + jsr drawa ;A-section + jsr drawma + + jmp drawfrnt ;A-section frontpiece +;(Note: This is necessary in case we do a +;layersave before we get to f.g. plane) + +*------------------------------- +* +* Redraw entire D-section +* +*------------------------------- +RedDSure + jsr drawc + jsr drawmc + jsr drawb + jsr drawd + jsr drawmd + jmp drawfrnt + +*------------------------------- +* +* Partial block redraw (as specified by redraw buffers) +* +*------------------------------- +RedBlockFast + lda wipebuf,y ;is wipebuf marked? + beq :skipwipe ;no--skip it + sec + sbc #1 + sta wipebuf,y ;decrement wipebuf + + jsr wipesq ;& wipe this block! + + ldy yindex + +:skipwipe + lda redbuf,y + beq :skipred + sec + sbc #1 + sta redbuf,y + + jsr setback + jsr RedBlockSure + + ldy yindex + bpl :skipmove + +:skipred + lda movebuf,y + beq :skipmove + sec + sbc #1 + sta movebuf,y + + jsr setback + jsr drawmc + jsr drawmb + jsr drawma + + ldy yindex + +:skipmove + lda floorbuf,y + beq :skipfloor + sec + sbc #1 + sta floorbuf,y + + jsr setmid + jsr drawfloor + + ldy yindex + bpl :skiphalf + +:skipfloor + lda halfbuf,y + beq :skiphalf + sec + sbc #1 + sta halfbuf,y + + jsr setmid + jsr drawhalf + + ldy yindex + +:skiphalf + lda objbuf,y + beq :skipobj + + lda #0 + sta objbuf,y + + jsr drawobjs ;draw all objects in this block + + lda blockxco + sta XCO + + ldy yindex + +:skipobj + lda fredbuf,y + beq :skipfred + sec + sbc #1 + sta fredbuf,y + + jsr drawfrnt + + ldy yindex + +:skipfred +]rts rts + +*------------------------------- +* +* Partial D-section redraw +* +*------------------------------- +RedDFast + ldy colno + lda topbuf,y ;is topbuf marked? + beq :skip ;no--skip it + sec + sbc #1 + sta topbuf,y + + jsr wiped + jsr drawc + jsr drawmc + jsr drawb + jsr redrawd ;(both bg and fg) + jsr drawmd + jsr drawfrnt +:skip +]rts rts + +*------------------------------- +* +* Draw objects +* +* Draw object/s with index # = yindex +* (Add appropriate images to mid list) +* +*------------------------------- +drawobjs + +* Go through obj list looking for objINDX = yindex + + lda objX + beq :rts + + ldy #0 ;y = sort list index + ldx #1 ;x = object list index + +:loop lda objINDX,x + cmp yindex + bne :next +;Found a match--add object to sort list + txa + iny + sta sortX,y + +:next inx + cpx objX + bcc :loop + beq :loop + + cpy #0 + beq :rts + sty sortX ;# of objects in sort list + +* Sort them into back-to-front order + + jsr sortlist + +* Transfer sorted objects from obj list to mid list + + ldx #1 +:loop2 + stx xsave + + lda sortX,x + tax ;obj list index + + jsr drawobjx ;draw object #x + + ldx xsave + inx + cpx sortX + bcc :loop2 + beq :loop2 +;Done +:rts rts + +*------------------------------- +* +* Get objids & states of 3 rightmost blocks +* of left-neighboring screen +* +* Out: PREV/sprev [0-2] +* +*------------------------------- +getprev lda SCRNUM + beq :null + + lda scrnLeft + beq :blackscrn + +:cont jsr calcblue ;screen to left + + ldy #9 + jsr getobjid1 + sta PREV + lda state + sta sprev + + ldy #19 + jsr getobjid1 + sta PREV+1 + lda state + sta sprev+1 + + ldy #29 + jsr getobjid1 + sta PREV+2 + lda state + sta sprev+2 + + rts + +:null ;this scrn is null screen + lda scrnLeft + bne :cont + +:blackscrn ;screen to left is null scrn + lda #block + sta PREV + sta PREV+1 + sta PREV+2 + lda #0 + sta sprev + sta sprev+1 + sta sprev+2 + rts + +*------------------------------- +* +* Get objids & states of 10 blocks in row below, +* 1 block to left +* +* In: rowno +* Out: BELOW/SBELOW [0-9] +* +* Use getbelow1 to look at screens other than scrnBelow +* (In: A = scrn #) +* +*------------------------------- +getbelow + ldx rowno + cpx #2 + bcc :onscr + +* Looking below bottom row + + lda scrnBelow + beq :belowblack ;screen below is black + jsr calcblue + + ldy #8 ;skip rmost +:loop + jsr getobjid + + sta BELOW+1,y + lda state + sta SBELOW+1,y + dey + bpl :loop +:cont1 + lda scrnBelowL + beq :llblack ;screen to l.l. is black + jsr calcblue + + ldy #9 ;u.r. block + jsr getobjid + sta BELOW + lda state + sta SBELOW +:done + lda SCRNUM + jsr calcblue ;restore SCRNUM + rts + +* "ONSCREEN": Looking below top or middle row + +:onscr lda PREV+1,x + sta BELOW + lda sprev+1,x + sta SBELOW + + lda yindex + clc + adc #10 + tay + + ldx #1 + +:loop1 stx xsave + jsr getobjid + ldx xsave + + sta BELOW,x + + lda state + sta SBELOW,x + + iny + inx + cpx #10 + bcc :loop1 + + rts + +* Look below null screen + +:belowblack + lda #1 + tax +:loop2 sta BELOW,x + inx + cpx #10 + bcc :loop2 + bcs :cont1 + +:llblack + lda level + cmp #12 + beq :2 ;sorry Lance! + lda #block +:1 sta BELOW + bpl :done +:2 lda #space + bpl :1 + +*------------------------------- +* +* L O A D O B J E C T +* +* Load vars with object data +* +* In: x = object table index +* X, OFF, Y, IMG, FACE, TYP, CU, CD, CL, CR, TAB +* +* Out: XCO, OFFSET, YCO, IMAGE, TABLE +* FCharFace, FCharCU-CD-CL-CR +* A = objTYP +* +*------------------------------- +loadobj + lda objX,x + sta FCharX + sta XCO + + lda objOFF,x + sta OFFSET + + lda objY,x + sta FCharY + sta YCO + + lda objIMG,x + sta IMAGE + + lda objTAB,x + sta TABLE + + lda objFACE,x + sta FCharFace + + lda objCU,x + sta FCharCU + lda objCD,x + sta FCharCD + lda objCL,x + sta FCharCL + lda objCR,x + sta FCharCR + + lda objTYP,x +]rts rts + +*------------------------------- +* +* D R A W F R O N T +* +*------------------------------- +drawfrnt + ldx PRECED + cpx #gate + bne :a + jsr DrawGateBF? ;special case + +:a ldx objid + cpx #slicer + bne :11 + jmp drawslicerf +:11 cpx #flask + bne :1 + lda state + and #%11100000 + cmp #%10100000 ;5 + beq :1 + cmp #%01000000 ;2 + bcc :1 + lda #specialflask + bne :12 + +:1 ldx objid + lda fronti,x + beq ]rts +:12 sta IMAGE + + lda Ay + clc + adc fronty,x + sta YCO + + lda blockxco + clc + adc frontx,x + sta XCO + + cpx #archtop2 + bcs :sta + + do EditorDisk + lda #EditorDisk + cmp #2 + beq :ndunj + fin + + lda BGset1 + cmp #1 ;pal + beq :ndunj + + cpx #posts + beq :sta ;for dungeon bg set +:ndunj cpx #block + beq :block + + jmp maddfore + +* Special handling for block + +:block ldy state + cpy #numblox + bcc :2 + ldy #0 +:2 lda blockfr,y + sta IMAGE + +* Pieces that go to byte boundaries can be STA'd w/o masking + +:sta ldx #sta + stx OPACITY + jmp addfore + +*------------------------------- +* Draw Gate B Front? +* (only if kid is to the left of bars) +*------------------------------- +DrawGateBF? + lda rowno + cmp KidBlockY + bne ]rts + + ldx colno + dex + cpx KidBlockX ;is kid in gate block? + bne ]rts + lda scrnRight + cmp KidScrn + beq ]rts + + jmp drawgatebf ;draw gate bars over char + +*------------------------------- +* +* D R A W M O V A B L E ' B ' +* +*------------------------------- +drawmb + lda PRECED + + cmp #gate ;check for special cases + bne :1 + jmp drawgateb ;draw B-section of moving gate + +:1 cmp #spikes + bne :2 + jmp drawspikeb + +:2 cmp #loose + bne :3 + jmp drawlooseb + +:3 cmp #torch + bne :4 + jmp drawtorchb +:4 +:5 cmp #exit + bne :6 + jmp drawexitb + +:6 +]rts rts + +*------------------------------- +* +* D R A W M O V A B L E ' C ' +* +*------------------------------- +drawmc + lda objid ;is there a piece here? + cmp #space + beq :ok + cmp #panelwof + beq :ok + cmp #pillartop + beq :ok + + bne ]rts ;if yes, its A-section will cover up +;the C-section of the piece below +:ok + ldx colno + lda BELOW,x ;objid of piece below & to left + + cmp #gate + bne ]rts + + ;That piece is a gate-- + jmp drawgatec ;special case (movable c) + +*------------------------------- +* +* Draw C-section (if visible) +* +*------------------------------- +drawc + jsr checkc + bcc ]rts + jsr dodrawc ;OR C-section of piece below & to left + jmp domaskb ;Mask B-section of piece to left + +*------------------------------- +* +* Return cs if C-section is visible, cc if hidden +* +*------------------------------- +checkc + lda objid ;Does this space contain solid floorpiece? + beq :vis + cmp #pillartop + beq :vis + cmp #panelwof + beq :vis + cmp #archtop1 + bcs :vis + bcc ]rts ;C-section is hidden +:vis sec ;C-section is visible +]rts rts + +*------------------------------- +* +* Draw C-section of piece below & to left +* +*------------------------------- +dodrawc + ldx colno + lda BELOW,x ;objid of piece below & to left + tax + cpx #block + beq :block + lda piecec,x + beq ]rts ;piece has no c-section + cmp #panelc0 + beq :panel ;special panel handling +:cont sta IMAGE + lda blockxco + sta XCO + lda Dy + sta YCO + lda #ora + sta OPACITY + jmp add + +* Special panel handling + +:panel ldx colno + lda SBELOW,x + tay + cpy #numpans ;# of different panels + bcs ]rts + lda panelc,y + bne :cont + rts + +:block ldx colno + lda SBELOW,x + tay + cpy #numblox + bcc :1 + ldy #0 +:1 lda blockc,y + bne :cont +]rts rts + +*------------------------------- +* +* Mask B-section of piece to left +* +*------------------------------- +domaskb + ldx PRECED + lda maskb,x + beq ]rts + sta IMAGE + + lda Dy + sta YCO + lda #and + sta OPACITY + jmp add + +*------------------------------- +* +* Draw B-section of piece to left +* +*------------------------------- +drawb + lda objid + cmp #block + beq ]rts ;B-section hidden by solid block + + ldx PRECED + cpx #space + beq :space + cpx #floor + beq :floor + cpx #block + beq :block + lda pieceb,x + beq :stripe + cmp #panelb0 + beq :panel ;special panel handling + +* draw regular B-section + + jsr :cont1 + +* Add stripe (palace bg set only) + +:stripe do EditorDisk + lda #EditorDisk + cmp #2 + beq :stripe + fin + + lda BGset1 + cmp #1 ;pal + bne ]rts + +:str1 ldx PRECED + lda bstripe,x + beq ]rts + sta IMAGE + lda Ay + sec + sbc #32 + jmp :cont2 + +* Special panel handling + +:panel ldy spreced + cpy #numpans + bcs ]rts + lda panelb,y + bne :cont1 +]rts rts + +:block ldy spreced + cpy #numblox + bcc :1 + ldy #0 +:1 lda blockb,y + bne :cont1 + +:floor ldy spreced + cpy #numbpans+1 + bcc :3 + ldy #0 +:3 lda floorb,y + beq ]rts + sta IMAGE + lda floorby,y + jmp :cont + +:space ldy spreced + cpy #numbpans+1 + bcs ]rts + lda spaceb,y + beq ]rts + sta IMAGE + lda spaceby,y + jmp :cont + +* Draw regular B-section + +:cont1 sta IMAGE + lda pieceby,x +:cont clc + adc Ay +:cont2 sta YCO + lda blockxco + sta XCO + lda #ora + sta OPACITY + jmp add + +*------------------------------- +* +* Draw D-section +* +*------------------------------- +redrawd jsr drawd + beq ]rts + jmp addfore + +drawd lda #sta + sta OPACITY + ldx objid + cpx #block + beq :block + cpx #panelwof ;Do we need to mask this D-section? + bne :cont ;no +:mask lda #ora + sta OPACITY +:cont lda pieced,x + beq ]rts +:cont1 sta IMAGE + lda blockxco + sta XCO + lda Dy + sta YCO + jsr add + lda #$ff +]rts rts + +* Block handling + +:block ldy state + cpy #numblox + bcc :1 + ldy #0 +:1 lda blockd,y + bne :cont1 + +*------------------------------- +* +* D R A W ' A ' +* +* (1) If piece to left has intrusive B-section (e.g., panel): +* MASK A-section +* (2) OR A-section +* +*------------------------------- +drawa + lda PRECED + cmp #archtop1 + beq :special + cmp #panelwif + beq :needmask + cmp #panelwof + beq :needmask + cmp #pillartop + beq :needmask + cmp #block + bne :nomask + +:needmask jsr addamask + +:nomask jmp adda + +:special ldx objid + cpx #panelwof + bne :nomask + lda #archpanel ;arch ends to L of panel + jmp adda1 + +*------------------------------- +addmidezfast + lda #UseFastlay + jmp addmidez +add +]add jmp addback ;self-mod + +setback lda #addback + sta ]add+1 + lda #>addback + sta ]add+2 + rts + +setmid lda #addmidezfast + sta ]add+1 + lda #>addmidezfast + sta ]add+2 +]rts rts + +maddfore ldx #mask + stx OPACITY + jsr addfore + ldx #ora + stx OPACITY + jmp addfore + +addamask ldx objid + lda maska,x + beq ]rts + sta IMAGE + lda blockxco + sta XCO + lda Ay + sta YCO + lda #and + sta OPACITY + jmp add + +adda ldx objid + jsr getpiecea + beq ]rts ;nothing here +adda1 sta IMAGE + lda blockxco + sta XCO + lda Ay + clc + adc pieceay,x + sta YCO + lda #ora + sta OPACITY + jmp add + +*------------------------------- +* +* D R A W M O V A B L E ' A ' +* +*------------------------------- +drawma + lda objid + cmp #spikes + bne :2 + jmp drawspikea + +:2 cmp #slicer + bne :3 + jmp drawslicera + +:3 cmp #flask + bne :4 + jmp drawflaska + +:4 cmp #sword + bne :5 + jmp drawsworda +:5 +]rts rts + +*------------------------------- +* +* D R A W M O V A B L E ' D ' +* +*------------------------------- +drawmd + lda objid + cmp #loose + bne :1 + jmp drawloosed + +:1 +]rts rts +*------------------------------- +* +* D R A W F L O O R +* +*------------------------------- +drawfloor + lda PRECED ;empty space to left? + bne ]rts +]drawflr + jsr addamask + jsr adda + jsr drawma + jmp drawd + +*------------------------------- +* +* D R A W H A L F +* +* Special version of "drawfloor" for climbup +* +*------------------------------- +drawhalf + lda PRECED + bne ]rts + +* empty space to left -- mask & draw "A" section + + ldx objid + cpx #floor + beq :flr + cpx #torch + beq :flr + cpx #dpressplate + beq :flr + cpx #exit + beq :flr + + lda BGset1 + cmp #1 ;pal? + bne ]drawflr ;if there's no halfpiece for this objid, +;redraw full floorpiece + cpx #posts + beq :post + cpx #archbot + bne ]drawflr + +:post jsr :sub + lda #CUpost + bne :cont + +:flr jsr :sub + lda #CUpiece +:cont sta IMAGE + lda #ora + sta OPACITY + jsr add + jmp drawd + +:sub lda #CUmask + sta IMAGE + lda blockxco + sta XCO + lda Ay + sta YCO + ldx objid + cpx #dpressplate + bne :1 + inc YCO ;quick trick for dpressplate +:1 lda #and + sta OPACITY + jmp add + +*------------------------------- +* +* S H O R T W I P E +* +* In: Y = buffer index +* +*------------------------------- +wipesq + lda whitebuf,y +]wipe sta height + + lda #4 + sta width + + lda blockxco + sta XCO + + lda Dy + sta YCO + + lda #$80 + jmp addwipe +]rts rts + +*------------------------------- +* +* Wipe D-section +* +*------------------------------- +wiped + lda objid + cmp #pillartop + beq ]rts + cmp #panelwif + beq ]rts + cmp #panelwof + beq ]rts + cmp #block + beq ]rts + + lda #3 + jmp ]wipe + +*------------------------------- +* D R A W L O O S E F L O O R " D " +*------------------------------- +drawloosed + lda state + jsr getloosey + + lda loosed,y + beq :rts + sta IMAGE + + lda blockxco + sta XCO + lda Dy + sta YCO + + lda #sta + sta OPACITY + + jmp add +]rts +:rts rts + +*------------------------------- +* D R A W L O O S E F L O O R " B " +*------------------------------- +drawlooseb + lda spreced + jsr getloosey + + lda #looseb + sta IMAGE + + lda Ay + clc + adc looseby,y + sta YCO + + lda #ora + sta OPACITY + + jmp add + +*------------------------------- +* +* Get piece "A" +* +* In: state; X = objid +* Out: A = A-section image # +* +*------------------------------- +getpiecea + cpx #loose + beq :loose + + lda piecea,x +]rts rts + +:loose lda state + jsr getloosey + lda loosea,y + rts + +*------------------------------- +* +* Get loose floor index +* +* In: A = state +* Out: Y = index +* +*------------------------------- +getloosey + do EditorDisk + ldy inbuilder + beq :1 + ldy #1 + rts + fin + +:1 tay ;state + bpl ]rts + and #$7f + cmp #Ffalling+1 + bcc :ok + lda #1 +:ok tay +]rts rts + +*------------------------------- +* Draw spikes A +*------------------------------- +drawspikea + ldx state + bpl :1 ;hibit clear --> frame # + ldx #spikeExt ;hibit set --> spikes extended +:1 lda spikea,x + beq ]rts + sta IMAGE + lda blockxco + sta XCO + lda Ay + sec + sbc #1 + sta YCO + lda #ora + sta OPACITY + jmp add + +*------------------------------- +* Draw spikes B +*------------------------------- +drawspikeb + ldx spreced + bpl :1 ;hibit clear --> frame # + ldx #spikeExt ;hibit set --> spikes extended +:1 lda spikeb,x + beq ]rts + sta IMAGE + lda blockxco + sta XCO + lda Ay + sec + sbc #1 + sta YCO + lda #ora + sta OPACITY + jmp add + +*------------------------------- +* Draw torch B (flame) +*------------------------------- +drawtorchb + do EditorDisk + lda inbuilder + bne ]rts + fin + + lda blockxco + beq ]rts ;no flame on leftmost torch + sta XCO + lda Ay + sta YCO + ldx spreced + jsr setupflame ;in gamebg + jmp addback +]rts rts + +*------------------------------- +* Draw flask A (bubbles) +*------------------------------- +drawflaska + do EditorDisk + lda inbuilder + bne ]rts + fin + + lda blockxco + sta XCO + lda Ay + sta YCO + ldx state + jsr setupflask + lda #UseLay + jmp addmidezo + +*------------------------------- +* Draw sword A +*------------------------------- +drawsworda + lda #swordgleam0 + ldx state + cpx #1 + bne :0 + lda #swordgleam1 +:0 sta IMAGE + lda blockxco + sta XCO + lda Ay + sta YCO + lda #sta + sta OPACITY + jmp add + +*------------------------------- +* Draw slicer A +*------------------------------- +drawslicera + lda state + and #$7f + tax + cpx #slicerRet + bcc :1 + ldx #slicerRet ;fully retracted +:1 lda slicerseq,x + tax + dex + stx xsave + + lda blockxco + sta XCO + lda Ay + sta YCO + lda state ;hibit set = smeared + bpl :clean + lda slicerbot2,x + bne :3 +:clean lda slicerbot,x + beq :2 +:3 sta IMAGE + lda #ora + sta OPACITY + jsr add + ldx xsave + +:2 lda slicertop,x + beq ]rts + sta IMAGE + lda Ay + sec + sbc slicergap,x + sta YCO + lda #ora + sta OPACITY + jmp add + +*------------------------------- +* Draw slicer front +*------------------------------- +drawslicerf + lda state + and #$7f + tax + cpx #slicerRet + bcc :1 + ldx #slicerRet ;fully retracted +:1 lda slicerseq,x + tax + dex + stx xsave + + lda blockxco + sta XCO + lda Ay + sta YCO + lda slicerfrnt,x + beq :2 + sta IMAGE + jmp maddfore +:2 +]rts rts + +*------------------------------- +* Draw exit "b" (stairs) +*------------------------------- +drawexitb + lda #stairs + sta IMAGE + + lda Ay + sec + sbc #12 + sta YCO + + lda blockxco + cmp #36 + bcs ]rts ;can't protrude off R + clc + adc #1 + sta XCO + + lda #sta + sta OPACITY + + lda SCRNUM + cmp KidStartScrn + beq :nostairs ;assume it's an entrance + jsr add +:nostairs + +* draw door, bottom to top + + lda Dy + sec + sbc #67 + cmp #192 + bcs ]rts + sta blockthr ;topmost usable line + + lda spreced + lsr + lsr + sta gateposn ;gateposn := spreced/4 + + lda Ay + sec + sbc #14 + sbc gateposn + sta doortop ;for CROPCHAR +:loop sta YCO + + lda #doormask + sta IMAGE + lda #and + sta OPACITY + jsr add + + lda #door + sta IMAGE + lda #ora + sta OPACITY + jsr add + + lda YCO + sec + sbc #4 + cmp blockthr + bcs :loop + +* repair top + + lda Ay + sec + sbc #64 ;Technically part of C-section + cmp #192 ;but who cares + bcs ]rts + + sta YCO + + lda #toprepair + sta IMAGE + lda #sta + sta OPACITY + jmp add + +]rts rts + +*------------------------------- +* D R A W G A T E " C " +*------------------------------- +drawgatec + lda Dy + sta YCO + lda #gatecmask + sta IMAGE + lda #and + sta OPACITY + jsr add ;mask out triangular area + + ldx colno + lda SBELOW,x ;gate state + cmp #gmaxval + bcc :1 + lda #gmaxval +:1 lsr + lsr + sta gateposn + and #$f8 + eor #$ff + clc + adc #1 + clc + adc gateposn + tay ;Y:= (state/4) mod 8 + lda gate8c,y + sta IMAGE + + lda #ora + sta OPACITY + jmp add + +*------------------------------- +* +* D R A W G A T E " B " +* +* Lay down (STA) the gate in sections, bottom +* to top. The bottom piece has two blank lines that +* erase its trail as the gate rises. +* Topmost section has 8 separate shapes, 1-8 pixels high. +* +*------------------------------- +setupdgb + lda Dy + sec + sbc #62 + sta blockthr ;topmost line of B-section + + lda spreced + cmp #gmaxval + bcc :1 + lda #gmaxval +:1 lsr + lsr + clc + adc #1 + sta gateposn ;gateposn:= state/4 + 1 +;(gatebottom height off floor) + lda Ay + sec + sbc gateposn + sta gatebot ;gatebottom YCO +]rts rts + +*------------------------------- +drawgatebf + jsr setupdgb + +* Gate bottom + + lda #ora + sta OPACITY + + lda gatebot + sec + sbc #2 + sta YCO ;no 2 blank lines at bottom + + lda #gatebotORA + sta IMAGE + + jsr addfore + +* Middle pieces + +:cont + lda #gateB1 + sta IMAGE + + lda gatebot + sec + sbc #12 + +:loop sta YCO + cmp #192 + bcs ]rts + + sec + sbc #7 ;grill mid piece is 8 lines high-- + bcc :done ;will it stick up out of block area? + cmp blockthr + bcc :done +;no, we're still safe--keep going + jsr addfore + + lda YCO + sec + sbc #8 + bne :loop +:done + ;Skip top piece to save a little time +]rts rts + +*------------------------------- +drawgateb + jsr setupdgb + +* First, draw bottom piece + + clc + adc #12 + cmp Ay ;over floor/wall boundary? + bcc :storit + +* Bottom piece is partly below floor line -- STA won't work. +* We need to redraw b.g., then OR gate bottom on top. + +:orit + jsr restorebot + + lda gatebot + sec + sbc #2 + sta YCO ;no 2 blank lines at bottom + + lda #gatebotORA + sta IMAGE + + lda #ora + sta OPACITY + + jsr addback + + jmp :cont + +* Gate is above floor line -- STA it + +:storit lda gatebot + sta YCO + + lda #gatebotSTA + sta IMAGE + + lda #sta + sta OPACITY + + jsr addback + +* Next, draw as many middle pieces as we need to make +* up rest of grill + +:cont + lda #sta + sta OPACITY + + lda #gateB1 + sta IMAGE + + lda gatebot + sec + sbc #12 + +:loop sta YCO + cmp #192 + bcs :rts + + sec + sbc #7 ;grill mid piece is 8 lines high-- + bcc :done ;will it stick up out of block area? + cmp blockthr + bcc :done +;no, we're still safe--keep going + jsr addback + + lda YCO + sec + sbc #8 + bne :loop + +* now add final piece at top + +:done lda YCO + sec + sbc blockthr + clc + adc #1 ;desired height (0-8 pixels) + + beq :rts + cmp #9 + bcs :rts + + tay + lda gate8b-1,y + sta IMAGE + + jsr addback + +:rts rts + +*------------------------------- +restorebot + ldx #gate + lda pieceb,x + sta IMAGE + lda pieceby,x + clc + adc Ay + sta YCO + lda blockxco + sta XCO + lda #sta + sta OPACITY + jsr add + + jsr checkc + bcc :1 + jsr dodrawc +:1 jmp drawa + +*------------------------------- +* +* Draw object #x +* (Add appropriate images to mid table) +* +* In: x = object table index +* +*------------------------------- +drawobjx + jsr loadobj ;Load vars with object data +;A = object type + cmp #TypeKid + beq :kid + cmp #TypeReflect + bne :1 +:kid jmp DrawKid + +:1 cmp #TypeShad + bne :2 + jmp DrawShad + +:2 cmp #TypeFF + bne :3 + jmp DrawFF + +:3 cmp #TypeSword + beq :5 + cmp #TypeComix + bne :4 +:5 jmp DrawSword + +:4 cmp #TypeGd + bne :6 + jmp DrawGuard +:6 +]rts rts + +*------------------------------- +* Draw Falling Floor +*------------------------------- +DrawFF + lda #-1 ;normal + sta FCharFace + + lda IMAGE ;mobframe # + sta FCharImage ;use as temp store + +* A-section + + lda FCharY + sec + sbc #3 + sta YCO + ldx #floor + lda maska,x + sta IMAGE + lda #and + sta OPACITY + lda #UseLayrsave + jsr addmid + + ldx FCharImage + lda loosea,x + sta IMAGE + lda #ora + sta OPACITY + lda #UseLay + jsr addmid + +* D-section + + ldx FCharImage + lda loosed,x + sta IMAGE + lda FCharY + sta YCO + lda #sta + sta OPACITY + lda #UseLayrsave + jsr addmid + +* B-section + + lda FCharX + clc + adc #4 + sta XCO + + lda FCharY + sec + sbc #4 + sta YCO + + lda #looseb + sta IMAGE + lda #ora + sta OPACITY + lda #UseLayrsave + jmp addmid + +*------------------------------- +* +* Get objid & state +* +* In: BlueType/Spec,Y +* +* Out: A = objid +* state = state +* +* Preserves X & Y +* +*------------------------------- +getobjid + lda SCRNUM + beq GOnull ;null scrn has no blueprint + +* Use getobjid1 for screen #s other than SCRNUM + +getobjid1 + do EditorDisk + lda inbuilder + bne getobjbldr + fin + + lda (BlueSpec),y + sta state + + lda (BlueType),y + and #idmask + + cmp #pressplate + beq :plate + + cmp #upressplate + beq :upp + + rts + +* Handle depressed pressplate + +:plate lda state ;LINKLOC index + tax + lda LINKMAP,x + + and #%00011111 ;bits 0-4 + cmp #2 + bcc :up + + lda #dpressplate ;plate depressed + rts + +:up lda #pressplate ;plate up + rts + +* Handle depressed upressplate + +:upp lda state + tax + lda LINKMAP,x + and #%00011111 + cmp #2 + bcc :up1 + + lda #0 + sta state + lda #floor ;depressed upp looks just like floor + rts + +:up1 lda #upressplate + rts + +* Null screen is black + +GOnull + do EditorDisk + lda inmenu + bne getobjbldr + fin + + lda #space + rts + +*------------------------------- +* +* In builder: BlueSpec contains initial gadget settings +* +*------------------------------- + do EditorDisk +getobjbldr + lda (BlueType),y + and #idmask + pha + jsr getinitobj1 + bcs :ok + lda (BlueSpec),y +:ok sta state + pla + rts + fin + +*------------------------------- +* +* Sort objects in sort list into back-to-front order +* (Foremost object should be at bottom of list) +* +*------------------------------- +sortlist + +:newpass + lda #0 + sta switches ;no switches yet this pass + + ldx sortX ;start at bottom of list + +:loop cpx #1 ;at top of list? + beq :attop ;yes--pass complated + + stx xsave + + jsr compare ;Is obj[X] in front of obj[X-1]? + + ldx xsave + + bcc :ok ;Yes--continue +;No--switch objects + lda sortX,x + pha + lda sortX-1,x + sta sortX,x + pla + sta sortX-1,x ;switch [X] with [X-1] + +:ok dex + bne :loop ;move up in list + +* At top of list--pass completed + +:attop + lda switches ;Any switches this pass? + bne :newpass ;Yes--do it again + +* No switches made--objects are in order + +:rts rts + +*------------------------------- +* +* Compare object [xsave] with object [xsave-1] +* +* If X is IN FRONT OF X-1, or if it doesn't matter, return cc; +* If X is BEHIND X-1, return cs (switch 'em). +* +*------------------------------- +compare + lda sortX,x + sta obj1 ;obj index [X] + lda sortX-1,x + sta obj2 ;obj index [X-1] + + ldx obj1 + ldy obj2 + + lda objTYP,x + cmp #TypeShad + beq :xinfront ;enemy is always in front + + lda objY,x + cmp objY,y + beq :same + bcc :xinfront + bcs :yinfront + +:same +:xinfront clc + rts + +:yinfront sec + rts + +*------------------------------- +* +* Get initial state of object +* +* In: BlueType, BlueSpec, Y +* +* Return cs if it matters, else cc +* +*------------------------------- +GETINITOBJ + lda (BlueType),y + and #idmask ;get objid + +getinitobj1 + cmp #gate + beq :okgate + cmp #loose + beq :okloose + cmp #flask + beq :okflask + bne :skip ;if it isn't a gadget, leave it alone + +:okgate lda (BlueSpec),y ;1=gate up, 2=gate down, etc. + tax + lda initsettings-1,x + sec + rts + +:okloose lda #0 ;loose floor + rts + +:okflask lda (BlueSpec),y + asl + asl + asl + asl + asl ;5x + sec + rts + +:skip clc +]rts rts + +*------------------------------- +metbufs3 jsr mbsub + iny +metbufs2 jsr mbsub + iny +mbsub ora redbuf,y + ora floorbuf,y + ora halfbuf,y + ora fredbuf,y + ora wipebuf,y + rts + +*------------------------------- + lst + ds 1 + usr $a9,3,$490,*-org + lst off diff --git a/01 POP Source/Source/FRAMEDEF.S b/01 POP Source/Source/FRAMEDEF.S index 4468695..df2d969 100755 --- a/01 POP Source/Source/FRAMEDEF.S +++ b/01 POP Source/Source/FRAMEDEF.S @@ -1 +1,490 @@ -* framedef bof = $2800 tr on ;TABS 15,20,40 lst off lstdo off *------------------------------- dum bof org ds 1200 altset1 ds 200 altset2 ds 450 swordtab ds 192 dend *------------------------------- org org Fdef * Fimage, Fsword, Fdx, Fdy, Fcheck :1 db $01,0,1,0,$c0+4 ;run-4 :2 db $02,0,1,0,$40+4 ;run-5 :3 db $03,0,3,0,$40+7 ;run-6 :4 db $04,0,4,0,$40+8 ;run-7 :5 db $05,0,0,0,$c0+$20+6 ;run-8 :6 db $06,0,0,0,$40+9 ;run-9 :7 db $07,0,0,0,$40+10 ;run-10 :8 db $08,0,0,0,$c0+5 ;run-11 :9 db $09,0,0,0,$40+4 ;run-12 :10 db $0a,0,0,0,$40+7 ;run-13 :11 db $0b,0,0,0,$40+11 ;run-14 :12 db $0c,0,0,0,$40+3 ;run-15 :13 db $0d,0,0,0,$c0+3 ;run-16 :14 db $0e,0,0,0,$40+7 ;run-17 :15 db $0f,9,0,0,$40+3 ;stand :16 db $10,0,0,0,$c0+3 ;standjump-9 :17 db $11,0,0,0,$40+4 ;standjump-10 :18 db $12,0,0,0,$40+6 ;standjump-11 :19 db $13,0,0,0,$40+8 ;standjump-12 :20 db $14,0,0,0,$80+9 ;standjump-13 :21 db $15,0,0,0,$00+11 ;standjump-14 :22 db $16,0,0,0,$80+11 ;standjump-15 :23 db $17,0,0,0,$00+17 ;standjump-16 :24 db $18,0,0,0,$00+7 ;standjump-17 :25 db $19,0,0,0,$00+5 ;standjump-18 :26 db $1a,0,0,0,$c0+1 ;standjump-19 :27 db $1b,0,0,0,$c0+6 ;standjump-20 :28 db $1c,0,0,0,$40+3 ;standjump-21 :29 db $1d,0,0,0,$40+8 ;standjump-22 :30 db $1e,0,0,0,$40+2 ;standjump-23 :31 db $1f,0,0,0,$40+2 ;standjump-24 :32 db $20,0,0,0,$c0+2 ;standjump-25 :33 db $21,0,0,0,$c0+2 ;standjump-26 :34 db $22,0,0,0,$40+3 ;runjump-1 :35 db $23,0,0,0,$40+8 ;runjump-2 :36 db $24,0,0,0,$c0+14 ;runjump-3 :37 db $25,0,0,0,$c0+1 ;runjump-4 :38 db $26,0,0,0,$40+5 ;runjump-5 :39 db $27,0,0,0,$80+14 ;runjump-6 :40 db $28,0,0,0,$00+11 ;runjump-7 :41 db $29,0,0,0,$80+11 ;runjump-8 :42 db $2a,0,0,0,$80+10 ;runjump-9 :43 db $2b,0,0,0,$00+1 ;runjump-10 :44 db $2c,0,0,0,$c0+4 ;runjump-11 :45 db $2d,0,0,0,$c0+3 ;turn-2 :46 db $2e,0,0,0,$c0+3 ;turn-3 :47 db $2f,0,0,0,$80+$20+5 ;turn-4 :48 db $30,0,0,0,$80+$20+4 ;turn-5 :49 db $31,0,0,0,$40+$20+6 ;turn-6 :50 db $32,0,4,0,$40+$20+7 ;turn-7 :51 db $33,0,3,0,$40+$20+6 ;turn-8 :52 db $34,0,1,0,$40+4 ;turn-10 :53 db $01,$40,0,0,$c0+2 ;runturn-8 :54 db $02,$40,0,0,$40+1 ;runturn-9 :55 db $03,$40,0,0,$40+2 ;runturn-10 :56 db $04,$40,0,0,$00 ;runturn-11 :57 db $05,$40,0,0,$00 ;runturn-12 :58 db $06,$40,0,0,$80 ;runturn-13 :59 db $07,$40,0,0,$00 ;runturn-14 :60 db $08,$40,0,0,$80 ;runturn-15 :61 db $09,$40,0,0,$00 ;runturn-16 :62 db $0a,$40,0,0,$80 ;runturn-17 :63 db $0b,$40,0,0,$00 ;runturn-18 :64 db $0c,$40,0,0,$00 ;runturn-19 :65 db $0d,$40,0,0,$80 ;runturn-20 :66 db 0,0,0,0,0 :67 db $11,$40,-2,0,$40+1 ;jumphang-2 :68 db $12,$40,-2,0,$40+1 ;jumphang-3 :69 db $13,$40,-1,0,$c0+2 ;jumphang-4 :70 db $14,$40,-2,0,$40+2 ;jumphang-5 :71 db $15,$40,-2,0,$40+1 ;jumphang-6 :72 db $16,$40,-2,0,$40+1 ;jumphang-7 :73 db $17,$40,-2,0,$40+1 ;jumphang-8 :74 db $18,$40,-1,0,$00+7 ;jumphang-9 :75 db $19,$40,-1,0,$00+5 ;jumphang-10 :76 db $1a,$40,2,0,$00+7 ;jumphang-11 :77 db $1b,$40,2,0,$00+7 ;jumphang-12 :78 db $1c,$40,2,-3,$00 ;jumphang-13 :79 db $1d,$40,2,-10,$00 ;jumphang-14 :80 db $1e,$40,2,-11,$80 ;jumphang-15 :81 db $1f,$40,3,-2,$40+3 ;hangdrop-4 :82 db $20,$40,3,0,$c0+3 ;hangdrop-5 :83 db $21,$40,3,0,$c0+3 ;hangdrop-6 :84 db $22,$40,3,0,$40+$20+3 ;hangdrop-7 :85 db $23,$40,4,0,$c0+$20+3 ;hangdrop-8 :86 db $1d,0,0,0,$00 ;test w/foot :87 db $25,$40,7,-14,$80 ;jumphang-22 :88 db $26,$40,7,-12,$80 ;jumphang-23 :89 db $27,$40,4,-12,$00 ;jumphang-24 :90 db $28,$40,3,-10,$80 ;jumphang-25 :91 db $29,$40,2,-10,$80 ;jumphang-26 :92 db $2a,$40,1,-10,$80 ;jumphang-27 :93 db $2b,$40,0,-11,$00 ;jumphang-28 :94 db $2c,$40,-1,-12,$00 ;jumphang-29 :95 db $2d,$40,-1,-14,$00 ;jumphang-30 :96 db $2e,$40,-1,-14,$00 ;jumphang-31 :97 db $2f,$40,-1,-15,$80 ;jumphang-32 :98 db $30,$40,-1,-15,$80 ;jumphang-33 :99 db $31,$40,0,-15,$00 ;jumphang-34 :100 db 0,0,0,0,0 :101 db 0,0,0,0,0 :102 db $32,$40,0,0,$c0+6 ;jumpfall-2 :103 db $33,$40,0,0,$40+6 ;jumpfall-3 :104 db $34,$40,0,0,$c0+5 ;jumpfall-4 :105 db $35,$40,0,0,$40+5 ;jumpfall-5 :106 db $36,$40,0,0,$c0+2 ;jumpfall-6 :107 db $37,$40,0,0,$c0+4 ;jumpfall-7 :108 db $38,$40,0,0,$c0+5 ;jumpfall-8 :109 db $39,$40,0,0,$40+6 ;jumpfall-9 :110 db $3a,$40,0,0,$40+7 ;jumpfall-10 :111 db $3b,$40,0,0,$40+7 ;jumpfall-11 :112 db $3c,$40,0,0,$40+9 ;jumpfall-12 :113 db $3d,$40,0,0,$c0+8 ;jumpfall-13 :114 db $3e,$40,0,0,$c0+9 ;jumpfall-14 :115 db $3f,$40,0,0,$40+9 ;jumpfall-15 :116 db $40,$40,0,0,$40+5 ;jumpfall-16 :117 db $41,$40,2,0,$40+5 ;jumpfall-17 :118 db $42,$40,2,0,$c0+5 ;jumpfall-18 :119 db $43,$40,0,0,$c0+3 ;jumpfall-19 :120 db 0,0,0,0,0 :121 db $01,$80,0,0,$40+3 ;stepfwd-1 :122 db $02,$80,0,0,$c0+4 ;stepfwd-2 :123 db $03,$80,0,0,$c0+5 ;stepfwd-3 :124 db $04,$80,0,0,$40+8 ;stepfwd-4 :125 db $05,$80,0,0,$40+$20+12 ;stepfwd-5 :126 db $06,$80,0,0,$c0+$20+15 ;stepfwd-6 :127 db $07,$80,0,0,$40+$20+3 ;stepfwd-7 :128 db $08,$80,0,0,$c0+3 ;stepfwd-8 :129 db $09,$80,0,0,$40+3 ;stepfwd-9 :130 db $0a,$80,0,0,$40+3 ;stepfwd-10 :131 db $0b,$80,0,0,$40+4 ;stepfwd-11 :132 db $0c,$80,0,0,$40+4 ;stepfwd-12 :133 db $3e,$80,00,1,$c0+1 ;sheathe34 :134 db $3f,$80,00,1,$c0+7 ;sheathe37 :135 db $0d,$80,-5+5,51-63,$00+1 ;climbup-int1 :136 db $0e,$80,-5+5,42-63,$00 ;climbup-int2 :137 db $0f,$80,-4+5,37-63,$80 ;climbup-8 :138 db $10,$80,-1+5,31-63,$80 ;climbup-10 :139 db $11,$80,1+5,27-63,$80+1 ;climbup-14 :140 db $12,$80,2+5,22-63,$80+2 ;climbup-16 :141 db $13,$80,2,17,$40+2 ;climbup-22 :142 db $14,$80,4,9,$c0+4 ;climbup-28 :143 db $15,$80,4,5,$c0+9 ;climbup-30 :144 db $16,$80,4,4,$c0+8 ;climbup-32 :145 db $17,$80,5,0,$40+$20+9 ;climbup-34 :146 db $18,$80,5,0,$c0+$20+9 ;climbup-35 :147 db $19,$80,5,0,$c0+$20+8 ;climbup-36 :148 db $1a,$80,5,0,$40+$20+9 ;climbup-37 :149 db $1b,$80,5,0,$40+$20+9 ;climbup-38 :150 db $8b,16,0,2,$80 ;missed block :151 db $81,26,0,2,$80 :152 db $82,18,3,2,$00 ;guy4/rob20 :153 db $83,22,7,2,$c0+4 :154 db $84,21,10,2,$00 ;full ext. :155 db $85,23,7,2,$80 ;guy-7 :156 db $86,25,4,2,$80 ;guy-8 :157 db $87,24,0,2,$c0+14 ;guy-9 :158 db $88,15,0,2,$c0+13 ;guy10/rob15 (ready) :159 db $89,20,3,2,$00 ;guy19/rob22 :160 db $8a,31,3,2,$00 ;guy20/rob23 :161 db $8b,16,0,2,$80 ;guy21/rob18 (blocking) :162 db $8c,17,0,2,$80 ;guy22/rob19 (block-to-strike) :163 db $8d,32,0,2,$00 ;guy-31 (advance) :164 db $8e,33,0,2,$80 ;guy-32 :165 db $8f,34,2,2,$c0+3 ;guy-33 :166 db $0f,0,0,0,$40+3 ;stand :167 db $91,19,7,2,$80 ;guy18/rob21 (blocked) :168 db $92,14,1,2,$80 ;pre-strike :169 db $93,27,0,2,$80 ;rob17 (begin block) :170 db $88,15,0,2,$c0+13 ;guy10/rob15 (ready) :171 db $88,15,0,2,$c0+13 ;guy10/rob15 (ready) :172 db $32,$40+43,0,0,$c0+6 ;jumpfall-2 :173 db $33,$40+44,0,0,$40+6 ;jumpfall-3 :174 db $34,$40+45,0,0,$c0+5 ;jumpfall-4 :175 db $35,$40+46,0,0,$40+5 ;jumpfall-5 :176 db $34,$40,0,0,$c0+5 :177 db $0f,$40,0,3,$80+10 ;impaled :178 db $0e,$40,4,3,$80+7 ;halves :179 db $a8,0,0,1,$40+4 ;collapse15 :180 db $a9,0,0,1,$40+4 ;collapse16 :181 db $aa,0,0,1,$40+4 ;collapse17 :182 db $ab,0,0,1,$40+7 ;collapse18 :183 db $ac,0,0,7,$40+11 ;collapse19 :184 db 0,0,0,0,0 :185 db $10,$40,4,7,$40+9 ;dead :186 db $44,$40,0,0,$40+4 ;mouse-1 :187 db $45,$40,0,0,$40+4 ;mouse-2 :188 db $46,$40,0,2,$40+4 ;mouse crouch :189 db 0,0,0,0,0 :190 db 0,0,0,0,0 :191 db $94,0,0,0,$00 ;drink4 :192 db $95,0,0,1,$00 ;drink5 :193 db $96,0,0,0,$80 ;drink6 :194 db $97,0,0,0,$00 ;drink7 :195 db $98,0,-1,0,$00 ;drink8 :196 db $99,0,-1,0,$00 ;drink9 :197 db $9a,0,-1,0,$00 ;drink10 :198 db $9b,0,-4,0,$00 ;drink11 :199 db $9c,0,-4,0,$80 ;drink12 :200 db $9d,0,-4,0,$00 ;drink13 :201 db $9e,0,-4,0,$00 ;drink14 :202 db $9f,0,-4,0,$00 ;drink15 :203 db $a0,0,-4,0,$00 ;drink16 :204 db $a1,0,-5,0,$00 ;drink17 :205 db $a2,0,-5,0,$00 ;drink18 :206 db $a3,0,0,0,0 ;unused :207 db $a4,0,0,1,$40+6 ;draw5 :208 db $a5,0,0,1,$c0+6 ;draw6 :209 db $a6,0,0,1,$c0+8 ;draw7 :210 db $a7,0,0,1,$40+10 ;draw8 :211 db 0,0,0,0,$00 :212 db 0,0,0,0,$00 :213 db 0,0,0,0,$00 :214 db 0,0,0,0,$00 :215 db 0,0,0,0,$00 :216 db 0,0,0,0,$00 :217 db $35,0,0,0,$80 ;climbst2 :218 db $36,0,0,0,$00 ;climbst3 :219 db $37,0,0,0,$00 ;climbst4 :220 db $38,0,0,0,$00 ;climbst5 :221 db $39,0,0,0,$80 ;climbst6 :222 db $3a,0,0,0,$00 ;climbst7 :223 db $3b,0,0,0,$00 ;climbst8 :224 db $3c,0,0,0,$00 ;climbst9 :225 db $3d,0,0,0,$80 ;climbst10 :226 db $3e,0,0,0,$00 ;climbst11 :227 db $3f,0,0,0,$80 ;climbst12 :228 db $40,0,0,0,$00 ;climbst13 :229 db $32,$80+35,1,1,$c0+3 ;sheathe22 :230 db $33,$80+36,0,1,$40+9 ;sheathe23 :231 db $34,$80+37,0,1,$c0+3 ;sheathe24 :232 db $35,$80+38,0,1,$40+9 ;sheathe25 :233 db $36,$80+39,0,1,$c0+3 ;sheathe26 :234 db $37,$80+40,1,1,$40+9 ;sheathe27 :235 db $38,$80+41,1,1,$40+3 ;sheathe28 :236 db $39,$80+42,1,1,$c0+9 ;sheathe29 :237 db $3a,$80,4,1,$c0+6 ;sheathe30 :238 db $3b,$80,3,1,$c0+10 ;sheathe31 :239 db $3c,$80,1,1,$40+3 ;sheathe32 :240 db $3d,$80,1,1,$c0+8 ;sheathe33 (-->133) *------------------------------- * * Alternate character set 1 (chtable4) * * 200 bytes allocated -- 40 frames (150-189) * * Frame def list shows kid, sword in RIGHT hand * Altset1 shows enemy, sword in LEFT hand (to be mirrored) * (Image tables always show character facing LEFT) * *------------------------------- ds altset1-* ALTSET1 :150 db $0b,$c0+13,2,1,$00 ;missed block :151 db $01,$c0+1,3,1,$00 ;guy-3 :152 db $02,$c0+2,4,1,$00 ;guy-4 :153 db $03,$c0+3,7,1,$40+4 ;guy-5 :154 db $04,$c0+4,10,1,$00 ;guy-6 (full ext) :155 db $05,$c0+5,7,1,$80 ;guy-7 :156 db $06,$c0+6,4,1,$80 ;guy-8 :157 db $07,$c0+7,0,1,$80 ;guy-9 :158 db $08,$c0+8,0,1,$c0+13 ;guy-10 (ready) :159 db $09,$c0+11,7,1,$80 ;guy-19 :160 db $0a,$c0+12,3,1,$00 ;guy-20 :161 db $0b,$c0+13,2,1,$00 ;guy-21 (blocking) :162 db $0c,$c0,2,1,$00 ;guy-22 :163 db $0d,$c0+28,0,1,$00 ;guy-31 (advance) :164 db $0e,$c0+29,0,1,$80 ;guy-32 :165 db $0f,$c0+30,2,1,$c0+3 ;guy-33 :166 db $10,$c0+9,-1,1,$40+8 ;alertstand :167 db $11,$c0+10,7,1,$80 ;guy-18 (blocked) :168 db $12,$c0+14,3,1,$80 ;guy-15 :169 db $08,$c0+8,0,1,$80 ;?? (ready-->block) :170 db $13,$c0+8,0,1,$c0+13 ;guy-11/12 (ready) :171 db $14,$c0+8,0,1,$c0+13 ;guy-13/14 (ready) :172 db $15,$c0+47,0,0,$c0+6 ;jumpfall-2 (stabbed) :173 db $16,$c0+48,0,0,$40+6 ;jumpfall-3 :174 db $17,$c0+49,0,0,$c0+5 ;jumpfall-4 :175 db $17,$c0+49,0,0,$c0+5 ;for jumpfall-5 :176 db $17,$c0+49,0,0,$c0+5 ;for jumpfall-6 :177 db $19,$c0,0,3,$80+10 ;impaled :178 db $1a,$c0,4,4,$80+7 ;halves :179 db $1b,$c0,-2,1,$40+4 ;collapse15 :180 db $1c,$c0,-2,1,$40+4 ;collapse16 :181 db $1d,$c0,-2,1,$40+4 ;collapse17 :182 db $1e,$c0,-2,2,$40+7 ;collapse18 :183 db $1f,$c0,-2,2,$40+10 ;collapse19 :184 db 0,0,0,0,0 :185 db $20,$c0,3,4,$c0+9 ;dead :186 db 0,0,0,0,0 :187 db 0,0,0,0,0 :188 db 0,0,0,0,0 :189 db 0,0,0,0,0 *------------------------------- * * Alternate character set 2 (chtable6) * * (450 bytes allocated -- 90 frames) * *------------------------------- ds altset2-* ALTSET2 :1 db $8a,$40,0,0,$00 ;pslump-1 :2 db $9a,$40,0,0,$80 ;pturn-4 :3 db $9b,$40,0,0,$80 ;pturn-5 :4 db $9c,$40,0,0,$80 ;pturn-6 :5 db $9d,$40,-1,0,$00 ;pturn-7 :6 db $9e,$40,2,0,$80 ;pturn-8 :7 db $9f,$40,2,0,$00 ;pturn-9 :8 db $a0,$40,0,0,$80 ;pturn-10 :9 db $a1,$40,1,0,$80 ;pturn-11 :10 db $a2,$40,2,0,$80 ;unused :11 db $99,$40,0,0,$80 ;pturn-15 (stand) :12 db $a3,$40,0,0,$80 ;pback-3 :13 db $a4,$40,0,0,$00 ;pback-5 :14 db $a5,$40,0,0,$80 ;pback-7 :15 db $a6,$40,0,0,$80 ;pback-9 :16 db $a7,$40,0,0,$80 ;pback-11 :17 db $a8,$40,0,0,$00 ;pback-13 (stand) :18 db $8b,$40,0,0,$00 ;pslump-1 :19 db $a9,$40,0,0,$00 ;plie :20 db $ad,$40,0,0,$00 ;embrace-1 :21 db $ae,$40,0,0,$00 ;embrace-2 :22 db $af,$40,0,0,$80 ;embrace-3 :23 db $b0,$40,0,0,$00 ;embrace-4 :24 db $b1,$40,0,0,$80 ;embrace-5 :25 db $b2,$40,0,0,$80 ;embrace-6 :26 db $b3,$40,0,0,$00 ;embrace-7 :27 db $b4,$40,0,0,$00 ;embrace-8 :28 db $b5,$40,0,0,$00 ;embrace-9 :29 db $b6,$40,0,0,$00 ;embrace-10 :30 db $b7,$40,0,0,$00 ;embrace-11 :31 db $b8,$40,0,0,$00 ;embrace-12 :32 db $b9,$40,0,0,$00 ;embrace-13 :33 db $ba,$40,0,0,$00 ;embrace-14 :34 db $bb,$40,0,0,$00 ;prise-1 :35 db $bc,$40,0,0,$00 ;prise-2 :36 db $bd,$40,0,0,$00 ;prise-3 :37 db $be,$40,0,0,$00 ;prise-4 :38 db $bf,$40,0,0,$80 ;prise-5 :39 db $bf,$40,0,0,$80 ;prise-6 :40 db $c1,$40,1,0,$00 ;prise-7 :41 db $c2,$40,-1,0,$00 ;prise-8 :42 db $c3,$40,2,0,$00 ;prise-9 :43 db $c4,$40,1,0,$80 ;prise-10 :44 db $c5,$40,0,0,$80 ;prise-11 :45 db $c6,$40,0,0,$80 ;prise-12 :46 db $c7,$40,0,0,$80 ;prise-13 :47 db $c8,$40,-1,0,$00 ;prise-14 :48 db $ca,$40,0,0,$80 ;vwalk-8 :49 db $cb,$40,0,0,$80 ;vwalk-9 :50 db $cc,$40,0,0,$80 ;vwalk-10 :51 db $cd,$40,0,0,$00 ;vwalk-11 :52 db $ce,$40,0,0,$00 ;vwalk-12 :53 db $cf,$40,0,0,$80 ;vwalk-13 :54 db $d0,$40,0,0,$80 ;vstand-3 :55 db $d1,$40,0,0,$80 ;vstand-2 :56 db $d2,$40,0,0,$80 ;vstand-1 :57 db $d3,$40,0,0,$80 ;vturn-5 :58 db $d4,$40,0,0,$80 ;vturn-6 :59 db $d5,$40,0,0,$80 ;vturn-7 :60 db $d6,$40,0,0,$80 ;vturn-8 :61 db $d7,$40,0,0,$00 ;vturn-9 :62 db $d8,$40,0,0,$80 ;vturn-10 :63 db $d9,$40,0,0,$00 ;vturn-11 :64 db $da,$40,0,0,$00 ;vturn-12 :65 db $db,$40,0,0,$80 ;vturn-13 :66 db $dc,$40,0,0,$00 ;vturn-14 :67 db $dd,$40,3,0,$00 ;vcast-2 :68 db $de,$40,3,0,$00 ;vcast-3 :69 db $df,$40,3,0,$00 ;vcast-4 :70 db $e0,$40,2,0,$00 ;vcast-5 :71 db $e1,$40,3,0,$80 ;vcast-6 :72 db $e2,$40,5,0,$00 ;vcast-7 :73 db $e3,$40,5,0,$00 ;vcast-8 :74 db $e4,$40,1,0,$80 ;vcast-9 :75 db $e5,$40,2,0,$80 ;vcast-10 :76 db $e6,$40,2,0,$80 ;vcast-11 (held) :77 db $e7,$40,1,0,$80 ;vcast-13 :78 db $81,$80,1,0,$00 ;vcast-14 :79 db $82,$80,2,0,$00 ;vcast-15 :80 db $83,$80,3,0,$00 ;vcast-16 :81 db $84,$80,3,0,$00 ;vcast-17 :82 db $85,$80,0,0,$80 ;vcast-18 :83 db $86,$80,2,0,$80 ;vcast-10a :84 db $87,$80,2,0,$80 ;vcast-10b :85 db $88,$80,1,0,$00 ;vcast-1 *------------------------------- * * S W O R D T A B L E * * (192 bytes allocated -- 64 swords) * * Sword images are taken from chtable3 * *------------------------------- ds swordtab-* SWORDTAB * (Image, DX, DY) :1 db $1d,0,-9 :2 db $22,-9,-29 :3 db $1e,7,-25 :4 db $1f,17,-26 :5 db $23,7,-14 :6 db $24,0,-5 :7 db $20,17,-16 :8 db $21,16,-19 :9 db $4b,12,-9 ;alertstand :10 db $26,13,-34 :11 db $27,7,-25 :12 db $28,10,-16 :13 db $29,10,-11 :14 db $2a,22,-21 :15 db $2b,28,-23 :16 db $2c,13,-35 :17 db $2d,0,-38 :18 db $2e,0,-29 :19 db $2f,21,-19 :20 db $30,14,-23 :21 db $31,21,-22 :22 db $31,22,-23 :23 db $2f,7,-13 :24 db $2f,15,-18 ;$20,17,-19 for flash :25 db $24,0,-8 :26 db $1e,7,-27 :27 db $48,14,-28 :28 db $26,7,-27 :29 db $21,6,-23 :30 db $21,9,-21 :31 db $28,11,-18 :32 db $2b,24,-23 :33 db $2b,19,-23 :34 db $2b,21,-23 ;sheathing :35 db $40,7,-32 :36 db $41,14,-32 :37 db $42,14,-31 :38 db $43,14,-29 :39 db $44,28,-28 :40 db $45,28,-28 :41 db $46,21,-25 :42 db $47,14,-22 :43 db 0,14,-25 ;43-46: kid stabbed :44 db 0,21,-25 :45 db $4a,0,-16 :46 db $26,8,-37 :47 db $4c,14,-24 ;47-50: enemy stabbed :48 db $4d,14,-24 :49 db $4e,7,-14 :50 db $26,8,-37 *------------------------------- lst ds 1 usr $a9,15,$00,*-org lst off \ No newline at end of file +* framedef +bof = $2800 + tr on ;TABS 15,20,40 + lst off + lstdo off + +*------------------------------- + dum bof + +org ds 1200 +altset1 ds 200 +altset2 ds 450 +swordtab ds 192 + + dend + +*------------------------------- + org org +Fdef + +* Fimage, Fsword, Fdx, Fdy, Fcheck + +:1 db $01,0,1,0,$c0+4 ;run-4 +:2 db $02,0,1,0,$40+4 ;run-5 +:3 db $03,0,3,0,$40+7 ;run-6 +:4 db $04,0,4,0,$40+8 ;run-7 +:5 db $05,0,0,0,$c0+$20+6 ;run-8 +:6 db $06,0,0,0,$40+9 ;run-9 +:7 db $07,0,0,0,$40+10 ;run-10 +:8 db $08,0,0,0,$c0+5 ;run-11 +:9 db $09,0,0,0,$40+4 ;run-12 +:10 db $0a,0,0,0,$40+7 ;run-13 +:11 db $0b,0,0,0,$40+11 ;run-14 +:12 db $0c,0,0,0,$40+3 ;run-15 +:13 db $0d,0,0,0,$c0+3 ;run-16 +:14 db $0e,0,0,0,$40+7 ;run-17 +:15 db $0f,9,0,0,$40+3 ;stand +:16 db $10,0,0,0,$c0+3 ;standjump-9 +:17 db $11,0,0,0,$40+4 ;standjump-10 +:18 db $12,0,0,0,$40+6 ;standjump-11 +:19 db $13,0,0,0,$40+8 ;standjump-12 +:20 db $14,0,0,0,$80+9 ;standjump-13 +:21 db $15,0,0,0,$00+11 ;standjump-14 +:22 db $16,0,0,0,$80+11 ;standjump-15 +:23 db $17,0,0,0,$00+17 ;standjump-16 +:24 db $18,0,0,0,$00+7 ;standjump-17 +:25 db $19,0,0,0,$00+5 ;standjump-18 +:26 db $1a,0,0,0,$c0+1 ;standjump-19 +:27 db $1b,0,0,0,$c0+6 ;standjump-20 +:28 db $1c,0,0,0,$40+3 ;standjump-21 +:29 db $1d,0,0,0,$40+8 ;standjump-22 +:30 db $1e,0,0,0,$40+2 ;standjump-23 +:31 db $1f,0,0,0,$40+2 ;standjump-24 +:32 db $20,0,0,0,$c0+2 ;standjump-25 +:33 db $21,0,0,0,$c0+2 ;standjump-26 +:34 db $22,0,0,0,$40+3 ;runjump-1 +:35 db $23,0,0,0,$40+8 ;runjump-2 +:36 db $24,0,0,0,$c0+14 ;runjump-3 +:37 db $25,0,0,0,$c0+1 ;runjump-4 +:38 db $26,0,0,0,$40+5 ;runjump-5 +:39 db $27,0,0,0,$80+14 ;runjump-6 +:40 db $28,0,0,0,$00+11 ;runjump-7 +:41 db $29,0,0,0,$80+11 ;runjump-8 +:42 db $2a,0,0,0,$80+10 ;runjump-9 +:43 db $2b,0,0,0,$00+1 ;runjump-10 +:44 db $2c,0,0,0,$c0+4 ;runjump-11 +:45 db $2d,0,0,0,$c0+3 ;turn-2 +:46 db $2e,0,0,0,$c0+3 ;turn-3 +:47 db $2f,0,0,0,$80+$20+5 ;turn-4 +:48 db $30,0,0,0,$80+$20+4 ;turn-5 +:49 db $31,0,0,0,$40+$20+6 ;turn-6 +:50 db $32,0,4,0,$40+$20+7 ;turn-7 +:51 db $33,0,3,0,$40+$20+6 ;turn-8 +:52 db $34,0,1,0,$40+4 ;turn-10 +:53 db $01,$40,0,0,$c0+2 ;runturn-8 +:54 db $02,$40,0,0,$40+1 ;runturn-9 +:55 db $03,$40,0,0,$40+2 ;runturn-10 +:56 db $04,$40,0,0,$00 ;runturn-11 +:57 db $05,$40,0,0,$00 ;runturn-12 +:58 db $06,$40,0,0,$80 ;runturn-13 +:59 db $07,$40,0,0,$00 ;runturn-14 +:60 db $08,$40,0,0,$80 ;runturn-15 +:61 db $09,$40,0,0,$00 ;runturn-16 +:62 db $0a,$40,0,0,$80 ;runturn-17 +:63 db $0b,$40,0,0,$00 ;runturn-18 +:64 db $0c,$40,0,0,$00 ;runturn-19 +:65 db $0d,$40,0,0,$80 ;runturn-20 +:66 db 0,0,0,0,0 +:67 db $11,$40,-2,0,$40+1 ;jumphang-2 +:68 db $12,$40,-2,0,$40+1 ;jumphang-3 +:69 db $13,$40,-1,0,$c0+2 ;jumphang-4 +:70 db $14,$40,-2,0,$40+2 ;jumphang-5 +:71 db $15,$40,-2,0,$40+1 ;jumphang-6 +:72 db $16,$40,-2,0,$40+1 ;jumphang-7 +:73 db $17,$40,-2,0,$40+1 ;jumphang-8 +:74 db $18,$40,-1,0,$00+7 ;jumphang-9 +:75 db $19,$40,-1,0,$00+5 ;jumphang-10 +:76 db $1a,$40,2,0,$00+7 ;jumphang-11 +:77 db $1b,$40,2,0,$00+7 ;jumphang-12 +:78 db $1c,$40,2,-3,$00 ;jumphang-13 +:79 db $1d,$40,2,-10,$00 ;jumphang-14 +:80 db $1e,$40,2,-11,$80 ;jumphang-15 +:81 db $1f,$40,3,-2,$40+3 ;hangdrop-4 +:82 db $20,$40,3,0,$c0+3 ;hangdrop-5 +:83 db $21,$40,3,0,$c0+3 ;hangdrop-6 +:84 db $22,$40,3,0,$40+$20+3 ;hangdrop-7 +:85 db $23,$40,4,0,$c0+$20+3 ;hangdrop-8 +:86 db $1d,0,0,0,$00 ;test w/foot +:87 db $25,$40,7,-14,$80 ;jumphang-22 +:88 db $26,$40,7,-12,$80 ;jumphang-23 +:89 db $27,$40,4,-12,$00 ;jumphang-24 +:90 db $28,$40,3,-10,$80 ;jumphang-25 +:91 db $29,$40,2,-10,$80 ;jumphang-26 +:92 db $2a,$40,1,-10,$80 ;jumphang-27 +:93 db $2b,$40,0,-11,$00 ;jumphang-28 +:94 db $2c,$40,-1,-12,$00 ;jumphang-29 +:95 db $2d,$40,-1,-14,$00 ;jumphang-30 +:96 db $2e,$40,-1,-14,$00 ;jumphang-31 +:97 db $2f,$40,-1,-15,$80 ;jumphang-32 +:98 db $30,$40,-1,-15,$80 ;jumphang-33 +:99 db $31,$40,0,-15,$00 ;jumphang-34 +:100 db 0,0,0,0,0 +:101 db 0,0,0,0,0 +:102 db $32,$40,0,0,$c0+6 ;jumpfall-2 +:103 db $33,$40,0,0,$40+6 ;jumpfall-3 +:104 db $34,$40,0,0,$c0+5 ;jumpfall-4 +:105 db $35,$40,0,0,$40+5 ;jumpfall-5 +:106 db $36,$40,0,0,$c0+2 ;jumpfall-6 +:107 db $37,$40,0,0,$c0+4 ;jumpfall-7 +:108 db $38,$40,0,0,$c0+5 ;jumpfall-8 +:109 db $39,$40,0,0,$40+6 ;jumpfall-9 +:110 db $3a,$40,0,0,$40+7 ;jumpfall-10 +:111 db $3b,$40,0,0,$40+7 ;jumpfall-11 +:112 db $3c,$40,0,0,$40+9 ;jumpfall-12 +:113 db $3d,$40,0,0,$c0+8 ;jumpfall-13 +:114 db $3e,$40,0,0,$c0+9 ;jumpfall-14 +:115 db $3f,$40,0,0,$40+9 ;jumpfall-15 +:116 db $40,$40,0,0,$40+5 ;jumpfall-16 +:117 db $41,$40,2,0,$40+5 ;jumpfall-17 +:118 db $42,$40,2,0,$c0+5 ;jumpfall-18 +:119 db $43,$40,0,0,$c0+3 ;jumpfall-19 +:120 db 0,0,0,0,0 +:121 db $01,$80,0,0,$40+3 ;stepfwd-1 +:122 db $02,$80,0,0,$c0+4 ;stepfwd-2 +:123 db $03,$80,0,0,$c0+5 ;stepfwd-3 +:124 db $04,$80,0,0,$40+8 ;stepfwd-4 +:125 db $05,$80,0,0,$40+$20+12 ;stepfwd-5 +:126 db $06,$80,0,0,$c0+$20+15 ;stepfwd-6 +:127 db $07,$80,0,0,$40+$20+3 ;stepfwd-7 +:128 db $08,$80,0,0,$c0+3 ;stepfwd-8 +:129 db $09,$80,0,0,$40+3 ;stepfwd-9 +:130 db $0a,$80,0,0,$40+3 ;stepfwd-10 +:131 db $0b,$80,0,0,$40+4 ;stepfwd-11 +:132 db $0c,$80,0,0,$40+4 ;stepfwd-12 +:133 db $3e,$80,00,1,$c0+1 ;sheathe34 +:134 db $3f,$80,00,1,$c0+7 ;sheathe37 +:135 db $0d,$80,-5+5,51-63,$00+1 ;climbup-int1 +:136 db $0e,$80,-5+5,42-63,$00 ;climbup-int2 +:137 db $0f,$80,-4+5,37-63,$80 ;climbup-8 +:138 db $10,$80,-1+5,31-63,$80 ;climbup-10 +:139 db $11,$80,1+5,27-63,$80+1 ;climbup-14 +:140 db $12,$80,2+5,22-63,$80+2 ;climbup-16 +:141 db $13,$80,2,17,$40+2 ;climbup-22 +:142 db $14,$80,4,9,$c0+4 ;climbup-28 +:143 db $15,$80,4,5,$c0+9 ;climbup-30 +:144 db $16,$80,4,4,$c0+8 ;climbup-32 +:145 db $17,$80,5,0,$40+$20+9 ;climbup-34 +:146 db $18,$80,5,0,$c0+$20+9 ;climbup-35 +:147 db $19,$80,5,0,$c0+$20+8 ;climbup-36 +:148 db $1a,$80,5,0,$40+$20+9 ;climbup-37 +:149 db $1b,$80,5,0,$40+$20+9 ;climbup-38 +:150 db $8b,16,0,2,$80 ;missed block +:151 db $81,26,0,2,$80 +:152 db $82,18,3,2,$00 ;guy4/rob20 +:153 db $83,22,7,2,$c0+4 +:154 db $84,21,10,2,$00 ;full ext. +:155 db $85,23,7,2,$80 ;guy-7 +:156 db $86,25,4,2,$80 ;guy-8 +:157 db $87,24,0,2,$c0+14 ;guy-9 +:158 db $88,15,0,2,$c0+13 ;guy10/rob15 (ready) +:159 db $89,20,3,2,$00 ;guy19/rob22 +:160 db $8a,31,3,2,$00 ;guy20/rob23 +:161 db $8b,16,0,2,$80 ;guy21/rob18 (blocking) +:162 db $8c,17,0,2,$80 ;guy22/rob19 (block-to-strike) +:163 db $8d,32,0,2,$00 ;guy-31 (advance) +:164 db $8e,33,0,2,$80 ;guy-32 +:165 db $8f,34,2,2,$c0+3 ;guy-33 +:166 db $0f,0,0,0,$40+3 ;stand +:167 db $91,19,7,2,$80 ;guy18/rob21 (blocked) +:168 db $92,14,1,2,$80 ;pre-strike +:169 db $93,27,0,2,$80 ;rob17 (begin block) +:170 db $88,15,0,2,$c0+13 ;guy10/rob15 (ready) +:171 db $88,15,0,2,$c0+13 ;guy10/rob15 (ready) +:172 db $32,$40+43,0,0,$c0+6 ;jumpfall-2 +:173 db $33,$40+44,0,0,$40+6 ;jumpfall-3 +:174 db $34,$40+45,0,0,$c0+5 ;jumpfall-4 +:175 db $35,$40+46,0,0,$40+5 ;jumpfall-5 +:176 db $34,$40,0,0,$c0+5 +:177 db $0f,$40,0,3,$80+10 ;impaled +:178 db $0e,$40,4,3,$80+7 ;halves +:179 db $a8,0,0,1,$40+4 ;collapse15 +:180 db $a9,0,0,1,$40+4 ;collapse16 +:181 db $aa,0,0,1,$40+4 ;collapse17 +:182 db $ab,0,0,1,$40+7 ;collapse18 +:183 db $ac,0,0,7,$40+11 ;collapse19 +:184 db 0,0,0,0,0 +:185 db $10,$40,4,7,$40+9 ;dead +:186 db $44,$40,0,0,$40+4 ;mouse-1 +:187 db $45,$40,0,0,$40+4 ;mouse-2 +:188 db $46,$40,0,2,$40+4 ;mouse crouch +:189 db 0,0,0,0,0 +:190 db 0,0,0,0,0 +:191 db $94,0,0,0,$00 ;drink4 +:192 db $95,0,0,1,$00 ;drink5 +:193 db $96,0,0,0,$80 ;drink6 +:194 db $97,0,0,0,$00 ;drink7 +:195 db $98,0,-1,0,$00 ;drink8 +:196 db $99,0,-1,0,$00 ;drink9 +:197 db $9a,0,-1,0,$00 ;drink10 +:198 db $9b,0,-4,0,$00 ;drink11 +:199 db $9c,0,-4,0,$80 ;drink12 +:200 db $9d,0,-4,0,$00 ;drink13 +:201 db $9e,0,-4,0,$00 ;drink14 +:202 db $9f,0,-4,0,$00 ;drink15 +:203 db $a0,0,-4,0,$00 ;drink16 +:204 db $a1,0,-5,0,$00 ;drink17 +:205 db $a2,0,-5,0,$00 ;drink18 +:206 db $a3,0,0,0,0 ;unused +:207 db $a4,0,0,1,$40+6 ;draw5 +:208 db $a5,0,0,1,$c0+6 ;draw6 +:209 db $a6,0,0,1,$c0+8 ;draw7 +:210 db $a7,0,0,1,$40+10 ;draw8 +:211 db 0,0,0,0,$00 +:212 db 0,0,0,0,$00 +:213 db 0,0,0,0,$00 +:214 db 0,0,0,0,$00 +:215 db 0,0,0,0,$00 +:216 db 0,0,0,0,$00 +:217 db $35,0,0,0,$80 ;climbst2 +:218 db $36,0,0,0,$00 ;climbst3 +:219 db $37,0,0,0,$00 ;climbst4 +:220 db $38,0,0,0,$00 ;climbst5 +:221 db $39,0,0,0,$80 ;climbst6 +:222 db $3a,0,0,0,$00 ;climbst7 +:223 db $3b,0,0,0,$00 ;climbst8 +:224 db $3c,0,0,0,$00 ;climbst9 +:225 db $3d,0,0,0,$80 ;climbst10 +:226 db $3e,0,0,0,$00 ;climbst11 +:227 db $3f,0,0,0,$80 ;climbst12 +:228 db $40,0,0,0,$00 ;climbst13 +:229 db $32,$80+35,1,1,$c0+3 ;sheathe22 +:230 db $33,$80+36,0,1,$40+9 ;sheathe23 +:231 db $34,$80+37,0,1,$c0+3 ;sheathe24 +:232 db $35,$80+38,0,1,$40+9 ;sheathe25 +:233 db $36,$80+39,0,1,$c0+3 ;sheathe26 +:234 db $37,$80+40,1,1,$40+9 ;sheathe27 +:235 db $38,$80+41,1,1,$40+3 ;sheathe28 +:236 db $39,$80+42,1,1,$c0+9 ;sheathe29 +:237 db $3a,$80,4,1,$c0+6 ;sheathe30 +:238 db $3b,$80,3,1,$c0+10 ;sheathe31 +:239 db $3c,$80,1,1,$40+3 ;sheathe32 +:240 db $3d,$80,1,1,$c0+8 ;sheathe33 (-->133) + +*------------------------------- +* +* Alternate character set 1 (chtable4) +* +* 200 bytes allocated -- 40 frames (150-189) +* +* Frame def list shows kid, sword in RIGHT hand +* Altset1 shows enemy, sword in LEFT hand (to be mirrored) +* (Image tables always show character facing LEFT) +* +*------------------------------- + ds altset1-* + +ALTSET1 + +:150 db $0b,$c0+13,2,1,$00 ;missed block +:151 db $01,$c0+1,3,1,$00 ;guy-3 +:152 db $02,$c0+2,4,1,$00 ;guy-4 +:153 db $03,$c0+3,7,1,$40+4 ;guy-5 +:154 db $04,$c0+4,10,1,$00 ;guy-6 (full ext) +:155 db $05,$c0+5,7,1,$80 ;guy-7 +:156 db $06,$c0+6,4,1,$80 ;guy-8 +:157 db $07,$c0+7,0,1,$80 ;guy-9 +:158 db $08,$c0+8,0,1,$c0+13 ;guy-10 (ready) +:159 db $09,$c0+11,7,1,$80 ;guy-19 +:160 db $0a,$c0+12,3,1,$00 ;guy-20 +:161 db $0b,$c0+13,2,1,$00 ;guy-21 (blocking) +:162 db $0c,$c0,2,1,$00 ;guy-22 +:163 db $0d,$c0+28,0,1,$00 ;guy-31 (advance) +:164 db $0e,$c0+29,0,1,$80 ;guy-32 +:165 db $0f,$c0+30,2,1,$c0+3 ;guy-33 +:166 db $10,$c0+9,-1,1,$40+8 ;alertstand +:167 db $11,$c0+10,7,1,$80 ;guy-18 (blocked) +:168 db $12,$c0+14,3,1,$80 ;guy-15 +:169 db $08,$c0+8,0,1,$80 ;?? (ready-->block) +:170 db $13,$c0+8,0,1,$c0+13 ;guy-11/12 (ready) +:171 db $14,$c0+8,0,1,$c0+13 ;guy-13/14 (ready) +:172 db $15,$c0+47,0,0,$c0+6 ;jumpfall-2 (stabbed) +:173 db $16,$c0+48,0,0,$40+6 ;jumpfall-3 +:174 db $17,$c0+49,0,0,$c0+5 ;jumpfall-4 +:175 db $17,$c0+49,0,0,$c0+5 ;for jumpfall-5 +:176 db $17,$c0+49,0,0,$c0+5 ;for jumpfall-6 +:177 db $19,$c0,0,3,$80+10 ;impaled +:178 db $1a,$c0,4,4,$80+7 ;halves +:179 db $1b,$c0,-2,1,$40+4 ;collapse15 +:180 db $1c,$c0,-2,1,$40+4 ;collapse16 +:181 db $1d,$c0,-2,1,$40+4 ;collapse17 +:182 db $1e,$c0,-2,2,$40+7 ;collapse18 +:183 db $1f,$c0,-2,2,$40+10 ;collapse19 +:184 db 0,0,0,0,0 +:185 db $20,$c0,3,4,$c0+9 ;dead +:186 db 0,0,0,0,0 +:187 db 0,0,0,0,0 +:188 db 0,0,0,0,0 +:189 db 0,0,0,0,0 + +*------------------------------- +* +* Alternate character set 2 (chtable6) +* +* (450 bytes allocated -- 90 frames) +* +*------------------------------- + ds altset2-* + +ALTSET2 + +:1 db $8a,$40,0,0,$00 ;pslump-1 +:2 db $9a,$40,0,0,$80 ;pturn-4 +:3 db $9b,$40,0,0,$80 ;pturn-5 +:4 db $9c,$40,0,0,$80 ;pturn-6 +:5 db $9d,$40,-1,0,$00 ;pturn-7 +:6 db $9e,$40,2,0,$80 ;pturn-8 +:7 db $9f,$40,2,0,$00 ;pturn-9 +:8 db $a0,$40,0,0,$80 ;pturn-10 +:9 db $a1,$40,1,0,$80 ;pturn-11 +:10 db $a2,$40,2,0,$80 ;unused +:11 db $99,$40,0,0,$80 ;pturn-15 (stand) +:12 db $a3,$40,0,0,$80 ;pback-3 +:13 db $a4,$40,0,0,$00 ;pback-5 +:14 db $a5,$40,0,0,$80 ;pback-7 +:15 db $a6,$40,0,0,$80 ;pback-9 +:16 db $a7,$40,0,0,$80 ;pback-11 +:17 db $a8,$40,0,0,$00 ;pback-13 (stand) +:18 db $8b,$40,0,0,$00 ;pslump-1 +:19 db $a9,$40,0,0,$00 ;plie +:20 db $ad,$40,0,0,$00 ;embrace-1 +:21 db $ae,$40,0,0,$00 ;embrace-2 +:22 db $af,$40,0,0,$80 ;embrace-3 +:23 db $b0,$40,0,0,$00 ;embrace-4 +:24 db $b1,$40,0,0,$80 ;embrace-5 +:25 db $b2,$40,0,0,$80 ;embrace-6 +:26 db $b3,$40,0,0,$00 ;embrace-7 +:27 db $b4,$40,0,0,$00 ;embrace-8 +:28 db $b5,$40,0,0,$00 ;embrace-9 +:29 db $b6,$40,0,0,$00 ;embrace-10 +:30 db $b7,$40,0,0,$00 ;embrace-11 +:31 db $b8,$40,0,0,$00 ;embrace-12 +:32 db $b9,$40,0,0,$00 ;embrace-13 +:33 db $ba,$40,0,0,$00 ;embrace-14 +:34 db $bb,$40,0,0,$00 ;prise-1 +:35 db $bc,$40,0,0,$00 ;prise-2 +:36 db $bd,$40,0,0,$00 ;prise-3 +:37 db $be,$40,0,0,$00 ;prise-4 +:38 db $bf,$40,0,0,$80 ;prise-5 +:39 db $bf,$40,0,0,$80 ;prise-6 +:40 db $c1,$40,1,0,$00 ;prise-7 +:41 db $c2,$40,-1,0,$00 ;prise-8 +:42 db $c3,$40,2,0,$00 ;prise-9 +:43 db $c4,$40,1,0,$80 ;prise-10 +:44 db $c5,$40,0,0,$80 ;prise-11 +:45 db $c6,$40,0,0,$80 ;prise-12 +:46 db $c7,$40,0,0,$80 ;prise-13 +:47 db $c8,$40,-1,0,$00 ;prise-14 +:48 db $ca,$40,0,0,$80 ;vwalk-8 +:49 db $cb,$40,0,0,$80 ;vwalk-9 +:50 db $cc,$40,0,0,$80 ;vwalk-10 +:51 db $cd,$40,0,0,$00 ;vwalk-11 +:52 db $ce,$40,0,0,$00 ;vwalk-12 +:53 db $cf,$40,0,0,$80 ;vwalk-13 +:54 db $d0,$40,0,0,$80 ;vstand-3 +:55 db $d1,$40,0,0,$80 ;vstand-2 +:56 db $d2,$40,0,0,$80 ;vstand-1 +:57 db $d3,$40,0,0,$80 ;vturn-5 +:58 db $d4,$40,0,0,$80 ;vturn-6 +:59 db $d5,$40,0,0,$80 ;vturn-7 +:60 db $d6,$40,0,0,$80 ;vturn-8 +:61 db $d7,$40,0,0,$00 ;vturn-9 +:62 db $d8,$40,0,0,$80 ;vturn-10 +:63 db $d9,$40,0,0,$00 ;vturn-11 +:64 db $da,$40,0,0,$00 ;vturn-12 +:65 db $db,$40,0,0,$80 ;vturn-13 +:66 db $dc,$40,0,0,$00 ;vturn-14 +:67 db $dd,$40,3,0,$00 ;vcast-2 +:68 db $de,$40,3,0,$00 ;vcast-3 +:69 db $df,$40,3,0,$00 ;vcast-4 +:70 db $e0,$40,2,0,$00 ;vcast-5 +:71 db $e1,$40,3,0,$80 ;vcast-6 +:72 db $e2,$40,5,0,$00 ;vcast-7 +:73 db $e3,$40,5,0,$00 ;vcast-8 +:74 db $e4,$40,1,0,$80 ;vcast-9 +:75 db $e5,$40,2,0,$80 ;vcast-10 +:76 db $e6,$40,2,0,$80 ;vcast-11 (held) +:77 db $e7,$40,1,0,$80 ;vcast-13 +:78 db $81,$80,1,0,$00 ;vcast-14 +:79 db $82,$80,2,0,$00 ;vcast-15 +:80 db $83,$80,3,0,$00 ;vcast-16 +:81 db $84,$80,3,0,$00 ;vcast-17 +:82 db $85,$80,0,0,$80 ;vcast-18 +:83 db $86,$80,2,0,$80 ;vcast-10a +:84 db $87,$80,2,0,$80 ;vcast-10b +:85 db $88,$80,1,0,$00 ;vcast-1 + + +*------------------------------- +* +* S W O R D T A B L E +* +* (192 bytes allocated -- 64 swords) +* +* Sword images are taken from chtable3 +* +*------------------------------- + ds swordtab-* + +SWORDTAB + +* (Image, DX, DY) + +:1 db $1d,0,-9 +:2 db $22,-9,-29 +:3 db $1e,7,-25 +:4 db $1f,17,-26 +:5 db $23,7,-14 +:6 db $24,0,-5 +:7 db $20,17,-16 +:8 db $21,16,-19 +:9 db $4b,12,-9 ;alertstand +:10 db $26,13,-34 +:11 db $27,7,-25 +:12 db $28,10,-16 +:13 db $29,10,-11 +:14 db $2a,22,-21 +:15 db $2b,28,-23 +:16 db $2c,13,-35 +:17 db $2d,0,-38 +:18 db $2e,0,-29 +:19 db $2f,21,-19 +:20 db $30,14,-23 +:21 db $31,21,-22 +:22 db $31,22,-23 +:23 db $2f,7,-13 +:24 db $2f,15,-18 ;$20,17,-19 for flash +:25 db $24,0,-8 +:26 db $1e,7,-27 +:27 db $48,14,-28 +:28 db $26,7,-27 +:29 db $21,6,-23 +:30 db $21,9,-21 +:31 db $28,11,-18 +:32 db $2b,24,-23 +:33 db $2b,19,-23 +:34 db $2b,21,-23 +;sheathing +:35 db $40,7,-32 +:36 db $41,14,-32 +:37 db $42,14,-31 +:38 db $43,14,-29 +:39 db $44,28,-28 +:40 db $45,28,-28 +:41 db $46,21,-25 +:42 db $47,14,-22 + +:43 db 0,14,-25 ;43-46: kid stabbed +:44 db 0,21,-25 +:45 db $4a,0,-16 +:46 db $26,8,-37 +:47 db $4c,14,-24 ;47-50: enemy stabbed +:48 db $4d,14,-24 +:49 db $4e,7,-14 +:50 db $26,8,-37 + +*------------------------------- + lst + ds 1 + usr $a9,15,$00,*-org + lst off diff --git a/01 POP Source/Source/GAMEBG.S b/01 POP Source/Source/GAMEBG.S index dbadbfd..92d03e1 100755 --- a/01 POP Source/Source/GAMEBG.S +++ b/01 POP Source/Source/GAMEBG.S @@ -1 +1,1192 @@ -* gamebg ThreeFive = 1 EditorDisk = 0 org = $4c00 tr on lst off lstdo off *------------------------------- * * PRINCE OF PERSIA * Copyright 1989 Jordan Mechner * *------------------------------- org org jmp UPDATEMETERS jmp DRAWKIDMETER jmp DRAWSWORD jmp DRAWKID jmp DRAWSHAD jmp SETUPFLAME jmp CONTINUEMSG jmp ADDCHAROBJ jmp SETOBJINDX jmp PRINTLEVEL jmp DRAWOPPMETER jmp FLIPDISKMSG jmp TIMELEFTMSG jmp DRAWGUARD jmp DRAWGUARD jmp SETUPFLASK jmp SETUPCOMIX jmp PSETUPFLAME jmp DRAWPOST jmp DRAWGLASS jmp INITLAY jmp TWINKLE jmp FLOW jmp PMASK jmp YELLOW jmp SETRECHECK0 jmp RECHECKYEL ds 3 ds 3 ds 3 *------------------------------- lst put eq lst put gameeq lst off *------------------------------- * * 2nd level copy protection * signature check routine * *------------------------------- do ThreeFive YELLOW lda #$80 sta yellowflag rts else put ryellow1 fin *------------------------------- lst put movedata lst off *------------------------------- dum locals xsave ds 1 addr ds 2 temp ds 1 dend tempsave ds $10 *------------------------------- * Strength meters KidStrX db 00,01,02,03,04,05,06,08,09,10,11,12 KidStrOFF db 00,01,02,03,04,05,06,00,01,02,03,04 OppStrX db 39,38,37,36,35,34,32,31,30,29,28,27 OppStrOFF db 05,04,03,02,01,00,06,05,04,03,02,01 bullet = $88 ;in bgtable2 blank = $8c bline hex 89,8a,8b *------------------------------- * Post in Princess's room postx = 31 posty = 152 postimg = $c ;chtable6 *------------------------------- * Stars outside Princess's window starx = 2 stary hex 62,65,6d,72 stari hex 2a,2b,2b,2a ;chtable6 *------------------------------- * Hourglass glassx = 19 glassy = 151 glassimg hex 15,0d,0e,0f,10,11,12,13,14 ;chtable6 sandht db 0,1,2,3,4,5,6,7 flowx = glassx+1 flowy = glassy-2 flowimg hex 16,17,18 ;chtable6 *------------------------------- * Masks for Princess's face & hair pmaskdx hex 00,00 pmaskdy db -4,-33 pmaski hex 2c,22 *------------------------------- * Comix starimage = $41 startable = 0 ;chtable1 *------------------------------- * Torch animation frames * 0 1 2 3 4 5 6 7 8 9 10 11 * 12 13 14 15 16 17 torchflame hex 52,53,54,55,56,61,62,63,64,52,54,56 hex 63,61,55,53,64,62 ptorchflame db 1,2,3,4,5,6,7,8,9,3,5,7,1,4,9,2,8,6 *------------------------------- * Bubbling flask frames * 0 1 2 3 4 5 6 7 8 9 10 11 bubble hex b2,af,b0,b1,b0,af,b1,b0,af *------------------------------- * Message data: YCO, XCO, OFFSET, IMAGE my = 90 lowmy = 153 hiconty = 73 lowconty = 168 contbox db hiconty,13,0,$7c ;Press button to continue msgbox db my,15,0,$7b ;Empty message box levelmsg db my-5,16,3,$7a ;"Level" flipbox db my-1,13,0,$7e ;Turn disk over timeleft db my,11,0,$7d ;Minutes left seconds db my-5,14,0,$7f ;"Seconds" *------------------------------- * Numbers (0-12) digit1 hex 00,00,00,00,00,00,00,00,00,00 hex 71,71,71 digit2 hex 70,71,72,73,74,75,76,77,78,79 hex 70,71,72 *------------------------------- * Print "XX Minutes Left" *------------------------------- ]rts rts TIMELEFTMSG lda #timeleft ldx #>timeleft jsr setupimage lda MinLeft cmp #2 bcs :ok lda KidAction cmp #3 beq :ok cmp #4 beq :ok ;falling lda KidBlockY cmp #1 bne :ok lda #lowmy sta YCO ;keep msg box out of kid's way :ok jsr superim1 lda YCO sec sbc #5 sta YCO lda XCO clc adc #1 sta XCO lda #0 sta OPACITY lda #ora sta OPACITY jsr getminleft lda MinLeft ;BCD byte (e.g., $55 = 55 minutes) cmp #2 bcs :1 lda SecLeft :1 sta temp lsr lsr lsr lsr beq :skip1st tax lda digit2,x ;1st digit sta IMAGE jsr addmsg :skip1st lda XCO clc adc #1 sta XCO lda temp and #$f tax lda digit2,x ;2nd digit sta IMAGE jsr addmsg * Minutes or seconds? lda MinLeft cmp #2 bcs ]rts lda YCO pha lda #seconds ldx #>seconds jsr setupimage pla sta YCO lda #sta sta OPACITY jmp addmsg ;replace "minutes" with "seconds" *------------------------------- * Print "Level XX" *------------------------------- ]rts rts PRINTLEVEL lda #msgbox ldx #>msgbox jsr superimage lda #levelmsg ldx #>levelmsg jsr setupimage jsr getlevelno cpx #10 bcc :1 lda #0 sta OFFSET :1 lda #ora sta OPACITY jsr addmsg lda XCO clc adc #6 sta XCO jsr getlevelno ;X = level # (0-12) lda digit1,x ;1st digit beq :skip1st sta IMAGE lda #ora sta OPACITY jsr addmsg lda XCO clc adc #1 sta XCO jsr getlevelno :skip1st lda digit2,x ;2nd digit sta IMAGE lda #ora sta OPACITY jmp addmsg *------------------------------- getlevelno ldx level cpx #13 bcc :ok ldx #12 :ok ]rts rts *------------------------------- * Superimpose "Press button to continue" message *------------------------------- CONTINUEMSG lda #contbox ldx #>contbox jsr setupimage lda KidBlockX and #1 bne :1 lda #lowconty sta YCO :1 jmp superim1 *------------------------------- * Superimpose "Turn disk over" message *------------------------------- FLIPDISKMSG lda #flipbox ldx #>flipbox jmp superimage *------------------------------- * Superimpose image (using layrsave) *------------------------------- superimage jsr setupimage superim1 lda #sta.$40 sta OPACITY jmp addmsg *------------------------------- * Set up image * * In: A-X = image data addr * Out: XCO, YCO, IMAGE *------------------------------- setupimage sta addr stx addr+1 ldy #0 lda (addr),y sta YCO iny lda (addr),y sta XCO iny lda (addr),y sta OFFSET iny lda (addr),y sta IMAGE ]rts :rts rts *------------------------------- * Draw Kid *------------------------------- DRAWKID lda backtolife beq :2 lda PAGE beq ]rts ;flash when coming back to life :2 lda mergetimer bmi :1 and #1 beq :1 jmp DrawEored ;flash between kid & shadowman :1 jmp DrawNormal *------------------------------- * Draw Sword *------------------------------- DRAWSWORD jmp DrawNormal *------------------------------- * Draw Shadowman *------------------------------- DRAWSHAD jmp DrawEored *------------------------------- * Draw Guard *------------------------------- DRAWGUARD do EditorDisk lda #EditorDisk cmp #2 beq DrawNormal fin lda GuardColor ;set by "ADDGUARD" in AUTO beq DrawNormal bne DrawShifted *------------------------------- DrawNormal lda #mask sta OPACITY lda #UseLayrsave.$80 jmp addmid ]rts rts *------------------------------- DrawShifted lda #1 jsr chgoffset lda #mask sta OPACITY lda #UseLayrsave.$80 jmp addmid *------------------------------- DrawEored lda #eor sta OPACITY lda #UseLayrsave.$80 jmp addmid *------------------------------- chgoffset clc adc OFFSET cmp #7 bcc :1 inc XCO sec sbc #7 :1 sta OFFSET rts *------------------------------- * * Update strength meters * *------------------------------- UPDATEMETERS lda redkidmeter beq :1 jsr DrawKidMeter :1 lda redoppmeter beq ]rts jmp DrawOppMeter ]rts rts *------------------------------- * * Draw kid's strength meter at lower left * *------------------------------- DRAWKIDMETER lda inbuilder bne ]rts lda #191 sta YCO lda #sta sta OPACITY ldx #0 stx xsave ;# of bullets drawn so far :loop lda KidStrength sec sbc xsave ;# of bullets left to draw beq :darkpart cmp #4 bcs :draw3 cmp #3 bcs :draw2 cmp #2 bcc :drawlast ;Draw 1 bullet :draw1 ldy #1 bne :drline ;Draw 2 bullets :draw2 ldy #2 bne :drline ;Draw 3 bullets :draw3 ldy #3 bne :drline :drawlast lda KidStrength cmp #2 bcs :steady lda PAGE beq :skip ;flashes when down to 1 :steady lda #bullet ldy #1 jsr :draw :skip jmp :darkpart * Draw line of 1-3 bullets :drline lda bline-1,y ;image # jsr :draw jmp :loop :draw sta IMAGE ldx xsave tya clc adc xsave sta xsave * In: IMAGE; x = unit # (0 = leftmost) :drawimg lda KidStrX,x sta XCO lda KidStrOFF,x sta OFFSET jmp addmsg * Draw blanks to limit of MaxKidStr :darkpart lda #and sta OPACITY lda #blank sta IMAGE :dloop ldx xsave cpx MaxKidStr bcs ]rts jsr :drawimg inc xsave bne :dloop ]rts rts *------------------------------- * * Draw opp's strength meter at lower right * *------------------------------- DRAWOPPMETER lda inbuilder bne ]rts lda OppStrength beq ]rts lda ShadID cmp #24 ;mouse beq ]rts cmp #4 ;skel beq ]rts cmp #1 ;shadow bne :1 lda level cmp #12 bne ]rts ;shad strength shows only on level 12 :1 lda #191 sta YCO lda #sta.$80 ;mirror sta OPACITY ldx #0 stx xsave ;# of bullets drawn so far :loop lda OppStrength sec sbc xsave ;# of bullets left to draw beq :darkpart cmp #4 bcs :draw3 cmp #3 bcs :draw2 cmp #2 bcc :drawlast ;Draw 1 bullet :draw1 ldy #1 bne :drline ;Draw 2 bullets :draw2 ldy #2 bne :drline ;Draw 3 bullets :draw3 ldy #3 bne :drline :drawlast lda OppStrength cmp #2 bcs :steady lda PAGE beq :darkpart ;flashes when down to 1 :steady lda #bullet ldy #1 jmp :draw * Draw line of 1-3 bullets :drline lda bline-1,y ;image # jsr :draw jmp :loop :draw sta IMAGE ldx xsave tya clc adc xsave sta xsave :drawimg lda OppStrX,x sta XCO lda OppStrOFF,x sta OFFSET jmp addmsg :darkpart lda #and.$80 sta OPACITY lda #blank sta IMAGE ldx xsave jmp :drawimg *------------------------------- * * Set up to draw bubbling flask * * In/out: same as SETUPFLAME * *------------------------------- EmptyPot = 0 RefreshPot = %00100000 BoostPot = %01000000 MystPot = %01100000 boffset = 2 SETUPFLASK lda #boffset sta OFFSET txa and #%11100000 cmp #EmptyPot beq :0 cmp #BoostPot beq :tall ;special flask (taller) bcc :cont inc OFFSET ;mystery potion (blue) :tall lda YCO sec sbc #4 sta YCO :cont txa and #%00011111 tax cpx #bubbLast+1 bcc :ok ldx #0 :ok lda bubble,x sta IMAGE inc XCO inc XCO lda YCO sec sbc #14 sta YCO lda #sta sta OPACITY lda #bgtable2 sta TABLE lda #>bgtable2 sta TABLE+1 ]rts rts :0 ldx #0 beq :ok *------------------------------- * * Setup to draw flame * * In: XCO = blockxco * YCO = Ay * X = spreced * * Out: ready to call ADDBACK (or FASTLAY) * *------------------------------- SETUPFLAME cpx #torchLast+1 bcs ]rts lda torchflame,x sta IMAGE inc XCO lda YCO sec sbc #43 sta YCO lda #sta sta OPACITY lda #bgtable1 sta TABLE lda #>bgtable1 sta TABLE+1 ]rts rts *------------------------------- * * Setup to draw flame (Princess's room) * * In: XCO, YCO; X = frame # * Out: Ready to call ADDMID or LAY * *------------------------------- PSETUPFLAME cpx #torchLast+1 bcs ]rts lda ptorchflame,x sta IMAGE lda #sta sta OPACITY jsr initlay ]setch6 lda #chtable6 sta TABLE lda #>chtable6 sta TABLE+1 ]rts rts *------------------------------- * * Twinkle one of the stars outside Princess's window * (Update it directly on both screens) * * In: X = star # (0-3) * *------------------------------- TWINKLE lda #starx sta XCO lda stary,x sta YCO lda stari,x sta IMAGE lda #eor sta OPACITY jsr ]setch6 jsr fastlay ;<--DIRECT HIRES CALL lda PAGE eor #$20 sta PAGE ;& on other page jsr fastlay lda PAGE eor #$20 sta PAGE rts *------------------------------- * * Draw big white post in Princess's room * *------------------------------- DRAWPOST lda #postx sta XCO lda #posty sta YCO lda #postimg sta IMAGE lda #ora sta OPACITY jsr ]setch6 jmp addfore *------------------------------- * * Draw hourglass in Princess's room * * In: X = glass state (0-8, 0 = full) * *------------------------------- DRAWGLASS lda #glassx sta XCO lda #glassy sta YCO lda glassimg,x sta IMAGE lda #sta sta OPACITY jsr ]setch6 jmp addback *------------------------------- * * Mask princess's face & hair for certain CharPosns * * (Called after ADDCHAROBJ) * *------------------------------- PMASK ldx CharPosn cpx #19 ;plie bne :1 ldx #0 bpl :mask :1 cpx #1 ;pslump-1 beq :m1 cpx #18 ;pslump-2 bne :2 :m1 ldx #1 bpl :mask :2 ]rts rts :mask lda FCharY clc adc pmaskdy,x sta YCO lda XCO clc adc pmaskdx,x sta XCO lda pmaski,x sta IMAGE lda #5 ;chtable6 sta TABLE lda #and sta OPACITY lda #UseLayrsave.$80 jmp addmid *------------------------------- * If failed copy prot check due to disk not in drive, recheck * In: a = 0 (Call after setrecheck0) *------------------------------- RECHECKYEL sta tempblockx sta tempblocky jsr indexblock ;set y = 0 lda (locals),y ;All of this just to hide "lda recheck0"! beq ]rts ldx #5 jsr yellow lda #$ff rts *------------------------------- * * Draw sand flowing through hourglass * * In: X = frame # (0-3) * Y = hourglass state (0-8) * *------------------------------- FLOW cpy #8 bcs ]rts ;glass is empty jsr initlay lda #glassy sec sbc sandht,y sta BOTCUT lda flowimg,x sta IMAGE lda #flowx sta XCO lda #0 sta OFFSET lda #flowy sta YCO lda #sta sta OPACITY jsr ]setch6 jmp lay ;<---DIRECT HIRES CALL *------------------------------- * Save/restore FCharVars saveFChar ldx #$f :loop lda FCharVars,x sta tempsave,x dex bpl :loop rts restoreFChar ldx #$f :loop lda tempsave,x sta FCharVars,x dex bpl :loop ]rts rts *------------------------------- * * Draw "comix" star * * In: Char data * *------------------------------- SETUPCOMIX jsr saveFChar jsr :sub jmp restoreFChar :sub lda #$ff sta FCharIndex * Get y-coord lda CharPosn cmp #185 ;dead beq :low cmp #177 ;impaled beq :imp cmp #106 bcc :80 cmp #111 ;crouching bcc :low :80 cmp #178 ;halved beq ]rts lda #-15 ldx CharID beq :3 lda #-11 ;kid strikes lower than opponent :3 clc adc FCharY sta FCharY jmp :8 :low lda #4 clc adc FCharY sta FCharY jmp :8 * Get x-coord :imp lda #-5 impaled bne :9 :8 lda #5 :9 jsr addfcharx * Get color (kid red, opps blue) lda CharID beq :2 ;kid: 0 lda #1 ;opponents: 1 :2 eor FCharX eor FCharFace and #1 ;look only at low bits bne :1 inc FCharX bne :1 inc FCharX+1 :1 lda #starimage sta FCharImage lda #startable sta FCharTable lda #0 sta FCharCU sta FCharCL lda #40 sta FCharCR lda #192 sta FCharCD lda #TypeComix jmp addcharobj ]rts rts *------------------------------- * * A D D C H A R O B J * * Add a character to object table * * In: FCharVars * A = object type * *------------------------------- ADDCHAROBJ ldx objX ;# objects already in list inx cpx #maxobj bcs ]rts ;list full (shouldn't happen) stx objX sta objTYP,x lda FCharX sta XCO lda FCharX+1 sta OFFSET txa pha jsr cvtx ;from 280-res to byte/offset pla tax lda XCO sta objX,x lda OFFSET sta objOFF,x lda FCharY sta objY,x lda FCharCU sta objCU,x lda FCharCL sta objCL,x lda FCharCR sta objCR,x lda FCharCD sta objCD,x lda FCharImage sta objIMG,x lda FCharTable sta objTAB,x lda FCharFace sta objFACE,x jmp SETOBJINDX *------------------------------- * * S E T O B J I N D X * * Set object index * *------------------------------- SETOBJINDX lda FCharIndex sta objINDX,x cmp #30 bcs :os tax lda #1 sta objbuf,x :os rts *------------------------------- * * Text routines * * NOTE: These routines bypass normal data structures * & write directly to hi-res page. * * Call at end of DRAWALL to make sure text goes on top * of everything else. * *------------------------------- * * Call once before using other text routines * *------------------------------- pretext jsr initlay lda #bgtable2 sta TABLE lda #>bgtable2 sta TABLE+1 rts *------------------------------- * Part of "Yellow" copy-protection SETRECHECK0 lda #recheck0 sta locals lda #>recheck0 sta locals+1 ;fall thru (& return A = 0) *------------------------------- INITLAY lda #3 ;auxmem sta BANK lda #40 sta RIGHTCUT lda #192 sta BOTCUT ;use full screen lda #0 sta LEFTCUT sta TOPCUT rts *------------------------------- * * Print character * * In: PAGE, XCO/OFFSET, YCO * a = ASCII value of character * Out: XCO/OFFSET (modified) * *------------------------------- prchar sec sbc #"/" ;"0" = 1 sta IMAGE lda #ora sta OPACITY jsr lay inc XCO rts *------------------------------- lst ds 1 usr $a9,17,$00,*-org lst off \ No newline at end of file +* gamebg +ThreeFive = 1 +EditorDisk = 0 +org = $4c00 + tr on + lst off + lstdo off +*------------------------------- +* +* PRINCE OF PERSIA +* Copyright 1989 Jordan Mechner +* +*------------------------------- + org org + + jmp UPDATEMETERS + jmp DRAWKIDMETER + jmp DRAWSWORD + jmp DRAWKID + jmp DRAWSHAD + + jmp SETUPFLAME + jmp CONTINUEMSG + jmp ADDCHAROBJ + jmp SETOBJINDX + jmp PRINTLEVEL + + jmp DRAWOPPMETER + jmp FLIPDISKMSG + jmp TIMELEFTMSG + jmp DRAWGUARD + jmp DRAWGUARD + + jmp SETUPFLASK + jmp SETUPCOMIX + jmp PSETUPFLAME + jmp DRAWPOST + jmp DRAWGLASS + + jmp INITLAY + jmp TWINKLE + jmp FLOW + jmp PMASK + jmp YELLOW + + jmp SETRECHECK0 + jmp RECHECKYEL + ds 3 + ds 3 + ds 3 + +*------------------------------- + lst + put eq + lst + put gameeq + lst off + +*------------------------------- +* +* 2nd level copy protection +* signature check routine +* +*------------------------------- + do ThreeFive +YELLOW lda #$80 + sta yellowflag + rts + + else + put ryellow1 + fin + +*------------------------------- + lst + put movedata + lst off + +*------------------------------- + dum locals + +xsave ds 1 +addr ds 2 +temp ds 1 + + dend + +tempsave ds $10 + +*------------------------------- +* Strength meters + +KidStrX db 00,01,02,03,04,05,06,08,09,10,11,12 +KidStrOFF db 00,01,02,03,04,05,06,00,01,02,03,04 + +OppStrX db 39,38,37,36,35,34,32,31,30,29,28,27 +OppStrOFF db 05,04,03,02,01,00,06,05,04,03,02,01 + +bullet = $88 ;in bgtable2 +blank = $8c +bline hex 89,8a,8b + +*------------------------------- +* Post in Princess's room + +postx = 31 +posty = 152 +postimg = $c ;chtable6 + +*------------------------------- +* Stars outside Princess's window + +starx = 2 +stary hex 62,65,6d,72 +stari hex 2a,2b,2b,2a ;chtable6 + +*------------------------------- +* Hourglass + +glassx = 19 +glassy = 151 +glassimg hex 15,0d,0e,0f,10,11,12,13,14 ;chtable6 +sandht db 0,1,2,3,4,5,6,7 + +flowx = glassx+1 +flowy = glassy-2 +flowimg hex 16,17,18 ;chtable6 + +*------------------------------- +* Masks for Princess's face & hair + +pmaskdx hex 00,00 +pmaskdy db -4,-33 +pmaski hex 2c,22 + +*------------------------------- +* Comix + +starimage = $41 +startable = 0 ;chtable1 + +*------------------------------- +* Torch animation frames +* 0 1 2 3 4 5 6 7 8 9 10 11 +* 12 13 14 15 16 17 + +torchflame hex 52,53,54,55,56,61,62,63,64,52,54,56 + hex 63,61,55,53,64,62 + +ptorchflame db 1,2,3,4,5,6,7,8,9,3,5,7,1,4,9,2,8,6 + +*------------------------------- +* Bubbling flask frames +* 0 1 2 3 4 5 6 7 8 9 10 11 + +bubble hex b2,af,b0,b1,b0,af,b1,b0,af + +*------------------------------- +* Message data: YCO, XCO, OFFSET, IMAGE + +my = 90 +lowmy = 153 +hiconty = 73 +lowconty = 168 + +contbox db hiconty,13,0,$7c ;Press button to continue +msgbox db my,15,0,$7b ;Empty message box +levelmsg db my-5,16,3,$7a ;"Level" +flipbox db my-1,13,0,$7e ;Turn disk over +timeleft db my,11,0,$7d ;Minutes left +seconds db my-5,14,0,$7f ;"Seconds" + +*------------------------------- +* Numbers (0-12) + +digit1 hex 00,00,00,00,00,00,00,00,00,00 + hex 71,71,71 + +digit2 hex 70,71,72,73,74,75,76,77,78,79 + hex 70,71,72 + +*------------------------------- +* Print "XX Minutes Left" +*------------------------------- +]rts rts + +TIMELEFTMSG + lda #timeleft + ldx #>timeleft + jsr setupimage + + lda MinLeft + cmp #2 + bcs :ok + lda KidAction + cmp #3 + beq :ok + cmp #4 + beq :ok ;falling + lda KidBlockY + cmp #1 + bne :ok + lda #lowmy + sta YCO ;keep msg box out of kid's way +:ok jsr superim1 + + lda YCO + sec + sbc #5 + sta YCO + + lda XCO + clc + adc #1 + sta XCO + lda #0 + sta OPACITY + + lda #ora + sta OPACITY + + jsr getminleft + + lda MinLeft ;BCD byte (e.g., $55 = 55 minutes) + cmp #2 + bcs :1 + lda SecLeft +:1 sta temp + lsr + lsr + lsr + lsr + beq :skip1st + tax + lda digit2,x ;1st digit + sta IMAGE + + jsr addmsg + +:skip1st lda XCO + clc + adc #1 + sta XCO + + lda temp + and #$f + tax + lda digit2,x ;2nd digit + sta IMAGE + + jsr addmsg + +* Minutes or seconds? + + lda MinLeft + cmp #2 + bcs ]rts + + lda YCO + pha + lda #seconds + ldx #>seconds + jsr setupimage + pla + sta YCO + lda #sta + sta OPACITY + jmp addmsg ;replace "minutes" with "seconds" + +*------------------------------- +* Print "Level XX" +*------------------------------- +]rts rts + +PRINTLEVEL + lda #msgbox + ldx #>msgbox + jsr superimage + + lda #levelmsg + ldx #>levelmsg + jsr setupimage + + jsr getlevelno + cpx #10 + bcc :1 + lda #0 + sta OFFSET +:1 + lda #ora + sta OPACITY + jsr addmsg + + lda XCO + clc + adc #6 + sta XCO + + jsr getlevelno ;X = level # (0-12) + lda digit1,x ;1st digit + beq :skip1st + sta IMAGE + + lda #ora + sta OPACITY + jsr addmsg + + lda XCO + clc + adc #1 + sta XCO + + jsr getlevelno +:skip1st lda digit2,x ;2nd digit + sta IMAGE + + lda #ora + sta OPACITY + jmp addmsg + +*------------------------------- +getlevelno + ldx level + cpx #13 + bcc :ok + ldx #12 +:ok +]rts rts + +*------------------------------- +* Superimpose "Press button to continue" message +*------------------------------- +CONTINUEMSG + lda #contbox + ldx #>contbox + jsr setupimage + + lda KidBlockX + and #1 + bne :1 + lda #lowconty + sta YCO +:1 jmp superim1 + +*------------------------------- +* Superimpose "Turn disk over" message +*------------------------------- +FLIPDISKMSG + lda #flipbox + ldx #>flipbox + jmp superimage + +*------------------------------- +* Superimpose image (using layrsave) +*------------------------------- +superimage + jsr setupimage +superim1 + lda #sta.$40 + sta OPACITY + jmp addmsg + +*------------------------------- +* Set up image +* +* In: A-X = image data addr +* Out: XCO, YCO, IMAGE +*------------------------------- +setupimage + sta addr + stx addr+1 + + ldy #0 + lda (addr),y + sta YCO + iny + lda (addr),y + sta XCO + iny + lda (addr),y + sta OFFSET + iny + lda (addr),y + sta IMAGE +]rts +:rts rts + +*------------------------------- +* Draw Kid +*------------------------------- +DRAWKID + lda backtolife + beq :2 + lda PAGE + beq ]rts ;flash when coming back to life + +:2 lda mergetimer + bmi :1 + and #1 + beq :1 + jmp DrawEored ;flash between kid & shadowman + +:1 jmp DrawNormal + +*------------------------------- +* Draw Sword +*------------------------------- +DRAWSWORD + jmp DrawNormal + +*------------------------------- +* Draw Shadowman +*------------------------------- +DRAWSHAD + jmp DrawEored + +*------------------------------- +* Draw Guard +*------------------------------- +DRAWGUARD + do EditorDisk + lda #EditorDisk + cmp #2 + beq DrawNormal + fin + + lda GuardColor ;set by "ADDGUARD" in AUTO + beq DrawNormal + bne DrawShifted + +*------------------------------- +DrawNormal + lda #mask + sta OPACITY + + lda #UseLayrsave.$80 + jmp addmid + +]rts rts + +*------------------------------- +DrawShifted + lda #1 + jsr chgoffset + + lda #mask + sta OPACITY + + lda #UseLayrsave.$80 + jmp addmid + +*------------------------------- +DrawEored + lda #eor + sta OPACITY + + lda #UseLayrsave.$80 + jmp addmid + +*------------------------------- +chgoffset + clc + adc OFFSET + cmp #7 + bcc :1 + + inc XCO + sec + sbc #7 + +:1 sta OFFSET + rts + +*------------------------------- +* +* Update strength meters +* +*------------------------------- +UPDATEMETERS + lda redkidmeter + beq :1 + + jsr DrawKidMeter + +:1 lda redoppmeter + beq ]rts + + jmp DrawOppMeter +]rts rts + +*------------------------------- +* +* Draw kid's strength meter at lower left +* +*------------------------------- +DRAWKIDMETER + lda inbuilder + bne ]rts + + lda #191 + sta YCO + lda #sta + sta OPACITY + + ldx #0 + stx xsave ;# of bullets drawn so far + +:loop lda KidStrength + sec + sbc xsave ;# of bullets left to draw + beq :darkpart + cmp #4 + bcs :draw3 + cmp #3 + bcs :draw2 + cmp #2 + bcc :drawlast +;Draw 1 bullet +:draw1 ldy #1 + bne :drline + ;Draw 2 bullets +:draw2 ldy #2 + bne :drline +;Draw 3 bullets +:draw3 ldy #3 + bne :drline + +:drawlast lda KidStrength + cmp #2 + bcs :steady + lda PAGE + beq :skip ;flashes when down to 1 +:steady lda #bullet + ldy #1 + jsr :draw +:skip jmp :darkpart + +* Draw line of 1-3 bullets + +:drline lda bline-1,y ;image # + jsr :draw + jmp :loop + +:draw sta IMAGE + ldx xsave + tya + clc + adc xsave + sta xsave + +* In: IMAGE; x = unit # (0 = leftmost) + +:drawimg lda KidStrX,x + sta XCO + lda KidStrOFF,x + sta OFFSET + jmp addmsg + +* Draw blanks to limit of MaxKidStr + +:darkpart + lda #and + sta OPACITY + lda #blank + sta IMAGE +:dloop ldx xsave + cpx MaxKidStr + bcs ]rts + jsr :drawimg + inc xsave + bne :dloop +]rts rts + +*------------------------------- +* +* Draw opp's strength meter at lower right +* +*------------------------------- +DRAWOPPMETER + lda inbuilder + bne ]rts + + lda OppStrength + beq ]rts + + lda ShadID + cmp #24 ;mouse + beq ]rts + cmp #4 ;skel + beq ]rts + cmp #1 ;shadow + bne :1 + lda level + cmp #12 + bne ]rts ;shad strength shows only on level 12 +:1 + lda #191 + sta YCO + lda #sta.$80 ;mirror + sta OPACITY + + ldx #0 + stx xsave ;# of bullets drawn so far + +:loop lda OppStrength + sec + sbc xsave ;# of bullets left to draw + beq :darkpart + cmp #4 + bcs :draw3 + cmp #3 + bcs :draw2 + cmp #2 + bcc :drawlast +;Draw 1 bullet +:draw1 ldy #1 + bne :drline + ;Draw 2 bullets +:draw2 ldy #2 + bne :drline +;Draw 3 bullets +:draw3 ldy #3 + bne :drline + +:drawlast lda OppStrength + cmp #2 + bcs :steady + lda PAGE + beq :darkpart ;flashes when down to 1 +:steady lda #bullet + ldy #1 + jmp :draw + +* Draw line of 1-3 bullets + +:drline lda bline-1,y ;image # + jsr :draw + jmp :loop + +:draw sta IMAGE + ldx xsave + tya + clc + adc xsave + sta xsave + +:drawimg lda OppStrX,x + sta XCO + lda OppStrOFF,x + sta OFFSET + jmp addmsg + +:darkpart + lda #and.$80 + sta OPACITY + lda #blank + sta IMAGE + ldx xsave + jmp :drawimg + +*------------------------------- +* +* Set up to draw bubbling flask +* +* In/out: same as SETUPFLAME +* +*------------------------------- +EmptyPot = 0 +RefreshPot = %00100000 +BoostPot = %01000000 +MystPot = %01100000 + +boffset = 2 + +SETUPFLASK + lda #boffset + sta OFFSET + + txa + and #%11100000 + cmp #EmptyPot + beq :0 + cmp #BoostPot + beq :tall ;special flask (taller) + bcc :cont + + inc OFFSET ;mystery potion (blue) + +:tall lda YCO + sec + sbc #4 + sta YCO + +:cont txa + and #%00011111 + tax + cpx #bubbLast+1 + bcc :ok + ldx #0 +:ok lda bubble,x + sta IMAGE + + inc XCO + inc XCO + + lda YCO + sec + sbc #14 + sta YCO + + lda #sta + sta OPACITY + + lda #bgtable2 + sta TABLE + lda #>bgtable2 + sta TABLE+1 + +]rts rts + +:0 ldx #0 + beq :ok + +*------------------------------- +* +* Setup to draw flame +* +* In: XCO = blockxco +* YCO = Ay +* X = spreced +* +* Out: ready to call ADDBACK (or FASTLAY) +* +*------------------------------- +SETUPFLAME + cpx #torchLast+1 + bcs ]rts + + lda torchflame,x + sta IMAGE + + inc XCO + + lda YCO + sec + sbc #43 + sta YCO + + lda #sta + sta OPACITY + + lda #bgtable1 + sta TABLE + lda #>bgtable1 + sta TABLE+1 + +]rts rts + +*------------------------------- +* +* Setup to draw flame (Princess's room) +* +* In: XCO, YCO; X = frame # +* Out: Ready to call ADDMID or LAY +* +*------------------------------- +PSETUPFLAME + cpx #torchLast+1 + bcs ]rts + + lda ptorchflame,x + sta IMAGE + + lda #sta + sta OPACITY + + jsr initlay + +]setch6 lda #chtable6 + sta TABLE + lda #>chtable6 + sta TABLE+1 + +]rts rts + +*------------------------------- +* +* Twinkle one of the stars outside Princess's window +* (Update it directly on both screens) +* +* In: X = star # (0-3) +* +*------------------------------- +TWINKLE + lda #starx + sta XCO + lda stary,x + sta YCO + lda stari,x + sta IMAGE + lda #eor + sta OPACITY + jsr ]setch6 + jsr fastlay ;<--DIRECT HIRES CALL + lda PAGE + eor #$20 + sta PAGE ;& on other page + jsr fastlay + lda PAGE + eor #$20 + sta PAGE + rts + +*------------------------------- +* +* Draw big white post in Princess's room +* +*------------------------------- +DRAWPOST + lda #postx + sta XCO + lda #posty + sta YCO + lda #postimg + sta IMAGE + lda #ora + sta OPACITY + jsr ]setch6 + jmp addfore + +*------------------------------- +* +* Draw hourglass in Princess's room +* +* In: X = glass state (0-8, 0 = full) +* +*------------------------------- +DRAWGLASS + lda #glassx + sta XCO + lda #glassy + sta YCO + lda glassimg,x + sta IMAGE + lda #sta + sta OPACITY + jsr ]setch6 + jmp addback + +*------------------------------- +* +* Mask princess's face & hair for certain CharPosns +* +* (Called after ADDCHAROBJ) +* +*------------------------------- +PMASK + ldx CharPosn + cpx #19 ;plie + bne :1 + ldx #0 + bpl :mask +:1 cpx #1 ;pslump-1 + beq :m1 + cpx #18 ;pslump-2 + bne :2 +:m1 ldx #1 + bpl :mask +:2 + +]rts rts + +:mask + lda FCharY + clc + adc pmaskdy,x + sta YCO + + lda XCO + clc + adc pmaskdx,x + sta XCO + + lda pmaski,x + sta IMAGE + + lda #5 ;chtable6 + sta TABLE + + lda #and + sta OPACITY + lda #UseLayrsave.$80 + jmp addmid + +*------------------------------- +* If failed copy prot check due to disk not in drive, recheck +* In: a = 0 (Call after setrecheck0) +*------------------------------- +RECHECKYEL + sta tempblockx + sta tempblocky + jsr indexblock ;set y = 0 + lda (locals),y ;All of this just to hide "lda recheck0"! + beq ]rts + ldx #5 + jsr yellow + lda #$ff + rts + +*------------------------------- +* +* Draw sand flowing through hourglass +* +* In: X = frame # (0-3) +* Y = hourglass state (0-8) +* +*------------------------------- +FLOW + cpy #8 + bcs ]rts ;glass is empty + jsr initlay + lda #glassy + sec + sbc sandht,y + sta BOTCUT + lda flowimg,x + sta IMAGE + lda #flowx + sta XCO + lda #0 + sta OFFSET + lda #flowy + sta YCO + lda #sta + sta OPACITY + jsr ]setch6 + jmp lay ;<---DIRECT HIRES CALL + +*------------------------------- +* Save/restore FCharVars + +saveFChar + ldx #$f +:loop lda FCharVars,x + sta tempsave,x + dex + bpl :loop + rts + +restoreFChar + ldx #$f +:loop lda tempsave,x + sta FCharVars,x + dex + bpl :loop +]rts rts + +*------------------------------- +* +* Draw "comix" star +* +* In: Char data +* +*------------------------------- +SETUPCOMIX + jsr saveFChar + jsr :sub + jmp restoreFChar + +:sub lda #$ff + sta FCharIndex + +* Get y-coord + + lda CharPosn + cmp #185 ;dead + beq :low + cmp #177 ;impaled + beq :imp + cmp #106 + bcc :80 + cmp #111 ;crouching + bcc :low +:80 cmp #178 ;halved + beq ]rts + + lda #-15 + ldx CharID + beq :3 + lda #-11 ;kid strikes lower than opponent +:3 clc + adc FCharY + sta FCharY + jmp :8 + +:low lda #4 + clc + adc FCharY + sta FCharY + jmp :8 + +* Get x-coord + +:imp lda #-5 impaled + bne :9 +:8 lda #5 +:9 jsr addfcharx + +* Get color (kid red, opps blue) + + lda CharID + beq :2 ;kid: 0 + lda #1 ;opponents: 1 +:2 + eor FCharX + eor FCharFace + and #1 ;look only at low bits + bne :1 + inc FCharX + bne :1 + inc FCharX+1 +:1 + lda #starimage + sta FCharImage + lda #startable + sta FCharTable + + lda #0 + sta FCharCU + sta FCharCL + lda #40 + sta FCharCR + lda #192 + sta FCharCD + + lda #TypeComix + jmp addcharobj +]rts rts + +*------------------------------- +* +* A D D C H A R O B J +* +* Add a character to object table +* +* In: FCharVars +* A = object type +* +*------------------------------- +ADDCHAROBJ + ldx objX ;# objects already in list + inx + cpx #maxobj + bcs ]rts ;list full (shouldn't happen) + stx objX + + sta objTYP,x + + lda FCharX + sta XCO + lda FCharX+1 + sta OFFSET + + txa + pha + jsr cvtx ;from 280-res to byte/offset + pla + tax + + lda XCO + sta objX,x + lda OFFSET + sta objOFF,x + + lda FCharY + sta objY,x + + lda FCharCU + sta objCU,x + lda FCharCL + sta objCL,x + lda FCharCR + sta objCR,x + lda FCharCD + sta objCD,x + + lda FCharImage + sta objIMG,x + + lda FCharTable + sta objTAB,x + + lda FCharFace + sta objFACE,x + + jmp SETOBJINDX + +*------------------------------- +* +* S E T O B J I N D X +* +* Set object index +* +*------------------------------- +SETOBJINDX + lda FCharIndex + sta objINDX,x + + cmp #30 + bcs :os + + tax + + lda #1 + sta objbuf,x +:os + rts + +*------------------------------- +* +* Text routines +* +* NOTE: These routines bypass normal data structures +* & write directly to hi-res page. +* +* Call at end of DRAWALL to make sure text goes on top +* of everything else. +* +*------------------------------- +* +* Call once before using other text routines +* +*------------------------------- +pretext + jsr initlay + + lda #bgtable2 + sta TABLE + lda #>bgtable2 + sta TABLE+1 + rts + +*------------------------------- +* Part of "Yellow" copy-protection + +SETRECHECK0 + lda #recheck0 + sta locals + lda #>recheck0 + sta locals+1 ;fall thru (& return A = 0) + +*------------------------------- +INITLAY + lda #3 ;auxmem + sta BANK + + lda #40 + sta RIGHTCUT + lda #192 + sta BOTCUT ;use full screen + lda #0 + sta LEFTCUT + sta TOPCUT + rts + +*------------------------------- +* +* Print character +* +* In: PAGE, XCO/OFFSET, YCO +* a = ASCII value of character +* Out: XCO/OFFSET (modified) +* +*------------------------------- +prchar + sec + sbc #"/" ;"0" = 1 + sta IMAGE + + lda #ora + sta OPACITY + + jsr lay + + inc XCO + rts + +*------------------------------- + lst + ds 1 + usr $a9,17,$00,*-org + lst off diff --git a/01 POP Source/Source/GAMEEQ.S b/01 POP Source/Source/GAMEEQ.S index caae035..88809c2 100755 --- a/01 POP Source/Source/GAMEEQ.S +++ b/01 POP Source/Source/GAMEEQ.S @@ -1 +1,673 @@ - tr on lst off * gameeq *------------------------------- * * Equates * *------------------------------- chtable1 = $6000 chtable2 = $8400 chtable3 = $0800 chtable4 = $9600 chtable5 = $a800 chtable6 = $6000 chtable7 = $9f00 bgtable1 = $6000 bgtable2 = $8400 topctrl = $2000 seqtable = $2800 seqtab = $3000 ctrl = $3a00 coll = $4500 gamebg = $4c00 auto = $5400 mobtables = $b600 savedgame = $b6f0 msys = $d400 ctrlsubs = $d000 specialk = $d900 textline = $dfd8 subs = $e000 sound = $ea00 mover = $ee00 misc = $f900 debugs = $fc00 *------------------------------- * * Jump tables * *------------------------------- dum mobtables trobspace = $20 mobspace = $10 maxsfx = $20 trloc ds trobspace trscrn ds trobspace trdirec ds trobspace mobx ds mobspace moby ds mobspace mobscrn ds mobspace mobvel ds mobspace mobtype ds mobspace moblevel ds mobspace soundtable ds maxsfx trobcount ds 1 dum savedgame SavLevel ds 1 SavStrength ds 1 SavMaxed ds 1 SavTimer ds 2 ds 1 SavNextMsg ds 1 dum topctrl start ds 3 restart ds 3 startresume ds 3 initsystem ds 3 ds 3 docrosscut ds 3 goattract ds 3 dum ctrl PlayerCtrl ds 3 checkfloor ds 3 ShadCtrl ds 3 rereadblocks ds 3 checkpress ds 3 DoImpale ds 3 GenCtrl ds 3 checkimpale ds 3 dum auto AutoCtrl ds 3 checkstrike ds 3 checkstab ds 3 AutoPlayback ds 3 cutcheck ds 3 cutguard ds 3 addguard ds 3 cut ds 3 dum coll checkbarr ds 3 collisions ds 3 getfwddist ds 3 checkcoll ds 3 animchar ds 3 checkslice ds 3 checkslice2 ds 3 ds 3 checkgate ds 3 ds 3 enemycoll ds 3 dum gamebg updatemeters ds 3 DrawKidMeter ds 3 DrawSword ds 3 DrawKid ds 3 DrawShad ds 3 setupflame ds 3 continuemsg ds 3 addcharobj ds 3 setobjindx ds 3 printlevel ds 3 DrawOppMeter ds 3 flipdiskmsg ds 3 timeleftmsg ds 3 DrawGuard ds 3 DrawGuard2 ds 3 setupflask ds 3 setupcomix ds 3 psetupflame ds 3 drawpost ds 3 drawglass ds 3 initlay ds 3 twinkle ds 3 flow ds 3 pmask ds 3 yellow ds 3 setrecheck0 ds 3 recheckyel ds 3 dum specialk keys ds 3 clrjstk ds 3 zerosound ds 3 addsound ds 3 facejstk ds 3 SaveSelect ds 3 LoadSelect ds 3 SaveDesel ds 3 LoadDesel ds 3 initinput ds 3 demokeys ds 3 listtorches ds 3 burn ds 3 getminleft ds 3 keeptime ds 3 shortentime ds 3 cuesong ds 3 ds 3 ds 3 ds 3 dloop ds 3 strobe ds 3 dum mover animtrans ds 3 trigspikes ds 3 pushpp ds 3 breakloose1 ds 3 breakloose ds 3 animmobs ds 3 addmobs ds 3 closeexit ds 3 getspikes ds 3 shakem ds 3 trigslicer ds 3 trigtorch ds 3 getflameframe ds 3 smashmirror ds 3 jamspikes ds 3 trigflask ds 3 getflaskframe ds 3 trigsword ds 3 jampp ds 3 dum ctrlsubs getframe ds 3 getseq ds 3 getbasex ds 3 getblockx ds 3 getblockxp ds 3 getblocky ds 3 getblockej ds 3 addcharx ds 3 getdist ds 3 getdist1 ds 3 getabovebeh ds 3 rdblock ds 3 rdblock1 ds 3 setupsword ds 3 getscrns ds 3 addguardobj ds 3 opjumpseq ds 3 getedges ds 3 indexchar ds 3 quickfg ds 3 cropchar ds 3 getleft ds 3 getright ds 3 getup ds 3 getdown ds 3 cmpspace ds 3 cmpbarr ds 3 addkidobj ds 3 addshadobj ds 3 addreflobj ds 3 LoadKid ds 3 LoadShad ds 3 SaveKid ds 3 SaveShad ds 3 setupchar ds 3 GetFrameInfo ds 3 indexblock ds 3 markred ds 3 markfred ds 3 markwipe ds 3 markmove ds 3 markfloor ds 3 unindex ds 3 quickfloor ds 3 unevenfloor ds 3 markhalf ds 3 addswordobj ds 3 getblocky1 ds 3 checkledge ds 3 get2infront ds 3 checkspikes ds 3 rechargemeter ds 3 addfcharx ds 3 facedx ds 3 jumpseq ds 3 GetBaseBlock ds 3 LoadKidwOp ds 3 SaveKidwOp ds 3 getopdist ds 3 LoadShadwOp ds 3 SaveShadwOp ds 3 boostmeter ds 3 getunderft ds 3 getinfront ds 3 getbehind ds 3 getabove ds 3 getaboveinf ds 3 cmpwall ds 3 dum subs addtorches ds 3 doflashon ds 3 PageFlip ds 3 demo ds 3 showtime ds 3 doflashoff ds 3 lrclse ds 3 ds 3 ds 3 ds 3 addslicers ds 3 pause ds 3 ds 3 deadenemy ds 3 playcut ds 3 addlowersound ds 3 RemoveObj ds 3 addfall ds 3 setinitials ds 3 startkid ds 3 startkid1 ds 3 gravity ds 3 initialguards ds 3 mirappear ds 3 crumble ds 3 dum sound playback ds 3 dum msys _minit ds 3 _mplay ds 3 dum seqtable Fdef ds 1200 altset1 ds 200 altset2 ds 450 swordtab ds 192 dum misc VanishChar ds 3 movemusic ds 3 moveauxlc ds 3 firstguard ds 3 markmeters ds 3 potioneffect ds 3 mouserescue ds 3 StabChar ds 3 unholy ds 3 reflection ds 3 MarkKidMeter ds 3 MarkOppMeter ds 3 bonesrise ds 3 decstr ds 3 DoSaveGame ds 3 LoadLevelX ds 3 checkalert ds 3 dispversion ds 3 dum debugs showpage ds 3 debugkeys ds 3 ds 3 titlescreen ds 3 *------------------------------- * * Zero page * *------------------------------- locals = $e8 *------------------------------- * $40-e7: Game globals *------------------------------- dum $40 Char ds $10 Kid ds $10 Shad ds $10 FCharVars ds 12 yellowflag ds 1 timebomb ds 1 justblocked ds 1 gdtimer ds 1 framepoint ds 2 Fimage ds 1 Fdx ds 1 Fdy ds 1 Fcheck ds 1 exitopen ds 1 collX ds 1 lightning ds 1 lightcolor ds 1 offguard ds 1 blockid ds 1 blockx ds 1 blocky ds 1 infrontx ds 1 behindx ds 1 abovey ds 1 tempblockx ds 1 tempblocky ds 1 tempscrn ds 1 tempid ds 1 numtrans ds 1 tempnt ds 1 redrawflg ds 1 xdiff ds 2 ydiff ds 2 xdir ds 1 ydir ds 1 RNDseed ds 1 invert ds 1 PlayCount ds 1 refract ds 1 backtolife ds 1 cutplan ds 1 lastcmd ds 1 distfallen ds 1 cutscrn ds 1 waitingtojump ds 1 trigppabove ds 1 direcpp ds 1 blockaddr ds 2 delay ds 1 XCOORD ds 2 savekidx ds 1 mirrx ds 1 dmirr ds 1 barrdist ds 1 barrcode ds 1 imwidth ds 1 imheight ds 1 leadedge ds 1 leftej ds 1 rightej ds 1 topej ds 1 leftblock ds 1 rightblock ds 1 topblock ds 1 bottomblock ds 1 CDLeftEj ds 1 CDRightEj ds 1 endrange ds 1 bufindex ds 1 blockedge ds 1 collideL ds 1 collideR ds 1 weightless ds 1 cutorder ds 1 AMtimer ds 1 begrange ds 1 scrn ds 1 keybufptr ds 1 VisScrn ds 1 OppStrength ds 1 jarabove ds 1 KidStrength ds 1 ChgKidStr ds 1 MaxKidStr ds 1 EnemyAlert ds 1 ChgOppStr ds 1 heroic ds 1 clrF ds 1 clrB ds 1 clrU ds 1 clrD ds 1 clrbtn ds 1 Fsword ds 1 purpleflag ds 1 ;$da msgtimer ds 1 MaxOppStr ds 1 guardprog ds 1 ManCtrl ds 1 mergetimer ds 1 lastpotion ds 1 origstrength ds 1 jmpaddr ds 2 alertguard ds 1 createshad ds 1 stunned ds 1 droppedout ds 1 *------------------------------- * * Page 2-3 * *------------------------------- dum $212 milestone ds 1 GlassState ds 1 redrawglass ds 1 doortop ds 1 GuardColor ds 1 shadowaction ds 1 skipmessage ds 1 savezp ds 32 MSset ds 1 rjumpflag ds 1 redherring ds 1 dum $300 MinLeft ds 1 NextTimeMsg ds 1 SecLeft ds 1 BGset1 ds 1 BGset2 ds 1 CHset ds 1 FrameCount ds 2 SongCount ds 1 PreRecPtr ds 1 gotsword ds 1 message ds 1 SPEED ds 1 nummob ds 1 clrSEL ds 5 clrDESEL ds 5 vibes ds 1 SongCue ds 1 musicon ds 1 redkidmeter ds 1 NextLevel ds 1 scrncolor ds 1 redoppmeter ds 1 timerequest ds 1 dum $320 CDthisframe ds $10 CDlastframe ds $10 CDbelow ds $10 CDabove ds $10 SNthisframe ds $10 SNlastframe ds $10 SNbelow ds $10 SNabove ds 10 BlockYthis ds 1 BlockYlast ds 1 Op ds $10 keybuflen = 10 keybuf ds keybuflen *------------------------------- * * Character data * *------------------------------- dum Char CharPosn ds 1 CharX ds 1 CharY ds 1 CharFace ds 1 CharBlockX ds 1 CharBlockY ds 1 CharAction ds 1 CharXVel ds 1 CharYVel ds 1 CharSeq ds 2 CharScrn ds 1 CharRepeat ds 1 CharID ds 1 CharSword ds 1 CharLife ds 1 dum Op OpPosn ds 1 OpX ds 1 OpY ds 1 OpFace ds 1 OpBlockX ds 1 OpBlockY ds 1 OpAction ds 1 OpXVel ds 1 OpYVel ds 1 OpSeq ds 2 OpScrn ds 1 OpRepeat ds 1 OpID ds 1 OpSword ds 1 OpLife ds 1 dum Kid KidPosn ds 1 KidX ds 1 KidY ds 1 KidFace ds 1 KidBlockX ds 1 KidBlockY ds 1 KidAction ds 1 KidXVel ds 1 KidYVel ds 1 KidSeq ds 2 KidScrn ds 1 KidRepeat ds 1 KidID ds 1 KidSword ds 1 KidLife ds 1 dum Shad ShadPosn ds 1 ShadX ds 1 ShadY ds 1 ShadFace ds 1 ShadBlockX ds 1 ShadBlockY ds 1 ShadAction ds 1 ShadXVel ds 1 ShadYVel ds 1 ShadSeq ds 2 ShadScrn ds 1 ShadRepeat ds 1 ShadID ds 1 ShadSword ds 1 ShadLife ds 1 dum FCharVars FCharImage ds 1 FCharX ds 2 FCharY ds 1 FCharFace ds 1 FCharIndex ds 1 FCharCU ds 1 FCharCD ds 1 FCharCL ds 1 FCharCR ds 1 FCharTable ds 1 dend *------------------------------- * * Misc. data * *------------------------------- Fcheckmark = %01000000 Fthinmark = %00100000 Ffootmark = %00011111 floorheight = 15 angle = 7 VertDist = 11 UseFastlay = 0 UseLay = 1 UseLayrsave = 2 TypeKid = 0 TypeShad = 1 TypeGd = 2 TypeSword = 3 TypeReflect = 4 TypeComix = 5 TypeFF = $80 lst off \ No newline at end of file + tr on + lst off +* gameeq +*------------------------------- +* +* Equates +* +*------------------------------- +chtable1 = $6000 +chtable2 = $8400 +chtable3 = $0800 +chtable4 = $9600 +chtable5 = $a800 +chtable6 = $6000 +chtable7 = $9f00 + +bgtable1 = $6000 +bgtable2 = $8400 + +topctrl = $2000 +seqtable = $2800 +seqtab = $3000 +ctrl = $3a00 +coll = $4500 +gamebg = $4c00 +auto = $5400 + +mobtables = $b600 +savedgame = $b6f0 + +msys = $d400 +ctrlsubs = $d000 +specialk = $d900 +textline = $dfd8 +subs = $e000 +sound = $ea00 +mover = $ee00 +misc = $f900 +debugs = $fc00 + +*------------------------------- +* +* Jump tables +* +*------------------------------- + dum mobtables + +trobspace = $20 +mobspace = $10 +maxsfx = $20 + +trloc ds trobspace +trscrn ds trobspace +trdirec ds trobspace + +mobx ds mobspace +moby ds mobspace +mobscrn ds mobspace +mobvel ds mobspace +mobtype ds mobspace +moblevel ds mobspace + +soundtable ds maxsfx + +trobcount ds 1 + + dum savedgame + +SavLevel ds 1 +SavStrength ds 1 +SavMaxed ds 1 +SavTimer ds 2 + ds 1 +SavNextMsg ds 1 + + dum topctrl + +start ds 3 +restart ds 3 +startresume ds 3 +initsystem ds 3 + ds 3 + +docrosscut ds 3 +goattract ds 3 + + dum ctrl + +PlayerCtrl ds 3 +checkfloor ds 3 +ShadCtrl ds 3 +rereadblocks ds 3 +checkpress ds 3 + +DoImpale ds 3 +GenCtrl ds 3 +checkimpale ds 3 + + dum auto + +AutoCtrl ds 3 +checkstrike ds 3 +checkstab ds 3 +AutoPlayback ds 3 +cutcheck ds 3 + +cutguard ds 3 +addguard ds 3 +cut ds 3 + + dum coll + +checkbarr ds 3 +collisions ds 3 +getfwddist ds 3 +checkcoll ds 3 +animchar ds 3 + +checkslice ds 3 +checkslice2 ds 3 + ds 3 +checkgate ds 3 + ds 3 + +enemycoll ds 3 + + dum gamebg + +updatemeters ds 3 +DrawKidMeter ds 3 +DrawSword ds 3 +DrawKid ds 3 +DrawShad ds 3 + +setupflame ds 3 +continuemsg ds 3 +addcharobj ds 3 +setobjindx ds 3 +printlevel ds 3 + +DrawOppMeter ds 3 +flipdiskmsg ds 3 +timeleftmsg ds 3 +DrawGuard ds 3 +DrawGuard2 ds 3 + +setupflask ds 3 +setupcomix ds 3 +psetupflame ds 3 +drawpost ds 3 +drawglass ds 3 + +initlay ds 3 +twinkle ds 3 +flow ds 3 +pmask ds 3 +yellow ds 3 + +setrecheck0 ds 3 +recheckyel ds 3 + + dum specialk + +keys ds 3 +clrjstk ds 3 +zerosound ds 3 +addsound ds 3 +facejstk ds 3 + +SaveSelect ds 3 +LoadSelect ds 3 +SaveDesel ds 3 +LoadDesel ds 3 +initinput ds 3 + +demokeys ds 3 +listtorches ds 3 +burn ds 3 +getminleft ds 3 +keeptime ds 3 + +shortentime ds 3 +cuesong ds 3 + ds 3 + ds 3 + ds 3 + +dloop ds 3 +strobe ds 3 + + dum mover + +animtrans ds 3 +trigspikes ds 3 +pushpp ds 3 +breakloose1 ds 3 +breakloose ds 3 + +animmobs ds 3 +addmobs ds 3 +closeexit ds 3 +getspikes ds 3 +shakem ds 3 + +trigslicer ds 3 +trigtorch ds 3 +getflameframe ds 3 +smashmirror ds 3 +jamspikes ds 3 + +trigflask ds 3 +getflaskframe ds 3 +trigsword ds 3 +jampp ds 3 + + dum ctrlsubs + +getframe ds 3 +getseq ds 3 +getbasex ds 3 +getblockx ds 3 +getblockxp ds 3 + +getblocky ds 3 +getblockej ds 3 +addcharx ds 3 +getdist ds 3 +getdist1 ds 3 + +getabovebeh ds 3 +rdblock ds 3 +rdblock1 ds 3 +setupsword ds 3 +getscrns ds 3 + +addguardobj ds 3 +opjumpseq ds 3 +getedges ds 3 +indexchar ds 3 +quickfg ds 3 + +cropchar ds 3 +getleft ds 3 +getright ds 3 +getup ds 3 +getdown ds 3 + +cmpspace ds 3 +cmpbarr ds 3 +addkidobj ds 3 +addshadobj ds 3 +addreflobj ds 3 + +LoadKid ds 3 +LoadShad ds 3 +SaveKid ds 3 +SaveShad ds 3 +setupchar ds 3 + +GetFrameInfo ds 3 +indexblock ds 3 +markred ds 3 +markfred ds 3 +markwipe ds 3 + +markmove ds 3 +markfloor ds 3 +unindex ds 3 +quickfloor ds 3 +unevenfloor ds 3 + +markhalf ds 3 +addswordobj ds 3 +getblocky1 ds 3 +checkledge ds 3 +get2infront ds 3 + +checkspikes ds 3 +rechargemeter ds 3 +addfcharx ds 3 +facedx ds 3 +jumpseq ds 3 + +GetBaseBlock ds 3 +LoadKidwOp ds 3 +SaveKidwOp ds 3 +getopdist ds 3 +LoadShadwOp ds 3 + +SaveShadwOp ds 3 +boostmeter ds 3 +getunderft ds 3 +getinfront ds 3 +getbehind ds 3 + +getabove ds 3 +getaboveinf ds 3 +cmpwall ds 3 + + dum subs + +addtorches ds 3 +doflashon ds 3 +PageFlip ds 3 +demo ds 3 +showtime ds 3 + +doflashoff ds 3 +lrclse ds 3 + ds 3 + ds 3 + ds 3 + +addslicers ds 3 +pause ds 3 + ds 3 +deadenemy ds 3 +playcut ds 3 + +addlowersound ds 3 +RemoveObj ds 3 +addfall ds 3 +setinitials ds 3 +startkid ds 3 + +startkid1 ds 3 +gravity ds 3 +initialguards ds 3 +mirappear ds 3 +crumble ds 3 + + dum sound + +playback ds 3 + + dum msys + +_minit ds 3 +_mplay ds 3 + + dum seqtable + +Fdef ds 1200 +altset1 ds 200 +altset2 ds 450 +swordtab ds 192 + + dum misc + +VanishChar ds 3 +movemusic ds 3 +moveauxlc ds 3 +firstguard ds 3 +markmeters ds 3 + +potioneffect ds 3 +mouserescue ds 3 +StabChar ds 3 +unholy ds 3 +reflection ds 3 + +MarkKidMeter ds 3 +MarkOppMeter ds 3 +bonesrise ds 3 +decstr ds 3 +DoSaveGame ds 3 + +LoadLevelX ds 3 +checkalert ds 3 +dispversion ds 3 + + dum debugs + +showpage ds 3 +debugkeys ds 3 + ds 3 +titlescreen ds 3 + +*------------------------------- +* +* Zero page +* +*------------------------------- +locals = $e8 + +*------------------------------- +* $40-e7: Game globals +*------------------------------- + dum $40 + +Char ds $10 +Kid ds $10 +Shad ds $10 +FCharVars ds 12 +yellowflag ds 1 +timebomb ds 1 +justblocked ds 1 +gdtimer ds 1 +framepoint ds 2 +Fimage ds 1 +Fdx ds 1 +Fdy ds 1 +Fcheck ds 1 +exitopen ds 1 +collX ds 1 +lightning ds 1 +lightcolor ds 1 +offguard ds 1 +blockid ds 1 +blockx ds 1 +blocky ds 1 +infrontx ds 1 +behindx ds 1 +abovey ds 1 +tempblockx ds 1 +tempblocky ds 1 +tempscrn ds 1 +tempid ds 1 +numtrans ds 1 +tempnt ds 1 +redrawflg ds 1 +xdiff ds 2 +ydiff ds 2 +xdir ds 1 +ydir ds 1 +RNDseed ds 1 +invert ds 1 +PlayCount ds 1 +refract ds 1 +backtolife ds 1 +cutplan ds 1 +lastcmd ds 1 +distfallen ds 1 +cutscrn ds 1 +waitingtojump ds 1 +trigppabove ds 1 +direcpp ds 1 +blockaddr ds 2 +delay ds 1 +XCOORD ds 2 +savekidx ds 1 +mirrx ds 1 +dmirr ds 1 +barrdist ds 1 +barrcode ds 1 +imwidth ds 1 +imheight ds 1 +leadedge ds 1 +leftej ds 1 +rightej ds 1 +topej ds 1 +leftblock ds 1 +rightblock ds 1 +topblock ds 1 +bottomblock ds 1 +CDLeftEj ds 1 +CDRightEj ds 1 +endrange ds 1 +bufindex ds 1 +blockedge ds 1 +collideL ds 1 +collideR ds 1 +weightless ds 1 +cutorder ds 1 +AMtimer ds 1 +begrange ds 1 +scrn ds 1 +keybufptr ds 1 +VisScrn ds 1 +OppStrength ds 1 +jarabove ds 1 +KidStrength ds 1 +ChgKidStr ds 1 +MaxKidStr ds 1 +EnemyAlert ds 1 +ChgOppStr ds 1 +heroic ds 1 +clrF ds 1 +clrB ds 1 +clrU ds 1 +clrD ds 1 +clrbtn ds 1 +Fsword ds 1 +purpleflag ds 1 ;$da +msgtimer ds 1 +MaxOppStr ds 1 +guardprog ds 1 +ManCtrl ds 1 +mergetimer ds 1 +lastpotion ds 1 +origstrength ds 1 +jmpaddr ds 2 +alertguard ds 1 +createshad ds 1 +stunned ds 1 +droppedout ds 1 + +*------------------------------- +* +* Page 2-3 +* +*------------------------------- + dum $212 + +milestone ds 1 +GlassState ds 1 +redrawglass ds 1 +doortop ds 1 +GuardColor ds 1 +shadowaction ds 1 +skipmessage ds 1 +savezp ds 32 +MSset ds 1 +rjumpflag ds 1 +redherring ds 1 + + dum $300 + +MinLeft ds 1 +NextTimeMsg ds 1 +SecLeft ds 1 +BGset1 ds 1 +BGset2 ds 1 +CHset ds 1 +FrameCount ds 2 +SongCount ds 1 +PreRecPtr ds 1 +gotsword ds 1 +message ds 1 +SPEED ds 1 +nummob ds 1 +clrSEL ds 5 +clrDESEL ds 5 +vibes ds 1 +SongCue ds 1 +musicon ds 1 +redkidmeter ds 1 +NextLevel ds 1 +scrncolor ds 1 +redoppmeter ds 1 +timerequest ds 1 + + dum $320 + +CDthisframe ds $10 +CDlastframe ds $10 +CDbelow ds $10 +CDabove ds $10 +SNthisframe ds $10 +SNlastframe ds $10 +SNbelow ds $10 +SNabove ds 10 +BlockYthis ds 1 +BlockYlast ds 1 + +Op ds $10 + +keybuflen = 10 +keybuf ds keybuflen + +*------------------------------- +* +* Character data +* +*------------------------------- + dum Char +CharPosn ds 1 +CharX ds 1 +CharY ds 1 +CharFace ds 1 +CharBlockX ds 1 +CharBlockY ds 1 +CharAction ds 1 +CharXVel ds 1 +CharYVel ds 1 +CharSeq ds 2 +CharScrn ds 1 +CharRepeat ds 1 +CharID ds 1 +CharSword ds 1 +CharLife ds 1 + + dum Op +OpPosn ds 1 +OpX ds 1 +OpY ds 1 +OpFace ds 1 +OpBlockX ds 1 +OpBlockY ds 1 +OpAction ds 1 +OpXVel ds 1 +OpYVel ds 1 +OpSeq ds 2 +OpScrn ds 1 +OpRepeat ds 1 +OpID ds 1 +OpSword ds 1 +OpLife ds 1 + + dum Kid +KidPosn ds 1 +KidX ds 1 +KidY ds 1 +KidFace ds 1 +KidBlockX ds 1 +KidBlockY ds 1 +KidAction ds 1 +KidXVel ds 1 +KidYVel ds 1 +KidSeq ds 2 +KidScrn ds 1 +KidRepeat ds 1 +KidID ds 1 +KidSword ds 1 +KidLife ds 1 + + dum Shad +ShadPosn ds 1 +ShadX ds 1 +ShadY ds 1 +ShadFace ds 1 +ShadBlockX ds 1 +ShadBlockY ds 1 +ShadAction ds 1 +ShadXVel ds 1 +ShadYVel ds 1 +ShadSeq ds 2 +ShadScrn ds 1 +ShadRepeat ds 1 +ShadID ds 1 +ShadSword ds 1 +ShadLife ds 1 + + dum FCharVars +FCharImage ds 1 +FCharX ds 2 +FCharY ds 1 +FCharFace ds 1 +FCharIndex ds 1 +FCharCU ds 1 +FCharCD ds 1 +FCharCL ds 1 +FCharCR ds 1 +FCharTable ds 1 + + dend + +*------------------------------- +* +* Misc. data +* +*------------------------------- +Fcheckmark = %01000000 +Fthinmark = %00100000 +Ffootmark = %00011111 + +floorheight = 15 +angle = 7 +VertDist = 11 + +UseFastlay = 0 +UseLay = 1 +UseLayrsave = 2 + +TypeKid = 0 +TypeShad = 1 +TypeGd = 2 +TypeSword = 3 +TypeReflect = 4 +TypeComix = 5 +TypeFF = $80 + + lst off diff --git a/01 POP Source/Source/GRAFIX.S b/01 POP Source/Source/GRAFIX.S index 1647e6a..ea28bb3 100755 --- a/01 POP Source/Source/GRAFIX.S +++ b/01 POP Source/Source/GRAFIX.S @@ -1 +1,2131 @@ -* 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 \ No newline at end of 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 diff --git a/01 POP Source/Source/HIRES.S b/01 POP Source/Source/HIRES.S index 6c1537b..3df79f9 100755 --- a/01 POP Source/Source/HIRES.S +++ b/01 POP Source/Source/HIRES.S @@ -1 +1,2130 @@ -* hires org = $ee00 tr on lst off *------------------------------- * * PRINCE OF PERSIA * Copyright 1989 Jordan Mechner * *------------------------------- org org jmp boot3 jmp cls jmp lay jmp fastlay jmp layrsave jmp lrcls jmp fastmask jmp fastblack jmp peel jmp getwidth jmp copyscrnMM jmp copyscrnAA jmp SETFASTAUX jmp SETFASTMAIN jmp copyscrnMA jmp copyscrnAM jmp INVERTY *------------------------------- put hrparams *------------------------------- boot3 = $f880 ;stage 3 boot peelbuf1 = $d000 peelbuf2 = $d600 * Local vars locals = $f0 locals2 = $18 dum locals BASE ds 2 IMSAVE ds 2 XSAVE ds 1 YSAVE ds 1 WIDTH ds 1 HEIGHT ds 1 TOPEDGE ds 1 OFFLEFT ds 1 OFFRIGHT ds 1 YREG ds 1 CARRY ds 1 dum locals2 index ztemp AMASK ds 1 BMASK ds 1 VISWIDTH ds 1 RMOST ds 1 carryim ds 1 imbyte ds 1 dend * OPACITY codes and = 0 ora = 1 sta = 2 eor = 3 ;OR/shift/XOR mask = 4 ;mask/OR *------------------------------- * * Assume hires routines are called from auxmem * (Exit with RAMRD, RAMWRT, ALTZP on) * *------------------------------- cls jsr mainmem jsr CLS jmp auxmem lay jsr mainmem jsr LAY jmp auxmem fastlay jsr FASTLAY jmp auxmem layrsave jsr mainmem jsr LAYRSAVE jmp auxmem lrcls jsr mainmem jsr LRCLS jmp auxmem fastmask jsr FASTMASK jmp auxmem fastblack jsr mainmem jsr FASTBLACK jmp auxmem peel jsr PEEL jmp auxmem getwidth jsr mainmem jsr GETWIDTH jmp auxmem copyscrnMM jsr mainmem ;r/w main ]copyscrn jsr COPYSCRN jmp auxmem copyscrnAA jsr auxmem ;r/w aux jmp ]copyscrn copyscrnMA sta $c002 ;read main sta $c005 ;write aux jmp ]copyscrn copyscrnAM sta $c003 ;read aux sta $c004 ;write main jmp ]copyscrn *------------------------------- mainmem sta $c004 ;RAMWRT off sta $c002 ;RAMRD off rts auxmem sta $c005 ;RAMWRT on sta $c003 ;RAMRD on rts *------------------------------- * * Parameters passed to hires routines: * * PAGE $00 = hires page 1, $20 = hires page 2 * XCO Screen X-coord (0=left, 39=right) * YCO Screen Y-coord (0=top, 191=bottom) * OFFSET # of bits to shift image right (0-6) * IMAGE Image # in table (1-127) * TABLE Starting address of image table (2 bytes) * BANK Memory bank of table (2 = main, 3 = aux) * OPACITY Bits 0-6: * 0 AND * 1 OR * 2 STA * 3 special XOR (OR/shift/XOR) * 4 mask/OR * Bit 7: 0 = normal, 1 = mirror * LEFTCUT Left edge of usable screen area * (0 for full screen) * RIGHTCUT Right edge +1 of usable screen area * (40 for full screen) * TOPCUT Top edge of usable screen area * (0 for full screen) * BOTCUT Bottom edge +1 of usable screen area * (192 for full screen) * *------------------------------- * * Image table format: * * Byte 0: width (# of bytes) * Byte 1: height (# of lines) * Byte 2-n: image bytes (read left-right, top-bottom) * *------------------------------- * * To preserve the background behind an animated character, * call LAYERSAVE before LAYing down each character image. * Afterwards, call PEEL to "peel off" the character & * restore the original background. * * Peel buffer stores background images sequentially, in * normal image table format, & is cleared after every frame. * *------------------------------- * * C L S * * Clear hi-res screen to black2 * *------------------------------- CLS lda PAGE ;00 = page 1; 20 = page 2 clc adc #$20 sta :loop+2 adc #$10 sta :smod+2 lda #$80 ;black2 ldx #$10 ldy #0 :loop sta $2000,y :smod sta $3000,y iny bne :loop inc :loop+2 inc :smod+2 dex bne :loop rts *------------------------------- * * L O - R E S C L S * * Clear lo-res/text screen (page 1) * * In: A = color * *------------------------------- LRCLS LDY #$F7 :2 STA $400,Y STA $500,Y STA $600,Y STA $700,Y DEY CPY #$7F BNE :3 LDY #$77 :3 CPY #$FF BNE :2 RTS *------------------------------- * * S E T I M A G E * * In: TABLE (2 bytes), IMAGE (image #) * Out: IMAGE = image start address (2 bytes) * *------------------------------- setimage lda IMAGE asl sec sbc #1 tay lda (TABLE),y sta IMAGE iny lda (TABLE),y sta IMAGE+1 rts *------------------------------- * * G E T W I D T H * * In: BANK, TABLE, IMAGE * Out: A = width, X = height * *------------------------------- GETWIDTH lda BANK sta :RAMRD+1 :RAMRD sta $c003 jsr setimage ldy #1 lda (IMAGE),y ;height tax dey lda (IMAGE),y ;width rts *------------------------------- * * P R E P R E P * * In: IMAGE, XCO, YCO * *------------------------------- PREPREP * Save IMAGE, XCO, YCO LDA IMAGE STA IMSAVE LDA XCO STA XSAVE LDA YCO STA YSAVE * Get image data start address lda BANK sta :RAMRD+1 :RAMRD sta $c003 jsr setimage * Read first two bytes (width, height) of image table LDY #0 LDA (IMAGE),Y STA WIDTH INY LDA (IMAGE),Y STA HEIGHT LDA IMAGE CLC ADC #2 STA IMAGE BCC :3 INC IMAGE+1 :3 sta $c002 ;RAMRD off (read mainmem) ]rts rts *------------------------------- * * C R O P * * In: Results of PREPREP (XCO, YCO, HEIGHT, WIDTH) * Screen area cutoffs (LEFTCUT, RIGHTCUT, TOPCUT, BOTCUT) * * Out: * * TOPEDGE Top line -1 * VISWIDTH Width, in bytes, of visible (onscreen) portion * of image * XCO X-coord of leftmost visible byte of image * (must be 0-39) * YCO Y-coord of lowest visible line of image * (must be 0-191) * OFFLEFT # of bytes off left edge * OFFRIGHT # of bytes off right edge (including carry byte) * RMOST # of bytes off right edge (excluding carry byte) * * Return - if entire image is offscreen, else + * *------------------------------- CROP * (1) Crop top & bottom lda YCO cmp BOTCUT bcs :botoff ;Bottom o.s. * Bottom is onscreen--check top sec sbc HEIGHT ;top line -1 cmp #191 bcc :topok ;Top is onscreen lda TOPCUT ;Top is offscreen sec sbc #1 sta TOPEDGE jmp :done :topok sta TOPEDGE ;Top line -1 (0-191) lda TOPCUT ;top line of image area (forced mask) beq :done ;no top cutoff sec sbc #1 cmp TOPEDGE bcc :done sta TOPEDGE bcs :done * Bottom is o.s.--advance IMAGE pointer past o.s. portion :botoff ;A = YCO sec sbc HEIGHT clc adc #1 ;top line cmp BOTCUT bcs :cancel ;Entire shape is o.s. sec sbc #1 sta TOPEDGE ;top line -1 ldx YCO :loop lda IMAGE clc adc WIDTH sta IMAGE bcc :1 inc IMAGE+1 :1 dex cpx BOTCUT bcs :loop stx YCO * (2) Crop sides :done lda XCO bmi :leftoff cmp LEFTCUT bcs :leftok ;XCO >= LEFTCUT * XCO < LEFTCUT: left edge is offscreen :leftoff lda LEFTCUT sec sbc XCO sta OFFLEFT ;Width of o.s. portion lda WIDTH sec sbc OFFLEFT bmi :cancel ;Entire image is o.s. -- skip it sta VISWIDTH ;Width of onscreen portion (can be 0) lda LEFTCUT sta XCO * Assume image is <=40 bytes wide --> right edge is onscreen lda #0 sta OFFRIGHT sta RMOST rts * Left edge is onscreen; what about right edge? :leftok ;A = XCO cmp RIGHTCUT ;normally 40 bcs :cancel ;Entire image is o.s. - skip it clc adc WIDTH ;rightmost byte +1 cmp RIGHTCUT bcc :bothok ;Entire image is onscreen sec sbc RIGHTCUT sta RMOST ;Width of o.s. portion clc adc #1 sta OFFRIGHT ;+1 lda RIGHTCUT sec sbc XCO sta VISWIDTH ;Width of onscreen portion lda #0 sta OFFLEFT rts :bothok lda WIDTH sta VISWIDTH lda #0 sta OFFLEFT sta OFFRIGHT sta RMOST rts :cancel lda #-1 ;Entire image is o.s. - skip it ]rts rts *------------------------------- * * Shift offset 1 bit right or left * (for special XOR) * * In/out: X = offset * *------------------------------- shiftoffset cpx #6 bcs :left inx rts :left dex ]rts rts *------------------------------- * * L A Y E R S A V E * * In: Same as for LAY, plus PEELBUF (2 bytes) * Out: PEELBUF (updated), PEELIMG (2 bytes), PEELXCO, PEELYCO * * PEELIMG is 2-byte pointer to beginning of image table. * (Hi byte = 0 means no image has been stored.) * * PEELBUF is 2-byte pointer to first available byte in * peel buffer. * *------------------------------- LAYRSAVE jsr PREPREP lda OPACITY bpl :normal LDA XCO SEC SBC WIDTH STA XCO :normal inc WIDTH ;extra byte to cover shift right jsr CROP bmi SKIPIT lda PEELBUF ;PEELBUF: 2-byte pointer to 1st sta PEELIMG ;available byte in peel buffer lda PEELBUF+1 sta PEELIMG+1 lda XCO sta PEELXCO sta :smXCO+1 lda YCO sta PEELYCO lda PAGE ;spend 7 cycles now -- sta :smPAGE+1 ;save 1 in loop ldy #0 lda VISWIDTH beq SKIPIT sta (PEELBUF),y sta :smWIDTH+1 sec sbc #1 sta :smSTART+1 * Continue :cont iny LDA YCO SEC SBC TOPEDGE STA (PEELBUF),y ;Height of onscreen portion ("VISHEIGHT") LDA PEELBUF CLC ADC #2 STA PEELBUF BCC :ok INC PEELBUF+1 :ok * Like FASTLAY in reverse ldx YCO :loop LDA YLO,X CLC :smXCO ADC #0 ;XCO STA :smBASE+1 LDA YHI,X :smPAGE ADC #0 ;PAGE STA :smBASE+2 :smSTART ldy #0 ;VISWIDTH-1 :inloop :smBASE lda $2000,y STA (PEELBUF),Y dey bpl :inloop :smWIDTH LDA #0 ;VISWIDTH ADC PEELBUF ;assume cc STA PEELBUF BCC :2 INC PEELBUF+1 :2 DEX CPX TOPEDGE BNE :loop JMP DONE SKIPIT lda #0 sta PEELIMG+1 ;signal that peelbuf is empty JMP DONE *------------------------------- * * L A Y * * General routine to lay down an image on hi-res screen * (Handles edge-clipping, bit-shifting, & mirroring) * * Calls one of the following routines: * * LayGen General (OR, AND, STA) * LayMask Mask & OR * LayXOR Special XOR * * Transfers control to MLAY if image is to be mirrored * *------------------------------- LAY lda OPACITY bpl :notmirr and #$7f sta OPACITY jmp MLAY :notmirr cmp #eor bne :1 jmp LayXOR :1 cmp #mask bcc :2 jmp LayMask :2 jmp LayGen *------------------------------- * * General (AND/OR/STORE) * *------------------------------- LayGen jsr PREPREP jsr CROP bpl :cont jmp DONE :cont lda BANK sta :RAMRD1+1 sta :RAMRD2+1 LDX OFFSET LDA SHIFTL,X STA :91+1 LDA SHIFTH,X STA :91+2 LDA CARRYL,X STA :90+1 STA :92+1 LDA CARRYH,X STA :90+2 STA :92+2 LDA AMASKS,X STA :AMASK+1 LDA BMASKS,X STA :BMASK+1 LDX OPACITY LDA OPCODE,X STA :80 STA :81 * Preparation completed -- Lay down shape LDY YCO :nextline LDA YLO,Y CLC ADC XCO STA BASE LDA YHI,Y ADC PAGE STA BASE+1 LDY OFFLEFT BEQ :2 * (a) Left edge of image is offscreen * Take initial carry byte from image table DEY :RAMRD1 sta $c003 ;aux/main lda (IMAGE),y sta $c002 ;main TAX :90 LDA $FFFF,X ;CARRYn STA CARRY LDA IMAGE CLC ADC OFFLEFT STA IMAGE BCC :1 INC IMAGE+1 :1 LDY #0 LDA VISWIDTH STA WIDTH BNE :3 BEQ :4 ;Zero width * (b) Left edge of image is onscreen * Take initial carry byte from screen :2 LDA (BASE),Y :AMASK AND #0 STA CARRY * Lay line down left-to-right fast as you can :3 :RAMRD2 sta $c003 ;aux/main lda (IMAGE),y sta $c002 ;main TAX :91 LDA $FFFF,X ;SHIFTn ORA CARRY ;Combine with carryover from previous byte :80 STA (BASE),Y ;STA/ORA/AND/EOR depending on OPACITY STA (BASE),Y :92 LDA $FFFF,X ;CARRYn STA CARRY ;Carry over to next byte INY CPY VISWIDTH BCC :3 * Extra byte on right (carryover) LDA OFFRIGHT BNE :5 ;Rightmost byte is offscreen :4 LDA (BASE),Y :BMASK AND #0 ORA CARRY :81 STA (BASE),Y STA (BASE),Y * Next line up :5 LDA WIDTH CLC ADC IMAGE STA IMAGE BCC :6 INC IMAGE+1 :6 DEC YCO LDY YCO CPY TOPEDGE BNE :nextline * Restore parameters DONE LDA IMSAVE STA IMAGE LDA XSAVE STA XCO LDA YSAVE STA YCO RTS *------------------------------- * * Mask, then OR * *------------------------------- ]done jmp DONE LayMask ldx OPACITY ;4 = mask, 5 = visible mask lda OPCODE,x ;4 = and, 5 = sta sta :masksm1 sta :masksm2 jsr PREPREP jsr CROP bmi ]done lda BANK sta :RAMRD1+1 sta :RAMRD2+1 LDX OFFSET LDA SHIFTL,X STA :91+1 sta :93+1 LDA SHIFTH,X STA :91+2 sta :93+2 LDA CARRYL,X STA :90+1 STA :92+1 sta :94+1 sta :96+1 LDA CARRYH,X STA :90+2 STA :92+2 sta :94+2 sta :96+2 LDA AMASKS,X STA :AMASK+1 LDA BMASKS,X STA :BMASK+1 LDY YCO :nextline LDA YLO,Y CLC ADC XCO STA BASE LDA YHI,Y ADC PAGE STA BASE+1 LDY OFFLEFT BEQ :2 * (a) Left edge of image is offscreen * Take initial carry byte from image table dey :RAMRD1 sta $c003 lda (IMAGE),y ; eor #$ff ;TEMP ; ora #$80 ;TEMP sta $c002 tax :96 lda $FFFF,x ;CARRYn sta carryim lda MASKTAB-$80,x tax :90 lda $FFFF,x ;CARRYn sta CARRY LDA IMAGE CLC ADC OFFLEFT STA IMAGE BCC :1 INC IMAGE+1 :1 ldy #0 LDA VISWIDTH STA WIDTH BNE :inloop BEQ :4 ;Zero width * (b) Left edge of image is onscreen * Take initial carry byte from screen :2 :AMASK lda #0 ;AMASK sta CARRY and (BASE),y sta carryim * Lay line down left-to-right fast as you can :inloop :RAMRD2 sta $c003 lda (IMAGE),y ; eor #$ff ;TEMP ; ora #$80 ;TEMP sta $c002 tax :93 lda $FFFF,x ;SHIFTn ora carryim sta imbyte ;shifted image byte :94 lda $FFFF,x ;CARRYn sta carryim lda MASKTAB-$80,x tax :91 lda $FFFF,x ;SHIFTn ora CARRY :masksm1 and (BASE),y ;AND with mask byte ora imbyte ;OR with original image byte sta (BASE),y :92 lda $FFFF,x ;CARRYn sta CARRY ;Carry over to next byte iny cpy VISWIDTH bcc :inloop * Extra byte on right (carryover) lda OFFRIGHT bne :5 ;Rightmost byte is offscreen :4 :BMASK lda #0 ;BMASK ora CARRY :masksm2 and (BASE),y ora carryim sta (BASE),y * Next line up :5 LDA WIDTH CLC ADC IMAGE STA IMAGE BCC :6 INC IMAGE+1 :6 DEC YCO LDY YCO CPY TOPEDGE beq :done jmp :nextline :done jmp DONE *------------------------------- * * Special XOR * * (OR, then shift 1 bit and XOR) * *------------------------------- LayXOR JSR PREPREP jsr CROP bpl :cont jmp DONE :cont lda BANK sta :RAMRD1+1 sta :RAMRD2+1 LDX OFFSET LDA SHIFTL,X STA :91+1 LDA SHIFTH,X STA :91+2 LDA CARRYL,X STA :90+1 STA :92+1 LDA CARRYH,X STA :90+2 STA :92+2 jsr shiftoffset ;shift 1 bit right lda SHIFTL,x sta :s1+1 lda SHIFTH,x sta :s1+2 lda CARRYL,x sta :c1+1 sta :c2+1 lda CARRYH,x sta :c1+2 sta :c2+2 LDA AMASKS,X STA :AMASK+1 * Omit opcode setting LDY YCO :0 LDA YLO,Y CLC ADC XCO STA BASE LDA YHI,Y ADC PAGE STA BASE+1 LDY OFFLEFT BEQ :2 * (a) Left edge offscreen * Take CARRY from off left edge DEY :RAMRD1 sta $c003 lda (IMAGE),y sta $c002 TAX :c2 lda $FFFF,x ;CARRYn+1 sta carryim :90 LDA $FFFF,X ;CARRYn STA CARRY LDA IMAGE CLC ADC OFFLEFT STA IMAGE BCC :1 INC IMAGE+1 :1 LDY #0 LDA VISWIDTH STA WIDTH BNE :inloop BEQ :4 ;Zero width * (b) Left edge onscreen * Start a new line at left edge :2 lda (BASE),y :AMASK and #0 ;AMASK sta CARRY lda #0 ;0 XOR X == X sta carryim * Lay line down left-to-right fast as you can :inloop :RAMRD2 sta $c003 lda (IMAGE),y sta $c002 tax :s1 lda $FFFF,x ;SHIFTn+1 ora carryim sta imbyte :c1 lda $FFFF,x ;CARRYn+1 sta carryim :91 lda $FFFF,x ;SHIFTn ora CARRY ;Combine with carryover from previous byte ora (BASE),y eor imbyte ora #$80 ;set hibit sta (BASE),y :92 LDA $FFFF,X ;CARRYn STA CARRY ;Carry over to next byte INY CPY VISWIDTH BCC :inloop * Extra byte on right (carryover) LDA OFFRIGHT BNE :5 ;Rightmost byte is offscreen :4 lda CARRY ;0's in unused part of byte ora (BASE),y eor carryim ora #$80 sta (BASE),y * Next line up :5 LDA WIDTH CLC ADC IMAGE STA IMAGE BCC :6 INC IMAGE+1 :6 DEC YCO LDY YCO CPY TOPEDGE beq :done jmp :0 * Restore parameters :done jmp DONE *------------------------------- * * M I R R O R L A Y * * Called by LAY * * Specified starting byte (XCO, YCO) is image's bottom * right corner, not bottom left; bytes are read off image * table R-L, T-B and mirrored before printing. * * In: A = OPACITY, sans bit 7 * *------------------------------- MLAY ;A = OPACITY cmp #eor bne :1 jmp MLayXOR :1 cmp #mask bcc :2 jmp MLayMask :2 jmp MLayGen *------------------------------- * * General (AND/OR/STORE) * *------------------------------- MLayGen JSR PREPREP LDA XCO SEC SBC WIDTH STA XCO jsr CROP bpl :cont jmp DONE :cont lda BANK sta :RAMRD1+1 sta :RAMRD2+1 LDX OFFSET LDA SHIFTL,X STA :91+1 LDA SHIFTH,X STA :91+2 LDA CARRYL,X STA :90+1 STA :92+1 LDA CARRYH,X STA :90+2 STA :92+2 LDA AMASKS,X STA AMASK LDA BMASKS,X STA BMASK LDX OPACITY LDA OPCODE,X STA :80 STA :81 * Lay on LDY YCO :0 LDA YLO,Y STA BASE LDA YHI,Y CLC ADC PAGE STA BASE+1 LDY OFFLEFT BEQ :2 * Take CARRY from off left edge LDY VISWIDTH :RAMRD1 sta $c003 lda (IMAGE),y sta $c002 TAX LDA MIRROR-$80,X TAX :90 LDA $FFFF,X ;CARRYn STA CARRY :1 DEY BPL :3 BMI :4 * Start a new line at left edge :2 LDY XCO LDA (BASE),Y AND AMASK STA CARRY LDY WIDTH DEY * Lay line down left-to-right fast as you can :3 STY YREG :RAMRD2 sta $c003 lda (IMAGE),y sta $c002 TAX LDA MIRROR-$80,X TAX :91 LDA $FFFF,X ;SHIFTn ORA CARRY ;Combine with carryover from previous byte LDY XCO :80 STA (BASE),Y ;STA/ORA/AND/EOR depending on OPACITY STA (BASE),Y :92 LDA $FFFF,X ;CARRYn STA CARRY ;Carry over to next byte INC BASE LDY YREG CPY RMOST BEQ :7 DEY BPL :3 * Extra byte on right (carryover) :7 LDA OFFRIGHT BNE :5 ;Rightmost byte is offscreen :4 LDY XCO LDA (BASE),Y AND BMASK ORA CARRY :81 STA (BASE),Y STA (BASE),Y * Next line up :5 LDA WIDTH CLC ADC IMAGE STA IMAGE BCC :6 INC IMAGE+1 :6 DEC YCO LDY YCO CPY TOPEDGE beq :done jmp :0 :done JMP DONE *------------------------------- * * Mask, then OR * *------------------------------- MLayMask ldx OPACITY ;4 = mask, 5 = visible mask lda OPCODE,x ;4 = and, 5 = sta sta :masksm1 sta :masksm2 JSR PREPREP LDA XCO SEC SBC WIDTH STA XCO jsr CROP bpl :cont jmp DONE :cont lda BANK sta :RAMRD1+1 sta :RAMRD2+1 LDX OFFSET LDA SHIFTL,X STA :91+1 sta :93+1 LDA SHIFTH,X STA :91+2 sta :93+2 LDA CARRYL,X STA :90+1 STA :92+1 sta :94+1 sta :96+1 LDA CARRYH,X STA :90+2 STA :92+2 sta :94+2 sta :96+2 LDA AMASKS,X STA :AMASK+1 LDA BMASKS,X STA :BMASK+1 * Lay on LDY YCO :0 LDA YLO,Y STA BASE LDA YHI,Y CLC ADC PAGE STA BASE+1 LDY OFFLEFT BEQ :2 * (a) Left edge offscreen * Take CARRY from off left edge LDY VISWIDTH :RAMRD1 sta $c003 lda (IMAGE),y ; eor #$ff ;TEMP ; ora #$80 ;TEMP sta $c002 TAX LDA MIRROR-$80,X TAX :96 lda $FFFF,x ;CARRYn sta carryim lda MASKTAB-$80,x tax :90 LDA $FFFF,X ;CARRYn STA CARRY :1 DEY BPL :3 BMI :4 * (b) Left edge onscreen * Start a new line at left edge :2 LDY XCO :AMASK lda #0 ;AMASK sta CARRY and (BASE),y sta carryim LDY WIDTH DEY * Lay line down left-to-right fast as you can :3 STY YREG :RAMRD2 sta $c003 lda (IMAGE),y ; eor #$ff ;TEMP ; ora #$80 ;TEMP sta $c002 TAX LDA MIRROR-$80,X TAX :93 lda $FFFF,x ;SHIFTn ora carryim sta imbyte :94 lda $FFFF,x ;CARRYn sta carryim lda MASKTAB-$80,x tax :91 LDA $FFFF,X ;SHIFTn ORA CARRY ;Combine with carryover from previous byte LDY XCO :masksm1 and (BASE),y ora imbyte STA (BASE),Y :92 LDA $FFFF,X ;CARRYn STA CARRY ;Carry over to next byte INC BASE LDY YREG CPY RMOST BEQ :7 DEY BPL :3 * Extra byte on right (carryover) :7 LDA OFFRIGHT BNE :5 ;Rightmost byte is offscreen :4 LDY XCO LDA (BASE),Y :BMASK AND #0 ;BMASK ORA CARRY :masksm2 and (BASE),y ora carryim STA (BASE),Y * Next line up :5 LDA WIDTH CLC ADC IMAGE STA IMAGE BCC :6 INC IMAGE+1 :6 DEC YCO LDY YCO CPY TOPEDGE beq :done jmp :0 :done jmp DONE *------------------------------- * * Special XOR * *------------------------------- MLayXOR JSR PREPREP LDA XCO SEC SBC WIDTH STA XCO jsr CROP bpl :cont jmp DONE :cont lda BANK sta :RAMRD1+1 sta :RAMRD2+1 LDX OFFSET LDA SHIFTL,X STA :91+1 LDA SHIFTH,X STA :91+2 LDA CARRYL,X STA :90+1 STA :92+1 LDA CARRYH,X STA :90+2 STA :92+2 jsr shiftoffset lda SHIFTL,x sta :s1+1 lda SHIFTH,x sta :s1+2 lda CARRYL,x sta :c1+1 sta :c2+1 lda CARRYH,x sta :c1+2 sta :c2+2 LDA AMASKS,X STA :AMASK+1 * Lay on LDY YCO :0 LDA YLO,Y STA BASE LDA YHI,Y CLC ADC PAGE STA BASE+1 LDY OFFLEFT BEQ :2 * (a) Left edge offscreen * Take CARRY from off left edge LDY VISWIDTH :RAMRD1 sta $c003 lda (IMAGE),y sta $c002 TAX LDA MIRROR-$80,X TAX :c2 lda $FFFF,x ;CARRYn+1 sta carryim :90 LDA $FFFF,X ;CARRYn STA CARRY :1 DEY BPL :3 BMI :4 * (b) Left edge onscreen * Start a new line at left edge :2 ldy XCO :AMASK lda #0 ;AMASK and (BASE),y sta CARRY lda #0 sta carryim LDY WIDTH DEY * Lay line down left-to-right fast as you can :3 STY YREG :RAMRD2 sta $c003 lda (IMAGE),y sta $c002 TAX LDA MIRROR-$80,X TAX :s1 lda $FFFF,x ;SHIFTn ora carryim sta imbyte :c1 lda $FFFF,x ;CARRYn sta carryim :91 LDA $FFFF,X ;SHIFTn ORA CARRY ;Combine with carryover from previous byte LDY XCO ora (BASE),y eor imbyte ora #$80 sta (BASE),Y :92 LDA $FFFF,X ;CARRYn STA CARRY ;Carry over to next byte INC BASE LDY YREG CPY RMOST BEQ :7 DEY BPL :3 * Extra byte on right (carryover) :7 LDA OFFRIGHT BNE :5 ;Rightmost byte is offscreen :4 LDY XCO lda CARRY ora (BASE),Y eor carryim ora #$80 STA (BASE),Y * Next line up :5 LDA WIDTH CLC ADC IMAGE STA IMAGE BCC :6 INC IMAGE+1 :6 DEC YCO LDY YCO CPY TOPEDGE beq :done jmp :0 :done JMP DONE *------------------------------- * * Peel * *------------------------------- PEEL sta $c004 ]ramrd1 sta $c003 jmp fastlaySTA *------------------------------- * * F A S T L A Y * * Streamlined LAY routine * * No offset - no clipping - no mirroring - no masking - * no EOR - trashes IMAGE - may crash if overtaxed - * but it's fast. * * 10/3/88: OK for images to protrude PARTLY off top * *------------------------------- FASTLAY sta $c004 ;RAMWRT main ]ramrd2 sta $c003 ;RAMRD aux jsr setimage ldx OPACITY ;hi bit off! cpx #sta beq fastlaySTA lda OPCODE,x sta :smod lda PAGE sta :smPAGE+1 lda XCO sta :smXCO+1 ldy #0 lda (IMAGE),y sta :smWIDTH+1 sec sbc #1 sta :smSTART+1 lda YCO tax iny sbc (IMAGE),y bcs :ok lda #-1 ;limited Y-clipping :ok sta :smTOP+1 lda IMAGE clc adc #2 sta IMAGE bcc :1 inc IMAGE+1 :1 :outloop lda YLO,x clc :smXCO adc #0 sta BASE lda YHI,x :smPAGE adc #$20 sta BASE+1 :smSTART ldy #3 :inloop ]ramrd3 sta $c003 ;RAMRD aux lda (IMAGE),y sta $c002 ;RAMRD main :smod ora (BASE),y sta (BASE),y dey bpl :inloop :smWIDTH lda #4 adc IMAGE ;assume cc sta IMAGE bcc :2 inc IMAGE+1 :2 dex :smTOP cpx #$ff bne :outloop rts *------------------------------- * * Still more streamlined version of FASTLAY (STA only) * *------------------------------- fastlaySTA lda PAGE sta :smPAGE+1 lda XCO sta :smXCO+1 ldy #0 lda (IMAGE),y sta :smWIDTH+1 sec sbc #1 sta :smSTART+1 lda YCO tax iny sbc (IMAGE),y bcs :ok lda #-1 ;limited Y-clipping :ok sta :smTOP+1 lda IMAGE clc adc #2 sta IMAGE bcc :1 inc IMAGE+1 :1 :outloop lda YLO,x clc :smXCO adc #0 sta :smod+1 lda YHI,x :smPAGE adc #$20 sta :smod+2 :smSTART ldy #3 :inloop lda (IMAGE),y :smod sta $2000,y ;BASE dey bpl :inloop :smWIDTH lda #4 adc IMAGE ;cc sta IMAGE bcc :2 inc IMAGE+1 :2 dex :smTOP cpx #$ff bne :outloop rts *------------------------------- * * F A S T M A S K * *------------------------------- FASTMASK sta $c004 ;RAMWRT main ]ramrd4 sta $c003 ;RAMRD aux jsr setimage lda PAGE sta :smPAGE+1 lda XCO sta :smXCO+1 ldy #0 lda (IMAGE),y sta :smWIDTH+1 sec sbc #1 sta :smSTART+1 lda YCO tax iny sbc (IMAGE),y bcs :ok lda #-1 ;limited Y-clipping :ok sta :smTOP+1 lda IMAGE clc adc #2 sta IMAGE bcc :1 inc IMAGE+1 :1 :outloop stx index lda YLO,x clc :smXCO adc #0 sta BASE lda YHI,x :smPAGE adc #$20 sta BASE+1 :smSTART ldy #3 :inloop ]ramrd5 sta $c003 ;RAMRD aux lda (IMAGE),y sta $c002 ;RAMRD main tax lda MASKTAB-$80,X and (BASE),Y sta (BASE),y dey bpl :inloop :smWIDTH lda #4 adc IMAGE ;cc sta IMAGE bcc :2 inc IMAGE+1 :2 ldx index dex :smTOP cpx #$ff bne :outloop rts *------------------------------- * * S E T F A S T M A I N / A U X * * Modify FASTLAY routines to expect image tables to * be in main/auxmem. SETFAST need be called only once * (e.g., when switching between game & builder). * *------------------------------- SETFASTMAIN lda #$02 ;RAMRD main ]setfast sta ]ramrd1+1 sta ]ramrd2+1 sta ]ramrd3+1 sta ]ramrd4+1 sta ]ramrd5+1 rts SETFASTAUX lda #$03 ;RAMRD aux bne ]setfast *------------------------------- * * F A S T B L A C K * * Wipe a rectangular area to black2 * * Width/height passed in IMAGE/IMAGE+1 * (width in bytes, height in pixels) * *------------------------------- FASTBLACK lda color sta :smCOLOR+1 lda PAGE sta :smPAGE+1 lda XCO sta :smXCO+1 lda width sec sbc #1 sta :smSTART+1 lda YCO tax sbc height ;cs sta :smTOP+1 :outloop lda YLO,x clc :smXCO adc #0 sta :smod+1 lda YHI,x :smPAGE adc #$20 sta :smod+2 :smCOLOR lda #$80 :smSTART ldy #3 :inloop :smod sta $2000,y ;BASE dey bpl :inloop dex :smTOP cpx #$ff bne :outloop rts *------------------------------- * * C O P Y S C R E E N * * Copy $2000 bytes * * In: IMAGE+1 = dest scrn, IMAGE = org scrn * (use hi byte of actual memory address) * *------------------------------- COPYSCRN lda IMAGE+1 sta :dst1+2 clc adc #$10 sta :dst2+2 lda IMAGE sta :org1+2 adc #$10 sta :org2+2 ldx #$10 ldy #0 :loop :org1 lda $2000,y :dst1 sta $4000,y :org2 lda $3000,y :dst2 sta $5000,y iny bne :loop inc :org1+2 inc :org2+2 inc :dst1+2 inc :dst2+2 dex bne :loop rts *------------------------------- * Invert Y-tables *------------------------------- INVERTY ldx #191 ;low line ldy #0 ;high line * Switch low & high lines :loop lda YLO,x pha lda YLO,y sta YLO,x pla sta YLO,y lda YHI,x pha lda YHI,y sta YHI,x pla sta YHI,y * Move 1 line closer to ctr dex iny cpy #96 bcc :loop ]rts rts *------------------------------- lst ds 1 usr $a9,1,$0000,*-org lst off \ No newline at end of file +* hires +org = $ee00 + tr on + lst off +*------------------------------- +* +* PRINCE OF PERSIA +* Copyright 1989 Jordan Mechner +* +*------------------------------- + org org + + jmp boot3 + jmp cls + jmp lay + jmp fastlay + jmp layrsave + + jmp lrcls + jmp fastmask + jmp fastblack + jmp peel + jmp getwidth + + jmp copyscrnMM + jmp copyscrnAA + jmp SETFASTAUX + jmp SETFASTMAIN + jmp copyscrnMA + + jmp copyscrnAM + jmp INVERTY + +*------------------------------- + put hrparams + +*------------------------------- +boot3 = $f880 ;stage 3 boot + +peelbuf1 = $d000 +peelbuf2 = $d600 + +* Local vars + +locals = $f0 +locals2 = $18 + + dum locals + +BASE ds 2 +IMSAVE ds 2 +XSAVE ds 1 +YSAVE ds 1 +WIDTH ds 1 +HEIGHT ds 1 +TOPEDGE ds 1 +OFFLEFT ds 1 +OFFRIGHT ds 1 +YREG ds 1 +CARRY ds 1 + + dum locals2 +index +ztemp +AMASK ds 1 +BMASK ds 1 +VISWIDTH ds 1 +RMOST ds 1 +carryim ds 1 +imbyte ds 1 + + dend + +* OPACITY codes + +and = 0 +ora = 1 +sta = 2 +eor = 3 ;OR/shift/XOR +mask = 4 ;mask/OR + +*------------------------------- +* +* Assume hires routines are called from auxmem +* (Exit with RAMRD, RAMWRT, ALTZP on) +* +*------------------------------- + +cls jsr mainmem + jsr CLS + jmp auxmem + +lay jsr mainmem + jsr LAY + jmp auxmem + +fastlay + jsr FASTLAY + jmp auxmem + +layrsave jsr mainmem + jsr LAYRSAVE + jmp auxmem + +lrcls jsr mainmem + jsr LRCLS + jmp auxmem + +fastmask + jsr FASTMASK + jmp auxmem + +fastblack jsr mainmem + jsr FASTBLACK + jmp auxmem + +peel + jsr PEEL + jmp auxmem + +getwidth jsr mainmem + jsr GETWIDTH + jmp auxmem + +copyscrnMM + jsr mainmem ;r/w main +]copyscrn jsr COPYSCRN + jmp auxmem + +copyscrnAA + jsr auxmem ;r/w aux + jmp ]copyscrn + +copyscrnMA + sta $c002 ;read main + sta $c005 ;write aux + jmp ]copyscrn + +copyscrnAM + sta $c003 ;read aux + sta $c004 ;write main + jmp ]copyscrn + +*------------------------------- +mainmem sta $c004 ;RAMWRT off + sta $c002 ;RAMRD off + rts + +auxmem sta $c005 ;RAMWRT on + sta $c003 ;RAMRD on + rts + +*------------------------------- +* +* Parameters passed to hires routines: +* +* PAGE $00 = hires page 1, $20 = hires page 2 +* XCO Screen X-coord (0=left, 39=right) +* YCO Screen Y-coord (0=top, 191=bottom) +* OFFSET # of bits to shift image right (0-6) +* IMAGE Image # in table (1-127) +* TABLE Starting address of image table (2 bytes) +* BANK Memory bank of table (2 = main, 3 = aux) +* OPACITY Bits 0-6: +* 0 AND +* 1 OR +* 2 STA +* 3 special XOR (OR/shift/XOR) +* 4 mask/OR +* Bit 7: 0 = normal, 1 = mirror +* LEFTCUT Left edge of usable screen area +* (0 for full screen) +* RIGHTCUT Right edge +1 of usable screen area +* (40 for full screen) +* TOPCUT Top edge of usable screen area +* (0 for full screen) +* BOTCUT Bottom edge +1 of usable screen area +* (192 for full screen) +* +*------------------------------- +* +* Image table format: +* +* Byte 0: width (# of bytes) +* Byte 1: height (# of lines) +* Byte 2-n: image bytes (read left-right, top-bottom) +* +*------------------------------- +* +* To preserve the background behind an animated character, +* call LAYERSAVE before LAYing down each character image. +* Afterwards, call PEEL to "peel off" the character & +* restore the original background. +* +* Peel buffer stores background images sequentially, in +* normal image table format, & is cleared after every frame. +* +*------------------------------- +* +* C L S +* +* Clear hi-res screen to black2 +* +*------------------------------- + +CLS lda PAGE ;00 = page 1; 20 = page 2 + clc + adc #$20 + sta :loop+2 + adc #$10 + sta :smod+2 + + lda #$80 ;black2 + + ldx #$10 + + ldy #0 + +:loop sta $2000,y +:smod sta $3000,y + iny + bne :loop + + inc :loop+2 + inc :smod+2 + + dex + bne :loop + + rts + +*------------------------------- +* +* L O - R E S C L S +* +* Clear lo-res/text screen (page 1) +* +* In: A = color +* +*------------------------------- + +LRCLS LDY #$F7 +:2 STA $400,Y + STA $500,Y + STA $600,Y + STA $700,Y + DEY + CPY #$7F + BNE :3 + LDY #$77 +:3 CPY #$FF + BNE :2 + RTS + +*------------------------------- +* +* S E T I M A G E +* +* In: TABLE (2 bytes), IMAGE (image #) +* Out: IMAGE = image start address (2 bytes) +* +*------------------------------- + +setimage lda IMAGE + asl + sec + sbc #1 + + tay + lda (TABLE),y + sta IMAGE + + iny + lda (TABLE),y + sta IMAGE+1 + + rts + +*------------------------------- +* +* G E T W I D T H +* +* In: BANK, TABLE, IMAGE +* Out: A = width, X = height +* +*------------------------------- +GETWIDTH + lda BANK + sta :RAMRD+1 + +:RAMRD sta $c003 + + jsr setimage + + ldy #1 + lda (IMAGE),y ;height + tax + + dey + lda (IMAGE),y ;width + rts + +*------------------------------- +* +* P R E P R E P +* +* In: IMAGE, XCO, YCO +* +*------------------------------- + +PREPREP + +* Save IMAGE, XCO, YCO + + LDA IMAGE + STA IMSAVE + LDA XCO + STA XSAVE + LDA YCO + STA YSAVE + +* Get image data start address + + lda BANK + sta :RAMRD+1 + +:RAMRD sta $c003 + + jsr setimage + +* Read first two bytes (width, height) of image table + + LDY #0 + LDA (IMAGE),Y + STA WIDTH + + INY + LDA (IMAGE),Y + STA HEIGHT + + LDA IMAGE + CLC + ADC #2 + STA IMAGE + BCC :3 + INC IMAGE+1 + +:3 sta $c002 ;RAMRD off (read mainmem) + +]rts rts + +*------------------------------- +* +* C R O P +* +* In: Results of PREPREP (XCO, YCO, HEIGHT, WIDTH) +* Screen area cutoffs (LEFTCUT, RIGHTCUT, TOPCUT, BOTCUT) +* +* Out: +* +* TOPEDGE Top line -1 +* VISWIDTH Width, in bytes, of visible (onscreen) portion +* of image +* XCO X-coord of leftmost visible byte of image +* (must be 0-39) +* YCO Y-coord of lowest visible line of image +* (must be 0-191) +* OFFLEFT # of bytes off left edge +* OFFRIGHT # of bytes off right edge (including carry byte) +* RMOST # of bytes off right edge (excluding carry byte) +* +* Return - if entire image is offscreen, else + +* +*------------------------------- +CROP + +* (1) Crop top & bottom + + lda YCO + cmp BOTCUT + bcs :botoff ;Bottom o.s. + +* Bottom is onscreen--check top + + sec + sbc HEIGHT ;top line -1 + cmp #191 + bcc :topok ;Top is onscreen + + lda TOPCUT ;Top is offscreen + sec + sbc #1 + sta TOPEDGE + jmp :done + +:topok sta TOPEDGE ;Top line -1 (0-191) + + lda TOPCUT ;top line of image area (forced mask) + beq :done ;no top cutoff + + sec + sbc #1 + cmp TOPEDGE + bcc :done + + sta TOPEDGE + bcs :done + +* Bottom is o.s.--advance IMAGE pointer past o.s. portion + +:botoff ;A = YCO + sec + sbc HEIGHT + clc + adc #1 ;top line + cmp BOTCUT + bcs :cancel ;Entire shape is o.s. + sec + sbc #1 + sta TOPEDGE ;top line -1 + + ldx YCO +:loop + lda IMAGE + clc + adc WIDTH + sta IMAGE + bcc :1 + inc IMAGE+1 +:1 + dex + cpx BOTCUT + bcs :loop + + stx YCO + +* (2) Crop sides + +:done + lda XCO + bmi :leftoff + cmp LEFTCUT + bcs :leftok ;XCO >= LEFTCUT + +* XCO < LEFTCUT: left edge is offscreen + +:leftoff + lda LEFTCUT + sec + sbc XCO + sta OFFLEFT ;Width of o.s. portion + + lda WIDTH + sec + sbc OFFLEFT + bmi :cancel ;Entire image is o.s. -- skip it + sta VISWIDTH ;Width of onscreen portion (can be 0) + + lda LEFTCUT + sta XCO + +* Assume image is <=40 bytes wide --> right edge is onscreen + + lda #0 + sta OFFRIGHT + sta RMOST + rts + +* Left edge is onscreen; what about right edge? + +:leftok ;A = XCO + cmp RIGHTCUT ;normally 40 + bcs :cancel ;Entire image is o.s. - skip it + + clc + adc WIDTH ;rightmost byte +1 + cmp RIGHTCUT + bcc :bothok ;Entire image is onscreen + + sec + sbc RIGHTCUT + sta RMOST ;Width of o.s. portion + + clc + adc #1 + sta OFFRIGHT ;+1 + + lda RIGHTCUT + sec + sbc XCO + sta VISWIDTH ;Width of onscreen portion + + lda #0 + sta OFFLEFT + rts + +:bothok lda WIDTH + sta VISWIDTH + + lda #0 + sta OFFLEFT + sta OFFRIGHT + sta RMOST + rts + +:cancel lda #-1 ;Entire image is o.s. - skip it +]rts rts + +*------------------------------- +* +* Shift offset 1 bit right or left +* (for special XOR) +* +* In/out: X = offset +* +*------------------------------- +shiftoffset + cpx #6 + bcs :left + + inx + rts + +:left dex +]rts rts + +*------------------------------- +* +* L A Y E R S A V E +* +* In: Same as for LAY, plus PEELBUF (2 bytes) +* Out: PEELBUF (updated), PEELIMG (2 bytes), PEELXCO, PEELYCO +* +* PEELIMG is 2-byte pointer to beginning of image table. +* (Hi byte = 0 means no image has been stored.) +* +* PEELBUF is 2-byte pointer to first available byte in +* peel buffer. +* +*------------------------------- + +LAYRSAVE + jsr PREPREP + + lda OPACITY + bpl :normal + + LDA XCO + SEC + SBC WIDTH + STA XCO + +:normal + inc WIDTH ;extra byte to cover shift right + + jsr CROP + bmi SKIPIT + + lda PEELBUF ;PEELBUF: 2-byte pointer to 1st + sta PEELIMG ;available byte in peel buffer + lda PEELBUF+1 + sta PEELIMG+1 + + lda XCO + sta PEELXCO + sta :smXCO+1 + + lda YCO + sta PEELYCO + + lda PAGE ;spend 7 cycles now -- + sta :smPAGE+1 ;save 1 in loop + + ldy #0 + + lda VISWIDTH + beq SKIPIT + sta (PEELBUF),y + sta :smWIDTH+1 + + sec + sbc #1 + sta :smSTART+1 + +* Continue + +:cont iny + + LDA YCO + SEC + SBC TOPEDGE + STA (PEELBUF),y ;Height of onscreen portion ("VISHEIGHT") + + LDA PEELBUF + CLC + ADC #2 + STA PEELBUF + BCC :ok + INC PEELBUF+1 +:ok + +* Like FASTLAY in reverse + + ldx YCO + +:loop LDA YLO,X + CLC +:smXCO ADC #0 ;XCO + STA :smBASE+1 + + LDA YHI,X +:smPAGE ADC #0 ;PAGE + STA :smBASE+2 + +:smSTART ldy #0 ;VISWIDTH-1 + +:inloop +:smBASE lda $2000,y + STA (PEELBUF),Y + + dey + bpl :inloop + +:smWIDTH LDA #0 ;VISWIDTH + ADC PEELBUF ;assume cc + STA PEELBUF + BCC :2 + INC PEELBUF+1 +:2 + DEX + CPX TOPEDGE + BNE :loop + + JMP DONE + +SKIPIT lda #0 + sta PEELIMG+1 ;signal that peelbuf is empty + + JMP DONE + +*------------------------------- +* +* L A Y +* +* General routine to lay down an image on hi-res screen +* (Handles edge-clipping, bit-shifting, & mirroring) +* +* Calls one of the following routines: +* +* LayGen General (OR, AND, STA) +* LayMask Mask & OR +* LayXOR Special XOR +* +* Transfers control to MLAY if image is to be mirrored +* +*------------------------------- + +LAY + lda OPACITY + bpl :notmirr + + and #$7f + sta OPACITY + jmp MLAY + +:notmirr cmp #eor + bne :1 + jmp LayXOR + +:1 cmp #mask + bcc :2 + jmp LayMask + +:2 jmp LayGen + +*------------------------------- +* +* General (AND/OR/STORE) +* +*------------------------------- +LayGen + jsr PREPREP + + jsr CROP + bpl :cont + jmp DONE +:cont + lda BANK + sta :RAMRD1+1 + sta :RAMRD2+1 + + LDX OFFSET + + LDA SHIFTL,X + STA :91+1 + LDA SHIFTH,X + STA :91+2 + + LDA CARRYL,X + STA :90+1 + STA :92+1 + LDA CARRYH,X + STA :90+2 + STA :92+2 + + LDA AMASKS,X + STA :AMASK+1 + LDA BMASKS,X + STA :BMASK+1 + + LDX OPACITY + LDA OPCODE,X + STA :80 + STA :81 + +* Preparation completed -- Lay down shape + + LDY YCO + +:nextline + LDA YLO,Y + CLC + ADC XCO + STA BASE + + LDA YHI,Y + ADC PAGE + STA BASE+1 + + LDY OFFLEFT + BEQ :2 + +* (a) Left edge of image is offscreen +* Take initial carry byte from image table + + DEY + +:RAMRD1 sta $c003 ;aux/main + lda (IMAGE),y + sta $c002 ;main + + TAX +:90 LDA $FFFF,X ;CARRYn + STA CARRY + + LDA IMAGE + CLC + ADC OFFLEFT + STA IMAGE + BCC :1 + INC IMAGE+1 +:1 + LDY #0 + + LDA VISWIDTH + STA WIDTH + BNE :3 + BEQ :4 ;Zero width + +* (b) Left edge of image is onscreen +* Take initial carry byte from screen + +:2 LDA (BASE),Y +:AMASK AND #0 + STA CARRY + +* Lay line down left-to-right fast as you can + +:3 +:RAMRD2 sta $c003 ;aux/main + lda (IMAGE),y + sta $c002 ;main + + TAX +:91 LDA $FFFF,X ;SHIFTn + ORA CARRY ;Combine with carryover from previous byte + +:80 STA (BASE),Y ;STA/ORA/AND/EOR depending on OPACITY + STA (BASE),Y + +:92 LDA $FFFF,X ;CARRYn + STA CARRY ;Carry over to next byte + + INY + CPY VISWIDTH + BCC :3 + +* Extra byte on right (carryover) + + LDA OFFRIGHT + BNE :5 ;Rightmost byte is offscreen + +:4 LDA (BASE),Y + +:BMASK AND #0 + ORA CARRY +:81 STA (BASE),Y + STA (BASE),Y + +* Next line up + +:5 LDA WIDTH + CLC + ADC IMAGE + STA IMAGE + BCC :6 + INC IMAGE+1 + +:6 DEC YCO + LDY YCO + CPY TOPEDGE + BNE :nextline + +* Restore parameters + +DONE LDA IMSAVE + STA IMAGE + + LDA XSAVE + STA XCO + LDA YSAVE + STA YCO + + RTS + +*------------------------------- +* +* Mask, then OR +* +*------------------------------- +]done jmp DONE + +LayMask + ldx OPACITY ;4 = mask, 5 = visible mask + lda OPCODE,x ;4 = and, 5 = sta + sta :masksm1 + sta :masksm2 + + jsr PREPREP + + jsr CROP + bmi ]done + + lda BANK + sta :RAMRD1+1 + sta :RAMRD2+1 + + LDX OFFSET + + LDA SHIFTL,X + STA :91+1 + sta :93+1 + + LDA SHIFTH,X + STA :91+2 + sta :93+2 + + LDA CARRYL,X + STA :90+1 + STA :92+1 + sta :94+1 + sta :96+1 + + LDA CARRYH,X + STA :90+2 + STA :92+2 + sta :94+2 + sta :96+2 + + LDA AMASKS,X + STA :AMASK+1 + + LDA BMASKS,X + STA :BMASK+1 + + LDY YCO + +:nextline + LDA YLO,Y + CLC + ADC XCO + STA BASE + + LDA YHI,Y + ADC PAGE + STA BASE+1 + + LDY OFFLEFT + BEQ :2 + +* (a) Left edge of image is offscreen +* Take initial carry byte from image table + + dey + +:RAMRD1 sta $c003 + lda (IMAGE),y +; eor #$ff ;TEMP +; ora #$80 ;TEMP + sta $c002 + + tax +:96 lda $FFFF,x ;CARRYn + sta carryim + + lda MASKTAB-$80,x + tax +:90 lda $FFFF,x ;CARRYn + sta CARRY + + LDA IMAGE + CLC + ADC OFFLEFT + STA IMAGE + BCC :1 + INC IMAGE+1 +:1 + ldy #0 + + LDA VISWIDTH + STA WIDTH + BNE :inloop + BEQ :4 ;Zero width + +* (b) Left edge of image is onscreen +* Take initial carry byte from screen + +:2 +:AMASK lda #0 ;AMASK + sta CARRY + + and (BASE),y + sta carryim + +* Lay line down left-to-right fast as you can + +:inloop + +:RAMRD2 sta $c003 + lda (IMAGE),y +; eor #$ff ;TEMP +; ora #$80 ;TEMP + sta $c002 + + tax + +:93 lda $FFFF,x ;SHIFTn + ora carryim + sta imbyte ;shifted image byte + +:94 lda $FFFF,x ;CARRYn + sta carryim + + lda MASKTAB-$80,x + tax + +:91 lda $FFFF,x ;SHIFTn + ora CARRY +:masksm1 and (BASE),y ;AND with mask byte + ora imbyte ;OR with original image byte + sta (BASE),y + +:92 lda $FFFF,x ;CARRYn + sta CARRY ;Carry over to next byte + + iny + cpy VISWIDTH + bcc :inloop + +* Extra byte on right (carryover) + + lda OFFRIGHT + bne :5 ;Rightmost byte is offscreen + +:4 +:BMASK lda #0 ;BMASK + ora CARRY +:masksm2 and (BASE),y + ora carryim + sta (BASE),y + +* Next line up + +:5 LDA WIDTH + CLC + ADC IMAGE + STA IMAGE + BCC :6 + INC IMAGE+1 + +:6 DEC YCO + LDY YCO + CPY TOPEDGE + beq :done + + jmp :nextline + +:done jmp DONE + +*------------------------------- +* +* Special XOR +* +* (OR, then shift 1 bit and XOR) +* +*------------------------------- + +LayXOR + JSR PREPREP + + jsr CROP + bpl :cont + jmp DONE +:cont + lda BANK + sta :RAMRD1+1 + sta :RAMRD2+1 + + LDX OFFSET + + LDA SHIFTL,X + STA :91+1 + LDA SHIFTH,X + STA :91+2 + + LDA CARRYL,X + STA :90+1 + STA :92+1 + LDA CARRYH,X + STA :90+2 + STA :92+2 + + jsr shiftoffset ;shift 1 bit right + + lda SHIFTL,x + sta :s1+1 + lda SHIFTH,x + sta :s1+2 + + lda CARRYL,x + sta :c1+1 + sta :c2+1 + lda CARRYH,x + sta :c1+2 + sta :c2+2 + + LDA AMASKS,X + STA :AMASK+1 + +* Omit opcode setting + + LDY YCO + +:0 LDA YLO,Y + CLC + ADC XCO + STA BASE + + LDA YHI,Y + ADC PAGE + STA BASE+1 + + LDY OFFLEFT + BEQ :2 + +* (a) Left edge offscreen +* Take CARRY from off left edge + + DEY + +:RAMRD1 sta $c003 + lda (IMAGE),y + sta $c002 + + TAX +:c2 lda $FFFF,x ;CARRYn+1 + sta carryim + +:90 LDA $FFFF,X ;CARRYn + STA CARRY + + LDA IMAGE + CLC + ADC OFFLEFT + STA IMAGE + BCC :1 + INC IMAGE+1 + +:1 LDY #0 + + LDA VISWIDTH + STA WIDTH + BNE :inloop + BEQ :4 ;Zero width + +* (b) Left edge onscreen +* Start a new line at left edge + +:2 lda (BASE),y +:AMASK and #0 ;AMASK + sta CARRY + + lda #0 ;0 XOR X == X + sta carryim + +* Lay line down left-to-right fast as you can + +:inloop + +:RAMRD2 sta $c003 + lda (IMAGE),y + sta $c002 + + tax + +:s1 lda $FFFF,x ;SHIFTn+1 + ora carryim + sta imbyte + +:c1 lda $FFFF,x ;CARRYn+1 + sta carryim + +:91 lda $FFFF,x ;SHIFTn + ora CARRY ;Combine with carryover from previous byte + + ora (BASE),y + eor imbyte + + ora #$80 ;set hibit + sta (BASE),y + +:92 LDA $FFFF,X ;CARRYn + STA CARRY ;Carry over to next byte + + INY + CPY VISWIDTH + BCC :inloop + +* Extra byte on right (carryover) + + LDA OFFRIGHT + BNE :5 ;Rightmost byte is offscreen + +:4 lda CARRY ;0's in unused part of byte + + ora (BASE),y + eor carryim + + ora #$80 + sta (BASE),y + +* Next line up + +:5 LDA WIDTH + CLC + ADC IMAGE + STA IMAGE + BCC :6 + INC IMAGE+1 + +:6 DEC YCO + LDY YCO + CPY TOPEDGE + beq :done + + jmp :0 + +* Restore parameters + +:done jmp DONE + +*------------------------------- +* +* M I R R O R L A Y +* +* Called by LAY +* +* Specified starting byte (XCO, YCO) is image's bottom +* right corner, not bottom left; bytes are read off image +* table R-L, T-B and mirrored before printing. +* +* In: A = OPACITY, sans bit 7 +* +*------------------------------- + +MLAY ;A = OPACITY + cmp #eor + bne :1 + jmp MLayXOR + +:1 cmp #mask + bcc :2 + jmp MLayMask + +:2 jmp MLayGen + +*------------------------------- +* +* General (AND/OR/STORE) +* +*------------------------------- +MLayGen + JSR PREPREP + + LDA XCO + SEC + SBC WIDTH + STA XCO + + jsr CROP + bpl :cont + jmp DONE +:cont + lda BANK + sta :RAMRD1+1 + sta :RAMRD2+1 + + LDX OFFSET + + LDA SHIFTL,X + STA :91+1 + LDA SHIFTH,X + STA :91+2 + + LDA CARRYL,X + STA :90+1 + STA :92+1 + LDA CARRYH,X + STA :90+2 + STA :92+2 + + LDA AMASKS,X + STA AMASK + LDA BMASKS,X + STA BMASK + + LDX OPACITY + LDA OPCODE,X + STA :80 + STA :81 + +* Lay on + + LDY YCO + +:0 LDA YLO,Y + STA BASE + + LDA YHI,Y + CLC + ADC PAGE + STA BASE+1 + + LDY OFFLEFT + BEQ :2 + +* Take CARRY from off left edge + + LDY VISWIDTH + +:RAMRD1 sta $c003 + lda (IMAGE),y + sta $c002 + + TAX + + LDA MIRROR-$80,X + TAX + +:90 LDA $FFFF,X ;CARRYn + STA CARRY + +:1 DEY + BPL :3 + BMI :4 + +* Start a new line at left edge + +:2 LDY XCO + LDA (BASE),Y + AND AMASK + STA CARRY + + LDY WIDTH + DEY + +* Lay line down left-to-right fast as you can + +:3 STY YREG + +:RAMRD2 sta $c003 + lda (IMAGE),y + sta $c002 + + TAX + + LDA MIRROR-$80,X + TAX + +:91 LDA $FFFF,X ;SHIFTn + ORA CARRY ;Combine with carryover from previous byte + + LDY XCO +:80 STA (BASE),Y ;STA/ORA/AND/EOR depending on OPACITY + STA (BASE),Y + +:92 LDA $FFFF,X ;CARRYn + STA CARRY ;Carry over to next byte + + INC BASE + + LDY YREG + CPY RMOST + BEQ :7 + + DEY + BPL :3 + +* Extra byte on right (carryover) + +:7 LDA OFFRIGHT + BNE :5 ;Rightmost byte is offscreen + +:4 LDY XCO + LDA (BASE),Y + + AND BMASK + ORA CARRY +:81 STA (BASE),Y + STA (BASE),Y + +* Next line up + +:5 LDA WIDTH + CLC + ADC IMAGE + STA IMAGE + BCC :6 + INC IMAGE+1 + +:6 DEC YCO + LDY YCO + CPY TOPEDGE + + beq :done + jmp :0 + +:done JMP DONE + +*------------------------------- +* +* Mask, then OR +* +*------------------------------- + +MLayMask + ldx OPACITY ;4 = mask, 5 = visible mask + lda OPCODE,x ;4 = and, 5 = sta + sta :masksm1 + sta :masksm2 + + JSR PREPREP + + LDA XCO + SEC + SBC WIDTH + STA XCO + + jsr CROP + bpl :cont + jmp DONE +:cont + lda BANK + sta :RAMRD1+1 + sta :RAMRD2+1 + + LDX OFFSET + + LDA SHIFTL,X + STA :91+1 + sta :93+1 + + LDA SHIFTH,X + STA :91+2 + sta :93+2 + + LDA CARRYL,X + STA :90+1 + STA :92+1 + sta :94+1 + sta :96+1 + + LDA CARRYH,X + STA :90+2 + STA :92+2 + sta :94+2 + sta :96+2 + + LDA AMASKS,X + STA :AMASK+1 + LDA BMASKS,X + STA :BMASK+1 + +* Lay on + + LDY YCO + +:0 LDA YLO,Y + STA BASE + + LDA YHI,Y + CLC + ADC PAGE + STA BASE+1 + + LDY OFFLEFT + BEQ :2 + +* (a) Left edge offscreen +* Take CARRY from off left edge + + LDY VISWIDTH + +:RAMRD1 sta $c003 + lda (IMAGE),y +; eor #$ff ;TEMP +; ora #$80 ;TEMP + sta $c002 + + TAX + LDA MIRROR-$80,X + TAX + +:96 lda $FFFF,x ;CARRYn + sta carryim + + lda MASKTAB-$80,x + tax +:90 LDA $FFFF,X ;CARRYn + STA CARRY + +:1 DEY + BPL :3 + BMI :4 + +* (b) Left edge onscreen +* Start a new line at left edge + +:2 LDY XCO +:AMASK lda #0 ;AMASK + sta CARRY + + and (BASE),y + sta carryim + + LDY WIDTH + DEY + +* Lay line down left-to-right fast as you can + +:3 STY YREG + +:RAMRD2 sta $c003 + lda (IMAGE),y +; eor #$ff ;TEMP +; ora #$80 ;TEMP + sta $c002 + + TAX + LDA MIRROR-$80,X + TAX + +:93 lda $FFFF,x ;SHIFTn + ora carryim + sta imbyte + +:94 lda $FFFF,x ;CARRYn + sta carryim + + lda MASKTAB-$80,x + tax + +:91 LDA $FFFF,X ;SHIFTn + ORA CARRY ;Combine with carryover from previous byte + + LDY XCO +:masksm1 and (BASE),y + ora imbyte + STA (BASE),Y + +:92 LDA $FFFF,X ;CARRYn + STA CARRY ;Carry over to next byte + + INC BASE + + LDY YREG + CPY RMOST + BEQ :7 + + DEY + BPL :3 + +* Extra byte on right (carryover) + +:7 LDA OFFRIGHT + BNE :5 ;Rightmost byte is offscreen + +:4 LDY XCO + LDA (BASE),Y + +:BMASK AND #0 ;BMASK + ORA CARRY +:masksm2 and (BASE),y + ora carryim + STA (BASE),Y + +* Next line up + +:5 LDA WIDTH + CLC + ADC IMAGE + STA IMAGE + BCC :6 + INC IMAGE+1 + +:6 DEC YCO + LDY YCO + CPY TOPEDGE + beq :done + + jmp :0 + +:done jmp DONE + +*------------------------------- +* +* Special XOR +* +*------------------------------- + +MLayXOR + JSR PREPREP + + LDA XCO + SEC + SBC WIDTH + STA XCO + + jsr CROP + bpl :cont + jmp DONE +:cont + lda BANK + sta :RAMRD1+1 + sta :RAMRD2+1 + + LDX OFFSET + + LDA SHIFTL,X + STA :91+1 + LDA SHIFTH,X + STA :91+2 + + LDA CARRYL,X + STA :90+1 + STA :92+1 + LDA CARRYH,X + STA :90+2 + STA :92+2 + + jsr shiftoffset + + lda SHIFTL,x + sta :s1+1 + lda SHIFTH,x + sta :s1+2 + + lda CARRYL,x + sta :c1+1 + sta :c2+1 + lda CARRYH,x + sta :c1+2 + sta :c2+2 + + LDA AMASKS,X + STA :AMASK+1 + +* Lay on + + LDY YCO + +:0 LDA YLO,Y + STA BASE + + LDA YHI,Y + CLC + ADC PAGE + STA BASE+1 + + LDY OFFLEFT + BEQ :2 + +* (a) Left edge offscreen +* Take CARRY from off left edge + + LDY VISWIDTH + +:RAMRD1 sta $c003 + lda (IMAGE),y + sta $c002 + + TAX + LDA MIRROR-$80,X + TAX + +:c2 lda $FFFF,x ;CARRYn+1 + sta carryim + +:90 LDA $FFFF,X ;CARRYn + STA CARRY + +:1 DEY + BPL :3 + BMI :4 + +* (b) Left edge onscreen +* Start a new line at left edge + +:2 ldy XCO +:AMASK lda #0 ;AMASK + and (BASE),y + sta CARRY + + lda #0 + sta carryim + + LDY WIDTH + DEY + +* Lay line down left-to-right fast as you can + +:3 STY YREG + +:RAMRD2 sta $c003 + lda (IMAGE),y + sta $c002 + + TAX + + LDA MIRROR-$80,X + TAX + +:s1 lda $FFFF,x ;SHIFTn + ora carryim + sta imbyte + +:c1 lda $FFFF,x ;CARRYn + sta carryim + +:91 LDA $FFFF,X ;SHIFTn + ORA CARRY ;Combine with carryover from previous byte + + LDY XCO + + ora (BASE),y + eor imbyte + + ora #$80 + sta (BASE),Y + +:92 LDA $FFFF,X ;CARRYn + STA CARRY ;Carry over to next byte + + INC BASE + + LDY YREG + CPY RMOST + BEQ :7 + + DEY + BPL :3 + +* Extra byte on right (carryover) + +:7 LDA OFFRIGHT + BNE :5 ;Rightmost byte is offscreen + +:4 LDY XCO + + lda CARRY + + ora (BASE),Y + eor carryim + + ora #$80 + STA (BASE),Y + +* Next line up + +:5 LDA WIDTH + CLC + ADC IMAGE + STA IMAGE + BCC :6 + INC IMAGE+1 + +:6 DEC YCO + LDY YCO + CPY TOPEDGE + beq :done + + jmp :0 + +:done JMP DONE + +*------------------------------- +* +* Peel +* +*------------------------------- +PEEL + sta $c004 +]ramrd1 sta $c003 + + jmp fastlaySTA + +*------------------------------- +* +* F A S T L A Y +* +* Streamlined LAY routine +* +* No offset - no clipping - no mirroring - no masking - +* no EOR - trashes IMAGE - may crash if overtaxed - +* but it's fast. +* +* 10/3/88: OK for images to protrude PARTLY off top +* +*------------------------------- +FASTLAY + sta $c004 ;RAMWRT main +]ramrd2 sta $c003 ;RAMRD aux + + jsr setimage + + ldx OPACITY ;hi bit off! + cpx #sta + beq fastlaySTA + + lda OPCODE,x + sta :smod + + lda PAGE + sta :smPAGE+1 + + lda XCO + sta :smXCO+1 + + ldy #0 + lda (IMAGE),y + sta :smWIDTH+1 + + sec + sbc #1 + sta :smSTART+1 + + lda YCO + tax + iny + sbc (IMAGE),y + bcs :ok + lda #-1 ;limited Y-clipping +:ok sta :smTOP+1 + + lda IMAGE + clc + adc #2 + sta IMAGE + bcc :1 + inc IMAGE+1 +:1 + +:outloop + lda YLO,x + clc +:smXCO adc #0 + sta BASE + + lda YHI,x +:smPAGE adc #$20 + sta BASE+1 + +:smSTART ldy #3 + +:inloop +]ramrd3 sta $c003 ;RAMRD aux + + lda (IMAGE),y + + sta $c002 ;RAMRD main + +:smod ora (BASE),y + sta (BASE),y + + dey + bpl :inloop + +:smWIDTH lda #4 + adc IMAGE ;assume cc + sta IMAGE + bcc :2 + inc IMAGE+1 +:2 + dex +:smTOP cpx #$ff + bne :outloop + + rts + +*------------------------------- +* +* Still more streamlined version of FASTLAY (STA only) +* +*------------------------------- +fastlaySTA + lda PAGE + sta :smPAGE+1 + + lda XCO + sta :smXCO+1 + + ldy #0 + lda (IMAGE),y + sta :smWIDTH+1 + + sec + sbc #1 + sta :smSTART+1 + + lda YCO + tax + iny + sbc (IMAGE),y + bcs :ok + lda #-1 ;limited Y-clipping +:ok sta :smTOP+1 + + lda IMAGE + clc + adc #2 + sta IMAGE + bcc :1 + inc IMAGE+1 +:1 + +:outloop + lda YLO,x + clc +:smXCO adc #0 + sta :smod+1 + + lda YHI,x +:smPAGE adc #$20 + sta :smod+2 + +:smSTART ldy #3 + +:inloop + lda (IMAGE),y +:smod sta $2000,y ;BASE + + dey + bpl :inloop + +:smWIDTH lda #4 + adc IMAGE ;cc + sta IMAGE + bcc :2 + inc IMAGE+1 +:2 + dex +:smTOP cpx #$ff + bne :outloop + + rts + +*------------------------------- +* +* F A S T M A S K +* +*------------------------------- +FASTMASK + sta $c004 ;RAMWRT main +]ramrd4 sta $c003 ;RAMRD aux + + jsr setimage + + lda PAGE + sta :smPAGE+1 + + lda XCO + sta :smXCO+1 + + ldy #0 + lda (IMAGE),y + sta :smWIDTH+1 + + sec + sbc #1 + sta :smSTART+1 + + lda YCO + tax + iny + sbc (IMAGE),y + bcs :ok + lda #-1 ;limited Y-clipping +:ok sta :smTOP+1 + + lda IMAGE + clc + adc #2 + sta IMAGE + bcc :1 + inc IMAGE+1 +:1 + +:outloop + stx index + + lda YLO,x + clc +:smXCO adc #0 + sta BASE + + lda YHI,x +:smPAGE adc #$20 + sta BASE+1 + +:smSTART ldy #3 + +:inloop +]ramrd5 sta $c003 ;RAMRD aux + + lda (IMAGE),y + + sta $c002 ;RAMRD main + + tax + lda MASKTAB-$80,X + + and (BASE),Y + sta (BASE),y + + dey + bpl :inloop + +:smWIDTH lda #4 + adc IMAGE ;cc + sta IMAGE + bcc :2 + inc IMAGE+1 +:2 + ldx index + dex +:smTOP cpx #$ff + bne :outloop + + rts + +*------------------------------- +* +* S E T F A S T M A I N / A U X +* +* Modify FASTLAY routines to expect image tables to +* be in main/auxmem. SETFAST need be called only once +* (e.g., when switching between game & builder). +* +*------------------------------- +SETFASTMAIN + lda #$02 ;RAMRD main +]setfast + sta ]ramrd1+1 + sta ]ramrd2+1 + sta ]ramrd3+1 + sta ]ramrd4+1 + sta ]ramrd5+1 + rts + +SETFASTAUX + lda #$03 ;RAMRD aux + bne ]setfast + +*------------------------------- +* +* F A S T B L A C K +* +* Wipe a rectangular area to black2 +* +* Width/height passed in IMAGE/IMAGE+1 +* (width in bytes, height in pixels) +* +*------------------------------- + +FASTBLACK + lda color + sta :smCOLOR+1 + + lda PAGE + sta :smPAGE+1 + + lda XCO + sta :smXCO+1 + + lda width + sec + sbc #1 + sta :smSTART+1 + + lda YCO + tax + sbc height ;cs + sta :smTOP+1 + +:outloop + lda YLO,x + clc +:smXCO adc #0 + sta :smod+1 + + lda YHI,x +:smPAGE adc #$20 + sta :smod+2 + +:smCOLOR lda #$80 + +:smSTART ldy #3 + +:inloop +:smod sta $2000,y ;BASE + dey + bpl :inloop + + dex +:smTOP cpx #$ff + bne :outloop + + rts + +*------------------------------- +* +* C O P Y S C R E E N +* +* Copy $2000 bytes +* +* In: IMAGE+1 = dest scrn, IMAGE = org scrn +* (use hi byte of actual memory address) +* +*------------------------------- +COPYSCRN + lda IMAGE+1 + sta :dst1+2 + clc + adc #$10 + sta :dst2+2 + + lda IMAGE + sta :org1+2 + adc #$10 + sta :org2+2 + + ldx #$10 + + ldy #0 +:loop +:org1 lda $2000,y +:dst1 sta $4000,y + +:org2 lda $3000,y +:dst2 sta $5000,y + + iny + bne :loop + + inc :org1+2 + inc :org2+2 + inc :dst1+2 + inc :dst2+2 + + dex + bne :loop + + rts + +*------------------------------- +* Invert Y-tables +*------------------------------- +INVERTY + ldx #191 ;low line + ldy #0 ;high line + +* Switch low & high lines + +:loop lda YLO,x + pha + lda YLO,y + sta YLO,x + pla + sta YLO,y + + lda YHI,x + pha + lda YHI,y + sta YHI,x + pla + sta YHI,y + +* Move 1 line closer to ctr + + dex + iny + cpy #96 + bcc :loop +]rts rts + +*------------------------------- + lst + ds 1 + usr $a9,1,$0000,*-org + lst off diff --git a/01 POP Source/Source/HRPARAMS.S b/01 POP Source/Source/HRPARAMS.S index cd31acf..84db03e 100755 --- a/01 POP Source/Source/HRPARAMS.S +++ b/01 POP Source/Source/HRPARAMS.S @@ -1 +1,70 @@ - tr on * hrparams hrtables = $e000 hrparams = $00 *------------------------------- dum hrtables YLO ds $c0 YHI ds $c0 SHIFT0 ds $80 SHIFT1 ds $80 SHIFT2 ds $80 SHIFT3 ds $80 SHIFT4 ds $80 SHIFT5 ds $80 SHIFT6 ds $80 CARRY0 ds $80 CARRY1 ds $80 CARRY2 ds $80 CARRY3 ds $80 CARRY4 ds $80 CARRY5 ds $80 CARRY6 ds $80 MIRROR ds $80 MASKTAB ds $80 SHIFTL ds 7 SHIFTH ds 7 CARRYL ds 7 CARRYH ds 7 AMASKS ds 7 BMASKS ds 7 OPCODE ds 6 endtabs dend *------------------------------- dum hrparams PAGE ds 1 XCO ds 1 YCO ds 1 OFFSET ds 1 IMAGE ds 2 OPACITY ds 1 TABLE ds 2 PEELBUF ds 2 PEELIMG ds 2 PEELXCO ds 1 PEELYCO ds 1 TOPCUT ds 1 LEFTCUT ds 1 RIGHTCUT ds 1 BANK ds 1 BOTCUT ds 1 dend height = IMAGE width = IMAGE+1 color = OPACITY lst off \ No newline at end of file + tr on +* hrparams + +hrtables = $e000 +hrparams = $00 +*------------------------------- + dum hrtables + +YLO ds $c0 +YHI ds $c0 + +SHIFT0 ds $80 +SHIFT1 ds $80 +SHIFT2 ds $80 +SHIFT3 ds $80 +SHIFT4 ds $80 +SHIFT5 ds $80 +SHIFT6 ds $80 + +CARRY0 ds $80 +CARRY1 ds $80 +CARRY2 ds $80 +CARRY3 ds $80 +CARRY4 ds $80 +CARRY5 ds $80 +CARRY6 ds $80 + +MIRROR ds $80 +MASKTAB ds $80 + +SHIFTL ds 7 +SHIFTH ds 7 +CARRYL ds 7 +CARRYH ds 7 +AMASKS ds 7 +BMASKS ds 7 + +OPCODE ds 6 + +endtabs dend + +*------------------------------- + dum hrparams + +PAGE ds 1 +XCO ds 1 +YCO ds 1 +OFFSET ds 1 +IMAGE ds 2 +OPACITY ds 1 +TABLE ds 2 + +PEELBUF ds 2 +PEELIMG ds 2 +PEELXCO ds 1 +PEELYCO ds 1 + +TOPCUT ds 1 +LEFTCUT ds 1 +RIGHTCUT ds 1 +BANK ds 1 +BOTCUT ds 1 + + dend + +height = IMAGE +width = IMAGE+1 +color = OPACITY + + lst off diff --git a/01 POP Source/Source/HRTABLES.S b/01 POP Source/Source/HRTABLES.S index 61d59c8..2ee04ce 100755 --- a/01 POP Source/Source/HRTABLES.S +++ b/01 POP Source/Source/HRTABLES.S @@ -1 +1,331 @@ -* hires tables org = $e000 tr on lst off *------------------------------- org org *------------------------------- * * YLO/YHI * * Index: Screen Y-coord (0-191, 0 = top) * Returns base address on hires page 1 (add $2000 for page 2) * *------------------------------- YLO hex 00000000000000008080808080808080 hex 00000000000000008080808080808080 hex 00000000000000008080808080808080 hex 00000000000000008080808080808080 hex 2828282828282828A8A8A8A8A8A8A8A8 hex 2828282828282828A8A8A8A8A8A8A8A8 hex 2828282828282828A8A8A8A8A8A8A8A8 hex 2828282828282828A8A8A8A8A8A8A8A8 hex 5050505050505050D0D0D0D0D0D0D0D0 hex 5050505050505050D0D0D0D0D0D0D0D0 hex 5050505050505050D0D0D0D0D0D0D0D0 hex 5050505050505050D0D0D0D0D0D0D0D0 YHI hex 2024282C3034383C2024282C3034383C hex 2125292D3135393D2125292D3135393D hex 22262A2E32363A3E22262A2E32363A3E hex 23272B2F33373B3F23272B2F33373B3F hex 2024282C3034383C2024282C3034383C hex 2125292D3135393D2125292D3135393D hex 22262A2E32363A3E22262A2E32363A3E hex 23272B2F33373B3F23272B2F33373B3F hex 2024282C3034383C2024282C3034383C hex 2125292D3135393D2125292D3135393D hex 22262A2E32363A3E22262A2E32363A3E hex 23272B2F33373B3F23272B2F33373B3F *------------------------------- * * SHIFTn/CARRYn * * n = # of pixels to shift right (0-6) * Index: byte value w/hibit clr (0-127) * * SHIFT returns shifted byte w/hibit set * CARRY returns carryover to next byte w/hibit clr * *------------------------------- SHIFT0 hex 808182838485868788898A8B8C8D8E8F hex 909192939495969798999A9B9C9D9E9F hex A0A1A2A3A4A5A6A7A8A9AAABACADAEAF hex B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF hex C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF hex D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF hex E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF hex F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF SHIFT1 hex 80828486888A8C8E90929496989A9C9E hex A0A2A4A6A8AAACAEB0B2B4B6B8BABCBE hex C0C2C4C6C8CACCCED0D2D4D6D8DADCDE hex E0E2E4E6E8EAECEEF0F2F4F6F8FAFCFE hex 80828486888A8C8E90929496989A9C9E hex A0A2A4A6A8AAACAEB0B2B4B6B8BABCBE hex C0C2C4C6C8CACCCED0D2D4D6D8DADCDE hex E0E2E4E6E8EAECEEF0F2F4F6F8FAFCFE SHIFT2 hex 8084888C9094989CA0A4A8ACB0B4B8BC hex C0C4C8CCD0D4D8DCE0E4E8ECF0F4F8FC hex 8084888C9094989CA0A4A8ACB0B4B8BC hex C0C4C8CCD0D4D8DCE0E4E8ECF0F4F8FC hex 8084888C9094989CA0A4A8ACB0B4B8BC hex C0C4C8CCD0D4D8DCE0E4E8ECF0F4F8FC hex 8084888C9094989CA0A4A8ACB0B4B8BC hex C0C4C8CCD0D4D8DCE0E4E8ECF0F4F8FC SHIFT3 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 SHIFT4 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 SHIFT5 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 SHIFT6 hex 80C080C080C080C080C080C080C080C0 hex 80C080C080C080C080C080C080C080C0 hex 80C080C080C080C080C080C080C080C0 hex 80C080C080C080C080C080C080C080C0 hex 80C080C080C080C080C080C080C080C0 hex 80C080C080C080C080C080C080C080C0 hex 80C080C080C080C080C080C080C080C0 hex 80C080C080C080C080C080C080C080C0 CARRY0 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 CARRY1 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 01010101010101010101010101010101 hex 01010101010101010101010101010101 hex 01010101010101010101010101010101 hex 01010101010101010101010101010101 CARRY2 hex 00000000000000000000000000000000 hex 00000000000000000000000000000000 hex 01010101010101010101010101010101 hex 01010101010101010101010101010101 hex 02020202020202020202020202020202 hex 02020202020202020202020202020202 hex 03030303030303030303030303030303 hex 03030303030303030303030303030303 CARRY3 hex 00000000000000000000000000000000 hex 01010101010101010101010101010101 hex 02020202020202020202020202020202 hex 03030303030303030303030303030303 hex 04040404040404040404040404040404 hex 05050505050505050505050505050505 hex 06060606060606060606060606060606 hex 07070707070707070707070707070707 CARRY4 hex 00000000000000000101010101010101 hex 02020202020202020303030303030303 hex 04040404040404040505050505050505 hex 06060606060606060707070707070707 hex 08080808080808080909090909090909 hex 0A0A0A0A0A0A0A0A0B0B0B0B0B0B0B0B hex 0C0C0C0C0C0C0C0C0D0D0D0D0D0D0D0D hex 0E0E0E0E0E0E0E0E0F0F0F0F0F0F0F0F CARRY5 hex 00000000010101010202020203030303 hex 04040404050505050606060607070707 hex 08080808090909090A0A0A0A0B0B0B0B hex 0C0C0C0C0D0D0D0D0E0E0E0E0F0F0F0F hex 10101010111111111212121213131313 hex 14141414151515151616161617171717 hex 18181818191919191A1A1A1A1B1B1B1B hex 1C1C1C1C1D1D1D1D1E1E1E1E1F1F1F1F CARRY6 hex 00000101020203030404050506060707 hex 080809090A0A0B0B0C0C0D0D0E0E0F0F hex 10101111121213131414151516161717 hex 181819191A1A1B1B1C1C1D1D1E1E1F1F hex 20202121222223232424252526262727 hex 282829292A2A2B2B2C2C2D2D2E2E2F2F hex 30303131323233333434353536363737 hex 383839393A3A3B3B3C3C3D3D3E3E3F3F *------------------------------- * * MIRROR * * Index: byte value w/hibit clr (0-127) * Returns mirrored byte w/hibit set * *------------------------------- MIRROR hex 80C0A0E090D0B0F088C8A8E898D8B8F8 hex 84C4A4E494D4B4F48CCCACEC9CDCBCFC hex 82C2A2E292D2B2F28ACAAAEA9ADABAFA hex 86C6A6E696D6B6F68ECEAEEE9EDEBEFE hex 81C1A1E191D1B1F189C9A9E999D9B9F9 hex 85C5A5E595D5B5F58DCDADED9DDDBDFD hex 83C3A3E393D3B3F38BCBABEB9BDBBBFB hex 87C7A7E797D7B7F78FCFAFEF9FDFBFFF *------------------------------- * * MASKTAB * * Index: byte value w/hibit clr (0-127) * Returns mask byte w/hibit set * *------------------------------- MASKTAB HEX FF,FC,F8,F8,F1,F0,F0,F0 HEX E3,E0,E0,E0,E1,E0,E0,E0 HEX C7,C4,C0,C0,C1,C0,C0,C0 HEX C3,C0,C0,C0,C1,C0,C0,C0 HEX 8F,8C,88,88,81,80,80,80 HEX 83,80,80,80,81,80,80,80 HEX 87,84,80,80,81,80,80,80 HEX 83,80,80,80,81,80,80,80 HEX 9F,9C,98,98,91,90,90,90 HEX 83,80,80,80,81,80,80,80 HEX 87,84,80,80,81,80,80,80 HEX 83,80,80,80,81,80,80,80 HEX 8F,8C,88,88,81,80,80,80 HEX 83,80,80,80,81,80,80,80 HEX 87,84,80,80,81,80,80,80 HEX 83,80,80,80,81,80,80,80 *------------------------------- * * SHIFTL-H/CARRYL-H * * Index: Bit offset (0-6) * Returns address of corresponding shift/carry table * *------------------------------- SHIFTL dfb #SHIFT0-$80 dfb #SHIFT1-$80 dfb #SHIFT2-$80 dfb #SHIFT3-$80 dfb #SHIFT4-$80 dfb #SHIFT5-$80 dfb #SHIFT6-$80 SHIFTH dfb >SHIFT0-$80 dfb >SHIFT1-$80 dfb >SHIFT2-$80 dfb >SHIFT3-$80 dfb >SHIFT4-$80 dfb >SHIFT5-$80 dfb >SHIFT6-$80 CARRYL dfb #CARRY0-$80 dfb #CARRY1-$80 dfb #CARRY2-$80 dfb #CARRY3-$80 dfb #CARRY4-$80 dfb #CARRY5-$80 dfb #CARRY6-$80 CARRYH dfb >CARRY0-$80 dfb >CARRY1-$80 dfb >CARRY2-$80 dfb >CARRY3-$80 dfb >CARRY4-$80 dfb >CARRY5-$80 dfb >CARRY6-$80 *------------------------------- * * AMASKS/BMASKS * * Index: Bit offset (0-6) * Returns appropriate mask bytes * *------------------------------- AMASKS dfb %10000000 dfb %10000001 dfb %10000011 dfb %10000111 dfb %10001111 dfb %10011111 dfb %10111111 BMASKS dfb %11111111 dfb %11111110 dfb %11111100 dfb %11111000 dfb %11110000 dfb %11100000 dfb %11000000 *------------------------------- * * OPCODE * * Index: OPACITY (0-5) * Returns opcode to put in self-mod code * *------------------------------- OPCODE dfb $31 ;and (oper),Y dfb $11 ;ora dfb $91 ;sta dfb $51 ;eor dfb $31 ;and dfb $91 ;sta *------------------------------- lst usr $a9,2,$0000,*-org lst off \ No newline at end of file +* hires tables +org = $e000 + tr on + lst off +*------------------------------- + org org +*------------------------------- +* +* YLO/YHI +* +* Index: Screen Y-coord (0-191, 0 = top) +* Returns base address on hires page 1 (add $2000 for page 2) +* +*------------------------------- + +YLO hex 00000000000000008080808080808080 + hex 00000000000000008080808080808080 + hex 00000000000000008080808080808080 + hex 00000000000000008080808080808080 + + hex 2828282828282828A8A8A8A8A8A8A8A8 + hex 2828282828282828A8A8A8A8A8A8A8A8 + hex 2828282828282828A8A8A8A8A8A8A8A8 + hex 2828282828282828A8A8A8A8A8A8A8A8 + + hex 5050505050505050D0D0D0D0D0D0D0D0 + hex 5050505050505050D0D0D0D0D0D0D0D0 + hex 5050505050505050D0D0D0D0D0D0D0D0 + hex 5050505050505050D0D0D0D0D0D0D0D0 + +YHI hex 2024282C3034383C2024282C3034383C + hex 2125292D3135393D2125292D3135393D + hex 22262A2E32363A3E22262A2E32363A3E + hex 23272B2F33373B3F23272B2F33373B3F + + hex 2024282C3034383C2024282C3034383C + hex 2125292D3135393D2125292D3135393D + hex 22262A2E32363A3E22262A2E32363A3E + hex 23272B2F33373B3F23272B2F33373B3F + + hex 2024282C3034383C2024282C3034383C + hex 2125292D3135393D2125292D3135393D + hex 22262A2E32363A3E22262A2E32363A3E + hex 23272B2F33373B3F23272B2F33373B3F + +*------------------------------- +* +* SHIFTn/CARRYn +* +* n = # of pixels to shift right (0-6) +* Index: byte value w/hibit clr (0-127) +* +* SHIFT returns shifted byte w/hibit set +* CARRY returns carryover to next byte w/hibit clr +* +*------------------------------- + +SHIFT0 hex 808182838485868788898A8B8C8D8E8F + hex 909192939495969798999A9B9C9D9E9F + hex A0A1A2A3A4A5A6A7A8A9AAABACADAEAF + hex B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF + + hex C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF + hex D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF + hex E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF + hex F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF + +SHIFT1 hex 80828486888A8C8E90929496989A9C9E + hex A0A2A4A6A8AAACAEB0B2B4B6B8BABCBE + hex C0C2C4C6C8CACCCED0D2D4D6D8DADCDE + hex E0E2E4E6E8EAECEEF0F2F4F6F8FAFCFE + + hex 80828486888A8C8E90929496989A9C9E + hex A0A2A4A6A8AAACAEB0B2B4B6B8BABCBE + hex C0C2C4C6C8CACCCED0D2D4D6D8DADCDE + hex E0E2E4E6E8EAECEEF0F2F4F6F8FAFCFE + +SHIFT2 hex 8084888C9094989CA0A4A8ACB0B4B8BC + hex C0C4C8CCD0D4D8DCE0E4E8ECF0F4F8FC + hex 8084888C9094989CA0A4A8ACB0B4B8BC + hex C0C4C8CCD0D4D8DCE0E4E8ECF0F4F8FC + + hex 8084888C9094989CA0A4A8ACB0B4B8BC + hex C0C4C8CCD0D4D8DCE0E4E8ECF0F4F8FC + hex 8084888C9094989CA0A4A8ACB0B4B8BC + hex C0C4C8CCD0D4D8DCE0E4E8ECF0F4F8FC + +SHIFT3 hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 + hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 + hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 + hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 + + hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 + hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 + hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 + hex 80889098A0A8B0B8C0C8D0D8E0E8F0F8 + +SHIFT4 hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 + hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 + hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 + hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 + + hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 + hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 + hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 + hex 8090A0B0C0D0E0F08090A0B0C0D0E0F0 + +SHIFT5 hex 80A0C0E080A0C0E080A0C0E080A0C0E0 + hex 80A0C0E080A0C0E080A0C0E080A0C0E0 + hex 80A0C0E080A0C0E080A0C0E080A0C0E0 + hex 80A0C0E080A0C0E080A0C0E080A0C0E0 + + hex 80A0C0E080A0C0E080A0C0E080A0C0E0 + hex 80A0C0E080A0C0E080A0C0E080A0C0E0 + hex 80A0C0E080A0C0E080A0C0E080A0C0E0 + hex 80A0C0E080A0C0E080A0C0E080A0C0E0 + +SHIFT6 hex 80C080C080C080C080C080C080C080C0 + hex 80C080C080C080C080C080C080C080C0 + hex 80C080C080C080C080C080C080C080C0 + hex 80C080C080C080C080C080C080C080C0 + + hex 80C080C080C080C080C080C080C080C0 + hex 80C080C080C080C080C080C080C080C0 + hex 80C080C080C080C080C080C080C080C0 + hex 80C080C080C080C080C080C080C080C0 + +CARRY0 hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + + hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + +CARRY1 hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + + hex 01010101010101010101010101010101 + hex 01010101010101010101010101010101 + hex 01010101010101010101010101010101 + hex 01010101010101010101010101010101 + +CARRY2 hex 00000000000000000000000000000000 + hex 00000000000000000000000000000000 + hex 01010101010101010101010101010101 + hex 01010101010101010101010101010101 + + hex 02020202020202020202020202020202 + hex 02020202020202020202020202020202 + hex 03030303030303030303030303030303 + hex 03030303030303030303030303030303 + +CARRY3 hex 00000000000000000000000000000000 + hex 01010101010101010101010101010101 + hex 02020202020202020202020202020202 + hex 03030303030303030303030303030303 + + hex 04040404040404040404040404040404 + hex 05050505050505050505050505050505 + hex 06060606060606060606060606060606 + hex 07070707070707070707070707070707 + +CARRY4 hex 00000000000000000101010101010101 + hex 02020202020202020303030303030303 + hex 04040404040404040505050505050505 + hex 06060606060606060707070707070707 + + hex 08080808080808080909090909090909 + hex 0A0A0A0A0A0A0A0A0B0B0B0B0B0B0B0B + hex 0C0C0C0C0C0C0C0C0D0D0D0D0D0D0D0D + hex 0E0E0E0E0E0E0E0E0F0F0F0F0F0F0F0F + +CARRY5 hex 00000000010101010202020203030303 + hex 04040404050505050606060607070707 + hex 08080808090909090A0A0A0A0B0B0B0B + hex 0C0C0C0C0D0D0D0D0E0E0E0E0F0F0F0F + + hex 10101010111111111212121213131313 + hex 14141414151515151616161617171717 + hex 18181818191919191A1A1A1A1B1B1B1B + hex 1C1C1C1C1D1D1D1D1E1E1E1E1F1F1F1F + +CARRY6 hex 00000101020203030404050506060707 + hex 080809090A0A0B0B0C0C0D0D0E0E0F0F + hex 10101111121213131414151516161717 + hex 181819191A1A1B1B1C1C1D1D1E1E1F1F + + hex 20202121222223232424252526262727 + hex 282829292A2A2B2B2C2C2D2D2E2E2F2F + hex 30303131323233333434353536363737 + hex 383839393A3A3B3B3C3C3D3D3E3E3F3F + +*------------------------------- +* +* MIRROR +* +* Index: byte value w/hibit clr (0-127) +* Returns mirrored byte w/hibit set +* +*------------------------------- + +MIRROR hex 80C0A0E090D0B0F088C8A8E898D8B8F8 + hex 84C4A4E494D4B4F48CCCACEC9CDCBCFC + hex 82C2A2E292D2B2F28ACAAAEA9ADABAFA + hex 86C6A6E696D6B6F68ECEAEEE9EDEBEFE + + hex 81C1A1E191D1B1F189C9A9E999D9B9F9 + hex 85C5A5E595D5B5F58DCDADED9DDDBDFD + hex 83C3A3E393D3B3F38BCBABEB9BDBBBFB + hex 87C7A7E797D7B7F78FCFAFEF9FDFBFFF + +*------------------------------- +* +* MASKTAB +* +* Index: byte value w/hibit clr (0-127) +* Returns mask byte w/hibit set +* +*------------------------------- + +MASKTAB HEX FF,FC,F8,F8,F1,F0,F0,F0 + HEX E3,E0,E0,E0,E1,E0,E0,E0 + HEX C7,C4,C0,C0,C1,C0,C0,C0 + HEX C3,C0,C0,C0,C1,C0,C0,C0 + + HEX 8F,8C,88,88,81,80,80,80 + HEX 83,80,80,80,81,80,80,80 + HEX 87,84,80,80,81,80,80,80 + HEX 83,80,80,80,81,80,80,80 + + HEX 9F,9C,98,98,91,90,90,90 + HEX 83,80,80,80,81,80,80,80 + HEX 87,84,80,80,81,80,80,80 + HEX 83,80,80,80,81,80,80,80 + + HEX 8F,8C,88,88,81,80,80,80 + HEX 83,80,80,80,81,80,80,80 + HEX 87,84,80,80,81,80,80,80 + HEX 83,80,80,80,81,80,80,80 + +*------------------------------- +* +* SHIFTL-H/CARRYL-H +* +* Index: Bit offset (0-6) +* Returns address of corresponding shift/carry table +* +*------------------------------- + +SHIFTL dfb #SHIFT0-$80 + dfb #SHIFT1-$80 + dfb #SHIFT2-$80 + dfb #SHIFT3-$80 + dfb #SHIFT4-$80 + dfb #SHIFT5-$80 + dfb #SHIFT6-$80 + +SHIFTH dfb >SHIFT0-$80 + dfb >SHIFT1-$80 + dfb >SHIFT2-$80 + dfb >SHIFT3-$80 + dfb >SHIFT4-$80 + dfb >SHIFT5-$80 + dfb >SHIFT6-$80 + +CARRYL dfb #CARRY0-$80 + dfb #CARRY1-$80 + dfb #CARRY2-$80 + dfb #CARRY3-$80 + dfb #CARRY4-$80 + dfb #CARRY5-$80 + dfb #CARRY6-$80 + +CARRYH dfb >CARRY0-$80 + dfb >CARRY1-$80 + dfb >CARRY2-$80 + dfb >CARRY3-$80 + dfb >CARRY4-$80 + dfb >CARRY5-$80 + dfb >CARRY6-$80 + +*------------------------------- +* +* AMASKS/BMASKS +* +* Index: Bit offset (0-6) +* Returns appropriate mask bytes +* +*------------------------------- + +AMASKS dfb %10000000 + dfb %10000001 + dfb %10000011 + dfb %10000111 + dfb %10001111 + dfb %10011111 + dfb %10111111 + +BMASKS dfb %11111111 + dfb %11111110 + dfb %11111100 + dfb %11111000 + dfb %11110000 + dfb %11100000 + dfb %11000000 + +*------------------------------- +* +* OPCODE +* +* Index: OPACITY (0-5) +* Returns opcode to put in self-mod code +* +*------------------------------- + +OPCODE dfb $31 ;and (oper),Y + dfb $11 ;ora + dfb $91 ;sta + dfb $51 ;eor + dfb $31 ;and + dfb $91 ;sta + +*------------------------------- + lst + usr $a9,2,$0000,*-org + lst off diff --git a/01 POP Source/Source/MASTER.S b/01 POP Source/Source/MASTER.S index fbaf651..acd1e71 100755 --- a/01 POP Source/Source/MASTER.S +++ b/01 POP Source/Source/MASTER.S @@ -1 +1,1447 @@ -* master 3.5 DemoDisk = 0 FinalDisk = 1 org = $f880 lst off *------------------------------- * * M A S T E R * * (3.5" version) * * Sits in main l.c. * *------------------------------- org org jmp FIRSTBOOT jmp LOADLEVEL jmp RELOAD jmp LoadStage2 jmp RELOAD jmp ATTRACTMODE jmp CUTPRINCESS jmp SAVEGAME jmp LOADGAME jmp DOSTARTGAME jmp EPILOG jmp LOADALTSET *------------------------------- lst put eq lst put gameeq lst off Tmoveauxlc = moveauxlc-$b000 *------------------------------- * RW18 ID bytes POPside1 = $a9 POPside2 = $ad * RW18 zero page vars slot = $fd track = $fe lastrack = $ff * RW18 commands DrvOn = $00 DrvOff = $01 Seek = $02 RdSeqErr = $03 RdGrpErr = $04 WrtSeqErr = $05 WrtGrpErr = $06 ModID = $07 RdSeq = $83 RdGrp = $84 WrtSeq = $85 WrtGrp = $86 Inc = $40 ;.Inc to inc track *------------------------------- * Local vars dum locals ]dest ds 2 ]source ds 2 ]endsourc ds 2 newBGset1 ds 1 newBGset2 ds 1 newCHset ds 1 dend *------------------------------- * Passed params params = $3f0 *------------------------------- * Coordinates of default load-in level demolevel db 33,0 firstlevel db 33,1 *------------------------------- * Hi bytes of crunch data * Double hi-res (stage 1) pacSplash = $40 delPresents = $70 delByline = $72 delTitle = $74 pacProlog = $7c pacSumup = $60 ;mainmem pacEpilog = $76 ;side B * Single hires (stage 2) pacProom = $84 *------------------------------- * Music song #s * Set 1 (title) s_Presents = 1 s_Byline = 2 s_Title = 3 s_Prolog = 4 s_Sumup = 5 s_Princess = 7 s_Squeek = 8 s_Vizier = 9 s_Buildup = 10 s_Magic = 11 * Set 2 (epilog) s_Epilog = 1 s_Curtain = 2 *------------------------------- * 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 *------------------------------- kprincess = "p"-$60 ;temp! kdemo = "d"-$60 ;temp! krestart = "r"-$60 kresume = "l"-$60 *------------------------------- * * Notes: * * Game code sits in auxmem & aux l.c. and uses aux z.p. * * Routines in main l.c. (including MASTER and HIRES) * are called via intermediary routines in GRAFIX (in auxmem). * * RW18 sits in bank 1 of main language card; * driveon switches it in, driveoff switches it out. * *------------------------------- * * F I R S T B O O T * *------------------------------- FIRSTBOOT lda MIXEDoff jsr setaux * Set BBund ID byte lda #POPside1 sta BBundID * Load hires tables & add'l hires routines sta RAMWRTmain lda #2 sta track jsr rw18 db RdGrp.Inc hex e0,e1,e2,e3,e4,e5,e6,e7,e8 hex e9,ea,eb,ec,ed,00,00,00,00 * Load as much of Stage 3 as we can keep jsr loadperm * Turn off drive jsr driveoff * Check for IIGS jsr checkIIGS ;returns IIGS * Start attract loop jsr initsystem ;in topctrl lda #0 sta invert ;rightside up Y tables lda #1 sta soundon ;Sound on jmp AttractLoop *------------------------------- * * Reload code & images * (Temp routine for game development) * *------------------------------- RELOAD do 0 jsr driveon jsr loadperm jsr LoadStage3 jmp driveoff fin *------------------------------- * * Load music (1K) * * Load at $5000 mainmem & move to aux l.c. * *------------------------------- * Load music set 1 (title) loadmusic1 jsr setmain lda #34 sta track jsr rw18 db RdSeq,$4e ;we only want $50-53 ]mm jsr setaux jmp xmovemusic *------------------------------- * Load music set 2 (game) loadmusic2 jsr setmain lda #20 sta track jsr rw18 db RdGrp.Inc hex 50,51,52,53,00,00,00,00,00 hex 00,00,00,00,00,00,00,00,00 jmp ]mm *------------------------------- * Load music set 3 (epilog) loadmusic3 jmp loadmusic1 *------------------------------- setaux sta RAMRDaux sta RAMWRTaux rts setmain sta RAMRDmain sta RAMWRTmain rts *------------------------------- * * D R I V E O N * * In: A = delay * BBundID * * Sets auxmem * *------------------------------- driveon lda #0 driveon1 sta :delay jsr setaux ;set auxmem * switch in bank 1 (RW18) bit RWBANK1 bit RWBANK1 ;1st 4k bank * set Bbund ID lda BBundID sta :IDbyte jsr rw18 db ModID :IDbyte hex a9 ;Bbund ID byte * turn on drive 1 jsr rw18 db DrvOn :drive hex 01 :delay hex 00 rts *------------------------------- * * D R I V E O F F * *------------------------------- driveoff jsr rw18 db DrvOff * switch in bank 2 bit RWBANK2 bit RWBANK2 ;2nd 4k bank sta $c010 ;clr kbd jmp setaux ;& set auxmem *------------------------------- * * Set first level/demo level * *------------------------------- set1stlevel lda firstlevel ldx firstlevel+1 SetLevel sta params stx params+1 ]rts rts setdemolevel lda demolevel ldx demolevel+1 jmp SetLevel *------------------------------- * * Check track 22 to make sure it's the right disk * * (Scratch page 2 mainmem--return w/mainmem set) * *------------------------------- checkdisk jsr setaux ldx #POPside2 stx BBundID jsr driveon :loop jsr setmain lda #22 sta track jsr rw18 db RdGrpErr.Inc hex 02,00,00,00,00,00,00,00,00 hex 00,00,00,00,00,00,00,00,00 bcc ]rts jsr error jmp :loop *------------------------------- * * Save/load game * * Write/read 256 bytes of data: sector 0, track 23, side 2 * We scorch an entire track, but on side 2 we can afford it * *------------------------------- SAVEGAME jsr checkdisk ;sets main sta RAMRDaux ldx #15 :loop lda savedgame,x ;aux sta $200,x ;main dex bpl :loop sta RAMRDmain lda #23 sta track jsr rw18 db WrtGrpErr hex 02,00,00,00,00,00,00,00,00 hex 00,00,00,00,00,00,00,00,00 bcc :ok jsr whoop :ok jmp driveoff *------------------------------- LOADGAME jsr checkdisk ;sets main lda #23 sta track jsr rw18 db RdGrp hex 02,00,00,00,00,00,00,00,00 hex 00,00,00,00,00,00,00,00,00 sta RAMWRTaux ldx #15 :loop lda $200,x ;main sta savedgame,x ;aux dex bpl :loop jmp driveoff *------------------------------- * * Load alt. character set (chtable4) * * In: Y = CHset4 * *------------------------------- LOADALTSET sty newCHset jsr driveon jsr rdch4 jmp driveoff *------------------------------- * * L O A D L E V E L * * In: bluepTRK, bluepREG * TRK = track # (1-33) * REG = region on track (0-1) * A = BGset1; X = BGset2; Y = CHset4 * * Load level into "working blueprint" buffer in auxmem; * game code will make a "backup copy" into aux l.c. * (which we can't reach from here). * * If bg & char sets in memory aren't right, load them in * *------------------------------- LOADLEVEL sta newBGset1 stx newBGset2 sty newCHset jsr driveon jsr rdbluep ;blueprint jsr rdbg1 ;bg set 1 jsr rdbg2 ;bg set 2 jsr rdch4 ;char set 4 jsr vidstuff jmp driveoff *------------------------------- setbluep lda bluepTRK sta track lda bluepREG ]rts rts *------------------------------- vidstuff lda BBundID cmp #POPside2 bne ]rts lda $c000 cmp #"^" bne ]rts jsr setmain lda #12 sta track jsr rw18 db RdGrp.Inc hex 00,00,00,00,00,00,00,00,00 hex 00,00,00,0c,0d,0e,0f,10,11 :loop jsr rw18 db RdSeq.Inc :sm hex 12 lda :sm clc adc #$12 sta :sm cmp #$6c bcc :loop jsr driveoff jsr setmain jmp $c00 *------------------------------- * Track data for alt bg/char sets * * Set #: 0 1 2 3 4 5 6 bg1trk hex 05,00,07 bg2trk hex 12,02,09 ch4trk hex 0d,03,04,05,0a,0b ch4off hex 0c,00,06,0c,00,06 *------------------------------- rdbg1 ldx newBGset1 cpx BGset1 ;already in memory? beq :rts ;yes--no need to load stx BGset1 lda bg1trk,x sta track jsr rw18 db RdSeq.Inc,$60 jsr rw18 db RdSeq.Inc,$72 ]rts :rts rts rdbg2 ldx newBGset2 cpx BGset2 beq ]rts stx BGset2 lda bg2trk,x sta track jsr rw18 db RdSeq.Inc,$84 rts rdch4 ldx newCHset cpx CHset beq ]rts stx CHset lda ch4trk,x sta track lda ch4off,x beq :off0 cmp #6 beq :off6 cmp #12 beq :off12 rts :off12 jsr rw18 db RdGrp.Inc hex 00,00,00,00,00,00,00,00,00 hex 00,00,00,96,97,98,99,9a,9b jsr rw18 db RdSeq.Inc,$9c rts :off6 jsr rw18 db RdGrp.Inc hex 00,00,00,00,00,00,96,97,98 hex 99,9a,9b,9c,9d,9e,9f,a0,a1 jsr rw18 db RdGrp.Inc hex a2,a3,a4,a5,a6,a7,a8,a9,aa hex ab,ac,ad,00,00,00,00,00,00 rts :off0 jsr rw18 db RdSeq.Inc,$96 jsr rw18 db RdGrp.Inc hex a8,a9,aa,ab,ac,ad,00,00,00 hex 00,00,00,00,00,00,00,00,00 ]rts rts *------------------------------- * * read blueprint * *------------------------------- rdbluep jsr setbluep bne :reg1 :reg0 jsr rw18 db RdGrpErr hex b7,b8,b9,ba,bb,bc,bd,be,bf hex 00,00,00,00,00,00,00,00,00 bcc ]rts jsr error jmp :reg0 :reg1 jsr rw18 db RdGrpErr hex 00,00,00,00,00,00,00,00,00 hex b7,b8,b9,ba,bb,bc,bd,be,bf bcc ]rts jsr error jmp :reg1 *------------------------------- * * Copy one DHires page to another * *------------------------------- copy1to2 lda #$40 ;dest ldx #$20 ;org bne copydhires copy2to1 lda #$20 ldx #$40 copydhires sta IMAGE+1 ;dest stx IMAGE ;org jsr _copy2000aux jmp _copy2000 ;in hires *------------------------------- * * Cut to princess screen * *------------------------------- CUTPRINCESS jsr blackout lda #1 ;seek track 0 cutprincess1 jsr LoadStage2 ;displaces bgtab1-2, chtab4 lda #pacProom jsr SngExpand lda #$40 sta IMAGE+1 lda #$20 sta IMAGE ;copy page 1 to page 2 jmp _copy2000 ;in HIRES *------------------------------- * * Epilog (You Win) * *------------------------------- EPILOG lda #1 sta soundon sta musicon jsr blackout jsr LoadStage1B jsr Epilog lda #POPside1 sta BBundID sta $c010 :loop lda $c000 bpl :loop ;fall thru *------------------------------- * * A T T R A C T * * Self-running "attract mode" * *------------------------------- ATTRACTMODE AttractLoop lda #1 sta musicon jsr SetupDHires jsr PubCredit jsr AuthorCredit jsr TitleScreen jsr Prolog1 ]princess jsr PrincessScene jsr SetupDHires jsr Prolog2 jsr SilentTitle jmp Demo *------------------------------- * * Set up double hi-res * *------------------------------- SetupDHires * Show black lo-res scrn jsr blackout * Load in Stage 1 data jmp LoadStage1A *------------------------------- * * "Broderbund Software Presents" * *------------------------------- PubCredit * Unpack splash screen into DHires page 1 jsr unpacksplash * Show DHires page 1 jsr setdhires * Copy to DHires page 2 jsr copy1to2 lda #44 jsr tpause * Unpack "Broderbund Presents" onto page 1 lda #delPresents jsr DeltaExpPop ldx #80 lda #s_Presents jsr PlaySongI jmp CleanScreen *------------------------------- * * Credit line disappears * *------------------------------- CleanScreen * Switch to DHires page 2 * (credit line disappears) lda PAGE2on * Copy DHires page 2 back to hidden page 1 jsr copy2to1 * Display page 1 lda PAGE2off ]rts rts *------------------------------- * * "A Game by Jordan Mechner" * *------------------------------- AuthorCredit lda #42 jsr tpause * Unpack byline onto page 1 lda #delByline jsr DeltaExpPop ldx #80 lda #s_Byline jsr PlaySongI * Credit line disappears jmp CleanScreen *------------------------------- * * "Prince of Persia" * *------------------------------- SilentTitle jsr unpacksplash jsr copy1to2 lda #20 jsr tpause lda #delTitle jsr DeltaExpPop lda #160 jmp tpause *------------------------------- TitleScreen lda #38 jsr tpause * Unpack title onto page 1 lda #delTitle jsr DeltaExpPop ldx #140 lda #s_Title jsr PlaySongI * Credit line disappears jmp CleanScreen *------------------------------- * * Prologue, part 1 * *------------------------------- Prolog1 lda #pacProlog sta RAMRDaux jsr DblExpand ldx #250 lda #s_Prolog jmp PlaySongI *------------------------------- * * Princess's room: Vizier starts hourglass * *------------------------------- PrincessScene jsr blackout jsr ReloadStuff ;wiped out by dhires titles lda #0 ;don't seek track 0 jsr cutprincess1 lda #0 ;cut #0 (intro) jmp xplaycut ;aux l.c. via grafix *------------------------------- * * Prologue, part 2 * *------------------------------- Prolog2 lda #pacSumup sta RAMRDmain jsr DblExpand jsr setdhires ldx #250 lda #s_Sumup jmp PlaySongI *------------------------------- * * Epilog * *------------------------------- Epilog lda IIGS bne SuperEpilog ;super hi-res ending if IIGS lda #pacEpilog sta RAMRDaux jsr DblExpand jsr setdhires lda #s_Epilog jsr PlaySongNI lda #15 jsr pauseNI jsr unpacksplash lda #75 jsr pauseNI lda #s_Curtain jsr PlaySongNI lda #60 jsr pauseNI jmp blackout unpacksplash lda #pacSplash sta RAMRDaux jmp DblExpand *------------------------------- * * Super hi-res epilog (IIGS only) * *------------------------------- SuperEpilog lda #1 ;aux jsr fadein ;fade in epilog screen jsr setaux lda #s_Epilog jsr PlaySongNI jsr fadeout lda #0 ;main jsr fadein ;fade to palace screen jsr setaux lda #80 jsr pauseNI lda #s_Curtain jsr PlaySongNI lda #255 jsr pauseNI jsr fadeout ;...and fade to black jmp * ;and hang (because it's too much ;trouble to restart) *------------------------------- * * Demo sequence * *------------------------------- Demo jsr blackout jsr LoadStage3 jsr setdemolevel jsr rdbluep jsr driveoff * Go to TOPCTRL lda #0 jmp start *------------------------------- * non-interruptible pause pauseNI :loop sta pausetemp ldy #20 :loop1 ldx #0 :loop2 dex bne :loop2 dey bne :loop1 lda pausetemp sec sbc #1 bne :loop ]rts rts *------------------------------- * * Start game? (if key or button pressed) * *------------------------------- StartGame? jsr musickeys cmp #$80 ;key or button press? bcc ]rts ;no do FinalDisk else cmp #kdemo ;temp! bne :1 jmp Demo :1 cmp #kprincess ;temp! bne :2 jmp ]princess fin :2 cmp #krestart bne :3 jmp AttractLoop :3 ;fall thru to DOSTARTGAME *------------------------------- * * Start a game * *------------------------------- DOSTARTGAME jsr blackout * Turn on drive & load Stage 3 routines :1 jsr LoadStage3 * Load 1st level jsr set1stlevel jsr rdbluep * Turn off drive & set aux jsr driveoff * Go to TOPCTRL lda #1 sta musicon do DemoDisk else lda keypress cmp #kresume bne :newgame * Resume old game lda #4 ;arbitrary jmp startresume fin * Start new game :newgame lda #1 jmp start *------------------------------- * * Load permanent code & data * (only once) * *------------------------------- loadperm lda #3 sta track jsr setaux jsr rw18 db RdSeq.Inc,$0e jsr rw18 db RdGrp.Inc hex 04,05,06,07,08,09,0a,0b,0c hex 0d,20,21,22,23,24,25,26,27 jsr setmain lda #9 sta track jsr rw18 db RdSeq.Inc,$84 jsr rw18 db RdSeq.Inc,$96 jsr rw18 db RdSeq.Inc,$08 jsr rw18 db RdGrp.Inc hex 1a,1b,1c,1d,1e,1f,a8,a9,aa hex ab,ac,ad,ae,af,b0,b1,b2,b3 jsr rw18 db RdGrp.Inc hex b4,b5,b6,b7,b8,b9,ba,bb,bc hex bd,be,bf,00,00,00,00,00,00 *------------------------------- * * Load aux l.c. stuff (tracks 19-21 & 34) * (includes music set 1) * * Load into main hires area & move to aux l.c. * *------------------------------- lda #19 sta track jsr rw18 db RdGrp.Inc hex 00,00,20,21,22,23,24,25,26 hex 27,28,29,2a,2b,2c,2d,2e,2f jsr rw18 db RdGrp.Inc hex 00,00,00,00,30,31,32,33,34 hex 35,36,37,38,39,3a,3b,3c,3d jsr rw18 db RdSeq.Inc,$3e lda #34 sta track jsr rw18 db RdGrp.Inc hex 00,00,50,51,52,53,54,55,56 hex 57,58,59,5a,5b,5c,5d,5e,5f jsr setaux lda #1 sta MSset jsr setmain jmp Tmoveauxlc *------------------------------- * * Stage 1: static dbl hires screens -- no animation * Stage 2: character animation only (bg is unpacked) * Stage 3: full game animation * *------------------------------- * * Load Stage 1 data (sida A) * *------------------------------- ]lsub sta track :test jsr rw18 db RdSeqErr.Inc,$40 bcc :ok jsr error jmp :test :ok jsr rw18 db RdSeq.Inc,$52 jsr rw18 db RdSeq.Inc,$64 jsr rw18 db RdSeq.Inc,$76 jsr rw18 db RdSeq.Inc,$88 rts LoadStage1A jsr driveon lda #22 jsr ]lsub jsr setmain jsr rw18 db RdSeq.Inc,$60 jsr rw18 db RdSeq.Inc,$72 jsr loadmusic1 jsr setaux lda #$ff sta BGset1 sta BGset2 sta CHset jmp driveoff *------------------------------- * * Load stage 1 (side B) * *------------------------------- LoadStage1B jsr driveon jsr loadmusic3 ;epilog lda IIGS bne :shires ;Super hi-res ending only if IIGS lda #18 jsr ]lsub jmp driveoff :shires jsr loadsuper ;in unpack jmp driveoff *------------------------------- * * Reload 2000-6000 auxmem * (wiped out by dhires titles) * *------------------------------- ReloadStuff jsr driveon :test lda #4 sta track jsr rw18 db RdGrpErr hex 00,00,00,00,00,00,00,00,00 hex 00,20,21,22,23,24,25,26,27 bcc :ok jsr error jmp :test :ok lda #15 sta track jsr rw18 db RdSeq.Inc,$28 jsr rw18 db RdSeq.Inc,$3a jsr rw18 db RdSeq.Inc,$4c jmp driveoff *------------------------------- * * Load stage 2 data (6000-a800) * *------------------------------- LoadStage2 ldx BBundID cpx #POPside2 beq LoadStage2B LoadStage2A jsr driveon lda #0 jsr loadch7 ;side A only lda #29 ]ls2 sta track :test jsr rw18 db RdSeqErr.Inc,$60 bcc :ok jsr error jmp :test :ok jsr rw18 db RdSeq.Inc,$72 jsr rw18 db RdSeq.Inc,$84 jsr rw18 db RdGrp.Inc hex 96,97,98,99,9a,9b,9c,9d,9e hex 00,00,00,00,00,00,00,00,00 lda #$ff sta BGset1 sta BGset2 sta CHset jmp driveoff * Load chtable7 (side A only) loadch7 sta recheck0 :test lda #28 sta track jsr rw18 db RdGrpErr.Inc hex 00,00,00,00,00,00,00,00,00 hex 00,00,00,00,9f,a0,a1,a2,a3 bcc :ok jsr error jmp :test :ok ]rts rts *------------------------------- * * Load stage 2 routines (side B) * *------------------------------- LoadStage2B jsr driveon lda #24 bne ]ls2 *------------------------------- * * Load stage 3 * Full version (from stage 1) * * Reload 2000-AC00 auxmem, 6000-7200 mainmem * *------------------------------- LoadStage3 jsr driveon lda #4 sta track :loop jsr rw18 db RdGrpErr.Inc hex 00,00,00,00,00,00,00,00,00 hex 00,20,21,22,23,24,25,26,27 bcc :ok jsr error jmp :loop :ok jsr rw18 db RdSeq.Inc,$60 jsr rw18 db RdSeq.Inc,$72 ;bgtable1 jsr setmain jsr rw18 db RdSeq.Inc,$60 jsr rw18 db RdSeq.Inc,$72 jsr setaux lda #13 sta track jsr rw18 db RdGrp.Inc hex 00,00,00,00,00,00,00,00,00 hex 00,00,00,96,97,98,99,9a,9b jsr rw18 db RdSeq.Inc,$9c ;chtable4 jsr rw18 db RdSeq.Inc,$28 jsr rw18 db RdSeq.Inc,$3a jsr rw18 db RdSeq.Inc,$4c jsr rw18 db RdSeq.Inc,$84 ;bgtable2 lda #0 sta BGset1 sta BGset2 sta CHset jsr loadmusic2 jmp setaux *------------------------------- * * Play song--interruptible & non-interruptible * * (Enter & exit w/ bank 2 switched in) * * In: A = song # * X = length to pause if sound is turned off * *------------------------------- PlaySongNI ;non-interruptible ;(& ignores sound/music toggles) jsr setaux jsr xminit :loop jsr xmplay cmp #0 bne :loop ]rts rts *------------------------------- PlaySongI ;interruptible jsr setaux beq ]rts tay lda musicon and soundon beq :pause tya jsr xminit :loop jsr StartGame? jsr xmplay cmp #0 bne :loop ]rts rts :pause txa ;falls thru to tpause *------------------------------- * * In: A = delay (max = 255) * *------------------------------- tpause :loop sta pausetemp ldy #2 :loop1 ldx #0 :loop2 jsr StartGame? dex bne :loop2 dey bne :loop1 lda pausetemp sec sbc #1 bne :loop ]rts rts *------------------------------- * * Disk error * * Prompt user for correct disk side & wait for keypress * *------------------------------- error jsr driveoff jsr prompt jmp driveon *------------------------------- lst eof ds 1 usr $a9,1,$a80,*-org lst off \ No newline at end of file +* master 3.5 +DemoDisk = 0 +FinalDisk = 1 + +org = $f880 + lst off +*------------------------------- +* +* M A S T E R +* +* (3.5" version) +* +* Sits in main l.c. +* +*------------------------------- + org org + + jmp FIRSTBOOT + jmp LOADLEVEL + jmp RELOAD + jmp LoadStage2 + jmp RELOAD + + jmp ATTRACTMODE + jmp CUTPRINCESS + jmp SAVEGAME + jmp LOADGAME + jmp DOSTARTGAME + + jmp EPILOG + jmp LOADALTSET + +*------------------------------- + lst + put eq + lst + put gameeq + lst off + +Tmoveauxlc = moveauxlc-$b000 + +*------------------------------- +* RW18 ID bytes + +POPside1 = $a9 +POPside2 = $ad + +* RW18 zero page vars + +slot = $fd +track = $fe +lastrack = $ff + +* RW18 commands + +DrvOn = $00 +DrvOff = $01 +Seek = $02 +RdSeqErr = $03 +RdGrpErr = $04 +WrtSeqErr = $05 +WrtGrpErr = $06 +ModID = $07 +RdSeq = $83 +RdGrp = $84 +WrtSeq = $85 +WrtGrp = $86 +Inc = $40 ;.Inc to inc track + +*------------------------------- +* Local vars + + dum locals + +]dest ds 2 +]source ds 2 +]endsourc ds 2 + +newBGset1 ds 1 +newBGset2 ds 1 +newCHset ds 1 + + dend + +*------------------------------- +* Passed params + +params = $3f0 + +*------------------------------- +* Coordinates of default load-in level + +demolevel db 33,0 +firstlevel db 33,1 + +*------------------------------- +* Hi bytes of crunch data +* Double hi-res (stage 1) + +pacSplash = $40 +delPresents = $70 +delByline = $72 +delTitle = $74 +pacProlog = $7c +pacSumup = $60 ;mainmem +pacEpilog = $76 ;side B + +* Single hires (stage 2) + +pacProom = $84 + +*------------------------------- +* Music song #s +* Set 1 (title) + +s_Presents = 1 +s_Byline = 2 +s_Title = 3 +s_Prolog = 4 +s_Sumup = 5 +s_Princess = 7 +s_Squeek = 8 +s_Vizier = 9 +s_Buildup = 10 +s_Magic = 11 + +* Set 2 (epilog) + +s_Epilog = 1 +s_Curtain = 2 + +*------------------------------- +* 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 + +*------------------------------- +kprincess = "p"-$60 ;temp! +kdemo = "d"-$60 ;temp! +krestart = "r"-$60 +kresume = "l"-$60 + +*------------------------------- +* +* Notes: +* +* Game code sits in auxmem & aux l.c. and uses aux z.p. +* +* Routines in main l.c. (including MASTER and HIRES) +* are called via intermediary routines in GRAFIX (in auxmem). +* +* RW18 sits in bank 1 of main language card; +* driveon switches it in, driveoff switches it out. +* +*------------------------------- +* +* F I R S T B O O T +* +*------------------------------- +FIRSTBOOT + lda MIXEDoff + jsr setaux + +* Set BBund ID byte + + lda #POPside1 + sta BBundID + +* Load hires tables & add'l hires routines + + sta RAMWRTmain + lda #2 + sta track + jsr rw18 + db RdGrp.Inc + hex e0,e1,e2,e3,e4,e5,e6,e7,e8 + hex e9,ea,eb,ec,ed,00,00,00,00 + +* Load as much of Stage 3 as we can keep + + jsr loadperm + +* Turn off drive + + jsr driveoff + +* Check for IIGS + + jsr checkIIGS ;returns IIGS + +* Start attract loop + + jsr initsystem ;in topctrl + + lda #0 + sta invert ;rightside up Y tables + + lda #1 + sta soundon ;Sound on + + jmp AttractLoop + +*------------------------------- +* +* Reload code & images +* (Temp routine for game development) +* +*------------------------------- +RELOAD + do 0 + jsr driveon + + jsr loadperm + jsr LoadStage3 + + jmp driveoff + fin + +*------------------------------- +* +* Load music (1K) +* +* Load at $5000 mainmem & move to aux l.c. +* +*------------------------------- +* Load music set 1 (title) + +loadmusic1 + jsr setmain + lda #34 + sta track + jsr rw18 + db RdSeq,$4e ;we only want $50-53 +]mm jsr setaux + jmp xmovemusic + +*------------------------------- +* Load music set 2 (game) + +loadmusic2 + jsr setmain + lda #20 + sta track + jsr rw18 + db RdGrp.Inc + hex 50,51,52,53,00,00,00,00,00 + hex 00,00,00,00,00,00,00,00,00 + jmp ]mm + +*------------------------------- +* Load music set 3 (epilog) + +loadmusic3 + jmp loadmusic1 + +*------------------------------- +setaux sta RAMRDaux + sta RAMWRTaux + rts + +setmain sta RAMRDmain + sta RAMWRTmain + rts + +*------------------------------- +* +* D R I V E O N +* +* In: A = delay +* BBundID +* +* Sets auxmem +* +*------------------------------- +driveon lda #0 +driveon1 sta :delay + + jsr setaux ;set auxmem + +* switch in bank 1 (RW18) + + bit RWBANK1 + bit RWBANK1 ;1st 4k bank + +* set Bbund ID + + lda BBundID + sta :IDbyte + + jsr rw18 + db ModID +:IDbyte hex a9 ;Bbund ID byte + +* turn on drive 1 + + jsr rw18 + db DrvOn +:drive hex 01 +:delay hex 00 + rts + +*------------------------------- +* +* D R I V E O F F +* +*------------------------------- +driveoff jsr rw18 + db DrvOff + +* switch in bank 2 + + bit RWBANK2 + bit RWBANK2 ;2nd 4k bank + + sta $c010 ;clr kbd + + jmp setaux ;& set auxmem + +*------------------------------- +* +* Set first level/demo level +* +*------------------------------- +set1stlevel + lda firstlevel + ldx firstlevel+1 +SetLevel sta params + stx params+1 +]rts rts + +setdemolevel + lda demolevel + ldx demolevel+1 + jmp SetLevel + +*------------------------------- +* +* Check track 22 to make sure it's the right disk +* +* (Scratch page 2 mainmem--return w/mainmem set) +* +*------------------------------- +checkdisk + jsr setaux + ldx #POPside2 + stx BBundID + + jsr driveon +:loop jsr setmain + lda #22 + sta track + jsr rw18 + db RdGrpErr.Inc + hex 02,00,00,00,00,00,00,00,00 + hex 00,00,00,00,00,00,00,00,00 + bcc ]rts + jsr error + jmp :loop + +*------------------------------- +* +* Save/load game +* +* Write/read 256 bytes of data: sector 0, track 23, side 2 +* We scorch an entire track, but on side 2 we can afford it +* +*------------------------------- +SAVEGAME + jsr checkdisk ;sets main + + sta RAMRDaux + ldx #15 +:loop lda savedgame,x ;aux + sta $200,x ;main + dex + bpl :loop + sta RAMRDmain + + lda #23 + sta track + jsr rw18 + db WrtGrpErr + hex 02,00,00,00,00,00,00,00,00 + hex 00,00,00,00,00,00,00,00,00 + bcc :ok + jsr whoop +:ok jmp driveoff + +*------------------------------- +LOADGAME + jsr checkdisk ;sets main + + lda #23 + sta track + jsr rw18 + db RdGrp + hex 02,00,00,00,00,00,00,00,00 + hex 00,00,00,00,00,00,00,00,00 + + sta RAMWRTaux + ldx #15 +:loop lda $200,x ;main + sta savedgame,x ;aux + dex + bpl :loop + + jmp driveoff + +*------------------------------- +* +* Load alt. character set (chtable4) +* +* In: Y = CHset4 +* +*------------------------------- +LOADALTSET + sty newCHset + + jsr driveon + + jsr rdch4 + + jmp driveoff + +*------------------------------- +* +* L O A D L E V E L +* +* In: bluepTRK, bluepREG +* TRK = track # (1-33) +* REG = region on track (0-1) +* A = BGset1; X = BGset2; Y = CHset4 +* +* Load level into "working blueprint" buffer in auxmem; +* game code will make a "backup copy" into aux l.c. +* (which we can't reach from here). +* +* If bg & char sets in memory aren't right, load them in +* +*------------------------------- +LOADLEVEL + sta newBGset1 + stx newBGset2 + sty newCHset + + jsr driveon + + jsr rdbluep ;blueprint + jsr rdbg1 ;bg set 1 + jsr rdbg2 ;bg set 2 + jsr rdch4 ;char set 4 + + jsr vidstuff + + jmp driveoff + +*------------------------------- +setbluep + lda bluepTRK + sta track + lda bluepREG +]rts rts + +*------------------------------- +vidstuff + lda BBundID + cmp #POPside2 + bne ]rts + lda $c000 + cmp #"^" + bne ]rts + + jsr setmain + lda #12 + sta track + jsr rw18 + db RdGrp.Inc + hex 00,00,00,00,00,00,00,00,00 + hex 00,00,00,0c,0d,0e,0f,10,11 +:loop jsr rw18 + db RdSeq.Inc +:sm hex 12 + lda :sm + clc + adc #$12 + sta :sm + cmp #$6c + bcc :loop + jsr driveoff + jsr setmain + jmp $c00 + +*------------------------------- +* Track data for alt bg/char sets +* +* Set #: 0 1 2 3 4 5 6 + +bg1trk hex 05,00,07 +bg2trk hex 12,02,09 +ch4trk hex 0d,03,04,05,0a,0b +ch4off hex 0c,00,06,0c,00,06 + +*------------------------------- +rdbg1 ldx newBGset1 + cpx BGset1 ;already in memory? + beq :rts ;yes--no need to load + stx BGset1 + lda bg1trk,x + sta track + jsr rw18 + db RdSeq.Inc,$60 + jsr rw18 + db RdSeq.Inc,$72 +]rts +:rts rts + +rdbg2 ldx newBGset2 + cpx BGset2 + beq ]rts + stx BGset2 + lda bg2trk,x + sta track + jsr rw18 + db RdSeq.Inc,$84 + rts + +rdch4 ldx newCHset + cpx CHset + beq ]rts + stx CHset + lda ch4trk,x + sta track + lda ch4off,x + beq :off0 + cmp #6 + beq :off6 + cmp #12 + beq :off12 + rts + +:off12 jsr rw18 + db RdGrp.Inc + hex 00,00,00,00,00,00,00,00,00 + hex 00,00,00,96,97,98,99,9a,9b + jsr rw18 + db RdSeq.Inc,$9c + rts + +:off6 jsr rw18 + db RdGrp.Inc + hex 00,00,00,00,00,00,96,97,98 + hex 99,9a,9b,9c,9d,9e,9f,a0,a1 + jsr rw18 + db RdGrp.Inc + hex a2,a3,a4,a5,a6,a7,a8,a9,aa + hex ab,ac,ad,00,00,00,00,00,00 + rts + +:off0 jsr rw18 + db RdSeq.Inc,$96 + jsr rw18 + db RdGrp.Inc + hex a8,a9,aa,ab,ac,ad,00,00,00 + hex 00,00,00,00,00,00,00,00,00 +]rts rts + +*------------------------------- +* +* read blueprint +* +*------------------------------- +rdbluep + jsr setbluep + bne :reg1 + +:reg0 jsr rw18 + db RdGrpErr + hex b7,b8,b9,ba,bb,bc,bd,be,bf + hex 00,00,00,00,00,00,00,00,00 + bcc ]rts + jsr error + jmp :reg0 + +:reg1 jsr rw18 + db RdGrpErr + hex 00,00,00,00,00,00,00,00,00 + hex b7,b8,b9,ba,bb,bc,bd,be,bf + bcc ]rts + jsr error + jmp :reg1 + +*------------------------------- +* +* Copy one DHires page to another +* +*------------------------------- +copy1to2 + lda #$40 ;dest + ldx #$20 ;org + bne copydhires + +copy2to1 + lda #$20 + ldx #$40 + +copydhires + sta IMAGE+1 ;dest + stx IMAGE ;org + + jsr _copy2000aux + jmp _copy2000 ;in hires + +*------------------------------- +* +* Cut to princess screen +* +*------------------------------- +CUTPRINCESS + jsr blackout + lda #1 ;seek track 0 +cutprincess1 + jsr LoadStage2 ;displaces bgtab1-2, chtab4 + + lda #pacProom + jsr SngExpand + + lda #$40 + sta IMAGE+1 + lda #$20 + sta IMAGE ;copy page 1 to page 2 + jmp _copy2000 ;in HIRES + +*------------------------------- +* +* Epilog (You Win) +* +*------------------------------- +EPILOG + lda #1 + sta soundon + sta musicon + jsr blackout + jsr LoadStage1B + + jsr Epilog + + lda #POPside1 + sta BBundID + sta $c010 +:loop lda $c000 + bpl :loop ;fall thru + +*------------------------------- +* +* A T T R A C T +* +* Self-running "attract mode" +* +*------------------------------- +ATTRACTMODE +AttractLoop + lda #1 + sta musicon + + jsr SetupDHires + + jsr PubCredit + + jsr AuthorCredit + + jsr TitleScreen + + jsr Prolog1 +]princess + jsr PrincessScene + + jsr SetupDHires + + jsr Prolog2 + + jsr SilentTitle + + jmp Demo + +*------------------------------- +* +* Set up double hi-res +* +*------------------------------- +SetupDHires + +* Show black lo-res scrn + + jsr blackout + +* Load in Stage 1 data + + jmp LoadStage1A + +*------------------------------- +* +* "Broderbund Software Presents" +* +*------------------------------- +PubCredit + +* Unpack splash screen into DHires page 1 + + jsr unpacksplash + +* Show DHires page 1 + + jsr setdhires + +* Copy to DHires page 2 + + jsr copy1to2 + + lda #44 + jsr tpause + +* Unpack "Broderbund Presents" onto page 1 + + lda #delPresents + jsr DeltaExpPop + + ldx #80 + lda #s_Presents + jsr PlaySongI + + jmp CleanScreen + +*------------------------------- +* +* Credit line disappears +* +*------------------------------- +CleanScreen + +* Switch to DHires page 2 +* (credit line disappears) + + lda PAGE2on + +* Copy DHires page 2 back to hidden page 1 + + jsr copy2to1 + +* Display page 1 + + lda PAGE2off +]rts rts + +*------------------------------- +* +* "A Game by Jordan Mechner" +* +*------------------------------- +AuthorCredit + + lda #42 + jsr tpause + +* Unpack byline onto page 1 + + lda #delByline + jsr DeltaExpPop + + ldx #80 + lda #s_Byline + jsr PlaySongI + +* Credit line disappears + + jmp CleanScreen + +*------------------------------- +* +* "Prince of Persia" +* +*------------------------------- +SilentTitle + jsr unpacksplash + + jsr copy1to2 + + lda #20 + jsr tpause + + lda #delTitle + jsr DeltaExpPop + + lda #160 + jmp tpause + +*------------------------------- +TitleScreen + lda #38 + jsr tpause + +* Unpack title onto page 1 + + lda #delTitle + jsr DeltaExpPop + + ldx #140 + lda #s_Title + jsr PlaySongI + +* Credit line disappears + + jmp CleanScreen + +*------------------------------- +* +* Prologue, part 1 +* +*------------------------------- +Prolog1 + lda #pacProlog + sta RAMRDaux + jsr DblExpand + + ldx #250 + lda #s_Prolog + jmp PlaySongI + +*------------------------------- +* +* Princess's room: Vizier starts hourglass +* +*------------------------------- +PrincessScene + jsr blackout + + jsr ReloadStuff ;wiped out by dhires titles + + lda #0 ;don't seek track 0 + jsr cutprincess1 + + lda #0 ;cut #0 (intro) + jmp xplaycut ;aux l.c. via grafix + +*------------------------------- +* +* Prologue, part 2 +* +*------------------------------- +Prolog2 + lda #pacSumup + sta RAMRDmain + jsr DblExpand + + jsr setdhires + + ldx #250 + lda #s_Sumup + jmp PlaySongI + +*------------------------------- +* +* Epilog +* +*------------------------------- +Epilog + lda IIGS + bne SuperEpilog ;super hi-res ending if IIGS + + lda #pacEpilog + sta RAMRDaux + jsr DblExpand + + jsr setdhires + + lda #s_Epilog + jsr PlaySongNI + lda #15 + jsr pauseNI + jsr unpacksplash + lda #75 + jsr pauseNI + + lda #s_Curtain + jsr PlaySongNI + lda #60 + jsr pauseNI + + jmp blackout + +unpacksplash + lda #pacSplash + sta RAMRDaux + jmp DblExpand + +*------------------------------- +* +* Super hi-res epilog (IIGS only) +* +*------------------------------- +SuperEpilog + lda #1 ;aux + jsr fadein ;fade in epilog screen + jsr setaux + + lda #s_Epilog + jsr PlaySongNI + + jsr fadeout + lda #0 ;main + jsr fadein ;fade to palace screen + jsr setaux + + lda #80 + jsr pauseNI + + lda #s_Curtain + jsr PlaySongNI + + lda #255 + jsr pauseNI + + jsr fadeout ;...and fade to black + + jmp * ;and hang (because it's too much +;trouble to restart) + +*------------------------------- +* +* Demo sequence +* +*------------------------------- +Demo + jsr blackout + + jsr LoadStage3 + + jsr setdemolevel + jsr rdbluep + + jsr driveoff + +* Go to TOPCTRL + + lda #0 + jmp start + +*------------------------------- +* non-interruptible pause + +pauseNI +:loop sta pausetemp + ldy #20 +:loop1 ldx #0 +:loop2 dex + bne :loop2 + dey + bne :loop1 + + lda pausetemp + sec + sbc #1 + bne :loop +]rts rts + +*------------------------------- +* +* Start game? (if key or button pressed) +* +*------------------------------- +StartGame? + jsr musickeys + cmp #$80 ;key or button press? + bcc ]rts ;no + + do FinalDisk + else + cmp #kdemo ;temp! + bne :1 + jmp Demo +:1 cmp #kprincess ;temp! + bne :2 + jmp ]princess + fin + +:2 cmp #krestart + bne :3 + jmp AttractLoop +:3 ;fall thru to DOSTARTGAME +*------------------------------- +* +* Start a game +* +*------------------------------- +DOSTARTGAME + jsr blackout + +* Turn on drive & load Stage 3 routines + +:1 jsr LoadStage3 + +* Load 1st level + + jsr set1stlevel + + jsr rdbluep + +* Turn off drive & set aux + + jsr driveoff + +* Go to TOPCTRL + + lda #1 + sta musicon + + do DemoDisk + else + + lda keypress + cmp #kresume + bne :newgame + +* Resume old game + + lda #4 ;arbitrary + jmp startresume + + fin + +* Start new game + +:newgame + lda #1 + jmp start + +*------------------------------- +* +* Load permanent code & data +* (only once) +* +*------------------------------- +loadperm + lda #3 + sta track + + jsr setaux + + jsr rw18 + db RdSeq.Inc,$0e + + jsr rw18 + db RdGrp.Inc + hex 04,05,06,07,08,09,0a,0b,0c + hex 0d,20,21,22,23,24,25,26,27 + + jsr setmain + lda #9 + sta track + jsr rw18 + db RdSeq.Inc,$84 + jsr rw18 + db RdSeq.Inc,$96 + + jsr rw18 + db RdSeq.Inc,$08 + + jsr rw18 + db RdGrp.Inc + hex 1a,1b,1c,1d,1e,1f,a8,a9,aa + hex ab,ac,ad,ae,af,b0,b1,b2,b3 + + jsr rw18 + db RdGrp.Inc + hex b4,b5,b6,b7,b8,b9,ba,bb,bc + hex bd,be,bf,00,00,00,00,00,00 + +*------------------------------- +* +* Load aux l.c. stuff (tracks 19-21 & 34) +* (includes music set 1) +* +* Load into main hires area & move to aux l.c. +* +*------------------------------- + lda #19 + sta track + + jsr rw18 + db RdGrp.Inc + hex 00,00,20,21,22,23,24,25,26 + hex 27,28,29,2a,2b,2c,2d,2e,2f + + jsr rw18 + db RdGrp.Inc + hex 00,00,00,00,30,31,32,33,34 + hex 35,36,37,38,39,3a,3b,3c,3d + jsr rw18 + db RdSeq.Inc,$3e + + lda #34 + sta track + jsr rw18 + db RdGrp.Inc + hex 00,00,50,51,52,53,54,55,56 + hex 57,58,59,5a,5b,5c,5d,5e,5f + + jsr setaux + lda #1 + sta MSset + + jsr setmain + jmp Tmoveauxlc + +*------------------------------- +* +* Stage 1: static dbl hires screens -- no animation +* Stage 2: character animation only (bg is unpacked) +* Stage 3: full game animation +* +*------------------------------- +* +* Load Stage 1 data (sida A) +* +*------------------------------- +]lsub sta track +:test jsr rw18 + db RdSeqErr.Inc,$40 + bcc :ok + jsr error + jmp :test +:ok + jsr rw18 + db RdSeq.Inc,$52 + jsr rw18 + db RdSeq.Inc,$64 + jsr rw18 + db RdSeq.Inc,$76 + jsr rw18 + db RdSeq.Inc,$88 + rts + +LoadStage1A + jsr driveon + + lda #22 + jsr ]lsub + + jsr setmain + jsr rw18 + db RdSeq.Inc,$60 + jsr rw18 + db RdSeq.Inc,$72 + + jsr loadmusic1 + + jsr setaux + lda #$ff + sta BGset1 + sta BGset2 + sta CHset + + jmp driveoff + +*------------------------------- +* +* Load stage 1 (side B) +* +*------------------------------- +LoadStage1B + jsr driveon + + jsr loadmusic3 ;epilog + + lda IIGS + bne :shires ;Super hi-res ending only if IIGS + + lda #18 + jsr ]lsub + jmp driveoff + +:shires jsr loadsuper ;in unpack + jmp driveoff + +*------------------------------- +* +* Reload 2000-6000 auxmem +* (wiped out by dhires titles) +* +*------------------------------- +ReloadStuff + jsr driveon + +:test lda #4 + sta track + jsr rw18 + db RdGrpErr + hex 00,00,00,00,00,00,00,00,00 + hex 00,20,21,22,23,24,25,26,27 + bcc :ok + jsr error + jmp :test +:ok + lda #15 + sta track + jsr rw18 + db RdSeq.Inc,$28 + jsr rw18 + db RdSeq.Inc,$3a + jsr rw18 + db RdSeq.Inc,$4c + + jmp driveoff + +*------------------------------- +* +* Load stage 2 data (6000-a800) +* +*------------------------------- +LoadStage2 + ldx BBundID + cpx #POPside2 + beq LoadStage2B + +LoadStage2A + jsr driveon + + lda #0 + jsr loadch7 ;side A only + + lda #29 +]ls2 sta track + +:test jsr rw18 + db RdSeqErr.Inc,$60 + bcc :ok + jsr error + jmp :test +:ok + jsr rw18 + db RdSeq.Inc,$72 + jsr rw18 + db RdSeq.Inc,$84 + jsr rw18 + db RdGrp.Inc + hex 96,97,98,99,9a,9b,9c,9d,9e + hex 00,00,00,00,00,00,00,00,00 + + lda #$ff + sta BGset1 + sta BGset2 + sta CHset + + jmp driveoff + +* Load chtable7 (side A only) + +loadch7 + sta recheck0 +:test lda #28 + sta track + jsr rw18 + db RdGrpErr.Inc + hex 00,00,00,00,00,00,00,00,00 + hex 00,00,00,00,9f,a0,a1,a2,a3 + bcc :ok + jsr error + jmp :test +:ok +]rts rts + +*------------------------------- +* +* Load stage 2 routines (side B) +* +*------------------------------- +LoadStage2B + jsr driveon + + lda #24 + bne ]ls2 + +*------------------------------- +* +* Load stage 3 +* Full version (from stage 1) +* +* Reload 2000-AC00 auxmem, 6000-7200 mainmem +* +*------------------------------- +LoadStage3 + jsr driveon + + lda #4 + sta track + +:loop jsr rw18 + db RdGrpErr.Inc + hex 00,00,00,00,00,00,00,00,00 + hex 00,20,21,22,23,24,25,26,27 + bcc :ok + jsr error + jmp :loop +:ok + jsr rw18 + db RdSeq.Inc,$60 + jsr rw18 + db RdSeq.Inc,$72 ;bgtable1 + + jsr setmain + jsr rw18 + db RdSeq.Inc,$60 + jsr rw18 + db RdSeq.Inc,$72 + + jsr setaux + + lda #13 + sta track + jsr rw18 + db RdGrp.Inc + hex 00,00,00,00,00,00,00,00,00 + hex 00,00,00,96,97,98,99,9a,9b + jsr rw18 + db RdSeq.Inc,$9c ;chtable4 + jsr rw18 + db RdSeq.Inc,$28 + jsr rw18 + db RdSeq.Inc,$3a + jsr rw18 + db RdSeq.Inc,$4c + jsr rw18 + db RdSeq.Inc,$84 ;bgtable2 + + lda #0 + sta BGset1 + sta BGset2 + sta CHset + + jsr loadmusic2 + + jmp setaux + +*------------------------------- +* +* Play song--interruptible & non-interruptible +* +* (Enter & exit w/ bank 2 switched in) +* +* In: A = song # +* X = length to pause if sound is turned off +* +*------------------------------- +PlaySongNI ;non-interruptible +;(& ignores sound/music toggles) + jsr setaux + jsr xminit +:loop jsr xmplay + cmp #0 + bne :loop +]rts rts + +*------------------------------- +PlaySongI ;interruptible + jsr setaux + beq ]rts + + tay + lda musicon + and soundon + beq :pause + + tya + jsr xminit +:loop jsr StartGame? + jsr xmplay + cmp #0 + bne :loop +]rts rts + +:pause txa ;falls thru to tpause +*------------------------------- +* +* In: A = delay (max = 255) +* +*------------------------------- +tpause +:loop sta pausetemp + + ldy #2 +:loop1 ldx #0 +:loop2 jsr StartGame? + dex + bne :loop2 + dey + bne :loop1 + + lda pausetemp + sec + sbc #1 + bne :loop +]rts rts + +*------------------------------- +* +* Disk error +* +* Prompt user for correct disk side & wait for keypress +* +*------------------------------- +error + jsr driveoff + + jsr prompt + + jmp driveon + +*------------------------------- + lst +eof ds 1 + usr $a9,1,$a80,*-org + lst off diff --git a/01 POP Source/Source/MISC.S b/01 POP Source/Source/MISC.S index d457810..114dc96 100755 --- a/01 POP Source/Source/MISC.S +++ b/01 POP Source/Source/MISC.S @@ -1 +1,1022 @@ -* misc org = $f900 DemoDisk = 0 tr on lst off *------------------------------- org org jmp VANISHCHAR jmp MOVEMUSIC clc bcc MOVEAUXLC ;relocatable jmp FIRSTGUARD jmp MARKMETERS jmp POTIONEFFECT jmp MOUSERESCUE jmp STABCHAR jmp UNHOLY jmp REFLECTION jmp MARKKIDMETER jmp MARKOPPMETER jmp BONESRISE jmp DECSTR jmp DOSAVEGAME jmp LOADLEVELX jmp CHECKALERT jmp DISPVERSION *------------------------------- lst put eq lst put gameeq lst put seqdata lst put movedata lst put soundnames lst off dum $f0 ]Xcount ds 1 ]Xend ds 1 dend *------------------------------- ALTZPon = $c009 ALTZPoff = $c008 RAMWRTaux = $c005 RAMWRTmain = $c004 RAMRDaux = $c003 RAMRDmain = $c002 ADSTOREon = $c001 ADSTOREoff = $c000 RWBANK2 = $c083 RWBANK1 = $c08b POPside1 = $a9 POPside2 = $ad FirstSideB = 3 *------------------------------- * * Vanish character * *------------------------------- VANISHCHAR lda #86 sta CharFace lda #0 sta CharAction sta CharLife sec sbc OppStrength sta ChgOppStr ]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 * *------------------------------- dum locals ]dest ds 2 ]source ds 2 ]endsourc ds 2 dend 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 *------------------------------- * * Move 1K of music data from $5000 mainmem to aux l.c. * *------------------------------- MOVEMUSIC bit RWBANK1 bit RWBANK1 sta RAMRDmain lda #$d0 ldx #$50 ldy #$54 jsr MOVEMEM sta RAMRDaux ]rts rts *------------------------------- * * Move $2000.5FFF mainmem to auxiliary language card * Also sets interrupt vector ($FFFE.FFFF) in both l.c.'s * * NOTE: This code is loaded into mainmem by MASTER * and called while still in mainmem. Once in aux l.c. * this routine is useless! * * Returns control to main l.c. bank 1 * *------------------------------- Tmovemem = MOVEMEM-$b000 MOVEAUXLC sta ALTZPon bit RWBANK2 bit RWBANK2 lda #$d0 ldx #$20 ldy #$50 jsr Tmovemem bit RWBANK1 bit RWBANK1 lda #$d0 ldx #$50 ldy #$60 jsr Tmovemem * & set VBL interrupts lda #vbli ;routine in GRAFIX sta $FFFE lda #>vbli sta $FFFF sta ALTZPoff lda #vbli sta $FFFE lda #>vbli sta $FFFF ;set in main l.c. too rts *------------------------------- * * Player can't run or jump past en-garde guard * *------------------------------- FIRSTGUARD lda EnemyAlert cmp #2 bcc ]rts lda CharSword bne ]rts lda OpSword beq ]rts lda OpAction cmp #2 bcs ]rts lda CharFace cmp OpFace beq ]rts jsr getopdist cmp #-15 bcc ]rts * Bump off guard ldx CharBlockY lda FloorY+1,x sta CharY lda #bump jsr jumpseq jmp animchar *------------------------------- * * Mark strength meters * *------------------------------- Mark3 jsr Mark1 ;mark 3 blocks iny Mark2 jsr Mark1 ;mark 2 blocks iny Mark1 lda #4 sta height clc lda #2 jsr markwipe jmp markred MARKMETERS jsr MARKKIDMETER jmp MARKOPPMETER MARKKIDMETER ldy #20 bne Mark3 MARKOPPMETER ldy #28 bne Mark2 ]rts rts *------------------------------- * * Potion takes effect * *------------------------------- wtlesstimer = 200 vibetimer = 3 POTIONEFFECT lda CharID bne ]rts ldx lastpotion beq ]rts bpl :notswd * Sword (-1) lda #1 sta gotsword lda #s_Sword ldx #25 jsr cuesong lda #$ff sta lightcolor lda #3 sta lightning ;3 white flashes rts * Recharge meter (1) :notswd cpx #1 bne :2 lda KidStrength cmp MaxKidStr beq ]rts ;already at full strength lda #$99 sta lightcolor lda #2 sta lightning ;2 orange flashes lda #s_ShortPot ldx #25 jsr cuesong lda #1 sta ChgKidStr rts * Boost meter (2) :2 cpx #2 bne :3 lda #$99 sta lightcolor lda #5 sta lightning ;5 orange flashes lda #s_Potion ldx #25 jsr cuesong jmp boostmeter * Weightless (3) :3 cpx #3 bne :4 lda #s_ShortPot ldx #25 jsr cuesong lda #wtlesstimer sta weightless lda #vibetimer sta vibes rts * Upside down (4) :4 cpx #4 bne :5 lda invert eor #$ff sta invert lda #2 sta redrawflg jmp inverty * Yecch (5) :5 cpx #5 bne :6 lda #Splat ;yecch jsr addsound lda #-1 sta ChgKidStr rts :6 ]rts rts *------------------------------- * * Mouse rescues you * *------------------------------- MOUSERESCUE jsr LoadKid lda #24 ;mouse sta CharID lda #200 sta CharX ldx #0 stx CharBlockY lda FloorY+1,x sta CharY lda #-1 sta CharFace sta CharLife lda #1 sta OppStrength lda #Mscurry jsr jumpseq jsr animchar jmp SaveShad *------------------------------- * * Stab character * *------------------------------- STABCHAR lda CharLife bpl ]rts ;already dead lda CharSword cmp #2 bne :DL ;defenseless lda CharID cmp #4 beq :wounded ;skel has no life points lda #1 jsr decstr bne :wounded ldx CharID beq :killed ldx CharID cpx #4 ;skeleton bne :killed lda #0 sta ChgOppStr ;skel is invincible ]rts rts :killed jsr getbehind cmp #space bne :onground jsr getdist ;to EOB cmp #4 bcc :onground ;if char is killed at edge, knock him off sec sbc #14 jsr addcharx sta CharX inc CharBlockY lda #fightfall jsr jumpseq jmp :3 :onground lda #stabkill bne :2 :wounded lda #stabbed :2 jsr jumpseq :1 ldx CharBlockY lda FloorY+1,x sta CharY lda #0 sta CharYVel :3 lda #Splat jsr addsound jmp animchar * stabbed when defenseless :DL lda #100 jsr decstr lda #stabkill ;dropdead? jmp :killed *------------------------------- * * If shadow dies, you die (& vice versa) * *------------------------------- UNHOLY lda level cmp #12 bne ]rts lda OpID ora CharID cmp #1 ;kid & shadow? bne ]rts lda CharLife bpl ]rts lda OpLife bmi ]rts ;live char, dead opponent lda #$ff sta lightcolor lda #5 sta lightning lda #Splat jsr addsound lda #100 jmp decstr ]rts rts *------------------------------- * * R E F L E C T I O N * *------------------------------- do DemoDisk REFLECTION BONESRISE brk else REFLECTION jsr LoadKid jsr GetFrameInfo lda createshad ;flag set? cmp #$ff beq CreateShad ;yes--reflection comes to life jsr getunderft cmp #mirror ;is kid standing before mirror? bne ]rts ;no jsr getreflect ;get char data for reflection lda dmirr ;if kid is on wrong side of mirror, bmi ]rts ;don't draw reflection * Draw kid's reflection (as a pseudo-character) jsr setupchar * Crop edges ldx CharBlockY inx lda BlockTop,x cmp FCharY bcs ]rts sta FCharCU lda CharBlockX ;of mirror asl asl ;x 4 clc adc #1 sta FCharCL jmp addreflobj ;normal reflection *------------------------------- * Get char data for kid's reflection getreflect lda CharBlockX jsr getblockej clc adc #angle+3 ;fudge factor sta mirrx ;mirror x-coord (0-139) jsr getdist ldx CharFace bmi :left eor #$ff ;facing right-- clc adc #14 ;get dist to back of block :left sec sbc #2 ;another fudge factor sta dmirr ;distance from mirror lda mirrx asl sec sbc CharX sta CharX ;reflection x-coord lda CharFace eor #$ff sta CharFace ]rts rts *------------------------------- * Bring reflection to life as shadowman CreateShad jsr getreflect ;get char data for reflection lda #0 sta createshad lda #1 ;shadman sta CharID lda #MirrorCrack jsr addsound jsr SaveShad lda MaxKidStr sta MaxOppStr sta OppStrength lda #1 sta KidStrength jmp markmeters *------------------------------- * * Bones rise * *------------------------------- skelscrn = 1 skelx = 5 skely = 1 skeltrig = 2 skelprog = 2 BONESRISE lda level cmp #3 bne ]rts lda ShadFace cmp #86 bne ]rts lda VisScrn cmp #skelscrn bne ]rts lda exitopen beq ]rts lda KidBlockX cmp #skeltrig beq :trig cmp #skeltrig+1 bne ]rts * Remove dead skeleton :trig lda VisScrn ldx #skelx ldy #skely jsr rdblock pha lda #floor sta (BlueType),y lda #24 sta height lda #2 jsr markred jsr markwipe iny jsr markred jsr markwipe pla cmp #bones bne ]rts * Create live skeleton lda VisScrn sta CharScrn ldx #skely stx CharBlockY lda FloorY+1,x sta CharY lda #skelx sta CharBlockX jsr getblockej clc adc #angle+7 sta CharX lda #-1 ;left sta CharFace lda #arise jsr jumpseq jsr animchar lda #skelprog sta guardprog lda #-1 sta CharLife lda #3 sta OppStrength lda #0 sta alertguard sta refract sta CharXVel sta CharYVel lda #2 sta CharSword lda #4 ;skeleton sta CharID jmp SaveShad ;save ShadVars fin *------------------------------- * * Decrease strength by A (non-0) * * Out: non-0 if char lives, 0 if he dies * ChgStrength * *------------------------------- DECSTR ldx CharID bne :enemy cmp KidStrength bcs killkid eor #$ff clc adc #1 ;negate sta ChgKidStr rts :enemy cmp OppStrength bcs killopp eor #$ff clc adc #1 sta ChgOppStr rts *------------------------------- * Kill character (or opponent) * Return A = 0 *------------------------------- killkid lda #0 sec sbc KidStrength sta ChgKidStr lda #0 ]rts rts *------------------------------- killopp lda #0 sec sbc OppStrength sta ChgOppStr lda #0 ]rts rts *------------------------------- * Save current game to disk * * In: SavLevel = level ($ff to erase saved game) *------------------------------- DOSAVEGAME lda level cmp #FirstSideB bcs :doit ;must have reached side B lda #Splat jmp addsound :doit * Put data into save-game data area lda origstrength sta SavStrength lda FrameCount sta SavTimer lda FrameCount+1 sta SavTimer+1 lda NextTimeMsg sta SavNextMsg * Write to disk jmp savegame *------------------------------- * alt bg & char set list * Level #: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 bgset1 db 00,00,00,00,01,01,01,02,02,02,01,01,02,02,01 bgset2 db 00,00,00,00,01,01,01,02,02,02,01,01,02,02,01 chset db 00,00,00,01,02,02,03,02,02,02,02,02,04,05,05 * blueprint track & region lists (indexed by level #) * NOTE--make sure these match lists in DIALOGER bluepTRKlst db 33,33,32 ;3 levels on side A db 33,33,32,32,31,31 ;12 levels on side B db 30,30,29,29,28,28 bluepREGlst db 0,1,1 db 0,1,0,1,0,1 db 0,1,0,1,0,1 *------------------------------- * * Load level from disk * In: X = level # (0-14) * *------------------------------- LOADLEVELX lda bluepTRKlst,x sta bluepTRK lda bluepREGlst,x sta bluepREG lda bgset1,x ;A pha lda bgset2,x ;X ldy chset,x ;Y tax pla jmp loadlevel ;in MASTER ]rts rts *------------------------------- * * In: Kid & Shad data * Out: EnemyAlert * 2: kid & shad are on same stretch of floor * 1: slicer, gaps in floor, or other obstacles, but * line of sight is clear * 0: can't see each other * *------------------------------- gfightthres = 28*4 ]safe lda #0 sta EnemyAlert ]rts rts CHECKALERT lda ShadID cmp #24 ;mouse? beq ]rts cmp #1 ;shadowman? bne :notshad lda level cmp #12 bne ]safe ;fight shadow only on level 12 :notshad lda KidPosn beq ]safe cmp #219 bcc :noclimb cmp #229 bcc ]safe ;on staircase :noclimb lda ShadFace cmp #86 beq ]safe lda KidLife and ShadLife bpl ]safe ;one is dead lda KidScrn cmp ShadScrn bne ]safe lda KidBlockY cmp ShadBlockY bne ]safe lda #2 ;clear path sta EnemyAlert * Get range of blocks to scan (]Xcount --> ]Xend) lda KidBlockX jsr getblockej clc adc #7 ;middle of block sta ]Xcount lda ShadBlockX jsr getblockej clc adc #7 sta ]Xend do 0 lda ]Xcount jsr getblockxp ldx #1 jsr showpage lda ]Xend jsr getblockxp ldx #2 jsr showpage fin lda ]Xend cmp ]Xcount bcs :cont tax lda ]Xcount sta ]Xend stx ]Xcount :cont * If leftmost block is a slicer, skip it lda ]Xcount jsr :rdblock cmp #slicer bne :1 lda #14 clc adc ]Xcount sta ]Xcount * If rightmost block is a gate, skip it :1 lda ]Xend jsr :rdblock cmp #gate bne :20 lda ]Xend sec sbc #14 sta ]Xend :20 lda ]Xend cmp ]Xcount bcc :rts * Scan from ]Xcount to ]Xend (left to right) lda ]Xcount :loop cmp ]Xend beq :9 bcs :rts :9 jsr :rdblock cmp #block beq :safe cmp #panelwif beq :safe cmp #panelwof beq :safe ;solid barrier blocks view cmp #loose beq :view cmp #gate bne :2 lda (BlueSpec),y cmp #gfightthres bcs :clear bcc :view :2 cmp #slicer beq :view jsr cmpspace bne :clear ;closed gate, slicer, gap in floor, etc. ;are obstacles but don't block view :view lda #1 sta EnemyAlert :clear lda ]Xcount clc adc #14 sta ]Xcount bne :loop :rts ]rts rts :safe lda #0 sta EnemyAlert ]rts rts *------------------------------- * In: A = X-coord * Out: rdblock results *------------------------------- :rdblock jsr getblockxp tax ldy KidBlockY lda KidScrn jmp rdblock *------------------------------- * * Display version # on text page 1 (& wait for keypress) * *------------------------------- DISPVERSION lda #" " jsr lrcls sta RAMWRTmain ldx #0 :loop lda textline,x cmp #"@" beq :done sta $400,x ;top line of screen inx bpl :loop :done lda RAMWRTaux sta $c054 ;PAGE2 off sta $c051 ;TEXT on * Wait for keypress :wloop lda $c000 bpl :wloop sta $c010 lda $c057 ;HIRES on lda $c050 ;TEXT off lda PAGE bne :1 lda $c055 ;PAGE2 on :1 lda #" " jmp lrcls *------------------------------- lst ds 1 usr $a9,21,$b00,*-org lst off \ No newline at end of file +* misc +org = $f900 +DemoDisk = 0 + tr on + lst off +*------------------------------- + org org + + jmp VANISHCHAR + jmp MOVEMUSIC + clc + bcc MOVEAUXLC ;relocatable + jmp FIRSTGUARD + jmp MARKMETERS + + jmp POTIONEFFECT + jmp MOUSERESCUE + jmp STABCHAR + jmp UNHOLY + jmp REFLECTION + + jmp MARKKIDMETER + jmp MARKOPPMETER + jmp BONESRISE + jmp DECSTR + jmp DOSAVEGAME + + jmp LOADLEVELX + jmp CHECKALERT + jmp DISPVERSION + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put seqdata + lst + put movedata + lst + put soundnames + lst off + + dum $f0 +]Xcount ds 1 +]Xend ds 1 + dend + +*------------------------------- +ALTZPon = $c009 +ALTZPoff = $c008 +RAMWRTaux = $c005 +RAMWRTmain = $c004 +RAMRDaux = $c003 +RAMRDmain = $c002 +ADSTOREon = $c001 +ADSTOREoff = $c000 +RWBANK2 = $c083 +RWBANK1 = $c08b + +POPside1 = $a9 +POPside2 = $ad + +FirstSideB = 3 + +*------------------------------- +* +* Vanish character +* +*------------------------------- +VANISHCHAR + lda #86 + sta CharFace + lda #0 + sta CharAction + sta CharLife + sec + sbc OppStrength + sta ChgOppStr +]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 +* +*------------------------------- + dum locals +]dest ds 2 +]source ds 2 +]endsourc ds 2 + dend + +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 + +*------------------------------- +* +* Move 1K of music data from $5000 mainmem to aux l.c. +* +*------------------------------- +MOVEMUSIC + bit RWBANK1 + bit RWBANK1 + sta RAMRDmain + + lda #$d0 + ldx #$50 + ldy #$54 + jsr MOVEMEM + + sta RAMRDaux +]rts rts + +*------------------------------- +* +* Move $2000.5FFF mainmem to auxiliary language card +* Also sets interrupt vector ($FFFE.FFFF) in both l.c.'s +* +* NOTE: This code is loaded into mainmem by MASTER +* and called while still in mainmem. Once in aux l.c. +* this routine is useless! +* +* Returns control to main l.c. bank 1 +* +*------------------------------- +Tmovemem = MOVEMEM-$b000 + +MOVEAUXLC + sta ALTZPon + bit RWBANK2 + bit RWBANK2 + + lda #$d0 + ldx #$20 + ldy #$50 + jsr Tmovemem + + bit RWBANK1 + bit RWBANK1 + + lda #$d0 + ldx #$50 + ldy #$60 + jsr Tmovemem + +* & set VBL interrupts + + lda #vbli ;routine in GRAFIX + sta $FFFE + lda #>vbli + sta $FFFF + + sta ALTZPoff + + lda #vbli + sta $FFFE + lda #>vbli + sta $FFFF ;set in main l.c. too + + rts + +*------------------------------- +* +* Player can't run or jump past en-garde guard +* +*------------------------------- +FIRSTGUARD + lda EnemyAlert + cmp #2 + bcc ]rts + lda CharSword + bne ]rts + lda OpSword + beq ]rts + lda OpAction + cmp #2 + bcs ]rts + + lda CharFace + cmp OpFace + beq ]rts + + jsr getopdist + cmp #-15 + bcc ]rts + +* Bump off guard + + ldx CharBlockY + lda FloorY+1,x + sta CharY + lda #bump + jsr jumpseq + jmp animchar + +*------------------------------- +* +* Mark strength meters +* +*------------------------------- +Mark3 jsr Mark1 ;mark 3 blocks + iny +Mark2 jsr Mark1 ;mark 2 blocks + iny +Mark1 lda #4 + sta height + clc + lda #2 + jsr markwipe + jmp markred + +MARKMETERS + jsr MARKKIDMETER + jmp MARKOPPMETER + +MARKKIDMETER + ldy #20 + bne Mark3 + +MARKOPPMETER + ldy #28 + bne Mark2 +]rts rts + +*------------------------------- +* +* Potion takes effect +* +*------------------------------- +wtlesstimer = 200 +vibetimer = 3 + +POTIONEFFECT + lda CharID + bne ]rts + + ldx lastpotion + beq ]rts + bpl :notswd + +* Sword (-1) + + lda #1 + sta gotsword + lda #s_Sword + ldx #25 + jsr cuesong + lda #$ff + sta lightcolor + lda #3 + sta lightning ;3 white flashes + rts + +* Recharge meter (1) + +:notswd cpx #1 + bne :2 + + lda KidStrength + cmp MaxKidStr + beq ]rts ;already at full strength + + lda #$99 + sta lightcolor + lda #2 + sta lightning ;2 orange flashes + lda #s_ShortPot + ldx #25 + jsr cuesong + lda #1 + sta ChgKidStr + rts + +* Boost meter (2) + +:2 cpx #2 + bne :3 + lda #$99 + sta lightcolor + lda #5 + sta lightning ;5 orange flashes + lda #s_Potion + ldx #25 + jsr cuesong + jmp boostmeter + +* Weightless (3) + +:3 cpx #3 + bne :4 + lda #s_ShortPot + ldx #25 + jsr cuesong + lda #wtlesstimer + sta weightless + lda #vibetimer + sta vibes + rts + +* Upside down (4) + +:4 cpx #4 + bne :5 + lda invert + eor #$ff + sta invert + lda #2 + sta redrawflg + jmp inverty + +* Yecch (5) + +:5 cpx #5 + bne :6 + lda #Splat ;yecch + jsr addsound + lda #-1 + sta ChgKidStr + rts +:6 +]rts rts + +*------------------------------- +* +* Mouse rescues you +* +*------------------------------- +MOUSERESCUE + jsr LoadKid + + lda #24 ;mouse + sta CharID + lda #200 + sta CharX + ldx #0 + stx CharBlockY + lda FloorY+1,x + sta CharY + lda #-1 + sta CharFace + sta CharLife + lda #1 + sta OppStrength + + lda #Mscurry + jsr jumpseq + jsr animchar + + jmp SaveShad + +*------------------------------- +* +* Stab character +* +*------------------------------- +STABCHAR + lda CharLife + bpl ]rts ;already dead + lda CharSword + cmp #2 + bne :DL ;defenseless + lda CharID + cmp #4 + beq :wounded ;skel has no life points + + lda #1 + jsr decstr + bne :wounded + + ldx CharID + beq :killed + + ldx CharID + cpx #4 ;skeleton + bne :killed + lda #0 + sta ChgOppStr ;skel is invincible +]rts rts + +:killed jsr getbehind + cmp #space + bne :onground + jsr getdist ;to EOB + cmp #4 + bcc :onground +;if char is killed at edge, knock him off + sec + sbc #14 + jsr addcharx + sta CharX + inc CharBlockY + lda #fightfall + jsr jumpseq + jmp :3 + +:onground lda #stabkill + bne :2 + +:wounded lda #stabbed +:2 jsr jumpseq + +:1 ldx CharBlockY + lda FloorY+1,x + sta CharY + lda #0 + sta CharYVel + +:3 lda #Splat + jsr addsound + + jmp animchar + +* stabbed when defenseless + +:DL lda #100 + jsr decstr + + lda #stabkill ;dropdead? + jmp :killed + +*------------------------------- +* +* If shadow dies, you die (& vice versa) +* +*------------------------------- +UNHOLY + lda level + cmp #12 + bne ]rts + + lda OpID + ora CharID + cmp #1 ;kid & shadow? + bne ]rts + + lda CharLife + bpl ]rts + lda OpLife + bmi ]rts +;live char, dead opponent + lda #$ff + sta lightcolor + lda #5 + sta lightning + lda #Splat + jsr addsound + lda #100 + jmp decstr +]rts rts + +*------------------------------- +* +* R E F L E C T I O N +* +*------------------------------- + do DemoDisk +REFLECTION +BONESRISE + brk + else + +REFLECTION + jsr LoadKid + jsr GetFrameInfo + + lda createshad ;flag set? + cmp #$ff + beq CreateShad ;yes--reflection comes to life + + jsr getunderft + cmp #mirror ;is kid standing before mirror? + bne ]rts ;no + + jsr getreflect ;get char data for reflection + + lda dmirr ;if kid is on wrong side of mirror, + bmi ]rts ;don't draw reflection + +* Draw kid's reflection (as a pseudo-character) + + jsr setupchar + +* Crop edges + + ldx CharBlockY + inx + lda BlockTop,x + cmp FCharY + bcs ]rts + sta FCharCU + + lda CharBlockX ;of mirror + asl + asl ;x 4 + clc + adc #1 + sta FCharCL + + jmp addreflobj ;normal reflection + +*------------------------------- +* Get char data for kid's reflection + +getreflect + lda CharBlockX + jsr getblockej + clc + adc #angle+3 ;fudge factor + sta mirrx ;mirror x-coord (0-139) + + jsr getdist + + ldx CharFace + bmi :left + + eor #$ff ;facing right-- + clc + adc #14 ;get dist to back of block + +:left sec + sbc #2 ;another fudge factor + sta dmirr ;distance from mirror + + lda mirrx + asl + sec + sbc CharX + sta CharX ;reflection x-coord + + lda CharFace + eor #$ff + sta CharFace + +]rts rts + +*------------------------------- +* Bring reflection to life as shadowman + +CreateShad + jsr getreflect ;get char data for reflection + + lda #0 + sta createshad + + lda #1 ;shadman + sta CharID + + lda #MirrorCrack + jsr addsound + + jsr SaveShad + + lda MaxKidStr + sta MaxOppStr + sta OppStrength + lda #1 + sta KidStrength + jmp markmeters + +*------------------------------- +* +* Bones rise +* +*------------------------------- +skelscrn = 1 +skelx = 5 +skely = 1 +skeltrig = 2 +skelprog = 2 + +BONESRISE + lda level + cmp #3 + bne ]rts + + lda ShadFace + cmp #86 + bne ]rts + lda VisScrn + cmp #skelscrn + bne ]rts + lda exitopen + beq ]rts + lda KidBlockX + cmp #skeltrig + beq :trig + cmp #skeltrig+1 + bne ]rts + +* Remove dead skeleton + +:trig lda VisScrn + ldx #skelx + ldy #skely + jsr rdblock + pha + lda #floor + sta (BlueType),y + lda #24 + sta height + lda #2 + jsr markred + jsr markwipe + iny + jsr markred + jsr markwipe + pla + cmp #bones + bne ]rts + +* Create live skeleton + + lda VisScrn + sta CharScrn + + ldx #skely + stx CharBlockY + lda FloorY+1,x + sta CharY + + lda #skelx + sta CharBlockX + jsr getblockej + clc + adc #angle+7 + sta CharX + + lda #-1 ;left + sta CharFace + + lda #arise + jsr jumpseq + jsr animchar + + lda #skelprog + sta guardprog + + lda #-1 + sta CharLife + lda #3 + sta OppStrength + + lda #0 + sta alertguard + sta refract + sta CharXVel + sta CharYVel + + lda #2 + sta CharSword + + lda #4 ;skeleton + sta CharID + + jmp SaveShad ;save ShadVars + + fin + +*------------------------------- +* +* Decrease strength by A (non-0) +* +* Out: non-0 if char lives, 0 if he dies +* ChgStrength +* +*------------------------------- +DECSTR + ldx CharID + bne :enemy + + cmp KidStrength + bcs killkid + + eor #$ff + clc + adc #1 ;negate + sta ChgKidStr + rts + +:enemy + cmp OppStrength + bcs killopp + + eor #$ff + clc + adc #1 + sta ChgOppStr + rts + +*------------------------------- +* Kill character (or opponent) +* Return A = 0 +*------------------------------- +killkid + lda #0 + sec + sbc KidStrength + sta ChgKidStr + + lda #0 +]rts rts + +*------------------------------- +killopp + lda #0 + sec + sbc OppStrength + sta ChgOppStr + + lda #0 +]rts rts + + +*------------------------------- +* Save current game to disk +* +* In: SavLevel = level ($ff to erase saved game) +*------------------------------- +DOSAVEGAME + lda level + cmp #FirstSideB + bcs :doit ;must have reached side B + lda #Splat + jmp addsound +:doit + +* Put data into save-game data area + + lda origstrength + sta SavStrength + + lda FrameCount + sta SavTimer + lda FrameCount+1 + sta SavTimer+1 + + lda NextTimeMsg + sta SavNextMsg + +* Write to disk + + jmp savegame + +*------------------------------- +* alt bg & char set list +* Level #: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + +bgset1 db 00,00,00,00,01,01,01,02,02,02,01,01,02,02,01 +bgset2 db 00,00,00,00,01,01,01,02,02,02,01,01,02,02,01 +chset db 00,00,00,01,02,02,03,02,02,02,02,02,04,05,05 + +* blueprint track & region lists (indexed by level #) +* NOTE--make sure these match lists in DIALOGER + +bluepTRKlst + db 33,33,32 ;3 levels on side A + db 33,33,32,32,31,31 ;12 levels on side B + db 30,30,29,29,28,28 + +bluepREGlst + db 0,1,1 + db 0,1,0,1,0,1 + db 0,1,0,1,0,1 + +*------------------------------- +* +* Load level from disk +* In: X = level # (0-14) +* +*------------------------------- +LOADLEVELX + lda bluepTRKlst,x + sta bluepTRK + lda bluepREGlst,x + sta bluepREG + + lda bgset1,x ;A + pha + lda bgset2,x ;X + ldy chset,x ;Y + tax + pla + + jmp loadlevel ;in MASTER +]rts rts + +*------------------------------- +* +* In: Kid & Shad data +* Out: EnemyAlert +* 2: kid & shad are on same stretch of floor +* 1: slicer, gaps in floor, or other obstacles, but +* line of sight is clear +* 0: can't see each other +* +*------------------------------- +gfightthres = 28*4 + +]safe lda #0 + sta EnemyAlert +]rts rts + +CHECKALERT + lda ShadID + cmp #24 ;mouse? + beq ]rts + cmp #1 ;shadowman? + bne :notshad + lda level + cmp #12 + bne ]safe ;fight shadow only on level 12 + +:notshad + lda KidPosn + beq ]safe + cmp #219 + bcc :noclimb + cmp #229 + bcc ]safe ;on staircase +:noclimb + lda ShadFace + cmp #86 + beq ]safe + + lda KidLife + and ShadLife + bpl ]safe ;one is dead + + lda KidScrn + cmp ShadScrn + bne ]safe + + lda KidBlockY + cmp ShadBlockY + bne ]safe + + lda #2 ;clear path + sta EnemyAlert + +* Get range of blocks to scan (]Xcount --> ]Xend) + + lda KidBlockX + jsr getblockej + clc + adc #7 ;middle of block + sta ]Xcount + + lda ShadBlockX + jsr getblockej + clc + adc #7 + sta ]Xend + + do 0 + lda ]Xcount + jsr getblockxp + ldx #1 + jsr showpage + lda ]Xend + jsr getblockxp + ldx #2 + jsr showpage + fin + + lda ]Xend + cmp ]Xcount + bcs :cont + tax + lda ]Xcount + sta ]Xend + stx ]Xcount +:cont + +* If leftmost block is a slicer, skip it + + lda ]Xcount + jsr :rdblock + cmp #slicer + bne :1 + lda #14 + clc + adc ]Xcount + sta ]Xcount + +* If rightmost block is a gate, skip it + +:1 lda ]Xend + jsr :rdblock + cmp #gate + bne :20 + lda ]Xend + sec + sbc #14 + sta ]Xend + +:20 lda ]Xend + cmp ]Xcount + bcc :rts + +* Scan from ]Xcount to ]Xend (left to right) + + lda ]Xcount +:loop cmp ]Xend + beq :9 + bcs :rts + +:9 jsr :rdblock + + cmp #block + beq :safe + cmp #panelwif + beq :safe + cmp #panelwof + beq :safe ;solid barrier blocks view + + cmp #loose + beq :view + cmp #gate + bne :2 + lda (BlueSpec),y + cmp #gfightthres + bcs :clear + bcc :view + +:2 cmp #slicer + beq :view + + jsr cmpspace + bne :clear ;closed gate, slicer, gap in floor, etc. +;are obstacles but don't block view +:view lda #1 + sta EnemyAlert + +:clear lda ]Xcount + clc + adc #14 + sta ]Xcount + bne :loop +:rts +]rts rts + +:safe lda #0 + sta EnemyAlert +]rts rts + +*------------------------------- +* In: A = X-coord +* Out: rdblock results +*------------------------------- +:rdblock jsr getblockxp + tax + ldy KidBlockY + lda KidScrn + jmp rdblock + +*------------------------------- +* +* Display version # on text page 1 (& wait for keypress) +* +*------------------------------- +DISPVERSION + lda #" " + jsr lrcls + + sta RAMWRTmain + + ldx #0 +:loop lda textline,x + cmp #"@" + beq :done + sta $400,x ;top line of screen + inx + bpl :loop +:done + lda RAMWRTaux + sta $c054 ;PAGE2 off + sta $c051 ;TEXT on + +* Wait for keypress + +:wloop lda $c000 + bpl :wloop + sta $c010 + + lda $c057 ;HIRES on + lda $c050 ;TEXT off + lda PAGE + bne :1 + lda $c055 ;PAGE2 on +:1 + lda #" " + jmp lrcls + +*------------------------------- + lst + ds 1 + usr $a9,21,$b00,*-org + lst off diff --git a/01 POP Source/Source/MOVEDATA.S b/01 POP Source/Source/MOVEDATA.S index cec2e1f..5678ac5 100755 --- a/01 POP Source/Source/MOVEDATA.S +++ b/01 POP Source/Source/MOVEDATA.S @@ -1 +1,59 @@ - tr on lst off * movedata *------------------------------- * objnames space = 0 floor = 1 spikes = 2 posts = 3 gate = 4 dpressplate = 5 ;down pressplate = 6 ;up panelwif = 7 ;w/floor pillarbottom = 8 pillartop = 9 flask = 10 loose = 11 panelwof = 12 ;w/o floor mirror = 13 rubble = 14 upressplate = 15 exit = 16 exit2 = 17 slicer = 18 torch = 19 block = 20 bones = 21 sword = 22 window = 23 window2 = 24 archbot = 25 archtop1 = 26 archtop2 = 27 archtop3 = 28 archtop4 = 29 *------------------------------- * misc. values from BGDATA torchLast = 17 bubbLast = 8 spikeExt = 5 spikeRet = 9 slicerExt = 2 slicerRet = 6 Ffalling = 10 ;1st "falling" frame *------------------------------- * moveparams gmaxval = 47*4 gminval = 0 lst off \ No newline at end of file + tr on + lst off + +* movedata +*------------------------------- +* objnames + +space = 0 +floor = 1 +spikes = 2 +posts = 3 +gate = 4 +dpressplate = 5 ;down +pressplate = 6 ;up +panelwif = 7 ;w/floor +pillarbottom = 8 +pillartop = 9 +flask = 10 +loose = 11 +panelwof = 12 ;w/o floor +mirror = 13 +rubble = 14 +upressplate = 15 +exit = 16 +exit2 = 17 +slicer = 18 +torch = 19 +block = 20 +bones = 21 +sword = 22 +window = 23 +window2 = 24 +archbot = 25 +archtop1 = 26 +archtop2 = 27 +archtop3 = 28 +archtop4 = 29 + +*------------------------------- +* misc. values from BGDATA + +torchLast = 17 +bubbLast = 8 + +spikeExt = 5 +spikeRet = 9 + +slicerExt = 2 +slicerRet = 6 + +Ffalling = 10 ;1st "falling" frame + +*------------------------------- +* moveparams + +gmaxval = 47*4 +gminval = 0 + + lst off diff --git a/01 POP Source/Source/MOVER.S b/01 POP Source/Source/MOVER.S index ce7e827..e23dddf 100755 --- a/01 POP Source/Source/MOVER.S +++ b/01 POP Source/Source/MOVER.S @@ -1 +1,2174 @@ -* mover org = $ee00 PalaceEditor = 0 tr on lst off *------------------------------- org org jmp ANIMTRANS jmp TRIGSPIKES jmp PUSHPP jmp BREAKLOOSE1 jmp BREAKLOOSE jmp ANIMMOBS jmp ADDMOBS jmp CLOSEEXIT jmp GETSPIKES jmp SHAKEM jmp TRIGSLICER jmp TRIGTORCH jmp GETFLAMEFRAME jmp SMASHMIRROR jmp JAMSPIKES jmp TRIGFLASK jmp GETFLASKFRAME jmp TRIGSWORD jmp JAMPP *------------------------------- lst put eq lst put gameeq lst put seqdata lst put movedata lst put soundnames dum locals state ds 1 temp1 ds 2 linkindex ds 1 pptype ds 1 mobframe ds 1 underFF ds 1 dend *------------------------------- gatevel db 0,0,0,20,40,60,80,100,120 maxgatevel = *-gatevel-1 *------------------------------- pptimer = 5 ;pressplate timer setting (min=3, max=30) ;(# cycles till plate pops up) spiketimer = 15+128 ;spike timer setting (2-127) +128 ;(# cycles till spikes retract) slicetimer = 15 ;# cycles between slices gatetimer = gmaxval+50 ;# cycles gate stays open loosetimer = Ffalling ;# cycles till floor detaches * falling floor params wiggletime = 4 ;# wiggling frames FFaccel = 3 FFtermvel = 29 crumbletime = 2 ;# crumbling frames crumbletime2 = 10 disappeartime = 2 FFheight = 17 CrushDist = 30 * wipe heights loosewipe = 31 ;[might erase spikes] spikewipe = 31 slicerwipe = 63 platewipe = 16 gateinc db -1,4,4 ;for trdirec = 0,1,2 (down,up,upjam) exitinc = 4 emaxval = 43*4 maxtr = trobspace-1 maxmob = mobspace-1 *------------------------------- * * Search trans list for object (trloc,trscrn) * * In: numtrans, trloc, trscrn * Out: X = index, 0 if not listed * *------------------------------- searchtrob ldx numtrans beq :rts :loop lda trloc,x cmp trloc bne :next lda trscrn,x cmp trscrn beq :rts ;found it :next dex bne :loop :rts rts *------------------------------- * * Add a new object to transition list * If it's already listed, just change trdirec to new value * * In: trdirec, trloc, trscrn * *------------------------------- addtrob jsr searchtrob ;Is object already listed? cpx #0 bne :chdir ;Yes--just change direc * It's not on the list - add it ldx numtrans cpx #maxtr beq :rts ;too many objects--trigger fails inx stx numtrans lda trdirec sta trdirec,x lda trloc sta trloc,x lda trscrn sta trscrn,x rts * Object already listed - change direction :chdir lda trdirec sta trdirec,x :rts rts *------------------------------- * * Add a MOB to MOB list * *------------------------------- addamob ldx nummob cpx #maxmob beq :rts inx stx nummob jmp savemob :rts rts *------------------------------- * * S A V E / L O A D M O B * *------------------------------- savemob lda mobx sta mobx,x lda moby sta moby,x lda mobscrn sta mobscrn,x lda mobvel sta mobvel,x lda mobtype sta mobtype,x lda moblevel sta moblevel,x rts loadmob lda mobx,x sta mobx lda moby,x sta moby lda mobscrn,x sta mobscrn lda mobvel,x sta mobvel lda mobtype,x sta mobtype lda moblevel,x sta moblevel ]rts rts *------------------------------- * * Trigger slicer * * In: A = initial state * *------------------------------- TRIGSLICER sta state ;temp lda (BlueSpec),y beq :ok cmp #slicerRet bcc ]rts ;in mid-slice--don't interfere * Between slices--OK to trigger :ok sty trloc lda state sta (BlueSpec),y lda VisScrn sta trscrn lda #1 sta trdirec jmp addtrob ;add slicer to trans list *------------------------------- * * Close exit * (Open it all the way & let it slam shut) * *------------------------------- CLOSEEXIT sty trloc sta trscrn lda #emaxval ;all the way open sta (BlueSpec),y lda #3 ;coming down fast sta trdirec jmp addtrob ;add to trans list *------------------------------- SMASHMIRROR lda #86 sta (BlueSpec),y ]rts rts *------------------------------- * * Trigger flask * *------------------------------- TRIGFLASK sty trloc sta trscrn lda #1 sta trdirec * Get rnd starting frame jsr rnd and #7 ora (BlueSpec),y sta (BlueSpec),y jmp addtrob *------------------------------- * * Trigger sword * *------------------------------- TRIGSWORD sty trloc sta trscrn lda #1 sta trdirec jsr rnd and #$1f sta (BlueSpec),y jmp addtrob *------------------------------- * * Trigger torch * *------------------------------- TRIGTORCH sty trloc sta trscrn lda #1 sta trdirec * Get rnd starting frame jsr rnd and #$f sta (BlueSpec),y jmp addtrob *------------------------------- * * Trigger spikes * *------------------------------- TRIGSPIKES lda (BlueSpec),y beq :ready ;State = 0: spikes are fully retracted-- ;spring 'em bpl ]rts ;Nonzero, hibit clear: spikes are in motion cmp #$ff beq ]rts ;jammed lda #spiketimer ;Nonzero, hibit set: spikes are fully sta (BlueSpec),y ;extended--reset timer to max value ]rts rts ;Spring spikes :ready ldx #1 ]cont stx trdirec sty trloc lda tempscrn ;from rdblock sta trscrn jsr addtrob ;add spikes to trans list jsr redspikes lda #GateDown ;TEMP jmp addsound *------------------------------- * * Jam spikes (& remove from trans list) * * In: Same as TRIGSPIKES * *------------------------------- JAMSPIKES lda #$ff sta (BlueSpec),y ldx #-1 ;stop object bmi ]cont *------------------------------- * * Get spike status: 0 = safe, 1 = sprung, 2 = springing * *------------------------------- GETSPIKES lda (BlueSpec),y bmi :sprung beq :safe ;fully retracted cmp #spikeExt bcc :springing :safe lda #0 ;safe: retracted or retracting rts :sprung cmp #$ff ;jammed (body impaled on them)? beq :safe lda #1 rts :springing lda #2 ]rts rts *------------------------------- * * Break off section of loose floor * *------------------------------- BREAKLOOSE lda #1 BREAKLOOSE1 ;in: A = initial state sta state lda (BlueType),y and #reqmask ;required floorpiece? bne ]rts ;yes--blocked below lda (BlueSpec),y bmi :ok ;wiggling bne ]rts ;already triggered :ok lda state sta (BlueSpec),y sty trloc lda tempscrn ;from rdblock sta trscrn lda #0 ;down sta trdirec jsr addtrob ;add floor to trans list jmp redloose *------------------------------- * * Depress pressplate * * In: results of RDBLOCK * (tempblockx-y, tempscrn refer to pressplate) * *------------------------------- PUSHPP lda (BlueType),y and #idmask sta pptype ;pressplate/upressplate/rubble pushpp1 lda (BlueSpec),y ;LINKLOC index sta linkindex tax jsr gettimer cmp #31 beq ]rts ;plate is permanently down cmp #2 bcs :starttimer ;plate is temporarily down-- ;just restart timer * Fresh plate has been stepped on--reset timer lda #pptimer ;put plate down for the count jsr chgtimer sty trloc lda tempscrn ;from rdblock1 sta trscrn lda #1 sta trdirec jsr addtrob ;add to trans list jsr redplate ;add plate to redraw list lda #1 sta alertguard lda #PlateDown jsr addsound :trig jmp trigger ;trigger something? * plate is already down--just restart timer * (& retrigger gates) :starttimer lda #pptimer jsr chgtimer jmp :trig *------------------------------- * * Jam pressplate (dead weight) * * In: Same as PUSHPP * *------------------------------- JAMPP lda (BlueType),y and #idmask sta pptype cmp #pressplate beq :1 lda #floor sta (BlueType),y lda #0 sta (BlueSpec),y lda #rubble sta pptype bne pushpp1 :1 lda #dpressplate sta (BlueType),y bne pushpp1 *------------------------------- * * We just pushed a pressplate -- did we trigger something? * * In: linkindex, pptype * *------------------------------- trigger :loop ldx linkindex lda LINKLOC,x cmp #$ff beq :rts ;linked to nothing jsr getloc sta trloc jsr getscrn ;get block # and screen # of sta trscrn ;gadget to trigger jsr calcblue ldy trloc lda (BlueType),y and #idmask ;get objid into A jsr trigobj ;call appropriate trigger routine lda trdirec bmi :skip ;trigger fails jsr addtrob ;add gadget to transition list :skip ldx linkindex inc linkindex jsr getlastflag beq :loop :rts rts *------------------------------- * * Trigger object * * Out: trdirec (-1 if trigger fails) * *------------------------------- trigobj cmp #gate bne :1 jmp triggate :1 cmp #exit bne :2 jmp openexit :2 ]rts rts *------------------------------- * * Open exit * *------------------------------- openexit lda (BlueSpec),y bne :fail ;Exit can only open, not close lda #1 bpl :1 :fail lda #-1 :1 sta trdirec rts *------------------------------- * * Trigger gate * * In: BlueSpec, Y, pptype * Out: trdirec * *------------------------------- triggate lda (BlueSpec),y ;current gate position ldx pptype cpx #upressplate beq :raise cpx #rubble beq :jam * Lower gate :lower cmp #gminval ;at bottom? bne :yeslower ;no--lower it ;yes--trigger fails :fail jmp stopobj :yeslower lda #3 ;down fast sta trdirec rts :jam ldx #2 ;open & jam stx trdirec cmp #gmaxval bcc :1 lda #$ff ;"jammed open" state bmi :3 :raise ldx #1 ;open stx trdirec cmp #$ff beq :fail ;jammed cmp #gmaxval bcc :1 lda #gatetimer :3 sta (BlueSpec),y ;reset timer bne :fail :1 ]rts rts *------------------------------- * * Animate transitional objects * (Advance each object to next frame in animation table) * *------------------------------- ]cleanflag ds 1 ANIMTRANS lda #0 sta trobcount ldx numtrans ;# objs in trans (0-maxtr) beq ]rts lda #0 sta ]cleanflag :loop stx tempnt jsr animobj ;animate obj #x ldx tempnt lda trdirec ;has object stopped? bpl :1 ;no lda #-1 ;yes--mark it for deletion sta ]cleanflag ;& set cleanup flag :1 sta trdirec,x ;save direction change if any dex bne :loop lda ]cleanflag beq ]rts * Delete all stopped objects (trdirec = ff) * (i.e., copy entire list back onto * itself, omitting stopped objects) ldx #1 ;source index (assume numtrans > 0) ldy #0 ;dest index :dloop lda trdirec,x cmp #$ff beq :next iny sta trdirec,y lda trloc,x sta trloc,y lda trscrn,x ;source sta trscrn,y ;dest :next inx cpx numtrans bcc :dloop beq :dloop sty numtrans rts *------------------------------- * * Animate TROB #x * *------------------------------- animobj lda trloc,x sta trloc lda trscrn,x sta trscrn lda trdirec,x sta trdirec * Find out what kind of object it is lda trscrn jsr calcblue ldy trloc lda (BlueSpec),y sta state ;original state lda (BlueType),y and #idmask ;objid * and branch to appropriate subroutine cmp #torch bne :1 jsr animtorch jmp :done :1 cmp #upressplate beq :plate cmp #pressplate bne :2 :plate jsr animplate jmp :done :2 cmp #spikes bne :3 jsr animspikes jmp :done :3 cmp #loose bne :31 jsr animfloor jmp :done :31 cmp #space ;(loose floor turns into space) bne :4 jsr animspace jmp :done :4 cmp #slicer bne :5 jsr animslicer jmp :done :5 cmp #gate bne :6 jsr animgate jmp :done :6 cmp #exit bne :7 jsr animexit jmp :done :7 cmp #flask bne :8 jsr animflask jmp :done :8 cmp #sword bne :9 jsr animsword jmp :done :9 jsr stopobj ;obj is none of these--purge it from trans list! :done lda state ldy trloc sta (BlueSpec),y :rts rts *------------------------------- * * Animate exit * *------------------------------- animexit ldx trdirec bmi :cont cpx #3 bcs :downfast ;>= 3: coming down fast lda #RaisingExit jsr addsound lda state clc adc #exitinc sta state cmp #emaxval bcs :stop :cont jmp redexit :stop jsr stopobj lda #GateDown jsr addsound lda #s_Stairs ldx #15 jsr cuesong lda #1 sta exitopen jsr mirappear jmp :cont * Exit coming down fast :downfast cpx #maxgatevel bcs :2 inx stx trdirec :2 lda state sec sbc gatevel,x sta state beq :cont bcs :cont jsr stopobj lda #0 sta state lda #GateSlam jsr addsound jmp :cont *------------------------------- * * Animate gate * *------------------------------- animgate ldx trdirec bmi :cont ;gate has stopped cpx #3 ;trdirec >= 3: coming down fast bcs :downfast lda state cmp #$ff beq :stop ;jammed open clc adc gateinc,x sta state cpx #0 beq :goingdown cmp #gmaxval bcs :attop ;stop at top lda #RaisingGate jsr addsound jmp :cont :goingdown cmp #gminval beq :stop bcc :stop cmp #gmaxval bcs :cont ;at top jsr addlowersound :cont jmp redgate ;mark gate for redrawing :stop jsr stopobj lda #GateDown jsr addsound jmp :cont * Gate has reached top * trdirec = 1: pause, then start to close again * trdirec = 2: jam at top :attop cpx #2 bcc :tr1 lda #$ff ;jammed-open value sta state jmp :stop :tr1 lda #gatetimer sta state lda #0 ;down sta trdirec ]rts rts * Down fast :downfast cpx #maxgatevel bcs :2 inx stx trdirec ;trdirec is velocity index :2 lda state sec sbc gatevel,x sta state beq :cont bcs :cont lda #0 sta state jsr stopobj lda #GateSlam jsr addsound jmp :cont *------------------------------- * * Animate pressplate * *------------------------------- animplate ldx trdirec bmi ]rts lda state tax jsr gettimer sec sbc #1 pha jsr chgtimer pla cmp #2 bcs ]rts ;timer stops at t=1 lda #PlateUp jsr addsound jsr stopobj jmp redplate ;add obj to redraw buffer ]rts rts *------------------------------- * * Animate slicer * *------------------------------- animslicer ldx trdirec bmi :done lda state tax and #$80 sta state ;preserve hibit txa and #$7f clc adc #1 cmp #slicetimer+1 bcc :1 lda #1 ;wrap around :1 ora state sta state and #$7f ;next frame # cmp #slicerExt bne :2 lda #JawsClash jsr addsound :2 lda trscrn cmp VisScrn ;is slicer on visible screen? bne :os ;no lda trloc jsr unindex cpx KidBlockY ;on same level as kid? bne :os ;no lda KidLife bmi :done ;If kid is dead, stop all unbloodied slicers lda state and #$80 bne :done * As soon as slicer is retracted, purge it from trans list :os lda state and #$7f cmp #slicerRet bcc :done :purge jsr stopobj :done lda state and #$7f cmp #slicerRet ;retracted? bcs ]rts ;yes--don't bother to redraw jmp redslicer *------------------------------- * * Animate flask * *------------------------------- animflask ldx trdirec bmi ]rts lda trscrn cmp VisScrn bne :purge lda state and #%11100000 ;potion # sta temp1 lda state and #%00011111 ;frame # jsr GETFLASKFRAME ora temp1 sta state jmp redflask ]purge :purge jmp stopobj *------------------------------- * * Animate gleaming sword * *------------------------------- animsword lda trscrn cmp VisScrn bne ]purge dec state bne :1 jsr rnd and #$3f clc adc #40 sta state :1 jmp redsword ]rts rts *------------------------------- * * Animate torch * *------------------------------- animtorch ldx trdirec bmi ]rts lda trscrn cmp VisScrn bne ]purge lda state jsr GETFLAMEFRAME sta state jmp redtorch *------------------------------- * * Get flame frame * * In/out: A = state * *------------------------------- GETFLAMEFRAME sta state jsr rnd cmp state beq :2 cmp #torchLast+1 bcc :1 lda state :2 clc adc #1 cmp #torchLast+1 bcc :1 lda #0 ;wrap around :1 ]rts rts *------------------------------- * * Get flask frame * * In/out: A = state (low 5 bits) * *------------------------------- GETFLASKFRAME clc adc #1 cmp #bubbLast+1 bcc ]rts lda #1 ]rts rts *------------------------------- * * Animate spikes * *------------------------------- animspikes ldx trdirec bmi :done lda state bmi :timerloop ;Hibit set: remaining 7 bits ;represent timer value * Hibit clear: remaining 7 bits represent BGDATA frame # inc state cmp #spikeExt ;is extension complete? beq :starttimer ;yes--start timer cmp #spikeRet ;is retraction complete? bne :done ;not yet lda #0 sta state ;yes--reset to "ready" state jsr stopobj :done jmp redspikes * Spike timer loop :starttimer lda #spiketimer sta state bne :done :timerloop dec state lda state and #$7f bne :rts ;Time's up lda #spikeExt+1 ;First "retracting" frame sta state bne :done :rts ]rts rts *------------------------------- * * Animate loose floor * *------------------------------- animfloor ldx trdirec bmi :red * When timer reaches max value & loose floor detaches: * (1) Change objid from "loose floor" to "empty space" * (2) Create a MOB to take over where TROB stopped inc state lda state bmi :wiggle ;floor is only wiggling cmp #loosetimer bcc :red * Timer has reached max value--detach floor jsr makespace sta state jsr stopobj * and create new MOB lda trloc jsr unindex asl asl ;x4 sta mobx stx moblevel lda BlockBot+1,x sta moby lda trscrn sta mobscrn lda #0 sta mobvel sta mobtype jsr addamob :red jmp redloose * Floor is only wiggling :wiggle ldx level cpx #13 beq ]rts cmp #wiggletime+$80 bcc :red lda #0 sta state jsr stopobj ;stop wiggling jmp :red animspace jsr stopobj jmp redloose *------------------------------- * * Stop object (set trdirec = -1) * *------------------------------- stopobj lda #-1 sta trdirec rts *------------------------------- * General redraw-object routine *------------------------------- redtrobj jsr check lda #2 jsr markred jsr markwipe jsr checkright lda #2 jsr markred jmp markwipe *------------------------------- * redraw torch/exit *------------------------------- redexit redtorch jsr checkright lda #2 jmp markmove *------------------------------- * redraw flask/sword *------------------------------- redsword redflask jsr check lda #2 jmp markmove *------------------------------- * redraw loose floor *------------------------------- redloose inc trobcount lda #loosewipe sta height jmp redtrobj *------------------------------- * redraw gate *------------------------------- redgate jsr checkright ;mark piece to right of gate lda #2 jsr markmove jsr markfred jsr checkabover ;& piece to right of gate panel lda #2 jmp markmove *------------------------------- * redraw spikes *------------------------------- redspikes inc trobcount lda #spikewipe sta height jmp redtrobj *------------------------------- * redraw slicer *------------------------------- redslicer inc trobcount lda #slicerwipe sta height jsr check lda #2 jsr markred jmp markwipe *------------------------------- * redraw pressplate *------------------------------- redplate lda #platewipe sta height jmp redtrobj *------------------------------- * * Before marking a piece in redraw buffer, * check whether it's visible. * * If piece is visible onscreen: * return with carry clear, y = redbuf index * If piece is not visible: * return with carry set * *------------------------------- ]no ldy #30 sec ]rts rts ]above cmp scrnAbove bne ]rts lda trloc sec sbc #20 ;if on top row, return 0-9 and cs tay sec rts *------------------------------- * Check (trscrn, trloc) *------------------------------- check lda trscrn cmp VisScrn bne ]above ldy trloc cpy #30 ;i.e., "clc" rts *------------------------------- * Check piece to left of (trscrn,trloc) *------------------------------- checkleft lda trscrn cmp VisScrn bne :notonscrn ;piece is on this screen cpy #0 beq ]no cpy #10 beq ]no cpy #20 beq ]no ;yes--piece is visible dey clc rts :notonscrn cmp scrnRight bne ]above ;piece is on screen to right ldy trloc cpy #0 beq :yesr cpy #10 beq :yesr cpy #20 bne :yesr :yesr tya clc adc #9 ;mark corresponding right-edge piece tay ;on this screen clc rts *------------------------------- * Check piece to right of (trscrn,trloc) *------------------------------- checkright lda trscrn cmp VisScrn bne :notonscrn ;piece is on this screen ldy trloc cpy #9 beq ]no cpy #19 beq ]no cpy #29 beq ]no ;yes iny clc rts :notonscrn cmp scrnLeft bne ]above ;piece is on screen to left ldy trloc cpy #9 beq :yesl cpy #19 beq :yesl cpy #29 bne ]no :yesl tya sec sbc #9 ;mark corresponding left-edge piece tay ;on this screen clc rts ]no ldy #30 sec ]rts rts *------------------------------- * Check piece above & to right of (trscrn,trloc) *------------------------------- checkabover lda trscrn cmp VisScrn bne :notonscrn ;piece is on this screen ldy trloc cpy #10 bcc :above ;piece is on top row cpy #19 beq ]no cpy #29 beq ]no ;yes tya sec sbc #9 tay clc rts :above iny sec rts :notonscrn cmp scrnLeft bne :notonleft ;piece is on screen to left ldy trloc cpy #9 beq :yes0 cpy #19 beq :yesl cpy #29 bne ]no :yesl tya sec sbc #19 ;mark corresponding left-edge piece tay ;on this screen clc rts :yes0 ldy #0 sec rts :notonleft cmp scrnBelow bne :notbelow ;piece is on screen below ldy trloc cpy #9 bcs ]no ;yes--piece is on top row tya clc adc #21 tay clc rts :notbelow cmp scrnBelowL bne ]rts ;piece is on scrn below & to left ldy trloc cpy #9 bne ]no ;yes--piece is in u.r. ldy #20 clc rts *------------------------------- * * Extract information from LINKLOC/LINKMAP * * In: X = linkindex * Out: A = info * *------------------------------- gettimer lda LINKMAP,x and #%00011111 ;pressplate timer (0-31) rts chgtimer ;In: A = new timer setting and #%00011111 sta temp1 lda LINKMAP,x and #%11100000 ora temp1 sta LINKMAP,x rts getloc lda LINKLOC,x and #%00011111 ;screen posn (0-29) rts getlastflag lda LINKLOC,x and #%10000000 ;last-entry flag (0-1) rts getscrn lda LINKLOC,x and #%01100000 ;low 2 bits lsr lsr sta temp1 lda LINKMAP,x and #%11100000 ;high 3 bits adc temp1 lsr lsr lsr ;Result: screen # (0-31) ]rts rts *------------------------------- * * Update all MOBs (falling floors) * *------------------------------- ANIMMOBS ldx nummob ;# MOBs in motion (0-maxmob) beq ]rts :loop stx tempnt jsr loadmob jsr animmob ;animate MOB #x jsr checkcrush ;did we just crush a character? ldx tempnt jsr savemob dex bne :loop * Delete MOBs that have ceased to exist ldx #1 ;source index (assume nummob > 0) ldy #0 ;dest index :dloop lda mobvel,x cmp #$ff beq :next iny sta mobvel,y lda mobx,x ;source sta mobx,y ;dest lda moby,x sta moby,y lda mobscrn,x sta mobscrn,y lda mobtype,x sta mobtype,y lda moblevel,x sta moblevel,y :next inx cpx nummob bcc :dloop beq :dloop sty nummob ]rts rts *------------------------------- * * Animate MOB #x * *------------------------------- animmob lda mobtype bne :done jsr mobfloor :done lda mobvel bpl ]rts ;is object stopping? inc mobvel ;yes ]rts rts *------------------------------- * * Animate falling floor * *------------------------------- mobfloor lda mobvel bmi ]rts :ok1 cmp #FFtermvel bcs :tv clc adc #FFaccel sta mobvel :tv clc adc moby sta moby * check for collision w/floor ldx mobscrn ;on null screen? beq :null ;yes--fall on cmp #-30 ;negative? bcs :fallon ;yes--fall on ldx moblevel cmp BlockAy+1,x bcc :fallon * Passing thru floor plane--what to do? * First see what's there ldx moblevel stx tempblocky lda mobx lsr lsr sta tempblockx lda mobscrn sta tempscrn jsr rdblock1 ;A = objid sta underFF ;under falling floor cmp #space beq :passthru cmp #loose bne :crash * Lands on loose floor * Knock out loose floor & continue jsr knockloose jmp :passthru * Lands on solid floor :crash lda #LooseCrash jsr addsound lda mobscrn sta tempscrn lda moblevel sta tempblocky jsr SHAKEM1 ;shake loose floors ldx moblevel lda BlockAy+1,x sta moby lda #-crumbletime sta mobvel jmp makerubble * Passes thru floor plane :passthru jsr passthru :fallon ]rts rts * Falling on null screen :null lda moby cmp #192+17 bcc ]rts ;MOB has fallen off null screen--delete it lda #-disappeartime sta mobvel ]rts rts *------------------------------- * Knock out loose floor *------------------------------- knockloose jsr makespace sta (BlueSpec),y lda mobvel lsr sta mobvel ldx tempnt jsr savemob ;save this MOB * Create new MOB (add'l falling floor) lda moby clc adc #6 sta moby jsr passthru jsr addamob * Retrieve old MOB ldx tempnt jsr loadmob jmp markmob *------------------------------- * Make space * Return A = BlueSpec *------------------------------- makespace lda #space ;change objid to empty space sta (BlueType),y do PalaceEditor lda #1 rts fin lda #0 ldx BGset1 cpx #1 ;pal? bne ]rts lda #1 ;stripe ]rts rts *------------------------------- * Pass thru floor plane *------------------------------- passthru inc moblevel lda moblevel cmp #3 bcc ]rts * ... and onto next screen * (NOTE: moby may be negative) lda moby sec sbc #192 sta moby lda #0 sta moblevel lda mobscrn jsr getdown sta mobscrn ]rts rts *------------------------------- * Delete MOB & change objid of floorpiece it landed on * If pressplate, trigger before reducing it to rubble *------------------------------- makerubble lda moblevel sta tempblocky lda mobx lsr lsr sta tempblockx lda mobscrn sta tempscrn jsr rdblock1 cmp #pressplate beq :pp cmp #upressplate beq :jampp cmp #floor beq :notpp cmp #spikes beq :notpp cmp #flask beq :notpp cmp #torch beq :notpp bne ]rts ;can't transform this piece into rubble :jampp lda #rubble sta (BlueType),y :pp jsr PUSHPP ;block lands on pressplate-- jsr rdblock1 ;crush pp & jam open all gates :notpp lda #rubble sta (BlueType),y jmp markmob *------------------------------- * Mark MOB *------------------------------- markmob lda mobscrn cmp VisScrn bne ]rts lda #loosewipe sta height jsr indexblock lda #2 jsr markred jsr markwipe inc tempblockx jsr indexblock lda #2 jsr markred jsr markfred jmp markwipe ]rts rts *------------------------------- * * Did falling floor crush anybody? * *------------------------------- checkcrush jsr LoadKid jsr chcrush1 ;return cs if crush bcc ]rts jsr crushchar jmp SaveKid chcrush1 lda mobscrn cmp CharScrn ;on same screen as char? bne :no lda mobx lsr lsr cmp CharBlockX ;same blockx? bne :no lda moby cmp CharY bcs :no ;mob is below char altogether lda CharY sec sbc #CrushDist cmp moby bcs :no sec ;crush! rts :no clc ]rts rts *------------------------------- * * Crush char with falling block * (Ordered by ANIMMOB) * *------------------------------- crushchar lda level cmp #13 beq :1 lda CharPosn cmp #5 bcc :1 cmp #15 bcc ]rts ;running-->escape :1 lda CharAction cmp #2 bcc :ground cmp #7 bne ]rts * Action code 0,1,7 -- on ground :ground ldx CharBlockY inx lda FloorY,x sta CharY ;align w/floor lda #1 jsr decstr beq :kill lda CharPosn cmp #109 beq ]rts lda #crush jmp jumpseq :kill lda #hardland ;temp jmp jumpseq *------------------------------- * * Add all visible MOBs to object table (to be drawn later) * *------------------------------- ADDMOBS ldx nummob ;# objs in motion (0-maxmob) beq :rts :loop stx tempnt jsr loadmob lda mobtype bne :1 jsr ATM ;Add this MOB :1 ldx tempnt dex bne :loop :rts ]rts rts *------------------------------- * * Add this MOB to obj table (if visible) * *------------------------------- ATM * Is floorpiece visible onscreen? lda mobscrn cmp VisScrn bne :ok2 lda moby cmp #192+17 ;17 is generous estimate of image height bcc :ok rts :ok2 cmp scrnBelow bne ]rts ;not on screen below lda moby cmp #-17 bcs :ok1 cmp #17 bcs ]rts :ok1 clc adc #192 sta moby ;(this change won't be saved) :ok * Get block #; index char lda moby jsr getblocky ;return blocky (0-3) sta tempblocky lda mobx lsr lsr sta tempblockx jsr indexblock sty FCharIndex * Mark floorbuf & fredbuf of affected blocks to R :cont1 inc tempblockx jsr indexblock ;block to R lda #2 jsr markfloor jsr markfred lda moby sec sbc #FFheight jsr getblocky ;highest affected blocky cmp tempblocky beq :same sta tempblocky jsr indexblock ;block to U.R. lda #2 jsr markfloor jsr markfred :same * Get frame # lda #Ffalling sta mobframe jmp addmobobj ;add MOB to object table *------------------------------- * * Add MOB to object table * * In: mob data * *------------------------------- addmobobj inc objX ldx objX lda mobtype ;0 = falling floor ora #$80 sta objTYP,x lda mobx sta objX,x lda #0 sta objOFF,x lda moby sta objY,x lda mobframe sta objIMG,x lda #0 sta objCU,x sta objCL,x lda #40 sta objCR,x jmp setobjindx ]rts rts *------------------------------- * * Shake floors * * In: A = CharBlockY * *------------------------------- SHAKEM ldx level cpx #13 beq ]rts sta tempblocky lda VisScrn sta tempscrn SHAKEM1 ldx #9 :loop txa pha sta tempblockx jsr rdblock1 cmp #loose bne :cont jsr shakeit :cont pla tax dex bpl :loop ]rts rts *------------------------------- * Shake loose floor *------------------------------- shakeit lda (BlueSpec),y bmi ]rts ;already wiggling bne ]rts ;active lda #$80 sta (BlueSpec),y sty trloc lda tempscrn ;from rdblock sta trscrn lda #1 sta trdirec jmp addtrob ;add floor to trans list *------------------------------- lst ds 1 usr $a9,21,$00,*-org lst off \ No newline at end of file +* mover +org = $ee00 +PalaceEditor = 0 + tr on + lst off +*------------------------------- + org org + + jmp ANIMTRANS + jmp TRIGSPIKES + jmp PUSHPP + jmp BREAKLOOSE1 + jmp BREAKLOOSE + + jmp ANIMMOBS + jmp ADDMOBS + jmp CLOSEEXIT + jmp GETSPIKES + jmp SHAKEM + + jmp TRIGSLICER + jmp TRIGTORCH + jmp GETFLAMEFRAME + jmp SMASHMIRROR + jmp JAMSPIKES + + jmp TRIGFLASK + jmp GETFLASKFRAME + jmp TRIGSWORD + jmp JAMPP + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put seqdata + lst + put movedata + lst + put soundnames + + dum locals +state ds 1 +temp1 ds 2 +linkindex ds 1 +pptype ds 1 +mobframe ds 1 +underFF ds 1 + dend + +*------------------------------- +gatevel db 0,0,0,20,40,60,80,100,120 + +maxgatevel = *-gatevel-1 + +*------------------------------- +pptimer = 5 ;pressplate timer setting (min=3, max=30) +;(# cycles till plate pops up) + +spiketimer = 15+128 ;spike timer setting (2-127) +128 +;(# cycles till spikes retract) + +slicetimer = 15 ;# cycles between slices + +gatetimer = gmaxval+50 ;# cycles gate stays open + +loosetimer = Ffalling ;# cycles till floor detaches + +* falling floor params + +wiggletime = 4 ;# wiggling frames +FFaccel = 3 +FFtermvel = 29 +crumbletime = 2 ;# crumbling frames +crumbletime2 = 10 +disappeartime = 2 +FFheight = 17 +CrushDist = 30 + +* wipe heights + +loosewipe = 31 ;[might erase spikes] +spikewipe = 31 +slicerwipe = 63 +platewipe = 16 + +gateinc db -1,4,4 ;for trdirec = 0,1,2 (down,up,upjam) + +exitinc = 4 +emaxval = 43*4 + +maxtr = trobspace-1 +maxmob = mobspace-1 + +*------------------------------- +* +* Search trans list for object (trloc,trscrn) +* +* In: numtrans, trloc, trscrn +* Out: X = index, 0 if not listed +* +*------------------------------- +searchtrob + ldx numtrans + beq :rts + +:loop lda trloc,x + cmp trloc + bne :next + lda trscrn,x + cmp trscrn + beq :rts ;found it + +:next dex + bne :loop + +:rts rts + +*------------------------------- +* +* Add a new object to transition list +* If it's already listed, just change trdirec to new value +* +* In: trdirec, trloc, trscrn +* +*------------------------------- +addtrob + jsr searchtrob ;Is object already listed? + + cpx #0 + bne :chdir ;Yes--just change direc + +* It's not on the list - add it + + ldx numtrans + cpx #maxtr + beq :rts ;too many objects--trigger fails + + inx + stx numtrans + + lda trdirec + sta trdirec,x + lda trloc + sta trloc,x + lda trscrn + sta trscrn,x + rts + +* Object already listed - change direction + +:chdir lda trdirec + sta trdirec,x +:rts rts + +*------------------------------- +* +* Add a MOB to MOB list +* +*------------------------------- +addamob + ldx nummob + cpx #maxmob + beq :rts + + inx + stx nummob + + jmp savemob + +:rts rts + +*------------------------------- +* +* S A V E / L O A D M O B +* +*------------------------------- +savemob + lda mobx + sta mobx,x + lda moby + sta moby,x + lda mobscrn + sta mobscrn,x + lda mobvel + sta mobvel,x + lda mobtype + sta mobtype,x + lda moblevel + sta moblevel,x + rts + +loadmob + lda mobx,x + sta mobx + lda moby,x + sta moby + lda mobscrn,x + sta mobscrn + lda mobvel,x + sta mobvel + lda mobtype,x + sta mobtype + lda moblevel,x + sta moblevel +]rts rts + +*------------------------------- +* +* Trigger slicer +* +* In: A = initial state +* +*------------------------------- +TRIGSLICER + sta state ;temp + + lda (BlueSpec),y + beq :ok + cmp #slicerRet + bcc ]rts ;in mid-slice--don't interfere + +* Between slices--OK to trigger + +:ok sty trloc + + lda state + sta (BlueSpec),y + + lda VisScrn + sta trscrn + + lda #1 + sta trdirec + + jmp addtrob ;add slicer to trans list + +*------------------------------- +* +* Close exit +* (Open it all the way & let it slam shut) +* +*------------------------------- +CLOSEEXIT + sty trloc + sta trscrn + + lda #emaxval ;all the way open + sta (BlueSpec),y + + lda #3 ;coming down fast + sta trdirec + + jmp addtrob ;add to trans list + +*------------------------------- +SMASHMIRROR + lda #86 + sta (BlueSpec),y +]rts rts + +*------------------------------- +* +* Trigger flask +* +*------------------------------- +TRIGFLASK + sty trloc + sta trscrn + + lda #1 + sta trdirec + +* Get rnd starting frame + + jsr rnd + and #7 + ora (BlueSpec),y + sta (BlueSpec),y + jmp addtrob + +*------------------------------- +* +* Trigger sword +* +*------------------------------- +TRIGSWORD + sty trloc + sta trscrn + lda #1 + sta trdirec + jsr rnd + and #$1f + sta (BlueSpec),y + jmp addtrob + +*------------------------------- +* +* Trigger torch +* +*------------------------------- +TRIGTORCH + sty trloc + sta trscrn + + lda #1 + sta trdirec + +* Get rnd starting frame + + jsr rnd + and #$f + sta (BlueSpec),y + jmp addtrob + +*------------------------------- +* +* Trigger spikes +* +*------------------------------- +TRIGSPIKES + lda (BlueSpec),y + beq :ready ;State = 0: spikes are fully retracted-- +;spring 'em + bpl ]rts ;Nonzero, hibit clear: spikes are in motion + cmp #$ff + beq ]rts ;jammed + lda #spiketimer ;Nonzero, hibit set: spikes are fully + sta (BlueSpec),y ;extended--reset timer to max value +]rts rts +;Spring spikes +:ready ldx #1 +]cont stx trdirec + sty trloc + + lda tempscrn ;from rdblock + sta trscrn + + jsr addtrob ;add spikes to trans list + jsr redspikes + + lda #GateDown ;TEMP + jmp addsound + +*------------------------------- +* +* Jam spikes (& remove from trans list) +* +* In: Same as TRIGSPIKES +* +*------------------------------- +JAMSPIKES + lda #$ff + sta (BlueSpec),y + ldx #-1 ;stop object + bmi ]cont + +*------------------------------- +* +* Get spike status: 0 = safe, 1 = sprung, 2 = springing +* +*------------------------------- +GETSPIKES + lda (BlueSpec),y + bmi :sprung + beq :safe ;fully retracted + + cmp #spikeExt + bcc :springing + +:safe lda #0 ;safe: retracted or retracting + rts + +:sprung cmp #$ff ;jammed (body impaled on them)? + beq :safe + lda #1 + rts + +:springing lda #2 +]rts rts + +*------------------------------- +* +* Break off section of loose floor +* +*------------------------------- +BREAKLOOSE + lda #1 + +BREAKLOOSE1 ;in: A = initial state + sta state + + lda (BlueType),y + and #reqmask ;required floorpiece? + bne ]rts ;yes--blocked below + + lda (BlueSpec),y + bmi :ok ;wiggling + bne ]rts ;already triggered + +:ok lda state + sta (BlueSpec),y + + sty trloc + + lda tempscrn ;from rdblock + sta trscrn + + lda #0 ;down + sta trdirec + + jsr addtrob ;add floor to trans list + jmp redloose + +*------------------------------- +* +* Depress pressplate +* +* In: results of RDBLOCK +* (tempblockx-y, tempscrn refer to pressplate) +* +*------------------------------- +PUSHPP + lda (BlueType),y + and #idmask + sta pptype ;pressplate/upressplate/rubble +pushpp1 + lda (BlueSpec),y ;LINKLOC index + sta linkindex + tax + jsr gettimer + + cmp #31 + beq ]rts ;plate is permanently down + + cmp #2 + bcs :starttimer ;plate is temporarily down-- +;just restart timer + +* Fresh plate has been stepped on--reset timer + + lda #pptimer ;put plate down for the count + jsr chgtimer + + sty trloc + + lda tempscrn ;from rdblock1 + sta trscrn + + lda #1 + sta trdirec + + jsr addtrob ;add to trans list + + jsr redplate ;add plate to redraw list + + lda #1 + sta alertguard + lda #PlateDown + jsr addsound + +:trig jmp trigger ;trigger something? + +* plate is already down--just restart timer +* (& retrigger gates) + +:starttimer lda #pptimer + jsr chgtimer + jmp :trig + +*------------------------------- +* +* Jam pressplate (dead weight) +* +* In: Same as PUSHPP +* +*------------------------------- +JAMPP + lda (BlueType),y + and #idmask + sta pptype + cmp #pressplate + beq :1 + + lda #floor + sta (BlueType),y + lda #0 + sta (BlueSpec),y + lda #rubble + sta pptype + bne pushpp1 + +:1 lda #dpressplate + sta (BlueType),y + bne pushpp1 + +*------------------------------- +* +* We just pushed a pressplate -- did we trigger something? +* +* In: linkindex, pptype +* +*------------------------------- +trigger +:loop ldx linkindex + + lda LINKLOC,x + cmp #$ff + beq :rts ;linked to nothing + + jsr getloc + sta trloc + + jsr getscrn ;get block # and screen # of + sta trscrn ;gadget to trigger + + jsr calcblue + ldy trloc + lda (BlueType),y + and #idmask ;get objid into A + + jsr trigobj ;call appropriate trigger routine + + lda trdirec + bmi :skip ;trigger fails + + jsr addtrob ;add gadget to transition list + +:skip ldx linkindex + inc linkindex + + jsr getlastflag + beq :loop + +:rts rts + +*------------------------------- +* +* Trigger object +* +* Out: trdirec (-1 if trigger fails) +* +*------------------------------- +trigobj + cmp #gate + bne :1 + jmp triggate +:1 + cmp #exit + bne :2 + jmp openexit +:2 +]rts rts + +*------------------------------- +* +* Open exit +* +*------------------------------- +openexit + lda (BlueSpec),y + bne :fail ;Exit can only open, not close + + lda #1 + bpl :1 + +:fail lda #-1 +:1 sta trdirec + rts + +*------------------------------- +* +* Trigger gate +* +* In: BlueSpec, Y, pptype +* Out: trdirec +* +*------------------------------- +triggate + lda (BlueSpec),y ;current gate position + + ldx pptype + cpx #upressplate + beq :raise + cpx #rubble + beq :jam + +* Lower gate + +:lower cmp #gminval ;at bottom? + bne :yeslower ;no--lower it +;yes--trigger fails +:fail jmp stopobj + +:yeslower + lda #3 ;down fast + sta trdirec + rts + +:jam ldx #2 ;open & jam + stx trdirec + cmp #gmaxval + bcc :1 + lda #$ff ;"jammed open" state + bmi :3 + +:raise ldx #1 ;open + stx trdirec + cmp #$ff + beq :fail ;jammed + cmp #gmaxval + bcc :1 + lda #gatetimer +:3 sta (BlueSpec),y ;reset timer + bne :fail +:1 +]rts rts + +*------------------------------- +* +* Animate transitional objects +* (Advance each object to next frame in animation table) +* +*------------------------------- +]cleanflag ds 1 + +ANIMTRANS + lda #0 + sta trobcount + + ldx numtrans ;# objs in trans (0-maxtr) + beq ]rts + + lda #0 + sta ]cleanflag + +:loop stx tempnt + + jsr animobj ;animate obj #x + + ldx tempnt + + lda trdirec ;has object stopped? + bpl :1 ;no + + lda #-1 ;yes--mark it for deletion + sta ]cleanflag ;& set cleanup flag + +:1 sta trdirec,x ;save direction change if any + + dex + bne :loop + + lda ]cleanflag + beq ]rts + +* Delete all stopped objects (trdirec = ff) +* (i.e., copy entire list back onto +* itself, omitting stopped objects) + + ldx #1 ;source index (assume numtrans > 0) + ldy #0 ;dest index + +:dloop lda trdirec,x + cmp #$ff + beq :next + + iny + sta trdirec,y + lda trloc,x + sta trloc,y + lda trscrn,x ;source + sta trscrn,y ;dest + +:next inx + + cpx numtrans + bcc :dloop + beq :dloop + + sty numtrans + rts + +*------------------------------- +* +* Animate TROB #x +* +*------------------------------- +animobj lda trloc,x + sta trloc + lda trscrn,x + sta trscrn + lda trdirec,x + sta trdirec + +* Find out what kind of object it is + + lda trscrn + jsr calcblue + + ldy trloc + lda (BlueSpec),y + sta state ;original state + + lda (BlueType),y + and #idmask ;objid + +* and branch to appropriate subroutine + + cmp #torch + bne :1 + jsr animtorch + jmp :done + +:1 cmp #upressplate + beq :plate + cmp #pressplate + bne :2 +:plate jsr animplate + jmp :done + +:2 cmp #spikes + bne :3 + jsr animspikes + jmp :done + +:3 cmp #loose + bne :31 + jsr animfloor + jmp :done + +:31 cmp #space ;(loose floor turns into space) + bne :4 + jsr animspace + jmp :done + +:4 cmp #slicer + bne :5 + jsr animslicer + jmp :done + +:5 cmp #gate + bne :6 + jsr animgate + jmp :done + +:6 cmp #exit + bne :7 + jsr animexit + jmp :done + +:7 cmp #flask + bne :8 + jsr animflask + jmp :done + +:8 cmp #sword + bne :9 + jsr animsword + jmp :done + +:9 jsr stopobj ;obj is none of these--purge it from trans list! + +:done lda state + ldy trloc + sta (BlueSpec),y + +:rts rts + +*------------------------------- +* +* Animate exit +* +*------------------------------- +animexit + ldx trdirec + bmi :cont + cpx #3 + bcs :downfast ;>= 3: coming down fast + + lda #RaisingExit + jsr addsound + + lda state + clc + adc #exitinc + sta state + + cmp #emaxval + bcs :stop + +:cont jmp redexit + +:stop jsr stopobj + + lda #GateDown + jsr addsound + lda #s_Stairs + ldx #15 + jsr cuesong + lda #1 + sta exitopen + jsr mirappear + jmp :cont + +* Exit coming down fast + +:downfast + cpx #maxgatevel + bcs :2 + inx + stx trdirec +:2 lda state + sec + sbc gatevel,x + sta state + beq :cont + bcs :cont + + jsr stopobj + + lda #0 + sta state + + lda #GateSlam + jsr addsound + + jmp :cont + +*------------------------------- +* +* Animate gate +* +*------------------------------- +animgate + ldx trdirec + bmi :cont ;gate has stopped + + cpx #3 ;trdirec >= 3: coming down fast + bcs :downfast + + lda state + cmp #$ff + beq :stop ;jammed open + clc + adc gateinc,x + sta state + + cpx #0 + beq :goingdown + + cmp #gmaxval + bcs :attop ;stop at top + + lda #RaisingGate + jsr addsound + + jmp :cont + +:goingdown + cmp #gminval + beq :stop + bcc :stop + + cmp #gmaxval + bcs :cont ;at top + jsr addlowersound + +:cont jmp redgate ;mark gate for redrawing + +:stop jsr stopobj + + lda #GateDown + jsr addsound + + jmp :cont + +* Gate has reached top +* trdirec = 1: pause, then start to close again +* trdirec = 2: jam at top + +:attop + cpx #2 + bcc :tr1 + lda #$ff ;jammed-open value + sta state + jmp :stop + +:tr1 lda #gatetimer + sta state + + lda #0 ;down + sta trdirec +]rts rts + +* Down fast + +:downfast + cpx #maxgatevel + bcs :2 + + inx + stx trdirec ;trdirec is velocity index +:2 + lda state + sec + sbc gatevel,x + sta state + beq :cont + bcs :cont + + lda #0 + sta state + jsr stopobj + + lda #GateSlam + jsr addsound + jmp :cont + +*------------------------------- +* +* Animate pressplate +* +*------------------------------- +animplate + ldx trdirec + bmi ]rts + + lda state + tax + jsr gettimer + sec + sbc #1 + pha + jsr chgtimer + pla + cmp #2 + bcs ]rts ;timer stops at t=1 + + lda #PlateUp + jsr addsound + + jsr stopobj + + jmp redplate ;add obj to redraw buffer +]rts rts + +*------------------------------- +* +* Animate slicer +* +*------------------------------- +animslicer + ldx trdirec + bmi :done + + lda state + tax + and #$80 + sta state ;preserve hibit + txa + and #$7f + clc + adc #1 + cmp #slicetimer+1 + bcc :1 + lda #1 ;wrap around +:1 ora state + sta state + and #$7f ;next frame # + cmp #slicerExt + bne :2 + + lda #JawsClash + jsr addsound + +:2 lda trscrn + cmp VisScrn ;is slicer on visible screen? + bne :os ;no + + lda trloc + jsr unindex + cpx KidBlockY ;on same level as kid? + bne :os ;no + + lda KidLife + bmi :done + ;If kid is dead, stop all unbloodied slicers + lda state + and #$80 + bne :done + +* As soon as slicer is retracted, purge it from trans list + +:os lda state + and #$7f + cmp #slicerRet + bcc :done + +:purge jsr stopobj + +:done lda state + and #$7f + cmp #slicerRet ;retracted? + bcs ]rts ;yes--don't bother to redraw + + jmp redslicer + +*------------------------------- +* +* Animate flask +* +*------------------------------- +animflask + ldx trdirec + bmi ]rts + + lda trscrn + cmp VisScrn + bne :purge + + lda state + and #%11100000 ;potion # + sta temp1 + lda state + and #%00011111 ;frame # + jsr GETFLASKFRAME + ora temp1 + sta state + + jmp redflask +]purge +:purge jmp stopobj + +*------------------------------- +* +* Animate gleaming sword +* +*------------------------------- +animsword + lda trscrn + cmp VisScrn + bne ]purge + + dec state + bne :1 + jsr rnd + and #$3f + clc + adc #40 + sta state + +:1 jmp redsword +]rts rts + +*------------------------------- +* +* Animate torch +* +*------------------------------- +animtorch + ldx trdirec + bmi ]rts + + lda trscrn + cmp VisScrn + bne ]purge + + lda state + jsr GETFLAMEFRAME + sta state + + jmp redtorch + +*------------------------------- +* +* Get flame frame +* +* In/out: A = state +* +*------------------------------- +GETFLAMEFRAME + sta state + + jsr rnd + + cmp state + beq :2 + cmp #torchLast+1 + bcc :1 + + lda state +:2 clc + adc #1 + cmp #torchLast+1 + bcc :1 + + lda #0 ;wrap around +:1 +]rts rts + +*------------------------------- +* +* Get flask frame +* +* In/out: A = state (low 5 bits) +* +*------------------------------- +GETFLASKFRAME + clc + adc #1 + cmp #bubbLast+1 + bcc ]rts + lda #1 +]rts rts + +*------------------------------- +* +* Animate spikes +* +*------------------------------- +animspikes + ldx trdirec + bmi :done + + lda state + bmi :timerloop ;Hibit set: remaining 7 bits + ;represent timer value + +* Hibit clear: remaining 7 bits represent BGDATA frame # + + inc state + + cmp #spikeExt ;is extension complete? + beq :starttimer ;yes--start timer + + cmp #spikeRet ;is retraction complete? + bne :done ;not yet + + lda #0 + sta state ;yes--reset to "ready" state + + jsr stopobj + +:done jmp redspikes + +* Spike timer loop + +:starttimer + lda #spiketimer + sta state + + bne :done + +:timerloop + dec state + + lda state + and #$7f + bne :rts +;Time's up + lda #spikeExt+1 ;First "retracting" frame + sta state + + bne :done +:rts +]rts rts + +*------------------------------- +* +* Animate loose floor +* +*------------------------------- +animfloor + ldx trdirec + bmi :red + +* When timer reaches max value & loose floor detaches: +* (1) Change objid from "loose floor" to "empty space" +* (2) Create a MOB to take over where TROB stopped + + inc state + + lda state + bmi :wiggle ;floor is only wiggling + + cmp #loosetimer + bcc :red + +* Timer has reached max value--detach floor + + jsr makespace + sta state + + jsr stopobj + +* and create new MOB + + lda trloc + jsr unindex + + asl + asl ;x4 + sta mobx + stx moblevel + + lda BlockBot+1,x + sta moby + + lda trscrn + sta mobscrn + + lda #0 + sta mobvel + sta mobtype + + jsr addamob + +:red jmp redloose + +* Floor is only wiggling + +:wiggle ldx level + cpx #13 + beq ]rts + + cmp #wiggletime+$80 + bcc :red + + lda #0 + sta state + jsr stopobj ;stop wiggling + + jmp :red + +animspace jsr stopobj + jmp redloose + +*------------------------------- +* +* Stop object (set trdirec = -1) +* +*------------------------------- +stopobj lda #-1 + sta trdirec + rts + +*------------------------------- +* General redraw-object routine +*------------------------------- +redtrobj + jsr check + lda #2 + jsr markred + jsr markwipe + jsr checkright + lda #2 + jsr markred + jmp markwipe + +*------------------------------- +* redraw torch/exit +*------------------------------- +redexit +redtorch + jsr checkright + lda #2 + jmp markmove + +*------------------------------- +* redraw flask/sword +*------------------------------- +redsword +redflask + jsr check + lda #2 + jmp markmove + +*------------------------------- +* redraw loose floor +*------------------------------- +redloose + inc trobcount + lda #loosewipe + sta height + jmp redtrobj + +*------------------------------- +* redraw gate +*------------------------------- +redgate + jsr checkright ;mark piece to right of gate + lda #2 + jsr markmove + jsr markfred + jsr checkabover ;& piece to right of gate panel + lda #2 + jmp markmove + +*------------------------------- +* redraw spikes +*------------------------------- +redspikes + inc trobcount + lda #spikewipe + sta height + jmp redtrobj + +*------------------------------- +* redraw slicer +*------------------------------- +redslicer + inc trobcount + lda #slicerwipe + sta height + jsr check + lda #2 + jsr markred + jmp markwipe + +*------------------------------- +* redraw pressplate +*------------------------------- +redplate + lda #platewipe + sta height + jmp redtrobj + +*------------------------------- +* +* Before marking a piece in redraw buffer, +* check whether it's visible. +* +* If piece is visible onscreen: +* return with carry clear, y = redbuf index +* If piece is not visible: +* return with carry set +* +*------------------------------- +]no ldy #30 + sec +]rts rts + +]above cmp scrnAbove + bne ]rts + + lda trloc + sec + sbc #20 ;if on top row, return 0-9 and cs + tay + + sec + rts + +*------------------------------- +* Check (trscrn, trloc) +*------------------------------- +check + lda trscrn + cmp VisScrn + bne ]above + + ldy trloc + cpy #30 ;i.e., "clc" + rts + +*------------------------------- +* Check piece to left of (trscrn,trloc) +*------------------------------- +checkleft + lda trscrn + cmp VisScrn + bne :notonscrn +;piece is on this screen + cpy #0 + beq ]no + cpy #10 + beq ]no + cpy #20 + beq ]no +;yes--piece is visible + dey + clc + rts + +:notonscrn + cmp scrnRight + bne ]above +;piece is on screen to right + ldy trloc + cpy #0 + beq :yesr + cpy #10 + beq :yesr + cpy #20 + bne :yesr + +:yesr tya + clc + adc #9 ;mark corresponding right-edge piece + tay ;on this screen + + clc + rts + +*------------------------------- +* Check piece to right of (trscrn,trloc) +*------------------------------- +checkright + lda trscrn + cmp VisScrn + bne :notonscrn +;piece is on this screen + ldy trloc + cpy #9 + beq ]no + + cpy #19 + beq ]no + + cpy #29 + beq ]no +;yes + iny + clc + rts + +:notonscrn + cmp scrnLeft + bne ]above +;piece is on screen to left + ldy trloc + cpy #9 + beq :yesl + + cpy #19 + beq :yesl + + cpy #29 + bne ]no + +:yesl tya + sec + sbc #9 ;mark corresponding left-edge piece + tay ;on this screen + + clc + rts + +]no ldy #30 + sec +]rts rts + +*------------------------------- +* Check piece above & to right of (trscrn,trloc) +*------------------------------- +checkabover + lda trscrn + cmp VisScrn + bne :notonscrn +;piece is on this screen + ldy trloc + cpy #10 + bcc :above ;piece is on top row + + cpy #19 + beq ]no + + cpy #29 + beq ]no +;yes + tya + sec + sbc #9 + tay + + clc + rts + +:above + iny + sec + rts + +:notonscrn + cmp scrnLeft + bne :notonleft +;piece is on screen to left + ldy trloc + cpy #9 + beq :yes0 + + cpy #19 + beq :yesl + + cpy #29 + bne ]no + +:yesl tya + sec + sbc #19 ;mark corresponding left-edge piece + tay ;on this screen + + clc + rts + +:yes0 ldy #0 + sec + rts + +:notonleft + cmp scrnBelow + bne :notbelow +;piece is on screen below + ldy trloc + cpy #9 + bcs ]no +;yes--piece is on top row + tya + clc + adc #21 + tay + + clc + rts + +:notbelow + cmp scrnBelowL + bne ]rts + ;piece is on scrn below & to left + ldy trloc + cpy #9 + bne ]no +;yes--piece is in u.r. + ldy #20 + clc + rts + +*------------------------------- +* +* Extract information from LINKLOC/LINKMAP +* +* In: X = linkindex +* Out: A = info +* +*------------------------------- +gettimer + lda LINKMAP,x + and #%00011111 ;pressplate timer (0-31) + rts +chgtimer ;In: A = new timer setting + and #%00011111 + sta temp1 + lda LINKMAP,x + and #%11100000 + ora temp1 + sta LINKMAP,x + rts +getloc + lda LINKLOC,x + and #%00011111 ;screen posn (0-29) + rts +getlastflag + lda LINKLOC,x + and #%10000000 ;last-entry flag (0-1) + rts +getscrn + lda LINKLOC,x + and #%01100000 ;low 2 bits + lsr + lsr + sta temp1 + lda LINKMAP,x + and #%11100000 ;high 3 bits + adc temp1 + lsr + lsr + lsr ;Result: screen # (0-31) +]rts rts + +*------------------------------- +* +* Update all MOBs (falling floors) +* +*------------------------------- +ANIMMOBS + ldx nummob ;# MOBs in motion (0-maxmob) + beq ]rts + +:loop stx tempnt + jsr loadmob + + jsr animmob ;animate MOB #x + + jsr checkcrush ;did we just crush a character? + + ldx tempnt + jsr savemob + + dex + bne :loop + +* Delete MOBs that have ceased to exist + + ldx #1 ;source index (assume nummob > 0) + ldy #0 ;dest index + +:dloop lda mobvel,x + cmp #$ff + beq :next + + iny + sta mobvel,y + lda mobx,x ;source + sta mobx,y ;dest + lda moby,x + sta moby,y + lda mobscrn,x + sta mobscrn,y + lda mobtype,x + sta mobtype,y + lda moblevel,x + sta moblevel,y + +:next inx + + cpx nummob + bcc :dloop + beq :dloop + + sty nummob + +]rts rts + +*------------------------------- +* +* Animate MOB #x +* +*------------------------------- +animmob + lda mobtype + bne :done + jsr mobfloor +:done + lda mobvel + bpl ]rts ;is object stopping? + inc mobvel ;yes +]rts rts + +*------------------------------- +* +* Animate falling floor +* +*------------------------------- +mobfloor + lda mobvel + bmi ]rts +:ok1 + cmp #FFtermvel + bcs :tv + clc + adc #FFaccel + sta mobvel + +:tv clc + adc moby + sta moby + +* check for collision w/floor + + ldx mobscrn ;on null screen? + beq :null ;yes--fall on + + cmp #-30 ;negative? + bcs :fallon ;yes--fall on + + ldx moblevel + cmp BlockAy+1,x + bcc :fallon + +* Passing thru floor plane--what to do? +* First see what's there + + ldx moblevel + stx tempblocky + + lda mobx + lsr + lsr + sta tempblockx + + lda mobscrn + sta tempscrn + + jsr rdblock1 ;A = objid + sta underFF ;under falling floor + + cmp #space + beq :passthru + + cmp #loose + bne :crash + +* Lands on loose floor +* Knock out loose floor & continue + + jsr knockloose + + jmp :passthru + +* Lands on solid floor + +:crash + lda #LooseCrash + jsr addsound + + lda mobscrn + sta tempscrn + lda moblevel + sta tempblocky + jsr SHAKEM1 ;shake loose floors + + ldx moblevel + lda BlockAy+1,x + sta moby + + lda #-crumbletime + sta mobvel + + jmp makerubble + +* Passes thru floor plane + +:passthru + jsr passthru +:fallon +]rts rts + +* Falling on null screen + +:null + lda moby + cmp #192+17 + bcc ]rts +;MOB has fallen off null screen--delete it + lda #-disappeartime + sta mobvel + +]rts rts + +*------------------------------- +* Knock out loose floor +*------------------------------- +knockloose + jsr makespace + sta (BlueSpec),y + + lda mobvel + lsr + sta mobvel + + ldx tempnt + jsr savemob ;save this MOB + +* Create new MOB (add'l falling floor) + + lda moby + clc + adc #6 + sta moby + + jsr passthru + + jsr addamob + +* Retrieve old MOB + + ldx tempnt + jsr loadmob + + jmp markmob + +*------------------------------- +* Make space +* Return A = BlueSpec +*------------------------------- +makespace lda #space ;change objid to empty space + sta (BlueType),y + + do PalaceEditor + lda #1 + rts + fin + + lda #0 + ldx BGset1 + cpx #1 ;pal? + bne ]rts + lda #1 ;stripe +]rts rts + +*------------------------------- +* Pass thru floor plane +*------------------------------- +passthru + inc moblevel + + lda moblevel + cmp #3 + bcc ]rts + +* ... and onto next screen +* (NOTE: moby may be negative) + + lda moby + sec + sbc #192 + sta moby + + lda #0 + sta moblevel + + lda mobscrn + jsr getdown + sta mobscrn +]rts rts + +*------------------------------- +* Delete MOB & change objid of floorpiece it landed on +* If pressplate, trigger before reducing it to rubble +*------------------------------- +makerubble + lda moblevel + sta tempblocky + + lda mobx + lsr + lsr + sta tempblockx + + lda mobscrn + sta tempscrn + + jsr rdblock1 + + cmp #pressplate + beq :pp + cmp #upressplate + beq :jampp + cmp #floor + beq :notpp + cmp #spikes + beq :notpp + cmp #flask + beq :notpp + cmp #torch + beq :notpp + bne ]rts ;can't transform this piece into rubble + +:jampp lda #rubble + sta (BlueType),y + +:pp jsr PUSHPP ;block lands on pressplate-- + jsr rdblock1 ;crush pp & jam open all gates + +:notpp lda #rubble + sta (BlueType),y + jmp markmob + +*------------------------------- +* Mark MOB +*------------------------------- +markmob + lda mobscrn + cmp VisScrn + bne ]rts + + lda #loosewipe + sta height + + jsr indexblock + lda #2 + jsr markred + jsr markwipe + + inc tempblockx + + jsr indexblock + lda #2 + jsr markred + jsr markfred + jmp markwipe + +]rts rts + +*------------------------------- +* +* Did falling floor crush anybody? +* +*------------------------------- +checkcrush + jsr LoadKid + jsr chcrush1 ;return cs if crush + bcc ]rts + jsr crushchar + jmp SaveKid + +chcrush1 + lda mobscrn + cmp CharScrn ;on same screen as char? + bne :no + + lda mobx + lsr + lsr + cmp CharBlockX ;same blockx? + bne :no + + lda moby + cmp CharY + bcs :no ;mob is below char altogether + + lda CharY + sec + sbc #CrushDist + cmp moby + bcs :no + sec ;crush! + rts + +:no clc +]rts rts + +*------------------------------- +* +* Crush char with falling block +* (Ordered by ANIMMOB) +* +*------------------------------- +crushchar + lda level + cmp #13 + beq :1 + lda CharPosn + cmp #5 + bcc :1 + cmp #15 + bcc ]rts ;running-->escape + +:1 lda CharAction + cmp #2 + bcc :ground + cmp #7 + bne ]rts + +* Action code 0,1,7 -- on ground + +:ground + ldx CharBlockY + inx + lda FloorY,x + sta CharY ;align w/floor + + lda #1 + jsr decstr + beq :kill + + lda CharPosn + cmp #109 + beq ]rts + lda #crush + jmp jumpseq + +:kill lda #hardland ;temp + jmp jumpseq + +*------------------------------- +* +* Add all visible MOBs to object table (to be drawn later) +* +*------------------------------- +ADDMOBS + ldx nummob ;# objs in motion (0-maxmob) + beq :rts + +:loop stx tempnt + jsr loadmob + + lda mobtype + bne :1 + jsr ATM ;Add this MOB +:1 + ldx tempnt + dex + bne :loop +:rts +]rts rts + +*------------------------------- +* +* Add this MOB to obj table (if visible) +* +*------------------------------- +ATM + +* Is floorpiece visible onscreen? + + lda mobscrn + cmp VisScrn + bne :ok2 + + lda moby + cmp #192+17 ;17 is generous estimate of image height + bcc :ok + rts +:ok2 + cmp scrnBelow + bne ]rts ;not on screen below + + lda moby + cmp #-17 + bcs :ok1 + cmp #17 + bcs ]rts +:ok1 + clc + adc #192 + sta moby ;(this change won't be saved) +:ok + +* Get block #; index char + + lda moby + jsr getblocky ;return blocky (0-3) + sta tempblocky + + lda mobx + lsr + lsr + sta tempblockx + + jsr indexblock + sty FCharIndex + +* Mark floorbuf & fredbuf of affected blocks to R + +:cont1 + inc tempblockx + jsr indexblock ;block to R + + lda #2 + jsr markfloor + jsr markfred + + lda moby + sec + sbc #FFheight + jsr getblocky ;highest affected blocky + cmp tempblocky + beq :same + + sta tempblocky + jsr indexblock ;block to U.R. + + lda #2 + jsr markfloor + jsr markfred +:same + +* Get frame # + + lda #Ffalling + sta mobframe + + jmp addmobobj ;add MOB to object table + +*------------------------------- +* +* Add MOB to object table +* +* In: mob data +* +*------------------------------- +addmobobj + inc objX + ldx objX + + lda mobtype ;0 = falling floor + ora #$80 + sta objTYP,x + + lda mobx + sta objX,x + lda #0 + sta objOFF,x + + lda moby + sta objY,x + + lda mobframe + sta objIMG,x + + lda #0 + sta objCU,x + sta objCL,x + lda #40 + sta objCR,x + + jmp setobjindx +]rts rts +*------------------------------- +* +* Shake floors +* +* In: A = CharBlockY +* +*------------------------------- +SHAKEM + ldx level + cpx #13 + beq ]rts + + sta tempblocky + + lda VisScrn + sta tempscrn + +SHAKEM1 + ldx #9 +:loop txa + pha + sta tempblockx + + jsr rdblock1 + cmp #loose + bne :cont + + jsr shakeit + +:cont pla + tax + dex + bpl :loop + +]rts rts + +*------------------------------- +* Shake loose floor +*------------------------------- +shakeit + lda (BlueSpec),y + bmi ]rts ;already wiggling + bne ]rts ;active + + lda #$80 + sta (BlueSpec),y + + sty trloc + + lda tempscrn ;from rdblock + sta trscrn + + lda #1 + sta trdirec + + jmp addtrob ;add floor to trans list + +*------------------------------- + lst + ds 1 + usr $a9,21,$00,*-org + lst off diff --git a/01 POP Source/Source/SEQDATA.S b/01 POP Source/Source/SEQDATA.S index eef51b2..8ce7170 100755 --- a/01 POP Source/Source/SEQDATA.S +++ b/01 POP Source/Source/SEQDATA.S @@ -1 +1,132 @@ - tr on lst off * seqdata fcheckmark = %01000000 fcentermark = %00011111 * Sequence table entry points startrun = 1 stand = 2 standjump = 3 runjump = 4 turn = 5 runturn = 6 stepfall = 7 jumphangMed = 8 hang = 9 climbup = 10 hangdrop = 11 freefall = 12 runstop = 13 jumpup = 14 fallhang = 15 jumpbackhang = 16 softland = 17 jumpfall = 18 stepfall2 = 19 medland = 20 rjumpfall = 21 hardland = 22 hangfall = 23 jumphangLong = 24 hangstraight = 25 rdiveroll = 26 sdiveroll = 27 highjump = 28 stepfwd1 = 29 ;stepfwd 1 thru 14 = 29 thru 42 turnrun = 43 testfoot = 44 bumpfall = 45 hardbump = 46 bump = 47 superhijump = 48 standup = 49 stoop = 50 impale = 51 crush = 52 deadfall = 53 halve = 54 engarde = 55 advance = 56 retreat = 57 strike = 58 flee = 59 turnengarde = 60 strikeblock = 61 readyblock = 62 landengarde = 63 bumpengfwd = 64 bumpengback = 65 blocktostrike = 66 strikeadv = 67 climbdown = 68 blockedstrike = 69 climbstairs = 70 dropdead = 71 stepback = 72 climbfail = 73 stabbed = 74 faststrike = 75 strikeret = 76 alertstand = 77 drinkpotion = 78 crawl = 79 alertturn = 80 fightfall = 81 efightfall = 82 efightfallfwd = 83 running = 84 stabkill = 85 fastadvance = 86 goalertstand = 87 arise = 88 turndraw = 89 guardengarde = 90 pickupsword = 91 resheathe = 92 fastsheathe = 93 Pstand = 94 Vstand = 95 Vapproach = 96 Vstop = 97 Palert = 98 Pback = 99 Vexit = 100 Mclimb = 101 Vraise = 102 Plie = 103 patchfall = 104 Mscurry = 105 Mstop = 106 Mleave = 107 Pembrace = 108 Pwaiting = 109 Pstroke = 110 Prise = 111 Pcrouch = 112 Pslump = 113 Mraise = 114 * Sequence table instruction codes goto = -1 aboutface = -2 up = -3 down = -4 chx = -5 chy = -6 act = -7 setfall = -8 ifwtless = -9 die = -10 jaru = -11 jard = -12 effect = -13 tap = -14 nextlevel = -15 lst off \ No newline at end of file + tr on + lst off + +* seqdata + +fcheckmark = %01000000 +fcentermark = %00011111 + +* Sequence table entry points + +startrun = 1 +stand = 2 +standjump = 3 +runjump = 4 +turn = 5 +runturn = 6 +stepfall = 7 +jumphangMed = 8 +hang = 9 +climbup = 10 +hangdrop = 11 +freefall = 12 +runstop = 13 +jumpup = 14 +fallhang = 15 +jumpbackhang = 16 +softland = 17 +jumpfall = 18 +stepfall2 = 19 +medland = 20 +rjumpfall = 21 +hardland = 22 +hangfall = 23 +jumphangLong = 24 +hangstraight = 25 +rdiveroll = 26 +sdiveroll = 27 +highjump = 28 +stepfwd1 = 29 +;stepfwd 1 thru 14 = 29 thru 42 +turnrun = 43 +testfoot = 44 +bumpfall = 45 +hardbump = 46 +bump = 47 +superhijump = 48 +standup = 49 +stoop = 50 +impale = 51 +crush = 52 +deadfall = 53 +halve = 54 +engarde = 55 +advance = 56 +retreat = 57 +strike = 58 +flee = 59 +turnengarde = 60 +strikeblock = 61 +readyblock = 62 +landengarde = 63 +bumpengfwd = 64 +bumpengback = 65 +blocktostrike = 66 +strikeadv = 67 +climbdown = 68 +blockedstrike = 69 +climbstairs = 70 +dropdead = 71 +stepback = 72 +climbfail = 73 +stabbed = 74 +faststrike = 75 +strikeret = 76 +alertstand = 77 +drinkpotion = 78 +crawl = 79 +alertturn = 80 +fightfall = 81 +efightfall = 82 +efightfallfwd = 83 +running = 84 +stabkill = 85 +fastadvance = 86 +goalertstand = 87 +arise = 88 +turndraw = 89 +guardengarde = 90 +pickupsword = 91 +resheathe = 92 +fastsheathe = 93 +Pstand = 94 +Vstand = 95 +Vapproach = 96 +Vstop = 97 +Palert = 98 +Pback = 99 +Vexit = 100 +Mclimb = 101 +Vraise = 102 +Plie = 103 +patchfall = 104 +Mscurry = 105 +Mstop = 106 +Mleave = 107 +Pembrace = 108 +Pwaiting = 109 +Pstroke = 110 +Prise = 111 +Pcrouch = 112 +Pslump = 113 +Mraise = 114 + +* Sequence table instruction codes + +goto = -1 +aboutface = -2 +up = -3 +down = -4 +chx = -5 +chy = -6 +act = -7 +setfall = -8 +ifwtless = -9 +die = -10 +jaru = -11 +jard = -12 +effect = -13 +tap = -14 +nextlevel = -15 + + lst off diff --git a/01 POP Source/Source/SEQTABLE.S b/01 POP Source/Source/SEQTABLE.S index 5d81fa2..0699455 100755 --- a/01 POP Source/Source/SEQTABLE.S +++ b/01 POP Source/Source/SEQTABLE.S @@ -1 +1,1716 @@ -* seqtable org = $3000 tr on ;TABS 15,20,40 lst off lstdo off *------------------------------- * Seq table instructions: goto = -1 aboutface = -2 up = -3 down = -4 chx = -5 chy = -6 act = -7 setfall = -8 ifwtless = -9 die = -10 jaru = -11 jard = -12 effect = -13 tap = -14 nextlevel = -15 *------------------------------- * * S E Q U E N C E T A B L E * *------------------------------- org org :1 dw startrun :2 dw stand :3 dw standjump :4 dw runjump :5 dw turn :6 dw runturn :7 dw stepfall :8 dw jumphangMed :9 dw hang :10 dw climbup :11 dw hangdrop :12 dw freefall :13 dw runstop :14 dw jumpup :15 dw fallhang :16 dw jumpbackhang :17 dw softland :18 dw jumpfall :19 dw stepfall2 :20 dw medland :21 dw rjumpfall :22 dw hardland :23 dw hangfall :24 dw jumphangLong :25 dw hangstraight :26 dw rdiveroll :27 dw sdiveroll :28 dw highjump :29 dw step1 :30 dw step2 :31 dw step3 :32 dw step4 :33 dw step5 :34 dw step6 :35 dw step7 :36 dw step8 :37 dw step9 :38 dw step10 :39 dw step11 :40 dw step12 :41 dw step13 :42 dw fullstep :43 dw turnrun :44 dw testfoot :45 dw bumpfall :46 dw hardbump :47 dw bump :48 dw superhijump :49 dw standup :50 dw stoop :51 dw impale :52 dw crush :53 dw deadfall :54 dw halve :55 dw engarde :56 dw advance :57 dw retreat :58 dw strike :59 dw flee :60 dw turnengarde :61 dw strikeblock :62 dw readyblock :63 dw landengarde :64 dw bumpengfwd :65 dw bumpengback :66 dw blocktostrike :67 dw strikeadv :68 dw climbdown :69 dw blockedstrike :70 dw climbstairs :71 dw dropdead :72 dw stepback :73 dw climbfail :74 dw stabbed :75 dw faststrike :76 dw strikeret :77 dw alertstand :78 dw drinkpotion :79 dw crawl :80 dw alertturn :81 dw fightfall :82 dw efightfall :83 dw efightfallfwd :84 dw running :85 dw stabkill :86 dw fastadvance :87 dw goalertstand :88 dw arise :89 dw turndraw :90 dw guardengarde :91 dw pickupsword :92 dw resheathe :93 dw fastsheathe :94 dw Pstand :95 dw Vstand :96 dw Vwalk :97 dw Vstop :98 dw Palert :99 dw Pback :100 dw Vexit :101 dw Mclimb :102 dw Vraise :103 dw Plie :104 dw patchfall :105 dw Mscurry :106 dw Mstop :107 dw Mleave :108 dw Pembrace :109 dw Pwaiting :110 dw Pstroke :111 dw Prise :112 dw Pcrouch :113 dw Pslump :114 dw Mraise *------------------------------- * r u n n i n g *------------------------------- running db act,1 db goto dw runcyc1 *------------------------------- * s t a r t r u n *------------------------------- startrun db act,1 runstt1 db 1 runstt2 db 2 runstt3 db 3 runstt4 db 4,chx,8 runstt5 db 5,chx,3 runstt6 db 6,chx,3 runcyc1 db 7,chx,5 runcyc2 db 8,chx,1 runcyc3 db tap,1,9,chx,2 runcyc4 db 10,chx,4 runcyc5 db 11,chx,5 runcyc6 db 12,chx,2 runcyc7 db tap,1,13,chx,3 runcyc8 db 14,chx,4 db goto dw runcyc1 *------------------------------- * s t a n d *------------------------------- stand db act,0 db 15 db goto dw stand *------------------------------- * a l e r t s t a n d *------------------------------- goalertstand db act,1 alertstand :loop db 166 db goto dw :loop *------------------------------- * a r i s e (skeleton) *------------------------------- arise db act,5 db chx,10,177 db 177 db chx,-7,chy,-2,178 db chx,5,chy,2,166 db chx,-1 db goto dw ready *------------------------------- * g u a r d e n g a r d e *------------------------------- guardengarde db goto dw ready *------------------------------- * e n g a r d e *------------------------------- engarde db act,1 db chx,2 db 207 db 208,chx,2 db 209,chx,2 db 210,chx,3 ready db act,1 db tap,0 db 158 db 170 :loop db 171 db goto dw :loop *------------------------------- * s t a b b e d *------------------------------- stabbed db act,5 db setfall,-1,0 db 172,chx,-1,chy,1 db 173,chx,-1 db 174,chx,-1,chy,2 ; db 175 db chx,-2,chy,1 db chx,-5,chy,-4 db goto dw guy8 *------------------------------- * s t r i k e - a d v a n c e *------------------------------- ;from guy6 (154) strikeadv db act,1 db setfall,1,0 db 155 db chx,2,165 db chx,-2 db goto dw ready *------------------------------- * s t r i k e - r e t r e a t *------------------------------- ;from guy6 (154) strikeret db act,1 db setfall,-1,0 db 155,156,157 db 158 db goto dw retreat *------------------------------- * a d v a n c e *------------------------------- advance db act,1 db setfall,1,0 db chx,2,163 db chx,4,164 db 165 db goto dw ready *------------------------------- * f a s t a d v a n c e *------------------------------- fastadvance db act,1 db setfall,1,0 db chx,6,164 db 165 db goto dw ready *------------------------------- * r e t r e a t *------------------------------- retreat db act,1 db setfall,-1,0 db chx,-3,160 db chx,-2,157 db goto dw ready *------------------------------- * s t r i k e *------------------------------- strike db act,1 db setfall,-1,0 db 168 faststrike db act,1 guy3 db 151 guy4 db act,1 db 152 ;-->blockedstrike guy5 db 153 guy6 db 154 guy7 db act,5 ;clr flags to avoid repeat strike db 155 guy8 db act,1 db 156 guy9 db 157 db goto dw ready *------------------------------- * b l o c k e d s t r i k e *------------------------------- blockedstrike db act,1 db 167 ;--> strikeblock db goto dw guy7 *------------------------------- * b l o c k t o s t r i k e *------------------------------- blocktostrike db 162 db goto dw guy4 *------------------------------- * r e a d y b l o c k *------------------------------- readyblock db 169 blocking db 150 ;--> blocktostrike/retreat db goto dw ready *------------------------------- * s t r i k e t o b l o c k *------------------------------- strikeblock db 159 db 160 db goto dw blocking *------------------------------- * l a n d e n g a r d e *------------------------------- landengarde db act,1 db jard db goto dw ready *------------------------------- * b u m p e n g a r d e ( f o r w a r d ) *------------------------------- bumpengfwd db act,5 db chx,-8 db goto dw ready *------------------------------- * b u m p e n g a r d e ( b a c k ) *------------------------------- bumpengback db act,5 db 160 db 157 db goto dw ready *------------------------------- * f l e e *------------------------------- flee db act,7 db chx,-8 db goto dw turn *------------------------------- * t u r n e n g a r d e *------------------------------- turnengarde db act,5 db aboutface,chx,5 db goto dw retreat *------------------------------- * a l e r t t u r n (for enemies) *------------------------------- alertturn db act,5 db aboutface,chx,18 db goto dw goalertstand *------------------------------- * s t a n d j u m p *------------------------------- standjump db act,1 db 16 db 17,chx,2 db 18,chx,2 db 19,chx,2 db 20,chx,2 db 21,chx,2 db 22,chx,7 db 23,chx,9 db 24,chx,5,chy,-6 ;chx 6? sjland db 25,chx,1,chy,6 db 26,chx,4 db jard db tap,1,27,chx,-3 db 28,chx,5 db 29 db tap,1,30 db 31 db 32 db 33,chx,1 db goto dw stand *------------------------------- * r u n j u m p *------------------------------- runjump db act,1 db tap,1,34,chx,5 db 35,chx,6 db 36,chx,3 db 37,chx,5 db tap,1,38,chx,7 db 39,chx,12,chy,-3 db 40,chx,8,chy,-9 db 41,chx,8,chy,-2 db 42,chx,4,chy,11 db 43,chx,4,chy,3 rjlandrun db 44,chx,5 db jard,tap,1 db goto dw runcyc1 *------------------------------- * r u n d i v e r o l l *------------------------------- rdiveroll db act,1 db chx,1 db 107,chx,2 db chx,2 db 108 db chx,2 db 109 db chx,2 db 109 db chx,2 :crouch db 109 db goto dw :crouch *------------------------------- * s t a n d d i v e r o l l *------------------------------- sdiveroll *------------------------------- * c r a w l *------------------------------- crawl db act,1 db chx,1,110 db 111,chx,2 db 112 db chx,2 db 108 db chx,2 :crouch db 109 db goto dw :crouch *------------------------------- * t u r n d r a w *------------------------------- turndraw db act,7 db aboutface,chx,6 db 45,chx,1 db 46 db goto dw engarde *------------------------------- * t u r n *------------------------------- turn db act,7 db aboutface,chx,6 db 45,chx,1 db 46,chx,2 db 47,chx,-1 finishturn db 48,chx,1 db 49,chx,-2 db 50,51,52 db goto dw stand *------------------------------- * t u r n r u n * (from frame 48) *------------------------------- turnrun db act,1 db chx,-1 db goto dw runstt1 *------------------------------- * r u n t u r n *------------------------------- runturn db act,1 db chx,1 db 53,chx,1 db tap,1,54,chx,8 db 55 db tap,1,56,chx,7 db 57,chx,3 db 58,chx,1 db 59 db 60,chx,2 db 61,chx,-1 db 62 db 63 db 64,chx,-1 db 65,chx,-14 db aboutface,goto dw runcyc7 *------------------------------- * f i g h t f a l l (backward) *------------------------------- fightfall db act,3 db chy,-1 db 102,chx,-2,chy,6 db 103,chx,-2,chy,9 db 104,chx,-1,chy,12 db 105,chx,-3 db setfall,0,15 db goto dw freefall *------------------------------- * e n e m y f i g h t f a l l *------------------------------- efightfall db act,3 db chy,-1,chx,-2 db 102,chx,-3,chy,6 db 103,chx,-3,chy,9 db 104,chx,-2,chy,12 db 105,chx,-3 ;for now--ultimately we want enemy ;shapes in here db setfall,0,15 db goto dw freefall *------------------------------- * e n e m y f i g h t f a l l f w d *------------------------------- efightfallfwd db act,3 db chx,1,chy,-1 db 102,chx,2,chy,6 db 103,chx,-1,chy,9 db 104,chy,12 db 105,chx,-2 ;for now--ultimately we want enemy ;shapes in here db setfall,1,15 db goto dw freefall *------------------------------- * s t e p f a l l *------------------------------- stepfall ;from #8 (run-11) db act,3 db chx,1,chy,3 db ifwtless dw stepfloat fall1 db 102,chx,2,chy,6 db 103,chx,-1,chy,9 db 104,chy,12 db 105,chx,-2 db setfall,1,15 db goto dw freefall *------------------------------- * p a t c h f a l l *------------------------------- patchfall db chx,-1,chy,-3 db goto dw fall1 *------------------------------- * s t e p f a l l 2 *------------------------------- stepfall2 ;from #12 (run-15) db chx,1 db goto dw stepfall *------------------------------- * s t e p f l o a t *------------------------------- stepfloat db 102,chx,2,chy,3 db 103,chx,-1,chy,4 db 104,chy,5 db 105,chx,-2 db setfall,1,6 db goto dw freefall *------------------------------- * j u m p f a l l *------------------------------- jumpfall ;from standjump-18 db act,3 db chx,1,chy,3 db 102,chx,2,chy,6 db 103,chx,1,chy,9 db 104,chx,2,chy,12 db 105 db setfall,2,15 db goto dw freefall *------------------------------- * r u n n i n g j u m p f a l l *------------------------------- rjumpfall ;from runjump-43 db act,3 db chx,1,chy,3 db 102,chx,3,chy,6 db 103,chx,2,chy,9 db 104,chx,3,chy,12 db 105 db setfall,3,15 db goto dw freefall *------------------------------- * j u m p h a n g *------------------------------- ;Med: DX = 0 jumphangMed db act,1 db 67,68,69,70,71,72,73,74,75,76,77 db act,2 db 78,79,80 db goto dw hang ;Long: DX = +4 jumphangLong db act,1 db 67,68,69,70,71,72,73,74,75,76,77 db act,2 db chx,1,78 db chx,2,79 db chx,1,80 db goto dw hang *------------------------------- * j u m p b a c k h a n g *------------------------------- jumpbackhang db act,1 db 67,68,69,70,71,72,73,74,75,76 db chx,-1,77 db act,2 db chx,-2,78 db chx,-1,79 db chx,-1,80 db goto dw hang *------------------------------- * h a n g *------------------------------- hang db act,2 ; db jaru db 91 hang1 db 90,89,88,87,87,87,88,89,90,91,92,93,94,95 db 96,97,98,99,97,96,95,94,93,92 db 91,90,89,88,87,88,89,90,91,92,93,94,95,96 db 95,94,93,92 db goto dw hangdrop *------------------------------- * h a n g s t r a i g h t *------------------------------- hangstraight db act,6 db tap,2 db 92,93,93,92,92 :loop db 91 db goto dw :loop *------------------------------- * c l i m b f a i l *------------------------------- climbfail db 135 db 136 db 137,137 db 138,138,138,138 db 137,136,135 db chx,-7 db goto dw hangdrop *------------------------------- * c l i m b d o w n *------------------------------- climbdown db act,1 db 148 db 145,144,143,142,141 db chx,-5 db chy,63 db down db act,3 ;to prevent a cut to scrn above db 140,138,136 db 91 db goto dw hang1 *------------------------------- * c l i m b u p *------------------------------- climbup db act,1 db 135 db 136 db 137 db 138 db 139 db 140 db chx,5 db chy,-63 db up db 141 db 142 db 143 db 144 db 145 db 146 db 147 db 148 db act,5 ;to clr flags db 149 db act,1 db 118,119 db chx,1 db goto dw stand *------------------------------- * h a n g d r o p *------------------------------- hangdrop ;1/2 story db act,0 ;NOTE -- hangdrop is an action relating ;to the ground, not to the ledge db 81,82 db act,5 ;to zero clrflags db 83 db act,1 db jard,tap,0 db 84,85 db chx,3 db goto dw stand *------------------------------- * h a n g f a l l *------------------------------- hangfall ;1/2 story db act,3 db 81,chy,6 db 81,chy,9 db 81,chy,12 db chx,2 db setfall,0,12 db goto dw freefall *------------------------------- * f r e e f a l l *------------------------------- freefall db act,4 :loop db 106 db goto dw :loop *------------------------------- * r u n s t o p *------------------------------- runstop db act,1 db 53,chx,2 db tap,1,54,chx,7 db 55 db tap,1,56,chx,2 db 49,chx,-2 db 50,51,52 db goto dw stand *------------------------------- * j u m p u p (& touch ceiling) *------------------------------- jumpup db act,1 db 67,68,69,70,71,72,73,74,75,76,77,78 db act,0 ;for cropchar db jaru,79 db goto dw hangdrop *------------------------------- * h i g h j u m p (no ceiling above) *------------------------------- highjump db act,1 db 67,68,69,70,71,72,73,74,75,76,77,78 db 79,chy,-4 db 79,chy,-2 db 79 db 79,chy,2 db 79,chy,4 db goto dw hangdrop *------------------------------- * s u p e r h i j u m p (when weightless) *------------------------------- superhijump db 67,68,69,70,71,72,73,74,75,76 db chy,-1,77 db chy,-3,78 db chy,-4,79 db chy,-10,79 db chy,-9,79 db chy,-8,79 db chy,-7,79 db chy,-6,79 db chy,-5,79 db chy,-4,79 db chy,-3,79 db chy,-2,79 db chy,-2,79 db chy,-1,79 db chy,-1,79 db chy,-1,79 db 79,79,79 db chy,1,79 db chy,1,79 db chy,2,79 db chy,2,79 db chy,3,79 db chy,4,79 db chy,5,79 db chy,6,79 db setfall,0,6 db goto dw freefall *------------------------------- * f a l l h a n g *------------------------------- fallhang db act,3 db 80 db tap,1 db goto dw hang *------------------------------- * b u m p *------------------------------- bump db act,5 db chx,-4 db 50,51,52 db goto dw stand *------------------------------- * b u m p f a l l *------------------------------- bumpfall db act,5 db chx,1,chy,3 db ifwtless dw bumpfloat db 102,chx,2,chy,6 db 103,chx,-1,chy,9 db 104,chy,12 db 105,chx,-2 db setfall,0,15 db goto dw freefall *------------------------------- * b u m p f l o a t *------------------------------- bumpfloat db 102,chx,2,chy,3 db 103,chx,-1,chy,4 db 104,chy,5 db 105,chx,-2 db setfall,0,6 db goto dw freefall *------------------------------- * h a r d b u m p *------------------------------- hardbump db act,5 db chx,-1,chy,-4,102 db chx,-1,chy,3 ;,104 db chx,-3,chy,1 db jard db chx,1 db tap,1 db 107,chx,2 db 108 db tap,1 db 109 db goto dw standup *------------------------------- * t e s t f o o t *------------------------------- testfoot db 121,chx,1 db 122 db 123,chx,2 db 124,chx,4 db 125,chx,3 db 126 db chx,-4,86 db tap,1,jard db chx,-4,116 db chx,-2 db 117,118,119 db goto dw stand *------------------------------- * s t e p b a c k *------------------------------- stepback db chx,-5 db goto dw stand *------------------------------- * s t e p f o r w a r d * * (1 - 14 pixels) *------------------------------- fullstep step14 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,3 db 124,chx,4 db 125,chx,3 db 126,chx,-1 db chx,3 db 127,128,129,130,131,132 db goto dw stand step13 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,3 db 124,chx,4 db 125,chx,3 db 126,chx,-1 db chx,2 db 127,128,129,130,131,132 db goto dw stand step12 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,3 db 124,chx,4 db 125,chx,3 db 126,chx,-1 db chx,1 db 127,128,129,130,131,132 db goto dw stand step11 ;corresponds directly to filmed sequence db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,3 db 124,chx,4 db 125,chx,3 db 126,chx,-1 db 127,128,129,130,131,132 db goto dw stand step10 db act,1 db 121,chx,1 step10a db 122,chx,1 db 123,chx,3 db 124,chx,4 db 125,chx,3 db 126,chx,-2 db 128,129,130,131,132 db goto dw stand step9 db act,1 db 121 db goto dw step10a step8 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,3 db 124,chx,4 db 125,chx,-1 db 127,128,129,130,131,132 db goto dw stand step7 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,3 db 124,chx,2 db 129,130,131,132 db goto dw stand step6 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,2 db 124,chx,2 db 129,130,131,132 db goto dw stand step5 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,2 db 124,chx,1 db 129,130,131,132 db goto dw stand step4 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,2 db 131,132 db goto dw stand step3 db act,1 db 121,chx,1 db 122,chx,1 db 123,chx,1 db 131,132 db goto dw stand step2 db act,1 db 121,chx,1 db 122,chx,1 db 132 db goto dw stand step1 db act,1 db 121,chx,1 db 132 db goto dw stand *------------------------------- * s t o o p *------------------------------- stoop db act,1 db chx,1 db 107,chx,2 db 108 :crouch db 109 db goto dw :crouch *------------------------------- * s t a n d u p *------------------------------- standup db act,5 db chx,1,110 db 111,chx,2 db 112 db 113,chx,1 db 114 db 115 db 116,chx,-4 db 117,118,119 db goto dw stand *------------------------------- * p i c k u p s w o r d *------------------------------- pickupsword db act,1 db effect,1 db 229,229,229,229,229,229 db 230,231,232 db goto dw resheathe *------------------------------- * r e s h e a t h e *------------------------------- resheathe db act,1 db chx,-5 db 233,234,235 db 236,237,238,239,240,133,133 db 134,134,134 db 48,chx,1 db 49,chx,-2 db act,5,50,act,1 db 51,52 db goto dw stand *------------------------------- * f a s t s h e a t h e *------------------------------- fastsheathe db act,1 db chx,-5 db 234,236,238,240,134 db chx,-1 db goto dw stand *------------------------------- * d r i n k p o t i o n *------------------------------- drinkpotion db act,1 db chx,4 db 191,192,193,194,195,196,197,198,199,200 db 201,202,203,204 ;if pressed for memory try ;cutting frames 202/204 or 201/203 db 205,205,205 db effect,1 db 205,205 db 201,198 db chx,-4 db goto dw stand *------------------------------- * s o f t l a n d *------------------------------- softland ;1 story db act,5 db jard db chx,1 db tap,1,107,chx,2 db 108 db tap,1 db act,1 :crouch db 109 db goto dw :crouch *------------------------------- * l a n d r u n *------------------------------- landrun db act,1 db chy,-2,chx,1 db 107,chx,2 db 108 db 109,chx,1 db 110 db 111,chx,2 db 112 db 113,chx,1,chy,1 db 114,chy,1 db 115,chx,-2 db goto dw runstt4 *------------------------------- * m e d i u m l a n d *------------------------------- medland ;1 1/2 - 2 stories db act,5 db jard db chy,-2,chx,1 ; db 107 db chx,2 db 108 db 109,109,109,109,109,109,109,109,109 db 109,109,109,109,109,109,109,109,109 db 109,109,109,109,109,109,109,109,109 db 109,109,chx,1 db 110,110,110 db 111,chx,2 db 112 db 113,chx,1,chy,1 db 114,chy,1 db 115 db 116,chx,-4 db 117 db 118 db 119 db goto dw stand *------------------------------- * h a r d l a n d (Splat!) *------------------------------- hardland ;> 2 stories db act,5 db jard db chy,-2,chx,3 db 185 db die :dead db 185 db goto dw :dead *------------------------------- * s t a b k i l l *------------------------------- stabkill db act,5 db goto dw dropdead *------------------------------- * d r o p d e a d *------------------------------- dropdead db act,1 db die db 179 db 180 db 181 db 182,chx,1 db 183,chx,-4 :dead db 185 db goto dw :dead *------------------------------- * i m p a l e *------------------------------- impale db act,1 db jard db chx,4 db 177 db die :dead db 177 db goto dw :dead *------------------------------- * h a l v e *------------------------------- halve db act,1 db 178 db die :dead db 178 db goto dw :dead *------------------------------- * c r u s h *------------------------------- crush db goto dw medland *------------------------------- * d e a d f a l l *------------------------------- deadfall db setfall,0,0 db act,4 :loop db 185 db goto dw :loop *------------------------------- * c l i m b s t a i r s *------------------------------- ;facing L climbstairs db act,5 db chx,-5,chy,-1 db tap,1,217 db 218 db 219,chx,1 db 220,chx,-4,chy,-3 db tap,1,221,chx,-4,chy,-2 db 222,222,chx,-2,chy,-3 db 223,223,chx,-3,chy,-8 db tap,1,224,224,chx,-1,chy,-1 db 225,225,chx,-3,chy,-4 db 226,226,chx,-1,chy,-5 db tap,1,227,227,chx,-2,chy,-1 db 228,228 db 0,tap,1 db 0,0,0,0,tap,1 db 0,0,0,0,tap,1 db 0,0,0,0,tap,1 do 0 db chx,10,chy,28 db goto dw stand fin db nextlevel :loop db 0,goto dw :loop *------------------------------- * Vizier: stand *------------------------------- Vstand db 54,goto dw Vstand *------------------------------- * Vizier: raise arms *------------------------------- Vraise db 85,67,67,67,67,67,67 db 68,69,70,71,72,73,74,75,83,84 :loop db 76 db goto dw :loop *------------------------------- * Vizier: walk *------------------------------- Vwalk db chx,1 Vwalk1 db 48,chx,2 Vwalk2 db 49,chx,6 db 50,chx,1 db 51,chx,-1 db 52,chx,1 db 53,chx,1 db goto dw Vwalk1 *------------------------------- * Vizier: stop *------------------------------- Vstop db chx,1 db 55,56 db goto dw Vstand *------------------------------- * Vizier: lower arms, turn & exit *------------------------------- Vexit db 77,78,79,80,81,82 db chx,1 db 54,54,54,54,54,54 ;standing db 57 db 58 db 59 db 60 db 61,chx,2 db 62,chx,-1 db 63,chx,-3 db 64 db 65,chx,-1 db 66 db aboutface,chx,16 db chx,3 db goto dw Vwalk2 *------------------------------- * Princess: stand *------------------------------- Pstand db 11,goto dw Pstand *------------------------------- * Princess: alert *------------------------------- Palert db 2,3,4,5,6,7,8,9 db aboutface,chx,9 db 11,goto dw Pstand *------------------------------- * Princess: step back *------------------------------- Pback db aboutface,chx,11 db 12 db chx,1,13 db chx,1,14 db chx,3,15 db chx,1,16 :loop db 17 db goto dw :loop *------------------------------- * Princess lying on cushions *------------------------------- Plie db 19 db goto dw Plie *------------------------------- * Princess: waiting *------------------------------- Pwaiting :loop db 20 db goto dw :loop *------------------------------- * Princess: embrace *------------------------------- Pembrace db 21 db chx,1,22 db 23 db 24 db chx,1,25 db chx,-3,26 db chx,-2,27 db chx,-4,28 db chx,-3,29 db chx,-2,30 db chx,-3,31 db chx,-1,32 :loop db 33 db goto dw :loop *------------------------------- * Princess: stroke mouse *------------------------------- Pstroke :loop db 37 db goto dw :loop *------------------------------- * Princess: rise *------------------------------- Prise db 37,38,39,40,41,42,43,44,45,46,47 db aboutface,chx,13 :loop db 11,goto dw :loop *------------------------------- * Princess: crouch & stroke mouse *------------------------------- Pcrouch db 11,11 db aboutface,chx,13 db 47,46,45,44,43,42,41,40,39,38,37 db 36,36,36,35,35,35 db 34,34,34,34,34,34,34 db 35,35,36,36,36,35,35,35 db 34,34,34,34,34,34,34 db 35,35,36,36,36,35,35,35 db 34,34,34,34,34,34,34,34,34 db 35,35,35 :loop db 36 db goto dw :loop *------------------------------- * Princess: slump shoulders *------------------------------- Pslump db 1 :loop db 18 db goto dw :loop *------------------------------- * Mouse: scurry *------------------------------- Mscurry db act,1 Mscurry1 :loop db 186,chx,5 db 186,chx,3 db 187,chx,4 db goto dw :loop *------------------------------- * Mouse: stop *------------------------------- Mstop :loop db 186 db goto dw :loop *------------------------------- * Mouse: raise head *------------------------------- Mraise :loop db 188 db goto dw :loop *------------------------------- * Mouse: leave *------------------------------- Mleave db act,0 db 186,186,186 db 188,188,188,188,188,188,188,188 db aboutface,chx,8 db goto dw Mscurry1 *------------------------------- * Mouse: climb *------------------------------- Mclimb db 186 db goto dw Mclimb *------------------------------- lst ds 1 usr $a9,15,$800,*-org lst off \ No newline at end of file +* seqtable +org = $3000 + tr on ;TABS 15,20,40 + lst off + lstdo off + +*------------------------------- +* Seq table instructions: + +goto = -1 +aboutface = -2 +up = -3 +down = -4 +chx = -5 +chy = -6 +act = -7 +setfall = -8 +ifwtless = -9 +die = -10 +jaru = -11 +jard = -12 +effect = -13 +tap = -14 +nextlevel = -15 + +*------------------------------- +* +* S E Q U E N C E T A B L E +* +*------------------------------- + org org + +:1 dw startrun +:2 dw stand +:3 dw standjump +:4 dw runjump +:5 dw turn +:6 dw runturn +:7 dw stepfall +:8 dw jumphangMed +:9 dw hang +:10 dw climbup +:11 dw hangdrop +:12 dw freefall +:13 dw runstop +:14 dw jumpup +:15 dw fallhang +:16 dw jumpbackhang +:17 dw softland +:18 dw jumpfall +:19 dw stepfall2 +:20 dw medland +:21 dw rjumpfall +:22 dw hardland +:23 dw hangfall +:24 dw jumphangLong +:25 dw hangstraight +:26 dw rdiveroll +:27 dw sdiveroll +:28 dw highjump +:29 dw step1 +:30 dw step2 +:31 dw step3 +:32 dw step4 +:33 dw step5 +:34 dw step6 +:35 dw step7 +:36 dw step8 +:37 dw step9 +:38 dw step10 +:39 dw step11 +:40 dw step12 +:41 dw step13 +:42 dw fullstep +:43 dw turnrun +:44 dw testfoot +:45 dw bumpfall +:46 dw hardbump +:47 dw bump +:48 dw superhijump +:49 dw standup +:50 dw stoop +:51 dw impale +:52 dw crush +:53 dw deadfall +:54 dw halve +:55 dw engarde +:56 dw advance +:57 dw retreat +:58 dw strike +:59 dw flee +:60 dw turnengarde +:61 dw strikeblock +:62 dw readyblock +:63 dw landengarde +:64 dw bumpengfwd +:65 dw bumpengback +:66 dw blocktostrike +:67 dw strikeadv +:68 dw climbdown +:69 dw blockedstrike +:70 dw climbstairs +:71 dw dropdead +:72 dw stepback +:73 dw climbfail +:74 dw stabbed +:75 dw faststrike +:76 dw strikeret +:77 dw alertstand +:78 dw drinkpotion +:79 dw crawl +:80 dw alertturn +:81 dw fightfall +:82 dw efightfall +:83 dw efightfallfwd +:84 dw running +:85 dw stabkill +:86 dw fastadvance +:87 dw goalertstand +:88 dw arise +:89 dw turndraw +:90 dw guardengarde +:91 dw pickupsword +:92 dw resheathe +:93 dw fastsheathe +:94 dw Pstand +:95 dw Vstand +:96 dw Vwalk +:97 dw Vstop +:98 dw Palert +:99 dw Pback +:100 dw Vexit +:101 dw Mclimb +:102 dw Vraise +:103 dw Plie +:104 dw patchfall +:105 dw Mscurry +:106 dw Mstop +:107 dw Mleave +:108 dw Pembrace +:109 dw Pwaiting +:110 dw Pstroke +:111 dw Prise +:112 dw Pcrouch +:113 dw Pslump +:114 dw Mraise + +*------------------------------- +* r u n n i n g +*------------------------------- +running + db act,1 + db goto + dw runcyc1 + +*------------------------------- +* s t a r t r u n +*------------------------------- +startrun + db act,1 +runstt1 db 1 +runstt2 db 2 +runstt3 db 3 +runstt4 db 4,chx,8 +runstt5 db 5,chx,3 +runstt6 db 6,chx,3 + +runcyc1 db 7,chx,5 +runcyc2 db 8,chx,1 +runcyc3 db tap,1,9,chx,2 +runcyc4 db 10,chx,4 +runcyc5 db 11,chx,5 +runcyc6 db 12,chx,2 +runcyc7 db tap,1,13,chx,3 +runcyc8 db 14,chx,4 + db goto + dw runcyc1 + +*------------------------------- +* s t a n d +*------------------------------- +stand + db act,0 + db 15 + db goto + dw stand + +*------------------------------- +* a l e r t s t a n d +*------------------------------- +goalertstand + db act,1 +alertstand +:loop db 166 + db goto + dw :loop + +*------------------------------- +* a r i s e (skeleton) +*------------------------------- +arise + db act,5 + db chx,10,177 + db 177 + db chx,-7,chy,-2,178 + db chx,5,chy,2,166 + db chx,-1 + db goto + dw ready + +*------------------------------- +* g u a r d e n g a r d e +*------------------------------- +guardengarde + db goto + dw ready + +*------------------------------- +* e n g a r d e +*------------------------------- +engarde + db act,1 + db chx,2 + db 207 + db 208,chx,2 + db 209,chx,2 + db 210,chx,3 +ready + db act,1 + db tap,0 + db 158 + db 170 +:loop db 171 + + db goto + dw :loop + +*------------------------------- +* s t a b b e d +*------------------------------- +stabbed + db act,5 + db setfall,-1,0 + db 172,chx,-1,chy,1 + db 173,chx,-1 + db 174,chx,-1,chy,2 +; db 175 + db chx,-2,chy,1 + db chx,-5,chy,-4 + db goto + dw guy8 + +*------------------------------- +* s t r i k e - a d v a n c e +*------------------------------- +;from guy6 (154) +strikeadv + db act,1 + db setfall,1,0 + db 155 + db chx,2,165 + db chx,-2 + db goto + dw ready + +*------------------------------- +* s t r i k e - r e t r e a t +*------------------------------- + ;from guy6 (154) +strikeret + db act,1 + db setfall,-1,0 + db 155,156,157 + db 158 + db goto + dw retreat + +*------------------------------- +* a d v a n c e +*------------------------------- +advance + db act,1 + db setfall,1,0 + db chx,2,163 + db chx,4,164 + db 165 + + db goto + dw ready + +*------------------------------- +* f a s t a d v a n c e +*------------------------------- +fastadvance + db act,1 + db setfall,1,0 + db chx,6,164 + db 165 + + db goto + dw ready + +*------------------------------- +* r e t r e a t +*------------------------------- +retreat + db act,1 + db setfall,-1,0 + db chx,-3,160 + db chx,-2,157 + + db goto + dw ready + +*------------------------------- +* s t r i k e +*------------------------------- +strike + db act,1 + db setfall,-1,0 + db 168 + +faststrike + db act,1 +guy3 db 151 +guy4 db act,1 + db 152 +;-->blockedstrike +guy5 db 153 +guy6 db 154 +guy7 db act,5 ;clr flags to avoid repeat strike + db 155 +guy8 db act,1 + db 156 +guy9 db 157 + + db goto + dw ready + +*------------------------------- +* b l o c k e d s t r i k e +*------------------------------- +blockedstrike + db act,1 + db 167 +;--> strikeblock + db goto + dw guy7 + +*------------------------------- +* b l o c k t o s t r i k e +*------------------------------- +blocktostrike + db 162 + db goto + dw guy4 + +*------------------------------- +* r e a d y b l o c k +*------------------------------- +readyblock + db 169 +blocking + db 150 + ;--> blocktostrike/retreat + db goto + dw ready + +*------------------------------- +* s t r i k e t o b l o c k +*------------------------------- +strikeblock + db 159 + db 160 + db goto + dw blocking + +*------------------------------- +* l a n d e n g a r d e +*------------------------------- +landengarde + db act,1 + db jard + + db goto + dw ready + +*------------------------------- +* b u m p e n g a r d e ( f o r w a r d ) +*------------------------------- +bumpengfwd + db act,5 + db chx,-8 + + db goto + dw ready + +*------------------------------- +* b u m p e n g a r d e ( b a c k ) +*------------------------------- +bumpengback + db act,5 + db 160 + db 157 + db goto + dw ready + +*------------------------------- +* f l e e +*------------------------------- +flee + db act,7 + db chx,-8 + + db goto + dw turn + +*------------------------------- +* t u r n e n g a r d e +*------------------------------- +turnengarde + db act,5 + db aboutface,chx,5 + + db goto + dw retreat + +*------------------------------- +* a l e r t t u r n (for enemies) +*------------------------------- +alertturn + db act,5 + + db aboutface,chx,18 + + db goto + dw goalertstand + +*------------------------------- +* s t a n d j u m p +*------------------------------- +standjump + db act,1 + db 16 + db 17,chx,2 + db 18,chx,2 + db 19,chx,2 + db 20,chx,2 + db 21,chx,2 + db 22,chx,7 + db 23,chx,9 + db 24,chx,5,chy,-6 ;chx 6? +sjland db 25,chx,1,chy,6 + db 26,chx,4 + db jard + db tap,1,27,chx,-3 + db 28,chx,5 + db 29 + db tap,1,30 + db 31 + db 32 + db 33,chx,1 + db goto + dw stand + +*------------------------------- +* r u n j u m p +*------------------------------- +runjump + db act,1 + db tap,1,34,chx,5 + db 35,chx,6 + db 36,chx,3 + db 37,chx,5 + db tap,1,38,chx,7 + db 39,chx,12,chy,-3 + db 40,chx,8,chy,-9 + db 41,chx,8,chy,-2 + db 42,chx,4,chy,11 + db 43,chx,4,chy,3 +rjlandrun + db 44,chx,5 + db jard,tap,1 + db goto + dw runcyc1 + +*------------------------------- +* r u n d i v e r o l l +*------------------------------- +rdiveroll + db act,1 + + db chx,1 + db 107,chx,2 + db chx,2 + db 108 + db chx,2 + db 109 + db chx,2 + db 109 + db chx,2 +:crouch db 109 + db goto + dw :crouch + +*------------------------------- +* s t a n d d i v e r o l l +*------------------------------- +sdiveroll + +*------------------------------- +* c r a w l +*------------------------------- +crawl + db act,1 + db chx,1,110 + db 111,chx,2 + db 112 + + db chx,2 + db 108 + db chx,2 +:crouch db 109 + db goto + dw :crouch + +*------------------------------- +* t u r n d r a w +*------------------------------- +turndraw + db act,7 + db aboutface,chx,6 + db 45,chx,1 + db 46 + db goto + dw engarde + +*------------------------------- +* t u r n +*------------------------------- +turn + db act,7 + db aboutface,chx,6 + db 45,chx,1 + db 46,chx,2 + db 47,chx,-1 +finishturn + db 48,chx,1 + db 49,chx,-2 + db 50,51,52 + db goto + dw stand + +*------------------------------- +* t u r n r u n +* (from frame 48) +*------------------------------- +turnrun + db act,1 + db chx,-1 + db goto + dw runstt1 + +*------------------------------- +* r u n t u r n +*------------------------------- +runturn + db act,1 + db chx,1 + db 53,chx,1 + db tap,1,54,chx,8 + db 55 + db tap,1,56,chx,7 + db 57,chx,3 + db 58,chx,1 + db 59 + db 60,chx,2 + db 61,chx,-1 + db 62 + db 63 + db 64,chx,-1 + db 65,chx,-14 + db aboutface,goto + dw runcyc7 + +*------------------------------- +* f i g h t f a l l (backward) +*------------------------------- +fightfall + db act,3 + db chy,-1 + + db 102,chx,-2,chy,6 + db 103,chx,-2,chy,9 + db 104,chx,-1,chy,12 + db 105,chx,-3 + + db setfall,0,15 + db goto + dw freefall + +*------------------------------- +* e n e m y f i g h t f a l l +*------------------------------- +efightfall + db act,3 + db chy,-1,chx,-2 + + db 102,chx,-3,chy,6 + db 103,chx,-3,chy,9 + db 104,chx,-2,chy,12 + db 105,chx,-3 +;for now--ultimately we want enemy +;shapes in here + db setfall,0,15 + db goto + dw freefall + +*------------------------------- +* e n e m y f i g h t f a l l f w d +*------------------------------- +efightfallfwd + db act,3 + db chx,1,chy,-1 + + db 102,chx,2,chy,6 + db 103,chx,-1,chy,9 + db 104,chy,12 + db 105,chx,-2 +;for now--ultimately we want enemy +;shapes in here + db setfall,1,15 + db goto + dw freefall + + +*------------------------------- +* s t e p f a l l +*------------------------------- +stepfall ;from #8 (run-11) + db act,3 + db chx,1,chy,3 + + db ifwtless + dw stepfloat +fall1 + db 102,chx,2,chy,6 + db 103,chx,-1,chy,9 + db 104,chy,12 + db 105,chx,-2 + + db setfall,1,15 + db goto + dw freefall + +*------------------------------- +* p a t c h f a l l +*------------------------------- +patchfall + db chx,-1,chy,-3 + db goto + dw fall1 + +*------------------------------- +* s t e p f a l l 2 +*------------------------------- +stepfall2 ;from #12 (run-15) + db chx,1 + db goto + dw stepfall + +*------------------------------- +* s t e p f l o a t +*------------------------------- +stepfloat + db 102,chx,2,chy,3 + db 103,chx,-1,chy,4 + db 104,chy,5 + db 105,chx,-2 + + db setfall,1,6 + db goto + dw freefall + +*------------------------------- +* j u m p f a l l +*------------------------------- +jumpfall ;from standjump-18 + db act,3 + db chx,1,chy,3 + db 102,chx,2,chy,6 + db 103,chx,1,chy,9 + db 104,chx,2,chy,12 + db 105 + + db setfall,2,15 + db goto + dw freefall + +*------------------------------- +* r u n n i n g j u m p f a l l +*------------------------------- +rjumpfall ;from runjump-43 + db act,3 + db chx,1,chy,3 + db 102,chx,3,chy,6 + db 103,chx,2,chy,9 + db 104,chx,3,chy,12 + db 105 + + db setfall,3,15 + db goto + dw freefall + +*------------------------------- +* j u m p h a n g +*------------------------------- +;Med: DX = 0 +jumphangMed + db act,1 + db 67,68,69,70,71,72,73,74,75,76,77 + db act,2 + db 78,79,80 + db goto + dw hang + +;Long: DX = +4 +jumphangLong + db act,1 + db 67,68,69,70,71,72,73,74,75,76,77 + db act,2 + db chx,1,78 + db chx,2,79 + db chx,1,80 + + db goto + dw hang + +*------------------------------- +* j u m p b a c k h a n g +*------------------------------- +jumpbackhang + db act,1 + db 67,68,69,70,71,72,73,74,75,76 + db chx,-1,77 + db act,2 + db chx,-2,78 + db chx,-1,79 + db chx,-1,80 + + db goto + dw hang + +*------------------------------- +* h a n g +*------------------------------- +hang + db act,2 +; db jaru + db 91 +hang1 + db 90,89,88,87,87,87,88,89,90,91,92,93,94,95 + db 96,97,98,99,97,96,95,94,93,92 + db 91,90,89,88,87,88,89,90,91,92,93,94,95,96 + db 95,94,93,92 + db goto + dw hangdrop + +*------------------------------- +* h a n g s t r a i g h t +*------------------------------- +hangstraight + db act,6 + db tap,2 + db 92,93,93,92,92 +:loop db 91 + db goto + dw :loop + +*------------------------------- +* c l i m b f a i l +*------------------------------- +climbfail + db 135 + db 136 + db 137,137 + db 138,138,138,138 + db 137,136,135 + db chx,-7 + + db goto + dw hangdrop + +*------------------------------- +* c l i m b d o w n +*------------------------------- +climbdown + db act,1 + + db 148 + db 145,144,143,142,141 + + db chx,-5 + db chy,63 + db down + db act,3 ;to prevent a cut to scrn above + + db 140,138,136 + db 91 + db goto + dw hang1 + +*------------------------------- +* c l i m b u p +*------------------------------- +climbup + db act,1 + + db 135 + db 136 + db 137 + db 138 + db 139 + db 140 + + db chx,5 + db chy,-63 + db up + + db 141 + db 142 + db 143 + db 144 + db 145 + db 146 + db 147 + db 148 + db act,5 ;to clr flags + db 149 + db act,1 + + db 118,119 + db chx,1 + db goto + dw stand + +*------------------------------- +* h a n g d r o p +*------------------------------- +hangdrop ;1/2 story + + db act,0 ;NOTE -- hangdrop is an action relating +;to the ground, not to the ledge + db 81,82 + db act,5 ;to zero clrflags + db 83 + db act,1 + db jard,tap,0 + db 84,85 + db chx,3 + db goto + dw stand + +*------------------------------- +* h a n g f a l l +*------------------------------- +hangfall ;1/2 story + + db act,3 + db 81,chy,6 + db 81,chy,9 + db 81,chy,12 + db chx,2 + + db setfall,0,12 + db goto + dw freefall + +*------------------------------- +* f r e e f a l l +*------------------------------- +freefall + db act,4 +:loop db 106 + db goto + dw :loop + +*------------------------------- +* r u n s t o p +*------------------------------- +runstop + db act,1 + db 53,chx,2 + db tap,1,54,chx,7 + db 55 + db tap,1,56,chx,2 + db 49,chx,-2 + db 50,51,52 + db goto + dw stand + +*------------------------------- +* j u m p u p (& touch ceiling) +*------------------------------- +jumpup + db act,1 + db 67,68,69,70,71,72,73,74,75,76,77,78 + db act,0 ;for cropchar + db jaru,79 + + db goto + dw hangdrop + +*------------------------------- +* h i g h j u m p (no ceiling above) +*------------------------------- +highjump + db act,1 + db 67,68,69,70,71,72,73,74,75,76,77,78 + db 79,chy,-4 + db 79,chy,-2 + db 79 + db 79,chy,2 + db 79,chy,4 + db goto + dw hangdrop + +*------------------------------- +* s u p e r h i j u m p (when weightless) +*------------------------------- +superhijump + db 67,68,69,70,71,72,73,74,75,76 + db chy,-1,77 + db chy,-3,78 + db chy,-4,79 + db chy,-10,79 + db chy,-9,79 + db chy,-8,79 + db chy,-7,79 + db chy,-6,79 + db chy,-5,79 + db chy,-4,79 + db chy,-3,79 + db chy,-2,79 + db chy,-2,79 + db chy,-1,79 + db chy,-1,79 + db chy,-1,79 + db 79,79,79 + db chy,1,79 + db chy,1,79 + db chy,2,79 + db chy,2,79 + db chy,3,79 + db chy,4,79 + db chy,5,79 + db chy,6,79 + + db setfall,0,6 + db goto + dw freefall + +*------------------------------- +* f a l l h a n g +*------------------------------- +fallhang + db act,3 + db 80 + db tap,1 + db goto + dw hang + +*------------------------------- +* b u m p +*------------------------------- +bump + db act,5 + db chx,-4 + + db 50,51,52 + db goto + dw stand + +*------------------------------- +* b u m p f a l l +*------------------------------- +bumpfall + db act,5 + db chx,1,chy,3 + + db ifwtless + dw bumpfloat + + db 102,chx,2,chy,6 + db 103,chx,-1,chy,9 + db 104,chy,12 + db 105,chx,-2 + + db setfall,0,15 + db goto + dw freefall + +*------------------------------- +* b u m p f l o a t +*------------------------------- +bumpfloat + db 102,chx,2,chy,3 + db 103,chx,-1,chy,4 + db 104,chy,5 + db 105,chx,-2 + + db setfall,0,6 + db goto + dw freefall + +*------------------------------- +* h a r d b u m p +*------------------------------- +hardbump + db act,5 + + db chx,-1,chy,-4,102 + db chx,-1,chy,3 ;,104 + db chx,-3,chy,1 + + db jard + db chx,1 + db tap,1 + db 107,chx,2 + db 108 + db tap,1 + + db 109 + db goto + dw standup + +*------------------------------- +* t e s t f o o t +*------------------------------- +testfoot + db 121,chx,1 + db 122 + db 123,chx,2 + db 124,chx,4 + db 125,chx,3 + db 126 + + db chx,-4,86 + db tap,1,jard + db chx,-4,116 + db chx,-2 + db 117,118,119 + db goto + dw stand + +*------------------------------- +* s t e p b a c k +*------------------------------- +stepback + db chx,-5 + db goto + dw stand + +*------------------------------- +* s t e p f o r w a r d +* +* (1 - 14 pixels) +*------------------------------- +fullstep +step14 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,3 + db 124,chx,4 + db 125,chx,3 + db 126,chx,-1 + + db chx,3 + + db 127,128,129,130,131,132 + db goto + dw stand + +step13 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,3 + db 124,chx,4 + db 125,chx,3 + db 126,chx,-1 + + db chx,2 + + db 127,128,129,130,131,132 + db goto + dw stand + +step12 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,3 + db 124,chx,4 + db 125,chx,3 + db 126,chx,-1 + + db chx,1 + + db 127,128,129,130,131,132 + db goto + dw stand + +step11 ;corresponds directly to filmed sequence + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,3 + db 124,chx,4 + db 125,chx,3 + db 126,chx,-1 + db 127,128,129,130,131,132 + db goto + dw stand + +step10 + db act,1 + db 121,chx,1 +step10a db 122,chx,1 + db 123,chx,3 + db 124,chx,4 + db 125,chx,3 + db 126,chx,-2 + db 128,129,130,131,132 + db goto + dw stand + +step9 + db act,1 + db 121 + db goto + dw step10a + +step8 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,3 + db 124,chx,4 + db 125,chx,-1 + db 127,128,129,130,131,132 + db goto + dw stand + +step7 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,3 + db 124,chx,2 + + db 129,130,131,132 + db goto + dw stand + +step6 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,2 + db 124,chx,2 + + db 129,130,131,132 + db goto + dw stand + +step5 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,2 + db 124,chx,1 + + db 129,130,131,132 + db goto + dw stand + +step4 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,2 + + db 131,132 + db goto + dw stand + +step3 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 123,chx,1 + + db 131,132 + db goto + dw stand + +step2 + db act,1 + db 121,chx,1 + db 122,chx,1 + db 132 + db goto + dw stand + +step1 + db act,1 + db 121,chx,1 + db 132 + db goto + dw stand + +*------------------------------- +* s t o o p +*------------------------------- +stoop + db act,1 + + db chx,1 + db 107,chx,2 + db 108 + +:crouch db 109 + db goto + dw :crouch + +*------------------------------- +* s t a n d u p +*------------------------------- +standup + db act,5 + db chx,1,110 + db 111,chx,2 + db 112 + db 113,chx,1 + db 114 + db 115 + db 116,chx,-4 + db 117,118,119 + + db goto + dw stand + +*------------------------------- +* p i c k u p s w o r d +*------------------------------- +pickupsword + db act,1 + db effect,1 + db 229,229,229,229,229,229 + db 230,231,232 + + db goto + dw resheathe + +*------------------------------- +* r e s h e a t h e +*------------------------------- +resheathe + db act,1 + db chx,-5 + db 233,234,235 + db 236,237,238,239,240,133,133 + db 134,134,134 + db 48,chx,1 + db 49,chx,-2 + db act,5,50,act,1 + db 51,52 + db goto + dw stand + +*------------------------------- +* f a s t s h e a t h e +*------------------------------- +fastsheathe + db act,1 + db chx,-5 + db 234,236,238,240,134 + db chx,-1 + db goto + dw stand + +*------------------------------- +* d r i n k p o t i o n +*------------------------------- +drinkpotion + db act,1 + db chx,4 + db 191,192,193,194,195,196,197,198,199,200 + db 201,202,203,204 +;if pressed for memory try +;cutting frames 202/204 or 201/203 + db 205,205,205 + db effect,1 + db 205,205 + db 201,198 + + db chx,-4 + db goto + dw stand + +*------------------------------- +* s o f t l a n d +*------------------------------- +softland ;1 story + db act,5 + + db jard + db chx,1 + db tap,1,107,chx,2 + db 108 + db tap,1 + + db act,1 +:crouch db 109 + db goto + dw :crouch + +*------------------------------- +* l a n d r u n +*------------------------------- +landrun + db act,1 + db chy,-2,chx,1 + db 107,chx,2 + db 108 + db 109,chx,1 + db 110 + db 111,chx,2 + db 112 + db 113,chx,1,chy,1 + db 114,chy,1 + db 115,chx,-2 + + db goto + dw runstt4 + +*------------------------------- +* m e d i u m l a n d +*------------------------------- +medland ;1 1/2 - 2 stories + db act,5 + db jard + db chy,-2,chx,1 +; db 107 + db chx,2 + db 108 + db 109,109,109,109,109,109,109,109,109 + db 109,109,109,109,109,109,109,109,109 + db 109,109,109,109,109,109,109,109,109 + db 109,109,chx,1 + db 110,110,110 + db 111,chx,2 + db 112 + db 113,chx,1,chy,1 + db 114,chy,1 + db 115 + db 116,chx,-4 + db 117 + db 118 + db 119 + db goto + dw stand + +*------------------------------- +* h a r d l a n d (Splat!) +*------------------------------- +hardland ;> 2 stories + db act,5 + db jard + db chy,-2,chx,3 + db 185 + db die + +:dead db 185 + db goto + dw :dead + +*------------------------------- +* s t a b k i l l +*------------------------------- +stabkill + db act,5 + db goto + dw dropdead + +*------------------------------- +* d r o p d e a d +*------------------------------- +dropdead + db act,1 + db die + + db 179 + db 180 + db 181 + db 182,chx,1 + db 183,chx,-4 +:dead db 185 + db goto + dw :dead + +*------------------------------- +* i m p a l e +*------------------------------- +impale + db act,1 + db jard + + db chx,4 + db 177 + db die + +:dead db 177 + db goto + dw :dead + +*------------------------------- +* h a l v e +*------------------------------- +halve + db act,1 + + db 178 + db die + +:dead db 178 + db goto + dw :dead + +*------------------------------- +* c r u s h +*------------------------------- +crush + db goto + dw medland + +*------------------------------- +* d e a d f a l l +*------------------------------- +deadfall + db setfall,0,0 + db act,4 +:loop db 185 + db goto + dw :loop + +*------------------------------- +* c l i m b s t a i r s +*------------------------------- +;facing L +climbstairs + db act,5 + db chx,-5,chy,-1 + db tap,1,217 + db 218 + db 219,chx,1 + db 220,chx,-4,chy,-3 + db tap,1,221,chx,-4,chy,-2 + db 222,222,chx,-2,chy,-3 + db 223,223,chx,-3,chy,-8 + db tap,1,224,224,chx,-1,chy,-1 + db 225,225,chx,-3,chy,-4 + db 226,226,chx,-1,chy,-5 + db tap,1,227,227,chx,-2,chy,-1 + db 228,228 + db 0,tap,1 + db 0,0,0,0,tap,1 + db 0,0,0,0,tap,1 + db 0,0,0,0,tap,1 + + do 0 + db chx,10,chy,28 + db goto + dw stand + fin + + db nextlevel +:loop db 0,goto + dw :loop + +*------------------------------- +* Vizier: stand +*------------------------------- +Vstand + db 54,goto + dw Vstand + +*------------------------------- +* Vizier: raise arms +*------------------------------- +Vraise + db 85,67,67,67,67,67,67 + db 68,69,70,71,72,73,74,75,83,84 +:loop db 76 + db goto + dw :loop + +*------------------------------- +* Vizier: walk +*------------------------------- +Vwalk + db chx,1 +Vwalk1 db 48,chx,2 +Vwalk2 db 49,chx,6 + db 50,chx,1 + db 51,chx,-1 + db 52,chx,1 + db 53,chx,1 + db goto + dw Vwalk1 + +*------------------------------- +* Vizier: stop +*------------------------------- +Vstop + db chx,1 + db 55,56 + db goto + dw Vstand + +*------------------------------- +* Vizier: lower arms, turn & exit +*------------------------------- +Vexit + db 77,78,79,80,81,82 + db chx,1 + db 54,54,54,54,54,54 ;standing + db 57 + db 58 + db 59 + db 60 + db 61,chx,2 + db 62,chx,-1 + db 63,chx,-3 + db 64 + db 65,chx,-1 + db 66 + db aboutface,chx,16 + db chx,3 + db goto + dw Vwalk2 + +*------------------------------- +* Princess: stand +*------------------------------- +Pstand + db 11,goto + dw Pstand + +*------------------------------- +* Princess: alert +*------------------------------- +Palert + db 2,3,4,5,6,7,8,9 + db aboutface,chx,9 + db 11,goto + dw Pstand + +*------------------------------- +* Princess: step back +*------------------------------- +Pback + db aboutface,chx,11 + db 12 + db chx,1,13 + db chx,1,14 + db chx,3,15 + db chx,1,16 +:loop db 17 + db goto + dw :loop + +*------------------------------- +* Princess lying on cushions +*------------------------------- +Plie + db 19 + db goto + dw Plie + +*------------------------------- +* Princess: waiting +*------------------------------- +Pwaiting +:loop db 20 + db goto + dw :loop + +*------------------------------- +* Princess: embrace +*------------------------------- +Pembrace + db 21 + db chx,1,22 + db 23 + db 24 + db chx,1,25 + db chx,-3,26 + db chx,-2,27 + db chx,-4,28 + db chx,-3,29 + db chx,-2,30 + db chx,-3,31 + db chx,-1,32 +:loop db 33 + db goto + dw :loop + +*------------------------------- +* Princess: stroke mouse +*------------------------------- +Pstroke +:loop db 37 + db goto + dw :loop + +*------------------------------- +* Princess: rise +*------------------------------- +Prise + db 37,38,39,40,41,42,43,44,45,46,47 + db aboutface,chx,13 +:loop db 11,goto + dw :loop + +*------------------------------- +* Princess: crouch & stroke mouse +*------------------------------- +Pcrouch + db 11,11 + db aboutface,chx,13 + db 47,46,45,44,43,42,41,40,39,38,37 + db 36,36,36,35,35,35 + db 34,34,34,34,34,34,34 + db 35,35,36,36,36,35,35,35 + db 34,34,34,34,34,34,34 + db 35,35,36,36,36,35,35,35 + db 34,34,34,34,34,34,34,34,34 + db 35,35,35 +:loop db 36 + db goto + dw :loop + +*------------------------------- +* Princess: slump shoulders +*------------------------------- +Pslump + db 1 +:loop db 18 + db goto + dw :loop + +*------------------------------- +* Mouse: scurry +*------------------------------- +Mscurry + db act,1 +Mscurry1 +:loop db 186,chx,5 + db 186,chx,3 + db 187,chx,4 + db goto + dw :loop + +*------------------------------- +* Mouse: stop +*------------------------------- +Mstop +:loop db 186 + db goto + dw :loop + +*------------------------------- +* Mouse: raise head +*------------------------------- +Mraise +:loop db 188 + db goto + dw :loop + +*------------------------------- +* Mouse: leave +*------------------------------- +Mleave + db act,0 + db 186,186,186 + db 188,188,188,188,188,188,188,188 + db aboutface,chx,8 + db goto + dw Mscurry1 + +*------------------------------- +* Mouse: climb +*------------------------------- +Mclimb + db 186 + db goto + dw Mclimb + +*------------------------------- + lst + ds 1 + usr $a9,15,$800,*-org + lst off diff --git a/01 POP Source/Source/SOUND.S b/01 POP Source/Source/SOUND.S index 906749b..6b36aea 100755 --- a/01 POP Source/Source/SOUND.S +++ b/01 POP Source/Source/SOUND.S @@ -1 +1,360 @@ -* sound org = $ea00 lst off *------------------------------- * * S O U N D * *------------------------------- org org jmp PLAYBACK *------------------------------- savex ds 1 spkr = $c030 *------------------------------- put soundnames put gameeq put eq *------------------------------- * * L O O K U P * * Sound routine lookup table * *------------------------------- lookup :0 dw DoPlateDown :1 dw DoPlateUp :2 dw DoGateDown :3 dw DoSpecialKey1 :4 dw DoSpecialKey2 :5 dw DoSplat :6 dw DoMirrorCrack :7 dw DoLooseCrash :8 dw DoGotKey :9 dw DoFootstep :10 dw DoRaisingExit :11 dw DoRaisingGate :12 dw DoLowerGate :13 dw DoSmackWall :14 dw DoImpaled :15 dw DoGateSlam :16 dw DoFlashMsg :17 dw DoSwordClash1 :18 dw DoSwordClash2 :19 dw DoJawsClash endlook maxaddr = endlook-lookup *------------------------------- * * Z E R O S O U N D * * Zero sound table * *------------------------------- ZEROSOUND lda #0 ;# sounds in table sta soundtable rts *------------------------------- * * A D D S O U N D * * Add sound to sound table * (preserve registers) * * In: A = sound # * *------------------------------- ADDSOUND stx savex ldx soundtable cpx #maxsfx bcs :rts ;sound table full inx sta soundtable,x stx soundtable ;# sounds in table :rts ldx savex rts *------------------------------- * * P L A Y B A C K * * Playback all sounds listed in sound table * *------------------------------- PLAYBACK lda soundon beq :rts ;sound switched off? ldx soundtable beq :rts ;sound table empty? :loop lda soundtable,x stx savex jsr makesound ;make sound #A ;(may destroy registers) ldx savex dex bne :loop :rts rts *------------------------------- * * M A K E S O U N D * * In: A = sound # (0-127) * *------------------------------- makesound asl cmp #maxaddr bcs :rts ;don't exceed lookup table tax lda lookup,x sta :sm+1 lda lookup+1,x sta :sm+2 :sm jmp $ffff ;self-modifying code :rts rts *------------------------------- * * S O U N D R O U T I N E S * *------------------------------- * Kid steps on pressplate DoPlateDown ldy #70 ldx #0 lda #4 jmp tone *------------------------------- * Pressplate pops back up DoPlateUp ldy #90 ldx #0 lda #4 jmp tone *------------------------------- * Gate hits stone floor with an ominous CLANG DoGateDown ldy #70 ldx #0 lda #4 jmp tone *------------------------------- * Jaws clash DoJawsClash ldy #10 ldx #0 lda #50 jmp tone *------------------------------- * Acknowledge special keypress SK1Pitch = 15 SK1Dur = 50 SK2Pitch = 40 SK2Dur = 50 DoSpecialKey1 DoSwordClash1 DoSwordClash2 ldy #SK1Pitch ldx #>SK1Pitch lda #SK1Dur jmp tone DoSpecialKey2 ldy #SK2Pitch ldx #>SK2Pitch lda #SK2Dur jmp tone *------------------------------- * Splat SplatPitch = 1000 SplatDur = 3 DoSplat ldy #SplatPitch ldx #>SplatPitch lda #SplatDur jmp tone *------------------------------- * Mirror Crack DoMirrorCrack jmp DoSplat rts *------------------------------- * Loose Floor Crash DoLooseCrash jmp DoSplat *------------------------------- * Flash message ]HiPitch = 100 ]HiDur = 25 ]LoPitch = 500 ]LoDur = 15 DoGotKey DoFlashMsg lda #2 :loop pha ldy #]LoPitch ldx #>]LoPitch lda #]LoDur jsr tone ldy #]HiPitch ldx #>]HiPitch lda #]HiDur jsr tone pla sec sbc #1 bne :loop rts *------------------------------- * Footstep DoFootstep ldy #35 ldx #0 lda #3 jmp tone *------------------------------- * Raising Exit DoRaisingExit ldy #40 ldx #0 lda #6 jmp tone *------------------------------- * Raising Gate DoRaisingGate ldy #20 ldx #0 lda #2 jmp tone *------------------------------- * Lowering Gate DoLowerGate ldy #7 ldx #0 lda #8 jmp tone *------------------------------- * Smack Wall SWPitch = 1000 SWDur = 3 DoSmackWall ldy #SWPitch ldx #>SWPitch lda #SWDur jmp tone ]rts rts *------------------------------- * Impaled DoImpaled jmp DoSmackWall *------------------------------- * Gate Slam DoGateSlam jmp DoSmackWall *------------------------------- * * T O N E * * In: y-x = pitch lo-hi * a = duration * *------------------------------- tone sty :pitch stx :pitch+1 :outloop bit spkr 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 *------------------------------- lst eof ds 1 usr $a9,20,$e00,*-org lst off \ No newline at end of file +* sound +org = $ea00 + lst off +*------------------------------- +* +* S O U N D +* +*------------------------------- + org org + + jmp PLAYBACK + +*------------------------------- +savex ds 1 + +spkr = $c030 + +*------------------------------- + put soundnames + put gameeq + put eq + +*------------------------------- +* +* L O O K U P +* +* Sound routine lookup table +* +*------------------------------- +lookup + +:0 dw DoPlateDown +:1 dw DoPlateUp +:2 dw DoGateDown +:3 dw DoSpecialKey1 +:4 dw DoSpecialKey2 +:5 dw DoSplat +:6 dw DoMirrorCrack +:7 dw DoLooseCrash +:8 dw DoGotKey +:9 dw DoFootstep +:10 dw DoRaisingExit +:11 dw DoRaisingGate +:12 dw DoLowerGate +:13 dw DoSmackWall +:14 dw DoImpaled +:15 dw DoGateSlam +:16 dw DoFlashMsg +:17 dw DoSwordClash1 +:18 dw DoSwordClash2 +:19 dw DoJawsClash + +endlook + +maxaddr = endlook-lookup + +*------------------------------- +* +* Z E R O S O U N D +* +* Zero sound table +* +*------------------------------- +ZEROSOUND + lda #0 ;# sounds in table + sta soundtable + rts + +*------------------------------- +* +* A D D S O U N D +* +* Add sound to sound table +* (preserve registers) +* +* In: A = sound # +* +*------------------------------- +ADDSOUND + stx savex + + ldx soundtable + cpx #maxsfx + bcs :rts ;sound table full + + inx + sta soundtable,x + stx soundtable ;# sounds in table + +:rts ldx savex + rts + +*------------------------------- +* +* P L A Y B A C K +* +* Playback all sounds listed in sound table +* +*------------------------------- +PLAYBACK + lda soundon + beq :rts ;sound switched off? + + ldx soundtable + beq :rts ;sound table empty? + +:loop lda soundtable,x + + stx savex + + jsr makesound ;make sound #A +;(may destroy registers) + ldx savex + + dex + bne :loop + +:rts rts + +*------------------------------- +* +* M A K E S O U N D +* +* In: A = sound # (0-127) +* +*------------------------------- +makesound + asl + cmp #maxaddr + bcs :rts ;don't exceed lookup table + + tax + lda lookup,x + sta :sm+1 + lda lookup+1,x + sta :sm+2 + +:sm jmp $ffff ;self-modifying code + +:rts rts + +*------------------------------- +* +* S O U N D R O U T I N E S +* +*------------------------------- +* Kid steps on pressplate + +DoPlateDown + ldy #70 + ldx #0 + lda #4 + jmp tone + +*------------------------------- +* Pressplate pops back up + +DoPlateUp + ldy #90 + ldx #0 + lda #4 + jmp tone + +*------------------------------- +* Gate hits stone floor with an ominous CLANG + +DoGateDown + ldy #70 + ldx #0 + lda #4 + jmp tone + +*------------------------------- +* Jaws clash + +DoJawsClash + ldy #10 + ldx #0 + lda #50 + jmp tone + +*------------------------------- +* Acknowledge special keypress + +SK1Pitch = 15 +SK1Dur = 50 + +SK2Pitch = 40 +SK2Dur = 50 + +DoSpecialKey1 +DoSwordClash1 +DoSwordClash2 + ldy #SK1Pitch + ldx #>SK1Pitch + lda #SK1Dur + jmp tone + +DoSpecialKey2 + ldy #SK2Pitch + ldx #>SK2Pitch + lda #SK2Dur + jmp tone + +*------------------------------- +* Splat + +SplatPitch = 1000 +SplatDur = 3 + +DoSplat + ldy #SplatPitch + ldx #>SplatPitch + lda #SplatDur + jmp tone + +*------------------------------- +* Mirror Crack + +DoMirrorCrack + jmp DoSplat + rts + +*------------------------------- +* Loose Floor Crash + +DoLooseCrash + jmp DoSplat + +*------------------------------- +* Flash message + +]HiPitch = 100 +]HiDur = 25 +]LoPitch = 500 +]LoDur = 15 + +DoGotKey +DoFlashMsg + lda #2 +:loop pha + + ldy #]LoPitch + ldx #>]LoPitch + lda #]LoDur + jsr tone + + ldy #]HiPitch + ldx #>]HiPitch + lda #]HiDur + jsr tone + + pla + sec + sbc #1 + bne :loop + + rts + +*------------------------------- +* Footstep + +DoFootstep + ldy #35 + ldx #0 + lda #3 + jmp tone + +*------------------------------- +* Raising Exit + +DoRaisingExit + ldy #40 + ldx #0 + lda #6 + jmp tone + +*------------------------------- +* Raising Gate + +DoRaisingGate + ldy #20 + ldx #0 + lda #2 + jmp tone + +*------------------------------- +* Lowering Gate + +DoLowerGate + ldy #7 + ldx #0 + lda #8 + jmp tone + +*------------------------------- +* Smack Wall + +SWPitch = 1000 +SWDur = 3 + +DoSmackWall + ldy #SWPitch + ldx #>SWPitch + lda #SWDur + jmp tone + +]rts rts + +*------------------------------- +* Impaled + +DoImpaled + jmp DoSmackWall + +*------------------------------- +* Gate Slam + +DoGateSlam + jmp DoSmackWall + + +*------------------------------- +* +* T O N E +* +* In: y-x = pitch lo-hi +* a = duration +* +*------------------------------- +tone + sty :pitch + stx :pitch+1 + +:outloop bit spkr + + 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 + +*------------------------------- + lst +eof ds 1 + usr $a9,20,$e00,*-org + lst off diff --git a/01 POP Source/Source/SOUNDNAMES.S b/01 POP Source/Source/SOUNDNAMES.S index 355b5db..ce2b846 100755 --- a/01 POP Source/Source/SOUNDNAMES.S +++ b/01 POP Source/Source/SOUNDNAMES.S @@ -1 +1,56 @@ - tr on lst off * sound names PlateDown = 0 PlateUp = 1 GateDown = 2 SpecialKey1 = 3 SpecialKey2 = 4 Splat = 5 MirrorCrack = 6 LooseCrash = 7 GotKey = 8 Footstep = 9 RaisingExit = 10 RaisingGate = 11 LoweringGate = 12 SmackWall = 13 Impaled = 14 GateSlam = 15 FlashMsg = 16 SwordClash1 = 17 SwordClash2 = 18 JawsClash = 19 *------------------------------- * game music s_Accid = 1 s_Heroic = 2 s_Danger = 3 s_Sword = 4 s_Rejoin = 5 s_Shadow = 6 s_Vict = 7 s_Stairs = 8 s_Upstairs = 9 s_Jaffar = 10 s_Potion = 11 s_ShortPot = 12 s_Timer = 13 s_Tragic = 14 s_Embrace = 15 s_Heartbeat = 16 * title music s_Princess = 7 s_Squeek = 8 s_Vizier = 9 s_Buildup = 10 s_Magic = 11 s_StTimer = 12 lst off \ No newline at end of file + tr on + lst off + +* sound names + +PlateDown = 0 +PlateUp = 1 +GateDown = 2 +SpecialKey1 = 3 +SpecialKey2 = 4 +Splat = 5 +MirrorCrack = 6 +LooseCrash = 7 +GotKey = 8 +Footstep = 9 +RaisingExit = 10 +RaisingGate = 11 +LoweringGate = 12 +SmackWall = 13 +Impaled = 14 +GateSlam = 15 +FlashMsg = 16 +SwordClash1 = 17 +SwordClash2 = 18 +JawsClash = 19 + +*------------------------------- +* game music + +s_Accid = 1 +s_Heroic = 2 +s_Danger = 3 +s_Sword = 4 +s_Rejoin = 5 +s_Shadow = 6 +s_Vict = 7 +s_Stairs = 8 +s_Upstairs = 9 +s_Jaffar = 10 +s_Potion = 11 +s_ShortPot = 12 +s_Timer = 13 +s_Tragic = 14 +s_Embrace = 15 +s_Heartbeat = 16 + +* title music + +s_Princess = 7 +s_Squeek = 8 +s_Vizier = 9 +s_Buildup = 10 +s_Magic = 11 +s_StTimer = 12 + + lst off diff --git a/01 POP Source/Source/SPECIALK.S b/01 POP Source/Source/SPECIALK.S index bcf1728..1075ecc 100755 --- a/01 POP Source/Source/SPECIALK.S +++ b/01 POP Source/Source/SPECIALK.S @@ -1 +1,1352 @@ -* specialk EditorDisk = 0 FinalDisk = 0 ;removes all cheat keys DebugKeys = 0 tr on lst off org = $d900 *------------------------------- * * PRINCE OF PERSIA * Copyright 1989 Jordan Mechner * *------------------------------- org org jmp KEYS jmp CLRJSTK jmp ZEROSOUND jmp ADDSOUND jmp FACEJSTK jmp SAVESELECT jmp LOADSELECT jmp SAVEDESEL jmp LOADDESEL jmp INITINPUT jmp DEMOKEYS jmp LISTTORCHES jmp BURN jmp GETMINLEFT jmp KEEPTIME jmp SHORTENTIME jmp CUESONG jmp DoSaveGame jmp LoadLevelX jmp decstr jmp DLOOP jmp STROBE *------------------------------- lst put eq lst put gameeq lst put soundnames lst put movedata lst off *------------------------------- initAMtimer = 10 ;antimatter cheat key timer dum locals ]temp ds 1 ]count ds 2 dend POPside1 = $a9 POPside2 = $ad FirstSideB = 3 *------------------------------- min = 725 ;# frames per "minute" ;(actual frame rate approx. 11 fps) sec = min/60 t = 60 ;game time limit *------------------------------- * Key equates CTRL = $60 ESC = $9b DELETE = $7f SHIFT = $20 * Player control keys kleft = "j" kdown = "k" kright = "l" kupleft = "u" kup = "i" kupright = "o" * Special keys (legit) kfreeze = ESC krestart = "r"-CTRL kabort = "a"-CTRL ksound = "s"-CTRL kmusic = "n"-CTRL ksetkbd = "k"-CTRL ksetjstk = "j"-CTRL ksavegame = "g"-CTRL kversion = "v"-CTRL kreturn = "m"-CTRL ;editor disk only kshowtime = " " kflipx = "x"-CTRL kflipy = "y"-CTRL * Special keys (development) knextlevel = ")" kclean = "m"-CTRL kscreendump = "@" kreload = "c"-CTRL kreboot = "z"-CTRL kforceredraw = "f"-CTRL kblackout = "B" kspeedup = "]" kslowdown = "[" kantimatter = "q"-CTRL kupone = "e"-CTRL kautoman = "A" kincstr = "S" kdecstr = "D" kincmax = "F" kzapgard = "Z" kplayback = "p"-CTRL kskip5 = "+" ktimeback = "<" ktimefwd = ">" ktimeup = "M" kerasegame = "*" *------------------------------- * * K E Y S * * Detect & respond to keypresses * *------------------------------- KEYS lda SINGSTEP beq KEYS1 freeze lda $C000 bpl freeze cmp #kfreeze beq :fradv ldx #0 stx SINGSTEP lda #0 ;ignore the keypress that breaks ESC beq KEYS2 :fradv lda #1 sta SINGSTEP sta $C010 sta keypress ]rts rts KEYS1 lda $C000 ;ASCII value of last keypress ;(Hibit is keyboard strobe) KEYS2 sta keypress lda $C010 ;Hibit is any-key-down flag ;(Clears keyboard strobe) sta keydown jsr KREAD ;Keyboard control lda keypress bpl ]rts do DebugKeys ldx develment beq :nogo ;GO codes work only in cheat mode cmp #"0" bcc :nogo cmp #"9"+1 bcs :nogo * We have a keypress 0-9 * Check if it follows a "GO" key sequence lda #C_go0 ldx #>C_go0 jsr checkcode bne :nogo0 lda #0 ;1st digit :golevel clc adc keypress sec sbc #"0" ;2-key value cmp #4 ;only levels 4-12 accessible bcc ]rts cmp #13 bcs ]rts sta NextLevel jsr shortentime ]rts rts :nogo0 lda #C_go1 ldx #>C_go1 jsr checkcode bne :nogo lda #10 bne :golevel fin * Normal key handling :nogo lda keypress jsr addkey ;Add key to kbd buffer do FinalDisk else * Set development flag? lda #C_devel ldx #>C_devel jsr checkcode bne :1 lda #1 sta develment jmp gtone :1 fin * Skip to next level? lda #C_skip ldx #>C_skip jsr checkcode bne :2 lda #3 ;up to level 4 ldx develment beq :limit lda #11 ;or level 12 in cheat mode :limit cmp level bcc :2 inc NextLevel jsr shortentime :2 fin * Special keys jsr LegitKeys jsr DevelKeys jsr TempDevel ]rts rts *------------------------------- * * L E G I T K E Y S * *------------------------------- LegitKeys lda keypress cmp #kfreeze bne :1 jmp freeze :1 cmp #krestart bne :1a jmp goattract ;in topctrl :1a cmp #kabort bne :1b jmp restart :1b do EditorDisk cmp #kreturn bne :2 jmp gobuild fin * Keyboard/joystick :2 cmp #ksetkbd bne :30 lda #0 sta joyon ]sk1 jmp gtone :30 cmp #ksetjstk bne :31 jsr setcenter jmp ]sk1 :31 cmp #kflipx bne :32 lda jhoriz eor #1 sta jhoriz bpl ]sk1 :32 cmp #kflipy bne :3 lda jvert eor #1 sta jvert bpl ]sk1 * Sound on/off :3 cmp #ksound bne :16 ]togsound jsr zerosound lda soundon eor #1 sta soundon bne ]sk1 rts :16 cmp #kmusic bne :26 lda musicon eor #1 sta musicon bne ]sk1 rts :26 cmp #kversion bne :17 jmp dispversion ;display version # * Save/load game :17 cmp #ksavegame bne :18 lda level sta SavLevel jmp DoSaveGame * Show time left :18 cmp #kshowtime bne :19 lda #3 sta timerequest rts :19 ]rts rts *------------------------------- * * D E V E L O P M E N T - O N L Y K E Y S * *------------------------------- DevelKeys lda develment ;development flag beq ]rts jsr checkcodes ;secret codes lda keypress cmp #kclean bne :1 lda #0 sta develment rts :1 ]rts rts *------------------------------- * Temp development keys * (remove for final version) *------------------------------- TempDevel do DebugKeys lda develment ;development flag beq ]rts lda keypress cmp #kforceredraw bne :10 lda #2 sta redrawflg lda #0 sta blackflag rts :10 cmp #kblackout bne :9 lda blackflag eor #$ff sta blackflag ]rts rts :9 cmp #kantimatter bne :17 lda #initAMtimer sta AMtimer rts :17 cmp #kincstr bne :20 inc ChgKidStr inc ChgOppStr rts :20 cmp #kincmax bne :36 jmp boostmeter :36 cmp #knextlevel bne :28 inc NextLevel rts :28 cmp #kskip5 bne :30 lda level clc adc #5 sta NextLevel rts :30 * keys 0-9 lda keypress cmp #"0" bcc :non cmp #"9"+1 bcs :non sec sbc #"0" sta guardprog ]sk1 jmp gtone * non-numeric keys :non cmp #kreload bne :8 jsr preload lda #2 sta redrawflg jsr reload jmp postload * speed up/slow down delay loop :8 cmp #kspeedup bne :13 lda SPEED cmp #5 bcc :12 sec sbc #4 sta SPEED jmp ]sk1 :12 lda #1 ;fastest sta SPEED ]rts rts :13 cmp #kslowdown bne :14 jsr gtone lda SPEED clc adc #4 sta SPEED rts * Screen dump :14 cmp #kscreendump bne :15 lda PAGE jmp screendump :15 cmp #kupone bne :19 lda KidY sec sbc #63 ;BlockHeight sta KidY dec KidBlockY rts :19 cmp #kdecstr bne :21 dec ChgKidStr ]rts rts :21 cmp #kautoman bne :23 lda ManCtrl eor #$ff sta ManCtrl rts * Change levels :23 cmp #kplayback bne :24 lda #1 sta level lda #2 sta NextLevel rts :24 cmp #ktimeback bne :31 lda #-2 :chgtime clc adc FrameCount+1 sta FrameCount+1 rts :31 cmp #ktimefwd bne :32 lda #2 bne :chgtime :32 cmp #kerasegame bne :33 lda #$ff sta SavLevel jmp DoSaveGame :33 cmp #ktimeup bne :34 lda #$ff sta FrameCount+1 rts :34 fin ]rts rts *------------------------------- * Temporarily change BBundID to reload code & data from side 1 postload ]sm lda #$a9 sta BBundID rts preload lda BBundID sta ]sm+1 lda #POPside1 sta BBundID rts *------------------------------- * * A D D K E Y * * In: A = key value * *------------------------------- addkey ldx keybufptr ;index to last key entry inx cpx #keybuflen bcc :ok ldx #0 ;wrap around :ok stx keybufptr sta keybuf,x ]rts rts *------------------------------- * * C H E C K C O D E S * * Only work in devel mode * *------------------------------- checkcodes do FinalDisk rts else lda #C_boost ldx #>C_boost jsr checkcode bne :1 jsr boostmeter lda MaxKidStr sta origstrength rts :1 lda #C_restore ldx #>C_restore jsr checkcode bne :2 jmp rechargemeter :2 lda #C_zap2 ldx #>C_zap2 jsr checkcode bne :3 ;zap guard down to 0 lda #0 sec sbc OppStrength sta ChgOppStr rts :3 lda #C_zap1 ldx #>C_zap1 jsr checkcode bne :4 ;zap guard down to 1 lda #1 sec sbc OppStrength sta ChgOppStr rts :4 lda #C_tina ldx #>C_tina jsr checkcode bmi :5 lda #14 sta NextLevel jsr shortentime rts :5 ]rts rts fin *------------------------------- * * Compare keybuf sequence against code sequence * * In: A-X = code sequence address lo-hi * Return A = 0 if it matches, else ff * *------------------------------- checkcode sta :smod+1 stx :smod+2 ldx keybufptr ;last key entry ldy #0 ;last char of code seq :loop :smod lda $ffff,y ;smod beq ]rts ;0 = code seq delimiter cmp keybuf,x beq :match cmp #"A" ;alpha? bcc :fail cmp #"Z"+1 bcs :fail ora #$20 ;yes--try LC too cmp keybuf,x bne :fail :match iny dex bpl :loop ldx #keybuflen-1 ;wrap around bpl :loop :fail lda #$ff ]rts rts *------------------------------- * * Key sequence codes * * Use all caps; LC will be accepted too * *------------------------------- C_skip rev "SKIP" db 0 do FinalDisk else C_devel rev "POP" db 0 C_go0 rev "GO0" db 0 C_go1 rev "GO1" db 0 C_zap2 rev "ZAP" db 0 C_boost rev "BOOST" db 0 C_restore rev "R" db 0 C_zap1 rev "Z" db 0 C_tina rev "TINA" db 0 fin *------------------------------- * * K R E A D * * Keyboard player control * * (Register a keypress for as long as key is held down) * * Out: kbdX, kbdY * *------------------------------- KREAD lda #0 sta kbdX sta kbdY lda keypress bmi :cont ;fresh press ldx keydown bpl ]rts ;No fresh press & no key down ora #$80 ;stale press, key still down :cont cmp #kleft beq :left cmp #kleft-SHIFT bne :1 :left lda #-1 :setx sta kbdX rts :1 cmp #kright beq :right cmp #kright-SHIFT bne :2 :right lda #1 bne :setx :2 cmp #kup beq :up cmp #kup-SHIFT bne :3 :up lda #-1 :sety sta kbdY rts :3 cmp #kdown beq :down cmp #kdown-SHIFT bne :4 :down lda #1 bne :sety :4 cmp #kupleft beq :ul cmp #kupleft-SHIFT bne :5 :ul lda #-1 sta kbdX bne :sety :5 cmp #kupright beq :ur cmp #kupright-SHIFT bne :6 :ur lda #1 sta kbdX lda #-1 sta kbdY bne :sety :6 ]rts rts *------------------------------- FACEJSTK lda #0 sec sbc JSTKX sta JSTKX ;reverse jstk x ldx clrF lda clrB sta clrF stx clrB ;& switch clrF/clrB ]rts rts *------------------------------- * * Note: Jstk-push flags are saved as if back = R, fwd = L * (i.e., char is facing L) * *------------------------------- SAVESELECT ldx #4 :loop lda clrF,x sta clrSEL,x dex bpl :loop rts *------------------------------- LOADSELECT ldx #4 :loop lda clrSEL,x sta clrF,x dex bpl :loop rts *------------------------------- SAVEDESEL ldx #4 :loop lda clrF,x sta clrDESEL,x dex bpl :loop rts *------------------------------- LOADDESEL ldx #4 :loop lda clrDESEL,x sta clrF,x dex bpl :loop rts *------------------------------- INITINPUT lda #0 ldx #4 :loop sta clrDESEL,x sta clrSEL,x dex bpl :loop ]rts rts *------------------------------- * * C L E A R J O Y S T I C K * * In/out: JSTKX, JSTKY, btn * clrF-B-U-D-btn * * clr = 0: no press * clr = 1: used press * clr = -1: unused press * * Assume char is facing L * *------------------------------- * * Input consists of 5 "buttons": forward, back, up, down, * and the real button. Each button has its own "clr" flag: * clrF,B,U,D & btn. * * When ClrJstk sees a button down: * If clr = 1 or -1... leave it alone * If clr = 0... set clr = -1 * * When ClrJstk sees a button up: * If clr = 0 or -1... leave it alone * If clr = 1... set clr = 0 * * When GenCtrl acts on a button press, it sets clr = 1. * *------------------------------- CLRJSTK lda clrF bmi :1 ;leave it set at -1 ldx JSTKX ;jstk fwd? bmi :yesF ;yes--if clr = 0, set clr = -1 ;no--set clr = 0 lda #0 beq :staF :yesF cmp #0 bne :1 lda #-1 :staF sta clrF *------------------------------- :1 lda clrB bmi :2 ldx JSTKX cpx #1 beq :yesB lda #0 beq :staB :yesB cmp #0 bne :2 lda #-1 :staB sta clrB *------------------------------- :2 lda clrU bmi :3 ldx JSTKY bmi :yesU lda #0 beq :staU :yesU cmp #0 bne :3 lda #-1 :staU sta clrU *------------------------------- :3 lda clrD bmi :4 ldx JSTKY cpx #1 beq :yesD lda #0 beq :staD :yesD cmp #0 bne :4 lda #-1 :staD sta clrD *------------------------------- :4 lda clrbtn bmi :5 ldx btn bmi :yesbtn lda #0 beq :stabtn :yesbtn cmp #0 bne :5 lda #-1 :stabtn sta clrbtn :5 ]rts rts *------------------------------- * * Z E R O S O U N D * * Zero sound table * *------------------------------- ZEROSOUND lda #0 ;# sounds in table sta soundtable rts *------------------------------- * * A D D S O U N D * * Add sound to sound table * (preserve registers) * * In: A = sound # * *------------------------------- ]temp1 ds 1 ADDSOUND stx ]temp1 ldx soundtable cpx #maxsfx bcs :rts ;sound table full inx sta soundtable,x stx soundtable ;# sounds in table :rts ldx ]temp1 rts *------------------------------- * * Demo keys (Call immediately after regular KEYS routine) * * All keys interrupt demo except ESC and CTRL-S * * Out: FF if interrupt, else 00 * *------------------------------- DEMOKEYS lda level bne :cont ;not in demo lda $c061 ora $c062 ;button? bmi :interrupt lda keypress bpl :cont cmp #ESC beq :cont cmp #ksound beq :cont :interrupt lda #$ff rts :cont lda #0 rts *------------------------------- * * Special routine for use by BURN * * Make a list of visible torches--don't disturb trans list * *------------------------------- maxtorches = 8 torchx ds maxtorches+1 torchy ds maxtorches+1 torchstate ds maxtorches+1 torchclip ds maxtorches+1 ]numtorches = locals torchcount ds 1 LISTTORCHES lda #0 sta ]numtorches lda VisScrn jsr calcblue ldy #29 :loop jsr :sub ldx ]numtorches cpx #maxtorches bcs :max dey bpl :loop ldx ]numtorches :max lda #$ff sta torchx,x sta torchcount ;start BURNing with torch #0 ]rts rts :sub lda (BlueType),y and #idmask cmp #torch bne ]rts lda fredbuf+1,y sta BOTCUT ;temp tya pha jsr unindex ;Out: A = tempblockx, X = tempblocky pha txa ldx ]numtorches tay lda BlockBot+1,y sec sbc #3 sta torchy,x lda BOTCUT ;0 or non0 sta torchclip,x pla clc adc #1 cmp #10 bcs ]rts asl asl sta torchx,x pla tay lda (BlueSpec),y sta torchstate,x inc ]numtorches ]rts rts *------------------------------- * * B U R N * * Animate torch flames (for use while music is playing) * * NOTE--this routine bypasses normal graphics system * and draws directly on the displayed page * Leaves trans list, redraw buffers, etc. undisturbed * *------------------------------- BURN lda torchx bmi ]rts ;no torches on this screen ldx torchcount ;last torch burned inx lda torchx,x bpl :ok ;torchx = $ff means "end of torch list" ldx #0 ;start again at beginning of list :ok stx torchcount lda torchx,x sta XCO lda torchy,x sta YCO lda torchclip,x sta BOTCUT lda torchstate,x jsr getflameframe sta torchstate,x tax jsr setupflame lda BOTCUT bne :partial :whole jmp fastlay ;<---DIRECT HIRES CALL ]rts rts * If bottom portion of flame would overlap with someone's * head, clip it (use LAY) :partial jsr initlay lda #0 sta OFFSET lda YCO sec sbc #4 sta BOTCUT jmp lay ;<---DIRECT HIRES CALL *------------------------------- * * Get # of minutes (or seconds) left * * In: FrameCount (0-65535) * Out: MinLeft (BCD byte: $00-99) = # of minutes left * SecLeft = # of seconds left (during final minute) * *------------------------------- GETMINLEFT lda #0 sta ]count sta ]count+1 lda #min sta :sm1+1 lda #>min sta :sm2+1 jsr :sub ;get MinLeft sty MinLeft cpy #2 bcs ]rts * Final minute only: count seconds lda #59*min sta ]count lda #>59*min sta ]count+1 lda #sec sta :sm1+1 lda #>sec sta :sm2+1 jsr :sub ;get SecLeft sty SecLeft rts * Sub returns min/sec left :sub ldy #$61 ;counter :loop lda ]count+1 cmp FrameCount+1 bcc :1 bne ]rts lda ]count cmp FrameCount bcs ]rts :1 lda ]count clc :sm1 adc #min sta ]count lda ]count+1 :sm2 adc #>min sta ]count+1 sed tya sec sbc #1 cld tay bpl :loop ldy #0 ]rts rts *------------------------------- timetable :0 dw t-60*min dw t-55*min dw t-50*min dw t-45*min dw t-40*min dw t-35*min dw t-30*min dw t-25*min dw t-20*min dw t-15*min :20 dw t-10*min dw t-5*min dw t-4*min dw t-3*min dw t-2*min dw t-1*min+1 dw t*min+5 ;5 frames after t=0: game over dw 65535 nummsg = *-timetable *------------------------------- * * Keep track of time remaining * *------------------------------- ]rts rts KEEPTIME ; lda autopilot ; bne ]rts lda level beq ]rts ;not in demo or during playback lda KidLife bpl ]rts ;clock stops when kid is dead * Inc frame counter inc FrameCount bne :1 inc FrameCount+1 :1 bne :2 lda #$ff sta FrameCount sta FrameCount+1 ;don't wrap around * time for next message yet? :2 ldy NextTimeMsg ;0-2-4 for 1st, 2nd, 3rd msgs cpy #nummsg bcs ]rts ;no more msgs lda FrameCount+1 cmp timetable+1,y bcc ]rts ;not yet lda FrameCount cmp timetable,y bcc ]rts * Yes--is this a convenient time to show msg? lda msgtimer bne ]rts ;wait till other msgs are gone * Yes--show msg (& inc NextTimeMsg) inc NextTimeMsg inc NextTimeMsg lda #2 sta timerequest ]rts rts *------------------------------- * * Shorten remaining time to 15 minutes * (e.g., 1st time player cheats by skipping a level) * *------------------------------- SHORTENTIME ldy NextTimeMsg cpy #20 bcs ]rts ;time is already short enough ldy #18 sty NextTimeMsg lda timetable,y sta FrameCount lda timetable+1,y sta FrameCount+1 ]rts rts *------------------------------- * * Cue song * * In: A = song # * X = # of cycles within which song must be played * *------------------------------- CUESONG sta SongCue stx SongCount rts *------------------------------- * * Strobe keyboard * *------------------------------- DLOOP STROBE jsr keys ;Detect & respond to keypresses jsr controller ]rts rts *------------------------------- lst eof ds 1 usr $a9,19,$b00,*-org lst off \ No newline at end of file +* specialk +EditorDisk = 0 +FinalDisk = 0 ;removes all cheat keys +DebugKeys = 0 + tr on + lst off +org = $d900 +*------------------------------- +* +* PRINCE OF PERSIA +* Copyright 1989 Jordan Mechner +* +*------------------------------- + org org + + jmp KEYS + jmp CLRJSTK + jmp ZEROSOUND + jmp ADDSOUND + jmp FACEJSTK + + jmp SAVESELECT + jmp LOADSELECT + jmp SAVEDESEL + jmp LOADDESEL + jmp INITINPUT + + jmp DEMOKEYS + jmp LISTTORCHES + jmp BURN + jmp GETMINLEFT + jmp KEEPTIME + + jmp SHORTENTIME + jmp CUESONG + jmp DoSaveGame + jmp LoadLevelX + jmp decstr + + jmp DLOOP + jmp STROBE + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put soundnames + lst + put movedata + lst off + +*------------------------------- +initAMtimer = 10 ;antimatter cheat key timer + + dum locals +]temp ds 1 +]count ds 2 + dend + +POPside1 = $a9 +POPside2 = $ad + +FirstSideB = 3 + +*------------------------------- +min = 725 ;# frames per "minute" + ;(actual frame rate approx. 11 fps) +sec = min/60 +t = 60 ;game time limit + +*------------------------------- +* Key equates + +CTRL = $60 +ESC = $9b +DELETE = $7f +SHIFT = $20 + +* Player control keys + +kleft = "j" +kdown = "k" +kright = "l" +kupleft = "u" +kup = "i" +kupright = "o" + +* Special keys (legit) + +kfreeze = ESC +krestart = "r"-CTRL +kabort = "a"-CTRL +ksound = "s"-CTRL +kmusic = "n"-CTRL +ksetkbd = "k"-CTRL +ksetjstk = "j"-CTRL +ksavegame = "g"-CTRL +kversion = "v"-CTRL +kreturn = "m"-CTRL ;editor disk only +kshowtime = " " +kflipx = "x"-CTRL +kflipy = "y"-CTRL + +* Special keys (development) + +knextlevel = ")" +kclean = "m"-CTRL +kscreendump = "@" +kreload = "c"-CTRL +kreboot = "z"-CTRL +kforceredraw = "f"-CTRL +kblackout = "B" +kspeedup = "]" +kslowdown = "[" +kantimatter = "q"-CTRL +kupone = "e"-CTRL +kautoman = "A" +kincstr = "S" +kdecstr = "D" +kincmax = "F" +kzapgard = "Z" +kplayback = "p"-CTRL +kskip5 = "+" +ktimeback = "<" +ktimefwd = ">" +ktimeup = "M" +kerasegame = "*" + +*------------------------------- +* +* K E Y S +* +* Detect & respond to keypresses +* +*------------------------------- +KEYS + lda SINGSTEP + beq KEYS1 + +freeze lda $C000 + bpl freeze + + cmp #kfreeze + beq :fradv + + ldx #0 + stx SINGSTEP + + lda #0 ;ignore the keypress that breaks ESC + beq KEYS2 + +:fradv lda #1 + sta SINGSTEP + sta $C010 + sta keypress +]rts rts + +KEYS1 lda $C000 ;ASCII value of last keypress + ;(Hibit is keyboard strobe) +KEYS2 sta keypress + + lda $C010 ;Hibit is any-key-down flag + ;(Clears keyboard strobe) + sta keydown + + jsr KREAD ;Keyboard control + + lda keypress + bpl ]rts + + do DebugKeys + + ldx develment + beq :nogo ;GO codes work only in cheat mode + cmp #"0" + bcc :nogo + cmp #"9"+1 + bcs :nogo + +* We have a keypress 0-9 +* Check if it follows a "GO" key sequence + + lda #C_go0 + ldx #>C_go0 + jsr checkcode + bne :nogo0 + lda #0 ;1st digit +:golevel clc + adc keypress + sec + sbc #"0" ;2-key value + + cmp #4 ;only levels 4-12 accessible + bcc ]rts + cmp #13 + bcs ]rts + sta NextLevel + jsr shortentime +]rts rts + +:nogo0 lda #C_go1 + ldx #>C_go1 + jsr checkcode + bne :nogo + lda #10 + bne :golevel + + fin + +* Normal key handling + +:nogo lda keypress + jsr addkey ;Add key to kbd buffer + + do FinalDisk + else + +* Set development flag? + + lda #C_devel + ldx #>C_devel + jsr checkcode + bne :1 + lda #1 + sta develment + jmp gtone +:1 + fin + +* Skip to next level? + + lda #C_skip + ldx #>C_skip + jsr checkcode + bne :2 + lda #3 ;up to level 4 + ldx develment + beq :limit + lda #11 ;or level 12 in cheat mode +:limit cmp level + bcc :2 + inc NextLevel + + jsr shortentime +:2 + fin + +* Special keys + + jsr LegitKeys + + jsr DevelKeys + + jsr TempDevel + +]rts rts + +*------------------------------- +* +* L E G I T K E Y S +* +*------------------------------- +LegitKeys + lda keypress + cmp #kfreeze + bne :1 + jmp freeze + +:1 cmp #krestart + bne :1a + jmp goattract ;in topctrl + +:1a cmp #kabort + bne :1b + jmp restart + +:1b do EditorDisk + cmp #kreturn + bne :2 + jmp gobuild + fin + +* Keyboard/joystick + +:2 cmp #ksetkbd + bne :30 + lda #0 + sta joyon +]sk1 jmp gtone + +:30 cmp #ksetjstk + bne :31 + jsr setcenter + jmp ]sk1 + +:31 cmp #kflipx + bne :32 + lda jhoriz + eor #1 + sta jhoriz + bpl ]sk1 + +:32 cmp #kflipy + bne :3 + lda jvert + eor #1 + sta jvert + bpl ]sk1 + +* Sound on/off + +:3 cmp #ksound + bne :16 +]togsound + jsr zerosound + lda soundon + eor #1 + sta soundon + bne ]sk1 + rts + +:16 cmp #kmusic + bne :26 + lda musicon + eor #1 + sta musicon + bne ]sk1 + rts + +:26 cmp #kversion + bne :17 + jmp dispversion ;display version # + +* Save/load game + +:17 cmp #ksavegame + bne :18 + lda level + sta SavLevel + jmp DoSaveGame + +* Show time left + +:18 cmp #kshowtime + bne :19 + lda #3 + sta timerequest + rts + +:19 +]rts rts + +*------------------------------- +* +* D E V E L O P M E N T - O N L Y K E Y S +* +*------------------------------- +DevelKeys + lda develment ;development flag + beq ]rts + + jsr checkcodes ;secret codes + + lda keypress + cmp #kclean + bne :1 + lda #0 + sta develment + rts +:1 +]rts rts + +*------------------------------- +* Temp development keys +* (remove for final version) +*------------------------------- +TempDevel + do DebugKeys + + lda develment ;development flag + beq ]rts + + lda keypress + cmp #kforceredraw + bne :10 + lda #2 + sta redrawflg + lda #0 + sta blackflag + rts + +:10 cmp #kblackout + bne :9 + lda blackflag + eor #$ff + sta blackflag +]rts rts + +:9 cmp #kantimatter + bne :17 + lda #initAMtimer + sta AMtimer + rts + +:17 cmp #kincstr + bne :20 + inc ChgKidStr + inc ChgOppStr + rts + +:20 cmp #kincmax + bne :36 + jmp boostmeter + +:36 cmp #knextlevel + bne :28 + inc NextLevel + rts + +:28 cmp #kskip5 + bne :30 + lda level + clc + adc #5 + sta NextLevel + rts +:30 + +* keys 0-9 + + lda keypress + cmp #"0" + bcc :non + cmp #"9"+1 + bcs :non + sec + sbc #"0" + sta guardprog +]sk1 jmp gtone + +* non-numeric keys + +:non cmp #kreload + bne :8 + jsr preload + lda #2 + sta redrawflg + jsr reload + jmp postload + +* speed up/slow down delay loop + +:8 cmp #kspeedup + bne :13 + lda SPEED + cmp #5 + bcc :12 + sec + sbc #4 + sta SPEED + jmp ]sk1 +:12 lda #1 ;fastest + sta SPEED +]rts rts + +:13 cmp #kslowdown + bne :14 + jsr gtone + lda SPEED + clc + adc #4 + sta SPEED + rts + +* Screen dump + +:14 cmp #kscreendump + bne :15 + lda PAGE + jmp screendump + +:15 cmp #kupone + bne :19 + lda KidY + sec + sbc #63 ;BlockHeight + sta KidY + dec KidBlockY + rts + +:19 cmp #kdecstr + bne :21 + dec ChgKidStr +]rts rts + +:21 cmp #kautoman + bne :23 + lda ManCtrl + eor #$ff + sta ManCtrl + rts + +* Change levels + +:23 + cmp #kplayback + bne :24 + lda #1 + sta level + lda #2 + sta NextLevel + rts + +:24 cmp #ktimeback + bne :31 + lda #-2 +:chgtime clc + adc FrameCount+1 + sta FrameCount+1 + rts + +:31 cmp #ktimefwd + bne :32 + lda #2 + bne :chgtime + +:32 cmp #kerasegame + bne :33 + lda #$ff + sta SavLevel + jmp DoSaveGame + +:33 cmp #ktimeup + bne :34 + lda #$ff + sta FrameCount+1 + rts + +:34 + fin +]rts rts + +*------------------------------- +* Temporarily change BBundID to reload code & data from side 1 + +postload +]sm lda #$a9 + sta BBundID + rts + +preload + lda BBundID + sta ]sm+1 + lda #POPside1 + sta BBundID + rts + +*------------------------------- +* +* A D D K E Y +* +* In: A = key value +* +*------------------------------- +addkey + ldx keybufptr ;index to last key entry + inx + cpx #keybuflen + bcc :ok + ldx #0 ;wrap around +:ok stx keybufptr + + sta keybuf,x +]rts rts + +*------------------------------- +* +* C H E C K C O D E S +* +* Only work in devel mode +* +*------------------------------- +checkcodes + do FinalDisk + rts + else + + lda #C_boost + ldx #>C_boost + jsr checkcode + bne :1 + jsr boostmeter + lda MaxKidStr + sta origstrength + rts + +:1 lda #C_restore + ldx #>C_restore + jsr checkcode + bne :2 + jmp rechargemeter + +:2 lda #C_zap2 + ldx #>C_zap2 + jsr checkcode + bne :3 +;zap guard down to 0 + lda #0 + sec + sbc OppStrength + sta ChgOppStr + rts + +:3 lda #C_zap1 + ldx #>C_zap1 + jsr checkcode + bne :4 + ;zap guard down to 1 + lda #1 + sec + sbc OppStrength + sta ChgOppStr + rts + +:4 lda #C_tina + ldx #>C_tina + jsr checkcode + bmi :5 + lda #14 + sta NextLevel + jsr shortentime + rts +:5 +]rts rts + fin + +*------------------------------- +* +* Compare keybuf sequence against code sequence +* +* In: A-X = code sequence address lo-hi +* Return A = 0 if it matches, else ff +* +*------------------------------- +checkcode + sta :smod+1 + stx :smod+2 + + ldx keybufptr ;last key entry + ldy #0 ;last char of code seq +:loop +:smod lda $ffff,y ;smod + beq ]rts ;0 = code seq delimiter + cmp keybuf,x + beq :match + cmp #"A" ;alpha? + bcc :fail + cmp #"Z"+1 + bcs :fail + ora #$20 ;yes--try LC too + cmp keybuf,x + bne :fail + +:match iny + dex + bpl :loop + ldx #keybuflen-1 ;wrap around + bpl :loop + +:fail lda #$ff +]rts rts + +*------------------------------- +* +* Key sequence codes +* +* Use all caps; LC will be accepted too +* +*------------------------------- +C_skip rev "SKIP" + db 0 + + do FinalDisk + else + +C_devel rev "POP" + db 0 +C_go0 rev "GO0" + db 0 +C_go1 rev "GO1" + db 0 +C_zap2 rev "ZAP" + db 0 +C_boost rev "BOOST" + db 0 +C_restore rev "R" + db 0 +C_zap1 rev "Z" + db 0 +C_tina rev "TINA" + db 0 + + fin + +*------------------------------- +* +* K R E A D +* +* Keyboard player control +* +* (Register a keypress for as long as key is held down) +* +* Out: kbdX, kbdY +* +*------------------------------- +KREAD + lda #0 + sta kbdX + sta kbdY + + lda keypress + bmi :cont ;fresh press + + ldx keydown + bpl ]rts ;No fresh press & no key down + + ora #$80 ;stale press, key still down +:cont + cmp #kleft + beq :left + cmp #kleft-SHIFT + bne :1 + +:left lda #-1 +:setx sta kbdX + rts + +:1 cmp #kright + beq :right + cmp #kright-SHIFT + bne :2 + +:right lda #1 + bne :setx + +:2 cmp #kup + beq :up + cmp #kup-SHIFT + bne :3 + +:up lda #-1 +:sety sta kbdY + rts + +:3 cmp #kdown + beq :down + cmp #kdown-SHIFT + bne :4 + +:down lda #1 + bne :sety + +:4 cmp #kupleft + beq :ul + cmp #kupleft-SHIFT + bne :5 + +:ul lda #-1 + sta kbdX + bne :sety + +:5 cmp #kupright + beq :ur + cmp #kupright-SHIFT + bne :6 + +:ur lda #1 + sta kbdX + lda #-1 + sta kbdY + bne :sety +:6 + +]rts rts +*------------------------------- +FACEJSTK + lda #0 + sec + sbc JSTKX + sta JSTKX ;reverse jstk x + + ldx clrF + lda clrB + sta clrF + stx clrB ;& switch clrF/clrB + +]rts rts + +*------------------------------- +* +* Note: Jstk-push flags are saved as if back = R, fwd = L +* (i.e., char is facing L) +* +*------------------------------- +SAVESELECT + ldx #4 +:loop lda clrF,x + sta clrSEL,x + dex + bpl :loop + rts + +*------------------------------- +LOADSELECT + ldx #4 +:loop lda clrSEL,x + sta clrF,x + dex + bpl :loop + rts + +*------------------------------- +SAVEDESEL + ldx #4 +:loop lda clrF,x + sta clrDESEL,x + dex + bpl :loop + rts + +*------------------------------- +LOADDESEL + ldx #4 +:loop lda clrDESEL,x + sta clrF,x + dex + bpl :loop + rts + +*------------------------------- +INITINPUT + lda #0 + + ldx #4 +:loop sta clrDESEL,x + sta clrSEL,x + dex + bpl :loop +]rts rts + +*------------------------------- +* +* C L E A R J O Y S T I C K +* +* In/out: JSTKX, JSTKY, btn +* clrF-B-U-D-btn +* +* clr = 0: no press +* clr = 1: used press +* clr = -1: unused press +* +* Assume char is facing L +* +*------------------------------- +* +* Input consists of 5 "buttons": forward, back, up, down, +* and the real button. Each button has its own "clr" flag: +* clrF,B,U,D & btn. +* +* When ClrJstk sees a button down: +* If clr = 1 or -1... leave it alone +* If clr = 0... set clr = -1 +* +* When ClrJstk sees a button up: +* If clr = 0 or -1... leave it alone +* If clr = 1... set clr = 0 +* +* When GenCtrl acts on a button press, it sets clr = 1. +* +*------------------------------- +CLRJSTK + lda clrF + bmi :1 ;leave it set at -1 + + ldx JSTKX ;jstk fwd? + bmi :yesF ;yes--if clr = 0, set clr = -1 +;no--set clr = 0 + lda #0 + beq :staF + +:yesF cmp #0 + bne :1 + + lda #-1 +:staF sta clrF + +*------------------------------- +:1 lda clrB + bmi :2 + + ldx JSTKX + cpx #1 + beq :yesB + + lda #0 + beq :staB + +:yesB cmp #0 + bne :2 + + lda #-1 +:staB sta clrB + +*------------------------------- +:2 lda clrU + bmi :3 + + ldx JSTKY + bmi :yesU + + lda #0 + beq :staU + +:yesU cmp #0 + bne :3 + + lda #-1 +:staU sta clrU + +*------------------------------- +:3 lda clrD + bmi :4 + + ldx JSTKY + cpx #1 + beq :yesD + + lda #0 + beq :staD + +:yesD cmp #0 + bne :4 + + lda #-1 +:staD sta clrD + +*------------------------------- +:4 lda clrbtn + bmi :5 + + ldx btn + bmi :yesbtn + + lda #0 + beq :stabtn + +:yesbtn cmp #0 + bne :5 + + lda #-1 +:stabtn sta clrbtn + +:5 +]rts rts + +*------------------------------- +* +* Z E R O S O U N D +* +* Zero sound table +* +*------------------------------- +ZEROSOUND + lda #0 ;# sounds in table + sta soundtable + rts + +*------------------------------- +* +* A D D S O U N D +* +* Add sound to sound table +* (preserve registers) +* +* In: A = sound # +* +*------------------------------- +]temp1 ds 1 + +ADDSOUND + stx ]temp1 + + ldx soundtable + cpx #maxsfx + bcs :rts ;sound table full + + inx + sta soundtable,x + stx soundtable ;# sounds in table + +:rts ldx ]temp1 + rts + +*------------------------------- +* +* Demo keys (Call immediately after regular KEYS routine) +* +* All keys interrupt demo except ESC and CTRL-S +* +* Out: FF if interrupt, else 00 +* +*------------------------------- +DEMOKEYS + lda level + bne :cont ;not in demo + + lda $c061 + ora $c062 ;button? + bmi :interrupt + lda keypress + bpl :cont + cmp #ESC + beq :cont + cmp #ksound + beq :cont +:interrupt + lda #$ff + rts +:cont lda #0 + rts + +*------------------------------- +* +* Special routine for use by BURN +* +* Make a list of visible torches--don't disturb trans list +* +*------------------------------- +maxtorches = 8 + +torchx ds maxtorches+1 +torchy ds maxtorches+1 +torchstate ds maxtorches+1 +torchclip ds maxtorches+1 + +]numtorches = locals + +torchcount ds 1 + +LISTTORCHES + lda #0 + sta ]numtorches + + lda VisScrn + jsr calcblue + + ldy #29 + +:loop jsr :sub + + ldx ]numtorches + cpx #maxtorches + bcs :max + + dey + bpl :loop + + ldx ]numtorches +:max lda #$ff + sta torchx,x + sta torchcount ;start BURNing with torch #0 +]rts rts + +:sub lda (BlueType),y + and #idmask + cmp #torch + bne ]rts + lda fredbuf+1,y + sta BOTCUT ;temp + + tya + pha + jsr unindex +;Out: A = tempblockx, X = tempblocky + pha + txa + ldx ]numtorches + tay + lda BlockBot+1,y + sec + sbc #3 + sta torchy,x + lda BOTCUT ;0 or non0 + sta torchclip,x + pla + clc + adc #1 + cmp #10 + bcs ]rts + asl + asl + sta torchx,x + + pla + tay + lda (BlueSpec),y + sta torchstate,x + + inc ]numtorches +]rts rts + +*------------------------------- +* +* B U R N +* +* Animate torch flames (for use while music is playing) +* +* NOTE--this routine bypasses normal graphics system +* and draws directly on the displayed page +* Leaves trans list, redraw buffers, etc. undisturbed +* +*------------------------------- +BURN + lda torchx + bmi ]rts ;no torches on this screen + + ldx torchcount ;last torch burned + inx + lda torchx,x + bpl :ok ;torchx = $ff means "end of torch list" + ldx #0 ;start again at beginning of list +:ok stx torchcount + lda torchx,x + sta XCO + lda torchy,x + sta YCO + lda torchclip,x + sta BOTCUT + lda torchstate,x + jsr getflameframe + sta torchstate,x + tax + jsr setupflame + lda BOTCUT + bne :partial +:whole jmp fastlay ;<---DIRECT HIRES CALL +]rts rts + +* If bottom portion of flame would overlap with someone's +* head, clip it (use LAY) + +:partial + jsr initlay + lda #0 + sta OFFSET + lda YCO + sec + sbc #4 + sta BOTCUT + jmp lay ;<---DIRECT HIRES CALL + +*------------------------------- +* +* Get # of minutes (or seconds) left +* +* In: FrameCount (0-65535) +* Out: MinLeft (BCD byte: $00-99) = # of minutes left +* SecLeft = # of seconds left (during final minute) +* +*------------------------------- +GETMINLEFT + lda #0 + sta ]count + sta ]count+1 + + lda #min + sta :sm1+1 + lda #>min + sta :sm2+1 + jsr :sub ;get MinLeft + sty MinLeft + cpy #2 + bcs ]rts + +* Final minute only: count seconds + + lda #59*min + sta ]count + lda #>59*min + sta ]count+1 + + lda #sec + sta :sm1+1 + lda #>sec + sta :sm2+1 + jsr :sub ;get SecLeft + sty SecLeft + rts + +* Sub returns min/sec left + +:sub ldy #$61 ;counter + +:loop lda ]count+1 + cmp FrameCount+1 + bcc :1 + bne ]rts + lda ]count + cmp FrameCount + bcs ]rts +:1 + lda ]count + clc +:sm1 adc #min + sta ]count + lda ]count+1 +:sm2 adc #>min + sta ]count+1 + + sed + tya + sec + sbc #1 + cld + tay + bpl :loop + ldy #0 +]rts rts + +*------------------------------- +timetable +:0 dw t-60*min + dw t-55*min + dw t-50*min + dw t-45*min + dw t-40*min + dw t-35*min + dw t-30*min + dw t-25*min + dw t-20*min + dw t-15*min +:20 dw t-10*min + dw t-5*min + dw t-4*min + dw t-3*min + dw t-2*min + dw t-1*min+1 + dw t*min+5 ;5 frames after t=0: game over + dw 65535 + +nummsg = *-timetable + +*------------------------------- +* +* Keep track of time remaining +* +*------------------------------- +]rts rts +KEEPTIME +; lda autopilot +; bne ]rts + lda level + beq ]rts ;not in demo or during playback + + lda KidLife + bpl ]rts ;clock stops when kid is dead + +* Inc frame counter + + inc FrameCount + bne :1 + inc FrameCount+1 +:1 bne :2 + lda #$ff + sta FrameCount + sta FrameCount+1 ;don't wrap around + +* time for next message yet? + +:2 ldy NextTimeMsg ;0-2-4 for 1st, 2nd, 3rd msgs + cpy #nummsg + bcs ]rts ;no more msgs + lda FrameCount+1 + cmp timetable+1,y + bcc ]rts ;not yet + lda FrameCount + cmp timetable,y + bcc ]rts + +* Yes--is this a convenient time to show msg? + + lda msgtimer + bne ]rts ;wait till other msgs are gone + +* Yes--show msg (& inc NextTimeMsg) + + inc NextTimeMsg + inc NextTimeMsg + + lda #2 + sta timerequest +]rts rts + +*------------------------------- +* +* Shorten remaining time to 15 minutes +* (e.g., 1st time player cheats by skipping a level) +* +*------------------------------- +SHORTENTIME + ldy NextTimeMsg + cpy #20 + bcs ]rts ;time is already short enough + ldy #18 + sty NextTimeMsg + lda timetable,y + sta FrameCount + lda timetable+1,y + sta FrameCount+1 +]rts rts + +*------------------------------- +* +* Cue song +* +* In: A = song # +* X = # of cycles within which song must be played +* +*------------------------------- +CUESONG + sta SongCue + stx SongCount + rts + +*------------------------------- +* +* Strobe keyboard +* +*------------------------------- +DLOOP +STROBE jsr keys ;Detect & respond to keypresses + jsr controller +]rts rts + + +*------------------------------- + lst +eof ds 1 + usr $a9,19,$b00,*-org + lst off diff --git a/01 POP Source/Source/SUBS.S b/01 POP Source/Source/SUBS.S index d000c42..4dc9b64 100755 --- a/01 POP Source/Source/SUBS.S +++ b/01 POP Source/Source/SUBS.S @@ -1 +1,1766 @@ -* subs DemoDisk = 0 EditorDisk = 0 CheckTimer = 0 org = $e000 tr on lst off *------------------------------- * * S U B S * *------------------------------- org org jmp ADDTORCHES jmp DOFLASHON jmp PAGEFLIP jmp DEMO jmp SHOWTIME jmp DOFLASHOFF jmp LRCLSE jmp potioneffect jmp checkalert jmp reflection jmp ADDSLICERS jmp PAUSE jmp bonesrise jmp DEADENEMY jmp PLAYCUT jmp ADDLOWERSOUND jmp REMOVEOBJ jmp ADDFALL jmp SETINITIALS jmp STARTKID jmp STARTKID1 jmp GRAVITY jmp INITIALGUARDS jmp MIRAPPEAR jmp CRUMBLE *------------------------------- lst put eq lst put gameeq lst put seqdata lst put movedata lst put soundnames lst off *------------------------------- dum $f0 ]Xcount ds 1 ]Xend ds 1 tempstate ds 1 dend POPside1 = $a9 POPside2 = $ad * Message #s LevelMsg = 1 ContMsg = 2 TimeMsg = 3 timemsgtimer = 20 mirscrn = 4 mirx = 4 miry = 0 ;also in topctrl, auto *------------------------------- do CheckTimer min = 180 else min = 1090 ;# frames per "minute" fin ;actual frame rate approx. 11 fps) sec = min/60 t = 60 ;game time limit *------------------------------- ALTZPon = $c009 ALTZPoff = $c008 RAMWRTaux = $c005 RAMWRTmain = $c004 RAMRDaux = $c003 RAMRDmain = $c002 *------------------------------- SceneCount ds 2 *------------------------------- * Level 13 only: When you enter, trigger loose floors on * screen above *------------------------------- ]rts rts CRUMBLE lda level cmp #13 bne ]rts lda VisScrn cmp #23 beq :1 cmp #16 bne ]rts ;Trigger blocks 2-7 on bottom row of scrn above :1 lda scrnAbove sta tempscrn lda #2 sta tempblocky ldx #7 :loop stx tempblockx jsr :trigloose ldx tempblockx dex cpx #2 bcs :loop ]rts rts :trigloose jsr rdblock1 cmp #loose bne ]rts jsr rnd and #$0f eor #$ff clc adc #1 jmp breakloose1 *------------------------------- * Add all flasks & torches on VisScrn to trans list * & swords *------------------------------- ADDTORCHES lda VisScrn jsr calcblue ldy #29 :loop lda (BlueType),y and #idmask cmp #torch bne :c1 tya pha lda VisScrn jsr trigtorch pla tay bpl :cont :c1 cmp #flask bne :c2 tya pha lda VisScrn jsr trigflask pla tay bpl :cont :c2 cmp #sword bne :cont tya pha lda VisScrn jsr trigsword pla tay :cont dey bpl :loop ]rts rts *------------------------------- * * In: A = length of pause (1-256) * *------------------------------- PAUSE :outer pha ldx #0 :loop dex bne :loop pla sec sbc #1 bne :outer ]rts rts *------------------------------- * * F L A S H * * Has a traumatic incident occured this frame? * If so, do lightning flash * *------------------------------- DOFLASHON jsr lrclse jsr vblank lda $c054 lda $c056 ;show lores rts *------------------------------- DOFLASHOFF jsr vblank lda PAGE bne :1 lda $c055 :1 lda $c057 ;show hires rts *------------------------------- * * Clear lo-res screen only if we need to * * In: A = byte value * *------------------------------ LRCLSE cmp scrncolor ;last scrncolor beq ]rts jmp lrcls *------------------------------- * Add all slicers on CharBlockY to trans list *------------------------------- slicetimer = 15 ;from mover slicersync = 3 ;# frames out of sync ADDSLICERS lda #slicetimer sta tempstate lda CharScrn jsr calcblue ldy CharBlockY cpy #3 bcs ]rts lda Mult10,y tay clc adc #10 sta :sm+1 :loop lda (BlueType),y and #idmask cmp #slicer bne :cont lda (BlueSpec),y tax and #$7f beq :ok cmp #slicerRet bcc :cont ;in mid-slice--leave it alone :ok txa and #$80 ;get hibit ora tempstate jsr trigslicer ;trigger slicer jsr getnextstate :cont iny :sm cpy #0 bcc :loop ]rts rts getnextstate lda tempstate sec sbc #slicersync cmp #slicerRet bcs :ok clc adc #slicetimer+1-slicerRet :ok sta tempstate ]rts rts *------------------------------- * * Special animation lists for princess's room * *------------------------------- ptorchx db 13,25,-1 ptorchoff db 0,6 ptorchy db 113,113 ptorchstate db 1,6 ptorchcount ds 1 psandcount ds 1 pstarcount ds 4 *------------------------------- * * Burn torches (Princess's room) * *------------------------------- pburn ldx ptorchcount ;last torch burned inx lda ptorchx,x bpl :ok ldx #0 :ok stx ptorchcount lda ptorchx,x sta XCO lda ptorchoff,x sta OFFSET lda ptorchy,x sta YCO lda ptorchstate,x jsr getflameframe sta ptorchstate,x tax jsr psetupflame jmp lay ;<---DIRECT HIRES CALL *------------------------------- * * Flow sand * *------------------------------- pflow ldx psandcount bmi ]rts ;no hourglass yet inx cpx #3 bcc :ok ldx #0 :ok stx psandcount ldy GlassState jmp flow ;<---Contains direct hires call *------------------------------- * * Twinkle stars * *------------------------------- pstars ldx #3 :loop lda pstarcount,x beq :ok dec pstarcount,x bne :ok txa pha jsr twinkle ;turn it off pla tax :ok dex bpl :loop * New twinkle? jsr rnd cmp #10 bcs ]rts jsr rnd and #3 clc adc #5 ;A = rnd length of twinkle (5-8) pha jsr rnd jsr rnd and #3 tax ;X = rnd star # (0-3) pla sta pstarcount,x jmp twinkle ;<---Contains direct hires call *------------------------------- * * P A G E F L I P * *------------------------------- PAGEFLIP jsr normspeed ;IIGS lda PAGE bne :1 lda #$20 sta PAGE lda $C054 ;show page 1 :3 lda $C057 ;hires on lda $C050 ;text off lda vibes beq :rts lda $c05e ]rts rts :rts lda $c05f rts :1 lda #0 sta PAGE lda $C055 ;show page 2 jmp :3 *------------------------------- * * Play pre-recorded "princess" scenes * * In: A = scene # * *------------------------------- AddrL db #PlayCut0,#PlayCut1,#PlayCut2,#PlayCut3 db #PlayCut4,#PlayCut5,#PlayCut6,#PlayCut7 db #PlayCut8 AddrH db #>PlayCut0,#>PlayCut1,#>PlayCut2,#>PlayCut3 db #>PlayCut4,#>PlayCut5,#>PlayCut6,#>PlayCut7 db #>PlayCut8 PLAYCUT pha jsr initit pla tax do 0 ;temp jmp PlayCut4 fin lda AddrL,x sta :sm+1 lda AddrH,x sta :sm+2 :sm jsr $FFFF ;self-mod lda #1 sta SPEED ]rts rts *------------------------------- do DemoDisk PlayCut8 PlayCut4 PlayCut7 brk else *------------------------------- * Cut #8: Princess sends out mouse *------------------------------- PlayCut8 jsr getglass jsr addglass jsr startP8 jsr SaveShad jsr startM8 jsr SaveKid lda #20 jsr play lda #Mleave jsr mjumpseq lda #20 jsr play lda #Prise jsr pjumpseq lda #20 jsr play lda #0 sta KidPosn ;mouse disappears ldx #50 lda #s_Heartbeat jmp PlaySongX *------------------------------- * Cut #4: Mouse returns to princess *------------------------------- PlayCut4 jsr getglass jsr addglass jsr startP4 jsr SaveShad jsr startM4 jsr SaveKid lda #5 jsr play lda #Pcrouch jsr pjumpseq lda #9 jsr play lda #Mraise jsr mjumpseq lda #58 jmp play *------------------------------- * Happy ending *------------------------------- PlayCut7 lda #8 sta SPEED lda #1 sta soundon sta musicon ;they must listen!! jsr startP7 jsr SaveShad lda #8 jsr play jsr startK7 jsr SaveKid lda #8 jsr play lda #Pembrace jsr pjumpseq lda #5 jsr play lda #runstop jsr vjumpseq lda #2 jsr play lda #0 sta KidPosn ;kid disappears on frame 8 of embrace lda #9 jsr play lda #s_Embrace jsr PlaySong jsr startM7 jsr SaveKid ;mouse runs in lda #12 jsr play lda #Mclimb jsr mjumpseq lda #30 jmp play fin *------------------------------- * Tragic ending *------------------------------- PlayCut6 lda #22 sta SPEED ldx #8 ;empty hourglass jsr addglass lda #2 jsr play lda #s_Tragic jsr PlaySong lda #100 jmp play *------------------------------- * Princess cut #5 *------------------------------- PlayCut5 jsr getglass cpx #7 bcs Ominous ;sand is almost out--go for it jmp PlayCut1 Ominous jsr getglass jsr addglass jsr startP5 jsr SaveShad lda #2 jsr play ldx #50 lda #s_Heartbeat jsr PlaySongX lda #Palert jsr pjumpseq ;princess hears something... lda #12 jsr play ldx #20 lda #s_Danger jmp PlaySongX *------------------------------- * Princess cut #2 (lying down) *------------------------------- PlayCut2 jsr getglass jsr addglass jsr startP2 jsr SaveShad lda #2 jsr play ldx #50 lda #s_Heartbeat jsr PlaySongX ]rts rts *------------------------------- * Princess cut #1 (standing) *------------------------------- PlayCut1 PlayCut3 jsr getglass jsr addglass jsr startP1 jsr SaveShad lda #2 jsr play ldx #50 lda #s_Timer jmp PlaySongX *------------------------------- * Opening titles scene *------------------------------- PlayCut0 jsr startV0 jsr SaveKid jsr startP0 ;put chars in starting posn jsr SaveShad lda #2 jsr play ;animate 2 frames lda #s_Princess ldx #8 jsr PlaySongI lda #5 jsr play lda #Palert jsr pjumpseq ;princess hears something... lda #9 jsr play lda #s_Squeek ldx #0 jsr PlaySongI ;door squeaks... lda #7 sta SPEED lda #5 jsr play lda #Vapproach jsr vjumpseq lda #6 jsr play lda #Vstop jsr vjumpseq lda #4 jsr play ;vizier enters lda #s_Vizier ldx #12 jsr PlaySongI lda #4 jsr play lda #Vapproach jsr vjumpseq lda #30 jsr play lda #Vstop jsr vjumpseq lda #4 jsr play ;stops in front of princess lda #s_Buildup ldx #25 jsr PlaySongI lda #Vraise ;raises arms jsr vjumpseq lda #1 jsr play lda #Pback jsr pjumpseq lda #13 jsr play ldx #0 jsr addglass1 ;hourglass appears lda #5 sta lightning lda #$ff sta lightcolor lda #12 sta SPEED lda #5 jsr play lda #0 sta psandcount ;sand starts flowing lda #s_Magic ldx #8 jsr PlaySongI lda #7 sta SPEED lda #Vexit jsr vjumpseq lda #17 jsr play ldx #1 jsr addglass1 ;glass starts to fill lda #12 jsr play lda #Pslump jsr pjumpseq lda #28 jsr play lda #12 sta SPEED lda #s_StTimer ldx #20 jmp PlaySongI *------------------------------- * Add hourglass to scene * In: X = state *------------------------------- addglass lda #0 sta psandcount ;start sand flowing addglass1 stx GlassState lda #2 sta redrawglass ]rts rts *------------------------------- * In: A = song # * X = # cycles to play if sound is off *------------------------------- PlaySongX tay lda soundon and musicon bne :1 txa jmp play :1 tya ;falls thru to PlaySong *------------------------------- * * Play Song (Princess's room) * * Button press ends song * * In: A = song # * *------------------------------- PlaySong jsr minit jsr swpage :loop lda #1 jsr strobe lda $c061 ora $c062 ora keypress bmi :interrupt jsr pburn jsr pstars jsr pflow jsr mplay cmp #0 bne :loop :interrupt jmp swpage *------------------------------- * * Play Song (Princess's room--Interruptible) * * Key or button press starts a new game * * In: A = song # * X = # cycles to play if sound is off * *------------------------------- PlaySongI tay lda soundon and musicon bne :1 txa beq ]rts jmp play :1 tya jsr minit jsr swpage :loop jsr musickeys cmp #$80 bcs :interrupt jsr pburn jsr pstars jsr pflow jsr mplay cmp #0 bne :loop jmp swpage :interrupt jmp dostartgame *------------------------------- * Switch hires pages for duration of song swpage lda PAGE eor #$20 sta PAGE ]rts rts *------------------------------- flashon lda lightning beq ]rts lda lightcolor jmp doflashon flashoff lda lightning beq ]rts dec lightning jmp doflashoff *------------------------------- * * Playback loop (simplified version of main loop in TOPCTRL) * * In: A = sequence length (# of frames) * *------------------------------- play sta SceneCount playloop jsr rnd lda SPEED jsr pause jsr strobe ;strobe kbd & jstk lda level bne :notdemo jsr demokeys bpl :cont lda #1 jmp dostartgame ;interrupted--start a new game :notdemo lda $c061 ora $c062 ora keypress bmi ]rts ;key or button to end scene :cont jsr NextFrame ;Determine what next frame should look like jsr flashon jsr FrameAdv ;Update hidden page to reflect new reality ;& show it jsr flashoff lda soundon beq :1 jsr playback ;play back sound fx jsr zerosound :1 ; jsr songcues dec SceneCount bne playloop rts *------------------------------- NextFrame jsr DoKid ;kid/vizier/mouse jsr DoShad ;always princess ]rts rts *------------------------------- FrameAdv jsr DoFast jsr vblank jmp PageFlip *------------------------------- DoKid jsr LoadKid lda CharPosn beq ]rts jsr ctrlkidchar jsr animchar ;Get next frame from sequence table jsr SaveKid ;Save all changes to char data ]rts rts *------------------------------- DoShad jsr LoadShadwOp lda CharPosn beq ]rts jsr ctrlshadchar jsr animchar jmp SaveShad *------------------------------- ctrlkidchar rts ctrlshadchar rts *------------------------------- DoFast * Set up image lists jsr zerolsts lda redrawglass beq :3 dec redrawglass ldx GlassState jsr drawglass ;hourglass :3 jsr LoadKid ;can be kid or vizier lda CharPosn beq :1 jsr setupchar lda #30 sta FCharIndex jsr addkidobj :1 jsr LoadShad ;always princess lda CharPosn beq :2 jsr setupchar lda #30 sta FCharIndex jsr addkidobj jsr pmask ;kludge to mask face & hair :2 jsr fast ;get char/objs into mid table jsr drawpost ;big white post * Draw to screen jsr pburn jsr pburn ;first put down 2 torch flames jsr pstars ;& twinkle stars jsr drawall ;...then draw the rest jmp pflow ;& flow sand ]rts rts *------------------------------- * * Jumpseq for princess & vizier * * In: A = sequence # * *------------------------------- pjumpseq pha jsr LoadShad pla jsr jumpseq jmp SaveShad kjumpseq mjumpseq vjumpseq pha jsr LoadKid pla jsr jumpseq jmp SaveKid *------------------------------- * * Put characters in starting position for scene * *------------------------------- floorY = 151 * mouse runs to princess startM8 jsr startM4 lda #144 sta CharX lda #Mstop jsr jumpseq jmp animchar startM4 lda #24 sta CharID lda #199 sta CharX lda #floorY+1 sta CharY lda #-1 sta CharFace lda #Mscurry jsr jumpseq jmp animchar * princess w/mouse startP8 jsr startP0 lda #130 sta CharX lda #floorY+3 sta CharY lda #Pstroke jsr jumpseq jmp animchar startP4 jsr startP1 lda #142 sta CharX lda #floorY+3 sta CharY lda #Pstand jsr jumpseq jmp animchar startP5 jsr startP0 lda #160 sta CharX rts startP2 jsr startP0 lda #89 sta CharX lda #floorY sta CharY lda #Plie jsr jumpseq jmp animchar startP1 jsr startP0 lda #0 sta CharFace rts startP7 jsr startP0 lda #136 sta CharX lda #floorY-2 sta CharY lda #Pwaiting ldx #1 cpx purpleflag beq :ok lda #120 ;crash (copy protect) :ok jsr jumpseq jmp animchar startM7 jsr startM4 lda #floorY-2 sta CharY rts startP0 lda #5 sta CharID lda #120 sta CharX lda #floorY sta CharY lda #-1 sta CharFace lda #Pstand jsr jumpseq jmp animchar startV0 lda #6 sta CharID lda #197 sta CharX lda #floorY sta CharY lda #-1 sta CharFace lda #Vstand jsr jumpseq jmp animchar startK7 lda #0 sta CharID lda #198 sta CharX lda #floorY-2 sta CharY lda #-1 sta CharFace lda #startrun jsr jumpseq jmp animchar *------------------------------- * Demo commands *------------------------------- EndProg = -2 EndDemo = -1 Ctr = 0 Fwd = 1 Back = 2 Up = 3 Down = 4 Upfwd = 5 Press = 6 Release = 7 *------------------------------- DemoProg1 ;up to fight w/1st guard db 0,Ctr db 1,Fwd db 13,Ctr db 30,Fwd ;start running... db 37,Upfwd ;jump 1st pit db 47,Ctr db 48,Fwd ;& keep running d1 = 65 db d1,Ctr ;stop db d1+8,Back ;look back... db d1+10,Ctr db d1+34,Back db d1+35,Ctr d2 = 115 db d2,Upfwd ;jump 2nd pit db d2+13,Press ;& grab ledge db d2+21,Up db d2+42,Release db d2+43,Ctr db d2+44,Fwd db d2+58,Down db d2+62,Ctr db d2+63,Fwd db d2+73,Ctr d3 = 193 db d3,Fwd db d3+12,Ctr db d3+40,EndDemo *------------------------------- * * D E M O * * Controls kid's movements during self-running demo * * (Called from PLAYERCTRL) * *------------------------------- DEMO lda #DemoProg1 ldx #>DemoProg1 jmp AutoPlayback *------------------------------- * * Init princess cut * *------------------------------- initit lda #" " sta scrncolor ;? lda #0 sta vibes sta redrawglass sta KidPosn sta ShadPosn sta ptorchcount ldx #3 :loop sta pstarcount,x dex bpl :loop lda #-1 ;no hourglass yet sta psandcount lda #12 sta SPEED jsr zeropeels jsr zerored jsr zerosound ]rts rts *------------------------------- * * Get hourglass state (based on time left) * * In: FrameCount * Out: X = glass state * *------------------------------- getglass jsr getminleft ldx #7 lda MinLeft cmp #6 bcc :got dex cmp #$11 bcc :got dex cmp #$21 bcc :got dex cmp #$41 bcc :got dex :got ]rts rts *------------------------------- * * Show time if requested * (& constant time display during final minute) * * In: timerequest (0 = no, 1-2 = auto, 3 = from kbd,) * 4 = Vizier dead) * *------------------------------- SHOWTIME lda timerequest beq ]rts lda KidLife bpl ]rts jsr getminleft lda MinLeft cmp #2 bcs :normal lda SecLeft beq :timeup * Countdown during final minute lda level cmp #14 bcs :normal bcc :showsec ;stop countdown when clock stops :timeup lda timerequest cmp #3 bcc ]rts ;Once t=0, show time only on kbd request :normal lda msgtimer bne ]rts ;wait till other msgs are gone lda #TimeMsg sta message lda #timemsgtimer ldx timerequest cpx #4 bcc :norm :delay lda #timemsgtimer+5 ;delay 5 cycles :norm sta msgtimer lda #0 sta timerequest ]rts rts :showsec lda SecLeft cmp #2 bcc :nomsg lda message cmp #TimeMsg beq :2 lda msgtimer bne ]rts lda #TimeMsg sta message :2 lda #1 sta timerequest lda #1 sta msgtimer rts :nomsg lda #0 sta timerequest sta msgtimer rts *------------------------------- * Add lowering-gate sound (only when gate is visible) * In: A = state *------------------------------- ADDLOWERSOUND lsr bcc ]rts ;alt frames lda level cmp #3 bne :n lda trscrn cmp #2 ;Exception: Level 3, screen 2 beq :y :n lda trscrn cmp scrnLeft bne :1 ldy trloc cpy #9 beq :y cpy #19 beq :y cpy #29 beq :y ;visible to left ]rts rts :1 cmp VisScrn bne ]rts ldy trloc cpy #9 beq ]rts cpy #19 beq ]rts cpy #29 beq ]rts :y lda #LoweringGate jmp addsound *------------------------------- * * Remove object * * In: A = lastpotion * *------------------------------- REMOVEOBJ sta lastpotion ldx #1 stx clrbtn lda #floor sta (BlueType),y ;remove object lda #0 sta (BlueSpec),y lda #35 ;TEMP sta height lda #2 clc jsr markwipe jmp markred *------------------------------- * * S E T I N I T I A L S * * Set initial states of gadgets * *------------------------------- SETINITIALS lda INFO ;number of screens +1 sec sbc #1 sta SCRNUM :loop jsr DoScrn ;for every screen dec SCRNUM bne :loop rts *------------------------------- DoScrn lda SCRNUM jsr calcblue ldy #29 :loop jsr getinitobj bcc :skip sta (BlueSpec),y :skip dey bpl :loop rts *------------------------------- * * S T A R T K I D * * Put kid in his starting position for this level * *------------------------------- STARTKID lda level cmp #3 bne :nomile * Level 3 milestone? :special3 lda milestone ;set to 1 when he gets past 1st gate beq :nomile lda #-1 sta KidStartFace lda #2 sta KidStartScrn lda #6 sta KidStartBlock ;put him just inside 1st gate... lda #7 ldx #4 ldy #0 jsr rdblock lda #space sta (BlueType),y ;remove loose floor... ;& continue :nomile lda KidStartScrn ;in INFO sta CharScrn lda KidStartBlock jsr unindex ;return A = blockx, X = blocky sta CharBlockX stx CharBlockY lda CharBlockX jsr getblockej clc adc #angle+7 sta CharX ;put kid on starting block lda KidStartFace eor #$ff sta CharFace lda origstrength ldx level bne :notdemo lda #4 :notdemo sta MaxKidStr sta KidStrength do EditorDisk jmp :normal fin lda level cmp #1 beq :special1 cmp #13 beq :special13 bne :normal * Special start for Level 1 :special1 lda #5 ;scrn ldx #2 ;blockx ldy #0 ;blocky jsr rdblock jsr pushpp ;slam gate shut lda #stepfall jsr jumpseq jmp STARTKID1 * & for level 13 :special13 lda #running jsr jumpseq jmp STARTKID1 * Normal start :normal lda #turn jsr jumpseq ;start in standing posn STARTKID1 ldx CharBlockY lda FloorY+1,x sta CharY lda #-1 sta CharLife ;ff = alive lda #0 ;kid sta CharID lda #0 sta CharXVel sta CharYVel sta waitingtojump sta weightless sta invert sta jarabove sta droppedout sta CharSword sta offguard :done jsr animchar ;get next frame * WTLESS level only--kid falls into screen lda level cmp #7 ;WTLESS level bne :notsp lda yellowflag ;should be - bmi :yelok lda #$40 sta timebomb ;2nd level copy protection :yelok lda CharScrn cmp #17 bne :notsp lda #3 ;down jsr cut :notsp jmp SaveKid ;save KidVars ]rts rts *------------------------------- * * G R A V I T Y * *------------------------------- TermVelocity = 33 AccelGravity = 3 WtlessTermVel = 4 WtlessGravity = 1 GRAVITY lda CharAction cmp #4 bne ]rts lda weightless bne :wtless lda CharYVel clc adc #AccelGravity cmp #TermVelocity bcc :ok lda #TermVelocity :ok sta CharYVel ]rts rts :wtless lda CharYVel clc adc #WtlessGravity cmp #WtlessTermVel bcc :ok lda #WtlessTermVel bcs :ok *------------------------------- * * Add falling velocity * *------------------------------- ADDFALL lda CharYVel clc adc CharY sta CharY * X-vel lda CharAction cmp #4 ;freefall? bne ]rts lda CharXVel jsr addcharx sta CharX jmp rereadblocks *------------------------------- * * Set initial guard posns for entire level (call once) * *------------------------------- INITIALGUARDS ldy #24 ;screen # :loop lda GdStartBlock-1,y cmp #30 bcs :nogd jsr unindex ;A = blockx jsr getblockej clc adc #angle+7 sta GdStartX-1,y lda #0 sta GdStartSeqH-1,y :nogd dey bne :loop ]rts rts *------------------------------- * * Newly dead enemy--play music (or whatever) * * In: Char vars * *------------------------------- DEADENEMY lda level beq :demo cmp #13 beq :wingame lda CharID cmp #1 beq ]rts ;shadow lda #s_Vict ldx #25 jsr cuesong ]rts rts :demo lda #1 sta milestone ;start demo, part 2 lda #0 sta PreRecPtr sta PlayCount rts :wingame lda #s_Upstairs ldx #25 jsr cuesong lda #$ff ;white sta lightcolor lda #10 sta lightning lda #1 sta exitopen lda #4 sta timerequest lda #24 ldx #0 ldy #0 jsr rdblock jmp pushpp ;open exit *------------------------------- * Mirror appears (called by MOVER when exit opened) *------------------------------- MIRAPPEAR do DemoDisk rts else lda level cmp #4 bne ]rts lda #mirscrn ldx #mirx ldy #miry jsr rdblock lda #mirror sta (BlueType),y rts fin *------------------------------- lst ds 1 usr $a9,20,$400,*-org lst off \ No newline at end of file +* subs +DemoDisk = 0 +EditorDisk = 0 +CheckTimer = 0 +org = $e000 + tr on + lst off +*------------------------------- +* +* S U B S +* +*------------------------------- + org org + + jmp ADDTORCHES + jmp DOFLASHON + jmp PAGEFLIP + jmp DEMO + jmp SHOWTIME + + jmp DOFLASHOFF + jmp LRCLSE + jmp potioneffect + jmp checkalert + jmp reflection + + jmp ADDSLICERS + jmp PAUSE + jmp bonesrise + jmp DEADENEMY + jmp PLAYCUT + + jmp ADDLOWERSOUND + jmp REMOVEOBJ + jmp ADDFALL + jmp SETINITIALS + jmp STARTKID + + jmp STARTKID1 + jmp GRAVITY + jmp INITIALGUARDS + jmp MIRAPPEAR + jmp CRUMBLE + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put seqdata + lst + put movedata + lst + put soundnames + lst off + +*------------------------------- + dum $f0 +]Xcount ds 1 +]Xend ds 1 +tempstate ds 1 + dend + + +POPside1 = $a9 +POPside2 = $ad + +* Message #s + +LevelMsg = 1 +ContMsg = 2 +TimeMsg = 3 + +timemsgtimer = 20 + +mirscrn = 4 +mirx = 4 +miry = 0 ;also in topctrl, auto + +*------------------------------- + do CheckTimer +min = 180 + else +min = 1090 ;# frames per "minute" + fin ;actual frame rate approx. 11 fps) + +sec = min/60 +t = 60 ;game time limit + +*------------------------------- +ALTZPon = $c009 +ALTZPoff = $c008 +RAMWRTaux = $c005 +RAMWRTmain = $c004 +RAMRDaux = $c003 +RAMRDmain = $c002 + +*------------------------------- +SceneCount ds 2 + +*------------------------------- +* Level 13 only: When you enter, trigger loose floors on +* screen above +*------------------------------- +]rts rts + +CRUMBLE + lda level + cmp #13 + bne ]rts + lda VisScrn + cmp #23 + beq :1 + cmp #16 + bne ]rts +;Trigger blocks 2-7 on bottom row of scrn above +:1 lda scrnAbove + sta tempscrn + lda #2 + sta tempblocky + ldx #7 +:loop stx tempblockx + jsr :trigloose + ldx tempblockx + dex + cpx #2 + bcs :loop +]rts rts + +:trigloose + jsr rdblock1 + cmp #loose + bne ]rts + jsr rnd + and #$0f + eor #$ff + clc + adc #1 + jmp breakloose1 + +*------------------------------- +* Add all flasks & torches on VisScrn to trans list +* & swords +*------------------------------- +ADDTORCHES + lda VisScrn + jsr calcblue + + ldy #29 +:loop lda (BlueType),y + and #idmask + cmp #torch + bne :c1 + tya + pha + lda VisScrn + jsr trigtorch + pla + tay + bpl :cont + +:c1 cmp #flask + bne :c2 + tya + pha + lda VisScrn + jsr trigflask + pla + tay + bpl :cont + +:c2 cmp #sword + bne :cont + tya + pha + lda VisScrn + jsr trigsword + pla + tay +:cont dey + bpl :loop + +]rts rts + +*------------------------------- +* +* In: A = length of pause (1-256) +* +*------------------------------- +PAUSE +:outer pha + ldx #0 +:loop dex + bne :loop + pla + sec + sbc #1 + bne :outer +]rts rts + +*------------------------------- +* +* F L A S H +* +* Has a traumatic incident occured this frame? +* If so, do lightning flash +* +*------------------------------- +DOFLASHON + jsr lrclse + + jsr vblank + + lda $c054 + lda $c056 ;show lores + rts + +*------------------------------- +DOFLASHOFF + jsr vblank + + lda PAGE + bne :1 + + lda $c055 +:1 lda $c057 ;show hires + + rts + +*------------------------------- +* +* Clear lo-res screen only if we need to +* +* In: A = byte value +* +*------------------------------ +LRCLSE + cmp scrncolor ;last scrncolor + beq ]rts + + jmp lrcls + +*------------------------------- +* Add all slicers on CharBlockY to trans list +*------------------------------- +slicetimer = 15 ;from mover +slicersync = 3 ;# frames out of sync + +ADDSLICERS + lda #slicetimer + sta tempstate + + lda CharScrn + jsr calcblue + + ldy CharBlockY + cpy #3 + bcs ]rts + + lda Mult10,y + tay + clc + adc #10 + sta :sm+1 +:loop + lda (BlueType),y + and #idmask + cmp #slicer + bne :cont + + lda (BlueSpec),y + tax + and #$7f + beq :ok + cmp #slicerRet + bcc :cont ;in mid-slice--leave it alone +:ok txa + and #$80 ;get hibit + ora tempstate + jsr trigslicer ;trigger slicer + jsr getnextstate + +:cont iny +:sm cpy #0 + bcc :loop + +]rts rts + +getnextstate + lda tempstate + sec + sbc #slicersync + cmp #slicerRet + bcs :ok + clc + adc #slicetimer+1-slicerRet +:ok sta tempstate +]rts rts + +*------------------------------- +* +* Special animation lists for princess's room +* +*------------------------------- +ptorchx db 13,25,-1 +ptorchoff db 0,6 +ptorchy db 113,113 +ptorchstate db 1,6 +ptorchcount ds 1 +psandcount ds 1 +pstarcount ds 4 + +*------------------------------- +* +* Burn torches (Princess's room) +* +*------------------------------- +pburn + ldx ptorchcount ;last torch burned + inx + lda ptorchx,x + bpl :ok + ldx #0 +:ok stx ptorchcount + lda ptorchx,x + sta XCO + lda ptorchoff,x + sta OFFSET + lda ptorchy,x + sta YCO + lda ptorchstate,x + jsr getflameframe + sta ptorchstate,x + tax + jsr psetupflame + jmp lay ;<---DIRECT HIRES CALL + +*------------------------------- +* +* Flow sand +* +*------------------------------- +pflow + ldx psandcount + bmi ]rts ;no hourglass yet + inx + cpx #3 + bcc :ok + ldx #0 +:ok stx psandcount + ldy GlassState + jmp flow ;<---Contains direct hires call + +*------------------------------- +* +* Twinkle stars +* +*------------------------------- +pstars + ldx #3 +:loop lda pstarcount,x + beq :ok + dec pstarcount,x + bne :ok + txa + pha + jsr twinkle ;turn it off + pla + tax +:ok dex + bpl :loop + +* New twinkle? + + jsr rnd + cmp #10 + bcs ]rts + jsr rnd + and #3 + clc + adc #5 ;A = rnd length of twinkle (5-8) + pha + jsr rnd + jsr rnd + and #3 + tax ;X = rnd star # (0-3) + pla + sta pstarcount,x + jmp twinkle ;<---Contains direct hires call + +*------------------------------- +* +* P A G E F L I P +* +*------------------------------- +PAGEFLIP + jsr normspeed ;IIGS + lda PAGE + bne :1 + + lda #$20 + sta PAGE + lda $C054 ;show page 1 + +:3 lda $C057 ;hires on + lda $C050 ;text off + lda vibes + beq :rts + lda $c05e +]rts rts +:rts lda $c05f + rts + +:1 lda #0 + sta PAGE + lda $C055 ;show page 2 + jmp :3 + +*------------------------------- +* +* Play pre-recorded "princess" scenes +* +* In: A = scene # +* +*------------------------------- +AddrL db #PlayCut0,#PlayCut1,#PlayCut2,#PlayCut3 + db #PlayCut4,#PlayCut5,#PlayCut6,#PlayCut7 + db #PlayCut8 +AddrH db #>PlayCut0,#>PlayCut1,#>PlayCut2,#>PlayCut3 + db #>PlayCut4,#>PlayCut5,#>PlayCut6,#>PlayCut7 + db #>PlayCut8 + +PLAYCUT + pha + jsr initit + pla + tax + + do 0 ;temp + jmp PlayCut4 + fin + + lda AddrL,x + sta :sm+1 + lda AddrH,x + sta :sm+2 +:sm jsr $FFFF ;self-mod + + lda #1 + sta SPEED +]rts rts + +*------------------------------- + do DemoDisk +PlayCut8 +PlayCut4 +PlayCut7 + brk + else +*------------------------------- +* Cut #8: Princess sends out mouse +*------------------------------- +PlayCut8 + jsr getglass + jsr addglass + + jsr startP8 + jsr SaveShad + jsr startM8 + jsr SaveKid + + lda #20 + jsr play + + lda #Mleave + jsr mjumpseq + lda #20 + jsr play + + lda #Prise + jsr pjumpseq + + lda #20 + jsr play + + lda #0 + sta KidPosn ;mouse disappears + ldx #50 + lda #s_Heartbeat + jmp PlaySongX + +*------------------------------- +* Cut #4: Mouse returns to princess +*------------------------------- +PlayCut4 + jsr getglass + jsr addglass + + jsr startP4 + jsr SaveShad + jsr startM4 + jsr SaveKid + lda #5 + jsr play + + lda #Pcrouch + jsr pjumpseq + lda #9 + jsr play + + lda #Mraise + jsr mjumpseq + + lda #58 + jmp play + +*------------------------------- +* Happy ending +*------------------------------- +PlayCut7 + lda #8 + sta SPEED + + lda #1 + sta soundon + sta musicon ;they must listen!! + + jsr startP7 + jsr SaveShad + lda #8 + jsr play + + jsr startK7 + jsr SaveKid + lda #8 + jsr play + + lda #Pembrace + jsr pjumpseq + lda #5 + jsr play + + lda #runstop + jsr vjumpseq + lda #2 + jsr play + + lda #0 + sta KidPosn ;kid disappears on frame 8 of embrace + + lda #9 + jsr play + + lda #s_Embrace + jsr PlaySong + + jsr startM7 + jsr SaveKid ;mouse runs in + + lda #12 + jsr play + + lda #Mclimb + jsr mjumpseq + + lda #30 + jmp play + + fin + +*------------------------------- +* Tragic ending +*------------------------------- +PlayCut6 + lda #22 + sta SPEED + ldx #8 ;empty hourglass + jsr addglass + lda #2 + jsr play + lda #s_Tragic + jsr PlaySong + lda #100 + jmp play + +*------------------------------- +* Princess cut #5 +*------------------------------- +PlayCut5 + jsr getglass + cpx #7 + bcs Ominous ;sand is almost out--go for it + jmp PlayCut1 + +Ominous + jsr getglass + jsr addglass + + jsr startP5 + jsr SaveShad + + lda #2 + jsr play + + ldx #50 + lda #s_Heartbeat + jsr PlaySongX + + lda #Palert + jsr pjumpseq ;princess hears something... + lda #12 + jsr play + + ldx #20 + lda #s_Danger + jmp PlaySongX + +*------------------------------- +* Princess cut #2 (lying down) +*------------------------------- +PlayCut2 + jsr getglass + jsr addglass + + jsr startP2 + jsr SaveShad + + lda #2 + jsr play + + ldx #50 + lda #s_Heartbeat + jsr PlaySongX +]rts rts + +*------------------------------- +* Princess cut #1 (standing) +*------------------------------- +PlayCut1 +PlayCut3 + jsr getglass + jsr addglass + + jsr startP1 + jsr SaveShad + + lda #2 + jsr play + + ldx #50 + lda #s_Timer + jmp PlaySongX + +*------------------------------- +* Opening titles scene +*------------------------------- +PlayCut0 + jsr startV0 + jsr SaveKid + jsr startP0 ;put chars in starting posn + jsr SaveShad + + lda #2 + jsr play ;animate 2 frames + + lda #s_Princess + ldx #8 + jsr PlaySongI + + lda #5 + jsr play + + lda #Palert + jsr pjumpseq ;princess hears something... + lda #9 + jsr play + lda #s_Squeek + ldx #0 + jsr PlaySongI ;door squeaks... + + lda #7 + sta SPEED + + lda #5 + jsr play + lda #Vapproach + jsr vjumpseq + lda #6 + jsr play + lda #Vstop + jsr vjumpseq + lda #4 + jsr play ;vizier enters + lda #s_Vizier + ldx #12 + jsr PlaySongI + lda #4 + jsr play + + lda #Vapproach + jsr vjumpseq + lda #30 + jsr play + lda #Vstop + jsr vjumpseq + lda #4 + jsr play ;stops in front of princess + lda #s_Buildup + ldx #25 + jsr PlaySongI + + lda #Vraise ;raises arms + jsr vjumpseq + lda #1 + jsr play + lda #Pback + jsr pjumpseq + lda #13 + jsr play + ldx #0 + jsr addglass1 ;hourglass appears + lda #5 + sta lightning + lda #$ff + sta lightcolor + + lda #12 + sta SPEED + lda #5 + jsr play + lda #0 + sta psandcount ;sand starts flowing + lda #s_Magic + ldx #8 + jsr PlaySongI + + lda #7 + sta SPEED + lda #Vexit + jsr vjumpseq + lda #17 + jsr play + ldx #1 + jsr addglass1 ;glass starts to fill + lda #12 + jsr play + lda #Pslump + jsr pjumpseq + lda #28 + jsr play + + lda #12 + sta SPEED + lda #s_StTimer + ldx #20 + jmp PlaySongI + +*------------------------------- +* Add hourglass to scene +* In: X = state +*------------------------------- +addglass + lda #0 + sta psandcount ;start sand flowing +addglass1 + stx GlassState + lda #2 + sta redrawglass +]rts rts + +*------------------------------- +* In: A = song # +* X = # cycles to play if sound is off +*------------------------------- +PlaySongX + tay + lda soundon + and musicon + bne :1 + txa + jmp play +:1 tya ;falls thru to PlaySong + +*------------------------------- +* +* Play Song (Princess's room) +* +* Button press ends song +* +* In: A = song # +* +*------------------------------- +PlaySong + jsr minit + jsr swpage +:loop lda #1 + jsr strobe + lda $c061 + ora $c062 + ora keypress + bmi :interrupt + jsr pburn + jsr pstars + jsr pflow + jsr mplay + cmp #0 + bne :loop +:interrupt + jmp swpage + +*------------------------------- +* +* Play Song (Princess's room--Interruptible) +* +* Key or button press starts a new game +* +* In: A = song # +* X = # cycles to play if sound is off +* +*------------------------------- +PlaySongI + tay + lda soundon + and musicon + bne :1 + txa + beq ]rts + jmp play +:1 tya + + jsr minit + jsr swpage +:loop jsr musickeys + cmp #$80 + bcs :interrupt + jsr pburn + jsr pstars + jsr pflow + jsr mplay + cmp #0 + bne :loop + jmp swpage +:interrupt + jmp dostartgame + +*------------------------------- +* Switch hires pages for duration of song + +swpage + lda PAGE + eor #$20 + sta PAGE +]rts rts + +*------------------------------- +flashon + lda lightning + beq ]rts + lda lightcolor + jmp doflashon + +flashoff + lda lightning + beq ]rts + dec lightning + jmp doflashoff + +*------------------------------- +* +* Playback loop (simplified version of main loop in TOPCTRL) +* +* In: A = sequence length (# of frames) +* +*------------------------------- +play + sta SceneCount +playloop + jsr rnd + + lda SPEED + jsr pause + + jsr strobe ;strobe kbd & jstk + + lda level + bne :notdemo + jsr demokeys + bpl :cont + lda #1 + jmp dostartgame ;interrupted--start a new game + +:notdemo lda $c061 + ora $c062 + ora keypress + bmi ]rts ;key or button to end scene + +:cont jsr NextFrame ;Determine what next frame should look like + + jsr flashon + + jsr FrameAdv ;Update hidden page to reflect new reality +;& show it + jsr flashoff + + lda soundon + beq :1 + jsr playback ;play back sound fx + jsr zerosound +:1 +; jsr songcues + + dec SceneCount + bne playloop + rts + +*------------------------------- +NextFrame + jsr DoKid ;kid/vizier/mouse + + jsr DoShad ;always princess + +]rts rts + +*------------------------------- +FrameAdv + jsr DoFast + + jsr vblank + + jmp PageFlip + +*------------------------------- +DoKid + jsr LoadKid + lda CharPosn + beq ]rts + + jsr ctrlkidchar + + jsr animchar ;Get next frame from sequence table + + jsr SaveKid ;Save all changes to char data + +]rts rts + +*------------------------------- +DoShad + jsr LoadShadwOp + lda CharPosn + beq ]rts + + jsr ctrlshadchar + + jsr animchar + + jmp SaveShad + +*------------------------------- +ctrlkidchar + rts + +ctrlshadchar + rts + +*------------------------------- +DoFast + +* Set up image lists + + jsr zerolsts + + lda redrawglass + beq :3 + dec redrawglass + ldx GlassState + jsr drawglass ;hourglass +:3 + jsr LoadKid ;can be kid or vizier + lda CharPosn + beq :1 + jsr setupchar + lda #30 + sta FCharIndex + jsr addkidobj +:1 + jsr LoadShad ;always princess + lda CharPosn + beq :2 + jsr setupchar + lda #30 + sta FCharIndex + jsr addkidobj + jsr pmask ;kludge to mask face & hair +:2 + jsr fast ;get char/objs into mid table + + jsr drawpost ;big white post + +* Draw to screen + + jsr pburn + jsr pburn ;first put down 2 torch flames + jsr pstars ;& twinkle stars + + jsr drawall ;...then draw the rest + + jmp pflow ;& flow sand + +]rts rts + +*------------------------------- +* +* Jumpseq for princess & vizier +* +* In: A = sequence # +* +*------------------------------- +pjumpseq + pha + jsr LoadShad + pla + jsr jumpseq + jmp SaveShad + +kjumpseq +mjumpseq +vjumpseq + pha + jsr LoadKid + pla + jsr jumpseq + jmp SaveKid + +*------------------------------- +* +* Put characters in starting position for scene +* +*------------------------------- +floorY = 151 + +* mouse runs to princess + +startM8 + jsr startM4 + lda #144 + sta CharX + lda #Mstop + jsr jumpseq + jmp animchar + +startM4 + lda #24 + sta CharID + lda #199 + sta CharX + lda #floorY+1 + sta CharY + lda #-1 + sta CharFace + + lda #Mscurry + jsr jumpseq + jmp animchar + +* princess w/mouse + +startP8 + jsr startP0 + lda #130 + sta CharX + lda #floorY+3 + sta CharY + lda #Pstroke + jsr jumpseq + jmp animchar + +startP4 + jsr startP1 + lda #142 + sta CharX + lda #floorY+3 + sta CharY + lda #Pstand + jsr jumpseq + jmp animchar + +startP5 + jsr startP0 + lda #160 + sta CharX + rts + +startP2 + jsr startP0 + lda #89 + sta CharX + lda #floorY + sta CharY + + lda #Plie + jsr jumpseq + jmp animchar + +startP1 + jsr startP0 + lda #0 + sta CharFace + rts + +startP7 + jsr startP0 + lda #136 + sta CharX + lda #floorY-2 + sta CharY + lda #Pwaiting + ldx #1 + cpx purpleflag + beq :ok + lda #120 ;crash (copy protect) +:ok jsr jumpseq + jmp animchar + +startM7 + jsr startM4 + lda #floorY-2 + sta CharY + rts + +startP0 + lda #5 + sta CharID + + lda #120 + sta CharX + lda #floorY + sta CharY + + lda #-1 + sta CharFace + + lda #Pstand + jsr jumpseq + jmp animchar + +startV0 + lda #6 + sta CharID + + lda #197 + sta CharX + lda #floorY + sta CharY + + lda #-1 + sta CharFace + + lda #Vstand + jsr jumpseq + jmp animchar + +startK7 + lda #0 + sta CharID + + lda #198 + sta CharX + lda #floorY-2 + sta CharY + + lda #-1 + sta CharFace + + lda #startrun + jsr jumpseq + jmp animchar + +*------------------------------- +* Demo commands +*------------------------------- +EndProg = -2 +EndDemo = -1 +Ctr = 0 +Fwd = 1 +Back = 2 +Up = 3 +Down = 4 +Upfwd = 5 +Press = 6 +Release = 7 + +*------------------------------- +DemoProg1 ;up to fight w/1st guard + db 0,Ctr + db 1,Fwd + db 13,Ctr + db 30,Fwd ;start running... + db 37,Upfwd ;jump 1st pit + db 47,Ctr + db 48,Fwd ;& keep running +d1 = 65 + db d1,Ctr ;stop + db d1+8,Back ;look back... + db d1+10,Ctr + db d1+34,Back + db d1+35,Ctr +d2 = 115 + db d2,Upfwd ;jump 2nd pit + db d2+13,Press ;& grab ledge + db d2+21,Up + db d2+42,Release + db d2+43,Ctr + db d2+44,Fwd + db d2+58,Down + db d2+62,Ctr + db d2+63,Fwd + db d2+73,Ctr +d3 = 193 + db d3,Fwd + db d3+12,Ctr + db d3+40,EndDemo + +*------------------------------- +* +* D E M O +* +* Controls kid's movements during self-running demo +* +* (Called from PLAYERCTRL) +* +*------------------------------- +DEMO + lda #DemoProg1 + ldx #>DemoProg1 + jmp AutoPlayback + +*------------------------------- +* +* Init princess cut +* +*------------------------------- +initit + lda #" " + sta scrncolor ;? + lda #0 + sta vibes + sta redrawglass + sta KidPosn + sta ShadPosn + sta ptorchcount + ldx #3 +:loop sta pstarcount,x + dex + bpl :loop + + lda #-1 ;no hourglass yet + sta psandcount + + lda #12 + sta SPEED + + jsr zeropeels + jsr zerored + jsr zerosound +]rts rts + +*------------------------------- +* +* Get hourglass state (based on time left) +* +* In: FrameCount +* Out: X = glass state +* +*------------------------------- +getglass + jsr getminleft + ldx #7 + lda MinLeft + cmp #6 + bcc :got + dex + cmp #$11 + bcc :got + dex + cmp #$21 + bcc :got + dex + cmp #$41 + bcc :got + dex +:got +]rts rts + +*------------------------------- +* +* Show time if requested +* (& constant time display during final minute) +* +* In: timerequest (0 = no, 1-2 = auto, 3 = from kbd,) +* 4 = Vizier dead) +* +*------------------------------- +SHOWTIME + lda timerequest + beq ]rts + lda KidLife + bpl ]rts + + jsr getminleft + + lda MinLeft + cmp #2 + bcs :normal + lda SecLeft + beq :timeup + +* Countdown during final minute + + lda level + cmp #14 + bcs :normal + bcc :showsec ;stop countdown when clock stops + +:timeup + lda timerequest + cmp #3 + bcc ]rts ;Once t=0, show time only on kbd request + +:normal + lda msgtimer + bne ]rts ;wait till other msgs are gone + + lda #TimeMsg + sta message + lda #timemsgtimer + ldx timerequest + cpx #4 + bcc :norm +:delay lda #timemsgtimer+5 ;delay 5 cycles +:norm sta msgtimer + + lda #0 + sta timerequest +]rts rts + +:showsec + lda SecLeft + cmp #2 + bcc :nomsg + + lda message + cmp #TimeMsg + beq :2 + lda msgtimer + bne ]rts + lda #TimeMsg + sta message +:2 lda #1 + sta timerequest + lda #1 + sta msgtimer + rts +:nomsg lda #0 + sta timerequest + sta msgtimer + rts + +*------------------------------- +* Add lowering-gate sound (only when gate is visible) +* In: A = state +*------------------------------- +ADDLOWERSOUND + lsr + bcc ]rts ;alt frames + + lda level + cmp #3 + bne :n + lda trscrn + cmp #2 ;Exception: Level 3, screen 2 + beq :y +:n lda trscrn + cmp scrnLeft + bne :1 + ldy trloc + cpy #9 + beq :y + cpy #19 + beq :y + cpy #29 + beq :y ;visible to left +]rts rts + +:1 cmp VisScrn + bne ]rts + ldy trloc + cpy #9 + beq ]rts + cpy #19 + beq ]rts + cpy #29 + beq ]rts + +:y lda #LoweringGate + jmp addsound + +*------------------------------- +* +* Remove object +* +* In: A = lastpotion +* +*------------------------------- +REMOVEOBJ + sta lastpotion + + ldx #1 + stx clrbtn + + lda #floor + sta (BlueType),y ;remove object + lda #0 + sta (BlueSpec),y + + lda #35 ;TEMP + sta height + + lda #2 + clc + jsr markwipe + jmp markred + +*------------------------------- +* +* S E T I N I T I A L S +* +* Set initial states of gadgets +* +*------------------------------- +SETINITIALS + lda INFO ;number of screens +1 + sec + sbc #1 + sta SCRNUM + +:loop jsr DoScrn ;for every screen + + dec SCRNUM + bne :loop + rts + +*------------------------------- +DoScrn + lda SCRNUM + jsr calcblue + + ldy #29 + +:loop jsr getinitobj + bcc :skip + sta (BlueSpec),y + +:skip dey + bpl :loop + + rts + +*------------------------------- +* +* S T A R T K I D +* +* Put kid in his starting position for this level +* +*------------------------------- +STARTKID + lda level + cmp #3 + bne :nomile + +* Level 3 milestone? + +:special3 + lda milestone ;set to 1 when he gets past 1st gate + beq :nomile + lda #-1 + sta KidStartFace + lda #2 + sta KidStartScrn + lda #6 + sta KidStartBlock ;put him just inside 1st gate... + + lda #7 + ldx #4 + ldy #0 + jsr rdblock + lda #space + sta (BlueType),y ;remove loose floor... +;& continue +:nomile + lda KidStartScrn ;in INFO + sta CharScrn + + lda KidStartBlock + jsr unindex ;return A = blockx, X = blocky + + sta CharBlockX + stx CharBlockY + + lda CharBlockX + jsr getblockej + clc + adc #angle+7 + sta CharX ;put kid on starting block + + lda KidStartFace + eor #$ff + sta CharFace + + lda origstrength + ldx level + bne :notdemo + lda #4 +:notdemo sta MaxKidStr + sta KidStrength + + do EditorDisk + jmp :normal + fin + + lda level + cmp #1 + beq :special1 + cmp #13 + beq :special13 + bne :normal + +* Special start for Level 1 + +:special1 + lda #5 ;scrn + ldx #2 ;blockx + ldy #0 ;blocky + jsr rdblock + jsr pushpp ;slam gate shut + + lda #stepfall + jsr jumpseq + jmp STARTKID1 + +* & for level 13 + +:special13 + lda #running + jsr jumpseq + jmp STARTKID1 + +* Normal start + +:normal lda #turn + jsr jumpseq ;start in standing posn + +STARTKID1 + ldx CharBlockY + lda FloorY+1,x + sta CharY + + lda #-1 + sta CharLife ;ff = alive + + lda #0 ;kid + sta CharID + + lda #0 + sta CharXVel + sta CharYVel + sta waitingtojump + sta weightless + sta invert + sta jarabove + sta droppedout + sta CharSword + sta offguard + +:done jsr animchar ;get next frame + +* WTLESS level only--kid falls into screen + + lda level + cmp #7 ;WTLESS level + bne :notsp + + lda yellowflag ;should be - + bmi :yelok + lda #$40 + sta timebomb ;2nd level copy protection +:yelok + lda CharScrn + cmp #17 + bne :notsp + lda #3 ;down + jsr cut +:notsp + jmp SaveKid ;save KidVars + +]rts rts + +*------------------------------- +* +* G R A V I T Y +* +*------------------------------- +TermVelocity = 33 +AccelGravity = 3 +WtlessTermVel = 4 +WtlessGravity = 1 + +GRAVITY + lda CharAction + cmp #4 + bne ]rts + + lda weightless + bne :wtless + + lda CharYVel + clc + adc #AccelGravity + + cmp #TermVelocity + bcc :ok + lda #TermVelocity + +:ok sta CharYVel +]rts rts + +:wtless lda CharYVel + clc + adc #WtlessGravity + + cmp #WtlessTermVel + bcc :ok + lda #WtlessTermVel + bcs :ok + +*------------------------------- +* +* Add falling velocity +* +*------------------------------- +ADDFALL + lda CharYVel + clc + adc CharY + sta CharY + +* X-vel + + lda CharAction + cmp #4 ;freefall? + bne ]rts + + lda CharXVel + jsr addcharx + sta CharX + + jmp rereadblocks + +*------------------------------- +* +* Set initial guard posns for entire level (call once) +* +*------------------------------- +INITIALGUARDS + ldy #24 ;screen # +:loop + lda GdStartBlock-1,y + cmp #30 + bcs :nogd + jsr unindex ;A = blockx + jsr getblockej + clc + adc #angle+7 + sta GdStartX-1,y + lda #0 + sta GdStartSeqH-1,y + +:nogd dey + bne :loop +]rts rts + +*------------------------------- +* +* Newly dead enemy--play music (or whatever) +* +* In: Char vars +* +*------------------------------- +DEADENEMY + lda level + beq :demo + cmp #13 + beq :wingame + + lda CharID + cmp #1 + beq ]rts ;shadow + lda #s_Vict + ldx #25 + jsr cuesong +]rts rts + +:demo lda #1 + sta milestone ;start demo, part 2 + lda #0 + sta PreRecPtr + sta PlayCount + rts + +:wingame lda #s_Upstairs + ldx #25 + jsr cuesong + + lda #$ff ;white + sta lightcolor + lda #10 + sta lightning + + lda #1 + sta exitopen + lda #4 + sta timerequest + + lda #24 + ldx #0 + ldy #0 + jsr rdblock + jmp pushpp ;open exit + +*------------------------------- +* Mirror appears (called by MOVER when exit opened) +*------------------------------- +MIRAPPEAR + do DemoDisk + rts + else + + lda level + cmp #4 + bne ]rts + + lda #mirscrn + ldx #mirx + ldy #miry + jsr rdblock + lda #mirror + sta (BlueType),y + rts + + fin + +*------------------------------- + lst + ds 1 + usr $a9,20,$400,*-org + lst off diff --git a/01 POP Source/Source/TABLES.S b/01 POP Source/Source/TABLES.S index 2261f5f..1bc3013 100755 --- a/01 POP Source/Source/TABLES.S +++ b/01 POP Source/Source/TABLES.S @@ -1 +1,200 @@ -* tables org = $e00 tr on lst off *------------------------------- * * PRINCE OF PERSIA * Copyright 1989 Jordan Mechner * *------------------------------- dum org ByteTable ds $100 OffsetTable ds $100 BlockTable ds $100 PixelTable ds $100 Mult10 ds $10 Mult7 ds $10 Mult30 ds $40 BlockEdge ds 20 BlockTop ds 5 BlockBot ds 5 FloorY ds 5 BlockAy ds 5 dend *------------------------------- org org *------------------------------- ScrnLeft = 58 ScrnTop = 0 ScrnBot = 191 VertDist = 10 ;from bottom of block to center plane BlockHeight = 63 DHeight = 3 ;floorpiece thickness Blox1 = BlockHeight Blox2 = 2*BlockHeight Blox3 = 3*BlockHeight Blox4 = 4*BlockHeight *------------------------------- * ByteTable * * Index: Real screen X-coord (0-255) * Yields: Byte # (0-36) *------------------------------- ds ByteTable-* ]byte = 0 lup 36 db ]byte,]byte,]byte,]byte,]byte,]byte,]byte ]byte = ]byte+1 --^ db 36,36,36,36 *------------------------------- * OffsetTable * * Index: Same as ByteTable * Yields: Offset (0-6) *------------------------------- ds OffsetTable-* lup 36 db 0,1,2,3,4,5,6 --^ db 0,1,2,3 *------------------------------- * BlockTable * * Index: Screen X-coord (0 to 255) * Yields: Block # (-5 to 14) *------------------------------- ds BlockTable-* ]byte = -5 db ]byte,]byte lup 18 ]byte = ]byte+1 db ]byte,]byte,]byte,]byte,]byte,]byte,]byte db ]byte,]byte,]byte,]byte,]byte,]byte,]byte --^ ]byte = ]byte+1 db ]byte,]byte *------------------------------- * PixelTable * * Index: Same as BlockTable * Yields: Pixel # within block (0 to 13) *------------------------------- ds PixelTable-* db 12,13 lup 18 db 0,1,2,3,4,5,6,7,8,9,10,11,12,13 --^ db 0,1 *------------------------------- * Mult10 *------------------------------- ds Mult10-* ]byte = 0 lup 16 db ]byte ]byte = ]byte+10 --^ *------------------------------- * Mult7 *------------------------------- ds Mult7-* ]byte = 0 lup 16 db ]byte ]byte = ]byte+7 --^ *------------------------------- * Mult30 *------------------------------- ds Mult30-* ]word = 0 lup 32 dw ]word ]word = ]word+30 --^ *------------------------------- * BlockEdge * * Index: Block X (-5 to 14) + 5 * Yields: Screen X-coord of left edge of block *------------------------------- ds BlockEdge-* ]byte = -12 lup 20 db ]byte ]byte = ]byte+14 --^ *------------------------------- * BlockTop, BlockBot, FloorY * * Index: Block Y (-1 to 3) + 1 ds BlockTop-* db ScrnBot+1-Blox4 db ScrnBot+1-Blox3 db ScrnBot+1-Blox2 db ScrnBot+1-Blox1 db ScrnBot+1 *------------------------------- ds BlockBot-* db ScrnBot-Blox3 db ScrnBot-Blox2 db ScrnBot-Blox1 db ScrnBot db ScrnBot+Blox1 *------------------------------- ds FloorY-* db ScrnBot-Blox3-VertDist db ScrnBot-Blox2-VertDist db ScrnBot-Blox1-VertDist db ScrnBot-VertDist db ScrnBot+Blox1-VertDist *------------------------------- ds BlockAy-* db ScrnBot-Blox3-DHeight db ScrnBot-Blox2-DHeight db ScrnBot-Blox1-DHeight db ScrnBot-DHeight db ScrnBot+Blox1-DHeight *------------------------------- lst eof ds 1 usr $a9,3,$000,*-org lst off \ No newline at end of file +* tables +org = $e00 + tr on + lst off +*------------------------------- +* +* PRINCE OF PERSIA +* Copyright 1989 Jordan Mechner +* +*------------------------------- + dum org + +ByteTable ds $100 +OffsetTable ds $100 +BlockTable ds $100 +PixelTable ds $100 +Mult10 ds $10 +Mult7 ds $10 +Mult30 ds $40 + +BlockEdge ds 20 +BlockTop ds 5 +BlockBot ds 5 +FloorY ds 5 +BlockAy ds 5 + + dend +*------------------------------- + org org +*------------------------------- +ScrnLeft = 58 +ScrnTop = 0 +ScrnBot = 191 + +VertDist = 10 ;from bottom of block to center plane +BlockHeight = 63 +DHeight = 3 ;floorpiece thickness + +Blox1 = BlockHeight +Blox2 = 2*BlockHeight +Blox3 = 3*BlockHeight +Blox4 = 4*BlockHeight + +*------------------------------- +* ByteTable +* +* Index: Real screen X-coord (0-255) +* Yields: Byte # (0-36) +*------------------------------- + + ds ByteTable-* + +]byte = 0 + lup 36 + db ]byte,]byte,]byte,]byte,]byte,]byte,]byte +]byte = ]byte+1 + --^ + db 36,36,36,36 + +*------------------------------- +* OffsetTable +* +* Index: Same as ByteTable +* Yields: Offset (0-6) +*------------------------------- + ds OffsetTable-* + + lup 36 + db 0,1,2,3,4,5,6 + --^ + db 0,1,2,3 + +*------------------------------- +* BlockTable +* +* Index: Screen X-coord (0 to 255) +* Yields: Block # (-5 to 14) +*------------------------------- + ds BlockTable-* + +]byte = -5 + db ]byte,]byte + + lup 18 +]byte = ]byte+1 + db ]byte,]byte,]byte,]byte,]byte,]byte,]byte + db ]byte,]byte,]byte,]byte,]byte,]byte,]byte + --^ + +]byte = ]byte+1 + db ]byte,]byte + +*------------------------------- +* PixelTable +* +* Index: Same as BlockTable +* Yields: Pixel # within block (0 to 13) +*------------------------------- + ds PixelTable-* + + db 12,13 + + lup 18 + db 0,1,2,3,4,5,6,7,8,9,10,11,12,13 + --^ + + db 0,1 + +*------------------------------- +* Mult10 +*------------------------------- + ds Mult10-* + +]byte = 0 + lup 16 + db ]byte +]byte = ]byte+10 + --^ + +*------------------------------- +* Mult7 +*------------------------------- + ds Mult7-* + +]byte = 0 + lup 16 + db ]byte +]byte = ]byte+7 + --^ + +*------------------------------- +* Mult30 +*------------------------------- + ds Mult30-* + +]word = 0 + lup 32 + dw ]word +]word = ]word+30 + --^ + +*------------------------------- +* BlockEdge +* +* Index: Block X (-5 to 14) + 5 +* Yields: Screen X-coord of left edge of block +*------------------------------- + ds BlockEdge-* + +]byte = -12 + lup 20 + db ]byte +]byte = ]byte+14 + --^ + +*------------------------------- +* BlockTop, BlockBot, FloorY +* +* Index: Block Y (-1 to 3) + 1 + + ds BlockTop-* + + db ScrnBot+1-Blox4 + db ScrnBot+1-Blox3 + db ScrnBot+1-Blox2 + db ScrnBot+1-Blox1 + db ScrnBot+1 + +*------------------------------- + ds BlockBot-* + + db ScrnBot-Blox3 + db ScrnBot-Blox2 + db ScrnBot-Blox1 + db ScrnBot + db ScrnBot+Blox1 + +*------------------------------- + ds FloorY-* + + db ScrnBot-Blox3-VertDist + db ScrnBot-Blox2-VertDist + db ScrnBot-Blox1-VertDist + db ScrnBot-VertDist + db ScrnBot+Blox1-VertDist + +*------------------------------- + ds BlockAy-* + + db ScrnBot-Blox3-DHeight + db ScrnBot-Blox2-DHeight + db ScrnBot-Blox1-DHeight + db ScrnBot-DHeight + db ScrnBot+Blox1-DHeight + +*------------------------------- + lst +eof ds 1 + usr $a9,3,$000,*-org + lst off diff --git a/01 POP Source/Source/TOPCTRL.S b/01 POP Source/Source/TOPCTRL.S index b52a71c..a708d9e 100755 --- a/01 POP Source/Source/TOPCTRL.S +++ b/01 POP Source/Source/TOPCTRL.S @@ -1 +1,1740 @@ -* topctrl org = $2000 EditorDisk = 0 FinalDisk = 1 DemoDisk = 0 ThreeFive = 1 ;3.5" disk? tr on lst off *------------------------------- * * PRINCE OF PERSIA * Copyright 1989 Jordan Mechner * *------------------------------- org org jmp START jmp RESTART jmp STARTRESUME jmp INITSYSTEM jmp showpage jmp showpage jmp GOATTRACT *------------------------------- lst put eq lst put gameeq lst put seqdata lst put movedata lst put soundnames lst off *------------------------------- * 18-sector ID bytes POPside1 = $a9 POPside2 = $ad FirstSideB = 3 ;1st level on Side B LastSideB = 14 ;& last *------------------------------- * Soft switches ALTZPon = $c009 ALTZPoff = $c008 RAMWRTaux = $c005 RAMWRTmain = $c004 RAMRDaux = $c003 RAMRDmain = $c002 TEXTon = $c051 PAGE2off = $c054 kresurrect = "R" *------------------------------- * Misc. changeable parameters initmaxstr = 3 BTLtimer = 20 ;back to life wtlflash = 15 ;weightless mousetimer = 150 *------------------------------- * message #s LevelMsg = 1 ContMsg = 2 TimeMsg = 3 leveltimer = 20 ;level message timer contflash = 95 contoff = 15 deadenough = 4 *------------------------------- * Mirror location mirlevel = 4 mirscrn = 4 mirx = 4 miry = 0 *------------------------------- * * Start a new game * * In: A = level # (0 for demo, 1 for game) * *------------------------------- START sta ALTZPon jsr StartGame jmp RESTART *------------------------------- * * Resume saved game * *------------------------------- STARTRESUME sta ALTZPon lda #4 ;arbitrary value >1 jsr StartGame jmp ResumeGame *------------------------------- * * Initialize system (Called from MASTER upon bootup) * *------------------------------- INITSYSTEM sta ALTZPon jsr setcenter ;Center joystick jsr setfastaux ;bgtable in auxmem lda #FinalDisk!1 sta develment jsr initgame ldx #0 txa :loop sta $0,x inx bne :loop sta ALTZPoff rts *------------------------------- * * Start a game * * In: A = level # (0 for demo, 1 for new game, >1 for * resumed game) * *------------------------------- StartGame sta level sta NextLevel cmp #1 bne :notfirst lda #s_Danger ldx #25 jsr cuesong ;Cue "Danger" theme if level 1 :notfirst lda #initmaxstr sta origstrength ;set initial strength jmp initgame *------------------------------- * * Resume saved game * *------------------------------- ResumeGame do DemoDisk rts else jsr flipdisk ;Ask player to flip disk lda #POPside2 sta BBundID ;& expect side 2 from now on :cont jsr loadgame ;Load saved-game info from disk lda SavLevel ;Has a game been saved? bpl :ok ;Yes * No game saved--start new game instead jsr flipdisk lda #POPside1 sta BBundID lda #1 sta level sta NextLevel jmp RESTART * Restore strength & timer :ok lda SavStrength sta origstrength lda SavTimer+1 sta FrameCount+1 lda SavTimer sta FrameCount lda SavNextMsg sta NextTimeMsg * & resume from beginning of level lda #1 sta timerequest ;show time remaining lda #$80 sta yellowflag ;pass copy prot. test lda SavLevel sta level sta NextLevel jmp RESTART fin *------------------------------- * * Initialize vars before starting game * *------------------------------- initgame lda #0 sta blackflag sta redrawflg sta inmenu sta inbuilder sta recheck0 sta SINGSTEP sta ManCtrl sta vibes sta invert sta milestone sta timerequest sta FrameCount sta FrameCount+1 sta NextTimeMsg lda #$ff sta MinLeft sta SecLeft lda #1 ;no delay sta SPEED rts *------------------------------- * * Restart current level * *------------------------------- RESTART sta ALTZPon sta $c010 ;clr kbd strobe do EditorDisk jsr reloadblue else lda #" " jsr lrcls jsr vblank lda PAGE2off lda TEXTon ldx level jsr LoadLevelX ;load blueprint & image sets from disk fin jsr setinitials ;Set initial states as specified in blueprint jsr initialguards ;& guards * Zero a lot of vars & tables lda #0 sta SINGSTEP sta vibes sta AMtimer sta VisScrn sta exitopen sta lightning sta mergetimer sta numtrans sta nummob sta EnemyAlert sta createshad sta stunned sta heroic sta ChgKidStr sta OppStrength ;no opponent sta msgtimer sta PreRecPtr sta PlayCount ldx SongCue cpx #s_Danger beq :1st sta SongCue :1st jsr zerosound jsr zeropeels jsr initCDbuf ;initialize collision detection buffers jsr initinput lda #1 sta gotsword lda #-1 sta cutorder lda #2 sta ShadID ;default opponent is guard lda #86 sta ShadFace jsr startkid do EditorDisk else lda level cmp #1 bne :gotswd lda #0 sta gotsword ;Start Level 1 w/o sword :gotswd fin lda level beq :nomsg cmp #14 beq :nomsg ;don't announce level 0 or 14 cmp #13 bne :1 lda skipmessage beq :1 lda #0 sta skipmessage beq :nomsg ;skip level 13 message 1st time :1 lda #LevelMsg sta message lda #leveltimer sta msgtimer :nomsg jsr entrance ;entrance slams shut jsr FirstFrame ;Generate & display first frame jmp MainLoop *------------------------------- * * Main loop * *------------------------------- MainLoop jsr rnd lda #0 sta ChgKidStr sta ChgOppStr jsr strobe ;Strobe kbd & jstk jsr demokeys bpl :4 lda #1 jmp START ;During demo, press any key to play :4 jsr misctimers jsr NextFrame ;Determine what next frame should look like jsr flashon jsr FrameAdv ;Draw next frame & show it jsr playback ;Play sounds jsr zerosound ;& zero sound table jsr flashoff jsr songcues ;Play music lda NextLevel cmp level beq MainLoop ;Continue until we change levels jsr yellowcheck ;copy protect! jmp LoadNextLevel *------------------------------- * * Load next level * * In: NextLevel = # of next level * level = # of current level * * Out: level = NextLevel * *------------------------------- LoadNextLevel lda NextLevel cmp #14 beq LoadNext1 lda #1 sta timerequest ;show time remaining LoadNext1 lda MaxKidStr sta origstrength ;save new strength level lda #0 sta milestone do EditorDisk lda level sta NextLevel jmp RESTART fin * NextLevel must be in range 1 - LastSideB lda NextLevel cmp #LastSideB+1 bcs :illegal cmp #1 bcs :2 :illegal lda level ;Illegal value--restart current level sta NextLevel jmp RESTART * Load from correct side of disk :2 ldx #POPside2 cmp #FirstSideB bcs :1 ldx #POPside1 :1 cpx BBundID ;do we need to flip disk? beq :ok ;no stx BBundID ;yes jsr flipdisk :ok lda NextLevel sta level ;set new level cmp #2 beq :cut1 cmp #4 beq :cut2 cmp #6 beq :cut3 cmp #8 beq :cut8 cmp #9 beq :cut4 cmp #12 beq :cut5 ;Princess cuts before certain levels :cont jmp RESTART ;Start new level * Princess cuts before certain levels :cut1 lda #1 ]pcut pha :repeat jsr cutprincess ;cut to princess's room... jsr setrecheck0 jsr recheckyel ;if wrong-disk error, recheck track 0 bne :repeat ;& repeat pla jsr playcut ;& play cut #1 jmp :cont :cut2 lda #2 bne ]pcut :cut3 lda #3 bne ]pcut :cut4 lda #4 bne ]pcut :cut5 lda #5 bne ]pcut :cut8 lda #8 bne ]pcut *------------------------------- * * N E X T F R A M E * * Determine what next frame should look like * * In: All data reflects last (currently displayed) frame. * *------------------------------- NextFrame jsr animmobs ;Update mobile objects (MOBs) jsr animtrans ;Update transitional objects (TROBs) jsr bonesrise ;Bring skeleton to life? jsr checkalert ;Determine EnemyAlert value jsr DoKid ;Update kid jsr DoShad ;Update shadowman (or other opponent) jsr checkstrike jsr checkstab ;Check for sword strikes :1 jsr addsfx ;Add additional sound fx jsr chgmeters ;Change strength meters jsr cutcheck ;Has kid moved offscreen? jsr PrepCut ;If so, prepare to cut to new screen jsr cutguard ;If guard has fallen offscreen, vanish him do EditorDisk rts fin * Level 0 (Demo): When kid exits screen 24, end demo lda level bne :no0 lda KidScrn cmp #24 bne :cont jmp GOATTRACT * Level 6: When kid falls off screen 1, cut to next level :no0 do DemoDisk else lda level cmp #6 bne :no6 lda KidScrn cmp #1 bne :cont lda KidY cmp #20 bcs :cont lda #-1 sta KidY inc NextLevel jmp :cont * Level 12: When kid exits screen 23, cut to next level :no6 cmp #12 bne :cont lda KidScrn cmp #23 bne :cont inc NextLevel lda #1 sta skipmessage ;but don't announce level # jmp LoadNext1 ;or show time fin * Continue... :cont lda level cmp #14 bcs :stopped cmp #13 bcc :ticking lda exitopen bne :stopped ;Timer stops when you kill Vizier on level 13 :ticking jsr keeptime :stopped jsr showtime ;if timerequest <> 0 lda level cmp #13 bcs :safe ;You have one chance to finish Level 13 ;after time runs out lda MinLeft ora SecLeft bne :safe jmp YouLose ;time's up--you lose :safe ]rts rts *------------------------------- * * F R A M E A D V A N C E * * Draw new frame (on hidden hi-res page) & show it * *------------------------------- FrameAdv lda cutplan ;set by PrepCut bne :cut jsr DoFast jmp PageFlip ;Update current screen... :cut jmp DoCleanCut ;or draw new screen from scratch *------------------------------- * * F I R S T F R A M E * * Generate & display first frame * *------------------------------- FirstFrame lda KidScrn sta cutscrn jsr PrepCut jmp DoCleanCut *------------------------------- * * D O K I D * * Update kid * *------------------------------- DoKid jsr LoadKidwOp ;Load kid as character (w/opponent) jsr rereadblocks jsr unholy ;If shadowman dies, kid dies jsr ctrlplayer ;Detect & act on commands from player lda invert beq :3 lda CharLife bmi :3 lda #2 sta redrawflg lda #0 sta invert jmp inverty ;Screen flips back rightside up when you're dead :3 jsr wtlessflash lda CharScrn beq :skip ;Skip all this if kid is on null screen: jsr animchar ;Get next frame from sequence table jsr gravity ;Adjust Y-velocity jsr addfall ;Add falling velocity jsr setupchar jsr rereadblocks jsr getedges jsr firstguard ;Check for collision w/guard jsr checkbarr ;Check for collisions w/vertical barriers jsr collisions ;React to collisions detected above jsr checkgate ;Knocked to side by closing gate? jsr checkfloor ;Is there floor underfoot? If not, fall jsr checkpress ;Is kid stepping on a pressure plate? ;If so, add pressplate (& whatever it ;triggers) to trans list. jsr checkspikes ;Trigger spikes? jsr checkimpale ;impaled by spikes? jsr checkslice ;sliced by slicer? :1 jsr shakeloose ;shake loose floors :skip jsr SaveKid ;Save all changes to char data ]rts rts *------------------------------- * * D O S H A D * * Update shadowman (or other opponent) * *------------------------------- DoShad lda ShadFace cmp #86 beq ]rts ;"no character" code jsr LoadShadwOp jsr rereadblocks jsr unholy jsr ShadCtrl ;Opponent control module lda CharScrn cmp VisScrn bne :os jsr animchar lda CharX cmp #ScrnLeft-14 bcc :os cmp #ScrnRight+14 bcs :os ;Skip all this if char is offscreen jsr gravity jsr addfall jsr setupchar jsr rereadblocks jsr getedges jsr enemycoll jsr checkfloor jsr checkpress jsr checkspikes jsr checkimpale jsr checkslice2 :os jmp SaveShad *------------------------------- * * Add all visible characters to object table * *------------------------------- addchars jsr :reflection jsr :shadowman jsr :kid jsr checkmeters ]rts rts *------------------------------- * Draw kid's reflection in mirror :reflection jmp reflection *------------------------------- * Draw shadowman or other opponent :shadowman lda ShadFace cmp #86 ;Is there a shadowman? beq ]rts ;no lda ShadScrn cmp VisScrn ;Is he visible? bne ]rts ;no jsr setupshad ;Add shadowman to object table lda ChgOppStr bpl :s1 jsr setupcomix ;Add impact star if he's been hurt :s1 jmp setupsword ;Add sword *------------------------------- * Draw kid :kid lda KidScrn beq ]rts cmp VisScrn bne ]rts jsr setupkid ;Add kid to obj table lda ChgKidStr bpl :s2 jsr setupcomix ;Add impact star :s2 jmp setupsword ;Add sword *------------------------------- * * S E T U P K I D * * Add kid to object table * Crop edges, index char, mark fredbuf/floorbuf * *------------------------------- setupkid jsr LoadKid jsr rereadblocks lda CharPosn bne :cont ;Delay loop if CharPosn = 0 lda #25 jmp pause :cont jsr setupchar jsr unevenfloor jsr getedges jsr indexchar jsr quickfg jsr quickfloor jsr cropchar jmp addkidobj ;add kid to obj table *------------------------------- * * S E T U P S H A D * * Add shadowman to obj table * *------------------------------- setupshad jsr LoadShad jsr rereadblocks jsr setupchar jsr unevenfloor jsr getedges jsr indexchar jsr quickfg jsr quickfloor jsr cropchar lda CharID cmp #1 ;Shadowman? bne :1 ;no lda level cmp #mirlevel bne :2 lda CharScrn cmp #mirscrn bne :2 lda #mirx ;Clip shadman at L as he jumps out of mirror asl asl clc adc #1 sta FCharCL :2 jmp addshadobj :1 jmp addguardobj *------------------------------- * * Cut to new screen * * DoQuickCut: Show bg before adding characters * DoCleanCut: Show frame only when complete * *------------------------------- UseQuick = 0 do UseQuick DoQuickCut jsr fastspeed ;IIGS lda #0 sta PAGE jsr drawbg ;draw bg on p1 jsr PageFlip jsr copyscrn ;copy bg to p2 jsr DoFast ;add chars jsr PageFlip ;show complete frame jmp normspeed else DoCleanCut jsr fastspeed ;IIGS lda #$20 sta PAGE jsr drawbg ;draw bg on p2 lda #0 sta PAGE jsr copyscrn ;copy bg to p1 jsr DoFast ;add chars ;jsr vblank2 jsr PageFlip jmp normspeed fin *------------------------------- * * D R A W B G * * Clear screen & draw background (on hidden hi-res page) * Show black lo-res screen to cover transition * *------------------------------- drawbg lda #0 sta cutplan lda #2 sta CUTTIMER ;min # of frames between cuts lda #" " jsr lrclse jsr vblank lda PAGE2off lda TEXTon jsr DoSure ;draw b.g. w/o chars jmp markmeters ;mark strength meters *------------------------------- * * D O S U R E * * Clear screen and redraw entire b.g. from scratch * *------------------------------- DoSure lda VisScrn sta SCRNUM jsr zerolsts ;zero image lists jsr sure ;Assemble image lists jsr zeropeels ;Zero peel buffers jsr zerored ;and redraw buffers ;(for next DoFast call) jmp drawall ;Dump contents of image lists to screen *------------------------------- * * D O F A S T * * Do a fast screen update * (Redraw objects and as little of b.g. as possible) * *------------------------------- DoFast jsr zerolsts ;zero image lists lda VisScrn sta SCRNUM jsr develpatch jsr addmobs ;Add MOBS to object list jsr addchars ;Add characters to object list ;(incl. strength meters) jsr fast ;Assemble image lists (including objects ;from obj list and necessary portions of bg) jsr dispmsg ;Superimpose message (if any) :1 jmp drawall ;Dump contents of image lists to screen ]rts rts *------------------------------- * * Lightning flashes * *------------------------------- flashon lda lightning beq :1 lda lightcolor bne :2 :1 lda ChgKidStr bpl ]rts lda #$11 ;Flash red if kid's been hurt :2 jmp doflashon flashoff lda lightning beq :1 dec lightning bpl :2 :1 lda ChgKidStr bpl ]rts :2 jmp doflashoff *------------------------------- * * Initialize collision detection buffers * *------------------------------- initCDbuf ldx #9 lda #$ff :zloop sta SNlastframe,x sta SNthisframe,x sta SNbelow,x sta SNabove,x dex bpl :zloop sta BlockYlast ]rts rts *------------------------------- * * Prepare to cut? * * In: VisScrn = current screen * cutscrn = screen we want to be on * * If cutscrn <> VisScrn, make necessary preparations * & return cutplan = 1 * *------------------------------- PrepCut lda cutscrn beq ]rts ;never cut to screen 0 cmp VisScrn beq ]rts ;If cutscrn = VisScrn, we don't need to cut lda cutscrn sta VisScrn cmp #5 bne :1 lda level cmp #14 bne :1 jmp YouWin ;Level 14, screen 5 is princess's room--you win! :1 lda #1 sta cutplan jsr getscrns ;Get neighboring screen #s jsr LoadKid jsr addslicers jsr addtorches jsr crumble ;Activate slicers, torches, etc. jmp addguard ;Add guard (if any) *------------------------------- * * Time's up--you lose * *------------------------------- YouLose jsr cutprincess ;cut to princess's room... lda #6 jsr playcut ;& play cut #6 jmp GOATTRACT ;go to title sequence *------------------------------- * * You win * *------------------------------- YouWin jsr cutprincess lda #7 jsr playcut ;Play cut #7 jmp epilog ;Play epilog (& hang) *------------------------------- * * Control player * * In/out: Char vars * *------------------------------- ctrlplayer jsr kill0 ;If char is on screen 0, kill him off jsr PlayerCtrl ;Control player lda CharLife bmi ]rts ;If char is still alive, return * When player dies, CharLife is set to 0. * Inc CharLife until = #deadenough; then put up message :dead lda CharPosn jsr cold? bne ]rts ;wait till char has stopped moving lda CharLife bne :inc jsr deathsong ;cue death music :inc lda CharLife cmp #deadenough bcs :deadenough inc CharLife ]rts rts :deadenough lda level beq :gameover ;Your death ends demo lda SongCue bne ]rts ;wait for song to finish before putting up msg lda MinLeft ora SecLeft bne :timeleft jmp YouLose ;if you die with time = 0, you lose * Otherwise: "Press Button to Continue" :timeleft lda message cmp #ContMsg bne :1 lda msgtimer bne :ok :1 lda #ContMsg sta message lda #255 sta msgtimer ;Put up continue message :ok cmp #1 beq :gameover ;End game when msgtimer = 1 do FinalDisk else lda develment beq :nodevel lda keypress cmp #kresurrect beq :raise ;TEMP! :nodevel fin lda BTN0 ora BTN1 bpl ]rts jmp RESTART ;Button press restarts level :gameover do EditorDisk jmp RESTART else jmp GOATTRACT fin * Raise kid from the dead (TEMP!) do FinalDisk else :raise lda #0 sta msgtimer sta SongCue lda #BTLtimer sta backtolife jsr LoadKid lda MaxKidStr sta ChgKidStr lda #stand jsr jumpseq jmp startkid1 fin *------------------------------- * * Play death song * *------------------------------- deathsong lda ShadID cmp #1 beq :shad ;if opponent was shadowman lda heroic ;was kid engaged in battle at time of death? bne :1 ;yes--"heroic death" music lda #s_Accid ;no--"accidental death" music bne :2 :shad lda #s_Shadow bne :2 :1 lda #s_Heroic :2 ldx #255 jmp cuesong ]rts rts *------------------------------- * * If char is on screen 0, kill him off * *------------------------------- kill0 lda CharLife bpl ]rts lda CharScrn bne ]rts lda #Splat jsr addsound lda #100 jsr decstr lda #0 sta msgtimer sta CharLife lda #185 sta CharPosn ]rts rts *------------------------------- * * Go to attract mode * *------------------------------- GOATTRACT do DemoDisk else lda BBundID cmp #POPside1 ;does he need to flip disk? beq :ok ;no do ThreeFive else lda BGset1 bpl :flip ldx #4 jsr LoadLevelX ;get "FLIP DISK" msg into memory fin :flip jsr flipdisk ;ask him to flip disk fin lda #POPside1 sta BBundID :ok jmp attractmode *------------------------------- * * Shake loose floors when character jumps * *------------------------------- shakeloose lda jarabove bmi :jarbelow bne :jarabove ]rts rts :jarbelow lda #0 sta jarabove lda CharBlockY jmp shakem ;shake every loose floorboard on level :jarabove lda #0 sta jarabove lda CharBlockY sec sbc #1 jmp shakem *------------------------------- * * If strength meters have changed, mark affected * blocks for redraw * *------------------------------- checkmeters lda ChgKidStr beq :1 jsr MarkKidMeter :1 lda ChgOppStr beq ]rts jmp MarkOppMeter *------------------------------- * * Change strength meters as specified * *------------------------------- chgmeters lda level cmp #12 bne :cont lda OpID ora CharID cmp #1 ;kid vs. shadowman? bne :cont ;yes lda ChgKidStr bpl :1 sta ChgOppStr bne :cont :1 lda ChgOppStr bpl :cont sta ChgKidStr * Kid's meter :cont lda KidStrength clc adc ChgKidStr cmp MaxKidStr beq :ok1 bcs :opp :ok1 sta KidStrength * Opponent's meter :opp lda OppStrength clc adc ChgOppStr cmp MaxOppStr beq :ok2 bcs ]rts :ok2 sta OppStrength ]rts rts *------------------------------- * * Slam player's entrance shut (add it to trans list) * *------------------------------- entrance lda KidScrn jsr calcblue ldy #29 :loop lda (BlueType),y and #idmask cmp #exit bne :cont ;find player's entrance lda KidScrn jmp closeexit ;& return :cont dey bpl :loop ]rts rts *------------------------------- * * Play song cues * * In: SongCue (0 = none, non0 = song #) * SongCount * *------------------------------- songcues do EditorDisk rts fin ldx SongCue beq ]rts lda level beq ]rts ;no music in demo lda SongCount bne :cont lda #0 sta SongCue ;when SongCount reaches 0, forget it ]rts rts :cont dec SongCount lda KidPosn bne :1 lda NextLevel cmp level beq ]rts ;Play only one song once kid has reached stairs :1 lda KidPosn jsr static? bne ]rts lda ShadFace cmp #86 beq :ok lda ShadScrn cmp VisScrn bne :ok lda ShadPosn jsr static? bne ]rts :ok lda trobcount ;(set by animtrans if there are any bne ]rts ;slicers or other fast-moving objects ;that it wouldn't look good to freeze) lda nummob bne ]rts lda lightning bne ]rts ;wait for no MOBs and no lightning lda mergetimer bmi :ok2 bne ]rts lda ChgKidStr ora ChgOppStr bne ]rts ;& no impact stars :ok2 * Prepare for minimal animation lda PAGE eor #$20 sta PAGE jsr listtorches * Play song lda SongCue jsr minit sta $c010 ;clr kbd :loop jsr burn jsr musickeys jsr mplay cmp #0 bne :loop :done lda #0 sta SongCue :rtn lda PAGE eor #$20 sta PAGE jmp clearjoy *------------------------------- * * Add additional sound fx * *------------------------------- addsfx lda #167 ;blocked strike cmp KidPosn ;if char is striking... bne :1 lda #SwordClash1 bne :clash :1 cmp ShadPosn bne :2 lda #SwordClash2 :clash jmp addsound :2 ]rts rts *------------------------------- * * Display message ("Press button to continue" or "Level #" * or "# minutes left") * *------------------------------- dispmsg lda msgtimer beq ]rts dec msgtimer lda KidLife bmi :alive * Kid is dead -- message is "Press button to continue" lda msgtimer cmp #contoff bcc ]rts cmp #contflash bcs :steady and #7 cmp #3 bcs ]rts cmp #2 bne :steady lda soundon bne :2 jsr gtone ;if sound off :2 lda #FlashMsg jsr addsound :steady jmp continuemsg ;Kid is dead--superimpose continue msg * Kid is alive -- message is "Level #" or "# Minutes" :alive lda msgtimer cmp #leveltimer-2 bcs ]rts lda message cmp #LevelMsg bne :1 jmp printlevel :1 cmp #TimeMsg bne ]rts jmp timeleftmsg *------------------------------- * * Display "Turn disk over" and wait for button press * *------------------------------- flipdisk do ThreeFive lda #1 sta purpleflag ;pass copy-protect! rts fin do DemoDisk jmp GOATTRACT else * 1st copy protection check lda redherring eor redherring2 cmp #POPside1 ;passed 1st check? beq :1 lda #POPside1 sta BBundID jmp attractmode * Passed copy protection--continue :1 lda #" " jsr lrcls jsr zerolsts jsr zeropeels lda #1 sta genCLS jsr flipdiskmsg jsr drawall jsr vblank jsr PageFlip lda $c010 ;clr kbd strobe :loop lda $c061 ora $c062 ora $c000 bpl :loop fin * Flip to clr text scrn showtext jsr vblank lda PAGE2off lda TEXTon ]rts rts *------------------------------- * * Is character moving? * * In: A = CharPosn * Out: 0 if static, 1 if moving * *------------------------------- static? cmp #0 beq ]ok cmp #15 ;stand beq ]ok cmp #229 ;brandish sword beq ]ok cmp #109 ;crouching beq ]ok cmp #171 ;en garde beq ]ok cmp #166 ;alert stand (for gd.) beq ]ok cold? cmp #185 ;dead beq ]ok cmp #177 ;impaled beq ]ok cmp #178 ;halves beq ]ok lda #1 rts ]ok lda #0 ]rts rts *------------------------------- * * Clear all jstk flags * *------------------------------- clearjoy jsr LoadSelect lda #0 sta clrF sta clrB sta clrU sta clrD jmp SaveSelect *------------------------------- * * Misc. timers (Call every cycle) * *------------------------------- misctimers lda mergetimer beq :3 bmi :3 dec mergetimer bne :3 dec mergetimer ;goes from 1 to -1 :3 * Level 8: When you've spent a certain amount of time on * screen 16 once exit is open, mouse rescues you lda level cmp #8 ;mouse level bne :12 lda CharScrn cmp #16 bne :12 lda exitopen beq :12 cmp #mousetimer bcc :11 bne :12 :10 jsr mouserescue :11 inc exitopen :12 ]rts rts *------------------------------- * * Screen flashes towards end of weightlessness period * *------------------------------- wtlessflash lda weightless beq ]rts ldx #0 sec sbc #1 sta weightless beq :3 ldx #$ff cmp #wtlflash bcs :3 lda vibes eor #$ff tax :3 stx vibes ;Screen flashes as weightlessness ends ]rts rts *------------------------------- * yellow copy protection * (call right before 1st princess cut) * In: A = next level *------------------------------- yellowcheck cmp #2 bne ]rts jsr showtext ldx #10 jmp yellow ;in gamebg ;sets yellowflag ($7c) hibit *------------------------------- * * Temp development patch for screen redraw * (also used for invert Y) * *------------------------------- develpatch do 0 lda blackflag ;blackout? beq :1 lda #1 sta genCLS fin :1 lda redrawflg ;forced redraw? beq ]rts dec redrawflg jsr markmeters jmp sure *------------------------------- lst ds 1 usr $a9,4,$a00,*-org lst off \ No newline at end of file +* topctrl +org = $2000 +EditorDisk = 0 +FinalDisk = 1 +DemoDisk = 0 +ThreeFive = 1 ;3.5" disk? + tr on + lst off +*------------------------------- +* +* PRINCE OF PERSIA +* Copyright 1989 Jordan Mechner +* +*------------------------------- + org org + + jmp START + jmp RESTART + jmp STARTRESUME + jmp INITSYSTEM + jmp showpage + + jmp showpage + jmp GOATTRACT + +*------------------------------- + lst + put eq + lst + put gameeq + lst + put seqdata + lst + put movedata + lst + put soundnames + lst off + +*------------------------------- +* 18-sector ID bytes + +POPside1 = $a9 +POPside2 = $ad + +FirstSideB = 3 ;1st level on Side B +LastSideB = 14 ;& last + +*------------------------------- +* Soft switches + +ALTZPon = $c009 +ALTZPoff = $c008 +RAMWRTaux = $c005 +RAMWRTmain = $c004 +RAMRDaux = $c003 +RAMRDmain = $c002 +TEXTon = $c051 +PAGE2off = $c054 + +kresurrect = "R" + +*------------------------------- +* Misc. changeable parameters + +initmaxstr = 3 + +BTLtimer = 20 ;back to life +wtlflash = 15 ;weightless + +mousetimer = 150 + +*------------------------------- +* message #s + +LevelMsg = 1 +ContMsg = 2 +TimeMsg = 3 + +leveltimer = 20 ;level message timer +contflash = 95 +contoff = 15 +deadenough = 4 + +*------------------------------- +* Mirror location + +mirlevel = 4 +mirscrn = 4 +mirx = 4 +miry = 0 + +*------------------------------- +* +* Start a new game +* +* In: A = level # (0 for demo, 1 for game) +* +*------------------------------- +START + sta ALTZPon + jsr StartGame + jmp RESTART + +*------------------------------- +* +* Resume saved game +* +*------------------------------- +STARTRESUME + sta ALTZPon + lda #4 ;arbitrary value >1 + jsr StartGame + jmp ResumeGame + +*------------------------------- +* +* Initialize system (Called from MASTER upon bootup) +* +*------------------------------- +INITSYSTEM + sta ALTZPon + + jsr setcenter ;Center joystick + + jsr setfastaux ;bgtable in auxmem + + lda #FinalDisk!1 + sta develment + + jsr initgame + + ldx #0 + txa +:loop sta $0,x + inx + bne :loop + + sta ALTZPoff + rts + +*------------------------------- +* +* Start a game +* +* In: A = level # (0 for demo, 1 for new game, >1 for +* resumed game) +* +*------------------------------- +StartGame + sta level + sta NextLevel + + cmp #1 + bne :notfirst + lda #s_Danger + ldx #25 + jsr cuesong ;Cue "Danger" theme if level 1 +:notfirst + + lda #initmaxstr + sta origstrength ;set initial strength + + jmp initgame + +*------------------------------- +* +* Resume saved game +* +*------------------------------- +ResumeGame + do DemoDisk + rts + else + + jsr flipdisk ;Ask player to flip disk + lda #POPside2 + sta BBundID ;& expect side 2 from now on + +:cont jsr loadgame ;Load saved-game info from disk + + lda SavLevel ;Has a game been saved? + bpl :ok ;Yes + +* No game saved--start new game instead + + jsr flipdisk + lda #POPside1 + sta BBundID + + lda #1 + sta level + sta NextLevel + jmp RESTART + +* Restore strength & timer + +:ok lda SavStrength + sta origstrength + + lda SavTimer+1 + sta FrameCount+1 + lda SavTimer + sta FrameCount + + lda SavNextMsg + sta NextTimeMsg + +* & resume from beginning of level + + lda #1 + sta timerequest ;show time remaining + lda #$80 + sta yellowflag ;pass copy prot. test + lda SavLevel + sta level + sta NextLevel + jmp RESTART + + fin + +*------------------------------- +* +* Initialize vars before starting game +* +*------------------------------- +initgame + lda #0 + sta blackflag + sta redrawflg + sta inmenu + sta inbuilder + sta recheck0 + sta SINGSTEP + sta ManCtrl + sta vibes + sta invert + sta milestone + sta timerequest + sta FrameCount + sta FrameCount+1 + sta NextTimeMsg + + lda #$ff + sta MinLeft + sta SecLeft + + lda #1 ;no delay + sta SPEED + rts + +*------------------------------- +* +* Restart current level +* +*------------------------------- +RESTART + sta ALTZPon + sta $c010 ;clr kbd strobe + + do EditorDisk + jsr reloadblue + else + + lda #" " + jsr lrcls + jsr vblank + lda PAGE2off + lda TEXTon + + ldx level + jsr LoadLevelX ;load blueprint & image sets from disk + fin + + jsr setinitials ;Set initial states as specified in blueprint + + jsr initialguards ;& guards + +* Zero a lot of vars & tables + + lda #0 + sta SINGSTEP + sta vibes + sta AMtimer + sta VisScrn + sta exitopen + sta lightning + sta mergetimer + sta numtrans + sta nummob + sta EnemyAlert + sta createshad + sta stunned + sta heroic + sta ChgKidStr + sta OppStrength ;no opponent + sta msgtimer + sta PreRecPtr + sta PlayCount + + ldx SongCue + cpx #s_Danger + beq :1st + sta SongCue +:1st + + jsr zerosound + + jsr zeropeels + + jsr initCDbuf ;initialize collision detection buffers + + jsr initinput + + lda #1 + sta gotsword + + lda #-1 + sta cutorder + + lda #2 + sta ShadID ;default opponent is guard + lda #86 + sta ShadFace + + jsr startkid + + do EditorDisk + else + + lda level + cmp #1 + bne :gotswd + lda #0 + sta gotsword ;Start Level 1 w/o sword +:gotswd + fin + + lda level + beq :nomsg + cmp #14 + beq :nomsg ;don't announce level 0 or 14 + cmp #13 + bne :1 + lda skipmessage + beq :1 + lda #0 + sta skipmessage + beq :nomsg ;skip level 13 message 1st time +:1 lda #LevelMsg + sta message + lda #leveltimer + sta msgtimer +:nomsg + + jsr entrance ;entrance slams shut + + jsr FirstFrame ;Generate & display first frame + + jmp MainLoop + +*------------------------------- +* +* Main loop +* +*------------------------------- +MainLoop + jsr rnd + + lda #0 + sta ChgKidStr + sta ChgOppStr + + jsr strobe ;Strobe kbd & jstk + + jsr demokeys + bpl :4 + lda #1 + jmp START ;During demo, press any key to play +:4 + jsr misctimers + + jsr NextFrame ;Determine what next frame should look like + + jsr flashon + + jsr FrameAdv ;Draw next frame & show it + + jsr playback ;Play sounds + jsr zerosound ;& zero sound table + + jsr flashoff + + jsr songcues ;Play music + + lda NextLevel + cmp level + beq MainLoop ;Continue until we change levels + + jsr yellowcheck ;copy protect! + + jmp LoadNextLevel + +*------------------------------- +* +* Load next level +* +* In: NextLevel = # of next level +* level = # of current level +* +* Out: level = NextLevel +* +*------------------------------- +LoadNextLevel + lda NextLevel + cmp #14 + beq LoadNext1 + lda #1 + sta timerequest ;show time remaining + +LoadNext1 + lda MaxKidStr + sta origstrength ;save new strength level + lda #0 + sta milestone + + do EditorDisk + lda level + sta NextLevel + jmp RESTART + fin + +* NextLevel must be in range 1 - LastSideB + + lda NextLevel + cmp #LastSideB+1 + bcs :illegal + cmp #1 + bcs :2 +:illegal lda level ;Illegal value--restart current level + sta NextLevel + jmp RESTART + +* Load from correct side of disk + +:2 ldx #POPside2 + cmp #FirstSideB + bcs :1 + ldx #POPside1 +:1 cpx BBundID ;do we need to flip disk? + beq :ok ;no + stx BBundID ;yes + jsr flipdisk + +:ok lda NextLevel + sta level ;set new level + cmp #2 + beq :cut1 + cmp #4 + beq :cut2 + cmp #6 + beq :cut3 + cmp #8 + beq :cut8 + cmp #9 + beq :cut4 + cmp #12 + beq :cut5 ;Princess cuts before certain levels + +:cont jmp RESTART ;Start new level + +* Princess cuts before certain levels + +:cut1 lda #1 +]pcut pha +:repeat jsr cutprincess ;cut to princess's room... + jsr setrecheck0 + jsr recheckyel ;if wrong-disk error, recheck track 0 + bne :repeat ;& repeat + pla + jsr playcut ;& play cut #1 + jmp :cont + +:cut2 lda #2 + bne ]pcut +:cut3 lda #3 + bne ]pcut +:cut4 lda #4 + bne ]pcut +:cut5 lda #5 + bne ]pcut +:cut8 lda #8 + bne ]pcut + +*------------------------------- +* +* N E X T F R A M E +* +* Determine what next frame should look like +* +* In: All data reflects last (currently displayed) frame. +* +*------------------------------- +NextFrame + jsr animmobs ;Update mobile objects (MOBs) + + jsr animtrans ;Update transitional objects (TROBs) + + jsr bonesrise ;Bring skeleton to life? + + jsr checkalert ;Determine EnemyAlert value + + jsr DoKid ;Update kid + + jsr DoShad ;Update shadowman (or other opponent) + + jsr checkstrike + jsr checkstab ;Check for sword strikes +:1 + jsr addsfx ;Add additional sound fx + + jsr chgmeters ;Change strength meters + + jsr cutcheck ;Has kid moved offscreen? + jsr PrepCut ;If so, prepare to cut to new screen + + jsr cutguard ;If guard has fallen offscreen, vanish him + + do EditorDisk + rts + fin + +* Level 0 (Demo): When kid exits screen 24, end demo + + lda level + bne :no0 + lda KidScrn + cmp #24 + bne :cont + jmp GOATTRACT + +* Level 6: When kid falls off screen 1, cut to next level + +:no0 do DemoDisk + else + + lda level + cmp #6 + bne :no6 + lda KidScrn + cmp #1 + bne :cont + lda KidY + cmp #20 + bcs :cont + lda #-1 + sta KidY + inc NextLevel + jmp :cont + +* Level 12: When kid exits screen 23, cut to next level + +:no6 cmp #12 + bne :cont + lda KidScrn + cmp #23 + bne :cont + inc NextLevel + lda #1 + sta skipmessage ;but don't announce level # + jmp LoadNext1 ;or show time + + fin + +* Continue... + +:cont lda level + cmp #14 + bcs :stopped + cmp #13 + bcc :ticking + lda exitopen + bne :stopped ;Timer stops when you kill Vizier on level 13 + +:ticking jsr keeptime + +:stopped jsr showtime ;if timerequest <> 0 + + lda level + cmp #13 + bcs :safe ;You have one chance to finish Level 13 +;after time runs out + lda MinLeft + ora SecLeft + bne :safe + jmp YouLose ;time's up--you lose +:safe +]rts rts + +*------------------------------- +* +* F R A M E A D V A N C E +* +* Draw new frame (on hidden hi-res page) & show it +* +*------------------------------- +FrameAdv + lda cutplan ;set by PrepCut + bne :cut + + jsr DoFast + jmp PageFlip ;Update current screen... + +:cut jmp DoCleanCut ;or draw new screen from scratch + +*------------------------------- +* +* F I R S T F R A M E +* +* Generate & display first frame +* +*------------------------------- +FirstFrame + lda KidScrn + sta cutscrn + + jsr PrepCut + + jmp DoCleanCut + +*------------------------------- +* +* D O K I D +* +* Update kid +* +*------------------------------- +DoKid + jsr LoadKidwOp ;Load kid as character (w/opponent) + + jsr rereadblocks + + jsr unholy ;If shadowman dies, kid dies + + jsr ctrlplayer ;Detect & act on commands from player + + lda invert + beq :3 + lda CharLife + bmi :3 + lda #2 + sta redrawflg + lda #0 + sta invert + jmp inverty ;Screen flips back rightside up when you're dead +:3 + jsr wtlessflash + + lda CharScrn + beq :skip ;Skip all this if kid is on null screen: + + jsr animchar ;Get next frame from sequence table + + jsr gravity ;Adjust Y-velocity + jsr addfall ;Add falling velocity + + jsr setupchar + jsr rereadblocks + jsr getedges + + jsr firstguard ;Check for collision w/guard + + jsr checkbarr ;Check for collisions w/vertical barriers + + jsr collisions ;React to collisions detected above + + jsr checkgate ;Knocked to side by closing gate? + + jsr checkfloor ;Is there floor underfoot? If not, fall + + jsr checkpress ;Is kid stepping on a pressure plate? +;If so, add pressplate (& whatever it +;triggers) to trans list. + + jsr checkspikes ;Trigger spikes? + + jsr checkimpale ;impaled by spikes? + jsr checkslice ;sliced by slicer? +:1 + jsr shakeloose ;shake loose floors + +:skip jsr SaveKid ;Save all changes to char data +]rts rts + +*------------------------------- +* +* D O S H A D +* +* Update shadowman (or other opponent) +* +*------------------------------- +DoShad + lda ShadFace + cmp #86 + beq ]rts ;"no character" code + + jsr LoadShadwOp + jsr rereadblocks + + jsr unholy + + jsr ShadCtrl ;Opponent control module + + lda CharScrn + cmp VisScrn + bne :os + + jsr animchar + + lda CharX + cmp #ScrnLeft-14 + bcc :os + cmp #ScrnRight+14 + bcs :os ;Skip all this if char is offscreen + + jsr gravity + jsr addfall + + jsr setupchar + jsr rereadblocks + jsr getedges + + jsr enemycoll + + jsr checkfloor + jsr checkpress + jsr checkspikes + jsr checkimpale + jsr checkslice2 + +:os jmp SaveShad + +*------------------------------- +* +* Add all visible characters to object table +* +*------------------------------- +addchars + jsr :reflection + jsr :shadowman + jsr :kid + + jsr checkmeters + +]rts rts + +*------------------------------- +* Draw kid's reflection in mirror + +:reflection + jmp reflection + +*------------------------------- +* Draw shadowman or other opponent + +:shadowman + lda ShadFace + cmp #86 ;Is there a shadowman? + beq ]rts ;no + lda ShadScrn + cmp VisScrn ;Is he visible? + bne ]rts ;no + + jsr setupshad ;Add shadowman to object table + + lda ChgOppStr + bpl :s1 + jsr setupcomix ;Add impact star if he's been hurt +:s1 jmp setupsword ;Add sword + +*------------------------------- +* Draw kid + +:kid lda KidScrn + beq ]rts + cmp VisScrn + bne ]rts + + jsr setupkid ;Add kid to obj table + + lda ChgKidStr + bpl :s2 + jsr setupcomix ;Add impact star +:s2 jmp setupsword ;Add sword + +*------------------------------- +* +* S E T U P K I D +* +* Add kid to object table +* Crop edges, index char, mark fredbuf/floorbuf +* +*------------------------------- +setupkid + jsr LoadKid + jsr rereadblocks + + lda CharPosn + bne :cont ;Delay loop if CharPosn = 0 + lda #25 + jmp pause + +:cont jsr setupchar + jsr unevenfloor + + jsr getedges + jsr indexchar + jsr quickfg + jsr quickfloor + jsr cropchar + + jmp addkidobj ;add kid to obj table + +*------------------------------- +* +* S E T U P S H A D +* +* Add shadowman to obj table +* +*------------------------------- +setupshad + jsr LoadShad + jsr rereadblocks + + jsr setupchar + jsr unevenfloor + + jsr getedges + jsr indexchar + jsr quickfg + jsr quickfloor + jsr cropchar + + lda CharID + cmp #1 ;Shadowman? + bne :1 ;no + lda level + cmp #mirlevel + bne :2 + lda CharScrn + cmp #mirscrn + bne :2 + lda #mirx ;Clip shadman at L as he jumps out of mirror + asl + asl + clc + adc #1 + sta FCharCL +:2 jmp addshadobj + +:1 jmp addguardobj + +*------------------------------- +* +* Cut to new screen +* +* DoQuickCut: Show bg before adding characters +* DoCleanCut: Show frame only when complete +* +*------------------------------- +UseQuick = 0 + + do UseQuick + +DoQuickCut + jsr fastspeed ;IIGS + + lda #0 + sta PAGE + jsr drawbg ;draw bg on p1 + + jsr PageFlip + + jsr copyscrn ;copy bg to p2 + jsr DoFast ;add chars + + jsr PageFlip ;show complete frame + jmp normspeed + + else + +DoCleanCut + jsr fastspeed ;IIGS + + lda #$20 + sta PAGE + jsr drawbg ;draw bg on p2 + + lda #0 + sta PAGE + jsr copyscrn ;copy bg to p1 + + jsr DoFast ;add chars + +;jsr vblank2 + jsr PageFlip + jmp normspeed + + fin + +*------------------------------- +* +* D R A W B G +* +* Clear screen & draw background (on hidden hi-res page) +* Show black lo-res screen to cover transition +* +*------------------------------- +drawbg + lda #0 + sta cutplan + + lda #2 + sta CUTTIMER ;min # of frames between cuts + + lda #" " + jsr lrclse + jsr vblank + lda PAGE2off + lda TEXTon + + jsr DoSure ;draw b.g. w/o chars + + jmp markmeters ;mark strength meters + +*------------------------------- +* +* D O S U R E +* +* Clear screen and redraw entire b.g. from scratch +* +*------------------------------- +DoSure + lda VisScrn + sta SCRNUM + + jsr zerolsts ;zero image lists + + jsr sure ;Assemble image lists + + jsr zeropeels ;Zero peel buffers + jsr zerored ;and redraw buffers +;(for next DoFast call) + + jmp drawall ;Dump contents of image lists to screen + +*------------------------------- +* +* D O F A S T +* +* Do a fast screen update +* (Redraw objects and as little of b.g. as possible) +* +*------------------------------- +DoFast + jsr zerolsts ;zero image lists + + lda VisScrn + sta SCRNUM + + jsr develpatch + + jsr addmobs ;Add MOBS to object list + + jsr addchars ;Add characters to object list +;(incl. strength meters) + + jsr fast ;Assemble image lists (including objects +;from obj list and necessary portions of bg) + + jsr dispmsg ;Superimpose message (if any) +:1 + jmp drawall ;Dump contents of image lists to screen +]rts rts + +*------------------------------- +* +* Lightning flashes +* +*------------------------------- +flashon + lda lightning + beq :1 + lda lightcolor + bne :2 +:1 lda ChgKidStr + bpl ]rts + lda #$11 ;Flash red if kid's been hurt +:2 jmp doflashon + +flashoff + lda lightning + beq :1 + dec lightning + bpl :2 + +:1 lda ChgKidStr + bpl ]rts +:2 jmp doflashoff + +*------------------------------- +* +* Initialize collision detection buffers +* +*------------------------------- +initCDbuf + ldx #9 + lda #$ff +:zloop sta SNlastframe,x + sta SNthisframe,x + sta SNbelow,x + sta SNabove,x + dex + bpl :zloop + + sta BlockYlast +]rts rts + +*------------------------------- +* +* Prepare to cut? +* +* In: VisScrn = current screen +* cutscrn = screen we want to be on +* +* If cutscrn <> VisScrn, make necessary preparations +* & return cutplan = 1 +* +*------------------------------- +PrepCut + lda cutscrn + beq ]rts ;never cut to screen 0 + cmp VisScrn + beq ]rts ;If cutscrn = VisScrn, we don't need to cut + + lda cutscrn + sta VisScrn + cmp #5 + bne :1 + lda level + cmp #14 + bne :1 + jmp YouWin ;Level 14, screen 5 is princess's room--you win! + +:1 lda #1 + sta cutplan + + jsr getscrns ;Get neighboring screen #s + + jsr LoadKid + jsr addslicers + jsr addtorches + jsr crumble ;Activate slicers, torches, etc. + + jmp addguard ;Add guard (if any) + +*------------------------------- +* +* Time's up--you lose +* +*------------------------------- +YouLose + jsr cutprincess ;cut to princess's room... + lda #6 + jsr playcut ;& play cut #6 + + jmp GOATTRACT ;go to title sequence + +*------------------------------- +* +* You win +* +*------------------------------- +YouWin jsr cutprincess + lda #7 + jsr playcut ;Play cut #7 + jmp epilog ;Play epilog (& hang) + +*------------------------------- +* +* Control player +* +* In/out: Char vars +* +*------------------------------- +ctrlplayer + jsr kill0 ;If char is on screen 0, kill him off + + jsr PlayerCtrl ;Control player + + lda CharLife + bmi ]rts ;If char is still alive, return + +* When player dies, CharLife is set to 0. +* Inc CharLife until = #deadenough; then put up message + +:dead lda CharPosn + jsr cold? + bne ]rts ;wait till char has stopped moving + + lda CharLife + bne :inc + jsr deathsong ;cue death music + +:inc lda CharLife + cmp #deadenough + bcs :deadenough + inc CharLife +]rts rts + +:deadenough + lda level + beq :gameover ;Your death ends demo + + lda SongCue + bne ]rts ;wait for song to finish before putting up msg + + lda MinLeft + ora SecLeft + bne :timeleft + jmp YouLose ;if you die with time = 0, you lose + +* Otherwise: "Press Button to Continue" + +:timeleft + lda message + cmp #ContMsg + bne :1 + lda msgtimer + bne :ok + +:1 lda #ContMsg + sta message + lda #255 + sta msgtimer ;Put up continue message + +:ok cmp #1 + beq :gameover ;End game when msgtimer = 1 + + do FinalDisk + else + + lda develment + beq :nodevel + lda keypress + cmp #kresurrect + beq :raise ;TEMP! +:nodevel + fin + + lda BTN0 + ora BTN1 + bpl ]rts + jmp RESTART ;Button press restarts level + +:gameover + do EditorDisk + jmp RESTART + else + jmp GOATTRACT + fin + +* Raise kid from the dead (TEMP!) + + do FinalDisk + else +:raise + lda #0 + sta msgtimer + sta SongCue + + lda #BTLtimer + sta backtolife + + jsr LoadKid + + lda MaxKidStr + sta ChgKidStr + + lda #stand + jsr jumpseq + jmp startkid1 + + fin + +*------------------------------- +* +* Play death song +* +*------------------------------- +deathsong + lda ShadID + cmp #1 + beq :shad ;if opponent was shadowman + lda heroic ;was kid engaged in battle at time of death? + bne :1 ;yes--"heroic death" music + lda #s_Accid ;no--"accidental death" music + bne :2 +:shad lda #s_Shadow + bne :2 +:1 lda #s_Heroic +:2 ldx #255 + jmp cuesong +]rts rts + +*------------------------------- +* +* If char is on screen 0, kill him off +* +*------------------------------- +kill0 + lda CharLife + bpl ]rts + lda CharScrn + bne ]rts + lda #Splat + jsr addsound + lda #100 + jsr decstr + lda #0 + sta msgtimer + sta CharLife + lda #185 + sta CharPosn +]rts rts + +*------------------------------- +* +* Go to attract mode +* +*------------------------------- +GOATTRACT + do DemoDisk + else + + lda BBundID + cmp #POPside1 ;does he need to flip disk? + beq :ok ;no + + do ThreeFive + else + lda BGset1 + bpl :flip + ldx #4 + jsr LoadLevelX ;get "FLIP DISK" msg into memory + fin + +:flip jsr flipdisk ;ask him to flip disk + + fin + + lda #POPside1 + sta BBundID + +:ok jmp attractmode + +*------------------------------- +* +* Shake loose floors when character jumps +* +*------------------------------- +shakeloose + lda jarabove + bmi :jarbelow + bne :jarabove +]rts rts + +:jarbelow + lda #0 + sta jarabove + + lda CharBlockY + jmp shakem ;shake every loose floorboard on level + +:jarabove + lda #0 + sta jarabove + + lda CharBlockY + sec + sbc #1 + jmp shakem + +*------------------------------- +* +* If strength meters have changed, mark affected +* blocks for redraw +* +*------------------------------- +checkmeters + lda ChgKidStr + beq :1 + jsr MarkKidMeter + +:1 lda ChgOppStr + beq ]rts + jmp MarkOppMeter + +*------------------------------- +* +* Change strength meters as specified +* +*------------------------------- +chgmeters + lda level + cmp #12 + bne :cont + lda OpID + ora CharID + cmp #1 ;kid vs. shadowman? + bne :cont + ;yes + lda ChgKidStr + bpl :1 + sta ChgOppStr + bne :cont + +:1 lda ChgOppStr + bpl :cont + sta ChgKidStr + +* Kid's meter + +:cont lda KidStrength + clc + adc ChgKidStr + + cmp MaxKidStr + beq :ok1 + bcs :opp + +:ok1 sta KidStrength + +* Opponent's meter + +:opp lda OppStrength + clc + adc ChgOppStr + + cmp MaxOppStr + beq :ok2 + bcs ]rts + +:ok2 sta OppStrength +]rts rts + +*------------------------------- +* +* Slam player's entrance shut (add it to trans list) +* +*------------------------------- +entrance + lda KidScrn + jsr calcblue + + ldy #29 + +:loop lda (BlueType),y + and #idmask + cmp #exit + bne :cont ;find player's entrance + + lda KidScrn + jmp closeexit ;& return + +:cont dey + bpl :loop + +]rts rts + +*------------------------------- +* +* Play song cues +* +* In: SongCue (0 = none, non0 = song #) +* SongCount +* +*------------------------------- +songcues + do EditorDisk + rts + fin + + ldx SongCue + beq ]rts + lda level + beq ]rts ;no music in demo + + lda SongCount + bne :cont + lda #0 + sta SongCue ;when SongCount reaches 0, forget it +]rts rts +:cont dec SongCount + + lda KidPosn + bne :1 + lda NextLevel + cmp level + beq ]rts ;Play only one song once kid has reached stairs + +:1 lda KidPosn + jsr static? + bne ]rts + + lda ShadFace + cmp #86 + beq :ok + lda ShadScrn + cmp VisScrn + bne :ok + lda ShadPosn + jsr static? + bne ]rts +:ok + lda trobcount ;(set by animtrans if there are any + bne ]rts ;slicers or other fast-moving objects +;that it wouldn't look good to freeze) + lda nummob + bne ]rts + lda lightning + bne ]rts ;wait for no MOBs and no lightning + lda mergetimer + bmi :ok2 + bne ]rts + lda ChgKidStr + ora ChgOppStr + bne ]rts ;& no impact stars +:ok2 + +* Prepare for minimal animation + + lda PAGE + eor #$20 + sta PAGE + + jsr listtorches + +* Play song + + lda SongCue + jsr minit + + sta $c010 ;clr kbd + +:loop jsr burn + jsr musickeys + + jsr mplay + cmp #0 + bne :loop + +:done lda #0 + sta SongCue + +:rtn lda PAGE + eor #$20 + sta PAGE + + jmp clearjoy + +*------------------------------- +* +* Add additional sound fx +* +*------------------------------- +addsfx + lda #167 ;blocked strike + cmp KidPosn ;if char is striking... + bne :1 + lda #SwordClash1 + bne :clash +:1 cmp ShadPosn + bne :2 + lda #SwordClash2 +:clash jmp addsound +:2 +]rts rts + +*------------------------------- +* +* Display message ("Press button to continue" or "Level #" +* or "# minutes left") +* +*------------------------------- +dispmsg + lda msgtimer + beq ]rts + dec msgtimer + + lda KidLife + bmi :alive + +* Kid is dead -- message is "Press button to continue" + + lda msgtimer + cmp #contoff + bcc ]rts + + cmp #contflash + bcs :steady + + and #7 + cmp #3 + bcs ]rts + cmp #2 + bne :steady + + lda soundon + bne :2 + jsr gtone ;if sound off +:2 lda #FlashMsg + jsr addsound + +:steady jmp continuemsg ;Kid is dead--superimpose continue msg + +* Kid is alive -- message is "Level #" or "# Minutes" + +:alive lda msgtimer + cmp #leveltimer-2 + bcs ]rts + + lda message + cmp #LevelMsg + bne :1 + jmp printlevel + +:1 cmp #TimeMsg + bne ]rts + jmp timeleftmsg + +*------------------------------- +* +* Display "Turn disk over" and wait for button press +* +*------------------------------- +flipdisk + do ThreeFive + lda #1 + sta purpleflag ;pass copy-protect! + rts + fin + + do DemoDisk + jmp GOATTRACT + else + +* 1st copy protection check + + lda redherring + eor redherring2 + cmp #POPside1 ;passed 1st check? + beq :1 + lda #POPside1 + sta BBundID + jmp attractmode + +* Passed copy protection--continue + +:1 lda #" " + jsr lrcls + + jsr zerolsts + jsr zeropeels + lda #1 + sta genCLS + + jsr flipdiskmsg + + jsr drawall + + jsr vblank + jsr PageFlip + + lda $c010 ;clr kbd strobe +:loop + lda $c061 + ora $c062 + ora $c000 + bpl :loop + + fin + +* Flip to clr text scrn + +showtext jsr vblank + lda PAGE2off + lda TEXTon +]rts rts + +*------------------------------- +* +* Is character moving? +* +* In: A = CharPosn +* Out: 0 if static, 1 if moving +* +*------------------------------- +static? + cmp #0 + beq ]ok + cmp #15 ;stand + beq ]ok + cmp #229 ;brandish sword + beq ]ok + cmp #109 ;crouching + beq ]ok + cmp #171 ;en garde + beq ]ok + cmp #166 ;alert stand (for gd.) + beq ]ok +cold? + cmp #185 ;dead + beq ]ok + cmp #177 ;impaled + beq ]ok + cmp #178 ;halves + beq ]ok + lda #1 + rts +]ok lda #0 +]rts rts + +*------------------------------- +* +* Clear all jstk flags +* +*------------------------------- +clearjoy + jsr LoadSelect + lda #0 + sta clrF + sta clrB + sta clrU + sta clrD + jmp SaveSelect + +*------------------------------- +* +* Misc. timers (Call every cycle) +* +*------------------------------- +misctimers + lda mergetimer + beq :3 + bmi :3 + dec mergetimer + bne :3 + dec mergetimer ;goes from 1 to -1 +:3 + +* Level 8: When you've spent a certain amount of time on +* screen 16 once exit is open, mouse rescues you + + lda level + cmp #8 ;mouse level + bne :12 + lda CharScrn + cmp #16 + bne :12 + lda exitopen + beq :12 + cmp #mousetimer + bcc :11 + bne :12 +:10 jsr mouserescue +:11 inc exitopen +:12 +]rts rts + +*------------------------------- +* +* Screen flashes towards end of weightlessness period +* +*------------------------------- +wtlessflash + lda weightless + beq ]rts + ldx #0 + sec + sbc #1 + sta weightless + beq :3 + ldx #$ff + cmp #wtlflash + bcs :3 + lda vibes + eor #$ff + tax +:3 stx vibes ;Screen flashes as weightlessness ends +]rts rts + +*------------------------------- +* yellow copy protection +* (call right before 1st princess cut) +* In: A = next level +*------------------------------- +yellowcheck + cmp #2 + bne ]rts + jsr showtext + ldx #10 + jmp yellow ;in gamebg + ;sets yellowflag ($7c) hibit + +*------------------------------- +* +* Temp development patch for screen redraw +* (also used for invert Y) +* +*------------------------------- +develpatch + do 0 + lda blackflag ;blackout? + beq :1 + lda #1 + sta genCLS + fin + +:1 lda redrawflg ;forced redraw? + beq ]rts + dec redrawflg + + jsr markmeters + jmp sure + +*------------------------------- + lst + ds 1 + usr $a9,4,$a00,*-org + lst off diff --git a/01 POP Source/Source/UNPACK.S b/01 POP Source/Source/UNPACK.S index b68c33c..5526afd 100755 --- a/01 POP Source/Source/UNPACK.S +++ b/01 POP Source/Source/UNPACK.S @@ -1 +1,883 @@ -* unpack 3.5 ThreeFive = 1 org = $ea00 lst off *------------------------------- * * Sits in main l.c. bank 2 * *------------------------------- org org jmp SNGEXPAND jmp DBLEXPAND jmp DELTAEXPPOP jmp INVERTY jmp DELTAEXPWIPE jmp PURPLE jmp PROMPT jmp BLACKOUT jmp CLR jmp TEXT jmp SETDHIRES jmp FADEIN jmp LOADSUPER jmp FADEOUT *------------------------------- lst put gameeq lst put eq lst off 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 *------------------------------- * RW18 ID bytes POPside1 = $a9 POPside2 = $ad * RW18 zero page vars slot = $fd track = $fe lastrack = $ff * RW18 commands DrvOn = $00 DrvOff = $01 Seek = $02 RdSeqErr = $03 RdGrpErr = $04 WrtSeqErr = $05 WrtGrpErr = $06 ModID = $07 RdSeq = $83 RdGrp = $84 WrtSeq = $85 WrtGrp = $86 Inc = $40 ;.Inc to inc track *------------------------------- * * Unpack single hi-res screen into page 1 * (Sorry about the code--it's lifted directly from DRAZ) * *------------------------------- dum $00 PAC ds 2 PIC ds 2 V2 ds 1 V3 ds 1 V4 ds 1 V5 ds 1 V8 ds 1 V9 ds 1 VA ds 1 VB ds 1 VC ds 1 dend *------------------------------- SNGEXPAND sta RAMRDaux sta RAMWRTmain STA PAC+1 ;org addr LDA #$20 STA PIC+1 ;dest addr LDA #0 STA PAC STA PIC LDA #$FE STA V8 LDA #0 STA VA LDY #$27 :4 LDA #$78 STA V2 LDA #$20 STA V3 :0 LDA V2 SEC SBC #$28 STA V2 BCS :1 DEC V3 :1 LDA V2 STA V4 LDA V3 CLC ADC #4 STA V5 :2 LDA V4 SEC SBC #$80 STA V4 BCS :3 DEC V5 :3 LDA V4 STA PIC LDA V5 CLC ADC #$20 STA PIC+1 :5 LDA PIC+1 SEC SBC #4 STA PIC+1 CLC BCC :6 :13 LDA PIC+1 CMP V5 BNE :5 LDA V4 CMP V2 BNE :2 LDA V5 CMP V3 BNE :2 LDA V2 BNE :0 DEY BPL :4 RTS :6 BIT VA BMI :11 LDX #0 LDA (PAC,X) STA VB CMP V8 BNE :10 INC PAC BNE :7 INC PAC+1 :7 LDA (PAC,X) STA V9 INC PAC BNE :8 INC PAC+1 :8 LDA (PAC,X) STA VB INC PAC BNE :9 INC PAC+1 :9 LDA #$80 STA VA CLC BCC :11 :10 LDA VB ORA #$80 STA (PIC),Y INC PAC BNE :12 INC PAC+1 :12 CLC BCC :13 :11 LDA VB ORA #$80 STA (PIC),Y DEC V9 BNE :13 LDA #0 STA VA BEQ :13 *------------------------------- * * Unpack crunched double hi-res screen * * Robert A. Cook 3/89 * * In: A = hi byte of crunched data address * RAMRD set to main/aux depending on where crunched * data is stored * *------------------------------- dum $f0 CrnDatPtr ds 2 XClmPos ds 1 YScrPos ds 1 ByteHld ds 1 RepeatCdn ds 1 ScrBasPtr ds 2 dend *------------------------------- DBLEXPAND sta CrnDatPtr+1 lda #1 sta CrnDatPtr ;(CrnDatPtr),0 is crunch type (unused) jmp WipeRgtExp *------------------------------- * * Wipe Right Expand * *------------------------------- WipeRgtExp lda #0 sta XClmPos :Loop lda #0 sta YScrPos jsr ExpandClm lda #1 sta YScrPos jsr ExpandClm inc XClmPos lda XClmPos cmp #80 bne :Loop ]rts rts *------------------------------- * * Delta Expand * * In: A = hi byte of crunched data address (in auxmem) * *------------------------------- DeltaExp sta RAMRDaux sta CrnDatPtr+1 lda #0 sta CrnDatPtr sta XClmPos :Loop ldy #0 lda (CrnDatPtr),y cmp #-1 beq :Done sta ByteHld and #$80 beq :ExpandOne lda ByteHld and #$7f beq :NewCoord tax ldy #1 lda (CrnDatPtr),y jsr ExpClmSeq1 clc lda CrnDatPtr adc #2 sta CrnDatPtr bcc :a4 inc CrnDatPtr+1 :a4 jmp :Next :NewCoord ldy #1 lda (CrnDatPtr),y sta XClmPos ldy #2 lda (CrnDatPtr),y sta YScrPos clc lda CrnDatPtr adc #3 sta CrnDatPtr bcc :a7 inc CrnDatPtr+1 :a7 jmp :Next :ExpandOne lda ByteHld ldx #1 jsr ExpClmSeq1 inc CrnDatPtr bne :sysi8 inc CrnDatPtr+1 :sysi8 :Next lda XClmPos cmp #$80 bne :Loop :Done sta RAMRDmain ]rts rts *------------------------------- * * Expand Column * *------------------------------- ExpandClm :Loop ldy #0 lda (CrnDatPtr),y sta ByteHld and #$80 beq :ExpandOne ldy #1 lda (CrnDatPtr),y tax lda ByteHld and #$7f jsr ExpClmSeq clc lda CrnDatPtr adc #2 sta CrnDatPtr bcc :a4 inc CrnDatPtr+1 :a4 jmp :Next :ExpandOne lda ByteHld ldx #1 jsr ExpClmSeq inc CrnDatPtr bne :sysi5 inc CrnDatPtr+1 :sysi5 :Next lda YScrPos cmp #192 bcc :Loop rts *------------------------------- * * Expand Column Sequence * *------------------------------- * * In: XClmPos * YScrPos * A (byte pattern) * X (repeat count) * * Out: YScrPos (modified) * *------------------------------- ExpClmSeq sta ByteHld stx RepeatCdn :Loop ldx XClmPos ldy YScrPos lda ByteHld jsr PutScrByte lda YScrPos clc adc #2 sta YScrPos dec RepeatCdn bne :Loop rts *------------------------------- * * Expand Column Sequence 1 * *------------------------------- ExpClmSeq1 sta ByteHld stx RepeatCdn :Loop ldx XClmPos ldy YScrPos lda ByteHld bmi :Next jsr PutScrByte :Next inc YScrPos lda YScrPos cmp #192 bne :SkipXInc lda #0 sta YScrPos inc XClmPos :SkipXInc dec RepeatCdn bne :Loop rts *------------------------------- * * Put DHires Byte Value * *------------------------------- * * In: X (XClmPos) * Y (YScrPos) * A (Byte value) * *------------------------------- PutScrByte sta ByteHld ;YScrPos in Y lda YLO,y sta ScrBasPtr lda YHI,y ora #$20 ;DHires page 1 sta ScrBasPtr+1 txa ;XClmPos in X lsr tay bcs NoAuxSet sta RAMWRTaux NoAuxSet lda ByteHld sta (ScrBasPtr),y sta RAMWRTmain ]rts rts *------------------------------- * * P U R P L E * *------------------------------- do ThreeFive PURPLE rts else put purple fin *------------------------------- * * Delta Expand (Pop or Wipe) * * In: A = hi byte of crunched data address (in auxmem) * *------------------------------- DELTAEXPPOP sta PAGE2on ]DE jsr DeltaExp sta PAGE2off sta RAMRDaux sta RAMWRTaux ]rts rts DELTAEXPWIPE sta PAGE2off jmp ]DE *------------------------------- * * Invert Y-tables * *------------------------------- INVERTY ldx #191 ;low line ldy #0 ;high line * Switch low & high lines :loop lda YLO,x pha lda YLO,y sta YLO,x pla sta YLO,y lda YHI,x pha lda YHI,y sta YHI,x pla sta YHI,y * Move 1 line closer to ctr dex iny cpy #96 bcc :loop ]rts rts *------------------------------- * * Prompt user to insert correct disk side * *------------------------------- do ThreeFive msg1 asc " Insert Prince of Persia Disk@" else msg1 asc "Insert Prince of Persia Disk, Side " fin msg2 asc "C@" *------------------------------- PROMPT lda #"A" ldx BBundID cpx #POPside1 beq :1 lda #"B" :1 sta msg2 ;side A or B? jsr blackout sta RAMWRTmain ldx #0 :loop lda msg1,x cmp #"@" beq :done sta $528+2,x ;midscrn inx bpl :loop :done sta RAMWRTaux jsr whoop ;whoop spkr :wloop lda $c000 ora $c061 ora $c062 bpl :wloop sta $c010 jmp clr ;clear screen *------------------------------- CLR bit RWBANK2 bit RWBANK2 sta $c010 lda #" " jmp _lrcls ;in hires *------------------------------- * * Show black screen (text page 1) * *------------------------------- BLACKOUT jsr CLR TEXT sta RAMRDaux jsr vblank sta TEXTon sta ADCOLoff sta PAGE2off ]rts rts *------------------------------- * Set dbl hires *------------------------------- SETDHIRES sta RAMRDaux sta RAMWRTaux jsr vblank sta ADCOLon bit HIRESon bit DHIRESon bit DHIRESoff bit DHIRESon bit DHIRESoff bit DHIRESon ;for old Apple RGB card sta TEXToff rts ************************************************** ************************************************** ************************************************** xc xc stlx mac bank;addr hex 9f da ]2 db ]1 <<< ldlx mac bank;addr hex bf da ]2 db ]1 <<< *------------------------------- * * FADE IN * * In: s-hires data in $2000.9FFF * A = 0 main, 1 aux * *------------------------------- FADEIN sta RAMRDmain sta :sm1+2 sta :sm2+2 clc xce sep $30 ;axy lda #%00011110 sta $C035 ;shadow reg lda #$41 sta $C029 ;SH reg rep $30 ;AXY * Clear scan line control byte table * and palette 0 to black lda #$0000 ldx #$011E :scbclr dex dex stlx $E1;$9D00 bne :scbclr * Now move data over ldx #$2000 ldy #$2000 lda #32000-1 phb :sm1 mvn $E1,1 ;main/aux plb * Turn on Super Hires mode sep $20 lda #$C1 sta $C029 rep $20 * Move desired palette over to PalFade area ldx #$9D00 ;aux mem ldy #new_palette lda #32-1 phb :sm2 mvn 0,1 ;aux to main/aux plb * Now fade in the picture bra PalFade ;switches back to e-mode *------------------------------- * * FADE OUT * *------------------------------- FADEOUT mx 3 * Clear the "destination" palette back to zero ldx #31 lda #$00 :palclr sta new_palette,x dex bpl :palclr * Now fade out bra PalFade ;switches back to e-mode *------------------------------------------------- PalFade * * Given current palette at $E19E00.1F, fade to * new palette given in new_palette * new_palette ds 32 PalFade dum 0 :green ds 1 :blue ds 1 dend sec xce bit $C019 bmi *-3 ldy #16 :fadein ldx #3 :fadein2 bit $C019 bpl *-3 bit $C019 bmi *-3 dex bne :fadein2 ldx #30 :palloop ldlx $E1;$9E01 and #$0f cmp new_palette+1,x beq :red_ok inc blt :red_ok dec dec :red_ok stlx $E1;$9E01 lda new_palette,x and #$F0 sta :green ldlx $E1;$9E00 and #$F0 cmp :green beq :green_ok blt :grn_add sbc #$20 :grn_add clc adc #$10 :green_ok sta :green lda new_palette,x and #$0F sta :blue ldlx $E1;$9E00 and #$0F cmp :blue beq :blue_ok inc blt :blue_ok dec dec :blue_ok ora :green stlx $E1;$9E00 dex dex bpl :palloop dey bpl :fadein rts xc off mx 3 *=============================== * * Load super hi-res data * *------------------------------- LOADSUPER jsr rw18 db ModID,$79 ;set "side C" lda #0 sta track sta RAMWRTmain jsr loadscrn ;"Tracks" 0-6: palace (mainmem) sta RAMWRTaux jmp loadscrn ;"Tracks" 7-13: epilog (auxmem) *------------------------------- * * Load super hi-res screen into $2000.9FFF * *------------------------------- loadscrn lda #$20 :loop sta :sm jsr rw18 db RdSeq.Inc :sm db $20 lda :sm clc adc #$12 cmp #$9e bcc :loop ;load 7 tracks ]rts rts *------------------------------- lst eof ds 1 usr $a9,2,$a00,*-org lst off \ No newline at end of file +* unpack 3.5 +ThreeFive = 1 +org = $ea00 + lst off +*------------------------------- +* +* Sits in main l.c. bank 2 +* +*------------------------------- + org org + + jmp SNGEXPAND + jmp DBLEXPAND + jmp DELTAEXPPOP + jmp INVERTY + jmp DELTAEXPWIPE + + jmp PURPLE + jmp PROMPT + jmp BLACKOUT + jmp CLR + jmp TEXT + + jmp SETDHIRES + jmp FADEIN + jmp LOADSUPER + jmp FADEOUT + +*------------------------------- + lst + put gameeq + lst + put eq + lst off + +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 + +*------------------------------- +* RW18 ID bytes + +POPside1 = $a9 +POPside2 = $ad + +* RW18 zero page vars + +slot = $fd +track = $fe +lastrack = $ff + +* RW18 commands + +DrvOn = $00 +DrvOff = $01 +Seek = $02 +RdSeqErr = $03 +RdGrpErr = $04 +WrtSeqErr = $05 +WrtGrpErr = $06 +ModID = $07 +RdSeq = $83 +RdGrp = $84 +WrtSeq = $85 +WrtGrp = $86 +Inc = $40 ;.Inc to inc track + +*------------------------------- +* +* Unpack single hi-res screen into page 1 +* (Sorry about the code--it's lifted directly from DRAZ) +* +*------------------------------- + dum $00 + +PAC ds 2 +PIC ds 2 +V2 ds 1 +V3 ds 1 +V4 ds 1 +V5 ds 1 +V8 ds 1 +V9 ds 1 +VA ds 1 +VB ds 1 +VC ds 1 + + dend + +*------------------------------- +SNGEXPAND + sta RAMRDaux + sta RAMWRTmain + + STA PAC+1 ;org addr + + LDA #$20 + STA PIC+1 ;dest addr + + LDA #0 + STA PAC + STA PIC + + LDA #$FE + STA V8 + LDA #0 + STA VA + LDY #$27 +:4 LDA #$78 + STA V2 + LDA #$20 + STA V3 +:0 LDA V2 + SEC + SBC #$28 + STA V2 + BCS :1 + DEC V3 +:1 LDA V2 + STA V4 + LDA V3 + CLC + ADC #4 + STA V5 +:2 LDA V4 + SEC + SBC #$80 + STA V4 + BCS :3 + DEC V5 +:3 LDA V4 + STA PIC + LDA V5 + CLC + ADC #$20 + STA PIC+1 +:5 LDA PIC+1 + SEC + SBC #4 + STA PIC+1 + CLC + BCC :6 +:13 LDA PIC+1 + CMP V5 + BNE :5 + LDA V4 + CMP V2 + BNE :2 + LDA V5 + CMP V3 + BNE :2 + LDA V2 + BNE :0 + DEY + BPL :4 + RTS +:6 BIT VA + BMI :11 + LDX #0 + LDA (PAC,X) + STA VB + CMP V8 + BNE :10 + INC PAC + BNE :7 + INC PAC+1 +:7 LDA (PAC,X) + STA V9 + INC PAC + BNE :8 + INC PAC+1 +:8 LDA (PAC,X) + STA VB + INC PAC + BNE :9 + INC PAC+1 +:9 LDA #$80 + STA VA + CLC + BCC :11 +:10 LDA VB + ORA #$80 + STA (PIC),Y + INC PAC + BNE :12 + INC PAC+1 +:12 CLC + BCC :13 +:11 LDA VB + ORA #$80 + STA (PIC),Y + DEC V9 + BNE :13 + LDA #0 + STA VA + BEQ :13 + +*------------------------------- +* +* Unpack crunched double hi-res screen +* +* Robert A. Cook 3/89 +* +* In: A = hi byte of crunched data address +* RAMRD set to main/aux depending on where crunched +* data is stored +* +*------------------------------- + + dum $f0 + +CrnDatPtr ds 2 +XClmPos ds 1 +YScrPos ds 1 +ByteHld ds 1 +RepeatCdn ds 1 +ScrBasPtr ds 2 + + dend + +*------------------------------- +DBLEXPAND + sta CrnDatPtr+1 + + lda #1 + sta CrnDatPtr +;(CrnDatPtr),0 is crunch type (unused) + jmp WipeRgtExp + +*------------------------------- +* +* Wipe Right Expand +* +*------------------------------- +WipeRgtExp + lda #0 + sta XClmPos + +:Loop lda #0 + sta YScrPos + jsr ExpandClm + + lda #1 + sta YScrPos + jsr ExpandClm + + inc XClmPos + + lda XClmPos + cmp #80 + bne :Loop + +]rts rts + +*------------------------------- +* +* Delta Expand +* +* In: A = hi byte of crunched data address (in auxmem) +* +*------------------------------- +DeltaExp + sta RAMRDaux + + sta CrnDatPtr+1 + + lda #0 + sta CrnDatPtr + + sta XClmPos + +:Loop ldy #0 + lda (CrnDatPtr),y + cmp #-1 + beq :Done + + sta ByteHld + and #$80 + beq :ExpandOne + + lda ByteHld + and #$7f + beq :NewCoord + + tax + + ldy #1 + lda (CrnDatPtr),y + jsr ExpClmSeq1 + + clc + lda CrnDatPtr + adc #2 + sta CrnDatPtr + bcc :a4 + inc CrnDatPtr+1 +:a4 + jmp :Next + +:NewCoord + ldy #1 + lda (CrnDatPtr),y + sta XClmPos + + ldy #2 + lda (CrnDatPtr),y + sta YScrPos + + clc + lda CrnDatPtr + adc #3 + sta CrnDatPtr + bcc :a7 + inc CrnDatPtr+1 +:a7 + jmp :Next + +:ExpandOne + lda ByteHld + ldx #1 + jsr ExpClmSeq1 + + inc CrnDatPtr + bne :sysi8 + inc CrnDatPtr+1 +:sysi8 + +:Next lda XClmPos + cmp #$80 + bne :Loop + +:Done sta RAMRDmain +]rts rts + +*------------------------------- +* +* Expand Column +* +*------------------------------- +ExpandClm + +:Loop ldy #0 + lda (CrnDatPtr),y + sta ByteHld + and #$80 + beq :ExpandOne + + ldy #1 + lda (CrnDatPtr),y + tax + lda ByteHld + and #$7f + jsr ExpClmSeq + + clc + lda CrnDatPtr + adc #2 + sta CrnDatPtr + bcc :a4 + inc CrnDatPtr+1 +:a4 + jmp :Next + +:ExpandOne + lda ByteHld + ldx #1 + jsr ExpClmSeq + + inc CrnDatPtr + bne :sysi5 + inc CrnDatPtr+1 +:sysi5 + +:Next lda YScrPos + cmp #192 + bcc :Loop + + rts + +*------------------------------- +* +* Expand Column Sequence +* +*------------------------------- +* +* In: XClmPos +* YScrPos +* A (byte pattern) +* X (repeat count) +* +* Out: YScrPos (modified) +* +*------------------------------- +ExpClmSeq + sta ByteHld + stx RepeatCdn + +:Loop ldx XClmPos + ldy YScrPos + lda ByteHld + jsr PutScrByte + + lda YScrPos + clc + adc #2 + sta YScrPos + + dec RepeatCdn + bne :Loop + + rts + +*------------------------------- +* +* Expand Column Sequence 1 +* +*------------------------------- +ExpClmSeq1 + sta ByteHld + stx RepeatCdn + +:Loop ldx XClmPos + ldy YScrPos + lda ByteHld + bmi :Next + + jsr PutScrByte + +:Next inc YScrPos + + lda YScrPos + cmp #192 + bne :SkipXInc + + lda #0 + sta YScrPos + + inc XClmPos + +:SkipXInc + dec RepeatCdn + bne :Loop + + rts + +*------------------------------- +* +* Put DHires Byte Value +* +*------------------------------- +* +* In: X (XClmPos) +* Y (YScrPos) +* A (Byte value) +* +*------------------------------- +PutScrByte + sta ByteHld + ;YScrPos in Y + lda YLO,y + sta ScrBasPtr + lda YHI,y + ora #$20 ;DHires page 1 + sta ScrBasPtr+1 + + txa ;XClmPos in X + lsr + tay + bcs NoAuxSet + + sta RAMWRTaux + +NoAuxSet lda ByteHld + sta (ScrBasPtr),y + + sta RAMWRTmain + +]rts rts + +*------------------------------- +* +* P U R P L E +* +*------------------------------- + do ThreeFive +PURPLE rts + + else + put purple + fin + +*------------------------------- +* +* Delta Expand (Pop or Wipe) +* +* In: A = hi byte of crunched data address (in auxmem) +* +*------------------------------- +DELTAEXPPOP + sta PAGE2on +]DE jsr DeltaExp + sta PAGE2off + sta RAMRDaux + sta RAMWRTaux +]rts rts + +DELTAEXPWIPE + sta PAGE2off + jmp ]DE + +*------------------------------- +* +* Invert Y-tables +* +*------------------------------- +INVERTY + ldx #191 ;low line + ldy #0 ;high line + +* Switch low & high lines + +:loop lda YLO,x + pha + lda YLO,y + sta YLO,x + pla + sta YLO,y + + lda YHI,x + pha + lda YHI,y + sta YHI,x + pla + sta YHI,y + +* Move 1 line closer to ctr + + dex + iny + cpy #96 + bcc :loop +]rts rts + +*------------------------------- +* +* Prompt user to insert correct disk side +* +*------------------------------- + do ThreeFive +msg1 asc " Insert Prince of Persia Disk@" + else +msg1 asc "Insert Prince of Persia Disk, Side " + fin + +msg2 asc "C@" + +*------------------------------- +PROMPT + lda #"A" + ldx BBundID + cpx #POPside1 + beq :1 + lda #"B" +:1 sta msg2 ;side A or B? + + jsr blackout + + sta RAMWRTmain + + ldx #0 +:loop lda msg1,x + cmp #"@" + beq :done + sta $528+2,x ;midscrn + inx + bpl :loop + +:done sta RAMWRTaux + jsr whoop ;whoop spkr + +:wloop lda $c000 + ora $c061 + ora $c062 + bpl :wloop + sta $c010 + + jmp clr ;clear screen + +*------------------------------- +CLR bit RWBANK2 + bit RWBANK2 + + sta $c010 + + lda #" " + jmp _lrcls ;in hires + +*------------------------------- +* +* Show black screen (text page 1) +* +*------------------------------- +BLACKOUT + jsr CLR + +TEXT sta RAMRDaux + jsr vblank + sta TEXTon + sta ADCOLoff + sta PAGE2off +]rts rts + +*------------------------------- +* Set dbl hires +*------------------------------- +SETDHIRES + sta RAMRDaux + sta RAMWRTaux + jsr vblank + sta ADCOLon + bit HIRESon + + bit DHIRESon + bit DHIRESoff + bit DHIRESon + bit DHIRESoff + bit DHIRESon ;for old Apple RGB card + + sta TEXToff + rts + +************************************************** +************************************************** +************************************************** + xc + xc + +stlx mac bank;addr + hex 9f + da ]2 + db ]1 + <<< +ldlx mac bank;addr + hex bf + da ]2 + db ]1 + <<< + +*------------------------------- +* +* FADE IN +* +* In: s-hires data in $2000.9FFF +* A = 0 main, 1 aux +* +*------------------------------- +FADEIN + sta RAMRDmain + sta :sm1+2 + sta :sm2+2 + + clc + xce + + sep $30 ;axy + + lda #%00011110 + sta $C035 ;shadow reg + lda #$41 + sta $C029 ;SH reg + + rep $30 ;AXY + +* Clear scan line control byte table +* and palette 0 to black + + lda #$0000 + ldx #$011E +:scbclr dex + dex + stlx $E1;$9D00 + bne :scbclr + +* Now move data over + + ldx #$2000 + ldy #$2000 + lda #32000-1 + phb +:sm1 mvn $E1,1 ;main/aux + plb + +* Turn on Super Hires mode + + sep $20 + lda #$C1 + sta $C029 + rep $20 + +* Move desired palette over to PalFade area + + ldx #$9D00 ;aux mem + ldy #new_palette + lda #32-1 + phb +:sm2 mvn 0,1 ;aux to main/aux + plb + +* Now fade in the picture + + bra PalFade ;switches back to e-mode + +*------------------------------- +* +* FADE OUT +* +*------------------------------- +FADEOUT + mx 3 + +* Clear the "destination" palette back to zero + + ldx #31 + lda #$00 +:palclr sta new_palette,x + dex + bpl :palclr + +* Now fade out + + bra PalFade ;switches back to e-mode + +*------------------------------------------------- PalFade +* +* Given current palette at $E19E00.1F, fade to +* new palette given in new_palette +* + +new_palette ds 32 + +PalFade dum 0 +:green ds 1 +:blue ds 1 + dend + + sec + xce + + bit $C019 + bmi *-3 + + ldy #16 + +:fadein ldx #3 + +:fadein2 bit $C019 + bpl *-3 + + bit $C019 + bmi *-3 + + dex + bne :fadein2 + + ldx #30 +:palloop ldlx $E1;$9E01 + and #$0f + cmp new_palette+1,x + beq :red_ok + inc + blt :red_ok + dec + dec + +:red_ok stlx $E1;$9E01 + + lda new_palette,x + and #$F0 + sta :green + + ldlx $E1;$9E00 + and #$F0 + cmp :green + beq :green_ok + blt :grn_add + sbc #$20 +:grn_add clc + adc #$10 + +:green_ok sta :green + + lda new_palette,x + and #$0F + sta :blue + + ldlx $E1;$9E00 + and #$0F + cmp :blue + beq :blue_ok + inc + blt :blue_ok + dec + dec + +:blue_ok ora :green + stlx $E1;$9E00 + + dex + dex + bpl :palloop + + dey + bpl :fadein + + rts + + xc off + mx 3 + +*=============================== +* +* Load super hi-res data +* +*------------------------------- +LOADSUPER + jsr rw18 + db ModID,$79 ;set "side C" + + lda #0 + sta track + sta RAMWRTmain + jsr loadscrn ;"Tracks" 0-6: palace (mainmem) + + sta RAMWRTaux + jmp loadscrn ;"Tracks" 7-13: epilog (auxmem) + +*------------------------------- +* +* Load super hi-res screen into $2000.9FFF +* +*------------------------------- +loadscrn + lda #$20 +:loop sta :sm + jsr rw18 + db RdSeq.Inc +:sm db $20 + lda :sm + clc + adc #$12 + cmp #$9e + bcc :loop ;load 7 tracks +]rts rts + +*------------------------------- + lst +eof ds 1 + usr $a9,2,$a00,*-org + lst off diff --git a/01 POP Source/Source/VERSION.S b/01 POP Source/Source/VERSION.S index bd93298..7047480 100755 --- a/01 POP Source/Source/VERSION.S +++ b/01 POP Source/Source/VERSION.S @@ -1 +1,14 @@ -* version org = $dfd8 lst off org org *------------------------------- TextLine asc "Prince of Persia 1.0 9/7/89" lst asc "@" *------------------------------- usr $a9,19,$11d8,*-org lst off \ No newline at end of file +* version +org = $dfd8 + lst off + + org org + +*------------------------------- + +TextLine asc "Prince of Persia 1.0 9/7/89" + lst + asc "@" +*------------------------------- + usr $a9,19,$11d8,*-org + lst off diff --git a/02 POP Disk Routines/CP.525/CUBE.S b/02 POP Disk Routines/CP.525/CUBE.S index f015bda..a10e7c8 100755 --- a/02 POP Disk Routines/CP.525/CUBE.S +++ b/02 POP Disk Routines/CP.525/CUBE.S @@ -1 +1,174 @@ - lst off *------------------------------------------------- rotcube mainYoffset = 46 ;(192-60)/2 botYoffset = 72 mainXoffset = 68 ;(280-144)/2 color = $E4 page = $E6 dum 0 index ds 1 ysave ds 1 yadd ds 1 yoffset ds 1 dend *------------------------------------------------- rotcube jsr $f3e2 ;hgr jsr $f3d8 ;hgr2 lda #1 sta yadd sta yoffset * Draw on page not showing: mainloop lda page eor #$60 sta page ldx #$7F jsr draw * If not a //c, then wait for vbl lda $FBC0 beq :is2c lda $C019 bpl *-3 lda $C019 bmi *-3 :is2c * Now display that page bit $C054 lda page cmp #$20 beq *+5 bit $C055 * Now erase old image from last page eor #$60 sta :smc0+2 sta :smc1+2 ldx #$20 lda #0 :loop tay :smc0 sta $2000,y :smc1 sta $2080,y iny bpl :smc0 inc :smc0+2 inc :smc1+2 dex bne :loop inc index jmp mainloop *------------------------------------------------- draw stx color ldy #12-1 :drawloop lda drawlist,y sty ysave pha and #15 jsr getpoint tax tya ldy #0 jsr $f457 ;plot pla lsr lsr lsr lsr jsr getpoint ldx #0 jsr $f53a ;lineto ldy ysave dey bpl :drawloop lda yoffset clc adc yadd bne :not0 inc yadd ;make +1 inc yadd :not0 cmp #191-48-botYoffset bcc :0 dec yadd ;make -1 dec yadd :0 sta yoffset rts *------------------------------------------------- * * given a = point number, return a = xcoor, y = ycoor * getpoint tay * Get index into tables asl ;*16 asl asl asl adc index and #$3F tax tya and #4 ;bottom? cmp #4 * Compute ycoor lda ydata,x bcc :not_bot adc #botYoffset-1 :not_bot adc yoffset tay * Compute xcoor lda xdata,x adc #mainXoffset rts *------------------------------------------------- drawlist hex 01122330 ;draw top hex 45566774 ;draw bottom hex 04152637 ;draw connecting lines xdata hex 908F8E8C8A87837F7A757069635C564F hex 484039332C261F1A15100C0805030100 hex 0000010305080C10151A1F262C333940 hex 474F565C636970757A7F83878A8C8E8F ydata hex 181A1C1E21232527282A2B2D2E2E2F2F hex 2F2F2F2E2E2D2B2A28272523211E1C1A hex 181513110E0C0A080705040201010000 hex 000000010102040507080A0C0E111315 *------------------------------------------------- \ No newline at end of file + lst off + +*------------------------------------------------- rotcube + +mainYoffset = 46 ;(192-60)/2 +botYoffset = 72 +mainXoffset = 68 ;(280-144)/2 + +color = $E4 +page = $E6 + + dum 0 +index ds 1 +ysave ds 1 +yadd ds 1 +yoffset ds 1 + dend + +*------------------------------------------------- + +rotcube jsr $f3e2 ;hgr + jsr $f3d8 ;hgr2 + + lda #1 + sta yadd + + sta yoffset + +* Draw on page not showing: + +mainloop lda page + eor #$60 + sta page + ldx #$7F + jsr draw + +* If not a //c, then wait for vbl + + lda $FBC0 + beq :is2c + lda $C019 + bpl *-3 + lda $C019 + bmi *-3 +:is2c + +* Now display that page + + bit $C054 + lda page + cmp #$20 + beq *+5 + bit $C055 + +* Now erase old image from last page + + eor #$60 + sta :smc0+2 + sta :smc1+2 + ldx #$20 + lda #0 +:loop tay +:smc0 sta $2000,y +:smc1 sta $2080,y + iny + bpl :smc0 + inc :smc0+2 + inc :smc1+2 + dex + bne :loop + + inc index + jmp mainloop + +*------------------------------------------------- + +draw stx color + + ldy #12-1 +:drawloop lda drawlist,y + sty ysave + + pha + and #15 + jsr getpoint + + tax + tya + ldy #0 + jsr $f457 ;plot + + pla + lsr + lsr + lsr + lsr + jsr getpoint + ldx #0 + jsr $f53a ;lineto + + ldy ysave + dey + bpl :drawloop + + lda yoffset + clc + adc yadd + bne :not0 + + inc yadd ;make +1 + inc yadd + +:not0 cmp #191-48-botYoffset + bcc :0 + + dec yadd ;make -1 + dec yadd + +:0 sta yoffset + rts + +*------------------------------------------------- +* +* given a = point number, return a = xcoor, y = ycoor +* + +getpoint tay + +* Get index into tables + + asl ;*16 + asl + asl + asl + adc index + and #$3F + tax + tya + + and #4 ;bottom? + cmp #4 + +* Compute ycoor + + lda ydata,x + bcc :not_bot + adc #botYoffset-1 + +:not_bot adc yoffset + tay + +* Compute xcoor + + lda xdata,x + adc #mainXoffset + rts + +*------------------------------------------------- + +drawlist hex 01122330 ;draw top + hex 45566774 ;draw bottom + hex 04152637 ;draw connecting lines + +xdata hex 908F8E8C8A87837F7A757069635C564F + hex 484039332C261F1A15100C0805030100 + hex 0000010305080C10151A1F262C333940 + hex 474F565C636970757A7F83878A8C8E8F + +ydata hex 181A1C1E21232527282A2B2D2E2E2F2F + hex 2F2F2F2E2E2D2B2A28272523211E1C1A + hex 181513110E0C0A080705040201010000 + hex 000000010102040507080A0C0E111315 + +*------------------------------------------------- diff --git a/02 POP Disk Routines/CP.525/LOSHOW.S b/02 POP Disk Routines/CP.525/LOSHOW.S index 9045d50..a865141 100755 --- a/02 POP Disk Routines/CP.525/LOSHOW.S +++ b/02 POP Disk Routines/CP.525/LOSHOW.S @@ -1 +1,371 @@ - lst off org $c00 *------------------------------------------------- dum 0 curpage ds 1 xsave ds 1 ysave ds 1 asave ds 1 temp ds 1 tmplo ds 1 tmphi ds 1 level ds 1 isGS? ds 1 dend framebase = $1000 *------------------------------------------------- show * * put on the show! * show bit $C010 lda #0 sta isGS? bit $C081 sec jsr $fe1f ;GS? bcs :notGS inc isGS? * Use special show frame routine for //GS that * writes directly to bank $E0, since page two * text is not properly shadowed to that bank. ldx #$4C ;jmp ldy #GSshowframe lda #>GSshowframe stx showframe sty showframe+1 sta showframe+2 * Make our lookup tables up in ramcard area :notGS bit $C083 bit $C083 jsr MAKEfade_tbls jsr lgr :again ldx #0 :fadein stx level lda #0 jsr showframe ldx level inx cpx #15 bcc :fadein * Here we go... lda #0 :floop pha ldx #15 jsr showframe pla clc adc #1 cmp #23 bcc :floop ldx #15 :fadeout stx level lda #22 jsr showframe ldx level dex bpl :fadeout bit $C000 bpl *-3 bit $C010 jmp :again *------------------------------------------------- lgr * * Clear and display lo-resolution screen * lgr sta $C000 ;turn off 55.54 select sta $C00C ;40 columns bit $C052 ;full screen bit $C055 ;show page two bit $C056 ;lores bit $C050 ;graphics on lda #4 ;use page one next sta curpage ldy #0 sty tmplo sta tmphi tya ldx #8 :0 sta (tmplo),y iny bne :0 inc tmphi dex bne :0 rts *------------------------------------------------- loget * * Enter with a:frame number * x:fade level * showframe asl asl adc #>framebase sta :src+2 ;hi byte txa ora #>fade_table sta :fademod+2 lda curpage sta :dst+2 eor #4!8 sta curpage lda #4 sta temp ldx #0 :loop :src ldy $1100,x :fademod lda fade_table+$F00,y :dst sta $0400,x inx bne :loop inc :src+2 ;hibyte inc :dst+2 ; " " dec temp bne :loop ]waitvbl jsr waitvbl bit $C055 lda curpage cmp #4 beq *+5 bit $C054 rts GSshowframe asl asl adc #>framebase sta :src+2 ;hi byte txa ora #>fade_table sta :fademod+2 lda curpage sta :dst+2 eor #4!8 sta curpage lda #4 sta temp ldx #0 :loop :src ldy $1100,x :fademod lda fade_table+$F00,y :dst stal $E00400,x inx bne :loop inc :src+2 ;hibyte inc :dst+2 ; " " dec temp bne :loop beq ]waitvbl *------------------------------------------------- waitvbl * * Wait for a few vbl's to go by! * waitvbl ldx #6 :0 bit $C019 bpl :0 :1 bit $C019 bmi :1 dex bne :0 rts *------------------------------------------------- MAKEfade_tbls * * Make 16 lookup tables each containing 256 bytes * for the 16 levels of fade-in. * MAKEfade_tbls dum 0 :curtmp ds 2 ;ptr into current tmp_scale table :curfade ds 2 ;ptr into current page of fade table :temp ds 1 :ysave ds 1 dend jsr MAKEtmp_scale ldy #tmp_scale lda #>tmp_scale sty :curtmp sta :curtmp+1 ldy #fade_table lda #>fade_table sty :curfade sta :curfade+1 * byte loop ldy #0 :bloop tya and #$0F jsr :convert sta :temp tya lsr lsr lsr lsr jsr :convert asl asl asl asl ora :temp sta (:curfade),y iny bne :bloop * next fade table inc :curfade+1 * next tmp table clc lda :curtmp adc #16 sta :curtmp bcc :bloop rts * given a=0-15, in lores unsequential grey scale, * convert it back to sequential, lookup new value * in tmp_scale table and then convert back to * lores unsequential. :convert sty :ysave * Convert lores color back to sequential 00-0F tax lda :unlores,x * Scale it tay lda (:curtmp),y * Convert back to unsequential lores color tax lda isGS? beq :notGS lda :loresGS,x bra :isGS :notGS lda :lores2e,x :isGS ldy :ysave rts :unlores hex 000301070405020a hex 06080b0c090e0d0f :loresGS hex 0002060104050803 hex 090c070a0b0e0d0f :lores2e hex 00000000 hex 02020202 hex 06060606 hex 07070707 *------------------------------------------------- MAKEtmp_scale * * Make lookup table that contains values * for 0-15 multiplied by 1/16... 16/16. * MAKEtmp_scale dum 0 :color ds 1 :scale ds 1 dend lda #1 ;start with 1/16th sta :scale :sloop ldy #0 :cloop sty :color lda #0 ldx :scale :mloop clc adc :color dex bne :mloop lsr lsr lsr lsr :smc sta tmp_scale,y iny cpy #16 bne :cloop inc :scale lda :smc+1 clc adc #16 sta :smc+1 bcc :sloop rts *------------------------------------------------- dum $D000 fade_table ds $1000 tmp_scale ds $100 dend *------------------------------------------------- EOF \ No newline at end of file + lst off + + org $c00 + +*------------------------------------------------- + + dum 0 +curpage ds 1 +xsave ds 1 +ysave ds 1 +asave ds 1 +temp ds 1 +tmplo ds 1 +tmphi ds 1 +level ds 1 +isGS? ds 1 + dend + +framebase = $1000 + +*------------------------------------------------- show +* +* put on the show! +* + +show bit $C010 + + lda #0 + sta isGS? + + bit $C081 + sec + jsr $fe1f ;GS? + bcs :notGS + + inc isGS? + +* Use special show frame routine for //GS that +* writes directly to bank $E0, since page two +* text is not properly shadowed to that bank. + + ldx #$4C ;jmp + ldy #GSshowframe + lda #>GSshowframe + stx showframe + sty showframe+1 + sta showframe+2 + +* Make our lookup tables up in ramcard area + +:notGS bit $C083 + bit $C083 + + jsr MAKEfade_tbls + + jsr lgr + +:again + + ldx #0 +:fadein stx level + lda #0 + jsr showframe + ldx level + inx + cpx #15 + bcc :fadein + +* Here we go... + + lda #0 +:floop pha + ldx #15 + jsr showframe + pla + clc + adc #1 + cmp #23 + bcc :floop + + ldx #15 +:fadeout stx level + lda #22 + jsr showframe + ldx level + dex + bpl :fadeout + + bit $C000 + bpl *-3 + bit $C010 + + jmp :again + +*------------------------------------------------- lgr +* +* Clear and display lo-resolution screen +* + +lgr sta $C000 ;turn off 55.54 select + sta $C00C ;40 columns + bit $C052 ;full screen + bit $C055 ;show page two + bit $C056 ;lores + bit $C050 ;graphics on + + lda #4 ;use page one next + sta curpage + + ldy #0 + sty tmplo + sta tmphi + + tya + ldx #8 + +:0 sta (tmplo),y + iny + bne :0 + + inc tmphi + dex + bne :0 + + rts + +*------------------------------------------------- loget +* +* Enter with a:frame number +* x:fade level +* + +showframe asl + asl + adc #>framebase + sta :src+2 ;hi byte + + txa + ora #>fade_table + sta :fademod+2 + + lda curpage + sta :dst+2 + eor #4!8 + sta curpage + + lda #4 + sta temp + + ldx #0 +:loop +:src ldy $1100,x +:fademod lda fade_table+$F00,y +:dst sta $0400,x + inx + bne :loop + + inc :src+2 ;hibyte + inc :dst+2 ; " " + + dec temp + bne :loop + +]waitvbl jsr waitvbl + + bit $C055 + lda curpage + cmp #4 + beq *+5 + bit $C054 + + rts + +GSshowframe asl + asl + adc #>framebase + sta :src+2 ;hi byte + + txa + ora #>fade_table + sta :fademod+2 + + lda curpage + sta :dst+2 + eor #4!8 + sta curpage + + lda #4 + sta temp + + ldx #0 +:loop +:src ldy $1100,x +:fademod lda fade_table+$F00,y +:dst stal $E00400,x + inx + bne :loop + + inc :src+2 ;hibyte + inc :dst+2 ; " " + + dec temp + bne :loop + beq ]waitvbl + +*------------------------------------------------- waitvbl +* +* Wait for a few vbl's to go by! +* + +waitvbl ldx #6 +:0 bit $C019 + bpl :0 +:1 bit $C019 + bmi :1 + dex + bne :0 + rts + +*------------------------------------------------- MAKEfade_tbls +* +* Make 16 lookup tables each containing 256 bytes +* for the 16 levels of fade-in. +* + +MAKEfade_tbls dum 0 +:curtmp ds 2 ;ptr into current tmp_scale table +:curfade ds 2 ;ptr into current page of fade table +:temp ds 1 +:ysave ds 1 + dend + + jsr MAKEtmp_scale + + ldy #tmp_scale + lda #>tmp_scale + sty :curtmp + sta :curtmp+1 + + ldy #fade_table + lda #>fade_table + sty :curfade + sta :curfade+1 + +* byte loop + + ldy #0 + +:bloop tya + and #$0F + jsr :convert + sta :temp + + tya + lsr + lsr + lsr + lsr + jsr :convert + asl + asl + asl + asl + ora :temp + + sta (:curfade),y + + iny + bne :bloop + +* next fade table + + inc :curfade+1 + +* next tmp table + + clc + lda :curtmp + adc #16 + sta :curtmp + bcc :bloop + + rts + +* given a=0-15, in lores unsequential grey scale, +* convert it back to sequential, lookup new value +* in tmp_scale table and then convert back to +* lores unsequential. + +:convert sty :ysave + +* Convert lores color back to sequential 00-0F + + tax + lda :unlores,x + +* Scale it + + tay + lda (:curtmp),y + +* Convert back to unsequential lores color + + tax + lda isGS? + beq :notGS + lda :loresGS,x + bra :isGS + +:notGS lda :lores2e,x + +:isGS ldy :ysave + rts + +:unlores hex 000301070405020a + hex 06080b0c090e0d0f + +:loresGS hex 0002060104050803 + hex 090c070a0b0e0d0f + +:lores2e hex 00000000 + hex 02020202 + hex 06060606 + hex 07070707 + +*------------------------------------------------- MAKEtmp_scale +* +* Make lookup table that contains values +* for 0-15 multiplied by 1/16... 16/16. +* + +MAKEtmp_scale dum 0 +:color ds 1 +:scale ds 1 + dend + + lda #1 ;start with 1/16th + sta :scale + +:sloop ldy #0 +:cloop sty :color + lda #0 + ldx :scale +:mloop clc + adc :color + dex + bne :mloop + lsr + lsr + lsr + lsr +:smc sta tmp_scale,y + iny + cpy #16 + bne :cloop + inc :scale + lda :smc+1 + clc + adc #16 + sta :smc+1 + bcc :sloop + rts + +*------------------------------------------------- + + dum $D000 +fade_table ds $1000 +tmp_scale ds $100 + dend + +*------------------------------------------------- EOF diff --git a/02 POP Disk Routines/CP.525/POPBOOT0.S b/02 POP Disk Routines/CP.525/POPBOOT0.S index 0fc350d..9cf093b 100755 --- a/02 POP Disk Routines/CP.525/POPBOOT0.S +++ b/02 POP Disk Routines/CP.525/POPBOOT0.S @@ -1 +1,951 @@ -* boot org = $800 lst off xc off REDFLAG79 = $23B ; in aux mem! *------------------------------- * $800 TS (0,0) boot sector SLOT = $2b sector = $50 text = $fb2f home = $fc58 vtab = $FB5B cout = $FDF0 normal = $fe84 pr0 = $fe93 in0 = $fe89 *------------------------------- smclo = $4E smchi = $4F rw18 = $d000 slot = $fd track = $fe lastrack = $ff dum $00 dest ds 2 source ds 2 endsourc ds 2 dend *------------------------------------------------- org org hex 01 entry lda #$60 sta entry lda #MAKEBIT sta smclo ldx #$ff stx $4fb stx $3f3 stx $3f4 stx $7831 stx $c000 ;80store off stx $c002 ;RAMRD main stx $9fd8 stx $c004 ;RAMWRT main stx $c00c ;80col off stx $c00e ;Altcharset off stx $c081 ;write RAM, read ROM (2nd 4k bank) txs jsr text jsr home jsr normal jsr pr0 sta $DF35 jsr in0 stx $8492 ldx SLOT txa lsr lsr lsr lsr ora #$c0 sta :rdsect+2 lda #$0f sta sector :0 ldy sector lda skewtbl,y sta $3d lda sectaddr,y beq :1 sta $27 inc $9fd8 :rdsect jsr $005c :1 dec sector bne :0 beq decode skewtbl hex 00,0d,0b,09,07,05,03,01 hex 0e,0c,0a,08,06,04,02,0f sectaddr hex 00,09,0a,0b,00,0c,0d,0e hex 30,31,32,33,34,10,11,2f decode ldx #14 :loop lda sectaddr,x beq :nope sta :smc0+2 sta :smc1+2 ldy #0 :loop1 :smc0 lda $FF00,y eor $2F00,y :smc1 sta $FF00,y eor $7831 ;bogus garbage sta $7831 ; " " " " sta $3C iny bne :loop1 :nope dex bpl :loop ldx SLOT stage2 stx slot jsr check128k ;check for 128K memory jsr moverw18 ;& move RW18 to D000 lda #0 sta lastrack jsr rw18 hex 07,a9 ;Bbund ID byte jsr rw18 hex 00,01,00 ;drive 1 on jsr rw18 ;seek track 1 hex 02,00,01 * load & run stage 3 boot * from drive 1 jsr rw18 hex c3,ee jmp $ee00 *------------------------------------------------- * Check for AUX memory routine CHECKER lda #$EE sta $C005 lda #>MAKEBIT sta smchi sta $C003 sta $0800 lda $0C00 cmp #$EE bne :0 asl $0C00 lda $0800 cmp $0C00 beq :1 :0 clc :1 sta $C004 sta $C002 rts CHECKEND = *-CHECKER *------------------------------------------------- * * Check to make sure //c or //e * with 128k * *------------------------------- hex 34 hex 55 hex 99 check128k sta $c081 lda $FBB3 ;Apple // family ID byte cmp #6 bne NOT128K ;Must be e/c/GS bit $C017 bmi NOT128K ldx #CHECKEND :0 lda CHECKER,X sta $180,X dex bpl :0 jsr $180 bcs NOT128K rts *------------------------------- * Turn off drive and display message NOT128K ldx SLOT lda $C088,X jsr text jsr home lda #8 jsr vtab ldy #0 :0 lda MEMTEXT,Y beq * jsr cout cmp #$8D bne :1 lda #4 sta $24 :1 iny bne :0 MEMTEXT hex 8D asc "REQUIRES A //C OR //E WITH 128K" hex 00 *------------------------------- * Move RW18 * d0 < 30.40 *------------------------------- moverw18 bit $c08b bit $c08b ;rd/wrt RAM, 1st 4k bank lda #$d0 ldx #$30 ldy #$40 * 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 lda #$24 sta (smclo),y 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 MAKEBIT rts hex FF *------------------------------------------------- * * HLS APPLE COPY PROTECTION * COPYRIGHT (C) 1987 HLS DUPLICATION * * CONTACT ROBERT FREEDMAN 408-773-1300 * IF THERE ARE QUESTIONS ABOUT USE OF * THIS CODE * * EXIT clc IF A O K * sec IF PIRATE * *------------------------------------------------- OBJSCT = $07 ;PHYSICAL SECTOR # * ZERO PAGE * IF THIS CONFLICTS WITH YOUR CODE * CHANGE THE FOLLOWING ZERO PAGE * LOCATIONS, OR USE THE SAVE ZERO * PAGE ROUTINE HDRC = $F0 HDRS = HDRC+1 HDRT = HDRC+2 HDRV = HDRC+3 HEADER SECTOR LSRETRY = HDRC+4 ;NIB READ RETRIES PRETRY = HDRC+5 ;OBJSCT RETRIES NPTR = HDRC+6 NPTRH = HDRC+7 MEM1 = HDRC+8 MEM2 = HDRC+9 *------------------------------------------------- CheckCP lda #10 sta LSRETRY lda #>REDFLAG79 sta smchi ldx SLOT lda $C089,X lda $C08E,X lda #:NIBS ; !!!!! LOW BYTE sta NPTR lda #>:NIBS ; !!!!! HIGH BYTE sta NPTRH :AGAIN lda #$80 sta PRETRY :M1 dec PRETRY beq :LSFAIL jsr RADR16 bcs :LSFAIL lda HDRS cmp #OBJSCT bne :M1 ldy #0 :M2 lda $C08C,X bpl :M2 dey beq :LSFAIL cmp #$D5 bne :M2 ldy #0 :M3 lda $C08C,X bpl :M3 dey beq :LSFAIL cmp #$E7 bne :M3 :M4 lda $C08C,X bpl :M4 cmp #$E7 bne :LSFAIL :M5 lda $C08C,X bpl :M5 cmp #$E7 bne :LSFAIL lda $C08D,X ldy #$10 bit $6 ;3 US. ( FOR //C) :M6 lda $C08C,X bpl :M6 dey beq :LSFAIL cmp #$EE bne :M6 * NOW AT 1/2 NIBBLES * * INSTEAD OF COMPARING AGAINST A TABLE * THE DATA READ FROM THE DISK CAN BE * USED IN YOUR PROGRAM. BE CAREFUL * WHEN MODIFYING THIS PART OF THE CODE. * KEEP THE CYCLE COUNTS CONSTANT. ldy #7 :M7 lda $C08C,X ; READ DISK DATA bpl :M7 cmp (NPTR),Y ; COMPARE AGAINST TABLE bne :LSFAIL1 dey bpl :M7 bmi :GOOD :LSFAIL jmp :LSFAIL1 * A O K :GOOD eor #$79!$FC iny ldx #6 dex sta $C000,x sta (smclo),y dex sta $C000,x eor #$ED sta $239 eor #$23 sta $4E jmp yippee * FAILED, try again :LSFAIL1 ldy #-1 tya dec LSRETRY beq :GOOD jmp :AGAIN :NIBS db $FC,$EE,$EE,$FC db $E7,$EE,$FC,$E7 *------------------------------------------------- * * Read address mark * RADR16 ldy #$FD ;READ ADR HDR sty MEM1 tya eor #REDFLAG79!$FD sta smclo :RA1 iny bne :RA2 inc MEM1 beq :RAEXIT :RA2 lda $C08C,X bpl :RA2 :RA3 cmp #$D5 bne :RA1 nop :RA4 lda $C08C,X bpl :RA4 cmp #$AA bne :RA3 ldy #3 :RA5 lda $C08C,X bpl :RA5 cmp #$96 bne :RA3 lda #0 :RA6 sta MEM2 :RA7 lda $C08C,X bpl :RA7 rol sta MEM1 :RA8 lda $C08C,X bpl :RA8 and MEM1 sta HDRC,Y eor MEM2 dey bpl :RA6 tay nop clc rts :RAEXIT sec ]rts rts oscsh sec jsr $FE1F bcs * jsr $1000 jmp ($FFFC) *------------------------------------------------- yippee ldx SLOT lda $C061 bpl ]rts lda $C062 bpl ]rts lda $C000 bpl ]rts bit $C010 sta :cmp+1 ldy #-3 :loop iny iny iny lda :dispatch,y beq ]rts :cmp cmp #$11 bne :loop lda :dispatch+1,y sta 0 lda :dispatch+2,y sta 1 bit $C081 lda $C088,x jmp (0) :dispatch hex FF da oscsh asc "!" da rcmess hex 8D da confusion asc "@" da rotcube asc "^" da drive db 0 *------------------------------------------------- * * motorcycle disk drive * drive lda $C089,x ;drive back on! :loop lda $C087,x lda $C080,x jsr :delay lda $C085,x lda $C086,x jsr :delay lda $C083,x lda $C084,x jsr :delay lda $C081,x lda $C082,x jsr :delay jmp :loop :delay lda #6 sta 0 :del2 bit $C070 nop nop bit $C064 bmi *-3 dec 0 bne :del2 rts *------------------------------------------------- rotcube mainYoffset = 46 ;(192-60)/2 botYoffset = 72 mainXoffset = 68 ;(280-144)/2 color = $E4 page = $E6 dum 0 index ds 1 ysave ds 1 yadd ds 1 yoffset ds 1 dend *------------------------------------------------- rotcube jsr $f3e2 ;hgr jsr $f3d8 ;hgr2 lda #1 sta yadd sta yoffset * Draw on page not showing: mainloop lda page eor #$60 sta page ldx #$7F jsr draw * If not a //c, then wait for vbl lda $FBC0 beq :is2c lda $C019 bpl *-3 lda $C019 bmi *-3 :is2c * Now display that page bit $C054 lda page cmp #$20 beq *+5 bit $C055 * Now erase old image from last page eor #$60 sta :smc0+2 sta :smc1+2 ldx #$20 lda #0 :loop tay :smc0 sta $2000,y :smc1 sta $2080,y iny bpl :smc0 inc :smc0+2 inc :smc1+2 dex bne :loop inc index jmp mainloop *------------------------------------------------- draw stx color ldy #12-1 :drawloop lda drawlist,y sty ysave pha and #15 jsr getpoint tax tya ldy #0 jsr $f457 ;plot pla lsr lsr lsr lsr jsr getpoint ldx #0 jsr $f53a ;lineto ldy ysave dey bpl :drawloop lda yoffset clc adc yadd bne :not0 inc yadd ;make +1 inc yadd :not0 cmp #191-48-botYoffset bcc :0 dec yadd ;make -1 dec yadd :0 sta yoffset rts *------------------------------------------------- * * given a = point number, return a = xcoor, y = ycoor * getpoint tay * Get index into tables asl ;*16 asl asl asl adc index and #$3F tax tya and #4 ;bottom? cmp #4 * Compute ycoor lda ydata,x bcc :not_bot adc #botYoffset-1 :not_bot adc yoffset tay * Compute xcoor lda xdata,x adc #mainXoffset rts *------------------------------------------------- drawlist hex 01122330 ;draw top hex 45566774 ;draw bottom hex 04152637 ;draw connecting lines xdata hex 908F8E8C8A87837F7A757069635C564F hex 484039332C261F1A15100C0805030100 hex 0000010305080C10151A1F262C333940 hex 474F565C636970757A7F83878A8C8E8F ydata hex 181A1C1E21232527282A2B2D2E2E2F2F hex 2F2F2F2E2E2D2B2A28272523211E1C1A hex 181513110E0C0A080705040201010000 hex 000000010102040507080A0C0E111315 *------------------------------------------------- confusion dum 0 xr ds 1 yr ds 1 randseed ds 1 temp ds 1 dend hgr2 = $F3D8 plot = $F457 hcolor = $F6F0 * Confusion triangle confusion lda #$7F sta $E4 ;hcolor=3 jsr hgr2 * xr=xarray(0), yr=yarray(0) ldx xarray ldy yarray stx xr sty yr * Plot that dot :loop lda $C000 bpl :nokey bit $C010 cmp #$E0 bcc *+4 and #$DF cmp #"C" bne :nokey :randcol jsr getrandcol sta temp jsr $F3F4 ;clear to that color :randloop jsr getrandcol tax eor temp bmi :randloop ;different hi bits cpx temp ;same color beq :randloop :nokey ldy #0 lda xr asl tax bcc :skip iny :skip lda yr jsr plot lda yr ldx $E0 ldy $E1 inx bne *+3 iny jsr plot * Get a random number between 0-2 jsr random sec :sub30 sbc #30 bcs :sub30 adc #30 sec :sub3 sbc #3 bcs :sub3 adc #3 tax *----------- * xr stuff: * determine which midpoint routine to use lda xarray,x cmp xr bge :xarr_xr * If xarray(rand) < xr then: * xr = xarray + ( xr - xarray) / 2 lda xr sec sbc xarray,x lsr clc adc xarray,x jmp :sta_xr * If xarray(rand) >= xr then: * xr = xr + ( xarray - xr ) / 2 :xarr_xr lda xarray,x sec sbc xr lsr clc adc xr :sta_xr sta xr *----------- * yr stuff: * determine which midpoint routine to use lda yarray,x cmp yr bge :yarr_yr * If yarray(rand) < yr then: * yr = yarray + ( yr - yarray) / 2 lda yr sec sbc yarray,x lsr clc adc yarray,x jmp :sta_yr * If yarray(rand) >= yr then: * yr = yr + ( yarray - yr ) / 2 :yarr_yr lda yarray,x sec sbc yr lsr clc adc yr :sta_yr sta yr jmp :loop xarray db 70,139,0 yarray db 0,191,191 random lda randseed adc #$23 sta randseed eor $C020 ;a little randomness rts getrandcol jsr random and #7 tax jmp hcolor *------------------------------------------------- rcmess rcmess ldy #0 :0 lda :text,y beq :lores jsr $FDF0 iny bne :0 :lores bit $c000 bpl :lores sta $c00d ;80 col sta $c001 ;80 store bit $c056 bit $c052 bit $c050 bit $c05e ;merez :loop lda #$FF jsr :random sta $30 ;color lda #80 ;max x jsr :random lsr tay bit $c054 bcs *+5 bit $c055 lda #48 ;max y jsr :random jsr $F800 ;plot jmp :loop :random sta 1 lda 0 adc #$23 sta 0 eor $C020 cmp 1 bcc :ok :loop2 sbc 1 bcs :loop2 adc 1 :ok rts :text hex 8d8d asc "8/25/89",8d8d8d asc "Robert!",8d8d8d asc "Jordan and Roland wish you the very",8d8d asc "Brightest College Years.",8d8d8d8d8d asc " meres !",8d,8d asc " meres !",8d,8d asc " meres !" brk *------------------------------------------------- EOF lst on da * lst off \ No newline at end of file +* boot +org = $800 + lst off + xc off + +REDFLAG79 = $23B ; in aux mem! + +*------------------------------- +* $800 TS (0,0) boot sector + +SLOT = $2b +sector = $50 + +text = $fb2f +home = $fc58 +vtab = $FB5B +cout = $FDF0 +normal = $fe84 +pr0 = $fe93 +in0 = $fe89 + +*------------------------------- + +smclo = $4E +smchi = $4F + +rw18 = $d000 + +slot = $fd +track = $fe +lastrack = $ff + + dum $00 + +dest ds 2 +source ds 2 +endsourc ds 2 + + dend + +*------------------------------------------------- + + org org + + hex 01 + +entry lda #$60 + sta entry + + lda #MAKEBIT + sta smclo + + ldx #$ff + stx $4fb + stx $3f3 + stx $3f4 + stx $7831 + stx $c000 ;80store off + stx $c002 ;RAMRD main + stx $9fd8 + stx $c004 ;RAMWRT main + stx $c00c ;80col off + stx $c00e ;Altcharset off + stx $c081 ;write RAM, read ROM (2nd 4k bank) + txs + jsr text + jsr home + jsr normal + jsr pr0 + sta $DF35 + jsr in0 + stx $8492 + + ldx SLOT + txa + lsr + lsr + lsr + lsr + ora #$c0 + sta :rdsect+2 + lda #$0f + sta sector + +:0 ldy sector + lda skewtbl,y + sta $3d + lda sectaddr,y + beq :1 + sta $27 + + inc $9fd8 + +:rdsect jsr $005c +:1 dec sector + bne :0 + + beq decode + +skewtbl hex 00,0d,0b,09,07,05,03,01 + hex 0e,0c,0a,08,06,04,02,0f + +sectaddr hex 00,09,0a,0b,00,0c,0d,0e + hex 30,31,32,33,34,10,11,2f + +decode ldx #14 +:loop lda sectaddr,x + beq :nope + + sta :smc0+2 + sta :smc1+2 + + ldy #0 +:loop1 +:smc0 lda $FF00,y + eor $2F00,y +:smc1 sta $FF00,y + eor $7831 ;bogus garbage + sta $7831 ; " " " " + sta $3C + iny + bne :loop1 + +:nope dex + bpl :loop + + ldx SLOT + +stage2 stx slot + + jsr check128k ;check for 128K memory + + jsr moverw18 ;& move RW18 to D000 + + lda #0 + sta lastrack + + jsr rw18 + hex 07,a9 ;Bbund ID byte + + jsr rw18 + hex 00,01,00 ;drive 1 on + + jsr rw18 ;seek track 1 + hex 02,00,01 + +* load & run stage 3 boot +* from drive 1 + + jsr rw18 + hex c3,ee + + jmp $ee00 + +*------------------------------------------------- +* Check for AUX memory routine + +CHECKER lda #$EE + sta $C005 + lda #>MAKEBIT + sta smchi + sta $C003 + sta $0800 + lda $0C00 + cmp #$EE + bne :0 + asl $0C00 + lda $0800 + cmp $0C00 + beq :1 +:0 clc +:1 sta $C004 + sta $C002 + rts + +CHECKEND = *-CHECKER + +*------------------------------------------------- +* +* Check to make sure //c or //e +* with 128k +* +*------------------------------- + + hex 34 + hex 55 + hex 99 + +check128k + sta $c081 + + lda $FBB3 ;Apple // family ID byte + cmp #6 + bne NOT128K ;Must be e/c/GS + + bit $C017 + bmi NOT128K + + ldx #CHECKEND +:0 lda CHECKER,X + sta $180,X + dex + bpl :0 + + jsr $180 + bcs NOT128K + + rts + +*------------------------------- +* Turn off drive and display message + +NOT128K ldx SLOT + lda $C088,X + + jsr text + jsr home + lda #8 + jsr vtab + + ldy #0 +:0 lda MEMTEXT,Y + beq * + jsr cout + cmp #$8D + bne :1 + lda #4 + sta $24 +:1 iny + bne :0 + +MEMTEXT hex 8D + asc "REQUIRES A //C OR //E WITH 128K" + hex 00 + +*------------------------------- +* Move RW18 +* d0 < 30.40 +*------------------------------- +moverw18 + bit $c08b + bit $c08b ;rd/wrt RAM, 1st 4k bank + + lda #$d0 + ldx #$30 + ldy #$40 + +* 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 + lda #$24 + sta (smclo),y + 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 + +MAKEBIT rts + hex FF + +*------------------------------------------------- +* +* HLS APPLE COPY PROTECTION +* COPYRIGHT (C) 1987 HLS DUPLICATION +* +* CONTACT ROBERT FREEDMAN 408-773-1300 +* IF THERE ARE QUESTIONS ABOUT USE OF +* THIS CODE +* +* EXIT clc IF A O K +* sec IF PIRATE +* +*------------------------------------------------- + +OBJSCT = $07 ;PHYSICAL SECTOR # + +* ZERO PAGE +* IF THIS CONFLICTS WITH YOUR CODE +* CHANGE THE FOLLOWING ZERO PAGE +* LOCATIONS, OR USE THE SAVE ZERO +* PAGE ROUTINE + +HDRC = $F0 +HDRS = HDRC+1 +HDRT = HDRC+2 +HDRV = HDRC+3 HEADER SECTOR +LSRETRY = HDRC+4 ;NIB READ RETRIES +PRETRY = HDRC+5 ;OBJSCT RETRIES +NPTR = HDRC+6 +NPTRH = HDRC+7 +MEM1 = HDRC+8 +MEM2 = HDRC+9 + +*------------------------------------------------- + +CheckCP + lda #10 + sta LSRETRY + lda #>REDFLAG79 + sta smchi + ldx SLOT + lda $C089,X + lda $C08E,X + lda #:NIBS ; !!!!! LOW BYTE + sta NPTR + lda #>:NIBS ; !!!!! HIGH BYTE + sta NPTRH +:AGAIN lda #$80 + sta PRETRY +:M1 dec PRETRY + beq :LSFAIL + jsr RADR16 + bcs :LSFAIL + lda HDRS + cmp #OBJSCT + bne :M1 + + ldy #0 +:M2 lda $C08C,X + bpl :M2 + dey + beq :LSFAIL + cmp #$D5 + bne :M2 + ldy #0 + +:M3 lda $C08C,X + bpl :M3 + dey + beq :LSFAIL + cmp #$E7 + bne :M3 + +:M4 lda $C08C,X + bpl :M4 + cmp #$E7 + bne :LSFAIL + +:M5 lda $C08C,X + bpl :M5 + cmp #$E7 + bne :LSFAIL + + lda $C08D,X + ldy #$10 + bit $6 ;3 US. ( FOR //C) +:M6 lda $C08C,X + bpl :M6 + dey + beq :LSFAIL + cmp #$EE + bne :M6 + +* NOW AT 1/2 NIBBLES +* +* INSTEAD OF COMPARING AGAINST A TABLE +* THE DATA READ FROM THE DISK CAN BE +* USED IN YOUR PROGRAM. BE CAREFUL +* WHEN MODIFYING THIS PART OF THE CODE. +* KEEP THE CYCLE COUNTS CONSTANT. + + ldy #7 +:M7 lda $C08C,X ; READ DISK DATA + bpl :M7 + cmp (NPTR),Y ; COMPARE AGAINST TABLE + bne :LSFAIL1 + dey + bpl :M7 + bmi :GOOD + +:LSFAIL jmp :LSFAIL1 + +* A O K + +:GOOD eor #$79!$FC + iny + ldx #6 + dex + sta $C000,x + sta (smclo),y + dex + sta $C000,x + eor #$ED + sta $239 + eor #$23 + sta $4E + + jmp yippee + +* FAILED, try again + +:LSFAIL1 ldy #-1 + tya + dec LSRETRY + beq :GOOD + jmp :AGAIN + +:NIBS db $FC,$EE,$EE,$FC + db $E7,$EE,$FC,$E7 + +*------------------------------------------------- +* +* Read address mark +* + +RADR16 ldy #$FD ;READ ADR HDR + sty MEM1 + tya + eor #REDFLAG79!$FD + sta smclo +:RA1 iny + bne :RA2 + inc MEM1 + beq :RAEXIT +:RA2 lda $C08C,X + bpl :RA2 +:RA3 cmp #$D5 + bne :RA1 + nop +:RA4 lda $C08C,X + bpl :RA4 + cmp #$AA + bne :RA3 + ldy #3 +:RA5 lda $C08C,X + bpl :RA5 + cmp #$96 + bne :RA3 + lda #0 +:RA6 sta MEM2 +:RA7 lda $C08C,X + bpl :RA7 + rol + sta MEM1 +:RA8 lda $C08C,X + bpl :RA8 + and MEM1 + sta HDRC,Y + eor MEM2 + dey + bpl :RA6 + tay + nop + clc + rts + +:RAEXIT sec +]rts rts + +oscsh sec + jsr $FE1F + bcs * + + jsr $1000 + + jmp ($FFFC) + +*------------------------------------------------- + +yippee ldx SLOT + lda $C061 + bpl ]rts + lda $C062 + bpl ]rts + lda $C000 + bpl ]rts + bit $C010 + sta :cmp+1 + + ldy #-3 +:loop iny + iny + iny + lda :dispatch,y + beq ]rts +:cmp cmp #$11 + bne :loop + + lda :dispatch+1,y + sta 0 + lda :dispatch+2,y + sta 1 + + bit $C081 + lda $C088,x + + jmp (0) + +:dispatch hex FF + da oscsh + + asc "!" + da rcmess + + hex 8D + da confusion + + asc "@" + da rotcube + + asc "^" + da drive + + db 0 + +*------------------------------------------------- +* +* motorcycle disk drive +* + +drive lda $C089,x ;drive back on! + +:loop lda $C087,x + lda $C080,x + jsr :delay + lda $C085,x + lda $C086,x + jsr :delay + lda $C083,x + lda $C084,x + jsr :delay + lda $C081,x + lda $C082,x + jsr :delay + jmp :loop + +:delay lda #6 + sta 0 + +:del2 bit $C070 + nop + nop + bit $C064 + bmi *-3 + + dec 0 + bne :del2 + rts + +*------------------------------------------------- rotcube + +mainYoffset = 46 ;(192-60)/2 +botYoffset = 72 +mainXoffset = 68 ;(280-144)/2 + +color = $E4 +page = $E6 + + dum 0 +index ds 1 +ysave ds 1 +yadd ds 1 +yoffset ds 1 + dend + +*------------------------------------------------- + +rotcube jsr $f3e2 ;hgr + jsr $f3d8 ;hgr2 + + lda #1 + sta yadd + + sta yoffset + +* Draw on page not showing: + +mainloop lda page + eor #$60 + sta page + ldx #$7F + jsr draw + +* If not a //c, then wait for vbl + + lda $FBC0 + beq :is2c + lda $C019 + bpl *-3 + lda $C019 + bmi *-3 +:is2c + +* Now display that page + + bit $C054 + lda page + cmp #$20 + beq *+5 + bit $C055 + +* Now erase old image from last page + + eor #$60 + sta :smc0+2 + sta :smc1+2 + ldx #$20 + lda #0 +:loop tay +:smc0 sta $2000,y +:smc1 sta $2080,y + iny + bpl :smc0 + inc :smc0+2 + inc :smc1+2 + dex + bne :loop + + inc index + jmp mainloop + +*------------------------------------------------- + +draw stx color + + ldy #12-1 +:drawloop lda drawlist,y + sty ysave + + pha + and #15 + jsr getpoint + + tax + tya + ldy #0 + jsr $f457 ;plot + + pla + lsr + lsr + lsr + lsr + jsr getpoint + ldx #0 + jsr $f53a ;lineto + + ldy ysave + dey + bpl :drawloop + + lda yoffset + clc + adc yadd + bne :not0 + + inc yadd ;make +1 + inc yadd + +:not0 cmp #191-48-botYoffset + bcc :0 + + dec yadd ;make -1 + dec yadd + +:0 sta yoffset + rts + +*------------------------------------------------- +* +* given a = point number, return a = xcoor, y = ycoor +* + +getpoint tay + +* Get index into tables + + asl ;*16 + asl + asl + asl + adc index + and #$3F + tax + tya + + and #4 ;bottom? + cmp #4 + +* Compute ycoor + + lda ydata,x + bcc :not_bot + adc #botYoffset-1 + +:not_bot adc yoffset + tay + +* Compute xcoor + + lda xdata,x + adc #mainXoffset + rts + +*------------------------------------------------- + +drawlist hex 01122330 ;draw top + hex 45566774 ;draw bottom + hex 04152637 ;draw connecting lines + +xdata hex 908F8E8C8A87837F7A757069635C564F + hex 484039332C261F1A15100C0805030100 + hex 0000010305080C10151A1F262C333940 + hex 474F565C636970757A7F83878A8C8E8F + +ydata hex 181A1C1E21232527282A2B2D2E2E2F2F + hex 2F2F2F2E2E2D2B2A28272523211E1C1A + hex 181513110E0C0A080705040201010000 + hex 000000010102040507080A0C0E111315 + +*------------------------------------------------- confusion + + dum 0 +xr ds 1 +yr ds 1 +randseed ds 1 +temp ds 1 + dend + +hgr2 = $F3D8 +plot = $F457 +hcolor = $F6F0 + +* Confusion triangle + +confusion lda #$7F + sta $E4 ;hcolor=3 + + jsr hgr2 + +* xr=xarray(0), yr=yarray(0) + + ldx xarray + ldy yarray + stx xr + sty yr + +* Plot that dot + +:loop lda $C000 + bpl :nokey + bit $C010 + cmp #$E0 + bcc *+4 + and #$DF + cmp #"C" + bne :nokey + +:randcol jsr getrandcol + sta temp + jsr $F3F4 ;clear to that color + +:randloop jsr getrandcol + tax + eor temp + bmi :randloop ;different hi bits + cpx temp ;same color + beq :randloop + +:nokey ldy #0 + lda xr + asl + tax + bcc :skip + iny +:skip lda yr + jsr plot + + lda yr + ldx $E0 + ldy $E1 + inx + bne *+3 + iny + jsr plot + +* Get a random number between 0-2 + + jsr random + sec +:sub30 sbc #30 + bcs :sub30 + adc #30 + sec +:sub3 sbc #3 + bcs :sub3 + adc #3 + tax + +*----------- +* xr stuff: +* determine which midpoint routine to use + + lda xarray,x + cmp xr + bge :xarr_xr + +* If xarray(rand) < xr then: +* xr = xarray + ( xr - xarray) / 2 + + lda xr + sec + sbc xarray,x + lsr + clc + adc xarray,x + jmp :sta_xr + +* If xarray(rand) >= xr then: +* xr = xr + ( xarray - xr ) / 2 + +:xarr_xr lda xarray,x + sec + sbc xr + lsr + clc + adc xr +:sta_xr sta xr + +*----------- +* yr stuff: +* determine which midpoint routine to use + + lda yarray,x + cmp yr + bge :yarr_yr + +* If yarray(rand) < yr then: +* yr = yarray + ( yr - yarray) / 2 + + lda yr + sec + sbc yarray,x + lsr + clc + adc yarray,x + jmp :sta_yr + +* If yarray(rand) >= yr then: +* yr = yr + ( yarray - yr ) / 2 + +:yarr_yr lda yarray,x + sec + sbc yr + lsr + clc + adc yr +:sta_yr sta yr + + jmp :loop + +xarray db 70,139,0 +yarray db 0,191,191 + +random lda randseed + adc #$23 + sta randseed + eor $C020 ;a little randomness + rts + +getrandcol jsr random + and #7 + tax + jmp hcolor + +*------------------------------------------------- rcmess + +rcmess ldy #0 +:0 lda :text,y + beq :lores + jsr $FDF0 + iny + bne :0 + +:lores bit $c000 + bpl :lores + + sta $c00d ;80 col + sta $c001 ;80 store + bit $c056 + bit $c052 + bit $c050 + bit $c05e ;merez + +:loop lda #$FF + jsr :random + sta $30 ;color + + lda #80 ;max x + jsr :random + lsr + tay + bit $c054 + bcs *+5 + bit $c055 + + lda #48 ;max y + jsr :random + + jsr $F800 ;plot + + jmp :loop + +:random sta 1 + + lda 0 + adc #$23 + sta 0 + eor $C020 + + cmp 1 + bcc :ok +:loop2 sbc 1 + bcs :loop2 + adc 1 + +:ok rts + +:text hex 8d8d + asc "8/25/89",8d8d8d + asc "Robert!",8d8d8d + asc "Jordan and Roland wish you the very",8d8d + asc "Brightest College Years.",8d8d8d8d8d + asc " meres !",8d,8d + asc " meres !",8d,8d + asc " meres !" + brk + +*------------------------------------------------- EOF + + lst on + da * + lst off diff --git a/02 POP Disk Routines/CP.525/PURPLE.MAIN.S b/02 POP Disk Routines/CP.525/PURPLE.MAIN.S index 3128ef6..bb99f5c 100755 --- a/02 POP Disk Routines/CP.525/PURPLE.MAIN.S +++ b/02 POP Disk Routines/CP.525/PURPLE.MAIN.S @@ -1 +1,211 @@ -* purple.main lst off * The job of this routine is to set $DA to $01 * ( in aux-zpage!!! ) slot = $FD *------------------------------------------------- * * HLS APPLE COPY PROTECTION * COPYRIGHT (C) 1987 HLS DUPLICATION * * HLS 408-773-1500 * * Modified by Roland Gustafsson 8/25/89 * for Prince of Persia copy protection. * *------------------------------------------------- * ZERO PAGE OBJSCT = $07 ;PHYSICAL SECTOR # HDRC = $40 HDRS = HDRC+1 HDRT = HDRC+2 HDRV = HDRC+3 HEADER SECTOR LSRETRY = HDRC+4 ;NIB READ RETRIES PRETRY = HDRC+5 ;OBJSCT RETRIES NPTR = HDRC+6 NPTRH = HDRC+7 MEM1 = HDRC+8 MEM2 = HDRC+9 zpage = HDRC zpagelen = 13 *------------------------------------------------- * * Here is the code that ends up at $6321. * Assemble it and run "make.purple.hex" which * reverses the code and puts it in a text file. * *------------------------------------------------- org $2000 da len6321 dum $6254 zpagebuf ds zpagelen dend org $6321 strt6321 jsr swapzpage lda #10 sta LSRETRY ldx slot lda $C089,X lda $C08E,X lda #:NIBS ; !!!!! LOW BYTE sta NPTR lda #>:NIBS ; !!!!! HIGH BYTE sta NPTRH :AGAIN lda #$80 sta PRETRY :M1 dec PRETRY beq :LSFAIL jsr RADR16 bcs :LSFAIL lda HDRS cmp #OBJSCT bne :M1 ldy #0 :M2 lda $C08C,X bpl :M2 dey beq :LSFAIL cmp #$D5 bne :M2 ldy #0 :M3 lda $C08C,X bpl :M3 dey beq :LSFAIL cmp #$E7 bne :M3 :M4 lda $C08C,X bpl :M4 cmp #$E7 bne :LSFAIL :M5 lda $C08C,X bpl :M5 cmp #$E7 bne :LSFAIL lda $C08D,X ldy #$10 bit $6 ;3 US. ( FOR //C) :M6 lda $C08C,X bpl :M6 dey beq :LSFAIL cmp #$EE bne :M6 * NOW AT 1/2 NIBBLES ldy #7 :M7 lda $C08C,X * READ DISK DATA bpl :M7 cmp (NPTR),Y * COMPARE AGAINST TABLE bne :LSFAIL dey bpl :M7 bmi :GOOD :LSFAIL jmp :LSFAIL1 * A O K :GOOD jsr swapzpage lda #0 sta $C009-zpagelen,x rol sta $DA-zpagelen,x sta $C008-zpagelen,x clc rts * FAILED :LSFAIL1 dec LSRETRY beq :ERROR jmp :AGAIN :NIBS db $FC,$EE,$EE,$FC db $E7,$EE,$FC,$E7 * Note that drive motor is still on :ERROR swapzpage ldx #0 :0 ldy zpagebuf,x lda zpage,x sty zpage,x sta zpagebuf,x inx cpx #zpagelen bne :0 rts *------------------------------------------------- * * Read address mark * RADR16 ldy #$FD ;READ ADR HDR sty MEM1 :RA1 iny bne :RA2 inc MEM1 beq :RAEXIT :RA2 lda $C08C,X bpl :RA2 :RA3 cmp #$D5 bne :RA1 nop :RA4 lda $C08C,X bpl :RA4 cmp #$AA bne :RA3 ldy #3 :RA5 lda $C08C,X bpl :RA5 cmp #$96 bne :RA3 lda #0 :RA6 sta MEM2 :RA7 lda $C08C,X bpl :RA7 rol sta MEM1 :RA8 lda $C08C,X bpl :RA8 and MEM1 sta HDRC,Y eor MEM2 dey bpl :RA6 tay nop clc rts :RAEXIT sec rts len6321 = *-strt6321 org *------------------------------------------------- EOF sav purple.main \ No newline at end of file +* purple.main + + lst off + +* The job of this routine is to set $DA to $01 +* ( in aux-zpage!!! ) + +slot = $FD + +*------------------------------------------------- +* +* HLS APPLE COPY PROTECTION +* COPYRIGHT (C) 1987 HLS DUPLICATION +* +* HLS 408-773-1500 +* +* Modified by Roland Gustafsson 8/25/89 +* for Prince of Persia copy protection. +* +*------------------------------------------------- + +* ZERO PAGE + +OBJSCT = $07 ;PHYSICAL SECTOR # + +HDRC = $40 +HDRS = HDRC+1 +HDRT = HDRC+2 +HDRV = HDRC+3 HEADER SECTOR +LSRETRY = HDRC+4 ;NIB READ RETRIES +PRETRY = HDRC+5 ;OBJSCT RETRIES +NPTR = HDRC+6 +NPTRH = HDRC+7 +MEM1 = HDRC+8 +MEM2 = HDRC+9 + +zpage = HDRC +zpagelen = 13 + +*------------------------------------------------- +* +* Here is the code that ends up at $6321. +* Assemble it and run "make.purple.hex" which +* reverses the code and puts it in a text file. +* +*------------------------------------------------- + + org $2000 + + da len6321 + + dum $6254 +zpagebuf ds zpagelen + dend + + org $6321 + +strt6321 jsr swapzpage + lda #10 + sta LSRETRY + ldx slot + lda $C089,X + lda $C08E,X + lda #:NIBS ; !!!!! LOW BYTE + sta NPTR + lda #>:NIBS ; !!!!! HIGH BYTE + sta NPTRH +:AGAIN lda #$80 + sta PRETRY +:M1 dec PRETRY + beq :LSFAIL + jsr RADR16 + bcs :LSFAIL + lda HDRS + cmp #OBJSCT + bne :M1 + + ldy #0 +:M2 lda $C08C,X + bpl :M2 + dey + beq :LSFAIL + cmp #$D5 + bne :M2 + ldy #0 + +:M3 lda $C08C,X + bpl :M3 + dey + beq :LSFAIL + cmp #$E7 + bne :M3 + +:M4 lda $C08C,X + bpl :M4 + cmp #$E7 + bne :LSFAIL + +:M5 lda $C08C,X + bpl :M5 + cmp #$E7 + bne :LSFAIL + + lda $C08D,X + ldy #$10 + bit $6 ;3 US. ( FOR //C) +:M6 lda $C08C,X + bpl :M6 + dey + beq :LSFAIL + cmp #$EE + bne :M6 + +* NOW AT 1/2 NIBBLES + + ldy #7 +:M7 lda $C08C,X * READ DISK DATA + bpl :M7 + cmp (NPTR),Y * COMPARE AGAINST TABLE + bne :LSFAIL + dey + bpl :M7 + bmi :GOOD +:LSFAIL jmp :LSFAIL1 + +* A O K + +:GOOD jsr swapzpage + lda #0 + sta $C009-zpagelen,x + rol + sta $DA-zpagelen,x + sta $C008-zpagelen,x + clc + rts + +* FAILED + +:LSFAIL1 dec LSRETRY + beq :ERROR + jmp :AGAIN + +:NIBS db $FC,$EE,$EE,$FC + db $E7,$EE,$FC,$E7 + +* Note that drive motor is still on + +:ERROR +swapzpage ldx #0 +:0 ldy zpagebuf,x + lda zpage,x + sty zpage,x + sta zpagebuf,x + inx + cpx #zpagelen + bne :0 + rts + +*------------------------------------------------- +* +* Read address mark +* + +RADR16 ldy #$FD ;READ ADR HDR + sty MEM1 +:RA1 iny + bne :RA2 + inc MEM1 + beq :RAEXIT +:RA2 lda $C08C,X + bpl :RA2 +:RA3 cmp #$D5 + bne :RA1 + nop +:RA4 lda $C08C,X + bpl :RA4 + cmp #$AA + bne :RA3 + ldy #3 +:RA5 lda $C08C,X + bpl :RA5 + cmp #$96 + bne :RA3 + lda #0 +:RA6 sta MEM2 +:RA7 lda $C08C,X + bpl :RA7 + rol + sta MEM1 +:RA8 lda $C08C,X + bpl :RA8 + and MEM1 + sta HDRC,Y + eor MEM2 + dey + bpl :RA6 + tay + nop + clc + rts + +:RAEXIT sec + rts + +len6321 = *-strt6321 + + org + +*------------------------------------------------- EOF + + sav purple.main diff --git a/02 POP Disk Routines/CP.525/PURPLE.S b/02 POP Disk Routines/CP.525/PURPLE.S index b012915..451870c 100755 --- a/02 POP Disk Routines/CP.525/PURPLE.S +++ b/02 POP Disk Routines/CP.525/PURPLE.S @@ -1 +1,63 @@ -* purple (put this file!!!) * This code sets $DA in aux mem to 1 * if signature is found on track zero. PURPrun = $6321 PURPLE ldy #PURPrun lda #>PURPrun jsr PURPsub jsr PURPjmp * Note: first byte of next junk must be $60 (rts) *------------------------------------------------- PURPcode hex 60386018EAA8E7108849450040994825 hex FB10C08CBD48852AFB10C08CBD498500 hex A9E7D096C9FB10C08CBD03A0F2D0AAC9 hex FB10C08CBDEAF0D0D5C9FB10C08CBD3D hex F048E604D0C84884FDA060F1D00DE0E8 hex 62549D409440B56254BC00A2E7FCEEE7 hex FCEEEEFC63384C0BF044C66018BFFB9D hex CD952ABFFC9D00A963BE2063AF4C0330 hex F4108805D046D1FB10C08CBD07A0F4D0 hex EEC914F088FB10C08CBD062410A0C08D hex BD23D0E7C9FB10C08CBD2CD0E7C9FB10 hex C08CBDF4D0E7C939F088FB10C08CBD00 hex A0F4D0D5C947F088FB10C08CBD00A0F1 hex D007C941A557B063D0205CF045C64585 hex 80A9478563A94685B6A9C08EBDC089BD hex FDA644850AA963BE20 *------------------------------------------------- PURPlen = *-PURPcode * Routine to decode code hex 20 PURPsub sty 4 sta 5 ldy #0 ldx #PURPlen :0 dex lda PURPcode,x sta (4),y iny bne :0 rts hex 2c PURPjmp jmp (4) *------------------------------------------------- EOF \ No newline at end of file +* purple (put this file!!!) + +* This code sets $DA in aux mem to 1 +* if signature is found on track zero. + +PURPrun = $6321 + +PURPLE + ldy #PURPrun + lda #>PURPrun + + jsr PURPsub + jsr PURPjmp + +* Note: first byte of next junk must be $60 (rts) +*------------------------------------------------- + +PURPcode + hex 60386018EAA8E7108849450040994825 + hex FB10C08CBD48852AFB10C08CBD498500 + hex A9E7D096C9FB10C08CBD03A0F2D0AAC9 + hex FB10C08CBDEAF0D0D5C9FB10C08CBD3D + hex F048E604D0C84884FDA060F1D00DE0E8 + hex 62549D409440B56254BC00A2E7FCEEE7 + hex FCEEEEFC63384C0BF044C66018BFFB9D + hex CD952ABFFC9D00A963BE2063AF4C0330 + hex F4108805D046D1FB10C08CBD07A0F4D0 + hex EEC914F088FB10C08CBD062410A0C08D + hex BD23D0E7C9FB10C08CBD2CD0E7C9FB10 + hex C08CBDF4D0E7C939F088FB10C08CBD00 + hex A0F4D0D5C947F088FB10C08CBD00A0F1 + hex D007C941A557B063D0205CF045C64585 + hex 80A9478563A94685B6A9C08EBDC089BD + hex FDA644850AA963BE20 + +*------------------------------------------------- + +PURPlen = *-PURPcode + +* Routine to decode code + + hex 20 + +PURPsub + sty 4 + sta 5 + + ldy #0 + + ldx #PURPlen +:0 dex + lda PURPcode,x + sta (4),y + iny + bne :0 + + rts + + hex 2c + +PURPjmp jmp (4) + +*------------------------------------------------- EOF diff --git a/02 POP Disk Routines/CP.525/RYELLOW1.S b/02 POP Disk Routines/CP.525/RYELLOW1.S index 722c84e..2273a83 100755 --- a/02 POP Disk Routines/CP.525/RYELLOW1.S +++ b/02 POP Disk Routines/CP.525/RYELLOW1.S @@ -1 +1,90 @@ -* Ryellow1 (put this file!!!) * This code sets the high bit of $7C in aux mem * if signature is found on track zero. * NOTE: make sure the x register has a number * greater than 4 when calling YELLOW. YELLrun = $AAAA YELLOW :0 sec rol clc rol dex bne :0 sta 4 jsr YELLsub jmp YELLnothing *------------------------------------------------- YELLcode hex 27A26A0C5717236A8AAD0603AA8A3401 hex 03A02F9E0C5717246A03012F9D03E92F hex 9C032A2F9F6C9F5AF68AF8011AFD0F9B hex 63AD7A5B0AAA17266ABA51225AED637F hex 7A5E0AAA17266ABA51225A93634D7A5E hex 17266ABA51634D7A8617266ABA51634D hex 7A8917276A0ABA8EAC17266ABA51225A hex BE63447A5E0AAD17266ABA517B9C7AAF hex 22BA5E9AA9E696018AAD06374215DCF1 hex B2CA6C9E5AA1E66100564444564D4456 hex 4D8AAD06374215CA0A572E92627AAE4C hex 925A9717266ABA51637F7A5A4017266A hex BA5163007A580AA917266ABA51633C7A hex 4D03AA2F9317266ABA51802F9217266A hex BA518F92339AAAEF9322BA4D0240B2CA hex 92CA03AE27620E6F555AFC03AA27670E hex 0F55276F0E9247620E5A9F1AACE3554C hex 553AAEC3546C5567670E3AA907670E63 hex A61AAB02928A440113B3068A5601076F hex 0EB28A5A01138F068A560144670E7A6A hex 8A5601B20F5583A980AF5700172A6A0C hex 57CA08B8607A579243AB7A5CCA08AA16 hex 0E0E1F9A3E9A370E0E424A8B7A5BCAAB hex 9A828E8AB4B7B6B6B6B6B6DA868C88B5 hex B4B7B6B6B6B6B655A9 *------------------------------------------------- YELLlen = *-YELLcode * Routine to decode code hex 20 ;jsr YELLsub sta 5 ldy #0 :0 lda YELLcode,y eor 4 sta (4),y inc 5 lda YELLcode+256,y eor 4 sta (4),y dec 5 iny bne :0 lda 4 eor #$4C!$AA ;jmp instruction sta 3 jmp 3 *------------------------------------------------- hex a9 ;lda #imm YELLnothing ldy #0 inc 5 :0 tya :1 sta (4),y iny bne :1 rts *------------------------------------------------- EOF \ No newline at end of file +* Ryellow1 (put this file!!!) + +* This code sets the high bit of $7C in aux mem +* if signature is found on track zero. + +* NOTE: make sure the x register has a number +* greater than 4 when calling YELLOW. + +YELLrun = $AAAA + +YELLOW +:0 sec + rol + clc + rol + dex + bne :0 + sta 4 + + jsr YELLsub + jmp YELLnothing + +*------------------------------------------------- + +YELLcode + hex 27A26A0C5717236A8AAD0603AA8A3401 + hex 03A02F9E0C5717246A03012F9D03E92F + hex 9C032A2F9F6C9F5AF68AF8011AFD0F9B + hex 63AD7A5B0AAA17266ABA51225AED637F + hex 7A5E0AAA17266ABA51225A93634D7A5E + hex 17266ABA51634D7A8617266ABA51634D + hex 7A8917276A0ABA8EAC17266ABA51225A + hex BE63447A5E0AAD17266ABA517B9C7AAF + hex 22BA5E9AA9E696018AAD06374215DCF1 + hex B2CA6C9E5AA1E66100564444564D4456 + hex 4D8AAD06374215CA0A572E92627AAE4C + hex 925A9717266ABA51637F7A5A4017266A + hex BA5163007A580AA917266ABA51633C7A + hex 4D03AA2F9317266ABA51802F9217266A + hex BA518F92339AAAEF9322BA4D0240B2CA + hex 92CA03AE27620E6F555AFC03AA27670E + hex 0F55276F0E9247620E5A9F1AACE3554C + hex 553AAEC3546C5567670E3AA907670E63 + hex A61AAB02928A440113B3068A5601076F + hex 0EB28A5A01138F068A560144670E7A6A + hex 8A5601B20F5583A980AF5700172A6A0C + hex 57CA08B8607A579243AB7A5CCA08AA16 + hex 0E0E1F9A3E9A370E0E424A8B7A5BCAAB + hex 9A828E8AB4B7B6B6B6B6B6DA868C88B5 + hex B4B7B6B6B6B6B655A9 + +*------------------------------------------------- + +YELLlen = *-YELLcode + +* Routine to decode code + + hex 20 ;jsr + +YELLsub sta 5 + ldy #0 +:0 lda YELLcode,y + eor 4 + sta (4),y + inc 5 + lda YELLcode+256,y + eor 4 + sta (4),y + dec 5 + iny + bne :0 + lda 4 + eor #$4C!$AA ;jmp instruction + sta 3 + jmp 3 + +*------------------------------------------------- + + hex a9 ;lda #imm + +YELLnothing ldy #0 + inc 5 +:0 tya +:1 sta (4),y + iny + bne :1 + rts + + +*------------------------------------------------- EOF diff --git a/02 POP Disk Routines/CP.525/UPDATE.LS.S b/02 POP Disk Routines/CP.525/UPDATE.LS.S index 7f754d1..007120a 100755 --- a/02 POP Disk Routines/CP.525/UPDATE.LS.S +++ b/02 POP Disk Routines/CP.525/UPDATE.LS.S @@ -1 +1,139 @@ - lst off org $300 * * loresshow:0C00.0FFF ($400) * framedata:1000.6BFF ($5C00) * * buffer18 :6C00.7DFF ($1200 one track) * rw18.d000:7E00.82FF ($500 moved to aux ramcard) * BbundID = $AD loresshow = $c00 buffer18 = $6c00 rw18 = $d000 rw18temp = $7e00 slot = $FD track = $FE lastrack = $FF startrack = 12 ;last 6 sectors here * 13,14,15,16,17 (5 full tracks here) errcode = 0 start jsr $e74c ;get slot# txa asl asl asl asl sta $C009 ;aux zpage, ramcard sta slot bit $C083 bit $C083 * Move rw18 to its home ldx #>rw18temp ldy #>rw18 lda #5 jsr movedata * Now we can use rw18 jsr rw18 db 7,BbundID jsr rw18 db 0,5,1 ;drive on jsr rw18 ;seek to startrack db 2,1,startrack * handle special track with jsr rw18 db 3 ;read in original data db >buffer18 lda #1 bcs :error * update last 6 sectors ldx #>loresshow ldy #>buffer18+$C00 lda #6 jsr movedata * write it back out jsr rw18 db 5 ;writesequ db >buffer18 lda #2 bcs :error * write out rest of data... lda #>loresshow+$600 :wloop sta :buf inc track jsr rw18 db 5 ;writesequ :buf db $11 lda #2 bcs :error lda :buf adc #$12 cmp #>loresshow+$600+{5*$1200} bne :wloop lda #0 :error pha jsr rw18 db 1 ;drive off pla sta $C008 bit $C081 sta errcode rts *------------------------------------------------- movedata * * Move data: x:source, y:dest, a:length * movedata stx :src+2 sty :dst+2 tax ldy #0 :loop :src lda $1100,y :dst sta $1100,y iny bne :loop inc :src+2 inc :dst+2 dex bne :loop rts *------------------------------------------------- EOF \ No newline at end of file + lst off + + org $300 + +* +* loresshow:0C00.0FFF ($400) +* framedata:1000.6BFF ($5C00) +* +* buffer18 :6C00.7DFF ($1200 one track) +* rw18.d000:7E00.82FF ($500 moved to aux ramcard) +* + +BbundID = $AD + +loresshow = $c00 +buffer18 = $6c00 + +rw18 = $d000 +rw18temp = $7e00 + +slot = $FD +track = $FE +lastrack = $FF + +startrack = 12 ;last 6 sectors here + +* 13,14,15,16,17 (5 full tracks here) + +errcode = 0 + +start jsr $e74c ;get slot# + txa + asl + asl + asl + asl + + sta $C009 ;aux zpage, ramcard + sta slot + + bit $C083 + bit $C083 + +* Move rw18 to its home + + ldx #>rw18temp + ldy #>rw18 + lda #5 + jsr movedata + +* Now we can use rw18 + + jsr rw18 + db 7,BbundID + + jsr rw18 + db 0,5,1 ;drive on + + jsr rw18 ;seek to startrack + db 2,1,startrack + +* handle special track with + + jsr rw18 + db 3 ;read in original data + db >buffer18 + lda #1 + bcs :error + +* update last 6 sectors + + ldx #>loresshow + ldy #>buffer18+$C00 + lda #6 + jsr movedata + +* write it back out + + jsr rw18 + db 5 ;writesequ + db >buffer18 + lda #2 + bcs :error + +* write out rest of data... + + lda #>loresshow+$600 +:wloop sta :buf + + inc track + + jsr rw18 + db 5 ;writesequ +:buf db $11 + lda #2 + bcs :error + + lda :buf + adc #$12 + cmp #>loresshow+$600+{5*$1200} + bne :wloop + + lda #0 + +:error pha + jsr rw18 + db 1 ;drive off + pla + + sta $C008 + bit $C081 + sta errcode + rts + +*------------------------------------------------- movedata +* +* Move data: x:source, y:dest, a:length +* + +movedata stx :src+2 + sty :dst+2 + tax + + ldy #0 +:loop +:src lda $1100,y +:dst sta $1100,y + iny + bne :loop + + inc :src+2 + inc :dst+2 + + dex + bne :loop + + rts + +*------------------------------------------------- EOF diff --git a/02 POP Disk Routines/CP.525/YELLOW.MAIN.S b/02 POP Disk Routines/CP.525/YELLOW.MAIN.S index 53d4002..0d7ea1a 100755 --- a/02 POP Disk Routines/CP.525/YELLOW.MAIN.S +++ b/02 POP Disk Routines/CP.525/YELLOW.MAIN.S @@ -1 +1,291 @@ -* yellow.main lst off * The job of this routine is to * set the high-bit of $7C in aux zpage. * (It does it by rotating in a carry set) slot = $fd lastrack = $ff *------------------------------------------------- * * HLS APPLE COPY PROTECTION * COPYRIGHT (C) 1987 HLS DUPLICATION * * Modified by Roland Gustafsson 8/25/89 * for Prince of Persia copy protection. * *------------------------------------------------- OBJSCT = $07 ;PHYSICAL SECTOR # * ZERO PAGE HDRC = $30 HDRS = HDRC+1 HDRT = HDRC+2 HDRV = HDRC+3 HEADER SECTOR LSRETRY = HDRC+4 ;NIB READ RETRIES PRETRY = HDRC+5 ;OBJSCT RETRIES NPTR = HDRC+6 NPTRH = HDRC+7 MEM1 = HDRC+8 MEM2 = HDRC+9 zpage = HDRC zpagelen = 33 ;arbitrarily long (only needs 10) *------------------------------------------------- * Jordan says: use $A400-ABFF * Roland says: OK orgCHECK = $AAAA ;must be highbyte=lowbyte org $2000 da lenCHECK dum $A4A4 zpagebuf ds zpagelen was27 ds 3 ;should be 1 !!! was2A ds 5 ; ditto was26 ds 7 ; ditto again dend org orgCHECK *------------------------------------------------- start sta $C008 ;switch to main zpage ldx slot lda $C089,x ;drive on jsr swapzpage * First seek track zero lda #0 jsr SEEK * Now check signature lda #10 sta LSRETRY ldx slot lda $C08E,X lda #>:NIBS sta NPTRH lda #:NIBS sta NPTR :AGAIN lda #$80 sta PRETRY :M1 dec PRETRY beq :LSFAIL jsr RADR16 bcs :LSFAIL lda HDRS cmp #OBJSCT bne :M1 ldy #0 :M2 lda $C08C,X bpl :M2 dey beq :LSFAIL cmp #$D5 bne :M2 ldy #0 :M3 lda $C08C,X bpl :M3 dey beq :LSFAIL cmp #$E7 bne :M3 :M4 lda $C08C,X bpl :M4 cmp #$E7 bne :LSFAIL :M5 lda $C08C,X bpl :M5 cmp #$E7 bne :LSFAIL lda $C08D,X ldy #$10 bit $6 ;3 US. ( FOR //C) :M6 lda $C08C,X bpl :M6 dey beq :LSFAIL cmp #$EE bne :M6 * NOW AT 1/2 NIBBLES ldy #7 :M7 lda $C08C,X * READ DISK DATA bpl :M7 cmp (NPTR),Y * COMPARE AGAINST TABLE bne :LSFAIL dey bpl :M7 bmi :GOOD :LSFAIL jmp :LSFAIL1 * A O K :GOOD jsr swapzpage sta $C009-zpagelen,x ror $7C-zpagelen,x clc rts * FAILED :LSFAIL1 dec LSRETRY beq :ERROR jmp :AGAIN :NIBS db $FC,$EE,$EE,$FC db $E7,$EE,$FC,$E7 :ERROR jsr swapzpage sta $C009-zpagelen,x rts *------------------------------------------------- * * Read address mark * RADR16 ldy #$FD sty MEM1 :RA1 iny bne :RA2 inc MEM1 beq :RAEXIT :RA2 lda $C08C,X bpl :RA2 :RA3 cmp #$D5 bne :RA1 nop :RA4 lda $C08C,X bpl :RA4 cmp #$AA bne :RA3 ldy #3 :RA5 lda $C08C,X bpl :RA5 cmp #$96 bne :RA3 lda #0 :RA6 sta MEM2 :RA7 lda $C08C,X bpl :RA7 rol sta MEM1 :RA8 lda $C08C,X bpl :RA8 and MEM1 sta HDRC,Y eor MEM2 dey bpl :RA6 tay nop clc rts :RAEXIT sec rts *------------------------------------------------- * * SEEK, a - track * SEEK4 lda #4 SEEK sta was2A cmp lastrack beq :RTS0 lda #0 sta was26 :MOVEHEAD lda lastrack sta was27 sec sbc was2A beq :ISTHERE bcs :T0 eor #$FF inc lastrack bcc :T1 :T0 adc #$FE dec lastrack :T1 cmp was26 bcc :T2 lda was26 :T2 cmp #$C bcs :T3 tay :T3 sec jsr :CHKPOS lda ONTBL,Y jsr :MSWAIT lda was27 clc jsr :CHKPOS2 lda OFFTBL,Y jsr :MSWAIT inc was26 bne :MOVEHEAD :ISTHERE jsr :MSWAIT clc :CHKPOS lda lastrack :CHKPOS2 and #3 rol ora slot tax lda $C080,X ldx slot :RTS0 rts :MSWAIT ldx #$12 :T21 dex bne :T21 sec sbc #1 bne :MSWAIT rts *------------------------------------------------- swapzpage ldx #0 :0 ldy zpagebuf,x lda zpage,x sty zpage,x sta zpagebuf,x inx cpx #zpagelen bne :0 rts *------------------------------------------------- ONTBL db $01,$30,$28,$24,$20,$1E,$1D,$1C,$1C,$1C,$1C,$1C OFFTBL db $70,$2C,$26,$22,$1F,$1E,$1D,$1C,$1C,$1C,$1C,$1C,$FF,$03 *------------------------------------------------- lenCHECK = *-orgCHECK org *------------------------------------------------- EOF sav yellow.main \ No newline at end of file +* yellow.main + lst off + +* The job of this routine is to +* set the high-bit of $7C in aux zpage. +* (It does it by rotating in a carry set) + +slot = $fd +lastrack = $ff + +*------------------------------------------------- +* +* HLS APPLE COPY PROTECTION +* COPYRIGHT (C) 1987 HLS DUPLICATION +* +* Modified by Roland Gustafsson 8/25/89 +* for Prince of Persia copy protection. +* +*------------------------------------------------- + +OBJSCT = $07 ;PHYSICAL SECTOR # + +* ZERO PAGE + +HDRC = $30 +HDRS = HDRC+1 +HDRT = HDRC+2 +HDRV = HDRC+3 HEADER SECTOR +LSRETRY = HDRC+4 ;NIB READ RETRIES +PRETRY = HDRC+5 ;OBJSCT RETRIES +NPTR = HDRC+6 +NPTRH = HDRC+7 +MEM1 = HDRC+8 +MEM2 = HDRC+9 + +zpage = HDRC +zpagelen = 33 ;arbitrarily long (only needs 10) + +*------------------------------------------------- + +* Jordan says: use $A400-ABFF +* Roland says: OK + +orgCHECK = $AAAA ;must be highbyte=lowbyte + + org $2000 + + da lenCHECK + + dum $A4A4 +zpagebuf ds zpagelen +was27 ds 3 ;should be 1 !!! +was2A ds 5 ; ditto +was26 ds 7 ; ditto again + dend + + org orgCHECK + +*------------------------------------------------- + +start sta $C008 ;switch to main zpage + + ldx slot + lda $C089,x ;drive on + + jsr swapzpage + +* First seek track zero + + lda #0 + jsr SEEK + +* Now check signature + + lda #10 + sta LSRETRY + ldx slot + lda $C08E,X + lda #>:NIBS + sta NPTRH + lda #:NIBS + sta NPTR + +:AGAIN lda #$80 + sta PRETRY +:M1 dec PRETRY + beq :LSFAIL + jsr RADR16 + bcs :LSFAIL + lda HDRS + cmp #OBJSCT + bne :M1 + + ldy #0 +:M2 lda $C08C,X + bpl :M2 + dey + beq :LSFAIL + cmp #$D5 + bne :M2 + ldy #0 + +:M3 lda $C08C,X + bpl :M3 + dey + beq :LSFAIL + cmp #$E7 + bne :M3 + +:M4 lda $C08C,X + bpl :M4 + cmp #$E7 + bne :LSFAIL + +:M5 lda $C08C,X + bpl :M5 + cmp #$E7 + bne :LSFAIL + + lda $C08D,X + ldy #$10 + bit $6 ;3 US. ( FOR //C) +:M6 lda $C08C,X + bpl :M6 + dey + beq :LSFAIL + cmp #$EE + bne :M6 + +* NOW AT 1/2 NIBBLES + + ldy #7 +:M7 lda $C08C,X * READ DISK DATA + bpl :M7 + cmp (NPTR),Y * COMPARE AGAINST TABLE + bne :LSFAIL + dey + bpl :M7 + bmi :GOOD +:LSFAIL jmp :LSFAIL1 + +* A O K + +:GOOD jsr swapzpage + sta $C009-zpagelen,x + ror $7C-zpagelen,x + clc + rts + +* FAILED + +:LSFAIL1 dec LSRETRY + beq :ERROR + jmp :AGAIN + +:NIBS db $FC,$EE,$EE,$FC + db $E7,$EE,$FC,$E7 + +:ERROR jsr swapzpage + sta $C009-zpagelen,x + rts + +*------------------------------------------------- +* +* Read address mark +* + +RADR16 ldy #$FD + sty MEM1 +:RA1 iny + bne :RA2 + inc MEM1 + beq :RAEXIT +:RA2 lda $C08C,X + bpl :RA2 +:RA3 cmp #$D5 + bne :RA1 + nop +:RA4 lda $C08C,X + bpl :RA4 + cmp #$AA + bne :RA3 + ldy #3 +:RA5 lda $C08C,X + bpl :RA5 + cmp #$96 + bne :RA3 + lda #0 +:RA6 sta MEM2 +:RA7 lda $C08C,X + bpl :RA7 + rol + sta MEM1 +:RA8 lda $C08C,X + bpl :RA8 + and MEM1 + sta HDRC,Y + eor MEM2 + dey + bpl :RA6 + tay + nop + clc + rts + +:RAEXIT sec + rts + +*------------------------------------------------- +* +* SEEK, a - track +* + +SEEK4 lda #4 +SEEK sta was2A + cmp lastrack + beq :RTS0 + lda #0 + sta was26 +:MOVEHEAD lda lastrack + sta was27 + sec + sbc was2A + beq :ISTHERE + bcs :T0 + eor #$FF + inc lastrack + bcc :T1 +:T0 adc #$FE + dec lastrack +:T1 cmp was26 + bcc :T2 + lda was26 +:T2 cmp #$C + bcs :T3 + tay +:T3 sec + jsr :CHKPOS + lda ONTBL,Y + jsr :MSWAIT + lda was27 + clc + jsr :CHKPOS2 + lda OFFTBL,Y + jsr :MSWAIT + inc was26 + bne :MOVEHEAD +:ISTHERE jsr :MSWAIT + clc +:CHKPOS lda lastrack +:CHKPOS2 and #3 + rol + ora slot + tax + lda $C080,X + ldx slot +:RTS0 rts + +:MSWAIT ldx #$12 +:T21 dex + bne :T21 + sec + sbc #1 + bne :MSWAIT + rts + +*------------------------------------------------- + +swapzpage ldx #0 +:0 ldy zpagebuf,x + lda zpage,x + sty zpage,x + sta zpagebuf,x + inx + cpx #zpagelen + bne :0 + rts + +*------------------------------------------------- + +ONTBL db $01,$30,$28,$24,$20,$1E,$1D,$1C,$1C,$1C,$1C,$1C +OFFTBL db $70,$2C,$26,$22,$1F,$1E,$1D,$1C,$1C,$1C,$1C,$1C,$FF,$03 + +*------------------------------------------------- +lenCHECK = *-orgCHECK + + org + +*------------------------------------------------- EOF + + sav yellow.main diff --git a/02 POP Disk Routines/RW1835/DEMOBOOT.S b/02 POP Disk Routines/RW1835/DEMOBOOT.S index 70104a7..ce6775f 100755 --- a/02 POP Disk Routines/RW1835/DEMOBOOT.S +++ b/02 POP Disk Routines/RW1835/DEMOBOOT.S @@ -1 +1,190 @@ - lst off org = $1000 org org *------------------------------------------------- * * 08/01/85 * 07/02/87 mod for 3.5 * * Demo using the 18 sector routines. * * Loads in a double hires picture * from tracks 2,3,4 and 5. * * by Roland Gustafsson * temp0 = $3A temp1 = $3B RW18temp = $2100 RW18 = $D000 slot = $FD track = $FE *------------------------------------------------- * * Move to actual run address * start ldy #0 :0 lda $2000,y sta org,y iny bne :0 jmp :1 * Tell RW18 which slot to use :1 lda $43 sta slot jsr check64k * Turn on the disk drive (It is * already on, but this call is * necessary to initialize the * RW18 routine) LOOP jsr RW18 hex 000100 * Clear hires page jsr hgr * Now seek to track two since that * is where the data starts. jsr RW18 hex 020002 * Display double hires page one sta $C050 sta $C052 sta $C054 sta $C057 sta $C00D sta $C05E sta $C001 * Load in the picture bit $C055 jsr LOADBANK bit $C054 jsr LOADBANK sta $C000 * Turn off the drive jsr RW18 hex 01 * Wait for keypress waitkey lda $C000 bpl waitkey sta $C010 bmi LOOP *------------------------------------------------- * * Load in two tracks * * The C in C3 and C4 means * bit7:sound speaker on error * bit6:auto inc track * * Read sequence * LOADBANK jsr RW18 hex C320 * Read group jsr RW18 hex 84 hex 32333435363738393A hex 3B3C3D3E0000000000 * ^^^^^^^^ * Note that the last five sectors * are ignored. * * Read last page by itself to * test RW18.35. jsr RW18 hex C4 hex 000000000000000000 hex 000000003F00000000 rts *------------------------------------------------- * * Clear double hires page * hgr sta $C005 jsr :0 sta $C004 :0 ldy #0 ldx #$20 sty temp0 stx temp1 tya :1 sta (temp0),y iny bne :1 inc temp1 dex bne :1 rts *------------------------------------------------- * * Check for 64k and move RW18 to its home. * check64k bit $C08B bit $C08B ldy #0 :0 sty $E000 cpy $E000 bne NOT64K iny bne :0 * Move RW18 to $D000 ldx #5 :1 lda RW18temp,y :2 sta RW18,y iny bne :1 inc :1+2 inc :2+2 dex bne :1 rts NOT64K sta $C081 ldy #0 :0 lda :errtext,y beq * sta $628,y iny bne :0 :errtext ASC "REQUIRES 64K MEMORY",00 *------------------------------------------------- EOF sav demoboot \ No newline at end of file + lst off + +org = $1000 + org org + +*------------------------------------------------- +* +* 08/01/85 +* 07/02/87 mod for 3.5 +* +* Demo using the 18 sector routines. +* +* Loads in a double hires picture +* from tracks 2,3,4 and 5. +* +* by Roland Gustafsson +* + +temp0 = $3A +temp1 = $3B + +RW18temp = $2100 +RW18 = $D000 + +slot = $FD +track = $FE + +*------------------------------------------------- +* +* Move to actual run address +* + +start ldy #0 +:0 lda $2000,y + sta org,y + iny + bne :0 + jmp :1 + +* Tell RW18 which slot to use + +:1 lda $43 + sta slot + + jsr check64k + +* Turn on the disk drive (It is +* already on, but this call is +* necessary to initialize the +* RW18 routine) + +LOOP jsr RW18 + hex 000100 + +* Clear hires page + + jsr hgr + +* Now seek to track two since that +* is where the data starts. + + jsr RW18 + hex 020002 + +* Display double hires page one + + sta $C050 + sta $C052 + sta $C054 + sta $C057 + sta $C00D + sta $C05E + sta $C001 + +* Load in the picture + + bit $C055 + jsr LOADBANK + bit $C054 + jsr LOADBANK + sta $C000 + +* Turn off the drive + + jsr RW18 + hex 01 + +* Wait for keypress + +waitkey lda $C000 + bpl waitkey + sta $C010 + bmi LOOP + +*------------------------------------------------- +* +* Load in two tracks +* +* The C in C3 and C4 means +* bit7:sound speaker on error +* bit6:auto inc track +* +* Read sequence +* + +LOADBANK jsr RW18 + hex C320 + +* Read group + + jsr RW18 + hex 84 + hex 32333435363738393A + hex 3B3C3D3E0000000000 +* ^^^^^^^^ +* Note that the last five sectors +* are ignored. +* +* Read last page by itself to +* test RW18.35. + + jsr RW18 + hex C4 + hex 000000000000000000 + hex 000000003F00000000 + + rts + +*------------------------------------------------- +* +* Clear double hires page +* + +hgr sta $C005 + jsr :0 + sta $C004 + +:0 ldy #0 + ldx #$20 + sty temp0 + stx temp1 + tya +:1 sta (temp0),y + iny + bne :1 + inc temp1 + dex + bne :1 + rts + +*------------------------------------------------- +* +* Check for 64k and move RW18 to its home. +* + +check64k bit $C08B + bit $C08B + ldy #0 +:0 sty $E000 + cpy $E000 + bne NOT64K + iny + bne :0 + +* Move RW18 to $D000 + + ldx #5 +:1 lda RW18temp,y +:2 sta RW18,y + iny + bne :1 + inc :1+2 + inc :2+2 + dex + bne :1 + rts + +NOT64K sta $C081 + ldy #0 +:0 lda :errtext,y + beq * + sta $628,y + iny + bne :0 + +:errtext ASC "REQUIRES 64K MEMORY",00 + +*------------------------------------------------- EOF + + sav demoboot diff --git a/02 POP Disk Routines/RW1835/MOVE35.S b/02 POP Disk Routines/RW1835/MOVE35.S index af8f067..ba212a8 100755 --- a/02 POP Disk Routines/RW1835/MOVE35.S +++ b/02 POP Disk Routines/RW1835/MOVE35.S @@ -1 +1,306 @@ - lst off org $E00 errcode = 0 get8bit = $E74C buffer = $1000 ;7 tracks long bufferend = buffer+$7E00 rw18 = $D000 ;both versions! slot = $FD track = $FE lastrack = $FF *------------------------------------------------- * * CALL RT - moves rw18 routines to their homes in aux mem * * CALL RT+3,<5.25" slot>,,, * ,<3.5" slot>, * jmp move * Get DEST information: start jsr get8bit stx slot525 jsr get8bit stx BbundID jsr get8bit stx track jsr get8bit inx stx ENDtrack * SOURCE information jsr get8bit stx slot35 jsr $DEBE ;get16bit jsr $DD67 jsr $E752 sty Boffset sta Boffset+1 * From now on we are using aux zpage and $D000 lda track sta $C009 sta track jsr recal525 loop lda track pha jsr read35 bcs :plarts pla sta track jsr write525 bcs :rts lda track eor ENDtrack bne loop pha :plarts pla :rts lda #0 rol sta $C008 ;back to main mem sta errcode bit $C081 rts ENDtrack db $11 *------------------------------------------------- write525 * * Write up to 7 tracks from 5.25" floppy. * write525 jsr prep525 * Drive on, delay 1 second jsr rw18 db 0,1,10 * Write until buffer is empty or END track reached lda #>buffer :loop sta :writebuf jsr rw18 db $45 ;auto-inc, writesequ :writebuf db $11 bcs :error lda :writebuf jsr buffend? bcc :loop clc :error php jsr rw18 db 1 ;drive off plp rts *------------------------------------------------- buffend? * * Have we reached the end of buffer, or ENDtrack? * Enter: a - last buffer address * * Exit: cs - no more buffer, or ENDtrack reached * cc - keep going, a=new buffer address * buffend? clc adc #$12 cmp #>bufferend bcs :rts ldy track cpy ENDtrack :rts rts *------------------------------------------------- prep525 * * Prepare to use 5.25" RW18 routine * * Normal RW18 routine is in second bank of $D000 prep525 bit $C08B bit $C08B * Set slot of 5.25" drive lda #$11 slot525 = *-1 asl asl asl asl sta slot tax * Turn off all phases lda $C080,x lda $C082,x lda $C084,x lda $C086,x * Set Broderbund ID byte jsr rw18 db 7 BbundID db $11 rts *------------------------------------------------- recal525 * * Recalibrate 5.25" floppy drive * recal525 jsr prep525 lda #$A0 sta lastrack * Drive on jsr rw18 db 0,1,3 ;.3 second delay * Seek to track zero lda track pha jsr rw18 db 2,0,0 pla sta track sta :track * Now seek first track jsr rw18 db 2,0 :track db $11 jsr rw18 db 1 ;drive off rts *------------------------------------------------- read35 * * Read up to 7 tracks to 3.5" disk. * read35 jsr prep35 * Write until no more buffer, or ENDtrack is reached lda #>buffer :loop sta :readbuf jsr rw18 db $43 ;auto-inc, writesequ :readbuf db $11 bcs :error lda :readbuf jsr buffend? bcc :loop clc :error rts *------------------------------------------------- prep35 * * Prepare to use 3.5" RW18 routine * * 3.5" RW18 routine is in first bank of $D000 prep35 bit $C083 bit $C083 * Set slot of 3.5" drive lda #$11 slot35 = *-1 asl asl asl asl sta slot tax * Set offset into 3.5" disk jsr rw18 db 8 Boffset da $1111 rts *------------------------------------------------- move * * Move the RW18 routines to their respective homes. * * $1000 - 3.5" rw18 routine * $2000 - 5.25" rw18 routine * move ldx #$83 lda #$10 jsr :0 ldx #$8B lda #$20 :0 sta :source+2 lda #$D0 sta :dest+2 lda $C000,x lda $C000,x sta $C009 ;aux $D000 ldx #$10 ldy #0 :source lda $1000,y :dest sta $D000,y iny bne :source inc :source+2 inc :dest+2 dex bne :source sta $C008 bit $C081 rts *------------------------------------------------- EOF \ No newline at end of file + lst off + + org $E00 + +errcode = 0 +get8bit = $E74C + +buffer = $1000 ;7 tracks long +bufferend = buffer+$7E00 + +rw18 = $D000 ;both versions! + +slot = $FD +track = $FE +lastrack = $FF + +*------------------------------------------------- +* +* CALL RT - moves rw18 routines to their homes in aux mem +* +* CALL RT+3,<5.25" slot>,,, +* ,<3.5" slot>, +* + + jmp move + +* Get DEST information: + +start jsr get8bit + stx slot525 + jsr get8bit + stx BbundID + jsr get8bit + stx track + jsr get8bit + inx + stx ENDtrack + +* SOURCE information + + jsr get8bit + stx slot35 + jsr $DEBE ;get16bit + jsr $DD67 + jsr $E752 + sty Boffset + sta Boffset+1 + +* From now on we are using aux zpage and $D000 + + lda track + sta $C009 + sta track + + jsr recal525 + +loop lda track + + pha + jsr read35 + bcs :plarts + pla + + sta track + jsr write525 + bcs :rts + + lda track + eor ENDtrack + bne loop + + pha + +:plarts pla +:rts lda #0 + rol + sta $C008 ;back to main mem + sta errcode + bit $C081 + rts + +ENDtrack db $11 + +*------------------------------------------------- write525 +* +* Write up to 7 tracks from 5.25" floppy. +* + +write525 jsr prep525 + +* Drive on, delay 1 second + + jsr rw18 + db 0,1,10 + +* Write until buffer is empty or END track reached + + lda #>buffer + +:loop sta :writebuf + + jsr rw18 + db $45 ;auto-inc, writesequ +:writebuf db $11 + bcs :error + + lda :writebuf + jsr buffend? + bcc :loop + clc + +:error php + jsr rw18 + db 1 ;drive off + plp + rts + +*------------------------------------------------- buffend? +* +* Have we reached the end of buffer, or ENDtrack? +* Enter: a - last buffer address +* +* Exit: cs - no more buffer, or ENDtrack reached +* cc - keep going, a=new buffer address +* + +buffend? clc + adc #$12 + cmp #>bufferend + bcs :rts + + ldy track + cpy ENDtrack + +:rts rts + +*------------------------------------------------- prep525 +* +* Prepare to use 5.25" RW18 routine +* + +* Normal RW18 routine is in second bank of $D000 + +prep525 bit $C08B + bit $C08B + +* Set slot of 5.25" drive + + lda #$11 +slot525 = *-1 + asl + asl + asl + asl + sta slot + tax + +* Turn off all phases + + lda $C080,x + lda $C082,x + lda $C084,x + lda $C086,x + +* Set Broderbund ID byte + + jsr rw18 + db 7 +BbundID db $11 + + rts + +*------------------------------------------------- recal525 +* +* Recalibrate 5.25" floppy drive +* + +recal525 jsr prep525 + + lda #$A0 + sta lastrack + +* Drive on + + jsr rw18 + db 0,1,3 ;.3 second delay + +* Seek to track zero + + lda track + pha + + jsr rw18 + db 2,0,0 + + pla + sta track + sta :track + +* Now seek first track + + jsr rw18 + db 2,0 +:track db $11 + + jsr rw18 + db 1 ;drive off + + rts + +*------------------------------------------------- read35 +* +* Read up to 7 tracks to 3.5" disk. +* + +read35 jsr prep35 + +* Write until no more buffer, or ENDtrack is reached + + lda #>buffer + +:loop sta :readbuf + + jsr rw18 + db $43 ;auto-inc, writesequ +:readbuf db $11 + bcs :error + + lda :readbuf + jsr buffend? + bcc :loop + clc + +:error rts + +*------------------------------------------------- prep35 +* +* Prepare to use 3.5" RW18 routine +* + +* 3.5" RW18 routine is in first bank of $D000 + +prep35 bit $C083 + bit $C083 + +* Set slot of 3.5" drive + + lda #$11 +slot35 = *-1 + asl + asl + asl + asl + sta slot + tax + +* Set offset into 3.5" disk + + jsr rw18 + db 8 +Boffset da $1111 + + rts + +*------------------------------------------------- move +* +* Move the RW18 routines to their respective homes. +* +* $1000 - 3.5" rw18 routine +* $2000 - 5.25" rw18 routine +* + +move ldx #$83 + lda #$10 + jsr :0 + ldx #$8B + lda #$20 + +:0 sta :source+2 + lda #$D0 + sta :dest+2 + + lda $C000,x + lda $C000,x + + sta $C009 ;aux $D000 + + ldx #$10 + ldy #0 +:source lda $1000,y +:dest sta $D000,y + iny + bne :source + + inc :source+2 + inc :dest+2 + + dex + bne :source + + sta $C008 + bit $C081 + + rts + +*------------------------------------------------- EOF diff --git a/02 POP Disk Routines/RW1835/MOVE53.S b/02 POP Disk Routines/RW1835/MOVE53.S index aa78e86..9282957 100755 --- a/02 POP Disk Routines/RW1835/MOVE53.S +++ b/02 POP Disk Routines/RW1835/MOVE53.S @@ -1 +1,303 @@ - lst off org $E00 errcode = 0 get8bit = $E74C buffer = $1000 ;7 tracks long bufferend = buffer+$7E00 rw18 = $D000 ;both versions! slot = $FD track = $FE lastrack = $FF *------------------------------------------------- * * CALL RT - moves rw18 routines to their homes in aux mem * * CALL RT+3,<5.25" slot>,,, * ,<3.5" slot>, * jmp move * Get source information: start jsr get8bit stx slot525 jsr get8bit stx BbundID jsr get8bit stx track jsr get8bit inx stx ENDtrack * Destination information jsr get8bit stx slot35 jsr $DEBE ;get16bit jsr $DD67 jsr $E752 sty Boffset sta Boffset+1 * From now on we are using aux zpage and $D000 lda track sta $C009 sta track jsr recal525 loop lda track pha jsr read525 bcs :plarts pla sta track jsr write35 bcs :rts lda track eor ENDtrack bne loop pha :plarts pla :rts lda #0 rol sta $C008 ;back to main mem sta errcode bit $C081 rts ENDtrack db $11 *------------------------------------------------- read525 * * Read up to 7 tracks from 5.25" floppy. * read525 jsr prep525 * Drive on, delay .5 seconds jsr rw18 db 0,1,5 * Read until buffer is full lda #>buffer :loop sta :readbuf jsr rw18 db $43 ;auto-inc, readsequ :readbuf db $11 bcs :error lda :readbuf jsr buffend? bcc :loop clc :error php jsr rw18 db 1 ;drive off plp rts *------------------------------------------------- buffend? * * Have we reached the end of buffer, or ENDtrack? * Enter: a - last buffer address * * Exit: cs - no more buffer, or ENDtrack reached * cc - keep going, a=new buffer address * buffend? clc adc #$12 cmp #>bufferend bcs :rts ldy track cpy ENDtrack :rts rts *------------------------------------------------- prep525 * * Prepare to use 5.25" RW18 routine * * Normal RW18 routine is in second bank of $D000 prep525 bit $C08B bit $C08B * Set slot of 5.25" drive lda #$11 slot525 = *-1 asl asl asl asl sta slot tax * Turn off all phases lda $C080,x lda $C082,x lda $C084,x lda $C086,x * Set Broderbund ID byte jsr rw18 db 7 BbundID db $11 rts *------------------------------------------------- recal525 * * Recalibrate 5.25" floppy drive * recal525 jsr prep525 lda #$A0 sta lastrack * Drive on jsr rw18 db 0,1,3 ;.3 second delay * Seek to track zero lda track pha jsr rw18 db 2,0,0 pla sta track sta :track * Now seek first track jsr rw18 db 2,0 :track db $11 rts *------------------------------------------------- write35 * * Write up to 7 tracks to 3.5" disk. * write35 jsr prep35 * Write until no more buffer, or ENDtrack is reached lda #>buffer :loop sta :writebuf jsr rw18 db $45 ;auto-inc, writesequ :writebuf db $11 bcs :error lda :writebuf jsr buffend? bcc :loop clc :error rts *------------------------------------------------- prep35 * * Prepare to use 3.5" RW18 routine * * 3.5" RW18 routine is in first bank of $D000 prep35 bit $C083 bit $C083 * Set slot of 3.5" drive lda #$11 slot35 = *-1 asl asl asl asl sta slot tax * Set offset into 3.5" disk jsr rw18 db 8 Boffset da $1111 rts *------------------------------------------------- move * * Move the RW18 routines to their respective homes. * * $1000 - 3.5" rw18 routine * $2000 - 5.25" rw18 routine * move ldx #$83 lda #$10 jsr :0 ldx #$8B lda #$20 :0 sta :source+2 lda #$D0 sta :dest+2 lda $C000,x lda $C000,x sta $C009 ;aux $D000 ldx #$10 ldy #0 :source lda $1000,y :dest sta $D000,y iny bne :source inc :source+2 inc :dest+2 dex bne :source sta $C008 bit $C081 rts *------------------------------------------------- EOF \ No newline at end of file + lst off + + org $E00 + +errcode = 0 +get8bit = $E74C + +buffer = $1000 ;7 tracks long +bufferend = buffer+$7E00 + +rw18 = $D000 ;both versions! + +slot = $FD +track = $FE +lastrack = $FF + +*------------------------------------------------- +* +* CALL RT - moves rw18 routines to their homes in aux mem +* +* CALL RT+3,<5.25" slot>,,, +* ,<3.5" slot>, +* + + jmp move + +* Get source information: + +start jsr get8bit + stx slot525 + jsr get8bit + stx BbundID + jsr get8bit + stx track + jsr get8bit + inx + stx ENDtrack + +* Destination information + + jsr get8bit + stx slot35 + jsr $DEBE ;get16bit + jsr $DD67 + jsr $E752 + sty Boffset + sta Boffset+1 + +* From now on we are using aux zpage and $D000 + + lda track + sta $C009 + sta track + + jsr recal525 + +loop lda track + + pha + jsr read525 + bcs :plarts + pla + + sta track + jsr write35 + bcs :rts + + lda track + eor ENDtrack + bne loop + + pha + +:plarts pla +:rts lda #0 + rol + sta $C008 ;back to main mem + sta errcode + bit $C081 + rts + +ENDtrack db $11 + +*------------------------------------------------- read525 +* +* Read up to 7 tracks from 5.25" floppy. +* + +read525 jsr prep525 + +* Drive on, delay .5 seconds + + jsr rw18 + db 0,1,5 + +* Read until buffer is full + + lda #>buffer + +:loop sta :readbuf + + jsr rw18 + db $43 ;auto-inc, readsequ +:readbuf db $11 + bcs :error + + lda :readbuf + jsr buffend? + bcc :loop + clc + +:error php + jsr rw18 + db 1 ;drive off + plp + rts + +*------------------------------------------------- buffend? +* +* Have we reached the end of buffer, or ENDtrack? +* Enter: a - last buffer address +* +* Exit: cs - no more buffer, or ENDtrack reached +* cc - keep going, a=new buffer address +* + +buffend? clc + adc #$12 + cmp #>bufferend + bcs :rts + + ldy track + cpy ENDtrack + +:rts rts + +*------------------------------------------------- prep525 +* +* Prepare to use 5.25" RW18 routine +* + +* Normal RW18 routine is in second bank of $D000 + +prep525 bit $C08B + bit $C08B + +* Set slot of 5.25" drive + + lda #$11 +slot525 = *-1 + asl + asl + asl + asl + sta slot + tax + +* Turn off all phases + + lda $C080,x + lda $C082,x + lda $C084,x + lda $C086,x + +* Set Broderbund ID byte + + jsr rw18 + db 7 +BbundID db $11 + + rts + +*------------------------------------------------- recal525 +* +* Recalibrate 5.25" floppy drive +* + +recal525 jsr prep525 + + lda #$A0 + sta lastrack + +* Drive on + + jsr rw18 + db 0,1,3 ;.3 second delay + +* Seek to track zero + + lda track + pha + + jsr rw18 + db 2,0,0 + + pla + sta track + sta :track + +* Now seek first track + + jsr rw18 + db 2,0 +:track db $11 + + rts + +*------------------------------------------------- write35 +* +* Write up to 7 tracks to 3.5" disk. +* + +write35 jsr prep35 + +* Write until no more buffer, or ENDtrack is reached + + lda #>buffer + +:loop sta :writebuf + + jsr rw18 + db $45 ;auto-inc, writesequ +:writebuf db $11 + bcs :error + + lda :writebuf + jsr buffend? + bcc :loop + clc + +:error rts + +*------------------------------------------------- prep35 +* +* Prepare to use 3.5" RW18 routine +* + +* 3.5" RW18 routine is in first bank of $D000 + +prep35 bit $C083 + bit $C083 + +* Set slot of 3.5" drive + + lda #$11 +slot35 = *-1 + asl + asl + asl + asl + sta slot + tax + +* Set offset into 3.5" disk + + jsr rw18 + db 8 +Boffset da $1111 + + rts + +*------------------------------------------------- move +* +* Move the RW18 routines to their respective homes. +* +* $1000 - 3.5" rw18 routine +* $2000 - 5.25" rw18 routine +* + +move ldx #$83 + lda #$10 + jsr :0 + ldx #$8B + lda #$20 + +:0 sta :source+2 + lda #$D0 + sta :dest+2 + + lda $C000,x + lda $C000,x + + sta $C009 ;aux $D000 + + ldx #$10 + ldy #0 +:source lda $1000,y +:dest sta $D000,y + iny + bne :source + + inc :source+2 + inc :dest+2 + + dex + bne :source + + sta $C008 + bit $C081 + + rts + +*------------------------------------------------- EOF diff --git a/02 POP Disk Routines/RW1835/POPBOOT35.S b/02 POP Disk Routines/RW1835/POPBOOT35.S index 538de0a..1961879 100755 --- a/02 POP Disk Routines/RW1835/POPBOOT35.S +++ b/02 POP Disk Routines/RW1835/POPBOOT35.S @@ -1 +1,210 @@ - lst off org $2000 *------------------------------------------------- * * 06/28/89 Prince of Persia boot code * for rw18 3.5" version * * Last mod: 09/05/89 * rw18 = $D000 slot = $FD *------------------------------------------------- * * Tell RW18 which slot to use * start bit RW18temp ldx #$FF txs lda $43 ;ProDOS boot drive sta slot * Clear screen, etc... jsr init * Check system for 128k of RAM jsr check128k * Determine if we are running on a GS * and do GS specific stuff also... jsr setGSflag * Move rw18 to its home jsr moverw18 * Start loading the game jsr rw18 db 7,$A9 ;Bbund ID=$A9 for side one jsr rw18 ;"seek" track one db 2,0,1 jsr rw18 ;read in $EE00-FFFF hex C3EE jmp $EE00 *------------------------------------------------- text = $fb2f home = $fc58 vtab = $FB5B cout = $FDF0 normal = $fe84 pr0 = $fe93 in0 = $fe89 init ldx #$ff stx $4fb stx $3f3 stx $3f4 stx $c000 ;80store off stx $c002 ;RAMRD main stx $c004 ;RAMWRT main stx $c00c ;80col off stx $c00e ;Altcharset off stx $c081 ;write RAM, read ROM (2nd 4k bank) jsr text jsr home jsr normal jsr pr0 jsr in0 rts *------------------------------------------------- * * Check to make sure //c or //e * with 128k * check128k sta $C081 lda $FBB3 ;Apple // family ID byte cmp #6 bne NOT128K ;Must be e/c/GS bit $C017 bmi NOT128K ldx #CHECKEND :0 lda CHECKER,X sta $180,X dex bpl :0 jsr $180 bcs NOT128K rts NOT128K jsr text jsr home lda #8 jsr vtab ldy #0 :0 lda MEMTEXT,Y beq * jsr cout cmp #$8D bne :1 lda #4 sta $24 :1 iny bne :0 MEMTEXT hex 8D asc "REQUIRES A //C OR //E WITH 128K" hex 00 *------------------------------------------------- * Check for AUX memory routine CHECKER lda #$EE sta $C005 sta $C003 sta $0800 lda $0C00 cmp #$EE bne :0 asl $0C00 lda $0800 cmp $0C00 beq :1 :0 clc :1 sta $C004 sta $C002 rts CHECKEND = *-CHECKER *------------------------------------------------- setGSflag * * Set the GS? flag in rw18 * setGSflag sta $C081 sec jsr $FE1F lda #$FF adc #0 sta GS? bpl :notGS * Set background color to black, text to white lda #$F0 sta $C022 * Set border color to black lda $C034 and #$F0 sta $C034 :notGS rts *------------------------------------------------- moverw18 * * Move RW18 to it's final home in $D000 * moverw18 bit $C08B bit $C08B ldy #0 :0 lda RW18temp,y :1 sta $D000,y iny bne :0 inc :0+2 inc :1+2 bne :0 rts *------------------------------------------------- sav popboot35 *------------------------------------------------- EOF dum * RW18temp ds 3 GS? ds 1 dend *------------------------------------------------- lst off \ No newline at end of file + lst off + + org $2000 + +*------------------------------------------------- +* +* 06/28/89 Prince of Persia boot code +* for rw18 3.5" version +* +* Last mod: 09/05/89 +* + +rw18 = $D000 + +slot = $FD + +*------------------------------------------------- +* +* Tell RW18 which slot to use +* + +start bit RW18temp + + ldx #$FF + txs + + lda $43 ;ProDOS boot drive + sta slot + +* Clear screen, etc... + + jsr init + +* Check system for 128k of RAM + + jsr check128k + +* Determine if we are running on a GS +* and do GS specific stuff also... + + jsr setGSflag + +* Move rw18 to its home + + jsr moverw18 + +* Start loading the game + + jsr rw18 + db 7,$A9 ;Bbund ID=$A9 for side one + + jsr rw18 ;"seek" track one + db 2,0,1 + + jsr rw18 ;read in $EE00-FFFF + hex C3EE + + jmp $EE00 + +*------------------------------------------------- +text = $fb2f +home = $fc58 +vtab = $FB5B +cout = $FDF0 +normal = $fe84 +pr0 = $fe93 +in0 = $fe89 + +init ldx #$ff + stx $4fb + stx $3f3 + stx $3f4 + stx $c000 ;80store off + stx $c002 ;RAMRD main + stx $c004 ;RAMWRT main + stx $c00c ;80col off + stx $c00e ;Altcharset off + stx $c081 ;write RAM, read ROM (2nd 4k bank) + jsr text + jsr home + jsr normal + jsr pr0 + jsr in0 + + rts + +*------------------------------------------------- +* +* Check to make sure //c or //e +* with 128k +* + +check128k sta $C081 + + lda $FBB3 ;Apple // family ID byte + cmp #6 + bne NOT128K ;Must be e/c/GS + + bit $C017 + bmi NOT128K + + ldx #CHECKEND +:0 lda CHECKER,X + sta $180,X + dex + bpl :0 + + jsr $180 + bcs NOT128K + + rts + +NOT128K jsr text + jsr home + lda #8 + jsr vtab + + ldy #0 +:0 lda MEMTEXT,Y + beq * + jsr cout + cmp #$8D + bne :1 + lda #4 + sta $24 +:1 iny + bne :0 + +MEMTEXT hex 8D + asc "REQUIRES A //C OR //E WITH 128K" + hex 00 + +*------------------------------------------------- +* Check for AUX memory routine + +CHECKER lda #$EE + sta $C005 + sta $C003 + sta $0800 + lda $0C00 + cmp #$EE + bne :0 + asl $0C00 + lda $0800 + cmp $0C00 + beq :1 +:0 clc +:1 sta $C004 + sta $C002 + rts + +CHECKEND = *-CHECKER + +*------------------------------------------------- setGSflag +* +* Set the GS? flag in rw18 +* + +setGSflag sta $C081 + sec + jsr $FE1F + lda #$FF + adc #0 + sta GS? + bpl :notGS + +* Set background color to black, text to white + + lda #$F0 + sta $C022 + +* Set border color to black + + lda $C034 + and #$F0 + sta $C034 + +:notGS rts + +*------------------------------------------------- moverw18 +* +* Move RW18 to it's final home in $D000 +* + +moverw18 bit $C08B + bit $C08B + + ldy #0 +:0 lda RW18temp,y +:1 sta $D000,y + iny + bne :0 + + inc :0+2 + inc :1+2 + bne :0 + + rts + +*------------------------------------------------- + + sav popboot35 + +*------------------------------------------------- EOF + dum * +RW18temp ds 3 +GS? ds 1 + dend +*------------------------------------------------- + lst off diff --git a/02 POP Disk Routines/RW1835/RW1835.POP.S b/02 POP Disk Routines/RW1835/RW1835.POP.S index 3d5f112..6a84a73 100755 --- a/02 POP Disk Routines/RW1835/RW1835.POP.S +++ b/02 POP Disk Routines/RW1835/RW1835.POP.S @@ -1 +1,618 @@ - lst off tr on org $D000 xc off *------------------------------------------------- * * 07/02/87 * * Unidisk 3.5 interface for * 18 sector read/write routine * * 09/05/89 Version for //e * * Copyright 1985, 1987 * by Roland Gustafsson * *------------------------------------------------- sigblock = 16+315 * * Permanent vars * slot = $FD track = $FE ;lastrack = $FF ;NOT USED * Zero page usage: temp = $40 command = $41 *------------------------------------------------- jmp RW18 *------------------------------------------------- GS? ds 1 ;bpl if not, bmi if GS OFFSET = 16 ;default offset *------------------------------------------------- * * READ/WRITE 18 sectors! * READ lda #1 hex 2C WRITE lda #2 sta SPcommand * Calculate starting block * (OFFSET+track*9) lda track ;0-34 asl asl asl tax ;x=lo lda #0 rol tay ;y=hi txa adc track tax tya adc #0 tay txa adc #OFFSET BOFFLO = *-1 sta BLOCKLO tya adc #>OFFSET BOFFHI = *-1 sta BLOCKHI * Loop for 18 sectors, 2 at a time. ldy #0 :0 tya pha * Do 2 sectors lda BUFTABLE,Y sta ]rbuf0 sta ]wbuf0 ldx BUFTABLE+1,Y stx ]rbuf1 stx ]wbuf1 dex cpx ]rbuf0 jsr RWSECTS pla tay bcs :rts * Next 2 sectors inc BLOCKLO bne :1 inc BLOCKHI :1 iny iny cpy #18 bne :0 clc :rts rts *----------- * * Read or write 2 sectors * * If the two sectors are sequential * then just go to the Device Driver. * RWSECTS bne :noncont * We are dealing with contiguous sectors... * if aux mem is set in any way, then we must * load them using the non-contiguous routine.. bit ]RAMread? bmi :noncont bit ]RAMwrite? bpl JMPSP * Non-contiguous... :noncont ldy SPcommand dey bne WSECTS * Read two non-contiguous sectors RSECTS lda ]rbuf0 ora ]rbuf1 clc beq :rts jsr JMPSPBUF bcs :rts * Now move them to where they belong ldx #$2C ; bit ABS ldy #$99 ; sta ABS,Y * If this sector is to be ignored, * then change sta $FF00,Y to bit. sty ]rmod0 lda ]rbuf0 bne *+5 stx ]rmod0 sty ]rmod1 lda ]rbuf1 bne *+5 stx ]rmod1 ldy #0 :0 lda BLOCKBUF,Y ]rmod0 sta $FF00,Y ]rbuf0 = *-1 lda BLOCKBUF+256,Y ]rmod1 sta $FF00,Y ]rbuf1 = *-1 iny bne :0 :rts rts *----------- * * Write two non-contiguous sectors * WSECTS ldy #0 :0 lda $FF00,Y ]wbuf0 = *-1 sta BLOCKBUF,Y lda $FF00,Y ]wbuf1 = *-1 sta BLOCKBUF+256,Y iny bne :0 JMPSPBUF lda #>BLOCKBUF *------------------------------------------------- * * Jump to Smart Port driver * * Enter: A - address of buffer * JMPSP sta SPbufhi * If ERROR? hi bit is set, then just return sec asl ERROR? bcs ]rtserr * Force main memory sta $C002 sta $C004 * Trick here, first time through, calculates * the entry point into the SmartPort, from * then on, direct access is available. ]SPjsr jsr calcSPjsr SPcommand db $11 da SPcmdlist restAux sta $C002 lda #$11 ]RAMread? = *-1 bpl *+5 sta $C003 sta $C004 lda #$11 ]RAMwrite? = *-1 bpl *+5 sta $C005 ]rtserr rts calcSPjsr lda slot lsr lsr lsr lsr ora #$C0 sta ]SPjsr+2 sta :calcSPmod+2 :calcSPmod lda $C5FF clc adc #3 sta ]SPjsr+1 jmp (]SPjsr+1) SPcmdlist db 3 unit_num db 1 ;unit one db 0 ;SPbuflo=$00 SPbufhi db $11 BLOCKLO db $11 ;"low" BLOCKHI db $11 ;"med" db 0 ;"high" always zero! *------------------------------------------------- RW18 * * Entry point into RW18 * RW18 pla sta GOTBYTE+1 pla sta GOTBYTE+2 bit $CFFF * Remember aux memory settings lda $C013 sta ]RAMread? lda $C014 sta ]RAMwrite? * Save aux text page if running on a GS bit GS? bpl *+5 jsr saveTaux * Save zpage ldx #0 :zsave lda 0,x sta ZPAGEBUF,x inx bne :zsave * Get the command jsr GETBYTE sta command and #$0F asl tax lda cmdadr,X sta :1+1 lda cmdadr+1,X sta :1+2 :1 jsr $FFFF * Restore aux text page if running on a GS bit GS? bpl *+5 jsr restTaux * Restore aux memory settings jsr restAux * Restore zpage ldy track ldx #0 :zrest lda ZPAGEBUF,x sta 0,x inx bne :zrest sty track lda GOTBYTE+2 pha lda GOTBYTE+1 pha rts rts cmdadr da CMdriveon da rts ; CMDRIVOFF da CMseek da CMreadseq da CMreadgroup da CMwriteseq da CMwritegroup da CMid da CMoffset *------------------------------------------------- CMseek * * SEEK * , * * CMseek jsr GETBYTE jsr GETBYTE sta track rts *------------------------------------------------- CMreadseq *------------------------------------------------- CMreadgroup * * Read sequence * * * Read group * <18 buf adr's> * CMreadseq ldx #1 hex 2C CMreadgroup ldx #18 jsr CMADINFO CMREAD2 jsr READ *------------------------------------------------- * * READ/WRITE exit. * INCTRAK? bit command bcs WHOOP? * If bit 6 set, then inc track bvc ]rts inc track ]rts rts * If bit 7 set then whoop speaker * WARNING:use only with READ WHOOP? bpl ]rts ldy #0 :1 tya bit $C030 :2 sec sbc #1 bne :2 dey bne :1 beq CMREAD2 *------------------------------------------------- CMdriveon * * "DriveOn" is when we check for the POP disk * ERROR? db 0 CMdriveon ldy #sigblock lda #>sigblock sty BLOCKLO sta BLOCKHI lda #1 ;read sta SPcommand jsr JMPSPBUF ;read in sig block bcs :9 ldy #-1 :chksig iny lda :sig,y beq :9 eor BLOCKBUF,y beq :chksig sec :9 lda #0 ror sta ERROR? rts :sig asc 'Prince of Persia 3.5!',00 *------------------------------------------------- CMwriteseq *------------------------------------------------- CMwritegroup * * Same as READ * CMwriteseq ldx #1 hex 2C CMwritegroup ldx #18 jsr CMADINFO jsr WRITE jmp INCTRAK? *------------------------------------------------- CMid * * Change offset based on ID * CMid jsr GETBYTE sta :IDmod+1 ldy #-3 :0 iny iny iny lda :IDlist,y beq :rts :IDmod cmp #$11 bne :0 lda :IDlist+1,y sta BOFFLO lda :IDlist+2,y sta BOFFHI :rts rts :IDlist db $A9 dw 16 ;side one db $AD dw 16+315+1 ;side two db $79 dw 16+315+1+315 ;side three!!! db 0 ;end of list *------------------------------------------------- * * Set new block offset * CMoffset jsr GETBYTE sta BOFFLO jsr GETBYTE sta BOFFHI rts *------------------------------------------------- * * Get buffer info. * CMADINFO stx temp ldx #0 :0 jsr GETBYTE jsr auxTfix sta BUFTABLE,X inx cpx temp bcc :0 tay * If sequence, then fill table :1 iny cpx #18 beq :2 tya jsr auxTfix sta BUFTABLE,X inx bne :1 :2 rts *------------------------------------------------- * * Only if running on a GS: * * If loading into text page, then change to * load into internal buffer instead. * auxTfix bit GS? bpl :0 cmp #4 bcc :0 cmp #8 bcs :0 adc #>auxTPAGEsave-$400 :0 rts *------------------------------------------------- * * Only if running on a GS: * * Save the aux memory text page to internal buffer * xc xc saveTaux clc xce rep $30 ldx #$0400 ldy #auxTPAGEsave lda #$400-1 phb mvn $10400,0 plb sec xce rts *------------------------------------------------- * * Only if running on a GS: * * Restore aux text page from internal buffer restTaux clc xce rep $30 ldx #auxTPAGEsave ldy #$0400 lda #$400-1 phb mvn 0,$10400 plb sec xce rts xc off *------------------------------------------------- GETBYTE inc GOTBYTE+1 bne GOTBYTE inc GOTBYTE+2 GOTBYTE lda $FFFF rts *------------------------------------------------- sav rw1835.pop *------------------------------------------------- lst on ZPAGEBUF ds $100 BUFTABLE ds 18 ds \ BLOCKBUF ds 512 auxTPAGEsave ds 1024 da * lst off *------------------------------------------------- EOF \ No newline at end of file + lst off + tr on + org $D000 + xc off + +*------------------------------------------------- +* +* 07/02/87 +* +* Unidisk 3.5 interface for +* 18 sector read/write routine +* +* 09/05/89 Version for //e +* +* Copyright 1985, 1987 +* by Roland Gustafsson +* +*------------------------------------------------- + +sigblock = 16+315 + +* +* Permanent vars +* + +slot = $FD +track = $FE +;lastrack = $FF ;NOT USED + +* Zero page usage: + +temp = $40 +command = $41 + +*------------------------------------------------- + jmp RW18 +*------------------------------------------------- +GS? ds 1 ;bpl if not, bmi if GS + +OFFSET = 16 ;default offset + +*------------------------------------------------- +* +* READ/WRITE 18 sectors! +* + +READ lda #1 + hex 2C +WRITE lda #2 + sta SPcommand + +* Calculate starting block +* (OFFSET+track*9) + + lda track ;0-34 + asl + asl + asl + tax ;x=lo + + lda #0 + rol + tay ;y=hi + + txa + adc track + tax + + tya + adc #0 + tay + + txa + adc #OFFSET +BOFFLO = *-1 + sta BLOCKLO + + tya + adc #>OFFSET +BOFFHI = *-1 + sta BLOCKHI + +* Loop for 18 sectors, 2 at a time. + + ldy #0 +:0 tya + pha + +* Do 2 sectors + + lda BUFTABLE,Y + sta ]rbuf0 + sta ]wbuf0 + ldx BUFTABLE+1,Y + stx ]rbuf1 + stx ]wbuf1 + dex + cpx ]rbuf0 + jsr RWSECTS + + pla + tay + + bcs :rts + +* Next 2 sectors + + inc BLOCKLO + bne :1 + inc BLOCKHI + +:1 iny + iny + cpy #18 + bne :0 + + clc +:rts rts + +*----------- +* +* Read or write 2 sectors +* +* If the two sectors are sequential +* then just go to the Device Driver. +* + +RWSECTS bne :noncont + +* We are dealing with contiguous sectors... +* if aux mem is set in any way, then we must +* load them using the non-contiguous routine.. + + bit ]RAMread? + bmi :noncont + bit ]RAMwrite? + bpl JMPSP + +* Non-contiguous... + +:noncont ldy SPcommand + dey + bne WSECTS + +* Read two non-contiguous sectors + +RSECTS lda ]rbuf0 + ora ]rbuf1 + clc + beq :rts + + jsr JMPSPBUF + bcs :rts + +* Now move them to where they belong + + ldx #$2C ; bit ABS + ldy #$99 ; sta ABS,Y + +* If this sector is to be ignored, +* then change sta $FF00,Y to bit. + + sty ]rmod0 + lda ]rbuf0 + bne *+5 + stx ]rmod0 + + sty ]rmod1 + lda ]rbuf1 + bne *+5 + stx ]rmod1 + + ldy #0 +:0 lda BLOCKBUF,Y +]rmod0 sta $FF00,Y +]rbuf0 = *-1 + lda BLOCKBUF+256,Y +]rmod1 sta $FF00,Y +]rbuf1 = *-1 + iny + bne :0 + +:rts rts + +*----------- +* +* Write two non-contiguous sectors +* + +WSECTS ldy #0 +:0 lda $FF00,Y +]wbuf0 = *-1 + sta BLOCKBUF,Y + lda $FF00,Y +]wbuf1 = *-1 + sta BLOCKBUF+256,Y + iny + bne :0 + +JMPSPBUF lda #>BLOCKBUF + +*------------------------------------------------- +* +* Jump to Smart Port driver +* +* Enter: A - address of buffer +* + +JMPSP sta SPbufhi + +* If ERROR? hi bit is set, then just return sec + + asl ERROR? + bcs ]rtserr + +* Force main memory + + sta $C002 + sta $C004 + +* Trick here, first time through, calculates +* the entry point into the SmartPort, from +* then on, direct access is available. + +]SPjsr jsr calcSPjsr +SPcommand db $11 + da SPcmdlist + +restAux sta $C002 + lda #$11 +]RAMread? = *-1 + bpl *+5 + sta $C003 + + sta $C004 + lda #$11 +]RAMwrite? = *-1 + bpl *+5 + sta $C005 + +]rtserr rts + +calcSPjsr lda slot + lsr + lsr + lsr + lsr + ora #$C0 + sta ]SPjsr+2 + sta :calcSPmod+2 + +:calcSPmod lda $C5FF + clc + adc #3 + sta ]SPjsr+1 + jmp (]SPjsr+1) + +SPcmdlist db 3 +unit_num db 1 ;unit one + db 0 ;SPbuflo=$00 +SPbufhi db $11 +BLOCKLO db $11 ;"low" +BLOCKHI db $11 ;"med" + db 0 ;"high" always zero! + +*------------------------------------------------- RW18 +* +* Entry point into RW18 +* + +RW18 pla + sta GOTBYTE+1 + pla + sta GOTBYTE+2 + + bit $CFFF + +* Remember aux memory settings + + lda $C013 + sta ]RAMread? + lda $C014 + sta ]RAMwrite? + +* Save aux text page if running on a GS + + bit GS? + bpl *+5 + jsr saveTaux + +* Save zpage + + ldx #0 +:zsave lda 0,x + sta ZPAGEBUF,x + inx + bne :zsave + +* Get the command + + jsr GETBYTE + sta command + and #$0F + asl + tax + + lda cmdadr,X + sta :1+1 + lda cmdadr+1,X + sta :1+2 + +:1 jsr $FFFF + +* Restore aux text page if running on a GS + + bit GS? + bpl *+5 + jsr restTaux + +* Restore aux memory settings + + jsr restAux + +* Restore zpage + + ldy track + ldx #0 +:zrest lda ZPAGEBUF,x + sta 0,x + inx + bne :zrest + sty track + + lda GOTBYTE+2 + pha + lda GOTBYTE+1 + pha + +rts rts + +cmdadr da CMdriveon + da rts ; CMDRIVOFF + da CMseek + da CMreadseq + da CMreadgroup + da CMwriteseq + da CMwritegroup + da CMid + da CMoffset + +*------------------------------------------------- CMseek +* +* SEEK +* , +* +* + +CMseek jsr GETBYTE + jsr GETBYTE + sta track + rts + +*------------------------------------------------- CMreadseq +*------------------------------------------------- CMreadgroup +* +* Read sequence +* +* +* Read group +* <18 buf adr's> +* + +CMreadseq ldx #1 + hex 2C +CMreadgroup ldx #18 + jsr CMADINFO + +CMREAD2 jsr READ + +*------------------------------------------------- +* +* READ/WRITE exit. +* +INCTRAK? bit command + bcs WHOOP? + +* If bit 6 set, then inc track + + bvc ]rts + inc track +]rts rts + +* If bit 7 set then whoop speaker +* WARNING:use only with READ + +WHOOP? bpl ]rts + ldy #0 +:1 tya + bit $C030 +:2 sec + sbc #1 + bne :2 + dey + bne :1 + beq CMREAD2 + +*------------------------------------------------- CMdriveon +* +* "DriveOn" is when we check for the POP disk +* + +ERROR? db 0 + +CMdriveon ldy #sigblock + lda #>sigblock + sty BLOCKLO + sta BLOCKHI + + lda #1 ;read + sta SPcommand + + jsr JMPSPBUF ;read in sig block + bcs :9 + + ldy #-1 +:chksig iny + lda :sig,y + beq :9 + eor BLOCKBUF,y + beq :chksig + sec + +:9 lda #0 + ror + sta ERROR? + rts + +:sig asc 'Prince of Persia 3.5!',00 + +*------------------------------------------------- CMwriteseq +*------------------------------------------------- CMwritegroup +* +* Same as READ +* + +CMwriteseq ldx #1 + hex 2C +CMwritegroup ldx #18 + jsr CMADINFO + jsr WRITE + jmp INCTRAK? + +*------------------------------------------------- CMid +* +* Change offset based on ID +* + +CMid jsr GETBYTE + sta :IDmod+1 + + ldy #-3 +:0 iny + iny + iny + lda :IDlist,y + beq :rts + +:IDmod cmp #$11 + bne :0 + + lda :IDlist+1,y + sta BOFFLO + lda :IDlist+2,y + sta BOFFHI + +:rts rts + +:IDlist db $A9 + dw 16 ;side one + + db $AD + dw 16+315+1 ;side two + + db $79 + dw 16+315+1+315 ;side three!!! + + db 0 ;end of list + +*------------------------------------------------- +* +* Set new block offset +* + +CMoffset jsr GETBYTE + sta BOFFLO + jsr GETBYTE + sta BOFFHI + rts + +*------------------------------------------------- +* +* Get buffer info. +* + +CMADINFO stx temp + ldx #0 +:0 jsr GETBYTE + jsr auxTfix + sta BUFTABLE,X + inx + cpx temp + bcc :0 + tay + +* If sequence, then fill table + +:1 iny + cpx #18 + beq :2 + tya + jsr auxTfix + sta BUFTABLE,X + inx + bne :1 + +:2 rts + +*------------------------------------------------- +* +* Only if running on a GS: +* +* If loading into text page, then change to +* load into internal buffer instead. +* + +auxTfix bit GS? + bpl :0 + + cmp #4 + bcc :0 + cmp #8 + bcs :0 + adc #>auxTPAGEsave-$400 + +:0 rts + +*------------------------------------------------- +* +* Only if running on a GS: +* +* Save the aux memory text page to internal buffer +* + + xc + xc + +saveTaux clc + xce + rep $30 + ldx #$0400 + ldy #auxTPAGEsave + lda #$400-1 + phb + mvn $10400,0 + plb + sec + xce + rts + +*------------------------------------------------- +* +* Only if running on a GS: +* +* Restore aux text page from internal buffer + +restTaux clc + xce + rep $30 + ldx #auxTPAGEsave + ldy #$0400 + lda #$400-1 + phb + mvn 0,$10400 + plb + sec + xce + rts + + xc off + +*------------------------------------------------- + +GETBYTE inc GOTBYTE+1 + bne GOTBYTE + inc GOTBYTE+2 +GOTBYTE lda $FFFF + rts + +*------------------------------------------------- + + sav rw1835.pop + +*------------------------------------------------- + + lst on + +ZPAGEBUF ds $100 +BUFTABLE ds 18 + ds \ +BLOCKBUF ds 512 + +auxTPAGEsave ds 1024 + + da * + + lst off + +*------------------------------------------------- EOF diff --git a/02 POP Disk Routines/RW1835/RW1835.S b/02 POP Disk Routines/RW1835/RW1835.S index 7bd8c79..d8c782e 100755 --- a/02 POP Disk Routines/RW1835/RW1835.S +++ b/02 POP Disk Routines/RW1835/RW1835.S @@ -1 +1,449 @@ - lst off tr on org $D000 xc off *------------------------------------------------- * * 07/02/87 * * Unidisk 3.5 interface for * 18 sector read/write routine * * Copyright 1985, 1987 * by Roland Gustafsson * *------------------------------------------------- * * Permanent vars * slot = $FD track = $FE ;lastrack = $FF ;NOT USED * Zero page usage: zpage = $40 zpagelen = 16 temp = $40 command = $41 * Device Driver Parameters: DDPcmd = $42 DDPunit = $43 DDPbuflo = $44 DDPbufhi = $45 DDPblklo = $46 DDPblkhi = $47 CARD = $4E *------------------------------------------------- jmp RW18 *------------------------------------------------- OFFSET = 16 ;default offset *------------------------------------------------- * * READ/WRITE 18 sectors! * READ lda #1 hex 2C WRITE lda #2 sta DDPcmd * Calculate starting block * (OFFSET+track*9) lda track ;0-34 asl asl asl tax ;x=lo lda #0 rol tay ;y=hi txa adc track tax tya adc #0 tay txa adc #OFFSET BOFFLO = *-1 sta BLOCKLO tya adc #>OFFSET BOFFHI = *-1 sta BLOCKHI * Loop for 18 sectors, 2 at a time. ldy #0 :0 tya pha * Do 2 sectors lda BUFTABLE,Y sta ]rbuf0 sta ]wbuf0 ldx BUFTABLE+1,Y stx ]rbuf1 stx ]wbuf1 dex cpx ]rbuf0 jsr RWSECTS pla tay bcs rts * Next 2 sectors inc BLOCKLO bne :1 inc BLOCKHI :1 iny iny cpy #18 bne :0 clc rts rts *----------- * * Read or write 2 sectors * * If the two sectors are sequential * then just go to the Device Driver. * RWSECTS beq JMPDD ldy DDPcmd dey bne WSECTS * Read two non-contiguous sectors RSECTS lda ]rbuf0 ora ]rbuf1 clc beq :rts jsr JMPDDBUF bcs :rts * Now move them to where they belong ldx #$2C ; bit ABS ldy #$99 ; sta ABS,Y * If this sector is to be ignored, * then change sta $FF00,Y to bit. sty ]rmod0 lda ]rbuf0 bne *+5 stx ]rmod0 sty ]rmod1 lda ]rbuf1 bne *+5 stx ]rmod1 ldy #0 :0 lda BLOCKBUF,Y ]rmod0 sta $FF00,Y ]rbuf0 = *-1 lda BLOCKBUF+256,Y ]rmod1 sta $FF00,Y ]rbuf1 = *-1 iny bne :0 :rts rts *----------- * * Write two non-contiguous sectors * WSECTS ldy #0 :0 lda $FF00,Y ]wbuf0 = *-1 sta BLOCKBUF,Y lda $FF00,Y ]wbuf1 = *-1 sta BLOCKBUF+256,Y iny bne :0 JMPDDBUF lda #>BLOCKBUF *----------- * * Jump to Device Driver * * Enter: A - address of buffer * JMPDD sta DDPbufhi * Set block number lda #$11 BLOCKLO = *-1 sta DDPblklo lda #$11 BLOCKHI = *-1 sta DDPblkhi * Get address of firmware lda slot sta DDPunit lsr lsr lsr lsr ora #$C0 sta CARD+1 lda #0 sta CARD sta DDPbuflo * Get address of Device Driver ldy #$FF lda (CARD),Y sta CARD * Jump to it!!! jmp (CARD) *------------------------------------------------- RW18 * * Entry point into RW18 * RW18 pla sta GOTBYTE+1 pla sta GOTBYTE+2 bit $CFFF jsr SWAPZPAG jsr GETBYTE sta command and #$0F asl tax lda cmdadr,X sta :1+1 lda cmdadr+1,X sta :1+2 :1 jsr $FFFF lda GOTBYTE+2 pha lda GOTBYTE+1 pha SWAPZPAG php ldx #0 :0 lda zpage,x ldy ZPAGSAVE,X sta ZPAGSAVE,X sty zpage,x inx cpx #zpagelen bne :0 plp rts cmdadr da SKIP2 ; CMDRIVON da rts ; CMDRIVOF da CMseek da CMreadseq da CMreadgroup da CMwriteseq da CMwritegroup da CMid da CMoffset *------------------------------------------------- CMseek * * SEEK * , * * CMseek jsr GETBYTE jsr GETBYTE sta track rts *------------------------------------------------- CMreadseq *------------------------------------------------- CMreadgroup * * Read sequence * * * Read group * <18 buf adr's> * CMreadseq ldx #1 hex 2C CMreadgroup ldx #18 jsr CMADINFO CMREAD2 jsr READ *------------------------------------------------- * * READ/WRITE exit. * INCTRAK? bit command bcs WHOOP? * If bit 6 set, then inc track bvc ]rts inc track ]rts rts * If bit 7 set then whoop speaker * WARNING:use only with READ WHOOP? bpl ]rts ldy #0 :1 tya bit $C030 :2 sec sbc #1 bne :2 dey bne :1 beq CMREAD2 *------------------------------------------------- CMwriteseq *------------------------------------------------- CMwritegroup * * Same as READ * CMwriteseq ldx #1 hex 2C CMwritegroup ldx #18 jsr CMADINFO jsr WRITE jmp INCTRAK? *------------------------------------------------- CMid * * Change offset based on ID * CMid jsr GETBYTE sta :IDmod+1 ldy #-3 :0 iny iny iny lda :IDlist,y beq :rts :IDmod cmp #$11 bne :0 lda :IDlist+1,y sta BOFFLO lda :IDlist+2,y sta BOFFHI :rts rts :IDlist db $A9 dw 16 ;side one db $AD dw 16+315 ;side two db 0 ;end of list *------------------------------------------------- CMoffset * * Set new block offset * CMoffset jsr GETBYTE sta BOFFLO jsr GETBYTE sta BOFFHI rts *------------------------------------------------- * * Get buffer info. * CMADINFO stx temp ldx #0 :0 jsr GETBYTE sta BUFTABLE,X inx cpx temp bcc :0 tay * If sequence, then fill table :1 iny cpx #18 beq :2 tya sta BUFTABLE,X inx bne :1 :2 rts *------------------------------------------------- * SKIP2 jsr GETBYTE SKIP1 GETBYTE inc GOTBYTE+1 bne GOTBYTE inc GOTBYTE+2 GOTBYTE lda $FFFF rts *------------------------------------------------- sav rw1835 ZPAGSAVE ds $100 BUFTABLE ds 18 ds \ BLOCKBUF ds 512 *------------------------------------------------- \ No newline at end of file + lst off + tr on + org $D000 + xc off + +*------------------------------------------------- +* +* 07/02/87 +* +* Unidisk 3.5 interface for +* 18 sector read/write routine +* +* Copyright 1985, 1987 +* by Roland Gustafsson +* +*------------------------------------------------- +* +* Permanent vars +* + +slot = $FD +track = $FE + ;lastrack = $FF ;NOT USED + +* Zero page usage: + +zpage = $40 +zpagelen = 16 + +temp = $40 +command = $41 + +* Device Driver Parameters: + +DDPcmd = $42 +DDPunit = $43 +DDPbuflo = $44 +DDPbufhi = $45 +DDPblklo = $46 +DDPblkhi = $47 + +CARD = $4E + +*------------------------------------------------- + jmp RW18 +*------------------------------------------------- + +OFFSET = 16 ;default offset + +*------------------------------------------------- +* +* READ/WRITE 18 sectors! +* + +READ lda #1 + hex 2C +WRITE lda #2 + sta DDPcmd + +* Calculate starting block +* (OFFSET+track*9) + + lda track ;0-34 + asl + asl + asl + tax ;x=lo + + lda #0 + rol + tay ;y=hi + + txa + adc track + tax + + tya + adc #0 + tay + + txa + adc #OFFSET +BOFFLO = *-1 + sta BLOCKLO + + tya + adc #>OFFSET +BOFFHI = *-1 + sta BLOCKHI + +* Loop for 18 sectors, 2 at a time. + + ldy #0 +:0 tya + pha + +* Do 2 sectors + + lda BUFTABLE,Y + sta ]rbuf0 + sta ]wbuf0 + ldx BUFTABLE+1,Y + stx ]rbuf1 + stx ]wbuf1 + dex + cpx ]rbuf0 + jsr RWSECTS + + pla + tay + + bcs rts + +* Next 2 sectors + + inc BLOCKLO + bne :1 + inc BLOCKHI + +:1 iny + iny + cpy #18 + bne :0 + + clc +rts rts + +*----------- +* +* Read or write 2 sectors +* +* If the two sectors are sequential +* then just go to the Device Driver. +* +RWSECTS beq JMPDD + + ldy DDPcmd + dey + bne WSECTS + +* Read two non-contiguous sectors + +RSECTS lda ]rbuf0 + ora ]rbuf1 + clc + beq :rts + + jsr JMPDDBUF + bcs :rts + +* Now move them to where they belong + + ldx #$2C ; bit ABS + ldy #$99 ; sta ABS,Y + +* If this sector is to be ignored, +* then change sta $FF00,Y to bit. + + sty ]rmod0 + lda ]rbuf0 + bne *+5 + stx ]rmod0 + + sty ]rmod1 + lda ]rbuf1 + bne *+5 + stx ]rmod1 + + ldy #0 +:0 lda BLOCKBUF,Y +]rmod0 sta $FF00,Y +]rbuf0 = *-1 + lda BLOCKBUF+256,Y +]rmod1 sta $FF00,Y +]rbuf1 = *-1 + iny + bne :0 +:rts rts + +*----------- +* +* Write two non-contiguous sectors +* + +WSECTS ldy #0 +:0 lda $FF00,Y +]wbuf0 = *-1 + sta BLOCKBUF,Y + lda $FF00,Y +]wbuf1 = *-1 + sta BLOCKBUF+256,Y + iny + bne :0 + +JMPDDBUF lda #>BLOCKBUF + +*----------- +* +* Jump to Device Driver +* +* Enter: A - address of buffer +* + +JMPDD sta DDPbufhi + +* Set block number + + lda #$11 +BLOCKLO = *-1 + sta DDPblklo + lda #$11 +BLOCKHI = *-1 + sta DDPblkhi + +* Get address of firmware + + lda slot + sta DDPunit + lsr + lsr + lsr + lsr + ora #$C0 + sta CARD+1 + lda #0 + sta CARD + sta DDPbuflo + +* Get address of Device Driver + + ldy #$FF + lda (CARD),Y + sta CARD + +* Jump to it!!! + + jmp (CARD) + +*------------------------------------------------- RW18 +* +* Entry point into RW18 +* + +RW18 pla + sta GOTBYTE+1 + pla + sta GOTBYTE+2 + + bit $CFFF + + jsr SWAPZPAG + + jsr GETBYTE + sta command + and #$0F + asl + tax + + lda cmdadr,X + sta :1+1 + lda cmdadr+1,X + sta :1+2 +:1 jsr $FFFF + + lda GOTBYTE+2 + pha + lda GOTBYTE+1 + pha + +SWAPZPAG php + ldx #0 +:0 lda zpage,x + ldy ZPAGSAVE,X + sta ZPAGSAVE,X + sty zpage,x + inx + cpx #zpagelen + bne :0 + plp + rts + +cmdadr da SKIP2 ; CMDRIVON + da rts ; CMDRIVOF + da CMseek + da CMreadseq + da CMreadgroup + da CMwriteseq + da CMwritegroup + da CMid + da CMoffset + +*------------------------------------------------- CMseek +* +* SEEK +* , +* +* +CMseek jsr GETBYTE + jsr GETBYTE + sta track + rts + +*------------------------------------------------- CMreadseq +*------------------------------------------------- CMreadgroup +* +* Read sequence +* +* +* Read group +* <18 buf adr's> +* +CMreadseq ldx #1 + hex 2C +CMreadgroup ldx #18 + jsr CMADINFO + +CMREAD2 jsr READ + +*------------------------------------------------- +* +* READ/WRITE exit. +* +INCTRAK? bit command + bcs WHOOP? + +* If bit 6 set, then inc track + + bvc ]rts + inc track +]rts rts + +* If bit 7 set then whoop speaker +* WARNING:use only with READ + +WHOOP? bpl ]rts + ldy #0 +:1 tya + bit $C030 +:2 sec + sbc #1 + bne :2 + dey + bne :1 + beq CMREAD2 + +*------------------------------------------------- CMwriteseq +*------------------------------------------------- CMwritegroup +* +* Same as READ +* + +CMwriteseq ldx #1 + hex 2C +CMwritegroup ldx #18 + jsr CMADINFO + jsr WRITE + jmp INCTRAK? + +*------------------------------------------------- CMid +* +* Change offset based on ID +* + +CMid jsr GETBYTE + sta :IDmod+1 + + ldy #-3 +:0 iny + iny + iny + lda :IDlist,y + beq :rts + +:IDmod cmp #$11 + bne :0 + + lda :IDlist+1,y + sta BOFFLO + lda :IDlist+2,y + sta BOFFHI + +:rts rts + +:IDlist db $A9 + dw 16 ;side one + + db $AD + dw 16+315 ;side two + + db 0 ;end of list + +*------------------------------------------------- CMoffset +* +* Set new block offset +* + +CMoffset jsr GETBYTE + sta BOFFLO + jsr GETBYTE + sta BOFFHI + rts + +*------------------------------------------------- +* +* Get buffer info. +* + +CMADINFO stx temp + ldx #0 +:0 jsr GETBYTE + sta BUFTABLE,X + inx + cpx temp + bcc :0 + tay + +* If sequence, then fill table + +:1 iny + cpx #18 + beq :2 + tya + sta BUFTABLE,X + inx + bne :1 + +:2 rts + +*------------------------------------------------- +* +SKIP2 jsr GETBYTE +SKIP1 + +GETBYTE inc GOTBYTE+1 + bne GOTBYTE + inc GOTBYTE+2 +GOTBYTE lda $FFFF + rts + +*------------------------------------------------- + + sav rw1835 + +ZPAGSAVE ds $100 +BUFTABLE ds 18 + ds \ +BLOCKBUF ds 512 + +*------------------------------------------------- diff --git a/03 Disk Protection/CUBE.S b/03 Disk Protection/CUBE.S index f015bda..a10e7c8 100755 --- a/03 Disk Protection/CUBE.S +++ b/03 Disk Protection/CUBE.S @@ -1 +1,174 @@ - lst off *------------------------------------------------- rotcube mainYoffset = 46 ;(192-60)/2 botYoffset = 72 mainXoffset = 68 ;(280-144)/2 color = $E4 page = $E6 dum 0 index ds 1 ysave ds 1 yadd ds 1 yoffset ds 1 dend *------------------------------------------------- rotcube jsr $f3e2 ;hgr jsr $f3d8 ;hgr2 lda #1 sta yadd sta yoffset * Draw on page not showing: mainloop lda page eor #$60 sta page ldx #$7F jsr draw * If not a //c, then wait for vbl lda $FBC0 beq :is2c lda $C019 bpl *-3 lda $C019 bmi *-3 :is2c * Now display that page bit $C054 lda page cmp #$20 beq *+5 bit $C055 * Now erase old image from last page eor #$60 sta :smc0+2 sta :smc1+2 ldx #$20 lda #0 :loop tay :smc0 sta $2000,y :smc1 sta $2080,y iny bpl :smc0 inc :smc0+2 inc :smc1+2 dex bne :loop inc index jmp mainloop *------------------------------------------------- draw stx color ldy #12-1 :drawloop lda drawlist,y sty ysave pha and #15 jsr getpoint tax tya ldy #0 jsr $f457 ;plot pla lsr lsr lsr lsr jsr getpoint ldx #0 jsr $f53a ;lineto ldy ysave dey bpl :drawloop lda yoffset clc adc yadd bne :not0 inc yadd ;make +1 inc yadd :not0 cmp #191-48-botYoffset bcc :0 dec yadd ;make -1 dec yadd :0 sta yoffset rts *------------------------------------------------- * * given a = point number, return a = xcoor, y = ycoor * getpoint tay * Get index into tables asl ;*16 asl asl asl adc index and #$3F tax tya and #4 ;bottom? cmp #4 * Compute ycoor lda ydata,x bcc :not_bot adc #botYoffset-1 :not_bot adc yoffset tay * Compute xcoor lda xdata,x adc #mainXoffset rts *------------------------------------------------- drawlist hex 01122330 ;draw top hex 45566774 ;draw bottom hex 04152637 ;draw connecting lines xdata hex 908F8E8C8A87837F7A757069635C564F hex 484039332C261F1A15100C0805030100 hex 0000010305080C10151A1F262C333940 hex 474F565C636970757A7F83878A8C8E8F ydata hex 181A1C1E21232527282A2B2D2E2E2F2F hex 2F2F2F2E2E2D2B2A28272523211E1C1A hex 181513110E0C0A080705040201010000 hex 000000010102040507080A0C0E111315 *------------------------------------------------- \ No newline at end of file + lst off + +*------------------------------------------------- rotcube + +mainYoffset = 46 ;(192-60)/2 +botYoffset = 72 +mainXoffset = 68 ;(280-144)/2 + +color = $E4 +page = $E6 + + dum 0 +index ds 1 +ysave ds 1 +yadd ds 1 +yoffset ds 1 + dend + +*------------------------------------------------- + +rotcube jsr $f3e2 ;hgr + jsr $f3d8 ;hgr2 + + lda #1 + sta yadd + + sta yoffset + +* Draw on page not showing: + +mainloop lda page + eor #$60 + sta page + ldx #$7F + jsr draw + +* If not a //c, then wait for vbl + + lda $FBC0 + beq :is2c + lda $C019 + bpl *-3 + lda $C019 + bmi *-3 +:is2c + +* Now display that page + + bit $C054 + lda page + cmp #$20 + beq *+5 + bit $C055 + +* Now erase old image from last page + + eor #$60 + sta :smc0+2 + sta :smc1+2 + ldx #$20 + lda #0 +:loop tay +:smc0 sta $2000,y +:smc1 sta $2080,y + iny + bpl :smc0 + inc :smc0+2 + inc :smc1+2 + dex + bne :loop + + inc index + jmp mainloop + +*------------------------------------------------- + +draw stx color + + ldy #12-1 +:drawloop lda drawlist,y + sty ysave + + pha + and #15 + jsr getpoint + + tax + tya + ldy #0 + jsr $f457 ;plot + + pla + lsr + lsr + lsr + lsr + jsr getpoint + ldx #0 + jsr $f53a ;lineto + + ldy ysave + dey + bpl :drawloop + + lda yoffset + clc + adc yadd + bne :not0 + + inc yadd ;make +1 + inc yadd + +:not0 cmp #191-48-botYoffset + bcc :0 + + dec yadd ;make -1 + dec yadd + +:0 sta yoffset + rts + +*------------------------------------------------- +* +* given a = point number, return a = xcoor, y = ycoor +* + +getpoint tay + +* Get index into tables + + asl ;*16 + asl + asl + asl + adc index + and #$3F + tax + tya + + and #4 ;bottom? + cmp #4 + +* Compute ycoor + + lda ydata,x + bcc :not_bot + adc #botYoffset-1 + +:not_bot adc yoffset + tay + +* Compute xcoor + + lda xdata,x + adc #mainXoffset + rts + +*------------------------------------------------- + +drawlist hex 01122330 ;draw top + hex 45566774 ;draw bottom + hex 04152637 ;draw connecting lines + +xdata hex 908F8E8C8A87837F7A757069635C564F + hex 484039332C261F1A15100C0805030100 + hex 0000010305080C10151A1F262C333940 + hex 474F565C636970757A7F83878A8C8E8F + +ydata hex 181A1C1E21232527282A2B2D2E2E2F2F + hex 2F2F2F2E2E2D2B2A28272523211E1C1A + hex 181513110E0C0A080705040201010000 + hex 000000010102040507080A0C0E111315 + +*------------------------------------------------- diff --git a/03 Disk Protection/LOSHOW.S b/03 Disk Protection/LOSHOW.S index 9045d50..a865141 100755 --- a/03 Disk Protection/LOSHOW.S +++ b/03 Disk Protection/LOSHOW.S @@ -1 +1,371 @@ - lst off org $c00 *------------------------------------------------- dum 0 curpage ds 1 xsave ds 1 ysave ds 1 asave ds 1 temp ds 1 tmplo ds 1 tmphi ds 1 level ds 1 isGS? ds 1 dend framebase = $1000 *------------------------------------------------- show * * put on the show! * show bit $C010 lda #0 sta isGS? bit $C081 sec jsr $fe1f ;GS? bcs :notGS inc isGS? * Use special show frame routine for //GS that * writes directly to bank $E0, since page two * text is not properly shadowed to that bank. ldx #$4C ;jmp ldy #GSshowframe lda #>GSshowframe stx showframe sty showframe+1 sta showframe+2 * Make our lookup tables up in ramcard area :notGS bit $C083 bit $C083 jsr MAKEfade_tbls jsr lgr :again ldx #0 :fadein stx level lda #0 jsr showframe ldx level inx cpx #15 bcc :fadein * Here we go... lda #0 :floop pha ldx #15 jsr showframe pla clc adc #1 cmp #23 bcc :floop ldx #15 :fadeout stx level lda #22 jsr showframe ldx level dex bpl :fadeout bit $C000 bpl *-3 bit $C010 jmp :again *------------------------------------------------- lgr * * Clear and display lo-resolution screen * lgr sta $C000 ;turn off 55.54 select sta $C00C ;40 columns bit $C052 ;full screen bit $C055 ;show page two bit $C056 ;lores bit $C050 ;graphics on lda #4 ;use page one next sta curpage ldy #0 sty tmplo sta tmphi tya ldx #8 :0 sta (tmplo),y iny bne :0 inc tmphi dex bne :0 rts *------------------------------------------------- loget * * Enter with a:frame number * x:fade level * showframe asl asl adc #>framebase sta :src+2 ;hi byte txa ora #>fade_table sta :fademod+2 lda curpage sta :dst+2 eor #4!8 sta curpage lda #4 sta temp ldx #0 :loop :src ldy $1100,x :fademod lda fade_table+$F00,y :dst sta $0400,x inx bne :loop inc :src+2 ;hibyte inc :dst+2 ; " " dec temp bne :loop ]waitvbl jsr waitvbl bit $C055 lda curpage cmp #4 beq *+5 bit $C054 rts GSshowframe asl asl adc #>framebase sta :src+2 ;hi byte txa ora #>fade_table sta :fademod+2 lda curpage sta :dst+2 eor #4!8 sta curpage lda #4 sta temp ldx #0 :loop :src ldy $1100,x :fademod lda fade_table+$F00,y :dst stal $E00400,x inx bne :loop inc :src+2 ;hibyte inc :dst+2 ; " " dec temp bne :loop beq ]waitvbl *------------------------------------------------- waitvbl * * Wait for a few vbl's to go by! * waitvbl ldx #6 :0 bit $C019 bpl :0 :1 bit $C019 bmi :1 dex bne :0 rts *------------------------------------------------- MAKEfade_tbls * * Make 16 lookup tables each containing 256 bytes * for the 16 levels of fade-in. * MAKEfade_tbls dum 0 :curtmp ds 2 ;ptr into current tmp_scale table :curfade ds 2 ;ptr into current page of fade table :temp ds 1 :ysave ds 1 dend jsr MAKEtmp_scale ldy #tmp_scale lda #>tmp_scale sty :curtmp sta :curtmp+1 ldy #fade_table lda #>fade_table sty :curfade sta :curfade+1 * byte loop ldy #0 :bloop tya and #$0F jsr :convert sta :temp tya lsr lsr lsr lsr jsr :convert asl asl asl asl ora :temp sta (:curfade),y iny bne :bloop * next fade table inc :curfade+1 * next tmp table clc lda :curtmp adc #16 sta :curtmp bcc :bloop rts * given a=0-15, in lores unsequential grey scale, * convert it back to sequential, lookup new value * in tmp_scale table and then convert back to * lores unsequential. :convert sty :ysave * Convert lores color back to sequential 00-0F tax lda :unlores,x * Scale it tay lda (:curtmp),y * Convert back to unsequential lores color tax lda isGS? beq :notGS lda :loresGS,x bra :isGS :notGS lda :lores2e,x :isGS ldy :ysave rts :unlores hex 000301070405020a hex 06080b0c090e0d0f :loresGS hex 0002060104050803 hex 090c070a0b0e0d0f :lores2e hex 00000000 hex 02020202 hex 06060606 hex 07070707 *------------------------------------------------- MAKEtmp_scale * * Make lookup table that contains values * for 0-15 multiplied by 1/16... 16/16. * MAKEtmp_scale dum 0 :color ds 1 :scale ds 1 dend lda #1 ;start with 1/16th sta :scale :sloop ldy #0 :cloop sty :color lda #0 ldx :scale :mloop clc adc :color dex bne :mloop lsr lsr lsr lsr :smc sta tmp_scale,y iny cpy #16 bne :cloop inc :scale lda :smc+1 clc adc #16 sta :smc+1 bcc :sloop rts *------------------------------------------------- dum $D000 fade_table ds $1000 tmp_scale ds $100 dend *------------------------------------------------- EOF \ No newline at end of file + lst off + + org $c00 + +*------------------------------------------------- + + dum 0 +curpage ds 1 +xsave ds 1 +ysave ds 1 +asave ds 1 +temp ds 1 +tmplo ds 1 +tmphi ds 1 +level ds 1 +isGS? ds 1 + dend + +framebase = $1000 + +*------------------------------------------------- show +* +* put on the show! +* + +show bit $C010 + + lda #0 + sta isGS? + + bit $C081 + sec + jsr $fe1f ;GS? + bcs :notGS + + inc isGS? + +* Use special show frame routine for //GS that +* writes directly to bank $E0, since page two +* text is not properly shadowed to that bank. + + ldx #$4C ;jmp + ldy #GSshowframe + lda #>GSshowframe + stx showframe + sty showframe+1 + sta showframe+2 + +* Make our lookup tables up in ramcard area + +:notGS bit $C083 + bit $C083 + + jsr MAKEfade_tbls + + jsr lgr + +:again + + ldx #0 +:fadein stx level + lda #0 + jsr showframe + ldx level + inx + cpx #15 + bcc :fadein + +* Here we go... + + lda #0 +:floop pha + ldx #15 + jsr showframe + pla + clc + adc #1 + cmp #23 + bcc :floop + + ldx #15 +:fadeout stx level + lda #22 + jsr showframe + ldx level + dex + bpl :fadeout + + bit $C000 + bpl *-3 + bit $C010 + + jmp :again + +*------------------------------------------------- lgr +* +* Clear and display lo-resolution screen +* + +lgr sta $C000 ;turn off 55.54 select + sta $C00C ;40 columns + bit $C052 ;full screen + bit $C055 ;show page two + bit $C056 ;lores + bit $C050 ;graphics on + + lda #4 ;use page one next + sta curpage + + ldy #0 + sty tmplo + sta tmphi + + tya + ldx #8 + +:0 sta (tmplo),y + iny + bne :0 + + inc tmphi + dex + bne :0 + + rts + +*------------------------------------------------- loget +* +* Enter with a:frame number +* x:fade level +* + +showframe asl + asl + adc #>framebase + sta :src+2 ;hi byte + + txa + ora #>fade_table + sta :fademod+2 + + lda curpage + sta :dst+2 + eor #4!8 + sta curpage + + lda #4 + sta temp + + ldx #0 +:loop +:src ldy $1100,x +:fademod lda fade_table+$F00,y +:dst sta $0400,x + inx + bne :loop + + inc :src+2 ;hibyte + inc :dst+2 ; " " + + dec temp + bne :loop + +]waitvbl jsr waitvbl + + bit $C055 + lda curpage + cmp #4 + beq *+5 + bit $C054 + + rts + +GSshowframe asl + asl + adc #>framebase + sta :src+2 ;hi byte + + txa + ora #>fade_table + sta :fademod+2 + + lda curpage + sta :dst+2 + eor #4!8 + sta curpage + + lda #4 + sta temp + + ldx #0 +:loop +:src ldy $1100,x +:fademod lda fade_table+$F00,y +:dst stal $E00400,x + inx + bne :loop + + inc :src+2 ;hibyte + inc :dst+2 ; " " + + dec temp + bne :loop + beq ]waitvbl + +*------------------------------------------------- waitvbl +* +* Wait for a few vbl's to go by! +* + +waitvbl ldx #6 +:0 bit $C019 + bpl :0 +:1 bit $C019 + bmi :1 + dex + bne :0 + rts + +*------------------------------------------------- MAKEfade_tbls +* +* Make 16 lookup tables each containing 256 bytes +* for the 16 levels of fade-in. +* + +MAKEfade_tbls dum 0 +:curtmp ds 2 ;ptr into current tmp_scale table +:curfade ds 2 ;ptr into current page of fade table +:temp ds 1 +:ysave ds 1 + dend + + jsr MAKEtmp_scale + + ldy #tmp_scale + lda #>tmp_scale + sty :curtmp + sta :curtmp+1 + + ldy #fade_table + lda #>fade_table + sty :curfade + sta :curfade+1 + +* byte loop + + ldy #0 + +:bloop tya + and #$0F + jsr :convert + sta :temp + + tya + lsr + lsr + lsr + lsr + jsr :convert + asl + asl + asl + asl + ora :temp + + sta (:curfade),y + + iny + bne :bloop + +* next fade table + + inc :curfade+1 + +* next tmp table + + clc + lda :curtmp + adc #16 + sta :curtmp + bcc :bloop + + rts + +* given a=0-15, in lores unsequential grey scale, +* convert it back to sequential, lookup new value +* in tmp_scale table and then convert back to +* lores unsequential. + +:convert sty :ysave + +* Convert lores color back to sequential 00-0F + + tax + lda :unlores,x + +* Scale it + + tay + lda (:curtmp),y + +* Convert back to unsequential lores color + + tax + lda isGS? + beq :notGS + lda :loresGS,x + bra :isGS + +:notGS lda :lores2e,x + +:isGS ldy :ysave + rts + +:unlores hex 000301070405020a + hex 06080b0c090e0d0f + +:loresGS hex 0002060104050803 + hex 090c070a0b0e0d0f + +:lores2e hex 00000000 + hex 02020202 + hex 06060606 + hex 07070707 + +*------------------------------------------------- MAKEtmp_scale +* +* Make lookup table that contains values +* for 0-15 multiplied by 1/16... 16/16. +* + +MAKEtmp_scale dum 0 +:color ds 1 +:scale ds 1 + dend + + lda #1 ;start with 1/16th + sta :scale + +:sloop ldy #0 +:cloop sty :color + lda #0 + ldx :scale +:mloop clc + adc :color + dex + bne :mloop + lsr + lsr + lsr + lsr +:smc sta tmp_scale,y + iny + cpy #16 + bne :cloop + inc :scale + lda :smc+1 + clc + adc #16 + sta :smc+1 + bcc :sloop + rts + +*------------------------------------------------- + + dum $D000 +fade_table ds $1000 +tmp_scale ds $100 + dend + +*------------------------------------------------- EOF diff --git a/03 Disk Protection/POPBOOT0.S b/03 Disk Protection/POPBOOT0.S index 0fc350d..9cf093b 100755 --- a/03 Disk Protection/POPBOOT0.S +++ b/03 Disk Protection/POPBOOT0.S @@ -1 +1,951 @@ -* boot org = $800 lst off xc off REDFLAG79 = $23B ; in aux mem! *------------------------------- * $800 TS (0,0) boot sector SLOT = $2b sector = $50 text = $fb2f home = $fc58 vtab = $FB5B cout = $FDF0 normal = $fe84 pr0 = $fe93 in0 = $fe89 *------------------------------- smclo = $4E smchi = $4F rw18 = $d000 slot = $fd track = $fe lastrack = $ff dum $00 dest ds 2 source ds 2 endsourc ds 2 dend *------------------------------------------------- org org hex 01 entry lda #$60 sta entry lda #MAKEBIT sta smclo ldx #$ff stx $4fb stx $3f3 stx $3f4 stx $7831 stx $c000 ;80store off stx $c002 ;RAMRD main stx $9fd8 stx $c004 ;RAMWRT main stx $c00c ;80col off stx $c00e ;Altcharset off stx $c081 ;write RAM, read ROM (2nd 4k bank) txs jsr text jsr home jsr normal jsr pr0 sta $DF35 jsr in0 stx $8492 ldx SLOT txa lsr lsr lsr lsr ora #$c0 sta :rdsect+2 lda #$0f sta sector :0 ldy sector lda skewtbl,y sta $3d lda sectaddr,y beq :1 sta $27 inc $9fd8 :rdsect jsr $005c :1 dec sector bne :0 beq decode skewtbl hex 00,0d,0b,09,07,05,03,01 hex 0e,0c,0a,08,06,04,02,0f sectaddr hex 00,09,0a,0b,00,0c,0d,0e hex 30,31,32,33,34,10,11,2f decode ldx #14 :loop lda sectaddr,x beq :nope sta :smc0+2 sta :smc1+2 ldy #0 :loop1 :smc0 lda $FF00,y eor $2F00,y :smc1 sta $FF00,y eor $7831 ;bogus garbage sta $7831 ; " " " " sta $3C iny bne :loop1 :nope dex bpl :loop ldx SLOT stage2 stx slot jsr check128k ;check for 128K memory jsr moverw18 ;& move RW18 to D000 lda #0 sta lastrack jsr rw18 hex 07,a9 ;Bbund ID byte jsr rw18 hex 00,01,00 ;drive 1 on jsr rw18 ;seek track 1 hex 02,00,01 * load & run stage 3 boot * from drive 1 jsr rw18 hex c3,ee jmp $ee00 *------------------------------------------------- * Check for AUX memory routine CHECKER lda #$EE sta $C005 lda #>MAKEBIT sta smchi sta $C003 sta $0800 lda $0C00 cmp #$EE bne :0 asl $0C00 lda $0800 cmp $0C00 beq :1 :0 clc :1 sta $C004 sta $C002 rts CHECKEND = *-CHECKER *------------------------------------------------- * * Check to make sure //c or //e * with 128k * *------------------------------- hex 34 hex 55 hex 99 check128k sta $c081 lda $FBB3 ;Apple // family ID byte cmp #6 bne NOT128K ;Must be e/c/GS bit $C017 bmi NOT128K ldx #CHECKEND :0 lda CHECKER,X sta $180,X dex bpl :0 jsr $180 bcs NOT128K rts *------------------------------- * Turn off drive and display message NOT128K ldx SLOT lda $C088,X jsr text jsr home lda #8 jsr vtab ldy #0 :0 lda MEMTEXT,Y beq * jsr cout cmp #$8D bne :1 lda #4 sta $24 :1 iny bne :0 MEMTEXT hex 8D asc "REQUIRES A //C OR //E WITH 128K" hex 00 *------------------------------- * Move RW18 * d0 < 30.40 *------------------------------- moverw18 bit $c08b bit $c08b ;rd/wrt RAM, 1st 4k bank lda #$d0 ldx #$30 ldy #$40 * 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 lda #$24 sta (smclo),y 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 MAKEBIT rts hex FF *------------------------------------------------- * * HLS APPLE COPY PROTECTION * COPYRIGHT (C) 1987 HLS DUPLICATION * * CONTACT ROBERT FREEDMAN 408-773-1300 * IF THERE ARE QUESTIONS ABOUT USE OF * THIS CODE * * EXIT clc IF A O K * sec IF PIRATE * *------------------------------------------------- OBJSCT = $07 ;PHYSICAL SECTOR # * ZERO PAGE * IF THIS CONFLICTS WITH YOUR CODE * CHANGE THE FOLLOWING ZERO PAGE * LOCATIONS, OR USE THE SAVE ZERO * PAGE ROUTINE HDRC = $F0 HDRS = HDRC+1 HDRT = HDRC+2 HDRV = HDRC+3 HEADER SECTOR LSRETRY = HDRC+4 ;NIB READ RETRIES PRETRY = HDRC+5 ;OBJSCT RETRIES NPTR = HDRC+6 NPTRH = HDRC+7 MEM1 = HDRC+8 MEM2 = HDRC+9 *------------------------------------------------- CheckCP lda #10 sta LSRETRY lda #>REDFLAG79 sta smchi ldx SLOT lda $C089,X lda $C08E,X lda #:NIBS ; !!!!! LOW BYTE sta NPTR lda #>:NIBS ; !!!!! HIGH BYTE sta NPTRH :AGAIN lda #$80 sta PRETRY :M1 dec PRETRY beq :LSFAIL jsr RADR16 bcs :LSFAIL lda HDRS cmp #OBJSCT bne :M1 ldy #0 :M2 lda $C08C,X bpl :M2 dey beq :LSFAIL cmp #$D5 bne :M2 ldy #0 :M3 lda $C08C,X bpl :M3 dey beq :LSFAIL cmp #$E7 bne :M3 :M4 lda $C08C,X bpl :M4 cmp #$E7 bne :LSFAIL :M5 lda $C08C,X bpl :M5 cmp #$E7 bne :LSFAIL lda $C08D,X ldy #$10 bit $6 ;3 US. ( FOR //C) :M6 lda $C08C,X bpl :M6 dey beq :LSFAIL cmp #$EE bne :M6 * NOW AT 1/2 NIBBLES * * INSTEAD OF COMPARING AGAINST A TABLE * THE DATA READ FROM THE DISK CAN BE * USED IN YOUR PROGRAM. BE CAREFUL * WHEN MODIFYING THIS PART OF THE CODE. * KEEP THE CYCLE COUNTS CONSTANT. ldy #7 :M7 lda $C08C,X ; READ DISK DATA bpl :M7 cmp (NPTR),Y ; COMPARE AGAINST TABLE bne :LSFAIL1 dey bpl :M7 bmi :GOOD :LSFAIL jmp :LSFAIL1 * A O K :GOOD eor #$79!$FC iny ldx #6 dex sta $C000,x sta (smclo),y dex sta $C000,x eor #$ED sta $239 eor #$23 sta $4E jmp yippee * FAILED, try again :LSFAIL1 ldy #-1 tya dec LSRETRY beq :GOOD jmp :AGAIN :NIBS db $FC,$EE,$EE,$FC db $E7,$EE,$FC,$E7 *------------------------------------------------- * * Read address mark * RADR16 ldy #$FD ;READ ADR HDR sty MEM1 tya eor #REDFLAG79!$FD sta smclo :RA1 iny bne :RA2 inc MEM1 beq :RAEXIT :RA2 lda $C08C,X bpl :RA2 :RA3 cmp #$D5 bne :RA1 nop :RA4 lda $C08C,X bpl :RA4 cmp #$AA bne :RA3 ldy #3 :RA5 lda $C08C,X bpl :RA5 cmp #$96 bne :RA3 lda #0 :RA6 sta MEM2 :RA7 lda $C08C,X bpl :RA7 rol sta MEM1 :RA8 lda $C08C,X bpl :RA8 and MEM1 sta HDRC,Y eor MEM2 dey bpl :RA6 tay nop clc rts :RAEXIT sec ]rts rts oscsh sec jsr $FE1F bcs * jsr $1000 jmp ($FFFC) *------------------------------------------------- yippee ldx SLOT lda $C061 bpl ]rts lda $C062 bpl ]rts lda $C000 bpl ]rts bit $C010 sta :cmp+1 ldy #-3 :loop iny iny iny lda :dispatch,y beq ]rts :cmp cmp #$11 bne :loop lda :dispatch+1,y sta 0 lda :dispatch+2,y sta 1 bit $C081 lda $C088,x jmp (0) :dispatch hex FF da oscsh asc "!" da rcmess hex 8D da confusion asc "@" da rotcube asc "^" da drive db 0 *------------------------------------------------- * * motorcycle disk drive * drive lda $C089,x ;drive back on! :loop lda $C087,x lda $C080,x jsr :delay lda $C085,x lda $C086,x jsr :delay lda $C083,x lda $C084,x jsr :delay lda $C081,x lda $C082,x jsr :delay jmp :loop :delay lda #6 sta 0 :del2 bit $C070 nop nop bit $C064 bmi *-3 dec 0 bne :del2 rts *------------------------------------------------- rotcube mainYoffset = 46 ;(192-60)/2 botYoffset = 72 mainXoffset = 68 ;(280-144)/2 color = $E4 page = $E6 dum 0 index ds 1 ysave ds 1 yadd ds 1 yoffset ds 1 dend *------------------------------------------------- rotcube jsr $f3e2 ;hgr jsr $f3d8 ;hgr2 lda #1 sta yadd sta yoffset * Draw on page not showing: mainloop lda page eor #$60 sta page ldx #$7F jsr draw * If not a //c, then wait for vbl lda $FBC0 beq :is2c lda $C019 bpl *-3 lda $C019 bmi *-3 :is2c * Now display that page bit $C054 lda page cmp #$20 beq *+5 bit $C055 * Now erase old image from last page eor #$60 sta :smc0+2 sta :smc1+2 ldx #$20 lda #0 :loop tay :smc0 sta $2000,y :smc1 sta $2080,y iny bpl :smc0 inc :smc0+2 inc :smc1+2 dex bne :loop inc index jmp mainloop *------------------------------------------------- draw stx color ldy #12-1 :drawloop lda drawlist,y sty ysave pha and #15 jsr getpoint tax tya ldy #0 jsr $f457 ;plot pla lsr lsr lsr lsr jsr getpoint ldx #0 jsr $f53a ;lineto ldy ysave dey bpl :drawloop lda yoffset clc adc yadd bne :not0 inc yadd ;make +1 inc yadd :not0 cmp #191-48-botYoffset bcc :0 dec yadd ;make -1 dec yadd :0 sta yoffset rts *------------------------------------------------- * * given a = point number, return a = xcoor, y = ycoor * getpoint tay * Get index into tables asl ;*16 asl asl asl adc index and #$3F tax tya and #4 ;bottom? cmp #4 * Compute ycoor lda ydata,x bcc :not_bot adc #botYoffset-1 :not_bot adc yoffset tay * Compute xcoor lda xdata,x adc #mainXoffset rts *------------------------------------------------- drawlist hex 01122330 ;draw top hex 45566774 ;draw bottom hex 04152637 ;draw connecting lines xdata hex 908F8E8C8A87837F7A757069635C564F hex 484039332C261F1A15100C0805030100 hex 0000010305080C10151A1F262C333940 hex 474F565C636970757A7F83878A8C8E8F ydata hex 181A1C1E21232527282A2B2D2E2E2F2F hex 2F2F2F2E2E2D2B2A28272523211E1C1A hex 181513110E0C0A080705040201010000 hex 000000010102040507080A0C0E111315 *------------------------------------------------- confusion dum 0 xr ds 1 yr ds 1 randseed ds 1 temp ds 1 dend hgr2 = $F3D8 plot = $F457 hcolor = $F6F0 * Confusion triangle confusion lda #$7F sta $E4 ;hcolor=3 jsr hgr2 * xr=xarray(0), yr=yarray(0) ldx xarray ldy yarray stx xr sty yr * Plot that dot :loop lda $C000 bpl :nokey bit $C010 cmp #$E0 bcc *+4 and #$DF cmp #"C" bne :nokey :randcol jsr getrandcol sta temp jsr $F3F4 ;clear to that color :randloop jsr getrandcol tax eor temp bmi :randloop ;different hi bits cpx temp ;same color beq :randloop :nokey ldy #0 lda xr asl tax bcc :skip iny :skip lda yr jsr plot lda yr ldx $E0 ldy $E1 inx bne *+3 iny jsr plot * Get a random number between 0-2 jsr random sec :sub30 sbc #30 bcs :sub30 adc #30 sec :sub3 sbc #3 bcs :sub3 adc #3 tax *----------- * xr stuff: * determine which midpoint routine to use lda xarray,x cmp xr bge :xarr_xr * If xarray(rand) < xr then: * xr = xarray + ( xr - xarray) / 2 lda xr sec sbc xarray,x lsr clc adc xarray,x jmp :sta_xr * If xarray(rand) >= xr then: * xr = xr + ( xarray - xr ) / 2 :xarr_xr lda xarray,x sec sbc xr lsr clc adc xr :sta_xr sta xr *----------- * yr stuff: * determine which midpoint routine to use lda yarray,x cmp yr bge :yarr_yr * If yarray(rand) < yr then: * yr = yarray + ( yr - yarray) / 2 lda yr sec sbc yarray,x lsr clc adc yarray,x jmp :sta_yr * If yarray(rand) >= yr then: * yr = yr + ( yarray - yr ) / 2 :yarr_yr lda yarray,x sec sbc yr lsr clc adc yr :sta_yr sta yr jmp :loop xarray db 70,139,0 yarray db 0,191,191 random lda randseed adc #$23 sta randseed eor $C020 ;a little randomness rts getrandcol jsr random and #7 tax jmp hcolor *------------------------------------------------- rcmess rcmess ldy #0 :0 lda :text,y beq :lores jsr $FDF0 iny bne :0 :lores bit $c000 bpl :lores sta $c00d ;80 col sta $c001 ;80 store bit $c056 bit $c052 bit $c050 bit $c05e ;merez :loop lda #$FF jsr :random sta $30 ;color lda #80 ;max x jsr :random lsr tay bit $c054 bcs *+5 bit $c055 lda #48 ;max y jsr :random jsr $F800 ;plot jmp :loop :random sta 1 lda 0 adc #$23 sta 0 eor $C020 cmp 1 bcc :ok :loop2 sbc 1 bcs :loop2 adc 1 :ok rts :text hex 8d8d asc "8/25/89",8d8d8d asc "Robert!",8d8d8d asc "Jordan and Roland wish you the very",8d8d asc "Brightest College Years.",8d8d8d8d8d asc " meres !",8d,8d asc " meres !",8d,8d asc " meres !" brk *------------------------------------------------- EOF lst on da * lst off \ No newline at end of file +* boot +org = $800 + lst off + xc off + +REDFLAG79 = $23B ; in aux mem! + +*------------------------------- +* $800 TS (0,0) boot sector + +SLOT = $2b +sector = $50 + +text = $fb2f +home = $fc58 +vtab = $FB5B +cout = $FDF0 +normal = $fe84 +pr0 = $fe93 +in0 = $fe89 + +*------------------------------- + +smclo = $4E +smchi = $4F + +rw18 = $d000 + +slot = $fd +track = $fe +lastrack = $ff + + dum $00 + +dest ds 2 +source ds 2 +endsourc ds 2 + + dend + +*------------------------------------------------- + + org org + + hex 01 + +entry lda #$60 + sta entry + + lda #MAKEBIT + sta smclo + + ldx #$ff + stx $4fb + stx $3f3 + stx $3f4 + stx $7831 + stx $c000 ;80store off + stx $c002 ;RAMRD main + stx $9fd8 + stx $c004 ;RAMWRT main + stx $c00c ;80col off + stx $c00e ;Altcharset off + stx $c081 ;write RAM, read ROM (2nd 4k bank) + txs + jsr text + jsr home + jsr normal + jsr pr0 + sta $DF35 + jsr in0 + stx $8492 + + ldx SLOT + txa + lsr + lsr + lsr + lsr + ora #$c0 + sta :rdsect+2 + lda #$0f + sta sector + +:0 ldy sector + lda skewtbl,y + sta $3d + lda sectaddr,y + beq :1 + sta $27 + + inc $9fd8 + +:rdsect jsr $005c +:1 dec sector + bne :0 + + beq decode + +skewtbl hex 00,0d,0b,09,07,05,03,01 + hex 0e,0c,0a,08,06,04,02,0f + +sectaddr hex 00,09,0a,0b,00,0c,0d,0e + hex 30,31,32,33,34,10,11,2f + +decode ldx #14 +:loop lda sectaddr,x + beq :nope + + sta :smc0+2 + sta :smc1+2 + + ldy #0 +:loop1 +:smc0 lda $FF00,y + eor $2F00,y +:smc1 sta $FF00,y + eor $7831 ;bogus garbage + sta $7831 ; " " " " + sta $3C + iny + bne :loop1 + +:nope dex + bpl :loop + + ldx SLOT + +stage2 stx slot + + jsr check128k ;check for 128K memory + + jsr moverw18 ;& move RW18 to D000 + + lda #0 + sta lastrack + + jsr rw18 + hex 07,a9 ;Bbund ID byte + + jsr rw18 + hex 00,01,00 ;drive 1 on + + jsr rw18 ;seek track 1 + hex 02,00,01 + +* load & run stage 3 boot +* from drive 1 + + jsr rw18 + hex c3,ee + + jmp $ee00 + +*------------------------------------------------- +* Check for AUX memory routine + +CHECKER lda #$EE + sta $C005 + lda #>MAKEBIT + sta smchi + sta $C003 + sta $0800 + lda $0C00 + cmp #$EE + bne :0 + asl $0C00 + lda $0800 + cmp $0C00 + beq :1 +:0 clc +:1 sta $C004 + sta $C002 + rts + +CHECKEND = *-CHECKER + +*------------------------------------------------- +* +* Check to make sure //c or //e +* with 128k +* +*------------------------------- + + hex 34 + hex 55 + hex 99 + +check128k + sta $c081 + + lda $FBB3 ;Apple // family ID byte + cmp #6 + bne NOT128K ;Must be e/c/GS + + bit $C017 + bmi NOT128K + + ldx #CHECKEND +:0 lda CHECKER,X + sta $180,X + dex + bpl :0 + + jsr $180 + bcs NOT128K + + rts + +*------------------------------- +* Turn off drive and display message + +NOT128K ldx SLOT + lda $C088,X + + jsr text + jsr home + lda #8 + jsr vtab + + ldy #0 +:0 lda MEMTEXT,Y + beq * + jsr cout + cmp #$8D + bne :1 + lda #4 + sta $24 +:1 iny + bne :0 + +MEMTEXT hex 8D + asc "REQUIRES A //C OR //E WITH 128K" + hex 00 + +*------------------------------- +* Move RW18 +* d0 < 30.40 +*------------------------------- +moverw18 + bit $c08b + bit $c08b ;rd/wrt RAM, 1st 4k bank + + lda #$d0 + ldx #$30 + ldy #$40 + +* 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 + lda #$24 + sta (smclo),y + 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 + +MAKEBIT rts + hex FF + +*------------------------------------------------- +* +* HLS APPLE COPY PROTECTION +* COPYRIGHT (C) 1987 HLS DUPLICATION +* +* CONTACT ROBERT FREEDMAN 408-773-1300 +* IF THERE ARE QUESTIONS ABOUT USE OF +* THIS CODE +* +* EXIT clc IF A O K +* sec IF PIRATE +* +*------------------------------------------------- + +OBJSCT = $07 ;PHYSICAL SECTOR # + +* ZERO PAGE +* IF THIS CONFLICTS WITH YOUR CODE +* CHANGE THE FOLLOWING ZERO PAGE +* LOCATIONS, OR USE THE SAVE ZERO +* PAGE ROUTINE + +HDRC = $F0 +HDRS = HDRC+1 +HDRT = HDRC+2 +HDRV = HDRC+3 HEADER SECTOR +LSRETRY = HDRC+4 ;NIB READ RETRIES +PRETRY = HDRC+5 ;OBJSCT RETRIES +NPTR = HDRC+6 +NPTRH = HDRC+7 +MEM1 = HDRC+8 +MEM2 = HDRC+9 + +*------------------------------------------------- + +CheckCP + lda #10 + sta LSRETRY + lda #>REDFLAG79 + sta smchi + ldx SLOT + lda $C089,X + lda $C08E,X + lda #:NIBS ; !!!!! LOW BYTE + sta NPTR + lda #>:NIBS ; !!!!! HIGH BYTE + sta NPTRH +:AGAIN lda #$80 + sta PRETRY +:M1 dec PRETRY + beq :LSFAIL + jsr RADR16 + bcs :LSFAIL + lda HDRS + cmp #OBJSCT + bne :M1 + + ldy #0 +:M2 lda $C08C,X + bpl :M2 + dey + beq :LSFAIL + cmp #$D5 + bne :M2 + ldy #0 + +:M3 lda $C08C,X + bpl :M3 + dey + beq :LSFAIL + cmp #$E7 + bne :M3 + +:M4 lda $C08C,X + bpl :M4 + cmp #$E7 + bne :LSFAIL + +:M5 lda $C08C,X + bpl :M5 + cmp #$E7 + bne :LSFAIL + + lda $C08D,X + ldy #$10 + bit $6 ;3 US. ( FOR //C) +:M6 lda $C08C,X + bpl :M6 + dey + beq :LSFAIL + cmp #$EE + bne :M6 + +* NOW AT 1/2 NIBBLES +* +* INSTEAD OF COMPARING AGAINST A TABLE +* THE DATA READ FROM THE DISK CAN BE +* USED IN YOUR PROGRAM. BE CAREFUL +* WHEN MODIFYING THIS PART OF THE CODE. +* KEEP THE CYCLE COUNTS CONSTANT. + + ldy #7 +:M7 lda $C08C,X ; READ DISK DATA + bpl :M7 + cmp (NPTR),Y ; COMPARE AGAINST TABLE + bne :LSFAIL1 + dey + bpl :M7 + bmi :GOOD + +:LSFAIL jmp :LSFAIL1 + +* A O K + +:GOOD eor #$79!$FC + iny + ldx #6 + dex + sta $C000,x + sta (smclo),y + dex + sta $C000,x + eor #$ED + sta $239 + eor #$23 + sta $4E + + jmp yippee + +* FAILED, try again + +:LSFAIL1 ldy #-1 + tya + dec LSRETRY + beq :GOOD + jmp :AGAIN + +:NIBS db $FC,$EE,$EE,$FC + db $E7,$EE,$FC,$E7 + +*------------------------------------------------- +* +* Read address mark +* + +RADR16 ldy #$FD ;READ ADR HDR + sty MEM1 + tya + eor #REDFLAG79!$FD + sta smclo +:RA1 iny + bne :RA2 + inc MEM1 + beq :RAEXIT +:RA2 lda $C08C,X + bpl :RA2 +:RA3 cmp #$D5 + bne :RA1 + nop +:RA4 lda $C08C,X + bpl :RA4 + cmp #$AA + bne :RA3 + ldy #3 +:RA5 lda $C08C,X + bpl :RA5 + cmp #$96 + bne :RA3 + lda #0 +:RA6 sta MEM2 +:RA7 lda $C08C,X + bpl :RA7 + rol + sta MEM1 +:RA8 lda $C08C,X + bpl :RA8 + and MEM1 + sta HDRC,Y + eor MEM2 + dey + bpl :RA6 + tay + nop + clc + rts + +:RAEXIT sec +]rts rts + +oscsh sec + jsr $FE1F + bcs * + + jsr $1000 + + jmp ($FFFC) + +*------------------------------------------------- + +yippee ldx SLOT + lda $C061 + bpl ]rts + lda $C062 + bpl ]rts + lda $C000 + bpl ]rts + bit $C010 + sta :cmp+1 + + ldy #-3 +:loop iny + iny + iny + lda :dispatch,y + beq ]rts +:cmp cmp #$11 + bne :loop + + lda :dispatch+1,y + sta 0 + lda :dispatch+2,y + sta 1 + + bit $C081 + lda $C088,x + + jmp (0) + +:dispatch hex FF + da oscsh + + asc "!" + da rcmess + + hex 8D + da confusion + + asc "@" + da rotcube + + asc "^" + da drive + + db 0 + +*------------------------------------------------- +* +* motorcycle disk drive +* + +drive lda $C089,x ;drive back on! + +:loop lda $C087,x + lda $C080,x + jsr :delay + lda $C085,x + lda $C086,x + jsr :delay + lda $C083,x + lda $C084,x + jsr :delay + lda $C081,x + lda $C082,x + jsr :delay + jmp :loop + +:delay lda #6 + sta 0 + +:del2 bit $C070 + nop + nop + bit $C064 + bmi *-3 + + dec 0 + bne :del2 + rts + +*------------------------------------------------- rotcube + +mainYoffset = 46 ;(192-60)/2 +botYoffset = 72 +mainXoffset = 68 ;(280-144)/2 + +color = $E4 +page = $E6 + + dum 0 +index ds 1 +ysave ds 1 +yadd ds 1 +yoffset ds 1 + dend + +*------------------------------------------------- + +rotcube jsr $f3e2 ;hgr + jsr $f3d8 ;hgr2 + + lda #1 + sta yadd + + sta yoffset + +* Draw on page not showing: + +mainloop lda page + eor #$60 + sta page + ldx #$7F + jsr draw + +* If not a //c, then wait for vbl + + lda $FBC0 + beq :is2c + lda $C019 + bpl *-3 + lda $C019 + bmi *-3 +:is2c + +* Now display that page + + bit $C054 + lda page + cmp #$20 + beq *+5 + bit $C055 + +* Now erase old image from last page + + eor #$60 + sta :smc0+2 + sta :smc1+2 + ldx #$20 + lda #0 +:loop tay +:smc0 sta $2000,y +:smc1 sta $2080,y + iny + bpl :smc0 + inc :smc0+2 + inc :smc1+2 + dex + bne :loop + + inc index + jmp mainloop + +*------------------------------------------------- + +draw stx color + + ldy #12-1 +:drawloop lda drawlist,y + sty ysave + + pha + and #15 + jsr getpoint + + tax + tya + ldy #0 + jsr $f457 ;plot + + pla + lsr + lsr + lsr + lsr + jsr getpoint + ldx #0 + jsr $f53a ;lineto + + ldy ysave + dey + bpl :drawloop + + lda yoffset + clc + adc yadd + bne :not0 + + inc yadd ;make +1 + inc yadd + +:not0 cmp #191-48-botYoffset + bcc :0 + + dec yadd ;make -1 + dec yadd + +:0 sta yoffset + rts + +*------------------------------------------------- +* +* given a = point number, return a = xcoor, y = ycoor +* + +getpoint tay + +* Get index into tables + + asl ;*16 + asl + asl + asl + adc index + and #$3F + tax + tya + + and #4 ;bottom? + cmp #4 + +* Compute ycoor + + lda ydata,x + bcc :not_bot + adc #botYoffset-1 + +:not_bot adc yoffset + tay + +* Compute xcoor + + lda xdata,x + adc #mainXoffset + rts + +*------------------------------------------------- + +drawlist hex 01122330 ;draw top + hex 45566774 ;draw bottom + hex 04152637 ;draw connecting lines + +xdata hex 908F8E8C8A87837F7A757069635C564F + hex 484039332C261F1A15100C0805030100 + hex 0000010305080C10151A1F262C333940 + hex 474F565C636970757A7F83878A8C8E8F + +ydata hex 181A1C1E21232527282A2B2D2E2E2F2F + hex 2F2F2F2E2E2D2B2A28272523211E1C1A + hex 181513110E0C0A080705040201010000 + hex 000000010102040507080A0C0E111315 + +*------------------------------------------------- confusion + + dum 0 +xr ds 1 +yr ds 1 +randseed ds 1 +temp ds 1 + dend + +hgr2 = $F3D8 +plot = $F457 +hcolor = $F6F0 + +* Confusion triangle + +confusion lda #$7F + sta $E4 ;hcolor=3 + + jsr hgr2 + +* xr=xarray(0), yr=yarray(0) + + ldx xarray + ldy yarray + stx xr + sty yr + +* Plot that dot + +:loop lda $C000 + bpl :nokey + bit $C010 + cmp #$E0 + bcc *+4 + and #$DF + cmp #"C" + bne :nokey + +:randcol jsr getrandcol + sta temp + jsr $F3F4 ;clear to that color + +:randloop jsr getrandcol + tax + eor temp + bmi :randloop ;different hi bits + cpx temp ;same color + beq :randloop + +:nokey ldy #0 + lda xr + asl + tax + bcc :skip + iny +:skip lda yr + jsr plot + + lda yr + ldx $E0 + ldy $E1 + inx + bne *+3 + iny + jsr plot + +* Get a random number between 0-2 + + jsr random + sec +:sub30 sbc #30 + bcs :sub30 + adc #30 + sec +:sub3 sbc #3 + bcs :sub3 + adc #3 + tax + +*----------- +* xr stuff: +* determine which midpoint routine to use + + lda xarray,x + cmp xr + bge :xarr_xr + +* If xarray(rand) < xr then: +* xr = xarray + ( xr - xarray) / 2 + + lda xr + sec + sbc xarray,x + lsr + clc + adc xarray,x + jmp :sta_xr + +* If xarray(rand) >= xr then: +* xr = xr + ( xarray - xr ) / 2 + +:xarr_xr lda xarray,x + sec + sbc xr + lsr + clc + adc xr +:sta_xr sta xr + +*----------- +* yr stuff: +* determine which midpoint routine to use + + lda yarray,x + cmp yr + bge :yarr_yr + +* If yarray(rand) < yr then: +* yr = yarray + ( yr - yarray) / 2 + + lda yr + sec + sbc yarray,x + lsr + clc + adc yarray,x + jmp :sta_yr + +* If yarray(rand) >= yr then: +* yr = yr + ( yarray - yr ) / 2 + +:yarr_yr lda yarray,x + sec + sbc yr + lsr + clc + adc yr +:sta_yr sta yr + + jmp :loop + +xarray db 70,139,0 +yarray db 0,191,191 + +random lda randseed + adc #$23 + sta randseed + eor $C020 ;a little randomness + rts + +getrandcol jsr random + and #7 + tax + jmp hcolor + +*------------------------------------------------- rcmess + +rcmess ldy #0 +:0 lda :text,y + beq :lores + jsr $FDF0 + iny + bne :0 + +:lores bit $c000 + bpl :lores + + sta $c00d ;80 col + sta $c001 ;80 store + bit $c056 + bit $c052 + bit $c050 + bit $c05e ;merez + +:loop lda #$FF + jsr :random + sta $30 ;color + + lda #80 ;max x + jsr :random + lsr + tay + bit $c054 + bcs *+5 + bit $c055 + + lda #48 ;max y + jsr :random + + jsr $F800 ;plot + + jmp :loop + +:random sta 1 + + lda 0 + adc #$23 + sta 0 + eor $C020 + + cmp 1 + bcc :ok +:loop2 sbc 1 + bcs :loop2 + adc 1 + +:ok rts + +:text hex 8d8d + asc "8/25/89",8d8d8d + asc "Robert!",8d8d8d + asc "Jordan and Roland wish you the very",8d8d + asc "Brightest College Years.",8d8d8d8d8d + asc " meres !",8d,8d + asc " meres !",8d,8d + asc " meres !" + brk + +*------------------------------------------------- EOF + + lst on + da * + lst off diff --git a/03 Disk Protection/PURPLE.MAIN.S b/03 Disk Protection/PURPLE.MAIN.S index 3128ef6..bb99f5c 100755 --- a/03 Disk Protection/PURPLE.MAIN.S +++ b/03 Disk Protection/PURPLE.MAIN.S @@ -1 +1,211 @@ -* purple.main lst off * The job of this routine is to set $DA to $01 * ( in aux-zpage!!! ) slot = $FD *------------------------------------------------- * * HLS APPLE COPY PROTECTION * COPYRIGHT (C) 1987 HLS DUPLICATION * * HLS 408-773-1500 * * Modified by Roland Gustafsson 8/25/89 * for Prince of Persia copy protection. * *------------------------------------------------- * ZERO PAGE OBJSCT = $07 ;PHYSICAL SECTOR # HDRC = $40 HDRS = HDRC+1 HDRT = HDRC+2 HDRV = HDRC+3 HEADER SECTOR LSRETRY = HDRC+4 ;NIB READ RETRIES PRETRY = HDRC+5 ;OBJSCT RETRIES NPTR = HDRC+6 NPTRH = HDRC+7 MEM1 = HDRC+8 MEM2 = HDRC+9 zpage = HDRC zpagelen = 13 *------------------------------------------------- * * Here is the code that ends up at $6321. * Assemble it and run "make.purple.hex" which * reverses the code and puts it in a text file. * *------------------------------------------------- org $2000 da len6321 dum $6254 zpagebuf ds zpagelen dend org $6321 strt6321 jsr swapzpage lda #10 sta LSRETRY ldx slot lda $C089,X lda $C08E,X lda #:NIBS ; !!!!! LOW BYTE sta NPTR lda #>:NIBS ; !!!!! HIGH BYTE sta NPTRH :AGAIN lda #$80 sta PRETRY :M1 dec PRETRY beq :LSFAIL jsr RADR16 bcs :LSFAIL lda HDRS cmp #OBJSCT bne :M1 ldy #0 :M2 lda $C08C,X bpl :M2 dey beq :LSFAIL cmp #$D5 bne :M2 ldy #0 :M3 lda $C08C,X bpl :M3 dey beq :LSFAIL cmp #$E7 bne :M3 :M4 lda $C08C,X bpl :M4 cmp #$E7 bne :LSFAIL :M5 lda $C08C,X bpl :M5 cmp #$E7 bne :LSFAIL lda $C08D,X ldy #$10 bit $6 ;3 US. ( FOR //C) :M6 lda $C08C,X bpl :M6 dey beq :LSFAIL cmp #$EE bne :M6 * NOW AT 1/2 NIBBLES ldy #7 :M7 lda $C08C,X * READ DISK DATA bpl :M7 cmp (NPTR),Y * COMPARE AGAINST TABLE bne :LSFAIL dey bpl :M7 bmi :GOOD :LSFAIL jmp :LSFAIL1 * A O K :GOOD jsr swapzpage lda #0 sta $C009-zpagelen,x rol sta $DA-zpagelen,x sta $C008-zpagelen,x clc rts * FAILED :LSFAIL1 dec LSRETRY beq :ERROR jmp :AGAIN :NIBS db $FC,$EE,$EE,$FC db $E7,$EE,$FC,$E7 * Note that drive motor is still on :ERROR swapzpage ldx #0 :0 ldy zpagebuf,x lda zpage,x sty zpage,x sta zpagebuf,x inx cpx #zpagelen bne :0 rts *------------------------------------------------- * * Read address mark * RADR16 ldy #$FD ;READ ADR HDR sty MEM1 :RA1 iny bne :RA2 inc MEM1 beq :RAEXIT :RA2 lda $C08C,X bpl :RA2 :RA3 cmp #$D5 bne :RA1 nop :RA4 lda $C08C,X bpl :RA4 cmp #$AA bne :RA3 ldy #3 :RA5 lda $C08C,X bpl :RA5 cmp #$96 bne :RA3 lda #0 :RA6 sta MEM2 :RA7 lda $C08C,X bpl :RA7 rol sta MEM1 :RA8 lda $C08C,X bpl :RA8 and MEM1 sta HDRC,Y eor MEM2 dey bpl :RA6 tay nop clc rts :RAEXIT sec rts len6321 = *-strt6321 org *------------------------------------------------- EOF sav purple.main \ No newline at end of file +* purple.main + + lst off + +* The job of this routine is to set $DA to $01 +* ( in aux-zpage!!! ) + +slot = $FD + +*------------------------------------------------- +* +* HLS APPLE COPY PROTECTION +* COPYRIGHT (C) 1987 HLS DUPLICATION +* +* HLS 408-773-1500 +* +* Modified by Roland Gustafsson 8/25/89 +* for Prince of Persia copy protection. +* +*------------------------------------------------- + +* ZERO PAGE + +OBJSCT = $07 ;PHYSICAL SECTOR # + +HDRC = $40 +HDRS = HDRC+1 +HDRT = HDRC+2 +HDRV = HDRC+3 HEADER SECTOR +LSRETRY = HDRC+4 ;NIB READ RETRIES +PRETRY = HDRC+5 ;OBJSCT RETRIES +NPTR = HDRC+6 +NPTRH = HDRC+7 +MEM1 = HDRC+8 +MEM2 = HDRC+9 + +zpage = HDRC +zpagelen = 13 + +*------------------------------------------------- +* +* Here is the code that ends up at $6321. +* Assemble it and run "make.purple.hex" which +* reverses the code and puts it in a text file. +* +*------------------------------------------------- + + org $2000 + + da len6321 + + dum $6254 +zpagebuf ds zpagelen + dend + + org $6321 + +strt6321 jsr swapzpage + lda #10 + sta LSRETRY + ldx slot + lda $C089,X + lda $C08E,X + lda #:NIBS ; !!!!! LOW BYTE + sta NPTR + lda #>:NIBS ; !!!!! HIGH BYTE + sta NPTRH +:AGAIN lda #$80 + sta PRETRY +:M1 dec PRETRY + beq :LSFAIL + jsr RADR16 + bcs :LSFAIL + lda HDRS + cmp #OBJSCT + bne :M1 + + ldy #0 +:M2 lda $C08C,X + bpl :M2 + dey + beq :LSFAIL + cmp #$D5 + bne :M2 + ldy #0 + +:M3 lda $C08C,X + bpl :M3 + dey + beq :LSFAIL + cmp #$E7 + bne :M3 + +:M4 lda $C08C,X + bpl :M4 + cmp #$E7 + bne :LSFAIL + +:M5 lda $C08C,X + bpl :M5 + cmp #$E7 + bne :LSFAIL + + lda $C08D,X + ldy #$10 + bit $6 ;3 US. ( FOR //C) +:M6 lda $C08C,X + bpl :M6 + dey + beq :LSFAIL + cmp #$EE + bne :M6 + +* NOW AT 1/2 NIBBLES + + ldy #7 +:M7 lda $C08C,X * READ DISK DATA + bpl :M7 + cmp (NPTR),Y * COMPARE AGAINST TABLE + bne :LSFAIL + dey + bpl :M7 + bmi :GOOD +:LSFAIL jmp :LSFAIL1 + +* A O K + +:GOOD jsr swapzpage + lda #0 + sta $C009-zpagelen,x + rol + sta $DA-zpagelen,x + sta $C008-zpagelen,x + clc + rts + +* FAILED + +:LSFAIL1 dec LSRETRY + beq :ERROR + jmp :AGAIN + +:NIBS db $FC,$EE,$EE,$FC + db $E7,$EE,$FC,$E7 + +* Note that drive motor is still on + +:ERROR +swapzpage ldx #0 +:0 ldy zpagebuf,x + lda zpage,x + sty zpage,x + sta zpagebuf,x + inx + cpx #zpagelen + bne :0 + rts + +*------------------------------------------------- +* +* Read address mark +* + +RADR16 ldy #$FD ;READ ADR HDR + sty MEM1 +:RA1 iny + bne :RA2 + inc MEM1 + beq :RAEXIT +:RA2 lda $C08C,X + bpl :RA2 +:RA3 cmp #$D5 + bne :RA1 + nop +:RA4 lda $C08C,X + bpl :RA4 + cmp #$AA + bne :RA3 + ldy #3 +:RA5 lda $C08C,X + bpl :RA5 + cmp #$96 + bne :RA3 + lda #0 +:RA6 sta MEM2 +:RA7 lda $C08C,X + bpl :RA7 + rol + sta MEM1 +:RA8 lda $C08C,X + bpl :RA8 + and MEM1 + sta HDRC,Y + eor MEM2 + dey + bpl :RA6 + tay + nop + clc + rts + +:RAEXIT sec + rts + +len6321 = *-strt6321 + + org + +*------------------------------------------------- EOF + + sav purple.main diff --git a/03 Disk Protection/RYELLOW1.S b/03 Disk Protection/RYELLOW1.S index 722c84e..2273a83 100755 --- a/03 Disk Protection/RYELLOW1.S +++ b/03 Disk Protection/RYELLOW1.S @@ -1 +1,90 @@ -* Ryellow1 (put this file!!!) * This code sets the high bit of $7C in aux mem * if signature is found on track zero. * NOTE: make sure the x register has a number * greater than 4 when calling YELLOW. YELLrun = $AAAA YELLOW :0 sec rol clc rol dex bne :0 sta 4 jsr YELLsub jmp YELLnothing *------------------------------------------------- YELLcode hex 27A26A0C5717236A8AAD0603AA8A3401 hex 03A02F9E0C5717246A03012F9D03E92F hex 9C032A2F9F6C9F5AF68AF8011AFD0F9B hex 63AD7A5B0AAA17266ABA51225AED637F hex 7A5E0AAA17266ABA51225A93634D7A5E hex 17266ABA51634D7A8617266ABA51634D hex 7A8917276A0ABA8EAC17266ABA51225A hex BE63447A5E0AAD17266ABA517B9C7AAF hex 22BA5E9AA9E696018AAD06374215DCF1 hex B2CA6C9E5AA1E66100564444564D4456 hex 4D8AAD06374215CA0A572E92627AAE4C hex 925A9717266ABA51637F7A5A4017266A hex BA5163007A580AA917266ABA51633C7A hex 4D03AA2F9317266ABA51802F9217266A hex BA518F92339AAAEF9322BA4D0240B2CA hex 92CA03AE27620E6F555AFC03AA27670E hex 0F55276F0E9247620E5A9F1AACE3554C hex 553AAEC3546C5567670E3AA907670E63 hex A61AAB02928A440113B3068A5601076F hex 0EB28A5A01138F068A560144670E7A6A hex 8A5601B20F5583A980AF5700172A6A0C hex 57CA08B8607A579243AB7A5CCA08AA16 hex 0E0E1F9A3E9A370E0E424A8B7A5BCAAB hex 9A828E8AB4B7B6B6B6B6B6DA868C88B5 hex B4B7B6B6B6B6B655A9 *------------------------------------------------- YELLlen = *-YELLcode * Routine to decode code hex 20 ;jsr YELLsub sta 5 ldy #0 :0 lda YELLcode,y eor 4 sta (4),y inc 5 lda YELLcode+256,y eor 4 sta (4),y dec 5 iny bne :0 lda 4 eor #$4C!$AA ;jmp instruction sta 3 jmp 3 *------------------------------------------------- hex a9 ;lda #imm YELLnothing ldy #0 inc 5 :0 tya :1 sta (4),y iny bne :1 rts *------------------------------------------------- EOF \ No newline at end of file +* Ryellow1 (put this file!!!) + +* This code sets the high bit of $7C in aux mem +* if signature is found on track zero. + +* NOTE: make sure the x register has a number +* greater than 4 when calling YELLOW. + +YELLrun = $AAAA + +YELLOW +:0 sec + rol + clc + rol + dex + bne :0 + sta 4 + + jsr YELLsub + jmp YELLnothing + +*------------------------------------------------- + +YELLcode + hex 27A26A0C5717236A8AAD0603AA8A3401 + hex 03A02F9E0C5717246A03012F9D03E92F + hex 9C032A2F9F6C9F5AF68AF8011AFD0F9B + hex 63AD7A5B0AAA17266ABA51225AED637F + hex 7A5E0AAA17266ABA51225A93634D7A5E + hex 17266ABA51634D7A8617266ABA51634D + hex 7A8917276A0ABA8EAC17266ABA51225A + hex BE63447A5E0AAD17266ABA517B9C7AAF + hex 22BA5E9AA9E696018AAD06374215DCF1 + hex B2CA6C9E5AA1E66100564444564D4456 + hex 4D8AAD06374215CA0A572E92627AAE4C + hex 925A9717266ABA51637F7A5A4017266A + hex BA5163007A580AA917266ABA51633C7A + hex 4D03AA2F9317266ABA51802F9217266A + hex BA518F92339AAAEF9322BA4D0240B2CA + hex 92CA03AE27620E6F555AFC03AA27670E + hex 0F55276F0E9247620E5A9F1AACE3554C + hex 553AAEC3546C5567670E3AA907670E63 + hex A61AAB02928A440113B3068A5601076F + hex 0EB28A5A01138F068A560144670E7A6A + hex 8A5601B20F5583A980AF5700172A6A0C + hex 57CA08B8607A579243AB7A5CCA08AA16 + hex 0E0E1F9A3E9A370E0E424A8B7A5BCAAB + hex 9A828E8AB4B7B6B6B6B6B6DA868C88B5 + hex B4B7B6B6B6B6B655A9 + +*------------------------------------------------- + +YELLlen = *-YELLcode + +* Routine to decode code + + hex 20 ;jsr + +YELLsub sta 5 + ldy #0 +:0 lda YELLcode,y + eor 4 + sta (4),y + inc 5 + lda YELLcode+256,y + eor 4 + sta (4),y + dec 5 + iny + bne :0 + lda 4 + eor #$4C!$AA ;jmp instruction + sta 3 + jmp 3 + +*------------------------------------------------- + + hex a9 ;lda #imm + +YELLnothing ldy #0 + inc 5 +:0 tya +:1 sta (4),y + iny + bne :1 + rts + + +*------------------------------------------------- EOF diff --git a/03 Disk Protection/UPDATE.LS.S b/03 Disk Protection/UPDATE.LS.S index 7f754d1..007120a 100755 --- a/03 Disk Protection/UPDATE.LS.S +++ b/03 Disk Protection/UPDATE.LS.S @@ -1 +1,139 @@ - lst off org $300 * * loresshow:0C00.0FFF ($400) * framedata:1000.6BFF ($5C00) * * buffer18 :6C00.7DFF ($1200 one track) * rw18.d000:7E00.82FF ($500 moved to aux ramcard) * BbundID = $AD loresshow = $c00 buffer18 = $6c00 rw18 = $d000 rw18temp = $7e00 slot = $FD track = $FE lastrack = $FF startrack = 12 ;last 6 sectors here * 13,14,15,16,17 (5 full tracks here) errcode = 0 start jsr $e74c ;get slot# txa asl asl asl asl sta $C009 ;aux zpage, ramcard sta slot bit $C083 bit $C083 * Move rw18 to its home ldx #>rw18temp ldy #>rw18 lda #5 jsr movedata * Now we can use rw18 jsr rw18 db 7,BbundID jsr rw18 db 0,5,1 ;drive on jsr rw18 ;seek to startrack db 2,1,startrack * handle special track with jsr rw18 db 3 ;read in original data db >buffer18 lda #1 bcs :error * update last 6 sectors ldx #>loresshow ldy #>buffer18+$C00 lda #6 jsr movedata * write it back out jsr rw18 db 5 ;writesequ db >buffer18 lda #2 bcs :error * write out rest of data... lda #>loresshow+$600 :wloop sta :buf inc track jsr rw18 db 5 ;writesequ :buf db $11 lda #2 bcs :error lda :buf adc #$12 cmp #>loresshow+$600+{5*$1200} bne :wloop lda #0 :error pha jsr rw18 db 1 ;drive off pla sta $C008 bit $C081 sta errcode rts *------------------------------------------------- movedata * * Move data: x:source, y:dest, a:length * movedata stx :src+2 sty :dst+2 tax ldy #0 :loop :src lda $1100,y :dst sta $1100,y iny bne :loop inc :src+2 inc :dst+2 dex bne :loop rts *------------------------------------------------- EOF \ No newline at end of file + lst off + + org $300 + +* +* loresshow:0C00.0FFF ($400) +* framedata:1000.6BFF ($5C00) +* +* buffer18 :6C00.7DFF ($1200 one track) +* rw18.d000:7E00.82FF ($500 moved to aux ramcard) +* + +BbundID = $AD + +loresshow = $c00 +buffer18 = $6c00 + +rw18 = $d000 +rw18temp = $7e00 + +slot = $FD +track = $FE +lastrack = $FF + +startrack = 12 ;last 6 sectors here + +* 13,14,15,16,17 (5 full tracks here) + +errcode = 0 + +start jsr $e74c ;get slot# + txa + asl + asl + asl + asl + + sta $C009 ;aux zpage, ramcard + sta slot + + bit $C083 + bit $C083 + +* Move rw18 to its home + + ldx #>rw18temp + ldy #>rw18 + lda #5 + jsr movedata + +* Now we can use rw18 + + jsr rw18 + db 7,BbundID + + jsr rw18 + db 0,5,1 ;drive on + + jsr rw18 ;seek to startrack + db 2,1,startrack + +* handle special track with + + jsr rw18 + db 3 ;read in original data + db >buffer18 + lda #1 + bcs :error + +* update last 6 sectors + + ldx #>loresshow + ldy #>buffer18+$C00 + lda #6 + jsr movedata + +* write it back out + + jsr rw18 + db 5 ;writesequ + db >buffer18 + lda #2 + bcs :error + +* write out rest of data... + + lda #>loresshow+$600 +:wloop sta :buf + + inc track + + jsr rw18 + db 5 ;writesequ +:buf db $11 + lda #2 + bcs :error + + lda :buf + adc #$12 + cmp #>loresshow+$600+{5*$1200} + bne :wloop + + lda #0 + +:error pha + jsr rw18 + db 1 ;drive off + pla + + sta $C008 + bit $C081 + sta errcode + rts + +*------------------------------------------------- movedata +* +* Move data: x:source, y:dest, a:length +* + +movedata stx :src+2 + sty :dst+2 + tax + + ldy #0 +:loop +:src lda $1100,y +:dst sta $1100,y + iny + bne :loop + + inc :src+2 + inc :dst+2 + + dex + bne :loop + + rts + +*------------------------------------------------- EOF diff --git a/03 Disk Protection/YELLOW.MAIN.S b/03 Disk Protection/YELLOW.MAIN.S index 53d4002..0d7ea1a 100755 --- a/03 Disk Protection/YELLOW.MAIN.S +++ b/03 Disk Protection/YELLOW.MAIN.S @@ -1 +1,291 @@ -* yellow.main lst off * The job of this routine is to * set the high-bit of $7C in aux zpage. * (It does it by rotating in a carry set) slot = $fd lastrack = $ff *------------------------------------------------- * * HLS APPLE COPY PROTECTION * COPYRIGHT (C) 1987 HLS DUPLICATION * * Modified by Roland Gustafsson 8/25/89 * for Prince of Persia copy protection. * *------------------------------------------------- OBJSCT = $07 ;PHYSICAL SECTOR # * ZERO PAGE HDRC = $30 HDRS = HDRC+1 HDRT = HDRC+2 HDRV = HDRC+3 HEADER SECTOR LSRETRY = HDRC+4 ;NIB READ RETRIES PRETRY = HDRC+5 ;OBJSCT RETRIES NPTR = HDRC+6 NPTRH = HDRC+7 MEM1 = HDRC+8 MEM2 = HDRC+9 zpage = HDRC zpagelen = 33 ;arbitrarily long (only needs 10) *------------------------------------------------- * Jordan says: use $A400-ABFF * Roland says: OK orgCHECK = $AAAA ;must be highbyte=lowbyte org $2000 da lenCHECK dum $A4A4 zpagebuf ds zpagelen was27 ds 3 ;should be 1 !!! was2A ds 5 ; ditto was26 ds 7 ; ditto again dend org orgCHECK *------------------------------------------------- start sta $C008 ;switch to main zpage ldx slot lda $C089,x ;drive on jsr swapzpage * First seek track zero lda #0 jsr SEEK * Now check signature lda #10 sta LSRETRY ldx slot lda $C08E,X lda #>:NIBS sta NPTRH lda #:NIBS sta NPTR :AGAIN lda #$80 sta PRETRY :M1 dec PRETRY beq :LSFAIL jsr RADR16 bcs :LSFAIL lda HDRS cmp #OBJSCT bne :M1 ldy #0 :M2 lda $C08C,X bpl :M2 dey beq :LSFAIL cmp #$D5 bne :M2 ldy #0 :M3 lda $C08C,X bpl :M3 dey beq :LSFAIL cmp #$E7 bne :M3 :M4 lda $C08C,X bpl :M4 cmp #$E7 bne :LSFAIL :M5 lda $C08C,X bpl :M5 cmp #$E7 bne :LSFAIL lda $C08D,X ldy #$10 bit $6 ;3 US. ( FOR //C) :M6 lda $C08C,X bpl :M6 dey beq :LSFAIL cmp #$EE bne :M6 * NOW AT 1/2 NIBBLES ldy #7 :M7 lda $C08C,X * READ DISK DATA bpl :M7 cmp (NPTR),Y * COMPARE AGAINST TABLE bne :LSFAIL dey bpl :M7 bmi :GOOD :LSFAIL jmp :LSFAIL1 * A O K :GOOD jsr swapzpage sta $C009-zpagelen,x ror $7C-zpagelen,x clc rts * FAILED :LSFAIL1 dec LSRETRY beq :ERROR jmp :AGAIN :NIBS db $FC,$EE,$EE,$FC db $E7,$EE,$FC,$E7 :ERROR jsr swapzpage sta $C009-zpagelen,x rts *------------------------------------------------- * * Read address mark * RADR16 ldy #$FD sty MEM1 :RA1 iny bne :RA2 inc MEM1 beq :RAEXIT :RA2 lda $C08C,X bpl :RA2 :RA3 cmp #$D5 bne :RA1 nop :RA4 lda $C08C,X bpl :RA4 cmp #$AA bne :RA3 ldy #3 :RA5 lda $C08C,X bpl :RA5 cmp #$96 bne :RA3 lda #0 :RA6 sta MEM2 :RA7 lda $C08C,X bpl :RA7 rol sta MEM1 :RA8 lda $C08C,X bpl :RA8 and MEM1 sta HDRC,Y eor MEM2 dey bpl :RA6 tay nop clc rts :RAEXIT sec rts *------------------------------------------------- * * SEEK, a - track * SEEK4 lda #4 SEEK sta was2A cmp lastrack beq :RTS0 lda #0 sta was26 :MOVEHEAD lda lastrack sta was27 sec sbc was2A beq :ISTHERE bcs :T0 eor #$FF inc lastrack bcc :T1 :T0 adc #$FE dec lastrack :T1 cmp was26 bcc :T2 lda was26 :T2 cmp #$C bcs :T3 tay :T3 sec jsr :CHKPOS lda ONTBL,Y jsr :MSWAIT lda was27 clc jsr :CHKPOS2 lda OFFTBL,Y jsr :MSWAIT inc was26 bne :MOVEHEAD :ISTHERE jsr :MSWAIT clc :CHKPOS lda lastrack :CHKPOS2 and #3 rol ora slot tax lda $C080,X ldx slot :RTS0 rts :MSWAIT ldx #$12 :T21 dex bne :T21 sec sbc #1 bne :MSWAIT rts *------------------------------------------------- swapzpage ldx #0 :0 ldy zpagebuf,x lda zpage,x sty zpage,x sta zpagebuf,x inx cpx #zpagelen bne :0 rts *------------------------------------------------- ONTBL db $01,$30,$28,$24,$20,$1E,$1D,$1C,$1C,$1C,$1C,$1C OFFTBL db $70,$2C,$26,$22,$1F,$1E,$1D,$1C,$1C,$1C,$1C,$1C,$FF,$03 *------------------------------------------------- lenCHECK = *-orgCHECK org *------------------------------------------------- EOF sav yellow.main \ No newline at end of file +* yellow.main + lst off + +* The job of this routine is to +* set the high-bit of $7C in aux zpage. +* (It does it by rotating in a carry set) + +slot = $fd +lastrack = $ff + +*------------------------------------------------- +* +* HLS APPLE COPY PROTECTION +* COPYRIGHT (C) 1987 HLS DUPLICATION +* +* Modified by Roland Gustafsson 8/25/89 +* for Prince of Persia copy protection. +* +*------------------------------------------------- + +OBJSCT = $07 ;PHYSICAL SECTOR # + +* ZERO PAGE + +HDRC = $30 +HDRS = HDRC+1 +HDRT = HDRC+2 +HDRV = HDRC+3 HEADER SECTOR +LSRETRY = HDRC+4 ;NIB READ RETRIES +PRETRY = HDRC+5 ;OBJSCT RETRIES +NPTR = HDRC+6 +NPTRH = HDRC+7 +MEM1 = HDRC+8 +MEM2 = HDRC+9 + +zpage = HDRC +zpagelen = 33 ;arbitrarily long (only needs 10) + +*------------------------------------------------- + +* Jordan says: use $A400-ABFF +* Roland says: OK + +orgCHECK = $AAAA ;must be highbyte=lowbyte + + org $2000 + + da lenCHECK + + dum $A4A4 +zpagebuf ds zpagelen +was27 ds 3 ;should be 1 !!! +was2A ds 5 ; ditto +was26 ds 7 ; ditto again + dend + + org orgCHECK + +*------------------------------------------------- + +start sta $C008 ;switch to main zpage + + ldx slot + lda $C089,x ;drive on + + jsr swapzpage + +* First seek track zero + + lda #0 + jsr SEEK + +* Now check signature + + lda #10 + sta LSRETRY + ldx slot + lda $C08E,X + lda #>:NIBS + sta NPTRH + lda #:NIBS + sta NPTR + +:AGAIN lda #$80 + sta PRETRY +:M1 dec PRETRY + beq :LSFAIL + jsr RADR16 + bcs :LSFAIL + lda HDRS + cmp #OBJSCT + bne :M1 + + ldy #0 +:M2 lda $C08C,X + bpl :M2 + dey + beq :LSFAIL + cmp #$D5 + bne :M2 + ldy #0 + +:M3 lda $C08C,X + bpl :M3 + dey + beq :LSFAIL + cmp #$E7 + bne :M3 + +:M4 lda $C08C,X + bpl :M4 + cmp #$E7 + bne :LSFAIL + +:M5 lda $C08C,X + bpl :M5 + cmp #$E7 + bne :LSFAIL + + lda $C08D,X + ldy #$10 + bit $6 ;3 US. ( FOR //C) +:M6 lda $C08C,X + bpl :M6 + dey + beq :LSFAIL + cmp #$EE + bne :M6 + +* NOW AT 1/2 NIBBLES + + ldy #7 +:M7 lda $C08C,X * READ DISK DATA + bpl :M7 + cmp (NPTR),Y * COMPARE AGAINST TABLE + bne :LSFAIL + dey + bpl :M7 + bmi :GOOD +:LSFAIL jmp :LSFAIL1 + +* A O K + +:GOOD jsr swapzpage + sta $C009-zpagelen,x + ror $7C-zpagelen,x + clc + rts + +* FAILED + +:LSFAIL1 dec LSRETRY + beq :ERROR + jmp :AGAIN + +:NIBS db $FC,$EE,$EE,$FC + db $E7,$EE,$FC,$E7 + +:ERROR jsr swapzpage + sta $C009-zpagelen,x + rts + +*------------------------------------------------- +* +* Read address mark +* + +RADR16 ldy #$FD + sty MEM1 +:RA1 iny + bne :RA2 + inc MEM1 + beq :RAEXIT +:RA2 lda $C08C,X + bpl :RA2 +:RA3 cmp #$D5 + bne :RA1 + nop +:RA4 lda $C08C,X + bpl :RA4 + cmp #$AA + bne :RA3 + ldy #3 +:RA5 lda $C08C,X + bpl :RA5 + cmp #$96 + bne :RA3 + lda #0 +:RA6 sta MEM2 +:RA7 lda $C08C,X + bpl :RA7 + rol + sta MEM1 +:RA8 lda $C08C,X + bpl :RA8 + and MEM1 + sta HDRC,Y + eor MEM2 + dey + bpl :RA6 + tay + nop + clc + rts + +:RAEXIT sec + rts + +*------------------------------------------------- +* +* SEEK, a - track +* + +SEEK4 lda #4 +SEEK sta was2A + cmp lastrack + beq :RTS0 + lda #0 + sta was26 +:MOVEHEAD lda lastrack + sta was27 + sec + sbc was2A + beq :ISTHERE + bcs :T0 + eor #$FF + inc lastrack + bcc :T1 +:T0 adc #$FE + dec lastrack +:T1 cmp was26 + bcc :T2 + lda was26 +:T2 cmp #$C + bcs :T3 + tay +:T3 sec + jsr :CHKPOS + lda ONTBL,Y + jsr :MSWAIT + lda was27 + clc + jsr :CHKPOS2 + lda OFFTBL,Y + jsr :MSWAIT + inc was26 + bne :MOVEHEAD +:ISTHERE jsr :MSWAIT + clc +:CHKPOS lda lastrack +:CHKPOS2 and #3 + rol + ora slot + tax + lda $C080,X + ldx slot +:RTS0 rts + +:MSWAIT ldx #$12 +:T21 dex + bne :T21 + sec + sbc #1 + bne :MSWAIT + rts + +*------------------------------------------------- + +swapzpage ldx #0 +:0 ldy zpagebuf,x + lda zpage,x + sty zpage,x + sta zpagebuf,x + inx + cpx #zpagelen + bne :0 + rts + +*------------------------------------------------- + +ONTBL db $01,$30,$28,$24,$20,$1E,$1D,$1C,$1C,$1C,$1C,$1C +OFFTBL db $70,$2C,$26,$22,$1F,$1E,$1D,$1C,$1C,$1C,$1C,$1C,$FF,$03 + +*------------------------------------------------- +lenCHECK = *-orgCHECK + + org + +*------------------------------------------------- EOF + + sav yellow.main