comparison genesis.c @ 1907:b021ca0bc375

Some partial work on TMSS registers, more accurate open bus locations and implement machine freezes for unmapped areas in the IO region
author Michael Pavone <pavone@retrodev.com>
date Wed, 25 Mar 2020 22:59:59 -0700
parents 2d462aa78349
children 508522f08e4d
comparison
equal deleted inserted replaced
1906:2d462aa78349 1907:b021ca0bc375
750 } else { 750 } else {
751 fatal_error("68K write to unhandled Z80 address %X\n", location); 751 fatal_error("68K write to unhandled Z80 address %X\n", location);
752 } 752 }
753 } 753 }
754 } else { 754 } else {
755 location &= 0x1FFF; 755 if (location < 0x10100) {
756 if (location < 0x100) { 756 switch(location >> 1 & 0xFF)
757 switch(location/2)
758 { 757 {
759 case 0x1: 758 case 0x1:
760 io_data_write(gen->io.ports, value, context->current_cycle); 759 io_data_write(gen->io.ports, value, context->current_cycle);
761 break; 760 break;
762 case 0x2: 761 case 0x2:
797 case 0xF: 796 case 0xF:
798 gen->io.ports[2].serial_ctrl = value; 797 gen->io.ports[2].serial_ctrl = value;
799 break; 798 break;
800 } 799 }
801 } else { 800 } else {
802 if (location == 0x1100) { 801 uint32_t masked = location & 0xFFF00;
802 if (masked == 0x11100) {
803 if (value & 1) { 803 if (value & 1) {
804 dputs("bus requesting Z80"); 804 dputs("bus requesting Z80");
805 if (z80_enabled) { 805 if (z80_enabled) {
806 z80_assert_busreq(gen->z80, context->current_cycle); 806 z80_assert_busreq(gen->z80, context->current_cycle);
807 } else { 807 } else {
822 z80_clear_busreq(gen->z80, context->current_cycle); 822 z80_clear_busreq(gen->z80, context->current_cycle);
823 } else { 823 } else {
824 gen->z80->busack = 0; 824 gen->z80->busack = 0;
825 } 825 }
826 } 826 }
827 } else if (location == 0x1200) { 827 } else if (masked == 0x11200) {
828 sync_z80(gen->z80, context->current_cycle); 828 sync_z80(gen->z80, context->current_cycle);
829 if (value & 1) { 829 if (value & 1) {
830 if (z80_enabled) { 830 if (z80_enabled) {
831 z80_clear_reset(gen->z80, context->current_cycle); 831 z80_clear_reset(gen->z80, context->current_cycle);
832 } else { 832 } else {
838 } else { 838 } else {
839 gen->z80->reset = 1; 839 gen->z80->reset = 1;
840 } 840 }
841 ym_reset(gen->ym); 841 ym_reset(gen->ym);
842 } 842 }
843 } else if (masked != 0x11300 && masked != 0x11000) {
844 fatal_error("Machine freeze due to unmapped write to address %X\n", location | 0xA00000);
843 } 845 }
844 } 846 }
845 } 847 }
846 return context; 848 return context;
847 } 849 }
874 if (location < 0x4000) { 876 if (location < 0x4000) {
875 value = gen->zram[location & 0x1FFF]; 877 value = gen->zram[location & 0x1FFF];
876 } else if (location < 0x6000) { 878 } else if (location < 0x6000) {
877 sync_sound(gen, context->current_cycle); 879 sync_sound(gen, context->current_cycle);
878 value = ym_read_status(gen->ym, context->current_cycle, location); 880 value = ym_read_status(gen->ym, context->current_cycle, location);
881 } else if (location < 0x7F00) {
882 value = 0xFF;
879 } else { 883 } else {
884 fatal_error("Machine freeze due to read of Z80 VDP memory window by 68K: %X\n", location | 0xA00000);
880 value = 0xFF; 885 value = 0xFF;
881 } 886 }
882 } else { 887 } else {
883 value = 0xFF; 888 value = 0xFF;
884 } 889 }
885 } else { 890 } else {
886 location &= 0x1FFF; 891 if (location < 0x10100) {
887 if (location < 0x100) { 892 switch(location >> 1 & 0xFF)
888 switch(location/2)
889 { 893 {
890 case 0x0: 894 case 0x0:
891 //version bits should be 0 for now since we're not emulating TMSS 895 //version bits should be 0 for now since we're not emulating TMSS
892 value = gen->version_reg; 896 value = gen->version_reg;
893 break; 897 break;
935 break; 939 break;
936 case 0xF: 940 case 0xF:
937 value = gen->io.ports[2].serial_ctrl; 941 value = gen->io.ports[2].serial_ctrl;
938 break; 942 break;
939 default: 943 default:
940 value = 0xFF; 944 value = get_open_bus_value(&gen->header) >> 8;
941 } 945 }
942 } else { 946 } else {
943 if (location == 0x1100) { 947 uint32_t masked = location & 0xFFF00;
948 if (masked == 0x11100) {
944 value = z80_enabled ? !z80_get_busack(gen->z80, context->current_cycle) : !gen->z80->busack; 949 value = z80_enabled ? !z80_get_busack(gen->z80, context->current_cycle) : !gen->z80->busack;
945 value |= (get_open_bus_value(&gen->header) >> 8) & 0xFE; 950 value |= (get_open_bus_value(&gen->header) >> 8) & 0xFE;
946 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d)\n", value, context->current_cycle, gen->z80->reset); 951 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d)\n", value, context->current_cycle, gen->z80->reset);
947 } else if (location == 0x1200) { 952 } else if (masked == 0x11200) {
948 value = !gen->z80->reset; 953 value = !gen->z80->reset;
954 } else if (masked == 0x11300 || masked == 0x11000) {
955 //A11300 is apparently completely unused
956 //A11000 is the memory control register which I am assuming is write only
957 value = get_open_bus_value(&gen->header) >> 8;
949 } else { 958 } else {
959 location |= 0xA00000;
960 fatal_error("Machine freeze due to read of unmapped IO location %X\n", location);
950 value = 0xFF; 961 value = 0xFF;
951 printf("Byte read of unknown IO location: %X\n", location);
952 } 962 }
953 } 963 }
954 } 964 }
955 return value; 965 return value;
956 } 966 }
1056 1066
1057 gen->z80_bank_reg = (gen->z80_bank_reg >> 1 | value << 8) & 0x1FF; 1067 gen->z80_bank_reg = (gen->z80_bank_reg >> 1 | value << 8) & 0x1FF;
1058 update_z80_bank_pointer(context->system); 1068 update_z80_bank_pointer(context->system);
1059 1069
1060 return context; 1070 return context;
1071 }
1072
1073 static uint16_t unused_read(uint32_t location, void *vcontext)
1074 {
1075 m68k_context *context = vcontext;
1076 genesis_context *gen = context->system;
1077 if ((location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1078 //Only called if the cart/exp doesn't have a more specific handler for this region
1079 return get_open_bus_value(&gen->header);
1080 } else if (location == 0xA14000 || location == 0xA14002) {
1081 if (gen->version_reg & 0xF) {
1082 return gen->tmss_lock[location >> 1 & 1];
1083 } else {
1084 fatal_error("Machine freeze due to read from TMSS lock when TMSS is not present %X\n", location);
1085 return 0xFFFF;
1086 }
1087 } else if (location == 0xA14100) {
1088 if (gen->version_reg & 0xF) {
1089 return get_open_bus_value(&gen->header);
1090 } else {
1091 fatal_error("Machine freeze due to read from TMSS control when TMSS is not present %X\n", location);
1092 return 0xFFFF;
1093 }
1094 } else {
1095 fatal_error("Machine freeze due to unmapped read from %X\n", location);
1096 return 0xFFFF;
1097 }
1098 }
1099
1100 static uint8_t unused_read_b(uint32_t location, void *vcontext)
1101 {
1102 uint16_t v = unused_read(location & 0xFFFFFE, vcontext);
1103 if (location & 1) {
1104 return v;
1105 } else {
1106 return v >> 8;
1107 }
1108 }
1109
1110 static void *unused_write(uint32_t location, void *vcontext, uint16_t value)
1111 {
1112 m68k_context *context = vcontext;
1113 genesis_context *gen = context->system;
1114 uint8_t has_tmss = gen->version_reg & 0xF;
1115 if (has_tmss && (location == 0xA14000 || location == 0xA14002)) {
1116 gen->tmss_lock[location >> 1 & 1] = value;
1117 } else if (has_tmss && location == 0xA14100) {
1118 //TODO: implement TMSS control register
1119 } else {
1120 fatal_error("Machine freeze due to unmapped write to %X\n", location);
1121 }
1122 return vcontext;
1123 }
1124
1125 static void *unused_write_b(uint32_t location, void *vcontext, uint8_t value)
1126 {
1127 m68k_context *context = vcontext;
1128 genesis_context *gen = context->system;
1129 uint8_t has_tmss = gen->version_reg & 0xF;
1130 if (has_tmss && location >= 0xA14000 && location <= 0xA14003) {
1131 uint32_t offset = location >> 1 & 1;
1132 if (location & 1) {
1133 gen->tmss_lock[offset] &= 0xFF00;
1134 gen->tmss_lock[offset] |= value;
1135 } else {
1136 gen->tmss_lock[offset] &= 0xFF;
1137 gen->tmss_lock[offset] |= value << 8;
1138 }
1139 } else if (has_tmss && (location == 0xA14100 || location == 0xA14101)) {
1140 //TODO: implement TMSS control register
1141 } else {
1142 fatal_error("Machine freeze due to unmapped byte write to %X\n", location);
1143 }
1144 return vcontext;
1061 } 1145 }
1062 1146
1063 static void set_speed_percent(system_header * system, uint32_t percent) 1147 static void set_speed_percent(system_header * system, uint32_t percent)
1064 { 1148 {
1065 genesis_context *context = (genesis_context *)system; 1149 genesis_context *context = (genesis_context *)system;
1546 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL, 1630 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL,
1547 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, 1631 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write,
1548 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, 1632 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b},
1549 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL, 1633 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL,
1550 (read_16_fun)io_read_w, (write_16_fun)io_write_w, 1634 (read_16_fun)io_read_w, (write_16_fun)io_write_w,
1551 (read_8_fun)io_read, (write_8_fun)io_write} 1635 (read_8_fun)io_read, (write_8_fun)io_write},
1636 {0x000000, 0xFFFFFF, 0xFFFFFF, 0, 0, 0, NULL,
1637 (read_16_fun)unused_read, (write_16_fun)unused_write,
1638 (read_8_fun)unused_read_b, (write_8_fun)unused_write_b}
1552 }; 1639 };
1553 static tern_node *rom_db; 1640 static tern_node *rom_db;
1554 if (!rom_db) { 1641 if (!rom_db) {
1555 rom_db = load_rom_db(); 1642 rom_db = load_rom_db();
1556 } 1643 }