trunk/src/mess/machine/applefdc.c
| r19778 | r19779 | |
| 39 | 39 | |
| 40 | 40 | |
| 41 | 41 | /*************************************************************************** |
| 42 | | PARAMETERS |
| 42 | CONSTANTS |
| 43 | 43 | ***************************************************************************/ |
| 44 | 44 | |
| 45 | | /* logging */ |
| 45 | // logging |
| 46 | 46 | #define LOG_APPLEFDC 0 |
| 47 | 47 | #define LOG_APPLEFDC_EXTRA 0 |
| 48 | 48 | |
| 49 | // mask for FDC lines |
| 50 | #define IWM_MOTOR 0x10 |
| 51 | #define IWM_DRIVE 0x20 |
| 52 | #define IWM_Q6 0x40 |
| 53 | #define IWM_Q7 0x80 |
| 49 | 54 | |
| 55 | const device_timer_id TIMER_MOTOR_ONOFF = 1; |
| 50 | 56 | |
| 51 | | /*************************************************************************** |
| 52 | | CONSTANTS |
| 53 | | ***************************************************************************/ |
| 54 | 57 | |
| 55 | | /* mask for FDC lines */ |
| 56 | | #define IWM_MOTOR 0x10 |
| 57 | | #define IWM_DRIVE 0x20 |
| 58 | | #define IWM_Q6 0x40 |
| 59 | | #define IWM_Q7 0x80 |
| 60 | 58 | |
| 61 | | enum applefdc_t |
| 62 | | { |
| 63 | | APPLEFDC_APPLE2, /* classic Apple II disk controller (pre-IWM) */ |
| 64 | | APPLEFDC_IWM, /* Integrated Woz Machine */ |
| 65 | | APPLEFDC_SWIM /* Sander/Woz Integrated Machine */ |
| 66 | | }; |
| 67 | 59 | |
| 68 | 60 | |
| 69 | | static UINT8 swim_default_parms[16] = |
| 70 | | { |
| 71 | | 0x38, 0x18, 0x41, 0x2e, 0x2e, 0x18, 0x18, 0x1b, |
| 72 | | 0x1b, 0x2f, 0x2f, 0x19, 0x19, 0x97, 0x1b, 0x57 |
| 73 | | }; |
| 74 | | |
| 75 | 61 | /*************************************************************************** |
| 76 | 62 | IWM MODE |
| 77 | 63 | |
| r19778 | r19779 | |
| 107 | 93 | IWM_MODE_LATCHMODE = 0x01 |
| 108 | 94 | }; |
| 109 | 95 | |
| 110 | | enum |
| 111 | | { |
| 112 | | SWIM_MODE_IWM, |
| 113 | | SWIM_MODE_SWIM, |
| 114 | | SWIM_MODE_SWIM2, |
| 115 | | SWIM_MODE_SWIM3 |
| 116 | | }; |
| 117 | 96 | |
| 118 | | /*************************************************************************** |
| 119 | | TYPE DEFINITIONS |
| 120 | | ***************************************************************************/ |
| 121 | 97 | |
| 122 | | struct applefdc_token |
| 123 | | { |
| 124 | | /* data that is constant for the lifetime of the emulation */ |
| 125 | | emu_timer *motor_timer; |
| 126 | | applefdc_t type; |
| 127 | | |
| 128 | | /* data that changes at emulation time */ |
| 129 | | UINT8 write_byte; |
| 130 | | UINT8 lines; /* flags from IWM_MOTOR - IWM_Q7 */ |
| 131 | | UINT8 mode; /* 0-31; see above */ |
| 132 | | UINT8 handshake_hack; /* not sure what this is for */ |
| 133 | | |
| 134 | | /* SWIM extentions */ |
| 135 | | UINT8 swim_mode; |
| 136 | | UINT8 swim_magic_state; |
| 137 | | UINT8 ism_regs[8]; |
| 138 | | UINT8 parm_offset; |
| 139 | | UINT8 parms[16]; |
| 140 | | }; |
| 141 | | |
| 142 | | |
| 143 | | |
| 144 | 98 | /*************************************************************************** |
| 145 | | PROTOTYPES |
| 99 | BASE DEVICE |
| 146 | 100 | ***************************************************************************/ |
| 147 | 101 | |
| 148 | | static TIMER_CALLBACK(iwm_turnmotor_onoff); |
| 102 | //------------------------------------------------- |
| 103 | // ctor |
| 104 | //------------------------------------------------- |
| 149 | 105 | |
| 150 | | |
| 151 | | |
| 152 | | /*************************************************************************** |
| 153 | | INLINE FUNCTIONS |
| 154 | | ***************************************************************************/ |
| 155 | | |
| 156 | | INLINE void assert_is_applefdc(device_t *device) |
| 106 | applefdc_base_device::applefdc_base_device(applefdc_base_device::applefdc_t fdc_type, const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) |
| 107 | : device_t(mconfig, type, name, tag, owner, clock) |
| 157 | 108 | { |
| 158 | | assert(device != NULL); |
| 159 | | assert((device->type() == APPLEFDC) || (device->type() == IWM) || (device->type() == SWIM)); |
| 109 | m_type = fdc_type; |
| 160 | 110 | } |
| 161 | 111 | |
| 162 | 112 | |
| 163 | 113 | |
| 164 | | INLINE applefdc_token *get_token(device_t *device) |
| 114 | //------------------------------------------------- |
| 115 | // device_start - device-specific startup |
| 116 | //------------------------------------------------- |
| 117 | |
| 118 | void applefdc_base_device::device_start() |
| 165 | 119 | { |
| 166 | | assert_is_applefdc(device); |
| 167 | | return (applefdc_token *) downcast<applefdc_base_device *>(device)->token(); |
| 120 | // timer |
| 121 | m_motor_timer = timer_alloc(TIMER_MOTOR_ONOFF); |
| 122 | |
| 123 | // state |
| 124 | m_write_byte = 0x00; |
| 125 | m_lines = 0x00; |
| 126 | m_mode = 0x1F; // default value needed by Lisa 2 - no, I don't know if it is true |
| 127 | m_handshake_hack = 0x00; |
| 128 | |
| 129 | // register save states |
| 130 | save_item(NAME(m_write_byte)); |
| 131 | save_item(NAME(m_lines)); |
| 132 | save_item(NAME(m_mode)); |
| 133 | save_item(NAME(m_handshake_hack)); |
| 168 | 134 | } |
| 169 | 135 | |
| 170 | 136 | |
| 171 | 137 | |
| 172 | | INLINE const applefdc_interface *get_interface(device_t *device) |
| 173 | | { |
| 174 | | static const applefdc_interface dummy_interface = {0, }; |
| 138 | //------------------------------------------------- |
| 139 | // device_reset - device-specific reset |
| 140 | //------------------------------------------------- |
| 175 | 141 | |
| 176 | | assert_is_applefdc(device); |
| 177 | | return (device->static_config() != NULL) |
| 178 | | ? (const applefdc_interface *) device->static_config() |
| 179 | | : &dummy_interface; |
| 142 | void applefdc_base_device::device_reset(void) |
| 143 | { |
| 144 | m_handshake_hack = 0x00; |
| 145 | m_write_byte = 0x00; |
| 146 | m_lines = 0x00; |
| 147 | m_mode = 0x1F; /* default value needed by Lisa 2 - no, I don't know if it is true */ |
| 148 | m_motor_timer->reset(); |
| 180 | 149 | } |
| 181 | 150 | |
| 182 | 151 | |
| 183 | 152 | |
| 184 | | /*************************************************************************** |
| 185 | | CORE IMPLEMENTATION |
| 186 | | ***************************************************************************/ |
| 153 | //------------------------------------------------- |
| 154 | // device_timer - device-specific timer callbacks |
| 155 | //------------------------------------------------- |
| 187 | 156 | |
| 188 | | /*------------------------------------------------- |
| 189 | | applefdc_start - starts up an FDC |
| 190 | | -------------------------------------------------*/ |
| 191 | | |
| 192 | | static void applefdc_start(device_t *device, applefdc_t type) |
| 157 | void applefdc_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 193 | 158 | { |
| 194 | | applefdc_token *fdc = get_token(device); |
| 195 | | |
| 196 | | memset(fdc, 0, sizeof(*fdc)); |
| 197 | | fdc->type = type; |
| 198 | | fdc->motor_timer = device->machine().scheduler().timer_alloc(FUNC(iwm_turnmotor_onoff), (void *) device); |
| 199 | | fdc->lines = 0x00; |
| 200 | | fdc->mode = 0x1F; /* default value needed by Lisa 2 - no, I don't know if it is true */ |
| 201 | | fdc->swim_mode = SWIM_MODE_IWM; |
| 202 | | |
| 203 | | /* register save states */ |
| 204 | | state_save_register_item(device->machine(), "applefdc", NULL, 0, fdc->write_byte); |
| 205 | | state_save_register_item(device->machine(), "applefdc", NULL, 0, fdc->lines); |
| 206 | | state_save_register_item(device->machine(), "applefdc", NULL, 0, fdc->mode); |
| 207 | | state_save_register_item(device->machine(), "applefdc", NULL, 0, fdc->handshake_hack); |
| 159 | switch(id) |
| 160 | { |
| 161 | case TIMER_MOTOR_ONOFF: |
| 162 | turn_motor_onoff(param != 0); |
| 163 | break; |
| 164 | } |
| 208 | 165 | } |
| 209 | 166 | |
| 210 | 167 | |
| 211 | 168 | |
| 212 | | /*------------------------------------------------- |
| 213 | | DEVICE_RESET(applefdc) - resets an FDC |
| 214 | | -------------------------------------------------*/ |
| 169 | //------------------------------------------------- |
| 170 | // get_interface - gets the interface |
| 171 | //------------------------------------------------- |
| 215 | 172 | |
| 216 | | static DEVICE_RESET(applefdc) |
| 173 | const applefdc_interface *applefdc_base_device::get_interface() |
| 217 | 174 | { |
| 218 | | applefdc_token *fdc = get_token(device); |
| 175 | static const applefdc_interface dummy_interface = {0, }; |
| 219 | 176 | |
| 220 | | fdc->handshake_hack = 0x00; |
| 221 | | fdc->write_byte = 0x00; |
| 222 | | fdc->lines = 0x00; |
| 223 | | fdc->mode = 0x1F; /* default value needed by Lisa 2 - no, I don't know if it is true */ |
| 224 | | fdc->swim_magic_state = 0; |
| 225 | | fdc->swim_mode = SWIM_MODE_IWM; |
| 226 | | fdc->parm_offset = 0; |
| 227 | | |
| 228 | | // setup SWIM default parms if it's a SWIM |
| 229 | | if (fdc->type == APPLEFDC_SWIM) |
| 230 | | { |
| 231 | | for (int i = 0; i < 16; i++) |
| 232 | | { |
| 233 | | fdc->parms[i] = swim_default_parms[i]; |
| 234 | | } |
| 235 | | } |
| 236 | | |
| 237 | | fdc->motor_timer->reset(); |
| 177 | return (static_config() != NULL) |
| 178 | ? (const applefdc_interface *) static_config() |
| 179 | : &dummy_interface; |
| 238 | 180 | } |
| 239 | 181 | |
| 240 | 182 | |
| 241 | 183 | |
| 242 | | /*------------------------------------------------- |
| 243 | | iwm_enable2 - hackish function |
| 244 | | -------------------------------------------------*/ |
| 184 | //------------------------------------------------- |
| 185 | // iwm_enable2 - hackish function |
| 186 | //------------------------------------------------- |
| 245 | 187 | |
| 246 | | static int iwm_enable2(device_t *device) |
| 188 | int applefdc_base_device::iwm_enable2() |
| 247 | 189 | { |
| 248 | | applefdc_token *fdc = get_token(device); |
| 249 | | |
| 250 | 190 | /* R. Nabet : This function looks more like a hack than a real feature of the IWM; */ |
| 251 | 191 | /* it is not called from the Mac Plus driver */ |
| 252 | | return (fdc->lines & APPLEFDC_PH1) && (fdc->lines & APPLEFDC_PH3); |
| 192 | return (m_lines & APPLEFDC_PH1) && (m_lines & APPLEFDC_PH3); |
| 253 | 193 | } |
| 254 | 194 | |
| 255 | 195 | |
| 256 | 196 | |
| 257 | | /*------------------------------------------------- |
| 258 | | iwm_readenable2handshake - hackish function |
| 259 | | -------------------------------------------------*/ |
| 197 | //------------------------------------------------- |
| 198 | // iwm_readenable2handshake - hackish function |
| 199 | //------------------------------------------------- |
| 260 | 200 | |
| 261 | | static UINT8 iwm_readenable2handshake(device_t *device) |
| 201 | UINT8 applefdc_base_device::iwm_readenable2handshake() |
| 262 | 202 | { |
| 263 | | applefdc_token *fdc = get_token(device); |
| 264 | | |
| 265 | 203 | /* R. Nabet : This function looks more like a hack than a real feature of the IWM; */ |
| 266 | 204 | /* it is not called from the Mac Plus driver */ |
| 267 | | fdc->handshake_hack++; |
| 268 | | fdc->handshake_hack %= 4; |
| 269 | | return (fdc->handshake_hack != 0) ? 0xc0 : 0x80; |
| 205 | m_handshake_hack++; |
| 206 | m_handshake_hack %= 4; |
| 207 | return (m_handshake_hack != 0) ? 0xc0 : 0x80; |
| 270 | 208 | } |
| 271 | 209 | |
| 272 | 210 | |
| 273 | 211 | |
| 274 | | /*------------------------------------------------- |
| 275 | | applefdc_statusreg_r - reads the status register |
| 276 | | -------------------------------------------------*/ |
| 212 | //------------------------------------------------- |
| 213 | // statusreg_r - reads the status register |
| 214 | //------------------------------------------------- |
| 277 | 215 | |
| 278 | | static UINT8 applefdc_statusreg_r(device_t *device) |
| 216 | UINT8 applefdc_base_device::statusreg_r() |
| 279 | 217 | { |
| 280 | 218 | UINT8 result; |
| 281 | 219 | int status; |
| 282 | | applefdc_token *fdc = get_token(device); |
| 283 | | const applefdc_interface *intf = get_interface(device); |
| 220 | const applefdc_interface *intf = get_interface(); |
| 284 | 221 | |
| 285 | 222 | /* IWM status: |
| 286 | 223 | * |
| r19778 | r19779 | |
| 290 | 227 | * Bits 4-0 Same as IWM mode bits 4-0 |
| 291 | 228 | */ |
| 292 | 229 | |
| 293 | | status = iwm_enable2(device) ? 1 : (intf->read_status ? intf->read_status(device) : 0); |
| 230 | status = iwm_enable2() ? 1 : (intf->read_status ? intf->read_status(this) : 0); |
| 294 | 231 | |
| 295 | 232 | result = (status ? 0x80 : 0x00); |
| 296 | 233 | |
| 297 | | if (fdc->type != APPLEFDC_APPLE2) |
| 298 | | result |= (((fdc->lines & IWM_MOTOR) ? 1 : 0) << 5) | fdc->mode; |
| 234 | if (m_type != APPLEFDC_APPLE2) |
| 235 | result |= (((m_lines & IWM_MOTOR) ? 1 : 0) << 5) | m_mode; |
| 299 | 236 | return result; |
| 300 | 237 | } |
| 301 | 238 | |
| 302 | 239 | |
| 303 | 240 | |
| 304 | | /*------------------------------------------------- |
| 305 | | iwm_modereg_w - changes the mode register |
| 306 | | -------------------------------------------------*/ |
| 241 | //------------------------------------------------- |
| 242 | // iwm_modereg_w - changes the mode register |
| 243 | //------------------------------------------------- |
| 307 | 244 | |
| 308 | | static void iwm_modereg_w(device_t *device, UINT8 data) |
| 245 | void applefdc_base_device::iwm_modereg_w(UINT8 data) |
| 309 | 246 | { |
| 310 | | applefdc_token *fdc = get_token(device); |
| 247 | m_mode = data & 0x1f; /* write mode register */ |
| 311 | 248 | |
| 312 | | fdc->mode = data & 0x1f; /* write mode register */ |
| 313 | | |
| 314 | | // SWIM mode is unlocked by writing 1/0/1/1 in a row to bit 6 (which is unused on IWM) |
| 315 | | // when SWIM mode engages, the IWM is disconnected from both the 68k and the drives, |
| 316 | | // and the ISM is substituted. |
| 317 | | if (fdc->type == APPLEFDC_SWIM) |
| 318 | | { |
| 319 | | switch (fdc->swim_magic_state) |
| 320 | | { |
| 321 | | case 0: |
| 322 | | case 2: |
| 323 | | case 3: |
| 324 | | if (data & 0x40) |
| 325 | | { |
| 326 | | fdc->swim_magic_state++; |
| 327 | | } |
| 328 | | else |
| 329 | | { |
| 330 | | fdc->swim_magic_state = 0; |
| 331 | | } |
| 332 | | break; |
| 333 | | case 1: |
| 334 | | if (!(data & 0x40)) |
| 335 | | { |
| 336 | | fdc->swim_magic_state++; |
| 337 | | } |
| 338 | | else |
| 339 | | { |
| 340 | | fdc->swim_magic_state = 0; |
| 341 | | } |
| 342 | | break; |
| 343 | | } |
| 344 | | |
| 345 | | if (fdc->swim_magic_state == 4) |
| 346 | | { |
| 347 | | fdc->swim_magic_state = 0; |
| 348 | | // printf("IWM: switching to SWIM mode\n"); |
| 349 | | fdc->swim_mode = SWIM_MODE_SWIM; |
| 350 | | } |
| 351 | | } |
| 352 | | |
| 353 | 249 | if (LOG_APPLEFDC_EXTRA) |
| 354 | | logerror("iwm_modereg_w: iwm_mode=0x%02x\n", (unsigned) fdc->mode); |
| 250 | logerror("iwm_modereg_w: iwm_mode=0x%02x\n", (unsigned) m_mode); |
| 355 | 251 | } |
| 356 | 252 | |
| 357 | 253 | |
| 358 | 254 | |
| 359 | | /*------------------------------------------------- |
| 360 | | applefdc_read_reg - reads a register |
| 361 | | -------------------------------------------------*/ |
| 255 | //------------------------------------------------- |
| 256 | // read_reg - reads a register |
| 257 | //------------------------------------------------- |
| 362 | 258 | |
| 363 | | static UINT8 applefdc_read_reg(device_t *device, int lines) |
| 259 | UINT8 applefdc_base_device::read_reg(int lines) |
| 364 | 260 | { |
| 365 | | applefdc_token *fdc = get_token(device); |
| 366 | | const applefdc_interface *intf = get_interface(device); |
| 261 | const applefdc_interface *intf = get_interface(); |
| 367 | 262 | UINT8 result = 0; |
| 368 | 263 | |
| 369 | 264 | switch(lines) |
| 370 | 265 | { |
| 371 | 266 | case 0: |
| 372 | | /* Read data register */ |
| 373 | | if ((fdc->type != APPLEFDC_APPLE2) && (iwm_enable2(device) || !(fdc->lines & IWM_MOTOR))) |
| 267 | // read data register |
| 268 | if ((m_type != APPLEFDC_APPLE2) && (iwm_enable2() || !(m_lines & IWM_MOTOR))) |
| 374 | 269 | { |
| 375 | 270 | result = 0xFF; |
| 376 | 271 | } |
| 377 | 272 | else |
| 378 | 273 | { |
| 379 | | /* |
| 380 | | * Right now, this function assumes latch mode; which is always used for |
| 381 | | * 3.5 inch drives. Eventually we should check to see if latch mode is |
| 382 | | * off |
| 383 | | */ |
| 274 | // Right now, this function assumes latch mode; which is always used for |
| 275 | // 3.5 inch drives. Eventually we should check to see if latch mode is |
| 276 | // off |
| 384 | 277 | if (LOG_APPLEFDC) |
| 385 | 278 | { |
| 386 | | if ((fdc->mode & IWM_MODE_LATCHMODE) == 0x00) |
| 279 | if ((m_mode & IWM_MODE_LATCHMODE) == 0x00) |
| 387 | 280 | logerror("applefdc_read_reg(): latch mode off not implemented\n"); |
| 388 | 281 | } |
| 389 | 282 | |
| 390 | | result = (intf->read_data ? intf->read_data(device) : 0x00); |
| 283 | result = (intf->read_data ? intf->read_data(this) : 0x00); |
| 391 | 284 | } |
| 392 | 285 | break; |
| 393 | 286 | |
| 394 | 287 | case IWM_Q6: |
| 395 | | /* Read status register */ |
| 396 | | result = applefdc_statusreg_r(device); |
| 288 | // read status register |
| 289 | result = statusreg_r(); |
| 397 | 290 | break; |
| 398 | 291 | |
| 399 | 292 | case IWM_Q7: |
| 400 | | /* Classic Apple II: Read status register |
| 401 | | * IWM: Read handshake register |
| 402 | | */ |
| 403 | | if (fdc->type == APPLEFDC_APPLE2) |
| 404 | | result = applefdc_statusreg_r(device); |
| 293 | // Classic Apple II: Read status register |
| 294 | // IWM: Read handshake register |
| 295 | if (m_type == APPLEFDC_APPLE2) |
| 296 | result = statusreg_r(); |
| 405 | 297 | else |
| 406 | | result = iwm_enable2(device) ? iwm_readenable2handshake(device) : 0x80; |
| 298 | result = iwm_enable2() ? iwm_readenable2handshake() : 0x80; |
| 407 | 299 | break; |
| 408 | 300 | } |
| 409 | 301 | return result; |
| r19778 | r19779 | |
| 411 | 303 | |
| 412 | 304 | |
| 413 | 305 | |
| 414 | | /*------------------------------------------------- |
| 415 | | applefdc_write_reg - writes a register |
| 416 | | -------------------------------------------------*/ |
| 306 | //------------------------------------------------- |
| 307 | // write_reg - writes a register |
| 308 | //------------------------------------------------- |
| 417 | 309 | |
| 418 | | static void applefdc_write_reg(device_t *device, UINT8 data) |
| 310 | void applefdc_base_device::write_reg(UINT8 data) |
| 419 | 311 | { |
| 420 | | applefdc_token *fdc = get_token(device); |
| 421 | | const applefdc_interface *intf = get_interface(device); |
| 312 | const applefdc_interface *intf = get_interface(); |
| 422 | 313 | |
| 423 | | switch(fdc->lines & (IWM_Q6 | IWM_Q7)) |
| 314 | switch(m_lines & (IWM_Q6 | IWM_Q7)) |
| 424 | 315 | { |
| 425 | 316 | case IWM_Q6 | IWM_Q7: |
| 426 | | if (!(fdc->lines & IWM_MOTOR)) |
| 317 | if (!(m_lines & IWM_MOTOR)) |
| 427 | 318 | { |
| 428 | | iwm_modereg_w(device, data); |
| 319 | iwm_modereg_w(data); |
| 429 | 320 | } |
| 430 | | else if (!iwm_enable2(device)) |
| 321 | else if (!iwm_enable2()) |
| 431 | 322 | { |
| 432 | | /* |
| 433 | | * Right now, this function assumes latch mode; which is always used for |
| 434 | | * 3.5 inch drives. Eventually we should check to see if latch mode is |
| 435 | | * off |
| 436 | | */ |
| 323 | // Right now, this function assumes latch mode; which is always used for |
| 324 | // 3.5 inch drives. Eventually we should check to see if latch mode is |
| 325 | // off |
| 437 | 326 | if (LOG_APPLEFDC) |
| 438 | 327 | { |
| 439 | | if ((fdc->mode & IWM_MODE_LATCHMODE) == 0) |
| 328 | if ((m_mode & IWM_MODE_LATCHMODE) == 0) |
| 440 | 329 | logerror("applefdc_write_reg(): latch mode off not implemented\n"); |
| 441 | 330 | } |
| 442 | 331 | |
| 443 | 332 | if (intf->write_data != NULL) |
| 444 | | intf->write_data(device,data); |
| 333 | intf->write_data(this, data); |
| 445 | 334 | } |
| 446 | 335 | break; |
| 447 | 336 | } |
| r19778 | r19779 | |
| 449 | 338 | |
| 450 | 339 | |
| 451 | 340 | |
| 452 | | /*------------------------------------------------- |
| 453 | | TIMER_CALLBACK(iwm_turnmotor_onoff) - timer |
| 454 | | callback for turning motor on or off |
| 455 | | -------------------------------------------------*/ |
| 341 | //------------------------------------------------- |
| 342 | // turn_motor_onoff - timer callback for turning |
| 343 | // motor on or off |
| 344 | //------------------------------------------------- |
| 456 | 345 | |
| 457 | | static TIMER_CALLBACK(iwm_turnmotor_onoff) |
| 346 | void applefdc_base_device::turn_motor_onoff(bool status) |
| 458 | 347 | { |
| 459 | | device_t *device = (device_t *) ptr; |
| 460 | | applefdc_token *fdc = get_token(device); |
| 461 | | const applefdc_interface *intf = get_interface(device); |
| 462 | | int status = param; |
| 348 | const applefdc_interface *intf = get_interface(); |
| 463 | 349 | int enable_lines; |
| 464 | 350 | |
| 465 | | if (status != 0) |
| 351 | if (status) |
| 466 | 352 | { |
| 467 | | fdc->lines |= IWM_MOTOR; |
| 468 | | enable_lines = (fdc->lines & IWM_DRIVE) ? 2 : 1; |
| 353 | m_lines |= IWM_MOTOR; |
| 354 | enable_lines = (m_lines & IWM_DRIVE) ? 2 : 1; |
| 469 | 355 | } |
| 470 | 356 | else |
| 471 | 357 | { |
| 472 | | fdc->lines &= ~IWM_MOTOR; |
| 358 | m_lines &= ~IWM_MOTOR; |
| 473 | 359 | |
| 474 | | if (fdc->type == APPLEFDC_APPLE2) |
| 475 | | enable_lines = (fdc->lines & IWM_DRIVE) ? 2 : 1; |
| 360 | if (m_type == APPLEFDC_APPLE2) |
| 361 | enable_lines = (m_lines & IWM_DRIVE) ? 2 : 1; |
| 476 | 362 | else |
| 477 | 363 | enable_lines = 0; |
| 478 | 364 | } |
| 479 | 365 | |
| 480 | 366 | /* invoke callback, if present */ |
| 481 | 367 | if (intf->set_enable_lines != NULL) |
| 482 | | intf->set_enable_lines(device,enable_lines); |
| 368 | intf->set_enable_lines(this, enable_lines); |
| 483 | 369 | |
| 484 | 370 | if (LOG_APPLEFDC_EXTRA) |
| 485 | 371 | logerror("iwm_turnmotor_onoff(): Turning motor %s\n", status ? "on" : "off"); |
| r19778 | r19779 | |
| 487 | 373 | |
| 488 | 374 | |
| 489 | 375 | |
| 490 | | /*------------------------------------------------- |
| 491 | | iwm_access |
| 492 | | -------------------------------------------------*/ |
| 376 | //------------------------------------------------- |
| 377 | // iwm_access |
| 378 | //------------------------------------------------- |
| 493 | 379 | |
| 494 | | static void iwm_access(device_t *device, int offset) |
| 380 | void applefdc_base_device::iwm_access(int offset) |
| 495 | 381 | { |
| 496 | 382 | static const char *const lines[] = |
| 497 | 383 | { |
| r19778 | r19779 | |
| 505 | 391 | "Q7" |
| 506 | 392 | }; |
| 507 | 393 | |
| 508 | | applefdc_token *fdc = get_token(device); |
| 509 | | const applefdc_interface *intf = get_interface(device); |
| 394 | const applefdc_interface *intf = get_interface(); |
| 510 | 395 | |
| 511 | 396 | if (offset & 1) |
| 512 | | fdc->lines |= (1 << (offset >> 1)); |
| 397 | m_lines |= (1 << (offset >> 1)); |
| 513 | 398 | else |
| 514 | | fdc->lines &= ~(1 << (offset >> 1)); |
| 399 | m_lines &= ~(1 << (offset >> 1)); |
| 515 | 400 | |
| 516 | 401 | if (LOG_APPLEFDC_EXTRA) |
| 517 | 402 | { |
| 518 | 403 | logerror("iwm_access(): %s line %s => %02x\n", |
| 519 | | (offset & 1) ? "setting" : "clearing", lines[offset >> 1], fdc->lines); |
| 404 | (offset & 1) ? "setting" : "clearing", lines[offset >> 1], m_lines); |
| 520 | 405 | } |
| 521 | 406 | |
| 522 | 407 | if ((offset < 0x08) && (intf->set_lines != NULL)) |
| 523 | | intf->set_lines(device,fdc->lines & 0x0f); |
| 408 | intf->set_lines(this, m_lines & 0x0f); |
| 524 | 409 | |
| 525 | 410 | switch(offset) |
| 526 | 411 | { |
| 527 | 412 | case 0x08: |
| 528 | 413 | /* turn off motor */ |
| 529 | | fdc->motor_timer->adjust( |
| 530 | | (fdc->mode & IWM_MODE_MOTOROFFDELAY) ? attotime::zero : attotime::from_seconds(1), 0); |
| 414 | m_motor_timer->adjust( |
| 415 | (m_mode & IWM_MODE_MOTOROFFDELAY) ? attotime::zero : attotime::from_seconds(1), 0); |
| 531 | 416 | break; |
| 532 | 417 | |
| 533 | 418 | case 0x09: |
| 534 | 419 | /* turn on motor */ |
| 535 | | fdc->motor_timer->adjust(attotime::zero, 1); |
| 420 | m_motor_timer->adjust(attotime::zero, 1); |
| 536 | 421 | break; |
| 537 | 422 | |
| 538 | 423 | case 0x0A: |
| 539 | 424 | /* turn off IWM_DRIVE */ |
| 540 | | if ((fdc->lines & IWM_MOTOR) && (intf->set_enable_lines != NULL)) |
| 541 | | intf->set_enable_lines(device,1); |
| 425 | if ((m_lines & IWM_MOTOR) && (intf->set_enable_lines != NULL)) |
| 426 | intf->set_enable_lines(this, 1); |
| 542 | 427 | break; |
| 543 | 428 | |
| 544 | 429 | case 0x0B: |
| 545 | 430 | /* turn on IWM_DRIVE */ |
| 546 | | if ((fdc->lines & IWM_MOTOR) && (intf->set_enable_lines != NULL)) |
| 547 | | intf->set_enable_lines(device,2); |
| 431 | if ((m_lines & IWM_MOTOR) && (intf->set_enable_lines != NULL)) |
| 432 | intf->set_enable_lines(this, 2); |
| 548 | 433 | break; |
| 549 | 434 | } |
| 550 | 435 | } |
| 551 | 436 | |
| 552 | 437 | |
| 553 | 438 | |
| 554 | | /*------------------------------------------------- |
| 555 | | applefdc_r - reads a byte from the FDC |
| 556 | | -------------------------------------------------*/ |
| 439 | //------------------------------------------------- |
| 440 | // read - reads a byte from the FDC |
| 441 | //------------------------------------------------- |
| 557 | 442 | |
| 558 | | READ8_DEVICE_HANDLER( applefdc_r ) |
| 443 | UINT8 applefdc_base_device::read(UINT8 offset) |
| 559 | 444 | { |
| 560 | | applefdc_token *fdc = get_token(device); |
| 561 | | const applefdc_interface *intf = get_interface(device); |
| 445 | const applefdc_interface *intf = get_interface(); |
| 562 | 446 | UINT8 result = 0; |
| 563 | 447 | |
| 564 | | /* normalize offset */ |
| 448 | // normalize offset |
| 565 | 449 | offset &= 0xf; |
| 566 | 450 | |
| 567 | 451 | if (LOG_APPLEFDC_EXTRA) |
| 568 | 452 | logerror("applefdc_r: offset=%i\n", offset); |
| 569 | 453 | |
| 570 | | if ((fdc->type < APPLEFDC_SWIM) || (fdc->swim_mode == SWIM_MODE_IWM)) |
| 454 | iwm_access(offset); |
| 455 | |
| 456 | switch(m_type) |
| 571 | 457 | { |
| 572 | | iwm_access(device, offset); |
| 458 | case APPLEFDC_APPLE2: |
| 459 | switch(offset) |
| 460 | { |
| 461 | case 0x0C: |
| 462 | if (m_lines & IWM_Q7) |
| 463 | { |
| 464 | if (intf->write_data != NULL) |
| 465 | intf->write_data(this, m_write_byte); |
| 466 | result = 0; |
| 467 | } |
| 468 | else |
| 469 | result = read_reg(0); |
| 470 | break; |
| 573 | 471 | |
| 574 | | switch(fdc->type) |
| 575 | | { |
| 576 | | case APPLEFDC_APPLE2: |
| 577 | | switch(offset) |
| 578 | | { |
| 579 | | case 0x0C: |
| 580 | | if (fdc->lines & IWM_Q7) |
| 581 | | { |
| 582 | | if (intf->write_data != NULL) |
| 583 | | intf->write_data(device,fdc->write_byte); |
| 584 | | result = 0; |
| 585 | | } |
| 586 | | else |
| 587 | | result = applefdc_read_reg(device, 0); |
| 472 | case 0x0D: |
| 473 | result = read_reg(IWM_Q6); |
| 474 | break; |
| 588 | 475 | |
| 589 | | break; |
| 590 | | case 0x0D: |
| 591 | | result = applefdc_read_reg(device, IWM_Q6); |
| 592 | | break; |
| 593 | | case 0x0E: |
| 594 | | result = applefdc_read_reg(device, IWM_Q7); |
| 595 | | break; |
| 596 | | case 0x0F: |
| 597 | | result = applefdc_read_reg(device, IWM_Q7 | IWM_Q6); |
| 598 | | break; |
| 599 | | } |
| 600 | | break; |
| 476 | case 0x0E: |
| 477 | result = read_reg(IWM_Q7); |
| 478 | break; |
| 601 | 479 | |
| 602 | | case APPLEFDC_IWM: |
| 603 | | if ((offset & 1) == 0) |
| 604 | | result = applefdc_read_reg(device, fdc->lines & (IWM_Q6 | IWM_Q7)); |
| 605 | | break; |
| 480 | case 0x0F: |
| 481 | result = read_reg(IWM_Q7 | IWM_Q6); |
| 482 | break; |
| 483 | } |
| 484 | break; |
| 606 | 485 | |
| 607 | | case APPLEFDC_SWIM: |
| 608 | | if ((offset & 1) == 0) |
| 609 | | result = applefdc_read_reg(device, fdc->lines & (IWM_Q6 | IWM_Q7)); |
| 610 | | break; |
| 611 | | } |
| 486 | case APPLEFDC_IWM: |
| 487 | if ((offset & 1) == 0) |
| 488 | result = read_reg(m_lines & (IWM_Q6 | IWM_Q7)); |
| 489 | break; |
| 490 | |
| 491 | case APPLEFDC_SWIM: |
| 492 | if ((offset & 1) == 0) |
| 493 | result = read_reg(m_lines & (IWM_Q6 | IWM_Q7)); |
| 494 | break; |
| 612 | 495 | } |
| 613 | | else if (fdc->swim_mode >= SWIM_MODE_SWIM) |
| 614 | | { |
| 615 | | // reading parameter RAM? |
| 616 | | if ((offset & 7) == 3) |
| 617 | | { |
| 618 | | result = fdc->parms[fdc->parm_offset++]; |
| 619 | | fdc->parm_offset &= 0xf; |
| 620 | | } |
| 621 | | else |
| 622 | | { |
| 623 | | result = fdc->ism_regs[offset&7]; |
| 624 | | } |
| 625 | | printf("SWIM: read %02x from offset %x\n", result, offset & 7); |
| 626 | | } |
| 627 | 496 | |
| 628 | 497 | return result; |
| 629 | 498 | } |
| 630 | 499 | |
| 631 | 500 | |
| 632 | 501 | |
| 633 | | /*------------------------------------------------- |
| 634 | | applefdc_w - writes a byte to the FDC |
| 635 | | -------------------------------------------------*/ |
| 502 | //------------------------------------------------- |
| 503 | // write - writes a byte to the FDC |
| 504 | //------------------------------------------------- |
| 636 | 505 | |
| 637 | | WRITE8_DEVICE_HANDLER( applefdc_w ) |
| 506 | void applefdc_base_device::write(UINT8 offset, UINT8 data) |
| 638 | 507 | { |
| 639 | | applefdc_token *fdc = get_token(device); |
| 640 | | const applefdc_interface *intf = get_interface(device); |
| 508 | const applefdc_interface *intf = get_interface(); |
| 641 | 509 | |
| 642 | 510 | /* normalize offset */ |
| 643 | 511 | offset &= 15; |
| r19778 | r19779 | |
| 645 | 513 | if (LOG_APPLEFDC_EXTRA) |
| 646 | 514 | logerror("applefdc_w: offset=%i data=0x%02x\n", offset, data); |
| 647 | 515 | |
| 648 | | if ((fdc->type < APPLEFDC_SWIM) || (fdc->swim_mode == SWIM_MODE_IWM)) |
| 649 | | { |
| 650 | | iwm_access(device, offset); |
| 516 | iwm_access(offset); |
| 651 | 517 | |
| 652 | | switch(fdc->type) |
| 653 | | { |
| 654 | | case APPLEFDC_APPLE2: |
| 655 | | switch(offset) |
| 656 | | { |
| 657 | | case 0x0C: |
| 658 | | if (fdc->lines & IWM_Q7) |
| 659 | | { |
| 660 | | if (intf->write_data != NULL) |
| 661 | | intf->write_data(device,fdc->write_byte); |
| 662 | | } |
| 663 | | break; |
| 664 | | |
| 665 | | case 0x0D: |
| 666 | | fdc->write_byte = data; |
| 667 | | break; |
| 668 | | } |
| 669 | | break; |
| 670 | | |
| 671 | | case APPLEFDC_IWM: |
| 672 | | if (offset & 1) |
| 673 | | applefdc_write_reg(device, data); |
| 674 | | break; |
| 675 | | |
| 676 | | case APPLEFDC_SWIM: |
| 677 | | if (offset & 1) |
| 678 | | applefdc_write_reg(device, data); |
| 679 | | break; |
| 680 | | } |
| 681 | | } |
| 682 | | else if (fdc->swim_mode >= SWIM_MODE_SWIM) |
| 518 | switch(m_type) |
| 683 | 519 | { |
| 684 | | printf("SWIM: write %02x to offset %x\n", data, offset & 7); |
| 685 | | switch (offset & 7) |
| 686 | | { |
| 687 | | case 2: // write CRC |
| 688 | | break; |
| 520 | case APPLEFDC_APPLE2: |
| 521 | switch(offset) |
| 522 | { |
| 523 | case 0x0C: |
| 524 | if (m_lines & IWM_Q7) |
| 525 | { |
| 526 | if (intf->write_data != NULL) |
| 527 | intf->write_data(this, m_write_byte); |
| 528 | } |
| 529 | break; |
| 689 | 530 | |
| 690 | | case 3: // write parameter |
| 691 | | fdc->parms[fdc->parm_offset++] = data; |
| 692 | | fdc->parm_offset &= 0xf; |
| 693 | | break; |
| 531 | case 0x0D: |
| 532 | m_write_byte = data; |
| 533 | break; |
| 534 | } |
| 535 | break; |
| 694 | 536 | |
| 695 | | case 6: // write zeros to status (also zeroes parameter RAM pointer) |
| 696 | | fdc->ism_regs[6] &= ~data; |
| 697 | | fdc->parm_offset = 0; |
| 537 | case APPLEFDC_IWM: |
| 538 | if (offset & 1) |
| 539 | write_reg(data); |
| 540 | break; |
| 698 | 541 | |
| 699 | | if (data == 0xf8) // magic "revert to IWM" value |
| 700 | | { |
| 701 | | printf("SWIM: reverting to IWM\n"); |
| 702 | | fdc->swim_mode = SWIM_MODE_IWM; |
| 703 | | } |
| 704 | | break; |
| 705 | | |
| 706 | | case 7: // write ones to status |
| 707 | | fdc->ism_regs[6] |= data; |
| 708 | | break; |
| 709 | | |
| 710 | | default: |
| 711 | | fdc->ism_regs[offset & 7] = data; |
| 712 | | break; |
| 713 | | |
| 714 | | } |
| 542 | case APPLEFDC_SWIM: |
| 543 | if (offset & 1) |
| 544 | write_reg(data); |
| 545 | break; |
| 715 | 546 | } |
| 716 | 547 | } |
| 717 | 548 | |
| 718 | 549 | |
| 719 | 550 | |
| 720 | | /*------------------------------------------------- |
| 721 | | applefdc_w - writes a byte to the FDC |
| 722 | | -------------------------------------------------*/ |
| 551 | //------------------------------------------------- |
| 552 | // get_lines - accessor |
| 553 | //------------------------------------------------- |
| 723 | 554 | |
| 724 | | UINT8 applefdc_get_lines(device_t *device) |
| 555 | UINT8 applefdc_base_device::get_lines() |
| 725 | 556 | { |
| 726 | | applefdc_token *fdc = get_token(device); |
| 727 | | return fdc->lines & 0x0f; |
| 557 | return m_lines & 0x0f; |
| 728 | 558 | } |
| 729 | 559 | |
| 730 | 560 | |
| 731 | 561 | |
| 732 | 562 | /*************************************************************************** |
| 733 | | INTERFACE |
| 563 | APPLE FDC - Used on Apple II |
| 734 | 564 | ***************************************************************************/ |
| 735 | 565 | |
| 736 | | /*------------------------------------------------- |
| 737 | | DEVICE_START(oldfdc) - device start |
| 738 | | callback |
| 739 | | -------------------------------------------------*/ |
| 740 | | |
| 741 | | static DEVICE_START(oldfdc) |
| 742 | | { |
| 743 | | applefdc_start(device, APPLEFDC_APPLE2); |
| 744 | | } |
| 745 | | |
| 746 | | |
| 747 | | |
| 748 | | /*------------------------------------------------- |
| 749 | | DEVICE_START(iwm) - device start |
| 750 | | callback |
| 751 | | -------------------------------------------------*/ |
| 752 | | |
| 753 | | static DEVICE_START(iwm) |
| 754 | | { |
| 755 | | applefdc_start(device, APPLEFDC_IWM); |
| 756 | | } |
| 757 | | |
| 758 | | |
| 759 | | /*------------------------------------------------- |
| 760 | | DEVICE_START(iwm) - device start |
| 761 | | callback |
| 762 | | -------------------------------------------------*/ |
| 763 | | |
| 764 | | static DEVICE_START(swim) |
| 765 | | { |
| 766 | | applefdc_start(device, APPLEFDC_SWIM); |
| 767 | | } |
| 768 | | |
| 769 | | |
| 770 | | applefdc_base_device::applefdc_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) |
| 771 | | : device_t(mconfig, type, name, tag, owner, clock) |
| 772 | | { |
| 773 | | m_token = global_alloc_clear(applefdc_token); |
| 774 | | } |
| 775 | | |
| 776 | | //------------------------------------------------- |
| 777 | | // device_config_complete - perform any |
| 778 | | // operations now that the configuration is |
| 779 | | // complete |
| 780 | | //------------------------------------------------- |
| 781 | | |
| 782 | | void applefdc_base_device::device_config_complete() |
| 783 | | { |
| 784 | | } |
| 785 | | |
| 786 | | //------------------------------------------------- |
| 787 | | // device_reset - device-specific reset |
| 788 | | //------------------------------------------------- |
| 789 | | |
| 790 | | void applefdc_base_device::device_reset() |
| 791 | | { |
| 792 | | DEVICE_RESET_NAME( applefdc )(this); |
| 793 | | } |
| 794 | | |
| 795 | | |
| 796 | 566 | const device_type APPLEFDC = &device_creator<applefdc_device>; |
| 797 | 567 | |
| 798 | 568 | applefdc_device::applefdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 799 | | : applefdc_base_device(mconfig, APPLEFDC, "Apple FDC", tag, owner, clock) |
| 569 | : applefdc_base_device(APPLEFDC_APPLE2, mconfig, APPLEFDC, "Apple FDC", tag, owner, clock) |
| 800 | 570 | { |
| 801 | 571 | } |
| 802 | 572 | |
| 803 | | //------------------------------------------------- |
| 804 | | // device_start - device-specific startup |
| 805 | | //------------------------------------------------- |
| 806 | 573 | |
| 807 | | void applefdc_device::device_start() |
| 808 | | { |
| 809 | | DEVICE_START_NAME( oldfdc )(this); |
| 810 | | } |
| 811 | 574 | |
| 575 | /*************************************************************************** |
| 576 | IWM - Used on early Macs |
| 577 | ***************************************************************************/ |
| 812 | 578 | |
| 813 | 579 | const device_type IWM = &device_creator<iwm_device>; |
| 814 | 580 | |
| 815 | 581 | iwm_device::iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 816 | | : applefdc_base_device(mconfig, IWM, "Apple IWM (Integrated Woz Machine)", tag, owner, clock) |
| 582 | : applefdc_base_device(APPLEFDC_IWM, mconfig, IWM, "Apple IWM (Integrated Woz Machine)", tag, owner, clock) |
| 817 | 583 | { |
| 818 | 584 | } |
| 819 | | |
| 820 | | //------------------------------------------------- |
| 821 | | // device_start - device-specific startup |
| 822 | | //------------------------------------------------- |
| 823 | | |
| 824 | | void iwm_device::device_start() |
| 825 | | { |
| 826 | | DEVICE_START_NAME( iwm )(this); |
| 827 | | } |
| 828 | | |
| 829 | | |
| 830 | | const device_type SWIM = &device_creator<swim_device>; |
| 831 | | |
| 832 | | swim_device::swim_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 833 | | : applefdc_base_device(mconfig, SWIM, "Apple SWIM (Steve Woz Integrated Machine)", tag, owner, clock) |
| 834 | | { |
| 835 | | } |
| 836 | | |
| 837 | | //------------------------------------------------- |
| 838 | | // device_start - device-specific startup |
| 839 | | //------------------------------------------------- |
| 840 | | |
| 841 | | void swim_device::device_start() |
| 842 | | { |
| 843 | | DEVICE_START_NAME( swim )(this); |
| 844 | | } |
| 845 | | |
| 846 | | |
trunk/src/mess/machine/applefdc.h
| r19778 | r19779 | |
| 28 | 28 | #define APPLEFDC_PH2 0x04 |
| 29 | 29 | #define APPLEFDC_PH3 0x08 |
| 30 | 30 | |
| 31 | | class applefdc_base_device : public device_t |
| 31 | extern const device_type APPLEFDC; |
| 32 | extern const device_type IWM; |
| 33 | extern const device_type SWIM; |
| 34 | |
| 35 | |
| 36 | |
| 37 | /*************************************************************************** |
| 38 | INTERFACE |
| 39 | ***************************************************************************/ |
| 40 | |
| 41 | struct applefdc_interface |
| 32 | 42 | { |
| 33 | | public: |
| 34 | | applefdc_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 35 | | ~applefdc_base_device() { global_free(m_token); } |
| 43 | void (*set_lines)(device_t *device, UINT8 lines); |
| 44 | void (*set_enable_lines)(device_t *device, int enable_mask); |
| 36 | 45 | |
| 37 | | // access to legacy token |
| 38 | | void *token() const { assert(m_token != NULL); return m_token; } |
| 39 | | protected: |
| 40 | | // device-level overrides |
| 41 | | virtual void device_config_complete(); |
| 42 | | virtual void device_start() { } |
| 43 | | virtual void device_reset(); |
| 44 | | private: |
| 45 | | // internal state |
| 46 | | void *m_token; |
| 46 | UINT8 (*read_data)(device_t *device); |
| 47 | void (*write_data)(device_t *device, UINT8 data); |
| 48 | int (*read_status)(device_t *device); |
| 47 | 49 | }; |
| 48 | 50 | |
| 49 | | class applefdc_device : public applefdc_base_device |
| 51 | |
| 52 | |
| 53 | /*************************************************************************** |
| 54 | BASE DEVICE |
| 55 | ***************************************************************************/ |
| 56 | |
| 57 | class applefdc_base_device : public device_t |
| 50 | 58 | { |
| 51 | 59 | public: |
| 52 | | applefdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 53 | | protected: |
| 54 | | // device-level overrides |
| 55 | | virtual void device_start(); |
| 56 | | }; |
| 60 | // read/write handlers |
| 61 | virtual UINT8 read(UINT8 offset); |
| 62 | virtual void write(UINT8 offset, UINT8 data); |
| 57 | 63 | |
| 58 | | extern const device_type APPLEFDC; |
| 64 | // read/write handlers overloads |
| 65 | UINT8 read(offs_t offset) { return read((UINT8) offset); } |
| 66 | void write(offs_t offset, UINT8 data) { write((UINT8) offset, data); } |
| 67 | DECLARE_READ8_MEMBER( read ) { return read((UINT8) offset); } |
| 68 | DECLARE_WRITE8_MEMBER( write ) { write((UINT8) offset, data); } |
| 59 | 69 | |
| 60 | | class iwm_device : public applefdc_base_device |
| 61 | | { |
| 62 | | public: |
| 63 | | iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 70 | // accessor |
| 71 | UINT8 get_lines(); |
| 72 | |
| 64 | 73 | protected: |
| 65 | | // device-level overrides |
| 66 | | virtual void device_start(); |
| 67 | | }; |
| 74 | enum applefdc_t |
| 75 | { |
| 76 | APPLEFDC_APPLE2, /* classic Apple II disk controller (pre-IWM) */ |
| 77 | APPLEFDC_IWM, /* Integrated Woz Machine */ |
| 78 | APPLEFDC_SWIM /* Sander/Woz Integrated Machine */ |
| 79 | }; |
| 68 | 80 | |
| 69 | | extern const device_type IWM; |
| 81 | // constructor |
| 82 | applefdc_base_device(applefdc_t fdc_type, const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 70 | 83 | |
| 71 | | class swim_device : public applefdc_base_device |
| 72 | | { |
| 73 | | public: |
| 74 | | swim_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 75 | | protected: |
| 76 | 84 | // device-level overrides |
| 77 | 85 | virtual void device_start(); |
| 78 | | }; |
| 86 | virtual void device_reset(); |
| 87 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 79 | 88 | |
| 80 | | extern const device_type SWIM; |
| 89 | // other protecteds |
| 90 | virtual void iwm_modereg_w(UINT8 data); |
| 81 | 91 | |
| 92 | private: |
| 93 | // data that is constant for the lifetime of the emulation |
| 94 | emu_timer * m_motor_timer; |
| 95 | applefdc_t m_type; |
| 82 | 96 | |
| 97 | // data that changes at emulation time |
| 98 | UINT8 m_write_byte; |
| 99 | UINT8 m_lines; /* flags from IWM_MOTOR - IWM_Q7 */ |
| 100 | UINT8 m_mode; /* 0-31; see above */ |
| 101 | UINT8 m_handshake_hack; /* not sure what this is for */ |
| 83 | 102 | |
| 103 | // functions |
| 104 | const applefdc_interface *get_interface(); |
| 105 | int iwm_enable2(); |
| 106 | UINT8 iwm_readenable2handshake(); |
| 107 | UINT8 statusreg_r(); |
| 108 | UINT8 read_reg(int lines); |
| 109 | void write_reg(UINT8 data); |
| 110 | void turn_motor_onoff(bool status); |
| 111 | void iwm_access(int offset); |
| 112 | }; |
| 84 | 113 | |
| 114 | |
| 115 | |
| 85 | 116 | /*************************************************************************** |
| 86 | | TYPE DEFINITIONS |
| 117 | APPLE FDC - Used on Apple II |
| 87 | 118 | ***************************************************************************/ |
| 88 | 119 | |
| 89 | | struct applefdc_interface |
| 120 | class applefdc_device : public applefdc_base_device |
| 90 | 121 | { |
| 91 | | void (*set_lines)(device_t *device, UINT8 lines); |
| 92 | | void (*set_enable_lines)(device_t *device, int enable_mask); |
| 93 | | |
| 94 | | UINT8 (*read_data)(device_t *device); |
| 95 | | void (*write_data)(device_t *device, UINT8 data); |
| 96 | | int (*read_status)(device_t *device); |
| 122 | public: |
| 123 | applefdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 97 | 124 | }; |
| 98 | 125 | |
| 99 | 126 | |
| 100 | 127 | |
| 101 | 128 | /*************************************************************************** |
| 102 | | PROTOTYPES |
| 129 | IWM - Used on early Macs |
| 103 | 130 | ***************************************************************************/ |
| 104 | | /* read/write handlers */ |
| 105 | | DECLARE_READ8_DEVICE_HANDLER(applefdc_r); |
| 106 | | DECLARE_WRITE8_DEVICE_HANDLER(applefdc_w); |
| 107 | 131 | |
| 108 | | /* accessor */ |
| 109 | | UINT8 applefdc_get_lines(device_t *device); |
| 132 | class iwm_device : public applefdc_base_device |
| 133 | { |
| 134 | public: |
| 135 | iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 136 | }; |
| 110 | 137 | |
| 138 | |
| 139 | |
| 111 | 140 | /*************************************************************************** |
| 112 | 141 | DEVICE CONFIGURATION MACROS |
| 113 | 142 | ***************************************************************************/ |
| r19778 | r19779 | |
| 128 | 157 | MCFG_DEVICE_MODIFY(_tag) \ |
| 129 | 158 | MCFG_DEVICE_CONFIG(_intrf) |
| 130 | 159 | |
| 131 | | #define MCFG_SWIM_ADD(_tag, _intrf) \ |
| 132 | | MCFG_DEVICE_ADD(_tag, SWIM, 0) \ |
| 133 | | MCFG_DEVICE_CONFIG(_intrf) |
| 134 | 160 | |
| 135 | | #define MCFG_SWIM_MODIFY(_tag, _intrf) \ |
| 136 | | MCFG_DEVICE_MODIFY(_tag) \ |
| 137 | | MCFG_DEVICE_CONFIG(_intrf) |
| 138 | | |
| 139 | | |
| 140 | 161 | #endif /* __APPLEFDC_H__ */ |