Spelunker Game Hacks

When I first set my mind to hacking and writing the article for the Spelunker Game Reverse Engineered, I realized I had some specific goals in mind. First I wanted to ensure I could obtain infinite lives. Then I wanted to find a way to speed up the player, provide a longer fall, and increase the player’s jump height. While I have not yet been successful in accomplishing all those goals, I did manage to work out a few and discover new hacks along the way.

Spelunker was written around 1984 by a company called Broderbund for the Commodore 64. It places your character deep inside a cavern at the start of the game, loaded on an elevator shaft. There are all kind of dangers along the way such as ghosts, bats, steaming lava pools, fissures, and so on. The goal of the game is to locate a hidden pyramid to win it.

This guide however is not meant to be a review of the Spelunker game. Rather you will learn how to hack into the game using WinVice and “change the rules”, as I like to say. The goal is to discover things along the way and have fun doing so.

Please Note: This page assumes an understanding of assembly language on the Commodore 64. Assembly language allows you to write very fast programs in memory since it speaks directly to the CPU. Most of the commercial games you see on the Commodore 64 and similar 8-bit machines were developed in Assembly language.

On this page you can view our Machine Language Tutorials for further information.

Click the button below to download the Spelunker game for the Commodore 64. Note to newbies: This file is in D64 (disk image) format. You will need a copy of the WinVice emulator to play this. Also note that the hacks on this page and my other game hacking pages, do not save a copy of the hacks. You will need to follow the video and enter them in the WinVice monitor to see them in action. Please feel free to leave a comment, if you get stuck on something.

Feel free to use the VICE C64 Emulator below to load up Basic programs or files that were downloaded on this page.

To load a file, click on the menu C64/Attach D64 or you can also drop and drag a .D64 image onto the VICE window and it will load.

So after you have clicked on the button DOWNLOAD SPELUNKER, first unzip it, and then you can drag the .D64 image straight into the VICE C64 window to see it running real time!

Specific Hacks Discovered

Spelunker Hack

First of all please understand that the code was exacted by using WinVice to take a snapshot of the assembly language listing, saved to to a VSF file. Then this file was loaded into Regenerator and copied to Microsoft Word so I could more easily analyze it. Also by using Word I was able to search through the entire source code for specific commands. Then I pasted this into an Excel spreadsheet so that the searched commands could be reviewed more easily. Microsoft Excel is an excellent tool where you can paste data into individual cells, and utilize the Find command to search through an expansive amount of data and see it compiled it in a window. Click on Find All and then on the More button to see the results. The only thing I can’t do (yet) is figure out how to copy the data from the Find and Replace window, but I am open for suggestions. 🙂

Player has infinite lives

Player has infinite lives

This is a very popular hack embedded into games. It allows the player’s death to be frozen while the game continues. In this way, the player will still lose a life, but the game will keep running. Often with this feat for the Spelunker Game Reverse Engineered the game player is free to to explore levels they could not find before. The following code segment below shows where the life counter exists. You may also notice that the player’s character bar is being reproduced several times on the far right side of the screen (at the bottom). This should be evidence enough that the hack is working since he can go on living forever.

$4AB1 LDA #$50
$4AB3 STA $80
$4AB5 DEC $40 ; change to DEC $39 to prevent the player from losing a life.
$4AB7 RTS

So memory address $4aB5 was changed from DEC $40 to DEC $39 in order to sustain the lives counter. By selecting a memory address not used by the game, the player’s lives is fixed and the game can be played forever.

Game Timer Speed

While submerging into late night hacks, after much trial and error in the Spelunker Game Reverse Engineered, I eventually discovered where some specific timing elements exist deep in the code. In the code segment below, there is a timer that controls the interrupt speed of the objects and characters surrounding our player. It is likely that our player subroutine exists within its own environment, so tweaking these bits had no effect (at least not on a minuscule level) on our player’s timed motion.

