How do I set up MMC3?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: How do I set up MMC3?

Post by koitsu »

sdm wrote:ok, everything seems to work, the problem was a small trifle - before LDA% 00000110, there was no "#" character (of course, nesasm3 did not display an error and I missed the problem).
Just a comment in passing, and isn't intended to disparage or chastise you! It's more about "assembler education":

If the code was lda %00000110, then that's 100% valid code; the assembler not showing an error is correct behaviour. What you did there is essentially the same as writing lda 6 or lda $06 (load accumulator from zero page location 6). Just because you chose to use base 2 (binary) instead of base 10 (decimal) or base 16 (hexadecimal) doesn't change things in the least. There's no 100% correct way for the assembler to detect this situation as an error vs. something the user actually wanted to do; you can't assume that using base 2 as an operand isn't what the user wanted to do, and I have seen plenty of code on the Apple II where people have used base 10 addresses as operands, as "bizarre" as that might seem, but it's perfectly OK.

Iplementing a feature in the assembler (defaulting to disabled) that would allow you to tell it "only expect labels/equates, or base 16 numbers, as operands for non-immediate addressing modes" might sound like a good idea, right? When enabled, lda %00000110, lda 6, or MYVAL = %00000110 / lda MYVAL would cause an error to be thrown, while lda $06 or MYVAL = $06 / lda MYVAL would be OK. This would be annoying to implement in the assembler, however, because it would then have to track what base a particular line of code used, and there's no way to sanely deal with, say, lda $06+%10000000 (e.g. lda $86) or MYVAL = $06 + 128 / lda MYVAL. In other words, there would be tons of edge-case situations that would cause the assembler to potentially throw an error when the user didn't want it, plus adding complexity. Starting to see why nobody tries to implement this kind of thing? :-)

Like with any programming language, a single character/byte mistake can cause lots of pain. Pain that can cost you hours of time debugging/reverse-engineering. It's not unique to 6502 assembly at all. There isn't a 100% infallible way to relieve this problem in the computing world, sorry to say.
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: How do I set up MMC3?

Post by sdm »

How many cpu cycles does the switching of mmc3 bank take? it's about 0 8000-9fff bank changed into another one:

Code: Select all

	LDA #%00000110	;6 / 8000-9fff
	STA $8000
	LDA #2		;switch to mmc3 bank 2
	STA $8001
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How do I set up MMC3?

Post by tepples »

That's 12 cycles: load immediate is 2, and store absolute is 4. The new bank is visible as soon as the STA instruction's memory access cycle completes, which is before the next instruction gets fetched.
sdm2
Posts: 46
Joined: Wed Feb 05, 2020 12:59 pm
Location: Poland

Re: How do I set up MMC3?

Post by sdm2 »

I would like to make sure that I have correctly initialized MMC3, because I had incorrectly initialized MM3 before (errors visible in MESEN with "Randobize power-on state for mappers" advanced mode set - Earlier, I did not notice any errors, only after enabling this option.).

Is everything OK or something else needs to be reset in MMC3? (Mesen displays no errors after these changes.)

Code: Select all

RESET:						;mmc3 + chr ram (tnrom)

	STA $E000				;Disable IRQs.

	ldx #$07				;MMC3 init
mmc3initloop:
	stx $8000
	lda mmc3tbl,x
	sta $8001
	dex
	bpl mmc3initloop
	sta $A000

	LDA #$01
	STA $A000				;Horizontal mirroring

	LDA #%10000000				;enable WRAM
	STA $A001

	SEI
	CLD
 
	LDA #$40
	STA $4017				;off APU IRQ.
 
	LDX #$FF
	TXS					;FF as stack pointer
 
	INX
	STX $2000
	STX $2001

	lda #7
	sta $8000
	lda #1					;#nrbankA000
	sta $8001

	lda #6
	sta $8000
	lda #0					;#nrbank8000
	sta $8001

VBlankWait1:					;two waitblank's

	BIT $2002
	BPL VBlankWait1

VBlankWait2:

	BIT $2002
	BPL VBlankWait2

	TXA

ClearMemory:

	STA $0000, x
	STA $0100, x
	STA $0200, x
	STA $0300, x
	STA $0400, x
	STA $0500, x
	STA $0600, x
	STA $0700, x

	STA $6000, x				;clear wram
	STA $6100, x
	STA $6200, x
	STA $6300, x
	STA $6400, x
	STA $6500, x
	STA $6600, x
	STA $6700, x
	STA $6800, x
	STA $6900, x
	STA $6A00, x
	STA $6B00, x
	STA $6C00, x
	STA $6D00, x
	STA $6E00, x
	STA $6F00, x
	STA $7000, x
	STA $7100, x
	STA $7200, x
	STA $7300, x
	STA $7400, x
	STA $7500, x
	STA $7600, x
	STA $7700, x
	STA $7800, x
	STA $7900, x
	STA $7A00, x
	STA $7B00, x
	STA $7C00, x
	STA $7D00, x
	STA $7E00, x
	STA $7F00, x

	INX
	BNE ClearMemory
(...)

mmc3tbl:
	.db $0,$2,$4,$5,$6,$7,$0,$1
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: How do I set up MMC3?

Post by Quietust »

sdm2 wrote: Tue Dec 08, 2020 2:43 am I would like to make sure that I have correctly initialized MMC3, because I had incorrectly initialized MM3 before (errors visible in MESEN with "Randobize power-on state for mappers" advanced mode set - Earlier, I did not notice any errors, only after enabling this option.).

Is everything OK or something else needs to be reset in MMC3? (Mesen displays no errors after these changes.)
You've got a superfluous write to $A000 which you can remove, but other than that it should be fine as long as the code is located within $E000-$FFFF (since that's the only region whose initial state is guaranteed).
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Post Reply