Previous 199869 Revisions Next

r26586 Wednesday 11th December, 2013 at 15:21:22 UTC by Michael Zapf
(MESS) ti99: Fix problems with BwG disk controller; will now correctly
write double density disks. [Michael Zapf]
[src/mess/drivers]ti99_4x.c ti99_8.c
[src/mess/machine/ti99]bwg.c bwg.h datamux.c datamux.h peribox.c peribox.h

trunk/src/mess/machine/ti99/datamux.c
r26585r26586
5252    +---+                      +-+     |      | |                   :
5353      ^                     LS244|     |      | |
5454      |                          |     +--+---+-++
55      |                          +--------| DMUX |
55      |                          +--------| DMUX |---------------<--: READY
5656      +--- READY -------------------------+------+
5757
5858         Databus width
r26585r26586
7979{
8080}
8181
82#define VERBOSE 1
83#define LOG logerror
82#define TRACE_READY 0
83#define TRACE_ACCESS 0
84#define TRACE_ADDRESS 0
85#define TRACE_WAITCOUNT 0
86#define TRACE_SETUP 0
8487
8588/***************************************************************************
8689    DEVICE ACCESSOR FUNCTIONS
r26585r26586
216219      // Reading the even address now (addr)
217220      UINT8 hbyte = 0;
218221      read_all(space, m_addr_buf, &hbyte);
219      if (VERBOSE>3) LOG("datamux: read even byte from address %04x -> %02x\n",  m_addr_buf, hbyte);
222      if (TRACE_ACCESS) logerror("datamux: read even byte from address %04x -> %02x\n",  m_addr_buf, hbyte);
220223
221224      return ((hbyte<<8) | m_latch) & mem_mask;
222225   }
r26585r26586
250253      m_latch = (data >> 8) & 0xff;
251254
252255      // write odd byte
253      if (VERBOSE>3) LOG("datamux: write odd byte to address %04x <- %02x\n",  m_addr_buf+1, data & 0xff);
256      if (TRACE_ACCESS) logerror("datamux: write odd byte to address %04x <- %02x\n",  m_addr_buf+1, data & 0xff);
254257      write_all(space, m_addr_buf+1, data & 0xff);
255258   }
256259}
r26585r26586
261264*/
262265SETOFFSET_MEMBER( ti99_datamux_device::setoffset )
263266{
264   if (VERBOSE>6) LOG("datamux: set address %04x\n", offset << 1);
267   if (TRACE_ADDRESS) logerror("datamux: set address %04x\n", offset << 1);
265268   // Initialize counter
266269   // 1 cycle for loading into the datamux
267270   // 2 subsequent wait states (LSB)
r26585r26586
284287      // propagate the setaddress operation
285288      // First the odd address
286289      setaddress_all(space, m_addr_buf+1);
287      m_ready(CLEAR_LINE);
290      m_muxready = CLEAR_LINE;
291      ready_join();
288292   }
289293   else m_waitcount = 0;
290294}
r26585r26586
298302   // return immediately if the datamux is currently inactive
299303   if (m_waitcount>0)
300304   {
301      if (VERBOSE>6) LOG("datamux: wait count %d\n", m_waitcount);
305      if (TRACE_WAITCOUNT) logerror("datamux: wait count %d\n", m_waitcount);
306      if (m_sysready==CLEAR_LINE)
307      {
308         if (TRACE_READY) logerror("datamux: stalled due to external READY=0\n");
309         return;
310      }
302311      if (m_read_mode)
303312      {
304313         // Reading
305314         if (state==ASSERT_LINE)
306315         {   // raising edge
307316            m_waitcount--;
308            if (m_waitcount==0) m_ready(ASSERT_LINE);
317            if (m_waitcount==0)
318            {
319               m_muxready = ASSERT_LINE;
320               ready_join();
321            }
309322            if (m_waitcount==2)
310323            {
311324               // read odd byte
312325               read_all(*m_spacep, m_addr_buf+1, &m_latch);
313               if (VERBOSE>3) LOG("datamux: read odd byte from address %04x -> %02x\n",  m_addr_buf+1, m_latch);
326               if (TRACE_ACCESS) logerror("datamux: read odd byte from address %04x -> %02x\n",  m_addr_buf+1, m_latch);
314327               // do the setaddress for the even address
315328               setaddress_all(*m_spacep, m_addr_buf);
316329            }
r26585r26586
321334         if (state==ASSERT_LINE)
322335         {   // raising edge
323336            m_waitcount--;
324            if (m_waitcount==0) m_ready(ASSERT_LINE);
337            if (m_waitcount==0)
338            {
339               m_muxready = ASSERT_LINE;
340               ready_join();
341            }
325342         }
326343         else
327344         {   // falling edge
r26585r26586
330347               // do the setaddress for the even address
331348               setaddress_all(*m_spacep, m_addr_buf);
332349               // write even byte
333               if (VERBOSE>3) LOG("datamux: write even byte to address %04x <- %02x\n",  m_addr_buf, m_latch);
350               if (TRACE_ACCESS) logerror("datamux: write even byte to address %04x <- %02x\n",  m_addr_buf, m_latch);
334351               write_all(*m_spacep, m_addr_buf, m_latch);
335352            }
336353         }
r26585r26586
338355   }
339356}
340357
358/*
359    Combine the external (sysready) and the own (muxready) READY states.
360*/
361void ti99_datamux_device::ready_join()
362{
363   m_ready((m_sysready==CLEAR_LINE || m_muxready==CLEAR_LINE)? CLEAR_LINE : ASSERT_LINE);
364}
365
341366WRITE_LINE_MEMBER( ti99_datamux_device::dbin_in )
342367{
343368   m_read_mode = (state==ASSERT_LINE);
344   if (VERBOSE>7) LOG("datamux: data bus in = %d\n", m_read_mode? 1:0 );
369   if (TRACE_ADDRESS) logerror("datamux: data bus in = %d\n", m_read_mode? 1:0 );
345370}
346371
372WRITE_LINE_MEMBER( ti99_datamux_device::ready_line )
373{
374   if (TRACE_READY)
375   {
376      if (state != m_sysready) logerror("datamux: READY line from PBox = %d\n", state);
377   }
378   m_sysready = (line_state)state;
379   // Also propagate to CPU via driver
380   ready_join();
381}
382
347383/***************************************************************************
348384    DEVICE LIFECYCLE FUNCTIONS
349385***************************************************************************/
r26585r26586
407443               {
408444                  attached_device *ad = new attached_device(dev, list[i]);
409445                  m_devices.append(*ad);
410                  if (VERBOSE>8) LOG("datamux: Device %s mounted at index %d.\n", list[i].name, i);
446                  if (TRACE_SETUP) logerror("datamux: Device %s mounted at index %d.\n", list[i].name, i);
411447               }
412448               else
413449               {
414                  if (VERBOSE>8) LOG("datamux: Device %s not found.\n", list[i].name);
450                  if (TRACE_SETUP) logerror("datamux: Device %s not found.\n", list[i].name);
415451               }
416452            }
417453            else
418454            {
419               if (VERBOSE>8) LOG("datamux: Device %s not mounted due to configuration setting %s.\n", list[i].name, list[i].setting);
455               if (TRACE_SETUP) logerror("datamux: Device %s not mounted due to configuration setting %s.\n", list[i].name, list[i].setting);
420456            }
421457         }
422458      }
423459   }
424   if (VERBOSE>8) LOG("datamux: Device count = %d\n", m_devices.count());
425   m_ready(ASSERT_LINE);
460   if (TRACE_SETUP) logerror("datamux: Device count = %d\n", m_devices.count());
426461
462   m_sysready = ASSERT_LINE;
463   m_muxready = ASSERT_LINE;
464   ready_join();
465
427466   m_waitcount = 0;
428467   m_latch = 0;
429468
trunk/src/mess/machine/ti99/peribox.c
r26585r26586
352352   else
353353      m_ready_flag &= ~(1 << slot);
354354
355   m_console_ready((m_ready_flag != 0)? CLEAR_LINE : ASSERT_LINE);
355   m_datamux_ready((m_ready_flag != 0)? CLEAR_LINE : ASSERT_LINE);
356356}
357357
358358void peribox_device::set_slot_loaded(int slot, peribox_slot_device* slotdev)
r26585r26586
382382   assert (intf != NULL);
383383   m_console_inta.resolve(intf->inta, *this);
384384   m_console_intb.resolve(intf->intb, *this);
385   m_console_ready.resolve(intf->ready, *this);
385   m_datamux_ready.resolve(intf->ready, *this);
386386
387387   m_inta_flag = 0;
388388   m_intb_flag = 0;
r26585r26586
446446*****************************************************************************/
447447
448448peribox_gen_device::peribox_gen_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
449: peribox_device(mconfig, PERIBOX_GEN, "Peripheral expansion box Generic", tag, owner, clock, "peribox_gen", __FILE__)
449: peribox_device(mconfig, PERIBOX_GEN, "Peripheral expansion box Geneve", tag, owner, clock, "peribox_gen", __FILE__)
450450{
451451};
452452
453// The BwG controller will not run with the Geneve due to its wait state
454// logic; it assumes that before reading 5FF6 (data register), address 5FF7
455// is also read (by means of the datamux). Unlike the 9900, the 9995 can read
456// single bytes, so it will never trigger a read operation on 5FF7.
457
458SLOT_INTERFACE_START( peribox_slot7nobwg )
459   SLOT_INTERFACE("ide", TI99_IDE)
460   SLOT_INTERFACE("usbsm", TI99_USBSM)
461   SLOT_INTERFACE("hfdc", TI99_HFDC)
462SLOT_INTERFACE_END
463
464SLOT_INTERFACE_START( peribox_slot8nobwg )
465   SLOT_INTERFACE("tifdc", TI99_FDC)
466   SLOT_INTERFACE("hfdc", TI99_HFDC)
467SLOT_INTERFACE_END
468
453469SLOT_INTERFACE_START( peribox_slotg )
454470   SLOT_INTERFACE("memex", TI99_MEMEX)
455471   SLOT_INTERFACE("myarcmem", TI99_MYARCMEM)
r26585r26586
466482   MCFG_PERIBOX_SLOT_ADD( PEBSLOT4, peribox_slotg )
467483   MCFG_PERIBOX_SLOT_ADD( PEBSLOT5, peribox_slotg )
468484   MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot6 )
469   MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot7 )
470   MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot8 )
485   MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot7nobwg )
486   MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot8nobwg )
471487
472488   MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(ti99_4_floppy_interface)
473489   MCFG_MFMHD_3_DRIVES_ADD()
r26585r26586
479495}
480496
481497/****************************************************************************
498    A variant of the box used for the TI-99/8
499*****************************************************************************/
500
501peribox_998_device::peribox_998_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
502: peribox_device(mconfig, PERIBOX_998, "Peripheral expansion box 99/8", tag, owner, clock, "peribox_998", __FILE__)
503{
504};
505
506// The BwG controller will not run with the TI-99/8 for the same reason why
507// it won't work with the Geneve.
508// We don't have many options here. The P-Box is not the prefered device for
509// the 99/8; it was intended to use the Hexbus interface. None of the memory
510// expansions are really supposed to work here.
511SLOT_INTERFACE_START( peribox_slot998 )
512   SLOT_INTERFACE("myarcmem", TI99_MYARCMEM)
513   SLOT_INTERFACE("samsmem", TI99_SAMSMEM)
514   SLOT_INTERFACE("horizon", TI99_HORIZON)
515   SLOT_INTERFACE("ide", TI99_IDE)
516   SLOT_INTERFACE("usbsm", TI99_USBSM)
517   SLOT_INTERFACE("tirs232", TI99_RS232)
518SLOT_INTERFACE_END
519
520MACHINE_CONFIG_FRAGMENT( peribox_998_device )
521   MCFG_PERIBOX_SLOT_ADD( PEBSLOT2, peribox_slot998 )
522   MCFG_PERIBOX_SLOT_ADD( PEBSLOT3, peribox_slot998 )
523   MCFG_PERIBOX_SLOT_ADD( PEBSLOT4, peribox_slot998 )
524   MCFG_PERIBOX_SLOT_ADD( PEBSLOT5, peribox_slot998 )
525   MCFG_PERIBOX_SLOT_ADD( PEBSLOT6, peribox_slot998 )
526   MCFG_PERIBOX_SLOT_ADD( PEBSLOT7, peribox_slot998 )
527   MCFG_PERIBOX_SLOT_ADD( PEBSLOT8, peribox_slot8nobwg )
528
529   MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(ti99_4_floppy_interface)
530   MCFG_MFMHD_3_DRIVES_ADD()
531MACHINE_CONFIG_END
532
533machine_config_constructor peribox_998_device::device_mconfig_additions() const
534{
535   return MACHINE_CONFIG_NAME( peribox_998_device );
536}
537
538/****************************************************************************
482539    A variant of the box used for the SGCPU (aka TI-99/4P).
483540*****************************************************************************/
484541
r26585r26586
681738const device_type PERIBOX_EV = &device_creator<peribox_ev_device>;
682739const device_type PERIBOX_SG = &device_creator<peribox_sg_device>;
683740const device_type PERIBOX_GEN = &device_creator<peribox_gen_device>;
741const device_type PERIBOX_998 = &device_creator<peribox_998_device>;
trunk/src/mess/machine/ti99/datamux.h
r26585r26586
7676
7777   DECLARE_WRITE_LINE_MEMBER( clock_in );
7878   DECLARE_WRITE_LINE_MEMBER( dbin_in );
79   DECLARE_WRITE_LINE_MEMBER( ready_line );
7980
8081protected:
8182   /* Constructor */
r26585r26586
101102   UINT16 debugger_read(address_space& space, UINT16 addr);
102103   void debugger_write(address_space& space, UINT16 addr, UINT16 data);
103104
105   // Join own READY and external READY
106   void ready_join();
107
104108   // Ready line to the CPU
105109   devcb_resolved_write_line m_ready;
106110
111   // Own ready state.
112   line_state  m_muxready;
113
114   // Ready state. Needed to control wait state generation via inbound READY
115   line_state  m_sysready;
116
107117   /* Address latch (emu). In reality, the address bus remains constant. */
108118   UINT16 m_addr_buf;
109119
trunk/src/mess/machine/ti99/peribox.h
r26585r26586
2222extern const device_type PERIBOX_EV;
2323extern const device_type PERIBOX_SG;
2424extern const device_type PERIBOX_GEN;
25extern const device_type PERIBOX_998;
2526
2627#define DSRROM "dsrrom"
2728
r26585r26586
7778   // Next three methods call back the console
7879   devcb_resolved_write_line m_console_inta;   // INTA line (Box to console)
7980   devcb_resolved_write_line m_console_intb;   // INTB line
80   devcb_resolved_write_line m_console_ready;  // READY line
81   devcb_resolved_write_line m_datamux_ready;  // READY line (to the datamux)
8182
8283   void set_slot_loaded(int slot, peribox_slot_device* slotdev);
8384   peribox_slot_device *m_slot[9];     // for the sake of simplicity we donate the first two positions (0,1)
r26585r26586
135136   virtual machine_config_constructor device_mconfig_additions() const;
136137};
137138
139/*
140    Variation for TI-99/8
141*/
142class peribox_998_device : public peribox_device
143{
144public:
145   peribox_998_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
146
147protected:
148   virtual machine_config_constructor device_mconfig_additions() const;
149};
150
138151/*****************************************************************************
139152    A single slot in the box.
140153******************************************************************************/
r26585r26586
236249   MCFG_DEVICE_ADD(_tag, PERIBOX_GEN, 0) \
237250   MCFG_DEVICE_CONFIG( _config )
238251
252#define MCFG_PERIBOX_998_ADD(_tag, _config) \
253   MCFG_DEVICE_ADD(_tag, PERIBOX_998, 0) \
254   MCFG_DEVICE_CONFIG( _config )
255
239256#define MCFG_PERIBOX_SLOT_ADD(_tag, _slot_intf) \
240257   MCFG_DEVICE_ADD(_tag, PERIBOX_SLOT, 0) \
241258   MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, NULL, false)
trunk/src/mess/machine/ti99/bwg.c
r26585r26586
2727
2828    Michael Zapf, September 2010
2929    January 2012: rewritten as class (MZ)
30
31    Known issues (Dec 2013):
32
33  1. The BwG controller may fail to read files from single density disks. This
34     is because the DSR tries to read the disk as double density first, which
35     usually fails for a single density disk image - unless we are in track 0.
36     The fix would be to enhance disk images in a way to tell the controller
37     whether they are single or double density and to refuse delivering data
38     when accessed wrongly.
39
40  2. The BwG controller cannot run with the Geneve or other non-9900 computers.
41     The reason for that is the wait state logic. It assumes that when
42     executing MOVB @>5FF6,*R2, first a value from 5FF7 is attempted to be read,
43     just as the TI console does. In that case, wait states are inserted if
44     necessary. The Geneve, however, will try to read a single byte from 5FF6
45     only and therefore circumvent the wait state generation. This is in fact
46     not an emulation glitch but the behavior of the real expansion card.
47
3048*******************************************************************************/
3149
3250#include "emu.h"
3351#include "peribox.h"
3452#include "bwg.h"
35#include "machine/wd17xx.h"
3653#include "formats/ti99_dsk.h"
3754#include "imagedev/flopdrv.h"
3855
39#define LOG logerror
40#define VERBOSE 1
56// ----------------------------------
57// Flags for debugging
4158
59// Show read and write accesses
60#define TRACE_RW 0
61
62// Show CRU bit accesses
63#define TRACE_CRU 0
64
65// Show ready line activity
66#define TRACE_READY 0
67
68// Show detailed signal activity
69#define TRACE_SIGNALS 0
70
71// Show sector data
72#define TRACE_DATA 0
73
74// Show address bus operations
75#define TRACE_ADDRESS 0
76// ----------------------------------
77
4278#define MOTOR_TIMER 1
4379#define FDC_TAG "wd1773"
4480#define CLOCK_TAG "mm58274c"
r26585r26586
4783
4884snug_bwg_device::snug_bwg_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
4985         : ti_expansion_card_device(mconfig, TI99_BWG, "SNUG BwG Floppy Controller", tag, owner, clock, "ti99_bwg", __FILE__),
50            m_clock(*this, CLOCK_TAG)
51{
52}
86            m_wd1773(*this, FDC_TAG),
87            m_clock(*this, CLOCK_TAG) { }
5388
5489/*
5590    Callback called at the end of DVENA pulse
r26585r26586
5792void snug_bwg_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
5893{
5994   m_DVENA = CLEAR_LINE;
60   handle_hold();
95   set_ready_line();
6196}
6297
98
6399/*
64    Call this when the state of DSKhold or DRQ/IRQ or DVENA change
65    Also see ti_fdc.
66
67    Emulation is faulty because the CPU is actually stopped in the midst of
68    instruction, at the end of the memory access
69
70    TODO: This has to be replaced by the proper READY handling that is already
71    prepared here. (Requires READY handling by the CPU.)
100    Operate the wait state logic.
72101*/
73void snug_bwg_device::handle_hold()
102void snug_bwg_device::set_ready_line()
74103{
75   line_state state;
104   // This is the wait state logic
105   if (TRACE_SIGNALS) logerror("bwg: address=%04x, DRQ=%d, INTRQ=%d, MOTOR=%d\n", m_address & 0xffff, m_DRQ, m_IRQ, m_DVENA);
106   line_state nready = (m_dataregLB &&         // Are we accessing 5ff7
107         m_WAITena &&                        // and the wait state generation is active (SBO 2)
108         (m_DRQ==CLEAR_LINE) &&              // and we are waiting for a byte
109         (m_IRQ==CLEAR_LINE) &&              // and there is no interrupt yet
110         (m_DVENA==ASSERT_LINE)              // and the motor is turning?
111         )? ASSERT_LINE : CLEAR_LINE;        // In that case, clear READY and thus trigger wait states
76112
77   if (m_hold && !m_DRQ && !m_IRQ && (m_DVENA==ASSERT_LINE))
78      state = ASSERT_LINE;
79   else
80      state = CLEAR_LINE;
81
82   m_slot->set_ready((state==CLEAR_LINE)? ASSERT_LINE : CLEAR_LINE);
83//  machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, state);
113   if (TRACE_READY) if (nready==ASSERT_LINE) logerror("bwg: READY line = %d\n", (nready==CLEAR_LINE)? 1:0);
114   m_slot->set_ready((nready==CLEAR_LINE)? ASSERT_LINE : CLEAR_LINE);
84115}
85116
86117/*
r26585r26586
88119*/
89120WRITE_LINE_MEMBER( snug_bwg_device::intrq_w )
90121{
91   if (VERBOSE>8) LOG("bwg: set irq = %02x\n", state);
92   m_IRQ = (state==ASSERT_LINE);
122   if (TRACE_SIGNALS) logerror("bwg: set intrq = %d\n", state);
123   m_IRQ = (line_state)state;
93124
94125   // Note that INTB is actually not used in the TI-99 family. But the
95126   // controller asserts the line nevertheless, probably intended for
96127   // use in another planned TI system
97   m_slot->set_intb(state);
128   m_slot->set_intb(state==ASSERT_LINE);
98129
99   handle_hold();
130   // We need to explicitly set the READY line to release the datamux
131   set_ready_line();
100132}
101133
102134WRITE_LINE_MEMBER( snug_bwg_device::drq_w )
103135{
104   if (VERBOSE>8) LOG("bwg: set drq = %02x\n", state);
105   m_DRQ = (state==ASSERT_LINE);
106   handle_hold();
136   if (TRACE_SIGNALS) logerror("bwg: set drq = %d\n", state);
137   m_DRQ = (line_state)state;
138
139   // We need to explicitly set the READY line to release the datamux
140   set_ready_line();
107141}
108142
109/*
110    Read a byte
111    4000 - 5bff: ROM (4 banks)
143SETADDRESS_DBIN_MEMBER( snug_bwg_device::setaddress_dbin )
144{
145   // Selection login in the PAL and some circuits on the board
112146
113    rtc disabled:
114    5c00 - 5fef: RAM
115    5ff0 - 5fff: Controller (f0 = status, f2 = track, f4 = sector, f6 = data)
147   // Is the card being selected?
148   m_address = offset;
149   m_inDsrArea = ((m_address & m_select_mask)==m_select_value);
116150
117    rtc enabled:
118    5c00 - 5fdf: RAM
119    5fe0 - 5fff: Clock (even addr)
151   if (!m_inDsrArea) return;
152
153   if (TRACE_ADDRESS) logerror("bwg: set address = %04x\n", offset & 0xffff);
154
155   // Is the WD chip on the card being selected?
156   // We need the even and odd addresses for the wait state generation,
157   // but only the even addresses when we access it
158   m_WDsel0 = m_inDsrArea && !m_rtc_enabled
159         && ((state==ASSERT_LINE && ((m_address & 0x1ff8)==0x1ff0))    // read
160            || (state==CLEAR_LINE && ((m_address & 0x1ff8)==0x1ff8)));  // write
161
162   m_WDsel = m_WDsel0 && ((m_address & 1)==0);
163
164   // Is the RTC selected on the card? (even addr)
165   m_RTCsel = m_inDsrArea && m_rtc_enabled && ((m_address & 0x1fe1)==0x1fe0);
166
167   // RTC disabled:
168   // 5c00 - 5fef: RAM
169   // 5ff0 - 5fff: Controller (f0 = status, f2 = track, f4 = sector, f6 = data)
170
171   // RTC enabled:
172   // 5c00 - 5fdf: RAM
173   // 5fe0 - 5fff: Clock (even addr)
174
175   // Is RAM selected? We just check for the last 1K and let the RTC or WD
176   // just take control before
177   m_lastK = m_inDsrArea && ((m_address & 0x1c00)==0x1c00);
178
179   // Is the data register port of the WD being selected?
180   // In fact, the address to read the data from is 5FF6, but the TI-99 datamux
181   // fetches both bytes from 5FF7 and 5FF6, the odd one first. The BwG uses
182   // the odd address to operate the READY line
183   m_dataregLB = m_WDsel0 && ((m_address & 0x07)==0x07);
184
185   // Clear or assert the outgoing READY line
186   set_ready_line();
187}
188
189/*
190    Read a byte from ROM, RAM, FDC, or RTC. See setaddress_dbin for selection
191    logic.
120192*/
121193READ8Z_MEMBER(snug_bwg_device::readz)
122194{
123   if (m_selected)
195   if (m_inDsrArea && m_selected)
124196   {
125      if ((offset & m_select_mask)==m_select_value)
197      // 010x xxxx xxxx xxxx
198      if (m_lastK)
126199      {
127         // 010x xxxx xxxx xxxx
128         if ((offset & 0x1c00)==0x1c00)
200         // ...1 11xx xxxx xxxx
201         if (m_rtc_enabled)
129202         {
130            // ...1 11xx xxxx xxxx
131            if (m_rtc_enabled)
203            if (m_RTCsel)
132204            {
133               if ((offset & 0x03e1)==0x03e0)
134               {
135                  // .... ..11 111x xxx0
136                  if (!space.debugger_access()) *value = m_clock->read(space, (offset & 0x001e) >> 1);
137               }
138               else
139               {
140                  *value = m_buffer_ram[(m_ram_page<<10) | (offset & 0x03ff)];
141               }
205               // .... ..11 111x xxx0
206               if (!space.debugger_access()) *value = m_clock->read(space, (m_address & 0x001e) >> 1);
207               if (TRACE_RW) logerror("bwg: read RTC: %04x -> %02x\n", m_address & 0xffff, *value);
142208            }
143209            else
144210            {
145               if ((offset & 0x03f9)==0x03f0)
146               {
147                  // .... ..11 1111 0xx0
148                  // Note that the value is inverted again on the board,
149                  // so we can drop the inversion
150                  if (!space.debugger_access()) *value = wd17xx_r(m_controller, space, (offset >> 1)&0x03);
151               }
152               else
153               {
154                  *value = m_buffer_ram[(m_ram_page<<10) | (offset & 0x03ff)];
155               }
211               *value = m_buffer_ram[(m_ram_page<<10) | (m_address & 0x03ff)];
212               if (TRACE_RW) logerror("bwg: read ram: %04x (page %d)-> %02x\n", m_address & 0xffff, m_ram_page, *value);
156213            }
157214         }
158215         else
159216         {
160            *value = m_dsrrom[(m_rom_page<<13) | (offset & 0x1fff)];
161            if (VERBOSE>7) LOG("bwg read dsr: %04x -> %02x\n", offset, *value);
217            if (m_WDsel)
218            {
219               // .... ..11 1111 0xx0
220               // Note that the value is inverted again on the board,
221               // so we can drop the inversion
222               if (!space.debugger_access()) *value = wd17xx_r(m_wd1773, space, (m_address >> 1)&0x03);
223               if (TRACE_RW) logerror("bwg: read FDC: %04x -> %02x\n", m_address & 0xffff, *value);
224               if (TRACE_DATA)
225               {
226                  if ((m_address & 0xffff)==0x5ff6) logerror("%02x ", *value);
227                  else logerror("\n%04x: %02x", m_address&0xffff, *value);
228               }
229            }
230            else
231            {
232               *value = m_buffer_ram[(m_ram_page<<10) | (m_address & 0x03ff)];
233               if (TRACE_RW) logerror("bwg: read ram: %04x (page %d)-> %02x\n", m_address & 0xffff, m_ram_page, *value);
234            }
162235         }
163236      }
237      else
238      {
239         *value = m_dsrrom[(m_rom_page<<13) | (m_address & 0x1fff)];
240         if (TRACE_RW) logerror("bwg: read dsr: %04x (page %d)-> %02x\n", m_address & 0xffff, m_rom_page, *value);
241      }
164242   }
165243}
166244
r26585r26586
199277*/
200278WRITE8_MEMBER(snug_bwg_device::write)
201279{
202   if (m_selected)
280   if (m_inDsrArea && m_selected)
203281   {
204      if ((offset & m_select_mask)==m_select_value)
282      if (m_lastK)
205283      {
206         // 010x xxxx xxxx xxxx
207         if ((offset & 0x1c00)==0x1c00)
284         if (m_rtc_enabled)
208285         {
209            // ...1 11xx xxxx xxxx
210            if (m_rtc_enabled)
286            if (m_RTCsel)
211287            {
212               if ((offset & 0x03e1)==0x03e0)
213               {
214                  // .... ..11 111x xxx0
215                  if (!space.debugger_access()) m_clock->write(space, (offset & 0x001e) >> 1, data);
216               }
217               else
218               {
219                  m_buffer_ram[(m_ram_page<<10) | (offset & 0x03ff)] = data;
220               }
288               // .... ..11 111x xxx0
289               if (TRACE_RW) logerror("bwg: write RTC: %04x <- %02x\n", m_address & 0xffff, data);
290               if (!space.debugger_access()) m_clock->write(space, (m_address & 0x001e) >> 1, data);
221291            }
222292            else
223293            {
224               if ((offset & 0x03f9)==0x03f8)
225               {
226                  // .... ..11 1111 1xx0
227                  // Note that the value is inverted again on the board,
228                  // so we can drop the inversion
229                  if (!space.debugger_access()) wd17xx_w(m_controller, space, (offset >> 1)&0x03, data);
230               }
231               else
232               {
233                  m_buffer_ram[(m_ram_page<<10) | (offset & 0x03ff)] = data;
234               }
294               if (TRACE_RW) logerror("bwg: write ram: %04x (page %d) <- %02x\n", m_address & 0xffff, m_ram_page, data);
295               m_buffer_ram[(m_ram_page<<10) | (m_address & 0x03ff)] = data;
235296            }
236297         }
298         else
299         {
300            if (m_WDsel)
301            {
302               // .... ..11 1111 1xx0
303               // Note that the value is inverted again on the board,
304               // so we can drop the inversion
305               if (TRACE_RW) logerror("bwg: write FDC: %04x <- %02x\n", m_address & 0xffff, data);
306               if (!space.debugger_access()) wd17xx_w(m_wd1773, space, (m_address >> 1)&0x03, data);
307            }
308            else
309            {
310               if (TRACE_RW) logerror("bwg: write ram: %04x (page %d) <- %02x\n", m_address & 0xffff, m_ram_page, data);
311               m_buffer_ram[(m_ram_page<<10) | (m_address & 0x03ff)] = data;
312            }
313         }
237314      }
238315   }
239316}
r26585r26586
272349      }
273350      else
274351         *value = 0;
352      if (TRACE_CRU) logerror("bwg: Read CRU = %02x\n", *value);
275353   }
276354}
277355
r26585r26586
287365      case 0:
288366         /* (De)select the card. Indicated by a LED on the board. */
289367         m_selected = (data != 0);
290         if (VERBOSE>4) LOG("bwg: Map DSR = %d\n", m_selected);
368         if (TRACE_CRU) logerror("bwg: Map DSR (bit 0) = %d\n", m_selected);
291369         break;
292370
293371      case 1:
294372         /* Activate motor */
295373         if (data && !m_strobe_motor)
296374         {   /* on rising edge, set motor_running for 4.23s */
375            if (TRACE_CRU) logerror("bwg: trigger motor (bit 1)\n");
297376            m_DVENA = ASSERT_LINE;
298            handle_hold();
299377            m_motor_on_timer->adjust(attotime::from_msec(4230));
300378         }
301379         m_strobe_motor = (data != 0);
r26585r26586
307385         // 1: TMS9900 is stopped until IRQ or DRQ are set
308386         // OR the motor stops rotating - rotates for 4.23s after write
309387         // to CRU bit 1
310         // This is not emulated and could cause the TI99 to lock up
311         m_hold = (data != 0);
312         handle_hold();
388         if (TRACE_CRU) logerror("bwg: arm wait state logic (bit 2) = %d\n", data);
389         m_WAITena = (data != 0);
313390         break;
314391
315392      case 4:
r26585r26586
319396         /* Select drive 0-2 (DSK1-DSK3) (bits 4-6) */
320397         /* Select drive 3 (DSK4) (bit 8) */
321398         drive = (bit == 8) ? 3 : (bit - 4);     /* drive # (0-3) */
399         if (TRACE_CRU) logerror("bwg: set drive (bit %d) = %d\n", bit, data);
322400         drivebit = 1<<drive;
323401
324402         if (data != 0)
r26585r26586
328406               if (m_DSEL != 0)
329407                  logerror("bwg: Multiple drives selected, %02x\n", m_DSEL);
330408               m_DSEL |= drivebit;
331               wd17xx_set_drive(m_controller, drive);
409               wd17xx_set_drive(m_wd1773, drive);
332410            }
333411         }
334412         else
r26585r26586
338416      case 7:
339417         /* Select side of disk (bit 7) */
340418         m_SIDE = data;
341         wd17xx_set_side(m_controller, m_SIDE);
419         if (TRACE_CRU) logerror("bwg: set side (bit 7) = %d\n", data);
420         wd17xx_set_side(m_wd1773, m_SIDE);
342421         break;
343422
344423      case 10:
345424         /* double density enable (active low) */
346         wd17xx_dden_w(m_controller, (data != 0) ? ASSERT_LINE : CLEAR_LINE);
425         if (TRACE_CRU) logerror("bwg: set double density (bit 10) = %d\n", data);
426         wd17xx_dden_w(m_wd1773, (data != 0) ? ASSERT_LINE : CLEAR_LINE);
347427         break;
348428
349429      case 11:
r26585r26586
352432            m_rom_page |= 1;
353433         else
354434            m_rom_page &= 0xfe;  // 11111110
435         if (TRACE_CRU) logerror("bwg: set ROM page (bit 11) = %d, page = %d\n", bit, m_rom_page);
355436         break;
356437
357438      case 13:
358439         /* RAM A10 */
359440         m_ram_page = data;
441         if (TRACE_CRU) logerror("bwg: set RAM page (bit 13) = %d, page = %d\n", bit, m_ram_page);
360442         break;
361443
362444      case 14:
363445         /* Override FDC with RTC (active high) */
446         if (TRACE_CRU) logerror("bwg: turn on RTC (bit 14) = %d\n", data);
364447         m_rtc_enabled = (data != 0);
365448         break;
366449
r26585r26586
370453            m_rom_page |= 2;
371454         else
372455            m_rom_page &= 0xfd; // 11111101
456         if (TRACE_CRU) logerror("bwg: set ROM page (bit 15) = %d, page = %d\n", bit, m_rom_page);
373457         break;
374458
375459      case 3:
460         if (TRACE_CRU) logerror("bwg: set head load (bit 3) = %d\n", data);
461         break;
376462      case 9:
377463      case 12:
378464         /* Unused (bit 3, 9 & 12) */
465         if (TRACE_CRU) logerror("bwg: set unknown bit %d = %d\n", bit, data);
379466         break;
380467      }
381468   }
r26585r26586
383470
384471void snug_bwg_device::device_start(void)
385472{
386   if (VERBOSE>5) LOG("bwg: BWG start\n");
473   logerror("bwg: BWG start\n");
387474   m_dsrrom = memregion(DSRROM)->base();
388475   m_buffer_ram = memregion(BUFFER)->base();
389476   m_motor_on_timer = timer_alloc(MOTOR_TIMER);
390   m_controller = subdevice(FDC_TAG);
391477   m_cru_base = 0x1100;
392478}
393479
394480void snug_bwg_device::device_reset()
395481{
396   if (VERBOSE>5) LOG("bwg: BWG reset\n");
482   logerror("bwg: BWG reset\n");
397483
398484   if (m_genmod)
399485   {
r26585r26586
408494
409495   m_strobe_motor = false;
410496   m_DVENA = CLEAR_LINE;
497   m_DSEL = 0;
498   m_SIDE = 0;
411499   ti99_set_80_track_drives(FALSE);
412500   floppy_type_t type = FLOPPY_STANDARD_5_25_DSDD_40;
413501   set_all_geometries(type);
414   m_DRQ = false;
415   m_IRQ = false;
416   m_hold = false;
502   m_DRQ = CLEAR_LINE;
503   m_IRQ = CLEAR_LINE;
504   m_WAITena = false;
417505   m_rtc_enabled = false;
418506   m_selected = false;
419507
trunk/src/mess/machine/ti99/bwg.h
r26585r26586
1717#include "ti99defs.h"
1818#include "imagedev/flopdrv.h"
1919#include "machine/mm58274c.h"
20#include "machine/wd17xx.h"
2021
2122extern const device_type TI99_BWG;
2223
r26585r26586
2627   snug_bwg_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
2728   DECLARE_READ8Z_MEMBER(readz);
2829   DECLARE_WRITE8_MEMBER(write);
30   DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin);
2931
3032   DECLARE_WRITE_LINE_MEMBER( intrq_w );
3133   DECLARE_WRITE_LINE_MEMBER( drq_w );
r26585r26586
4143   virtual ioport_constructor device_input_ports() const;
4244
4345private:
44   void handle_hold(void);
46   void set_ready_line();
4547   void set_all_geometries(floppy_type_t type);
4648   void set_geometry(device_t *drive, floppy_type_t type);
4749   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
4850
4951   // Holds the status of the DRQ and IRQ lines.
50   bool            m_DRQ, m_IRQ;
52   line_state      m_DRQ, m_IRQ;
5153
5254   // DIP switch state
5355   int             m_dip1, m_dip2, m_dip34;
r26585r26586
5658   int             m_ram_page;  // 0-1
5759   int             m_rom_page;  // 0-3
5860
59   // When TRUE the CPU is halted while DRQ/IRQ are true.
60   bool            m_hold;
61   // When true, the READY line will be cleared (create wait states) when
62   // waiting for data from the controller.
63   bool            m_WAITena;
6164
65   // Address in card area
66   bool            m_inDsrArea;
67
68   // WD selected
69   bool            m_WDsel, m_WDsel0;
70
71   // RTC selected
72   bool            m_RTCsel;
73
74   // last 1K area selected
75   bool            m_lastK;
76
77   // Data register +1 selected
78   bool            m_dataregLB;
79
6280   /* Indicates whether the clock is mapped into the address space. */
6381   bool            m_rtc_enabled;
6482
r26585r26586
6886   // Signal DVENA. When TRUE, makes some drive turning.
6987   line_state      m_DVENA;
7088
89   // Recent address
90   int             m_address;
91
7192   /* Indicates which drive has been selected. Values are 0, 1, 2, and 4. */
7293   // 000 = no drive
7394   // 001 = drive 1
r26585r26586
7899   /* Signal SIDSEL. 0 or 1, indicates the selected head. */
79100   int             m_SIDE;
80101
81   // Link to the FDC1771 controller on the board.
82   device_t*       m_controller;
102   // Link to the WD1773 controller on the board.
103   required_device<wd1773_device>   m_wd1773;
83104
84105   // Link to the real-time clock on the board.
85106   required_device<mm58274c_device> m_clock;
trunk/src/mess/drivers/ti99_8.c
r26585r26586
10511051   MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG, console_cartslot )
10521052
10531053   /* Peripheral expansion box */
1054   MCFG_PERIBOX_ADD( PERIBOX_TAG, peribox_conf )
1054   MCFG_PERIBOX_998_ADD( PERIBOX_TAG, peribox_conf )
10551055
10561056   /* Sound hardware */
10571057   MCFG_TI_SOUND_76496_ADD( TISOUND_TAG, sound_conf )
r26585r26586
10961096   MCFG_TI99_GROMPORT_ADD( GROMPORT_TAG, console_cartslot )
10971097
10981098   /* Peripheral expansion box */
1099   MCFG_PERIBOX_ADD( PERIBOX_TAG, peribox_conf )
1099   MCFG_PERIBOX_998_ADD( PERIBOX_TAG, peribox_conf )
11001100
11011101   /* Sound hardware */
11021102   MCFG_TI_SOUND_76496_ADD( TISOUND_TAG, sound_conf )
trunk/src/mess/drivers/ti99_4x.c
r26585r26586
381381{
382382   DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, extint),            // INTA
383383   DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, notconnected),  // INTB
384   DEVCB_DRIVER_LINE_MEMBER(ti99_4x_state, console_ready_pbox), // READY
384   DEVCB_DEVICE_LINE_MEMBER(DATAMUX_TAG, ti99_datamux_device, ready_line), // READY
385385   0x70000                                             // Address bus prefix (AMA/AMB/AMC)
386386};
387387

Previous 199869 Revisions Next


© 1997-2024 The MAME Team