home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / dos_ency / 6 / ch1.asm < prev    next >
Encoding:
Assembly Source File  |  1988-08-11  |  9.4 KB  |  270 lines

  1.         TITLE   CH1.ASM
  2.  
  3. ; CH1.ASM -- support file for CTERM.C terminal emulator
  4. ;       set up to work with COM2
  5. ;       for use with Microsoft C and SMALL model only...
  6.  
  7. _TEXT   segment byte public 'CODE'
  8. _TEXT   ends
  9. _DATA   segment byte public 'DATA'
  10. _DATA   ends
  11. CONST   segment byte public 'CONST'
  12. CONST   ends
  13. _BSS    segment byte public 'BSS'
  14. _BSS    ends
  15.  
  16. DGROUP  GROUP   CONST, _BSS, _DATA
  17.         assume  cs:_TEXT, DS:DGROUP, ES:DGROUP, SS:DGROUP
  18.  
  19. _TEXT   segment
  20.  
  21.         public  _i_m,_rdmdm,_Send_Byte,_wrtmdm,_set_mdm,_u_m
  22.  
  23. bport   EQU     02F8h           ; COM2 base address, use 03F8H for COM1
  24. getiv   EQU     350Bh           ; COM2 vectors, use 0CH for COM1
  25. putiv   EQU     250Bh
  26. imrmsk  EQU     00001000b       ; COM2 mask, use 00000100b for COM1
  27. oiv_o   DW      0               ; old int vector save space
  28. oiv_s   DW      0
  29.  
  30. bf_pp   DW      in_bf           ; put pointer (last used)
  31. bf_gp   DW      in_bf           ; get pointer (next to use)
  32. bf_bg   DW      in_bf           ; start of buffer
  33. bf_fi   DW      b_last          ; end of buffer
  34.  
  35. in_bf   DB      512 DUP (?)     ; input buffer
  36.  
  37. b_last  EQU     $               ; address just past buffer end
  38.  
  39. bd_dv   DW      0417h           ; baud rate divisors (0=110 bps)
  40.         DW      0300h           ; code 1 =  150 bps
  41.         DW      0180h           ; code 2 =  300 bps
  42.         DW      00C0h           ; code 3 =  600 bps
  43.         DW      0060h           ; code 4 = 1200 bps
  44.         DW      0030h           ; code 5 = 2400 bps
  45.         DW      0018h           ; code 6 = 4800 bps
  46.         DW      000Ch           ; code 7 = 9600 bps
  47.  
  48. _set_mdm proc   near            ; replaces BIOS 'init' function
  49.         PUSH    BP
  50.         MOV     BP,SP           ; establish stackframe pointer
  51.         PUSH    ES              ; save registers
  52.         PUSH    DS
  53.         MOV     AX,CS           ; point them to CODE segment
  54.         MOV     DS,AX
  55.         MOV     ES,AX
  56.         MOV     AH,[BP+4]       ; get parameter passed by C
  57.         MOV     DX,BPORT+3      ; point to Line Control Reg
  58.         MOV     AL,80h          ; set DLAB bit (see text)
  59.         OUT     DX,AL
  60.         MOV     DL,AH           ; shift param to BAUD field
  61.         MOV     CL,4
  62.         ROL     DL,CL
  63.         AND     DX,00001110b    ; mask out all other bits
  64.         MOV     DI,OFFSET bd_dv
  65.         ADD     DI,DX           ; make pointer to true divisor
  66.         MOV     DX,BPORT+1      ; set to high byte first
  67.         MOV     AL,[DI+1]
  68.         OUT     DX,AL           ; put high byte into UART
  69.         MOV     DX,BPORT        ; then to low byte
  70.         MOV     AL,[DI]
  71.         OUT     DX,AL
  72.         MOV     AL,AH           ; now use rest of parameter
  73.         AND     AL,00011111b    ; to set Line Control Reg
  74.         MOV     DX,BPORT+3
  75.         OUT     DX,AL
  76.         MOV     DX,BPORT+2      ; Interrupt Enable Register
  77.         MOV     AL,1            ; Receive type only
  78.         OUT     DX,AL
  79.         POP     DS              ; restore saved registers
  80.         POP     ES
  81.         MOV     SP,BP
  82.         POP     BP
  83.         RET
  84. _set_mdm endp
  85.  
  86. _wrtmdm proc    near            ; write char to modem
  87. _Send_Byte:                     ; name used by main program
  88.         PUSH    BP
  89.         MOV     BP,SP           ; set up pointer and save regs
  90.         PUSH    ES
  91.         PUSH    DS
  92.         MOV     AX,CS
  93.         MOV     DS,AX
  94.         MOV     ES,AX
  95.         MOV     DX,BPORT+4      ; establish DTR, RTS, and OUT2
  96.         MOV     AL,0Bh
  97.         OUT     DX,AL
  98.         MOV     DX,BPORT+6      ; check for on line, CTS
  99.         MOV     BH,30h
  100.         CALL    w_tmr
  101.         JNZ     w_out           ; timed out
  102.         MOV     DX,BPORT+5      ; check for UART ready
  103.         MOV     BH,20h
  104.         CALL    w_tmr
  105.         JNZ     w_out           ; timed out
  106.         MOV     DX,BPORT        ; send out to UART port
  107.         MOV     AL,[BP+4]       ; get char passed from C
  108.         OUT     DX,AL
  109. w_out:  POP     DS              ; restore saved regs
  110.         POP     ES
  111.         MOV     SP,BP
  112.         POP     BP
  113.         RET
  114. _wrtmdm endp
  115.  
  116. _rdmdm  proc    near            ; reads byte from buffer
  117.         PUSH    BP
  118.         MOV     BP,SP           ; set up ptr, save regs
  119.         PUSH    ES
  120.         PUSH    DS
  121.         MOV     AX,CS
  122.         MOV     DS,AX
  123.         MOV     ES,AX
  124.         MOV     AX,0FFFFh       ; set for EOF flag
  125.         MOV     BX,bf_gp        ; use "get" ptr
  126.         CMP     BX,bf_pp        ; compare to "put"
  127.         JZ      nochr           ; same, empty
  128.         INC     BX              ; else char available
  129.         CMP     BX,bf_fi        ; at end of bfr?
  130.         JNZ     noend           ; no
  131.         MOV     BX,bf_bg        ; yes, set to beg
  132. noend:  MOV     AL,[BX]         ; get the char
  133.         MOV     bf_gp,BX        ; update "get" ptr
  134.         INC     AH              ; zero AH as flag
  135. nochr:  POP     DS              ; restore regs
  136.         POP     ES
  137.         MOV     SP,BP
  138.         POP     BP
  139.         RET
  140. _rdmdm  endp
  141.  
  142. w_tmr   proc    near
  143.         MOV     BL,1            ; wait timer, double loop
  144. w_tm1:  SUB     CX,CX           ; set up inner loop
  145. w_tm2:  IN      AL,DX           ; check for requested response
  146.         MOV     AH,AL           ; save what came in
  147.         AND     AL,BH           ; mask with desired bits
  148.         CMP     AL,BH           ; then compare
  149.         JZ      w_tm3           ; got it, return with ZF set
  150.         LOOP    w_tm2           ; else keep trying
  151.         DEC     BL              ; until double loop expires
  152.         JNZ     w_tm1
  153.         OR      BH,BH           ; timed out, return NZ
  154. w_tm3:  RET
  155. w_tmr   endp
  156.  
  157. ; hardware interrupt service routine
  158. rts_m:  CLI
  159.         PUSH    DS              ; save all regs
  160.         PUSH    AX
  161.         PUSH    BX
  162.         PUSH    CX
  163.         PUSH    DX
  164.         PUSH    CS              ; set DS same as CS
  165.         POP     DS
  166.         MOV     DX,BPORT        ; grab the char from UART
  167.         IN      AL,DX
  168.         MOV     BX,bf_pp        ; use "put" ptr
  169.         INC     BX              ; step to next slot
  170.         CMP     BX,bf_fi        ; past end yet?
  171.         JNZ     nofix           ; no
  172.         MOV     BX,bf_bg        ; yes, set to begin
  173. nofix:  MOV     [BX],AL         ; put char in buffer
  174.         MOV     bf_pp,BX        ; update "put" ptr
  175.         MOV     AL,20h          ; send EOI to 8259 chip
  176.         OUT     20h,AL
  177.         POP     DX              ; restore regs
  178.         POP     CX
  179.         POP     BX
  180.         POP     AX
  181.         POP     DS
  182.         IRET
  183.  
  184. _i_m    proc    near            ; install modem service
  185.         PUSH    BP
  186.         MOV     BP,SP           ; save all regs used
  187.         PUSH    ES
  188.         PUSH    DS
  189.         MOV     AX,CS           ; set DS,ES=CS
  190.         MOV     DS,AX
  191.         MOV     ES,AX
  192.         MOV     DX,BPORT+1      ; Interrupt Enable Reg
  193.         MOV     AL,0Fh          ; enable all ints now
  194.         OUT     DX,AL
  195.  
  196. im1:    MOV     DX,BPORT+2      ; clear junk from UART
  197.         IN      AL,DX           ; read IID reg of UART
  198.         MOV     AH,AL           ; save what came in
  199.         TEST    AL,1            ; anything pending?
  200.         JNZ     im5             ; no, all clear now
  201.         CMP     AH,0            ; yes, Modem Status?
  202.         JNZ     im2             ; no
  203.         MOV     DX,BPORT+6      ; yes, read MSR to clear
  204.         IN      AL,DX
  205. im2:    CMP     AH,2            ; Transmit HR empty?
  206.         JNZ     im3             ; no (no action needed)
  207. im3:    CMP     AH,4            ; Received Data Ready?
  208.         JNZ     im4             ; no
  209.         MOV     DX,BPORT        ; yes, read it to clear
  210.         IN      AL,DX
  211. im4:    CMP     AH,6            ; Line Status?
  212.         JNZ     im1             ; no, check for more
  213.         MOV     DX,BPORT+5      ; yes, read LSR to clear
  214.         IN      AL,DX
  215.         JMP     im1             ; then check for more
  216.  
  217. im5:    MOV     DX,BPORT+4      ; set up working conditions
  218.         MOV     AL,0Bh          ; DTR, RTS, OUT2 bits
  219.         OUT     DX,AL
  220.         MOV     AL,1            ; enable RCV interrupt only
  221.         MOV     DX,BPORT+1
  222.         OUT     DX,AL
  223.         MOV     AX,GETIV        ; get old int vector
  224.         INT     21h
  225.         MOV     oiv_o,BX        ; save for restoring later
  226.         MOV     oiv_s,ES
  227.         MOV     DX,OFFSET rts_m ; set in new one
  228.         MOV     AX,PUTIV
  229.         INT     21h
  230.         IN      AL,21h          ; now enable 8259 PIC
  231.         AND     AL,NOT IMRMSK
  232.         OUT     21h,AL
  233.         MOV     AL,20h          ; then send out an EOI
  234.         OUT     20h,AL
  235.         POP     DS              ; restore regs
  236.         POP     ES
  237.         MOV     SP,BP
  238.         POP     BP
  239.         RET
  240. _i_m    endp
  241.  
  242. _u_m    proc    near            ; uninstall modem service
  243.         PUSH    BP
  244.         MOV     BP,SP           ; save registers
  245.         IN      AL,21h          ; disable COM int in 8259
  246.         OR      AL,IMRMSK
  247.         OUT     21h,AL
  248.         PUSH    ES
  249.         PUSH    DS
  250.         MOV     AX,CS           ; set same as CS
  251.         MOV     DS,AX
  252.         MOV     ES,AX
  253.         MOV     AL,0            ; disable UART ints
  254.         MOV     DX,BPORT+1
  255.         OUT     DX,AL
  256.         MOV     DX,oiv_o        ; restore original vector
  257.         MOV     DS,oiv_s
  258.         MOV     AX,PUTIV
  259.         INT     21h
  260.         POP     DS              ; restore registers
  261.         POP     ES
  262.         MOV     SP,BP
  263.         POP     BP
  264.         RET
  265. _u_m    endp
  266.  
  267. _TEXT   ends
  268.  
  269.         END
  270.