diff --git a/AltairZ80/altairz80_cpu.c b/AltairZ80/altairz80_cpu.c index 9afd4ce95..d6b261859 100644 --- a/AltairZ80/altairz80_cpu.c +++ b/AltairZ80/altairz80_cpu.c @@ -164,12 +164,14 @@ static t_stat cpu_set_nonbanked (UNIT *uptr, int32 value, CONST char *cptr, static t_stat cpu_set_ramtype (UNIT *uptr, int32 value, CONST char *cptr, void *desc); static t_stat cpu_set_chiptype (UNIT *uptr, int32 value, CONST char *cptr, void *desc); static t_stat cpu_set_size (UNIT *uptr, int32 value, CONST char *cptr, void *desc); +static t_stat set_size (uint32 size, t_bool unmap); static t_stat m68k_set_chiptype (UNIT * uptr, int32 value, CONST char* cptr, void* desc); static t_stat cpu_set_memory (UNIT *uptr, int32 value, CONST char *cptr, void *desc); +static t_stat cpu_resize_memory (UNIT *uptr, int32 value, CONST char *cptr, void *desc); static t_stat cpu_set_hist (UNIT *uptr, int32 val, CONST char *cptr, void *desc); static t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, CONST void *desc); static t_stat cpu_clear_command (UNIT *uptr, int32 value, CONST char *cptr, void *desc); -static void cpu_clear(void); +static void cpu_clear(t_bool unmap); static t_stat cpu_show (FILE *st, UNIT *uptr, int32 val, CONST void *desc); static t_stat chip_show (FILE *st, UNIT *uptr, int32 val, CONST void *desc); static t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); @@ -536,13 +538,15 @@ static MTAB cpu_mod[] = { { UNIT_CPU_VERBOSE, 0, "QUIET", "QUIET", NULL, NULL, NULL, "Disable verbose messages" }, { MTAB_VDV, 0, NULL, "CLEARMEMORY", &cpu_clear_command, - NULL, NULL, "Clears the RAM" }, + NULL, NULL, "Clears the RAM and removes mapped memory handlers" }, { UNIT_CPU_MMU, UNIT_CPU_MMU, "MMU", "MMU", NULL, NULL, NULL, "Enable the Memory Management Unit for 8080 / Z80" }, { UNIT_CPU_MMU, 0, "NOMMU", "NOMMU", &cpu_set_nommu, NULL, NULL, "Disable the Memory Management Unit for 8080 / Z80" }, - { MTAB_XTD | MTAB_VDV, 0, NULL, "MEMORY", &cpu_set_memory, - NULL, NULL, "Sets the RAM size for 8080 / Z80 / 8086" }, + { MTAB_XTD | MTAB_VDV | MTAB_VALR, 0, NULL, "MEMORY", &cpu_set_memory, + NULL, NULL, "Sets the RAM size and removes mapped memory handlers for 8080 / Z80 / 8086" }, + { MTAB_XTD | MTAB_VDV | MTAB_VALR, 0, NULL, "RESIZEMEMORY", &cpu_resize_memory, + NULL, NULL, "Sets the RAM size without removing mapped memory handlers for 8080 / Z80 / 8086" }, { UNIT_CPU_SWITCHER, UNIT_CPU_SWITCHER, "SWITCHER", "SWITCHER", &cpu_set_switcher, &cpu_show_switcher, NULL, "Sets CPU switcher port for 8080 / Z80 / 8086" }, { UNIT_CPU_SWITCHER, 0, "NOSWITCHER", "NOSWITCHER", &cpu_reset_switcher, &cpu_show_switcher, @@ -6700,14 +6704,19 @@ static t_stat cpu_show(FILE *st, UNIT *uptr, int32 val, CONST void *desc) { return SCPE_OK; } -static void cpu_clear(void) { +static void cpu_clear(t_bool unmap) { uint32 i; for (i = 0; i < MAXMEMORY; i++) M[i] = 0; for (i = 0; i < (MAXMEMORY >> LOG2PAGESIZE); i++) - mmu_table[i] = RAM_PAGE; + if (!mmu_table[i].routine || unmap) { + if (mmu_table[i].routine && (cpu_unit.flags & UNIT_CPU_VERBOSE)) + sim_printf("Unmapping memory 0x%05x, handler=%s\n", i << LOG2PAGESIZE, mmu_table[i].name); + mmu_table[i] = RAM_PAGE; + } for (i = (MEMORYSIZE >> LOG2PAGESIZE); i < (MAXMEMORY >> LOG2PAGESIZE); i++) - mmu_table[i] = EMPTY_PAGE; + if (!mmu_table[i].routine || unmap) + mmu_table[i] = EMPTY_PAGE; if (cpu_unit.flags & UNIT_CPU_ALTAIRROM) install_ALTAIRbootROM(); m68k_clear_memory(); @@ -6715,7 +6724,7 @@ static void cpu_clear(void) { } static t_stat cpu_clear_command(UNIT *uptr, int32 value, CONST char *cptr, void *desc) { - cpu_clear(); + cpu_clear(TRUE); return SCPE_OK; } @@ -6754,7 +6763,7 @@ static t_stat cpu_set_banked(UNIT *uptr, int32 value, CONST char *cptr, void *de previousCapacity = MEMORYSIZE; MEMORYSIZE = MAXMEMORY; cpu_dev.awidth = MAXBANKSIZELOG2 + MAXBANKSLOG2; - cpu_clear(); + cpu_clear(TRUE); } else if (chiptype == CHIP_TYPE_8086) { sim_printf("Cannot use banked memory for 8086 CPU.\n"); return SCPE_ARG; @@ -6766,7 +6775,7 @@ static t_stat cpu_set_nonbanked(UNIT *uptr, int32 value, CONST char *cptr, void if ((chiptype == CHIP_TYPE_8080) || (chiptype == CHIP_TYPE_Z80)) { MEMORYSIZE = previousCapacity; cpu_dev.awidth = MAXBANKSIZELOG2; - cpu_clear(); + cpu_clear(TRUE); } return SCPE_OK; } @@ -6904,7 +6913,7 @@ static void cpu_set_chiptype_short(const int32 value) { static t_stat cpu_set_chiptype(UNIT *uptr, int32 value, CONST char *cptr, void *desc) { cpu_set_chiptype_short(value); - cpu_clear(); + cpu_clear(TRUE); return SCPE_OK; } @@ -7037,7 +7046,7 @@ static t_stat cpu_set_ramtype(UNIT *uptr, int32 value, CONST char *cptr, void *d } /* set memory to 'size' kilo byte */ -static t_stat set_size(uint32 size) { +static t_stat set_size(uint32 size, t_bool unmap) { uint32 maxsize; if (chiptype == CHIP_TYPE_M68K) { // ignore for M68K if (cpu_unit.flags & UNIT_CPU_VERBOSE) @@ -7059,23 +7068,40 @@ static t_stat set_size(uint32 size) { cpu_dev.awidth = MAXBANKSIZELOG2; if (size > MAXBANKSIZE) cpu_dev.awidth += MAXBANKSLOG2; - cpu_clear(); + cpu_clear(unmap); return SCPE_OK; } static t_stat cpu_set_size(UNIT *uptr, int32 value, CONST char *cptr, void *desc) { - return set_size(value); + return set_size(value, TRUE); } static t_stat cpu_set_memory(UNIT *uptr, int32 value, CONST char *cptr, void *desc) { uint32 size, result, i; - if (cptr == NULL) - return SCPE_ARG; + if (cptr == NULL) { + sim_printf("Memory size must be provided as SET CPU MEMORY=xK\n"); + return SCPE_ARG | SCPE_NOMESSAGE; + } + result = sscanf(cptr, "%i%n", &size, &i); + if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) || + ((cptr[i + 1] == 'B') && (cptr[i + 2] == 0)))) + return set_size(size, TRUE); + sim_printf("Memory size must be specified as xK\n"); + return SCPE_ARG | SCPE_NOMESSAGE; +} + +static t_stat cpu_resize_memory(UNIT *uptr, int32 value, CONST char *cptr, void *desc) { + uint32 size, result, i; + if (cptr == NULL) { + sim_printf("Memory size must be provided as SET CPU RESIZEMEMORY=xK\n"); + return SCPE_ARG | SCPE_NOMESSAGE; + } result = sscanf(cptr, "%i%n", &size, &i); if ((result == 1) && (cptr[i] == 'K') && ((cptr[i + 1] == 0) || ((cptr[i + 1] == 'B') && (cptr[i + 2] == 0)))) - return set_size(size); - return SCPE_ARG; + return set_size(size, FALSE); + sim_printf("Memory size must be specified as xK\n"); + return SCPE_ARG | SCPE_NOMESSAGE; } static t_stat m68k_set_chiptype(UNIT* uptr, int32 value, CONST char* cptr, void* desc) { @@ -7233,7 +7259,7 @@ t_value altairz80_pc_value (void) { /* AltairZ80 Simulator initialization */ void altairz80_init(void) { - cpu_clear(); + cpu_clear(TRUE); sim_vm_pc_value = &altairz80_pc_value; /* altairz80_print_tables(); */ }