The subroutine begins at memory address $2C3E and starts with the command INC $BA. This is a command that means to “Increment hex memory address $ba. The hexadecimal number be is translated into decimal as 186. So from an elementary understanding this is increasing the value found in memory address 186 by 1 byte. This will then read 187 on the next access (such as using an LDA command), which Loads it from the accumulator.

I won’t go into a lot of detail for the Spelunker Game Reverse Engineered, since this is not meant to be a tutorial for assembly language. However, the next few lines load a value from memory address $07 and check the bits in there. I changed it from AND #$03 to AND #$28. By accessing a larger number here (known as comparing the binary bits), we can slow down the time by that many more machine cycles. Then the next line will jump to (BNE – Branch Not Equal) to memory address $2C5E if then condition is not yet true (or <> in Basic). Often you will see this in commercial games. Also I am only showing a small snippet to avoid any confusion in larger sections of code. That would require its own massive tutorial.

$2C3E INC $BA
$2C40 LDA a07
$2C42 AND #$03 ; interrupt timer
$2C44 BNE b2C5E

Player can fall longer

Another hack I uncovered while surfing through the code and trying out different address changes, was allowing our player to fall from a greater height without dying. In the original version of the Spelunker Game Reverse Engineered, the player only has to drop a few feet in the air and he dies instantly. This was quite annoying so I knew I wanted to change this. The code below takes care of this for us:

$351A LDA $1E

$351C BEQ $352D

$351E INC $1F

$3520 LDX #$02

$3522 LDA $64

$3524 BNE $352A

$3526 LDA $7E

$3528 BEQ $352D

$352A JSR $352E

$352D RTS

It was so wonderful to see our player fall further without dying. What this section is doing is increasing the gravity on our player and allowing more cycles for his fall. Sometimes the player can get stuck, so use it wisely.

Setting a Dynamite Charge

Spelunker DynamiteIn order to get through boulders that barricade another side of the screen, your player must first collect dynamite objects and then blast the rocks by pressing the ‘D’ key on your keyboard. If you are caught in the middle of an explosion, then well…it’s curtains for you.

Anyway I wanted our player to not lose any of his dynamite charges, so I began searching late one evening into the Spelunker Game Reverse Engineered code using the Regenerator tool. I’ll admit this was not an easy find. I could probably have searched for memory address $C5 (keyboard read: 197 = decimal) and traced it from there, but I was busy uncovering many other hacks and didn’t want to divulge a lot of time on that. So on accident one day I discovered it while combing through some DEC statements. The code is below.

I don’t wish to explain everything seen below, but by glancing at it likely the first section LDA ($79),Y is checking a bomb on the screen to see if you are empty or something, and if you’re not it appears to jump over the statement that reduces the dynamite inventory, by pulling a value off the stack and returning back where it came from. However, the heart of the subroutine is on line $3F4F, which decreases the amount of dynamite our player is carrying. The hack involved is to change this to something like DEC $30 that isn’t being used by the program. This will never deduct it from his inventory and allow you to keep one dynamite charge, if that’s all you have in possession. Also there is more code to follow below that, but to keep this example simple, I truncated a section of it.

$3F3B LDA ($79),Y
$3F3D BNE b3F63
$3F3F LDA #$7F
$3F41 STA ($79),Y
$3F43 LDA #$80
$3F45 STA a35
$3F47 LDA #$16
$3F49 STA aB9
$3F4B LDA #$FF
$3F4D STA a32
$3F4F DEC a34

$3F51 LDA $79
$3F53 STA $36
$3F55 LDA $7A
$3F57 STA $37
$3F59 LDA $14
$3F5B STA $38
$3F5D LDA $15
$3F5F STA $39
$3F61 LDX #$06
$3F63 PLA
$3F64 RTS

Bat’s Coordinates

Spelunker Bat

While hacking and disassembling the game source, I eventually found the area that controls the sprite bat seen later in the lower caverns. The bat will spit droplets on our player, which is often pretty hard to avoid. These will come down in pairs as seen in the Spelunker Game Reverse Engineered. However, I found a way to move the bat very quickly so that it is not locked in on specific positions to take out our player for our example of the Spelunker Game Reverse Engineered. The hack is below:

