gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 7a413072f03f333a796a51056533c553f9b8c1b0 parent c4db8a61a4041f84c004505a35ac674aa4f7da81 Author: Toxa <untoxa@mail.ru> Date: Sun, 23 Jul 2023 22:07:16 +0300 Merge branch 'develop' of https://github.com/gbdk-2020/gbdk-2020 into develop Diffstat:
19 files changed, 535 insertions(+), 125 deletions(-)
diff --git a/gbdk-lib/examples/cross-platform/banks/Makefile b/gbdk-lib/examples/cross-platform/banks/Makefile @@ -17,7 +17,7 @@ LCCFLAGS_duck = -Wl-yt0x1B # Usually the same as required for .gb LCCFLAGS_gbc = -Wl-yt0x1B -Wm-yc # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) LCCFLAGS_sms = LCCFLAGS_gg = -LCCFLAGS_nes = -Wl-yt0x1B +LCCFLAGS_nes = LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags diff --git a/gbdk-lib/examples/cross-platform/banks_autobank/Makefile b/gbdk-lib/examples/cross-platform/banks_autobank/Makefile @@ -15,7 +15,7 @@ LCCFLAGS_duck = -Wl-yt0x1B # Usually the same as required for .gb LCCFLAGS_gbc = -Wl-yt0x1B -Wm-yc # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) LCCFLAGS_sms = LCCFLAGS_gg = -LCCFLAGS_nes = -Wl-yt0x1B +LCCFLAGS_nes = LCCFLAGS_msxdos = LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags diff --git a/gbdk-lib/examples/cross-platform/banks_farptr/Makefile b/gbdk-lib/examples/cross-platform/banks_farptr/Makefile @@ -15,7 +15,7 @@ LCCFLAGS_duck = -Wl-yt0x1B # Usually the same as required for .gb LCCFLAGS_gbc = -Wl-yt0x1B -Wm-yc # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) LCCFLAGS_sms = LCCFLAGS_gg = -LCCFLAGS_nes = -Wl-yt0x1B +LCCFLAGS_nes = LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags diff --git a/gbdk-lib/examples/cross-platform/banks_nonintrinsic/Makefile b/gbdk-lib/examples/cross-platform/banks_nonintrinsic/Makefile @@ -15,7 +15,7 @@ LCCFLAGS_duck = -Wl-yt0x1B # Usually the same as required for .gb LCCFLAGS_gbc = -Wl-yt0x1B -Wm-yc # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) LCCFLAGS_sms = LCCFLAGS_gg = -LCCFLAGS_nes = -Wl-yt0x1B +LCCFLAGS_nes = LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags diff --git a/gbdk-lib/examples/cross-platform/large_map/Makefile b/gbdk-lib/examples/cross-platform/large_map/Makefile @@ -16,7 +16,7 @@ LCCFLAGS_duck = -Wl-yt0x1B -autobank # Usually the same as required for .gb LCCFLAGS_gbc = -Wl-yt0x1B -Wm-yc -autobank # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) LCCFLAGS_sms = LCCFLAGS_gg = -LCCFLAGS_nes = -Wl-yt0x1B -autobank +LCCFLAGS_nes = -autobank LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags diff --git a/gbdk-lib/examples/cross-platform/libc_memcpy/Makefile b/gbdk-lib/examples/cross-platform/libc_memcpy/Makefile @@ -0,0 +1,79 @@ +# If you move this project you can change the directory +# to match your GBDK root directory (ex: GBDK_HOME = "C:/GBDK/" +GBDK_HOME = ../../../ +LCC = $(GBDK_HOME)bin/lcc + +# Set platforms to build here, spaced separated. (These are in the separate Makefile.targets) +# They can also be built/cleaned individually: "make gg" and "make gg-clean" +# Possible are: gb gbc pocket megaduck sms gg +TARGETS=gb pocket megaduck sms gg nes + +# Configure platform specific LCC flags here: +LCCFLAGS_gb = -Wl-yt0x1B -autobank # Set an MBC for banking (1B-ROM+MBC5+RAM+BATT) +LCCFLAGS_pocket = -Wl-yt0x1B -autobank # Usually the same as required for .gb +LCCFLAGS_duck = -Wl-yt0x1B -autobank # Usually the same as required for .gb +LCCFLAGS_gbc = -Wl-yt0x1B -Wm-yc -autobank # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) +LCCFLAGS_sms = -autobank +LCCFLAGS_gg = -autobank +LCCFLAGS_nes = + +LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags + +LCCFLAGS += -Wl-j -Wm-yoA -Wm-ya4 -Wb-ext=.rel -Wb-v # MBC + Autobanking related flags +# LCCFLAGS += -debug # Uncomment to enable debug output +# LCCFLAGS += -v # Uncomment for lcc verbose output + +# You can set the name of the ROM file here +PROJECTNAME = libc_memcpy + +# EXT?=gb # Only sets extension to default (game boy .gb) if not populated +SRCDIR = src +OBJDIR = obj/$(EXT) +RESDIR = res +BINDIR = build/$(EXT) +MKDIRS = $(OBJDIR) $(BINDIR) # See bottom of Makefile for directory auto-creation + +BINS = $(OBJDIR)/$(PROJECTNAME).$(EXT) +CSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.c))) $(foreach dir,$(RESDIR),$(notdir $(wildcard $(dir)/*.c))) +ASMSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.s))) +OBJS = $(CSOURCES:%.c=$(OBJDIR)/%.o) $(ASMSOURCES:%.s=$(OBJDIR)/%.o) + +# Builds all targets sequentially +all: $(TARGETS) + +# Compile .c files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .c files in "res/" to .o object files +$(OBJDIR)/%.o: $(RESDIR)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .s assembly files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.s + $(LCC) $(CFLAGS) -c -o $@ $< + +# If needed, compile .c files in "src/" to .s assembly files +# (not required if .c is compiled directly to .o) +$(OBJDIR)/%.s: $(SRCDIR)/%.c + $(LCC) $(CFLAGS) -S -o $@ $< + +# Link the compiled object files into a .gb ROM file +$(BINS): $(OBJS) + $(LCC) $(LCCFLAGS) $(CFLAGS) -o $(BINDIR)/$(PROJECTNAME).$(EXT) $(OBJS) + +clean: + @echo Cleaning + @for target in $(TARGETS); do \ + $(MAKE) $$target-clean; \ + done + +# Include available build targets +include Makefile.targets + + +# create necessary directories after Makefile is parsed but before build +# info prevents the command from being pasted into the makefile +ifneq ($(strip $(EXT)),) # Only make the directories if EXT has been set by a target +$(info $(shell mkdir -p $(MKDIRS))) +endif diff --git a/gbdk-lib/examples/cross-platform/libc_memcpy/Makefile.targets b/gbdk-lib/examples/cross-platform/libc_memcpy/Makefile.targets @@ -0,0 +1,55 @@ + +# Platform specific flags for compiling (only populate if they're both present) +ifneq ($(strip $(PORT)),) +ifneq ($(strip $(PLAT)),) +CFLAGS += -m$(PORT):$(PLAT) +endif +endif + +# Called by the individual targets below to build a ROM +build-target: $(BINS) + +clean-target: + rm -rf $(OBJDIR) + rm -rf $(BINDIR) + +gb-clean: + ${MAKE} clean-target EXT=gb +gb: + ${MAKE} build-target PORT=sm83 PLAT=gb EXT=gb + + +gbc-clean: + ${MAKE} clean-target EXT=gbc +gbc: + ${MAKE} build-target PORT=sm83 PLAT=gb EXT=gbc + + +pocket-clean: + ${MAKE} clean-target EXT=pocket +pocket: + ${MAKE} build-target PORT=sm83 PLAT=ap EXT=pocket + + +megaduck-clean: + ${MAKE} clean-target EXT=duck +megaduck: + ${MAKE} build-target PORT=sm83 PLAT=duck EXT=duck + + +sms-clean: + ${MAKE} clean-target EXT=sms +sms: + ${MAKE} build-target PORT=z80 PLAT=sms EXT=sms + + +gg-clean: + ${MAKE} clean-target EXT=gg +gg: + ${MAKE} build-target PORT=z80 PLAT=gg EXT=gg + + +nes-clean: + ${MAKE} clean-target EXT=nes +nes: + ${MAKE} build-target PORT=mos6502 PLAT=nes EXT=nes diff --git a/gbdk-lib/examples/cross-platform/libc_memcpy/src/libc_memcpy.c b/gbdk-lib/examples/cross-platform/libc_memcpy/src/libc_memcpy.c @@ -0,0 +1,57 @@ +// +// libc_memcpy.c +// Simple test of memcpy/memset/memmove functions in C library string.h +// + +#include <stdio.h> +#include <string.h> + +#include <gbdk/platform.h> +#include <gbdk/font.h> +#include <gbdk/console.h> + +uint8_t memcpy_dst[300]; +const uint8_t memcpy_src[300]; + +int benchmark_memcpy(int num, int size) +{ + int i; + uint16_t start_time = sys_time; + for(i = 0; i < num; i++) + memcpy(memcpy_dst, memcpy_src, size); + return (int)(sys_time - start_time); +} + +void main(void) +{ + font_t ibm_font; + + // init the font system to use IBM font + font_init(); + ibm_font = font_load(font_ibm); + font_set(ibm_font); + + // Test memcpy + { + char dst[4] = "dst"; + const char* src = "src"; + printf("memcpy(dst,src,2)\n-> %s\n", memcpy(dst, src, 2)); + } + // Test memmove + { + char dst[4] = "dst"; + const char* src = "src"; + printf("memmove(dst,src,2)\n-> %s\n", memmove(dst, src, 2)); + } + // Test memset + { + char dst[4] = "dst"; + printf("memset(dst,x,2)\n-> %s\n", memset(dst, 'x', 2)); + } + // Benchmark memcpy + printf("\nBenchmark memcpy:\n"); + { + printf("800*memcpy(d,s,150)\n-> %d frames\n", benchmark_memcpy(800, 150)); + printf("400*memcpy(d,s,300)\n-> %d frames\n", benchmark_memcpy(400, 300)); + } +} diff --git a/gbdk-lib/examples/cross-platform/libc_string/Makefile b/gbdk-lib/examples/cross-platform/libc_string/Makefile @@ -0,0 +1,79 @@ +# If you move this project you can change the directory +# to match your GBDK root directory (ex: GBDK_HOME = "C:/GBDK/" +GBDK_HOME = ../../../ +LCC = $(GBDK_HOME)bin/lcc + +# Set platforms to build here, spaced separated. (These are in the separate Makefile.targets) +# They can also be built/cleaned individually: "make gg" and "make gg-clean" +# Possible are: gb gbc pocket megaduck sms gg +TARGETS=gb pocket megaduck sms gg nes + +# Configure platform specific LCC flags here: +LCCFLAGS_gb = -Wl-yt0x1B -autobank # Set an MBC for banking (1B-ROM+MBC5+RAM+BATT) +LCCFLAGS_pocket = -Wl-yt0x1B -autobank # Usually the same as required for .gb +LCCFLAGS_duck = -Wl-yt0x1B -autobank # Usually the same as required for .gb +LCCFLAGS_gbc = -Wl-yt0x1B -Wm-yc -autobank # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) +LCCFLAGS_sms = -autobank +LCCFLAGS_gg = -autobank +LCCFLAGS_nes = + +LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags + +LCCFLAGS += -Wl-j -Wm-yoA -Wm-ya4 -Wb-ext=.rel -Wb-v # MBC + Autobanking related flags +# LCCFLAGS += -debug # Uncomment to enable debug output +# LCCFLAGS += -v # Uncomment for lcc verbose output + +# You can set the name of the ROM file here +PROJECTNAME = libc_string + +# EXT?=gb # Only sets extension to default (game boy .gb) if not populated +SRCDIR = src +OBJDIR = obj/$(EXT) +RESDIR = res +BINDIR = build/$(EXT) +MKDIRS = $(OBJDIR) $(BINDIR) # See bottom of Makefile for directory auto-creation + +BINS = $(OBJDIR)/$(PROJECTNAME).$(EXT) +CSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.c))) $(foreach dir,$(RESDIR),$(notdir $(wildcard $(dir)/*.c))) +ASMSOURCES = $(foreach dir,$(SRCDIR),$(notdir $(wildcard $(dir)/*.s))) +OBJS = $(CSOURCES:%.c=$(OBJDIR)/%.o) $(ASMSOURCES:%.s=$(OBJDIR)/%.o) + +# Builds all targets sequentially +all: $(TARGETS) + +# Compile .c files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .c files in "res/" to .o object files +$(OBJDIR)/%.o: $(RESDIR)/%.c + $(LCC) $(CFLAGS) -c -o $@ $< + +# Compile .s assembly files in "src/" to .o object files +$(OBJDIR)/%.o: $(SRCDIR)/%.s + $(LCC) $(CFLAGS) -c -o $@ $< + +# If needed, compile .c files in "src/" to .s assembly files +# (not required if .c is compiled directly to .o) +$(OBJDIR)/%.s: $(SRCDIR)/%.c + $(LCC) $(CFLAGS) -S -o $@ $< + +# Link the compiled object files into a .gb ROM file +$(BINS): $(OBJS) + $(LCC) $(LCCFLAGS) $(CFLAGS) -o $(BINDIR)/$(PROJECTNAME).$(EXT) $(OBJS) + +clean: + @echo Cleaning + @for target in $(TARGETS); do \ + $(MAKE) $$target-clean; \ + done + +# Include available build targets +include Makefile.targets + + +# create necessary directories after Makefile is parsed but before build +# info prevents the command from being pasted into the makefile +ifneq ($(strip $(EXT)),) # Only make the directories if EXT has been set by a target +$(info $(shell mkdir -p $(MKDIRS))) +endif diff --git a/gbdk-lib/examples/cross-platform/libc_string/Makefile.targets b/gbdk-lib/examples/cross-platform/libc_string/Makefile.targets @@ -0,0 +1,55 @@ + +# Platform specific flags for compiling (only populate if they're both present) +ifneq ($(strip $(PORT)),) +ifneq ($(strip $(PLAT)),) +CFLAGS += -m$(PORT):$(PLAT) +endif +endif + +# Called by the individual targets below to build a ROM +build-target: $(BINS) + +clean-target: + rm -rf $(OBJDIR) + rm -rf $(BINDIR) + +gb-clean: + ${MAKE} clean-target EXT=gb +gb: + ${MAKE} build-target PORT=sm83 PLAT=gb EXT=gb + + +gbc-clean: + ${MAKE} clean-target EXT=gbc +gbc: + ${MAKE} build-target PORT=sm83 PLAT=gb EXT=gbc + + +pocket-clean: + ${MAKE} clean-target EXT=pocket +pocket: + ${MAKE} build-target PORT=sm83 PLAT=ap EXT=pocket + + +megaduck-clean: + ${MAKE} clean-target EXT=duck +megaduck: + ${MAKE} build-target PORT=sm83 PLAT=duck EXT=duck + + +sms-clean: + ${MAKE} clean-target EXT=sms +sms: + ${MAKE} build-target PORT=z80 PLAT=sms EXT=sms + + +gg-clean: + ${MAKE} clean-target EXT=gg +gg: + ${MAKE} build-target PORT=z80 PLAT=gg EXT=gg + + +nes-clean: + ${MAKE} clean-target EXT=nes +nes: + ${MAKE} build-target PORT=mos6502 PLAT=nes EXT=nes diff --git a/gbdk-lib/examples/cross-platform/libc_string/src/libc_string.c b/gbdk-lib/examples/cross-platform/libc_string/src/libc_string.c @@ -0,0 +1,50 @@ +// +// libc_string.c +// Simple test of string functions in C library string.h +// +#include <stdio.h> +#include <string.h> + +#include <gbdk/platform.h> +#include <gbdk/font.h> +#include <gbdk/console.h> + +void main(void) +{ + font_t ibm_font, italic_font, min_font; + int i; + + // init the font system to use IBM font + font_init(); + ibm_font = font_load(font_ibm); + font_set(ibm_font); + + // Test strlen + printf("strlen(gbdk) -> %d\n", strlen("gbdk")); + // Test strcmp / strncmp + printf("strcmp(gbdk,gbdk)\n-> %d\n", strcmp("gbdk", "gbdk")); + printf("strcmp(gbdk,ggdk)\n-> %d\n", strcmp("gbdk", "ggdk")); + printf("strcmp(ggdk,gbdk)\n-> %d\n", strcmp("ggdk", "gbdk")); + printf("strncmp(gbdk,gbc,2)\n-> %d\n", strncmp("gbdk", "gbc", 2)); + // Test strcpy + { + char dst[4] = "dst"; + const char* src = "src"; + strcpy(dst, src); + printf("strcpy(dst,src)\n-> %s\n", dst); + } + // Test strncpy + { + char dst[4] = "dst"; + const char* src = "src"; + strncpy(dst, src, 2); + printf("strncpy(dst,src,2)\n-> %s\n", dst); + } + // Test strcat/strncat + { + char dst[9] = "gbdk"; + char dst2[9] = "gbdk"; + printf("strcat(gbdk,2020)\n-> %s\n", strcat(dst, "2020")); + printf("strncat(gbdk,lib,2)\n-> %s\n", strncat(dst2, "lib",2)); + } +} diff --git a/gbdk-lib/examples/cross-platform/scroller/Makefile b/gbdk-lib/examples/cross-platform/scroller/Makefile @@ -15,7 +15,7 @@ LCCFLAGS_duck = -Wl-yt0x1B # Usually the same as required for .gb LCCFLAGS_gbc = -Wl-yt0x1B -Wm-yc # Same as .gb with: -Wm-yc (gb & gbc) or Wm-yC (gbc exclusive) LCCFLAGS_sms = LCCFLAGS_gg = -LCCFLAGS_nes = -Wl-yt0x1B +LCCFLAGS_nes = LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags diff --git a/gbdk-lib/include/asm/mos6502/string.h b/gbdk-lib/include/asm/mos6502/string.h @@ -39,7 +39,8 @@ int strcmp(const char *s1, const char *s2); @param src Buffer to copy from @param len Number of Bytes to copy */ -void *memcpy(void *dest, const void *src, size_t len); +void *__memcpy(void *dest, const void *src, size_t len); +#define memcpy(dst, src, n) __memcpy(dst, src, n) /** Copies n bytes from memory area src to memory area dest, areas may overlap */ diff --git a/gbdk-lib/libc/targets/mos6502/nes/crt0.s b/gbdk-lib/libc/targets/mos6502/nes/crt0.s @@ -96,6 +96,116 @@ i = 0 i = i + 1 .endm +.define ProcessDrawList_tempX "__crt0_NMITEMP+2" +.define ProcessDrawList_addr "__crt0_NMITEMP+0" + +.bndry 0x100 +ProcessDrawList_UnrolledCopyLoop: +.rept 32 +pla ; +4 +sta PPUDATA ; +4 +.endm +ProcessDrawList_DoOneTransfer: + pla ; +4 + beq ProcessDrawList_EndOfList ; +2/3 + ; branchaddr = 128-4*num_bytes = NOT(4*num_bytes)+1+128 = NOT(4*num_bytes)+129 + asl ; +2 + asl ; +2 + eor #0xFF ; +2 + adc #129 ; +2 + sta *ProcessDrawList_addr ; +3 + pla ; +4 + sta PPUCTRL ; +4 + pla ; +4 + sta PPUADDR ; +4 + pla ; +4 + sta PPUADDR ; +4 + nop ; +2 + jmp [ProcessDrawList_addr] ; +5 + ; Total = 4 + 2 + 2 + 4 + 3 + 6*4 + 2 + 2 + 5 = 48 for each transfer (...+ 8*NumBytesCopied) + ; 4 + 3 + 14 = 7 + 14 = 21 fixed-cost exit + +; .bndry 0x100 (skip alignment as previous alignment means page-cross won't happen) +__crt0_doSpriteDMA: + bit *__crt0_spritePageValid + bpl __crt0_doSpriteDMA_spritePageInvalid + lda #0 ; +2 + sta OAMADDR ; +4 + lda #>_shadow_OAM ; +2 + sta OAMDMA ; +512/513 + rts +__crt0_doSpriteDMA_spritePageInvalid: + ; Delay 520 cycles to keep timing consistent + ldx #104 +__crt0_doSpriteDMA_loop: + dex + bne __crt0_doSpriteDMA_loop + rts + +ProcessDrawList_EndOfList: + ldx *ProcessDrawList_tempX ; +3 + txs ; +2 + lda #0 ; +2 + sta *__vram_transfer_buffer_pos_w ; +3 + sta *__vram_transfer_buffer_valid ; +3 + rts ; +6 + ; = 3 + 2 + 2 + 3 + 3 + 6 = 19 + +; +; Number of cycles spent = 19 + 21 + 48*NumTransfers + 8*NumBytesTransferred +; = 56 + 48*NumTransfers + 8*NumBytesTransferred +; = 8 * (7 + 6*NumTransfers + NumBytesTransferred) +; = 8 * (6*NumTransfers + NumBytesTransferred + 7) +; +ProcessDrawList: + lda #>ProcessDrawList_UnrolledCopyLoop ; +2 + sta *ProcessDrawList_addr+1 ; +3 + tsx ; +2 + stx *ProcessDrawList_tempX ; +3 + ldx #0xFF ; +2 + txs ; +2 + jmp ProcessDrawList_DoOneTransfer ; +3 + ; Total = 2 + 3 + 2 + 3 + 2 + 2 + 3 = 17 fixed-cost entry + +; +; Delays until specified (non-zero) scanline is reached +; +; First scanline's delay needs adjusting for cycle cost of subroutine execution: +; beq-not-taken -1 +; jsr +6 +; lda #0 +2 +; sta *.acc +3 +; ldy #N +2 +; nop +2 +; nop +2 +; bne-taken +3 +; rts +6 +; -> 25 cycles less +; -> N = 19-25/5 = 19-5 +; +.define .acc "___SDCC_m6502_ret4" +.delay_to_lcd_scanline:: + lda #0 + sta *.acc + ldy #(19-5) + nop + nop + bne 2$ +1$: + ldy #19 +2$: + dey + bne 2$ ; -> 2 + 18*5 + 4 = 91 cycles + lda *.acc + clc + adc #85 + bcc 3$ +3$: + sta *.acc ; -> 12.666 cycles + dex + bne 1$ ; -> 5 cycles + rts + __crt0_NMI: ; Prevent NMI re-entry bit *__crt0_NMI_insideNMI @@ -178,23 +288,6 @@ __crt0_NMI_doUpdateVRAM_blanked: nop rts -.bndry 0x100 -__crt0_doSpriteDMA: - bit *__crt0_spritePageValid - bpl __crt0_doSpriteDMA_spritePageInvalid - lda #0 ; +2 - sta OAMADDR ; +4 - lda #>_shadow_OAM ; +2 - sta OAMDMA ; +512/513 - rts -__crt0_doSpriteDMA_spritePageInvalid: - ; Delay 520 cycles to keep timing consistent - ldx #104 -__crt0_doSpriteDMA_loop: - dex - bne __crt0_doSpriteDMA_loop - rts - DoUpdateVRAM: WRITE_PALETTE_SHADOW bit *__vram_transfer_buffer_valid @@ -221,105 +314,6 @@ DoUpdateVRAM_valid_loop: sta *__vram_transfer_buffer_num_cycles_x8 rts -; -; Number of cycles spent = 19 + 21 + 48*NumTransfers + 8*NumBytesTransferred -; = 56 + 48*NumTransfers + 8*NumBytesTransferred -; = 8 * (7 + 6*NumTransfers + NumBytesTransferred) -; = 8 * (6*NumTransfers + NumBytesTransferred + 7) -; -ProcessDrawList: - .define ProcessDrawList_tempX "__crt0_NMITEMP+2" - .define ProcessDrawList_addr "__crt0_NMITEMP+0" - lda #>ProcessDrawList_UnrolledCopyLoop ; +2 - sta *ProcessDrawList_addr+1 ; +3 - tsx ; +2 - stx *ProcessDrawList_tempX ; +3 - ldx #0xFF ; +2 - txs ; +2 - jmp ProcessDrawList_DoOneTransfer ; +3 - ; Total = 2 + 3 + 2 + 3 + 2 + 2 + 3 = 17 fixed-cost entry - -.bndry 0x100 -ProcessDrawList_UnrolledCopyLoop: -.rept 64 -pla ; +4 -sta PPUDATA ; +4 -.endm -ProcessDrawList_DoOneTransfer: - pla ; +4 - beq ProcessDrawList_EndOfList ; +2/3 - tay ; +2 - ; branchaddr = 256-4*num_bytes = NOT(4*num_bytes)+1+256 = NOT(4*num_bytes)+1 - lda ProcessDrawList_NumBytesToAddress,y ; +4 - sta *ProcessDrawList_addr ; +3 - pla ; +4 - sta PPUCTRL ; +4 - pla ; +4 - sta PPUADDR ; +4 - pla ; +4 - sta PPUADDR ; +4 - nop ; +2 - nop ; +2 - jmp [ProcessDrawList_addr] ; +5 - ; Total = 4 + 2 + 2 + 4 + 3 + 6*4 + 2 + 2 + 5 = 48 for each transfer (...+ 8*NumBytesCopied) - ; 4 + 3 + 14 = 7 + 14 = 21 fixed-cost exit - -ProcessDrawList_EndOfList: - ldx *ProcessDrawList_tempX ; +3 - txs ; +2 - lda #0 ; +2 - sta *__vram_transfer_buffer_pos_w ; +3 - sta *__vram_transfer_buffer_valid ; +3 - rts ; +6 - ; = 3 + 2 + 2 + 3 + 3 + 6 = 19 - -; -; Delays until specified (non-zero) scanline is reached -; -; First scanline's delay needs adjusting for cycle cost of subroutine execution: -; beq-not-taken -1 -; jsr +6 -; lda #0 +2 -; sta *.acc +3 -; ldy #N +2 -; nop +2 -; nop +2 -; bne-taken +3 -; rts +6 -; -> 25 cycles less -; -> N = 19-25/5 = 19-5 -; -.define .acc "___SDCC_m6502_ret4" -.delay_to_lcd_scanline:: - lda #0 - sta *.acc - ldy #(19-5) - nop - nop - bne 2$ -1$: - ldy #19 -2$: - dey - bne 2$ ; -> 2 + 18*5 + 4 = 91 cycles - lda *.acc - clc - adc #85 - bcc 3$ -3$: - sta *.acc ; -> 12.666 cycles - dex - bne 1$ ; -> 5 cycles - rts - -.bndry 0x100 -ProcessDrawList_NumBytesToAddress: -i = 0 -.rept 65 -.db <(256-4*i) -i = i + 1 -.endm - __crt0_IRQ: jmp __crt0_IRQ diff --git a/gbdk-support/bankpack/bankpack.c b/gbdk-support/bankpack/bankpack.c @@ -95,6 +95,8 @@ static int handle_args(int argc, char * argv[]) { files_set_out_path(argv[i] + 6); } else if (strstr(argv[i], "-mbc=") == argv[i]) { option_set_mbc(atoi(argv[i] + 5)); + } else if (strstr(argv[i], "-mapper=") == argv[i]) { + option_set_nes_mapper(atoi(argv[i] + 8)); } else if (strstr(argv[i], "-yt") == argv[i]) { option_mbc_by_rom_byte_149(strtol(argv[i] + 3, NULL, 0)); } else if (strstr(argv[i], "-v") == argv[i]) { diff --git a/gbdk-support/bankpack/common.h b/gbdk-support/bankpack/common.h @@ -15,6 +15,16 @@ enum { MBC_TYPE_DEFAULT = MBC_TYPE_NONE }; +enum { + NES_MAPPER_TYPE_NONE = 0, + NES_MAPPER_TYPE_UXROM = 2, + NES_MAPPER_TYPE_MAPPER30 = 30, + + NES_MAPPER_TYPE_MIN = NES_MAPPER_TYPE_NONE, + NES_MAPPER_TYPE_MAX = NES_MAPPER_TYPE_MAPPER30, + NES_MAPPER_TYPE_DEFAULT = NES_MAPPER_TYPE_MAPPER30 +}; + #define MAX_FILE_STR 2048 #define BANK_NUM_UNASSIGNED 0xFFFFU @@ -33,6 +43,9 @@ enum { #define BANK_NUM_ROM_MAX_MBC3 127 #define BANK_NUM_ROM_MAX_MBC5 255 // 511 // TODO: support full MBC5 address range (currently 8 bit only) +#define BANK_NUM_ROM_MAX_UXROM 127 // Oversize UNROM supports up to 4MB, but iNES 1.0 only supports up to 2MB. Historical UxROM boards only supported 256kB at most +#define BANK_NUM_ROM_MAX_MAPPER30 31 // Mapper30 only supports up to 512kB due to other register bits being used for CHR-RAM / 1-screen mirroring control. + #define STRINGIFY(x) #x #define TOSTR(x) STRINGIFY(x) diff --git a/gbdk-support/bankpack/options.c b/gbdk-support/bankpack/options.c @@ -245,7 +245,30 @@ void option_set_mbc(int mbc_type) { bank_limit_rom_max = mbc_bank_limit_rom_max; } - +// Set NES mapper type directly +void option_set_nes_mapper(int mapper_type) { + + uint16_t mapper_bank_limit_rom_max; + + switch (mapper_type) { + case NES_MAPPER_TYPE_NONE: + option_mbc_type = NES_MAPPER_TYPE_NONE; + break; + case NES_MAPPER_TYPE_UXROM: + option_mbc_type = mapper_type; + mapper_bank_limit_rom_max = BANK_NUM_ROM_MAX_UXROM; + break; + case NES_MAPPER_TYPE_MAPPER30: + option_mbc_type = mapper_type; + mapper_bank_limit_rom_max = BANK_NUM_ROM_MAX_MAPPER30; + break; + default: + printf("BankPack: Warning: unrecognized NES mapper option -mapper%d!\n", mapper_type); + break; + } + if (mapper_bank_limit_rom_max < bank_limit_rom_max) + bank_limit_rom_max = mapper_bank_limit_rom_max; +} // From makebin // Byte diff --git a/gbdk-support/bankpack/options.h b/gbdk-support/bankpack/options.h @@ -38,6 +38,8 @@ int option_get_mbc_type(void); void option_set_mbc(int); void option_mbc_by_rom_byte_149(int); +void option_set_nes_mapper(int mapper_type); + uint32_t option_banks_calc_cart_size(void); bool option_banks_set_min(uint16_t bank_num); diff --git a/gbdk-support/lcc/targets.c b/gbdk-support/lcc/targets.c @@ -161,7 +161,7 @@ CLASS classes[] = { .include = "%includedefault%", .com = "%com% %comdefault% -Wa%asdefault% --no-peep $1 %comflag% $2 -o $3", .as = "%as_6500% %asdefault% $1 $3 $2", - .bankpack = "%bankpack% -plat=nes $1 $2", + .bankpack = "%bankpack% -plat=nes -mapper=30 $1 $2", .ld = "%ld_6808% -a nes -n -i -j $1 %libs_include% $3 %crt0dir% $2", .ihxcheck = "%ihxcheck% $2 $1", .mkbin = "%mkbin% -N -yo A -yS $2 $3",
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.