Author Topic: PC-FX homebrew development.  (Read 10152 times)

Mednafen

  • Full Member
  • ***
  • Posts: 140
Re: PC-FX homebrew development.
« Reply #225 on: April 12, 2016, 11:14:06 AM »
Quick and dirty code that proooobably(:p) works right(just pack nybbles low to high, little-endian):

Code: [Select]
static const int step_sizes[49] =
{
 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50,
 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157,
 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
};

static const int step_index_deltas[16] =
{
 -1, -1, -1, -1, 2, 4, 6, 8,
 -1, -1, -1, -1, 2, 4, 6, 8
};

typedef struct
{
 int predictor;
 int step_size_index;
 int delta_mask;

 long long error_sum;
} encoder_ctx_t;

void encoder_reset(encoder_ctx_t* ctx)
{
 ctx->predictor = 0;
 ctx->step_size_index = 0;
}

void encoder_init(encoder_ctx_t* ctx, int linear_ip, unsigned char raw_rate)
{
 if(linear_ip)
  ctx->delta_mask = ~((1 << raw_rate) - 1);
 else
  ctx->delta_mask = ~0;

 ctx->error_sum = 0;

 encoder_reset(ctx);
}

unsigned char encoder_encode(encoder_ctx_t* ctx, int16_t samp)
{
 const int32_t delta = (samp >> 1) - ctx->predictor;
 const int32_t abs_delta = abs(delta);
 const int32_t cur_ss = step_sizes[ctx->step_size_index];
 int32_t m;
 uint8_t nyb;

 m = (abs_delta / cur_ss) - 1;

 if(m < 0)
  m = 0;
 if(m > 7)
  m = 7;

 nyb = m | ((delta < 0) ? 8 : 0);

 //
 //
 //
 ctx->predictor += ((step_sizes[ctx->step_size_index] * ((nyb & 7) + 1)) & ctx->delta_mask) * ((nyb & 8) ? -1 : 1);
 if(ctx->predictor < -16384)
  ctx->predictor = -16384;

 if(ctx->predictor > 16383)
  ctx->predictor = 16383;

 ctx->step_size_index += step_index_deltas[nyb];
 if(ctx->step_size_index < 0)
  ctx->step_size_index = 0;

 if(ctx->step_size_index > 48)
  ctx->step_size_index = 48;

 ctx->error_sum += abs(samp - (int32_t)((uint32_t)ctx->predictor << 1));

#if 0
 {
  int16_t tmp = ctx->predictor << 1;
  fwrite(&tmp, 2, 1, stderr);
 }
#endif

 return nyb;
}

elmer

  • Hero Member
  • *****
  • Posts: 2148
Re: PC-FX homebrew development.
« Reply #226 on: April 12, 2016, 12:53:28 PM »
Quick and dirty code that proooobably(:p) works right(just pack nybbles low to high, little-endian):

Thanks!  :D

That's going to need a bit of studying ... but I was already taking a look at your code in Mednafen's soundbox.cpp.

Errrmmm ... that's definitely a bit different the standard OKI 12-bit codec implementation.

I'm going to need a little bit of time to delve into the details to understand the implications of the differences.

I guess that the 1st thing that I'm noticing is that it's dealing in 14-bit samples, and that the multiplier for the code bits is definitely different ... (n&7) + 1 instead of the (2*(n&7) + 1) / 2 that I'd expect.

But it is saturating, so I guess that I wasn't wrong on that aspect.

Well ... it's something to look at more-deeply once I've dealt with the PCE codec.

Mednafen

  • Full Member
  • ***
  • Posts: 140
Re: PC-FX homebrew development.
« Reply #227 on: April 14, 2016, 11:17:59 AM »
Should probably mention these libraries in case anyone wants to make an all-in-one encoder and isn't already familiar with them:

https://uazu.net/fidlib/
http://www.mega-nerd.com/libsndfile/
http://www.mega-nerd.com/SRC/

elmer

  • Hero Member
  • *****
  • Posts: 2148
Re: PC-FX homebrew development.
« Reply #228 on: April 14, 2016, 01:11:54 PM »
That's going to need a bit of studying ... but I was already taking a look at your code in Mednafen's soundbox.cpp.

Errrmmm ... that's definitely a bit different the standard OKI 12-bit codec implementation.

I'm going to need a little bit of time to delve into the details to understand the implications of the differences.

OK, I finally understand what's going on.  :)

I checked the PC-FX manual for the HuC6230 sound chip and here's what I found ...