$3467 LDA $07
$3469 AND #$07
$346B BNE $3479
$346D INC $5B
$346F LDA $5B
$3471 CMP #$30
$3473 BNE $3479
$3475 LDA #$00
$3477 STA $5B
$3479 RTS

So the hack to perform is to change memory address $346D to something like DEC $58. This will send the bat flying across the street in scattered directions. By doing this I was able to progress through various stages where the bat impeded my entry earlier. Line $34EE (not listed here) also controls the animation frames of the bat.

Spelunker Bouncing on the Screen

Spelunker sprite

Sometime later, I discovered a new hack as I was modifying the player’s gravity. I noticed that as I reverse a decrement (DEC) register to an increment (INC) that it knocked the player’s gravity out of order and suddenly our Spelunker Game Reverse Engineered character was flying all over the screen.  So apparently this seems to control the positioning of the player and it throws off the coordinates and somehow the gravity. This is accomplished by entering the WinVICE monitor and changing the following assembled lines as listed below

a 45b8 inc $9a

Many other Spelunker Hacks Discovered

Okay, as I was exhausting a lot of time into disassembling this game, I began to see more of how the Spelunker Game Reverse Engineered worked and made a note (below) of many of the other little “secrets” I uncovered. The total time spent breaking down code, spending many hours utilizing tweaks with the WinVice monitor, and running the game was close to one week of work. That is about exactly how long it will take to pretty much tear down any game. So be prepared if you suddenly have an urge to learn about your favorite Commodore 64 game. You will invest a lot of time and research on it. I hope this guide was an eye opener for you and inspires you to write your own game soon.

The code is not complete below, but it does show everything I learned along the way of this tiring journey. Stay tuned to this website and my YouTube channel as more hacks will be coming soon. Hoping to put out a new game hack each month.

Spelunker Game Reverse Engineered Segments

* = $1005

$100C – VIC Interrupt Mask Register (IMR), $D01A
$100F – Raster position ($D01A)
$1014 – CIA1 Interrupt Control Register, $DC0D
$1017 – Read low/hi byte, #LDA #<$262F, LDA #>$262F
$101F – CIA2 Data Direction Register A ($DD02)
$1024 – CIA2 Data Direction Register A ($DD02)
$1027 – CIA2 Data Port Register A, $DD02
$102C – CIA2 Data Port Register A, $DD02
$1031 – Border Color
$1034 – Background Color 0
$1037 – Background Color 1, Multi-Color Register 0
$103A – Background Color 2, Multi-Color Register 1
$103D – Sprite display Enable
$1040 – JSR $117C: STA $CC00,$CD00,$CE00,$CF00
$1045 – JSR $1192: STA $D800,$D900,$DA00,$DB00
$1048 – JSR $11A6: STA $CCF0,$CD18,$CD40,$CD68,$CD90,$CDB8,$CE08,$CE58,$CE80
$104B – Read low/hi bytes, $109B (IRQ)
$106C – VIC Memory Control Register
$1071 – VIC Control Register 2, $D016
$1076 – VIC Control Register 1, $D011
$1080 – JSR $22E4: STA $1C,$1D,$20,$18,$19,$D400 (Audio)
$1089 – JSR $1120: LDA $112E,LDA $1131,PHA, LDA $1130,PHA
$108C – JSR $230E: DEC $20, LDA $18, STA $D404, $D40B, DEC $18, DEC $19 (Audio)
$108F – JSR $158E: LDA $07, DEC $C3, INC $BB, STA $A1, STA $C4, STA $C408
$1092 – JSR $21C8: LDA $112E, CMP #$0F
$1095 – JSR $10AB: LDA $DC00, STA $D011: $D022: $D023, etc (Set Interrupt)
$109B – VIC Interrupt Request Register (IRR), $D019
$109F – VIC Interrupt Request Register (IRR), $D019
$10AB – CIA1 Data Port Register A
$10B8 – VIC Control Register 1, $D011
$10BD – VIC Control Register 1, $D011
$10C2 – Background Color 1, Multi-Color Register 0
$10C7 – Background Color 2, Multi-Color Register 1
$10CC – JSR $1192: STA $D800,$D900,$DA00,$DB00
$10D6 – VIC Interrupt Mask Register (IMR), $D01A
$10D9 – Raster Position, $D012
$109C – Read low/hi bytes, LDA #<$109B, LDA #>$109B
$10E8 – Sprite display Enable
$10EB – Select Filter Mode and Volume, $D418
$10EE – JSR $117C: STA $CC00,$CD00,$CE00,$CF00
$10F3 – VIC Memory Control Register, $D018
$10F6 – JSR $11A6: STA $CCF0,$CD18,$CD40,$CD68,$CD90,$CDB8,$CE08,$CE58,$CE80
$10FB – VIC Control Register 1, $D011
$10FF – VIC Control Register 2, $D016
$110C – JSR $3B6C: STA $BA
$1110 – VIC Control Register 1, $D011
$1115 – VIC Control Register 1, $D011
$117E – Could be screen area that is being written to, $CC00-$CF00 because it is followed by Color RAM Memory
$1192 – Color RAM Memory write
$11A6 – More possible areas for writing to the display screen
$1224 – JSR $117C: STA $CC00: $CD00: $CE00: $CF00
$1227 – JSR $11E2: STA $CCF0: $CD40: $CD68: $CDE0: $CE30: $CE58: $CE80: $CEA8: $CED0: $CF20
$122A – JSR $112E
$1233 – JSR $1243: STA $9F, STA $A1, STA $9E, STA $A0, STA ($A0),Y, INC $9f, INC $A1
$123D – JSR $1243: STA $9F, STA $A1, STA $9E, STA $A0, STA ($A0),Y, INC $9f, INC $A1
$1272 – Background Color 2, Multi-Color Register 1, INC $112E
$1280 – Background Color 1, Multi-Color Register 0
$1289 – Background Color 1, Multi-Color Register 0
$128C – Background Color 2, Multi-Color Register 1
$128F – JSR $1192: STA $D800,$D900,$DA00,$DB00
$159B – DEC $C3

$1FA1 – Read low/hi bytes, LDA #<$109B, LDA #>$109B
$1FAD – VIC Interrupt Mask Register (IMR), $D01A
$1FB2 – Raster Position, $D012
$1FB7 – Sprite display Enable
$1FC4 – JSR $21B4: STA $D018: $D016, INC $112 (53272, 53270 – Character set)
$1FC7 – JSR $1FDF: LDA $5AB2,X CMP $5AB5, LDA $20FE, STA $A2, LDA $5AB2 STA $5AB5
$1FCA – JSR $208D: LDA $A2 CMP #$02, CMP #$05, CMP #$08, LDA $210A,Y STA $9E, LDA $210B,Y STA $95, LDA $2112,Y STA $A0, LDA $2113,Y STA $A1, STA ($9E),Y, STA ($A0),Y
$1FD3 – JSR $2125: LDA $DC00, STA $2124, STA ($9E),Y, STA , STA ($A0),Y (keyboard)
$1FD6 – JSR $21D0: LDA $07 AND #$03, INC $22, STA $D955: $D956: $D957: $D958: $D959
$1FD9 – JSR $21F3: STA $CCFA: $D8FA: $CD4A,X: $CD9A: $D99A: $CDEA: $CE3A,X: $DA3A,X: $CEB2,X: $DAB2,X: $CF02,X: $DB02,X: $D952: $D9A2: $D9F2: $DA42: $D94E: $D94F: $D950
$2038 – JSR $20C3: LDA #<$22D7 STA $9E, $9F, LDA #<$FAB2 STA $A0, $A1, STY $A3, $A4, LDA $211A,X STA ($9E),Y
$203B – JSR $27C2: STA $D01A, $D012, LDA #$<109B STA $0314, $0315, STA $D011 STA $5ACD: $3C0C
$205B – Read low/hi bytes, LDA #<$2276, LDA #>$2276
$205F – Read low/hi bytes, LDA #<$5AB5, LDA #>$5AB5
$206F – JSR $20D3
$2089 – JSR $20C3
$20C3 – Read low/hi bytes, LDA #<$22D7, LDA #>$22D7
$20CB – Read low/hi bytes, LDA #<$FAB2, LDA #>$FAB2
$2131 – CIA1 Data Port Register A, $DC00
$21A9 – JSR $3B80
$21B6 – VIC Memory Control Register, $D018
$21BB – VIC Control Register 2, $D016
$21BE – JSR $117C
$21C1 – JSr $21F3
$21D0 – More writing to Color RAM Memory
$22FA – Voice 1 Frequency Control – Low Byte, $D400
$2302 – Select Filter Mode and Volume, $D418
$2307 – Voice 1 Attack / Decay Cycle Control, $D405
$230A – Voice 2 Attack / Decay Cycle Control, $D40C
$2320 – Voice 1 Control Register, $D404
$232B – Voice 2 Control Register, $D40B
$2334 – DEC $18: Audio control variabloe
$233A – Voice 1 Control Register, $D404
$2340 – DEC $19: Audio control variable

$2346 – Voice 2 Control Register, $D40B
$2365 – Voice 1 Frequency Control – Low Byte, $D400
$236B – Voice 1 Frequency Control – High Byte, $D401
$2373 – Voice 1 Control Register, $D404
$237E – Voice 1 Control Register, $D404
$2385 – Voice 2 Control Register, $D40B
$267D – Read low/hi bytes, LDA #<$10AA, LDA #>$10AA
$2687 – JSR $203E
$2694 – JSR $3B6E
$269D – VIC Control Register 1, $D011
$26A2 – VIC Control Register 1, $D011
$26AC – CIA1 Interrupt Control Register, $DC0D
$26AF – Read low/hi bytes, LDA #<$262F, LDA #>$262F
$26B7 – CIA2 Data Direction Register A, $DD02
$26BC – CIA2 Data Direction Register A, $DD02
$26BF – CIA2 Data Port Register A, $DD00
$26C4 – CIA2 Data Port Register A, $DD00
$26F8 – DEC $A2
$26FC – JSR $2906
$26FF – JSR $2937
$2702 – JSr $27AB
$27C5 – VIC Interrupt Mask Register (IMR), $D01A
$27CA – Raster Position, $D012
$27CD – Read low/hi bytes, LDA #<$109B, LDA #>$109B
$27D7 – VIC Control Register 1, $D011
$27DC – VIC Control Register 1, $D011
$27E0 – JSR $27AB
$27F0 – JSR $3C0C
$27F3 – JSR $2B02
$27F6 – JSR $2BA0
$27F9 – JSR $2B34
$27FC – JSR $2BD2
$2801 – Sprite display Enable, $D015
$2804 – JSR $53A6
$2807 – JSR $2A46
$280A – Sprite to Sprite Collision Detect, $D01E
$280D – Sprite to Background Collision Detect, $D01F
$282D – JSR $4661
$2830 – JSR $3270
$2833 – JSR $30B3
$2836 – JSR $3DAD
$2839 – JSR $3C0E
$283C – JSR s3741
$283F – JSR s3E67
$2842 – JSR s3CF1
$2845 – JSR s42A9
$2848 – JSR s2A46
$284F – JSR s36B9
$2852 – JSR s2A7B
$2855 – JSR s33AF
$2858 – JSR s32C9
$285B – JSR s4059
$285E – JSR s4452
$2861 – JSR s3507
$2864 – JSR s49EF
$2867 – JSR s2A24
$286A – JSR j4C3D
$286D – JSR s4E15
$2870 – JSR s4608
$2873 – JSR s35DF
$2876 – JSR s47C7
$287D – JSR s31D4
$2880 – JSR s354A
$2883 – JSR s4691
$2886 – JSR s4996
$2889 – JSR s49CC
$288C – JSR s3FE1
$288F – JSR s484D
$2892 – JSR s47EF
$2895 – JSR s48C8
$2898 – JSR s3F65
$289B – JSR s2C3E
$289E – JSR s3A0C
$28A1 – JSR s28D7
$28A4 – JSR s53A6
$28A7 – JSR s4AB8
$28AA – JSR s4B3A
$28AD – JSR s28B3
$28B5 – Voice 3 Frequency Control – High Byte, $D40F
$28B9 – Voice 3 Control Register, $D412
$28BC – Oscillator 3 Output, $D41B
$28C4 – Voice 3 Frquency Control – High Byte, $D40F
$28F2 – Select Filter Mode and Volume, $D418
$5132 – JSR $27AB
$290E – Read low/hi bytes, LDA #<$0E00, LDA #>$0E00
$2937 – Read low/hi bytes, LDA #<$D800, LDA #>$D800
$295C – Color RAM Memory write
$297E – Read low/hi bytes, LDA #<$CED0, LDA #>$CED0
$2986 – Read low/hi bytes, LDA #<$391C, LDA #>$391C
$29CC – Raster Position, $D012
$29D8 – Background Color 0, $D021
$29DD – VIC Control Register 1, $D011
$29E2 – VIC Memory Control Register, $D018
$29E7 – Sprite 2 X Pos
$29EA – Sprite 3 X Pos
$29ED – Sprite 4 X Pos
$29F0 – Sprite 5 X Pos
$29F3 – Sprite 6 X Pos
$29F6 – Sprites 0-7 MSB of X coordinate
$29FB – Sprites 0-7 MSB of X coordinate
$2A03 – Background Color 0
$2A10 – VIC Control Register 1, $D011
$2A2E – CIA1 Data Direction Register A, $DC02
$2A31 – CIA1 Data Port Register A, $DC00
$2A42 – CIA1 Data Direction Register A, $DC02
$2A4A – JSR $33EE
$2A4F – JSR $352E
$2A54 – JSR $352E
$2A5B – JSR $330E
$2A67 – Sprite 0 X Pos
$2A6E – Sprite 0 Y Pos
$2A77 – Sprites 0-7 MSB of X coordinate
$2AD5 – INC $11 – scrolling down control
$2AE3 – INC $12 – turns off ground level
$2AE8 – DEC $12 – Turns off ground level view or in game-turns green
$2B30 – DEC $A2 – crashes if tweaked

