Previous 15994 Revisions Next

r3296 Friday 19th September, 2008 at 20:42:41 UTC by Wilbert Pol
[KIM1] Changed to use the new 6530 MIOT device.
[src/mess]mess.mak
[src/mess/drivers]kim1.c
[src/mess/includes]kim1.h
[src/mess/machine]6530miot.c* 6530miot.h* kim1.c

src/mess/includes/kim1.h
r3295r3296
1717
1818INTERRUPT_GEN( kim1_interrupt );
1919
20READ8_HANDLER ( m6530_003_r );
21READ8_HANDLER ( m6530_002_r );
22
23WRITE8_HANDLER ( m6530_003_w );
24WRITE8_HANDLER ( m6530_002_w );
25
26
2720/*----------- defined in video/kim1.c -----------*/
2821
2922PALETTE_INIT( kim1 );
src/mess/machine/kim1.c
r3295r3296
1212#include "includes/kim1.h"
1313#include "sound/dac.h"
1414
15typedef struct
16{
17   UINT8 dria;    /* Data register A input */
18   UINT8 droa;    /* Data register A output */
19   UINT8 ddra;    /* Data direction register A; 1 bits = output */
20   UINT8 drib;    /* Data register B input */
21   UINT8 drob;    /* Data register B output */
22   UINT8 ddrb;    /* Data direction register B; 1 bits = output */
23   UINT8 irqen;   /* IRQ enabled ? */
24   UINT8 state;   /* current timer state (bit 7) */
25   double clock;   /* 100000/1(,8,64,1024) */
26   emu_timer *timer;   /* timer callback */
27}
28M6530;
29
30static M6530 m6530[2];
31
32static TIMER_CALLBACK(m6530_timer_cb);
33
3415DRIVER_INIT( kim1 )
3516{
3617   UINT8 *dst;
r3295r3296
595576//   artwork_set_overlay(kim1_overlay);
596577}
597578
598static void set_chip_clock(int chip, int data)
599{
600   timer_adjust_periodic(m6530[chip].timer, attotime_zero, chip, ATTOTIME_IN_HZ((data + 1) * m6530[chip].clock / 256 / 256));
601}
602579
603580MACHINE_RESET( kim1 )
604581{
r3295r3296
616593      RAM[0x17fe] = 0x00;
617594      RAM[0x17ff] = 0x1c;
618595   }
619
620   /* reset the 6530 */
621   memset(&m6530, 0, sizeof (m6530));
622
623   m6530[0].dria = 0xff;
624   m6530[0].drib = 0xff;
625   m6530[0].clock = (double) 1000000 / 1;
626   m6530[0].timer = timer_alloc(m6530_timer_cb, NULL);
627   set_chip_clock(0, 255);
628
629   m6530[1].dria = 0xff;
630   m6530[1].drib = 0xff;
631   m6530[1].clock = (double) 1000000 / 1;
632   m6530[1].timer = timer_alloc(m6530_timer_cb, NULL);
633   set_chip_clock(1, 255);
634596}
635597
636598static DEVICE_IMAGE_LOAD( kim1_cassette )
r3295r3296
657619   return INIT_PASS;
658620}
659621
660static TIMER_CALLBACK(m6530_timer_cb)
661{
662   int chip = param;
663   logerror("m6530(%d) timer expired\n", chip);
664   m6530[chip].state |= 0x80;
665   if (m6530[chip].irqen)            /* with IRQ? */
666      cpunum_set_input_line(machine, 0, 0, HOLD_LINE);
667}
668
669622INTERRUPT_GEN( kim1_interrupt )
670623{
671624   int i;
r3295r3296
678631   }
679632}
680633
681INLINE int m6530_r(running_machine *machine, int chip, int offset)
682{
683   int data = 0xff;
684634
685   switch (offset)
686   {
687   case 0x00:
688   case 0x08:                     /* Data register A */
689      if (chip == 1)
690      {
691         int which = ((m6530[1].drob & m6530[1].ddrb) >> 1) & 0x0f;
692
693         switch (which)
694         {
695         case 0:               /* key row 0 */
696            m6530[1].dria = input_port_read(machine, "LINE0");
697            logerror("read keybd(%d): %c%c%c%c%c%c%c\n",
698                which,
699                (m6530[1].dria & 0x40) ? '.' : '0',
700                (m6530[1].dria & 0x20) ? '.' : '1',
701                (m6530[1].dria & 0x10) ? '.' : '2',
702                (m6530[1].dria & 0x08) ? '.' : '3',
703                (m6530[1].dria & 0x04) ? '.' : '4',
704                (m6530[1].dria & 0x02) ? '.' : '5',
705                (m6530[1].dria & 0x01) ? '.' : '6');
706            break;
707         case 1:               /* key row 1 */
708            m6530[1].dria = input_port_read(machine, "LINE1");
709            logerror("read keybd(%d): %c%c%c%c%c%c%c\n",
710                which,
711                (m6530[1].dria & 0x40) ? '.' : '7',
712                (m6530[1].dria & 0x20) ? '.' : '8',
713                (m6530[1].dria & 0x10) ? '.' : '9',
714                (m6530[1].dria & 0x08) ? '.' : 'A',
715                (m6530[1].dria & 0x04) ? '.' : 'B',
716                (m6530[1].dria & 0x02) ? '.' : 'C',
717                (m6530[1].dria & 0x01) ? '.' : 'D');
718            break;
719         case 2:               /* key row 2 */
720            m6530[1].dria = input_port_read(machine, "LINE2");
721            logerror("read keybd(%d): %c%c%c%c%c%c%c\n",
722                which,
723                (m6530[1].dria & 0x40) ? '.' : 'E',
724                (m6530[1].dria & 0x20) ? '.' : 'F',
725                (m6530[1].dria & 0x10) ? '.' : 'a',
726                (m6530[1].dria & 0x08) ? '.' : 'd',
727                (m6530[1].dria & 0x04) ? '.' : '+',
728                (m6530[1].dria & 0x02) ? '.' : 'g',
729                (m6530[1].dria & 0x01) ? '.' : 'p');
730            break;
731         case 3:               /* WR4?? */
732            m6530[1].dria = 0xff;
733            break;
734         default:
735            m6530[1].dria = 0xff;
736            logerror("read DRA(%d) $ff\n", which);
737         }
738      }
739      data = (m6530[chip].dria & ~m6530[chip].ddra) | (m6530[chip].droa & m6530[chip].ddra);
740      logerror("m6530(%d) DRA   read : $%02x\n", chip, data);
741      break;
742   case 0x01:
743   case 0x09:                     /* Data direction register A */
744      data = m6530[chip].ddra;
745      logerror("m6530(%d) DDRA  read : $%02x\n", chip, data);
746      break;
747   case 0x02:
748   case 0x0a:                     /* Data register B */
749      data = (m6530[chip].drib & ~m6530[chip].ddrb) | (m6530[chip].drob & m6530[chip].ddrb);
750      logerror("m6530(%d) DRB   read : $%02x\n", chip, data);
751      break;
752   case 0x03:
753   case 0x0b:                     /* Data direction register B */
754      data = m6530[chip].ddrb;
755      logerror("m6530(%d) DDRB  read : $%02x\n", chip, data);
756      break;
757   case 0x04:
758   case 0x0c:                     /* Timer count read (not supported?) */
759      data = attotime_mul(timer_timeleft(m6530[chip].timer), 256 * m6530[chip].clock).seconds;
760      m6530[chip].irqen = (offset & 8) ? 1 : 0;
761      logerror("m6530(%d) TIMR  read : $%02x%s\n", chip, data, (offset & 8) ? " (IRQ)" : "");
762      break;
763   case 0x05:
764   case 0x0d:                     /* Timer count read (not supported?) */
765      data = attotime_mul(timer_timeleft(m6530[chip].timer), 256 * m6530[chip].clock).seconds;
766      m6530[chip].irqen = (offset & 8) ? 1 : 0;
767      logerror("m6530(%d) TIMR  read : $%02x%s\n", chip, data, (offset & 8) ? " (IRQ)" : "");
768      break;
769   case 0x06:
770   case 0x0e:                     /* Timer count read */
771      data = attotime_mul(timer_timeleft(m6530[chip].timer), 256 * m6530[chip].clock).seconds;
772      m6530[chip].irqen = (offset & 8) ? 1 : 0;
773      logerror("m6530(%d) TIMR  read : $%02x%s\n", chip, data, (offset & 8) ? " (IRQ)" : "");
774      break;
775   case 0x07:
776   case 0x0f:                     /* Timer status read */
777      data = m6530[chip].state;
778      m6530[chip].state &= ~0x80;
779      m6530[chip].irqen = (offset & 8) ? 1 : 0;
780      logerror("m6530(%d) STAT  read : $%02x%s\n", chip, data, (offset & 8) ? " (IRQ)" : "");
781      break;
782   }
783   return data;
784}
785
786READ8_HANDLER ( m6530_003_r )
787{
788   return m6530_r(machine, 0, offset);
789}
790READ8_HANDLER ( m6530_002_r )
791{
792   return m6530_r(machine, 1, offset);
793}
794
795static void m6530_w(int chip, int offset, int data)
796{
797   switch (offset)
798   {
799   case 0x00:
800   case 0x08:                     /* Data register A */
801      logerror("m6530(%d) DRA  write: $%02x\n", chip, data);
802      m6530[chip].droa = data;
803      if (chip == 1)
804      {
805         int which = (m6530[1].drob & m6530[1].ddrb) >> 1;
806
807         switch (which)
808         {
809         case 0:               /* key row 0 */
810            break;
811         case 1:               /* key row 1 */
812            break;
813         case 2:               /* key row 2 */
814            break;
815         case 3:               /* WR4?? */
816            break;
817            /* write LED # 1-6 */
818         case 4:
819         case 5:
820         case 6:
821         case 7:
822         case 8:
823         case 9:
824            if (data & 0x80)
825            {
826               logerror("write 7seg(%d): %c%c%c%c%c%c%c\n",
827                   which + 1 - 4,
828                   (data & 0x01) ? 'a' : '.',
829                   (data & 0x02) ? 'b' : '.',
830                   (data & 0x04) ? 'c' : '.',
831                   (data & 0x08) ? 'd' : '.',
832                   (data & 0x10) ? 'e' : '.',
833                   (data & 0x20) ? 'f' : '.',
834                   (data & 0x40) ? 'g' : '.');
835               videoram[(which - 4) * 2 + 0] = data & 0x7f;
836               videoram[(which - 4) * 2 + 1] = 15;
837            }
838         }
839      }
840      break;
841   case 0x01:
842   case 0x09:                     /* Data direction register A */
843      logerror("m6530(%d) DDRA  write: $%02x\n", chip, data);
844      m6530[chip].ddra = data;
845      break;
846   case 0x02:
847   case 0x0a:                     /* Data register B */
848      logerror("m6530(%d) DRB   write: $%02x\n", chip, data);
849      m6530[chip].drob = data;
850      if (chip == 1)
851      {
852         int which = m6530[1].ddrb & m6530[1].drob;
853
854         if ((which & 0x3f) == 0x27)
855         {
856            /* This is the cassette output port */
857            logerror("write cassette port: %d\n", (which & 0x80) ? 1 : 0);
858            dac_signed_data_w(0, (which & 0x80) ? 255 : 0);
859         }
860      }
861      break;
862   case 0x03:
863   case 0x0b:                     /* Data direction register B */
864      logerror("m6530(%d) DDRB  write: $%02x\n", chip, data);
865      m6530[chip].ddrb = data;
866      break;
867   case 0x04:
868   case 0x0c:                     /* Timer 1 start */
869      logerror("m6530(%d) TMR1  write: $%02x%s\n", chip, data, (offset & 8) ? " (IRQ)" : "");
870      m6530[chip].state &= ~0x80;
871      m6530[chip].irqen = (offset & 8) ? 1 : 0;
872      m6530[chip].clock = (double) 1000000 / 1;
873      set_chip_clock(chip, data);
874      break;
875   case 0x05:
876   case 0x0d:                     /* Timer 8 start */
877      logerror("m6530(%d) TMR8  write: $%02x%s\n", chip, data, (offset & 8) ? " (IRQ)" : "");
878      m6530[chip].state &= ~0x80;
879      m6530[chip].irqen = (offset & 8) ? 1 : 0;
880      m6530[chip].clock = (double) 1000000 / 8;
881      set_chip_clock(chip, data);
882      break;
883   case 0x06:
884   case 0x0e:                     /* Timer 64 start */
885      logerror("m6530(%d) TMR64 write: $%02x%s\n", chip, data, (offset & 8) ? " (IRQ)" : "");
886      m6530[chip].state &= ~0x80;
887      m6530[chip].irqen = (offset & 8) ? 1 : 0;
888      m6530[chip].clock = (double) 1000000 / 64;
889      set_chip_clock(chip, data);
890      break;
891   case 0x07:
892   case 0x0f:                     /* Timer 1024 start */
893      logerror("m6530(%d) TMR1K write: $%02x%s\n", chip, data, (offset & 8) ? " (IRQ)" : "");
894      m6530[chip].state &= ~0x80;
895      m6530[chip].irqen = (offset & 8) ? 1 : 0;
896      m6530[chip].clock = (double) 1000000 / 1024;
897      set_chip_clock(chip, data);
898      break;
899   }
900}
901
902WRITE8_HANDLER ( m6530_003_w )
903{
904   m6530_w(0, offset, data);
905}
906WRITE8_HANDLER ( m6530_002_w )
907{
908   m6530_w(1, offset, data);
909}
910
911635void kim1_cassette_getinfo(const mess_device_class *devclass, UINT32 state, union devinfo *info)
912636{
913637   switch(state)
src/mess/machine/6530miot.c
r0r3296
1/***************************************************************************
2
3  MIOT 6530 emulation
4
5The timer seems to follow these rules:
6- When the timer flag changes from 0 to 1 the timer continues to count
7  down at a 1 cycle rate.
8- When the timer is being read or written the timer flag is reset.
9- When the timer flag is set and the timer contents are 0, the counting
10  stops.
11
12***************************************************************************/
13
14#include "driver.h"
15#include "6530miot.h"
16
17
18/***************************************************************************
19    CONSTANTS
20***************************************************************************/
21
22enum
23{
24   TIMER_IDLE,
25   TIMER_COUNTING,
26   TIMER_FINISHING
27};
28
29#define TIMER_FLAG      0x80
30
31
32
33/***************************************************************************
34    TYPE DEFINITIONS
35***************************************************************************/
36
37typedef struct _miot6530_port miot6530_port;
38struct _miot6530_port
39{
40   UINT8            in;
41   UINT8            out;
42   UINT8            ddr;
43   miot_read_func      in_func;
44   miot_write_func      out_func;
45};
46
47
48typedef struct _miot6530_state miot6530_state;
49struct _miot6530_state
50{
51   const miot6530_interface *intf;
52
53   miot6530_port   port[2];
54
55   UINT8         irqstate;
56   UINT8         irqenable;
57
58   UINT8         timershift;
59   UINT8         timerstate;
60   emu_timer *      timer;
61
62   UINT32         clock;
63};
64
65
66
67/***************************************************************************
68    INLINE FUNCTIONS
69***************************************************************************/
70
71/*-------------------------------------------------
72    get_safe_token - convert a device's token
73    into a miot6530_state
74-------------------------------------------------*/
75
76INLINE miot6530_state *get_safe_token(const device_config *device)
77{
78   assert(device != NULL);
79   assert(device->token != NULL);
80   assert(device->type == MIOT6530);
81   return (miot6530_state *)device->token;
82}
83
84
85/*-------------------------------------------------
86    update_irqstate - update the IRQ state
87    based on interrupt enables
88-------------------------------------------------*/
89
90INLINE void update_irqstate(const device_config *device)
91{
92   miot6530_state *miot = get_safe_token(device);
93   UINT8 out = miot->port[1].out;
94
95   if ( miot->irqenable )
96      out = ( ( miot->irqstate & TIMER_FLAG ) ? 0x00 : 0x80 ) | ( out & 0x7F );
97
98   if (miot->port[1].out_func != NULL)
99      (*miot->port[1].out_func)(device, out, out);
100   else
101      logerror("6530MIOT chip %s: Port B is being written to but has no handler.\n", device->tag);
102}
103
104
105/*-------------------------------------------------
106    get_timer - return the current timer value
107-------------------------------------------------*/
108
109INLINE UINT8 get_timer(miot6530_state *miot)
110{
111   /* if idle, return 0 */
112   if (miot->timerstate == TIMER_IDLE)
113      return 0;
114
115   /* if counting, return the number of ticks remaining */
116   else if (miot->timerstate == TIMER_COUNTING)
117      return attotime_to_ticks(timer_timeleft(miot->timer), miot->clock) >> miot->timershift;
118
119   /* if finishing, return the number of ticks without the shift */
120   else
121      return attotime_to_ticks(timer_timeleft(miot->timer), miot->clock);
122}
123
124
125/***************************************************************************
126    INTERNAL FUNCTIONS
127***************************************************************************/
128
129/*-------------------------------------------------
130    timer_end_callback - callback to process the
131    timer
132-------------------------------------------------*/
133
134static TIMER_CALLBACK( timer_end_callback )
135{
136   const device_config *device = ptr;
137   miot6530_state *miot = get_safe_token(device);
138
139   assert(miot->timerstate != TIMER_IDLE);
140
141   /* if we finished counting, switch to the finishing state */
142   if (miot->timerstate == TIMER_COUNTING)
143   {
144      miot->timerstate = TIMER_FINISHING;
145      timer_adjust_oneshot(miot->timer, ticks_to_attotime(256, miot->clock), 0);
146
147      /* signal timer IRQ as well */
148      miot->irqstate |= TIMER_FLAG;
149      update_irqstate(device);
150   }
151
152   /* if we finished finishing, switch to the idle state */
153   else if (miot->timerstate == TIMER_FINISHING)
154   {
155      miot->timerstate = TIMER_IDLE;
156      timer_adjust_oneshot(miot->timer, attotime_never, 0);
157   }
158}
159
160
161
162/***************************************************************************
163    I/O ACCESS
164***************************************************************************/
165
166/*-------------------------------------------------
167    miot6530_w - master I/O write access
168-------------------------------------------------*/
169
170WRITE8_DEVICE_HANDLER( miot6530_w )
171{
172   miot6530_state *miot = get_safe_token(device);
173
174   /* if A2 == 1, we are writing to the timer */
175   if (offset & 0x04)
176   {
177      static const UINT8 timershift[4] = { 0, 3, 6, 10 };
178      attotime curtime = timer_get_time();
179      INT64 target;
180
181      /* A0-A1 contain the timer divisor */
182      miot->timershift = timershift[offset & 3];
183
184      /* A3 contains the timer IRQ enable */
185      if (offset & 8)
186         miot->irqenable |= TIMER_FLAG;
187      else
188         miot->irqenable &= ~TIMER_FLAG;
189
190      /* writes here clear the timer flag */
191      if (miot->timerstate != TIMER_FINISHING || get_timer(miot) != 0xff)
192         miot->irqstate &= ~TIMER_FLAG;
193      update_irqstate(device);
194
195      /* update the timer */
196      miot->timerstate = TIMER_COUNTING;
197      target = attotime_to_ticks(curtime, miot->clock) + 1 + (data << miot->timershift);
198      timer_adjust_oneshot(miot->timer, attotime_sub(ticks_to_attotime(target, miot->clock), curtime), 0);
199   }
200
201   /* if A2 == 0, we are writing to the I/O section */
202   else
203   {
204      /* A1 selects the port */
205      miot6530_port *port = &miot->port[(offset >> 1) & 1];
206
207      /* if A0 == 1, we are writing to the port's DDR */
208      if (offset & 1)
209         port->ddr = data;
210
211      /* if A0 == 0, we are writing to the port's output */
212      else
213      {
214         UINT8 olddata = port->out;
215         port->out = data;
216
217         if ( ( offset & 2 ) && miot->irqenable )
218         {
219            olddata = ( ( miot->irqstate & TIMER_FLAG ) ? 0x00 : 0x80 ) | ( olddata & 0x7F );
220            data = ( ( miot->irqstate & TIMER_FLAG ) ? 0x00 : 0x80 ) | ( data & 0x7F );
221         }
222
223         if (port->out_func != NULL)
224            (*port->out_func)(device, data, olddata);
225         else
226            logerror("6530MIOT chip %s: Port %c is being written to but has no handler.  PC: %08X - %02X\n", device->tag, 'A' + (offset & 1), safe_activecpu_get_pc(), data);
227      }
228   }
229}
230
231
232/*-------------------------------------------------
233    miot6530_r - master I/O read access
234-------------------------------------------------*/
235
236READ8_DEVICE_HANDLER( miot6530_r )
237{
238   miot6530_state *miot = get_safe_token(device);
239   UINT8 val = 0;
240
241   /* if A2 == 1 and A0 == 1, we are reading interrupt flags */
242   if ((offset & 0x05) == 0x05)
243   {
244      val = miot->irqstate;
245   }
246
247   /* if A2 == 1 and A0 == 0, we are reading the timer */
248   else if ((offset & 0x05) == 0x04)
249   {
250      val = get_timer(miot);
251
252      /* A3 contains the timer IRQ enable */
253      if (offset & 8)
254         miot->irqenable |= TIMER_FLAG;
255      else
256         miot->irqenable &= ~TIMER_FLAG;
257
258      /* implicitly clears the timer flag */
259      if (miot->timerstate != TIMER_FINISHING || val != 0xff)
260         miot->irqstate &= ~TIMER_FLAG;
261      update_irqstate(device);
262   }
263
264   /* if A2 == 0 and A0 == anything, we are reading from ports */
265   else
266   {
267      /* A1 selects the port */
268      miot6530_port *port = &miot->port[(offset >> 1) & 1];
269
270      /* if A0 == 1, we are reading the port's DDR */
271      if (offset & 1)
272         val = port->ddr;
273
274      /* if A0 == 0, we are reading the port as an input */
275      else
276      {
277         UINT8   out = port->out;
278
279         if ( ( offset & 2 ) && miot->irqenable )
280            out = ( ( miot->irqstate & TIMER_FLAG ) ? 0x00 : 0x80 ) | ( out & 0x7F );
281
282         /* call the input callback if it exists */
283         if (port->in_func != NULL)
284         {
285            port->in = (*port->in_func)(device, port->in);
286         }
287         else
288            logerror("6530MIOT chip %s: Port %c is being read but has no handler.  PC: %08X\n", device->tag, 'A' + (offset & 1), safe_activecpu_get_pc());
289
290         /* apply the DDR to the result */
291         val = (out & port->ddr) | (port->in & ~port->ddr);
292      }
293   }
294   return val;
295}
296
297
298/*-------------------------------------------------
299    miot6530_porta_in_set - set port A input
300    value
301-------------------------------------------------*/
302
303void miot6530_porta_in_set(const device_config *device, UINT8 data, UINT8 mask)
304{
305   miot6530_state *miot = get_safe_token(device);
306   miot->port[0].in = (miot->port[0].in & ~mask) | (data & mask);
307}
308
309
310/*-------------------------------------------------
311    miot6530_portb_in_set - set port B input
312    value
313-------------------------------------------------*/
314
315void miot6530_portb_in_set(const device_config *device, UINT8 data, UINT8 mask)
316{
317   miot6530_state *miot = get_safe_token(device);
318   miot->port[1].in = (miot->port[1].in & ~mask) | (data & mask);
319}
320
321
322/*-------------------------------------------------
323    miot6530_porta_in_get - return port A input
324    value
325-------------------------------------------------*/
326
327UINT8 miot6530_porta_in_get(const device_config *device)
328{
329   miot6530_state *miot = get_safe_token(device);
330   return miot->port[0].in;
331}
332
333
334/*-------------------------------------------------
335    miot6530_portb_in_get - return port B input
336    value
337-------------------------------------------------*/
338
339UINT8 miot6530_portb_in_get(const device_config *device)
340{
341   miot6530_state *miot = get_safe_token(device);
342   return miot->port[1].in;
343}
344
345
346/*-------------------------------------------------
347    miot6530_porta_in_get - return port A output
348    value
349-------------------------------------------------*/
350
351UINT8 miot6530_porta_out_get(const device_config *device)
352{
353   miot6530_state *miot = get_safe_token(device);
354   return miot->port[0].out;
355}
356
357
358/*-------------------------------------------------
359    miot6530_portb_in_get - return port B output
360    value
361-------------------------------------------------*/
362
363UINT8 miot6530_portb_out_get(const device_config *device)
364{
365   miot6530_state *miot = get_safe_token(device);
366   return miot->port[1].out;
367}
368
369
370/***************************************************************************
371    DEVICE INTERFACE
372***************************************************************************/
373
374static DEVICE_START( miot6530 )
375{
376   const miot6530_config *config = device->inline_config;
377   miot6530_state *miot = get_safe_token(device);
378   char unique_tag[30];
379
380   /* validate arguments */
381   assert(device != NULL);
382   assert(device->tag != NULL);
383   assert(strlen(device->tag) < 20);
384
385   /* set static values */
386   miot->intf = device->static_config;
387   miot->clock = config->clock;
388
389   /* configure the ports */
390   miot->port[0].in_func = miot->intf->in_a_func;
391   miot->port[0].out_func = miot->intf->out_a_func;
392   miot->port[1].in_func = miot->intf->in_b_func;
393   miot->port[1].out_func = miot->intf->out_b_func;
394
395   /* allocate timers */
396   miot->timer = timer_alloc(timer_end_callback, (void *)device);
397
398   /* register for save states */
399   state_save_combine_module_and_tag(unique_tag, "miot6530", device->tag);
400
401   state_save_register_item(unique_tag, 0, miot->port[0].in);
402   state_save_register_item(unique_tag, 0, miot->port[0].out);
403   state_save_register_item(unique_tag, 0, miot->port[0].ddr);
404   state_save_register_item(unique_tag, 0, miot->port[1].in);
405   state_save_register_item(unique_tag, 0, miot->port[1].out);
406   state_save_register_item(unique_tag, 0, miot->port[1].ddr);
407
408   state_save_register_item(unique_tag, 0, miot->irqstate);
409   state_save_register_item(unique_tag, 0, miot->irqenable);
410
411   state_save_register_item(unique_tag, 0, miot->timershift);
412   state_save_register_item(unique_tag, 0, miot->timerstate);
413
414   return DEVICE_START_OK;
415}
416
417
418static DEVICE_RESET( miot6530 )
419{
420   miot6530_state *miot = get_safe_token(device);
421
422   /* reset I/O states */
423   miot->port[0].out = 0;
424   miot->port[0].ddr = 0;
425   miot->port[1].out = 0;
426   miot->port[1].ddr = 0;
427
428   /* reset IRQ states */
429   miot->irqenable = 0;
430   miot->irqstate = 0;
431   update_irqstate(device);
432
433   /* reset timer states */
434   miot->timershift = 0;
435   miot->timerstate = TIMER_IDLE;
436   timer_adjust_oneshot(miot->timer, attotime_never, 0);
437}
438
439
440static DEVICE_SET_INFO( miot6530 )
441{
442   switch (state)
443   {
444      /* no parameters to set */
445   }
446}
447
448
449DEVICE_GET_INFO( miot6530 )
450{
451   switch (state)
452   {
453      /* --- the following bits of info are returned as 64-bit signed integers --- */
454      case DEVINFO_INT_TOKEN_BYTES:               info->i = sizeof(miot6530_state);      break;
455      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = sizeof(miot6530_config);      break;
456      case DEVINFO_INT_CLASS:                     info->i = DEVICE_CLASS_PERIPHERAL;      break;
457
458      /* --- the following bits of info are returned as pointers to data or functions --- */
459      case DEVINFO_FCT_SET_INFO:                  info->set_info = DEVICE_SET_INFO_NAME(miot6530); break;
460      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(miot6530);break;
461      case DEVINFO_FCT_STOP:                     /* Nothing */                     break;
462      case DEVINFO_FCT_RESET:                     info->reset = DEVICE_RESET_NAME(miot6530);break;
463
464      /* --- the following bits of info are returned as NULL-terminated strings --- */
465      case DEVINFO_STR_NAME:                     info->s = "6530 (MIOT)";            break;
466      case DEVINFO_STR_FAMILY:                  info->s = "I/O devices";            break;
467      case DEVINFO_STR_VERSION:                  info->s = "1.0";                  break;
468      case DEVINFO_STR_SOURCE_FILE:               info->s = __FILE__;                  break;
469      case DEVINFO_STR_CREDITS:                  info->s = "Copyright Nicola Salmoria and the MAME Team"; break;
470   }
471}
src/mess/machine/6530miot.h
r0r3296
1/***************************************************************************
2
3  MIOT 6530 emulation
4
5***************************************************************************/
6
7#ifndef __MIOT6530_H__
8#define __MIOT6530_H__
9
10
11/***************************************************************************
12    TYPE DEFINITIONS
13***************************************************************************/
14
15typedef struct _miot6530_config miot6530_config;
16struct _miot6530_config
17{
18   UINT32               clock;
19};
20
21
22typedef UINT8 (*miot_read_func)(const device_config *device, UINT8 olddata);
23typedef void (*miot_write_func)(const device_config *device, UINT8 newdata, UINT8 olddata);
24
25
26typedef struct _miot6530_interface miot6530_interface;
27struct _miot6530_interface
28{
29   miot_read_func      in_a_func;
30   miot_read_func      in_b_func;
31   miot_write_func      out_a_func;
32   miot_write_func      out_b_func;
33};
34
35
36
37/***************************************************************************
38    DEVICE CONFIGURATION MACROS
39***************************************************************************/
40
41#define MDRV_MIOT6530_ADD(_tag, _clock, _intrf) \
42   MDRV_DEVICE_ADD(_tag, MIOT6530) \
43   MDRV_DEVICE_CONFIG_DATA32(miot6530_config, clock, _clock) \
44   MDRV_DEVICE_CONFIG(_intrf)
45
46#define MDRV_MIOT6530_REMOVE(_tag) \
47   MDRV_DEVICE_REMOVE(_tag, MIOT6530)
48
49
50
51/***************************************************************************
52    FUNCTION PROTOTYPES
53***************************************************************************/
54
55READ8_DEVICE_HANDLER( miot6530_r );
56WRITE8_DEVICE_HANDLER( miot6530_w );
57
58void miot6530_porta_in_set(const device_config *device, UINT8 data, UINT8 mask);
59void miot6530_portb_in_set(const device_config *device, UINT8 data, UINT8 mask);
60
61UINT8 miot6530_porta_in_get(const device_config *device);
62UINT8 miot6530_portb_in_get(const device_config *device);
63
64UINT8 miot6530_porta_out_get(const device_config *device);
65UINT8 miot6530_portb_out_get(const device_config *device);
66
67
68/* ----- device interface ----- */
69
70#define MIOT6530 DEVICE_GET_INFO_NAME(miot6530)
71DEVICE_GET_INFO( miot6530 );
72
73#endif
src/mess/mess.mak
r3295r3296
511511   $(MESS_MACHINE)/68901mfp.o \
512512   $(MESS_FORMATS)/rk_cas.o   \
513513   $(MESS_VIDEO)/msm6255.o   \
514   $(MESS_MACHINE)/6530miot.o   \
514515
515516
516517
src/mess/drivers/kim1.c
r3295r3296
6565
6666#include "driver.h"
6767#include "includes/kim1.h"
68#include "machine/6530miot.h"
6869
70
6971static ADDRESS_MAP_START ( kim1_map , ADDRESS_SPACE_PROGRAM, 8)
7072   AM_RANGE(0x0000, 0x03ff) AM_MIRROR(0xe000) AM_RAM
71   AM_RANGE(0x1700, 0x173f) AM_MIRROR(0xe000) AM_READWRITE( m6530_003_r, m6530_003_w )
72   AM_RANGE(0x1740, 0x177f) AM_MIRROR(0xe000) AM_READWRITE( m6530_002_r, m6530_002_w )
73   AM_RANGE(0x1700, 0x173f) AM_MIRROR(0xe000) AM_DEVREADWRITE( MIOT6530, "miot_u3", miot6530_r, miot6530_w )
74   AM_RANGE(0x1740, 0x177f) AM_MIRROR(0xe000) AM_DEVREADWRITE( MIOT6530, "miot_u2", miot6530_r, miot6530_w )
7375   AM_RANGE(0x1780, 0x17bf) AM_MIRROR(0xe000) AM_RAM
7476   AM_RANGE(0x17c0, 0x17ff) AM_MIRROR(0xe000) AM_RAM
7577   AM_RANGE(0x1800, 0x1bff) AM_MIRROR(0xe000) AM_ROM
r3295r3296
161163GFXDECODE_END
162164
163165
166static UINT8   u2_port_b;
167
168static UINT8 kim1_u2_read_a(const device_config *device, UINT8 olddata)
169{
170   UINT8   data = 0xff;
171
172   switch( ( u2_port_b >> 1 ) & 0x0f )
173   {
174   case 0:
175      data = input_port_read(device->machine, "LINE0");
176      break;
177   case 1:
178      data = input_port_read(device->machine, "LINE1");
179      break;
180   case 2:
181      data = input_port_read(device->machine, "LINE2");
182      break;
183   }
184   return data;
185}
186
187
188static void kim1_u2_write_a(const device_config *device, UINT8 newdata, UINT8 olddata)
189{
190   switch( ( u2_port_b >> 1 ) & 0x0f )
191   {
192   case 4:
193   case 5:
194   case 6:
195   case 7:
196   case 8:
197   case 9:
198      if ( newdata & 0x80 )
199      {
200         videoram[(( ( u2_port_b >> 1 ) & 0x0f ) - 4) * 2 + 0] = newdata & 0x7f;
201         videoram[(( ( u2_port_b >> 1 ) & 0x0f ) - 4) * 2 + 1] = 15;
202      }
203      break;
204   }
205}
206
207
208static UINT8 kim1_u2_read_b(const device_config *device, UINT8 olddata)
209{
210   return 0xFF;
211}
212
213
214static void kim1_u2_write_b(const device_config *device, UINT8 newdata, UINT8 olddata)
215{
216   u2_port_b = newdata;
217
218   if ( ( newdata & 0x3f ) == 0x27 )
219   {
220      /* cassette write/speaker update */
221   }
222
223   /* Set IRQ when bit 7 is cleared */
224}
225
226
227static const miot6530_interface kim1_u2_miot6530_interface =
228{
229   kim1_u2_read_a,
230   kim1_u2_read_b,
231   kim1_u2_write_a,
232   kim1_u2_write_b
233};
234
235
236static UINT8 kim1_u3_read_a(const device_config *device, UINT8 olddata)
237{
238   return 0xFF;
239}
240
241
242static void kim1_u3_write_a(const device_config *device, UINT8 newdata, UINT8 olddata)
243{
244}
245
246
247static UINT8 kim1_u3_read_b(const device_config *device, UINT8 olddata)
248{
249   return 0xFF;
250}
251
252
253static void kim1_u3_write_b(const device_config *device, UINT8 newdata, UINT8 olddata)
254{
255}
256
257
258static const miot6530_interface kim1_u3_miot6530_interface =
259{
260   kim1_u3_read_a,
261   kim1_u3_read_b,
262   kim1_u3_write_a,
263   kim1_u3_write_b
264};
265
266
164267static MACHINE_DRIVER_START( kim1 )
165268   /* basic machine hardware */
166269   MDRV_CPU_ADD("main", M6502, 1000000)        /* 1 MHz */
r3295r3296
184287   MDRV_VIDEO_START( kim1 )
185288   MDRV_VIDEO_UPDATE( kim1 )
186289
290   MDRV_MIOT6530_ADD( "miot_u2", 1000000, kim1_u2_miot6530_interface )
291   MDRV_MIOT6530_ADD( "miot_u3", 1000000, kim1_u3_miot6530_interface )
292
187293   /* sound hardware */
188294   MDRV_SPEAKER_STANDARD_MONO("mono")
189295

Previous 15994 Revisions Next


© 1998-2018 The MESS Team