comparison sms.c @ 1149:6b0da6021544

Don't lock up CPU if performing a read with writes configured when in PBC mode. Allow access to VDP debug commands from Z80 debugger in PBC mode. Handle Mode 4 in VDP debug print functions
author Michael Pavone <pavone@retrodev.com>
date Wed, 04 Jan 2017 20:43:22 -0800
parents 80ef49539550
children c83ec07ddbac
comparison
equal deleted inserted replaced
1148:80ef49539550 1149:6b0da6021544
60 uint8_t ret = vdp_control_port_read(sms->vdp); 60 uint8_t ret = vdp_control_port_read(sms->vdp);
61 sms->vdp->flags2 &= ~(FLAG2_VINT_PENDING|FLAG2_HINT_PENDING); 61 sms->vdp->flags2 &= ~(FLAG2_VINT_PENDING|FLAG2_HINT_PENDING);
62 update_interrupts(sms); 62 update_interrupts(sms);
63 return ret; 63 return ret;
64 } else { 64 } else {
65 return vdp_data_port_read(sms->vdp); 65 return vdp_data_port_read_pbc(sms->vdp);
66 } 66 }
67 } 67 }
68 68
69 static void *vdp_write(uint32_t location, void *vcontext, uint8_t value) 69 static void *vdp_write(uint32_t location, void *vcontext, uint8_t value)
70 { 70 {
102 z80_context *z80 = vcontext; 102 z80_context *z80 = vcontext;
103 sms_context *sms = z80->system; 103 sms_context *sms = z80->system;
104 void *old_value; 104 void *old_value;
105 sms->ram[location & (sizeof(sms->ram)-1)] = value; 105 sms->ram[location & (sizeof(sms->ram)-1)] = value;
106 location &= 3; 106 location &= 3;
107 sms->bank_regs[location] = value;
107 if (location) { 108 if (location) {
108 uint32_t idx = location - 1; 109 uint32_t idx = location - 1;
109 old_value = z80->mem_pointers[idx]; 110 old_value = z80->mem_pointers[idx];
110 z80->mem_pointers[idx] = sms->rom + (value << 14 & (sms->rom_size-1)); 111 z80->mem_pointers[idx] = sms->rom + (value << 14 & (sms->rom_size-1));
111 if (old_value != z80->mem_pointers[idx]) { 112 if (old_value != z80->mem_pointers[idx]) {
112 //invalidate any code we translated for the relevant bank 113 //invalidate any code we translated for the relevant bank
113 z80_invalidate_code_range(z80, idx ? idx * 0x4000 : 0x400, idx * 0x4000 + 0x4000); 114 z80_invalidate_code_range(z80, idx ? idx * 0x4000 : 0x400, idx * 0x4000 + 0x4000);
114 } 115 }
115 } else { 116 } else {
116 //TODO: implement me 117 old_value = z80->mem_pointers[2];
117 } 118 if (value & 8) {
118 return vcontext; 119 //cartridge RAM is enabled
120 z80->mem_pointers[2] = sms->cart_ram + (value & 4 ? (SMS_CART_RAM_SIZE/2) : 0);
121 } else {
122 //cartridge RAM is disabled
123 z80->mem_pointers[2] = sms->rom + (sms->bank_regs[3] << 14 & (sms->rom_size-1));
124 }
125 if (old_value != z80->mem_pointers[2]) {
126 //invalidate any code we translated for the relevant bank
127 z80_invalidate_code_range(z80, 0x8000, 0xC000);
128 }
129 }
130 return vcontext;
131 }
132
133 static void *cart_ram_write(uint32_t location, void *vcontext, uint8_t value)
134 {
135 z80_context *z80 = vcontext;
136 sms_context *sms = z80->system;
137 if (sms->bank_regs[0] & 8) {
138 //cartridge RAM is enabled
139 location &= 0x3FFF;
140 z80->mem_pointers[2][location] = value;
141 z80_handle_code_write(0x8000 + location, z80);
142 }
143 return vcontext;
144 }
145
146 uint8_t debug_commands(system_header *system, char *input_buf)
147 {
148 sms_context *sms = (sms_context *)system;
149 switch(input_buf[0])
150 {
151 case 'v':
152 if (input_buf[1] == 'r') {
153 vdp_print_reg_explain(sms->vdp);
154 } else if (input_buf[1] == 's') {
155 vdp_print_sprite_table(sms->vdp);
156 } else {
157 return 0;
158 }
159 break;
160 }
161 return 1;
119 } 162 }
120 163
121 static memmap_chunk io_map[] = { 164 static memmap_chunk io_map[] = {
122 {0x00, 0x40, 0xFF, 0, 0, 0, NULL, NULL, NULL, NULL, memory_io_write}, 165 {0x00, 0x40, 0xFF, 0, 0, 0, NULL, NULL, NULL, NULL, memory_io_write},
123 {0x40, 0x80, 0xFF, 0, 0, 0, NULL, NULL, NULL, hv_read, sms_psg_write}, 166 {0x40, 0x80, 0xFF, 0, 0, 0, NULL, NULL, NULL, hv_read, sms_psg_write},
230 info_out->map_chunks = 6; 273 info_out->map_chunks = 6;
231 uint8_t *ram_reg_overlap = sms->ram + sizeof(sms->ram) - 4; 274 uint8_t *ram_reg_overlap = sms->ram + sizeof(sms->ram) - 4;
232 memory_map[0] = (memmap_chunk){0x0000, 0x0400, 0xFFFF, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL}; 275 memory_map[0] = (memmap_chunk){0x0000, 0x0400, 0xFFFF, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL};
233 memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, 0, 0, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL}; 276 memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, 0, 0, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL};
234 memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, 0, 1, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL}; 277 memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, 0, 1, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL};
235 memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, 0, 2, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL}; 278 memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, 0, 2, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, cart_ram_write};
236 memory_map[4] = (memmap_chunk){0xC000, 0xFFFC, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL}; 279 memory_map[4] = (memmap_chunk){0xC000, 0xFFFC, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL};
237 memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0xFFFF, 0, 0, MMAP_READ, ram_reg_overlap, NULL, NULL, NULL, mapper_write}; 280 memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0xFFFF, 0, 0, MMAP_READ, ram_reg_overlap, NULL, NULL, NULL, mapper_write};
238 } else { 281 } else {
239 info_out->map_chunks = 2; 282 info_out->map_chunks = 2;
240 memory_map[0] = (memmap_chunk){0x0000, 0xC000, rom_size-1, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL}; 283 memory_map[0] = (memmap_chunk){0x0000, 0xC000, rom_size-1, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL};
244 memcpy(info_out->map, memory_map, sizeof(memmap_chunk) * info_out->map_chunks); 287 memcpy(info_out->map, memory_map, sizeof(memmap_chunk) * info_out->map_chunks);
245 z80_options *zopts = malloc(sizeof(z80_options)); 288 z80_options *zopts = malloc(sizeof(z80_options));
246 init_z80_opts(zopts, info_out->map, info_out->map_chunks, io_map, 4, 15, 0xFF); 289 init_z80_opts(zopts, info_out->map, info_out->map_chunks, io_map, 4, 15, 0xFF);
247 sms->z80 = init_z80_context(zopts); 290 sms->z80 = init_z80_context(zopts);
248 sms->z80->system = sms; 291 sms->z80->system = sms;
292 sms->z80->options->gen.debug_cmd_handler = debug_commands;
249 293
250 sms->rom = rom; 294 sms->rom = rom;
251 sms->rom_size = rom_size; 295 sms->rom_size = rom_size;
252 if (info_out->map_chunks > 2) { 296 if (info_out->map_chunks > 2) {
253 sms->z80->mem_pointers[0] = sms->rom; 297 sms->z80->mem_pointers[0] = sms->rom;