vgmrips

The forum about vgm files
It is currently 2018-10-22, 14:49:51

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 79 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
 Post subject:
PostPosted: 2017-07-28, 18:54:39 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
grauw wrote:
Vampirefrog, it’s the OPL4 linux driver, it’s existing for ages. Not sure if it came from an official vendor, or some Linux dev who got provided the official data, or retrieved the table data from the SoundEdge software or by disassembling the SoundEdge drivers, or just manually build the table, could be anything. Could try to find and disassemble the SoundEdge Windows driver if you want a second data point.


All I want is to decipher the bit fields in that element table at 0x176ab in the program ROM.

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-28, 20:06:23 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Okay so here's how it works.

- The instrument table at 0x10410 has the following data (this is what I've figured out so far):
- Instrument uses two elements (bool)
- Level (volume) for element 1 and 2
- Detune for element 1 and 2
- Pan for element 1 and 2
- Name (8 chars, space padded)
- Region group ID for both elements

Each entry in the table starts with 16 bytes that hold Level, Detune, two elements bool, and other stuff I haven't figured out yet.
Next 8 bytes is the name
Next comes a pair of 36 bytes, one for each element
First two bytes use only the lower 4 bits to select the region group
Within these 36 byte chunks are also Pan bytes (pan goes from L7 to R7)

The Region group ID is an index into the table at 0x1841C (I might be off by a couple of bytes). That table has the start index into the region table at 0x176ab. The next index in the same table is the next start index, you can use that to compute the number of entries used.

So to view the samples used by an instrument, go to the instrument table at 0x10410, go to bytes 24 and 25 for element 1, and 60 and 61 for element 2 (if the first byte of the entry is 1, which means it uses the second element). Put those bytes together and you have an index into the table at 0x1841C. Read the value there (let's call it N) and count N entries, or N*9 bytes from the start of the region table at 0x176ab. You select the region you're interested in, depending on which key you're playing, and you have the sample number, which is an index into the sample rom table, which is at its beginning.

See this spreadsheet for more details.

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-29, 2:53:45 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Here is a capture from the chip:

sync word is 0xeeee, every 9 words
data is samples (1/44100 of a second) then D0-D7 and A0-A3

It goes out of sync sometimes, so I'm not sure what's up. I'm still trying to figure it out. Capture was made with a 3000000 baud rate and a FT232 board. I am not sure what the results should look like, so can someone check if the data is good?

I've logged since turn on of the device up to playing the demo song until the end.


Attachments:
foo.cap.gz [1.32 MiB]
Downloaded 27 times

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.
Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-29, 9:02:34 

Contributors Contributors
Staff Staff
Reverse engineers Reverse engineers
Offline
User avatar

Joined: 2013-07-17, 23:32:39
Posts: 333
Not sure if I can make much sense of this unless /CS (/GEW8) and /WR is logged as well. I see there is 32 bytes of data between each 0xEE,0xEE sequence.

An example sequence looks like this (there are 8 four byte sequences per sync word and not 9):
Code:
a6 03 ff f8
72 0b 00 fb
a2 03 ff f8
d6 07 94 eb
82 06 00 fb
a4 03 ff f8
d0 0c 00 fb
a4 03 ff f8


So the "ff,f8" part in the first line is the data present on the bus?. I think that you could actually get rid of the "samples" part, as timing is not something we're too concerned about now, just the data instead.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-29, 11:08:20 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Here are the connections:
/WR - PD15
/CS - PE1
D0-D7 - PD0-PD7
A0-A3 - PD8-PD11
NC - PD13,PD14
/RD - PD12

I am triggering on /WR, and checking if /CS is low in the interrupt handler. Here is the ISR:

Code:
static int mark = 0;
void exti15_10_isr(void) {
   if((GPIOE_IDR & GPIO1) == 0) { // Check /CS (PE1)
      uint16_t w = timer_get_counter(TIM1);
      TIM1_CNT = 0; // reset counter
      _write(1, (char *)&w, 2);

      w = GPIOD_IDR; // get the whole 16 bits
      _write(1, (char *)&w, 2);

      mark++;
      if(mark == 8) {
         w = 0xeeee;
         _write(1, (char *)&w, 2);
         mark = 0;
      }
   }
   exti_reset_request(EXTI15);
}

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-29, 11:35:27 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Ok here's another capture, this time in binary and with a marker for every write. you'll notice that the second byte of data always has the 0x80 bit set, that's because it's /RD.

At the beginning it goes out of sync at some point then it seems to be ok.

Code:
void exti15_10_isr(void) {         // trigger on /WR (PD15)
   uint16_t w;
   if((GPIOE_IDR & GPIO1) == 0) { // check if /CS is on
      w = 0xeeee;                // marker
      _write(1, (char *)&w, 2);  // send marker

      w = TIM1_CNT;              // get samples since last ISR call
      TIM1_CNT = 0;              // reset timer to zero
      _write(1, (char *)&w, 2);  // send samples

      w = GPIOD_IDR;             // get D0-D7, A0-A3, /RD, NC, NC, /WR
      _write(1, (char *)&w, 2);  // send data

   }
   exti_reset_request(EXTI15);
}


Edit: I've fixed the timing code. I was counting up to 3773 at the mcu's clock, which is 168MHz in this case. I've changed it to prescale by 3810 and count up to 65535. This way the timing should be for real. 168000000 / 3810 = 44094.5. Reattached another log. I've noticed that when I hit play on the demo song, it freezes up a bit, I assume the CPU is doing some intensive work and not sending any data to the YM chippo.
Edit 2: Perhaps if we can figure out which messages to ignore, I can reduce the log's size.
Edit 3: I can also log VGM data directly, not sure which commands though.


Attachments:
foo.cap.gz [309.75 KiB]
Downloaded 29 times

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.
Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 0:17:39 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Perhaps we can ask that R. Belmont fella why MAME uses only 3 of the 4 address lines

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 1:05:26 

Staff Staff
Programmers Programmers
Musicians Musicians
Contributors Contributors
Reverse engineers Reverse engineers
Offline
User avatar

Joined: 2011-12-01, 20:20:07
Posts: 3014
Location: Germany
It's actually emulating 3 of the 16 possible addresses.

I looked at your captured data and made a list of commands and how often they occoured:
Code:
80 18   x3104
82 00   x2330
83 FE   x3104
84 03   x109044
86 00   x473003
86 01   x3107
86 AF   x3107
87 00   x2325
88 04   x3167
88 3D   x35
8B 03   x3104
8B 09   x954
8C 05   x227465
8D AF   x701
8D F2   x431
8E 02   x3107
8E 05   x3107
8F 09   x609
8F 8B   x3167
8F AF   x880
8F C4   x366
8F CC   x11
8F CE   x45
8F EE   x36
8F EF   x1524
The first byte is A0-A3/RD/WR, the second byte is D0-D7. The last column is how many times the commands were captured. (in decimal)
It doesn't make sense to be, though. I think there should be a more commands.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 1:42:03 

Contributors Contributors
Staff Staff
Reverse engineers Reverse engineers
Offline
User avatar

Joined: 2013-07-17, 23:32:39
Posts: 333
I think it might be a good idea to enter the TG100 test program and do a capture while executing test #10. It will play a tone on all 28 channels sequentially.

And, yes, I made a similar program to analyze the log and get pretty much the same results as Valley Bell. It seems like there are only 26 unique commands in the log.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 2:12:45 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Okay, so I thought that 0x80 bit being set was a little weird, since the code was meant to read it while it was low. It's actually /CS, not /RD. The ISR is a bit slow and reads just after the /CS and /WR lines have gone back to high state, so all that data was bogus. I'll make it so it uses a DMA to read the GPIO port instead, perhaps that'll make it more responsive. This is on an STM32F4 board, here's what it looks like: http://www.ebay.com/itm/STM32F4Discover ... SwOyJX-NcZ

If you look on the scope, you'll see the top signal, yellow, comes a bit after the middle one (cyan). Top is an output pin from the micro, middle is /CS and bottom is /WR.

Attachment:
IMG_0722.JPG
IMG_0722.JPG [ 6.65 MiB | Viewed 706 times ]


Attachments:
IMG_0715.JPG
IMG_0715.JPG [ 6.93 MiB | Viewed 706 times ]
IMG_0721.JPG
IMG_0721.JPG [ 6.36 MiB | Viewed 706 times ]
IMG_0720.JPG
IMG_0720.JPG [ 6.55 MiB | Viewed 706 times ]

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.
Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 2:42:58 

Contributors Contributors
Staff Staff
Reverse engineers Reverse engineers
Offline
User avatar

Joined: 2013-07-17, 23:32:39
Posts: 333
So I made a small breakthrough in reversing the program ROM.

Looking at the MAME source, I found out that the YMW258/MultiPCM maps channels in a slightly unusual way. In MAME the channel map table looks like this
Code:
const int32_t multipcm_device::VALUE_TO_CHANNEL[32] =
{
   0, 1, 2, 3, 4, 5, 6 , -1,
   7, 8, 9, 10,11,12,13, -1,
   14,15,16,17,18,19,20, -1,
   21,22,23,24,25,26,27, -1,
};


i found an equivalent table in the program rom at 0x14e10 to used to convert logical channel numbers to physical (how the chip recognizes them).
Code:
ROM:94E10 ChannelMapTable:.byte 0, 1, 2, 3, 4, 5, 6, 8! 0
ROM:94E10                 .byte 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0x10, 0x11! 8
ROM:94E10                 .byte 0x12, 0x13, 0x14, 0x15, 0x16, 0x18, 0x19, 0x1A! 0x10
ROM:94E10                 .byte 0x1B, 0x1C, 0x1D, 0x1E! 0x18


This led me to find the write to chip function
Code:
ROM:81F6A GEW8GetChannelWrite: ! near             ! CODE XREF: sub_8264A+25p
ROM:81F6A                 mov:g.w r4, @-sp
ROM:81F6C
ROM:81F6C loc_81F6C:                              ! CODE XREF: GEW8GetChannelWrite+5j
ROM:81F6C                 btst.b  #0:8, @unk_800:8 ! check busy flag?
ROM:81F6F                 bne     loc_81F6C:8
ROM:81F71                 mov:g.b @unk_3957:16, r4
ROM:81F75                 extu.b  r4
ROM:81F77                 add:q.w #-2, sp
ROM:81F79                 stc.b   ep, @sp
ROM:81F7B                 ldc.b   #9:8, ep
ROM:81F7E                 ! assume ep:9
ROM:81F7E                 mov:g.b @(0x4E10:16,r4), r4 ! Convert channel number to physical
ROM:81F82                 ldc.b   @sp, ep
ROM:81F84                 ! assume ep:nothing
ROM:81F84                 add:q.w #2, sp
ROM:81F86                 mov:s.b r4, @unk_801:8  ! set channel
ROM:81F88                 jsr     SmallDelay:16
ROM:81F8B                 mov:s.b r0, @unk_802:8  ! set register number
ROM:81F8D                 jsr     SmallDelay:16
ROM:81F90                 mov:s.b r1, @unk_800:8  ! write data
ROM:81F92                 mov:g.w @sp+, r4
ROM:81F94                 rts
ROM:81F94 ! End of function GEW8GetChannelWrite

(There are also variations of this function to only set the channel and to write data to a register.)

Just like the MAME MultiPCM core, this only uses three addresses to set the channel number, register number and to write the data.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 3:18:52 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
ctr wrote:
I think it might be a good idea to enter the TG100 test program and do a capture while executing test #10. It will play a tone on all 28 channels sequentially.


Okay, thanks for the tip. I've managed to enter that menu, it only works with the midi cable connected from in to out.

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.


Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 15:17:12 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Okay, I've managed to configure the DMA controller, here's the code for anyone curious, and a new capture. Unfortunately I'm still struggling to get timing information in there (trying to configure a second DMA stream triggered by the same signal to read a timer counter), but I think the data is probably less bogus this time. It starts before the demo song and ends after it.

The capture file format is now: 0xeeee, then 16 words of data. The wiring is now, from LSB to MSB: D0-D7, A0-A3, /RD, /CS, NC, NC. To read the file, ignore words with /CS high. These are captured by DMA, so they should be closer to the truth. I have no way of checking currently, would need a 16 channel logic analyzer.


Attachments:
tg100.c [4.32 KiB]
Downloaded 25 times
foo.cap.gz [2.62 MiB]
Downloaded 19 times

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.
Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 18:20:44 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Here are some more captures, this time with timing. I am using one DMA transfer, without much buffering, but it seems to work well. I was hoping to use DMA entirely but I couldn't figure it out.

Included are test mode 10, startup, idle state and demo song.


Attachments:
startup.cap.gz [15.89 KiB]
Downloaded 28 times
idle.cap.gz [6.7 KiB]
Downloaded 21 times
demosong.cap.gz [309.28 KiB]
Downloaded 23 times
testmode.cap.gz [425 Bytes]
Downloaded 18 times

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.
Top
 Profile  
 
 Post subject:
PostPosted: 2017-07-30, 18:56:47 

Staff Staff
Programmers Programmers
Contributors Contributors
Ball Fondlers Ball Fondlers
Offline
User avatar

Joined: 2014-01-28, 5:51:54
Posts: 625
Here is another capture. It is a few midi notes. See if you can recognize the song.

With this one I've cleared the top bits of the second byte, so it's purely D0-D7 and A0-A3


Attachments:
notes.cap.gz [20.51 KiB]
Downloaded 18 times

_________________
Support me on patreon!.
Follow me on twitter.

If you like this post, give it a big thumbs up and hit that subscribe button down below! And as always, thanks for reading, and see you next post.
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 79 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group