Change musashi to pre-compile opcode array on host instead of at device start; fix IWM to always report no disk in drive.

This commit is contained in:
Jeroen Domburg 2017-03-23 20:46:17 +08:00
parent 308ad2225f
commit 7cb34b257d
17 changed files with 23125 additions and 15 deletions

View File

@ -103,10 +103,10 @@ void printFps() {
oldtv.tv_usec=tv.tv_usec;
}
typedef void (m68ki_instruction_jump_call)(void);
//typedef void (m68ki_instruction_jump_call)(void);
m68ki_instruction_jump_call **m68ki_instruction_jump_table;
unsigned char **m68ki_cycles;
//m68ki_instruction_jump_call **m68ki_instruction_jump_table;
//unsigned char **m68ki_cycles;
void tmeStartEmu(void *ram, void *rom) {
@ -114,6 +114,7 @@ void tmeStartEmu(void *ram, void *rom) {
int x, frame=0;
macRom=rom;
macRam=ram;
/*
printf("Allocating mem for m68k structs\n");
m68ki_instruction_jump_table=malloc(sizeof(*m68ki_instruction_jump_table)*0x10000);
m68ki_cycles=malloc(sizeof(*m68ki_cycles)*4);
@ -124,6 +125,7 @@ void tmeStartEmu(void *ram, void *rom) {
printf("Malloc of 68k emu structs failed.\n");
abort();
}
*/
printf("Clearing ram...\n");
for (int x=0; x<TME_RAMSIZE; x++) macRam[x]=0;
rom_remap=1;
@ -199,6 +201,7 @@ void viaCbPortAWrite(unsigned int val) {
rom_remap=(val&(1<<4))?1:0;
audio_remap=(val&(1<<3))?1:0;
if (oldRomRemap!=rom_remap) printf("ROM REMAP %d\n", rom_remap);
iwmSetHeadSel(val&(1<<5));
}
void viaCbPortBWrite(unsigned int val) {

View File

@ -13,7 +13,7 @@ At the moment, this only emulates enough of the IWM to make the Plus boot.
#define IWM_Q6 (1<<6)
#define IWM_Q7 (1<<7)
int iwmLines, iwmModeReg;
int iwmLines, iwmModeReg, iwmHeadSel;
void iwmAccess(unsigned int addr) {
if (addr&1) {
@ -30,6 +30,10 @@ void iwmWrite(unsigned int addr, unsigned int val) {
// printf("IWM write %x (iwm reg %x) val %x\n", addr, reg, val);
}
void iwmSetHeadSel(int s) {
iwmHeadSel=s;
}
unsigned int iwmRead(unsigned int addr) {
unsigned int val=0;
iwmAccess(addr);
@ -39,8 +43,12 @@ unsigned int iwmRead(unsigned int addr) {
val=0;
} else if (reg==IWM_Q6) {
//Status register
int iwmSel=iwmLines&(IWM_CA0|IWM_CA1|IWM_CA2);
if (iwmHeadSel) iwmSel|=IWM_SELECT; //Abusing this bit for the separate VIA-controlled SEL line
if (iwmSel==IWM_SELECT) val|=0x80; //No disk in drive.
if (iwmLines&IWM_ENABLE) val|=0x20; //enable
val|=iwmModeReg&0x1F;
// printf("Read disk status %x\n", iwmLines);
} else if (reg==IWM_Q7) {
//Read handshake register
val=0xC0;
@ -49,6 +57,7 @@ unsigned int iwmRead(unsigned int addr) {
if (iwmLines&IWM_ENABLE) val|=0x20; //enable
val|=iwmModeReg&0x1F;
}
// printf("IWM read %x (iwm reg %x) val %x\n", addr, reg, val);
return val;
}

View File

@ -1,2 +1,3 @@
void iwmWrite(unsigned int addr, unsigned int val);
unsigned int iwmRead(unsigned int addr);
void iwmSetHeadSel(int s);

20
components/tme/musashi/.gitignore vendored Normal file
View File

@ -0,0 +1,20 @@
build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
profile
*.moved-aside
DerivedData
.DS_Store
Thumbs.db
.svn
.BridgeSort
*.bak
.~*
*.orig

View File

@ -0,0 +1,115 @@
The history of Musashi for anyone who might be interested:
---------------------------------------------------------
Musashi was born out of sheer boredom.
I needed something to code, and so having had fun with a few of the emulators
around, I decided to try my hand at CPU emulation.
I had owned an Amiga for many years and had done some assembly coding on it so
I figured it would be the ideal chip to cut my teeth on.
Had I known then how much work was involved in emulating a chip like this, I
may not have even started ;-)
15-Jul-2013: Musashi license changed to MIT.
10-Jun-2002: Musashi 3.4 released
- Added various undocumented m68k features thanks to Bart
Trzynadlowski's experiments.
See http://dynarec.com/~bart/files/68knotes.txt for details.
- Fixed a bug that caused privilege violation and illegal
instruction exceptions to stack the wrong PC value.
- Added emulation of address errors (Note: this only works
in 68000 mode. All other CPUs require a LOT of overhead
to emulate this. I'm not sure if I'll implement them or not.
27-Jan-2001: Musashi 3.3 released
- Fixed problem when displaying negative numbers in disassembler
- Fixed cpu type selector - was allowing 020 instructions to be
disassembled when in 000 mode.
- Fixed opcode jumptable generator (ambiguous operators in the
test for f-line ops)
- Fixed signed/unsigned problem in divl and mull opcodes (not
sure if this was causing an error but best to be sure)
- Cleaned up the naming scheme for the opcode handlers
14-Aug-2000: Musashi 3.2 released
- Fixed RTE bug that killed the program counter when in m68020
mode.
- Minor fixes in negx and nbcd.
- renamed d68k.c to m68kdasm.c and merged d68k.h into m68k.h.
d68k_read_xxx() instructions have been renamed to
m68k_read_xxx_disassembler().
- Rewrote exception processing and fixed 68020 stack frame
problems.
- FINALLY fixed the mull and divl instructions.
- Added 64-bit safe code fixes.
- Added 64-bit optimizations (these will only be ANSI compliant
under c9x, and so to use them you must turn on M68K_USE_64_BIT
in m68kconf.h).
28-May-2000: Musashi 3.1 released
- Fixed bug in m68k_get_reg() that retrieved the wrong value for
the status register.
- Fixed register bug in movec.
- Fixed cpu type comparison problem that caused indexed
addressing modes to be incorrectly interpreted when in m68ec020
mode.
- Added code to speed up busy waiting on some branch instructions.
- Fixed some bfxxx opcode bugs.
05-Apr-2000: Musashi 3.0 released
- Major code overhaul.
- Rewrote code generator program and changed the format of
m68k_in.c.
- Added support for m68ec020.
- Removed timing from the opcode handlers.
- Added correct timing for m68000, m68010, and m68020.
Note: 68020 timing is the cache timing from the manual.
- Removed the m68k_peek_xxx() and m68k_poke_xxx() instructions and
replaced them with m68k_get_reg() and m68k_set_reg().
- Added support for function codes.
- Revamped m68kconf.h to be easier to configure and more powerful.
- Added option to separate immediate and normal reads.
- Added support for (undocumented) m68000 instruction prefetch.
- Rewrote indexed addressing mode handling.
- Rewrote interrupt handling.
- Fixed a masking bug for m68k_get_reg() when requesting the PC.
- Moved the instruction table sorting routine to m68kmake.c so
that it is invoked at compile time rather than at runtime.
- Rewrote the exception handling routines to support different
stack frames (needed for m68020 emulation).
- Rewrote faster status register and condition code flag handling
functions / macros.
- Fixed function code handling to fetch from program space when
using pc-relative addressing.
- Fixed initial program counter and stack pointer fetching on
reset (loads from program space now).
- A lot of code cleanup.
- LOTS of bugfixes (especially in the m68020 code).
13-May-1999: Musashi 2.2 released
- Added support for m68020.
- Lots of bugfixes.
25-Mar-1999: Musashi 2.1 released
- Added support for m68010.
- Many bugfixes.
17-Mar-1999: Musashi 2.0 released
- Major code overhaul.
- Replaced monolithic codebase with a code generator program.
- Added correct m68000 timing.
- Moved timing into the opcode handlers.
06-Jan-1999: Musashi 1.0 released
20-Dec-1998: Beta release of Musashi v0.5 that could run Rastan Saga under MAME
(barely).
04-Dec-1998: Final prototype v0.4
20-Nov-1998: First prototype v0.1
11-Jun-1998: Early disassembler
12-May-1998: First outline

358
components/tme/musashi/m68k.h Executable file
View File

@ -0,0 +1,358 @@
/* ======================================================================== */
/* ========================= LICENSING & COPYRIGHT ======================== */
/* ======================================================================== */
/*
* MUSASHI
* Version 3.4
*
* A portable Motorola M680x0 processor emulation engine.
* Copyright 1998-2001 Karl Stenerud. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef M68K__HEADER
#define M68K__HEADER
/* ======================================================================== */
/* ============================= CONFIGURATION ============================ */
/* ======================================================================== */
/* Import the configuration for this build */
#include "m68kconf.h"
/* ======================================================================== */
/* ============================ GENERAL DEFINES =========================== */
/* ======================================================================== */
/* There are 7 levels of interrupt to the 68K.
* A transition from < 7 to 7 will cause a non-maskable interrupt (NMI).
*/
#define M68K_IRQ_NONE 0
#define M68K_IRQ_1 1
#define M68K_IRQ_2 2
#define M68K_IRQ_3 3
#define M68K_IRQ_4 4
#define M68K_IRQ_5 5
#define M68K_IRQ_6 6
#define M68K_IRQ_7 7
/* Special interrupt acknowledge values.
* Use these as special returns from the interrupt acknowledge callback
* (specified later in this header).
*/
/* Causes an interrupt autovector (0x18 + interrupt level) to be taken.
* This happens in a real 68K if VPA or AVEC is asserted during an interrupt
* acknowledge cycle instead of DTACK.
*/
#define M68K_INT_ACK_AUTOVECTOR 0xffffffff
/* Causes the spurious interrupt vector (0x18) to be taken
* This happens in a real 68K if BERR is asserted during the interrupt
* acknowledge cycle (i.e. no devices responded to the acknowledge).
*/
#define M68K_INT_ACK_SPURIOUS 0xfffffffe
/* CPU types for use in m68k_set_cpu_type() */
enum
{
M68K_CPU_TYPE_INVALID,
M68K_CPU_TYPE_68000,
M68K_CPU_TYPE_68010,
M68K_CPU_TYPE_68EC020,
M68K_CPU_TYPE_68020,
M68K_CPU_TYPE_68030, /* Supported by disassembler ONLY */
M68K_CPU_TYPE_68040 /* Supported by disassembler ONLY */
};
/* Registers used by m68k_get_reg() and m68k_set_reg() */
typedef enum
{
/* Real registers */
M68K_REG_D0, /* Data registers */
M68K_REG_D1,
M68K_REG_D2,
M68K_REG_D3,
M68K_REG_D4,
M68K_REG_D5,
M68K_REG_D6,
M68K_REG_D7,
M68K_REG_A0, /* Address registers */
M68K_REG_A1,
M68K_REG_A2,
M68K_REG_A3,
M68K_REG_A4,
M68K_REG_A5,
M68K_REG_A6,
M68K_REG_A7,
M68K_REG_PC, /* Program Counter */
M68K_REG_SR, /* Status Register */
M68K_REG_SP, /* The current Stack Pointer (located in A7) */
M68K_REG_USP, /* User Stack Pointer */
M68K_REG_ISP, /* Interrupt Stack Pointer */
M68K_REG_MSP, /* Master Stack Pointer */
M68K_REG_SFC, /* Source Function Code */
M68K_REG_DFC, /* Destination Function Code */
M68K_REG_VBR, /* Vector Base Register */
M68K_REG_CACR, /* Cache Control Register */
M68K_REG_CAAR, /* Cache Address Register */
/* Assumed registers */
/* These are cheat registers which emulate the 1-longword prefetch
* present in the 68000 and 68010.
*/
M68K_REG_PREF_ADDR, /* Last prefetch address */
M68K_REG_PREF_DATA, /* Last prefetch data */
/* Convenience registers */
M68K_REG_PPC, /* Previous value in the program counter */
M68K_REG_IR, /* Instruction register */
M68K_REG_CPU_TYPE /* Type of CPU being run */
} m68k_register_t;
/* ======================================================================== */
/* ====================== FUNCTIONS CALLED BY THE CPU ===================== */
/* ======================================================================== */
/* You will have to implement these functions */
/* read/write functions called by the CPU to access memory.
* while values used are 32 bits, only the appropriate number
* of bits are relevant (i.e. in write_memory_8, only the lower 8 bits
* of value should be written to memory).
*
* NOTE: I have separated the immediate and PC-relative memory fetches
* from the other memory fetches because some systems require
* differentiation between PROGRAM and DATA fetches (usually
* for security setups such as encryption).
* This separation can either be achieved by setting
* M68K_SEPARATE_READS in m68kconf.h and defining
* the read functions, or by setting M68K_EMULATE_FC and
* making a function code callback function.
* Using the callback offers better emulation coverage
* because you can also monitor whether the CPU is in SYSTEM or
* USER mode, but it is also slower.
*/
/* Read from anywhere */
unsigned int m68k_read_memory_8(unsigned int address);
unsigned int m68k_read_memory_16(unsigned int address);
unsigned int m68k_read_memory_32(unsigned int address);
/* Read data immediately following the PC */
unsigned int m68k_read_immediate_16(unsigned int address);
unsigned int m68k_read_immediate_32(unsigned int address);
/* Read data relative to the PC */
unsigned int m68k_read_pcrelative_8(unsigned int address);
unsigned int m68k_read_pcrelative_16(unsigned int address);
unsigned int m68k_read_pcrelative_32(unsigned int address);
/* Memory access for the disassembler */
unsigned int m68k_read_disassembler_8 (unsigned int address);
unsigned int m68k_read_disassembler_16 (unsigned int address);
unsigned int m68k_read_disassembler_32 (unsigned int address);
/* Write to anywhere */
void m68k_write_memory_8(unsigned int address, unsigned int value);
void m68k_write_memory_16(unsigned int address, unsigned int value);
void m68k_write_memory_32(unsigned int address, unsigned int value);
/* Special call to simulate undocumented 68k behavior when move.l with a
* predecrement destination mode is executed.
* To simulate real 68k behavior, first write the high word to
* [address+2], and then write the low word to [address].
*
* Enable this functionality with M68K_SIMULATE_PD_WRITES in m68kconf.h.
*/
void m68k_write_memory_32_pd(unsigned int address, unsigned int value);
/* ======================================================================== */
/* ============================== CALLBACKS =============================== */
/* ======================================================================== */
/* These functions allow you to set callbacks to the host when specific events
* occur. Note that you must enable the corresponding value in m68kconf.h
* in order for these to do anything useful.
* Note: I have defined default callbacks which are used if you have enabled
* the corresponding #define in m68kconf.h but either haven't assigned a
* callback or have assigned a callback of NULL.
*/
/* Set the callback for an interrupt acknowledge.
* You must enable M68K_EMULATE_INT_ACK in m68kconf.h.
* The CPU will call the callback with the interrupt level being acknowledged.
* The host program must return either a vector from 0x02-0xff, or one of the
* special interrupt acknowledge values specified earlier in this header.
* If this is not implemented, the CPU will always assume an autovectored
* interrupt, and will automatically clear the interrupt request when it
* services the interrupt.
* Default behavior: return M68K_INT_ACK_AUTOVECTOR.
*/
void m68k_set_int_ack_callback(int (*callback)(int int_level));
/* Set the callback for a breakpoint acknowledge (68010+).
* You must enable M68K_EMULATE_BKPT_ACK in m68kconf.h.
* The CPU will call the callback with whatever was in the data field of the
* BKPT instruction for 68020+, or 0 for 68010.
* Default behavior: do nothing.
*/
void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data));
/* Set the callback for the RESET instruction.
* You must enable M68K_EMULATE_RESET in m68kconf.h.
* The CPU calls this callback every time it encounters a RESET instruction.
* Default behavior: do nothing.
*/
void m68k_set_reset_instr_callback(void (*callback)(void));
/* Set the callback for informing of a large PC change.
* You must enable M68K_MONITOR_PC in m68kconf.h.
* The CPU calls this callback with the new PC value every time the PC changes
* by a large value (currently set for changes by longwords).
* Default behavior: do nothing.
*/
void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc));
/* Set the callback for CPU function code changes.
* You must enable M68K_EMULATE_FC in m68kconf.h.
* The CPU calls this callback with the function code before every memory
* access to set the CPU's function code according to what kind of memory
* access it is (supervisor/user, program/data and such).
* Default behavior: do nothing.
*/
void m68k_set_fc_callback(void (*callback)(unsigned int new_fc));
/* Set a callback for the instruction cycle of the CPU.
* You must enable M68K_INSTRUCTION_HOOK in m68kconf.h.
* The CPU calls this callback just before fetching the opcode in the
* instruction cycle.
* Default behavior: do nothing.
*/
void m68k_set_instr_hook_callback(void (*callback)(void));
/* ======================================================================== */
/* ====================== FUNCTIONS TO ACCESS THE CPU ===================== */
/* ======================================================================== */
/* Use this function to set the CPU type you want to emulate.
* Currently supported types are: M68K_CPU_TYPE_68000, M68K_CPU_TYPE_68010,
* M68K_CPU_TYPE_EC020, and M68K_CPU_TYPE_68020.
*/
void m68k_set_cpu_type(unsigned int cpu_type);
/* Do whatever initialisations the core requires. Should be called
* at least once at init time.
*/
void m68k_init(void);
/* Pulse the RESET pin on the CPU.
* You *MUST* reset the CPU at least once to initialize the emulation
* Note: If you didn't call m68k_set_cpu_type() before resetting
* the CPU for the first time, the CPU will be set to
* M68K_CPU_TYPE_68000.
*/
void m68k_pulse_reset(void);
/* execute num_cycles worth of instructions. returns number of cycles used */
int m68k_execute(int num_cycles);
/* These functions let you read/write/modify the number of cycles left to run
* while m68k_execute() is running.
* These are useful if the 68k accesses a memory-mapped port on another device
* that requires immediate processing by another CPU.
*/
int m68k_cycles_run(void); /* Number of cycles run so far */
int m68k_cycles_remaining(void); /* Number of cycles left */
void m68k_modify_timeslice(int cycles); /* Modify cycles left */
void m68k_end_timeslice(void); /* End timeslice now */
/* Set the IPL0-IPL2 pins on the CPU (IRQ).
* A transition from < 7 to 7 will cause a non-maskable interrupt (NMI).
* Setting IRQ to 0 will clear an interrupt request.
*/
void m68k_set_irq(unsigned int int_level);
/* Halt the CPU as if you pulsed the HALT pin. */
void m68k_pulse_halt(void);
/* Context switching to allow multiple CPUs */
/* Get the size of the cpu context in bytes */
unsigned int m68k_context_size(void);
/* Get a cpu context */
unsigned int m68k_get_context(void* dst);
/* set the current cpu context */
void m68k_set_context(void* dst);
/* Register the CPU state information */
void m68k_state_register(const char *type);
/* Peek at the internals of a CPU context. This can either be a context
* retrieved using m68k_get_context() or the currently running context.
* If context is NULL, the currently running CPU context will be used.
*/
unsigned int m68k_get_reg(void* context, m68k_register_t reg);
/* Poke values into the internals of the currently running CPU context */
void m68k_set_reg(m68k_register_t reg, unsigned int value);
/* Check if an instruction is valid for the specified CPU type */
unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type);
/* Disassemble 1 instruction using the epecified CPU type at pc. Stores
* disassembly in str_buff and returns the size of the instruction in bytes.
*/
unsigned int m68k_disassemble(char* str_buff, unsigned int pc, unsigned int cpu_type);
/* ======================================================================== */
/* ============================== MAME STUFF ============================== */
/* ======================================================================== */
#if M68K_COMPILE_FOR_MAME == OPT_ON
#include "m68kmame.h"
#endif /* M68K_COMPILE_FOR_MAME */
/* ======================================================================== */
/* ============================== END OF FILE ============================= */
/* ======================================================================== */
#endif /* M68K__HEADER */

10409
components/tme/musashi/m68k_in.c Executable file

File diff suppressed because it is too large Load Diff

882
components/tme/musashi/m68kcpu.c Executable file
View File

@ -0,0 +1,882 @@
/* ======================================================================== */
/* ========================= LICENSING & COPYRIGHT ======================== */
/* ======================================================================== */
/*
* MUSASHI
* Version 3.4
*
* A portable Motorola M680x0 processor emulation engine.
* Copyright 1998-2001 Karl Stenerud. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* ======================================================================== */
/* ================================= NOTES ================================ */
/* ======================================================================== */
/* ======================================================================== */
/* ================================ INCLUDES ============================== */
/* ======================================================================== */
#include "m68kops.h"
#include "m68kcpu.h"
/* ======================================================================== */
/* ================================= DATA ================================= */
/* ======================================================================== */
int m68ki_initial_cycles;
int m68ki_remaining_cycles = 0; /* Number of clocks remaining */
uint m68ki_tracing = 0;
uint m68ki_address_space;
#ifdef M68K_LOG_ENABLE
char* m68ki_cpu_names[9] =
{
"Invalid CPU",
"M68000",
"M68010",
"Invalid CPU",
"M68EC020"
"Invalid CPU",
"Invalid CPU",
"Invalid CPU",
"M68020"
};
#endif /* M68K_LOG_ENABLE */
/* The CPU core */
m68ki_cpu_core m68ki_cpu = {0};
#if M68K_EMULATE_ADDRESS_ERROR
jmp_buf m68ki_aerr_trap;
#endif /* M68K_EMULATE_ADDRESS_ERROR */
uint m68ki_aerr_address;
uint m68ki_aerr_write_mode;
uint m68ki_aerr_fc;
/* Used by shift & rotate instructions */
const uint8 m68ki_shift_8_table[65] =
{
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff
};
const uint16 m68ki_shift_16_table[65] =
{
0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00,
0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff
};
const uint m68ki_shift_32_table[65] =
{
0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,
0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,
0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
};
/* Number of clock cycles to use for exception processing.
* I used 4 for any vectors that are undocumented for processing times.
*/
uint8 m68ki_exception_cycle_table[3][256] =
{
{ /* 000 */
4, /* 0: Reset - Initial Stack Pointer */
4, /* 1: Reset - Initial Program Counter */
50, /* 2: Bus Error (unemulated) */
50, /* 3: Address Error (unemulated) */
34, /* 4: Illegal Instruction */
38, /* 5: Divide by Zero -- ASG: changed from 42 */
40, /* 6: CHK -- ASG: chanaged from 44 */
34, /* 7: TRAPV */
34, /* 8: Privilege Violation */
34, /* 9: Trace */
34, /* 10: 1010 */
34, /* 11: 1111 */
4, /* 12: RESERVED */
4, /* 13: Coprocessor Protocol Violation (unemulated) */
4, /* 14: Format Error */
44, /* 15: Uninitialized Interrupt */
4, /* 16: RESERVED */
4, /* 17: RESERVED */
4, /* 18: RESERVED */
4, /* 19: RESERVED */
4, /* 20: RESERVED */
4, /* 21: RESERVED */
4, /* 22: RESERVED */
4, /* 23: RESERVED */
44, /* 24: Spurious Interrupt */
44, /* 25: Level 1 Interrupt Autovector */
44, /* 26: Level 2 Interrupt Autovector */
44, /* 27: Level 3 Interrupt Autovector */
44, /* 28: Level 4 Interrupt Autovector */
44, /* 29: Level 5 Interrupt Autovector */
44, /* 30: Level 6 Interrupt Autovector */
44, /* 31: Level 7 Interrupt Autovector */
34, /* 32: TRAP #0 -- ASG: chanaged from 38 */
34, /* 33: TRAP #1 */
34, /* 34: TRAP #2 */
34, /* 35: TRAP #3 */
34, /* 36: TRAP #4 */
34, /* 37: TRAP #5 */
34, /* 38: TRAP #6 */
34, /* 39: TRAP #7 */
34, /* 40: TRAP #8 */
34, /* 41: TRAP #9 */
34, /* 42: TRAP #10 */
34, /* 43: TRAP #11 */
34, /* 44: TRAP #12 */
34, /* 45: TRAP #13 */
34, /* 46: TRAP #14 */
34, /* 47: TRAP #15 */
4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
4, /* 49: FP Inexact Result (unemulated) */
4, /* 50: FP Divide by Zero (unemulated) */
4, /* 51: FP Underflow (unemulated) */
4, /* 52: FP Operand Error (unemulated) */
4, /* 53: FP Overflow (unemulated) */
4, /* 54: FP Signaling NAN (unemulated) */
4, /* 55: FP Unimplemented Data Type (unemulated) */
4, /* 56: MMU Configuration Error (unemulated) */
4, /* 57: MMU Illegal Operation Error (unemulated) */
4, /* 58: MMU Access Level Violation Error (unemulated) */
4, /* 59: RESERVED */
4, /* 60: RESERVED */
4, /* 61: RESERVED */
4, /* 62: RESERVED */
4, /* 63: RESERVED */
/* 64-255: User Defined */
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
},
{ /* 010 */
4, /* 0: Reset - Initial Stack Pointer */
4, /* 1: Reset - Initial Program Counter */
126, /* 2: Bus Error (unemulated) */
126, /* 3: Address Error (unemulated) */
38, /* 4: Illegal Instruction */
44, /* 5: Divide by Zero */
44, /* 6: CHK */
34, /* 7: TRAPV */
38, /* 8: Privilege Violation */
38, /* 9: Trace */
4, /* 10: 1010 */
4, /* 11: 1111 */
4, /* 12: RESERVED */
4, /* 13: Coprocessor Protocol Violation (unemulated) */
4, /* 14: Format Error */
44, /* 15: Uninitialized Interrupt */
4, /* 16: RESERVED */
4, /* 17: RESERVED */
4, /* 18: RESERVED */
4, /* 19: RESERVED */
4, /* 20: RESERVED */
4, /* 21: RESERVED */
4, /* 22: RESERVED */
4, /* 23: RESERVED */
46, /* 24: Spurious Interrupt */
46, /* 25: Level 1 Interrupt Autovector */
46, /* 26: Level 2 Interrupt Autovector */
46, /* 27: Level 3 Interrupt Autovector */
46, /* 28: Level 4 Interrupt Autovector */
46, /* 29: Level 5 Interrupt Autovector */
46, /* 30: Level 6 Interrupt Autovector */
46, /* 31: Level 7 Interrupt Autovector */
38, /* 32: TRAP #0 */
38, /* 33: TRAP #1 */
38, /* 34: TRAP #2 */
38, /* 35: TRAP #3 */
38, /* 36: TRAP #4 */
38, /* 37: TRAP #5 */
38, /* 38: TRAP #6 */
38, /* 39: TRAP #7 */
38, /* 40: TRAP #8 */
38, /* 41: TRAP #9 */
38, /* 42: TRAP #10 */
38, /* 43: TRAP #11 */
38, /* 44: TRAP #12 */
38, /* 45: TRAP #13 */
38, /* 46: TRAP #14 */
38, /* 47: TRAP #15 */
4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
4, /* 49: FP Inexact Result (unemulated) */
4, /* 50: FP Divide by Zero (unemulated) */
4, /* 51: FP Underflow (unemulated) */
4, /* 52: FP Operand Error (unemulated) */
4, /* 53: FP Overflow (unemulated) */
4, /* 54: FP Signaling NAN (unemulated) */
4, /* 55: FP Unimplemented Data Type (unemulated) */
4, /* 56: MMU Configuration Error (unemulated) */
4, /* 57: MMU Illegal Operation Error (unemulated) */
4, /* 58: MMU Access Level Violation Error (unemulated) */
4, /* 59: RESERVED */
4, /* 60: RESERVED */
4, /* 61: RESERVED */
4, /* 62: RESERVED */
4, /* 63: RESERVED */
/* 64-255: User Defined */
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
},
{ /* 020 */
4, /* 0: Reset - Initial Stack Pointer */
4, /* 1: Reset - Initial Program Counter */
50, /* 2: Bus Error (unemulated) */
50, /* 3: Address Error (unemulated) */
20, /* 4: Illegal Instruction */
38, /* 5: Divide by Zero */
40, /* 6: CHK */
20, /* 7: TRAPV */
34, /* 8: Privilege Violation */
25, /* 9: Trace */
20, /* 10: 1010 */
20, /* 11: 1111 */
4, /* 12: RESERVED */
4, /* 13: Coprocessor Protocol Violation (unemulated) */
4, /* 14: Format Error */
30, /* 15: Uninitialized Interrupt */
4, /* 16: RESERVED */
4, /* 17: RESERVED */
4, /* 18: RESERVED */
4, /* 19: RESERVED */
4, /* 20: RESERVED */
4, /* 21: RESERVED */
4, /* 22: RESERVED */
4, /* 23: RESERVED */
30, /* 24: Spurious Interrupt */
30, /* 25: Level 1 Interrupt Autovector */
30, /* 26: Level 2 Interrupt Autovector */
30, /* 27: Level 3 Interrupt Autovector */
30, /* 28: Level 4 Interrupt Autovector */
30, /* 29: Level 5 Interrupt Autovector */
30, /* 30: Level 6 Interrupt Autovector */
30, /* 31: Level 7 Interrupt Autovector */
20, /* 32: TRAP #0 */
20, /* 33: TRAP #1 */
20, /* 34: TRAP #2 */
20, /* 35: TRAP #3 */
20, /* 36: TRAP #4 */
20, /* 37: TRAP #5 */
20, /* 38: TRAP #6 */
20, /* 39: TRAP #7 */
20, /* 40: TRAP #8 */
20, /* 41: TRAP #9 */
20, /* 42: TRAP #10 */
20, /* 43: TRAP #11 */
20, /* 44: TRAP #12 */
20, /* 45: TRAP #13 */
20, /* 46: TRAP #14 */
20, /* 47: TRAP #15 */
4, /* 48: FP Branch or Set on Unknown Condition (unemulated) */
4, /* 49: FP Inexact Result (unemulated) */
4, /* 50: FP Divide by Zero (unemulated) */
4, /* 51: FP Underflow (unemulated) */
4, /* 52: FP Operand Error (unemulated) */
4, /* 53: FP Overflow (unemulated) */
4, /* 54: FP Signaling NAN (unemulated) */
4, /* 55: FP Unimplemented Data Type (unemulated) */
4, /* 56: MMU Configuration Error (unemulated) */
4, /* 57: MMU Illegal Operation Error (unemulated) */
4, /* 58: MMU Access Level Violation Error (unemulated) */
4, /* 59: RESERVED */
4, /* 60: RESERVED */
4, /* 61: RESERVED */
4, /* 62: RESERVED */
4, /* 63: RESERVED */
/* 64-255: User Defined */
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
}
};
uint8 m68ki_ea_idx_cycle_table[64] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, /* ..01.000 no memory indirect, base NULL */
5, /* ..01..01 memory indirect, base NULL, outer NULL */
7, /* ..01..10 memory indirect, base NULL, outer 16 */
7, /* ..01..11 memory indirect, base NULL, outer 32 */
0, 5, 7, 7, 0, 5, 7, 7, 0, 5, 7, 7,
2, /* ..10.000 no memory indirect, base 16 */
7, /* ..10..01 memory indirect, base 16, outer NULL */
9, /* ..10..10 memory indirect, base 16, outer 16 */
9, /* ..10..11 memory indirect, base 16, outer 32 */
0, 7, 9, 9, 0, 7, 9, 9, 0, 7, 9, 9,
6, /* ..11.000 no memory indirect, base 32 */
11, /* ..11..01 memory indirect, base 32, outer NULL */
13, /* ..11..10 memory indirect, base 32, outer 16 */
13, /* ..11..11 memory indirect, base 32, outer 32 */
0, 11, 13, 13, 0, 11, 13, 13, 0, 11, 13, 13
};
/* ======================================================================== */
/* =============================== CALLBACKS ============================== */
/* ======================================================================== */
/* Default callbacks used if the callback hasn't been set yet, or if the
* callback is set to NULL
*/
/* Interrupt acknowledge */
static int default_int_ack_callback_data;
static int default_int_ack_callback(int int_level)
{
default_int_ack_callback_data = int_level;
CPU_INT_LEVEL = 0;
return M68K_INT_ACK_AUTOVECTOR;
}
/* Breakpoint acknowledge */
static unsigned int default_bkpt_ack_callback_data;
static void default_bkpt_ack_callback(unsigned int data)
{
default_bkpt_ack_callback_data = data;
}
/* Called when a reset instruction is executed */
static void default_reset_instr_callback(void)
{
}
/* Called when the program counter changed by a large value */
static unsigned int default_pc_changed_callback_data;
static void default_pc_changed_callback(unsigned int new_pc)
{
default_pc_changed_callback_data = new_pc;
}
/* Called every time there's bus activity (read/write to/from memory */
static unsigned int default_set_fc_callback_data;
static void default_set_fc_callback(unsigned int new_fc)
{
default_set_fc_callback_data = new_fc;
}
/* Called every instruction cycle prior to execution */
static void default_instr_hook_callback(void)
{
}
#if M68K_EMULATE_ADDRESS_ERROR
#include <setjmp.h>
jmp_buf m68ki_aerr_trap;
#endif /* M68K_EMULATE_ADDRESS_ERROR */
/* ======================================================================== */
/* ================================= API ================================== */
/* ======================================================================== */
/* Access the internals of the CPU */
unsigned int m68k_get_reg(void* context, m68k_register_t regnum)
{
m68ki_cpu_core* cpu = context != NULL ?(m68ki_cpu_core*)context : &m68ki_cpu;
switch(regnum)
{
case M68K_REG_D0: return cpu->dar[0];
case M68K_REG_D1: return cpu->dar[1];
case M68K_REG_D2: return cpu->dar[2];
case M68K_REG_D3: return cpu->dar[3];
case M68K_REG_D4: return cpu->dar[4];
case M68K_REG_D5: return cpu->dar[5];
case M68K_REG_D6: return cpu->dar[6];
case M68K_REG_D7: return cpu->dar[7];
case M68K_REG_A0: return cpu->dar[8];
case M68K_REG_A1: return cpu->dar[9];
case M68K_REG_A2: return cpu->dar[10];
case M68K_REG_A3: return cpu->dar[11];
case M68K_REG_A4: return cpu->dar[12];
case M68K_REG_A5: return cpu->dar[13];
case M68K_REG_A6: return cpu->dar[14];
case M68K_REG_A7: return cpu->dar[15];
case M68K_REG_PC: return MASK_OUT_ABOVE_32(cpu->pc);
case M68K_REG_SR: return cpu->t1_flag |
cpu->t0_flag |
(cpu->s_flag << 11) |
(cpu->m_flag << 11) |
cpu->int_mask |
((cpu->x_flag & XFLAG_SET) >> 4) |
((cpu->n_flag & NFLAG_SET) >> 4) |
((!cpu->not_z_flag) << 2) |
((cpu->v_flag & VFLAG_SET) >> 6) |
((cpu->c_flag & CFLAG_SET) >> 8);
case M68K_REG_SP: return cpu->dar[15];
case M68K_REG_USP: return cpu->s_flag ? cpu->sp[0] : cpu->dar[15];
case M68K_REG_ISP: return cpu->s_flag && !cpu->m_flag ? cpu->dar[15] : cpu->sp[4];
case M68K_REG_MSP: return cpu->s_flag && cpu->m_flag ? cpu->dar[15] : cpu->sp[6];
case M68K_REG_SFC: return cpu->sfc;
case M68K_REG_DFC: return cpu->dfc;
case M68K_REG_VBR: return cpu->vbr;
case M68K_REG_CACR: return cpu->cacr;
case M68K_REG_CAAR: return cpu->caar;
case M68K_REG_PREF_ADDR: return cpu->pref_addr;
case M68K_REG_PREF_DATA: return cpu->pref_data;
case M68K_REG_PPC: return MASK_OUT_ABOVE_32(cpu->ppc);
case M68K_REG_IR: return cpu->ir;
case M68K_REG_CPU_TYPE:
switch(cpu->cpu_type)
{
case CPU_TYPE_000: return (unsigned int)M68K_CPU_TYPE_68000;
case CPU_TYPE_010: return (unsigned int)M68K_CPU_TYPE_68010;
case CPU_TYPE_EC020: return (unsigned int)M68K_CPU_TYPE_68EC020;
case CPU_TYPE_020: return (unsigned int)M68K_CPU_TYPE_68020;
}
return M68K_CPU_TYPE_INVALID;
default: return 0;
}
return 0;
}
void m68k_set_reg(m68k_register_t regnum, unsigned int value)
{
switch(regnum)
{
case M68K_REG_D0: REG_D[0] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_D1: REG_D[1] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_D2: REG_D[2] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_D3: REG_D[3] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_D4: REG_D[4] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_D5: REG_D[5] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_D6: REG_D[6] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_D7: REG_D[7] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_A0: REG_A[0] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_A1: REG_A[1] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_A2: REG_A[2] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_A3: REG_A[3] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_A4: REG_A[4] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_A5: REG_A[5] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_A6: REG_A[6] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_A7: REG_A[7] = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_PC: m68ki_jump(MASK_OUT_ABOVE_32(value)); return;
case M68K_REG_SR: m68ki_set_sr(value); return;
case M68K_REG_SP: REG_SP = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_USP: if(FLAG_S)
REG_USP = MASK_OUT_ABOVE_32(value);
else
REG_SP = MASK_OUT_ABOVE_32(value);
return;
case M68K_REG_ISP: if(FLAG_S && !FLAG_M)
REG_SP = MASK_OUT_ABOVE_32(value);
else
REG_ISP = MASK_OUT_ABOVE_32(value);
return;
case M68K_REG_MSP: if(FLAG_S && FLAG_M)
REG_SP = MASK_OUT_ABOVE_32(value);
else
REG_MSP = MASK_OUT_ABOVE_32(value);
return;
case M68K_REG_VBR: REG_VBR = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_SFC: REG_SFC = value & 7; return;
case M68K_REG_DFC: REG_DFC = value & 7; return;
case M68K_REG_CACR: REG_CACR = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_CAAR: REG_CAAR = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_PPC: REG_PPC = MASK_OUT_ABOVE_32(value); return;
case M68K_REG_IR: REG_IR = MASK_OUT_ABOVE_16(value); return;
case M68K_REG_CPU_TYPE: m68k_set_cpu_type(value); return;
default: return;
}
}
/* Set the callbacks */
void m68k_set_int_ack_callback(int (*callback)(int int_level))
{
CALLBACK_INT_ACK = callback ? callback : default_int_ack_callback;
}
void m68k_set_bkpt_ack_callback(void (*callback)(unsigned int data))
{
CALLBACK_BKPT_ACK = callback ? callback : default_bkpt_ack_callback;
}
void m68k_set_reset_instr_callback(void (*callback)(void))
{
CALLBACK_RESET_INSTR = callback ? callback : default_reset_instr_callback;
}
void m68k_set_pc_changed_callback(void (*callback)(unsigned int new_pc))
{
CALLBACK_PC_CHANGED = callback ? callback : default_pc_changed_callback;
}
void m68k_set_fc_callback(void (*callback)(unsigned int new_fc))
{
CALLBACK_SET_FC = callback ? callback : default_set_fc_callback;
}
void m68k_set_instr_hook_callback(void (*callback)(void))
{
CALLBACK_INSTR_HOOK = callback ? callback : default_instr_hook_callback;
}
#include <stdio.h>
/* Set the CPU type. */
void m68k_set_cpu_type(unsigned int cpu_type)
{
switch(cpu_type)
{
case M68K_CPU_TYPE_68000:
CPU_TYPE = CPU_TYPE_000;
CPU_ADDRESS_MASK = 0x00ffffff;
CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
CYC_INSTRUCTION = m68ki_cycles[0];
CYC_EXCEPTION = m68ki_exception_cycle_table[0];
CYC_BCC_NOTAKE_B = -2;
CYC_BCC_NOTAKE_W = 2;
CYC_DBCC_F_NOEXP = -2;
CYC_DBCC_F_EXP = 2;
CYC_SCC_R_TRUE = 2;
CYC_MOVEM_W = 2;
CYC_MOVEM_L = 3;
CYC_SHIFT = 1;
CYC_RESET = 132;
return;
case M68K_CPU_TYPE_68010:
CPU_TYPE = CPU_TYPE_010;
CPU_ADDRESS_MASK = 0x00ffffff;
CPU_SR_MASK = 0xa71f; /* T1 -- S -- -- I2 I1 I0 -- -- -- X N Z V C */
CYC_INSTRUCTION = m68ki_cycles[1];
CYC_EXCEPTION = m68ki_exception_cycle_table[1];
CYC_BCC_NOTAKE_B = -4;
CYC_BCC_NOTAKE_W = 0;
CYC_DBCC_F_NOEXP = 0;
CYC_DBCC_F_EXP = 6;
CYC_SCC_R_TRUE = 0;
CYC_MOVEM_W = 2;
CYC_MOVEM_L = 3;
CYC_SHIFT = 1;
CYC_RESET = 130;
return;
case M68K_CPU_TYPE_68EC020:
CPU_TYPE = CPU_TYPE_EC020;
CPU_ADDRESS_MASK = 0x00ffffff;
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
CYC_INSTRUCTION = m68ki_cycles[2];
CYC_EXCEPTION = m68ki_exception_cycle_table[2];
CYC_BCC_NOTAKE_B = -2;
CYC_BCC_NOTAKE_W = 0;
CYC_DBCC_F_NOEXP = 0;
CYC_DBCC_F_EXP = 4;
CYC_SCC_R_TRUE = 0;
CYC_MOVEM_W = 2;
CYC_MOVEM_L = 2;
CYC_SHIFT = 0;
CYC_RESET = 518;
return;
case M68K_CPU_TYPE_68020:
CPU_TYPE = CPU_TYPE_020;
CPU_ADDRESS_MASK = 0xffffffff;
CPU_SR_MASK = 0xf71f; /* T1 T0 S M -- I2 I1 I0 -- -- -- X N Z V C */
CYC_INSTRUCTION = m68ki_cycles[2];
CYC_EXCEPTION = m68ki_exception_cycle_table[2];
CYC_BCC_NOTAKE_B = -2;
CYC_BCC_NOTAKE_W = 0;
CYC_DBCC_F_NOEXP = 0;
CYC_DBCC_F_EXP = 4;
CYC_SCC_R_TRUE = 0;
CYC_MOVEM_W = 2;
CYC_MOVEM_L = 2;
CYC_SHIFT = 0;
CYC_RESET = 518;
return;
}
}
/* Execute some instructions until we use up num_cycles clock cycles */
/* ASG: removed per-instruction interrupt checks */
int m68k_execute(int num_cycles)
{
/* Make sure we're not stopped */
if(!CPU_STOPPED)
{
/* Set our pool of clock cycles available */
SET_CYCLES(num_cycles);
m68ki_initial_cycles = num_cycles;
/* ASG: update cycles */
USE_CYCLES(CPU_INT_CYCLES);
CPU_INT_CYCLES = 0;
/* Return point if we had an address error */
m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
/* Main loop. Keep going until we run out of clock cycles */
do
{
/* Set tracing accodring to T1. (T0 is done inside instruction) */
m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
/* Set the address space for reads */
m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */
/* Call external hook to peek at CPU */
m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */
/* Record previous program counter */
REG_PPC = REG_PC;
/* Read an instruction and call its handler */
REG_IR = m68ki_read_imm_16();
m68ki_instruction_jump_table[REG_IR]();
USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
/* Trace m68k_exception, if necessary */
m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
} while(GET_CYCLES() > 0);
/* set previous PC to current PC for the next entry into the loop */
REG_PPC = REG_PC;
/* ASG: update cycles */
USE_CYCLES(CPU_INT_CYCLES);
CPU_INT_CYCLES = 0;
/* return how many clocks we used */
return m68ki_initial_cycles - GET_CYCLES();
}
/* We get here if the CPU is stopped or halted */
SET_CYCLES(0);
CPU_INT_CYCLES = 0;
return num_cycles;
}
int m68k_cycles_run(void)
{
return m68ki_initial_cycles - GET_CYCLES();
}
int m68k_cycles_remaining(void)
{
return GET_CYCLES();
}
/* Change the timeslice */
void m68k_modify_timeslice(int cycles)
{
m68ki_initial_cycles += cycles;
ADD_CYCLES(cycles);
}
void m68k_end_timeslice(void)
{
m68ki_initial_cycles = GET_CYCLES();
SET_CYCLES(0);
}
/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
/* KS: Modified so that IPL* bits match with mask positions in the SR
* and cleaned out remenants of the interrupt controller.
*/
void m68k_set_irq(unsigned int int_level)
{
uint old_level = CPU_INT_LEVEL;
CPU_INT_LEVEL = int_level << 8;
/* A transition from < 7 to 7 always interrupts (NMI) */
/* Note: Level 7 can also level trigger like a normal IRQ */
if(old_level != 0x0700 && CPU_INT_LEVEL == 0x0700)
m68ki_exception_interrupt(7); /* Edge triggered level 7 (NMI) */
else
m68ki_check_interrupts(); /* Level triggered (IRQ) */
}
void m68k_init(void)
{
static uint emulation_initialized = 0;
/* The first call to this function initializes the opcode handler jump table */
if(!emulation_initialized)
{
m68ki_build_opcode_table();
emulation_initialized = 1;
}
m68k_set_int_ack_callback(NULL);
m68k_set_bkpt_ack_callback(NULL);
m68k_set_reset_instr_callback(NULL);
m68k_set_pc_changed_callback(NULL);
m68k_set_fc_callback(NULL);
m68k_set_instr_hook_callback(NULL);
}
/* Pulse the RESET line on the CPU */
void m68k_pulse_reset(void)
{
/* Clear all stop levels and eat up all remaining cycles */
CPU_STOPPED = 0;
SET_CYCLES(0);
CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
CPU_INSTR_MODE = INSTRUCTION_YES;
/* Turn off tracing */
FLAG_T1 = FLAG_T0 = 0;
m68ki_clear_trace();
/* Interrupt mask to level 7 */
FLAG_INT_MASK = 0x0700;
/* Reset VBR */
REG_VBR = 0;
/* Go to supervisor mode */
m68ki_set_sm_flag(SFLAG_SET | MFLAG_CLEAR);
/* Invalidate the prefetch queue */
#if M68K_EMULATE_PREFETCH
/* Set to arbitrary number since our first fetch is from 0 */
CPU_PREF_ADDR = 0x1000;
#endif /* M68K_EMULATE_PREFETCH */
/* Read the initial stack pointer and program counter */
m68ki_jump(0);
REG_SP = m68ki_read_imm_32();
REG_PC = m68ki_read_imm_32();
m68ki_jump(REG_PC);
CPU_RUN_MODE = RUN_MODE_NORMAL;
}
/* Pulse the HALT line on the CPU */
void m68k_pulse_halt(void)
{
CPU_STOPPED |= STOP_LEVEL_HALT;
}
/* Get and set the current CPU context */
/* This is to allow for multiple CPUs */
unsigned int m68k_context_size()
{
return sizeof(m68ki_cpu_core);
}
unsigned int m68k_get_context(void* dst)
{
if(dst) *(m68ki_cpu_core*)dst = m68ki_cpu;
return sizeof(m68ki_cpu_core);
}
void m68k_set_context(void* src)
{
if(src) m68ki_cpu = *(m68ki_cpu_core*)src;
}
/* ======================================================================== */
/* ============================== MAME STUFF ============================== */
/* ======================================================================== */
#if M68K_COMPILE_FOR_MAME == OPT_ON
#include "state.h"
static struct {
UINT16 sr;
int stopped;
int halted;
} m68k_substate;
static void m68k_prepare_substate(void)
{
m68k_substate.sr = m68ki_get_sr();
m68k_substate.stopped = (CPU_STOPPED & STOP_LEVEL_STOP) != 0;
m68k_substate.halted = (CPU_STOPPED & STOP_LEVEL_HALT) != 0;
}
static void m68k_post_load(void)
{
m68ki_set_sr_noint_nosp(m68k_substate.sr);
CPU_STOPPED = m68k_substate.stopped ? STOP_LEVEL_STOP : 0
| m68k_substate.halted ? STOP_LEVEL_HALT : 0;
m68ki_jump(REG_PC);
}
void m68k_state_register(const char *type)
{
int cpu = cpu_getactivecpu();
state_save_register_UINT32(type, cpu, "D" , REG_D, 8);
state_save_register_UINT32(type, cpu, "A" , REG_A, 8);
state_save_register_UINT32(type, cpu, "PPC" , &REG_PPC, 1);
state_save_register_UINT32(type, cpu, "PC" , &REG_PC, 1);
state_save_register_UINT32(type, cpu, "USP" , &REG_USP, 1);
state_save_register_UINT32(type, cpu, "ISP" , &REG_ISP, 1);
state_save_register_UINT32(type, cpu, "MSP" , &REG_MSP, 1);
state_save_register_UINT32(type, cpu, "VBR" , &REG_VBR, 1);
state_save_register_UINT32(type, cpu, "SFC" , &REG_SFC, 1);
state_save_register_UINT32(type, cpu, "DFC" , &REG_DFC, 1);
state_save_register_UINT32(type, cpu, "CACR" , &REG_CACR, 1);
state_save_register_UINT32(type, cpu, "CAAR" , &REG_CAAR, 1);
state_save_register_UINT16(type, cpu, "SR" , &m68k_substate.sr, 1);
state_save_register_UINT32(type, cpu, "INT_LEVEL" , &CPU_INT_LEVEL, 1);
state_save_register_UINT32(type, cpu, "INT_CYCLES", &CPU_INT_CYCLES, 1);
state_save_register_int (type, cpu, "STOPPED" , &m68k_substate.stopped);
state_save_register_int (type, cpu, "HALTED" , &m68k_substate.halted);
state_save_register_UINT32(type, cpu, "PREF_ADDR" , &CPU_PREF_ADDR, 1);
state_save_register_UINT32(type, cpu, "PREF_DATA" , &CPU_PREF_DATA, 1);
state_save_register_func_presave(m68k_prepare_substate);
state_save_register_func_postload(m68k_post_load);
}
#endif /* M68K_COMPILE_FOR_MAME */
/* ======================================================================== */
/* ============================== END OF FILE ============================= */
/* ======================================================================== */