; ANIMATION TIMER – increase to slow down enemies, objects, etc.
; rapid fire on button will allow player to float up the screen INC $00

$2C3E: E6 BA s2C3E INC aBA

INC $BA
LDA $07
AND #$28, #$2D
BNE $2C5E

$2C46 – JSR $2D35
$2C49 – JSR $2DA3
$2C4C – JSR $2E52
$2C4F – JSR $313F
$2C58 – JSR $2FE8
$2C5B – JSR $2781
$2C62 – JSR $318C
$2C6B – JSR $2C78
$2C74 – JSR $2C9C
$2DDA – DEC $09,X – changes the animated pits that Spelunker can fall into
$2E52 – INC $27 – set to DEC $27; lava explosion in pits (going up)
$2E78 – INC $28 – bat fires one round in an upward direction
$2FEF – Read low/hi bytes, LDA #<$3032, LDA #>$3032
$3011 – Read low/hi bytes, LDA #<$3032, LDA #>$3032
$30F7 – DEC $33 – graphics for the up/down moving escalator
$3163 – DEC $2F
$31F6 – INC $54 – animation frames for ghost
$327A – DEC $57 – player jumps higher. Yet ghost is invincible to player’s weapon

$335B – DEC $67 – animates data through the energy charge
$3368 – INC $67 – animation of photon charge
$338C – Read low/hi bytes, LDA #<$010B, LDA #>$010B
$3461 – Hardware Reset, $FFFC
$346D – INC $5B – position of bat’s movement
$34EE – INC $59 – animation frames of bat, INC $00 – increases mass of player
$3517 – JSR $352E
$351E – INC $1F – adds gravity to player. player can fall further down, set to INC $00
$352A – JSR $352E
$3543 – Hardware Reset, $FFFC
$357B – JSR $33EE
$3587 – JSR $3597
$358D – DEC $21 – increases rock wall fragments around the screen
$358F – DEC $42 – unknown
$3681 – CIA1 Data Port Register B, $DC01
$368A – CIA1 Data Port Register A, $DC00
$3691 – CIA1 Data Port Register B, $DC01
$3694 – CIA1 Data Port Register B, $DC01
$36AB – CIA1 Data Port Register A, $DC00
$36B4 – CIA1 Data Port Register A, $DC00
$36EE – DEC $64 – scrolling register. If set to INC $64, the screen bounces
$36F8 – when player scrolls off the screen, he is thrown quickly to the right
$3702 – INY
$3703 – INY
$3695 – INY
$3710 – INX
$3711 – INX
$3713 – INX
$3725 – DEY
$3726 – DEY
$3728 – DEY
$3733 – DEX
$3734 – DEX
$3735 – DEX
$3736 – DEX
$374A – JSR $37DD
$374D – JSR $38E8
$3761 – JSR $37DD
$3764 – JSR $38E8
$3788 – JSR $37DD
$3797 – JSR $3878
$37A2 – JSR $37DD
$37C9 – JSR $37DD
$37D7 – JSR $37DD
$3A53 – SBC #$08
$3A6D – DEC $3C – UNKNOWN
$3A6F – DEC $3B
$3ADB – DEC $A2 – crashed when changed to INC $A2
$3AE8 – DEC $A2 – display lives on screen. INC $A2 increases the number shown
$3530 – DEC $C7 – flare falls after player dies
$3BDF – CIA1 Data Port Register B
$3BEB – CIA1 Data Port Register A, $Dc00
$3BEE – CIA1 Data Port Register B, $DC01
$3BF7 – CIA1 Data Port Register A, $DC00

