Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KA10: Update DPK device. #187

Merged
merged 1 commit into from
Feb 25, 2020
Merged

Conversation

larsbrinkhoff
Copy link
Contributor

Fix #160 and #166. Just a draft!

@larsbrinkhoff
Copy link
Contributor Author

@markpizz, can you please take a look at this?

I call tmxr_set_line_output. But the ouput svc call to sim_activate_after (uptr, 1000) doesn't adjust the delay according to the line speed. What am I doing wrong?

@larsbrinkhoff
Copy link
Contributor Author

Background information. This is a DMA device for output. Each line has two words in memory. The first word is a character count going down to -1. The second word is a byte pointer that is incremented for each character output.

Input goes to a 16 item FIFO and is interrupt driven.

@markpizz
Copy link
Contributor

  1. Your call to tmxr_set_line_speed(&dpk_ldsc[i], "4800") usually would be optional only for someone who truly wanted to experience 4800bps. That person could achieve that experience with ATTACH DPK port,SPEED=4800. Leave it if you want, but for all but the devices that have programmable line speeds, specifying speed on the attach command was the intended use model.
  2. I don't know how PDP10 devices worked with respect to enabling/disabling a specific device's ability to interrupt, but on other systems there is a specific way to enable and disable the device's ability to interrupt. Your logic in dpk_devio() case DATAO|4 seems to only provide a way to enable, but not disable interrupts.
  3. In the situation where more than one line is active, how does this hardware convey whether an interrupt is for input or output, and then which line has data (input) or is ready (output)?
  4. It seems that your loop in dpk_output_svc that scans through the lines currently breaks out of the loop when it finds a character to transmit on a particular line. I can't see a reason why the scan should stop for that reason. It probably should break only when an interrupt has been generated for a line. This suggestion presumes that somehow the current line's completion shouldn't be confused with others (see question 3 above).
  5. the check for previous done (via tmxr_txdone_ln) really doesn't belong in the scan, but right next to the logic that may generate the interrupt.
static t_stat dpk_output_svc (UNIT *uptr)
{
    static int scan = 0;
    int i;

    for (i = 0; i < DPK_LINES; i++) {
        /* Round robin scan 16 lines. */
        scan = (scan + 1) & 017;

        if (dpk_output (scan, &dpk_ldsc[scan]))
          break;
    }

    tmxr_poll_tx (&dpk_desc);

    /* 16 ports at 4800 baud, rounded up. */
    sim_activate_after (uptr, 1000);

    return SCPE_OK;
}


static int dpk_output (int port, TMLN *lp)
{
    uint64 count;
    int ch;

    if ((dpk_port[port] & PORT_OUTPUT) == 0)    /* Not outputting */
        return 0;

    if (tmxr_txdone_ln (lp) == 0)               /* Last character not done yet? */
        return 0;

    if (M[dpk_base + 2*port] == 0777777777777LL) {
        dpk_port[port] &= ~PORT_OUTPUT;
        dpk_status &= ~DPK_OLINE;
        dpk_status |= port << 18;
        dpk_status |= DPK_ODONE;
        if (dpk_ien) {
            set_interrupt(DPK_DEVNUM, dpk_status & DPK_PIA);
            return 1;
        } else
            return 0;
    }

    ch = ildb (&M[dpk_base + 2*port + 1]);
    ch = sim_tt_outcvt(ch & 0377, TT_GET_MODE (dpk_unit[0].flags));
    tmxr_putc_ln (lp, ch);
            
    count = M[dpk_base + 2*port] - 1;
    M[dpk_base + 2*port] = count & 0777777777777LL;

    return 0;
}

@larsbrinkhoff
Copy link
Contributor Author

Thanks! To answer some of your points.

  1. Probably copy-paste leftover. This device does have programmable speeds which I'll add in later.
  2. The symbols that have STOP in their name disables input or output. I'll add some sim_cancel. But if I cancel the input unit, it will not be able to accept incoming connections, right?
  3. CONI ("status register") bits signal input or output interrupt, and for output which line. DATAI reads a character and also which line it's for.

@markpizz
Copy link
Contributor

  1. I would not suggest canceling activities. For many devices, interrupts don't have to be enabled for operation, it just is inefficient. When interrupts are explicitly enabled, the device logic usually looks around and if there is an activity that would have a pending interrupt, one is generated. If interrupts are disabled, then you just don't signal them, but everything else flows the same.
  2. Given what you say here, it seems that since multiple lines can have outgoing transfers simultaneously, when one output operation completes you should add an entry to a queue of pending interrupts which if the queue was empty then you trigger the interrupt. The interrupt acknowledge logic will only clear the interrupt pending condition if the pending output interrupt queue is empty. The entries in this queue are the line numbers that have completed output. Look at pdp11_vh.c for a conceptual example. There is a ton of complicated code there, but if you focus on the interrupt logic you shouldn't get lost.

@rcornwell
Copy link
Owner

On the KA10 interrupt scans only occur after a device sets and interrupt request. Clearing a interrupt request does not trigger a scan. The PDP10 has level sensitive interrupts. So once and interrupt is set, it remains set until the device drops it. The PDP10 has to do something to the device to tell it it has serviced it's interrupt.

You might check out my DC10 which has a scanner to detect received characters. I rely on lower level buffering in the socket layer to handle long output strings.

@markpizz
Copy link
Contributor

On the KA10 interrupt scans only occur after a device sets and interrupt request. Clearing a interrupt request does not trigger a scan. The PDP10 has level sensitive interrupts. So once and interrupt is set, it remains set until the device drops it. The PDP10 has to do something to the device to tell it it has serviced it's interrupt.

OK, so does me saying: "The interrupt acknowledge logic will only clear the interrupt pending condition if the pending output interrupt queue is empty." cover this case. The PDP10's driver will do something to figure out what interrupt just happened, and I'm calling that code path in dpk_devio() where this needs to be done. The output interrupt queue management needs to be handled there. That queue management should set or leave set DKP_ODONE in dpk_status if there are pending output interrupts for different lines, and update the interrupt line in the dpk_status.

@rcornwell
Copy link
Owner

Without looking at the device again. Generally if a device sets DONE flag it should post an interrupt if enabled. Some devices don't have a specific enable and just set the PIA to zero to indicate disabled interrupt. set_interrupt will ignore calls with zero level. Once the device decides to clear the DONE flag it should also clr_interrupt(dev), to stop the CPU from dealing with interrupts. There can be other conditions that can trigger an interrupt, it is up to device writer to let 10 know it needs help.

@larsbrinkhoff
Copy link
Contributor Author

This device just has a master interrupt enable bit for all interrupts.

@larsbrinkhoff
Copy link
Contributor Author

I have four terminals printing full speed to DPK and they seem to hold up well. I'll add programmable line speed settings.

Next up, TK is due for a similar overhaul.

@larsbrinkhoff larsbrinkhoff changed the title KA10: Update DPK device. KA10: Update DPK and TK devices. Feb 22, 2020
@larsbrinkhoff larsbrinkhoff changed the title KA10: Update DPK and TK devices. KA10: Update DPK device. Feb 24, 2020
@larsbrinkhoff larsbrinkhoff marked this pull request as ready for review February 24, 2020 14:30
@larsbrinkhoff
Copy link
Contributor Author

I dropped TK from this pull request so the DPK update can be merged.

@rcornwell
Copy link
Owner

Looks ok to me... will pull it in tonight and let you check it.

@larsbrinkhoff
Copy link
Contributor Author

Rebased and tested.

Copy link
Owner

@rcornwell rcornwell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this passes tests I can merge it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

KA10: DPK only allows one connection
3 participants