Compare commits
5 commits
main
...
multidrive
| Author | SHA1 | Date | |
|---|---|---|---|
| cd98358391 | |||
| a59b9fbeb3 | |||
| 24c8b1ebe6 | |||
| b12811d05b | |||
| a16d721ce8 |
9 changed files with 203 additions and 105 deletions
6
Makefile
6
Makefile
|
|
@ -66,7 +66,7 @@ $(MUSASHI)/m68kops.c $(MUSASHI)/m68kops.h:
|
||||||
prepare: $(MUSASHI)/m68kops.c $(MUSASHI)/m68kops.h
|
prepare: $(MUSASHI)/m68kops.c $(MUSASHI)/m68kops.h
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_CFG) -c $< -o $@
|
$(CC) $(CFLAGS) $(CFLAGS_CFG) -c $< -o $@ -MMD -MF $*.d
|
||||||
|
|
||||||
main: $(OBJS)
|
main: $(OBJS)
|
||||||
@echo Linking $(OBJS)
|
@echo Linking $(OBJS)
|
||||||
|
|
@ -74,7 +74,7 @@ main: $(OBJS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C $(MUSASHI) clean
|
make -C $(MUSASHI) clean
|
||||||
rm -f $(MY_OBJS) main
|
rm -f $(MY_OBJS) $(OBJS:%.o=%.d) main
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Mac driver sources (no need to generally rebuild
|
# Mac driver sources (no need to generally rebuild
|
||||||
|
|
@ -94,3 +94,5 @@ sonydrv.bin: macsrc/sonydrv.S
|
||||||
cpp $< | $(M68K_AS) -o sonydrv.o
|
cpp $< | $(M68K_AS) -o sonydrv.o
|
||||||
$(M68K_LD) sonydrv.o -o sonydrv.elf -Ttext=0
|
$(M68K_LD) sonydrv.o -o sonydrv.elf -Ttext=0
|
||||||
$(M68K_OBJCOPY) sonydrv.elf -O binary --keep-section=.text $@
|
$(M68K_OBJCOPY) sonydrv.elf -O binary --keep-section=.text $@
|
||||||
|
|
||||||
|
-include $(OBJS:%.o=%.d)
|
||||||
|
|
|
||||||
2
external/Musashi
vendored
2
external/Musashi
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit b3144f12c1296d8fbb600eea13f5db71ffb1b8d8
|
Subproject commit 8dcac80091b745e9181281fbf63cdd04a95b963a
|
||||||
|
|
@ -48,5 +48,5 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
void disc_init(disc_descr_t discs[DISC_NUM_DRIVES]);
|
void disc_init(disc_descr_t discs[DISC_NUM_DRIVES]);
|
||||||
int disc_pv_hook(uint8_t opcode);
|
int disc_pv_hook(uint8_t opcode);
|
||||||
|
void disc_tick();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,13 @@
|
||||||
#define M68K_FAST_FUNC(x) __not_in_flash_func(x)
|
#define M68K_FAST_FUNC(x) __not_in_flash_func(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* If ON, CPU will support "emul_op" instructions from 0x7100..0x713f by
|
||||||
|
* calling m68k_end_timeslice when they are encountered. The caller can (must)
|
||||||
|
* check the IR register and implement the operation.
|
||||||
|
* If off, these remain illegal instructions.
|
||||||
|
*/
|
||||||
|
#define M68K_EMUL_OP OPT_ON
|
||||||
|
|
||||||
#endif /* M68K_COMPILE_FOR_MAME */
|
#endif /* M68K_COMPILE_FOR_MAME */
|
||||||
|
|
||||||
/* ======================================================================== */
|
/* ======================================================================== */
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c,
|
0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x6a,
|
||||||
0x00, 0x56, 0x00, 0x68, 0x00, 0x94, 0x05, 0x2e, 0x53, 0x6f, 0x6e, 0x79,
|
0x00, 0x74, 0x00, 0x86, 0x00, 0xb2, 0x05, 0x2e, 0x53, 0x6f, 0x6e, 0x79,
|
||||||
0x48, 0xe7, 0x00, 0xc0, 0x10, 0x3c, 0x00, 0x1e, 0xa7, 0x1e, 0x24, 0x48,
|
0xa0, 0x2f, 0x26, 0x7a, 0x00, 0x9c, 0x16, 0xbc, 0x00, 0x04, 0x48, 0xe7,
|
||||||
0x4c, 0xdf, 0x03, 0x00, 0xb5, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00,
|
0x00, 0xc0, 0x10, 0x3c, 0x00, 0x3c, 0xa7, 0x1e, 0x24, 0x48, 0x4c, 0xdf,
|
||||||
0x00, 0x18, 0x26, 0x7a, 0x00, 0x64, 0x16, 0xbc, 0x00, 0x00, 0x20, 0x3c,
|
0x03, 0x00, 0xb5, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x2c,
|
||||||
0x00, 0x01, 0xff, 0xfb, 0x20, 0x4a, 0x5c, 0x88, 0xa0, 0x4e, 0x4e, 0x75,
|
0x26, 0x7a, 0x00, 0x7a, 0x16, 0xbc, 0x00, 0x00, 0x76, 0x02, 0xd5, 0xfc,
|
||||||
0x70, 0xe9, 0x4e, 0x75, 0x24, 0x7a, 0x00, 0x4a, 0x14, 0xbc, 0x00, 0x01,
|
0x00, 0x00, 0x00, 0x24, 0x20, 0x03, 0x48, 0x40, 0x00, 0x40, 0xff, 0xfb,
|
||||||
0x60, 0x1a, 0x24, 0x7a, 0x00, 0x40, 0x14, 0xbc, 0x00, 0x02, 0x0c, 0x68,
|
0x20, 0x4a, 0xa0, 0x4e, 0x95, 0xfc, 0x00, 0x00, 0x00, 0x1e, 0x53, 0x43,
|
||||||
0x00, 0x01, 0x00, 0x1a, 0x66, 0x0a, 0x4e, 0x75, 0x24, 0x7a, 0x00, 0x2e,
|
0x66, 0x00, 0xff, 0xea, 0x4e, 0x75, 0x70, 0xe9, 0x4e, 0x75, 0x24, 0x7a,
|
||||||
0x14, 0xbc, 0x00, 0x03, 0x32, 0x28, 0x00, 0x06, 0x08, 0x01, 0x00, 0x09,
|
0x00, 0x4c, 0x14, 0xbc, 0x00, 0x01, 0x60, 0x1a, 0x24, 0x7a, 0x00, 0x42,
|
||||||
0x67, 0x0c, 0x4a, 0x40, 0x6f, 0x02, 0x42, 0x40, 0x31, 0x40, 0x00, 0x10,
|
0x14, 0xbc, 0x00, 0x02, 0x0c, 0x68, 0x00, 0x01, 0x00, 0x1a, 0x66, 0x0a,
|
||||||
0x4e, 0x75, 0x4a, 0x40, 0x6f, 0x04, 0x42, 0x40, 0x4e, 0x75, 0x2f, 0x38,
|
0x4e, 0x75, 0x24, 0x7a, 0x00, 0x30, 0x14, 0xbc, 0x00, 0x03, 0x32, 0x28,
|
||||||
0x08, 0xfc, 0x4e, 0x75, 0x70, 0xe8, 0x4e, 0x75, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x06, 0x08, 0x01, 0x00, 0x09, 0x67, 0x0c, 0x4a, 0x40, 0x6f, 0x02,
|
||||||
|
0x42, 0x40, 0x31, 0x40, 0x00, 0x10, 0x4e, 0x75, 0x4a, 0x40, 0x6f, 0x04,
|
||||||
|
0x42, 0x40, 0x4e, 0x75, 0x2f, 0x38, 0x08, 0xfc, 0x4e, 0x75, 0x70, 0xe8,
|
||||||
|
0x4e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#define SONY_REF_NUM -5
|
#define SONY_REF_NUM -5
|
||||||
#define SONY_STATUS_SIZE 30
|
#define SONY_STATUS_SIZE 30
|
||||||
|
#define SONY_DRIVE_COUNT 2
|
||||||
|
|
||||||
.org 0
|
.org 0
|
||||||
.globl _start
|
.globl _start
|
||||||
|
|
@ -31,26 +32,41 @@ name:
|
||||||
.byte 5
|
.byte 5
|
||||||
.ascii ".Sony"
|
.ascii ".Sony"
|
||||||
|
|
||||||
|
accrun:
|
||||||
|
.word 0xA02F // PostEvent
|
||||||
|
move.l (faulting_address), %a3
|
||||||
|
move.b #4, (%a3) // Fault! end timeslice
|
||||||
|
|
||||||
open:
|
open:
|
||||||
// Open()
|
// Open()
|
||||||
// Allocate drive status block and pass to Open routine:
|
// Allocate drive status block and pass to Open routine:
|
||||||
movem.l %a0-%a1, -(%sp)
|
movem.l %a0-%a1, -(%sp)
|
||||||
move.b #SONY_STATUS_SIZE, %d0
|
move.b #SONY_STATUS_SIZE*SONY_DRIVE_COUNT, %d0
|
||||||
.word 0xa71e // NewPtrSysClear
|
.word 0xa71e // NewPtrSysClear
|
||||||
move.l %a0, %a2
|
move.l %a0, %a2
|
||||||
movem.l (%sp)+, %a0-%a1
|
movem.l (%sp)+, %a0-%a1
|
||||||
cmp.l #0, %a2
|
cmp.l #0, %a2
|
||||||
beq 2f // lolfail
|
beq 2f // lolfail
|
||||||
|
|
||||||
|
|
||||||
move.l (faulting_address), %a3
|
move.l (faulting_address), %a3
|
||||||
move.b #0, (%a3) // Fault! Open: op 0
|
move.b #0, (%a3) // Fault! Open: op 0
|
||||||
|
|
||||||
// FIXME: Support variable number of drives
|
// Now add the drives:
|
||||||
// Now add the drive:
|
mov.l #SONY_DRIVE_COUNT, %d3
|
||||||
move.l #(0x00010000 + (0xffff & SONY_REF_NUM)), %d0
|
add.l #6+SONY_STATUS_SIZE*(SONY_DRIVE_COUNT-1), %a2
|
||||||
|
|
||||||
|
3:
|
||||||
|
move.l %d3, %d0
|
||||||
|
swap %d0 // refnum in top half of d0, lower is 0000
|
||||||
|
ori.w #(0xffff & SONY_REF_NUM), %d0 // index & refnum in d0
|
||||||
move.l %a2, %a0
|
move.l %a2, %a0
|
||||||
add.l #6, %a0
|
|
||||||
.word 0xa04e // AddDrive
|
.word 0xa04e // AddDrive
|
||||||
|
|
||||||
|
sub.l #SONY_STATUS_SIZE, %a2 // next drive on next iteration
|
||||||
|
subq #1, %d3
|
||||||
|
bne 3b // more drives to add?
|
||||||
|
|
||||||
1: rts
|
1: rts
|
||||||
2: moveq #-23, %d0
|
2: moveq #-23, %d0
|
||||||
rts
|
rts
|
||||||
|
|
|
||||||
142
src/disc.c
142
src/disc.c
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
extern void umac_disc_ejected(void);
|
extern void umac_disc_ejected(void);
|
||||||
|
|
||||||
|
static uint8_t accrun_flag;
|
||||||
|
|
||||||
// B2 decls:
|
// B2 decls:
|
||||||
static int16_t SonyOpen(uint32_t pb, uint32_t dce, uint32_t status);
|
static int16_t SonyOpen(uint32_t pb, uint32_t dce, uint32_t status);
|
||||||
static int16_t SonyPrime(uint32_t pb, uint32_t dce);
|
static int16_t SonyPrime(uint32_t pb, uint32_t dce);
|
||||||
|
|
@ -66,6 +68,10 @@ int disc_pv_hook(uint8_t opcode)
|
||||||
DDBG("[Disc: STATUS]\n");
|
DDBG("[Disc: STATUS]\n");
|
||||||
d0 = SonyStatus(ADR24(a0), ADR24(a1));
|
d0 = SonyStatus(ADR24(a0), ADR24(a1));
|
||||||
break;
|
break;
|
||||||
|
case 4: // upcall helper
|
||||||
|
DDBG("[Disc: end timeslice]\n");
|
||||||
|
m68k_end_timeslice();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DERR("[Disc PV op %02x unhandled!]\n", opcode);
|
DERR("[Disc PV op %02x unhandled!]\n", opcode);
|
||||||
|
|
@ -162,15 +168,16 @@ static sony_drinfo_t *get_drive_info(int num)
|
||||||
|
|
||||||
void SonyInit(disc_descr_t discs[DISC_NUM_DRIVES])
|
void SonyInit(disc_descr_t discs[DISC_NUM_DRIVES])
|
||||||
{
|
{
|
||||||
drives[0].num = 0;
|
for(int i = 0; i < DISC_NUM_DRIVES; i++) {
|
||||||
drives[0].to_be_mounted = 1;
|
drives[i].num = 0; // set in SonyOpen
|
||||||
drives[0].read_only = discs[0].read_only;
|
drives[i].to_be_mounted = 1;
|
||||||
drives[0].data = discs[0].base;
|
drives[i].read_only = discs[i].read_only;
|
||||||
drives[0].size = discs[0].size;
|
drives[i].data = discs[i].base;
|
||||||
drives[0].op_ctx = discs[0].op_ctx;
|
drives[i].size = discs[i].size;
|
||||||
drives[0].op_read = discs[0].op_read;
|
drives[i].op_ctx = discs[i].op_ctx;
|
||||||
drives[0].op_write = discs[0].op_write;
|
drives[i].op_read = discs[i].op_read;
|
||||||
// FIXME: Disc 2
|
drives[i].op_write = discs[i].op_write;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -227,38 +234,44 @@ int16_t SonyOpen(uint32_t pb, uint32_t dce, uint32_t status)
|
||||||
set_dsk_err(0);
|
set_dsk_err(0);
|
||||||
|
|
||||||
// Install drives
|
// Install drives
|
||||||
//for (int drnum = 0; drnum < NUM_DRIVES; drnum++) {
|
int free_drive_number = 1;
|
||||||
const int drnum = 0;
|
for (int drnum = 0; drnum < DISC_NUM_DRIVES; drnum++) {
|
||||||
sony_drinfo_t *info = &drives[drnum];
|
sony_drinfo_t *info = &drives[drnum];
|
||||||
|
|
||||||
info->num = FindFreeDriveNumber(1); // ? 1 for internal, 2 for external
|
info->num = FindFreeDriveNumber(free_drive_number); // ? 1 for internal, 2 for external
|
||||||
info->to_be_mounted = 0;
|
free_drive_number = info->num + 1;
|
||||||
|
info->to_be_mounted = 0;
|
||||||
|
|
||||||
// Original code allocated drive status record here (invoked
|
// Original code allocated drive status record here (invoked
|
||||||
// trap to NewPtrSysClear), but our driver does this instead
|
// trap to NewPtrSysClear), but our driver does this instead
|
||||||
// (it's passed in via status parameter), to avoid having to
|
// (it's passed in via status parameter), to avoid having to
|
||||||
// implement invocation of 68K traps/upcalls from sim env.
|
// implement invocation of 68K traps/upcalls from sim env.
|
||||||
info->status = status;
|
info->status = status + 30 * drnum;
|
||||||
DDBG(" DrvSts at %08x\n", info->status);
|
DDBG(" DrvSts at %08x gets drnum %d num %d\n", info->status, drnum, info->num);
|
||||||
|
|
||||||
// Set up drive status
|
// Set up drive status
|
||||||
// ME: do 800K, double sided (see IM)
|
// ME: do 800K, double sided (see IM)
|
||||||
WriteMacInt16(info->status + dsQType, sony);
|
WriteMacInt16(info->status + dsQType, sony);
|
||||||
WriteMacInt8(info->status + dsInstalled, 1);
|
WriteMacInt8(info->status + dsInstalled, 1);
|
||||||
WriteMacInt8(info->status + dsSides, 0xff); // 2 sides
|
WriteMacInt8(info->status + dsSides, 0xff); // 2 sides
|
||||||
WriteMacInt8(info->status + dsTwoSideFmt, 0xff); //
|
WriteMacInt8(info->status + dsTwoSideFmt, 0xff); //
|
||||||
//WriteMacInt8(info->status + dsNewIntf, 0xff);
|
//WriteMacInt8(info->status + dsNewIntf, 0xff);
|
||||||
WriteMacInt8(info->status + dsMFMDrive, 0); // 0 = 400/800K GCR drive)
|
WriteMacInt8(info->status + dsMFMDrive, 0); // 0 = 400/800K GCR drive)
|
||||||
WriteMacInt8(info->status + dsMFMDisk, 0);
|
WriteMacInt8(info->status + dsMFMDisk, 0);
|
||||||
//WriteMacInt8(info->status + dsTwoMegFmt, 0xff); // 1.44MB (0 = 720K)
|
//WriteMacInt8(info->status + dsTwoMegFmt, 0xff); // 1.44MB (0 = 720K)
|
||||||
|
|
||||||
// If disk in drive...
|
// If disk in drive...
|
||||||
WriteMacInt8(info->status + dsDiskInPlace, 1); // Inserted removable disk
|
if (info->size) {
|
||||||
WriteMacInt8(info->status + dsWriteProt, info->read_only ? 0xff : 0);
|
if (drnum == 0)
|
||||||
DDBG(" disk inserted, flagging for mount\n");
|
WriteMacInt8(info->status + dsDiskInPlace, 1); // Inserted removable disk
|
||||||
info->to_be_mounted = 1;
|
else
|
||||||
|
info->to_be_mounted = 1;
|
||||||
|
WriteMacInt8(info->status + dsWriteProt, info->read_only ? 0xff : 0);
|
||||||
|
DDBG(" disk inserted, flagging for mount\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Original code ddded drive to drive queue here (invoked trap
|
// Original code added drive to drive queue here (invoked trap
|
||||||
// to AddDrive), but our driver does this after this PV call returns.
|
// to AddDrive), but our driver does this after this PV call returns.
|
||||||
// FIXME: In future return a bitmap of drives to add.
|
// FIXME: In future return a bitmap of drives to add.
|
||||||
(void)pb;
|
(void)pb;
|
||||||
|
|
@ -369,14 +382,8 @@ int16_t SonyControl(uint32_t pb, uint32_t dce)
|
||||||
return set_dsk_err(noErr);
|
return set_dsk_err(noErr);
|
||||||
|
|
||||||
case 65: { // Periodic action (accRun, "insert" disks on startup)
|
case 65: { // Periodic action (accRun, "insert" disks on startup)
|
||||||
static int complained_yet = 0;
|
accrun_flag = 1;
|
||||||
if (!complained_yet) {
|
return set_dsk_err(noErr);
|
||||||
DERR("SonyControl:accRun: Not supported!\n");
|
|
||||||
complained_yet = 1;
|
|
||||||
}
|
|
||||||
// The original emulation code hooked this to mount_mountable_volumes,
|
|
||||||
// which called back to PostEvent(diskEvent).
|
|
||||||
return set_dsk_err(-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -411,7 +418,8 @@ int16_t SonyControl(uint32_t pb, uint32_t dce)
|
||||||
// SysEject(info->fh);
|
// SysEject(info->fh);
|
||||||
WriteMacInt8(info->status + dsDiskInPlace, 0);
|
WriteMacInt8(info->status + dsDiskInPlace, 0);
|
||||||
|
|
||||||
umac_disc_ejected();
|
if(info->num == 1)
|
||||||
|
umac_disc_ejected();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -534,3 +542,47 @@ int16_t SonyStatus(uint32_t pb, uint32_t dce)
|
||||||
|
|
||||||
return set_dsk_err(err);
|
return set_dsk_err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define M68K_REG_LAST (M68K_REG_CPU_TYPE)
|
||||||
|
|
||||||
|
static int PostEvent(int type, int num) {
|
||||||
|
DDBG("PostEvent EventCode=%d EventMsg=%d\n", type, num);
|
||||||
|
uint32_t regs[M68K_REG_LAST];
|
||||||
|
for(int i=0; i<M68K_REG_LAST; i++)
|
||||||
|
regs[i] = m68k_get_reg(NULL, i);
|
||||||
|
m68k_set_reg(M68K_REG_D0, num);
|
||||||
|
m68k_set_reg(M68K_REG_A0, type);
|
||||||
|
uint32_t new_sp = regs[M68K_REG_SP] - 4;
|
||||||
|
cpu_write_word(new_sp, 0xA02F); // PostEvent
|
||||||
|
cpu_write_word(new_sp+2, 0x7180); // emul_ret
|
||||||
|
m68k_set_reg(M68K_REG_PC, new_sp); // PostEvent
|
||||||
|
m68k_set_reg(M68K_REG_SP, new_sp); // Emul_Ret
|
||||||
|
int used = m68k_execute(80000);
|
||||||
|
int result = m68k_get_reg(NULL, M68K_REG_D0);
|
||||||
|
if (used >= 20000 || m68k_get_reg(NULL, M68K_REG_PC) != new_sp + 4 ||
|
||||||
|
m68k_get_reg(NULL, M68K_REG_SP) != new_sp) {
|
||||||
|
DERR("trap call didn't seem to work. used=%d PC=%08x (expected %08x) SP=%08x (expected %08x)\n",
|
||||||
|
used,
|
||||||
|
m68k_get_reg(NULL, M68K_REG_PC), new_sp+4,
|
||||||
|
m68k_get_reg(NULL, M68K_REG_SP), new_sp);
|
||||||
|
result = 1; // some kind of failure (but you're probably doomed)
|
||||||
|
}
|
||||||
|
for(int i=0; i<M68K_REG_LAST; i++)
|
||||||
|
m68k_set_reg(i, regs[i]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disc_tick() {
|
||||||
|
if (!accrun_flag) return;
|
||||||
|
accrun_flag = 0;
|
||||||
|
for (int i = 0; i < DISC_NUM_DRIVES; i++) {
|
||||||
|
sony_drinfo_t *info = &drives[i];
|
||||||
|
if (drives[i].to_be_mounted) {
|
||||||
|
int inPlace = ReadMacInt8(info->status + dsDiskInPlace); // Inserted removable disk
|
||||||
|
if (inPlace || PostEvent(7, drives[i].num) == 0) {
|
||||||
|
drives[i].to_be_mounted = 0;
|
||||||
|
WriteMacInt8(info->status + dsDiskInPlace, 1); // Inserted removable disk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -712,6 +712,7 @@ int umac_loop(void)
|
||||||
// Device polling
|
// Device polling
|
||||||
via_tick(global_time_us);
|
via_tick(global_time_us);
|
||||||
mouse_tick();
|
mouse_tick();
|
||||||
|
disc_tick();
|
||||||
kbd_check_work();
|
kbd_check_work();
|
||||||
|
|
||||||
return sim_done;
|
return sim_done;
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ static void print_help(char *n)
|
||||||
printf("Syntax: %s <options>\n"
|
printf("Syntax: %s <options>\n"
|
||||||
"\t-r <rom path>\t\tDefault 'rom.bin'\n"
|
"\t-r <rom path>\t\tDefault 'rom.bin'\n"
|
||||||
"\t-W <rom dump path>\tDump ROM after patching\n"
|
"\t-W <rom dump path>\tDump ROM after patching\n"
|
||||||
"\t-d <disc path>\n"
|
"\t-d <disc path> (may be repeated)\n"
|
||||||
"\t-w\t\t\tEnable persistent disc writes (default R/O)\n"
|
"\t-w\t\t\tEnable persistent disc writes (default R/O)\n"
|
||||||
"\t-i\t\t\tDisassembled instruction trace\n", n);
|
"\t-i\t\t\tDisassembled instruction trace\n", n);
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +78,44 @@ static void copy_fb(uint32_t *fb_out, uint8_t *fb_in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int open_disc(disc_descr_t *desc, int slot, int opt_write, const char *disc_filename) {
|
||||||
|
int ofd;
|
||||||
|
void *disc_base;
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
printf("Opening disc '%s'\n", disc_filename);
|
||||||
|
// FIXME: >1 disc
|
||||||
|
ofd = open(disc_filename, opt_write ? O_RDWR : O_RDONLY);
|
||||||
|
if (ofd < 0) {
|
||||||
|
perror("Disc");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fstat(ofd, &sb);
|
||||||
|
size_t disc_size = sb.st_size;
|
||||||
|
|
||||||
|
/* Discs are always _writable_ from the perspective of
|
||||||
|
* the Mac, but by default data is a MAP_PRIVATE copy
|
||||||
|
* and is not synchronised to the backing file. If
|
||||||
|
* opt_write, we use MAP_SHARED and open the file RW,
|
||||||
|
* so writes persist to the disc image.
|
||||||
|
*/
|
||||||
|
disc_base = mmap(0, disc_size, PROT_READ | PROT_WRITE,
|
||||||
|
opt_write ? MAP_SHARED : MAP_PRIVATE,
|
||||||
|
ofd, 0);
|
||||||
|
if (disc_base == MAP_FAILED) {
|
||||||
|
printf("Can't mmap disc!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("Disc mapped at %p, slot %d, size %ld\n", (void *)disc_base, slot, disc_size);
|
||||||
|
|
||||||
|
desc->base = disc_base;
|
||||||
|
desc->read_only = 0; /* See above */
|
||||||
|
desc->size = disc_size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
/* The emulator core expects to be given ROM and RAM pointers,
|
/* The emulator core expects to be given ROM and RAM pointers,
|
||||||
|
|
@ -91,11 +129,9 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
void *ram_base;
|
void *ram_base;
|
||||||
void *rom_base;
|
void *rom_base;
|
||||||
void *disc_base;
|
|
||||||
char *rom_filename = "rom.bin";
|
char *rom_filename = "rom.bin";
|
||||||
char *rom_dump_filename = NULL;
|
char *rom_dump_filename = NULL;
|
||||||
char *ram_filename = "ram.bin";
|
char *ram_filename = "ram.bin";
|
||||||
char *disc_filename = NULL;
|
|
||||||
int ofd;
|
int ofd;
|
||||||
int ch;
|
int ch;
|
||||||
int opt_disassemble = 0;
|
int opt_disassemble = 0;
|
||||||
|
|
@ -104,6 +140,9 @@ int main(int argc, char *argv[])
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Args
|
// Args
|
||||||
|
|
||||||
|
disc_descr_t discs[DISC_NUM_DRIVES] = {0};
|
||||||
|
size_t disc_num = 0;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "r:d:W:ihw")) != -1) {
|
while ((ch = getopt(argc, argv, "r:d:W:ihw")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'r':
|
case 'r':
|
||||||
|
|
@ -115,7 +154,19 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
disc_filename = strdup(optarg);
|
if (disc_num < DISC_NUM_DRIVES) {
|
||||||
|
if (open_disc(&discs[disc_num], disc_num, opt_write, optarg) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
disc_num ++;
|
||||||
|
} else {
|
||||||
|
printf("Too many discs\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'R':
|
||||||
|
opt_write = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w':
|
case 'w':
|
||||||
|
|
@ -192,40 +243,6 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
printf("RAM mapped at %p\n", (void *)ram_base);
|
printf("RAM mapped at %p\n", (void *)ram_base);
|
||||||
|
|
||||||
disc_descr_t discs[DISC_NUM_DRIVES] = {0};
|
|
||||||
|
|
||||||
if (disc_filename) {
|
|
||||||
printf("Opening disc '%s'\n", disc_filename);
|
|
||||||
// FIXME: >1 disc
|
|
||||||
ofd = open(disc_filename, opt_write ? O_RDWR : O_RDONLY);
|
|
||||||
if (ofd < 0) {
|
|
||||||
perror("Disc");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fstat(ofd, &sb);
|
|
||||||
size_t disc_size = sb.st_size;
|
|
||||||
|
|
||||||
/* Discs are always _writable_ from the perspective of
|
|
||||||
* the Mac, but by default data is a MAP_PRIVATE copy
|
|
||||||
* and is not synchronised to the backing file. If
|
|
||||||
* opt_write, we use MAP_SHARED and open the file RW,
|
|
||||||
* so writes persist to the disc image.
|
|
||||||
*/
|
|
||||||
disc_base = mmap(0, disc_size, PROT_READ | PROT_WRITE,
|
|
||||||
opt_write ? MAP_SHARED : MAP_PRIVATE,
|
|
||||||
ofd, 0);
|
|
||||||
if (disc_base == MAP_FAILED) {
|
|
||||||
printf("Can't mmap disc!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("Disc mapped at %p, size %ld\n", (void *)disc_base, disc_size);
|
|
||||||
|
|
||||||
discs[0].base = disc_base;
|
|
||||||
discs[0].read_only = 0; /* See above */
|
|
||||||
discs[0].size = disc_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// SDL/UI init
|
// SDL/UI init
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue