trunk/src/mess/drivers/a7000.c
| r32302 | r32303 | |
| 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 | | |
| 24 | | class a7000_state : public driver_device |
| 25 | | { |
| 26 | | public: |
| 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 | | |
| 78 | | static 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 |
| 99 | | static 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 |
| 130 | | static 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 | | |
| 160 | | void 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 | | |
| 198 | | WRITE32_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 | | |
| 275 | | UINT32 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 */ |
| 412 | | static 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 | | |
| 574 | | void 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 | | |
| 585 | | TIMER_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 | | |
| 594 | | TIMER_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 | | |
| 603 | | TIMER_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 | | |
| 614 | | void 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 | | |
| 633 | | READ32_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 | | |
| 687 | | WRITE32_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 | | |
| 752 | | static 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 |
| 771 | | ADDRESS_MAP_END |
| 772 | | |
| 773 | | |
| 774 | | /* Input ports */ |
| 775 | | static INPUT_PORTS_START( a7000 ) |
| 776 | | INPUT_PORTS_END |
| 777 | | |
| 778 | | void 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 | | |
| 787 | | void 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 | | |
| 800 | | static 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) |
| 813 | | MACHINE_CONFIG_END |
| 814 | | |
| 815 | | static MACHINE_CONFIG_DERIVED( a7000p, a7000 ) |
| 816 | | MCFG_CPU_MODIFY("maincpu") |
| 817 | | MCFG_CPU_CLOCK(XTAL_48MHz) |
| 818 | | MACHINE_CONFIG_END |
| 819 | | |
| 820 | | ROM_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 ) |
| 827 | | ROM_END |
| 828 | | |
| 829 | | ROM_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 ) |
| 844 | | ROM_END |
| 845 | | |
| 846 | | /*************************************************************************** |
| 847 | | |
| 848 | | Game driver(s) |
| 849 | | |
| 850 | | ***************************************************************************/ |
| 851 | | |
| 852 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 853 | | COMP( 1995, a7000, 0, 0, a7000, a7000, driver_device, 0, "Acorn", "Archimedes A7000", GAME_NOT_WORKING | GAME_NO_SOUND ) |
| 854 | | COMP( 1997, a7000p, a7000, 0, a7000p, a7000, driver_device, 0, "Acorn", "Archimedes A7000+", GAME_NOT_WORKING | GAME_NO_SOUND ) |
trunk/src/mess/drivers/riscpc.c
| r0 | r32303 | |
| 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 | |
| 24 | class riscpc_state : public driver_device |
| 25 | { |
| 26 | public: |
| 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 | |
| 78 | static 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 |
| 99 | static 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 |
| 130 | static 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 | |
| 160 | void 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 | |
| 198 | WRITE32_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 | |
| 275 | UINT32 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 */ |
| 412 | static 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 | |
| 574 | void 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 | |
| 585 | TIMER_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 | |
| 594 | TIMER_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 | |
| 603 | TIMER_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 | |
| 614 | void 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 | |
| 633 | READ32_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 | |
| 687 | WRITE32_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 | |
| 752 | static 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 |
| 771 | ADDRESS_MAP_END |
| 772 | |
| 773 | |
| 774 | /* Input ports */ |
| 775 | static INPUT_PORTS_START( a7000 ) |
| 776 | INPUT_PORTS_END |
| 777 | |
| 778 | void 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 | |
| 787 | void 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 | |
| 800 | static 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) |
| 813 | MACHINE_CONFIG_END |
| 814 | |
| 815 | static 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) |
| 828 | MACHINE_CONFIG_END |
| 829 | |
| 830 | static 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) |
| 843 | MACHINE_CONFIG_END |
| 844 | |
| 845 | static MACHINE_CONFIG_DERIVED( a7000p, a7000 ) |
| 846 | MCFG_CPU_MODIFY("maincpu") // ARM7500FE |
| 847 | MCFG_CPU_CLOCK(XTAL_48MHz) |
| 848 | MACHINE_CONFIG_END |
| 849 | |
| 850 | static 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) |
| 863 | MACHINE_CONFIG_END |
| 864 | |
| 865 | static 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) |
| 878 | MACHINE_CONFIG_END |
| 879 | |
| 880 | ROM_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 ) |
| 887 | ROM_END |
| 888 | |
| 889 | ROM_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 ) |
| 896 | ROM_END |
| 897 | |
| 898 | ROM_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 ) |
| 905 | ROM_END |
| 906 | |
| 907 | ROM_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 ) |
| 922 | ROM_END |
| 923 | |
| 924 | ROM_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)) |
| 930 | ROM_END |
| 931 | |
| 932 | ROM_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)) |
| 938 | ROM_END |
| 939 | |
| 940 | /*************************************************************************** |
| 941 | |
| 942 | Game driver(s) |
| 943 | |
| 944 | ***************************************************************************/ |
| 945 | |
| 946 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 947 | COMP( 1994, rpc600, 0, 0, rpc600, a7000, driver_device, 0, "Acorn", "Risc PC 600", GAME_NOT_WORKING | GAME_NO_SOUND ) |
| 948 | COMP( 1994, rpc700, rpc600, 0, rpc700, a7000, driver_device, 0, "Acorn", "Risc PC 700", GAME_NOT_WORKING | GAME_NO_SOUND ) |
| 949 | COMP( 1995, a7000, rpc600, 0, a7000, a7000, driver_device, 0, "Acorn", "Archimedes A7000", GAME_NOT_WORKING | GAME_NO_SOUND ) |
| 950 | COMP( 1997, a7000p, rpc600, 0, a7000p, a7000, driver_device, 0, "Acorn", "Archimedes A7000+", GAME_NOT_WORKING | GAME_NO_SOUND ) |
| 951 | COMP( 1997, sarpc, rpc600, 0, sarpc, a7000, driver_device, 0, "Acorn", "StrongARM Risc PC", GAME_NOT_WORKING | GAME_NO_SOUND ) |
| 952 | COMP( 1997, sarpc_j233, rpc600, 0, sarpc_j233, a7000, driver_device, 0, "Acorn", "J233 StrongARM Risc PC", GAME_NOT_WORKING | GAME_NO_SOUND ) |