mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-24 02:01:48 +01:00
rewrote file interface
This commit is contained in:
parent
6a9974c865
commit
8ea80d38a5
@ -25,8 +25,9 @@ Genesis Plus for Gamecube
|
||||
- rewrote video engine: improved horizontal scaling (VI+GX), improved rendering speed (direct texture mapping)
|
||||
- removed embedded font, (re)enabled IPL font support: now should works for Qoob users too (thanks to emukiddid)
|
||||
- fixed "Reset" button behavior, now acts more like Genesis Reset button ;-)
|
||||
- minor bugfixes and menu tweaks
|
||||
- compiled with libogc 1.7.0
|
||||
- patched libfat for faster SDCARD accesses (thanks to svpe)
|
||||
- various bugfixes and menu tweaks
|
||||
|
||||
|
||||
[NGC only]
|
||||
- added 480p support in menu
|
||||
@ -34,7 +35,8 @@ Genesis Plus for Gamecube
|
||||
[Wii only]
|
||||
- implemented fast scrolling in menu using Wiimote D-PAD
|
||||
- added "Power" button support
|
||||
- libogc 1.7.0 features (SDHC support , Wiimote shutdown button support)
|
||||
- added USB Storage support
|
||||
- *new* libogc 1.7.0 features: SDHC support, Wiimote shutdown button support
|
||||
|
||||
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@ -225,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
|
@ -31,57 +31,58 @@ t_input input;
|
||||
*****************************************************************************/
|
||||
/* H counter values for a 256-pixel wide display (342 pixel max.) */
|
||||
uint8 hc_256[171] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93,
|
||||
0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
|
||||
/* H counter values for a 320-pixel wide display (442 pixels max.) */
|
||||
uint8 hc_320[210] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
|
||||
0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
|
||||
0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED,
|
||||
0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD,
|
||||
0xFE, 0xFF
|
||||
};
|
||||
|
||||
static inline void lightgun_reset(int num)
|
||||
{
|
||||
input.analog[num][0] = bitmap.viewport.w >> 1;
|
||||
input.analog[num][1] = bitmap.viewport.h >> 1;
|
||||
input.analog[num][0] = bitmap.viewport.w >> 1;
|
||||
input.analog[num][1] = bitmap.viewport.h >> 1;
|
||||
}
|
||||
|
||||
static inline void lightgun_update(int num)
|
||||
{
|
||||
if ((input.analog[num][1] == v_counter + input.y_offset))
|
||||
{
|
||||
{
|
||||
/* HL enabled ? */
|
||||
if (io_reg[5] & 0x80)
|
||||
{
|
||||
/* External Interrupt ? */
|
||||
if (reg[11] & 0x08) {irq_status &= 0xff; irq_status |= 0x12;}
|
||||
|
||||
/* HVC Latch:
|
||||
1) some games does not set HVC latch but instead use bigger X offset
|
||||
2) for games using H40 mode, the gun routine scales up the Hcounter value,
|
||||
/* HVC Latch:
|
||||
1) some games does not set HVC latch but instead use bigger X offset
|
||||
2) for games using H40 mode, the gun routine scales up the Hcounter value,
|
||||
H-Counter range is approx. 292 pixel clocks
|
||||
*/
|
||||
hc_latch = 0x100;
|
||||
@ -90,19 +91,19 @@ static inline void lightgun_update(int num)
|
||||
else
|
||||
hc_latch |= hc_256[(input.analog[num][0] / 2 + input.x_offset)%171];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sega Menacer specific */
|
||||
uint32 menacer_read()
|
||||
{
|
||||
/* pins should return 0 by default (fix Body Count when mouse is enabled) */
|
||||
int retval = 0x00;
|
||||
if (input.pad[4] & INPUT_B) retval |= 0x01;
|
||||
if (input.pad[4] & INPUT_A) retval |= 0x02;
|
||||
if (input.pad[4] & INPUT_B) retval |= 0x01;
|
||||
if (input.pad[4] & INPUT_A) retval |= 0x02;
|
||||
if (input.pad[4] & INPUT_C) retval |= 0x04;
|
||||
if (input.pad[4] & INPUT_START) retval |= 0x08;
|
||||
if (input.pad[4] & INPUT_START) retval |= 0x08;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -130,8 +131,8 @@ uint32 justifier_read()
|
||||
return retval;
|
||||
|
||||
default: /* guns disabled */
|
||||
return retval;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -148,8 +149,8 @@ struct mega_mouse
|
||||
|
||||
static inline void mouse_reset()
|
||||
{
|
||||
mouse.State = 0x60;
|
||||
mouse.Counter = 0;
|
||||
mouse.State = 0x60;
|
||||
mouse.Counter = 0;
|
||||
mouse.Wait = 0;
|
||||
mouse.Port = (input.system[0] == SYSTEM_MOUSE) ? 0 : 4;
|
||||
}
|
||||
@ -267,19 +268,19 @@ struct pad
|
||||
|
||||
static inline void gamepad_raz(uint32 i)
|
||||
{
|
||||
gamepad[i].Counter = 0;
|
||||
gamepad[i].Delay = 0;
|
||||
gamepad[i].Counter = 0;
|
||||
gamepad[i].Delay = 0;
|
||||
}
|
||||
|
||||
static inline void gamepad_reset(uint32 i)
|
||||
{
|
||||
gamepad[i].State = 0x40;
|
||||
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
|
||||
gamepad[i].State = 0x40;
|
||||
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
|
||||
}
|
||||
|
||||
static inline void gamepad_update(uint32 i)
|
||||
{
|
||||
if (gamepad[i].Delay++ > 25) gamepad_raz(i);
|
||||
if (gamepad[i].Delay++ > 25) gamepad_raz(i);
|
||||
}
|
||||
|
||||
static inline uint32 gamepad_read(uint32 i)
|
||||
@ -288,10 +289,10 @@ static inline uint32 gamepad_read(uint32 i)
|
||||
int retval = 0x7F;
|
||||
|
||||
control = (gamepad[i].State & 0x40) >> 6; /* current TH state */
|
||||
|
||||
|
||||
if (input.dev[i] == DEVICE_6BUTTON)
|
||||
{
|
||||
control += (gamepad[i].Counter & 3) << 1; /* TH transitions counter */
|
||||
control += (gamepad[i].Counter & 3) << 1; /* TH transitions counter */
|
||||
}
|
||||
|
||||
switch (control)
|
||||
@ -299,7 +300,7 @@ static inline uint32 gamepad_read(uint32 i)
|
||||
case 1: /*** First High ***/
|
||||
case 3: /*** Second High ***/
|
||||
case 5: /*** Third High ***/
|
||||
|
||||
|
||||
/* TH = 1 : ?1CBRLDU */
|
||||
if (input.pad[i] & INPUT_C) retval &= ~0x20;
|
||||
if (input.pad[i] & INPUT_B) retval &= ~0x10;
|
||||
@ -311,7 +312,7 @@ static inline uint32 gamepad_read(uint32 i)
|
||||
|
||||
case 0: /*** First low ***/
|
||||
case 2: /*** Second low ***/
|
||||
|
||||
|
||||
/* TH = 0 : ?0SA00DU */
|
||||
if (input.pad[i] & INPUT_A) retval &= ~0x10;
|
||||
if (input.pad[i] & INPUT_START) retval &= ~0x20;
|
||||
@ -333,7 +334,7 @@ static inline uint32 gamepad_read(uint32 i)
|
||||
TH = 0 : ?0SA1111 D3-0 are forced to '1'
|
||||
*/
|
||||
case 4: /*** Third Low ***/
|
||||
|
||||
|
||||
/* TH = 0 : ?0SA0000 D3-0 are forced to '0'*/
|
||||
if (input.pad[i] & INPUT_A) retval &= ~0x10;
|
||||
if (input.pad[i] & INPUT_START) retval &= ~0x20;
|
||||
@ -341,7 +342,7 @@ static inline uint32 gamepad_read(uint32 i)
|
||||
break;
|
||||
|
||||
case 6: /*** Fourth Low ***/
|
||||
|
||||
|
||||
/* TH = 0 : ?0SA1111 D3-0 are forced to '1'*/
|
||||
if (input.pad[i] & INPUT_A) retval &= ~0x10;
|
||||
if (input.pad[i] & INPUT_START) retval &= ~0x20;
|
||||
@ -349,7 +350,7 @@ static inline uint32 gamepad_read(uint32 i)
|
||||
break;
|
||||
|
||||
case 7: /*** Fourth High ***/
|
||||
|
||||
|
||||
/* TH = 1 : ?1CBMXYZ Extra buttons returned in D3-0*/
|
||||
if (input.pad[i] & INPUT_X) retval &= ~0x04;
|
||||
if (input.pad[i] & INPUT_Y) retval &= ~0x02;
|
||||
@ -360,7 +361,7 @@ static inline uint32 gamepad_read(uint32 i)
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
/* bit7 is latched */
|
||||
@ -371,12 +372,12 @@ static inline void gamepad_write(uint32 i, uint32 data)
|
||||
{
|
||||
if (input.dev[i] == DEVICE_6BUTTON)
|
||||
{
|
||||
/* TH=0 to TH=1 transition */
|
||||
if (!(gamepad[i].State & 0x40) && (data & 0x40))
|
||||
{
|
||||
gamepad[i].Counter++;
|
||||
gamepad[i].Delay = 0;
|
||||
}
|
||||
/* TH=0 to TH=1 transition */
|
||||
if (!(gamepad[i].State & 0x40) && (data & 0x40))
|
||||
{
|
||||
gamepad[i].Counter++;
|
||||
gamepad[i].Delay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gamepad[i].State = data;
|
||||
@ -396,85 +397,85 @@ struct teamplayer
|
||||
|
||||
static inline void teamplayer_reset(uint32 port)
|
||||
{
|
||||
int i;
|
||||
int index = 0;
|
||||
int pad_input = 0;
|
||||
int i;
|
||||
int index = 0;
|
||||
int pad_input = 0;
|
||||
|
||||
teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */
|
||||
teamplayer[port].Counter = 0;
|
||||
teamplayer[port].State = 0x60; /* TH = 1, TR = 1 */
|
||||
teamplayer[port].Counter = 0;
|
||||
|
||||
/* this table determines which gamepad input should be returned during acquisition sequence
|
||||
index = teamplayer read table index: 0=1st read, 1=2nd read, ...
|
||||
pad_input = gamepad input 0-14: 0=P1_DIR, 1=P1_SABC, 2=P1_MXYZ, 4=P2_DIR, 5=P2_SABC, ...
|
||||
*/
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (input.dev[(4*port) + i] == DEVICE_3BUTTON)
|
||||
{
|
||||
teamplayer[port].Table[index++] = pad_input;
|
||||
teamplayer[port].Table[index++] = pad_input + 1;
|
||||
}
|
||||
else if (input.dev[(4*port) + i] == DEVICE_6BUTTON)
|
||||
{
|
||||
teamplayer[port].Table[index++] = pad_input;
|
||||
teamplayer[port].Table[index++] = pad_input + 1;
|
||||
teamplayer[port].Table[index++] = pad_input + 2;
|
||||
}
|
||||
pad_input += 4;
|
||||
}
|
||||
/* this table determines which gamepad input should be returned during acquisition sequence
|
||||
index = teamplayer read table index: 0=1st read, 1=2nd read, ...
|
||||
pad_input = gamepad input 0-14: 0=P1_DIR, 1=P1_SABC, 2=P1_MXYZ, 4=P2_DIR, 5=P2_SABC, ...
|
||||
*/
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (input.dev[(4*port) + i] == DEVICE_3BUTTON)
|
||||
{
|
||||
teamplayer[port].Table[index++] = pad_input;
|
||||
teamplayer[port].Table[index++] = pad_input + 1;
|
||||
}
|
||||
else if (input.dev[(4*port) + i] == DEVICE_6BUTTON)
|
||||
{
|
||||
teamplayer[port].Table[index++] = pad_input;
|
||||
teamplayer[port].Table[index++] = pad_input + 1;
|
||||
teamplayer[port].Table[index++] = pad_input + 2;
|
||||
}
|
||||
pad_input += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* SEGA teamplayer returns successively:
|
||||
- PAD1 inputs
|
||||
- PAD2 inputs
|
||||
- PAD3 inputs
|
||||
- PAD4 inputs
|
||||
- PAD2 inputs
|
||||
- PAD3 inputs
|
||||
- PAD4 inputs
|
||||
|
||||
Each PAD inputs is obtained through 2 or 3 sequential reads:
|
||||
1/ DIR buttons
|
||||
2/ START,A,C,B buttons
|
||||
3/ MODE, X,Y,Z buttons (6Button only !)
|
||||
2/ START,A,C,B buttons
|
||||
3/ MODE, X,Y,Z buttons (6Button only !)
|
||||
*/
|
||||
static inline uint32 teamplayer_read_device(uint32 port, uint32 index)
|
||||
{
|
||||
int retval = 0x7F;
|
||||
int pad_input = teamplayer[port].Table[index] & 0x03;
|
||||
int pad_num = (4 * port) + ((teamplayer[port].Table[index] >> 2) & 0x03);
|
||||
|
||||
switch (pad_input)
|
||||
{
|
||||
case 0:
|
||||
/* Directions Buttons */
|
||||
if (input.pad[pad_num] & INPUT_UP) retval &= ~0x01;
|
||||
if (input.pad[pad_num] & INPUT_DOWN) retval &= ~0x02;
|
||||
if (input.pad[pad_num] & INPUT_LEFT) retval &= ~0x04;
|
||||
if (input.pad[pad_num] & INPUT_RIGHT) retval &= ~0x08;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* S,A,C,B Buttons */
|
||||
if (input.pad[pad_num] & INPUT_B) retval &= ~0x01;
|
||||
if (input.pad[pad_num] & INPUT_C) retval &= ~0x02;
|
||||
if (input.pad[pad_num] & INPUT_A) retval &= ~0x04;
|
||||
if (input.pad[pad_num] & INPUT_START) retval &= ~0x08;
|
||||
break;
|
||||
int retval = 0x7F;
|
||||
int pad_input = teamplayer[port].Table[index] & 0x03;
|
||||
int pad_num = (4 * port) + ((teamplayer[port].Table[index] >> 2) & 0x03);
|
||||
|
||||
case 2:
|
||||
/* M,X,Y,Z Buttons (6-Buttons only)*/
|
||||
if (input.pad[pad_num] & INPUT_Z) retval &= ~0x01;
|
||||
if (input.pad[pad_num] & INPUT_Y) retval &= ~0x02;
|
||||
if (input.pad[pad_num] & INPUT_X) retval &= ~0x04;
|
||||
if (input.pad[pad_num] & INPUT_MODE) retval &= ~0x08;
|
||||
break;
|
||||
}
|
||||
switch (pad_input)
|
||||
{
|
||||
case 0:
|
||||
/* Directions Buttons */
|
||||
if (input.pad[pad_num] & INPUT_UP) retval &= ~0x01;
|
||||
if (input.pad[pad_num] & INPUT_DOWN) retval &= ~0x02;
|
||||
if (input.pad[pad_num] & INPUT_LEFT) retval &= ~0x04;
|
||||
if (input.pad[pad_num] & INPUT_RIGHT) retval &= ~0x08;
|
||||
break;
|
||||
|
||||
return retval;
|
||||
case 1:
|
||||
/* S,A,C,B Buttons */
|
||||
if (input.pad[pad_num] & INPUT_B) retval &= ~0x01;
|
||||
if (input.pad[pad_num] & INPUT_C) retval &= ~0x02;
|
||||
if (input.pad[pad_num] & INPUT_A) retval &= ~0x04;
|
||||
if (input.pad[pad_num] & INPUT_START) retval &= ~0x08;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* M,X,Y,Z Buttons (6-Buttons only)*/
|
||||
if (input.pad[pad_num] & INPUT_Z) retval &= ~0x01;
|
||||
if (input.pad[pad_num] & INPUT_Y) retval &= ~0x02;
|
||||
if (input.pad[pad_num] & INPUT_X) retval &= ~0x04;
|
||||
if (input.pad[pad_num] & INPUT_MODE) retval &= ~0x08;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline uint32 teamplayer_read(uint32 port)
|
||||
{
|
||||
int retval = 0x7F;
|
||||
int padnum;
|
||||
int retval = 0x7F;
|
||||
int padnum;
|
||||
|
||||
switch (teamplayer[port].Counter) /* acquisition sequence steps */
|
||||
{
|
||||
@ -490,7 +491,7 @@ static inline uint32 teamplayer_read(uint32 port)
|
||||
case 3: /* ack request: TH=0, TR handshake */
|
||||
retval = 0x00;
|
||||
break;
|
||||
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
@ -498,16 +499,16 @@ static inline uint32 teamplayer_read(uint32 port)
|
||||
padnum = (4 * port) + teamplayer[port].Counter - 4;
|
||||
retval = input.dev[padnum];
|
||||
break;
|
||||
|
||||
|
||||
default: /* gamepads inputs acquisition */
|
||||
retval = teamplayer_read_device(port, teamplayer[port].Counter - 8);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* TL must match TR state */
|
||||
retval &= ~0x10;
|
||||
if (teamplayer[port].State & 0x20) retval |= 0x10;
|
||||
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -517,7 +518,7 @@ static inline void teamplayer_write(uint32 port, uint32 data)
|
||||
teamplayer[port].State = (data & io_reg[port+4]) | (teamplayer[port].State & ~io_reg[port+4]);
|
||||
if (old_state != teamplayer[port].State) teamplayer[port].Counter ++;
|
||||
if ((data&0x60) == 0x60) teamplayer[port].Counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* 4WAYPLAY adapter
|
||||
@ -531,7 +532,7 @@ static inline void wayplay_write(uint32 port, uint32 data)
|
||||
|
||||
static inline uint32 wayplay_read(uint32 port)
|
||||
{
|
||||
if (port == 1) return 0x7F;
|
||||
if (port == 1) return 0x7F;
|
||||
if (input.current >= 4) return 0x70; /* multitap detection (TH2 = 1) */
|
||||
return gamepad_read(input.current); /* 0x0C = Pad1, 0x1C = Pad2, ... */
|
||||
}
|
||||
@ -563,54 +564,54 @@ void gamepad_2_write (uint32 data)
|
||||
|
||||
uint32 wayplay_1_read (void)
|
||||
{
|
||||
return wayplay_read(0);
|
||||
return wayplay_read(0);
|
||||
}
|
||||
|
||||
uint32 wayplay_2_read (void)
|
||||
{
|
||||
return wayplay_read(1);
|
||||
return wayplay_read(1);
|
||||
}
|
||||
|
||||
void wayplay_1_write (uint32 data)
|
||||
{
|
||||
wayplay_write(0, data);
|
||||
wayplay_write(0, data);
|
||||
}
|
||||
|
||||
void wayplay_2_write (uint32 data)
|
||||
{
|
||||
wayplay_write(1, data);
|
||||
wayplay_write(1, data);
|
||||
}
|
||||
|
||||
uint32 teamplayer_1_read (void)
|
||||
{
|
||||
return teamplayer_read(0);
|
||||
return teamplayer_read(0);
|
||||
}
|
||||
|
||||
uint32 teamplayer_2_read (void)
|
||||
{
|
||||
return teamplayer_read(1);
|
||||
return teamplayer_read(1);
|
||||
}
|
||||
|
||||
void teamplayer_1_write (uint32 data)
|
||||
{
|
||||
teamplayer_write(0, data);
|
||||
teamplayer_write(0, data);
|
||||
}
|
||||
|
||||
void teamplayer_2_write (uint32 data)
|
||||
{
|
||||
teamplayer_write(1, data);
|
||||
teamplayer_write(1, data);
|
||||
}
|
||||
|
||||
uint32 jcart_read(uint32 address)
|
||||
{
|
||||
return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 (is it correct ?) */
|
||||
return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 (is it correct ?) */
|
||||
}
|
||||
|
||||
void jcart_write(uint32 address, uint32 data)
|
||||
{
|
||||
gamepad_write(5, (data&1) << 6);
|
||||
gamepad_write(6, (data&1) << 6);
|
||||
return;
|
||||
gamepad_write(5, (data&1) << 6);
|
||||
gamepad_write(6, (data&1) << 6);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -619,16 +620,16 @@ void jcart_write(uint32 address, uint32 data)
|
||||
*****************************************************************************/
|
||||
void input_reset ()
|
||||
{
|
||||
int i,j;
|
||||
|
||||
input.max = 0;
|
||||
int i,j;
|
||||
|
||||
input.max = 0;
|
||||
input.current = 0;
|
||||
|
||||
for (i=0; i<MAX_DEVICES; i++)
|
||||
{
|
||||
input.dev[i] = NO_DEVICE;
|
||||
input.pad[i] = 0;
|
||||
}
|
||||
for (i=0; i<MAX_DEVICES; i++)
|
||||
{
|
||||
input.dev[i] = NO_DEVICE;
|
||||
input.pad[i] = 0;
|
||||
}
|
||||
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
@ -640,8 +641,8 @@ void input_reset ()
|
||||
input.max ++;
|
||||
gamepad_reset(i*4);
|
||||
break;
|
||||
|
||||
case SYSTEM_MOUSE:
|
||||
|
||||
case SYSTEM_MOUSE:
|
||||
if (input.max == MAX_INPUTS) return;
|
||||
input.dev[i*4] = DEVICE_MOUSE;
|
||||
input.max ++;
|
||||
@ -687,70 +688,70 @@ void input_reset ()
|
||||
}
|
||||
|
||||
/* J-CART: add two gamepad inputs */
|
||||
if (j_cart)
|
||||
{
|
||||
input.dev[5] = input.padtype[2];
|
||||
input.dev[6] = input.padtype[3];
|
||||
gamepad_reset(5);
|
||||
gamepad_reset(6);
|
||||
}
|
||||
if (j_cart)
|
||||
{
|
||||
input.dev[5] = input.padtype[2];
|
||||
input.dev[6] = input.padtype[3];
|
||||
gamepad_reset(5);
|
||||
gamepad_reset(6);
|
||||
}
|
||||
}
|
||||
|
||||
void input_update()
|
||||
{
|
||||
int i;
|
||||
switch (input.system[0])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0);
|
||||
break;
|
||||
|
||||
case SYSTEM_WAYPLAY:
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (input.dev[i] == DEVICE_6BUTTON) gamepad_update(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (input.system[1])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[4] == DEVICE_6BUTTON) gamepad_update(4);
|
||||
break;
|
||||
int i;
|
||||
switch (input.system[0])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[0] == DEVICE_6BUTTON) gamepad_update(0);
|
||||
break;
|
||||
|
||||
case SYSTEM_MENACER:
|
||||
lightgun_update(0);
|
||||
break;
|
||||
case SYSTEM_WAYPLAY:
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (input.dev[i] == DEVICE_6BUTTON) gamepad_update(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (input.system[1])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[4] == DEVICE_6BUTTON) gamepad_update(4);
|
||||
break;
|
||||
|
||||
case SYSTEM_MENACER:
|
||||
lightgun_update(0);
|
||||
break;
|
||||
|
||||
case SYSTEM_JUSTIFIER:
|
||||
if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0);
|
||||
if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1);
|
||||
break;
|
||||
}
|
||||
if ((io_reg[2] & 0x30) == 0x00) lightgun_update(0);
|
||||
if ((io_reg[2] & 0x30) == 0x20) lightgun_update(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void input_raz()
|
||||
{
|
||||
int i;
|
||||
switch (input.system[0])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0);
|
||||
break;
|
||||
|
||||
case SYSTEM_WAYPLAY:
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (input.system[1])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4);
|
||||
break;
|
||||
}
|
||||
int i;
|
||||
switch (input.system[0])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[0] == DEVICE_6BUTTON) gamepad_raz(0);
|
||||
break;
|
||||
|
||||
case SYSTEM_WAYPLAY:
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
if (input.dev[i] == DEVICE_6BUTTON) gamepad_raz(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (input.system[1])
|
||||
{
|
||||
case SYSTEM_GAMEPAD:
|
||||
if (input.dev[4] == DEVICE_6BUTTON) gamepad_raz(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,12 @@
|
||||
#define MAX_DEVICES (8)
|
||||
|
||||
/* Device types */
|
||||
#define DEVICE_3BUTTON (0x00) /* 3-button gamepad */
|
||||
#define DEVICE_6BUTTON (0x01) /* 6-button gamepad */
|
||||
#define DEVICE_LIGHTGUN (0x02) /* Sega Menacer or Konami Justifier */
|
||||
#define DEVICE_MOUSE (0x03) /* Sega Mouse */
|
||||
#define DEVICE_2BUTTON (0x04) /* 2-button gamepad (not supported) */
|
||||
#define NO_DEVICE (0x0F) /* unconnected */
|
||||
#define DEVICE_3BUTTON (0x00) /* 3-button gamepad */
|
||||
#define DEVICE_6BUTTON (0x01) /* 6-button gamepad */
|
||||
#define DEVICE_LIGHTGUN (0x02) /* Sega Menacer or Konami Justifier */
|
||||
#define DEVICE_MOUSE (0x03) /* Sega Mouse */
|
||||
#define DEVICE_2BUTTON (0x04) /* 2-button gamepad (not supported) */
|
||||
#define NO_DEVICE (0x0F) /* unconnected */
|
||||
|
||||
/* Input bitmasks */
|
||||
#define INPUT_MODE (0x00000800)
|
||||
@ -53,10 +53,10 @@
|
||||
#define NO_SYSTEM (0) /* Unconnected Port*/
|
||||
#define SYSTEM_MOUSE (1) /* Sega Mouse */
|
||||
#define SYSTEM_GAMEPAD (2) /* Single Gamepad */
|
||||
#define SYSTEM_MENACER (3) /* Sega Menacer (port 2) */
|
||||
#define SYSTEM_JUSTIFIER (4) /* Konami Justifier (port 2) */
|
||||
#define SYSTEM_TEAMPLAYER (5) /* Sega TeamPlayer */
|
||||
#define SYSTEM_WAYPLAY (6) /* EA 4-Way Play (use both ports) */
|
||||
#define SYSTEM_MENACER (3) /* Sega Menacer (port 2) */
|
||||
#define SYSTEM_JUSTIFIER (4) /* Konami Justifier (port 2) */
|
||||
#define SYSTEM_TEAMPLAYER (5) /* Sega TeamPlayer */
|
||||
#define SYSTEM_WAYPLAY (6) /* EA 4-Way Play (use both ports) */
|
||||
|
||||
/* Players Inputs */
|
||||
#define PLAYER_1A (0)
|
||||
@ -76,7 +76,7 @@ typedef struct
|
||||
uint8 system[2]; /* Can be any of the SYSTEM_* bitmasks */
|
||||
uint8 max; /* maximum number of connected devices */
|
||||
uint8 current; /* current PAD number (4WAYPLAY) */
|
||||
int analog[3][2]; /* analog devices */
|
||||
int analog[3][2]; /* analog devices */
|
||||
int x_offset;
|
||||
int y_offset;
|
||||
} t_input;
|
||||
|
@ -28,12 +28,12 @@ uint8 region_code = REGION_USA;
|
||||
|
||||
/*****************************************************************************
|
||||
* I/O chip functions *
|
||||
* *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
struct port_t
|
||||
{
|
||||
void (*data_w)(unsigned int data);
|
||||
unsigned int (*data_r)(void);
|
||||
void (*data_w)(uint32 data);
|
||||
uint32 (*data_r)(void);
|
||||
} port[3];
|
||||
|
||||
void io_reset(void)
|
||||
@ -41,12 +41,12 @@ void io_reset(void)
|
||||
/* I/O register default settings */
|
||||
uint8 io_def[0x10] =
|
||||
{
|
||||
0xA0,
|
||||
0x7F, 0x7F, 0x7F,
|
||||
0x00, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00,
|
||||
0xFB, 0x00, 0x00,
|
||||
0xA0,
|
||||
0x7F, 0x7F, 0x7F,
|
||||
0x00, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00,
|
||||
0xFB, 0x00, 0x00,
|
||||
};
|
||||
|
||||
/* Initialize I/O registers */
|
||||
@ -66,20 +66,20 @@ void io_reset(void)
|
||||
break;
|
||||
|
||||
case SYSTEM_WAYPLAY:
|
||||
port[0].data_w = wayplay_1_write;
|
||||
port[0].data_r = wayplay_1_read;
|
||||
break;
|
||||
port[0].data_w = wayplay_1_write;
|
||||
port[0].data_r = wayplay_1_read;
|
||||
break;
|
||||
|
||||
case SYSTEM_TEAMPLAYER:
|
||||
port[0].data_w = teamplayer_1_write;
|
||||
port[0].data_r = teamplayer_1_read;
|
||||
break;
|
||||
port[0].data_w = teamplayer_1_write;
|
||||
port[0].data_r = teamplayer_1_read;
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
port[0].data_w = NULL;
|
||||
port[0].data_r = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (input.system[1])
|
||||
{
|
||||
@ -104,20 +104,20 @@ void io_reset(void)
|
||||
break;
|
||||
|
||||
case SYSTEM_WAYPLAY:
|
||||
port[1].data_w = wayplay_2_write;
|
||||
port[1].data_r = wayplay_2_read;
|
||||
break;
|
||||
port[1].data_w = wayplay_2_write;
|
||||
port[1].data_r = wayplay_2_read;
|
||||
break;
|
||||
|
||||
case SYSTEM_TEAMPLAYER:
|
||||
port[1].data_w = teamplayer_2_write;
|
||||
port[1].data_r = teamplayer_2_read;
|
||||
break;
|
||||
port[1].data_w = teamplayer_2_write;
|
||||
port[1].data_r = teamplayer_2_read;
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
port[1].data_w = NULL;
|
||||
port[1].data_r = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* External Port (unconnected) */
|
||||
port[2].data_w = NULL;
|
||||
@ -127,7 +127,7 @@ void io_reset(void)
|
||||
input_reset();
|
||||
}
|
||||
|
||||
void io_write(unsigned int offset, unsigned int value)
|
||||
void io_write(uint32 offset, uint32 value)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
@ -138,7 +138,7 @@ void io_write(unsigned int offset, unsigned int value)
|
||||
if(port[offset-1].data_w) port[offset-1].data_w(value);
|
||||
return;
|
||||
|
||||
case 0x05: /* Port B Ctrl */
|
||||
case 0x05: /* Port B Ctrl */
|
||||
if (((value & 0x7F) == 0x7F) &&
|
||||
((input.system[0] == SYSTEM_TEAMPLAYER) ||
|
||||
(input.system[1] == SYSTEM_TEAMPLAYER)))
|
||||
@ -153,47 +153,47 @@ void io_write(unsigned int offset, unsigned int value)
|
||||
input_reset();
|
||||
}
|
||||
|
||||
case 0x04: /* Port A Ctrl */
|
||||
case 0x06: /* Port C Ctrl */
|
||||
case 0x04: /* Port A Ctrl */
|
||||
case 0x06: /* Port C Ctrl */
|
||||
io_reg[offset] = value & 0xFF;
|
||||
io_reg[offset-3] = ((io_reg[offset-3] & 0x80) | (io_reg[offset-3] & io_reg[offset]));
|
||||
return;
|
||||
|
||||
case 0x07: /* Port A TxData */
|
||||
case 0x0A: /* Port B TxData */
|
||||
case 0x0D: /* Port C TxData */
|
||||
case 0x07: /* Port A TxData */
|
||||
case 0x0A: /* Port B TxData */
|
||||
case 0x0D: /* Port C TxData */
|
||||
io_reg[offset] = value;
|
||||
return;
|
||||
|
||||
case 0x09: /* Port A S-Ctrl */
|
||||
case 0x0C: /* Port B S-Ctrl */
|
||||
case 0x0F: /* Port C S-Ctrl */
|
||||
case 0x09: /* Port A S-Ctrl */
|
||||
case 0x0C: /* Port B S-Ctrl */
|
||||
case 0x0F: /* Port C S-Ctrl */
|
||||
io_reg[offset] = (value & 0xF8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int io_read(unsigned int offset)
|
||||
|
||||
uint32 io_read(uint32 offset)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 0x00: /* Version register */
|
||||
{
|
||||
uint8 has_scd = 0x20; /* No Sega CD unit attached */
|
||||
uint8 gen_ver = (config.bios_enabled == 3) ? 0x01 : 0x00; /* hardware version */
|
||||
{
|
||||
uint8 has_scd = 0x20; /* No Sega CD unit attached */
|
||||
uint8 gen_ver = (config.bios_enabled == 3) ? 0x01 : 0x00; /* hardware version */
|
||||
return (region_code | has_scd | gen_ver);
|
||||
}
|
||||
}
|
||||
|
||||
case 0x01: /* Port A Data */
|
||||
case 0x02: /* Port B Data */
|
||||
case 0x03: /* Port C Data */
|
||||
{
|
||||
uint8 input = 0x7F; /* default input state */
|
||||
case 0x03: /* Port C Data */
|
||||
{
|
||||
uint8 input = 0x7F; /* default input state */
|
||||
if(port[offset-1].data_r) input = port[offset-1].data_r();
|
||||
return (io_reg[offset] | ((~io_reg[offset+3]) & input));
|
||||
}
|
||||
return (io_reg[offset] | ((~io_reg[offset+3]) & input));
|
||||
}
|
||||
|
||||
default:
|
||||
return (io_reg[offset]);
|
||||
}
|
||||
default:
|
||||
return (io_reg[offset]);
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,10 @@
|
||||
#ifndef _GEN_IO_H_
|
||||
#define _GEN_IO_H_
|
||||
|
||||
#define REGION_USA 0x80
|
||||
#define REGION_JAPAN_NTSC 0x00
|
||||
#define REGION_EUROPE 0xC0
|
||||
#define REGION_JAPAN_PAL 0x40
|
||||
#define REGION_JAPAN_NTSC 0x00
|
||||
#define REGION_JAPAN_PAL 0x40
|
||||
#define REGION_USA 0x80
|
||||
#define REGION_EUROPE 0xC0
|
||||
|
||||
/* Global variables */
|
||||
extern uint8 io_reg[0x10];
|
||||
@ -36,8 +36,8 @@ extern uint8 pad_type;
|
||||
|
||||
/* Function prototypes */
|
||||
extern void io_reset(void);
|
||||
extern void io_write(unsigned int offset, unsigned int value);
|
||||
extern unsigned int io_read(unsigned int offset);
|
||||
extern void io_write(uint32 offset, uint32 value);
|
||||
extern uint32 io_read(uint32 offset);
|
||||
|
||||
#endif /* _IO_H_ */
|
||||
|
||||
|
210
source/genesis.c
210
source/genesis.c
@ -23,62 +23,61 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
uint8 *cart_rom; /* cart_rom NEED to be previously dynamically allocated */
|
||||
uint8 bios_rom[0x10000];
|
||||
uint8 *cart_rom; /* CART rom */
|
||||
uint8 bios_rom[0x10000]; /* BIOS rom */
|
||||
uint8 work_ram[0x10000]; /* 68K work RAM */
|
||||
uint8 zram[0x2000]; /* Z80 work RAM */
|
||||
uint8 zbusreq; /* /BUSREQ from Z80 */
|
||||
uint8 zreset; /* /RESET to Z80 */
|
||||
uint8 zbusack; /* /BUSACK to Z80 */
|
||||
uint8 zirq; /* /IRQ to Z80 */
|
||||
uint32 zbank; /* Address of Z80 bank window */
|
||||
uint8 zram[0x2000]; /* Z80 work RAM */
|
||||
uint8 zbusreq; /* /BUSREQ from Z80 */
|
||||
uint8 zreset; /* /RESET to Z80 */
|
||||
uint8 zbusack; /* /BUSACK to Z80 */
|
||||
uint8 zirq; /* /IRQ to Z80 */
|
||||
uint32 zbank; /* Address of Z80 bank window */
|
||||
uint8 gen_running;
|
||||
uint32 genromsize;
|
||||
int32 resetline;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, shutdown functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void set_softreset(void)
|
||||
{
|
||||
resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0));
|
||||
resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0));
|
||||
}
|
||||
|
||||
void gen_init (void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
/* initialize CPUs */
|
||||
m68k_set_cpu_type (M68K_CPU_TYPE_68000);
|
||||
m68k_init();
|
||||
z80_init(0,0,0,z80_irq_callback);
|
||||
/* initialize CPUs */
|
||||
m68k_set_cpu_type (M68K_CPU_TYPE_68000);
|
||||
m68k_init();
|
||||
z80_init(0,0,0,z80_irq_callback);
|
||||
|
||||
/* initialize 68k default address space */
|
||||
for (i=0x0; i<0x100; i++)
|
||||
{
|
||||
{
|
||||
m68k_memory_map[i].base = work_ram;
|
||||
m68k_memory_map[i].read8 = NULL;
|
||||
m68k_memory_map[i].read16 = NULL;
|
||||
m68k_memory_map[i].write8 = NULL;
|
||||
m68k_memory_map[i].write16 = NULL;
|
||||
m68k_memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
/* initialize 68k memory map */
|
||||
for (i=0x80; i<0xe0; i++)
|
||||
{
|
||||
/* illegal area */
|
||||
for (i=0x80; i<0xe0; i++)
|
||||
{
|
||||
/* illegal area */
|
||||
m68k_memory_map[i].read8 = m68k_lockup_r_8;
|
||||
m68k_memory_map[i].read16 = m68k_lockup_r_16;
|
||||
m68k_memory_map[i].write8 = m68k_lockup_w_8;
|
||||
m68k_memory_map[i].write16 = m68k_lockup_w_16;
|
||||
m68k_memory_map[i].write16 = m68k_lockup_w_16;
|
||||
zbank_memory_map[i].read = zbank_lockup_r;
|
||||
zbank_memory_map[i].write = zbank_lockup_w;
|
||||
}
|
||||
}
|
||||
|
||||
/* Z80 bus */
|
||||
/* Z80 bus */
|
||||
m68k_memory_map[0xa0].read8 = z80_read_byte;
|
||||
m68k_memory_map[0xa0].read16 = z80_read_word;
|
||||
m68k_memory_map[0xa0].write8 = z80_write_byte;
|
||||
@ -86,7 +85,7 @@ void gen_init (void)
|
||||
zbank_memory_map[0xa0].read = zbank_lockup_r;
|
||||
zbank_memory_map[0xa0].write = zbank_lockup_w;
|
||||
|
||||
/* I/O & Control registers */
|
||||
/* I/O & Control registers */
|
||||
m68k_memory_map[0xa1].read8 = ctrl_io_read_byte;
|
||||
m68k_memory_map[0xa1].read16 = ctrl_io_read_word;
|
||||
m68k_memory_map[0xa1].write8 = ctrl_io_write_byte;
|
||||
@ -102,7 +101,7 @@ void gen_init (void)
|
||||
m68k_memory_map[0x80].write8 = m68k_unused_8_w;
|
||||
m68k_memory_map[0x80].write16 = m68k_unused_16_w;
|
||||
|
||||
/* there is no I/O area (Notaz) */
|
||||
/* there is no I/O area (Notaz) */
|
||||
m68k_memory_map[0xa0].read8 = m68k_read_bus_8;
|
||||
m68k_memory_map[0xa0].read16 = m68k_read_bus_16;
|
||||
m68k_memory_map[0xa0].write8 = m68k_unused_8_w;
|
||||
@ -113,7 +112,7 @@ void gen_init (void)
|
||||
m68k_memory_map[0xa1].write16 = m68k_unused_16_w;
|
||||
}
|
||||
|
||||
/* VDP */
|
||||
/* VDP */
|
||||
m68k_memory_map[0xc0].read8 = vdp_read_byte;
|
||||
m68k_memory_map[0xc0].read16 = vdp_read_word;
|
||||
m68k_memory_map[0xc0].write8 = vdp_write_byte;
|
||||
@ -142,38 +141,37 @@ void gen_init (void)
|
||||
|
||||
void gen_reset (uint32 hard_reset)
|
||||
{
|
||||
if (hard_reset)
|
||||
{
|
||||
/* Clear RAM */
|
||||
memset (work_ram, 0x00, sizeof (work_ram));
|
||||
memset (zram, 0x00, sizeof (zram));
|
||||
if (hard_reset)
|
||||
{
|
||||
/* Clear RAM */
|
||||
memset (work_ram, 0x00, sizeof (work_ram));
|
||||
memset (zram, 0x00, sizeof (zram));
|
||||
|
||||
/* TMSS BIOS */
|
||||
/* TMSS BIOS */
|
||||
if (config.bios_enabled == 3)
|
||||
{
|
||||
m68k_memory_map[0].base = bios_rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gen_running = 1;
|
||||
resetline = -1;
|
||||
gen_running = 1;
|
||||
resetline = -1;
|
||||
|
||||
zreset = 0; /* Z80 is reset */
|
||||
zbusreq = 0; /* Z80 has control of the Z bus */
|
||||
zbusack = 1; /* Z80 is busy using the Z bus */
|
||||
zirq = 0; /* No interrupts occuring */
|
||||
zbank = 0; /* Assume default bank is 000000-007FFF */
|
||||
zreset = 0; /* Z80 is reset */
|
||||
zbusreq = 0; /* Z80 has control of the Z bus */
|
||||
zbusack = 1; /* Z80 is busy using the Z bus */
|
||||
zirq = 0; /* No interrupts occuring */
|
||||
zbank = 0; /* Assume default bank is 000000-007FFF */
|
||||
|
||||
/* Reset CPUs */
|
||||
m68k_pulse_reset ();
|
||||
z80_reset ();
|
||||
_YM2612_Reset();
|
||||
/* Reset CPUs */
|
||||
m68k_pulse_reset ();
|
||||
z80_reset ();
|
||||
_YM2612_Reset();
|
||||
|
||||
#ifdef NGC
|
||||
/* register SOFTRESET */
|
||||
SYS_SetResetCallback(set_softreset);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void gen_shutdown (void)
|
||||
@ -185,86 +183,86 @@ void gen_shutdown (void)
|
||||
-----------------------------------------------------------------------*/
|
||||
void gen_busreq_w (uint32 state)
|
||||
{
|
||||
uint32 z80_cycles_to_run;
|
||||
uint32 z80_cycles_to_run;
|
||||
|
||||
input_raz (); /* from Gens */
|
||||
|
||||
if (state)
|
||||
{
|
||||
/* Bus Request */
|
||||
if (!zbusreq && zreset)
|
||||
{
|
||||
/* Z80 stopped */
|
||||
/* z80 was ON during the last 68k cycles */
|
||||
/* we execute the appropriate number of z80 cycles */
|
||||
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
|
||||
input_raz (); /* from Gens */
|
||||
|
||||
if (state)
|
||||
{
|
||||
/* Bus Request */
|
||||
if (!zbusreq && zreset)
|
||||
{
|
||||
/* Z80 stopped */
|
||||
/* z80 was ON during the last 68k cycles */
|
||||
/* we execute the appropriate number of z80 cycles */
|
||||
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
|
||||
current_z80 = z80_cycles_to_run - count_z80;
|
||||
if (current_z80 > 0) count_z80 += z80_execute(current_z80);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bus released */
|
||||
if (zbusreq && zreset)
|
||||
{
|
||||
/* Z80 started */
|
||||
/* z80 was OFF during the last 68k cycles */
|
||||
/* we burn the appropriate number of z80 cycles */
|
||||
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
|
||||
count_z80 = z80_cycles_to_run;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bus released */
|
||||
if (zbusreq && zreset)
|
||||
{
|
||||
/* Z80 started */
|
||||
/* z80 was OFF during the last 68k cycles */
|
||||
/* we burn the appropriate number of z80 cycles */
|
||||
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
|
||||
count_z80 = z80_cycles_to_run;
|
||||
}
|
||||
}
|
||||
|
||||
zbusreq = state;
|
||||
zbusack = 1 ^ (zbusreq & zreset);
|
||||
zbusreq = state;
|
||||
zbusack = 1 ^ (zbusreq & zreset);
|
||||
}
|
||||
|
||||
void gen_reset_w (uint32 state)
|
||||
{
|
||||
uint32 z80_cycles_to_run;
|
||||
uint32 z80_cycles_to_run;
|
||||
|
||||
if (state)
|
||||
{
|
||||
/* stop RESET process */
|
||||
if (!zbusreq && !zreset)
|
||||
{
|
||||
/* Z80 started */
|
||||
/* z80 was OFF during the last 68k cycles */
|
||||
/* we burn the appropriate number of z80 cycles */
|
||||
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
|
||||
count_z80 = z80_cycles_to_run;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* start RESET process */
|
||||
if (!zbusreq && zreset)
|
||||
{
|
||||
/* Z80 stopped */
|
||||
/* z80 was ON during the last 68k cycles */
|
||||
/* we execute the appropriate number of z80 cycles */
|
||||
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
|
||||
if (state)
|
||||
{
|
||||
/* stop RESET process */
|
||||
if (!zbusreq && !zreset)
|
||||
{
|
||||
/* Z80 started */
|
||||
/* z80 was OFF during the last 68k cycles */
|
||||
/* we burn the appropriate number of z80 cycles */
|
||||
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
|
||||
count_z80 = z80_cycles_to_run;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* start RESET process */
|
||||
if (!zbusreq && zreset)
|
||||
{
|
||||
/* Z80 stopped */
|
||||
/* z80 was ON during the last 68k cycles */
|
||||
/* we execute the appropriate number of z80 cycles */
|
||||
z80_cycles_to_run = line_z80 + ((count_m68k - line_m68k)*7)/15;
|
||||
current_z80 = z80_cycles_to_run - count_z80;
|
||||
if (current_z80 > 0) count_z80 += z80_execute(current_z80);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset Z80 & YM2612 */
|
||||
_YM2612_Reset();
|
||||
z80_reset ();
|
||||
}
|
||||
/* Reset Z80 & YM2612 */
|
||||
_YM2612_Reset();
|
||||
z80_reset ();
|
||||
}
|
||||
|
||||
zreset = state;
|
||||
zbusack = 1 ^ (zbusreq & zreset);
|
||||
zreset = state;
|
||||
zbusack = 1 ^ (zbusreq & zreset);
|
||||
}
|
||||
|
||||
void gen_bank_w (uint32 state)
|
||||
{
|
||||
zbank = ((zbank >> 1) | ((state & 1) << 23)) & 0xFF8000;
|
||||
zbank = ((zbank >> 1) | ((state & 1) << 23)) & 0xFF8000;
|
||||
}
|
||||
|
||||
int z80_irq_callback (int param)
|
||||
{
|
||||
zirq = 0;
|
||||
z80_set_irq_line (0, CLEAR_LINE);
|
||||
return 0xFF;
|
||||
zirq = 0;
|
||||
z80_set_irq_line (0, CLEAR_LINE);
|
||||
return 0xFF;
|
||||
}
|
||||
|
183
source/hvc.h
183
source/hvc.h
@ -125,41 +125,41 @@
|
||||
|
||||
/* V counter values for NTSC 192-line display */
|
||||
uint8 vc_ntsc_192[262] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
|
||||
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
|
||||
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
};
|
||||
|
||||
/* V counter values for NTSC 224-line display */
|
||||
uint8 vc_ntsc_224[262] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
|
||||
0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||
@ -167,20 +167,20 @@ uint8 vc_ntsc_224[262] = {
|
||||
|
||||
/* V counter values for NTSC 240-line display (invalid mode) */
|
||||
uint8 vc_ntsc_240[262] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
|
||||
@ -188,20 +188,20 @@ uint8 vc_ntsc_240[262] = {
|
||||
|
||||
/* V counter values for PAL 192-line display */
|
||||
uint8 vc_pal_192[313] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2,
|
||||
0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6,
|
||||
@ -213,20 +213,20 @@ uint8 vc_pal_192[313] = {
|
||||
|
||||
/* V counter values for PAL 224-line display */
|
||||
uint8 vc_pal_224[313] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||
0x00, 0x01, 0x02,
|
||||
@ -238,20 +238,20 @@ uint8 vc_pal_224[313] = {
|
||||
|
||||
/* V counter values for PAL 240-line display */
|
||||
uint8 vc_pal_240[313] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
|
||||
@ -340,7 +340,7 @@ uint8 cycle2hc32[488] = {
|
||||
0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8A, 0x8A, 0x8A,
|
||||
0x8B, 0x8B, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8D, 0x8E, 0x8E, 0x8E, 0x8F, 0x8F, 0x8F, 0x90, 0x90,
|
||||
0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x93, 0x93,
|
||||
0xE9, 0xE9, 0xE9, 0xEA, 0xEA, 0xEA,
|
||||
0xE9, 0xE9, 0xE9, 0xEA, 0xEA, 0xEA,
|
||||
0xEB, 0xEB, 0xEB, 0xEC, 0xEC, 0xEC, 0xED, 0xED, 0xED, 0xEE, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0, 0xF0,
|
||||
0xF0, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, 0xF2, 0xF3, 0xF3, 0xF3, 0xF4, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6,
|
||||
0xF6, 0xF6, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF8, 0xF9, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB,
|
||||
@ -372,9 +372,9 @@ uint8 cycle2hc32[488] = {
|
||||
};
|
||||
|
||||
uint8 cycle2hc40[488] = {
|
||||
0xA4, 0xA5, 0xA5, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA8, 0xA8, 0xA9, 0xA9, 0xAA, 0xAA,
|
||||
0xAA, 0xAB, 0xAB, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAF, 0xAF, 0xB0, 0xB0, 0xB1, 0xB1,
|
||||
0xB1, 0xB2, 0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6,
|
||||
0xA4, 0xA5, 0xA5, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA8, 0xA8, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAB,
|
||||
0xAB, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAF, 0xAF, 0xB0, 0xB0, 0xB1, 0xB1, 0xB1, 0xB2,
|
||||
0xB2, 0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB5, 0xB5, 0xB6, 0xB6,
|
||||
0xE4, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6, 0xE6,
|
||||
0xE7, 0xE7, 0xE7, 0xE8, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED,
|
||||
0xEE, 0xEE, 0xEE, 0xEF, 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4,
|
||||
@ -406,7 +406,6 @@ uint8 cycle2hc40[488] = {
|
||||
0xA1, 0xA2, 0xA2, 0xA3, 0xA3, 0xA4, 0xA4,
|
||||
};
|
||||
|
||||
|
||||
uint8 *vctab;
|
||||
uint8 *hctab;
|
||||
|
||||
|
310
source/loadrom.c
310
source/loadrom.c
@ -25,48 +25,48 @@
|
||||
#include "shared.h"
|
||||
|
||||
/*** ROM Information ***/
|
||||
#define ROMCONSOLE 256
|
||||
#define ROMCOPYRIGHT 272
|
||||
#define ROMDOMESTIC 288
|
||||
#define ROMWORLD 336
|
||||
#define ROMTYPE 384
|
||||
#define ROMPRODUCT 386
|
||||
#define ROMCHECKSUM 398
|
||||
#define ROMIOSUPPORT 400
|
||||
#define ROMROMSTART 416
|
||||
#define ROMROMEND 420
|
||||
#define ROMRAMINFO 424
|
||||
#define ROMRAMSTART 436
|
||||
#define ROMRAMEND 440
|
||||
#define ROMMODEMINFO 444
|
||||
#define ROMMEMO 456
|
||||
#define ROMCOUNTRY 496
|
||||
#define ROMCONSOLE 256
|
||||
#define ROMCOPYRIGHT 272
|
||||
#define ROMDOMESTIC 288
|
||||
#define ROMWORLD 336
|
||||
#define ROMTYPE 384
|
||||
#define ROMPRODUCT 386
|
||||
#define ROMCHECKSUM 398
|
||||
#define ROMIOSUPPORT 400
|
||||
#define ROMROMSTART 416
|
||||
#define ROMROMEND 420
|
||||
#define ROMRAMINFO 424
|
||||
#define ROMRAMSTART 436
|
||||
#define ROMRAMEND 440
|
||||
#define ROMMODEMINFO 444
|
||||
#define ROMMEMO 456
|
||||
#define ROMCOUNTRY 496
|
||||
|
||||
#define P3BUTTONS 1
|
||||
#define P6BUTTONS 2
|
||||
#define PKEYBOARD 4
|
||||
#define PPRINTER 8
|
||||
#define PBALL 16
|
||||
#define PFLOPPY 32
|
||||
#define PACTIVATOR 64
|
||||
#define P3BUTTONS 1
|
||||
#define P6BUTTONS 2
|
||||
#define PKEYBOARD 4
|
||||
#define PPRINTER 8
|
||||
#define PBALL 16
|
||||
#define PFLOPPY 32
|
||||
#define PACTIVATOR 64
|
||||
#define PTEAMPLAYER 128
|
||||
#define PMSYSTEMPAD 256
|
||||
#define PSERIAL 512
|
||||
#define PTABLET 1024
|
||||
#define PPADDLE 2048
|
||||
#define PCDROM 4096
|
||||
#define PMOUSE 8192
|
||||
#define PTABLET 1024
|
||||
#define PPADDLE 2048
|
||||
#define PCDROM 4096
|
||||
#define PMOUSE 8192
|
||||
|
||||
int peripherals;
|
||||
uint16 realchecksum;
|
||||
ROMINFO rominfo;
|
||||
|
||||
/***************************************************************************
|
||||
/***************************************************************************
|
||||
* Genesis ROM Manufacturers
|
||||
*
|
||||
* Based on the document provided at
|
||||
* http://www.zophar.net/tech/files/Genesis_ROM_Format.txt
|
||||
***************************************************************************/
|
||||
**************************************************************************/
|
||||
COMPANYINFO companyinfo[MAXCOMPANY] = {
|
||||
{"ACLD", "Ballistic"},
|
||||
{"RSI", "Razorsoft"},
|
||||
@ -186,35 +186,35 @@ uint16 GetRealChecksum (uint8 *rom, int length)
|
||||
****************************************************************************/
|
||||
int getcompany ()
|
||||
{
|
||||
char *s;
|
||||
int i;
|
||||
char company[10];
|
||||
char *s;
|
||||
int i;
|
||||
char company[10];
|
||||
|
||||
for (i = 3; i < 8; i++) company[i - 3] = rominfo.copyright[i];
|
||||
company[5] = 0;
|
||||
for (i = 3; i < 8; i++) company[i - 3] = rominfo.copyright[i];
|
||||
company[5] = 0;
|
||||
|
||||
/** OK, first look for a hyphen
|
||||
* Capcom use T-12 for example
|
||||
*/
|
||||
s = strstr (company, "-");
|
||||
if (s != NULL)
|
||||
{
|
||||
s++;
|
||||
strcpy (company, s);
|
||||
}
|
||||
/** OK, first look for a hyphen
|
||||
* Capcom use T-12 for example
|
||||
*/
|
||||
s = strstr (company, "-");
|
||||
if (s != NULL)
|
||||
{
|
||||
s++;
|
||||
strcpy (company, s);
|
||||
}
|
||||
|
||||
/** Strip any trailing spaces **/
|
||||
for (i = strlen (company) - 1; i >= 0; i--)
|
||||
/** Strip any trailing spaces **/
|
||||
for (i = strlen (company) - 1; i >= 0; i--)
|
||||
if (company[i] == 32) company[i] = 0;
|
||||
|
||||
if (strlen (company) == 0) return MAXCOMPANY - 1;
|
||||
if (strlen (company) == 0) return MAXCOMPANY - 1;
|
||||
|
||||
for (i = 0; i < MAXCOMPANY - 1; i++)
|
||||
{
|
||||
if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) return i;
|
||||
}
|
||||
for (i = 0; i < MAXCOMPANY - 1; i++)
|
||||
{
|
||||
if (!(strncmp (company, companyinfo[i].companyid, strlen (company)))) return i;
|
||||
}
|
||||
|
||||
return MAXCOMPANY - 1;
|
||||
return MAXCOMPANY - 1;
|
||||
}
|
||||
|
||||
|
||||
@ -236,11 +236,11 @@ void getrominfo (char *romheader)
|
||||
j=1;
|
||||
for (i=1; i<48; i++)
|
||||
{
|
||||
if ((rominfo.domestic[j-1] != 32) || (romheader[ROMDOMESTIC + i] != 32))
|
||||
{
|
||||
rominfo.domestic[j] = romheader[ROMDOMESTIC + i];
|
||||
j++;
|
||||
}
|
||||
if ((rominfo.domestic[j-1] != 32) || (romheader[ROMDOMESTIC + i] != 32))
|
||||
{
|
||||
rominfo.domestic[j] = romheader[ROMDOMESTIC + i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
rominfo.domestic[j] = 0;
|
||||
|
||||
@ -248,11 +248,11 @@ void getrominfo (char *romheader)
|
||||
j=1;
|
||||
for (i=1; i<48; i++)
|
||||
{
|
||||
if ((rominfo.international[j-1] != 32) || (romheader[ROMWORLD + i] != 32))
|
||||
{
|
||||
rominfo.international[j] = romheader[ROMWORLD + i];
|
||||
j++;
|
||||
}
|
||||
if ((rominfo.international[j-1] != 32) || (romheader[ROMWORLD + i] != 32))
|
||||
{
|
||||
rominfo.international[j] = romheader[ROMWORLD + i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
rominfo.international[j] = 0;
|
||||
|
||||
@ -277,8 +277,8 @@ void getrominfo (char *romheader)
|
||||
peripherals = 0;
|
||||
|
||||
for (i = 0; i < 14; i++)
|
||||
for (j=0; j < 14; j++)
|
||||
if (rominfo.io_support[i] == peripheralinfo[j].pID[0]) peripherals |= (1 << j);
|
||||
for (j=0; j < 14; j++)
|
||||
if (rominfo.io_support[i] == peripheralinfo[j].pID[0]) peripherals |= (1 << j);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
@ -292,63 +292,63 @@ void getrominfo (char *romheader)
|
||||
/* 05/05/2006: new region detection routine (taken from GENS sourcecode) */
|
||||
void set_region ()
|
||||
{
|
||||
/* country codes used to differentiate region */
|
||||
/* 0001 = japan ntsc (1) */
|
||||
/* 0010 = japan pal (2) */
|
||||
/* 0100 = usa (4) */
|
||||
/* 1000 = europe (8) */
|
||||
/* country codes used to differentiate region */
|
||||
/* 0001 = japan ntsc (1) */
|
||||
/* 0010 = japan pal (2) */
|
||||
/* 0100 = usa (4) */
|
||||
/* 1000 = europe (8) */
|
||||
|
||||
int country = 0;
|
||||
int i = 0;
|
||||
char c;
|
||||
int country = 0;
|
||||
int i = 0;
|
||||
char c;
|
||||
|
||||
/* reading header to find the country */
|
||||
if (!strnicmp(rominfo.country, "eur", 3)) country |= 8;
|
||||
else if (!strnicmp(rominfo.country, "usa", 3)) country |= 4;
|
||||
else if (!strnicmp(rominfo.country, "jap", 3)) country |= 1;
|
||||
/* reading header to find the country */
|
||||
if (!strnicmp(rominfo.country, "eur", 3)) country |= 8;
|
||||
else if (!strnicmp(rominfo.country, "usa", 3)) country |= 4;
|
||||
else if (!strnicmp(rominfo.country, "jap", 3)) country |= 1;
|
||||
|
||||
else for(i = 0; i < 4; i++)
|
||||
{
|
||||
c = toupper((int)rominfo.country[i]);
|
||||
if (c == 'U') country |= 4;
|
||||
else if (c == 'J') country |= 1;
|
||||
else if (c == 'E') country |= 8;
|
||||
else if (c < 16) country |= c;
|
||||
else if ((c >= '0') && (c <= '9')) country |= c - '0';
|
||||
else if ((c >= 'A') && (c <= 'F')) country |= c - 'A' + 10;
|
||||
}
|
||||
else for(i = 0; i < 4; i++)
|
||||
{
|
||||
c = toupper((int)rominfo.country[i]);
|
||||
if (c == 'U') country |= 4;
|
||||
else if (c == 'J') country |= 1;
|
||||
else if (c == 'E') country |= 8;
|
||||
else if (c < 16) country |= c;
|
||||
else if ((c >= '0') && (c <= '9')) country |= c - '0';
|
||||
else if ((c >= 'A') && (c <= 'F')) country |= c - 'A' + 10;
|
||||
}
|
||||
|
||||
/* automatic detection */
|
||||
/* setting region */
|
||||
/* this is used by IO register */
|
||||
if (country & 4) region_code = REGION_USA;
|
||||
else if (country & 1) region_code = REGION_JAPAN_NTSC;
|
||||
else if (country & 8) region_code = REGION_EUROPE;
|
||||
else if (country & 2) region_code = REGION_JAPAN_PAL;
|
||||
else region_code = REGION_USA;
|
||||
/* automatic detection */
|
||||
/* setting region */
|
||||
/* this is used by IO register */
|
||||
if (country & 4) region_code = REGION_USA;
|
||||
else if (country & 1) region_code = REGION_JAPAN_NTSC;
|
||||
else if (country & 8) region_code = REGION_EUROPE;
|
||||
else if (country & 2) region_code = REGION_JAPAN_PAL;
|
||||
else region_code = REGION_USA;
|
||||
|
||||
/* some games need specific REGION setting */
|
||||
/* some games need specific REGION setting */
|
||||
if (((strstr(rominfo.product,"T-45033") != NULL) && (rominfo.checksum == 0x0F81)) || /* Alisia Dragon (E) */
|
||||
(strstr(rominfo.product,"T-69046-50") != NULL)) /* On Dal Jang Goon (Korea) */
|
||||
{
|
||||
/* need PAL settings */
|
||||
region_code = REGION_EUROPE;
|
||||
}
|
||||
else if ((realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL))
|
||||
{
|
||||
/* On Dal Jang Goon (Korea) needs JAP region code */
|
||||
region_code = REGION_JAPAN_NTSC;
|
||||
}
|
||||
(strstr(rominfo.product,"T-69046-50") != NULL)) /* On Dal Jang Goon (Korea) */
|
||||
{
|
||||
/* need PAL settings */
|
||||
region_code = REGION_EUROPE;
|
||||
}
|
||||
else if ((realchecksum == 0x532e) && (strstr(rominfo.product,"1011-00") != NULL))
|
||||
{
|
||||
/* On Dal Jang Goon (Korea) needs JAP region code */
|
||||
region_code = REGION_JAPAN_NTSC;
|
||||
}
|
||||
|
||||
/* Force region setting */
|
||||
if (config.region_detect == 1) region_code = REGION_USA;
|
||||
else if (config.region_detect == 2) region_code = REGION_EUROPE;
|
||||
else if (config.region_detect == 3) region_code = REGION_JAPAN_NTSC;
|
||||
else if (config.region_detect == 4) region_code = REGION_JAPAN_PAL;
|
||||
/* Force region setting */
|
||||
if (config.region_detect == 1) region_code = REGION_USA;
|
||||
else if (config.region_detect == 2) region_code = REGION_EUROPE;
|
||||
else if (config.region_detect == 3) region_code = REGION_JAPAN_NTSC;
|
||||
else if (config.region_detect == 4) region_code = REGION_JAPAN_PAL;
|
||||
|
||||
/* set cpu/vdp speed: PAL or NTSC */
|
||||
if ((region_code == REGION_EUROPE) || (region_code == REGION_JAPAN_PAL)) vdp_pal = 1;
|
||||
else vdp_pal = 0;
|
||||
/* set cpu/vdp speed: PAL or NTSC */
|
||||
if ((region_code == REGION_EUROPE) || (region_code == REGION_JAPAN_PAL)) vdp_pal = 1;
|
||||
else vdp_pal = 0;
|
||||
}
|
||||
|
||||
/* SMD (interleaved) rom support */
|
||||
@ -370,64 +370,64 @@ int load_rom(char *filename)
|
||||
int i, size, offset = 0;
|
||||
|
||||
#ifdef NGC
|
||||
size = genromsize;
|
||||
size = genromsize;
|
||||
#else
|
||||
uint8 *ptr;
|
||||
ptr = load_archive(filename, &size);
|
||||
uint8 *ptr;
|
||||
ptr = load_archive(filename, &size);
|
||||
if(!ptr) return (0);
|
||||
memcpy(cart_rom, ptr + offset, size);
|
||||
free(ptr);
|
||||
#endif
|
||||
|
||||
/* detect interleaved roms (.smd format) */
|
||||
if (strncmp((char *)(cart_rom + 0x100),"SEGA", 4) && ((size / 512) & 1))
|
||||
{
|
||||
size -= 512;
|
||||
offset += 512;
|
||||
/* detect interleaved roms (.smd format) */
|
||||
if (strncmp((char *)(cart_rom + 0x100),"SEGA", 4) && ((size / 512) & 1))
|
||||
{
|
||||
size -= 512;
|
||||
offset += 512;
|
||||
|
||||
for (i = 0; i < (size / 0x4000); i += 1)
|
||||
{
|
||||
deinterleave_block (cart_rom + offset + (i * 0x4000));
|
||||
}
|
||||
for (i = 0; i < (size / 0x4000); i += 1)
|
||||
{
|
||||
deinterleave_block (cart_rom + offset + (i * 0x4000));
|
||||
}
|
||||
|
||||
memcpy(cart_rom, cart_rom + offset, size);
|
||||
}
|
||||
memcpy(cart_rom, cart_rom + offset, size);
|
||||
}
|
||||
|
||||
/* max. 10 MBytes supported */
|
||||
if (size > 0xA00000) size = 0xA00000;
|
||||
genromsize = size;
|
||||
|
||||
/* clear unused ROM space */
|
||||
if (size < 0xA00000) memset (cart_rom + size, 0x00, 0xA00000 - size);
|
||||
/* max. 10 MBytes supported */
|
||||
if (size > 0xA00000) size = 0xA00000;
|
||||
genromsize = size;
|
||||
|
||||
/* clear unused ROM space */
|
||||
if (size < 0xA00000) memset (cart_rom + size, 0x00, 0xA00000 - size);
|
||||
|
||||
getrominfo((char *)cart_rom); /* get infos from ROM header */
|
||||
set_region(); /* set game region (PAL/NTSC, JAP/USA/EUR) */
|
||||
getrominfo((char *)cart_rom); /* get infos from ROM header */
|
||||
set_region(); /* set game region (PAL/NTSC, JAP/USA/EUR) */
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
/* Byteswap ROM */
|
||||
uint8 temp;
|
||||
for(i = 0; i < genromsize; i += 2)
|
||||
{
|
||||
temp = cart_rom[i];
|
||||
cart_rom[i] = cart_rom[i+1];
|
||||
cart_rom[i+1] = temp;
|
||||
}
|
||||
/* Byteswap ROM */
|
||||
uint8 temp;
|
||||
for(i = 0; i < genromsize; i += 2)
|
||||
{
|
||||
temp = cart_rom[i];
|
||||
cart_rom[i] = cart_rom[i+1];
|
||||
cart_rom[i+1] = temp;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* byteswapped RADICA dumps (from Haze) */
|
||||
if (((strstr(rominfo.product,"-K0101") != NULL) && (rominfo.checksum == 0xf424)) ||
|
||||
((strstr(rominfo.product,"-K0109") != NULL) && (rominfo.checksum == 0x4f10)))
|
||||
{
|
||||
uint8 temp;
|
||||
for(i = 0; i < genromsize; i += 2)
|
||||
{
|
||||
temp = cart_rom[i];
|
||||
cart_rom[i] = cart_rom[i+1];
|
||||
cart_rom[i+1] = temp;
|
||||
}
|
||||
}
|
||||
/* byteswapped RADICA dumps (from Haze) */
|
||||
if (((strstr(rominfo.product,"-K0101") != NULL) && (rominfo.checksum == 0xf424)) ||
|
||||
((strstr(rominfo.product,"-K0109") != NULL) && (rominfo.checksum == 0x4f10)))
|
||||
{
|
||||
uint8 temp;
|
||||
for(i = 0; i < genromsize; i += 2)
|
||||
{
|
||||
temp = cart_rom[i];
|
||||
cart_rom[i] = cart_rom[i+1];
|
||||
cart_rom[i+1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/* console hardware */
|
||||
/* console hardware */
|
||||
if (strstr(rominfo.consoletype, "SEGA PICO") != NULL) system_hw = SYSTEM_PICO;
|
||||
else if (strstr(rominfo.consoletype, "SEGA MEGADRIVE") != NULL) system_hw = SYSTEM_MEGADRIVE;
|
||||
else system_hw = SYSTEM_GENESIS;
|
||||
|
@ -27,22 +27,22 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char consoletype[18]; /* Genesis or Mega Drive */
|
||||
char copyright[18]; /* Copyright message */
|
||||
char domestic[50]; /* Domestic name of ROM */
|
||||
char international[50]; /* International name of ROM */
|
||||
char ROMType[4]; /* Educational or Game */
|
||||
char product[14]; /* Product serial number */
|
||||
unsigned short checksum; /* Checksum */
|
||||
char io_support[18]; /* Actually 16 chars :) */
|
||||
unsigned int romstart;
|
||||
unsigned int romend;
|
||||
char RAMInfo[14];
|
||||
unsigned int ramstart;
|
||||
unsigned int ramend;
|
||||
char modem[14];
|
||||
char memo[50];
|
||||
char country[18];
|
||||
char consoletype[18]; /* Genesis or Mega Drive */
|
||||
char copyright[18]; /* Copyright message */
|
||||
char domestic[50]; /* Domestic name of ROM */
|
||||
char international[50]; /* International name of ROM */
|
||||
char ROMType[4]; /* Educational or Game */
|
||||
char product[14]; /* Product serial number */
|
||||
unsigned short checksum; /* Checksum */
|
||||
char io_support[18]; /* Actually 16 chars :) */
|
||||
unsigned int romstart; /* ROM start address */
|
||||
unsigned int romend; /* ROM end address */
|
||||
char RAMInfo[14]; /* Backup RAM header */
|
||||
unsigned int ramstart; /* RAM start address */
|
||||
unsigned int ramend; /* RAM end address */
|
||||
char modem[14]; /* Sega Modem support */
|
||||
char memo[50]; /* Misc */
|
||||
char country[18]; /* Country flag */
|
||||
} ROMINFO;
|
||||
|
||||
typedef struct
|
||||
|
@ -4,20 +4,23 @@
|
||||
#ifdef LSB_FIRST
|
||||
|
||||
#define READ_BYTE(BASE, ADDR) (BASE)[(ADDR)^1]
|
||||
#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | \
|
||||
(BASE)[(ADDR)+1])
|
||||
#define READ_WORD_LONG(BASE, ADDR) (((BASE)[ADDR]<<24) | \
|
||||
((BASE)[(ADDR)+1]<<16) | \
|
||||
((BASE)[(ADDR)+2]<<8) | \
|
||||
(BASE)[(ADDR)+3])
|
||||
|
||||
#define READ_WORD(BASE, ADDR) (((BASE)[ADDR]<<8) | (BASE)[(ADDR)+1])
|
||||
|
||||
#define READ_WORD_LONG(BASE, ADDR) (((BASE)[ADDR]<<24) | \
|
||||
((BASE)[(ADDR)+1]<<16) | \
|
||||
((BASE)[(ADDR)+2]<<8) | \
|
||||
(BASE)[(ADDR)+3])
|
||||
|
||||
#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)&0xff
|
||||
#define WRITE_WORD(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>8) & 0xff; \
|
||||
(BASE)[(ADDR)+1] = (VAL)&0xff
|
||||
#define WRITE_WORD_LONG(BASE, ADDR, VAL) (BASE)[(ADDR] = ((VAL)>>24) & 0xff; \
|
||||
(BASE)[(ADDR)+1] = ((VAL)>>16)&0xff; \
|
||||
(BASE)[(ADDR)+2] = ((VAL)>>8)&0xff; \
|
||||
(BASE)[(ADDR)+3] = (VAL)&0xff
|
||||
|
||||
#define WRITE_WORD(BASE, ADDR, VAL) (BASE)[ADDR] = ((VAL)>>8) & 0xff; \
|
||||
(BASE)[(ADDR)+1] = (VAL)&0xff
|
||||
|
||||
#define WRITE_WORD_LONG(BASE, ADDR, VAL) (BASE)[(ADDR] = ((VAL)>>24) & 0xff; \
|
||||
(BASE)[(ADDR)+1] = ((VAL)>>16)&0xff; \
|
||||
(BASE)[(ADDR)+2] = ((VAL)>>8)&0xff; \
|
||||
(BASE)[(ADDR)+3] = (VAL)&0xff
|
||||
|
||||
#else
|
||||
|
||||
|
@ -32,7 +32,7 @@ uint32 zbank_unused_r(uint32 address)
|
||||
#ifdef LOGERROR
|
||||
error("Z80 bank unused read %06X\n", address);
|
||||
#endif
|
||||
return (address & 1) ? 0x00 : 0xFF;
|
||||
return (address & 1) ? 0x00 : 0xFF;
|
||||
}
|
||||
|
||||
void zbank_unused_w(uint32 address, uint32 data)
|
||||
@ -47,7 +47,7 @@ uint32 zbank_lockup_r(uint32 address)
|
||||
#ifdef LOGERROR
|
||||
error("Z80 bank lockup read %06X\n", address);
|
||||
#endif
|
||||
gen_running = config.force_dtack;
|
||||
gen_running = config.force_dtack;
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ void zbank_lockup_w(uint32 address, uint32 data)
|
||||
#ifdef LOGERROR
|
||||
error("Z80 bank lockup write %06X = %02X\n", address, data);
|
||||
#endif
|
||||
gen_running = config.force_dtack;
|
||||
gen_running = config.force_dtack;
|
||||
}
|
||||
|
||||
/* I/O & Control registers */
|
||||
@ -64,57 +64,57 @@ uint32 zbank_read_ctrl_io(uint32 address)
|
||||
{
|
||||
switch ((address >> 8) & 0xff)
|
||||
{
|
||||
case 0x00: /* I/O chip */
|
||||
case 0x00: /* I/O chip */
|
||||
if (address & 0xe0) return zbank_unused_r(address);
|
||||
else return (io_read((address >> 1) & 0x0f));
|
||||
|
||||
case 0x11: /* BUSACK */
|
||||
case 0x11: /* BUSACK */
|
||||
if (address & 1) return zbank_unused_r(address);
|
||||
else return (0xfe | zbusack);
|
||||
|
||||
case 0x30: /* TIME */
|
||||
case 0x30: /* TIME */
|
||||
if (cart_hw.time_r) return cart_hw.time_r(address);
|
||||
else return zbank_unused_r(address);
|
||||
|
||||
case 0x10: /* MEMORY MODE */
|
||||
case 0x12: /* RESET */
|
||||
case 0x20: /* MEGA-CD */
|
||||
case 0x40: /* TMSS */
|
||||
case 0x41: /* BOOTROM */
|
||||
case 0x44: /* RADICA */
|
||||
case 0x50: /* SVP REGISTERS */
|
||||
case 0x10: /* MEMORY MODE */
|
||||
case 0x12: /* RESET */
|
||||
case 0x20: /* MEGA-CD */
|
||||
case 0x40: /* TMSS */
|
||||
case 0x41: /* BOOTROM */
|
||||
case 0x44: /* RADICA */
|
||||
case 0x50: /* SVP REGISTERS */
|
||||
return zbank_unused_r(address);
|
||||
|
||||
default: /* Invalid address */
|
||||
default: /* Invalid address */
|
||||
return zbank_lockup_r(address);
|
||||
}
|
||||
}
|
||||
|
||||
void zbank_write_ctrl_io(uint32 address, uint32 data)
|
||||
{
|
||||
{
|
||||
switch ((address >> 8) & 0xff)
|
||||
{
|
||||
case 0x00: /* I/O chip */
|
||||
case 0x00: /* I/O chip */
|
||||
if ((address & 0xe1) == 0x01) io_write((address >> 1) & 0x0f, data); /* get /LWR only */
|
||||
else zbank_unused_w(address, data);
|
||||
return;
|
||||
|
||||
case 0x11: /* BUSREQ */
|
||||
case 0x11: /* BUSREQ */
|
||||
if (address & 1) zbank_unused_w(address, data);
|
||||
else gen_busreq_w(data & 1);
|
||||
return;
|
||||
|
||||
case 0x12: /* RESET */
|
||||
case 0x12: /* RESET */
|
||||
if (address & 1) zbank_unused_w(address, data);
|
||||
else gen_reset_w(data & 1);
|
||||
return;
|
||||
|
||||
case 0x30: /* TIME */
|
||||
case 0x30: /* TIME */
|
||||
if (cart_hw.time_w) cart_hw.time_w(address, data);
|
||||
else zbank_unused_w(address, data);
|
||||
return;
|
||||
|
||||
case 0x41: /* BOOTROM */
|
||||
case 0x41: /* BOOTROM */
|
||||
if (address & 1)
|
||||
{
|
||||
m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom;
|
||||
@ -130,15 +130,15 @@ void zbank_write_ctrl_io(uint32 address, uint32 data)
|
||||
else zbank_unused_w (address, data);
|
||||
return;
|
||||
|
||||
case 0x10: /* MEMORY MODE */
|
||||
case 0x20: /* MEGA-CD */
|
||||
case 0x40: /* TMSS */
|
||||
case 0x44: /* RADICA */
|
||||
case 0x10: /* MEMORY MODE */
|
||||
case 0x20: /* MEGA-CD */
|
||||
case 0x40: /* TMSS */
|
||||
case 0x44: /* RADICA */
|
||||
case 0x50: /* SVP REGISTERS */
|
||||
zbank_unused_w(address, data);
|
||||
return;
|
||||
|
||||
default: /* Invalid address */
|
||||
default: /* Invalid address */
|
||||
zbank_lockup_w(address, data);
|
||||
return;
|
||||
}
|
||||
@ -150,33 +150,33 @@ uint32 zbank_read_vdp(uint32 address)
|
||||
{
|
||||
switch (address & 0xfd)
|
||||
{
|
||||
case 0x00: /* DATA */
|
||||
case 0x00: /* DATA */
|
||||
return (vdp_data_r() >> 8);
|
||||
|
||||
case 0x01: /* DATA */
|
||||
|
||||
case 0x01: /* DATA */
|
||||
return (vdp_data_r() & 0xff);
|
||||
|
||||
case 0x04: /* CTRL */
|
||||
|
||||
case 0x04: /* CTRL */
|
||||
return (0xfc | ((vdp_ctrl_r() >> 8) & 3));
|
||||
|
||||
case 0x05: /* CTRL */
|
||||
case 0x05: /* CTRL */
|
||||
return (vdp_ctrl_r() & 0xff);
|
||||
|
||||
case 0x08: /* HVC */
|
||||
|
||||
case 0x08: /* HVC */
|
||||
case 0x0c:
|
||||
return (vdp_hvc_r() >> 8);
|
||||
|
||||
case 0x09: /* HVC */
|
||||
|
||||
case 0x09: /* HVC */
|
||||
case 0x0d:
|
||||
return (vdp_hvc_r() & 0xff);
|
||||
|
||||
case 0x18: /* Unused */
|
||||
|
||||
case 0x18: /* Unused */
|
||||
case 0x19:
|
||||
case 0x1c:
|
||||
case 0x1d:
|
||||
return zbank_unused_r(address);
|
||||
|
||||
default: /* Invalid address */
|
||||
default: /* Invalid address */
|
||||
return zbank_lockup_r(address);
|
||||
}
|
||||
}
|
||||
@ -185,15 +185,15 @@ void zbank_write_vdp(uint32 address, uint32 data)
|
||||
{
|
||||
switch (address & 0xfc)
|
||||
{
|
||||
case 0x00: /* Data port */
|
||||
case 0x00: /* Data port */
|
||||
vdp_data_w(data << 8 | data);
|
||||
return;
|
||||
|
||||
case 0x04: /* Control port */
|
||||
case 0x04: /* Control port */
|
||||
vdp_ctrl_w(data << 8 | data);
|
||||
return;
|
||||
|
||||
case 0x10: /* PSG */
|
||||
case 0x10: /* PSG */
|
||||
case 0x14:
|
||||
if (address & 1) psg_write(0, data);
|
||||
else zbank_unused_w(address, data);
|
||||
@ -207,7 +207,7 @@ void zbank_write_vdp(uint32 address, uint32 data)
|
||||
vdp_test_w(data << 8 | data);
|
||||
return;
|
||||
|
||||
default: /* Invalid address */
|
||||
default: /* Invalid address */
|
||||
zbank_lockup_w(address, data);
|
||||
return;
|
||||
}
|
||||
|
@ -24,8 +24,8 @@
|
||||
#define LOG_PORT 0 /* 1= Log Z80 I/O port accesses */
|
||||
|
||||
/*
|
||||
Handlers for access to unused addresses and those which make the
|
||||
machine lock up.
|
||||
Handlers for access to unused addresses and those which make the
|
||||
machine lock up.
|
||||
*/
|
||||
static inline void z80_unused_w(unsigned int address, unsigned int data)
|
||||
{
|
||||
@ -39,7 +39,7 @@ static inline unsigned int z80_unused_r(unsigned int address)
|
||||
#ifdef LOGERROR
|
||||
error("Z80 unused read %04X\n", address);
|
||||
#endif
|
||||
return 0xff;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static inline void z80_lockup_w(unsigned int address, unsigned int data)
|
||||
@ -47,7 +47,7 @@ static inline void z80_lockup_w(unsigned int address, unsigned int data)
|
||||
#ifdef LOGERROR
|
||||
error("Z80 lockup write %04X = %02X\n", address, data);
|
||||
#endif
|
||||
gen_running = config.force_dtack;
|
||||
gen_running = config.force_dtack;
|
||||
}
|
||||
|
||||
static inline unsigned int z80_lockup_r(unsigned int address)
|
||||
@ -55,8 +55,8 @@ static inline unsigned int z80_lockup_r(unsigned int address)
|
||||
#ifdef LOGERROR
|
||||
error("Z80 lockup read %04X\n", address);
|
||||
#endif
|
||||
gen_running = config.force_dtack;
|
||||
return 0xff;
|
||||
gen_running = config.force_dtack;
|
||||
return 0xff;
|
||||
}
|
||||
/*
|
||||
VDP access
|
||||
@ -85,34 +85,34 @@ static inline unsigned int z80_vdp_r(unsigned int address)
|
||||
case 0x0d:
|
||||
return (vdp_hvc_r() & 0xff);
|
||||
|
||||
case 0x18: /* Unused */
|
||||
case 0x19:
|
||||
case 0x18: /* Unused */
|
||||
case 0x19:
|
||||
case 0x1c:
|
||||
case 0x1d:
|
||||
return z80_unused_r(address);
|
||||
case 0x1d:
|
||||
return z80_unused_r(address);
|
||||
|
||||
default: /* Invalid address */
|
||||
return z80_lockup_r(address);
|
||||
}
|
||||
return z80_lockup_r(address);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void z80_vdp_w(unsigned int address, unsigned int data)
|
||||
{
|
||||
switch (address & 0xfc)
|
||||
{
|
||||
case 0x00: /* Data port */
|
||||
case 0x00: /* Data port */
|
||||
vdp_data_w(data << 8 | data);
|
||||
return;
|
||||
|
||||
case 0x04: /* Control port */
|
||||
case 0x04: /* Control port */
|
||||
vdp_ctrl_w(data << 8 | data);
|
||||
return;
|
||||
|
||||
case 0x10: /* PSG */
|
||||
case 0x10: /* PSG */
|
||||
case 0x14:
|
||||
if (address & 1) psg_write(0, data);
|
||||
else z80_unused_w(address, data);
|
||||
return;
|
||||
return;
|
||||
|
||||
case 0x18: /* Unused */
|
||||
z80_unused_w(address, data);
|
||||
@ -122,7 +122,7 @@ static inline void z80_vdp_w(unsigned int address, unsigned int data)
|
||||
vdp_test_w(data << 8 | data);
|
||||
return;
|
||||
|
||||
default: /* Invalid address */
|
||||
default: /* Invalid address */
|
||||
z80_lockup_w(address, data);
|
||||
return;
|
||||
}
|
||||
@ -194,22 +194,22 @@ void cpu_writemem16(unsigned int address, unsigned int data)
|
||||
if (zbank_memory_map[slot].write) (*zbank_memory_map[slot].write)(address, data);
|
||||
else WRITE_BYTE(m68k_memory_map[slot].base, address&0xffff, data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Port handlers. Ports are unused when not in Mark III compatability mode.
|
||||
Port handlers. Ports are unused when not in Mark III compatability mode.
|
||||
|
||||
Games that access ports anyway:
|
||||
- Thunder Force IV reads port $BF in it's interrupt handler.
|
||||
Games that access ports anyway:
|
||||
Thunder Force IV reads port $BF in it's interrupt handler.
|
||||
*/
|
||||
|
||||
unsigned int cpu_readport16(unsigned int port)
|
||||
{
|
||||
#if LOG_PORT
|
||||
error("Z80 read port %04X\n", port);
|
||||
#endif
|
||||
#endif
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
@ -12,15 +12,19 @@
|
||||
|
||||
void config_save()
|
||||
{
|
||||
if (!use_FAT) return;
|
||||
char pathname[MAXPATHLEN];
|
||||
|
||||
if (!fat_enabled) return;
|
||||
|
||||
/* first check if directory exist */
|
||||
DIR_ITER *dir = diropen("/genplus");
|
||||
if (dir == NULL) mkdir("/genplus",S_IRWXU);
|
||||
sprintf (pathname, DEFAULT_PATH);
|
||||
DIR_ITER *dir = diropen(pathname);
|
||||
if (dir == NULL) mkdir(pathname,S_IRWXU);
|
||||
else dirclose(dir);
|
||||
|
||||
/* open configuration file */
|
||||
FILE *fp = fopen("/genplus/genplus.ini", "wb");
|
||||
sprintf (pathname, "%s/config.ini", pathname);
|
||||
FILE *fp = fopen(pathname, "wb");
|
||||
if (fp == NULL) return;
|
||||
|
||||
/* save options */
|
||||
@ -31,8 +35,11 @@ void config_save()
|
||||
|
||||
void config_load()
|
||||
{
|
||||
char pathname[MAXPATHLEN];
|
||||
|
||||
/* open configuration file */
|
||||
FILE *fp = fopen("/genplus/genplus.ini", "rb");
|
||||
sprintf (pathname, "%s/genplus.ini", DEFAULT_PATH);
|
||||
FILE *fp = fopen(pathname, "rb");
|
||||
if (fp == NULL) return;
|
||||
|
||||
/* read version */
|
||||
@ -42,7 +49,7 @@ void config_load()
|
||||
if (strcmp(version,CONFIG_VERSION)) return;
|
||||
|
||||
/* read file */
|
||||
fp = fopen("/genplus/genplus.ini", "rb");
|
||||
fp = fopen(pathname, "rb");
|
||||
fread(&config, sizeof(config), 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ t_config config;
|
||||
extern void config_save();
|
||||
extern void config_load();
|
||||
extern void set_config_defaults(void);
|
||||
extern bool use_FAT;
|
||||
extern bool fat_enabled;
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
||||
|
||||
|
@ -1,28 +1,17 @@
|
||||
/****************************************************************************
|
||||
* Nintendo Gamecube DVD Reading Library
|
||||
*
|
||||
* This is NOT a complete DVD library, in that it works for reading
|
||||
* ISO9660 discs only.
|
||||
* Low-Level DVD access
|
||||
*
|
||||
* If you need softmod drivecodes etc, look elsewhere.
|
||||
* There are known issues with libogc dvd handling, so these work
|
||||
* outside of it ,if you will.
|
||||
*
|
||||
* This is ideal for using with a gc-linux self booting DVD only.
|
||||
* Go http://www.gc-linux.org for further information and the tools
|
||||
* for your platform.
|
||||
*
|
||||
* To keep libOGC stable, make sure you call DVD_Init before using
|
||||
* these functions.
|
||||
***************************************************************************/
|
||||
#include "shared.h"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include "di/di.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HW_RVL
|
||||
static u64 DvdMaxOffset = 0x57057C00; /* 1.4 GB max. */
|
||||
static u64 DvdMaxOffset = 0x57057C00; /* 1.4 GB max. by default */
|
||||
static vu32* const dvd = (u32*)0xCC006000; /* DVD I/O Address base */
|
||||
static u8 *inquiry=(unsigned char *)0x80000004; /* pointer to drive ID */
|
||||
#else
|
||||
@ -32,7 +21,6 @@ static u64 DvdMaxOffset = 0x118244F00LL; /* 4.7 GB max. */
|
||||
static u8 DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32); /* data buffer for all DVD operations */
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* dvd_read
|
||||
*
|
||||
@ -85,19 +73,19 @@ u32 dvd_read (void *dst, u32 len, u64 offset)
|
||||
void dvd_motor_off( )
|
||||
{
|
||||
#ifndef HW_RVL
|
||||
dvd[0] = 0x2e;
|
||||
dvd[1] = 0;
|
||||
dvd[2] = 0xe3000000;
|
||||
dvd[3] = 0;
|
||||
dvd[4] = 0;
|
||||
dvd[5] = 0;
|
||||
dvd[6] = 0;
|
||||
dvd[7] = 1; // Do immediate
|
||||
while (dvd[7] & 1);
|
||||
dvd[0] = 0x2e;
|
||||
dvd[1] = 0;
|
||||
dvd[2] = 0xe3000000;
|
||||
dvd[3] = 0;
|
||||
dvd[4] = 0;
|
||||
dvd[5] = 0;
|
||||
dvd[6] = 0;
|
||||
dvd[7] = 1; // Do immediate
|
||||
while (dvd[7] & 1);
|
||||
|
||||
/*** PSO Stops blackscreen at reload ***/
|
||||
dvd[0] = 0x14;
|
||||
dvd[1] = 0;
|
||||
/*** PSO Stops blackscreen at reload ***/
|
||||
dvd[0] = 0x14;
|
||||
dvd[1] = 0;
|
||||
|
||||
#else
|
||||
DI_StopMotor();
|
19
source/ngc/dvd.h
Normal file
19
source/ngc/dvd.h
Normal 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
|
@ -9,8 +9,8 @@
|
||||
#include "dvd.h"
|
||||
#include "font.h"
|
||||
#include "unzip.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
/*
|
||||
* PKWare Zip Header - adopted into zip standard
|
||||
@ -24,7 +24,7 @@
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50
|
||||
unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50
|
||||
unsigned short zipversion __attribute__ ((__packed__));
|
||||
unsigned short zipflags __attribute__ ((__packed__));
|
||||
unsigned short compressionMethod __attribute__ ((__packed__));
|
||||
@ -119,34 +119,34 @@ int UnZipDVD (unsigned char *outbuffer, u64 discoffset, int length)
|
||||
{
|
||||
zs.avail_in = zipchunk;
|
||||
zs.next_in = (Bytef *) & readbuffer[zipoffset];
|
||||
|
||||
|
||||
/*** Now inflate until input buffer is exhausted ***/
|
||||
do
|
||||
{
|
||||
zs.avail_out = ZIPCHUNK;
|
||||
zs.next_out = (Bytef *) & out;
|
||||
res = inflate (&zs, Z_NO_FLUSH);
|
||||
{
|
||||
zs.avail_out = ZIPCHUNK;
|
||||
zs.next_out = (Bytef *) & out;
|
||||
res = inflate (&zs, Z_NO_FLUSH);
|
||||
|
||||
if (res == Z_MEM_ERROR)
|
||||
{
|
||||
inflateEnd (&zs);
|
||||
return 0;
|
||||
}
|
||||
if (res == Z_MEM_ERROR)
|
||||
{
|
||||
inflateEnd (&zs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
have = ZIPCHUNK - zs.avail_out;
|
||||
if (have)
|
||||
{
|
||||
have = ZIPCHUNK - zs.avail_out;
|
||||
if (have)
|
||||
{
|
||||
/*** Copy to normal block buffer ***/
|
||||
memcpy (&outbuffer[bufferoffset], &out, have);
|
||||
bufferoffset += have;
|
||||
}
|
||||
memcpy (&outbuffer[bufferoffset], &out, have);
|
||||
bufferoffset += have;
|
||||
}
|
||||
}
|
||||
while (zs.avail_out == 0);
|
||||
|
||||
/*** Readup the next 2k block ***/
|
||||
/*** Readup the next 2k block ***/
|
||||
zipoffset = 0;
|
||||
zipchunk = ZIPCHUNK;
|
||||
|
||||
|
||||
discoffset += 2048;
|
||||
dvd_read (&readbuffer, 2048, discoffset);
|
||||
}
|
||||
|
399
source/ngc/fileio_dvd.c
Normal file
399
source/ngc/fileio_dvd.c
Normal 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
14
source/ngc/fileio_dvd.h
Normal 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
313
source/ngc/fileio_fat.c
Normal 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
21
source/ngc/fileio_fat.h
Normal 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
|
@ -9,10 +9,8 @@
|
||||
#include "shared.h"
|
||||
|
||||
#define ARAMSTART 0x8000
|
||||
|
||||
|
||||
#define ARAM_READ 1
|
||||
#define ARAM_WRITE 0
|
||||
#define ARAM_READ 1
|
||||
#define ARAM_WRITE 0
|
||||
|
||||
/**
|
||||
* StartARAM
|
||||
@ -20,8 +18,7 @@
|
||||
* Passing NULL for array list, and 0 items to allocate.
|
||||
* Required so libOGC knows to handle any interrupts etc.
|
||||
*/
|
||||
void
|
||||
StartARAM ()
|
||||
void StartARAM ()
|
||||
{
|
||||
AR_Init (NULL, 0);
|
||||
}
|
||||
@ -31,8 +28,7 @@ StartARAM ()
|
||||
*
|
||||
* Move data from MAIN memory to ARAM
|
||||
*/
|
||||
void
|
||||
ARAMPut (char *src, char *dst, int len)
|
||||
void ARAMPut (char *src, char *dst, int len)
|
||||
{
|
||||
DCFlushRange (src, len);
|
||||
AR_StartDMA( ARAM_WRITE, (u32)src, (u32)dst, len);
|
||||
@ -51,16 +47,3 @@ ARAMFetch (char *dst, char *src, int len)
|
||||
AR_StartDMA( ARAM_READ, (u32) dst, (u32) src, len);
|
||||
while (AR_GetDMAStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* ShadowROM
|
||||
* Copy the rom from cart_rom into ARAM
|
||||
* NB: libOGC appears to use the first 0x4000 bytes.
|
||||
* As there's plenty left, all ARAM addresses are 0x8000 based.
|
||||
* Here, the ROM is simply copied in one swift movement :)
|
||||
*/
|
||||
void
|
||||
ShadowROM ()
|
||||
{
|
||||
ARAMPut ((char *)cart_rom, (void *) ARAMSTART, genromsize);
|
||||
}
|
||||
|
@ -7,8 +7,11 @@
|
||||
* Good to know :)
|
||||
*/
|
||||
|
||||
extern void StartARAM ();
|
||||
void ShadowROM ();
|
||||
void ARAMFetch (char *src, char *dst, int len);
|
||||
void ARAMPut (char *src, char *dst, int len);
|
||||
#ifndef _ARAM_H
|
||||
#define _ARAM_H
|
||||
|
||||
extern void StartARAM ();
|
||||
extern void ARAMFetch (char *src, char *dst, int len);
|
||||
extern void ARAMPut (char *src, char *dst, int len);
|
||||
|
||||
#endif
|
||||
|
@ -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
|
@ -11,56 +11,22 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "shared.h"
|
||||
#include "iso9660.h"
|
||||
#include "font.h"
|
||||
#include "fileio.h"
|
||||
#include "history.h"
|
||||
#include "dvd.h"
|
||||
#include "fileio_dvd.h"
|
||||
#include "fileio_fat.h"
|
||||
#include "filesel.h"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <di/di.h>
|
||||
#endif
|
||||
/* Global Variables */
|
||||
int maxfiles = 0;
|
||||
int offset = 0;
|
||||
int selection = 0;
|
||||
int old_selection = 0;
|
||||
int old_offset = 0;
|
||||
int useFAT = 0;
|
||||
int useHistory = 0;
|
||||
int haveDVDdir = 0;
|
||||
int haveFATdir = 0;
|
||||
|
||||
#define PAGESIZE 12
|
||||
|
||||
static int maxfiles;
|
||||
static int offset = 0;
|
||||
static int selection = 0;
|
||||
static int old_selection = 0;
|
||||
static int old_offset = 0;
|
||||
static char rootFATdir[256];
|
||||
static u8 haveDVDdir = 0;
|
||||
static u8 haveFATdir = 0;
|
||||
static u8 UseFAT = 0;
|
||||
static u8 UseHistory = 0;
|
||||
static int LoadFile (unsigned char *buffer);
|
||||
|
||||
/***************************************************************************
|
||||
* FileSortCallback (Marty Disibio)
|
||||
*
|
||||
* Quick sort callback to sort file entries with the following order:
|
||||
* .
|
||||
* ..
|
||||
* <dirs>
|
||||
* <files>
|
||||
***************************************************************************/
|
||||
static int FileSortCallback(const void *f1, const void *f2)
|
||||
{
|
||||
/* Special case for implicit directories */
|
||||
if(((FILEENTRIES *)f1)->filename[0] == '.' || ((FILEENTRIES *)f2)->filename[0] == '.')
|
||||
{
|
||||
if(strcmp(((FILEENTRIES *)f1)->filename, ".") == 0) { return -1; }
|
||||
if(strcmp(((FILEENTRIES *)f2)->filename, ".") == 0) { return 1; }
|
||||
if(strcmp(((FILEENTRIES *)f1)->filename, "..") == 0) { return -1; }
|
||||
if(strcmp(((FILEENTRIES *)f2)->filename, "..") == 0) { return 1; }
|
||||
}
|
||||
|
||||
/* If one is a file and one is a directory the directory is first. */
|
||||
if(((FILEENTRIES *)f1)->flags == 1 && ((FILEENTRIES *)f2)->flags == 0) return -1;
|
||||
if(((FILEENTRIES *)f1)->flags == 0 && ((FILEENTRIES *)f2)->flags == 1) return 1;
|
||||
|
||||
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* ShowFiles
|
||||
@ -87,137 +53,17 @@ static void ShowFiles (int offset, int selection)
|
||||
SetScreen ();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* updateFATdirname
|
||||
*
|
||||
* Update ROOT directory while browsing SDCARD
|
||||
***************************************************************************/
|
||||
static int updateFATdirname()
|
||||
{
|
||||
int size=0;
|
||||
char *test;
|
||||
char temp[1024];
|
||||
|
||||
/* current directory doesn't change */
|
||||
if (strcmp(filelist[selection].filename,".") == 0) return 0;
|
||||
|
||||
/* go up to parent directory */
|
||||
else if (strcmp(filelist[selection].filename,"..") == 0)
|
||||
{
|
||||
/* determine last subdirectory namelength */
|
||||
sprintf(temp,"%s",rootFATdir);
|
||||
test= strtok(temp,"/");
|
||||
while (test != NULL)
|
||||
{
|
||||
size = strlen(test);
|
||||
test = strtok(NULL,"/");
|
||||
}
|
||||
|
||||
/* remove last subdirectory name */
|
||||
size = strlen(rootFATdir) - size;
|
||||
rootFATdir[size-1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(rootFATdir, "%s%s/",rootFATdir, filelist[selection].filename);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* parseFATdirectory
|
||||
*
|
||||
* List files into one SDCARD directory
|
||||
***************************************************************************/
|
||||
static int parseFATdirectory()
|
||||
{
|
||||
int nbfiles = 0;
|
||||
char filename[MAXPATHLEN];
|
||||
struct stat filestat;
|
||||
|
||||
/* open directory */
|
||||
DIR_ITER *dir = diropen (rootFATdir);
|
||||
if (dir == NULL)
|
||||
{
|
||||
sprintf(filename, "Error opening %s", rootFATdir);
|
||||
WaitPrompt (filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (dirnext(dir, filename, &filestat) == 0)
|
||||
{
|
||||
if (strcmp(filename,".") != 0)
|
||||
{
|
||||
memset(&filelist[nbfiles], 0, sizeof (FILEENTRIES));
|
||||
sprintf(filelist[nbfiles].filename,"%s",filename);
|
||||
filelist[nbfiles].length = filestat.st_size;
|
||||
filelist[nbfiles].flags = (filestat.st_mode & S_IFDIR) ? 1 : 0;
|
||||
nbfiles++;
|
||||
}
|
||||
}
|
||||
|
||||
dirclose(dir);
|
||||
|
||||
/* Sort the file list */
|
||||
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
|
||||
|
||||
return nbfiles;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* FileSelected
|
||||
*
|
||||
* Called when a file is selected by the user inside the FileSelector loop.
|
||||
****************************************************************************/
|
||||
static int FileSelected()
|
||||
{
|
||||
/* If loading from history then we need to setup a few more things. */
|
||||
if(UseHistory)
|
||||
{
|
||||
/* Get the parent folder for the file. */
|
||||
strncpy(rootFATdir, history.entries[selection].filepath, MAXJOLIET-1);
|
||||
rootFATdir[MAXJOLIET-1] = '\0';
|
||||
|
||||
/* Get the length of the file. This has to be done
|
||||
* before calling LoadFile(). */
|
||||
char filepath[MAXJOLIET];
|
||||
struct stat filestat;
|
||||
snprintf(filepath, MAXJOLIET-1, "%s%s", history.entries[selection].filepath, history.entries[selection].filename);
|
||||
filepath[MAXJOLIET-1] = '\0';
|
||||
if(stat(filepath, &filestat) == 0)
|
||||
{
|
||||
filelist[selection].length = filestat.st_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add/move the file to the top of the history. */
|
||||
if (UseFAT) history_add_file(rootFATdir, filelist[selection].filename);
|
||||
|
||||
rootdir = filelist[selection].offset;
|
||||
rootdirlength = filelist[selection].length;
|
||||
memfile_autosave();
|
||||
genromsize = LoadFile(cart_rom);
|
||||
if (genromsize)
|
||||
{
|
||||
reloadrom();
|
||||
memfile_autoload();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* FileSelector
|
||||
*
|
||||
* Let user select a file from the File listing
|
||||
****************************************************************************/
|
||||
static int FileSelector ()
|
||||
int FileSelector()
|
||||
{
|
||||
short p;
|
||||
int redraw = 1;
|
||||
int go_up = 0;
|
||||
int ret;
|
||||
int i,size;
|
||||
|
||||
while (1)
|
||||
@ -297,22 +143,7 @@ static int FileSelector ()
|
||||
if ((selection - offset) >= PAGESIZE) offset += PAGESIZE;
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
/* go up one directory or quit */
|
||||
if (p & PAD_BUTTON_B)
|
||||
{
|
||||
filelist[selection].filename_offset = 0;
|
||||
if (UseFAT)
|
||||
{
|
||||
if (strcmp(filelist[0].filename,"..") != 0) return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (basedir == rootdir) return 0;
|
||||
}
|
||||
go_up = 1;
|
||||
}
|
||||
|
||||
|
||||
/* quit */
|
||||
if (p & PAD_TRIGGER_Z)
|
||||
{
|
||||
@ -321,349 +152,45 @@ static int FileSelector ()
|
||||
}
|
||||
|
||||
/* open selected file or directory */
|
||||
if ((p & PAD_BUTTON_A) || go_up)
|
||||
if ((p & PAD_BUTTON_A) || (p & PAD_BUTTON_B))
|
||||
{
|
||||
filelist[selection].filename_offset = 0;
|
||||
if (go_up)
|
||||
go_up = 0;
|
||||
|
||||
if (p & PAD_BUTTON_B)
|
||||
{
|
||||
/* select item #1 */
|
||||
go_up = 0;
|
||||
selection = UseFAT ? 0 : 1;
|
||||
/* go up one directory or quit */
|
||||
go_up = 1;
|
||||
selection = useFAT ? 0 : 1;
|
||||
}
|
||||
|
||||
/*** This is directory ***/
|
||||
if (filelist[selection].flags)
|
||||
{
|
||||
/* SDCARD directory handler */
|
||||
if (UseFAT)
|
||||
{
|
||||
/* update current directory */
|
||||
if (updateFATdirname())
|
||||
{
|
||||
/* reinit selector (previous value is saved for one level) */
|
||||
if (selection == 0)
|
||||
{
|
||||
selection = old_selection;
|
||||
offset = old_offset;
|
||||
old_selection = 0;
|
||||
old_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save current selector value */
|
||||
old_selection = selection;
|
||||
old_offset = offset;
|
||||
selection = 0;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
/* set new entry list */
|
||||
maxfiles = parseFATdirectory();
|
||||
if (!maxfiles)
|
||||
{
|
||||
/* quit */
|
||||
WaitPrompt ("No files found !");
|
||||
haveFATdir = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* DVD directory handler */
|
||||
{
|
||||
/* move to a new directory */
|
||||
if (selection != 0)
|
||||
{
|
||||
/* update current directory */
|
||||
rootdir = filelist[selection].offset;
|
||||
rootdirlength = filelist[selection].length;
|
||||
|
||||
/* reinit selector (previous value is saved for one level) */
|
||||
if (selection == 1)
|
||||
{
|
||||
selection = old_selection;
|
||||
offset = old_offset;
|
||||
old_selection = 0;
|
||||
old_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save current selector value */
|
||||
old_selection = selection;
|
||||
old_offset = offset;
|
||||
selection = 0;
|
||||
offset = 0;
|
||||
}
|
||||
/* get new directory */
|
||||
ret = useFAT ? FAT_UpdateDir(go_up) : DVD_UpdateDir(go_up);
|
||||
|
||||
/* get new entry list */
|
||||
maxfiles = parseDVDdirectory ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else /*** This is a file ***/
|
||||
{
|
||||
return FileSelected();
|
||||
}
|
||||
redraw = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* OpenDVD
|
||||
*
|
||||
* Function to load a DVD directory and display to user.
|
||||
****************************************************************************/
|
||||
int OpenDVD ()
|
||||
{
|
||||
UseFAT = 0;
|
||||
UseHistory = 0;
|
||||
|
||||
if (!getpvd())
|
||||
{
|
||||
/* mount DVD */
|
||||
ShowAction("Mounting DVD ... Wait");
|
||||
|
||||
#ifndef HW_RVL
|
||||
DVD_Mount();
|
||||
#else
|
||||
u32 val;
|
||||
DI_GetCoverRegister(&val);
|
||||
|
||||
if(val & 0x1)
|
||||
{
|
||||
WaitPrompt("No Disc inserted !");
|
||||
return 0;
|
||||
}
|
||||
DI_Mount();
|
||||
while(DI_GetStatus() & DVD_INIT);
|
||||
if (!(DI_GetStatus() & DVD_READY))
|
||||
{
|
||||
char msg[50];
|
||||
sprintf(msg, "DI Status Error: 0x%08X\n",DI_GetStatus());
|
||||
WaitPrompt(msg);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
haveDVDdir = 0;
|
||||
if (!getpvd())
|
||||
{
|
||||
WaitPrompt ("Failed to mount DVD");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (haveDVDdir == 0)
|
||||
{
|
||||
/* don't mess with SD entries */
|
||||
haveFATdir = 0;
|
||||
|
||||
/* reinit selector */
|
||||
rootdir = basedir;
|
||||
old_selection = selection = offset = old_offset = 0;
|
||||
}
|
||||
|
||||
/* Parse root directory and get entries list */
|
||||
ShowAction("Reading Directory ...");
|
||||
if ((maxfiles = parseDVDdirectory ()))
|
||||
{
|
||||
/* Select an entry */
|
||||
haveDVDdir = 1;
|
||||
return FileSelector ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no entries found */
|
||||
WaitPrompt ("no files found !");
|
||||
haveDVDdir = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* OpenFAT
|
||||
*
|
||||
* Function to load a FAT directory and display to user.
|
||||
****************************************************************************/
|
||||
int OpenFAT (char *name)
|
||||
{
|
||||
UseFAT = 1;
|
||||
UseHistory = 0;
|
||||
|
||||
if (haveFATdir == 0)
|
||||
{
|
||||
/* don't mess with DVD entries */
|
||||
haveDVDdir = 0;
|
||||
|
||||
/* reinit selector */
|
||||
old_selection = selection = offset = old_offset = 0;
|
||||
|
||||
/* Reset SDCARD root directory */
|
||||
sprintf (rootFATdir, "%s/genplus/roms/", name);
|
||||
|
||||
/* if directory doesn't exist, use root */
|
||||
DIR_ITER *dir = diropen(rootFATdir);
|
||||
if (dir == NULL) sprintf (rootFATdir, "%s/", name);
|
||||
else dirclose(dir);
|
||||
}
|
||||
|
||||
/* Parse root directory and get entries list */
|
||||
ShowAction("Reading Directory ...");
|
||||
if ((maxfiles = parseFATdirectory ()))
|
||||
{
|
||||
/* Select an entry */
|
||||
haveFATdir = 1;
|
||||
return FileSelector ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no entries found */
|
||||
WaitPrompt ("no files found !");
|
||||
haveFATdir = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* OpenHistory
|
||||
*
|
||||
* Function to load a recent file from SDCARD (Marty Disibio)
|
||||
****************************************************************************/
|
||||
int OpenHistory()
|
||||
{
|
||||
int i;
|
||||
|
||||
UseFAT = 1;
|
||||
UseHistory = 1;
|
||||
|
||||
/* don't mess with other entries */
|
||||
haveFATdir = 0;
|
||||
haveDVDdir = 0;
|
||||
|
||||
/* reinit selector */
|
||||
old_selection = selection = offset = old_offset = 0;
|
||||
|
||||
/* Recreate the file listing from the history
|
||||
* as if all of the roms were in the same directory. */
|
||||
ShowAction("Reading Files ...");
|
||||
|
||||
maxfiles = 0;
|
||||
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
||||
{
|
||||
if(history.entries[i].filepath[0] > 0)
|
||||
{
|
||||
filelist[i].offset = 0;
|
||||
filelist[i].length = 0;
|
||||
filelist[i].flags = 0;
|
||||
filelist[i].filename_offset = 0;
|
||||
strncpy(filelist[i].filename, history.entries[i].filename, MAXJOLIET-1);
|
||||
filelist[i].filename[MAXJOLIET-1] = '\0';
|
||||
|
||||
maxfiles++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Found the end of the list. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!maxfiles)
|
||||
{
|
||||
WaitPrompt ("No recent files");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return FileSelector();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* LoadFile
|
||||
*
|
||||
* This function will load a file from DVD or SDCARD, in BIN, SMD or ZIP format.
|
||||
* The values for offset and length are inherited from rootdir and
|
||||
* rootdirlength.
|
||||
*
|
||||
* The buffer parameter should re-use the initial ROM buffer.
|
||||
****************************************************************************/
|
||||
static int LoadFile (unsigned char *buffer)
|
||||
{
|
||||
u64 discoffset = 0;
|
||||
char readbuffer[2048];
|
||||
char fname[MAXPATHLEN];
|
||||
FILE *sdfile = NULL;
|
||||
|
||||
if (rootdirlength == 0) return 0;
|
||||
|
||||
/* SDCard access */
|
||||
if (UseFAT)
|
||||
{
|
||||
/* open file */
|
||||
sprintf(fname, "%s%s",rootFATdir,filelist[selection].filename);
|
||||
sdfile = fopen(fname, "rb");
|
||||
if (sdfile == NULL)
|
||||
{
|
||||
WaitPrompt ("Unable to open file!");
|
||||
haveFATdir = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ShowAction ("Loading ... Wait");
|
||||
|
||||
/* Read first data chunk */
|
||||
if (UseFAT)
|
||||
{
|
||||
fread(readbuffer, 1, 2048, sdfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
discoffset = rootdir;
|
||||
dvd_read (&readbuffer, 2048, discoffset);
|
||||
}
|
||||
|
||||
/* determine file type */
|
||||
if (!IsZipFile ((char *) readbuffer))
|
||||
{
|
||||
if (UseFAT)
|
||||
{
|
||||
/* go back to file start and read file */
|
||||
fseek(sdfile, 0, SEEK_SET);
|
||||
fread(buffer, 1, rootdirlength, sdfile);
|
||||
fclose(sdfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* How many 2k blocks to read */
|
||||
int blocks = rootdirlength / 2048;
|
||||
int readoffset = 0;
|
||||
int i;
|
||||
|
||||
/* read data chunks */
|
||||
for (i = 0; i < blocks; i++)
|
||||
{
|
||||
dvd_read(readbuffer, 2048, discoffset);
|
||||
discoffset += 2048;
|
||||
memcpy (buffer + readoffset, readbuffer, 2048);
|
||||
readoffset += 2048;
|
||||
/* get new entry list or quit */
|
||||
if (ret) maxfiles = useFAT ? FAT_ParseDirectory() : DVD_ParseDirectory();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/* final read */
|
||||
i = rootdirlength % 2048;
|
||||
if (i)
|
||||
/*** This is a file ***/
|
||||
else
|
||||
{
|
||||
dvd_read (readbuffer, 2048, discoffset);
|
||||
memcpy (buffer + readoffset, readbuffer, i);
|
||||
/* Load file */
|
||||
genromsize = useFAT ? FAT_LoadFile(cart_rom) : DVD_LoadFile(cart_rom);
|
||||
if (genromsize)
|
||||
{
|
||||
memfile_autosave();
|
||||
reloadrom();
|
||||
memfile_autoload();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
redraw = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unzip file */
|
||||
if (UseFAT) return UnZipFAT(buffer, fname);
|
||||
else return UnZipDVD (buffer, discoffset, rootdirlength);
|
||||
}
|
||||
|
||||
return rootdirlength;
|
||||
}
|
||||
|
35
source/ngc/gui/filesel.h
Normal file
35
source/ngc/gui/filesel.h
Normal 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
@ -34,8 +34,8 @@ typedef struct
|
||||
} GGPATCH;
|
||||
|
||||
/*** Game Genie Codes Array ***/
|
||||
unsigned char ggcodes[MAXCODES][10]; /*** Codes are entered as XXXX-XXXX ***/
|
||||
int gghpos[MAXCODES]; /*** Edit positions ***/
|
||||
unsigned char ggcodes[MAXCODES][10]; /*** Codes are entered as XXXX-XXXX ***/
|
||||
int gghpos[MAXCODES]; /*** Edit positions ***/
|
||||
int ggrow = 0;
|
||||
int editing = 0;
|
||||
char ggvalidchars[] = "ABCDEFGHJKLMNPRSTVWXYZ0123456789*";
|
||||
@ -50,53 +50,53 @@ void decode_genie (char *code, int which)
|
||||
int n, i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
/*** This should only happen if memory is corrupt! ***/
|
||||
p = strchr (ggvalidchars, code[i]);
|
||||
if (p == NULL)
|
||||
{
|
||||
ggpatch[which].address = ggpatch[which].data = 0;
|
||||
return;
|
||||
}
|
||||
/*** This should only happen if memory is corrupt! ***/
|
||||
p = strchr (ggvalidchars, code[i]);
|
||||
if (p == NULL)
|
||||
{
|
||||
ggpatch[which].address = ggpatch[which].data = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
n = p - ggvalidchars;
|
||||
n = p - ggvalidchars;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
ggpatch[which].data |= n << 3;
|
||||
break;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
ggpatch[which].data |= n << 3;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ggpatch[which].data |= n >> 2;
|
||||
ggpatch[which].address |= (n & 3) << 14;
|
||||
break;
|
||||
case 1:
|
||||
ggpatch[which].data |= n >> 2;
|
||||
ggpatch[which].address |= (n & 3) << 14;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ggpatch[which].address |= n << 9;
|
||||
break;
|
||||
case 2:
|
||||
ggpatch[which].address |= n << 9;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
ggpatch[which].address |= (n & 0xF) << 20 | (n >> 4) << 8;
|
||||
break;
|
||||
case 3:
|
||||
ggpatch[which].address |= (n & 0xF) << 20 | (n >> 4) << 8;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
ggpatch[which].data |= (n & 1) << 12;
|
||||
ggpatch[which].address |= (n >> 1) << 16;
|
||||
break;
|
||||
case 4:
|
||||
ggpatch[which].data |= (n & 1) << 12;
|
||||
ggpatch[which].address |= (n >> 1) << 16;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
ggpatch[which].data |= (n & 1) << 15 | (n >> 1) << 8;
|
||||
break;
|
||||
case 5:
|
||||
ggpatch[which].data |= (n & 1) << 15 | (n >> 1) << 8;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
ggpatch[which].data |= (n >> 3) << 13;
|
||||
ggpatch[which].address |= (n & 7) << 5;
|
||||
break;
|
||||
case 6:
|
||||
ggpatch[which].data |= (n >> 3) << 13;
|
||||
ggpatch[which].address |= (n & 7) << 5;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
ggpatch[which].address |= n;
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
ggpatch[which].address |= n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,25 +112,25 @@ void decode_ggcodes ()
|
||||
j = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (strcmp ((char *)ggcodes[i], "AAAA-AAAA"))
|
||||
{
|
||||
/*** Move the code into thiscode ***/
|
||||
memcpy (&thiscode, &ggcodes[i], 4);
|
||||
memcpy (&thiscode[4], &ggcodes[i][5], 4);
|
||||
if (strcmp ((char *)ggcodes[i], "AAAA-AAAA"))
|
||||
{
|
||||
/*** Move the code into thiscode ***/
|
||||
memcpy (&thiscode, &ggcodes[i], 4);
|
||||
memcpy (&thiscode[4], &ggcodes[i][5], 4);
|
||||
|
||||
decode_genie (thiscode, j);
|
||||
j++;
|
||||
}
|
||||
decode_genie (thiscode, j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
/*** And now apply the patches ***/
|
||||
if (j)
|
||||
{
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
if (ggpatch[i].address < 0x400000)
|
||||
{
|
||||
/*** Patching ROM space ONLY (Game Genie does NOT have access to other memory areas) ***/
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
if (ggpatch[i].address < 0x400000)
|
||||
{
|
||||
/*** Patching ROM space ONLY (Game Genie does NOT have access to other memory areas) ***/
|
||||
if (cart_rom) *(uint16 *)(cart_rom + ggpatch[i].address) = ggpatch[i].data & 0xffff;
|
||||
}
|
||||
}
|
||||
@ -148,8 +148,8 @@ void ClearGGCodes ()
|
||||
|
||||
for (i = 0; i < MAXCODES; i++)
|
||||
{
|
||||
strcpy ((char *)ggcodes[i], "AAAA-AAAA");
|
||||
gghpos[i] = 0;
|
||||
strcpy ((char *)ggcodes[i], "AAAA-AAAA");
|
||||
gghpos[i] = 0;
|
||||
}
|
||||
ggrow = 0;
|
||||
}
|
||||
@ -169,29 +169,29 @@ void DrawGGCodes ()
|
||||
|
||||
for (i = 0; i < MAXCODES; i++)
|
||||
{
|
||||
if (i == ggrow)
|
||||
{
|
||||
/*** Highlight selected ***/
|
||||
WriteCentre_HL (i * fheight + 224, (char *)ggcodes[i]);
|
||||
if (i == ggrow)
|
||||
{
|
||||
/*** Highlight selected ***/
|
||||
WriteCentre_HL (i * fheight + 224, (char *)ggcodes[i]);
|
||||
|
||||
/*** If editing, highlight the current character ***/
|
||||
if (editing)
|
||||
{
|
||||
int hpos = 0;
|
||||
/*** If editing, highlight the current character ***/
|
||||
if (editing)
|
||||
{
|
||||
int hpos = 0;
|
||||
|
||||
for (j=0; j<strlen ((char *)ggcodes[i]); j++) hpos += font_size[ggcodes[i][j]];
|
||||
hpos = ((640 - hpos) >> 1);
|
||||
for (j=0; j<gghpos[i]; j++) hpos += font_size[ggcodes[i][j]];
|
||||
hpos = ((640 - hpos) >> 1);
|
||||
for (j=0; j<gghpos[i]; j++) hpos += font_size[ggcodes[i][j]];
|
||||
|
||||
c[0] = ggcodes[i][gghpos[i]];
|
||||
fntDrawBoxFilled (hpos, (i * fheight) + 224, hpos + font_size[c[0]],
|
||||
c[0] = ggcodes[i][gghpos[i]];
|
||||
fntDrawBoxFilled (hpos, (i * fheight) + 224, hpos + font_size[c[0]],
|
||||
((i + 1) * fheight) + 224, COLOR_YELLOW);
|
||||
setfontcolour (COLOR_BLUE);
|
||||
write_font (hpos, (i * fheight) + 224, (char *)c);
|
||||
setfontcolour (COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
else WriteCentre ((i * fheight) + 224, (char *)ggcodes[i]);
|
||||
setfontcolour (COLOR_BLUE);
|
||||
write_font (hpos, (i * fheight) + 224, (char *)c);
|
||||
setfontcolour (COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
else WriteCentre ((i * fheight) + 224, (char *)ggcodes[i]);
|
||||
}
|
||||
SetScreen ();
|
||||
}
|
||||
@ -215,55 +215,55 @@ void GGEditLine ()
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
if (redraw)
|
||||
{
|
||||
DrawGGCodes ();
|
||||
redraw = 0;
|
||||
}
|
||||
if (redraw)
|
||||
{
|
||||
DrawGGCodes ();
|
||||
redraw = 0;
|
||||
}
|
||||
|
||||
p = ogc_input__getMenuButtons();
|
||||
p = ogc_input__getMenuButtons();
|
||||
|
||||
if (p & PAD_BUTTON_UP)
|
||||
{
|
||||
/*** Increment the entry ***/
|
||||
redraw = 1;
|
||||
c[0] = ggcodes[ggrow][gghpos[ggrow]];
|
||||
v = strstr (ggvalidchars, c);
|
||||
v++;
|
||||
if (*v == '*') ggcodes[ggrow][gghpos[ggrow]] = 'A';
|
||||
else ggcodes[ggrow][gghpos[ggrow]] = *v;
|
||||
}
|
||||
if (p & PAD_BUTTON_UP)
|
||||
{
|
||||
/*** Increment the entry ***/
|
||||
redraw = 1;
|
||||
c[0] = ggcodes[ggrow][gghpos[ggrow]];
|
||||
v = strstr (ggvalidchars, c);
|
||||
v++;
|
||||
if (*v == '*') ggcodes[ggrow][gghpos[ggrow]] = 'A';
|
||||
else ggcodes[ggrow][gghpos[ggrow]] = *v;
|
||||
}
|
||||
|
||||
if (p & PAD_BUTTON_DOWN)
|
||||
{
|
||||
/*** Decrement entry ***/
|
||||
redraw = 1;
|
||||
c[0] = ggcodes[ggrow][gghpos[ggrow]];
|
||||
v = strstr (ggvalidchars, c);
|
||||
if (*v == 'A') ggcodes[ggrow][gghpos[ggrow]] = '9';
|
||||
else
|
||||
{
|
||||
v--;
|
||||
ggcodes[ggrow][gghpos[ggrow]] = *v;
|
||||
}
|
||||
}
|
||||
if (p & PAD_BUTTON_DOWN)
|
||||
{
|
||||
/*** Decrement entry ***/
|
||||
redraw = 1;
|
||||
c[0] = ggcodes[ggrow][gghpos[ggrow]];
|
||||
v = strstr (ggvalidchars, c);
|
||||
if (*v == 'A') ggcodes[ggrow][gghpos[ggrow]] = '9';
|
||||
else
|
||||
{
|
||||
v--;
|
||||
ggcodes[ggrow][gghpos[ggrow]] = *v;
|
||||
}
|
||||
}
|
||||
|
||||
if (p & PAD_BUTTON_LEFT)
|
||||
{
|
||||
redraw = 1;
|
||||
gghpos[ggrow]--;
|
||||
if (gghpos[ggrow] == 4) gghpos[ggrow]--;
|
||||
}
|
||||
if (p & PAD_BUTTON_LEFT)
|
||||
{
|
||||
redraw = 1;
|
||||
gghpos[ggrow]--;
|
||||
if (gghpos[ggrow] == 4) gghpos[ggrow]--;
|
||||
}
|
||||
|
||||
if (p & PAD_BUTTON_RIGHT)
|
||||
{
|
||||
redraw = 1;
|
||||
gghpos[ggrow]++;
|
||||
if (gghpos[ggrow] == 4) gghpos[ggrow]++;
|
||||
}
|
||||
if (p & PAD_BUTTON_RIGHT)
|
||||
{
|
||||
redraw = 1;
|
||||
gghpos[ggrow]++;
|
||||
if (gghpos[ggrow] == 4) gghpos[ggrow]++;
|
||||
}
|
||||
|
||||
if (gghpos[ggrow] < 0) gghpos[ggrow] = 8;
|
||||
if (gghpos[ggrow] > 8) gghpos[ggrow] = 0;
|
||||
if (gghpos[ggrow] < 0) gghpos[ggrow] = 8;
|
||||
if (gghpos[ggrow] > 8) gghpos[ggrow] = 0;
|
||||
|
||||
if (p & PAD_BUTTON_A) quit = 1;
|
||||
}
|
||||
@ -283,49 +283,49 @@ void GGSelectLine ()
|
||||
short j;
|
||||
|
||||
/*** To select a line, just move up or down.
|
||||
Pressing A will enter edit mode.
|
||||
Pressing B will exit to caller. ***/
|
||||
Pressing A will enter edit mode.
|
||||
Pressing B will exit to caller. ***/
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
if (redraw)
|
||||
{
|
||||
DrawGGCodes ();
|
||||
redraw = 0;
|
||||
}
|
||||
if (redraw)
|
||||
{
|
||||
DrawGGCodes ();
|
||||
redraw = 0;
|
||||
}
|
||||
|
||||
j = ogc_input__getMenuButtons();
|
||||
j = ogc_input__getMenuButtons();
|
||||
|
||||
if (j & PAD_BUTTON_UP)
|
||||
{
|
||||
ggrow--;
|
||||
redraw = 1;
|
||||
}
|
||||
if (j & PAD_BUTTON_UP)
|
||||
{
|
||||
ggrow--;
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
if (j & PAD_BUTTON_DOWN)
|
||||
{
|
||||
ggrow++;
|
||||
redraw = 1;
|
||||
}
|
||||
if (j & PAD_BUTTON_DOWN)
|
||||
{
|
||||
ggrow++;
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
if (ggrow < 0) ggrow = MAXCODES - 1;
|
||||
if (ggrow == MAXCODES) ggrow = 0;
|
||||
if (ggrow < 0) ggrow = MAXCODES - 1;
|
||||
if (ggrow == MAXCODES) ggrow = 0;
|
||||
|
||||
if (j & PAD_BUTTON_B) quit = 1;
|
||||
if (j & PAD_BUTTON_B) quit = 1;
|
||||
|
||||
if (j & PAD_BUTTON_A)
|
||||
{
|
||||
GGEditLine ();
|
||||
redraw = 1;
|
||||
}
|
||||
if (j & PAD_BUTTON_A)
|
||||
{
|
||||
GGEditLine ();
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
if (j & PAD_TRIGGER_Z)
|
||||
{
|
||||
/* reset code */
|
||||
{
|
||||
/* reset code */
|
||||
strcpy ((char *)ggcodes[ggrow], "AAAA-AAAA");
|
||||
gghpos[ggrow] = 0;
|
||||
redraw = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -80,12 +80,12 @@ void legal ()
|
||||
dispoffset = (316 * 320) + ((640 - dkpro_WIDTH) >> 2);
|
||||
|
||||
for (h = 0; h < dkpro_HEIGHT; h++)
|
||||
{
|
||||
for (w = 0; w < dkpro_WIDTH >> 1; w++)
|
||||
xfb[whichfb][dispoffset + w] = dkproraw[p++];
|
||||
{
|
||||
for (w = 0; w < dkpro_WIDTH >> 1; w++)
|
||||
xfb[whichfb][dispoffset + w] = dkproraw[p++];
|
||||
|
||||
dispoffset += 320;
|
||||
}
|
||||
dispoffset += 320;
|
||||
}
|
||||
|
||||
free (dkproraw);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,22 +8,25 @@
|
||||
*/
|
||||
|
||||
#include "shared.h"
|
||||
#include "font.h"
|
||||
#include "history.h"
|
||||
|
||||
t_history history;
|
||||
|
||||
void history_save()
|
||||
{
|
||||
if (!use_FAT) return;
|
||||
char pathname[MAXPATHLEN];
|
||||
|
||||
if (!fat_enabled) return;
|
||||
|
||||
/* first check if directory exist */
|
||||
DIR_ITER *dir = diropen("/genplus");
|
||||
if (dir == NULL) mkdir("/genplus",S_IRWXU);
|
||||
sprintf (pathname, DEFAULT_PATH);
|
||||
DIR_ITER *dir = diropen(pathname);
|
||||
if (dir == NULL) mkdir(pathname,S_IRWXU);
|
||||
else dirclose(dir);
|
||||
|
||||
/* open file for writing */
|
||||
FILE *fp = fopen("/genplus/romhistory.ini", "wb");
|
||||
sprintf (pathname, "%s/history.ini", pathname);
|
||||
FILE *fp = fopen(pathname, "wb");
|
||||
if (fp == NULL) return;
|
||||
|
||||
/* save options */
|
||||
@ -42,46 +45,49 @@ void history_save()
|
||||
****************************************************************************/
|
||||
void history_add_file(char *filepath, char *filename)
|
||||
{
|
||||
/* Create the new entry for this path. */
|
||||
t_history_entry newentry;
|
||||
strncpy(newentry.filepath, filepath, MAXJOLIET - 1);
|
||||
strncpy(newentry.filename, filename, MAXJOLIET - 1);
|
||||
newentry.filepath[MAXJOLIET - 1] = '\0';
|
||||
newentry.filename[MAXJOLIET - 1] = '\0';
|
||||
|
||||
t_history_entry oldentry; /* Old entry is the one being shuffled down a spot. */
|
||||
t_history_entry currentry; /* Curr entry is the one that just replaced old path. */
|
||||
|
||||
/* Initially set curr entry to the new value. */
|
||||
memcpy(¤try, &newentry, sizeof(t_history_entry));
|
||||
/* Create the new entry for this path. */
|
||||
t_history_entry newentry;
|
||||
strncpy(newentry.filepath, filepath, MAXJOLIET - 1);
|
||||
strncpy(newentry.filename, filename, MAXJOLIET - 1);
|
||||
newentry.filepath[MAXJOLIET - 1] = '\0';
|
||||
newentry.filename[MAXJOLIET - 1] = '\0';
|
||||
|
||||
t_history_entry oldentry; /* Old entry is the one being shuffled down a spot. */
|
||||
t_history_entry currentry; /* Curr entry is the one that just replaced old path. */
|
||||
|
||||
/* Initially set curr entry to the new value. */
|
||||
memcpy(¤try, &newentry, sizeof(t_history_entry));
|
||||
|
||||
int i;
|
||||
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
||||
{
|
||||
/* Save off the next entry. */
|
||||
memcpy(&oldentry, &history.entries[i], sizeof(t_history_entry));
|
||||
|
||||
/* Overwrite with the previous entry. */
|
||||
memcpy(&history.entries[i], ¤try, sizeof(t_history_entry));
|
||||
|
||||
/* Switch the old entry to the curr entry now. */
|
||||
memcpy(¤try, &oldentry, sizeof(t_history_entry));
|
||||
|
||||
/* If the entry in the list at this spot matches
|
||||
the new entry then do nothing and let this
|
||||
entry get deleted. */
|
||||
if(strcmp(newentry.filepath, currentry.filepath) == 0 && strcmp(newentry.filename, currentry.filename) == 0)
|
||||
break;
|
||||
}
|
||||
int i;
|
||||
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
||||
{
|
||||
/* Save off the next entry. */
|
||||
memcpy(&oldentry, &history.entries[i], sizeof(t_history_entry));
|
||||
|
||||
/* now save to disk */
|
||||
history_save();
|
||||
/* Overwrite with the previous entry. */
|
||||
memcpy(&history.entries[i], ¤try, sizeof(t_history_entry));
|
||||
|
||||
/* Switch the old entry to the curr entry now. */
|
||||
memcpy(¤try, &oldentry, sizeof(t_history_entry));
|
||||
|
||||
/* If the entry in the list at this spot matches
|
||||
the new entry then do nothing and let this
|
||||
entry get deleted. */
|
||||
if(strcmp(newentry.filepath, currentry.filepath) == 0 && strcmp(newentry.filename, currentry.filename) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* now save to disk */
|
||||
history_save();
|
||||
}
|
||||
|
||||
void history_load()
|
||||
{
|
||||
char pathname[MAXPATHLEN];
|
||||
|
||||
/* open file for reading */
|
||||
FILE *fp = fopen("/genplus/romhistory.ini", "rb");
|
||||
sprintf (pathname, "%s/history.ini", DEFAULT_PATH);
|
||||
FILE *fp = fopen(pathname, "rb");
|
||||
if (fp == NULL) return;
|
||||
|
||||
/* read file */
|
||||
@ -92,11 +98,11 @@ void history_load()
|
||||
|
||||
void set_history_defaults(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
||||
{
|
||||
memset(&history.entries[i], 0, sizeof(t_history_entry));
|
||||
}
|
||||
int i;
|
||||
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
||||
{
|
||||
memset(&history.entries[i], 0, sizeof(t_history_entry));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,20 +5,19 @@
|
||||
* Created by Martin Disibio on 6/17/08.
|
||||
*
|
||||
*/
|
||||
#ifndef _HISTORY_H
|
||||
#define _HISTORY_H
|
||||
|
||||
#include "types.h"
|
||||
#include "iso9660.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
#ifndef _HISTORY_H
|
||||
#define _HISTORY_H
|
||||
|
||||
|
||||
#include "types.h"
|
||||
#include "filesel.h"
|
||||
|
||||
#define NUM_HISTORY_ENTRIES (10)
|
||||
|
||||
/****************************************************************************
|
||||
* ROM Play History
|
||||
*
|
||||
****************************************************************************/
|
||||
#define NUM_HISTORY_ENTRIES (10)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char filepath[MAXJOLIET];
|
||||
@ -27,14 +26,12 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
t_history_entry entries[NUM_HISTORY_ENTRIES];
|
||||
t_history_entry entries[NUM_HISTORY_ENTRIES];
|
||||
} t_history;
|
||||
|
||||
extern t_history history;
|
||||
extern void history_add_file(char *filepath, char *filename);
|
||||
extern void history_load();
|
||||
extern void set_history_defaults();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "shared.h"
|
||||
#include "font.h"
|
||||
#include "saveicon.h"
|
||||
|
||||
#ifndef HW_RVL
|
||||
#include "dvd.h"
|
||||
#endif
|
||||
@ -29,8 +30,8 @@ static card_stat CardStatus;
|
||||
*/
|
||||
static u8 savebuffer[0x26000] ATTRIBUTE_ALIGN (32);
|
||||
|
||||
int ManageSRAM (u8 direction, u8 device);
|
||||
int ManageState (u8 direction, u8 device);
|
||||
int ManageSRAM(u8 direction, u8 device);
|
||||
int ManageState(u8 direction, u8 device);
|
||||
|
||||
/****************************************************************************
|
||||
* FILE autoload (SRAM/FreezeState or Config File)
|
||||
@ -39,7 +40,7 @@ int ManageState (u8 direction, u8 device);
|
||||
*****************************************************************************/
|
||||
void memfile_autoload()
|
||||
{
|
||||
/* this should be transparent to the user */
|
||||
/* this should be transparent to the user */
|
||||
SILENT = 1;
|
||||
|
||||
/* SRAM */
|
||||
@ -50,7 +51,7 @@ void memfile_autoload()
|
||||
if (config.freeze_auto != -1)
|
||||
ManageState(1,config.freeze_auto);
|
||||
|
||||
SILENT = 0;
|
||||
SILENT = 0;
|
||||
}
|
||||
|
||||
void memfile_autosave()
|
||||
@ -85,15 +86,17 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
|
||||
int done = 0;
|
||||
int filesize;
|
||||
|
||||
if (!use_FAT) return 0;
|
||||
if (!fat_enabled) return 0;
|
||||
|
||||
/* first check if directory exist */
|
||||
DIR_ITER *dir = diropen("/genplus/saves");
|
||||
if (dir == NULL) mkdir("/genplus/saves",S_IRWXU);
|
||||
sprintf (pathname, "%s/saves", DEFAULT_PATH);
|
||||
|
||||
DIR_ITER *dir = diropen(pathname);
|
||||
if (dir == NULL) mkdir(pathname,S_IRWXU);
|
||||
else dirclose(dir);
|
||||
|
||||
/* build complete SDCARD filename */
|
||||
sprintf (pathname, "/genplus/saves/%s", filename);
|
||||
sprintf (pathname, "%s/%s", pathname, filename);
|
||||
|
||||
/* open file */
|
||||
FILE *fp = fopen(pathname, direction ? "rb" : "wb");
|
||||
@ -104,17 +107,17 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case 0: /* SAVING */
|
||||
switch (direction)
|
||||
{
|
||||
case 0: /* SAVING */
|
||||
|
||||
if (filetype) /* SRAM */
|
||||
{
|
||||
memcpy(savebuffer, sram.sram, 0x10000);
|
||||
sram.crc = crc32 (0, sram.sram, 0x10000);
|
||||
if (filetype) /* SRAM */
|
||||
{
|
||||
memcpy(savebuffer, sram.sram, 0x10000);
|
||||
sram.crc = crc32 (0, sram.sram, 0x10000);
|
||||
filesize = 0x10000;
|
||||
}
|
||||
else filesize = state_save(savebuffer); /* STATE */
|
||||
}
|
||||
else filesize = state_save(savebuffer); /* STATE */
|
||||
|
||||
/* write buffer */
|
||||
done = fwrite(savebuffer, 1, filesize, fp);
|
||||
@ -129,9 +132,9 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
|
||||
sprintf (filename, "Saved %d bytes successfully", done);
|
||||
WaitPrompt (filename);
|
||||
return 1;
|
||||
|
||||
case 1: /* LOADING */
|
||||
|
||||
|
||||
case 1: /* LOADING */
|
||||
|
||||
/* read size */
|
||||
fseek(fp , 0 , SEEK_END);
|
||||
filesize = ftell (fp);
|
||||
@ -147,20 +150,20 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if (filetype) /* SRAM */
|
||||
{
|
||||
memcpy(sram.sram, savebuffer, filesize);
|
||||
sram.crc = crc32 (0, sram.sram, 0x10000);
|
||||
system_reset ();
|
||||
}
|
||||
else state_load(savebuffer); /* STATE */
|
||||
|
||||
sprintf (filename, "Loaded %d bytes successfully", done);
|
||||
WaitPrompt (filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (filetype) /* SRAM */
|
||||
{
|
||||
memcpy(sram.sram, savebuffer, filesize);
|
||||
sram.crc = crc32 (0, sram.sram, 0x10000);
|
||||
system_reset ();
|
||||
}
|
||||
else state_load(savebuffer); /* STATE */
|
||||
|
||||
sprintf (filename, "Loaded %d bytes successfully", done);
|
||||
WaitPrompt (filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -174,21 +177,21 @@ static int SD_ManageFile(char *filename, int direction, int filetype)
|
||||
*****************************************************************************/
|
||||
int MountTheCard (u8 slot)
|
||||
{
|
||||
int tries = 0;
|
||||
int CardError;
|
||||
*(unsigned long *) (0xcc006800) |= 1 << 13; /*** Disable Encryption ***/
|
||||
int tries = 0;
|
||||
int CardError;
|
||||
*(unsigned long *) (0xcc006800) |= 1 << 13; /*** Disable Encryption ***/
|
||||
#ifndef HW_RVL
|
||||
uselessinquiry ();
|
||||
uselessinquiry ();
|
||||
#endif
|
||||
while (tries < 10)
|
||||
{
|
||||
VIDEO_WaitVSync ();
|
||||
CardError = CARD_Mount (slot, SysArea, NULL); /*** Don't need or want a callback ***/
|
||||
if (CardError == 0) return 1;
|
||||
else EXI_ProbeReset ();
|
||||
tries++;
|
||||
}
|
||||
return 0;
|
||||
CardError = CARD_Mount (slot, SysArea, NULL); /*** Don't need or want a callback ***/
|
||||
if (CardError == 0) return 1;
|
||||
else EXI_ProbeReset ();
|
||||
tries++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -199,13 +202,13 @@ int MountTheCard (u8 slot)
|
||||
****************************************************************************/
|
||||
int CardFileExists (char *filename, u8 slot)
|
||||
{
|
||||
int CardError = CARD_FindFirst (slot, &CardDir, TRUE);
|
||||
while (CardError != CARD_ERROR_NOFILE)
|
||||
{
|
||||
CardError = CARD_FindNext (&CardDir);
|
||||
if (strcmp ((char *) CardDir.filename, filename) == 0) return 1;
|
||||
}
|
||||
return 0;
|
||||
int CardError = CARD_FindFirst (slot, &CardDir, TRUE);
|
||||
while (CardError != CARD_ERROR_NOFILE)
|
||||
{
|
||||
CardError = CARD_FindNext (&CardDir);
|
||||
if (strcmp ((char *) CardDir.filename, filename) == 0) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -221,185 +224,185 @@ int CardFileExists (char *filename, u8 slot)
|
||||
****************************************************************************/
|
||||
int ManageSRAM (u8 direction, u8 device)
|
||||
{
|
||||
char filename[128];
|
||||
char action[80];
|
||||
int CardError;
|
||||
unsigned int SectorSize;
|
||||
int blocks;
|
||||
char comment[2][32] = { {"Genesis Plus 1.2a"}, {"SRAM Save"} };
|
||||
char filename[128];
|
||||
char action[80];
|
||||
int CardError;
|
||||
unsigned int SectorSize;
|
||||
int blocks;
|
||||
char comment[2][32] = { {"Genesis Plus 1.2a"}, {"SRAM Save"} };
|
||||
int outbytes = 0;
|
||||
int sbo;
|
||||
unsigned long inzipped,outzipped;
|
||||
int sbo;
|
||||
unsigned long inzipped,outzipped;
|
||||
|
||||
if (!genromsize) return 0;
|
||||
if (!genromsize) return 0;
|
||||
|
||||
/* clean buffer */
|
||||
/* clean buffer */
|
||||
memset(savebuffer, 0, 0x24000);
|
||||
|
||||
if (direction) ShowAction ("Loading SRAM ...");
|
||||
else ShowAction ("Saving SRAM ...");
|
||||
if (direction) ShowAction ("Loading SRAM ...");
|
||||
else ShowAction ("Saving SRAM ...");
|
||||
|
||||
/* First, build a filename */
|
||||
sprintf (filename, "MD-%04X.srm", realchecksum);
|
||||
strcpy (comment[1], filename);
|
||||
/* First, build a filename */
|
||||
sprintf (filename, "MD-%04X.srm", realchecksum);
|
||||
strcpy (comment[1], filename);
|
||||
|
||||
/* device is SDCARD, let's go */
|
||||
if (device == 0) return SD_ManageFile(filename,direction,1);
|
||||
|
||||
/* device is SDCARD, let's go */
|
||||
if (device == 0) return SD_ManageFile(filename,direction,1);
|
||||
|
||||
/* set MCARD slot nr. */
|
||||
u8 CARDSLOT = device - 1;
|
||||
|
||||
/* device is MCARD, we continue */
|
||||
if (direction == 0) /*** Saving ***/
|
||||
{
|
||||
/*** Build the output buffer ***/
|
||||
memcpy (&savebuffer, &icon, 2048);
|
||||
memcpy (&savebuffer[2048], &comment[0], 64);
|
||||
/* device is MCARD, we continue */
|
||||
if (direction == 0) /*** Saving ***/
|
||||
{
|
||||
/*** Build the output buffer ***/
|
||||
memcpy (&savebuffer, &icon, 2048);
|
||||
memcpy (&savebuffer[2048], &comment[0], 64);
|
||||
|
||||
inzipped = 0x10000;
|
||||
outzipped = 0x12000;
|
||||
compress2 ((Bytef *) &savebuffer[2112+sizeof(outzipped)], &outzipped, (Bytef *) &sram.sram, inzipped, 9);
|
||||
memcpy(&savebuffer[2112], &outzipped, sizeof(outzipped));
|
||||
}
|
||||
|
||||
outbytes = 2048 + 64 + outzipped + sizeof(outzipped);
|
||||
inzipped = 0x10000;
|
||||
outzipped = 0x12000;
|
||||
compress2 ((Bytef *) &savebuffer[2112+sizeof(outzipped)], &outzipped, (Bytef *) &sram.sram, inzipped, 9);
|
||||
memcpy(&savebuffer[2112], &outzipped, sizeof(outzipped));
|
||||
}
|
||||
|
||||
/*** Initialise the CARD system ***/
|
||||
memset (&SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("GENP", "00");
|
||||
outbytes = 2048 + 64 + outzipped + sizeof(outzipped);
|
||||
|
||||
/*** Attempt to mount the card ***/
|
||||
CardError = MountTheCard (CARDSLOT);
|
||||
/*** Initialise the CARD system ***/
|
||||
memset (&SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("GENP", "00");
|
||||
|
||||
if (CardError)
|
||||
{
|
||||
/*** Retrieve the sector size ***/
|
||||
CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize);
|
||||
/*** Attempt to mount the card ***/
|
||||
CardError = MountTheCard (CARDSLOT);
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case 0: /*** Saving ***/
|
||||
/*** Determine number of blocks on this card ***/
|
||||
blocks = (outbytes / SectorSize) * SectorSize;
|
||||
if (outbytes % SectorSize) blocks += SectorSize;
|
||||
if (CardError)
|
||||
{
|
||||
/*** Retrieve the sector size ***/
|
||||
CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize);
|
||||
|
||||
/*** Check if a previous save exists ***/
|
||||
if (CardFileExists (filename,CARDSLOT))
|
||||
{
|
||||
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Open : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
switch (direction)
|
||||
{
|
||||
case 0: /*** Saving ***/
|
||||
/*** Determine number of blocks on this card ***/
|
||||
blocks = (outbytes / SectorSize) * SectorSize;
|
||||
if (outbytes % SectorSize) blocks += SectorSize;
|
||||
|
||||
int size = CardFile.len;
|
||||
CARD_Close (&CardFile);
|
||||
/*** Check if a previous save exists ***/
|
||||
if (CardFileExists (filename,CARDSLOT))
|
||||
{
|
||||
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Open : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (size < blocks)
|
||||
{
|
||||
/* new size is bigger: check if there is enough space left */
|
||||
CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Update : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Delete(CARDSLOT, "TEMP");
|
||||
}
|
||||
int size = CardFile.len;
|
||||
CARD_Close (&CardFile);
|
||||
|
||||
/* always delete existing slot */
|
||||
CARD_Delete(CARDSLOT, filename);
|
||||
}
|
||||
|
||||
/*** Create a new slot ***/
|
||||
CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error create : %d %d", CardError, CARDSLOT);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
if (size < blocks)
|
||||
{
|
||||
/* new size is bigger: check if there is enough space left */
|
||||
CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Update : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Delete(CARDSLOT, "TEMP");
|
||||
}
|
||||
|
||||
/*** Continue and save ***/
|
||||
CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
|
||||
CardStatus.icon_addr = 0x0;
|
||||
CardStatus.icon_fmt = 2;
|
||||
CardStatus.icon_speed = 1;
|
||||
CardStatus.comment_addr = 2048;
|
||||
CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
|
||||
/* always delete existing slot */
|
||||
CARD_Delete(CARDSLOT, filename);
|
||||
}
|
||||
|
||||
/*** And write the blocks out ***/
|
||||
sbo = 0;
|
||||
while (outbytes > 0)
|
||||
{
|
||||
CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo);
|
||||
outbytes -= SectorSize;
|
||||
sbo += SectorSize;
|
||||
}
|
||||
/*** Create a new slot ***/
|
||||
CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error create : %d %d", CardError, CARDSLOT);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
sram.crc = crc32 (0, &sram.sram[0], 0x10000);
|
||||
sprintf (action, "Saved %d bytes successfully", blocks);
|
||||
WaitPrompt (action);
|
||||
return 1;
|
||||
/*** Continue and save ***/
|
||||
CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
|
||||
CardStatus.icon_addr = 0x0;
|
||||
CardStatus.icon_fmt = 2;
|
||||
CardStatus.icon_speed = 1;
|
||||
CardStatus.comment_addr = 2048;
|
||||
CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
|
||||
|
||||
default: /*** Loading ***/
|
||||
if (!CardFileExists (filename,CARDSLOT))
|
||||
{
|
||||
WaitPrompt ("No SRAM File Found");
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
/*** And write the blocks out ***/
|
||||
sbo = 0;
|
||||
while (outbytes > 0)
|
||||
{
|
||||
CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo);
|
||||
outbytes -= SectorSize;
|
||||
sbo += SectorSize;
|
||||
}
|
||||
|
||||
memset (&CardFile, 0, sizeof (CardFile));
|
||||
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Open : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
sram.crc = crc32 (0, &sram.sram[0], 0x10000);
|
||||
sprintf (action, "Saved %d bytes successfully", blocks);
|
||||
WaitPrompt (action);
|
||||
return 1;
|
||||
|
||||
blocks = CardFile.len;
|
||||
if (blocks < SectorSize) blocks = SectorSize;
|
||||
if (blocks % SectorSize) blocks++;
|
||||
default: /*** Loading ***/
|
||||
if (!CardFileExists (filename,CARDSLOT))
|
||||
{
|
||||
WaitPrompt ("No SRAM File Found");
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** Just read the file back in ***/
|
||||
sbo = 0;
|
||||
int size = blocks;
|
||||
while (blocks > 0)
|
||||
{
|
||||
CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo);
|
||||
sbo += SectorSize;
|
||||
blocks -= SectorSize;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
memset (&CardFile, 0, sizeof (CardFile));
|
||||
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Open : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy to SRAM */
|
||||
memcpy(&inzipped,&savebuffer[2112],sizeof(inzipped));
|
||||
outzipped = 0x10000;
|
||||
uncompress ((Bytef *) &sram.sram, &outzipped, (Bytef *) &savebuffer[2112+sizeof(inzipped)], inzipped);
|
||||
sram.crc = crc32 (0, &sram.sram[0], 0x10000);
|
||||
system_reset ();
|
||||
blocks = CardFile.len;
|
||||
if (blocks < SectorSize) blocks = SectorSize;
|
||||
if (blocks % SectorSize) blocks++;
|
||||
|
||||
/*** Inform user ***/
|
||||
sprintf (action, "Loaded %d bytes successfully", size);
|
||||
WaitPrompt (action);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else WaitPrompt ("Unable to mount memory card");
|
||||
return 0; /*** Signal failure ***/
|
||||
/*** Just read the file back in ***/
|
||||
sbo = 0;
|
||||
int size = blocks;
|
||||
while (blocks > 0)
|
||||
{
|
||||
CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo);
|
||||
sbo += SectorSize;
|
||||
blocks -= SectorSize;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
|
||||
/* Copy to SRAM */
|
||||
memcpy(&inzipped,&savebuffer[2112],sizeof(inzipped));
|
||||
outzipped = 0x10000;
|
||||
uncompress ((Bytef *) &sram.sram, &outzipped, (Bytef *) &savebuffer[2112+sizeof(inzipped)], inzipped);
|
||||
sram.crc = crc32 (0, &sram.sram[0], 0x10000);
|
||||
system_reset ();
|
||||
|
||||
/*** Inform user ***/
|
||||
sprintf (action, "Loaded %d bytes successfully", size);
|
||||
WaitPrompt (action);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else WaitPrompt ("Unable to mount memory card");
|
||||
return 0; /*** Signal failure ***/
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -412,174 +415,174 @@ int ManageSRAM (u8 direction, u8 device)
|
||||
****************************************************************************/
|
||||
int ManageState (u8 direction, u8 device)
|
||||
{
|
||||
char filename[128];
|
||||
char action[80];
|
||||
int CardError;
|
||||
unsigned int SectorSize;
|
||||
int blocks;
|
||||
char comment[2][32] = { {"Genesis Plus 1.2a [FRZ]"}, {"Freeze State"} };
|
||||
int outbytes = 0;
|
||||
int sbo;
|
||||
int state_size = 0;
|
||||
char filename[128];
|
||||
char action[80];
|
||||
int CardError;
|
||||
unsigned int SectorSize;
|
||||
int blocks;
|
||||
char comment[2][32] = { {"Genesis Plus 1.2a [FRZ]"}, {"Freeze State"} };
|
||||
int outbytes = 0;
|
||||
int sbo;
|
||||
int state_size = 0;
|
||||
|
||||
if (!genromsize) return 0;
|
||||
if (!genromsize) return 0;
|
||||
|
||||
/* clean buffer */
|
||||
memset(savebuffer, 0, 0x24000);
|
||||
/* clean buffer */
|
||||
memset(savebuffer, 0, 0x24000);
|
||||
|
||||
if (direction) ShowAction ("Loading State ...");
|
||||
else ShowAction ("Saving State ...");
|
||||
else ShowAction ("Saving State ...");
|
||||
|
||||
/* First, build a filename */
|
||||
sprintf (filename, "MD-%04X.gpz", realchecksum);
|
||||
strcpy (comment[1], filename);
|
||||
/* First, build a filename */
|
||||
sprintf (filename, "MD-%04X.gpz", realchecksum);
|
||||
strcpy (comment[1], filename);
|
||||
|
||||
/* device is SDCARD, let's go */
|
||||
if (device == 0) return SD_ManageFile(filename,direction,0);
|
||||
/* device is SDCARD, let's go */
|
||||
if (device == 0) return SD_ManageFile(filename,direction,0);
|
||||
|
||||
/* set MCARD slot nr. */
|
||||
u8 CARDSLOT = device - 1;
|
||||
|
||||
/* device is MCARD, we continue */
|
||||
if (direction == 0) /* Saving */
|
||||
{
|
||||
/* Build the output buffer */
|
||||
memcpy (&savebuffer, &icon, 2048);
|
||||
memcpy (&savebuffer[2048], &comment[0], 64);
|
||||
state_size = state_save(&savebuffer[2112]);
|
||||
}
|
||||
/* device is MCARD, we continue */
|
||||
if (direction == 0) /* Saving */
|
||||
{
|
||||
/* Build the output buffer */
|
||||
memcpy (&savebuffer, &icon, 2048);
|
||||
memcpy (&savebuffer[2048], &comment[0], 64);
|
||||
state_size = state_save(&savebuffer[2112]);
|
||||
}
|
||||
|
||||
outbytes = 2048 + 64 + state_size;
|
||||
outbytes = 2048 + 64 + state_size;
|
||||
|
||||
/*** Initialise the CARD system ***/
|
||||
memset (&SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("GENP", "00");
|
||||
/*** Initialise the CARD system ***/
|
||||
memset (&SysArea, 0, CARD_WORKAREA);
|
||||
CARD_Init ("GENP", "00");
|
||||
|
||||
/*** Attempt to mount the card ***/
|
||||
CardError = MountTheCard (CARDSLOT);
|
||||
/*** Attempt to mount the card ***/
|
||||
CardError = MountTheCard (CARDSLOT);
|
||||
|
||||
if (CardError)
|
||||
{
|
||||
/*** Retrieve the sector size ***/
|
||||
CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize);
|
||||
if (CardError)
|
||||
{
|
||||
/*** Retrieve the sector size ***/
|
||||
CardError = CARD_GetSectorSize (CARDSLOT, &SectorSize);
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case 0: /*** Saving ***/
|
||||
/*** Determine number of blocks on this card ***/
|
||||
blocks = (outbytes / SectorSize) * SectorSize;
|
||||
if (outbytes % SectorSize) blocks += SectorSize;
|
||||
switch (direction)
|
||||
{
|
||||
case 0: /*** Saving ***/
|
||||
/*** Determine number of blocks on this card ***/
|
||||
blocks = (outbytes / SectorSize) * SectorSize;
|
||||
if (outbytes % SectorSize) blocks += SectorSize;
|
||||
|
||||
/*** Check if a previous save exists ***/
|
||||
if (CardFileExists (filename, CARDSLOT))
|
||||
{
|
||||
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Open : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
/*** Check if a previous save exists ***/
|
||||
if (CardFileExists (filename, CARDSLOT))
|
||||
{
|
||||
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Open : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int size = CardFile.len;
|
||||
CARD_Close (&CardFile);
|
||||
int size = CardFile.len;
|
||||
CARD_Close (&CardFile);
|
||||
|
||||
if (size < blocks)
|
||||
{
|
||||
/* new size is bigger: check if there is enough space left */
|
||||
CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Update : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Delete(CARDSLOT, "TEMP");
|
||||
}
|
||||
if (size < blocks)
|
||||
{
|
||||
/* new size is bigger: check if there is enough space left */
|
||||
CardError = CARD_Create (CARDSLOT, "TEMP", blocks-size, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Update : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Delete(CARDSLOT, "TEMP");
|
||||
}
|
||||
|
||||
/* always delete existing slot */
|
||||
CARD_Delete(CARDSLOT, filename);
|
||||
}
|
||||
/* always delete existing slot */
|
||||
CARD_Delete(CARDSLOT, filename);
|
||||
}
|
||||
|
||||
/*** Create a new slot ***/
|
||||
CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error create : %d %d", CardError, CARDSLOT);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** Continue and save ***/
|
||||
CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
|
||||
CardStatus.icon_addr = 0x0;
|
||||
CardStatus.icon_fmt = 2;
|
||||
CardStatus.icon_speed = 1;
|
||||
CardStatus.comment_addr = 2048;
|
||||
CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
|
||||
/*** Create a new slot ***/
|
||||
CardError = CARD_Create (CARDSLOT, filename, blocks, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error create : %d %d", CardError, CARDSLOT);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*** Continue and save ***/
|
||||
CARD_GetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
|
||||
CardStatus.icon_addr = 0x0;
|
||||
CardStatus.icon_fmt = 2;
|
||||
CardStatus.icon_speed = 1;
|
||||
CardStatus.comment_addr = 2048;
|
||||
CARD_SetStatus (CARDSLOT, CardFile.filenum, &CardStatus);
|
||||
|
||||
/*** And write the blocks out ***/
|
||||
sbo = 0;
|
||||
while (outbytes > 0)
|
||||
{
|
||||
CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo);
|
||||
outbytes -= SectorSize;
|
||||
sbo += SectorSize;
|
||||
}
|
||||
/*** And write the blocks out ***/
|
||||
sbo = 0;
|
||||
while (outbytes > 0)
|
||||
{
|
||||
CardError = CARD_Write (&CardFile, &savebuffer[sbo], SectorSize, sbo);
|
||||
outbytes -= SectorSize;
|
||||
sbo += SectorSize;
|
||||
}
|
||||
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
sprintf (action, "Saved %d bytes successfully", blocks);
|
||||
WaitPrompt (action);
|
||||
return 1;
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
sprintf (action, "Saved %d bytes successfully", blocks);
|
||||
WaitPrompt (action);
|
||||
return 1;
|
||||
|
||||
default: /*** Loading ***/
|
||||
if (!CardFileExists (filename, CARDSLOT))
|
||||
{
|
||||
WaitPrompt ("No Savestate Found");
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
default: /*** Loading ***/
|
||||
if (!CardFileExists (filename, CARDSLOT))
|
||||
{
|
||||
WaitPrompt ("No Savestate Found");
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset (&CardFile, 0, sizeof (CardFile));
|
||||
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Open : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
memset (&CardFile, 0, sizeof (CardFile));
|
||||
CardError = CARD_Open (CARDSLOT, filename, &CardFile);
|
||||
if (CardError)
|
||||
{
|
||||
sprintf (action, "Error Open : %d", CardError);
|
||||
WaitPrompt (action);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
blocks = CardFile.len;
|
||||
if (blocks < SectorSize) blocks = SectorSize;
|
||||
if (blocks % SectorSize) blocks++;
|
||||
blocks = CardFile.len;
|
||||
if (blocks < SectorSize) blocks = SectorSize;
|
||||
if (blocks % SectorSize) blocks++;
|
||||
|
||||
/*** Just read the file back in ***/
|
||||
sbo = 0;
|
||||
int size = blocks;
|
||||
while (blocks > 0)
|
||||
{
|
||||
CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo);
|
||||
sbo += SectorSize;
|
||||
blocks -= SectorSize;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
/*** Just read the file back in ***/
|
||||
sbo = 0;
|
||||
int size = blocks;
|
||||
while (blocks > 0)
|
||||
{
|
||||
CARD_Read (&CardFile, &savebuffer[sbo], SectorSize, sbo);
|
||||
sbo += SectorSize;
|
||||
blocks -= SectorSize;
|
||||
}
|
||||
CARD_Close (&CardFile);
|
||||
CARD_Unmount (CARDSLOT);
|
||||
|
||||
/*** Load State ***/
|
||||
state_load(&savebuffer[2112]);
|
||||
/*** Load State ***/
|
||||
state_load(&savebuffer[2112]);
|
||||
|
||||
/*** Inform user ***/
|
||||
sprintf (action, "Loaded %d bytes successfully", size);
|
||||
WaitPrompt (action);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else WaitPrompt ("Unable to mount memory card");
|
||||
return 0; /*** Signal failure ***/
|
||||
/*** Inform user ***/
|
||||
sprintf (action, "Loaded %d bytes successfully", size);
|
||||
WaitPrompt (action);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else WaitPrompt ("Unable to mount memory card");
|
||||
return 0; /*** Signal failure ***/
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <di/di.h>
|
||||
#endif
|
||||
|
||||
#include <fat.h>
|
||||
|
||||
int Shutdown = 0;
|
||||
|
||||
#ifdef HW_RVL
|
||||
@ -46,11 +48,14 @@ void Power_Off(void)
|
||||
***************************************************************************/
|
||||
static void load_bios()
|
||||
{
|
||||
char pathname[MAXPATHLEN];
|
||||
|
||||
/* reset BIOS found flag */
|
||||
config.bios_enabled &= ~2;
|
||||
|
||||
/* open file */
|
||||
FILE *fp = fopen("/genplus/BIOS.bin", "rb");
|
||||
sprintf (pathname, "%s/BIOS.bin", DEFAULT_PATH);
|
||||
FILE *fp = fopen(pathname, "rb");
|
||||
if (fp == NULL) return;
|
||||
|
||||
/* read file */
|
||||
@ -113,12 +118,12 @@ void reloadrom ()
|
||||
***************************************************************************/
|
||||
int FramesPerSecond = 0;
|
||||
int frameticker = 0;
|
||||
bool use_FAT = 0;
|
||||
bool fat_enabled = 0;
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
/* initialize Wii DVD interface first */
|
||||
/* initialize Wii DVD interface first */
|
||||
DI_Close();
|
||||
DI_Init();
|
||||
#endif
|
||||
@ -127,7 +132,7 @@ int main (int argc, char *argv[])
|
||||
long long now, prev;
|
||||
int RenderedFrameCount = 0;
|
||||
int FrameCount = 0;
|
||||
|
||||
|
||||
/* Initialize OGC subsystems */
|
||||
ogc_video__init();
|
||||
ogc_input__init();
|
||||
@ -147,7 +152,7 @@ int main (int argc, char *argv[])
|
||||
/* Initialize FAT Interface */
|
||||
if (fatInitDefault() == true)
|
||||
{
|
||||
use_FAT = 1;
|
||||
fat_enabled = 1;
|
||||
}
|
||||
|
||||
/* Default Config */
|
||||
@ -172,11 +177,11 @@ int main (int argc, char *argv[])
|
||||
legal();
|
||||
MainMenu();
|
||||
ConfigRequested = 0;
|
||||
|
||||
|
||||
/* Initialize Frame timings */
|
||||
frameticker = 0;
|
||||
prev = gettime();
|
||||
|
||||
|
||||
/* Emulation Loop */
|
||||
while (1)
|
||||
{
|
||||
@ -202,7 +207,7 @@ int main (int argc, char *argv[])
|
||||
system_frame(0);
|
||||
RenderedFrameCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use VSync */
|
||||
@ -223,11 +228,11 @@ int main (int argc, char *argv[])
|
||||
|
||||
frameticker--;
|
||||
}
|
||||
|
||||
|
||||
/* update video & audio */
|
||||
ogc_video__update();
|
||||
ogc_audio__update();
|
||||
|
||||
|
||||
/* Check rendered frames (FPS) */
|
||||
FrameCount++;
|
||||
if (FrameCount == vdp_rate)
|
||||
@ -236,17 +241,17 @@ int main (int argc, char *argv[])
|
||||
RenderedFrameCount = 0;
|
||||
FrameCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check for Menu request */
|
||||
if (ConfigRequested)
|
||||
{
|
||||
/* reset AUDIO */
|
||||
ogc_audio__reset();
|
||||
|
||||
|
||||
/* go to menu */
|
||||
MainMenu ();
|
||||
ConfigRequested = 0;
|
||||
|
||||
|
||||
/* reset frame timings */
|
||||
frameticker = 0;
|
||||
prev = gettime();
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
/* global datas */
|
||||
unsigned char soundbuffer[16][3840] ATTRIBUTE_ALIGN(32);
|
||||
int mixbuffer = 0;
|
||||
int mixbuffer = 0;
|
||||
|
||||
static int playbuffer = 0;
|
||||
static int IsPlaying = 0;
|
||||
@ -42,14 +42,14 @@ static void AudioSwitchBuffers()
|
||||
IsPlaying = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
u32 dma_len = (vdp_pal) ? 3840 : 3200;
|
||||
|
||||
/* restart audio DMA with current soundbuffer */
|
||||
AUDIO_InitDMA((u32) soundbuffer[playbuffer], dma_len);
|
||||
DCFlushRange(soundbuffer[playbuffer], dma_len);
|
||||
AUDIO_StartDMA();
|
||||
|
||||
|
||||
/* increment soundbuffers index */
|
||||
if (playbuffer == mixbuffer)
|
||||
{
|
||||
@ -65,10 +65,10 @@ static void AudioSwitchBuffers()
|
||||
|
||||
void ogc_audio__init(void)
|
||||
{
|
||||
AUDIO_Init (NULL);
|
||||
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
|
||||
AUDIO_RegisterDMACallback (AudioSwitchBuffers);
|
||||
memset(soundbuffer, 0, 16 * 3840);
|
||||
AUDIO_Init (NULL);
|
||||
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
|
||||
AUDIO_RegisterDMACallback (AudioSwitchBuffers);
|
||||
memset(soundbuffer, 0, 16 * 3840);
|
||||
}
|
||||
|
||||
void ogc_audio__reset(void)
|
||||
|
@ -77,9 +77,9 @@ static int held_cnt = 0;
|
||||
|
||||
static u32 wpad_dirmap[3][4] =
|
||||
{
|
||||
{WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, // WIIMOTE only
|
||||
{WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, // WIIMOTE + NUNCHUK
|
||||
{WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT} // CLASSIC
|
||||
{WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, /* WIIMOTE only */
|
||||
{WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, /* WIIMOTE + NUNCHUK */
|
||||
{WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT} /* CLASSIC */
|
||||
};
|
||||
|
||||
/* wiimote/expansion available buttons */
|
||||
@ -581,7 +581,7 @@ void ogc_input__init(void)
|
||||
|
||||
#ifdef HW_RVL
|
||||
WPAD_Init();
|
||||
WPAD_SetIdleTimeout(60);
|
||||
WPAD_SetIdleTimeout(60);
|
||||
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
|
||||
WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
|
||||
#endif
|
||||
@ -763,7 +763,7 @@ u16 ogc_input__getMenuButtons(void)
|
||||
s8 y = PAD_StickY(0);
|
||||
if (x > 70) p |= PAD_BUTTON_RIGHT;
|
||||
else if (x < -70) p |= PAD_BUTTON_LEFT;
|
||||
if (y > 60) p |= PAD_BUTTON_UP;
|
||||
if (y > 60) p |= PAD_BUTTON_UP;
|
||||
else if (y < -60) p |= PAD_BUTTON_DOWN;
|
||||
|
||||
#ifdef HW_RVL
|
||||
@ -853,7 +853,7 @@ u16 ogc_input__getMenuButtons(void)
|
||||
if (q & WPAD_CLASSIC_BUTTON_B) p |= PAD_BUTTON_B;
|
||||
if (q & WPAD_CLASSIC_BUTTON_HOME) p |= PAD_TRIGGER_Z;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ sms_ntsc_t sms_ntsc;
|
||||
int gc_pal = 0;
|
||||
|
||||
/*** VI ***/
|
||||
unsigned int *xfb[2]; /*** Double buffered ***/
|
||||
int whichfb = 0; /*** External framebuffer index ***/
|
||||
GXRModeObj *vmode; /*** Menu video mode ***/
|
||||
u8 *texturemem; /*** Texture Data ***/
|
||||
unsigned int *xfb[2]; /*** Double buffered ***/
|
||||
int whichfb = 0; /*** External framebuffer index ***/
|
||||
GXRModeObj *vmode; /*** Menu video mode ***/
|
||||
u8 *texturemem; /*** Texture Data ***/
|
||||
|
||||
/*** GX ***/
|
||||
#define TEX_WIDTH 360 * 2
|
||||
@ -57,12 +57,12 @@ static u32 vwidth, vheight;
|
||||
/* 288 lines progressive (PAL 50Hz) */
|
||||
GXRModeObj TV50hz_288p =
|
||||
{
|
||||
VI_TVMODE_PAL_DS, // viDisplayMode
|
||||
VI_TVMODE_PAL_DS,// viDisplayMode
|
||||
640, // fbWidth
|
||||
286, // efbHeight
|
||||
286, // xfbHeight
|
||||
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2, // viYOrigin
|
||||
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2,// viYOrigin
|
||||
720, // viWidth
|
||||
572, // viHeight
|
||||
VI_XFBMODE_SF, // xFBmode
|
||||
@ -70,34 +70,34 @@ GXRModeObj TV50hz_288p =
|
||||
GX_FALSE, // aa
|
||||
|
||||
// sample points arranged in increasing Y order
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
|
||||
// vertical filter[7], 1/64 units, 6 bits each
|
||||
{
|
||||
0, // line n-1
|
||||
0, // line n-1
|
||||
21, // line n
|
||||
22, // line n
|
||||
21, // line n
|
||||
0, // line n+1
|
||||
0 // line n+1
|
||||
}
|
||||
{
|
||||
0, // line n-1
|
||||
0, // line n-1
|
||||
21, // line n
|
||||
22, // line n
|
||||
21, // line n
|
||||
0, // line n+1
|
||||
0 // line n+1
|
||||
}
|
||||
};
|
||||
|
||||
/* 288 lines interlaced (PAL 50Hz) */
|
||||
GXRModeObj TV50hz_288i =
|
||||
{
|
||||
VI_TVMODE_PAL_INT, // viDisplayMode
|
||||
640, // fbWidth
|
||||
286, // efbHeight
|
||||
286, // xfbHeight
|
||||
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2, // viYOrigin
|
||||
VI_TVMODE_PAL_INT,// viDisplayMode
|
||||
640, // fbWidth
|
||||
286, // efbHeight
|
||||
286, // xfbHeight
|
||||
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_PAL/2 - 572/2)/2,// viYOrigin
|
||||
720, // viWidth
|
||||
572, // viHeight
|
||||
VI_XFBMODE_SF, // xFBmode
|
||||
@ -105,34 +105,34 @@ GXRModeObj TV50hz_288i =
|
||||
GX_FALSE, // aa
|
||||
|
||||
// sample points arranged in increasing Y order
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
|
||||
// vertical filter[7], 1/64 units, 6 bits each
|
||||
{
|
||||
0, // line n-1
|
||||
0, // line n-1
|
||||
21, // line n
|
||||
22, // line n
|
||||
21, // line n
|
||||
0, // line n+1
|
||||
0 // line n+1
|
||||
}
|
||||
{
|
||||
0, // line n-1
|
||||
0, // line n-1
|
||||
21, // line n
|
||||
22, // line n
|
||||
21, // line n
|
||||
0, // line n+1
|
||||
0 // line n+1
|
||||
}
|
||||
};
|
||||
|
||||
/* 576 lines interlaced (PAL 50Hz, scaled) */
|
||||
GXRModeObj TV50hz_576i =
|
||||
{
|
||||
VI_TVMODE_PAL_INT, // viDisplayMode
|
||||
VI_TVMODE_PAL_INT,// viDisplayMode
|
||||
640, // fbWidth
|
||||
480, // efbHeight
|
||||
574, // xfbHeight
|
||||
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_PAL - 574)/2, // viYOrigin
|
||||
(VI_MAX_WIDTH_PAL - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_PAL - 574)/2,// viYOrigin
|
||||
720, // viWidth
|
||||
574, // viHeight
|
||||
VI_XFBMODE_DF, // xFBmode
|
||||
@ -140,34 +140,34 @@ GXRModeObj TV50hz_576i =
|
||||
GX_FALSE, // aa
|
||||
|
||||
// sample points arranged in increasing Y order
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
|
||||
// vertical filter[7], 1/64 units, 6 bits each
|
||||
{
|
||||
8, // line n-1
|
||||
8, // line n-1
|
||||
10, // line n
|
||||
12, // line n
|
||||
10, // line n
|
||||
8, // line n+1
|
||||
8 // line n+1
|
||||
}
|
||||
{
|
||||
8, // line n-1
|
||||
8, // line n-1
|
||||
10, // line n
|
||||
12, // line n
|
||||
10, // line n
|
||||
8, // line n+1
|
||||
8 // line n+1
|
||||
}
|
||||
};
|
||||
|
||||
/* 240 lines progressive (NTSC or PAL 60Hz) */
|
||||
GXRModeObj TV60hz_240p =
|
||||
{
|
||||
VI_TVMODE_EURGB60_DS, // viDisplayMode
|
||||
VI_TVMODE_EURGB60_DS,// viDisplayMode
|
||||
640, // fbWidth
|
||||
240, // efbHeight
|
||||
240, // xfbHeight
|
||||
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
|
||||
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
|
||||
720, // viWidth
|
||||
480, // viHeight
|
||||
VI_XFBMODE_SF, // xFBmode
|
||||
@ -175,34 +175,34 @@ GXRModeObj TV60hz_240p =
|
||||
GX_FALSE, // aa
|
||||
|
||||
// sample points arranged in increasing Y order
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
|
||||
// vertical filter[7], 1/64 units, 6 bits each
|
||||
{
|
||||
0, // line n-1
|
||||
0, // line n-1
|
||||
21, // line n
|
||||
22, // line n
|
||||
21, // line n
|
||||
0, // line n+1
|
||||
0 // line n+1
|
||||
}
|
||||
{
|
||||
0, // line n-1
|
||||
0, // line n-1
|
||||
21, // line n
|
||||
22, // line n
|
||||
21, // line n
|
||||
0, // line n+1
|
||||
0 // line n+1
|
||||
}
|
||||
};
|
||||
|
||||
/* 240 lines interlaced (NTSC or PAL 60Hz) */
|
||||
GXRModeObj TV60hz_240i =
|
||||
{
|
||||
VI_TVMODE_EURGB60_INT, // viDisplayMode
|
||||
VI_TVMODE_EURGB60_INT,// viDisplayMode
|
||||
640, // fbWidth
|
||||
240, // efbHeight
|
||||
240, // xfbHeight
|
||||
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
|
||||
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_NTSC/2 - 480/2)/2, // viYOrigin
|
||||
720, // viWidth
|
||||
480, // viHeight
|
||||
VI_XFBMODE_SF, // xFBmode
|
||||
@ -210,34 +210,34 @@ GXRModeObj TV60hz_240i =
|
||||
GX_FALSE, // aa
|
||||
|
||||
// sample points arranged in increasing Y order
|
||||
{
|
||||
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{3,2},{9,6},{3,10}, // pix 1
|
||||
{9,2},{3,6},{9,10}, // pix 2
|
||||
{9,2},{3,6},{9,10} // pix 3
|
||||
},
|
||||
{
|
||||
{3,2},{9,6},{3,10}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{3,2},{9,6},{3,10}, // pix 1
|
||||
{9,2},{3,6},{9,10}, // pix 2
|
||||
{9,2},{3,6},{9,10} // pix 3
|
||||
},
|
||||
|
||||
// vertical filter[7], 1/64 units, 6 bits each
|
||||
{
|
||||
0, // line n-1
|
||||
0, // line n-1
|
||||
21, // line n
|
||||
22, // line n
|
||||
21, // line n
|
||||
0, // line n+1
|
||||
0 // line n+1
|
||||
}
|
||||
{
|
||||
0, // line n-1
|
||||
0, // line n-1
|
||||
21, // line n
|
||||
22, // line n
|
||||
21, // line n
|
||||
0, // line n+1
|
||||
0 // line n+1
|
||||
}
|
||||
};
|
||||
|
||||
/* 480 lines interlaced (NTSC or PAL 60Hz) */
|
||||
GXRModeObj TV60hz_480i =
|
||||
{
|
||||
VI_TVMODE_EURGB60_INT, // viDisplayMode
|
||||
VI_TVMODE_EURGB60_INT,// viDisplayMode
|
||||
640, // fbWidth
|
||||
480, // efbHeight
|
||||
480, // xfbHeight
|
||||
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
|
||||
(VI_MAX_WIDTH_NTSC - 720)/2, // viXOrigin
|
||||
(VI_MAX_HEIGHT_NTSC - 480)/2, // viYOrigin
|
||||
720, // viWidth
|
||||
480, // viHeight
|
||||
VI_XFBMODE_DF, // xFBmode
|
||||
@ -245,29 +245,29 @@ GXRModeObj TV60hz_480i =
|
||||
GX_FALSE, // aa
|
||||
|
||||
// sample points arranged in increasing Y order
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
{
|
||||
{6,6},{6,6},{6,6}, // pix 0, 3 sample points, 1/12 units, 4 bits each
|
||||
{6,6},{6,6},{6,6}, // pix 1
|
||||
{6,6},{6,6},{6,6}, // pix 2
|
||||
{6,6},{6,6},{6,6} // pix 3
|
||||
},
|
||||
|
||||
// vertical filter[7], 1/64 units, 6 bits each
|
||||
{
|
||||
8, // line n-1
|
||||
8, // line n-1
|
||||
10, // line n
|
||||
12, // line n
|
||||
10, // line n
|
||||
8, // line n+1
|
||||
8 // line n+1
|
||||
}
|
||||
{
|
||||
8, // line n-1
|
||||
8, // line n-1
|
||||
10, // line n
|
||||
12, // line n
|
||||
10, // line n
|
||||
8, // line n+1
|
||||
8 // line n+1
|
||||
}
|
||||
};
|
||||
|
||||
/* TV Modes table */
|
||||
GXRModeObj *tvmodes[6] = {
|
||||
&TV60hz_240p, &TV60hz_240i, &TV60hz_480i, /* 60hz modes */
|
||||
&TV50hz_288p, &TV50hz_288i, &TV50hz_576i /* 50Hz modes */
|
||||
&TV60hz_240p, &TV60hz_240i, &TV60hz_480i, /* 60hz modes */
|
||||
&TV50hz_288p, &TV50hz_288i, &TV50hz_576i /* 50Hz modes */
|
||||
};
|
||||
|
||||
typedef struct tagcamera
|
||||
@ -279,7 +279,7 @@ typedef struct tagcamera
|
||||
|
||||
/*** Square Matrix
|
||||
This structure controls the size of the image on the screen.
|
||||
Think of the output as a -80 x 80 by -60 x 60 graph.
|
||||
Think of the output as a -80 x 80 by -60 x 60 graph.
|
||||
***/
|
||||
static s16 square[] ATTRIBUTE_ALIGN (32) =
|
||||
{
|
||||
@ -287,10 +287,10 @@ static s16 square[] ATTRIBUTE_ALIGN (32) =
|
||||
* X, Y, Z
|
||||
* Values set are for roughly 4:3 aspect
|
||||
*/
|
||||
-HASPECT, VASPECT, 0, // 0
|
||||
HASPECT, VASPECT, 0, // 1
|
||||
HASPECT, -VASPECT, 0, // 2
|
||||
-HASPECT, -VASPECT, 0, // 3
|
||||
-HASPECT, VASPECT, 0, // 0
|
||||
HASPECT, VASPECT, 0, // 1
|
||||
HASPECT, -VASPECT, 0, // 2
|
||||
-HASPECT, -VASPECT, 0, // 3
|
||||
};
|
||||
|
||||
static camera cam = {
|
||||
@ -402,23 +402,23 @@ static void gxScale(GXRModeObj *rmode)
|
||||
/* original aspect ratio */
|
||||
/* the following values have been detected from comparison with a real 50/60hz Mega Drive */
|
||||
if (config.overscan)
|
||||
{
|
||||
{
|
||||
/* borders are emulated */
|
||||
xscale = 358 + ((reg[12] & 1)*2) - gc_pal;
|
||||
xscale = 358 + ((reg[12] & 1)*2) - gc_pal;
|
||||
yscale = vdp_pal + ((gc_pal && !config.render) ? 143 : 120);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* borders are simulated (black) */
|
||||
xscale = 325 + ((reg[12] & 1)*2) - gc_pal;
|
||||
xscale = 325 + ((reg[12] & 1)*2) - gc_pal;
|
||||
yscale = bitmap.viewport.h / 2;
|
||||
if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 240 / 288;
|
||||
else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 240;
|
||||
if (vdp_pal && (!gc_pal || config.render)) yscale = yscale * 240 / 288;
|
||||
else if (!vdp_pal && gc_pal && !config.render) yscale = yscale * 288 / 240;
|
||||
}
|
||||
|
||||
xshift = config.xshift;
|
||||
yshift = 2 - vdp_pal + 2*(gc_pal & !config.render) + config.yshift;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* manual aspect ratio (default is fullscreen) */
|
||||
@ -440,8 +440,8 @@ static void gxScale(GXRModeObj *rmode)
|
||||
yscale += config.yscale;
|
||||
|
||||
xshift = config.xshift;
|
||||
yshift = config.yshift;
|
||||
}
|
||||
yshift = config.yshift;
|
||||
}
|
||||
|
||||
/* Double resolution modes */
|
||||
if (config.render)
|
||||
@ -488,9 +488,9 @@ static void gxScale(GXRModeObj *rmode)
|
||||
|
||||
/* update GX scaler (Vertex Position Matrix) */
|
||||
square[6] = square[3] = xscale + xshift;
|
||||
square[0] = square[9] = -xscale + xshift;
|
||||
square[0] = square[9] = -xscale + xshift;
|
||||
square[4] = square[1] = yscale + yshift;
|
||||
square[7] = square[10] = -yscale + yshift;
|
||||
square[7] = square[10] = -yscale + yshift;
|
||||
|
||||
DCFlushRange (square, 32);
|
||||
GX_InvVtxCache ();
|
||||
@ -499,7 +499,7 @@ static void gxScale(GXRModeObj *rmode)
|
||||
/* Reinitialize Video */
|
||||
void ogc_video__reset()
|
||||
{
|
||||
Mtx p;
|
||||
Mtx p;
|
||||
GXRModeObj *rmode;
|
||||
|
||||
/* 50Hz/60Hz mode */
|
||||
@ -522,18 +522,18 @@ void ogc_video__reset()
|
||||
|
||||
/* Set current TV mode */
|
||||
if (config.render) rmode = tvmodes[gc_pal*3 + 2];
|
||||
else rmode = tvmodes[gc_pal*3 + interlaced];
|
||||
else rmode = tvmodes[gc_pal*3 + interlaced];
|
||||
|
||||
/* Aspect ratio */
|
||||
gxScale(rmode);
|
||||
|
||||
/* Configure VI */
|
||||
VIDEO_Configure (rmode);
|
||||
VIDEO_ClearFrameBuffer(rmode, xfb[whichfb], COLOR_BLACK);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
|
||||
VIDEO_ClearFrameBuffer(rmode, xfb[whichfb], COLOR_BLACK);
|
||||
VIDEO_Flush();
|
||||
VIDEO_WaitVSync();
|
||||
if (rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||
else while (VIDEO_GetNextField()) VIDEO_WaitVSync();
|
||||
|
||||
/* Configure GX */
|
||||
GX_SetViewport (0.0F, 0.0F, rmode->fbWidth, rmode->efbHeight, 0.0F, 1.0F);
|
||||
@ -596,7 +596,7 @@ void ogc_video__update()
|
||||
ogc_video__reset();
|
||||
|
||||
/* reinitialize texture */
|
||||
GX_InitTexObj (&texobj, texturemem, vwidth * 4, vheight * 4, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GX_InitTexObj (&texobj, texturemem, vwidth * 4, vheight * 4, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
|
||||
/* enable/disable bilinear filtering */
|
||||
if (!config.bilinear)
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <fat.h>
|
||||
#include <sys/dir.h>
|
||||
|
||||
#include "ogc_input.h"
|
||||
@ -19,6 +18,8 @@
|
||||
#include "config.h"
|
||||
#include "history.h"
|
||||
|
||||
#define DEFAULT_PATH "/genplus"
|
||||
|
||||
#define update_input() ogc_input__update()
|
||||
|
||||
/* globals */
|
||||
|
404
source/render.c
404
source/render.c
@ -63,7 +63,7 @@ static uint32 make_lut_bgobj_ste(uint32 bx, uint32 sx);
|
||||
static __inline__ uint32 READ_LONG(void *address)
|
||||
{
|
||||
if ((uint32)address & 3)
|
||||
{
|
||||
{
|
||||
#ifdef LSB_FIRST /* little endian version */
|
||||
return ( *((uint8 *)address) +
|
||||
(*((uint8 *)address+1) << 8) +
|
||||
@ -75,14 +75,14 @@ static __inline__ uint32 READ_LONG(void *address)
|
||||
(*((uint8 *)address+1) << 16) +
|
||||
(*((uint8 *)address) << 24) );
|
||||
#endif /* LSB_FIRST */
|
||||
}
|
||||
else return *(uint32 *)address;
|
||||
}
|
||||
else return *(uint32 *)address;
|
||||
}
|
||||
|
||||
static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
{
|
||||
if ((uint32)address & 3)
|
||||
{
|
||||
{
|
||||
#ifdef LSB_FIRST
|
||||
*((uint8 *)address) = data;
|
||||
*((uint8 *)address+1) = (data >> 8);
|
||||
@ -94,9 +94,9 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
*((uint8 *)address+1) = (data >> 16);
|
||||
*((uint8 *)address) = (data >> 24);
|
||||
#endif /* LSB_FIRST */
|
||||
return;
|
||||
}
|
||||
else *(uint32 *)address = data;
|
||||
return;
|
||||
}
|
||||
else *(uint32 *)address = data;
|
||||
}
|
||||
|
||||
#endif /* ALIGN_LONG */
|
||||
@ -112,26 +112,26 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
N = Pattern Number (11 bits)
|
||||
|
||||
MSB PCCVHNNN NNNNNNNN LSB PCCVHNNN NNNNNNNN LSB
|
||||
PATTERN1 PATTERN2
|
||||
PATTERN1 PATTERN2
|
||||
|
||||
Pattern attributes are read from VRAM as 32bits WORD like this:
|
||||
|
||||
LIT_ENDIAN: ATTR is MSB PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN LSB
|
||||
PATTERN2 PATTERN1
|
||||
PATTERN2 PATTERN1
|
||||
|
||||
BIG_ENDIAN: ATTR is MSB PCCVHNNN NNNNNNNN PCCVHNNN NNNNNNNN LSB
|
||||
PATTERN1 PATTERN2
|
||||
PATTERN1 PATTERN2
|
||||
|
||||
|
||||
Each Line Buffer written byte describe one pixel data like this:
|
||||
|
||||
msb SPppcccc lsb
|
||||
msb SPppcccc lsb
|
||||
|
||||
with:
|
||||
S = sprite data indicator (not written here)
|
||||
P = priority bit (from Pattern Attribute)
|
||||
p = color palette (from Pattern Attribute)
|
||||
c = color data (from Pattern Cache)
|
||||
with:
|
||||
S = sprite data indicator (not written here)
|
||||
P = priority bit (from Pattern Attribute)
|
||||
p = color palette (from Pattern Attribute)
|
||||
c = color data (from Pattern Cache)
|
||||
|
||||
|
||||
A column is 2 patterns wide
|
||||
@ -141,11 +141,11 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
/* Draw a single 8-pixel column */
|
||||
/*
|
||||
pattern cache is addressed like this: 00000VHN NNNNNNNN NNYYYXXX
|
||||
with : Y = pattern row (1-8 lines)
|
||||
X = pattern column (1-8 pixels)
|
||||
V = Vertical Flip bit
|
||||
H = Horizontal Flip bit
|
||||
N = Pattern Number (1-2048)
|
||||
with : Y = pattern row (1-8 lines)
|
||||
X = pattern column (1-8 pixels)
|
||||
V = Vertical Flip bit
|
||||
H = Horizontal Flip bit
|
||||
N = Pattern Number (1-2048)
|
||||
*/
|
||||
#ifdef ALIGN_LONG
|
||||
#ifdef LSB_FIRST
|
||||
@ -170,7 +170,7 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
#else
|
||||
#define DRAW_COLUMN(ATTR, LINE) \
|
||||
attr_msb = ATTR >> 16; \
|
||||
atex = atex_table[(ATTR_MSB >> 13) & 7]; \
|
||||
atex = atex_table[(ATTR_MSB >> 13) & 7]; \
|
||||
src = (uint32 *)&bg_pattern_cache[(ATTR_MSB & 0x1FFF) << 6 | (LINE)]; \
|
||||
WRITE_LONG(dst, READ_LONG(src) | atex); \
|
||||
dst++; \
|
||||
@ -202,7 +202,7 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
#else
|
||||
#define DRAW_COLUMN(ATTR, LINE) \
|
||||
attr_msb = ATTR >> 16; \
|
||||
atex = atex_table[(attr_msb >> 13) & 7]; \
|
||||
atex = atex_table[(attr_msb >> 13) & 7]; \
|
||||
src = (uint32 *)&bg_pattern_cache[(attr_msb & 0x1FFF) << 6 | (LINE)]; \
|
||||
*dst++ = (*src++ | atex); \
|
||||
*dst++ = (*src++ | atex); \
|
||||
@ -217,11 +217,11 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
/* Draw a single 16-pixel column */
|
||||
/*
|
||||
pattern cache is addressed like this: 00000VHN NNNNNNNN NYYYYXXX
|
||||
with : Y = pattern row (1-16 lines)
|
||||
X = pattern column (1-8 pixels)
|
||||
V = Vertical Flip bit
|
||||
H = Horizontal Flip bit
|
||||
N = Pattern Number (1-1024)
|
||||
with : Y = pattern row (1-16 lines)
|
||||
X = pattern column (1-8 pixels)
|
||||
V = Vertical Flip bit
|
||||
H = Horizontal Flip bit
|
||||
N = Pattern Number (1-1024)
|
||||
|
||||
one pattern line is 8 pixels = 8 bytes = 2 * 32 bits
|
||||
*/
|
||||
@ -252,7 +252,7 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
#else
|
||||
#define DRAW_COLUMN_IM2(ATTR, LINE) \
|
||||
attr_msb = ATTR >> 16; \
|
||||
atex = atex_table[(attr_msb >> 13) & 7]; \
|
||||
atex = atex_table[(attr_msb >> 13) & 7]; \
|
||||
offs = (attr_msb & 0x03FF) << 7 | (attr_msb & 0x1800) << 6 | (LINE); \
|
||||
if(attr_msb & 0x1000) offs ^= 0x40; \
|
||||
src = (uint32 *)&bg_pattern_cache[offs]; \
|
||||
@ -318,11 +318,11 @@ static __inline__ void WRITE_LONG(void *address, uint32 data)
|
||||
check if non-transparent sprite data has been previously drawn
|
||||
*/
|
||||
#define DRAW_SPRITE_TILE \
|
||||
for(i=0; i<8; i++) \
|
||||
{ \
|
||||
if ((lb[i] & 0x80) && (lb[i] & 0x0F) && (src[i] & 0x0F)) status |= 0x20; \
|
||||
lb[i] = table[(lb[i] << 8) |(src[i] | palette)]; \
|
||||
}
|
||||
for(i=0; i<8; i++) \
|
||||
{ \
|
||||
if ((lb[i] & 0x80) && (lb[i] & 0x0F) && (src[i] & 0x0F)) status |= 0x20; \
|
||||
lb[i] = table[(lb[i] << 8) |(src[i] | palette)]; \
|
||||
}
|
||||
|
||||
|
||||
/* Pixel creation macros, input is four bits each */
|
||||
@ -387,11 +387,11 @@ static uint16 pixel_16[0x100];
|
||||
static uint16 pixel_16_lut[3][0x200];
|
||||
|
||||
/* Line buffers */
|
||||
static uint8 tmp_buf[0x400]; /* Temporary buffer */
|
||||
static uint8 bg_buf[0x400]; /* Merged background buffer */
|
||||
static uint8 nta_buf[0x400]; /* Plane A / Window line buffer */
|
||||
static uint8 ntb_buf[0x400]; /* Plane B line buffer */
|
||||
static uint8 obj_buf[0x400]; /* Object layer line buffer */
|
||||
static uint8 tmp_buf[0x400]; /* Temporary buffer */
|
||||
static uint8 bg_buf[0x400]; /* Merged background buffer */
|
||||
static uint8 nta_buf[0x400]; /* Plane A / Window line buffer */
|
||||
static uint8 ntb_buf[0x400]; /* Plane B line buffer */
|
||||
static uint8 obj_buf[0x400]; /* Object layer line buffer */
|
||||
|
||||
/* Sprite line buffer data */
|
||||
static uint32 object_index_count;
|
||||
@ -401,8 +401,8 @@ static uint32 object_index_count;
|
||||
this is used to convert 3bits RGB values to 5bits (R,B) or 6bits (G) values
|
||||
there is three color modes:
|
||||
normal: RGB range is [0;MAX]
|
||||
half: RGB range is [0;MAX/2] (shadow mode)
|
||||
high: RGB range is [MAX/2;MAX] (highlight mode)
|
||||
half: RGB range is [0;MAX/2] (shadow mode)
|
||||
high: RGB range is [MAX/2;MAX] (highlight mode)
|
||||
|
||||
MAX is 31 (R,B) or 63 (G) for 5:6:5 pixels and 7 (R,G,B) for 3:3:3 pixels
|
||||
MAX/2 is rounded to inferior value (15, 31 or 3)
|
||||
@ -410,59 +410,59 @@ static uint32 object_index_count;
|
||||
the extrapolation is linear and calculated like this:
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
rgb565_norm[0][i] = round(((double)i * 31.0) / 7.0);
|
||||
rgb565_norm[1][i] = round(((double)i * 63.0) / 7.0);
|
||||
|
||||
rgb565_half[0][i] = round(((double)i * 31.0) / 7.0 / 2.0);
|
||||
rgb565_half[1][i] = round(((double)i * 63.0) / 7.0 / 2.0);
|
||||
|
||||
rgb565_high[0][i] = round(((double)i * 31.0) / 7.0 / 2.0 + 15.5);
|
||||
rgb565_high[1][i] = round(((double)i * 63.0) / 7.0 / 2.0 + 31.5);
|
||||
}
|
||||
{
|
||||
rgb565_norm[0][i] = round(((double)i * 31.0) / 7.0);
|
||||
rgb565_norm[1][i] = round(((double)i * 63.0) / 7.0);
|
||||
|
||||
rgb565_half[0][i] = round(((double)i * 31.0) / 7.0 / 2.0);
|
||||
rgb565_half[1][i] = round(((double)i * 63.0) / 7.0 / 2.0);
|
||||
|
||||
rgb565_high[0][i] = round(((double)i * 31.0) / 7.0 / 2.0 + 15.5);
|
||||
rgb565_high[1][i] = round(((double)i * 63.0) / 7.0 / 2.0 + 31.5);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
uint8 rgb565_norm[2][8] = {{0 , 4, 9, 13, 18, 22, 27, 31},
|
||||
{0 , 9, 18, 27, 36, 45, 54, 63}};
|
||||
{0 , 9, 18, 27, 36, 45, 54, 63}};
|
||||
uint8 rgb565_half[2][8] = {{0 , 2, 4, 6, 9, 11, 13, 15},
|
||||
{0 , 4, 9, 13, 18, 22, 27, 31}};
|
||||
{0 , 4, 9, 13, 18, 22, 27, 31}};
|
||||
uint8 rgb565_high[2][8] = {{15, 17, 19, 21, 24, 26, 28, 31},
|
||||
{31, 35, 40, 44, 49, 53, 58, 63}};
|
||||
{31, 35, 40, 44, 49, 53, 58, 63}};
|
||||
|
||||
|
||||
void palette_init(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 0x200; i += 1)
|
||||
{
|
||||
int r, g, b;
|
||||
for (i = 0; i < 0x200; i += 1)
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
r = (i >> 6) & 7;
|
||||
g = (i >> 3) & 7;
|
||||
b = (i >> 0) & 7;
|
||||
r = (i >> 6) & 7;
|
||||
g = (i >> 3) & 7;
|
||||
b = (i >> 0) & 7;
|
||||
|
||||
#ifndef NGC
|
||||
pixel_8_lut[0][i] = MAKE_PIXEL_8(r>>1,g>>1,b>>1);
|
||||
pixel_8_lut[1][i] = MAKE_PIXEL_8(r,g,b);
|
||||
pixel_8_lut[2][i] = MAKE_PIXEL_8((r>>1)|4,(g>>1)|4,(b>>1)|4);
|
||||
pixel_8_lut[0][i] = MAKE_PIXEL_8(r>>1,g>>1,b>>1);
|
||||
pixel_8_lut[1][i] = MAKE_PIXEL_8(r,g,b);
|
||||
pixel_8_lut[2][i] = MAKE_PIXEL_8((r>>1)|4,(g>>1)|4,(b>>1)|4);
|
||||
|
||||
pixel_15_lut[0][i] = MAKE_PIXEL_15(r,g,b);
|
||||
pixel_15_lut[1][i] = MAKE_PIXEL_15(r<<1,g<<1,b<<1);
|
||||
pixel_15_lut[2][i] = MAKE_PIXEL_15(r|8,g|8,b|8);
|
||||
pixel_15_lut[0][i] = MAKE_PIXEL_15(r,g,b);
|
||||
pixel_15_lut[1][i] = MAKE_PIXEL_15(r<<1,g<<1,b<<1);
|
||||
pixel_15_lut[2][i] = MAKE_PIXEL_15(r|8,g|8,b|8);
|
||||
|
||||
pixel_32_lut[0][i] = MAKE_PIXEL_32(r,g,b);
|
||||
pixel_32_lut[1][i] = MAKE_PIXEL_32(r<<1,g<<1,b<<1);
|
||||
pixel_32_lut[2][i] = MAKE_PIXEL_32(r|8,g|8,b|8);
|
||||
pixel_32_lut[0][i] = MAKE_PIXEL_32(r,g,b);
|
||||
pixel_32_lut[1][i] = MAKE_PIXEL_32(r<<1,g<<1,b<<1);
|
||||
pixel_32_lut[2][i] = MAKE_PIXEL_32(r|8,g|8,b|8);
|
||||
#endif
|
||||
|
||||
/* RGB 565 format: we extrapolate each 3-bit value into a 5-bit (R,B) or 6-bit (G) value
|
||||
this is needed to correctly cover full color range: [0-31] for R,B or [0-63] for G */
|
||||
pixel_16_lut[0][i] = MAKE_PIXEL_16(rgb565_half[0][r],rgb565_half[1][g],rgb565_half[0][b]);
|
||||
pixel_16_lut[1][i] = MAKE_PIXEL_16(rgb565_norm[0][r],rgb565_norm[1][g],rgb565_norm[0][b]);
|
||||
pixel_16_lut[2][i] = MAKE_PIXEL_16(rgb565_high[0][r],rgb565_high[1][g],rgb565_high[0][b]);
|
||||
}
|
||||
/* RGB 565 format: we extrapolate each 3-bit value into a 5-bit (R,B) or 6-bit (G) value
|
||||
this is needed to correctly cover full color range: [0-31] for R,B or [0-63] for G */
|
||||
pixel_16_lut[0][i] = MAKE_PIXEL_16(rgb565_half[0][r],rgb565_half[1][g],rgb565_half[0][b]);
|
||||
pixel_16_lut[1][i] = MAKE_PIXEL_16(rgb565_norm[0][r],rgb565_norm[1][g],rgb565_norm[0][b]);
|
||||
pixel_16_lut[2][i] = MAKE_PIXEL_16(rgb565_high[0][r],rgb565_high[1][g],rgb565_high[0][b]);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -471,75 +471,75 @@ void palette_init(void)
|
||||
|
||||
int render_init (void)
|
||||
{
|
||||
int bx, ax, i;
|
||||
int bx, ax, i;
|
||||
|
||||
/* Allocate and align pixel look-up tables */
|
||||
if (lut_base == NULL) lut_base = malloc ((LUT_MAX * LUT_SIZE) + LUT_SIZE);
|
||||
lut[0] = (uint8 *) (((uint32) lut_base + LUT_SIZE) & ~(LUT_SIZE - 1));
|
||||
for (i = 1; i < LUT_MAX; i += 1) lut[i] = lut[0] + (i * LUT_SIZE);
|
||||
/* Allocate and align pixel look-up tables */
|
||||
if (lut_base == NULL) lut_base = malloc ((LUT_MAX * LUT_SIZE) + LUT_SIZE);
|
||||
lut[0] = (uint8 *) (((uint32) lut_base + LUT_SIZE) & ~(LUT_SIZE - 1));
|
||||
for (i = 1; i < LUT_MAX; i += 1) lut[i] = lut[0] + (i * LUT_SIZE);
|
||||
|
||||
/* Make pixel look-up table data */
|
||||
for (bx = 0; bx < 0x100; bx += 1)
|
||||
for (ax = 0; ax < 0x100; ax += 1)
|
||||
{
|
||||
uint16 index = (bx << 8) | (ax);
|
||||
lut[0][index] = make_lut_bg (bx, ax);
|
||||
lut[1][index] = make_lut_obj (bx, ax);
|
||||
lut[2][index] = make_lut_bg_ste (bx, ax);
|
||||
lut[3][index] = make_lut_obj_ste (bx, ax);
|
||||
lut[4][index] = make_lut_bgobj_ste (bx, ax);
|
||||
}
|
||||
/* Make pixel look-up table data */
|
||||
for (bx = 0; bx < 0x100; bx += 1)
|
||||
for (ax = 0; ax < 0x100; ax += 1)
|
||||
{
|
||||
uint16 index = (bx << 8) | (ax);
|
||||
lut[0][index] = make_lut_bg (bx, ax);
|
||||
lut[1][index] = make_lut_obj (bx, ax);
|
||||
lut[2][index] = make_lut_bg_ste (bx, ax);
|
||||
lut[3][index] = make_lut_obj_ste (bx, ax);
|
||||
lut[4][index] = make_lut_bgobj_ste (bx, ax);
|
||||
}
|
||||
|
||||
/* Make pixel data tables */
|
||||
palette_init();
|
||||
/* Make pixel data tables */
|
||||
palette_init();
|
||||
|
||||
/* Set up color update function */
|
||||
/* Set up color update function */
|
||||
#ifndef NGC
|
||||
switch(bitmap.depth)
|
||||
{
|
||||
case 8: color_update = color_update_8; break;
|
||||
case 15: color_update = color_update_15; break;
|
||||
case 16: color_update = color_update_16; break;
|
||||
case 32: color_update = color_update_32; break;
|
||||
}
|
||||
switch(bitmap.depth)
|
||||
{
|
||||
case 8: color_update = color_update_8; break;
|
||||
case 15: color_update = color_update_15; break;
|
||||
case 16: color_update = color_update_16; break;
|
||||
case 32: color_update = color_update_32; break;
|
||||
}
|
||||
#else
|
||||
color_update = color_update_16;
|
||||
color_update = color_update_16;
|
||||
#endif
|
||||
|
||||
/* Make sprite name look-up table */
|
||||
make_name_lut();
|
||||
/* Make sprite name look-up table */
|
||||
make_name_lut();
|
||||
|
||||
return (1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void make_name_lut(void)
|
||||
{
|
||||
int col, row;
|
||||
int vcol, vrow;
|
||||
int width, height;
|
||||
int flipx, flipy;
|
||||
int i, name;
|
||||
int col, row;
|
||||
int vcol, vrow;
|
||||
int width, height;
|
||||
int flipx, flipy;
|
||||
int i, name;
|
||||
|
||||
memset (name_lut, 0, sizeof (name_lut));
|
||||
memset (name_lut, 0, sizeof (name_lut));
|
||||
|
||||
for (i = 0; i < 0x400; i += 1)
|
||||
{
|
||||
vcol = col = i & 3;
|
||||
vrow = row = (i >> 2) & 3;
|
||||
height = (i >> 4) & 3;
|
||||
width = (i >> 6) & 3;
|
||||
flipx = (i >> 8) & 1;
|
||||
flipy = (i >> 9) & 1;
|
||||
for (i = 0; i < 0x400; i += 1)
|
||||
{
|
||||
vcol = col = i & 3;
|
||||
vrow = row = (i >> 2) & 3;
|
||||
height = (i >> 4) & 3;
|
||||
width = (i >> 6) & 3;
|
||||
flipx = (i >> 8) & 1;
|
||||
flipy = (i >> 9) & 1;
|
||||
|
||||
if(flipx) vcol = (width - col);
|
||||
if(flipy) vrow = (height - row);
|
||||
if(flipx) vcol = (width - col);
|
||||
if(flipy) vrow = (height - row);
|
||||
|
||||
name = vrow + (vcol * (height + 1));
|
||||
name = vrow + (vcol * (height + 1));
|
||||
|
||||
if ((row > height) || col > width) name = -1;
|
||||
if ((row > height) || col > width) name = -1;
|
||||
|
||||
name_lut[i] = name;
|
||||
}
|
||||
name_lut[i] = name;
|
||||
}
|
||||
}
|
||||
|
||||
void render_reset(void)
|
||||
@ -547,7 +547,7 @@ void render_reset(void)
|
||||
/* Clear display bitmap */
|
||||
memset(bitmap.data, 0, bitmap.pitch * bitmap.height);
|
||||
|
||||
memset(&clip, 0, sizeof(clip));
|
||||
memset(&clip, 0, sizeof(clip));
|
||||
memset(bg_buf, 0, sizeof(bg_buf));
|
||||
memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
memset(nta_buf, 0, sizeof(nta_buf));
|
||||
@ -555,7 +555,7 @@ void render_reset(void)
|
||||
memset(obj_buf, 0, sizeof(obj_buf));
|
||||
|
||||
#ifndef NGC
|
||||
memset(&pixel_8, 0, sizeof(pixel_8));
|
||||
memset(&pixel_8, 0, sizeof(pixel_8));
|
||||
memset(&pixel_15, 0, sizeof(pixel_15));
|
||||
memset(&pixel_32, 0, sizeof(pixel_32));
|
||||
#endif
|
||||
@ -580,10 +580,10 @@ static inline void update_bg_pattern_cache(uint32 index)
|
||||
uint8 *dst;
|
||||
uint32 bp;
|
||||
#ifdef LSB_FIRST
|
||||
uint8 shift_table[8] = {12, 8, 4, 0, 28, 24, 20, 16};
|
||||
uint8 shift_table[8] = {12, 8, 4, 0, 28, 24, 20, 16};
|
||||
#else
|
||||
uint8 shift_table[8] = {28, 24, 20, 16, 12, 8, 4, 0};
|
||||
#endif
|
||||
uint8 shift_table[8] = {28, 24, 20, 16, 12, 8, 4, 0};
|
||||
#endif
|
||||
|
||||
for(i = 0; i < index; i ++)
|
||||
{
|
||||
@ -599,11 +599,11 @@ static inline void update_bg_pattern_cache(uint32 index)
|
||||
|
||||
for(x = 0; x < 8; x ++)
|
||||
{
|
||||
c = (bp >> shift_table[x]) & 0x0F;
|
||||
dst[0x00000 | (y << 3) | (x)] = (c); /* hf=0, vf=0: normal */
|
||||
dst[0x20000 | (y << 3) | (x ^ 7)] = (c); /* hf=1, vf=0: horizontal flipped */
|
||||
dst[0x40000 | ((y ^ 7) << 3) | (x)] = (c); /* hf=0, vf=1: vertical flipped */
|
||||
dst[0x60000 | ((y ^ 7) << 3) | (x ^ 7)] = (c); /* hf=1, vf=1: horizontal & vertical flipped */
|
||||
c = (bp >> shift_table[x]) & 0x0F;
|
||||
dst[0x00000 | (y << 3) | (x)] = (c); /* hf=0, vf=0: normal */
|
||||
dst[0x20000 | (y << 3) | (x ^ 7)] = (c); /* hf=1, vf=0: horizontal flipped */
|
||||
dst[0x40000 | ((y ^ 7) << 3) | (x)] = (c); /* hf=0, vf=1: vertical flipped */
|
||||
dst[0x60000 | ((y ^ 7) << 3) | (x ^ 7)] = (c); /* hf=1, vf=1: horizontal & vertical flipped */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -751,7 +751,7 @@ void remap_buffer(uint32 line, uint32 width)
|
||||
else sms_ntsc_blit(&sms_ntsc, ( SMS_NTSC_IN_T const * )pixel_16, tmp_buf+0x20-bitmap.viewport.x, width, line);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NGC
|
||||
/* directly fill the RGB565 texture */
|
||||
/* one tile is 32 byte = 4x4 pixels */
|
||||
@ -764,17 +764,17 @@ void remap_buffer(uint32 line, uint32 width)
|
||||
void *out =((void *)&bitmap.data[(line * bitmap.pitch)]);
|
||||
switch(bitmap.depth)
|
||||
{
|
||||
case 8:
|
||||
remap_8(tmp_buf+0x20-bitmap.viewport.x, (uint8 *)out, pixel_8, width);
|
||||
break;
|
||||
case 8:
|
||||
remap_8(tmp_buf+0x20-bitmap.viewport.x, (uint8 *)out, pixel_8, width);
|
||||
break;
|
||||
case 15:
|
||||
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_15, width);
|
||||
break;
|
||||
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_15, width);
|
||||
break;
|
||||
case 16:
|
||||
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_16, width);
|
||||
break;
|
||||
remap_16(tmp_buf+0x20-bitmap.viewport.x, (uint16 *)out, pixel_16, width);
|
||||
break;
|
||||
case 32:
|
||||
remap_32(tmp_buf+0x20-bitmap.viewport.x, (uint32 *)out, pixel_32, width);
|
||||
remap_32(tmp_buf+0x20-bitmap.viewport.x, (uint32 *)out, pixel_32, width);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -782,16 +782,16 @@ void remap_buffer(uint32 line, uint32 width)
|
||||
|
||||
void render_line(uint32 line, uint32 overscan)
|
||||
{
|
||||
uint32 width = bitmap.viewport.w;
|
||||
uint32 width = bitmap.viewport.w;
|
||||
uint32 x_offset = bitmap.viewport.x;
|
||||
|
||||
/* background color (display OFF or borders) */
|
||||
/* background color (display OFF or borders) */
|
||||
if (overscan || !(reg[1] & 0x40))
|
||||
{
|
||||
width += 2 * x_offset;
|
||||
memset(&tmp_buf[0x20 - x_offset], 0x40, width);
|
||||
}
|
||||
else
|
||||
memset(&tmp_buf[0x20 - x_offset], 0x40, width);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 *lb = tmp_buf;
|
||||
|
||||
@ -910,17 +910,17 @@ static void render_bg(uint32 line, uint32 width)
|
||||
uint32 y_scroll = (line + (vs[0] & 0x3FF)) & pf_row_mask;
|
||||
#endif
|
||||
|
||||
uint32 v_line = (y_scroll & 7) << 3;
|
||||
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
|
||||
uint32 v_line = (y_scroll & 7) << 3;
|
||||
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
|
||||
|
||||
if(shift)
|
||||
{
|
||||
dst = (uint32 *)&buf[0x10 + shift];
|
||||
dst = (uint32 *)&buf[0x10 + shift];
|
||||
atbuf = nt[(index-1) & pf_col_mask];
|
||||
DRAW_COLUMN(atbuf, v_line);
|
||||
DRAW_COLUMN(atbuf, v_line);
|
||||
}
|
||||
|
||||
dst = (uint32 *)&buf[0x20 + shift];
|
||||
dst = (uint32 *)&buf[0x20 + shift];
|
||||
for(column = 0; column < end; column ++, index ++)
|
||||
{
|
||||
atbuf = nt[index & pf_col_mask];
|
||||
@ -991,7 +991,7 @@ static void render_bg(uint32 line, uint32 width)
|
||||
if (w)
|
||||
{
|
||||
v_line = (line & 7) << 3;
|
||||
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
|
||||
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
|
||||
dst = (uint32 *)&buf[0x20 + (start << 4)];
|
||||
for(column = start; column < end; column ++)
|
||||
{
|
||||
@ -1029,19 +1029,19 @@ static void render_bg_vs(uint32 line, uint32 width)
|
||||
uint32 index = pf_col_mask + 1 - ((xscroll >> 4) & pf_col_mask);
|
||||
#endif
|
||||
|
||||
uint32 y_scroll, v_line, *nt;
|
||||
uint32 y_scroll, v_line, *nt;
|
||||
|
||||
if(shift)
|
||||
if(shift)
|
||||
{
|
||||
y_scroll = (line & pf_row_mask);
|
||||
v_line = (y_scroll & 7) << 3;
|
||||
nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
|
||||
dst = (uint32 *)&buf[0x10 + shift];
|
||||
dst = (uint32 *)&buf[0x10 + shift];
|
||||
atbuf = nt[(index-1) & pf_col_mask];
|
||||
DRAW_COLUMN(atbuf, v_line);
|
||||
DRAW_COLUMN(atbuf, v_line);
|
||||
}
|
||||
|
||||
dst = (uint32 *)&buf[0x20 + shift];
|
||||
dst = (uint32 *)&buf[0x20 + shift];
|
||||
for(column = start; column < end; column ++, index ++)
|
||||
{
|
||||
#ifdef LSB_FIRST
|
||||
@ -1108,7 +1108,7 @@ static void render_bg_vs(uint32 line, uint32 width)
|
||||
y_scroll = (line + (vs[column] & 0x3FF)) & pf_row_mask;
|
||||
#else
|
||||
y_scroll = (line + ((vs[column] >> 16) & 0x3FF)) & pf_row_mask;
|
||||
#endif
|
||||
#endif
|
||||
v_line = (y_scroll & 7) << 3;
|
||||
nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
|
||||
atbuf = nt[index & pf_col_mask];
|
||||
@ -1124,7 +1124,7 @@ static void render_bg_vs(uint32 line, uint32 width)
|
||||
if (w)
|
||||
{
|
||||
v_line = (line & 7) << 3;
|
||||
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
|
||||
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
|
||||
dst = (uint32 *)&buf[0x20 + (start << 4)];
|
||||
for(column = start; column < end; column ++)
|
||||
{
|
||||
@ -1164,17 +1164,17 @@ static void render_bg_im2(uint32 line, uint32 width, uint32 odd)
|
||||
uint32 y_scroll = (line + ((vs[0] >> 1) & 0x3FF)) & pf_row_mask; /* IM2 specific */
|
||||
#endif
|
||||
|
||||
uint32 v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
|
||||
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
|
||||
uint32 v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
|
||||
uint32 *nt = (uint32 *)&vram[ntbb + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
|
||||
|
||||
if(shift)
|
||||
{
|
||||
dst = (uint32 *)&buf[0x10 + shift];
|
||||
dst = (uint32 *)&buf[0x10 + shift];
|
||||
atbuf = nt[(index-1) & pf_col_mask];
|
||||
DRAW_COLUMN_IM2(atbuf, v_line); /* IM2 specific */
|
||||
DRAW_COLUMN_IM2(atbuf, v_line); /* IM2 specific */
|
||||
}
|
||||
|
||||
dst = (uint32 *)&buf[0x20 + shift];
|
||||
dst = (uint32 *)&buf[0x20 + shift];
|
||||
for(column = 0; column < end; column ++, index ++)
|
||||
{
|
||||
atbuf = nt[index & pf_col_mask];
|
||||
@ -1215,18 +1215,18 @@ static void render_bg_im2(uint32 line, uint32 width, uint32 odd)
|
||||
y_scroll = (line + ((vs[0] >> 17) & 0x3FF)) & pf_row_mask; /* IM2 specific */
|
||||
#endif
|
||||
|
||||
v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
|
||||
nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
|
||||
v_line = (((y_scroll & 7) << 1) | odd) << 3; /* IM2 specific */
|
||||
nt = (uint32 *)&vram[ntab + (((y_scroll >> 3) << pf_shift) & pf_y_mask)];
|
||||
|
||||
if(shift)
|
||||
{
|
||||
dst = (uint32 *)&buf[0x10 + shift + (start<<4)];
|
||||
dst = (uint32 *)&buf[0x10 + shift + (start<<4)];
|
||||
|
||||
/* Window bug */
|
||||
if (start) atbuf = nt[index & pf_col_mask];
|
||||
/* Window bug */
|
||||
if (start) atbuf = nt[index & pf_col_mask];
|
||||
else atbuf = nt[(index-1) & pf_col_mask];
|
||||
|
||||
DRAW_COLUMN_IM2(atbuf, v_line); /* IM2 specific */
|
||||
DRAW_COLUMN_IM2(atbuf, v_line); /* IM2 specific */
|
||||
}
|
||||
|
||||
dst = (uint32 *)&buf[0x20 + shift + (start<<4)];
|
||||
@ -1245,7 +1245,7 @@ static void render_bg_im2(uint32 line, uint32 width, uint32 odd)
|
||||
if (w)
|
||||
{
|
||||
v_line = ((line & 7) << 1 | odd) << 3; /* IM2 specific */
|
||||
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
|
||||
nt = (uint32 *)&vram[ntwb | ((line >> 3) << (6 + (reg[12] & 1)))];
|
||||
dst = (uint32 *)&buf[0x20 + (start << 4)];
|
||||
for(column = start; column < end; column ++)
|
||||
{
|
||||
@ -1612,23 +1612,23 @@ void parse_satb(uint32 line)
|
||||
{
|
||||
ypos = (q[link] >> im2_flag) & 0x1FF;
|
||||
size = q[link + 1] >> 8;
|
||||
height = sizetab[size & 3];
|
||||
height = sizetab[size & 3];
|
||||
|
||||
if((line >= ypos) && (line < (ypos + height)))
|
||||
{
|
||||
/* sprite limit (max. 16 or 20 sprites displayed per line) */
|
||||
if(object_index_count == limit)
|
||||
if(object_index_count == limit)
|
||||
{
|
||||
if(vint_pending == 0) status |= 0x40;
|
||||
return;
|
||||
}
|
||||
|
||||
// using xpos from internal satb stops sprite x
|
||||
// using xpos from internal satb stops sprite x
|
||||
// scrolling in bloodlin.bin,
|
||||
// but this seems to go against the test prog
|
||||
object_info[object_index_count].attr = p[link + 2];
|
||||
object_info[object_index_count].attr = p[link + 2];
|
||||
object_info[object_index_count].xpos = p[link + 3];
|
||||
object_info[object_index_count].ypos = ypos;
|
||||
object_info[object_index_count].ypos = ypos;
|
||||
object_info[object_index_count].size = size;
|
||||
++object_index_count;
|
||||
}
|
||||
@ -1668,14 +1668,14 @@ static void render_obj(uint32 line, uint8 *buf, uint8 *table)
|
||||
xpos = object_info[count].xpos & 0x1ff;
|
||||
|
||||
/* sprite masking */
|
||||
if(xpos != 0) sol_flag = 1;
|
||||
else if(xpos == 0 && sol_flag) return;
|
||||
if(xpos != 0) sol_flag = 1;
|
||||
else if(xpos == 0 && sol_flag) return;
|
||||
|
||||
size = object_info[count].size & 0x0f;
|
||||
width = sizetab[(size >> 2) & 3];
|
||||
width = sizetab[(size >> 2) & 3];
|
||||
|
||||
/* update pixel count (off-screen sprites included) */
|
||||
pixelcount += width;
|
||||
/* update pixel count (off-screen sprites included) */
|
||||
pixelcount += width;
|
||||
|
||||
if(((xpos + width) >= left) && (xpos < right))
|
||||
{
|
||||
@ -1695,10 +1695,10 @@ static void render_obj(uint32 line, uint8 *buf, uint8 *table)
|
||||
|
||||
lb = (uint8 *)&buf[0x20 + (xpos - 0x80)];
|
||||
|
||||
/* number of tiles to draw */
|
||||
/* adjusted for sprite limit */
|
||||
/* number of tiles to draw */
|
||||
/* adjusted for sprite limit */
|
||||
if (pixelcount > bitmap.viewport.w) width -= (pixelcount - bitmap.viewport.w);
|
||||
width >>= 3;
|
||||
width >>= 3;
|
||||
|
||||
for(column = 0; column < width; column += 1, lb+=8)
|
||||
{
|
||||
@ -1709,8 +1709,8 @@ static void render_obj(uint32 line, uint8 *buf, uint8 *table)
|
||||
|
||||
}
|
||||
|
||||
/* sprite limit (256 or 320 pixels) */
|
||||
if (pixelcount >= bitmap.viewport.w) return;
|
||||
/* sprite limit (256 or 320 pixels) */
|
||||
if (pixelcount >= bitmap.viewport.w) return;
|
||||
|
||||
}
|
||||
}
|
||||
@ -1741,20 +1741,20 @@ static void render_obj_im2(uint32 line, uint32 odd, uint8 *buf, uint8 *table)
|
||||
|
||||
int attr_mask, nt_row;
|
||||
|
||||
for(count = 0; count < object_index_count; count += 1)
|
||||
for(count = 0; count < object_index_count; count += 1)
|
||||
{
|
||||
xpos = object_info[count].xpos & 0x1ff;
|
||||
|
||||
/* sprite masking */
|
||||
if(xpos != 0) sol_flag = 1;
|
||||
else if(xpos == 0 && sol_flag) return;
|
||||
/* sprite masking */
|
||||
if(xpos != 0) sol_flag = 1;
|
||||
else if(xpos == 0 && sol_flag) return;
|
||||
|
||||
size = object_info[count].size & 0x0f;
|
||||
width = sizetab[(size >> 2) & 3];
|
||||
|
||||
/* update pixel count (off-screen sprites included) */
|
||||
pixelcount += width;
|
||||
|
||||
/* update pixel count (off-screen sprites included) */
|
||||
pixelcount += width;
|
||||
|
||||
if(((xpos + width) >= left) && (xpos < right))
|
||||
{
|
||||
ypos = object_info[count].ypos;
|
||||
@ -1773,10 +1773,10 @@ static void render_obj_im2(uint32 line, uint32 odd, uint8 *buf, uint8 *table)
|
||||
|
||||
lb = (uint8 *)&buf[0x20 + (xpos - 0x80)];
|
||||
|
||||
/* number of tiles to draw */
|
||||
/* adjusted for sprite limit */
|
||||
/* number of tiles to draw */
|
||||
/* adjusted for sprite limit */
|
||||
if (pixelcount > bitmap.viewport.w) width -= (pixelcount - bitmap.viewport.w);
|
||||
width >>= 3;
|
||||
width >>= 3;
|
||||
|
||||
for(column = 0; column < width; column += 1, lb+=8)
|
||||
{
|
||||
@ -1788,8 +1788,8 @@ static void render_obj_im2(uint32 line, uint32 odd, uint8 *buf, uint8 *table)
|
||||
}
|
||||
}
|
||||
|
||||
/* sprite limit (256 or 320 pixels) */
|
||||
if (pixelcount >= bitmap.viewport.w) return;
|
||||
/* sprite limit (256 or 320 pixels) */
|
||||
if (pixelcount >= bitmap.viewport.w) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
252
source/state.c
252
source/state.c
@ -27,163 +27,163 @@ static unsigned int bufferptr;
|
||||
|
||||
static inline void load_param(void *param, unsigned int size)
|
||||
{
|
||||
memcpy(param, &state[bufferptr], size);
|
||||
bufferptr+= size;
|
||||
memcpy(param, &state[bufferptr], size);
|
||||
bufferptr+= size;
|
||||
}
|
||||
|
||||
static inline void save_param(void *param, unsigned int size)
|
||||
{
|
||||
memcpy(&state[bufferptr], param, size);
|
||||
bufferptr+= size;
|
||||
memcpy(&state[bufferptr], param, size);
|
||||
bufferptr+= size;
|
||||
}
|
||||
|
||||
void state_load(unsigned char *buffer)
|
||||
{
|
||||
/* reset buffer pointer */
|
||||
bufferptr = 0;
|
||||
/* reset buffer pointer */
|
||||
bufferptr = 0;
|
||||
|
||||
/* uncompress savestate */
|
||||
unsigned long inbytes, outbytes;
|
||||
memcpy(&inbytes, buffer, 4);
|
||||
outbytes = 0x24000;
|
||||
memcpy(&inbytes, buffer, 4);
|
||||
outbytes = 0x24000;
|
||||
uncompress ((Bytef *)state, &outbytes, (Bytef *)(buffer + 4), inbytes);
|
||||
|
||||
/* reset system */
|
||||
system_reset();
|
||||
m68k_memory_map[0].base = default_rom;
|
||||
/* reset system */
|
||||
system_reset();
|
||||
m68k_memory_map[0].base = default_rom;
|
||||
|
||||
// GENESIS
|
||||
load_param(work_ram, sizeof(work_ram));
|
||||
load_param(zram, sizeof(zram));
|
||||
load_param(&zbusreq, sizeof(zbusreq));
|
||||
load_param(&zreset, sizeof(zreset));
|
||||
load_param(&zbank, sizeof(zbank));
|
||||
zbusack = 1 ^(zbusreq & zreset);
|
||||
// GENESIS
|
||||
load_param(work_ram, sizeof(work_ram));
|
||||
load_param(zram, sizeof(zram));
|
||||
load_param(&zbusreq, sizeof(zbusreq));
|
||||
load_param(&zreset, sizeof(zreset));
|
||||
load_param(&zbank, sizeof(zbank));
|
||||
zbusack = 1 ^(zbusreq & zreset);
|
||||
|
||||
// IO
|
||||
load_param(io_reg, sizeof(io_reg));
|
||||
|
||||
// VDP
|
||||
uint8 temp_reg[0x20];
|
||||
load_param(sat, sizeof(sat));
|
||||
load_param(vram, sizeof(vram));
|
||||
load_param(cram, sizeof(cram));
|
||||
load_param(vsram, sizeof(vsram));
|
||||
load_param(temp_reg, sizeof(temp_reg));
|
||||
load_param(&addr, sizeof(addr));
|
||||
load_param(&addr_latch, sizeof(addr_latch));
|
||||
load_param(&code, sizeof(code));
|
||||
load_param(&pending, sizeof(pending));
|
||||
load_param(&status, sizeof(status));
|
||||
load_param(&dmafill, sizeof(dmafill));
|
||||
load_param(&hint_pending, sizeof(hint_pending));
|
||||
load_param(&vint_pending, sizeof(vint_pending));
|
||||
load_param(&irq_status, sizeof(irq_status));
|
||||
vdp_restore(temp_reg);
|
||||
// IO
|
||||
load_param(io_reg, sizeof(io_reg));
|
||||
|
||||
// FM
|
||||
load_param(fm_reg,sizeof(fm_reg));
|
||||
fm_restore();
|
||||
// VDP
|
||||
uint8 temp_reg[0x20];
|
||||
load_param(sat, sizeof(sat));
|
||||
load_param(vram, sizeof(vram));
|
||||
load_param(cram, sizeof(cram));
|
||||
load_param(vsram, sizeof(vsram));
|
||||
load_param(temp_reg, sizeof(temp_reg));
|
||||
load_param(&addr, sizeof(addr));
|
||||
load_param(&addr_latch, sizeof(addr_latch));
|
||||
load_param(&code, sizeof(code));
|
||||
load_param(&pending, sizeof(pending));
|
||||
load_param(&status, sizeof(status));
|
||||
load_param(&dmafill, sizeof(dmafill));
|
||||
load_param(&hint_pending, sizeof(hint_pending));
|
||||
load_param(&vint_pending, sizeof(vint_pending));
|
||||
load_param(&irq_status, sizeof(irq_status));
|
||||
vdp_restore(temp_reg);
|
||||
|
||||
// PSG
|
||||
load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
|
||||
// FM
|
||||
load_param(fm_reg,sizeof(fm_reg));
|
||||
fm_restore();
|
||||
|
||||
// 68000
|
||||
uint16 tmp16;
|
||||
uint32 tmp32;
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32);
|
||||
load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32);
|
||||
// PSG
|
||||
load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
|
||||
|
||||
// Z80
|
||||
load_param(&Z80, sizeof(Z80_Regs));
|
||||
// 68000
|
||||
uint16 tmp16;
|
||||
uint32 tmp32;
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D0, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D1, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D2, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D3, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D4, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D5, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D6, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_D7, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A0, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A1, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A2, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A3, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A4, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A5, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A6, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_A7, tmp32);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_PC, tmp32);
|
||||
load_param(&tmp16, 2); m68k_set_reg(M68K_REG_SR, tmp16);
|
||||
load_param(&tmp32, 4); m68k_set_reg(M68K_REG_USP,tmp32);
|
||||
|
||||
// Z80
|
||||
load_param(&Z80, sizeof(Z80_Regs));
|
||||
}
|
||||
|
||||
int state_save(unsigned char *buffer)
|
||||
{
|
||||
/* reset buffer pointer */
|
||||
bufferptr = 0;
|
||||
/* reset buffer pointer */
|
||||
bufferptr = 0;
|
||||
|
||||
// GENESIS
|
||||
save_param(work_ram, sizeof(work_ram));
|
||||
save_param(zram, sizeof(zram));
|
||||
save_param(&zbusreq, sizeof(zbusreq));
|
||||
save_param(&zreset, sizeof(zreset));
|
||||
save_param(&zbank, sizeof(zbank));
|
||||
// GENESIS
|
||||
save_param(work_ram, sizeof(work_ram));
|
||||
save_param(zram, sizeof(zram));
|
||||
save_param(&zbusreq, sizeof(zbusreq));
|
||||
save_param(&zreset, sizeof(zreset));
|
||||
save_param(&zbank, sizeof(zbank));
|
||||
|
||||
// IO
|
||||
save_param(io_reg, sizeof(io_reg));
|
||||
|
||||
// VDP
|
||||
save_param(sat, sizeof(sat));
|
||||
save_param(vram, sizeof(vram));
|
||||
save_param(cram, sizeof(cram));
|
||||
save_param(vsram, sizeof(vsram));
|
||||
save_param(reg, sizeof(reg));
|
||||
save_param(&addr, sizeof(addr));
|
||||
save_param(&addr_latch, sizeof(addr_latch));
|
||||
save_param(&code, sizeof(code));
|
||||
save_param(&pending, sizeof(pending));
|
||||
save_param(&status, sizeof(status));
|
||||
save_param(&dmafill, sizeof(dmafill));
|
||||
save_param(&hint_pending, sizeof(hint_pending));
|
||||
save_param(&vint_pending, sizeof(vint_pending));
|
||||
save_param(&irq_status, sizeof(irq_status));
|
||||
// IO
|
||||
save_param(io_reg, sizeof(io_reg));
|
||||
|
||||
// FM
|
||||
save_param(fm_reg,sizeof(fm_reg));
|
||||
// VDP
|
||||
save_param(sat, sizeof(sat));
|
||||
save_param(vram, sizeof(vram));
|
||||
save_param(cram, sizeof(cram));
|
||||
save_param(vsram, sizeof(vsram));
|
||||
save_param(reg, sizeof(reg));
|
||||
save_param(&addr, sizeof(addr));
|
||||
save_param(&addr_latch, sizeof(addr_latch));
|
||||
save_param(&code, sizeof(code));
|
||||
save_param(&pending, sizeof(pending));
|
||||
save_param(&status, sizeof(status));
|
||||
save_param(&dmafill, sizeof(dmafill));
|
||||
save_param(&hint_pending, sizeof(hint_pending));
|
||||
save_param(&vint_pending, sizeof(vint_pending));
|
||||
save_param(&irq_status, sizeof(irq_status));
|
||||
|
||||
// PSG
|
||||
save_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
|
||||
// FM
|
||||
save_param(fm_reg,sizeof(fm_reg));
|
||||
|
||||
// 68000
|
||||
uint16 tmp16;
|
||||
uint32 tmp32;
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D5); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D6); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D7); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A0); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A1); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A2); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A3); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A4); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A5); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A6); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4);
|
||||
tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
|
||||
// PSG
|
||||
save_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());
|
||||
|
||||
// Z80
|
||||
save_param(&Z80, sizeof(Z80_Regs));
|
||||
// 68000
|
||||
uint16 tmp16;
|
||||
uint32 tmp32;
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D0); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D1); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D2); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D3); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D4); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D5); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D6); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_D7); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A0); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A1); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A2); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A3); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A4); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A5); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A6); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_A7); save_param(&tmp32, 4);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_PC); save_param(&tmp32, 4);
|
||||
tmp16 = m68k_get_reg(NULL, M68K_REG_SR); save_param(&tmp16, 2);
|
||||
tmp32 = m68k_get_reg(NULL, M68K_REG_USP); save_param(&tmp32, 4);
|
||||
|
||||
/* compress state file */
|
||||
unsigned long inbytes = bufferptr;
|
||||
// Z80
|
||||
save_param(&Z80, sizeof(Z80_Regs));
|
||||
|
||||
/* compress state file */
|
||||
unsigned long inbytes = bufferptr;
|
||||
unsigned long outbytes = 0x26000;
|
||||
compress2 ((Bytef *)(buffer + 4), &outbytes, (Bytef *)state, inbytes, 9);
|
||||
memcpy(buffer, &outbytes, 4);
|
||||
memcpy(buffer, &outbytes, 4);
|
||||
|
||||
/* return total size */
|
||||
return (outbytes + 4);
|
||||
/* return total size */
|
||||
return (outbytes + 4);
|
||||
}
|
||||
|
288
source/system.c
288
source/system.c
@ -49,13 +49,13 @@ static inline void audio_update (void);
|
||||
****************************************************************/
|
||||
void system_init (void)
|
||||
{
|
||||
/* PAL/NTSC timings */
|
||||
vdp_rate = vdp_pal ? 50 : 60;
|
||||
lines_per_frame = vdp_pal ? 313 : 262;
|
||||
|
||||
gen_init ();
|
||||
vdp_init ();
|
||||
render_init ();
|
||||
/* PAL/NTSC timings */
|
||||
vdp_rate = vdp_pal ? 50 : 60;
|
||||
lines_per_frame = vdp_pal ? 313 : 262;
|
||||
|
||||
gen_init ();
|
||||
vdp_init ();
|
||||
render_init ();
|
||||
cart_hw_init();
|
||||
}
|
||||
|
||||
@ -64,30 +64,30 @@ void system_init (void)
|
||||
****************************************************************/
|
||||
void system_reset (void)
|
||||
{
|
||||
aim_m68k = 0;
|
||||
count_m68k = 0;
|
||||
line_m68k = 0;
|
||||
aim_z80 = 0;
|
||||
count_z80 = 0;
|
||||
line_z80 = 0;
|
||||
current_z80 = 0;
|
||||
odd_frame = 0;
|
||||
interlaced = 0;
|
||||
aim_m68k = 0;
|
||||
count_m68k = 0;
|
||||
line_m68k = 0;
|
||||
aim_z80 = 0;
|
||||
count_z80 = 0;
|
||||
line_z80 = 0;
|
||||
current_z80 = 0;
|
||||
odd_frame = 0;
|
||||
interlaced = 0;
|
||||
|
||||
/* Cart Hardware reset */
|
||||
cart_hw_reset();
|
||||
/* Cart Hardware reset */
|
||||
cart_hw_reset();
|
||||
|
||||
/* Hard reset */
|
||||
gen_reset (1);
|
||||
vdp_reset ();
|
||||
render_reset ();
|
||||
io_reset();
|
||||
SN76489_Reset(0);
|
||||
/* Hard reset */
|
||||
gen_reset (1);
|
||||
vdp_reset ();
|
||||
render_reset ();
|
||||
io_reset();
|
||||
SN76489_Reset(0);
|
||||
|
||||
/* Sound buffers reset */
|
||||
memset (snd.psg.buffer, 0, SND_SIZE);
|
||||
memset (snd.fm.buffer[0], 0, SND_SIZE*2);
|
||||
memset (snd.fm.buffer[1], 0, SND_SIZE*2);
|
||||
/* Sound buffers reset */
|
||||
memset (snd.psg.buffer, 0, SND_SIZE);
|
||||
memset (snd.fm.buffer[0], 0, SND_SIZE*2);
|
||||
memset (snd.fm.buffer[1], 0, SND_SIZE*2);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
@ -95,9 +95,9 @@ void system_reset (void)
|
||||
****************************************************************/
|
||||
void system_shutdown (void)
|
||||
{
|
||||
gen_shutdown ();
|
||||
vdp_shutdown ();
|
||||
render_shutdown ();
|
||||
gen_shutdown ();
|
||||
vdp_shutdown ();
|
||||
render_shutdown ();
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
@ -105,19 +105,19 @@ void system_shutdown (void)
|
||||
****************************************************************/
|
||||
int system_frame (int do_skip)
|
||||
{
|
||||
if (!gen_running)
|
||||
if (!gen_running)
|
||||
{
|
||||
update_input();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reset cycles counts */
|
||||
count_m68k = 0;
|
||||
aim_m68k = 0;
|
||||
aim_z80 = 0;
|
||||
count_z80 = 0;
|
||||
fifo_write_cnt = 0;
|
||||
fifo_lastwrite = 0;
|
||||
}
|
||||
|
||||
/* reset cycles counts */
|
||||
count_m68k = 0;
|
||||
aim_m68k = 0;
|
||||
aim_z80 = 0;
|
||||
count_z80 = 0;
|
||||
fifo_write_cnt = 0;
|
||||
fifo_lastwrite = 0;
|
||||
|
||||
/* update display settings */
|
||||
int line;
|
||||
@ -125,48 +125,48 @@ int system_frame (int do_skip)
|
||||
int vdp_height = bitmap.viewport.h;
|
||||
int end_line = vdp_height + bitmap.viewport.y;
|
||||
int start_line = lines_per_frame - bitmap.viewport.y;
|
||||
int old_interlaced = interlaced;
|
||||
int old_interlaced = interlaced;
|
||||
interlaced = (reg[12] & 2) >> 1;
|
||||
if (old_interlaced != interlaced)
|
||||
if (old_interlaced != interlaced)
|
||||
{
|
||||
bitmap.viewport.changed = 2;
|
||||
bitmap.viewport.changed = 2;
|
||||
im2_flag = ((reg[12] & 6) == 6);
|
||||
odd_frame = 1;
|
||||
}
|
||||
odd_frame = 1;
|
||||
}
|
||||
|
||||
odd_frame ^= 1;
|
||||
|
||||
/* clear VBLANK and DMA flags */
|
||||
status &= 0xFFF5;
|
||||
|
||||
|
||||
/* even/odd field flag (interlaced modes only) */
|
||||
if (odd_frame && interlaced) status |= 0x0010;
|
||||
else status &= 0xFFEF;
|
||||
|
||||
/* reload HCounter */
|
||||
int h_counter = reg[10];
|
||||
/* reload HCounter */
|
||||
int h_counter = reg[10];
|
||||
|
||||
/* parse sprites for line 0 (done on last line) */
|
||||
parse_satb (0x80);
|
||||
parse_satb (0x80);
|
||||
|
||||
/* process frame */
|
||||
for (line = 0; line < lines_per_frame; line ++)
|
||||
{
|
||||
/* process frame */
|
||||
for (line = 0; line < lines_per_frame; line ++)
|
||||
{
|
||||
/* update VCounter */
|
||||
v_counter = line;
|
||||
v_counter = line;
|
||||
|
||||
/* update 6-Buttons or Menacer */
|
||||
input_update();
|
||||
/* update 6-Buttons or Menacer */
|
||||
input_update();
|
||||
|
||||
/* update CPU cycle counters */
|
||||
/* update CPU cycle counters */
|
||||
hint_m68k = count_m68k;
|
||||
line_m68k = aim_m68k;
|
||||
line_z80 = aim_z80;
|
||||
line_z80 = aim_z80;
|
||||
aim_z80 += z80cycles_per_line;
|
||||
aim_m68k += m68cycles_per_line;
|
||||
|
||||
/* Soft Reset ? */
|
||||
if (line == reset)
|
||||
/* Soft Reset ? */
|
||||
if (line == reset)
|
||||
{
|
||||
#ifdef NGC
|
||||
/* wait for RESET button to be released */
|
||||
@ -177,14 +177,14 @@ int system_frame (int do_skip)
|
||||
|
||||
/* active display */
|
||||
if (line <= vdp_height)
|
||||
{
|
||||
/* H Interrupt */
|
||||
{
|
||||
/* H Interrupt */
|
||||
if(--h_counter < 0)
|
||||
{
|
||||
h_counter = reg[10];
|
||||
hint_pending = 1;
|
||||
{
|
||||
h_counter = reg[10];
|
||||
hint_pending = 1;
|
||||
if (reg[0] & 0x10) irq_status = (irq_status & 0xff) | 0x14;
|
||||
|
||||
|
||||
/* adjust timings to take further decrement in account (see below) */
|
||||
if ((line != 0) || (h_counter == 0)) aim_m68k += 36;
|
||||
}
|
||||
@ -198,9 +198,9 @@ int system_frame (int do_skip)
|
||||
/* update DMA timings */
|
||||
if (dma_length) dma_update();
|
||||
|
||||
/* vertical retrace */
|
||||
/* vertical retrace */
|
||||
if (line == vdp_height)
|
||||
{
|
||||
{
|
||||
/* render overscan */
|
||||
if ((line < end_line) && (!do_skip)) render_line(line, 1);
|
||||
|
||||
@ -211,9 +211,9 @@ int system_frame (int do_skip)
|
||||
status |= 0x08;
|
||||
|
||||
/* Z80 interrupt is 16ms period (one frame) and 64us length (one scanline) */
|
||||
zirq = 1;
|
||||
z80_set_irq_line(0, ASSERT_LINE);
|
||||
|
||||
zirq = 1;
|
||||
z80_set_irq_line(0, ASSERT_LINE);
|
||||
|
||||
/* delay between HINT, VBLANK and VINT (Dracula, OutRunners, VR Troopers) */
|
||||
m68k_run(line_m68k + 84);
|
||||
if (zreset && !zbusreq)
|
||||
@ -223,7 +223,7 @@ int system_frame (int do_skip)
|
||||
}
|
||||
else count_z80 = line_z80 + 39;
|
||||
|
||||
/* V Interrupt */
|
||||
/* V Interrupt */
|
||||
status |= 0x80;
|
||||
vint_pending = 1;
|
||||
|
||||
@ -235,7 +235,7 @@ int system_frame (int do_skip)
|
||||
/* render scanline and parse sprites for line n+1 */
|
||||
render_line(line, 0);
|
||||
if (line < (vdp_height-1)) parse_satb(0x81 + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -253,57 +253,57 @@ int system_frame (int do_skip)
|
||||
}
|
||||
}
|
||||
|
||||
/* process line */
|
||||
m68k_run(aim_m68k);
|
||||
if (zreset == 1 && zbusreq == 0)
|
||||
/* process line */
|
||||
m68k_run(aim_m68k);
|
||||
if (zreset == 1 && zbusreq == 0)
|
||||
{
|
||||
current_z80 = aim_z80 - count_z80;
|
||||
if (current_z80 > 0) count_z80 += z80_execute(current_z80);
|
||||
}
|
||||
else count_z80 = aim_z80;
|
||||
|
||||
/* SVP chip */
|
||||
if (svp) ssp1601_run(SVP_cycles);
|
||||
}
|
||||
}
|
||||
else count_z80 = aim_z80;
|
||||
|
||||
/* SVP chip */
|
||||
if (svp) ssp1601_run(SVP_cycles);
|
||||
}
|
||||
|
||||
audio_update ();
|
||||
|
||||
return gen_running;
|
||||
audio_update ();
|
||||
|
||||
return gen_running;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Audio System
|
||||
* Audio System
|
||||
****************************************************************/
|
||||
int audio_init (int rate)
|
||||
{
|
||||
/* Shutdown first */
|
||||
/* Shutdown first */
|
||||
audio_shutdown();
|
||||
|
||||
/* Clear the sound data context */
|
||||
memset (&snd, 0, sizeof (snd));
|
||||
/* Clear the sound data context */
|
||||
memset (&snd, 0, sizeof (snd));
|
||||
|
||||
/* Make sure the requested sample rate is valid */
|
||||
if (!rate || ((rate < 8000) | (rate > 48000))) return (-1);
|
||||
snd.sample_rate = rate;
|
||||
|
||||
/* Calculate the sound buffer size (for one frame) */
|
||||
snd.buffer_size = (rate / vdp_rate);
|
||||
/* Make sure the requested sample rate is valid */
|
||||
if (!rate || ((rate < 8000) | (rate > 48000))) return (-1);
|
||||
snd.sample_rate = rate;
|
||||
|
||||
/* Calculate the sound buffer size (for one frame) */
|
||||
snd.buffer_size = (rate / vdp_rate);
|
||||
|
||||
#ifdef DOS
|
||||
/* output buffers */
|
||||
snd.buffer[0] = (int16 *) malloc(SND_SIZE);
|
||||
snd.buffer[1] = (int16 *) malloc(SND_SIZE);
|
||||
if (!snd.buffer[0] || !snd.buffer[1]) return (-1);
|
||||
memset (snd.buffer[0], 0, SND_SIZE);
|
||||
memset (snd.buffer[1], 0, SND_SIZE);
|
||||
snd.buffer[1] = (int16 *) malloc(SND_SIZE);
|
||||
if (!snd.buffer[0] || !snd.buffer[1]) return (-1);
|
||||
memset (snd.buffer[0], 0, SND_SIZE);
|
||||
memset (snd.buffer[1], 0, SND_SIZE);
|
||||
#endif
|
||||
|
||||
/* YM2612 stream buffers */
|
||||
snd.fm.buffer[0] = (int *)malloc (SND_SIZE*2);
|
||||
snd.fm.buffer[1] = (int *)malloc (SND_SIZE*2);
|
||||
if (!snd.fm.buffer[0] || !snd.fm.buffer[1]) return (-1);
|
||||
memset (snd.fm.buffer[0], 0, SND_SIZE*2);
|
||||
memset (snd.fm.buffer[1], 0, SND_SIZE*2);
|
||||
snd.fm.buffer[1] = (int *)malloc (SND_SIZE*2);
|
||||
if (!snd.fm.buffer[0] || !snd.fm.buffer[1]) return (-1);
|
||||
memset (snd.fm.buffer[0], 0, SND_SIZE*2);
|
||||
memset (snd.fm.buffer[1], 0, SND_SIZE*2);
|
||||
|
||||
/* SRC buffers */
|
||||
if (config.hq_fm && !config.fm_core)
|
||||
@ -312,23 +312,23 @@ int audio_init (int rate)
|
||||
if (!snd.fm.src_out) return (-1);
|
||||
}
|
||||
|
||||
/* SN76489 stream buffers */
|
||||
/* SN76489 stream buffers */
|
||||
snd.psg.buffer = (int16 *)malloc (SND_SIZE);
|
||||
if (!snd.psg.buffer) return (-1);
|
||||
memset (snd.psg.buffer, 0, SND_SIZE);
|
||||
if (!snd.psg.buffer) return (-1);
|
||||
memset (snd.psg.buffer, 0, SND_SIZE);
|
||||
|
||||
/* Set audio enable flag */
|
||||
snd.enabled = 1;
|
||||
/* Set audio enable flag */
|
||||
snd.enabled = 1;
|
||||
|
||||
/* Initialize Sound Chips emulation */
|
||||
sound_init(rate);
|
||||
/* Initialize Sound Chips emulation */
|
||||
sound_init(rate);
|
||||
|
||||
return (0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void audio_shutdown(void)
|
||||
{
|
||||
/* free sound buffers */
|
||||
/* free sound buffers */
|
||||
if (snd.buffer[0]) free(snd.buffer[0]);
|
||||
if (snd.buffer[1]) free(snd.buffer[1]);
|
||||
if (snd.fm.buffer[0]) free(snd.fm.buffer[0]);
|
||||
@ -341,7 +341,7 @@ static int ll, rr;
|
||||
|
||||
static inline void audio_update (void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
int l, r;
|
||||
double psg_preamp = config.psg_preamp;
|
||||
double fm_preamp = config.fm_preamp;
|
||||
@ -349,56 +349,56 @@ static inline void audio_update (void)
|
||||
int filter = config.filter;
|
||||
|
||||
#ifndef DOS
|
||||
int16 *sb = (int16 *) soundbuffer[mixbuffer];
|
||||
int16 *sb = (int16 *) soundbuffer[mixbuffer];
|
||||
#endif
|
||||
|
||||
/* get remaining samples */
|
||||
sound_update();
|
||||
/* get remaining samples */
|
||||
sound_update();
|
||||
|
||||
/* mix samples */
|
||||
for (i = 0; i < snd.buffer_size; i ++)
|
||||
{
|
||||
l = r = (int) ((double)snd.psg.buffer[i] * psg_preamp);
|
||||
l += (int) ((double)snd.fm.buffer[0][i] * fm_preamp);
|
||||
r += (int) ((double)snd.fm.buffer[1][i] * fm_preamp);
|
||||
snd.fm.buffer[0][i] = 0;
|
||||
snd.fm.buffer[1][i] = 0;
|
||||
snd.psg.buffer[i] = 0;
|
||||
/* mix samples */
|
||||
for (i = 0; i < snd.buffer_size; i ++)
|
||||
{
|
||||
l = r = (int) ((double)snd.psg.buffer[i] * psg_preamp);
|
||||
l += (int) ((double)snd.fm.buffer[0][i] * fm_preamp);
|
||||
r += (int) ((double)snd.fm.buffer[1][i] * fm_preamp);
|
||||
snd.fm.buffer[0][i] = 0;
|
||||
snd.fm.buffer[1][i] = 0;
|
||||
snd.psg.buffer[i] = 0;
|
||||
|
||||
/* single-pole low-pass filter (6 dB/octave) */
|
||||
if (filter)
|
||||
{
|
||||
if (filter)
|
||||
{
|
||||
l = (ll + l) >> 1;
|
||||
r = (rr + r) >> 1;
|
||||
r = (rr + r) >> 1;
|
||||
ll = l;
|
||||
rr = r;
|
||||
}
|
||||
|
||||
/* boost volume if asked*/
|
||||
l = l * boost;
|
||||
r = r * boost;
|
||||
l = l * boost;
|
||||
r = r * boost;
|
||||
|
||||
/* clipping */
|
||||
if (l > 32767) l = 32767;
|
||||
else if (l < -32768) l = -32768;
|
||||
if (r > 32767) r = 32767;
|
||||
else if (r < -32768) r = -32768;
|
||||
/* clipping */
|
||||
if (l > 32767) l = 32767;
|
||||
else if (l < -32768) l = -32768;
|
||||
if (r > 32767) r = 32767;
|
||||
else if (r < -32768) r = -32768;
|
||||
|
||||
/* update sound buffer */
|
||||
/* update sound buffer */
|
||||
#ifdef DOS
|
||||
snd.buffer[0][i] = l;
|
||||
snd.buffer[1][i] = r;
|
||||
snd.buffer[0][i] = l;
|
||||
snd.buffer[1][i] = r;
|
||||
#elif LSB_FIRST
|
||||
*sb++ = l;
|
||||
*sb++ = r;
|
||||
*sb++ = l;
|
||||
*sb++ = r;
|
||||
#else
|
||||
*sb++ = r;
|
||||
*sb++ = l;
|
||||
*sb++ = l;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DOS
|
||||
mixbuffer++;
|
||||
mixbuffer &= 0xf;
|
||||
mixbuffer++;
|
||||
mixbuffer &= 0xf;
|
||||
#endif
|
||||
}
|
||||
|
@ -35,38 +35,38 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 *data; /* Bitmap data */
|
||||
int width; /* Bitmap width (32+512+32) */
|
||||
int height; /* Bitmap height (256) */
|
||||
int depth; /* Color depth (8 bits) */
|
||||
int pitch; /* Width of bitmap in bytes */
|
||||
int granularity; /* Size of each pixel in bytes */
|
||||
int remap; /* 1= Translate pixel data */
|
||||
uint8 *data; /* Bitmap data */
|
||||
int width; /* Bitmap width (32+512+32) */
|
||||
int height; /* Bitmap height (256) */
|
||||
int depth; /* Color depth (8 bits) */
|
||||
int pitch; /* Width of bitmap in bytes */
|
||||
int granularity; /* Size of each pixel in bytes */
|
||||
int remap; /* 1= Translate pixel data */
|
||||
struct
|
||||
{
|
||||
int x; /* X offset of viewport within bitmap */
|
||||
int y; /* Y offset of viewport within bitmap */
|
||||
int w; /* Width of viewport */
|
||||
int h; /* Height of viewport */
|
||||
int ow; /* Previous width of viewport */
|
||||
int oh; /* Previous height of viewport */
|
||||
int changed; /* 1= Viewport width or height have changed */
|
||||
int x; /* X offset of viewport within bitmap */
|
||||
int y; /* Y offset of viewport within bitmap */
|
||||
int w; /* Width of viewport */
|
||||
int h; /* Height of viewport */
|
||||
int ow; /* Previous width of viewport */
|
||||
int oh; /* Previous height of viewport */
|
||||
int changed; /* 1= Viewport width or height have changed */
|
||||
} viewport;
|
||||
} t_bitmap;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int sample_rate; /* Sample rate (8000-48000) */
|
||||
int enabled; /* 1= sound emulation is enabled */
|
||||
int buffer_size; /* Size of sound buffer (in bytes) */
|
||||
int16 *buffer[2]; /* Signed 16-bit stereo sound data */
|
||||
int sample_rate; /* Sample rate (8000-48000) */
|
||||
int enabled; /* 1= sound emulation is enabled */
|
||||
int buffer_size; /* Size of sound buffer (in bytes) */
|
||||
int16 *buffer[2]; /* Signed 16-bit stereo sound data */
|
||||
struct
|
||||
{
|
||||
int curStage;
|
||||
int lastStage;
|
||||
int *buffer[2];
|
||||
float *src_out; /* SRC conversion buffer */
|
||||
float *src_out; /* SRC conversion buffer */
|
||||
} fm;
|
||||
struct
|
||||
{
|
||||
|
1380
source/unzip.c
1380
source/unzip.c
File diff suppressed because it is too large
Load Diff
766
source/vdp.c
766
source/vdp.c
File diff suppressed because it is too large
Load Diff
30
source/vdp.h
30
source/vdp.h
@ -27,8 +27,8 @@
|
||||
/* VDP context */
|
||||
extern uint8 sat[0x400];
|
||||
extern uint8 vram[0x10000];
|
||||
extern uint8 cram[0x80];
|
||||
extern uint8 vsram[0x80];
|
||||
extern uint8 cram[0x80];
|
||||
extern uint8 vsram[0x80];
|
||||
extern uint8 reg[0x20];
|
||||
extern uint16 addr;
|
||||
extern uint16 addr_latch;
|
||||
@ -41,20 +41,20 @@ extern uint8 vint_pending;
|
||||
extern uint16 irq_status;
|
||||
|
||||
/* Global variables */
|
||||
extern uint16 ntab;
|
||||
extern uint16 ntbb;
|
||||
extern uint16 ntwb;
|
||||
extern uint16 satb;
|
||||
extern uint16 hscb;
|
||||
extern uint8 border;
|
||||
extern uint8 bg_name_dirty[0x800];
|
||||
extern uint16 bg_name_list[0x800];
|
||||
extern uint16 bg_list_index;
|
||||
extern uint16 ntab;
|
||||
extern uint16 ntbb;
|
||||
extern uint16 ntwb;
|
||||
extern uint16 satb;
|
||||
extern uint16 hscb;
|
||||
extern uint8 border;
|
||||
extern uint8 bg_name_dirty[0x800];
|
||||
extern uint16 bg_name_list[0x800];
|
||||
extern uint16 bg_list_index;
|
||||
extern uint8 bg_pattern_cache[0x80000];
|
||||
extern uint8 playfield_shift;
|
||||
extern uint8 playfield_col_mask;
|
||||
extern uint16 playfield_row_mask;
|
||||
extern uint32 y_mask;
|
||||
extern uint8 playfield_shift;
|
||||
extern uint8 playfield_col_mask;
|
||||
extern uint16 playfield_row_mask;
|
||||
extern uint32 y_mask;
|
||||
extern uint16 hc_latch;
|
||||
extern uint16 v_counter;
|
||||
extern uint8 im2_flag;
|
||||
|
Loading…
Reference in New Issue
Block a user