home *** CD-ROM | disk | FTP | other *** search
/ Crazy Collection 12 / CC-12_1.iso / update / doompack / data.a00 / PSETUP11.ZIP / PSSRC.ZIP / PLIO.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-09-05  |  9.3 KB  |  410 lines

  1. ver equ     0
  2. ;History:562,1
  3.  
  4. ;  Copyright, 1988-1992, Russell Nelson, Crynwr Software
  5.  
  6. ;   This program is free software; you can redistribute it and/or modify
  7. ;   it under the terms of the GNU General Public License as published by
  8. ;   the Free Software Foundation, version 1.
  9. ;
  10. ;   This program is distributed in the hope that it will be useful,
  11. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ;   GNU General Public License for more details.
  14. ;
  15. ;   You should have received a copy of the GNU General Public License
  16. ;   along with this program; if not, write to the Free Software
  17. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. include defs.asm
  20.  
  21. .model small
  22.  
  23. .code
  24.  
  25. comment \
  26.  
  27. The following says how to transfer a sequence of bytes.  The bytes
  28. are structured as [ count-low, count-high, bytes, bytes, bytes, checksum ].
  29.  
  30. Send        Recv
  31. 8->
  32. [ repeat the following
  33.         <-1
  34. 10h+low_nib->
  35.         <-0
  36. high_nib->
  37. until all bytes have been transferred ]
  38.         <-0
  39. \
  40.  
  41. DATA        equ    0
  42. REQUEST_IRQ    equ    08h
  43. STATUS        equ    1
  44. CONTROL        equ    2
  45.  
  46. extrn   _bufseg:word
  47. extrn   _bufofs:word
  48. extrn   _recv_count:word
  49. extrn   _newpkt:word
  50. extrn   _portbase:word
  51.  
  52. send_nib_count    db    ?
  53. recv_byte_count    db    ?
  54.  
  55. ;put into the public domain by Russell Nelson, nelson@crynwr.com
  56.  
  57. ;we read the timer chip's counter zero.  It runs freely, counting down
  58. ;from 65535 to zero.  We sample the count coming in and subract the previous
  59. ;count.  Then we double it and add it to our timeout_counter.  When it overflows,
  60. ;then we've waited a tick of 27.5 ms.
  61.  
  62. timeout        dw    ?        ;number of ticks to wait.
  63. timeout_counter    dw    ?        ;old counter zero value.
  64. timeout_value    dw    ?
  65.  
  66. set_timeout:
  67. ;enter with ax = number of ticks (36.4 ticks per second).
  68.     inc    ax            ;the first times out immediately.
  69.     mov    cs:timeout,ax
  70.     mov    cs:timeout_counter,0
  71.     call    latch_timer
  72.     mov    cs:timeout_value,ax
  73.     ret
  74.  
  75. latch_timer:
  76.     mov    al,0            ;latch counter zero.
  77.     out    43h,al
  78.     in    al,40h            ;read counter zero.
  79.     mov    ah,al
  80.     in    al,40h
  81.     xchg    ah,al
  82.     ret
  83.  
  84.  
  85. do_timeout:
  86. ;call at *least* every 27.5ms when checking for timeout.  Returns nz
  87. ;if we haven't timed out yet.
  88.     call    latch_timer
  89.     xchg    ax,cs:timeout_value
  90.     sub    ax,cs:timeout_value
  91.     shl    ax,1            ;keep timeout in increments of 27.5 ms.
  92.     add    cs:timeout_counter,ax    ;has the counter overflowed yet?
  93.     jnc    do_timeout_1        ;no.
  94.     dec    cs:timeout        ;Did we hit the timeout value yet?
  95.     ret
  96. do_timeout_1:
  97.     or    sp,sp            ;ensure nz.
  98.         ret
  99.  
  100.  
  101.         public  _send_pkt
  102. _send_pkt:
  103. ;enter with es:di->upcall routine, (0:0) if no upcall is desired.
  104. ;  (only if the high-performance bit is set in driver_function)
  105. ;enter with ds:si -> packet, cx = packet length.
  106. ;if we're a high-performance driver, es:di -> upcall.
  107. ;exit with nc if ok, or else cy if error, dh set to error number.
  108.     assume    ds:nothing
  109.  
  110.     cmp    cx,GIANT        ; Is this packet too large?
  111.     ja    send_pkt_toobig
  112.  
  113. ;cause an interrupt on the other end.
  114.         mov     dx, _portbase
  115.     mov    al,REQUEST_IRQ
  116.     out    dx,al
  117.  
  118. ;wait for the other end to ack the interrupt.
  119.     mov    ax,18
  120.     call    set_timeout
  121.         mov     dx, _portbase
  122.         inc     dx
  123. send_pkt_1:
  124.     in    al,dx
  125.     test    al,1 shl 3        ;wait for them to output 1.
  126.     jne    send_pkt_2
  127.     call    do_timeout
  128.     jne    send_pkt_1
  129.     jmp    short send_pkt_4    ;if it times out, they're not listening.
  130. send_pkt_2:
  131.  
  132.     mov    send_nib_count,0
  133.         mov     dx, _portbase
  134.     mov    al,cl            ;send the count.
  135.     call    send_byte
  136.     jc    send_pkt_4        ;it timed out.
  137.     mov    al,ch
  138.     call    send_byte
  139.     jc    send_pkt_4        ;it timed out.
  140.     xor    bl,bl
  141. send_pkt_3:
  142.     lodsb                ;send the data bytes.
  143.     add    bl,al
  144.     call    send_byte
  145.     jc    send_pkt_4        ;it timed out.
  146.     loop    send_pkt_3
  147.  
  148.     mov    al,bl            ;send the checksum.
  149.         ; mov     hexout_color,30h        ;aqua
  150.         ; call    hexout_more
  151.     call    send_byte
  152.     jc    send_pkt_4        ;it timed out.
  153.  
  154.     mov    al,0            ;go back to quiescent state.
  155.     out    dx,al
  156.     clc
  157.     ret
  158.  
  159. send_pkt_toobig:
  160.     mov    dh,NO_SPACE
  161.     stc
  162.     ret
  163.  
  164. send_pkt_4:
  165.         mov     dx, _portbase
  166.     mov    al,send_nib_count
  167.         ; mov     hexout_color,20h        ;green
  168.         ; call    hexout_more
  169.     xor    al,al            ;clear the data.
  170.     out    dx,al
  171.     mov    dh,CANT_SEND
  172.     stc
  173.     ret
  174. ;
  175. ; It's important to ensure that the most recent setport is a setport DATA.
  176. ;
  177. send_byte:
  178. ;enter with al = byte to send.
  179. ;exit with cy if it timed out.
  180.     push    ax
  181.     or    al,10h            ;set the clock bit.
  182.     call    send_nibble
  183.     pop    ax
  184.     jc    send_nibble_2
  185.     shr    al,1
  186.     shr    al,1
  187.     shr    al,1
  188.     shr    al,1            ;clock bit is cleared by shr.
  189. send_nibble:
  190. ;enter with setport DATA, al[3-0] = nibble to output.
  191. ;exit with dx set to DATA.
  192.     out    dx,al
  193.     and    al,10h            ;get the bit we're waiting for to come back.
  194.     shl    al,1            ;put it in the right position.
  195.     shl    al,1
  196.     shl    al,1
  197.     mov    ah,al
  198.         ; mov     hexout_color,60h        ;orange
  199.         ; call    hexout_more
  200.  
  201.         mov     dx, _portbase
  202.         inc     dx
  203.     push    cx
  204.     xor    cx,cx
  205. send_nibble_1:
  206.     in    al,dx            ;keep getting the status until
  207.     xor    al,87h
  208.     and    al,80h
  209.     cmp    al,ah            ;  we get the status we're looking for.
  210.     loopne    send_nibble_1
  211.     pop    cx
  212.     jne    send_nibble_2
  213.  
  214.         ; mov     hexout_color,50h        ;purple
  215.         ; call    hexout_more
  216.  
  217.     inc    send_nib_count
  218.         mov     dx, _portbase                ;leave with setport DATA.
  219.     clc
  220.     ret
  221. send_nibble_2:
  222.     stc
  223.     ret
  224.  
  225.  
  226.         extrn   _count_in_err: near
  227.         extrn   _count_out_err: near
  228.  
  229. recv_char    db    '0'
  230.  
  231.         public  _recv
  232. _recv:
  233. ;called from the recv isr.  All registers have been saved, and ds=cs.
  234. ;Upon exit, the interrupt will be acknowledged.
  235.  
  236.         mov     dx, _portbase
  237.         inc     dx                      ; see if we've gotten a real interrupt.
  238.     in    al,dx
  239.         and     al, 11111000b           ; mask off the shit
  240.         cmp     al,0c0h                 ; it must be 0c0h, otherwise spurious.
  241.     je    recv_real
  242.         jmp     recv_err
  243. recv_real:
  244.  
  245.         ; mov     al,recv_char
  246.         ; inc     recv_char
  247.         ; and     recv_char,'7'
  248.         ; to_scrn 24,79,al
  249.  
  250.         mov     ax, _bufseg
  251.         mov     es, ax
  252.         mov     di, _bufofs
  253.  
  254.         mov     dx, _portbase
  255.     mov    al,1            ;say that we're ready.
  256.     out    dx,al
  257.  
  258.     mov    recv_byte_count,0
  259.  
  260.         mov     dx, _portbase
  261.         inc     dx
  262.     call    recv_byte        ;get the count.
  263.         jc      recv_err                        ;it timed out.
  264.     mov    cl,al
  265.     call    recv_byte
  266.         jc      recv_err                        ;it timed out.
  267.     mov    ch,al
  268.     xor    bl,bl
  269.         mov     _recv_count,cx
  270. recv_1:
  271.     call    recv_byte        ;get a data byte.
  272.         jc      recv_err                        ;it timed out.
  273.     add    bl,al
  274.     stosb
  275.     loop    recv_1
  276.  
  277.     call    recv_byte        ;get the checksum.
  278.         jc      recv_err                        ;it timed out.
  279.     cmp    al,bl            ;checksum okay?
  280.         jne     recv_err                ;no.
  281.  
  282.     jmp    short recv_free
  283.  
  284. recv_err:
  285.     call    _count_in_err
  286.  
  287. recv_free:
  288.  
  289. ;wait for the other end to reset to zero.
  290.         mov     _newpkt, 1
  291.     mov    ax,10            ;1/9th of a second.
  292.     call    set_timeout
  293.         mov     dx, _portbase
  294.         inc     dx
  295. recv_pkt_1:
  296.     in    al,dx
  297.         and     al, 11111000b
  298.         cmp     al,80h                  ;wait for them to output 0.
  299.     je    recv_4
  300.  
  301.         ; mov     hexout_color,20h        ;green
  302.         ; call    hexout_more
  303.  
  304.     call    do_timeout
  305.     jne    recv_pkt_1
  306.  
  307.     mov    al,recv_byte_count
  308.         ; mov     hexout_color,20h        ;green
  309.         ; call    hexout_more
  310. recv_4:
  311.         mov     dx, _portbase
  312.     xor    al,al
  313.     out    dx,al
  314.     ret
  315.  
  316.         mov     dx, _portbase
  317.         inc     dx
  318.                                         ;this code doesn't get executed,
  319.                     ;but it sets up for call to recv_byte.
  320.  
  321. recv_byte:
  322. ;called with setport STATUS.
  323. ;exit with nc, al = byte, or cy if it timed out.
  324.  
  325.     push    cx
  326.     mov    cx,65535
  327. recv_low_nibble:
  328.     in    al,61h
  329.     in    al,61h
  330.     in    al,61h
  331.     in    al,61h
  332.     in    al,61h
  333.     in    al,61h
  334.     in    al,61h
  335.         in      al,61h
  336.  
  337.     in    al,dx            ;get the next data value.
  338.     test    al,80h            ;wait for handshake low (transmitted hi).
  339.     loopne    recv_low_nibble
  340.     pop    cx
  341.     jne    recv_byte_1
  342.  
  343.     shr    al,1            ;put our bits into position.
  344.     shr    al,1
  345.     shr    al,1
  346.     mov    ah,al
  347.     and    ah,0fh
  348.  
  349.     mov    al,10h            ;send our handshake back.
  350.         mov     dx, _portbase
  351.     out    dx,al
  352.         mov     dx, _portbase
  353.         inc     dx
  354.  
  355.     push    cx
  356.     mov    cx,65535
  357. recv_high_nibble:
  358.     in    al,61h
  359.     in    al,61h
  360.     in    al,61h
  361.     in    al,61h
  362.     in    al,61h
  363.     in    al,61h
  364.     in    al,61h
  365.         in      al,61h
  366.  
  367.     in    al,dx            ;get the next data value.
  368.     test    al,80h            ;check for handshake high (transmitted low).
  369.     loope    recv_high_nibble
  370.     pop    cx
  371.     je    recv_byte_1
  372.  
  373.     shl    al,1            ;put our bits into position.
  374.     and    al,0f0h
  375.     or    ah,al
  376.  
  377.     mov    al,0            ;send our handshake back.
  378.         mov     dx, _portbase
  379.     out    dx,al
  380.         mov     dx, _portbase
  381.         inc     dx
  382.  
  383.     inc    recv_byte_count
  384.  
  385.     mov    al,ah
  386.         ; mov     hexout_color,40h        ;red
  387.         ; call    hexout_more
  388.     clc
  389.     ret
  390. recv_byte_1:
  391.     stc
  392.     ret
  393.  
  394.  
  395.         public  timer_isr
  396. timer_isr:
  397. ;if the first instruction is an iret, then the timer is not hooked
  398.     iret
  399.  
  400. ;any code after this will not be kept after initialization. Buffers
  401. ;used by the program, if any, are allocated from the memory between
  402. ;end_resident and end_free_mem.
  403.     public end_resident,end_free_mem
  404. end_resident    label    byte
  405.     db    GIANT dup(?)
  406. end_free_mem    label    byte
  407.  
  408.  
  409.     end
  410.