archie: support for IDE, auto-save for CMOS.

This commit is contained in:
sorgelig
2020-08-20 17:35:20 +08:00
parent 141c0bedae
commit 1b9537eee7
5 changed files with 243 additions and 52 deletions

View File

@@ -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;
/******************************************************************/

View File

@@ -1,22 +1,26 @@
#include "stdio.h"
#include "string.h"
#include <stdio.h>
#include <string.h>
#include <time.h>
#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);
}
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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__