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

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: PC-FX homebrew development.
« Reply #105 on: February 22, 2016, 04:54:25 PM »
Congratulations, that was quick!

Now, I've still got some important stuff left to do on the toolchain (like getting newlib compiling again), so I'm going to have to slow you down somehow ...  :-k

Errrrmmm ... you do realize that I can only pass on the new toolchain to folks who have completed the Zeroigar translation's "Sakuraigar Mode"?  (That should keep him busy for a while!) :wink:

Gredler

  • Guest
Re: PC-FX homebrew development.
« Reply #106 on: February 22, 2016, 05:12:04 PM »
Congratulations, that was quick!

Now, I've still got some important stuff left to do on the toolchain (like getting newlib compiling again), so I'm going to have to slow you down somehow ...  :-k

Errrrmmm ... you do realize that I can only pass on the new toolchain to folks who have completed the Zeroigar translation's "Sakuraigar Mode"?  (That should keep him busy for a while!) :wink:


I'll never work with these tools, drat!

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #107 on: March 06, 2016, 01:45:52 PM »
OK I beat your game... any idea on when this might be ready for testing? :)

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: PC-FX homebrew development.
« Reply #108 on: March 06, 2016, 02:30:07 PM »
OK I beat your game... any idea on when this might be ready for testing? :)

Oh, cr*p that was quick!  :shock:

I hope that you didn't actually take me seriously and really play the game ... unless you actually wanted to!  #-o

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #109 on: March 08, 2016, 12:24:50 PM »
After being a royal pain in elmer's ass (sorry bro hehe), I got the toolchain working here... so now comes the fun part. :D

« Last Edit: March 08, 2016, 12:32:18 PM by The Old Rover »

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: PC-FX homebrew development.
« Reply #110 on: March 08, 2016, 12:38:38 PM »
After being a royal pain in elmer's ass (sorry bro hehe), I got the toolchain working here... so now comes the fun part. :D

Woohoo!

Well ... there's the V810 VWF-code that I wrote for Zeroigar and posted in one of the other threads when you're ready to tackle that nasty ROM font in Alex's example code!  :wink:

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #111 on: March 08, 2016, 01:16:09 PM »
Ran it on my PC-FX... works beautifully. :)



Woohoo!

Well ... there's the V810 VWF-code that I wrote for Zeroigar and posted in one of the other threads when you're ready to tackle that nasty ROM font in Alex's example code!  :wink:

Oh yeah, definitely... and I'm gonna test the hell out of this thing and annoy you further ;) haha :lol:

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #112 on: March 08, 2016, 02:04:49 PM »
Naturally, one of the first things I looked for was library code to play CD audio tracks... looks like there are none, but there's low-level SCSI command access, so I can just write some code to do all the drive stabbies and wrap it up in a neat high-level implementation. :)

EDIT: OK, this part would be easier if I knew what the LUN was of the drive... :lol:
« Last Edit: March 08, 2016, 03:58:22 PM by The Old Rover »

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #113 on: March 09, 2016, 06:39:17 AM »
According to Ryphecha, the LUN should be 0. So, I attempted to edit the hello.c example program to play a CD track. I'm getting no audio, and it must be because I am missing some important step.

Code: [Select]
eris_low_psg_set_main_volume(15,15);
eris_low_cdda_set_volume(63,63);
scsicmd10[0] = 0x48;
scsicmd10[1] = 0;
scsicmd10[4] = 2;
scsicmd10[5] = 1;
scsicmd10[7] = 3;
scsicmd10[8] = 1;
scsicmd10[9] = 0;
eris_low_scsi_command(scsicmd10,10);

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #114 on: March 09, 2016, 01:14:08 PM »
I still can't get CD audio to work and I am not sure why... in the meantime, I've added some more high-level functionality to mimic HuC's behavior, as I did with the high-level sprite library. While it's pretty basic for now, it's a good proof of concept.

First up is put_string() as per HuC's implementation, with the addition of the Tall font.
Code: [Select]
void put_string(char* str, int x, int y, int tall)
{
u32 o[256];
int i;
int len = strlen8(str);
if (len > 255) len = 255;
for(i = 0; i < len; i++)
o[i] = str[i];
o[i] = 0;
u32 kram = x + (y << 5);
len = strlen32(o);
for(i = 0; i < len; i++) {
printch(o[i], kram + i, tall);
}
}

