src/mess/video/upd7220.c
| r6013 | r6014 | |
| 149 | 149 | |
| 150 | 150 | UINT8 sr; /* status register */ |
| 151 | 151 | UINT8 cr; /* command register */ |
| 152 | | UINT8 pr[16]; /* parameter byte register */ |
| 152 | UINT8 pr[17]; /* parameter byte register */ |
| 153 | 153 | int param_ptr; /* parameter pointer */ |
| 154 | 154 | |
| 155 | 155 | UINT8 fifo[16]; /* FIFO data queue */ |
| r6013 | r6014 | |
| 195 | 195 | { |
| 196 | 196 | assert(device != NULL); |
| 197 | 197 | assert(device->token != NULL); |
| 198 | assert((device->type == UPD7220)); |
| 198 | 199 | return (upd7220_t *)device->token; |
| 199 | 200 | } |
| 200 | 201 | |
| r6013 | r6014 | |
| 215 | 216 | upd7220->fifo_flag[i] = FIFO_EMPTY; |
| 216 | 217 | } |
| 217 | 218 | |
| 218 | | upd7220->fifo_ptr = 0; |
| 219 | upd7220->fifo_ptr = -1; |
| 219 | 220 | |
| 220 | 221 | upd7220->sr &= ~UPD7220_SR_DATA_READY; |
| 221 | 222 | upd7220->sr |= UPD7220_SR_FIFO_EMPTY; |
| r6013 | r6014 | |
| 246 | 247 | |
| 247 | 248 | INLINE void queue(upd7220_t *upd7220, UINT8 data, int flag) |
| 248 | 249 | { |
| 249 | | if (upd7220->fifo_ptr < 16) |
| 250 | if (upd7220->fifo_ptr < 15) |
| 250 | 251 | { |
| 252 | upd7220->fifo_ptr++; |
| 253 | |
| 251 | 254 | upd7220->fifo[upd7220->fifo_ptr] = data; |
| 252 | 255 | upd7220->fifo_flag[upd7220->fifo_ptr] = flag; |
| 253 | 256 | |
| 254 | | upd7220->fifo_ptr++; |
| 255 | | |
| 256 | 257 | if (upd7220->fifo_ptr == 16) |
| 257 | 258 | { |
| 258 | 259 | upd7220->sr |= UPD7220_SR_FIFO_FULL; |
| r6013 | r6014 | |
| 411 | 412 | { |
| 412 | 413 | upd7220_t *upd7220 = get_safe_token(device); |
| 413 | 414 | |
| 414 | | int horiz_pix_total = upd7220->hs + upd7220->hbp + upd7220->aw + upd7220->hfp; |
| 415 | int horiz_pix_total = (upd7220->hs + upd7220->hbp + upd7220->aw + upd7220->hfp) * 16; |
| 415 | 416 | int vert_pix_total = upd7220->vs + upd7220->vbp + upd7220->al + upd7220->vfp; |
| 416 | 417 | |
| 417 | | attoseconds_t refresh = HZ_TO_ATTOSECONDS(upd7220->clock) / horiz_pix_total / vert_pix_total; |
| 418 | attoseconds_t refresh = HZ_TO_ATTOSECONDS(device->clock) * horiz_pix_total * vert_pix_total; |
| 418 | 419 | |
| 419 | 420 | rectangle visarea; |
| 420 | 421 | |
| 421 | | visarea.min_x = upd7220->hs + upd7220->hbp; |
| 422 | visarea.min_x = (upd7220->hs + upd7220->hbp) * 16; |
| 422 | 423 | visarea.min_y = upd7220->vs + upd7220->vbp; |
| 423 | | visarea.max_x = horiz_pix_total - upd7220->hfp - 1; |
| 424 | visarea.max_x = horiz_pix_total - (upd7220->hfp * 16) - 1; |
| 424 | 425 | visarea.max_y = vert_pix_total - upd7220->vfp - 1; |
| 425 | 426 | |
| 426 | 427 | if (LOG) |
| 427 | 428 | { |
| 428 | | logerror("uPD7220 '%s' Screen: width %u height x %u\n", device->tag, horiz_pix_total, vert_pix_total); |
| 429 | logerror("uPD7220 '%s' Screen: width %u height %u refresh %f\n", device->tag, horiz_pix_total, vert_pix_total, 1 / ATTOSECONDS_TO_DOUBLE(refresh)); |
| 429 | 430 | logerror("uPD7220 '%s' Visible Area: (%u, %u) - (%u, %u)\n", device->tag, visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y); |
| 430 | 431 | } |
| 431 | 432 | |
| r6013 | r6014 | |
| 554 | 555 | switch (data & 0xf0) |
| 555 | 556 | { |
| 556 | 557 | case UPD7220_COMMAND_PRAM: |
| 558 | command = COMMAND_PRAM; |
| 559 | break; |
| 557 | 560 | default: |
| 558 | 561 | switch (data & 0xe4) |
| 559 | 562 | { |
| r6013 | r6014 | |
| 592 | 595 | if (flag == FIFO_COMMAND) |
| 593 | 596 | { |
| 594 | 597 | upd7220->cr = data; |
| 595 | | upd7220->param_ptr = 0; |
| 598 | upd7220->param_ptr = 1; |
| 596 | 599 | } |
| 597 | 600 | else |
| 598 | 601 | { |
| r6013 | r6014 | |
| 607 | 610 | break; |
| 608 | 611 | |
| 609 | 612 | case COMMAND_RESET: /* reset */ |
| 610 | | if (LOG) logerror("uPD7220 '%s' RESET\n", device->tag); |
| 611 | | |
| 612 | 613 | switch (upd7220->param_ptr) |
| 613 | 614 | { |
| 614 | 615 | case 0: |
| 616 | if (LOG) logerror("uPD7220 '%s' RESET\n", device->tag); |
| 617 | |
| 615 | 618 | upd7220->de = 0; |
| 616 | 619 | upd7220->ra[0] = upd7220->ra[1] = upd7220->ra[2] = 0; |
| 617 | 620 | upd7220->ra[3] = 0x19; |
| r6013 | r6014 | |
| 620 | 623 | upd7220->mask = 0; |
| 621 | 624 | break; |
| 622 | 625 | |
| 623 | | case 8: |
| 626 | case 9: |
| 624 | 627 | upd7220->mode = upd7220->pr[1]; |
| 625 | 628 | upd7220->aw = upd7220->pr[2] + 2; |
| 626 | 629 | upd7220->hs = (upd7220->pr[3] & 0x1f) + 1; |
| 627 | | upd7220->vs = ((upd7220->pr[4] & 0x03) << 2) | (upd7220->pr[3] >> 5); |
| 630 | upd7220->vs = ((upd7220->pr[4] & 0x03) << 3) | (upd7220->pr[3] >> 5); |
| 628 | 631 | upd7220->hfp = (upd7220->pr[4] >> 2) + 1; |
| 629 | 632 | upd7220->hbp = (upd7220->pr[5] & 0x3f) + 1; |
| 630 | 633 | upd7220->vfp = upd7220->pr[6] & 0x3f; |
| 631 | | upd7220->al = ((upd7220->pr[8] & 0x03) << 8) | upd7220->pr[7]; |
| 634 | upd7220->al = ((upd7220->pr[8] & 0x03) << 8) | upd7220->pr[7]; // TODO wrong! |
| 632 | 635 | upd7220->vbp = upd7220->pr[8] >> 2; |
| 633 | 636 | |
| 634 | 637 | upd7220->pitch = upd7220->aw; |
| 635 | 638 | |
| 639 | if (LOG) |
| 640 | { |
| 641 | logerror("uPD7220 '%s' Mode: %02x\n", device->tag, upd7220->mode); |
| 642 | logerror("uPD7220 '%s' AW: %u\n", device->tag, upd7220->aw); |
| 643 | logerror("uPD7220 '%s' HS: %u\n", device->tag, upd7220->hs); |
| 644 | logerror("uPD7220 '%s' VS: %u\n", device->tag, upd7220->vs); |
| 645 | logerror("uPD7220 '%s' HFP: %u\n", device->tag, upd7220->hfp); |
| 646 | logerror("uPD7220 '%s' HBP: %u\n", device->tag, upd7220->hbp); |
| 647 | logerror("uPD7220 '%s' VFP: %u\n", device->tag, upd7220->vfp); |
| 648 | logerror("uPD7220 '%s' AL: %u\n", device->tag, upd7220->al); |
| 649 | logerror("uPD7220 '%s' VBP: %u\n", device->tag, upd7220->vbp); |
| 650 | logerror("uPD7220 '%s' PITCH: %u\n", device->tag, upd7220->pitch); |
| 651 | } |
| 652 | |
| 636 | 653 | recompute_parameters(device); |
| 637 | 654 | break; |
| 638 | 655 | } |
| 639 | 656 | break; |
| 640 | 657 | |
| 641 | 658 | case COMMAND_SYNC: /* sync format specify */ |
| 642 | | if (upd7220->param_ptr == 8) |
| 659 | if (upd7220->param_ptr == 9) |
| 643 | 660 | { |
| 644 | 661 | upd7220->mode = upd7220->pr[1]; |
| 645 | 662 | upd7220->aw = upd7220->pr[2] + 2; |
| 646 | 663 | upd7220->hs = (upd7220->pr[3] & 0x1f) + 1; |
| 647 | | upd7220->vs = ((upd7220->pr[4] & 0x03) << 2) | (upd7220->pr[3] >> 5); |
| 664 | upd7220->vs = ((upd7220->pr[4] & 0x03) << 3) | (upd7220->pr[3] >> 5); |
| 648 | 665 | upd7220->hfp = (upd7220->pr[4] >> 2) + 1; |
| 649 | 666 | upd7220->hbp = (upd7220->pr[5] & 0x3f) + 1; |
| 650 | 667 | upd7220->vfp = upd7220->pr[6] & 0x3f; |
| r6013 | r6014 | |
| 653 | 670 | |
| 654 | 671 | upd7220->pitch = upd7220->aw; |
| 655 | 672 | |
| 673 | if (LOG) |
| 674 | { |
| 675 | logerror("uPD7220 '%s' Mode: %02x\n", device->tag, upd7220->mode); |
| 676 | logerror("uPD7220 '%s' AW: %u\n", device->tag, upd7220->aw); |
| 677 | logerror("uPD7220 '%s' HS: %u\n", device->tag, upd7220->hs); |
| 678 | logerror("uPD7220 '%s' VS: %u\n", device->tag, upd7220->vs); |
| 679 | logerror("uPD7220 '%s' HFP: %u\n", device->tag, upd7220->hfp); |
| 680 | logerror("uPD7220 '%s' HBP: %u\n", device->tag, upd7220->hbp); |
| 681 | logerror("uPD7220 '%s' VFP: %u\n", device->tag, upd7220->vfp); |
| 682 | logerror("uPD7220 '%s' AL: %u\n", device->tag, upd7220->al); |
| 683 | logerror("uPD7220 '%s' VBP: %u\n", device->tag, upd7220->vbp); |
| 684 | logerror("uPD7220 '%s' PITCH: %u\n", device->tag, upd7220->pitch); |
| 685 | } |
| 686 | |
| 656 | 687 | recompute_parameters(device); |
| 657 | 688 | } |
| 658 | 689 | break; |
| r6013 | r6014 | |
| 666 | 697 | break; |
| 667 | 698 | |
| 668 | 699 | case COMMAND_CCHAR: /* cursor & character characteristics */ |
| 669 | | if (upd7220->param_ptr == 3) |
| 700 | if (upd7220->param_ptr == 4) |
| 670 | 701 | { |
| 671 | 702 | upd7220->lr = (upd7220->pr[1] & 0x1f) + 1; |
| 672 | 703 | upd7220->dc = BIT(upd7220->pr[1], 7); |
| r6013 | r6014 | |
| 701 | 732 | break; |
| 702 | 733 | |
| 703 | 734 | case COMMAND_CURS: /* cursor position specify */ |
| 704 | | if (upd7220->param_ptr == 3) |
| 735 | if (upd7220->param_ptr == 4) |
| 705 | 736 | { |
| 706 | 737 | upd7220->ead = ((upd7220->pr[3] & 0x03) << 16) | (upd7220->pr[2] << 8) | upd7220->pr[1]; |
| 707 | 738 | upd7220->dad = upd7220->pr[3] >> 4; |
| r6013 | r6014 | |
| 735 | 766 | { |
| 736 | 767 | upd7220->pitch = data; |
| 737 | 768 | |
| 738 | | if (LOG) logerror("uPD7220 '%s' PITCH: %02x\n", device->tag, upd7220->pitch); |
| 769 | if (LOG) logerror("uPD7220 '%s' PITCH: %u\n", device->tag, upd7220->pitch); |
| 739 | 770 | } |
| 740 | 771 | break; |
| 741 | 772 | |
| r6013 | r6014 | |
| 749 | 780 | break; |
| 750 | 781 | |
| 751 | 782 | case COMMAND_MASK: /* mask register load */ |
| 752 | | if (upd7220->param_ptr == 2) |
| 783 | if (upd7220->param_ptr == 3) |
| 753 | 784 | { |
| 754 | 785 | upd7220->mask = (upd7220->pr[2] << 8) | upd7220->pr[1]; |
| 755 | 786 | |
| r6013 | r6014 | |
| 930 | 961 | // int im2 = BIT(upd7220->ra[7], 6); |
| 931 | 962 | int wd2 = BIT(upd7220->ra[7], 7); |
| 932 | 963 | |
| 933 | | int x, y; |
| 964 | int sx, y; |
| 934 | 965 | |
| 935 | 966 | /* display partition area 1 */ |
| 936 | 967 | for (y = 0; y < len1; y++) |
| 937 | 968 | { |
| 938 | 969 | UINT32 addr = sad1 + (y * upd7220->pitch); |
| 939 | 970 | |
| 940 | | for (x = 0; x < (upd7220->aw + 2); x += 16) |
| 971 | for (sx = 0; sx < upd7220->aw; sx++) |
| 941 | 972 | { |
| 942 | | UINT16 data = memory_raw_read_word(upd7220->vram, addr & 0x3ffff); |
| 943 | | upd7220->display_func(device, bitmap, y, x, addr, data); |
| 973 | UINT16 data = memory_raw_read_word(device->space[0], addr & 0x3ffff); |
| 974 | upd7220->display_func(device, bitmap, y, sx << 4, addr, data); |
| 944 | 975 | if (wd1) addr += 2; else addr++; |
| 945 | 976 | } |
| 946 | 977 | } |
| r6013 | r6014 | |
| 950 | 981 | { |
| 951 | 982 | UINT32 addr = sad2 + (y * upd7220->pitch); |
| 952 | 983 | |
| 953 | | for (x = 0; x < (upd7220->aw + 2); x += 16) |
| 984 | for (sx = 0; sx < upd7220->aw; sx++) |
| 954 | 985 | { |
| 955 | | UINT16 data = memory_raw_read_word(upd7220->vram, addr); |
| 956 | | upd7220->display_func(device, bitmap, y, x, addr, data); |
| 986 | UINT16 data = memory_raw_read_word(device->space[0], addr); |
| 987 | upd7220->display_func(device, bitmap, y, sx << 4, addr, data); |
| 957 | 988 | if (wd2) addr += 2; else addr++; |
| 958 | 989 | } |
| 959 | 990 | } |
| r6013 | r6014 | |
| 965 | 996 | |
| 966 | 997 | void upd7220_update(const device_config *device, bitmap_t *bitmap, const rectangle *cliprect) |
| 967 | 998 | { |
| 968 | | // TODO check mode |
| 969 | | update_graphics(device, bitmap, cliprect); |
| 999 | upd7220_t *upd7220 = get_safe_token(device); |
| 1000 | |
| 1001 | if (upd7220->de) |
| 1002 | { |
| 1003 | // TODO check mode |
| 1004 | update_graphics(device, bitmap, cliprect); |
| 1005 | } |
| 970 | 1006 | } |
| 971 | 1007 | |
| 972 | 1008 | /*------------------------------------------------- |
| r6013 | r6014 | |
| 1015 | 1051 | upd7220->blank_timer = timer_alloc(device->machine, blank_tick, (void *)device); |
| 1016 | 1052 | |
| 1017 | 1053 | /* set initial values */ |
| 1054 | upd7220->fifo_ptr = -1; |
| 1018 | 1055 | upd7220->sr = UPD7220_SR_FIFO_EMPTY; |
| 1019 | 1056 | |
| 1020 | 1057 | for (i = 0; i < 16; i++) |
| r6013 | r6014 | |
| 1076 | 1113 | case DEVINFO_INT_DATABUS_WIDTH_0: info->i = 16; break; |
| 1077 | 1114 | case DEVINFO_INT_ADDRBUS_WIDTH_0: info->i = 18; break; |
| 1078 | 1115 | case DEVINFO_INT_ADDRBUS_SHIFT_0: info->i = 0; break; |
| 1079 | | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break; |
| 1080 | 1116 | case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break; |
| 1081 | 1117 | |
| 1082 | 1118 | /* --- the following bits of info are returned as pointers --- */ |
src/mess/drivers/mikromik.c
| r6013 | r6014 | |
| 16 | 16 | |
| 17 | 17 | TODO: |
| 18 | 18 | |
| 19 | | - floppy access violation |
| 20 | 19 | - add HRTC/VRTC output to i8275 |
| 21 | 20 | - NEC uPD7220 GDC |
| 22 | 21 | - accurate video timing |
| r6013 | r6014 | |
| 131 | 130 | AM_RANGE(0x0000, 0x0fff) AM_RAMBANK(1) |
| 132 | 131 | AM_RANGE(0x1000, 0xfeff) AM_RAM |
| 133 | 132 | AM_RANGE(0xff00, 0xff0f) AM_MIRROR(0x80) AM_DEVREADWRITE(I8237_TAG, dma8237_r, dma8237_w) |
| 134 | | AM_RANGE(0xff10, 0xff13) AM_MIRROR(0x8c) AM_DEVREADWRITE(UPD7201_TAG, upd7201_cd_ba_r, upd7201_cd_ba_w) |
| 133 | // AM_RANGE(0xff10, 0xff13) AM_MIRROR(0x8c) AM_DEVREADWRITE(UPD7201_TAG, upd7201_cd_ba_r, upd7201_cd_ba_w) |
| 135 | 134 | AM_RANGE(0xff20, 0xff21) AM_MIRROR(0x8e) AM_DEVREADWRITE(I8275_TAG, i8275_r, i8275_w) |
| 136 | 135 | AM_RANGE(0xff30, 0xff33) AM_MIRROR(0x8c) AM_DEVREADWRITE(I8253_TAG, pit8253_r, pit8253_w) |
| 137 | 136 | AM_RANGE(0xff40, 0xff40) AM_MIRROR(0x8f) AM_DEVREADWRITE(I8212_TAG, i8212_r, i8212_w) |
| r6013 | r6014 | |
| 323 | 322 | |
| 324 | 323 | for (i = 0; i < 16; i++) |
| 325 | 324 | { |
| 326 | | int color = BIT(data, i); |
| 327 | | |
| 328 | | *BITMAP_ADDR16(bitmap, y, x + i) = color; |
| 325 | if (BIT(data, i)) *BITMAP_ADDR16(bitmap, y, x + i) = 1; |
| 329 | 326 | } |
| 330 | 327 | } |
| 331 | 328 | |
| r6013 | r6014 | |
| 358 | 355 | copybitmap(bitmap, tmpbitmap, 0, 0, 0, 0, cliprect); |
| 359 | 356 | |
| 360 | 357 | /* graphics */ |
| 361 | | //upd7220_update(state->i8275, bitmap, cliprect); |
| 358 | upd7220_update(state->upd7220, bitmap, cliprect); |
| 362 | 359 | |
| 363 | 360 | return 0; |
| 364 | 361 | } |
| r6013 | r6014 | |
| 804 | 801 | |
| 805 | 802 | /* basic system hardware */ |
| 806 | 803 | MDRV_CPU_MODIFY(I8085A_TAG) |
| 807 | | MDRV_CPU_PROGRAM_MAP(mm1_map) |
| 804 | MDRV_CPU_PROGRAM_MAP(mm1m6_map) |
| 808 | 805 | |
| 809 | 806 | /* video hardware */ |
| 810 | 807 | MDRV_UPD7220_ADD(UPD7220_TAG, XTAL_18_720MHz/8, mm1_upd7220_intf, mm1_upd7220_map) |