Files

281 lines
7.0 KiB
C
Executable File

/*****************************************************************************
** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Memory/romMapperBeerIDE.c,v $
**
** $Revision: 1.9 $
**
** $Date: 2008-03-31 19:42:22 $
**
** More info: http://www.bluemsx.com
**
** Copyright (C) 2003-2006 Daniel Vik
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
******************************************************************************
*/
#include "romMapperBeerIDE.h"
#include "HarddiskIDE.h"
#include "MediaDb.h"
#include "SlotManager.h"
#include "DeviceManager.h"
#include "DebugDeviceManager.h"
#include "SaveState.h"
#include "IoPort.h"
#include "I8255.h"
#include "Disk.h"
#include "Language.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
PPI NAME IDE PIN
--- ---- -------
PA0 HD0 17 D0
PA1 HD1 15 D1
PA2 HD2 13 D2
PA3 HD3 11 D3
PA4 HD4 9 D4
PA5 HD5 7 D5
PA6 HD6 5 D6
PA7 HD7 3 D7
PB0 HD8 4 D8
PB1 HD9 6 D9
PB2 HD10 8 D10
PB3 HD11 10 D11
PB4 HD12 12 D12
PB5 HD13 14 D13
PB6 HD14 16 D14
PB7 HD15 18 D15
PC0 HA0 35 A0
PC1 HA1 33 A1
PC2 HA2 36 A2
PC3 N/A
PC4 N/A
PC5 HCS 37 /CS0
PC6 HWR 23 /IOWR
PC7 HRD 25 /IORD
*/
typedef struct {
int deviceHandle;
int debugHandle;
UInt8* romData;
int slot;
int sslot;
int startPage;
HarddiskIde* hdide;
I8255* i8255;
UInt8 ideAddress;
UInt8 ideIoRead;
UInt8 ideIoWrite;
UInt16 ideData;
} RomMapperBeerIde;
static void saveState(RomMapperBeerIde* rm)
{
SaveState* state = saveStateOpenForWrite("RomMapperBeerIde");
saveStateSet(state, "ideAddress", rm->ideAddress);
saveStateSet(state, "ideIoRead", rm->ideIoRead);
saveStateSet(state, "ideIoWrite", rm->ideIoWrite);
saveStateSet(state, "ideData", rm->ideData);
saveStateClose(state);
harddiskIdeSaveState(rm->hdide);
i8255SaveState(rm->i8255);
}
static void loadState(RomMapperBeerIde* rm)
{
SaveState* state = saveStateOpenForRead("RomMapperBeerIde");
rm->ideAddress = (UInt8)saveStateGet(state, "ideAddress", 0);
rm->ideIoRead = (UInt8)saveStateGet(state, "ideIoRead", 0);
rm->ideIoWrite = (UInt8)saveStateGet(state, "ideIoWrite", 0);
rm->ideData = (UInt8)saveStateGet(state, "ideData", 0);
saveStateClose(state);
harddiskIdeLoadState(rm->hdide);
i8255LoadState(rm->i8255);
}
static void destroy(RomMapperBeerIde* rm)
{
ioPortUnregister(0x30);
ioPortUnregister(0x31);
ioPortUnregister(0x32);
ioPortUnregister(0x33);
slotUnregister(rm->slot, rm->sslot, rm->startPage);
deviceManagerUnregister(rm->deviceHandle);
debugDeviceUnregister(rm->debugHandle);
harddiskIdeDestroy(rm->hdide);
i8255Destroy(rm->i8255);
free(rm->romData);
free(rm);
}
static UInt8 peekIo(RomMapperBeerIde* rm, UInt16 ioPort)
{
return 0xff;
}
static UInt8 readA(RomMapperBeerIde* rm)
{
return (UInt8)rm->ideData;
}
static UInt8 readB(RomMapperBeerIde* rm)
{
return (UInt8)(rm->ideData >> 8);
}
static void writeA(RomMapperBeerIde* rm, UInt8 value)
{
rm->ideData &= 0xff00;
rm->ideData |= value;
}
static void writeB(RomMapperBeerIde* rm, UInt8 value)
{
rm->ideData &= 0x00ff;
rm->ideData |= value<<8;
}
static void writeCLo(RomMapperBeerIde* rm, UInt8 value)
{
rm->ideAddress = value & 0x07;
}
static void writeCHi(RomMapperBeerIde* rm, UInt8 value)
{
rm->ideIoRead = value & 0x08 ? 0:1;
rm->ideIoWrite = value & 0x04 ? 0:1;
if (rm->ideIoRead)
{
switch (rm->ideAddress)
{
case 0:
rm->ideData = harddiskIdeRead(rm->hdide);
break;
default:
rm->ideData = harddiskIdeReadRegister(rm->hdide, rm->ideAddress);
break;
}
}
if (rm->ideIoWrite)
{
switch (rm->ideAddress)
{
case 0:
harddiskIdeWrite(rm->hdide, rm->ideData);
break;
default:
harddiskIdeWriteRegister(rm->hdide, rm->ideAddress, (UInt8)rm->ideData);
break;
}
}
}
static UInt8 read(RomMapperBeerIde* rm, UInt16 address)
{
return address < 0x4000 ? rm->romData[address] : 0xff;
}
static void reset(RomMapperBeerIde* rm)
{
harddiskIdeReset(rm->hdide);
i8255Reset(rm->i8255);
}
static void getDebugInfo(RomMapperBeerIde* rm, DbgDevice* dbgDevice)
{
DbgIoPorts* ioPorts;
int i;
ioPorts = dbgDeviceAddIoPorts(dbgDevice, langDbgDevIdeBeer(), 4);
for (i = 0; i < 4; i++) {
dbgIoPortsAddPort(ioPorts, i, 0x30 + i, DBG_IO_READWRITE, i8255Peek(rm->i8255, 0x30 + i));
}
}
int romMapperBeerIdeCreate(int hdId, const char* fileName, UInt8* romData,
int size, int slot, int sslot, int startPage)
{
DeviceCallbacks callbacks = { destroy, reset, saveState, loadState };
DebugCallbacks dbgCallbacks = { getDebugInfo, NULL, NULL, NULL };
RomMapperBeerIde* rm;
int i;
int origSize = size;
size = 0x4000;
while (size < origSize) {
size *= 2;
}
if (romData == NULL) {
size = 0x4000;
}
rm = malloc(sizeof(RomMapperBeerIde));
rm->deviceHandle = deviceManagerRegister(ROM_BEERIDE, &callbacks, rm);
rm->debugHandle = debugDeviceRegister(DBGTYPE_PORT, langDbgDevIdeBeer(), &dbgCallbacks, rm);
slotRegister(slot, sslot, startPage, 4, read, read, NULL, destroy, rm);
rm->i8255 = i8255Create( NULL, readA, writeA,
NULL, readB, writeB,
NULL, NULL, writeCLo,
NULL, NULL, writeCHi,
rm);
rm->romData = calloc(1, size);
if (romData != NULL) {
memcpy(rm->romData, romData, origSize);
}
else {
memset(rm->romData, 0xff, size);
}
rm->slot = slot;
rm->sslot = sslot;
rm->startPage = startPage;
for (i = 0; i < 8; i++) {
slotMapPage(rm->slot, rm->sslot, rm->startPage + i, NULL, 0, 0);
}
ioPortRegister(0x30, i8255Read, i8255Write, rm->i8255); // PPI Port A
ioPortRegister(0x31, i8255Read, i8255Write, rm->i8255); // PPI Port B
ioPortRegister(0x32, i8255Read, i8255Write, rm->i8255); // PPI Port C
ioPortRegister(0x33, i8255Read, i8255Write, rm->i8255); // PPI Mode
rm->hdide = harddiskIdeCreate(diskGetHdDriveId(hdId, 0));
reset(rm);
return 1;
}