; Baguette is tasty nomnom 🥖(๑ᵔ⤙ᵔ๑) memcpy: ; src = DE, dest = HL, n = BC .loop: LD A, (DE) LD (HL+), A INC DE DEC BC XOR A CP B JR NZ =.loop CP C JR NZ =.loop RET tilemap_memcpy: ; src = DE, dest = HL, n = C .loop: LD A, (DE) LD (HL), A LD A, L INC A AND $1f LD B, A LD A, L AND $e0 OR B LD L, A INC DE DEC C XOR A CP C JR NZ =.loop RET .MACRODEF HBLANK_WAIT LD A, $reg_lcd_controller BIT 7, A JR Z, =$HBlank_Wait.End $HBlank_Wait.loop: LD A, $reg_lcd_status AND $03 CP $00 JR NZ, =$HBlank_Wait.loop $HBlank_Wait.End: .END .MACRODEF SET_WINDOW_LCDC_E LD A, $mem_display_flag BIT 3, A LD E, $00 JR Z, =$No_Window LD E, $60 $No_Window: .END .MACRODEF ENABLE_TOP_BAR XOR A LD $reg_viewport_x, A LD A, $57 LD $reg_viewport_y, A LD A, $lcdc_guibg_tilemap OR E LD $reg_lcd_controller, A LD A, $palette_bold_font LD $reg_bg_palette, A .END .MACRODEF DISABLE_TOP_BAR LD A, $mem_prepared_viewport_x LD $reg_viewport_x, A LD A, $mem_prepared_viewport_y LD $reg_viewport_y, A LD A, $mem_prepared_color_palette LD $reg_bg_palette, A LD A, $lcdc_mapbg_tilemap OR E LD $reg_lcd_controller, A .END .MACRODEF ENABLE_DIALOGUE .HBLANK_WAIT LD A, $98 LD $reg_viewport_x, A LD A, $b8 LD $reg_viewport_y, A LD A, $lcdc_guibg_tilemap OR E LD $reg_lcd_controller, A .END .MACRODEF DISABLE_DIALOGUE PUSH BC LD A, $mem_prepared_viewport_x LD B, A LD A, $mem_prepared_viewport_y LD C, A .HBLANK_WAIT LD A, B LD $reg_viewport_x, A LD A, C LD $reg_viewport_y, A LD A, $mem_prepared_color_palette LD $reg_bg_palette, A LD A, $lcdc_mapbg_tilemap OR E LD $reg_lcd_controller, A POP BC .END .MACRODEF ENABLE_VBLANK_INTERRUPTS LD A, $reg_interrupt_flags RES 0, A LD $reg_interrupt_flags, A LD A, $reg_interrupt_enable OR $01 LD $reg_interrupt_enable, A .END .MACRODEF RESET_INTERRUPTS LD A, $00 LD $reg_interrupt_flags, A .END .MACRODEF ENABLE_LYC_INTERRUPT LD A, low(=STAT_Entrypoint) LD ($mem_stat_jump_destination), A LD A, high(=STAT_Entrypoint) LD ($mem_stat_jump_destination+1), A .RESET_INTERRUPTS LD A, $40 LD $reg_lcd_status, A LD A, $02 LD $reg_interrupt_enable, A .END .MACRODEF DISABLE_LYC_INTERRUPT LD A, $reg_interrupt_enable RES 1, A LD $reg_interrupt_enable, A .END bzero: ; dest = HL, n = BC LD A, $00 .loop: LD (HL+), A INC DE DEC BC CP B JR NZ =.loop CP C JR NZ =.loop RET bff: ; dest = HL, n = BC LD A, $ff .loop: LD (HL+), A INC DE DEC BC CP B JR NZ =.loop CP C JR NZ =.loop RET .MACRODEF ABS BIT 7, A JR Z, =$end XOR $ff INC A $end: .END .MACRODEF CALL_DE LD BC, =$end PUSH BC PUSH DE RET $end: .END .MACRODEF JUMP_TABLE ; Jump table pointer in BC, index in A, also overwrites DE LD E, A LD D, $00 SLA E RL D SLA E RL D LD A, E ADD C LD E, A LD A, D ADC B LD D, A .CALL_DE .END .MACRODEF ADD_MOVING_ANIMATION_OFFSET ; Add current moving animation offset to BC, also overwrites A LD A, $mem_map_loading_flags BIT 3, A JR Z, =$end LD A, $mem_bunny_direction BIT 3, A JR Z, =$end PUSH DE DEC A XOR $01 INC A LD D, A LD A, $mem_bunny_flags BIT 0, A LD A, $mem_moving_animation_step JR Z, =$skip_double SLA A $skip_double: .ADD_A_TO_DIRECTION_BC POP DE $end: .END Print_8bit: ; Number in A, Memory Tilemap position in HL PUSH AF PUSH BC LD C, A SWAP A ; We start by the highest nibble AND $0f OR $80 LD (HL+), A LD A, C AND $0f ; Then the lowest OR $80 LD (HL+), A POP BC POP AF RET Print_8bit_Thin: ; Number in A, Memory Tilemap position in HL PUSH AF PUSH BC LD C, A SWAP A ; We start by the highest nibble AND $0f OR $b0 LD (HL+), A LD A, C AND $0f ; Then the lowest OR $b0 LD (HL+), A POP BC POP AF RET Print_str: ; Memory Tilemap position in HL, Text address in BC, FF ended PUSH AF PUSH BC .loop: LD A, (BC) CP $ff JR Z, =.end LD (HL+), A INC BC JR =.loop .end: POP BC POP AF RET strlen: ; Text address in HL, FF ended. Result in A PUSH HL PUSH BC LD B, $00 .loop: LD A, (HL+) CP $FF JR Z, =.end INC B JR =.loop .end: LD A, B POP BC POP HL RET MUL: ; B x C => EA XOR A LD E, $00 BIT 7, B JR Z, =.bit7 ADD C .bit7: SLA A RL E BIT 6, B JR Z, =.bit6 ADD C .bit6: SLA A RL E BIT 5, B JR Z, =.bit5 ADD C .bit5: SLA A RL E BIT 4, B JR Z, =.bit4 ADD C .bit4: SLA A RL E BIT 3, B JR Z, =.bit3 ADD C .bit3: SLA A RL E BIT 2, B JR Z, =.bit2 ADD C .bit2: SLA A RL E BIT 1, B JR Z, =.bit1 ADD C .bit1: SLA A RL E BIT 0, B JR Z, =.bit0 ADD C .bit0: RET RRx: ; B is the number to rotate, A & 7 is how many bits to rotate it AND $07 CP $04 CALL NC, =.swap CP $00 RET Z RRC B DEC A RET Z RRC B DEC A RET Z RRC B DEC A RET .swap: SWAP B SUB $04 RET Next_VBlank_Wait: PUSH AF .HBLANK_WAIT POP AF VBlank_Wait: PUSH AF LD A, $reg_lcd_controller BIT 7, A JR Z, =.End .loop: LD A, $reg_lcd_status AND $03 CP $01 JR NZ, =.loop .End: POP AF RET .MACRODEF CHANGE_BANK_TO_A LD $reg_rom_bank, A LD $saved_rom_bank, A .END .MACRODEF LOAD_BANK_OF =addr .ASSERT bank(.) $00 LD A, bank(=addr) .CHANGE_BANK_TO_A .END .MACRODEF BANK_CALL =addr .ASSERT bank(.) $00 PUSH AF LD A, bank(=addr) .CHANGE_BANK_TO_A POP AF CALL ptr(=addr) .END .MACRODEF BANK_CALL_A_DE .ASSERT bank(.) $00 .CHANGE_BANK_TO_A .CALL_DE .END Call_Save_Bank: ; Address in DE (bank 0) ; Breaks A LD A, $saved_rom_bank PUSH AF .CALL_DE LD A, $saved_rom_bank POP AF .CHANGE_BANK_TO_A RET .MACRODEF CALL_SAVE_BANK =addr .ASSERT bank(=addr) $00 LD DE, ptr(=addr) CALL =Call_Save_Bank .END .MACRODEF COPY_4BYTES dest src LD A, ($src) LD ($dest), A LD A, ($src+1) LD ($dest+1), A LD A, ($src+2) LD ($dest+2), A LD A, ($src+3) LD ($dest+3), A .END .MACRODEF COPY_2BYTES dest src LD A, ($src) LD ($dest), A LD A, ($src+1) LD ($dest+1), A .END