From 0aefffacb5cb08202f7ba53b6e3b9a7303b1d66e Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Thu, 23 Jan 2025 13:57:45 +0100 Subject: Use custom configurations everywhere MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moreover, I have introduced a linker configuration for MMC1 as well, so to properly implement the `basics/persist.s` example. Signed-off-by: Miquel Sabaté Solà --- Makefile | 12 ++++++------ basics/flicker.s | 1 - basics/input.s | 3 +-- basics/persist.s | 24 ++++++++++++++++-------- basics/sprite.s | 28 ++++++++++++++++------------ config/mmc1.cfg | 26 ++++++++++++++++++++++++++ config/nrom.cfg | 24 ++++++++++++++++++++++++ config/unrom.cfg | 24 +++++++++++------------- space/src/space.s | 2 -- 9 files changed, 100 insertions(+), 44 deletions(-) create mode 100644 config/mmc1.cfg create mode 100644 config/nrom.cfg diff --git a/Makefile b/Makefile index 179ee62..7b89700 100644 --- a/Makefile +++ b/Makefile @@ -30,16 +30,16 @@ build: basics space scroll .PHONY: basics basics: $(E) " CC basics/sprite" - $(Q) $(CC65) $(CCOPTS) basics/sprite.s -o out/basics/sprite.nes + $(Q) $(CC65) $(CCOPTS) basics/sprite.s -C config/nrom.cfg -o out/basics/sprite.nes $(E) " CC basics/input" - $(Q) $(CC65) $(CCOPTS) basics/input.s -o out/basics/input.nes + $(Q) $(CC65) $(CCOPTS) basics/input.s -C config/nrom.cfg -o out/basics/input.nes $(E) " CC basics/persist" - $(Q) $(CC65) $(CCOPTS) basics/persist.s -o out/basics/persist.nes + $(Q) $(CC65) $(CCOPTS) basics/persist.s -C config/mmc1.cfg -o out/basics/persist.nes $(E) " CC basics/flicker" - $(Q) $(CC65) $(CCOPTS) basics/flicker.s -o out/basics/flicker.nes + $(Q) $(CC65) $(CCOPTS) basics/flicker.s -C config/nrom.cfg -o out/basics/flicker.nes $(E) " CC basics/unrom" $(Q) $(CC65) $(CCOPTS) basics/unrom.s -C config/unrom.cfg -o out/basics/unrom.nes @@ -50,9 +50,9 @@ basics: .PHONY: space space: $(E) " CC space" - $(Q) $(CC65) $(CCOPTS) space/src/space.s -o out/space/space.nes + $(Q) $(CC65) $(CCOPTS) space/src/space.s -C config/nrom.cfg -o out/space/space.nes .PHONY: scroll scroll: $(E) " CC scroll" - $(Q) $(CC65) $(CCOPTS) scroll/level.s -o out/scroll/level.nes + $(Q) $(CC65) $(CCOPTS) scroll/level.s -C config/nrom.cfg -o out/scroll/level.nes diff --git a/basics/flicker.s b/basics/flicker.s index 34fc312..25f1d33 100644 --- a/basics/flicker.s +++ b/basics/flicker.s @@ -18,7 +18,6 @@ .segment "CHARS" .incbin "../assets/diskun.chr" -.segment "STARTUP" .segment "CODE" .include "../shared/diskun.s" diff --git a/basics/input.s b/basics/input.s index 6918487..b773fd7 100644 --- a/basics/input.s +++ b/basics/input.s @@ -32,8 +32,6 @@ .addr reset .addr irq -.segment "STARTUP" - .segment "CODE" nmi: @@ -173,3 +171,4 @@ pressed: .endproc .segment "CHARS" +.byte $00 diff --git a/basics/persist.s b/basics/persist.s index 430654f..3e7c439 100644 --- a/basics/persist.s +++ b/basics/persist.s @@ -11,10 +11,9 @@ ;; Last but not least, all of this is done thanks to the MMC1 chip. Thus, this ;; file is also a minimalistic example on how to configure it, even if it ;; doesn't take full advantage of it (e.g. we are not doing any bank switching). -;; Because of this, note that we are not using a proper linker configuration for -;; it (I'm using cc65's default, which is tailored for NROM chips). Thus, bank -;; switching will actually never work under this setup. Bank switching is -;; covered through other examples like `basics/unrom.s`. +;; A base configuration for this chip can be found in `config/mmc1.cfg`. For +;; better grasping bank switching though refer to other examples like +;; `basics/unrom.s`. .segment "HEADER" .byte 'N', 'E', 'S', $1A @@ -36,9 +35,12 @@ .addr reset .addr irq -.segment "STARTUP" -.segment "CODE" +;; Unused. This is the swappable PRG-ROM bank as per `config/mmc1.cfg`. +.segment "BANK0" +.byte $00 +;; This is the fixed PRG-ROM bank as per `config/mmc1.cfg`. +.segment "BANK1" ;; Unused nmi: @@ -65,7 +67,7 @@ reset: ;; point to any address range of $8000-$FFFF. If you want to be sure about ;; it, you can simply do: `lda #%10000000` and then `sta $8000`. This will ;; ensure that the chip is reset. That being said, a micro-optimization can - ;; be performed by taking advantage that the "CODE" segment resides above + ;; be performed by taking advantage that the "BANK1" segment resides above ;; address $8000. Then, you can use the `inc` instruction which first writes ;; the old value before the incremented one. All having thus the same effect ;; but saving 2 bytes. I know it's somewhat obfuscated and it's done for @@ -164,4 +166,10 @@ reset_mmc1: @loop: jmp @loop -.segment "CHARS" +;; Unused +.segment "CHR0" +.byte $00 + +;; Unused +.segment "CHR1" +.byte $00 diff --git a/basics/sprite.s b/basics/sprite.s index 34f9dba..1fa55ad 100644 --- a/basics/sprite.s +++ b/basics/sprite.s @@ -70,18 +70,20 @@ .addr irq ;;; -;; Required by the default linker configuration. Theoretically there should be a -;; semantical difference between this section and "CODE", but as for the linker -;; goes, there is no difference and everything will be put sequentially on the -;; resulting binary. Hence, if you want (and as I do here), you can leave this -;; empty (so to make the default configuration of the linker happy), and put -;; everything into the "CODE" segment. In fact, according to the Famicom Party -;; Book (https://famicom.party/book/04-hardwareoverview/), the "STARTUP" section -;; is only used by C programs compiled down into 6502 assembly, so it might not -;; be even relevant for us (and in fact said book actually removes this segment -;; in its linker configuration down the road). +;; The "STARTUP" segment is required by the default linker configuration. +;; Theoretically there should be a semantical difference between this section +;; and "CODE", but as for the linker goes, there is no difference and everything +;; will be put sequentially on the resulting binary. Hence, if you want, you can +;; leave this empty (so to make the default configuration of the linker happy), +;; and put everything into the "CODE" segment. In fact, according to the Famicom +;; Party Book (https://famicom.party/book/04-hardwareoverview/), the "STARTUP" +;; section is only used by C programs compiled down into 6502 assembly, so it +;; might not be even relevant for assembly programmers (and in fact said book +;; actually removes this segment in its linker configuration down the road). +;; This is also removed by the configuration provided in `config/nrom.cfg`, +;; which is the one being used in the end for this example. ;;; -.segment "STARTUP" +;; .segment "STARTUP" .segment "CODE" @@ -143,7 +145,9 @@ reset: ;;; ;; NOTE: If you are using a mapper which needs some special configuration, ;; now it would be a good time set it up. I am not using a special mapper, - ;; so there's nothing from me to do here. + ;; so there's nothing from me to do here. Refer to other examples like + ;; `basics/persist.s` on how some chips such as MMC1 are set up at this + ;; point. ;;; ;; At this point, we have to wait for the PPU to stabilize. This is diff --git a/config/mmc1.cfg b/config/mmc1.cfg new file mode 100644 index 0000000..5544c1f --- /dev/null +++ b/config/mmc1.cfg @@ -0,0 +1,26 @@ +MEMORY { + # iNES header. + HEADER: start = $0, size = $10, fill = yes; + + # Banked PRG ROM. + PRG0: start = $8000, size = $4000, fill = yes, fillval = $f8, define = yes; + PRG1: start = $C000, size = $3FFA, fill = yes, fillval = $f9, define = yes; + + # Hardware Vectors. + ROMV: start = $FFFA, size = $0006, fill = yes; + + # Banked CHR banks. + ROM2_0: start = $0000, size = $2000, fill = yes, fillval = $11; + ROM2_1: start = $2000, size = $2000, fill = yes, fillval = $22; +} + +SEGMENTS { + HEADER: load = HEADER, type = ro; + + BANK0: load = PRG0, type = ro; + BANK1: load = PRG1, type = ro; + VECTORS: load = ROMV, type = ro; + + CHR0: load = ROM2_0, type = ro; + CHR1: load = ROM2_1, type = ro; +} diff --git a/config/nrom.cfg b/config/nrom.cfg new file mode 100644 index 0000000..41a1f2a --- /dev/null +++ b/config/nrom.cfg @@ -0,0 +1,24 @@ +## +# Same as the default NROM configuration provided by cc65, but with C stuff +# stripped away (e.g. namely, there are no more segments like 'STARTUP'). + +MEMORY { + # iNES header + HEADER: file = %O, start = $0000, size = $0010, fill = yes; + + # Fixed ROM. + ROM0: file = %O, start = $8000, size = $7FFA, fill = yes, define = yes; + + # Hardware Vectors. + ROMV: file = %O, start = $FFFA, size = $0006, fill = yes; + + # 1 8k CHR Bank + ROM2: file = %O, start = $0000, size = $2000, fill = yes; +} + +SEGMENTS { + HEADER: load = HEADER, type = ro; + CODE: load = ROM0, type = ro, define = yes; + VECTORS: load = ROMV, type = rw; + CHARS: load = ROM2, type = rw; +} diff --git a/config/unrom.cfg b/config/unrom.cfg index 5b18707..fccdb88 100644 --- a/config/unrom.cfg +++ b/config/unrom.cfg @@ -15,7 +15,7 @@ MEMORY { HEADER: start = $0, size = $10, fill = yes; # Program RAM. Available if a battery-backed RAM was requested. - WRAM: start = $6000, size = $2000, define = yes; + WRAM: file = "" start = $6000, size = $2000, define = yes; # Swappable ROM addresses. Note the filled values. This is done so it's also # clear by inspecting the memory which bank we are on. This can come in @@ -29,7 +29,8 @@ MEMORY { PRG6: start = $8000, size = $4000, fill = yes, fillval = $fe, define = yes; # Fixed ROM address. - PRG: start = $C000, size = $4000, fill = yes, fillval = $ff, define = yes; + PRG: start = $C000, size = $3FFA, fill = yes, fillval = $ff, define = yes; + ROMV: start = $FFFA, size = $0006, fill = yes; } SEGMENTS { @@ -40,19 +41,16 @@ SEGMENTS { # code and basic stuff that you don't want ever to be gone here. This will # include stuff like the reset code, bank switching utilities, etc. FIXED: load = PRG, type = ro, define = yes; + VECTORS: load = ROMV, type = ro, define = yes; ## # Swappable banks. - BANK0: load = PRG0, type = ro, define = yes; - BANK1: load = PRG1, type = ro, define = yes; - BANK2: load = PRG2, type = ro, define = yes; - BANK3: load = PRG3, type = ro, define = yes; - BANK4: load = PRG4, type = ro, define = yes; - BANK5: load = PRG5, type = ro, define = yes; - BANK6: load = PRG6, type = ro, define = yes; - - # Last but not least, the vectors must be the last thing and they are - # expecting a very special place on the fixed bank. - VECTORS: load = PRG, start = $fffa, type = ro; + BANK0: load = PRG0, type = ro; + BANK1: load = PRG1, type = ro; + BANK2: load = PRG2, type = ro; + BANK3: load = PRG3, type = ro; + BANK4: load = PRG4, type = ro; + BANK5: load = PRG5, type = ro; + BANK6: load = PRG6, type = ro; } diff --git a/space/src/space.s b/space/src/space.s index 675aaa2..1d39e7a 100644 --- a/space/src/space.s +++ b/space/src/space.s @@ -28,8 +28,6 @@ .segment "CHARS" .incbin "../../assets/space.chr" -.segment "STARTUP" - .segment "CODE" .include "../include/apu.s" -- cgit v1.2.3