Updates
This commit is contained in:
608
common/emumz.c
608
common/emumz.c
@@ -17,6 +17,8 @@
|
||||
// v1.1 Nov 2021 - Further work on Video Controller and infrastructure.
|
||||
// v1.2 Nov 2021 - Adding MZ2000 logic.
|
||||
// v1.3 Dec 2021 - Adding MZ800 logic.
|
||||
// v1.4 Jan 2022 - Adding floppy disk support.
|
||||
// v1.5 Mar 2022 - Consolidation and bug rectification.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -80,8 +82,8 @@ extern "C" {
|
||||
#define debugfx(a, ...) if(emuControl.debug) { printf("\033[1;32m%s: " a "\033[0m\n", __func__, ##__VA_ARGS__); }
|
||||
|
||||
// Version data.
|
||||
#define EMUMZ_VERSION 1.45
|
||||
#define EMUMZ_VERSION_DATE "26/01/2022"
|
||||
#define EMUMZ_VERSION 1.50
|
||||
#define EMUMZ_VERSION_DATE "16/03/2022"
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Sharp MZ Series Emulation Service Methods //
|
||||
@@ -1262,7 +1264,6 @@ void EMZNextDisplayType(enum ACTIONMODE mode)
|
||||
// Move to the next valid entry, looping round as necessary.
|
||||
do {
|
||||
emuConfig.params[emuConfig.machineModel].displayType = (emuConfig.params[emuConfig.machineModel].displayType+1 >= NUMELEM(SHARPMZ_DISPLAY_TYPE[emuConfig.machineModel]) ? 0 : emuConfig.params[emuConfig.machineModel].displayType+1);
|
||||
printf("%d\n", emuConfig.params[emuConfig.machineModel].displayType);
|
||||
} while(SHARPMZ_DISPLAY_TYPE[emuConfig.machineModel][emuConfig.params[emuConfig.machineModel].displayType] == NULL);
|
||||
}
|
||||
return;
|
||||
@@ -2061,7 +2062,6 @@ void EMZNextMonitorROM40(enum ACTIONMODE mode)
|
||||
if(mode == ACTION_DEFAULT || mode == ACTION_TOGGLECHOICE)
|
||||
{
|
||||
emuConfig.params[emuConfig.machineModel].romMonitor40.romEnabled = (emuConfig.params[emuConfig.machineModel].romMonitor40.romEnabled == 1 ? 0 : 1);
|
||||
printf("romEnabled=%d\n", emuConfig.params[emuConfig.machineModel].romMonitor40.romEnabled );
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -5640,317 +5640,331 @@ void EMZservice(uint8_t interrupt)
|
||||
// Has an interrupt been generated by the emulator support hardware?
|
||||
if(interrupt)
|
||||
{
|
||||
// Read the reason code register.
|
||||
// Take out a Lock on the Z80 bus - this is needed as a number of small operations are performed on the Z80/FPGA during an interrupt cycle and it adds overhead to wait for a Z80 request approval on each occasion.
|
||||
//
|
||||
result=readZ80Array(MZ_EMU_REG_INTR_ADDR, emuISRReason, MZ_EMU_INTR_MAX_REGISTERS, FPGA);
|
||||
printf("IntrReg:"); for(uint16_t idx=0; idx < MZ_EMU_INTR_MAX_REGISTERS; idx++) { printf("%02x ", emuISRReason[idx]); } printf("\n");
|
||||
if(!result)
|
||||
if(lockZ80() == 0)
|
||||
{
|
||||
// Keyboard interrupt?
|
||||
if(emuISRReason[MZ_EMU_INTR_REG_ISR] & MZ_EMU_INTR_SRC_KEYB)
|
||||
// Read the reason code register.
|
||||
//
|
||||
result=readZ80Array(MZ_EMU_REG_INTR_ADDR, emuISRReason, MZ_EMU_INTR_MAX_REGISTERS, FPGA);
|
||||
printf("IntrReg:"); for(uint16_t idx=0; idx < MZ_EMU_INTR_MAX_REGISTERS; idx++) { printf("%02x ", emuISRReason[idx]); } printf("\n");
|
||||
if(!result)
|
||||
{
|
||||
// Read the key pressed.
|
||||
result=readZ80Array(MZ_EMU_REG_KEYB_ADDR+MZ_EMU_KEYB_CTRL_REG, &emuInData[MZ_EMU_KEYB_CTRL_REG], MZ_EMU_KEYB_MAX_REGISTERS, FPGA);
|
||||
printf("KeyReg:"); for(uint16_t idx=MZ_EMU_KEYB_CTRL_REG; idx < MZ_EMU_KEYB_CTRL_REG+MZ_EMU_KEYB_MAX_REGISTERS; idx++) { printf("%02x ", emuInData[idx]); } printf("\n");
|
||||
if(!result)
|
||||
// Keyboard interrupt?
|
||||
if(emuISRReason[MZ_EMU_INTR_REG_ISR] & MZ_EMU_INTR_SRC_KEYB)
|
||||
{
|
||||
printf("Received key:%02x, %02x, %d, %d (%d,%d)\n", emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG], emuInData[MZ_EMU_KEYB_KEY_POS_REG], emuInData[MZ_EMU_KEYB_KEY_POS_LAST_REG], emuInData[MZ_EMU_KEYB_FIFO_WR_ADDR], emuInData[MZ_EMU_KEYB_FIFO_RD_ADDR]);
|
||||
|
||||
// Not interested in up key events or control events except for CTRL+BREAK, discard.
|
||||
if(emuInData[MZ_EMU_KEYB_KEYC_REG] & KEY_DOWN_BIT)
|
||||
// Read the key pressed.
|
||||
result=readZ80Array(MZ_EMU_REG_KEYB_ADDR+MZ_EMU_KEYB_CTRL_REG, &emuInData[MZ_EMU_KEYB_CTRL_REG], MZ_EMU_KEYB_MAX_REGISTERS, FPGA);
|
||||
printf("KeyReg:"); for(uint16_t idx=MZ_EMU_KEYB_CTRL_REG; idx < MZ_EMU_KEYB_CTRL_REG+MZ_EMU_KEYB_MAX_REGISTERS; idx++) { printf("%02x ", emuInData[idx]); } printf("\n");
|
||||
if(!result)
|
||||
{
|
||||
// First time the menu key has been pressed, pop up the menu and redirect all key input to the I/O processor.
|
||||
if(emuControl.activeMenu.menu[0] == MENU_DISABLED && emuInData[MZ_EMU_KEYB_KEYD_REG] == 0xFE)
|
||||
printf("Received key:%02x, %02x, %d, %d (%d,%d)\n", emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG], emuInData[MZ_EMU_KEYB_KEY_POS_REG], emuInData[MZ_EMU_KEYB_KEY_POS_LAST_REG], emuInData[MZ_EMU_KEYB_FIFO_WR_ADDR], emuInData[MZ_EMU_KEYB_FIFO_RD_ADDR]);
|
||||
|
||||
// Not interested in up key events or control events except for CTRL+BREAK, discard.
|
||||
if(emuInData[MZ_EMU_KEYB_KEYC_REG] & KEY_DOWN_BIT)
|
||||
{
|
||||
// Recheck OSD parameters - the running machine may change resolution which in turn changes the OSD settings.
|
||||
OSDUpdateScreenSize();
|
||||
|
||||
// Setup Menu Font according to available X pixels. Original screen formats only have 320 pixel width.
|
||||
if((uint16_t)OSDGet(ACTIVE_MAX_X) < 512)
|
||||
// First time the menu key has been pressed, pop up the menu and redirect all key input to the I/O processor.
|
||||
if(emuControl.activeMenu.menu[0] == MENU_DISABLED && emuInData[MZ_EMU_KEYB_KEYD_REG] == 0xFE)
|
||||
{
|
||||
EMZSetMenuFont(FONT_5X7);
|
||||
// Recheck OSD parameters - the running machine may change resolution which in turn changes the OSD settings.
|
||||
OSDUpdateScreenSize();
|
||||
|
||||
// Setup Menu Font according to available X pixels. Original screen formats only have 320 pixel width.
|
||||
if((uint16_t)OSDGet(ACTIVE_MAX_X) < 512)
|
||||
{
|
||||
EMZSetMenuFont(FONT_5X7);
|
||||
} else
|
||||
{
|
||||
EMZSetMenuFont(FONT_7X8);
|
||||
}
|
||||
|
||||
// Disable keyboard scan being sent to emulation, enable interrupts on each key press.
|
||||
emuOutData[MZ_EMU_KEYB_CTRL_REG] = MZ_EMU_KEYB_DISABLE_EMU | MZ_EMU_KEYB_ENABLE_INTR;
|
||||
writeZ80Array(MZ_EMU_REG_KEYB_ADDR+MZ_EMU_KEYB_CTRL_REG, &emuOutData[MZ_EMU_KEYB_CTRL_REG], 1, FPGA);
|
||||
emuControl.activeMenu.menuIdx = 0;
|
||||
emuControl.activeMenu.menu[emuControl.activeMenu.menuIdx] = MENU_MAIN;
|
||||
|
||||
// Draw the initial main menu.
|
||||
EMZMainMenu();
|
||||
OSDRefreshScreen();
|
||||
|
||||
// Enable the OSD.
|
||||
emuOutData[0] = 0x40 | emuConfig.params[emuConfig.machineModel].displayOutput;
|
||||
emuConfig.emuRegisters[MZ_EMU_REG_DISPLAY2] = emuConfig.emuRegisters[MZ_EMU_REG_DISPLAY2] | 0x40;
|
||||
writeZ80Array(MZ_EMU_ADDR_REG_DISPLAY2, emuOutData, 1, FPGA);
|
||||
|
||||
// Menu active and user has requested to return to emulation?
|
||||
}
|
||||
else if(emuControl.activeMenu.menu[emuControl.activeMenu.menuIdx] != MENU_DISABLED && emuInData[MZ_EMU_KEYB_KEYD_REG] == 0xFE)
|
||||
{
|
||||
// Enable keyboard scan being sent to emulation, disable interrupts on each key press.
|
||||
emuOutData[MZ_EMU_KEYB_CTRL_REG] = 0;
|
||||
writeZ80Array(MZ_EMU_REG_KEYB_ADDR+MZ_EMU_KEYB_CTRL_REG, &emuOutData[MZ_EMU_KEYB_CTRL_REG], 1, FPGA);
|
||||
emuControl.activeMenu.menuIdx = 0;
|
||||
emuControl.activeMenu.menu[emuControl.activeMenu.menuIdx] = MENU_DISABLED;
|
||||
|
||||
// Release any allocated menu or file list memory as next invocation restarts at the main menu.
|
||||
EMZReleaseDirMemory();
|
||||
EMZReleaseMenuMemory();
|
||||
|
||||
// Disable the OSD cursor.
|
||||
OSDClearCursorFlash();
|
||||
|
||||
// Disable the OSD, this is done by updating the local register copy as the final act is to upload the latest configuration, OSD mode included.
|
||||
emuConfig.emuRegisters[MZ_EMU_REG_DISPLAY2] = emuConfig.emuRegisters[MZ_EMU_REG_DISPLAY2] & 0xbf;
|
||||
//emuOutData[0] = 0x0;
|
||||
//writeZ80Array(MZ_EMU_ADDR_REG_DISPLAY3, emuOutData, 1, FPGA);
|
||||
|
||||
// Switch to the requested machine if changed, update the configuration in the FPGA.
|
||||
//
|
||||
if(emuConfig.machineChanged)
|
||||
{
|
||||
EMZRun();
|
||||
} else
|
||||
{
|
||||
EMZSwitchToMachine(emuConfig.machineModel, 0);
|
||||
}
|
||||
|
||||
// Direct key intercept, process according to state.
|
||||
} else
|
||||
{
|
||||
EMZSetMenuFont(FONT_7X8);
|
||||
}
|
||||
|
||||
// Disable keyboard scan being sent to emulation, enable interrupts on each key press.
|
||||
emuOutData[MZ_EMU_KEYB_CTRL_REG] = MZ_EMU_KEYB_DISABLE_EMU | MZ_EMU_KEYB_ENABLE_INTR;
|
||||
writeZ80Array(MZ_EMU_REG_KEYB_ADDR+MZ_EMU_KEYB_CTRL_REG, &emuOutData[MZ_EMU_KEYB_CTRL_REG], 1, FPGA);
|
||||
emuControl.activeMenu.menuIdx = 0;
|
||||
emuControl.activeMenu.menu[emuControl.activeMenu.menuIdx] = MENU_MAIN;
|
||||
|
||||
// Draw the initial main menu.
|
||||
EMZMainMenu();
|
||||
OSDRefreshScreen();
|
||||
|
||||
// Enable the OSD.
|
||||
emuOutData[0] = 0x40 | emuConfig.params[emuConfig.machineModel].displayOutput;
|
||||
emuConfig.emuRegisters[MZ_EMU_REG_DISPLAY2] = emuConfig.emuRegisters[MZ_EMU_REG_DISPLAY2] | 0x40;
|
||||
writeZ80Array(MZ_EMU_ADDR_REG_DISPLAY2, emuOutData, 1, FPGA);
|
||||
|
||||
// Menu active and user has requested to return to emulation?
|
||||
}
|
||||
else if(emuControl.activeMenu.menu[emuControl.activeMenu.menuIdx] != MENU_DISABLED && emuInData[MZ_EMU_KEYB_KEYD_REG] == 0xFE)
|
||||
{
|
||||
// Enable keyboard scan being sent to emulation, disable interrupts on each key press.
|
||||
emuOutData[MZ_EMU_KEYB_CTRL_REG] = 0;
|
||||
writeZ80Array(MZ_EMU_REG_KEYB_ADDR+MZ_EMU_KEYB_CTRL_REG, &emuOutData[MZ_EMU_KEYB_CTRL_REG], 1, FPGA);
|
||||
emuControl.activeMenu.menuIdx = 0;
|
||||
emuControl.activeMenu.menu[emuControl.activeMenu.menuIdx] = MENU_DISABLED;
|
||||
|
||||
// Release any allocated menu or file list memory as next invocation restarts at the main menu.
|
||||
EMZReleaseDirMemory();
|
||||
EMZReleaseMenuMemory();
|
||||
|
||||
// Disable the OSD cursor.
|
||||
OSDClearCursorFlash();
|
||||
|
||||
// Disable the OSD, this is done by updating the local register copy as the final act is to upload the latest configuration, OSD mode included.
|
||||
emuConfig.emuRegisters[MZ_EMU_REG_DISPLAY2] = emuConfig.emuRegisters[MZ_EMU_REG_DISPLAY2] & 0xbf;
|
||||
//emuOutData[0] = 0x0;
|
||||
//writeZ80Array(MZ_EMU_ADDR_REG_DISPLAY3, emuOutData, 1, FPGA);
|
||||
|
||||
// Switch to the requested machine if changed, update the configuration in the FPGA.
|
||||
//
|
||||
if(emuConfig.machineChanged)
|
||||
{
|
||||
EMZRun();
|
||||
} else
|
||||
{
|
||||
EMZSwitchToMachine(emuConfig.machineModel, 0);
|
||||
}
|
||||
|
||||
// Direct key intercept, process according to state.
|
||||
} else
|
||||
{
|
||||
// Event driven key processing
|
||||
switch(emuControl.activeDialog)
|
||||
{
|
||||
case DIALOG_FILELIST:
|
||||
EMZProcessFileListKey(emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG]);
|
||||
break;
|
||||
|
||||
case DIALOG_KEYENTRY:
|
||||
EMZKeyInjectionEdit(emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG]);
|
||||
break;
|
||||
|
||||
case DIALOG_MENU:
|
||||
default:
|
||||
EMZProcessMenuKey(emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG]);
|
||||
//EMZProcessMenuKeyDebug(emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG]);
|
||||
break;
|
||||
// Event driven key processing
|
||||
switch(emuControl.activeDialog)
|
||||
{
|
||||
case DIALOG_FILELIST:
|
||||
EMZProcessFileListKey(emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG]);
|
||||
break;
|
||||
|
||||
case DIALOG_KEYENTRY:
|
||||
EMZKeyInjectionEdit(emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG]);
|
||||
break;
|
||||
|
||||
case DIALOG_MENU:
|
||||
default:
|
||||
EMZProcessMenuKey(emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG]);
|
||||
//EMZProcessMenuKeyDebug(emuInData[MZ_EMU_KEYB_KEYD_REG], emuInData[MZ_EMU_KEYB_KEYC_REG]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
printf("Key retrieval error.\n");
|
||||
}
|
||||
} else
|
||||
{
|
||||
printf("Key retrieval error.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// CMT generated an interrupt?
|
||||
if(emuISRReason[MZ_EMU_INTR_REG_ISR] & MZ_EMU_INTR_SRC_CMT)
|
||||
|
||||
// CMT generated an interrupt?
|
||||
if(emuISRReason[MZ_EMU_INTR_REG_ISR] & MZ_EMU_INTR_SRC_CMT)
|
||||
{
|
||||
// Read the cmt status directly. This data can also be ready from the Master Control register of the emulator.
|
||||
result=readZ80Array(MZ_EMU_CMT_REG_ADDR, emuInData, MZ_EMU_CMT_MAX_REGISTERS, FPGA);
|
||||
|
||||
// Update the local copy.
|
||||
emuConfig.emuRegisters[MZ_EMU_REG_CMT3] = emuInData[MZ_EMU_CMT_STATUS_INTR_REG];
|
||||
emuConfig.emuRegisters[MZ_EMU_REG_CMT2] = emuInData[MZ_EMU_CMT_STATUS2_INTR_REG];
|
||||
|
||||
// When debugging output register change as text message.
|
||||
debugf("CMT/CMT2 (%02x,%02x,%s%s%s%s%s%s:%s%s%s%s%s).",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG], emuInData[MZ_EMU_CMT_STATUS2_REG],
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_PLAY_READY ? "PLAY_READY," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_PLAYING ? "PLAYING," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_RECORD_READY ? "RECORD_READY,": "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_RECORDING ? "RECORDING," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_ACTIVE ? "ACTIVE," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_SENSE ? "SENSE," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_APSS ? "APSS," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_APSS ? emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_DIRECTION ? "FFWD," : "REW," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_EJECT ? "EJECT," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_PLAY ? "PLAY," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_STOP ? "STOP," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_AUTOREW ? "AUTOREW," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_AUTOPLAY ? "AUTOPLAY" : "");
|
||||
|
||||
debugf("CMT/CMT2i(%02x,%02x,%s%s%s%s%s%s:%s%s%s%s%s).",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG], emuInData[MZ_EMU_CMT_STATUS2_INTR_REG],
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_PLAY_READY ? "PLAY_READY," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_PLAYING ? "PLAYING," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_RECORD_READY ? "RECORD_READY,": "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_RECORDING ? "RECORDING," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_ACTIVE ? "ACTIVE," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_SENSE ? "SENSE," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_APSS ? "APSS," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_APSS ? emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_DIRECTION ? "FFWD," : "REW," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_EJECT ? "EJECT," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_PLAY ? "PLAY," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_STOP ? "STOP," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_AUTOREW ? "AUTOREW," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_AUTOPLAY ? "AUTOPLAY" : "");
|
||||
|
||||
// Process the tape queue according to signals received from the hardware.
|
||||
EMZProcessTapeQueue(1);
|
||||
}
|
||||
|
||||
// Floppy Disk Drive unit interrupt?
|
||||
if(emuISRReason[MZ_EMU_INTR_REG_ISR] & MZ_EMU_INTR_SRC_FDD)
|
||||
{
|
||||
|
||||
// Read the control data to allow a decision as to what is required.
|
||||
result=readZ80Array(MZ_EMU_FDD_CTRL_ADDR, emuInData, MZ_EMU_FDD_MAX_REGISTERS, FPGA);
|
||||
|
||||
// Debug information to evaluate interrupt.
|
||||
result=readZ80Array(MZ_EMU_FDC_CTRL_ADDR, &emuInData[MZ_EMU_FDD_MAX_REGISTERS], 32, FPGA); //MZ_EMU_FDC_MAX_REGISTERS, FPGA);
|
||||
debugf("FDD: (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)",
|
||||
emuInData[MZ_EMU_FDD_CTRL_REG],
|
||||
emuInData[MZ_EMU_FDD_SECTOR_REG],
|
||||
emuInData[MZ_EMU_FDD_TRACK_REG],
|
||||
emuInData[MZ_EMU_FDD_CST_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_TRACK_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_SECTOR_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_DATA_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_LCMD_REG]);
|
||||
|
||||
debugf("FDD IOP: Drive No:%d, Head:%s, Request:%s, Command: %s, Sector:%d, Track:%d",
|
||||
((emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_DISK_SELECT_NO) >> 5) & 0x03,
|
||||
emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_SIDE ? "1" : "0",
|
||||
emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_SERVICE_REQ ? "YES " : "NO",
|
||||
(emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_REQ_MODE) == 0 ? "NOP" : (emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_REQ_MODE) == 1 ? "READ" : (emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_REQ_MODE) == 2 ? "WRITE" : "INFO",
|
||||
emuInData[MZ_EMU_FDD_SECTOR_REG],
|
||||
emuInData[MZ_EMU_FDD_TRACK_REG]);
|
||||
debugf(" FDD Signals:(%s%s%s%s) Raw Drive Select:(%d)",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_BUSY ? "BUSY," : "",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_DRQ ? "DRQ," : "",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_DDEN ? "" : "DDEN,",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_MOTORON ? "" : "MOTOR",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_SELECT_NO);
|
||||
|
||||
cmdSvc = 0;
|
||||
switch(emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_LCMD_REG] & 0xF0)
|
||||
{
|
||||
case FDC_CMD_RESTORE:
|
||||
cmdStr = "RESTORE";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_SEEK:
|
||||
cmdStr = "SEEK";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEP:
|
||||
cmdStr = "STEP";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEP_TU:
|
||||
cmdStr = "STEP TU";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEP_IN:
|
||||
cmdStr = "STEPIN";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEPIN_TU:
|
||||
cmdStr = "STEPIN TU";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEPOUT:
|
||||
cmdStr = "STEPOUT";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEPOUT_TU:
|
||||
cmdStr = "STEPOUT TU";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_READSEC:
|
||||
cmdStr = "READSEC";
|
||||
cmdSvc = 1;
|
||||
cmdType = 2;
|
||||
break;
|
||||
case FDC_CMD_READSEC_MULT:
|
||||
cmdStr = "READSEC MULT";
|
||||
cmdSvc = 1;
|
||||
cmdType = 2;
|
||||
break;
|
||||
case FDC_CMD_WRITESEC:
|
||||
cmdStr = "WRITESEC";
|
||||
cmdSvc = 1;
|
||||
cmdType = 2;
|
||||
break;
|
||||
case FDC_CMD_WRITESEC_MULT:
|
||||
cmdStr = "WRITESEC MULT";
|
||||
cmdSvc = 1;
|
||||
cmdType = 2;
|
||||
break;
|
||||
case FDC_CMD_READADDR:
|
||||
cmdStr = "READADDR";
|
||||
cmdSvc = 1;
|
||||
cmdType = 3;
|
||||
break;
|
||||
case FDC_CMD_READTRACK:
|
||||
cmdStr = "READTRACK";
|
||||
cmdSvc = 1;
|
||||
cmdType = 3;
|
||||
break;
|
||||
case FDC_CMD_WRITETRACK:
|
||||
cmdStr = "WRITETRACK";
|
||||
cmdSvc = 1;
|
||||
cmdType = 3;
|
||||
break;
|
||||
case FDC_CMD_FORCEINT:
|
||||
cmdStr = "FORCEINT";
|
||||
cmdType = 4;
|
||||
break;
|
||||
}
|
||||
debugf(" WD1793 Signals:(%s%s%s%s%s%s%s%s%s[%02x,%d])",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_NOTRDY ? "NOTRDY," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_PROTECTED ? "PROTECTED," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_HEADLOADED ? cmdType != 1 ? "RTYPE/WFAULT," : "HEADLOADED," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_SEEKERROR ? cmdType != 1 ? "RNF," : "SEEKERROR," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_CRCERROR ? "CRCERROR," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_TRACK0 ? cmdType != 1 ? "LOSTDATA," : "TRACK0," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_INDEX ? cmdType != 1 ? "DRQ," : "INDEX," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_BUSY ? "BUSY," : "",
|
||||
cmdStr, emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_LCMD_REG], cmdType);
|
||||
if(cmdType == 3)
|
||||
debugf("READADDR:%02x,%02x,%02x,%02x,%02x,%02x", emuInData[MZ_EMU_FDD_MAX_REGISTERS+16], emuInData[MZ_EMU_FDD_MAX_REGISTERS+17],emuInData[MZ_EMU_FDD_MAX_REGISTERS+18],emuInData[MZ_EMU_FDD_MAX_REGISTERS+19],emuInData[MZ_EMU_FDD_MAX_REGISTERS+20],emuInData[MZ_EMU_FDD_MAX_REGISTERS+21]);
|
||||
|
||||
for(uint8_t tst=0; tst < 32; tst ++)
|
||||
{
|
||||
printf("%02x,", emuInData[MZ_EMU_FDD_MAX_REGISTERS+tst]);
|
||||
}
|
||||
// Clear the READY flag. This also clears the interrupt, basically an acknowledgement.
|
||||
emuControl.fdd.ctrlReg &= ((~FDD_CTRL_READY) & 0x1f);
|
||||
printf("CTRLREG ENTER:%02x\n", emuControl.fdd.ctrlReg );
|
||||
writeZ80Array(MZ_EMU_FDD_CTRL_ADDR+MZ_EMU_FDD_CTRL_REG, &emuControl.fdd.ctrlReg, 1, FPGA);
|
||||
|
||||
// Process the request if it requires servicing.
|
||||
enum FLOPPYERRORCODES floppyError = FLPYERR_NOERROR;
|
||||
uint16_t thisSectorSize = 0;
|
||||
uint16_t thisRotationalSpeed = 0;
|
||||
if(cmdSvc) floppyError = (uint8_t)EMZProcessFDDRequest(emuInData[MZ_EMU_FDD_CTRL_REG], emuInData[MZ_EMU_FDD_TRACK_REG], emuInData[MZ_EMU_FDD_SECTOR_REG], emuInData[MZ_EMU_FDD_CST_REG], &thisSectorSize, &thisRotationalSpeed);
|
||||
printf("Error Code:%d, Sector Size:%d, Rotational Speed:%d\n", floppyError, thisSectorSize, thisRotationalSpeed);
|
||||
|
||||
// Processing complete, set the READY flag along with current sector size, rotational speed and error code. 7:5 = error code, 4 = rotational speed, 3:1 = sector size code, 0 = Ready flag.
|
||||
if(floppyError != FLPYERR_NOERROR)
|
||||
{
|
||||
emuControl.fdd.ctrlReg = (floppyError << 5 | FDD_CTRL_READY);
|
||||
} else
|
||||
{
|
||||
emuControl.fdd.ctrlReg = thisRotationalSpeed == 360 ? 0x10 : 0x00 | ((uint8_t)((thisSectorSize&0xff00) >> 7) & 0x0E) | FDD_CTRL_READY;
|
||||
}
|
||||
printf("CTRLREG EXIT:%02x\n", emuControl.fdd.ctrlReg );
|
||||
writeZ80Array(MZ_EMU_FDD_CTRL_ADDR+MZ_EMU_FDD_CTRL_REG, &emuControl.fdd.ctrlReg, 1, FPGA);
|
||||
}
|
||||
} else
|
||||
{
|
||||
// Read the cmt status directly. This data can also be ready from the Master Control register of the emulator.
|
||||
result=readZ80Array(MZ_EMU_CMT_REG_ADDR, emuInData, MZ_EMU_CMT_MAX_REGISTERS, FPGA);
|
||||
|
||||
// Update the local copy.
|
||||
emuConfig.emuRegisters[MZ_EMU_REG_CMT3] = emuInData[MZ_EMU_CMT_STATUS_INTR_REG];
|
||||
emuConfig.emuRegisters[MZ_EMU_REG_CMT2] = emuInData[MZ_EMU_CMT_STATUS2_INTR_REG];
|
||||
|
||||
// When debugging output register change as text message.
|
||||
debugf("CMT/CMT2 (%02x,%02x,%s%s%s%s%s%s:%s%s%s%s%s).",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG], emuInData[MZ_EMU_CMT_STATUS2_REG],
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_PLAY_READY ? "PLAY_READY," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_PLAYING ? "PLAYING," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_RECORD_READY ? "RECORD_READY,": "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_RECORDING ? "RECORDING," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_ACTIVE ? "ACTIVE," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_REG] & MZ_EMU_CMT_SENSE ? "SENSE," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_APSS ? "APSS," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_APSS ? emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_DIRECTION ? "FFWD," : "REW," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_EJECT ? "EJECT," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_PLAY ? "PLAY," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_STOP ? "STOP," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_AUTOREW ? "AUTOREW," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_REG] & MZ_EMU_CMT2_AUTOPLAY ? "AUTOPLAY" : "");
|
||||
|
||||
debugf("CMT/CMT2i(%02x,%02x,%s%s%s%s%s%s:%s%s%s%s%s).",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG], emuInData[MZ_EMU_CMT_STATUS2_INTR_REG],
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_PLAY_READY ? "PLAY_READY," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_PLAYING ? "PLAYING," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_RECORD_READY ? "RECORD_READY,": "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_RECORDING ? "RECORDING," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_ACTIVE ? "ACTIVE," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS_INTR_REG] & MZ_EMU_CMT_SENSE ? "SENSE," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_APSS ? "APSS," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_APSS ? emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_DIRECTION ? "FFWD," : "REW," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_EJECT ? "EJECT," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_PLAY ? "PLAY," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_STOP ? "STOP," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_AUTOREW ? "AUTOREW," : "",
|
||||
emuInData[MZ_EMU_CMT_STATUS2_INTR_REG] & MZ_EMU_CMT2_AUTOPLAY ? "AUTOPLAY" : "");
|
||||
|
||||
// Process the tape queue according to signals received from the hardware.
|
||||
EMZProcessTapeQueue(1);
|
||||
}
|
||||
|
||||
// Floppy Disk Drive unit interrupt?
|
||||
if(emuISRReason[MZ_EMU_INTR_REG_ISR] & MZ_EMU_INTR_SRC_FDD)
|
||||
{
|
||||
// Read the control data to allow a decision as to what is required.
|
||||
result=readZ80Array(MZ_EMU_FDD_CTRL_ADDR, emuInData, MZ_EMU_FDD_MAX_REGISTERS, FPGA);
|
||||
|
||||
// Debug information to evaluate interrupt.
|
||||
result=readZ80Array(MZ_EMU_FDC_CTRL_ADDR, &emuInData[MZ_EMU_FDD_MAX_REGISTERS], 32, FPGA); //MZ_EMU_FDC_MAX_REGISTERS, FPGA);
|
||||
debugf("FDD: (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)",
|
||||
emuInData[MZ_EMU_FDD_CTRL_REG],
|
||||
emuInData[MZ_EMU_FDD_SECTOR_REG],
|
||||
emuInData[MZ_EMU_FDD_TRACK_REG],
|
||||
emuInData[MZ_EMU_FDD_CST_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_TRACK_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_SECTOR_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_DATA_REG],
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_LCMD_REG]);
|
||||
|
||||
debugf("FDD IOP: Drive No:%d, Head:%s, Request:%s, Command: %s, Sector:%d, Track:%d",
|
||||
((emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_DISK_SELECT_NO) >> 5) & 0x03,
|
||||
emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_SIDE ? "1" : "0",
|
||||
emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_SERVICE_REQ ? "YES " : "NO",
|
||||
(emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_REQ_MODE) == 0 ? "NOP" : (emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_REQ_MODE) == 1 ? "READ" : (emuInData[MZ_EMU_FDD_CTRL_REG] & FDD_IOP_REQ_MODE) == 2 ? "WRITE" : "INFO",
|
||||
emuInData[MZ_EMU_FDD_SECTOR_REG],
|
||||
emuInData[MZ_EMU_FDD_TRACK_REG]);
|
||||
debugf(" FDD Signals:(%s%s%s%s) Raw Drive Select:(%d)",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_BUSY ? "BUSY," : "",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_DRQ ? "DRQ," : "",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_DDEN ? "" : "DDEN,",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_MOTORON ? "" : "MOTOR",
|
||||
emuInData[MZ_EMU_FDD_CST_REG] & FDD_DISK_SELECT_NO);
|
||||
|
||||
cmdSvc = 0;
|
||||
switch(emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_LCMD_REG] & 0xF0)
|
||||
{
|
||||
case FDC_CMD_RESTORE:
|
||||
cmdStr = "RESTORE";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_SEEK:
|
||||
cmdStr = "SEEK";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEP:
|
||||
cmdStr = "STEP";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEP_TU:
|
||||
cmdStr = "STEP TU";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEP_IN:
|
||||
cmdStr = "STEPIN";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEPIN_TU:
|
||||
cmdStr = "STEPIN TU";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEPOUT:
|
||||
cmdStr = "STEPOUT";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_STEPOUT_TU:
|
||||
cmdStr = "STEPOUT TU";
|
||||
cmdType = 1;
|
||||
break;
|
||||
case FDC_CMD_READSEC:
|
||||
cmdStr = "READSEC";
|
||||
cmdSvc = 1;
|
||||
cmdType = 2;
|
||||
break;
|
||||
case FDC_CMD_READSEC_MULT:
|
||||
cmdStr = "READSEC MULT";
|
||||
cmdSvc = 1;
|
||||
cmdType = 2;
|
||||
break;
|
||||
case FDC_CMD_WRITESEC:
|
||||
cmdStr = "WRITESEC";
|
||||
cmdSvc = 1;
|
||||
cmdType = 2;
|
||||
break;
|
||||
case FDC_CMD_WRITESEC_MULT:
|
||||
cmdStr = "WRITESEC MULT";
|
||||
cmdSvc = 1;
|
||||
cmdType = 2;
|
||||
break;
|
||||
case FDC_CMD_READADDR:
|
||||
cmdStr = "READADDR";
|
||||
cmdSvc = 1;
|
||||
cmdType = 3;
|
||||
break;
|
||||
case FDC_CMD_READTRACK:
|
||||
cmdStr = "READTRACK";
|
||||
cmdSvc = 1;
|
||||
cmdType = 3;
|
||||
break;
|
||||
case FDC_CMD_WRITETRACK:
|
||||
cmdStr = "WRITETRACK";
|
||||
cmdSvc = 1;
|
||||
cmdType = 3;
|
||||
break;
|
||||
case FDC_CMD_FORCEINT:
|
||||
cmdStr = "FORCEINT";
|
||||
cmdType = 4;
|
||||
break;
|
||||
}
|
||||
debugf(" WD1793 Signals:(%s%s%s%s%s%s%s%s%s[%02x,%d])",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_NOTRDY ? "NOTRDY," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_PROTECTED ? "PROTECTED," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_HEADLOADED ? cmdType != 1 ? "RTYPE/WFAULT," : "HEADLOADED," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_SEEKERROR ? cmdType != 1 ? "RNF," : "SEEKERROR," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_CRCERROR ? "CRCERROR," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_TRACK0 ? cmdType != 1 ? "LOSTDATA," : "TRACK0," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_INDEX ? cmdType != 1 ? "DRQ," : "INDEX," : "",
|
||||
emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_CTRL_REG] & FDC_STI_BUSY ? "BUSY," : "",
|
||||
cmdStr, emuInData[MZ_EMU_FDD_MAX_REGISTERS+MZ_EMU_FDC_LCMD_REG], cmdType);
|
||||
if(cmdType == 3)
|
||||
debugf("READADDR:%02x,%02x,%02x,%02x,%02x,%02x", emuInData[MZ_EMU_FDD_MAX_REGISTERS+16], emuInData[MZ_EMU_FDD_MAX_REGISTERS+17],emuInData[MZ_EMU_FDD_MAX_REGISTERS+18],emuInData[MZ_EMU_FDD_MAX_REGISTERS+19],emuInData[MZ_EMU_FDD_MAX_REGISTERS+20],emuInData[MZ_EMU_FDD_MAX_REGISTERS+21]);
|
||||
|
||||
for(uint8_t tst=0; tst < 32; tst ++)
|
||||
{
|
||||
printf("%02x,", emuInData[MZ_EMU_FDD_MAX_REGISTERS+tst]);
|
||||
}
|
||||
// Clear the READY flag. This also clears the interrupt, basically an acknowledgement.
|
||||
emuControl.fdd.ctrlReg &= ((~FDD_CTRL_READY) & 0x1f);
|
||||
printf("CTRLREG ENTER:%02x\n", emuControl.fdd.ctrlReg );
|
||||
writeZ80Array(MZ_EMU_FDD_CTRL_ADDR+MZ_EMU_FDD_CTRL_REG, &emuControl.fdd.ctrlReg, 1, FPGA);
|
||||
|
||||
// Process the request if it requires servicing.
|
||||
enum FLOPPYERRORCODES floppyError = FLPYERR_NOERROR;
|
||||
uint16_t thisSectorSize = 0;
|
||||
uint16_t thisRotationalSpeed = 0;
|
||||
if(cmdSvc) floppyError = (uint8_t)EMZProcessFDDRequest(emuInData[MZ_EMU_FDD_CTRL_REG], emuInData[MZ_EMU_FDD_TRACK_REG], emuInData[MZ_EMU_FDD_SECTOR_REG], emuInData[MZ_EMU_FDD_CST_REG], &thisSectorSize, &thisRotationalSpeed);
|
||||
printf("Error Code:%d, Sector Size:%d, Rotational Speed:%d\n", floppyError, thisSectorSize, thisRotationalSpeed);
|
||||
|
||||
// Processing complete, set the READY flag along with current sector size, rotational speed and error code. 7:5 = error code, 4 = rotational speed, 3:1 = sector size code, 0 = Ready flag.
|
||||
if(floppyError != FLPYERR_NOERROR)
|
||||
{
|
||||
emuControl.fdd.ctrlReg = (floppyError << 5 | FDD_CTRL_READY);
|
||||
} else
|
||||
{
|
||||
emuControl.fdd.ctrlReg = thisRotationalSpeed == 360 ? 0x10 : 0x00 | ((uint8_t)((thisSectorSize&0xff00) >> 7) & 0x0E) | FDD_CTRL_READY;
|
||||
}
|
||||
printf("CTRLREG EXIT:%02x\n", emuControl.fdd.ctrlReg );
|
||||
writeZ80Array(MZ_EMU_FDD_CTRL_ADDR+MZ_EMU_FDD_CTRL_REG, &emuControl.fdd.ctrlReg, 1, FPGA);
|
||||
printf("Interrupt reason retrieval error.\n");
|
||||
}
|
||||
|
||||
// Release the lock on the Z80 bus before exitting.
|
||||
releaseLockZ80();
|
||||
|
||||
// Indicate processing time.
|
||||
debugf("Int time:%ld", *ms - time);
|
||||
} else
|
||||
{
|
||||
printf("Interrupt reason retrieval error.\n");
|
||||
// Raise an error, couldnt service the interrupt because the Z80 bus couldnt be locked.
|
||||
//
|
||||
debugf("Failed to lock the Z80 bus, cannot service interrupt!");
|
||||
}
|
||||
|
||||
// Indicate processing time.
|
||||
debugf("Int time:%ld", *ms - time);
|
||||
}
|
||||
|
||||
// Scheduling block, called periodically by the zOS scheduling.
|
||||
|
||||
@@ -848,7 +848,7 @@ uint8_t reqZ80Bus(uint32_t timeout)
|
||||
{
|
||||
// Set BUSRQ low which sets the Z80 BUSRQ low.
|
||||
pinLow(CTL_BUSRQ);
|
||||
printf("Wait for low\n");
|
||||
|
||||
// Set BUSRQ low and wait for a BUSACK or for the timeout period. If no response in the timeout period then the tranZPUter board/CPLD has locked up.
|
||||
// do {
|
||||
// // Wait 1ms or until BUSACK goes low.
|
||||
@@ -860,18 +860,16 @@ printf("Wait for low\n");
|
||||
// pinHigh(CTL_BUSRQ);
|
||||
// }
|
||||
// }
|
||||
while(((*ms - startTime) < timeout && pinGet(CTL_BUSACK)));
|
||||
while(((*ms - startTime) < timeout && pinGet(CTL_BUSACK)));
|
||||
|
||||
// If we timed out, deassert BUSRQ and return error.
|
||||
//
|
||||
if((*ms - startTime) >= timeout)
|
||||
{
|
||||
printf("It is HIGH\n");
|
||||
pinHigh(CTL_BUSRQ);
|
||||
result = 1;
|
||||
} else
|
||||
{
|
||||
printf("It is low\n");
|
||||
// Setup the bus ready for transactions, default to read.
|
||||
setupSignalsForZ80Access(READ);
|
||||
|
||||
@@ -943,6 +941,54 @@ uint8_t reqTranZPUterBus(uint32_t timeout, enum TARGETS target)
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to request the Z80 bus and once obtained, hold it until later release. This is an external method to allow and prevent multiple
|
||||
// bus request transactions and roll them up into one transaction.
|
||||
//
|
||||
uint8_t lockZ80(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t result = 0;
|
||||
printf("LOCK Z80\n");
|
||||
// Requst the Z80 Bus to tri-state the Z80.
|
||||
if((result=reqZ80Bus(DEFAULT_BUSREQ_TIMEOUT)) == 0)
|
||||
{
|
||||
// Lock the bus, prevents it being released on method exit.
|
||||
z80Control.holdZ80 = 1;
|
||||
} else
|
||||
{
|
||||
printf("Failed to lock Z80 Bus\n");
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to release an acquired lock on the Z80 bus.
|
||||
//
|
||||
uint8_t releaseLockZ80(void)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
uint8_t result = 0;
|
||||
printf("RELEASE LOCK Z80\n");
|
||||
|
||||
// Check to ensure a lock is in place.
|
||||
if(z80Control.holdZ80 == 1)
|
||||
{
|
||||
// Indicate bus lock no longer required.
|
||||
z80Control.holdZ80 = 0;
|
||||
|
||||
// Release the bus to complete.
|
||||
//
|
||||
releaseZ80();
|
||||
} else
|
||||
{
|
||||
result = 1;
|
||||
printf("Request to release lock and no lock active!\n");
|
||||
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to set all the pins to be able to perform a transaction on the Z80 bus.
|
||||
//
|
||||
void setupSignalsForZ80Access(enum BUS_DIRECTION dir)
|
||||
|
||||
@@ -947,6 +947,8 @@ void resetZ80(uint8_t);
|
||||
uint8_t reqZ80Bus(uint32_t);
|
||||
uint8_t reqMainboardBus(uint32_t);
|
||||
uint8_t reqTranZPUterBus(uint32_t, enum TARGETS);
|
||||
uint8_t lockZ80(void);
|
||||
uint8_t releaseLockZ80(void);
|
||||
void setupSignalsForZ80Access(enum BUS_DIRECTION);
|
||||
void releaseZ80(void);
|
||||
void refreshZ80(void);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user