All working ok!! New beta!!

Oh, and about speed. Seems there is no need in frameskipping. Really slow part is z80 core emulation :(

So, what to do with scrolling. Why it repeated 8x times?

(i tried to add counter in video draw, which allow only each 8 line to be draw - but no good)

if in background_y=((y*8)+(256-scroll_reg))%256;

you change y*8 to y*16 it will repeated 16 times, but if you make y*1 it will repeated forever (i.e. only one tile will be draw/scrool at all screen)
 
As for the Z80 core, I was afraid of that. C emulation cores are deadly slow.

The scrolling, then. Yes, i tried to convert the Jim method... I can't really make a build right now.

Only now I noticed that the version I did is not really correct. y_background is actually quite simpler ^^;.

The scroll_reg is simply a value of the offset from the background layer. That _should_ be a perfect match for the slScrPosNbg () function.

Here's a little better version.

Code:
y_background = (256-scroll_reg)%256;

slScrPosNbg1(toFIXED(-220), toFIXED(-(background_y >> 2)));

No other method makes sense for me, so im interested in the method you had in mind.
 
Hmm, now you've got me wanting to hack on this thing.

Be afraid :).

I took a look at the Z80_RDMEM implementation, and saw a bit of room for optimization, so I decided to see if I could rewrite it. My C is rather rusty, but I'm pretty sure I've got my performance principles correct in writing this. Unfortunately I don't quite have a working SGL build environment at the moment, so it remains to be seen whether or not this is even correct, let alone substantially faster than the old version. The general idea was to get rid of as many if/else/elseif statements as possible.

Please let me know if this makes any sense :).

Code:
unsigned Z80_RDMEM(dword A)

