changeset 2045:b119e0de9a70 proprietary

Strip out mega wifi support and debugger
author Michael Pavone <pavone@retrodev.com>
date Tue, 21 Sep 2021 23:17:34 -0700
parents 804954731e3f
children 0f2855db27ea
files Makefile debug.c megawifi.c megawifi.h romdb.c
diffstat 5 files changed, 2 insertions(+), 1877 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Aug 05 23:48:41 2021 -0700
+++ b/Makefile	Tue Sep 21 23:17:34 2021 -0700
@@ -218,11 +218,11 @@
 
 #MAINOBJS=blastem.o system.o genesis.o debug.o gdb_remote.o vdp.o $(RENDEROBJS) io.o romdb.o hash.o menu.o xband.o 
 MAINOBJS=blastem.o system.o genesis.o vdp.o $(RENDEROBJS) io.o romdb.o hash.o menu.o xband.o \
-	realtec.o i2c.o nor.o sega_mapper.o multi_game.o megawifi.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
+	realtec.o i2c.o nor.o sega_mapper.o multi_game.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
 	$(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o zip.o bindings.o jcart.o gen_player.o
 
 LIBOBJS=libblastem.o system.o genesis.o debug.o gdb_remote.o vdp.o io.o romdb.o hash.o xband.o realtec.o \
-	i2c.o nor.o sega_mapper.o multi_game.o megawifi.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
+	i2c.o nor.o sega_mapper.o multi_game.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
 	$(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o jcart.o rom.db.o gen_player.o $(LIBZOBJS)
 	
 ifdef NONUKLEAR
--- a/debug.c	Thu Aug 05 23:48:41 2021 -0700
+++ b/debug.c	Tue Sep 21 23:17:34 2021 -0700
@@ -113,999 +113,22 @@
 
 void debugger_print(m68k_context *context, char format_char, char *param, uint32_t address)
 {
-	uint32_t value;
-	char format[8];
-	strcpy(format, "%s: %d\n");
-	switch (format_char)
-	{
-	case 'x':
-	case 'X':
-	case 'd':
-	case 'c':
-		format[5] = format_char;
-		break;
-	case '\0':
-		break;
-	default:
-		fprintf(stderr, "Unrecognized format character: %c\n", format_char);
-	}
-	if (param[0] == 'd' && param[1] >= '0' && param[1] <= '7') {
-		value = context->dregs[param[1]-'0'];
-		if (param[2] == '.') {
-			if (param[3] == 'w') {
-				value &= 0xFFFF;
-			} else if (param[3] == 'b') {
-				value &= 0xFF;
-			}
-		}
-	} else if (param[0] == 'a' && param[1] >= '0' && param[1] <= '7') {
-		value = context->aregs[param[1]-'0'];
-		if (param[2] == '.') {
-			if (param[3] == 'w') {
-				value &= 0xFFFF;
-			} else if (param[3] == 'b') {
-				value &= 0xFF;
-			}
-		}
-	} else if (param[0] == 's' && param[1] == 'r') {
-		value = (context->status << 8);
-		for (int flag = 0; flag < 5; flag++) {
-			value |= context->flags[flag] << (4-flag);
-		}
-	} else if(param[0] == 'c') {
-		value = context->current_cycle;
-	} else if(param[0] == 'f') {
-		genesis_context *gen = context->system;
-		value = gen->vdp->frame;
-	} else if (param[0] == 'p' && param[1] == 'c') {
-		value = address;
-	} else if ((param[0] == '0' && param[1] == 'x') || param[0] == '$') {
-		char *after;
-		uint32_t p_addr = strtol(param+(param[0] == '0' ? 2 : 1), &after, 16);
-		if (after[0] == '.' && after[1] == 'l') {
-			value = m68k_read_long(p_addr, context);
-		} else if (after[0] == '.' && after[1] == 'b') {
-			value = m68k_read_byte(p_addr, context);
-		} else {
-			value = m68k_read_word(p_addr, context);
-		}
-	} else if(param[0] == '(' && (param[1] == 'a' || param[1] == 'd') && param[2] >= '0' && param[2] <= '7' && param[3] == ')') {
-		uint8_t reg = param[2] - '0';
-		uint32_t p_addr = param[1] == 'a' ? context->aregs[reg] : context->dregs[reg];
-		if (param[4] == '.' && param[5] == 'l') {
-			value = m68k_read_long(p_addr, context);
-		} else if (param[4] == '.' && param[5] == 'b') {
-			value = m68k_read_byte(p_addr, context);
-		} else {
-			value = m68k_read_word(p_addr, context);
-		}
-	} else {
-		fprintf(stderr, "Unrecognized parameter to p: %s\n", param);
-		return;
-	}
-	printf(format, param, value);
 }
 
 #ifndef NO_Z80
 
 void zdebugger_print(z80_context * context, char format_char, char * param)
 {
-	uint32_t value;
-	char format[8];
-	strcpy(format, "%s: %d\n");
-	genesis_context *system = context->system;
-	switch (format_char)
-	{
-	case 'x':
-	case 'X':
-	case 'd':
-	case 'c':
-		format[5] = format_char;
-		break;
-	case '\0':
-		break;
-	default:
-		fprintf(stderr, "Unrecognized format character: %c\n", format_char);
-	}
-	switch (param[0])
-	{
-#ifndef NEW_CORE
-	case 'a':
-		if (param[1] == 'f') {
-			if(param[2] == '\'') {
-				value = context->alt_regs[Z80_A] << 8;
-				value |= context->alt_flags[ZF_S] << 7;
-				value |= context->alt_flags[ZF_Z] << 6;
-				value |= context->alt_flags[ZF_H] << 4;
-				value |= context->alt_flags[ZF_PV] << 2;
-				value |= context->alt_flags[ZF_N] << 1;
-				value |= context->alt_flags[ZF_C];
-			} else {
-				value = context->regs[Z80_A] << 8;
-				value |= context->flags[ZF_S] << 7;
-				value |= context->flags[ZF_Z] << 6;
-				value |= context->flags[ZF_H] << 4;
-				value |= context->flags[ZF_PV] << 2;
-				value |= context->flags[ZF_N] << 1;
-				value |= context->flags[ZF_C];
-			}
-		} else if(param[1] == '\'') {
-			value = context->alt_regs[Z80_A];
-		} else {
-			value = context->regs[Z80_A];
-		}
-		break;
-	case 'b':
-		if (param[1] == 'c') {
-			if(param[2] == '\'') {
-				value = context->alt_regs[Z80_B] << 8;
-				value |= context->alt_regs[Z80_C];
-			} else {
-				value = context->regs[Z80_B] << 8;
-				value |= context->regs[Z80_C];
-			}
-		} else if(param[1] == '\'') {
-			value = context->alt_regs[Z80_B];
-		} else if(param[1] == 'a') {
-			value = context->bank_reg << 15;
-		} else {
-			value = context->regs[Z80_B];
-		}
-		break;
-	case 'c':
-		if(param[1] == '\'') {
-			value = context->alt_regs[Z80_C];
-		} else if(param[1] == 'y') {
-			value = context->current_cycle;
-		} else {
-			value = context->regs[Z80_C];
-		}
-		break;
-	case 'd':
-		if (param[1] == 'e') {
-			if(param[2] == '\'') {
-				value = context->alt_regs[Z80_D] << 8;
-				value |= context->alt_regs[Z80_E];
-			} else {
-				value = context->regs[Z80_D] << 8;
-				value |= context->regs[Z80_E];
-			}
-		} else if(param[1] == '\'') {
-			value = context->alt_regs[Z80_D];
-		} else {
-			value = context->regs[Z80_D];
-		}
-		break;
-	case 'e':
-		if(param[1] == '\'') {
-			value = context->alt_regs[Z80_E];
-		} else {
-			value = context->regs[Z80_E];
-		}
-		break;
-	case 'f':
-		if(param[2] == '\'') {
-			value = context->alt_flags[ZF_S] << 7;
-			value |= context->alt_flags[ZF_Z] << 6;
-			value |= context->alt_flags[ZF_H] << 4;
-			value |= context->alt_flags[ZF_PV] << 2;
-			value |= context->alt_flags[ZF_N] << 1;
-			value |= context->alt_flags[ZF_C];
-		} else {
-			value = context->flags[ZF_S] << 7;
-			value |= context->flags[ZF_Z] << 6;
-			value |= context->flags[ZF_H] << 4;
-			value |= context->flags[ZF_PV] << 2;
-			value |= context->flags[ZF_N] << 1;
-			value |= context->flags[ZF_C];
-		}
-		break;
-	case 'h':
-		if (param[1] == 'l') {
-			if(param[2] == '\'') {
-				value = context->alt_regs[Z80_H] << 8;
-				value |= context->alt_regs[Z80_L];
-			} else {
-				value = context->regs[Z80_H] << 8;
-				value |= context->regs[Z80_L];
-			}
-		} else if(param[1] == '\'') {
-			value = context->alt_regs[Z80_H];
-		} else {
-			value = context->regs[Z80_H];
-		}
-		break;
-	case 'l':
-		if(param[1] == '\'') {
-			value = context->alt_regs[Z80_L];
-		} else {
-			value = context->regs[Z80_L];
-		}
-		break;
-	case 'i':
-		if(param[1] == 'x') {
-			if (param[2] == 'h') {
-				value = context->regs[Z80_IXH];
-			} else if(param[2] == 'l') {
-				value = context->regs[Z80_IXL];
-			} else {
-				value = context->regs[Z80_IXH] << 8;
-				value |= context->regs[Z80_IXL];
-			}
-		} else if(param[1] == 'y') {
-			if (param[2] == 'h') {
-				value = context->regs[Z80_IYH];
-			} else if(param[2] == 'l') {
-				value = context->regs[Z80_IYL];
-			} else {
-				value = context->regs[Z80_IYH] << 8;
-				value |= context->regs[Z80_IYL];
-			}
-		} else if(param[1] == 'n') {
-			value = context->int_cycle;
-		} else if(param[1] == 'f' && param[2] == 'f' && param[3] == '1') {
-			value = context->iff1;
-		} else if(param[1] == 'f' && param[2] == 'f' && param[3] == '2') {
-			value = context->iff2;
-		} else {
-			value = context->im;
-		}
-		break;
-#endif
-	case 's':
-		if (param[1] == 'p') {
-			value = context->sp;
-		}
-		break;
-	case '0':
-		if (param[1] == 'x') {
-			uint16_t p_addr = strtol(param+2, NULL, 16);
-			value = read_byte(p_addr, (void **)context->mem_pointers, &context->options->gen, context);
-		}
-		break;
-	}
-	printf(format, param, value);
 }
 
 z80_context * zdebugger(z80_context * context, uint16_t address)
 {
-	static char last_cmd[1024];
-	char input_buf[1024];
-	static uint16_t branch_t;
-	static uint16_t branch_f;
-	z80inst inst;
-	genesis_context *system = context->system;
-	init_terminal();
-	//Check if this is a user set breakpoint, or just a temporary one
-	bp_def ** this_bp = find_breakpoint(&zbreakpoints, address);
-	if (*this_bp) {
-		printf("Z80 Breakpoint %d hit\n", (*this_bp)->index);
-	} else {
-		zremove_breakpoint(context, address);
-	}
-	uint8_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->Z80_OPTS->gen);
-	if (!pc) {
-		fatal_error("Failed to get native pointer on entering Z80 debugger at address %X\n", address);
-	}
-	for (disp_def * cur = zdisplays; cur; cur = cur->next) {
-		zdebugger_print(context, cur->format_char, cur->param);
-	}
-	uint8_t * after_pc = z80_decode(pc, &inst);
-	z80_disasm(&inst, input_buf, address);
-	printf("%X:\t%s\n", address, input_buf);
-	uint16_t after = address + (after_pc-pc);
-	int debugging = 1;
-	while(debugging) {
-		fputs(">", stdout);
-		if (!fgets(input_buf, sizeof(input_buf), stdin)) {
-			fputs("fgets failed", stderr);
-			break;
-		}
-		strip_nl(input_buf);
-		//hitting enter repeats last command
-		if (input_buf[0]) {
-			strcpy(last_cmd, input_buf);
-		} else {
-			strcpy(input_buf, last_cmd);
-		}
-		char * param;
-		char format[8];
-		uint32_t value;
-		bp_def * new_bp;
-		switch(input_buf[0])
-		{
-			case 'a':
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("a command requires a parameter\n", stderr);
-					break;
-				}
-				value = strtol(param, NULL, 16);
-				zinsert_breakpoint(context, value, (uint8_t *)zdebugger);
-				debugging = 0;
-				break;
-			case 'b':
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("b command requires a parameter\n", stderr);
-					break;
-				}
-				value = strtol(param, NULL, 16);
-				zinsert_breakpoint(context, value, (uint8_t *)zdebugger);
-				new_bp = malloc(sizeof(bp_def));
-				new_bp->next = zbreakpoints;
-				new_bp->address = value;
-				new_bp->index = zbp_index++;
-				new_bp->commands = NULL;
-				zbreakpoints = new_bp;
-				printf("Z80 Breakpoint %d set at %X\n", new_bp->index, value);
-				break;
-			case 'c':
-				puts("Continuing");
-				debugging = 0;
-				break;
-			case 'd':
-				if (input_buf[1] == 'i') {
-					char format_char = 0;
-					for(int i = 2; input_buf[i] != 0 && input_buf[i] != ' '; i++) {
-						if (input_buf[i] == '/') {
-							format_char = input_buf[i+1];
-							break;
-						}
-					}
-					param = find_param(input_buf);
-					if (!param) {
-						fputs("display command requires a parameter\n", stderr);
-						break;
-					}
-					zdebugger_print(context, format_char, param);
-					add_display(&zdisplays, &zdisp_index, format_char, param);
-				} else if (input_buf[1] == 'e' || input_buf[1] == ' ') {
-					param = find_param(input_buf);
-					if (!param) {
-						fputs("delete command requires a parameter\n", stderr);
-						break;
-					}
-					if (param[0] >= '0' && param[0] <= '9') {
-						value = atoi(param);
-						this_bp = find_breakpoint_idx(&zbreakpoints, value);
-						if (!*this_bp) {
-							fprintf(stderr, "Breakpoint %d does not exist\n", value);
-							break;
-						}
-						new_bp = *this_bp;
-						zremove_breakpoint(context, new_bp->address);
-						*this_bp = new_bp->next;
-						free(new_bp);
-					} else if (param[0] == 'd') {
-						param = find_param(param);
-						if (!param) {
-							fputs("delete display command requires a parameter\n", stderr);
-							break;
-						}
-						remove_display(&zdisplays, atoi(param));
-					}
-				}
-				break;
-			case 'n':
-				//TODO: Handle conditional branch instructions
-				if (inst.op == Z80_JP) {
-					if (inst.addr_mode == Z80_IMMED) {
-						after = inst.immed;
-					} else if (inst.ea_reg == Z80_HL) {
-#ifndef NEW_CORE
-						after = context->regs[Z80_H] << 8 | context->regs[Z80_L];
-					} else if (inst.ea_reg == Z80_IX) {
-						after = context->regs[Z80_IXH] << 8 | context->regs[Z80_IXL];
-					} else if (inst.ea_reg == Z80_IY) {
-						after = context->regs[Z80_IYH] << 8 | context->regs[Z80_IYL];
-#endif
-					}
-				} else if(inst.op == Z80_JR) {
-					after += inst.immed;
-				} else if(inst.op == Z80_RET) {
-					uint8_t *sp = get_native_pointer(context->sp, (void **)context->mem_pointers, &context->Z80_OPTS->gen);
-					if (sp) {
-						after = *sp;
-						sp = get_native_pointer((context->sp + 1) & 0xFFFF, (void **)context->mem_pointers, &context->Z80_OPTS->gen);
-						if (sp) {
-							after |= *sp << 8;
-						}
-					}
-				}
-				zinsert_breakpoint(context, after, (uint8_t *)zdebugger);
-				debugging = 0;
-				break;
-			case 'p':
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("p command requires a parameter\n", stderr);
-					break;
-				}
-				zdebugger_print(context, input_buf[1] == '/' ? input_buf[2] : 0, param);
-				break;
-			case 'q':
-				puts("Quitting");
-				exit(0);
-				break;
-			case 's': {
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("s command requires a file name\n", stderr);
-					break;
-				}
-				memmap_chunk const *ram_chunk = NULL;
-				for (int i = 0; i < context->Z80_OPTS->gen.memmap_chunks; i++)
-				{
-					memmap_chunk const *cur = context->Z80_OPTS->gen.memmap + i;
-					if (cur->flags & MMAP_WRITE) {
-						ram_chunk = cur;
-						break;
-					}
-				}
-				if (ram_chunk) {
-					uint32_t size = ram_chunk->end - ram_chunk->start;
-					if (size > ram_chunk->mask) {
-						size = ram_chunk->mask+1;
-					}
-					uint8_t *buf = get_native_pointer(ram_chunk->start, (void **)context->mem_pointers, &context->Z80_OPTS->gen);
-					FILE * f = fopen(param, "wb");
-					if (f) {
-						if(fwrite(buf, 1, size, f) != size) {
-							fputs("Error writing file\n", stderr);
-						}
-						fclose(f);
-						printf("Wrote %d bytes to %s\n", size, param);
-					} else {
-						fprintf(stderr, "Could not open %s for writing\n", param);
-					}
-				} else {
-					fputs("Failed to find a RAM memory chunk\n", stderr);
-				}
-				break;
-			}
-			case '?':
-				print_z80_help();
-				break;
-			default:
-				if (
-					!context->Z80_OPTS->gen.debug_cmd_handler
-					|| !context->Z80_OPTS->gen.debug_cmd_handler(&system->header, input_buf)
-				) {
-					fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf);
-				}
-				break;
-		}
-	}
 	return context;
 }
 
 #endif
 
-static uint32_t branch_t;
-static uint32_t branch_f;
-
-int run_debugger_command(m68k_context *context, uint32_t address, char *input_buf, m68kinst inst, uint32_t after)
-{
-	char * param;
-	char format_char;
-	genesis_context *system = context->system;
-	uint32_t value;
-	bp_def *new_bp, **this_bp;
-	switch(input_buf[0])
-	{
-		case 'c':
-			if (input_buf[1] == 0 || input_buf[1] == 'o' && input_buf[2] == 'n')
-			{
-				puts("Continuing");
-				return 0;
-			} else if (input_buf[1] == 'o' && input_buf[2] == 'm') {
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("com command requires a parameter\n", stderr);
-					break;
-				}
-				bp_def **target = find_breakpoint_idx(&breakpoints, atoi(param));
-				if (!target) {
-					fprintf(stderr, "Breakpoint %s does not exist!\n", param);
-					break;
-				}
-				printf("Enter commands for breakpoing %d, type end when done\n", atoi(param));
-				char cmd_buf[1024];
-				char *commands = NULL;
-				for (;;)
-				{
-					fputs(">>", stdout);
-					fflush(stdout);
-					fgets(cmd_buf, sizeof(cmd_buf), stdin);
-					if (strcmp(cmd_buf, "end\n")) {
-						if (commands) {
-							char *tmp = commands;
-							commands = alloc_concat(commands, cmd_buf);
-							free(tmp);
-						} else {
-							commands = strdup(cmd_buf);
-						}
-					} else {
-						break;
-					}
-				}
-				(*target)->commands = commands;
-			} else {
-			}
-			break;
-		case 'b':
-			if (input_buf[1] == 't') {
-				uint32_t stack = context->aregs[7];
-				if (stack >= 0xE00000) {
-					stack &= 0xFFFF;
-					uint8_t non_adr_count = 0;
-					do {
-						uint32_t bt_address = system->work_ram[stack/2] << 16 | system->work_ram[stack/2+1];
-						bt_address = get_instruction_start(context->options, bt_address - 2);
-						if (bt_address) {
-							stack += 4;
-							non_adr_count = 0;
-							uint16_t *bt_pc = NULL;
-							if (bt_address < 0x400000) {
-								bt_pc = system->cart + bt_address/2;
-							} else if(bt_address > 0xE00000) {
-								bt_pc = system->work_ram + (bt_address & 0xFFFF)/2;
-							}
-							m68k_decode(bt_pc, &inst, bt_address);
-							m68k_disasm(&inst, input_buf);
-							printf("%X: %s\n", bt_address, input_buf);
-						} else {
-							//non-return address value on stack can be word wide
-							stack += 2;
-							non_adr_count++;
-						}
-						stack &= 0xFFFF;
-					} while (stack && non_adr_count < 6);
-				}
-			} else {
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("b command requires a parameter\n", stderr);
-					break;
-				}
-				value = strtol(param, NULL, 16);
-				insert_breakpoint(context, value, debugger);
-				new_bp = malloc(sizeof(bp_def));
-				new_bp->next = breakpoints;
-				new_bp->address = value;
-				new_bp->index = bp_index++;
-				new_bp->commands = NULL;
-				breakpoints = new_bp;
-				printf("68K Breakpoint %d set at %X\n", new_bp->index, value);
-			}
-			break;
-		case 'a':
-			param = find_param(input_buf);
-			if (!param) {
-				fputs("a command requires a parameter\n", stderr);
-				break;
-			}
-			value = strtol(param, NULL, 16);
-			insert_breakpoint(context, value, debugger);
-			return 0;
-		case 'd':
-			if (input_buf[1] == 'i') {
-				format_char = 0;
-				for(int i = 2; input_buf[i] != 0 && input_buf[i] != ' '; i++) {
-					if (input_buf[i] == '/') {
-						format_char = input_buf[i+1];
-						break;
-					}
-				}
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("display command requires a parameter\n", stderr);
-					break;
-				}
-				debugger_print(context, format_char, param, address);
-				add_display(&displays, &disp_index, format_char, param);
-			} else {
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("d command requires a parameter\n", stderr);
-					break;
-				}
-				value = atoi(param);
-				this_bp = find_breakpoint_idx(&breakpoints, value);
-				if (!*this_bp) {
-					fprintf(stderr, "Breakpoint %d does not exist\n", value);
-					break;
-				}
-				new_bp = *this_bp;
-				*this_bp = (*this_bp)->next;
-				if (new_bp->commands) {
-					free(new_bp->commands);
-				}
-				free(new_bp);
-			}
-			break;
-		case 'p':
-			format_char = 0;
-			for(int i = 1; input_buf[i] != 0 && input_buf[i] != ' '; i++) {
-				if (input_buf[i] == '/') {
-					format_char = input_buf[i+1];
-					break;
-				}
-			}
-			param = find_param(input_buf);
-			if (param) {
-				debugger_print(context, format_char, param, address);
-			} else {
-				m68k_disasm(&inst, input_buf);
-				printf("%X: %s\n", address, input_buf);
-			}
-			
-			break;
-		case 'n':
-			if (inst.op == M68K_RTS) {
-				after = m68k_read_long(context->aregs[7], context);
-			} else if (inst.op == M68K_RTE || inst.op == M68K_RTR) {
-				after = m68k_read_long(context->aregs[7] + 2, context);
-			} else if(m68k_is_noncall_branch(&inst)) {
-				if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) {
-					branch_f = after;
-					branch_t = m68k_branch_target(&inst, context->dregs, context->aregs);
-					insert_breakpoint(context, branch_t, debugger);
-				} else if(inst.op == M68K_DBCC) {
-					if ( inst.extra.cond == COND_FALSE) {
-						if (context->dregs[inst.dst.params.regs.pri] & 0xFFFF) {
-							after = m68k_branch_target(&inst, context->dregs, context->aregs);
-						}
-					} else {
-						branch_t = after;
-						branch_f = m68k_branch_target(&inst, context->dregs, context->aregs);
-						insert_breakpoint(context, branch_f, debugger);
-					}
-				} else {
-					after = m68k_branch_target(&inst, context->dregs, context->aregs);
-				}
-			}
-			insert_breakpoint(context, after, debugger);
-			return 0;
-		case 'o':
-			if (inst.op == M68K_RTS) {
-				after = m68k_read_long(context->aregs[7], context);
-			} else if (inst.op == M68K_RTE || inst.op == M68K_RTR) {
-				after = m68k_read_long(context->aregs[7] + 2, context);
-			} else if(m68k_is_noncall_branch(&inst)) {
-				if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) {
-					branch_t = m68k_branch_target(&inst, context->dregs, context->aregs)  & 0xFFFFFF;
-					if (branch_t < after) {
-							branch_t = 0;
-					} else {
-						branch_f = after;
-						insert_breakpoint(context, branch_t, debugger);
-					}
-				} else if(inst.op == M68K_DBCC) {
-					uint32_t target = m68k_branch_target(&inst, context->dregs, context->aregs)  & 0xFFFFFF;
-					if (target > after) {
-						if (inst.extra.cond == COND_FALSE) {
-							after = target;
-						} else {
-							branch_f = target;
-							branch_t = after;
-							insert_breakpoint(context, branch_f, debugger);
-						}
-					}
-				} else {
-					after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
-				}
-			}
-			insert_breakpoint(context, after, debugger);
-			return 0;
-		case 's':
-			if (input_buf[1] == 'e') {
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("Missing destination parameter for set\n", stderr);
-					return 1;
-				}
-				char *val = find_param(param);
-				if (!val) {
-					fputs("Missing value parameter for set\n", stderr);
-					return 1;
-				}
-				long int_val;
-				int reg_num;
-				switch (val[0])
-				{
-				case 'd':
-				case 'a':
-					reg_num = val[1] - '0';
-					if (reg_num < 0 || reg_num > 8) {
-						fprintf(stderr, "Invalid register %s\n", val);
-						return 1;
-					}
-					int_val = (val[0] == 'd' ? context->dregs : context->aregs)[reg_num];
-					break;
-				case '$':
-					int_val = strtol(val+1, NULL, 16);
-					break;
-				case '0':
-					if (val[1] == 'x') {
-						int_val = strtol(val+2, NULL, 16);
-						break;
-					}
-				default:
-					int_val = strtol(val, NULL, 10);
-				}
-				switch(param[0])
-				{
-				case 'd':
-				case 'a':
-					reg_num = param[1] - '0';
-					if (reg_num < 0 || reg_num > 8) {
-						fprintf(stderr, "Invalid register %s\n", param);
-						return 1;
-					}
-					(param[0] == 'd' ? context->dregs : context->aregs)[reg_num] = int_val;
-					break;
-				default:
-					fprintf(stderr, "Invalid destinatino %s\n", param);
-				}
-				break;
-			} else if (input_buf[1] == 'r') {
-				system->header.soft_reset(&system->header);
-				return 0;
-			} else {
-				if (inst.op == M68K_RTS) {
-					after = m68k_read_long(context->aregs[7], context);
-				} else if (inst.op == M68K_RTE || inst.op == M68K_RTR) {
-					after = m68k_read_long(context->aregs[7] + 2, context);
-				} else if(m68k_is_branch(&inst)) {
-					if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) {
-						branch_f = after;
-						branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
-						insert_breakpoint(context, branch_t, debugger);
-					} else if(inst.op == M68K_DBCC) {
-						if (inst.extra.cond == COND_FALSE) {
-							if (context->dregs[inst.dst.params.regs.pri] & 0xFFFF) {
-								after = m68k_branch_target(&inst, context->dregs, context->aregs);
-							}
-						} else {
-							branch_t = after;
-							branch_f = m68k_branch_target(&inst, context->dregs, context->aregs);
-							insert_breakpoint(context, branch_f, debugger);
-						}
-					} else {
-						after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
-					}
-				}
-				insert_breakpoint(context, after, debugger);
-				return 0;
-			}
-		case 'v': {
-			genesis_context * gen = context->system;
-			//VDP debug commands
-			switch(input_buf[1])
-			{
-			case 's':
-				vdp_print_sprite_table(gen->vdp);
-				break;
-			case 'r':
-				vdp_print_reg_explain(gen->vdp);
-				break;
-			}
-			break;
-		}
-		case 'y': {
-			genesis_context * gen = context->system;
-			//YM-2612 debug commands
-			switch(input_buf[1])
-			{
-			case 'c':
-				if (input_buf[2] == ' ') {
-					int channel = atoi(input_buf+3)-1;
-					ym_print_channel_info(gen->ym, channel);
-				} else {
-					for (int i = 0; i < 6; i++) {
-						ym_print_channel_info(gen->ym, i);
-					}
-				}
-				break;
-			case 't':
-				ym_print_timer_info(gen->ym);
-				break;
-			}
-			break;
-		}
-#ifndef NO_Z80
-		case 'z': {
-			genesis_context * gen = context->system;
-			//Z80 debug commands
-			switch(input_buf[1])
-			{
-			case 'b':
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("zb command requires a parameter\n", stderr);
-					break;
-				}
-				value = strtol(param, NULL, 16);
-				zinsert_breakpoint(gen->z80, value, (uint8_t *)zdebugger);
-				new_bp = malloc(sizeof(bp_def));
-				new_bp->next = zbreakpoints;
-				new_bp->address = value;
-				new_bp->index = zbp_index++;
-				zbreakpoints = new_bp;
-				printf("Z80 Breakpoint %d set at %X\n", new_bp->index, value);
-				break;
-			case 'p':
-				param = find_param(input_buf);
-				if (!param) {
-					fputs("zp command requires a parameter\n", stderr);
-					break;
-				}
-				zdebugger_print(gen->z80, input_buf[2] == '/' ? input_buf[3] : 0, param);
-			}
-			break;
-		}
-#endif
-		case '?':
-			print_m68k_help();
-			break;
-		case 'q':
-			puts("Quitting");
-			exit(0);
-			break;
-		default:
-			fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf);
-			break;
-	}
-	return 1;
-}
-
-void print_m68k_help()
-{
-	printf("M68k Debugger Commands\n");
-	printf("    b ADDRESS            - Set a breakpoint at ADDRESS\n");
-	printf("    d BREAKPOINT         - Delete a 68K breakpoint\n");
-	printf("    co BREAKPOINT        - Run a list of debugger commands each time\n");
-	printf("                           BREAKPOINT is hit\n");
-	printf("    a ADDRESS            - Advance to address\n");
-	printf("    n                    - Advance to next instruction\n");
-	printf("    o                    - Advance to next instruction ignoring branches to\n");
-	printf("                           lower addresses (good for breaking out of loops)\n");
-	printf("    s                    - Advance to next instruction (follows bsr/jsr)\n");
-	printf("    se REG|ADDRESS VALUE - Set value\n");
-	printf("    sr                   - Soft reset\n");
-	printf("    c                    - Continue\n");
-	printf("    bt                   - Print a backtrace\n");
-	printf("    p[/(x|X|d|c)] VALUE  - Print a register or memory location\n");
-	printf("    di[/(x|X|d|c)] VALUE - Print a register or memory location each time\n");
-	printf("                           a breakpoint is hit\n");
-	printf("    vs                   - Print VDP sprite list\n");
-	printf("    vr                   - Print VDP register info\n");
-	printf("    yc [CHANNEL NUM]     - Print YM-2612 channel info\n");
-	printf("    yt                   - Print YM-2612 timer info\n");
-	printf("    zb ADDRESS           - Set a Z80 breakpoint\n");
-	printf("    zp[/(x|X|d|c)] VALUE - Display a Z80 value\n");
-	printf("    ?                    - Display help\n");
-	printf("    q                    - Quit BlastEm\n");
-}
-
-void print_z80_help()
-{
-	printf("Z80 Debugger Commands\n");
-	printf("    b  ADDRESS           - Set a breakpoint at ADDRESS\n");
-	printf("    de BREAKPOINT        - Delete a Z80 breakpoint\n");
-	printf("    a  ADDRESS           - Advance to address\n");
-	printf("    n                    - Advance to next instruction\n");
-	printf("    c                    - Continue\n");
-	printf("    p[/(x|X|d|c)] VALUE  - Print a register or memory location\n");
-	printf("    di[/(x|X|d|c)] VALUE - Print a register or memory location each time\n");
-	printf("                           a breakpoint is hit\n");
-	printf("    q                    - Quit BlastEm\n");
-}
-
 void debugger(m68k_context * context, uint32_t address)
 {
-	static char last_cmd[1024];
-	char input_buf[1024];
-	m68kinst inst;
-
-	init_terminal();
-
-	sync_components(context, 0);
-	genesis_context *gen = context->system;
-	vdp_force_update_framebuffer(gen->vdp);
-	//probably not necessary, but let's play it safe
-	address &= 0xFFFFFF;
-	if (address == branch_t) {
-		bp_def ** f_bp = find_breakpoint(&breakpoints, branch_f);
-		if (!*f_bp) {
-			remove_breakpoint(context, branch_f);
-		}
-		branch_t = branch_f = 0;
-	} else if(address == branch_f) {
-		bp_def ** t_bp = find_breakpoint(&breakpoints, branch_t);
-		if (!*t_bp) {
-			remove_breakpoint(context, branch_t);
-		}
-		branch_t = branch_f = 0;
-	}
-
-	uint16_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->options->gen);
-	if (!pc) {
-		fatal_error("Entered 68K debugger at address %X\n", address);
-	}
-	uint16_t * after_pc = m68k_decode(pc, &inst, address);
-	uint32_t after = address + (after_pc-pc)*2;
-	int debugging = 1;
-	//Check if this is a user set breakpoint, or just a temporary one
-	bp_def ** this_bp = find_breakpoint(&breakpoints, address);
-	if (*this_bp) {
-
-		if ((*this_bp)->commands)
-		{
-			char *commands = strdup((*this_bp)->commands);
-			char *copy = commands;
-
-			while (debugging && *commands)
-			{
-				char *cmd = commands;
-				strip_nl(cmd);
-				commands += strlen(cmd) + 1;
-				debugging = run_debugger_command(context, address, cmd, inst, after);
-			}
-			free(copy);
-		}
-		if (debugging) {
-			printf("68K Breakpoint %d hit\n", (*this_bp)->index);
-		} else {
-			return;
-		}
-	} else {
-		remove_breakpoint(context, address);
-	}
-	for (disp_def * cur = displays; cur; cur = cur->next) {
-		debugger_print(context, cur->format_char, cur->param, address);
-	}
-	m68k_disasm(&inst, input_buf);
-	printf("%X: %s\n", address, input_buf);
-#ifdef _WIN32
-#define prompt 1
-#else
-	int prompt = 1;
-	fd_set read_fds;
-	FD_ZERO(&read_fds);
-	struct timeval timeout;
-#endif
-	while (debugging) {
-		if (prompt) {
-			fputs(">", stdout);
-			fflush(stdout);
-		}
-		process_events();
-#ifndef _WIN32
-		timeout.tv_sec = 0;
-		timeout.tv_usec = 16667;
-		FD_SET(fileno(stdin), &read_fds);
-		if(select(fileno(stdin) + 1, &read_fds, NULL, NULL, &timeout) < 1) {
-			prompt = 0;
-			continue;
-		} else {
-			prompt = 1;
-		}
-#endif
-		if (!fgets(input_buf, sizeof(input_buf), stdin)) {
-			fputs("fgets failed", stderr);
-			break;
-		}
-		strip_nl(input_buf);
-		//hitting enter repeats last command
-		if (input_buf[0]) {
-			strcpy(last_cmd, input_buf);
-		} else {
-			strcpy(input_buf, last_cmd);
-		}
-		debugging = run_debugger_command(context, address, input_buf, inst, after);
-	}
 	return;
 }
