cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

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   = 0x0001 ; Default platform MBC rom switching address
     21
     22        rRAMG           = 0x0000 ; $0000->$1fff
     23        rROMB0          = 0x0001 ; $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           = 0x20  ; Sound register
     96        rNR10           = 0xFF20
     97        rAUD1SWEEP      = 0xFF20
     98
     99        AUD1SWEEP_UP    = 0b00000000
    100        AUD1SWEEP_DOWN  = 0b00001000
    101
    102        .NR11           = 0x22  ; Sound register
    103        rNR11           = 0xFF22
    104        rAUD1LEN        = 0xFF22
    105
    106        .NR12           = 0x21  ; Sound register
    107        rNR12           = 0xFF21
    108        rAUD1ENV        = 0xFF21
    109        
    110        .NR13           = 0x23  ; Sound register
    111        rNR13           = 0xFF23
    112        rAUD1LOW        = 0xFF23
    113
    114        .NR14           = 0x24  ; Sound register
    115        rNR14           = 0xFF24
    116        rAUD1HIGH       = 0xFF24
    117
    118        .NR21           = 0x25  ; Sound register
    119        rNR21           = 0xFF25
    120        rAUD2LEN        = 0xFF25
    121
    122        .NR22           = 0x27  ; Sound register
    123        rNR22           = 0xFF27
    124        rAUD2ENV        = 0xFF27
    125
    126        .NR23           = 0x28  ; Sound register
    127        rNR23           = 0xFF28
    128        rAUD2LOW        = 0xFF28
    129
    130        .NR24           = 0x29  ; Sound register
    131        rNR24           = 0xFF29
    132        rAUD2HIGH       = 0xFF29
    133
    134        .NR30           = 0x2A  ; Sound register
    135        rNR30           = 0xFF2A
    136        rAUD3ENA        = 0xFF2A
    137
    138        .NR31           = 0x2B  ; Sound register
    139        rNR31           = 0xFF2B
    140        rAUD3LEN        = 0xFF2B
    141
    142        .NR32           = 0x2C  ; Sound register
    143        rNR32           = 0xFF2C
    144        rAUD3LEVEL      = 0xFF2C
    145
    146        .NR33           = 0x2E  ; Sound register
    147        rNR33           = 0xFF2E
    148        rAUD3LOW        = 0xFF2E
    149
    150        .NR34           = 0x2D  ; Sound register
    151        rNR34           = 0xFF2D
    152        rAUD3HIGH       = 0xFF2D
    153
    154        .NR41           = 0x40  ; Sound register
    155        rNR41           = 0xFF40
    156        rAUD4LEN        = 0xFF40
    157
    158        .NR42           = 0x42  ; Sound register
    159        rNR42           = 0xFF42
    160        rAUD4ENV        = 0xFF42
    161
    162        .NR43           = 0x41  ; Sound register
    163        rNR43           = 0xFF41
    164        rAUD4POLY       = 0xFF41
    165
    166        .NR44           = 0x43  ; Sound register
    167        rNR44           = 0xFF43
    168        rAUD4GO         = 0xFF43
    169
    170        .NR50           = 0x44  ; Sound register
    171        rNR50           = 0xFF44
    172        rAUDVOL         = 0xFF44
    173
    174        AUDVOL_VIN_LEFT  = 0b10000000 ; SO2
    175        AUDVOL_VIN_RIGHT = 0b00001000 ; SO1
    176
    177        .NR51           = 0x46  ; Sound register
    178        rNR51           = 0xFF46
    179        rAUDTERM        = 0xFF46
    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           = 0x45  ; Sound register
    191        rNR52           = 0xFF45
    192        rAUDENA         = 0xFF45
    193
    194        AUDENA_ON       = 0b10000000
    195        AUDENA_OFF      = 0b00000000  ; sets all audio regs to 0!
    196
    197        .LCDC           = 0x10  ; LCD control
    198        rLCDC           = 0xFF10
    199
    200        LCDCF_OFF       = 0b00000000 ; LCD Control Operation
    201        LCDCF_ON        = 0b10000000 ; LCD Control Operation
    202        LCDCF_WIN9800   = 0b00000000 ; Window Tile Map Display Select
    203        LCDCF_WIN9C00   = 0b00001000 ; Window Tile Map Display Select
    204        LCDCF_WINOFF    = 0b00000000 ; Window Display
    205        LCDCF_WINON     = 0b00100000 ; Window Display
    206        LCDCF_BG8800    = 0b00000000 ; BG & Window Tile Data Select
    207        LCDCF_BG8000    = 0b00010000 ; BG & Window Tile Data Select
    208        LCDCF_BG9800    = 0b00000000 ; BG Tile Map Display Select
    209        LCDCF_BG9C00    = 0b00000100 ; BG Tile Map Display Select
    210        LCDCF_OBJ8      = 0b00000000 ; OBJ Construction
    211        LCDCF_OBJ16     = 0b00000010 ; OBJ Construction
    212        LCDCF_OBJOFF    = 0b00000000 ; OBJ Display
    213        LCDCF_OBJON     = 0b00000001 ; OBJ Display
    214        LCDCF_BGOFF     = 0b00000000 ; BG Display
    215        LCDCF_BGON      = 0b01000000 ; BG Display
    216        LCDCF_B_ON      = 7
    217        LCDCF_B_WIN9C00 = 3
    218        LCDCF_B_WINON   = 5
    219        LCDCF_B_BG8000  = 4
    220        LCDCF_B_BG9C00  = 2
    221        LCDCF_B_OBJ16   = 1
    222        LCDCF_B_OBJON   = 0
    223        LCDCF_B_BGON    = 6
    224
    225        .STAT           = 0x11  ; LCD status
    226        rSTAT           = 0xFF11
    227
    228        STATF_LYC       = 0b01000000 ; LYC=LY Coincidence (Selectable)
    229        STATF_MODE10    = 0b00100000 ; Mode 10
    230        STATF_MODE01    = 0b00010000 ; Mode 01 (V-Blank)
    231        STATF_MODE00    = 0b00001000 ; Mode 00 (H-Blank)
    232        STATF_LYCF      = 0b00000100 ; Coincidence Flag
    233        STATF_HBL       = 0b00000000 ; H-Blank
    234        STATF_VBL       = 0b00000001 ; V-Blank
    235        STATF_OAM       = 0b00000010 ; OAM-RAM is used by system
    236        STATF_LCD       = 0b00000011 ; Both OAM and VRAM used by system
    237        STATF_BUSY      = 0b00000010 ; When set, VRAM access is unsafe
    238        STATF_B_LYC     = 6
    239        STATF_B_MODE10  = 5
    240        STATF_B_MODE01  = 4
    241        STATF_B_MODE00  = 3
    242        STATF_B_LYCF    = 2
    243        STATF_B_VBL     = 0
    244        STATF_B_OAM     = 1
    245        STATF_B_BUSY    = 1
    246
    247        .SCY            = 0x12  ; Scroll Y
    248        rSCY            = 0xFF12
    249
    250        .SCX            = 0x13  ; Scroll X
    251        rSCX            = 0xFF13
    252
    253        .LY             = 0x18  ; LCDC Y-coordinate
    254        rLY             = 0xFF18
    255
    256        .LYC            = 0x19  ; LY compare
    257        rLYC            = 0xFF19
    258
    259        .DMA            = 0x1A  ; DMA transfer
    260        rDMA            = 0xFF1A
    261
    262        .BGP            = 0x1B  ; BG palette data
    263        rBGP            = 0xFF1B
    264
    265        .OBP0           = 0x14  ; OBJ palette 0 data
    266        rOBP0           = 0xFF14
    267
    268        .OBP1           = 0x15  ; OBJ palette 1 data
    269        rOBP1           = 0xFF15
    270
    271        .WY             = 0x16  ; Window Y coordinate
    272        rWY             = 0xFF16
    273
    274        .WX             = 0x17  ; Window X coordinate
    275        rWX             = 0xFF17
    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