Prince-of-Persia-Apple-II

A running-jumping-swordfighting game Jordan Mechner made on the Apple II from 1985-89
Log | Files | Refs | README | LICENSE

SPECIALK.S (17559B)


      1 * specialk
      2 EditorDisk = 0
      3 FinalDisk = 0 ;removes all cheat keys
      4 DebugKeys = 0
      5  tr on
      6  lst off
      7 org = $d900
      8 *-------------------------------
      9 *
     10 *  PRINCE OF PERSIA
     11 *  Copyright 1989 Jordan Mechner
     12 *
     13 *-------------------------------
     14  org org
     15 
     16  jmp KEYS
     17  jmp CLRJSTK
     18  jmp ZEROSOUND
     19  jmp ADDSOUND
     20  jmp FACEJSTK
     21 
     22  jmp SAVESELECT
     23  jmp LOADSELECT
     24  jmp SAVEDESEL
     25  jmp LOADDESEL
     26  jmp INITINPUT
     27 
     28  jmp DEMOKEYS
     29  jmp LISTTORCHES
     30  jmp BURN
     31  jmp GETMINLEFT
     32  jmp KEEPTIME
     33 
     34  jmp SHORTENTIME
     35  jmp CUESONG
     36  jmp DoSaveGame
     37  jmp LoadLevelX
     38  jmp decstr
     39 
     40  jmp DLOOP
     41  jmp STROBE
     42 
     43 *-------------------------------
     44  lst
     45  put eq
     46  lst
     47  put gameeq
     48  lst
     49  put soundnames
     50  lst
     51  put movedata
     52  lst off
     53 
     54 *-------------------------------
     55 initAMtimer = 10 ;antimatter cheat key timer
     56 
     57  dum locals
     58 ]temp ds 1
     59 ]count ds 2
     60  dend
     61 
     62 POPside1 = $a9
     63 POPside2 = $ad
     64 
     65 FirstSideB = 3
     66 
     67 *-------------------------------
     68 min = 725 ;# frames per "minute"
     69   ;(actual frame rate approx. 11 fps)
     70 sec = min/60
     71 t = 60 ;game time limit
     72 
     73 *-------------------------------
     74 *  Key equates
     75 
     76 CTRL = $60
     77 ESC = $9b
     78 DELETE = $7f
     79 SHIFT = $20
     80 
     81 *  Player control keys
     82 
     83 kleft = "j"
     84 kdown = "k"
     85 kright = "l"
     86 kupleft = "u"
     87 kup = "i"
     88 kupright = "o"
     89 
     90 *  Special keys (legit)
     91 
     92 kfreeze = ESC
     93 krestart = "r"-CTRL
     94 kabort = "a"-CTRL
     95 ksound = "s"-CTRL
     96 kmusic = "n"-CTRL
     97 ksetkbd = "k"-CTRL
     98 ksetjstk = "j"-CTRL
     99 ksavegame = "g"-CTRL
    100 kversion = "v"-CTRL
    101 kreturn = "m"-CTRL ;editor disk only
    102 kshowtime = " "
    103 kflipx = "x"-CTRL
    104 kflipy = "y"-CTRL
    105 
    106 *  Special keys (development)
    107 
    108 knextlevel = ")"
    109 kclean = "m"-CTRL
    110 kscreendump = "@"
    111 kreload = "c"-CTRL
    112 kreboot = "z"-CTRL
    113 kforceredraw = "f"-CTRL
    114 kblackout = "B"
    115 kspeedup = "]"
    116 kslowdown = "["
    117 kantimatter = "q"-CTRL
    118 kupone = "e"-CTRL
    119 kautoman = "A"
    120 kincstr = "S"
    121 kdecstr = "D"
    122 kincmax = "F"
    123 kzapgard = "Z"
    124 kplayback = "p"-CTRL
    125 kskip5 = "+"
    126 ktimeback = "<"
    127 ktimefwd = ">"
    128 ktimeup = "M"
    129 kerasegame = "*"
    130 
    131 *-------------------------------
    132 *
    133 *  K E Y S
    134 *
    135 *  Detect & respond to keypresses
    136 *
    137 *-------------------------------
    138 KEYS
    139  lda SINGSTEP
    140  beq KEYS1
    141 
    142 freeze lda $C000
    143  bpl freeze
    144 
    145  cmp #kfreeze
    146  beq :fradv
    147 
    148  ldx #0
    149  stx SINGSTEP
    150 
    151  lda #0 ;ignore the keypress that breaks ESC
    152  beq KEYS2
    153 
    154 :fradv lda #1
    155  sta SINGSTEP
    156  sta $C010
    157  sta keypress
    158 ]rts rts
    159 
    160 KEYS1 lda $C000 ;ASCII value of last keypress
    161  ;(Hibit is keyboard strobe)
    162 KEYS2 sta keypress
    163 
    164  lda $C010 ;Hibit is any-key-down flag
    165  ;(Clears keyboard strobe)
    166  sta keydown
    167 
    168  jsr KREAD ;Keyboard control
    169 
    170  lda keypress
    171  bpl ]rts
    172 
    173  do DebugKeys
    174 
    175  ldx develment
    176  beq :nogo ;GO codes work only in cheat mode
    177  cmp #"0"
    178  bcc :nogo
    179  cmp #"9"+1
    180  bcs :nogo
    181 
    182 * We have a keypress 0-9
    183 * Check if it follows a "GO" key sequence
    184 
    185  lda #C_go0
    186  ldx #>C_go0
    187  jsr checkcode
    188  bne :nogo0
    189  lda #0 ;1st digit
    190 :golevel clc
    191  adc keypress
    192  sec
    193  sbc #"0" ;2-key value
    194 
    195  cmp #4 ;only levels 4-12 accessible
    196  bcc ]rts
    197  cmp #13
    198  bcs ]rts
    199  sta NextLevel
    200  jsr shortentime
    201 ]rts rts
    202 
    203 :nogo0 lda #C_go1
    204  ldx #>C_go1
    205  jsr checkcode
    206  bne :nogo
    207  lda #10
    208  bne :golevel
    209 
    210  fin
    211 
    212 * Normal key handling
    213 
    214 :nogo lda keypress
    215  jsr addkey ;Add key to kbd buffer
    216 
    217  do FinalDisk
    218  else
    219 
    220 * Set development flag?
    221 
    222  lda #C_devel
    223  ldx #>C_devel
    224  jsr checkcode
    225  bne :1
    226  lda #1
    227  sta develment
    228  jmp gtone
    229 :1
    230  fin
    231 
    232 * Skip to next level?
    233 
    234  lda #C_skip
    235  ldx #>C_skip
    236  jsr checkcode
    237  bne :2
    238  lda #3 ;up to level 4
    239  ldx develment
    240  beq :limit
    241  lda #11 ;or level 12 in cheat mode
    242 :limit cmp level
    243  bcc :2
    244  inc NextLevel
    245 
    246  jsr shortentime
    247 :2
    248  fin
    249 
    250 * Special keys
    251 
    252  jsr LegitKeys
    253 
    254  jsr DevelKeys
    255 
    256  jsr TempDevel
    257 
    258 ]rts rts
    259 
    260 *-------------------------------
    261 *
    262 *  L E G I T   K E Y S
    263 *
    264 *-------------------------------
    265 LegitKeys
    266  lda keypress
    267  cmp #kfreeze
    268  bne :1
    269  jmp freeze
    270 
    271 :1 cmp #krestart
    272  bne :1a
    273  jmp goattract ;in topctrl
    274 
    275 :1a cmp #kabort
    276  bne :1b
    277  jmp restart
    278 
    279 :1b do EditorDisk
    280  cmp #kreturn
    281  bne :2
    282  jmp gobuild
    283  fin
    284 
    285 * Keyboard/joystick
    286 
    287 :2 cmp #ksetkbd
    288  bne :30
    289  lda #0
    290  sta joyon
    291 ]sk1 jmp gtone
    292 
    293 :30 cmp #ksetjstk
    294  bne :31
    295  jsr setcenter
    296  jmp ]sk1
    297 
    298 :31 cmp #kflipx
    299  bne :32
    300  lda jhoriz
    301  eor #1
    302  sta jhoriz
    303  bpl ]sk1
    304 
    305 :32 cmp #kflipy
    306  bne :3
    307  lda jvert
    308  eor #1
    309  sta jvert
    310  bpl ]sk1
    311 
    312 * Sound on/off
    313 
    314 :3 cmp #ksound
    315  bne :16
    316 ]togsound
    317  jsr zerosound
    318  lda soundon
    319  eor #1
    320  sta soundon
    321  bne ]sk1
    322  rts
    323 
    324 :16 cmp #kmusic
    325  bne :26
    326  lda musicon
    327  eor #1
    328  sta musicon
    329  bne ]sk1
    330  rts
    331 
    332 :26 cmp #kversion
    333  bne :17
    334  jmp dispversion ;display version #
    335 
    336 * Save/load game
    337 
    338 :17 cmp #ksavegame
    339  bne :18
    340  lda level
    341  sta SavLevel
    342  jmp DoSaveGame
    343 
    344 * Show time left
    345 
    346 :18 cmp #kshowtime
    347  bne :19
    348  lda #3
    349  sta timerequest
    350  rts
    351 
    352 :19
    353 ]rts rts
    354 
    355 *-------------------------------
    356 *
    357 *  D E V E L O P M E N T - O N L Y   K E Y S
    358 *
    359 *-------------------------------
    360 DevelKeys
    361  lda develment ;development flag
    362  beq ]rts
    363 
    364  jsr checkcodes ;secret codes
    365 
    366  lda keypress
    367  cmp #kclean
    368  bne :1
    369  lda #0
    370  sta develment
    371  rts
    372 :1
    373 ]rts rts
    374 
    375 *-------------------------------
    376 * Temp development keys
    377 * (remove for final version)
    378 *-------------------------------
    379 TempDevel
    380  do DebugKeys
    381 
    382  lda develment ;development flag
    383  beq ]rts
    384 
    385  lda keypress
    386  cmp #kforceredraw
    387  bne :10
    388  lda #2
    389  sta redrawflg
    390  lda #0
    391  sta blackflag
    392  rts
    393 
    394 :10 cmp #kblackout
    395  bne :9
    396  lda blackflag
    397  eor #$ff
    398  sta blackflag
    399 ]rts rts
    400 
    401 :9 cmp #kantimatter
    402  bne :17
    403  lda #initAMtimer
    404  sta AMtimer
    405  rts
    406 
    407 :17 cmp #kincstr
    408  bne :20
    409  inc ChgKidStr
    410  inc ChgOppStr
    411  rts
    412 
    413 :20 cmp #kincmax
    414  bne :36
    415  jmp boostmeter
    416 
    417 :36 cmp #knextlevel
    418  bne :28
    419  inc NextLevel
    420  rts
    421 
    422 :28 cmp #kskip5
    423  bne :30
    424  lda level
    425  clc
    426  adc #5
    427  sta NextLevel
    428  rts
    429 :30
    430 
    431 * keys 0-9
    432 
    433  lda keypress
    434  cmp #"0"
    435  bcc :non
    436  cmp #"9"+1
    437  bcs :non
    438  sec
    439  sbc #"0"
    440  sta guardprog
    441 ]sk1 jmp gtone
    442 
    443 * non-numeric keys
    444 
    445 :non cmp #kreload
    446  bne :8
    447  jsr preload
    448  lda #2
    449  sta redrawflg
    450  jsr reload
    451  jmp postload
    452 
    453 * speed up/slow down delay loop
    454 
    455 :8 cmp #kspeedup
    456  bne :13
    457  lda SPEED
    458  cmp #5
    459  bcc :12
    460  sec
    461  sbc #4
    462  sta SPEED
    463  jmp ]sk1
    464 :12 lda #1 ;fastest
    465  sta SPEED
    466 ]rts rts
    467 
    468 :13 cmp #kslowdown
    469  bne :14
    470  jsr gtone
    471  lda SPEED
    472  clc
    473  adc #4
    474  sta SPEED
    475  rts
    476 
    477 * Screen dump
    478 
    479 :14 cmp #kscreendump
    480  bne :15
    481  lda PAGE
    482  jmp screendump
    483 
    484 :15 cmp #kupone
    485  bne :19
    486  lda KidY
    487  sec
    488  sbc #63 ;BlockHeight
    489  sta KidY
    490  dec KidBlockY
    491  rts
    492 
    493 :19 cmp #kdecstr
    494  bne :21
    495  dec ChgKidStr
    496 ]rts rts
    497 
    498 :21 cmp #kautoman
    499  bne :23
    500  lda ManCtrl
    501  eor #$ff
    502  sta ManCtrl
    503  rts
    504 
    505 * Change levels
    506 
    507 :23
    508  cmp #kplayback
    509  bne :24
    510  lda #1
    511  sta level
    512  lda #2
    513  sta NextLevel
    514  rts
    515 
    516 :24 cmp #ktimeback
    517  bne :31
    518  lda #-2
    519 :chgtime clc
    520  adc FrameCount+1
    521  sta FrameCount+1
    522  rts
    523 
    524 :31 cmp #ktimefwd
    525  bne :32
    526  lda #2
    527  bne :chgtime
    528 
    529 :32 cmp #kerasegame
    530  bne :33
    531  lda #$ff
    532  sta SavLevel
    533  jmp DoSaveGame
    534 
    535 :33 cmp #ktimeup
    536  bne :34
    537  lda #$ff
    538  sta FrameCount+1
    539  rts
    540 
    541 :34
    542  fin
    543 ]rts rts
    544 
    545 *-------------------------------
    546 * Temporarily change BBundID to reload code & data from side 1
    547 
    548 postload
    549 ]sm lda #$a9
    550  sta BBundID
    551  rts
    552 
    553 preload
    554  lda BBundID
    555  sta ]sm+1
    556  lda #POPside1
    557  sta BBundID
    558  rts
    559 
    560 *-------------------------------
    561 *
    562 * A D D K E Y
    563 *
    564 * In: A = key value
    565 *
    566 *-------------------------------
    567 addkey
    568  ldx keybufptr ;index to last key entry
    569  inx
    570  cpx #keybuflen
    571  bcc :ok
    572  ldx #0 ;wrap around
    573 :ok stx keybufptr
    574 
    575  sta keybuf,x
    576 ]rts rts
    577 
    578 *-------------------------------
    579 *
    580 *  C H E C K   C O D E S
    581 *
    582 *  Only work in devel mode
    583 *
    584 *-------------------------------
    585 checkcodes
    586  do FinalDisk
    587  rts
    588  else
    589 
    590  lda #C_boost
    591  ldx #>C_boost
    592  jsr checkcode
    593  bne :1
    594  jsr boostmeter
    595  lda MaxKidStr
    596  sta origstrength
    597  rts
    598 
    599 :1 lda #C_restore
    600  ldx #>C_restore
    601  jsr checkcode
    602  bne :2
    603  jmp rechargemeter
    604 
    605 :2 lda #C_zap2
    606  ldx #>C_zap2
    607  jsr checkcode
    608  bne :3
    609 ;zap guard down to 0
    610  lda #0
    611  sec
    612  sbc OppStrength
    613  sta ChgOppStr
    614  rts
    615 
    616 :3 lda #C_zap1
    617  ldx #>C_zap1
    618  jsr checkcode
    619  bne :4
    620  ;zap guard down to 1
    621  lda #1
    622  sec
    623  sbc OppStrength
    624  sta ChgOppStr
    625  rts
    626 
    627 :4 lda #C_tina
    628  ldx #>C_tina
    629  jsr checkcode
    630  bmi :5
    631  lda #14
    632  sta NextLevel
    633  jsr shortentime
    634  rts
    635 :5
    636 ]rts rts
    637  fin
    638 
    639 *-------------------------------
    640 *
    641 * Compare keybuf sequence against code sequence
    642 *
    643 * In: A-X = code sequence address lo-hi
    644 * Return A = 0 if it matches, else ff
    645 *
    646 *-------------------------------
    647 checkcode
    648  sta :smod+1
    649  stx :smod+2
    650 
    651  ldx keybufptr ;last key entry
    652  ldy #0 ;last char of code seq
    653 :loop
    654 :smod lda $ffff,y ;smod
    655  beq ]rts ;0 = code seq delimiter
    656  cmp keybuf,x
    657  beq :match
    658  cmp #"A" ;alpha?
    659  bcc :fail
    660  cmp #"Z"+1
    661  bcs :fail
    662  ora #$20 ;yes--try LC too
    663  cmp keybuf,x
    664  bne :fail
    665 
    666 :match iny
    667  dex
    668  bpl :loop
    669  ldx #keybuflen-1 ;wrap around
    670  bpl :loop
    671 
    672 :fail lda #$ff
    673 ]rts rts
    674 
    675 *-------------------------------
    676 *
    677 * Key sequence codes
    678 *
    679 * Use all caps; LC will be accepted too
    680 *
    681 *-------------------------------
    682 C_skip rev "SKIP"
    683  db 0
    684 
    685  do FinalDisk
    686  else
    687 
    688 C_devel rev "POP"
    689  db 0
    690 C_go0 rev "GO0"
    691  db 0
    692 C_go1 rev "GO1"
    693  db 0
    694 C_zap2 rev "ZAP"
    695  db 0
    696 C_boost rev "BOOST"
    697  db 0
    698 C_restore rev "R"
    699  db 0
    700 C_zap1 rev "Z"
    701  db 0
    702 C_tina rev "TINA"
    703  db 0
    704 
    705  fin
    706 
    707 *-------------------------------
    708 *
    709 *  K R E A D
    710 *
    711 *  Keyboard player control
    712 *
    713 *  (Register a keypress for as long as key is held down)
    714 *
    715 *  Out: kbdX, kbdY
    716 *
    717 *-------------------------------
    718 KREAD
    719  lda #0
    720  sta kbdX
    721  sta kbdY
    722 
    723  lda keypress
    724  bmi :cont ;fresh press
    725 
    726  ldx keydown
    727  bpl ]rts ;No fresh press & no key down
    728 
    729  ora #$80 ;stale press, key still down
    730 :cont
    731  cmp #kleft
    732  beq :left
    733  cmp #kleft-SHIFT
    734  bne :1
    735 
    736 :left lda #-1
    737 :setx sta kbdX
    738  rts
    739 
    740 :1 cmp #kright
    741  beq :right
    742  cmp #kright-SHIFT
    743  bne :2
    744 
    745 :right lda #1
    746  bne :setx
    747 
    748 :2 cmp #kup
    749  beq :up
    750  cmp #kup-SHIFT
    751  bne :3
    752 
    753 :up lda #-1
    754 :sety sta kbdY
    755  rts
    756 
    757 :3 cmp #kdown
    758  beq :down
    759  cmp #kdown-SHIFT
    760  bne :4
    761 
    762 :down lda #1
    763  bne :sety
    764 
    765 :4 cmp #kupleft
    766  beq :ul
    767  cmp #kupleft-SHIFT
    768  bne :5
    769 
    770 :ul lda #-1
    771  sta kbdX
    772  bne :sety
    773 
    774 :5 cmp #kupright
    775  beq :ur
    776  cmp #kupright-SHIFT
    777  bne :6
    778 
    779 :ur lda #1
    780  sta kbdX
    781  lda #-1
    782  sta kbdY
    783  bne :sety
    784 :6
    785 
    786 ]rts rts
    787 *-------------------------------
    788 FACEJSTK
    789  lda #0
    790  sec
    791  sbc JSTKX
    792  sta JSTKX ;reverse jstk x
    793 
    794  ldx clrF
    795  lda clrB
    796  sta clrF
    797  stx clrB ;& switch clrF/clrB
    798 
    799 ]rts rts
    800 
    801 *-------------------------------
    802 *
    803 *  Note: Jstk-push flags are saved as if back = R, fwd = L
    804 *  (i.e., char is facing L)
    805 *
    806 *-------------------------------
    807 SAVESELECT
    808  ldx #4
    809 :loop lda clrF,x
    810  sta clrSEL,x
    811  dex
    812  bpl :loop
    813  rts
    814 
    815 *-------------------------------
    816 LOADSELECT
    817  ldx #4
    818 :loop lda clrSEL,x
    819  sta clrF,x
    820  dex
    821  bpl :loop
    822  rts
    823 
    824 *-------------------------------
    825 SAVEDESEL
    826  ldx #4
    827 :loop lda clrF,x
    828  sta clrDESEL,x
    829  dex
    830  bpl :loop
    831  rts
    832 
    833 *-------------------------------
    834 LOADDESEL
    835  ldx #4
    836 :loop lda clrDESEL,x
    837  sta clrF,x
    838  dex
    839  bpl :loop
    840  rts
    841 
    842 *-------------------------------
    843 INITINPUT
    844  lda #0
    845 
    846  ldx #4
    847 :loop sta clrDESEL,x
    848  sta clrSEL,x
    849  dex
    850  bpl :loop
    851 ]rts rts
    852 
    853 *-------------------------------
    854 *
    855 *  C L E A R   J O Y S T I C K
    856 *
    857 *  In/out: JSTKX, JSTKY, btn
    858 *          clrF-B-U-D-btn
    859 *
    860 *  clr = 0: no press
    861 *  clr = 1: used press
    862 *  clr = -1: unused press
    863 *
    864 *  Assume char is facing L
    865 *
    866 *-------------------------------
    867 *
    868 *  Input consists of 5 "buttons": forward, back, up, down,
    869 *  and the real button.  Each button has its own "clr" flag:
    870 *  clrF,B,U,D & btn.
    871 *
    872 *  When ClrJstk sees a button down:
    873 *    If clr = 1 or -1... leave it alone
    874 *    If clr = 0... set clr = -1
    875 *
    876 *  When ClrJstk sees a button up:
    877 *    If clr = 0 or -1... leave it alone
    878 *    If clr = 1... set clr = 0
    879 *
    880 *  When GenCtrl acts on a button press, it sets clr = 1.
    881 *
    882 *-------------------------------
    883 CLRJSTK
    884  lda clrF
    885  bmi :1 ;leave it set at -1
    886 
    887  ldx JSTKX ;jstk fwd?
    888  bmi :yesF ;yes--if clr = 0, set clr = -1
    889 ;no--set clr = 0
    890  lda #0
    891  beq :staF
    892 
    893 :yesF cmp #0
    894  bne :1
    895 
    896  lda #-1
    897 :staF sta clrF
    898 
    899 *-------------------------------
    900 :1 lda clrB
    901  bmi :2
    902 
    903  ldx JSTKX
    904  cpx #1
    905  beq :yesB
    906 
    907  lda #0
    908  beq :staB
    909 
    910 :yesB cmp #0
    911  bne :2
    912 
    913  lda #-1
    914 :staB sta clrB
    915 
    916 *-------------------------------
    917 :2 lda clrU
    918  bmi :3
    919 
    920  ldx JSTKY
    921  bmi :yesU
    922 
    923  lda #0
    924  beq :staU
    925 
    926 :yesU cmp #0
    927  bne :3
    928 
    929  lda #-1
    930 :staU sta clrU
    931 
    932 *-------------------------------
    933 :3 lda clrD
    934  bmi :4
    935 
    936  ldx JSTKY
    937  cpx #1
    938  beq :yesD
    939 
    940  lda #0
    941  beq :staD
    942 
    943 :yesD cmp #0
    944  bne :4
    945 
    946  lda #-1
    947 :staD sta clrD
    948 
    949 *-------------------------------
    950 :4 lda clrbtn
    951  bmi :5
    952 
    953  ldx btn
    954  bmi :yesbtn
    955 
    956  lda #0
    957  beq :stabtn
    958 
    959 :yesbtn cmp #0
    960  bne :5
    961 
    962  lda #-1
    963 :stabtn sta clrbtn
    964 
    965 :5
    966 ]rts rts
    967 
    968 *-------------------------------
    969 *
    970 *  Z E R O S O U N D
    971 *
    972 *  Zero sound table
    973 *
    974 *-------------------------------
    975 ZEROSOUND
    976  lda #0 ;# sounds in table
    977  sta soundtable
    978  rts
    979 
    980 *-------------------------------
    981 *
    982 *  A D D S O U N D
    983 *
    984 *  Add sound to sound table
    985 *  (preserve registers)
    986 *
    987 *  In: A = sound #
    988 *
    989 *-------------------------------
    990 ]temp1 ds 1
    991 
    992 ADDSOUND
    993  stx ]temp1
    994 
    995  ldx soundtable
    996  cpx #maxsfx
    997  bcs :rts ;sound table full
    998 
    999  inx
   1000  sta soundtable,x
   1001  stx soundtable ;# sounds in table
   1002 
   1003 :rts ldx ]temp1
   1004  rts
   1005 
   1006 *-------------------------------
   1007 *
   1008 *  Demo keys (Call immediately after regular KEYS routine)
   1009 *
   1010 *  All keys interrupt demo except ESC and CTRL-S
   1011 *
   1012 *  Out: FF if interrupt, else 00
   1013 *
   1014 *-------------------------------
   1015 DEMOKEYS
   1016  lda level
   1017  bne :cont ;not in demo
   1018 
   1019  lda $c061
   1020  ora $c062 ;button?
   1021  bmi :interrupt
   1022  lda keypress
   1023  bpl :cont
   1024  cmp #ESC
   1025  beq :cont
   1026  cmp #ksound
   1027  beq :cont
   1028 :interrupt
   1029  lda #$ff
   1030  rts
   1031 :cont lda #0
   1032  rts
   1033 
   1034 *-------------------------------
   1035 *
   1036 * Special routine for use by BURN
   1037 *
   1038 * Make a list of visible torches--don't disturb trans list
   1039 *
   1040 *-------------------------------
   1041 maxtorches = 8
   1042 
   1043 torchx ds maxtorches+1
   1044 torchy ds maxtorches+1
   1045 torchstate ds maxtorches+1
   1046 torchclip ds maxtorches+1
   1047 
   1048 ]numtorches = locals
   1049 
   1050 torchcount ds 1
   1051 
   1052 LISTTORCHES
   1053  lda #0
   1054  sta ]numtorches
   1055 
   1056  lda VisScrn
   1057  jsr calcblue
   1058 
   1059  ldy #29
   1060 
   1061 :loop jsr :sub
   1062 
   1063  ldx ]numtorches
   1064  cpx #maxtorches
   1065  bcs :max
   1066 
   1067  dey
   1068  bpl :loop
   1069 
   1070  ldx ]numtorches
   1071 :max lda #$ff
   1072  sta torchx,x
   1073  sta torchcount ;start BURNing with torch #0
   1074 ]rts rts
   1075 
   1076 :sub lda (BlueType),y
   1077  and #idmask
   1078  cmp #torch
   1079  bne ]rts
   1080  lda fredbuf+1,y
   1081  sta BOTCUT ;temp
   1082 
   1083  tya
   1084  pha
   1085  jsr unindex
   1086 ;Out: A = tempblockx, X = tempblocky
   1087  pha
   1088  txa
   1089  ldx ]numtorches
   1090  tay
   1091  lda BlockBot+1,y
   1092  sec
   1093  sbc #3
   1094  sta torchy,x
   1095  lda BOTCUT ;0 or non0
   1096  sta torchclip,x
   1097  pla
   1098  clc
   1099  adc #1
   1100  cmp #10
   1101  bcs ]rts
   1102  asl
   1103  asl
   1104  sta torchx,x
   1105 
   1106  pla
   1107  tay
   1108  lda (BlueSpec),y
   1109  sta torchstate,x
   1110 
   1111  inc ]numtorches
   1112 ]rts rts
   1113 
   1114 *-------------------------------
   1115 *
   1116 * B U R N
   1117 *
   1118 * Animate torch flames (for use while music is playing)
   1119 *
   1120 * NOTE--this routine bypasses normal graphics system
   1121 * and draws directly on the displayed page
   1122 * Leaves trans list, redraw buffers, etc. undisturbed
   1123 *
   1124 *-------------------------------
   1125 BURN
   1126  lda torchx
   1127  bmi ]rts ;no torches on this screen
   1128 
   1129  ldx torchcount ;last torch burned
   1130  inx
   1131  lda torchx,x
   1132  bpl :ok ;torchx = $ff means "end of torch list"
   1133  ldx #0 ;start again at beginning of list
   1134 :ok stx torchcount
   1135  lda torchx,x
   1136  sta XCO
   1137  lda torchy,x
   1138  sta YCO
   1139  lda torchclip,x
   1140  sta BOTCUT
   1141  lda torchstate,x
   1142  jsr getflameframe
   1143  sta torchstate,x
   1144  tax
   1145  jsr setupflame
   1146  lda BOTCUT
   1147  bne :partial
   1148 :whole jmp fastlay  ;<---DIRECT HIRES CALL
   1149 ]rts rts
   1150 
   1151 * If bottom portion of flame would overlap with someone's
   1152 * head, clip it (use LAY)
   1153 
   1154 :partial
   1155  jsr initlay
   1156  lda #0
   1157  sta OFFSET
   1158  lda YCO
   1159  sec
   1160  sbc #4
   1161  sta BOTCUT
   1162  jmp lay ;<---DIRECT HIRES CALL
   1163 
   1164 *-------------------------------
   1165 *
   1166 * Get # of minutes (or seconds) left
   1167 *
   1168 * In: FrameCount (0-65535)
   1169 * Out: MinLeft (BCD byte: $00-99) = # of minutes left
   1170 *      SecLeft = # of seconds left (during final minute)
   1171 *
   1172 *-------------------------------
   1173 GETMINLEFT
   1174  lda #0
   1175  sta ]count
   1176  sta ]count+1
   1177 
   1178  lda #min
   1179  sta :sm1+1
   1180  lda #>min
   1181  sta :sm2+1
   1182  jsr :sub ;get MinLeft
   1183  sty MinLeft
   1184  cpy #2
   1185  bcs ]rts
   1186 
   1187 * Final minute only: count seconds
   1188 
   1189  lda #59*min
   1190  sta ]count
   1191  lda #>59*min
   1192  sta ]count+1
   1193 
   1194  lda #sec
   1195  sta :sm1+1
   1196  lda #>sec
   1197  sta :sm2+1
   1198  jsr :sub ;get SecLeft
   1199  sty SecLeft
   1200  rts
   1201 
   1202 * Sub returns min/sec left
   1203 
   1204 :sub ldy #$61 ;counter
   1205 
   1206 :loop lda ]count+1
   1207  cmp FrameCount+1
   1208  bcc :1
   1209  bne ]rts
   1210  lda ]count
   1211  cmp FrameCount
   1212  bcs ]rts
   1213 :1
   1214  lda ]count
   1215  clc
   1216 :sm1 adc #min
   1217  sta ]count
   1218  lda ]count+1
   1219 :sm2 adc #>min
   1220  sta ]count+1
   1221 
   1222  sed
   1223  tya
   1224  sec
   1225  sbc #1
   1226  cld
   1227  tay
   1228  bpl :loop
   1229  ldy #0
   1230 ]rts rts
   1231 
   1232 *-------------------------------
   1233 timetable
   1234 :0 dw t-60*min
   1235  dw t-55*min
   1236  dw t-50*min
   1237  dw t-45*min
   1238  dw t-40*min
   1239  dw t-35*min
   1240  dw t-30*min
   1241  dw t-25*min
   1242  dw t-20*min
   1243  dw t-15*min
   1244 :20 dw t-10*min
   1245  dw t-5*min
   1246  dw t-4*min
   1247  dw t-3*min
   1248  dw t-2*min
   1249  dw t-1*min+1
   1250  dw t*min+5 ;5 frames after t=0: game over
   1251  dw 65535
   1252 
   1253 nummsg = *-timetable
   1254 
   1255 *-------------------------------
   1256 *
   1257 * Keep track of time remaining
   1258 *
   1259 *-------------------------------
   1260 ]rts rts
   1261 KEEPTIME
   1262 ; lda autopilot
   1263 ; bne ]rts
   1264  lda level
   1265  beq ]rts ;not in demo or during playback
   1266 
   1267  lda KidLife
   1268  bpl ]rts ;clock stops when kid is dead
   1269 
   1270 * Inc frame counter
   1271 
   1272  inc FrameCount
   1273  bne :1
   1274  inc FrameCount+1
   1275 :1 bne :2
   1276  lda #$ff
   1277  sta FrameCount
   1278  sta FrameCount+1 ;don't wrap around
   1279 
   1280 * time for next message yet?
   1281 
   1282 :2 ldy NextTimeMsg ;0-2-4 for 1st, 2nd, 3rd msgs
   1283  cpy #nummsg
   1284  bcs ]rts ;no more msgs
   1285  lda FrameCount+1
   1286  cmp timetable+1,y
   1287  bcc ]rts ;not yet
   1288  lda FrameCount
   1289  cmp timetable,y
   1290  bcc ]rts
   1291 
   1292 * Yes--is this a convenient time to show msg?
   1293 
   1294  lda msgtimer
   1295  bne ]rts ;wait till other msgs are gone
   1296 
   1297 * Yes--show msg (& inc NextTimeMsg)
   1298 
   1299  inc NextTimeMsg
   1300  inc NextTimeMsg
   1301 
   1302  lda #2
   1303  sta timerequest
   1304 ]rts rts
   1305 
   1306 *-------------------------------
   1307 *
   1308 * Shorten remaining time to 15 minutes
   1309 * (e.g., 1st time player cheats by skipping a level)
   1310 *
   1311 *-------------------------------
   1312 SHORTENTIME
   1313  ldy NextTimeMsg
   1314  cpy #20
   1315  bcs ]rts ;time is already short enough
   1316  ldy #18
   1317  sty NextTimeMsg
   1318  lda timetable,y
   1319  sta FrameCount
   1320  lda timetable+1,y
   1321  sta FrameCount+1
   1322 ]rts rts
   1323 
   1324 *-------------------------------
   1325 *
   1326 * Cue song
   1327 *
   1328 * In: A = song #
   1329 *     X = # of cycles within which song must be played
   1330 *
   1331 *-------------------------------
   1332 CUESONG
   1333  sta SongCue
   1334  stx SongCount
   1335  rts
   1336 
   1337 *-------------------------------
   1338 *
   1339 *  Strobe keyboard
   1340 *
   1341 *-------------------------------
   1342 DLOOP
   1343 STROBE jsr keys ;Detect & respond to keypresses
   1344  jsr controller
   1345 ]rts rts
   1346 
   1347 
   1348 *-------------------------------
   1349  lst
   1350 eof ds 1
   1351   usr $a9,19,$b00,*-org
   1352  lst off