Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.asm.x86    |    Ahh, the lost art of x86 assembly    |    4,675 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 4,590 of 4,675    |
|    Paul Edwards to All    |
|    Re: serial port    |
|    16 Apr 23 17:44:53    |
   
   From: mutazilah@nospicedham.gmail.com   
      
   I have now added read functionality.   
      
   And I was able to reuse my existing assembler code.   
      
   So that's a great result.   
      
   But as per comments below, I did get two surprising   
   results attempting to get it to work, with a working   
   theory.   
      
   BFN. Paul.   
      
      
   static int readcomm(int port)   
   {   
    UART uart;   
    unsigned long old1;   
    unsigned long old2;   
    unsigned long intdesc1;   
    unsigned long intdesc2;   
    unsigned long intaddr;   
    int xch;   
    int intno = 4;   
    int a8259 = 0x20;   
    int imr = 0x21;   
    int id;   
    int ch;   
      
    uartInit(&uart);   
    uartAddress(&uart, 0x3f8);   
    PREADB(a8259); /* we don't use the result of this */   
    uartDisableInts(&uart);   
    /* IRQs 0-7 are at 0xb0 instead of 8 now */   
    /* we are using IRQ 4 for COM1 */   
    old1 = G_intloc[(intno + 0xb0) * 2];   
    old2 = G_intloc[(intno + 0xb0) * 2 + 1];   
    intaddr = (unsigned long)hltinthit;   
      
    /* we are interested in this interrupt */   
    xch = PREADB(imr);   
    xch &= ~(1 << (intno % 8));   
    PWRITEB(imr, xch);   
      
    uartEnableGPO2(&uart);   
      
    /* uartEnableModem(&uart); */   
    /* uartRaiseDTR(&uart); */   
    /* uartRaiseRTS(&uart); */   
    /* uartCTS(&uart); */   
    intdesc1 = (0x8 << 16) | (intaddr & 0xffff);   
    intdesc2 = (intaddr & 0xffff0000)   
    | (1 << 15)   
    | (0 << 13)   
    | (0x0e << 8);   
    disable();   
    G_intloc[(intno + 0xb0) * 2] = intdesc1;   
    G_intloc[(intno + 0xb0) * 2 + 1] = intdesc2;   
    uartEnableRxRDY(&uart);   
    hltintgo();   
    /* if I immediately disable UART interrupts, I can no   
    longer read the old pending id of RxRDY.   
    If I read the pending ids, RxRDY just gets reasserted,   
    presumably because I haven't actually read the   
    character yet.   
    If I try reading the character, a new character may   
    come in and I'll miss it.   
    So the safest thing to do is just disable interrupts   
    and assume that RxRDY was hit, since that was the only   
    thing actually enabled, and I don't bother reading the   
    interrupt ids. */   
    G_intloc[(intno + 0xb0) * 2] = old1;   
    G_intloc[(intno + 0xb0) * 2 + 1] = old2;   
    uartDisableInts(&uart);   
    enable();   
    ch = uartRecCh(&uart);   
    PWRITEB(0x20, 0x20);   
    uartDisableGPO2(&uart);   
      
    xch = PREADB(imr);   
    xch |= (1 << (intno % 8));   
    PWRITEB(imr, xch);   
      
    uartReset(&uart);   
    uartTerm(&uart);   
      
    return (ch);   
   }   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca