src/mess/drivers/mikromik.c
| r13330 | r13331 | |
| 52 | 52 | |
| 53 | 53 | #include "includes/mikromik.h" |
| 54 | 54 | |
| 55 | | /* Read/Write Handlers */ |
| 56 | 55 | |
| 57 | | WRITE8_MEMBER( mm1_state::ls259_w ) |
| 56 | |
| 57 | //************************************************************************** |
| 58 | // MACROS / CONSTANTS |
| 59 | //************************************************************************** |
| 60 | |
| 61 | #define LOG 0 |
| 62 | |
| 63 | #define MMU_IOEN_MEMEN 0x01 |
| 64 | #define MMU_RAMEN 0x02 |
| 65 | #define MMU_CE4 0x08 |
| 66 | #define MMU_CE0 0x10 |
| 67 | #define MMU_CE1 0x20 |
| 68 | #define MMU_CE2 0x40 |
| 69 | #define MMU_CE3 0x80 |
| 70 | |
| 71 | |
| 72 | |
| 73 | //************************************************************************** |
| 74 | // MEMORY MANAGEMENT UNIT |
| 75 | //************************************************************************** |
| 76 | |
| 77 | //------------------------------------------------- |
| 78 | // mmu_r - |
| 79 | //------------------------------------------------- |
| 80 | |
| 81 | READ8_MEMBER( mm1_state::mmu_r ) |
| 58 | 82 | { |
| 59 | | address_space *program = m_maincpu->memory().space(AS_PROGRAM); |
| 60 | | int d = BIT(data, 0); |
| 83 | UINT8 data = 0; |
| 84 | UINT8 mmu = m_mmu_rom[(m_a8 << 8) | (offset >> 8)]; |
| 85 | |
| 86 | if (mmu & MMU_IOEN_MEMEN) |
| 87 | { |
| 88 | switch ((offset >> 4) & 0x07) |
| 89 | { |
| 90 | case 0: |
| 91 | data = i8237_r(m_dmac, offset & 0x0f); |
| 92 | break; |
| 93 | |
| 94 | case 1: |
| 95 | data = m_mpsc->cd_ba_r(space, offset & 0x03); |
| 96 | break; |
| 97 | |
| 98 | case 2: |
| 99 | data = i8275_r(m_crtc, offset & 0x01); |
| 100 | break; |
| 101 | |
| 102 | case 3: |
| 103 | data = pit8253_r(m_pit, offset & 0x03); |
| 104 | break; |
| 105 | |
| 106 | case 4: |
| 107 | data = m_iop->data_r(space, 0); |
| 108 | break; |
| 109 | |
| 110 | case 5: |
| 111 | if (BIT(offset, 0)) |
| 112 | { |
| 113 | data = upd765_data_r(m_fdc, 0); |
| 114 | } |
| 115 | else |
| 116 | { |
| 117 | data = upd765_status_r(m_fdc, 0); |
| 118 | } |
| 119 | break; |
| 120 | |
| 121 | case 7: |
| 122 | data = m_hgdc->read(space, offset & 0x01); |
| 123 | break; |
| 124 | } |
| 125 | } |
| 126 | else |
| 127 | { |
| 128 | if (mmu & MMU_RAMEN) |
| 129 | { |
| 130 | data = ram_get_ptr(m_ram)[offset]; |
| 131 | } |
| 132 | else if (!(mmu & MMU_CE0)) |
| 133 | { |
| 134 | data = machine().region(I8085A_TAG)->base()[offset & 0x1fff]; |
| 135 | } |
| 136 | else if (!(mmu & MMU_CE1)) |
| 137 | { |
| 138 | data = machine().region(I8085A_TAG)->base()[0x2000 + (offset & 0x1fff)]; |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | return data; |
| 143 | } |
| 61 | 144 | |
| 62 | | switch (offset) |
| 145 | |
| 146 | |
| 147 | //------------------------------------------------- |
| 148 | // mmu_w - |
| 149 | //------------------------------------------------- |
| 150 | |
| 151 | WRITE8_MEMBER( mm1_state::mmu_w ) |
| 152 | { |
| 153 | UINT8 mmu = m_mmu_rom[(m_a8 << 8) | (offset >> 8)]; |
| 154 | |
| 155 | if (mmu & MMU_IOEN_MEMEN) |
| 63 | 156 | { |
| 64 | | case 0: /* IC24 A8 */ |
| 65 | | //logerror("IC24 A8 %u\n", d); |
| 66 | | memory_set_bank(machine(), "bank1", d); |
| 67 | | |
| 68 | | if (d) |
| 157 | switch ((offset >> 4) & 0x07) |
| 69 | 158 | { |
| 70 | | program->install_readwrite_bank(0x0000, 0x0fff, "bank1"); |
| 159 | case 0: |
| 160 | i8237_w(m_dmac, offset & 0x0f, data); |
| 161 | break; |
| 162 | |
| 163 | case 1: |
| 164 | m_mpsc->cd_ba_w(space, offset & 0x03, data); |
| 165 | break; |
| 166 | |
| 167 | case 2: |
| 168 | i8275_w(m_crtc, offset & 0x01, data); |
| 169 | break; |
| 170 | |
| 171 | case 3: |
| 172 | pit8253_w(m_pit, offset & 0x03, data); |
| 173 | break; |
| 174 | |
| 175 | case 4: |
| 176 | m_iop->data_w(space, 0, data); |
| 177 | break; |
| 178 | |
| 179 | case 5: |
| 180 | if (BIT(offset, 0)) |
| 181 | { |
| 182 | upd765_data_w(m_fdc, 0, data); |
| 183 | } |
| 184 | break; |
| 185 | |
| 186 | case 6: |
| 187 | ls259_w(space, offset & 0x07, data); |
| 188 | break; |
| 189 | |
| 190 | case 7: |
| 191 | m_hgdc->write(space, offset & 0x01, data); |
| 192 | break; |
| 71 | 193 | } |
| 72 | | else |
| 194 | } |
| 195 | else |
| 196 | { |
| 197 | if (mmu & MMU_RAMEN) |
| 73 | 198 | { |
| 74 | | program->install_read_bank(0x0000, 0x0fff, "bank1"); |
| 75 | | program->unmap_write(0x0000, 0x0fff); |
| 199 | ram_get_ptr(m_ram)[offset] = data; |
| 76 | 200 | } |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | |
| 205 | //------------------------------------------------- |
| 206 | // ls259_w - |
| 207 | //------------------------------------------------- |
| 208 | |
| 209 | WRITE8_MEMBER( mm1_state::ls259_w ) |
| 210 | { |
| 211 | int d = BIT(data, 0); |
| 212 | |
| 213 | switch (offset) |
| 214 | { |
| 215 | case 0: // IC24 A8 |
| 216 | if (LOG) logerror("IC24 A8 %u\n", d); |
| 217 | m_a8 = d; |
| 77 | 218 | break; |
| 78 | 219 | |
| 79 | | case 1: /* RECALL */ |
| 80 | | //logerror("RECALL %u\n", d); |
| 220 | case 1: // RECALL |
| 221 | if (LOG) logerror("RECALL %u\n", d); |
| 81 | 222 | m_recall = d; |
| 82 | 223 | upd765_reset_w(m_fdc, d); |
| 83 | 224 | break; |
| 84 | 225 | |
| 85 | | case 2: /* _RV28/RX21 */ |
| 226 | case 2: // _RV28/RX21 |
| 86 | 227 | m_rx21 = d; |
| 87 | 228 | break; |
| 88 | 229 | |
| 89 | | case 3: /* _TX21 */ |
| 230 | case 3: // _TX21 |
| 90 | 231 | m_tx21 = d; |
| 91 | 232 | break; |
| 92 | 233 | |
| 93 | | case 4: /* _RCL */ |
| 234 | case 4: // _RCL |
| 94 | 235 | m_rcl = d; |
| 95 | 236 | break; |
| 96 | 237 | |
| 97 | | case 5: /* _INTC */ |
| 238 | case 5: // _INTC |
| 98 | 239 | m_intc = d; |
| 99 | 240 | break; |
| 100 | 241 | |
| 101 | | case 6: /* LLEN */ |
| 102 | | //logerror("LLEN %u\n", d); |
| 242 | case 6: // LLEN |
| 243 | if (LOG) logerror("LLEN %u\n", d); |
| 103 | 244 | m_llen = d; |
| 104 | 245 | break; |
| 105 | 246 | |
| 106 | | case 7: /* MOTOR ON */ |
| 107 | | //logerror("MOTOR %u\n", d); |
| 247 | case 7: // MOTOR ON |
| 248 | if (LOG) logerror("MOTOR %u\n", d); |
| 108 | 249 | floppy_mon_w(m_floppy0, !d); |
| 109 | 250 | floppy_mon_w(m_floppy1, !d); |
| 110 | 251 | floppy_drive_set_ready_state(m_floppy0, d, 1); |
| r13330 | r13331 | |
| 115 | 256 | } |
| 116 | 257 | } |
| 117 | 258 | |
| 118 | | /* Memory Maps */ |
| 119 | 259 | |
| 260 | |
| 261 | //************************************************************************** |
| 262 | // KEYBOARD |
| 263 | //************************************************************************** |
| 264 | |
| 265 | //------------------------------------------------- |
| 266 | // scan_keyboard - |
| 267 | //------------------------------------------------- |
| 268 | |
| 269 | void mm1_state::scan_keyboard() |
| 270 | { |
| 271 | static const char *const keynames[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7", "ROW8", "ROW9" }; |
| 272 | |
| 273 | UINT8 data = input_port_read(machine(), keynames[m_drive]); |
| 274 | UINT8 special = input_port_read(machine(), "SPECIAL"); |
| 275 | int ctrl = BIT(special, 0); |
| 276 | int shift = BIT(special, 2) & BIT(special, 1); |
| 277 | UINT8 keydata = 0xff; |
| 278 | |
| 279 | if (!BIT(data, m_sense)) |
| 280 | { |
| 281 | // get key data from PROM |
| 282 | keydata = m_key_rom[(ctrl << 8) | (shift << 7) | (m_drive << 3) | (m_sense)]; |
| 283 | } |
| 284 | |
| 285 | if (m_keydata != keydata) |
| 286 | { |
| 287 | // latch key data |
| 288 | m_keydata = keydata; |
| 289 | |
| 290 | if (keydata != 0xff) |
| 291 | { |
| 292 | // strobe in key data |
| 293 | m_iop->stb_w(1); |
| 294 | m_iop->stb_w(0); |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | if (keydata == 0xff) |
| 299 | { |
| 300 | // increase scan counters |
| 301 | m_sense++; |
| 302 | |
| 303 | if (m_sense == 8) |
| 304 | { |
| 305 | m_sense = 0; |
| 306 | m_drive++; |
| 307 | |
| 308 | if (m_drive == 10) |
| 309 | { |
| 310 | m_drive = 0; |
| 311 | } |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | } |
| 316 | |
| 317 | |
| 318 | //------------------------------------------------- |
| 319 | // TIMER_DEVICE_CALLBACK( kbclk_tick ) |
| 320 | //------------------------------------------------- |
| 321 | |
| 322 | static TIMER_DEVICE_CALLBACK( kbclk_tick ) |
| 323 | { |
| 324 | mm1_state *state = timer.machine().driver_data<mm1_state>(); |
| 325 | |
| 326 | state->scan_keyboard(); |
| 327 | } |
| 328 | |
| 329 | |
| 330 | |
| 331 | //************************************************************************** |
| 332 | // ADDRESS MAPS |
| 333 | //************************************************************************** |
| 334 | |
| 335 | //------------------------------------------------- |
| 336 | // ADDRESS_MAP( mm1_map ) |
| 337 | //------------------------------------------------- |
| 338 | |
| 120 | 339 | static ADDRESS_MAP_START( mm1_map, AS_PROGRAM, 8, mm1_state ) |
| 121 | | AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("bank1") |
| 122 | | AM_RANGE(0x1000, 0xfeff) AM_RAM |
| 123 | | AM_RANGE(0xff00, 0xff0f) AM_MIRROR(0x80) AM_DEVREADWRITE_LEGACY(I8237_TAG, i8237_r, i8237_w) |
| 124 | | AM_RANGE(0xff10, 0xff13) AM_MIRROR(0x8c) AM_DEVREADWRITE(UPD7201_TAG, upd7201_device, cd_ba_r, cd_ba_w) |
| 125 | | AM_RANGE(0xff20, 0xff21) AM_MIRROR(0x8e) AM_DEVREADWRITE_LEGACY(I8275_TAG, i8275_r, i8275_w) |
| 126 | | AM_RANGE(0xff30, 0xff33) AM_MIRROR(0x8c) AM_DEVREADWRITE_LEGACY(I8253_TAG, pit8253_r, pit8253_w) |
| 127 | | AM_RANGE(0xff40, 0xff40) AM_MIRROR(0x8f) AM_DEVREADWRITE(I8212_TAG, i8212_device, data_r, data_w) |
| 128 | | AM_RANGE(0xff50, 0xff50) AM_MIRROR(0x8e) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r) |
| 129 | | AM_RANGE(0xff51, 0xff51) AM_MIRROR(0x8e) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w) |
| 130 | | AM_RANGE(0xff60, 0xff67) AM_MIRROR(0x88) AM_WRITE(ls259_w) |
| 340 | AM_RANGE(0x0000, 0xffff) AM_READWRITE(mmu_r, mmu_w) |
| 131 | 341 | ADDRESS_MAP_END |
| 132 | 342 | |
| 133 | | static ADDRESS_MAP_START( mm1m6_map, AS_PROGRAM, 8, mm1_state ) |
| 134 | | AM_IMPORT_FROM(mm1_map) |
| 135 | | AM_RANGE(0xff70, 0xff71) AM_MIRROR(0x8e) AM_DEVREADWRITE(UPD7220_TAG, upd7220_device, read, write) |
| 136 | | ADDRESS_MAP_END |
| 137 | 343 | |
| 138 | | static ADDRESS_MAP_START( mm1_upd7220_map, AS_0, 8, mm1_state ) |
| 139 | | AM_RANGE(0x00000, 0x3ffff) AM_DEVREADWRITE(UPD7220_TAG, upd7220_device, vram_r, vram_w) |
| 140 | | ADDRESS_MAP_END |
| 141 | 344 | |
| 142 | | /* Input Ports */ |
| 345 | //************************************************************************** |
| 346 | // INPUT PORTS |
| 347 | //************************************************************************** |
| 143 | 348 | |
| 349 | //------------------------------------------------- |
| 350 | // INPUT_PORTS( mm1 ) |
| 351 | //------------------------------------------------- |
| 352 | |
| 144 | 353 | static INPUT_PORTS_START( mm1 ) |
| 145 | 354 | PORT_START("ROW0") |
| 146 | 355 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') |
| r13330 | r13331 | |
| 253 | 462 | PORT_CONFSETTING( 0x01, "160/320 KB" ) |
| 254 | 463 | INPUT_PORTS_END |
| 255 | 464 | |
| 256 | | /* Video */ |
| 257 | 465 | |
| 258 | | static PALETTE_INIT( mm1 ) |
| 259 | | { |
| 260 | | palette_set_color(machine, 0, RGB_BLACK); /* black */ |
| 261 | | palette_set_color_rgb(machine, 1, 0x00, 0xc0, 0x00); /* green */ |
| 262 | | palette_set_color_rgb(machine, 2, 0x00, 0xff, 0x00); /* bright green */ |
| 263 | | } |
| 264 | 466 | |
| 265 | | static I8275_DISPLAY_PIXELS( crtc_display_pixels ) |
| 266 | | { |
| 267 | | mm1_state *state = device->machine().driver_data<mm1_state>(); |
| 467 | //************************************************************************** |
| 468 | // DEVICE CONFIGURATION |
| 469 | //************************************************************************** |
| 268 | 470 | |
| 269 | | UINT8 romdata = state->m_char_rom[(charcode << 4) | linecount]; |
| 471 | //------------------------------------------------- |
| 472 | // I8212_INTERFACE( iop_intf ) |
| 473 | //------------------------------------------------- |
| 270 | 474 | |
| 271 | | int d0 = BIT(romdata, 0); |
| 272 | | int d7 = BIT(romdata, 7); |
| 273 | | int gpa0 = BIT(gpa, 0); |
| 274 | | int llen = state->m_llen; |
| 275 | | int i; |
| 276 | | |
| 277 | | UINT8 data = (romdata << 1) | (d7 & d0); |
| 278 | | |
| 279 | | for (i = 0; i < 8; i++) |
| 280 | | { |
| 281 | | int qh = BIT(data, i); |
| 282 | | int video_in = ((((d7 & llen) | !vsp) & !gpa0) & qh) | lten; |
| 283 | | int compl_in = rvv; |
| 284 | | int hlt_in = hlgt; |
| 285 | | |
| 286 | | int color = hlt_in ? 2 : (video_in ^ compl_in); |
| 287 | | |
| 288 | | *BITMAP_ADDR16(device->machine().generic.tmpbitmap, y, x + i) = color; |
| 289 | | } |
| 290 | | } |
| 291 | | |
| 292 | | static const i8275_interface crtc_intf = |
| 293 | | { |
| 294 | | SCREEN_TAG, |
| 295 | | 8, |
| 296 | | 0, |
| 297 | | DEVCB_DEVICE_LINE(I8237_TAG, i8237_dreq0_w), |
| 298 | | DEVCB_NULL, |
| 299 | | crtc_display_pixels |
| 300 | | }; |
| 301 | | |
| 302 | | /* TODO */ |
| 303 | | static UPD7220_DISPLAY_PIXELS( hgdc_display_pixels ) |
| 304 | | { |
| 305 | | int i; |
| 306 | | |
| 307 | | for (i = 0; i < 8; i++) |
| 308 | | { |
| 309 | | if (BIT(data, i)) *BITMAP_ADDR16(bitmap, y, x + i) = 1; |
| 310 | | } |
| 311 | | } |
| 312 | | |
| 313 | | static UPD7220_INTERFACE( hgdc_intf ) |
| 314 | | { |
| 315 | | SCREEN_TAG, |
| 316 | | hgdc_display_pixels, |
| 317 | | NULL, |
| 318 | | DEVCB_NULL, |
| 319 | | DEVCB_NULL, |
| 320 | | DEVCB_NULL |
| 321 | | }; |
| 322 | | |
| 323 | | void mm1_state::video_start() |
| 324 | | { |
| 325 | | // find memory regions |
| 326 | | m_char_rom = machine().region("chargen")->base(); |
| 327 | | |
| 328 | | VIDEO_START_NAME(generic_bitmapped)(machine()); |
| 329 | | } |
| 330 | | |
| 331 | | bool mm1_state::screen_update(screen_device &screen, bitmap_t &bitmap, const rectangle &cliprect) |
| 332 | | { |
| 333 | | /* text */ |
| 334 | | i8275_update(m_crtc, &bitmap, &cliprect); |
| 335 | | copybitmap(&bitmap, screen.machine().generic.tmpbitmap, 0, 0, 0, 0, &cliprect); |
| 336 | | |
| 337 | | /* graphics */ |
| 338 | | m_hgdc->update_screen(&bitmap, &cliprect); |
| 339 | | |
| 340 | | return 0; |
| 341 | | } |
| 342 | | |
| 343 | | static const gfx_layout tiles8x16_layout = |
| 344 | | { |
| 345 | | 8, 16, |
| 346 | | RGN_FRAC(1,1), |
| 347 | | 1, |
| 348 | | { 0 }, |
| 349 | | { 7, 6, 5, 4, 3, 2, 1, 0 }, |
| 350 | | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, |
| 351 | | 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, |
| 352 | | 8*16 |
| 353 | | }; |
| 354 | | |
| 355 | | static GFXDECODE_START( mm1 ) |
| 356 | | GFXDECODE_ENTRY( "chargen", 0, tiles8x16_layout, 0, 0x100 ) |
| 357 | | GFXDECODE_END |
| 358 | | |
| 359 | | /* 8212 Interface */ |
| 360 | | |
| 361 | 475 | READ8_MEMBER( mm1_state::kb_r ) |
| 362 | 476 | { |
| 363 | 477 | return m_keydata; |
| 364 | 478 | } |
| 365 | 479 | |
| 366 | | static I8212_INTERFACE( mm1_i8212_intf ) |
| 480 | static I8212_INTERFACE( iop_intf ) |
| 367 | 481 | { |
| 368 | 482 | DEVCB_CPU_INPUT_LINE(I8085A_TAG, I8085_RST65_LINE), |
| 369 | 483 | DEVCB_DRIVER_MEMBER(mm1_state, kb_r), |
| 370 | 484 | DEVCB_NULL |
| 371 | 485 | }; |
| 372 | 486 | |
| 373 | | /* 8237 Interface */ |
| 374 | 487 | |
| 488 | //------------------------------------------------- |
| 489 | // I8237_INTERFACE( dmac_intf ) |
| 490 | //------------------------------------------------- |
| 491 | |
| 375 | 492 | WRITE_LINE_MEMBER( mm1_state::dma_hrq_changed ) |
| 376 | 493 | { |
| 377 | 494 | device_set_input_line(m_maincpu, INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 378 | 495 | |
| 379 | | /* Assert HLDA */ |
| 496 | // Assert HLDA |
| 380 | 497 | i8237_hlda_w(m_dmac, state); |
| 381 | 498 | } |
| 382 | 499 | |
| 383 | 500 | READ8_MEMBER( mm1_state::mpsc_dack_r ) |
| 384 | 501 | { |
| 385 | | /* clear data request */ |
| 502 | // clear data request |
| 386 | 503 | i8237_dreq2_w(m_dmac, CLEAR_LINE); |
| 387 | 504 | |
| 388 | 505 | return m_mpsc->dtra_r(); |
| r13330 | r13331 | |
| 392 | 509 | { |
| 393 | 510 | m_mpsc->hai_w(data); |
| 394 | 511 | |
| 395 | | /* clear data request */ |
| 512 | // clear data request |
| 396 | 513 | i8237_dreq1_w(m_dmac, CLEAR_LINE); |
| 397 | 514 | } |
| 398 | 515 | |
| r13330 | r13331 | |
| 400 | 517 | { |
| 401 | 518 | if (!m_dack3) |
| 402 | 519 | { |
| 403 | | /* floppy terminal count */ |
| 520 | // floppy terminal count |
| 404 | 521 | upd765_tc_w(m_fdc, !state); |
| 405 | 522 | } |
| 406 | 523 | |
| r13330 | r13331 | |
| 415 | 532 | |
| 416 | 533 | if (!m_dack3) |
| 417 | 534 | { |
| 418 | | /* floppy terminal count */ |
| 535 | // floppy terminal count |
| 419 | 536 | upd765_tc_w(m_fdc, m_tc); |
| 420 | 537 | } |
| 421 | 538 | } |
| r13330 | r13331 | |
| 423 | 540 | static UINT8 memory_read_byte(address_space *space, offs_t address) { return space->read_byte(address); } |
| 424 | 541 | static void memory_write_byte(address_space *space, offs_t address, UINT8 data) { space->write_byte(address, data); } |
| 425 | 542 | |
| 426 | | static I8237_INTERFACE( mm1_dma8237_intf ) |
| 543 | static I8237_INTERFACE( dmac_intf ) |
| 427 | 544 | { |
| 428 | 545 | DEVCB_DRIVER_LINE_MEMBER(mm1_state, dma_hrq_changed), |
| 429 | 546 | DEVCB_DRIVER_LINE_MEMBER(mm1_state, tc_w), |
| r13330 | r13331 | |
| 434 | 551 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_LINE_MEMBER(mm1_state, dack3_w) } |
| 435 | 552 | }; |
| 436 | 553 | |
| 437 | | /* uPD765 Interface */ |
| 438 | 554 | |
| 439 | | static const upd765_interface fdc_intf = |
| 440 | | { |
| 441 | | DEVCB_CPU_INPUT_LINE(I8085A_TAG, I8085_RST55_LINE), |
| 442 | | DEVCB_DEVICE_LINE(I8237_TAG, i8237_dreq3_w), |
| 443 | | NULL, |
| 444 | | UPD765_RDY_PIN_NOT_CONNECTED, |
| 445 | | { FLOPPY_0, FLOPPY_1, NULL, NULL } |
| 446 | | }; |
| 555 | //------------------------------------------------- |
| 556 | // pit8253_config pit_intf |
| 557 | //------------------------------------------------- |
| 447 | 558 | |
| 448 | | /* 8253 Interface */ |
| 449 | | |
| 450 | 559 | WRITE_LINE_MEMBER( mm1_state::itxc_w ) |
| 451 | 560 | { |
| 452 | 561 | if (!m_intc) |
| r13330 | r13331 | |
| 469 | 578 | m_mpsc->rxcb_w(state); |
| 470 | 579 | } |
| 471 | 580 | |
| 472 | | static const struct pit8253_config mm1_pit8253_intf = |
| 581 | static const struct pit8253_config pit_intf = |
| 473 | 582 | { |
| 474 | 583 | { |
| 475 | 584 | { |
| r13330 | r13331 | |
| 488 | 597 | } |
| 489 | 598 | }; |
| 490 | 599 | |
| 491 | | /* uPD7201 Interface */ |
| 492 | 600 | |
| 601 | //------------------------------------------------- |
| 602 | // UPD7201_INTERFACE( mpsc_intf ) |
| 603 | //------------------------------------------------- |
| 604 | |
| 493 | 605 | WRITE_LINE_MEMBER( mm1_state::drq2_w ) |
| 494 | 606 | { |
| 495 | 607 | if (state) |
| r13330 | r13331 | |
| 508 | 620 | |
| 509 | 621 | static UPD7201_INTERFACE( mpsc_intf ) |
| 510 | 622 | { |
| 511 | | DEVCB_NULL, /* interrupt */ |
| 623 | DEVCB_NULL, // interrupt |
| 512 | 624 | { |
| 513 | 625 | { |
| 514 | | 0, /* receive clock */ |
| 515 | | 0, /* transmit clock */ |
| 516 | | DEVCB_DRIVER_LINE_MEMBER(mm1_state, drq2_w), /* receive DRQ */ |
| 517 | | DEVCB_DRIVER_LINE_MEMBER(mm1_state, drq1_w), /* transmit DRQ */ |
| 518 | | DEVCB_NULL, /* receive data */ |
| 519 | | DEVCB_NULL, /* transmit data */ |
| 520 | | DEVCB_NULL, /* clear to send */ |
| 521 | | DEVCB_NULL, /* data carrier detect */ |
| 522 | | DEVCB_NULL, /* ready to send */ |
| 523 | | DEVCB_NULL, /* data terminal ready */ |
| 524 | | DEVCB_NULL, /* wait */ |
| 525 | | DEVCB_NULL /* sync output */ |
| 626 | 0, // receive clock |
| 627 | 0, // transmit clock |
| 628 | DEVCB_DRIVER_LINE_MEMBER(mm1_state, drq2_w), // receive DRQ |
| 629 | DEVCB_DRIVER_LINE_MEMBER(mm1_state, drq1_w), // transmit DRQ |
| 630 | DEVCB_NULL, // receive data |
| 631 | DEVCB_NULL, // transmit data |
| 632 | DEVCB_NULL, // clear to send |
| 633 | DEVCB_NULL, // data carrier detect |
| 634 | DEVCB_NULL, // ready to send |
| 635 | DEVCB_NULL, // data terminal ready |
| 636 | DEVCB_NULL, // wait |
| 637 | DEVCB_NULL // sync output |
| 526 | 638 | }, { |
| 527 | | 0, /* receive clock */ |
| 528 | | 0, /* transmit clock */ |
| 529 | | DEVCB_NULL, /* receive DRQ */ |
| 530 | | DEVCB_NULL, /* transmit DRQ */ |
| 531 | | DEVCB_NULL, /* receive data */ |
| 532 | | DEVCB_NULL, /* transmit data */ |
| 533 | | DEVCB_NULL, /* clear to send */ |
| 534 | | DEVCB_LINE_GND, /* data carrier detect */ |
| 535 | | DEVCB_NULL, /* ready to send */ |
| 536 | | DEVCB_NULL, /* data terminal ready */ |
| 537 | | DEVCB_NULL, /* wait */ |
| 538 | | DEVCB_NULL /* sync output */ |
| 639 | 0, // receive clock |
| 640 | 0, // transmit clock |
| 641 | DEVCB_NULL, // receive DRQ |
| 642 | DEVCB_NULL, // transmit DRQ |
| 643 | DEVCB_NULL, // receive data |
| 644 | DEVCB_NULL, // transmit data |
| 645 | DEVCB_NULL, // clear to send |
| 646 | DEVCB_LINE_GND, // data carrier detect |
| 647 | DEVCB_NULL, // ready to send |
| 648 | DEVCB_NULL, // data terminal ready |
| 649 | DEVCB_NULL, // wait |
| 650 | DEVCB_NULL // sync output |
| 539 | 651 | } |
| 540 | 652 | } |
| 541 | 653 | }; |
| 542 | 654 | |
| 543 | | /* I8085A Interface */ |
| 544 | 655 | |
| 656 | //------------------------------------------------- |
| 657 | // I8085_CONFIG( i8085_intf ) |
| 658 | //------------------------------------------------- |
| 659 | |
| 545 | 660 | READ_LINE_MEMBER( mm1_state::dsra_r ) |
| 546 | 661 | { |
| 547 | 662 | return 1; |
| r13330 | r13331 | |
| 549 | 664 | |
| 550 | 665 | static I8085_CONFIG( i8085_intf ) |
| 551 | 666 | { |
| 552 | | DEVCB_NULL, /* STATUS changed callback */ |
| 553 | | DEVCB_NULL, /* INTE changed callback */ |
| 554 | | DEVCB_DRIVER_LINE_MEMBER(mm1_state, dsra_r), /* SID changed callback (I8085A only) */ |
| 555 | | DEVCB_DEVICE_LINE(SPEAKER_TAG, speaker_level_w) /* SOD changed callback (I8085A only) */ |
| 667 | DEVCB_NULL, // STATUS changed callback |
| 668 | DEVCB_NULL, // INTE changed callback |
| 669 | DEVCB_DRIVER_LINE_MEMBER(mm1_state, dsra_r), // SID changed callback (I8085A only) |
| 670 | DEVCB_DEVICE_LINE(SPEAKER_TAG, speaker_level_w) // SOD changed callback (I8085A only) |
| 556 | 671 | }; |
| 557 | 672 | |
| 558 | | /* Keyboard */ |
| 559 | 673 | |
| 560 | | void mm1_state::scan_keyboard() |
| 561 | | { |
| 562 | | static const char *const keynames[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7", "ROW8", "ROW9" }; |
| 674 | //------------------------------------------------- |
| 675 | // upd765_interface fdc_intf |
| 676 | //------------------------------------------------- |
| 563 | 677 | |
| 564 | | UINT8 data = input_port_read(machine(), keynames[m_drive]); |
| 565 | | UINT8 special = input_port_read(machine(), "SPECIAL"); |
| 566 | | int ctrl = BIT(special, 0); |
| 567 | | int shift = BIT(special, 2) & BIT(special, 1); |
| 568 | | UINT8 keydata = 0xff; |
| 569 | | |
| 570 | | if (!BIT(data, m_sense)) |
| 571 | | { |
| 572 | | /* get key data from PROM */ |
| 573 | | keydata = m_key_rom[(ctrl << 8) | (shift << 7) | (m_drive << 3) | (m_sense)]; |
| 574 | | } |
| 575 | | |
| 576 | | if (m_keydata != keydata) |
| 577 | | { |
| 578 | | /* latch key data */ |
| 579 | | m_keydata = keydata; |
| 580 | | |
| 581 | | if (keydata != 0xff) |
| 582 | | { |
| 583 | | /* strobe in key data */ |
| 584 | | m_iop->stb_w(1); |
| 585 | | m_iop->stb_w(0); |
| 586 | | } |
| 587 | | } |
| 588 | | |
| 589 | | if (keydata == 0xff) |
| 590 | | { |
| 591 | | /* increase scan counters */ |
| 592 | | m_sense++; |
| 593 | | |
| 594 | | if (m_sense == 8) |
| 595 | | { |
| 596 | | m_sense = 0; |
| 597 | | m_drive++; |
| 598 | | |
| 599 | | if (m_drive == 10) |
| 600 | | { |
| 601 | | m_drive = 0; |
| 602 | | } |
| 603 | | } |
| 604 | | } |
| 605 | | |
| 606 | | } |
| 607 | | |
| 608 | | static TIMER_DEVICE_CALLBACK( kbclk_tick ) |
| 609 | | { |
| 610 | | mm1_state *state = timer.machine().driver_data<mm1_state>(); |
| 611 | | |
| 612 | | state->scan_keyboard(); |
| 613 | | } |
| 614 | | |
| 615 | | /* Floppy Configuration */ |
| 616 | | |
| 617 | 678 | static LEGACY_FLOPPY_OPTIONS_START( mm1 ) |
| 618 | 679 | LEGACY_FLOPPY_OPTION( mm1_640kb, "dsk", "Nokia MikroMikko 1 640KB disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, |
| 619 | 680 | HEADS([2]) |
| 620 | 681 | TRACKS([80]) |
| 621 | | SECTORS([8]) /* 3:1 sector skew (1,4,7,2,5,8,3,6) */ |
| 682 | SECTORS([8]) // 3:1 sector skew (1,4,7,2,5,8,3,6) |
| 622 | 683 | SECTOR_LENGTH([512]) |
| 623 | 684 | FIRST_SECTOR_ID([1])) |
| 624 | 685 | LEGACY_FLOPPY_OPTIONS_END |
| r13330 | r13331 | |
| 646 | 707 | DEVCB_NULL, |
| 647 | 708 | DEVCB_NULL, |
| 648 | 709 | DEVCB_NULL, |
| 649 | | FLOPPY_STANDARD_5_25_DSHD, |
| 710 | FLOPPY_STANDARD_5_25_DSQD, |
| 650 | 711 | LEGACY_FLOPPY_OPTIONS_NAME(mm1), |
| 651 | | NULL, |
| 712 | "floppy_5_25", |
| 652 | 713 | NULL |
| 653 | 714 | }; |
| 654 | 715 | |
| 655 | | /* Machine Initialization */ |
| 716 | static const upd765_interface fdc_intf = |
| 717 | { |
| 718 | DEVCB_CPU_INPUT_LINE(I8085A_TAG, I8085_RST55_LINE), |
| 719 | DEVCB_DEVICE_LINE(I8237_TAG, i8237_dreq3_w), |
| 720 | NULL, |
| 721 | UPD765_RDY_PIN_NOT_CONNECTED, |
| 722 | { FLOPPY_0, FLOPPY_1, NULL, NULL } |
| 723 | }; |
| 656 | 724 | |
| 725 | |
| 726 | |
| 727 | //************************************************************************** |
| 728 | // MACHINE INITIALIZATION |
| 729 | //************************************************************************** |
| 730 | |
| 731 | //------------------------------------------------- |
| 732 | // MACHINE_START( mm1 ) |
| 733 | //------------------------------------------------- |
| 734 | |
| 657 | 735 | void mm1_state::machine_start() |
| 658 | 736 | { |
| 659 | | address_space *program = m_maincpu->memory().space(AS_PROGRAM); |
| 660 | | |
| 661 | | /* find memory regions */ |
| 737 | // find memory regions |
| 738 | m_mmu_rom = machine().region("address")->base(); |
| 662 | 739 | m_key_rom = machine().region("keyboard")->base(); |
| 663 | 740 | |
| 664 | | /* setup memory banking */ |
| 665 | | program->install_read_bank(0x0000, 0x0fff, "bank1"); |
| 666 | | program->unmap_write(0x0000, 0x0fff); |
| 667 | | memory_configure_bank(machine(), "bank1", 0, 1, machine().region("bios")->base(), 0); |
| 668 | | memory_configure_bank(machine(), "bank1", 1, 1, ram_get_ptr(machine().device(RAM_TAG)), 0); |
| 669 | | memory_set_bank(machine(), "bank1", 0); |
| 670 | | |
| 671 | | /* register for state saving */ |
| 741 | // register for state saving |
| 672 | 742 | state_save_register_global(machine(), m_sense); |
| 673 | 743 | state_save_register_global(machine(), m_drive); |
| 674 | 744 | state_save_register_global(machine(), m_llen); |
| r13330 | r13331 | |
| 680 | 750 | state_save_register_global(machine(), m_dack3); |
| 681 | 751 | } |
| 682 | 752 | |
| 753 | |
| 754 | //------------------------------------------------- |
| 755 | // MACHINE_RESET( mm1 ) |
| 756 | //------------------------------------------------- |
| 757 | |
| 683 | 758 | void mm1_state::machine_reset() |
| 684 | 759 | { |
| 685 | 760 | address_space *program = m_maincpu->memory().space(AS_PROGRAM); |
| 686 | 761 | int i; |
| 687 | 762 | |
| 688 | | /* reset LS259 */ |
| 763 | // reset LS259 |
| 689 | 764 | for (i = 0; i < 8; i++) ls259_w(*program, i, 0); |
| 690 | 765 | |
| 691 | | /* set FDC ready */ |
| 766 | // set FDC ready |
| 692 | 767 | if (!input_port_read(machine(), "T5")) upd765_ready_w(m_fdc, 1); |
| 693 | 768 | |
| 694 | | /* reset FDC */ |
| 769 | // reset FDC |
| 695 | 770 | upd765_reset_w(m_fdc, 1); |
| 696 | 771 | upd765_reset_w(m_fdc, 0); |
| 697 | 772 | } |
| 698 | 773 | |
| 699 | | /* Machine Drivers */ |
| 700 | 774 | |
| 775 | |
| 776 | //************************************************************************** |
| 777 | // MACHINE DRIVERS |
| 778 | //************************************************************************** |
| 779 | |
| 780 | //------------------------------------------------- |
| 781 | // MACHINE_CONFIG( mm1 ) |
| 782 | //------------------------------------------------- |
| 783 | |
| 701 | 784 | static MACHINE_CONFIG_START( mm1, mm1_state ) |
| 702 | | /* basic system hardware */ |
| 785 | // basic system hardware |
| 703 | 786 | MCFG_CPU_ADD(I8085A_TAG, I8085A, XTAL_6_144MHz) |
| 704 | 787 | MCFG_CPU_PROGRAM_MAP(mm1_map) |
| 705 | 788 | MCFG_CPU_CONFIG(i8085_intf) |
| 706 | 789 | |
| 707 | 790 | MCFG_TIMER_ADD_PERIODIC("kbclk", kbclk_tick, attotime::from_hz(2500)) //attotime::from_hz(XTAL_6_144MHz/2/8)) |
| 708 | 791 | |
| 709 | | /* video hardware */ |
| 710 | | MCFG_SCREEN_ADD( SCREEN_TAG, RASTER ) |
| 711 | | MCFG_SCREEN_REFRESH_RATE( 50 ) |
| 712 | | MCFG_SCREEN_FORMAT( BITMAP_FORMAT_INDEXED16 ) |
| 713 | | MCFG_SCREEN_SIZE( 800, 400 ) |
| 714 | | MCFG_SCREEN_VISIBLE_AREA( 0, 800-1, 0, 400-1 ) |
| 715 | | //MCFG_SCREEN_RAW_PARAMS(XTAL_18_720MHz, ...) |
| 716 | | |
| 717 | | MCFG_GFXDECODE(mm1) |
| 718 | | MCFG_PALETTE_LENGTH(3) |
| 719 | | MCFG_PALETTE_INIT(mm1) |
| 720 | | |
| 721 | | MCFG_I8275_ADD(I8275_TAG, crtc_intf) |
| 722 | | |
| 723 | | /* sound hardware */ |
| 792 | // sound hardware |
| 724 | 793 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 725 | 794 | MCFG_SOUND_ADD(SPEAKER_TAG, SPEAKER_SOUND, 0) |
| 726 | 795 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 727 | 796 | |
| 728 | | /* peripheral hardware */ |
| 729 | | MCFG_I8212_ADD(I8212_TAG, mm1_i8212_intf) |
| 730 | | MCFG_I8237_ADD(I8237_TAG, XTAL_6_144MHz/2, mm1_dma8237_intf) |
| 731 | | MCFG_PIT8253_ADD(I8253_TAG, mm1_pit8253_intf) |
| 732 | | MCFG_UPD765A_ADD(UPD765_TAG, /* XTAL_16MHz/2/2, */ fdc_intf) |
| 797 | // peripheral hardware |
| 798 | MCFG_I8212_ADD(I8212_TAG, iop_intf) |
| 799 | MCFG_I8237_ADD(I8237_TAG, XTAL_6_144MHz/2, dmac_intf) |
| 800 | MCFG_PIT8253_ADD(I8253_TAG, pit_intf) |
| 801 | MCFG_UPD765A_ADD(UPD765_TAG, /* XTAL_16MHz/2/2 */ fdc_intf) |
| 733 | 802 | MCFG_UPD7201_ADD(UPD7201_TAG, XTAL_6_144MHz/2, mpsc_intf) |
| 734 | 803 | |
| 735 | 804 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(mm1_floppy_interface) |
| 736 | 805 | |
| 737 | | /* internal ram */ |
| 806 | // internal ram |
| 738 | 807 | MCFG_RAM_ADD(RAM_TAG) |
| 739 | 808 | MCFG_RAM_DEFAULT_SIZE("64K") |
| 740 | 809 | MACHINE_CONFIG_END |
| 741 | 810 | |
| 811 | |
| 812 | //------------------------------------------------- |
| 813 | // MACHINE_CONFIG( mm1m6 ) |
| 814 | //------------------------------------------------- |
| 815 | |
| 742 | 816 | static MACHINE_CONFIG_DERIVED( mm1m6, mm1 ) |
| 743 | | /* basic system hardware */ |
| 744 | | MCFG_CPU_MODIFY(I8085A_TAG) |
| 745 | | MCFG_CPU_PROGRAM_MAP(mm1m6_map) |
| 746 | | |
| 747 | | /* video hardware */ |
| 748 | | MCFG_UPD7220_ADD(UPD7220_TAG, XTAL_18_720MHz/8, hgdc_intf, mm1_upd7220_map) |
| 817 | // video hardware |
| 818 | MCFG_FRAGMENT_ADD(mm1m6_video) |
| 749 | 819 | MACHINE_CONFIG_END |
| 750 | 820 | |
| 751 | | /* ROMs */ |
| 752 | 821 | |
| 753 | | ROM_START( mm1m6 ) |
| 754 | | ROM_REGION( 0x4000, "bios", 0 ) /* BIOS */ |
| 755 | | ROM_LOAD( "9081b.ic2", 0x0000, 0x2000, CRC(2955feb3) SHA1(946a6b0b8fb898be3f480c04da33d7aaa781152b) ) |
| 756 | 822 | |
| 757 | | /* |
| 823 | //************************************************************************** |
| 824 | // ROMS |
| 825 | //************************************************************************** |
| 758 | 826 | |
| 759 | | Address Decoder PROM outputs |
| 827 | //------------------------------------------------- |
| 828 | // ROM( mm1m6 ) |
| 829 | //------------------------------------------------- |
| 760 | 830 | |
| 761 | | D0 IOEN/_MEMEN |
| 762 | | D1 RAMEN |
| 763 | | D2 not connected |
| 764 | | D3 _CE4 |
| 765 | | D4 _CE0 |
| 766 | | D5 _CE1 |
| 767 | | D6 _CE2 |
| 768 | | D7 _CE3 |
| 769 | | |
| 770 | | */ |
| 771 | | ROM_REGION( 0x200, "address", 0 ) /* address decoder */ |
| 831 | ROM_START( mm1m6 ) |
| 832 | ROM_REGION( 0x4000, I8085A_TAG, 0 ) // BIOS |
| 833 | ROM_LOAD( "9081b.ic2", 0x0000, 0x2000, CRC(2955feb3) SHA1(946a6b0b8fb898be3f480c04da33d7aaa781152b) ) |
| 834 | |
| 835 | ROM_REGION( 0x200, "address", 0 ) // address decoder |
| 772 | 836 | ROM_LOAD( "720793a.ic24", 0x0000, 0x0200, CRC(deea87a6) SHA1(8f19e43252c9a0b1befd02fc9d34fe1437477f3a) ) |
| 773 | 837 | |
| 774 | | ROM_REGION( 0x200, "keyboard", 0 ) /* keyboard encoder */ |
| 838 | ROM_REGION( 0x200, "keyboard", 0 ) // keyboard encoder |
| 775 | 839 | ROM_LOAD( "mmi6349-1j.bin", 0x0000, 0x0200, CRC(4ab3bf03) SHA1(925c9ee22db13566416cdbc505c03d4116ff8d5f) ) |
| 776 | 840 | |
| 777 | | ROM_REGION( 0x1000, "chargen", 0 ) /* character generator */ |
| 841 | ROM_REGION( 0x1000, "chargen", 0 ) // character generator |
| 778 | 842 | ROM_LOAD( "6807b.ic61", 0x0000, 0x1000, CRC(32b36220) SHA1(8fe7a181badea3f7e656dfaea21ee9e4c9baf0f1) ) |
| 779 | 843 | ROM_END |
| 780 | 844 | |
| 845 | |
| 846 | //------------------------------------------------- |
| 847 | // ROM( mm1m7 ) |
| 848 | //------------------------------------------------- |
| 849 | |
| 781 | 850 | #define rom_mm1m7 rom_mm1m6 |
| 782 | 851 | |
| 783 | | /* System Drivers */ |
| 784 | 852 | |
| 853 | |
| 854 | //************************************************************************** |
| 855 | // SYSTEM DRIVERS |
| 856 | //************************************************************************** |
| 857 | |
| 785 | 858 | // YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS |
| 786 | 859 | COMP( 1981, mm1m6, 0, 0, mm1m6, mm1, 0, "Nokia Data", "MikroMikko 1 M6", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND) |
| 787 | 860 | COMP( 1981, mm1m7, mm1m6, 0, mm1m6, mm1, 0, "Nokia Data", "MikroMikko 1 M7", GAME_NOT_WORKING) |