Previous 199869 Revisions Next

r32303 Tuesday 23rd September, 2014 at 08:09:56 UTC by Curt Coder
(MESS) a7000: Renamed to riscpc.c and added missing variants. (nw)
[src/mess]mess.lst mess.mak
[src/mess/drivers]a7000.c riscpc.c*

trunk/src/mess/drivers/a7000.c
r32302r32303
1// license:MAME
2// copyright-holders:Angelo Salese
3/***************************************************************************
4
5    Acorn Archimedes 7000/7000+
6
7    very preliminary driver by Angelo Salese,
8    based on work by Tomasz Slanina and Tom Walker
9
10    TODO:
11    - probably needs a full rewrite & merge with ssfindo.c
12
13    ???
14    bp (0382827C) (second trigger)
15    do R13 = SR13
16
17****************************************************************************/
18
19#include "emu.h"
20#include "cpu/arm7/arm7.h"
21#include "cpu/arm7/arm7core.h"
22
23
24class a7000_state : public driver_device
25{
26public:
27   a7000_state(const machine_config &mconfig, device_type type, const char *tag)
28      : driver_device(mconfig, type, tag),
29      m_maincpu(*this, "maincpu"),
30      m_palette(*this, "palette")
31   { }
32
33   required_device<cpu_device> m_maincpu;
34   required_device<palette_device> m_palette;
35   DECLARE_READ32_MEMBER(a7000_iomd_r);
36   DECLARE_WRITE32_MEMBER(a7000_iomd_w);
37   DECLARE_WRITE32_MEMBER(a7000_vidc20_w);
38
39   UINT8 m_vidc20_pal_index;
40   UINT16 m_vidc20_horz_reg[0x10];
41   UINT16 m_vidc20_vert_reg[0x10];
42   UINT8 m_vidc20_bpp_mode;
43   emu_timer *m_flyback_timer;
44   UINT16 m_timer_in[2];
45   UINT16 m_timer_out[2];
46   int m_timer_counter[2];
47   emu_timer *m_IOMD_timer[2];
48   UINT8 m_IRQ_status_A;
49   UINT8 m_IRQ_mask_A;
50   UINT8 m_IOMD_IO_ctrl;
51   UINT8 m_IOMD_keyb_ctrl;
52   UINT16 m_io_id;
53   UINT8 m_viddma_status;
54   UINT32 m_viddma_addr_start;
55   UINT32 m_viddma_addr_end;
56   UINT8 m_t0readinc;
57   UINT8 m_t1readinc;
58   void fire_iomd_timer(int timer);
59   void viddma_transfer_start();
60   void vidc20_dynamic_screen_change();
61   virtual void machine_reset();
62   virtual void machine_start();
63
64   UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
65   TIMER_CALLBACK_MEMBER(IOMD_timer0_callback);
66   TIMER_CALLBACK_MEMBER(IOMD_timer1_callback);
67   TIMER_CALLBACK_MEMBER(flyback_timer_callback);
68};
69
70
71/*
72 *
73 * VIDC20 chip emulation
74 *
75 */
76
77
78static const char *const vidc20_regnames[] =
79{
80   "Video Palette",                    // 0
81   "Video Palette Address",            // 1
82   "RESERVED",                         // 2
83   "LCD offset",                       // 3
84   "Border Colour",                    // 4
85   "Cursor Palette Logical Colour 1",  // 5
86   "Cursor Palette Logical Colour 2",  // 6
87   "Cursor Palette Logical Colour 3",  // 7
88   "Horizontal",                       // 8
89   "Vertical",                         // 9
90   "Stereo Image",                     // A
91   "Sound",                            // B
92   "External",                         // C
93   "Frequency Synthesis",              // D
94   "Control",                          // E
95   "Data Control"                      // F
96};
97
98#if 0
99static const char *const vidc20_horz_regnames[] =
100{
101   "Horizontal Cycle",                 // 0x80 HCR
102   "Horizontal Sync Width",            // 0x81 HSWR
103   "Horizontal Border Start",          // 0x82 HBSR
104   "Horizontal Display Start",         // 0x83 HDSR
105   "Horizontal Display End",           // 0x84 HDER
106   "Horizontal Border End",            // 0x85 HBER
107   "Horizontal Cursor Start",          // 0x86 HCSR
108   "Horizontal Interlace",             // 0x87 HIR
109   "Horizontal Counter TEST",          // 0x88
110   "Horizontal <UNDEFINED>",           // 0x89
111   "Horizontal <UNDEFINED>",           // 0x8a
112   "Horizontal <UNDEFINED>",           // 0x8b
113   "Horizontal All TEST",              // 0x8c
114   "Horizontal <UNDEFINED>",           // 0x8d
115   "Horizontal <UNDEFINED>",           // 0x8e
116   "Horizontal <UNDEFINED>"            // 0x8f
117};
118#endif
119
120#define HCR  0
121#define HSWR 1
122#define HBSR 2
123#define HDSR 3
124#define HDER 4
125#define HBER 5
126#define HCSR 6
127#define HIR  7
128
129#if 0
130static const char *const vidc20_vert_regnames[] =
131{
132   "Vertical Cycle",                   // 0x90 VCR
133   "Vertical Sync Width",              // 0x91 VSWR
134   "Vertical Border Start",            // 0x92 VBSR
135   "Vertical Display Start",           // 0x93 VDSR
136   "Vertical Display End",             // 0x94 VDER
137   "Vertical Border End",              // 0x95 VBER
138   "Vertical Cursor Start",            // 0x96 VCSR
139   "Vertical Cursor End",              // 0x97 VCER
140   "Vertical Counter TEST",            // 0x98
141   "Horizontal <UNDEFINED>",           // 0x99
142   "Vertical Counter Increment TEST",  // 0x9a
143   "Horizontal <UNDEFINED>",           // 0x9b
144   "Vertical All TEST",                // 0x9c
145   "Horizontal <UNDEFINED>",           // 0x9d
146   "Horizontal <UNDEFINED>",           // 0x9e
147   "Horizontal <UNDEFINED>"            // 0x9f
148};
149#endif
150
151#define VCR  0
152#define VSWR 1
153#define VBSR 2
154#define VDSR 3
155#define VDER 4
156#define VBER 5
157#define VCSR 6
158#define VCER 7
159
160void a7000_state::vidc20_dynamic_screen_change()
161{
162   /* sanity checks - first pass */
163   /*
164   total cycles + border start/end
165   */
166   if(m_vidc20_horz_reg[HCR] && m_vidc20_horz_reg[HBSR] && m_vidc20_horz_reg[HBER] &&
167      m_vidc20_vert_reg[VCR] && m_vidc20_vert_reg[VBSR] && m_vidc20_vert_reg[VBER])
168   {
169      /* sanity checks - second pass */
170      /*
171      total cycles > border end > border start
172      */
173      if((m_vidc20_horz_reg[HCR] > m_vidc20_horz_reg[HBER]) &&
174         (m_vidc20_horz_reg[HBER] > m_vidc20_horz_reg[HBSR]) &&
175         (m_vidc20_vert_reg[VCR] > m_vidc20_vert_reg[VBER]) &&
176         (m_vidc20_vert_reg[VBER] > m_vidc20_vert_reg[VBSR]))
177      {
178         /* finally ready to change the resolution */
179         int hblank_period,vblank_period;
180         rectangle visarea = machine().first_screen()->visible_area();
181         hblank_period = (m_vidc20_horz_reg[HCR] & 0x3ffc);
182         vblank_period = (m_vidc20_vert_reg[VCR] & 0x3fff);
183         /* note that we use the border registers as the visible area */
184         visarea.min_x = (m_vidc20_horz_reg[HBSR] & 0x3ffe);
185         visarea.max_x = (m_vidc20_horz_reg[HBER] & 0x3ffe)-1;
186         visarea.min_y = (m_vidc20_vert_reg[VBSR] & 0x1fff);
187         visarea.max_y = (m_vidc20_vert_reg[VBER] & 0x1fff)-1;
188
189         machine().first_screen()->configure(hblank_period, vblank_period, visarea, machine().first_screen()->frame_period().attoseconds );
190         logerror("VIDC20: successfully changed the screen to:\n Display Size = %d x %d\n Border Size %d x %d\n Cycle Period %d x %d\n",
191                  (m_vidc20_horz_reg[HDER]-m_vidc20_horz_reg[HDSR]),(m_vidc20_vert_reg[VDER]-m_vidc20_vert_reg[VDSR]),
192                  (m_vidc20_horz_reg[HBER]-m_vidc20_horz_reg[HBSR]),(m_vidc20_vert_reg[VBER]-m_vidc20_vert_reg[VBSR]),
193                  hblank_period,vblank_period);
194      }
195   }
196}
197
198WRITE32_MEMBER( a7000_state::a7000_vidc20_w )
199{
200   int r,g,b,cursor_index,horz_reg,vert_reg,reg = data >> 28;
201
202   switch(reg)
203   {
204      case 0: // Video Palette
205         r = (data & 0x0000ff) >> 0;
206         g = (data & 0x00ff00) >> 8;
207         b = (data & 0xff0000) >> 16;
208
209         m_palette->set_pen_color(m_vidc20_pal_index & 0xff,r,g,b);
210
211         /* auto-increment & wrap-around */
212         m_vidc20_pal_index++;
213         m_vidc20_pal_index &= 0xff;
214         break;
215
216      case 1: // Video Palette Address
217
218         // according to RPCEmu, these mustn't be set
219         if (data & 0x0fffff00)
220            return;
221
222         m_vidc20_pal_index = data & 0xff;
223         break;
224
225      case 4: // Border Color
226         r = (data & 0x0000ff) >> 0;
227         g = (data & 0x00ff00) >> 8;
228         b = (data & 0xff0000) >> 16;
229
230         m_palette->set_pen_color(0x100,r,g,b);
231         break;
232      case 5: // Cursor Palette Logical Colour n
233      case 6:
234      case 7:
235         cursor_index = 0x100 + reg - 4; // 0x101,0x102 and 0x103 (plus 0x100 of above, 2bpp)
236
237         r = (data & 0x0000ff) >> 0;
238         g = (data & 0x00ff00) >> 8;
239         b = (data & 0xff0000) >> 16;
240
241         m_palette->set_pen_color(cursor_index,r,g,b);
242         break;
243      case 8: // Horizontal
244         horz_reg = (data >> 24) & 0xf;
245         m_vidc20_horz_reg[horz_reg] = data & 0x3fff;
246         if(horz_reg == 0 || horz_reg == 2 || horz_reg == 5)
247            vidc20_dynamic_screen_change();
248
249         // logerror("VIDC20: %s Register write = %08x (%d)\n",vidc20_horz_regnames[horz_reg],val,val);
250         break;
251      case 9: // Vertical
252         vert_reg = (data >> 24) & 0xf;
253         m_vidc20_vert_reg[vert_reg] = data & 0x1fff;
254         if(vert_reg == 0 || vert_reg == 2 || vert_reg == 5)
255            vidc20_dynamic_screen_change();
256
257         if(vert_reg == 4)
258         {
259            if(m_vidc20_vert_reg[VDER] != 0)
260               m_flyback_timer->adjust(machine().first_screen()->time_until_pos(m_vidc20_vert_reg[VDER]));
261            else
262               m_flyback_timer->adjust(attotime::never);
263         }
264
265         // logerror("VIDC20: %s Register write = %08x (%d)\n",vidc20_vert_regnames[vert_reg],val,val);
266
267         break;
268      case 0x0e: // Control
269         m_vidc20_bpp_mode = (data & 0xe0) >> 5;
270         break;
271      default: logerror("VIDC20: %s Register write = %08x\n",vidc20_regnames[reg],data & 0xfffffff);
272   }
273}
274
275UINT32 a7000_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
276{
277   int x_size,y_size,x_start,y_start;
278   int x,y,xi;
279   UINT32 count;
280   UINT8 *vram = memregion("vram")->base();
281
282   bitmap.fill(m_palette->pen(0x100), cliprect);
283
284   x_size = (m_vidc20_horz_reg[HDER]-m_vidc20_horz_reg[HDSR]);
285   y_size = (m_vidc20_vert_reg[VDER]-m_vidc20_vert_reg[VDSR]);
286   x_start = m_vidc20_horz_reg[HDSR];
287   y_start = m_vidc20_vert_reg[VDSR];
288
289   /* check if display is enabled */
290   if(x_size <= 0 || y_size <= 0)
291      return 0;
292
293//  popmessage("%d",m_vidc20_bpp_mode);
294
295   count = 0;
296
297   switch(m_vidc20_bpp_mode)
298   {
299      case 0: /* 1 bpp */
300      {
301         for(y=0;y<y_size;y++)
302         {
303            for(x=0;x<x_size;x+=8)
304            {
305               for(xi=0;xi<8;xi++)
306                  bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((vram[count]>>(xi))&1);
307
308               count++;
309            }
310         }
311      }
312      break;
313      case 1: /* 2 bpp */
314      {
315         for(y=0;y<y_size;y++)
316         {
317            for(x=0;x<x_size;x+=4)
318            {
319               for(xi=0;xi<4;xi++)
320                  bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((vram[count]>>(xi*2))&3);
321
322               count++;
323            }
324         }
325      }
326      break;
327      case 2: /* 4 bpp */
328      {
329         for(y=0;y<y_size;y++)
330         {
331            for(x=0;x<x_size;x+=2)
332            {
333               for(xi=0;xi<2;xi++)
334                  bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((vram[count]>>(xi*4))&0xf);
335
336               count++;
337            }
338         }
339      }
340      break;
341      case 3: /* 8 bpp */
342      {
343         for(y=0;y<y_size;y++)
344         {
345            for(x=0;x<x_size;x++)
346            {
347               bitmap.pix32(y+y_start, x+x_start) = m_palette->pen((vram[count])&0xff);
348
349               count++;
350            }
351         }
352      }
353      break;
354      case 4: /* 16 bpp */
355      {
356         for(y=0;y<y_size;y++)
357         {
358            for(x=0;x<x_size;x++)
359            {
360               int r,g,b,pen;
361
362               pen = ((vram[count]<<8)|(vram[count+1]))&0xffff;
363               r = (pen & 0x000f);
364               g = (pen & 0x00f0) >> 4;
365               b = (pen & 0x0f00) >> 8;
366               r = (r << 4) | (r & 0xf);
367               g = (g << 4) | (g & 0xf);
368               b = (b << 4) | (b & 0xf);
369
370               bitmap.pix32(y+y_start, x+x_start) =  b | g << 8 | r << 16;
371
372               count+=2;
373            }
374         }
375      }
376      break;
377      case 6: /* 32 bpp */
378      {
379         for(y=0;y<y_size;y++)
380         {
381            for(x=0;x<x_size;x++)
382            {
383               int r,g,b,pen;
384
385               pen = ((vram[count]<<24)|(vram[count+1]<<16)|(vram[count+2]<<8)|(vram[count+3]<<0));
386               r = (pen & 0x0000ff);
387               g = (pen & 0x00ff00) >> 8;
388               b = (pen & 0xff0000) >> 16;
389
390               bitmap.pix32(y+y_start, x+x_start) =  b | g << 8 | r << 16;
391
392               count+=4;
393            }
394         }
395      }
396      break;
397      default:
398         //fatalerror("VIDC20 %08x BPP mode not supported\n",m_vidc20_bpp_mode);
399         break;
400   }
401
402   return 0;
403}
404
405/*
406*
407* IOMD / ARM7500 / ARM7500FE chip emulation
408*
409*/
410
411/* TODO: some of these registers are actually ARM7500 specific */
412static const char *const iomd_regnames[] =
413{
414   "I/O Control",                      // 0x000 IOCR
415   "Keyboard Data",                    // 0x004 KBDDAT
416   "Keyboard Control",                 // 0x008 KBDCR
417   "General Purpose I/O Lines",        // 0x00c IOLINES
418   "IRQA Status",                      // 0x010 IRQSTA
419   "IRQA Request/clear",               // 0x014 IRQRQA
420   "IRQA Mask",                        // 0x018 IRQMSKA
421   "Enter SUSPEND Mode",               // 0x01c SUSMODE
422   "IRQB Status",                      // 0x020 IRQSTB
423   "IRQB Request/clear",               // 0x024 IRQRQB
424   "IRQB Mask",                        // 0x028 IRQMSKB
425   "Enter STOP Mode",                  // 0x02c STOPMODE
426   "FIQ Status",                       // 0x030 FIQST
427   "FIQ Request/clear",                // 0x034 FIQRQ
428   "FIQ Mask",                         // 0x038 FIQMSK
429   "Clock divider control",            // 0x03c CLKCTL
430   "Timer 0 Low Bits",                 // 0x040 T0LOW
431   "Timer 0 High Bits",                // 0x044 T0HIGH
432   "Timer 0 Go Command",               // 0x048 T0GO
433   "Timer 0 Latch Command",            // 0x04c T0LATCH
434   "Timer 1 Low Bits",                 // 0x050 T1LOW
435   "Timer 1 High Bits",                // 0x054 T1HIGH
436   "Timer 1 Go Command",               // 0x058 T1GO
437   "Timer 1 Latch Command",            // 0x05c T1LATCH
438   "IRQC Status",                      // 0x060 IRQSTC
439   "IRQC Request/clear",               // 0x064 IRQRQC
440   "IRQC Mask",                        // 0x068 IRQMSKC
441   "LCD and IIS Control Bits",         // 0x06c VIDIMUX
442   "IRQD Status",                      // 0x070 IRQSTD
443   "IRQD Request/clear",               // 0x074 IRQRQD
444   "IRQD Mask",                        // 0x078 IRQMSKD
445   "<RESERVED>",                       // 0x07c
446   "ROM Control Bank 0",               // 0x080 ROMCR0
447   "ROM Control Bank 1",               // 0x084 ROMCR1
448   "DRAM Control (IOMD)",              // 0x088 DRAMCR
449   "VRAM and Refresh Control",         // 0x08c VREFCR
450   "Flyback Line Size",                // 0x090 FSIZE
451   "Chip ID no. Low Byte",             // 0x094 ID0
452   "Chip ID no. High Byte",            // 0x098 ID1
453   "Chip Version Number",              // 0x09c VERSION
454   "Mouse X Position",                 // 0x0a0 MOUSEX
455   "Mouse Y Position",                 // 0x0a4 MOUSEY
456   "Mouse Data",                       // 0x0a8 MSEDAT
457   "Mouse Control",                    // 0x0ac MSECR
458   "<RESERVED>",                       // 0x0b0
459   "<RESERVED>",                       // 0x0b4
460   "<RESERVED>",                       // 0x0b8
461   "<RESERVED>",                       // 0x0bc
462   "DACK Timing Control",              // 0x0c0 DMATCR
463   "I/O Timing Control",               // 0x0c4 IOTCR
464   "Expansion Card Timing",            // 0x0c8 ECTCR
465   "DMA External Control",             // 0x0cc DMAEXT (IOMD) / ASTCR (ARM7500)
466   "DRAM Width Control",               // 0x0d0 DRAMWID
467   "Force CAS/RAS Lines Low",          // 0x0d4 SELFREF
468   "<RESERVED>",                       // 0x0d8
469   "<RESERVED>",                       // 0x0dc
470   "A to D IRQ Control",               // 0x0e0 ATODICR
471   "A to D IRQ Status",                // 0x0e4 ATODCC
472   "A to D IRQ Converter Control",     // 0x0e8 ATODICR
473   "A to D IRQ Counter 1",             // 0x0ec ATODCNT1
474   "A to D IRQ Counter 2",             // 0x0f0 ATODCNT2
475   "A to D IRQ Counter 3",             // 0x0f4 ATODCNT3
476   "A to D IRQ Counter 4",             // 0x0f8 ATODCNT4
477   "<RESERVED>",                       // 0x0fc
478   "I/O DMA 0 CurA",                   // 0x100 IO0CURA
479   "I/O DMA 0 EndA",                   // 0x104 IO0ENDA
480   "I/O DMA 0 CurB",                   // 0x108 IO0CURB
481   "I/O DMA 0 EndB",                   // 0x10c IO0ENDB
482   "I/O DMA 0 Control",                // 0x110 IO0CR
483   "I/O DMA 0 Status",                 // 0x114 IO0ST
484   "<RESERVED>",                       // 0x118
485   "<RESERVED>",                       // 0x11c
486   "I/O DMA 1 CurA",                   // 0x120 IO1CURA
487   "I/O DMA 1 EndA",                   // 0x124 IO1ENDA
488   "I/O DMA 1 CurB",                   // 0x128 IO1CURB
489   "I/O DMA 1 EndB",                   // 0x12c IO1ENDB
490   "I/O DMA 1 Control",                // 0x130 IO1CR
491   "I/O DMA 1 Status",                 // 0x134 IO1ST
492   "<RESERVED>",                       // 0x138
493   "<RESERVED>",                       // 0x13c
494   "I/O DMA 2 CurA",                   // 0x140 IO2CURA
495   "I/O DMA 2 EndA",                   // 0x144 IO2ENDA
496   "I/O DMA 2 CurB",                   // 0x148 IO2CURB
497   "I/O DMA 2 EndB",                   // 0x14c IO2ENDB
498   "I/O DMA 2 Control",                // 0x150 IO2CR
499   "I/O DMA 2 Status",                 // 0x154 IO2ST
500   "<RESERVED>",                       // 0x158
501   "<RESERVED>",                       // 0x15c
502   "I/O DMA 3 CurA",                   // 0x160 IO3CURA
503   "I/O DMA 3 EndA",                   // 0x164 IO3ENDA
504   "I/O DMA 3 CurB",                   // 0x168 IO3CURB
505   "I/O DMA 3 EndB",                   // 0x16c IO3ENDB
506   "I/O DMA 3 Control",                // 0x170 IO3CR
507   "I/O DMA 3 Status",                 // 0x174 IO3ST
508   "<RESERVED>",                       // 0x178
509   "<RESERVED>",                       // 0x17c
510   "Sound DMA 0 CurA",                 // 0x180 SD0CURA
511   "Sound DMA 0 EndA",                 // 0x184 SD0ENDA
512   "Sound DMA 0 CurB",                 // 0x188 SD0CURB
513   "Sound DMA 0 EndB",                 // 0x18c SD0ENDB
514   "Sound DMA 0 Control",              // 0x190 SD0CR
515   "Sound DMA 0 Status",               // 0x194 SD0ST
516   "<RESERVED>",                       // 0x198
517   "<RESERVED>",                       // 0x19c
518   "Sound DMA 1 CurA",                 // 0x1a0 SD1CURA
519   "Sound DMA 1 EndA",                 // 0x1a4 SD1ENDA
520   "Sound DMA 1 CurB",                 // 0x1a8 SD1CURB
521   "Sound DMA 1 EndB",                 // 0x1ac SD1ENDB
522   "Sound DMA 1 Control",              // 0x1b0 SD1CR
523   "Sound DMA 1 Status",               // 0x1b4 SD1ST
524   "<RESERVED>",                       // 0x1b8
525   "<RESERVED>",                       // 0x1bc
526   "Cursor DMA Current",               // 0x1c0 CURSCUR
527   "Cursor DMA Init",                  // 0x1c4 CURSINIT
528   "Duplex LCD Current B",             // 0x1c8 VIDCURB
529   "<RESERVED>",                       // 0x1cc
530   "Video DMA Current",                // 0x1d0 VIDCUR
531   "Video DMA End",                    // 0x1d4 VIDEND
532   "Video DMA Start",                  // 0x1d8 VIDSTART
533   "Video DMA Init",                   // 0x1dc VIDINIT
534   "Video DMA Control",                // 0x1e0 VIDCR
535   "<RESERVED>",                       // 0x1e4
536   "Duplex LCD Init B",                // 0x1e8 VIDINITB
537   "<RESERVED>",                       // 0x1ec
538   "DMA IRQ Status",                   // 0x1f0 DMAST
539   "DMA IRQ Request",                  // 0x1f4 DMARQ
540   "DMA IRQ Mask",                     // 0x1f8 DMAMSK
541   "<RESERVED>"                        // 0x1fc
542};
543
544#define IOMD_IOCR       0x000/4
545#define IOMD_KBDDAT     0x004/4
546#define IOMD_KBDCR      0x008/4
547
548#define IOMD_IRQSTA     0x010/4
549#define IOMD_IRQRQA     0x014/4
550#define IOMD_IRQMSKA    0x018/4
551
552#define IOMD_T0LOW      0x040/4
553#define IOMD_T0HIGH     0x044/4
554#define IOMD_T0GO       0x048/4
555#define IOMD_T0LATCH    0x04c/4
556
557#define IOMD_T1LOW      0x050/4
558#define IOMD_T1HIGH     0x054/4
559#define IOMD_T1GO       0x058/4
560#define IOMD_T1LATCH    0x05c/4
561
562#define IOMD_ID0        0x094/4
563#define IOMD_ID1        0x098/4
564#define IOMD_VERSION    0x09c/4
565
566#define IOMD_VIDCUR     0x1d0/4
567#define IOMD_VIDEND     0x1d4/4
568#define IOMD_VIDSTART   0x1d8/4
569#define IOMD_VIDINIT    0x1dc/4
570#define IOMD_VIDCR      0x1e0/4
571
572
573
574void a7000_state::fire_iomd_timer(int timer)
575{
576   int timer_count = m_timer_counter[timer];
577   int val = timer_count / 2; // correct?
578
579   if(val==0)
580      m_IOMD_timer[timer]->adjust(attotime::never);
581   else
582      m_IOMD_timer[timer]->adjust(attotime::from_usec(val), 0, attotime::from_usec(val));
583}
584
585TIMER_CALLBACK_MEMBER(a7000_state::IOMD_timer0_callback)
586{
587   m_IRQ_status_A|=0x20;
588   if(m_IRQ_mask_A&0x20)
589   {
590      generic_pulse_irq_line(m_maincpu, ARM7_IRQ_LINE,1);
591   }
592}
593
594TIMER_CALLBACK_MEMBER(a7000_state::IOMD_timer1_callback)
595{
596   m_IRQ_status_A|=0x40;
597   if(m_IRQ_mask_A&0x40)
598   {
599      generic_pulse_irq_line(m_maincpu, ARM7_IRQ_LINE,1);
600   }
601}
602
603TIMER_CALLBACK_MEMBER(a7000_state::flyback_timer_callback)
604{
605   m_IRQ_status_A|=0x08;
606   if(m_IRQ_mask_A&0x08)
607   {
608      generic_pulse_irq_line(m_maincpu, ARM7_IRQ_LINE,1);
609   }
610
611   m_flyback_timer->adjust(machine().first_screen()->time_until_pos(m_vidc20_vert_reg[VDER]));
612}
613
614void a7000_state::viddma_transfer_start()
615{
616   address_space &mem = m_maincpu->space(AS_PROGRAM);
617   UINT32 src = m_viddma_addr_start;
618   UINT32 dst = 0;
619   UINT32 size = m_viddma_addr_end;
620   UINT32 dma_index;
621   UINT8 *vram = memregion("vram")->base();
622
623   /* TODO: this should actually be a qword transfer */
624   for(dma_index = 0;dma_index < size;dma_index++)
625   {
626      vram[dst] = mem.read_byte(src);
627
628      src++;
629      dst++;
630   }
631}
632
633READ32_MEMBER( a7000_state::a7000_iomd_r )
634{
635//  if(offset != IOMD_KBDCR)
636//      logerror("IOMD: %s Register (%04x) read\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4);
637
638
639   switch(offset)
640   {
641      case IOMD_IOCR:
642      {
643         UINT8 flyback;
644         int vert_pos;
645
646         vert_pos = machine().first_screen()->vpos();
647         flyback = (vert_pos <= m_vidc20_vert_reg[VDSR] || vert_pos >= m_vidc20_vert_reg[VDER]) ? 0x80 : 0x00;
648
649         return m_IOMD_IO_ctrl | 0x34 | flyback;
650      }
651      case IOMD_KBDCR:    return m_IOMD_keyb_ctrl | 0x80; //IOMD Keyb status
652
653      /*
654      1--- ---- always high
655      -x-- ---- Timer 1
656      --x- ---- Timer 0
657      ---x ---- Power On Reset
658      ---- x--- Flyback
659      ---- -x-- nINT1
660      ---- --0- always low
661      ---- ---x INT2
662      */
663      case IOMD_IRQSTA:   return (m_IRQ_status_A & ~2) | 0x80;
664      case IOMD_IRQRQA:   return (m_IRQ_status_A & m_IRQ_mask_A) | 0x80;
665      case IOMD_IRQMSKA:  return m_IRQ_mask_A;
666
667      case IOMD_T0LOW:    return m_timer_out[0] & 0xff;
668      case IOMD_T0HIGH:   return (m_timer_out[0] >> 8) & 0xff;
669
670      case IOMD_T1LOW:    return m_timer_out[1] & 0xff;
671      case IOMD_T1HIGH:   return (m_timer_out[1] >> 8) & 0xff;
672
673      case IOMD_ID0:      return m_io_id & 0xff; // IOMD ID low
674      case IOMD_ID1:      return (m_io_id >> 8) & 0xff; // IOMD ID high
675      case IOMD_VERSION:  return 0;
676
677      case IOMD_VIDEND:   return m_viddma_addr_end & 0x00fffff8; //bits 31:24 undefined
678      case IOMD_VIDSTART: return m_viddma_addr_start & 0x1ffffff8; //bits 31, 30, 29 undefined
679      case IOMD_VIDCR:    return (m_viddma_status & 0xa0) | 0x50; //bit 6 = DRAM mode, bit 4 = QWORD transfer
680
681      default:    logerror("IOMD: %s Register (%04x) read\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4); break;
682   }
683
684   return 0;
685}
686
687WRITE32_MEMBER( a7000_state::a7000_iomd_w )
688{
689//  logerror("IOMD: %s Register (%04x) write = %08x\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4,data);
690
691   switch(offset)
692   {
693      case IOMD_IOCR:     m_IOMD_IO_ctrl = data & ~0xf4; break;
694
695      case IOMD_KBDCR:
696         m_IOMD_keyb_ctrl = data & ~0xf4;
697         //keyboard_ctrl_write(data & 0x08);
698         break;
699
700      case IOMD_IRQRQA:   m_IRQ_status_A &= ~data; break;
701      case IOMD_IRQMSKA:  m_IRQ_mask_A = (data & ~2) | 0x80; break;
702
703      case IOMD_T0LOW:    m_timer_in[0] = (m_timer_in[0] & 0xff00) | (data & 0xff); break;
704      case IOMD_T0HIGH:   m_timer_in[0] = (m_timer_in[0] & 0x00ff) | ((data & 0xff) << 8); break;
705      case IOMD_T0GO:
706         m_timer_counter[0] = m_timer_in[0];
707         fire_iomd_timer(0);
708         break;
709      case IOMD_T0LATCH:
710         {
711            m_t0readinc^=1;
712            m_timer_out[0] = m_timer_counter[0];
713            if(m_t0readinc)
714            {
715               m_timer_counter[0]--;
716               if(m_timer_counter[0] < 0)
717                  m_timer_counter[0]+= m_timer_in[0];
718            }
719         }
720         break;
721
722      case IOMD_T1LOW:    m_timer_in[1] = (m_timer_in[1] & 0xff00) | (data & 0xff); break;
723      case IOMD_T1HIGH:   m_timer_in[1] = (m_timer_in[1] & 0x00ff) | ((data & 0xff) << 8); break;
724      case IOMD_T1GO:
725         m_timer_counter[1] = m_timer_in[1];
726         fire_iomd_timer(1);
727         break;
728      case IOMD_T1LATCH:
729         {
730            m_t1readinc^=1;
731            m_timer_out[1] = m_timer_counter[1];
732            if(m_t1readinc)
733            {
734               m_timer_counter[1]--;
735               if(m_timer_counter[1] < 0)
736                  m_timer_counter[1]+= m_timer_in[1];
737            }
738         }
739         break;
740
741      case IOMD_VIDEND:   m_viddma_addr_end = data & 0x00fffff8; //bits 31:24 unused
742      case IOMD_VIDSTART: m_viddma_addr_start = data & 0x1ffffff8; //bits 31, 30, 29 unused
743      case IOMD_VIDCR:
744         m_viddma_status = data & 0xa0; if(data & 0x20) { viddma_transfer_start(); }
745         break;
746
747
748      default: logerror("IOMD: %s Register (%04x) write = %08x\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4,data);
749   }
750}
751
752static ADDRESS_MAP_START( a7000_mem, AS_PROGRAM, 32, a7000_state)
753   AM_RANGE(0x00000000, 0x003fffff) AM_MIRROR(0x00800000) AM_ROM AM_REGION("user1", 0)
754//  AM_RANGE(0x01000000, 0x01ffffff) AM_NOP //expansion ROM
755//  AM_RANGE(0x02000000, 0x02ffffff) AM_RAM //VRAM
756//  I/O 03000000 - 033fffff
757//  AM_RANGE(0x03010000, 0x03011fff) //Super IO
758//  AM_RANGE(0x03012000, 0x03029fff) //FDC
759//  AM_RANGE(0x0302b000, 0x0302bfff) //Network podule
760//  AM_RANGE(0x03040000, 0x0304ffff) //podule space 0,1,2,3
761//  AM_RANGE(0x03070000, 0x0307ffff) //podule space 4,5,6,7
762   AM_RANGE(0x03200000, 0x032001ff) AM_READWRITE(a7000_iomd_r,a7000_iomd_w) //IOMD Registers //mirrored at 0x03000000-0x1ff?
763//  AM_RANGE(0x03310000, 0x03310003) //Mouse Buttons
764
765   AM_RANGE(0x03400000, 0x037fffff) AM_WRITE(a7000_vidc20_w)
766//  AM_RANGE(0x08000000, 0x08ffffff) AM_MIRROR(0x07000000) //EASI space
767   AM_RANGE(0x10000000, 0x13ffffff) AM_RAM //SIMM 0 bank 0
768   AM_RANGE(0x14000000, 0x17ffffff) AM_RAM //SIMM 0 bank 1
769//  AM_RANGE(0x18000000, 0x18ffffff) AM_MIRROR(0x03000000) AM_RAM //SIMM 1 bank 0
770//  AM_RANGE(0x1c000000, 0x1cffffff) AM_MIRROR(0x03000000) AM_RAM //SIMM 1 bank 1
771ADDRESS_MAP_END
772
773
774/* Input ports */
775static INPUT_PORTS_START( a7000 )
776INPUT_PORTS_END
777
778void a7000_state::machine_start()
779{
780   m_IOMD_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a7000_state::IOMD_timer0_callback),this));
781   m_IOMD_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a7000_state::IOMD_timer1_callback),this));
782   m_flyback_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a7000_state::flyback_timer_callback),this));
783
784   m_io_id = 0xd4e7;
785}
786
787void a7000_state::machine_reset()
788{
789   m_IOMD_IO_ctrl = 0x0b | 0x34; //bit 0,1 and 3 set high on reset plus 2,4,5 always high
790//  m_IRQ_status_A = 0x10; // set POR bit ON
791   m_IRQ_mask_A = 0x00;
792
793   m_IOMD_keyb_ctrl = 0x00;
794
795   m_IOMD_timer[0]->adjust( attotime::never);
796   m_IOMD_timer[1]->adjust( attotime::never);
797   m_flyback_timer->adjust( attotime::never);
798}
799
800static MACHINE_CONFIG_START( a7000, a7000_state )
801   /* Basic machine hardware */
802   MCFG_CPU_ADD( "maincpu", ARM7, XTAL_32MHz )
803   MCFG_CPU_PROGRAM_MAP(a7000_mem)
804
805   /* video hardware */
806   MCFG_SCREEN_ADD("screen", RASTER)
807   MCFG_SCREEN_REFRESH_RATE(60)
808   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
809   MCFG_SCREEN_SIZE(1900, 1080) //max available size
810   MCFG_SCREEN_VISIBLE_AREA(0, 1900-1, 0, 1080-1)
811   MCFG_SCREEN_UPDATE_DRIVER(a7000_state, screen_update)
812   MCFG_PALETTE_ADD("palette", 0x200)
813MACHINE_CONFIG_END
814
815static MACHINE_CONFIG_DERIVED( a7000p, a7000 )
816   MCFG_CPU_MODIFY("maincpu")
817   MCFG_CPU_CLOCK(XTAL_48MHz)
818MACHINE_CONFIG_END
819
820ROM_START(a7000)
821   ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF )
822   // Version 3.60
823   ROM_SYSTEM_BIOS( 0, "360", "RiscOS 3.60" )
824   ROMX_LOAD( "1203,101-01.bin", 0x000000, 0x200000, CRC(2eeded56) SHA1(7217f942cdac55033b9a8eec4a89faa2dd63cd68), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
825   ROMX_LOAD( "1203,102-01.bin", 0x000002, 0x200000, CRC(6db87d21) SHA1(428403ed31682041f1e3d114ea02a688d24b7d94), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
826   ROM_REGION( 0x800000, "vram", ROMREGION_ERASE00 )
827ROM_END
828
829ROM_START(a7000p)
830   ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF )
831   // Version 3.71
832   ROM_SYSTEM_BIOS( 0, "371", "RiscOS 3.71" )
833   ROMX_LOAD( "1203,261-01.bin", 0x000000, 0x200000, CRC(8e3c570a) SHA1(ffccb52fa8e165d3f64545caae1c349c604386e9), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
834   ROMX_LOAD( "1203,262-01.bin", 0x000002, 0x200000, CRC(cf4615b4) SHA1(c340f29aeda3557ebd34419fcb28559fc9b620f8), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
835   // Version 4.02
836   ROM_SYSTEM_BIOS( 1, "402", "RiscOS 4.02" )
837   ROMX_LOAD( "riscos402_1.bin", 0x000000, 0x200000, CRC(4c32f7e2) SHA1(d290e29a4de7be9eb36cbafbb2dc99b1c4ce7f72), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(2))
838   ROMX_LOAD( "riscos402_2.bin", 0x000002, 0x200000, CRC(7292b790) SHA1(67f999c1ccf5419e0a142b7e07f809e13dfed425), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(2))
839   // Version 4.39
840   ROM_SYSTEM_BIOS( 2, "439", "RiscOS 4.39" )
841   ROMX_LOAD( "riscos439_1.bin", 0x000000, 0x200000, CRC(dab94cb8) SHA1(a81fb7f1a8117f85e82764675445092d769aa9af), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(3))
842   ROMX_LOAD( "riscos439_2.bin", 0x000002, 0x200000, CRC(22e6a5d4) SHA1(b73b73c87824045130840a19ce16fa12e388c039), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(3))
843   ROM_REGION( 0x800000, "vram", ROMREGION_ERASE00 )
844ROM_END
845
846/***************************************************************************
847
848  Game driver(s)
849
850***************************************************************************/
851
852/*    YEAR  NAME        PARENT  COMPAT  MACHINE     INPUT   INIT    COMPANY FULLNAME        FLAGS */
853COMP( 1995, a7000,      0,      0,      a7000,      a7000, driver_device,   0,      "Acorn",  "Archimedes A7000",   GAME_NOT_WORKING | GAME_NO_SOUND )
854COMP( 1997, a7000p,     a7000,  0,      a7000p,     a7000, driver_device,   0,      "Acorn",  "Archimedes A7000+",  GAME_NOT_WORKING | GAME_NO_SOUND )
trunk/src/mess/drivers/riscpc.c
r0r32303
1// license:MAME
2// copyright-holders:Angelo Salese
3/***************************************************************************
4
5    Acorn Archimedes 7000/7000+
6
7    very preliminary driver by Angelo Salese,
8    based on work by Tomasz Slanina and Tom Walker
9
10    TODO:
11    - probably needs a full rewrite & merge with ssfindo.c
12
13    ???
14    bp (0382827C) (second trigger)
15    do R13 = SR13
16
17****************************************************************************/
18
19#include "emu.h"
20#include "cpu/arm7/arm7.h"
21#include "cpu/arm7/arm7core.h"
22
23
24class riscpc_state : public driver_device
25{
26public:
27   riscpc_state(const machine_config &mconfig, device_type type, const char *tag)
28      : driver_device(mconfig, type, tag),
29      m_maincpu(*this, "maincpu"),
30      m_palette(*this, "palette")
31   { }
32
33   required_device<cpu_device> m_maincpu;
34   required_device<palette_device> m_palette;
35   DECLARE_READ32_MEMBER(a7000_iomd_r);
36   DECLARE_WRITE32_MEMBER(a7000_iomd_w);
37   DECLARE_WRITE32_MEMBER(a7000_vidc20_w);
38
39   UINT8 m_vidc20_pal_index;
40   UINT16 m_vidc20_horz_reg[0x10];
41   UINT16 m_vidc20_vert_reg[0x10];
42   UINT8 m_vidc20_bpp_mode;
43   emu_timer *m_flyback_timer;
44   UINT16 m_timer_in[2];
45   UINT16 m_timer_out[2];
46   int m_timer_counter[2];
47   emu_timer *m_IOMD_timer[2];
48   UINT8 m_IRQ_status_A;
49   UINT8 m_IRQ_mask_A;
50   UINT8 m_IOMD_IO_ctrl;
51   UINT8 m_IOMD_keyb_ctrl;
52   UINT16 m_io_id;
53   UINT8 m_viddma_status;
54   UINT32 m_viddma_addr_start;
55   UINT32 m_viddma_addr_end;
56   UINT8 m_t0readinc;
57   UINT8 m_t1readinc;
58   void fire_iomd_timer(int timer);
59   void viddma_transfer_start();
60   void vidc20_dynamic_screen_change();
61   virtual void machine_reset();
62   virtual void machine_start();
63
64   UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
65   TIMER_CALLBACK_MEMBER(IOMD_timer0_callback);
66   TIMER_CALLBACK_MEMBER(IOMD_timer1_callback);
67   TIMER_CALLBACK_MEMBER(flyback_timer_callback);
68};
69
70
71/*
72 *
73 * VIDC20 chip emulation
74 *
75 */
76
77
78static const char *const vidc20_regnames[] =
79{
80   "Video Palette",                    // 0
81   "Video Palette Address",            // 1
82   "RESERVED",                         // 2
83   "LCD offset",                       // 3
84   "Border Colour",                    // 4
85   "Cursor Palette Logical Colour 1",  // 5
86   "Cursor Palette Logical Colour 2",  // 6
87   "Cursor Palette Logical Colour 3",  // 7
88   "Horizontal",                       // 8
89   "Vertical",                         // 9
90   "Stereo Image",                     // A
91   "Sound",                            // B
92   "External",                         // C
93   "Frequency Synthesis",              // D
94   "Control",                          // E
95   "Data Control"                      // F
96};
97
98#if 0
99static const char *const vidc20_horz_regnames[] =
100{
101   "Horizontal Cycle",                 // 0x80 HCR
102   "Horizontal Sync Width",            // 0x81 HSWR
103   "Horizontal Border Start",          // 0x82 HBSR
104   "Horizontal Display Start",         // 0x83 HDSR
105   "Horizontal Display End",           // 0x84 HDER
106   "Horizontal Border End",            // 0x85 HBER
107   "Horizontal Cursor Start",          // 0x86 HCSR
108   "Horizontal Interlace",             // 0x87 HIR
109   "Horizontal Counter TEST",          // 0x88
110   "Horizontal <UNDEFINED>",           // 0x89
111   "Horizontal <UNDEFINED>",           // 0x8a
112   "Horizontal <UNDEFINED>",           // 0x8b
113   "Horizontal All TEST",              // 0x8c
114   "Horizontal <UNDEFINED>",           // 0x8d
115   "Horizontal <UNDEFINED>",           // 0x8e
116   "Horizontal <UNDEFINED>"            // 0x8f
117};
118#endif
119
120#define HCR  0
121#define HSWR 1
122#define HBSR 2
123#define HDSR 3
124#define HDER 4
125#define HBER 5
126#define HCSR 6
127#define HIR  7
128
129#if 0
130static const char *const vidc20_vert_regnames[] =
131{
132   "Vertical Cycle",                   // 0x90 VCR
133   "Vertical Sync Width",              // 0x91 VSWR
134   "Vertical Border Start",            // 0x92 VBSR
135   "Vertical Display Start",           // 0x93 VDSR
136   "Vertical Display End",             // 0x94 VDER
137   "Vertical Border End",              // 0x95 VBER
138   "Vertical Cursor Start",            // 0x96 VCSR
139   "Vertical Cursor End",              // 0x97 VCER
140   "Vertical Counter TEST",            // 0x98
141   "Horizontal <UNDEFINED>",           // 0x99
142   "Vertical Counter Increment TEST",  // 0x9a
143   "Horizontal <UNDEFINED>",           // 0x9b
144   "Vertical All TEST",                // 0x9c
145   "Horizontal <UNDEFINED>",           // 0x9d
146   "Horizontal <UNDEFINED>",           // 0x9e
147   "Horizontal <UNDEFINED>"            // 0x9f
148};
149#endif
150
151#define VCR  0
152#define VSWR 1
153#define VBSR 2
154#define VDSR 3
155#define VDER 4
156#define VBER 5
157#define VCSR 6
158#define VCER 7
159
160void riscpc_state::vidc20_dynamic_screen_change()
161{
162   /* sanity checks - first pass */
163   /*
164   total cycles + border start/end
165   */
166   if(m_vidc20_horz_reg[HCR] && m_vidc20_horz_reg[HBSR] && m_vidc20_horz_reg[HBER] &&
167      m_vidc20_vert_reg[VCR] && m_vidc20_vert_reg[VBSR] && m_vidc20_vert_reg[VBER])
168   {
169      /* sanity checks - second pass */
170      /*
171      total cycles > border end > border start
172      */
173      if((m_vidc20_horz_reg[HCR] > m_vidc20_horz_reg[HBER]) &&
174         (m_vidc20_horz_reg[HBER] > m_vidc20_horz_reg[HBSR]) &&
175         (m_vidc20_vert_reg[VCR] > m_vidc20_vert_reg[VBER]) &&
176         (m_vidc20_vert_reg[VBER] > m_vidc20_vert_reg[VBSR]))
177      {
178         /* finally ready to change the resolution */
179         int hblank_period,vblank_period;
180         rectangle visarea = machine().first_screen()->visible_area();
181         hblank_period = (m_vidc20_horz_reg[HCR] & 0x3ffc);
182         vblank_period = (m_vidc20_vert_reg[VCR] & 0x3fff);
183         /* note that we use the border registers as the visible area */
184         visarea.min_x = (m_vidc20_horz_reg[HBSR] & 0x3ffe);
185         visarea.max_x = (m_vidc20_horz_reg[HBER] & 0x3ffe)-1;
186         visarea.min_y = (m_vidc20_vert_reg[VBSR] & 0x1fff);
187         visarea.max_y = (m_vidc20_vert_reg[VBER] & 0x1fff)-1;
188
189         machine().first_screen()->configure(hblank_period, vblank_period, visarea, machine().first_screen()->frame_period().attoseconds );
190         logerror("VIDC20: successfully changed the screen to:\n Display Size = %d x %d\n Border Size %d x %d\n Cycle Period %d x %d\n",
191                  (m_vidc20_horz_reg[HDER]-m_vidc20_horz_reg[HDSR]),(m_vidc20_vert_reg[VDER]-m_vidc20_vert_reg[VDSR]),
192                  (m_vidc20_horz_reg[HBER]-m_vidc20_horz_reg[HBSR]),(m_vidc20_vert_reg[VBER]-m_vidc20_vert_reg[VBSR]),
193                  hblank_period,vblank_period);
194      }
195   }
196}
197
198WRITE32_MEMBER( riscpc_state::a7000_vidc20_w )
199{
200   int r,g,b,cursor_index,horz_reg,vert_reg,reg = data >> 28;
201
202   switch(reg)
203   {
204      case 0: // Video Palette
205         r = (data & 0x0000ff) >> 0;
206         g = (data & 0x00ff00) >> 8;
207         b = (data & 0xff0000) >> 16;
208
209         m_palette->set_pen_color(m_vidc20_pal_index & 0xff,r,g,b);
210
211         /* auto-increment & wrap-around */
212         m_vidc20_pal_index++;
213         m_vidc20_pal_index &= 0xff;
214         break;
215
216      case 1: // Video Palette Address
217
218         // according to RPCEmu, these mustn't be set
219         if (data & 0x0fffff00)
220            return;
221
222         m_vidc20_pal_index = data & 0xff;
223         break;
224
225      case 4: // Border Color
226         r = (data & 0x0000ff) >> 0;
227         g = (data & 0x00ff00) >> 8;
228         b = (data & 0xff0000) >> 16;
229
230         m_palette->set_pen_color(0x100,r,g,b);
231         break;
232      case 5: // Cursor Palette Logical Colour n
233      case 6:
234      case 7:
235         cursor_index = 0x100 + reg - 4; // 0x101,0x102 and 0x103 (plus 0x100 of above, 2bpp)
236
237         r = (data & 0x0000ff) >> 0;
238         g = (data & 0x00ff00) >> 8;
239         b = (data & 0xff0000) >> 16;
240
241         m_palette->set_pen_color(cursor_index,r,g,b);
242         break;
243      case 8: // Horizontal
244         horz_reg = (data >> 24) & 0xf;
245         m_vidc20_horz_reg[horz_reg] = data & 0x3fff;
246         if(horz_reg == 0 || horz_reg == 2 || horz_reg == 5)
247            vidc20_dynamic_screen_change();
248
249         // logerror("VIDC20: %s Register write = %08x (%d)\n",vidc20_horz_regnames[horz_reg],val,val);
250         break;
251      case 9: // Vertical
252         vert_reg = (data >> 24) & 0xf;
253         m_vidc20_vert_reg[vert_reg] = data & 0x1fff;
254         if(vert_reg == 0 || vert_reg == 2 || vert_reg == 5)
255            vidc20_dynamic_screen_change();
256
257         if(vert_reg == 4)
258         {
259            if(m_vidc20_vert_reg[VDER] != 0)
260               m_flyback_timer->adjust(machine().first_screen()->time_until_pos(m_vidc20_vert_reg[VDER]));
261            else
262               m_flyback_timer->adjust(attotime::never);
263         }
264
265         // logerror("VIDC20: %s Register write = %08x (%d)\n",vidc20_vert_regnames[vert_reg],val,val);
266
267         break;
268      case 0x0e: // Control
269         m_vidc20_bpp_mode = (data & 0xe0) >> 5;
270         break;
271      default: logerror("VIDC20: %s Register write = %08x\n",vidc20_regnames[reg],data & 0xfffffff);
272   }
273}
274
275UINT32 riscpc_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
276{
277   int x_size,y_size,x_start,y_start;
278   int x,y,xi;
279   UINT32 count;
280   UINT8 *vram = memregion("vram")->base();
281
282   bitmap.fill(m_palette->pen(0x100), cliprect);
283
284   x_size = (m_vidc20_horz_reg[HDER]-m_vidc20_horz_reg[HDSR]);
285   y_size = (m_vidc20_vert_reg[VDER]-m_vidc20_vert_reg[VDSR]);
286   x_start = m_vidc20_horz_reg[HDSR];
287   y_start = m_vidc20_vert_reg[VDSR];
288
289   /* check if display is enabled */
290   if(x_size <= 0 || y_size <= 0)
291      return 0;
292
293//  popmessage("%d",m_vidc20_bpp_mode);
294
295   count = 0;
296
297   switch(m_vidc20_bpp_mode)
298   {
299      case 0: /* 1 bpp */
300      {
301         for(y=0;y<y_size;y++)
302         {
303            for(x=0;x<x_size;x+=8)
304            {
305               for(xi=0;xi<8;xi++)
306                  bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((vram[count]>>(xi))&1);
307
308               count++;
309            }
310         }
311      }
312      break;
313      case 1: /* 2 bpp */
314      {
315         for(y=0;y<y_size;y++)
316         {
317            for(x=0;x<x_size;x+=4)
318            {
319               for(xi=0;xi<4;xi++)
320                  bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((vram[count]>>(xi*2))&3);
321
322               count++;
323            }
324         }
325      }
326      break;
327      case 2: /* 4 bpp */
328      {
329         for(y=0;y<y_size;y++)
330         {
331            for(x=0;x<x_size;x+=2)
332            {
333               for(xi=0;xi<2;xi++)
334                  bitmap.pix32(y+y_start, x+xi+x_start) = m_palette->pen((vram[count]>>(xi*4))&0xf);
335
336               count++;
337            }
338         }
339      }
340      break;
341      case 3: /* 8 bpp */
342      {
343         for(y=0;y<y_size;y++)
344         {
345            for(x=0;x<x_size;x++)
346            {
347               bitmap.pix32(y+y_start, x+x_start) = m_palette->pen((vram[count])&0xff);
348
349               count++;
350            }
351         }
352      }
353      break;
354      case 4: /* 16 bpp */
355      {
356         for(y=0;y<y_size;y++)
357         {
358            for(x=0;x<x_size;x++)
359            {
360               int r,g,b,pen;
361
362               pen = ((vram[count]<<8)|(vram[count+1]))&0xffff;
363               r = (pen & 0x000f);
364               g = (pen & 0x00f0) >> 4;
365               b = (pen & 0x0f00) >> 8;
366               r = (r << 4) | (r & 0xf);
367               g = (g << 4) | (g & 0xf);
368               b = (b << 4) | (b & 0xf);
369
370               bitmap.pix32(y+y_start, x+x_start) =  b | g << 8 | r << 16;
371
372               count+=2;
373            }
374         }
375      }
376      break;
377      case 6: /* 32 bpp */
378      {
379         for(y=0;y<y_size;y++)
380         {
381            for(x=0;x<x_size;x++)
382            {
383               int r,g,b,pen;
384
385               pen = ((vram[count]<<24)|(vram[count+1]<<16)|(vram[count+2]<<8)|(vram[count+3]<<0));
386               r = (pen & 0x0000ff);
387               g = (pen & 0x00ff00) >> 8;
388               b = (pen & 0xff0000) >> 16;
389
390               bitmap.pix32(y+y_start, x+x_start) =  b | g << 8 | r << 16;
391
392               count+=4;
393            }
394         }
395      }
396      break;
397      default:
398         //fatalerror("VIDC20 %08x BPP mode not supported\n",m_vidc20_bpp_mode);
399         break;
400   }
401
402   return 0;
403}
404
405/*
406*
407* IOMD / ARM7500 / ARM7500FE chip emulation
408*
409*/
410
411/* TODO: some of these registers are actually ARM7500 specific */
412static const char *const iomd_regnames[] =
413{
414   "I/O Control",                      // 0x000 IOCR
415   "Keyboard Data",                    // 0x004 KBDDAT
416   "Keyboard Control",                 // 0x008 KBDCR
417   "General Purpose I/O Lines",        // 0x00c IOLINES
418   "IRQA Status",                      // 0x010 IRQSTA
419   "IRQA Request/clear",               // 0x014 IRQRQA
420   "IRQA Mask",                        // 0x018 IRQMSKA
421   "Enter SUSPEND Mode",               // 0x01c SUSMODE
422   "IRQB Status",                      // 0x020 IRQSTB
423   "IRQB Request/clear",               // 0x024 IRQRQB
424   "IRQB Mask",                        // 0x028 IRQMSKB
425   "Enter STOP Mode",                  // 0x02c STOPMODE
426   "FIQ Status",                       // 0x030 FIQST
427   "FIQ Request/clear",                // 0x034 FIQRQ
428   "FIQ Mask",                         // 0x038 FIQMSK
429   "Clock divider control",            // 0x03c CLKCTL
430   "Timer 0 Low Bits",                 // 0x040 T0LOW
431   "Timer 0 High Bits",                // 0x044 T0HIGH
432   "Timer 0 Go Command",               // 0x048 T0GO
433   "Timer 0 Latch Command",            // 0x04c T0LATCH
434   "Timer 1 Low Bits",                 // 0x050 T1LOW
435   "Timer 1 High Bits",                // 0x054 T1HIGH
436   "Timer 1 Go Command",               // 0x058 T1GO
437   "Timer 1 Latch Command",            // 0x05c T1LATCH
438   "IRQC Status",                      // 0x060 IRQSTC
439   "IRQC Request/clear",               // 0x064 IRQRQC
440   "IRQC Mask",                        // 0x068 IRQMSKC
441   "LCD and IIS Control Bits",         // 0x06c VIDIMUX
442   "IRQD Status",                      // 0x070 IRQSTD
443   "IRQD Request/clear",               // 0x074 IRQRQD
444   "IRQD Mask",                        // 0x078 IRQMSKD
445   "<RESERVED>",                       // 0x07c
446   "ROM Control Bank 0",               // 0x080 ROMCR0
447   "ROM Control Bank 1",               // 0x084 ROMCR1
448   "DRAM Control (IOMD)",              // 0x088 DRAMCR
449   "VRAM and Refresh Control",         // 0x08c VREFCR
450   "Flyback Line Size",                // 0x090 FSIZE
451   "Chip ID no. Low Byte",             // 0x094 ID0
452   "Chip ID no. High Byte",            // 0x098 ID1
453   "Chip Version Number",              // 0x09c VERSION
454   "Mouse X Position",                 // 0x0a0 MOUSEX
455   "Mouse Y Position",                 // 0x0a4 MOUSEY
456   "Mouse Data",                       // 0x0a8 MSEDAT
457   "Mouse Control",                    // 0x0ac MSECR
458   "<RESERVED>",                       // 0x0b0
459   "<RESERVED>",                       // 0x0b4
460   "<RESERVED>",                       // 0x0b8
461   "<RESERVED>",                       // 0x0bc
462   "DACK Timing Control",              // 0x0c0 DMATCR
463   "I/O Timing Control",               // 0x0c4 IOTCR
464   "Expansion Card Timing",            // 0x0c8 ECTCR
465   "DMA External Control",             // 0x0cc DMAEXT (IOMD) / ASTCR (ARM7500)
466   "DRAM Width Control",               // 0x0d0 DRAMWID
467   "Force CAS/RAS Lines Low",          // 0x0d4 SELFREF
468   "<RESERVED>",                       // 0x0d8
469   "<RESERVED>",                       // 0x0dc
470   "A to D IRQ Control",               // 0x0e0 ATODICR
471   "A to D IRQ Status",                // 0x0e4 ATODCC
472   "A to D IRQ Converter Control",     // 0x0e8 ATODICR
473   "A to D IRQ Counter 1",             // 0x0ec ATODCNT1
474   "A to D IRQ Counter 2",             // 0x0f0 ATODCNT2
475   "A to D IRQ Counter 3",             // 0x0f4 ATODCNT3
476   "A to D IRQ Counter 4",             // 0x0f8 ATODCNT4
477   "<RESERVED>",                       // 0x0fc
478   "I/O DMA 0 CurA",                   // 0x100 IO0CURA
479   "I/O DMA 0 EndA",                   // 0x104 IO0ENDA
480   "I/O DMA 0 CurB",                   // 0x108 IO0CURB
481   "I/O DMA 0 EndB",                   // 0x10c IO0ENDB
482   "I/O DMA 0 Control",                // 0x110 IO0CR
483   "I/O DMA 0 Status",                 // 0x114 IO0ST
484   "<RESERVED>",                       // 0x118
485   "<RESERVED>",                       // 0x11c
486   "I/O DMA 1 CurA",                   // 0x120 IO1CURA
487   "I/O DMA 1 EndA",                   // 0x124 IO1ENDA
488   "I/O DMA 1 CurB",                   // 0x128 IO1CURB
489   "I/O DMA 1 EndB",                   // 0x12c IO1ENDB
490   "I/O DMA 1 Control",                // 0x130 IO1CR
491   "I/O DMA 1 Status",                 // 0x134 IO1ST
492   "<RESERVED>",                       // 0x138
493   "<RESERVED>",                       // 0x13c
494   "I/O DMA 2 CurA",                   // 0x140 IO2CURA
495   "I/O DMA 2 EndA",                   // 0x144 IO2ENDA
496   "I/O DMA 2 CurB",                   // 0x148 IO2CURB
497   "I/O DMA 2 EndB",                   // 0x14c IO2ENDB
498   "I/O DMA 2 Control",                // 0x150 IO2CR
499   "I/O DMA 2 Status",                 // 0x154 IO2ST
500   "<RESERVED>",                       // 0x158
501   "<RESERVED>",                       // 0x15c
502   "I/O DMA 3 CurA",                   // 0x160 IO3CURA
503   "I/O DMA 3 EndA",                   // 0x164 IO3ENDA
504   "I/O DMA 3 CurB",                   // 0x168 IO3CURB
505   "I/O DMA 3 EndB",                   // 0x16c IO3ENDB
506   "I/O DMA 3 Control",                // 0x170 IO3CR
507   "I/O DMA 3 Status",                 // 0x174 IO3ST
508   "<RESERVED>",                       // 0x178
509   "<RESERVED>",                       // 0x17c
510   "Sound DMA 0 CurA",                 // 0x180 SD0CURA
511   "Sound DMA 0 EndA",                 // 0x184 SD0ENDA
512   "Sound DMA 0 CurB",                 // 0x188 SD0CURB
513   "Sound DMA 0 EndB",                 // 0x18c SD0ENDB
514   "Sound DMA 0 Control",              // 0x190 SD0CR
515   "Sound DMA 0 Status",               // 0x194 SD0ST
516   "<RESERVED>",                       // 0x198
517   "<RESERVED>",                       // 0x19c
518   "Sound DMA 1 CurA",                 // 0x1a0 SD1CURA
519   "Sound DMA 1 EndA",                 // 0x1a4 SD1ENDA
520   "Sound DMA 1 CurB",                 // 0x1a8 SD1CURB
521   "Sound DMA 1 EndB",                 // 0x1ac SD1ENDB
522   "Sound DMA 1 Control",              // 0x1b0 SD1CR
523   "Sound DMA 1 Status",               // 0x1b4 SD1ST
524   "<RESERVED>",                       // 0x1b8
525   "<RESERVED>",                       // 0x1bc
526   "Cursor DMA Current",               // 0x1c0 CURSCUR
527   "Cursor DMA Init",                  // 0x1c4 CURSINIT
528   "Duplex LCD Current B",             // 0x1c8 VIDCURB
529   "<RESERVED>",                       // 0x1cc
530   "Video DMA Current",                // 0x1d0 VIDCUR
531   "Video DMA End",                    // 0x1d4 VIDEND
532   "Video DMA Start",                  // 0x1d8 VIDSTART
533   "Video DMA Init",                   // 0x1dc VIDINIT
534   "Video DMA Control",                // 0x1e0 VIDCR
535   "<RESERVED>",                       // 0x1e4
536   "Duplex LCD Init B",                // 0x1e8 VIDINITB
537   "<RESERVED>",                       // 0x1ec
538   "DMA IRQ Status",                   // 0x1f0 DMAST
539   "DMA IRQ Request",                  // 0x1f4 DMARQ
540   "DMA IRQ Mask",                     // 0x1f8 DMAMSK
541   "<RESERVED>"                        // 0x1fc
542};
543
544#define IOMD_IOCR       0x000/4
545#define IOMD_KBDDAT     0x004/4
546#define IOMD_KBDCR      0x008/4
547
548#define IOMD_IRQSTA     0x010/4
549#define IOMD_IRQRQA     0x014/4
550#define IOMD_IRQMSKA    0x018/4
551
552#define IOMD_T0LOW      0x040/4
553#define IOMD_T0HIGH     0x044/4
554#define IOMD_T0GO       0x048/4
555#define IOMD_T0LATCH    0x04c/4
556
557#define IOMD_T1LOW      0x050/4
558#define IOMD_T1HIGH     0x054/4
559#define IOMD_T1GO       0x058/4
560#define IOMD_T1LATCH    0x05c/4
561
562#define IOMD_ID0        0x094/4
563#define IOMD_ID1        0x098/4
564#define IOMD_VERSION    0x09c/4
565
566#define IOMD_VIDCUR     0x1d0/4
567#define IOMD_VIDEND     0x1d4/4
568#define IOMD_VIDSTART   0x1d8/4
569#define IOMD_VIDINIT    0x1dc/4
570#define IOMD_VIDCR      0x1e0/4
571
572
573
574void riscpc_state::fire_iomd_timer(int timer)
575{
576   int timer_count = m_timer_counter[timer];
577   int val = timer_count / 2; // correct?
578
579   if(val==0)
580      m_IOMD_timer[timer]->adjust(attotime::never);
581   else
582      m_IOMD_timer[timer]->adjust(attotime::from_usec(val), 0, attotime::from_usec(val));
583}
584
585TIMER_CALLBACK_MEMBER(riscpc_state::IOMD_timer0_callback)
586{
587   m_IRQ_status_A|=0x20;
588   if(m_IRQ_mask_A&0x20)
589   {
590      generic_pulse_irq_line(m_maincpu, ARM7_IRQ_LINE,1);
591   }
592}
593
594TIMER_CALLBACK_MEMBER(riscpc_state::IOMD_timer1_callback)
595{
596   m_IRQ_status_A|=0x40;
597   if(m_IRQ_mask_A&0x40)
598   {
599      generic_pulse_irq_line(m_maincpu, ARM7_IRQ_LINE,1);
600   }
601}
602
603TIMER_CALLBACK_MEMBER(riscpc_state::flyback_timer_callback)
604{
605   m_IRQ_status_A|=0x08;
606   if(m_IRQ_mask_A&0x08)
607   {
608      generic_pulse_irq_line(m_maincpu, ARM7_IRQ_LINE,1);
609   }
610
611   m_flyback_timer->adjust(machine().first_screen()->time_until_pos(m_vidc20_vert_reg[VDER]));
612}
613
614void riscpc_state::viddma_transfer_start()
615{
616   address_space &mem = m_maincpu->space(AS_PROGRAM);
617   UINT32 src = m_viddma_addr_start;
618   UINT32 dst = 0;
619   UINT32 size = m_viddma_addr_end;
620   UINT32 dma_index;
621   UINT8 *vram = memregion("vram")->base();
622
623   /* TODO: this should actually be a qword transfer */
624   for(dma_index = 0;dma_index < size;dma_index++)
625   {
626      vram[dst] = mem.read_byte(src);
627
628      src++;
629      dst++;
630   }
631}
632
633READ32_MEMBER( riscpc_state::a7000_iomd_r )
634{
635//  if(offset != IOMD_KBDCR)
636//      logerror("IOMD: %s Register (%04x) read\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4);
637
638
639   switch(offset)
640   {
641      case IOMD_IOCR:
642      {
643         UINT8 flyback;
644         int vert_pos;
645
646         vert_pos = machine().first_screen()->vpos();
647         flyback = (vert_pos <= m_vidc20_vert_reg[VDSR] || vert_pos >= m_vidc20_vert_reg[VDER]) ? 0x80 : 0x00;
648
649         return m_IOMD_IO_ctrl | 0x34 | flyback;
650      }
651      case IOMD_KBDCR:    return m_IOMD_keyb_ctrl | 0x80; //IOMD Keyb status
652
653      /*
654      1--- ---- always high
655      -x-- ---- Timer 1
656      --x- ---- Timer 0
657      ---x ---- Power On Reset
658      ---- x--- Flyback
659      ---- -x-- nINT1
660      ---- --0- always low
661      ---- ---x INT2
662      */
663      case IOMD_IRQSTA:   return (m_IRQ_status_A & ~2) | 0x80;
664      case IOMD_IRQRQA:   return (m_IRQ_status_A & m_IRQ_mask_A) | 0x80;
665      case IOMD_IRQMSKA:  return m_IRQ_mask_A;
666
667      case IOMD_T0LOW:    return m_timer_out[0] & 0xff;
668      case IOMD_T0HIGH:   return (m_timer_out[0] >> 8) & 0xff;
669
670      case IOMD_T1LOW:    return m_timer_out[1] & 0xff;
671      case IOMD_T1HIGH:   return (m_timer_out[1] >> 8) & 0xff;
672
673      case IOMD_ID0:      return m_io_id & 0xff; // IOMD ID low
674      case IOMD_ID1:      return (m_io_id >> 8) & 0xff; // IOMD ID high
675      case IOMD_VERSION:  return 0;
676
677      case IOMD_VIDEND:   return m_viddma_addr_end & 0x00fffff8; //bits 31:24 undefined
678      case IOMD_VIDSTART: return m_viddma_addr_start & 0x1ffffff8; //bits 31, 30, 29 undefined
679      case IOMD_VIDCR:    return (m_viddma_status & 0xa0) | 0x50; //bit 6 = DRAM mode, bit 4 = QWORD transfer
680
681      default:    logerror("IOMD: %s Register (%04x) read\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4); break;
682   }
683
684   return 0;
685}
686
687WRITE32_MEMBER( riscpc_state::a7000_iomd_w )
688{
689//  logerror("IOMD: %s Register (%04x) write = %08x\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4,data);
690
691   switch(offset)
692   {
693      case IOMD_IOCR:     m_IOMD_IO_ctrl = data & ~0xf4; break;
694
695      case IOMD_KBDCR:
696         m_IOMD_keyb_ctrl = data & ~0xf4;
697         //keyboard_ctrl_write(data & 0x08);
698         break;
699
700      case IOMD_IRQRQA:   m_IRQ_status_A &= ~data; break;
701      case IOMD_IRQMSKA:  m_IRQ_mask_A = (data & ~2) | 0x80; break;
702
703      case IOMD_T0LOW:    m_timer_in[0] = (m_timer_in[0] & 0xff00) | (data & 0xff); break;
704      case IOMD_T0HIGH:   m_timer_in[0] = (m_timer_in[0] & 0x00ff) | ((data & 0xff) << 8); break;
705      case IOMD_T0GO:
706         m_timer_counter[0] = m_timer_in[0];
707         fire_iomd_timer(0);
708         break;
709      case IOMD_T0LATCH:
710         {
711            m_t0readinc^=1;
712            m_timer_out[0] = m_timer_counter[0];
713            if(m_t0readinc)
714            {
715               m_timer_counter[0]--;
716               if(m_timer_counter[0] < 0)
717                  m_timer_counter[0]+= m_timer_in[0];
718            }
719         }
720         break;
721
722      case IOMD_T1LOW:    m_timer_in[1] = (m_timer_in[1] & 0xff00) | (data & 0xff); break;
723      case IOMD_T1HIGH:   m_timer_in[1] = (m_timer_in[1] & 0x00ff) | ((data & 0xff) << 8); break;
724      case IOMD_T1GO:
725         m_timer_counter[1] = m_timer_in[1];
726         fire_iomd_timer(1);
727         break;
728      case IOMD_T1LATCH:
729         {
730            m_t1readinc^=1;
731            m_timer_out[1] = m_timer_counter[1];
732            if(m_t1readinc)
733            {
734               m_timer_counter[1]--;
735               if(m_timer_counter[1] < 0)
736                  m_timer_counter[1]+= m_timer_in[1];
737            }
738         }
739         break;
740
741      case IOMD_VIDEND:   m_viddma_addr_end = data & 0x00fffff8; //bits 31:24 unused
742      case IOMD_VIDSTART: m_viddma_addr_start = data & 0x1ffffff8; //bits 31, 30, 29 unused
743      case IOMD_VIDCR:
744         m_viddma_status = data & 0xa0; if(data & 0x20) { viddma_transfer_start(); }
745         break;
746
747
748      default: logerror("IOMD: %s Register (%04x) write = %08x\n",iomd_regnames[offset & (0x1ff >> 2)],offset*4,data);
749   }
750}
751
752static ADDRESS_MAP_START( a7000_mem, AS_PROGRAM, 32, riscpc_state)
753   AM_RANGE(0x00000000, 0x003fffff) AM_MIRROR(0x00800000) AM_ROM AM_REGION("user1", 0)
754//  AM_RANGE(0x01000000, 0x01ffffff) AM_NOP //expansion ROM
755//  AM_RANGE(0x02000000, 0x02ffffff) AM_RAM //VRAM
756//  I/O 03000000 - 033fffff
757//  AM_RANGE(0x03010000, 0x03011fff) //Super IO
758//  AM_RANGE(0x03012000, 0x03029fff) //FDC
759//  AM_RANGE(0x0302b000, 0x0302bfff) //Network podule
760//  AM_RANGE(0x03040000, 0x0304ffff) //podule space 0,1,2,3
761//  AM_RANGE(0x03070000, 0x0307ffff) //podule space 4,5,6,7
762   AM_RANGE(0x03200000, 0x032001ff) AM_READWRITE(a7000_iomd_r,a7000_iomd_w) //IOMD Registers //mirrored at 0x03000000-0x1ff?
763//  AM_RANGE(0x03310000, 0x03310003) //Mouse Buttons
764
765   AM_RANGE(0x03400000, 0x037fffff) AM_WRITE(a7000_vidc20_w)
766//  AM_RANGE(0x08000000, 0x08ffffff) AM_MIRROR(0x07000000) //EASI space
767   AM_RANGE(0x10000000, 0x13ffffff) AM_RAM //SIMM 0 bank 0
768   AM_RANGE(0x14000000, 0x17ffffff) AM_RAM //SIMM 0 bank 1
769//  AM_RANGE(0x18000000, 0x18ffffff) AM_MIRROR(0x03000000) AM_RAM //SIMM 1 bank 0
770//  AM_RANGE(0x1c000000, 0x1cffffff) AM_MIRROR(0x03000000) AM_RAM //SIMM 1 bank 1
771ADDRESS_MAP_END
772
773
774/* Input ports */
775static INPUT_PORTS_START( a7000 )
776INPUT_PORTS_END
777
778void riscpc_state::machine_start()
779{
780   m_IOMD_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(riscpc_state::IOMD_timer0_callback),this));
781   m_IOMD_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(riscpc_state::IOMD_timer1_callback),this));
782   m_flyback_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(riscpc_state::flyback_timer_callback),this));
783
784   m_io_id = 0xd4e7;
785}
786
787void riscpc_state::machine_reset()
788{
789   m_IOMD_IO_ctrl = 0x0b | 0x34; //bit 0,1 and 3 set high on reset plus 2,4,5 always high
790//  m_IRQ_status_A = 0x10; // set POR bit ON
791   m_IRQ_mask_A = 0x00;
792
793   m_IOMD_keyb_ctrl = 0x00;
794
795   m_IOMD_timer[0]->adjust( attotime::never);
796   m_IOMD_timer[1]->adjust( attotime::never);
797   m_flyback_timer->adjust( attotime::never);
798}
799
800static MACHINE_CONFIG_START( rpc600, riscpc_state )
801   /* Basic machine hardware */
802   MCFG_CPU_ADD( "maincpu", ARM7, XTAL_30MHz ) // ARM610
803   MCFG_CPU_PROGRAM_MAP(a7000_mem)
804
805   /* video hardware */
806   MCFG_SCREEN_ADD("screen", RASTER)
807   MCFG_SCREEN_REFRESH_RATE(60)
808   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
809   MCFG_SCREEN_SIZE(1900, 1080) //max available size
810   MCFG_SCREEN_VISIBLE_AREA(0, 1900-1, 0, 1080-1)
811   MCFG_SCREEN_UPDATE_DRIVER(riscpc_state, screen_update)
812   MCFG_PALETTE_ADD("palette", 0x200)
813MACHINE_CONFIG_END
814
815static MACHINE_CONFIG_START( rpc700, riscpc_state )
816   /* Basic machine hardware */
817   MCFG_CPU_ADD( "maincpu", ARM7, XTAL_40MHz ) // ARM710
818   MCFG_CPU_PROGRAM_MAP(a7000_mem)
819
820   /* video hardware */
821   MCFG_SCREEN_ADD("screen", RASTER)
822   MCFG_SCREEN_REFRESH_RATE(60)
823   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
824   MCFG_SCREEN_SIZE(1900, 1080) //max available size
825   MCFG_SCREEN_VISIBLE_AREA(0, 1900-1, 0, 1080-1)
826   MCFG_SCREEN_UPDATE_DRIVER(riscpc_state, screen_update)
827   MCFG_PALETTE_ADD("palette", 0x200)
828MACHINE_CONFIG_END
829
830static MACHINE_CONFIG_START( a7000, riscpc_state )
831   /* Basic machine hardware */
832   MCFG_CPU_ADD( "maincpu", ARM7, XTAL_32MHz ) // ARM7500
833   MCFG_CPU_PROGRAM_MAP(a7000_mem)
834
835   /* video hardware */
836   MCFG_SCREEN_ADD("screen", RASTER)
837   MCFG_SCREEN_REFRESH_RATE(60)
838   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
839   MCFG_SCREEN_SIZE(1900, 1080) //max available size
840   MCFG_SCREEN_VISIBLE_AREA(0, 1900-1, 0, 1080-1)
841   MCFG_SCREEN_UPDATE_DRIVER(riscpc_state, screen_update)
842   MCFG_PALETTE_ADD("palette", 0x200)
843MACHINE_CONFIG_END
844
845static MACHINE_CONFIG_DERIVED( a7000p, a7000 )
846   MCFG_CPU_MODIFY("maincpu") // ARM7500FE
847   MCFG_CPU_CLOCK(XTAL_48MHz)
848MACHINE_CONFIG_END
849
850static MACHINE_CONFIG_START( sarpc, riscpc_state )
851   /* Basic machine hardware */
852   MCFG_CPU_ADD( "maincpu", ARM7, 202000000 ) // StrongARM
853   MCFG_CPU_PROGRAM_MAP(a7000_mem)
854
855   /* video hardware */
856   MCFG_SCREEN_ADD("screen", RASTER)
857   MCFG_SCREEN_REFRESH_RATE(60)
858   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
859   MCFG_SCREEN_SIZE(1900, 1080) //max available size
860   MCFG_SCREEN_VISIBLE_AREA(0, 1900-1, 0, 1080-1)
861   MCFG_SCREEN_UPDATE_DRIVER(riscpc_state, screen_update)
862   MCFG_PALETTE_ADD("palette", 0x200)
863MACHINE_CONFIG_END
864
865static MACHINE_CONFIG_START( sarpc_j233, riscpc_state )
866   /* Basic machine hardware */
867   MCFG_CPU_ADD( "maincpu", ARM7, 233000000 ) // StrongARM
868   MCFG_CPU_PROGRAM_MAP(a7000_mem)
869
870   /* video hardware */
871   MCFG_SCREEN_ADD("screen", RASTER)
872   MCFG_SCREEN_REFRESH_RATE(60)
873   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
874   MCFG_SCREEN_SIZE(1900, 1080) //max available size
875   MCFG_SCREEN_VISIBLE_AREA(0, 1900-1, 0, 1080-1)
876   MCFG_SCREEN_UPDATE_DRIVER(riscpc_state, screen_update)
877   MCFG_PALETTE_ADD("palette", 0x200)
878MACHINE_CONFIG_END
879
880ROM_START(rpc600)
881   ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF )
882   // Version 3.50
883   ROM_SYSTEM_BIOS( 0, "350", "RiscOS 3.50" )
884   ROMX_LOAD( "0277,521-01.bin", 0x000000, 0x100000, CRC(8ba4444e) SHA1(1b31d7a6e924bef0e0056c3a00a3fed95e55b175), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
885   ROMX_LOAD( "0277,522-01.bin", 0x000002, 0x100000, CRC(2bc95c9f) SHA1(f8c6e2a1deb4fda48aac2e9fa21b9e01955331cf), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
886   ROM_REGION( 0x800000, "vram", ROMREGION_ERASE00 )
887ROM_END
888
889ROM_START(rpc700)
890   ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF )
891   // Version 3.60
892   ROM_SYSTEM_BIOS( 0, "360", "RiscOS 3.60" )
893   ROMX_LOAD( "1203,101-01.bin", 0x000000, 0x200000, CRC(2eeded56) SHA1(7217f942cdac55033b9a8eec4a89faa2dd63cd68), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
894   ROMX_LOAD( "1203,102-01.bin", 0x000002, 0x200000, CRC(6db87d21) SHA1(428403ed31682041f1e3d114ea02a688d24b7d94), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
895   ROM_REGION( 0x800000, "vram", ROMREGION_ERASE00 )
896ROM_END
897
898ROM_START(a7000)
899   ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF )
900   // Version 3.60
901   ROM_SYSTEM_BIOS( 0, "360", "RiscOS 3.60" )
902   ROMX_LOAD( "1203,101-01.bin", 0x000000, 0x200000, CRC(2eeded56) SHA1(7217f942cdac55033b9a8eec4a89faa2dd63cd68), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
903   ROMX_LOAD( "1203,102-01.bin", 0x000002, 0x200000, CRC(6db87d21) SHA1(428403ed31682041f1e3d114ea02a688d24b7d94), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
904   ROM_REGION( 0x800000, "vram", ROMREGION_ERASE00 )
905ROM_END
906
907ROM_START(a7000p)
908   ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF )
909   // Version 3.71
910   ROM_SYSTEM_BIOS( 0, "371", "RiscOS 3.71" )
911   ROMX_LOAD( "1203,261-01.bin", 0x000000, 0x200000, CRC(8e3c570a) SHA1(ffccb52fa8e165d3f64545caae1c349c604386e9), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
912   ROMX_LOAD( "1203,262-01.bin", 0x000002, 0x200000, CRC(cf4615b4) SHA1(c340f29aeda3557ebd34419fcb28559fc9b620f8), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
913   // Version 4.02
914   ROM_SYSTEM_BIOS( 1, "402", "RiscOS 4.02" )
915   ROMX_LOAD( "riscos402_1.bin", 0x000000, 0x200000, CRC(4c32f7e2) SHA1(d290e29a4de7be9eb36cbafbb2dc99b1c4ce7f72), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(2))
916   ROMX_LOAD( "riscos402_2.bin", 0x000002, 0x200000, CRC(7292b790) SHA1(67f999c1ccf5419e0a142b7e07f809e13dfed425), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(2))
917   // Version 4.39
918   ROM_SYSTEM_BIOS( 2, "439", "RiscOS 4.39" )
919   ROMX_LOAD( "riscos439_1.bin", 0x000000, 0x200000, CRC(dab94cb8) SHA1(a81fb7f1a8117f85e82764675445092d769aa9af), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(3))
920   ROMX_LOAD( "riscos439_2.bin", 0x000002, 0x200000, CRC(22e6a5d4) SHA1(b73b73c87824045130840a19ce16fa12e388c039), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(3))
921   ROM_REGION( 0x800000, "vram", ROMREGION_ERASE00 )
922ROM_END
923
924ROM_START(sarpc)
925   ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF )
926   // Version 3.70
927   ROM_SYSTEM_BIOS( 0, "370", "RiscOS 3.70" )
928   ROMX_LOAD( "1203,191-01.bin", 0x000000, 0x200000, NO_DUMP, ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
929   ROMX_LOAD( "1203,192-01.bin", 0x000002, 0x200000, NO_DUMP, ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
930ROM_END
931
932ROM_START(sarpc_j233)
933   ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF )
934   // Version 3.71
935   ROM_SYSTEM_BIOS( 0, "371", "RiscOS 3.71" )
936   ROMX_LOAD( "1203,261-01.bin", 0x000000, 0x200000, CRC(8e3c570a) SHA1(ffccb52fa8e165d3f64545caae1c349c604386e9), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
937   ROMX_LOAD( "1203,262-01.bin", 0x000002, 0x200000, CRC(cf4615b4) SHA1(c340f29aeda3557ebd34419fcb28559fc9b620f8), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1))
938ROM_END
939
940/***************************************************************************
941
942  Game driver(s)
943
944***************************************************************************/
945
946/*    YEAR  NAME        PARENT  COMPAT  MACHINE     INPUT   INIT    COMPANY FULLNAME        FLAGS */
947COMP( 1994, rpc600,     0,      0,      rpc600,     a7000, driver_device,   0,      "Acorn",  "Risc PC 600",        GAME_NOT_WORKING | GAME_NO_SOUND )
948COMP( 1994, rpc700,     rpc600, 0,      rpc700,     a7000, driver_device,   0,      "Acorn",  "Risc PC 700",        GAME_NOT_WORKING | GAME_NO_SOUND )
949COMP( 1995, a7000,      rpc600, 0,      a7000,      a7000, driver_device,   0,      "Acorn",  "Archimedes A7000",   GAME_NOT_WORKING | GAME_NO_SOUND )
950COMP( 1997, a7000p,     rpc600, 0,      a7000p,     a7000, driver_device,   0,      "Acorn",  "Archimedes A7000+",  GAME_NOT_WORKING | GAME_NO_SOUND )
951COMP( 1997, sarpc,      rpc600, 0,      sarpc,      a7000, driver_device,   0,      "Acorn",  "StrongARM Risc PC",  GAME_NOT_WORKING | GAME_NO_SOUND )
952COMP( 1997, sarpc_j233, rpc600, 0,      sarpc_j233, a7000, driver_device,   0,      "Acorn",  "J233 StrongARM Risc PC",  GAME_NOT_WORKING | GAME_NO_SOUND )
Property changes on: trunk/src/mess/drivers/riscpc.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/mess.mak
r32302r32303
910910$(MESSOBJ)/acorn.a:             \
911911   $(MESS_DRIVERS)/a310.o      \
912912   $(MESS_DRIVERS)/a6809.o     \
913   $(MESS_DRIVERS)/a7000.o     \
914913   $(MESS_DRIVERS)/acrnsys1.o  \
915914   $(MESS_DRIVERS)/atom.o      \
916915   $(MESS_VIDEO)/bbc.o         \
r32302r32303
920919   $(MESS_VIDEO)/electron.o    \
921920   $(MESS_MACHINE)/electron.o  \
922921   $(MESS_DRIVERS)/electron.o  \
922   $(MESS_DRIVERS)/riscpc.o    \
923923   $(MESS_DRIVERS)/z88.o       \
924924   $(MESS_VIDEO)/z88.o         \
925925   $(MESS_MACHINE)/upd65031.o  \
trunk/src/mess/mess.lst
r32302r32303
386386a7000     // 1995 Acorn Archimedes 7000
387387a7000p    // 1997 Acorn Archimedes 7000+
388388a6809
389rpc600
390rpc700
391sarpc
392sarpc_j233
389393
390394// ACT
391395apricot // 1983 ACT

Previous 199869 Revisions Next


© 1997-2024 The MAME Team