1986
components/tme/musashi/m68kcpu.h Executable file

File diff suppressed because it is too large Load Diff

3477
components/tme/musashi/m68kdasm.c Executable file

File diff suppressed because it is too large Load Diff

1429
components/tme/musashi/m68kmake.c Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

305
components/tme/musashi/readme.txt Executable file
View File

@ -0,0 +1,305 @@
MUSASHI
=======
Version 3.4
A portable Motorola M680x0 processor emulation engine.
Copyright 1998-2002 Karl Stenerud. All rights reserved.
INTRODUCTION:
------------
Musashi is a Motorola 68000, 68010, 68EC020, and 68020 emulator written in C.
This emulator was written with two goals in mind: portability and speed.
The emulator is written to ANSI C89 specifications. It also uses inline
functions, which are C9X compliant.
It has been successfully running in the MAME project (www.mame.net) for years
and so has had time to mature.
LICENSE AND COPYRIGHT:
---------------------
Copyright © 1998-2001 Karl Stenerud
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
AVAILABILITY:
------------
The latest version of this code can be obtained at:
https://github.com/kstenerud/Musashi
CONTACTING THE AUTHOR:
---------------------
I can be reached at kstenerud@gmail.com
BASIC CONFIGURATION:
-------------------
The basic configuration will give you a standard 68000 that has sufficient
functionality to work in a primitive environment.
This setup assumes that you only have 1 device interrupting it, that the
device will always request an autovectored interrupt, and it will always clear
the interrupt before the interrupt service routine finishes (but could
possibly re-assert the interrupt).
You will have only one address space, no tracing, and no instruction prefetch.
To implement the basic configuration:
- Open m68kconf.h and verify that the settings for INLINE will work with your
compiler. (Currently set to "static __inline__", which works in gcc 2.9.
For C9X compliance, it should be "inline")
- In your host program, implement the following functions:
unsigned int m68k_read_memory_8(unsigned int address);
unsigned int m68k_read_memory_16(unsigned int address);
unsigned int m68k_read_memory_32(unsigned int address);
void m68k_write_memory_8(unsigned int address, unsigned int value);
void m68k_write_memory_16(unsigned int address, unsigned int value);
void m68k_write_memory_32(unsigned int address, unsigned int value);
- In your host program, be sure to call m68k_pulse_reset() once before calling
any of the other functions as this initializes the core.
- Use m68k_execute() to execute instructions and m68k_set_irq() to cause an
interrupt.
ADDING PROPER INTERRUPT HANDLING:
--------------------------------
The interrupt handling in the basic configuration doesn't emulate the
interrupt acknowledge phase of the CPU and automatically clears an interrupt
request during interrupt processing.
While this works for most systems, you may need more accurate interrupt
handling.
To add proper interrupt handling:
- In m68kconf.h, set M68K_EMULATE_INT_ACK to OPT_SPECIFY_HANDLER
- In m68kconf.h, set M68K_INT_ACK_CALLBACK(A) to your interrupt acknowledge
routine
- Your interrupt acknowledge routine must return an interrupt vector,
M68K_INT_ACK_AUTOVECTOR, or M68K_INT_ACK_SPURIOUS. most m68k
implementations just use autovectored interrupts.
- When the interrupting device is satisfied, you must call m68k_set_irq(0) to
remove the interrupt request.
MULTIPLE INTERRUPTS:
-------------------
The above system will work if you have only one device interrupting the CPU,
but if you have more than one device, you must do a bit more.
To add multiple interrupts:
- You must make an interrupt arbitration device that will take the highest
priority interrupt and encode it onto the IRQ pins on the CPU.
- The interrupt arbitration device should use m68k_set_irq() to set the
highest pending interrupt, or 0 for no interrupts pending.
SEPARATE IMMEDIATE READS:
------------------------
You can write faster memory access functions if you know whether you are
fetching from ROM or RAM. Immediate reads are always from the program space
(Always in ROM unless it is running self-modifying code).
To enable separate immediate reads:
- In m68kconf.h, turn on M68K_SEPARATE_READ_IMM.
- In your host program, implement the following functions:
unsigned int m68k_read_immediate_16(unsigned int address);
unsigned int m68k_read_immediate_32(unsigned int address);
- If you need to know the current PC (for banking and such), set
M68K_MONITOR_PC to OPT_SPECIFY_HANDLER, and set M68K_SET_PC_CALLBACK(A) to
your routine.
ADDRESS SPACES:
--------------
Most systems will only implement one address space, placing ROM at the lower
addresses and RAM at the higher. However, there is the possibility that a
system will implement ROM and RAM in the same address range, but in different
address spaces.
In this case, you might get away with assuming that immediate reads are in the
program space and all other reads are in the data space, if it weren't for the
fact that the exception vectors are fetched from the data space. As a result,
anyone implementing this kind of system will have to copy the vector table
from ROM to RAM using pc-relative instructions.
This makes things bad for emulation, because this means that a non-immediate
read is not necessarily in the data space.
The m68k deals with this by encoding the requested address space on the
function code pins:
FC
Address Space 210
------------------ ---
USER DATA 001
USER PROGRAM 010
SUPERVISOR DATA 101
SUPERVISOR PROGRAM 110
CPU SPACE 111 <-- not emulated in this core since we emulate
interrupt acknowledge in another way.
To emulate the function code pins:
- In m68kconf.h, set M68K_EMULATE_FC to OPT_SPECIFY_HANDLER and set
M68K_SET_FC_CALLBACK(A) to your function code handler function.
- Your function code handler should select the proper address space for
subsequent calls to m68k_read_xx (and m68k_write_xx for 68010+).
Note: immediate reads are always done from program space, so technically you
don't need to implement the separate immediate reads, although you could
gain more speed improvements leaving them in and doing some clever
programming.
USING DIFFERENT CPU TYPES:
-------------------------
The default is to enable only the 68000 cpu type. To change this, change the
settings for M68K_EMULATE_010 etc in m68kconf.h.
To set the CPU type you want to use:
- Make sure it is enabled in m68kconf.h. Current switches are:
M68K_EMULATE_010
M68K_EMULATE_EC020
M68K_EMULATE_020
- In your host program, call m68k_set_cpu_type() and then call
m68k_pulse_reset(). Valid CPU types are:
M68K_CPU_TYPE_68000,
M68K_CPU_TYPE_68010,
M68K_CPU_TYPE_68EC020,
M68K_CPU_TYPE_68020
CLOCK FREQUENCY:
---------------
In order to emulate the correct clock frequency, you will have to calculate
how long it takes the emulation to execute a certain number of "cycles" and
vary your calls to m68k_execute() accordingly.
As well, it is a good idea to take away the CPU's timeslice when it writes to
a memory-mapped port in order to give the device it wrote to a chance to
react.
You can use the functions m68k_cycles_run(), m68k_cycles_remaining(),
m68k_modify_timeslice(), and m68k_end_timeslice() to do this.
Try to use large cycle values in your calls to m68k_execute() since it will
increase throughput. You can always take away the timeslice later.
MORE CORRECT EMULATION:
----------------------
You may need to enable these in order to properly emulate some of the more
obscure functions of the m68k:
- M68K_EMULATE_BKPT_ACK causes the CPU to call a breakpoint handler on a BKPT
instruction
- M68K_EMULATE_TRACE causes the CPU to generate trace exceptions when the
trace bits are set
- M68K_EMULATE_RESET causes the CPU to call a reset handler on a RESET
instruction.
- M68K_EMULATE_PREFETCH emulates the 4-word instruction prefetch that is part
of the 68000/68010 (needed for Amiga emulation).
NOTE: if the CPU fetches a word or longword at an odd address when this
option is on, it will yield unpredictable results, which is why a real
68000 will generate an address error exception.
- M68K_EMULATE_ADDRESS_ERROR will cause the CPU to generate address error
exceptions if it attempts to read a word or longword at an odd address.
- call m68k_pulse_halt() to emulate the HALT pin.
CONVENIENCE FUNCTIONS:
---------------------
These are in here for programmer convenience:
- M68K_INSTRUCTION_HOOK lets you call a handler before each instruction.
- M68K_LOG_ENABLE and M68K_LOG_1010_1111 lets you log illegal and A/F-line
instructions.
MULTIPLE CPU EMULATION:
----------------------
The default is to use only one CPU. To use more than one CPU in this core,
there are some things to keep in mind:
- To have different cpus call different functions, use OPT_ON instead of
OPT_SPECIFY_HANDLER, and use the m68k_set_xxx_callback() functions to set
your callback handlers on a per-cpu basis.
- Be sure to call set_cpu_type() for each CPU you use.
- Use m68k_set_context() and m68k_get_context() to switch to another CPU.
LOAD AND SAVE CPU CONTEXTS FROM DISK:
------------------------------------
You can use them68k_load_context() and m68k_save_context() functions to load
and save the CPU state to disk.
GET/SET INFORMATION FROM THE CPU:
--------------------------------
You can use m68k_get_reg() and m68k_set_reg() to gain access to the internals
of the CPU.
EXAMPLE:
-------
The subdir example contains a full example (currently DOS only).

