Previous 15994 Revisions Next

r12902 Tuesday 20th September, 2011 at 19:59:11 UTC by Curt Coder
[ABC1600] ABCenix is now panicking. (nw)
[hash]abc1600.xml
[src/emu/machine]z8536.c z8536.h
[src/mess/drivers]abc1600.c

hash/abc1600.xml
r12901r12902
22<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
33<softwarelist name="abc1600" description="Luxor ABC 1600 disk images">
44  <software name="abcenix">
5    <description>ABCenix 5.18</description>
5    <description>ABCenix 5.12</description>
66    <year>198?</year>
77    <publisher>Luxor</publisher>
88    <part name="flop1" interface="floppy_5_25">
src/emu/machine/z8536.c
r12901r12902
2020//  MACROS / CONSTANTS
2121//**************************************************************************
2222
23#define LOG 1
24
25
2326// states
2427enum
2528{
r12901r12902
9396};
9497
9598
99// interrupt control
100enum
101{
102   IC_NULL = 0,
103   IC_CLEAR_IP_IUS,
104   IC_SET_IUS,
105   IC_CLEAR_IUS,
106   IC_SET_IP,
107   IC_CLEAR_IP,
108   IC_SET_IE,
109   IC_CLEAR_IE
110};
111
112
96113// counter/timer link control
97114enum
98115{
r12901r12902
119136   PMS_DISABLE = 0,
120137   PMS_AND,
121138   PMS_OR,
122   PMS_VECTOR
139   PMS_OR_PEVM
123140};
124141
125142
r12901r12902
221238#define CTMS_ETE      0x10   // external trigger enable
222239#define CTMS_ECE      0x20   // external count enable
223240#define CTMS_EOE      0x40   // external output enable
224#define CTMS_CSC      0x80   // continuous single cycle
241#define CTMS_CSC      0x80   // continuous/single cycle
225242
226243
227244// counter/timer command and status registers
r12901r12902
241258//**************************************************************************
242259
243260//-------------------------------------------------
261//  check_interrupt - check interrupt status
262//-------------------------------------------------
263
264inline void z8536_device::check_interrupt()
265{
266   if (!(m_register[MASTER_INTERRUPT_CONTROL] & MICR_MIE)) return;
267
268   int state = ASSERT_LINE;
269   UINT8 vector = 0xff;
270
271   if ((m_register[COUNTER_TIMER_3_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE)) == (CTCS_IP | CTCS_IE))
272   {
273      vector = m_register[COUNTER_TIMER_INTERRUPT_VECTOR];
274     
275      if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_CT_VIS)
276      {
277         vector = (vector & 0xf9) | 0;
278      }
279   }
280   else if ((m_register[PORT_A_COMMAND_AND_STATUS] & (PCS_IP | PCS_IE)) == (PCS_IP | PCS_IE))
281   {
282      vector = m_register[PORT_A_INTERRUPT_VECTOR];
283
284      if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_CT_VIS)
285      {
286         if ((m_register[PORT_A_MODE_SPECIFICATION] & PMS_PMS_MASK) == PMS_OR_PEVM)
287         {
288            // TODO
289         }
290         else
291         {
292            vector = (vector & 0xf1) | (m_register[PORT_A_COMMAND_AND_STATUS] & 0x0e);
293         }
294      }
295   }
296   else if ((m_register[COUNTER_TIMER_2_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE)) == (CTCS_IP | CTCS_IE))
297   {
298      vector = m_register[COUNTER_TIMER_INTERRUPT_VECTOR];
299     
300      if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_CT_VIS)
301      {
302         vector = (vector & 0xf9) | 1;
303      }
304   }
305   else if ((m_register[PORT_B_COMMAND_AND_STATUS] & (PCS_IP | PCS_IE)) == (PCS_IP | PCS_IE))
306   {
307      vector = m_register[PORT_B_INTERRUPT_VECTOR];
308
309      if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_CT_VIS)
310      {
311         if ((m_register[PORT_B_MODE_SPECIFICATION] & PMS_PMS_MASK) == PMS_OR_PEVM)
312         {
313            // TODO
314         }
315         else
316         {
317            vector = (vector & 0xf1) | (m_register[PORT_B_COMMAND_AND_STATUS] & 0x0e);
318         }
319      }
320   }
321   else if ((m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE)) == (CTCS_IP | CTCS_IE))
322   {
323      vector = m_register[COUNTER_TIMER_INTERRUPT_VECTOR];
324     
325      if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_CT_VIS)
326      {
327         vector = (vector & 0xf9) | 2;
328      }
329   }
330   else
331   {
332      state = CLEAR_LINE;
333   }
334   
335   m_register[CURRENT_VECTOR] = vector;
336   
337   if (m_int != state)
338   {
339      if (LOG) logerror("Z8536 '%s' Interrupt: %u\n", tag(), state);
340      m_int = state;
341      m_out_int_func(state);
342   }
343}
344
345
346//-------------------------------------------------
244347//  read_register - read from register
245348//-------------------------------------------------
246349
r12901r12902
293396   case MASTER_INTERRUPT_CONTROL:
294397      if (data & MICR_RESET)
295398      {
399         if (LOG) logerror("Z8536 '%s' Reset\n", tag());
296400         device_reset();
297401      }
298      else if (m_state == STATE_RESET)
402      else
299403      {
300         m_state = STATE_0;
404         if (m_state == STATE_RESET)
405         {
406            m_state = STATE_0;
407         }
408     
409         if (LOG)
410         {
411            logerror("Z8536 '%s' Master Interrupt Enable: %u\n", tag(), (data & MICR_MIE) ? 1 : 0);
412            logerror("Z8536 '%s' Disable Lower Chain: %u\n", tag(), (data & MICR_DLC) ? 1 : 0);
413            logerror("Z8536 '%s' No Vector: %u\n", tag(), (data & MICR_NV) ? 1 : 0);
414            logerror("Z8536 '%s' Port A Vector Includes Status: %u\n", tag(), (data & MICR_PA_VIS) ? 1 : 0);
415            logerror("Z8536 '%s' Port B Vector Includes Status: %u\n", tag(), (data & MICR_PB_VIS) ? 1 : 0);
416            logerror("Z8536 '%s' Counter/Timer Vector Includes Status: %u\n", tag(), (data & MICR_CT_VIS) ? 1 : 0);
417            logerror("Z8536 '%s' Right Justified Address: %u\n", tag(), (data & MICR_RJA) ? 1 : 0);
418         }
419
420         m_register[offset] = data;
421         check_interrupt();
301422      }
302423      break;
424     
425   case MASTER_CONFIGURATION_CONTROL:
426      if (LOG)
427      {
428         logerror("Z8536 '%s' Port B Enable: %u\n", tag(), (data & MCCR_PBE) ? 1 : 0);
429         logerror("Z8536 '%s' Counter/Timer 1 Enable: %u\n", tag(), (data & MCCR_CT1E) ? 1 : 0);
430         logerror("Z8536 '%s' Counter/Timer 2 Enable: %u\n", tag(), (data & MCCR_CT2E) ? 1 : 0);
431         logerror("Z8536 '%s' Port C and Counter/Timer 3 Enable: %u\n", tag(), (data & MCCR_PCE_CT3E) ? 1 : 0);
432         logerror("Z8536 '%s' Port A Enable: %u\n", tag(), (data & MCCR_PAE) ? 1 : 0);
433         logerror("Z8536 '%s' Port Link Control: %u\n", tag(), (data & MCCR_PLC) ? 1 : 0);
434         logerror("Z8536 '%s' Counter/Timer Link Controls: %u\n", tag(), data & MCCR_LC_MASK);
435      }
436     
437      m_register[offset] = data;
438      break;
439     
440   case PORT_A_INTERRUPT_VECTOR:
441      if (LOG) logerror("Z8536 '%s' Port A Interrupt Vector: %02x\n", tag(), data);
442      m_register[offset] = data;
443      break;
444     
445   case PORT_B_INTERRUPT_VECTOR:
446      if (LOG) logerror("Z8536 '%s' Port B Interrupt Vector: %02x\n", tag(), data);
447      m_register[offset] = data;
448      break;
303449
450   case COUNTER_TIMER_INTERRUPT_VECTOR:
451      if (LOG) logerror("Z8536 '%s' Counter/Timer Interrupt Vector: %02x\n", tag(), data);
452      m_register[offset] = data;
453      break;
454     
455   case PORT_C_DATA_DIRECTION:
456      if (LOG) logerror("Z8536 '%s' Port C Data Direction: %02x\n", tag(), data);
457      m_register[offset] = data;
458      break;
459   
460   case PORT_A_COMMAND_AND_STATUS:
461   case PORT_B_COMMAND_AND_STATUS:
462      {
463      char port = 'A' + offset - PORT_A_COMMAND_AND_STATUS;
464     
465      if (LOG) logerror("Z8536 '%s' Port %c Interrupt on Error: %u\n", tag(), port, (data & PCS_IOE) ? 1 : 0);
466     
467      switch (data >> 5)
468      {
469      case IC_CLEAR_IP_IUS:   m_register[offset] &= ~(PCS_IP | PCS_IUS);   if (LOG) logerror("Z8536 '%s' Port %c Clear IP/IUS\n", tag(), port);   break;
470      case IC_SET_IUS:      m_register[offset] |= PCS_IUS;            if (LOG) logerror("Z8536 '%s' Port %c Set IUS\n", tag(), port);         break;
471      case IC_CLEAR_IUS:      m_register[offset] &= ~PCS_IUS;            if (LOG) logerror("Z8536 '%s' Port %c Clear IUS\n", tag(), port);      break;
472      case IC_SET_IP:         m_register[offset] |= PCS_IP;            if (LOG) logerror("Z8536 '%s' Port %c Set IP\n", tag(), port);         break;
473      case IC_CLEAR_IP:      m_register[offset] &= ~PCS_IP;            if (LOG) logerror("Z8536 '%s' Port %c Clear IP\n", tag(), port);      break;
474      case IC_SET_IE:         m_register[offset] |= PCS_IE;            if (LOG) logerror("Z8536 '%s' Port %c Set IE\n", tag(), port);         break;
475      case IC_CLEAR_IE:      m_register[offset] &= ~PCS_IE;            if (LOG) logerror("Z8536 '%s' Port %c Clear IE\n", tag(), port);      break;
476      }
477
478      m_register[offset] = (m_register[offset] & 0xfe) | (data & 0x01);
479     
480      check_interrupt();
481      }
482      break;
483   
304484   case PORT_A_DATA:
305485      m_out_pa_func(0, data);
306486      break;
r12901r12902
318498      m_out_pc_func(0, m_output[PORT_C]);
319499      }
320500      break;
501     
502   case COUNTER_TIMER_1_MODE_SPECIFICATION:
503   case COUNTER_TIMER_2_MODE_SPECIFICATION:
504   case COUNTER_TIMER_3_MODE_SPECIFICATION:
505      if (LOG)
506      {
507         int counter = offset - COUNTER_TIMER_1_MODE_SPECIFICATION;
508         
509         logerror("Z8536 '%s' Counter/Timer %u Mode: %s\n", tag(), counter, (data & CTMS_CSC) ? "Continuous" : "Single Cycle");
510         logerror("Z8536 '%s' Counter/Timer %u External Output Enable: %u\n", tag(), counter, (data & CTMS_EOE) ? 1 : 0);
511         logerror("Z8536 '%s' Counter/Timer %u External Count Enable: %u\n", tag(), counter, (data & CTMS_ECE) ? 1 : 0);
512         logerror("Z8536 '%s' Counter/Timer %u External Trigger Enable: %u\n", tag(), counter, (data & CTMS_ETE) ? 1 : 0);
513         logerror("Z8536 '%s' Counter/Timer %u External Gate Enable: %u\n", tag(), counter, (data & CTMS_EDE) ? 1 : 0);
514         logerror("Z8536 '%s' Counter/Timer %u Retrigger Enable: %u\n", tag(), counter, (data & CTMS_REB) ? 1 : 0);
515         logerror("Z8536 '%s' Counter/Timer %u Output Duty Cycle: %u\n", tag(), counter, data & CTMS_DCS_MASK);
516      }
517      m_register[offset] = data;
518      break;
321519
322520   default:
323      logerror("Z8536 '%s' Unimplemented write %02x to register %u\n", tag(), data, offset);
521      logerror("%s: Z8536 '%s' Unimplemented write %02x to register %u\n", this->machine().describe_context(), tag(), data, offset);
522      m_register[offset] = data;
324523   }
325
326   m_register[offset] = data; // HACK
327524}
328525
329526
r12901r12902
340537
341538
342539//-------------------------------------------------
343//   count -
540//   count - count down
344541//-------------------------------------------------
345542
346543inline void z8536_device::count(device_timer_id id)
347544{
545   if (!m_gate[id]) return;
546   
547   // count down
548   m_counter[id]--;
549   
550   if (m_counter == 0)
551   {
552      // clear count in progress bit
553      m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] &= ~CTCS_CIP;
554
555      if (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_IP)
556      {
557         // set interrupt error bit
558         m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_ERR;
559      }
560     
561      // set interrupt pending bit
562      m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_IP;
563     
564      check_interrupt();
565   }
348566}
349567
350568
r12901r12902
354572
355573inline void z8536_device::trigger(device_timer_id id)
356574{
575   // load counter with time constant
576   m_counter[id] = (m_register[COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE + (id << 1)] << 8) | m_register[COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE + (id << 1)];
577   
578   // set count in progress bit
579   m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_CIP;
357580}
358581
359582
r12901r12902
361584//  gate -
362585//-------------------------------------------------
363586
364inline void z8536_device::gate(device_timer_id id)
587inline void z8536_device::gate(device_timer_id id, int state)
365588{
589   m_gate[id] = state;
366590}
367591
368592
r12901r12902
376600//-------------------------------------------------
377601
378602z8536_device::z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
379    : device_t(mconfig, Z8536, "Zilog Z8536", tag, owner, clock)
603    : device_t(mconfig, Z8536, "Zilog Z8536", tag, owner, clock),
604     device_z80daisy_interface(mconfig, *this),
605     m_int(CLEAR_LINE)
380606{
381607}
382608
r12901r12902
414640
415641void z8536_device::device_start()
416642{
417   // allocate timers
418   m_timer[TIMER_1] = timer_alloc(TIMER_1);
419   m_timer[TIMER_2] = timer_alloc(TIMER_2);
420   m_timer[TIMER_3] = timer_alloc(TIMER_3);
643   // allocate timer
644   m_timer = timer_alloc();
645   m_timer->adjust(attotime::from_hz(clock() / 2), 0, attotime::from_hz(clock() / 2));
421646
422647   // resolve callbacks
423648   m_out_int_func.resolve(m_out_int_cb, *this);
r12901r12902
444669   }
445670
446671   m_register[MASTER_INTERRUPT_CONTROL] = MICR_RESET;
672   m_register[PORT_A_COMMAND_AND_STATUS] = PCS_ORE;
673   m_register[PORT_B_COMMAND_AND_STATUS] = PCS_ORE;
674   m_register[CURRENT_VECTOR] = 0xff;
675   
447676   m_pointer = 0;
677   
678   check_interrupt();
448679}
449680
450681
r12901r12902
454685
455686void z8536_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
456687{
457   switch (id)
688   if ((m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_CT1E) &&
689      !(m_register[COUNTER_TIMER_1_MODE_SPECIFICATION] & CTMS_ECE))
458690   {
459   case TIMER_1:
460691      count(TIMER_1);
461      break;
462
463   case TIMER_2:
692   }
693   
694   if ((m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_CT2E) &&
695      !(m_register[COUNTER_TIMER_2_MODE_SPECIFICATION] & CTMS_ECE))
696   {
464697      count(TIMER_2);
465      break;
466
467   case TIMER_3:
698   }
699   
700   if ((m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_PCE_CT3E) &&
701      !(m_register[COUNTER_TIMER_3_MODE_SPECIFICATION] & CTMS_ECE))
702   {
468703      count(TIMER_3);
469      break;
470704   }
471705}
472706
473707
708
709//**************************************************************************
710//  DAISY CHAIN INTERFACE
711//**************************************************************************
712
474713//-------------------------------------------------
714//  z80daisy_irq_state - return the overall IRQ
715//  state for this device
716//-------------------------------------------------
717
718int z8536_device::z80daisy_irq_state()
719{
720   return 0;
721}
722
723
724//-------------------------------------------------
725//  z80daisy_irq_ack - acknowledge an IRQ and
726//  return the appropriate vector
727//-------------------------------------------------
728
729int z8536_device::z80daisy_irq_ack()
730{
731   return 0;
732}
733
734
735//-------------------------------------------------
736//  z80daisy_irq_reti - clear the interrupt
737//  pending state to allow other interrupts through
738//-------------------------------------------------
739
740void z8536_device::z80daisy_irq_reti()
741{
742}
743
744
745
746//**************************************************************************
747//  INTERNAL STATE MANAGEMENT
748//**************************************************************************
749
750//-------------------------------------------------
475751//  read - register read
476752//-------------------------------------------------
477753
r12901r12902
564840
565841
566842//-------------------------------------------------
567//  intack_w - interrupt acknowledge
843//  intack_r - interrupt acknowledge
568844//-------------------------------------------------
569845
570WRITE_LINE_MEMBER( z8536_device::intack_w )
846UINT8 z8536_device::intack_r()
571847{
848   UINT8 data = m_register[CURRENT_VECTOR];
849   
850   if (LOG) logerror("Z8536 '%s' Interrupt Acknowledge: %02x\n", tag(), data);
851   
852   if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_NV)
853   {
854      data = 0;
855   }
856   
857   return data;
572858}
573859
574860
src/emu/machine/z8536.h
r12901r12902
3636#define __Z8536__
3737
3838#include "emu.h"
39#include "cpu/z80/z80daisy.h"
3940
4041
4142
r12901r12902
8384// ======================> z8536_device
8485
8586class z8536_device :  public device_t,
87                 public device_z80daisy_interface,
8688                      public z8536_interface
8789{
8890public:
r12901r12902
9294    DECLARE_READ8_MEMBER( read );
9395    DECLARE_WRITE8_MEMBER( write );
9496
95   DECLARE_WRITE_LINE_MEMBER( intack_w );
97   UINT8 intack_r();
9698
9799   DECLARE_WRITE_LINE_MEMBER( pb0_w );
98100   DECLARE_WRITE_LINE_MEMBER( pb1_w );
r12901r12902
114116    virtual void device_reset();
115117   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
116118
119   // device_z80daisy_interface overrides
120   virtual int z80daisy_irq_state();
121   virtual int z80daisy_irq_ack();
122   virtual void z80daisy_irq_reti();
123
117124private:
118125   static const device_timer_id TIMER_1 = 0;
119126   static const device_timer_id TIMER_2 = 1;
120127   static const device_timer_id TIMER_3 = 2;
121128
129   inline void check_interrupt();
130
122131   inline UINT8 read_register(offs_t offset);
123132   inline UINT8 read_register(offs_t offset, UINT8 mask);
124133   inline void write_register(offs_t offset, UINT8 data);
r12901r12902
126135
127136   inline void count(device_timer_id id);
128137   inline void trigger(device_timer_id id);
129   inline void gate(device_timer_id id);
138   inline void gate(device_timer_id id, int state);
130139
131140   devcb_resolved_write_line      m_out_int_func;
132141
r12901r12902
145154   UINT8 m_input[3];
146155   UINT8 m_output[3];
147156   UINT8 m_buffer[3];
157   
158   int m_int;
148159
149160   // timers
150   emu_timer *m_timer[3];
161   emu_timer *m_timer;
162   UINT16 m_counter[3];
163   bool m_gate[3];
151164};
152165
153166
src/mess/drivers/abc1600.c
r12901r12902
1010
1111    TODO:
1212
13    - MAC
14        - MAGIC bit (disable IFC2?)
13   - keyboard
14      - "Bad command" on first enter after boot
1515    - floppy
1616        - internal floppy is really drive 2, but wd17xx.c doesn't like having NULL drives
1717    - BUS0I/0X/1/2
r12901r12902
423423
424424offs_t abc1600_state::translate_address(offs_t offset, int *nonx, int *wp)
425425{
426   if (offset == 0x4730)
427   {
428      logerror("virtuality %06x\n", 0);
429   }
430
431426   // segment
432427   offs_t sega = get_segment_address(offset);
433428   UINT8 segd = m_segment_ram[sega];
r12901r12902
14611456//**************************************************************************
14621457
14631458//-------------------------------------------------
1459//  IRQ_CALLBACK( abc1600_int_ack )
1460//-------------------------------------------------
1461
1462static IRQ_CALLBACK( abc1600_int_ack )
1463{
1464   abc1600_state *state = device->machine().driver_data<abc1600_state>();
1465   UINT8 data = 0;
1466
1467   switch (irqline)
1468   {
1469   case 5:
1470      data = state->m_cio->intack_r();
1471      break;
1472   }
1473   
1474   return data;
1475}
1476
1477
1478//-------------------------------------------------
14641479//  MACHINE_START( abc1600 )
14651480//-------------------------------------------------
14661481
14671482void abc1600_state::machine_start()
14681483{
1484   // interrupt callback
1485   device_set_irq_callback(m_maincpu, abc1600_int_ack);
1486
1487   // fill segment RAM with non-zero values or no boot
1488   memset(m_segment_ram, 0xcd, 0x400);
1489
14691490   // state saving
14701491   save_item(NAME(m_ifc2));
14711492   save_item(NAME(m_task));

Previous 15994 Revisions Next


© 1998-2018 The MESS Team