00001. ; Super Mario Bros. 3 Full Disassembly by Southbird 2012 
00002. ; For more info, see http://www.sonicepoch.com/sm3mix/ 
00003. ; 
00004. ; PLEASE INCLUDE A CREDIT TO THE SOUTHBIRD DISASSEMBLY 
00005. ; AND THE ABOVE LINK SOMEWHERE IN YOUR WORKS :) 
00006. ; 
00007. ; Original disassembler source generated by DCC6502 version v1.4 
00008. ; (With labels, comments, and some syntax corrections for nesasm by Southbird) 
00009. ; For more info about DCC6502, e-mail veilleux@ameth.org 
00010. ; 
00011. ; This source file last updated: 2012-06-03 20:09:21.000000000 -0500 
00012. ; Distribution package date: Sun Jun 10 18:21:30 UTC 2012 
00013. ;--------------------------------------------------------------------------- 
00014. ; STANDARD HORIZONTAL SCREEN 
00015.  
00016. Tile_Mem_Addr:  
00017. ; This breaks up the overall "tile" layout memory into screen-based chunks 
00018. ; With a screen width of 256 pixels, that makes 16 blocks across every "screen", 
00019. ; NTSC res of 224, two screens tall, is 448 / 16px-per-tile = 28 POTENTIAL rows per screen 
00020. ; but the status bar occludes one, so only 27 rows are stored...  
00021. ; Up to 15 screens! 
00022. .word Tile_Mem, Tile_Mem+$01B0, Tile_Mem+$0360, Tile_Mem+$0510, Tile_Mem+$06C0, Tile_Mem+$0870, Tile_Mem+$0A20, Tile_Mem+$0BD0 
00023. .word Tile_Mem+$0D80, Tile_Mem+$0F30, Tile_Mem+$10E0, Tile_Mem+$1290, Tile_Mem+$1440, Tile_Mem+$15F0, Tile_Mem+$17A0 
00024.  
00025.  
00026. ; ALTERNATE VERTICAL SCREEN 
00027.  
00028. ; Each "screen" (stacked vertically) is made up of 15 rows of tiles 
00029. ; which amounts to $F0 bytes per screen; the following split LUT defines tile memory 
00030. ; offsets gapped by $F0... not sure why they had to make the address lookup into two LUTs 
00031. ; like they did, but whatever... 16 vertical screens available 
00032.  
00033. ; High bytes are separate from low 
00034. Tile_MemH = HIGH(Tile_Mem) 
00035.  
00036. ; Vertical low byte, per screen 
00037. Tile_Mem_AddrVL: 
00038. .byte $00, $F0, $E0, $D0, $C0, $B0, $A0, $90, $80, $70, $60, $50, $40, $30, $20, $10 
00039.  
00040. ; Vertical high byte, per screen 
00041. Tile_Mem_AddrVH: 
00042. .byte Tile_MemH+$0, Tile_MemH+$0, Tile_MemH+$1, Tile_MemH+$2 
00043. .byte Tile_MemH+$3, Tile_MemH+$4, Tile_MemH+$5, Tile_MemH+$6 
00044. .byte Tile_MemH+$7, Tile_MemH+$8, Tile_MemH+$9, Tile_MemH+$A 
00045. .byte Tile_MemH+$B, Tile_MemH+$C, Tile_MemH+$D, Tile_MemH+$E 
00046.  
00047.  
00048.  
00049. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
00050. ; This table contains commands for Video_Misc_Updates which tells 
00051. ; it how to generate certain graphical elements programatically 
00052. ; 
00053. ; Format: 
00054. ; [2B TVA][CMD][DATA] 
00055. ; TVA: Target Video Address, typ. inside the nametable somewhere 
00056. ; CMD: - Bit 7 set = Use vertical updates (32B) else use horizontal (1B) 
00057. ; - Bit 6 set = Means that there is only one byte of DATA, repeated 
00058. ; - Bits 0-5 = Count of bytes to write directly to PPU  
00059. ; DATA: Raw byte(s) to write to the PPU, count specified by CMD 
00060. ; After a data chunk has been read, a new TVA is expected, or a $00 byte which terminates the stream. 
00061. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
00062. ; Remember that the left edge is typically clipped, so nothing is visible there... 
00063. Video_Upd_Table: ; $803E 
00064. .word Graphics_Buffer ; $00 - Graphics buffer for dynamically generated content 
00065. .word Video_DoStatusBarV; $01 - status bar (vertical level) 
00066. .word Video_DoStatusBar ; $02 - status bar (typical) 
00067. .word $A000 ; $03 - ??? 
00068. .word $A06F ; $04 - ??? 
00069. .word Video_DoStatusBarHM; $05 - status bar appropriate for horizontal mirroring 
00070. .word Video_DoPalUpd ; $06 - Updates palettes per values in the $07BE+ Palette_* vars; used during fade in/out routines 
00071. .word Video_RoulBordAttr; $07 - Roulette sliders border and attribute settings 
00072. .word Bonus_InstBoxTop ; $08 - Top of Bonus Game instruction box 
00073. .word Bonus_InstBoxLine1; $09 - First line of Bonus Game instruction box 
00074. .word Bonus_InstBoxLine2; $0A - Second line of Bonus Game instruction box 
00075. .word Bonus_InstBoxLine3; $0B - Third line of Bonus Game instruction box 
00076. .word Bonus_InstBoxBot ; $0C - Bottom of Bonus Game instruction box 
00077. .word Video_NSpadeBG ; $0D - N-Spade candy striping background 
00078. .word Video_DoWXMario00 ; $0E - "World X" Intro, Mario (horizontal scroll at $00) 
00079. .word Video_DoWXLuigi00 ; $0F - "World X" Intro, Luigi (horizontal scroll at $00) 
00080. .word Video_DoWXMario80 ; $10 - "World X" Intro, Mario (horizontal scroll at $80) 
00081. .word Video_DoWXLuigi80 ; $11 - "World X" Intro, Luigi (horizontal scroll at $80) 
00082. .word Video_DoGameOver00; $12 - "GAME OVER" Box (horizontal scroll at $00) 
00083. .word Video_DoGameOver80; $13 - "GAME OVER" Box (horizontal scroll at $80) 
00084. .word Video_Blackout ; $14 - Blacks out 3 colors, used during end-level triple card match; not sure what for? 
00085. .word Video_3CMMushTop ; $15 - End Level Triple Card Match: Mushroom top 
00086. .word Video_3CMFlowTop ; $16 - End Level Triple Card Match: Flower top 
00087. .word Video_3CMStarTop ; $17 - End Level Triple Card Match: Star top 
00088. .word Video_3CMMushLeft ; $18 - End Level Triple Card Match: Mushroom left spot 
00089. .word Video_3CMFlowDiag ; $19 - End Level Triple Card Match: Flower inner diagonal 
00090. .word Video_3CMStarTip ; $1A - End Level Triple Card Match: Star eyes and tips 
00091. .word Video_3CMMushMid ; $1B - End Level Triple Card Match: Mushroom eyes and middle 
00092. .word Video_3CMFlowMid ; $1C - End Level Triple Card Match: Flower middle 
00093. .word Video_3CMStarSide ; $1D - End Level Triple Card Match: Star left/right sides 
00094. .word Video_3CMMushRight; $1E - End Level Triple Card Match: Mushroom right spot 
00095. .word Video_3CMFlowStem ; $1F - End Level Triple Card Match: Flower stem 
00096. .word Video_3CMStarBot1 ; $20 - End Level Triple Card Match: Star near bottom 
00097. .word Video_3CMMushBot ; $21 - End Level Triple Card Match: Mushroom bottom 
00098. .word Video_3CMFlowBot ; $22 - End Level Triple Card Match: Flower bottom 
00099. .word Video_3CMStarBot2 ; $23 - End Level Triple Card Match: Star bottom 
00100. .word Video_3CMAppear1 ; $24 - End Level Triple Card Match: Make big shape appear attribute change 1 
00101. .word Video_3CMAppear2 ; $25 - End Level Triple Card Match: Alters palette 
00102. .word Video_3CMAppear3 ; $26 - End Level Triple Card Match: Make big shape appear attribute change 2 
00103. .word Video_3CMAppear4 ; $27 - End Level Triple Card Match: Make big shape appear attribute change 3 
00104. .word Video_3CMAppear5 ; $28 - End Level Triple Card Match: Make big shape appear attribute change 4 
00105. .word Video_3CMAppear6 ; $29 - End Level Triple Card Match: Make big shape appear attribute change 5 
00106. .word Video_3CMAppear7 ; $2A - End Level Triple Card Match: Make big shape appear attribute change 6 
00107. .word Video_DoW2WZ ; $2B - "WELCOME TO WARP ZONE" banner 
00108. .word Video_YouGotCardH ; $2C - "YOU GOT A CARD" (and the card space) [for the End Level Triple Card Match] 
00109. .word Video_CourseClear ; $2D - "COURSE CLEAR" 
00110. .word Video_YouGotCard ; $2E - "YOU GOT A CARD" (and the card space) [for the End Level otherwise] 
00111.  
00112. ; The status bar comes in three identical versions with different VRAM start addresses 
00113. ; Might as well make a macro out of that, eh? 
00114.  
00115. ; NOTE!! If you want to edit the status bar, you should also sync up 
00116. ; with the "flip" data in PRG026 as noted below... 
00117. StatusBar .macro 
00118.  
00119. ; Sync next three with PRG026 Flip_TopBarCards 
00120. vaddr \1 + $00 
00121. .byte $02, $FC, $A0 ; Upper left corner 
00122.  
00123. vaddr \1 + $02 
00124. .byte VU_REPEAT | $12, $A1 ; Bar across the top 
00125.  
00126. vaddr \1 + $14 
00127. .byte $0C, $A2, $A0, $A1, $A1, $A3, $A1, $A1, $A3, $A1, $A1, $A2, $FC ; top of card slots 
00128.  
00129. ; Sync this with PRG026 Flip_MidTStatCards 
00130. vaddr \1 + $20 
00131. .byte $20, $FC, $A6, $70, $71, $72, $73, $FE, $FE, $EF, $EF, $EF, $EF, $EF, $EF, $3C ; |WORLD >>>>>>[P] $ | | | | | | | | 
00132. .byte $3D, $FE, $EC, $F0, $F0, $A7, $A6, $FE, $FE, $AA, $FE, $FE, $AA, $FE, $FE, $A7, $FC 
00133. ; Discrepency --------^ (Pattern is ... $FE, $F0 ... in PRG026 status bar graphics) 
00134.  
00135. ; Sync this with PRG026 Flip_MidBStatCards 
00136. vaddr \1 + $40 
00137. ; Discrepency --------v (Pattern is ... $FE, $FE ... in PRG030 status bar) Unimportant; inserts <M> which is replaced anyway 
00138. .byte $20, $FC, $A6, $FE, $FE, $FB, $FE, $F3, $FE, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; [M/L]x 000000 c000| etc. 
00139. .byte $FE, $ED, $F4, $F0, $F0, $A7, $A6, $FE, $FE, $AA, $FE, $FE, $AA, $FE, $FE, $A7, $FC 
00140. ; Discrepency --------^ (Pattern is ... $F4, $F0 ... in PRG030 status bar graphics) 
00141.  
00142. ; Sync next three with PRG026 Flip_BottomBarCards 
00143. vaddr \1 + $60 
00144. .byte $02, $FC, $A8 ; Lower corner 
00145.  
00146. vaddr \1 + $62 
00147. .byte VU_REPEAT | $12, $A4 ; Bottom bar 
00148.  
00149. vaddr \1 + $74 
00150. .byte $0C, $A5, $A8, $A4, $A4, $A9, $A4, $A4, $A9, $A4, $A4, $A5, $FC ; lower corner and card bottoms 
00151.  
00152. ; End PRG026 sync 
00153.  
00154. vaddr \1 + $80 
00155. .byte VU_REPEAT | $20, $FC ; black space 
00156.  
00157. vaddr \1 + $A0 
00158. .byte VU_REPEAT | $20, $FC ; black space 
00159.  
00160. ; Terminator 
00161. .byte $00 
00162. .endm 
00163.  
00164. ; Typical status bar (vertical level) 
00165. Video_DoStatusBarV: 
00166. StatusBar $2700 
00167.  
00168. ; Typical status bar (non-vertical level) 
00169. Video_DoStatusBar: 
00170. StatusBar $2B00 
00171.  
00172. ; Status bar used when Horizontal Mirroring in effect (Roulette game) 
00173. Video_DoStatusBarHM: 
00174. StatusBar $2300 
00175.  
00176. Video_3CMStarTop: 
00177. vaddr $208F 
00178. .byte VU_REPEAT | $02, $A9 
00179. vaddr $20AE 
00180. .byte VU_VERT | VU_REPEAT | $02, $A9 
00181. vaddr $20B1 
00182. .byte VU_VERT | VU_REPEAT | $02, $A9 
00183. vaddr $20ED 
00184. .byte $01, $A9 
00185. vaddr $20F2 
00186. .byte $01, $A9 
00187. vaddr $2108 
00188. .byte VU_REPEAT | $06, $A9 
00189. vaddr $2112 
00190. .byte VU_REPEAT | $06, $A9 
00191. .byte $00 ; Terminator 
00192.  
00193. Video_3CMStarTip: 
00194. vaddr $2128 
00195. .byte $01, $A9 
00196. vaddr $2137 
00197. .byte $01, $A9 
00198. vaddr $2149 
00199. .byte $01, $A9 
00200. vaddr $214E 
00201. .byte VU_VERT | VU_REPEAT | $03, $A9 
00202. vaddr $2151 
00203. .byte VU_VERT | VU_REPEAT | $03, $A9 
00204. vaddr $2156 
00205. .byte $01, $A9 
00206. .byte $00 ; Terminator 
00207.  
00208. Video_3CMStarSide: 
00209. vaddr $216A 
00210. .byte $01, $A9 
00211. vaddr $2175 
00212. .byte $01, $A9 
00213. vaddr $218B 
00214. .byte VU_VERT | VU_REPEAT | $02, $A9 
00215. vaddr $2194 
00216. .byte VU_VERT | VU_REPEAT | $02, $A9 
00217. vaddr $21CA 
00218. .byte VU_VERT | VU_REPEAT | $02, $A9 
00219. vaddr $21D5 
00220. .byte VU_VERT | VU_REPEAT | $02, $A9 
00221. .byte $00 ; Terminator 
00222.  
00223. Video_3CMStarBot1: 
00224. vaddr $2209 
00225. .byte VU_VERT | VU_REPEAT | $02, $A9 
00226. vaddr $220F 
00227. .byte VU_REPEAT | $42, $A9 
00228. vaddr $2216 
00229. .byte VU_VERT | VU_REPEAT | $02, $A9 
00230. vaddr $222D 
00231. .byte VU_REPEAT | $02, $A9 
00232. vaddr $2231 
00233. .byte VU_REPEAT | $02, $A9 
00234. .byte $00 ; Terminator 
00235.  
00236. Video_3CMStarBot2: 
00237. vaddr $2248 
00238. .byte $05, $A9, $FC, $FC, $A9, $A9 
00239. vaddr $2253 
00240. .byte $05, $A9, $A9, $FC, $FC, $A9 
00241. vaddr $2268 
00242. .byte VU_REPEAT | $03, $A9 
00243. vaddr $2275 
00244. .byte VU_REPEAT | $03, $A9 
00245. .byte $00 ; Terminator 
00246.  
00247. Video_3CMAppear1: 
00248. vaddr $23CA 
00249. .byte VU_REPEAT | $04, $FF 
00250. vaddr $23D2 
00251. .byte VU_REPEAT | $04, $FF 
00252. vaddr $23DA 
00253. .byte VU_REPEAT | $04, $FF 
00254. vaddr $23E2 
00255. .byte VU_REPEAT | $04, $FF 
00256. .byte $00 ; Terminator 
00257.  
00258. Video_3CMAppear3: 
00259. vaddr $23D3 
00260. .byte $02, $BF, $EF 
00261. vaddr $23DB 
00262. .byte $02, $FB, $FE 
00263. .byte $00 ; Terminator 
00264.  
00265. Video_3CMAppear4: 
00266. vaddr $23D3 
00267. .byte $02, $6A, $9A 
00268. vaddr $23DB 
00269. .byte $02, $A6, $A9 
00270. .byte $00 ; Terminator 
00271.  
00272. Video_3CMAppear5: 
00273. vaddr $23CA 
00274. .byte $04, $BF, $AF, $AF, $EF 
00275. vaddr $23D2 
00276. .byte $04, $BB, $55, $55, $EE 
00277. vaddr $23DA 
00278. .byte $04, $BB, $55, $55, $EE 
00279. vaddr $23E2 
00280. .byte $04, $FB, $FA, $FA, $FE 
00281. .byte $00 ; Terminator 
00282.  
00283. Video_3CMAppear6: 
00284. vaddr $23CA 
00285. .byte $04, $7F, $5F, $5F, $DF 
00286. vaddr $23D2 
00287. .byte $04, $77, $55, $55, $DD 
00288. vaddr $23DA 
00289. .byte $04, $77, $55, $55, $DD 
00290. vaddr $23E2 
00291. .byte $04, $F7, $F5, $F5, $FD 
00292. .byte $00 ; Terminator 
00293.  
00294. Video_3CMAppear7: 
00295. vaddr $23CA 
00296. .byte VU_REPEAT | $04, $55 
00297. vaddr $23D2 
00298. .byte VU_REPEAT | $04, $55 
00299. vaddr $23DA 
00300. .byte VU_REPEAT | $04, $55 
00301. vaddr $23E2 
00302. .byte VU_REPEAT | $04, $55 
00303. .byte $00 ; Terminator 
00304.  
00305. ; Blacks out a little bit of the palette during end level triple-card match sequecnce 
00306. Video_Blackout: 
00307. vaddr $3F0D 
00308. .byte VU_REPEAT | $03, $0F, $00 
00309.  
00310.  
00311. Video_3CMAppear2: 
00312. vaddr $3F05 
00313. .byte $03 
00314.  
00315. EndLevelCard_PalData: 
00316. .byte $0F, $30, $3C 
00317. vaddr $3F09 
00318. .byte $03, $0F, $10, $2C 
00319. vaddr $3F0D 
00320. .byte VU_REPEAT | $03, $0F 
00321. .byte $00 ; Terminator 
00322.  
00323. Video_YouGotCardH: 
00324. vaddr $22C7 
00325. .byte $13 
00326. ; Y O U G O T A C A R D | | 
00327. .byte $0D, $0E, $0A, $FC, $06, $0E, $09, $FC, $00, $FC, $05, $00, $02, $07, $FC, $26, $FE, $FE, $27 
00328. vaddr $22B6 
00329. .byte $04 ; _ _ _ _ 
00330. ; | | 
00331. .byte $20, $21, $21, $22 
00332.  
00333. vaddr $22F6 
00334. .byte $04 
00335. ; | | 
00336. .byte $26, $FE, $FE, $27 
00337.  
00338. vaddr $2316 
00339. .byte $04 
00340. ; |_ _ _ _| 
00341. .byte $28, $24, $24, $25 
00342.  
00343. .byte $00 ; Terminator 
00344.  
00345. Video_CourseClear: 
00346. vaddr $2889 
00347. .byte $0E 
00348. ; C O U R S E C L E A R ! 
00349. .byte $85, $8E, $8A, $82, $83, $84, $FC, $85, $8B, $84, $80, $82, $FC, $9B, $00 
00350.  
00351. Video_YouGotCard: 
00352. vaddr $28E7 
00353. .byte $13 
00354. ; Y O U G O T A C A R D | | 
00355. .byte $8D, $8E, $8A, $FC, $86, $8E, $89, $FC, $80, $FC, $85, $80, $82, $87, $FC, $A6, $FE, $FE, $A7 
00356.  
00357. vaddr $28D6 
00358. .byte $04 ; _ _ _ _ 
00359. ; | | 
00360. .byte $A0, $A1, $A1, $A2 
00361.  
00362. vaddr $2916 
00363. .byte $04 
00364. ; | | 
00365. .byte $A6, $FE, $FE, $A7 
00366.  
00367. vaddr $2936 
00368. .byte $04 
00369. ; |_ _ _ _| 
00370. .byte $A8, $A4, $A4, $A5 
00371. .byte $00 ; Terminator 
00372.  
00373. .byte $AF, $11 
00374.  
00375. Map_Y_Starts: 
00376. ; Map Y start positions, World 1-8 (X is always $20) 
00377. .byte $40, $A0, $A0, $40, $80, $60, $30, $50 
00378.  
00379. ; A clear pattern set by Level_Tileset (for use with Clear_Nametable_Short) 
00380. ClearPattern_ByTileset: 
00381. .byte $FF ; 0 - Map 
00382. .byte $FC ; 1 - Plains 
00383. .byte $FF ; 2 - Mini fortress style 
00384. .byte $FC ; 3 - Hills style 
00385. .byte $FC ; 4 - High-Up style 
00386. .byte $FC ; 5 - pipe world plant infestation 
00387. .byte $FC ; 6 - Water world 
00388. .byte $FF ; 7 - Toad house 
00389. .byte $FF ; 8 - Vertical pipe maze 
00390. .byte $FC ; 9 - desert level 
00391. .byte $FC ; 10 - airship 
00392. .byte $FC ; 11 - Giant World 
00393. .byte $FC ; 12 - ice level 
00394. .byte $FC ; 13 - coin heaven / sky level 
00395. .byte $FC ; 14 - underground 
00396. .byte $FF ; 15 - bonus game intro 
00397. .byte $FF ; 16 - spade game sliders 
00398. .byte $FF ; 17 - N-spade 
00399. .byte $FC ; 18 - 2P Vs 
00400.  
00401.  
00402. .byte $AB, $83, $C6, $83, $CD, $83 
00403.  
00404. ; This single byte is used in plant infestation levels to load the animation counter 
00405. PlantInfest_ACnt_MaxConst: .byte (PlantInfest_PTPAC_End - PlantInfest_PatTablePerACnt - 1) 
00406. PlantInfest_PatTablePerACnt: 
00407. .byte $60, $60, $60, $60, $60, $60, $60, $60, $60, $60, $62, $64, $66, $3E, $3E, $3E 
00408. .byte $3E, $3E, $3E, $3E, $3E, $3E, $3E, $66, $64, $62, $06 
00409. PlantInfest_PTPAC_End 
00410.  
00411. .byte $34, $36, $38, $3A, $3C 
00412. .byte $3E, $08, $34, $36, $38, $36, $34, $3A, $3E, $3A 
00413.  
00414. ; List of C000 pages to switch to by Level_Tileset 
00415. PAGE_C000_ByTileset: ; $83D6 
00416. .byte 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 22, 22, 22, 14 
00417.  
00418. ; List of A000 pages to switch to by Level_Tileset 
00419. PAGE_A000_ByTileset: ; $83E9 
00420. .byte 11, 15, 21, 16, 17, 19, 18, 18, 18, 20, 23, 19, 17, 19, 13, 26, 26, 26, 9 
00421.  
00422. ; The normal level VROM page cycle set 
00423. PT2_Anim: .byte $60, $62, $64, $66 
00424.  
00425. PAUSE_Sprites: 
00426. .byte $58, $F1, $03, $60 ; P 
00427. .byte $58, $F5, $03, $70 ; A 
00428. .byte $58, $F9, $03, $80 ; U 
00429. .byte $58, $FD, $03, $90 ; S 
00430. .byte $58, $FF, $03, $A0 ; E 
00431. PAUSE_Sprites_End 
00432.  
00433. ; The BGM per world (see also World_BGM_Restore in PRG010) 
00434. World_BGM:  
00435. .byte MUS2A_WORLD1, MUS2A_WORLD2, MUS2A_WORLD3, MUS2A_WORLD4 
00436. .byte MUS2A_WORLD5, MUS2A_WORLD6, MUS2A_WORLD7, MUS2A_WORLD8 
00437. .byte MUS2A_WARPWHISTLE 
00438.  
00439. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
00440. ; IntReset_Part2 
00441. ; 
00442. ; Part 2 of the Reset routine... 
00443. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
00444. IntReset_Part2: 
00445. LDA PPU_STAT ; 
00446. BPL IntReset_Part2 ; Wait until VBlank 
00447. LDA #$00 ;  
00448. STA PPU_CTL2 ; Most importantly, hide sprites/bg 
00449. STA PPU_CTL1 ; Most likely just to disable further Resets 
00450.  
00451. ; Map_Unused7992 = 0 (used only in dead code it seems) 
00452. LDA #$00 
00453. STA Map_Unused7992 
00454.  
00455. ; Note: This is setting up the address $7F00 @ $00/$01, the last page of SRAM 
00456. LDY #$00 ; Y = $00 
00457. STY <Temp_Var1 ; <Temp_Var1 = $00 
00458. LDA #$7f ; A = $7F 
00459. STA <Temp_Var2 ; <Temp_Var2 = $7F 
00460.  
00461. ; The following loop clears all of $6000 - $7FFF ... a lot of RAM! 
00462. PRG030_8437: 
00463. LDA #$00 ; A = 0 
00464. STA [Temp_Var1],Y ; Clear  
00465. DEY ; Y-- 
00466. BNE PRG030_8437 ; While Y is not zero, loop (since Y started at 0, this does a full 256 bytes) 
00467.  
00468. ; This decrement then moves to $7E, $7D ... $60 
00469. DEC <Temp_Var2 ; Next lower page 
00470. LDA <Temp_Var2 ; Get page -> A 
00471. CMP #$5f ;  
00472. BNE PRG030_8437 ; If A <> $5F, loop again (clears down to $6000) 
00473.  
00474. ; Clear $07FF - $0000, excluding $01xx 
00475. LDY #$07 
00476. JSR Clear_RAM_thru_ZeroPage 
00477.  
00478. ; Reset_Latch = $5A (magic value that prevents reset vector from being run) 
00479. LDA #$5a 
00480. STA Reset_Latch 
00481.  
00482. ; N-Spade appears every 80,000 points, but the leading zero is fake, so 8000 
00483.  
00484. ; Middle byte of the N-Spade score 
00485. LDA #HIGH(8000) 
00486. STA Map_NSpade_NextScore+1 
00487.  
00488. ; Lowest byte of the N-Spade score 
00489. LDA #LOW(8000) 
00490. STA Map_NSpade_NextScore+2 
00491.  
00492. PRG030_845A: 
00493. JSR Sprite_RAM_Clear  
00494. JSR Scroll_PPU_Reset  
00495. JSR Reset_PPU_Clear_Nametables 
00496.  
00497. ; Load title screen graphics 
00498. LDA #$78 
00499. STA PatTable_BankSel 
00500. LDA #$7a  
00501. STA PatTable_BankSel+1 
00502. LDA #$20  
00503. STA PatTable_BankSel+2 
00504. LDA #$21  
00505. STA PatTable_BankSel+3 
00506. LDA #$04  
00507. STA PatTable_BankSel+4 
00508. LDA #$7f  
00509. STA PatTable_BankSel+5 
00510.  
00511. ; Load page 24 into A000 and page 25 into C000 
00512. LDA #24  
00513. STA PAGE_A000 
00514. LDA #25  
00515. STA PAGE_C000 
00516. JSR PRGROM_Change_Both2  
00517.  
00518. LDA #$20 
00519. STA Update_Select ; Update_Select = $20 (Title Screen) 
00520. STA Raster_Effect ; Raster_Effect = $20 (Title Screen style) 
00521.  
00522. LDA #%10101000 
00523. STA PPU_CTL1 ; Generate VBlank Resets, use 8x16 sprites, sprites use PT2 
00524. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync! 
00525.  
00526. JSR Do_Title_Screen ; Do the title screen! 
00527.  
00528. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
00529. ; BEGINNING INITIALIZATION OF WORLD MAP! 
00530. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
00531. PRG030_84A0: 
00532.  
00533. ; Load page 11 into A000 and page 10 into C000 
00534. LDA #10 
00535. STA PAGE_C000 
00536. LDA #11 
00537. STA PAGE_A000 
00538. JSR PRGROM_Change_Both2  
00539.  
00540.  
00541. JSR Map_Init ; Initialize map variables (page 11) 
00542.  
00543. LDA #$00 
00544. STA Map_Operation ; Map_Operation = 0 ("World X" intro) 
00545. STA BigQBlock_GotIt ; Clear the opened Big ? Block variable 
00546. STA Map_Airship_Dest ; Map_Airship_Dest = 0 
00547. STA Map_Got13Warp ; Clear the "Got 1-3 Warp Whistle" flag 
00548. STA Map_Anchored ; Map_Anchored = 0 (not anchored yet) 
00549.  
00550. ; Map_UnusedGOFlag = $F8? 
00551. LDA #$f8 
00552. STA <Map_UnusedGOFlag 
00553.  
00554. LDA #$00 ;  
00555. STA PPU_CTL2 ; Most importantly, hide sprites/bg 
00556.  
00557. ; Stop Update_Select activity temporarily while we initialize 
00558. INC UpdSel_Disable 
00559.  
00560. ; The following clears Map_Completions (stores completed levels on the map) 
00561. LDY #$7f ; Y = $7F 
00562. LDA #$00 ; A = $00 
00563. PRG030_84D1: 
00564. STA Map_Completions,Y 
00565. DEY ; Y-- 
00566. BPL PRG030_84D1 ; While Y >= 0, loop! 
00567.  
00568. PRG030_84D7: 
00569. JSR Sprite_RAM_Clear  
00570. JSR Scroll_PPU_Reset  
00571. JSR Reset_PPU_Clear_Nametables 
00572.  
00573. ; Init for lost bonus game?? 
00574. LDA #$2b 
00575. STA Bonus_UnusedVH 
00576. LDA #$35 
00577. STA Bonus_UnusedVL 
00578.  
00579. LDA #$00 
00580. STA Level_Tileset ; Level_Tileset = 0 
00581. STA Map_Unused72C ; Map_Unused72C = 0 
00582. STA Map_March_Count ; Not sure about this 
00583. STA Raster_Effect ; Raster Effects disabled 
00584. STA UpdSel_Disable ; Stop Update_Select activity 
00585. STA Vert_Scroll_Off ; Vert_Scroll_Off = 0 
00586.  
00587. ; Init for lost bonus game?? 
00588. LDA #$04 
00589. STA BonusText_CharPause 
00590. STA Bonus_DieCnt 
00591.  
00592. ; Reload the timer tick for the next time it's used 
00593. LDA #$28  
00594. STA Level_TimerTick 
00595.  
00596. ; Unused699 = 3 (never used) 
00597. LDA #$03  
00598. STA Unused699 
00599.  
00600. ; Update_Select = $C0 
00601. LDA #$c0  
00602. STA Update_Select 
00603.  
00604. ; Load world map graphics 
00605. LDA #$14 
00606. STA PatTable_BankSel 
00607. LDA #$16 
00608. STA PatTable_BankSel+1 
00609. LDX #$20 
00610. STX PatTable_BankSel+2 
00611. INX 
00612. STX PatTable_BankSel+3 
00613. INX 
00614. STX PatTable_BankSel+4 
00615. INX 
00616. STX PatTable_BankSel+5 
00617.  
00618. ; Changes pages at A000 and C000 based on value Level_Tileset (0) 
00619. JSR SetPages_ByTileset ; A000 = Page 11, C000 = Page 10 
00620.  
00621. LDX Player_Current ; X = Player_Current 
00622. LDA #(Inventory_Score - Inventory_Items) ; Base offset to score from Inventory_Items 
00623. CPX #$00 ;  
00624. BEQ PRG030_853F ; If X = 0 (Player is Mario), jump to PRG030_853F 
00625. ADD #(Inventory_Score2 - Inventory_Score) ; Otherwise, add $23 
00626.  
00627. PRG030_853F: 
00628. TAY ; Y = $1F (Mario) or $42 (Luigi) 
00629.  
00630. ; Copies the 3 byte score of this Player to the status bar 
00631. ; loading area to display their score... 
00632. LDX #$00 ; X = 0 
00633. PRG030_8542: 
00634. LDA Inventory_Items,Y ; Starts at $1F or $42, score offset 
00635. STA Player_Score,X ; Store into buffer area.. 
00636. INY ; Y++ 
00637. INX ; X++ 
00638. CPX #$03  
00639. BNE PRG030_8542 ; While X <> 3, loop 
00640.  
00641.  
00642. ; Init Player's on map 
00643. LDX Total_Players 
00644. DEX ; X = Total_Players-1 
00645. PRG030_8552: 
00646. ; Set Player's Y position 
00647. LDA Map_Entered_Y,X 
00648. STA <World_Map_Y,X 
00649.  
00650. ; Set Player's X position 
00651. LDA Map_Entered_XHi,X 
00652. STA <World_Map_XHi,X 
00653. LDA Map_Entered_X,X 
00654. STA <World_Map_X,X 
00655.  
00656. LDA Map_Previous_UnusedPVal2,X 
00657. STA <Map_UnusedPlayerVal2,X 
00658.  
00659. ; Map_UnusedPlayerVal = $20 each Player (not used for anything) 
00660. LDA #$20 
00661. STA <Map_UnusedPlayerVal,X 
00662.  
00663. DEX ; X-- 
00664. BPL PRG030_8552 ; If more players to initialize, loop! 
00665.  
00666. LDA #$00  
00667. STA Level_Tileset ; Map uses Level_Tileset = 0 
00668. STA World_EnterState ; World_EnterState = 0 (just arriving) 
00669. STA <Map_EnterLevelFX ; Scratch = 0 
00670. STA <Map_Intro_CurStripe ; Start with the first "strip" of erasing the World X intro box 
00671. STA <Map_WarpWind_FX ; No warp whistle wind effects 
00672. STA Map_Intro_Tick ; Map_Intro_Tick = 0 (forces init in some functions) 
00673.  
00674. PRG030_857E: 
00675. JSR Sprite_RAM_Clear  
00676. JSR Scroll_PPU_Reset  
00677. JSR Reset_PPU_Clear_Nametables 
00678.  
00679. LDA #$01  
00680. STA MMC3_MIRROR ; Set vertical mirroring 
00681.  
00682. LDX Player_Current ; X = current Player index 
00683.  
00684. LDA World_Map_Power,X ; X = Player's current world map power 
00685. STA Map_Power_Disp ; Set as powerup currently displayed  
00686.  
00687. LDY #$00 ; "Darkness" flag (only works correctly on World 8 level 2) 
00688. LDA World_Num ; A = World_Num 
00689. CMP #$07  
00690. BNE PRG030_85A5 ; If this is NOT World 8, jump to PRG030_85A5 
00691.  
00692. ; We're in World 8... 
00693. LDA <World_Map_XHi,X 
00694. CMP #$02  
00695. BNE PRG030_85A5 ; If NOT on the third level of World 8, jump to PRG030_85A5 
00696. INY ; Activate darkness 
00697.  
00698. PRG030_85A5: 
00699. STY World_8_Dark ; Set the darkness flag 
00700.  
00701. ; Not sure what this assignment means here? 
00702. LDA #$00 
00703. STA Bonus_UnusedFlag 
00704.  
00705. ; Changes pages at A000 and C000 based on value Level_Tileset (0) 
00706. JSR SetPages_ByTileset ; A000 = Page 11, C000 = Page 10 
00707.  
00708. JSR Scroll_Map_SpriteBorder ; Draw sprite-based border on map 
00709.  
00710. ; Set A000 page to 12 
00711. LDA #12 
00712. STA PAGE_A000  
00713. JSR PRGROM_Change_A000 
00714.  
00715. JSR Map_Reload_with_Completions ; Load map and set already completed levels 
00716. JSR Fill_Tile_AttrTable_ByTileset ; Load tile attribute tiles by the tileset 
00717.  
00718. LDA Inventory_Open  
00719. BNE PRG012_85CE ; If Inventory is open, jump to PRG012_85CE 
00720.  
00721. ; If Inventory is not open 
00722. LDX Player_Current ; X = Player_Current 
00723.  
00724. LDA Map_Previous_Dir,X ; Get Player's previous moment direction 
00725. STA <World_Map_Dir,X ; Restore it 
00726.  
00727. PRG012_85CE: 
00728. LDA #%00101000 ; use 8x16 sprites, sprites use PT2 (NOTE: No VBlank trigger!) 
00729. STA PPU_CTL1 
00730. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync 
00731.  
00732. LDY Player_Current ; Y = current Player index 
00733.  
00734. ; This sets up the scroll correctly given wherever the Player last was on the map 
00735. LDA Map_Prev_XOff,Y  
00736. STA <Scroll_Temp ; Scroll_Temp = X offset 
00737. LDA Map_Prev_XHi,Y ; A = hi byte of X offset 
00738. JSR Scroll_Update_Ranges ; Off to Scroll_Update_Ranges... 
00739.  
00740. LDA #$00  
00741. STA <Scroll_LastDir ; Scroll_LastDir = 0 
00742.  
00743. LDA <Scroll_ColumnL  
00744. STA <Scroll_ColumnR ; Scroll_ColumnR = Scroll_ColumnL 
00745.  
00746. ; Scroll_Cols2Upd = 32 (full dirty scroll update sweep) 
00747. LDA #32 
00748. STA Scroll_Cols2Upd 
00749.  
00750. ; This (re)draws the status bar 
00751. LDA #$02 
00752. JSR Video_Do_Update 
00753.  
00754. ; Switch to page 26 @ A000 
00755. LDA #MMC3_8K_TO_PRG_A000 
00756. STA MMC3_COMMAND 
00757. LDA #26  
00758. STA MMC3_PAGE  
00759.  
00760. JSR StatusBar_Update_Cards ; Update status bar cards 
00761. JSR StatusBar_UpdateValues ; Update other status bar stuff 
00762. JSR StatusBar_Fill_MorL ; Patch in correct M or L on status bar 
00763. JSR StatusBar_Fill_World ; Fill in correct world number 
00764.  
00765. LDA #$00 ; Commit graphics in Graphics_Buffer 
00766. JSR Video_Do_Update ; Do it! 
00767.  
00768. JSR Scroll_Dirty_Update ; Do a full draw of the map tiles 
00769.  
00770. ; Clear all the map object Y to zero! 
00771. LDY #$0d ; Y = $D 
00772. LDA #$00 ; A = 0 
00773. PRG030_8617: 
00774. STA Map_Object_ActY,Y 
00775. DEY ; Y-- 
00776. BPL PRG030_8617 ; While Y >= 0, loop! 
00777.  
00778. LDA World_8_Dark 
00779. BEQ PRG030_8625 ; If World_8_Dark = 0 (not doing the effect), jump to PRG030_8625 
00780.  
00781. JSR Map_W8DarknessFill ; Fill in the entire screen with black 
00782.  
00783. PRG030_8625: 
00784. LDA World_Num  
00785. CMP #$08 
00786. BNE PRG030_8634 ; If World_Num <> 8 (World 9 / Warp Zone), jump to PRG030_8634 
00787.  
00788. LDA #$2b  
00789. JSR Video_Do_Update ; Print the "WELCOME TO WARP ZONE" banner 
00790. JSR PRGROM_Change_A000 ; Fix bank A000 
00791.  
00792. PRG030_8634: 
00793. LDY Player_Current ; Y = Player_Current 
00794. LDA Map_Prev_XOff,Y ; Get player's previous X offset (low byte) 
00795. STA <Horz_Scroll ; Set the scroll to that 
00796. STA <Scroll_Temp  
00797. LDA Map_Prev_XHi,Y ; Get player's previous X offset (high byte)  
00798. STA <Horz_Scroll_Hi ; Store as current scroll "high" 
00799. JSR Scroll_Update_Ranges 
00800.  
00801. PRG030_8646: 
00802. JSR Map_DrawAndPan ; Draw and pan map as necessary 
00803.  
00804. ; Pushes any buffered graphics thru 
00805. LDA #$00  
00806. JSR Video_Do_Update  
00807.  
00808. LDA Map_DrawPanState 
00809. BNE PRG030_8646 ; If some kind of map drawing/panning activity is occurring, loop around 
00810.  
00811. LDA Map_Operation 
00812. BNE PRG030_86A2 ; If map operation is anything besides zero, jump to PRG030_86A2 
00813.  
00814. ; Map_Operation = 0 ... the "World X" intro 
00815. ; Used at the beginning of a world, and alternating players 
00816. LDA Inventory_Open 
00817. BNE PRG030_86A2 ; If inventory is open, jump to PRG030_86A2 
00818.  
00819. ; Set bank at A000 to page 11 
00820. LDA #11  
00821. STA PAGE_A000 
00822. JSR PRGROM_Change_A000 
00823.  
00824. JSR Map_IntroAttrSave ; Pick up the current attribute info under the box 
00825.  
00826. LDX #$0E ; X = 14 (standard $00 aligned box) 
00827.  
00828. LDA <Horz_Scroll ; A = Horz_Scroll 
00829. BEQ PRG030_8670 ; If Horz_Scroll = 0, jump to PRG030_8670 
00830.  
00831. LDX #$10 ; Otherwise, X = 16 (map halfway scroll $80 aligned box) 
00832. PRG030_8670: 
00833. LDA Player_Current 
00834. BEQ PRG030_8676 ; If Player_Current = 0 (Mario), jump to PRG030_8676 
00835. INX ; Otherwise, increment X (use Luigi's name!) 
00836. PRG030_8676: 
00837. TXA ; A = X ($0E/$0F, $10/$11) 
00838. JSR Video_Do_Update ; Do the World X intro box! 
00839.  
00840. JSR Map_ConfigWorldIntro ; Apply the world number and lives count 
00841.  
00842. ; Push the buffered update 
00843. LDA #$00 
00844. JSR Video_Do_Update  
00845.  
00846. LDX World_Num  
00847. LDY World_BGM,X ; Get BGM index for this world 
00848. CPX #4  
00849. BNE PRG030_8698 ; If we're NOT on world 5, jump to PRG030_8698 
00850.  
00851. ; World 5 special handling (Sky part different music) 
00852. LDX Player_Current ; X = Player_Current 
00853. LDA <World_Map_XHi,X ; Get the high byte of this Player's X position 
00854. BEQ PRG030_8698 ; If it's equal to 0 (the "lower" part of the Sky World), jump to PRG030_8698 
00855.  
00856. ; Otherwise... 
00857. LDY #MUS2A_SKY ; Use Sky music! 
00858. JMP PRG030_869F  
00859.  
00860. PRG030_8698: 
00861. ; Either not world 5, or ground-side of world 5 
00862. LDA Map_MusicBox_Cnt  
00863. BEQ PRG030_869F ; If Map_MusicBox_Cnt = 0, jump to PRG030_869F 
00864. LDY #MUS2A_MUSICBOX ; Otherwise, play the music box song 
00865.  
00866. PRG030_869F: 
00867. STY Sound_QMusic2 ; Play BGM! 
00868.  
00869. PRG030_86A2: 
00870. LDA #$00 
00871. STA Inventory_Open ; Inventory_Open = 0 
00872.  
00873. LDA #$ef  
00874. STA <Vert_Scroll ; Vert_Scroll = $EF (map always stays at this height) 
00875.  
00876. LDA #$c0  
00877. STA Update_Select ; Update_Select = $C0 (Normal) 
00878.  
00879. ; Switch bank A000 to page 11 
00880. LDA #11  
00881. STA PAGE_A000  
00882. JSR PRGROM_Change_A000 
00883. JSR Map_DoAnimations ; On page 11 
00884.  
00885. ; Resume Update_Select activity 
00886. LDA #$00 
00887. STA UpdSel_Disable 
00888.  
00889. ; Switch bank A000 to page 27 
00890. LDA #27 
00891. STA PAGE_A000 
00892. JSR PRGROM_Change_A000 
00893. JSR Setup_PalData ; On page 27 -- PalData now holds palette data for world map tiles/objects 
00894.  
00895. ; Switch bank A000 to page 26 
00896. LDA #26 
00897. STA PAGE_A000 
00898. JSR PRGROM_Change_A000 
00899. JSR Palette_FadeIn ; On page 26 -- Fade in the world map 
00900.  
00901. ; Switch bank A000 to page 11 
00902. LDA #11  
00903. STA PAGE_A000  
00904. JSR PRGROM_Change_A000 
00905.  
00906. WorldMap_Loop: 
00907. JSR GraphicsBuf_Prep_And_WaitVSync ; This is probably just using it to VSync 
00908. JSR Sprite_RAM_Clear ; Clear sprites! 
00909.  
00910. ; Switch bank A000 to page 11  
00911. LDA #11 
00912. STA PAGE_A000  
00913. JSR PRGROM_Change_A000 
00914. JSR Map_DoAnimations ; On page 11 -- animate world map 
00915.  
00916. LDA InvFlip_Counter 
00917. BNE PRG030_86F9 ; If InvFlip_Counter <> 0, jump to PRG030_86F9 
00918.  
00919. LDA Inventory_Open  
00920. BEQ PRG030_8715 ; If Inventory_Open = 0, jump to PRG030_8715 
00921.  
00922. PRG030_86F9: 
00923. ; Inventory_Open <> 0 && InvFlip_Counter = 0 ... 
00924.  
00925. ; Switch bank A000 to page 26 
00926. LDA #26  
00927. STA PAGE_A000 
00928. JSR PRGROM_Change_A000 
00929. JSR Map_DoInventory_And_PoofFX ; Do everything with that inventory bar (On page 26) 
00930.  
00931. ; Switch bank A000 to page 11 
00932. LDA #11  
00933. STA PAGE_A000 
00934. JSR PRGROM_Change_A000  
00935.  
00936. JSR World5_Sky_AddCloudDeco ; World 5 sky area gets an extra cloud sprite (strange?) 
00937. JSR WorldMap_UpdateAndDraw ; Update and draw map graphics 
00938. JMP WorldMap_Loop ; Loop back around... 
00939.  
00940. PRG030_8715: 
00941. ; Switch bank A000 to page 11 
00942. LDA #11  
00943. STA PAGE_A000 
00944. JSR PRGROM_Change_A000 
00945.  
00946. JSR Map_DoMap ; Do the map! 
00947.  
00948. LDA Map_Operation 
00949. CMP #$02  
00950. BLT PRG030_8732 ; If Map_Operation < 2, jump to PRG030_8732  
00951.  
00952. ; Map_Operation >= 2... 
00953.  
00954. ; Switch bank A000 to page 26 
00955. LDA #26 
00956. STA PAGE_A000 
00957. JSR PRGROM_Change_A000 
00958. JSR StatusBar_UpdateValues ; Update status bar 
00959.  
00960. PRG030_8732: 
00961. LDY Map_Operation 
00962. CPY #$0d  
00963. BNE PRG030_873F ; If Map_Operation <> $D (Normal), jump to PRG030_873F 
00964.  
00965. LDA <Map_WarpWind_FX 
00966. CMP #$03  
00967. BEQ PRG030_874F ; If Map_WarpWind_FX = 3 (initialize for warp island), jump to PRG030_874F 
00968.  
00969. PRG030_873F: 
00970. ; Map_WarpWind_FX <> 3 or Map_Operation <> $D... 
00971.  
00972. CPY #$04 
00973. BEQ PRG030_874F ; If Map_Operation <> $4, jump to PRG010_874F 
00974.  
00975. CPY #$0f  
00976. BLT WorldMap_Loop ; If Map_Operation < $F (edge scroll), jump to WorldMap_Loop 
00977.  
00978. ; Map_Operation >= $F... 
00979.  
00980. LDX Player_Current  
00981. LDA Map_Player_SkidBack,X 
00982. BEQ PRG030_87BD ; If Map_Player_SkidBack = 0, jump to PRG030_87BD 
00983.  
00984. PRG030_874F: 
00985. ; Switch bank A000 to page 26 
00986. LDA #26 
00987. STA PAGE_A000 
00988. JSR PRGROM_Change_A000 
00989. JSR Palette_FadeOut ; Fade out 
00990. JSR GraphicsBuf_Prep_And_WaitVSync ; Likely just using this for VSync 
00991.  
00992. ; Disable the display 
00993. LDA #$00  
00994. STA <PPU_CTL2_Copy 
00995. STA PPU_CTL2  
00996.  
00997. ; Stop Update_Select activity temporarily 
00998. INC UpdSel_Disable 
00999.  
01000. LDA <Map_WarpWind_FX 
01001. BNE PRG030_8772 ; If Map_WarpWind_FX <> 0 (warp wind is active), jump to PRG030_8772 
01002.  
01003. LDA Map_Operation 
01004. CMP #$04  
01005. BNE PRG030_8775 ; If Map_Operation <> 4, jump to PRG030_8775 
01006.  
01007. PRG030_8772: 
01008. JMP PRG030_857E ; Jump to PRG030_857E (partial loop back) 
01009.  
01010. PRG030_8775: 
01011. ; Map_Operation <> 4 
01012.  
01013. LDX Player_Current 
01014.  
01015. ; Store current map scroll positions and Player positions  
01016. ; into the respective backup variables... 
01017. LDA <Horz_Scroll 
01018. STA Map_Prev_XOff,X 
01019.  
01020. LDA <Horz_Scroll_Hi  
01021. STA Map_Prev_XHi,X 
01022.  
01023. LDA <World_Map_Y,X 
01024. STA Map_Entered_Y,X 
01025.  
01026. LDA <World_Map_XHi,X 
01027. STA Map_Entered_XHi,X 
01028.  
01029. LDA <World_Map_X,X 
01030. STA Map_Entered_X,X 
01031.  
01032. LDA <Map_UnusedPlayerVal2,X 
01033. STA Map_Previous_UnusedPVal2,X  
01034.  
01035. LDA #$00 
01036. STA Map_Player_SkidBack,X 
01037.  
01038. PRG030_879B: 
01039. ; Switch to the other Player (if any!) 
01040. INX 
01041. STX Player_Current 
01042. CPX Total_Players 
01043. BNE PRG030_87A9 ; If not at the total Player count, jump to PRG030_87A9 
01044.  
01045. LDA #$00  
01046. STA Player_Current ; Otherwise, back to 0 (basically keeps at 0 for 1P or goes 0, 1, 0, 1...) 
01047. PRG030_87A9: 
01048.  
01049. LDA Player_Current 
01050. TAX  
01051. LDA Player_Lives,X  
01052. BMI PRG030_879B ; If Player's lives are negative (dead!), jump to PRG030_879B (makes assumption at least ONE Player is alive...) 
01053.  
01054. LDA #$00 
01055. STA Map_Operation ; Map_Operation = 0 
01056. STA Map_PlayerLost2PVs ; Clear Map_PlayerLost2PVs 
01057.  
01058. JMP PRG030_84D7 ; Jump to PRG030_84D7 (partial loop) 
01059.  
01060. PRG030_87BD: 
01061. ; Map_Operation >= $F... 
01062.  
01063. JSR GraphicsBuf_Prep_And_WaitVSync ; Vertical sync 
01064.  
01065. ; Copy the Player's positions into respective backup variables 
01066. LDX Player_Current 
01067. LDA <Horz_Scroll 
01068. STA Map_Prev_XOff,X 
01069. LDA <Horz_Scroll_Hi 
01070. STA Map_Prev_XHi,X 
01071. LDA <World_Map_Y,X 
01072. STA Map_Entered_Y,X 
01073. LDA <World_Map_XHi,X 
01074. STA Map_Entered_XHi,X 
01075. LDA <World_Map_X,X  
01076. STA Map_Entered_X,X  
01077. LDA <Map_UnusedPlayerVal2,X  
01078. STA Map_Previous_UnusedPVal2,X  
01079.  
01080. LDA #$00 
01081. STA <Map_EnterLevelFX ; Map_EnterLevelFX = 0 
01082. STA Map_EntTran_BorderLoop ; Map_EntTran_BorderLoop = 0 
01083. STA Update_Select ; Update_Select = 0 
01084. STA World_EnterState ; World_EnterState = 0 
01085.  
01086. JSR Map_Clear_EntTranMem ; Clear entrance transition memory 
01087.  
01088. ; Set initial "high" parts of VRAM addresses 
01089. LDA #$28  
01090. STA Map_EntTran_BVAddrH ; top VRAM high 
01091. STA Map_EntTran_BVAddrH+2 ; left VRAM high 
01092. STA Map_EntTran_BVAddrH+3 ; right VRAM high 
01093.  
01094. LDA #$2a  
01095. STA Map_EntTran_BVAddrH+1 ; bottom VRAM high 
01096.  
01097. LDA #$00  
01098. STA Map_EntTran_BVAddrL ; top VRAM low 
01099. STA Map_EntTran_BVAddrL+3 ; right VRAM low 
01100.  
01101. LDA #$1f  
01102. STA Map_EntTran_BVAddrL+2 ; left VRAM low 
01103. STA Map_EntTran_TBCnt ; Map_EntTran_TBCnt also happens to be $1f 
01104.  
01105. LDA #$e0  
01106. STA Map_EntTran_BVAddrL+1 ; bottom VRAM low 
01107.  
01108. LDA #$17  
01109. STA Map_EntTran_LRCnt ; Map_EntTran_LRCnt = $17 
01110.  
01111.  
01112. ; Top 0, bottom 1, right 2, left 3 
01113. LDX #$03 ; X = 3 
01114. PRG030_881D: 
01115. LDA <Scroll_ColumnL 
01116. AND #$0f 
01117. ASL A  
01118. ADD Map_EntTran_BVAddrL,X ; adds 2 per column scrolled 
01119. STA Map_EntTran_BVAddrL,X 
01120. DEX ; X-- 
01121. BPL PRG030_881D ; While X >= 0, loop! 
01122.  
01123. LDA Map_EntTran_BVAddrL+2 
01124. AND #$1f  
01125. STA Map_EntTran_BVAddrL+2 
01126.  
01127. LDA #$30 
01128. STA Map_EntTran_Cnt ; Map_EntTran_Cnt = $30 
01129.  
01130. LDA #SND_MAPENTERLEVEL 
01131. STA Sound_QMap ; Play "enter level" sound effect! 
01132.  
01133. ; Loop until V-Blank is not occurring 
01134. PRG030_883E: 
01135. LDA PPU_STAT 
01136. AND #$80  
01137. BNE PRG030_883E  
01138.  
01139. LDA #%10101000 ; sprites on PT2, 8x16 sprites, generate V-Blank NMIs 
01140. STA PPU_CTL1  
01141. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync! 
01142.  
01143. ; The actual border rendering occurs in the interrupt's "Update_Select" routine 
01144. ; which calls "Map_EnterLevel_Effect" in PRG026 
01145. PRG030_884C: 
01146. JSR GraphicsBuf_Prep_And_WaitVSync ; Just VSyncs 
01147.  
01148. LDA #$01 
01149. STA <Map_EnterLevelFX ; Map_EnterLevelFX = 1 
01150.  
01151. LDX Map_EntTran_BorderLoop ; Get current border loop counter (0-3: Top 0, bottom 1, right 2, left 3) 
01152. TXA 
01153. AND #$02 
01154. BEQ PRG030_887F ; If Map_EntTran_BorderLoop & 2 = 0, jump to PRG030_887F (means jump if doing top/bottom) 
01155.  
01156. ; Left/right edge sprite removal check... 
01157.  
01158. ; This calculates the border's relative X position -> Temp_Var1 
01159. LDA Map_EntTran_BVAddrL,X 
01160. ASL A 
01161. ASL A 
01162. ASL A 
01163. SUB <Horz_Scroll 
01164. STA <Temp_Var1 ; Temp_Var1 = (Map_EntTran_BVAddrL[X] << 3) - Horz_Scroll 
01165.  
01166. ; This goes through all system sprites and removes them as the encroaching black border hits them 
01167. LDX #$00 ; X = 0 
01168. PRG030_8868: 
01169. LDA Sprite_RAM+$03,X ; Get this sprite's X coordinate 
01170. AND #$f8 ; Only considering its nearest-8 position (aligned to the pattern-based border) 
01171. CMP <Temp_Var1  
01172. BNE PRG030_8876 ; If this sprite hasn't been touched yet, jump to PRG030_8876 
01173.  
01174. LDA #$f8  
01175. STA Sprite_RAM+$00,X ; Set this sprite's Y to $F8 (make invisible) 
01176.  
01177. PRG030_8876: 
01178. DEX 
01179. DEX 
01180. DEX 
01181. DEX ; X -= 4 
01182. BNE PRG030_8868 ; While X <> 0, loop! 
01183.  
01184. JMP PRG030_88A5 ; Jump to PRG030_88A5 
01185.  
01186. PRG030_887F: 
01187. ; Top/bottom edge sprite removal check... 
01188.  
01189. ; This calculates the border's relative Y position -> Temp_Var1 
01190. LDA Map_EntTran_BVAddrL,X 
01191. AND #$c0  
01192. STA <Temp_Var1 
01193. LDA Map_EntTran_BVAddrH,X 
01194. LSR A  
01195. ROR <Temp_Var1  
01196. LSR A  
01197. ROR <Temp_Var1  
01198.  
01199. LDX #$00 ; X = 0 
01200. PRG030_8891: 
01201. LDA Sprite_RAM+$00,X ; Get this sprite's Y position 
01202. AND #$f0 ; Only check its nearest-16 position (16 because of 16 pixel tall sprites) 
01203. CMP <Temp_Var1 
01204. BNE PRG030_889F ; If this sprite hasn't been touched yet, jump to PRG030_889F 
01205.  
01206. LDA #$f8  
01207. STA Sprite_RAM+$00,X ; Set this sprite's Y to $F8 (make invisible) 
01208.  
01209. PRG030_889F: 
01210. DEX 
01211. DEX 
01212. DEX 
01213. DEX ; X -= 4 
01214. BNE PRG030_8891 ; While X <> 0, loop! 
01215.  
01216. PRG030_88A5: 
01217. DEC Map_EntTran_Cnt ; Map_EntTran_Cnt-- 
01218. BMI PRG030_88AD ; If Map_EntTran_Cnt < 0, jump to PRG030_88AD 
01219.  
01220. JMP PRG030_884C ; Jump to PRG030_884C (loop) 
01221.  
01222. PRG030_88AD: 
01223. ; Completed the entrance transition... 
01224.  
01225. LDA #%00011000 
01226. STA <PPU_CTL2_Copy ; Show BG+Sprites 
01227.  
01228. JSR GraphicsBuf_Prep_And_WaitVSync ; Waiting for vertical sync 
01229.  
01230. ; Stop Update_Select activity temporarily 
01231. INC UpdSel_Disable 
01232.  
01233. LDA #%00101000 ; use 8x16 sprites, sprites use PT2 (NOTE: No VBlank trigger!) 
01234. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync! 
01235. STA PPU_CTL1  
01236.  
01237. ; Disable display 
01238. LDA #$00 
01239. STA PPU_CTL2 
01240.  
01241. LDA #$04  
01242. STA Level_TimerMSD ; Level_TimerMSD = 4 
01243.  
01244. PRG030_88C8: 
01245. ; Clearing scroll variables 
01246. LDA #$00 
01247. STA <Horz_Scroll_Hi 
01248. STA <Horz_Scroll 
01249. STA <Vert_Scroll_Hi 
01250. STA <Vert_Scroll 
01251. STA <Scroll_ColumnR 
01252. STA <Scroll_ColumnL 
01253. STA <Scroll_LastDir 
01254.  
01255. STA Coins_ThisLevel ; Clear "coins earned this level" counter 
01256. STA Map_BonusCoinsReqd ; Clear the "coins required for bonus" 
01257. STA Map_BonusType ; Clear the "bonus type" 
01258.  
01259. STA <Temp_Var1 ; Temp_Var1 = 0 
01260.  
01261. LDX #$05  
01262. STX <Temp_Var2 ; Temp_Var2 = 5 
01263.  
01264. ; Going to clear memory from $9D to $01 
01265. LDY #$9d ; Y = $9D 
01266. PRG030_88E9: 
01267. STA [Temp_Var1],Y ; Clear this byte 
01268. DEY ; Y-- 
01269. BNE PRG030_88E9 ; While Y <> 0, loop! 
01270.  
01271. STA [Temp_Var1],Y ; And address $00 is cleared too (though this is technically unnecessary) 
01272.  
01273. LDA <Map_Enter2PFlag 
01274. BEQ PRG030_891A ; If not entering 2P Vs mode, jump to PRG030_891A 
01275.  
01276. ; 2P Vs mode begin! 
01277.  
01278. ; Level_Tileset = 18 (2P Vs) 
01279. LDA #18 
01280. STA Level_Tileset 
01281.  
01282. JSR SetPages_ByTileset 
01283.  
01284. INC Map_2PVsGame ; Map_2PVsGame++ (play next game style) 
01285.  
01286. LDA Map_2PVsGame 
01287. CMP #12 
01288. BNE PRG030_890B ; If Map_2PVsGame <> 12 (overflow), jump to PRG030_890B 
01289.  
01290. ; Otherwise, restart count 
01291. LDA #$00 
01292. STA Map_2PVsGame 
01293.  
01294. PRG030_890B: 
01295. ASL A ; Multiply game style by 2 
01296. TAX ; -> 'X' 
01297.  
01298. ; Load address to battlefield level data 
01299. LDA Vs_Battlefields,X 
01300. STA <Level_LayPtr_AddrL 
01301. LDA Vs_Battlefields+1,X 
01302. STA <Level_LayPtr_AddrH 
01303.  
01304. JMP PRG030_892A ; Jump to PRG030_892A 
01305.  
01306. PRG030_891A: 
01307.  
01308. ; Non-2P Mode begin! 
01309.  
01310. ; Set bank C000 to page 22 and A000 to page 12 
01311. LDA #22 
01312. STA PAGE_C000 
01313. LDA #12 
01314. STA PAGE_A000 
01315. JSR PRGROM_Change_Both2 
01316.  
01317. ; The ultimate output is properly configured 
01318. ; Level_ObjPtr_AddrL/H and Level_ObjPtrOrig_AddrL/H (object list pointer) 
01319. ; Level_LayPtr_AddrL/H and Level_LayPtrH_AddrL/H (tile layout pointer) 
01320. ; Level_Tileset 
01321. JSR Map_PrepareLevel  
01322.  
01323. PRG030_892A: 
01324. LDA World_Num 
01325. CMP #$08  
01326. BNE PRG030_893F ; If World_Num <> 8 (World 9), jump to PRG030_893F 
01327.  
01328. ; Warp zone special 
01329. LDA #MUS1_STOPMUSIC  
01330. STA Sound_QMusic1 ; Stop BGM 
01331.  
01332. ; The destination world is fed back out through Map_Warp_PrevWorld 
01333. LDA Map_Warp_PrevWorld 
01334. STA World_Num ; World_Num = Map_Warp_PrevWorld 
01335. JMP PRG030_84A0 ; Jump to PRG030_84A0 (initialize the world map!) 
01336.  
01337. PRG030_893F: 
01338. LDY Level_Tileset ; Y = Level_Tileset 
01339. LDA ClearPattern_ByTileset,Y 
01340. STA ClearPattern ; ClearPattern = ClearPattern_ByTileset[Y] 
01341.  
01342. CPY #$07  
01343. BNE PRG030_8964 ; If Level_Tileset <> 7 (Toad House), jump to PRG030_8964 
01344.  
01345. ; Toad House object pointer override! 
01346.  
01347. ; The object set pointer has different meaning for a Toad House! 
01348. LDA <Level_ObjPtr_AddrL 
01349. STA THouse_ID ; Toad House ID; not used, would have tracked boxes already opened (multiple visits perhaps??) 
01350. LDA <Level_ObjPtr_AddrH 
01351. STA THouse_Treasure  
01352.  
01353. ; Force object set at TOADO (Toad and the message object) 
01354. LDA #LOW(TOADO) 
01355. STA <Level_ObjPtr_AddrL 
01356. STA Level_ObjPtrOrig_AddrL  
01357. LDA #HIGH(TOADO) 
01358. STA <Level_ObjPtr_AddrH 
01359. STA Level_ObjPtrOrig_AddrH  
01360.  
01361. PRG030_8964: 
01362.  
01363. ; Clears $7F bytes starting at Level_BlockGrabHitMem ($7E02) 
01364. ; Clear Level_BlockGrabHitMem (collected coins and 1-ups memory) 
01365. LDY #$7f ; Y = $7f 
01366. LDA #$00 ; A = 0 
01367. PRG030_8968: 
01368. STA Level_BlockGrabHitMem,Y 
01369. DEY ; Y-- 
01370. BPL PRG030_8968 ; While Y >= 0, loop! 
01371.  
01372. ; Clears $80 bytes starting at Player_XHi ($75, gameplay context) 
01373. LDY #$80 ; Y = $80 
01374. LDA #$00 ; A = 0 
01375. STA LevelJctBQ_Flag ; LevelJctBQ_Flag = 0  
01376. PRG030_8975:  
01377. STA Player_XHi,Y 
01378. DEY ; Y-- 
01379. BNE PRG030_8975 ; While Y >= 0, loop! 
01380.  
01381. PRG030_897B: 
01382. ; Level junctions enter here, to continue with preparation to display! 
01383.  
01384. LDA #$00  
01385. STA Vert_Scroll_Off ; Vert_Scroll_Off = 0 
01386.  
01387. ; If Level_Tileset = 16 (Spade game sliding cards) or 17 (N-Spade), jump to PRG030_89AB 
01388. LDA Level_Tileset 
01389. CMP #16 
01390. BEQ PRG030_89AB 
01391. CMP #17 
01392. BEQ PRG030_89AB  
01393.  
01394. ; Inline clone of "SetPages_ByTileset" 
01395. ; Change A000 and C000 pages by Level_Tileset 
01396. LDY Level_Tileset 
01397. LDA PAGE_C000_ByTileset,Y 
01398. STA PAGE_C000  
01399. LDA PAGE_A000_ByTileset,Y 
01400. STA PAGE_A000  
01401. JSR PRGROM_Change_Both2 
01402.  
01403. JSR LevelLoad_ByTileset ; Load the level layout data! 
01404. JSR Sprite_RAM_Clear ; Clear the sprites 
01405. JSR Fill_Tile_AttrTable_ByTileset ; Load tile attribute tiles by the tileset 
01406.  
01407. ; Scroll_Cols2Upd = 32 (full dirty scroll update sweep) 
01408. LDA #32 
01409. STA Scroll_Cols2Upd 
01410.  
01411. PRG030_89AB: 
01412. JSR Reset_PPU_Clear_Nametables2 ; Blank display, clear nametables 
01413. JSR Sprite_RAM_Clear ; Clear the sprites 
01414.  
01415. ; Select the first bank of BG VROM as specified by Level_BG_Page1_2 
01416. LDY Level_BG_Page1_2 
01417. LDA Level_BG_Pages1,Y 
01418. STA PatTable_BankSel 
01419.  
01420. LDA Level_BG_Pages2,Y 
01421.  
01422. LDX Level_PSwitchCnt 
01423. BEQ PRG030_89C4 ; If P-Switch not active, jump to PRG030_89C4 
01424.  
01425. LDA #$3e ; Otherwise, force override to page $3E 
01426.  
01427. PRG030_89C4: 
01428. STA PatTable_BankSel+1 ; Select second bank of BG VROM 
01429.  
01430. LDA Level_Tileset  
01431. CMP #16 
01432. BEQ PRG030_89D1 ; If Level_Tileset = 16 (Spade game sliders), jump to PRG030_89D1 
01433.  
01434. JMP PRG030_8A4E ; Otherwise, jump to PRG030_8A4E 
01435.  
01436. PRG030_89D1: 
01437. ; Spade game sliders (Roulette Game) 
01438.  
01439. ; Set pattern banks on sprite side... only really need the border sprites?? 
01440. LDY #$20 
01441. STY PatTable_BankSel+2 
01442. INY 
01443. STY PatTable_BankSel+3 
01444. INY 
01445. STY PatTable_BankSel+4 
01446. INY 
01447. STY PatTable_BankSel+5 
01448.  
01449. ; Horizontal mirroring 
01450. LDA #$00 
01451. STA MMC3_MIRROR 
01452.  
01453. JSR Roulette_DrawShapes ; Draw in the Roulette Shapes 
01454. JSR Roulette_DrawBorderSprites ; Draw the sprite borders 
01455.  
01456. ; Render Roulette borders and set attributes 
01457. LDA #$07 
01458. JSR Video_Do_Update 
01459.  
01460. ; Status bar suitable for the horizontal mirroring mode 
01461. LDA #$05 
01462. JSR Video_Do_Update 
01463.  
01464. ; Switch to page 26 @ A000 
01465. LDA #MMC3_8K_TO_PRG_A000 
01466. STA MMC3_COMMAND 
01467. LDA #26  
01468. STA MMC3_PAGE  
01469.  
01470. JSR StatusBar_Update_Cards ; Update status bar cards 
01471. JSR StatusBar_UpdateValues ; Update other status bar stuff 
01472. JSR StatusBar_Fill_MorL ; Patch in correct M or L on status bar 
01473. JSR StatusBar_Fill_World ; Fill in correct world number 
01474.  
01475. ; Push through what's in graphics buffer 
01476. LDA #$00 
01477. JSR Video_Do_Update 
01478.  
01479. ; Update_Select = $C0 
01480. LDA #$c0 
01481. STA Update_Select 
01482.  
01483. ; Set scrolling to absolute top 
01484. LDA #$00 
01485. STA <Vert_Scroll 
01486.  
01487. ; Resume Update_Select activity 
01488. STA UpdSel_Disable 
01489.  
01490. ; Set page @ A000 to 27 
01491. LDA #27 
01492. STA PAGE_A000 
01493. JSR PRGROM_Change_A000 
01494.  
01495. JSR Setup_PalData ; Setup palette data 
01496.  
01497. ; Set page @ A000 to 26 
01498. LDA #26 
01499. STA PAGE_A000 
01500. JSR PRGROM_Change_A000 
01501.  
01502. JSR Palette_FadeIn ; Fade in palette 
01503.  
01504. ; Enable the Roulette slider raster effect 
01505. LDA #UPDATERASTER_SPADEGAME 
01506. STA Update_Request 
01507.  
01508. ; We actually get hung up here until afer the end of the Roulette 
01509. ; game when it has completely faded out due to Update_Request = UPDATERASTER_SPADEGAME 
01510. JSR GraphicsBuf_Prep_And_WaitVSync 
01511.  
01512. ; Update_Select = $C0 
01513. LDA #$c0 
01514. STA Update_Select 
01515.  
01516. ; Vertical mirroring 
01517. LDA #$01 
01518. STA MMC3_MIRROR 
01519.  
01520. ; Stop music 
01521. LDA #MUS1_STOPMUSIC 
01522. STA Sound_QMusic1 
01523.  
01524. ; Returning to map 
01525. JMP PRG030_8FA1 ; Jump to PRG030_8FA1 
01526.  
01527. PRG030_8A4E: 
01528. ; Not spade game sliders 
01529.  
01530. CMP #17 
01531. BEQ PRG030_8A55 ; If Level_Tileset = 17 (N-Spade game), jump to PRG030_8A55 
01532. JMP PRG030_8AE0 ; Otherwise, jump to PRG030_8AE0 
01533.  
01534. PRG030_8A55: 
01535. ; N-Spade Game 
01536.  
01537. ; Load graphics for N-Spade 
01538. LDY #$28 
01539. STY PatTable_BankSel+2 
01540. INY 
01541. STY PatTable_BankSel+3 
01542. INY 
01543. INY 
01544. STY PatTable_BankSel+5 
01545. LDA #$5a 
01546. STA PatTable_BankSel+4 
01547.  
01548. ; Card_Index = $0E (this assignment isn't really used for anything) 
01549. LDA #$0E 
01550. STA Card_Index 
01551.  
01552. ; Temp_Var1 = $20 (VRAM High Address for Clear_Nametable_Short) 
01553. LDA #$20 
01554. STA <Temp_Var1 
01555. JSR Clear_Nametable_Short 
01556.  
01557. ; Generate the candystripe background of the N-Spade game 
01558. LDA #$0d 
01559. JSR Video_Do_Update 
01560.  
01561. PRG030_8A79: 
01562. JSR Card_InitGame ; Do this stage of initialization 
01563.  
01564. LDA <Graphics_Queue 
01565. JSR Video_Do_Update ; Push graphics update 
01566.  
01567. LDA Card_InitState 
01568. CMP #$03 
01569. BNE PRG030_8A79 ; While Card_InitState <> 3, loop! 
01570.  
01571. ; Status bar suitable for the card game 
01572. LDA #$05 
01573. JSR Video_Do_Update 
01574.  
01575. JSR StatusBar_Update_Cards ; Update status bar cards 
01576. JSR StatusBar_UpdateValues ; Update other status bar stuff 
01577. JSR StatusBar_Fill_MorL ; Patch in correct M or L on status bar 
01578. JSR StatusBar_Fill_World ; Fill in correct world number 
01579.  
01580. ; Push through what's in graphics buffer 
01581. LDA #$00 
01582. JSR Video_Do_Update 
01583.  
01584. ; Update_Select = $C0 
01585. LDA #$c0 
01586. STA Update_Select 
01587.  
01588. ; Set scrolling to absolute top 
01589. LDA #$00 
01590. STA <Vert_Scroll 
01591.  
01592. ; Resume Update_Select activity 
01593. STA UpdSel_Disable 
01594.  
01595. ; Set page @ A000 to 27 
01596. LDA #27 
01597. STA PAGE_A000 
01598. JSR PRGROM_Change_A000 
01599.  
01600. JSR Setup_PalData ; Setup palette data 
01601.  
01602. ; Set bank at A000 to page 26 
01603. LDA #26 
01604. STA PAGE_A000 
01605. JSR PRGROM_Change_A000 
01606.  
01607. JSR Palette_FadeIn ; Fade in palette 
01608.  
01609. PRG030_8AC0: 
01610. JSR GraphicsBuf_Prep_And_WaitVSync ; VSync 
01611.  
01612. JSR NSpade_DoGame ; Run N-Spade game 
01613.  
01614. JSR StatusBar_UpdateValues ; Update status bar 
01615.  
01616. LDA <Level_ExitToMap 
01617. BEQ PRG030_8AC0 ; If we're not exiting to map, loop N-Spade game 
01618.  
01619. ; Stop music 
01620. LDA #MUS1_STOPMUSIC 
01621. STA Sound_QMusic1 
01622.  
01623. ; Set bank at A000 to page 26 
01624. LDA #26 
01625. STA PAGE_A000 
01626. JSR PRGROM_Change_A000 
01627.  
01628. JSR Palette_FadeOut ; Fade out 
01629.  
01630. JMP PRG030_8FA1 ; Jump to PRG030_8FA1 
01631.  
01632. PRG030_8AE0: 
01633. CMP #18 
01634. BNE PRG030_8AE7 ; If Level_Tileset <> 18 (2P Vs), jump to PRG030_8AE7 
01635.  
01636. JMP Do_2PVsChallenge ; Jump Do_2PVsChallenge 
01637.  
01638. PRG030_8AE7: 
01639. ; Normal gameplay... 
01640.  
01641. ; Clear Update_Request 
01642. LDA #$00 
01643. STA Update_Request 
01644.  
01645. ; Vertical mirroring 
01646. LDA #$01 
01647. STA MMC3_MIRROR 
01648.  
01649. LDA #$02 ; A = 2 
01650. LDX #$c0 ; X = $C0 (Normal style updating) 
01651.  
01652. LDY Level_7Vertical 
01653. BEQ PRG030_8B03 ; If level is NOT a vertical one, jump to PRG030_8B03 
01654.  
01655. ; Level is vertical! 
01656.  
01657. ; Horizontal mirroring 
01658. LDA #$00 
01659. STA MMC3_MIRROR 
01660.  
01661. LDA #$01 ; A = 1 
01662. LDX #$80 ; X = $80 (Vertical style updating) 
01663.  
01664. PRG030_8B03: 
01665. STX Update_Select ; Set Update_Select 
01666.  
01667. JSR Video_Do_Update ; Video update 
01668.  
01669. ; Set bank at A000 to page 26 
01670. LDA #26 
01671. STA PAGE_A000 
01672. JSR PRGROM_Change_A000 
01673.  
01674. JSR StatusBar_Update_Cards ; Update status bar cards 
01675. JSR StatusBar_UpdateValues ; Update other status bar stuff 
01676. JSR StatusBar_Fill_MorL ; Patch in correct M or L on status bar 
01677. JSR StatusBar_Fill_World ; Fill in correct world number 
01678.  
01679. LDA #$00 ; A = 0 (Graphics buffer push) 
01680. JSR Video_Do_Update ; Push through what's in graphics buffer 
01681.  
01682. JSR Scroll_Dirty_Update ; Entering level, do dirty update 
01683.  
01684. LDA Level_Tileset 
01685. CMP #15 
01686. BEQ PRG030_8B6D ; If Level_Tileset = 15 (Bonus game intro), jump to PRG030_8B6D 
01687.  
01688. ; Changes pages at A000 and C000 to 26 and 6, respectively 
01689. LDA #6 
01690. STA PAGE_C000 
01691. LDA #26 
01692. STA PAGE_A000 
01693. JSR PRGROM_Change_Both2 
01694.  
01695. JSR LevelLoad_CopyObjectList ; Copy in level objects! 
01696.  
01697. LDX Player_Current 
01698. LDA Player_FallToKing,X 
01699. BNE PRG030_8B6D ; If Player is bound for king, jump to PRG030_8B6D 
01700.  
01701. LDA Inventory_Open 
01702. BNE PRG030_8B51 ; If inventory is open (only normally happens at this point in Toad House), jump to PRG030_8B51 
01703.  
01704. LDA Level_JctCtl 
01705. BNE PRG030_8B51 ; If we're using a level junction override, jump to PRG030_8B51 
01706.  
01707. JMP PRG030_8B6D ; Otherwise, jump to PRG030_8B6D 
01708.  
01709. PRG030_8B51: 
01710. ; Level junction override! Copy in junction variables as appropriate 
01711. LDA Level_Jct_HS 
01712. STA <Horz_Scroll 
01713. LDA Level_Jct_HSHi 
01714. STA <Horz_Scroll_Hi 
01715.  
01716. LDA Level_Jct_VS 
01717. STA <Vert_Scroll 
01718.  
01719. LDA Level_Jct_VSHi 
01720. STA <Vert_Scroll_Hi 
01721.  
01722. ; Junction complete (and inventory is NOT open) 
01723. LDA #$00  
01724. STA Inventory_Open 
01725. STA Level_JctCtl 
01726.  
01727. PRG030_8B6D: 
01728. LDX Player_Current 
01729.  
01730. LDA Player_FallToKing,X 
01731. BEQ PRG030_8B78 ; If player is NOT bound for king's room, jump to PRG030_8B78 
01732.  
01733. JMP PRG030_9009 ; Jump to PRG030_9009 
01734.  
01735. PRG030_8B78: 
01736. LDA #$00  
01737. STA Raster_Effect ; Raster_Effect = $00 (Normal status bar) 
01738. STA UpdSel_Disable ; Resume Update_Select activity 
01739.  
01740. ; Set page @ A000 to 27 
01741. LDA #27 
01742. STA PAGE_A000 
01743. JSR PRGROM_Change_A000 
01744.  
01745. JSR Setup_PalData ; Setup palette data 
01746.  
01747. LDA Level_Tileset 
01748. CMP #15 
01749. BNE PRG030_8B9A ; If Level_Tileset <> 15 (Bonus game intro), jump to PRG030_8B9A 
01750.  
01751. ; Otherwise, set page @ C000 to 22 
01752. LDA #22 
01753. STA PAGE_C000 
01754. JSR PRGROM_Change_Both2 
01755.  
01756. PRG030_8B9A: 
01757. ; Set page @ A000 to 26 
01758. LDA #26 
01759. STA PAGE_A000 
01760. JSR PRGROM_Change_A000 
01761.  
01762. JSR Palette_FadeIn ; Fade in palette 
01763.  
01764. ; Set page @ A000 as appropriate for this tileset 
01765. LDY Level_Tileset 
01766. LDA PAGE_A000_ByTileset,Y 
01767. STA PAGE_A000 
01768. JSR PRGROM_Change_A000 
01769.  
01770. ; This is the init code for the level "boxing out" effect removed in the US release 
01771.  
01772. ; US VERSION DOES THIS: 
01773. JMP PRG030_8CB8 ; Jump to PRG030_8CB8 (skipping code related to the "Boxing out" effect, removed in US version) 
01774.  
01775. ; Leftover optional code, see below 
01776. LDA #$00 
01777. STA <Map_EnterLevelFX ; Map_EnterLevelFX = 0 
01778.  
01779. ; ORIGINAL VERSION DID THIS (addresses relate to original code!): 
01780. ; LDA Level_Tileset 
01781. ; CMP #15 
01782. ; BEQ PRG030_8BC2 ; If Level_Tileset = 15 (bonus game intro), jump to PRG030_8BC2 
01783. ; 
01784. ; LDA Map_UNK713 
01785. ; BEQ PRG030_8BC5 ; If Map_UNK713 = 0, jump to PRG030_8BC5 
01786. ; 
01787. ;PRG030_8BC2: 
01788. ; JMP PRG030_8CC9 ; Jump to PRG030_8CC9 
01789. ; 
01790. ;PRG030_8BC5: 
01791. ; LDA #$00 
01792. ; STA <Map_EnterLevelFX ; Map_EnterLevelFX = 0 
01793. ;PRG030_8CC9: 
01794.  
01795. JSR Map_Clear_EntTranMem ; Clear entrance transition memory 
01796.  
01797. LDA #$ff 
01798. STA Map_EntTran_Temp ; Map_EntTran_Temp = $ff 
01799.  
01800. LDA Level_7Vertical 
01801. BEQ PRG030_8BD5 ; If not a vertical level, jump to PRG030_8BD5 
01802.  
01803. ; Set address as appropriate for vertical 
01804. LDY Level_SizeOrig 
01805. LDA Tile_Mem_AddrVL,Y 
01806. STA <Map_Tile_AddrL 
01807. LDA Tile_Mem_AddrVH,Y 
01808. STA <Map_Tile_AddrH 
01809.  
01810. JMP PRG030_8BDF ; Jump to PRG030_8BDF 
01811.  
01812. PRG030_8BD5:  
01813.  
01814. ; First screen is always where non-vertical maps start 
01815. LDA Tile_Mem_Addr 
01816. STA <Map_Tile_AddrL 
01817. LDA Tile_Mem_Addr+1 
01818. STA <Map_Tile_AddrH 
01819.  
01820. PRG030_8BDF: 
01821. LDA #$00  
01822. STA Map_EntTran_VLHalf ; Map_EntTran_VLHalf = 0 
01823.  
01824. LDA <Vert_Scroll 
01825. BEQ PRG030_8BF4 ; If Vert_Scroll = 0, jump to PRG030_8BF4 
01826.  
01827. ; Otherwise, offset initial address by $F0 (15 rows) and 
01828. ; flag we're performing this on the lower vertical 
01829. LDA <Map_Tile_AddrL 
01830. ADD #$f0  
01831. STA <Map_Tile_AddrL ; Map_Tile_AddrL += $F0 
01832.  
01833. LDA #$01 
01834. STA Map_EntTran_VLHalf ; Map_EntTran_VLHalf = 1 
01835.  
01836. PRG030_8BF4: 
01837. LDY #$04 ; Y = 4 (search begin) 
01838.  
01839. PRG030_8BF6: 
01840. LDA <Vert_Scroll 
01841. CMP BoxOut_ByVStart,Y 
01842. BEQ PRG030_8C00 
01843. DEY ; Y-- 
01844. BPL PRG030_8BF6 ; While Y >= 0, loop 
01845.  
01846. PRG030_8C00: 
01847. STY Map_EntTran_InitValIdx ; Store initial value index 
01848.  
01849. LDA BoxOut_InitVAddrH,Y ; Get initial high part of VRAM address 
01850. STA Map_EntTran_BVAddrH 
01851. STA Map_EntTran_BVAddrH+1 
01852. STA Map_EntTran_BVAddrH+2 
01853. STA Map_EntTran_BVAddrH+3 
01854.  
01855. ; Copy in the four low bytes 
01856. LDA BoxOut_InitVAddrL0,Y 
01857. STA Map_EntTran_BVAddrL  
01858.  
01859. LDA BoxOut_InitVAddrL2,Y 
01860. STA Map_EntTran_BVAddrL+2 
01861.  
01862. LDA BoxOut_InitVAddrL1,Y 
01863. STA Map_EntTran_BVAddrL+1 
01864.  
01865. LDA BoxOut_InitVAddrL3,Y 
01866. STA Map_EntTran_BVAddrL+3 
01867.  
01868. LDA #$00 
01869. STA Map_EntTran_BorderLoop ; Map_EntTran_BorderLoop = 0 
01870.  
01871. LDA #$04 
01872. STA Map_EntTran_TBCnt ; Map_EntTran_TBCnt = 4 
01873.  
01874. LDY #$01  
01875. STY Map_EntTran_LRCnt ; Map_EntTran_LRCnt= 1 
01876.  
01877. LDA #$00  
01878. STA Update_Select ; Insist (again!) that Update_Select = 0 
01879.  
01880. PRG030_8C3E: 
01881. JSR GraphicsBuf_Prep_And_WaitVSync ; VSync 
01882.  
01883. ; Set page @ A000 as appropriate by Level_Tileset 
01884. LDY Level_Tileset 
01885. LDA PAGE_A000_ByTileset,Y 
01886. STA PAGE_A000 
01887. JSR PRGROM_Change_A000 
01888.  
01889. LDX Map_EntTran_BorderLoop ; X = current border index (0-3: Top 0, bottom 1, right 2, left 3) 
01890.  
01891. LDA Map_EntTran_BVAddrH,X ; Get high byte of VRAM addres 
01892. STA Map_EntTran_VAddrH ; Store it 
01893.  
01894. LDA Map_EntTran_BVAddrL,X ; Get low byte of VRAM address 
01895. STA Map_EntTran_VAddrL ; Store it 
01896.  
01897. LDA Map_EntTran_BorderLoop ; A = current border index (0-3: Top 0, bottom 1, right 2, left 3) 
01898. AND #$02 
01899. BNE PRG030_8C74 ; If not updating top/bottom, jump to PRG030_8C74 
01900.  
01901. ; top/bottom update... 
01902. LDX Map_EntTran_TBCnt 
01903.  
01904. LDA #$01 
01905. STA Map_EntTran_VRAMGap ; Map_EntTran_VRAMGap = 1 
01906.  
01907. LDA Map_EntTran_VAddrL 
01908. AND #$01 
01909. BEQ PRG030_8C8C ; If on even address, jump to PRG030_8C8C 
01910. BNE PRG030_8C83 ; If on odd address, jump to PRG030_8C83 
01911.  
01912. PRG030_8C74: 
01913.  
01914. ; left/right update... 
01915. LDX Map_EntTran_LRCnt 
01916.  
01917. LDA #32 
01918. STA Map_EntTran_VRAMGap ; PRG030_8C8C = 32 
01919.  
01920. LDA Map_EntTran_VAddrL 
01921. AND #$20 
01922. BEQ PRG030_8C8C ; If on 32 byte aligned address, jump to PRG030_8C8C 
01923.  
01924. PRG030_8C83: 
01925. JSR BoxOut_PutPatternInStrip ; Put an 8x8 pattern into the strip 
01926. JSR BoxOut_SetThisBorderVRAM ; Set the VRAM offset for this border 
01927. DEX ; X-- (counter decrement) 
01928. BMI PRG030_8CAA ; If X < 0, jump to PRG030_8CAA 
01929.  
01930. PRG030_8C8C: 
01931. JSR BoxOut_PutPatternInStrip ; Put an 8x8 pattern into the strip 
01932. DEX ; X-- (counter decrement) 
01933. BMI PRG030_8CAA ; If X < 0, jump to PRG030_8CAA 
01934.  
01935. INC <Temp_Var14 ; Temp_Var14++ (tile pattern layout high, jump to next pattern) 
01936.  
01937. LDA Map_EntTran_VRAMGap 
01938. AND #$01  
01939. BEQ PRG030_8C9D ; If Map_EntTran_VRAMGap & 1 jump to PRG030_8C9D 
01940.  
01941. INC <Temp_Var14 ; Temp_Var14++ (tile pattern layout high, jump to next pattern) 
01942.  
01943. PRG030_8C9D: 
01944. LDA [Temp_Var13],Y ; Get 8x8 pattern 
01945. STA <Scroll_ColorStrip,X ; Store into strip 
01946.  
01947. JSR BoxOut_SetThisBorderVRAM ; Set border VRAM 
01948. JSR BoxOut_SetThisBorderVRAM ; Called twice?? 
01949. DEX ; X-- 
01950. BPL PRG030_8C8C ; While X >= 0, loop! 
01951.  
01952. PRG030_8CAA: 
01953. LDA #$02 
01954. STA <Map_EnterLevelFX ; Map_EnterLevelFX = 2 (begin the proper box out effect!) 
01955.  
01956. LDA Map_EntTran_Cnt 
01957. CMP #$34  
01958. BEQ PRG030_8CB8 ; If Map_EntTran_Cnt = $34, jump to PRG030_8CB8 
01959. JMP PRG030_8C3E ; Otherwise, loop! 
01960.  
01961. PRG030_8CB8: 
01962. ; End of box-out effect (removed in US version) 
01963.  
01964. ; Set page @ A000 as appropriate for Tileset 
01965. LDY Level_Tileset 
01966. LDA PAGE_A000_ByTileset,Y 
01967. STA PAGE_A000 
01968. JSR PRGROM_Change_A000 
01969.  
01970. LDA #$00 
01971. STA <Map_EnterLevelFX ; Map_EnterLevelFX = 0 
01972.  
01973. LDX #$c0 ; X = $C0 (Normal style updating) 
01974. LDA Level_7Vertical  
01975. BEQ PRG030_8CD1 ; If not a vertical level, jump to PRG030_8CD1 
01976.  
01977. LDX #$80 ; X = $80 (Vertical style updating) 
01978.  
01979. PRG030_8CD1: 
01980. STX Update_Select ; Set Update_Select as appropriate 
01981.  
01982. LDA Level_Tileset 
01983. CMP #15  
01984. BEQ PRG030_8CDE ; If Level_Tileset = 15 (bonus game intro), jump to PRG030_8CDE 
01985. JMP PRG030_8DCB ; Jump to PRG030_8DCB 
01986.  
01987. PRG030_8CDE: 
01988. ; Bonus game intro  
01989.  
01990. LDA #$04 
01991. STA BonusText_CharPause ; BonusText_CharPause = $04 
01992. STA Bonus_UnusedFlag ; Bonus_UnusedFlag = $04 
01993.  
01994. ; Set text VRAM pointer to $28C5 
01995. LDA #$28 
01996. STA BonusText_VH 
01997. LDA #$c5 
01998. STA BonusText_VL 
01999.  
02000. LDA #$2b 
02001. STA ToadTalk_VH 
02002. STA PatTable_BankSel+4 ; Load host graphics 
02003.  
02004. LDA #$35 
02005. STA ToadTalk_VL 
02006.  
02007. ; BonusDie_YVel = -$60 
02008. LDA #-$60 
02009. STA <BonusDie_YVel 
02010.  
02011. ; Set the die to Y = $78, X = $78 
02012. LDA #$78 
02013. STA <BonusDie_Y 
02014. STA <BonusDie_X 
02015.  
02016. ; Queue the bonus music 
02017. LDA #MUS2A_BONUSGAME 
02018. STA Level_MusicQueue 
02019.  
02020. ; The Bonus Game Loop begins here... 
02021.  
02022. BonusGame_Loop: 
02023. JSR GraphicsBuf_Prep_And_WaitVSync ; Wait for VSync 
02024.  
02025. LDA SndCur_Map 
02026. AND #SND_MAPENTERLEVEL 
02027. BNE PRG030_8D23 ; If the "entering" sound is still playing, jump to PRG030_8D23 
02028.  
02029. LDA Level_MusicQueue 
02030. BEQ PRG030_8D23 ; If nothing is in the music queue, jump to PRG030_8D23 
02031.  
02032. ; Start the queued music 
02033. STA Sound_QMusic2 
02034.  
02035. ; Clear the music queue 
02036. LDA #$00 
02037. STA Level_MusicQueue 
02038.  
02039. PRG030_8D23: 
02040. JSR BonusGame_Do ; Run the Bonus Game 
02041. JSR StatusBar_Fill_Score ; Update score 
02042.  
02043. LDA <Level_ExitToMap 
02044. BEQ BonusGame_Loop ; If Level_ExitToMap = 0, loop!! 
02045.  
02046. ; Exiting the Bonus Game loop... 
02047.  
02048. LDA #%00101000 ; use 8x16 sprites, sprites use PT2 (NOTE: No VBlank trigger!) 
02049. STA PPU_CTL1  
02050. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync! 
02051.  
02052. LDA Bonus_GameType 
02053. CMP #BONUS_UNUSED_DDDD 
02054. BNE PRG030_8D43 ; If Bonus_GameType <> BONUS_UNUSED_DDDD (??!), jump to PRG030_8D43 
02055.  
02056. ; BONUS_UNUSED_DDDD (??!) only... 
02057.  
02058. ; Set Bonus_DDDD = 1 (??) 
02059. LDA #$01 
02060. STA Bonus_DDDD 
02061.  
02062. JMP PRG030_8D4A ; Jump to PRG030_8D4A 
02063.  
02064. PRG030_8D43: 
02065. CMP #BONUS_UNUSED_2RETURN 
02066. BNE PRG030_8D4A ; If Bonus_GameType <> BONUS_UNUSED_2RETURN (??!), jump to PRG030_8D4A 
02067.  
02068. ; BONUS_UNUSED_2RETURN (??!) only... 
02069.  
02070. JSR Bonus_Return2_SetMapPos ; Change Player's map position and mark them as having died?? 
02071.  
02072. PRG030_8D4A: 
02073. ; BonusText_CPos = 0 
02074. LDA #$00 
02075. STA BonusText_CPos 
02076. STA Bonus_UnusedFlag ; Bonus_UnusedFlag = 0 
02077.  
02078. ; Set page @ A000 to 26 
02079. LDA #26 
02080. STA PAGE_A000 
02081. JSR PRGROM_Change_A000 
02082.  
02083. JSR Palette_FadeOut ; Fade out 
02084.  
02085. LDA #%00011000 
02086. STA <PPU_CTL2_Copy ; Show BG+Sprites 
02087.  
02088. JSR GraphicsBuf_Prep_And_WaitVSync ; Wait for vertical sync 
02089.  
02090. LDA #$00 
02091. STA PPU_CTL2 ; Most importantly, hide sprites/bg 
02092.  
02093. ; NOTE: This jumps to PRG030_8DC3, which returns to World Map, if the die is face value 1. 
02094. ; Seems like the die face logic for jumping to "Roulette" / "Card" is not implemented. 
02095. LDA Bonus_DieCnt 
02096. BEQ PRG030_8DC3 ; If Bonus_DieCnt = 0 (Face value 1), jump to PRG030_8DC3 
02097.  
02098. LDY #$00 ; Level tileset 0 (World Map) 
02099.  
02100. LDA Bonus_GameType 
02101. CMP #BONUS_SPADE 
02102. BNE PRG030_8D85 ; If Bonus_GameType <> BONUS_SPADE, jump to PRG030_8D85 
02103.  
02104. ; Select palettes 
02105. LDA #$01 
02106. STA PalSel_Tile_Colors 
02107. LDA #$09 
02108. STA PalSel_Obj_Colors 
02109.  
02110. LDY #16 ; Level tileset 16 (Spade) 
02111.  
02112. BNE PRG030_8D95 ; Jump (technically always) to PRG030_8D95 
02113.  
02114. PRG030_8D85: 
02115. CMP #BONUS_NSPADE 
02116. BNE PRG030_8D95 ; If Bonus_GameType <> BONUS_NSPADE, jump to PRG030_8D95 
02117.  
02118. ; Select palettes 
02119. LDA #$02 
02120. STA PalSel_Tile_Colors 
02121. LDA #$0a 
02122. STA PalSel_Obj_Colors 
02123.  
02124. LDY #17 ; Level tileset 17 (N-Spade) 
02125.  
02126. PRG030_8D95: 
02127. STY Level_Tileset ; Update Level_Tileset 
02128. STY Level_BG_Page1_2 ; Use proper BG patterns 
02129.  
02130. CPY #$00 
02131. BEQ PRG030_8DC3 ; If tileset = 0 (exit back to world map :(), jump to PRG030_8DC3 
02132.  
02133.  
02134. ; About to enter Spade / N-Spade game! 
02135.  
02136. ; Stop Update_Select activity temporarily 
02137. INC UpdSel_Disable 
02138.  
02139. ; A little cleanup loop... 
02140.  
02141. ; Clears page 0 addresses $00-$FD, excluding $69-$74 (?) 
02142.  
02143. LDY #$fd ; Y = $FD 
02144. LDA #$00 ; A = 0 
02145. PRG030_BDA6: 
02146. STA Temp_Var1,Y ; Clear this byte 
02147.  
02148. PRG030_BDA9: 
02149. DEY ; Y-- 
02150.  
02151. CPY #World_Map_Y 
02152. BGE PRG030_8DB2 ; If Y >= World_Map_Y, jump to PRG030_8DB2 
02153.  
02154. ; Range between $69-$74 is not cleared ... mainly protecting sound engine I think 
02155.  
02156. CPY #Video_Upd_AddrL 
02157. BGE PRG030_BDA9 ; If Y >= Video_Upd_AddrL, jump to PRG030_BDA9 
02158. PRG030_8DB2:  
02159. CPY #$ff 
02160. BNE PRG030_BDA6 ; If Y <> $FF (underflow), loop! 
02161.  
02162.  
02163. ; Clears memory $0400-$04CF (mainly Bonus game cleanup) 
02164. LDY #$cf ; Y = $CF 
02165. PRG030_8DB8: 
02166. STA Roulette_Pos,Y ; Clear this byte 
02167.  
02168. DEY ; Y-- 
02169. CPY #$ff 
02170. BNE PRG030_8DB8 ; If Y <> $FF (underflow), loop! 
02171.  
02172. JMP PRG030_897B ; Jump to PRG030_897B 
02173.  
02174. PRG030_8DC3: 
02175.  
02176. ; Exiting to world map... 
02177.  
02178. ; Bonus_DieCnt = 0 
02179. LDA #$00 
02180. STA Bonus_DieCnt 
02181.  
02182. JMP PRG030_8FA8 ; Jump to PRG030_8FA8 (proceed back to World Map) 
02183.  
02184. PRG030_8DCB: 
02185. LDY Level_Tileset 
02186. CPY #$05 
02187. BNE Level_MainLoop ; If Level_Tileset <> 5 (pipe world plant infestation), jump to Level_MainLoop 
02188.  
02189. LDA PlantInfest_ACnt_MaxConst ; A = [PlantInfest_ACnt_MaxConst] ($1A) (weird specific read??) 
02190. STA PlantInfest_ACnt_Max ; PlantInfest_ACnt_Max = [PlantInfest_ACnt_MaxConst] ($1A) 
02191.  
02192.  
02193.  
02194. ; LEVEL MAIN LOOP BEGIN! 
02195.  
02196. Level_MainLoop: 
02197. JSR GraphicsBuf_Prep_And_WaitVSync 
02198.  
02199. LDA SndCur_Map 
02200. AND #$04  
02201. BNE PRG030_8DF4 ; If enter level sound is still playing, jump to PRG030_8DF4 
02202.  
02203. LDA Level_MusicQueue 
02204. BEQ PRG030_8DF4 ; If Music Queue is empty, jump to PRG030_8DF4 
02205.  
02206. CMP SndCur_Music2 
02207. BEQ PRG030_8DEF ; If we're queueing the BGM already playing, jump to PRG030_8DEF (don't re-queue) 
02208.  
02209. STA Sound_QMusic2 ; Queue the song that's waiting in Level_MusicQueue 
02210.  
02211. PRG030_8DEF: 
02212. LDA #$00 
02213. STA Level_MusicQueue ; Queue is emptied 
02214.  
02215. PRG030_8DF4: 
02216. LDA Level_TimerEn 
02217. BMI PRG030_8E2E ; If bit 7 is set (animations disabled), jump to PRG030_8E2E 
02218.  
02219. LDY Level_Tileset 
02220. CPY #$05  
02221. BNE PRG030_8E1D ; If Level_Tileset <> 5 (pipe world plant infestation), jump to PRG030_8E1D 
02222.  
02223.  
02224. ; PLANT INFESTATION ALTERNATE ANIMATION 
02225.  
02226. ; Specific animation style for the pirhana plant world thing in World 7 
02227. LDA <Counter_1 
02228. AND #$07 
02229. BNE PRG030_8E2E ; Only update every 8 ticks (otherwise, nothing) 
02230.  
02231. INC <PlantInfest_ACnt ; PlantInfest_ACnt++ 
02232.  
02233. LDA <PlantInfest_ACnt 
02234. CMP PlantInfest_ACnt_Max 
02235. BNE PRG030_8E13 ; If PlantInfest_ACnt <> PlantInfest_ACnt_Max, jump to PRG030_8E13 
02236.  
02237. LDA #$00  
02238. STA <PlantInfest_ACnt ; PlantInfest_ACnt = 0 
02239.  
02240. PRG030_8E13: 
02241.  
02242. ; Set proper VROM for this animation count of the plant infestation animation 
02243. TAY ; Y = PlantInfest_ACnt 
02244. LDA PlantInfest_PatTablePerACnt,Y 
02245. STA PatTable_BankSel+1 
02246.  
02247. JMP PRG030_8E5D ; Jump to PlantInfest_ACnt 
02248.  
02249. PRG030_8E1D: 
02250. CPY #$07 
02251. BNE PRG030_8E24 ; If Level_Tileset <> 7 (Toad House), jump to PRG030_8E24 
02252. JMP PRG030_8EAD ; Toad House's also do not use the standard animations 
02253.  
02254. PRG030_8E24: 
02255. ; NOT TOAD HOUSE 
02256.  
02257. LDA Level_PSwitchCnt 
02258. BEQ PRG030_8E31 ; If P-Switch is not active, jump to PRG030_8E31 
02259.  
02260. ; Otherwise force pattern override to $3E 
02261. LDA #$3e 
02262. STA PatTable_BankSel+1 
02263.  
02264. PRG030_8E2E: 
02265. JMP PRG030_8E5D ; Jump to PRG030_8E5D (skip main anim code) 
02266.  
02267. PRG030_8E31: 
02268. CPY #10 
02269. BNE PRG030_8E4F ; If Level_Tileset <> 10 (Airship), jump to PRG030_8E4F 
02270.  
02271. ; AIRSHIP ONLY 
02272.  
02273. LDY PatTable_BankSel+1 
02274. CPY #$6a  
02275. BEQ PRG030_8E5D ; If the current animation active pattern table is $6A (Airship standard), jump to PRG030_8E5D (do nothing) 
02276.  
02277. ; Otherwise... 
02278. LDA <Counter_1 
02279. AND #$03  
02280. BNE PRG030_8E5D ; Only update every 4 ticks (otherwise nothing, jump to PRG030_8E5D) 
02281.  
02282. INY 
02283. INY ; +2 pattern tables 
02284.  
02285. CPY #$76  
02286. BNE PRG030_8E4A ; If we're at $76, jump to PRG030_8E4A 
02287.  
02288. LDY #$70 ; Otherwise, use $70 
02289.  
02290. PRG030_8E4A: 
02291. STY PatTable_BankSel+1 ; Update active pattern table 
02292. BNE PRG030_8E5D ; Jump (technically always) to PRG030_8E5D 
02293.  
02294. PRG030_8E4F: 
02295. ; REGULAR LEVEL ANIMATIONS 
02296.  
02297. LDA <Counter_1 
02298. AND #$18 
02299. LSR A  
02300. LSR A  
02301. LSR A  
02302. TAX ; 0-3, changing every 8 ticks 
02303.  
02304. LDA PT2_Anim,X  
02305. STA PatTable_BankSel+1 ; Set pattern for this tick 
02306.  
02307. PRG030_8E5D: 
02308. ; End of animations... 
02309.  
02310. LDA SndCur_Pause 
02311. BNE PRG030_8E79 ; Can't unpause game while pause sound is playing 
02312.  
02313. LDA <Pad_Input  
02314. AND #PAD_START 
02315. BEQ PRG030_8E79 ; If Player is NOT pressing START, jump to PRG030_8E79 
02316.  
02317. LDX #PAUSE_STOPMUSIC ; for Sound_QPause, pause sound 
02318.  
02319. LDA Level_PauseFlag 
02320. EOR #$01  
02321. STA Level_PauseFlag ; Toggle pause flag 
02322.  
02323. BNE PRG030_8E76 ; If game is now paused, jump to PRG030_8E76 
02324.  
02325. LDX #PAUSE_RESUMEMUSIC ; for Sound_QPause, resume sound 
02326.  
02327. PRG030_8E76: 
02328. STX Sound_QPause ; Set appropriately 
02329.  
02330. PRG030_8E79: 
02331. LDA Level_PauseFlag 
02332. BEQ PRG030_8EAD ; If not paused, jump to PRG030_8EAD 
02333.  
02334. ; When game is paused... 
02335.  
02336. ; Wow, what the heck did they remove here?? 
02337. NOP 
02338. NOP 
02339. NOP 
02340. NOP 
02341. NOP 
02342. NOP 
02343. NOP 
02344. NOP 
02345. NOP 
02346. NOP 
02347. NOP 
02348. NOP 
02349. NOP 
02350. NOP 
02351. NOP 
02352. NOP 
02353. NOP 
02354. NOP 
02355. NOP 
02356. NOP 
02357. NOP 
02358.  
02359. LDA #$32 
02360. STA PatTable_BankSel+5 ; Set patterns needed for P A U S E sprites 
02361.  
02362. JSR Sprite_RAM_Clear ; Clear other sprites 
02363.  
02364. ; Copy in the P A U S E sprites 
02365. LDY #(PAUSE_Sprites_End - PAUSE_Sprites - 1) 
02366. PRG030_8E9D: 
02367. LDA PAUSE_Sprites,Y 
02368. STA Sprite_RAM+$00,Y 
02369. DEY ; Y-- 
02370. BPL PRG030_8E9D ; While Y >= 0, loop! 
02371.  
02372. ; Updates palette 
02373. LDA #$06  
02374. STA <Graphics_Queue 
02375.  
02376. ; Nothing else to do while paused; loop! 
02377. JMP Level_MainLoop 
02378.  
02379.  
02380. PRG030_8EAD: 
02381. ; Not paused! 
02382.  
02383. LDA <Player_IsDying 
02384. BNE PRG030_8ECC ; If Player is dying, jump to PRG030_8ECC 
02385.  
02386. LDY <Scroll_LastDir ; Y = Scroll_LastDir 
02387.  
02388. LDA Level_7Vertical 
02389. BEQ PRG030_8EC3 ; If level is NOT vertical, jump to PRG030_8EC3 
02390.  
02391. ; Forms a value of current "scroll row" in upper 4 bits 
02392. ; and "current screen" in lower 4 bits -> Scroll_Temp 
02393. LDA <Vert_Scroll 
02394. AND #$f0  
02395. ORA <Vert_Scroll_Hi 
02396. STA <Scroll_Temp 
02397.  
02398. JMP PRG030_8EC9 ; Jump to PRG030_8EC9 
02399.  
02400. PRG030_8EC3: 
02401. LDA <Horz_Scroll 
02402. STA <Scroll_Temp ; Scroll_Temp = Horz_Scroll 
02403. LDA <Horz_Scroll_Hi ; A = Horz_Scroll_Hi 
02404.  
02405. PRG030_8EC9: 
02406. JSR Scroll_Update_Ranges 
02407.  
02408. PRG030_8ECC: 
02409. LDA Level_JctCtl  
02410. BEQ PRG030_8EE7 ; If not junctioning, jump to PRG030_8EE7 
02411.  
02412. ; Level junction! 
02413.  
02414. ; Set page @ A000 to 27 
02415. LDA #27 
02416. STA PAGE_A000 
02417. JSR PRGROM_Change_A000 
02418. JSR Setup_PalData 
02419.  
02420. ; Set page @ A000 to 26 
02421. LDA #26 
02422. STA PAGE_A000 
02423. JSR PRGROM_Change_A000 
02424. JMP HandleLevelJunction ; Handle the junction! 
02425.  
02426. PRG030_8EE7: 
02427. ; Not junctioning... 
02428.  
02429. JSR Scroll_Update 
02430.  
02431. LDA #$00 
02432. STA PAGE_C000 ; Load page 0 @ C000 
02433.  
02434. LDA #$00 
02435. STA Level_ScrollDiffH ; Level_ScrollDiffH = 0 
02436. STA Level_ScrollDiffV ; Level_ScrollDiffV = 0 
02437.  
02438. LDA #$08  
02439. STA PAGE_A000 ; Load page 8 @ A000 
02440.  
02441. ; Change both A000/C000 pages! 
02442. JSR PRGROM_Change_Both2 
02443.  
02444. JSR Player_DoGameplay ; Does just about everything that makes the Player in gameplay mode! 
02445.  
02446. LDA <Player_IsDying 
02447. CMP #$03 
02448. BEQ PRG030_8F31 ; If dead due to TIME UP, jump to PRG030_8F31 
02449.  
02450. ; Load page 0 @ C000 
02451. LDA #$00 
02452. STA PAGE_C000 
02453. JSR PRGROM_Change_Both2  
02454.  
02455. JSR Objects_HandleScrollAndUpdate 
02456.  
02457. ; Load page 7 @ A000 
02458. LDY #$07 
02459. STY PAGE_A000 
02460. JSR PRGROM_Change_A000 
02461.  
02462. JSR Scores_GiveAndDraw ; Give point awards and draw score sprites 
02463.  
02464.  
02465. ; Color rotation effects, lava, donut lifts, arrow platforms, 
02466. ; brick busts, water/waterfall visual effects, bubbles, splashes, 
02467. ; pop-up coins, Special Objects, Cannon Fires, Player Projectiles, 
02468. ; and, last but not least (well, maybe least), "shell kill flashes"! 
02469. JSR Gameplay_UpdateAndDrawMisc 
02470.  
02471. LDA Level_HAutoScroll 
02472. BEQ PRG030_8F31 ; If Auto Horizontal Scrolling is NOT active, jump to PRG030_8F31 
02473.  
02474. ; Load page 9 @ A000 
02475. LDA #$09 
02476. STA PAGE_A000 
02477. JSR PRGROM_Change_A000 
02478.  
02479. JSR AutoScroll_Do ; Perform auto scroll, if any 
02480.  
02481. PRG030_8F31: 
02482. LDA <Level_ExitToMap 
02483. BEQ PRG030_8F42 ; If Level_ExitToMap flag is not set, jump to PRG030_8F42 
02484.  
02485. LDX Player_Current ; X = Player_Current 
02486.  
02487. ; Transfer Player's current power up to the World Map counterpart 
02488. LDA <Player_Suit 
02489. STA World_Map_Power,X 
02490.  
02491. ; Level_GetWandState = 0 
02492. LDA #$00 
02493. STA Level_GetWandState 
02494.  
02495. PRG030_8F42: 
02496.  
02497. ; Load page 29 @ C000 
02498. LDA #29 
02499. STA PAGE_C000 
02500. JSR PRGROM_Change_C000 
02501.  
02502. JSR BlockChange_Do ; Do Block Change event, if necessary 
02503.  
02504. ; Load page 0 @ C000 
02505. LDA #$00 
02506. STA PAGE_C000 
02507. JSR PRGROM_Change_C000 
02508.  
02509. ; If scroll updates need to be committed, jump to PRG030_8F80  
02510. LDA Scroll_ToVRAMHi 
02511. BNE PRG030_8F80 
02512. LDA Scroll_ToVRAMHA 
02513. BNE PRG030_8F80 
02514.  
02515. ; No scroll updates need committed... 
02516.  
02517. LDA Level_SkipStatusBarUpd 
02518. BNE PRG030_8F80 ; If requesting we skip the status bar updates for this frame, jump to PRG030_8F80 
02519.  
02520. LDA <Graphics_Queue 
02521. BNE PRG030_8F80 ; If we have a video update to do, skip the status bar updates for this frame, jump to PRG030_8F80 
02522.  
02523. ; Switch bank A000 to page 26 
02524. LDA #26  
02525. STA PAGE_A000 
02526. JSR PRGROM_Change_A000 
02527.  
02528. LDA InvFlip_Counter 
02529. BNE PRG030_8F7D ; If InvFlip_Counter <> 0 (flipping open Inventory), jump to PRG030_8F7D 
02530.  
02531. JSR StatusBar_UpdateValues ; Just update values on the status bar 
02532.  
02533. LDA Inventory_Open 
02534. BEQ PRG030_8F85 ; If Inventory is not open, jump to PRG030_8F85 
02535.  
02536. PRG030_8F7D: 
02537. JSR Map_DoInventory_And_PoofFX ; Do everything with that inventory bar (On page 26) 
02538.  
02539. PRG030_8F80: 
02540.  
02541. ; StatusBar_UpdFl = 0 (we just updated it) 
02542. LDA #$00 
02543. STA StatusBar_UpdFl 
02544.  
02545. PRG030_8F85: 
02546.  
02547. ; Level_SkipStatusBarUpd = 0 (only skip updating for one frame) 
02548. LDA #$00 
02549. STA Level_SkipStatusBarUpd 
02550.  
02551. LDA <Level_ExitToMap 
02552. BEQ PRG030_9006 ; If not exiting to map, jump to PRG030_9006 (Level_MainLoop) 
02553.  
02554. LDX Player_Current ; X = Player_Current 
02555.  
02556. ; Map_Unused749 = 1 (just set here, never read back) 
02557. LDA #$01 
02558. STA Map_Unused749,X 
02559.  
02560. ; Switch bank A000 to page 26 
02561. LDA #26 
02562. STA PAGE_A000 
02563. JSR PRGROM_Change_A000 
02564.  
02565. JSR Palette_FadeOut ; Fade out 
02566.  
02567. PRG030_8FA1: 
02568. LDA #%00011000 
02569. STA <PPU_CTL2_Copy ; Show BG+Sprites 
02570. JSR GraphicsBuf_Prep_And_WaitVSync ; Wait for VSync 
02571.  
02572. PRG030_8FA8: 
02573. ; World_EnterState = 0 
02574. LDA #$00 
02575. STA World_EnterState 
02576.  
02577. ; Disable the display 
02578. STA <PPU_CTL2_Copy 
02579. STA PPU_CTL2  
02580.  
02581. PRG030_8FB2: 
02582. LDA #$01  
02583. STA MMC3_MIRROR ; Set vertical mirroring 
02584.  
02585. LDX Player_Current ; X = LDX Player_Current 
02586.  
02587. LDA Player_FallToKing,X 
02588. BEQ PRG030_8FCA ; If not falling to the King's room, jump to PRG030_8FCA 
02589.  
02590. ; Exiting to King's room... 
02591.  
02592. LDA Map_ReturnStatus 
02593. BNE PRG030_8FCA ; If Player died, jump to PRG030_8FCA 
02594.  
02595. ; Player is alive... 
02596.  
02597. ; Stop Update_Select activity temporarily 
02598. INC UpdSel_Disable 
02599.  
02600. JMP PRG030_88C8 ; Jump to PRG030_88C8 
02601.  
02602. PRG030_8FCA: 
02603. ; Clear $06FF - $0000, excluding $01xx 
02604. LDY #$06 
02605. JSR Clear_RAM_thru_ZeroPage 
02606.  
02607. ; Vert_Scroll_Off = 0 
02608. LDA #$00 
02609. STA Vert_Scroll_Off 
02610.  
02611. ; Stop the music 
02612. LDA #MUS1_STOPMUSIC 
02613. STA Sound_QMusic1 
02614.  
02615. LDA Map_ReturnStatus 
02616. BNE PRG030_8FFC ; If Player died, jump to PRG030_8FFC 
02617.  
02618. LDA Player_RescuePrincess 
02619. BEQ PRG030_8FFC ; If not rescuing the Princess, jump to PRG030_8FFC 
02620.  
02621. ; Load page 24 into A000 and page 25 into C000 
02622. LDA #25 
02623. STA PAGE_C000 
02624. LDA #24 
02625. STA PAGE_A000 
02626. JSR PRGROM_Change_Both2 
02627.  
02628. LDA #%10101000 
02629. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync! 
02630.  
02631. LDA #$20 
02632. STA Update_Select ; Update_Select = $20 (Title Screen... or ending in this case) 
02633.  
02634. JMP Rescue_Princess ; Do the Princess Rescue sequence!! 
02635.  
02636. PRG030_8FFC: 
02637.  
02638. ; Player died or not rescuing the princess... 
02639.  
02640. LDA #%00101000 ; use 8x16 sprites, sprites use PT2 (NOTE: No VBlank trigger!) 
02641. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync! 
02642. STA PPU_CTL1  
02643.  
02644. JMP PRG030_9097 ; Jump to PRG030_9097 
02645.  
02646. PRG030_9006: 
02647. JMP Level_MainLoop ; Gameplay loop! 
02648.  
02649. PRG030_9009: 
02650. ; Player is falling into king's room... 
02651.  
02652. LDA #$c0 
02653. STA Update_Select ; Update_Select = $C0 (Normal) 
02654.  
02655. LDA #$00 
02656. STA Raster_Effect ; Raster_Effect = $00 (Normal status bar) 
02657.  
02658. LDA #$00 
02659. STA World_EnterState ; World_EnterState = 0 
02660. STA <Level_ExitToMap ; Level_ExitToMap = 0 (not going to exit to map) 
02661.  
02662. ; Set page @ A000 to 27 
02663. LDA #27 
02664. STA PAGE_A000 
02665. JSR PRGROM_Change_A000 
02666.  
02667. JSR EndWorldLetter_GenerateText ; Generate the text for the end-of-world letter 
02668.  
02669. ; Resume Update_Select activity 
02670. LDA #$00 
02671. STA UpdSel_Disable 
02672.  
02673. ; Set page @ A000 to 27 
02674. LDA #27 
02675. STA PAGE_A000 
02676. JSR PRGROM_Change_A000 
02677. JSR Setup_PalData ; Setup palette data 
02678.  
02679. ; Switch bank A000 to page 26 
02680. LDA #26 
02681. STA PAGE_A000 
02682. JSR PRGROM_Change_A000 
02683. JSR Palette_FadeIn ; On page 26 -- Fade in 
02684.  
02685. ; Load font graphics 
02686. LDA #$5e 
02687. STA PatTable_BankSel+1 
02688.  
02689. ; Set page @ A000 to 27 
02690. LDA #27 
02691. STA PAGE_A000 
02692. JSR PRGROM_Change_A000 
02693.  
02694. PRG030_904D: 
02695. JSR GraphicsBuf_Prep_And_WaitVSync ; VSync 
02696.  
02697. JSR CineKing_DoWandReturn ; Do the returned wand scene! 
02698.  
02699. LDA <Level_ExitToMap 
02700. BEQ PRG030_904D ; While Level_ExitToMap = 0, loop 
02701.  
02702. ; Clear $06FF - $0000, excluding $01xx 
02703. LDY #$06 
02704. JSR Clear_RAM_thru_ZeroPage 
02705.  
02706. ; Clear some relevant Player values 
02707. LDX Total_Players 
02708. DEX ; X = Total_Players - 1 
02709. LDA #$00 ; Clear value 
02710. PRG030_9062: 
02711. STA Player_FallToKing,X 
02712. STA Map_ReturnStatus 
02713. STA Map_Prev_XOff,X 
02714. STA Map_Prev_XHi,X 
02715.  
02716. DEX ; X-- 
02717. BPL PRG030_9062 ; While X >= 0, loop 
02718.  
02719. LDX Player_Current ; X = current Player index 
02720.  
02721. LDA #(Inventory_Score - Inventory_Items) ; Mario's score 
02722.  
02723. CPX #$00 
02724. BEQ PRG030_907D ; If Player is Mario, jump to PRG030_907D 
02725. ADD #(Inventory_Score2 - Inventory_Score) ; offset to Luigi's score 
02726. PRG030_907D: 
02727. TAY ; Y = offset to score 
02728.  
02729. LDX #$00 ; X = 0 
02730. PRG030_9080: 
02731. LDA Player_Score,X 
02732. STA Inventory_Items,Y 
02733. INY ; Y++ (next byte of Inventory score) 
02734. INX ; X++ (next byte of Player's score) 
02735. CPX #$03 
02736. BNE PRG030_9080 ; If X <> 3, jump to PRG030_9080 
02737.  
02738. ; Stop any music 
02739. LDA #MUS1_STOPMUSIC 
02740. STA Sound_QMusic1 
02741.  
02742. INC World_Num ; Go to next world! 
02743.  
02744. JMP PRG030_84A0 ; Jump to PRG030_84A0 (initialize the world map!) 
02745.  
02746. PRG030_9097: 
02747.  
02748. ; Exiting to map somehow 
02749.  
02750. LDA #$c0 
02751. STA Update_Select ; Update_Select = $C0 (Normal) 
02752.  
02753. LDA #$00 
02754. STA Raster_Effect ; Raster_Effect = $00 (Normal status bar) 
02755.  
02756.  
02757. ; Need to transfer Player's "gameplay score" to their "inventory" score storage... 
02758.  
02759. LDX Player_Current ; X = Player_Current 
02760.  
02761. LDA #(Inventory_Score - Inventory_Items) ; Offset to Mario's Score 
02762.  
02763. CPX #$00 
02764. BEQ PRG030_90AD ; If Player is Mario, jump to PRG030_90AD 
02765.  
02766. ADD #(Inventory_Items2 - Inventory_Items) ; Offset to Luigi's Score 
02767.  
02768. PRG030_90AD: 
02769. TAY ; -> 'Y' 
02770.  
02771. LDX #$00 ; X = 0 
02772.  
02773. PRG030_90B0: 
02774. LDA Player_Score,X ; Get this byte of score 
02775. STA Inventory_Items,Y ; Transfer into Mario/Luigi's specific score storage 
02776.  
02777. INY ; Y++ (next score storage byte) 
02778. INX ; X++ (next gameplay score byte) 
02779.  
02780. CPX #$03 
02781. BNE PRG030_90B0 ; While X <> 3, loop! 
02782.  
02783. LDA Map_MusicBox_Cnt 
02784. BEQ PRG030_90C4 ; If Map_MusicBox_Cnt = 0, jump to PRG030_90C4 
02785.  
02786. DEC Map_MusicBox_Cnt ; Otherwise, one less turn with music box... 
02787.  
02788. PRG030_90C4: 
02789. LDY #$06 ; Y = 6 
02790.  
02791. LDA Map_ReturnStatus 
02792. BNE PRG030_910C ; If Player died, jump to PRG030_910C 
02793.  
02794. ; Player did not die... 
02795.  
02796. ; Toad House and bonuses jump to PRG030_9128 
02797. LDA Level_Tileset 
02798. CMP #15 
02799. BGE PRG030_9128 ; If Level_Tileset >= 15 (some kind of Bonus Game), jump to PRG030_9128 
02800. CMP #$07 
02801. BEQ PRG030_9128 ; If Level_Tileset = 7 (Toad House), jump to PRG030_9128 
02802.  
02803. ; Typical levels go here... 
02804.  
02805. LDX Player_Current ; X = Player_Current 
02806.  
02807. ; Set bonus appearance coordinates at your last valid location! 
02808. LDA Map_Previous_Y,X 
02809. STA Map_BonusAppY 
02810. LDA Map_Previous_XHi,X 
02811. STA Map_BonusAppXHi 
02812. LDA Map_Previous_X,X 
02813. STA Map_BonusAppX 
02814.  
02815. LDA Map_Entered_Y,X 
02816. STA Map_Previous_Y,X 
02817.  
02818. LDA Map_Entered_XHi,X 
02819. STA Map_Previous_XHi,X 
02820.  
02821. LDA Map_Entered_X,X 
02822. STA Map_Previous_X,X 
02823.  
02824. LDA Map_Prev_XOff,X 
02825. STA Map_Prev_XOff2,X 
02826.  
02827. LDA Map_Prev_XHi,X 
02828. STA Map_Prev_XHi2,X 
02829.  
02830. JMP PRG030_9128 ; Jump to PRG030_9128 
02831.  
02832. PRG030_910C: 
02833.  
02834. ; Player returns to map dead 
02835.  
02836. LDY #$02 ; Y = 2 (Will be the Map_Operation value) 
02837.  
02838. ; Map_ReturnStatus = 0 
02839. LDA #$00 
02840. STA Map_ReturnStatus 
02841.  
02842. ; Clear all Big ? Blocks bits 
02843. STA BigQBlock_GotIt 
02844.  
02845. LDX Player_Current ; X = Player_Current 
02846.  
02847. ; Skid backward 
02848. LDA #$01 
02849. STA Map_Player_SkidBack,X 
02850.  
02851. LDA Map_PlayerLost2PVs 
02852. BNE PRG030_9128 ; If Map_PlayerLost2PVs is set, jump to PRG030_9128 
02853.  
02854. DEC Player_Lives,X ; One less life for the Player... 
02855. BMI PRG030_9133 ; If fell below zero, GAMEOVER!; jump to PRG030_9133 
02856.  
02857. PRG030_9128: 
02858.  
02859. ; Stop any music 
02860. LDA #MUS1_STOPMUSIC 
02861. STA Sound_QMusic1 
02862.  
02863. STY Map_Operation ; Map_Operation = 2 
02864. JMP PRG030_84D7 ; Jump to PRG030_84D7 
02865.  
02866. PRG030_9133: 
02867.  
02868. ; GAME OVER!! 
02869.  
02870. ; Set Player as twirling (in case they Continue...) 
02871. LDA #$01  
02872. STA World_Map_Twirl,X 
02873.  
02874. ; Init map vars 
02875. LDA #$00 
02876. STA Level_Tileset 
02877. STA <Map_EnterLevelFX 
02878. STA <Map_WarpWind_FX 
02879. STA Map_Intro_Tick 
02880.  
02881. ; Map_GameOver_CursorY = $60 
02882. LDA #$60 
02883. STA Map_GameOver_CursorY 
02884.  
02885. PRG030_9149: 
02886. JSR Sprite_RAM_Clear  
02887. JSR Scroll_PPU_Reset  
02888. JSR Reset_PPU_Clear_Nametables 
02889.  
02890. LDA #%00101000 ; use 8x16 sprites, sprites use PT2 (NOTE: No VBlank trigger!) 
02891. STA PPU_CTL1  
02892. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync! 
02893.  
02894. LDA World_EnterState 
02895. BNE PRG030_9163 ; If World_EnterState <> 0, jump to PRG030_9163 
02896.  
02897. ; Otherwise, gotta player the game over music! 
02898. LDA #MUS1_GAMEOVER 
02899. STA Sound_QMusic1 
02900.  
02901. PRG030_9163: 
02902.  
02903. ; Load up graphics 
02904. LDA #$14 
02905. STA PatTable_BankSel 
02906. LDA #$16 
02907. STA PatTable_BankSel+1 
02908. LDX #$20 
02909. STX PatTable_BankSel+2 
02910. INX 
02911. STX PatTable_BankSel+3 
02912. INX 
02913. STX PatTable_BankSel+4 
02914. INX 
02915. STX PatTable_BankSel+5 
02916. JSR SetPages_ByTileset 
02917.  
02918.  
02919. ; Set both Players to their previous map values 
02920. LDX Total_Players 
02921. DEX ; X = Total_Players - 1 
02922.  
02923. PRG030_9185: 
02924. LDA Map_Entered_Y,X 
02925. STA <World_Map_Y,X 
02926. LDA Map_Entered_XHi,X 
02927. STA <World_Map_XHi,X 
02928. LDA Map_Entered_X,X 
02929. STA <World_Map_X,X 
02930. LDA Map_Previous_UnusedPVal2,X 
02931. STA <Map_UnusedPlayerVal2,X 
02932.  
02933. ; Set Player's previous travel direction 
02934. LDA Map_Previous_Dir,X 
02935. STA <World_Map_Dir,X 
02936.  
02937. DEX ; X-- 
02938. BPL PRG030_9185 ; While X >= 0, loop! 
02939.  
02940. JSR Scroll_Map_SpriteBorder ; Keep that map border going! 
02941.  
02942. ; Set page @ A000 to 12 
02943. LDA #12 
02944. STA PAGE_A000 
02945. JSR PRGROM_Change_A000 
02946.  
02947. JSR Map_Reload_with_Completions ; Load map and set already completed levels 
02948.  
02949. LDX Player_Current ; X = Player_Current 
02950.  
02951. ; Set Player's previous movement direction 
02952. LDA Map_Previous_Dir,X 
02953. STA <World_Map_Dir,X 
02954.  
02955. LDA #%00101000 ; use 8x16 sprites, sprites use PT2 (NOTE: No VBlank trigger!) 
02956. STA PPU_CTL1  
02957. STA <PPU_CTL1_Copy ; Keep PPU_CTL1_Copy in sync! 
02958.  
02959. LDY #$00 ; Y = 0 
02960.  
02961. LDA World_Num 
02962. CMP #$07 
02963. BNE PRG030_91D1 ; If World_Num <> 7 (World 8), jump to PRG030_91D1 
02964.  
02965. ; World 8 only... 
02966.  
02967. LDX Player_Current ; X = Player_Current 
02968.  
02969. LDA <World_Map_XHi,X 
02970. CMP #$02 
02971. BNE PRG030_91D1 ; If Player is not on the "dark" part of World 8, jump to PRG030_91D1 
02972.  
02973. INY ; Y = 1 (enable the World 8 darkness) 
02974.  
02975. PRG030_91D1: 
02976. STY World_8_Dark ; Set World_8_Dark appropriately 
02977.  
02978. LDY Player_Current ; Y = Player_Current 
02979.  
02980. ; Scroll updates 
02981. LDA Map_Prev_XOff,Y 
02982. STA <Scroll_Temp 
02983. LDA Map_Prev_XHi,Y 
02984. JSR Scroll_Update_Ranges 
02985.  
02986. LDA <Scroll_ColumnL 
02987. STA <Scroll_ColumnR 
02988.  
02989. ; Scroll_Cols2Upd = 32 (full dirty scroll update sweep) 
02990. LDA #32 
02991. STA Scroll_Cols2Upd 
02992.  
02993. ; This (re)draws the status bar 
02994. LDA #$02 
02995. JSR Video_Do_Update 
02996.  
02997. ; Set page @ A000 to 26 
02998. LDA #26  
02999. STA PAGE_A000 
03000. JSR PRGROM_Change_A000 
03001.  
03002. JSR StatusBar_Update_Cards ; Update status bar cards 
03003. JSR StatusBar_UpdateValues ; Update other status bar stuff 
03004. JSR StatusBar_Fill_MorL ; Patch in correct M or L on status bar 
03005. JSR StatusBar_Fill_World ; Fill in correct world number 
03006.  
03007. LDA #$00 ; A = 0 (Graphics buffer push) 
03008. JSR Video_Do_Update ; Push through what's in graphics buffer 
03009.  
03010. JSR Scroll_Dirty_Update ; Do a full draw of the map tiles 
03011.  
03012. LDA World_8_Dark 
03013. BEQ PRG030_9214 ; If World_8_Dark = 0 (not doing the effect), jump to PRG030_9214 
03014.  
03015. JSR Map_W8DarknessFill ; Fill in the entire screen with black 
03016.  
03017. PRG030_9214: 
03018.  
03019. LDY Player_Current ; Y = Player_Current 
03020.  
03021. LDA Map_Prev_XOff,Y 
03022. STA <Horz_Scroll 
03023. STA <Scroll_Temp 
03024. LDA Map_Prev_XHi,Y 
03025. STA <Horz_Scroll_Hi 
03026. JSR Scroll_Update_Ranges 
03027.  
03028. PRG030_9226: 
03029. JSR Map_DrawAndPan ; Draw and pan map as necessary 
03030.  
03031. LDA #$00 ; A = 0 (Graphics buffer push) 
03032. JSR Video_Do_Update ; Push through what's in graphics buffer 
03033.  
03034. LDA Map_DrawPanState 
03035. BNE PRG030_9226 ; If some kind of map drawing/panning activity is occurring, loop around 
03036.  
03037. LDA World_EnterState 
03038. BNE PRG030_9257 ; If World_EnterState <> 0, jump to PRG030_9257 
03039.  
03040. ; Set page @ A000 to 11 
03041. LDA #11 
03042. STA PAGE_A000 
03043. JSR PRGROM_Change_A000 
03044.  
03045. JSR Map_IntroAttrSave ; Pick up the current attribute info under the box 
03046.  
03047. LDX #$12 ; X = $12 (standard $00 aligned GAME OVER box) 
03048.  
03049. LDA <Horz_Scroll ; A = Horz_Scroll 
03050. BEQ PRG030_924B ; If Horz_Scroll = 0, jump to PRG030_924B 
03051.  
03052. LDX #$13 ; Otherwise, X = $13 (map halfway scroll $80 aligned GAME OVER box) 
03053.  
03054. PRG030_924B: 
03055. TXA ; A = X 
03056. JSR Video_Do_Update ; Draw up the Game Over! box 
03057.  
03058. JSR GameOver_PatchPlayerName ; Add MARIO/LUIGI to gameover box 
03059.  
03060. LDA #$00 ; A = 0 (Graphics buffer push) 
03061. JSR Video_Do_Update ; Push through what's in graphics buffer 
03062.  
03063. PRG030_9257: 
03064. LDA #$ef  
03065. STA <Vert_Scroll ; Vert_Scroll = $EF (map always stays at this height) 
03066.  
03067. LDA #$c0  
03068. STA Update_Select ; Update_Select = $C0 (Normal) 
03069.  
03070. ; Switch bank A000 to page 27 
03071. LDA #27 
03072. STA PAGE_A000 
03073. JSR PRGROM_Change_A000 
03074. JSR Setup_PalData ; On page 27 -- PalData now holds palette data for world map tiles/objects 
03075.  
03076. ; Switch bank A000 to page 26 
03077. LDA #26 
03078. STA PAGE_A000 
03079. JSR PRGROM_Change_A000 
03080. JSR Palette_FadeIn ; On page 26 -- Fade in the world map 
03081.  
03082. ; Switch bank A000 to page 11 
03083. LDA #11  
03084. STA PAGE_A000  
03085. JSR PRGROM_Change_A000 
03086.  
03087. PRG030_927E: 
03088. JSR GraphicsBuf_Prep_And_WaitVSync ; This is probably just using it to VSync 
03089. JSR Sprite_RAM_Clear ; Clear sprites! 
03090. JSR GameOver_Loop ; Do Gameover stuff 
03091. JSR World5_Sky_AddCloudDeco ; World 5 sky area gets an extra cloud sprite (strange?) 
03092.  
03093. LDA GameOver_State 
03094.  
03095. CMP #$06 
03096. BEQ PRG030_929C ; If GameOver_State = 6 (Player aligning to start panel Y), jump to PRG030_929C 
03097.  
03098. CMP #$09 
03099. BNE PRG030_927E ; If GameOver_State <> 9 (Player did not choose to END), jump to PRG030_927E (loop around) 
03100.  
03101. ; Player chose to END... 
03102.  
03103. LDA Total_Players 
03104. CMP #$01 
03105. BEQ PRG030_92B6 ; If Total_Players = 1, jump to PRG030_92B6 
03106.  
03107. ; More than 2 Players 
03108.  
03109. PRG030_929C: 
03110.  
03111. ; Stop music 
03112. LDA #MUS1_STOPMUSIC 
03113. STA Sound_QMusic1 
03114.  
03115. ; Switch bank A000 to page 26 
03116. LDA #26 
03117. STA PAGE_A000 
03118. JSR PRGROM_Change_A000 
03119.  
03120. JSR Palette_FadeOut ; Fade out 
03121.  
03122. LDA GameOver_State 
03123. CMP #$09 
03124. BEQ PRG030_92B6 ; If GameOver_State = 9 (Player chose to END), jump to PRG030_92B6 
03125.  
03126. JMP PRG030_9149 ; Jump to PRG030_9149 
03127.  
03128. PRG030_92B6: 
03129.  
03130. LDA #$00 
03131. STA World_EnterState ; World_EnterState = 0 (just arriving) 
03132.  
03133. LDX Player_Current ; X = Player_Current 
03134.  
03135. LDA Map_GameOver_CursorY 
03136. AND #$08 
03137. BNE PRG030_932A ; If Player chose to END, jump to PRG030_932A 
03138.  
03139. ; Player's live reset to 4 
03140. LDA #$04 
03141. STA Player_Lives,X 
03142.  
03143. ; Set up position variables 
03144. LDA <Horz_Scroll 
03145. STA Map_Prev_XOff,X 
03146. LDA <Horz_Scroll_Hi 
03147. STA Map_Prev_XHi,X 
03148. LDA <World_Map_Y,X 
03149. STA Map_Entered_Y,X 
03150. LDA <World_Map_XHi,X 
03151. STA Map_Entered_XHi,X 
03152. LDA <World_Map_X,X 
03153. STA Map_Entered_X,X 
03154. LDA <Map_UnusedPlayerVal2,X 
03155. STA Map_Previous_UnusedPVal2,X 
03156.  
03157. ; Reset map variables 
03158. LDA #$00 
03159. STA Map_Player_SkidBack,X 
03160. STA World_EnterState 
03161. STA Map_GameOver_CursorY 
03162. STA BigQBlock_GotIt ; Didn't get any Big ? Blocks 
03163.  
03164. LDY #(Inventory_Coins - Inventory_Cards) ; Y = offset to Mario's coins 
03165.  
03166. CPX #$00 
03167. BEQ PRG030_92FE ; If Player is Mario, jump to PRG030_92FE 
03168.  
03169. LDY #(Inventory_Coins2 - Inventory_Cards) ; Y = offset to Luigi's coins 
03170.  
03171. PRG030_92FE: 
03172. LDA #(Inventory_Coins - Inventory_Cards) 
03173. STA <Temp_Var1 ; Temp_Var1 = total bytes to clear 
03174.  
03175. LDA #$00 ; A = 0 
03176. PRG030_9304: 
03177. STA Inventory_Cards,Y ; Clear cards/coins 
03178.  
03179. DEY ; Y-- 
03180. DEC <Temp_Var1 ; Temp_Var1-- 
03181. BPL PRG030_9304 ; While Temp_Var1 >= 0, loop 
03182.  
03183. LDY #$3f ; Y = $3F (End of Mario's Map Completions) 
03184.  
03185. CPX #$00 
03186. BEQ PRG030_9314 ; If Player is Mario, jump to PRG030_9314 
03187.  
03188. LDY #$7f ; Y = $7F (End of Luigi's Map Completions) 
03189.  
03190. PRG030_9314: 
03191. LDA #$3f 
03192. STA <Temp_Var1 ; Temp_Var1 = $3F 
03193.  
03194. PRG030_9318: 
03195. TYA 
03196. EOR #$40 
03197. TAX 
03198.  
03199. ; Clear this Player's map completions 
03200. LDA Map_Completions,X 
03201. AND Map_Completions,Y 
03202. STA Map_Completions,Y 
03203.  
03204. DEY ; Y-- 
03205. DEC <Temp_Var1 ; Temp_Var1-- 
03206. BPL PRG030_9318 ; While Temp_Var1 >= 0, loop! 
03207.  
03208. PRG030_932A: 
03209. LDY Total_Players ; Y = Total_Players 
03210. DEY ; Y = 0 if 1P, or 1 if 2P 
03211.  
03212. PRG030_932E: 
03213. LDA Player_Lives,Y 
03214. BPL PRG030_933E ; If this Player isn't dead, jump to PRG030_933E 
03215.  
03216. DEY ; Y-- 
03217. BPL PRG030_932E ; While Y >= 0, loop 
03218.  
03219. ; All Players are dead and have given up 
03220.  
03221. ; Stop music 
03222. LDA #MUS1_STOPMUSIC 
03223. STA Sound_QMusic1 
03224.  
03225. ; Reset game 
03226. JMP IntReset_Part2 
03227.  
03228. PRG030_933E: 
03229.  
03230. ; A Player gave up, but there's one left 
03231.  
03232. JSR GameOver_PlayerQuitCleanup ; Performs some cleanup work for the Player who left 
03233.  
03234. ; Map_Operation = 0 
03235. LDY #$00 
03236. STY Map_Operation 
03237.  
03238. LDX Player_Current ; X = Player_Current 
03239. JMP PRG030_879B ; Jump to PRG030_879B 
03240.  
03241.  
03242. Do_2PVsChallenge: 
03243.  
03244. ; 2P Vs Challenge! 
03245.  
03246. ; Load page 14 @ C000 
03247. LDA #14 
03248. STA PAGE_C000 
03249. JSR PRGROM_Change_Both2 
03250.  
03251. JSR Scroll_Dirty_Update ; Render the 2P Vs terrain 
03252.  
03253. ; Update_Select = $C0 
03254. LDA #$c0 
03255. STA Update_Select 
03256.  
03257. ; Raster_Effect = $80 
03258. LDA #$80 
03259. STA Raster_Effect 
03260.  
03261. ; Load graphics for 2P Vs 
03262. LDY #$04 
03263. STY PatTable_BankSel+2 
03264. INY 
03265. STY PatTable_BankSel+3 
03266. INY 
03267. STY PatTable_BankSel+4 
03268. INY 
03269. STY PatTable_BankSel+5 
03270.  
03271. ; Play battle (2P Vs) music 
03272. LDA #MUS2B_BATTLE 
03273. STA Level_MusicQueue 
03274.  
03275. ; Set page @ A000 to 27 
03276. LDA #27 
03277. STA PAGE_A000 
03278. JSR PRGROM_Change_A000 
03279.  
03280. JSR Setup_PalData ; On page 27 -- PalData now holds palette data for world map tiles/objects 
03281.  
03282. ; Resume Update_Select activity 
03283. LDA #$00 
03284. STA UpdSel_Disable 
03285.  
03286. ; Set page @ A000 to 26 
03287. LDA #26 
03288. STA PAGE_A000 
03289. JSR PRGROM_Change_A000 
03290. JSR Palette_FadeIn ; On page 26 -- Fade in the world map 
03291.  
03292. ; Set page @ A000 to 9 
03293. LDA #$09 
03294. STA PAGE_A000 
03295. JSR PRGROM_Change_A000 
03296.  
03297. PRG030_939A: 
03298. JSR GraphicsBuf_Prep_And_WaitVSync ; V Sync 
03299.  
03300. LDA SndCur_Map 
03301. AND #SND_MAPENTERLEVEL 
03302. BNE PRG030_93B1 ; If the level entrance sound is still playing, jump to PRG030_93B1 
03303.  
03304. LDA Level_MusicQueue 
03305. BEQ PRG030_93B1 ; If no BGM is queued, jump to PRG030_93B1 
03306.  
03307. ; Play the queued music 
03308. STA Sound_QMusic2 
03309.  
03310. ; Clear music queue 
03311. LDA #$00 
03312. STA Level_MusicQueue 
03313.  
03314. PRG030_93B1: 
03315. JSR Sprite_RAM_Clear ; Clear Sprite RAM  
03316. JSR Vs_2PVsPauseHandler ; Handle pausing 
03317.  
03318. LDA Level_ExitToMap 
03319. BEQ PRG030_939A ; If not exiting to map, loop 2P Vs! 
03320.  
03321. ; Set page @ A000 to 26 
03322. LDA #26 
03323. STA PAGE_A000 
03324. JSR PRGROM_Change_A000 
03325. JSR Palette_FadeOut ; Fade out 
03326.  
03327. ; Stop 2P Vs music 
03328. LDA #MUS1_STOPMUSIC 
03329. STA Sound_QMusic1 
03330.  
03331. LDA #%00011000 
03332. STA <PPU_CTL2_Copy ; Show BG+Sprites 
03333.  
03334. JSR GraphicsBuf_Prep_And_WaitVSync ; Vertical sync 
03335.  
03336. ; Disable display 
03337. LDA #$00 
03338. STA PPU_CTL1 
03339. STA PPU_CTL2 
03340.  
03341. LDX Map_PlayerLost2PVs 
03342. DEX 
03343. CPX Player_Current 
03344. BNE PRG030_93E7 ; If the Player who lost the match was not the Player whose turn it was, jump to PRG030_93E7 
03345.  
03346. JMP PRG030_946C ; Jump to PRG030_946C 
03347.  
03348. PRG030_93E7: 
03349. LDA #(Inventory_Score - Inventory_Items) ; Offset to Mario's score 
03350.  
03351. LDX Player_Current 
03352. BEQ PRG030_93F1 ; If current Player is Mario, jump to PRG030_93F1 
03353.  
03354. ADD #(Inventory_Score2 - Inventory_Score) ; Offset to Luigi's score 
03355.  
03356. PRG030_93F1: 
03357. TAY ; Y = offset to Player's score 
03358.  
03359. LDX #$00 ; X = 0 
03360. PRG030_93F4: 
03361. LDA Inventory_Items,Y 
03362. STA Player_Score,X 
03363.  
03364. INY ; Y++ (next "inventory" score byte) 
03365. INX ; X++ (next "active" score byte) 
03366.  
03367. CPX #$03 
03368. BNE PRG030_93F4 ; While X <> 3, loop! 
03369.  
03370. LDX Map_PlayerLost2PVs 
03371. DEX 
03372. TXA 
03373. EOR #$01 
03374. TAY ; Y = the OTHER Player's index 
03375.  
03376. ; Swap all Player map position variables because the challenger lost! 
03377. LDA Map_Previous_Y,Y 
03378. STA <Temp_Var1 
03379. LDA Map_Previous_XHi,Y 
03380. STA <Temp_Var2 
03381. LDA Map_Previous_X,Y 
03382. STA <Temp_Var3 
03383. LDA Map_Prev_XOff2,Y 
03384. STA <Temp_Var4 
03385. LDA Map_Prev_XHi2,Y 
03386. STA <Temp_Var5 
03387. LDA Map_Prev_XOff,Y 
03388. STA <Temp_Var6 
03389. LDA Map_Prev_XHi,Y 
03390. STA <Temp_Var7 
03391. LDA Map_Previous_Y,X 
03392. STA Map_Previous_Y,Y 
03393. LDA Map_Previous_XHi,X 
03394. STA Map_Previous_XHi,Y 
03395. LDA Map_Previous_X,X 
03396. STA Map_Previous_X,Y 
03397. LDA Map_Prev_XOff2,X 
03398. STA Map_Prev_XOff2,Y 
03399. LDA Map_Prev_XHi2,X 
03400. STA Map_Prev_XHi2,Y 
03401. LDA <Temp_Var1 
03402. STA Map_Previous_Y,X 
03403. LDA <Temp_Var2 
03404. STA Map_Previous_XHi,X 
03405. LDA <Temp_Var3 
03406. STA Map_Previous_X,X 
03407. LDA <Temp_Var4 
03408. STA Map_Prev_XOff2,X 
03409. LDA <Temp_Var5 
03410. STA Map_Prev_XHi2,X 
03411. LDA <Temp_Var6 
03412. STA Map_Prev_XOff,X 
03413. LDA <Temp_Var7 
03414. STA Map_Prev_XHi,X 
03415.  
03416. PRG030_946C: 
03417.  
03418. ; Flag as "death" so challenger flies backward 
03419. LDX Map_PlayerLost2PVs 
03420. STX Map_ReturnStatus 
03421.  
03422. ; Set new current Player 
03423. DEX ; X-- 
03424. STX Player_Current 
03425.  
03426. JMP PRG030_8FB2 ; Jump to PRG030_8FB2 
03427.  
03428. GameOver_WhiteMapObjs: 
03429. .byte MAPOBJ_NSPADE, MAPOBJ_WHITETOADHOUSE, MAPOBJ_UNK0C 
03430.  
03431.  
03432. GameOver_PlayerQuitCleanup: 
03433. LDY Total_Players ; Y = Total_Players 
03434. CPY #$01 
03435. BEQ PRG030_948F ; If only a 1P game, jump to PRG030_948F 
03436.  
03437. ; This is a 2P game 
03438.  
03439. DEY ; Y-- (Y = 1) 
03440. PRG030_9484: 
03441. LDA Player_Lives,Y 
03442. BPL PRG030_948E ; If this is the living Player, jump to PRG030_948E (RTS) 
03443.  
03444. DEY ; Y-- 
03445. BPL PRG030_9484 ; While Y >= 0, loop! 
03446.  
03447. BMI PRG030_948F ; Jump to PRG030_948F 
03448.  
03449. PRG030_948E: 
03450. RTS ; Return 
03451.  
03452. PRG030_948F: 
03453. ; BUG!! Apparently the game is SUPPOSED to delete all  
03454. ; bonus objects after a game over, but code starts with 
03455. ; the wrong index (see immediately below) and that causes 
03456. ; this to not work correctly! Strange, huh? 
03457.  
03458. ; As my brother put it: 
03459. ; "It may have been because of the 2P mode. You can't punish 
03460. ; the other player because one of you sucks bad." 
03461.  
03462. LDX #-$04 ; <-- BUG! BAD INDEX!! (Should be X = 2??) 
03463. PRG030_9491: 
03464. LDY #(MAPOBJ_TOTAL-1) ; Y = (MAPOBJ_TOTAL-1) (all Map Objects) 
03465.  
03466. PRG030_9493: 
03467. LDA Map_Objects_IDs,Y 
03468. BEQ PRG030_94A2 ; If this Map Object is empty, jump to PRG030_94A2 
03469.  
03470. CMP GameOver_WhiteMapObjs,X 
03471. BNE PRG030_94A2 ; If this is NOT one of the "white" objects (White Toad House, Coin Ship, and the ??), jump to PRG030_94A2 
03472.  
03473. ; Delete the bonus objects! You don't deserve them! 
03474.  
03475. LDA #MAPOBJ_EMPTY 
03476. STA Map_Objects_IDs,Y 
03477.  
03478. PRG030_94A2: 
03479. DEY ; Y-- 
03480. BPL PRG030_9493 ; While Y >= 0, loop 
03481.  
03482. DEX ; X-- 
03483. BPL PRG030_9491 ; While X >= 0, loop <-- BUG! This will fail on the first pass! 
03484.  
03485. LDA #$00 
03486. STA Map_NSpade_NextScore ; Highest byte in the N-Spade score = 0 
03487. STA Map_Anchored ; Airship is no longer anchored 
03488.  
03489. ; N-Spade appears every 80,000 points, but the leading zero is fake, so 8000 
03490.  
03491. ; Middle byte of the N-Spade score 
03492. LDA #HIGH(8000) 
03493. STA Map_NSpade_NextScore+1 
03494.  
03495. ; Lowest byte of the N-Spade score 
03496. LDA #LOW(8000) 
03497. STA Map_NSpade_NextScore+2 
03498.  
03499. RTS ; Return 
03500.  
03501.  
03502. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03503. ; SetPages_ByTileset 
03504. ; 
03505. ; This routine uses sets both A000 and C000 pages based on the active Level_Tileset 
03506. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03507. SetPages_ByTileset: ; $94BB 
03508. LDY Level_Tileset ; Y = Level_Tileset 
03509.  
03510. ; Change A000 and C000 pages based on Page_A/C000_List 
03511. LDA PAGE_C000_ByTileset,Y 
03512. STA PAGE_C000 
03513. LDA PAGE_A000_ByTileset,Y 
03514. STA PAGE_A000  
03515. JMP PRGROM_Change_Both2 ; JUMP to page routine, do not continue below... 
03516.  
03517.  
03518. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03519. ; Video_Do_Update 
03520. ; 
03521. ; This very important subroutine takes an index value in 'A' 
03522. ; and sets up to execute one of the Video_Upd_Table updates 
03523. ; to the screen, e.g. A = 2 for the status bar. 
03524. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03525. Video_Do_Update: ; $94CD 
03526. PHA ; Push A 
03527.  
03528. ASL A ; A << 1 (multiply by 2, looks up different address) 
03529. TAY ; Y = A 
03530.  
03531. ; Set update VRAM address high/low 
03532. LDA Video_Upd_Table,Y 
03533. STA <Video_Upd_AddrL 
03534. LDA Video_Upd_Table+1,Y 
03535. STA <Video_Upd_AddrH  
03536.  
03537. ; Set page @ A000 to 26 
03538. LDA #26 
03539. STA PAGE_A000 
03540. JSR PRGROM_Change_A000 
03541.  
03542. JSR Video_Misc_Updates  
03543.  
03544. PLA ; Pop A 
03545.  
03546. BNE PRG030_94EE ; If A <> 0, jump to PRG030_94EE 
03547. STA Graphics_BufCnt ; Clear the buffer counter 
03548. STA Graphics_Buffer ; Immediately terminate the buffer 
03549.  
03550. PRG030_94EE: 
03551. ; Jump into SetPages_ByTileset to "correct" the tables back 
03552. ; (mainly A000) 
03553. JMP SetPages_ByTileset 
03554.  
03555. ; Select the attribute table (which loads 8 bytes into Tile_AttrTable) 
03556. TileAttribute_ByTileset: 
03557. .word Tile_Attributes_TS0 ; 0 - Map 
03558. .word Tile_Attributes_TS1 ; 1 - Plains [15] 
03559. .word Tile_Attributes_TS2 ; 2 - Mini fortress style [21] 
03560. .word Tile_Attributes_TS3 ; 3 - Hills style [16] 
03561. .word Tile_Attributes_TS4_TS12 ; 4 - High-Up style [17] 
03562. .word Tile_Attributes_TS5_TS11_TS13 ; 5 - pipe world plant infestation [19] 
03563. .word Tile_Attributes_TS6_TS7_TS8 ; 6 - Water world [18] 
03564. .word Tile_Attributes_TS6_TS7_TS8 ; 7 - Toad house [18] 
03565. .word Tile_Attributes_TS6_TS7_TS8 ; 8 - Vertical pipe maze [18] 
03566. .word Tile_Attributes_TS9 ; 9 - desert level [20] 
03567. .word Tile_Attributes_TS10 ; 10 - airship [23] 
03568. .word Tile_Attributes_TS5_TS11_TS13 ; 11 - Giant World [19] 
03569. .word Tile_Attributes_TS4_TS12 ; 12 - ice level [17] 
03570. .word Tile_Attributes_TS5_TS11_TS13 ; 13 - coin heaven / sky level [19] 
03571. .word Tile_Attributes_TS14 ; 14 - underground [13] 
03572. .word Tile_Attributes_TS15_TS16_TS17 ; 15 - bonus game intro [22] 
03573. .word Tile_Attributes_TS15_TS16_TS17 ; 16 - spade game sliders [22] 
03574. .word Tile_Attributes_TS15_TS16_TS17 ; 17 - N-spade [22] 
03575. .word Tile_Attributes_TS18 ; 18 - 2P Vs [14] 
03576.  
03577. ; NOT USED Tile Attribute values (not valid either; incomplete set!) 
03578. Tile_Attributes_TS15_TS16_TS17: 
03579. ; Unused space 
03580. .byte $FF, $FF, $FF, $FF 
03581.  
03582.  
03583. Fill_Tile_AttrTable_ByTileset: 
03584. LDA Level_Tileset 
03585. ASL A  
03586. TAY ; Y = Level_Tileset << 1 
03587.  
03588. ; Index into TileAttribute_ByTileset and store address to [Temp_Var2][Temp_Var1] 
03589. LDA TileAttribute_ByTileset,Y 
03590. STA <Temp_Var1  
03591. LDA TileAttribute_ByTileset+1,Y 
03592. STA <Temp_Var2  
03593.  
03594. LDY #$07 ; Y = 7 
03595. PRG030_952C: 
03596. LDA [Temp_Var1],Y  
03597. STA Tile_AttrTable,Y  
03598. DEY ; Y-- 
03599. BPL PRG030_952C ; While Y >= 0, loop! 
03600.  
03601. RTS ; Return 
03602.  
03603. ; This LUTs are for the unused-in-US-release "Box out" effect when a level starts 
03604.  
03605. ; This one selects the appropriate init values for everything 
03606. ; else based on what the vertical start position is... 
03607. BoxOut_ByVStart: .byte $00, $30, $70, $B0, $EF ; Needs to sync with GamePlay_VStart 
03608.  
03609. ; The init values, each column links to an above vertical start position 
03610. BoxOut_InitVAddrH: .byte $21, $22, $23, $28, $29 
03611. BoxOut_InitVAddrL0: .byte $6E, $2E, $2E, $6E, $6E 
03612. BoxOut_InitVAddrL1: .byte $8E, $4E, $4E, $8E, $8E 
03613. BoxOut_InitVAddrL2: .byte $73, $33, $33, $73, $73 
03614. BoxOut_InitVAddrL3: .byte $6D, $2D, $2D, $6D, $6D 
03615.  
03616. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03617. ; Map_Clear_EntTranMem 
03618. ; 
03619. ; Clears memory used by the entrance transition 
03620. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03621. Map_Clear_EntTranMem: 
03622. LDY #$1c ; Y = $1C 
03623. PRG030_9555: 
03624. LDA #$00 ; A = 0 
03625. STA Map_EntTran_VLHalf,Y 
03626. DEY ; Y-- 
03627. BPL PRG030_9555 ; While Y >= 0, loop! 
03628. RTS ; Return 
03629.  
03630.  
03631. BoxOut_SetThisBorderVRAM: 
03632. ; Map_EntTran_VAddrL/H += Map_EntTran_VRAMGap 
03633. LDA Map_EntTran_VAddrL 
03634. ADD Map_EntTran_VRAMGap 
03635. STA Map_EntTran_VAddrL 
03636. LDA Map_EntTran_VAddrH 
03637. ADC #$00 
03638. STA Map_EntTran_VAddrH 
03639.  
03640. LDA Map_EntTran_InitValIdx 
03641. CMP #$04 
03642. BEQ PRG030_95AD ; If the initial index was 4, jump to PRG030_95AD (RTS) 
03643.  
03644. LDA Map_EntTran_Temp 
03645. CMP #$ff  
03646. BNE PRG030_95AD ; If Map_EntTran_Temp <> $FF, jump to PRG030_95AD (RTS) 
03647.  
03648. LDY Map_EntTran_BorderLoop ; Y = current border index (0-3: Top 0, bottom 1, right 2, left 3) 
03649.  
03650. ; Prevent out of range video writes 
03651. LDA Map_EntTran_BVAddrH,Y 
03652. CMP #$28  
03653. BGE PRG030_95AD ; If border's VRAM high address >= $28, jump to PRG030_95AD (RTS) 
03654.  
03655. LDA Map_EntTran_VAddrH 
03656. CMP #$23 
03657. BLT PRG030_95AD ; If border's VRAM high address < $23, jump to PRG030_95AD (RTS) 
03658.  
03659. LDA Map_EntTran_VAddrL 
03660. CMP #$c0 
03661. BLT PRG030_95AD ; If border's VRAM low address < $C0, jump to PRG030_95AD (RTS) 
03662.  
03663. ; Set VRAM address to [$28][Map_EntTran_BVAddrL & $1f] 
03664. LDA #$28 
03665. STA Map_EntTran_VAddrH 
03666.  
03667. LDA Map_EntTran_VAddrL 
03668. AND #$1f 
03669. STA Map_EntTran_VAddrL 
03670.  
03671. LDA Map_EntTran_BorderLoop ; A = current border index (0-3: Top 0, bottom 1, right 2, left 3) 
03672. AND #$02  
03673. BEQ PRG030_95AD ; If not doing right side update, jump to PRG030_95AD (RTS) 
03674.  
03675. STX Map_EntTran_Temp ; Store X (LRCnt) into Map_EntTran_Temp 
03676.  
03677. PRG030_95AD: 
03678. RTS ; Return 
03679.  
03680.  
03681. ; As part of the "boxing out" effect, calculate adjusted VRAM  
03682. ; addresses as fit to the arbitrary positioning of the screen 
03683. BoxOut_CalcOffsets: 
03684. ; I'll let someone else figure this out in particular, 
03685. ; I'm not as concerned about a removed effect... 
03686.  
03687. LDA Map_EntTran_VAddrL 
03688. AND #$c0 
03689. STA Map_EntTran_TileOff 
03690.  
03691. LDA Map_EntTran_VAddrH 
03692. AND #$0f 
03693. STA Map_EntTran_VAddrHAdj 
03694.  
03695. CLC 
03696. ROR Map_EntTran_VAddrHAdj 
03697. ROR Map_EntTran_TileOff 
03698. CLC 
03699. ROR Map_EntTran_VAddrHAdj 
03700. ROR Map_EntTran_TileOff 
03701. LDA Map_EntTran_VAddrL 
03702. AND #$1f 
03703. LSR A  
03704. ADD Map_EntTran_TileOff 
03705. STA Map_EntTran_TileOff 
03706.  
03707. RTS ; Return 
03708.  
03709.  
03710. ; Determine which 8x8 of the tile layout we're going to need 
03711. BoxOut_CalcWhich8x8: 
03712. LDA Map_EntTran_VAddrL 
03713. AND #$01 
03714. STA Map_EntTran_Tile8x8 
03715.  
03716. LDA Map_EntTran_VAddrL 
03717. AND #$20  
03718. BNE PRG030_95EF  
03719.  
03720. ASL Map_EntTran_Tile8x8 
03721. JMP PRG030_95F3 ; Jump to PRG030_95F3 
03722.  
03723. PRG030_95EF:  
03724. SEC  
03725. ROL Map_EntTran_Tile8x8 
03726.  
03727. PRG030_95F3: 
03728. RTS ; Return 
03729.  
03730. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03731. ; Map_Calc_NT2Addr_By_XY 
03732. ; 
03733. ; This calculates the Nametable 2 address where a modification 
03734. ; is about to take place (e.g. when a hammer has broken a rock) 
03735. ; X = X coordinate on map (e.g. MapPoof_X) 
03736. ; A = Y coordinate on map (e.g. MapPoof_Y) 
03737. ; 
03738. ; High byte of address is in Temp_Var15 
03739. ; Low byte of address is in Temp_Var16 
03740. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03741. Map_Calc_NT2Addr_By_XY: 
03742.  
03743. ; This rearranges 'A' such that the two highest bits become 
03744. ; the two lowest bits, and the other 6 are shifted up. 
03745. ; Basically a ROL without the carry being involved 
03746. ASL A 
03747. ADC #$00 
03748. ASL A  
03749. ADC #$00 
03750. STA <Temp_Var13 ; Stored into Temp_Var13 
03751.  
03752. TXA ; A = X coordinate 
03753. LSR A 
03754. LSR A 
03755. LSR A 
03756. STA <Temp_Var14 ; Temp_Var14 = X coord >> 3 
03757.  
03758. LDA <Temp_Var13 ; A = Temp_Var13 
03759. AND #%11 ; Get just the lower 2 bits (which are the upper 2 bits of Y coordinate) 
03760. ORA #$28 ; OR $28 (upper byte of video address for Nametable 2) 
03761. STA <Temp_Var15 ; Store into Temp_Var15 
03762.  
03763. LDA <Temp_Var13 ; A = Temp_Var13 
03764. AND #%11000000 ; Get just the upper 2 bits of Temp_Var13 
03765. ORA <Temp_Var14 ; OR in Temp_Var14 
03766. STA <Temp_Var16 ; Store into Temp_Var16 
03767.  
03768. RTS ; Return 
03769.  
03770.  
03771. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03772. ; Bonus_Prize1 
03773. ; 
03774. ; FOR UNUSED BONUS GAMES 
03775. ; This is the routine used to give a prize for a roll of "2" on the die 
03776. ; It's not completely clear what was intended, but that might be because 
03777. ; the memory it is manipulating used to be something else once... 
03778. ; 
03779. ; It uses Inventory_Cards as the base but the only use of "Bonus_Prize1" 
03780. ; is the lost bonus game die and it uses an input value of X = 3, which 
03781. ; ultimately means we edit the first byte of Inventory_Score instead. 
03782. ; But not in a "safe" way with carried arithmetic etc... which makes me 
03783. ; think that memory space was once home to some other idea... 
03784. ; And not that it'd make sense to "increment" your card storage either!! 
03785. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03786. Bonus_Prize1: 
03787.  
03788. ; Backup Y/X 
03789. TYA 
03790. PHA 
03791. TXA 
03792. PHA 
03793.  
03794. ; Temp_Var16 = 0 (offset to Mario's Inventory) 
03795. LDA #$00 
03796. STA <Temp_Var16 
03797.  
03798. LDY Player_Current 
03799. CPY #$00 
03800. BEQ PRG030_962C ; If Player is Mario, jump to PRG030_962C 
03801.  
03802. PRG030_9622: 
03803. ; Offset to Luigi's Inventory 
03804. LDA <Temp_Var16 
03805. ADD #(Inventory_Items2 - Inventory_Items) 
03806. STA <Temp_Var16 
03807.  
03808. DEY ; Y will equal 1 here, so this just makes Y zero 
03809. BNE PRG030_9622 ; Jump technically NEVER to PRG030_9622 (?!) 
03810.  
03811. PRG030_962C: 
03812. TXA ; Input value -> 'A' 
03813.  
03814. ADD <Temp_Var16 ; Add to offset value 
03815. TAX ; -> 'X' 
03816.  
03817. INC Inventory_Cards,X ; The intention of this is unclear! 
03818.  
03819. ; Restore X/Y 
03820. PLA 
03821. TAX 
03822. PLA 
03823. TAY 
03824.  
03825. RTS ; Return 
03826.  
03827. BoxOut_PutPatternInStrip: 
03828. JSR BoxOut_CalcOffsets ; Calculate offset to tile 
03829. JSR BoxOut_CalcWhich8x8 ; Calculate which 8x8 pattern of the tile layout we're going to use 
03830.  
03831. LDA Level_7Vertical 
03832. BEQ PRG030_9654 ; If level is not vertical, jump to PRG030_9654 
03833.  
03834. LDY Level_SizeOrig 
03835.  
03836. ; Correct base address for vertical levels 
03837. LDA Tile_Mem_AddrVL,Y 
03838. STA <Map_Tile_AddrL 
03839. LDA Tile_Mem_AddrVH,Y 
03840. STA <Map_Tile_AddrH 
03841.  
03842. JMP PRG030_965E ; Jump to PRG030_965E 
03843.  
03844. PRG030_9654: 
03845. ; Correct base address for non-vertical levels 
03846. LDA Tile_Mem_Addr 
03847. STA <Map_Tile_AddrL 
03848. LDA Tile_Mem_Addr+1 
03849. STA <Map_Tile_AddrH 
03850.  
03851. PRG030_965E: 
03852. LDA Map_EntTran_VAddrH 
03853. AND #$08  
03854. BEQ PRG030_966C ; If "high" address is not halfway through vertically, jump to PRG030_966C 
03855.  
03856. ; Otherwise, offset halfway through screen 
03857. LDA <Map_Tile_AddrL 
03858. ADD #$f0 
03859. STA <Map_Tile_AddrL ; Map_Tile_AddrL += $F0 
03860.  
03861. PRG030_966C: 
03862. LDA Level_Tileset 
03863. ASL A  
03864. TAY  
03865.  
03866. ; Set Temp_Var13/14 to point to the layout data for this Tileset 
03867. LDA TileLayout_ByTileset,Y 
03868. STA <Temp_Var13  
03869. LDA TileLayout_ByTileset+1,Y 
03870. STA <Temp_Var14  
03871.  
03872. LDY Map_EntTran_TileOff 
03873. LDA [Map_Tile_AddrL],Y ; Get the tile we're working on 
03874.  
03875. TAY  
03876. LDA Map_EntTran_Tile8x8 
03877. ADD <Temp_Var14  
03878. STA <Temp_Var14  
03879. LDA [Temp_Var13],Y ; Get the specific 8x8 tile of the tile we're working on 
03880.  
03881. STA <Scroll_ColorStrip,X ; Store into the strip 
03882. RTS ; Return 
03883.  
03884. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03885. ; Scroll_Update_Ranges 
03886. ; 
03887. ; This subroutine updates Scroll_ColumnL/R based on 
03888. ; where the screen has currently scrolled to... 
03889. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03890. Scroll_Update_Ranges:  
03891. LDY Level_7Vertical 
03892. BNE PRG030_96A5 ; If Level_7Vertical, jump to PRG030_96A5 
03893.  
03894. ; Non-vertical map 
03895. ; Expected that 'A' is currently set to the "Hi byte" of the X Scroll coordinate 
03896.  
03897. ; This loop puts the lower 4 bits of the "hi byte" X into the  
03898. ; upper 4 bits of Scroll_Temp, and shifts Scroll_Temp 4 bits down... or basically, 
03899. ; Scroll_Temp = (Scroll_Temp >> 4) | (A << 4) 
03900.  
03901. ; Most importantly, this has taken a pixel-based scroll X and a "high byte" of X 
03902. ; scroll and combined them into a reduced accuracy (column-based) value of where 
03903. ; we're at horizontally... 
03904. LDX #$03 ; X = 3 
03905. PRG030_9695: 
03906. LSR A ; Pushes the LSb -> Carry 
03907. ROR <Scroll_Temp ; Shift everything in Scroll_Temp to the right, and pull in the carry 
03908. DEX ; X-- 
03909. BPL PRG030_9695 ; If X >= 0, loop! 
03910.  
03911. LDA <Scroll_Temp ; A = result from loop... 
03912. STA <Scroll_ColumnL ; Store as the current "left side" column 
03913. ADD #16  
03914. STA <Scroll_ColumnR ; Scroll_ColumnR = Scroll_ColumnL + 16 (always -- 256/16 = 16 columns spanning the screen) 
03915. RTS ; Return! 
03916.  
03917. PRG030_96A5: 
03918. ; Vertical level 
03919.  
03920. LDA <Scroll_Temp 
03921. BEQ PRG030_96B7 ; If Scroll_Temp = 0, jump to PRG030_96B7 
03922.  
03923. SUB #16  
03924. STA <Scroll_Temp ; Scroll_Temp -= 16 
03925.  
03926. CMP #$f0  
03927. BLT PRG030_96B7 ; If Scroll_Temp < $F0 (would only happen if it was previously $00-$0F), jump to PRG030_96B7 
03928.  
03929. SUB #17 
03930. STA <Scroll_Temp ; Scroll_Temp -= 17 
03931.  
03932. PRG030_96B7: 
03933. LDA <Scroll_Temp  
03934. STA <Scroll_VOffsetT ; Scroll_VOffsetT = Scroll_Temp 
03935.  
03936. ; Calculate bottom tile row offset 
03937.  
03938. ADD #$e0 ; A = Scroll_Temp + $E0 
03939. BCC PRG030_96C2 ; If no carry occurred, jump to PRG030_96C2 
03940.  
03941. ADC #$10 ; A = Scroll_Temp + $F0 
03942.  
03943. PRG030_96C2: 
03944. CMP #$f0  
03945. BLT PRG030_96CB ; If A < $F0, jump to PRG030_96CB 
03946. AND #$0f ; A &= $F 
03947. ADD #$01 ; A += 1 
03948.  
03949. PRG030_96CB: 
03950. STA <Scroll_VOffsetB ; Update Scroll_VOffsetB 
03951. RTS ; Return! 
03952.  
03953. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03954. ; Clear_RAM_thru_ZeroPage 
03955. ;  
03956. ; Starting at the page provided in Y, this will clear everything 
03957. ; (except the stack space) $YY00 to $0000 
03958. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03959. Clear_RAM_thru_ZeroPage: 
03960. STY <Temp_Var2 ; Save Y in <Temp_Var2 
03961. LDY #$00 ; Y = 0 
03962. STY <Temp_Var1 ; Clear <Temp_Var1 
03963. TYA ; A = 0 
03964.  
03965. ; Y is the initial input as the high byte of the address 
03966. ; low first then high, so [Temp_Var2][Temp_Var1] 
03967. PRG030_96D5: 
03968. LDX <Temp_Var2 ; X = current high byte of address in this case 
03969. CPX #$01 ; If we've reached the $01xx bank... 
03970. BEQ PRG030_96DD ; ... skip the next line (don't clear the stack space!) 
03971. STA [Temp_Var1],Y ; Otherwise, clear this byte 
03972. PRG030_96DD: 
03973. DEY ; Y-- 
03974. BNE PRG030_96D5 ; While Y <> 0, loop around again (goes $00, $FF, $FE, ... back to $00) again 
03975. DEC <Temp_Var2 ; Next lower bank 
03976. BPL PRG030_96D5 ; While we're >= bank $00 
03977. RTS ; Return 
03978.  
03979. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03980. ; GraphicsBuf_Prep_And_WaitVSync 
03981. ; 
03982. ; This subroutine takes Graphics_Queue and loads and address 
03983. ; from Video_Upd_Table into the Video_Upd_Addr, then waits for 
03984. ; a VBlank cycle to occur via reading the VBlank_Tick after 
03985. ; force-setting it to zero. This gets the system into a state 
03986. ; where it can actually apply the update! 
03987. ; 
03988. ; See also GraphicsBuf_Prep_And_WaitVSyn2 in PRG024 
03989. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
03990. GraphicsBuf_Prep_And_WaitVSync: ; 96E5 
03991. LDA <Graphics_Queue 
03992. ASL A  
03993. TAY ; Y = Graphics_Queue * 2 
03994.  
03995. ; Get the address where the video update data is 
03996. LDA Video_Upd_Table,Y 
03997. STA <Video_Upd_AddrL 
03998. LDA Video_Upd_Table+1,Y 
03999. STA <Video_Upd_AddrH  
04000.  
04001. LDA #$01  
04002. STA <VBlank_TickEn ; Enable the VBlank tick 
04003. LDA #$00  
04004. STA <VBlank_Tick ; Force VBlank_Tick = 0, so we know when a VBlank has occurred 
04005.  
04006. ; Waiting for VBlank... 
04007. PRG030_96FB: 
04008. LDA <VBlank_Tick 
04009. BPL PRG030_96FB  
04010.  
04011. LDA #$00  
04012. STA <VBlank_TickEn ; Disable the VBlank 
04013.  
04014. CLI ; Enable further masked interrupts 
04015. RTS ; Return 
04016.  
04017.  
04018. ; Tile_Mem_ClearA/B form a way to rapidly clear all of the tile 
04019. ; memory to a specific value (A), used in conjunction with the 
04020. ; proper iterative loop... 
04021.  
04022. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04023. ; Tile_Mem_ClearA 
04024. ; 
04025. ; $1B0 is the size of one screen, so this essentially writes to the 
04026. ; same place on all screens, offset by 'Y'. Unfortunately since  
04027. ; one screen is $1B0, 'Y' cannot cover the entire space, so we have 
04028. ; Tile_Mem_ClearB with a different offset... 
04029. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04030. Tile_Mem_ClearA: ; $9705 
04031. STA Tile_Mem,Y  
04032. STA Tile_Mem+$1B0,Y 
04033. STA Tile_Mem+$360,Y 
04034. STA Tile_Mem+$510,Y 
04035. STA Tile_Mem+$6C0,Y 
04036. STA Tile_Mem+$870,Y 
04037. STA Tile_Mem+$A20,Y 
04038. STA Tile_Mem+$BD0,Y 
04039. STA Tile_Mem+$D80,Y 
04040. STA Tile_Mem+$F30,Y 
04041. STA Tile_Mem+$10E0,Y 
04042. STA Tile_Mem+$1290,Y 
04043. STA Tile_Mem+$1440,Y 
04044. STA Tile_Mem+$15F0,Y 
04045. STA Tile_Mem+$17A0,Y 
04046. INY ; Y++ 
04047.  
04048. RTS ; Return 
04049.  
04050.  
04051. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04052. ; Tile_Mem_ClearB 
04053. ; 
04054. ; Similar to Tile_Mem_ClearA, writes to the same place on all screens, 
04055. ; only this one begins at the 12th row (making up for the 'Y' 
04056. ; register coming up short of a full screen) 
04057. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04058. Tile_Mem_ClearB: ; $9734 
04059. STA Tile_Mem+$0C0,Y 
04060. STA Tile_Mem+$270,Y 
04061. STA Tile_Mem+$420,Y 
04062. STA Tile_Mem+$5D0,Y 
04063. STA Tile_Mem+$780,Y 
04064. STA Tile_Mem+$930,Y 
04065. STA Tile_Mem+$AE0,Y 
04066. STA Tile_Mem+$C90,Y 
04067. STA Tile_Mem+$E40,Y 
04068. STA Tile_Mem+$FF0,Y 
04069. STA Tile_Mem+$11A0,Y 
04070. STA Tile_Mem+$1350,Y 
04071. STA Tile_Mem+$1500,Y 
04072. STA Tile_Mem+$16B0,Y 
04073. STA Tile_Mem+$1860,Y 
04074. RTS ; Return 
04075.  
04076.  
04077. ; Array of bank selections by Level_BG_Page1_2  
04078. ; What LEVEL4_BGBANK_INDEX references 
04079. Level_BG_Pages1: 
04080. .byte $00 ; 0 Not Used 
04081. .byte $08 ; 1 Plains 
04082. .byte $10 ; 2 Fortress 
04083. .byte $1C ; 3 Hills / Underground 
04084. .byte $0C ; 4 High-Up 
04085. .byte $58 ; 5 Plant Infestation 
04086. .byte $58 ; 6 Underwater 
04087. .byte $5C ; 7 Toad House 
04088. .byte $58 ; 8 Pipe Maze 
04089. .byte $30 ; 9 Desert 
04090. .byte $34 ; 10 Airship 
04091. .byte $6E ; 11 Giant world 
04092. .byte $18 ; 12 Ice 
04093. .byte $38 ; 13 Sky 
04094. .byte $1C ; 14 Not Used (Same as Hills / Underground) 
04095. .byte $24 ; 15 Bonus Room 
04096. .byte $2C ; 16 Spade (Roulette) 
04097. .byte $5C ; 17 N-Spade (Card) 
04098. .byte $58 ; 18 2P Vs 
04099. .byte $6C ; 19 Hills / Underground alternate 
04100. .byte $68 ; 20 3-7 only 
04101. .byte $34 ; 21 World 8 War Vehicle 
04102. .byte $28 ; 22 Throne Room 
04103.  
04104. Level_BG_Pages2: 
04105. .byte $00 ; 0 Not Used 
04106. .byte $60 ; 1 Plains 
04107. .byte $60 ; 2 Fortress 
04108. .byte $60 ; 3 Hills / Underground 
04109. .byte $60 ; 4 High-Up 
04110. .byte $3E ; 5 Plant Infestation 
04111. .byte $60 ; 6 Underwater 
04112. .byte $5E ; 7 Toad House 
04113. .byte $60 ; 8 Pipe Maze 
04114. .byte $60 ; 9 Desert 
04115. .byte $6A ; 10 Airship 
04116. .byte $60 ; 11 Giant world 
04117. .byte $60 ; 12 Ice 
04118. .byte $60 ; 13 Sky 
04119. .byte $60 ; 14 Not Used (Same as Hills / Underground) 
04120. .byte $5E ; 15 Bonus Room 
04121. .byte $2E ; 16 Spade (Roulette) 
04122. .byte $5E ; 17 N-Spade (Card) 
04123. .byte $60 ; 18 2P Vs 
04124. .byte $60 ; 19 Hills / Underground alternate 
04125. .byte $60 ; 20 3-7 only 
04126. .byte $70 ; 21 World 8 War Vehicle 
04127. .byte $60 ; 22 Throne Room 
04128.  
04129.  
04130. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04131. ; LevelLoad 
04132. ; 
04133. ; The master level loader function! Without this, there's no game! 
04134. ; 
04135. ; This function performs all the work necessary to translate  
04136. ; "layout" data into functional geometry. Note that based on 
04137. ; the value of Level_Tileset, there are different "generators" 
04138. ; that are employed, so while the overall macro format is consistent, 
04139. ; the stylization and inner format may not be! 
04140. ; 
04141. ; Best to follow through to figure out the format to each "style"... 
04142. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04143. ; There are 8 defined vertical start positions 
04144.  
04145. ; Defines Player's Y "high" start 
04146. GamePlay_YHiStart: .byte $01, $00, $00, $01, $00, $00, $00, $01 
04147.  
04148. ; Defines Player's Y start 
04149. GamePlay_YStart: .byte $70, $40, $00, $40, $70, $B0, $F0, $80 
04150.  
04151. ; Defines screen vertical position starts 
04152. ; NOTE: If the "box out" effect were to be used, needs to sync with BoxOut_ByVStart 
04153. GamePlay_VStart: .byte $EF, $00, $00, $EF, $30, $70, $B0, $EF 
04154.  
04155. ; Available MSD time start values 
04156. GamePlay_TimeStart: .byte 3, 4, 2, 0 
04157.  
04158. ; Available BGMs for levels (16 possible with stock code, only 11 defined here) 
04159. GamePlay_BGM: 
04160. .byte MUS2B_OVERWORLD ; 0 
04161. .byte MUS2B_UNDERGROUND ; 1 
04162. .byte MUS2B_UNDERWATER ; 2 
04163. .byte MUS2B_FORTRESS ; 3 
04164. .byte MUS2B_BOSS ; 4 
04165. .byte MUS2B_AIRSHIP ; 5 
04166. .byte MUS2B_BATTLE ; 6 
04167. .byte MUS2B_TOADHOUSE ; 7 
04168. .byte MUS2B_ATHLETIC ; 8 
04169. .byte MUS2A_THRONEROOM ; 9 
04170. .byte MUS2A_SKY ; 10 
04171.  
04172.  
04173. LevelLoad: ; $97B7 
04174.  
04175. ; Clear loading variables 
04176. LDA #$00 
04177. STA TileAddr_Off 
04178. STA LevLoad_Unused4 
04179. STA LevLoad_Unused3 
04180. STA LevLoad_Unused1 
04181. STA LevLoad_Unused2 
04182.  
04183. LDY #$04 ; Y = 4 (in case we're skipping first 4 bytes of header) 
04184.  
04185. ; If we're using a "junction" device (door/pipe/etc.), we don't want to (incorrectly) set the "alternates"... 
04186. LDA Level_JctCtl  
04187. CMP #$80  
04188. BEQ PRG030_980D ; If Level_JctCtl = $80, jump to PRG030_980D (use current Level_AltLayout/Level_AltObjects values) 
04189.  
04190. LDY #$00 ; Y = 0 
04191.  
04192. ; Get bytes 0-3 of layout data; pointers Level_AltLayout and Level_AltObjects 
04193.  
04194. LDA [Level_LayPtr_AddrL],Y 
04195. STA Level_AltLayout 
04196. INY 
04197. LDA [Level_LayPtr_AddrL],Y 
04198. STA Level_AltLayout+1 
04199. INY  
04200.  
04201. LDA [Level_LayPtr_AddrL],Y 
04202. STA Level_AltObjects 
04203. INY  
04204. LDA [Level_LayPtr_AddrL],Y 
04205. STA Level_AltObjects+1 
04206. INY  
04207.  
04208. LDA Level_JctCtl  
04209. BNE PRG030_980D ; If Level_JctCtl <> 0, jump to PRG030_980D (skip setting vertical start position) 
04210.  
04211. LDA [Level_LayPtr_AddrL],Y 
04212. AND #%11100000 
04213. LSR A  
04214. LSR A  
04215. LSR A  
04216. LSR A  
04217. LSR A  
04218. TAX ; X = upper 3 bits, shifted down, from byte 4 (0-7) 
04219.  
04220. ; Set up the vertical starting position! 
04221. LDA GamePlay_YHiStart,X 
04222. STA <Player_YHi ; Player_YHi = GamePlay_YHiStart[X] 
04223.  
04224. LDA GamePlay_YStart,X 
04225. STA <Player_Y ; Player_Y = GamePlay_YStart[X] 
04226.  
04227. LDA #$00  
04228. STA <Player_XHi ; Player_XHi = 0 
04229.  
04230. ; Set the starting vertical position 
04231. LDA GamePlay_VStart,X 
04232. STA <Vert_Scroll ; Vert_Scroll = GamePlay_VStart[X] 
04233.  
04234. PRG030_980D: 
04235.  
04236. ; Set the width of the level (in screens) from byte 4 
04237. LDA [Level_LayPtr_AddrL],Y 
04238. AND #%00001111 
04239. STA <Level_Width 
04240. STA Level_SizeOrig  
04241.  
04242. ;;;;;;;;;;;;;;; 
04243. INY  
04244.  
04245. ; First 3 bits of byte 5 determine the palette select for tiles 
04246. LDA [Level_LayPtr_AddrL],Y 
04247. AND #%00000111 
04248. STA PalSel_Tile_Colors 
04249.  
04250. ; Next 2 bits select an object palette, root value 8 
04251. LDA [Level_LayPtr_AddrL],Y 
04252. AND #%00011000 
04253. LSR A  
04254. LSR A  
04255. LSR A  
04256. ORA #%00001000 ; forces minimum value of 8 
04257. STA PalSel_Obj_Colors 
04258.  
04259. ; Next 2 bits sets Level_SelXStart (sets Player_X after level starts) 
04260. LDA [Level_LayPtr_AddrL],Y 
04261. AND #%01100000 
04262. LSR A  
04263. LSR A  
04264. LSR A  
04265. LSR A  
04266. LSR A  
04267. STA Level_SelXStart  
04268.  
04269. ; Finally, bit 7 sets Level_UnusedFlag (unused; only set, never read) 
04270. LDA [Level_LayPtr_AddrL],Y 
04271. AND #$80  
04272. STA Level_UnusedFlag  
04273.  
04274. ;;;;;;;;;;;;;;; 
04275. INY  
04276.  
04277. ; Bit 7 of byte 6 sets Level_PipeNotExit 
04278. LDA [Level_LayPtr_AddrL],Y 
04279. AND #$80  
04280. STA Level_PipeNotExit 
04281.  
04282. ; Bits 5-6 set Level_FreeVertScroll 
04283. LDA [Level_LayPtr_AddrL],Y 
04284. AND #%01100000 
04285. LSR A 
04286. LSR A 
04287. LSR A 
04288. LSR A 
04289. LSR A 
04290. STA Level_FreeVertScroll 
04291.  
04292. CMP #$02 
04293. BNE PRG030_9864 ; If Level_FreeVertScroll <> 2 (arbitrary scroll lock), jump to PRG030_9864 
04294.  
04295. ; Otherwise for a level started with the arbitrary lock, it picks Vert_Scroll = 0 (highest point) 
04296. ; if Vert_Scroll is less than $B0, otherwise it picks $EF (lowest point) 
04297. ; NOTE however that these two points are not required during normal gameplay; you can arbitrarily 
04298. ; lock to ANY Vert_Scroll value and it will work just fine! 
04299.  
04300. LDX #$00 ; X = 0 
04301.  
04302. LDA <Vert_Scroll 
04303. CMP #$b0 
04304. BLT PRG030_985F ; If Vert_Scroll < $B0, jump to PRG030_985F 
04305.  
04306. LDX #$ef ; Otherwise, X = $EF 
04307.  
04308. PRG030_985F: 
04309. STX <Vert_Scroll ; Vert_Scroll = X 
04310. STX Level_Jct_VS ; Level_Jct_VS = Vert_Scroll 
04311.  
04312. PRG030_9864: 
04313.  
04314. ; Bit 4 sets whether this level is a vertical one 
04315. LDA [Level_LayPtr_AddrL],Y 
04316. AND #%00010000 
04317. STA Level_7Vertical 
04318. BEQ PRG030_9893 ; If not vertical, jump to PRG030_9893 
04319.  
04320. LDX Level_JctCtl 
04321. BNE PRG030_987C ; If Level_JctCtl <> 0, jump to PRG030_987C 
04322.  
04323. ; Start at bottom of vertical level 
04324. LDA Level_SizeOrig 
04325. STA <Vert_Scroll_Hi 
04326. STA <Player_YHi ; Player's Y High is the same! 
04327. JMP PRG030_9893  
04328.  
04329.  
04330. PRG030_987C: 
04331. LDA #$00  
04332. STA Level_SizeOrig ; ?? Why? 
04333.  
04334. LDA <Player_YHi  
04335. BEQ PRG030_988E ; If the Player Y high is zero, jump to PRG030_988E 
04336.  
04337. LDA <Level_Width 
04338. STA <Vert_Scroll_Hi 
04339. STA <Player_YHi  
04340. STA Level_SizeOrig 
04341.  
04342. PRG030_988E: 
04343. LDA <Vert_Scroll_Hi 
04344. STA Level_Jct_VSHi ; Level_Jct_VSHi = Vert_Scroll_Hi 
04345.  
04346. ; End of Vertical alternative 
04347.  
04348. PRG030_9893: 
04349.  
04350. ; Bits 0-3 set Level_AltTileset 
04351. LDA [Level_LayPtr_AddrL],Y 
04352. AND #$0f  
04353. STA Level_AltTileset 
04354.  
04355. ;;;;;;;;;;;;;;; 
04356. INY ; Y++  
04357.  
04358. ; Bits 5-7 of byte 7 set Level_InitAction (sets an action to begin level, see Level_InitAction_JumpTable) 
04359. LDA [Level_LayPtr_AddrL],Y 
04360. AND #%11100000  
04361. LSR A  
04362. LSR A  
04363. LSR A  
04364. LSR A  
04365. LSR A  
04366. STA Level_InitAction 
04367.  
04368. ; Bits 0-4 set Level_BG_Page1_2 (an index to which pages of BG graphics should be loaded) 
04369. LDA [Level_LayPtr_AddrL],Y 
04370. AND #%00011111  
04371. STA Level_BG_Page1_2 
04372.  
04373. ;;;;;;;;;;;;;;; 
04374. INY ; Y++ 
04375.  
04376. LDA Level_JctCtl 
04377. BNE PRG030_98C8 ; If using a junction device, don't set the time; jump to PRG030_98C8 
04378.  
04379. ; Bits 6-7 of byte 8 select a time setting (0=300, 1=400, 2=200, 3=000 [unlimited]) 
04380. LDA [Level_LayPtr_AddrL],Y 
04381. AND #%11000000  
04382. CLC  
04383. ROL A  
04384. ROL A  
04385. ROL A  
04386. TAX  
04387. LDA GamePlay_TimeStart,X 
04388. STA Level_TimerMSD 
04389. BNE PRG030_98C8 ; If not using the 000 time, jump to PRG030_98C8 
04390.  
04391. INC Level_TimerEn ; Otherwise Level_TimerEn = 1 (disable the clock, hence unlimited time) 
04392.  
04393. PRG030_98C8: 
04394.  
04395. ; Bits 0-3 select a BGM 
04396. LDA [Level_LayPtr_AddrL],Y 
04397. AND #%00001111 
04398. TAX 
04399. LDA GamePlay_BGM,X ; A = target music 
04400. LDX SndCur_Music2 ; X = currently playing music 
04401.  
04402. CPX #MUS2B_PSWITCH 
04403. BEQ PRG030_98DE ; If playing the P-Tab music, don't queue this song right now 
04404. CPX #MUS2A_INVINCIBILITY  
04405. BEQ PRG030_98DE ; If playing the Invincibility music, don't queue this song right now 
04406.  
04407. ; Queue this music to play 
04408. STA Level_MusicQueue 
04409.  
04410. PRG030_98DE: 
04411. ; Set this as the music to "restore" to when P-Tab / Invincibility ends 
04412. STA Level_MusicQueueRestore 
04413.  
04414. ; Level_LayPtr_AddrL/H += 9 (i.e. move pointer to after the header) 
04415. LDA <Level_LayPtr_AddrL 
04416. ADD #$09 
04417. STA <Level_LayPtr_AddrL 
04418. LDA <Level_LayPtr_AddrH 
04419. ADC #$00 
04420. STA <Level_LayPtr_AddrH 
04421.  
04422. PRG030_98EE: 
04423. LDY #$00 ; Y = 0 (beginning of post-header) 
04424.  
04425. LDA [Level_LayPtr_AddrL],Y ; Get next byte 
04426. CMP #$ff  
04427. BEQ PRG030_9934 ; If $FF, jump to PRG030_9934 (RTS) 
04428.  
04429. ; Otherwise... 
04430. STA <Temp_Var15 ; Store byte into Temp_Var15 
04431.  
04432. INY ; Y++ 
04433. LDA [Level_LayPtr_AddrL],Y ; Get next byte 
04434. STA <Temp_Var16 ; Store into Temp_Var16 
04435.  
04436. INY ; Y++ 
04437. LDA [Level_LayPtr_AddrL],Y ; Get next byte 
04438. STA LL_ShapeDef ; Store into LL_ShapeDef 
04439.  
04440. INY ; Y++ 
04441. TYA ; A = Y 
04442.  
04443. ; Add current offset into Level_LayPtr_AddrL/H, moving it ahead 
04444. ADD <Level_LayPtr_AddrL 
04445. STA <Level_LayPtr_AddrL 
04446. LDA <Level_LayPtr_AddrH 
04447. ADC #$00  
04448. STA <Level_LayPtr_AddrH 
04449.  
04450. LDA <Temp_Var15 ; Retrieve first byte we read 
04451. AND #$e0  
04452. CMP #$e0  
04453. BNE PRG030_991E ; If its upper 3 bits are not all set, jump to PRG030_991E 
04454.  
04455. ; ***************** 
04456. ; Upper 3 bits of Temp_Var15 are ALL set... i.e. Temp_Var15 = 111x xxxx 
04457. ; ***************** 
04458.  
04459. JSR LoadLevel_StoreJctStart ; Temp_Var16 and LL_ShapeDef define junction start positions 
04460. JMP PRG030_98EE ; Loop around 
04461.  
04462. PRG030_991E: 
04463.  
04464. ; ***************** 
04465. ; Upper 3 bits of Temp_Var15 are NOT ALL set... i.e. Temp_Var15 DOES *NOT follow* the mask 111x xxxx 
04466. ; ***************** 
04467.  
04468. ; Temp_Var15 and Temp_Var16 are the input parameters to LoadLevel_Set_TileMemAddr, 
04469. ; which set, most importantly, "Map_Tile_Addr" to some root screen address, and 
04470. ; set "TileAddr_Off" as an offset value within that screen. 
04471.  
04472. ; "Map_Tile_Addr" is formed Tile_Mem_Addr[ (Temp_Var16 & $F0) >> 3 ] 
04473. ; - The upper 4 bits of Temp_Var16 select the starting screen 
04474. ; 
04475. ; "TileAddr_Off" is formed (Temp_Var15 << 4) | (Temp_Var16 & $f) 
04476. ; - The lower 4 bits of Temp_Var15, and lower 4 bits of Temp_Var16 
04477. JSR LoadLevel_Set_TileMemAddr 
04478.  
04479. LDA LL_ShapeDef 
04480. AND #$f0 
04481. BEQ PRG030_992E ; If upper 4 bits of LL_ShapeDef are all zero, jump to PRG030_992E 
04482.  
04483. ; ***************** 
04484. ; Upper 4 bits of LL_ShapeDef are NOT ALL clear... i.e. LL_ShapeDef DOES *NOT follow* the mask 0000 xxxx 
04485. ; ***************** 
04486.  
04487. ; Otherwise, we handle this as a construction command, and so turn 
04488. ; to the "generators" which define what the bytes mean... 
04489. JSR LeveLoad_Generators  
04490.  
04491. JMP PRG030_9931 ; (Essentially) loop around (pointless jump, heh) 
04492.  
04493. PRG030_992E: 
04494. ; ***************** 
04495. ; Upper 4 bits of LL_ShapeDef are ALL NOT set... i.e. LL_ShapeDef = 0000 xxxx 
04496. ; ***************** 
04497.  
04498. ; This is a fixed-size construction type 
04499. JSR LeveLoad_FixedSizeGens 
04500.  
04501. PRG030_9931: 
04502. JMP PRG030_98EE ; Loop around... 
04503.  
04504. PRG030_9934: 
04505. RTS ; Return 
04506.  
04507.  
04508. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04509. ; LoadLevel_Set_TileMemAddr 
04510. ; 
04511. ; Used while loading a level. Sets the Map_Tile_AddrL/H pointer 
04512. ; to a specified "screen", and also sets TileAddr_Off to an offset 
04513. ; within that screen. 
04514. ; 
04515. ; Takes input parameters of Temp_Var15 and Temp_Var16 and from  
04516. ; there generates: 
04517. ; 
04518. ; Guide to help visualize the input: 
04519. ; Temp_Var15 Temp_Var16 
04520. ; FEDC BA98 7654 3210 <-- bits 
04521. ; 
04522. ; 
04523. ; * Map_Tile_AddrL/H points to Tile_Mem_Addr(V)[7654 0] <-- '0' is a one-up shift, not bit 0 of Temp_Var16; (V) is the "Vertical" table, used if applicable 
04524. ; 
04525. ; * If 'C' (bit 4) of Temp_Var15 is set, then Map_Tile_AddrH is incremented 
04526. ; 
04527. ; * Temp_Var5 = Map_Tile_AddrH + 1 -- Pre-'C' increment, ONLY WHEN NOT VERTICAL (otherwise unassigned) 
04528. ; 
04529. ; * Temp_Var6 = Map_Tile_AddrH -- Post-'C' increment (i.e. equals whatever Map_Tile_AddrH does at end of function) 
04530. ; 
04531. ; * TileAddr_Off = BA98 3210 -OR- (Temp_Var15 << 4) | (Temp_Var16 & $f) 
04532. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04533. LoadLevel_Set_TileMemAddr: 
04534. ; Upper 3 bits of first byte were all set... 
04535.  
04536.  
04537. LDA <Temp_Var15 ; Get that first byte 
04538. ASL A  
04539. ASL A  
04540. ASL A  
04541. ASL A  
04542. STA <Temp_Var7 ; Temp_Var7 = Temp_Var15 << 4 (take lower 4 bits and multiply by 16) 
04543.  
04544. LDA <Temp_Var16 ; Second byte 
04545. AND #$0f ; Lower 4 bits 
04546. ORA <Temp_Var7 ; Applied to Temp_Var7 
04547. STA TileAddr_Off ; Stored into TileAddr_Off 
04548.  
04549. ; TileAddr_Off = BA98 3210 -OR- (first byte << 4) | (second byte & $f) 
04550.  
04551.  
04552. LDA <Temp_Var16 ; Second byte 
04553. AND #$f0 ; Upper 4 bits 
04554. LSR A  
04555. LSR A  
04556. LSR A  
04557. TAX ; X = (Temp_Var16 & $F0) >> 3 (value in upper 4 bits times 2, 2 byte index for Tile_Mem_Addr) 
04558.  
04559. ; X = 7654 0 <-- '0' is a one-up shift, not bit 0 of Temp_Var16 
04560.  
04561. LDA Level_7Vertical 
04562. BEQ PRG030_9963 ; If not a vertical level, jump to PRG030_9963 
04563.  
04564. ; Vertical level 
04565.  
04566. TXA 
04567. LSR A 
04568. TAX ; X >>= 1 (single byte index, since the Tile_Mem_AddrV lookup is split into two tables) 
04569.  
04570. ; Load the target address into Map_Tile_AddrH/L 
04571. LDA Tile_Mem_AddrVL,X 
04572. STA <Map_Tile_AddrL 
04573. LDA Tile_Mem_AddrVH,X 
04574. STA <Map_Tile_AddrH 
04575.  
04576. JMP PRG030_997F ; Jump to PRG030_997F 
04577.  
04578. PRG030_9963: 
04579.  
04580. ; Non-vertical level 
04581.  
04582. CPX #$1e 
04583. BNE PRG030_9969 ; If X <> $1E (the max value), jump to PRG030_9969 
04584.  
04585. ; Otherwise, X -= 2 
04586. DEX 
04587. DEX 
04588.  
04589. PRG030_9969: 
04590.  
04591. ; Load the target address into Map_Tile_AddrH/L 
04592. LDA Tile_Mem_Addr,X 
04593. STA <Map_Tile_AddrL 
04594. LDA Tile_Mem_Addr+1,X 
04595. STA <Map_Tile_AddrH 
04596.  
04597. STA <Temp_Var5  
04598. INC <Temp_Var5 ; Temp_Var5 = Map_Tile_AddrH + 1 
04599.  
04600. LDA <Temp_Var15  
04601. AND #$10  
04602. BEQ PRG030_997F ; If bit 4 of the first byte is not set, jump to PRG030_997F 
04603.  
04604. ; Otherwise, Map_Tile_AddrH++ 
04605. INC <Map_Tile_AddrH 
04606.  
04607. PRG030_997F: 
04608. LDA <Map_Tile_AddrH 
04609. STA <Temp_Var6 ; Temp_Var6 = Map_Tile_AddrH 
04610.  
04611. RTS ; Return 
04612.  
04613. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04614. ; Randomize 
04615. ; 
04616. ; Shakes up the random number pool a bit! 
04617. ; Anyone want to detail the algorithm, go right ahead... 
04618. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04619. Randomize: 
04620. LDX #$00  
04621. LDY #$09  
04622. LDA Random_Pool  
04623. AND #$02  
04624. STA <Temp_Var1  
04625. LDA RandomN  
04626. AND #$02  
04627. EOR <Temp_Var1  
04628. CLC  
04629. BEQ PRG030_999A  
04630. SEC  
04631. PRG030_999A: 
04632. ROR Random_Pool,X 
04633. INX  
04634. DEY  
04635. BNE PRG030_999A  
04636.  
04637. RTS ; Return 
04638.  
04639.  
04640.  
04641. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04642. ; Level_RecordBlockHit 
04643. ; 
04644. ; Called after a coin is collected or a hidden 1-Up is found. 
04645. ; This records those events so if the level is swapped with its 
04646. ; alternate, these things do not retun. Next best thing to 
04647. ; actually having enough memory to hold both levels together... 
04648. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04649. RecordBlockHitBits: 
04650. .byte $80, $40, $20, $10, $08, $04, $02, $01 
04651.  
04652. Level_RecordBlockHit: 
04653.  
04654. ; Currently Temp_Var13-16 are defined as follows: 
04655. ; Temp_Var13 / Temp_Var14 -- Y Hi and Lo 
04656. ; Temp_Var15 / Temp_Var16 -- X Hi and Lo 
04657. ; ... of Player detection coordinates 
04658.  
04659. TYA 
04660. PHA ; Save 'Y' 
04661.  
04662. TXA 
04663. PHA ; Save 'X' 
04664.  
04665. LDA <Temp_Var16 
04666. PHA ; Save Temp_Var16 
04667.  
04668. LDA <Temp_Var13 
04669. PHA ; Save Temp_Var13 
04670.  
04671. ; This converts Temp_Var15/Temp_Var16 into a tile row stored in Temp_Var16 
04672. ; Essentially a 16-bit right shift 4 bits 
04673. LDA <Temp_Var16 
04674. LSR A 
04675. LSR A 
04676. LSR A 
04677. LSR A 
04678. STA <Temp_Var16 
04679. LDA <Temp_Var15 
04680. ASL A 
04681. ASL A 
04682. ASL A 
04683. ASL A 
04684. ORA <Temp_Var16 
04685. STA <Temp_Var16 
04686.  
04687. ; This turns Temp_Var13 into an index into Level_BlockGrabHitMem 
04688. LDA <Temp_Var16 
04689. AND #%11111000 
04690. LSR A 
04691. LSR A 
04692. ORA <Temp_Var13 
04693. STA <Temp_Var13 
04694.  
04695. LDA Level_JctFlag 
04696. BEQ PRG030_99DC ; If we're not junctioning, jump to PRG030_99DC 
04697.  
04698. ; If junctioning, Temp_Var13 += $40 
04699. LDA <Temp_Var13 
04700. ADD #$40 
04701. STA <Temp_Var13 
04702.  
04703. PRG030_99DC: 
04704. LDA <Temp_Var16 
04705. AND #$07 
04706. TAX 
04707. LDY <Temp_Var13 
04708. LDA Level_BlockGrabHitMem,Y 
04709. ORA RecordBlockHitBits,X 
04710. STA Level_BlockGrabHitMem,Y 
04711.  
04712. ; Restore everything we saved 
04713. PLA 
04714. STA <Temp_Var13 
04715. PLA 
04716. STA <Temp_Var16 
04717. PLA 
04718. TAX 
04719. PLA 
04720. TAY 
04721.  
04722. RTS ; Return 
04723.  
04724. TileLayout_ByTileset: 
04725. ; Defines the 8x8 blocks to build a particular 16x16 "tile" 
04726.  
04727. .word Tile_Layout_TS0 ; 0 - Map 
04728. .word Tile_Layout_TS1 ; 1 - Plains [15] 
04729. .word Tile_Layout_TS2 ; 2 - Mini fortress style [21] 
04730. .word Tile_Layout_TS3 ; 3 - Hills style [16] 
04731. .word Tile_Layout_TS4_TS12 ; 4 - High-Up style [17] 
04732. .word Tile_Layout_TS5_TS11_TS13 ; 5 - pipe world plant infestation [19] 
04733. .word Tile_Layout_TS6_TS7_TS8 ; 6 - Water world [18] 
04734. .word Tile_Layout_TS6_TS7_TS8 ; 7 - Toad house [18] 
04735. .word Tile_Layout_TS6_TS7_TS8 ; 8 - Vertical pipe maze [18] 
04736. .word Tile_Layout_TS9 ; 9 - desert level [20] 
04737. .word Tile_Layout_TS10 ; 10 - airship [23] 
04738. .word Tile_Layout_TS5_TS11_TS13 ; 11 - Giant World [19] 
04739. .word Tile_Layout_TS4_TS12 ; 12 - ice level [17] 
04740. .word Tile_Layout_TS5_TS11_TS13 ; 13 - coin heaven / sky level [19] 
04741. .word Tile_Layout_TS14 ; 14 - underground [13] 
04742. .word Tile_Layout_TS15_TS16_TS17; 15 - bonus game intro [22] 
04743. .word Tile_Layout_TS15_TS16_TS17; 16 - spade game sliders [22] 
04744. .word Tile_Layout_TS15_TS16_TS17; 17 - N-spade [22] 
04745. .word Tile_Layout_TS18 ; 18 - 2P Vs [14] 
04746.  
04747. LevelLoad_ByTileset: 
04748. LDA Level_Tileset 
04749. JSR DynJump 
04750.  
04751. ; Page numbers are determined by PAGE_A000_ByTileset and PAGE_C000_ByTileset, indexed by Level_Tileset 
04752.  
04753. ; THESE MUST FOLLOW DynJump FOR THE DYNAMIC JUMP TO WORK!! 
04754. .word LT0 ; 0 - Map [11] (not used, enters in the middle of WWFX_WarpIslandInit, and not in a logical place) 
04755. .word LevelLoad_TS1 ; 1 - Plains [15] 
04756. .word LevelLoad_TS2 ; 2 - Mini fortress style [21] 
04757. .word LevelLoad_TS3 ; 3 - Hills style [16] 
04758. .word LevelLoad_TS4_TS12 ; 4 - High-Up style [17] 
04759. .word LevelLoad_TS5 ; 5 - pipe world plant infestation [19] 
04760. .word LevelLoad_TS6 ; 6 - Water world [18] 
04761. .word LevelLoad_TS7 ; 7 - Toad house [18] 
04762. .word LevelLoad_TS8 ; 8 - Vertical pipe maze [18] 
04763. .word LevelLoad_TS9 ; 9 - desert level [20] 
04764. .word LevelLoad_TS10 ; 10 - airship [23] 
04765. .word LevelLoad_TS5 ; 11 - Giant World [19] 
04766. .word LevelLoad_TS4_TS12 ; 12 - ice level [17] 
04767. .word LevelLoad_TS13 ; 13 - coin heaven / sky level [19] 
04768. .word LevelLoad_TS14 ; 14 - underground [13] 
04769.  
04770. .word LevelLoad_TS15_TS16_TS17 ; 15 - bonus game intro [22] 
04771. .word LevelLoad_TS15_TS16_TS17 ; 16 - spade game sliders [22] 
04772. .word LevelLoad_TS15_TS16_TS17 ; 17 - N-spade [22] 
04773. .word LevelLoad_TS18 ; 18 - 2P Vs [14] 
04774.  
04775.  
04776. ; RegEx S&R: 
04777. ; LDA LL_ShapeDef.*\n.*AND #\$0f.*\n.*STA <Temp_Var(.) ; .* 
04778. ; LDA LL_ShapeDef\n\tAND #$0f\n\tSTA <Temp_Var\1 ; Temp_Var\1 = lower 4 bits of LL_ShapeDef 
04779.  
04780. ; LDA LL_ShapeDef.*\n.*AND #\$0f.*\n.*TAX ; .* 
04781. ; LDA LL_ShapeDef\n\tAND #$0f\n\tTAX ; X = lower 4 bits of LL_ShapeDef 
04782.  
04783. ; LDA <Temp_Var(.).*\n.*STA <Temp_Var(.) ; .* 
04784. ; LDA <Temp_Var\1\n\tSTA <Temp_Var\2 ; Temp_Var\2 = Temp_Var\1 
04785.  
04786. ; DEC <Temp_Var(.) ; .* 
04787. ; DEC <Temp_Var\1 ; Temp_Var\1-- 
04788.  
04789. ; LDA <Map_Tile_AddrL.*\n.*STA <Temp_Var1.*\n.*LDA <Map_Tile_AddrH.*\n.*STA <Temp_Var2.* 
04790. ;; Backup Map_Tile_AddrL/H into Temp_Var1/2\n\tLDA <Map_Tile_AddrL\n\tSTA <Temp_Var1\n\tLDA <Map_Tile_AddrH\n\tSTA <Temp_Var2 
04791.  
04792. ; LDA <Temp_Var1.*\n.*STA <Map_Tile_AddrL.*\n.*LDA <Temp_Var2.*\n.*STA <Map_Tile_AddrH.* 
04793. ;; Restore Map_Tile_Addr from backup\n\tLDA <Temp_Var1\n\tSTA <Map_Tile_AddrL\n\tLDA <Temp_Var2\n\tSTA <Map_Tile_AddrH 
04794.  
04795. LeveLoad_Generators: 
04796. LDA Level_Tileset 
04797. JSR DynJump 
04798.  
04799. ; THESE MUST FOLLOW DynJump FOR THE DYNAMIC JUMP TO WORK!! 
04800. .word LT0B ; 0 - Map [11] (not used, enters in the middle of nowhere, in a not logical place) 
04801. .word LoadLevel_Generator_TS1 ; 1 - Plains [15] 
04802. .word LoadLevel_Generator_TS2 ; 2 - Mini fortress style [21] 
04803. .word LoadLevel_Generator_TS3 ; 3 - Hills style [16] 
04804. .word LoadLevel_Generator_TS4_TS12 ; 4 - High-Up style [17] 
04805. .word LoadLevel_Generator_TS051113 ; 5 - pipe world plant infestation [19] 
04806. .word LoadLevel_Generator_TS678 ; 6 - Water world [18] 
04807. .word LoadLevel_Generator_TS678 ; 7 - Toad house [18] 
04808. .word LoadLevel_Generator_TS678 ; 8 - Vertical pipe maze [18] 
04809. .word LoadLevel_Generator_TS9 ; 9 - desert level 
04810. .word LoadLevel_Generator_TS10 ; 10 - airship 
04811. .word LoadLevel_Generator_TS051113 ; 11 - Giant World 
04812. .word LoadLevel_Generator_TS4_TS12 ; 12 - ice level [17] 
04813. .word LoadLevel_Generator_TS051113 ; 13 - coin heaven / sky level [19] 
04814. .word LoadLevel_Generator_TS14 ; 14 - underground [13] 
04815. .word LoadLevel_Generator_TS151617 ; 15 - bonus game intro 
04816. .word LoadLevel_Generator_TS151617 ; 16 - spade game sliders 
04817. .word LoadLevel_Generator_TS151617 ; 17 - N-spade 
04818. .word LoadLevel_Generator_TS18 ; 18 - 2P Vs 
04819.  
04820. LeveLoad_FixedSizeGens: 
04821. LDA Level_Tileset 
04822. JSR DynJump 
04823.  
04824. ; THESE MUST FOLLOW DynJump FOR THE DYNAMIC JUMP TO WORK!! 
04825. .word LT0B ; 0 - Map [11] (not used, enters in the middle of nowhere, in a not logical place) 
04826. .word LeveLoad_FixedSizeGen_TS1 ; 1 - Plains 
04827. .word LeveLoad_FixedSizeGen_TS2 ; 2 - Mini fortress style 
04828. .word LeveLoad_FixedSizeGen_TS3 ; 3 - Hills style [16] 
04829. .word LeveLoad_FixedSizeGen_TS4_TS12 ; 4 - High-Up style [17] 
04830. .word LeveLoad_FixedSizeGen_TS051113 ; 5 - pipe world plant infestation [19] 
04831. .word LeveLoad_FixedSizeGen_TS678 ; 6 - Water world 
04832. .word LeveLoad_FixedSizeGen_TS678 ; 7 - Toad house 
04833. .word LeveLoad_FixedSizeGen_TS678 ; 8 - Vertical pipe maze 
04834. .word LeveLoad_FixedSizeGen_TS9 ; 9 - desert level 
04835. .word LeveLoad_FixedSizeGen_TS10 ; 10 - airship 
04836. .word LeveLoad_FixedSizeGen_TS051113 ; 11 - Giant World [19] 
04837. .word LeveLoad_FixedSizeGen_TS4_TS12 ; 12 - ice level [17] 
04838. .word LeveLoad_FixedSizeGen_TS051113 ; 13 - coin heaven / sky level [19] 
04839. .word LeveLoad_FixedSizeGen_TS14 ; 14 - underground [13] 
04840. .word LeveLoad_FixedSizeGen_TS151617 ; 15 - bonus game intro 
04841. .word LeveLoad_FixedSizeGen_TS151617 ; 16 - spade game sliders 
04842. .word LeveLoad_FixedSizeGen_TS151617 ; 17 - N-spade 
04843. .word LeveLoad_FixedSizeGen_TS18 ; 18 - 2P Vs 
04844.  
04845. PRG030_9AA1: 
04846. .byte $01, $FF 
04847.  
04848. PRG030_9AA3: 
04849. .byte $08, $F8 
04850.  
04851. PRG030_9AA5: 
04852. .byte $00, $08 
04853.  
04854.  
04855. TileLayoutPage_ByTileset: 
04856. ; A000 page selected per-Level_Tileset... 
04857. .byte BANK(Tile_Layout_TS0) ; 0 - Map [11] 
04858. .byte BANK(Tile_Layout_TS1) ; 1 - Plains [15] 
04859. .byte BANK(Tile_Layout_TS2) ; 2 - Mini fortress style [21] 
04860. .byte BANK(Tile_Layout_TS3) ; 3 - Hills style [16] 
04861. .byte BANK(Tile_Layout_TS4_TS12) ; 4 - High-Up style [17] 
04862. .byte BANK(Tile_Layout_TS5_TS11_TS13) ; 5 - pipe world plant infestation [19] 
04863. .byte BANK(Tile_Layout_TS6_TS7_TS8) ; 6 - Water world [18] 
04864. .byte BANK(Tile_Layout_TS6_TS7_TS8) ; 7 - Toad house [18] 
04865. .byte BANK(Tile_Layout_TS6_TS7_TS8) ; 8 - Vertical pipe maze [18] 
04866. .byte BANK(Tile_Layout_TS9) ; 9 - desert level [20] 
04867. .byte BANK(Tile_Layout_TS10) ; 10 - airship [23] 
04868. .byte BANK(Tile_Layout_TS5_TS11_TS13) ; 11 - Giant World [19] 
04869. .byte BANK(Tile_Layout_TS4_TS12) ; 12 - ice level [17] 
04870. .byte BANK(Tile_Layout_TS5_TS11_TS13) ; 13 - coin heaven / sky level [19] 
04871. .byte BANK(Tile_Layout_TS14) ; 14 - underground [13] 
04872.  
04873. ; THESE VALUES ARE WRONG! Appears that they were not maintained? 
04874. ; It doesn't matter because these specialized cases go where they need to anyway! 
04875. .byte 23 ; 15 - bonus game intro (WRONG: Should be 22) 
04876. .byte 23 ; 16 - spade game sliders (WRONG: Should be 22) 
04877. .byte 23 ; 17 - N-spade (WRONG: Should be 22) 
04878. .byte 16 ; 18 - 2P Vs (WRONG: Should be 14) 
04879.  
04880. ; CORRECT VALUES: 
04881. ;.byte BANK(Tile_Layout_TS15_TS16_TS17) ; 15 - bonus game intro [22] 
04882. ;.byte BANK(Tile_Layout_TS15_TS16_TS17) ; 16 - spade game sliders [22] 
04883. ;.byte BANK(Tile_Layout_TS15_TS16_TS17) ; 17 - N-spade [22] 
04884. ;.byte BANK(Tile_Layout_TS18) ; 18 - 2P Vs [14] 
04885.  
04886. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04887. ; Scroll_Dirty_Update 
04888. ; 
04889. ; This function performs a full-screen redraw of all tiles,  
04890. ; used when first showing map/level, but not for scrolling! 
04891. ; (Though it does call the same routine USED for scrolling) 
04892. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
04893. Scroll_Dirty_Update: 
04894. LDA Level_7Vertical 
04895. BNE PRG030_9B10 ; If level is vertical, jump to PRG030_9B10 
04896.  
04897. ; Non-vertical level 
04898. LDX <Scroll_LastDir ; X = Scroll_LastDir 
04899. LDA <Horz_Scroll ; A = Horz_Scroll 
04900. STA <Scroll_RightUpd,X ; Current horizontal scroll stored into appropriate left/right value 
04901.  
04902. PRG030_9AC5: 
04903. ; Set proper Page @ A000 for tile layout data 
04904. LDY Level_Tileset 
04905. LDA TileLayoutPage_ByTileset,Y  
04906. STA PAGE_A000  
04907. JSR PRGROM_Change_A000 
04908.  
04909. ; Buffers a single 8x8 column of tiles 
04910. JSR Scroll_DoColumn 
04911.  
04912. ; Set page @ A000 to 26 
04913. LDA #26 
04914. STA PAGE_A000 
04915. JSR PRGROM_Change_A000 
04916.  
04917. ; Commits the buffer 
04918. JSR Scroll_Commit_Column 
04919.  
04920. LDX <Scroll_LastDir ; X = Scroll_LastDir 
04921. LDA <Scroll_RightUpd,X ; A = Get the last 8 pixel location update 
04922. ADD PRG030_9AA3,X ; Add an appropriate offset given the direction of travel 
04923. STA <Scroll_RightUpd,X ; Update it! 
04924.  
04925. ; Produce the attribute data and commits the buffer 
04926. JSR Scroll_Do_AttrColumn 
04927. JSR Scroll_Commit_Column 
04928.  
04929. LDX <Scroll_LastDir ; Last direction to index the following 
04930. LDA <Scroll_RightUpd,X ; Get updated column 
04931. AND #$08 ; Every half screen 
04932. CMP PRG030_9AA5,X 
04933. BNE PRG030_9B02 ; For updating on half-tiles (??), jump to PRG030_9B02 
04934. LDA <Scroll_ColumnR,X  
04935. ADD PRG030_9AA1,X 
04936. STA <Scroll_ColumnR,X 
04937.  
04938. PRG030_9B02: 
04939. DEC Scroll_Cols2Upd ; Scroll_Cols2Upd-- 
04940. BNE PRG030_9AC5 ; While Scroll_Cols2Upd <> 0, loop! 
04941.  
04942. LDA #$ff 
04943. STA <Scroll_RightUpd ; Scroll_RightUpd = $ff (marker as in "not last updated"; flat for dirty) 
04944. STA <Scroll_LeftUpd ; Scroll_LeftUpd = $ff (marker as in "not last updated"; flat for dirty) 
04945. JMP SetPages_ByTileset ; JUMP to SetPages_ByTileset to reset pages (will take care of the RTS) 
04946.  
04947. PRG030_9B10: 
04948.  
04949. ; Scroll_LastDir = 0 
04950. LDA #$00 
04951. STA <Scroll_LastDir 
04952.  
04953. ; Vert_Scroll = $E0 
04954. LDA #$e0 
04955. STA <Vert_Scroll 
04956.  
04957. ; Scroll_RightUpd = $E8 
04958. ADD #$08 
04959. STA <Scroll_RightUpd 
04960.  
04961. ; Scroll_ColumnR = (Level_SizeOrig - 1) | $E0 
04962. LDY Level_SizeOrig ; Y = Level_SizeOrig 
04963. DEY ; Y-- 
04964. TYA 
04965. ORA #$e0 
04966. STA <Scroll_ColumnR 
04967.  
04968. PRG030_9B26: 
04969. ; Set proper Page @ A000 for tile layout data 
04970. LDY Level_Tileset 
04971. LDA TileLayoutPage_ByTileset,Y  
04972. STA PAGE_A000  
04973. JSR PRGROM_Change_A000 
04974.  
04975. JSR VScroll_PageAndDoPatAttrRow ; Do the row of patterns and attributes for vertical scroll 
04976.  
04977. ; Set page @ A000 to 26 
04978. LDA #26 
04979. STA PAGE_A000 
04980. JSR PRGROM_Change_A000 
04981.  
04982. JSR Scroll_ToVRAM_Apply ; Applies Scroll_ToVRAMHi and Scroll_ToVRAMHA updates 
04983. JSR Scroll_ToVRAM_Apply ; Applies Scroll_ToVRAMHi and Scroll_ToVRAMHA updates 
04984.  
04985. LDA <Vert_Scroll 
04986. ADD #$08 
04987. STA <Vert_Scroll 
04988.  
04989. CMP #$f0 
04990. BNE PRG030_9B59 ; If not changing to new screen, jump to PRG030_9B59 
04991.  
04992. INC <Scroll_VOffsetT ; Scroll_VOffsetT++ 
04993.  
04994. ; Loop vertical offset to new screen 
04995. LDA <Scroll_VOffsetT 
04996. AND #$0f 
04997. STA <Scroll_VOffsetT 
04998.  
04999. JMP PRG030_9B66 ; Jump to PRG030_9B66 
05000.  
05001. PRG030_9B59: 
05002. LDA <Vert_Scroll 
05003. AND #$08 
05004. BNE PRG030_9B66 ; If only halfway vertically through tile row, jump to PRG030_9B66 
05005.  
05006. ; Otherwise, go to next row 
05007. LDA <Scroll_VOffsetT 
05008. ADD #$10 
05009. STA <Scroll_VOffsetT 
05010.  
05011. PRG030_9B66: 
05012. LDA <Vert_Scroll 
05013. CMP #$d0 
05014. BNE PRG030_9B26 ; While Vert_Scroll <> $D0, loop! 
05015.  
05016. LDA #$00 
05017. STA <Vert_Scroll ; Vert_Scroll = 0 
05018. STA <Scroll_VertUpd ; Scroll_VertUpd = 0 
05019.  
05020. RTS ; Return 
05021.  
05022.  
05023. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05024. ; Scroll_Update 
05025. ; 
05026. ; This subroutine updates one column of tiles worth 
05027. ; of scroll (tile and attribute) as needed per 
05028. ; changes in Horz_Scroll 
05029. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05030. Scroll_Update: 
05031. LDA Level_7Vertical 
05032. BNE PRG030_9BB2 ; If this is a vertical scroller world, jump to PRG030_9BB2 
05033.  
05034. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05035. LDA <Horz_Scroll ; A = Horz_Scroll 
05036. AND #$f8 ; Only caring about every 8 pixels (for valid comparison to Scroll_RightUpd) 
05037. CMP <Scroll_RightUpd,X ; Compared to whichever update applies to the last scroll 
05038. BEQ PRG030_9BA9 ; If we are updated completely, jump to PRG030_9BA9 
05039.  
05040. ; Otherwise ... 
05041. TAY ; Y = A (Horz_Scroll, 8 pixel aligned) 
05042.  
05043. LDA Scroll_Cols2Upd 
05044. BNE PRG030_9B9B ; If columns remain to be updated, jump to PRG030_9B9B 
05045.  
05046. LDA <Horz_Scroll 
05047. AND #$07 ; How many pixels across a tile boundary of 8 (0 - 7) 
05048.  
05049. CPX #$00 
05050. BNE PRG030_9B97 ; If last scroll direction <> 0 (last moved left), jump to PRG030_9B97 
05051.  
05052. ; Last moved right... 
05053. CMP #$02 
05054. BGE PRG030_9B9B ; If greater-or-equal to 2 pixels to the right, jump to PRG030_9B9B 
05055.  
05056. JMP PRG030_9BA9 ; Otherwise, jump to PRG030_9BA9 
05057.  
05058. PRG030_9B97: 
05059. ; Last moved left... 
05060.  
05061. CMP #$05 
05062. BGE PRG030_9BA9 ; If greater-or-equal to 5 pixels in (complement to 2 pixels from right case), jump to PRG030_9BA9 
05063.  
05064. ; Otherwise... 
05065.  
05066. PRG030_9B9B: 
05067. STY <Scroll_RightUpd,X ; Store our right/left update 
05068.  
05069. LDA <Scroll_LastDir 
05070. EOR #$01  
05071. TAX  
05072. LDA #$ff  
05073. STA <Scroll_RightUpd,X ; Store $FF on the other side 
05074.  
05075. JSR Scroll_DoColumn ; Render a column of tiles... 
05076.  
05077. PRG030_9BA9: 
05078. LDA Scroll_UpdAttrFlag  
05079. BEQ PRG030_9BB1 ; If Scroll_UpdAttrFlag is not set (not time to update attributes), jump to PRG030_9BB1 (RTS) 
05080.  
05081. JSR Scroll_Do_AttrColumn ; Otherwise, Render a column of attributes... 
05082.  
05083. PRG030_9BB1: 
05084. RTS ; Return 
05085.  
05086.  
05087. PRG030_9BB2: 
05088. LDA <Vert_Scroll 
05089. AND #$f8 
05090. CMP <Scroll_VertUpd 
05091. BEQ PRG030_9BD2 ; If the vertical scroll hasn't changed 8 pixels, jump to PRG030_9BD2 (RTS) 
05092.  
05093. ; Otherwise, change the Scroll_VertUpd value 
05094. LDA <Vert_Scroll 
05095. AND #$f8 
05096. STA <Scroll_VertUpd 
05097.  
05098. VScroll_PageAndDoPatAttrRow: 
05099. ; Set proper Page @ A000 for tile layout data 
05100. LDY Level_Tileset 
05101. LDA TileLayoutPage_ByTileset,Y  
05102. STA PAGE_A000  
05103. JSR PRGROM_Change_A000 
05104.  
05105. JSR VScroll_CalcPatternVRAMAddr ; Calculate start of pattern row 
05106. JSR VScroll_DoPatternAndAttrRow ; Do the pattern row AND attributes 
05107.  
05108. PRG030_9BD2: 
05109. RTS ; Return 
05110.  
05111. PRG030_9BD3: .byte $00, $01 
05112.  
05113. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05114. ; Scroll_DoColumn  
05115. ; 
05116. ; This subroutine renders a "column" of 8x8 blocks for the 
05117. ; screen scrolling. Also used by the "dirty update" routine 
05118. ; to sweep across and render the blocks... 
05119. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05120. Scroll_DoColumn: 
05121. ; Set proper Page @ A000 for tile layout data 
05122. LDY Level_Tileset 
05123. LDA TileLayoutPage_ByTileset,Y  
05124. STA PAGE_A000  
05125. JSR PRGROM_Change_A000 
05126.  
05127. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05128. LDA <Scroll_RightUpd,X ; Related last update value 
05129. AND #$08 ; Take just whether we've moved onto an 8 
05130. LSR A  
05131. LSR A  
05132. LSR A  
05133. STA <Scroll_OddEven ; <Scroll_OddEven is 0 for 0, 1 for 8 
05134. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05135. LDA <Horz_Scroll ; A = Horz_Scroll 
05136. AND #$0f ; A is now 0-15 
05137. CPX #$00  
05138. BNE PRG030_9BFD ; If Scroll_LastDir = 0 (last scrolled right), jump to PRG030_9BFD 
05139.  
05140. ; Last scrolled left 
05141. CMP #$04  
05142. BGE PRG030_9C01 ; If the horizontal scroll is 4-15, jump to PRG030_9C01 
05143. JMP PRG030_9C06 ; Otherwise, jump to PRG030_9C06 
05144.  
05145. PRG030_9BFD: 
05146. ; Last scrolled right 
05147. CMP #12  
05148. BGE PRG030_9C06 ; If the horizontal scroll is 12-15, jump to PRG030_9C06 
05149.  
05150. PRG030_9C01: ; (Scrolled left and scroll is 4-15) OR (Scrolled right and scroll is 0-11) 
05151.  
05152. ; Scroll_UpdAttrFlag = 1 (time to update attributes!) 
05153. LDA #$01 
05154. STA Scroll_UpdAttrFlag 
05155.  
05156. PRG030_9C06: 
05157. LDA Level_Tileset  
05158. ASL A ; A = Level_Tileset << 1 (index into TileLayout_ByTileset) 
05159. TAY ; -> 'Y' 
05160.  
05161. ; A tile is laid out like: 
05162. ; 02 
05163. ; 13 
05164.  
05165. ; Store the low byte of the address into Temp_Var11/Temp_Var13 
05166. ; This defines addresses used to look up the construction of a tile 
05167. ; by its index number; note that top and bottom half use a common 
05168. ; low byte. 
05169. LDA TileLayout_ByTileset,Y 
05170. STA <Temp_Var11  
05171. STA <Temp_Var13  
05172.  
05173. ; The following takes the high byte of the "TileLayout_ByTileset" 
05174. ; and either adds nothing or a jump of 512, and still adds a jump of 
05175. ; 256 to the after address  
05176. LDX TileLayout_ByTileset+1,Y ; X = High byte of address (block 0 of tile) 
05177. LDA <Scroll_OddEven ; A = Scroll_OddEven 
05178. BEQ PRG030_9C1B ; If Scroll_OddEven = 0, jump to PRG030_9C1B 
05179. INX ; +256 (block 1) 
05180. INX ; +256 (block 2) beginning of the right half 
05181.  
05182. PRG030_9C1B: 
05183. STX <Temp_Var12 ; High byte [?] into Temp_Var12 
05184. INX ; block 1 or 3, depending on Scroll_OddEven 
05185. STX <Temp_Var14 ; High byte [?] into Temp_Var14 
05186.  
05187. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05188. LDA <Scroll_ColumnR,X ; A = appropriate current column (right or left) 
05189. AND #$f0 ; Checking what screen we're on (every 16 columns is a screen's worth) 
05190. LSR A  
05191. LSR A  
05192. LSR A  
05193. TAY ; Y = ((Scroll_ColumnR & $F0) >> 3), or basically, 2 for every screen we've moved (for indexing...) 
05194.  
05195. ; Set the address of the tiles we need to modify! 
05196. LDA Tile_Mem_Addr,Y 
05197. STA <Temp_Var15  
05198. LDA Tile_Mem_Addr+1,Y 
05199. STA <Temp_Var16  
05200.  
05201. LDA #26 ; Number of rows to update (NTSC res of 224, two screens tall, is 448 / 16px-per-tile = 26) 
05202. STA <Temp_Var1 ; Temp_Var1 = 26 (see immediately above) 
05203. LDA <Scroll_ColumnR,X ; Get the column we're on 
05204. AND #$0f ; Make it relative to THIS screen, 0-15 
05205. STA <Temp_Var2 ; Temp_Var2 stores this value 
05206.  
05207. LDX #$00 ; X = 0 
05208. PRG030_9C40: 
05209. LDY <Temp_Var2 ; Y = Temp_Var2 (screen relative column) 
05210. LDA [Temp_Var15],Y ; Get tile to display 
05211. TAY ; Tile becomes offset 'Y' 
05212.  
05213. ; Store the top block for this tile 
05214. LDA [Temp_Var11],Y 
05215. STA Scroll_PatStrip,X 
05216.  
05217. ; Store the bottom block for this tile 
05218. LDA [Temp_Var13],Y 
05219. STA Scroll_PatStrip+1,X 
05220.  
05221. LDA <Temp_Var2 
05222. ADD #16  
05223. STA <Temp_Var2 ; Temp_Var2 += 16 (next row in this column is 16 bytes down) 
05224. BCC PRG030_9C5A ; If we haven't overflowed, jump to PRG030_9C5A 
05225. INC <Temp_Var16 ; Otherwise we need to increment the upper part of the tile address 
05226. PRG030_9C5A: 
05227. INX  
05228. INX ; X += 2 (two tiles added) 
05229.  
05230. DEC <Temp_Var1 ; Temp_Var1-- 
05231. BPL PRG030_9C40 ; If more tiles to go, loop! 
05232.  
05233.  
05234. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05235. LDA <Scroll_ColumnR,X ; A = last column value 
05236. AND #$0f ; Screen column relative 
05237. ASL A ; A << 1 (0, 2, 4, ... E) 
05238. ORA <Scroll_OddEven ; Apply the odd/even (forms an 8x8 current column) 
05239. STA Scroll_LastCol8 ; Store this in Scroll_LastCol8 
05240.  
05241. LDA #$20 ;  
05242. STA Scroll_ToVRAMHi ; Scroll_ToVRAMHi = $20 
05243. JMP SetPages_ByTileset ; JUMP to SetPages_ByTileset (restores page A000 most importantly, and will do the RTS) 
05244.  
05245.  
05246. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05247. ; Scroll_Do_AttrColumn 
05248. ; 
05249. ; This subroutine renders a "column" of attributes for the 
05250. ; screen scrolling. Also used by the "dirty update" routine 
05251. ; to sweep across and render the blocks... 
05252. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05253. PRG030_9C74: 
05254. .byte $F1, $01 
05255.  
05256. PRG030_9C76: 
05257. .byte $ff, $0f 
05258.  
05259. Scroll_Do_AttrColumn: 
05260. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05261. LDY <Scroll_ColumnR,X ; Y = get column 
05262. TYA ; A = Y 
05263. AND #$01 ; Get odd/even 
05264. BEQ PRG030_9C87 ; If even, jump to PRG030_9C87 
05265.  
05266. TYA ; A = back to column again 
05267. ADD PRG030_9C76,X ; Add appropriate value, whether going right or left (-1 or +15) 
05268. TAY ; Y = A 
05269.  
05270. PRG030_9C87: 
05271. STY <Temp_Var1 ; column, possibly offset, into Temp_Var1 
05272. LDA #$00  
05273. STA <Temp_Var2 ; Temp_Var2 = 0 
05274.  
05275. PRG030_9C8D: 
05276. LDA <Temp_Var1 ; A = Temp_Var1 (column, possibly offset) 
05277. AND #$f0 ; Figure out which SCREEN we're on 
05278. LSR A  
05279. LSR A  
05280. LSR A ; A >> 3 (2 byte per screen index) 
05281. TAY ; Y = A 
05282.  
05283. ; Setup pointer to tile memory we need to be focusing on! 
05284. LDA Tile_Mem_Addr,Y  
05285. STA <Temp_Var15  
05286. LDA Tile_Mem_Addr+1,Y  
05287. STA <Temp_Var16  
05288.  
05289. LDX <Temp_Var2 ; X = Temp_Var2 
05290. LDA <Temp_Var1 ; A = Temp_Var1 
05291. AND #$0f ; Current screen-relative column 
05292. TAY ; Y = A (screen relative column) 
05293. PRG030_9CA6: 
05294. LDA [Temp_Var15],Y ; Get next tile 
05295. AND #$c0 ; Set attributes based on the "range" of the tile, like palette 0 for tiles 00-3f, palette 1 for tiles 40-7f, etc. 
05296. STA <Scroll_ColorStrip,X ; Store this into the attribute strip 
05297. TYA ; A = Y (the tile offset) 
05298. ADD #16 ; A += 16 (every tile row is 16 bytes) 
05299. TAY ; Y = A 
05300. BCC PRG030_9CB5 ; If we didn't overflow, jump to PRG030_9CB5 
05301. INC <Temp_Var16 ; Increment the high byte 
05302. PRG030_9CB5: 
05303. INX ; X++ (next byte in the Scroll_ColorStrip) 
05304. STX <Temp_Var2 ; Temp_Var2 = X 
05305. CPX #27  
05306. BNE PRG030_9CD0 ; If X <> 27, jump to PRG030_9CD0 
05307.  
05308. ; X is 27, we need to go to the next page 
05309. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05310. LDY <Scroll_ColumnR,X ; Get the column 
05311. TYA ; A = Y 
05312. AND #$01 ;  
05313. BNE PRG030_9CCB ; If odd, jump to PRG030_9CCB 
05314. TYA ; A = Y (back to the column) 
05315. ADD PRG030_9C74,X 
05316. TAY ; -> 'Y' 
05317. PRG030_9CCB: 
05318. STY <Temp_Var1 ; -> Temp_Var1 
05319. JMP PRG030_9C8D ; Loop around again... 
05320.  
05321. PRG030_9CD0: 
05322. CPX #54 
05323. BNE PRG030_9CA6 ; If A <> 54, loop! 
05324.  
05325.  
05326. LDY #$00 ; Y = 0 
05327. LDX #$00 ; X = 0  
05328.  
05329. PRG030_9CD8: 
05330. ; Attributes store colors for 4 tiles in one byte, this 
05331. ; forms the coloring information for all four blocks; this 
05332. ; also explains the odd-but-necessary offsets 
05333. LDA <Scroll_ColorStrip,X 
05334. LSR A  
05335. LSR A ; A >>= 2 
05336. ORA <Scroll_ColorStrip+27,X 
05337. LSR A  
05338. LSR A ; A >>= 2  
05339. ORA <Scroll_ColorStrip+1,X 
05340. LSR A  
05341. LSR A ; A >>= 2 
05342. ORA <Scroll_ColorStrip+28,X 
05343.  
05344. STA Scroll_AttrStrip,Y 
05345. INX ; X++ 
05346. INX ; X++ 
05347. CPY #$07  
05348. BNE PRG030_9CF8 ; If Y <> 7, jump to PRG030_9CF8 
05349.  
05350. ; Only store half the attribute data on row 7 
05351. LDA Scroll_AttrStrip,Y  
05352. AND #$0f 
05353. STA Scroll_AttrStrip,Y  
05354. DEX ; X-- ; Redo other half later! 
05355.  
05356. PRG030_9CF8: 
05357. INY ; Y++ 
05358. CPY #14  
05359. BNE PRG030_9CD8 ; If Y <> 14, loop! 
05360.  
05361. LDA #$23  
05362. STA Scroll_ToVRAMHA ; Scroll_ToVRAMHA = $23 
05363. LDX <Scroll_LastDir  
05364. LDA <Scroll_ColumnR,X ; Get column 
05365. AND #$0f ; Screen relative 
05366. LSR A ; A >> 1 (every two blocks when dealing with attributes) 
05367. ORA #$c0 ; $C0 is the base offset into Attribute Table 0/2 
05368. STA Scroll_LastAttr ; Store into Scroll_LastAttr 
05369.  
05370. ; Scroll_UpdAttrFlag = 0 
05371. LDA #$00  
05372. STA Scroll_UpdAttrFlag 
05373.  
05374. RTS ; Return! 
05375.  
05376.  
05377. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05378. ; VScroll_CalcPatternVRAMAddr 
05379. ; 
05380. ; Calculates Scroll_ToVRAMHi/Lo for patterns for the current vertical scroll 
05381. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05382. VScroll_CalcPatternVRAMAddr: 
05383. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05384.  
05385. ; Calculate VRAM High into nametable for this offset 
05386. LDA <Scroll_VOffsetT,X 
05387. AND #$c0 
05388. LSR A 
05389. LSR A 
05390. LSR A 
05391. LSR A 
05392. LSR A 
05393. LSR A 
05394. ADD #$20 
05395. STA Scroll_ToVRAMHi 
05396.  
05397. ; Calculate VRAM Low into nametable for this offset 
05398. LDA <Scroll_VOffsetT,X 
05399. AND #$30 
05400. ASL A 
05401. ASL A 
05402. STA Scroll_LastOff8 
05403.  
05404. LDA <Vert_Scroll 
05405. AND #$08 
05406. BEQ PRG030_9D3E ; If not on odd row, jump to PRG030_9D3E (RTS) 
05407.  
05408. ; +32 bytes to offset to reach next tile row in VRAM 
05409. LDA Scroll_LastOff8 
05410. ADD #32 
05411. STA Scroll_LastOff8 
05412.  
05413. PRG030_9D3E: 
05414. RTS ; Return 
05415.  
05416.  
05417. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05418. ; VScroll_DoPatternAndAttrRow 
05419. ; 
05420. ; This subroutine renders a "row" of 8x8 blocks for the vertical 
05421. ; screen scrolling. Also creates the attributes for the same. 
05422. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05423. VScroll_DoPatternAndAttrRow: 
05424. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05425.  
05426. LDA <Scroll_VOffsetT,X ; Get proper offset based on direction of scroll 
05427. AND #$0f 
05428. TAY ; Y = offset column 
05429.  
05430. ; Get address of tile at this vertical position 
05431. LDA Tile_Mem_AddrVL,Y 
05432. STA <Map_Tile_AddrL 
05433. LDA Tile_Mem_AddrVH,Y 
05434. STA <Map_Tile_AddrH 
05435.  
05436. ; Temp_Var9 = offset at leftmost column in current row 
05437. LDA <Scroll_VOffsetT,X 
05438. AND #$f0 
05439. STA <Temp_Var9 
05440.  
05441. ; Temp_Var10 = 0 
05442. LDA #$00 
05443. STA <Temp_Var10 
05444.  
05445. PRG030_9D5A: 
05446. LDY <Temp_Var9 ; Y = current offset along row 
05447. LDA [Map_Tile_AddrL],Y ; Get tile here 
05448. STA <Temp_Var11 ; -> Temp_Var11 
05449.  
05450. INC <Temp_Var9 ; Temp_Var9++ (next column) 
05451.  
05452. JSR TileLayout_GetBaseAddr ; Get tile layout address -> Temp_Var13/14 
05453.  
05454. LDX <Temp_Var10 ; X = Temp_Var10 
05455.  
05456. LDA <Vert_Scroll 
05457. AND #$08 
05458. BEQ PRG030_9D6F ; If not vertically halfway on the tile, jump to PRG030_9D6F 
05459.  
05460. INC <Temp_Var14 ; Otherwise, Temp_Var14++ (next row of layout) 
05461.  
05462. PRG030_9D6F: 
05463. LDA [Temp_Var13],Y ; Get pattern of tile 
05464. STA Scroll_PatStrip,X ; Store into pattern strip 
05465.  
05466. INX ; X++ (next pattern strip byte) 
05467.  
05468. ; Temp_Var14 += 2 (next adjacent tile pattern) 
05469. INC <Temp_Var14 
05470. INC <Temp_Var14 
05471.  
05472. LDA [Temp_Var13],Y ; Get pattern of tile 
05473. STA Scroll_PatStrip,X ; Store into pattern strip 
05474.  
05475. INX ; X++ (next pattern strip byte) 
05476.  
05477. STX <Temp_Var10 ; X -> Temp_Var10 
05478.  
05479. CPX #$20 
05480. BLT PRG030_9D5A ; If not at end of strip row, loop 
05481.  
05482. LDA Scroll_LastOff8 
05483. CMP #$20 
05484. BEQ PRG030_9D92 ; If Scroll_LastOff8 = $20 (end of top row), jump to PRG030_9D92 
05485.  
05486. CMP #$a0 
05487. BEQ PRG030_9D92 ; If Scroll_LastOff8 = $A0 (end of bottom row), jump to PRG030_9D92 
05488.  
05489. BNE PRG030_9D98 ; Otherwise, jump to PRG030_9D98 (RTS) 
05490.  
05491. PRG030_9D92: 
05492. JSR VScroll_CalcAttributeVRAMAddr ; Calculate the attribute VRAM addresses 
05493. JSR Scroll_Do_AttrRow ; Do row of attributes 
05494.  
05495. PRG030_9D98: 
05496. RTS ; Return 
05497.  
05498.  
05499. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05500. ; VScroll_CalcAttributeVRAMAddr 
05501. ; 
05502. ; Calculates Scroll_ToVRAMHA/Scroll_LastAttr for attributes for the current vertical scroll 
05503. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05504. VScroll_CalcAttributeVRAMAddr: 
05505.  
05506. ; VRAM High address to attributes 
05507. LDA #$23 
05508. STA Scroll_ToVRAMHA 
05509.  
05510. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05511.  
05512. ; VRAM Low address to attributes 
05513. LDA <Scroll_VOffsetT,X ; Get proper offset based on direction of scroll 
05514. AND #$c0 
05515. LSR A 
05516. LSR A 
05517. ADD #$c0 
05518. STA Scroll_LastAttr 
05519.  
05520. LDA <Scroll_VOffsetT,X 
05521. AND #$20 
05522. BEQ PRG030_9DBB  
05523.  
05524. ; Scroll_LastAttr += 8 
05525. LDA Scroll_LastAttr 
05526. ADD #$08 
05527. STA Scroll_LastAttr 
05528.  
05529. PRG030_9DBB: 
05530. RTS ; Return 
05531.  
05532.  
05533. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05534. ; Scroll_Do_AttrRow 
05535. ; 
05536. ; This subroutine renders a "row" of attributes for the 
05537. ; screen scrolling. 
05538. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05539. Scroll_Do_AttrRow: 
05540. LDX <Scroll_LastDir ; X = Scroll_LastDir 
05541.  
05542. LDA <Scroll_VOffsetT,X ; Get proper offset based on direction of scroll 
05543. AND #$0f 
05544. TAY ; Y = offset column 
05545.  
05546. ; Get address of tile at this vertical position 
05547. LDA Tile_Mem_AddrVL,Y 
05548. STA <Map_Tile_AddrL 
05549. LDA Tile_Mem_AddrVH,Y 
05550. STA <Map_Tile_AddrH 
05551.  
05552. ; Temp_Var9 = offset at leftmost column in current row 
05553. LDA <Scroll_VOffsetT,X 
05554. AND #$f0 
05555. STA <Temp_Var9 
05556.  
05557. AND #$10 
05558. BNE PRG030_9DDE 
05559.  
05560. LDA <Temp_Var9 
05561. ADD #$10 
05562. STA <Temp_Var9  
05563.  
05564. PRG030_9DDE: 
05565. INC <Temp_Var9 ; Temp_Var9++ (next column) 
05566.  
05567. ; Temp_Var8 = 0 
05568. LDA #$00 
05569. STA <Temp_Var8 
05570. PRG030_9DE4: 
05571. LDY <Temp_Var9 ; Y = current offset along row 
05572. JSR VScroll_TileQuads2Attrs ; Create attribute bits out of tile values 
05573.  
05574. ; Y -= 15 (previous row; 15 because VScroll_TileQuads2Attrs already subtracted 1) 
05575. TYA 
05576. SUB #$0f 
05577. TAY 
05578.  
05579. JSR VScroll_TileQuads2Attrs ; Create attribute bits out of tile values 
05580.  
05581. ; Temp_Var9 += 2 (next 2 columns over) 
05582. INC <Temp_Var9 
05583. INC <Temp_Var9 
05584.  
05585. ; Temp_Var8++ (next Scroll_AttrStrip byte) 
05586. INC <Temp_Var8 
05587.  
05588. LDA <Temp_Var8 
05589. CMP #$08 
05590. BLT PRG030_9DE4 ; While not at end of row, loop 
05591.  
05592. LDA Scroll_LastAttr 
05593. CMP #$f8 
05594. BNE PRG030_9E11 
05595.  
05596. LDY #$07 ; Y = 7 
05597. PRG030_9E06: 
05598.  
05599. LDA Scroll_AttrStrip,Y 
05600. AND #$0f 
05601. STA Scroll_AttrStrip,Y 
05602.  
05603. DEY ; Y-- 
05604. BPL PRG030_9E06 ; While Y >= 0, loop 
05605.  
05606. PRG030_9E11: 
05607. RTS ; Return 
05608.  
05609. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05610. ; TileLayout_GetBaseAddr 
05611. ; 
05612. ; Set layout pointer for the active tileset -> Temp_Var13/14 
05613. ; also reloads 'Y' with the tile in Temp_Var11 
05614. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05615. TileLayout_GetBaseAddr: 
05616. LDA Level_Tileset  
05617. ASL A 
05618. TAX ; X = Level_Tileset * 2 
05619.  
05620. ; Set Temp_Var13/14 to point to the layout data for this Tileset 
05621. LDA TileLayout_ByTileset,X 
05622. STA <Temp_Var13 
05623. LDA TileLayout_ByTileset+1,X 
05624. STA <Temp_Var14 
05625.  
05626. LDY <Temp_Var11 ; Y = tile temp 
05627.  
05628. RTS ; Return 
05629.  
05630.  
05631. VScroll_TileQuads2Attrs: 
05632. LDX <Temp_Var8 ; X = Temp_Var8 (Scroll_AttrStrip offset) 
05633.  
05634. LDA [Map_Tile_AddrL],Y ; Get the tile 
05635.  
05636. ; "Quadrant" bits (6 and 7) are pushed in as attribute bits 
05637. ASL A 
05638. ROL Scroll_AttrStrip,X 
05639. ASL A 
05640. ROL Scroll_AttrStrip,X 
05641.  
05642. DEY ; Y-- 
05643.  
05644. LDA [Map_Tile_AddrL],Y ; Get the tile 
05645.  
05646. ; "Quadrant" bits (6 and 7) are pushed in as attribute bits 
05647. ASL A 
05648. ROL Scroll_AttrStrip,X 
05649. ASL A 
05650. ROL Scroll_AttrStrip,X 
05651.  
05652. RTS ; Return 
05653.  
05654.  
05655. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05656. ; Player_GetTileV 
05657. ; 
05658. ; Gets tile in vertical level 
05659. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05660. Player_GetTileV: ; $9E3C  
05661.  
05662. ; Temp_Var13 / Temp_Var14 -- Y Hi and Lo 
05663. ; Temp_Var15 / Temp_Var16 -- X Hi and Lo 
05664.  
05665. LDA <Temp_Var13 ; A = Temp_Var13 (Y Hi) 
05666. PHA ; Save it 
05667. TAY ; Y = Y Hi 
05668.  
05669. LDA <Temp_Var14 ; A = Temp_Var14 (Y Lo) 
05670. PHA ; Save it 
05671.  
05672. JSR LevelJct_GetVScreenH 
05673.  
05674. STA <Temp_Var14 ; Adjusted Y for vertical -> Temp_Var14 
05675.  
05676. ; Select root offset into tile memory 
05677. LDA Tile_Mem_AddrVL,Y 
05678. STA <Map_Tile_AddrL 
05679. LDA Tile_Mem_AddrVH,Y 
05680. STA <Map_Tile_AddrH 
05681.  
05682. ; Combine positions into Temp_Var15 to form tile mem offset 
05683. LDA <Temp_Var14 
05684. AND #$f0 
05685. STA <Temp_Var15 
05686.  
05687. LDA <Temp_Var16 
05688. LSR A 
05689. LSR A 
05690. LSR A 
05691. LSR A 
05692. ORA <Temp_Var15 
05693.  
05694. TAY ; Offset -> 'Y' 
05695.  
05696. PLA ; Restore original value for Temp_Var14 
05697. STA <Temp_Var14 ; Store it 
05698.  
05699. PLA ; Restore original value for Temp_Var13 
05700. STA <Temp_Var13 ; Store it 
05701.  
05702. LDA [Map_Tile_AddrL],Y ; Get tile 
05703. STA <Level_Tile ; Store into Level_Tile 
05704.  
05705. RTS ; Return 
05706.  
05707.  
05708. ; This is basically a lookup for any given "Player Y Hi" shifted up 4 bits 
05709. PRG030_9E6C: 
05710. .byte $00, $10, $20, $30, $40, $50, $60, $70, $80, $90, $A0, $B0, $C0, $D0, $E0, $F0 
05711.  
05712. ; Translates the Player position into appropriate "high" value 
05713. ; as Vertical describes it ($0(00), $0(F0), $1(E0), ...) 
05714. LevelJct_GetVScreenH: 
05715. ; Y = Player_YHi 
05716. ; A = Player_Y 
05717.  
05718. CPY #$00 
05719. BLS PRG030_9E8E ; If Y < 0 (i.e. if the Player Y High is less than zero, which shouldn't happen!), jump to PRG030_9E8E (RTS) 
05720.  
05721. ADD PRG030_9E6C,Y ; Player_Y += Player_YHi[Y] 
05722. BCS PRG030_9E8A ; If carry set (overflow occurred), jump to PRG030_9E8A 
05723.  
05724. CMP #$f0  
05725. BLT PRG030_9E8E ; If result is < $F0, jump to PRG030_9E8E 
05726.  
05727. PRG030_9E8A: 
05728. ; Add $10 and roll over 'Y' (Considered in the lower vertical half) 
05729. ADD #$10 
05730. INY  
05731.  
05732. PRG030_9E8E: 
05733. RTS ; Return 
05734.  
05735.  
05736. ; Something similar to LevelJct_GetVScreenH, but I'm  
05737. ; not quite following the purpose 
05738. LevelJct_GetVScreenH2: 
05739. ; A = Player_Y 
05740. ; Y = Player_YHi 
05741. CPY #$00 
05742. BLS PRG030_9E9A ; If YHi < 0 (shouldn't happen?), jump to PRG030_9E9A 
05743.  
05744. SUB PRG030_9E6C,Y 
05745. BCS PRG030_9E9A ; If carry set, jump to PRG030_9E9A 
05746.  
05747. DEY ; Y-- 
05748.  
05749. PRG030_9E9A: 
05750. RTS ; Return 
05751.  
05752.  
05753. ; FIXME: Anybody want to claim this?? 
05754. ; $9E9B 
05755. .byte $F0, $20 
05756.  
05757. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05758. ; Player_GetTileAndSlope_Normal 
05759. ; 
05760. ; Get tile and slope for given position and offset 
05761. ; for non-vertical ("normal") levels 
05762. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
05763. Player_GetTileAndSlope_Normal: ; $9E9D 
05764.  
05765. ; Temp_Var13 / Temp_Var14 -- Y Hi and Lo 
05766. ; Temp_Var15 / Temp_Var16 -- X Hi and Lo 
05767.  
05768. ; Clear slope array 
05769. LDA #$00  
05770. STA <Player_Slopes 
05771. STA <Player_Slopes+1 ; Not used; see below with Temp_Var1 assignment 
05772. STA <Player_Slopes+2 ; Not used; see below with Temp_Var1 assignment 
05773.  
05774. LDA <Temp_Var16 
05775. LSR A 
05776. LSR A 
05777. LSR A 
05778. LSR A 
05779. STA <Level_TileOff ; Level_TileOff = Temp_Var16 >> 4 (current column Player is in) 
05780.  
05781. LDA <Temp_Var15 
05782. AND #$0f  
05783. ASL A  
05784. TAX ; X = (Temp_Var15 & $0F) << 1 (current "high" part of Player X shifted up by 1, indexing Tile Mem) 
05785.  
05786. ; Set Map_Tile_AddrL/H to appropriate screen based on Player's position 
05787. LDA Tile_Mem_Addr,X 
05788. STA <Map_Tile_AddrL 
05789. LDA Tile_Mem_Addr+1,X 
05790. STA <Map_Tile_AddrH 
05791.  
05792. LDA <Temp_Var13 
05793. BEQ PRG030_9EC3 ; If Temp_Var13 (Y Hi) = 0, jump to PRG030_9EC3 
05794.  
05795. INC <Map_Tile_AddrH ; Otherwise, go to second half of screen 
05796.  
05797. PRG030_9EC3: 
05798. LDA <Temp_Var14 
05799. AND #$f0 
05800. ORA <Level_TileOff ; Level_TileOff gets the Player's current row in the upper 4 bits 
05801.  
05802. ; Level_TileOff is now Player's current offset in Tile Mem from the selected pointer 
05803.  
05804. STA <Temp_Var12 ; ... and copied into Temp_Var12 
05805.  
05806. TAY ; Y = current offset 
05807. LDA [Map_Tile_AddrL],Y ; Get tile here 
05808. STA <Level_Tile ; Store into Level_Tile 
05809.  
05810. LDY Level_Tileset 
05811. CPY #3 
05812. BEQ PRG030_9EDB ; If Level_Tileset = 3 (Hills style), jump to PRG030_9EDB 
05813.  
05814. CPY #14 
05815. BNE PRG030_9F0D ; If Level_Tileset <> 14 (Underground), jump to PRG030_9F0D 
05816.  
05817. PRG030_9EDB: 
05818. ; NOTE: Temp_Var1 = 0 and is used directly; at one time there was probably some kind 
05819. ; of loop here that would have implicated Player_Slopes+1 and Player_Slopes+2 
05820. LDA #$00 
05821. STA <Temp_Var1 ; Temp_Var1 = 0 
05822.  
05823. LDY <Temp_Var12 ; Y = current offset in Tile Mem 
05824. LDA [Map_Tile_AddrL],Y ; Get tile here 
05825. STA <Temp_Var2 ; Store into Temp_Var2 
05826.  
05827. AND #$c0 
05828. CLC 
05829. ROL A 
05830. ROL A 
05831. ROL A 
05832. TAY ; Y = tile quadrant (0 to 3) 
05833.  
05834. LDA <Temp_Var2 ; Re-get tile 
05835. CMP Tile_AttrTable,Y 
05836. BLT PRG030_9F0D ; If it's less than the tile specified in Tile_AttrTable[Y], jump to PRG030_9F0D 
05837.  
05838. TYA 
05839. ASL A 
05840. TAX ; X = Y (tile quadrant) << 1 (two byte index) 
05841.  
05842. ; Temp_Var3/4 are loaded with address inside PRG000_C000 
05843. LDA Level_SlopeSetByQuad,X 
05844. STA <Temp_Var3 
05845. LDA Level_SlopeSetByQuad+1,X 
05846. STA <Temp_Var4 
05847.  
05848. LDX <Temp_Var1 ; X = Temp_Var1 (always 0) 
05849. LDA <Temp_Var2 ; A = Temp_Var2 (the retrieved tile) 
05850. SUB Tile_AttrTable,Y ; Subtract the root tile value 
05851. TAY ; Y = result 
05852.  
05853. LDA [Temp_Var3],Y ; Get value  
05854. STA <Player_Slopes,X ; Store into Player_Slopes 
05855.  
05856. PRG030_9F0D: 
05857. LDA <Level_Tile ; A = Level_Tile (the tile retrieved) 
05858. RTS ; Return 
05859.  
05860. ; Probably unused space 
05861. .byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff 
05862. .byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff 
05863. .byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff 
05864.  
05865.  
05866. PRG030_SUB_9F40: 
05867. LDA #$00 
05868. STA Raster_State ; Reset Raster_State 
05869.  
05870. LDA Update_Request 
05871. JMP PRG031_F499 
05872.  
05873. ; Filler space 
05874. .byte $ff, $ff, $ff, $ff, $ff 
05875.  
05876. ; Sub part of A0 mode of IRQ 
05877. PRG030_SUB_9F50: 
05878. ; Some kind of delay loop? 
05879. LDX #$17 ; X = $17 
05880. PRG030_9F52: 
05881. NOP ; ? 
05882. DEX ; X-- 
05883. BPL PRG030_9F52 ; While X > 0, loop 
05884.  
05885. ; Latch this value, and force it into the counter! 
05886. STA MMC3_IRQLATCH 
05887. STA MMC3_IRQDISABLE 
05888. STA MMC3_IRQENABLE 
05889. RTS ; Return 
05890.  
05891. ; Probably unused space 
05892. .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF 
05893. .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF 
05894.  
05895. IntIRQ_32PixelPartition_Part5: 
05896.  
05897. ; Some kind of delay loop? 
05898. LDX #$13 ; X = $13 
05899. PRG030_9F80: 
05900. NOP ; ? 
05901. DEX ; X-- 
05902. BPL PRG030_9F80 ; While X > 0, loop 
05903.  
05904. ; More NOPs 
05905. NOP 
05906. NOP 
05907. NOP 
05908.  
05909. STA MMC3_IRQLATCH ; Latch A (last set to 27!) 
05910. STA MMC3_IRQENABLE ; Enable IRQ again 
05911. JMP PRG031_FA3C ; Jump to PRG031_FA3C 
05912.  
05913. ; Unused space 
05914. .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF 
05915.  
05916. IntIRQ_32PixelPartition_Part2: ; $9FA0 
05917. LDA Update_Request  
05918. AND #UPDATERASTER_32PIXSHOWSPR 
05919. BNE PRG030_9FAA ; If UPDATERASTER_32PIXSHOWSPR is set, go to PRG030_9FAA 
05920.  
05921. ; Otherwise, change loaded pattern tables to hide sprites that fall beneath the 32 pixel partition 
05922. JMP IntIRQ_32PixPart_HideSprites 
05923.  
05924. PRG030_9FAA: 
05925.  
05926. ; I think the following NOPs and loop are to help synchronize the IRQ 
05927. ; routine if it didn't perform the IntIRQ_32PixPart_HideSprites step 
05928. NOP 
05929. NOP 
05930. NOP 
05931.  
05932. LDX #$03 ; X = 3 
05933. PRG030_9FAF: 
05934. NOP ; ? 
05935. DEX ; X-- 
05936. BPL PRG030_9FAF ; While X > 0, loop 
05937.  
05938. JMP IntIRQ_32PixelPartition_Part3 
05939.  
05940. ; NOTE: The remaining ROM space was all blank ($FF) 
05941.  
05942.