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 | |