diff --git a/imlac/imlac_cpu.c b/imlac/imlac_cpu.c index 13c49138..5fced6c9 100644 --- a/imlac/imlac_cpu.c +++ b/imlac/imlac_cpu.c @@ -506,6 +506,12 @@ flag_off (uint16 flag) sim_debug (DBG_IRQ, &irq_dev, "Flag off %06o -> %06o\n", flag, FLAGS); } +uint16 +flag_check (uint16 flag) +{ + return FLAGS & flag; +} + static uint16 irq_iot (uint16 insn, uint16 AC) { diff --git a/imlac/imlac_defs.h b/imlac/imlac_defs.h index db3ccc2c..ecf9bab9 100644 --- a/imlac/imlac_defs.h +++ b/imlac/imlac_defs.h @@ -56,6 +56,7 @@ typedef struct { extern t_bool build_dev_tab (void); extern void flag_on (uint16 flag); extern void flag_off (uint16 flag); +extern uint16 flag_check (uint16 flag); extern void dp_on (int flag); extern uint16 dp_is_on (void); extern void crt_point (uint16 x, uint16 y); diff --git a/imlac/imlac_pt.c b/imlac/imlac_pt.c index da0742c5..dcf23d51 100644 --- a/imlac/imlac_pt.c +++ b/imlac/imlac_pt.c @@ -26,10 +26,17 @@ #include "imlac_defs.h" +/* Debug */ +#define DBG 0001 + /* Function declaration. */ +static t_stat ptr_svc (UNIT *uptr); static uint16 ptr_iot (uint16, uint16); static uint16 ptp_iot (uint16, uint16); static t_stat ptr_boot (int32 u, DEVICE *dptr); +static t_stat ptr_detach (UNIT *uptr); + +static uint16 PTRB; static uint16 ptr_rom[] = { 0060077, 0020010, 0104076, 0020020, 0001061, 0100011, 0002400, 0010046, @@ -38,18 +45,32 @@ static uint16 ptr_rom[] = { 0010067, 0100011, 0030020, 0010053, 0110076, 0000002, 0037700, 0037677, }; +static UNIT ptr_unit = { + UDATA (&ptr_svc, UNIT_IDLE+UNIT_ATTABLE, 0) +}; + +static REG ptr_reg[] = { + { ORDATAD (PTRB, PTRB, 8, "Receive buffer") }, + { NULL } +}; + static IMDEV ptr_imdev = { 2, { { 0005, ptr_iot, { NULL, "HRB", "HOF", NULL } }, { 0006, ptr_iot, { NULL, "HON", "STB", NULL } } } }; +static DEBTAB ptr_deb[] = { + { "DBG", DBG }, + { NULL, 0 } +}; + DEVICE ptr_dev = { - "PTR", NULL, NULL, NULL, - 0, 8, 16, 1, 8, 16, + "PTR", &ptr_unit, ptr_reg, NULL, + 1, 8, 16, 1, 8, 16, NULL, NULL, NULL, - &ptr_boot, NULL, NULL, - &ptr_imdev, DEV_DISABLE | DEV_DEBUG | DEV_DIS, 0, NULL, + &ptr_boot, &attach_unit, &ptr_detach, + &ptr_imdev, DEV_DISABLE | DEV_DEBUG | DEV_DIS, 0, ptr_deb, NULL, NULL, NULL, NULL, NULL, NULL }; @@ -67,17 +88,50 @@ DEVICE ptp_dev = { NULL, NULL, NULL, NULL, NULL, NULL }; +static t_stat +ptr_svc (UNIT *uptr) +{ + unsigned char ch; + uint16 flag; + + /* This function is called when the motor is on. The data ready + flag toggles on and off when the tape goes past the read head. */ + + if (flag_check (FLAG_PTR)) { + flag_off (FLAG_PTR); + } else { + if (sim_fread (&ch, 1, 1, uptr->fileref) == 1) { + sim_debug (DBG, &ptr_dev, "Received character %03o\n", ch); + PTRB = ch; + flag_on (FLAG_PTR); + } else { + sim_debug (DBG, &ptr_dev, "No more data\n"); + return SCPE_OK; + } + } + + sim_activate_after (uptr, 1000); + return SCPE_OK; +} + static uint16 ptr_iot (uint16 insn, uint16 AC) { if ((insn & 0771) == 0051) { /* HRB */ - AC |= 0; + sim_debug (DBG, &ptr_dev, "Read character %03o\n", PTRB); + AC |= PTRB; } if ((insn & 0772) == 0052) { /* HOF */ - ; + flag_off (FLAG_PTR); + if (sim_is_active (&ptr_unit)) + sim_cancel (&ptr_unit); + sim_debug (DBG, &ptr_dev, "Motor off.\n"); } if ((insn & 0771) == 0061) { /* HON */ - ; + flag_off (FLAG_PTR); + if (ptr_unit.flags & UNIT_ATT) + sim_activate_after (&ptr_unit, 1000); + sim_debug (DBG, &ptr_dev, "Motor on.\n"); } if ((insn & 0772) == 0062) { /* STB */ ; @@ -111,3 +165,13 @@ ptr_boot (int32 u, DEVICE *dptr) *PC = 040; return SCPE_OK; } + +static t_stat +ptr_detach (UNIT *uptr) +{ + if (!(uptr->flags & UNIT_ATT)) + return SCPE_OK; + if (sim_is_active (uptr)) + sim_cancel (uptr); + return detach_unit (uptr); +}