Esempio n. 1
0
t_stat clk_svc (UNIT *uptr)
{
tmr_poll = sim_rtcn_calb (clk_tps, TMR_CLK);            /* calibrate clock */
sim_activate_after (uptr, 1000000/clk_tps);             /* reactivate unit */
tmxr_poll = tmr_poll * TMXR_MULT;                       /* set mux poll */
AIO_SET_INTERRUPT_LATENCY(tmr_poll*clk_tps);            /* set interrrupt latency */
return SCPE_OK;
}
Esempio n. 2
0
t_stat clk_svc (UNIT *uptr)
{
tmr_poll = sim_rtcn_calb (clk_tps, TMR_CLK);            /* calibrate clock */
sim_activate_after (uptr, 1000000/clk_tps);             /* reactivate unit */
tmxr_poll = tmr_poll * TMXR_MULT;                       /* set mux poll */
AIO_SET_INTERRUPT_LATENCY(tmr_poll*clk_tps);            /* set interrrupt latency */
if ((tmr_iccs & TMR_CSR_RUN) && tmr_use_100hz)          /* timer on, std intvl? */
    tmr_incr (TMR_INC);                                 /* do timer service */
return SCPE_OK;
}
Esempio n. 3
0
void tmr_sched (uint32 nicr)
{
uint32 usecs = (nicr) ? (~nicr + 1) : 0xFFFFFFFF;

clk_tps = (int32)((1000000.0 / usecs) + 0.5);

sim_debug (TMR_DB_SCHED, &tmr_dev, "tmr_sched(nicr=0x%08X-usecs=0x%08X) - tps=%d\n", nicr, usecs, clk_tps);
tmr_poll = sim_rtcn_calb (clk_tps, TMR_CLK);
sim_activate_after (&tmr_unit, usecs);
}
Esempio n. 4
0
t_stat
ng_svc(UNIT *uptr)
{
  if (ng_cycle(uptr->wait, 0))
    sim_activate_after (uptr, uptr->wait);
  if (ng_stop_flag) {
    ng_stop_flag = FALSE;
    return SCPE_STOP;
  }
  return SCPE_OK;
}
Esempio n. 5
0
void tmr_sched (uint32 nicr)
{
uint32 usecs = (nicr) ? (~nicr + 1) : 0xFFFFFFFF;

clk_tps = 1000000 / usecs;

sim_debug (TMR_DB_SCHED, &tmr_dev, "tmr_sched(nicr=0x%08X-usecs=0x%08X) - tps=%d\n", nicr, usecs, clk_tps);
tmr_poll = sim_rtcn_calb (clk_tps, TMR_CLK);
if (SCPE_OK == sim_activate_after (&tmr_unit, usecs))
    tmr_sav = sim_grtime();                             /* Save interval base time */
}
Esempio n. 6
0
static void pclk_set_ctr (uint32 val)
{
if ((pclk_csr & CSR_GO) == 0)                           /* stopped? */
    pclk_ctr = val;                                     /* save */
else {
    uint32 delay = DMASK & ((pclk_csr & CSR_UPDN) ? (DMASK + 1 - val) : val);
    int32 rv;

    rv = CSR_GETRATE (pclk_csr);                        /* get rate */
    sim_activate_after (&pclk_unit, xtim[rv] * delay);  /* schedule interrupt */
    }
}
Esempio n. 7
0
t_stat clk_svc (UNIT *uptr)
{
int32 t;

clk_csr = clk_csr | CSR_DONE;                           /* set done */
if ((clk_csr & CSR_IE) || clk_fie)
    SET_INT (CLK);
t = sim_rtcn_calb (clk_tps, TMR_CLK);                   /* calibrate clock */
sim_activate_after (uptr, 1000000/clk_tps);             /* reactivate unit */
tmr_poll = t;                                           /* set timer poll */
tmxr_poll = t;                                          /* set mux poll */
return SCPE_OK;
}
Esempio n. 8
0
t_stat clk_svc (UNIT *uptr)
{
int32 t;

if (clk_csr & CSR_IE)
    SET_INT (CLK);
t = sim_rtcn_calb (clk_tps, TMR_CLK);                   /* calibrate clock */
sim_activate_after (&clk_unit, 1000000/clk_tps);        /* reactivate unit */
tmr_poll = t;                                           /* set tmr poll */
tmxr_poll = t * TMXR_MULT;                              /* set mux poll */
if (!todr_blow && todr_reg)                             /* if running? */
    todr_reg = todr_reg + 1;                            /* incr TODR */
return SCPE_OK;
}
Esempio n. 9
0
t_stat fe_reset (DEVICE *dptr)
{
tmxr_set_console_units (&fe_unit[0], &fe_unit[1]);
fei_unit.buf = feo_unit.buf = 0;

M[FE_CTYIN] = M[FE_CTYOUT] = 0;
M[FE_KLININ] = M[FE_KLINOUT] = 0;

M[FE_KEEPA] = INT64_C(0003740000000);                  /* PARITY STOP, CRM, DP PAREN, CACHE EN, 1MSTMR, TRAPEN */
kaf_unit.u3 = 0;
kaf_unit.u4 = 0;
apr_flg = apr_flg & ~(APRF_ITC | APRF_CON);
sim_activate (&fei_unit, KBD_WAIT (fei_unit.wait, tmxr_poll));
sim_activate_after (&kaf_unit, kaf_unit.wait);
return SCPE_OK;
}
Esempio n. 10
0
t_stat clk_svc (UNIT *uptr)
{
    int32 t;

    if ( DEV_IS_BUSY(INT_CLK) )
    {
        DEV_CLR_BUSY( INT_CLK ) ;
        DEV_SET_DONE( INT_CLK ) ;
        DEV_UPDATE_INTR ;
    }
    t = sim_rtc_calb (clk_tps[clk_sel]);                    /* calibrate delay */
    sim_activate_after (uptr, 1000000/clk_tps[clk_sel]);    /* reactivate unit */
    if (clk_adj[clk_sel] > 0)                               /* clk >= 60Hz? */
        tmxr_poll = t * clk_adj[clk_sel];                   /* poll is longer */
    else
        tmxr_poll = t / (-clk_adj[clk_sel]);                /* poll is shorter */

    return SCPE_OK;
}
Esempio n. 11
0
t_stat clk_reset (DEVICE *dptr)
{
    int32 t;

    clk_csr = 0;
    CLR_INT (CLK);
    if (!sim_is_running) {                                  /* RESET (not IORESET)? */
        t = sim_rtcn_init_unit (&clk_unit, clk_unit.wait, TMR_CLK);/* init 100Hz timer */
        sim_activate_after (&clk_unit, 1000000/clk_tps);    /* activate 100Hz unit */
        tmr_poll = t;                                       /* set tmr poll */
        tmxr_poll = t * TMXR_MULT;                          /* set mux poll */
    }
    if (clk_unit.filebuf == NULL) {                         /* make sure the TODR is initialized */
        clk_unit.filebuf = calloc(sizeof(TOY), 1);
        if (clk_unit.filebuf == NULL)
            return SCPE_MEM;
        todr_resync ();
    }
    return SCPE_OK;
}
Esempio n. 12
0
/* Keep-alive service
 * If the 8080 detects the 'force reload' bit, it initiates a disk
 * boot.  IO is reset, but memory is preserved.
 *
 * If the keep-alive enable bit is set, the -10 updates the keep-alive
 * count field every second.  The 8080 also checks the word every second.
 * If the 8080 finds that the count hasn't changed for 15 consecutive seconds,
 * a Keep-Alive Failure is declared.  This forces the -10 to execute the
 * contents of exec location 71 to collect status and initiate error recovery.
 */
