gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit d6d85e64a39ce28a06012e70da2994af498b439e parent 854ec54dca586cdf867e6c7f6a364c0557b0652f Author: Toxa <56631470+untoxa@users.noreply.github.com> Date: Sat, 5 Nov 2022 10:42:22 +0400 Merge pull request #443 from michel-iwaniec/nes_set_bkg_submap NES: Add large map scrolling support Diffstat:
| M | gbdk-lib/examples/cross-platform/large_map/Makefile | 13 | +++++++------ |
| M | gbdk-lib/examples/cross-platform/large_map/Makefile.targets | 6 | ++++++ |
| M | gbdk-lib/libc/targets/mos6502/nes/Makefile | 2 | +- |
| M | gbdk-lib/libc/targets/mos6502/nes/global.s | 4 | ++++ |
| A | gbdk-lib/libc/targets/mos6502/nes/set_tile_submap.s | 249 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 267 insertions(+), 7 deletions(-)
diff --git a/gbdk-lib/examples/cross-platform/large_map/Makefile b/gbdk-lib/examples/cross-platform/large_map/Makefile @@ -6,19 +6,20 @@ 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 gg sms +TARGETS=gb gg sms nes # Configure platform specific LCC flags here: -LCCFLAGS_gb = -Wl-yt0x1B # Set an MBC for banking (1B-ROM+MBC5+RAM+BATT) -LCCFLAGS_pocket = -Wl-yt0x1B # Usually the same as required for .gb -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_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 = LCCFLAGS_gg = +LCCFLAGS_nes = LCCFLAGS += $(LCCFLAGS_$(EXT)) # This adds the current platform specific LCC Flags -LCCFLAGS += -Wl-j -Wm-yoA -Wm-ya4 -autobank -Wb-ext=.rel -Wb-v # MBC + Autobanking related 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 diff --git a/gbdk-lib/examples/cross-platform/large_map/Makefile.targets b/gbdk-lib/examples/cross-platform/large_map/Makefile.targets @@ -48,3 +48,9 @@ gg-clean: 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/libc/targets/mos6502/nes/Makefile b/gbdk-lib/libc/targets/mos6502/nes/Makefile @@ -10,7 +10,7 @@ CSRC = crlf.c ASSRC = f_ibm_full.s f_ibm_sh.s f_italic.s f_min.s f_spect.s \ font.s font_color.s set_data.s set_1bit_data.s color.s mode.s \ metasprites.s metasprites_hide.s metasprites_hide_spr.s \ - set_bk_ts.s fill_rect_bk.s set_bk_attributes.s \ + set_bk_ts.s set_tile_submap.s fill_rect_bk.s set_bk_attributes.s \ nes_palettes.s \ pad.s pad_ex.s \ rle_decompress.s \ diff --git a/gbdk-lib/libc/targets/mos6502/nes/global.s b/gbdk-lib/libc/targets/mos6502/nes/global.s @@ -9,6 +9,10 @@ .START = 0x08 ;; Screen dimensions (in tiles) + .DEVICE_SCREEN_WIDTH = 32 + .DEVICE_SCREEN_HEIGHT = 30 + .DEVICE_SCREEN_BUFFER_WIDTH = 32 + .DEVICE_SCREEN_BUFFER_HEIGHT = 30 .MAXCURSPOSX = 31 .MAXCURSPOSY = 29 diff --git a/gbdk-lib/libc/targets/mos6502/nes/set_tile_submap.s b/gbdk-lib/libc/targets/mos6502/nes/set_tile_submap.s @@ -0,0 +1,249 @@ + .include "global.s" + + .area OSEG (PAG, OVR) + _set_bkg_submap_PARM_3:: .ds 1 + _set_bkg_submap_PARM_4:: .ds 1 + _set_bkg_submap_PARM_5:: .ds 2 + _set_bkg_submap_PARM_6:: .ds 1 + .xpos: .ds 1 + .ypos: .ds 1 + .num_rows: .ds 1 + .src_tiles: .ds 2 + .remainder: .ds 1 + + .area _HOME + +_set_bkg_submap:: + .define .width "_set_bkg_submap_PARM_3" + .define .height "_set_bkg_submap_PARM_4" + .define .tiles "_set_bkg_submap_PARM_5" + .define .map_width "_set_bkg_submap_PARM_6" + sta *.xpos + stx *.ypos + lda .tiles + CLC + ADC *.xpos + sta *.src_tiles + lda .tiles+1 + ADC #0 + sta *.src_tiles+1 + ; += ypos * map_width + lda *.ypos + ldx *.map_width + jsr __muluchar + clc + adc *.src_tiles + sta *.src_tiles + txa + adc *.src_tiles+1 + sta *.src_tiles+1 + ; + lda *.height + sta *.num_rows + ; xpos %= DEVICE_SCREEN_WIDTH + lda *.xpos + and #.DEVICE_SCREEN_WIDTH-1 + sta *.xpos + ; ypos %= DEVICE_SCREEN_HEIGHT + lda #0 + clc + FAST_MOD8 *.ypos #.DEVICE_SCREEN_HEIGHT + sta *.ypos + ; Prefer vertical stripes if height > width + lda *.height + cmp *.width + bcc _set_bkg_submap_horizontalStripes + beq _set_bkg_submap_horizontalStripes + jmp _set_bkg_submap_verticalStripes +_set_bkg_submap_horizontalStripes: + ; Adjust width and calculate remainder if row wraps from right to left + lda *.xpos + clc + adc *.width + sec + sbc #.DEVICE_SCREEN_WIDTH + sta *.remainder + bmi 1$ + lda *.width + sec + sbc *.remainder + sta *.width +1$: + ; Decrement to allow treating 0-case same as negative + dec *.remainder +_set_bkg_submap_horizontalStripes_rowLoop: + ; tmp = PPU_NT0 | (ypos << 5) | xpos + lda #0 + sta *.tmp+1 + lda *.ypos + asl + rol *.tmp+1 + asl + rol *.tmp+1 + asl + rol *.tmp+1 + asl + rol *.tmp+1 + asl + rol *.tmp+1 + ora *.xpos + sta *.tmp + ; + lda *.tmp+1 + ora #>PPU_NT0 + tax + lda *.tmp + jsr .ppu_stripe_begin_horizontal + ldy #0 + ldx *.width +1$: + lda [*.src_tiles],y + iny + jsr .ppu_stripe_write_byte + dex + bne 1$ + jsr .ppu_stripe_end + ; if wrapped around, write remainder + lda *.remainder + bpl _set_bkg_submap_horizontalStripes_remainder +_set_bkg_submap_horizontalStripes_rowLoopEnd: + ; .src_tiles += .map_width + lda *.map_width + clc + adc *.src_tiles + sta *.src_tiles + lda #0 + adc *.src_tiles+1 + sta *.src_tiles+1 + ;inc *.ypos + ; ypos += 1, with wrap back to 0 if gone past bottom of nametable + lda *.ypos + clc + adc #1 + cmp #.DEVICE_SCREEN_HEIGHT + bcc 1$ + lda #0 +1$: + sta *.ypos + dec *.num_rows + bne _set_bkg_submap_horizontalStripes_rowLoop + rts + +_set_bkg_submap_horizontalStripes_remainder: + lda *.tmp+1 + ora #>PPU_NT0 + tax + lda *.tmp + and #0xE0 ; Always start remainder at X=0 + jsr .ppu_stripe_begin_horizontal + ldx *.remainder +1$: + lda [*.src_tiles],y + iny + jsr .ppu_stripe_write_byte + dex + bpl 1$ + jsr .ppu_stripe_end + jmp _set_bkg_submap_horizontalStripes_rowLoopEnd + + +.define .num_cols ".num_rows" + +_set_bkg_submap_verticalStripes: + ; Adjust height and calculate remainder if row wraps from bottom to top + lda *.ypos + clc + adc *.height + sec + sbc #.DEVICE_SCREEN_HEIGHT + sta *.remainder + bmi 1$ + lda *.height + sec + sbc *.remainder + sta *.height +1$: + ; Decrement to allow treating 0-case same as negative + dec *.remainder + ; + lda *.src_tiles + sta *.tiles + lda *.src_tiles+1 + sta *.tiles+1 + ; + lda *.width + sta *.num_cols + ldy #0 +_set_bkg_submap_verticalStripes_columnLoop: + lda *.tiles + sta *.src_tiles + lda *.tiles+1 + sta *.src_tiles+1 + ; + lda #0 + sta *.tmp+1 + lda *.ypos + asl + rol *.tmp+1 + asl + rol *.tmp+1 + asl + rol *.tmp+1 + asl + rol *.tmp+1 + asl + rol *.tmp+1 + ora *.xpos + sta *.tmp + ; + lda *.tmp+1 + ora #>PPU_NT0 + tax + lda *.tmp + jsr .ppu_stripe_begin_vertical + ldx *.height +1$: + lda [*.src_tiles],y + jsr .ppu_stripe_write_byte + ; .src_tiles += width + lda *.map_width + clc + adc *.src_tiles + sta *.src_tiles + lda #0 + adc *.src_tiles+1 + sta *.src_tiles+1 + dex + bne 1$ + jsr .ppu_stripe_end + ; if wrapped around, write remainder + lda *.remainder + bpl _set_bkg_submap_verticalStripes_remainder +_set_bkg_submap_verticalStripes_columnLoopEnd: + iny + inc *.xpos + dec *.num_cols + bne _set_bkg_submap_verticalStripes_columnLoop + rts + +_set_bkg_submap_verticalStripes_remainder: + ldx #>PPU_NT0 + lda *.tmp + and #.DEVICE_SCREEN_WIDTH-1 ; Always start remainder at Y=0 + jsr .ppu_stripe_begin_vertical + ldx *.remainder +1$: + lda [*.src_tiles],y + jsr .ppu_stripe_write_byte + ; .src_tiles += width + lda *.map_width + clc + adc *.src_tiles + sta *.src_tiles + lda #0 + adc *.src_tiles+1 + sta *.src_tiles+1 + dex + bpl 1$ + jsr .ppu_stripe_end + jmp _set_bkg_submap_verticalStripes_columnLoopEnd
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.