/** * Take into account the Falcon Bus Control register $ff8007.b $FFFF8007 Falcon Bus Control BIT 6 : F30 Start (0=Cold, 1=Warm) BIT 5 : STe Bus Emulation (0=on) BIT 3 : Blitter Flag (0=on, 1=off) BIT 2 : Blitter (0=8mhz, 1=16mhz) BIT 0 : 68030 (0=8mhz, 1=16mhz) */ static void IoMemTabFalcon_BusCtrl_WriteByte(void) { Uint8 busCtrl = IoMem_ReadByte(0xff8007); /* Set Falcon bus or STE compatible bus emulation */ if ((busCtrl & 0x20) == 0) IoMem_Init_FalconInSTeBuscompatibilityMode(0); else IoMem_Init_FalconInSTeBuscompatibilityMode(1); /* 68030 Frequency changed ? */ /* We change freq only in 68030 mode for a normal Falcon, */ /* not if CPU is 68040 or 68060 is used */ if ( ConfigureParams.System.nCpuLevel == 3 ) { if ((busCtrl & 0x1) == 1) { /* 16 Mhz bus for 68030 */ nCpuFreqShift = 1; ConfigureParams.System.nCpuFreq = 16; } else { /* 8 Mhz bus for 68030 */ nCpuFreqShift = 0; ConfigureParams.System.nCpuFreq = 8; } } Statusbar_UpdateInfo(); /* Update clock speed in the status bar */ }
bool DSP_ProcessIRQ(void) { if (bDspHostInterruptPending && regs.intmask < 6) { M68000_Exception(IoMem_ReadByte(0xffa203)*4, M68000_EXC_SRC_INT_DSP); bDspHostInterruptPending = false; // M68000_UnsetSpecial(SPCFLAG_DSP); return true; } return false; }
/** * Write to RTC/NVRAM offset selection register ($ff8961) */ void NvRam_Select_WriteByte(void) { Uint8 value = IoMem_ReadByte(0xff8961); if (value < sizeof(nvram)) { nvram_index = value; } else { Log_Printf(LOG_WARN, "NVRAM: trying to set out-of-bound position (%d)\n", value); } }
/** * Set default memory configuration, connected floppies, memory size and * clear the ST-RAM area. * As TOS checks hardware for memory size + connected devices on boot-up * we set these values ourselves and fill in the magic numbers so TOS * skips these tests. */ void STMemory_SetDefaultConfig(void) { int i; int screensize, limit; int memtop, phystop; Uint8 nMemControllerByte; Uint8 nFalcSysCntrl; static const int MemControllerTable[] = { 0x01, /* 512 KiB */ 0x05, /* 1 MiB */ 0x02, /* 2 MiB */ 0x06, /* 2.5 MiB */ 0x0A /* 4 MiB */ }; if (bRamTosImage) { /* Clear ST-RAM, excluding the RAM TOS image */ STMemory_Clear(0x00000000, TosAddress); STMemory_Clear(TosAddress+TosSize, STRamEnd); } else { /* Clear whole ST-RAM */ STMemory_Clear(0x00000000, STRamEnd); } /* Mirror ROM boot vectors */ STMemory_WriteLong(0x00, STMemory_ReadLong(TosAddress)); STMemory_WriteLong(0x04, STMemory_ReadLong(TosAddress+4)); /* Fill in magic numbers to bypass TOS' memory tests for faster boot or * if VDI resolution is enabled or if more than 4 MB of ram are used * or if TT RAM added in Falcon mode. * (for highest compatibility, those tests should not be bypassed in * the common STF/STE cases as some programs like "Yolanda" rely on * the RAM content after those tests) */ if ( ConfigureParams.System.bFastBoot || bUseVDIRes || ( ConfigureParams.Memory.nMemorySize > 4 && !bIsEmuTOS ) || ( ( ConfigureParams.System.nMachineType == MACHINE_FALCON ) && TTmemory ) ) { /* Write magic values to sysvars to signal valid config */ STMemory_WriteLong(0x420, 0x752019f3); /* memvalid */ STMemory_WriteLong(0x43a, 0x237698aa); /* memval2 */ STMemory_WriteLong(0x51a, 0x5555aaaa); /* memval3 */ /* If ST RAM detection is bypassed, we must also force TT RAM config if enabled */ if ( TTmemory ) STMemory_WriteLong ( 0x5a4 , 0x01000000 + TTmem_size ); /* ramtop */ else STMemory_WriteLong ( 0x5a4 , 0 ); /* ramtop */ STMemory_WriteLong ( 0x5a8 , 0x1357bd13 ); /* ramvalid */ /* On Falcon, set bit6=1 at $ff8007 to simulate a warm start */ /* (else memory detection is not skipped after a cold start/reset) */ if ( ConfigureParams.System.nMachineType == MACHINE_FALCON ) STMemory_WriteByte ( 0xff8007, IoMem_ReadByte(0xff8007) | 0x40 ); /* On TT, set bit0=1 at $ff8e09 to simulate a warm start */ /* (else memory detection is not skipped after a cold start/reset) */ if ( ConfigureParams.System.nMachineType == MACHINE_TT ) STMemory_WriteByte ( 0xff8e09, IoMem_ReadByte(0xff8e09) | 0x01 ); } /* Set memory size, adjust for extra VDI screens if needed. */ screensize = VDIWidth * VDIHeight / 8 * VDIPlanes; /* Use 32 kiB in normal screen mode or when the screen size is smaller than 32 kiB */ if (!bUseVDIRes || screensize < 0x8000) screensize = 0x8000; /* mem top - upper end of user memory (right before the screen memory) * memtop / phystop must be dividable by 512 or TOS crashes */ memtop = (STRamEnd - screensize) & 0xfffffe00; /* phys top - 32k gap causes least issues with apps & TOS * as that's the largest _common_ screen size. EmuTOS behavior * depends on machine type. * * TODO: what to do about _native_ TT & Videl resolutions * which size is >32k? Should memtop be adapted also for * those? */ switch (ConfigureParams.System.nMachineType) { case MACHINE_FALCON: /* TOS v4 doesn't work with VDI mode (yet), and * EmuTOS works with correct gap, so use that */ phystop = STRamEnd; break; case MACHINE_TT: /* For correct TOS v3 memory detection, phystop should be * at the end of memory, not at memtop + 32k. * * However: * - TOS v3 crashes/hangs if phystop-memtop gap is larger * than largest real HW screen size (150k) * - NVDI hangs if gap is larger than 32k in any other than * monochrome mode */ if (VDIPlanes == 1) limit = 1280*960/8; else limit = 0x8000; if (screensize > limit) { phystop = memtop + limit; fprintf(stderr, "WARNING: too large VDI mode for TOS v3 memory detection to work correctly!\n"); } else phystop = STRamEnd; break; default: phystop = memtop + 0x8000; } STMemory_WriteLong(0x436, memtop); STMemory_WriteLong(0x42e, phystop); if (bUseVDIRes) fprintf(stderr, "VDI mode memtop: 0x%x, phystop: 0x%x (screensize: %d kB, memtop->phystop: %d kB)\n", memtop, phystop, (screensize+511) / 1024, (phystop-memtop+511) / 1024); /* Set memory controller byte according to different memory sizes */ /* Setting per bank: %00=128k %01=512k %10=2Mb %11=reserved. - e.g. %1010 means 4Mb */ if (ConfigureParams.Memory.nMemorySize <= 4) nMemControllerByte = MemControllerTable[ConfigureParams.Memory.nMemorySize]; else nMemControllerByte = 0x0f; STMemory_WriteByte(0x424, nMemControllerByte); IoMem_WriteByte(0xff8001, nMemControllerByte); if (ConfigureParams.System.nMachineType == MACHINE_FALCON) { /* Set the Falcon memory and monitor configuration register: $ffff8006.b [R] 76543210 Monitor-memory |||||||| |||||||+- RAM Wait Status ||||||| 0 = 1 Wait (default) ||||||| 1 = 0 Wait ||||||+-- Video Bus size ??? |||||| 0 = 16 Bit |||||| 1 = 32 Bit (default) ||||++--- ROM Wait Status |||| 00 = Reserved |||| 01 = 2 Wait (default) |||| 10 = 1 Wait |||| 11 = 0 Wait ||++----- Falcon Memory || 00 = 1 MB || 01 = 4 MB || 10 = 14 MB || 11 = no boot ! ++------- Monitor-Typ 00 - Monochrome (SM124) 01 - Color (SC1224) 10 - VGA Color 11 - Television Bit 1 seems not to be well documented. It's used by TOS at bootup to compute the memory size. After some tests, I get the following RAM values (Bits 5, 4, 1 are involved) : 00 = 512 Ko 20 = 8192 Ko 02 = 1024 Ko 22 = 14366 Ko 10 = 2048 Ko 30 = Illegal 12 = 4096 Ko 32 = Illegal I use these values for Hatari's emulation. I also set the bit 3 and 2 at value 01 are mentioned in the register description. */ if (ConfigureParams.Memory.nMemorySize == 14) /* 14 Meg */ nFalcSysCntrl = 0x26; else if (ConfigureParams.Memory.nMemorySize == 8) /* 8 Meg */ nFalcSysCntrl = 0x24; else if (ConfigureParams.Memory.nMemorySize == 4) /* 4 Meg */ nFalcSysCntrl = 0x16; else if (ConfigureParams.Memory.nMemorySize == 2) /* 2 Meg */ nFalcSysCntrl = 0x14; else if (ConfigureParams.Memory.nMemorySize == 1) /* 1 Meg */ nFalcSysCntrl = 0x06; else nFalcSysCntrl = 0x04; /* 512 Ko */ switch(ConfigureParams.Screen.nMonitorType) { case MONITOR_TYPE_TV: nFalcSysCntrl |= FALCON_MONITOR_TV; break; case MONITOR_TYPE_VGA: nFalcSysCntrl |= FALCON_MONITOR_VGA; break; case MONITOR_TYPE_RGB: nFalcSysCntrl |= FALCON_MONITOR_RGB; break; case MONITOR_TYPE_MONO: nFalcSysCntrl |= FALCON_MONITOR_MONO; break; } STMemory_WriteByte(0xff8006, nFalcSysCntrl); } /* Set TOS floppies */ STMemory_WriteWord(0x446, nBootDrive); /* Boot up on A(0) or C(2) */ /* Create connected drives mask (only for harddrives, don't change floppy drive detected by TOS) */ ConnectedDriveMask = STMemory_ReadLong(0x4c2); // Get initial drive mask (see what TOS thinks) if (GEMDOS_EMU_ON) { for (i = 0; i < MAX_HARDDRIVES; i++) { if (emudrives[i] != NULL) // Is this GEMDOS drive enabled? ConnectedDriveMask |= (1 << emudrives[i]->drive_number); } } /* Set connected drives system variable. * NOTE: some TOS images overwrite this value, see 'OpCode_SysInit', too */ STMemory_WriteLong(0x4c2, ConnectedDriveMask); }
void NvRam_Data_WriteByte(void) { Uint8 value = IoMem_ReadByte(0xff8963); LOG_TRACE(TRACE_NVRAM, "NVRAM: write data at %d = %d ($%02x)\n", nvram_index, value, value); nvram[nvram_index] = value; }