rewrote file interface

This commit is contained in:
ekeeke31 2008-12-10 18:16:30 +00:00
parent 6a9974c865
commit 8ea80d38a5
48 changed files with 4616 additions and 5194 deletions

View File

@ -25,8 +25,9 @@ Genesis Plus for Gamecube
- rewrote video engine: improved horizontal scaling (VI+GX), improved rendering speed (direct texture mapping)
- removed embedded font, (re)enabled IPL font support: now should works for Qoob users too (thanks to emukiddid)
- fixed "Reset" button behavior, now acts more like Genesis Reset button ;-)
- minor bugfixes and menu tweaks
- compiled with libogc 1.7.0
- patched libfat for faster SDCARD accesses (thanks to svpe)
- various bugfixes and menu tweaks
[NGC only]
- added 480p support in menu
@ -34,7 +35,8 @@ Genesis Plus for Gamecube
[Wii only]
- implemented fast scrolling in menu using Wiimote D-PAD
- added "Power" button support
- libogc 1.7.0 features (SDHC support , Wiimote shutdown button support)
- added USB Storage support
- *new* libogc 1.7.0 features: SDHC support, Wiimote shutdown button support

View File

@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it

View File

@ -31,57 +31,58 @@ t_input input;
*****************************************************************************/
/* H counter values for a 256-pixel wide display (342 pixel max.) */
uint8 hc_256[171] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93,
0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
};
/* H counter values for a 320-pixel wide display (442 pixels max.) */
uint8 hc_320[210] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED,
0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD,
0xFE, 0xFF
};
static inline void lightgun_reset(int num)
{
input.analog[num][0] = bitmap.viewport.w >> 1;
input.analog[num][1] = bitmap.viewport.h >> 1;
input.analog[num][0] = bitmap.viewport.w >> 1;
input.analog[num][1] = bitmap.viewport.h >> 1;
}
static inline void lightgun_update(int num)
{
if ((input.analog[num][1] == v_counter + input.y_offset))
{
{
/* HL enabled ? */
if (io_reg[5] & 0x80)
{
/* External Interrupt ? */
if (reg[11] & 0x08) {irq_status &= 0xff; irq_status |= 0x12;}
/* HVC Latch:
1) some games does not set HVC latch but instead use bigger X offset
2) for games using H40 mode, the gun routine scales up the Hcounter value,
/* HVC Latch:
1) some games does not set HVC latch but instead use bigger X offset
2) for games using H40 mode, the gun routine scales up the Hcounter value,
H-Counter range is approx. 292 pixel clocks
*/
hc_latch = 0x100;
@ -90,19 +91,19 @@ static inline void lightgun_update(int num)
else
hc_latch |= hc_256[(input.analog[num][0] / 2 + input.x_offset)%171];
}
}
}
}
}
}
/* Sega Menacer specific */
uint32 menacer_read()
{
/* pins should return 0 by default (fix Body Count when mouse is enabled) */
int retval = 0x00;
if (input.pad[4] & INPUT_B) retval |= 0x01;
if (input.pad[4] & INPUT_A) retval |= 0x02;
if (input.pad[4] & INPUT_B) retval |= 0x01;
if (input.pad[4] & INPUT_A) retval |= 0x02;
if (input.pad[4] & INPUT_C) retval |= 0x04;
if (input.pad[4] & INPUT_START) retval |= 0x08;
if (input.pad[4] & INPUT_START) retval |= 0x08;
return retval;
}
@ -130,8 +131,8 @@ uint32 justifier_read()
return retval;
default: /* guns disabled */
return retval;
}
return retval;
}
}
/*****************************************************************************
@ -148,8 +149,8 @@ struct mega_mouse
static inline void mouse_reset()
{
mouse.State = 0x60;
mouse.Counter = 0;
mouse.State = 0x60;
mouse.Counter = 0;
mouse.Wait = 0;
mouse.Port = (input.system[0] == SYSTEM_MOUSE) ? 0 : 4;
}
@ -267,19 +268,19 @@ struct pad
static inline void gamepad_raz(uint32 i)
{
gamepad[i].Counter = 0;
gamepad[i].Delay = 0;
gamepad[i].Counter = 0;
gamepad[i].Delay = 0;
}
static inline void gamepad_reset(uint32 i)
{
gamepad[i].State = 0x40;
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
gamepad[i].State = 0x40;
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
}
static inline void gamepad_update(uint32 i)
{
if (gamepad[i].Delay++ > 25) gamepad_raz(i);
if (gamepad[i].Delay++ > 25) gamepad_raz(i);
}
static inline uint32 gamepad_read(uint32 i)
@ -288,10 +289,10 @@ static inline uint32 gamepad_read(uint32 i)
int retval = 0x7F;
control = (gamepad[i].State & 0x40) >> 6; /* current TH state */
if (input.dev[i] == DEVICE_6BUTTON)
{
control += (gamepad[i].Counter & 3) << 1; /* TH transitions counter */
control += (gamepad[i].Counter & 3) << 1; /* TH transitions counter */
}
switch (control)
@ -299,7 +300,7 @@ static inline uint32 gamepad_read(uint32 i)
case 1: /*** First High ***/
case 3: /*** Second High ***/
case 5: /*** Third High ***/
/* TH = 1 : ?1CBRLDU */
if (input.pad[i] & INPUT_C) retval &= ~0x20;
if (input.pad[i] & INPUT_B) retval &= ~0x10;
@ -311,7 +312,7 @@ static inline uint32 gamepad_read(uint32 i)
case 0: /*** First low ***/
case 2: /*** Second low ***/
/* TH = 0 : ?0SA00DU */
if (input.pad[i] & INPUT_A) retval &= ~0x10;
if (input.pad[i] & INPUT_START) retval &= ~0x20;
@ -333,7 +334,7 @@ static inline uint32 gamepad_read(uint32 i)
TH = 0 : ?0SA1111 D3-0 are forced to '1'
*/
case 4: /*** Third Low ***/
/* TH = 0 : ?0SA0000 D3-0 are forced to '0'*/
if (input.pad[i] & INPUT_A) retval &= ~0x10;
if (input.pad[i] & INPUT_START) retval &= ~0x20;
@ -341,7 +342,7 @@ static inline uint32 gamepad_read(uint32 i)
break;
case 6: /*** Fourth Low ***/
/* TH = 0 : ?0SA1111 D3-0 are forced to '1'*/
if (input.pad[i] & INPUT_A) retval &= ~0x10;
if (input.pad[i] & INPUT_START) retval &= ~0x20;
@ -349,7 +350,7 @@ static inline uint32 gamepad_read(uint32 i)
break;
case 7: /*** Fourth High ***/
/* TH = 1 : ?1CBMXYZ Extra buttons returned in D3-0*/
if (input.pad[i] & INPUT_X) retval &= ~0x04;
if (input.pad[i] & INPUT_Y) retval &= ~0x02;
@ -360,7 +361,7 @@ static inline uint32 gamepad_read(uint32 i)
break;
default:
break;
break;
}
/* bit7 is latched */
@ -371,12 +372,12 @@ static inline void gamepad_write(uint32 i, uint32 data)
{
if (input.dev[i] == DEVICE_6BUTTON)
{
/* TH=0 to TH=1 transition */
if (!(gamepad[i].State & 0x40) && (data & 0x40))
{
gamepad[i].Counter++;
gamepad[i].Delay = 0;
}
/* TH=0 to TH=1 transition */
if (!(gamepad[i].State & 0x40) && (data & 0x40))
{
gamepad[i].Counter++;
gamepad[i].Delay = 0;
}
}
gamepad[i].State = data;
@ -396,85 +397,85 @@ struct teamplayer
static inline void teamplayer_reset(uint32 port)
{
int i;
int index = 0;
int pad_input = 0;
int i;
int index = 0;
int pad_input = 0;
teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */
teamplayer[port].Counter = 0;
teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */
teamplayer[port].Counter = 0;
/* this table determines which gamepad input should be returned during acquisition sequence
index = teamplayer read table index: 0=1st read, 1=2nd read, ...
pad_input = gamepad input 0-14: 0=P1_DIR, 1=P1_SABC, 2=P1_MXYZ, 4=P2_DIR, 5=P2_SABC, ...
*/
for (i=0; i<4; i++)
{
if (input.dev[(4*port) + i] == DEVICE_3BUTTON)
{
teamplayer[port].Table[index++] = pad_input;
teamplayer[port].Table[index++] = pad_input + 1;
}
else if (input.dev[(4*port) + i] == DEVICE_6BUTTON)
{
teamplayer[port].Table[index++] = pad_input;
teamplayer[port].Table[index++] = pad_input + 1;
teamplayer[port].Table[index++] = pad_input + 2;
}
pad_input += 4;
}
/* this table determines which gamepad input should be returned during acquisition sequence
index = teamplayer read table index: 0=1st read, 1=2nd read, ...
pad_input = gamepad input 0-14: 0=P1_DIR, 1=P1_SABC, 2=P1_MXYZ, 4=P2_DIR, 5=P2_SABC, ...
*/
for (i=0; i<4; i++)
{
if (input.dev[(4*port) + i] == DEVICE_3BUTTON)
{
teamplayer[port].Table[index++] = pad_input;
teamplayer[port].Table[index++] = pad_input + 1;
}
else if (input.dev[(4*port) + i] == DEVICE_6BUTTON)
{
teamplayer[port].Table[index++] = pad_input;
teamplayer[port].Table[index++] = pad_input + 1;
teamplayer[port].Table[index++] = pad_input + 2;
}
pad_input += 4;
}
}
/* SEGA teamplayer returns successively:
- PAD1 inputs
- PAD2 inputs
- PAD3 inputs
- PAD4 inputs
- PAD2 inputs
- PAD3 inputs
- PAD4 inputs
Each PAD inputs is obtained through 2 or 3 sequential reads:
1/ DIR buttons
2/ START,A,C,B buttons
3/ MODE, X,Y,Z buttons (6Button only !)
2/ START,A,C,B buttons
3/ MODE, X,Y,Z buttons (6Button only !)
*/
static inline uint32 teamplayer_read_device(uint32 port, uint32 index)
{
int retval = 0x7F;
int pad_input = teamplayer[port].Table[index] & 0x03;
int pad_num = (4 * port) + ((teamplayer[port].Table[index] >> 2) & 0x03);
switch (pad_input)
{
case 0:
/* Directions Buttons */
if (input.pad[pad_num] & INPUT_UP) retval &= ~0x01;
if (input.pad[pad_num] & INPUT_DOWN) retval &= ~0x02;
if (input.pad[pad_num] & INPUT_LEFT) retval &= ~0x04;
if (input.pad[pad_num] & INPUT_RIGHT) retval &= ~0x08;
break;
case 1:
/* S,A,C,B Buttons */
if (input.pad[pad_num] & INPUT_B) retval &= ~0x01;
if (input.pad[pad_num] & INPUT_C) retval &= ~0x02;
if (input.pad[pad_num] & INPUT_A) retval &= ~0x04;
if (input.pad[pad_num] & INPUT_START) retval &= ~0x08;
break;
int retval = 0x7F;
int pad_input = teamplayer[port].Table[index] & 0x03;
int pad_num = (4 * port) + ((teamplayer[port].Table[index] >> 2) & 0x03);
case 2:
/* M,X,Y,Z Buttons (6-Buttons only)*/
if (input.pad[pad_num] & INPUT_Z) retval &= ~0x01;
if (input.pad[pad_num] & INPUT_Y) retval &= ~0x02;
if (input.pad[pad_num] & INPUT_X) retval &= ~0x04;
if (input.pad[pad_num] & INPUT_MODE) retval &= ~0x08;
break;
}
switch (pad_input)
{
case 0:
/* Directions Buttons */
if (input.pad[pad_num] & INPUT_UP) retval &= ~0x01;
if (input.pad[pad_num] & INPUT_DOWN) retval &= ~0x02;
if (input.pad[pad_num] & INPUT_LEFT) retval &= ~0x04;
if (input.pad[pad_num] & INPUT_RIGHT) retval &= ~0x08;
break;
return retval;
case 1:
/* S,A,C,B Buttons */
if (input.pad[pad_num] & INPUT_B) retval &= ~0x01;
if (input.pad[pad_num] & INPUT_C) retval &= ~0x02;
if (input.pad[pad_num] & INPUT_A) retval &= ~0x04;
if (input.pad[pad_num] & INPUT_START) retval &= ~0x08;
break;
case 2:
/* M,X,Y,Z Buttons (6-Buttons only)*/
if (input.pad[pad_num] & INPUT_Z) retval &= ~0x01;
if (input.pad[pad_num] & INPUT_Y) retval &= ~0x02;
if (input.pad[pad_num] & INPUT_X) retval &= ~0x04;
if (input.pad[pad_num] & INPUT_MODE) retval &= ~0x08;
break;
}
return retval;
}
static inline uint32 teamplayer_read(uint32 port)
{
int retval = 0x7F;
int padnum;
int retval = 0x7F;
int padnum;
switch (teamplayer[port].Counter) /* acquisition sequence steps */
{
@ -490,7 +491,7 @@ static inline uint32 teamplayer_read(uint32 port)
case 3: /* ack request: TH=0, TR handshake */
retval = 0x00;
break;
case 4:
case 5:
case 6:
@ -498,16 +499,16 @@ static inline uint32 teamplayer_read(uint32 port)
padnum = (4 * port) + teamplayer[port].Counter - 4;
retval = input.dev[padnum];
break;
default: /* gamepads inputs acquisition */
retval = teamplayer_read_device(port, teamplayer[port].Counter - 8);
break;
}
/* TL must match TR state */
retval &= ~0x10;
if (teamplayer[port].State & 0x20) retval |= 0x10;
return retval;
}
@ -517,7 +518,7 @@ static inline void teamplayer_write(uint32 port, uint32 data)
teamplayer[port].State = (data & io_reg[port+4]) | (teamplayer[port].State & ~io_reg[port+4]);
if (old_state != teamplayer[port].State) teamplayer[port].Counter ++;
if ((data&0x60) == 0x60) teamplayer[port].Counter = 0;
}
}
/*****************************************************************************
* 4WAYPLAY adapter
@ -531,7 +532,7 @@ static inline void wayplay_write(uint32 port, uint32 data)
static inline uint32 wayplay_read(uint32 port)
{
if (port == 1) return 0x7F;
if (port == 1) return 0x7F;
if (input.current >= 4) return 0x70; /* multitap detection (TH2 = 1) */
return gamepad_read(input.current); /* 0x0C = Pad1, 0x1C = Pad2, ... */
}
@ -563,54 +564,54 @@ void gamepad_2_write (uint32 data)
uint32 wayplay_1_read (void)
{
return wayplay_read(0);
return wayplay_read(0);
}
uint32 wayplay_2_read (void)
{
return wayplay_read(1);
return wayplay_read(1);
}
void wayplay_1_write (uint32 data)
{
wayplay_write(0, data);
wayplay_write(0, data);
}
void wayplay_2_write (uint32 data)
{
wayplay_write(1, data);
wayplay_write(1, data);
}
uint32 teamplayer_1_read (void)
{
return teamplayer_read(0);
return teamplayer_read(0);
}
uint32 teamplayer_2_read (void)
{
return teamplayer_read(1);
return teamplayer_read(1);
}
void teamplayer_1_write (uint32 data)
{
teamplayer_write(0, data);
teamplayer_write(0, data);
}
void teamplayer_2_write (uint32 data)
{
teamplayer_write(1, data);
teamplayer_write(1, data);
}
uint32 jcart_read(uint32 address)
{
return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 (is it correct ?) */
return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 (is it correct ?) */
}
void jcart_write(uint32 address, uint32 data)
{
gamepad_write(5, (data&1) << 6);
gamepad_write(6, (data&1) << 6);
return;
gamepad_write(5, (data&1) << 6);
gamepad_write(6, (data&1) << 6);
return;
}
/*****************************************************************************
@ -619,16 +620,16 @@ void jcart_write(uint32 address, uint32 data)
*****************************************************************************/
void input_reset ()
{
int i,j;
input.max = 0;
int i,j;
input.max = 0;
input.current = 0;
for (i=0; i<MAX_DEVICES; i++)
{
input.dev[i] = NO_DEVICE;
input.pad[i] = 0;
}
for (i=0; i<MAX_DEVICES; i++)
{
input.dev[i] = NO_DEVICE;
input.pad[i] = 0;
}
for (i=0; i<2; i++)
{
@ -640,8 +641,8 @@ void input_reset ()
input.max ++;
gamepad_reset(i*4);
break;
case SYSTEM_MOUSE:
case SYSTEM_MOUSE:
if (input.max == MAX_INPUTS) return;
input.dev[i*4] = DEVICE_MOUSE;
input.max ++;
@ -687,70 +688,70 @@ void input_reset ()
}
/* J-CART: add two gamepad inputs */
if (j_cart)
{
input.dev[5] = input.padtype[2];
input.dev[6] = input.padtype[3];
gamepad_reset(5);
gamepad_reset(6);
}
if (j_cart)
{
input.dev[5] = input.padtype[2];
input.dev[6] = input.padtype[3];
gamepad_reset(5);
gamepad_reset(6);
}
}
void input_update()
{
int i;
switch (input.system[0])
{
case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0);
break;
case SYSTEM_WAYPLAY:
for (i=0; i<4; i++)
{
if (input.dev[i] == DEVICE_6BUTTON) gamepad_update(i);
}
break;
}
switch (input.system[1])
{
case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_update(4);
break;
int i;
switch (input.system[0])
{
case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0);
break;
case SYSTEM_MENACER:
lightgun_update(0);
break;
case SYSTEM_WAYPLAY:
for (i=0; i<4; i++)
{
if (input.dev[i] == DEVICE_6BUTTON) gamepad_update(i);
}
break;
}
switch (input.system[1])
{
case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_update(4);
break;
case SYSTEM_MENACER:
lightgun_update(0);
break;
case SYSTEM_JUSTIFIER:
if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0);
if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1);
break;
}
if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0);
if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1);
break;
}
}
void input_raz()
{
int i;
switch (input.system[0])
{
case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0);
break;
case SYSTEM_WAYPLAY:
for (i=0; i<4; i++)
{
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
}
break;
}
switch (input.system[1])
{
case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4);
break;
}
int i;
switch (input.system[0])
{
case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0);
break;
case SYSTEM_WAYPLAY:
for (i=0; i<4; i++)
{
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
}
break;
}
switch (input.system[1])
{
case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4);
break;
}
}

View File

@ -28,12 +28,12 @@
#define MAX_DEVICES (8)
/* Device types */
#define DEVICE_3BUTTON (0x00) /* 3-button gamepad */
#define DEVICE_6BUTTON (0x01) /* 6-button gamepad */
#define DEVICE_LIGHTGUN (0x02) /* Sega Menacer or Konami Justifier */
#define DEVICE_MOUSE (0x03) /* Sega Mouse */
#define DEVICE_2BUTTON (0x04) /* 2-button gamepad (not supported) */
#define NO_DEVICE (0x0F) /* unconnected */
#define DEVICE_3BUTTON (0x00) /* 3-button gamepad */
#define DEVICE_6BUTTON (0x01) /* 6-button gamepad */
#define DEVICE_LIGHTGUN (0x02) /* Sega Menacer or Konami Justifier */
#define DEVICE_MOUSE (0x03) /* Sega Mouse */
#define DEVICE_2BUTTON (0x04) /* 2-button gamepad (not supported) */
#define NO_DEVICE (0x0F) /* unconnected */
/* Input bitmasks */
#define INPUT_MODE (0x00000800)
@ -53,10 +53,10 @@
#define NO_SYSTEM (0) /* Unconnected Port*/
#define SYSTEM_MOUSE (1) /* Sega Mouse */
#define SYSTEM_GAMEPAD (2) /* Single Gamepad */
#define SYSTEM_MENACER (3) /* Sega Menacer (port 2) */
#define SYSTEM_JUSTIFIER (4) /* Konami Justifier (port 2) */
#define SYSTEM_TEAMPLAYER (5) /* Sega TeamPlayer */
#define SYSTEM_WAYPLAY (6) /* EA 4-Way Play (use both ports) */
#define SYSTEM_MENACER (3) /* Sega Menacer (port 2) */
#define SYSTEM_JUSTIFIER (4) /* Konami Justifier (port 2) */
#define SYSTEM_TEAMPLAYER (5) /* Sega TeamPlayer */
#define SYSTEM_WAYPLAY (6) /* EA 4-Way Play (use both ports) */
/* Players Inputs */
#define PLAYER_1A (0)
@ -76,7 +76,7 @@ typedef struct
uint8 system[2]; /* Can be any of the SYSTEM_* bitmasks */
uint8 max; /* maximum number of connected devices */
uint8 current; /* current PAD number (4WAYPLAY) */
int analog[3][2]; /* analog devices */
int analog[3][2]; /* analog devices */
int x_offset;
int y_offset;
} t_input;

View File

@ -28,12 +28,12 @@ uint8 region_code = REGION_USA;
/*****************************************************************************
* I/O chip functions *
* *
* *
*****************************************************************************/
struct port_t
{
void (*data_w)(unsigned int data);
unsigned int (*data_r)(void);
void (*data_w)(uint32 data);
uint32 (*data_r)(void);
} port[3];
void io_reset(void)
@ -41,12 +41,12 @@ void io_reset(void)
/* I/O register default settings */
uint8 io_def[0x10] =
{
0xA0,
0x7F, 0x7F, 0x7F,
0x00, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFB, 0x00, 0x00,
0xA0,
0x7F, 0x7F, 0x7F,
0x00, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFB, 0x00, 0x00,
};
/* Initialize I/O registers */
@ -66,20 +66,20 @@ void io_reset(void)
break;
case SYSTEM_WAYPLAY:
port[0].data_w = wayplay_1_write;
port[0].data_r = wayplay_1_read;
break;
port[0].data_w = wayplay_1_write;
port[0].data_r = wayplay_1_read;
break;
case SYSTEM_TEAMPLAYER:
port[0].data_w = teamplayer_1_write;
port[0].data_r = teamplayer_1_read;
break;
port[0].data_w = teamplayer_1_write;
port[0].data_r = teamplayer_1_read;
break;
default:
default:
port[0].data_w = NULL;
port[0].data_r = NULL;
break;
}
}
switch (input.system[1])
{
@ -104,20 +104,20 @@ void io_reset(void)
break;
case SYSTEM_WAYPLAY:
port[1].data_w = wayplay_2_write;
port[1].data_r = wayplay_2_read;
break;
port[1].data_w = wayplay_2_write;
port[1].data_r = wayplay_2_read;
break;
case SYSTEM_TEAMPLAYER:
port[1].data_w = teamplayer_2_write;
port[1].data_r = teamplayer_2_read;
break;
port[1].data_w = teamplayer_2_write;
port[1].data_r = teamplayer_2_read;
break;
default:
default:
port[1].data_w = NULL;
port[1].data_r = NULL;
break;
}
}
/* External Port (unconnected) */
port[2].data_w = NULL;
@ -127,7 +127,7 @@ void io_reset(void)
input_reset();
}
void io_write(unsigned int offset, unsigned int value)
void io_write(uint32 offset, uint32 value)
{
switch (offset)
{
@ -138,7 +138,7 @@ void io_write(unsigned int offset, unsigned int value)
if(port[offset-1].data_w) port[offset-1].data_w(value);
return;
case 0x05: /* Port B Ctrl */
case 0x05: /* Port B Ctrl */
if (((value & 0x7F) == 0x7F) &&
((input.system[0] == SYSTEM_TEAMPLAYER) ||
(input.system[1] == SYSTEM_TEAMPLAYER)))
@ -153,47 +153,47 @@ void io_write(unsigned int offset, unsigned int value)
input_reset();
}
case 0x04: /* Port A Ctrl */
case 0x06: /* Port C Ctrl */
case 0x04: /* Port A Ctrl */
case 0x06: /* Port C Ctrl */
io_reg[offset] = value & 0xFF;
io_reg[offset-3] = ((io_reg[offset-3] & 0x80) | (io_reg[offset-3] & io_reg[offset]));
return;
case 0x07: /* Port A TxData */
case 0x0A: /* Port B TxData */
case 0x0D: /* Port C TxData */
case 0x07: /* Port A TxData */
case 0x0A: /* Port B TxData */
case 0x0D: /* Port C TxData */
io_reg[offset] = value;
return;
case 0x09: /* Port A S-Ctrl */
case 0x0C: /* Port B S-Ctrl */
case 0x0F: /* Port C S-Ctrl */
case 0x09: /* Port A S-Ctrl */
case 0x0C: /* Port B S-Ctrl */
case 0x0F: /* Port C S-Ctrl */
io_reg[offset] = (value & 0xF8);
return;
}
}
unsigned int io_read(unsigned int offset)
uint32 io_read(uint32 offset)
{
switch(offset)
{
case 0x00: /* Version register */
{
uint8 has_scd = 0x20; /* No Sega CD unit attached */
uint8 gen_ver = (config.bios_enabled == 3) ? 0x01 : 0x00; /* hardware version */
{
uint8 has_scd = 0x20; /* No Sega CD unit attached */
uint8 gen_ver = (config.bios_enabled == 3) ? 0x01 : 0x00; /* hardware version */
return (region_code | has_scd | gen_ver);
}
}
case 0x01: /* Port A Data */
case 0x02: /* Port B Data */
case 0x03: /* Port C Data */
{
uint8 input = 0x7F; /* default input state */
case 0x03: /* Port C Data */
{
uint8 input = 0x7F; /* default input state */
if(port[offset-1].data_r) input = port[offset-1].data_r();
return (io_reg[offset] | ((~io_reg[offset+3]) & input));
}
return (io_reg[offset] | ((~io_reg[offset+3]) & input));
}
default:
return (io_reg[offset]);
}
default:
return (io_reg[offset]);
}
}

View File

@ -24,10 +24,10 @@
#ifndef _GEN_IO_H_
#define _GEN_IO_H_
#define REGION_USA 0x80
#define REGION_JAPAN_NTSC 0x00
#define REGION_EUROPE 0xC0
#define REGION_JAPAN_PAL 0x40
#define REGION_JAPAN_NTSC 0x00
#define REGION_JAPAN_PAL 0x40
#define REGION_USA 0x80
#define REGION_EUROPE 0xC0
/* Global variables */
extern uint8 io_reg[0x10];
@ -36,8 +36,8 @@ extern uint8 pad_type;
/* Function prototypes */
extern void io_reset(void);
extern void io_write(unsigned int offset, unsigned int value);
extern unsigned int io_read(unsigned int offset);
extern void io_write(uint32 offset, uint32 value);
extern uint32 io_read(uint32 offset);
#endif /* _IO_H_ */

View File

