src/mame/drivers/megadriv.c
| r9408 | r9409 | |
| 3996 | 3996 | |
| 3997 | 3997 | 0 = Main CPU Accesses WordRam0 (1st Half of WordRAM) |
| 3998 | 3998 | Sub CPU Accesses WordRam1 (2nd Half of WordRAM) |
| 3999 | | |
| 3999 | |
| 4000 | 4000 | 1 = Main CPU Accesses WordRam1 (2nd Half of WordRAM) |
| 4001 | 4001 | Sub CPU Accesses WordRam0 (1st Half of WordRAM) |
| 4002 | | |
| 4002 | |
| 4003 | 4003 | DMNA |
| 4004 | 4004 | |
| 4005 | 4005 | Setting this bis sends a Swap request to the SUB-CPU (Main CPU access only?) |
| r9408 | r9409 | |
| 4023 | 4023 | //printf("dmna set (swap requested)\n"); // give ram to sub? |
| 4024 | 4024 | |
| 4025 | 4025 | // this should take some time? |
| 4026 | | |
| 4026 | |
| 4027 | 4027 | //segacd_ret = 1; |
| 4028 | 4028 | |
| 4029 | | //printf("main cpu dmna set dmna: %d ret: %d\n", segacd_dmna, segacd_ret); |
| 4029 | //printf("main cpu dmna set dmna: %d ret: %d\n", segacd_dmna, segacd_ret); |
| 4030 | 4030 | if (segacd_ram_mode==0) |
| 4031 | 4031 | { |
| 4032 | 4032 | if (!timer_enabled(segacd_dmna_ret_timer)) |
| r9408 | r9409 | |
| 4091 | 4091 | { |
| 4092 | 4092 | //printf("ret bit set\n"); |
| 4093 | 4093 | //segacd_dmna = 0; |
| 4094 | | |
| 4095 | 4094 | |
| 4096 | | //printf("sub cpu ret set dmna: %d ret: %d\n", segacd_dmna, segacd_ret); |
| 4097 | 4095 | |
| 4096 | //printf("sub cpu ret set dmna: %d ret: %d\n", segacd_dmna, segacd_ret); |
| 4097 | |
| 4098 | 4098 | if (segacd_ram_mode==0) |
| 4099 | 4099 | { |
| 4100 | 4100 | if (!timer_enabled(segacd_dmna_ret_timer)) |
| r9408 | r9409 | |
| 4448 | 4448 | } |
| 4449 | 4449 | else |
| 4450 | 4450 | { |
| 4451 | | printf("Unspported: segacd_main_dataram_part1_r (Cell rearranged RAM) in mode 1\n"); |
| 4451 | printf("Unspported: segacd_main_dataram_part1_r (Cell rearranged RAM) in mode 1\n"); |
| 4452 | 4452 | return 0x0000; |
| 4453 | | } |
| 4453 | } |
| 4454 | 4454 | } |
| 4455 | 4455 | |
| 4456 | 4456 | return 0x0000; |
| r9408 | r9409 | |
| 4470 | 4470 | { |
| 4471 | 4471 | printf("Illegal: segacd_main_dataram_part1_w in mode 0 without permission\n"); |
| 4472 | 4472 | } |
| 4473 | | |
| 4473 | |
| 4474 | 4474 | } |
| 4475 | 4475 | else if (segacd_ram_mode==1) |
| 4476 | 4476 | { |
| r9408 | r9409 | |
| 4478 | 4478 | { |
| 4479 | 4479 | //printf("Unspported: segacd_main_dataram_part1_w (word RAM) in mode 1\n"); |
| 4480 | 4480 | // wordram accees |
| 4481 | | |
| 4481 | |
| 4482 | 4482 | // ret bit set by sub cpu determines which half of WorkRAM we have access to? |
| 4483 | 4483 | if (segacd_ret) |
| 4484 | 4484 | { |
| r9408 | r9409 | |
| 4492 | 4492 | else |
| 4493 | 4493 | { |
| 4494 | 4494 | printf("Unspported: segacd_main_dataram_part1_w (Cell rearranged RAM) in mode 1 (illega?)\n"); // is this legal?? |
| 4495 | | } |
| 4495 | } |
| 4496 | 4496 | } |
| 4497 | 4497 | } |
| 4498 | 4498 | |
| r9408 | r9409 | |
| 4857 | 4857 | { |
| 4858 | 4858 | const int tilesize = 4; // 0xf pixels |
| 4859 | 4859 | const int tilemapsize = 0x0f; |
| 4860 | | |
| 4860 | |
| 4861 | 4861 | int wraparound = segacd_stampsize&1; |
| 4862 | | |
| 4862 | |
| 4863 | 4863 | int xtile = xpos / (1<<tilesize); |
| 4864 | 4864 | int ytile = ypos / (1<<tilesize); |
| 4865 | 4865 | |
| r9408 | r9409 | |
| 4873 | 4873 | { |
| 4874 | 4874 | if (xtile>tilemapsize) return 0; |
| 4875 | 4875 | if (xtile<0) return 0; |
| 4876 | | |
| 4876 | |
| 4877 | 4877 | if (ytile>tilemapsize) return 0; |
| 4878 | 4878 | if (ytile<0) return 0; |
| 4879 | 4879 | } |
| r9408 | r9409 | |
| 4893 | 4893 | { |
| 4894 | 4894 | const int tilesize = 5; // 0x1f pixels |
| 4895 | 4895 | const int tilemapsize = 0x07; |
| 4896 | | |
| 4896 | |
| 4897 | 4897 | int wraparound = segacd_stampsize&1; |
| 4898 | | |
| 4898 | |
| 4899 | 4899 | int xtile = xpos / (1<<tilesize); |
| 4900 | 4900 | int ytile = ypos / (1<<tilesize); |
| 4901 | 4901 | |
| r9408 | r9409 | |
| 4909 | 4909 | { |
| 4910 | 4910 | if (xtile>tilemapsize) return 0; |
| 4911 | 4911 | if (xtile<0) return 0; |
| 4912 | | |
| 4912 | |
| 4913 | 4913 | if (ytile>tilemapsize) return 0; |
| 4914 | 4914 | if (ytile<0) return 0; |
| 4915 | 4915 | } |
| 4916 | | |
| 4916 | |
| 4917 | 4917 | int tile_index = (ytile * (tilemapsize+1)) + xtile; |
| 4918 | | |
| 4918 | |
| 4919 | 4919 | int tile_region, tileno; |
| 4920 | 4920 | SCD_GET_TILE_INFO_32x32_1x1(tile_region,tileno,(int)tile_index); |
| 4921 | 4921 | |
| r9408 | r9409 | |
| 4929 | 4929 | { |
| 4930 | 4930 | const int tilesize = 4; // 0xf pixels |
| 4931 | 4931 | const int tilemapsize = 0xff; |
| 4932 | | |
| 4932 | |
| 4933 | 4933 | int wraparound = segacd_stampsize&1; |
| 4934 | | |
| 4934 | |
| 4935 | 4935 | int xtile = xpos / (1<<tilesize); |
| 4936 | 4936 | int ytile = ypos / (1<<tilesize); |
| 4937 | 4937 | |
| r9408 | r9409 | |
| 4945 | 4945 | { |
| 4946 | 4946 | if (xtile>tilemapsize) return 0; |
| 4947 | 4947 | if (xtile<0) return 0; |
| 4948 | | |
| 4948 | |
| 4949 | 4949 | if (ytile>tilemapsize) return 0; |
| 4950 | 4950 | if (ytile<0) return 0; |
| 4951 | 4951 | } |
| r9408 | r9409 | |
| 4965 | 4965 | { |
| 4966 | 4966 | const int tilesize = 5; // 0x1f pixels |
| 4967 | 4967 | const int tilemapsize = 0x7f; |
| 4968 | | |
| 4968 | |
| 4969 | 4969 | int wraparound = segacd_stampsize&1; |
| 4970 | | |
| 4970 | |
| 4971 | 4971 | int xtile = xpos / (1<<tilesize); |
| 4972 | 4972 | int ytile = ypos / (1<<tilesize); |
| 4973 | 4973 | |
| r9408 | r9409 | |
| 4981 | 4981 | { |
| 4982 | 4982 | if (xtile>tilemapsize) return 0; |
| 4983 | 4983 | if (xtile<0) return 0; |
| 4984 | | |
| 4984 | |
| 4985 | 4985 | if (ytile>tilemapsize) return 0; |
| 4986 | 4986 | if (ytile<0) return 0; |
| 4987 | 4987 | } |
| 4988 | | |
| 4988 | |
| 4989 | 4989 | int tile_index = (ytile * (tilemapsize+1)) + xtile; |
| 4990 | | |
| 4990 | |
| 4991 | 4991 | int tile_region, tileno; |
| 4992 | 4992 | SCD_GET_TILE_INFO_32x32_16x16(tile_region,tileno,(int)tile_index); |
| 4993 | 4993 | |
| r9408 | r9409 | |
| 5259 | 5259 | } |
| 5260 | 5260 | } |
| 5261 | 5261 | |
| 5262 | | static void cdd_hock_irq(running_machine *machine,UINT8 dir) |
| 5262 | static TIMER_CALLBACK( execute_hock_irq ) |
| 5263 | 5263 | { |
| 5264 | 5264 | int i,cdd_crc; |
| 5265 | 5265 | |
| 5266 | | if((segacd_cdd.ctrl & 4 || dir) && segacd_irq_mask & 0x10) // export status, check if bit 2 (HOst ClocK) and irq is enabled |
| 5267 | | { |
| 5268 | | // TODO: this shouldn't be instant, CDD should first fill receive data. |
| 5269 | | segacd_cdd.ctrl &= 0x103; // clear HOCK flag |
| 5266 | segacd_cdd.ctrl &= ~4; // clear HOCK flag |
| 5270 | 5267 | |
| 5271 | | segacd_cdd_rx[0] = (segacd_cdd.status & 0xf0) >> 4; |
| 5272 | | segacd_cdd_rx[1] = (segacd_cdd.status & 0x0f) >> 0; |
| 5273 | | segacd_cdd_rx[2] = (segacd_cdd.minute & 0xf0) >> 4; |
| 5274 | | segacd_cdd_rx[3] = (segacd_cdd.minute & 0x0f) >> 0; |
| 5275 | | segacd_cdd_rx[4] = (segacd_cdd.seconds & 0xf0) >> 4; |
| 5276 | | segacd_cdd_rx[5] = (segacd_cdd.seconds & 0x0f) >> 0; |
| 5277 | | segacd_cdd_rx[6] = (segacd_cdd.frame & 0xf0) >> 4; |
| 5278 | | segacd_cdd_rx[7] = (segacd_cdd.frame & 0x0f) >> 0; |
| 5279 | | segacd_cdd_rx[8] = (segacd_cdd.ext & 0x0f) >> 0; |
| 5268 | segacd_cdd_rx[0] = (segacd_cdd.status & 0xf0) >> 4; |
| 5269 | segacd_cdd_rx[1] = (segacd_cdd.status & 0x0f) >> 0; |
| 5270 | segacd_cdd_rx[2] = (segacd_cdd.minute & 0xf0) >> 4; |
| 5271 | segacd_cdd_rx[3] = (segacd_cdd.minute & 0x0f) >> 0; |
| 5272 | segacd_cdd_rx[4] = (segacd_cdd.seconds & 0xf0) >> 4; |
| 5273 | segacd_cdd_rx[5] = (segacd_cdd.seconds & 0x0f) >> 0; |
| 5274 | segacd_cdd_rx[6] = (segacd_cdd.frame & 0xf0) >> 4; |
| 5275 | segacd_cdd_rx[7] = (segacd_cdd.frame & 0x0f) >> 0; |
| 5276 | segacd_cdd_rx[8] = (segacd_cdd.ext & 0x0f) >> 0; |
| 5280 | 5277 | |
| 5281 | | /* Do checksum calculation of the above registers */ |
| 5282 | | cdd_crc = 0; |
| 5283 | | for(i=0;i<9;i++) |
| 5284 | | cdd_crc += segacd_cdd_rx[i]; |
| 5278 | /* Do checksum calculation of the above registers */ |
| 5279 | cdd_crc = 0; |
| 5280 | for(i=0;i<9;i++) |
| 5281 | cdd_crc += segacd_cdd_rx[i]; |
| 5285 | 5282 | |
| 5286 | | segacd_cdd_rx[9] = ((cdd_crc & 0xf) ^ 0xf); |
| 5283 | segacd_cdd_rx[9] = ((cdd_crc & 0xf) ^ 0xf); |
| 5287 | 5284 | |
| 5288 | | cputag_set_input_line(machine, "segacd_68k", 4, HOLD_LINE); |
| 5285 | cputag_set_input_line(machine, "segacd_68k", 4, HOLD_LINE); |
| 5286 | } |
| 5287 | |
| 5288 | static void cdd_hock_irq(running_machine *machine,UINT8 dir) |
| 5289 | { |
| 5290 | if((segacd_cdd.ctrl & 4 || dir) && segacd_irq_mask & 0x10) // export status, check if bit 2 (HOst ClocK) and irq is enabled |
| 5291 | { |
| 5292 | segacd_cdd.ctrl |= 4; // enable Hock bit if it isn't already active |
| 5293 | timer_set(machine, ATTOTIME_IN_HZ(75), NULL,0, execute_hock_irq); // 1 / 75th of a second |
| 5289 | 5294 | } |
| 5290 | 5295 | } |
| 5291 | 5296 | |
| r9408 | r9409 | |
| 5363 | 5368 | { |
| 5364 | 5369 | // ... |
| 5365 | 5370 | |
| 5366 | | /*segacd_cdd.status = 0; |
| 5371 | segacd_cdd.status = 0; |
| 5367 | 5372 | segacd_cdd.minute = 0; |
| 5368 | 5373 | segacd_cdd.seconds = 0; |
| 5369 | 5374 | segacd_cdd.frame = 0; |
| 5370 | | segacd_cdd.ext = 0;*/ |
| 5375 | segacd_cdd.ext = 0; |
| 5371 | 5376 | |
| 5372 | 5377 | cdd_hock_irq(machine,1); |
| 5373 | 5378 | } |
| r9408 | r9409 | |
| 5382 | 5387 | segacd_cdd.frame = 0; |
| 5383 | 5388 | segacd_cdd.ext = 0; |
| 5384 | 5389 | |
| 5385 | | //cdd_hock_irq(machine,1); // doesn't work? |
| 5390 | cdd_hock_irq(machine,1); |
| 5386 | 5391 | } |
| 5387 | 5392 | |
| 5388 | 5393 | |
| r9408 | r9409 | |
| 5520 | 5525 | |
| 5521 | 5526 | if (x >= srcbitmap->width) return 0; |
| 5522 | 5527 | if (y >= srcbitmap->height) return 0; |
| 5523 | | |
| 5528 | |
| 5524 | 5529 | UINT16* cacheptr = BITMAP_ADDR16( srcbitmap, y, x); |
| 5525 | 5530 | |
| 5526 | 5531 | return cacheptr[0] & 0xf; |
| r9408 | r9409 | |
| 5533 | 5538 | case 0x02: return get_stampmap_16x16_16x16_tile_info_pixel( machine, x, y ); |
| 5534 | 5539 | case 0x03: return get_stampmap_32x32_16x16_tile_info_pixel( machine, x, y ); |
| 5535 | 5540 | } |
| 5536 | | |
| 5541 | |
| 5537 | 5542 | return 0; |
| 5538 | 5543 | } |
| 5539 | 5544 | |
| r9408 | r9409 | |
| 5545 | 5550 | UINT32 offset; |
| 5546 | 5551 | |
| 5547 | 5552 | offset = bufferstart+(((segacd_imagebuffer_vcell_size+1)*0x10)*xpos); |
| 5548 | | |
| 5553 | |
| 5549 | 5554 | // lines of each output cell |
| 5550 | 5555 | offset+= (line*2); |
| 5551 | | |
| 5556 | |
| 5552 | 5557 | while (offset>=bufferend) |
| 5553 | 5558 | offset-= bufferend; |
| 5554 | | |
| 5555 | | |
| 5559 | |
| 5560 | |
| 5556 | 5561 | switch (segacd_memory_priority_mode) |
| 5557 | 5562 | { |
| 5558 | 5563 | case 0x00: // normal write, just write the data |
| 5559 | 5564 | segacd_dataram[offset] = pix >> 16; |
| 5560 | 5565 | segacd_dataram[offset+1] = pix & 0xffff; |
| 5561 | 5566 | break; |
| 5562 | | |
| 5567 | |
| 5563 | 5568 | case 0x01: // underwrite, only write if the existing data is 0 |
| 5564 | 5569 | if ((segacd_dataram[offset]&0xf000) == 0x0000) segacd_dataram[offset] |= (pix>>16)&0xf000; |
| 5565 | 5570 | if ((segacd_dataram[offset]&0x0f00) == 0x0000) segacd_dataram[offset] |= (pix>>16)&0x0f00; |
| r9408 | r9409 | |
| 5570 | 5575 | if ((segacd_dataram[offset+1]&0x00f0) == 0x0000) segacd_dataram[offset+1] |= (pix)&0x00f0; |
| 5571 | 5576 | if ((segacd_dataram[offset+1]&0x000f) == 0x0000) segacd_dataram[offset+1] |= (pix)&0x000f; |
| 5572 | 5577 | break; |
| 5573 | | |
| 5578 | |
| 5574 | 5579 | case 0x02: // overwrite, only write non-zero data |
| 5575 | 5580 | if ((pix>>16)&0xf000) segacd_dataram[offset] = (segacd_dataram[offset] & 0x0fff) | ((pix>>16)&0xf000); |
| 5576 | 5581 | if ((pix>>16)&0x0f00) segacd_dataram[offset] = (segacd_dataram[offset] & 0xf0ff) | ((pix>>16)&0x0f00); |
| r9408 | r9409 | |
| 5581 | 5586 | if ((pix)&0x00f0) segacd_dataram[offset+1] = (segacd_dataram[offset+1] & 0xff0f) | ((pix)&0x00f0); |
| 5582 | 5587 | if ((pix)&0x000f) segacd_dataram[offset+1] = (segacd_dataram[offset+1] & 0xfff0) | ((pix)&0x000f); |
| 5583 | 5588 | break; |
| 5584 | | |
| 5589 | |
| 5585 | 5590 | default: |
| 5586 | 5591 | case 0x03: // invalid? |
| 5587 | 5592 | segacd_dataram[offset] = mame_rand(machine); |
| 5588 | 5593 | segacd_dataram[offset+1] = mame_rand(machine); |
| 5589 | 5594 | break; |
| 5590 | | |
| 5595 | |
| 5591 | 5596 | } |
| 5592 | | |
| 5597 | |
| 5593 | 5598 | segacd_mark_tiles_dirty(machine, offset); |
| 5594 | 5599 | segacd_mark_tiles_dirty(machine, offset+1); |
| 5595 | 5600 | |
| r9408 | r9409 | |
| 5626 | 5631 | for (line=0;line<segacd_imagebuffer_vdot_size;line++) |
| 5627 | 5632 | { |
| 5628 | 5633 | int currbase = base + line * 0x8; |
| 5629 | | |
| 5634 | |
| 5630 | 5635 | // are the 256x256 tile modes using the same sign bits? |
| 5631 | 5636 | INT16 tilemapxoffs,tilemapyoffs; |
| 5632 | 5637 | INT16 deltax,deltay; |
| 5633 | | |
| 5638 | |
| 5634 | 5639 | tilemapxoffs = segacd_dataram[(currbase+0x0)>>1]; |
| 5635 | 5640 | tilemapyoffs = segacd_dataram[(currbase+0x2)>>1]; |
| 5636 | 5641 | deltax = segacd_dataram[(currbase+0x4)>>1]; // x-zoom |
| r9408 | r9409 | |
| 5641 | 5646 | int xbase = tilemapxoffs * 256; |
| 5642 | 5647 | int ybase = tilemapyoffs * 256; |
| 5643 | 5648 | int count; |
| 5644 | | |
| 5649 | |
| 5645 | 5650 | for (count=0;count<(segacd_imagebuffer_hdot_size>>3);count++) |
| 5646 | 5651 | { |
| 5647 | 5652 | int i; |
| 5648 | 5653 | UINT32 pixblock = 0x00000000; |
| 5649 | 5654 | for (i=7*4;i>=0;i-=4) |
| 5650 | | { |
| 5655 | { |
| 5651 | 5656 | pixblock |= read_pixel_from_stampmap(space->machine, srcbitmap, xbase>>(3+8), ybase>>(3+8)) << (i); |
| 5652 | | |
| 5653 | | |
| 5657 | |
| 5658 | |
| 5654 | 5659 | xbase += deltax; |
| 5655 | 5660 | ybase += deltay; |
| 5656 | | |
| 5661 | |
| 5657 | 5662 | // clamp to 24-bits, seems to be required for all the intro effects to work |
| 5658 | 5663 | xbase &= 0xffffff; |
| 5659 | 5664 | ybase &= 0xffffff; |
| 5660 | | |
| 5661 | 5665 | |
| 5666 | |
| 5662 | 5667 | } |
| 5663 | | |
| 5664 | | |
| 5665 | | |
| 5666 | | |
| 5668 | |
| 5669 | |
| 5670 | |
| 5671 | |
| 5667 | 5672 | write_pixel_to_imagebuffer(space->machine, pixblock, line, count); |
| 5668 | 5673 | } |
| 5669 | 5674 | |
| r9408 | r9409 | |
| 5777 | 5782 | { |
| 5778 | 5783 | if (segacd_irq_mask & 0x08) |
| 5779 | 5784 | cputag_set_input_line(machine, "segacd_68k", 3, HOLD_LINE); |
| 5780 | | |
| 5785 | |
| 5781 | 5786 | timer_adjust_oneshot(segacd_irq3_timer, SEGACD_IRQ3_TIMER_SPEED, 0); |
| 5782 | 5787 | } |
| 5783 | 5788 | |
| r9408 | r9409 | |
| 5792 | 5797 | |
| 5793 | 5798 | AM_RANGE(0xff0000, 0xff001f) AM_DEVWRITE8("rfsnd", rf5c68_w, 0x00ff) // PCM, RF5C164 |
| 5794 | 5799 | AM_RANGE(0xff2000, 0xff3fff) AM_DEVREADWRITE8("rfsnd", rf5c68_mem_r, rf5c68_mem_w,0x00ff) // PCM, RF5C164 |
| 5795 | | |
| 5796 | | |
| 5800 | |
| 5801 | |
| 5797 | 5802 | AM_RANGE(0xff8000 ,0xff8001) AM_READWRITE(segacd_sub_led_ready_r, segacd_sub_led_ready_w) |
| 5798 | 5803 | AM_RANGE(0xff8002 ,0xff8003) AM_READWRITE(segacd_sub_memory_mode_r, segacd_sub_memory_mode_w) |
| 5799 | 5804 | |