commit 72b1ab6035932d7edbd7cb5414e4f5f052d0b220 Author: mid-kid Date: Wed Jul 15 23:33:15 2020 +0200 Initial commit diff --git a/.gutctags b/.gutctags new file mode 100644 index 0000000..a9f8923 --- /dev/null +++ b/.gutctags @@ -0,0 +1,5 @@ +--languages=asm +--langmap=asm:.asm.inc +--regex-asm=/^([a-z0-9_]+):+.*/\1/l,labels/i +--regex-asm=/^([a-z0-9_]+)\s+=.*/\1/c,constants/i +--regex-asm=/^([a-z0-9_]+)\s+[Ee][Qq][Uu][Ss]?.*/\1/c,constants/i diff --git a/.lvimrc b/.lvimrc new file mode 100644 index 0000000..e453939 --- /dev/null +++ b/.lvimrc @@ -0,0 +1,3 @@ +if expand(":e") ==? 'asm' || expand(":e") ==? 'inc' || expand(":e") ==? 'link' + setf rgbds +endif diff --git a/.tags b/.tags new file mode 100644 index 0000000..562754a --- /dev/null +++ b/.tags @@ -0,0 +1,7 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ +!_TAG_PROGRAM_AUTHOR Universal Ctags Team // +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ +!_TAG_PROGRAM_URL https://ctags.io/ /official site/ +!_TAG_PROGRAM_VERSION 0.0.0 // diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..db67608 --- /dev/null +++ b/Makefile @@ -0,0 +1,56 @@ +name := Something + +dir_build := build +dir_source := source +dir_assets := assets + +RGBASM := rgbasm +RGBGFX := rgbgfx +RGBLINK := rgblink +RGBFIX := rgbfix + +RGBASMFLAGS := -p 0xff -L +RGBLINKFLAGS := -p 0xff -d -t +RGBFIXFLAGS := -p 0xff -j -m 0 -r 0 -n 0 -k "HB" -i "SMTH" -t "Something" + +rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2)) +objects := $(patsubst $(dir_source)/%.asm, $(dir_build)/%.o, $(call rwildcard, $(dir_source)/, *.asm)) + +RGBASMFLAGS += -DENABLE_CGB #-DENABLE_CLEAR +RGBFIXFLAGS += -c + +.SECONDEXPANSION: + +.PHONY: all +all: $(name).gb + +.PHONY: clean +clean: + rm -rf $(name).gb $(name).sym $(name).map $(dir_build) + +$(name).gb: $(objects) + +%.gb: layout.link + $(RGBLINK) $(RGBLINKFLAGS) -l $< -n $(@:.gb=.sym) -m $(@:.gb=.map) -o $@ $(filter-out $<, $^) + $(RGBFIX) $(RGBFIXFLAGS) -v $@ + +$(dir_build)/%.o: $(dir_source)/%.asm | $$(dir $$@) + $(RGBASM) $(RGBASMFLAGS) -i $(dir_build)/ -i $(dir_source)/ -M $(@:.o=.d) -o $@ $< + +$(dir_build)/%.pal: $(dir_assets)/%.png | $$(dir $$@) + $(RGBGFX) -p $@ $< + +$(dir_build)/%.tilemap: $(dir_assets)/%.png | $$(dir $$@) + $(RGBGFX) -u -t $@ $< + +$(dir_build)/%.2bpp: $(dir_assets)/%.png | $$(dir $$@) + $(RGBGFX) -u -o $@ $< + +$(dir_build)/%.1bpp: $(dir_assets)/%.png | $$(dir $$@) + $(RGBGFX) -d 1 -u -o $@ $< + +.PRECIOUS: %/ +%/: + mkdir -p $@ + +-include $(patsubst %.o, %.d, $(objects)) diff --git a/assets/tetrisfont.1bpp b/assets/tetrisfont.1bpp new file mode 100644 index 0000000..be468d7 Binary files /dev/null and b/assets/tetrisfont.1bpp differ diff --git a/assets/tetrisfont.png b/assets/tetrisfont.png new file mode 100644 index 0000000..9d3a88c Binary files /dev/null and b/assets/tetrisfont.png differ diff --git a/layout.link b/layout.link new file mode 100644 index 0000000..b0e8199 --- /dev/null +++ b/layout.link @@ -0,0 +1,12 @@ +rom0 + org $40 + "home/vblank.asm@int40" + org $58 + "home/serial.asm@int58" + org $100 + "home/start.asm" +wram0 + "home/start.asm@wram0" +vram 0 + org $9800 + "home/video.asm@vram" diff --git a/source/charmap.inc b/source/charmap.inc new file mode 100644 index 0000000..e899243 --- /dev/null +++ b/source/charmap.inc @@ -0,0 +1,58 @@ +; vim:set syn=asm: + +if 0 ;!def(_charmap_inc_) +_charmap_inc_ equ 0 + +char: macro + charmap \1, x +x = x + 1 +endm + +x = 0 + char " " + char "0" + char "1" + char "2" + char "3" + char "4" + char "5" + char "6" + char "7" + char "8" + char "9" + char "A" + char "B" + char "C" + char "D" + char "E" + char "F" + char "G" + char "H" + char "I" + char "J" + char "K" + char "L" + char "M" + char "N" + char "O" + char "P" + char "Q" + char "R" + char "S" + char "T" + char "U" + char "V" + char "W" + char "X" + char "Y" + char "Z" + char "." + char "-" + + charmap "$", $ff + +dstr: macro + db \1, "$" +endm + +endc diff --git a/source/defines.inc b/source/defines.inc new file mode 100644 index 0000000..bfd17bf --- /dev/null +++ b/source/defines.inc @@ -0,0 +1,45 @@ +if !def(_defines_inc_) +_defines_inc_ equ 0 + +bits: macro +; Defines a _f constant and a mask constant for one +; or multiple bits in a byte. + +if _NARG < 2 +\1_f rb 1 +\1 equ 1 << \1_f +else +\1_f rb \2 +x = 0 +rept \2 +x = x << 1 | 1 +endr +\1 equ x << \1_f +endc +endm + +enum: macro +\1 rb 1 +endm + +; h_console +rsreset + enum console_dmg + enum console_mgb + enum console_cgb + enum console_agb + +; h_joypad +rsreset + bits joy_a + bits joy_b + bits joy_select + bits joy_start + bits joy_right + bits joy_left + bits joy_up + bits joy_down +joy_buttons equ joy_a | joy_b | joy_select | joy_start +joy_dpad equ joy_right | joy_left | joy_up | joy_down + +endc diff --git a/source/hardware.inc b/source/hardware.inc new file mode 100644 index 0000000..96dba15 --- /dev/null +++ b/source/hardware.inc @@ -0,0 +1,103 @@ +if !def(_hardware_inc_) +_hardware_inc_ equ 0 + +include "defines.inc" + +; Memory map +rsreset +mmap_rom0 rb $4000 +mmap_rom0_end rb 0 +mmap_romx rb $4000 +mmap_romx_end rb 0 +mmap_vram rb $2000 +mmap_vram_end rb 0 +mmap_sram rb $2000 +mmap_sram_end rb 0 +mmap_wram0 rb $1000 +mmap_wram0_end rb 0 +mmap_wramx rb $1000 +mmap_wramx_end rb 0 +mmap_echo rb $1e00 +mmap_echo_end rb 0 +mmap_oam rb $a0 +mmap_oam_end rb 0 +mmap_nu rb $60 +mmap_nu_end rb 0 +mmap_io rb $80 +mmap_io_end rb 0 +mmap_hram rb $7f +mmap_hram_end rb 0 + +rsreset +r_joyp equ $ff00 + bits r_joyp_data, 4 + bits r_joyp_select, 2 +r_joyp_select_dpad equ %10 << r_joyp_select_f +r_joyp_select_buttons equ %01 << r_joyp_select_f + +r_sb equ $ff01 + +rsreset +r_sc equ $ff02 + bits r_sc_clk_internal + bits r_sc_clk_fast +rsset _RS + 5 + bits r_sc_start + +rsreset +r_if equ $ff0f +r_ie equ $ffff + bits r_int_vblank + bits r_int_stat + bits r_int_timer + bits r_int_serial + bits r_int_joypad + +rsreset +r_nr52 equ $ff26 + bits r_nr52_ch1 + bits r_nr52_ch2 + bits r_nr52_ch3 + bits r_nr52_ch4 +rsset _RS + 3 + bits r_nr52_on + +rsreset +r_lcdc equ $ff40 + bits r_lcdc_bg_on + bits r_lcdc_obj_on + bits r_lcdc_obj_big + bits r_lcdc_bg_map_high + bits r_lcdc_tiles_low + bits r_lcdc_window_on + bits r_lcdc_window_map_high + bits r_lcdc_on + +rsreset +r_stat equ $ff41 + bits r_stat_mode, 2 + bits r_stat_lyc_match + bits r_stat_int_hblank + bits r_stat_int_vblank + bits r_stat_int_oam + bits r_stat_int_lyc +r_stat_mode_hblank equ 0 << r_stat_mode_f +r_stat_mode_vblank equ 1 << r_stat_mode_f +r_stat_mode_oam equ 2 << r_stat_mode_f +r_stat_mode_vram equ 3 << r_stat_mode_f + +r_ly equ $ff44 +r_ly_vblank equ 144 + +rsreset +r_bcps equ $ff68 + bits r_bcps_offs, 3 + bits r_bcps_pal, 3 +rsset _RS + 1 + bits r_bcps_inc + +r_bcpd equ $ff69 + +r_svbk equ $ff70 + +endc diff --git a/source/home/audio.asm b/source/home/audio.asm new file mode 100644 index 0000000..56e6e41 --- /dev/null +++ b/source/home/audio.asm @@ -0,0 +1,8 @@ +include "hardware.inc" + +section "home/audio.asm", rom0 + +audio_disable:: + ld hl, r_nr52 + res r_nr52_on_f, [hl] + ret diff --git a/source/home/joypad.asm b/source/home/joypad.asm new file mode 100644 index 0000000..4ba96d2 --- /dev/null +++ b/source/home/joypad.asm @@ -0,0 +1,58 @@ +include "hardware.inc" + +section "home/joypad.asm@hram", hram +h_joypad: db +h_joypad_down:: db +h_joypad_pressed:: db +h_joypad_released:: db + +section "home/joypad.asm", rom0 + +joypad_read:: + ld a, r_joyp_select_dpad + ldh [r_joyp], a +rept 2 + ldh a, [r_joyp] +endr + + ; Save the dpad value to the high nybble + cpl + and r_joyp_data + swap a + ld b, a + + ld a, r_joyp_select_buttons + ldh [r_joyp], a +rept 6 + ldh a, [r_joyp] +endr + + ; Save the buttons to the low nybble + cpl + and r_joyp_data + or b + ldh [h_joypad], a + + ld a, r_joyp_select + ldh [r_joyp], a + ret + +joypad_update:: + ldh a, [h_joypad] + ld b, a + ldh a, [h_joypad_down] + ld c, a + + xor b + ld d, a + and c + ldh [h_joypad_released], a + + ld a, d + and b + ldh [h_joypad_pressed], a + + ld a, b + ldh [h_joypad_down], a + + ret diff --git a/source/home/math.asm b/source/home/math.asm new file mode 100644 index 0000000..111adbc --- /dev/null +++ b/source/home/math.asm @@ -0,0 +1,24 @@ +section "home/math.asm", rom0 + +bits_swap:: + ld c, $80 + ld b, a + xor a +.loop + rrc b + jr nc, .skip + or c +.skip + rrc c + jr nc, .loop + ret + +divide:: + ld b, 0 +.loop + inc b + sub c + jr nc, .loop + dec b + add c + ret diff --git a/source/home/memory.asm b/source/home/memory.asm new file mode 100644 index 0000000..5474670 --- /dev/null +++ b/source/home/memory.asm @@ -0,0 +1,54 @@ +section "home/copy.asm", rom0 + +memcpy:: + inc b + inc c + jr .check + +.loop + ld a, [hli] + ld [de], a + inc de + +.check + dec c + jr nz, .loop + dec b + jr nz, .loop + ret + +memcpy_double:: + call swap_hl_de + + inc b + inc c + jr .check + +.loop + ld a, [de] + inc de + ld [hli], a + ld [hli], a + +.check + dec c + jr nz, .loop + dec b + jr nz, .loop + + jp swap_hl_de + +memset:: + inc b + inc c + jr .check + +.loop + ld [hli], a + +.check + dec c + jr nz, .loop + dec b + jr nz, .loop + ret diff --git a/source/home/serial.asm b/source/home/serial.asm new file mode 100644 index 0000000..3f9eeca --- /dev/null +++ b/source/home/serial.asm @@ -0,0 +1,132 @@ +include "hardware.inc" + +section "home/serial.asm@hram", hram +h_serial_len: dw +h_serial_send_ptr: dw +h_serial_recv_ptr: dw + +section "home/serial.asm@int58", rom0[$58] + push af + push hl + push bc + push de + jp serial_shift_int + +section "home/serial.asm", rom0 + +serial_shift_int: + call serial_shift + pop de + pop bc + pop hl + pop af + reti + +serial_end: + +serial_shift: + ldh a, [h_serial_len + 0] + ld c, a + ldh a, [h_serial_len + 1] + ld b, a + + ; End early if we're done + or c + ret z + + ldh a, [h_serial_recv_ptr + 0] + ld e, a + ldh a, [h_serial_recv_ptr + 1] + ld d, a + + ; Store the last received byte + or e + jr z, .no_recv + ldh a, [r_sb] + ld [de], a + inc de +.no_recv + + ; We've transferred an entire byte in both directions + dec bc + + ldh a, [h_serial_send_ptr + 0] + ld l, a + ldh a, [h_serial_send_ptr + 1] + ld h, a + + ; fallthrough + +serial_queue: + ; If the length is 0, not much should be done + ld a, b + or c + jr z, .empty + + ld a, h + or l + ld a, -1 + jr z, .no_send + ld a, [hli] +.no_send + ldh [r_sb], a + + ldh a, [r_sc] + set r_sc_start_f, a + jr .store + +.empty + ldh a, [r_sc] + res r_sc_start_f, a + +.store + ldh [r_sc], a + + ld a, c + ldh [h_serial_len + 0], a + ld a, b + ldh [h_serial_len + 1], a + + ld a, e + ldh [h_serial_recv_ptr + 0], a + ld a, d + ldh [h_serial_recv_ptr + 1], a + + ld a, l + ldh [h_serial_send_ptr + 0], a + ld a, h + ldh [h_serial_send_ptr + 1], a + + ret + +serial_finished:: +; ret: z if done, nz if not done + ldh a, [r_sc] + bit r_sc_start_f, a + ret + +serial_transfer:: +; hl: Source buffer +; de: Destination buffer +; bc: Size +; ret: nz if previous transfer is still in transit + call serial_finished + ret nz + jp serial_queue + +serial_init_master:: + ld a, 1 + db $fe ; CP A, n8 + +serial_init_slave:: + xor a + + ; fallthrough + +serial_init: + ldh [r_sc], a + + ldh a, [r_ie] + set r_int_serial_f, a + ldh [r_ie], a + ret diff --git a/source/home/start.asm b/source/home/start.asm new file mode 100644 index 0000000..afefa11 --- /dev/null +++ b/source/home/start.asm @@ -0,0 +1,161 @@ +include "hardware.inc" +include "defines.inc" + +NULL equ 0 +global NULL + +section "home/start.asm@wram0", wram0 + ds $100 - 1 +w_stack: + ds 1 + +section "home/start.asm@hram", hram +h_console:: db + +section "home/start.asm", rom0[$100] + nop + jp _start + +rept $150 - $104 + db 0 +endr + +_start: + di + + ; Attempt to detect console model + cp $ff + jr z, .console_mgb + cp $11 + jr z, .console_cgb + + ld a, console_dmg + jr .console_end + +.console_mgb + ld a, console_mgb + jr .console_end + +.console_cgb + dec b + jr z, .console_agb + ld a, console_cgb + jr .console_end + +.console_agb + ld a, console_agb + +.console_end + ldh [h_console], a + + xor a + ldh [r_ie], a + ldh [r_if], a + +if def(ENABLE_CLEAR) + ; Clear wram0 + ld hl, mmap_wram0 + ld bc, mmap_wram0_end - mmap_wram0 + call memset +endc + + ld sp, w_stack + ldh a, [h_console] + push af + +if def(ENABLE_CLEAR) + ; Clear the hram and wram1 + xor a + ld hl, mmap_hram + ld bc, mmap_hram_end - mmap_hram + call memset + ld hl, mmap_wramx + ld bc, mmap_wramx_end - mmap_wramx + call memset +endc + + pop af + ldh [h_console], a + +if def(ENABLE_CGB) && def(ENABLE_CLEAR) + ; Clear the different wram banks + cp console_cgb + jr c, .end + + ld d, 8 +.cgb_loop + dec d + ld a, d + ldh [r_svbk], a + cp 2 + jr c, .end + + ld hl, mmap_wramx + ld bc, mmap_wramx_end - mmap_wramx + call memset + + jr .cgb_loop +.end +endc + + ei + jp main + +_halt_:: + halt + jr _halt_ + +_stop_:: + ; Save registers + ldh a, [r_ie] + ld b, a + ldh a, [r_lcdc] + ld c, a + + ; Turn everything off + xor a + ldh [r_ie], a + ldh [r_if], a + ldh [r_joyp], a + call lcd_vblank_wait + xor a + ldh [r_lcdc], a + + ; Make sure the joypad doesn't inmediately trigger anything. + ld d, $ff +.wait + ldh a, [r_joyp] + cpl + and r_joyp_data + jr nz, .wait + dec d + jr nz, .wait + + stop + + ; Restore registers + ld a, c + ldh [r_lcdc], a + ld a, b + ldh [r_ie], a + ret + +_hl_:: + jp hl + +_bc_:: + push bc + ret + +_de_:: + push de + ret + +swap_hl_de:: + ld a, h + ld h, d + ld d, a + ld a, l + ld l, e + ld e, a + ret diff --git a/source/home/text.asm b/source/home/text.asm new file mode 100644 index 0000000..d0c86c6 --- /dev/null +++ b/source/home/text.asm @@ -0,0 +1,42 @@ +include "charmap.inc" + +section "home/text.asm", rom0 + +print:: +; hl: String +; de: Tilemap position + ld a, [hli] + cp "$" + ret z + call lcd_blank_wait ; TODO: Really hackish. + ld [de], a + inc de + jr print + +print_num_3digit:: +; a: Number +; de: Tilemap positon + push af + call lcd_blank_wait + xor a + ld [de], a + inc de + ld [de], a + inc de + ld [de], a + pop af + + ld l, 3 +.loop + ld c, 10 + call divide + add "0" + call lcd_blank_wait + ld [de], a + ld a, b + and a + ret z + dec de + dec l + jr nz, .loop + ret diff --git a/source/home/vblank.asm b/source/home/vblank.asm new file mode 100644 index 0000000..0335ad9 --- /dev/null +++ b/source/home/vblank.asm @@ -0,0 +1,36 @@ +include "defines.inc" +include "hardware.inc" + +section "home/vblank.asm@hram", hram +h_vblank: db + +section "home/vblank.asm@int40", rom0[$40] + push af + ld a, 1 + ldh [h_vblank], a + jp vblank + +section "home/vblank.asm", rom0 + +vblank: + push hl + push bc + push de + + call joypad_read + + pop de + pop bc + pop hl + pop af + reti + +vblank_wait:: + xor a + ldh [h_vblank], a +.loop + halt + ld a, [h_vblank] + and a + jr z, .loop + ret diff --git a/source/home/video.asm b/source/home/video.asm new file mode 100644 index 0000000..6a6600a --- /dev/null +++ b/source/home/video.asm @@ -0,0 +1,54 @@ +include "video.inc" +include "hardware.inc" + +section "home/video.asm@vram", vram[$9800] +v_bgmap1:: ds $400 +v_bgmap2:: ds $400 + +section "home/video.asm", rom0 + +lcd_vblank_wait:: + ldh a, [r_ly] + cp r_ly_vblank + 1 + jr nz, lcd_vblank_wait + ret + +lcd_blank_wait:: + push af +.loop + ldh a, [r_stat] + and r_stat_mode + cp r_stat_mode_vblank + 1 + jr nc, .loop + pop af + ret + +lcd_disable:: + call lcd_vblank_wait + + ld hl, r_lcdc + res r_lcdc_on_f, [hl] + + ld hl, r_ie + res r_int_vblank_f, [hl] + ret + +lcd_enable:: + ld hl, r_lcdc + set r_lcdc_on_f, [hl] + + ld hl, r_if + res r_int_vblank_f, [hl] + + ld hl, r_ie + set r_int_vblank_f, [hl] + ret + +vram_clear:: + xor a + ld hl, mmap_vram + ld bc, mmap_vram_end - mmap_vram + call memset + ld hl, mmap_oam + ld bc, mmap_oam_end - mmap_oam + jp memset diff --git a/source/main.asm b/source/main.asm new file mode 100644 index 0000000..50c93dd --- /dev/null +++ b/source/main.asm @@ -0,0 +1,127 @@ +include "charmap.inc" +include "defines.inc" +include "video.inc" +include "hardware.inc" + +section "main.asm@data", rom0 +gfx_font: +incbin "assets/tetrisfont.1bpp" +gfx_font_end: + +section "main.asm@vram", vram + +ds $2D tiles +v_font_dash_period: ds 2 tiles +ds $1 tiles +v_font_numbers: ds 10 tiles +ds $7 tiles +v_font_uppercase: ds 26 tiles +ds $6 tiles +v_font_lowercase: ds 26 tiles + +section "main.asm", rom0 + +main:: + call audio_disable + call lcd_disable +if def(ENABLE_CLEAR) + call vram_clear +endc + + ; Load the font + ld hl, gfx_font + ld de, v_font_numbers + ld bc, (10 tiles) / 2 + call memcpy_double + ld de, v_font_uppercase + ld bc, (26 tiles) / 2 + call memcpy_double + ld hl, gfx_font + (10 tiles) / 2 + ld de, v_font_lowercase + ld bc, (26 tiles) / 2 + call memcpy_double + ld de, v_font_dash_period + (1 tiles) + ld bc, (1 tiles) / 2 + call memcpy_double + ld de, v_font_dash_period + ld bc, (1 tiles) / 2 + call memcpy_double + + ; Setup the palettes +if def(ENABLE_CGB) + ldh a, [h_console] + cp console_cgb + jr c, .skip_pals + + ld a, r_bcps_inc | 0 << r_bcps_pal_f | 0 << r_bcps_offs_f + ld c, LOW(r_bcps) + ldh [c], a + inc c + ld b, 4 + ld a, $ff +.loop_pal_1 + ldh [c], a + dec b + jr nz, .loop_pal_1 + ld b, 4 + xor a +.loop_pal_2 + ldh [c], a + dec b + jr nz, .loop_pal_2 + +.skip_pals +endc + + ; Clear the background map + xor a + ld hl, v_bgmap1 + ld bc, bgmap_width * bgmap_height + call memset + + call lcd_enable + ld hl, string_something + bgcoord de, 5, 2 + call print + + call serial_init_master + +main_loop: + call joypad_update + bit joy_a_f, a + jr nz, .send_shit + + bgcoord hl, 7, 5 + call lcd_blank_wait + ld [hl], " " + +.continue + call vblank_wait + jr main_loop + +.send_shit + call vblank_wait + call joypad_update + bit joy_a_f, a + jr nz, .send_shit + + bgcoord hl, 7, 5 + call lcd_blank_wait + ld [hl], "A" + ld hl, transfer_buffer + ld de, NULL + ld bc, transfer_buffer.end - transfer_buffer + call serial_transfer + +.send_shit_wait + call vblank_wait + call serial_finished + jr nz, .send_shit_wait + + jr .continue + +transfer_buffer: +db $00, $11, $22, $33, $44, $55, $66, $77, $88, $99, $AA, $BB, $CC, $DD, $EE, $FF +.end + +string_something: db "SOMETHING$" diff --git a/source/video.inc b/source/video.inc new file mode 100644 index 0000000..89f7b37 --- /dev/null +++ b/source/video.inc @@ -0,0 +1,33 @@ +; vim:set syn=asm: + +if !def(_video_inc_) +_video_inc_ equ 0 + +bgmap_width equ 32 +bgmap_height equ 32 +screen_width equ 20 +screen_height equ 18 + +tile_height equ 8 +len_1bpp_tile equ 1 * tile_height +len_2bpp_tile equ 2 * tile_height +tile equs "+ len_2bpp_tile *" +tiles equs "* len_2bpp_tile" + +coord: MACRO +if _NARG < 4 + ld \1, (\3) * screen_width + (\2) + w_tilemap +else + ld \1, (\3) * screen_height + (\2) + (\4) +endc +ENDM + +bgcoord: MACRO +if _NARG < 4 + ld \1, (\3) * bgmap_width + (\2) + v_bgmap1 +else + ld \1, (\3) * bgmap_width + (\2) + (\4) +endc +ENDM + +endc