diff --git a/PDP10/ka10_pd.c b/PDP10/ka10_pd.c index 2aeaeed..d428cec 100644 --- a/PDP10/ka10_pd.c +++ b/PDP10/ka10_pd.c @@ -42,14 +42,24 @@ #define PD_DEVNUM 0500 #define PD_OFF (1 << DEV_V_UF) +#define PIA_CH u3 + +#define PIA_FLG 07 +#define CLK_IRQ 010 + +#define TMR_PD 3 + +int pd_tps = 60; + t_stat pd_devio(uint32 dev, uint64 *data); const char *pd_description (DEVICE *dptr); +t_stat pd_srv(UNIT *uptr); t_stat pd_set_on(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat pd_set_off(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat pd_show_on(FILE *st, UNIT *uptr, int32 val, CONST void *desc); UNIT pd_unit[] = { - {UDATA(NULL, UNIT_DISABLE, 0)}, /* 0 */ + {UDATA(pd_srv, UNIT_IDLE|UNIT_DISABLE, 0)}, /* 0 */ }; DIB pd_dib = {PD_DEVNUM, 1, &pd_devio, NULL}; @@ -91,6 +101,21 @@ t_stat pd_devio(uint32 dev, uint64 *data) else *data = pd_ticks(); break; + case CONI: + *data = (uint64)(pd_unit[0].PIA_CH & (CLK_IRQ|PIA_FLG)); + break; + case CONO: + pd_unit[0].PIA_CH &= ~(PIA_FLG); + pd_unit[0].PIA_CH |= (int32)(*data & PIA_FLG); + if (pd_unit[0].PIA_CH & PIA_FLG) { + if (!sim_is_active(pd_unit)) + sim_activate(pd_unit, 10000); + } + if (*data & CLK_IRQ) { + pd_unit[0].PIA_CH &= ~(CLK_IRQ); + clr_interrupt(PD_DEVNUM); + } + break; default: break; } @@ -98,6 +123,23 @@ t_stat pd_devio(uint32 dev, uint64 *data) return SCPE_OK; } +t_stat +pd_srv(UNIT * uptr) +{ + int32 t; + + t = sim_rtcn_calb (pd_tps, TMR_PD); + sim_activate_after(uptr, 1000000/pd_tps); + if (uptr->PIA_CH & PIA_FLG) { + uptr->PIA_CH |= CLK_IRQ; + set_interrupt(PD_DEVNUM, uptr->PIA_CH); + } else + sim_cancel(uptr); + + return SCPE_OK; +} + + const char *pd_description (DEVICE *dptr) { return "Paul DeCoriolis clock";