****** DYNAMITE ******

$3F4F – DEC $34 – player sets a dynamite charge
$3F8A – DEC $9F – unknown
$3FA4 – DEC $9F – unknown
$3FF9 – DEC $3D – unknown
$4002 – JSR $4046
$4014 – DEC $3D
$401A – JSR $4046
$4014 – DEC $3D
$4020 – DEC $4E – moved the ghost closer after it spawns
$403F – DEC $6A – unknown
$4046 – JSR $33EE
$4074 – JSR $33EE
$407D – DEC $D022 – Background Color 1, Multi-Color Register 0
$4088 – DEC $46 – Color cycling
$40CC – Read low/hi bytes, LDA #<$4146, LDA #>$4146
$40D8 – VIC Control Register 1, $D011
$40DD – VIC Memory Control Register 2, $D016
$40E2 – VIC Control Register 2, $D016
$40E7 – Select Filter Mode and Volume, $D418
$40EA – Sprite display Enable
$40FA – JSR $4103
$40FD – JSR $4136
$4146 – VIC Interrupt Request Register (IRR), $D019
$4149 – VIC Interrupt Request Register (IRR), $D019
$4109 – INC $A2 – increase player lives display on screen
$437A – DEC $15 – Joystick up movement of player
$4397 – DEC $14 – Joystick left movement of player
$43AE – INC $15 – player’s falling motion.
$43C4 – DEC $15 – changing to DEC $15 sent player through the floor then he dies.
$446C – DEC $97 – unknown
$4487 – JSR $452E
$44AB – JSR $452E
$44C9 – JSR $4B7A
$44EC – JSR $4B7A
$453D – DEC $15 – unknown
$4553 – DEC $14 – unknown
$455F – JSR $45DD
$4597 – DEC $14 – Changing to INC $9A makes Spelunker bounce all over the place.
$45B8 – DEC $9A – Speeds up jumping to the right
$4665 – DEC $4C – if changed to INC $4C player falls, but no flashing occurs on death
$4669 – DEC $4B – speeds up time when ghost appears
$467D – Sprite 0 Color, $D027
$4682 – Sprite Multi-Color Register 1
$468D – Sprite Multi-Color Register 0
$46CD – JSR $47AF
$46D6 – JSr $47AF
$4718 – JSR $452E
$471D – JSR $452E
$4720 – JSR $4B7A
$474A – JSR $4B7A
$47AF – Oscillator 3 Output, $D41B
$47D5 – DEC $08 – unknown
$47E1 – DEC $3F – unknown
$48B1 – DEC $9B, X – changing to INC $9B,X speeds up player
$48E3 – DEC $3D – unknown
$48EC – DEC $3E – unknown
$4917 – DEC $9F – unknown
$4988 – DEC $08 – unknown
$498A – DEC $08 – unknown
$499A – DEC $96 – unknown

