Previous 199869 Revisions Next

r22732 Friday 10th May, 2013 at 13:22:21 UTC by Miodrag Milanović
(MESS)new driver: 15IE-00-013 serial terminal [shattered]

Note: this is without bitbanger abuse part
[src/emu/cpu]cpu.mak
[src/emu/cpu/ie15]ie15.c* ie15.h* ie15dasm.c*
[src/emu/drivers]xtal.h
[src/mess]mess.lst mess.mak
[src/mess/drivers]ie15.c*
[src/tools]unidasm.c

trunk/src/tools/unidasm.c
r22731r22732
134134CPU_DISASSEMBLE( i80c52 );
135135CPU_DISASSEMBLE( i860 );
136136CPU_DISASSEMBLE( i960 );
137CPU_DISASSEMBLE( ie15 );
137138CPU_DISASSEMBLE( jaguardsp );
138139CPU_DISASSEMBLE( jaguargpu );
139140CPU_DISASSEMBLE( konami );
r22731r22732
276277   { "i80c52",     _8bit,  0, CPU_DISASSEMBLE_NAME(i80c52) },
277278   { "i860",       _64le,  0, CPU_DISASSEMBLE_NAME(i860) },
278279   { "i960",       _32le,  0, CPU_DISASSEMBLE_NAME(i960) },
280   { "ie15",       _8bit,  0, CPU_DISASSEMBLE_NAME(ie15) },
279281   { "jaguardsp",  _16be,  0, CPU_DISASSEMBLE_NAME(jaguardsp) },
280282   { "jaguargpu",  _16be,  0, CPU_DISASSEMBLE_NAME(jaguargpu) },
281283   { "konami",     _8bit,  0, CPU_DISASSEMBLE_NAME(konami) },
trunk/src/emu/drivers/xtal.h
r22731r22732
173173   XTAL_28_63636MHz    = 28636363,     /* Later Leland games and Atari GT, Amiga NTSC, Raiden2 h/w (8x NTSC subcarrier)*/
174174   XTAL_30MHz          = 30000000,     /* Impera Magic Card */
175175   XTAL_30_4761MHz     = 30476100,     /* Taito JC */
176   XTAL_30_8MHz        = 30800000,     /* 15IE-00-013 */
176177   XTAL_32MHz          = 32000000,
177178   XTAL_32_22MHz       = 32220000,     /* Typically used on 90's Data East PCBs */
178179   XTAL_32_5304MHz     = 32530400,     /* Seta 2 */
trunk/src/emu/cpu/cpu.mak
r22731r22732
613613
614614
615615#-------------------------------------------------
616# 15IE-00-013 CPU ("Microprogrammed Control Device")
617#-------------------------------------------------
618
619ifneq ($(filter IE15,$(CPUS)),)
620OBJDIRS += $(CPUOBJ)/ie15
621CPUOBJS += $(CPUOBJ)/ie15/ie15.o
622DASMOBJS += $(CPUOBJ)/ie15/ie15dasm.o
623endif
624
625
626#-------------------------------------------------
616627# Intel 4004
617628#-------------------------------------------------
618629
r22731r22732
20952106
20962107$(CPUOBJ)/scudsp/scudspdasm.o: CPUOBJS += $(CPUOBJ)/scudsp/scudspdasm.c
20972108
2109#-------------------------------------------------
2110# Electronika 15IE-00-013
2111#-------------------------------------------------
20982112
2113ifneq ($(filter IE15,$(CPUS)),)
2114OBJDIRS += $(CPUOBJ)/ie15
2115DASMOBJS += $(CPUOBJ)/ie15/ie15dasm.o
2116endif
trunk/src/emu/cpu/ie15/ie15.c
r0r22732
1#include "emu.h"
2#include "debugger.h"
3#include "ie15.h"
4
5//**************************************************************************
6//  MACROS
7//**************************************************************************
8
9#define SKIP_OP(x) do { \
10         x = rop() & 0xf0; \
11         if (x == 0x10 || x == 0x20 || x == 0x30)  \
12            m_PC.w.l = m_PC.w.l + 1; \
13         } while(0)
14
15//**************************************************************************
16//  GLOBAL VARIABLES
17//**************************************************************************
18
19// device type definition
20const device_type IE15 = &device_creator<ie15_device>;
21
22//**************************************************************************
23//  DEVICE INTERFACE
24//**************************************************************************
25
26//-------------------------------------------------
27//  ie15_device - constructor
28//-------------------------------------------------
29ie15_device::ie15_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
30   : cpu_device(mconfig, IE15, "ie15", tag, owner, clock),
31      m_program_config("program", ENDIANNESS_LITTLE, 8, 14),
32      m_io_config("io", ENDIANNESS_LITTLE, 8, 8),
33      m_program(0),
34      m_direct(0)
35{
36   // set our instruction counter
37   m_icountptr = &m_icount;
38};
39
40//-------------------------------------------------
41//  device_start - start up the device
42//-------------------------------------------------
43
44void ie15_device::device_start()
45{
46   // find address spaces
47   m_program = &space(AS_PROGRAM);
48   m_direct = &m_program->direct();
49   m_io = &space(AS_IO);
50
51   // save state
52   save_item(NAME(m_PC));
53   save_item(NAME(m_A));
54   save_item(NAME(m_CF));
55   save_item(NAME(m_ZF));
56   save_item(NAME(m_RF));
57   // XXX save registers
58
59   // register our state for the debugger
60   state_add(IE15_PC,       "PC",       m_PC.w.l).mask(0x0fff);
61   state_add(STATE_GENPC,   "GENPC",    m_PC.w.l).mask(0x0fff).noshow();
62   state_add(STATE_GENFLAGS,"GENFLAGS", m_flags).mask(0x0f).callimport().callexport().noshow().formatstr("%4s");
63   state_add(IE15_A,        "A",        m_A);
64
65   astring tempstring;
66   for (int ireg = 0; ireg < 32; ireg++)
67      state_add(IE15_R0 + ireg, tempstring.format("R%d", ireg), m_REGS[ireg]);
68}
69
70//-------------------------------------------------
71//  device_reset - reset the device
72//-------------------------------------------------
73
74void ie15_device::device_reset()
75{
76   m_CF = m_ZF = m_RF = 0;
77   m_A = 0;
78   m_PC.d = 0;
79   memset(m_REGS,0,sizeof(m_REGS));
80}
81
82//-------------------------------------------------
83//  memory_space_config - return the configuration
84//  of the specified address space, or NULL if
85//  the space doesn't exist
86//-------------------------------------------------
87
88const address_space_config *ie15_device::memory_space_config(address_spacenum spacenum) const
89{
90   return  (spacenum == AS_PROGRAM) ? &m_program_config :
91         (spacenum == AS_IO) ? &m_io_config :
92         NULL;
93}
94
95//-------------------------------------------------
96//  state_import - import state into the device,
97//  after it has been set
98//-------------------------------------------------
99
100void ie15_device::state_import(const device_state_entry &entry)
101{
102   switch (entry.index())
103   {
104      case STATE_GENFLAGS:
105         m_CF = (m_flags >> 3) & 1;
106         m_ZF = (m_flags >> 2) & 1;
107         m_RF = (m_flags >> 1) & 1;
108         break;
109   }
110}
111
112//-------------------------------------------------
113//  state_export - export state from the device,
114//  to a known location where it can be read
115//-------------------------------------------------
116
117void ie15_device::state_export(const device_state_entry &entry)
118{
119   switch (entry.index())
120   {
121      case STATE_GENFLAGS:
122         m_flags = (m_CF ? 0x08 : 0x00) |
123                        (m_ZF ? 0x04 : 0x00) |
124                        (m_RF ? 0x02 : 0x00);
125         break;
126   }
127}
128
129//-------------------------------------------------
130//  state_string_export - export state as a string
131//  for the debugger
132//-------------------------------------------------
133
134void ie15_device::state_string_export(const device_state_entry &entry, astring &string)
135{
136   switch (entry.index())
137   {
138      case STATE_GENFLAGS:
139         string.printf("%c%c%c",
140            m_CF ? 'C':'.',
141            m_ZF ? 'Z':'.',
142            m_RF ? 'R':'.');
143         break;
144   }
145}
146
147//-------------------------------------------------
148//  disasm_min_opcode_bytes - return the length
149//  of the shortest instruction, in bytes
150//-------------------------------------------------
151
152UINT32 ie15_device::disasm_min_opcode_bytes() const
153{
154   return 1;
155}
156
157//-------------------------------------------------
158//  disasm_max_opcode_bytes - return the length
159//  of the longest instruction, in bytes
160//-------------------------------------------------
161
162UINT32 ie15_device::disasm_max_opcode_bytes() const
163{
164   return 2;
165}
166
167//-------------------------------------------------
168//  disasm_disassemble - call the disassembly
169//  helper function
170//-------------------------------------------------
171
172offs_t ie15_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
173{
174   extern CPU_DISASSEMBLE( ie15 );
175   return CPU_DISASSEMBLE_NAME(ie15)(NULL, buffer, pc, oprom, opram, 0);
176}
177
178//**************************************************************************
179//  EXECUTION
180//**************************************************************************
181
182//-------------------------------------------------
183//  execute_min_cycles - return minimum number of
184//  cycles it takes for one instruction to execute
185//-------------------------------------------------
186
187UINT32 ie15_device::execute_min_cycles() const
188{
189   return 1;
190}
191
192//-------------------------------------------------
193//  execute_max_cycles - return maximum number of
194//  cycles it takes for one instruction to execute
195//-------------------------------------------------
196
197UINT32 ie15_device::execute_max_cycles() const
198{
199   return 1;
200}
201
202//-------------------------------------------------
203//  execute_run - execute until our icount expires
204//-------------------------------------------------
205
206void ie15_device::execute_run()
207{
208   do
209   {
210      debugger_instruction_hook(this, m_PC.d);
211      execute_one(rop());
212   } while (m_icount > 0);
213}
214
215inline void ie15_device::illegal(UINT8 opcode)
216{
217   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
218   {
219      logerror("IE15 illegal instruction %04X $%02X\n", m_PC.w.l, opcode);
220   }
221}
222
223// XXX verify that m_ZF and m_CF are set and handled right
224// XXX 'ota' apparently writes the ALU buffer register, not accumulator
225// XXX what if ldc was at 0x_ff?
226inline void ie15_device::execute_one(int opcode)
227{
228   UINT16 tmp;
229
230   m_icount -= 1;
231
232   switch (opcode & 0xf0)
233   {
234      case 0x00:   // add
235         tmp = m_A + get_reg_lo(opcode & 15);
236         m_A = tmp & 255;
237         update_flags(m_A);
238         m_CF = BIT(tmp, 8);
239         break;
240      case 0x10:   // jmp
241         m_PC.w.l = get_addr(opcode);
242//         m_CF = 0;
243         break;
244      case 0x20:   // ldc
245         set_reg(opcode & 15, arg() | (m_PC.w.l & 0xf00));
246         m_PC.w.l = m_PC.w.l + 1;
247//         m_CF = 0;
248         break;
249      case 0x40:    // dsr
250         tmp = get_reg_lo(opcode & 15) - 1;
251//         m_CF = BIT(tmp, 8);
252         tmp &= 255;
253         set_reg(opcode & 15, tmp);
254         update_flags(tmp);
255         if (m_ZF) {
256            SKIP_OP(tmp);
257         }
258         break;
259      case 0x30:
260         switch (opcode)
261         {
262            case 0x30:   // lca
263               m_A = arg();
264               update_flags(m_A);
265               m_PC.w.l = m_PC.w.l + 1;
266               break;
267            case 0x33:   // ral
268               tmp = m_A;
269               m_A = (m_A << 1) | BIT(tmp,7);
270               update_flags(m_A);
271               break;
272            case 0x35:   // rar
273               tmp = m_A;
274               m_A = (m_A >> 1) | (BIT(tmp,0) ? 0x80 : 0x00);
275               update_flags(m_A);
276               break;
277            default:
278               illegal(opcode);
279               break;
280         };
281         break;
282      case 0x50:
283         switch (opcode)
284         {
285            case 0x51:   // inc
286            case 0x50:   // isn
287            case 0x58:   // ise
288               tmp = m_A + 1;
289               m_A = tmp & 255;
290               update_flags(m_A);
291               m_CF = BIT(tmp, 8);
292               if (opcode == 0x50 && m_ZF)
293                  SKIP_OP(tmp);
294               if (opcode == 0x58 && !m_ZF)
295                  SKIP_OP(tmp);
296               break;
297            case 0x5b:   // dec
298            case 0x52:   // dsn
299            case 0x5a:   // dse
300               tmp = m_A - 1;
301               m_A = tmp & 255;
302               update_flags(m_A);
303               m_CF = BIT(tmp, 8);
304               if (opcode == 0x52 && m_ZF)
305                  SKIP_OP(tmp);
306               if (opcode == 0x5a && !m_ZF)
307                  SKIP_OP(tmp);
308               break;
309            case 0x5d:   // com
310               m_A ^= 255;
311               update_flags(m_A);
312               break;
313            case 0x5f:   // clr
314               m_A = 0;
315               update_flags(m_A);
316               break;
317            default:
318               illegal(opcode);
319               break;
320         };
321         break;
322      case 0x70:   // jmi
323//         m_CF = 0;
324         m_PC.w.l = get_reg(opcode & 15);
325         break;
326      case 0x60:   // lla
327         // special case -- port 7
328         if (opcode == 0x67)
329            m_A = 255;
330         else
331            m_A = m_io->read_byte(opcode & 15);
332         update_flags(m_A);
333         break;
334      case 0xf0:   // ota
335         // special case -- ports 016, 017
336         if (opcode == 0xfe)
337            m_RF = 1;
338         else if (opcode == 0xff)
339            m_RF = 0;
340         else
341            m_io->write_byte(opcode & 15, m_A);
342//         m_CF = 0;
343         break;
344      case 0xc0:   // cfl, sfl
345         switch (opcode)
346         {
347            // special case -- accessing control flag 05 resets CF
348            case 0xc5:
349            case 0xcd:
350               m_CF = 0;
351               break;
352            default:
353               m_io->write_byte(020 | (opcode & 7), BIT(opcode, 3));
354               break;
355         }
356         break;
357      case 0x80:   // sfc, skp, sfs, nop
358         tmp = opcode & 7;
359         switch (tmp)
360         {
361            case 5:
362               tmp = BIT(m_A, 7);
363               break;
364            case 6:
365               tmp = m_CF;
366               break;
367            case 7:
368               tmp = 0;
369               break;
370            default:
371               tmp = m_io->read_byte(020 | tmp);
372               break;
373
374         }
375         if (!BIT(opcode, 3) && !tmp)
376            SKIP_OP(tmp);
377         if (BIT(opcode, 3) && tmp)
378            SKIP_OP(tmp);
379         break;
380      case 0xb0:   // cs
381//         m_CF = 0;
382         if (m_A == get_reg_lo(opcode & 15)) {
383            m_ZF = 1;
384            SKIP_OP(tmp);
385         }
386         break;
387      case 0x90:   // and
388         m_A &= get_reg_lo(opcode & 15);
389         update_flags(m_A);
390         break;
391      case 0xa0:   // xor
392         m_A ^= get_reg_lo(opcode & 15);
393         update_flags(m_A);
394         break;
395      case 0xd0:   // lda
396         m_A = get_reg_lo(opcode & 15);
397         update_flags(m_A);
398         break;
399      case 0xe0:   // sta
400         set_reg(opcode & 15, m_A | (m_PC.w.l & 0xf00));
401//         m_CF = 0;
402         break;
403      default:
404         illegal(opcode);
405         break;
406   }
407}
408
409/***************************************************************************
410    INLINE FUNCTIONS
411***************************************************************************/
412
413inline UINT8 ie15_device::rop()
414{
415   UINT8 retVal = m_direct->read_decrypted_byte(m_PC.w.l);
416   m_PC.w.l = (m_PC.w.l + 1) & 0x0fff;
417   return retVal;
418}
419
420inline UINT8 ie15_device::arg()
421{
422   UINT8 retVal = m_direct->read_raw_byte(m_PC.w.l);
423   return retVal;
424}
425
426inline UINT8 ie15_device::get_reg_lo(UINT8 reg)
427{
428   UINT16 tmp = m_RF ? m_REGS[16 + reg] : m_REGS[reg];
429   return tmp & 255;
430}
431
432inline UINT16 ie15_device::get_reg(UINT8 reg)
433{
434   return m_RF ? m_REGS[16 + reg] : m_REGS[reg];
435}
436
437inline void ie15_device::set_reg(UINT8 reg, UINT16 val)
438{
439   (m_RF ? m_REGS[16 + reg] : m_REGS[reg]) = val;
440   
441}
442
443inline void ie15_device::update_flags(UINT8 val)
444{
445   m_ZF = (val == 0xff) ? 1 : 0;
446}
447
448inline UINT8 ie15_device::do_condition(UINT8 val)
449{
450   UINT8 v = (val >> 5) & 1;
451   UINT8 cond = 0;
452   switch((val>> 3) & 0x03) {
453      case 0 :
454            if (m_CF==v) cond = 1;
455            break;
456      case 1 :
457            if (m_ZF==v) cond = 1;
458            break;
459   }
460   return cond;
461}
462
463inline UINT16 ie15_device::get_addr(UINT8 val)
464{
465   UINT8 lo = arg();
466   return ((val & 0x0f) << 8) + lo + 1;
467}
Property changes on: trunk/src/emu/cpu/ie15/ie15.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/emu/cpu/ie15/ie15dasm.c
r0r22732
1#include "emu.h"
2
3#define OP(A)   oprom[(A) - PC]
4#define ARG(A)  opram[(A) - PC]
5
6CPU_DISASSEMBLE( ie15 )
7{
8   UINT32 flags = 0;
9   UINT8 op;
10   unsigned PC = pc;
11
12   op = OP(pc++);
13   switch (op & 0xf0)
14   {
15      case 0x00:
16         sprintf (buffer,"add  r%d", op & 0x0f);             
17         break;
18      case 0x10:
19         sprintf (buffer,"jmp  $%04x", (((op & 0x0f) << 8) | ARG(pc)) + 1);
20         pc+=1;     
21         break;
22      case 0x20:
23         sprintf (buffer,"ldc  r%d, #$%02x", (op & 0x0f), ARG(pc));
24         pc+=1;     
25         break;
26      case 0x30: switch (op)
27      {
28         case 0x30:
29            sprintf (buffer,"lca  #$%02x", ARG(pc));       
30            pc+=1;
31            break;
32         case 0x33:
33            sprintf (buffer,"ral");                     
34            break;
35         case 0x35:
36            sprintf (buffer,"rar");                     
37            break;
38         default:
39            sprintf (buffer,"illegal");
40            break;
41      };
42      break;
43      case 0x40:
44         sprintf (buffer,"dsr  r%d", op & 0x0f);             
45         break;
46      case 0x50: switch (op)
47      {
48         case 0x50:
49            sprintf (buffer,"isn");                     
50            break;
51         case 0x51:
52            sprintf (buffer,"inc");                     
53            break;
54         case 0x52:
55            sprintf (buffer,"dsn");                     
56            break;
57         case 0x58:
58            sprintf (buffer,"ise");                     
59            break;
60         case 0x5a:
61            sprintf (buffer,"dse");                     
62            break;
63         case 0x5b:
64            sprintf (buffer,"dec");                     
65            break;
66         case 0x5d:
67            sprintf (buffer,"com");                     
68            break;
69         case 0x5f:
70            sprintf (buffer,"clr");                     
71            break;
72         default:
73            sprintf (buffer,"illegal");
74            break;
75      };
76      break;
77      case 0x60:
78         sprintf (buffer,"lla  #$%02x", op & 0x0f);             
79         break;
80      case 0x70:
81         sprintf (buffer,"jmi  r%d", op & 0x0f);             
82         break;
83      case 0x80: switch (op)
84      {
85         case 0x80: case 0x81: case 0x82: case 0x83:
86         case 0x84: case 0x85: case 0x86:
87            sprintf (buffer,"sfc  #%d", op & 0x07);       
88            break;
89         case 0x87:
90            sprintf (buffer,"skp");                     
91            break;
92         case 0x88: case 0x89: case 0x8a: case 0x8b:
93         case 0x8c: case 0x8d: case 0x8e:
94            sprintf (buffer,"sfs  #%d", op & 0x07);       
95            break;
96         case 0x8f:
97            sprintf (buffer,"nop");                     
98            break;
99      };
100      break;
101      case 0x90:
102         sprintf (buffer,"and  r%d", op & 0x0f);             
103         break;
104      case 0xa0:
105         sprintf (buffer,"xor  r%d", op & 0x0f);             
106         break;
107      case 0xb0:
108         sprintf (buffer,"cs   r%d", op & 0x0f);             
109         break;
110      case 0xc0:
111         sprintf (buffer,"%s  #%d", BIT(op, 3) ? "sfl" : "cfl", op & 0x07);             
112         break;
113      case 0xd0:
114         sprintf (buffer,"lda  r%d", op & 0x0f);             
115         break;
116      case 0xe0:
117         sprintf (buffer,"sta  r%d", op & 0x0f);             
118         break;
119      case 0xf0:
120         sprintf (buffer,"ota  #$%02x", op & 0x0f);             
121         break;
122   }
123   return (pc - PC) | flags | DASMFLAG_SUPPORTED;
124}
Property changes on: trunk/src/emu/cpu/ie15/ie15dasm.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/emu/cpu/ie15/ie15.h
r0r22732
1#ifndef __IE15_H__
2#define __IE15_H__
3
4//**************************************************************************
5//  ENUMERATIONS
6//**************************************************************************
7
8enum
9{
10   IE15_PC,
11   IE15_A,
12   IE15_R0, IE15_R1, IE15_R2, IE15_R3, IE15_R4, IE15_R5, IE15_R6, IE15_R7,
13   IE15_R8, IE15_R9, IE15_R10, IE15_R11, IE15_R12, IE15_R13, IE15_R14, IE15_R15,
14   IE15_R16, IE15_R17, IE15_R18, IE15_R19, IE15_R20, IE15_R21, IE15_R22, IE15_R23,
15   IE15_R24, IE15_R25, IE15_R26, IE15_R27, IE15_R28, IE15_R29, IE15_R30, IE15_R31,
16
17   IE15_GENPC = STATE_GENPC,
18   IE15_GENPCBASE = STATE_GENPCBASE
19};
20
21//**************************************************************************
22//  TYPE DEFINITIONS
23//**************************************************************************
24
25class ie15_device;
26
27class ie15_device : public cpu_device
28{
29public:
30   // construction/destruction
31   ie15_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
32
33protected:
34   // device-level overrides
35   virtual void device_start();
36   virtual void device_reset();
37
38   // device_execute_interface overrides
39   virtual UINT32 execute_min_cycles() const;
40   virtual UINT32 execute_max_cycles() const;
41   virtual void execute_run();
42
43   // device_memory_interface overrides
44   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
45
46   // device_state_interface overrides
47   virtual void state_import(const device_state_entry &entry);
48   virtual void state_export(const device_state_entry &entry);
49   virtual void state_string_export(const device_state_entry &entry, astring &string);
50
51   // device_disasm_interface overrides
52   virtual UINT32 disasm_min_opcode_bytes() const;
53   virtual UINT32 disasm_max_opcode_bytes() const;
54   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
55
56   virtual void execute_one(int opcode);
57
58   UINT8 rop();
59   UINT8 get_reg_lo(UINT8 reg);
60   UINT16 get_reg(UINT8 reg);
61   void set_reg(UINT8 reg, UINT16 val);
62   UINT8 arg();
63   void update_flags(UINT8 val);
64   UINT8 do_condition(UINT8 val);
65   UINT16 get_addr(UINT8 val);
66   void illegal(UINT8 opcode);
67
68   int m_icount;
69
70   // configuration
71   const address_space_config      m_program_config;
72   const address_space_config      m_io_config;
73
74   UINT8   m_A;
75   PAIR    m_PC;
76   UINT16   m_REGS[32]; // General registers (2 pages of 16)
77   UINT8   m_CF; // Carry flag
78   UINT8   m_ZF; // Zero flag
79   UINT8   m_RF; // Current register page
80   UINT8   m_flags; // temporary I/O only
81
82   address_space *m_program;
83   address_space *m_io;
84   direct_read_data *m_direct;
85};
86
87// device type definition
88extern const device_type IE15;
89
90#endif
Property changes on: trunk/src/emu/cpu/ie15/ie15.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/mess.lst
r22731r22732
21952195itt3030
21962196vax785
21972197ms0515
2198ie15
21982199alphasma
21992200altos5
22002201merlin
trunk/src/mess/mess.mak
r22731r22732
124124CPUS += LC8670
125125CPUS += ES5510
126126CPUS += SCUDSP
127CPUS += IE15
127128
128129#-------------------------------------------------
129130# specify available sound cores; some of these are
r22731r22732
21122113   $(MESS_DRIVERS)/horizon.o   \
21132114   $(MESS_DRIVERS)/hpz80unk.o  \
21142115   $(MESS_DRIVERS)/ht68k.o     \
2116   $(MESS_DRIVERS)/ie15.o     \
21152117   $(MESS_DRIVERS)/if800.o     \
21162118   $(MESS_DRIVERS)/indiana.o   \
21172119   $(MESS_DRIVERS)/itt3030.o   \
trunk/src/mess/drivers/ie15.c
r0r22732
1/***************************************************************************
2
3        15IE-00-013 Terminal
4
5            board images : http://asvcorp.ru/darch/hardware/pdp/fryazin-display/index.html
6
7        29/06/2012 Skeleton driver.
8
9   A serial (RS232 or current loop) green-screen terminal, mostly VT52 compatible
10   (no Hold Screen mode and no graphics character set, but has Cyrillic characters).
11   The top line is a status line.
12
13****************************************************************************/
14
15#include "emu.h"
16#include "cpu/ie15/ie15.h"
17#include "imagedev/bitbngr.h"
18#include "machine/keyboard.h"
19#include "sound/beep.h"
20
21#define SCREEN_PAGE   (80*48)
22
23#define   IE_1      0x80
24#define IE_KB_ACK   1
25
26#define IE15_TOTAL_HORZ   1000
27#define IE15_TOTAL_VERT   28*11
28
29#define IE15_DISP_HORZ   800
30#define IE15_DISP_VERT   25*11
31
32#define IE15_HORZ_START   100
33#define IE15_VERT_START   2*11
34
35#define VERBOSE_DBG 1       /* general debug messages */
36
37#define DBG_LOG(N,M,A) \
38   do { \
39      if(VERBOSE_DBG>=N) \
40      { \
41         if( M ) \
42            logerror("%11.6f at %s: %-24s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
43         logerror A; \
44      } \
45   } while (0)
46
47#if VERBOSE_DBG > 0
48#define LOOPBACK (m_io_keyboard->read() & 0x20)
49#else
50#define LOOPBACK (0)
51#endif
52
53#define BITBANGER_TAG   "bitbanger"
54
55class ie15_state : public driver_device
56{
57public:
58   ie15_state(const machine_config &mconfig, device_type type, const char *tag)
59      : driver_device(mconfig, type, tag)
60      , m_maincpu(*this, "maincpu")
61      , m_beeper(*this, "beeper")
62      , m_bitbanger(*this, BITBANGER_TAG)
63      , m_io_keyboard(*this, KEYBOARD_TAG)
64   { }
65
66   virtual void machine_reset();
67   virtual void video_start();
68   virtual void palette_init();
69   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
70   UINT32 screen_update_hle(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
71   TIMER_DEVICE_CALLBACK_MEMBER(scanline_callback);
72   DECLARE_WRITE8_MEMBER(kbd_put);
73   static const bitbanger_config ie15_bitbanger_config;
74   TIMER_CALLBACK_MEMBER(serial_tx_callback);
75   emu_timer  *m_serial_tx_timer;
76
77   DECLARE_WRITE8_MEMBER( mem_w );
78   DECLARE_READ8_MEMBER( mem_r );
79   DECLARE_WRITE8_MEMBER( mem_addr_lo_w );
80   DECLARE_WRITE8_MEMBER( mem_addr_hi_w );
81   DECLARE_WRITE8_MEMBER( mem_addr_inc_w );
82   DECLARE_WRITE8_MEMBER( mem_addr_dec_w );
83   DECLARE_READ8_MEMBER( flag_r );
84   DECLARE_WRITE8_MEMBER( flag_w );
85   DECLARE_WRITE8_MEMBER( beep_w );
86   DECLARE_READ8_MEMBER( kb_r );
87   DECLARE_READ8_MEMBER( kb_ready_r );
88   DECLARE_READ8_MEMBER( kb_s_red_r );
89   DECLARE_READ8_MEMBER( kb_s_sdv_r );
90   DECLARE_READ8_MEMBER( kb_s_dk_r );
91   DECLARE_READ8_MEMBER( kb_s_dupl_r );
92   DECLARE_READ8_MEMBER( kb_s_lin_r );
93   DECLARE_WRITE8_MEMBER( kb_ready_w );
94   DECLARE_READ8_MEMBER( serial_tx_ready_r );
95   DECLARE_WRITE8_MEMBER( serial_w );
96   DECLARE_READ8_MEMBER( serial_rx_ready_r );
97   DECLARE_READ8_MEMBER( serial_r );
98#if 0
99   DECLARE_WRITE8_MEMBER( serial_speed_w );
100#endif
101
102private:
103   TIMER_CALLBACK_MEMBER(ie15_beepoff);
104   UINT32 draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline, UINT8 y);
105   bitmap_ind16 m_tmpbmp;
106
107   const UINT8 *m_p_chargen;
108   UINT8 *m_p_videoram;
109   UINT8 m_beep;
110   UINT8 m_cursor;
111   UINT8 m_kb_data;
112   UINT8 m_kb_flag;
113   UINT8 m_kb_flag0;
114   UINT8 m_latch;
115   UINT8 m_ruslat;
116   UINT8 m_serial_rx_bits;
117   UINT8 m_serial_rx_buffer;
118   UINT8 m_serial_rx_data;
119   UINT8 m_serial_tx_bits;
120   UINT8 m_serial_tx_data;
121   UINT8 m_statusline;
122   UINT8 m_video;
123   UINT32 m_videoptr;
124   UINT32 m_videoptr_2;
125
126   static void bitbanger_callback(running_machine &machine, UINT8 bit);
127   DECLARE_WRITE_LINE_MEMBER( serial_rx_callback );
128
129protected:
130   required_device<cpu_device> m_maincpu;
131   required_device<beep_device> m_beeper;
132   required_device<bitbanger_device> m_bitbanger;
133   required_ioport m_io_keyboard;
134};
135
136READ8_MEMBER( ie15_state::mem_r ) {
137   UINT8 ret;
138
139   ret = m_p_videoram[m_videoptr];
140   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 && m_videoptr >= SCREEN_PAGE)
141   {
142      DBG_LOG(2,"memory",("R @ %03x == %02x\n", m_videoptr, ret));
143   }
144   m_videoptr++;
145   m_videoptr &= 0xfff;
146   m_latch = 0;
147   return ret;
148}
149
150WRITE8_MEMBER( ie15_state::mem_w ) {
151   if ((m_latch ^= 1) == 0) {
152      if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 && m_videoptr >= SCREEN_PAGE)
153      {
154         DBG_LOG(2,"memory",("W @ %03x <- %02x\n", m_videoptr, data));
155      }
156      m_p_videoram[m_videoptr++] = data;
157      m_videoptr &= 0xfff;
158   }
159}
160
161WRITE8_MEMBER( ie15_state::mem_addr_inc_w ) {
162   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
163   {
164      DBG_LOG(2,"memory",("++ %03x\n", m_videoptr));
165   }
166   m_videoptr++;
167   m_videoptr &= 0xfff;
168   if (m_video)
169      m_videoptr_2 = m_videoptr;
170}
171
172WRITE8_MEMBER( ie15_state::mem_addr_dec_w ) {
173   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
174   {
175      DBG_LOG(2,"memory",("-- %03x\n", m_videoptr));
176   }
177   m_videoptr--;
178   m_videoptr &= 0xfff;
179   if (m_video)
180      m_videoptr_2 = m_videoptr;
181}
182
183WRITE8_MEMBER( ie15_state::mem_addr_lo_w ) {
184   UINT16 tmp = m_videoptr;
185
186   tmp &= 0xff0;
187   tmp |= ((data >> 4) & 0xf);
188   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
189   {
190      DBG_LOG(2,"memory",("lo %03x <- %02x = %03x\n", m_videoptr, data, tmp));
191   }
192   m_videoptr = tmp;
193   if (m_video)
194      m_videoptr_2 = tmp;
195}
196
197WRITE8_MEMBER( ie15_state::mem_addr_hi_w ) {
198   UINT16 tmp = m_videoptr;
199
200   tmp &= 0xf;
201   tmp |= (data << 4);
202   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
203   {
204      DBG_LOG(2,"memory",("hi %03x <- %02x = %03x\n", m_videoptr, data, tmp));
205   }
206   m_videoptr = tmp;
207   if (m_video)
208      m_videoptr_2 = tmp;
209}
210
211TIMER_CALLBACK_MEMBER(ie15_state::ie15_beepoff)
212{
213   machine().device<beep_device>("beeper")->set_state(0);
214}
215
216WRITE8_MEMBER( ie15_state::beep_w ) {
217   UINT16 length = (m_beep&128)?150:400;
218
219   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
220   {
221      DBG_LOG(1,"beep",("(%s)\n", m_beep?"short":"long"));
222   }
223   machine().scheduler().timer_set(attotime::from_msec(length), timer_expired_delegate(FUNC(ie15_state::ie15_beepoff),this));
224   machine().device<beep_device>("beeper")->set_state(1);
225}
226
227// active high
228READ8_MEMBER( ie15_state::kb_r ) {
229   DBG_LOG(2,"keyboard",("R %02X '%c'\n", m_kb_data, m_kb_data < 0x20?' ':m_kb_data));
230   return m_kb_data;
231}
232
233// active low
234READ8_MEMBER( ie15_state::kb_ready_r ) {
235   m_kb_flag &= IE_1;
236   if (m_kb_flag != m_kb_flag0) {
237      DBG_LOG(2,"keyboard",("? %c\n", m_kb_flag?'n':'y'));
238      m_kb_flag0 = m_kb_flag;
239   }
240   return m_kb_flag;
241}
242
243// active low
244WRITE8_MEMBER( ie15_state::kb_ready_w ) {
245   DBG_LOG(2,"keyboard",("clear ready\n"));
246   m_kb_flag = IE_1 | IE_KB_ACK;
247}
248
249
250// active high; active = interpret controls, inactive = display controls
251READ8_MEMBER( ie15_state::kb_s_red_r ) {
252   return m_io_keyboard->read() & 0x01 ? IE_1 : 0;
253}
254
255// active high; active = setup mode
256READ8_MEMBER( ie15_state::kb_s_sdv_r ) {
257   return m_io_keyboard->read() & 0x02 ? IE_1 : 0;
258}
259
260// active high, XXX stub
261READ8_MEMBER( ie15_state::kb_s_dk_r ) {
262   return 0;
263}
264
265// active low; active = full duplex, inactive = half duplex
266READ8_MEMBER( ie15_state::kb_s_dupl_r ) {
267   return m_io_keyboard->read() & 0x08 ? IE_1 : 0;
268}
269
270// active high; active = on-line, inactive = local editing
271READ8_MEMBER( ie15_state::kb_s_lin_r ) {
272   return m_io_keyboard->read() & 0x10 ? IE_1 : 0;
273}
274
275// active low
276READ8_MEMBER( ie15_state::serial_rx_ready_r ) {
277   if (LOOPBACK)
278      return m_serial_tx_data ? 0 : IE_1;
279   else
280      return m_serial_rx_data ? 0 : IE_1;
281}
282
283// not called unless data is ready
284READ8_MEMBER( ie15_state::serial_r ) {
285   UINT8 tmp;
286
287   if (LOOPBACK) {
288      tmp = m_serial_tx_data;
289      m_serial_tx_data = 0;
290   } else {
291      tmp = m_serial_rx_data;
292      m_serial_rx_data = 0;
293   }
294   DBG_LOG(2,"serial",("R %02X '%c'\n", tmp, tmp < 0x20?' ':tmp));
295   return tmp;
296}
297
298/*
299   m_serial_rx_buffer   incoming bits.
300   m_serial_rx_bits   number of bits in _buffer.
301   m_serial_rx_data   complete byte, ready to be read by host, or 0 if no data.
302*/
303
304WRITE_LINE_MEMBER( ie15_state::serial_rx_callback )
305{
306   UINT8 tmp = m_serial_rx_bits;
307
308   switch (m_serial_rx_bits) {
309      // wait for start bit (0)
310      case 10:
311         m_serial_rx_bits = 0;
312      case 0:
313         if (!state) {
314            m_serial_rx_bits++;
315            m_serial_rx_buffer = 0;
316         }
317         break;
318      // stuff incoming bits into byte buffer
319      case 1: case 2: case 3: case 4:
320      case 5: case 6: case 7: case 8:
321         m_serial_rx_buffer |= state << (m_serial_rx_bits-1);
322         m_serial_rx_bits++;
323         break;
324      // expecting stop bit (1)
325      case 9:
326         if (state && !m_serial_rx_data) {
327            m_serial_rx_data = m_serial_rx_buffer;
328            m_serial_rx_bits++;
329         } else
330            m_serial_rx_bits = 0;
331         break;
332      default:
333         // overflow
334         break;
335   }
336   DBG_LOG(2,"serial",("r %d bits %02d->%02d buffer %02X data %02X\n",
337      state, tmp, m_serial_rx_bits, m_serial_rx_buffer, m_serial_rx_data));
338}
339
340const bitbanger_config ie15_state::ie15_bitbanger_config =
341{
342   DEVCB_DRIVER_LINE_MEMBER(ie15_state, serial_rx_callback),   /* callback */
343   BITBANGER_PRINTER,                                          /* default mode */
344   BITBANGER_9600,                                             /* default output baud */
345   BITBANGER_0PERCENT                                          /* default fine tune adjustment */
346};
347
348// active high
349READ8_MEMBER( ie15_state::serial_tx_ready_r ) {
350   return m_serial_tx_data ? 0 : IE_1;
351}
352
353WRITE8_MEMBER( ie15_state::serial_w ) {
354   DBG_LOG(2,"serial",("W %02X '%c'\n", data, data < 0x20?' ':data));
355   if (LOOPBACK) {
356      if (!m_serial_tx_data)
357         m_serial_tx_data = data;
358   } else {
359      /* 1 start bit */
360      m_bitbanger->output(0);
361      /* 8 data bits, 1 stop bit, no parity */
362      m_serial_tx_bits = 8;
363      m_serial_tx_data = data;
364      m_serial_tx_timer->adjust(attotime::from_hz(9600));
365   }
366}
367
368TIMER_CALLBACK_MEMBER(ie15_state::serial_tx_callback) {
369   if (!m_serial_tx_bits) {
370      m_bitbanger->output(1);
371      m_serial_tx_data = 0;
372   } else {
373      m_bitbanger->output(BIT(m_serial_tx_data, 8-(m_serial_tx_bits--)));
374      m_serial_tx_timer->adjust(attotime::from_hz(9600));
375   }
376}
377
378READ8_MEMBER( ie15_state::flag_r ) {
379   UINT8 ret = 0;
380
381   switch (offset)
382   {
383      case 0:   // hsync pulse (not hblank)
384         ret = machine().primary_screen->hpos() < IE15_HORZ_START;
385         break;
386      case 1:   // marker scanline
387         ret = (machine().primary_screen->vpos() % 11) > 7;
388         break;
389      case 2:   // vblank
390         ret = !machine().primary_screen->vblank();
391         break;
392      case 4:
393         ret = m_ruslat;
394         break;
395      default:
396         break;
397   }
398   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 && ret)
399   {
400      DBG_LOG(2,"flag",("read %d: %d\n", offset, ret));
401   }
402   return ret;
403}
404
405WRITE8_MEMBER( ie15_state::flag_w ) {
406   switch (offset)
407   {
408      case 0:
409         m_video = data;
410         break;
411      case 1:
412         m_cursor = data;
413         break;
414      case 2:
415         m_beep = data;
416         break;
417      case 3:
418         m_statusline = data;
419         break;
420      case 4:
421         m_ruslat = data;
422         break;
423      default:
424         break;
425   }
426   if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
427   {
428      DBG_LOG(2,"flag",("%sset %d\n", data?"":"re", offset));
429   }
430}
431
432static ADDRESS_MAP_START(ie15_mem, AS_PROGRAM, 8, ie15_state)
433   ADDRESS_MAP_UNMAP_HIGH
434   AM_RANGE( 0x0000, 0x0fff ) AM_ROM
435ADDRESS_MAP_END
436
437static ADDRESS_MAP_START(ie15_io, AS_IO, 8, ie15_state)
438   ADDRESS_MAP_UNMAP_HIGH
439   AM_RANGE(000, 000) AM_READ(mem_r) AM_WRITE(mem_w)   // 00h W: memory request, R: memory data [6.1.2.2]
440   AM_RANGE(001, 001) AM_READ(serial_rx_ready_r) AM_WRITENOP   // 01h W: memory latch [6.1.2.2]
441   AM_RANGE(002, 002) AM_WRITE(mem_addr_hi_w)      // 02h W: memory address high [6.1.2.2]
442   AM_RANGE(003, 003) AM_WRITE(mem_addr_lo_w)      // 03h W: memory address low [6.1.2.2]
443   AM_RANGE(004, 004) AM_WRITE(mem_addr_inc_w)      // 04h W: memory address counter + [6.1.2.2]
444   AM_RANGE(005, 005) AM_WRITE(mem_addr_dec_w)      // 05h W: memory address counter - [6.1.2.2]
445   AM_RANGE(006, 006) AM_READ(serial_r) AM_WRITE(serial_w)      // 06h W: serial port data [6.1.5.4]
446// port 7 is handled in cpu core
447   AM_RANGE(010, 010) AM_READ(serial_tx_ready_r) AM_WRITE(beep_w)   // 08h W: speaker control [6.1.5.4]
448   AM_RANGE(011, 011) AM_READ(kb_r)         // 09h R: keyboard data [6.1.5.2]
449   AM_RANGE(012, 012) AM_READ(kb_s_red_r)         // 0Ah I: keyboard mode "RED" [6.1.5.2]
450   AM_RANGE(013, 013) AM_READ(kb_ready_r)         // 0Bh R: keyboard data ready [6.1.5.2]
451   AM_RANGE(014, 014) AM_READ(kb_s_sdv_r) AM_WRITENOP   // 0Ch W: serial port speed [6.1.3.1], R: keyboard mode "SDV" [6.1.5.2]
452   AM_RANGE(015, 015) AM_READ(kb_s_dk_r) AM_WRITE(kb_ready_w)   // 0Dh I: keyboard mode "DK" [6.1.5.2]
453   AM_RANGE(016, 016) AM_READ(kb_s_dupl_r)         // 0Eh I: keyboard mode "DUPL" [6.1.5.2]
454   AM_RANGE(017, 017) AM_READ(kb_s_lin_r)         // 0Fh I: keyboard mode "LIN" [6.1.5.2]
455// simulation of flag registers
456   AM_RANGE(020, 027) AM_READ(flag_r) AM_WRITE(flag_w)
457ADDRESS_MAP_END
458
459/* Input ports */
460static INPUT_PORTS_START( ie15 )
461   PORT_START("keyboard")
462   PORT_DIPNAME(0x01, 0x00, "RED mode")
463   PORT_DIPSETTING(0x00, "Off" )
464   PORT_DIPSETTING(0x01, "On" )
465   PORT_DIPNAME(0x02, 0x00, "SDV mode (Setup)")
466   PORT_DIPSETTING(0x00, "Off" )
467   PORT_DIPSETTING(0x02, "On" )
468   PORT_DIPNAME(0x08, 0x00, "DUPL mode")
469   PORT_DIPSETTING(0x00, "Off" )
470   PORT_DIPSETTING(0x08, "On" )
471   PORT_DIPNAME(0x10, 0x00, "LIN mode")
472   PORT_DIPSETTING(0x00, "Off" )
473   PORT_DIPSETTING(0x10, "On" )
474   PORT_DIPNAME(0x20, 0x00, "digital loopback")
475   PORT_DIPSETTING(0x00, "Off" )
476   PORT_DIPSETTING(0x20, "On" )
477INPUT_PORTS_END
478
479WRITE8_MEMBER( ie15_state::kbd_put )
480{
481   DBG_LOG(2,"keyboard",("W %02X<-%02X '%c' %c\n", m_kb_data, data, data < 0x20?' ':data, m_kb_flag?'n':'y'));
482   if (m_kb_flag == IE_1) {
483      m_kb_data = data;
484      m_kb_flag = 0;
485   }
486}
487
488static ASCII_KEYBOARD_INTERFACE( keyboard_intf )
489{
490   DEVCB_DRIVER_MEMBER(ie15_state, kbd_put)
491};
492
493
494void ie15_state::machine_reset()
495{
496   m_ruslat = m_beep = m_statusline = m_cursor = m_video = m_kb_data = m_kb_flag0 = 0;
497   m_serial_tx_data = m_serial_tx_bits = m_serial_rx_buffer = m_serial_rx_data = m_serial_rx_bits = 0;
498   m_kb_flag = IE_1;
499
500   machine().device<beep_device>("beeper")->set_frequency(2400);
501   machine().device<beep_device>("beeper")->set_state(0);
502
503   m_serial_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ie15_state::serial_tx_callback),this));
504}
505
506void ie15_state::video_start()
507{
508   m_p_chargen = machine().root_device().memregion("chargen")->base();
509   m_p_videoram = memregion("video")->base();
510   m_videoptr = m_videoptr_2 = m_latch = 0;
511
512   m_tmpbmp.allocate(IE15_DISP_HORZ, IE15_DISP_VERT);
513}
514
515UINT32 ie15_state::draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline, UINT8 y)
516{
517   UINT8 gfx,fg,bg,ra,blink,red;
518   UINT16 x,chr;
519
520   bg = 0; fg = 1; ra = scanline % 8;
521   blink = (machine().primary_screen->frame_number() % 10) >= 5;
522   red = m_io_keyboard->read() & 0x01;
523
524   DBG_LOG(2,"draw_scanline",
525      ("addr %03x row %d-%d video %d\n", offset, y, scanline, m_video));
526
527   for (x = offset; x < offset + 80; x++)
528   {
529      if (m_video) {
530         chr = m_p_videoram[x] << 3;
531         gfx = m_p_chargen[chr | ra];
532
533         /*
534            Cursor is a character with only 3 scan lines, and is
535            not shown if flag 1 is not active on this scan line.
536            It always blinks if shown.
537
538            Control characters blink if RED mode is on and they
539            are not on status line; else they are blanked out. 
540         */
541
542         if (scanline > 7 && (!m_cursor || blink))
543            gfx = 0;
544         if (chr < (0x20<<3)) {
545            if (!y || !red || blink)
546               gfx = 0;
547            else
548               gfx = m_p_chargen[chr | 0x200 | ra];
549         }
550         /* Display a scanline of a character */
551         *p++ = BIT(gfx, 7) ? fg : bg;
552         *p++ = BIT(gfx, 6) ? fg : bg;
553         *p++ = BIT(gfx, 5) ? fg : bg;
554         *p++ = BIT(gfx, 4) ? fg : bg;
555         *p++ = BIT(gfx, 3) ? fg : bg;
556         *p++ = BIT(gfx, 2) ? fg : bg;
557         *p++ = BIT(gfx, 1) ? fg : bg;
558         *p++ = bg;
559         *p++ = bg;
560         *p++ = bg;
561      } else {
562         *p++ = bg;
563         *p++ = bg;
564         *p++ = bg;
565         *p++ = bg;
566         *p++ = bg;
567         *p++ = bg;
568         *p++ = bg;
569         *p++ = bg;
570         *p++ = bg;
571         *p++ = bg;
572      }
573   }
574   return 0;
575}
576
577TIMER_DEVICE_CALLBACK_MEMBER(ie15_state::scanline_callback)
578{
579   UINT16 y = machine().primary_screen->vpos();
580//   DBG_LOG(2,"scanline",
581//      ("addr %03x frame %lld x %04d y %03d\n", m_videoptr_2, machine().primary_screen->frame_number(), machine().primary_screen->hpos(), y));
582   if (y>=IE15_VERT_START) {
583      y -= IE15_VERT_START;
584      if (y < IE15_DISP_VERT) {
585         draw_scanline(&m_tmpbmp.pix16(y), m_videoptr_2, y%11, y/11);
586      }
587   }
588}
589
590UINT32 ie15_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
591{
592   copybitmap( bitmap, m_tmpbmp, 0, 0, IE15_HORZ_START, IE15_VERT_START, cliprect );
593   return 0;
594}
595
596
597/* F4 Character Displayer */
598static const gfx_layout ie15_charlayout =
599{
600   7, 8,               /* 7x8 pixels in 10x11 cell */
601   256,               /* 256 characters */
602   1,               /* 1 bits per pixel */
603   { 0 },               /* no bitplanes */
604   /* x offsets */
605   { 0, 1, 2, 3, 4, 5, 6 },
606   /* y offsets */
607   { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
608   8*8               /* every char takes 8 bytes */
609};
610
611static GFXDECODE_START( ie15 )
612   GFXDECODE_ENTRY( "chargen", 0x0000, ie15_charlayout, 0, 1 )
613GFXDECODE_END
614
615void ie15_state::palette_init()
616{
617   palette_set_color(machine(), 0, RGB_BLACK); // black
618   palette_set_color_rgb(machine(), 1, 0x00, 0xc0, 0x00); // green
619}
620
621static MACHINE_CONFIG_START( ie15, ie15_state )
622   /* Basic machine hardware */
623   MCFG_CPU_ADD("maincpu", IE15, XTAL_30_8MHz / 10)
624   MCFG_CPU_PROGRAM_MAP(ie15_mem)
625   MCFG_CPU_IO_MAP(ie15_io)
626   MCFG_TIMER_DRIVER_ADD_PERIODIC("scantimer", ie15_state, scanline_callback, attotime::from_hz(50*28*11))
627   MCFG_TIMER_START_DELAY(attotime::from_hz(XTAL_30_8MHz/(2*IE15_HORZ_START)))
628
629   /* Video hardware */
630   MCFG_SCREEN_ADD("screen", RASTER)
631   MCFG_SCREEN_UPDATE_DRIVER(ie15_state, screen_update)
632   MCFG_SCREEN_RAW_PARAMS(XTAL_30_8MHz/2,IE15_TOTAL_HORZ,IE15_HORZ_START,
633      IE15_HORZ_START+IE15_DISP_HORZ,IE15_TOTAL_VERT,IE15_VERT_START,
634      IE15_VERT_START+IE15_DISP_VERT);
635   MCFG_GFXDECODE(ie15)
636   MCFG_PALETTE_LENGTH(2)
637
638   /* Devices */
639   MCFG_ASCII_KEYBOARD_ADD(KEYBOARD_TAG, keyboard_intf)
640   MCFG_BITBANGER_ADD(BITBANGER_TAG, ie15_state::ie15_bitbanger_config)
641
642   MCFG_SPEAKER_STANDARD_MONO("mono")
643   MCFG_SOUND_ADD("beeper", BEEP, 0)
644   MCFG_SOUND_ROUTE(ALL_OUTPUTS,"mono",0.15)
645MACHINE_CONFIG_END
646
647
648/* ROM definition */
649ROM_START( ie15 )
650   ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASE00 )
651   ROM_DEFAULT_BIOS("5chip")
652   ROM_SYSTEM_BIOS(0, "5chip", "5-chip firmware (newer)")
653   ROMX_LOAD( "dump1.bin", 0x0000, 0x1000, CRC(14b82284) SHA1(5ac4159fbb1c3b81445605e26cd97a713ae12b5f),ROM_BIOS(1) )
654   ROM_SYSTEM_BIOS(1, "6chip", "6-chip firmware (older)")
655   ROMX_LOAD( "dump5.bin", 0x0000, 0x1000, CRC(01f2e065) SHA1(2b72dc0594e38a528400cd25aed0c47e0c432895),ROM_BIOS(2) )
656
657   ROM_REGION( 0x1000, "video", ROMREGION_ERASE00 )
658
659   ROM_REGION( 0x0800, "chargen", ROMREGION_ERASE00 )
660   ROM_LOAD( "chargen-15ie.bin", 0x0000, 0x0800, CRC(ed16bf6b) SHA1(6af9fb75f5375943d5c0ce9ed408e0fb4621b17e) )
661ROM_END
662
663/* Driver */
664
665/*    YEAR  NAME      PARENT  COMPAT   MACHINE    INPUT                       INIT   COMPANY     FULLNAME       FLAGS */
666COMP( 1980, ie15,     0,      0,       ie15,      ie15,    driver_device,     0,     "USSR",     "15IE-00-013", 0)
Property changes on: trunk/src/mess/drivers/ie15.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Previous 199869 Revisions Next


© 1997-2024 The MAME Team