home bbs files messages ]

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,582 of 4,675   
   Paul Edwards to All   
   Re: serial port   
   15 Apr 23 07:24:27   
   
   From: mutazilah@nospicedham.gmail.com   
      
   I finally realized that since I'm getting an interrupt from   
   the TBE enable (for unknown reasons), then if I moved   
   the disable (cli) before that, then by the time I had   
   outputted a byte, the interrupt would still be pending   
   and even if I didn't get one for the outputted byte, it   
   was enough to get one for the TBE call.   
      
   And now it is working, with the simple design.   
      
   I will look into refinements now that the basics are working.   
      
   static void writecomm(int port, int ch)   
   {   
       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;   
      
       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);   
      
       disable();   
       uartEnableGPO2(&uart);   
      
       uartEnableTBE(&uart);   
       /* uartEnableModem(&uart); */   
       /* uartRaiseDTR(&uart); */   
       /* uartRaiseRTS(&uart); */   
       /* uartCTS(&uart); */   
       intdesc1 = (0x8 << 16) | (intaddr & 0xffff);   
       intdesc2 = (intaddr & 0xffff0000)   
                  | (1 << 15)   
                  | (0 << 13)   
                  | (0x0e << 8);   
       G_intloc[(intno + 0xb0) * 2] = intdesc1;   
       G_intloc[(intno + 0xb0) * 2 + 1] = intdesc2;   
       uartTxCh(&uart, ch);   
       hltintgo();   
       enable();   
       do   
       {   
           id = uartGetIntType(&uart);   
       } while (id != UART_NO_PENDING);   
       PWRITEB(0x20, 0x20);   
       uartDisableInts(&uart);   
       uartDisableGPO2(&uart);   
      
       xch = PREADB(imr);   
       xch |= (1 << (intno % 8));   
       PWRITEB(imr, xch);   
      
       uartReset(&uart);   
       uartTerm(&uart);   
      
       disable();   
       G_intloc[(intno + 0xb0) * 2] = old1;   
       G_intloc[(intno + 0xb0) * 2 + 1] = old2;   
       enable();   
   }   
      
      
   / enable interrupts and then halt until interrupt hit   
   _hltintgo:   
   hloop:   
   / I believe hlt will be interrupted by other interrupts, like   
   / the timer interrupt, so we need to do it in a loop   
           sti   
           hlt   
           cli   
           jmp     hloop   
   _hltinthit:   
   / remove return address, segment and flags from the stack as we   
   / do not intend to return to the jmp following the hlt instruction   
   / that was likely interrupted   
           add     $12, %esp   
   / note that interrupts will be disabled again (I think) by virtue   
   / of the fact that an interrupt occurred. The caller would have   
   / disabled interrupts already, so we are returning to the same   
   / disabled state.   
           ret   
      
   --- 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