diff --git a/common/emumz.c b/common/emumz.c index 86e8419..f1be326 100644 --- a/common/emumz.c +++ b/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. diff --git a/common/tranzputer.c b/common/tranzputer.c index b252c3e..1e24875 100644 --- a/common/tranzputer.c +++ b/common/tranzputer.c @@ -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) diff --git a/include/tranzputer.h b/include/tranzputer.h index 02b7957..37366c4 100755 --- a/include/tranzputer.h +++ b/include/tranzputer.h @@ -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); diff --git a/libraries/lib/libimath2-k64f.a b/libraries/lib/libimath2-k64f.a index 965b890..01ed16c 100644 Binary files a/libraries/lib/libimath2-k64f.a and b/libraries/lib/libimath2-k64f.a differ diff --git a/libraries/lib/libumansi-k64f.a b/libraries/lib/libumansi-k64f.a index 6c2cb2b..78e0e15 100644 Binary files a/libraries/lib/libumansi-k64f.a and b/libraries/lib/libumansi-k64f.a differ diff --git a/libraries/lib/libummath-k64f.a b/libraries/lib/libummath-k64f.a index 1ab012c..771c2c2 100644 Binary files a/libraries/lib/libummath-k64f.a and b/libraries/lib/libummath-k64f.a differ diff --git a/libraries/lib/libummathf-k64f.a b/libraries/lib/libummathf-k64f.a index ca4dd88..d28e874 100644 Binary files a/libraries/lib/libummathf-k64f.a and b/libraries/lib/libummathf-k64f.a differ diff --git a/libraries/lib/libummisc-k64f.a b/libraries/lib/libummisc-k64f.a index c8bd0f9..c1242f3 100644 Binary files a/libraries/lib/libummisc-k64f.a and b/libraries/lib/libummisc-k64f.a differ diff --git a/libraries/lib/libumstdio-k64f.a b/libraries/lib/libumstdio-k64f.a index e115875..fc72d3f 100644 Binary files a/libraries/lib/libumstdio-k64f.a and b/libraries/lib/libumstdio-k64f.a differ