src/mess/video/x68k.c
| r1068 | r1069 | |
| 29 | 29 | #include "inputx.h" |
| 30 | 30 | #include "render.h" |
| 31 | 31 | #include "includes/x68k.h" |
| 32 | #include "machine/68901mfp.h" |
| 32 | 33 | |
| 33 | 34 | extern struct x68k_system sys; |
| 34 | 35 | |
| r1068 | r1069 | |
| 188 | 189 | int state = param; |
| 189 | 190 | mame_time irq_time = video_screen_get_scan_period(0); |
| 190 | 191 | mame_time hsync_time = MAME_TIME_IN_CYCLES(0,32); |
| 191 | | |
| 192 | |
| 193 | sys.crtc.hblank = state; |
| 192 | 194 | if(state == 1) |
| 193 | 195 | { |
| 194 | | sys.crtc.hblank = 1; |
| 195 | | mfp_trigger_irq(MFP_IRQ_GPIP7); // HSync |
| 196 | // mfp_trigger_irq(MFP_IRQ_GPIP7); // HSync |
| 196 | 197 | mame_timer_adjust(scanline_timer,hsync_time,0,time_never); |
| 197 | 198 | } |
| 198 | 199 | if(state == 0) |
| 199 | 200 | { |
| 200 | 201 | double time_to_irq = mame_time_to_double(irq_time) - mame_time_to_double(hsync_time); |
| 201 | | sys.crtc.hblank = 0; |
| 202 | 202 | mame_timer_adjust(scanline_timer,double_to_mame_time(time_to_irq),1,time_never); |
| 203 | if(!(sys.mfp.gpio & 0x40)) // if GPIP6 is active, clear it |
| 204 | sys.mfp.gpio |= 0x40; |
| 203 | 205 | } |
| 204 | 206 | } |
| 205 | 207 | |
| r1068 | r1069 | |
| 208 | 210 | { |
| 209 | 211 | int scan = param; |
| 210 | 212 | mame_time irq_time; |
| 211 | | mfp_trigger_irq(MFP_IRQ_GPIP6); |
| 212 | | if((sys.mfp.iera & 0x40) && (readinputportbytag("options") & 0x01)) |
| 213 | // mfp_trigger_irq(MFP_IRQ_GPIP6); |
| 214 | sys.mfp.gpio &= ~0x40; // GPIP6 |
| 215 | if((readinputportbytag("options") & 0x01)) |
| 213 | 216 | { |
| 214 | | video_screen_update_partial(0,(scan+1)); |
| 217 | video_screen_update_partial(0,scan+1); |
| 215 | 218 | } |
| 216 | 219 | |
| 217 | 220 | irq_time = video_screen_get_time_until_pos(0,scan,2); |
| r1068 | r1069 | |
| 229 | 232 | |
| 230 | 233 | if(val == 1) // VBlank on |
| 231 | 234 | { |
| 232 | | mfp_timer_a_callback(machine, 0); |
| 235 | //mfp_timer_a_callback(machine, 0); |
| 233 | 236 | // if(!(sys.mfp.aer & 0x10)) |
| 234 | | mfp_trigger_irq(MFP_IRQ_GPIP4); // V-DISP |
| 237 | // mfp_trigger_irq(MFP_IRQ_GPIP4); // V-DISP |
| 235 | 238 | vblank_line = sys.crtc.reg[6]; |
| 236 | 239 | if(vblank_line > sys.crtc.reg[4]) |
| 237 | 240 | vblank_line = sys.crtc.reg[4]; |
| r1068 | r1069 | |
| 992 | 995 | { |
| 993 | 996 | sys.mfp.isra = 0; |
| 994 | 997 | sys.mfp.isrb = 0; |
| 995 | | mfp_trigger_irq(MFP_IRQ_GPIP6); |
| 998 | // mfp_trigger_irq(MFP_IRQ_GPIP6); |
| 996 | 999 | // cpunum_set_input_line_and_vector(0,6,ASSERT_LINE,0x43); |
| 997 | 1000 | } |
| 998 | 1001 | if(input_code_pressed(KEYCODE_9)) |
src/mess/drivers/x68k.c
| r1068 | r1069 | |
| 128 | 128 | #include "inputx.h" |
| 129 | 129 | #include "render.h" |
| 130 | 130 | #include "cpu/m68000/m68000.h" |
| 131 | #include "machine/68901mfp.h" |
| 131 | 132 | #include "machine/8255ppi.h" |
| 132 | 133 | #include "machine/nec765.h" |
| 133 | 134 | #include "sound/2151intf.h" |
| r1068 | r1069 | |
| 151 | 152 | UINT8 current_irq_line; |
| 152 | 153 | unsigned int x68k_scanline; |
| 153 | 154 | |
| 155 | UINT8 mfp_key; |
| 156 | |
| 154 | 157 | extern mame_bitmap* x68k_text_bitmap; // 1024x1024 4x1bpp planes text |
| 155 | 158 | extern mame_bitmap* x68k_gfx_0_bitmap_16; // 16 colour, 512x512, 4 pages |
| 156 | 159 | extern mame_bitmap* x68k_gfx_1_bitmap_16; |
| r1068 | r1069 | |
| 166 | 169 | extern tilemap* x68k_bg1_16; |
| 167 | 170 | |
| 168 | 171 | mame_timer* kb_timer; |
| 169 | | mame_timer* mfp_timer[4]; |
| 170 | | mame_timer* mfp_irq; |
| 172 | //mame_timer* mfp_timer[4]; |
| 173 | //mame_timer* mfp_irq; |
| 171 | 174 | mame_timer* scanline_timer; |
| 172 | 175 | mame_timer* raster_irq; |
| 173 | 176 | mame_timer* vblank_irq; |
| 174 | 177 | mame_timer* mouse_timer; // to set off the mouse interrupts via the SCC |
| 175 | 178 | |
| 176 | 179 | // MFP is clocked at 4MHz, so at /4 prescaler the timer is triggered after 1us (4 cycles) |
| 177 | | static mame_time prescale(int val) |
| 180 | // No longer necessary with the new MFP core |
| 181 | /*static mame_time prescale(int val) |
| 178 | 182 | { |
| 179 | 183 | switch(val) |
| 180 | 184 | { |
| r1068 | r1069 | |
| 189 | 193 | default: |
| 190 | 194 | fatalerror("out of range"); |
| 191 | 195 | } |
| 192 | | } |
| 196 | }*/ |
| 193 | 197 | |
| 194 | 198 | void mfp_init(void); |
| 195 | | static TIMER_CALLBACK(mfp_update_irq); |
| 199 | //static TIMER_CALLBACK(mfp_update_irq); |
| 196 | 200 | |
| 197 | 201 | void mfp_init() |
| 198 | 202 | { |
| r1068 | r1069 | |
| 201 | 205 | sys.mfp.irqline = 6; // MFP is connected to 68000 IRQ line 6 |
| 202 | 206 | sys.mfp.current_irq = -1; // No current interrupt |
| 203 | 207 | |
| 204 | | mfp_timer[0] = mame_timer_alloc(mfp_timer_a_callback); |
| 208 | /* mfp_timer[0] = mame_timer_alloc(mfp_timer_a_callback); |
| 205 | 209 | mfp_timer[1] = mame_timer_alloc(mfp_timer_b_callback); |
| 206 | 210 | mfp_timer[2] = mame_timer_alloc(mfp_timer_c_callback); |
| 207 | 211 | mfp_timer[3] = mame_timer_alloc(mfp_timer_d_callback); |
| 208 | 212 | mfp_irq = mame_timer_alloc(mfp_update_irq); |
| 209 | 213 | mame_timer_adjust(mfp_irq, time_zero, 0, MAME_TIME_IN_USEC(32)); |
| 214 | */ |
| 210 | 215 | } |
| 211 | | |
| 216 | /* |
| 212 | 217 | TIMER_CALLBACK(mfp_update_irq) |
| 213 | 218 | { |
| 214 | 219 | int x; |
| r1068 | r1069 | |
| 335 | 340 | logerror("MFP: Timer #%i set to %2.1fus\n",timer, mame_time_to_double(prescale(data & 0x07)) * 1000000); |
| 336 | 341 | |
| 337 | 342 | } |
| 338 | | |
| 343 | */ |
| 339 | 344 | // 4 channel DMA controller (Hitachi HD63450) |
| 340 | 345 | WRITE16_HANDLER( x68k_dmac_w ) |
| 341 | 346 | { |
| r1068 | r1069 | |
| 435 | 440 | if(sys.keyboard.enabled != 0) |
| 436 | 441 | { |
| 437 | 442 | sys.mfp.rsr |= 0x80; // Buffer full |
| 438 | | mfp_trigger_irq(MFP_IRQ_RX_FULL); |
| 443 | // mfp_trigger_irq(MFP_IRQ_RX_FULL); |
| 439 | 444 | logerror("MFP: Receive buffer full IRQ sent\n"); |
| 440 | 445 | } |
| 441 | 446 | } |
| r1068 | r1069 | |
| 443 | 448 | if(sys.keyboard.headpos > 15) |
| 444 | 449 | { |
| 445 | 450 | sys.keyboard.headpos = 0; |
| 446 | | mfp_trigger_irq(MFP_IRQ_RX_ERROR); |
| 451 | // mfp_trigger_irq(MFP_IRQ_RX_ERROR); |
| 447 | 452 | } |
| 448 | 453 | } |
| 449 | 454 | |
| r1068 | r1069 | |
| 501 | 506 | sys.mfp.tsr |= 0x80; |
| 502 | 507 | sys.mfp.usart.recv_buffer = 0x00; // TODO: set up keyboard data |
| 503 | 508 | sys.mfp.vector = current_vector[6] = (sys.mfp.vr & 0xf0) | 0x0c; |
| 504 | | mfp_trigger_irq(MFP_IRQ_RX_FULL); |
| 509 | // mfp_trigger_irq(MFP_IRQ_RX_FULL); |
| 505 | 510 | // logerror("MFP: Receive buffer full IRQ sent\n"); |
| 506 | 511 | } |
| 507 | 512 | |
| r1068 | r1069 | |
| 922 | 927 | } |
| 923 | 928 | } |
| 924 | 929 | |
| 925 | | |
| 930 | /* |
| 926 | 931 | READ16_HANDLER( x68k_mfp_r ) |
| 927 | 932 | { |
| 928 | 933 | int ret; |
| 929 | | /* Initial settings indicate that IRQs are generated for FM (YM2151), Receive buffer error or full, |
| 930 | | MFP Timer C, and the power switch*/ |
| 934 | // Initial settings indicate that IRQs are generated for FM (YM2151), Receive buffer error or full, |
| 935 | // MFP Timer C, and the power switch |
| 931 | 936 | // logerror("MFP: [%08x] Reading offset %i\n",activecpu_get_pc(),offset); |
| 932 | 937 | switch(offset) |
| 933 | 938 | { |
| r1068 | r1069 | |
| 986 | 991 | } |
| 987 | 992 | |
| 988 | 993 | WRITE16_HANDLER( x68k_mfp_w ) |
| 989 | | { |
| 994 | {*/ |
| 990 | 995 | /* For the Interrupt registers, the bits are set out as such: |
| 991 | 996 | Reg A - bit 7: GPIP7 (HSync) |
| 992 | 997 | bit 6: GPIP6 (CRTC CIRQ) |
| r1068 | r1069 | |
| 1005 | 1010 | bit 1: GPIP1 (EXPON) |
| 1006 | 1011 | bit 0: GPIP0 (Alarm) |
| 1007 | 1012 | */ |
| 1008 | | switch(offset) |
| 1013 | /* switch(offset) |
| 1009 | 1014 | { |
| 1010 | 1015 | case 0: // GPDR |
| 1011 | 1016 | // All bits are inputs generally, so no action taken. |
| r1068 | r1069 | |
| 1111 | 1116 | return; |
| 1112 | 1117 | } |
| 1113 | 1118 | } |
| 1119 | */ |
| 1114 | 1120 | |
| 1115 | 1121 | WRITE16_HANDLER( x68k_ppi_w ) |
| 1116 | 1122 | { |
| r1068 | r1069 | |
| 1137 | 1143 | if(sys.mfp.aer & 0x01) |
| 1138 | 1144 | { |
| 1139 | 1145 | if(state == 1) |
| 1140 | | mfp_trigger_irq(MFP_IRQ_GPIP0); // RTC ALARM |
| 1146 | sys.mfp.gpio |= 0x01; |
| 1147 | //mfp_trigger_irq(MFP_IRQ_GPIP0); // RTC ALARM |
| 1141 | 1148 | } |
| 1142 | 1149 | else |
| 1143 | 1150 | { |
| 1144 | 1151 | if(state == 0) |
| 1145 | | mfp_trigger_irq(MFP_IRQ_GPIP0); // RTC ALARM |
| 1152 | sys.mfp.gpio &= ~0x01; |
| 1153 | //mfp_trigger_irq(MFP_IRQ_GPIP0); // RTC ALARM |
| 1146 | 1154 | } |
| 1147 | 1155 | } |
| 1148 | 1156 | |
| r1068 | r1069 | |
| 1245 | 1253 | { |
| 1246 | 1254 | } |
| 1247 | 1255 | |
| 1256 | READ16_HANDLER( x68k_areaset_r ) |
| 1257 | { |
| 1258 | // register is write-only |
| 1259 | return 0xffff; |
| 1260 | } |
| 1261 | |
| 1262 | WRITE16_HANDLER( x68k_areaset_w ) |
| 1263 | { |
| 1264 | // TODO |
| 1265 | logerror("SYS: Supervisor area set: 0x%02x\n",data & 0xff); |
| 1266 | } |
| 1267 | |
| 1268 | WRITE16_HANDLER( x68k_enh_areaset_w ) |
| 1269 | { |
| 1270 | // TODO |
| 1271 | logerror("SYS: Enhanced Supervisor area set (from %iMB): 0x%02x\n",(offset + 1) * 2,data & 0xff); |
| 1272 | } |
| 1273 | |
| 1248 | 1274 | static TIMER_CALLBACK(x68k_fake_bus_error) |
| 1249 | 1275 | { |
| 1250 | 1276 | int val = param; |
| r1068 | r1069 | |
| 1351 | 1377 | |
| 1352 | 1378 | void x68k_fm_irq(int irq) |
| 1353 | 1379 | { |
| 1354 | | if(irq == ASSERT_LINE) |
| 1380 | if(irq == CLEAR_LINE) |
| 1355 | 1381 | { |
| 1356 | | // sys.mfp.isrb |= 0x08; |
| 1357 | | // current_vector[6] = (sys.mfp.vr & 0xf0) | 0x03; |
| 1358 | | // current_irq_line = 6; |
| 1359 | | mfp_trigger_irq(MFP_IRQ_GPIP3); |
| 1382 | sys.mfp.gpio |= 0x08; |
| 1360 | 1383 | } |
| 1384 | else |
| 1385 | { |
| 1386 | sys.mfp.gpio &= ~0x08; |
| 1387 | current_vector[6] = 0x43; |
| 1388 | } |
| 1389 | |
| 1361 | 1390 | } |
| 1362 | 1391 | |
| 1392 | READ8_HANDLER(mfp_gpio_r) |
| 1393 | { |
| 1394 | UINT8 data = sys.mfp.gpio; |
| 1395 | |
| 1396 | data &= ~(video_screen_get_hblank(0) << 7); |
| 1397 | data &= ~(sys.crtc.vblank << 4); |
| 1398 | data |= 0x23; // GPIP5 is unused, always 1 |
| 1399 | mfp68901_tai_w(0,sys.crtc.vblank); |
| 1400 | |
| 1401 | return data; |
| 1402 | } |
| 1403 | |
| 1404 | TIMER_CALLBACK( x68k_delayed_irq ) |
| 1405 | { |
| 1406 | if((sys.ioc.irqstatus & 0xc0) != 0) // if the FDC is busy, then we don't want to miss that IRQ |
| 1407 | { |
| 1408 | mame_timer_set(MAME_TIME_IN_CYCLES(32,0),param,x68k_delayed_irq); |
| 1409 | return; |
| 1410 | } |
| 1411 | current_vector[6] = param; |
| 1412 | cpunum_set_input_line_and_vector(0,6,HOLD_LINE,param); |
| 1413 | } |
| 1414 | |
| 1415 | void mfp_irq_callback(int which, int state, int vector) |
| 1416 | { |
| 1417 | if(state == HOLD_LINE) |
| 1418 | { |
| 1419 | if((sys.ioc.irqstatus & 0xc0) != 0) // if the FDC is busy, then we don't want to miss that IRQ |
| 1420 | { |
| 1421 | mame_timer_set(MAME_TIME_IN_CYCLES(32,0),vector,x68k_delayed_irq); |
| 1422 | return; |
| 1423 | } |
| 1424 | current_vector[6] = vector; |
| 1425 | cpunum_set_input_line_and_vector(0,6,state,vector); |
| 1426 | // logerror("MFP IRQ callback: state=%i,vector=0x%02x\n",state,vector); |
| 1427 | } |
| 1428 | } |
| 1429 | |
| 1363 | 1430 | static INTERRUPT_GEN( x68k_vsync_irq ) |
| 1364 | 1431 | { |
| 1365 | 1432 | // if(sys.mfp.ierb & 0x40) |
| r1068 | r1069 | |
| 1370 | 1437 | // mfp_timer_a_callback(0); // Timer A is usually always in event count mode, and is tied to V-DISP |
| 1371 | 1438 | // mfp_trigger_irq(MFP_IRQ_GPIP4); |
| 1372 | 1439 | // } |
| 1373 | | if(sys.crtc.height == 256) |
| 1374 | | video_screen_update_partial(0,256);//sys.crtc.reg[4]/2); |
| 1375 | | else |
| 1376 | | video_screen_update_partial(0,512);//sys.crtc.reg[4]); |
| 1440 | // if(sys.crtc.height == 256) |
| 1441 | // video_screen_update_partial(0,256);//sys.crtc.reg[4]/2); |
| 1442 | // else |
| 1443 | // video_screen_update_partial(0,512);//sys.crtc.reg[4]); |
| 1377 | 1444 | } |
| 1378 | 1445 | |
| 1379 | 1446 | static int x68k_int_ack(int line) |
| r1068 | r1069 | |
| 1390 | 1457 | if(line == 6) // MFP |
| 1391 | 1458 | { |
| 1392 | 1459 | // if(sys.mfp.isra & 0x10) |
| 1393 | | sys.mfp.rsr &= ~0x80; |
| 1460 | // sys.mfp.rsr &= ~0x80; |
| 1394 | 1461 | // if(sys.mfp.isra & 0x04) |
| 1395 | | sys.mfp.tsr &= ~0x80; |
| 1462 | // sys.mfp.tsr &= ~0x80; |
| 1396 | 1463 | |
| 1397 | | if(sys.mfp.current_irq < 8) |
| 1398 | | { |
| 1399 | | sys.mfp.iprb &= ~(1 << sys.mfp.current_irq); |
| 1464 | // if(sys.mfp.current_irq < 8) |
| 1465 | // { |
| 1466 | // sys.mfp.iprb &= ~(1 << sys.mfp.current_irq); |
| 1400 | 1467 | // IRQ is in service |
| 1401 | | if(sys.mfp.eoi_mode != 0) // automatic EOI does not set the ISR registers |
| 1402 | | sys.mfp.isrb |= (1 << sys.mfp.current_irq); |
| 1403 | | } |
| 1404 | | else |
| 1405 | | { |
| 1406 | | sys.mfp.ipra &= ~(1 << (sys.mfp.current_irq - 8)); |
| 1468 | // if(sys.mfp.eoi_mode != 0) // automatic EOI does not set the ISR registers |
| 1469 | // sys.mfp.isrb |= (1 << sys.mfp.current_irq); |
| 1470 | // } |
| 1471 | // else |
| 1472 | // { |
| 1473 | // sys.mfp.ipra &= ~(1 << (sys.mfp.current_irq - 8)); |
| 1407 | 1474 | // IRQ is in service |
| 1408 | | if(sys.mfp.eoi_mode != 0) // automatic EOI does not set the ISR registers |
| 1409 | | sys.mfp.isra |= (1 << (sys.mfp.current_irq - 8)); |
| 1410 | | } |
| 1475 | // if(sys.mfp.eoi_mode != 0) // automatic EOI does not set the ISR registers |
| 1476 | // sys.mfp.isra |= (1 << (sys.mfp.current_irq - 8)); |
| 1477 | // } |
| 1411 | 1478 | sys.mfp.current_irq = -1; |
| 1412 | 1479 | } |
| 1413 | 1480 | |
| r1068 | r1069 | |
| 1425 | 1492 | AM_RANGE(0xe80000, 0xe81fff) AM_READWRITE(x68k_crtc_r, x68k_crtc_w) |
| 1426 | 1493 | AM_RANGE(0xe82000, 0xe83fff) AM_READWRITE(x68k_vid_r, x68k_vid_w) |
| 1427 | 1494 | AM_RANGE(0xe84000, 0xe85fff) AM_READWRITE(x68k_dmac_r, x68k_dmac_w) |
| 1428 | | // AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE(x68k_areaset_r, x68k_areaset_w) |
| 1429 | | AM_RANGE(0xe88000, 0xe89fff) AM_READWRITE(x68k_mfp_r, x68k_mfp_w) |
| 1495 | AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE(x68k_areaset_r, x68k_areaset_w) |
| 1496 | AM_RANGE(0xe88000, 0xe89fff) AM_READWRITE(mfp68901_0_register_lsb_r, mfp68901_0_register_lsb_w) |
| 1430 | 1497 | AM_RANGE(0xe8a000, 0xe8bfff) AM_READWRITE(x68k_rtc_r, x68k_rtc_w) |
| 1431 | 1498 | // AM_RANGE(0xe8c000, 0xe8dfff) AM_READWRITE(x68k_printer_r, x68k_printer_w) |
| 1432 | 1499 | AM_RANGE(0xe8e000, 0xe8ffff) AM_READWRITE(x68k_sysport_r, x68k_sysport_w) |
| r1068 | r1069 | |
| 1438 | 1505 | AM_RANGE(0xe9a000, 0xe9bfff) AM_READWRITE(x68k_ppi_r, x68k_ppi_w) |
| 1439 | 1506 | AM_RANGE(0xe9c000, 0xe9dfff) AM_READWRITE(x68k_ioc_r, x68k_ioc_w) |
| 1440 | 1507 | AM_RANGE(0xeafa00, 0xeafa1f) AM_READWRITE(x68k_exp_r, x68k_exp_w) |
| 1508 | AM_RANGE(0xeafa80, 0xeafa89) AM_READWRITE(x68k_areaset_r, x68k_enh_areaset_w) |
| 1441 | 1509 | AM_RANGE(0xeb0000, 0xeb7fff) AM_READWRITE(x68k_spritereg_r, x68k_spritereg_w) |
| 1442 | 1510 | AM_RANGE(0xeb8000, 0xebffff) AM_READWRITE(x68k_spriteram_r, x68k_spriteram_w) |
| 1443 | 1511 | AM_RANGE(0xec0000, 0xecffff) AM_NOP // User I/O |
| r1068 | r1069 | |
| 1447 | 1515 | AM_RANGE(0xf00000, 0xffffff) AM_ROM |
| 1448 | 1516 | ADDRESS_MAP_END |
| 1449 | 1517 | |
| 1518 | static mfp68901_interface mfp_interface = |
| 1519 | { |
| 1520 | 4000000, // 4MHz clock |
| 1521 | 4000000, |
| 1522 | 0, |
| 1523 | 0, |
| 1524 | &mfp_key, // Rx |
| 1525 | NULL, // Tx |
| 1526 | NULL, |
| 1527 | mfp_irq_callback, |
| 1528 | mfp_gpio_r, |
| 1529 | NULL |
| 1530 | }; |
| 1531 | |
| 1450 | 1532 | static ppi8255_interface ppi_interface = |
| 1451 | 1533 | { |
| 1452 | 1534 | 1, // 1 PPI |
| r1068 | r1069 | |
| 1822 | 1904 | |
| 1823 | 1905 | // start HBlank timer |
| 1824 | 1906 | mame_timer_adjust(scanline_timer,video_screen_get_scan_period(0),1,time_never); |
| 1907 | |
| 1908 | sys.mfp.gpio = 0xfb; |
| 1825 | 1909 | } |
| 1826 | 1910 | |
| 1827 | 1911 | MACHINE_START( x68000 ) |
| r1068 | r1069 | |
| 1883 | 1967 | |
| 1884 | 1968 | memset(&sys,0,sizeof(sys)); |
| 1885 | 1969 | |
| 1970 | mfp68901_config(0,&mfp_interface); |
| 1886 | 1971 | cpunum_set_irq_callback(0, x68k_int_ack); |
| 1887 | 1972 | |
| 1888 | 1973 | // init keyboard |