home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msvp98b1.lzh / MSNUT1.ASM < prev    next >
Assembly Source File  |  1992-07-04  |  13KB  |  606 lines

  1.        NAME    MSNUT1
  2. ; File MSNUT1.ASM
  3. ; Provides various Intel 8088 level operations, including
  4. ; display facilities (via msg buffer or DOS) for char, strings, etc.
  5. ;
  6. ; Copyright 1991, University of Waterloo.
  7. ;  Copyright (C) 1985, 1992, Trustees of Columbia University in the 
  8. ;  City of New York.  Permission is granted to any individual or institution
  9. ;  to use this software as long as it is not sold for profit.  This copyright
  10. ;  notice must be retained.  This software may not be included in commercial
  11. ;  products without written permission of Columbia University.
  12. ; Written by Erick Engelke of the University of Waterloo, Waterloo, 
  13. ;  Ontario, Canada,
  14. ;  and by Joe R. Doupnik, Utah State University, 
  15. ;  jrd@cc.usu.edu, jrd@usu.Bitnet.
  16. ;
  17. ; Edit history
  18. ; 6 Sept 1991 v3.11
  19. ; Last Edit
  20. ; 2 Feb 1992
  21.  
  22. cr    equ    0dh
  23. lf    equ    0ah
  24. conout    equ    2
  25. dos    equ    21h
  26.  
  27. ;[HF]BIOSCLK    equ    046ch
  28. ;[HF]HI_MAX    equ    018h
  29. ;[HF]LO_MAX    equ     0b0h
  30. HI_MAX    equ    262
  31. LO_MAX    equ    54784
  32.  
  33. _TEXT    SEGMENT  WORD PUBLIC 'CODE'
  34. _TEXT    ENDS
  35. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  36. _DATA    ENDS
  37. CONST    SEGMENT  WORD PUBLIC 'CONST'
  38. CONST    ENDS
  39. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  40. _BSS    ENDS
  41. DGROUP    GROUP    CONST, _BSS, _DATA
  42.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
  43.  
  44. _DATA    SEGMENT
  45.     extrn    _doslevel:word, _msgcnt:word, _msgbuf:byte,_display_mode:byte
  46. _DATA    ENDS
  47.  
  48. _TEXT    segment
  49.  
  50.         ; Compute 1's-complement sum of data buffer
  51.         ; unsigned checksum( unsigned word *buf, unsigned cnt)
  52.     extrn    _realclock:near        ; [HF]
  53.     public    _checksum
  54. _checksum proc    near
  55.     push    bp
  56.     mov    bp,sp
  57.     push    si
  58.     push    bx
  59.     push    cx
  60.     push    dx
  61.         mov     si,[bp+4+0]        ; offset of data to be checked
  62.     mov     cx,[bp+4+2]        ; cx = cnt
  63.     mov    bl,cl
  64.     shr     cx,1            ; group into words
  65.     xor    dx,dx            ; set checksum to 0
  66.         cld
  67.     jcxz    chk3
  68.         clc
  69. chk1:    lodsw
  70.     adc    dx,ax
  71.     loop    chk1
  72.                     ; resolve remainder
  73. chk2:    adc     dx,0
  74.         jc    chk2
  75. chk3:    and    bl,1
  76.     jz    chk5
  77.         xor     ah,ah
  78.     lodsb
  79.         clc
  80.         add     dx,ax
  81. chk4:    adc     dx,0
  82.     jc    chk4
  83. chk5:    mov    ax,dx            ; result into ax
  84.         or      ax,ax
  85.     jnz    chk6
  86.         mov     ax,0ffffh
  87. chk6:    pop    dx
  88.     pop    cx
  89.     pop    bx
  90.     pop    si
  91.     pop    bp
  92.     ret
  93. _checksum endp
  94.  
  95. ;  ntohl(longword x)    32 bit network (big endian) to host (little endian)
  96. ;  htonl(longword x)    32 bit host (little endian) to network (big endian)
  97. ;  intel(longword x)
  98. ;  Reverse order of 4 byte groups between big and little endian forms
  99. ;
  100.     public    _intel, _ntohl, _htonl
  101.  
  102. _intel    proc    near
  103. _ntohl    equ    this byte
  104. _htonl    equ    this byte
  105.     push    bp
  106.     mov    bp,sp
  107.     mov    ax,[bp+4+2]
  108.     mov    dx,[bp+4+0]
  109.     xchg    al,ah
  110.     xchg    dl,dh
  111.     pop    bp
  112.     ret
  113. _intel    endp
  114.  
  115. ;  ntohs(word x)    16 bit network (big endian) to host (little endian)
  116. ;  htons(word x)    16 bit host (little endian) to network (big endian)
  117. ;  intel16(word x)
  118. ;  Reverse order of 2 byte groups between big and little endian forms
  119.     public    _intel16, _ntohs, _htons
  120. _intel16 proc    near
  121. _ntohs    equ    this byte
  122. _htons    equ    this byte
  123.     push    bp
  124.     mov    bp,sp
  125.     mov    ax,[bp+4+0]
  126.     xchg    al,ah
  127.     pop    bp
  128.     ret
  129. _intel16 endp
  130.  
  131.  
  132. ; int ourmod(int top, int bottom)
  133. ; Perform modulo function on 16 bit quantities
  134.     public    _ourmod
  135. _ourmod    proc    near
  136.     push    bp
  137.     mov    bp,sp
  138.     push    bx
  139.     mov    ax,[bp+4+0]        ; top number
  140.     mov    bx,[bp+4+2]        ; bottom number (radix)
  141.     xor    dx,dx
  142.     or    bx,bx            ; bottom is zero?
  143.     jz    ourmod1            ; z = yes, return zero
  144.     div    bx
  145. ourmod1:mov    ax,dx            ; return remainder
  146.     pop    bx
  147.     pop    bp
  148.     ret
  149. _ourmod    endp
  150.  
  151. ; int ourdiv(int top, int bottom)
  152. ; Perform 16 bit integer division
  153.     public    _ourdiv
  154. _ourdiv    proc    near
  155.     push    bp
  156.     mov    bp,sp
  157.     push    bx
  158.     mov    ax,[bp+4+0]        ; top
  159.     mov    bx,[bp+4+2]        ; bottom
  160.     xor    dx,dx
  161.     or    bx,bx            ; divide by zero?
  162.     jz    outdiv1            ; z = yes, divide by one
  163.     div    bx
  164. outdiv1:pop    bx
  165.     pop    bp            ; quotient is returned in ax
  166.     ret
  167. _ourdiv    endp
  168.  
  169. ; int ourlmod(long top, int bottom)
  170. ; Perform 32 bit integer modulo function
  171.     public    _ourlmod
  172. _ourlmod proc    near
  173.     push    bp
  174.     mov    bp,sp
  175.     push    bx
  176.     mov    ax,[bp+4+0]        ; top lower 16 bits
  177.     mov    dx,[bp+4+2]        ; top upper 16 bits
  178.     mov    bx,[bp+4+4]        ; bottom
  179.     or    bx,bx            ; zero?
  180.     jz    outlmo1            ; z = yes divide by 2^16 and quit
  181.     div    bx
  182. outlmo1:mov    ax,dx            ; return remainder in ax
  183.     pop    bx
  184.     pop    bp
  185.     ret
  186. _ourlmod endp
  187.  
  188. ; int ourldiv(long top, int bottom)
  189. ; Perform 32 bit integer division of 32 bit quotient by 16 bit divisor
  190.     public    _ourldiv
  191. _ourldiv proc    near
  192.     push    bp
  193.     mov    bp,sp
  194.     push    bx
  195.     mov    ax,[bp+4+0]        ; top lower 16 bits
  196.     mov    dx,[bp+4+2]        ; top upper 16 bits
  197.     mov    bx,[bp+4+4]        ; bottom
  198.     cmp    dx,bx            ; about to overflow?
  199.     jae    ourldiv1        ; ae = yes, return 0xffffh
  200.     div    bx
  201.     xor    dx,dx            ; clear remainder (high order ret)
  202.     pop    bx
  203.     pop    bp            ; quotient is returned in dx:ax
  204.     ret
  205. ourldiv1:mov    ax,0ffffh        ; overflow indication
  206.     xor    dx,dx            ; clear high order
  207.     pop    bx
  208.     pop    bp
  209.     ret
  210. _ourldiv endp
  211.  
  212. ; long ourlmul(long top, int bottom)
  213. ; Perform 32 bit integer multiplication of 32 bit multiplicand by 16 bit mult
  214.     public    _ourlmul
  215. _ourlmul proc    near
  216.     push    bp
  217.     mov    bp,sp
  218.     push    bx
  219.     push    cx
  220.     mov    ax,[bp+4+2]        ; top upper 16 bits
  221.     mov    bx,[bp+4+4]        ; bottom
  222.     mul    bx
  223.     mov    cx,ax            ; save product (no overflow noted)
  224.     mov    ax,[bp+4+0]        ; top lower 16 bits
  225.     mul    bx
  226.     adc    dx,cx            ; new upper 16 bits
  227.     pop    cx
  228.     pop    bx
  229.     mov    sp,bp
  230.     pop    bp            ; long product is returned in dx:ax
  231.     ret
  232. _ourlmul endp
  233.  
  234. ; void * bcopy(src, dest, count)
  235. ; void *dest, *src;
  236. ; size_t count;
  237. ; copy count bytes from src to dest
  238.     public    _bcopy
  239. _bcopy proc    near
  240.     push    bp
  241.     mov    bp,sp
  242.     push    es
  243.     push    si
  244.     push    di
  245.     push    cx
  246.     mov    ax,ds            ; set to same data segment
  247.     mov    es,ax
  248.     mov    si,[bp+4+0]        ; offset of source
  249.     mov    di,[bp+4+2]        ; offset of destination
  250.     mov    cx,[bp+4+4]        ; count
  251.     cld
  252.     push    di            ; push dest address for return
  253.     jcxz    bcopy2            ; z = nothing to copy
  254.     or    di,di            ; is destination NULL?
  255.     jz    bcopy2            ; z = yes, don't do a thing
  256.     cmp    si,di            ; is source after destination?
  257.     ja    bcopy1            ; a = yes, no overlap problem
  258.     je    bcopy2            ; e = same place, do nothing
  259.     add    di,cx            ; start at the ends
  260.     dec    di
  261.     add    si,cx
  262.     dec    si
  263.     std                ; work backward
  264. bcopy1:    rep    movsb
  265. bcopy2:    pop    ax            ; recover return destination
  266.     cld
  267.     pop    cx
  268.     pop    di
  269.     pop    si
  270.     pop    es
  271.     mov    sp,bp
  272.     pop    bp
  273.     ret
  274. _bcopy endp
  275.  
  276. ; void * memset(dest, c, count)
  277. ; void *dest;
  278. ; char c;
  279. ; size_t count;
  280. ; Store count copies of byte c in destination area dest
  281.     public    _memset
  282. _memset    proc    near
  283.     push    bp
  284.     mov    bp,sp
  285.     push    es
  286.     push    di
  287.     push    cx
  288.     mov    ax,ds            ; setup data segment
  289.     mov    es,ax
  290.     mov    di,[bp+4+0]        ; offset of destination
  291.     or    di,di            ; is it NULL?
  292.     jz    memset1            ; z = yes, don't do a thing
  293.     push    di            ; save dest for return
  294.     mov    al,[bp+4+2]        ; byte of character c
  295.     mov    ah,al
  296.     mov    cx,[bp+4+4]        ; count
  297.     jcxz    memset1            ; z = do nothing
  298.     cld
  299.     shr    cx,1
  300.     jnc    memset2
  301.     stosb
  302. memset2:rep    stosw
  303.     pop    ax            ; return pointer to destination
  304. memset1:pop    cx
  305.     pop    di
  306.     pop    es
  307.     mov    sp,bp
  308.     pop    bp
  309.     ret
  310. _memset    endp
  311.  
  312. ;  Timer routines - use set_*timeout to receive a clock value which
  313. ;                   can later be tested by calling chk_timeout with
  314. ;                   that clock value to determine if a timeout has
  315. ;                   occurred.  chk_timeout returns 0 if NOT timed out.
  316. ;  Usage:   long set_timeout( int seconds );
  317. ;           long set_ttimeout( int bios_ticks );
  318. ;           int chk_timeout( long value );
  319. ;
  320. ;  (c) 1990 University of Waterloo,
  321. ;           Faculty of Engineering,
  322. ;           Engineering Microcomputer Network Development Office
  323. ;  version
  324. ;    0.1    7-Nov -1990   E. P. Engelke
  325.  
  326.     public    _set_ttimeout
  327. _set_ttimeout proc    near
  328.     push    bp
  329.     mov    bp,sp
  330. ;[HF]    push    es
  331. ;[HF]        xor     ax,ax
  332. ;[HF]        cwd
  333. ;[HF]        mov     es,ax
  334. ;[HF]        mov     ax,[bp+4+0]        ; initial Bios clock ticks
  335. ;[HF]    pushf                ; critical section
  336. ;[HF]    cli
  337. ;[HF]        add     ax,es:[BIOSCLK+0];
  338. ;[HF]        adc     dx,es:[BIOSCLK+2];
  339. ;[HF]    popf                ; end critical section
  340. ;[HF]    pop    es
  341.     call    _realclock        ;[HF]
  342.     add    ax,[bp+4+0]        ;[HF]
  343.     adc    dx,0            ;[HF]
  344.     pop    bp
  345.     ret
  346. _set_ttimeout endp
  347.  
  348.     public    _set_timeout
  349. _set_timeout proc near
  350.     push    bp
  351.     mov    bp,sp
  352. ;[HF]    push    es
  353. ;[HF]    push    cx
  354. ;[HF]    xor    ax,ax            ; reference low memory
  355. ;[HF]    mov    es,ax
  356. ;[HF]    mov    ax,[bp+4+0]        ; seconds
  357. ;[HF]    xor    dx,dx
  358. ;[HF]    mov    cx,1165
  359. ;[HF]    mul    cx            ; 1165/64 = 18.203...
  360. ;[HF]    mov    cx,6
  361. ;[HF]tmp:    shr    dx,1
  362. ;[HF]    rcr    ax,1
  363. ;[HF]    loop    tmp
  364. ;[HF]    pushf                ; critical section
  365. ;[HF]    cli
  366. ;[HF]    add    ax,es:[BIOSCLK+0]
  367. ;[HF]    adc    dx,es:[BIOSCLK+2]
  368. ;[HF]    popf                ; end critical section
  369. ;[HF]    pop    cx
  370. ;[HF]    pop    es
  371.     push    bx            ;[HF]
  372.     push    cx            ;[HF]
  373.     mov    ax,[bp+4+0]        ;[HF]
  374.     xor    dx,dx            ;[HF]
  375.     mov    cx,25            ;[HF] sec -> tic (40 msec)
  376.     mul    cx            ;[HF] dx:ax = tic counts
  377.     mov    bx,ax            ;[HF]
  378.     mov    cx,dx            ;[HF] save dx:ax -> cx:bx
  379.     call    _realclock        ;[HF] get current time in tic
  380.     add    ax,bx            ;[HF] add it (long word)
  381.     adc    dx,cx            ;[HF]
  382.     pop    cx            ;[HF]
  383.     pop    bx            ;[HF]
  384.     pop    bp
  385.     ret
  386. _set_timeout    endp
  387.  
  388.     public    _chk_timeout
  389. _chk_timeout    proc near
  390.     push    bp
  391.     mov    bp,sp
  392.     push    cx
  393. ;[HF]    push    es
  394. ;[HF]    xor    ax,ax
  395. ;[HF]    mov    es,ax
  396. ;[HF]    pushf                ; critical section
  397. ;[HF]    cli
  398. ;[HF]    mov    cx,es:[BIOSCLK+0]
  399. ;[HF]    mov    bx,es:[BIOSCLK+2]
  400. ;[HF]    popf                ; end critical section
  401. ;[HF]    pop    es
  402.     call    _realclock        ;[HF] get current time (dx:ax)
  403.     mov    cx,ax            ;[HF] copy dx:ax -> bx:cx
  404.     mov    bx,dx            ;[HF]
  405.     mov    ax,[bp+4+0]        ; timeout value
  406.     mov    dx,[bp+4+2]
  407.     cmp    dx,bx            ; if timeout < clock, has expired
  408.         jb      ret_tru
  409.     cmp    ax,cx
  410.         jbe    ret_tru
  411.                     ; may have gone over by one day
  412.     sub    ax,LO_MAX
  413.     sbb    dx,HI_MAX
  414.     jc    ret_fal            ; c = nope, timeout is today
  415.                     ; test timeout new values
  416.     cmp    dx,bx
  417.     jb    ret_tru
  418.     cmp    ax,cx
  419.     ja    ret_fal
  420. ret_tru:mov    ax,1            ; say have timed out
  421.     pop    cx
  422.     pop    bp
  423.     ret
  424.  
  425. ret_fal:xor    ax,ax            ; say have not timed out
  426.     pop    cx
  427.     pop    bp
  428.     ret
  429. _chk_timeout    endp
  430.  
  431. ; unsigned long realclock(void)
  432. ;[HF]    public    _realclock
  433. ;[HF]_realclock    proc near        ; get Bios time of day dword
  434. ;[HF]    push    es
  435. ;[HF]    xor    ax,ax            ; reference low memory
  436. ;[HF]    mov    es,ax
  437. ;[HF]    pushf                ; critical section
  438. ;[HF]    cli
  439. ;[HF]    mov    ax,es:[BIOSCLK+0]    ; return Bios time of day tick count
  440. ;[HF]    mov    dx,es:[BIOSCLK+2]
  441. ;[HF]    popf                ; end critical section
  442. ;[HF]    pop    es
  443. ;[HF]    ret
  444. ;[HF]_realclock endp
  445.  
  446. ; void _chkstk()
  447. ; Stack checker
  448. ; {
  449. ;  ;
  450. ; }
  451.     public    __chkstk, __aNchkstk
  452. __chkstk proc    near            ; MSC v5.1
  453. __aNchkstk equ    this byte        ; MSC v6.00
  454.     pop    bx            ; pop return address
  455.     sub    sp,ax            ; down adjust stack pointer
  456.     jmp    bx            ; return the no-stack way
  457. __chkstk endp
  458.  
  459.  
  460. ; void 
  461. ; outch(char ch)
  462. ; Sends character to the screen via the msgbuf buffer if operating at
  463. ; interrupt level, or via DOS if operating at task level.
  464.     public    _outch
  465. _outch    proc    near
  466.     push    bp
  467.     mov    bp,sp
  468.     push    ax
  469.     push    bx
  470.     cmp    _display_mode,0        ; quiet screen?
  471.     je    outch3            ; e = yes
  472.     mov    al,[bp+4]        ; get the character
  473.     cmp    _doslevel,0        ; at DOS task level?
  474.     je    outch1            ; e = no
  475.     mov    ah,conout        ; use DOS
  476.     push    dx
  477.     mov    dl,al
  478.     int    dos
  479.     pop    dx
  480.     jmp    short outch3
  481. outch1:    cmp    _msgcnt,256        ; is buffer filled?
  482.     ja    outch3            ; a = yes, discard this byte
  483.     mov    bx,_msgcnt
  484.     mov    _msgbuf[bx],al
  485.     inc    _msgcnt
  486. outch3:    pop    bx
  487.     pop    ax
  488.     mov    sp,bp
  489.     pop    bp
  490.     ret
  491. _outch    endp
  492.  
  493.  
  494. ; void 
  495. ; outsn(char * string, int count)
  496. ; display counted string
  497.     public    _outsn
  498. _outsn    proc    near
  499.     push    bp
  500.     mov    bp,sp
  501.     push    ax
  502.     push    si
  503.     mov    si,[bp+4]        ; string address
  504.     mov    cx,[bp+4+2]        ; string length
  505.     cld
  506. outsn1:    lodsb
  507.     or    al,al
  508.         jz      outsn2
  509.     push    ax            ; push arg
  510.         call    _outch
  511.     pop    ax            ; clean stack
  512.     loop    outsn1
  513. outsn2:    pop    si
  514.     pop    ax
  515.     mov    sp,bp
  516.     pop    bp
  517.     ret
  518. _outsn    endp
  519.  
  520. ; void 
  521. ; outs(char * string)
  522. ; display asciiz string
  523.     public    _outs
  524. _outs    proc    near
  525.     push    bp
  526.     mov    bp,sp
  527.     push    ax
  528.     push    si
  529.     mov    si,[bp+4]        ; asciiz string address
  530.     cld
  531. outs1:    lodsb
  532.         or      al,al            ; terminator ?
  533.     jz     outs2            ; z = yes
  534.     push    ax            ; push arg
  535.     call    _outch
  536.     pop    ax            ; clean stack
  537.     jmp    short outs1
  538. outs2:    pop    si
  539.     pop    ax
  540.     mov    sp,bp
  541.     pop    bp
  542.     ret
  543. _outs    endp
  544.  
  545. ; void
  546. ; outhex(char c)
  547. ; display char in hex
  548.     public _outhex
  549. _outhex    proc    near
  550.     push    bp
  551.     mov    bp,sp
  552.     push    ax
  553.         mov     ax,[bp+4]        ; incoming character
  554.         mov     cl, 4
  555.         shr     al, cl
  556.         call    outh
  557.         mov     ax,[bp+4]
  558.         call    outh
  559.     pop    ax
  560.     mov    sp,bp
  561.     pop    bp
  562.     ret
  563.  
  564. ; worker for outhex
  565. outh    proc    near
  566.     and     al,0fh
  567.         cmp     al,9
  568.         jbe     outh1
  569.         add     al,'A' - '9' - 1
  570. outh1:    add     al,'0'
  571.         push    ax
  572.         call    _outch
  573.         pop     ax
  574.         ret
  575. outh    endp
  576. _outhex    endp
  577.  
  578. ; output a string of hex chars
  579. ; void
  580. ; outhexes(char * string, int count )
  581.     public    _outhexes
  582. _outhexes proc    near
  583.     push    bp
  584.     mov    bp,sp
  585.     push    ax
  586.     push    si            ; preserve such things
  587.     mov    si,[bp+4]        ; get string pointer
  588.     mov    cx,[bp+4+2]        ; get char count
  589.     cld
  590. outhexs1:lodsb                ; read a byte
  591.     push    cx            ; save loop counter
  592.     push    ax
  593.     call    _outhex            ; display as hex pair
  594.     add    sp,2            ; clean stack
  595.     pop    cx
  596.     loop    outhexs1        ; do count's worth
  597.     pop    si
  598.     pop    ax
  599.     mov    sp,bp
  600.     pop    bp
  601.     ret
  602. _outhexes endp
  603. _TEXT    ends
  604.         end
  605.