@ -23,62 +23,61 @@
#include "shared.h"
uint8 *cart_rom; /* cart_rom NEED to be previously dynamically allocated */
uint8 bios_rom[0x10000];
uint8 *cart_rom; /* CART rom */
uint8 bios_rom[0x10000]; /* BIOS rom */
uint8 work_ram[0x10000]; /* 68K work RAM */
uint8 zram[0x2000]; /* Z80 work RAM */
uint8 zbusreq; /* /BUSREQ from Z80 */
uint8 zreset; /* /RESET to Z80 */
uint8 zbusack; /* /BUSACK to Z80 */
uint8 zirq; /* /IRQ to Z80 */
uint32 zbank; /* Address of Z80 bank window */
uint8 zram[0x2000]; /* Z80 work RAM */
uint8 zbusreq; /* /BUSREQ from Z80 */
uint8 zreset; /* /RESET to Z80 */
uint8 zbusack; /* /BUSACK to Z80 */
uint8 zirq; /* /IRQ to Z80 */
uint32 zbank; /* Address of Z80 bank window */
uint8 gen_running;
uint32 genromsize;
int32 resetline;
/*--------------------------------------------------------------------------*/
/* Init, reset, shutdown functions */
/*--------------------------------------------------------------------------*/
void set_softreset(void)
{
resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0));
resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0));
}
void gen_init (void)
{
int i;
int i;
/* initialize CPUs */
m68k_set_cpu_type (M68K_CPU_TYPE_68000);
m68k_init();
z80_init(0,0,0,z80_irq_callback);
/* initialize CPUs */
m68k_set_cpu_type (M68K_CPU_TYPE_68000);
m68k_init();
z80_init(0,0,0,z80_irq_callback);
/* initialize 68k default address space */
for (i=0x0; i<0x100; i++)
{
{
m68k_memory_map[i].base = work_ram;
m68k_memory_map[i].read8 = NULL;
m68k_memory_map[i].read16 = NULL;
m68k_memory_map[i].write8 = NULL;
m68k_memory_map[i].write16 = NULL;
m68k_memory_map[i].write16 = NULL;
zbank_memory_map[i].read = NULL;
zbank_memory_map[i].write = NULL;
}
/* initialize 68k memory map */
for (i=0x80; i<0xe0; i++)
{
/* illegal area */
for (i=0x80; i<0xe0; i++)
{
/* illegal area */
m68k_memory_map[i].read8 = m68k_lockup_r_8;
m68k_memory_map[i].read16 = m68k_lockup_r_16;
m68k_memory_map[i].write8 = m68k_lockup_w_8;
m68k_memory_map[i].write16 = m68k_lockup_w_16;
m68k_memory_map[i].write16 = m68k_lockup_w_16;
zbank_memory_map[i].read = zbank_lockup_r;
zbank_memory_map[i].write = zbank_lockup_w;
}
}
/* Z80 bus */
/* Z80 bus */
m68k_memory_map[0xa0].read8 = z80_read_byte;
m68k_memory_map[0xa0].read16 = z80_read_word;
m68k_memory_map[0xa0].write8 = z80_write_byte;
@ -86,7 +85,7 @@ void gen_init (void)
zbank_memory_map[0xa0].read = zbank_lockup_r;
zbank_memory_map[0xa0].write = zbank_lockup_w;
/* I/O & Control registers */
/* I/O & Control registers */
m68k_memory_map[0xa1].read8 = ctrl_io_read_byte;
m68k_memory_map[0xa1].read16 = ctrl_io_read_word;
m68k_memory_map[0xa1].write8 = ctrl_io_write_byte;
@ -102,7 +101,7 @@ void gen_init (void)
m68k_memory_map[0x80].write8 = m68k_unused_8_w;
m68k_memory_map[0x80].write16 = m68k_unused_16_w;
/* there is no I/O area (Notaz) */
/* there is no I/O area (Notaz) */
m68k_memory_map[0xa0].read8 = m68k_read_bus_8;
m68k_memory_map[0xa0].read16 = m68k_read_bus_16;
m68k_memory_map[0xa0].write8 = m68k_unused_8_w;
@ -113,7 +112,7 @@ void gen_init (void)
m68k_memory_map[0xa1].write16 = m68k_unused_16_w;
}
/* VDP */
/* VDP */
m68k_memory_map[0xc0].read8 = vdp_read_byte;
m68k_memory_map[0xc0].read16 = vdp_read_word;
m68k_memory_map[0xc0].write8 = vdp_write_byte;
@ -142,38 +141,37 @@ void gen_init (void)
void gen_reset (uint32 hard_reset)
{
if (hard_reset)
{
/* Clear RAM */
memset (work_ram, 0x00, sizeof (work_ram));
memset (zram, 0x00, sizeof (zram));
if (hard_reset)
{
/* Clear RAM */
memset (work_ram, 0x00, sizeof (work_ram));
memset (zram, 0x00, sizeof (zram));
/* TMSS BIOS */
/* TMSS BIOS */
if (config.bios_enabled == 3)
{
m68k_memory_map[0].base = bios_rom;
}
}
}
gen_running = 1;
resetline = -1;
gen_running = 1;
resetline = -1;
zreset = 0; /* Z80 is reset */
zbusreq = 0; /* Z80 has control of the Z bus */
zbusack = 1; /* Z80 is busy using the Z bus */
zirq = 0; /* No interrupts occuring */
zbank = 0; /* Assume default bank is 000000-007FFF */
zreset = 0; /* Z80 is reset */
zbusreq = 0; /* Z80 has control of the Z bus */
zbusack = 1; /* Z80 is busy using the Z bus */
zirq = 0; /* No interrupts occuring */
zbank = 0; /* Assume default bank is 000000-007FFF */
/* Reset CPUs */
m68k_pulse_reset ();
z80_reset ();
_YM2612_Reset();
/* Reset CPUs */
m68k_pulse_reset ();
z80_reset ();
_YM2612_Reset();
#ifdef NGC
/* register SOFTRESET */
SYS_SetResetCallback(set_softreset);
#endif
}
void gen_shutdown (void)
@ -185,86 +183,86 @@ void gen_shutdown (void)
-----------------------------------------------------------------------*/
void gen_busreq_w (uint32 state)
{
uint32 z80_cycles_to_run;
uint32 z80_cycles_to_run;
input_raz (); /* from Gens */
if (state)
{
/* Bus Request */
if (!zbusreq && zreset)
{
/* Z80 stopped */
/* z80 was ON during the last 68k cycles */
/* we execute the appropriate number of z80 cycles */
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
input_raz (); /* from Gens */
if (state)
{
/* Bus Request */
if (!zbusreq && zreset)
{
/* Z80 stopped */
/* z80 was ON during the last 68k cycles */
/* we execute the appropriate number of z80 cycles */
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
current_z80 = z80_cycles_to_run - count_z80;
if (current_z80 > 0) count_z80 += z80_execute(current_z80);
}
}
else
{
/* Bus released */
if (zbusreq && zreset)
{
/* Z80 started */
/* z80 was OFF during the last 68k cycles */
/* we burn the appropriate number of z80 cycles */
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
count_z80 = z80_cycles_to_run;
}
}
}
}
else
{
/* Bus released */
if (zbusreq && zreset)
{
/* Z80 started */
/* z80 was OFF during the last 68k cycles */
/* we burn the appropriate number of z80 cycles */
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
count_z80 = z80_cycles_to_run;
}
}
zbusreq = state;
zbusack = 1 ^ (zbusreq & zreset);
zbusreq = state;
zbusack = 1 ^ (zbusreq & zreset);
}
void gen_reset_w (uint32 state)
{
uint32 z80_cycles_to_run;
uint32 z80_cycles_to_run;
if (state)
{
/* stop RESET process */
if (!zbusreq && !zreset)
{
/* Z80 started */
/* z80 was OFF during the last 68k cycles */
/* we burn the appropriate number of z80 cycles */
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
count_z80 = z80_cycles_to_run;
}
}
else
{
/* start RESET process */
if (!zbusreq && zreset)
{
/* Z80 stopped */
/* z80 was ON during the last 68k cycles */
/* we execute the appropriate number of z80 cycles */
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
if (state)
{
/* stop RESET process */
if (!zbusreq && !zreset)
{
/* Z80 started */
/* z80 was OFF during the last 68k cycles */
/* we burn the appropriate number of z80 cycles */
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
count_z80 = z80_cycles_to_run;
}
}
else
{
/* start RESET process */
if (!zbusreq && zreset)
{
/* Z80 stopped */
/* z80 was ON during the last 68k cycles */
/* we execute the appropriate number of z80 cycles */
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
current_z80 = z80_cycles_to_run - count_z80;
if (current_z80 > 0) count_z80 += z80_execute(current_z80);
}
}
/* Reset Z80 & YM2612 */
_YM2612_Reset();
z80_reset ();
}
/* Reset Z80 & YM2612 */
_YM2612_Reset();
z80_reset ();
}
zreset = state;
zbusack = 1 ^ (zbusreq & zreset);
zreset = state;
zbusack = 1 ^ (zbusreq & zreset);
}
void gen_bank_w (uint32 state)
{
zbank = ((zbank >> 1) | ((state & 1) << 23)) & 0xFF8000;
zbank = ((zbank >> 1) | ((state & 1) << 23)) & 0xFF8000;
}
int z80_irq_callback (int param)
{
zirq = 0;
z80_set_irq_line (0, CLEAR_LINE);
return 0xFF;
zirq = 0;
z80_set_irq_line (0, CLEAR_LINE);
return 0xFF;
}

View File

@ -125,41 +125,41 @@
/* V counter values for NTSC 192-line display */
uint8 vc_ntsc_192[262] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
};
/* V counter values for NTSC 224-line display */
uint8 vc_ntsc_224[262] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
@ -167,20 +167,20 @@ uint8 vc_ntsc_224[262] = {
/* V counter values for NTSC 240-line display (invalid mode) */
uint8 vc_ntsc_240[262] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
@ -188,20 +188,20 @@ uint8 vc_ntsc_240[262] = {
/* V counter values for PAL 192-line display */
uint8 vc_pal_192[313] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2,
0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6,
@ -213,20 +213,20 @@ uint8 vc_pal_192[313] = {
/* V counter values for PAL 224-line display */
uint8 vc_pal_224[313] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02,
@ -238,20 +238,20 @@ uint8 vc_pal_224[313] = {
/* V counter values for PAL 240-line display */
uint8 vc_pal_240[313] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
@ -340,7 +340,7 @@ uint8 cycle2hc32[488] = {
0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8A, 0x8A, 0x8A,
0x8B, 0x8B, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8D, 0x8E, 0x8E, 0x8E, 0x8F, 0x8F, 0x8F, 0x90, 0x90,
0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x93, 0x93,
0xE9, 0xE9, 0xE9, 0xEA, 0xEA, 0xEA,
0xE9, 0xE9, 0xE9, 0xEA, 0xEA, 0xEA,
0xEB, 0xEB, 0xEB, 0xEC, 0xEC, 0xEC, 0xED, 0xED, 0xED, 0xEE, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0, 0xF0,
0xF0, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, 0xF2, 0xF3, 0xF3, 0xF3, 0xF4, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6,
0xF6, 0xF6, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF8, 0xF9, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB,
@ -372,9 +372,9 @@ uint8 cycle2hc32[488] = {
};
uint8 cycle2hc40[488] = {
0xA4, 0xA5, 0xA5, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA8, 0xA8, 0xA9, 0xA9, 0xAA, 0xAA,
0xAA, 0xAB, 0xAB, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAF, 0xAF, 0xB0, 0xB0, 0xB1, 0xB1,
0xB1, 0xB2, 0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6,
0xA4, 0xA5, 0xA5, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA8, 0xA8, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAB,
0xAB, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAF, 0xAF, 0xB0, 0xB0, 0xB1, 0xB1, 0xB1, 0xB2,
0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6,
0xE4, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6, 0xE6,
0xE7, 0xE7, 0xE7, 0xE8, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED,
0xEE, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4,
@ -406,7 +406,6 @@ uint8 cycle2hc40[488] = {
0xA1, 0xA2, 0xA2, 0xA3, 0xA3, 0xA4, 0xA4,
};
uint8 *vctab;
uint8 *hctab;

View File

@ -25,48 +25,48 @@
#include "shared.h"
/*** ROM Information ***/
#define ROMCONSOLE 256
#define ROMCOPYRIGHT 272
#define ROMDOMESTIC 288
#define ROMWORLD 336
#define ROMTYPE 384
#define ROMPRODUCT 386
#define ROMCHECKSUM 398
#define ROMIOSUPPORT 400
#define ROMROMSTART 416
#define ROMROMEND 420
#define ROMRAMINFO 424
#define ROMRAMSTART 436
#define ROMRAMEND 440
#define ROMMODEMINFO 444
#define ROMMEMO 456
#define ROMCOUNTRY 496
#define ROMCONSOLE 256
#define ROMCOPYRIGHT 272
#define ROMDOMESTIC 288
#define ROMWORLD 336
#define ROMTYPE 384
#define ROMPRODUCT 386
#define ROMCHECKSUM 398
#define ROMIOSUPPORT 400
#define ROMROMSTART 416
#define ROMROMEND 420
#define ROMRAMINFO 424
#define ROMRAMSTART 436
#define ROMRAMEND 440
#define ROMMODEMINFO 444
#define ROMMEMO 456
#define ROMCOUNTRY 496
#define P3BUTTONS 1
#define P6BUTTONS 2
#define PKEYBOARD 4
#define PPRINTER 8
#define PBALL 16
#define PFLOPPY 32
#define PACTIVATOR 64
#define P3BUTTONS 1
#define P6BUTTONS 2
#define PKEYBOARD 4
#define PPRINTER 8
#define PBALL 16
#define PFLOPPY 32
#define PACTIVATOR 64
#define PTEAMPLAYER 128
#define PMSYSTEMPAD 256
#define PSERIAL 512
#define PTABLET 1024
#define PPADDLE 2048
#define PCDROM 4096
#define PMOUSE 8192
#define PTABLET 1024
#define PPADDLE 2048
#define PCDROM 4096
#define PMOUSE 8192
int peripherals;
uint16 realchecksum;
ROMINFO rominfo;
/***************************************************************************
/***************************************************************************
* Genesis ROM Manufacturers
*
* Based on the document provided at
* http://www.zophar.net/tech/files/Genesis_ROM_Format.txt
***************************************************************************/
**************************************************************************/
COMPANYINFO companyinfo[MAXCOMPANY] = {
{"ACLD", "Ballistic"},
{"RSI", "Razorsoft"},
@ -186,35 +186,35 @@ uint16 GetRealChecksum (uint8 *rom, int length)
****************************************************************************/
int getcompany ()
{
char *s;
int i;
char company[10];
char *s;
int i;
char company[10];
for (i = 3; i < 8; i++) company[i - 3] = rominfo.copyright[i];
company[5] = 0;
for (i = 3; i < 8; i++) company[i - 3] = rominfo.copyright[i];
company[5] = 0;
/** OK, first look for a hyphen
* Capcom use T-12 for example
*/
s = strstr (company, "-");
if (s != NULL)
{
s++;
strcpy (company, s);
}
/** OK, first look for a hyphen
* Capcom use T-12 for example
*/
s = strstr (company, "-");
if (s != NULL)
{
s++;
strcpy (company, s);
}
/** Strip any trailing spaces **/
for (i = strlen (company) - 1; i >= 0; i--)
/** Strip any trailing spaces **/
for (i = strlen (company) - 1; i >= 0; i--)
if (company[i] == 32) company[i] = 0;
if (strlen (company) == 0) return MAXCOMPANY - 1;
if (strlen (company) == 0) return MAXCOMPANY - 1;
for (i = 0; i < MAXCOMPANY - 1; i++)
{
if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) return i;
}
for (i = 0; i < MAXCOMPANY - 1; i++)
{
if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) return i;
}
return MAXCOMPANY - 1;
return MAXCOMPANY - 1;
}
@ -236,11 +236,11 @@ void getrominfo (char *romheader)
j=1;
for (i=1; i<48; i++)
{
if ((rominfo.domestic[j-1] != 32) || (romheader[ROMDOMESTIC + i] != 32))
{
rominfo.domestic[j] = romheader[ROMDOMESTIC + i];
j++;
}
if ((rominfo.domestic[j-1] != 32) || (romheader[ROMDOMESTIC + i] != 32))
{
rominfo.domestic[j] = romheader[ROMDOMESTIC + i];
j++;
}
}
rominfo.domestic[j] = 0;
@ -248,11 +248,11 @@ void getrominfo (char *romheader)
j=1;
for (i=1; i<48; i++)
{
if ((rominfo.international[j-1] != 32) || (romheader[ROMWORLD + i] != 32))
{
rominfo.international[j] = romheader[ROMWORLD + i];
j++;
}
if ((rominfo.international[j-1] != 32) || (romheader[ROMWORLD + i] != 32))
{
rominfo.international[j] = romheader[ROMWORLD + i];
j++;
}
}
rominfo.international[j] = 0;
@ -277,8 +277,8 @@ void getrominfo (char *romheader)
peripherals = 0;
for (i = 0; i < 14; i++)
for (j=0; j < 14; j++)
if (rominfo.io_support[i] == peripheralinfo[j].pID[0]) peripherals |= (1 << j);
for (j=0; j < 14; j++)
if (rominfo.io_support[i] == peripheralinfo[j].pID[0]) peripherals |= (1 << j);
for (i = 0; i < 8; i++)
{
@ -292,63 +292,63 @@ void getrominfo (char *romheader)
/* 05/05/2006: new region detection routine (taken from GENS sourcecode) */
void set_region ()
{
/* country codes used to differentiate region */
/* 0001 = japan ntsc (1) */
/* 0010 = japan pal (2) */
/* 0100 = usa (4) */
/* 1000 = europe (8) */
/* country codes used to differentiate region */
/* 0001 = japan ntsc (1) */
/* 0010 = japan pal (2) */
/* 0100 = usa (4) */
/* 1000 = europe (8) */
int country = 0;
int i = 0;
char c;
int country = 0;
int i = 0;
char c;
/* reading header to find the country */
if (!strnicmp(rominfo.country, "eur", 3)) country |= 8;
else if (!strnicmp(rominfo.country, "usa", 3)) country |= 4;
else if (!strnicmp(rominfo.country, "jap", 3)) country |= 1;
/* reading header to find the country */
if (!strnicmp(rominfo.country, "eur", 3)) country |= 8;
else if (!strnicmp(rominfo.country, "usa", 3)) country |= 4;
else if (!strnicmp(rominfo.country, "jap", 3)) country |= 1;
else for(i = 0; i < 4; i++)
{
c = toupper((int)rominfo.country[i]);
if (c == 'U') country |= 4;
else if (c == 'J') country |= 1;
else if (c == 'E') country |= 8;
else if (c < 16) country |= c;
else if ((c >= '0') && (c <= '9')) country |= c - '0';
else if ((c >= 'A') && (c <= 'F')) country |= c - 'A' + 10;
}
else for(i = 0; i < 4; i++)
{
c = toupper((int)rominfo.country[i]);
if (c == 'U') country |= 4;
else if (c == 'J') country |= 1;
else if (c == 'E') country |= 8;
else if (c < 16) country |= c;
else if ((c >= '0') && (c <= '9')) country |= c - '0';
else if ((c >= 'A') && (c <= 'F')) country |= c - 'A' + 10;
}
/* automatic detection */
/* setting region */
/* this is used by IO register */
if (country & 4) region_code = REGION_USA;
else if (country & 1) region_code = REGION_JAPAN_NTSC;
else if (country & 8) region_code = REGION_EUROPE;
else if (country & 2) region_code = REGION_JAPAN_PAL;
else region_code = REGION_USA;
/* automatic detection */
/* setting region */
/* this is used by IO register */
if (country & 4) region_code = REGION_USA;
else if (country & 1) region_code = REGION_JAPAN_NTSC;
else if (country & 8) region_code = REGION_EUROPE;
else if (country & 2) region_code = REGION_JAPAN_PAL;
else region_code = REGION_USA;
/* some games need specific REGION setting */
/* some games need specific REGION setting */
if (((strstr(rominfo.product,"T-45033") != NULL) && (rominfo.checksum == 0x0F81)) || /* Alisia Dragon (E) */
(strstr(rominfo.product,"T-69046-50") != NULL)) /* On Dal Jang Goon (Korea) */
{
/* need PAL settings */
region_code = REGION_EUROPE;
}
else if ((realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL))
{
/* On Dal Jang Goon (Korea) needs JAP region code */
region_code = REGION_JAPAN_NTSC;
}
(strstr(rominfo.product,"T-69046-50") != NULL)) /* On Dal Jang Goon (Korea) */
{
/* need PAL settings */
region_code = REGION_EUROPE;
}
else if ((realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL))
{
/* On Dal Jang Goon (Korea) needs JAP region code */
region_code = REGION_JAPAN_NTSC;
}
/* Force region setting */
if (config.region_detect == 1) region_code = REGION_USA;
else if (config.region_detect == 2) region_code = REGION_EUROPE;
else if (config.region_detect == 3) region_code = REGION_JAPAN_NTSC;
else if (config.region_detect == 4) region_code = REGION_JAPAN_PAL;
/* Force region setting */
if (config.region_detect == 1) region_code = REGION_USA;
else if (config.region_detect == 2) region_code = REGION_EUROPE;
else if (config.region_detect == 3) region_code = REGION_JAPAN_NTSC;
else if (config.region_detect == 4) region_code = REGION_JAPAN_PAL;
/* set cpu/vdp speed: PAL or NTSC */
if ((region_code == REGION_EUROPE) || (region_code == REGION_JAPAN_PAL)) vdp_pal = 1;
else vdp_pal = 0;
/* set cpu/vdp speed: PAL or NTSC */
if ((region_code == REGION_EUROPE) || (region_code == REGION_JAPAN_PAL)) vdp_pal = 1;
else vdp_pal = 0;
}
/* SMD (interleaved) rom support */
@ -370,64 +370,64 @@ int load_rom(char *filename)
int i, size, offset = 0;
#ifdef NGC
size = genromsize;
size = genromsize;
#else
uint8 *ptr;
ptr = load_archive(filename, &size);
uint8 *ptr;
ptr = load_archive(filename, &size);
if(!ptr) return (0);
memcpy(cart_rom, ptr + offset, size);
free(ptr);
#endif
/* detect interleaved roms (.smd format) */
if (strncmp((char *)(cart_rom + 0x100),"SEGA", 4) && ((size / 512) & 1))
{
size -= 512;
offset += 512;
/* detect interleaved roms (.smd format) */
if (strncmp((char *)(cart_rom + 0x100),"SEGA", 4) && ((size / 512) & 1))
{
size -= 512;
offset += 512;
for (i = 0; i < (size / 0x4000); i += 1)
{
deinterleave_block (cart_rom + offset + (i * 0x4000));
}
for (i = 0; i < (size / 0x4000); i += 1)
{
deinterleave_block (cart_rom + offset + (i * 0x4000));
}
memcpy(cart_rom, cart_rom + offset, size);
}
memcpy(cart_rom, cart_rom + offset, size);
}
/* max. 10 MBytes supported */
if (size > 0xA00000) size = 0xA00000;
genromsize = size;
/* clear unused ROM space */
if (size < 0xA00000) memset (cart_rom + size, 0x00, 0xA00000 - size);
/* max. 10 MBytes supported */
if (size > 0xA00000) size = 0xA00000;
genromsize = size;
/* clear unused ROM space */
if (size < 0xA00000) memset (cart_rom + size, 0x00, 0xA00000 - size);
getrominfo((char *)cart_rom); /* get infos from ROM header */
set_region(); /* set game region (PAL/NTSC, JAP/USA/EUR) */
getrominfo((char *)cart_rom); /* get infos from ROM header */
set_region(); /* set game region (PAL/NTSC, JAP/USA/EUR) */
#ifdef LSB_FIRST
/* Byteswap ROM */
uint8 temp;
for(i = 0; i < genromsize; i += 2)
{
temp = cart_rom[i];
cart_rom[i] = cart_rom[i+1];
cart_rom[i+1] = temp;
}
/* Byteswap ROM */
uint8 temp;
for(i = 0; i < genromsize; i += 2)
{
temp = cart_rom[i];
cart_rom[i] = cart_rom[i+1];
cart_rom[i+1] = temp;
}
#endif
/* byteswapped RADICA dumps (from Haze) */
if (((strstr(rominfo.product,"-K0101") != NULL) && (rominfo.checksum == 0xf424)) ||
((strstr(rominfo.product,"-K0109") != NULL) && (rominfo.checksum == 0x4f10)))
{
uint8 temp;
for(i = 0; i < genromsize; i += 2)
{
temp = cart_rom[i];
cart_rom[i] = cart_rom[i+1];
cart_rom[i+1] = temp;
}
}
/* byteswapped RADICA dumps (from Haze) */
if (((strstr(rominfo.product,"-K0101") != NULL) && (rominfo.checksum == 0xf424)) ||
((strstr(rominfo.product,"-K0109") != NULL) && (rominfo.checksum == 0x4f10)))
{
uint8 temp;
for(i = 0; i < genromsize; i += 2)
{
temp = cart_rom[i];
cart_rom[i] = cart_rom[i+1];
cart_rom[i+1] = temp;
}
}
/* console hardware */
/* console hardware */
if (strstr(rominfo.consoletype, "SEGA PICO") != NULL) system_hw = SYSTEM_PICO;
else if (strstr(rominfo.consoletype, "SEGA MEGADRIVE") != NULL) system_hw = SYSTEM_MEGADRIVE;
else system_hw = SYSTEM_GENESIS;

View File

@ -27,22 +27,22 @@
typedef struct
{
char consoletype[18]; /* Genesis or Mega Drive */
char copyright[18]; /* Copyright message */
char domestic[50]; /* Domestic name of ROM */
char international[50]; /* International name of ROM */
char ROMType[4]; /* Educational or Game */
char product[14]; /* Product serial number */
unsigned short checksum; /* Checksum */
char io_support[18]; /* Actually 16 chars :) */
unsigned int romstart;
unsigned int romend;
char RAMInfo[14];
unsigned int ramstart;
unsigned int ramend;
char modem[14];
char memo[50];
char country[18];
char consoletype[18]; /* Genesis or Mega Drive */
char copyright[18]; /* Copyright message */
char domestic[50]; /* Domestic name of ROM */
char international[50]; /* International name of ROM */
char ROMType[4]; /* Educational or Game */
char product[14]; /* Product serial number */
unsigned short checksum; /* Checksum */
char io_support[18]; /* Actually 16 chars :) */
unsigned int romstart; /* ROM start address */
unsigned int romend; /* ROM end address */
char RAMInfo[14]; /* Backup RAM header */
unsigned int ramstart; /* RAM start address */
unsigned int ramend; /* RAM end address */
char modem[14]; /* Sega Modem support */
char memo[50]; /* Misc */
char country[18]; /* Country flag */
} ROMINFO;
typedef struct

View File

@ -4,20 +4,23 @@
#ifdef LSB_FIRST
#define READ_BYTE(BASE, ADDR) (BASE)[(ADDR)^1]
#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | \
(BASE)[(ADDR)+1])
#define READ_WORD_LONG(BASE, ADDR) (((BASE)[ADDR]<<24) | \
((BASE)[(ADDR)+1]<<16) | \
((BASE)[(ADDR)+2]<<8) | \
(BASE)[(ADDR)+3])
#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | (BASE)[(ADDR)+1])
#define READ_WORD_LONG(BASE, ADDR) (((BASE)[ADDR]<<24) | \
((BASE)[(ADDR)+1]<<16) | \
((BASE)[(ADDR)+2]<<8) | \
(BASE)[(ADDR)+3])
#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)&0xff
#define WRITE_WORD(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>8) & 0xff; \
(BASE)[(ADDR)+1] = (VAL)&0xff
#define WRITE_WORD_LONG(BASE, ADDR, VAL) (BASE)[(ADDR] = ((VAL)>>24) & 0xff; \
(BASE)[(ADDR)+1] = ((VAL)>>16)&0xff; \
(BASE)[(ADDR)+2] = ((VAL)>>8)&0xff; \
(BASE)[(ADDR)+3] = (VAL)&0xff
#define WRITE_WORD(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>8) & 0xff; \
(BASE)[(ADDR)+1] = (VAL)&0xff
#define WRITE_WORD_LONG(BASE, ADDR, VAL) (BASE)[(ADDR] = ((VAL)>>24) & 0xff; \
(BASE)[(ADDR)+1] = ((VAL)>>16)&0xff; \
(BASE)[(ADDR)+2] = ((VAL)>>8)&0xff; \
(BASE)[(ADDR)+3] = (VAL)&0xff
#else

View File

@ -32,7 +32,7 @@ uint32 zbank_unused_r(uint32 address)
#ifdef LOGERROR
error("Z80 bank unused read %06X\n", address);
#endif
return (address & 1) ? 0x00 : 0xFF;
return (address & 1) ? 0x00 : 0xFF;
}
void zbank_unused_w(uint32 address, uint32 data)
@ -47,7 +47,7 @@ uint32 zbank_lockup_r(uint32 address)
#ifdef LOGERROR
error("Z80 bank lockup read %06X\n", address);
#endif
gen_running = config.force_dtack;
gen_running = config.force_dtack;
return 0xFF;
}
@ -56,7 +56,7 @@ void zbank_lockup_w(uint32 address, uint32 data)
#ifdef LOGERROR
error("Z80 bank lockup write %06X = %02X\n", address, data);
#endif
gen_running = config.force_dtack;
gen_running = config.force_dtack;
}
/* I/O & Control registers */
@ -64,57 +64,57 @@ uint32 zbank_read_ctrl_io(uint32 address)
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
case 0x00: /* I/O chip */
if (address & 0xe0) return zbank_unused_r(address);
else return (io_read((address >> 1) & 0x0f));
case 0x11: /* BUSACK */
case 0x11: /* BUSACK */
if (address & 1) return zbank_unused_r(address);
else return (0xfe | zbusack);
case 0x30: /* TIME */
case 0x30: /* TIME */
if (cart_hw.time_r) return cart_hw.time_r(address);
else return zbank_unused_r(address);
case 0x10: /* MEMORY MODE */
case 0x12: /* RESET */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x41: /* BOOTROM */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
case 0x10: /* MEMORY MODE */
case 0x12: /* RESET */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x41: /* BOOTROM */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
return zbank_unused_r(address);
default: /* Invalid address */
default: /* Invalid address */
return zbank_lockup_r(address);
}
}
void zbank_write_ctrl_io(uint32 address, uint32 data)
{
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
case 0x00: /* I/O chip */
if ((address & 0xe1) == 0x01) io_write((address >> 1) & 0x0f, data); /* get /LWR only */
else zbank_unused_w(address, data);
return;
case 0x11: /* BUSREQ */
case 0x11: /* BUSREQ */
if (address & 1) zbank_unused_w(address, data);
else gen_busreq_w(data & 1);
return;
case 0x12: /* RESET */
case 0x12: /* RESET */
if (address & 1) zbank_unused_w(address, data);
else gen_reset_w(data & 1);
return;
case 0x30: /* TIME */
case 0x30: /* TIME */
if (cart_hw.time_w) cart_hw.time_w(address, data);
else zbank_unused_w(address, data);
return;
case 0x41: /* BOOTROM */
case 0x41: /* BOOTROM */
if (address & 1)
{
m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom;
@ -130,15 +130,15 @@ void zbank_write_ctrl_io(uint32 address, uint32 data)
else zbank_unused_w (address, data);
return;
case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x44: /* RADICA */
case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
zbank_unused_w(address, data);
return;
default: /* Invalid address */
default: /* Invalid address */
zbank_lockup_w(address, data);
return;
}
@ -150,33 +150,33 @@ uint32 zbank_read_vdp(uint32 address)
{
switch (address & 0xfd)
{
case 0x00: /* DATA */
case 0x00: /* DATA */
return (vdp_data_r() >> 8);
case 0x01: /* DATA */
case 0x01: /* DATA */
return (vdp_data_r() & 0xff);
case 0x04: /* CTRL */
case 0x04: /* CTRL */
return (0xfc | ((vdp_ctrl_r() >> 8) & 3));
case 0x05: /* CTRL */
case 0x05: /* CTRL */
return (vdp_ctrl_r() & 0xff);
case 0x08: /* HVC */
case 0x08: /* HVC */
case 0x0c:
return (vdp_hvc_r() >> 8);
case 0x09: /* HVC */
case 0x09: /* HVC */
case 0x0d:
return (vdp_hvc_r() & 0xff);
case 0x18: /* Unused */
case 0x18: /* Unused */
case 0x19:
case 0x1c:
case 0x1d:
return zbank_unused_r(address);
default: /* Invalid address */
default: /* Invalid address */
return zbank_lockup_r(address);
}
}
@ -185,15 +185,15 @@ void zbank_write_vdp(uint32 address, uint32 data)
{
switch (address & 0xfc)
{
case 0x00: /* Data port */
case 0x00: /* Data port */
vdp_data_w(data << 8 | data);
return;
case 0x04: /* Control port */
case 0x04: /* Control port */
vdp_ctrl_w(data << 8 | data);
return;
case 0x10: /* PSG */
case 0x10: /* PSG */
case 0x14:
if (address & 1) psg_write(0, data);
else zbank_unused_w(address, data);
@ -207,7 +207,7 @@ void zbank_write_vdp(uint32 address, uint32 data)
vdp_test_w(data << 8 | data);
return;
default: /* Invalid address */
default: /* Invalid address */
zbank_lockup_w(address, data);
return;
}

View File

@ -24,8 +24,8 @@
#define LOG_PORT 0 /* 1= Log Z80 I/O port accesses */
/*
Handlers for access to unused addresses and those which make the
machine lock up.
Handlers for access to unused addresses and those which make the
machine lock up.
*/
static inline void z80_unused_w(unsigned int address, unsigned int data)
{
@ -39,7 +39,7 @@ static inline unsigned int z80_unused_r(unsigned int address)
#ifdef LOGERROR
error("Z80 unused read %04X\n", address);
#endif
return 0xff;
return 0xff;
}
static inline void z80_lockup_w(unsigned int address, unsigned int data)
@ -47,7 +47,7 @@ static inline void z80_lockup_w(unsigned int address, unsigned int data)
#ifdef LOGERROR
error("Z80 lockup write %04X = %02X\n", address, data);
#endif
gen_running = config.force_dtack;
gen_running = config.force_dtack;
}
static inline unsigned int z80_lockup_r(unsigned int address)
@ -55,8 +55,8 @@ static inline unsigned int z80_lockup_r(unsigned int address)
#ifdef LOGERROR
error("Z80 lockup read %04X\n", address);
#endif
gen_running = config.force_dtack;
return 0xff;
gen_running = config.force_dtack;
return 0xff;
}
/*
VDP access
@ -85,34 +85,34 @@ static inline unsigned int z80_vdp_r(unsigned int address)
case 0x0d:
return (vdp_hvc_r() & 0xff);
case 0x18: /* Unused */
case 0x19:
case 0x18: /* Unused */
case 0x19:
case 0x1c:
case 0x1d:
return z80_unused_r(address);
case 0x1d:
return z80_unused_r(address);
default: /* Invalid address */
return z80_lockup_r(address);
}
return z80_lockup_r(address);
}
}
static inline void z80_vdp_w(unsigned int address, unsigned int data)
{
switch (address & 0xfc)
{
case 0x00: /* Data port */
case 0x00: /* Data port */
vdp_data_w(data << 8 | data);
return;
case 0x04: /* Control port */
case 0x04: /* Control port */
vdp_ctrl_w(data << 8 | data);
return;
case 0x10: /* PSG */
case 0x10: /* PSG */
case 0x14:
if (address & 1) psg_write(0, data);
else z80_unused_w(address, data);
return;
return;
case 0x18: /* Unused */
z80_unused_w(address, data);
@ -122,7 +122,7 @@ static inline void z80_vdp_w(unsigned int address, unsigned int data)
vdp_test_w(data << 8 | data);
return;
default: /* Invalid address */
default: /* Invalid address */
z80_lockup_w(address, data);
return;
}
@ -194,22 +194,22 @@ void cpu_writemem16(unsigned int address, unsigned int data)
if (zbank_memory_map[slot].write) (*zbank_memory_map[slot].write)(address, data);
else WRITE_BYTE(m68k_memory_map[slot].base, address&0xffff, data);
return;
}
}
}
}
/*
Port handlers. Ports are unused when not in Mark III compatability mode.
Port handlers. Ports are unused when not in Mark III compatability mode.
Games that access ports anyway:
- Thunder Force IV reads port $BF in it's interrupt handler.
Games that access ports anyway:
Thunder Force IV reads port $BF in it's interrupt handler.
*/
unsigned int cpu_readport16(unsigned int port)
{
#if LOG_PORT
error("Z80 read port %04X\n", port);
#endif
#endif
return 0xFF;
}

