Proper way to emulate DMA transfers.

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
urbanspr1nter
Posts: 39
Joined: Thu Aug 16, 2012 7:55 pm

Proper way to emulate DMA transfers.

Post by urbanspr1nter » Thu Feb 16, 2017 6:01 pm

Hi all, I am currently writing an SNES emulator, and have been implementing the CPU so far. I have implemented about 120 opcodes and have gotten it to be able to execute some code in Super Mario World ROM. For debugging, I have it output some disassembly. I have gotten to the point where the SMW rom executes what looks to be a DMA transfer... I have never written an emulator for a game console before and was wondering if anyone here could point me in the right direction on how DMA transfer will work in an emulated sense.

My assumption is that CPU loop stops and we actually modify the array that represents RAM directly and move the PC value the number of bytes that were read? (In a sense, this would behave like an interrupt, right?)

The piece of disassembly I have encountered is along the lines of:

Code: Select all

LDA $9277, X
At $9277, I see there are bytes $42 and $26 loaded. Which prompts a series of consecutive bytes to follow:

Code: Select all

7C 92 00 F0 A0 04 F0 80 05 00
I actually am using a disassembly for reference and it looks to be referring to this piece of code here:

Site for reference:
http://caffie.net:31415/root/smw-irq/bl ... ank_00.asm

Image

Any thoughts?

Thanks!

creaothceann
Posts: 228
Joined: Mon Jan 23, 2006 7:47 am
Location: Germany
Contact:

Re: Proper way to emulate DMA transfers.

Post by creaothceann » Fri Feb 17, 2017 8:50 am

documentation

HDMA is DMA that automatically runs in HBLANK when enabled.
Last edited by creaothceann on Fri Feb 17, 2017 9:33 am, edited 1 time in total.
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10

tepples
Posts: 22014
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Proper way to emulate DMA transfers.

Post by tepples » Fri Feb 17, 2017 9:15 am

I thought it was called HDMA because it ran in horizontal blanking, not vertical blanking.

creaothceann
Posts: 228
Joined: Mon Jan 23, 2006 7:47 am
Location: Germany
Contact:

Re: Proper way to emulate DMA transfers.

Post by creaothceann » Fri Feb 17, 2017 9:33 am

...fixed.
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10

urbanspr1nter
Posts: 39
Joined: Thu Aug 16, 2012 7:55 pm

Re: Proper way to emulate DMA transfers.

Post by urbanspr1nter » Fri Feb 17, 2017 10:22 am

creaothceann wrote:documentation

HDMA is DMA that automatically runs in HBLANK when enabled.
So basically, I would watch for a flag in HBLANK or some sort and then proceed with emulating the transfers from there?

In my mind:
1. CPU execution stops due to HBLANK.
2. Handle the HDMA transfer. => From here, the PC is incremented to transfer the appropriate data.
3. Proceed with CPU execution again?

Thanks.

Nicole
Posts: 218
Joined: Sun Mar 27, 2016 7:56 pm

Re: Proper way to emulate DMA transfers.

Post by Nicole » Fri Feb 17, 2017 10:26 am

PC? As in the program counter? No, that shouldn't be touched at all, it transfers data from whatever HDMA tables are pointed to in the HDMA registers.

urbanspr1nter
Posts: 39
Joined: Thu Aug 16, 2012 7:55 pm

Re: Proper way to emulate DMA transfers.

Post by urbanspr1nter » Fri Feb 17, 2017 10:37 am

Nicole wrote:PC? As in the program counter? No, that shouldn't be touched at all, it transfers data from whatever HDMA tables are pointed to in the HDMA registers.
Ah, ok. I guess my main and probably very stupid question is... How would we move past the following bytes in the emulator:

If the PC (program counter) if left off around here:

Code: Select all

7C 92 00 F0 A0 04 F0 80 05 00
Those would be interpreted as opcodes and operands -- but it looks like from the assembly reference, it looks to just be raw data.

Nicole
Posts: 218
Joined: Sun Mar 27, 2016 7:56 pm

Re: Proper way to emulate DMA transfers.

Post by Nicole » Fri Feb 17, 2017 10:44 am

The PC is never there in the first place, it doesn't need to move past them.

nocash
Posts: 1211
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: Proper way to emulate DMA transfers.

Post by nocash » Fri Feb 17, 2017 11:50 am

Did you already emulate the RTS opcode, or at least understand what RTS is supposed to do?

urbanspr1nter
Posts: 39
Joined: Thu Aug 16, 2012 7:55 pm

Re: Proper way to emulate DMA transfers.

Post by urbanspr1nter » Fri Feb 17, 2017 11:51 am

Nicole wrote:The PC is never there in the first place, it doesn't need to move past them.
Ah I realize this now after tracing this... So basically it's something like this for this snippet of code:

Code: Select all

setup_window_HDMA:
	LDX.b #$04				                ;$009250	\ Index for DMA set up
.loop						                ;                \ Upload to $4374 to $4370
	LDA.w window_HDMA_settings,X		;$009252	  |
	STA.w $4370,X				                ;$009255	  |
	DEX					                        ;$009258	  |
	BPL .loop				                        ;$009259	 /
	LDA.b #$00				                ;$00925B	 \ HDMA Data bank $00
	STA.w $4377				                ;$00925D	 /


....

window_HDMA_settings:                 
	db $41,$26                                               ;$009277
	dl window_HDMA_data

window_HDMA_data:
	db $F0                                                      ;$00927C
	dw $04A0
	db $F0
	dw $0580
	db $00
X = $04

LDA $9277, X => LDA $927C, Then A = $00
STA $4370, X => STA $4374, Then $00 gets stored in $4370
DEX => X = 3

Repeat until X is negative

And we will have:

Code: Select all

$4370 -> $41
$4371 -> $26
$4372 -> $7C
$4373 -> $92
$4374 -> $00
Apologies for being so newbie. Still trying to learn assembly, hehe.

urbanspr1nter
Posts: 39
Joined: Thu Aug 16, 2012 7:55 pm

Re: Proper way to emulate DMA transfers.

Post by urbanspr1nter » Fri Feb 17, 2017 11:55 am

nocash wrote:Did you already emulate the RTS opcode, or at least understand what RTS is supposed to do?
Yes -- i realized now that it was my misunderstanding in the assembly code that caused me to trace it the incorrect way initially. But correct me if I am wrong:

RTS will basically:

- Pull the PC values from the stack.
-> increments the PC by 1 to point to the next instruction of where the jump occurred.

Post Reply