Get the emulator to the point where it'll start to run code; it then fails,
because the version of Musashi I imported doesn't support floating point...
This commit is contained in:
parent
a8802c934b
commit
2cf39be752
|
@ -79,7 +79,7 @@
|
||||||
* If off, all interrupts will be autovectored and all interrupt requests will
|
* If off, all interrupts will be autovectored and all interrupt requests will
|
||||||
* auto-clear when the interrupt is serviced.
|
* auto-clear when the interrupt is serviced.
|
||||||
*/
|
*/
|
||||||
#define M68K_EMULATE_INT_ACK OPT_SPECIFY_HANDLER
|
#define M68K_EMULATE_INT_ACK OPT_OFF
|
||||||
#define M68K_INT_ACK_CALLBACK(A) cpu_irq_ack(A)
|
#define M68K_INT_ACK_CALLBACK(A) cpu_irq_ack(A)
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@
|
||||||
/* If ON, CPU will call the output reset callback when it encounters a reset
|
/* If ON, CPU will call the output reset callback when it encounters a reset
|
||||||
* instruction.
|
* instruction.
|
||||||
*/
|
*/
|
||||||
#define M68K_EMULATE_RESET OPT_SPECIFY_HANDLER
|
#define M68K_EMULATE_RESET OPT_OFF
|
||||||
#define M68K_RESET_CALLBACK() cpu_pulse_reset()
|
#define M68K_RESET_CALLBACK() cpu_pulse_reset()
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
* want to properly emulate the m68010 or higher. (moves uses function codes
|
* want to properly emulate the m68010 or higher. (moves uses function codes
|
||||||
* to read/write data from different address spaces)
|
* to read/write data from different address spaces)
|
||||||
*/
|
*/
|
||||||
#define M68K_EMULATE_FC OPT_SPECIFY_HANDLER
|
#define M68K_EMULATE_FC OPT_OFF
|
||||||
#define M68K_SET_FC_CALLBACK(A) cpu_set_fc(A)
|
#define M68K_SET_FC_CALLBACK(A) cpu_set_fc(A)
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
*/
|
*/
|
||||||
#define M68K_LOG_ENABLE OPT_OFF
|
#define M68K_LOG_ENABLE OPT_OFF
|
||||||
#define M68K_LOG_1010_1111 OPT_OFF
|
#define M68K_LOG_1010_1111 OPT_OFF
|
||||||
#define M68K_LOG_FILEHANDLE some_file_handle
|
#define M68K_LOG_FILEHANDLE stderr
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------- COMPATIBILITY ---------------------------- */
|
/* ----------------------------- COMPATIBILITY ---------------------------- */
|
||||||
|
@ -166,7 +166,8 @@
|
||||||
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
* NOTE: not enabling inline functions will SEVERELY slow down emulation.
|
||||||
*/
|
*/
|
||||||
#ifndef INLINE
|
#ifndef INLINE
|
||||||
#define INLINE static __inline__
|
//#define INLINE static __inline__
|
||||||
|
#define INLINE static
|
||||||
#endif /* INLINE */
|
#endif /* INLINE */
|
||||||
|
|
||||||
#endif /* M68K_COMPILE_FOR_MAME */
|
#endif /* M68K_COMPILE_FOR_MAME */
|
||||||
|
|
|
@ -7,22 +7,12 @@
|
||||||
|
|
||||||
void disassemble_program();
|
void disassemble_program();
|
||||||
|
|
||||||
/* Memory-mapped IO ports */
|
#define ADDRESS_MASK 0xffffffff
|
||||||
#define INPUT_ADDRESS 0x800000
|
#define RAM_BASE 0x08000000
|
||||||
#define OUTPUT_ADDRESS 0x400000
|
#define RAM_TOP 0x08100000
|
||||||
|
|
||||||
/* IRQ connections */
|
|
||||||
#define IRQ_NMI_DEVICE 7
|
|
||||||
#define IRQ_INPUT_DEVICE 2
|
|
||||||
#define IRQ_OUTPUT_DEVICE 1
|
|
||||||
|
|
||||||
/* Time between characters sent to output device (seconds) */
|
|
||||||
#define OUTPUT_DEVICE_PERIOD 1
|
|
||||||
|
|
||||||
/* ROM and RAM sizes */
|
|
||||||
#define MAX_ROM 0xfff
|
|
||||||
#define MAX_RAM 0xff
|
|
||||||
|
|
||||||
|
#define INIT_SP RAM_TOP
|
||||||
|
#define INIT_PC 0x08000054
|
||||||
|
|
||||||
/* Read/write macros */
|
/* Read/write macros */
|
||||||
#define READ_BYTE(BASE, ADDR) (BASE)[ADDR]
|
#define READ_BYTE(BASE, ADDR) (BASE)[ADDR]
|
||||||
|
@ -42,8 +32,8 @@ void disassemble_program();
|
||||||
(BASE)[(ADDR)+3] = (VAL)&0xff
|
(BASE)[(ADDR)+3] = (VAL)&0xff
|
||||||
|
|
||||||
|
|
||||||
/* Prototypes */
|
static void exit_error(char* fmt, ...);
|
||||||
void exit_error(char* fmt, ...);
|
static void syscall(void);
|
||||||
|
|
||||||
unsigned int cpu_read_byte(unsigned int address);
|
unsigned int cpu_read_byte(unsigned int address);
|
||||||
unsigned int cpu_read_word(unsigned int address);
|
unsigned int cpu_read_word(unsigned int address);
|
||||||
|
@ -51,47 +41,8 @@ unsigned int cpu_read_long(unsigned int address);
|
||||||
void cpu_write_byte(unsigned int address, unsigned int value);
|
void cpu_write_byte(unsigned int address, unsigned int value);
|
||||||
void cpu_write_word(unsigned int address, unsigned int value);
|
void cpu_write_word(unsigned int address, unsigned int value);
|
||||||
void cpu_write_long(unsigned int address, unsigned int value);
|
void cpu_write_long(unsigned int address, unsigned int value);
|
||||||
void cpu_pulse_reset(void);
|
|
||||||
void cpu_set_fc(unsigned int fc);
|
|
||||||
int cpu_irq_ack(int level);
|
|
||||||
|
|
||||||
void nmi_device_reset(void);
|
unsigned char g_ram[RAM_TOP - RAM_BASE];
|
||||||
void nmi_device_update(void);
|
|
||||||
int nmi_device_ack(void);
|
|
||||||
|
|
||||||
void input_device_reset(void);
|
|
||||||
void input_device_update(void);
|
|
||||||
int input_device_ack(void);
|
|
||||||
unsigned int input_device_read(void);
|
|
||||||
void input_device_write(unsigned int value);
|
|
||||||
|
|
||||||
void output_device_reset(void);
|
|
||||||
void output_device_update(void);
|
|
||||||
int output_device_ack(void);
|
|
||||||
unsigned int output_device_read(void);
|
|
||||||
void output_device_write(unsigned int value);
|
|
||||||
|
|
||||||
void int_controller_set(unsigned int value);
|
|
||||||
void int_controller_clear(unsigned int value);
|
|
||||||
|
|
||||||
void get_user_input(void);
|
|
||||||
|
|
||||||
|
|
||||||
/* Data */
|
|
||||||
unsigned int g_quit = 0; /* 1 if we want to quit */
|
|
||||||
unsigned int g_nmi = 0; /* 1 if nmi pending */
|
|
||||||
|
|
||||||
int g_input_device_value = -1; /* Current value in input device */
|
|
||||||
|
|
||||||
unsigned int g_output_device_ready = 0; /* 1 if output device is ready */
|
|
||||||
time_t g_output_device_last_output; /* Time of last char output */
|
|
||||||
|
|
||||||
unsigned int g_int_controller_pending = 0; /* list of pending interrupts */
|
|
||||||
unsigned int g_int_controller_highest_int = 0; /* Highest pending interrupt */
|
|
||||||
|
|
||||||
unsigned char g_rom[MAX_ROM+1]; /* ROM */
|
|
||||||
unsigned char g_ram[MAX_RAM+1]; /* RAM */
|
|
||||||
unsigned int g_fc; /* Current function code from CPU */
|
|
||||||
|
|
||||||
|
|
||||||
/* Exit with an error message. Use printf syntax. */
|
/* Exit with an error message. Use printf syntax. */
|
||||||
|
@ -118,343 +69,67 @@ void exit_error(char* fmt, ...)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned int transform_address(unsigned int address)
|
||||||
/* Read data from RAM, ROM, or a device */
|
|
||||||
unsigned int cpu_read_byte(unsigned int address)
|
|
||||||
{
|
{
|
||||||
if(g_fc & 2) /* Program */
|
unsigned int i = (address & ADDRESS_MASK) - RAM_BASE;
|
||||||
{
|
if (i >= (unsigned int)(RAM_TOP - RAM_BASE))
|
||||||
if(address > MAX_ROM)
|
exit_error("Attempted to read from RAM address %08x %08x", address, i);
|
||||||
exit_error("Attempted to read byte from ROM address %08x", address);
|
return i;
|
||||||
return READ_BYTE(g_rom, address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise it's data space */
|
|
||||||
switch(address)
|
|
||||||
{
|
|
||||||
case INPUT_ADDRESS:
|
|
||||||
return input_device_read();
|
|
||||||
case OUTPUT_ADDRESS:
|
|
||||||
return output_device_read();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(address > MAX_RAM)
|
|
||||||
exit_error("Attempted to read byte from RAM address %08x", address);
|
|
||||||
return READ_BYTE(g_ram, address);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int cpu_read_word(unsigned int address)
|
|
||||||
{
|
|
||||||
if(g_fc & 2) /* Program */
|
|
||||||
{
|
|
||||||
if(address > MAX_ROM)
|
|
||||||
exit_error("Attempted to read word from ROM address %08x", address);
|
|
||||||
return READ_WORD(g_rom, address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise it's data space */
|
|
||||||
switch(address)
|
|
||||||
{
|
|
||||||
case INPUT_ADDRESS:
|
|
||||||
return input_device_read();
|
|
||||||
case OUTPUT_ADDRESS:
|
|
||||||
return output_device_read();
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(address > MAX_RAM)
|
|
||||||
exit_error("Attempted to read word from RAM address %08x", address);
|
|
||||||
return READ_WORD(g_ram, address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int cpu_read_long(unsigned int address)
|
unsigned int cpu_read_long(unsigned int address)
|
||||||
{
|
{
|
||||||
if(g_fc & 2) /* Program */
|
|
||||||
{
|
|
||||||
if(address > MAX_ROM)
|
|
||||||
exit_error("Attempted to read long from ROM address %08x", address);
|
|
||||||
return READ_LONG(g_rom, address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise it's data space */
|
|
||||||
switch (address)
|
switch (address)
|
||||||
{
|
{
|
||||||
case INPUT_ADDRESS:
|
case 0x00: return INIT_SP;
|
||||||
return input_device_read();
|
case 0x04: return INIT_PC;
|
||||||
case OUTPUT_ADDRESS:
|
case 0x80: syscall(); return 0x10000;
|
||||||
return output_device_read();
|
case 0x10000: return 0x4e73; /* rte */
|
||||||
default:
|
case 0x10004: return 0;
|
||||||
break;
|
default: return READ_LONG(g_ram, transform_address(address));
|
||||||
}
|
}
|
||||||
if(address > MAX_RAM)
|
|
||||||
exit_error("Attempted to read long from RAM address %08x", address);
|
|
||||||
return READ_LONG(g_ram, address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int cpu_read_word(unsigned int address)
|
||||||
|
{
|
||||||
|
unsigned int l = cpu_read_long(address & ~3);
|
||||||
|
l >>= (address & 2) * 8;
|
||||||
|
return l & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int cpu_read_byte(unsigned int address)
|
||||||
|
{
|
||||||
|
unsigned int l = cpu_read_long(address & ~3);
|
||||||
|
l >>= (address & 3) * 8;
|
||||||
|
return l & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int cpu_read_word_dasm(unsigned int address)
|
unsigned int cpu_read_word_dasm(unsigned int address)
|
||||||
{
|
{
|
||||||
if(address > MAX_ROM)
|
return cpu_read_word(address);
|
||||||
exit_error("Disassembler attempted to read word from ROM address %08x", address);
|
|
||||||
return READ_WORD(g_rom, address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int cpu_read_long_dasm(unsigned int address)
|
unsigned int cpu_read_long_dasm(unsigned int address)
|
||||||
{
|
{
|
||||||
if(address > MAX_ROM)
|
return cpu_read_long(address);
|
||||||
exit_error("Dasm attempted to read long from ROM address %08x", address);
|
|
||||||
return READ_LONG(g_rom, address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write data to RAM or a device */
|
/* Write data to RAM or a device */
|
||||||
void cpu_write_byte(unsigned int address, unsigned int value)
|
void cpu_write_byte(unsigned int address, unsigned int value)
|
||||||
{
|
{
|
||||||
if(g_fc & 2) /* Program */
|
WRITE_BYTE(g_ram, transform_address(address), value);
|
||||||
exit_error("Attempted to write %02x to ROM address %08x", value&0xff, address);
|
|
||||||
|
|
||||||
/* Otherwise it's data space */
|
|
||||||
switch(address)
|
|
||||||
{
|
|
||||||
case INPUT_ADDRESS:
|
|
||||||
input_device_write(value&0xff);
|
|
||||||
return;
|
|
||||||
case OUTPUT_ADDRESS:
|
|
||||||
output_device_write(value&0xff);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(address > MAX_RAM)
|
|
||||||
exit_error("Attempted to write %02x to RAM address %08x", value&0xff, address);
|
|
||||||
WRITE_BYTE(g_ram, address, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_write_word(unsigned int address, unsigned int value)
|
void cpu_write_word(unsigned int address, unsigned int value)
|
||||||
{
|
{
|
||||||
if(g_fc & 2) /* Program */
|
WRITE_WORD(g_ram, transform_address(address), value);
|
||||||
exit_error("Attempted to write %04x to ROM address %08x", value&0xffff, address);
|
|
||||||
|
|
||||||
/* Otherwise it's data space */
|
|
||||||
switch(address)
|
|
||||||
{
|
|
||||||
case INPUT_ADDRESS:
|
|
||||||
input_device_write(value&0xffff);
|
|
||||||
return;
|
|
||||||
case OUTPUT_ADDRESS:
|
|
||||||
output_device_write(value&0xffff);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(address > MAX_RAM)
|
|
||||||
exit_error("Attempted to write %04x to RAM address %08x", value&0xffff, address);
|
|
||||||
WRITE_WORD(g_ram, address, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_write_long(unsigned int address, unsigned int value)
|
void cpu_write_long(unsigned int address, unsigned int value)
|
||||||
{
|
{
|
||||||
if(g_fc & 2) /* Program */
|
WRITE_LONG(g_ram, transform_address(address), value);
|
||||||
exit_error("Attempted to write %08x to ROM address %08x", value, address);
|
|
||||||
|
|
||||||
/* Otherwise it's data space */
|
|
||||||
switch(address)
|
|
||||||
{
|
|
||||||
case INPUT_ADDRESS:
|
|
||||||
input_device_write(value);
|
|
||||||
return;
|
|
||||||
case OUTPUT_ADDRESS:
|
|
||||||
output_device_write(value);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(address > MAX_RAM)
|
|
||||||
exit_error("Attempted to write %08x to RAM address %08x", value, address);
|
|
||||||
WRITE_LONG(g_ram, address, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called when the CPU pulses the RESET line */
|
|
||||||
void cpu_pulse_reset(void)
|
|
||||||
{
|
|
||||||
nmi_device_reset();
|
|
||||||
output_device_reset();
|
|
||||||
input_device_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called when the CPU changes the function code pins */
|
|
||||||
void cpu_set_fc(unsigned int fc)
|
|
||||||
{
|
|
||||||
g_fc = fc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called when the CPU acknowledges an interrupt */
|
|
||||||
int cpu_irq_ack(int level)
|
|
||||||
{
|
|
||||||
switch(level)
|
|
||||||
{
|
|
||||||
case IRQ_NMI_DEVICE:
|
|
||||||
return nmi_device_ack();
|
|
||||||
case IRQ_INPUT_DEVICE:
|
|
||||||
return input_device_ack();
|
|
||||||
case IRQ_OUTPUT_DEVICE:
|
|
||||||
return output_device_ack();
|
|
||||||
}
|
|
||||||
return M68K_INT_ACK_SPURIOUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Implementation for the NMI device */
|
|
||||||
void nmi_device_reset(void)
|
|
||||||
{
|
|
||||||
g_nmi = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nmi_device_update(void)
|
|
||||||
{
|
|
||||||
if(g_nmi)
|
|
||||||
{
|
|
||||||
g_nmi = 0;
|
|
||||||
int_controller_set(IRQ_NMI_DEVICE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int nmi_device_ack(void)
|
|
||||||
{
|
|
||||||
printf("\nNMI\n");fflush(stdout);
|
|
||||||
int_controller_clear(IRQ_NMI_DEVICE);
|
|
||||||
return M68K_INT_ACK_AUTOVECTOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Implementation for the input device */
|
|
||||||
void input_device_reset(void)
|
|
||||||
{
|
|
||||||
g_input_device_value = -1;
|
|
||||||
int_controller_clear(IRQ_INPUT_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void input_device_update(void)
|
|
||||||
{
|
|
||||||
if(g_input_device_value >= 0)
|
|
||||||
int_controller_set(IRQ_INPUT_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int input_device_ack(void)
|
|
||||||
{
|
|
||||||
return M68K_INT_ACK_AUTOVECTOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int input_device_read(void)
|
|
||||||
{
|
|
||||||
int value = g_input_device_value > 0 ? g_input_device_value : 0;
|
|
||||||
int_controller_clear(IRQ_INPUT_DEVICE);
|
|
||||||
g_input_device_value = -1;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void input_device_write(unsigned int value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Implementation for the output device */
|
|
||||||
void output_device_reset(void)
|
|
||||||
{
|
|
||||||
g_output_device_last_output = time(NULL);
|
|
||||||
g_output_device_ready = 0;
|
|
||||||
int_controller_clear(IRQ_OUTPUT_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_device_update(void)
|
|
||||||
{
|
|
||||||
if(!g_output_device_ready)
|
|
||||||
{
|
|
||||||
if((time(NULL) - g_output_device_last_output) >= OUTPUT_DEVICE_PERIOD)
|
|
||||||
{
|
|
||||||
g_output_device_ready = 1;
|
|
||||||
int_controller_set(IRQ_OUTPUT_DEVICE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int output_device_ack(void)
|
|
||||||
{
|
|
||||||
return M68K_INT_ACK_AUTOVECTOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int output_device_read(void)
|
|
||||||
{
|
|
||||||
int_controller_clear(IRQ_OUTPUT_DEVICE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void output_device_write(unsigned int value)
|
|
||||||
{
|
|
||||||
char ch;
|
|
||||||
if(g_output_device_ready)
|
|
||||||
{
|
|
||||||
ch = value & 0xff;
|
|
||||||
printf("%c", ch);
|
|
||||||
g_output_device_last_output = time(NULL);
|
|
||||||
g_output_device_ready = 0;
|
|
||||||
int_controller_clear(IRQ_OUTPUT_DEVICE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Implementation for the interrupt controller */
|
|
||||||
void int_controller_set(unsigned int value)
|
|
||||||
{
|
|
||||||
unsigned int old_pending = g_int_controller_pending;
|
|
||||||
|
|
||||||
g_int_controller_pending |= (1<<value);
|
|
||||||
|
|
||||||
if(old_pending != g_int_controller_pending && value > g_int_controller_highest_int)
|
|
||||||
{
|
|
||||||
g_int_controller_highest_int = value;
|
|
||||||
m68k_set_irq(g_int_controller_highest_int);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void int_controller_clear(unsigned int value)
|
|
||||||
{
|
|
||||||
g_int_controller_pending &= ~(1<<value);
|
|
||||||
|
|
||||||
for(g_int_controller_highest_int = 7;g_int_controller_highest_int > 0;g_int_controller_highest_int--)
|
|
||||||
if(g_int_controller_pending & (1<<g_int_controller_highest_int))
|
|
||||||
break;
|
|
||||||
|
|
||||||
m68k_set_irq(g_int_controller_highest_int);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Parse user input and update any devices that need user input */
|
|
||||||
void get_user_input(void)
|
|
||||||
{
|
|
||||||
static int last_ch = -1;
|
|
||||||
int ch = -1; /* not supported */
|
|
||||||
//int ch = osd_get_char();
|
|
||||||
|
|
||||||
if(ch >= 0)
|
|
||||||
{
|
|
||||||
switch(ch)
|
|
||||||
{
|
|
||||||
case 0x1b:
|
|
||||||
g_quit = 1;
|
|
||||||
break;
|
|
||||||
case '~':
|
|
||||||
if(last_ch != ch)
|
|
||||||
g_nmi = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_input_device_value = ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
last_ch = ch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disassembler */
|
/* Disassembler */
|
||||||
|
@ -494,21 +169,34 @@ void disassemble_program()
|
||||||
void cpu_instr_callback()
|
void cpu_instr_callback()
|
||||||
{
|
{
|
||||||
/* The following code would print out instructions as they are executed */
|
/* The following code would print out instructions as they are executed */
|
||||||
/*
|
|
||||||
|
#if 1
|
||||||
static char buff[100];
|
static char buff[100];
|
||||||
static char buff2[100];
|
static char buff2[100];
|
||||||
static unsigned int pc;
|
static unsigned int pc;
|
||||||
static unsigned int instr_size;
|
static unsigned int instr_size;
|
||||||
|
|
||||||
pc = m68k_get_reg(NULL, M68K_REG_PC);
|
pc = m68k_get_reg(NULL, M68K_REG_PC);
|
||||||
instr_size = m68k_disassemble(buff, pc, M68K_CPU_TYPE_68000);
|
instr_size = m68k_disassemble(buff, pc, M68K_CPU_TYPE_68020);
|
||||||
make_hex(buff2, pc, instr_size);
|
make_hex(buff2, pc, instr_size);
|
||||||
printf("E %03x: %-20s: %s\n", pc, buff2, buff);
|
printf("E %03x: %-20s: %s\n", pc, buff2, buff);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
*/
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void syscall(void)
|
||||||
|
{
|
||||||
|
int s = m68k_get_reg(NULL, M68K_REG_D0);
|
||||||
|
switch (s)
|
||||||
|
{
|
||||||
|
case 45: /* brk */
|
||||||
|
m68k_set_reg(M68K_REG_D0, RAM_TOP-0x1000);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
exit_error("unknown system call %d", s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The main loop */
|
/* The main loop */
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
|
@ -524,38 +212,42 @@ int main(int argc, char* argv[])
|
||||||
if((fhandle = fopen(argv[1], "rb")) == NULL)
|
if((fhandle = fopen(argv[1], "rb")) == NULL)
|
||||||
exit_error("Unable to open %s", argv[1]);
|
exit_error("Unable to open %s", argv[1]);
|
||||||
|
|
||||||
if(fread(g_rom, 1, MAX_ROM+1, fhandle) <= 0)
|
if(fread(g_ram, 1, RAM_TOP - RAM_BASE, fhandle) <= 0)
|
||||||
exit_error("Error reading %s", argv[1]);
|
exit_error("Error reading %s", argv[1]);
|
||||||
|
|
||||||
// disassemble_program();
|
// disassemble_program();
|
||||||
|
|
||||||
m68k_init();
|
m68k_init();
|
||||||
m68k_set_cpu_type(M68K_CPU_TYPE_68000);
|
m68k_set_cpu_type(M68K_CPU_TYPE_68020);
|
||||||
m68k_pulse_reset();
|
m68k_pulse_reset();
|
||||||
input_device_reset();
|
|
||||||
output_device_reset();
|
|
||||||
nmi_device_reset();
|
|
||||||
|
|
||||||
g_quit = 0;
|
/* On entry, the Linux stack looks like this.
|
||||||
while(!g_quit)
|
*
|
||||||
|
* sp+.. NULL
|
||||||
|
* sp+8+(4*argc) env (X quads)
|
||||||
|
* sp+4+(4*argc) NULL
|
||||||
|
* sp+4 argv (argc quads)
|
||||||
|
* sp argc
|
||||||
|
*
|
||||||
|
* We'll set it up with a bodgy stack frame with argc=0 just to keep the
|
||||||
|
* startup code happy.
|
||||||
|
*/
|
||||||
|
|
||||||
{
|
{
|
||||||
// Our loop requires some interleaving to allow us to update the
|
unsigned int sp = INIT_SP;
|
||||||
// input, output, and nmi devices.
|
cpu_write_long(sp -= 4, 0);
|
||||||
|
unsigned int envp = sp;
|
||||||
get_user_input();
|
cpu_write_long(sp -= 4, envp);
|
||||||
|
cpu_write_long(sp -= 4, 0);
|
||||||
// Values to execute determine the interleave rate.
|
unsigned long argv = sp;
|
||||||
// Smaller values allow for more accurate interleaving with multiple
|
cpu_write_long(sp -= 4, argv);
|
||||||
// devices/CPUs but is more processor intensive.
|
cpu_write_long(sp -= 4, 0);
|
||||||
// 100000 is usually a good value to start at, then work from there.
|
m68k_set_reg(M68K_REG_SP, sp);
|
||||||
|
|
||||||
// Note that I am not emulating the correct clock speed!
|
|
||||||
m68k_execute(100000);
|
|
||||||
output_device_update();
|
|
||||||
input_device_update();
|
|
||||||
nmi_device_update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
m68k_execute(100000);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
plat/linux68k/tests/build.lua
Normal file
7
plat/linux68k/tests/build.lua
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
include("tests/plat/build.lua")
|
||||||
|
|
||||||
|
plat_testsuite {
|
||||||
|
name = "tests",
|
||||||
|
plat = "linux68k",
|
||||||
|
method = "plat/linux68k/emu+emu68k"
|
||||||
|
}
|
Loading…
Reference in a new issue