trunk/src/emu/video/upd7220.c
| r241347 | r241348 | |
| 33 | 33 | - honor visible area |
| 34 | 34 | - wide mode (32-bit access) |
| 35 | 35 | - light pen |
| 36 | - dad and mask are the same, in figd dad is shifted every step and when msb or lsb are 1 ead is advanced in x dir |
| 36 | 37 | |
| 37 | 38 | */ |
| 38 | 39 | |
| r241347 | r241348 | |
| 120 | 121 | #define UPD7220_SR_HBLANK_ACTIVE 0x40 |
| 121 | 122 | #define UPD7220_SR_LIGHT_PEN_DETECT 0x80 |
| 122 | 123 | |
| 123 | | #define UPD7220_MODE_S 0x01 |
| 124 | 124 | #define UPD7220_MODE_REFRESH_RAM 0x04 |
| 125 | | #define UPD7220_MODE_I 0x08 |
| 126 | 125 | #define UPD7220_MODE_DRAW_ON_RETRACE 0x10 |
| 127 | 126 | #define UPD7220_MODE_DISPLAY_MASK 0x22 |
| 128 | 127 | #define UPD7220_MODE_DISPLAY_MIXED 0x00 |
| 129 | 128 | #define UPD7220_MODE_DISPLAY_GRAPHICS 0x02 |
| 130 | 129 | #define UPD7220_MODE_DISPLAY_CHARACTER 0x20 |
| 131 | 130 | #define UPD7220_MODE_DISPLAY_INVALID 0x22 |
| 131 | #define UPD7220_MODE_INTERLACE_MASK 0x09 |
| 132 | #define UPD7220_MODE_INTERLACE_NONE 0x00 |
| 133 | #define UPD7220_MODE_INTERLACE_INVALID 0x01 |
| 134 | #define UPD7220_MODE_INTERLACE_REPEAT 0x08 |
| 135 | #define UPD7220_MODE_INTERLACE_ON 0x09 |
| 132 | 136 | |
| 137 | |
| 133 | 138 | static const int x_dir[8] = { 0, 1, 1, 1, 0,-1,-1,-1}; |
| 134 | 139 | static const int y_dir[8] = { 1, 1, 0,-1,-1,-1, 0, 1}; |
| 135 | 140 | |
| r241347 | r241348 | |
| 366 | 371 | |
| 367 | 372 | inline void upd7220_device::recompute_parameters() |
| 368 | 373 | { |
| 374 | int horiz_mult; |
| 369 | 375 | /* TODO: assume that the pitch also controls number of horizontal pixels in a single cell */ |
| 370 | | int horiz_mult = ((m_pitch == 40) ? 16 : 8); |
| 371 | | int horiz_pix_total = (m_hs + m_hbp + m_aw + m_hfp) * horiz_mult; |
| 376 | // horiz_mult = 4 if both mixed and interlace? |
| 377 | if(((m_mode & UPD7220_MODE_DISPLAY_MASK) == UPD7220_MODE_DISPLAY_MIXED) || |
| 378 | ((m_mode & UPD7220_MODE_INTERLACE_MASK) == UPD7220_MODE_INTERLACE_ON)) |
| 379 | horiz_mult = 8; |
| 380 | else |
| 381 | horiz_mult = 16; |
| 382 | |
| 383 | int horiz_pix_total = (m_hs + m_hbp + m_hfp + m_aw) * horiz_mult; |
| 372 | 384 | int vert_pix_total = m_vs + m_vbp + m_al + m_vfp; |
| 373 | 385 | |
| 374 | 386 | //printf("%d %d %d %d\n",m_hs,m_hbp,m_aw,m_hfp); |
| r241347 | r241348 | |
| 377 | 389 | if (horiz_pix_total == 0 || vert_pix_total == 0) //bail out if screen params aren't valid |
| 378 | 390 | return; |
| 379 | 391 | |
| 380 | | attoseconds_t refresh = HZ_TO_ATTOSECONDS(clock() * horiz_mult) * horiz_pix_total * vert_pix_total; |
| 392 | attoseconds_t refresh = HZ_TO_ATTOSECONDS(clock() * 8) * horiz_pix_total * vert_pix_total; |
| 381 | 393 | |
| 382 | 394 | rectangle visarea; |
| 383 | 395 | |
| r241347 | r241348 | |
| 419 | 431 | m_figs.m_d1 = 0x0008; |
| 420 | 432 | m_figs.m_d2 = 0x0000; |
| 421 | 433 | m_figs.m_dm = 0x0000; |
| 434 | m_figs.m_gd = 0; |
| 422 | 435 | } |
| 423 | 436 | |
| 424 | 437 | |
| r241347 | r241348 | |
| 479 | 492 | |
| 480 | 493 | result = 0; |
| 481 | 494 | |
| 495 | if(((m_mode & UPD7220_MODE_DISPLAY_MASK) == UPD7220_MODE_DISPLAY_GRAPHICS) || m_figs.m_gd) |
| 496 | result = BITSWAP8(m_pr[1],0,1,2,3,4,5,6,7) | (BITSWAP8(m_pr[2],0,1,2,3,4,5,6,7) << 8); |
| 497 | else |
| 498 | result = m_pr[1] | (m_pr[2] << 8); |
| 499 | |
| 482 | 500 | switch(type) |
| 483 | 501 | { |
| 484 | 502 | case 0: |
| 485 | | result = (m_pr[1] & 0xff); |
| 486 | | result |= (m_pr[2] << 8); |
| 487 | 503 | result &= m_mask; |
| 488 | 504 | break; |
| 489 | 505 | case 2: |
| 490 | | result = (m_pr[1] & 0xff); |
| 491 | 506 | result &= (m_mask & 0xff); |
| 492 | 507 | break; |
| 493 | 508 | case 3: |
| 494 | | result = (m_pr[1] << 8); |
| 509 | result <<= 8; |
| 495 | 510 | result &= (m_mask & 0xff00); |
| 496 | 511 | break; |
| 497 | 512 | } |
| r241347 | r241348 | |
| 760 | 775 | |
| 761 | 776 | void upd7220_device::draw_pixel(int x, int y, int xi, UINT16 tile_data) |
| 762 | 777 | { |
| 763 | | UINT32 addr = (y * m_pitch * 2 + (x >> 3)) & 0x3ffff; |
| 778 | UINT32 addr = ((y * m_pitch * 2) + (x >> 3)) & 0x3ffff; |
| 764 | 779 | UINT8 data = readbyte(addr); |
| 765 | 780 | UINT8 new_pixel = (xi & 8 ? tile_data >> 8 : tile_data & 0xff) & (0x80 >> (xi & 7)); |
| 766 | 781 | new_pixel = new_pixel ? (0xff & (0x80 >> (x & 7))) : 0; |
| r241347 | r241348 | |
| 797 | 812 | UINT16 pattern = (m_ra[8]) | (m_ra[9]<<8); |
| 798 | 813 | int line_step = 0; |
| 799 | 814 | |
| 800 | | LOG(("uPD7220 line check: %d %d %02x %08x %d %d\n",x,y,m_figs.m_dir,m_ead,m_figs.m_d1,m_figs.m_dc)); |
| 815 | LOG(("uPD7220 line check: %d %d %02x %08x %d %d %d\n",x,y,m_figs.m_dir,m_ead,m_figs.m_d1,m_figs.m_dc,m_bitmap_mod)); |
| 801 | 816 | |
| 802 | 817 | line_size = m_figs.m_dc; |
| 803 | 818 | |
| r241347 | r241348 | |
| 815 | 830 | x += (line_step*line_x_step[m_figs.m_dir]); |
| 816 | 831 | y += (line_step*line_y_step[m_figs.m_dir]); |
| 817 | 832 | |
| 818 | | m_ead = (x >> 4) + (y * m_pitch); |
| 833 | m_ead = (x >> 4) + (y * (m_pitch >> m_figs.m_gd)); |
| 819 | 834 | m_dad = x & 0x0f; |
| 820 | 835 | } |
| 821 | 836 | |
| r241347 | r241348 | |
| 880 | 895 | break; |
| 881 | 896 | } |
| 882 | 897 | |
| 883 | | m_ead = (x >> 4) + (y * m_pitch); |
| 898 | m_ead = (x >> 4) + (y * (m_pitch >> m_figs.m_gd)); |
| 884 | 899 | m_dad = x & 0x0f; |
| 885 | 900 | } |
| 886 | 901 | |
| r241347 | r241348 | |
| 935 | 950 | y+=rect_y_dir[rect_dir]; |
| 936 | 951 | } |
| 937 | 952 | |
| 938 | | m_ead = (x >> 4) + (y * m_pitch); |
| 953 | m_ead = (x >> 4) + (y * (m_pitch >> m_figs.m_gd)); |
| 939 | 954 | m_dad = x & 0x0f; |
| 940 | 955 | |
| 941 | 956 | } |
| r241347 | r241348 | |
| 975 | 990 | } |
| 976 | 991 | } |
| 977 | 992 | |
| 978 | | m_ead = (x >> 4) + (y * m_pitch); |
| 993 | m_ead = (x >> 4) + (y * (m_pitch >> m_figs.m_gd)); |
| 979 | 994 | m_dad = (x & 0xf); |
| 980 | 995 | } |
| 981 | 996 | |
| r241347 | r241348 | |
| 1037 | 1052 | { |
| 1038 | 1053 | UINT8 data; |
| 1039 | 1054 | int flag; |
| 1055 | UINT16 eff_pitch = m_pitch >> m_figs.m_gd; |
| 1040 | 1056 | |
| 1041 | 1057 | dequeue(&data, &flag); |
| 1042 | 1058 | |
| r241347 | r241348 | |
| 1203 | 1219 | |
| 1204 | 1220 | m_ead = (upper_addr << 16) | (m_pr[2] << 8) | m_pr[1]; |
| 1205 | 1221 | |
| 1206 | | //LOG(("uPD7220 '%s' EAD: %06x\n", tag(), m_ead)); |
| 1222 | LOG(("uPD7220 '%s' EAD: %06x\n", tag(), m_ead)); |
| 1207 | 1223 | |
| 1208 | 1224 | if(m_param_ptr == 4) |
| 1209 | 1225 | { |
| 1210 | 1226 | m_dad = m_pr[3] >> 4; |
| 1211 | | //LOG(("uPD7220 '%s' DAD: %01x\n", tag(), m_dad)); |
| 1227 | LOG(("uPD7220 '%s' DAD: %01x\n", tag(), m_dad)); |
| 1212 | 1228 | } |
| 1213 | 1229 | } |
| 1214 | 1230 | break; |
| r241347 | r241348 | |
| 1246 | 1262 | |
| 1247 | 1263 | if (m_param_ptr == 3 || (m_param_ptr == 2 && m_cr & 0x10)) |
| 1248 | 1264 | { |
| 1249 | | //printf("%02x = %02x %02x (%c) %04x\n",m_cr,m_pr[2],m_pr[1],m_pr[1],EAD); |
| 1265 | LOG(("%02x = %02x %02x (%c) %06x %04x\n",m_cr,m_pr[2],m_pr[1],m_pr[1]?m_pr[1]:' ',m_ead,m_figs.m_dc)); |
| 1250 | 1266 | fifo_set_direction(FIFO_WRITE); |
| 1251 | 1267 | |
| 1252 | 1268 | write_vram((m_cr & 0x18) >> 3,m_cr & 3); |
| r241347 | r241348 | |
| 1280 | 1296 | m_figs.m_dc = (m_pr[2]) | (m_figs.m_dc & 0x3f00); |
| 1281 | 1297 | |
| 1282 | 1298 | if (m_param_ptr == 4) |
| 1299 | { |
| 1283 | 1300 | m_figs.m_dc = (m_pr[2]) | ((m_pr[3] & 0x3f) << 8); |
| 1301 | m_figs.m_gd = (m_pr[3] & 0x40) && ((m_mode & UPD7220_MODE_DISPLAY_MASK) == UPD7220_MODE_DISPLAY_MIXED); |
| 1302 | } |
| 1284 | 1303 | |
| 1285 | 1304 | if (m_param_ptr == 6) |
| 1286 | 1305 | m_figs.m_d = (m_pr[4]) | ((m_pr[5] & 0x3f) << 8); |
| r241347 | r241348 | |
| 1298 | 1317 | |
| 1299 | 1318 | case COMMAND_FIGD: /* figure draw start */ |
| 1300 | 1319 | if(m_figs.m_figure_type == 0) |
| 1301 | | draw_pixel(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch),m_dad,(m_ra[8]) | (m_ra[9]<<8)); |
| 1320 | draw_pixel(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch),m_dad,(m_ra[8]) | (m_ra[9]<<8)); |
| 1302 | 1321 | else if(m_figs.m_figure_type == 1) |
| 1303 | | draw_line(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch)); |
| 1322 | draw_line(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch)); |
| 1304 | 1323 | else if(m_figs.m_figure_type == 4) |
| 1305 | | draw_arc(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch)); |
| 1324 | draw_arc(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch)); |
| 1306 | 1325 | else if(m_figs.m_figure_type == 8) |
| 1307 | | draw_rectangle(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch)); |
| 1326 | draw_rectangle(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch)); |
| 1308 | 1327 | else |
| 1309 | 1328 | logerror("uPD7220 '%s' Unimplemented command FIGD %02x\n", tag(),m_figs.m_figure_type); |
| 1310 | 1329 | |
| r241347 | r241348 | |
| 1314 | 1333 | |
| 1315 | 1334 | case COMMAND_GCHRD: /* graphics character draw and area filling start */ |
| 1316 | 1335 | if(m_figs.m_figure_type == 2) |
| 1317 | | draw_char(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch)); |
| 1336 | draw_char(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch)); |
| 1318 | 1337 | else |
| 1319 | 1338 | logerror("uPD7220 '%s' Unimplemented command GCHRD %02x\n", tag(),m_figs.m_figure_type); |
| 1320 | 1339 | |
| r241347 | r241348 | |
| 1568 | 1587 | addr = ((sad << 1) & 0x3ffff) + (y * m_pitch * 2); |
| 1569 | 1588 | |
| 1570 | 1589 | if (!m_display_cb.isnull()) |
| 1571 | | draw_graphics_line(bitmap, addr, y + bsy/((m_pitch == 40)+1), wd); |
| 1590 | draw_graphics_line(bitmap, addr, y + (bsy >> !im), wd); |
| 1572 | 1591 | } |
| 1573 | 1592 | } |
| 1574 | 1593 | else |
trunk/src/mess/drivers/compis.c
| r241347 | r241348 | |
| 100 | 100 | if (offset < 2) |
| 101 | 101 | return m_crtc->read(space, offset & 0x01); |
| 102 | 102 | else |
| 103 | // monochrome only, hblank? vblank? |
| 104 | if(offset == 2) |
| 105 | { |
| 106 | switch(m_unk_video) |
| 107 | { |
| 108 | case 0x04: |
| 109 | m_unk_video = 0x44; |
| 110 | break; |
| 111 | case 0x44: |
| 112 | m_unk_video = 0x64; |
| 113 | break; |
| 114 | default: |
| 115 | m_unk_video = 0x04; |
| 116 | break; |
| 117 | } |
| 118 | return m_unk_video; |
| 119 | } |
| 120 | else |
| 103 | 121 | return 0; |
| 104 | 122 | } |
| 105 | 123 | else |
| r241347 | r241348 | |
| 115 | 133 | { |
| 116 | 134 | if (ACCESSING_BITS_0_7) |
| 117 | 135 | { |
| 136 | // 0x336 is likely the color plane register |
| 118 | 137 | if (offset < 2) m_crtc->write(space, offset & 0x01, data); |
| 138 | |
| 119 | 139 | } |
| 120 | 140 | else |
| 121 | 141 | { |
| r241347 | r241348 | |
| 221 | 241 | } |
| 222 | 242 | |
| 223 | 243 | |
| 224 | | //------------------------------------------------- |
| 225 | | // vram_r - |
| 226 | | //------------------------------------------------- |
| 227 | | |
| 228 | | READ8_MEMBER( compis_state::vram_r ) |
| 229 | | { |
| 230 | | return m_video_ram[offset]; |
| 231 | | } |
| 232 | | |
| 233 | | |
| 234 | | //------------------------------------------------- |
| 235 | | // vram_w - |
| 236 | | //------------------------------------------------- |
| 237 | | |
| 238 | | WRITE8_MEMBER( compis_state::vram_w ) |
| 239 | | { |
| 240 | | m_video_ram[offset] = data; |
| 241 | | } |
| 242 | | |
| 243 | | |
| 244 | | |
| 245 | 244 | //************************************************************************** |
| 246 | 245 | // ADDRESS MAPS |
| 247 | 246 | //************************************************************************** |
| r241347 | r241348 | |
| 253 | 252 | static ADDRESS_MAP_START( compis_mem, AS_PROGRAM, 16, compis_state ) |
| 254 | 253 | ADDRESS_MAP_UNMAP_HIGH |
| 255 | 254 | AM_RANGE(0x00000, 0x1ffff) AM_RAM |
| 256 | | AM_RANGE(0x40000, 0x5ffff) AM_READWRITE8(vram_r, vram_w, 0xffff) |
| 257 | 255 | AM_RANGE(0x60000, 0x63fff) AM_MIRROR(0x1c000) AM_DEVICE(I80130_TAG, i80130_device, rom_map) |
| 258 | 256 | AM_RANGE(0xe0000, 0xeffff) AM_MIRROR(0x10000) AM_ROM AM_REGION(I80186_TAG, 0) |
| 259 | 257 | ADDRESS_MAP_END |
| r241347 | r241348 | |
| 265 | 263 | |
| 266 | 264 | static ADDRESS_MAP_START( compis2_mem, AS_PROGRAM, 16, compis_state ) |
| 267 | 265 | ADDRESS_MAP_UNMAP_HIGH |
| 268 | | AM_RANGE(0x00000, 0x3ffff) AM_RAM |
| 269 | | AM_RANGE(0x40000, 0x5ffff) AM_READWRITE8(vram_r, vram_w, 0xffff) |
| 270 | | AM_RANGE(0x60000, 0xbffff) AM_RAM |
| 266 | AM_RANGE(0x00000, 0xbffff) AM_RAM |
| 271 | 267 | AM_RANGE(0xe0000, 0xeffff) AM_MIRROR(0x10000) AM_ROM AM_REGION(I80186_TAG, 0) |
| 272 | 268 | ADDRESS_MAP_END |
| 273 | 269 | |
| r241347 | r241348 | |
| 317 | 313 | //------------------------------------------------- |
| 318 | 314 | |
| 319 | 315 | static ADDRESS_MAP_START( upd7220_map, AS_0, 8, compis_state ) |
| 320 | | ADDRESS_MAP_GLOBAL_MASK(0x1ffff) |
| 321 | | AM_RANGE(0x00000, 0x1ffff) AM_RAM AM_SHARE("video_ram") |
| 316 | ADDRESS_MAP_GLOBAL_MASK(0x7fff) |
| 317 | AM_RANGE(0x00000, 0x7fff) AM_RAM AM_SHARE("video_ram") |
| 322 | 318 | ADDRESS_MAP_END |
| 323 | 319 | |
| 324 | 320 | |
| r241347 | r241348 | |
| 455 | 451 | |
| 456 | 452 | UPD7220_DISPLAY_PIXELS_MEMBER( compis_state::hgdc_display_pixels ) |
| 457 | 453 | { |
| 458 | | UINT8 i,gfx = m_video_ram[address]; |
| 454 | UINT8 i,gfx = m_video_ram[(address & 0x7fff)]; |
| 459 | 455 | const pen_t *pen = m_palette->pens(); |
| 460 | 456 | |
| 461 | 457 | for(i=0; i<8; i++) |
| 462 | | bitmap.pix32(y, x + i) = pen[BIT(gfx, i)]; |
| 458 | bitmap.pix32(y, x + i) = pen[BIT(gfx, 7 - i)]; |
| 463 | 459 | } |
| 464 | 460 | |
| 465 | 461 | |