diff options
author | 2014-01-22 17:33:47 +0000 | |
---|---|---|
committer | 2014-01-22 17:33:47 +0000 | |
commit | 134c691d632d928429a171a1cf2ad782a76e0a8a (patch) | |
tree | c89135fbe443d7d3d2f7f1c7fe558b8f023d630e /src/emu/machine/mc6843.c | |
parent | c3372f0a5af569367e4acd624d4adf0d725e73ed (diff) |
Modernized mc6843 device.(nw)
Diffstat (limited to 'src/emu/machine/mc6843.c')
-rw-r--r-- | src/emu/machine/mc6843.c | 711 |
1 files changed, 334 insertions, 377 deletions
diff --git a/src/emu/machine/mc6843.c b/src/emu/machine/mc6843.c index cce3385ff10..c2bb4a68197 100644 --- a/src/emu/machine/mc6843.c +++ b/src/emu/machine/mc6843.c @@ -32,50 +32,12 @@ #include "emu.h" #include "mc6843.h" -#include "imagedev/flopdrv.h" -#include "devlegcy.h" /******************* parameters ******************/ #define VERBOSE 0 - -/******************* internal chip data structure ******************/ - -struct mc6843_t -{ - /* interface */ - const mc6843_interface* iface; - - /* registers */ - UINT8 CTAR; /* current track */ - UINT8 CMR; /* command */ - UINT8 ISR; /* interrupt status */ - UINT8 SUR; /* set-up */ - UINT8 STRA; /* status */ - UINT8 STRB; /* status */ - UINT8 SAR; /* sector address */ - UINT8 GCR; /* general count */ - UINT8 CCR; /* CRC control */ - UINT8 LTAR; /* logical address track (=track destination) */ - - /* internal state */ - UINT8 drive; - UINT8 side; - UINT8 data[128]; /* sector buffer */ - UINT32 data_size; /* size of data */ - UINT32 data_idx; /* current read/write position in data */ - UINT32 data_id; /* chrd_id for sector write */ - UINT8 index_pulse; - - /* trigger delayed actions (bottom halves) */ - emu_timer* timer_cont; - -}; - - - /* macro-command numbers */ #define CMD_STZ 0x2 /* seek track zero */ #define CMD_SEK 0x3 /* seek */ @@ -107,22 +69,122 @@ static const char *const mc6843_cmd[16] = -INLINE mc6843_t* get_safe_token( device_t *device ) + +const device_type MC6843 = &device_creator<mc6843_device>; + +mc6843_device::mc6843_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MC6843, "Motorola MC6843 floppy controller", tag, owner, clock, "mc6843", __FILE__), + m_CTAR(0), + m_CMR(0), + m_ISR(0), + m_SUR(0), + m_STRA(0), + m_STRB(0), + m_SAR(0), + m_GCR(0), + m_CCR(0), + m_LTAR(0), + m_drive(0), + m_side(0), + m_data_size(0), + m_data_idx(0), + m_data_id(0), + m_index_pulse(0), + m_timer_cont(NULL) +{ + for (int i = 0; i < 128; i++) + { + m_data[i] = 0; + } +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void mc6843_device::device_config_complete() +{ + // inherit a copy of the static data + const mc6843_interface *intf = reinterpret_cast<const mc6843_interface *>(static_config()); + if (intf != NULL) + *static_cast<mc6843_interface *>(this) = *intf; + + // or initialize to defaults if none provided + else + { + memset(&m_irq_cb, 0, sizeof(m_irq_cb)); + } +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc6843_device::device_start() { - assert( device != NULL ); - assert( device->type() == MC6843 ); - return (mc6843_t*) downcast<mc6843_device *>(device)->token(); + m_timer_cont = timer_alloc(TIMER_CONT) ; + + save_item(NAME(m_CTAR)); + save_item(NAME(m_CMR)); + save_item(NAME(m_ISR)); + save_item(NAME(m_SUR)); + save_item(NAME(m_STRA)); + save_item(NAME(m_STRB)); + save_item(NAME(m_SAR)); + save_item(NAME(m_GCR)); + save_item(NAME(m_CCR)); + save_item(NAME(m_LTAR)); + save_item(NAME(m_drive)); + save_item(NAME(m_side)); + save_item(NAME(m_data)); + save_item(NAME(m_data_size)); + save_item(NAME(m_data_idx)); + save_item(NAME(m_data_id)); } +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void mc6843_device::device_reset() +{ + int i; + LOG (( "mc6843 reset\n" )); + + /* setup/reset floppy drive */ + for ( i = 0; i < 4; i++ ) + { + device_t * img = floppy_image( i ); + floppy_mon_w(img, CLEAR_LINE); + floppy_drive_set_ready_state( img, FLOPPY_DRIVE_READY, 0 ); + floppy_drive_set_rpm( img, 300. ); + } + + m_irq_func.resolve(m_irq_cb, *this); + + /* reset registers */ + m_CMR &= 0xf0; /* zero only command */ + m_ISR = 0; + m_STRA &= 0x5c; + m_SAR = 0; + m_STRB &= 0x20; + status_update( ); + + m_data_size = 0; + m_data_idx = 0; + m_timer_cont->adjust( attotime::never ); +} /************************** floppy interface ****************************/ -static device_t* mc6843_floppy_image ( device_t *device, UINT8 drive ) +device_t* mc6843_device::floppy_image( UINT8 drive ) { - device_t *img = floppy_get_device( device->machine(), drive ); - if (!img && device->owner()) { + device_t *img = floppy_get_device( machine(), drive ); + if (!img && owner()) { // For slot devices, drives are typically attached to the slot rather than the machine const char *floppy_name = NULL; switch (drive) { @@ -139,97 +201,90 @@ static device_t* mc6843_floppy_image ( device_t *device, UINT8 drive ) floppy_name = FLOPPY_3; break; } - img = device->owner()->subdevice(floppy_name); + img = owner()->subdevice(floppy_name); } return img; } -static device_t* mc6843_floppy_image ( device_t *device ) +device_t* mc6843_device::floppy_image( ) { - mc6843_t* mc6843 = get_safe_token( device ); - return mc6843_floppy_image( device, mc6843->drive ); + return floppy_image( m_drive ); } -void mc6843_set_drive( device_t *device, int drive ) +void mc6843_device::set_drive( int drive ) { - mc6843_t* mc6843 = get_safe_token( device ); - mc6843->drive = drive; + m_drive = drive; } -void mc6843_set_side( device_t *device, int side ) +void mc6843_device::set_side( int side ) { - mc6843_t* mc6843 = get_safe_token( device ); - mc6843->side = side; + m_side = side; } /* called after ISR or STRB has changed */ -static void mc6843_status_update( device_t *device ) +void mc6843_device::status_update( ) { - mc6843_t* mc6843 = get_safe_token( device ); int irq = 0; /* ISR3 */ - if ( (mc6843->CMR & 0x40) || ! mc6843->STRB ) - mc6843->ISR &= ~8; + if ( (m_CMR & 0x40) || ! m_STRB ) + m_ISR &= ~8; else - mc6843->ISR |= 8; + m_ISR |= 8; /* interrupts */ - if ( mc6843->ISR & 4 ) + if ( m_ISR & 4 ) irq = 1; /* unmaskable */ - if ( ! (mc6843->CMR & 0x80) ) + if ( ! (m_CMR & 0x80) ) { /* maskable */ - if ( mc6843->ISR & ~4 ) + if ( m_ISR & ~4 ) irq = 1; } - if ( mc6843->iface->irq_func ) + if ( !m_irq_func.isnull() ) { - mc6843->iface->irq_func( device, irq ); - LOG(( "mc6843_status_update: irq=%i (CMR=%02X, ISR=%02X)\n", irq, mc6843->CMR, mc6843->ISR )); + m_irq_func( irq ); + LOG(( "status_update: irq=%i (CMR=%02X, ISR=%02X)\n", irq, m_CMR, m_ISR )); } } -void mc6843_set_index_pulse ( device_t *device, int index_pulse ) +void mc6843_device::set_index_pulse( int index_pulse ) { - mc6843_t* mc6843 = get_safe_token( device ); - mc6843->index_pulse = index_pulse; + m_index_pulse = index_pulse; } /* called at end of command */ -static void mc6843_cmd_end( device_t *device ) +void mc6843_device::cmd_end( ) { - mc6843_t* mc6843 = get_safe_token( device ); - int cmd = mc6843->CMR & 0x0f; + int cmd = m_CMR & 0x0f; if ( ( cmd == CMD_STZ ) || ( cmd == CMD_SEK ) ) { - mc6843->ISR |= 0x02; /* set Settling Time Complete */ + m_ISR |= 0x02; /* set Settling Time Complete */ } else { - mc6843->ISR |= 0x01; /* set Macro Command Complete */ + m_ISR |= 0x01; /* set Macro Command Complete */ } - mc6843->STRA &= ~0x80; /* clear Busy */ - mc6843->CMR &= 0xf0; /* clear command */ - mc6843_status_update( device ); + m_STRA &= ~0x80; /* clear Busy */ + m_CMR &= 0xf0; /* clear command */ + status_update( ); } /* Seek Track Zero bottom half */ -static void mc6843_finish_STZ( device_t *device ) +void mc6843_device::finish_STZ( ) { - mc6843_t* mc6843 = get_safe_token( device ); - device_t* img = mc6843_floppy_image( device ); + device_t* img = floppy_image( ); int i; /* seek to track zero */ @@ -240,74 +295,72 @@ static void mc6843_finish_STZ( device_t *device ) floppy_drive_seek( img, -1 ); } - LOG(( "%f mc6843_finish_STZ: actual=%i\n", device->machine().time().as_double(), floppy_drive_get_current_track( img ) )); + LOG(( "%f mc6843_finish_STZ: actual=%i\n", machine().time().as_double(), floppy_drive_get_current_track( img ) )); /* update state */ - mc6843->CTAR = 0; - mc6843->GCR = 0; - mc6843->SAR = 0; - mc6843->STRB |= floppy_tk00_r(img) << 4; + m_CTAR = 0; + m_GCR = 0; + m_SAR = 0; + m_STRB |= floppy_tk00_r(img) << 4; - mc6843_cmd_end( device ); + cmd_end( ); } /* Seek bottom half */ -static void mc6843_finish_SEK( device_t *device ) +void mc6843_device::finish_SEK( ) { - mc6843_t* mc6843 = get_safe_token( device ); - device_t* img = mc6843_floppy_image( device ); + device_t* img = floppy_image( ); /* seek to track */ // TODO: not sure how CTAR bit 7 is handled here, but this is the safest approach for now - floppy_drive_seek( img, mc6843->GCR - (mc6843->CTAR & 0x7F) ); + floppy_drive_seek( img, m_GCR - (m_CTAR & 0x7F) ); - LOG(( "%f mc6843_finish_SEK: from %i to %i (actual=%i)\n", device->machine().time().as_double(), (mc6843->CTAR & 0x7F), mc6843->GCR, floppy_drive_get_current_track( img ) )); + LOG(( "%f mc6843_finish_SEK: from %i to %i (actual=%i)\n", machine().time().as_double(), (m_CTAR & 0x7F), m_GCR, floppy_drive_get_current_track( img ) )); /* update state */ - mc6843->CTAR = mc6843->GCR; - mc6843->SAR = 0; - mc6843_cmd_end( device ); + m_CTAR = m_GCR; + m_SAR = 0; + cmd_end( ); } /* preamble to all sector read / write commands, returns 1 if found */ -static int mc6843_address_search( device_t *device, chrn_id* id ) +int mc6843_device::address_search( chrn_id* id ) { - mc6843_t* mc6843 = get_safe_token( device ); - device_t* img = mc6843_floppy_image( device ); + device_t* img = floppy_image( ); int r = 0; while ( 1 ) { - if ( ( ! floppy_drive_get_next_id( img, mc6843->side, id ) ) || ( id->flags & ID_FLAG_CRC_ERROR_IN_ID_FIELD ) || ( id->N != 0 ) ) + if ( ( ! floppy_drive_get_next_id( img, m_side, id ) ) || ( id->flags & ID_FLAG_CRC_ERROR_IN_ID_FIELD ) || ( id->N != 0 ) ) { /* read address error */ - LOG(( "%f mc6843_address_search: get_next_id failed\n", device->machine().time().as_double() )); - mc6843->STRB |= 0x0a; /* set CRC error & Sector Address Undetected */ - mc6843_cmd_end( device ); + LOG(( "%f mc6843_address_search: get_next_id failed\n", machine().time().as_double() )); + m_STRB |= 0x0a; /* set CRC error & Sector Address Undetected */ + cmd_end( ); return 0; } - if ( id->C != mc6843->LTAR ) + if ( id->C != m_LTAR ) { /* track mismatch */ - LOG(( "%f mc6843_address_search: track mismatch: logical=%i real=%i\n", device->machine().time().as_double(), mc6843->LTAR, id->C )); - mc6843->data[0] = id->C; /* make the track number available to the CPU */ - mc6843->STRA |= 0x20; /* set Track Not Equal */ - mc6843_cmd_end( device ); + LOG(( "%f mc6843_address_search: track mismatch: logical=%i real=%i\n", machine().time().as_double(), m_LTAR, id->C )); + m_data[0] = id->C; /* make the track number available to the CPU */ + m_STRA |= 0x20; /* set Track Not Equal */ + cmd_end( ); return 0; } - if ( id->R == mc6843->SAR ) + if ( id->R == m_SAR ) { /* found! */ - LOG(( "%f mc6843_address_search: sector %i found on track %i\n", device->machine().time().as_double(), id->R, id->C )); - if ( ! (mc6843->CMR & 0x20) ) + LOG(( "%f mc6843_address_search: sector %i found on track %i\n", machine().time().as_double(), id->R, id->C )); + if ( ! (m_CMR & 0x20) ) { - mc6843->ISR |= 0x04; /* if no DMA, set Status Sense */ + m_ISR |= 0x04; /* if no DMA, set Status Sense */ } return 1; } @@ -318,9 +371,9 @@ static int mc6843_address_search( device_t *device, chrn_id* id ) if ( r >= 4 ) { /* time-out after 3 full revolutions */ - LOG(( "%f mc6843_address_search: no sector %i found after 3 revolutions\n", device->machine().time().as_double(), mc6843->SAR )); - mc6843->STRB |= 0x08; /* set Sector Address Undetected */ - mc6843_cmd_end( device ); + LOG(( "%f mc6843_address_search: no sector %i found after 3 revolutions\n", machine().time().as_double(), m_SAR )); + m_STRB |= 0x08; /* set Sector Address Undetected */ + cmd_end( ); return 0; } } @@ -332,24 +385,23 @@ static int mc6843_address_search( device_t *device, chrn_id* id ) /* preamble specific to read commands (adds extra checks) */ -static int mc6843_address_search_read( device_t *device, chrn_id* id ) +int mc6843_device::address_search_read( chrn_id* id ) { - mc6843_t* mc6843 = get_safe_token( device ); - if ( ! mc6843_address_search( device, id ) ) + if ( ! address_search( id ) ) return 0; if ( id->flags & ID_FLAG_CRC_ERROR_IN_DATA_FIELD ) { - LOG(( "%f mc6843_address_search_read: data CRC error\n", device->machine().time().as_double() )); - mc6843->STRB |= 0x06; /* set CRC error & Data Mark Undetected */ - mc6843_cmd_end( device ); + LOG(( "%f mc6843_address_search_read: data CRC error\n", machine().time().as_double() )); + m_STRB |= 0x06; /* set CRC error & Data Mark Undetected */ + cmd_end( ); return 0; } if ( id->flags & ID_FLAG_DELETED_DATA ) { - LOG(( "%f mc6843_address_search_read: deleted data\n", device->machine().time().as_double() )); - mc6843->STRA |= 0x02; /* set Delete Data Mark Detected */ + LOG(( "%f mc6843_address_search_read: deleted data\n", machine().time().as_double() )); + m_STRA |= 0x02; /* set Delete Data Mark Detected */ } return 1; @@ -359,78 +411,84 @@ static int mc6843_address_search_read( device_t *device, chrn_id* id ) /* Read CRC bottom half */ -static void mc6843_finish_RCR( device_t *device ) +void mc6843_device::finish_RCR( ) { chrn_id id; - if ( ! mc6843_address_search_read( device, &id ) ) + if ( ! address_search_read( &id ) ) return; - mc6843_cmd_end( device ); + cmd_end( ); } /* Single / Multiple Sector Read bottom half */ -static void mc6843_cont_SR( device_t *device ) +void mc6843_device::cont_SR( ) { - mc6843_t* mc6843 = get_safe_token( device ); chrn_id id; - device_t* img = mc6843_floppy_image( device ); + device_t* img = floppy_image( ); /* sector seek */ - if ( ! mc6843_address_search_read( device, &id ) ) + if ( ! address_search_read( &id ) ) return; /* sector read */ - floppy_drive_read_sector_data( img, mc6843->side, id.data_id, mc6843->data, 128 ); - mc6843->data_idx = 0; - mc6843->data_size = 128; - mc6843->STRA |= 0x01; /* set Data Transfer Request */ - mc6843_status_update( device ); + floppy_drive_read_sector_data( img, m_side, id.data_id, m_data, 128 ); + m_data_idx = 0; + m_data_size = 128; + m_STRA |= 0x01; /* set Data Transfer Request */ + status_update( ); } /* Single / Multiple Sector Write bottom half */ -static void mc6843_cont_SW( device_t *device ) +void mc6843_device::cont_SW( ) { - mc6843_t* mc6843 = get_safe_token( device ); chrn_id id; /* sector seek */ - if ( ! mc6843_address_search( device, &id ) ) + if ( ! address_search( &id ) ) return; /* setup sector write buffer */ - mc6843->data_idx = 0; - mc6843->data_size = 128; - mc6843->STRA |= 0x01; /* set Data Transfer Request */ - mc6843->data_id = id.data_id; /* for subsequent write sector command */ - mc6843_status_update( device ); + m_data_idx = 0; + m_data_size = 128; + m_STRA |= 0x01; /* set Data Transfer Request */ + m_data_id = id.data_id; /* for subsequent write sector command */ + status_update( ); } /* bottom halves, called to continue / finish a command after some delay */ -static TIMER_CALLBACK( mc6843_cont ) +void mc6843_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - device_t* device = (device_t*) ptr; - mc6843_t* mc6843 = get_safe_token( device ); - int cmd = mc6843->CMR & 0x0f; + switch (id) + { + case TIMER_CONT: + { + int cmd = m_CMR & 0x0f; - LOG(( "%f mc6843_cont: timer called for cmd=%s(%i)\n", device->machine().time().as_double(), mc6843_cmd[cmd], cmd )); + LOG(( "%f mc6843_cont: timer called for cmd=%s(%i)\n", machine().time().as_double(), mc6843_cmd[cmd], cmd )); - mc6843->timer_cont->adjust( attotime::never ); + m_timer_cont->adjust( attotime::never ); - switch ( cmd ) - { - case CMD_STZ: mc6843_finish_STZ( device ); break; - case CMD_SEK: mc6843_finish_SEK( device ); break; - case CMD_SSR: mc6843_cont_SR( device ); break; - case CMD_SSW: mc6843_cont_SW( device ); break; - case CMD_RCR: mc6843_finish_RCR( device ); break; - case CMD_SWD: mc6843_cont_SW( device ); break; - case CMD_MSW: mc6843_cont_SW( device ); break; - case CMD_MSR: mc6843_cont_SR( device ); break; + switch ( cmd ) + { + case CMD_STZ: finish_STZ( ); break; + case CMD_SEK: finish_SEK( ); break; + case CMD_SSR: cont_SR( ); break; + case CMD_SSW: cont_SW( ); break; + case CMD_RCR: finish_RCR( ); break; + case CMD_SWD: cont_SW( ); break; + case CMD_MSW: cont_SW( ); break; + case CMD_MSR: cont_SR( ); break; + } + } + break; + + default: + break; } } @@ -440,71 +498,70 @@ static TIMER_CALLBACK( mc6843_cont ) -READ8_DEVICE_HANDLER ( mc6843_r ) +READ8_MEMBER( mc6843_device::read ) { - mc6843_t* mc6843 = get_safe_token( device ); UINT8 data = 0; switch ( offset ) { case 0: /* Data Input Register (DIR) */ { - int cmd = mc6843->CMR & 0x0f; + int cmd = m_CMR & 0x0f; LOG(( "%f $%04x mc6843_r: data input cmd=%s(%i), pos=%i/%i, GCR=%i, ", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), - mc6843_cmd[cmd], cmd, mc6843->data_idx, - mc6843->data_size, mc6843->GCR )); + machine().time().as_double(), machine().firstcpu->pcbase( ), + mc6843_cmd[cmd], cmd, m_data_idx, + m_data_size, m_GCR )); if ( cmd == CMD_SSR || cmd == CMD_MSR ) { /* sector read */ - assert( mc6843->data_size > 0 ); - assert( mc6843->data_idx < mc6843->data_size ); - assert( mc6843->data_idx < sizeof(mc6843->data) ); - data = mc6843->data[ mc6843->data_idx ]; - mc6843->data_idx++; + assert( m_data_size > 0 ); + assert( m_data_idx < m_data_size ); + assert( m_data_idx < sizeof(m_data) ); + data = m_data[ m_data_idx ]; + m_data_idx++; - if ( mc6843->data_idx >= mc6843->data_size ) + if ( m_data_idx >= m_data_size ) { /* end of sector read */ - mc6843->STRA &= ~0x01; /* clear Data Transfer Request */ + m_STRA &= ~0x01; /* clear Data Transfer Request */ if ( cmd == CMD_MSR ) { /* schedule next sector in multiple sector read */ - mc6843->GCR--; - mc6843->SAR++; - if ( mc6843->GCR == 0xff ) + m_GCR--; + m_SAR++; + if ( m_GCR == 0xff ) { - mc6843_cmd_end( device ); + cmd_end( ); } - else if ( mc6843->SAR > 26 ) + else if ( m_SAR > 26 ) { - mc6843->STRB |= 0x08; /* set Sector Address Undetected */ - mc6843_cmd_end( device ); + m_STRB |= 0x08; /* set Sector Address Undetected */ + cmd_end( ); } else { - mc6843->timer_cont->adjust( DELAY_ADDR ); + m_timer_cont->adjust( DELAY_ADDR ); } } else { - mc6843_cmd_end( device ); + cmd_end( ); } } } else if ( cmd == 0 ) { - data = mc6843->data[0]; + data = m_data[0]; } else { /* XXX TODO: other read modes */ - data = mc6843->data[0]; - logerror( "$%04x mc6843 read in unsupported command mode %i\n", space.machine().firstcpu->pcbase( ), cmd ); + data = m_data[0]; + logerror( "$%04x mc6843 read in unsupported command mode %i\n", machine().firstcpu->pcbase( ), cmd ); } LOG(( "data=%02X\n", data )); @@ -513,131 +570,130 @@ READ8_DEVICE_HANDLER ( mc6843_r ) } case 1: /* Current-Track Address Register (CTAR) */ - data = mc6843->CTAR; + data = m_CTAR; LOG(( "%f $%04x mc6843_r: read CTAR %i (actual=%i)\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), data, - floppy_drive_get_current_track( mc6843_floppy_image( device ) ) )); + machine().time().as_double(), machine().firstcpu->pcbase( ), data, + floppy_drive_get_current_track( floppy_image( ) ) )); break; case 2: /* Interrupt Status Register (ISR) */ - data = mc6843->ISR; + data = m_ISR; LOG(( "%f $%04x mc6843_r: read ISR %02X: cmd=%scomplete settle=%scomplete sense-rq=%i STRB=%i\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), data, + machine().time().as_double(), machine().firstcpu->pcbase( ), data, (data & 1) ? "" : "not-" , (data & 2) ? "" : "not-", (data >> 2) & 1, (data >> 3) & 1 )); /* reset */ - mc6843->ISR &= 8; /* keep STRB */ - mc6843_status_update( device ); + m_ISR &= 8; /* keep STRB */ + status_update( ); break; case 3: /* Status Register A (STRA) */ { /* update */ - device_t* img = mc6843_floppy_image( device ); + device_t* img = floppy_image( ); int flag = floppy_drive_get_flag_state( img, FLOPPY_DRIVE_READY); - mc6843->STRA &= 0xa3; + m_STRA &= 0xa3; if ( flag & FLOPPY_DRIVE_READY ) - mc6843->STRA |= 0x04; + m_STRA |= 0x04; - mc6843->STRA |= !floppy_tk00_r(img) << 3; - mc6843->STRA |= !floppy_wpt_r(img) << 4; + m_STRA |= !floppy_tk00_r(img) << 3; + m_STRA |= !floppy_wpt_r(img) << 4; - if ( mc6843->index_pulse ) - mc6843->STRA |= 0x40; + if ( m_index_pulse ) + m_STRA |= 0x40; - data = mc6843->STRA; + data = m_STRA; LOG(( "%f $%04x mc6843_r: read STRA %02X: data-rq=%i del-dta=%i ready=%i t0=%i wp=%i trk-dif=%i idx=%i busy=%i\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), data, + machine().time().as_double(), machine().firstcpu->pcbase( ), data, data & 1, (data >> 1) & 1, (data >> 2) & 1, (data >> 3) & 1, (data >> 4) & 1, (data >> 5) & 1, (data >> 6) & 1, (data >> 7) & 1 )); break; } case 4: /* Status Register B (STRB) */ - data = mc6843->STRB; + data = m_STRB; LOG(( "%f $%04x mc6843_r: read STRB %02X: data-err=%i CRC-err=%i dta--mrk-err=%i sect-mrk-err=%i seek-err=%i fi=%i wr-err=%i hard-err=%i\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), data, + machine().time().as_double(), machine().firstcpu->pcbase( ), data, data & 1, (data >> 1) & 1, (data >> 2) & 1, (data >> 3) & 1, (data >> 4) & 1, (data >> 5) & 1, (data >> 6) & 1, (data >> 7) & 1 )); /* (partial) reset */ - mc6843->STRB &= ~0xfb; - mc6843_status_update( device ); + m_STRB &= ~0xfb; + status_update( ); break; case 7: /* Logical-Track Address Register (LTAR) */ - data = mc6843->LTAR; + data = m_LTAR; LOG(( "%f $%04x mc6843_r: read LTAR %i (actual=%i)\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), data, - floppy_drive_get_current_track( mc6843_floppy_image( device ) ) )); + machine().time().as_double(), machine().firstcpu->pcbase( ), data, + floppy_drive_get_current_track( floppy_image( ) ) )); break; default: - logerror( "$%04x mc6843 invalid read offset %i\n", space.machine().firstcpu->pcbase( ), offset ); + logerror( "$%04x mc6843 invalid read offset %i\n", machine().firstcpu->pcbase( ), offset ); } return data; } -WRITE8_DEVICE_HANDLER ( mc6843_w ) +WRITE8_MEMBER( mc6843_device::write ) { - mc6843_t* mc6843 = get_safe_token( device ); switch ( offset ) { case 0: /* Data Output Register (DOR) */ { - int cmd = mc6843->CMR & 0x0f; - int FWF = (mc6843->CMR >> 4) & 1; + int cmd = m_CMR & 0x0f; + int FWF = (m_CMR >> 4) & 1; LOG(( "%f $%04x mc6843_w: data output cmd=%s(%i), pos=%i/%i, GCR=%i, data=%02X\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), - mc6843_cmd[cmd], cmd, mc6843->data_idx, - mc6843->data_size, mc6843->GCR, data )); + machine().time().as_double(), machine().firstcpu->pcbase( ), + mc6843_cmd[cmd], cmd, m_data_idx, + m_data_size, m_GCR, data )); if ( cmd == CMD_SSW || cmd == CMD_MSW || cmd == CMD_SWD ) { /* sector write */ - assert( mc6843->data_size > 0 ); - assert( mc6843->data_idx < mc6843->data_size ); - assert( mc6843->data_idx < sizeof(mc6843->data) ); - mc6843->data[ mc6843->data_idx ] = data; - mc6843->data_idx++; - if ( mc6843->data_idx >= mc6843->data_size ) + assert( m_data_size > 0 ); + assert( m_data_idx < m_data_size ); + assert( m_data_idx < sizeof(m_data) ); + m_data[ m_data_idx ] = data; + m_data_idx++; + if ( m_data_idx >= m_data_size ) { /* end of sector write */ - device_t* img = mc6843_floppy_image( device ); + device_t* img = floppy_image( ); - LOG(( "%f $%04x mc6843_w: write sector %i\n", space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), mc6843->data_id )); + LOG(( "%f $%04x mc6843_w: write sector %i\n", machine().time().as_double(), machine().firstcpu->pcbase( ), m_data_id )); floppy_drive_write_sector_data( - img, mc6843->side, mc6843->data_id, - mc6843->data, mc6843->data_size, + img, m_side, m_data_id, + m_data, m_data_size, (cmd == CMD_SWD) ? ID_FLAG_DELETED_DATA : 0 ); - mc6843->STRA &= ~0x01; /* clear Data Transfer Request */ + m_STRA &= ~0x01; /* clear Data Transfer Request */ if ( cmd == CMD_MSW ) { - mc6843->GCR--; - mc6843->SAR++; - if ( mc6843->GCR == 0xff ) + m_GCR--; + m_SAR++; + if ( m_GCR == 0xff ) { - mc6843_cmd_end( device ); + cmd_end( ); } - else if ( mc6843->SAR > 26 ) + else if ( m_SAR > 26 ) { - mc6843->STRB |= 0x08; /* set Sector Address Undetected */ - mc6843_cmd_end( device ); + m_STRB |= 0x08; /* set Sector Address Undetected */ + cmd_end( ); } else { - mc6843->timer_cont->adjust( DELAY_ADDR ); + m_timer_cont->adjust( DELAY_ADDR ); } } else { - mc6843_cmd_end( device ); + cmd_end( ); } } } @@ -651,39 +707,39 @@ WRITE8_DEVICE_HANDLER ( mc6843_w ) ((data & 0x10) >> 2 )| ((data & 0x40) >> 3 ); - assert( mc6843->data_idx < sizeof(mc6843->data) ); + assert( m_data_idx < sizeof(m_data) ); - mc6843->data[mc6843->data_idx / 2] = - (mc6843->data[mc6843->data_idx / 2] << 4) | nibble; + m_data[m_data_idx / 2] = + (m_data[m_data_idx / 2] << 4) | nibble; - if ( (mc6843->data_idx == 0) && (mc6843->data[0] == 0xfe ) ) + if ( (m_data_idx == 0) && (m_data[0] == 0xfe ) ) { /* address mark detected */ - mc6843->data_idx = 2; + m_data_idx = 2; } - else if ( mc6843->data_idx == 9 ) + else if ( m_data_idx == 9 ) { /* address id field complete */ - if ( (mc6843->data[2] == 0) && (mc6843->data[4] == 0) ) + if ( (m_data[2] == 0) && (m_data[4] == 0) ) { /* valid address id field */ - device_t* img = mc6843_floppy_image( device ); - UINT8 track = mc6843->data[1]; - UINT8 sector = mc6843->data[3]; + device_t* img = floppy_image( ); + UINT8 track = m_data[1]; + UINT8 sector = m_data[3]; UINT8 filler = 0xe5; /* standard Thomson filler */ - LOG(( "%f $%04x mc6843_w: address id detected track=%i sector=%i\n", space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), track, sector)); - floppy_drive_format_sector( img, mc6843->side, sector, track, 0, sector, 0, filler ); + LOG(( "%f $%04x mc6843_w: address id detected track=%i sector=%i\n", machine().time().as_double(), machine().firstcpu->pcbase( ), track, sector)); + floppy_drive_format_sector( img, m_side, sector, track, 0, sector, 0, filler ); } else { /* abort */ - mc6843->data_idx = 0; + m_data_idx = 0; } } - else if ( mc6843->data_idx > 0 ) + else if ( m_data_idx > 0 ) { /* accumulate address id field */ - mc6843->data_idx++; + m_data_idx++; } } else if ( cmd == 0 ) @@ -693,16 +749,16 @@ WRITE8_DEVICE_HANDLER ( mc6843_w ) else { /* XXX TODO: other write modes */ - logerror( "$%04x mc6843 write %02X in unsupported command mode %i (FWF=%i)\n", space.machine().firstcpu->pcbase( ), data, cmd, FWF ); + logerror( "$%04x mc6843 write %02X in unsupported command mode %i (FWF=%i)\n", machine().firstcpu->pcbase( ), data, cmd, FWF ); } break; } case 1: /* Current-Track Address Register (CTAR) */ - mc6843->CTAR = data; + m_CTAR = data; LOG(( "%f $%04x mc6843_w: set CTAR to %i %02X (actual=%i) \n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), mc6843->CTAR, data, - floppy_drive_get_current_track( mc6843_floppy_image( device ) ) )); + machine().time().as_double(), machine().firstcpu->pcbase( ), m_CTAR, data, + floppy_drive_get_current_track( floppy_image( ) ) )); break; case 2: /* Command Register (CMR) */ @@ -710,14 +766,14 @@ WRITE8_DEVICE_HANDLER ( mc6843_w ) int cmd = data & 15; LOG(( "%f $%04x mc6843_w: set CMR to $%02X: cmd=%s(%i) FWF=%i DMA=%i ISR3-intr=%i fun-intr=%i\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), + machine().time().as_double(), machine().firstcpu->pcbase( ), data, mc6843_cmd[cmd], cmd, (data >> 4) & 1, (data >> 5) & 1, (data >> 6) & 1, (data >> 7) & 1 )); /* sanitize state */ - mc6843->STRA &= ~0x81; /* clear Busy & Data Transfer Request */ - mc6843->data_idx = 0; - mc6843->data_size = 0; + m_STRA &= ~0x81; /* clear Busy & Data Transfer Request */ + m_data_idx = 0; + m_data_size = 0; /* commands are initiated by updating some flags and scheduling a bottom-half (mc6843_cont) after some delay */ @@ -730,161 +786,62 @@ WRITE8_DEVICE_HANDLER ( mc6843_w ) case CMD_RCR: case CMD_MSR: case CMD_MSW: - mc6843->STRA |= 0x80; /* set Busy */ - mc6843->STRA &= ~0x22; /* clear Track Not Equal & Delete Data Mark Detected */ - mc6843->STRB &= ~0x04; /* clear Data Mark Undetected */ - mc6843->timer_cont->adjust( DELAY_ADDR ); + m_STRA |= 0x80; /* set Busy */ + m_STRA &= ~0x22; /* clear Track Not Equal & Delete Data Mark Detected */ + m_STRB &= ~0x04; /* clear Data Mark Undetected */ + m_timer_cont->adjust( DELAY_ADDR ); break; case CMD_STZ: case CMD_SEK: - mc6843->STRA |= 0x80; /* set Busy */ - mc6843->timer_cont->adjust( DELAY_SEEK ); + m_STRA |= 0x80; /* set Busy */ + m_timer_cont->adjust( DELAY_SEEK ); break; case CMD_FFW: case CMD_FFR: - mc6843->data_idx = 0; - mc6843->STRA |= 0x01; /* set Data Transfer Request */ + m_data_idx = 0; + m_STRA |= 0x01; /* set Data Transfer Request */ break; } - mc6843->CMR = data; - mc6843_status_update( device ); + m_CMR = data; + status_update( ); break; } case 3: /* Set-Up Register (SUR) */ - mc6843->SUR = data; + m_SUR = data; /* assume CLK freq = 1MHz (IBM 3740 compatibility) */ LOG(( "%f $%04x mc6843_w: set SUR to $%02X: head settling time=%fms, track-to-track seek time=%f\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), + machine().time().as_double(), machine().firstcpu->pcbase( ), data, 4.096 * (data & 15), 1.024 * ((data >> 4) & 15) )); break; case 4: /* Sector Address Register (SAR) */ - mc6843->SAR = data & 0x1f; - LOG(( "%f $%04x mc6843_w: set SAR to %i (%02X)\n", space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), mc6843->SAR, data )); + m_SAR = data & 0x1f; + LOG(( "%f $%04x mc6843_w: set SAR to %i (%02X)\n", machine().time().as_double(), machine().firstcpu->pcbase( ), m_SAR, data )); break; case 5: /* General Count Register (GCR) */ - mc6843->GCR = data & 0x7f; - LOG(( "%f $%04x mc6843_w: set GCR to %i (%02X)\n", space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), mc6843->GCR, data )); + m_GCR = data & 0x7f; + LOG(( "%f $%04x mc6843_w: set GCR to %i (%02X)\n", machine().time().as_double(), machine().firstcpu->pcbase( ), m_GCR, data )); break; case 6: /* CRC Control Register (CCR) */ - mc6843->CCR = data & 3; + m_CCR = data & 3; LOG(( "%f $%04x mc6843_w: set CCR to %02X: CRC=%s shift=%i\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), data, + machine().time().as_double(), machine().firstcpu->pcbase( ), data, (data & 1) ? "enabled" : "disabled", (data >> 1) & 1 )); break; case 7: /* Logical-Track Address Register (LTAR) */ - mc6843->LTAR = data & 0x7f; + m_LTAR = data & 0x7f; LOG(( "%f $%04x mc6843_w: set LTAR to %i %02X (actual=%i)\n", - space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), mc6843->LTAR, data, - floppy_drive_get_current_track( mc6843_floppy_image( device ) ) )); + machine().time().as_double(), machine().firstcpu->pcbase( ), m_LTAR, data, + floppy_drive_get_current_track( floppy_image( ) ) )); break; default: - logerror( "$%04x mc6843 invalid write offset %i (data=$%02X)\n", space.machine().firstcpu->pcbase( ), offset, data ); - } -} - - - -/************************ reset *****************************/ - -static DEVICE_RESET( mc6843 ) -{ - mc6843_t* mc6843 = get_safe_token( device ); - int i; - LOG (( "mc6843 reset\n" )); - - /* setup/reset floppy drive */ - for ( i = 0; i < 4; i++ ) - { - device_t * img = mc6843_floppy_image( device, i ); - floppy_mon_w(img, CLEAR_LINE); - floppy_drive_set_ready_state( img, FLOPPY_DRIVE_READY, 0 ); - floppy_drive_set_rpm( img, 300. ); + logerror( "$%04x mc6843 invalid write offset %i (data=$%02X)\n", machine().firstcpu->pcbase( ), offset, data ); } - - /* reset registers */ - mc6843->CMR &= 0xf0; /* zero only command */ - mc6843->ISR = 0; - mc6843->STRA &= 0x5c; - mc6843->SAR = 0; - mc6843->STRB &= 0x20; - mc6843_status_update( device ); - - mc6843->data_size = 0; - mc6843->data_idx = 0; - mc6843->timer_cont->adjust( attotime::never ); -} - - - -/************************ start *****************************/ - -static DEVICE_START( mc6843 ) -{ - mc6843_t* mc6843 = get_safe_token( device ); - - mc6843->iface = (const mc6843_interface*)device->static_config(); - - mc6843->timer_cont = device->machine().scheduler().timer_alloc(FUNC(mc6843_cont), (void*) device) ; - - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->CTAR ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->CMR ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->ISR ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->SUR ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->STRA ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->STRB ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->SAR ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->GCR ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->CCR ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->LTAR ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->drive ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->side ); - state_save_register_item_array( device->machine(),"mc6843", device->tag(), 0, mc6843->data ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->data_size ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->data_idx ); - state_save_register_item( device->machine(),"mc6843", device->tag(), 0, mc6843->data_id ); -} - - -const device_type MC6843 = &device_creator<mc6843_device>; - -mc6843_device::mc6843_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, MC6843, "Motorola MC6843 floppy controller", tag, owner, clock, "mc6843", __FILE__) -{ - m_token = global_alloc_clear(mc6843_t); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void mc6843_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void mc6843_device::device_start() -{ - DEVICE_START_NAME( mc6843 )(this); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void mc6843_device::device_reset() -{ - DEVICE_RESET_NAME( mc6843 )(this); } |