Then there's put_number() which requires itoa... looks like this is in stdlib but the default makefile explicitly prevents stdlib from linking so I just added K&R's implementation of itoa, slightly modified to work with this toolchain.

Code: [Select]
void put_number(int thenumber, int length, int x, int y, int tall)
{
char onum[33];
if (length > 32) length = 32;
if (length < 1) length = 1;
itoa(thenumber,onum);
onum[length] = 0;
put_string(onum, x, y, tall);
}

/* itoa:  convert n to characters in s */
void itoa(int n, char s[])
 {
     int i, sign;
 
     if ((sign = n) < 0)  /* record sign */
         n = -n;          /* make n positive */
     i = 0;
     do {       /* generate digits in reverse order */
         s[i++] = n % 10 + '0';   /* get next digit */
     } while ((n /= 10) > 0);     /* delete it */
     if (sign < 0)
         s[i++] = '-';
     s[i] = '\0';
     reverse(s);
 }
 
 /* reverse:  reverse string s in place */
 void reverse(char s[])
 {
     int i, j;
     char c;
 
     for (i = 0, j = strlen8(s)-1; i<j; i++, j--) {
         c = s[i];
         s[i] = s[j];
         s[j] = c;
     }
 }

And yeah, this is based on chartou32() and printstr() in hello.c... they work well, so why reinvent the wheel... I just merged them into a single function and added a safeguard.
« Last Edit: March 09, 2016, 02:29:52 PM by The Old Rover »

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #115 on: March 09, 2016, 02:24:16 PM »
Here's a put_hex() based on Robert Jan Schaper's itoa() that hardcodes in a base value of 16:

Code: [Select]
void put_hex(int thenumber, int x, int y, int tall)
{
static char buf[32] = {0};
int i = 30;
if (thenumber < 1)
{
put_string("0",x,y,tall);
return;
}
for(; thenumber && i ; --i, thenumber /= 16)
buf[i] = "0123456789ABCDEF"[thenumber % 16];
put_string(&buf[i+1],x,y,tall);
}
« Last Edit: March 09, 2016, 02:27:48 PM by The Old Rover »

elmer

  • Hero Member
  • *****
  • Posts: 2153
Re: PC-FX homebrew development.
« Reply #116 on: March 10, 2016, 02:29:08 AM »
Then there's put_number() which requires itoa... looks like this is in stdlib but the default makefile explicitly prevents stdlib from linking so I just added K&R's implementation of itoa, slightly modified to work with this toolchain.

Yes, I've got to figure out what the command-line-magic is that's needed to get stdlib actually linked into the build again.

I've got newlib is compiled for the V810, and it provides all the usual goodies, but I guess that Alex wasn't using it when he did his work on liberis.

Good work on the investigations ... I'll be interested to see what kind of code the compiler comes up with for some of the C code that you've done.

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #117 on: March 10, 2016, 08:42:47 AM »
Okay so I had the code working fine for CD audio playback all along... there was actually a bug in liberis that prevented it from outputting sound.

In src/low/soundbox.S:
Code: [Select]
.global _eris_low_cdda_set_volume

_eris_low_cdda_set_volume:
out.b r6, 0x12A[r6]
out.b r7, 0x12C[r6]
jmp [lp]

change it to this:
Code: [Select]
.global _eris_low_cdda_set_volume

_eris_low_cdda_set_volume:
out.b r6, 0x12A[r0]
out.b r7, 0x12C[r0]
jmp [lp]

though you can get the same effect in regular C code with the following:
Code: [Select]
out8(0x12A, leftvol);
out8(0x12C, rightvol);

so that's one mystery solved! :)

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #118 on: March 10, 2016, 10:35:14 AM »
So... we got some basic CD audio functionality now as well... here we go:

Code: [Select]
void cd_set_volume(u8 leftvol, u8 rightvol)
{
if (leftvol > 63) leftvol = 63;
if (rightvol > 63) rightvol = 63;
out8(0x12A, leftvol);
out8(0x12C, rightvol);
}

This does not exist in HuC because there's apparently no way to adjust the volume outside of using the hardware faders.

