From 4538a39df43b74f6d28a2a43b9fbeebea980e119 Mon Sep 17 00:00:00 2001 From: alloncm Date: Mon, 6 Feb 2023 00:59:34 +0200 Subject: [PATCH 1/5] First test --- Makefile | 17 +++-- .../graphics_data.asm | 0 .../main.asm} | 50 +------------- src/common.asm | 49 ++++++++++++++ src/oam_internal_priority/graphics_data.asm | 41 ++++++++++++ src/oam_internal_priority/main.asm | 66 +++++++++++++++++++ 6 files changed, 165 insertions(+), 58 deletions(-) rename src/{ => color_bg_oam_priority}/graphics_data.asm (100%) rename src/{color_bg_oam_priority.asm => color_bg_oam_priority/main.asm} (86%) create mode 100644 src/oam_internal_priority/graphics_data.asm create mode 100644 src/oam_internal_priority/main.asm diff --git a/Makefile b/Makefile index 94f0a4a..9bedc2b 100644 --- a/Makefile +++ b/Makefile @@ -15,16 +15,15 @@ FIXFLAGS = -C -v -m 0 -p 0 # v - equlivant to -f lhg that fixes some header val C - for CGB only HARDWAREINC_PATH = hardware.inc/ -SRC_DIR = src -SRC_FILE = $(SRC_DIR)/color_bg_oam_priority.asm -TARGET = bg_oam_priority +define create_target = + $(RGBASM) -i $(2) -i $(HARDWAREINC_PATH) -o $(1).o $(2)/main.asm + $(RGBLINK) -o $(1).gbc $(1).o + $(RGBFIX) $(FIXFLAGS) $(1).gbc +endef -$(TARGET).gbc: $(TARGET).o - $(RGBLINK) -o $@ $^ - $(RGBFIX) $(FIXFLAGS) $@ - -$(TARGET).o: $(SRC_FILE) - $(RGBASM) -i $(SRC_DIR) -i $(HARDWAREINC_PATH) -o $@ $^ +all: + $(call create_target,bg_oam_priority,src/color_bg_oam_priority) + $(call create_target,oam_internal_priority,src/oam_internal_priority) .PHONY: clean clean: diff --git a/src/graphics_data.asm b/src/color_bg_oam_priority/graphics_data.asm similarity index 100% rename from src/graphics_data.asm rename to src/color_bg_oam_priority/graphics_data.asm diff --git a/src/color_bg_oam_priority.asm b/src/color_bg_oam_priority/main.asm similarity index 86% rename from src/color_bg_oam_priority.asm rename to src/color_bg_oam_priority/main.asm index 249ba2c..364012c 100644 --- a/src/color_bg_oam_priority.asm +++ b/src/color_bg_oam_priority/main.asm @@ -3,7 +3,7 @@ INCLUDE "graphics_data.asm" INCLUDE "hardware.inc" SECTION "std", ROM0 -INCLUDE "common.asm" +INCLUDE "../common.asm" SECTION "stat interrupt", ROM0[$48] jp hl @@ -138,55 +138,7 @@ Main:: jp .loop ; wait for interrupts ;---------------------------------------------------- -; Wait for Vblank -; Wait untill the STAT register shows vblank status -;---------------------------------------------------- -WaitVblank: - ld a, [rSTAT] - and a, %11 ; get only the mode flag - cp a, 1 ; check for 1 (the vblank status) - jr nz, WaitVblank - ret - -;---------------------------------------------------- -; Turn off the LCD display -;---------------------------------------------------- -TurnOffLcd: ld a, [rLCDC] - and a, %10000000 ; get LCDC bit 7 to check if lcd is off - cp a, 0 ; check lcdc for lcd off - ret z ; if lcd already off return and dont wait for vblank (it will never return) - call WaitVblank - ld a, 0 - ld [rLCDC], a - ret - -;---------------------------------------------------- -; Laod a pallete color with a color -; mut d - color index -; const e - oam or bg (0 for oam, 1 for bg) -; const bc - color -;---------------------------------------------------- -LoadPallete: - ld a, d - set 7, a ; in order for the pallete pointer to auto increment - bit 0, e ; check if 0 (oam) or 1 (bg) - jr z, .oam_pallete - .bg_pallete - ld [rBCPS], a - ld a, c - ld [rBCPD], a - ld a, b - ld [rBCPD], a - .oam_pallete - ld [rOCPS], a - ld a, c - ld [rOCPD], a - ld a, b - ld [rOCPD], a - ret - -;---------------------------------------------------- ; All the stat interrupt handlers - one for each ; OAM object (pipeline) ;---------------------------------------------------- diff --git a/src/common.asm b/src/common.asm index aa9dad3..e56fb02 100644 --- a/src/common.asm +++ b/src/common.asm @@ -58,4 +58,53 @@ Mulu8: jr nz, .mulloop .exit pop de + ret + +;---------------------------------------------------- +; Wait for Vblank +; Wait untill the STAT register shows vblank status +;---------------------------------------------------- +WaitVblank: + ld a, [rSTAT] + and a, %11 ; get only the mode flag + cp a, 1 ; check for 1 (the vblank status) + jr nz, WaitVblank + ret + +;---------------------------------------------------- +; Turn off the LCD display +;---------------------------------------------------- +TurnOffLcd: + ld a, [rLCDC] + and a, %10000000 ; get LCDC bit 7 to check if lcd is off + cp a, 0 ; check lcdc for lcd off + ret z ; if lcd already off return and dont wait for vblank (it will never return) + call WaitVblank + ld a, 0 + ld [rLCDC], a + ret + +;---------------------------------------------------- +; Laod a pallete color with a color +; mut d - color index +; const e - oam or bg (0 for oam, 1 for bg) +; const bc - color +;---------------------------------------------------- +LoadPallete: + ld a, d + set 7, a ; in order for the pallete pointer to auto increment + bit 0, e ; check if 0 (oam) or 1 (bg) + jr z, .oam_pallete +.bg_pallete + ld [rBCPS], a + ld a, c + ld [rBCPD], a + ld a, b + ld [rBCPD], a +.oam_pallete + ld [rOCPS], a + ld a, c + ld [rOCPD], a + ld a, b + ld [rOCPD], a ret \ No newline at end of file diff --git a/src/oam_internal_priority/graphics_data.asm b/src/oam_internal_priority/graphics_data.asm new file mode 100644 index 0000000..f889675 --- /dev/null +++ b/src/oam_internal_priority/graphics_data.asm @@ -0,0 +1,41 @@ +; Colors definition +DEF WHITE EQU $FFFF +DEF RED EQU $001F +DEF GREEN EQU $03E0 + +TileData: + ; bg tile + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + + ; oam tiles + dw `00000000 + dw `00000010 + dw `00000110 + dw `00001110 + dw `00011110 + dw `00111110 + dw `01111110 + dw `00000000 + + dw `00000000 + dw `00000020 + dw `00000220 + dw `00002220 + dw `00022220 + dw `00222220 + dw `02222220 + dw `00000000 +.end + +OAMData: + ; Y, X, Tile, attr + db 40, 46, 2, 0 + db 40, 40, 1, 0 +.end \ No newline at end of file diff --git a/src/oam_internal_priority/main.asm b/src/oam_internal_priority/main.asm new file mode 100644 index 0000000..f943182 --- /dev/null +++ b/src/oam_internal_priority/main.asm @@ -0,0 +1,66 @@ +SECTION "graphics_data", ROM0 +INCLUDE "graphics_data.asm" +INCLUDE "hardware.inc" + +SECTION "std", ROM0 +INCLUDE "../common.asm" + +SECTION "boot", ROM0[$100] + nop + jp Main + +SECTION "main", ROM0[$150] +Main:: + di ; no need for interrupts for now + ld sp, $0FFFE ; setup the stack + + call TurnOffLcd + + ; Copy tiles to VRAM + ld hl, _VRAM + ld bc, TileData + ld de, TileData.end - TileData + call Memcpy + + ; Set screen 0 to use tile 0 + ld hl, _SCRN0 + ld bc, $400 + ld a, 0 + call Memset + + ; set vram bank to 1 in order to set the BG attributes + ld a, 1 + ld [rVBK], a + + ld hl, _SCRN0 + ld bc, $400 + ld a, 0 ; bg priority off, bg pallete 0 + call Memset ; loading the first screen attributes with 0 + + ; load the oam attributes to the oam ram + ld hl, _OAMRAM + ld bc, OAMData + ld de, OAMData.end - OAMData + call Memcpy + + ; set up palletes + ld d, 2 ; color index + ld e, 1 ; BG + ld bc, WHITE + call LoadPallete ; BG pallete - set color 1 of pallete 0 + + ld d, 2 ; color index + ld e, 0 ; OAM + ld bc, GREEN + call LoadPallete ; OAM pallete - set color 1 of pallete 0 + + ld d, 4 ; color index + ld e, 0 ; OAM + ld bc, RED + call LoadPallete ; OAM pallete - set color 2 of pallete 0 + + ld a, LCDCF_ON|LCDCF_BG8000|LCDCF_OBJON|LCDCF_BGON + ld [rLCDC], a ; turn lcd on, with the correct flags + +.loop + jp .loop ; wait forever \ No newline at end of file From 1d3494e25a58a6dee7b5cfe5e01436efa5d9edda Mon Sep 17 00:00:00 2001 From: alloncm Date: Tue, 7 Feb 2023 15:28:36 +0200 Subject: [PATCH 2/5] Fix make file --- Makefile | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 9bedc2b..d8dedb7 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,3 @@ -RGBASM = rgbasm -RGBLINK = rgblink -RGBFIX = rgbfix - RM_F = ifeq ($(OS), Windows_NT) RM_F = Del @@ -9,21 +5,23 @@ else RM_F = rm -f endif -ASMFLAGS = -L # L - disable optimiziations -FIXFLAGS = -C -v -m 0 -p 0 # v - equlivant to -f lhg that fixes some header values \ - m - cartrigde type, p - pad value \ - C - for CGB only -HARDWAREINC_PATH = hardware.inc/ +# L - disable optimiziations +ASMFLAGS = -L + +# v - equlivant to -f lhg that fixes some header values +# m - cartrigde type, p - pad value +# C - for CGB only +FIXFLAGS = -C -v -m 0 -p 0 define create_target = - $(RGBASM) -i $(2) -i $(HARDWAREINC_PATH) -o $(1).o $(2)/main.asm - $(RGBLINK) -o $(1).gbc $(1).o - $(RGBFIX) $(FIXFLAGS) $(1).gbc + rgbasm $(ASMFLAGS) -i $(2) -i hardware.inc/ -o $(1).o $(2)/main.asm + rgblink -o $(1).gbc $(1).o + rgbfix $(FIXFLAGS) $(1).gbc endef all: - $(call create_target,bg_oam_priority,src/color_bg_oam_priority) - $(call create_target,oam_internal_priority,src/oam_internal_priority) + $(call create_target, bg_oam_priority, src/color_bg_oam_priority) + $(call create_target, oam_internal_priority, src/oam_internal_priority) .PHONY: clean clean: From abb309d63dc4f601900cf6c25fdeacb58fdea171 Mon Sep 17 00:00:00 2001 From: alloncm Date: Tue, 7 Feb 2023 15:32:08 +0200 Subject: [PATCH 3/5] Remove merge dirt --- src/color_bg_oam_priority/main.asm | 1 - 1 file changed, 1 deletion(-) diff --git a/src/color_bg_oam_priority/main.asm b/src/color_bg_oam_priority/main.asm index 364012c..2c40bce 100644 --- a/src/color_bg_oam_priority/main.asm +++ b/src/color_bg_oam_priority/main.asm @@ -138,7 +138,6 @@ Main:: jp .loop ; wait for interrupts ;---------------------------------------------------- - ld a, [rLCDC] ; All the stat interrupt handlers - one for each ; OAM object (pipeline) ;---------------------------------------------------- From 905dbb516becab070dd1cc0995cab2df4e545c20 Mon Sep 17 00:00:00 2001 From: alloncm Date: Tue, 7 Feb 2023 15:35:47 +0200 Subject: [PATCH 4/5] Fix hardware.inc include place --- src/oam_internal_priority/main.asm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/oam_internal_priority/main.asm b/src/oam_internal_priority/main.asm index f943182..2341ce7 100644 --- a/src/oam_internal_priority/main.asm +++ b/src/oam_internal_priority/main.asm @@ -1,6 +1,7 @@ +INCLUDE "hardware.inc" + SECTION "graphics_data", ROM0 INCLUDE "graphics_data.asm" -INCLUDE "hardware.inc" SECTION "std", ROM0 INCLUDE "../common.asm" From 3237949e687d768368a6d9b71e132de23c1ce342 Mon Sep 17 00:00:00 2001 From: alloncm Date: Tue, 7 Feb 2023 21:04:25 +0200 Subject: [PATCH 5/5] Update readme and refactor LoadPallete --- README.md | 48 ++++++++---------- ...oam_internal_priority_expected_sameboy.png | Bin 0 -> 1355 bytes src/common.asm | 27 +++++----- src/oam_internal_priority/graphics_data.asm | 3 ++ src/oam_internal_priority/main.asm | 4 +- 5 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 images/oam_internal_priority_expected_sameboy.png diff --git a/README.md b/README.md index 8431438..c75f1e2 100644 --- a/README.md +++ b/README.md @@ -6,41 +6,37 @@ Well during the development of MagenBoy (My gameboy emulator) I found plenty of Unfortuntly, now when adding support for the Gameboy Color (CGB) I had a hard time finding all the information online so I decided to try and test it myself ## ColorBgOamPriority -The gameboy color has 3 different places where the priority between the Background layer and the OAM a layer is declared: -1. OAM Attributes bit 7 - Those attributes exists in the gameboy too - if set pixels 1-3 of the BG layer will get priority over OAM pixels (OAM will still be prioritize over BG pixel 0) - [source](https://gbdev.io/pandocs/OAM.html#byte-3---attributesflags) +The gameboy color has 3 different places where the priority between the Background layer and the OAM a layer can be declared. -2. LCDC bit 0 - in Gameboy Color this bit changes its purpose and defines the priority of the background - according to the pandocs this supposed to be master priority mode but this is not always the case - [source](https://gbdev.io/pandocs/LCDC.html#lcdc0---bg-and-window-enablepriority) +This test verifies the reltions between those flags and the behavior when they colide. -3. BG Map Attribute bit 7 - in color we got Tile attributes for the BG too, according to The pandocs setting this bit should ignore the OAM priority bit, which not always the case - [source](https://gbdev.io/pandocs/Tile_Maps.html#bg-map-attributes-cgb-mode-only) +Checkout the [PanDocs](https://gbdev.io/pandocs/Tile_Maps.html#bg-to-obj-priority-in-cgb-mode) for background on the CGB behavior. -After trying to implement this behavior I noticed that this is not the whole picture and there are a few edge cases not covered. +### Test result -### Expected behavior -Colors: -* Green - visible OAM objects -* Blue - BG tiles that mask OAM objects -* Red - hidden OAM objects (you shouldn't see them) +You should see 5 green squares and 3 half grren and half blue squares with no red lines -| OAM priority bit | Background priority bit | Background master enable bit | Result | Description | -| ---------------- | ------------------------ | ---------------------------- | ------ | ----------- | -| [X] | [X] | [X] |![image](images/expceted_green_blue.png)| depends on the color number of the BG pixel - BG color 0 the OAM have priority otherwise the BG have priority | -| [X] | [X] | [_] |![image](images/expceted_green.png)| OAM have priority | -| [_] | [_] | [X] |![image](images/expceted_green_blue.png)| depends on the color number of the BG pixel - BG color 0 the OAM have priority otherwise the BG have priority | -| [_] | [X] | [X] |![image](images/expceted_green_blue.png)| depends on the color number of the BG pixel - BG color 0 the OAM have priority otherwise the BG have priority | -| [X] | [_] | [X] |![image](images/expceted_green.png)| OAM have priority | -| [X] | [_] | [_] |![image](images/expceted_green.png)| OAM have priority | -| [_] | [X] | [_] |![image](images/expceted_green.png)| OAM have priority | -| [_] | [_] | [_] |![image](images/expceted_green.png)| OAM have priority | +#### Expected results: -*Notice that when BG color is 0 the oam will always have priority* +Screnshoot from Orignal CGB hardware -### Test result -You should see 5 green squares and 3 half grren and half blue squares with no red lines - -#### Example: ![image](images/hardware_screenshot.jpg) #### Original hardware -Special thanks to [ISSOtm](https://github.com/ISSOtm) for running this test rom on original hardware, verifying it actually works and screenshoting the result. \ No newline at end of file +Special thanks to [ISSOtm](https://github.com/ISSOtm) for running this test rom on original hardware, verifying it actually works and screenshoting the result. + +## ColorOamInternalPriority + +The gameboy color changes the way the PPU manages its internal OAM objects priority. + +For more info checks the [PanDocs](https://gbdev.io/pandocs/OAM.html#drawing-priority). + +### Test result + +You should see 2 pairs of rectangles connected or touching each other. + +#### Expected result + +![image](images/oam_internal_priority_expected_sameboy.png) \ No newline at end of file diff --git a/images/oam_internal_priority_expected_sameboy.png b/images/oam_internal_priority_expected_sameboy.png new file mode 100644 index 0000000000000000000000000000000000000000..3f0ea4e01388275b83263ca8ed357fd08ffb6ef3 GIT binary patch literal 1355 zcmeAS@N?(olHy`uVBq!ia0y~yV6+2bbq+S5h`~esWFW;@9OUlAu z_aSpp%X=kn{%?vPZ`3BfJXqJle?o8{zmDyV=^$@?KX$44FDJ;G-AmbJfxhf1j>>Of z=>{sYQ*i&$AOkXiik#mUcl2M6HG8)IJoCRckORsmE@l5M0J3Y}hA#>Bpm4s=K27e8 zH^}blgvIqjSP=}WO(nVv|+veQF&nb!QkoY p=d#Wzp~*wYUcvKEgUUzdNk{kxGl%2WHv2;sc3m=Zr!