View File

@ -12,15 +12,19 @@
void config_save()
{
if (!use_FAT) return;
char pathname[MAXPATHLEN];
if (!fat_enabled) return;
/* first check if directory exist */
DIR_ITER *dir = diropen("/genplus");
if (dir == NULL) mkdir("/genplus",S_IRWXU);
sprintf (pathname, DEFAULT_PATH);
DIR_ITER *dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* open configuration file */
FILE *fp = fopen("/genplus/genplus.ini", "wb");
sprintf (pathname, "%s/config.ini", pathname);
FILE *fp = fopen(pathname, "wb");
if (fp == NULL) return;
/* save options */
@ -31,8 +35,11 @@ void config_save()
void config_load()
{
char pathname[MAXPATHLEN];
/* open configuration file */
FILE *fp = fopen("/genplus/genplus.ini", "rb");
sprintf (pathname, "%s/genplus.ini", DEFAULT_PATH);
FILE *fp = fopen(pathname, "rb");
if (fp == NULL) return;
/* read version */
@ -42,7 +49,7 @@ void config_load()
if (strcmp(version,CONFIG_VERSION)) return;
/* read file */
fp = fopen("/genplus/genplus.ini", "rb");
fp = fopen(pathname, "rb");
fread(&config, sizeof(config), 1, fp);
fclose(fp);
}

View File

@ -44,7 +44,7 @@ t_config config;
extern void config_save();
extern void config_load();
extern void set_config_defaults(void);
extern bool use_FAT;
extern bool fat_enabled;
#endif /* _CONFIG_H_ */

View File

@ -1,28 +1,17 @@
/****************************************************************************
* Nintendo Gamecube DVD Reading Library
*
* This is NOT a complete DVD library, in that it works for reading
* ISO9660 discs only.
* Low-Level DVD access
*
* If you need softmod drivecodes etc, look elsewhere.
* There are known issues with libogc dvd handling, so these work
* outside of it ,if you will.
*
* This is ideal for using with a gc-linux self booting DVD only.
* Go http://www.gc-linux.org for further information and the tools
* for your platform.
*
* To keep libOGC stable, make sure you call DVD_Init before using
* these functions.
***************************************************************************/
#include "shared.h"
#ifdef HW_RVL
#include "di/di.h"
#endif
#ifndef HW_RVL
static u64 DvdMaxOffset = 0x57057C00; /* 1.4 GB max. */
static u64 DvdMaxOffset = 0x57057C00; /* 1.4 GB max. by default */
static vu32* const dvd = (u32*)0xCC006000; /* DVD I/O Address base */
static u8 *inquiry=(unsigned char *)0x80000004; /* pointer to drive ID */
#else
@ -32,7 +21,6 @@ static u64 DvdMaxOffset = 0x118244F00LL; /* 4.7 GB max. */
static u8 DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32); /* data buffer for all DVD operations */
/***************************************************************************
* dvd_read
*
@ -85,19 +73,19 @@ u32 dvd_read (void *dst, u32 len, u64 offset)
void dvd_motor_off( )
{
#ifndef HW_RVL
dvd[0] = 0x2e;
dvd[1] = 0;
dvd[2] = 0xe3000000;
dvd[3] = 0;
dvd[4] = 0;
dvd[5] = 0;
dvd[6] = 0;
dvd[7] = 1; // Do immediate
while (dvd[7] & 1);
dvd[0] = 0x2e;
dvd[1] = 0;
dvd[2] = 0xe3000000;
dvd[3] = 0;
dvd[4] = 0;
dvd[5] = 0;
dvd[6] = 0;
dvd[7] = 1; // Do immediate
while (dvd[7] & 1);
/*** PSO Stops blackscreen at reload ***/
dvd[0] = 0x14;
dvd[1] = 0;
/*** PSO Stops blackscreen at reload ***/
dvd[0] = 0x14;
dvd[1] = 0;
#else
DI_StopMotor();

19
source/ngc/dvd.h Normal file
View File

@ -0,0 +1,19 @@
/****************************************************************************
* Nintendo Gamecube DVD Reading Library
*
* Low-Level DVD access
*
***************************************************************************/
#ifndef _DVD_H_
#define _DVD_H_
extern u32 dvd_read (void *dst, u32 len, u64 offset);
extern void dvd_motor_off ();
#ifndef HW_RVL
extern void uselessinquiry ();
extern void dvd_drive_detect();
#endif
#endif

View File

@ -9,8 +9,8 @@
#include "dvd.h"
#include "font.h"
#include "unzip.h"
#include <zlib.h>
#include <zlib.h>
/*
* PKWare Zip Header - adopted into zip standard
@ -24,7 +24,7 @@
*/
typedef struct
{
unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50
unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50
unsigned short zipversion __attribute__ ((__packed__));
unsigned short zipflags __attribute__ ((__packed__));
unsigned short compressionMethod __attribute__ ((__packed__));
@ -119,34 +119,34 @@ int UnZipDVD (unsigned char *outbuffer, u64 discoffset, int length)
{
zs.avail_in = zipchunk;
zs.next_in = (Bytef *) & readbuffer[zipoffset];
/*** Now inflate until input buffer is exhausted ***/
do
{
zs.avail_out = ZIPCHUNK;
zs.next_out = (Bytef *) & out;
res = inflate (&zs, Z_NO_FLUSH);
{
zs.avail_out = ZIPCHUNK;
zs.next_out = (Bytef *) & out;
res = inflate (&zs, Z_NO_FLUSH);
if (res == Z_MEM_ERROR)
{
inflateEnd (&zs);
return 0;
}
if (res == Z_MEM_ERROR)
{
inflateEnd (&zs);
return 0;
}
have = ZIPCHUNK - zs.avail_out;
if (have)
{
have = ZIPCHUNK - zs.avail_out;
if (have)
{
/*** Copy to normal block buffer ***/
memcpy (&outbuffer[bufferoffset], &out, have);
bufferoffset += have;
}
memcpy (&outbuffer[bufferoffset], &out, have);
bufferoffset += have;
}
}
while (zs.avail_out == 0);
/*** Readup the next 2k block ***/
/*** Readup the next 2k block ***/
zipoffset = 0;
zipchunk = ZIPCHUNK;
discoffset += 2048;
dvd_read (&readbuffer, 2048, discoffset);
}

399
source/ngc/fileio_dvd.c Normal file
View File

@ -0,0 +1,399 @@
/****************************************************************************
*
* DVD ISO9660/Joliet loading support
*
***************************************************************************/
#include "shared.h"
#include "font.h"
#include "fileio_dvd.h"
#include "filesel.h"
#include "fileio.h"
#include "dvd.h"
#ifdef HW_RVL
#include "di/di.h"
#endif
/** Minimal ISO Directory Definition **/
#define RECLEN 0 /* Record length */
#define EXTENT 6 /* Extent */
#define FILE_LENGTH 14 /* File length (BIG ENDIAN) */
#define FILE_FLAGS 25 /* File flags */
#define FILENAME_LENGTH 32 /* Filename length */
#define FILENAME 33 /* ASCIIZ filename */
/** Minimal Primary Volume Descriptor **/
#define PVDROOT 0x9c
/** Static Variables **/
static u64 rootdir = 0; /* current root directory offset */
static u64 basedir = 0; /* base directory offset */
static int rootdirlength = 0; /* current root directory length */
static int IsJoliet = 0;
static int diroffset = 0;
static char dvdbuffer[2048];
/****************************************************************************
* Primary Volume Descriptor
*
* The PVD should reside between sector 16 and 31.
* This is for single session DVD only.
****************************************************************************/
static int getpvd ()
{
int sector = 16;
u32 rootdir32;
basedir = rootdirlength = 0;
IsJoliet = -1;
/** Look for Joliet PVD first **/
while (sector < 32)
{
if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11)))
{
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
{
memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
basedir = (u64)rootdir32;
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
basedir <<= 11;
IsJoliet = 1;
break;
}
}
else return 0; /*** Can't read sector! ***/
sector++;
}
if (IsJoliet > 0) return 1; /*** Joliet PVD Found ? ***/
/*** Look for standard ISO9660 PVD ***/
sector = 16;
while (sector < 32)
{
if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11)))
{
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
{
memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
basedir = (u64)rootdir32;
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
IsJoliet = 0;
basedir <<= 11;
break;
}
}
else return 0; /*** Can't read sector! ***/
sector++;
}
return (IsJoliet == 0);
}
/****************************************************************************
* getentry
*
* Support function to return the next file entry, if any
* Declared static to avoid accidental external entry.
****************************************************************************/
static int getentry (int entrycount)
{
char fname[512]; /* Huge, but experience has determined this */
char *ptr;
char *filename;
char *filenamelength;
char *rr;
int j;
u32 offset32;
/* Basic checks */
if (entrycount >= MAXFILES) return 0;
if (diroffset >= 2048) return 0;
/** Decode this entry **/
if (dvdbuffer[diroffset]) /* Record length available */
{
/* Update offsets into sector buffer */
ptr = (char *) &dvdbuffer[0];
ptr += diroffset;
filename = ptr + FILENAME;
filenamelength = ptr + FILENAME_LENGTH;
/* Check for wrap round - illegal in ISO spec,
* but certain crap writers do it! */
if ((diroffset + dvdbuffer[diroffset]) > 2048) return 0;
if (*filenamelength)
{
memset (&fname, 0, 512);
/*** Do ISO 9660 first ***/
if (!IsJoliet) strcpy (fname, filename);
else
{
/*** The more tortuous unicode joliet entries ***/
for (j = 0; j < (*filenamelength >> 1); j++)
{
fname[j] = filename[j * 2 + 1];
}
fname[j] = 0;
if (strlen (fname) >= MAXJOLIET) fname[MAXJOLIET - 1] = 0;
if (strlen (fname) == 0) fname[0] = filename[0];
}
if (strlen (fname) == 0) strcpy (fname, ".");
else
{
if (fname[0] == 1) strcpy (fname, "..");
else
{
/*
* Move *filenamelength to t,
* Only to stop gcc warning for noobs :)
*/
int t = *filenamelength;
fname[t] = 0;
}
}
/** Rockridge Check **/
rr = strstr (fname, ";");
if (rr != NULL) *rr = 0;
strcpy (filelist[entrycount].filename, fname);
memcpy (&offset32, &dvdbuffer[diroffset + EXTENT], 4);
filelist[entrycount].offset = (u64)offset32;
memcpy (&filelist[entrycount].length, &dvdbuffer[diroffset + FILE_LENGTH], 4);
memcpy (&filelist[entrycount].flags, &dvdbuffer[diroffset + FILE_FLAGS], 1);
filelist[entrycount].offset <<= 11;
filelist[entrycount].flags = filelist[entrycount].flags & 2;
filelist[entrycount].filename_offset = 0;
/*** Prepare for next entry ***/
diroffset += dvdbuffer[diroffset];
return 1;
}
}
return 0;
}
/***************************************************************************
* DVD_UpdateRootDir
*
* Update DVD current root directory
***************************************************************************/
int DVD_UpdateDir(int go_up)
{
/* current directory doesn't change */
if (selection == 0) return 1;
/* root has no parent directory */
if (go_up && (basedir == rootdir)) return 0;
/* by default, update current directory */
rootdir = filelist[selection].offset;
rootdirlength = filelist[selection].length;
/* reinit selector (previous value is saved for one level) */
if (selection == 1)
{
selection = old_selection;
offset = old_offset;
old_selection = 0;
old_offset = 0;
}
else
{
/* save current selector value */
old_selection = selection;
old_offset = offset;
selection = 0;
offset = 0;
}
return 1;
}
/****************************************************************************
* DVD_ParseDirectory
*
* This function will parse the directory tree.
* It relies on rootdir and rootdirlength being pre-populated by a call to
* getpvd, a previous parse or a menu selection.
*
* The return value is number of files collected, or 0 on failure.
****************************************************************************/
int DVD_ParseDirectory ()
{
int pdlength;
u64 pdoffset;
u64 rdoffset;
int len = 0;
int filecount = 0;
pdoffset = rdoffset = rootdir;
pdlength = rootdirlength;
filecount = 0;
/** Clear any existing values ***/
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
/*** Get as many files as possible ***/
while (len < pdlength)
{
if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0) return 0;
diroffset = 0;
while (getentry (filecount))
{
if (filecount < MAXFILES) filecount++;
}
len += 2048;
pdoffset = rdoffset + len;
}
return filecount;
}
/****************************************************************************
* DVD_LoadFile
*
* This function will load a BIN, SMD or ZIP file from DVD into the ROM buffer.
* The index values indicates the file position in filentry list
* This functions return the actual size of data copied into the buffer
*
****************************************************************************/
int DVD_LoadFile (unsigned char *buffer)
{
/* file size */
int length = filelist[selection].length;
if (length > 0)
{
/* Read first data chunk */
char readbuffer[2048];
u64 discoffset = filelist[selection].offset;
dvd_read (&readbuffer, 2048, discoffset);
/* determine file type */
if (!IsZipFile ((char *) readbuffer))
{
/* How many 2k blocks to read */
int blocks = length / 2048;
int readoffset = 0;
int i;
/* read data chunks */
for (i = 0; i < blocks; i++)
{
dvd_read(readbuffer, 2048, discoffset);
discoffset += 2048;
memcpy (buffer + readoffset, readbuffer, 2048);
readoffset += 2048;
}
/* final read */
i = length % 2048;
if (i)
{
dvd_read (readbuffer, 2048, discoffset);
memcpy (buffer + readoffset, readbuffer, i);
}
return length;
}
else
{
return UnZipDVD (buffer, discoffset, length);
}
}
return 0;
}
/****************************************************************************
* DVD_Open
*
* Function to load a DVD directory and display to user.
****************************************************************************/
int DVD_Open ()
{
/* reset flags */
useFAT = 0;
/* is DVD mounted ? */
if (!getpvd())
{
/* mount DVD */
ShowAction("Mounting DVD ... Wait");
#ifdef HW_RVL
u32 val;
DI_GetCoverRegister(&val);
if(val & 0x1)
{
WaitPrompt("No Disc inserted !");
return 0;
}
DI_Mount();
while(DI_GetStatus() & DVD_INIT);
if (!(DI_GetStatus() & DVD_READY))
{
char msg[50];
sprintf(msg, "DI Status Error: 0x%08X\n",DI_GetStatus());
WaitPrompt(msg);
return 0;
}
#else
DVD_Mount();
#endif
haveDVDdir = 0;
if (!getpvd())
{
WaitPrompt ("Failed to mount DVD");
return 0;
}
}
if (haveDVDdir == 0)
{
/* reset root directory */
rootdir = basedir;
/* parse root directory */
ShowAction("Reading Directory ...");
int max = DVD_ParseDirectory ();
if (max)
{
/* set DVD as default */
haveDVDdir = 1;
haveFATdir = 0;
/* reset File selector */
maxfiles = max;
offset = 0;
selection = 0;
old_offset = 0;
old_selection = 0;
return FileSelector ();
}
else
{
/* no entries found */
WaitPrompt ("no files found !");
return 0;
}
}
return FileSelector ();
}

14
source/ngc/fileio_dvd.h Normal file
View File

@ -0,0 +1,14 @@
/****************************************************************************
*
* DVD ISO9660/Joliet loading support
*
***************************************************************************/
#ifndef _FILEIO_DVD_H
#define _FILEIO_DVD_H
extern int DVD_UpdateDir(int go_up);
extern int DVD_ParseDirectory();
extern int DVD_LoadFile(unsigned char* buffer);
extern int DVD_Open ();
#endif

313
source/ngc/fileio_fat.c Normal file
View File

@ -0,0 +1,313 @@
/****************************************************************************
* FAT loading support
*
***************************************************************************/
#include "shared.h"
#include "font.h"
#include "fileio_fat.h"
#include "filesel.h"
#include "fileio.h"
#include "history.h"
/* current FAT directory */
static char fatdir[256];
/* current FAT device */
static int fat_type = 0;
static int useHistory = 0;
/***************************************************************************
* FAT_UpdateDir
*
* Update FAT current root directory
***************************************************************************/
int FAT_UpdateDir(int go_up)
{
int size=0;
char *test;
char temp[1024];
/* current directory doesn't change */
if (strcmp(filelist[selection].filename,".") == 0) return 1;
/* go up to parent directory */
if (strcmp(filelist[selection].filename,"..") == 0)
{
/* determine last subdirectory namelength */
sprintf(temp,"%s",fatdir);
test= strtok(temp,"/");
while (test != NULL)
{
size = strlen(test);
test = strtok(NULL,"/");
}
/* remove last subdirectory name */
size = strlen(fatdir) - size;
fatdir[size-1] = 0;
/* restore previous selector state */
selection = old_selection;
offset = old_offset;
/* reset old selection */
old_selection = 0;
old_offset = 0;
}
else if (go_up)
{
/* root has no parent directory */
return 0;
}
else
{
/* by default, simply append folder name */
sprintf(fatdir, "%s%s/",fatdir, filelist[selection].filename);
/* save current selector state */
old_selection = selection;
old_offset = offset;
/* reset selection */
selection = 0;
offset = 0;
}
return 1;
}
/***************************************************************************
* FileSortCallback (Marty Disibio)
*
* Quick sort callback to sort file entries with the following order:
* .
* ..
* <dirs>
* <files>
***************************************************************************/
static int FileSortCallback(const void *f1, const void *f2)
{
/* Special case for implicit directories */
if(((FILEENTRIES *)f1)->filename[0] == '.' || ((FILEENTRIES *)f2)->filename[0] == '.')
{
if(strcmp(((FILEENTRIES *)f1)->filename, ".") == 0) { return -1; }
if(strcmp(((FILEENTRIES *)f2)->filename, ".") == 0) { return 1; }
if(strcmp(((FILEENTRIES *)f1)->filename, "..") == 0) { return -1; }
if(strcmp(((FILEENTRIES *)f2)->filename, "..") == 0) { return 1; }
}
/* If one is a file and one is a directory the directory is first. */
if(((FILEENTRIES *)f1)->flags == 1 && ((FILEENTRIES *)f2)->flags == 0) return -1;
if(((FILEENTRIES *)f1)->flags == 0 && ((FILEENTRIES *)f2)->flags == 1) return 1;
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
}
/***************************************************************************
* FAT_ParseDirectory
*
* List files into one FAT directory
***************************************************************************/
int FAT_ParseDirectory()
{
int nbfiles = 0;
char filename[MAXPATHLEN];
struct stat filestat;
/* open directory */
DIR_ITER *dir = diropen (fatdir);
if (dir == NULL)
{
sprintf(filename, "Error opening %s", fatdir);
WaitPrompt (filename);
return 0;
}
while ((dirnext(dir, filename, &filestat) == 0) && (nbfiles < MAXFILES))
{
if (strcmp(filename,".") != 0)
{
memset(&filelist[nbfiles], 0, sizeof (FILEENTRIES));
sprintf(filelist[nbfiles].filename,"%s",filename);
filelist[nbfiles].length = filestat.st_size;
filelist[nbfiles].flags = (filestat.st_mode & S_IFDIR) ? 1 : 0;
nbfiles++;
}
}
dirclose(dir);
/* Sort the file list */
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
return nbfiles;
}
/****************************************************************************
* FAT_LoadFile
*
* This function will load a BIN, SMD or ZIP file from DVD into the ROM buffer.
* This functions return the actual size of data copied into the buffer
*
****************************************************************************/
int FAT_LoadFile (unsigned char *buffer)
{
/* If loading from history then we need to setup a few more things. */
if(useHistory)
{
/* Get the parent folder for the file. */
strncpy(fatdir, history.entries[selection].filepath, MAXJOLIET-1);
fatdir[MAXJOLIET-1] = '\0';
/* Get the length of the file. This has to be done
* before calling LoadFile(). */
char filepath[MAXJOLIET];
struct stat filestat;
snprintf(filepath, MAXJOLIET-1, "%s%s", history.entries[selection].filepath, history.entries[selection].filename);
filepath[MAXJOLIET-1] = '\0';
if(stat(filepath, &filestat) == 0)
{
filelist[selection].length = filestat.st_size;
}
}
/* file size */
int length = filelist[selection].length;
if (length > 0)
{
/* Add/move the file to the top of the history. */
history_add_file(fatdir, filelist[selection].filename);
/* full filename */
char fname[MAXPATHLEN];
sprintf(fname, "%s%s",fatdir,filelist[selection].filename);
/* open file */
FILE *sdfile = fopen(fname, "rb");
if (sdfile == NULL)
{
WaitPrompt ("Unable to open file!");
haveFATdir = 0;
return 0;
}
/* Read first data chunk */
unsigned char temp[2048];
fread(temp, 1, 2048, sdfile);
fclose(sdfile);
/* determine file type */
if (!IsZipFile ((char *) temp))
{
/* re-open and read file */
sdfile = fopen(fname, "rb");
if (sdfile)
{
fread(buffer, 1, length, sdfile);
fclose(sdfile);
return length;
}
}
else
{
/* unzip file */
return UnZipFAT(buffer, fname);
}
}
return 0;
}
/****************************************************************************
* OpenFAT
*
* Function to load a FAT directory and display to user.
****************************************************************************/
int FAT_Open(int type)
{
int max = 0;
char root[10] = "";
/* reset flags */
useFAT = 1;
useHistory = 0;
/* FAT header */
#ifdef HW_RVL
if (type == TYPE_SD) sprintf (root, "sd:");
else if (type == TYPE_USB) sprintf (root, "usb:");
#endif
/* if FAT device type changed, reload filelist */
if (fat_type != type)
{
haveFATdir = 0;
}
fat_type = type;
/* update filelist */
if (haveFATdir == 0)
{
if (type == TYPE_RECENT)
{
/* fetch history list */
useHistory = 1;
int i;
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{
if(history.entries[i].filepath[0] > 0)
{
filelist[i].offset = 0;
filelist[i].length = 0;
filelist[i].flags = 0;
filelist[i].filename_offset = 0;
strncpy(filelist[i].filename, history.entries[i].filename, MAXJOLIET-1);
filelist[i].filename[MAXJOLIET-1] = '\0';
max++;
}
else
{
/* Found the end of the list. */
break;
}
}
}
else
{
/* reset root directory */
sprintf (fatdir, "%s%s/roms", root, DEFAULT_PATH);
/* if directory doesn't exist, use root as default */
DIR_ITER *dir = diropen(fatdir);
if (dir == NULL) sprintf (fatdir, "%s/", root);
else dirclose(dir);
/* parse root directory */
ShowAction("Reading Directory ...");
max = FAT_ParseDirectory ();
}
if (max)
{
/* FAT is default */
haveFATdir = 1;
haveDVDdir = 0;
/* reset file selection */
maxfiles = max;
offset = 0;
selection = 0;
old_offset = 0;
old_selection = 0;
return FileSelector ();
}
else
{
/* no entries found */
WaitPrompt ("no files found !");
return 0;
}
}
return FileSelector ();
}

21
source/ngc/fileio_fat.h Normal file
View File

@ -0,0 +1,21 @@
/****************************************************************************
*
* FAT loading support
*
***************************************************************************/
#ifndef _FILEIO_FAT_H
#define _FILEIO_FAT_H
#define TYPE_RECENT 0
#define TYPE_SD 1
#ifdef HW_RVL
#define TYPE_USB 2
#endif
extern int FAT_UpdateDir(int go_up);
extern int FAT_ParseDirectory(void);
extern int FAT_LoadFile(unsigned char* buffer);
extern int FAT_Open (int device);
#endif

View File

@ -9,10 +9,8 @@
#include "shared.h"
#define ARAMSTART 0x8000
#define ARAM_READ 1
#define ARAM_WRITE 0
#define ARAM_READ 1
#define ARAM_WRITE 0
/**
* StartARAM
@ -20,8 +18,7 @@
* Passing NULL for array list, and 0 items to allocate.
* Required so libOGC knows to handle any interrupts etc.
*/
void
StartARAM ()
void StartARAM ()
{
AR_Init (NULL, 0);
}
@ -31,8 +28,7 @@ StartARAM ()
*
* Move data from MAIN memory to ARAM
*/
void
ARAMPut (char *src, char *dst, int len)
void ARAMPut (char *src, char *dst, int len)
{
DCFlushRange (src, len);
AR_StartDMA( ARAM_WRITE, (u32)src, (u32)dst, len);
@ -51,16 +47,3 @@ ARAMFetch (char *dst, char *src, int len)
AR_StartDMA( ARAM_READ, (u32) dst, (u32) src, len);
while (AR_GetDMAStatus());
}
/**
* ShadowROM
* Copy the rom from cart_rom into ARAM
* NB: libOGC appears to use the first 0x4000 bytes.
* As there's plenty left, all ARAM addresses are 0x8000 based.
* Here, the ROM is simply copied in one swift movement :)
*/
void
ShadowROM ()
{
ARAMPut ((char *)cart_rom, (void *) ARAMSTART, genromsize);
}

View File

@ -7,8 +7,11 @@
* Good to know :)
*/
extern void StartARAM ();
void ShadowROM ();
void ARAMFetch (char *src, char *dst, int len);
void ARAMPut (char *src, char *dst, int len);
#ifndef _ARAM_H
#define _ARAM_H
extern void StartARAM ();
extern void ARAMFetch (char *src, char *dst, int len);
extern void ARAMPut (char *src, char *dst, int len);
#endif

View File

@ -1,29 +0,0 @@
/****************************************************************************
* Nintendo Gamecube DVD Reading Library
*
* This is NOT a complete DVD library, in that it works for reading
* ISO9660 discs only.
*
* If you need softmod drivecodes etc, look elsewhere.
* There are known issues with libogc dvd handling, so these work
* outside of it ,if you will.
*
* This is ideal for using with a gc-linux self booting DVD only.
* Go http://www.gc-linux.org for further information and the tools
* for your platform.
*
* To keep libOGC stable, make sure you call DVD_Init before using
* these functions.
***************************************************************************/
#ifndef _DVD_H_
#define _DVD_H_
extern u32 dvd_read (void *dst, u32 len, u64 offset);
extern void dvd_motor_off ();
#ifndef HW_RVL
extern void uselessinquiry ();
extern void dvd_drive_detect();
#endif
#endif

View File

@ -11,56 +11,22 @@
*
***************************************************************************/
#include "shared.h"
#include "iso9660.h"
#include "font.h"
#include "fileio.h"
#include "history.h"
#include "dvd.h"
#include "fileio_dvd.h"
#include "fileio_fat.h"
#include "filesel.h"
#ifdef HW_RVL
#include <di/di.h>
#endif
/* Global Variables */
int maxfiles = 0;
int offset = 0;
int selection = 0;
int old_selection = 0;
int old_offset = 0;
int useFAT = 0;
int useHistory = 0;
int haveDVDdir = 0;
int haveFATdir = 0;
#define PAGESIZE 12
static int maxfiles;
static int offset = 0;
static int selection = 0;
static int old_selection = 0;
static int old_offset = 0;
static char rootFATdir[256];
static u8 haveDVDdir = 0;
static u8 haveFATdir = 0;
static u8 UseFAT = 0;
static u8 UseHistory = 0;
static int LoadFile (unsigned char *buffer);
/***************************************************************************
* FileSortCallback (Marty Disibio)
*
* Quick sort callback to sort file entries with the following order:
* .
* ..
* <dirs>
* <files>
***************************************************************************/
static int FileSortCallback(const void *f1, const void *f2)
{
/* Special case for implicit directories */
if(((FILEENTRIES *)f1)->filename[0] == '.' || ((FILEENTRIES *)f2)->filename[0] == '.')
{
if(strcmp(((FILEENTRIES *)f1)->filename, ".") == 0) { return -1; }
if(strcmp(((FILEENTRIES *)f2)->filename, ".") == 0) { return 1; }
if(strcmp(((FILEENTRIES *)f1)->filename, "..") == 0) { return -1; }
if(strcmp(((FILEENTRIES *)f2)->filename, "..") == 0) { return 1; }
}
/* If one is a file and one is a directory the directory is first. */
if(((FILEENTRIES *)f1)->flags == 1 && ((FILEENTRIES *)f2)->flags == 0) return -1;
if(((FILEENTRIES *)f1)->flags == 0 && ((FILEENTRIES *)f2)->flags == 1) return 1;
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
}
/***************************************************************************
* ShowFiles
@ -87,137 +53,17 @@ static void ShowFiles (int offset, int selection)
SetScreen ();
}
/***************************************************************************
* updateFATdirname
*
* Update ROOT directory while browsing SDCARD
***************************************************************************/
static int updateFATdirname()
{
int size=0;
char *test;
char temp[1024];
/* current directory doesn't change */
if (strcmp(filelist[selection].filename,".") == 0) return 0;
/* go up to parent directory */
else if (strcmp(filelist[selection].filename,"..") == 0)
{
/* determine last subdirectory namelength */
sprintf(temp,"%s",rootFATdir);
test= strtok(temp,"/");
while (test != NULL)
{
size = strlen(test);
test = strtok(NULL,"/");
}
/* remove last subdirectory name */
size = strlen(rootFATdir) - size;
rootFATdir[size-1] = 0;
}
else
{
sprintf(rootFATdir, "%s%s/",rootFATdir, filelist[selection].filename);
}
return 1;
}
/***************************************************************************
* parseFATdirectory
*
* List files into one SDCARD directory
***************************************************************************/
static int parseFATdirectory()
{
int nbfiles = 0;
char filename[MAXPATHLEN];
struct stat filestat;
/* open directory */
DIR_ITER *dir = diropen (rootFATdir);
if (dir == NULL)
{
sprintf(filename, "Error opening %s", rootFATdir);
WaitPrompt (filename);
return 0;
}
while (dirnext(dir, filename, &filestat) == 0)
{
if (strcmp(filename,".") != 0)
{
memset(&filelist[nbfiles], 0, sizeof (FILEENTRIES));
sprintf(filelist[nbfiles].filename,"%s",filename);
filelist[nbfiles].length = filestat.st_size;
filelist[nbfiles].flags = (filestat.st_mode & S_IFDIR) ? 1 : 0;
nbfiles++;
}
}
dirclose(dir);
/* Sort the file list */
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
return nbfiles;
}
/****************************************************************************
* FileSelected
*
* Called when a file is selected by the user inside the FileSelector loop.
****************************************************************************/
static int FileSelected()
{
/* If loading from history then we need to setup a few more things. */
if(UseHistory)
{
/* Get the parent folder for the file. */
strncpy(rootFATdir, history.entries[selection].filepath, MAXJOLIET-1);
rootFATdir[MAXJOLIET-1] = '\0';
/* Get the length of the file. This has to be done
* before calling LoadFile(). */
char filepath[MAXJOLIET];
struct stat filestat;
snprintf(filepath, MAXJOLIET-1, "%s%s", history.entries[selection].filepath, history.entries[selection].filename);
filepath[MAXJOLIET-1] = '\0';
if(stat(filepath, &filestat) == 0)
{
filelist[selection].length = filestat.st_size;
}
}
/* Add/move the file to the top of the history. */
if (UseFAT) history_add_file(rootFATdir, filelist[selection].filename);
rootdir = filelist[selection].offset;
rootdirlength = filelist[selection].length;
memfile_autosave();
genromsize = LoadFile(cart_rom);
if (genromsize)
{
reloadrom();
memfile_autoload();
return 1;
}
return 0;
}
/****************************************************************************
* FileSelector
*
* Let user select a file from the File listing
****************************************************************************/
static int FileSelector ()
int FileSelector()
{
short p;
int redraw = 1;
int go_up = 0;
int ret;
int i,size;
while (1)
@ -297,22 +143,7 @@ static int FileSelector ()
if ((selection - offset) >= PAGESIZE) offset += PAGESIZE;
redraw = 1;
}
/* go up one directory or quit */
if (p & PAD_BUTTON_B)
{
filelist[selection].filename_offset = 0;
if (UseFAT)
{
if (strcmp(filelist[0].filename,"..") != 0) return 0;
}
else
{
if (basedir == rootdir) return 0;
}
go_up = 1;
}
/* quit */
if (p & PAD_TRIGGER_Z)
{
@ -321,349 +152,45 @@ static int FileSelector ()
}
/* open selected file or directory */
if ((p & PAD_BUTTON_A) || go_up)
if ((p & PAD_BUTTON_A) || (p & PAD_BUTTON_B))
{
filelist[selection].filename_offset = 0;
if (go_up)
go_up = 0;
if (p & PAD_BUTTON_B)
{
/* select item #1 */
go_up = 0;
selection = UseFAT ? 0 : 1;
/* go up one directory or quit */
go_up = 1;
selection = useFAT ? 0 : 1;
}
/*** This is directory ***/
if (filelist[selection].flags)
{
/* SDCARD directory handler */
if (UseFAT)
{
/* update current directory */
if (updateFATdirname())
{
/* reinit selector (previous value is saved for one level) */
if (selection == 0)
{
selection = old_selection;
offset = old_offset;
old_selection = 0;
old_offset = 0;
}
else
{
/* save current selector value */
old_selection = selection;
old_offset = offset;
selection = 0;
offset = 0;
}
/* set new entry list */
maxfiles = parseFATdirectory();
if (!maxfiles)
{
/* quit */
WaitPrompt ("No files found !");
haveFATdir = 0;
return 0;
}
}
}
else /* DVD directory handler */
{
/* move to a new directory */
if (selection != 0)
{
/* update current directory */
rootdir = filelist[selection].offset;
rootdirlength = filelist[selection].length;
/* reinit selector (previous value is saved for one level) */
if (selection == 1)
{
selection = old_selection;
offset = old_offset;
old_selection = 0;
old_offset = 0;
}
else
{
/* save current selector value */
old_selection = selection;
old_offset = offset;
selection = 0;
offset = 0;
}
/* get new directory */
ret = useFAT ? FAT_UpdateDir(go_up) : DVD_UpdateDir(go_up);
/* get new entry list */
maxfiles = parseDVDdirectory ();
}
}
}
else /*** This is a file ***/
{
return FileSelected();
}
redraw = 1;
}
}
}
/****************************************************************************
* OpenDVD
*
* Function to load a DVD directory and display to user.
****************************************************************************/
int OpenDVD ()
{
UseFAT = 0;
UseHistory = 0;
if (!getpvd())
{
/* mount DVD */
ShowAction("Mounting DVD ... Wait");
#ifndef HW_RVL
DVD_Mount();
#else
u32 val;
DI_GetCoverRegister(&val);
if(val & 0x1)
{
WaitPrompt("No Disc inserted !");
return 0;
}
DI_Mount();
while(DI_GetStatus() & DVD_INIT);
if (!(DI_GetStatus() & DVD_READY))
{
char msg[50];
sprintf(msg, "DI Status Error: 0x%08X\n",DI_GetStatus());
WaitPrompt(msg);
return 0;
}
#endif
haveDVDdir = 0;
if (!getpvd())
{
WaitPrompt ("Failed to mount DVD");
return 0;
}
}
if (haveDVDdir == 0)
{
/* don't mess with SD entries */
haveFATdir = 0;
/* reinit selector */
rootdir = basedir;
old_selection = selection = offset = old_offset = 0;
}
/* Parse root directory and get entries list */
ShowAction("Reading Directory ...");
if ((maxfiles = parseDVDdirectory ()))
{
/* Select an entry */
haveDVDdir = 1;
return FileSelector ();
}
else
{
/* no entries found */
WaitPrompt ("no files found !");
haveDVDdir = 0;
return 0;
}
}
/****************************************************************************
* OpenFAT
*
* Function to load a FAT directory and display to user.
****************************************************************************/
int OpenFAT (char *name)
{
UseFAT = 1;
UseHistory = 0;
if (haveFATdir == 0)
{
/* don't mess with DVD entries */
haveDVDdir = 0;
/* reinit selector */
old_selection = selection = offset = old_offset = 0;
/* Reset SDCARD root directory */
sprintf (rootFATdir, "%s/genplus/roms/", name);
/* if directory doesn't exist, use root */
DIR_ITER *dir = diropen(rootFATdir);
if (dir == NULL) sprintf (rootFATdir, "%s/", name);
else dirclose(dir);
}
/* Parse root directory and get entries list */
ShowAction("Reading Directory ...");
if ((maxfiles = parseFATdirectory ()))
{
/* Select an entry */
haveFATdir = 1;
return FileSelector ();
}
else
{
/* no entries found */
WaitPrompt ("no files found !");
haveFATdir = 0;
return -1;
}
}
/****************************************************************************
* OpenHistory
*
* Function to load a recent file from SDCARD (Marty Disibio)
****************************************************************************/
int OpenHistory()
{
int i;
UseFAT = 1;
UseHistory = 1;
/* don't mess with other entries */
haveFATdir = 0;
haveDVDdir = 0;
/* reinit selector */
old_selection = selection = offset = old_offset = 0;
/* Recreate the file listing from the history
* as if all of the roms were in the same directory. */
ShowAction("Reading Files ...");
maxfiles = 0;
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{
if(history.entries[i].filepath[0] > 0)
{
filelist[i].offset = 0;
filelist[i].length = 0;
filelist[i].flags = 0;
filelist[i].filename_offset = 0;
strncpy(filelist[i].filename, history.entries[i].filename, MAXJOLIET-1);
filelist[i].filename[MAXJOLIET-1] = '\0';
maxfiles++;
}
else
{
/* Found the end of the list. */
break;
}
}
if(!maxfiles)
{
WaitPrompt ("No recent files");
return 0;
}
return FileSelector();
}
/****************************************************************************
* LoadFile
*
* This function will load a file from DVD or SDCARD, in BIN, SMD or ZIP format.
* The values for offset and length are inherited from rootdir and
* rootdirlength.
*
* The buffer parameter should re-use the initial ROM buffer.
****************************************************************************/
static int LoadFile (unsigned char *buffer)
{
u64 discoffset = 0;
char readbuffer[2048];
char fname[MAXPATHLEN];
FILE *sdfile = NULL;
if (rootdirlength == 0) return 0;
/* SDCard access */
if (UseFAT)
{
/* open file */
sprintf(fname, "%s%s",rootFATdir,filelist[selection].filename);
sdfile = fopen(fname, "rb");
if (sdfile == NULL)
{
WaitPrompt ("Unable to open file!");
haveFATdir = 0;
return -1;
}
}
ShowAction ("Loading ... Wait");
/* Read first data chunk */
if (UseFAT)
{
fread(readbuffer, 1, 2048, sdfile);
}
else
{
discoffset = rootdir;
dvd_read (&readbuffer, 2048, discoffset);
}
/* determine file type */
if (!IsZipFile ((char *) readbuffer))
{
if (UseFAT)
{
/* go back to file start and read file */
fseek(sdfile, 0, SEEK_SET);
fread(buffer, 1, rootdirlength, sdfile);
fclose(sdfile);
}
else
{
/* How many 2k blocks to read */
int blocks = rootdirlength / 2048;
int readoffset = 0;
int i;
/* read data chunks */
for (i = 0; i < blocks; i++)
{
dvd_read(readbuffer, 2048, discoffset);
discoffset += 2048;
memcpy (buffer + readoffset, readbuffer, 2048);
readoffset += 2048;
/* get new entry list or quit */
if (ret) maxfiles = useFAT ? FAT_ParseDirectory() : DVD_ParseDirectory();
else return 0;
}
/* final read */
i = rootdirlength % 2048;
if (i)
/*** This is a file ***/
else
{
dvd_read (readbuffer, 2048, discoffset);
memcpy (buffer + readoffset, readbuffer, i);
/* Load file */
genromsize = useFAT ? FAT_LoadFile(cart_rom) : DVD_LoadFile(cart_rom);
if (genromsize)
{
memfile_autosave();
reloadrom();
memfile_autoload();
return 1;
}
return 0;
}
redraw = 1;
}
}
else
{
/* unzip file */
if (UseFAT) return UnZipFAT(buffer, fname);
else return UnZipDVD (buffer, discoffset, rootdirlength);
}
return rootdirlength;
}

35
source/ngc/gui/filesel.h Normal file
View File

