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) - 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) - 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 ;-) - fixed "Reset" button behavior, now acts more like Genesis Reset button ;-)
- minor bugfixes and menu tweaks - patched libfat for faster SDCARD accesses (thanks to svpe)
- compiled with libogc 1.7.0 - various bugfixes and menu tweaks
[NGC only] [NGC only]
- added 480p support in menu - added 480p support in menu
@ -34,7 +35,8 @@ Genesis Plus for Gamecube
[Wii only] [Wii only]
- implemented fast scrolling in menu using Wiimote D-PAD - implemented fast scrolling in menu using Wiimote D-PAD
- added "Power" button support - 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 GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 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 Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
Preamble Preamble
The licenses for most software are designed to take away your The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public 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 The precise terms and conditions for copying, distribution and
modification follow. modification follow.
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains 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 License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on does not normally print such an announcement, your work based on
the Program is not required to print an announcement.) the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program, identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in 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 access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not distribution of the source code, even though third parties are not
compelled to copy the source along with the object code. compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program 4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is 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 This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License. be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in 8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License 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 preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally. 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 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 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 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES. POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest 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 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.) */ /* H counter values for a 256-pixel wide display (342 pixel max.) */
uint8 hc_256[171] = { uint8 hc_256[171] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 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, 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, 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, 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, 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, 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, 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, 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, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x90, 0x91, 0x92, 0x93,
0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF 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.) */ /* H counter values for a 320-pixel wide display (442 pixels max.) */
uint8 hc_320[210] = { uint8 hc_320[210] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF 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) static inline void lightgun_reset(int num)
{ {
input.analog[num][0] = bitmap.viewport.w >> 1; input.analog[num][0] = bitmap.viewport.w >> 1;
input.analog[num][1] = bitmap.viewport.h >> 1; input.analog[num][1] = bitmap.viewport.h >> 1;
} }
static inline void lightgun_update(int num) static inline void lightgun_update(int num)
{ {
if ((input.analog[num][1] == v_counter + input.y_offset)) if ((input.analog[num][1] == v_counter + input.y_offset))
{ {
/* HL enabled ? */ /* HL enabled ? */
if (io_reg[5] & 0x80) if (io_reg[5] & 0x80)
{ {
/* External Interrupt ? */ /* External Interrupt ? */
if (reg[11] & 0x08) {irq_status &= 0xff; irq_status |= 0x12;} if (reg[11] & 0x08) {irq_status &= 0xff; irq_status |= 0x12;}
/* HVC Latch: /* HVC Latch:
1) some games does not set HVC latch but instead use bigger X offset 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, 2) for games using H40 mode, the gun routine scales up the Hcounter value,
H-Counter range is approx. 292 pixel clocks H-Counter range is approx. 292 pixel clocks
*/ */
hc_latch = 0x100; hc_latch = 0x100;
@ -90,19 +91,19 @@ static inline void lightgun_update(int num)
else else
hc_latch |= hc_256[(input.analog[num][0] / 2 + input.x_offset)%171]; hc_latch |= hc_256[(input.analog[num][0] / 2 + input.x_offset)%171];
} }
} }
} }
/* Sega Menacer specific */ /* Sega Menacer specific */
uint32 menacer_read() uint32 menacer_read()
{ {
/* pins should return 0 by default (fix Body Count when mouse is enabled) */ /* pins should return 0 by default (fix Body Count when mouse is enabled) */
int retval = 0x00; int retval = 0x00;
if (input.pad[4] & INPUT_B) retval |= 0x01; if (input.pad[4] & INPUT_B) retval |= 0x01;
if (input.pad[4] & INPUT_A) retval |= 0x02; if (input.pad[4] & INPUT_A) retval |= 0x02;
if (input.pad[4] & INPUT_C) retval |= 0x04; 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; return retval;
} }
@ -130,8 +131,8 @@ uint32 justifier_read()
return retval; return retval;
default: /* guns disabled */ default: /* guns disabled */
return retval; return retval;
} }
} }
/***************************************************************************** /*****************************************************************************
@ -148,8 +149,8 @@ struct mega_mouse
static inline void mouse_reset() static inline void mouse_reset()
{ {
mouse.State = 0x60; mouse.State = 0x60;
mouse.Counter = 0; mouse.Counter = 0;
mouse.Wait = 0; mouse.Wait = 0;
mouse.Port = (input.system[0] == SYSTEM_MOUSE) ? 0 : 4; mouse.Port = (input.system[0] == SYSTEM_MOUSE) ? 0 : 4;
} }
@ -267,19 +268,19 @@ struct pad
static inline void gamepad_raz(uint32 i) static inline void gamepad_raz(uint32 i)
{ {
gamepad[i].Counter = 0; gamepad[i].Counter = 0;
gamepad[i].Delay = 0; gamepad[i].Delay = 0;
} }
static inline void gamepad_reset(uint32 i) static inline void gamepad_reset(uint32 i)
{ {
gamepad[i].State = 0x40; gamepad[i].State = 0x40;
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i); if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
} }
static inline void gamepad_update(uint32 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) static inline uint32 gamepad_read(uint32 i)
@ -288,10 +289,10 @@ static inline uint32 gamepad_read(uint32 i)
int retval = 0x7F; int retval = 0x7F;
control = (gamepad[i].State & 0x40) >> 6; /* current TH state */ control = (gamepad[i].State & 0x40) >> 6; /* current TH state */
if (input.dev[i] == DEVICE_6BUTTON) 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) switch (control)
@ -299,7 +300,7 @@ static inline uint32 gamepad_read(uint32 i)
case 1: /*** First High ***/ case 1: /*** First High ***/
case 3: /*** Second High ***/ case 3: /*** Second High ***/
case 5: /*** Third High ***/ case 5: /*** Third High ***/
/* TH = 1 : ?1CBRLDU */ /* TH = 1 : ?1CBRLDU */
if (input.pad[i] & INPUT_C) retval &= ~0x20; if (input.pad[i] & INPUT_C) retval &= ~0x20;
if (input.pad[i] & INPUT_B) retval &= ~0x10; if (input.pad[i] & INPUT_B) retval &= ~0x10;
@ -311,7 +312,7 @@ static inline uint32 gamepad_read(uint32 i)
case 0: /*** First low ***/ case 0: /*** First low ***/
case 2: /*** Second low ***/ case 2: /*** Second low ***/
/* TH = 0 : ?0SA00DU */ /* TH = 0 : ?0SA00DU */
if (input.pad[i] & INPUT_A) retval &= ~0x10; if (input.pad[i] & INPUT_A) retval &= ~0x10;
if (input.pad[i] & INPUT_START) retval &= ~0x20; 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' TH = 0 : ?0SA1111 D3-0 are forced to '1'
*/ */
case 4: /*** Third Low ***/ case 4: /*** Third Low ***/
/* TH = 0 : ?0SA0000 D3-0 are forced to '0'*/ /* TH = 0 : ?0SA0000 D3-0 are forced to '0'*/
if (input.pad[i] & INPUT_A) retval &= ~0x10; if (input.pad[i] & INPUT_A) retval &= ~0x10;
if (input.pad[i] & INPUT_START) retval &= ~0x20; if (input.pad[i] & INPUT_START) retval &= ~0x20;
@ -341,7 +342,7 @@ static inline uint32 gamepad_read(uint32 i)
break; break;
case 6: /*** Fourth Low ***/ case 6: /*** Fourth Low ***/
/* TH = 0 : ?0SA1111 D3-0 are forced to '1'*/ /* TH = 0 : ?0SA1111 D3-0 are forced to '1'*/
if (input.pad[i] & INPUT_A) retval &= ~0x10; if (input.pad[i] & INPUT_A) retval &= ~0x10;
if (input.pad[i] & INPUT_START) retval &= ~0x20; if (input.pad[i] & INPUT_START) retval &= ~0x20;
@ -349,7 +350,7 @@ static inline uint32 gamepad_read(uint32 i)
break; break;
case 7: /*** Fourth High ***/ case 7: /*** Fourth High ***/
/* TH = 1 : ?1CBMXYZ Extra buttons returned in D3-0*/ /* TH = 1 : ?1CBMXYZ Extra buttons returned in D3-0*/
if (input.pad[i] & INPUT_X) retval &= ~0x04; if (input.pad[i] & INPUT_X) retval &= ~0x04;
if (input.pad[i] & INPUT_Y) retval &= ~0x02; if (input.pad[i] & INPUT_Y) retval &= ~0x02;
@ -360,7 +361,7 @@ static inline uint32 gamepad_read(uint32 i)
break; break;
default: default:
break; break;
} }
/* bit7 is latched */ /* bit7 is latched */
@ -371,12 +372,12 @@ static inline void gamepad_write(uint32 i, uint32 data)
{ {
if (input.dev[i] == DEVICE_6BUTTON) if (input.dev[i] == DEVICE_6BUTTON)
{ {
/* TH=0 to TH=1 transition */ /* TH=0 to TH=1 transition */
if (!(gamepad[i].State & 0x40) && (data & 0x40)) if (!(gamepad[i].State & 0x40) && (data & 0x40))
{ {
gamepad[i].Counter++; gamepad[i].Counter++;
gamepad[i].Delay = 0; gamepad[i].Delay = 0;
} }
} }
gamepad[i].State = data; gamepad[i].State = data;
@ -396,85 +397,85 @@ struct teamplayer
static inline void teamplayer_reset(uint32 port) static inline void teamplayer_reset(uint32 port)
{ {
int i; int i;
int index = 0; int index = 0;
int pad_input = 0; int pad_input = 0;
teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */ teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */
teamplayer[port].Counter = 0; teamplayer[port].Counter = 0;
/* this table determines which gamepad input should be returned during acquisition sequence /* this table determines which gamepad input should be returned during acquisition sequence
index = teamplayer read table index: 0=1st read, 1=2nd read, ... 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, ... 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++) for (i=0; i<4; i++)
{ {
if (input.dev[(4*port) + i] == DEVICE_3BUTTON) if (input.dev[(4*port) + i] == DEVICE_3BUTTON)
{ {
teamplayer[port].Table[index++] = pad_input; teamplayer[port].Table[index++] = pad_input;
teamplayer[port].Table[index++] = pad_input + 1; teamplayer[port].Table[index++] = pad_input + 1;
} }
else if (input.dev[(4*port) + i] == DEVICE_6BUTTON) else if (input.dev[(4*port) + i] == DEVICE_6BUTTON)
{ {
teamplayer[port].Table[index++] = pad_input; teamplayer[port].Table[index++] = pad_input;
teamplayer[port].Table[index++] = pad_input + 1; teamplayer[port].Table[index++] = pad_input + 1;
teamplayer[port].Table[index++] = pad_input + 2; teamplayer[port].Table[index++] = pad_input + 2;
} }
pad_input += 4; pad_input += 4;
} }
} }
/* SEGA teamplayer returns successively: /* SEGA teamplayer returns successively:
- PAD1 inputs - PAD1 inputs
- PAD2 inputs - PAD2 inputs
- PAD3 inputs - PAD3 inputs
- PAD4 inputs - PAD4 inputs
Each PAD inputs is obtained through 2 or 3 sequential reads: Each PAD inputs is obtained through 2 or 3 sequential reads:
1/ DIR buttons 1/ DIR buttons
2/ START,A,C,B buttons 2/ START,A,C,B buttons
3/ MODE, X,Y,Z buttons (6Button only !) 3/ MODE, X,Y,Z buttons (6Button only !)
*/ */
static inline uint32 teamplayer_read_device(uint32 port, uint32 index) static inline uint32 teamplayer_read_device(uint32 port, uint32 index)
{ {
int retval = 0x7F; int retval = 0x7F;
int pad_input = teamplayer[port].Table[index] & 0x03; int pad_input = teamplayer[port].Table[index] & 0x03;
int pad_num = (4 * port) + ((teamplayer[port].Table[index] >> 2) & 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;
case 2: switch (pad_input)
/* M,X,Y,Z Buttons (6-Buttons only)*/ {
if (input.pad[pad_num] & INPUT_Z) retval &= ~0x01; case 0:
if (input.pad[pad_num] & INPUT_Y) retval &= ~0x02; /* Directions Buttons */
if (input.pad[pad_num] & INPUT_X) retval &= ~0x04; if (input.pad[pad_num] & INPUT_UP) retval &= ~0x01;
if (input.pad[pad_num] & INPUT_MODE) retval &= ~0x08; if (input.pad[pad_num] & INPUT_DOWN) retval &= ~0x02;
break; 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) static inline uint32 teamplayer_read(uint32 port)
{ {
int retval = 0x7F; int retval = 0x7F;
int padnum; int padnum;
switch (teamplayer[port].Counter) /* acquisition sequence steps */ 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 */ case 3: /* ack request: TH=0, TR handshake */
retval = 0x00; retval = 0x00;
break; break;
case 4: case 4:
case 5: case 5:
case 6: case 6:
@ -498,16 +499,16 @@ static inline uint32 teamplayer_read(uint32 port)
padnum = (4 * port) + teamplayer[port].Counter - 4; padnum = (4 * port) + teamplayer[port].Counter - 4;
retval = input.dev[padnum]; retval = input.dev[padnum];
break; break;
default: /* gamepads inputs acquisition */ default: /* gamepads inputs acquisition */
retval = teamplayer_read_device(port, teamplayer[port].Counter - 8); retval = teamplayer_read_device(port, teamplayer[port].Counter - 8);
break; break;
} }
/* TL must match TR state */ /* TL must match TR state */
retval &= ~0x10; retval &= ~0x10;
if (teamplayer[port].State & 0x20) retval |= 0x10; if (teamplayer[port].State & 0x20) retval |= 0x10;
return retval; 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]); 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 (old_state != teamplayer[port].State) teamplayer[port].Counter ++;
if ((data&0x60) == 0x60) teamplayer[port].Counter = 0; if ((data&0x60) == 0x60) teamplayer[port].Counter = 0;
} }
/***************************************************************************** /*****************************************************************************
* 4WAYPLAY adapter * 4WAYPLAY adapter
@ -531,7 +532,7 @@ static inline void wayplay_write(uint32 port, uint32 data)
static inline uint32 wayplay_read(uint32 port) 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) */ if (input.current >= 4) return 0x70; /* multitap detection (TH2 = 1) */
return gamepad_read(input.current); /* 0x0C = Pad1, 0x1C = Pad2, ... */ return gamepad_read(input.current); /* 0x0C = Pad1, 0x1C = Pad2, ... */
} }
@ -563,54 +564,54 @@ void gamepad_2_write (uint32 data)
uint32 wayplay_1_read (void) uint32 wayplay_1_read (void)
{ {
return wayplay_read(0); return wayplay_read(0);
} }
uint32 wayplay_2_read (void) uint32 wayplay_2_read (void)
{ {
return wayplay_read(1); return wayplay_read(1);
} }
void wayplay_1_write (uint32 data) void wayplay_1_write (uint32 data)
{ {
wayplay_write(0, data); wayplay_write(0, data);
} }
void wayplay_2_write (uint32 data) void wayplay_2_write (uint32 data)
{ {
wayplay_write(1, data); wayplay_write(1, data);
} }
uint32 teamplayer_1_read (void) uint32 teamplayer_1_read (void)
{ {
return teamplayer_read(0); return teamplayer_read(0);
} }
uint32 teamplayer_2_read (void) uint32 teamplayer_2_read (void)
{ {
return teamplayer_read(1); return teamplayer_read(1);
} }
void teamplayer_1_write (uint32 data) void teamplayer_1_write (uint32 data)
{ {
teamplayer_write(0, data); teamplayer_write(0, data);
} }
void teamplayer_2_write (uint32 data) void teamplayer_2_write (uint32 data)
{ {
teamplayer_write(1, data); teamplayer_write(1, data);
} }
uint32 jcart_read(uint32 address) 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) void jcart_write(uint32 address, uint32 data)
{ {
gamepad_write(5, (data&1) << 6); gamepad_write(5, (data&1) << 6);
gamepad_write(6, (data&1) << 6); gamepad_write(6, (data&1) << 6);
return; return;
} }
/***************************************************************************** /*****************************************************************************
@ -619,16 +620,16 @@ void jcart_write(uint32 address, uint32 data)
*****************************************************************************/ *****************************************************************************/
void input_reset () void input_reset ()
{ {
int i,j; int i,j;
input.max = 0; input.max = 0;
input.current = 0; input.current = 0;
for (i=0; i<MAX_DEVICES; i++) for (i=0; i<MAX_DEVICES; i++)
{ {
input.dev[i] = NO_DEVICE; input.dev[i] = NO_DEVICE;
input.pad[i] = 0; input.pad[i] = 0;
} }
for (i=0; i<2; i++) for (i=0; i<2; i++)
{ {
@ -640,8 +641,8 @@ void input_reset ()
input.max ++; input.max ++;
gamepad_reset(i*4); gamepad_reset(i*4);
break; break;
case SYSTEM_MOUSE: case SYSTEM_MOUSE:
if (input.max == MAX_INPUTS) return; if (input.max == MAX_INPUTS) return;
input.dev[i*4] = DEVICE_MOUSE; input.dev[i*4] = DEVICE_MOUSE;
input.max ++; input.max ++;
@ -687,70 +688,70 @@ void input_reset ()
} }
/* J-CART: add two gamepad inputs */ /* J-CART: add two gamepad inputs */
if (j_cart) if (j_cart)
{ {
input.dev[5] = input.padtype[2]; input.dev[5] = input.padtype[2];
input.dev[6] = input.padtype[3]; input.dev[6] = input.padtype[3];
gamepad_reset(5); gamepad_reset(5);
gamepad_reset(6); gamepad_reset(6);
} }
} }
void input_update() void input_update()
{ {
int i; int i;
switch (input.system[0]) switch (input.system[0])
{ {
case SYSTEM_GAMEPAD: case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0); if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0);
break; 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: case SYSTEM_WAYPLAY:
lightgun_update(0); for (i=0; i<4; i++)
break; {
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: case SYSTEM_JUSTIFIER:
if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0); if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0);
if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1); if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1);
break; break;
} }
} }
void input_raz() void input_raz()
{ {
int i; int i;
switch (input.system[0]) switch (input.system[0])
{ {
case SYSTEM_GAMEPAD: case SYSTEM_GAMEPAD:
if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0); if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0);
break; break;
case SYSTEM_WAYPLAY: case SYSTEM_WAYPLAY:
for (i=0; i<4; i++) for (i=0; i<4; i++)
{ {
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i); if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
} }
break; break;
} }
switch (input.system[1]) switch (input.system[1])
{ {
case SYSTEM_GAMEPAD: case SYSTEM_GAMEPAD:
if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4); if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4);
break; break;
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -125,41 +125,41 @@
/* V counter values for NTSC 192-line display */ /* V counter values for NTSC 192-line display */
uint8 vc_ntsc_192[262] = { uint8 vc_ntsc_192[262] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 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, 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 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
}; };
/* V counter values for NTSC 224-line display */ /* V counter values for NTSC 224-line display */
uint8 vc_ntsc_224[262] = { uint8 vc_ntsc_224[262] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 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 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) */ /* V counter values for NTSC 240-line display (invalid mode) */
uint8 vc_ntsc_240[262] = { uint8 vc_ntsc_240[262] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05 0x00, 0x01, 0x02, 0x03, 0x04, 0x05
@ -188,20 +188,20 @@ uint8 vc_ntsc_240[262] = {
/* V counter values for PAL 192-line display */ /* V counter values for PAL 192-line display */
uint8 vc_pal_192[313] = { uint8 vc_pal_192[313] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF0, 0xF1, 0xF2,
0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 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 */ /* V counter values for PAL 224-line display */
uint8 vc_pal_224[313] = { uint8 vc_pal_224[313] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
0x00, 0x01, 0x02, 0x00, 0x01, 0x02,
@ -238,20 +238,20 @@ uint8 vc_pal_224[313] = {
/* V counter values for PAL 240-line display */ /* V counter values for PAL 240-line display */
uint8 vc_pal_240[313] = { uint8 vc_pal_240[313] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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] = { uint8 cycle2hc40[488] = {
0xA4, 0xA5, 0xA5, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA8, 0xA8, 0xA9, 0xA9, 0xAA, 0xAA, 0xA4, 0xA5, 0xA5, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA8, 0xA8, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAB,
0xAA, 0xAB, 0xAB, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAF, 0xAF, 0xB0, 0xB0, 0xB1, 0xB1, 0xAB, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAF, 0xAF, 0xB0, 0xB0, 0xB1, 0xB1, 0xB1, 0xB2,
0xB1, 0xB2, 0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6, 0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6,
0xE4, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6, 0xE6, 0xE4, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6, 0xE6,
0xE7, 0xE7, 0xE7, 0xE8, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 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, 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, 0xA1, 0xA2, 0xA2, 0xA3, 0xA3, 0xA4, 0xA4,
}; };
uint8 *vctab; uint8 *vctab;
uint8 *hctab; uint8 *hctab;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,28 +1,17 @@
/**************************************************************************** /****************************************************************************
* Nintendo Gamecube DVD Reading Library * Nintendo Gamecube DVD Reading Library
* *
* This is NOT a complete DVD library, in that it works for reading * Low-Level DVD access
* 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.
***************************************************************************/ ***************************************************************************/
#include "shared.h" #include "shared.h"
#ifdef HW_RVL #ifdef HW_RVL
#include "di/di.h" #include "di/di.h"
#endif #endif
#ifndef HW_RVL #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 vu32* const dvd = (u32*)0xCC006000; /* DVD I/O Address base */
static u8 *inquiry=(unsigned char *)0x80000004; /* pointer to drive ID */ static u8 *inquiry=(unsigned char *)0x80000004; /* pointer to drive ID */
#else #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 */ static u8 DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32); /* data buffer for all DVD operations */
/*************************************************************************** /***************************************************************************
* dvd_read * dvd_read
* *
@ -85,19 +73,19 @@ u32 dvd_read (void *dst, u32 len, u64 offset)
void dvd_motor_off( ) void dvd_motor_off( )
{ {
#ifndef HW_RVL #ifndef HW_RVL
dvd[0] = 0x2e; dvd[0] = 0x2e;
dvd[1] = 0; dvd[1] = 0;
dvd[2] = 0xe3000000; dvd[2] = 0xe3000000;
dvd[3] = 0; dvd[3] = 0;
dvd[4] = 0; dvd[4] = 0;
dvd[5] = 0; dvd[5] = 0;
dvd[6] = 0; dvd[6] = 0;
dvd[7] = 1; // Do immediate dvd[7] = 1; // Do immediate
while (dvd[7] & 1); while (dvd[7] & 1);
/*** PSO Stops blackscreen at reload ***/ /*** PSO Stops blackscreen at reload ***/
dvd[0] = 0x14; dvd[0] = 0x14;
dvd[1] = 0; dvd[1] = 0;
#else #else
DI_StopMotor(); 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 "dvd.h"
#include "font.h" #include "font.h"
#include "unzip.h" #include "unzip.h"
#include <zlib.h>
#include <zlib.h>
/* /*
* PKWare Zip Header - adopted into zip standard * PKWare Zip Header - adopted into zip standard
@ -24,7 +24,7 @@
*/ */
typedef struct typedef struct
{ {
unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50 unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50
unsigned short zipversion __attribute__ ((__packed__)); unsigned short zipversion __attribute__ ((__packed__));
unsigned short zipflags __attribute__ ((__packed__)); unsigned short zipflags __attribute__ ((__packed__));
unsigned short compressionMethod __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.avail_in = zipchunk;
zs.next_in = (Bytef *) & readbuffer[zipoffset]; zs.next_in = (Bytef *) & readbuffer[zipoffset];
/*** Now inflate until input buffer is exhausted ***/ /*** Now inflate until input buffer is exhausted ***/
do do
{ {
zs.avail_out = ZIPCHUNK; zs.avail_out = ZIPCHUNK;
zs.next_out = (Bytef *) & out; zs.next_out = (Bytef *) & out;
res = inflate (&zs, Z_NO_FLUSH); res = inflate (&zs, Z_NO_FLUSH);
if (res == Z_MEM_ERROR) if (res == Z_MEM_ERROR)
{ {
inflateEnd (&zs); inflateEnd (&zs);
return 0; return 0;
} }
have = ZIPCHUNK - zs.avail_out; have = ZIPCHUNK - zs.avail_out;
if (have) if (have)
{ {
/*** Copy to normal block buffer ***/ /*** Copy to normal block buffer ***/
memcpy (&outbuffer[bufferoffset], &out, have); memcpy (&outbuffer[bufferoffset], &out, have);
bufferoffset += have; bufferoffset += have;
} }
} }
while (zs.avail_out == 0); while (zs.avail_out == 0);
/*** Readup the next 2k block ***/ /*** Readup the next 2k block ***/
zipoffset = 0; zipoffset = 0;
zipchunk = ZIPCHUNK; zipchunk = ZIPCHUNK;
discoffset += 2048; discoffset += 2048;
dvd_read (&readbuffer, 2048, discoffset); 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" #include "shared.h"
#define ARAMSTART 0x8000 #define ARAMSTART 0x8000
#define ARAM_READ 1
#define ARAM_WRITE 0
#define ARAM_READ 1
#define ARAM_WRITE 0
/** /**
* StartARAM * StartARAM
@ -20,8 +18,7 @@
* Passing NULL for array list, and 0 items to allocate. * Passing NULL for array list, and 0 items to allocate.
* Required so libOGC knows to handle any interrupts etc. * Required so libOGC knows to handle any interrupts etc.
*/ */
void void StartARAM ()
StartARAM ()
{ {
AR_Init (NULL, 0); AR_Init (NULL, 0);
} }
@ -31,8 +28,7 @@ StartARAM ()
* *
* Move data from MAIN memory to ARAM * Move data from MAIN memory to ARAM
*/ */
void void ARAMPut (char *src, char *dst, int len)
ARAMPut (char *src, char *dst, int len)
{ {
DCFlushRange (src, len); DCFlushRange (src, len);
AR_StartDMA( ARAM_WRITE, (u32)src, (u32)dst, 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); AR_StartDMA( ARAM_READ, (u32) dst, (u32) src, len);
while (AR_GetDMAStatus()); 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 :) * Good to know :)
*/ */
extern void StartARAM (); #ifndef _ARAM_H
void ShadowROM (); #define _ARAM_H
void ARAMFetch (char *src, char *dst, int len);
void ARAMPut (char *src, char *dst, int len);
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 "shared.h"
#include "iso9660.h"
#include "font.h" #include "font.h"
#include "fileio.h" #include "fileio_dvd.h"
#include "history.h" #include "fileio_fat.h"
#include "dvd.h" #include "filesel.h"
#ifdef HW_RVL /* Global Variables */
#include <di/di.h> int maxfiles = 0;
#endif 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 * ShowFiles
@ -87,137 +53,17 @@ static void ShowFiles (int offset, int selection)
SetScreen (); 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 * FileSelector
* *
* Let user select a file from the File listing * Let user select a file from the File listing
****************************************************************************/ ****************************************************************************/
static int FileSelector () int FileSelector()
{ {
short p; short p;
int redraw = 1; int redraw = 1;
int go_up = 0; int go_up = 0;
int ret;
int i,size; int i,size;
while (1) while (1)
@ -297,22 +143,7 @@ static int FileSelector ()
if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; if ((selection - offset) >= PAGESIZE) offset += PAGESIZE;
redraw = 1; 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 */ /* quit */
if (p & PAD_TRIGGER_Z) if (p & PAD_TRIGGER_Z)
{ {
@ -321,349 +152,45 @@ static int FileSelector ()
} }
/* open selected file or directory */ /* 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; filelist[selection].filename_offset = 0;
if (go_up) go_up = 0;
if (p & PAD_BUTTON_B)
{ {
/* select item #1 */ /* go up one directory or quit */
go_up = 0; go_up = 1;
selection = UseFAT ? 0 : 1; selection = useFAT ? 0 : 1;
} }
/*** This is directory ***/ /*** This is directory ***/
if (filelist[selection].flags) if (filelist[selection].flags)
{ {
/* SDCARD directory handler */ /* get new directory */
if (UseFAT) ret = useFAT ? FAT_UpdateDir(go_up) : DVD_UpdateDir(go_up);
{
/* 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 entry list */ /* get new entry list or quit */
maxfiles = parseDVDdirectory (); if (ret) maxfiles = useFAT ? FAT_ParseDirectory() : DVD_ParseDirectory();
} else return 0;
}
}
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;
} }
/* final read */ /*** This is a file ***/
i = rootdirlength % 2048; else
if (i)
{ {
dvd_read (readbuffer, 2048, discoffset); /* Load file */
memcpy (buffer + readoffset, readbuffer, i); 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; } GGPATCH;
/*** Game Genie Codes Array ***/ /*** Game Genie Codes Array ***/
unsigned char ggcodes[MAXCODES][10]; /*** Codes are entered as XXXX-XXXX ***/ unsigned char ggcodes[MAXCODES][10]; /*** Codes are entered as XXXX-XXXX ***/
int gghpos[MAXCODES]; /*** Edit positions ***/ int gghpos[MAXCODES]; /*** Edit positions ***/
int ggrow = 0; int ggrow = 0;
int editing = 0; int editing = 0;
char ggvalidchars[] = "ABCDEFGHJKLMNPRSTVWXYZ0123456789*"; char ggvalidchars[] = "ABCDEFGHJKLMNPRSTVWXYZ0123456789*";
@ -50,53 +50,53 @@ void decode_genie (char *code, int which)
int n, i; int n, i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
/*** This should only happen if memory is corrupt! ***/ /*** This should only happen if memory is corrupt! ***/
p = strchr (ggvalidchars, code[i]); p = strchr (ggvalidchars, code[i]);
if (p == NULL) if (p == NULL)
{ {
ggpatch[which].address = ggpatch[which].data = 0; ggpatch[which].address = ggpatch[which].data = 0;
return; return;
} }
n = p - ggvalidchars; n = p - ggvalidchars;
switch (i) switch (i)
{ {
case 0: case 0:
ggpatch[which].data |= n << 3; ggpatch[which].data |= n << 3;
break; break;
case 1: case 1:
ggpatch[which].data |= n >> 2; ggpatch[which].data |= n >> 2;
ggpatch[which].address |= (n & 3) << 14; ggpatch[which].address |= (n & 3) << 14;
break; break;
case 2: case 2:
ggpatch[which].address |= n << 9; ggpatch[which].address |= n << 9;
break; break;
case 3: case 3:
ggpatch[which].address |= (n & 0xF) << 20 | (n >> 4) << 8; ggpatch[which].address |= (n & 0xF) << 20 | (n >> 4) << 8;
break; break;
case 4: case 4:
ggpatch[which].data |= (n & 1) << 12; ggpatch[which].data |= (n & 1) << 12;
ggpatch[which].address |= (n >> 1) << 16; ggpatch[which].address |= (n >> 1) << 16;
break; break;
case 5: case 5:
ggpatch[which].data |= (n & 1) << 15 | (n >> 1) << 8; ggpatch[which].data |= (n & 1) << 15 | (n >> 1) << 8;
break; break;
case 6: case 6:
ggpatch[which].data |= (n >> 3) << 13; ggpatch[which].data |= (n >> 3) << 13;
ggpatch[which].address |= (n & 7) << 5; ggpatch[which].address |= (n & 7) << 5;
break; break;
case 7: case 7:
ggpatch[which].address |= n; ggpatch[which].address |= n;
break; break;
} }
} }
} }
@ -112,25 +112,25 @@ void decode_ggcodes ()
j = 0; j = 0;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
if (strcmp ((char *)ggcodes[i], "AAAA-AAAA")) if (strcmp ((char *)ggcodes[i], "AAAA-AAAA"))
{ {
/*** Move the code into thiscode ***/ /*** Move the code into thiscode ***/
memcpy (&thiscode, &ggcodes[i], 4); memcpy (&thiscode, &ggcodes[i], 4);
memcpy (&thiscode[4], &ggcodes[i][5], 4); memcpy (&thiscode[4], &ggcodes[i][5], 4);
decode_genie (thiscode, j); decode_genie (thiscode, j);
j++; j++;
} }
} }
/*** And now apply the patches ***/ /*** And now apply the patches ***/
if (j) if (j)
{ {
for (i = 0; i < j; i++) for (i = 0; i < j; i++)
{ {
if (ggpatch[i].address < 0x400000) if (ggpatch[i].address < 0x400000)
{ {
/*** Patching ROM space ONLY (Game Genie does NOT have access to other memory areas) ***/ /*** 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; 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++) for (i = 0; i < MAXCODES; i++)
{ {
strcpy ((char *)ggcodes[i], "AAAA-AAAA"); strcpy ((char *)ggcodes[i], "AAAA-AAAA");
gghpos[i] = 0; gghpos[i] = 0;
} }
ggrow = 0; ggrow = 0;
} }
@ -169,29 +169,29 @@ void DrawGGCodes ()
for (i = 0; i < MAXCODES; i++) for (i = 0; i < MAXCODES; i++)
{ {
if (i == ggrow) if (i == ggrow)
{ {
/*** Highlight selected ***/ /*** Highlight selected ***/
WriteCentre_HL (i * fheight + 224, (char *)ggcodes[i]); WriteCentre_HL (i * fheight + 224, (char *)ggcodes[i]);
/*** If editing, highlight the current character ***/ /*** If editing, highlight the current character ***/
if (editing) if (editing)
{ {
int hpos = 0; int hpos = 0;
for (j=0; j<strlen ((char *)ggcodes[i]); j++) hpos += font_size[ggcodes[i][j]]; for (j=0; j<strlen ((char *)ggcodes[i]); j++) hpos += font_size[ggcodes[i][j]];
hpos = ((640 - hpos) >> 1); hpos = ((640 - hpos) >> 1);
for (j=0; j<gghpos[i]; j++) hpos += font_size[ggcodes[i][j]]; for (j=0; j<gghpos[i]; j++) hpos += font_size[ggcodes[i][j]];
c[0] = ggcodes[i][gghpos[i]]; c[0] = ggcodes[i][gghpos[i]];
fntDrawBoxFilled (hpos, (i * fheight) + 224, hpos + font_size[c[0]], fntDrawBoxFilled (hpos, (i * fheight) + 224, hpos + font_size[c[0]],
((i + 1) * fheight) + 224, COLOR_YELLOW); ((i + 1) * fheight) + 224, COLOR_YELLOW);
setfontcolour (COLOR_BLUE); setfontcolour (COLOR_BLUE);
write_font (hpos, (i * fheight) + 224, (char *)c); write_font (hpos, (i * fheight) + 224, (char *)c);
setfontcolour (COLOR_WHITE); setfontcolour (COLOR_WHITE);
} }
} }
else WriteCentre ((i * fheight) + 224, (char *)ggcodes[i]); else WriteCentre ((i * fheight) + 224, (char *)ggcodes[i]);
} }
SetScreen (); SetScreen ();
} }
@ -215,55 +215,55 @@ void GGEditLine ()
while (quit == 0) while (quit == 0)
{ {
if (redraw) if (redraw)
{ {
DrawGGCodes (); DrawGGCodes ();
redraw = 0; redraw = 0;
} }
p = ogc_input__getMenuButtons(); p = ogc_input__getMenuButtons();
if (p & PAD_BUTTON_UP) if (p & PAD_BUTTON_UP)
{ {
/*** Increment the entry ***/ /*** Increment the entry ***/
redraw = 1; redraw = 1;
c[0] = ggcodes[ggrow][gghpos[ggrow]]; c[0] = ggcodes[ggrow][gghpos[ggrow]];
v = strstr (ggvalidchars, c); v = strstr (ggvalidchars, c);
v++; v++;
if (*v == '*') ggcodes[ggrow][gghpos[ggrow]] = 'A'; if (*v == '*') ggcodes[ggrow][gghpos[ggrow]] = 'A';
else ggcodes[ggrow][gghpos[ggrow]] = *v; else ggcodes[ggrow][gghpos[ggrow]] = *v;
} }
if (p & PAD_BUTTON_DOWN) if (p & PAD_BUTTON_DOWN)
{ {
/*** Decrement entry ***/ /*** Decrement entry ***/
redraw = 1; redraw = 1;
c[0] = ggcodes[ggrow][gghpos[ggrow]]; c[0] = ggcodes[ggrow][gghpos[ggrow]];
v = strstr (ggvalidchars, c); v = strstr (ggvalidchars, c);
if (*v == 'A') ggcodes[ggrow][gghpos[ggrow]] = '9'; if (*v == 'A') ggcodes[ggrow][gghpos[ggrow]] = '9';
else else
{ {
v--; v--;
ggcodes[ggrow][gghpos[ggrow]] = *v; ggcodes[ggrow][gghpos[ggrow]] = *v;
} }
} }
if (p & PAD_BUTTON_LEFT) if (p & PAD_BUTTON_LEFT)
{ {
redraw = 1; redraw = 1;
gghpos[ggrow]--; gghpos[ggrow]--;
if (gghpos[ggrow] == 4) gghpos[ggrow]--; if (gghpos[ggrow] == 4) gghpos[ggrow]--;
} }
if (p & PAD_BUTTON_RIGHT) if (p & PAD_BUTTON_RIGHT)
{ {
redraw = 1; redraw = 1;
gghpos[ggrow]++; gghpos[ggrow]++;
if (gghpos[ggrow] == 4) gghpos[ggrow]++; if (gghpos[ggrow] == 4) gghpos[ggrow]++;
} }
if (gghpos[ggrow] < 0) gghpos[ggrow] = 8; if (gghpos[ggrow] < 0) gghpos[ggrow] = 8;
if (gghpos[ggrow] > 8) gghpos[ggrow] = 0; if (gghpos[ggrow] > 8) gghpos[ggrow] = 0;
if (p & PAD_BUTTON_A) quit = 1; if (p & PAD_BUTTON_A) quit = 1;
} }
@ -283,49 +283,49 @@ void GGSelectLine ()
short j; short j;
/*** To select a line, just move up or down. /*** To select a line, just move up or down.
Pressing A will enter edit mode. Pressing A will enter edit mode.
Pressing B will exit to caller. ***/ Pressing B will exit to caller. ***/
while (quit == 0) while (quit == 0)
{ {
if (redraw) if (redraw)
{ {
DrawGGCodes (); DrawGGCodes ();
redraw = 0; redraw = 0;
} }
j = ogc_input__getMenuButtons(); j = ogc_input__getMenuButtons();
if (j & PAD_BUTTON_UP) if (j & PAD_BUTTON_UP)
{ {
ggrow--; ggrow--;
redraw = 1; redraw = 1;
} }
if (j & PAD_BUTTON_DOWN) if (j & PAD_BUTTON_DOWN)
{ {
ggrow++; ggrow++;
redraw = 1; redraw = 1;
} }
if (ggrow < 0) ggrow = MAXCODES - 1; if (ggrow < 0) ggrow = MAXCODES - 1;
if (ggrow == MAXCODES) ggrow = 0; if (ggrow == MAXCODES) ggrow = 0;
if (j & PAD_BUTTON_B) quit = 1; if (j & PAD_BUTTON_B) quit = 1;
if (j & PAD_BUTTON_A) if (j & PAD_BUTTON_A)
{ {
GGEditLine (); GGEditLine ();
redraw = 1; redraw = 1;
} }
if (j & PAD_TRIGGER_Z) if (j & PAD_TRIGGER_Z)
{ {
/* reset code */ /* reset code */
strcpy ((char *)ggcodes[ggrow], "AAAA-AAAA"); strcpy ((char *)ggcodes[ggrow], "AAAA-AAAA");
gghpos[ggrow] = 0; gghpos[ggrow] = 0;
redraw = 1; 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); dispoffset = (316 * 320) + ((640 - dkpro_WIDTH) >> 2);
for (h = 0; h < dkpro_HEIGHT; h++) for (h = 0; h < dkpro_HEIGHT; h++)
{ {
for (w = 0; w < dkpro_WIDTH >> 1; w++) for (w = 0; w < dkpro_WIDTH >> 1; w++)
xfb[whichfb][dispoffset + w] = dkproraw[p++]; xfb[whichfb][dispoffset + w] = dkproraw[p++];
dispoffset += 320; dispoffset += 320;
} }
free (dkproraw); free (dkproraw);
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,22 +8,25 @@
*/ */
#include "shared.h" #include "shared.h"
#include "font.h"
#include "history.h" #include "history.h"
t_history history; t_history history;
void history_save() void history_save()
{ {
if (!use_FAT) return; char pathname[MAXPATHLEN];
if (!fat_enabled) return;
/* first check if directory exist */ /* first check if directory exist */
DIR_ITER *dir = diropen("/genplus"); sprintf (pathname, DEFAULT_PATH);
if (dir == NULL) mkdir("/genplus",S_IRWXU); DIR_ITER *dir = diropen(pathname);
if (dir == NULL) mkdir(pathname,S_IRWXU);
else dirclose(dir); else dirclose(dir);
/* open file for writing */ /* 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; if (fp == NULL) return;
/* save options */ /* save options */
@ -42,46 +45,49 @@ void history_save()
****************************************************************************/ ****************************************************************************/
void history_add_file(char *filepath, char *filename) void history_add_file(char *filepath, char *filename)
{ {
/* Create the new entry for this path. */ /* Create the new entry for this path. */
t_history_entry newentry; t_history_entry newentry;
strncpy(newentry.filepath, filepath, MAXJOLIET - 1); strncpy(newentry.filepath, filepath, MAXJOLIET - 1);
strncpy(newentry.filename, filename, MAXJOLIET - 1); strncpy(newentry.filename, filename, MAXJOLIET - 1);
newentry.filepath[MAXJOLIET - 1] = '\0'; newentry.filepath[MAXJOLIET - 1] = '\0';
newentry.filename[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 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. */ t_history_entry currentry; /* Curr entry is the one that just replaced old path. */
/* Initially set curr entry to the new value. */ /* Initially set curr entry to the new value. */
memcpy(&currentry, &newentry, sizeof(t_history_entry)); memcpy(&currentry, &newentry, sizeof(t_history_entry));
int i; int i;
for(i=0; i < NUM_HISTORY_ENTRIES; i++) for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{ {
/* Save off the next entry. */ /* Save off the next entry. */
memcpy(&oldentry, &history.entries[i], sizeof(t_history_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;
}
/* now save to disk */ /* Overwrite with the previous entry. */
history_save(); 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() void history_load()
{ {
char pathname[MAXPATHLEN];
/* open file for reading */ /* 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; if (fp == NULL) return;
/* read file */ /* read file */
@ -92,11 +98,11 @@ void history_load()
void set_history_defaults(void) void set_history_defaults(void)
{ {
int i; int i;
for(i=0; i < NUM_HISTORY_ENTRIES; i++) for(i=0; i < NUM_HISTORY_ENTRIES; i++)
{ {
memset(&history.entries[i], 0, sizeof(t_history_entry)); memset(&history.entries[i], 0, sizeof(t_history_entry));
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -63,7 +63,7 @@ static uint32 make_lut_bgobj_ste(uint32 bx, uint32 sx);
static __inline__ uint32 READ_LONG(void *address) static __inline__ uint32 READ_LONG(void *address)
{ {
if ((uint32)address & 3) if ((uint32)address & 3)
{ {
#ifdef LSB_FIRST /* little endian version */ #ifdef LSB_FIRST /* little endian version */
return ( *((uint8 *)address) + return ( *((uint8 *)address) +
(*((uint8 *)address+1) << 8) + (*((uint8 *)address+1) << 8) +
@ -75,14 +75,14 @@ static __inline__ uint32 READ_LONG(void *address)
(*((uint8 *)address+1) << 16) + (*((uint8 *)address+1) << 16) +
(*((uint8 *)address) << 24) ); (*((uint8 *)address) << 24) );
#endif /* LSB_FIRST */ #endif /* LSB_FIRST */
} }
else return *(uint32 *)address; else return *(uint32 *)address;
} }
static __inline__ void WRITE_LONG(void *address, uint32 data) static __inline__ void WRITE_LONG(void *address, uint32 data)
{ {
if ((uint32)address & 3) if ((uint32)address & 3)
{ {
#ifdef LSB_FIRST #ifdef LSB_FIRST
*((uint8 *)address) = data; *((uint8 *)address) = data;
*((uint8 *)address+1) = (data >> 8); *((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+1) = (data >> 16);
*((uint8 *)address) = (data >> 24); *((uint8 *)address) = (data >> 24);
#endif /* LSB_FIRST */ #endif /* LSB_FIRST */
return; return;
} }
else *(uint32 *)address = data; else *(uint32 *)address = data;
} }
#endif /* ALIGN_LONG */ #endif /* ALIGN_LONG */
@ -112,26 +112,26 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
N = Pattern Number (11 bits) N = Pattern Number (11 bits)
MSB PCCVHNNN NNNNNNNN LSB PCCVHNNN NNNNNNNN LSB MSB PCCVHNNN NNNNNNNN LSB PCCVHNNN NNNNNNNN LSB
PATTERN1 PATTERN2 PATTERN1 PATTERN2
Pattern attributes are read from VRAM as 32bits WORD like this: Pattern attributes are read from VRAM as 32bits WORD like this:
LIT_ENDIAN: ATTR is MSB PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN LSB LIT_ENDIAN: ATTR is MSB PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN LSB
PATTERN2 PATTERN1 PATTERN2 PATTERN1
BIG_ENDIAN: ATTR is MSB PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN LSB 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: Each Line Buffer written byte describe one pixel data like this:
msb SPppcccc lsb msb SPppcccc lsb
with: with:
S = sprite data indicator (not written here) S = sprite data indicator (not written here)
P = priority bit (from Pattern Attribute) P = priority bit (from Pattern Attribute)
p = color palette (from Pattern Attribute) p = color palette (from Pattern Attribute)
c = color data (from Pattern Cache) c = color data (from Pattern Cache)
A column is 2 patterns wide 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 */ /* Draw a single 8-pixel column */
/* /*
pattern cache is addressed like this: 00000VHN NNNNNNNN NNYYYXXX pattern cache is addressed like this: 00000VHN NNNNNNNN NNYYYXXX
with : Y = pattern row (1-8 lines) with : Y = pattern row (1-8 lines)
X = pattern column (1-8 pixels) X = pattern column (1-8 pixels)
V = Vertical Flip bit V = Vertical Flip bit
H = Horizontal Flip bit H = Horizontal Flip bit
N = Pattern Number (1-2048) N = Pattern Number (1-2048)
*/ */
#ifdef ALIGN_LONG #ifdef ALIGN_LONG
#ifdef LSB_FIRST #ifdef LSB_FIRST
@ -170,7 +170,7 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
#else #else
#define DRAW_COLUMN(ATTR, LINE) \ #define DRAW_COLUMN(ATTR, LINE) \
attr_msb = ATTR >> 16; \ 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)]; \ src = (uint32 *)&bg_pattern_cache[(ATTR_MSB & 0x1FFF) << 6 | (LINE)]; \
WRITE_LONG(dst, READ_LONG(src) | atex); \ WRITE_LONG(dst, READ_LONG(src) | atex); \
dst++; \ dst++; \
@ -202,7 +202,7 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
#else #else
#define DRAW_COLUMN(ATTR, LINE) \ #define DRAW_COLUMN(ATTR, LINE) \
attr_msb = ATTR >> 16; \ 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)]; \ src = (uint32 *)&bg_pattern_cache[(attr_msb & 0x1FFF) << 6 | (LINE)]; \
*dst++ = (*src++ | atex); \ *dst++ = (*src++ | atex); \
*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 */ /* Draw a single 16-pixel column */
/* /*
pattern cache is addressed like this: 00000VHN NNNNNNNN NYYYYXXX pattern cache is addressed like this: 00000VHN NNNNNNNN NYYYYXXX
with : Y = pattern row (1-16 lines) with : Y = pattern row (1-16 lines)
X = pattern column (1-8 pixels) X = pattern column (1-8 pixels)
V = Vertical Flip bit V = Vertical Flip bit
H = Horizontal Flip bit H = Horizontal Flip bit
N = Pattern Number (1-1024) N = Pattern Number (1-1024)
one pattern line is 8 pixels = 8 bytes = 2 * 32 bits 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 #else
#define DRAW_COLUMN_IM2(ATTR, LINE) \ #define DRAW_COLUMN_IM2(ATTR, LINE) \
attr_msb = ATTR >> 16; \ 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); \ offs = (attr_msb & 0x03FF) << 7 | (attr_msb & 0x1800) << 6 | (LINE); \
if(attr_msb & 0x1000) offs ^= 0x40; \ if(attr_msb & 0x1000) offs ^= 0x40; \
src = (uint32 *)&bg_pattern_cache[offs]; \ 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 check if non-transparent sprite data has been previously drawn
*/ */
#define DRAW_SPRITE_TILE \ #define DRAW_SPRITE_TILE \
for(i=0; i<8; i++) \ for(i=0; i<8; i++) \
{ \ { \
if ((lb[i] & 0x80) && (lb[i] & 0x0F) && (src[i] & 0x0F)) status |= 0x20; \ if ((lb[i] & 0x80) && (lb[i] & 0x0F) && (src[i] & 0x0F)) status |= 0x20; \
lb[i] = table[(lb[i] << 8) |(src[i] | palette)]; \ lb[i] = table[(lb[i] << 8) |(src[i] | palette)]; \
} }
/* Pixel creation macros, input is four bits each */ /* Pixel creation macros, input is four bits each */
@ -387,11 +387,11 @@ static uint16 pixel_16[0x100];
static uint16 pixel_16_lut[3][0x200]; static uint16 pixel_16_lut[3][0x200];
/* Line buffers */ /* Line buffers */
static uint8 tmp_buf[0x400]; /* Temporary buffer */ static uint8 tmp_buf[0x400]; /* Temporary buffer */
static uint8 bg_buf[0x400]; /* Merged background buffer */ static uint8 bg_buf[0x400]; /* Merged background buffer */
static uint8 nta_buf[0x400]; /* Plane A / Window line buffer */ static uint8 nta_buf[0x400]; /* Plane A / Window line buffer */
static uint8 ntb_buf[0x400]; /* Plane B line buffer */ static uint8 ntb_buf[0x400]; /* Plane B line buffer */
static uint8 obj_buf[0x400]; /* Object layer line buffer */ static uint8 obj_buf[0x400]; /* Object layer line buffer */
/* Sprite line buffer data */ /* Sprite line buffer data */
static uint32 object_index_count; 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 this is used to convert 3bits RGB values to 5bits (R,B) or 6bits (G) values
there is three color modes: there is three color modes:
normal: RGB range is [0;MAX] normal: RGB range is [0;MAX]
half: RGB range is [0;MAX/2] (shadow mode) half: RGB range is [0;MAX/2] (shadow mode)
high: RGB range is [MAX/2;MAX] (highlight 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 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) 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: the extrapolation is linear and calculated like this:
for (i=0; i<8; i++) for (i=0; i<8; i++)
{ {
rgb565_norm[0][i] = round(((double)i * 31.0) / 7.0); rgb565_norm[0][i] = round(((double)i * 31.0) / 7.0);
rgb565_norm[1][i] = round(((double)i * 63.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[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_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[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_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}, 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}, 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}, 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) void palette_init(void)
{ {
int i; int i;
for (i = 0; i < 0x200; i += 1) for (i = 0; i < 0x200; i += 1)
{ {
int r, g, b; int r, g, b;
r = (i >> 6) & 7; r = (i >> 6) & 7;
g = (i >> 3) & 7; g = (i >> 3) & 7;
b = (i >> 0) & 7; b = (i >> 0) & 7;
#ifndef NGC #ifndef NGC
pixel_8_lut[0][i] = MAKE_PIXEL_8(r>>1,g>>1,b>>1); 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[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[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[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[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[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[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[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[2][i] = MAKE_PIXEL_32(r|8,g|8,b|8);
#endif #endif
/* RGB 565 format: we extrapolate each 3-bit value into a 5-bit (R,B) or 6-bit (G) value /* 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 */ 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[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[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]); 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 render_init (void)
{ {
int bx, ax, i; int bx, ax, i;
/* Allocate and align pixel look-up tables */ /* Allocate and align pixel look-up tables */
if (lut_base == NULL) lut_base = malloc ((LUT_MAX * LUT_SIZE) + LUT_SIZE); if (lut_base == NULL) lut_base = malloc ((LUT_MAX * LUT_SIZE) + LUT_SIZE);
lut[0] = (uint8 *) (((uint32) lut_base + LUT_SIZE) & ~(LUT_SIZE - 1)); 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); for (i = 1; i < LUT_MAX; i += 1) lut[i] = lut[0] + (i * LUT_SIZE);
/* Make pixel look-up table data */ /* Make pixel look-up table data */
for (bx = 0; bx < 0x100; bx += 1) for (bx = 0; bx < 0x100; bx += 1)
for (ax = 0; ax < 0x100; ax += 1) for (ax = 0; ax < 0x100; ax += 1)
{ {
uint16 index = (bx << 8) | (ax); uint16 index = (bx << 8) | (ax);
lut[0][index] = make_lut_bg (bx, ax); lut[0][index] = make_lut_bg (bx, ax);
lut[1][index] = make_lut_obj (bx, ax); lut[1][index] = make_lut_obj (bx, ax);
lut[2][index] = make_lut_bg_ste (bx, ax); lut[2][index] = make_lut_bg_ste (bx, ax);
lut[3][index] = make_lut_obj_ste (bx, ax); lut[3][index] = make_lut_obj_ste (bx, ax);
lut[4][index] = make_lut_bgobj_ste (bx, ax); lut[4][index] = make_lut_bgobj_ste (bx, ax);
} }
/* Make pixel data tables */ /* Make pixel data tables */
palette_init(); palette_init();
/* Set up color update function */ /* Set up color update function */
#ifndef NGC #ifndef NGC
switch(bitmap.depth) switch(bitmap.depth)
{ {
case 8: color_update = color_update_8; break; case 8: color_update = color_update_8; break;
case 15: color_update = color_update_15; break; case 15: color_update = color_update_15; break;
case 16: color_update = color_update_16; break; case 16: color_update = color_update_16; break;
case 32: color_update = color_update_32; break; case 32: color_update = color_update_32; break;
} }
#else #else
color_update = color_update_16; color_update = color_update_16;
#endif #endif
/* Make sprite name look-up table */ /* Make sprite name look-up table */
make_name_lut(); make_name_lut();
return (1); return (1);
} }
void make_name_lut(void) void make_name_lut(void)
{ {
int col, row; int col, row;
int vcol, vrow; int vcol, vrow;
int width, height; int width, height;
int flipx, flipy; int flipx, flipy;
int i, name; int i, name;
memset (name_lut, 0, sizeof (name_lut)); memset (name_lut, 0, sizeof (name_lut));
for (i = 0; i < 0x400; i += 1) for (i = 0; i < 0x400; i += 1)
{ {
vcol = col = i & 3; vcol = col = i & 3;
vrow = row = (i >> 2) & 3; vrow = row = (i >> 2) & 3;
height = (i >> 4) & 3; height = (i >> 4) & 3;
width = (i >> 6) & 3; width = (i >> 6) & 3;
flipx = (i >> 8) & 1; flipx = (i >> 8) & 1;
flipy = (i >> 9) & 1; flipy = (i >> 9) & 1;
if(flipx) vcol = (width - col); if(flipx) vcol = (width - col);
if(flipy) vrow = (height - row); 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) void render_reset(void)
@ -547,7 +547,7 @@ void render_reset(void)
/* Clear display bitmap */ /* Clear display bitmap */
memset(bitmap.data, 0, bitmap.pitch * bitmap.height); 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(bg_buf, 0, sizeof(bg_buf));
memset(tmp_buf, 0, sizeof(tmp_buf)); memset(tmp_buf, 0, sizeof(tmp_buf));
memset(nta_buf, 0, sizeof(nta_buf)); memset(nta_buf, 0, sizeof(nta_buf));
@ -555,7 +555,7 @@ void render_reset(void)
memset(obj_buf, 0, sizeof(obj_buf)); memset(obj_buf, 0, sizeof(obj_buf));
#ifndef NGC #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_15, 0, sizeof(pixel_15));
memset(&pixel_32, 0, sizeof(pixel_32)); memset(&pixel_32, 0, sizeof(pixel_32));
#endif #endif
@ -580,10 +580,10 @@ static inline void update_bg_pattern_cache(uint32 index)
uint8 *dst; uint8 *dst;
uint32 bp; uint32 bp;
#ifdef LSB_FIRST #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 #else
uint8 shift_table[8] = {28, 24, 20, 16, 12, 8, 4, 0}; uint8 shift_table[8] = {28, 24, 20, 16, 12, 8, 4, 0};
#endif #endif
for(i = 0; i < index; i ++) 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 ++) for(x = 0; x < 8; x ++)
{ {
c = (bp >> shift_table[x]) & 0x0F; c = (bp >> shift_table[x]) & 0x0F;
dst[0x00000 | (y << 3) | (x)] = (c); /* hf=0, vf=0: normal */ 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[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[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 */ 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); else sms_ntsc_blit(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
return; return;
} }
#ifdef NGC #ifdef NGC
/* directly fill the RGB565 texture */ /* directly fill the RGB565 texture */
/* one tile is 32 byte = 4x4 pixels */ /* 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)]); void *out =((void *)&bitmap.data[(line * bitmap.pitch)]);
switch(bitmap.depth) switch(bitmap.depth)
{ {
case 8: case 8:
remap_8(tmp_buf+0x20-bitmap.viewport.x, (uint8 *)out, pixel_8, width); remap_8(tmp_buf+0x20-bitmap.viewport.x, (uint8 *)out, pixel_8, width);
break; break;
case 15: case 15:
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_15, width); remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_15, width);
break; break;
case 16: case 16:
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_16, width); remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_16, width);
break; break;
case 32: 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; break;
} }
#endif #endif
@ -782,16 +782,16 @@ void remap_buffer(uint32 line, uint32 width)
void render_line(uint32 line, uint32 overscan) void render_line(uint32 line, uint32 overscan)
{ {
uint32 width = bitmap.viewport.w; uint32 width = bitmap.viewport.w;
uint32 x_offset = bitmap.viewport.x; uint32 x_offset = bitmap.viewport.x;
/* background color (display OFF or borders) */ /* background color (display OFF or borders) */
if (overscan || !(reg[1] & 0x40)) if (overscan || !(reg[1] & 0x40))
{ {
width += 2 * x_offset; width += 2 * x_offset;
memset(&tmp_buf[0x20 - x_offset], 0x40, width); memset(&tmp_buf[0x20 - x_offset], 0x40, width);
} }
else else
{ {
uint8 *lb = tmp_buf; 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; uint32 y_scroll = (line + (vs[0] & 0x3FF)) & pf_row_mask;
#endif #endif
uint32 v_line = (y_scroll & 7) << 3; uint32 v_line = (y_scroll & 7) << 3;
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)]; uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
if(shift) if(shift)
{ {
dst = (uint32 *)&buf[0x10 + shift]; dst = (uint32 *)&buf[0x10 + shift];
atbuf = nt[(index-1) & pf_col_mask]; 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 ++) for(column = 0; column < end; column ++, index ++)
{ {
atbuf = nt[index & pf_col_mask]; atbuf = nt[index & pf_col_mask];
@ -991,7 +991,7 @@ static void render_bg(uint32 line, uint32 width)
if (w) if (w)
{ {
v_line = (line & 7) << 3; 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)]; dst = (uint32 *)&buf[0x20 + (start << 4)];
for(column = start; column < end; column ++) 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); uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
#endif #endif
uint32 y_scroll, v_line, *nt; uint32 y_scroll, v_line, *nt;
if(shift) if(shift)
{ {
y_scroll = (line & pf_row_mask); y_scroll = (line & pf_row_mask);
v_line = (y_scroll & 7) << 3; v_line = (y_scroll & 7) << 3;
nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)]; 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]; 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 ++) for(column = start; column < end; column ++, index ++)
{ {
#ifdef LSB_FIRST #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; y_scroll = (line + (vs[column] & 0x3FF)) & pf_row_mask;
#else #else
y_scroll = (line + ((vs[column] >> 16) & 0x3FF)) & pf_row_mask; y_scroll = (line + ((vs[column] >> 16) & 0x3FF)) & pf_row_mask;
#endif #endif
v_line = (y_scroll & 7) << 3; v_line = (y_scroll & 7) << 3;
nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)]; nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
atbuf = nt[index & pf_col_mask]; atbuf = nt[index & pf_col_mask];
@ -1124,7 +1124,7 @@ static void render_bg_vs(uint32 line, uint32 width)
if (w) if (w)
{ {
v_line = (line & 7) << 3; 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)]; dst = (uint32 *)&buf[0x20 + (start << 4)];
for(column = start; column < end; column ++) 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 */ uint32 y_scroll = (line + ((vs[0] >> 1) & 0x3FF)) & pf_row_mask; /* IM2 specific */
#endif #endif
uint32 v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */ 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 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
if(shift) if(shift)
{ {
dst = (uint32 *)&buf[0x10 + shift]; dst = (uint32 *)&buf[0x10 + shift];
atbuf = nt[(index-1) & pf_col_mask]; 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 ++) for(column = 0; column < end; column ++, index ++)
{ {
atbuf = nt[index & pf_col_mask]; 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 */ y_scroll = (line + ((vs[0] >> 17) & 0x3FF)) & pf_row_mask; /* IM2 specific */
#endif #endif
v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */ v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)]; nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
if(shift) if(shift)
{ {
dst = (uint32 *)&buf[0x10 + shift + (start<<4)]; dst = (uint32 *)&buf[0x10 + shift + (start<<4)];
/* Window bug */ /* Window bug */
if (start) atbuf = nt[index & pf_col_mask]; if (start) atbuf = nt[index & pf_col_mask];
else atbuf = nt[(index-1) & 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)]; dst = (uint32 *)&buf[0x20 + shift + (start<<4)];
@ -1245,7 +1245,7 @@ static void render_bg_im2(uint32 line, uint32 width, uint32 odd)
if (w) if (w)
{ {
v_line = ((line & 7) << 1 | odd) << 3; /* IM2 specific */ 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)]; dst = (uint32 *)&buf[0x20 + (start << 4)];
for(column = start; column < end; column ++) for(column = start; column < end; column ++)
{ {
@ -1612,23 +1612,23 @@ void parse_satb(uint32 line)
{ {
ypos = (q[link] >> im2_flag) & 0x1FF; ypos = (q[link] >> im2_flag) & 0x1FF;
size = q[link + 1] >> 8; size = q[link + 1] >> 8;
height = sizetab[size & 3]; height = sizetab[size & 3];
if((line >= ypos) && (line < (ypos + height))) if((line >= ypos) && (line < (ypos + height)))
{ {
/* sprite limit (max. 16 or 20 sprites displayed per line) */ /* 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; if(vint_pending == 0) status |= 0x40;
return; return;
} }
// using xpos from internal satb stops sprite x // using xpos from internal satb stops sprite x
// scrolling in bloodlin.bin, // scrolling in bloodlin.bin,
// but this seems to go against the test prog // 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].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_info[object_index_count].size = size;
++object_index_count; ++object_index_count;
} }
@ -1668,14 +1668,14 @@ static void render_obj(uint32 line, uint8 *buf, uint8 *table)
xpos = object_info[count].xpos & 0x1ff; xpos = object_info[count].xpos & 0x1ff;
/* sprite masking */ /* sprite masking */
if(xpos != 0) sol_flag = 1; if(xpos != 0) sol_flag = 1;
else if(xpos == 0 && sol_flag) return; else if(xpos == 0 && sol_flag) return;
size = object_info[count].size & 0x0f; size = object_info[count].size & 0x0f;
width = sizetab[(size >> 2) & 3]; width = sizetab[(size >> 2) & 3];
/* update pixel count (off-screen sprites included) */ /* update pixel count (off-screen sprites included) */
pixelcount += width; pixelcount += width;
if(((xpos + width) >= left) && (xpos < right)) 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)]; lb = (uint8 *)&buf[0x20 + (xpos - 0x80)];
/* number of tiles to draw */ /* number of tiles to draw */
/* adjusted for sprite limit */ /* adjusted for sprite limit */
if (pixelcount > bitmap.viewport.w) width -= (pixelcount - bitmap.viewport.w); if (pixelcount > bitmap.viewport.w) width -= (pixelcount - bitmap.viewport.w);
width >>= 3; width >>= 3;
for(column = 0; column < width; column += 1, lb+=8) 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) */ /* sprite limit (256 or 320 pixels) */
if (pixelcount >= bitmap.viewport.w) return; 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; 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; xpos = object_info[count].xpos & 0x1ff;
/* sprite masking */ /* sprite masking */
if(xpos != 0) sol_flag = 1; if(xpos != 0) sol_flag = 1;
else if(xpos == 0 && sol_flag) return; else if(xpos == 0 && sol_flag) return;
size = object_info[count].size & 0x0f; size = object_info[count].size & 0x0f;
width = sizetab[(size >> 2) & 3]; width = sizetab[(size >> 2) & 3];
/* update pixel count (off-screen sprites included) */ /* update pixel count (off-screen sprites included) */
pixelcount += width; pixelcount += width;
if(((xpos + width) >= left) && (xpos < right)) if(((xpos + width) >= left) && (xpos < right))
{ {
ypos = object_info[count].ypos; 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)]; lb = (uint8 *)&buf[0x20 + (xpos - 0x80)];
/* number of tiles to draw */ /* number of tiles to draw */
/* adjusted for sprite limit */ /* adjusted for sprite limit */
if (pixelcount > bitmap.viewport.w) width -= (pixelcount - bitmap.viewport.w); if (pixelcount > bitmap.viewport.w) width -= (pixelcount - bitmap.viewport.w);
width >>= 3; width >>= 3;
for(column = 0; column < width; column += 1, lb+=8) 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) */ /* sprite limit (256 or 320 pixels) */
if (pixelcount >= bitmap.viewport.w) return; 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) static inline void load_param(void *param, unsigned int size)
{ {
memcpy(param, &state[bufferptr], size); memcpy(param, &state[bufferptr], size);
bufferptr+= size; bufferptr+= size;
} }
static inline void save_param(void *param, unsigned int size) static inline void save_param(void *param, unsigned int size)
{ {
memcpy(&state[bufferptr], param, size); memcpy(&state[bufferptr], param, size);
bufferptr+= size; bufferptr+= size;
} }
void state_load(unsigned char *buffer) void state_load(unsigned char *buffer)
{ {
/* reset buffer pointer */ /* reset buffer pointer */
bufferptr = 0; bufferptr = 0;
/* uncompress savestate */ /* uncompress savestate */
unsigned long inbytes, outbytes; unsigned long inbytes, outbytes;
memcpy(&inbytes, buffer, 4); memcpy(&inbytes, buffer, 4);
outbytes = 0x24000; outbytes = 0x24000;
uncompress ((Bytef *)state, &outbytes, (Bytef *)(buffer + 4), inbytes); uncompress ((Bytef *)state, &outbytes, (Bytef *)(buffer + 4), inbytes);
/* reset system */ /* reset system */
system_reset(); system_reset();
m68k_memory_map[0].base = default_rom; m68k_memory_map[0].base = default_rom;
// GENESIS // GENESIS
load_param(work_ram, sizeof(work_ram)); load_param(work_ram, sizeof(work_ram));
load_param(zram, sizeof(zram)); load_param(zram, sizeof(zram));
load_param(&zbusreq, sizeof(zbusreq)); load_param(&zbusreq, sizeof(zbusreq));
load_param(&zreset, sizeof(zreset)); load_param(&zreset, sizeof(zreset));
load_param(&zbank, sizeof(zbank)); load_param(&zbank, sizeof(zbank));
zbusack = 1 ^(zbusreq & zreset); zbusack = 1 ^(zbusreq & zreset);
// IO // IO
load_param(io_reg, sizeof(io_reg)); 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);
// FM // VDP
load_param(fm_reg,sizeof(fm_reg)); uint8 temp_reg[0x20];
fm_restore(); 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 // FM
load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ()); load_param(fm_reg,sizeof(fm_reg));
fm_restore();
// 68000 // PSG
uint16 tmp16; load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
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 // 68000
load_param(&Z80, sizeof(Z80_Regs)); 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) int state_save(unsigned char *buffer)
{ {
/* reset buffer pointer */ /* reset buffer pointer */
bufferptr = 0; bufferptr = 0;
// GENESIS // GENESIS
save_param(work_ram, sizeof(work_ram)); save_param(work_ram, sizeof(work_ram));
save_param(zram, sizeof(zram)); save_param(zram, sizeof(zram));
save_param(&zbusreq, sizeof(zbusreq)); save_param(&zbusreq, sizeof(zbusreq));
save_param(&zreset, sizeof(zreset)); save_param(&zreset, sizeof(zreset));
save_param(&zbank, sizeof(zbank)); save_param(&zbank, sizeof(zbank));
// IO // IO
save_param(io_reg, sizeof(io_reg)); 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));
// FM // VDP
save_param(fm_reg,sizeof(fm_reg)); 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 // FM
save_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ()); save_param(fm_reg,sizeof(fm_reg));
// 68000 // PSG
uint16 tmp16; save_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
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);
// Z80 // 68000
save_param(&Z80, sizeof(Z80_Regs)); 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 */ // Z80
unsigned long inbytes = bufferptr; save_param(&Z80, sizeof(Z80_Regs));
/* compress state file */
unsigned long inbytes = bufferptr;
unsigned long outbytes = 0x26000; unsigned long outbytes = 0x26000;
compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9); compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9);
memcpy(buffer, &outbytes, 4); memcpy(buffer, &outbytes, 4);
/* return total size */ /* return total size */
return (outbytes + 4); return (outbytes + 4);
} }

View File

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

View File

@ -35,38 +35,38 @@
typedef struct typedef struct
{ {
uint8 *data; /* Bitmap data */ uint8 *data; /* Bitmap data */
int width; /* Bitmap width (32+512+32) */ int width; /* Bitmap width (32+512+32) */
int height; /* Bitmap height (256) */ int height; /* Bitmap height (256) */
int depth; /* Color depth (8 bits) */ int depth; /* Color depth (8 bits) */
int pitch; /* Width of bitmap in bytes */ int pitch; /* Width of bitmap in bytes */
int granularity; /* Size of each pixel in bytes */ int granularity; /* Size of each pixel in bytes */
int remap; /* 1= Translate pixel data */ int remap; /* 1= Translate pixel data */
struct struct
{ {
int x; /* X offset of viewport within bitmap */ int x; /* X offset of viewport within bitmap */
int y; /* Y offset of viewport within bitmap */ int y; /* Y offset of viewport within bitmap */
int w; /* Width of viewport */ int w; /* Width of viewport */
int h; /* Height of viewport */ int h; /* Height of viewport */
int ow; /* Previous width of viewport */ int ow; /* Previous width of viewport */
int oh; /* Previous height of viewport */ int oh; /* Previous height of viewport */
int changed; /* 1= Viewport width or height have changed */ int changed; /* 1= Viewport width or height have changed */
} viewport; } viewport;
} t_bitmap; } t_bitmap;
typedef struct typedef struct
{ {
int sample_rate; /* Sample rate (8000-48000) */ int sample_rate; /* Sample rate (8000-48000) */
int enabled; /* 1= sound emulation is enabled */ int enabled; /* 1= sound emulation is enabled */
int buffer_size; /* Size of sound buffer (in bytes) */ int buffer_size; /* Size of sound buffer (in bytes) */
int16 *buffer[2]; /* Signed 16-bit stereo sound data */ int16 *buffer[2]; /* Signed 16-bit stereo sound data */
struct struct
{ {
int curStage; int curStage;
int lastStage; int lastStage;
int *buffer[2]; int *buffer[2];
float *src_out; /* SRC conversion buffer */ float *src_out; /* SRC conversion buffer */
} fm; } fm;
struct 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 */ /* VDP context */
extern uint8 sat[0x400]; extern uint8 sat[0x400];
extern uint8 vram[0x10000]; extern uint8 vram[0x10000];
extern uint8 cram[0x80]; extern uint8 cram[0x80];
extern uint8 vsram[0x80]; extern uint8 vsram[0x80];
extern uint8 reg[0x20]; extern uint8 reg[0x20];
extern uint16 addr; extern uint16 addr;
extern uint16 addr_latch; extern uint16 addr_latch;
@ -41,20 +41,20 @@ extern uint8 vint_pending;
extern uint16 irq_status; extern uint16 irq_status;
/* Global variables */ /* Global variables */
extern uint16 ntab; extern uint16 ntab;
extern uint16 ntbb; extern uint16 ntbb;
extern uint16 ntwb; extern uint16 ntwb;
extern uint16 satb; extern uint16 satb;
extern uint16 hscb; extern uint16 hscb;
extern uint8 border; extern uint8 border;
extern uint8 bg_name_dirty[0x800]; extern uint8 bg_name_dirty[0x800];
extern uint16 bg_name_list[0x800]; extern uint16 bg_name_list[0x800];
extern uint16 bg_list_index; extern uint16 bg_list_index;
extern uint8 bg_pattern_cache[0x80000]; extern uint8 bg_pattern_cache[0x80000];
extern uint8 playfield_shift; extern uint8 playfield_shift;
extern uint8 playfield_col_mask; extern uint8 playfield_col_mask;
extern uint16 playfield_row_mask; extern uint16 playfield_row_mask;
extern uint32 y_mask; extern uint32 y_mask;
extern uint16 hc_latch; extern uint16 hc_latch;
extern uint16 v_counter; extern uint16 v_counter;
extern uint8 im2_flag; extern uint8 im2_flag;