trunk/src/mess/drivers/necapc.c
| r18966 | r18967 | |
| 1 | | /*************************************************************************** |
| 2 | | |
| 3 | | NEC APC |
| 4 | | |
| 5 | | front ^ |
| 6 | | | |
| 7 | | card |
| 8 | | ---- |
| 9 | | 69PFCU 7220 PFCU1R 2764 |
| 10 | | 69PTS 7220 |
| 11 | | - |
| 12 | | 69PFB2 8086/8087 DFBU2J PFBU2L 2732 |
| 13 | | 69SNB RAM |
| 14 | | |
| 15 | | i/o memory map: |
| 16 | | 0x00 - 0x1f DMA |
| 17 | | 0x20 - 0x23 i8259 master |
| 18 | | 0x28 - 0x2b i8259 slave |
| 19 | | 0x2b / 0x2f / 0x61 / 0x6f pit8253 (!) |
| 20 | | 0x30 - 0x37 serial i8251, even #1 / odd #2 |
| 21 | | 0x38 - 0x3f DMA segments |
| 22 | | 0x40 - 0x43 upd7220, even chr / odd bitmap |
| 23 | | 0x48 - 0x4f keyboard |
| 24 | | 0x50 - 0x53 upd765 |
| 25 | | 0x58 rtc |
| 26 | | 0x5a - 0x5e APU |
| 27 | | 0x60 MPU (melody) |
| 28 | | 0x68 - 0x6f parallel port |
| 29 | | |
| 30 | | ***************************************************************************/ |
| 31 | | |
| 32 | | |
| 33 | | #include "emu.h" |
| 34 | | #include "cpu/i86/i86.h" |
| 35 | | #include "machine/pic8259.h" |
| 36 | | #include "machine/pit8253.h" |
| 37 | | #include "machine/8237dma.h" |
| 38 | | #include "machine/upd765.h" |
| 39 | | #include "video/upd7220.h" |
| 40 | | #include "imagedev/flopdrv.h" |
| 41 | | #include "formats/mfi_dsk.h" |
| 42 | | #include "formats/d88_dsk.h" |
| 43 | | //#include "sound/ay8910.h" |
| 44 | | |
| 45 | | class apc_state : public driver_device |
| 46 | | { |
| 47 | | public: |
| 48 | | apc_state(const machine_config &mconfig, device_type type, const char *tag) |
| 49 | | : driver_device(mconfig, type, tag), |
| 50 | | m_maincpu(*this, "maincpu"), |
| 51 | | m_hgdc1(*this, "upd7220_chr"), |
| 52 | | m_hgdc2(*this, "upd7220_btm"), |
| 53 | | m_i8259_m(*this, "pic8259_master"), |
| 54 | | m_i8259_s(*this, "pic8259_slave") |
| 55 | | { } |
| 56 | | |
| 57 | | // devices |
| 58 | | required_device<cpu_device> m_maincpu; |
| 59 | | required_device<upd7220_device> m_hgdc1; |
| 60 | | required_device<upd7220_device> m_hgdc2; |
| 61 | | required_device<pic8259_device> m_i8259_m; |
| 62 | | required_device<pic8259_device> m_i8259_s; |
| 63 | | UINT8 *m_char_rom; |
| 64 | | |
| 65 | | // screen updates |
| 66 | | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 67 | | |
| 68 | | |
| 69 | | DECLARE_READ8_MEMBER(apc_port_28_r); |
| 70 | | DECLARE_WRITE8_MEMBER(apc_port_28_w); |
| 71 | | DECLARE_WRITE8_MEMBER(apc_port_2e_w); |
| 72 | | DECLARE_READ8_MEMBER(apc_port_60_r); |
| 73 | | DECLARE_WRITE8_MEMBER(apc_port_60_w); |
| 74 | | DECLARE_READ8_MEMBER(apc_gdc_r); |
| 75 | | DECLARE_WRITE8_MEMBER(apc_gdc_w); |
| 76 | | DECLARE_READ8_MEMBER(apc_dma_r); |
| 77 | | DECLARE_WRITE8_MEMBER(apc_dma_w); |
| 78 | | |
| 79 | | DECLARE_WRITE_LINE_MEMBER(apc_master_set_int_line); |
| 80 | | DECLARE_READ8_MEMBER(get_slave_ack); |
| 81 | | DECLARE_WRITE_LINE_MEMBER(pc_dma_hrq_changed); |
| 82 | | DECLARE_WRITE_LINE_MEMBER(pc_dack0_w); |
| 83 | | DECLARE_WRITE_LINE_MEMBER(pc_dack1_w); |
| 84 | | DECLARE_WRITE_LINE_MEMBER(pc_dack2_w); |
| 85 | | DECLARE_WRITE_LINE_MEMBER(pc_dack3_w); |
| 86 | | DECLARE_READ8_MEMBER(test_r); |
| 87 | | DECLARE_WRITE8_MEMBER(test_w); |
| 88 | | DECLARE_READ8_MEMBER(pc_dma_read_byte); |
| 89 | | DECLARE_WRITE8_MEMBER(pc_dma_write_byte); |
| 90 | | |
| 91 | | DECLARE_DRIVER_INIT(apc); |
| 92 | | |
| 93 | | int m_dma_channel; |
| 94 | | UINT8 m_dma_offset[2][4]; |
| 95 | | UINT8 m_at_pages[0x10]; |
| 96 | | |
| 97 | | protected: |
| 98 | | // driver_device overrides |
| 99 | | virtual void machine_start(); |
| 100 | | virtual void machine_reset(); |
| 101 | | |
| 102 | | virtual void video_start(); |
| 103 | | virtual void palette_init(); |
| 104 | | }; |
| 105 | | |
| 106 | | void apc_state::video_start() |
| 107 | | { |
| 108 | | m_char_rom = memregion("gfx")->base(); |
| 109 | | } |
| 110 | | |
| 111 | | UINT32 apc_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| 112 | | { |
| 113 | | bitmap.fill(0, cliprect); |
| 114 | | |
| 115 | | /* graphics */ |
| 116 | | m_hgdc2->screen_update(screen, bitmap, cliprect); |
| 117 | | m_hgdc1->screen_update(screen, bitmap, cliprect); |
| 118 | | |
| 119 | | return 0; |
| 120 | | } |
| 121 | | |
| 122 | | |
| 123 | | static UPD7220_DISPLAY_PIXELS( hgdc_display_pixels ) |
| 124 | | { |
| 125 | | // ... |
| 126 | | } |
| 127 | | |
| 128 | | static UPD7220_DRAW_TEXT_LINE( hgdc_draw_text ) |
| 129 | | { |
| 130 | | |
| 131 | | } |
| 132 | | |
| 133 | | READ8_MEMBER(apc_state::apc_port_28_r) |
| 134 | | { |
| 135 | | UINT8 res; |
| 136 | | |
| 137 | | if(offset & 1) |
| 138 | | { |
| 139 | | if(offset == 3) |
| 140 | | res = pit8253_r(machine().device("pit8253"), space, 0); |
| 141 | | else |
| 142 | | { |
| 143 | | printf("Read undefined port 0x29\n"); |
| 144 | | res = 0xff; |
| 145 | | } |
| 146 | | } |
| 147 | | else |
| 148 | | { |
| 149 | | res = pic8259_r(machine().device("pic8259_slave"), space, (offset & 2) >> 1); |
| 150 | | } |
| 151 | | |
| 152 | | return res; |
| 153 | | } |
| 154 | | |
| 155 | | WRITE8_MEMBER(apc_state::apc_port_28_w) |
| 156 | | { |
| 157 | | if(offset & 1) |
| 158 | | { |
| 159 | | if(offset == 3) |
| 160 | | pit8253_w(machine().device("pit8253"), space, 0, data); |
| 161 | | else |
| 162 | | { |
| 163 | | printf("Write undefined port 0x29\n"); |
| 164 | | } |
| 165 | | } |
| 166 | | else |
| 167 | | { |
| 168 | | pic8259_w(machine().device("pic8259_slave"), space, (offset & 2) >> 1, data); |
| 169 | | } |
| 170 | | } |
| 171 | | |
| 172 | | WRITE8_MEMBER(apc_state::apc_port_2e_w) |
| 173 | | { |
| 174 | | pit8253_w(machine().device("pit8253"), space, 1, data); |
| 175 | | } |
| 176 | | |
| 177 | | |
| 178 | | READ8_MEMBER(apc_state::apc_port_60_r) |
| 179 | | { |
| 180 | | UINT8 res; |
| 181 | | |
| 182 | | if(offset & 1) |
| 183 | | { |
| 184 | | if(offset == 1) |
| 185 | | res = pit8253_r(machine().device("pit8253"), space, 2); |
| 186 | | else |
| 187 | | { |
| 188 | | printf("Read undefined port %02x\n",offset+0x60); |
| 189 | | res = 0xff; |
| 190 | | } |
| 191 | | } |
| 192 | | else |
| 193 | | { |
| 194 | | printf("Read melody port %02x\n",offset+0x60); |
| 195 | | res = 0xff; |
| 196 | | } |
| 197 | | |
| 198 | | return res; |
| 199 | | } |
| 200 | | |
| 201 | | WRITE8_MEMBER(apc_state::apc_port_60_w) |
| 202 | | { |
| 203 | | if(offset & 1) |
| 204 | | { |
| 205 | | if(offset == 1) |
| 206 | | pit8253_w(machine().device("pit8253"), space, 2, data); |
| 207 | | else if(offset == 7) |
| 208 | | pit8253_w(machine().device("pit8253"), space, 3, data); |
| 209 | | else |
| 210 | | { |
| 211 | | printf("Write undefined port %02x\n",offset+0x60); |
| 212 | | } |
| 213 | | } |
| 214 | | else |
| 215 | | { |
| 216 | | printf("Write melody port %02x\n",offset+0x60); |
| 217 | | } |
| 218 | | } |
| 219 | | |
| 220 | | READ8_MEMBER(apc_state::apc_gdc_r) |
| 221 | | { |
| 222 | | UINT8 res; |
| 223 | | |
| 224 | | if(offset & 1) |
| 225 | | res = m_hgdc2->read(space, (offset & 2) >> 1); // upd7220 bitmap port |
| 226 | | else |
| 227 | | res = m_hgdc1->read(space, (offset & 2) >> 1); // upd7220 character port |
| 228 | | |
| 229 | | return res; |
| 230 | | } |
| 231 | | |
| 232 | | WRITE8_MEMBER(apc_state::apc_gdc_w) |
| 233 | | { |
| 234 | | if(offset & 1) |
| 235 | | m_hgdc2->write(space, (offset & 2) >> 1,data); // upd7220 bitmap port |
| 236 | | else |
| 237 | | m_hgdc1->write(space, (offset & 2) >> 1,data); // upd7220 character port |
| 238 | | } |
| 239 | | |
| 240 | | |
| 241 | | READ8_MEMBER(apc_state::apc_dma_r) |
| 242 | | { |
| 243 | | return i8237_r(machine().device("8237dma"), space, offset & 0xf); |
| 244 | | } |
| 245 | | |
| 246 | | WRITE8_MEMBER(apc_state::apc_dma_w) |
| 247 | | { |
| 248 | | //printf("%08x %02x\n",m_maincpu->pc(),data); |
| 249 | | i8237_w(machine().device("8237dma"), space, offset & 0xf, data); |
| 250 | | } |
| 251 | | |
| 252 | | |
| 253 | | static ADDRESS_MAP_START( apc_map, AS_PROGRAM, 16, apc_state ) |
| 254 | | AM_RANGE(0x00000, 0x1ffff) AM_RAM |
| 255 | | // AM_RANGE(0xa0000, 0xaffff) space for an external ROM |
| 256 | | AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION("ipl", 0) |
| 257 | | ADDRESS_MAP_END |
| 258 | | |
| 259 | | static ADDRESS_MAP_START( apc_io, AS_IO, 16, apc_state ) |
| 260 | | // ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 261 | | AM_RANGE(0x00, 0x1f) AM_READWRITE8(apc_dma_r, apc_dma_w, 0x00ff) |
| 262 | | AM_RANGE(0x20, 0x23) AM_DEVREADWRITE8_LEGACY("pic8259_master", pic8259_r, pic8259_w, 0x00ff) // i8259 |
| 263 | | AM_RANGE(0x28, 0x2b) AM_READWRITE8(apc_port_28_r, apc_port_28_w, 0xffff) |
| 264 | | AM_RANGE(0x2e, 0x2f) AM_WRITE8(apc_port_2e_w, 0x00ff) |
| 265 | | // 0x2b RTC counter port 0 |
| 266 | | // 0x2f RTC counter mode 0 (w) |
| 267 | | // 0x30, 0x37 serial port 0/1 (i8251) (even/odd) |
| 268 | | // 0x38, 0x3f DMA extended address |
| 269 | | AM_RANGE(0x40, 0x43) AM_READWRITE8(apc_gdc_r, apc_gdc_w, 0xffff) |
| 270 | | // 0x46 UPD7220 reset interrupt |
| 271 | | // 0x48, 0x4f keyboard controller |
| 272 | | AM_RANGE(0x50, 0x53) AM_DEVICE8("upd765", upd765a_device, map, 0x00ff ) // upd765 |
| 273 | | // 0x5a APU data (Arithmetic Processing Unit!) |
| 274 | | // 0x5e APU status/command |
| 275 | | AM_RANGE(0x60, 0x67) AM_READWRITE8(apc_port_60_r, apc_port_60_w, 0xffff) |
| 276 | | // 0x60 Melody Processing Unit |
| 277 | | // 0x61 RTC counter port 1 |
| 278 | | // 0x67 RTC counter mode 1 (w) |
| 279 | | // AM_RANGE(0x68, 0x6f) i8255 , printer port (A: status (R) B: data (W) C: command (W)) |
| 280 | | // AM_DEVREADWRITE8("upd7220_btm", upd7220_device, read, write, 0x00ff) |
| 281 | | ADDRESS_MAP_END |
| 282 | | |
| 283 | | static INPUT_PORTS_START( apc ) |
| 284 | | /* dummy active high structure */ |
| 285 | | PORT_START("SYSA") |
| 286 | | PORT_DIPNAME( 0x01, 0x00, "SYSA" ) |
| 287 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 288 | | PORT_DIPSETTING( 0x01, DEF_STR( On ) ) |
| 289 | | PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) |
| 290 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 291 | | PORT_DIPSETTING( 0x02, DEF_STR( On ) ) |
| 292 | | PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) |
| 293 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 294 | | PORT_DIPSETTING( 0x04, DEF_STR( On ) ) |
| 295 | | PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) |
| 296 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 297 | | PORT_DIPSETTING( 0x08, DEF_STR( On ) ) |
| 298 | | PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) |
| 299 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 300 | | PORT_DIPSETTING( 0x10, DEF_STR( On ) ) |
| 301 | | PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) |
| 302 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 303 | | PORT_DIPSETTING( 0x20, DEF_STR( On ) ) |
| 304 | | PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) |
| 305 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 306 | | PORT_DIPSETTING( 0x40, DEF_STR( On ) ) |
| 307 | | PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) |
| 308 | | PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) |
| 309 | | PORT_DIPSETTING( 0x80, DEF_STR( On ) ) |
| 310 | | |
| 311 | | /* dummy active low structure */ |
| 312 | | PORT_START("DSWA") |
| 313 | | PORT_DIPNAME( 0x01, 0x01, "DSWA" ) |
| 314 | | PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) |
| 315 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 316 | | PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) |
| 317 | | PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) |
| 318 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 319 | | PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) |
| 320 | | PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) |
| 321 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 322 | | PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) |
| 323 | | PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) |
| 324 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 325 | | PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) |
| 326 | | PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) |
| 327 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 328 | | PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) |
| 329 | | PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) |
| 330 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 331 | | PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) |
| 332 | | PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) |
| 333 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 334 | | PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) |
| 335 | | PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) |
| 336 | | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 337 | | INPUT_PORTS_END |
| 338 | | |
| 339 | | |
| 340 | | void apc_state::machine_start() |
| 341 | | { |
| 342 | | } |
| 343 | | |
| 344 | | void apc_state::machine_reset() |
| 345 | | { |
| 346 | | } |
| 347 | | |
| 348 | | |
| 349 | | void apc_state::palette_init() |
| 350 | | { |
| 351 | | } |
| 352 | | |
| 353 | | static UPD7220_INTERFACE( hgdc_1_intf ) |
| 354 | | { |
| 355 | | "screen", |
| 356 | | NULL, |
| 357 | | hgdc_draw_text, |
| 358 | | DEVCB_NULL, |
| 359 | | DEVCB_NULL, |
| 360 | | DEVCB_NULL |
| 361 | | }; |
| 362 | | |
| 363 | | |
| 364 | | static UPD7220_INTERFACE( hgdc_2_intf ) |
| 365 | | { |
| 366 | | "screen", |
| 367 | | hgdc_display_pixels, |
| 368 | | NULL, |
| 369 | | DEVCB_NULL, |
| 370 | | DEVCB_NULL, |
| 371 | | DEVCB_NULL |
| 372 | | }; |
| 373 | | |
| 374 | | static const gfx_layout charset_8x16 = |
| 375 | | { |
| 376 | | 8,16, |
| 377 | | 256, |
| 378 | | 1, |
| 379 | | { 0 }, |
| 380 | | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 381 | | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, |
| 382 | | 8*16 |
| 383 | | }; |
| 384 | | |
| 385 | | |
| 386 | | static GFXDECODE_START( apc ) |
| 387 | | GFXDECODE_ENTRY( "gfx", 0x0000, charset_8x16, 0, 8 ) |
| 388 | | GFXDECODE_END |
| 389 | | |
| 390 | | |
| 391 | | static ADDRESS_MAP_START( upd7220_1_map, AS_0, 8, apc_state) |
| 392 | | AM_RANGE(0x00000, 0x3ffff) AM_RAM AM_SHARE("video_ram_1") |
| 393 | | ADDRESS_MAP_END |
| 394 | | |
| 395 | | static ADDRESS_MAP_START( upd7220_2_map, AS_0, 8, apc_state ) |
| 396 | | AM_RANGE(0x00000, 0x3ffff) AM_RAM AM_SHARE("video_ram_2") |
| 397 | | ADDRESS_MAP_END |
| 398 | | |
| 399 | | static const struct pit8253_config pit8253_config = |
| 400 | | { |
| 401 | | { |
| 402 | | { |
| 403 | | 1996800, /* heartbeat IRQ */ |
| 404 | | DEVCB_NULL, |
| 405 | | DEVCB_NULL |
| 406 | | }, { |
| 407 | | 1996800, /* Memory Refresh */ |
| 408 | | DEVCB_NULL, |
| 409 | | DEVCB_NULL |
| 410 | | }, { |
| 411 | | 1996800, /* RS-232c */ |
| 412 | | DEVCB_NULL, |
| 413 | | DEVCB_NULL |
| 414 | | } |
| 415 | | } |
| 416 | | }; |
| 417 | | /* |
| 418 | | irq assignment: |
| 419 | | |
| 420 | | 8259 master: |
| 421 | | ir0 |
| 422 | | ir1 |
| 423 | | ir2 |
| 424 | | ir3 |
| 425 | | ir4 |
| 426 | | ir5 |
| 427 | | ir6 |
| 428 | | ir7 |
| 429 | | |
| 430 | | 8259 slave: |
| 431 | | ir0 |
| 432 | | ir1 |
| 433 | | ir2 |
| 434 | | ir3 |
| 435 | | ir4 |
| 436 | | ir5 |
| 437 | | ir6 |
| 438 | | ir7 |
| 439 | | */ |
| 440 | | |
| 441 | | |
| 442 | | WRITE_LINE_MEMBER(apc_state::apc_master_set_int_line) |
| 443 | | { |
| 444 | | //printf("%02x\n",interrupt); |
| 445 | | machine().device("maincpu")->execute().set_input_line(0, state ? HOLD_LINE : CLEAR_LINE); |
| 446 | | } |
| 447 | | |
| 448 | | READ8_MEMBER(apc_state::get_slave_ack) |
| 449 | | { |
| 450 | | if (offset==7) { // IRQ = 7 |
| 451 | | return pic8259_acknowledge( machine().device( "pic8259_slave" )); |
| 452 | | } |
| 453 | | return 0x00; |
| 454 | | } |
| 455 | | |
| 456 | | static const struct pic8259_interface pic8259_master_config = |
| 457 | | { |
| 458 | | DEVCB_DRIVER_LINE_MEMBER(apc_state, apc_master_set_int_line), |
| 459 | | DEVCB_LINE_VCC, |
| 460 | | DEVCB_DRIVER_MEMBER(apc_state,get_slave_ack) |
| 461 | | }; |
| 462 | | |
| 463 | | static const struct pic8259_interface pic8259_slave_config = |
| 464 | | { |
| 465 | | DEVCB_DEVICE_LINE("pic8259_master", pic8259_ir7_w), //TODO: check me |
| 466 | | DEVCB_LINE_GND, |
| 467 | | DEVCB_NULL |
| 468 | | }; |
| 469 | | |
| 470 | | /**************************************** |
| 471 | | * |
| 472 | | * I8237 DMA interface |
| 473 | | * |
| 474 | | ****************************************/ |
| 475 | | |
| 476 | | WRITE_LINE_MEMBER(apc_state::pc_dma_hrq_changed) |
| 477 | | { |
| 478 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 479 | | |
| 480 | | /* Assert HLDA */ |
| 481 | | i8237_hlda_w( machine().device("dma8237"), state ); |
| 482 | | } |
| 483 | | |
| 484 | | |
| 485 | | READ8_MEMBER(apc_state::pc_dma_read_byte) |
| 486 | | { |
| 487 | | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) |
| 488 | | & 0xFF0000; |
| 489 | | |
| 490 | | return space.read_byte(page_offset + offset); |
| 491 | | } |
| 492 | | |
| 493 | | |
| 494 | | WRITE8_MEMBER(apc_state::pc_dma_write_byte) |
| 495 | | { |
| 496 | | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) |
| 497 | | & 0xFF0000; |
| 498 | | |
| 499 | | space.write_byte(page_offset + offset, data); |
| 500 | | } |
| 501 | | |
| 502 | | static void set_dma_channel(running_machine &machine, int channel, int state) |
| 503 | | { |
| 504 | | apc_state *drvstate = machine.driver_data<apc_state>(); |
| 505 | | if (!state) drvstate->m_dma_channel = channel; |
| 506 | | } |
| 507 | | |
| 508 | | WRITE_LINE_MEMBER(apc_state::pc_dack0_w){ /*printf("%02x 0\n",state);*/ set_dma_channel(machine(), 0, state); } |
| 509 | | WRITE_LINE_MEMBER(apc_state::pc_dack1_w){ /*printf("%02x 1\n",state);*/ set_dma_channel(machine(), 1, state); } |
| 510 | | WRITE_LINE_MEMBER(apc_state::pc_dack2_w){ /*printf("%02x 2\n",state);*/ set_dma_channel(machine(), 2, state); } |
| 511 | | WRITE_LINE_MEMBER(apc_state::pc_dack3_w){ /*printf("%02x 3\n",state);*/ set_dma_channel(machine(), 3, state); } |
| 512 | | |
| 513 | | READ8_MEMBER(apc_state::test_r) |
| 514 | | { |
| 515 | | // printf("2dd DACK R\n"); |
| 516 | | |
| 517 | | return 0xff; |
| 518 | | } |
| 519 | | |
| 520 | | WRITE8_MEMBER(apc_state::test_w) |
| 521 | | { |
| 522 | | // printf("2dd DACK W\n"); |
| 523 | | } |
| 524 | | |
| 525 | | static I8237_INTERFACE( dma8237_config ) |
| 526 | | { |
| 527 | | DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dma_hrq_changed), |
| 528 | | DEVCB_NULL, |
| 529 | | DEVCB_DRIVER_MEMBER(apc_state, pc_dma_read_byte), |
| 530 | | DEVCB_DRIVER_MEMBER(apc_state, pc_dma_write_byte), |
| 531 | | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(apc_state,test_r) }, |
| 532 | | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(apc_state,test_w) }, |
| 533 | | { DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dack0_w), DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dack1_w), DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dack2_w), DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dack3_w) } |
| 534 | | }; |
| 535 | | |
| 536 | | static const floppy_format_type apc_floppy_formats[] = { |
| 537 | | FLOPPY_D88_FORMAT, |
| 538 | | FLOPPY_MFI_FORMAT, |
| 539 | | NULL // TODO: IMD |
| 540 | | }; |
| 541 | | |
| 542 | | static SLOT_INTERFACE_START( apc_floppies ) |
| 543 | | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) // TODO: 8" |
| 544 | | SLOT_INTERFACE_END |
| 545 | | |
| 546 | | |
| 547 | | #define MAIN_CLOCK XTAL_5MHz |
| 548 | | |
| 549 | | static MACHINE_CONFIG_START( apc, apc_state ) |
| 550 | | |
| 551 | | /* basic machine hardware */ |
| 552 | | MCFG_CPU_ADD("maincpu",I8086,MAIN_CLOCK) |
| 553 | | MCFG_CPU_PROGRAM_MAP(apc_map) |
| 554 | | MCFG_CPU_IO_MAP(apc_io) |
| 555 | | |
| 556 | | MCFG_PIT8253_ADD( "pit8253", pit8253_config ) |
| 557 | | MCFG_PIC8259_ADD( "pic8259_master", pic8259_master_config ) |
| 558 | | MCFG_PIC8259_ADD( "pic8259_slave", pic8259_slave_config ) |
| 559 | | MCFG_I8237_ADD("8237dma", MAIN_CLOCK, dma8237_config) |
| 560 | | |
| 561 | | MCFG_UPD765A_ADD("upd765", true, true) |
| 562 | | MCFG_FLOPPY_DRIVE_ADD("upd765:0", apc_floppies, "525hd", 0, apc_floppy_formats) |
| 563 | | MCFG_FLOPPY_DRIVE_ADD("upd765:1", apc_floppies, "525hd", 0, apc_floppy_formats) |
| 564 | | |
| 565 | | /* video hardware */ |
| 566 | | MCFG_SCREEN_ADD("screen", RASTER) |
| 567 | | MCFG_SCREEN_REFRESH_RATE(60) |
| 568 | | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) |
| 569 | | MCFG_SCREEN_UPDATE_DRIVER(apc_state, screen_update) |
| 570 | | MCFG_SCREEN_SIZE(32*8, 32*8) |
| 571 | | MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1) |
| 572 | | |
| 573 | | MCFG_GFXDECODE(apc) |
| 574 | | |
| 575 | | MCFG_UPD7220_ADD("upd7220_chr", 5000000/2, hgdc_1_intf, upd7220_1_map) |
| 576 | | MCFG_UPD7220_ADD("upd7220_btm", 5000000/2, hgdc_2_intf, upd7220_2_map) |
| 577 | | |
| 578 | | MCFG_PALETTE_LENGTH(8) |
| 579 | | |
| 580 | | /* sound hardware */ |
| 581 | | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 582 | | // MCFG_SOUND_ADD("aysnd", AY8910, MAIN_CLOCK/4) |
| 583 | | // MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30) |
| 584 | | MACHINE_CONFIG_END |
| 585 | | |
| 586 | | |
| 587 | | /*************************************************************************** |
| 588 | | |
| 589 | | Game driver(s) |
| 590 | | |
| 591 | | ***************************************************************************/ |
| 592 | | |
| 593 | | ROM_START( apc ) |
| 594 | | ROM_REGION( 0x2000, "ipl", ROMREGION_ERASE00 ) |
| 595 | | ROM_LOAD16_BYTE( "pfbu2j.bin", 0x00000, 0x001000, CRC(86970df5) SHA1(be59c5dad3bd8afc21e9f2f1404553d4371978be) ) |
| 596 | | ROM_LOAD16_BYTE( "pfbu2l.bin", 0x00001, 0x001000, CRC(38df2e70) SHA1(a37ccaea00c2b290610d354de08b489fa897ec48) ) |
| 597 | | |
| 598 | | // ROM_REGION( 0x10000, "file", ROMREGION_ERASE00 ) |
| 599 | | // ROM_LOAD( "sioapc.o", 0, 0x10000, CRC(1) SHA1(1) ) |
| 600 | | |
| 601 | | ROM_REGION( 0x2000, "gfx", ROMREGION_ERASE00 ) |
| 602 | | ROM_LOAD( "pfcu1r.bin", 0x000000, 0x002000, BAD_DUMP CRC(683efa94) SHA1(43157984a1746b2e448f3236f571011af9a3aa73) ) |
| 603 | | ROM_END |
| 604 | | |
| 605 | | DRIVER_INIT_MEMBER(apc_state,apc) |
| 606 | | { |
| 607 | | UINT8 *ROM = memregion("ipl")->base(); |
| 608 | | |
| 609 | | /* patch DMA check */ |
| 610 | | ROM[0xff334 & 0x1fff] = 0x90; |
| 611 | | ROM[0xff335 & 0x1fff] = 0x90; |
| 612 | | ROM[0xff339 & 0x1fff] = 0x90; |
| 613 | | ROM[0xff33a & 0x1fff] = 0x90; |
| 614 | | |
| 615 | | } |
| 616 | | |
| 617 | | GAME( 198?, apc, 0, apc, apc, apc_state, apc, ROT0, "NEC", "APC", GAME_IS_SKELETON ) |
trunk/src/mess/drivers/apc.c
| r18966 | r18967 | |
| 12 | 12 | 69PFB2 8086/8087 DFBU2J PFBU2L 2732 |
| 13 | 13 | 69SNB RAM |
| 14 | 14 | |
| 15 | i/o memory map: |
| 16 | 0x00 - 0x1f DMA |
| 17 | 0x20 - 0x23 i8259 master |
| 18 | 0x28 - 0x2b i8259 slave |
| 19 | 0x2b / 0x2f / 0x61 / 0x6f pit8253 (!) |
| 20 | 0x30 - 0x37 serial i8251, even #1 / odd #2 |
| 21 | 0x38 - 0x3f DMA segments |
| 22 | 0x40 - 0x43 upd7220, even chr / odd bitmap |
| 23 | 0x48 - 0x4f keyboard |
| 24 | 0x50 - 0x53 upd765 |
| 25 | 0x58 rtc |
| 26 | 0x5a - 0x5e APU |
| 27 | 0x60 MPU (melody) |
| 28 | 0x68 - 0x6f parallel port |
| 29 | |
| 15 | 30 | ***************************************************************************/ |
| 16 | 31 | |
| 17 | 32 | |
| 18 | 33 | #include "emu.h" |
| 19 | 34 | #include "cpu/i86/i86.h" |
| 35 | #include "machine/pic8259.h" |
| 36 | #include "machine/pit8253.h" |
| 37 | #include "machine/8237dma.h" |
| 38 | #include "machine/upd765.h" |
| 20 | 39 | #include "video/upd7220.h" |
| 40 | #include "imagedev/flopdrv.h" |
| 41 | #include "formats/mfi_dsk.h" |
| 42 | #include "formats/d88_dsk.h" |
| 21 | 43 | //#include "sound/ay8910.h" |
| 22 | 44 | |
| 23 | | |
| 24 | 45 | class apc_state : public driver_device |
| 25 | 46 | { |
| 26 | 47 | public: |
| r18966 | r18967 | |
| 28 | 49 | : driver_device(mconfig, type, tag), |
| 29 | 50 | m_maincpu(*this, "maincpu"), |
| 30 | 51 | m_hgdc1(*this, "upd7220_chr"), |
| 31 | | m_hgdc2(*this, "upd7220_btm") |
| 52 | m_hgdc2(*this, "upd7220_btm"), |
| 53 | m_i8259_m(*this, "pic8259_master"), |
| 54 | m_i8259_s(*this, "pic8259_slave") |
| 32 | 55 | { } |
| 33 | 56 | |
| 34 | 57 | // devices |
| 35 | 58 | required_device<cpu_device> m_maincpu; |
| 36 | 59 | required_device<upd7220_device> m_hgdc1; |
| 37 | 60 | required_device<upd7220_device> m_hgdc2; |
| 61 | required_device<pic8259_device> m_i8259_m; |
| 62 | required_device<pic8259_device> m_i8259_s; |
| 63 | UINT8 *m_char_rom; |
| 38 | 64 | |
| 39 | 65 | // screen updates |
| 40 | 66 | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 41 | 67 | |
| 68 | |
| 69 | DECLARE_READ8_MEMBER(apc_port_28_r); |
| 70 | DECLARE_WRITE8_MEMBER(apc_port_28_w); |
| 71 | DECLARE_WRITE8_MEMBER(apc_port_2e_w); |
| 72 | DECLARE_READ8_MEMBER(apc_port_60_r); |
| 73 | DECLARE_WRITE8_MEMBER(apc_port_60_w); |
| 74 | DECLARE_READ8_MEMBER(apc_gdc_r); |
| 75 | DECLARE_WRITE8_MEMBER(apc_gdc_w); |
| 76 | DECLARE_READ8_MEMBER(apc_dma_r); |
| 77 | DECLARE_WRITE8_MEMBER(apc_dma_w); |
| 78 | |
| 79 | DECLARE_WRITE_LINE_MEMBER(apc_master_set_int_line); |
| 80 | DECLARE_READ8_MEMBER(get_slave_ack); |
| 81 | DECLARE_WRITE_LINE_MEMBER(pc_dma_hrq_changed); |
| 82 | DECLARE_WRITE_LINE_MEMBER(pc_dack0_w); |
| 83 | DECLARE_WRITE_LINE_MEMBER(pc_dack1_w); |
| 84 | DECLARE_WRITE_LINE_MEMBER(pc_dack2_w); |
| 85 | DECLARE_WRITE_LINE_MEMBER(pc_dack3_w); |
| 86 | DECLARE_READ8_MEMBER(test_r); |
| 87 | DECLARE_WRITE8_MEMBER(test_w); |
| 88 | DECLARE_READ8_MEMBER(pc_dma_read_byte); |
| 89 | DECLARE_WRITE8_MEMBER(pc_dma_write_byte); |
| 90 | |
| 91 | DECLARE_DRIVER_INIT(apc); |
| 92 | |
| 93 | int m_dma_channel; |
| 94 | UINT8 m_dma_offset[2][4]; |
| 95 | UINT8 m_at_pages[0x10]; |
| 96 | |
| 42 | 97 | protected: |
| 43 | 98 | // driver_device overrides |
| 44 | 99 | virtual void machine_start(); |
| r18966 | r18967 | |
| 50 | 105 | |
| 51 | 106 | void apc_state::video_start() |
| 52 | 107 | { |
| 53 | | |
| 108 | m_char_rom = memregion("gfx")->base(); |
| 54 | 109 | } |
| 55 | 110 | |
| 56 | 111 | UINT32 apc_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| r18966 | r18967 | |
| 72 | 127 | |
| 73 | 128 | static UPD7220_DRAW_TEXT_LINE( hgdc_draw_text ) |
| 74 | 129 | { |
| 75 | | // ... |
| 130 | |
| 76 | 131 | } |
| 77 | 132 | |
| 133 | READ8_MEMBER(apc_state::apc_port_28_r) |
| 134 | { |
| 135 | UINT8 res; |
| 136 | |
| 137 | if(offset & 1) |
| 138 | { |
| 139 | if(offset == 3) |
| 140 | res = pit8253_r(machine().device("pit8253"), space, 0); |
| 141 | else |
| 142 | { |
| 143 | printf("Read undefined port 0x29\n"); |
| 144 | res = 0xff; |
| 145 | } |
| 146 | } |
| 147 | else |
| 148 | { |
| 149 | res = pic8259_r(machine().device("pic8259_slave"), space, (offset & 2) >> 1); |
| 150 | } |
| 151 | |
| 152 | return res; |
| 153 | } |
| 154 | |
| 155 | WRITE8_MEMBER(apc_state::apc_port_28_w) |
| 156 | { |
| 157 | if(offset & 1) |
| 158 | { |
| 159 | if(offset == 3) |
| 160 | pit8253_w(machine().device("pit8253"), space, 0, data); |
| 161 | else |
| 162 | { |
| 163 | printf("Write undefined port 0x29\n"); |
| 164 | } |
| 165 | } |
| 166 | else |
| 167 | { |
| 168 | pic8259_w(machine().device("pic8259_slave"), space, (offset & 2) >> 1, data); |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | WRITE8_MEMBER(apc_state::apc_port_2e_w) |
| 173 | { |
| 174 | pit8253_w(machine().device("pit8253"), space, 1, data); |
| 175 | } |
| 176 | |
| 177 | |
| 178 | READ8_MEMBER(apc_state::apc_port_60_r) |
| 179 | { |
| 180 | UINT8 res; |
| 181 | |
| 182 | if(offset & 1) |
| 183 | { |
| 184 | if(offset == 1) |
| 185 | res = pit8253_r(machine().device("pit8253"), space, 2); |
| 186 | else |
| 187 | { |
| 188 | printf("Read undefined port %02x\n",offset+0x60); |
| 189 | res = 0xff; |
| 190 | } |
| 191 | } |
| 192 | else |
| 193 | { |
| 194 | printf("Read melody port %02x\n",offset+0x60); |
| 195 | res = 0xff; |
| 196 | } |
| 197 | |
| 198 | return res; |
| 199 | } |
| 200 | |
| 201 | WRITE8_MEMBER(apc_state::apc_port_60_w) |
| 202 | { |
| 203 | if(offset & 1) |
| 204 | { |
| 205 | if(offset == 1) |
| 206 | pit8253_w(machine().device("pit8253"), space, 2, data); |
| 207 | else if(offset == 7) |
| 208 | pit8253_w(machine().device("pit8253"), space, 3, data); |
| 209 | else |
| 210 | { |
| 211 | printf("Write undefined port %02x\n",offset+0x60); |
| 212 | } |
| 213 | } |
| 214 | else |
| 215 | { |
| 216 | printf("Write melody port %02x\n",offset+0x60); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | READ8_MEMBER(apc_state::apc_gdc_r) |
| 221 | { |
| 222 | UINT8 res; |
| 223 | |
| 224 | if(offset & 1) |
| 225 | res = m_hgdc2->read(space, (offset & 2) >> 1); // upd7220 bitmap port |
| 226 | else |
| 227 | res = m_hgdc1->read(space, (offset & 2) >> 1); // upd7220 character port |
| 228 | |
| 229 | return res; |
| 230 | } |
| 231 | |
| 232 | WRITE8_MEMBER(apc_state::apc_gdc_w) |
| 233 | { |
| 234 | if(offset & 1) |
| 235 | m_hgdc2->write(space, (offset & 2) >> 1,data); // upd7220 bitmap port |
| 236 | else |
| 237 | m_hgdc1->write(space, (offset & 2) >> 1,data); // upd7220 character port |
| 238 | } |
| 239 | |
| 240 | |
| 241 | READ8_MEMBER(apc_state::apc_dma_r) |
| 242 | { |
| 243 | return i8237_r(machine().device("8237dma"), space, offset & 0xf); |
| 244 | } |
| 245 | |
| 246 | WRITE8_MEMBER(apc_state::apc_dma_w) |
| 247 | { |
| 248 | //printf("%08x %02x\n",m_maincpu->pc(),data); |
| 249 | i8237_w(machine().device("8237dma"), space, offset & 0xf, data); |
| 250 | } |
| 251 | |
| 252 | |
| 78 | 253 | static ADDRESS_MAP_START( apc_map, AS_PROGRAM, 16, apc_state ) |
| 79 | 254 | AM_RANGE(0x00000, 0x1ffff) AM_RAM |
| 80 | | // AM_RANGE(0xa0000, 0xaffff) AM_ROM AM_REGION("file", 0) |
| 255 | // AM_RANGE(0xa0000, 0xaffff) space for an external ROM |
| 81 | 256 | AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION("ipl", 0) |
| 82 | 257 | ADDRESS_MAP_END |
| 83 | 258 | |
| 84 | 259 | static ADDRESS_MAP_START( apc_io, AS_IO, 16, apc_state ) |
| 85 | 260 | // ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 86 | | // AM_RANGE(0x00, 0x1f) i8237 |
| 87 | | // AM_RANGE(0x20, 0x23) i8259 master |
| 88 | | // AM_RANGE(0x28, 0x2b) i8259 slave |
| 261 | AM_RANGE(0x00, 0x1f) AM_READWRITE8(apc_dma_r, apc_dma_w, 0x00ff) |
| 262 | AM_RANGE(0x20, 0x23) AM_DEVREADWRITE8_LEGACY("pic8259_master", pic8259_r, pic8259_w, 0x00ff) // i8259 |
| 263 | AM_RANGE(0x28, 0x2b) AM_READWRITE8(apc_port_28_r, apc_port_28_w, 0xffff) |
| 264 | AM_RANGE(0x2e, 0x2f) AM_WRITE8(apc_port_2e_w, 0x00ff) |
| 89 | 265 | // 0x2b RTC counter port 0 |
| 90 | 266 | // 0x2f RTC counter mode 0 (w) |
| 91 | 267 | // 0x30, 0x37 serial port 0/1 (i8251) (even/odd) |
| 92 | 268 | // 0x38, 0x3f DMA extended address |
| 93 | | AM_RANGE(0x40, 0x43) AM_DEVREADWRITE8("upd7220_chr", upd7220_device, read, write, 0x00ff) // odd address UPD7220 #2! |
| 269 | AM_RANGE(0x40, 0x43) AM_READWRITE8(apc_gdc_r, apc_gdc_w, 0xffff) |
| 94 | 270 | // 0x46 UPD7220 reset interrupt |
| 95 | 271 | // 0x48, 0x4f keyboard controller |
| 96 | | // 0x50, 0x53 upd765 |
| 272 | AM_RANGE(0x50, 0x53) AM_DEVICE8("upd765", upd765a_device, map, 0x00ff ) // upd765 |
| 97 | 273 | // 0x5a APU data (Arithmetic Processing Unit!) |
| 98 | 274 | // 0x5e APU status/command |
| 275 | AM_RANGE(0x60, 0x67) AM_READWRITE8(apc_port_60_r, apc_port_60_w, 0xffff) |
| 99 | 276 | // 0x60 Melody Processing Unit |
| 100 | 277 | // 0x61 RTC counter port 1 |
| 101 | 278 | // 0x67 RTC counter mode 1 (w) |
| 102 | 279 | // AM_RANGE(0x68, 0x6f) i8255 , printer port (A: status (R) B: data (W) C: command (W)) |
| 103 | 280 | // AM_DEVREADWRITE8("upd7220_btm", upd7220_device, read, write, 0x00ff) |
| 104 | | |
| 105 | 281 | ADDRESS_MAP_END |
| 106 | 282 | |
| 107 | 283 | static INPUT_PORTS_START( apc ) |
| r18966 | r18967 | |
| 195 | 371 | DEVCB_NULL |
| 196 | 372 | }; |
| 197 | 373 | |
| 198 | | static const gfx_layout apc_chars_8x8 = |
| 374 | static const gfx_layout charset_8x16 = |
| 199 | 375 | { |
| 200 | | 8,8, |
| 201 | | RGN_FRAC(1,1), |
| 202 | | 2, |
| 203 | | { 0, 1 }, |
| 204 | | { 0, 1*2, 2*2, 3*2, 4*2, 5*2, 6*2, 7*2 }, |
| 205 | | { 0*8*2, 1*8*2, 2*8*2, 3*8*2, 4*8*2, 5*8*2, 6*8*2, 7*8*2 }, |
| 206 | | 8*8*2 |
| 376 | 8,16, |
| 377 | 256, |
| 378 | 1, |
| 379 | { 0 }, |
| 380 | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 381 | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, |
| 382 | 8*16 |
| 207 | 383 | }; |
| 208 | 384 | |
| 385 | |
| 209 | 386 | static GFXDECODE_START( apc ) |
| 210 | | GFXDECODE_ENTRY( "gfx", 0x0000, apc_chars_8x8, 0, 8 ) |
| 387 | GFXDECODE_ENTRY( "gfx", 0x0000, charset_8x16, 0, 8 ) |
| 211 | 388 | GFXDECODE_END |
| 212 | 389 | |
| 213 | 390 | |
| r18966 | r18967 | |
| 219 | 396 | AM_RANGE(0x00000, 0x3ffff) AM_RAM AM_SHARE("video_ram_2") |
| 220 | 397 | ADDRESS_MAP_END |
| 221 | 398 | |
| 399 | static const struct pit8253_config pit8253_config = |
| 400 | { |
| 401 | { |
| 402 | { |
| 403 | 1996800, /* heartbeat IRQ */ |
| 404 | DEVCB_NULL, |
| 405 | DEVCB_NULL |
| 406 | }, { |
| 407 | 1996800, /* Memory Refresh */ |
| 408 | DEVCB_NULL, |
| 409 | DEVCB_NULL |
| 410 | }, { |
| 411 | 1996800, /* RS-232c */ |
| 412 | DEVCB_NULL, |
| 413 | DEVCB_NULL |
| 414 | } |
| 415 | } |
| 416 | }; |
| 417 | /* |
| 418 | irq assignment: |
| 419 | |
| 420 | 8259 master: |
| 421 | ir0 |
| 422 | ir1 |
| 423 | ir2 |
| 424 | ir3 |
| 425 | ir4 |
| 426 | ir5 |
| 427 | ir6 |
| 428 | ir7 |
| 429 | |
| 430 | 8259 slave: |
| 431 | ir0 |
| 432 | ir1 |
| 433 | ir2 |
| 434 | ir3 |
| 435 | ir4 |
| 436 | ir5 |
| 437 | ir6 |
| 438 | ir7 |
| 439 | */ |
| 440 | |
| 441 | |
| 442 | WRITE_LINE_MEMBER(apc_state::apc_master_set_int_line) |
| 443 | { |
| 444 | //printf("%02x\n",interrupt); |
| 445 | machine().device("maincpu")->execute().set_input_line(0, state ? HOLD_LINE : CLEAR_LINE); |
| 446 | } |
| 447 | |
| 448 | READ8_MEMBER(apc_state::get_slave_ack) |
| 449 | { |
| 450 | if (offset==7) { // IRQ = 7 |
| 451 | return pic8259_acknowledge( machine().device( "pic8259_slave" )); |
| 452 | } |
| 453 | return 0x00; |
| 454 | } |
| 455 | |
| 456 | static const struct pic8259_interface pic8259_master_config = |
| 457 | { |
| 458 | DEVCB_DRIVER_LINE_MEMBER(apc_state, apc_master_set_int_line), |
| 459 | DEVCB_LINE_VCC, |
| 460 | DEVCB_DRIVER_MEMBER(apc_state,get_slave_ack) |
| 461 | }; |
| 462 | |
| 463 | static const struct pic8259_interface pic8259_slave_config = |
| 464 | { |
| 465 | DEVCB_DEVICE_LINE("pic8259_master", pic8259_ir7_w), //TODO: check me |
| 466 | DEVCB_LINE_GND, |
| 467 | DEVCB_NULL |
| 468 | }; |
| 469 | |
| 470 | /**************************************** |
| 471 | * |
| 472 | * I8237 DMA interface |
| 473 | * |
| 474 | ****************************************/ |
| 475 | |
| 476 | WRITE_LINE_MEMBER(apc_state::pc_dma_hrq_changed) |
| 477 | { |
| 478 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 479 | |
| 480 | /* Assert HLDA */ |
| 481 | i8237_hlda_w( machine().device("dma8237"), state ); |
| 482 | } |
| 483 | |
| 484 | |
| 485 | READ8_MEMBER(apc_state::pc_dma_read_byte) |
| 486 | { |
| 487 | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) |
| 488 | & 0xFF0000; |
| 489 | |
| 490 | return space.read_byte(page_offset + offset); |
| 491 | } |
| 492 | |
| 493 | |
| 494 | WRITE8_MEMBER(apc_state::pc_dma_write_byte) |
| 495 | { |
| 496 | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) |
| 497 | & 0xFF0000; |
| 498 | |
| 499 | space.write_byte(page_offset + offset, data); |
| 500 | } |
| 501 | |
| 502 | static void set_dma_channel(running_machine &machine, int channel, int state) |
| 503 | { |
| 504 | apc_state *drvstate = machine.driver_data<apc_state>(); |
| 505 | if (!state) drvstate->m_dma_channel = channel; |
| 506 | } |
| 507 | |
| 508 | WRITE_LINE_MEMBER(apc_state::pc_dack0_w){ /*printf("%02x 0\n",state);*/ set_dma_channel(machine(), 0, state); } |
| 509 | WRITE_LINE_MEMBER(apc_state::pc_dack1_w){ /*printf("%02x 1\n",state);*/ set_dma_channel(machine(), 1, state); } |
| 510 | WRITE_LINE_MEMBER(apc_state::pc_dack2_w){ /*printf("%02x 2\n",state);*/ set_dma_channel(machine(), 2, state); } |
| 511 | WRITE_LINE_MEMBER(apc_state::pc_dack3_w){ /*printf("%02x 3\n",state);*/ set_dma_channel(machine(), 3, state); } |
| 512 | |
| 513 | READ8_MEMBER(apc_state::test_r) |
| 514 | { |
| 515 | // printf("2dd DACK R\n"); |
| 516 | |
| 517 | return 0xff; |
| 518 | } |
| 519 | |
| 520 | WRITE8_MEMBER(apc_state::test_w) |
| 521 | { |
| 522 | // printf("2dd DACK W\n"); |
| 523 | } |
| 524 | |
| 525 | static I8237_INTERFACE( dma8237_config ) |
| 526 | { |
| 527 | DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dma_hrq_changed), |
| 528 | DEVCB_NULL, |
| 529 | DEVCB_DRIVER_MEMBER(apc_state, pc_dma_read_byte), |
| 530 | DEVCB_DRIVER_MEMBER(apc_state, pc_dma_write_byte), |
| 531 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(apc_state,test_r) }, |
| 532 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(apc_state,test_w) }, |
| 533 | { DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dack0_w), DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dack1_w), DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dack2_w), DEVCB_DRIVER_LINE_MEMBER(apc_state, pc_dack3_w) } |
| 534 | }; |
| 535 | |
| 536 | static const floppy_format_type apc_floppy_formats[] = { |
| 537 | FLOPPY_D88_FORMAT, |
| 538 | FLOPPY_MFI_FORMAT, |
| 539 | NULL // TODO: IMD |
| 540 | }; |
| 541 | |
| 542 | static SLOT_INTERFACE_START( apc_floppies ) |
| 543 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) // TODO: 8" |
| 544 | SLOT_INTERFACE_END |
| 545 | |
| 546 | |
| 222 | 547 | #define MAIN_CLOCK XTAL_5MHz |
| 223 | 548 | |
| 224 | 549 | static MACHINE_CONFIG_START( apc, apc_state ) |
| r18966 | r18967 | |
| 228 | 553 | MCFG_CPU_PROGRAM_MAP(apc_map) |
| 229 | 554 | MCFG_CPU_IO_MAP(apc_io) |
| 230 | 555 | |
| 556 | MCFG_PIT8253_ADD( "pit8253", pit8253_config ) |
| 557 | MCFG_PIC8259_ADD( "pic8259_master", pic8259_master_config ) |
| 558 | MCFG_PIC8259_ADD( "pic8259_slave", pic8259_slave_config ) |
| 559 | MCFG_I8237_ADD("8237dma", MAIN_CLOCK, dma8237_config) |
| 560 | |
| 561 | MCFG_UPD765A_ADD("upd765", true, true) |
| 562 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", apc_floppies, "525hd", 0, apc_floppy_formats) |
| 563 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", apc_floppies, "525hd", 0, apc_floppy_formats) |
| 564 | |
| 231 | 565 | /* video hardware */ |
| 232 | 566 | MCFG_SCREEN_ADD("screen", RASTER) |
| 233 | 567 | MCFG_SCREEN_REFRESH_RATE(60) |
| r18966 | r18967 | |
| 265 | 599 | // ROM_LOAD( "sioapc.o", 0, 0x10000, CRC(1) SHA1(1) ) |
| 266 | 600 | |
| 267 | 601 | ROM_REGION( 0x2000, "gfx", ROMREGION_ERASE00 ) |
| 268 | | ROM_LOAD( "pfcu1r.bin", 0x000000, 0x002000, CRC(683efa94) SHA1(43157984a1746b2e448f3236f571011af9a3aa73) ) |
| 602 | ROM_LOAD( "pfcu1r.bin", 0x000000, 0x002000, BAD_DUMP CRC(683efa94) SHA1(43157984a1746b2e448f3236f571011af9a3aa73) ) |
| 269 | 603 | ROM_END |
| 270 | 604 | |
| 271 | | GAME( 198?, apc, 0, apc, apc, driver_device, 0, ROT0, "NEC", "APC", GAME_IS_SKELETON ) |
| 605 | DRIVER_INIT_MEMBER(apc_state,apc) |
| 606 | { |
| 607 | UINT8 *ROM = memregion("ipl")->base(); |
| 608 | |
| 609 | /* patch DMA check */ |
| 610 | ROM[0xff334 & 0x1fff] = 0x90; |
| 611 | ROM[0xff335 & 0x1fff] = 0x90; |
| 612 | ROM[0xff339 & 0x1fff] = 0x90; |
| 613 | ROM[0xff33a & 0x1fff] = 0x90; |
| 614 | |
| 615 | } |
| 616 | |
| 617 | GAME( 198?, apc, 0, apc, apc, apc_state, apc, ROT0, "NEC", "APC", GAME_IS_SKELETON ) |