static t_stat kaf_svc (UNIT *uptr)
{
if (M[FE_KEEPA] & INT64_C(0020000000000)) {              /* KSRLD - "Forced" (actually, requested) reload */
    uint32 oldsw = sim_switches;
    DEVICE *bdev = NULL;
    int32 i;

    sim_switches &= ~SWMASK ('P');
    reset_all (4);                                      /* RESET IO starting with UBA */
    sim_switches = oldsw;

    M[FE_KEEPA] &= ~INT64_C(0030000177777);             /* Clear KAF, RLD, KPALIV & reason
                                                         * 8080 ucode actually clears HW 
                                                         * status too, but that's a bug. */
    M[FE_KEEPA] |= 02;                                  /* Reason = FORREL */
    fei_unit.buf = feo_unit.buf = 0;
    M[FE_CTYIN] = M[FE_CTYOUT] = 0;
    M[FE_KLININ] = M[FE_KLINOUT] = 0;

    /* The 8080 has the disk RH address & unit in its memory, even if
     * the previous boot was from tape.  It has no NVM, so the last opr
     * selection will do here.  The case of DS MT <rld> would require a
     * SET FE command.  It's not a common case.
     */

    /* The device may have been detached, disabled or reconfigured since boot time.
     * Therefore, search for it by CSR address & validate that it's bootable.
     * If there are problems, the processor is halted.
     */

    for (i = 0; fe_bootrh && (bdev = sim_devices[i]) != NULL; i++ ) {
        DIB *dibp = (DIB *)bdev->ctxt;
        if (dibp && (fe_bootrh >= dibp->ba) &&
           (fe_bootrh < (dibp->ba + dibp->lnt))) {
            break;
            }
        }

    fe_xct = 2;
    if ((bdev != NULL) && (fe_bootunit >= 0) && (fe_bootunit < (int32) bdev->numunits)) {
        UNIT *bunit = bdev->units + fe_bootunit;

        if (!(bunit->flags & UNIT_DIS) && (bunit->flags & UNIT_ATTABLE) && (bunit->flags & UNIT_ATT)) {
            if (bdev->boot (fe_bootunit, bdev) == SCPE_OK) /* boot the device */
                fe_xct = 1;
            }
        }
    }
else if (M[FE_KEEPA] & INT64_C(0010000000000)) {        /* KPACT */
    d10 kav = M[FE_KEEPA] & INT64_C(0000000177400);     /* KPALIV */
    if (kaf_unit.u3 != (int32)kav) {
        kaf_unit.u3 = (int32)kav;
        kaf_unit.u4 = 0;
        }
    else if (++kaf_unit.u4 >= 15) {
        kaf_unit.u4 = 0;
        M[FE_KEEPA] = (M[FE_KEEPA] & ~INT64_C(0000000000377)) | 01; /* RSN = KAF (leaves enabled) */
        fei_unit.buf = feo_unit.buf = 0;
        M[FE_CTYIN] = M[FE_CTYOUT] = 0;
        M[FE_KLININ] = M[FE_KLINOUT] = 0;
        fe_xct = 071;
        }
    }

sim_activate_after (&kaf_unit, kaf_unit.wait);
if (fe_xct == 2) {
    fe_xct = 0;
    return STOP_CONSOLE;
    }
return SCPE_OK;
}
Esempio n. 13
0
void tmr_sched (uint32 nicr)
{
sim_activate_after (&tmr_unit, (nicr) ? (~nicr + 1) : 0xFFFFFFFF);
tmr_sav = sim_grtime();
}
Esempio n. 14
0
static void ports_cmd(uint8 cid, cio_entry *rentry, uint8 *rapp_data)
{
    cio_entry centry = {0};
    uint32 ln, i;
    PORTS_OPTIONS opts;
    char line_config[16];
    uint8 app_data[4] = {0};

    centry.address = rentry->address;
    cio[cid].op = rentry->opcode;
    ln = LN(cid, rentry->subdevice & 0xf);

    switch(rentry->opcode) {
    case CIO_DLM:
        for (i = 0; i < rentry->byte_count; i++) {
            ports_crc = cio_crc32_shift(ports_crc, pread_b(rentry->address + i));
        }
        centry.address = rentry->address + rentry->byte_count;
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] CIO Download Memory: bytecnt=%04x "
                  "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n",
                  R[NUM_PC],
                  rentry->byte_count, rentry->address,
                  centry.address, centry.subdevice, ports_crc);
        /* We intentionally do not set the subdevice in
         * the completion entry */
        cio_cexpress(cid, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_DLM);
        break;
    case CIO_ULM:
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] CIO Upload Memory\n",
                  R[NUM_PC]);
        cio_cexpress(cid, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_ULM);
        break;
    case CIO_FCF:
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] CIO Force Function Call (CRC=%08x)\n",
                  R[NUM_PC], ports_crc);

        /* If the currently running program is a diagnostics program,
         * we are expected to write results into memory at address
         * 0x200f000 */
        if (ports_crc == PORTS_DIAG_CRC1 ||
            ports_crc == PORTS_DIAG_CRC2 ||
            ports_crc == PORTS_DIAG_CRC3) {
            pwrite_h(0x200f000, 0x1);   /* Test success */
            pwrite_h(0x200f002, 0x0);   /* Test Number */
            pwrite_h(0x200f004, 0x0);   /* Actual */
            pwrite_h(0x200f006, 0x0);   /* Expected */
            pwrite_b(0x200f008, 0x1);   /* Success flag again */
        }

        /* An interesting (?) side-effect of FORCE FUNCTION CALL is
         * that it resets the card state such that a new SYSGEN is
         * required in order for new commands to work. In fact, an
         * INT0/INT1 combo _without_ a RESET can sysgen the board. So,
         * we reset the command bits here. */
        cio[cid].sysgen_s = 0;
        cio_cexpress(cid, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_FCF);
        break;
    case CIO_DOS:
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] CIO Determine Op Status\n",
                  R[NUM_PC]);
        cio_cexpress(cid, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_DOS);
        break;
    case CIO_DSD:
        /* Determine Sub-Devices. We have none. */
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] Determine Sub-Devices.\n",
                  R[NUM_PC]);

        /* The system wants us to write sub-device structures
         * at the supplied address */

        pwrite_h(rentry->address, 0x0);
        cio_cexpress(cid, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_DSD);
        break;
    case PPC_OPTIONS:
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] PPC Options Operation\n",
                  R[NUM_PC]);

        opts.line   = pread_h(rentry->address);
        opts.iflag  = pread_h(rentry->address + 4);
        opts.oflag  = pread_h(rentry->address + 6);
        opts.cflag  = pread_h(rentry->address + 8);
        opts.lflag  = pread_h(rentry->address + 10);
        opts.cerase = pread_b(rentry->address + 11);
        opts.ckill  = pread_b(rentry->address + 12);
        opts.cinter = pread_b(rentry->address + 13);
        opts.cquit  = pread_b(rentry->address + 14);
        opts.ceof   = pread_b(rentry->address + 15);
        opts.ceol   = pread_b(rentry->address + 16);
        opts.itime  = pread_b(rentry->address + 17);
        opts.vtime  = pread_b(rentry->address + 18);
        opts.vcount = pread_b(rentry->address + 19);

        sim_debug(TRACE_DBG, &ports_dev,  "    PPC Options: iflag=%04x\n", opts.iflag);
        sim_debug(TRACE_DBG, &ports_dev,  "    PPC Options: oflag=%04x\n", opts.oflag);
        sim_debug(TRACE_DBG, &ports_dev,  "    PPC Options: cflag=%04x\n", opts.cflag);
        sim_debug(TRACE_DBG, &ports_dev,  "    PPC Options: lflag=%04x\n", opts.lflag);
        sim_debug(TRACE_DBG, &ports_dev,  "    PPC Options: itime=%02x\n", opts.itime);
        sim_debug(TRACE_DBG, &ports_dev,  "    PPC Options: vtime=%02x\n", opts.vtime);
        sim_debug(TRACE_DBG, &ports_dev,  "    PPC Options: vcount=%02x\n", opts.vcount);

        ports_state[ln].iflag = opts.iflag;
        ports_state[ln].oflag = opts.oflag;

        if ((rentry->subdevice & 0xf) < PORTS_LINES) {
            /* Adjust baud rate */
            sprintf(line_config, "%s-8N1",
                    ports_baud[opts.cflag&0xf]);

            sim_debug(TRACE_DBG, &ports_dev,
                      "Setting PORTS line %d to %s\n",
                      ln, line_config);

            tmxr_set_config_line(&ports_ldsc[ln], line_config);
        }

        centry.byte_count = sizeof(PPC_OPTIONS);
        centry.opcode = PPC_OPTIONS;
        centry.subdevice = rentry->subdevice;
        centry.address = rentry->address;
        cio_cqueue(cid, CIO_STAT, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_OPTIONS);
        break;
    case PPC_VERS:
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] PPC Version\n",
                  R[NUM_PC]);

        /* Write the version number at the supplied address */
        pwrite_b(rentry->address, PORTS_VERSION);

        centry.opcode = CIO_ULM;

        /* TODO: It's unknown what the value 0x50 means, but this
         * is what a real board sends. */
        app_data[0] = 0x50;
        cio_cqueue(cid, CIO_STAT, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_VERS);
        break;
    case PPC_CONN:
        /* CONNECT - Full request and completion queues */
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] PPC CONNECT - subdevice = %02x\n",
                  R[NUM_PC], rentry->subdevice);

        ports_state[ln].conn = TRUE;

        centry.opcode = PPC_CONN;
        centry.subdevice = rentry->subdevice;
        centry.address = rentry->address;
        cio_cqueue(cid, CIO_STAT, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_CONN);
        break;
    case PPC_XMIT:
        /* XMIT - Full request and completion queues */

        /* The port being referred to is in the subdevice. */
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] PPC XMIT - subdevice = %02x, address=%08x, byte_count=%d\n",
                  R[NUM_PC], rentry->subdevice, rentry->address, rentry->byte_count);

        /* Set state for xmit */
        ports_state[ln].tx_addr = rentry->address;
        ports_state[ln].tx_req_addr = rentry->address;
        ports_state[ln].tx_chars = rentry->byte_count + 1;
        ports_state[ln].tx_req_chars = rentry->byte_count + 1;

        sim_activate_after(&ports_unit[1], ports_unit[1].wait);

        break;
    case PPC_DEVICE:
        /* DEVICE Control - Express request and completion queues */
        /* The port being referred to is in the subdevice. */
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] PPC DEVICE - subdevice = %02x\n",
                  R[NUM_PC], rentry->subdevice);
        centry.subdevice = rentry->subdevice;
        centry.opcode = PPC_DEVICE;
        cio_cexpress(cid, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_DEVICE);
        break;
    case PPC_RECV:
        /* RECV - Full request and completion queues */

        /* The port being referred to is in the subdevice. */
        sim_debug(TRACE_DBG, &ports_dev,
                  "[%08x] [ports_cmd] PPC RECV - subdevice = %02x addr=%08x\n",
                  R[NUM_PC], rentry->subdevice, rentry->address);

        break;
    case PPC_DISC:
        /* Disconnect */
        centry.subdevice = rentry->subdevice;
        centry.opcode = PPC_DISC;
        ports_ldsc[ln].rcve = 0;
        cio_cqueue(cid, CIO_STAT, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_STD);
        break;
    case PPC_BRK:
    case PPC_CLR:
    default:
        sim_debug(TRACE_DBG, &ports_dev,
                  ">>> Op %d Not Handled Yet\n",
                  rentry->opcode);

        cio_cexpress(cid, PPQESIZE, &centry, app_data);
        cio_irq(cid, rentry->subdevice, DELAY_STD);
        break;
    }
}