@ -0,0 +1,35 @@
/****************************************************************************
* ROM Selection Interface
*
***************************************************************************/
#ifndef _FILESEL_H
#define _FILESEL_H
#define MAXJOLIET 256
#define MAXFILES 1000
#define PAGESIZE 12
typedef struct
{
u64 offset;
unsigned int length;
char flags;
char filename[MAXJOLIET];
u16 filename_offset;
}FILEENTRIES;
FILEENTRIES filelist[MAXFILES];
/* Global Variables */
extern int maxfiles;
extern int offset;
extern int selection;
extern int old_selection;
extern int old_offset;
extern int useFAT;
extern int haveDVDdir;
extern int haveFATdir;
extern int FileSelector();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,8 @@ typedef struct
} GGPATCH;
/*** Game Genie Codes Array ***/
unsigned char ggcodes[MAXCODES][10]; /*** Codes are entered as XXXX-XXXX ***/
int gghpos[MAXCODES]; /*** Edit positions ***/
unsigned char ggcodes[MAXCODES][10]; /*** Codes are entered as XXXX-XXXX ***/
int gghpos[MAXCODES]; /*** Edit positions ***/
int ggrow = 0;
int editing = 0;
char ggvalidchars[] = "ABCDEFGHJKLMNPRSTVWXYZ0123456789*";
@ -50,53 +50,53 @@ void decode_genie (char *code, int which)
int n, i;
for (i = 0; i < 8; i++)
{
/*** This should only happen if memory is corrupt! ***/
p = strchr (ggvalidchars, code[i]);
if (p == NULL)
{
ggpatch[which].address = ggpatch[which].data = 0;
return;
}
/*** This should only happen if memory is corrupt! ***/
p = strchr (ggvalidchars, code[i]);
if (p == NULL)
{
ggpatch[which].address = ggpatch[which].data = 0;
return;
}
n = p - ggvalidchars;
n = p - ggvalidchars;
switch (i)
{
case 0:
ggpatch[which].data |= n << 3;
break;
switch (i)
{
case 0:
ggpatch[which].data |= n << 3;
break;
case 1:
ggpatch[which].data |= n >> 2;
ggpatch[which].address |= (n & 3) << 14;
break;
case 1:
ggpatch[which].data |= n >> 2;
ggpatch[which].address |= (n & 3) << 14;
break;
case 2:
ggpatch[which].address |= n << 9;
break;
case 2:
ggpatch[which].address |= n << 9;
break;
case 3:
ggpatch[which].address |= (n & 0xF) << 20 | (n >> 4) << 8;
break;
case 3:
ggpatch[which].address |= (n & 0xF) << 20 | (n >> 4) << 8;
break;
case 4:
ggpatch[which].data |= (n & 1) << 12;
ggpatch[which].address |= (n >> 1) << 16;
break;
case 4:
ggpatch[which].data |= (n & 1) << 12;
ggpatch[which].address |= (n >> 1) << 16;
break;
case 5:
ggpatch[which].data |= (n & 1) << 15 | (n >> 1) << 8;
break;
case 5:
ggpatch[which].data |= (n & 1) << 15 | (n >> 1) << 8;
break;
case 6:
ggpatch[which].data |= (n >> 3) << 13;
ggpatch[which].address |= (n & 7) << 5;
break;
case 6:
ggpatch[which].data |= (n >> 3) << 13;
ggpatch[which].address |= (n & 7) << 5;
break;
case 7:
ggpatch[which].address |= n;
break;
}
case 7:
ggpatch[which].address |= n;
break;
}
}
}
@ -112,25 +112,25 @@ void decode_ggcodes ()
j = 0;
for (i = 0; i < 8; i++)
{
if (strcmp ((char *)ggcodes[i], "AAAA-AAAA"))
{
/*** Move the code into thiscode ***/
memcpy (&thiscode, &ggcodes[i], 4);
memcpy (&thiscode[4], &ggcodes[i][5], 4);
if (strcmp ((char *)ggcodes[i], "AAAA-AAAA"))
{
/*** Move the code into thiscode ***/
memcpy (&thiscode, &ggcodes[i], 4);
memcpy (&thiscode[4], &ggcodes[i][5], 4);
decode_genie (thiscode, j);
j++;
}
decode_genie (thiscode, j);
j++;
}
}
/*** And now apply the patches ***/
if (j)
{
for (i = 0; i < j; i++)
{
if (ggpatch[i].address < 0x400000)
{
/*** Patching ROM space ONLY (Game Genie does NOT have access to other memory areas) ***/
for (i = 0; i < j; i++)
{
if (ggpatch[i].address < 0x400000)
{
/*** Patching ROM space ONLY (Game Genie does NOT have access to other memory areas) ***/
if (cart_rom) *(uint16 *)(cart_rom + ggpatch[i].address) = ggpatch[i].data & 0xffff;
}
}
@ -148,8 +148,8 @@ void ClearGGCodes ()
for (i = 0; i < MAXCODES; i++)
{
strcpy ((char *)ggcodes[i], "AAAA-AAAA");
gghpos[i] = 0;
strcpy ((char *)ggcodes[i], "AAAA-AAAA");
gghpos[i] = 0;
}
ggrow = 0;
}
@ -169,29 +169,29 @@ void DrawGGCodes ()
for (i = 0; i < MAXCODES; i++)
{
if (i == ggrow)
{
/*** Highlight selected ***/
WriteCentre_HL (i * fheight + 224, (char *)ggcodes[i]);
if (i == ggrow)
{
/*** Highlight selected ***/
WriteCentre_HL (i * fheight + 224, (char *)ggcodes[i]);
/*** If editing, highlight the current character ***/
if (editing)
{
int hpos = 0;
/*** If editing, highlight the current character ***/
if (editing)
{
int hpos = 0;
for (j=0; j<strlen ((char *)ggcodes[i]); j++) hpos += font_size[ggcodes[i][j]];
hpos = ((640 - hpos) >> 1);
for (j=0; j<gghpos[i]; j++) hpos += font_size[ggcodes[i][j]];
hpos = ((640 - hpos) >> 1);
for (j=0; j<gghpos[i]; j++) hpos += font_size[ggcodes[i][j]];
c[0] = ggcodes[i][gghpos[i]];
fntDrawBoxFilled (hpos, (i * fheight) + 224, hpos + font_size[c[0]],
c[0] = ggcodes[i][gghpos[i]];
fntDrawBoxFilled (hpos, (i * fheight) + 224, hpos + font_size[c[0]],
((i + 1) * fheight) + 224, COLOR_YELLOW);
setfontcolour (COLOR_BLUE);
write_font (hpos, (i * fheight) + 224, (char *)c);
setfontcolour (COLOR_WHITE);
}
}
else WriteCentre ((i * fheight) + 224, (char *)ggcodes[i]);
setfontcolour (COLOR_BLUE);
write_font (hpos, (i * fheight) + 224, (char *)c);
setfontcolour (COLOR_WHITE);
}
}
else WriteCentre ((i * fheight) + 224, (char *)ggcodes[i]);
}
SetScreen ();
}
@ -215,55 +215,55 @@ void GGEditLine ()
while (quit == 0)
{
if (redraw)
{
DrawGGCodes ();
redraw = 0;
}
if (redraw)
{
DrawGGCodes ();
redraw = 0;
}
p = ogc_input__getMenuButtons();
p = ogc_input__getMenuButtons();
if (p & PAD_BUTTON_UP)
{
/*** Increment the entry ***/
redraw = 1;
c[0] = ggcodes[ggrow][gghpos[ggrow]];
v = strstr (ggvalidchars, c);
v++;
if (*v == '*') ggcodes[ggrow][gghpos[ggrow]] = 'A';
else ggcodes[ggrow][gghpos[ggrow]] = *v;
}
if (p & PAD_BUTTON_UP)
{
/*** Increment the entry ***/
redraw = 1;
c[0] = ggcodes[ggrow][gghpos[ggrow]];
v = strstr (ggvalidchars, c);
v++;
if (*v == '*') ggcodes[ggrow][gghpos[ggrow]] = 'A';
else ggcodes[ggrow][gghpos[ggrow]] = *v;
}
if (p & PAD_BUTTON_DOWN)
{
/*** Decrement entry ***/
redraw = 1;
c[0] = ggcodes[ggrow][gghpos[ggrow]];
v = strstr (ggvalidchars, c);
if (*v == 'A') ggcodes[ggrow][gghpos[ggrow]] = '9';
else
{
v--;
ggcodes[ggrow][gghpos[ggrow]] = *v;
}
}
if (p & PAD_BUTTON_DOWN)
{
/*** Decrement entry ***/
redraw = 1;
c[0] = ggcodes[ggrow][gghpos[ggrow]];
v = strstr (ggvalidchars, c);
if (*v == 'A') ggcodes[ggrow][gghpos[ggrow]] = '9';
else
{
v--;
ggcodes[ggrow][gghpos[ggrow]] = *v;
}
}
if (p & PAD_BUTTON_LEFT)
{
redraw = 1;
gghpos[ggrow]--;
if (gghpos[ggrow] == 4) gghpos[ggrow]--;
}
if (p & PAD_BUTTON_LEFT)
{
redraw = 1;
gghpos[ggrow]--;
if (gghpos[ggrow] == 4) gghpos[ggrow]--;
}
if (p & PAD_BUTTON_RIGHT)
{
redraw = 1;
gghpos[ggrow]++;
if (gghpos[ggrow] == 4) gghpos[ggrow]++;
}
if (p & PAD_BUTTON_RIGHT)
{
redraw = 1;
gghpos[ggrow]++;
if (gghpos[ggrow] == 4) gghpos[ggrow]++;
}
if (gghpos[ggrow] < 0) gghpos[ggrow] = 8;
if (gghpos[ggrow] > 8) gghpos[ggrow] = 0;
if (gghpos[ggrow] < 0) gghpos[ggrow] = 8;
if (gghpos[ggrow] > 8) gghpos[ggrow] = 0;
if (p & PAD_BUTTON_A) quit = 1;
}
@ -283,49 +283,49 @@ void GGSelectLine ()
short j;
/*** To select a line, just move up or down.
Pressing A will enter edit mode.
Pressing B will exit to caller. ***/
Pressing A will enter edit mode.
Pressing B will exit to caller. ***/
while (quit == 0)
{
if (redraw)
{
DrawGGCodes ();
redraw = 0;
}
if (redraw)
{
DrawGGCodes ();
redraw = 0;
}
j = ogc_input__getMenuButtons();
j = ogc_input__getMenuButtons();
if (j & PAD_BUTTON_UP)
{
ggrow--;
redraw = 1;
}
if (j & PAD_BUTTON_UP)
{
ggrow--;
redraw = 1;
}
if (j & PAD_BUTTON_DOWN)
{
ggrow++;
redraw = 1;
}
if (j & PAD_BUTTON_DOWN)
{
ggrow++;
redraw = 1;
}
if (ggrow < 0) ggrow = MAXCODES - 1;
if (ggrow == MAXCODES) ggrow = 0;
if (ggrow < 0) ggrow = MAXCODES - 1;
if (ggrow == MAXCODES) ggrow = 0;
if (j & PAD_BUTTON_B) quit = 1;
if (j & PAD_BUTTON_B) quit = 1;
if (j & PAD_BUTTON_A)
{
GGEditLine ();
redraw = 1;
}
if (j & PAD_BUTTON_A)
{
GGEditLine ();
redraw = 1;
}
if (j & PAD_TRIGGER_Z)
{
/* reset code */
{
/* reset code */
strcpy ((char *)ggcodes[ggrow], "AAAA-AAAA");
gghpos[ggrow] = 0;
redraw = 1;
}
}
}
}

View File

@ -1,221 +0,0 @@
/****************************************************************************
* DVD ISO9660/Joliet Parsing
*
* This is not intended as a complete guide to ISO9660.
* Here I use the bare minimum!
***************************************************************************/
#include "shared.h"
#include "dvd.h"
#include "iso9660.h"
/** Minimal ISO Directory Definition **/
#define RECLEN 0 /* Record length */
#define EXTENT 6 /* Extent */
#define FILE_LENGTH 14 /* File length (BIG ENDIAN) */
#define FILE_FLAGS 25 /* File flags */
#define FILENAME_LENGTH 32 /* Filename length */
#define FILENAME 33 /* ASCIIZ filename */
/** Minimal Primary Volume Descriptor **/
#define PVDROOT 0x9c
static int IsJoliet = 0;
u64 rootdir = 0;
u64 basedir = 0;
int rootdirlength = 0;
/** Global file entry table **/
FILEENTRIES filelist[MAXFILES];
static char dvdbuffer[2048] ATTRIBUTE_ALIGN (32);
/****************************************************************************
* Primary Volume Descriptor
*
* The PVD should reside between sector 16 and 31.
* This is for single session DVD only.
****************************************************************************/
int getpvd ()
{
int sector = 16;
u32 rootdir32;
basedir = rootdirlength = 0;
IsJoliet = -1;
/** Look for Joliet PVD first **/
while (sector < 32)
{
if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11)))
{
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
{
memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
basedir = (u64)rootdir32;
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
basedir <<= 11;
IsJoliet = 1;
break;
}
}
else return 0; /*** Can't read sector! ***/
sector++;
}
if (IsJoliet > 0) return 1; /*** Joliet PVD Found ? ***/
/*** Look for standard ISO9660 PVD ***/
sector = 16;
while (sector < 32)
{
if (dvd_read (&dvdbuffer, 2048, (u64)(sector << 11)))
{
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
{
memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
basedir = (u64)rootdir32;
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
IsJoliet = 0;
basedir <<= 11;
break;
}
}
else return 0; /*** Can't read sector! ***/
sector++;
}
return (IsJoliet == 0);
}
/****************************************************************************
* getentry
*
* Support function to return the next file entry, if any
* Declared static to avoid accidental external entry.
****************************************************************************/
static int diroffset = 0;
static int getentry (int entrycount)
{
char fname[512]; /* Huge, but experience has determined this */
char *ptr;
char *filename;
char *filenamelength;
char *rr;
int j;
u32 offset32;
/* Basic checks */
if (entrycount >= MAXFILES) return 0;
if (diroffset >= 2048) return 0;
/** Decode this entry **/
if (dvdbuffer[diroffset]) /* Record length available */
{
/* Update offsets into sector buffer */
ptr = (char *) &dvdbuffer[0];
ptr += diroffset;
filename = ptr + FILENAME;
filenamelength = ptr + FILENAME_LENGTH;
/* Check for wrap round - illegal in ISO spec,
* but certain crap writers do it! */
if ((diroffset + dvdbuffer[diroffset]) > 2048) return 0;
if (*filenamelength)
{
memset (&fname, 0, 512);
/*** Do ISO 9660 first ***/
if (!IsJoliet) strcpy (fname, filename);
else
{
/*** The more tortuous unicode joliet entries ***/
for (j = 0; j < (*filenamelength >> 1); j++)
{
fname[j] = filename[j * 2 + 1];
}
fname[j] = 0;
if (strlen (fname) >= MAXJOLIET) fname[MAXJOLIET - 1] = 0;
if (strlen (fname) == 0) fname[0] = filename[0];
}
if (strlen (fname) == 0) strcpy (fname, ".");
else
{
if (fname[0] == 1) strcpy (fname, "..");
else
{
/*
* Move *filenamelength to t,
* Only to stop gcc warning for noobs :)
*/
int t = *filenamelength;
fname[t] = 0;
}
}
/** Rockridge Check **/
rr = strstr (fname, ";");
if (rr != NULL) *rr = 0;
strcpy (filelist[entrycount].filename, fname);
memcpy (&offset32, &dvdbuffer[diroffset + EXTENT], 4);
filelist[entrycount].offset = (u64)offset32;
memcpy (&filelist[entrycount].length, &dvdbuffer[diroffset + FILE_LENGTH], 4);
memcpy (&filelist[entrycount].flags, &dvdbuffer[diroffset + FILE_FLAGS], 1);
filelist[entrycount].offset <<= 11;
filelist[entrycount].flags = filelist[entrycount].flags & 2;
filelist[entrycount].filename_offset = 0;
/*** Prepare for next entry ***/
diroffset += dvdbuffer[diroffset];
return 1;
}
}
return 0;
}
/****************************************************************************
* parseDVDdirectory
*
* This function will parse the directory tree.
* It relies on rootdir and rootdirlength being pre-populated by a call to
* getpvd, a previous parse or a menu selection.
*
* The return value is number of files collected, or 0 on failure.
****************************************************************************/
int parseDVDdirectory ()
{
int pdlength;
u64 pdoffset;
u64 rdoffset;
int len = 0;
int filecount = 0;
pdoffset = rdoffset = rootdir;
pdlength = rootdirlength;
filecount = 0;
/** Clear any existing values ***/
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
/*** Get as many files as possible ***/
while (len < pdlength)
{
if (dvd_read (&dvdbuffer, 2048, pdoffset) == 0) return 0;
diroffset = 0;
while (getentry (filecount))
{
if (filecount < MAXFILES) filecount++;
}
len += 2048;
pdoffset = rdoffset + len;
}
return filecount;
}

View File

@ -1,31 +0,0 @@
/****************************************************************************
*
* DVD ISO9660/Joliet Parsing
*
* This is not intended as a complete guide to ISO9660.
* Here I use the bare minimum!
***************************************************************************/
#ifndef _ISO9660_H
#define _ISO9660_H
#define MAXJOLIET 256
#define MAXFILES 1000 /** Restrict to 1000 files per dir **/
typedef struct
{
u64 offset;
unsigned int length;
char flags;
char filename[MAXJOLIET];
u16 filename_offset;
} FILEENTRIES;
extern u64 basedir;
extern u64 rootdir;
extern int rootdirlength;
extern int getpvd ();
extern int parseDVDdirectory ();
extern FILEENTRIES filelist[MAXFILES];
#endif

View File

@ -80,12 +80,12 @@ void legal ()
dispoffset = (316 * 320) + ((640 - dkpro_WIDTH) >> 2);
for (h = 0; h < dkpro_HEIGHT; h++)
{
for (w = 0; w < dkpro_WIDTH >> 1; w++)
xfb[whichfb][dispoffset + w] = dkproraw[p++];
{
for (w = 0; w < dkpro_WIDTH >> 1; w++)
xfb[whichfb][dispoffset + w] = dkproraw[p++];
dispoffset += 320;
}
dispoffset += 320;
}
free (dkproraw);
}

File diff suppressed because it is too large Load Diff

View File