Code: [Select]
void cd_playtrk(u8 start, u8 end, u8 mode)
{
u8 scsicmd10[10];
scsicmd10[0] = 0x48;
scsicmd10[1] = 0;
scsicmd10[2] = 0; /* reserved */
scsicmd10[3] = 0; /* reserved */
scsicmd10[4] = start;
scsicmd10[5] = 1;
scsicmd10[6] = 0; /* reserved */
scsicmd10[7] = end;
scsicmd10[8] = 1;
scsicmd10[9] = 0;
eris_low_scsi_command(scsicmd10,10);
}

I made the prototype identical to the HuC one, although this is incomplete. There's probably a way to set the track(s) to loop, but I don't know what it is yet... made sense to prepare for it though. :) If there's no way to do it in hardware (what a step back that would be), then it could probably be emulated by polling the drive status at regular intervals.

Anyway, this is all tested working... I will try to add the rest of the CD audio functionality from here. MSF playback is supported, as well as pause/resume, so these won't be too difficult to add in. I just wanted to get a working base to start... now that it's working fine, it can be expanded.

nodtveidt

  • Guest
Re: PC-FX homebrew development.
« Reply #119 on: March 10, 2016, 01:58:49 PM »
More CD functionality based on direct SCSI commands.

Code: [Select]
void cd_pause()
{
u8 scsicmd10[10];
scsicmd10[0] = 0x47; // operation code PAUSE RESUME
scsicmd10[1] = 0; // Logical unit number
scsicmd10[2] = 0; // reserved
scsicmd10[3] = 0; // reserved
scsicmd10[4] = 0; // reserved
scsicmd10[5] = 0; // reserved
scsicmd10[6] = 0; // reserved
scsicmd10[7] = 0; // reserved
scsicmd10[8] = 0; // Resume bit
scsicmd10[9] = 0; // control
eris_low_scsi_command(scsicmd10,10);
}

void cd_unpause()
{
u8 scsicmd10[10];
scsicmd10[0] = 0x47; // operation code PAUSE RESUME
scsicmd10[1] = 0; // Logical unit number
scsicmd10[2] = 0; // reserved
scsicmd10[3] = 0; // reserved
scsicmd10[4] = 0; // reserved
scsicmd10[5] = 0; // reserved
scsicmd10[6] = 0; // reserved
scsicmd10[7] = 0; // reserved
scsicmd10[8] = 1; // Resume bit
scsicmd10[9] = 0; // control
eris_low_scsi_command(scsicmd10,10);
}

void cd_playmsf(u8 strt_m, u8 strt_s, u8 strt_f, u8 end_m, u8 end_s, u8 end_f, u8 mode)
{
u8 scsicmd10[10];
scsicmd10[0] = 0x47; // operation code PLAY AUDIO MSF
scsicmd10[1] = 0; // Logical unit number
scsicmd10[2] = 0; // reserved
scsicmd10[3] = strt_m; // starting M
scsicmd10[4] = strt_s; // starting S
scsicmd10[5] = strt_f; // starting F
scsicmd10[6] = end_m; // ending M
scsicmd10[7] = end_s; // ending S
scsicmd10[8] = end_f; // ending F
scsicmd10[9] = 0; // control
eris_low_scsi_command(scsicmd10,10);
}

Again, using HuC's convention. The pause/unpause functions could easily be put into a single function with a parameter... would save some code space...

Code: [Select]
void cd_pausectrl(u8 resume)
{
u8 scsicmd10[10];
if (resume > 1) resume = 1; // single bit; top 7 bits reserved
scsicmd10[0] = 0x47; // operation code PAUSE RESUME
scsicmd10[1] = 0; // Logical unit number
scsicmd10[2] = 0; // reserved
scsicmd10[3] = 0; // reserved
scsicmd10[4] = 0; // reserved
scsicmd10[5] = 0; // reserved
scsicmd10[6] = 0; // reserved
scsicmd10[7] = 0; // reserved
scsicmd10[8] = resume; // Resume bit
scsicmd10[9] = 0; // control
eris_low_scsi_command(scsicmd10,10);
}

Some #defines would make that clearer...

Code: [Select]
#define CD_PAUSE 0
#define CD_UNPAUSE 1
#define CD_RESUME 1
three #defines, because reasons. :lol:
« Last Edit: March 10, 2016, 02:02:09 PM by The Old Rover »