ADPCM Sample Rates:

  31.47KHz / 15.73KHz / 7.87KHz / 3.93KHz

  The 15.73KHz / 7.87KHz / 3.93KHz rates support optional LERP.

ADPCM Sample Range:

  0..4095.875 (12-bit output, 15-bit internal)

ADPCM Initialization:

  Sample(N) = 2048.000
  Step(N)   = 16

  Sample clamps to 0 min or 4095.875 max.

On Decompression:

  SampleDelta(N) = ((Code(N) + 1) * Step(N-1)) / 8

  (Is this integer rounded, or stored as 15-bit???)

On Compression:

  Code(N) = ((8 * SampleDelta(N)) / Step(N-1)) - 1

  (Code(N) = Min 0, Max 7)


Now Mednafen's code makes sense ... thanks!

Yes, that's an interesting twist on the standard OKI algorithm.  :-k

I'm a bit disappointed that the PC-FX is only outputing 12-bit samples ... but at-least it's raised the sample rate to nearly 32KHz.

It looks like an easy algorithm to add into my converter ... I think that the code that Rypheca posted should work nicely!


Should probably mention these libraries in case anyone wants to make an all-in-one encoder and isn't already familiar with them:

https://uazu.net/fidlib/
http://www.mega-nerd.com/libsndfile/
http://www.mega-nerd.com/SRC/

Thanks, those are definitely some interesting libraries.  8)

But personally, I'm really, really, really, trying to avoid doing anything too comprehensive, because I don't see the point in attempting to compete with SOX or Audacity for the majority of the audio processing.

I just want to make sure that the final 16KHz 16-bit .wav -> 16KHz ADPCM .voc stage is actually correct for the chips that we're using.
« Last Edit: April 14, 2016, 01:16:41 PM by elmer »

NightWolve

  • Hero Member
  • *****
  • Posts: 5277
Re: PC-FX homebrew development.
« Reply #229 on: April 14, 2016, 03:34:10 PM »
2, I have no idea how to receive the results from an SCSI command.

Err, that's what I was trying to address, using the ModeSense10 SCSI command is something trickier (and I wouldn't wanna go into that myself here).

But my best guess for status results of a SCSI command would be to look at the 17th byte passed the CDBByte[16] array (the SCSI command packet array). In both ASPI and SPTI programming styles, to communicate with SCSI devices, the SENSE_DATA structure has always been placed right after CDBByte[16]. So the 17th byte would be the ErrorCode, the 19th byte would be the SenseKey, etc.

If ErrorCode is 0x00, the command is pending, the drive still working. If it's 0x01, you got success, and if it's 0x04, you got an error which is when you then need to check 3 variables, SenseKey, AddSenQual, and AddSenseCode to convert the error to a human readable string.

Here's a short sample on that:

Code: [Select]
switch (bySenseKey) {
// MEDIUM ERROR: Indicates that the command terminated with a non-recovered error condition
// that may have been caused by a flaw in the medium or an error in the recorded data.
// This sense key may also be returned if the device server is unable to distinguish
// between a flaw in the medium and a specific hardware failure (i.e., sense key 4h).
case KEY_MEDIUMERR:
switch (gAddSenseCode) {
case 0x02:
switch (gAddSenQual) {
case 0x00:
return "No seek complete (Unreadable sector: unburned/gap/bad disc or lens)";
}
break;
case 0x06:
switch (gAddSenQual) {
case 0x00:
return "No reference position found";
}
break;
case 0x11:
switch (gAddSenQual) {
case 0x00:
return "Unrecovered read error";
case 0x01:
return "Read retries exhausted";
case 0x05:
return "Layered-Error Correction uncorrectable error";
case 0x06:
return "CIRC unrecovered error";
case 0x0F:
return "Error reading UPC/EAN number";
case 0x10:
return "Error reading ISRC number";
}
break;
}

I should think at least for PC-FX, a 1994 console, that the CD component is a fully compliant SCSI device, so it should behave similarly and that info should be available right after CDBByte[16]. Dunno about the PCE though, David Shadoff described it as a "hacked audio CD player" so it'd be a bit more primitive I gather.
« Last Edit: April 14, 2016, 04:11:23 PM by NightWolve »

elmer

  • Hero Member
  • *****
  • Posts: 2148
Re: PC-FX homebrew development.
« Reply #230 on: April 14, 2016, 04:16:32 PM »
2, I have no idea how to receive the results from an SCSI command.

Err, that's what I was trying to address, using the ModeSense10 SCSI command is something trickier (and I wouldn't wanna go into that myself).

Ahhh ... what you're missing is that we're not getting anything sensible back from the SCSI device.  :wink:

The PC-FX SCSI interface is done at a very, very low level ... and the library routines that Alex wrote for reading data from the CD just don't actually handle reading back the results of the "SENSE" command, or any results, really (unless I'm missing something).

The routines are very, very "fragile", they're not like Microsoft's SCSI commands, and they "break" and crash the PC-FX when they're not used 100% as-expected.

That's not surprising (to me), it just means that we need to wrap some error-handling code around them to make them "friendly".

The point (to me) is that Alex created a wonderful set of "groundwork" that can be expanded to build a robust and full-featured library for PC-FX development.

But it's not "friendly" yet ... and The Old Rover is doing a great job in pointing out areas that need to be improved.


NightWolve

  • Hero Member
  • *****
  • Posts: 5277
Re: PC-FX homebrew development.
« Reply #231 on: April 14, 2016, 04:41:43 PM »
The routines are very, very "fragile", they're not like Microsoft's SCSI commands, and they "break" and crash the PC-FX when they're not used 100% as-expected.

Right, but I think it's a SCSI thing/standard, not a Microsoft or Adaptec thing in what I was pointing out. Somewhere, you have the CDBByte[16] array in the PC-FX code which is the SCSI command packet array, and if you have that, the 17th byte would be the SCSI return ErrorCode, and the 19th byte would be SenseKey, etc. It's a hunch. So, that's where I would look.

He also wanted to know how to use the ModeSense10 command, which is how you detect the drive's speed setting, return the information on its abilities, stuff like that, but I don't wanna get into that one, it's tricky and it along with ModeSelect10 lock up the drive easy when used improperly. ;)

I locked up my drives plenty of times when developing TurboRip. It's sending a bad SCSI command to the drive that did the trick. One of the safeguards though that I learned from looking at Adaptec's code was to loop through all detected CD drives, and set their timeouts to 15 seconds. By default, some manufacturers in the past set insane timeouts to like 15 minutes or so which is why you'd get stuck seemingly for good with a bad command or issue, etc...

elmer

  • Hero Member
  • *****
  • Posts: 2148
Re: PC-FX homebrew development.
« Reply #232 on: July 13, 2016, 04:40:57 AM »
Here's a bit of good news ... a developer on one of the VirtualBoy forums is giving my V810 GCC compiler a test drive.

Here's the better news ... his C code showed-up a huge mistake/bug that I'd made in the compiler!

Hopefully I've fixed that particular bug now, but this all goes to show how important it is to test the compiler with lots of different code so that these sort of problems show up.

It'll be interesting to see if he unearths any more problems.  8-[

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #233 on: July 13, 2016, 06:29:10 AM »
Nice. Tis good to see that there's still progress on this. :D

elmer

  • Hero Member
  • *****
  • Posts: 2148
Re: PC-FX homebrew development.
« Reply #234 on: July 15, 2016, 04:06:46 AM »
Nice. Tis good to see that there's still progress on this. :D

Yep ... slowly, it's mainly a question of priorities, and that the toolchain needs more testing.

I've fixed an 2nd bug, this time in the GNU assembler that was causing it to assert() and crash when it automatically replaced out-of-range short branches with long jumps (nice feature).

I don't know if you found that one in testing, but it does explain some weird stuff that I was seeing while doing the Zeroigar translation. Turned out to be a stupid 1-character cut-n-paste typo!  :oops:

elmer

  • Hero Member
  • *****
  • Posts: 2148
Re: PC-FX homebrew development.
« Reply #235 on: July 19, 2016, 04:54:50 AM »
Yep ... slowly, it's mainly a question of priorities, and that the toolchain needs more testing.

Well, the VirtualBoy guy (jorgeche) has got his engine/game-demo running with my patched GCC now, and I guess that means that it's pretty much got as thorough a testing as it's going to for a while.

I'll try and clean up the patches for a "release" sometime in the next few weeks/months (there's no rush, right?).

One thing that was particularly interesting about jorgeche's engine code is that he's basically implemented a lot of C++ object-oriented features in C as macros.

It made me curious enough that I tried building the GCC C++ compiler for the V810/PC-FX, and it actually compiled!

Anyone interested in C++, or rather "Embedded C++" (the saner subset for small machines) programming for the PC-FX?

FYI ... most of my game development work over the years on lots of platforms was done in C++, but basically following the same restrictions as Embedded C++.

