Browse Source

Initial commit

master
mid-kid 4 years ago
commit
72b1ab6035
  1. 5
      .gutctags
  2. 3
      .lvimrc
  3. 7
      .tags
  4. 56
      Makefile
  5. BIN
      assets/tetrisfont.1bpp
  6. BIN
      assets/tetrisfont.png
  7. 12
      layout.link
  8. 58
      source/charmap.inc
  9. 45
      source/defines.inc
  10. 103
      source/hardware.inc
  11. 8
      source/home/audio.asm
  12. 58
      source/home/joypad.asm
  13. 24
      source/home/math.asm
  14. 54
      source/home/memory.asm
  15. 132
      source/home/serial.asm
  16. 161
      source/home/start.asm
  17. 42
      source/home/text.asm
  18. 36
      source/home/vblank.asm
  19. 54
      source/home/video.asm
  20. 127
      source/main.asm
  21. 33
      source/video.inc

5
.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

3
.lvimrc

@ -0,0 +1,3 @@
if expand("<afile>:e") ==? 'asm' || expand("<afile>:e") ==? 'inc' || expand("<afile>:e") ==? 'link'
setf rgbds
endif

7
.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 //

56
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))

BIN
assets/tetrisfont.1bpp

Binary file not shown.

BIN
assets/tetrisfont.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

12
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"

58
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

45
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

103
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

8
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

58
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

24
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

54
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

132
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

161
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

42
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

36
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

54
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

127
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$"

33
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
Loading…
Cancel
Save