{

// The basic goal here was to convert from a chain of if/elseif

// statements to a switch construct. The idea is based on the

// fact that all numbers from 0x7800 to 0x7BFF start with 010010,

// while all numbers from 7000 to 73FF start with 010000. The sync

// code is unchanged.

switch(A & 0xFC00)

{

case 0x78:

 if(DipSwitchSYNC == 1)

  {

  VideoDraw();

  DipSwitchSYNC = 0;

  slSynch();

  return 128;

  }

 else return 0;

// My implementation of the control bit mangling is completely

// independent of the overall if/elseif to switch conversion. Feel

// free to use the code that was here before - after all, this is

// untested. It's also a bit hairy, maybe it could be made into a

// macro or something... or maybe I'm just crazy.

case 0x70:

 hexdata |= (Smpc_Peripheral[0].data & PER_DGT_TR) >> 7; // Right Shift = Coin 1

 hexdata |= (Smpc_Peripheral[0].data & PER_DGT_ST) >> 9; // Start Button = 1P Start

 hexdata |= (Smpc_Peripheral[0].data & PER_DGT_TC) >> 5; // C Button = Fire

 hexdata |= (Smpc_Peripheral[0].data & PER_DGT_KR) >> 10; // D-Right = Right

 hexdata |= (Smpc_Peripheral[0].data & PER_DGT_KL) >> 8; // D-Left= Left

 hexdata |= (Smpc_Peripheral[0].data & PER_DGT_TB) >> 1; // B Button = Shield

 hexdata |= 0x0C; // Unused bits

 return hexdata;

default:

// The RAM/ROM read had a call to print a warning, but it was after

// a return, so I don't think it ever executed...

 return RAM[A];

} // switch(A & 0xFC00)
 
Yes. I did version 0.7 "scroll". The background scrolling ok for now (no it not used slScrPosNbg0)! Possibly, it also fix some gfx bugs mentioned by mal ("displacement" of monsters, crash of player ship and some others). Please, report how it works and if there any other bugs. Frame skipping removed (the main slow part is z80 core).

url:

http://phemusat.tripod.com/beta7.zip
 
I gave it a full play (one round till the mothership and beat it) and it works flawlessly! I think that it is a bit faster, but not much though...

Tears come to my eyes to see one of my fav games being emulated in one of my dearest consoles... Cool! Great work!

Now it is only a matter of Z80 emulation.. If i can will try to give it a look this weekend...

BTW he scrolling is great!
 
Ohh, but now you left me wondering, Denis ^^; if you're not releasing the source, could you at least enlighten me somewhat in your solution?

*oh*

Forget it, just seen the Source link on your page. Obviously, the screen format of Phoenix is more tile based than I ever imagined. Great work!

Eh, maybe you should give a post to those big emulation news thingies, and let them know of your feat. I'm not responsable for the tons of e-mail you'll be recieving, tough...

The fact that the ISO you provide is most likely illegal, has also been causing me some consern... Maybe a "legal" version, only with the binary, the ISO making tools and .cti file, but no Phoenix ROM's could be done? With a little help file at the side?

I'd be glad to help :)

(Edited by TakaIsSilly at 11:40 am on Dec. 12, 2001)
 
In that way I have some advance.. I made the scripts and CTI to build it.. of course I bet you have that too

Maybe you could tell zophar.net or retrogames...

Luck! and great work!
 
The binary itself is illegal to distribute because it contains SGL functions. The only way I can think of to get around the illegality is to code it without using any Sega libraries, and *then* distribute only the binary.
 
And actually, just the fact any CD program shows the "Licenced or approved by SEGA" screen at boot is matter for some pursuit of legal action.But Sega seems to go light on that particular matter. As of the moment they abandoned all support for Sega Saturn, as long as we don't request them for help, the SGL library should not be a matter of annoyance to them. However, a warning claiming this emulator not being for sale, rent or any commercial use would be quite nice.

ROM files, however, is a slight problem we could live without. ^^; Most sites will not distribute files with ROM's included, no matter the legality of the library used to produce the game.
 
Yeah, I hadn't looked at it from that perspective; maybe it's best to deal with it that way...

By the way, I think the scrolling is line-based - JAE and MAME apparently both implement it this way. Unfortunately, I don't have a real Phoenix board to test. Is it a "collector's item" now, or can it still be found at a reasonable price on the used PCB market? It's really a neat game that I wouldn't mind having...
 
Well, don't bother wasting a CD-R to try my Z80_RDMEM - it's broken. I still wouldn't mind any comments on the general idea, though :).

edit: speaking of not wasting CD-Rs, anyone who happens to have a commslink setup might find this useful...

edit: my controller code does work, but doesn't provide any speedup that I noticed. I suppose it's just not reading the controls enough for it to matter...

edit: Fixed the bug in my Z80_RDMEM, and still no noticeable speedup. Either the compiler isn't taking advantage of the case statements (i.e. compiling them into jump tables), or the main core is just eating up so much time that it doesn't matter.

(Edited by ExCyber at 4:43 pm on Dec. 12, 2001)
 
Just some thinkings about speeding up z80 emulation.

I think there are three possibly methods:

1) Phoenix uses 8085 which have much less instructions then z80. So, possibly remove all non-8085 instructions from z80 emu to speed it up a little.

2) Marcel z80 core includes a x86ams optimised module, is it possible to use inline sh2 asm in SGL? - if yes then it's too a method =)

3) Which z80 core are faster - Marcel or Marat? Maybe try just for testing Marat Faizullin core?

Possibly, from next version will do "legal" version - only binary sl.bin.
 
C cores are simply too slow for the 25 Mhz processor of the Saturn. I doubt changing C cores would do any good (you can try, tough). You need a SH2 ASM core to really see some results. I'm not really a ASM expert but will look into this ^^; Ah, and removing instructions from a case() structure is not really mutch of a speed increase. The Z80 has only 2 extra instructions, I don't really see the bad in it.

*arg, where did I but those Hitachi docs?*

As for ExCyber, the case stucture is might fast, but not

fast enough :p I was really curious to see how would a Saturn behave to the heavy cycle of a emulation core (secrettly hoping it had some kind of secret optimization :)). Stardust needs his SH2 core as well, then... Geez.
 
Hi guys, i've been following this emulator and its really great to see more homebrew dev for the Saturn.

If you check my website (link below) you'll see that i have Marat's z80 core running about 50% on the gameboy advance, so i really think full speed on the Saturn isn't too hard to achieve.

Here's what i'd recommend:

1) make new look up tables to reduce computation in the cpu. Make post add/sub flag tables (each table is 64k, i.e. 256*256, but Saturn has plenty of ram), this

will take care of add,sub,adc,sbc and cp. Next make

post inc and post dec flag tables (256 bytes each),

