diff --git a/menu.cpp b/menu.cpp index 8c039ab..3163837 100644 --- a/menu.cpp +++ b/menu.cpp @@ -1222,8 +1222,7 @@ void HandleUI(void) OsdSetTitle(CoreName, OSD_ARROW_RIGHT | OSD_ARROW_LEFT); m = 0; - menumask = 0x3ff; - OsdWrite(m++); + menumask = 0xfff; strcpy(s, " Floppy 0: "); strncat(s, get_image_name(0) ? get_image_name(0) : "* no disk *",27); @@ -1235,39 +1234,47 @@ void HandleUI(void) OsdWrite(m++); + strcpy(s, " HDD 0: "); + strncat(s, archie_get_hdd_name(0) ? archie_get_hdd_name(0) : "* no disk *", 27); + OsdWrite(m++, s, menusub == 2); + + strcpy(s, " HDD 1: "); + strncat(s, archie_get_hdd_name(1) ? archie_get_hdd_name(1) : "* no disk *", 27); + OsdWrite(m++, s, menusub == 3); + + OsdWrite(m++); + strcpy(s, " OS ROM: "); strcat(s, archie_get_rom_name()); - OsdWrite(m++, s, menusub == 2); + OsdWrite(m++, s, menusub == 4); OsdWrite(m++); strcpy(s, " Aspect ratio: "); strcat(s, archie_get_ar() ? "16:9" : "4:3"); - OsdWrite(m++, s, menusub == 3); + OsdWrite(m++, s, menusub == 5); strcpy(s, " Refresh rate: "); strcat(s, archie_get_60() ? "Variable" : "60Hz"); - OsdWrite(m++, s, menusub == 4); - - OsdWrite(m++); + OsdWrite(m++, s, menusub == 6); sprintf(s, " Stereo mix: %s", config_stereo_msg[archie_get_amix()]); - OsdWrite(m++, s, menusub == 5); + OsdWrite(m++, s, menusub == 7); strcpy(s, " 25MHz audio fix: "); strcat(s, archie_get_afix() ? "Enable" : "Disable"); - OsdWrite(m++, s, menusub == 6); + OsdWrite(m++, s, menusub == 8); OsdWrite(m++); sprintf(s, " Swap joysticks: %s", user_io_get_joyswap() ? "Yes" : "No"); - OsdWrite(m++, s, menusub == 7); + OsdWrite(m++, s, menusub == 9); sprintf(s, " Swap mouse btn 2/3: %s", archie_get_mswap() ? "Yes" : "No"); - OsdWrite(m++, s, menusub == 8); + OsdWrite(m++, s, menusub == 10); while(m<15) OsdWrite(m++); - OsdWrite(15, STD_EXIT, menusub == 9, 0); + OsdWrite(15, STD_EXIT, menusub == 11, 0); menustate = MENU_ARCHIE_MAIN2; parentstate = MENU_ARCHIE_MAIN1; @@ -1281,69 +1288,75 @@ void HandleUI(void) case MENU_ARCHIE_MAIN2: // menu key closes menu if (menu) menustate = MENU_NONE1; - if (recent) + if (recent && (menusub <= 3)) { - if (menusub <= 1) - { - fs_Options = SCANO_DIR | SCANO_UMOUNT; - fs_MenuSelect = MENU_ARCHIE_MAIN_FILE_SELECTED; - fs_MenuCancel = MENU_ARCHIE_MAIN1; - strcpy(fs_pFileExt, "ADF"); - if (recent_init(500)) menustate = MENU_RECENT1; - } + fs_Options = SCANO_DIR | SCANO_UMOUNT; + fs_MenuSelect = MENU_ARCHIE_MAIN_FILE_SELECTED; + fs_MenuCancel = MENU_ARCHIE_MAIN1; + strcpy(fs_pFileExt, (menusub <= 1) ? "ADF" : "HDF"); + if (recent_init((menusub <= 1) ? 500 : 501)) menustate = MENU_RECENT1; } if (select || plus || minus) { - switch (menusub) { + switch (menusub) + { case 0: // Floppy 0 case 1: // Floppy 1 if (select) { ioctl_index = 0; - SelectFile(Selected_F[menusub], "ADF", SCANO_DIR | SCANO_UMOUNT, MENU_ARCHIE_MAIN_FILE_SELECTED, MENU_ARCHIE_MAIN1); + SelectFile(Selected_S[menusub], "ADF", SCANO_DIR | SCANO_UMOUNT, MENU_ARCHIE_MAIN_FILE_SELECTED, MENU_ARCHIE_MAIN1); } break; - case 2: // Load ROM + case 2: // HDD 0 + case 3: // HDD 1 if (select) { ioctl_index = 1; + SelectFile(Selected_S[menusub], "HDF", SCANO_DIR | SCANO_UMOUNT, MENU_ARCHIE_MAIN_FILE_SELECTED, MENU_ARCHIE_MAIN1); + } + break; + + case 4: // Load ROM + if (select) + { SelectFile(Selected_F[menusub], "ROM", 0, MENU_ARCHIE_MAIN_FILE_SELECTED, MENU_ARCHIE_MAIN1); } break; - case 3: + case 5: archie_set_ar(!archie_get_ar()); menustate = MENU_ARCHIE_MAIN1; break; - case 4: + case 6: archie_set_60(!archie_get_60()); menustate = MENU_ARCHIE_MAIN1; break; - case 5: + case 7: archie_set_amix(archie_get_amix() + (minus ? -1 : 1)); menustate = MENU_ARCHIE_MAIN1; break; - case 6: + case 8: archie_set_afix(!archie_get_afix()); menustate = MENU_ARCHIE_MAIN1; break; - case 7: + case 9: user_io_set_joyswap(!user_io_get_joyswap()); menustate = MENU_ARCHIE_MAIN1; break; - case 8: + case 10: archie_set_mswap(!archie_get_mswap()); menustate = MENU_ARCHIE_MAIN1; break; - case 9: // Exit + case 11: // Exit if (select) menustate = MENU_NONE1; break; } @@ -1362,18 +1375,25 @@ void HandleUI(void) break; case MENU_ARCHIE_MAIN_FILE_SELECTED: + menustate = MENU_ARCHIE_MAIN1; if (menusub <= 1) { memcpy(Selected_F[menusub], selPath, sizeof(Selected_F[menusub])); recent_update(SelectedDir, Selected_F[menusub], SelectedLabel, 500); user_io_file_mount(selPath, menusub); } - else if (menusub == 2) + else if (menusub <= 3) + { + memcpy(Selected_F[menusub], selPath, sizeof(Selected_F[menusub])); + recent_update(SelectedDir, Selected_F[menusub], SelectedLabel, 501); + archie_hdd_mount(selPath, menusub - 2); + } + else if (menusub == 4) { memcpy(Selected_F[menusub], selPath, sizeof(Selected_F[menusub])); archie_set_rom(selPath); + menustate = MENU_NONE1; } - menustate = MENU_ARCHIE_MAIN1; break; /******************************************************************/ diff --git a/support/archie/archie.cpp b/support/archie/archie.cpp index 3d4ecc2..293e83a 100644 --- a/support/archie/archie.cpp +++ b/support/archie/archie.cpp @@ -1,22 +1,26 @@ -#include "stdio.h" -#include "string.h" +#include +#include +#include + #include "../../hardware.h" #include "../../fpga_io.h" #include "../../menu.h" -#include "archie.h" #include "../../debug.h" #include "../../user_io.h" #include "../../input.h" +#include "../../support.h" +#include "archie.h" #define CONFIG_FILENAME "ARCHIE.CFG" typedef struct { unsigned long system_ctrl; // system control word - char rom_img[1024]; // rom image file name + char rom_img[1024]; // rom image file name + char hdd_img[2][1024]; } archie_config_t; -static archie_config_t config; +static archie_config_t config = {}; #define archie_debugf(a, ...) printf("\033[1;31mARCHIE: " a "\033[0m\n", ##__VA_ARGS__) // #define archie_debugf(a, ...) @@ -189,10 +193,91 @@ static void archie_kbd_reset(void) flags = 0; } -void archie_init(void) +#define cmos_name user_io_make_filepath(HomeDir(), "cmos.dat") + +static uint8_t rtc[16] = {}; +static uint8_t year = 0; +static void update_rtc() +{ + time_t t = time(NULL); + struct tm tm = *localtime(&t); + year = tm.tm_year - 100; + rtc[2] = (tm.tm_sec % 10) | ((tm.tm_sec / 10) << 4); + rtc[3] = (tm.tm_min % 10) | ((tm.tm_min / 10) << 4); + rtc[4] = (tm.tm_hour % 10) | ((tm.tm_hour / 10) << 4); + rtc[5] = (tm.tm_mday % 10) | ((tm.tm_mday / 10) << 4) | (year << 6); + rtc[6] = ((tm.tm_mon + 1) % 10) | (((tm.tm_mon + 1) / 10) << 4) | (tm.tm_wday << 5); +} + +static void load_cmos() +{ + static uint8_t cmos_data[256] = {}; + if (FileLoad(cmos_name, cmos_data, sizeof(cmos_data))) + { + update_rtc(); + memcpy(cmos_data, rtc, 16); + cmos_data[0xC0] = year; + cmos_data[0xC1] = 20; + + user_io_set_index(3); + user_io_set_download(1); + user_io_file_tx_data(cmos_data, sizeof(cmos_data)); + user_io_set_download(0); + } +} + +static void check_cmos(uint8_t cnt) +{ + static uint8_t old_cnt = 0; + static uint32_t cmos_timer = 0; + static uint32_t rtc_timer = 0; + + if (!cmos_timer || CheckTimer(cmos_timer)) + { + cmos_timer = GetTimer(1000); + if (old_cnt != cnt) + { + old_cnt = cnt; + + static uint8_t cmos_data[256]; + user_io_set_index(3); + user_io_set_upload(1); + user_io_file_rx_data(cmos_data, sizeof(cmos_data)); + user_io_set_upload(0); + memset(cmos_data, 0, 16); + cmos_data[0xC0] = 0; + cmos_data[0xC1] = 0; + + static uint8_t cmos_old[256]; + FileLoad(cmos_name, cmos_old, sizeof(cmos_old)); + memset(cmos_old, 0, 16); + cmos_old[0xC0] = 0; + cmos_old[0xC1] = 0; + + if (memcmp(cmos_old, cmos_data, 256)) + { + printf("update cmos.dat\n"); + //hexdump(cmos_data, 256); printf("\n"); + FileSave(cmos_name, cmos_data, sizeof(cmos_data)); + } + } + } + + if (!rtc_timer || CheckTimer(rtc_timer)) + { + rtc_timer = GetTimer(60000); + update_rtc(); + user_io_set_index(3); + user_io_set_download(1); + user_io_file_tx_data(rtc, 16); + user_io_set_download(0); + } +} + +void archie_init() { archie_debugf("init"); - user_io_8bit_set_status(1, UIO_STATUS_RESET); + user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET); // set config defaults config.system_ctrl = 0; @@ -217,6 +302,15 @@ void archie_init(void) archie_set_60(archie_get_60()); archie_set_afix(archie_get_afix()); + if(!config.hdd_img[0][0] || !OpenHardfile(0, config.hdd_img[0])) + { + memset(config.hdd_img[0], 0, sizeof(config.hdd_img[0])); + } + + if (!config.hdd_img[1][0] || !OpenHardfile(1, config.hdd_img[1])) + { + memset(config.hdd_img[1], 0, sizeof(config.hdd_img[1])); + } // upload rom file archie_set_rom(config.rom_img); @@ -224,9 +318,9 @@ void archie_init(void) // upload ext file //user_io_file_tx("Archie/RISCOS.EXT", 2); - user_io_file_tx(user_io_make_filepath(HomeDir(), "CMOS.DAT"), 3); + load_cmos(); - user_io_8bit_set_status(0, UIO_STATUS_RESET); + user_io_8bit_set_status(~UIO_STATUS_RESET, UIO_STATUS_RESET); /* int i; @@ -332,8 +426,38 @@ static void archie_check_queue(void) tx_queue_rptr = QUEUE_NEXT(tx_queue_rptr); } +static void check_reset() +{ + static uint32_t timer = 0; + + // check the user button + if (!user_io_osd_is_visible() && (user_io_user_button() || user_io_get_kbd_reset())) + { + if (!timer) timer = GetTimer(1000); + else if (timer != 1) + { + if (CheckTimer(timer)) + { + archie_set_rom(config.rom_img); + timer = 1; + } + } + } + else + { + timer = 0; + } +} + void archie_poll(void) { + EnableFpga(); + uint16_t status = spi_w(0); + DisableFpga(); + HandleHDD(status >> 8, 0); + check_cmos(status); + check_reset(); + #ifdef HOLD_OFF_TIME if ((kbd_state == STATE_HOLD_OFF) && CheckTimer(hold_off_timer)) { archie_debugf("KBD resume after hold off"); @@ -473,3 +597,22 @@ void archie_poll(void) else DisableIO(); } + +const char *archie_get_hdd_name(int i) +{ + if (!config.hdd_img[i][0]) return NULL; + + char *p = strrchr(config.hdd_img[i], '/'); + if (!p) p = config.hdd_img[i]; else p++; + + return p; +} + +void archie_hdd_mount(char *filename, int idx) +{ + memset(config.hdd_img[idx], 0, sizeof(config.hdd_img[idx])); + if (OpenHardfile(idx, filename)) + { + strcpy(config.hdd_img[idx], filename); + } +} diff --git a/support/archie/archie.h b/support/archie/archie.h index 0b7b1e2..1f63cee 100644 --- a/support/archie/archie.h +++ b/support/archie/archie.h @@ -22,4 +22,7 @@ int archie_get_60(); void archie_set_afix(char i); int archie_get_afix(); +const char *archie_get_hdd_name(int i); +void archie_hdd_mount(char *filename, int idx); + #endif // ARCHIE_H diff --git a/support/minimig/minimig_hdd.cpp b/support/minimig/minimig_hdd.cpp index 715b10a..9fbe836 100644 --- a/support/minimig/minimig_hdd.cpp +++ b/support/minimig/minimig_hdd.cpp @@ -397,7 +397,8 @@ static void ATA_IdentifyDevice(uint8_t* tfr, hdfTYPE *hdf) fpga_spi_fast(CMD_IDE_DATA_WR<<8); // write data command fpga_spi_fast(0); fpga_spi_fast(0); - fpga_spi_fast_block_write_be((uint16_t*)sector_buffer, 256); + if(is_minimig()) fpga_spi_fast_block_write_be((uint16_t*)sector_buffer, 256); + else fpga_spi_fast_block_write((uint16_t*)sector_buffer, 256); DisableFpga(); WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ); } @@ -509,7 +510,8 @@ static void SendSector() fpga_spi_fast(CMD_IDE_DATA_WR << 8); // write data command fpga_spi_fast(0); fpga_spi_fast(0); - fpga_spi_fast_block_write_be((uint16_t*)sector_buffer, 256); + if (is_minimig()) fpga_spi_fast_block_write_be((uint16_t*)sector_buffer, 256); + else fpga_spi_fast_block_write((uint16_t*)sector_buffer, 256); DisableFpga(); } @@ -519,7 +521,8 @@ static void RecvSector() fpga_spi_fast(CMD_IDE_DATA_RD << 8); // read data command fpga_spi_fast(0); fpga_spi_fast(0); - fpga_spi_fast_block_read_be((uint16_t*)sector_buffer, 256); + if (is_minimig()) fpga_spi_fast_block_read_be((uint16_t*)sector_buffer, 256); + else fpga_spi_fast_block_read((uint16_t*)sector_buffer, 256); DisableFpga(); } @@ -717,21 +720,44 @@ void HandleHDD(uint8_t c1, uint8_t c2) } } -uint8_t OpenHardfile(uint8_t unit) +uint8_t OpenHardfile(uint8_t unit, const char* filename) { hdfTYPE *hdf = &HDF[unit]; hdf->unit = unit; hdf->enabled = 0; - if (minimig_config.enable_ide && minimig_config.hardfile[unit].enabled) + + if (is_minimig()) + { + if (minimig_config.enable_ide && minimig_config.hardfile[unit].enabled) + { + printf("\nChecking HDD %d\n", unit); + if (minimig_config.hardfile[unit].filename[0]) + { + if (FileOpenEx(&hdf->file, minimig_config.hardfile[unit].filename, FileCanWrite(minimig_config.hardfile[unit].filename) ? O_RDWR : O_RDONLY)) + { + hdf->enabled = 1; + printf("file: \"%s\": ", hdf->file.name); + SetHardfileGeometry(hdf, !strcasecmp(".hdf", minimig_config.hardfile[unit].filename + strlen(minimig_config.hardfile[unit].filename) - 4)); + printf("size: %llu (%llu MB)\n", hdf->file.size, hdf->file.size >> 20); + printf("CHS: %u/%u/%u", hdf->cylinders, hdf->heads, hdf->sectors); + printf(" (%llu MB), ", ((((uint64_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11)); + printf("Offset: %d\n", hdf->offset); + return 1; + } + } + printf("HDD %d: not present\n", unit); + } + } + else { printf("\nChecking HDD %d\n", unit); - if (minimig_config.hardfile[unit].filename[0]) + if (filename[0]) { - if (FileOpenEx(&hdf->file, minimig_config.hardfile[unit].filename, FileCanWrite(minimig_config.hardfile[unit].filename) ? O_RDWR : O_RDONLY)) + if (FileOpenEx(&hdf->file, filename, FileCanWrite(filename) ? O_RDWR : O_RDONLY)) { hdf->enabled = 1; printf("file: \"%s\": ", hdf->file.name); - SetHardfileGeometry(hdf, !strcasecmp(".hdf", minimig_config.hardfile[unit].filename + strlen(minimig_config.hardfile[unit].filename) - 4)); + SetHardfileGeometry(hdf, 0); printf("size: %llu (%llu MB)\n", hdf->file.size, hdf->file.size >> 20); printf("CHS: %u/%u/%u", hdf->cylinders, hdf->heads, hdf->sectors); printf(" (%llu MB), ", ((((uint64_t)hdf->cylinders) * hdf->heads * hdf->sectors) >> 11)); @@ -739,7 +765,6 @@ uint8_t OpenHardfile(uint8_t unit) return 1; } } - printf("HDD %d: not present\n", unit); } // close if opened earlier. diff --git a/support/minimig/minimig_hdd.h b/support/minimig/minimig_hdd.h index bdd23e6..68945ab 100644 --- a/support/minimig/minimig_hdd.h +++ b/support/minimig/minimig_hdd.h @@ -7,7 +7,7 @@ // functions void HandleHDD(uint8_t c1, uint8_t c2); -uint8_t OpenHardfile(uint8_t unit); +uint8_t OpenHardfile(uint8_t unit, const char* filename = 0); int checkHDF(const char* name, struct RigidDiskBlock **rdb); #endif // __HDD_H__