Re: new to snes environment, have some questions.
Posted: Wed Apr 25, 2018 2:17 pm
I'm not sure. I'm just doing the test right at the very beginning of the NMI. It's the only code I have running, then I end with an RTI.
NES Development Forums
https://forums.nesdev.org/
Yes, STY, sorry I had a typo.93143 wrote:More importantly, did you mean STY and not STA?
From my previous post:infidelity wrote:And I got the oam to write without dma, the info on the write register being a word helped!
FeelsBadMan. By "8-bit double-write", that means the MMIO register itself is a single address (ex. $2104), not a pair of addresses (ex. $2104 + $2105), and that it requires you to write twice to it (low byte first, then high byte). It's just like MMIO register $2122 in this respect. A "full 16-bit address" would be like $2116 and $2117 (for PPU RAM access), where you can do rep #$10 ldx #$1234 stx $2116 to write $34 to $2116 and $12 to $2117.koitsu wrote: $2104 is write-only an 8-bit double-write register (i.e. it's like $2122 but for OAM).
Code: Select all
2104 wb++--
dddddddd
2116 wl++?-
2117 wh++?-
aaaaaaaa aaaaaaaa
2122 ww+++-
-bbbbbgg gggrrrrr
Code: Select all
|rwd2?|Address|Title & Explanation |
||||||-----------------------------------------------------------------------|
|||||| |
||||||__ ?: Don't know what the statistics on this register are |
|||||____ 2: 2 byte (1 word) length register |
||||_____ d: Double-byte write required when writing to this register |
|||______ w: Writable register |
||_______ r: Readable register |
|----------------------------------------------------------------------------|
|rwd2?|Address|Title & Explanation |
|----------------------------------------------------------------------------|
...
| wd |$2104 |OAM data register [OAMDATA] |
| | |???????? ???????? |
...
| w 2 |$2116 |Video port address [VMADDL/VMADDH] |
| | |???????? ???????? |
...
| wd |$2122 |Colour data register [CGDATA] |
| | |xxxxxxxx x: Value of colour. |
Code: Select all
| w |$43x0 |DMA Control register [DMAPX] |
| | |vh0cbaaa v: 0 = CPU memory -> PPU. |
| | | 1 = PPU -> CPU memory. |
| | | h: For HDMA only: |
| | | 0 = Absolute addressing. |
| | | 1 = Indirect addressing. |
| | | c: 0 = Auto address inc/decrement. |
| | | 1 = Fixed address (for VRAM, etc.). |
| | | b: 0 = Automatic increment. |
| | | 1 = Automatic decrement. |
| | | a: Transfer type:
| | | 000 = 1 address write twice: LH. |
| | | 001 = 2 addresses: LH. |
| | | 010 = 1 address write once. |
| | | 011 = 2 addresses write twice: LLHH |
| | | 100 = 4 addresses: LHLH |
Code: Select all
$43x0: AB0CDEEE DMA Setup Register [DMAPx]
A -- Transfer Direction (0==CPU -> PPU, 1==PPU -> CPU)
B -- HDMA Addressing Mode (0==Absolute, 1==Indirect)
C -- CPU addr Auto inc/dec selection (0==Increment, 1==Decrement)
D -- CPU addr Auto inc/dec enable (0==Enable, 1==Disable (fixed))
E -- DMA Transfer Word Select
For DMA: (B0-B3 are the source data bytes, $21XX is PPU destination)
000 == Write 1 byte, B0->$21xx
001 == Write 2 bytes, B0->$21xx B1->$21XX+1
010 == Identical to 000
011 == Write 4 bytes, B0->$21XX B1->$21XX B2->$21XX+1 B3->$21XX+1
100 == Write 4 bytes, B0->$21XX B1->$21XX+1 B2->$21XX+2 B3->$21XX+3
Code: Select all
010 == Write 2 bytes, B0->$21xx B0->$21xx (i.e. same byte, written twice)
Are you sure about this part? My understanding (based on higan) is that the A-bus address is always updated after every byte written regardless of transfer type.koitsu wrote:(i.e. same byte, written twice)
Honestly, I'm not sure. Quoting official documentation:Revenant wrote:Are you sure about this part? My understanding (based on higan) is that the A-bus address is always updated after every byte written regardless of transfer type.koitsu wrote:(i.e. same byte, written twice)
(Which, given that regular DMA size is measured in bytes and not "transfer units", means that it would be equivalent to %000 for regular DMA, but not HDMA)
Code: Select all
$43x0: AB0CDEEE DMA Setup Register [DMAPx]
A -- Transfer Direction (0==CPU -> PPU, 1==PPU -> CPU)
B -- HDMA Addressing Mode (0==Absolute, 1==Indirect)
C -- CPU addr Auto inc/dec selection (0==Increment, 1==Decrement)
D -- CPU addr Auto inc/dec enable (0==Enable, 1==Disable (fixed))
E -- DMA Transfer Word Select
For DMA: (B0-B3 are the source data bytes, $21XX is PPU destination)
000 == Write 1 byte, B0->$21xx
001 == Write 2 bytes, B0->$21xx B1->$21XX+1
010 == Identical to 000
011 == Write 4 bytes, B0->$21XX B1->$21XX B2->$21XX+1 B3->$21XX+1
100 == Write 4 bytes, B0->$21XX B1->$21XX+1 B2->$21XX+2 B3->$21XX+3
For HDMA: (B0-B3 are the source data bytes, $21XX is PPU destination)
000 == Write 1 byte, B0->$21xx
001 == Write 2 bytes, B0->$21XX, B1->$21XX+1
010 == Write 2 bytes, B0->$21XX, B1->$21XX
011 == Write 4 bytes, B0->$21XX, B1->$21XX B2->$21XX+1 B3->$21XX+1
100 == Write 4 bytes, B0->$21XX, B1->$21XX+1, B2->$21XX+2, B3->$21XX+3
Code: Select all
43x0 rwb++++
da-ifttt
d = Transfer Direction.^
a = HDMA Addressing Mode.^^
i = DMA Address Increment.^^^
f = DMA Fixed Transfer.^^^^
ttt = Transfer Mode.
000 => 1 register write once (1 byte: p )
001 => 2 registers write once (2 bytes: p, p+1 )
010 => 1 register write twice (2 bytes: p, p )
011 => 2 registers write twice each (4 bytes: p, p, p+1, p+1)
100 => 4 registers write once (4 bytes: p, p+1, p+2, p+3)
101 => 2 registers write twice alternate (4 bytes: p, p+1, p, p+1)
110 => 1 register write twice (2 bytes: p, p )
111 => 2 registers write twice each (4 bytes: p, p, p+1, p+1)
I don't know why I somehow failed to remember this in my last post (other than it being somewhat late at night), but the last demo I wrote/released uses %010 for CGRAM color gradients. Presumably, so does every other game that uses HDMA to perform color gradient effects. So yes, it writes two different bytes.koitsu wrote: I don't know of any games which use %010 off the top of my head (do I look like I sit around disassembling every commercial game and analysing their DMA params? Haha), but it's safe to say we can't trust emulator source code, and everyone's documentation is either inconsistent or wrong (including my own).
Possible to test on hardware? Absolutely! Should it be tested on hardware? Absolutely!
With NMI-on-VBlank enabled, you can use wai in your main loop to effectively wait for VBlank to finish (e.g. wai / lda #1 would sit and wait for NMI to occur, then after rti in your NMI routine, the next instruction run would be lda #1). Technically it waits for any interrupt (NMI, IRQ, ABORT, or RESET (not that the latter matters)). It's quicker, easier, faster (cycle-wise) and more precise (timing-wise) than polling $4210 and watching bit 7 (akin to the above loop on the NES) but it depends on what your needs are.infidelity wrote:I have another question regarding "WAI"
Is that 1 byte opcode the same as what the NES uses for cpu cycles (LDA $2002, DEX, BPL back to DEX)? I want to know examples of how to use WAI properly.
Respectfully, this description is no better than any of the existing documentation. :\ Which is it?Revenant wrote:I don't know why I somehow failed to remember this in my last post (other than it being somewhat late at night), but the last demo I wrote/released uses %010 for CGRAM color gradients. Presumably, so does every other game that uses HDMA to perform color gradient effects. So yes, it writes two different bytes.
It's subjective. Two writes to a single MMIO register still technically is "transferring" two bytes of data. What matter is *which* two bytes it's transferring (from the source). Case in point: %001 is described "2 BYTE", "2-ADDRESS (VRAM etc.) L,H" -- two different source bytes are transferred, to two different destination addresses (i.e. B0->$21xx, B1->$21xx+1).Revenant wrote:My interpretation of the official documentation's "1-ADDRESS (WRITE TWICE)" is that it's only supposed to describe which type of register it's designed to write to. It clearly also states that it "transfers" two bytes, not just performs two writes. (Likewise, "L" and "H" are clearly referring to register addresses, not source bytes.)
I use %x11, so that I can set both the address and the colour with one channel. This method wastes a write because the address gets hit twice, but unfortunately (p, p+1, p+1) is not an available HDMA pattern.Revenant wrote:the last demo I wrote/released uses %010 for CGRAM color gradients. Presumably, so does every other game that uses HDMA to perform color gradient effects.