Console manufacturers don't allow you to use exceptions, and C++'s horrible and slow RTTI is trivially-replacable with much faster type-safe dynamic casting using functions/macros if you don't use multiple-inheritance. OTOH any kind of dynamic casting would be slow on the PC-FX.

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #236 on: July 19, 2016, 07:25:54 AM »
Not a fan of C++ myself but there are plenty of others who are so it'd be wise to keep support for it, imo.

Krimstah

  • Newbie
  • *
  • Posts: 6
Re: PC-FX homebrew development.
« Reply #237 on: July 28, 2016, 02:32:29 PM »
Serious respect Elmer, enjoyed reading this thread , you too the old rover!

Just a question where do i start if i want to contribute,

My coding abilities are limited but i am willing to learn . Anywhere i should start?

I have two working PC FX's

Also i have read that code can be executed from the memory card slot is this true?

If so can a hacked memory card with an sd slot be used similar to what the gamecube can do?

Looking forward to hearing from you.

elmer

  • Hero Member
  • *****
  • Posts: 2148
Re: PC-FX homebrew development.
« Reply #238 on: July 29, 2016, 07:28:05 AM »
jorgeche managed to trigger another "hidden" bug in the compiler.  #-o

This time it was only with large C functions and when the frame-pointer was enabled in the compiler.

Turns out that GCC was "helpfully" rearranging the order of CPU instructions so that things were put on the stack before the stack was actually adjusted ... causing havoc if an interrupt happened.

That may be a bit too technical for most folks ... but any programmer here that's had to track down a bug like that knows what an absolute swine it is to track down the cause when the CPU just starts randomly jumping into strange locations because the stack has been corrupted! Without Mednafen, it would have been almost impossible to find.

Anyway ... I finally figured out how to convince GCC not to be so stupid, and everything seems good now.

Simple C++ test code seems to work fine with "new" and "delete" using the regular C malloc() and free() from newlib.

Those probably shouldn't be used in practice in a game-engine on the PC-FX, but replacing them with something more sophisticated can wait until work on liberis resumes.

The VirtualBoy guys are wanting to release a new version of their IDE/engine/game with the latest compiler, so I'm cleaning it all up for the first official release of the new compiler patches.

*****************************

Also i have read that code can be executed from the memory card slot is this true?

If so can a hacked memory card with an sd slot be used similar to what the gamecube can do?

I've heard that the PC-FX will load/run code off of the BMP memory card, but I've not tried it, and I have little idea of how you'd sensibly get any code on there in the first place.

I suppose that you'd have to burn a program on a PC-FX CD that would then write the 2nd program onto the BMP itself.

Sounds like a PITA, and I'm not sure what the gain would be ... unless someone either hacked a BMP to add circuitry to communicate to a PC, or someone designed a PC-to-PCFX joypad communication cable.

At the moment, it's just easier to develop in Mednafen and then burn a CD to test stuff on a real console.

It's even easier if you have a PC-FXGA card that already has all the PC communications side built into it.

Unless you're an electronics engineer and want to design a BMP-to-sdcard modification, then it's never going to work that simply.


Just a question where do i start if i want to contribute,

My coding abilities are limited but i am willing to learn . Anywhere i should start?

I'm not sure that we're at the point where there's much that anyone can contribute unless they have skills/experience in specific areas.

If someone is an electronics engineer, then it would be nice to have that PC-to-PCFX cable or BMP hack designed.

If someone is an expert in Japanese, then it would be nice to have more of the PC-FX hardware documentation translated.

If someone has a lot of experience at designing/creating assembly libraries for low-level hardware access, then liberis still needs a lot of work.

If someone has a lot of experience at designing/creating graphics tools or modern IDEs, then the new compiler and Mednafen could be wrapped-up in an easy-to-use package for newcomers to start with (like the VirtualBoy guys have done with VBDE).

If someone is a graphic artist, then there will eventually need to be some artwork done for a demos to show off the machine, but it's still too early for that.

If you don't have any of those skills, then I'm not sure what help you can provide at this time that's going to help out.

Helping others get interested in the platform is one way ... for instance, letting people know about the Zeroigar translation so that they can see one of the more-interesting games on the machine, that was pretty impressive in its story-telling.

Learning to program is always good, and you may want to get started with HuC on the PC Engine since the PC-FX uses 2 of the same VDC chips inside it, so anything that you learn should transfer over fairly easily later on.

Necromancer

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 21332
Re: PC-FX homebrew development.
« Reply #239 on: July 29, 2016, 08:12:59 AM »
If you don't have any of those skills, then I'm not sure what help you can provide at this time that's going to help out.

I will cheer from the sidelines and offer free corn if you ever find yourself in Nebraska.
U.S. Collection: 97% complete    155/159 titles