@ -8,22 +8,25 @@
*/
#include "shared.h"
#include "font.h"
#include "history.h"
t_history history;
void history_save()
{
if (!use_FAT) return;
char pathname[MAXPATHLEN];
if (!fat_enabled) return;
/* first check if directory exist */
DIR_ITER *dir = diropen("/genplus");
if (dir == NULL) mkdir("/genplus",S_IRWXU);
sprintf (pathname, DEFAULT_PATH);
DIR_ITER *dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* open file for writing */
FILE *fp = fopen("/genplus/romhistory.ini", "wb");
sprintf (pathname, "%s/history.ini", pathname);
FILE *fp = fopen(pathname, "wb");
if (fp == NULL) return;
/* save options */
@ -42,46 +45,49 @@ void history_save()
****************************************************************************/
void history_add_file(char *filepath, char *filename)
{
/* Create the new entry for this path. */
t_history_entry newentry;
strncpy(newentry.filepath, filepath, MAXJOLIET - 1);
strncpy(newentry.filename, filename, MAXJOLIET - 1);
newentry.filepath[MAXJOLIET - 1] = '\0';
newentry.filename[MAXJOLIET - 1] = '\0';
t_history_entry oldentry; /* Old entry is the one being shuffled down a spot. */
t_history_entry currentry; /* Curr entry is the one that just replaced old path. */
/* Initially set curr entry to the new value. */
memcpy(&currentry, &newentry, sizeof(t_history_entry));
/* Create the new entry for this path. */
t_history_entry newentry;
strncpy(newentry.filepath, filepath, MAXJOLIET - 1);
strncpy(newentry.filename, filename, MAXJOLIET - 1);
newentry.filepath[MAXJOLIET - 1] = '\0';
newentry.filename[MAXJOLIET - 1] = '\0';
t_history_entry oldentry; /* Old entry is the one being shuffled down a spot. */
t_history_entry currentry; /* Curr entry is the one that just replaced old path. */
/* Initially set curr entry to the new value. */
memcpy(&currentry, &newentry, sizeof(t_history_entry));
int i;
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{
/* Save off the next entry. */
memcpy(&oldentry, &history.entries[i], sizeof(t_history_entry));
/* Overwrite with the previous entry. */
memcpy(&history.entries[i], &currentry, sizeof(t_history_entry));
/* Switch the old entry to the curr entry now. */
memcpy(&currentry, &oldentry, sizeof(t_history_entry));
/* If the entry in the list at this spot matches
the new entry then do nothing and let this
entry get deleted. */
if(strcmp(newentry.filepath, currentry.filepath) == 0 && strcmp(newentry.filename, currentry.filename) == 0)
break;
}
int i;
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{
/* Save off the next entry. */
memcpy(&oldentry, &history.entries[i], sizeof(t_history_entry));
/* now save to disk */
history_save();
/* Overwrite with the previous entry. */
memcpy(&history.entries[i], &currentry, sizeof(t_history_entry));
/* Switch the old entry to the curr entry now. */
memcpy(&currentry, &oldentry, sizeof(t_history_entry));
/* If the entry in the list at this spot matches
the new entry then do nothing and let this
entry get deleted. */
if(strcmp(newentry.filepath, currentry.filepath) == 0 && strcmp(newentry.filename, currentry.filename) == 0)
break;
}
/* now save to disk */
history_save();
}
void history_load()
{
char pathname[MAXPATHLEN];
/* open file for reading */
FILE *fp = fopen("/genplus/romhistory.ini", "rb");
sprintf (pathname, "%s/history.ini", DEFAULT_PATH);
FILE *fp = fopen(pathname, "rb");
if (fp == NULL) return;
/* read file */
@ -92,11 +98,11 @@ void history_load()
void set_history_defaults(void)
{
int i;
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{
memset(&history.entries[i], 0, sizeof(t_history_entry));
}
int i;
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{
memset(&history.entries[i], 0, sizeof(t_history_entry));
}
}

View File

@ -5,20 +5,19 @@
* Created by Martin Disibio on 6/17/08.
*
*/
#ifndef _HISTORY_H
#define _HISTORY_H
#include "types.h"
#include "iso9660.h"
/****************************************************************************
#ifndef _HISTORY_H
#define _HISTORY_H
#include "types.h"
#include "filesel.h"
#define NUM_HISTORY_ENTRIES (10)
/****************************************************************************
* ROM Play History
*
****************************************************************************/
#define NUM_HISTORY_ENTRIES (10)
typedef struct
{
char filepath[MAXJOLIET];
@ -27,14 +26,12 @@ typedef struct
typedef struct
{
t_history_entry entries[NUM_HISTORY_ENTRIES];
t_history_entry entries[NUM_HISTORY_ENTRIES];
} t_history;
extern t_history history;
extern void history_add_file(char *filepath, char *filename);
extern void history_load();
extern void set_history_defaults();
#endif
#endif

View File

@ -6,6 +6,7 @@
#include "shared.h"
#include "font.h"
#include "saveicon.h"
#ifndef HW_RVL
#include "dvd.h"
#endif
@ -29,8 +30,8 @@ static card_stat CardStatus;
*/
static u8 savebuffer[0x26000] ATTRIBUTE_ALIGN (32);
int ManageSRAM (u8 direction, u8 device);
int ManageState (u8 direction, u8 device);
int ManageSRAM(u8 direction, u8 device);
int ManageState(u8 direction, u8 device);
/****************************************************************************
* FILE autoload (SRAM/FreezeState or Config File)
@ -39,7 +40,7 @@ int ManageState (u8 direction, u8 device);
*****************************************************************************/
void memfile_autoload()
{
/* this should be transparent to the user */
/* this should be transparent to the user */
SILENT = 1;
/* SRAM */
@ -50,7 +51,7 @@ void memfile_autoload()
if (config.freeze_auto != -1)
ManageState(1,config.freeze_auto);
SILENT = 0;
SILENT = 0;
}
void memfile_autosave()
@ -85,15 +86,17 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
int done = 0;
int filesize;
if (!use_FAT) return 0;
if (!fat_enabled) return 0;
/* first check if directory exist */
DIR_ITER *dir = diropen("/genplus/saves");
if (dir == NULL) mkdir("/genplus/saves",S_IRWXU);
sprintf (pathname, "%s/saves", DEFAULT_PATH);
DIR_ITER *dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir);
/* build complete SDCARD filename */
sprintf (pathname, "/genplus/saves/%s", filename);
sprintf (pathname, "%s/%s", pathname, filename);
/* open file */
FILE *fp = fopen(pathname, direction ? "rb" : "wb");
@ -104,17 +107,17 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
return 0;
}
switch (direction)
{
case 0: /* SAVING */
switch (direction)
{
case 0: /* SAVING */
if (filetype) /* SRAM */
{
memcpy(savebuffer, sram.sram, 0x10000);
sram.crc = crc32 (0, sram.sram, 0x10000);
if (filetype) /* SRAM */
{
memcpy(savebuffer, sram.sram, 0x10000);
sram.crc = crc32 (0, sram.sram, 0x10000);
filesize = 0x10000;
}
else filesize = state_save(savebuffer); /* STATE */
}
else filesize = state_save(savebuffer); /* STATE */
/* write buffer */
done = fwrite(savebuffer, 1, filesize, fp);
@ -129,9 +132,9 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
sprintf (filename, "Saved %d bytes successfully", done);
WaitPrompt (filename);
return 1;
case 1: /* LOADING */
case 1: /* LOADING */
/* read size */
fseek(fp , 0 , SEEK_END);
filesize = ftell (fp);
@ -147,20 +150,20 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
}
fclose(fp);
if (filetype) /* SRAM */
{
memcpy(sram.sram, savebuffer, filesize);
sram.crc = crc32 (0, sram.sram, 0x10000);
system_reset ();
}
else state_load(savebuffer); /* STATE */
sprintf (filename, "Loaded %d bytes successfully", done);
WaitPrompt (filename);
return 1;
}
return 0;
if (filetype) /* SRAM */
{
memcpy(sram.sram, savebuffer, filesize);
sram.crc = crc32 (0, sram.sram, 0x10000);
system_reset ();
}
else state_load(savebuffer); /* STATE */
sprintf (filename, "Loaded %d bytes successfully", done);
WaitPrompt (filename);
return 1;
}
return 0;
}
/****************************************************************************
@ -174,21 +177,21 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
*****************************************************************************/
int MountTheCard (u8 slot)
{
int tries = 0;
int CardError;
*(unsigned long *) (0xcc006800) |= 1 << 13; /*** Disable Encryption ***/
int tries = 0;
int CardError;
*(unsigned long *) (0xcc006800) |= 1 << 13; /*** Disable Encryption ***/
#ifndef HW_RVL
uselessinquiry ();
uselessinquiry ();
#endif
while (tries < 10)
{
VIDEO_WaitVSync ();
CardError = CARD_Mount (slot, SysArea, NULL); /*** Don't need or want a callback ***/
if (CardError == 0) return 1;
else EXI_ProbeReset ();
tries++;
}
return 0;
CardError = CARD_Mount (slot, SysArea, NULL); /*** Don't need or want a callback ***/
if (CardError == 0) return 1;
else EXI_ProbeReset ();
tries++;
}
return 0;
}
/****************************************************************************
@ -199,13 +202,13 @@ int MountTheCard (u8 slot)
****************************************************************************/
int CardFileExists (char *filename, u8 slot)
{
int CardError = CARD_FindFirst (slot, &CardDir, TRUE);
while (CardError != CARD_ERROR_NOFILE)
{
CardError = CARD_FindNext (&CardDir);
if (strcmp ((char *) CardDir.filename, filename) == 0) return 1;
}
return 0;
int CardError = CARD_FindFirst (slot, &CardDir, TRUE);
while (CardError != CARD_ERROR_NOFILE)
{
CardError = CARD_FindNext (&CardDir);
if (strcmp ((char *) CardDir.filename, filename) == 0) return 1;
}
return 0;
}
/****************************************************************************
@ -221,185 +224,185 @@ int CardFileExists (char *filename, u8 slot)
****************************************************************************/
int ManageSRAM (u8 direction, u8 device)
{
char filename[128];
char action[80];
int CardError;
unsigned int SectorSize;
int blocks;
char comment[2][32] = { {"Genesis Plus 1.2a"}, {"SRAM Save"} };
char filename[128];
char action[80];
int CardError;
unsigned int SectorSize;
int blocks;
char comment[2][32] = { {"Genesis Plus 1.2a"}, {"SRAM Save"} };
int outbytes = 0;
int sbo;
unsigned long inzipped,outzipped;
int sbo;
unsigned long inzipped,outzipped;
if (!genromsize) return 0;
if (!genromsize) return 0;
/* clean buffer */
/* clean buffer */
memset(savebuffer, 0, 0x24000);
if (direction) ShowAction ("Loading SRAM ...");
else ShowAction ("Saving SRAM ...");
if (direction) ShowAction ("Loading SRAM ...");
else ShowAction ("Saving SRAM ...");
/* First, build a filename */
sprintf (filename, "MD-%04X.srm", realchecksum);
strcpy (comment[1], filename);
/* First, build a filename */
sprintf (filename, "MD-%04X.srm", realchecksum);
strcpy (comment[1], filename);
/* device is SDCARD, let's go */
if (device == 0) return SD_ManageFile(filename,direction,1);
/* device is SDCARD, let's go */
if (device == 0) return SD_ManageFile(filename,direction,1);
/* set MCARD slot nr. */
u8 CARDSLOT = device - 1;
/* device is MCARD, we continue */
if (direction == 0) /*** Saving ***/
{
/*** Build the output buffer ***/
memcpy (&savebuffer, &icon, 2048);
memcpy (&savebuffer[2048], &comment[0], 64);
/* device is MCARD, we continue */
if (direction == 0) /*** Saving ***/
{
/*** Build the output buffer ***/
memcpy (&savebuffer, &icon, 2048);
memcpy (&savebuffer[2048], &comment[0], 64);
inzipped = 0x10000;
outzipped = 0x12000;
compress2 ((Bytef *) &savebuffer[2112+sizeof(outzipped)], &outzipped, (Bytef *) &sram.sram, inzipped, 9);
memcpy(&savebuffer[2112], &outzipped, sizeof(outzipped));
}
outbytes = 2048 + 64 + outzipped + sizeof(outzipped);
inzipped = 0x10000;
outzipped = 0x12000;
compress2 ((Bytef *) &savebuffer[2112+sizeof(outzipped)], &outzipped, (Bytef *) &sram.sram, inzipped, 9);
memcpy(&savebuffer[2112], &outzipped, sizeof(outzipped));
}
/*** Initialise the CARD system ***/
memset (&SysArea, 0, CARD_WORKAREA);
CARD_Init ("GENP", "00");
outbytes = 2048 + 64 + outzipped + sizeof(outzipped);
/*** Attempt to mount the card ***/
CardError = MountTheCard (CARDSLOT);
/*** Initialise the CARD system ***/
memset (&SysArea, 0, CARD_WORKAREA);
CARD_Init ("GENP", "00");
if (CardError)
{
/*** Retrieve the sector size ***/
CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize);
/*** Attempt to mount the card ***/
CardError = MountTheCard (CARDSLOT);
switch (direction)
{
case 0: /*** Saving ***/
/*** Determine number of blocks on this card ***/
blocks = (outbytes / SectorSize) * SectorSize;
if (outbytes % SectorSize) blocks += SectorSize;
if (CardError)
{
/*** Retrieve the sector size ***/
CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize);
/*** Check if a previous save exists ***/
if (CardFileExists (filename,CARDSLOT))
{
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
if (CardError)
{
sprintf (action, "Error Open : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
switch (direction)
{
case 0: /*** Saving ***/
/*** Determine number of blocks on this card ***/
blocks = (outbytes / SectorSize) * SectorSize;
if (outbytes % SectorSize) blocks += SectorSize;
int size = CardFile.len;
CARD_Close (&CardFile);
/*** Check if a previous save exists ***/
if (CardFileExists (filename,CARDSLOT))
{
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
if (CardError)
{
sprintf (action, "Error Open : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
if (size < blocks)
{
/* new size is bigger: check if there is enough space left */
CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile);
if (CardError)
{
sprintf (action, "Error Update : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
CARD_Close (&CardFile);
CARD_Delete(CARDSLOT, "TEMP");
}
int size = CardFile.len;
CARD_Close (&CardFile);
/* always delete existing slot */
CARD_Delete(CARDSLOT, filename);
}
/*** Create a new slot ***/
CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile);
if (CardError)
{
sprintf (action, "Error create : %d %d", CardError, CARDSLOT);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
if (size < blocks)
{
/* new size is bigger: check if there is enough space left */
CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile);
if (CardError)
{
sprintf (action, "Error Update : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
CARD_Close (&CardFile);
CARD_Delete(CARDSLOT, "TEMP");
}
/*** Continue and save ***/
CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
CardStatus.icon_addr = 0x0;
CardStatus.icon_fmt = 2;
CardStatus.icon_speed = 1;
CardStatus.comment_addr = 2048;
CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
/* always delete existing slot */
CARD_Delete(CARDSLOT, filename);
}
/*** And write the blocks out ***/
sbo = 0;
while (outbytes > 0)
{
CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo);
outbytes -= SectorSize;
sbo += SectorSize;
}
/*** Create a new slot ***/
CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile);
if (CardError)
{
sprintf (action, "Error create : %d %d", CardError, CARDSLOT);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
CARD_Close (&CardFile);
CARD_Unmount (CARDSLOT);
sram.crc = crc32 (0, &sram.sram[0], 0x10000);
sprintf (action, "Saved %d bytes successfully", blocks);
WaitPrompt (action);
return 1;
/*** Continue and save ***/
CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
CardStatus.icon_addr = 0x0;
CardStatus.icon_fmt = 2;
CardStatus.icon_speed = 1;
CardStatus.comment_addr = 2048;
CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
default: /*** Loading ***/
if (!CardFileExists (filename,CARDSLOT))
{
WaitPrompt ("No SRAM File Found");
CARD_Unmount (CARDSLOT);
return 0;
}
/*** And write the blocks out ***/
sbo = 0;
while (outbytes > 0)
{
CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo);
outbytes -= SectorSize;
sbo += SectorSize;
}
memset (&CardFile, 0, sizeof (CardFile));
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
if (CardError)
{
sprintf (action, "Error Open : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
CARD_Close (&CardFile);
CARD_Unmount (CARDSLOT);
sram.crc = crc32 (0, &sram.sram[0], 0x10000);
sprintf (action, "Saved %d bytes successfully", blocks);
WaitPrompt (action);
return 1;
blocks = CardFile.len;
if (blocks < SectorSize) blocks = SectorSize;
if (blocks % SectorSize) blocks++;
default: /*** Loading ***/
if (!CardFileExists (filename,CARDSLOT))
{
WaitPrompt ("No SRAM File Found");
CARD_Unmount (CARDSLOT);
return 0;
}
/*** Just read the file back in ***/
sbo = 0;
int size = blocks;
while (blocks > 0)
{
CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo);
sbo += SectorSize;
blocks -= SectorSize;
}
CARD_Close (&CardFile);
CARD_Unmount (CARDSLOT);
memset (&CardFile, 0, sizeof (CardFile));
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
if (CardError)
{
sprintf (action, "Error Open : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
/* Copy to SRAM */
memcpy(&inzipped,&savebuffer[2112],sizeof(inzipped));
outzipped = 0x10000;
uncompress ((Bytef *) &sram.sram, &outzipped, (Bytef *) &savebuffer[2112+sizeof(inzipped)], inzipped);
sram.crc = crc32 (0, &sram.sram[0], 0x10000);
system_reset ();
blocks = CardFile.len;
if (blocks < SectorSize) blocks = SectorSize;
if (blocks % SectorSize) blocks++;
/*** Inform user ***/
sprintf (action, "Loaded %d bytes successfully", size);
WaitPrompt (action);
return 1;
}
}
else WaitPrompt ("Unable to mount memory card");
return 0; /*** Signal failure ***/
/*** Just read the file back in ***/
sbo = 0;
int size = blocks;
while (blocks > 0)
{
CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo);
sbo += SectorSize;
blocks -= SectorSize;
}
CARD_Close (&CardFile);
CARD_Unmount (CARDSLOT);
/* Copy to SRAM */
memcpy(&inzipped,&savebuffer[2112],sizeof(inzipped));
outzipped = 0x10000;
uncompress ((Bytef *) &sram.sram, &outzipped, (Bytef *) &savebuffer[2112+sizeof(inzipped)], inzipped);
sram.crc = crc32 (0, &sram.sram[0], 0x10000);
system_reset ();
/*** Inform user ***/
sprintf (action, "Loaded %d bytes successfully", size);
WaitPrompt (action);
return 1;
}
}
else WaitPrompt ("Unable to mount memory card");
return 0; /*** Signal failure ***/
}
/****************************************************************************
@ -412,174 +415,174 @@ int ManageSRAM (u8 direction, u8 device)
****************************************************************************/
int ManageState (u8 direction, u8 device)
{
char filename[128];
char action[80];
int CardError;
unsigned int SectorSize;
int blocks;
char comment[2][32] = { {"Genesis Plus 1.2a [FRZ]"}, {"Freeze State"} };
int outbytes = 0;
int sbo;
int state_size = 0;
char filename[128];
char action[80];
int CardError;
unsigned int SectorSize;
int blocks;
char comment[2][32] = { {"Genesis Plus 1.2a [FRZ]"}, {"Freeze State"} };
int outbytes = 0;
int sbo;
int state_size = 0;
if (!genromsize) return 0;
if (!genromsize) return 0;
/* clean buffer */
memset(savebuffer, 0, 0x24000);
/* clean buffer */
memset(savebuffer, 0, 0x24000);
if (direction) ShowAction ("Loading State ...");
else ShowAction ("Saving State ...");
else ShowAction ("Saving State ...");
/* First, build a filename */
sprintf (filename, "MD-%04X.gpz", realchecksum);
strcpy (comment[1], filename);
/* First, build a filename */
sprintf (filename, "MD-%04X.gpz", realchecksum);
strcpy (comment[1], filename);
/* device is SDCARD, let's go */
if (device == 0) return SD_ManageFile(filename,direction,0);
/* device is SDCARD, let's go */
if (device == 0) return SD_ManageFile(filename,direction,0);
/* set MCARD slot nr. */
u8 CARDSLOT = device - 1;
/* device is MCARD, we continue */
if (direction == 0) /* Saving */
{
/* Build the output buffer */
memcpy (&savebuffer, &icon, 2048);
memcpy (&savebuffer[2048], &comment[0], 64);
state_size = state_save(&savebuffer[2112]);
}
/* device is MCARD, we continue */
if (direction == 0) /* Saving */
{
/* Build the output buffer */
memcpy (&savebuffer, &icon, 2048);
memcpy (&savebuffer[2048], &comment[0], 64);
state_size = state_save(&savebuffer[2112]);
}
outbytes = 2048 + 64 + state_size;
outbytes = 2048 + 64 + state_size;
/*** Initialise the CARD system ***/
memset (&SysArea, 0, CARD_WORKAREA);
CARD_Init ("GENP", "00");
/*** Initialise the CARD system ***/
memset (&SysArea, 0, CARD_WORKAREA);
CARD_Init ("GENP", "00");
/*** Attempt to mount the card ***/
CardError = MountTheCard (CARDSLOT);
/*** Attempt to mount the card ***/
CardError = MountTheCard (CARDSLOT);
if (CardError)
{
/*** Retrieve the sector size ***/
CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize);
if (CardError)
{
/*** Retrieve the sector size ***/
CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize);
switch (direction)
{
case 0: /*** Saving ***/
/*** Determine number of blocks on this card ***/
blocks = (outbytes / SectorSize) * SectorSize;
if (outbytes % SectorSize) blocks += SectorSize;
switch (direction)
{
case 0: /*** Saving ***/
/*** Determine number of blocks on this card ***/
blocks = (outbytes / SectorSize) * SectorSize;
if (outbytes % SectorSize) blocks += SectorSize;
/*** Check if a previous save exists ***/
if (CardFileExists (filename, CARDSLOT))
{
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
if (CardError)
{
sprintf (action, "Error Open : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
/*** Check if a previous save exists ***/
if (CardFileExists (filename, CARDSLOT))
{
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
if (CardError)
{
sprintf (action, "Error Open : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
int size = CardFile.len;
CARD_Close (&CardFile);
int size = CardFile.len;
CARD_Close (&CardFile);
if (size < blocks)
{
/* new size is bigger: check if there is enough space left */
CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile);
if (CardError)
{
sprintf (action, "Error Update : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
CARD_Close (&CardFile);
CARD_Delete(CARDSLOT, "TEMP");
}
if (size < blocks)
{
/* new size is bigger: check if there is enough space left */
CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile);
if (CardError)
{
sprintf (action, "Error Update : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
CARD_Close (&CardFile);
CARD_Delete(CARDSLOT, "TEMP");
}
/* always delete existing slot */
CARD_Delete(CARDSLOT, filename);
}
/* always delete existing slot */
CARD_Delete(CARDSLOT, filename);
}
/*** Create a new slot ***/
CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile);
if (CardError)
{
sprintf (action, "Error create : %d %d", CardError, CARDSLOT);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
/*** Continue and save ***/
CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
CardStatus.icon_addr = 0x0;
CardStatus.icon_fmt = 2;
CardStatus.icon_speed = 1;
CardStatus.comment_addr = 2048;
CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
/*** Create a new slot ***/
CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile);
if (CardError)
{
sprintf (action, "Error create : %d %d", CardError, CARDSLOT);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
/*** Continue and save ***/
CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
CardStatus.icon_addr = 0x0;
CardStatus.icon_fmt = 2;
CardStatus.icon_speed = 1;
CardStatus.comment_addr = 2048;
CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
/*** And write the blocks out ***/
sbo = 0;
while (outbytes > 0)
{
CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo);
outbytes -= SectorSize;
sbo += SectorSize;
}
/*** And write the blocks out ***/
sbo = 0;
while (outbytes > 0)
{
CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo);
outbytes -= SectorSize;
sbo += SectorSize;
}
CARD_Close (&CardFile);
CARD_Unmount (CARDSLOT);
sprintf (action, "Saved %d bytes successfully", blocks);
WaitPrompt (action);
return 1;
CARD_Close (&CardFile);
CARD_Unmount (CARDSLOT);
sprintf (action, "Saved %d bytes successfully", blocks);
WaitPrompt (action);
return 1;
default: /*** Loading ***/
if (!CardFileExists (filename, CARDSLOT))
{
WaitPrompt ("No Savestate Found");
CARD_Unmount (CARDSLOT);
return 0;
}
default: /*** Loading ***/
if (!CardFileExists (filename, CARDSLOT))
{
WaitPrompt ("No Savestate Found");
CARD_Unmount (CARDSLOT);
return 0;
}
memset (&CardFile, 0, sizeof (CardFile));
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
if (CardError)
{
sprintf (action, "Error Open : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
memset (&CardFile, 0, sizeof (CardFile));
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
if (CardError)
{
sprintf (action, "Error Open : %d", CardError);
WaitPrompt (action);
CARD_Unmount (CARDSLOT);
return 0;
}
blocks = CardFile.len;
if (blocks < SectorSize) blocks = SectorSize;
if (blocks % SectorSize) blocks++;
blocks = CardFile.len;
if (blocks < SectorSize) blocks = SectorSize;
if (blocks % SectorSize) blocks++;
/*** Just read the file back in ***/
sbo = 0;
int size = blocks;
while (blocks > 0)
{
CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo);
sbo += SectorSize;
blocks -= SectorSize;
}
CARD_Close (&CardFile);
CARD_Unmount (CARDSLOT);
/*** Just read the file back in ***/
sbo = 0;
int size = blocks;
while (blocks > 0)
{
CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo);
sbo += SectorSize;
blocks -= SectorSize;
}
CARD_Close (&CardFile);
CARD_Unmount (CARDSLOT);
/*** Load State ***/
state_load(&savebuffer[2112]);
/*** Load State ***/
state_load(&savebuffer[2112]);
/*** Inform user ***/
sprintf (action, "Loaded %d bytes successfully", size);
WaitPrompt (action);
return 1;
}
}
else WaitPrompt ("Unable to mount memory card");
return 0; /*** Signal failure ***/
/*** Inform user ***/
sprintf (action, "Loaded %d bytes successfully", size);
WaitPrompt (action);
return 1;
}
}
else WaitPrompt ("Unable to mount memory card");
return 0; /*** Signal failure ***/
}

View File

@ -28,6 +28,8 @@
#include <di/di.h>
#endif
#include <fat.h>
int Shutdown = 0;
#ifdef HW_RVL
@ -46,11 +48,14 @@ void Power_Off(void)
***************************************************************************/
static void load_bios()
{
char pathname[MAXPATHLEN];
/* reset BIOS found flag */
config.bios_enabled &= ~2;
/* open file */
FILE *fp = fopen("/genplus/BIOS.bin", "rb");
sprintf (pathname, "%s/BIOS.bin", DEFAULT_PATH);
FILE *fp = fopen(pathname, "rb");
if (fp == NULL) return;
/* read file */
@ -113,12 +118,12 @@ void reloadrom ()
***************************************************************************/
int FramesPerSecond = 0;
int frameticker = 0;
bool use_FAT = 0;
bool fat_enabled = 0;
int main (int argc, char *argv[])
{
#ifdef HW_RVL
/* initialize Wii DVD interface first */
/* initialize Wii DVD interface first */
DI_Close();
DI_Init();
#endif
@ -127,7 +132,7 @@ int main (int argc, char *argv[])
long long now, prev;
int RenderedFrameCount = 0;
int FrameCount = 0;
/* Initialize OGC subsystems */
ogc_video__init();
ogc_input__init();
@ -147,7 +152,7 @@ int main (int argc, char *argv[])
/* Initialize FAT Interface */
if (fatInitDefault() == true)
{
use_FAT = 1;
fat_enabled = 1;
}
/* Default Config */
@ -172,11 +177,11 @@ int main (int argc, char *argv[])
legal();
MainMenu();
ConfigRequested = 0;
/* Initialize Frame timings */
frameticker = 0;
prev = gettime();
/* Emulation Loop */
while (1)
{
@ -202,7 +207,7 @@ int main (int argc, char *argv[])
system_frame(0);
RenderedFrameCount++;
}
}
}
else
{
/* use VSync */
@ -223,11 +228,11 @@ int main (int argc, char *argv[])
frameticker--;
}
/* update video & audio */
ogc_video__update();
ogc_audio__update();
/* Check rendered frames (FPS) */
FrameCount++;
if (FrameCount == vdp_rate)
@ -236,17 +241,17 @@ int main (int argc, char *argv[])
RenderedFrameCount = 0;
FrameCount = 0;
}
/* Check for Menu request */
if (ConfigRequested)
{
/* reset AUDIO */
ogc_audio__reset();
/* go to menu */
MainMenu ();
ConfigRequested = 0;
/* reset frame timings */
frameticker = 0;
prev = gettime();

View File

@ -24,7 +24,7 @@
/* global datas */
unsigned char soundbuffer[16][3840] ATTRIBUTE_ALIGN(32);
int mixbuffer = 0;
int mixbuffer = 0;
static int playbuffer = 0;
static int IsPlaying = 0;
@ -42,14 +42,14 @@ static void AudioSwitchBuffers()
IsPlaying = 0;
return;
}
u32 dma_len = (vdp_pal) ? 3840 : 3200;
/* restart audio DMA with current soundbuffer */
AUDIO_InitDMA((u32) soundbuffer[playbuffer], dma_len);
DCFlushRange(soundbuffer[playbuffer], dma_len);
AUDIO_StartDMA();
/* increment soundbuffers index */
if (playbuffer == mixbuffer)
{
@ -65,10 +65,10 @@ static void AudioSwitchBuffers()
void ogc_audio__init(void)
{
AUDIO_Init (NULL);
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
AUDIO_RegisterDMACallback (AudioSwitchBuffers);
memset(soundbuffer, 0, 16 * 3840);
AUDIO_Init (NULL);
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
AUDIO_RegisterDMACallback (AudioSwitchBuffers);
memset(soundbuffer, 0, 16 * 3840);
}
void ogc_audio__reset(void)

View File

@ -77,9 +77,9 @@ static int held_cnt = 0;
static u32 wpad_dirmap[3][4] =
{
{WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, // WIIMOTE only
{WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, // WIIMOTE + NUNCHUK
{WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT} // CLASSIC
{WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, /* WIIMOTE only */
{WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, /* WIIMOTE + NUNCHUK */
{WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT} /* CLASSIC */
};
/* wiimote/expansion available buttons */
@ -581,7 +581,7 @@ void ogc_input__init(void)
#ifdef HW_RVL
WPAD_Init();
WPAD_SetIdleTimeout(60);
WPAD_SetIdleTimeout(60);
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
#endif
@ -763,7 +763,7 @@ u16 ogc_input__getMenuButtons(void)
s8 y = PAD_StickY(0);
if (x > 70) p |= PAD_BUTTON_RIGHT;
else if (x < -70) p |= PAD_BUTTON_LEFT;
if (y > 60) p |= PAD_BUTTON_UP;
if (y > 60) p |= PAD_BUTTON_UP;
else if (y < -60) p |= PAD_BUTTON_DOWN;
#ifdef HW_RVL
@ -853,7 +853,7 @@ u16 ogc_input__getMenuButtons(void)
if (q & WPAD_CLASSIC_BUTTON_B) p |= PAD_BUTTON_B;
if (q & WPAD_CLASSIC_BUTTON_HOME) p |= PAD_TRIGGER_Z;
#endif
#endif
return p;
}

View File

@ -35,10 +35,10 @@ sms_ntsc_t sms_ntsc;
int gc_pal = 0;
/*** VI ***/
unsigned int *xfb[2]; /*** Double buffered ***/
int whichfb = 0; /*** External framebuffer index ***/
GXRModeObj *vmode; /*** Menu video mode ***/
u8 *texturemem; /*** Texture Data ***/
unsigned int *xfb[2]; /*** Double buffered ***/
int whichfb = 0; /*** External framebuffer index ***/
GXRModeObj *vmode; /*** Menu video mode ***/
u8 *texturemem; /*** Texture Data ***/
/*** GX ***/
#define TEX_WIDTH 360 * 2
@ -57,12 +57,12 @@ static u32 vwidth, vheight;
/* 288 lines progressive (PAL 50Hz) */
GXRModeObj TV50hz_288p =
{
VI_TVMODE_PAL_DS, // viDisplayMode
VI_TVMODE_PAL_DS,// viDisplayMode
640, // fbWidth
286, // efbHeight
286, // xfbHeight
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2, // viYOrigin
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2,// viYOrigin
720, // viWidth
572, // viHeight
VI_XFBMODE_SF, // xFBmode
@ -70,34 +70,34 @@ GXRModeObj TV50hz_288p =
GX_FALSE, // aa
// sample points arranged in increasing Y order
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
// vertical filter[7], 1/64 units, 6 bits each
{
0, // line n-1
0, // line n-1
21, // line n
22, // line n
21, // line n
0, // line n+1
0 // line n+1
}
{
0, // line n-1
0, // line n-1
21, // line n
22, // line n
21, // line n
0, // line n+1
0 // line n+1
}
};
/* 288 lines interlaced (PAL 50Hz) */
GXRModeObj TV50hz_288i =
{
VI_TVMODE_PAL_INT, // viDisplayMode
640, // fbWidth
286, // efbHeight
286, // xfbHeight
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2, // viYOrigin
VI_TVMODE_PAL_INT,// viDisplayMode
640, // fbWidth
286, // efbHeight
286, // xfbHeight
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2,// viYOrigin
720, // viWidth
572, // viHeight
VI_XFBMODE_SF, // xFBmode
@ -105,34 +105,34 @@ GXRModeObj TV50hz_288i =
GX_FALSE, // aa
// sample points arranged in increasing Y order
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
// vertical filter[7], 1/64 units, 6 bits each
{
0, // line n-1
0, // line n-1
21, // line n
22, // line n
21, // line n
0, // line n+1
0 // line n+1
}
{
0, // line n-1
0, // line n-1
21, // line n
22, // line n
21, // line n
0, // line n+1
0 // line n+1
}
};
/* 576 lines interlaced (PAL 50Hz, scaled) */
GXRModeObj TV50hz_576i =
{
VI_TVMODE_PAL_INT, // viDisplayMode
VI_TVMODE_PAL_INT,// viDisplayMode
640, // fbWidth
480, // efbHeight
574, // xfbHeight
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_PAL - 574)/2, // viYOrigin
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_PAL - 574)/2,// viYOrigin
720, // viWidth
574, // viHeight
VI_XFBMODE_DF, // xFBmode
@ -140,34 +140,34 @@ GXRModeObj TV50hz_576i =
GX_FALSE, // aa
// sample points arranged in increasing Y order
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
// vertical filter[7], 1/64 units, 6 bits each
{
8, // line n-1
8, // line n-1
10, // line n
12, // line n
10, // line n
8, // line n+1
8 // line n+1
}
{
8, // line n-1
8, // line n-1
10, // line n
12, // line n
10, // line n
8, // line n+1
8 // line n+1
}
};
/* 240 lines progressive (NTSC or PAL 60Hz) */
GXRModeObj TV60hz_240p =
{
VI_TVMODE_EURGB60_DS, // viDisplayMode
VI_TVMODE_EURGB60_DS,// viDisplayMode
640, // fbWidth
240, // efbHeight
240, // xfbHeight
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
720, // viWidth
480, // viHeight
VI_XFBMODE_SF, // xFBmode
@ -175,34 +175,34 @@ GXRModeObj TV60hz_240p =
GX_FALSE, // aa
// sample points arranged in increasing Y order
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
// vertical filter[7], 1/64 units, 6 bits each
{
0, // line n-1
0, // line n-1
21, // line n
22, // line n
21, // line n
0, // line n+1
0 // line n+1
}
{
0, // line n-1
0, // line n-1
21, // line n
22, // line n
21, // line n
0, // line n+1
0 // line n+1
}
};
/* 240 lines interlaced (NTSC or PAL 60Hz) */
GXRModeObj TV60hz_240i =
{
VI_TVMODE_EURGB60_INT, // viDisplayMode
VI_TVMODE_EURGB60_INT,// viDisplayMode
640, // fbWidth
240, // efbHeight
240, // xfbHeight
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
720, // viWidth
480, // viHeight
VI_XFBMODE_SF, // xFBmode
@ -210,34 +210,34 @@ GXRModeObj TV60hz_240i =
GX_FALSE, // aa
// sample points arranged in increasing Y order
{
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{3,2},{9,6},{3,10}, // pix 1
{9,2},{3,6},{9,10}, // pix 2
{9,2},{3,6},{9,10} // pix 3
},
{
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{3,2},{9,6},{3,10}, // pix 1
{9,2},{3,6},{9,10}, // pix 2
{9,2},{3,6},{9,10} // pix 3
},
// vertical filter[7], 1/64 units, 6 bits each
{
0, // line n-1
0, // line n-1
21, // line n
22, // line n
21, // line n
0, // line n+1
0 // line n+1
}
{
0, // line n-1
0, // line n-1
21, // line n
22, // line n
21, // line n
0, // line n+1
0 // line n+1
}
};
/* 480 lines interlaced (NTSC or PAL 60Hz) */
GXRModeObj TV60hz_480i =
{
VI_TVMODE_EURGB60_INT, // viDisplayMode
VI_TVMODE_EURGB60_INT,// viDisplayMode
640, // fbWidth
480, // efbHeight
480, // xfbHeight
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
(VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
720, // viWidth
480, // viHeight
VI_XFBMODE_DF, // xFBmode
@ -245,29 +245,29 @@ GXRModeObj TV60hz_480i =
GX_FALSE, // aa
// sample points arranged in increasing Y order
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
{
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
{6,6},{6,6},{6,6}, // pix 1
{6,6},{6,6},{6,6}, // pix 2
{6,6},{6,6},{6,6} // pix 3
},
// vertical filter[7], 1/64 units, 6 bits each
{
8, // line n-1
8, // line n-1
10, // line n
12, // line n
10, // line n
8, // line n+1
8 // line n+1
}
{
8, // line n-1
8, // line n-1
10, // line n
12, // line n
10, // line n
8, // line n+1
8 // line n+1
}
};
/* TV Modes table */
GXRModeObj *tvmodes[6] = {
&TV60hz_240p, &TV60hz_240i, &TV60hz_480i, /* 60hz modes */
&TV50hz_288p, &TV50hz_288i, &TV50hz_576i /* 50Hz modes */
&TV60hz_240p, &TV60hz_240i, &TV60hz_480i, /* 60hz modes */
&TV50hz_288p, &TV50hz_288i, &TV50hz_576i /* 50Hz modes */
};
typedef struct tagcamera
@ -279,7 +279,7 @@ typedef struct tagcamera
/*** Square Matrix
This structure controls the size of the image on the screen.
Think of the output as a -80 x 80 by -60 x 60 graph.
Think of the output as a -80 x 80 by -60 x 60 graph.
***/
static s16 square[] ATTRIBUTE_ALIGN (32) =
{
@ -287,10 +287,10 @@ static s16 square[] ATTRIBUTE_ALIGN (32) =
* X, Y, Z
* Values set are for roughly 4:3 aspect
*/
-HASPECT, VASPECT, 0, // 0
HASPECT, VASPECT, 0, // 1
HASPECT, -VASPECT, 0, // 2
-HASPECT, -VASPECT, 0, // 3
-HASPECT, VASPECT, 0, // 0
HASPECT, VASPECT, 0, // 1
HASPECT, -VASPECT, 0, // 2
-HASPECT, -VASPECT, 0, // 3
};
static camera cam = {
@ -402,23 +402,23 @@ static void gxScale(GXRModeObj *rmode)
/* original aspect ratio */
/* the following values have been detected from comparison with a real 50/60hz Mega Drive */
if (config.overscan)
{
{
/* borders are emulated */
xscale = 358 + ((reg[12] & 1)*2) - gc_pal;
xscale = 358 + ((reg[12] & 1)*2) - gc_pal;
yscale = vdp_pal + ((gc_pal && !config.render) ? 143 : 120);
}
else
{
/* borders are simulated (black) */
xscale = 325 + ((reg[12] & 1)*2) - gc_pal;
xscale = 325 + ((reg[12] & 1)*2) - gc_pal;
yscale = bitmap.viewport.h / 2;
if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 240 / 288;
else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 240;
if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 240 / 288;
else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 240;
}
xshift = config.xshift;
yshift = 2 - vdp_pal + 2*(gc_pal & !config.render) + config.yshift;
}
}
else
{
/* manual aspect ratio (default is fullscreen) */
@ -440,8 +440,8 @@ static void gxScale(GXRModeObj *rmode)
yscale += config.yscale;
xshift = config.xshift;
yshift = config.yshift;
}
yshift = config.yshift;
}
/* Double resolution modes */
if (config.render)
@ -488,9 +488,9 @@ static void gxScale(GXRModeObj *rmode)
/* update GX scaler (Vertex Position Matrix) */
square[6] = square[3] = xscale + xshift;
square[0] = square[9] = -xscale + xshift;
square[0] = square[9] = -xscale + xshift;
square[4] = square[1] = yscale + yshift;
square[7] = square[10] = -yscale + yshift;
square[7] = square[10] = -yscale + yshift;
DCFlushRange (square, 32);
GX_InvVtxCache ();
@ -499,7 +499,7 @@ static void gxScale(GXRModeObj *rmode)
/* Reinitialize Video */
void ogc_video__reset()
{
Mtx p;
Mtx p;
GXRModeObj *rmode;
/* 50Hz/60Hz mode */
@ -522,18 +522,18 @@ void ogc_video__reset()
/* Set current TV mode */
if (config.render) rmode = tvmodes[gc_pal*3 + 2];
else rmode = tvmodes[gc_pal*3 + interlaced];
else rmode = tvmodes[gc_pal*3 + interlaced];
/* Aspect ratio */
gxScale(rmode);
/* Configure VI */
VIDEO_Configure (rmode);
VIDEO_ClearFrameBuffer(rmode, xfb[whichfb], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
VIDEO_ClearFrameBuffer(rmode, xfb[whichfb], COLOR_BLACK);
VIDEO_Flush();
VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
/* Configure GX */
GX_SetViewport (0.0F, 0.0F, rmode->fbWidth, rmode->efbHeight, 0.0F, 1.0F);
@ -596,7 +596,7 @@ void ogc_video__update()
ogc_video__reset();
/* reinitialize texture */
GX_InitTexObj (&texobj, texturemem, vwidth * 4, vheight * 4, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObj (&texobj, texturemem, vwidth * 4, vheight * 4, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
/* enable/disable bilinear filtering */
if (!config.bilinear)

View File

@ -10,7 +10,6 @@
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <fat.h>
#include <sys/dir.h>
#include "ogc_input.h"
@ -19,6 +18,8 @@
#include "config.h"
#include "history.h"
#define DEFAULT_PATH "/genplus"
#define update_input() ogc_input__update()
/* globals */

View File

@ -63,7 +63,7 @@ static uint32 make_lut_bgobj_ste(uint32 bx, uint32 sx);
static __inline__ uint32 READ_LONG(void *address)
{
if ((uint32)address & 3)
{
{
#ifdef LSB_FIRST /* little endian version */
return ( *((uint8 *)address) +
(*((uint8 *)address+1) << 8) +
@ -75,14 +75,14 @@ static __inline__ uint32 READ_LONG(void *address)
(*((uint8 *)address+1) << 16) +
(*((uint8 *)address) << 24) );
#endif /* LSB_FIRST */
}
else return *(uint32 *)address;
}
else return *(uint32 *)address;
}
static __inline__ void WRITE_LONG(void *address, uint32 data)
{
if ((uint32)address & 3)
{
{
#ifdef LSB_FIRST
*((uint8 *)address) = data;
*((uint8 *)address+1) = (data >> 8);
@ -94,9 +94,9 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
*((uint8 *)address+1) = (data >> 16);
*((uint8 *)address) = (data >> 24);
#endif /* LSB_FIRST */
return;
}
else *(uint32 *)address = data;
return;
}
else *(uint32 *)address = data;
}
#endif /* ALIGN_LONG */
@ -112,26 +112,26 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
N = Pattern Number (11 bits)
MSB PCCVHNNN NNNNNNNN LSB PCCVHNNN NNNNNNNN LSB
PATTERN1 PATTERN2
PATTERN1 PATTERN2
Pattern attributes are read from VRAM as 32bits WORD like this:
LIT_ENDIAN: ATTR is MSB PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN LSB
PATTERN2 PATTERN1
PATTERN2 PATTERN1
BIG_ENDIAN: ATTR is MSB PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN LSB
PATTERN1 PATTERN2
PATTERN1 PATTERN2
Each Line Buffer written byte describe one pixel data like this:
msb SPppcccc lsb
msb SPppcccc lsb
with:
S = sprite data indicator (not written here)
P = priority bit (from Pattern Attribute)
p = color palette (from Pattern Attribute)
c = color data (from Pattern Cache)
with:
S = sprite data indicator (not written here)
P = priority bit (from Pattern Attribute)
p = color palette (from Pattern Attribute)
c = color data (from Pattern Cache)
A column is 2 patterns wide
@ -141,11 +141,11 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
/* Draw a single 8-pixel column */
/*
pattern cache is addressed like this: 00000VHN NNNNNNNN NNYYYXXX
with : Y = pattern row (1-8 lines)
X = pattern column (1-8 pixels)
V = Vertical Flip bit
H = Horizontal Flip bit
N = Pattern Number (1-2048)
with : Y = pattern row (1-8 lines)
X = pattern column (1-8 pixels)
V = Vertical Flip bit
H = Horizontal Flip bit
N = Pattern Number (1-2048)
*/
#ifdef ALIGN_LONG
#ifdef LSB_FIRST
@ -170,7 +170,7 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
#else
#define DRAW_COLUMN(ATTR, LINE) \
attr_msb = ATTR >> 16; \
atex = atex_table[(ATTR_MSB >> 13) & 7]; \
atex = atex_table[(ATTR_MSB >> 13) & 7]; \
src = (uint32 *)&bg_pattern_cache[(ATTR_MSB & 0x1FFF) << 6 | (LINE)]; \
WRITE_LONG(dst, READ_LONG(src) | atex); \
dst++; \
@ -202,7 +202,7 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
#else
#define DRAW_COLUMN(ATTR, LINE) \
attr_msb = ATTR >> 16; \
atex = atex_table[(attr_msb >> 13) & 7]; \
atex = atex_table[(attr_msb >> 13) & 7]; \
src = (uint32 *)&bg_pattern_cache[(attr_msb & 0x1FFF) << 6 | (LINE)]; \
*dst++ = (*src++ | atex); \
*dst++ = (*src++ | atex); \
@ -217,11 +217,11 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
/* Draw a single 16-pixel column */
/*
pattern cache is addressed like this: 00000VHN NNNNNNNN NYYYYXXX
with : Y = pattern row (1-16 lines)
X = pattern column (1-8 pixels)
V = Vertical Flip bit
H = Horizontal Flip bit
N = Pattern Number (1-1024)
with : Y = pattern row (1-16 lines)
X = pattern column (1-8 pixels)
V = Vertical Flip bit
H = Horizontal Flip bit
N = Pattern Number (1-1024)
one pattern line is 8 pixels = 8 bytes = 2 * 32 bits
*/
@ -252,7 +252,7 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
#else
#define DRAW_COLUMN_IM2(ATTR, LINE) \
attr_msb = ATTR >> 16; \
atex = atex_table[(attr_msb >> 13) & 7]; \
atex = atex_table[(attr_msb >> 13) & 7]; \
offs = (attr_msb & 0x03FF) << 7 | (attr_msb & 0x1800) << 6 | (LINE); \
if(attr_msb & 0x1000) offs ^= 0x40; \
src = (uint32 *)&bg_pattern_cache[offs]; \
@ -318,11 +318,11 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
check if non-transparent sprite data has been previously drawn
*/
#define DRAW_SPRITE_TILE \
for(i=0; i<8; i++) \
{ \
if ((lb[i] & 0x80) && (lb[i] & 0x0F) && (src[i] & 0x0F)) status |= 0x20; \
lb[i] = table[(lb[i] << 8) |(src[i] | palette)]; \
}
for(i=0; i<8; i++) \
{ \
if ((lb[i] & 0x80) && (lb[i] & 0x0F) && (src[i] & 0x0F)) status |= 0x20; \
lb[i] = table[(lb[i] << 8) |(src[i] | palette)]; \
}
/* Pixel creation macros, input is four bits each */
@ -387,11 +387,11 @@ static uint16 pixel_16[0x100];
static uint16 pixel_16_lut[3][0x200];
/* Line buffers */
static uint8 tmp_buf[0x400]; /* Temporary buffer */
static uint8 bg_buf[0x400]; /* Merged background buffer */
static uint8 nta_buf[0x400]; /* Plane A / Window line buffer */
static uint8 ntb_buf[0x400]; /* Plane B line buffer */
static uint8 obj_buf[0x400]; /* Object layer line buffer */
static uint8 tmp_buf[0x400]; /* Temporary buffer */
static uint8 bg_buf[0x400]; /* Merged background buffer */
static uint8 nta_buf[0x400]; /* Plane A / Window line buffer */
static uint8 ntb_buf[0x400]; /* Plane B line buffer */
static uint8 obj_buf[0x400]; /* Object layer line buffer */
/* Sprite line buffer data */
static uint32 object_index_count;
@ -401,8 +401,8 @@ static uint32 object_index_count;
this is used to convert 3bits RGB values to 5bits (R,B) or 6bits (G) values
there is three color modes:
normal: RGB range is [0;MAX]
half: RGB range is [0;MAX/2] (shadow mode)
high: RGB range is [MAX/2;MAX] (highlight mode)
half: RGB range is [0;MAX/2] (shadow mode)
high: RGB range is [MAX/2;MAX] (highlight mode)
MAX is 31 (R,B) or 63 (G) for 5:6:5 pixels and 7 (R,G,B) for 3:3:3 pixels
MAX/2 is rounded to inferior value (15, 31 or 3)
@ -410,59 +410,59 @@ static uint32 object_index_count;
the extrapolation is linear and calculated like this:
for (i=0; i<8; i++)
{
rgb565_norm[0][i] = round(((double)i * 31.0) / 7.0);
rgb565_norm[1][i] = round(((double)i * 63.0) / 7.0);
rgb565_half[0][i] = round(((double)i * 31.0) / 7.0 / 2.0);
rgb565_half[1][i] = round(((double)i * 63.0) / 7.0 / 2.0);
rgb565_high[0][i] = round(((double)i * 31.0) / 7.0 / 2.0 + 15.5);
rgb565_high[1][i] = round(((double)i * 63.0) / 7.0 / 2.0 + 31.5);
}
{
rgb565_norm[0][i] = round(((double)i * 31.0) / 7.0);
rgb565_norm[1][i] = round(((double)i * 63.0) / 7.0);
rgb565_half[0][i] = round(((double)i * 31.0) / 7.0 / 2.0);
rgb565_half[1][i] = round(((double)i * 63.0) / 7.0 / 2.0);
rgb565_high[0][i] = round(((double)i * 31.0) / 7.0 / 2.0 + 15.5);
rgb565_high[1][i] = round(((double)i * 63.0) / 7.0 / 2.0 + 31.5);
}
*/
uint8 rgb565_norm[2][8] = {{0 , 4, 9, 13, 18, 22, 27, 31},
{0 , 9, 18, 27, 36, 45, 54, 63}};
{0 , 9, 18, 27, 36, 45, 54, 63}};
uint8 rgb565_half[2][8] = {{0 , 2, 4, 6, 9, 11, 13, 15},
{0 , 4, 9, 13, 18, 22, 27, 31}};
{0 , 4, 9, 13, 18, 22, 27, 31}};
uint8 rgb565_high[2][8] = {{15, 17, 19, 21, 24, 26, 28, 31},
{31, 35, 40, 44, 49, 53, 58, 63}};
{31, 35, 40, 44, 49, 53, 58, 63}};
void palette_init(void)
{
int i;
int i;
for (i = 0; i < 0x200; i += 1)
{
int r, g, b;
for (i = 0; i < 0x200; i += 1)
{
int r, g, b;
r = (i >> 6) & 7;
g = (i >> 3) & 7;
b = (i >> 0) & 7;
r = (i >> 6) & 7;
g = (i >> 3) & 7;
b = (i >> 0) & 7;
#ifndef NGC
pixel_8_lut[0][i] = MAKE_PIXEL_8(r>>1,g>>1,b>>1);
pixel_8_lut[1][i] = MAKE_PIXEL_8(r,g,b);
pixel_8_lut[2][i] = MAKE_PIXEL_8((r>>1)|4,(g>>1)|4,(b>>1)|4);
pixel_8_lut[0][i] = MAKE_PIXEL_8(r>>1,g>>1,b>>1);
pixel_8_lut[1][i] = MAKE_PIXEL_8(r,g,b);
pixel_8_lut[2][i] = MAKE_PIXEL_8((r>>1)|4,(g>>1)|4,(b>>1)|4);
pixel_15_lut[0][i] = MAKE_PIXEL_15(r,g,b);
pixel_15_lut[1][i] = MAKE_PIXEL_15(r<<1,g<<1,b<<1);
pixel_15_lut[2][i] = MAKE_PIXEL_15(r|8,g|8,b|8);
pixel_15_lut[0][i] = MAKE_PIXEL_15(r,g,b);
pixel_15_lut[1][i] = MAKE_PIXEL_15(r<<1,g<<1,b<<1);
pixel_15_lut[2][i] = MAKE_PIXEL_15(r|8,g|8,b|8);
pixel_32_lut[0][i] = MAKE_PIXEL_32(r,g,b);
pixel_32_lut[1][i] = MAKE_PIXEL_32(r<<1,g<<1,b<<1);
pixel_32_lut[2][i] = MAKE_PIXEL_32(r|8,g|8,b|8);
pixel_32_lut[0][i] = MAKE_PIXEL_32(r,g,b);
pixel_32_lut[1][i] = MAKE_PIXEL_32(r<<1,g<<1,b<<1);
pixel_32_lut[2][i] = MAKE_PIXEL_32(r|8,g|8,b|8);
#endif
/* RGB 565 format: we extrapolate each 3-bit value into a 5-bit (R,B) or 6-bit (G) value
this is needed to correctly cover full color range: [0-31] for R,B or [0-63] for G */
pixel_16_lut[0][i] = MAKE_PIXEL_16(rgb565_half[0][r],rgb565_half[1][g],rgb565_half[0][b]);
pixel_16_lut[1][i] = MAKE_PIXEL_16(rgb565_norm[0][r],rgb565_norm[1][g],rgb565_norm[0][b]);
pixel_16_lut[2][i] = MAKE_PIXEL_16(rgb565_high[0][r],rgb565_high[1][g],rgb565_high[0][b]);
}
/* RGB 565 format: we extrapolate each 3-bit value into a 5-bit (R,B) or 6-bit (G) value
this is needed to correctly cover full color range: [0-31] for R,B or [0-63] for G */
pixel_16_lut[0][i] = MAKE_PIXEL_16(rgb565_half[0][r],rgb565_half[1][g],rgb565_half[0][b]);
pixel_16_lut[1][i] = MAKE_PIXEL_16(rgb565_norm[0][r],rgb565_norm[1][g],rgb565_norm[0][b]);
pixel_16_lut[2][i] = MAKE_PIXEL_16(rgb565_high[0][r],rgb565_high[1][g],rgb565_high[0][b]);
}
}
/*--------------------------------------------------------------------------*/
@ -471,75 +471,75 @@ void palette_init(void)
int render_init (void)
{
int bx, ax, i;
int bx, ax, i;
/* Allocate and align pixel look-up tables */
if (lut_base == NULL) lut_base = malloc ((LUT_MAX * LUT_SIZE) + LUT_SIZE);
lut[0] = (uint8 *) (((uint32) lut_base + LUT_SIZE) & ~(LUT_SIZE - 1));
for (i = 1; i < LUT_MAX; i += 1) lut[i] = lut[0] + (i * LUT_SIZE);
/* Allocate and align pixel look-up tables */
if (lut_base == NULL) lut_base = malloc ((LUT_MAX * LUT_SIZE) + LUT_SIZE);
lut[0] = (uint8 *) (((uint32) lut_base + LUT_SIZE) & ~(LUT_SIZE - 1));
for (i = 1; i < LUT_MAX; i += 1) lut[i] = lut[0] + (i * LUT_SIZE);
/* Make pixel look-up table data */
for (bx = 0; bx < 0x100; bx += 1)
for (ax = 0; ax < 0x100; ax += 1)
{
uint16 index = (bx << 8) | (ax);
lut[0][index] = make_lut_bg (bx, ax);
lut[1][index] = make_lut_obj (bx, ax);
lut[2][index] = make_lut_bg_ste (bx, ax);
lut[3][index] = make_lut_obj_ste (bx, ax);
lut[4][index] = make_lut_bgobj_ste (bx, ax);
}
/* Make pixel look-up table data */
for (bx = 0; bx < 0x100; bx += 1)
for (ax = 0; ax < 0x100; ax += 1)
{
uint16 index = (bx << 8) | (ax);
lut[0][index] = make_lut_bg (bx, ax);
lut[1][index] = make_lut_obj (bx, ax);
lut[2][index] = make_lut_bg_ste (bx, ax);
lut[3][index] = make_lut_obj_ste (bx, ax);
lut[4][index] = make_lut_bgobj_ste (bx, ax);
}
/* Make pixel data tables */
palette_init();
/* Make pixel data tables */
palette_init();
/* Set up color update function */
/* Set up color update function */
#ifndef NGC
switch(bitmap.depth)
{
case 8: color_update = color_update_8; break;
case 15: color_update = color_update_15; break;
case 16: color_update = color_update_16; break;
case 32: color_update = color_update_32; break;
}
switch(bitmap.depth)
{
case 8: color_update = color_update_8; break;
case 15: color_update = color_update_15; break;
case 16: color_update = color_update_16; break;
case 32: color_update = color_update_32; break;
}
#else
color_update = color_update_16;
color_update = color_update_16;
#endif
/* Make sprite name look-up table */
make_name_lut();
/* Make sprite name look-up table */
make_name_lut();
return (1);
return (1);
}
void make_name_lut(void)
{
int col, row;
int vcol, vrow;
int width, height;
int flipx, flipy;
int i, name;
int col, row;
int vcol, vrow;
int width, height;
int flipx, flipy;
int i, name;
memset (name_lut, 0, sizeof (name_lut));
memset (name_lut, 0, sizeof (name_lut));
for (i = 0; i < 0x400; i += 1)
{
vcol = col = i & 3;
vrow = row = (i >> 2) & 3;
height = (i >> 4) & 3;
width = (i >> 6) & 3;
flipx = (i >> 8) & 1;
flipy = (i >> 9) & 1;
for (i = 0; i < 0x400; i += 1)
{
vcol = col = i & 3;
vrow = row = (i >> 2) & 3;
height = (i >> 4) & 3;
width = (i >> 6) & 3;
flipx = (i >> 8) & 1;
flipy = (i >> 9) & 1;
if(flipx) vcol = (width - col);
if(flipy) vrow = (height - row);
if(flipx) vcol = (width - col);
if(flipy) vrow = (height - row);
name = vrow + (vcol * (height + 1));
name = vrow + (vcol * (height + 1));
if ((row > height) || col > width) name = -1;
if ((row > height) || col > width) name = -1;
name_lut[i] = name;
}
name_lut[i] = name;
}
}
void render_reset(void)
@ -547,7 +547,7 @@ void render_reset(void)
/* Clear display bitmap */
memset(bitmap.data, 0, bitmap.pitch * bitmap.height);
memset(&clip, 0, sizeof(clip));
memset(&clip, 0, sizeof(clip));
memset(bg_buf, 0, sizeof(bg_buf));
memset(tmp_buf, 0, sizeof(tmp_buf));
memset(nta_buf, 0, sizeof(nta_buf));
@ -555,7 +555,7 @@ void render_reset(void)
memset(obj_buf, 0, sizeof(obj_buf));
#ifndef NGC
memset(&pixel_8, 0, sizeof(pixel_8));
memset(&pixel_8, 0, sizeof(pixel_8));
memset(&pixel_15, 0, sizeof(pixel_15));
memset(&pixel_32, 0, sizeof(pixel_32));
#endif
@ -580,10 +580,10 @@ static inline void update_bg_pattern_cache(uint32 index)
uint8 *dst;
uint32 bp;
#ifdef LSB_FIRST
uint8 shift_table[8] = {12, 8, 4, 0, 28, 24, 20, 16};
uint8 shift_table[8] = {12, 8, 4, 0, 28, 24, 20, 16};
#else
uint8 shift_table[8] = {28, 24, 20, 16, 12, 8, 4, 0};
#endif
uint8 shift_table[8] = {28, 24, 20, 16, 12, 8, 4, 0};
#endif
for(i = 0; i < index; i ++)
{
@ -599,11 +599,11 @@ static inline void update_bg_pattern_cache(uint32 index)
for(x = 0; x < 8; x ++)
{
c = (bp >> shift_table[x]) & 0x0F;
dst[0x00000 | (y << 3) | (x)] = (c); /* hf=0, vf=0: normal */
dst[0x20000 | (y << 3) | (x ^ 7)] = (c); /* hf=1, vf=0: horizontal flipped */
dst[0x40000 | ((y ^ 7) << 3) | (x)] = (c); /* hf=0, vf=1: vertical flipped */
dst[0x60000 | ((y ^ 7) << 3) | (x ^ 7)] = (c); /* hf=1, vf=1: horizontal & vertical flipped */
c = (bp >> shift_table[x]) & 0x0F;
dst[0x00000 | (y << 3) | (x)] = (c); /* hf=0, vf=0: normal */
dst[0x20000 | (y << 3) | (x ^ 7)] = (c); /* hf=1, vf=0: horizontal flipped */
dst[0x40000 | ((y ^ 7) << 3) | (x)] = (c); /* hf=0, vf=1: vertical flipped */
dst[0x60000 | ((y ^ 7) << 3) | (x ^ 7)] = (c); /* hf=1, vf=1: horizontal & vertical flipped */
}
}
}
@ -751,7 +751,7 @@ void remap_buffer(uint32 line, uint32 width)
else sms_ntsc_blit(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
return;
}
#ifdef NGC
/* directly fill the RGB565 texture */
/* one tile is 32 byte = 4x4 pixels */
@ -764,17 +764,17 @@ void remap_buffer(uint32 line, uint32 width)
void *out =((void *)&bitmap.data[(line * bitmap.pitch)]);
switch(bitmap.depth)
{
case 8:
remap_8(tmp_buf+0x20-bitmap.viewport.x, (uint8 *)out, pixel_8, width);
break;
case 8:
remap_8(tmp_buf+0x20-bitmap.viewport.x, (uint8 *)out, pixel_8, width);
break;
case 15:
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_15, width);
break;
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_15, width);
break;
case 16:
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_16, width);
break;
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_16, width);
break;
case 32:
remap_32(tmp_buf+0x20-bitmap.viewport.x, (uint32 *)out, pixel_32, width);
remap_32(tmp_buf+0x20-bitmap.viewport.x, (uint32 *)out, pixel_32, width);
break;
}
#endif
@ -782,16 +782,16 @@ void remap_buffer(uint32 line, uint32 width)
void render_line(uint32 line, uint32 overscan)
{
uint32 width = bitmap.viewport.w;
uint32 width = bitmap.viewport.w;
uint32 x_offset = bitmap.viewport.x;
/* background color (display OFF or borders) */
/* background color (display OFF or borders) */
if (overscan || !(reg[1] & 0x40))
{
width += 2 * x_offset;
memset(&tmp_buf[0x20 - x_offset], 0x40, width);
}
else
memset(&tmp_buf[0x20 - x_offset], 0x40, width);
}
else
{
uint8 *lb = tmp_buf;
@ -910,17 +910,17 @@ static void render_bg(uint32 line, uint32 width)
uint32 y_scroll = (line + (vs[0] & 0x3FF)) & pf_row_mask;
#endif
uint32 v_line = (y_scroll & 7) << 3;
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
uint32 v_line = (y_scroll & 7) << 3;
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
if(shift)
{
dst = (uint32 *)&buf[0x10 + shift];
dst = (uint32 *)&buf[0x10 + shift];
atbuf = nt[(index-1) & pf_col_mask];
DRAW_COLUMN(atbuf, v_line);
DRAW_COLUMN(atbuf, v_line);
}
dst = (uint32 *)&buf[0x20 + shift];
dst = (uint32 *)&buf[0x20 + shift];
for(column = 0; column < end; column ++, index ++)
{
atbuf = nt[index & pf_col_mask];
@ -991,7 +991,7 @@ static void render_bg(uint32 line, uint32 width)
if (w)
{
v_line = (line & 7) << 3;
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
dst = (uint32 *)&buf[0x20 + (start << 4)];
for(column = start; column < end; column ++)
{
@ -1029,19 +1029,19 @@ static void render_bg_vs(uint32 line, uint32 width)
uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
#endif
uint32 y_scroll, v_line, *nt;
uint32 y_scroll, v_line, *nt;
if(shift)
if(shift)
{
y_scroll = (line & pf_row_mask);
v_line = (y_scroll & 7) << 3;
nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
dst = (uint32 *)&buf[0x10 + shift];
dst = (uint32 *)&buf[0x10 + shift];
atbuf = nt[(index-1) & pf_col_mask];
DRAW_COLUMN(atbuf, v_line);
DRAW_COLUMN(atbuf, v_line);
}
dst = (uint32 *)&buf[0x20 + shift];
dst = (uint32 *)&buf[0x20 + shift];
for(column = start; column < end; column ++, index ++)
{
#ifdef LSB_FIRST
@ -1108,7 +1108,7 @@ static void render_bg_vs(uint32 line, uint32 width)
y_scroll = (line + (vs[column] & 0x3FF)) & pf_row_mask;
#else
y_scroll = (line + ((vs[column] >> 16) & 0x3FF)) & pf_row_mask;
#endif
#endif
v_line = (y_scroll & 7) << 3;
nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
atbuf = nt[index & pf_col_mask];
@ -1124,7 +1124,7 @@ static void render_bg_vs(uint32 line, uint32 width)
if (w)
{
v_line = (line & 7) << 3;
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
dst = (uint32 *)&buf[0x20 + (start << 4)];
for(column = start; column < end; column ++)
{
@ -1164,17 +1164,17 @@ static void render_bg_im2(uint32 line, uint32 width, uint32 odd)
uint32 y_scroll = (line + ((vs[0] >> 1) & 0x3FF)) & pf_row_mask; /* IM2 specific */
#endif
uint32 v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
uint32 v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
if(shift)
{
dst = (uint32 *)&buf[0x10 + shift];
dst = (uint32 *)&buf[0x10 + shift];
atbuf = nt[(index-1) & pf_col_mask];
DRAW_COLUMN_IM2(atbuf, v_line); /* IM2 specific */
DRAW_COLUMN_IM2(atbuf, v_line); /* IM2 specific */
}
dst = (uint32 *)&buf[0x20 + shift];
dst = (uint32 *)&buf[0x20 + shift];
for(column = 0; column < end; column ++, index ++)
{
atbuf = nt[index & pf_col_mask];
@ -1215,18 +1215,18 @@ static void render_bg_im2(uint32 line, uint32 width, uint32 odd)
y_scroll = (line + ((vs[0] >> 17) & 0x3FF)) & pf_row_mask; /* IM2 specific */
#endif
v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
if(shift)
{
dst = (uint32 *)&buf[0x10 + shift + (start<<4)];
dst = (uint32 *)&buf[0x10 + shift + (start<<4)];
/* Window bug */
if (start) atbuf = nt[index & pf_col_mask];
/* Window bug */
if (start) atbuf = nt[index & pf_col_mask];
else atbuf = nt[(index-1) & pf_col_mask];
DRAW_COLUMN_IM2(atbuf, v_line); /* IM2 specific */
DRAW_COLUMN_IM2(atbuf, v_line); /* IM2 specific */
}
dst = (uint32 *)&buf[0x20 + shift + (start<<4)];
@ -1245,7 +1245,7 @@ static void render_bg_im2(uint32 line, uint32 width, uint32 odd)
if (w)
{
v_line = ((line & 7) << 1 | odd) << 3; /* IM2 specific */
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
dst = (uint32 *)&buf[0x20 + (start << 4)];
for(column = start; column < end; column ++)
{
@ -1612,23 +1612,23 @@ void parse_satb(uint32 line)
{
ypos = (q[link] >> im2_flag) & 0x1FF;
size = q[link + 1] >> 8;
height = sizetab[size & 3];
height = sizetab[size & 3];
if((line >= ypos) && (line < (ypos + height)))
{
/* sprite limit (max. 16 or 20 sprites displayed per line) */
if(object_index_count == limit)
if(object_index_count == limit)
{
if(vint_pending == 0) status |= 0x40;
return;
}
// using xpos from internal satb stops sprite x
// using xpos from internal satb stops sprite x
// scrolling in bloodlin.bin,
// but this seems to go against the test prog
object_info[object_index_count].attr = p[link + 2];
object_info[object_index_count].attr = p[link + 2];
object_info[object_index_count].xpos = p[link + 3];
object_info[object_index_count].ypos = ypos;
object_info[object_index_count].ypos = ypos;
object_info[object_index_count].size = size;
++object_index_count;
}
@ -1668,14 +1668,14 @@ static void render_obj(uint32 line, uint8 *buf, uint8 *table)
xpos = object_info[count].xpos & 0x1ff;
/* sprite masking */
if(xpos != 0) sol_flag = 1;
else if(xpos == 0 && sol_flag) return;
if(xpos != 0) sol_flag = 1;
else if(xpos == 0 && sol_flag) return;
size = object_info[count].size & 0x0f;
width = sizetab[(size >> 2) & 3];
width = sizetab[(size >> 2) & 3];
/* update pixel count (off-screen sprites included) */
pixelcount += width;
/* update pixel count (off-screen sprites included) */
pixelcount += width;
if(((xpos + width) >= left) && (xpos < right))
{
@ -1695,10 +1695,10 @@ static void render_obj(uint32 line, uint8 *buf, uint8 *table)
lb = (uint8 *)&buf[0x20 + (xpos - 0x80)];
/* number of tiles to draw */
/* adjusted for sprite limit */
/* number of tiles to draw */
/* adjusted for sprite limit */
if (pixelcount > bitmap.viewport.w) width -= (pixelcount - bitmap.viewport.w);
width >>= 3;
width >>= 3;
for(column = 0; column < width; column += 1, lb+=8)
{
@ -1709,8 +1709,8 @@ static void render_obj(uint32 line, uint8 *buf, uint8 *table)
}
/* sprite limit (256 or 320 pixels) */
if (pixelcount >= bitmap.viewport.w) return;
/* sprite limit (256 or 320 pixels) */
if (pixelcount >= bitmap.viewport.w) return;
}
}
@ -1741,20 +1741,20 @@ static void render_obj_im2(uint32 line, uint32 odd, uint8 *buf, uint8 *table)
int attr_mask, nt_row;
for(count = 0; count < object_index_count; count += 1)
for(count = 0; count < object_index_count; count += 1)
{
xpos = object_info[count].xpos & 0x1ff;
/* sprite masking */
if(xpos != 0) sol_flag = 1;
else if(xpos == 0 && sol_flag) return;
/* sprite masking */
if(xpos != 0) sol_flag = 1;
else if(xpos == 0 && sol_flag) return;
size = object_info[count].size & 0x0f;
width = sizetab[(size >> 2) & 3];
/* update pixel count (off-screen sprites included) */
pixelcount += width;
/* update pixel count (off-screen sprites included) */
pixelcount += width;
if(((xpos + width) >= left) && (xpos < right))
{
ypos = object_info[count].ypos;
@ -1773,10 +1773,10 @@ static void render_obj_im2(uint32 line, uint32 odd, uint8 *buf, uint8 *table)
lb = (uint8 *)&buf[0x20 + (xpos - 0x80)];
/* number of tiles to draw */
/* adjusted for sprite limit */
/* number of tiles to draw */
/* adjusted for sprite limit */
if (pixelcount > bitmap.viewport.w) width -= (pixelcount - bitmap.viewport.w);
width >>= 3;
width >>= 3;
for(column = 0; column < width; column += 1, lb+=8)
{
@ -1788,8 +1788,8 @@ static void render_obj_im2(uint32 line, uint32 odd, uint8 *buf, uint8 *table)
}
}
/* sprite limit (256 or 320 pixels) */
if (pixelcount >= bitmap.viewport.w) return;
/* sprite limit (256 or 320 pixels) */
if (pixelcount >= bitmap.viewport.w) return;
}
}

View File

@ -27,163 +27,163 @@ static unsigned int bufferptr;
static inline void load_param(void *param, unsigned int size)
{
memcpy(param, &state[bufferptr], size);
bufferptr+= size;
memcpy(param, &state[bufferptr], size);
bufferptr+= size;
}
static inline void save_param(void *param, unsigned int size)
{
memcpy(&state[bufferptr], param, size);
bufferptr+= size;
memcpy(&state[bufferptr], param, size);
bufferptr+= size;
}
void state_load(unsigned char *buffer)
{
/* reset buffer pointer */
bufferptr = 0;
/* reset buffer pointer */
bufferptr = 0;
/* uncompress savestate */
unsigned long inbytes, outbytes;
memcpy(&inbytes, buffer, 4);
outbytes = 0x24000;
memcpy(&inbytes, buffer, 4);
outbytes = 0x24000;
uncompress ((Bytef *)state, &outbytes, (Bytef *)(buffer + 4), inbytes);
/* reset system */
system_reset();
m68k_memory_map[0].base = default_rom;
/* reset system */
system_reset();
m68k_memory_map[0].base = default_rom;
// GENESIS
load_param(work_ram, sizeof(work_ram));
load_param(zram, sizeof(zram));
load_param(&zbusreq, sizeof(zbusreq));
load_param(&zreset, sizeof(zreset));
load_param(&zbank, sizeof(zbank));
zbusack = 1 ^(zbusreq & zreset);
// GENESIS
load_param(work_ram, sizeof(work_ram));
load_param(zram, sizeof(zram));
load_param(&zbusreq, sizeof(zbusreq));
load_param(&zreset, sizeof(zreset));
load_param(&zbank, sizeof(zbank));
zbusack = 1 ^(zbusreq & zreset);
// IO
load_param(io_reg, sizeof(io_reg));
// VDP
uint8 temp_reg[0x20];
load_param(sat, sizeof(sat));
load_param(vram, sizeof(vram));
load_param(cram, sizeof(cram));
load_param(vsram, sizeof(vsram));
load_param(temp_reg, sizeof(temp_reg));
load_param(&addr, sizeof(addr));
load_param(&addr_latch, sizeof(addr_latch));
load_param(&code, sizeof(code));
load_param(&pending, sizeof(pending));
load_param(&status, sizeof(status));
load_param(&dmafill, sizeof(dmafill));
load_param(&hint_pending, sizeof(hint_pending));
load_param(&vint_pending, sizeof(vint_pending));
load_param(&irq_status, sizeof(irq_status));
vdp_restore(temp_reg);
// IO
load_param(io_reg, sizeof(io_reg));
// FM
load_param(fm_reg,sizeof(fm_reg));
fm_restore();
// VDP
uint8 temp_reg[0x20];
load_param(sat, sizeof(sat));
load_param(vram, sizeof(vram));
load_param(cram, sizeof(cram));
load_param(vsram, sizeof(vsram));
load_param(temp_reg, sizeof(temp_reg));
load_param(&addr, sizeof(addr));
load_param(&addr_latch, sizeof(addr_latch));
load_param(&code, sizeof(code));
load_param(&pending, sizeof(pending));
load_param(&status, sizeof(status));
load_param(&dmafill, sizeof(dmafill));
load_param(&hint_pending, sizeof(hint_pending));
load_param(&vint_pending, sizeof(vint_pending));
load_param(&irq_status, sizeof(irq_status));
vdp_restore(temp_reg);
// PSG
load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
// FM
load_param(fm_reg,sizeof(fm_reg));
fm_restore();
// 68000
uint16 tmp16;
uint32 tmp32;
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32);
load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32);
// PSG
load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
// Z80
load_param(&Z80, sizeof(Z80_Regs));
// 68000
uint16 tmp16;
uint32 tmp32;
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32);
load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16);
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32);
// Z80
load_param(&Z80, sizeof(Z80_Regs));
}
int state_save(unsigned char *buffer)
{
/* reset buffer pointer */
bufferptr = 0;
/* reset buffer pointer */
bufferptr = 0;
// GENESIS
save_param(work_ram, sizeof(work_ram));
save_param(zram, sizeof(zram));
save_param(&zbusreq, sizeof(zbusreq));
save_param(&zreset, sizeof(zreset));
save_param(&zbank, sizeof(zbank));
// GENESIS
save_param(work_ram, sizeof(work_ram));
save_param(zram, sizeof(zram));
save_param(&zbusreq, sizeof(zbusreq));
save_param(&zreset, sizeof(zreset));
save_param(&zbank, sizeof(zbank));
// IO
save_param(io_reg, sizeof(io_reg));
// VDP
save_param(sat, sizeof(sat));
save_param(vram, sizeof(vram));
save_param(cram, sizeof(cram));
save_param(vsram, sizeof(vsram));
save_param(reg, sizeof(reg));
save_param(&addr, sizeof(addr));
save_param(&addr_latch, sizeof(addr_latch));
save_param(&code, sizeof(code));
save_param(&pending, sizeof(pending));
save_param(&status, sizeof(status));
save_param(&dmafill, sizeof(dmafill));
save_param(&hint_pending, sizeof(hint_pending));
save_param(&vint_pending, sizeof(vint_pending));
save_param(&irq_status, sizeof(irq_status));
// IO
save_param(io_reg, sizeof(io_reg));
// FM
save_param(fm_reg,sizeof(fm_reg));
// VDP
save_param(sat, sizeof(sat));
save_param(vram, sizeof(vram));
save_param(cram, sizeof(cram));
save_param(vsram, sizeof(vsram));
save_param(reg, sizeof(reg));
save_param(&addr, sizeof(addr));
save_param(&addr_latch, sizeof(addr_latch));
save_param(&code, sizeof(code));
save_param(&pending, sizeof(pending));
save_param(&status, sizeof(status));
save_param(&dmafill, sizeof(dmafill));
save_param(&hint_pending, sizeof(hint_pending));
save_param(&vint_pending, sizeof(vint_pending));
save_param(&irq_status, sizeof(irq_status));
// PSG
save_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
// FM
save_param(fm_reg,sizeof(fm_reg));
// 68000
uint16 tmp16;
uint32 tmp32;
tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D5); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D6); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D7); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A0); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A1); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A2); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A3); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A4); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A5); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A6); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4);
tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2);
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
// PSG
save_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
// Z80
save_param(&Z80, sizeof(Z80_Regs));
// 68000
uint16 tmp16;
uint32 tmp32;
tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D5); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D6); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_D7); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A0); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A1); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A2); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A3); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A4); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A5); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A6); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4);
tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4);
tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2);
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
/* compress state file */
unsigned long inbytes = bufferptr;
// Z80
save_param(&Z80, sizeof(Z80_Regs));
/* compress state file */
unsigned long inbytes = bufferptr;
unsigned long outbytes = 0x26000;
compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9);
memcpy(buffer, &outbytes, 4);
memcpy(buffer, &outbytes, 4);
/* return total size */
return (outbytes + 4);
/* return total size */
return (outbytes + 4);
}

