home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / modem / commsupp.arc / COMMASM.A next >
Text File  |  1988-07-21  |  13KB  |  440 lines

  1. ;
  2. ; commasm.a
  3. ;
  4. ;   Tom Poindexter, March 1984
  5. ;
  6. ;   assembler routines for commsupp.c
  7. ;
  8. ;   int_c_handlr - handle interrupts for IRQ4 - com1:
  9. ;   int_b_handlr - handle interrupts for IRQ3 - com2:
  10. ;   sysint       - call a system interrupt
  11. ;   inb          - input a byte from a hardware port
  12. ;   inw          - input a word from a hardware port
  13. ;   outb         - output a byte to a hardware port
  14. ;   outw         - output a word to a hardware port
  15. ;   cli          - clear interrupts (cli)
  16. ;   sti          - set interrupts   (sti)
  17. ;
  18. ;
  19. ; ***************************************************************************
  20. ;
  21. ; int_c_handlr/int_b_handlr - get character from comm port and stuff into
  22. ;                             buffer; check if XOFF should be sent if
  23. ;                             buffer is more than 3/4 when enabled.
  24. ;
  25. ; notes:
  26. ; determination of port to send XOFF and values of end-of-interrupt is from
  27. ; the offset of the comm parms saved in BX at the start of the interrupt handlr
  28. ; hence, the code only supports 2 (and only 2) comm ports as written
  29. ;
  30. ; the C data segment is inserted into the code segment by init_com
  31. ; so that the interrupt handler will have access to the _com_parms
  32. ; control block
  33. ;
  34. ;
  35. ;
  36. C8259_1 equ 20h
  37. EOI_IRQ4 equ 64h
  38. EOI_IRQ3 equ 63h
  39. XON     equ 11h
  40. XOFF    equ 13h
  41. TRUE    equ 1
  42. FALSE   equ 0
  43. ;
  44. ; offsets for _com_parms structure elements
  45. PORT    equ 0
  46. B_ADDR  equ 2
  47. B_LEN   equ 4
  48. B_HEAD  equ 6
  49. B_TAIL  equ 8
  50. B_CNT   equ 10
  51. X_STATE equ 12
  52. X_RECD  equ 14
  53. X_SENT  equ 16
  54. ORG_OFF equ 18
  55. ORG_SEG equ 20
  56. ON_COM  equ 22
  57. ;
  58. ; _com_parms structure length (sizeof(_com_parms))
  59. STRUCT_LEN equ 24
  60. ;
  61. ;
  62.         dseg
  63.         public _com_parms_:word
  64. ;
  65. ;  _com_parms[2] declared in commsupp.c
  66. ;
  67. ;
  68.         cseg
  69.         public int_c_handlr_
  70.         public int_b_handlr_
  71.         public outp_char_               ;C routine to send a char
  72.         public sysint_
  73.         public inb_
  74.         public inw_
  75.         public outb_
  76.         public outw_
  77.         public cli_
  78.         public sti_
  79. ;
  80. ; ****************************************************************************
  81. ;
  82. ; prologue for IRQ4 - com1 interrupt
  83. ;
  84. int_c_handlr_:
  85.         jmp start_c     ;jump around storage for C data seg
  86. c_ds:   dw 0            ;this is filled in by init_com, loction known in
  87.                         ;init_com is "(unsigned) &int_c_handlr + 2"
  88. com1on  db 0            ;flag to see if on_com routine in progress-com1
  89. com2on  db 0            ;flag to see if on_com routine in progress-com2
  90. start_c:
  91.         push ax          ;save regs
  92.         push bx
  93.         push cx
  94.         push dx
  95.         push si
  96.         push di
  97.         push ds
  98.         push es
  99.         push bp
  100.         mov ax,cs:c_ds  ;get the C data segment..
  101.         mov ds,ax       ;..and establish addressability
  102.         mov es,ax       ;...
  103.         mov bx,offset _com_parms_       ;_com_parms offset for com1:
  104.         mov ah,EOI_IRQ4 ;EOI value when exiting this routine
  105.         jmp get_char
  106. ;
  107. ;
  108. ; prologue for IRQ3 - com2 interrupt
  109. int_b_handlr_:
  110.         push ax         ;save regs
  111.         push bx
  112.         push cx
  113.         push dx
  114.         push si
  115.         push di
  116.         push ds
  117.         push es
  118.         push bp
  119.         mov ax,cs:c_ds  ;get the C data segment
  120.         mov ds,ax       ;and establish addressability
  121.         mov es,ax       ;...
  122.         mov bx,offset _com_parms_       ;_com_parms offset for com1:
  123.         add bx,STRUCT_LEN               ; and adjust for com2:
  124.         mov ah,EOI_IRQ3 ;EOI value when exiting this routing
  125. ;
  126. ;
  127. ; get the char held in the receive register
  128. ;
  129. get_char:
  130.         mov dx,[bx+PORT]        ;get port address
  131.         in  al,dx               ;get the byte from the serial card
  132. ;
  133. ; check to see if XON/XOFF protocol enabled;
  134. ; if enabled and buffer 3/4, send XOFF
  135. ;
  136.         cmp word [bx+X_STATE],FALSE     ;are we interested in XON/XOFF?
  137.         je  store               ;no, bypass XOFF and buffer full check
  138.         cmp al,XOFF             ;did we receive XOFF
  139.         jne no_xoff             ;no, go on to check our buffer
  140.         mov word [bx+X_RECD],TRUE       ;yes, set XOFF received flag
  141.         jmp leave               ;and leave this place
  142. no_xoff:
  143.         mov dx,[bx+B_LEN]       ;see if our buffer is 3/4 full
  144.         shr dx,1                ;divide by 2 so that we have 1/2 of buffer len
  145.         shr dx,1                ;divide by 2 again for 1/4 of buffer len
  146.         neg dx                  ;set negative so that we can add it
  147.         add dx,[bx+B_LEN]       ;now we have 3/4 of the buffer len
  148.         cmp [bx+B_CNT],dx       ;is buffer 3/4 full?
  149.         jle store               ;no, go on to store
  150.         cmp word [bx+X_SENT],TRUE   ;have we already sent XOFF
  151.         je store                ;yes, save char
  152.         mov word [bx+X_SENT],TRUE       ;no, set XOFF sent flag and send
  153.         push ax                 ;save the char and EOI
  154.         push bx                 ;save parm block offset
  155.         mov dx,XOFF             ;send XOFF
  156.         push dx                 ;save the XOFF as argrument to routine
  157.         mov dx,1                ;setup for port 1
  158.         cmp bx,offset _com_parms_       ;is this really com1: ?
  159.         je  portarg             ;yup, save it
  160.         mov dx,2                ;no, it's really com2:
  161. portarg:
  162.         push dx                 ;save port as argument
  163.         call outp_char_         ;call C routine to send it
  164.         add sp,4                ;get rid of arguments
  165.         pop bx                  ;restore parm block
  166.         pop ax                  ;restore char and EOI
  167. ;
  168. ; store the char in buffer, if we wrap around, drop the incoming char
  169. ;
  170. store:
  171.         mov dx,[bx+B_CNT]       ;check to see if buffer is full
  172.         cmp dx,[bx+B_LEN]       ;are we full? CNT = LEN
  173.         je  leave               ;yup, sorry Charlie
  174.         mov si,[bx+B_HEAD]      ;get offset to store char
  175.         mov byte [si],al        ;store the char in the buffer..
  176.         inc word [bx+B_CNT]     ;..and increment the count of chars in buffer
  177.         inc word [bx+B_HEAD]    ;increment buffer head for next char
  178.         mov dx,[bx+B_ADDR]      ;now get buffer start..
  179.         add dx,[bx+B_LEN]       ;..and see if we are at the end of the buffer
  180.         cmp [bx+B_HEAD],dx      ;head > end of buffer?
  181.         jl  leave               ;no, continue
  182.         mov dx,[bx+B_ADDR]      ;yes, circle buffer to beginning
  183.         mov [bx+B_HEAD],dx      ;start buffer head at beginning of buffer
  184. ;
  185. ; signal end-of-interrupt, and return
  186. ;
  187. leave:
  188.         mov al,ah               ;setup for specific EOI(determined in prologue)
  189.         out C8259_1,al          ;send the EOI command to the 8259 int ctlr.
  190.         sti                     ;enable interrupts again
  191. ;
  192. ; if on_com routine valid and not active, then call routine
  193. ;
  194.         cmp word [bx+ON_COM],FALSE ;routine there?
  195.         je done                 ;no, finished
  196.         cmp bx,offset _com_parms_ ;is this com1?
  197.         je com1flag             ;yes, go on to com1 logic
  198.         cmp byte cs:com2on,TRUE ;is com2 routine active?
  199.         je done                 ;yes, finished
  200.         mov byte cs:com2on,TRUE ;set the flag on and...
  201.         call word [bx+ON_COM]   ;call the routine
  202.         mov byte cs:com2on,FALSE ;now reset it
  203.         jmp done                ;com2 routine done
  204. com1flag:
  205.         cmp byte cs:com1on,TRUE ;no, is com1 routine active?
  206.         je done                 ;yes, finished
  207.         mov byte cs:com1on,TRUE ;no, set the flag on and...
  208.         call word [bx+ON_COM]   ;call the routine
  209.         mov byte cs:com1on,FALSE ;now reset it
  210. done:
  211.         pop bp                  ;restore everything
  212.         pop es
  213.         pop ds
  214.         pop di
  215.         pop si
  216.         pop dx
  217.         pop cx
  218.         pop bx
  219.         pop ax
  220.         iret                    ;back to where we came
  221. ;
  222. ; end of int_a_handlr and int_b_handlr
  223. ;
  224. ; ***************************************************************************
  225. ;
  226. ;
  227. ; sysint.a -- system interupt call
  228. ;         returns: flags
  229. ;
  230. ;
  231. ; usage:  struct regval {int ax, bx, cx, dx, si, di, ds, es;};
  232. ;         struct regval input_regs, output_regs;
  233. ;         int int_vec;
  234. ;         ....
  235. ;         sysint(int_vec, &input_regs, &output_regs);
  236. ;
  237. ;
  238. ;
  239. ;       cseg                    ;remove comment if you want to use
  240. ;       public sysint_          ;sysint alone
  241. ;
  242. ; prologue
  243. ;
  244. sysint_:
  245.         push    bp              ;save calling bp
  246.         mov     bp,sp           ;addr args thru bp
  247. ;
  248. ;save all regs except ax and dx for parm return
  249. ;
  250.         push    bx
  251.         push    cx
  252.         push    si
  253.         push    di
  254.         push    ds
  255.         push    es
  256. ;
  257. ;get interrupt number
  258. ;
  259.         mov     ax,[bp+4]       ;get interrupt number
  260.         mov     ah,0            ;zero high byte
  261.         mov     cs:intcal+1,al  ;insert interrupt in code
  262. ;
  263. ;get input regs
  264. ;
  265.         push    bp              ;save for after int call
  266.         mov     bp,[bp+6]       ;set-up bp for input reg values
  267.         mov     ax,[bp+00]      ;ax
  268.         mov     bx,[bp+02]      ;bx
  269.         mov     cx,[bp+04]      ;cx
  270.         mov     dx,[bp+06]      ;dx
  271.         mov     si,[bp+08]      ;si
  272.         mov     di,[bp+10]      ;di
  273.         mov     ds,[bp+12]      ;ds
  274.         mov     es,[bp+14]      ;es
  275. ;
  276. ;call the interupt
  277. ;
  278. intcal:
  279.         int     255             ;call the interupt
  280. ;                               ;255 is just a placeholder for the byte
  281. ;                               ;inserted from above
  282. ;
  283. ;put output regs
  284. ;
  285.         pop     bp              ;get bp from our save
  286.         pushf                   ;save flags for return
  287.         push    ax              ;save ax for outregs
  288.         mov     bp,[bp+8]       ;point to output regs struct
  289.         mov     [bp+14],es      ;es
  290.         mov     [bp+12],ds      ;ds
  291.         mov     [bp+10],di      ;di
  292.         mov     [bp+08],si      ;si
  293.         mov     [bp+06],dx      ;dx
  294.         mov     [bp+04],cx      ;cx
  295.         mov     [bp+02],bx      ;bx
  296.         pop     ax              ;get ax again
  297.         mov     [bp+00],ax      ;ax
  298. ;
  299. ; restore all except ax which will contain flags
  300.         pop     ax              ;flags into ax
  301.         mov     dx,0            ;dx:ax return value
  302.         pop     es
  303.         pop     ds
  304.         pop     di
  305.         pop     si
  306.         pop     cx
  307.         pop     bx
  308. ;
  309. ;epilogue
  310.         pop     bp              ;restore calling bp
  311.         ret                     ;so-long
  312. ;
  313. ;
  314. ; end of sysint
  315. ;
  316. ; ***************************************************************************
  317. ;
  318. ;
  319. ; portio.a -- I/O for hardware ports
  320. ;
  321. ;   inb - input one byte
  322. ;   inw - input one word
  323. ;  outb - output one byte
  324. ;  outw - output one word
  325. ;
  326. ; usage:  int addr, val;
  327. ;         addr = 0x0379;
  328. ;         val = inb(addr);
  329. ;         outb(addr,val);
  330. ;
  331. ;
  332. ;
  333. ;       cseg                            ;remove comments if you want to use
  334. ;       public inb_,inw_,outb_,outw_    ;portio alone
  335. ;
  336. ; inb
  337. ; prologue
  338. ;
  339. inb_:
  340.         push    bp              ;save calling bp
  341.         mov     bp,sp           ;addr args thru bp
  342. ;
  343. ;get port address
  344.         mov     dx,[bp+4]       ;port address
  345. ;
  346. ;get port value
  347.         mov     ax,0            ;clear reg
  348.         in      al,dx           ;get it
  349. ;
  350. ;epilogue
  351.         pop     bp              ;restore calling bp
  352.         ret                     ;so-long
  353. ;
  354. ;
  355. ; inw
  356. ; prologue
  357. ;
  358. inw_:
  359.         push    bp              ;save calling bp
  360.         mov     bp,sp           ;addr args thru bp
  361. ;
  362. ;get port address
  363.         mov     dx,[bp+4]       ;port address
  364. ;
  365. ;get port value
  366.         mov     ax,0            ;clear reg
  367.         in      ax,dx           ;get it
  368. ;
  369. ;epilogue
  370.         pop     bp              ;restore calling bp
  371.         ret                     ;so-long
  372. ;
  373. ; outb
  374. ; prologue
  375. ;
  376. outb_:
  377.         push    bp              ;save calling bp
  378.         mov     bp,sp           ;addr args thru bp
  379. ;
  380. ;get port address
  381.         mov     dx,[bp+4]       ;port address
  382. ;
  383. ;get value
  384.         mov     ax,[bp+6]
  385. ;
  386. ;output it
  387.         out     dx,al           ;send it
  388. ;
  389. ;epilogue
  390.         pop     bp              ;restore calling bp
  391.         ret                     ;so-long
  392. ;
  393. ; outw
  394. ; prologue
  395. ;
  396. outw_:
  397.         push    bp              ;save calling bp
  398.         mov     bp,sp           ;addr args thru bp
  399. ;
  400. ;get port address
  401.         mov     dx,[bp+4]       ;port address
  402. ;
  403. ;get value
  404.         mov     ax,[bp+6]
  405. ;
  406. ;output it
  407.         out     dx,ax           ;send it
  408. ;
  409. ;epilogue
  410.         pop     bp              ;restore calling bp
  411.         ret                     ;so-long
  412. ;
  413. ;
  414. ; end of portio
  415. ;
  416. ; ****************************************************************************
  417. ;
  418. ;
  419. ; clisti.a - disable/enable system interrupts
  420. ;
  421. ;
  422. ;       cseg                            ;remove comments if you want to use
  423. ;       public cli_,sti_                ;clisti alone
  424. ;
  425. ;
  426. cli_:   cli
  427.         ret
  428. ;
  429. ;
  430. sti_:   sti
  431.         ret
  432. ;
  433. ; end of clisti.a
  434. ;
  435. ; ***************************************************************************
  436. ;
  437. ; end of commasm.a
  438. ;
  439.  
  440.