Skip to content

Commit

Permalink
AltairZ80: Adds SET CPU RESIZEMEMORY and other
Browse files Browse the repository at this point in the history
Changing the CPU type or MEMORY size/configuration causes memory
resources mapped by other devices to be removed. This is not made
clear by "HELP CPU" and the user has no feedback that this is
happening.

This PR does the following:

1) HELP SET CPU shows that SET CPU MEMORY requires a value.
2) Feedback is provided if the value is omitted or not properly formatted.
3) Unmapped memory resources caused by a SET CPU command are displayed
   on the SIMH console.
4) Adds a SET CPU RESIZEMEMORY command that resizes system memory
   without unmapping other device memory resources.
  • Loading branch information
deltecent committed Jan 14, 2024
1 parent c077c22 commit 8c5df1c
Showing 1 changed file with 45 additions and 19 deletions.
64 changes: 45 additions & 19 deletions AltairZ80/altairz80_cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -6700,22 +6704,27 @@ 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)
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();
clockHasChanged = FALSE;
}

static t_stat cpu_clear_command(UNIT *uptr, int32 value, CONST char *cptr, void *desc) {
cpu_clear();
cpu_clear(TRUE);
return SCPE_OK;
}

Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand All @@ -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) {
Expand Down Expand Up @@ -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(); */
}
Expand Down

0 comments on commit 8c5df1c

Please sign in to comment.