Previous 15994 Revisions Next

r13892 Friday 6th January, 2012 at 10:08:26 UTC by Miodrag Milanović
New driver: RM-380Z [Gabriele D'Antona]

out of whatsnew: This is driver in original form, need some rewrite still to make things look proper
[src/mess]mess.lst mess.mak
[src/mess/drivers]rm380z.c*

src/mess/mess.lst
r13891r13892
20792079konin
20802080m79152pc
20812081dmv
2082rm380z
src/mess/mess.mak
r13891r13892
17981798   $(MESS_DRIVERS)/ptcsol.o   \
17991799   $(MESS_DRIVERS)/pv9234.o   \
18001800   $(MESS_DRIVERS)/qtsbc.o      \
1801   $(MESS_DRIVERS)/rm380z.o   \
18011802   $(MESS_DRIVERS)/rvoice.o   \
18021803   $(MESS_DRIVERS)/sacstate.o   \
18031804   $(MESS_DRIVERS)/sage2.o      \
src/mess/drivers/rm380z.c
r0r13892
1
2/*
3
4Research Machines RM-380Z
5microcomputer produced by Research Machines Limited
61978-1985
7MESS driver by judge, friol
8
9===
10
11Memory map:
12
130x0000-0x0fff - COS ROM (in page 0)/RAM (in page 1)
140x1c00-0x1dff - additional ROM (?)
150x4000-0xbc00 - RAM page0
160xE000-0xEFFF - COS ROM mirror
170xF000-0xF5FF - video ram
180xf600-0xf9ff - ROM (?)
190xfa00-0xffff - RAM
20
210xfbfc - port0
220xfbfd - "scroll" register in COS 4.0 (?)
23
24According to the manuals, VDU-1 chargen is Texas 74LS262.
25
26===
27
28COS 4.0 disassembly
29
30- routine at 0xe438 is called at startup in COS 4.0 and it sets the RST vectors in RAM
31- routine at 0xe487 finds "top" of system RAM and stores it in 0x0006 and 0x000E
32- 0xeca0 - outputs a string (null terminated) to screen (?)
33- 0xff18 - does char output to screen (char in A?)
34
35*/
36
37#define ADDRESS_MAP_MODERN
38
39
40#include "emu.h"
41#include "cpu/z80/z80.h"
42#include "imagedev/flopdrv.h"
43#include "machine/wd17xx.h"
44
45
46#define PORTS_ENABLED_HIGH   ( m_port0 & 0x80 )
47#define PORTS_ENABLED_LOW   ( ( m_port0 & 0x80 ) == 0x00 )
48
49//
50//
51//
52
53class rm380z_state : public driver_device
54{
55private:
56   
57   UINT8 decode_videoram_char(UINT8 ch1,UINT8 ch2);
58   
59protected:
60   virtual void machine_reset();
61
62public:
63
64   UINT8 m_port0;
65   UINT8 m_port0_kbd;
66   UINT8 m_port1;
67   UINT8 m_fbfd;
68   UINT8 *m_cos_rom;
69
70   int m_ksampler;
71
72   UINT8   m_vram[0x600];
73   UINT8 m_mainVideoram[0x600];
74
75   UINT8   m_vramchars[0x600];
76   UINT8   m_vramattribs[0x600];
77
78   UINT8 m_mainram[0x10000];
79   
80   int m_rasterlineCtr;
81   emu_timer* m_vblankTimer;
82   int m_old_fbfd;
83
84   required_device<cpu_device> m_maincpu;
85   optional_device<device_t> m_fdc;
86
87   rm380z_state(const machine_config &mconfig, device_type type, const char *tag): driver_device(mconfig, type, tag),
88      m_maincpu(*this, "maincpu"),
89      m_fdc(*this, "wd1771")
90   {
91   }
92
93   void port_1bfc_write(int offset,UINT8 data);
94   UINT8 port_1bfc_read(int offset);
95
96   DECLARE_READ8_MEMBER( port_fbfc_read );
97   DECLARE_WRITE8_MEMBER( port_fbfc_write );
98
99   void port_write(int offset,UINT8 data);
100   UINT8 port_read(int offset);
101
102   DECLARE_READ8_MEMBER( main_read );
103   DECLARE_WRITE8_MEMBER( main_write );
104
105   DECLARE_READ8_MEMBER( videoram_read );
106   DECLARE_WRITE8_MEMBER( videoram_write );
107
108   DECLARE_READ8_MEMBER(rm380z_io_r);
109   DECLARE_WRITE8_MEMBER(rm380z_io_w);
110
111   int keyboard_decode();
112};
113
114//
115
116void rm380z_state::port_1bfc_write(int offset,UINT8 data)
117{
118   port_write(offset, data );
119}
120
121UINT8 rm380z_state::port_1bfc_read(int offset)
122{
123   return port_read(offset );
124}
125
126WRITE8_MEMBER( rm380z_state::port_fbfc_write )
127{
128   port_write(offset, data );
129}
130
131READ8_MEMBER( rm380z_state::port_fbfc_read )
132{
133   return port_read(offset );
134}
135
136void rm380z_state::port_write(int offset,UINT8 data)
137{
138   switch ( offset )
139   {
140   case 0x00:      // PORT0
141      //printf("write of [%x] to FBFC\n",data);
142      m_port0 = data;
143      if (data&0x01)
144      {
145         //printf("WARNING: bit0 of port0 reset\n");
146         m_port0_kbd=0;
147      }
148      break;
149
150   case 0x01:      // screen line counter (?)
151      //printf("write of [%x] to FBFD\n",data&0x1f);
152      m_fbfd=data&0x1f;
153      break;
154
155   case 0x02:      // PORT1
156      //printf("write of [%x] to FBFE\n",data);
157      break;
158
159   case 0x03:      // user I/O port
160      //printf("write of [%x] to FBFF\n",data);
161      //logerror("%s: Write %02X to user I/O port\n", machine().describe_context(), data );
162      break;
163   }
164}
165
166UINT8 rm380z_state::port_read(int offset)
167{
168   UINT8 data = 0xFF;
169
170   switch ( offset )
171   {
172   case 0x00:      // PORT0
173      //m_port0_kbd=getKeyboard();
174      data = m_port0_kbd;
175      //if (m_port0_kbd!=0) m_port0_kbd=0;
176      //m_port0_kbd=0;
177      //printf("read of port0 (kbd) at [%f] from PC [%x]\n",machine().time().as_double(),cpu_get_pc(machine().device("maincpu")));
178      break;
179
180   case 0x01:      // "counter" (?)
181      printf("%s: Read from counter FBFD\n", machine().describe_context());
182      data = 0x00;
183      break;
184
185   case 0x02:      // PORT1
186      data = m_port1;
187      break;
188
189   case 0x03:      // user port
190      printf("%s: Read from user port\n", machine().describe_context());
191      break;
192   }
193
194   return data;
195}
196
197#define LINE_SUBDIVISION 40
198#define TIMER_SPEED 50*100*LINE_SUBDIVISION
199
200//
201// this simulates line+frame blanking
202// according to the System manual, "frame blanking bit (bit 6) of port1 becomes high
203// for about 4.5 milliseconds every 20 milliseconds"
204//
205
206static TIMER_CALLBACK(static_vblank_timer)
207{
208   //printf("timer callback called at [%f]\n",machine.time().as_double());
209
210   rm380z_state *state = machine.driver_data<rm380z_state>();
211   
212   state->m_rasterlineCtr++;
213   state->m_rasterlineCtr%=(100*LINE_SUBDIVISION);
214   
215   if (state->m_rasterlineCtr>=((100-22)*LINE_SUBDIVISION))
216   {
217      // frame blanking
218      state->m_port1=0x41;
219   }
220   else
221   {
222      state->m_port1=0x00;
223   }
224
225   if ((state->m_rasterlineCtr%LINE_SUBDIVISION)==0) state->m_port1|=0x80; // line blanking
226
227   //     
228   // poll keyboard at fixed intervals, otherwise keys get pressed too fast
229   //
230   
231   state->m_ksampler++;
232   if (state->m_ksampler>(4*100*LINE_SUBDIVISION))
233   {
234      state->m_port0_kbd=state->keyboard_decode();
235      state->m_ksampler=0;
236   }
237}
238
239void rm380z_state::machine_reset()
240{
241   m_port0=0x00;
242   m_port0_kbd=0x00;
243   m_port1=0x00;
244   m_fbfd=0x00;
245   m_old_fbfd=0x00;
246   
247   m_rasterlineCtr=0;
248   m_ksampler=0;
249   
250   memset(m_vramattribs,0,0x600);
251   memset(m_vramchars,0,0x600);
252   
253   m_cos_rom=machine().region("maincpu")->base();
254
255   machine().scheduler().timer_pulse(attotime::from_hz(TIMER_SPEED), FUNC(static_vblank_timer));
256     
257   wd17xx_reset(machine().device("wd1771"));
258}
259
260//
261
262WRITE8_MEMBER( rm380z_state::main_write )
263{
264   rm380z_state *state = machine().driver_data<rm380z_state>();
265
266   if ( PORTS_ENABLED_LOW )
267   {
268      if ((offset>=0x1bfc)&&(offset<=0x1bff))
269      {
270         state->port_1bfc_write(offset-0x1bfc,data);
271         return;
272      }
273
274      if ((offset>=0x0000)&&(offset<0x1000))
275      {
276         // ROM
277         printf("ERROR: write on rom at [%x]\n",offset);
278         return;
279      }
280      else if ((offset>=0x1000)&&(offset<0x4000))
281      {
282         // ?
283         printf("WARNING: unhandled write page0 at [%x]\n",offset);
284         return;
285      }     
286      else if ((offset>=0x4000)&&(offset<0xBC00))
287      {
288         state->m_mainram[offset-0x4000]=data;
289         return;
290      }
291   }
292   else
293   {
294      if ((offset==0x000e)||(offset==0x000f))
295      {
296         printf("WARNING: writing [%x] at 0x000f at PC [%x]\n",data,cpu_get_pc(machine().device("maincpu")));
297      }
298
299      //if ((offset>=0x0000)&&(offset<0x7c00))
300      if ((offset>=0x0000)&&(offset<0xdf00))
301      {
302         // RAM
303         state->m_mainram[offset]=data;
304         return;
305      }
306   }
307   
308   //printf("ERROR: unhandled default write at [%x] of [%x]\n",offset,data);
309}
310
311READ8_MEMBER( rm380z_state::main_read )
312{
313   rm380z_state *state = machine().driver_data<rm380z_state>();
314
315   if ( PORTS_ENABLED_LOW )
316   {
317      if ((offset>=0x1bfc)&&(offset<=0x1bff))
318      {
319         return state->port_1bfc_read(offset-0x1bfc);
320      }
321
322      if ((offset>=0x0000)&&(offset<0x1000))
323      {
324         // ROM
325         return state->m_cos_rom[offset];
326      }
327      else if ((offset>=0x1c00)&&(offset<=0x1dff))
328      {
329         return m_cos_rom[offset-0x800];
330      }
331      else if ((offset>=0x1000)&&(offset<0x4000))
332      {
333         // ?
334         //printf("WARNING: unhandled read page0 at [%x]\n",offset);
335         return 0xff;
336      }     
337      else if ((offset>=0x4000)&&(offset<0xBC00))
338      {
339         return state->m_mainram[offset-0x4000];
340      }
341   }
342   else
343   {
344      //if ((offset>=0x0000)&&(offset<0x7c00))
345      if ((offset>=0x0000)&&(offset<0xdf00))
346      {
347         // ROM
348         return state->m_mainram[offset];
349      }
350   }
351
352   //printf("ERROR: unhandled default read at [%x]\n",offset);   
353   return 0xff;
354}
355
356//
357
358UINT8 rm380z_state::decode_videoram_char(UINT8 ch1,UINT8 ch2)
359{
360   if ((ch1>0x0f)&&(ch1<0x80))
361   {
362      return ch1;
363   }
364   else if ((ch2>0x0f)&&(ch2<0x80))
365   {
366      return ch2;
367   }
368   else if (ch1==0x80)
369   {
370      // "blank"?
371      return 0x80;
372   }
373   else if ((ch1==0)&&(ch2==8))
374   {
375      // cursor
376      return 0x7f;
377   }
378   else if ((ch1==0)&&(ch2==0))
379   {
380      return 0x20;
381   }
382   else if ((ch1==4)&&(ch2==4))
383   {
384      // reversed cursor?
385      return 0x20;
386   }
387   else if ((ch1==4)&&(ch2==8))
388   {
389      // normal cursor
390      return 0x7f;
391   }
392   else
393   {
394      //printf("unhandled character combination [%x][%x]\n",ch1,ch2);
395   }
396   
397   return 0;
398}
399
400WRITE8_MEMBER( rm380z_state::videoram_write )
401{
402   rm380z_state *state = machine().driver_data<rm380z_state>();
403
404   //printf("vramw [%x][%x] port0 [%x] fbfd [%x]\n",offset,data,state->m_port0,m_fbfd);
405   
406   if (m_old_fbfd>m_fbfd)
407   {
408      printf("WARN: fbfd wrapped\n");
409   }
410   m_old_fbfd=m_fbfd;
411   
412   int lineAdder=(m_fbfd&0x1f)*0x40;
413   int realA=offset+lineAdder;
414
415   // we suppose videoram is being written as character/attribute couple
416   // fbfc 6th bit set=attribute, unset=char
417
418   if (!(state->m_port0&0x40))
419   {
420      m_vramchars[realA%0x600]=data;
421   }
422   else
423   {
424      m_vramattribs[realA%0x600]=data;
425   }
426
427   UINT8 curch=decode_videoram_char(m_vramchars[realA],m_vramattribs[realA]);
428   state->m_vram[realA%0x600]=curch;
429
430   state->m_mainVideoram[offset]=data;
431}
432
433READ8_MEMBER( rm380z_state::videoram_read )
434{
435   rm380z_state *state = machine().driver_data<rm380z_state>();
436   //printf("read from videoram at [%x]\n",offset);   
437   //return state->m_vram[offset];
438   return state->m_mainVideoram[offset];
439}
440
441//
442// ports c0-cf are related to the floppy disc controller
443// c0-c3: wd1771
444// c4-c8: disk drive port0
445// code at f7df writes 2f to c0
446// code at e526 reads from c1
447//
448// the manual says: "the B command reads a sector from drive 0, track 0, sector 1 into memory
449// at 0x0080 to 0x00FF, then jumps to it if there is no error.
450//
451
452
453WRITE8_MEMBER( rm380z_state::rm380z_io_w )
454{
455   UINT8 portnum=offset&0xff;
456   device_t *fdc = machine().device("wd1771");
457   
458   //printf("port write of [%x] at [%x] from PC [%x]\n",data,portnum,cpu_get_pc(machine().device("maincpu")));
459   
460   if (portnum==0xc0)
461   {
462      wd17xx_command_w(fdc, 0, data);
463      //printf("wrote command [%x] to floppy disk\n",data);
464   }
465   else if (portnum==0xc1)
466   {
467      wd17xx_track_w(fdc, 0, data);
468      //printf("wrote track data [%x] to floppy disk\n",data);
469   }
470   else if (portnum==0xc2)
471   {
472      wd17xx_sector_w(fdc, 0, data);
473      //printf("wrote sector data [%x] to floppy disk\n",data);
474   }
475   else if (portnum==0xc3)
476   {
477      wd17xx_data_w(fdc, 0, data);
478      //printf("wrote data [%x] to floppy disk\n",data);
479   }
480   else if (portnum==0xc4)
481   {
482      printf("disk drive port0 write [%x]\n",data);
483     
484      // drive port0
485      if (data&0x01)
486      {
487         // drive select bit 0
488         wd17xx_set_drive(fdc,0);
489      }
490     
491      if (data&0x08)
492      {
493         // motor on
494      }
495     
496      // "MSEL (dir/side select bit)
497      if (data&0x20)
498      {
499         wd17xx_set_side(fdc,1);
500      }
501      else
502      {
503         wd17xx_set_side(fdc,0);
504      }
505     
506      // set drive en- (?)
507      if (data&0x40)
508      {
509      }
510   }
511}
512
513READ8_MEMBER( rm380z_state::rm380z_io_r )
514{
515   UINT8 retval=0;
516   UINT8 portnum=offset&0xff;
517   device_t *fdc = machine().device("wd1771");
518
519   //printf("port read at [%x] from PC [%x]\n",portnum,cpu_get_pc(machine().device("maincpu")));
520
521   if (portnum==0xc0)
522   {
523      retval=wd17xx_status_r(fdc,0);
524      //printf("disk drive status read is [%x]\n",retval);
525   }
526   else if (portnum==0xc1)
527   {
528      retval=wd17xx_track_r(fdc, 0);
529      //printf("disk drive track read is [%x]\n",retval);
530   }
531   else if (portnum==0xc2)
532   {
533      retval=wd17xx_sector_r(fdc, 0);
534      //printf("disk drive sector read is [%x]\n",retval);
535   }
536   else if (portnum==0xc3)
537   {
538      retval=wd17xx_data_r(fdc, 0);
539      //printf("disk drive data read [%x] at PC [%x]\n",retval,cpu_get_pc(machine().device("maincpu")));
540   }
541   else if (portnum==0xcc)
542   {
543      // CTC (?)
544      return 0x00;
545   }
546   else
547   {
548      printf("other disk drive port read [%x] PC [%x]\n",portnum,cpu_get_pc(machine().device("maincpu")));
549      return 0x00;
550   }
551
552   return retval;
553}
554
555static ADDRESS_MAP_START(rm380z_mem, AS_PROGRAM, 8, rm380z_state)
556   AM_RANGE( 0x0000, 0xdfff ) AM_READWRITE(main_read,main_write)
557   AM_RANGE( 0xe000, 0xefff ) AM_ROM AM_REGION("maincpu", 0)
558   AM_RANGE( 0xf000, 0xf5ff ) AM_READWRITE(videoram_read,videoram_write)
559   AM_RANGE( 0xf600, 0xf9ff ) AM_ROM AM_REGION("maincpu", 0x1000)      /* Extra ROM space for COS4.0 */
560   AM_RANGE( 0xfa00, 0xfbfb ) AM_RAM
561   AM_RANGE( 0xfbfc, 0xfbff ) AM_READWRITE( port_fbfc_read, port_fbfc_write )
562   AM_RANGE( 0xfc00, 0xffff ) AM_RAM
563ADDRESS_MAP_END
564
565// ports c0-c3 are related to the floppy disk controller
566// which seems to be based on WD1771 from the documentation
567// (n.b.: this is not working properly, need to get real fdc mapping)
568
569static ADDRESS_MAP_START( rm380z_io , AS_IO, 8, rm380z_state)
570   ADDRESS_MAP_GLOBAL_MASK(0xff)
571   AM_RANGE(0x0000, 0xffff) AM_READWRITE(rm380z_io_r, rm380z_io_w)
572//   AM_RANGE(0xc3, 0xc3) AM_DEVWRITE_LEGACY("wd1771", wd17xx_command_w)
573//   AM_RANGE(0xc1, 0xc1) AM_DEVREADWRITE_LEGACY("wd1771", wd17xx_track_r, wd17xx_track_w)
574//   AM_RANGE(0xc2, 0xc2) AM_DEVREADWRITE_LEGACY("wd1771", wd17xx_sector_r, wd17xx_sector_w)
575//   AM_RANGE(0xc0, 0xc0) AM_DEVREADWRITE_LEGACY("wd1771", wd17xx_data_r, wd17xx_data_w)
576ADDRESS_MAP_END
577
578//
579// how do we simulate the "keyup" event in MESS?
580// rm380z documentation says that data from the keyboard appears in the FBFC latch
581// when key is *released*
582//
583
584int rm380z_state::keyboard_decode()
585{
586      int outKb=0x00;
587      bool controlPressed=false;
588
589      int k2=input_port_read(machine(),"kbModifiers");
590      if ((k2&0x01)||(k2&0x02))
591      {
592         controlPressed=true;
593      }
594     
595      int k=input_port_read(machine(),"pc_keyboard_0");
596      if (k&1)      outKb=0x51; //Q
597      else if (k&2)   outKb=0x52; //R
598      else if (k&4) outKb=0x53; //S
599      else if (k&8) outKb=0x54; //T
600      else if (k&0x10)
601      {
602         if (controlPressed)   outKb=0x15; //ctrl-u
603         else outKb=0x55; //U
604      }
605      else if (k&0x20) outKb=0x56; //V
606      else if (k&0x40)
607      {
608         if (controlPressed)   outKb=0x16; //ctrl-w
609         else outKb=0x57; //W
610      }
611      else if (k&0x80) outKb=0x58; //X
612      else if (k&0x100) outKb=0x59; //Y
613      else if (k&0x200) outKb=0x5a; //Z
614      else if (k&0x400) outKb=0x7f; // backspace
615
616      k=input_port_read(machine(),"pc_keyboard_1");
617      if (k&1)      outKb=0x31; //1
618      else if (k&2)   outKb=0x32; //2
619      else if (k&4)   outKb=0x33; //3
620      else if (k&8)   outKb=0x34; //4
621      else if (k&0x10)   outKb=0x35; //5
622      else if (k&0x20)   outKb=0x36; //6
623      else if (k&0x40)   outKb=0x37; //7
624      else if (k&0x80)   outKb=0x38; //8
625      else if (k&0x100)   outKb=0x39; //9
626      else if (k&0x200)   outKb=0x30; //0
627      else if (k&0x400)   outKb=0x0d; //enter
628      else if (k&0x800)   outKb=0x2e; //.
629
630      k=input_port_read(machine(),"pc_keyboard_2");
631      if (k&1)     
632      {
633         if (controlPressed)   outKb=0x01; //ctrl-a
634         else outKb=0x41; //A
635      }
636      else if (k&2)   outKb=0x42; //B
637      else if (k&4) outKb=0x43; //C
638      else if (k&8) outKb=0x44; //D
639      else if (k&0x10) outKb=0x45; //E
640      else if (k&0x20)
641      {
642         if (controlPressed)   outKb=0x06; //ctrl-f
643         else outKb=0x46;
644      }
645      else if (k&0x40)
646      {
647         if (controlPressed)   outKb=0x07; //bell/ctrl-g
648         else outKb=0x47; //G
649      }
650      else if (k&0x80) outKb=0x48; //H
651      else if (k&0x100) outKb=0x49; //I
652      else if (k&0x200)
653      {
654         if (controlPressed)   outKb=0x0a; //ctrl-j/cursor down
655         else outKb=0x4a; //J
656      }
657      else if (k&0x400) outKb=0x4b; //k
658      else if (k&0x800)
659      {
660         if (controlPressed)   outKb=0x0c; //ctrl-l
661         else outKb=0x4c; //L
662      }
663      else if (k&0x1000) outKb=0x4d; //m
664      else if (k&0x2000) outKb=0x4e; //n
665      else if (k&0x4000) outKb=0x4f; //o
666      else if (k&0x8000) outKb=0x50; //p
667
668      return outKb;
669}
670
671INPUT_PORTS_START( rm380z )
672   PORT_START("pc_keyboard_0")
673   PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q)
674   PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R)
675   PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S)
676   PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T)
677   PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U)
678   PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V)
679   PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W)
680   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X)
681   PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y)
682   PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z)
683   PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("backspace") PORT_CODE(KEYCODE_BACKSPACE)
684
685   PORT_START("pc_keyboard_1")
686   PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1)
687   PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2)
688   PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3)
689   PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4)
690   PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5)
691   PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6)
692   PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7)
693   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8)
694   PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9)
695   PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0)
696   PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER)
697   PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP)
698
699   PORT_START("pc_keyboard_2")
700   PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A)
701   PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B)
702   PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C)
703   PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D)
704   PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E)
705   PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F)
706   PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G)
707   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H)
708   PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I)
709   PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J)
710   PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K)
711   PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L)
712   PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M)
713   PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N)
714   PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O)
715   PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P)
716
717   PORT_START("kbModifiers")
718   PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("lctrl") PORT_CODE(KEYCODE_LCONTROL)
719   PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("rctrl") PORT_CODE(KEYCODE_RCONTROL)
720
721INPUT_PORTS_END
722
723//
724//
725//
726
727#define chdimx 5
728#define chdimy 9
729#define ncx 8
730#define ncy 16
731#define screencols 40
732#define screenrows 24
733
734static void putChar(int charnum,int x,int y,UINT16* pscr,unsigned char* chsb)
735{
736   if ((charnum>0)&&(charnum<=0x7f))
737   {
738      int basex=chdimx*(charnum/ncy);
739      int basey=chdimy*(charnum%ncy);
740     
741      int inix=x*chdimx;
742      int iniy=y*chdimx*screencols*chdimy;
743     
744      for (int r=0;r<chdimy;r++)
745      {
746         for (int c=0;c<chdimx;c++)
747         {
748            pscr[(inix+c)+(iniy+(r*chdimx*screencols))]=(chsb[((basey+r)*(chdimx*ncx))+(basex+c)])==0xff?0:1;
749         }
750      }
751   }
752}
753
754static SCREEN_UPDATE( rm380z )
755{
756   rm380z_state *state = screen.machine().driver_data<rm380z_state>();
757
758   unsigned char* pChar=screen.machine().region("maincpu")->base()+0x1600;
759   UINT16* scrptr = &bitmap.pix16(0, 0);
760
761   for (int row=0;row<screenrows;row++)
762   {
763      for (int col=0;col<screencols;col++)
764      {
765         unsigned char curchar=state->m_vram[(row*64)+col];
766         putChar(curchar,col,row,scrptr,pChar);         
767      }
768   }
769
770   return 0;
771}
772
773//
774//
775//
776
777static const floppy_interface rm380z_floppy_interface =
778{
779   DEVCB_NULL,
780   DEVCB_NULL,
781   DEVCB_NULL,
782   DEVCB_NULL,
783   DEVCB_NULL,
784   FLOPPY_STANDARD_5_25_DSSD,
785   LEGACY_FLOPPY_OPTIONS_NAME(default),
786   "floppy0",
787   NULL
788};
789
790
791static MACHINE_CONFIG_START( rm380z, rm380z_state )
792   /* basic machine hardware */
793   MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz)
794   MCFG_CPU_PROGRAM_MAP(rm380z_mem)
795   MCFG_CPU_IO_MAP(rm380z_io)
796
797   /* video hardware */
798   MCFG_SCREEN_ADD("screen", RASTER)
799   MCFG_SCREEN_REFRESH_RATE(50)
800   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
801   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
802   MCFG_SCREEN_SIZE((screencols*chdimx), (screenrows*chdimy))
803   MCFG_SCREEN_VISIBLE_AREA(0, (screencols*chdimx)-1, 0, (screenrows*chdimy)-1)
804   MCFG_SCREEN_UPDATE(rm380z)
805   MCFG_PALETTE_LENGTH(2)
806   MCFG_PALETTE_INIT(black_and_white)
807
808   /* floppy disk */
809   MCFG_FD1771_ADD("wd1771", default_wd17xx_interface)
810   MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, rm380z_floppy_interface)
811
812MACHINE_CONFIG_END
813
814/* ROM definition */
815ROM_START( rm380z )
816   ROM_REGION( 0x1600+0x1680, "maincpu", 0 )
817   ROM_LOAD( "cos40b-m.bin", 0x0000, 0x1000, CRC(1f0b3a5c) SHA1(0b29cb2a3b7eaa3770b34f08c4fd42844f42700f))
818   ROM_LOAD( "cos40b-m_f600-f9ff.bin", 0x1000, 0x400, CRC(e3397d9d) SHA1(490a0c834b0da392daf782edc7d51ca8f0668b1a))
819   ROM_LOAD( "cos40b-m_1c00-1dff.bin", 0x1400, 0x200, CRC(0f759f44) SHA1(9689c1c1faa62c56def999cbedbbb0c8d928dcff))
820   ROM_LOAD( "ch3.raw", 0x1600, 0x1680, CRC(e0b10221) SHA1(95304ccad9a7af49d79a349feb2bc23035f90abc))
821ROM_END
822
823/* Driver */
824
825COMP(1978, rm380z, 0,      0,       rm380z,    rm380z,  0,    "Research Machines", "RM-380Z", GAME_NO_SOUND_HW)

Previous 15994 Revisions Next


© 1998-2018 The MESS Team