View File

@ -49,13 +49,13 @@ static inline void audio_update (void);
****************************************************************/
void system_init (void)
{
/* PAL/NTSC timings */
vdp_rate = vdp_pal ? 50 : 60;
lines_per_frame = vdp_pal ? 313 : 262;
gen_init ();
vdp_init ();
render_init ();
/* PAL/NTSC timings */
vdp_rate = vdp_pal ? 50 : 60;
lines_per_frame = vdp_pal ? 313 : 262;
gen_init ();
vdp_init ();
render_init ();
cart_hw_init();
}
@ -64,30 +64,30 @@ void system_init (void)
****************************************************************/
void system_reset (void)
{
aim_m68k = 0;
count_m68k = 0;
line_m68k = 0;
aim_z80 = 0;
count_z80 = 0;
line_z80 = 0;
current_z80 = 0;
odd_frame = 0;
interlaced = 0;
aim_m68k = 0;
count_m68k = 0;
line_m68k = 0;
aim_z80 = 0;
count_z80 = 0;
line_z80 = 0;
current_z80 = 0;
odd_frame = 0;
interlaced = 0;
/* Cart Hardware reset */
cart_hw_reset();
/* Cart Hardware reset */
cart_hw_reset();
/* Hard reset */
gen_reset (1);
vdp_reset ();
render_reset ();
io_reset();
SN76489_Reset(0);
/* Hard reset */
gen_reset (1);
vdp_reset ();
render_reset ();
io_reset();
SN76489_Reset(0);
/* Sound buffers reset */
memset (snd.psg.buffer, 0, SND_SIZE);
memset (snd.fm.buffer[0], 0, SND_SIZE*2);
memset (snd.fm.buffer[1], 0, SND_SIZE*2);
/* Sound buffers reset */
memset (snd.psg.buffer, 0, SND_SIZE);
memset (snd.fm.buffer[0], 0, SND_SIZE*2);
memset (snd.fm.buffer[1], 0, SND_SIZE*2);
}
/****************************************************************
@ -95,9 +95,9 @@ void system_reset (void)
****************************************************************/
void system_shutdown (void)
{
gen_shutdown ();
vdp_shutdown ();
render_shutdown ();
gen_shutdown ();
vdp_shutdown ();
render_shutdown ();
}
/****************************************************************
@ -105,19 +105,19 @@ void system_shutdown (void)
****************************************************************/
int system_frame (int do_skip)
{
if (!gen_running)
if (!gen_running)
{
update_input();
return 0;
}
/* reset cycles counts */
count_m68k = 0;
aim_m68k = 0;
aim_z80 = 0;
count_z80 = 0;
fifo_write_cnt = 0;
fifo_lastwrite = 0;
}
/* reset cycles counts */
count_m68k = 0;
aim_m68k = 0;
aim_z80 = 0;
count_z80 = 0;
fifo_write_cnt = 0;
fifo_lastwrite = 0;
/* update display settings */
int line;
@ -125,48 +125,48 @@ int system_frame (int do_skip)
int vdp_height = bitmap.viewport.h;
int end_line = vdp_height + bitmap.viewport.y;
int start_line = lines_per_frame - bitmap.viewport.y;
int old_interlaced = interlaced;
int old_interlaced = interlaced;
interlaced = (reg[12] & 2) >> 1;
if (old_interlaced != interlaced)
if (old_interlaced != interlaced)
{
bitmap.viewport.changed = 2;
bitmap.viewport.changed = 2;
im2_flag = ((reg[12] & 6) == 6);
odd_frame = 1;
}
odd_frame = 1;
}
odd_frame ^= 1;
/* clear VBLANK and DMA flags */
status &= 0xFFF5;
/* even/odd field flag (interlaced modes only) */
if (odd_frame && interlaced) status |= 0x0010;
else status &= 0xFFEF;
/* reload HCounter */
int h_counter = reg[10];
/* reload HCounter */
int h_counter = reg[10];
/* parse sprites for line 0 (done on last line) */
parse_satb (0x80);
parse_satb (0x80);
/* process frame */
for (line = 0; line < lines_per_frame; line ++)
{
/* process frame */
for (line = 0; line < lines_per_frame; line ++)
{
/* update VCounter */
v_counter = line;
v_counter = line;
/* update 6-Buttons or Menacer */
input_update();
/* update 6-Buttons or Menacer */
input_update();
/* update CPU cycle counters */
/* update CPU cycle counters */
hint_m68k = count_m68k;
line_m68k = aim_m68k;
line_z80 = aim_z80;
line_z80 = aim_z80;
aim_z80 += z80cycles_per_line;
aim_m68k += m68cycles_per_line;
/* Soft Reset ? */
if (line == reset)
/* Soft Reset ? */
if (line == reset)
{
#ifdef NGC
/* wait for RESET button to be released */
@ -177,14 +177,14 @@ int system_frame (int do_skip)
/* active display */
if (line <= vdp_height)
{
/* H Interrupt */
{
/* H Interrupt */
if(--h_counter < 0)
{
h_counter = reg[10];
hint_pending = 1;
{
h_counter = reg[10];
hint_pending = 1;
if (reg[0] & 0x10) irq_status = (irq_status & 0xff) | 0x14;
/* adjust timings to take further decrement in account (see below) */
if ((line != 0) || (h_counter == 0)) aim_m68k += 36;
}
@ -198,9 +198,9 @@ int system_frame (int do_skip)
/* update DMA timings */
if (dma_length) dma_update();
/* vertical retrace */
/* vertical retrace */
if (line == vdp_height)
{
{
/* render overscan */
if ((line < end_line) && (!do_skip)) render_line(line, 1);
@ -211,9 +211,9 @@ int system_frame (int do_skip)
status |= 0x08;
/* Z80 interrupt is 16ms period (one frame) and 64us length (one scanline) */
zirq = 1;
z80_set_irq_line(0, ASSERT_LINE);
zirq = 1;
z80_set_irq_line(0, ASSERT_LINE);
/* delay between HINT, VBLANK and VINT (Dracula, OutRunners, VR Troopers) */
m68k_run(line_m68k + 84);
if (zreset && !zbusreq)
@ -223,7 +223,7 @@ int system_frame (int do_skip)
}
else count_z80 = line_z80 + 39;
/* V Interrupt */
/* V Interrupt */
status |= 0x80;
vint_pending = 1;
@ -235,7 +235,7 @@ int system_frame (int do_skip)
/* render scanline and parse sprites for line n+1 */
render_line(line, 0);
if (line < (vdp_height-1)) parse_satb(0x81 + line);
}
}
}
else
{
@ -253,57 +253,57 @@ int system_frame (int do_skip)
}
}
/* process line */
m68k_run(aim_m68k);
if (zreset == 1 && zbusreq == 0)
/* process line */
m68k_run(aim_m68k);
if (zreset == 1 && zbusreq == 0)
{
current_z80 = aim_z80 - count_z80;
if (current_z80 > 0) count_z80 += z80_execute(current_z80);
}
else count_z80 = aim_z80;
/* SVP chip */
if (svp) ssp1601_run(SVP_cycles);
}
}
else count_z80 = aim_z80;
/* SVP chip */
if (svp) ssp1601_run(SVP_cycles);
}
audio_update ();
return gen_running;
audio_update ();
return gen_running;
}
/****************************************************************
* Audio System
* Audio System
****************************************************************/
int audio_init (int rate)
{
/* Shutdown first */
/* Shutdown first */
audio_shutdown();
/* Clear the sound data context */
memset (&snd, 0, sizeof (snd));
/* Clear the sound data context */
memset (&snd, 0, sizeof (snd));
/* Make sure the requested sample rate is valid */
if (!rate || ((rate < 8000) | (rate > 48000))) return (-1);
snd.sample_rate = rate;
/* Calculate the sound buffer size (for one frame) */
snd.buffer_size = (rate / vdp_rate);
/* Make sure the requested sample rate is valid */
if (!rate || ((rate < 8000) | (rate > 48000))) return (-1);
snd.sample_rate = rate;
/* Calculate the sound buffer size (for one frame) */
snd.buffer_size = (rate / vdp_rate);
#ifdef DOS
/* output buffers */
snd.buffer[0] = (int16 *) malloc(SND_SIZE);
snd.buffer[1] = (int16 *) malloc(SND_SIZE);
if (!snd.buffer[0] || !snd.buffer[1]) return (-1);
memset (snd.buffer[0], 0, SND_SIZE);
memset (snd.buffer[1], 0, SND_SIZE);
snd.buffer[1] = (int16 *) malloc(SND_SIZE);
if (!snd.buffer[0] || !snd.buffer[1]) return (-1);
memset (snd.buffer[0], 0, SND_SIZE);
memset (snd.buffer[1], 0, SND_SIZE);
#endif
/* YM2612 stream buffers */
snd.fm.buffer[0] = (int *)malloc (SND_SIZE*2);
snd.fm.buffer[1] = (int *)malloc (SND_SIZE*2);
if (!snd.fm.buffer[0] || !snd.fm.buffer[1]) return (-1);
memset (snd.fm.buffer[0], 0, SND_SIZE*2);
memset (snd.fm.buffer[1], 0, SND_SIZE*2);
snd.fm.buffer[1] = (int *)malloc (SND_SIZE*2);
if (!snd.fm.buffer[0] || !snd.fm.buffer[1]) return (-1);
memset (snd.fm.buffer[0], 0, SND_SIZE*2);
memset (snd.fm.buffer[1], 0, SND_SIZE*2);
/* SRC buffers */
if (config.hq_fm && !config.fm_core)
@ -312,23 +312,23 @@ int audio_init (int rate)
if (!snd.fm.src_out) return (-1);
}
/* SN76489 stream buffers */
/* SN76489 stream buffers */
snd.psg.buffer = (int16 *)malloc (SND_SIZE);
if (!snd.psg.buffer) return (-1);
memset (snd.psg.buffer, 0, SND_SIZE);
if (!snd.psg.buffer) return (-1);
memset (snd.psg.buffer, 0, SND_SIZE);
/* Set audio enable flag */
snd.enabled = 1;
/* Set audio enable flag */
snd.enabled = 1;
/* Initialize Sound Chips emulation */
sound_init(rate);
/* Initialize Sound Chips emulation */
sound_init(rate);
return (0);
return (0);
}
void audio_shutdown(void)
{
/* free sound buffers */
/* free sound buffers */
if (snd.buffer[0]) free(snd.buffer[0]);
if (snd.buffer[1]) free(snd.buffer[1]);
if (snd.fm.buffer[0]) free(snd.fm.buffer[0]);
@ -341,7 +341,7 @@ static int ll, rr;
static inline void audio_update (void)
{
int i;
int i;
int l, r;
double psg_preamp = config.psg_preamp;
double fm_preamp = config.fm_preamp;
@ -349,56 +349,56 @@ static inline void audio_update (void)
int filter = config.filter;
#ifndef DOS
int16 *sb = (int16 *) soundbuffer[mixbuffer];
int16 *sb = (int16 *) soundbuffer[mixbuffer];
#endif
/* get remaining samples */
sound_update();
/* get remaining samples */
sound_update();
/* mix samples */
for (i = 0; i < snd.buffer_size; i ++)
{
l = r = (int) ((double)snd.psg.buffer[i] * psg_preamp);
l += (int) ((double)snd.fm.buffer[0][i] * fm_preamp);
r += (int) ((double)snd.fm.buffer[1][i] * fm_preamp);
snd.fm.buffer[0][i] = 0;
snd.fm.buffer[1][i] = 0;
snd.psg.buffer[i] = 0;
/* mix samples */
for (i = 0; i < snd.buffer_size; i ++)
{
l = r = (int) ((double)snd.psg.buffer[i] * psg_preamp);
l += (int) ((double)snd.fm.buffer[0][i] * fm_preamp);
r += (int) ((double)snd.fm.buffer[1][i] * fm_preamp);
snd.fm.buffer[0][i] = 0;
snd.fm.buffer[1][i] = 0;
snd.psg.buffer[i] = 0;
/* single-pole low-pass filter (6 dB/octave) */
if (filter)
{
if (filter)
{
l = (ll + l) >> 1;
r = (rr + r) >> 1;
r = (rr + r) >> 1;
ll = l;
rr = r;
}
/* boost volume if asked*/
l = l * boost;
r = r * boost;
l = l * boost;
r = r * boost;
/* clipping */
if (l > 32767) l = 32767;
else if (l < -32768) l = -32768;
if (r > 32767) r = 32767;
else if (r < -32768) r = -32768;
/* clipping */
if (l > 32767) l = 32767;
else if (l < -32768) l = -32768;
if (r > 32767) r = 32767;
else if (r < -32768) r = -32768;
/* update sound buffer */
/* update sound buffer */
#ifdef DOS
snd.buffer[0][i] = l;
snd.buffer[1][i] = r;
snd.buffer[0][i] = l;
snd.buffer[1][i] = r;
#elif LSB_FIRST
*sb++ = l;
*sb++ = r;
*sb++ = l;
*sb++ = r;
#else
*sb++ = r;
*sb++ = l;
*sb++ = l;
#endif
}
}
#ifndef DOS
mixbuffer++;
mixbuffer &= 0xf;
mixbuffer++;
mixbuffer &= 0xf;
#endif
}

View File

@ -35,38 +35,38 @@
typedef struct
{
uint8 *data; /* Bitmap data */
int width; /* Bitmap width (32+512+32) */
int height; /* Bitmap height (256) */
int depth; /* Color depth (8 bits) */
int pitch; /* Width of bitmap in bytes */
int granularity; /* Size of each pixel in bytes */
int remap; /* 1= Translate pixel data */
uint8 *data; /* Bitmap data */
int width; /* Bitmap width (32+512+32) */
int height; /* Bitmap height (256) */
int depth; /* Color depth (8 bits) */
int pitch; /* Width of bitmap in bytes */
int granularity; /* Size of each pixel in bytes */
int remap; /* 1= Translate pixel data */
struct
{
int x; /* X offset of viewport within bitmap */
int y; /* Y offset of viewport within bitmap */
int w; /* Width of viewport */
int h; /* Height of viewport */
int ow; /* Previous width of viewport */
int oh; /* Previous height of viewport */
int changed; /* 1= Viewport width or height have changed */
int x; /* X offset of viewport within bitmap */
int y; /* Y offset of viewport within bitmap */
int w; /* Width of viewport */
int h; /* Height of viewport */
int ow; /* Previous width of viewport */
int oh; /* Previous height of viewport */
int changed; /* 1= Viewport width or height have changed */
} viewport;
} t_bitmap;
typedef struct
{
int sample_rate; /* Sample rate (8000-48000) */
int enabled; /* 1= sound emulation is enabled */
int buffer_size; /* Size of sound buffer (in bytes) */
int16 *buffer[2]; /* Signed 16-bit stereo sound data */
int sample_rate; /* Sample rate (8000-48000) */
int enabled; /* 1= sound emulation is enabled */
int buffer_size; /* Size of sound buffer (in bytes) */
int16 *buffer[2]; /* Signed 16-bit stereo sound data */
struct
{
int curStage;
int lastStage;
int *buffer[2];
float *src_out; /* SRC conversion buffer */
float *src_out; /* SRC conversion buffer */
} fm;
struct
{

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,8 @@
/* VDP context */
extern uint8 sat[0x400];
extern uint8 vram[0x10000];
extern uint8 cram[0x80];
extern uint8 vsram[0x80];
extern uint8 cram[0x80];
extern uint8 vsram[0x80];
extern uint8 reg[0x20];
extern uint16 addr;
extern uint16 addr_latch;
@ -41,20 +41,20 @@ extern uint8 vint_pending;
extern uint16 irq_status;
/* Global variables */
extern uint16 ntab;
extern uint16 ntbb;
extern uint16 ntwb;
extern uint16 satb;
extern uint16 hscb;
extern uint8 border;
extern uint8 bg_name_dirty[0x800];
extern uint16 bg_name_list[0x800];
extern uint16 bg_list_index;
extern uint16 ntab;
extern uint16 ntbb;
extern uint16 ntwb;
extern uint16 satb;
extern uint16 hscb;
extern uint8 border;
extern uint8 bg_name_dirty[0x800];
extern uint16 bg_name_list[0x800];
extern uint16 bg_list_index;
extern uint8 bg_pattern_cache[0x80000];
extern uint8 playfield_shift;
extern uint8 playfield_col_mask;
extern uint16 playfield_row_mask;
extern uint32 y_mask;
extern uint8 playfield_shift;
extern uint8 playfield_col_mask;
extern uint16 playfield_row_mask;
extern uint32 y_mask;
extern uint16 hc_latch;
extern uint16 v_counter;
extern uint8 im2_flag;