--- a/megawifi.c	Thu Aug 05 23:48:41 2021 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,834 +0,0 @@
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#ifdef _WIN32
-#define WINVER 0x501
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <sys/param.h>
-#else
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#include <time.h>
-#include "genesis.h"
-#include "net.h"
-#include "util.h"
-
-#if defined(_WIN32) || defined(__APPLE__)
-#  if BYTE_ORDER == LITTLE_ENDIAN
-#define htobe64(val)   ((((uint64_t)htonl((val)&0xFFFFFFFF))<<32) | htonl((val)>>32))
-#  else
-#define htobe64(val)	(val)
-#  endif
-#endif
-
-enum {
-	TX_IDLE,
-	TX_LEN1,
-	TX_LEN2,
-	TX_PAYLOAD,
-	TX_WAIT_ETX
-};
-#define STX 0x7E
-#define ETX 0x7E
-#define MAX_RECV_SIZE 1460
-
-#define E(N) N
-enum {
-#include "mw_commands.c"
-	CMD_ERROR = 255
-};
-#undef E
-#define E(N) #N
-static const char *cmd_names[] = {
-#include "mw_commands.c"
-	[255] = "CMD_ERROR"
-};
-
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
-#endif
-
-enum mw_state {
-	STATE_IDLE=1,
-	STATE_AP_JOIN,
-	STATE_SCAN,
-	STATE_READY,
-	STATE_TRANSPARENT
-};
-
-enum {
-	SOCKST_NONE = 0,
-	SOCKST_TCP_LISTEN,
-	SOCKST_TCP_EST,
-	SOCKST_UDP_READY
-};
-
-// TCP/UDP address message
-struct mw_addr_msg {
-	char dst_port[6];
-	char src_port[6];
-	uint8_t channel;
-	char host[];
-};
-
-#define FLAG_ONLINE 
-
-typedef struct {
-	uint32_t transmit_bytes;
-	uint32_t expected_bytes;
-	uint32_t receive_bytes;
-	uint32_t receive_read;
-	int      sock_fds[15];
-	uint16_t channel_flags;
-	uint8_t  channel_state[15];
-	uint8_t  scratchpad;
-	uint8_t  transmit_channel;
-	uint8_t  transmit_state;
-	uint8_t  module_state;
-	uint8_t  flags;
-	uint8_t  transmit_buffer[4096];
-	uint8_t  receive_buffer[4096];
-	struct sockaddr_in remote_addr[15];	// Needed for UDP sockets
-} megawifi;
-
-static megawifi *get_megawifi(void *context)
-{
-	m68k_context *m68k = context;
-	genesis_context *gen = m68k->system;
-	if (!gen->extra) {
-		socket_init();
-		gen->extra = calloc(1, sizeof(megawifi));
-		megawifi *mw = gen->extra;
-		mw->module_state = STATE_IDLE;
-		mw->flags = 0xE0; // cfg_ok, dt_ok, online
-		for (int i = 0; i < 15; i++) {
-			mw->sock_fds[i] = -1;
-		}
-	}
-	return gen->extra;
-}
-
-static void mw_putc(megawifi *mw, uint8_t v)
-{
-	if (mw->receive_bytes == sizeof(mw->receive_buffer)) {
-		return;
-	}
-	mw->receive_buffer[mw->receive_bytes++] = v;
-}
-
-static void mw_set(megawifi *mw, uint8_t val, uint32_t count)
-{
-	if (count + mw->receive_bytes > sizeof(mw->receive_buffer)) {
-		count = sizeof(mw->receive_buffer) - mw->receive_bytes;
-	}
-	memset(mw->receive_buffer + mw->receive_bytes, val, count);
-	mw->receive_bytes += count;
-}
-
-static void mw_copy(megawifi *mw, const uint8_t *src, uint32_t count)
-{
-	if (count + mw->receive_bytes > sizeof(mw->receive_buffer)) {
-		count = sizeof(mw->receive_buffer) - mw->receive_bytes;
-	}
-	memcpy(mw->receive_buffer + mw->receive_bytes, src, count);
-	mw->receive_bytes += count;
-}
-
-static void mw_puts(megawifi *mw, const char *s)
-{
-	size_t len = strlen(s);
-	mw_copy(mw, (uint8_t*)s, len);
-}
-
-static void udp_recv(megawifi *mw, uint8_t idx)
-{
-	ssize_t recvd;
-	int s = mw->sock_fds[idx];
-	struct sockaddr_in remote;
-	socklen_t addr_len = sizeof(struct sockaddr_in);
-
-	if (mw->remote_addr[idx].sin_addr.s_addr != htonl(INADDR_ANY)) {
-		// Receive only from specified address
-		recvd = recvfrom(s, (char*)mw->receive_buffer + 3, MAX_RECV_SIZE, 0,
-				(struct sockaddr*)&remote, &addr_len);
-		if (recvd > 0) {
-			if (remote.sin_addr.s_addr != mw->remote_addr[idx].sin_addr.s_addr) {
-				printf("Discarding UDP packet from unknown addr %s:%d\n",
-						inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
-				recvd = 0;
-			}
-		}
-	} else {
-		// Reuse mode, data is preceded by remote IPv4 and port
-		recvd = recvfrom(s, (char*)mw->receive_buffer + 9, MAX_RECV_SIZE - 6,
-				0, (struct sockaddr*)&remote, &addr_len);
-		if (recvd > 0) {
-			mw->receive_buffer[3] = remote.sin_addr.s_addr;
-			mw->receive_buffer[4] = remote.sin_addr.s_addr>>8;
-			mw->receive_buffer[5] = remote.sin_addr.s_addr>>16;
-			mw->receive_buffer[6] = remote.sin_addr.s_addr>>24;
-			mw->receive_buffer[7] = remote.sin_port;
-			mw->receive_buffer[8] = remote.sin_port>>8;
-			recvd += 6;
-		}
-	}
-
-	if (recvd > 0) {
-		mw_putc(mw, STX);
-		mw_putc(mw, (recvd >> 8) | ((idx+1) << 4));
-		mw_putc(mw, recvd);
-		mw->receive_bytes += recvd;
-		mw_putc(mw, ETX);
-		//should this set the channel flag?
-	} else if (recvd < 0 && !socket_error_is_wouldblock()) {
-		socket_close(mw->sock_fds[idx]);
-		mw->channel_state[idx] = SOCKST_NONE;
-		mw->channel_flags |= 1 << (idx + 1);
-	}
-}
-
-static void udp_send(megawifi *mw, uint8_t idx)
-{
-	struct sockaddr_in remote;
-	int s = mw->sock_fds[idx];
-	int sent;
-	char *data = (char*)mw->transmit_buffer;
-
-	if (mw->remote_addr[idx].sin_addr.s_addr != htonl(INADDR_ANY)) {
-		sent = sendto(s, data, mw->transmit_bytes, 0, (struct sockaddr*)&mw->remote_addr[idx],
-				sizeof(struct sockaddr_in));
-	} else {
-		// Reuse mode, extract address from leading bytes
-		// NOTE: mw->remote_addr[idx].sin_addr.s_addr == INADDR_ANY
-		remote.sin_addr.s_addr = *((int32_t*)data);
-		remote.sin_port = *((int16_t*)(data + 4));
-		remote.sin_family = AF_INET;
-		memset(remote.sin_zero, 0, sizeof(remote.sin_zero));
-		sent = sendto(s, data + 6, mw->transmit_bytes - 6, 0, (struct sockaddr*)&remote,
-				sizeof(struct sockaddr_in)) + 6;
-	}
-	if (sent < 0 && !socket_error_is_wouldblock()) {
-		socket_close(s);
-		mw->sock_fds[idx] = -1;
-		mw->channel_state[idx] = SOCKST_NONE;
-		mw->channel_flags |= 1 << (idx + 1);
-	} else if (sent < mw->transmit_bytes) {
-		//TODO: save this data somewhere so it can be sent in poll_socket
-		printf("Sent %d bytes on channel %d, but %d were requested\n", sent, idx + 1, mw->transmit_bytes);
-	}
-}
-
-static void poll_socket(megawifi *mw, uint8_t channel)
-{
-	if (mw->sock_fds[channel] < 0) {
-		return;
-	}
-	if (mw->channel_state[channel] == SOCKST_TCP_LISTEN) {
-		int res = accept(mw->sock_fds[channel], NULL, NULL);
-		if (res >= 0) {
-			socket_close(mw->sock_fds[channel]);
-			socket_blocking(res, 0);
-			mw->sock_fds[channel] = res;
-			mw->channel_state[channel] = SOCKST_TCP_EST;
-			mw->channel_flags |= 1 << (channel + 1);
-		} else if (errno != EAGAIN && errno != EWOULDBLOCK) {
-			socket_close(mw->sock_fds[channel]);
-			mw->channel_state[channel] = SOCKST_NONE;
-			mw->channel_flags |= 1 << (channel + 1);
-		}
-	} else if (mw->channel_state[channel] == SOCKST_TCP_EST && mw->receive_bytes < (sizeof(mw->receive_buffer) - 4)) {
-		size_t max = sizeof(mw->receive_buffer) - 4 - mw->receive_bytes;
-		if (max > MAX_RECV_SIZE) {
-			max = MAX_RECV_SIZE;
-		}
-		int bytes = recv(mw->sock_fds[channel], (char*)(mw->receive_buffer + mw->receive_bytes + 3), max, 0);
-		if (bytes > 0) {
-			mw_putc(mw, STX);
-			mw_putc(mw, bytes >> 8 | (channel+1) << 4);
-			mw_putc(mw, bytes);
-			mw->receive_bytes += bytes;
-			mw_putc(mw, ETX);
-			//should this set the channel flag?
-		} else if (bytes < 0 && !socket_error_is_wouldblock()) {
-			socket_close(mw->sock_fds[channel]);
-			mw->channel_state[channel] = SOCKST_NONE;
-			mw->channel_flags |= 1 << (channel + 1);
-		}
-	} else if (mw->channel_state[channel] == SOCKST_UDP_READY && !mw->receive_bytes) {
-		udp_recv(mw, channel);
-	}
-}
-
-static void poll_all_sockets(megawifi *mw)
-{
-	for (int i = 0; i < 15; i++)
-	{
-		poll_socket(mw, i);
-	}
-}
-
-
-static void start_reply(megawifi *mw, uint8_t cmd)
-{
-	mw_putc(mw, STX);
-	//reserve space for length
-	mw->receive_bytes += 2;
-	//cmd
-	mw_putc(mw, 0);
-	mw_putc(mw, cmd);
-	//reserve space for length
-	mw->receive_bytes += 2;
-}
-
-static void end_reply(megawifi *mw)
-{
-	uint32_t len = mw->receive_bytes - 3;
-	//LSD packet length
-	mw->receive_buffer[1] = len >> 8;
-	mw->receive_buffer[2] = len;
-	//command length
-	len -= 4;
-	mw->receive_buffer[5] = len >> 8;
-	mw->receive_buffer[6] = len;
-	mw_putc(mw, ETX);
-}
-
-static void cmd_ap_cfg_get(megawifi *mw)
-{
-	char ssid[32] = {0};
-	char pass[64] = {0};
-	uint8_t slot = mw->transmit_buffer[4];
-
-	sprintf(ssid, "BLASTEM! SSID %d", slot + 1);
-	sprintf(pass, "BLASTEM! PASS %d", slot + 1);
-	start_reply(mw, CMD_OK);
-	mw_putc(mw, slot);
-	mw_putc(mw, 7);	/// 11bgn
-	mw_copy(mw, (uint8_t*)ssid, 32);
-	mw_copy(mw, (uint8_t*)pass, 64);
-	end_reply(mw);
-}
-
-static void cmd_ip_cfg_get(megawifi *mw)
-{
-	uint32_t ipv4s[5] = {0};
-
-	start_reply(mw, CMD_OK);
-	mw_putc(mw, mw->transmit_buffer[4]);
-	mw_putc(mw, 0);
-	mw_putc(mw, 0);
-	mw_putc(mw, 0);
-	mw_copy(mw, (uint8_t*)ipv4s, sizeof(ipv4s));
-	end_reply(mw);
-}
-
-static void cmd_tcp_con(megawifi *mw, uint32_t size)
-{
-	struct mw_addr_msg *addr = (struct mw_addr_msg*)(mw->transmit_buffer + 4);
-	struct addrinfo hints;
-	struct addrinfo *res = NULL;
-	int s;
-	int err;
-
-	uint8_t channel = addr->channel;
-	if (!channel || channel > 15 || mw->sock_fds[channel - 1] >= 0) {
-		start_reply(mw, CMD_ERROR);
-		end_reply(mw);
-		return;
-	}
-	channel--;
-
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;
-#ifndef _WIN32
-	hints.ai_flags = AI_NUMERICSERV;
-#endif
-	hints.ai_socktype = SOCK_STREAM;
-
-	if ((err = getaddrinfo(addr->host, addr->dst_port, &hints, &res)) != 0) {
-		printf("getaddrinfo failed: %s\n", gai_strerror(err));
-		start_reply(mw, CMD_ERROR);
-		end_reply(mw);
-		return;
-	}
-
-	s = socket(AF_INET, SOCK_STREAM, 0);
-	if (s < 0) {
-		goto err;
-	}
-
-	// Should this be handled in a separate thread to avoid blocking emulation?
-	if (connect(s, res->ai_addr, res->ai_addrlen) != 0) {
-		goto err;
-	}
-
-	socket_blocking(s, 0);
-	mw->sock_fds[channel] = s;
-	mw->channel_state[channel] = SOCKST_TCP_EST;
-	mw->channel_flags |= 1 << (channel + 1);
-	printf("Connection established on ch %d with %s:%s\n", channel + 1,
-			addr->host, addr->dst_port);
-
-	if (res) {
-		freeaddrinfo(res);
-	}
-	start_reply(mw, CMD_OK);
-	end_reply(mw);
-	return;
-
-err:
-	freeaddrinfo(res);
-	printf("Connection to %s:%s failed, %s\n", addr->host, addr->dst_port, strerror(errno));
-	start_reply(mw, CMD_ERROR);
-	end_reply(mw);
-}
-
-static void cmd_close(megawifi *mw)
-{
-	int channel = mw->transmit_buffer[4] - 1;
-
-	if (channel >= 15 || mw->sock_fds[channel] < 0) {
-		start_reply(mw, CMD_ERROR);
-		end_reply(mw);
-		return;
-	}
-
-	socket_close(mw->sock_fds[channel]);
-	mw->sock_fds[channel] = -1;
-	mw->channel_state[channel] = SOCKST_NONE;
-	mw->channel_flags |= 1 << (channel + 1);
-	start_reply(mw, CMD_OK);
-	end_reply(mw);
-}
-
-static void cmd_udp_set(megawifi *mw)
-{
-	struct mw_addr_msg *addr = (struct mw_addr_msg*)(mw->transmit_buffer + 4);
-	unsigned int local_port, remote_port;
-	int s;
-	struct addrinfo *raddr;
-	struct addrinfo hints;
-	struct sockaddr_in local;
-	int err;
-
-	uint8_t channel = addr->channel;
-	if (!channel || channel > 15 || mw->sock_fds[channel - 1] >= 0) {
-		goto err;
-	}
-	channel--;
-	local_port = atoi(addr->src_port);
-	remote_port = atoi(addr->dst_port);
-
-	if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
-		printf("Datagram socket creation failed\n");
-		goto err;
-	}
-
-	memset(local.sin_zero, 0, sizeof(local.sin_zero));
-	local.sin_family = AF_INET;
-	local.sin_addr.s_addr = htonl(INADDR_ANY);
-	local.sin_port = htons(local_port);
-	if (remote_port && addr->host[0]) {
-		// Communication with remote peer
-		printf("Set UDP ch %d, port %d to addr %s:%d\n", addr->channel,
-				local_port, addr->host, remote_port);
-
-		memset(&hints, 0, sizeof(hints));
-		hints.ai_family = AF_INET;
-#ifndef _WIN32
-		hints.ai_flags = AI_NUMERICSERV;
-#endif
-		hints.ai_socktype = SOCK_DGRAM;
-
-		if ((err = getaddrinfo(addr->host, addr->dst_port, &hints, &raddr)) != 0) {
-			printf("getaddrinfo failed: %s\n", gai_strerror(err));
-			goto err;
-		}
-		mw->remote_addr[channel] = *((struct sockaddr_in*)raddr->ai_addr);
-		freeaddrinfo(raddr);
-	} else if (local_port) {
-		// Server in reuse mode
-		printf("Set UDP ch %d, src port %d\n", addr->channel, local_port);
-		mw->remote_addr[channel] = local;
-	} else {
-		printf("Invalid UDP socket data\n");
-		goto err;
-	}
-
-	if (bind(s, (struct sockaddr*)&local, sizeof(struct sockaddr_in)) < 0) {
-		printf("bind to port %d failed\n", local_port);
-		goto err;
-	}
-
-	socket_blocking(s, 0);
-	mw->sock_fds[channel] = s;
-	mw->channel_state[channel] = SOCKST_UDP_READY;
-	mw->channel_flags |= 1 << (channel + 1);
-
-	start_reply(mw, CMD_OK);
-	end_reply(mw);
-
-	return;
-
-err:
-	start_reply(mw, CMD_ERROR);
-	end_reply(mw);
-}
-
-#define AVATAR_BYTES	(32 * 48 / 2)
-static void cmd_gamertag_get(megawifi *mw)
-{
-	uint32_t id = htonl(1);
-	char buf[AVATAR_BYTES];
-
-	start_reply(mw, CMD_OK);
-	// TODO Get items from config file
-	mw_copy(mw, (uint8_t*)&id, 4);
-	strncpy(buf, "doragasu on Blastem!", 32);
-	mw_copy(mw, (uint8_t*)buf, 32);
-	strncpy(buf, "My cool password", 32);
-	mw_copy(mw, (uint8_t*)buf, 32);
-	strncpy(buf, "All your WiFi are belong to me!", 32);
-	mw_copy(mw, (uint8_t*)buf, 32);
-	memset(buf, 0, 64); // Telegram token
-	mw_copy(mw, (uint8_t*)buf, 64);
-	mw_copy(mw, (uint8_t*)buf, AVATAR_BYTES); // Avatar tiles
-	mw_copy(mw, (uint8_t*)buf, 32); // Avatar palette
-	end_reply(mw);
-}
-
-static void cmd_hrng_get(megawifi *mw)
-{
-	uint16_t len = (mw->transmit_buffer[4]<<8) + mw->transmit_buffer[5];
-	if (len > (MAX_RECV_SIZE - 4)) {
-		start_reply(mw, CMD_ERROR);
-		end_reply(mw);
-		return;
-	}
-	// Pseudo-random, but who cares
-	start_reply(mw, CMD_OK);
-	srand(time(NULL));
-	for (uint16_t i = 0; i < len; i++) {
-		mw_putc(mw, rand());
-	}
-	end_reply(mw);
-}
-
-static void cmd_datetime(megawifi *mw)
-{
-	start_reply(mw, CMD_OK);
-#ifdef _WIN32
-	__time64_t t = _time64(NULL);
-	int64_t t_be = htobe64(t);
-	mw_copy(mw, (uint8_t*)&t_be, sizeof(int64_t));
-	mw_puts(mw, _ctime64(&t));
-#else
-	time_t t = time(NULL);
-	int64_t t_be = htobe64(t);
-	mw_copy(mw, (uint8_t*)&t_be, sizeof(int64_t));
-	mw_puts(mw, ctime(&t));
-#endif
-
-	mw_putc(mw, '\0');
-	end_reply(mw);
-}
-
-static void process_command(megawifi *mw)
-{
-	uint32_t command = mw->transmit_buffer[0] << 8 | mw->transmit_buffer[1];
-	uint32_t size = mw->transmit_buffer[2] << 8 | mw->transmit_buffer[3];
-	if (size > mw->transmit_bytes - 4) {
-		size = mw->transmit_bytes - 4;
-	}
-	int orig_receive_bytes = mw->receive_bytes;
-	switch (command)
-	{
-	case CMD_VERSION:
-		start_reply(mw, CMD_OK);
-		mw_putc(mw, 1);
-		mw_putc(mw, 3);
-		mw_putc(mw, 0);
-		mw_puts(mw, "blastem");
-		mw_putc(mw, '\0');
-		end_reply(mw);
-		break;
-	case CMD_ECHO:
-		mw->receive_bytes = mw->transmit_bytes;
-		memcpy(mw->receive_buffer, mw->transmit_buffer, mw->transmit_bytes);
-		break;
-	case CMD_AP_CFG_GET:
-		cmd_ap_cfg_get(mw);
-		break;
-	case CMD_IP_CURRENT: {
-		iface_info i;
-		if (get_host_address(&i)) {
-			start_reply(mw, CMD_OK);
-			//config number and reserved bytes
-			mw_set(mw, 0, 4);
-			//ip
-			mw_copy(mw, i.ip, sizeof(i.ip));
-			//net mask
-			mw_copy(mw, i.net_mask, sizeof(i.net_mask));
-			//gateway guess
-			mw_putc(mw, i.ip[0] & i.net_mask[0]);
-			mw_putc(mw, i.ip[1] & i.net_mask[1]);
-			mw_putc(mw, i.ip[2] & i.net_mask[2]);
-			mw_putc(mw, (i.ip[3] & i.net_mask[3]) + 1);
-			//dns
-			static const uint8_t localhost[] = {127,0,0,1};
-			mw_copy(mw, localhost, sizeof(localhost));
-			mw_copy(mw, localhost, sizeof(localhost));
-			
-		} else {
-			start_reply(mw, CMD_ERROR);
-		}
-		end_reply(mw);
-		break;
-	}
-	case CMD_IP_CFG_GET:
-		cmd_ip_cfg_get(mw);
-		break;
-	case CMD_DEF_AP_CFG_GET:
-		start_reply(mw, CMD_OK);
-		mw_putc(mw, 0);
-		end_reply(mw);
-		break;
-	case CMD_AP_JOIN:
-		mw->module_state = STATE_READY;
-		start_reply(mw, CMD_OK);
-		end_reply(mw);
-		break;
-	case CMD_TCP_CON:
-		cmd_tcp_con(mw, size);
-		break;
-	case CMD_TCP_BIND:{
-		if (size < 7){
-			start_reply(mw, CMD_ERROR);
-			end_reply(mw);
-			break;
-		}
-		uint8_t channel = mw->transmit_buffer[10];
-		if (!channel || channel > 15) {
-			start_reply(mw, CMD_ERROR);
-			end_reply(mw);
-			break;
-		}
-		channel--;
-		if (mw->sock_fds[channel] >= 0) {
-			socket_close(mw->sock_fds[channel]);
-		}
-		mw->sock_fds[channel] = socket(AF_INET, SOCK_STREAM, 0);
-		if (mw->sock_fds[channel] < 0) {
-			start_reply(mw, CMD_ERROR);
-			end_reply(mw);
-			break;
-		}
-		int value = 1;
-		setsockopt(mw->sock_fds[channel], SOL_SOCKET, SO_REUSEADDR, (char*)&value, sizeof(value));
-		struct sockaddr_in bind_addr;
-		memset(&bind_addr, 0, sizeof(bind_addr));
-		bind_addr.sin_family = AF_INET;
-		bind_addr.sin_port = htons(mw->transmit_buffer[8] << 8 | mw->transmit_buffer[9]);
-		if (bind(mw->sock_fds[channel], (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0) {
-			socket_close(mw->sock_fds[channel]);
-			mw->sock_fds[channel] = -1;
-			start_reply(mw, CMD_ERROR);
-			end_reply(mw);
-			break;
-		}
-		int res = listen(mw->sock_fds[channel], 2);
-		start_reply(mw, res ? CMD_ERROR : CMD_OK);
-		if (res) {
-			socket_close(mw->sock_fds[channel]);
-			mw->sock_fds[channel] = -1;
-		} else {
-			mw->channel_flags |= 1 << (channel + 1);
-			mw->channel_state[channel] = SOCKST_TCP_LISTEN;
-			socket_blocking(mw->sock_fds[channel], 0);
-		}
-		end_reply(mw);
-		break;
-	}
-	case CMD_CLOSE:
-		cmd_close(mw);
-		break;
-	case CMD_UDP_SET:
-		cmd_udp_set(mw);
-		break;
-	case CMD_SOCK_STAT: {
-		uint8_t channel = mw->transmit_buffer[4];
-		if (!channel || channel > 15) {
-			start_reply(mw, CMD_ERROR);
-			end_reply(mw);
-			break;
-		}
-		mw->channel_flags &= ~(1 << channel);
-		channel--;
-		poll_socket(mw, channel);
-		start_reply(mw, CMD_OK);
-		mw_putc(mw, mw->channel_state[channel]);
-		end_reply(mw);
-		break;
-	}
-	case CMD_DATETIME:
-		cmd_datetime(mw);
-		break;
-	case CMD_SYS_STAT:
-		poll_all_sockets(mw);
-		start_reply(mw, CMD_OK);
-		mw_putc(mw, mw->module_state);
-		mw_putc(mw, mw->flags);
-		mw_putc(mw, mw->channel_flags >> 8);
-		mw_putc(mw, mw->channel_flags);
-		end_reply(mw);
-		break;
-	case CMD_GAMERTAG_GET:
-		cmd_gamertag_get(mw);
-		break;
-	case CMD_LOG:
-		start_reply(mw, CMD_OK);
-		puts((char*)&mw->transmit_buffer[4]);
-		end_reply(mw);
-		break;
-	case CMD_HRNG_GET:
-		cmd_hrng_get(mw);
-		break;
-	case CMD_SERVER_URL_GET:
-		start_reply(mw, CMD_OK);
-		// FIXME: This should be get from config file
-		mw_puts(mw, "doragasu.com");
-		mw_putc(mw,'\0');
-		end_reply(mw);
-		break;
-	default:
-		printf("Unhandled MegaWiFi command %s(%d) with length %X\n", cmd_names[command], command, size);
-		break;
-	}
-}
-
-static void process_packet(megawifi *mw)
-{
-	if (mw->transmit_channel == 0) {
-		process_command(mw);
-	} else {
-		uint8_t channel = mw->transmit_channel - 1;
-		int channel_state = mw->channel_state[channel];
-		int sock_fd = mw->sock_fds[channel];
-		if (sock_fd >= 0 && channel_state == SOCKST_TCP_EST) {
-			int sent = send(sock_fd, (char*)mw->transmit_buffer, mw->transmit_bytes, 0);
-			if (sent < 0 && !socket_error_is_wouldblock()) {
-				socket_close(sock_fd);
-				mw->sock_fds[channel] = -1;
-				mw->channel_state[channel] = SOCKST_NONE;
-				mw->channel_flags |= 1 << mw->transmit_channel;
-			} else if (sent < mw->transmit_bytes) {
-				//TODO: save this data somewhere so it can be sent in poll_socket
-				printf("Sent %d bytes on channel %d, but %d were requested\n", sent, mw->transmit_channel, mw->transmit_bytes);
-			}
-		} else if (sock_fd >= 0 && channel_state == SOCKST_UDP_READY) {
-			udp_send(mw, channel);
-		} else {
-			printf("Unhandled receive of MegaWiFi data on channel %d\n", mw->transmit_channel);
-		}
-	}
-	mw->transmit_bytes = mw->expected_bytes = 0;
-}
-
-void *megawifi_write_b(uint32_t address, void *context, uint8_t value)
-{
-	if (!(address & 1)) {
-		return context;
-	}
-	megawifi *mw = get_megawifi(context);
-	address = address >> 1 & 7;
-	switch (address)
-	{
-	case 0:
-		switch (mw->transmit_state)
-		{
-		case TX_IDLE:
-			if (value == STX) {
-				mw->transmit_state = TX_LEN1;
-			}
-			break;
-		case TX_LEN1:
-			mw->transmit_channel = value >> 4;
-			mw->expected_bytes = value << 8 & 0xF00;
-			mw->transmit_state = TX_LEN2;
-			break;
-		case TX_LEN2:
-			mw->expected_bytes |= value;
-			mw->transmit_state = TX_PAYLOAD;
-			break;
-		case TX_PAYLOAD:
-			mw->transmit_buffer[mw->transmit_bytes++] = value;
-			if (mw->transmit_bytes == mw->expected_bytes) {
-				mw->transmit_state = TX_WAIT_ETX;
-			}
-			break;
-		case TX_WAIT_ETX:
-			if (value == ETX) {
-				mw->transmit_state = TX_IDLE;
-				process_packet(mw);
-			}
-			break;
-		}
-		break;
-	case 7:
-		mw->scratchpad = value;
-		break;
-	default:
-		printf("Unhandled write to MegaWiFi UART register %X: %X\n", address, value);
-	}
-	return context;
-}
-
-void *megawifi_write_w(uint32_t address, void *context, uint16_t value)
-{
-	return megawifi_write_b(address | 1, context, value);
-}
-
-uint8_t megawifi_read_b(uint32_t address, void *context)
-{
-	
-	if (!(address & 1)) {
-		return 0xFF;
-	}
-	megawifi *mw = get_megawifi(context);
-	address = address >> 1 & 7;
-	switch (address)
-	{
-	case 0:
-		poll_all_sockets(mw);
-		if (mw->receive_read < mw->receive_bytes) {
-			uint8_t ret = mw->receive_buffer[mw->receive_read++];
-			if (mw->receive_read == mw->receive_bytes) {
-				mw->receive_read = mw->receive_bytes = 0;
-			}
-			return ret;
-		}
-		return 0xFF;
-	case 5:
-		poll_all_sockets(mw);
-		//line status
-		return 0x60 | (mw->receive_read < mw->receive_bytes);
-	case 7:
-		return mw->scratchpad;
-	default:
-		printf("Unhandled read from MegaWiFi UART register %X\n", address);
-		return 0xFF;
-	}
-}
-
-uint16_t megawifi_read_w(uint32_t address, void *context)
-{
-	return 0xFF00 | megawifi_read_b(address | 1, context);
-}
--- a/megawifi.h	Thu Aug 05 23:48:41 2021 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef MEGAWIFI_H_
-#define MEGAWIFI_H_
-
-void *megawifi_write_w(uint32_t address, void *context, uint16_t value);
-void *megawifi_write_b(uint32_t address, void *context, uint8_t value);
-uint16_t megawifi_read_w(uint32_t address, void *context);
-uint8_t megawifi_read_b(uint32_t address, void *context);
-
-#endif //MEGAWIFI_H_
--- a/romdb.c	Thu Aug 05 23:48:41 2021 -0700
+++ b/romdb.c	Tue Sep 21 23:17:34 2021 -0700
@@ -11,7 +11,6 @@
 #include "nor.h"
 #include "sega_mapper.h"
 #include "multi_game.h"
-#include "megawifi.h"
 #include "jcart.h"
 #include "blastem.h"
 
@@ -298,46 +297,6 @@
 		info->map[8].write_16 = (write_16_fun)write_bank_reg_w;
 		info->map[8].write_8 = (write_8_fun)write_bank_reg_b;
 		return;
-	} else if(!memcmp("SEGA MEGAWIFI", rom + 0x100, strlen("SEGA MEGAWIFI"))) {
-		info->mapper_type = MAPPER_NONE;
-		info->map_chunks = base_chunks + 2;
-		info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
-		memset(info->map, 0, sizeof(memmap_chunk)*2);
-		memcpy(info->map+2, base_map, sizeof(memmap_chunk) * base_chunks);
-		info->save_size = 0x400000;
-		info->save_bus = RAM_FLAG_BOTH;
-		info->save_type = SAVE_NOR;
-		info->map[0].start = 0;
-		info->map[0].end = 0x400000;
-		info->map[0].mask = 0xFFFFFF;
-		info->map[0].write_16 = nor_flash_write_w;
-		info->map[0].write_8 = nor_flash_write_b;
-		info->map[0].read_16 = nor_flash_read_w;
-		info->map[0].read_8 = nor_flash_read_b;
-		info->map[0].flags = MMAP_READ_CODE | MMAP_CODE;
-		info->map[0].buffer = info->save_buffer = calloc(info->save_size, 1);
-		uint32_t init_size = size < info->save_size ? size : info->save_size;
-		memcpy(info->save_buffer, rom, init_size);
-		byteswap_rom(info->save_size, (uint16_t *)info->save_buffer);
-		info->nor = calloc(1, sizeof(nor_state));
-		nor_flash_init(info->nor, info->save_buffer, info->save_size, 128, 0xDA45, RAM_FLAG_BOTH);
-		info->nor->cmd_address1 = 0xAAB;
-		info->nor->cmd_address2 = 0x555;
-		info->map[1].start = 0xA130C0;
-		info->map[1].end = 0xA130D0;
-		info->map[1].mask = 0xFFFFFF;
-		if (!strcmp(
-			"on", 
-			tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval)
-		) {
-			info->map[1].write_16 = megawifi_write_w;
-			info->map[1].write_8 = megawifi_write_b;
-			info->map[1].read_16 = megawifi_read_w;
-			info->map[1].read_8 = megawifi_read_b;
-		} else {
-			warning("ROM uses MegaWiFi, but it is disabled\n");
-		}
-		return;
 	} else if (has_ram_header(rom, size)) {
 		uint32_t ram_start = read_ram_header(info, rom);
 
@@ -866,20 +825,6 @@
 		map->mask = 0xFF;
 		map->write_16 = write_multi_game_w;
 		map->write_8 = write_multi_game_b;
-	} else if (!strcmp(dtype, "megawifi")) {
-		if (!strcmp(
-			"on", 
-			tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval)
-		) {
-			map->write_16 = megawifi_write_w;
-			map->write_8 = megawifi_write_b;
-			map->read_16 = megawifi_read_w;
-			map->read_8 = megawifi_read_b;
-			map->mask = 0xFFFFFF;
-		} else {
-			warning("ROM uses MegaWiFi, but it is disabled\n");
-			return;
-		}
 	} else if (!strcmp(dtype, "jcart")) {
 		state->info->mapper_type = MAPPER_JCART;
 		map->write_16 = jcart_write_w;