Author
|
Topic: Need some H/DMA clarification (Read 2 times)
|
Lenophis
Guest
|
|
« on: October 19, 2006, 02:23:21 am » |
|
The documentation (all 2 of them) about DMA and HDMA are as clear as mud. So far, this is what I've been able to determine:
* $4354 seems to hold the bank of where the table is. (It appears to be stored there by 8-bit A.) * $4357 seems to hold the bank of where the table is (hey wait a sec, *looks up*). I'm still rather confused as to why this is done twice overall (to $4354 and $4357). * HDMA and DMA cannot both use the same channels at once. If a channel is being used by DMA it cannot be used for HDMA and vice versa. That's about all that was really clear. * $4351 seems to hold how many bytes it will transfer, or so it seems. (It matches up with the table from time to time, but it's pretty inconsistant). * One of the H/DMA (or maybe it was both?) tables is null-terminated. * $4352 seems to hold the location of where the table is. (So far this has been consistant, so I'm fairly certain of this.)
And that's about all I can gather. I figure I'd rather ask people who know what they are doing rather than randomly guess based on crap documentation. Can anybody explain what I'm missing?
|
|
|
|
Nightcrawler
Guest
|
|
« Reply #1 on: October 19, 2006, 07:33:57 am » |
|
http://www.romhacking.net/docs/regs.txtHere.. Read this one. It's the most up to date accurate SNES register information there is at present time AND it has a whole bunch of useful topics at the bottom everybody overlooks such as 'DMA and HDMA'. All the information is there. Go read and use it.
|
|
|
|
DaMarsMan
Guest
|
|
« Reply #2 on: October 19, 2006, 09:32:48 am » |
|
I don't believe your missing anything. Here is some xkas code that I used for Heracles 4. Keep in mind it changes the games already existing HDMA routine. lorom
org $80CAFC ;seems to be a table of register settings starting at 4310
db $03 ;original is 00 for single byte table format 03 is for 4 byte and 04 is four byte with reg increment (translucent) this get's written to $43x0
db $21 ;register to write to (original $31) 30 for translucent and 21 for cg fade game store this value at $43x1
dl $FFD000 ; lacation for our HDMA table, original is 7E:2A61 (this balue stored at $43x2-4)
org $FFD000 ; the text box is 72 pixels in height so 72 scanlines BahamutLagoonStyleSharpDoubleFade() { db $6F dd $00000000 ;font color to black db $21 dd $00000000 ;font color to black db $D0
;this is the start of the textbox scanline (the next 72 control the color)
dd $10000300  ;the first 3 bytes are the color data to write and dd $00000000  ;the last byte is the palette enty for the color to change dd $14000300  ;keep in mind xkas flips these upon insert dd $00000000
dd $18000300 dd $00000000 dd $1C000300 dd $00000000
dd $20000300 dd $00000000 dd $24000300 dd $00000000
dd $28000300 dd $00000000 dd $2C000300 dd $00000000
dd $30000300 dd $00000000 dd $34000300 dd $00000000
dd $38000300 dd $00000000 dd $3C000300 dd $00000000
dd $40000300 dd $00000000 dd $44000300 dd $00000000
dd $48000300 dd $00000000 dd $4C000300 dd $00000000
dd $50000300 dd $00000000 dd $54000300 dd $00000000
dd $54000300 dd $00000000 dd $50000300 dd $00000000
dd $4C000300 dd $00000000 dd $48000300 dd $00000000
dd $44000300 dd $00000000 dd $40000300 dd $00000000
dd $3C000300 dd $00000000 dd $38000300 dd $00000000
dd $34000300 dd $00000000 dd $30000300 dd $00000000
dd $2C000300 dd $00000000 dd $28000300 dd $00000000
dd $24000300 dd $00000000 dd $20000300 dd $00000000
dd $1C000300 dd $00000000 dd $18000300 dd $00000000
dd $14000300 dd $00000000 dd $10000300 dd $00000000
;this is end of 72 pixels for textbox dd $00000000 dd $00000000 dd $00000000 dd $00000000 dd $00000000 ;back to original color dd $00000001 ;close out table dd $00000000 ;end table }
|
|
|
|
Lenophis
Guest
|
|
« Reply #3 on: October 19, 2006, 02:47:54 pm » |
|
http://www.romhacking.net/docs/regs.txtHere.. Read this one. It's the most up to date accurate SNES register information there is at present time AND it has a whole bunch of useful topics at the bottom everybody overlooks such as 'DMA and HDMA'. All the information is there. Go read and use it. A bunch of information, and no examples of how the hell anything is used. It kinda looks like this: "Here you go, you have an entire engine to a car. Every part is there and clearly labeled. Now put it together. Wait? A how-to? Nah, you don't get that, just work it out." \ It's a catch-22, since I already need to know how this works, and I don't. The bytes I listed don't seem to follow what this document even says. I don't believe your missing anything. Here is some xkas code that I used for Heracles 4. Keep in mind it changes the games already existing HDMA routine.
*snip* Considering I don't even know what the original routine looks like, it's no help. Also considering I haven't played Bahamut Lagoon before, I don't know what that "double fade" looks like. *sigh*
|
|
|
|
Nightcrawler
Guest
|
|
« Reply #4 on: October 19, 2006, 04:58:22 pm » |
|
http://www.romhacking.net/docs/regs.txtHere.. Read this one. It's the most up to date accurate SNES register information there is at present time AND it has a whole bunch of useful topics at the bottom everybody overlooks such as 'DMA and HDMA'. All the information is there. Go read and use it. A bunch of information, and no examples of how the hell anything is used. It kinda looks like this: "Here you go, you have an entire engine to a car. Every part is there and clearly labeled. Now put it together. Wait? A how-to? Nah, you don't get that, just work it out." \ It's a catch-22, since I already need to know how this works, and I don't. The bytes I listed don't seem to follow what this document even says. Oh please. It TELLS you the process necessary for HDMA in the HDMA section. It tells you what registers you need to set before starting it, what goes there, and what they are. How about you forget about HDMA and work with DMA. Have you at least mastered that? Because if you haven't you're jumping into something you're not ready for yet and you need to go back a step to a lower level. I don't think documents are the problem here. I think you're just missing out on some core concepts to be able to use some of the information. Have you even TRIED to write some code yet to do any DMA or HDMA transfers? Let's start with that and see where your trouble is. Write some code to do a simple DMA transfer. We'll start there. What is your goal here? Are you writing HDMA code? Are you trying to hack existing HDMA code? It makes a difference where we should really start. A disassembly or making some working code. Here's something else for you to chew on: http://transcorp.parodius.com/hdma.zipThat's an HDMA demo ROM Byuu wrote some time ago. P.S. http://www.romhacking.net/docs/GrogHDMA.txtDid you read that one as well?
|
|
|
|
Lenophis
Guest
|
|
« Reply #5 on: October 19, 2006, 05:15:40 pm » |
|
Oh please. It TELLS you the process necessary for HDMA in the HDMA section. It tells you what registers you need to set before starting it, what goes there, and what they are. Well then your reading comprehension is obviously a lot better than mine is. I learn by example since not everybody is gifted with reading something and instantly understanding it. How about you forget about HDMA and work with DMA. Have you at least mastered that? Let's see here. I started coding in C++ back in August 2004. Nowhere near close to mastering that. Did some minor 6502 stuff a year ago, nowhere near mastering that. Figured out a lot of 65816 because of an existing disassembly, but still nowhere near mastering that. If my leading up isn't any indication, a loud emphatic "no." Have you even TRIED to write some code yet to do any DMA or HDMA transfers? Let's start with that and see where your trouble is. Write some code to do a simple DMA transfer. We'll start there. I would, which is why I was asking questions in the first place. Think about it, if I had any knowledge about the subject, why would I be asking about it? What is your goal here? Are you writing HDMA code? Are you trying to hack existing HDMA code? It makes a difference where we should really start. A disassembly or making some working code. I'm looking at a routine that makes a gradiant effect to the screen, which falls under "hack existing HDMA code." I've already documented the routine that does it, I'm just having a hard time figuring out where the second table ends. Then there's the issue of "how does this table work?" Oh yeah, it's a general purpose routine, so it's called a bunch of times all throughout the rom. :'( "Oh, but why are you trying to do this?" Simple: *gets* I found two documents on this site about H/DMA. This was one of them. I got nowhere with it. --Edit-- Forget it, just lock this...
|
|
« Last Edit: October 19, 2006, 05:26:25 pm by Lenophis »
|
|
|
|
creaothceann
Guest
|
|
« Reply #6 on: October 19, 2006, 05:51:02 pm » |
|
Maybe this helps: http://vsnes.aep-emu.de/vSNES/SNESdocs.rarThis is how I understand the registers: (just ignore the "RW1VHFA" thing and the "8") 420B _W1VHFA 8 mDMAEn ; status flags: DMA channels 420C _W1VHFA 8 hDMAEn ; status flags: HDMA channels
; [INFO FOR CHANNELS 0..7] 4300 RW1VHFA 8 dma0Param ; DMA & HDMA transfer parameters 4310 RW1VHFA 8 dma1Param ; (A-Bus = CART & WRAM; B-Bus = PPU, APU & WRAM) 4320 RW1VHFA 8 dma2Param 4330 RW1VHFA 8 dma3Param ; D7 = Bus transfer direction: B to A (1) or A to B (0) 4340 RW1VHFA 8 dma4Param ; D6 = HDMA addressing mode: indirect (1) or direct (0) 4350 RW1VHFA 8 dma5Param ; D4 = inc/dec setting for D3=0: automatic dec. (1) or inc. (0) 4360 RW1VHFA 8 dma6Param ; D3 = DMA start address: fixed (1) or automatic inc/dec (0) 4370 RW1VHFA 8 dma7Param ; D2..D0 = DMA & HDMA transfer mode
4301 RW1VHFA 8 dma0B ; B-Bus address 4311 RW1VHFA 8 dma1B ; address of the register will be 21??h 4321 RW1VHFA 8 dma2B 4331 RW1VHFA 8 dma3B 4341 RW1VHFA 8 dma4B 4351 RW1VHFA 8 dma5B 4361 RW1VHFA 8 dma6B 4371 RW1VHFA 8 dma7B
4302 RWLVHFA 8 dma0A1L ; DMA start address / HDMA table address 4312 RWLVHFA 8 dma1A1L ; (low byte) 4322 RWLVHFA 8 dma2A1L 4332 RWLVHFA 8 dma3A1L 4342 RWLVHFA 8 dma4A1L 4352 RWLVHFA 8 dma5A1L 4362 RWLVHFA 8 dma6A1L 4372 RWLVHFA 8 dma7A1L
4303 RWHVHFA 8 dma0A1H ; DMA start address / HDMA table address 4313 RWHVHFA 8 dma1A1H ; (high byte) 4323 RWHVHFA 8 dma2A1H 4333 RWHVHFA 8 dma3A1H 4343 RWHVHFA 8 dma4A1H 4353 RWHVHFA 8 dma5A1H 4363 RWHVHFA 8 dma6A1H 4373 RWHVHFA 8 dma7A1H
4304 RW1VHFA 8 dma0ABank ; DMA transfer bank / HDMA table bank 4314 RW1VHFA 8 dma1ABank 4324 RW1VHFA 8 dma2ABank 4334 RW1VHFA 8 dma3ABank 4344 RW1VHFA 8 dma4ABank 4354 RW1VHFA 8 dma5ABank 4364 RW1VHFA 8 dma6ABank 4374 RW1VHFA 8 dma7ABank
4305 RWLVHFA 8 dma0DataL ; DMA byte count / indirect HDMA data address 4315 RWLVHFA 8 dma1DataL ; (low byte) 4325 RWLVHFA 8 dma2DataL 4335 RWLVHFA 8 dma3DataL 4345 RWLVHFA 8 dma4DataL 4355 RWLVHFA 8 dma5DataL 4365 RWLVHFA 8 dma6DataL 4375 RWLVHFA 8 dma7DataL
4306 RWHVHFA 8 dma0DataH ; DMA byte count / indirect HDMA data address 4316 RWHVHFA 8 dma1DataH ; (high byte) 4326 RWHVHFA 8 dma2DataH 4336 RWHVHFA 8 dma3DataH 4346 RWHVHFA 8 dma4DataH 4356 RWHVHFA 8 dma5DataH 4366 RWHVHFA 8 dma6DataH 4376 RWHVHFA 8 dma7DataH
4307 RW1VHFA 8 dma0HBank ; indirect HDMA data bank 4317 RW1VHFA 8 dma1HBank 4327 RW1VHFA 8 dma2HBank 4337 RW1VHFA 8 dma3HBank 4347 RW1VHFA 8 dma4HBank 4357 RW1VHFA 8 dma5HBank 4367 RW1VHFA 8 dma6HBank 4377 RW1VHFA 8 dma7HBank
4308 RWLVHFA 8 dma0A2L ; DMA destination address 4318 RWLVHFA 8 dma1A2L ; (low byte) 4328 RWLVHFA 8 dma2A2L 4338 RWLVHFA 8 dma3A2L 4348 RWLVHFA 8 dma4A2L 4358 RWLVHFA 8 dma5A2L 4368 RWLVHFA 8 dma6A2L 4378 RWLVHFA 8 dma7A2L
4309 RWHVHFA 8 dma0A2H ; DMA destination address 4319 RWHVHFA 8 dma1A2H ; (high byte) 4329 RWHVHFA 8 dma2A2H 4339 RWHVHFA 8 dma3A2H 4349 RWHVHFA 8 dma4A2H 4359 RWHVHFA 8 dma5A2H 4369 RWHVHFA 8 dma6A2H 4379 RWHVHFA 8 dma7A2H
430A RW1VHFA 8 dma0HLine ; HDMA Line Counter 431A RW1VHFA 8 dma1HLine ; Repeat (D7), value (D6..D0) 432A RW1VHFA 8 dma2HLine 433A RW1VHFA 8 dma3HLine 434A RW1VHFA 8 dma4HLine 435A RW1VHFA 8 dma5HLine 436A RW1VHFA 8 dma6HLine 437A RW1VHFA 8 dma7HLine
|
|
|
|
pagefault
Guest
|
|
« Reply #7 on: October 19, 2006, 06:39:34 pm » |
|
I don't know if it's been answered yet in this thread, I am still figuring out HDMA for myself. But for your own sake don't run any tests against the current ZSNES or any WIP's because our HDMA code is horrible. I would recommend bsnes for this if you aren't already doing this. But if it hasn't been answered I will try to find out from people who would know the answer.
|
|
|
|
DaMarsMan
Guest
|
|
« Reply #8 on: October 19, 2006, 11:55:26 pm » |
|
Ok let me try to explain to you exactly how HDMA works. Look at my code up there...In order to understand HDMA you need to understand how registers work. When you write to them you change the way the snes works. They also control some built in snes hardware functions. HDMA is one of those. Basically this is how it works.
All the registers are set and then HDMA is enabled. After HDMA is enabled it will continue working for every frame until disabled. When an snes outputs to the screen it starts by writing the top scanline and writes each scanline until it's native 244 scanlines are complete. If HDMA is enabled it allows the snes to change register information between scanlines. So the table determines which scanlines to change. Look at my code above. There is 72 entries because that was the size in horizontal scanlines of the textbox I wanted to change. So basically a table has one entry per scanline. The first byte tell it how many to repeat that one for. Since you want to just modify an HDMA you really dont have to worry about that. You need to change you table data. Table data can either be direct or indirect (pointers to table within table). Even if it's indirect and the table is in RAM you can always just make it direct and change it's position by changing the settings of the HDMA registers. So open up vSNES. I shows you the table data. It also shows you the table position (it reads this from the register). When you find your table position you can find where you game loads it in by setting a write breakpoint on the $43X4 - $43X7. Then look at a trace and see how your HDMA initialization is being done and where the data is loaded from. Change the location of the table to a new location you want by changing the values. Use xkas with incbin or db function to insert a new table at that location. Fool around with the table entries and test until you get it right.
Ok maybe I just confused you even more but trying to put this stuff in words is kind of hard sometimes.
|
|
|
|
Lenophis
Guest
|
|
« Reply #9 on: October 20, 2006, 12:06:17 am » |
|
|
|
|
|
byuu
Guest
|
|
« Reply #10 on: October 20, 2006, 03:22:12 am » |
|
Ouch! 17fps SNES9x v1.503+ should have all of our latest findings in HDMA. The only really recent thing not in Super Sleuth or the latest SNES9x is the HDMA indirect termination behavior, which won't affect your tests anyway.
|
|
|
|
Nightcrawler
Guest
|
|
« Reply #11 on: October 20, 2006, 07:46:38 am » |
|
Lenophis:
THAT's what you needed to do. Now you can get some help because you have something more specific. You were just asking a generic 'How does HDMA work?' question that was explained a handful different times from different sources and you were unsatisfied with them all. That's like a newb asking 'How do I hack a ROM?'. That's why I was so snappy. I brought up DMA because that's a simpler implementation. HDMA is just a more complicated DMA implementation generally speaking.
Anyway, maybe next time give a little reasoning/explanation behind your question and you might get some better help.
Try to take a look at DaMarsMans example again. See how his table is laid out? Color followed by palette entry. I assume this is probably what FFVI is doing or similar. It IS using HDMA for the color gradient right? You'll need to know how the table is laid out to get any kind of useable results from editing it. You should be able to figure that out by the pattern with some trial and error. You may want to post a bit of the table here and maybe some of the guys here can help you that way.
Just remember the concept of what the table is doing. Each 'entry' in the table transfers per one scanline. First, how long is each 'entry'? It's probably just one color and a palette entry, but I'm just assuming as I haven't looked at FFVI or the table.
|
|
|
|
RedComet
Guest
|
|
« Reply #12 on: October 20, 2006, 08:13:35 am » |
|
Wow. HDMA is a lot simpler than I had thought it was.
|
|
|
|
Nightcrawler
Guest
|
|
« Reply #13 on: October 20, 2006, 08:19:52 am » |
|
Wow. HDMA is a lot simpler than I had thought it was.
Setting up the registers is the hardest part. People get confused there especially because you can have a direct or indirect table and configuration can get a bit confusing. Otherwise, if you can understand the concept of DMA, you can understand the concept of HDMA. They are the same thing except HDMA can only fire between scanlines and it will CONTINUE transfers spanning multiple scanlines. DMA is a one shot, execute NOW, I'm finished deal.
|
|
|
|
DaMarsMan
Guest
|
|
« Reply #14 on: October 20, 2006, 11:56:22 am » |
|
It is a lot simpler than most think. Looks like your getting close Lenophis if you you may have to change the format of your table too and use 4 byte if it's not already using it. It can make everything a lot easier.
|
|
|
|
|