void h8_sci_device::rx_raised_edge() { logerror("%s: rx_raised_edge state=%s bit=%d\n", tag(), state_names[rx_state], rx_bit); switch(rx_state) { case ST_START: if(rx_value) { clock_stop(CLK_RX); break; } rx_state = ST_BIT; rx_bit = smr & SMR_CHR ? 7 : 8; break; case ST_BIT: rx_parity ^= rx_value; rsr >>= 1; if(rx_value) { rx_parity = !rx_parity; rsr |= (smr & (SMR_CA|SMR_CHR)) == SMR_CHR ? 0x40 : 0x80; } rx_bit--; if(!rx_bit) { if(smr & SMR_CA) rx_done(); else if(smr & SMR_PE) { rx_state = ST_PARITY; rx_bit = 1; } else { rx_state = ST_STOP; rx_bit = 1; // Always 1 on rx } } break; case ST_PARITY: rx_parity ^= rx_value; assert(rx_bit == 1); rx_state = ST_STOP; rx_bit = 1; break; case ST_STOP: assert(rx_bit == 1); if(!rx_value) ssr |= SSR_FER; else if((smr & SMR_PE) && rx_parity) ssr |= SSR_PER; rx_done(); break; default: abort(); } logerror("%s: -> state=%s, bit=%d\n", tag(), state_names[rx_state], rx_bit); }
t_stat rx_reset (DEVICE *dptr) { rx_csr = rx_dbr = 0; /* clear regs */ rx_esr = rx_ecode = 0; /* clear error */ rx_track = rx_sector = 0; /* clear addr */ rx_state = IDLE; /* ctrl idle */ CLR_INT (RX); /* clear int req */ sim_cancel (&rx_unit[1]); /* cancel drive 1 */ if (dptr->flags & DEV_DIS) sim_cancel (&rx_unit[0]); /* disabled? */ else if (rx_unit[0].flags & UNIT_BUF) { /* attached? */ rx_state = INIT_COMPLETE; /* yes, sched init */ sim_activate (&rx_unit[0], rx_swait * abs (1 - rx_unit[0].TRACK)); } else rx_done (0, 0010); /* no, error */ return auto_config (0, 0); /* run autoconfig */ }
t_stat rx_svc (UNIT *uptr) { int32 i, func; uint32 da; int8 *fbuf = uptr->filebuf; func = RXCS_GETFNC (rx_csr); /* get function */ switch (rx_state) { /* case on state */ case IDLE: /* idle */ return SCPE_IERR; /* done */ case EMPTY: /* empty buffer */ if (rx_bptr >= RX_NUMBY) /* done all? */ rx_done (0, 0); else { rx_dbr = rx_buf[rx_bptr]; /* get next */ rx_bptr = rx_bptr + 1; rx_csr = rx_csr | RXCS_TR; /* set xfer */ } break; case FILL: /* fill buffer */ rx_buf[rx_bptr] = rx_dbr; /* write next */ rx_bptr = rx_bptr + 1; if (rx_bptr < RX_NUMBY) /* more? set xfer */ rx_csr = rx_csr | RXCS_TR; else rx_done (0, 0); /* else done */ break; case RWDS: /* wait for sector */ rx_sector = rx_dbr & RX_M_SECTOR; /* save sector */ rx_csr = rx_csr | RXCS_TR; /* set xfer */ rx_state = RWDT; /* advance state */ return SCPE_OK; case RWDT: /* wait for track */ rx_track = rx_dbr & RX_M_TRACK; /* save track */ rx_state = RWXFR; sim_activate (uptr, /* sched done */ rx_swait * abs (rx_track - uptr->TRACK)); return SCPE_OK; case RWXFR: if ((uptr->flags & UNIT_BUF) == 0) { /* not buffered? */ rx_done (0, 0110); /* done, error */ return IORETURN (rx_stopioe, SCPE_UNATT); } if (rx_track >= RX_NUMTR) { /* bad track? */ rx_done (0, 0040); /* done, error */ break; } uptr->TRACK = rx_track; /* now on track */ if ((rx_sector == 0) || (rx_sector > RX_NUMSC)) { /* bad sect? */ rx_done (0, 0070); /* done, error */ break; } da = CALC_DA (rx_track, rx_sector); /* get disk address */ if (func == RXCS_WRDEL) /* del data? */ rx_esr = rx_esr | RXES_DD; if (func == RXCS_READ) { /* read? */ for (i = 0; i < RX_NUMBY; i++) rx_buf[i] = fbuf[da + i]; } else { if (uptr->flags & UNIT_WPRT) { /* write and locked? */ rx_done (RXES_WLK, 0100); /* done, error */ break; } for (i = 0; i < RX_NUMBY; i++) /* write */ fbuf[da + i] = rx_buf[i]; da = da + RX_NUMBY; if (da > uptr->hwmark) uptr->hwmark = da; } rx_done (0, 0); /* done */ break; case CMD_COMPLETE: /* command complete */ if (func == RXCS_ECODE) { /* read ecode? */ rx_dbr = rx_ecode; /* set dbr */ rx_done (0, -1); /* don't update */ } else rx_done (0, 0); break; case INIT_COMPLETE: /* init complete */ rx_unit[0].TRACK = 1; /* drive 0 to trk 1 */ rx_unit[1].TRACK = 0; /* drive 1 to trk 0 */ if ((rx_unit[0].flags & UNIT_BUF) == 0) { /* not buffered? */ rx_done (RXES_ID, 0010); /* init done, error */ break; } da = CALC_DA (1, 1); /* track 1, sector 1 */ for (i = 0; i < RX_NUMBY; i++) /* read sector */ rx_buf[i] = fbuf[da + i]; rx_done (RXES_ID, 0); /* set done */ if ((rx_unit[1].flags & UNIT_ATT) == 0) rx_ecode = 0020; break; } /* end case state */ return SCPE_OK; }