View File

@ -271,7 +271,7 @@ void ncrWrite(unsigned int addr, unsigned int dack, unsigned int val) {
} else if (addr==7) {
//Start DMA. We already do this using the mode bit.
}
printf("%08X SCSI: (dack %d), cur state %s %02x to %s (reg %d)\n", pc, dack, stateNames[ncr.state], val, regNamesW[addr], addr);
// printf("%08X SCSI: (dack %d), cur state %s %02x to %s (reg %d)\n", pc, dack, stateNames[ncr.state], val, regNamesW[addr], addr);
}
void ncrRegisterDevice(int id, SCSIDevice* dev){

View File

@ -1,4 +1,5 @@
#!/bin/bash
#python /home/jeroen/esp8266/esp32/esp-idf/bin/esptool.py --chip esp32 --port "/dev/ttyUSB0" --baud 115200 write_flash -z -fs 32m 0x100000 doom1-cut.wad
python /home/jeroen/esp8266/esp32/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port "/dev/ttyUSB1" --baud $((921600/2)) --before default_reset --after hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size detect 0x100000 rom.bin
#python /home/jeroen/esp8266/esp32/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port "/dev/ttyUSB1" --baud $((921600/2)) --before default_reset --after hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size detect 0x100000 rom.bin
python /home/jeroen/esp8266/esp32/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port "/dev/ttyUSB1" --baud $((921600/2)) --before default_reset --after hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size detect 0x100000 rom320240.bin

View File

@ -105,13 +105,7 @@ CONFIG_TRACEMEM_RESERVE_DRAM=0x0
# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
# CONFIG_ESP32_ENABLE_COREDUMP is not set
CONFIG_MEMMAP_SPIRAM_ENABLE=y
CONFIG_MEMMAP_SPIRAM_TYPE_ESPPSRAM32=y
CONFIG_MEMMAP_SPIRAM_SIZE=4194304
# CONFIG_MEMMAP_SPIRAM_NO_HEAPALLOC is not set
CONFIG_MEMMAP_SPIRAM_TEST=y
CONFIG_MEMMAP_SPIRAM_ENABLE_MALLOC=y
CONFIG_MEMMAP_SPIRAM_ALLOC_LIMIT_INTERNAL=40960
# CONFIG_MEMMAP_SPIRAM_ENABLE is not set
# CONFIG_TWO_MAC_ADDRESS_FROM_EFUSE is not set
CONFIG_FOUR_MAC_ADDRESS_FROM_EFUSE=y
CONFIG_NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE=4
@ -146,7 +140,7 @@ CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=0
#
# FreeRTOS
#
# CONFIG_FREERTOS_UNICORE is not set
CONFIG_FREERTOS_UNICORE=y
CONFIG_FREERTOS_CORETIMER_0=y
# CONFIG_FREERTOS_CORETIMER_1 is not set
CONFIG_FREERTOS_HZ=100
@ -154,7 +148,7 @@ CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y
# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set