AltairZ80: SS1 bug fix and unused variable removal
This commit is contained in:
parent
892f7d5636
commit
c49f4c552b
3 changed files with 96 additions and 50 deletions
|
@ -240,8 +240,8 @@ static MTAB m2sio_mod[] = {
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static M2SIO_CTX m2sio0_ctx = {0, 0, M2SIO0_IOBASE, M2SIO0_IOSIZE, 0, 0, m2sio0_tmln, &m2sio0_tmxr, M2SIO_BAUD, 1};
|
static M2SIO_CTX m2sio0_ctx = {{0, 0, M2SIO0_IOBASE, M2SIO0_IOSIZE}, 0, 0, m2sio0_tmln, &m2sio0_tmxr, M2SIO_BAUD, 1};
|
||||||
static M2SIO_CTX m2sio1_ctx = {0, 0, M2SIO1_IOBASE, M2SIO1_IOSIZE, 1, 0, m2sio1_tmln, &m2sio1_tmxr, M2SIO_BAUD, 1};
|
static M2SIO_CTX m2sio1_ctx = {{0, 0, M2SIO1_IOBASE, M2SIO1_IOSIZE}, 1, 0, m2sio1_tmln, &m2sio1_tmxr, M2SIO_BAUD, 1};
|
||||||
|
|
||||||
static UNIT m2sio0_unit[] = {
|
static UNIT m2sio0_unit[] = {
|
||||||
{ UDATA (&m2sio_svc, UNIT_ATTABLE | UNIT_DISABLE, 0), M2SIO_WAIT },
|
{ UDATA (&m2sio_svc, UNIT_ATTABLE | UNIT_DISABLE, 0), M2SIO_WAIT },
|
||||||
|
@ -363,7 +363,7 @@ static t_stat m2sio1_reset(DEVICE *dptr)
|
||||||
static t_stat m2sio_reset(DEVICE *dptr, int32 (*routine)(const int32, const int32, const int32))
|
static t_stat m2sio_reset(DEVICE *dptr, int32 (*routine)(const int32, const int32, const int32))
|
||||||
{
|
{
|
||||||
M2SIO_CTX *xptr;
|
M2SIO_CTX *xptr;
|
||||||
int32 i,c;
|
int32 c;
|
||||||
|
|
||||||
xptr = dptr->ctxt;
|
xptr = dptr->ctxt;
|
||||||
|
|
||||||
|
@ -540,7 +540,6 @@ static t_stat m2sio_set_baud(UNIT *uptr, int32 value, const char *cptr, void *de
|
||||||
M2SIO_CTX *xptr;
|
M2SIO_CTX *xptr;
|
||||||
int32 baud;
|
int32 baud;
|
||||||
t_stat r = SCPE_ARG;
|
t_stat r = SCPE_ARG;
|
||||||
char config[20];
|
|
||||||
|
|
||||||
xptr = uptr->dptr->ctxt;
|
xptr = uptr->dptr->ctxt;
|
||||||
|
|
||||||
|
@ -686,7 +685,7 @@ static int32 m2sio_io(DEVICE *dptr, int32 addr, int32 io, int32 data)
|
||||||
static int32 m2sio_stat(DEVICE *dptr, int32 io, int32 data)
|
static int32 m2sio_stat(DEVICE *dptr, int32 io, int32 data)
|
||||||
{
|
{
|
||||||
M2SIO_CTX *xptr;
|
M2SIO_CTX *xptr;
|
||||||
int32 r,s,stb;
|
int32 r,s;
|
||||||
|
|
||||||
xptr = dptr->ctxt;
|
xptr = dptr->ctxt;
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ static MTAB pmmi_mod[] = {
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static PMMI_CTX pmmi_ctx = {0, 0, PMMI_IOBASE, PMMI_IOSIZE, 0, pmmi_tmln, &pmmi_tmxr, PMMI_BAUD, 1};
|
static PMMI_CTX pmmi_ctx = {{0, 0, PMMI_IOBASE, PMMI_IOSIZE}, 0, pmmi_tmln, &pmmi_tmxr, PMMI_BAUD, 1};
|
||||||
|
|
||||||
static UNIT pmmi_unit[] = {
|
static UNIT pmmi_unit[] = {
|
||||||
{ UDATA (&pmmi_svc, UNIT_ATTABLE | UNIT_DISABLE, 0), PMMI_WAIT },
|
{ UDATA (&pmmi_svc, UNIT_ATTABLE | UNIT_DISABLE, 0), PMMI_WAIT },
|
||||||
|
@ -260,7 +260,6 @@ static const char* pmmi_description(DEVICE *dptr)
|
||||||
static t_stat pmmi_reset(DEVICE *dptr)
|
static t_stat pmmi_reset(DEVICE *dptr)
|
||||||
{
|
{
|
||||||
PMMI_CTX *xptr;
|
PMMI_CTX *xptr;
|
||||||
int32 i,c;
|
|
||||||
|
|
||||||
xptr = dptr->ctxt;
|
xptr = dptr->ctxt;
|
||||||
|
|
||||||
|
@ -493,7 +492,6 @@ static t_stat pmmi_set_baud(UNIT *uptr, int32 value, const char *cptr, void *des
|
||||||
PMMI_CTX *xptr;
|
PMMI_CTX *xptr;
|
||||||
int32 baud;
|
int32 baud;
|
||||||
t_stat r = SCPE_ARG;
|
t_stat r = SCPE_ARG;
|
||||||
char config[20];
|
|
||||||
|
|
||||||
xptr = uptr->dptr->ctxt;
|
xptr = uptr->dptr->ctxt;
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ static uint8 SS1_Write(const uint32 Addr, uint8 cData);
|
||||||
static int32 ss1dev(const int32 port, const int32 io, const int32 data);
|
static int32 ss1dev(const int32 port, const int32 io, const int32 data);
|
||||||
void raise_ss1_interrupt(uint8 isr_index);
|
void raise_ss1_interrupt(uint8 isr_index);
|
||||||
static const char* ss1_description(DEVICE *dptr);
|
static const char* ss1_description(DEVICE *dptr);
|
||||||
|
static void setClockSS1(void);
|
||||||
|
|
||||||
/* SS1 Interrupt Controller notes:
|
/* SS1 Interrupt Controller notes:
|
||||||
*
|
*
|
||||||
|
@ -158,12 +159,28 @@ I8253_REGS ss1_tc[1];
|
||||||
#define I8253_CTL_MODE_MASK 0x0E
|
#define I8253_CTL_MODE_MASK 0x0E
|
||||||
#define I8253_CTL_BCD 0x01
|
#define I8253_CTL_BCD 0x01
|
||||||
|
|
||||||
|
#define RTS_SECONDS_1_DIGIT 0
|
||||||
|
#define RTS_SECONDS_10_DIGIT 1
|
||||||
|
#define RTS_MINUTES_1_DIGIT 2
|
||||||
|
#define RTS_MINUTES_10_DIGIT 3
|
||||||
|
#define RTS_HOURS_1_DIGIT 4
|
||||||
|
#define RTS_HOURS_10_DIGIT 5
|
||||||
|
#define RTS_DAY_OF_WEEK_DIGIT 6
|
||||||
|
#define RTS_DAYS_1_DIGIT 7
|
||||||
|
#define RTS_DAYS_10_DIGIT 8
|
||||||
|
#define RTS_MONTHS_1_DIGIT 9
|
||||||
|
#define RTS_MONTHS_10_DIGIT 10
|
||||||
|
#define RTS_YEARS_1_DIGIT 11
|
||||||
|
#define RTS_YEARS_10_DIGIT 12
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8 digit_sel;
|
uint8 digit_sel;
|
||||||
uint8 flags;
|
uint8 flags;
|
||||||
|
uint8 digits[RTS_YEARS_10_DIGIT + 1];
|
||||||
|
int32 clockDelta; /* delta between real clock and SS1 clock */
|
||||||
} RTC_REGS;
|
} RTC_REGS;
|
||||||
|
|
||||||
RTC_REGS ss1_rtc[1];
|
RTC_REGS ss1_rtc[1] = { { 0 } };
|
||||||
|
|
||||||
static UNIT ss1_unit[] = {
|
static UNIT ss1_unit[] = {
|
||||||
{ UDATA (&ss1_svc, UNIT_FIX | UNIT_DISABLE | UNIT_ROABLE, 0) },
|
{ UDATA (&ss1_svc, UNIT_FIX | UNIT_DISABLE | UNIT_ROABLE, 0) },
|
||||||
|
@ -194,6 +211,21 @@ static REG ss1_reg[] = {
|
||||||
|
|
||||||
{ HRDATAD (RTC_DIGIT, ss1_rtc[0].digit_sel, 4, "Digit selector register"), },
|
{ HRDATAD (RTC_DIGIT, ss1_rtc[0].digit_sel, 4, "Digit selector register"), },
|
||||||
{ HRDATAD (RTC_FLAGS, ss1_rtc[0].flags, 4, "Flags register"), },
|
{ HRDATAD (RTC_FLAGS, ss1_rtc[0].flags, 4, "Flags register"), },
|
||||||
|
{ DRDATAD (RTC_DELTA, ss1_rtc[0].clockDelta, 32,
|
||||||
|
"SS1 Clock - Delta between real clock and SS1 clock") },
|
||||||
|
{ HRDATAD (RTC_DIGIT_SEC_1, ss1_rtc[0].digits[RTS_SECONDS_1_DIGIT], 4, "Seconds 1 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_SEC_10,ss1_rtc[0].digits[RTS_SECONDS_10_DIGIT], 4, "Seconds 10 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_MIN_1, ss1_rtc[0].digits[RTS_MINUTES_1_DIGIT], 4, "Minutes 1 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_MIN_10,ss1_rtc[0].digits[RTS_MINUTES_10_DIGIT], 4, "Minutes 10 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_HR_1, ss1_rtc[0].digits[RTS_HOURS_1_DIGIT], 4, "Hours 1 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_HR_10, ss1_rtc[0].digits[RTS_HOURS_10_DIGIT], 4, "Hours 10 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_DAY, ss1_rtc[0].digits[RTS_DAY_OF_WEEK_DIGIT], 4, "Day of week digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_DAY_1, ss1_rtc[0].digits[RTS_DAYS_1_DIGIT], 4, "Days 1 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_DAY_10,ss1_rtc[0].digits[RTS_DAYS_10_DIGIT], 4, "Days 10 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_MO_1, ss1_rtc[0].digits[RTS_MONTHS_1_DIGIT], 4, "Months 1 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_MO_10, ss1_rtc[0].digits[RTS_MONTHS_10_DIGIT], 4, "Months 10 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_YR_1, ss1_rtc[0].digits[RTS_YEARS_1_DIGIT], 4, "Years 1 digit"), },
|
||||||
|
{ HRDATAD (RTC_DIGIT_YR_10, ss1_rtc[0].digits[RTS_YEARS_10_DIGIT], 4, "Years 10 digit"), },
|
||||||
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
@ -287,7 +319,6 @@ extern int32 sio0d(const int32 port, const int32 io, const int32 data);
|
||||||
extern int32 sio0s(const int32 port, const int32 io, const int32 data);
|
extern int32 sio0s(const int32 port, const int32 io, const int32 data);
|
||||||
|
|
||||||
static struct tm currentTime;
|
static struct tm currentTime;
|
||||||
static int32 toBCD(const int32 x);
|
|
||||||
|
|
||||||
static uint8 SS1_Read(const uint32 Addr)
|
static uint8 SS1_Read(const uint32 Addr)
|
||||||
{
|
{
|
||||||
|
@ -348,48 +379,49 @@ static uint8 SS1_Read(const uint32 Addr)
|
||||||
break;
|
break;
|
||||||
case SS1_RTC_DATA:
|
case SS1_RTC_DATA:
|
||||||
time(&now);
|
time(&now);
|
||||||
|
now += ss1_rtc[0].clockDelta;
|
||||||
currentTime = *localtime(&now);
|
currentTime = *localtime(&now);
|
||||||
|
|
||||||
switch(ss1_rtc[0].digit_sel) {
|
switch(ss1_rtc[0].digit_sel) {
|
||||||
case 0:
|
case 0:
|
||||||
cData = toBCD(currentTime.tm_sec) & 0xF;
|
cData = currentTime.tm_sec % 10;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
cData = (toBCD(currentTime.tm_sec) >> 4) & 0xF;
|
cData = currentTime.tm_sec / 10;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
cData = toBCD(currentTime.tm_min) & 0xF;
|
cData = currentTime.tm_min % 10;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
cData = (toBCD(currentTime.tm_min) >> 4) & 0xF;
|
cData = currentTime.tm_min / 10;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
cData = toBCD(currentTime.tm_hour) & 0xF;
|
cData = currentTime.tm_hour % 10;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
cData = (toBCD(currentTime.tm_hour) >> 4) & 0x3;
|
cData = currentTime.tm_hour / 10;
|
||||||
cData |= 0x08; /* Set to 24-hour format */
|
cData |= 0x08; /* Set to 24-hour format */
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
cData = toBCD(currentTime.tm_wday) & 0xF;
|
cData = currentTime.tm_wday;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
cData = toBCD(currentTime.tm_mday) & 0xF;
|
cData = currentTime.tm_mday % 10;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
cData = (toBCD(currentTime.tm_mday) >> 4) & 0xF;
|
cData = currentTime.tm_mday / 10;
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
cData = toBCD(currentTime.tm_mon+1) & 0xF;
|
cData = (currentTime.tm_mon + 1) % 10;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
cData = (toBCD(currentTime.tm_mon+1) >> 4) & 0xF;
|
cData = (currentTime.tm_mon + 1) / 10;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
cData = toBCD(currentTime.tm_year-22) & 0xF;
|
cData = currentTime.tm_year % 10;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
cData = (toBCD(currentTime.tm_year-22) >> 4) & 0xF;
|
cData = (currentTime.tm_year % 100) / 10;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cData = 0;
|
cData = 0;
|
||||||
|
@ -423,6 +455,23 @@ static uint8 SS1_Read(const uint32 Addr)
|
||||||
uint16 newcount = 0;
|
uint16 newcount = 0;
|
||||||
uint8 bc;
|
uint8 bc;
|
||||||
|
|
||||||
|
/* setClockSS1 sets the new ClockSS1Delta based on the provided digits */
|
||||||
|
static void setClockSS1(void) {
|
||||||
|
struct tm newTime;
|
||||||
|
time_t newTime_t;
|
||||||
|
int32 year = 10 * ss1_rtc[0].digits[RTS_YEARS_10_DIGIT] + ss1_rtc[0].digits[RTS_YEARS_1_DIGIT];
|
||||||
|
newTime.tm_year = year < 50 ? year + 100 : year;
|
||||||
|
newTime.tm_mon = 10 * ss1_rtc[0].digits[RTS_MONTHS_10_DIGIT] + ss1_rtc[0].digits[RTS_MONTHS_1_DIGIT] - 1;
|
||||||
|
newTime.tm_mday = 10 * (ss1_rtc[0].digits[RTS_DAYS_10_DIGIT] & 3) + ss1_rtc[0].digits[RTS_DAYS_1_DIGIT]; // remove leap year information in days 10 digit
|
||||||
|
newTime.tm_hour = 10 * (ss1_rtc[0].digits[RTS_HOURS_10_DIGIT] & 3) + ss1_rtc[0].digits[RTS_HOURS_1_DIGIT]; // also remove AM/PM- and 12/24-information in hours 10 digit
|
||||||
|
newTime.tm_min = 10 * ss1_rtc[0].digits[RTS_MINUTES_10_DIGIT] + ss1_rtc[0].digits[RTS_MINUTES_1_DIGIT];
|
||||||
|
newTime.tm_sec = 10 * ss1_rtc[0].digits[RTS_SECONDS_10_DIGIT] + ss1_rtc[0].digits[RTS_SECONDS_1_DIGIT];
|
||||||
|
newTime.tm_isdst = -1;
|
||||||
|
newTime_t = mktime(&newTime);
|
||||||
|
if (newTime_t != (time_t)-1)
|
||||||
|
ss1_rtc[0].clockDelta = (int32)(newTime_t - time(NULL));
|
||||||
|
}
|
||||||
|
|
||||||
static void generate_ss1_interrupt(void);
|
static void generate_ss1_interrupt(void);
|
||||||
|
|
||||||
static uint8 SS1_Write(const uint32 Addr, uint8 cData)
|
static uint8 SS1_Write(const uint32 Addr, uint8 cData)
|
||||||
|
@ -538,10 +587,14 @@ static uint8 SS1_Write(const uint32 Addr, uint8 cData)
|
||||||
ss1_rtc[0].flags & 0x2 ? "WR" :"",
|
ss1_rtc[0].flags & 0x2 ? "WR" :"",
|
||||||
ss1_rtc[0].flags & 0x1 ? "RD" :"",
|
ss1_rtc[0].flags & 0x1 ? "RD" :"",
|
||||||
ss1_rtc[0].digit_sel);
|
ss1_rtc[0].digit_sel);
|
||||||
|
if (cData == 0) // set clock delta
|
||||||
|
setClockSS1();
|
||||||
break;
|
break;
|
||||||
case SS1_RTC_DATA:
|
case SS1_RTC_DATA:
|
||||||
sim_debug(RTC_MSG, &ss1_dev, "SS1: " ADDRESS_FORMAT
|
sim_debug(RTC_MSG, &ss1_dev, "SS1: " ADDRESS_FORMAT
|
||||||
" WR: RTC Data=0x%02x\n", PCX, cData);
|
" WR: RTC Data=0x%02x\n", PCX, cData);
|
||||||
|
if (ss1_rtc[0].digit_sel <= RTS_YEARS_10_DIGIT)
|
||||||
|
ss1_rtc[0].digits[ss1_rtc[0].digit_sel] = cData;
|
||||||
break;
|
break;
|
||||||
case SS1_UART_DATA:
|
case SS1_UART_DATA:
|
||||||
sim_debug(UART_MSG, &ss1_dev, "SS1: " ADDRESS_FORMAT
|
sim_debug(UART_MSG, &ss1_dev, "SS1: " ADDRESS_FORMAT
|
||||||
|
@ -662,7 +715,3 @@ static t_stat ss1_svc (UNIT *uptr)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32 toBCD(const int32 x) {
|
|
||||||
return (x / 10) * 16 + (x % 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue