this repo has no description
at main 214 lines 4.7 kB view raw
1/* 2 IWMEVDEV.c 3 4 Copyright (C) 2006 Philip Cummins, Paul C. Pratt 5 6 You can redistribute this file and/or modify it under the terms 7 of version 2 of the GNU General Public License as published by 8 the Free Software Foundation. You should have received a copy 9 of the license along with this file; see the file COPYING. 10 11 This file is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 license for more details. 15*/ 16 17/* 18 Integrated Woz Machine EMulated DEVice 19 20 Emulates the IWM found in the Mac Plus. 21 22 This code is adapted from "IWM.c" in vMac by Philip Cummins. 23*/ 24 25/* 26 This is the emulation for the IWM, the Integrated Woz Machine. 27 It's basically a serial to parallel converter with some timing 28 in-built into it to perform handshaking. Emulation so far just 29 includes Status and Mode Register Accesses. 30*/ 31 32#include "PICOMMON.h" 33 34#include "IWMEMDEV.h" 35 36#define IWM_dolog (dbglog_HAVE && 0) 37 38/* 39 ReportAbnormalID unused 0x0603 - 0x06FF 40*/ 41 42#define kph0L 0x00 /* CA0 off (0) */ 43#define kph0H 0x01 /* CA0 on (1) */ 44#define kph1L 0x02 /* CA1 off (0) */ 45#define kph1H 0x03 /* CA1 on (1) */ 46#define kph2L 0x04 /* CA2 off (0) */ 47#define kph2H 0x05 /* CA2 on (1) */ 48#define kph3L 0x06 /* LSTRB off (low) */ 49#define kph3H 0x07 /* LSTRB on (high) */ 50#define kmtrOff 0x08 /* disk enable off */ 51#define kmtrOn 0x09 /* disk enable on */ 52#define kintDrive 0x0A /* select internal drive */ 53#define kextDrive 0x0B /* select external drive */ 54#define kq6L 0x0C /* Q6 off */ 55#define kq6H 0x0D /* Q6 on */ 56#define kq7L 0x0E /* Q7 off */ 57#define kq7H 0x0F /* Q7 on */ 58 59#define kph0 0x01 60#define kph1 0x02 61#define kph2 0x04 62#define kph3 0x08 63#define kmtr 0x10 64#define kdrv 0x20 65#define kq6 0x40 66#define kq7 0x80 67 68typedef struct 69{ 70 ui3b DataIn; /* Read Data Register */ 71 ui3b Handshake; /* Read Handshake Register */ 72 ui3b Status; /* Read Status Register */ 73 ui3b Mode; 74 /* Drive Off : Write Mode Register */ 75 /* Drive On : Write Data Register */ 76 ui3b DataOut; /* Write Data Register */ 77 ui3b Lines; /* Used to Access Disk Drive Registers */ 78} IWM_Ty; 79 80IWM_Ty IWM; 81 82GLOBALPROC IWM_Reset(void) 83{ 84 IWM.DataIn = IWM.Handshake = IWM.Status = IWM.Mode = 85 IWM.DataOut = IWM.Lines = 0; 86} 87 88typedef enum {On, Off} Mode_Ty; 89 90LOCALPROC IWM_Set_Lines(ui3b line, Mode_Ty the_mode) 91{ 92 if (the_mode == Off) { 93 IWM.Lines &= (0xFF - line); 94 } else { 95 IWM.Lines |= line; 96 } 97} 98 99LOCALFUNC ui3b IWM_Read_Reg(void) 100{ 101 switch ((IWM.Lines & (kq6 + kq7)) >> 6) { 102 case 0 : 103#if (CurEmMd >= kEmMd_SE) && (CurEmMd <= kEmMd_IIx) 104 /* don't report */ 105#else 106 ReportAbnormalID(0x0601, "IWM Data Read"); 107#endif 108#if IWM_dolog 109 dbglog_WriteNote("IWM Data Read"); 110#endif 111 return IWM.DataIn; 112 break; 113 case 1 : 114#if IWM_dolog 115 dbglog_WriteNote("IWM Status Read"); 116#endif 117 return IWM.Status; 118 break; 119 case 2 : 120 ReportAbnormalID(0x0602, "IWM Handshake Read"); 121#if IWM_dolog 122 dbglog_WriteNote("IWM Handshake Read"); 123#endif 124 return IWM.Handshake; 125 break; 126 case 3 : 127 default : 128 /* 129 should alway be in 0-3, 130 but compiler warnings don't know that 131 */ 132 return 0; 133 break; 134 } 135} 136 137LOCALPROC IWM_Write_Reg(ui3b in) 138{ 139 if (((IWM.Lines & kmtr) >> 4) == 0) { 140#if IWM_dolog 141 dbglog_WriteNote("IWM Mode Register Write"); 142#endif 143 IWM.Mode = in; 144 IWM.Status = ((IWM.Status & 0xE0) + (IWM.Mode & 0x1F)); 145 } 146} 147 148GLOBALFUNC ui5b IWM_Access(ui5b Data, blnr WriteMem, CPTR addr) 149{ 150#if IWM_dolog 151 dbglog_AddrAccess("IWM", Data, WriteMem, addr); 152#endif 153 154 switch (addr) { 155 case kph0L : 156 IWM_Set_Lines(kph0, Off); 157 break; 158 case kph0H : 159 IWM_Set_Lines(kph0, On); 160 break; 161 case kph1L : 162 IWM_Set_Lines(kph1, Off); 163 break; 164 case kph1H : 165 IWM_Set_Lines(kph1, On); 166 break; 167 case kph2L : 168 IWM_Set_Lines(kph2, Off); 169 break; 170 case kph2H : 171 IWM_Set_Lines(kph2, On); 172 break; 173 case kph3L : 174 IWM_Set_Lines(kph3, Off); 175 break; 176 case kph3H : 177 IWM_Set_Lines(kph3, On); 178 break; 179 case kmtrOff : 180 IWM.Status &= 0xDF; 181 IWM_Set_Lines(kmtr, Off); 182 break; 183 case kmtrOn : 184 IWM.Status |= 0x20; 185 IWM_Set_Lines(kmtr, On); 186 break; 187 case kintDrive : 188 IWM_Set_Lines(kdrv, Off); 189 break; 190 case kextDrive : 191 IWM_Set_Lines(kdrv, On); 192 break; 193 case kq6L : 194 IWM_Set_Lines(kq6, Off); 195 break; 196 case kq6H : 197 IWM_Set_Lines(kq6, On); 198 break; 199 case kq7L : 200 if (! WriteMem) { 201 Data = IWM_Read_Reg(); 202 } 203 IWM_Set_Lines(kq7, Off); 204 break; 205 case kq7H : 206 if (WriteMem) { 207 IWM_Write_Reg(Data); 208 } 209 IWM_Set_Lines(kq7, On); 210 break; 211 } 212 213 return Data; 214}