**** LIFE COUNTER *****

$4AB5 – DEC $40 – life counter for player (LIFE COUNTER)

$49B7 – SBC $14
$49FB – Sprite to Background Collision Detect, $D01F
$4A04 – JSR $4BA0
$4A07 – Sprite to Sprite Collision Detect, $D01E
$4A2C – JSR $4A80
$4A37 – JSR $352E
$4A42 – JSR $352E
$4A49 – JSR $4A80
$4A52 – JSR $4A80
$4A8E – JSR $35C8
$4A91 – JSR $33EE
$4A96 – JSR $352E
$4A9B – JSR $352E
$4A9E – JSR $4B27
$4AA9 – Read low/hi bytes, LDA #<$010C, LDA #>$010C
$4AB5 – DEC $40
$4AC9 – DEC $4ADA
$4ACE – DEC $4ADA
$4AD1 – DEC $04ADB
$4AE6 – JSR $4B09
$4AE9 – JSR $330E
$4AF4 – Read low/hi bytes, LDA #<$14FF, LDA #>$14FF
$4B00 – Select Filter Mode and Volume, $D418
$4B11 – Sprite 0 Color
$4B16 – Sprite Multi-Color Register 0
$4B1B – Sprite Multi-Color Register 1
$4B3E – DEC $80 – after your player dies, he is stuck in death mode, but can move around and not jump

$4B77 – DEC $66 – unknown
$4C0B – Voice 1 Frequency Control – Low Byte, $D400
$4C1F – Select Filter Mode and Volume, $D418
$4C24 – Voice 1 Pulse Waveform Width – High Nybble
$4C27 – Voice 2 Pulse Waveform Width – High Nybble
$4C2A – Voice 3 Pulse Waveform Width – High Nybble
$4C2F – Voice 1 Sustain / Release Cycle Control
$4C32 – Voice 2 Sustain / Release Cycle Control
$4C35 – Voice 3 Sustain / Release Cycle Control
$4C47 – JSR $4D65
$4C54 – JSR $4CD4
$4C61 – JSR $4DE9
$4C96 – Voice 1 Frequency Control – Low Byte
$4C9E – Voice 1 Control Register
$4CB8 – Voice 1 Frequency Control – High Byte
$4CCD – Voice 1 Control Register
$4CF4 – DEC $AB
$4CFC – JSR $4C6D
$4D29 – Voice 2 Frequency Control – Low Byte
$4D31 – Voice 2 Control Register
$4D4B – Voice 2 Frequency Control – High Byte
$4D5E – Voice 2 Control Register
$4D85 – DEC $AC
$4D8D – JSr $4D00
$4DA3 – Voice 3 Frequency Control – Low Byte
$4DBE – Select Filter Mode and Volume
$4DCA – Voice 3 Frequency Control – High Byte
$4DDD – Voice 3 Control Register
$4DE5 – Select Filter Mode and Volume
$4E09 – DEC $AD
$4E11 – JSR $4D91
$53AA – JSR $2143

$53BF – ADC #$03

$53EE – ADC #$01 – Design for “ENTERING THE ELEVATOR”
$541D – JSR $551F

$5449 – JSR $5541
$544C – JSR $4B27
$544F – JSR $4B09
$5452 – JSR $54B9
$5457 – JSR $3B6C
$548A – JSR $549A
$548F – JSR $551F
$5492 – INC $47
$5494 – INC $47
$5496 – JSR $4B7A