home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 183_01 / comasm.a < prev    next >
Text File  |  1984-06-22  |  10KB  |  439 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.