1 /*****************************************************************************
2 ** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Memory/romMapperRsIDE.c,v $
3 **
4 ** $Revision: 1.0 $
5 **
6 ** $Date: 2008-03-31 19:42:22 $
7 **
8 ** More info: http://www.bluemsx.com
9 **
10 ** Copyright (C) 2003-2006 Daniel Vik, Tomas Karlsson
11 **
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License as published by
14 ** the Free Software Foundation; either version 2 of the License, or
15 ** (at your option) any later version.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 **
26 ******************************************************************************
27 */
28 #include "romMapperSvi328RsIDE.h"
29 #include "HarddiskIDE.h"
30 #include "MediaDb.h"
31 #include "SlotManager.h"
32 #include "DeviceManager.h"
33 #include "DebugDeviceManager.h"
34 #include "SaveState.h"
35 #include "IoPort.h"
36 #include "I8255.h"
37 #include "Disk.h"
38 #include "Language.h"
39 #include <stdlib.h>
40 #include <string.h>
41 #include <stdio.h>
42
43 /*
44 PPI NAME IDE PIN PPI NAME IDE PIN
45 --- ---- ------- --- ---- -------
46 PA0 HD0 17 D0 PB0 HD0 17 D0
47 PA1 HD1 15 D1 PB1 HD1 15 D1
48 PA2 HD2 13 D2 PB2 HD2 13 D2
49 PA3 HD3 11 D3 PB3 HD3 11 D3
50 PA4 HD4 9 D4 PB4 HD4 9 D4
51 PA5 HD5 7 D5 PB5 HD5 7 D5
52 PA6 HD6 5 D6 PB6 HD6 5 D6
53 PA7 HD7 3 D7 PB7 HD7 3 D7
54
55 PB0 HD8 4 D8 PC0 HD8 4 D8
56 PB1 HD9 6 D9 PC1 HD9 6 D9
57 PB2 HD10 8 D10 PC2 HD10 8 D10
58 PB3 HD11 10 D11 PC3 HD11 10 D11
59 PB4 HD12 12 D12 PC4 HD12 12 D12
60 PB5 HD13 14 D13 PC5 HD13 14 D13
61 PB6 HD14 16 D14 PC6 HD14 16 D14
62 PB7 HD15 18 D15 PC7 HD15 18 D15
63
64 PC0 HA0 35 A0 PA0 HA0 35 A0
65 PC1 HA1 33 A1 PA1 HA1 33 A1
66 PC2 HA2 36 A2 PA2 HA2 36 A2
67 PC3 N/A PA3 HCS0 37 CS0
68 PC4 N/A PA4 HCS1 38 CS1
69 PC5 HCS 37 /CS0 PA5 HWR 23 IOWR
70 PC6 HWR 23 /IOWR PA6 HRD 25 IORD
71 PC7 HRD 25 /IORD PA7 HRST 1 RST
72 */
73
74 typedef struct {
75 int deviceHandle;
76 int debugHandle;
77 HarddiskIde* hdide;
78 I8255* i8255;
79 UInt8 ideAddress;
80 UInt8 ideIoRead;
81 UInt8 ideIoWrite;
82 UInt16 ideData;
83 } RomMapperRsIde;
84
saveState(RomMapperRsIde * rm)85 static void saveState(RomMapperRsIde* rm)
86 {
87 SaveState* state = saveStateOpenForWrite("RomMapperRsIde");
88
89 saveStateSet(state, "ideAddress", rm->ideAddress);
90 saveStateSet(state, "ideIoRead", rm->ideIoRead);
91 saveStateSet(state, "ideIoWrite", rm->ideIoWrite);
92 saveStateSet(state, "ideData", rm->ideData);
93
94 saveStateClose(state);
95
96 harddiskIdeSaveState(rm->hdide);
97 i8255SaveState(rm->i8255);
98 }
99
loadState(RomMapperRsIde * rm)100 static void loadState(RomMapperRsIde* rm)
101 {
102 SaveState* state = saveStateOpenForRead("RomMapperRsIde");
103
104 rm->ideAddress = (UInt8)saveStateGet(state, "ideAddress", 0);
105 rm->ideIoRead = (UInt8)saveStateGet(state, "ideIoRead", 0);
106 rm->ideIoWrite = (UInt8)saveStateGet(state, "ideIoWrite", 0);
107 rm->ideData = (UInt8)saveStateGet(state, "ideData", 0);
108
109 saveStateClose(state);
110
111 harddiskIdeLoadState(rm->hdide);
112 i8255LoadState(rm->i8255);
113 }
114
destroy(RomMapperRsIde * rm)115 static void destroy(RomMapperRsIde* rm)
116 {
117 ioPortUnregister(0x14);
118 ioPortUnregister(0x15);
119 ioPortUnregister(0x16);
120 ioPortUnregister(0x17);
121
122 deviceManagerUnregister(rm->deviceHandle);
123 debugDeviceUnregister(rm->debugHandle);
124
125 harddiskIdeDestroy(rm->hdide);
126 i8255Destroy(rm->i8255);
127
128 free(rm);
129 }
130
peekIo(RomMapperRsIde * rm,UInt16 ioPort)131 static UInt8 peekIo(RomMapperRsIde* rm, UInt16 ioPort)
132 {
133 return 0xff;
134 }
135
readB(RomMapperRsIde * rm)136 static UInt8 readB(RomMapperRsIde* rm)
137 {
138 return (UInt8)rm->ideData;
139 }
140
readCLo(RomMapperRsIde * rm)141 static UInt8 readCLo(RomMapperRsIde* rm)
142 {
143 return (UInt8)(rm->ideData >> 8);
144 }
145
readCHi(RomMapperRsIde * rm)146 static UInt8 readCHi(RomMapperRsIde* rm)
147 {
148 return (UInt8)(rm->ideData >> 8);
149 }
150
writeA(RomMapperRsIde * rm,UInt8 value)151 static void writeA(RomMapperRsIde* rm, UInt8 value)
152 {
153 rm->ideAddress = value & 0x07;
154 rm->ideIoRead = value & 0x40 ? 0:1;
155 rm->ideIoWrite = value & 0x20 ? 0:1;
156
157 if (rm->ideIoRead)
158 {
159 switch (rm->ideAddress)
160 {
161 case 0:
162 rm->ideData = harddiskIdeRead(rm->hdide);
163 break;
164 default:
165 rm->ideData = harddiskIdeReadRegister(rm->hdide, rm->ideAddress);
166 break;
167 }
168 }
169
170 if (rm->ideIoWrite)
171 {
172 switch (rm->ideAddress)
173 {
174 case 0:
175 harddiskIdeWrite(rm->hdide, rm->ideData);
176 break;
177 default:
178 harddiskIdeWriteRegister(rm->hdide, rm->ideAddress, (UInt8)rm->ideData);
179 break;
180 }
181 }
182 }
183
writeB(RomMapperRsIde * rm,UInt8 value)184 static void writeB(RomMapperRsIde* rm, UInt8 value)
185 {
186 rm->ideData &= 0xff00;
187 rm->ideData |= value;
188 }
189
writeCLo(RomMapperRsIde * rm,UInt8 value)190 static void writeCLo(RomMapperRsIde* rm, UInt8 value)
191 {
192 rm->ideData &= 0x00ff;
193 rm->ideData |= value<<8;
194 }
195
writeCHi(RomMapperRsIde * rm,UInt8 value)196 static void writeCHi(RomMapperRsIde* rm, UInt8 value)
197 {
198 rm->ideData &= 0x00ff;
199 rm->ideData |= value<<8;
200 }
201
reset(RomMapperRsIde * rm)202 static void reset(RomMapperRsIde* rm)
203 {
204 harddiskIdeReset(rm->hdide);
205
206 i8255Reset(rm->i8255);
207 }
208
getDebugInfo(RomMapperRsIde * rm,DbgDevice * dbgDevice)209 static void getDebugInfo(RomMapperRsIde* rm, DbgDevice* dbgDevice)
210 {
211 DbgIoPorts* ioPorts;
212 int i;
213
214 ioPorts = dbgDeviceAddIoPorts(dbgDevice, langDbgDevIdeSviRs(), 4);
215 for (i = 0; i < 4; i++) {
216 dbgIoPortsAddPort(ioPorts, i, 0x14 + i, DBG_IO_READWRITE, i8255Peek(rm->i8255, 0x14 + i));
217 }
218 }
219
romMapperSvi328RsIdeCreate(int hdId)220 int romMapperSvi328RsIdeCreate(int hdId)
221 {
222 DeviceCallbacks callbacks = { destroy, reset, saveState, loadState };
223 DebugCallbacks dbgCallbacks = { getDebugInfo, NULL, NULL, NULL };
224 RomMapperRsIde* rm;
225
226 rm = malloc(sizeof(RomMapperRsIde));
227
228 rm->deviceHandle = deviceManagerRegister(ROM_SVI328RSIDE, &callbacks, rm);
229 rm->debugHandle = debugDeviceRegister(DBGTYPE_PORT, langDbgDevIdeSviRs(), &dbgCallbacks, rm);
230
231 rm->i8255 = i8255Create( NULL, NULL, writeA,
232 NULL, readB, writeB,
233 NULL, readCLo, writeCLo,
234 NULL, readCHi, writeCHi,
235 rm);
236
237 ioPortRegister(0x14, i8255Read, i8255Write, rm->i8255); // PPI Port A
238 ioPortRegister(0x15, i8255Read, i8255Write, rm->i8255); // PPI Port B
239 ioPortRegister(0x16, i8255Read, i8255Write, rm->i8255); // PPI Port C
240 ioPortRegister(0x17, i8255Read, i8255Write, rm->i8255); // PPI Mode
241
242 rm->hdide = harddiskIdeCreate(diskGetHdDriveId(hdId, 0));
243
244 reset(rm);
245
246 return 1;
247 }
248