OKay, after one week of studying, tweaking, debugging, I present to you the mmc3 startup I made, c000 switchable
cart.s , attached, is pure ASM. No C was used at all.
ITS HEAVY COMMENTED, so everyone understands each step. I even made my very first own font
The config :
[/size]
Enjoy, and feel free to ask if you need help !
To use, just download the cart.s, replace the current config by this one, and compile with cc65 !
Make sure to remove all the .incbin I have in the code ( when I load my dmc samples, and my chr.rom and chr.rom2 )
For the zeropage, use your own or simply replace the include by:
.segment "zeropage"
For the header, use this :
[/size]
I compile using a .bat:
Message me if you want a even cleaner version ;D





cart.s , attached, is pure ASM. No C was used at all.
ITS HEAVY COMMENTED, so everyone understands each step. I even made my very first own font


The config :
Code:
MEMORY {#INES Header: HEADER: start = $0, size = $10, file = %O ,fill = yes;#RAM Addresses: # Zero page ZP: start = $00, size = $100, type = rw, file = "", define = yes;#note, the c compiler + neslib + famitone2 use about 60 zp addresses, I think#note OAM: start = $0200, size = $0100, define = yes;#note, sprites stored here in the RAMRAM: start = $0300, size = $0400, file = "", define = yes;#note, I located the c stack at 700-7ff, see belowWRAM: start = $6000, size = $2000, file = "", define = yes;#ROM Addresses:DMC: start = $C000, size = $2000, file = %O, fill = yes, define = yes;# Switchable PRG-ROM bank for my dmc samplesDMC2: start = $C000, size = $2000, file = %O, fill = yes, define = yes; # Switchable PRG-ROM bank for my dmc samplesDMC3: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bank for my dmc samples DMC4: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bank DMC5: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bank DMC6: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bank DMC7: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bank DMC8: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bank DMC9: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bank DMC10: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bankDMC11: start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes; # Switchable PRG-ROM bank#DMC12: start = $C000, size = $2000, file = %O, fill = yes, define = yes; # Switchable PRG-ROM bank #DMC13: start = $C000, size = $2000, file = %O, fill = yes, define = yes; # Switchable PRG-ROM bankPRG: start = $A000, size = $2000, file = %O, fill = yes, define = yes; # Switchable PRG-ROM bank for $A000-$BFFFPRG2: start = $A000, size = $2000, file = %O, fill = yes, define = yes; # Switchable PRG-ROM bank for $A000-$BFFFPRG3: start = $A000, size = $2000, file = %O, fill = yes, define = yes; # Switchable PRG-ROM bank for $A000-$BFFF#since we are using $c000 switchable THIS HAVE TO BE HERE for mmc3 to work correctly!!! correct me if im wrong, cc65 compiler.PRG_FIXED: start = $8000, size = $2000, file = %O, fill = yes, define = yes; # Fixed PRG-ROM, second-last bank, PRGRESET: start = $E000, size = $2000-6, file = %O, fill = yes, define = yes; # Fixed PRG-ROM for reset at last bank# make sure the reset code is in e000-ffff, and vectors at that end.ROMV: start = $FFFA, size = $6 , file =%O, fill = yes, define = yes ;# ! 16 Banks of 8K CHR ROMCHR0: start = $0000, size = $2000, file = %O, fill = yes; CHR1: start = $2000, size = $2000, file = %O, fill = yes; CHR2: start = $4000, size = $2000, file = %O, fill = yes; CHR3: start = $6000, size = $2000, file = %O, fill = yes; CHR4: start = $8000, size = $2000, file = %O, fill = yes; CHR5: start = $A000, size = $2000, file = %O, fill = yes; CHR6:start = $C000, size = $2000, file = %O, fill = yes; CHR7:start = $E000, size = $2000, file = %O, fill = yes; CHR8: start = $10000, size = $2000, file = %O, fill = yes; CHR9: start = $12000, size = $2000, file = %O, fill = yes; CHR10: start = $14000, size = $2000, file = %O, fill = yes; CHR11: start = $16000, size = $2000, file = %O, fill = yes; CHR12:start = $18000, size = $2000, file = %O, fill = yes; CHR13:start = $1A000, size = $2000, file = %O, fill = yes; CHR14:start = $1C000, size = $2000, file = %O, fill = yes; CHR15:start = $1E000, size = $2000, file = %O, fill = yes;}SEGMENTS { HEADER: load = HEADER, type = ro; ZEROPAGE: load = ZP, type = zp;# this needs to be in right order and nothing missing except optionals#LOWCODE: load = PRG_FIXED, type = ro, optional = yes;#INIT: load = PRG_FIXED, type = ro, define = yes, optional = yes; CODE: load = PRG_FIXED, type = ro, define = yes; RODATA: load = PRG_FIXED, type = ro, define = yes; #DATA: load = PRG, run = RAM, type = rw, define = yes; BSS: load = RAM, type = bss, define = yes; #HEAP: load = RAM, type = bss, optional = yes; #ONCE: load = PRG_FIXED, type = ro, define = yes;XRAM: load = WRAM,type = bss, define = yes; ABANK1: load = PRG, type = ro, define = yes;# SWITCHABLE $A000 #1ABANK2: load = PRG2, type = ro, define = yes;# SWITCHABLE $A000 #2 ABANK3: load = PRG3, type = ro, define = yes;# SWITCHABLE $A000 #3 DMCBANK1: load = DMC, type = ro, define = yes; #$C000 first of 13 banks DMCBANK2: load = DMC2, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK3: load = DMC3, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK4: load = DMC4, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK5: load = DMC5, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK6: load = DMC6, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK7: load = DMC7, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK8: load = DMC8, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK9: load = DMC9, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK10: load = DMC10, type = ro, define = yes; # SWITCHABLE PRG-ROM DMCBANK11: load = DMC11, type = ro, define = yes; # SWITCHABLE PRG-ROM # startup needs to be in the e000-ffff fixed bankSTARTUP: load = PRGRESET, type = ro, define = yes;# VECTORS at the last fixed bank, in our case startupVECTORS: load = ROMV, type = ro;CHARS: load = CHR0, type = ro;CHARS2: load = CHR1, type = ro;CHARS3: load = CHR2, type = ro;}#I know nothing yet about theses, not even sure we need it.#FEATURES {# CONDES: segment = INIT,# type = constructor,# label = __CONSTRUCTOR_TABLE__,# count = __CONSTRUCTOR_COUNT__;# CONDES: segment = RODATA,# type = destructor,# label = __DESTRUCTOR_TABLE__,# count = __DESTRUCTOR_COUNT__;# CONDES: type = interruptor,# segment = RODATA,# label = __INTERRUPTOR_TABLE__,# count = __INTERRUPTOR_COUNT__;#}
Enjoy, and feel free to ask if you need help !
To use, just download the cart.s, replace the current config by this one, and compile with cc65 !
Make sure to remove all the .incbin I have in the code ( when I load my dmc samples, and my chr.rom and chr.rom2 )
For the zeropage, use your own or simply replace the include by:
.segment "zeropage"
For the header, use this :
Code:
.segment "HEADER" .byte "NES", $1A ; [0x00-0x03] Identification String ("NES" + EOF, standard for NES ROMs) ; "NES" = ASCII bytes $4E, $45, $53 ; $1A = EOF marker .byte $08 ; [0x04] PRG-ROM size ; Number of 16 KB PRG-ROM banks: ; 0x00: No PRG-ROM (invalid for NES) ; 0x01: 16 KB ; 0x02: 32 KB ; ... ; 0xFF: 4 MB .byte $10 ; [0x05] CHR-ROM size ; Number of 8 KB CHR-ROM banks: ; 0x00: CHR-RAM used instead of ROM ; 0x01: 8 KB ; 0x02: 16 KB ; ... ; 0xFF: 2 MB .byte %01000000 ; [0x06] Flags 6: ; %00100000 is UNROM , %0100 0000 is mmc3 ; |||||||| ; |||||||+-- Mirroring type: ; ||||||| 0: Horizontal arrangement ("mirrored horizontally") ; ||||||| 1: Vertical arrangement ("mirrored vertically") ; ||||||+--- Battery-backed PRG-RAM: ; |||||| 0: No battery-backed memory ; |||||| 1: Battery-backed memory present (e.g., for saving games) ; |||||+---- Trainer presence: ; ||||| 0: No trainer ; ||||| 1: 512-byte trainer present between header and PRG-ROM ; ||||+----- Four-screen VRAM layout: ; |||| 0: No (uses mirroring specified above) ; |||| 1: Yes (ignores mirroring bits) ; ++++------ Lower 4 bits of mapper number (0-15) .byte $08 ; [0x07] Flags 7: ; %00001000 ; |||||||| ; |||||||+-- Console type: ; ||||||| 00: NES/Famicom ; ||||||| 01: Vs. System ; ||||||| 10: PlayChoice-10 ; ||||||| 11: Extended Console Type (see byte 13) ; ||||||+--- Reserved, always 0 ; |||||+---- NES 2.0 identifier: ; ||||| 0: iNES format ; ||||| 1: NES 2.0 format ; ++++------ Upper 4 bits of mapper number (16-255 when combined with lower bits) .byte $00 ;8 Mapper MSB/Submapper;D~7654 3210;---------;SSSS NNNN;|||| ++++- Mapper number D11..D8;++++------ Submapper number .byte $00 ; [0x09] PRG-R0M size 9 ;PRG-ROM/CHR-ROM size MSB;D~7654 3210;---------;CCCC PPPP;|||| ++++- PRG-ROM size MSB;++++------ CHR-ROM size MSB ; PRG-R0M size is determined as: "64 << shift count" bytes ; 0x00: No PRG-R0M ; 0x01: 64 bytes ; 0x02: 128 bytes ; ... ; 0x07: 8192 bytes (8 KB) ; ... ; 0x0F: 1 MB (uncommon) ;10 .byte $00 ;PRG-RAM/EEPROM size;D~7654 3210; ---------; pppp PPPP; |||| ++++- PRG-RAM (volatile) shift count; ++++------ PRG-NVRAM/EEPROM (non-volatile) shift count;If the shift count is zero, there is no PRG-(NV)RAM.;If the shift count is non-zero, the actual size is;"64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7. .byte $00 ;11 CHR-RAM size;D~7654 3210; ---------; cccc CCCC; |||| ++++- CHR-RAM size (volatile) shift count; ++++------ CHR-NVRAM size (non-volatile) shift count;If the shift count is zero, there is no CHR-(NV)RAM.;If the shift count is non-zero, the actual size is;"64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7. .byte $00 ;12; [0x0A] CPU/PPU timing ; Timing mode: ; 00: NTSC (RP2C02 PPU, 60Hz) ; 01: PAL (RP2C07 PPU, 50Hz) ; 10: Multi-region (both NTSC and PAL compatible) ; 11: Dendy (UA6538, NTSC-like frame timing with PAL-like clock speed) .byte $00 ;13 When Byte 7 AND 3 =1: Vs. System Type;D~7654 3210;---------;MMMM PPPP;|||| ++++- Vs. PPU Type;++++------ Vs. Hardware Type;When Byte 7 AND 3 =3: Extended Console Type;D~7654 3210; ---------;.... CCCC; ++++- Extended Console Type.byte $00;14 Miscellaneous ROMs;D~7654 3210; ---------;.... ..RR;++- Number of miscellaneous ROMs present.byte $00 ;15 Default Expansion Device; D~7654 3210; ---------; ..DD DDDD; ++-++++- Default Expansion Device;https://www.nesdev.org/wiki/NES_2.0#PRG-ROM_Area
I compile using a .bat:
Code:
ca65 cart.s -o cart.o -t nes -l cart.asmld65 cart.o -o cart.nes -t nes
Statistics: Posted by v.depatie — Mon Jan 06, 2025 11:33 pm — Replies 3 — Views 124