Previous 199869 Revisions Next

r32115 Sunday 14th September, 2014 at 20:19:37 UTC by Michael Zapf
(MESS) hdc9234 WIP: Some intermediate cleanups. Also, guard HFDC against
debugger.(nw)
[src/emu/bus/ti99_peb]hfdc.c
[src/emu/machine]hdc9234.c hdc9234.h

trunk/src/emu/bus/ti99_peb/hfdc.c
r32114r32115
9494{
9595}
9696
97
9897SETADDRESS_DBIN_MEMBER( myarc_hfdc_device::setaddress_dbin )
9998{
99   // Debugger does not run safely with HFDC
100   // TODO: Check why debugger messes up the access (likely to happen at other locations, too)
101   if (space.debugger_access()) return;
102
100103   // Selection login in the PAL and some circuits on the board
101104
102105   // Is the card being selected?
103106   // Area = 4000-5fff
104107   // 010x xxxx xxxx xxxx
105108   m_address = offset;
109
106110   m_inDsrArea = ((m_address & m_select_mask)==m_select_value);
107111
108112   if (!m_inDsrArea) return;
r32114r32115
151155*/
152156READ8Z_MEMBER(myarc_hfdc_device::readz)
153157{
158   // Debugger does not run safely with HFDC
159   if (space.debugger_access()) return;
160
154161   if (m_inDsrArea && m_selected)
155162   {
156163      if (m_tapesel)
r32114r32115
161168
162169      if (m_HDCsel)
163170      {
164         if (!space.debugger_access()) *value = m_hdc9234->read(space, (m_address>>2)&1, 0xff);
171         *value = m_hdc9234->read(space, (m_address>>2)&1, 0xff);
165172         if (TRACE_COMP) logerror("%s: %04x[HDC] -> %02x\n", tag(), m_address & 0xffff, *value);
166173         return;
167174      }
168175
169176      if (m_RTCsel)
170177      {
171         if (!space.debugger_access()) *value = m_clock->read(space, (m_address & 0x001e) >> 1);
178         *value = m_clock->read(space, (m_address & 0x001e) >> 1);
172179         if (TRACE_COMP) logerror("%s: %04x[CLK] -> %02x\n", tag(), m_address & 0xffff, *value);
173180         return;
174181      }
r32114r32115
222229*/
223230WRITE8_MEMBER( myarc_hfdc_device::write )
224231{
232   // Debugger does not run safely with HFDC
233   if (space.debugger_access()) return;
234
225235   if (m_inDsrArea && m_selected)
226236   {
227237      if (m_tapesel)
r32114r32115
233243      if (m_HDCsel)
234244      {
235245         if (TRACE_COMP) logerror("%s: %04x[HDC] <- %02x\n", tag(), m_address & 0xffff, data);
236         if (!space.debugger_access()) m_hdc9234->write(space, (m_address>>2)&1, data, 0xff);
246         m_hdc9234->write(space, (m_address>>2)&1, data, 0xff);
237247         return;
238248      }
239249
240250      if (m_RTCsel)
241251      {
242252         if (TRACE_COMP) logerror("%s: %04x[CLK] <- %02x\n", tag(), m_address & 0xffff, data);
243         if (!space.debugger_access()) m_clock->write(space, (m_address & 0x001e) >> 1, data);
253         m_clock->write(space, (m_address & 0x001e) >> 1, data);
244254         return;
245255      }
246256
trunk/src/emu/machine/hdc9234.c
r32114r32115
1// license:BSD-3-Clause
2// copyright-holders:Michael Zapf
13/**************************************************************************
24
35    HDC9234 Hard and Floppy Disk Controller
r32114r32115
190192   OUT2_HEADSEL    = 0x0f
191193};
192194
195#define NODRIVE -1
196
193197enum
194198{
195199   TYPE_AT = 0x00,
r32114r32115
229233static const int step_flop5[]   = { 436, 1000, 2000, 4000, 8000, 16000, 32000, 64000 };
230234
231235/*
236    Head load timer increments in usec. Delay value is calculated from this value
237    multiplied by the factor in the DATA/DELAY register. For FM mode all
238    values are doubled. The values depend on the drive type.
239*/
240static const int head_load_timer_increment[] = { 200, 200, 2000, 4000 };
241
242/*
232243    ID fields association to registers
233244*/
234245static const int id_field[] = { CURRENT_CYLINDER, CURRENT_HEAD, CURRENT_SECTOR, CURRENT_SIZE, CURRENT_CRC1, CURRENT_CRC2 };
r32114r32115
265276   RESTORE_CHECK1,
266277   RESTORE_CHECK2,
267278   SEEK_COMPLETE,
279   HEAD_DELAY,
268280
269281   READ_ID = 0x40,
270282   READ_ID1,
r32114r32115
312324
313325const hdc9234_device::cmddef hdc9234_device::s_command[] =
314326{
315   { 0x00, 0xff, &hdc9234_device::device_reset },
327   { 0x00, 0xff, &hdc9234_device::reset_controller },
316328   { 0x01, 0xff, &hdc9234_device::drive_deselect },
317329   { 0x02, 0xfe, &hdc9234_device::restore_drive },
318330   { 0x04, 0xfc, &hdc9234_device::step_drive },
r32114r32115
510522         // If an error occured (no IDAM found), terminate the command
511523         if ((m_register_r[CHIP_STATUS] & CS_SYNCERR) != 0)
512524         {
513            logerror("%s: READ_ID failed to find an IDAM\n", tag());
525            logerror("%s: READ_ID failed to find any IDAM\n", tag());
514526            cont = ERROR;
515527            break;
516528         }
r32114r32115
602614         // (This test is only relevant when we did not have a seek phase before)
603615         if ((m_register_r[CHIP_STATUS] & CS_SYNCERR) != 0)
604616         {
605            logerror("%s: VERIFY failed to find an IDAM\n", tag());
617            logerror("%s: VERIFY failed to find any IDAM\n", tag());
606618            cont = ERROR;
607619            break;
608620         }
r32114r32115
853865// ===========================================================================
854866
855867/*
868    RESET
869*/
870void hdc9234_device::reset_controller()
871{
872   if (TRACE_COMMAND) logerror("%s: RESET command\n", tag());
873   device_reset();
874}
875/*
856876    DESELECT DRIVE
857    done when no drive is in use
858877*/
859878void hdc9234_device::drive_deselect()
860879{
861880   if (TRACE_COMMAND) logerror("%s: DESELECT command\n", tag());
862   set_bits(m_output1, OUT1_DRVSEL3|OUT1_DRVSEL2|OUT1_DRVSEL1|OUT1_DRVSEL0, false);
881   m_selected_drive_number = NODRIVE;
863882   auxbus_out();
864883   set_command_done(TC_SUCCESS);
865884}
866885
867886/*
868    Step on / off; used by RESTORE and STEP IN/OUT
869*/
870void hdc9234_device::step_on(bool towards00, int next)
871{
872   if (TRACE_ACT) logerror("%s: substate STEP_ON\n", tag());
873
874   // STEPDIR = 0 -> towards TRK00
875   set_bits(m_output2, OUT2_STEPDIR, !towards00);
876
877   // Raising edge (note that all signals must be inverted before leading them to the drive)
878   set_bits(m_output2, OUT2_STEPPULSE, true);
879   auxbus_out();
880   wait_time(m_timer, pulse_width(), next);
881}
882
883void hdc9234_device::step_off(int next)
884{
885   if (TRACE_ACT) logerror("%s: substate STEP_OFF\n", tag());
886   set_bits(m_output2, OUT2_STEPPULSE, false);
887   auxbus_out();
888   wait_time(m_timer, step_time(), next);
889}
890
891/*
892887    // RESTORE DRIVE
893888    // bit 0:
894889    // 0 -> command ends after last seek pulse,
r32114r32115
10231018
10241019void hdc9234_device::drive_select()
10251020{
1026   int driveparm = current_command() & 0x1f;
1021   int cont = CONTINUE;
1022   int head_load_delay = 0;
10271023
1028   m_output1 = (0x10 << (driveparm & 0x03)) | (m_register_w[RETRY_COUNT]&0x0f);
1024   if (m_substate == UNDEF)
1025   {
1026      int driveparm = current_command() & 0x1f;
1027      bool head_load_delay_enable = (driveparm & 0x10)!=0;
10291028
1030   // The drive type is used to configure DMA burst mode ([1], p.12)
1031   // and to select the timing parameters
1032   m_selected_drive_type = (driveparm>>2) & 0x03;
1033   m_head_load_delay_enable = (driveparm>>4)&0x01;
1029      // The drive type is used to configure DMA burst mode ([1], p.12)
1030      // and to select the timing parameters
1031      m_selected_drive_type = (driveparm>>2) & 0x03;
1032      m_selected_drive_number = driveparm & 0x03;
10341033
1035   if (TRACE_COMMAND) logerror("%s: DRIVE SELECT command (%02x): head load delay=%d, type=%d, drive=%d, pout=%02x\n", tag(), current_command(), m_head_load_delay_enable, m_selected_drive_type, driveparm&3, m_register_w[RETRY_COUNT]&0x0f);
1034      // Calculate the head load delays
1035      head_load_delay = head_load_delay_enable? m_register_w[DATA] * head_load_timer_increment[m_selected_drive_type] : 0;
1036      if (fm_mode()) head_load_delay <<= 1;
10361037
1037   if (m_substate != UNDEF)
1038      if (TRACE_COMMAND) logerror("%s: DRIVE SELECT command (%02x): head load delay=%d, type=%d, drive=%d, pout=%02x\n", tag(), current_command(), head_load_delay, m_selected_drive_type, driveparm&3, m_register_w[RETRY_COUNT]&0x0f);
1039
1040      // Copy the DMA registers to registers CURRENT_HEAD, CURRENT_CYLINDER,
1041      // and CURRENT_IDENT. This is required during formatting ([1], p. 14)
1042      // as the format command reuses the registers for formatting parameters.
1043      m_register_r[CURRENT_HEAD] = m_register_r[DMA7_0];
1044      m_register_r[CURRENT_CYLINDER] = m_register_r[DMA15_8];
1045      m_register_r[CURRENT_IDENT] = m_register_r[DMA23_16];
1046
1047      // Copy the selected drive number to the chip status register
1048      m_register_r[CHIP_STATUS] = (m_register_r[CHIP_STATUS] & 0xfc) | m_selected_drive_number;
1049      auxbus_out();
1050
1051      m_substate = (head_load_delay>0)? HEAD_DELAY : DONE;
1052   }
1053
1054   // As for the head delay, the specs are not clear when it is applied.
1055   // There is no input line indicating whether the head is already loaded
1056   // (see WD17xx: HLT). Let's assume for now that the head is loaded with
1057   // this drive select operation, and that we have the delay here.
1058   switch (m_substate)
10381059   {
1039      logerror("%s: substate = %d\n", tag(), m_substate);
1060   case HEAD_DELAY:
1061      wait_time(m_timer, head_load_delay, DONE);
1062      cont = WAIT;
1063      break;
1064   case DONE:
1065      cont = SUCCESS;
1066      break;
10401067   }
10411068
1042   // Copy the DMA registers to registers CURRENT_HEAD, CURRENT_CYLINDER,
1043   // and CURRENT_IDENT. This is required during formatting ([1], p. 14)
1044   // as the format command reuses the registers for formatting parameters.
1045   m_register_r[CURRENT_HEAD] = m_register_r[DMA7_0];
1046   m_register_r[CURRENT_CYLINDER] = m_register_r[DMA15_8];
1047   m_register_r[CURRENT_IDENT] = m_register_r[DMA23_16];
1048
1049   // Copy the selected drive number to the chip status register
1050   m_register_r[CHIP_STATUS] = (m_register_r[CHIP_STATUS] & 0xfc) | (driveparm & 0x03);
1051
1052   auxbus_out();
1053   set_command_done(TC_SUCCESS);
1069   if (cont==SUCCESS) set_command_done(TC_SUCCESS);
10541070}
10551071
10561072/*
r32114r32115
11971213// ===========================================================================
11981214
11991215/*
1216    Step on / off; used by RESTORE and STEP IN/OUT
1217*/
1218void hdc9234_device::step_on(bool towards00, int next)
1219{
1220   if (TRACE_ACT) logerror("%s: substate STEP_ON\n", tag());
1221
1222   // STEPDIR = 0 -> towards TRK00
1223   set_bits(m_output2, OUT2_STEPDIR, !towards00);
1224
1225   // Raising edge (note that all signals must be inverted before leading them to the drive)
1226   set_bits(m_output2, OUT2_STEPPULSE, true);
1227   auxbus_out();
1228   wait_time(m_timer, pulse_width(), next);
1229}
1230
1231void hdc9234_device::step_off(int next)
1232{
1233   if (TRACE_ACT) logerror("%s: substate STEP_OFF\n", tag());
1234   set_bits(m_output2, OUT2_STEPPULSE, false);
1235   auxbus_out();
1236   wait_time(m_timer, step_time(), next);
1237}
1238
1239/*
12001240    Delivers the step time (in microseconds) minus the pulse width
12011241*/
12021242int hdc9234_device::step_time()
r32114r32115
16971737
16981738         if (m_transfer_enabled)
16991739         {
1740            m_register_r[DATA] = m_register_w[DATA] = m_live_state.data_reg;
17001741            m_out_dip(ASSERT_LINE);
1701            m_out_dma(0, m_live_state.data_reg, 0xff);
1742            m_out_dma(0, m_register_r[DATA], 0xff);
17021743            m_out_dip(CLEAR_LINE);
17031744
17041745            m_out_dmarq(CLEAR_LINE);
r32114r32115
18431884         {
18441885            // Read byte via DMA
18451886            m_out_dip(ASSERT_LINE);
1846            UINT8 data = m_in_dma(0, 0xff);
1847            if (TRACE_WRITE) logerror("%s: [%s] Write %02x\n", tag(), tts(m_live_state.time).cstr(), data);
1848            encode_byte(data);
1887            m_register_r[DATA] = m_register_w[DATA] = m_in_dma(0, 0xff);
1888            if (TRACE_WRITE) logerror("%s: [%s] Write %02x\n", tag(), tts(m_live_state.time).cstr(), m_register_r[DATA]);
1889            encode_byte(m_register_r[DATA]);
18491890            m_out_dip(CLEAR_LINE);
18501891            m_out_dmarq(CLEAR_LINE);
18511892
r32114r32115
21482189*/
21492190WRITE8_MEMBER( hdc9234_device::write )
21502191{
2151   m_data = data & 0xff;
2152
21532192   if ((offset & 1) == 0)
21542193   {
2194      m_regvalue = data & 0xff;
21552195      wait_time(m_cmd_timer, attotime::from_nsec(REGISTER_COMMIT), REGISTER_ACCESS);
21562196   }
21572197   else
21582198   {
21592199      if (m_executing)
21602200      {
2161         logerror("%s: [%s] Error - previous command %02x not completed; new command %02x ignored\n", tag(), ttsn().cstr(), current_command(), m_data);
2201         logerror("%s: [%s] Error - previous command %02x not completed; new command %02x ignored\n", tag(), ttsn().cstr(), current_command(), data);
21622202      }
21632203      else
21642204      {
2205         m_register_w[COMMAND] = data;
21652206         wait_time(m_cmd_timer, attotime::from_nsec(COMMAND_COMMIT), COMMAND_INIT);
21662207      }
21672208   }
r32114r32115
21792220      if (TRACE_REG)
21802221      {
21812222         if (m_register_pointer == INT_COMM_TERM)
2182            logerror("%s: Setting interrupt trigger DONE=%d READY=%d\n", tag(), (m_data & TC_INTDONE)? 1:0, (m_data & TC_INTRDCH)? 1:0);
2223            logerror("%s: Setting interrupt trigger DONE=%d READY=%d\n", tag(), (m_regvalue & TC_INTDONE)? 1:0, (m_regvalue & TC_INTRDCH)? 1:0);
21832224         else
2184            logerror("%s: register[%d] <- %02x\n", tag(), m_register_pointer, m_data);
2225            logerror("%s: register[%d] <- %02x\n", tag(), m_register_pointer, m_regvalue);
21852226      }
2186      m_register_w[m_register_pointer] = m_data;
2227      m_register_w[m_register_pointer] = m_regvalue;
21872228
21882229      // Changes to these registers must be output via the auxbus
21892230      if (m_register_pointer == DESIRED_HEAD || m_register_pointer == RETRY_COUNT)
r32114r32115
21912232
21922233      // The DMA registers and the sector register for read and
21932234      // write are identical, so in that case we copy the contents
2194      if (m_register_pointer < DESIRED_HEAD) m_register_r[m_register_pointer] = m_data;
2235      if (m_register_pointer < DESIRED_HEAD) m_register_r[m_register_pointer] = m_regvalue;
21952236
21962237      // Autoincrement until DATA is reached.
21972238      if (m_register_pointer < DATA)  m_register_pointer++;
r32114r32115
22072248      // Clear Interrupt Pending and Ready Change
22082249      set_bits(m_register_r[INT_STATUS], ST_INTPEND | ST_RDYCHNG, false);
22092250
2210      // Store command
2211      UINT8 command = m_data;
2212      m_register_w[COMMAND] = command;
2213      m_stop_after_index = false;
2214      m_wait_for_index = false;
2215
22162251      int index = 0;
22172252      bool found = false;
22182253
22192254      while (s_command[index].mask!=0 && !found)
22202255      {
2221         if ((command & s_command[index].mask) == s_command[index].baseval)
2256         if ((m_register_w[COMMAND] & s_command[index].mask) == s_command[index].baseval)
22222257         {
2223            // Invoke command
2258            found = true;
2259
2260            m_stop_after_index = false;
2261            m_wait_for_index = false;
22242262            m_substate = UNDEF;
2225            found = true;
22262263            m_executing = true;
22272264            m_command = s_command[index].command;
2265            // Invoke command
22282266            (this->*m_command)();
22292267         }
22302268         else index++;
22312269      }
22322270      if (!found)
22332271      {
2234         logerror("%s: Command %02x not defined\n", tag(), command);
2272         logerror("%s: Command %02x not defined\n", tag(), m_register_w[COMMAND]);
22352273      }
22362274   }
22372275}
r32114r32115
24052443*/
24062444void hdc9234_device::auxbus_out()
24072445{
2446   m_output1 = (m_selected_drive_number != NODRIVE)? (0x10 << m_selected_drive_number) : 0;
2447   m_output1 |= (m_register_w[RETRY_COUNT]&0x0f);
2448
24082449   if (TRACE_AUXBUS) logerror("%s: Setting OUTPUT1 to %02x\n", tag(), m_output1);
24092450   m_out_auxbus((offs_t)HDC_OUTPUT_1, m_output1);
24102451
r32114r32115
24542495{
24552496   if (state==ASSERT_LINE)
24562497   {
2457      if (TRACE_LINES) logerror("%s: [%s] DMA acknowledged\n", tag(), ttsn().cstr());
2498      if (TRACE_LIVE) logerror("%s: [%s] DMA acknowledged\n", tag(), ttsn().cstr());
24582499      set_bits(m_register_r[INT_STATUS], ST_OVRUN, false);
24592500   }
24602501}
r32114r32115
24662507{
24672508   if (state == ASSERT_LINE)
24682509   {
2469      if (TRACE_ACT) logerror("%s: Reset via RST line\n", tag());
2510      if (TRACE_LINES) logerror("%s: Reset via RST line\n", tag());
24702511      device_reset();
24712512   }
24722513}
24732514
24742515void hdc9234_device::device_start()
24752516{
2476   logerror("%s: Start\n", tag());
24772517   m_out_intrq.resolve_safe();
24782518   m_out_dip.resolve_safe();
24792519   m_out_auxbus.resolve_safe();
r32114r32115
24912531
24922532void hdc9234_device::device_reset()
24932533{
2494   logerror("%s: Reset\n", tag());
2495
2496   m_selected_drive_type = 0;
2497   m_head_load_delay_enable = false;
2498
2499   m_register_pointer = 0;
2500
2534   m_deleted = false;
2535   m_executing = false;
2536   m_initialized = true;
2537   m_live_state.state = IDLE;
2538   m_live_state.time = attotime::never;
2539   m_multi_sector = false;
25012540   m_output1 = 0;
25022541   m_output2 = 0x80;
2503
2504   set_interrupt(CLEAR_LINE);
2505   m_out_dip(CLEAR_LINE);
2506   m_out_dmarq(CLEAR_LINE);
2507
2508   for (int i=0; i<=11; i++)
2509      m_register_r[i] = m_register_w[i] = 0;
2510
2542   m_precompensation = 0;
2543   m_reduced_write_current = false;
2544   m_regvalue = 0;
2545   m_register_pointer = 0;
2546   m_retry_save = 0;
2547   m_seek_count = 0;
2548   m_selected_drive_number = NODRIVE;
2549   m_selected_drive_type = 0;
25112550   m_state_after_line = UNDEF;
2512   m_seek_count = 0;
2513
2514   m_live_state.time = attotime::never;
2515   m_live_state.state = IDLE;
2516
2551   m_stop_after_index = false;
2552   m_substate = UNDEF;
25172553   m_track_delta = 0;
2518
2519   m_multi_sector = false;
2520   m_retry_save = 0;
2521
2522   m_substate = UNDEF;
2523
2524   m_executing = false;
2525
2526   m_stop_after_index = false;
2554   m_transfer_enabled = true;
25272555   m_wait_for_index = false;
2528
2529   m_transfer_enabled = true;
25302556   m_write = false;
2531   m_deleted = false;
25322557
2533   m_data = 0;
2534   m_precompensation = 0;
2535   m_reduced_write_current = false;
2558   for (int i=0; i<=11; i++)
2559      m_register_r[i] = m_register_w[i] = 0;
25362560
2537   m_initialized = true;
2561   set_interrupt(CLEAR_LINE);
2562   m_out_dip(CLEAR_LINE);
2563   m_out_dmarq(CLEAR_LINE);
25382564}
25392565
25402566const device_type HDC9234 = &device_creator<hdc9234_device>;
trunk/src/emu/machine/hdc9234.h
r32114r32115
140140   // Write the DMA address to the external latches
141141   void dma_address_out();
142142
143   // Intermediate storage
144   UINT8 m_data;
143   // Intermediate storage for register
144   UINT8 m_regvalue;
145145
146146   // Drive type that has been selected in drive_select
147147   int m_selected_drive_type;
148148
149   // Drive numbere that has been selected in drive_select
150   int m_selected_drive_number;
151
149152   // Indicates whether the device has completed initialization
150153   bool m_initialized;
151154
r32114r32115
305308   // Do we apply a reduced write current?
306309   bool m_reduced_write_current;
307310
308   // Enables head load delays
309   bool m_head_load_delay_enable;
310
311311   // Used in RESTORE to find out when to give up
312312   int m_seek_count;
313313
r32114r32115
361361   // ===================================================
362362   //   Commands
363363   // ===================================================
364
365   void reset_controller();
364366   void drive_select();
365367   void drive_deselect();
366368   void restore_drive();

Previous 199869 Revisions Next


© 1997-2024 The MAME Team