global.s (17029B)
1 .NEAR_CALLS = 1 ; <near_calls> - tag so that sed can change this 2 3 _VRAM = 0x8000 ; $8000->$9FFF 4 _VRAM8000 = 0x8000 5 _VRAM8800 = 0x8800 6 _VRAM9000 = 0x9000 7 _SCRN0 = 0x9800 ; $9800->$9BFF 8 _SCRN1 = 0x9C00 ; $9C00->$9FFF 9 _SRAM = 0xA000 ; $A000->$BFFF 10 _RAM = 0xC000 ; $C000->$CFFF / $C000->$DFFF 11 _RAMBANK = 0xD000 ; $D000->$DFFF 12 _OAMRAM = 0xFE00 ; $FE00->$FE9F 13 _IO = 0xFF00 ; $FF00->$FF7F,$FFFF 14 _AUD3WAVERAM = 0xFF30 ; $FF30->$FF3F 15 _HRAM = 0xFF80 ; $FF80->$FFFE 16 17 ;; MBC Equates 18 19 .MBC1_ROM_PAGE = 0x2000 ; Address to write to for MBC1 switching 20 .MBC_ROM_PAGE = 0x2000 ; Default platform MBC rom switching address 21 22 rRAMG = 0x0000 ; $0000->$1fff 23 rROMB0 = 0x2000 ; $2000->$2fff 24 rROMB1 = 0x3000 ; $3000->$3fff - If more than 256 ROM banks are present. 25 rRAMB = 0x4000 ; $4000->$5fff - Bit 3 enables rumble (if present) 26 27 ;; Keypad 28 .START = 0x80 29 .SELECT = 0x40 30 .B = 0x20 31 .A = 0x10 32 .DOWN = 0x08 33 .UP = 0x04 34 .LEFT = 0x02 35 .RIGHT = 0x01 36 37 .P14 = 0x10 38 .P15 = 0x20 39 40 ;; Screen dimensions 41 .MAXCURSPOSX = 0x13 ; In tiles 42 .MAXCURSPOSY = 0x11 43 44 .SCREENWIDTH = 0xA0 45 .SCREENHEIGHT = 0x90 46 .MINWNDPOSX = 0x07 47 .MINWNDPOSY = 0x00 48 .MAXWNDPOSX = 0xA6 49 .MAXWNDPOSY = 0x8F 50 51 ;; Hardware registers 52 53 .P1 = 0x00 ; Joystick: 1.1.P15.P14.P13.P12.P11.P10 54 rP1 = 0xFF00 55 56 P1F_5 = 0b00100000 ; P15 out port, set to 0 to get buttons 57 P1F_4 = 0b00010000 ; P14 out port, set to 0 to get dpad 58 P1F_3 = 0b00001000 ; P13 in port 59 P1F_2 = 0b00000100 ; P12 in port 60 P1F_1 = 0b00000010 ; P11 in port 61 P1F_0 = 0b00000001 ; P10 in port 62 63 P1F_GET_DPAD = 0b00100000 64 P1F_GET_BTN = 0b00010000 65 P1F_GET_NONE = 0b00110000 66 67 .SB = 0x01 ; Serial IO data buffer 68 rSB = 0xFF01 69 70 .SC = 0x02 ; Serial IO control register 71 rSC = 0xFF02 72 73 .DIV = 0x04 ; Divider register 74 rDIV = 0xFF04 75 76 .TIMA = 0x05 ; Timer counter 77 rTIMA = 0xFF05 78 79 .TMA = 0x06 ; Timer modulo 80 rTMA = 0xFF06 81 82 .TAC = 0x07 ; Timer control 83 rTAC = 0xFF07 84 85 TACF_START = 0b00000100 86 TACF_STOP = 0b00000000 87 TACF_4KHZ = 0b00000000 88 TACF_16KHZ = 0b00000011 89 TACF_65KHZ = 0b00000010 90 TACF_262KHZ = 0b00000001 91 92 .IF = 0x0F ; Interrupt flags: 0.0.0.JST.SIO.TIM.LCD.VBL 93 rIF = 0xFF0F 94 95 .NR10 = 0x10 ; Sound register 96 rNR10 = 0xFF10 97 rAUD1SWEEP = 0xFF10 98 99 AUD1SWEEP_UP = 0b00000000 100 AUD1SWEEP_DOWN = 0b00001000 101 102 .NR11 = 0x11 ; Sound register 103 rNR11 = 0xFF11 104 rAUD1LEN = 0xFF11 105 106 .NR12 = 0x12 ; Sound register 107 rNR12 = 0xFF12 108 rAUD1ENV = 0xFF12 109 110 .NR13 = 0x13 ; Sound register 111 rNR13 = 0xFF13 112 rAUD1LOW = 0xFF13 113 114 .NR14 = 0x14 ; Sound register 115 rNR14 = 0xFF14 116 rAUD1HIGH = 0xFF14 117 118 .NR21 = 0x16 ; Sound register 119 rNR21 = 0xFF16 120 rAUD2LEN = 0xFF16 121 122 .NR22 = 0x17 ; Sound register 123 rNR22 = 0xFF17 124 rAUD2ENV = 0xFF17 125 126 .NR23 = 0x18 ; Sound register 127 rNR23 = 0xFF18 128 rAUD2LOW = 0xFF18 129 130 .NR24 = 0x19 ; Sound register 131 rNR24 = 0xFF19 132 rAUD2HIGH = 0xFF19 133 134 .NR30 = 0x1A ; Sound register 135 rNR30 = 0xFF1A 136 rAUD3ENA = 0xFF1A 137 138 .NR31 = 0x1B ; Sound register 139 rNR31 = 0xFF1B 140 rAUD3LEN = 0xFF1B 141 142 .NR32 = 0x1C ; Sound register 143 rNR32 = 0xFF1C 144 rAUD3LEVEL = 0xFF1C 145 146 .NR33 = 0x1D ; Sound register 147 rNR33 = 0xFF1D 148 rAUD3LOW = 0xFF1D 149 150 .NR34 = 0x1E ; Sound register 151 rNR34 = 0xFF1E 152 rAUD3HIGH = 0xFF1E 153 154 .NR41 = 0x20 ; Sound register 155 rNR41 = 0xFF20 156 rAUD4LEN = 0xFF20 157 158 .NR42 = 0x21 ; Sound register 159 rNR42 = 0xFF21 160 rAUD4ENV = 0xFF21 161 162 .NR43 = 0x22 ; Sound register 163 rNR43 = 0xFF22 164 rAUD4POLY = 0xFF22 165 166 .NR44 = 0x23 ; Sound register 167 rNR44 = 0xFF23 168 rAUD4GO = 0xFF23 169 170 .NR50 = 0x24 ; Sound register 171 rNR50 = 0xFF24 172 rAUDVOL = 0xFF24 173 174 AUDVOL_VIN_LEFT = 0b10000000 ; SO2 175 AUDVOL_VIN_RIGHT = 0b00001000 ; SO1 176 177 .NR51 = 0x25 ; Sound register 178 rNR51 = 0xFF25 179 rAUDTERM = 0xFF25 180 181 AUDTERM_4_LEFT = 0b10000000 182 AUDTERM_3_LEFT = 0b01000000 183 AUDTERM_2_LEFT = 0b00100000 184 AUDTERM_1_LEFT = 0b00010000 185 AUDTERM_4_RIGHT = 0b00001000 186 AUDTERM_3_RIGHT = 0b00000100 187 AUDTERM_2_RIGHT = 0b00000010 188 AUDTERM_1_RIGHT = 0b00000001 189 190 .NR52 = 0x26 ; Sound register 191 rNR52 = 0xFF26 192 rAUDENA = 0xFF26 193 194 AUDENA_ON = 0b10000000 195 AUDENA_OFF = 0b00000000 ; sets all audio regs to 0! 196 197 .LCDC = 0x4E ; LCD control 198 rLCDC = 0xFF4E 199 200 LCDCF_OFF = 0b00000000 ; LCD Control Operation 201 LCDCF_ON = 0b00000001 ; LCD Control Operation 202 LCDCF_WIN9800 = 0b00000000 ; Window Tile Map Display Select 203 LCDCF_WIN9C00 = 0b00000010 ; Window Tile Map Display Select 204 LCDCF_WINOFF = 0b00000000 ; Window Display 205 LCDCF_WINON = 0b00000100 ; Window Display 206 LCDCF_BG8800 = 0b00000000 ; BG & Window Tile Data Select 207 LCDCF_BG8000 = 0b00001000 ; BG & Window Tile Data Select 208 LCDCF_BG9800 = 0b00000000 ; BG Tile Map Display Select 209 LCDCF_BG9C00 = 0b00010000 ; BG Tile Map Display Select 210 LCDCF_OBJ8 = 0b00000000 ; OBJ Construction 211 LCDCF_OBJ16 = 0b00100000 ; OBJ Construction 212 LCDCF_OBJOFF = 0b00000000 ; OBJ Display 213 LCDCF_OBJON = 0b01000000 ; OBJ Display 214 LCDCF_BGOFF = 0b00000000 ; BG Display 215 LCDCF_BGON = 0b10000000 ; BG Display 216 LCDCF_B_ON = 0 217 LCDCF_B_WIN9C00 = 1 218 LCDCF_B_WINON = 2 219 LCDCF_B_BG8000 = 3 220 LCDCF_B_BG9C00 = 4 221 LCDCF_B_OBJ16 = 5 222 LCDCF_B_OBJON = 6 223 LCDCF_B_BGON = 7 224 225 .STAT = 0x41 ; LCD status 226 rSTAT = 0xFF41 227 228 STATF_LYC = 0b00000010 ; LYC=LY Coincidence (Selectable) 229 STATF_MODE10 = 0b00000100 ; Mode 10 230 STATF_MODE01 = 0b00001000 ; Mode 01 (V-Blank) 231 STATF_MODE00 = 0b00010000 ; Mode 00 (H-Blank) 232 STATF_LYCF = 0b00100000 ; Coincidence Flag 233 STATF_HBL = 0b00000000 ; H-Blank 234 STATF_VBL = 0b10000000 ; V-Blank 235 STATF_OAM = 0b01000000 ; OAM-RAM is used by system 236 STATF_LCD = 0b11000000 ; Both OAM and VRAM used by system 237 STATF_BUSY = 0b01000000 ; When set, VRAM access is unsafe 238 STATF_B_LYC = 1 239 STATF_B_MODE10 = 2 240 STATF_B_MODE01 = 3 241 STATF_B_MODE00 = 4 242 STATF_B_LYCF = 5 243 STATF_B_VBL = 7 244 STATF_B_OAM = 6 245 STATF_B_BUSY = 6 246 247 .SCY = 0x42 ; Scroll Y 248 rSCY = 0xFF42 249 250 .SCX = 0x43 ; Scroll X 251 rSCX = 0xFF43 252 253 .LY = 0x44 ; LCDC Y-coordinate 254 rLY = 0xFF44 255 256 .LYC = 0x45 ; LY compare 257 rLYC = 0xFF45 258 259 .DMA = 0x46 ; DMA transfer 260 rDMA = 0xFF46 261 262 .BGP = 0x47 ; BG palette data 263 rBGP = 0xFF47 264 265 .OBP0 = 0x48 ; OBJ palette 0 data 266 rOBP0 = 0xFF48 267 268 .OBP1 = 0x49 ; OBJ palette 1 data 269 rOBP1 = 0xFF49 270 271 .WY = 0x4A ; Window Y coordinate 272 rWY = 0xFF4A 273 274 .WX = 0x4B ; Window X coordinate 275 rWX = 0xFF4B 276 277 .KEY1 = 0x4D ; CPU speed 278 rKEY1 = 0xFF4D 279 rSPD = 0xFF4D 280 281 KEY1F_DBLSPEED = 0b10000000 ; 0=Normal Speed, 1=Double Speed (R) 282 KEY1F_PREPARE = 0b00000001 ; 0=No, 1=Prepare (R/W) 283 284 .VBK = 0x4F ; VRAM bank 285 rVBK = 0xFF4F 286 287 .HDMA1 = 0x51 ; DMA control 1 288 rHDMA1 = 0xFF51 289 290 .HDMA2 = 0x52 ; DMA control 2 291 rHDMA2 = 0xFF52 292 293 .HDMA3 = 0x53 ; DMA control 3 294 rHDMA3 = 0xFF53 295 296 .HDMA4 = 0x54 ; DMA control 4 297 rHDMA4 = 0xFF54 298 299 .HDMA5 = 0x55 ; DMA control 5 300 rHDMA5 = 0xFF55 301 302 HDMA5F_MODE_GP = 0b00000000 ; General Purpose DMA (W) 303 HDMA5F_MODE_HBL = 0b10000000 ; HBlank DMA (W) 304 305 HDMA5F_BUSY = 0b10000000 ; 0=Busy (DMA still in progress), 1=Transfer complete (R) 306 307 .RP = 0x56 ; IR port 308 rRP = 0xFF56 309 310 RPF_ENREAD = 0b11000000 311 RPF_DATAIN = 0b00000010 ; 0=Receiving IR Signal, 1=Normal 312 RPF_WRITE_HI = 0b00000001 313 RPF_WRITE_LO = 0b00000000 314 315 .BCPS = 0x68 ; BG color palette specification 316 rBCPS = 0xFF68 317 318 BCPSF_AUTOINC = 0b10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing) 319 320 .BCPD = 0x69 ; BG color palette data 321 rBCPD = 0xFF69 322 323 .OCPS = 0x6A ; OBJ color palette specification 324 rOCPS = 0xFF6A 325 326 OCPSF_AUTOINC = 0b10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing) 327 328 .OCPD = 0x6B ; OBJ color palette data 329 rOCPD = 0xFF6B 330 331 .SVBK = 0x70 ; WRAM bank 332 rSVBK = 0xFF70 333 rSMBK = 0xFF70 334 335 rPCM12 = 0xFF76 336 337 rPCM34 = 0xFF77 338 339 .IE = 0xFF ; Interrupt enable 340 rIE = 0xFFFF 341 342 .VBL_IFLAG = 0x01 343 .LCD_IFLAG = 0x02 344 .TIM_IFLAG = 0x04 345 .SIO_IFLAG = 0x08 346 .JOY_IFLAG = 0x10 347 348 IEF_HILO = 0b00010000 ; Transition from High to Low of Pin number P10-P13 349 IEF_SERIAL = 0b00001000 ; Serial I/O transfer end 350 IEF_TIMER = 0b00000100 ; Timer Overflow 351 IEF_STAT = 0b00000010 ; STAT 352 IEF_VBLANK = 0b00000001 ; V-Blank 353 354 ;; Flags common to multiple sound channels 355 356 AUDLEN_DUTY_12_5 = 0b00000000 ; 12.5% 357 AUDLEN_DUTY_25 = 0b01000000 ; 25% 358 AUDLEN_DUTY_50 = 0b10000000 ; 50% 359 AUDLEN_DUTY_75 = 0b11000000 ; 75% 360 361 AUDENV_UP = 0b00001000 362 AUDENV_DOWN = 0b00000000 363 364 AUDHIGH_RESTART = 0b10000000 365 AUDHIGH_LENGTH_ON = 0b01000000 366 AUDHIGH_LENGTH_OFF = 0b00000000 367 368 ;; OAM related constants 369 370 OAM_COUNT = 40 ; number of OAM entries in OAM RAM 371 372 OAMF_PRI = 0b10000000 ; Priority 373 OAMF_YFLIP = 0b01000000 ; Y flip 374 OAMF_XFLIP = 0b00100000 ; X flip 375 OAMF_PAL0 = 0b00000000 ; Palette number; 0,1 (DMG) 376 OAMF_PAL1 = 0b00010000 ; Palette number; 0,1 (DMG) 377 OAMF_BANK0 = 0b00000000 ; Bank number; 0,1 (GBC) 378 OAMF_BANK1 = 0b00001000 ; Bank number; 0,1 (GBC) 379 380 OAMF_PALMASK = 0b00000111 ; Palette (GBC) 381 382 OAMB_PRI = 7 ; Priority 383 OAMB_YFLIP = 6 ; Y flip 384 OAMB_XFLIP = 5 ; X flip 385 OAMB_PAL1 = 4 ; Palette number; 0,1 (DMG) 386 OAMB_BANK1 = 3 ; Bank number; 0,1 (GBC) 387 388 ;; SGB packets 389 .PAL_01 = 0x00 390 .PAL_23 = 0x01 391 .PAL_03 = 0x02 392 .PAL_12 = 0x03 393 .ATTR_BLK = 0x04 394 .ATTR_LIN = 0x05 395 .ATTR_DIV = 0x06 396 .ATTR_CHR = 0x07 397 .SOUND = 0x08 398 .SOU_TRN = 0x09 399 .PAL_SET = 0x0A 400 .PAL_TRN = 0x0B 401 .ATRC_EN = 0x0C 402 .TEST_EN = 0x0D 403 .ICON_EN = 0x0E 404 .DATA_SND = 0x0F 405 .DATA_TRN = 0x10 406 .MLT_REQ = 0x11 407 .JUMP = 0x12 408 .CHR_TRN = 0x13 409 .PCT_TRN = 0x14 410 .ATTR_TRN = 0x15 411 .ATTR_SET = 0x16 412 .MASK_EN = 0x17 413 .OBJ_TRN = 0x18 414 415 ;; CPU detection 416 .DMG_TYPE = 0x01 ; Original GB or Super GB 417 .MGB_TYPE = 0xFF ; Pocket GB or Super GB 2 418 .CGB_TYPE = 0x11 ; Color GB 419 420 ;; GBDK library screen modes 421 422 .G_MODE = 0x01 ; Graphic mode 423 .T_MODE = 0x02 ; Text mode (bit 2) 424 .T_MODE_OUT = 0x02 ; Text mode output only 425 .T_MODE_INOUT = 0x03 ; Text mode with input 426 .M_NO_SCROLL = 0x04 ; Disables scrolling of the screen in text mode 427 .M_NO_INTERP = 0x08 ; Disables special character interpretation 428 429 ;; Status codes for IO 430 .IO_IDLE = 0x00 431 .IO_SENDING = 0x01 432 .IO_RECEIVING = 0x02 433 .IO_ERROR = 0x04 434 435 ;; Type of IO data 436 .DT_IDLE = 0x66 437 .DT_RECEIVING = 0x55 438 439 ;; Table of routines for modes 440 .MODE_TABLE = 0x01E0 441 442 ;; C related 443 ;; Overheap of a banked call. Used for parameters 444 ;; = ret + real ret + bank 445 446 .if .NEAR_CALLS 447 .BANKOV = 2 448 449 .else 450 .BANKOV = 6 451 452 .endif 453 454 .globl __current_bank 455 .globl __shadow_OAM_base 456 457 ;; Global variables 458 .globl .mode 459 460 .globl __cpu 461 .globl __is_GBA 462 463 ;; Global routines 464; .globl .set_mode ;; don't link mode.o by default 465 466 .globl .reset 467 468 .globl .display_off 469 470 .globl .wait_vbl_done 471 472 ;; Interrupt routines 473 .globl .add_VBL 474; .globl .add_LCD ;; don't link LCD.o by default 475; .globl .add_TIM ;; don't link TIM.o by default 476; .globl .add_SIO ;; don't link serial.o by default 477; .globl .add_JOY ;; don't link JOY.o by default 478 479 ;; Symbols defined at link time 480 .globl .STACK 481 .globl _shadow_OAM 482 .globl .refresh_OAM 483 484 ;; Main user routine 485 .globl _main 486 487 ;; Macro definitions 488 489.macro WAIT_STAT ?lbl 490lbl: LDH A, (.STAT) 491 AND #STATF_BUSY ; Check if in LCD modes 0 or 1 492 JR NZ, lbl 493.endm 494 495.macro ADD_A_REG16 regH regL 496 ADD regL 497 LD regL, A 498 ADC regH 499 SUB regL 500 LD regH, A 501.endm 502 503.macro SIGNED_ADD_A_REG16 regH regL ?lbl 504 ; If A is negative, we need to subtract 1 from upper byte of 16-bit value 505 BIT 7, A ; set z if a signed bit is 0 506 JR Z, lbl ; if z is set jump to positive 507 dec regH ; if negative decrement upper byte 508lbl: 509 ADD_A_REG16 regH, regL 510.endm 511 512.macro SIGNED_SUB_A_REG16 regH regL ?lbl 513 ; negate A then add to 16-bit value 514 CPL 515 INC A 516 SIGNED_ADD_A_REG16 regH, regL 517.endm 518 519.macro MUL_DE_BY_A_RET_HL ?lbl1 ?lbl2 ?lbl3 520 ; Multiply DE by A, return result in HL; preserves: BC 521 LD HL, #0 522lbl1: 523 SRL A 524 JR NC, lbl2 525 ADD HL, DE 526lbl2: 527 JR Z, lbl3 528 SLA E 529 RL D 530 JR lbl1 531lbl3: 532.endm 533