and perhaps even post and/or etc tables, the're only 256 bytes each

2) underclock the cpu a bit. I bet the game is sitting

pretty idle for most of the frame

3) sorry if you've already done this (i have looked at the source but i can't remember), but try to inline the read handler, by moving everything to the write handler and

making the read handler direct memory access.

ummm, there quite a few other simple things that

can be done which i can't remember now...

anyway, hope this helps a little

fools

www.goldroad.co.uk
 
"If you check my website (link below) you'll see that i have Marat's z80 core running about 50% on the gameboy advance, so i really think full speed on the Saturn isn't too hard to achieve."

AFAIK, SH2 doesn't have any particularly huge advantage over ARM7, the Saturn CPU is not quite running twice as fast as the GBA CPU, and I get the impression that GCC's ARM code generation/optimization has received more work than its SuperH code generation/optimization, so I'm not real sure that it would be easy.

"1) make new look up tables to reduce computation in the cpu. Make post add/sub flag tables (each table is 64k, i.e. 256*256, but Saturn has plenty of ram), this

will take care of add,sub,adc,sbc and cp. Next make

post inc and post dec flag tables (256 bytes each),

and perhaps even post and/or etc tables, the're only 256 bytes each."

This might not be a bad idea. Marcel's core already has a table for DAA, but Phoenix probably doesn't make use of that very often. However, we need to consider whether or not this would actually punish us more than the existing implementation - anyone know how fast/slow the Saturn RAM is?

"2) underclock the cpu a bit. I bet the game is sitting

pretty idle for most of the frame."

I'm not sure that this can really be done, because the Phoenix hardware has no interrupts. Changing IPeriod seems to have a negligible effect on speed (I tried changing it from 12000 to 10000, 4000, and 500 with no noticeable change in speed)

"3) sorry if you've already done this (i have looked at the source but i can't remember), but try to inline the read handler, by moving everything to the write handler and

making the read handler direct memory access."

There's really not much to move; the read handler only has two non-memory regions:

- controls

- DIP switches / vsync flag

Neither of these can be moved to the write handler, for obvious reasons. I guess inlining it might help. I'll see if I can make that work...
 
Try commenting out the SlSynch() call in Z80_RDMEM, I noticed a slight speed improvement without it, and as far as I've played it, nothing's broken...
 
Even if the ram is quite slow, it should stil be faster to do 1 load than all the calculations for carry & overflow which are both pretty expensive.

I'm looking at the source now, theres just a few little things i personally would want to change;

in Z80_RDMEM,

the joypad is being polled for every single call, when it could be moved inside the " else if (A >= 0x7000 && A <= 0x73FF) " bit. Plus, if the game site in idle loops polling the joypad then the Z80_RDMEM function is going to be quite expensive, so why not just poll the joypad once per frame, this is almost always often enough.

The only other thing is that if the Z80_RDMEM function is being used to fetch opcodes, it would probably be beneficial to write a separate, simpler version just for opcode & opcode operand fetches, because the software isn't going to try to fetch opcodes from the dip switch or joystick io port regions.

fools
 
That had occured to me also, but as far as I can tell, the controls just aren't getting read often enough for it to matter (tried making the read handler return a fixed byte).

I'm really starting to think that writing a new core in SuperH assembly language is the best way to go. It's not quite as bad as you might think at first glance - only a fraction of the Z80 instruction set actually needs to be implemented since, as mentioned previously, Phoenix does not actually use a Z80...
 
There are actually even less function than i tought. 8085 only uses the one byte opcodes (less than 100 diferent ones), while Z80 has the "extended" ED opcodes and all the "non-official" opcodes as well... Should be very easy to acomplish something...

And speaking of that, I sucessfully added the -O3 and -mrelax to the makefile, but it seems -mrelax adds to the file size (it should do exactly the oposite). I recomend changing -O2 to -O3 in the makefile, then :)
 
Speaking of compiler optimization, which version of GCC are you using? I'm still using cygnus-2.7-96q3 SOA-960904, and I suspect somewhat that moving to 2.95.3 or 3.0.2 might yield a performance increase, or at least more control over optimization. I'm pretty sure that any properly-compiled sh-coff-gcc will work with Saturn as long as the standard SGL Makefile is used...
 
Back
Top