1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "snes9x.h"
#include "memmap.h"
#include "seta.h"
static int line; // line counter
uint8 S9xGetST018 (uint32 Address)
{
uint8 t = 0;
uint16 address = (uint16) Address & 0xFFFF;
line++;
// these roles may be flipped
// op output
if (address == 0x3804)
{
if (ST018.out_count)
{
t = (uint8) ST018.output[ST018.out_index];
ST018.out_index++;
if (ST018.out_count == ST018.out_index)
ST018.out_count = 0;
}
else
t = 0x81;
}
// status register
else
if (address == 0x3800)
t = ST018.status;
#ifdef DEBUGGER
printf("ST018 R: %06X %02X\n", Address, t);
#endif
return (t);
}
void S9xSetST018 (uint8 Byte, uint32 Address)
{
static bool reset = false;
uint16 address = (uint16) Address & 0xFFFF;
#ifdef DEBUGGER
printf("ST018 W: %06X %02X\n", Address, Byte);
#endif
line++;
if (!reset)
{
// bootup values
ST018.waiting4command = true;
ST018.part_command = 0;
reset = true;
}
Memory.SRAM[address] = Byte;
// default status for now
ST018.status = 0x00;
// op data goes through this address
if (address == 0x3804)
{
// check for new commands: 3 bytes length
if (ST018.waiting4command && ST018.part_command == 2)
{
ST018.waiting4command = false;
ST018.in_index = 0;
ST018.out_index = 0;
ST018.part_command = 0; // 3-byte commands
ST018.pass = 0; // data streams into the chip
ST018.command <<= 8;
ST018.command |= Byte;
switch (ST018.command & 0xFFFFFF)
{
case 0x0100: ST018.in_count = 0; break;
case 0xFF00: ST018.in_count = 0; break;
default: ST018.waiting4command = true; break;
}
}
else
if (ST018.waiting4command)
{
// 3-byte commands
ST018.part_command++;
ST018.command <<= 8;
ST018.command |= Byte;
}
}
// extra parameters
else
if (address == 0x3802)
{
ST018.parameters[ST018.in_index] = Byte;
ST018.in_index++;
}
if (ST018.in_count == ST018.in_index)
{
// qctually execute the command
ST018.waiting4command = true;
ST018.in_index = 0;
ST018.out_index = 0;
switch (ST018.command)
{
// hardware check?
case 0x0100:
ST018.waiting4command = false;
ST018.pass++;
if (ST018.pass == 1)
{
ST018.in_count = 1;
ST018.out_count = 2;
// Overload's research
ST018.output[0x00] = 0x81;
ST018.output[0x01] = 0x81;
}
else
{
//ST018.in_count = 1;
ST018.out_count = 3;
// no reason to change this
//ST018.output[0x00] = 0x81;
//ST018.output[0x01] = 0x81;
ST018.output[0x02] = 0x81;
// done processing requests
if (ST018.pass == 3)
ST018.waiting4command = true;
}
break;
// unknown: feels like a security detection
// format identical to 0x0100
case 0xFF00:
ST018.waiting4command = false;
ST018.pass++;
if (ST018.pass == 1)
{
ST018.in_count = 1;
ST018.out_count = 2;
// Overload's research
ST018.output[0x00] = 0x81;
ST018.output[0x01] = 0x81;
}
else
{
//ST018.in_count = 1;
ST018.out_count = 3;
// no reason to change this
//ST018.output[0x00] = 0x81;
//ST018.output[0x01] = 0x81;
ST018.output[0x02] = 0x81;
// done processing requests
if (ST018.pass == 3)
ST018.waiting4command = true;
}
break;
}
}
}
|