home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / ct22d / tskprf.asm < prev    next >
Encoding:
Assembly Source File  |  1993-03-03  |  34.0 KB  |  2,011 lines

  1. ;
  2. ;    --- Version 2.2 93-03-03 17:17 ---
  3. ;
  4. ;    CTask - Printf replacement
  5. ;
  6. ;    Public Domain Software written by
  7. ;        Thomas Wagner
  8. ;        Ferrari electronic Gmbh
  9. ;        Beusselstrasse 27
  10. ;        D-1000 Berlin 21
  11. ;        Germany
  12. ;
  13. ;    This file is new with Version 2.1. 
  14. ;
  15. ;    This module contains substitutes for the standard C printf
  16. ;    family formatting routines. It uses no helper routines, and
  17. ;    thus can be called from Assembler programs and is model
  18. ;    independent. It is smaller and faster (up to 5 times) than
  19. ;    the standard C printf, and supports all output options except 
  20. ;    floating point and some esoteric flags. 
  21. ;
  22. ;    Also supported is output to the second monitor in a dual-
  23. ;    monitor system.
  24. ;
  25. ;    The routines in this module are reentrant in the sense that nothing
  26. ;    will crash if routines are re-entered concurrently. No protection
  27. ;    against a garbled screen is built in, however, so external
  28. ;    resource request/release calls are still necessary to make
  29. ;    sure output to the display stays in proper order. The sprintf
  30. ;    routines need no protection.
  31. ;
  32. ;    No CTask specific stuff is used to allow use of the routines
  33. ;    even when CTask is not installed.
  34. ;
  35. ;    Note that the tsk_fprintf routine takes a different parameter
  36. ;    than the standard fprintf. You have to pass an integer file 
  37. ;    handle, not a FILE *.
  38. ;
  39. ;---------------------------------------------------------------------------
  40. ;
  41. ;    Conversion format:
  42. ;
  43. ;        % [flags] [width] [.precision] [indirection] [size] conversion
  44. ;
  45. ;    Flags supported:
  46. ;
  47. ;        -    Left-justify output
  48. ;
  49. ;        the +, blank, and # flags are not supported.
  50. ;
  51. ;    Width and precision are handled like in standard C, i.e.
  52. ;    the * specification is supported. The only exception is
  53. ;    that numeric output will not be suppressed for an explicit
  54. ;    0 precision.
  55. ;
  56. ;    Size modifiers supported:
  57. ;
  58. ;        N    Near pointer
  59. ;        F    Far pointer
  60. ;        h    Short
  61. ;        l    Long
  62. ;        H    Byte-sized operand in parameter list
  63. ;
  64. ;    Conversion characters supported:
  65. ;
  66. ;        c    single character
  67. ;        s    zero-terminated string
  68. ;        x    unsigned hex word, a-f
  69. ;        X    unsigned hex word, A-F
  70. ;        d    signed decimal int
  71. ;        u    unsigned decimal int
  72. ;        p    hex pointer, a-f
  73. ;        P    hex pointer, A-F
  74. ;        n    store converted length at int pointer
  75. ;
  76. ;    In addition, two indirection operators are supported. Both
  77. ;    can be repeated, but they should not normally be mixed.
  78. ;
  79. ;        ^    Near indirection (param is DS-based near pointer)
  80. ;        @    Far indirection (param is far pointer)
  81. ;
  82. ;    Example:
  83. ;        %d    Displays the word parameter
  84. ;        %^d    Displays the word at DS:parameter
  85. ;        %@d    Displays the word at the far address 
  86. ;            given as parameter
  87. ;
  88. ;---------------------------------------------------------------------------
  89. ;
  90.     name    tskprf
  91. ;
  92.     include    tsk.mac
  93. ;
  94.     .tsk_model
  95. ;
  96.     public    tsk_regen        ; far pointer to regen buffer
  97.     public    tsk_regen_s        ; regen buffer segment
  98.     public    tsk_regen_o        ; current regen buffer offset
  99.     public    tsk_disport        ; display controller I/O port
  100.     public    tsk_comport        ; comm I/O port
  101. ;
  102.     Pubfunc    tsk_putc        ; put char to screen
  103.     Pubfunc    tsk_puts        ; put string to screen
  104.     Pubfunc    tsk_rputc        ; put char to regen
  105.     Pubfunc    tsk_rputs        ; put string to regen
  106.     Pubfunc    tsk_cputc        ; put char to comm port
  107.     Pubfunc    tsk_cputs        ; put string to comm port
  108. ;
  109.     CPubfnc    tsk_printf        ; print to screen
  110.     Pubfunc    tsk_vprintf        ; print to screen with arg pointer
  111.     CPubfnc    tsk_fprintf        ; print to file handle
  112.     Pubfunc    tsk_vfprintf        ; print to file handle w. argptr
  113.     CPubfnc    tsk_sprintf        ; print to string
  114.     Pubfunc    tsk_vsprintf        ; print to string w. argptr
  115.     CPubfnc    tsk_rprintf        ; print to regen
  116.     Pubfunc    tsk_vrprintf        ; print to regen w. argptr
  117.     CPubfnc    tsk_cprintf        ; print to comm port
  118.     Pubfunc    tsk_vcprintf        ; print to comm port w. argptr
  119. ;
  120.     Pubfunc    tsk_setpos        ; set regen cursor position
  121.     Pubfunc    tsk_set_regen        ; set regen address
  122.     Pubfunc    tsk_set_dualdis        ; init secondary monitor
  123.     Pubfunc    tsk_set_currdis        ; init primary monitor
  124.     Pubfunc    tsk_set_colour        ; init colour monitor
  125.     Pubfunc    tsk_set_mono        ; init mono monitor
  126.     Pubfunc    tsk_set_attr        ; set display attribute
  127.     Pubfunc    tsk_set_clreol        ; CR clears to EOL when set
  128. ;
  129.     Pubfunc    tsk_cprint_init        ; init comm port
  130.     Pubfunc    tsk_cprint_getc        ; get comm port char (no wait)
  131.     Pubfunc    tsk_cprint_waitc    ; get comm port char (with wait)
  132. ;
  133. ;
  134. ; Configuration options:
  135. ;
  136. ; FILE_BUFSIZE    Is the local buffer size for tsk_fprintf and tsk_vfprintf.
  137. ;        The buffer is allocated on the stack, so it should
  138. ;        not be chosen too large to avoid stack overflows.
  139. ;        It must be a power of 2, and less than or equal to 256.
  140. ;
  141. FILE_BUFSIZE    =    64 - 1
  142. ;
  143. ;
  144. ; DFLT_FAR    If set, pointers (%p and %n) and strings (%s) are assumed
  145. ;        far by default, near pointers must use the N size
  146. ;        modifiers.
  147. ;        If clear, the default is near, so the F size modifier
  148. ;        must be used for far pointers.
  149. ;
  150. DFLT_FAR    =    1    ; by default, pointers and strings are Far
  151. ;
  152. ;
  153. ;    The local variables used in the main formatter.
  154. ;    Those variables are relative to BP, and are accessed by
  155. ;    several routines in this module (the local routines do not
  156. ;    use the standard stack discipline, they should be viewed as
  157. ;    Pascal-like nested routines within the scope of @disprintf).
  158. ;
  159. dislocrec    struc
  160. convbuf    db    17 dup(?)    ; conversion buffer (hex/dec)
  161. prflags    db    ?        ; formatting flags
  162. prhexch    db    ?        ; Hex format offset for upper/lower case
  163. prfcnt    db    ?        ; file output counter
  164. procnt    dw    ?        ; output char counter
  165. prwidth    dw    ?        ; field width
  166. prec    dw    ?        ; precision
  167. arglen    dw    ?        ; argument length in bytes
  168. prproc    dw    ?        ; output routine offset
  169. prargbx    dw    ?        ; output routine BX argument
  170. prargdx    dw    ?        ; output routine DX argument
  171. dislocrec    ends
  172. ;
  173. ;    formatting flags
  174. ;
  175. F_LONGARG    =    01h    ; argument is long/far (4 bytes)
  176. F_SHORTARG    =    02h    ; argument is single byte
  177. F_PADZERO    =    04h    ; pad with zeros
  178. F_LEFTADJ    =    08h    ; left adjust output
  179. F_SIGNED    =    10h    ; signed number
  180. F_WIDTH        =    20h    ; width is valid
  181. F_PREC        =    40h    ; precision is valid
  182. F_INDIR        =    80h    ; indirection was used
  183. ;
  184. XON    =    11h
  185. XOFF    =    13h
  186. ;
  187. biosdata    segment at 40h
  188.         org    4ah
  189. bios_cols    dw    ?
  190.         org    63h
  191. bios_chipad    dw    ?
  192.         org    84h
  193. bios_rows    db    ?
  194. biosdata    ends
  195. ;
  196.     .tsk_data
  197. ;
  198. tsk_regen    label    dword
  199. tsk_regen_o    dw    0
  200. tsk_regen_s    dw    0b000h        ; default mono screen
  201. ;
  202. tsk_disport    dw    3b4h        ; default mono 6845
  203. tsk_attrib    db    07h        ; default white on black
  204. ;
  205. sc_clreol    db    0        ; default is don't clear
  206. ;
  207. sc_cols    dw    80 * 2
  208. sc_end    dw    25 * 80 * 2
  209. ;
  210. tsk_comport    dw    0
  211. tsk_combuf    db    16 dup(0)
  212. tsk_comiptr    dw    0
  213. tsk_comoptr    dw    0
  214. tsk_comcnt    dw    0
  215. tsk_comxoff    db    XON
  216. ;
  217. sc_proc    dw    offset @nodis
  218. ;
  219.     .tsk_edata
  220.     .tsk_code
  221. ;
  222. ctdataseg    dw    @CTASK_DATA
  223. ;
  224. ;    setcsr - local routine to set the cursor to the current position
  225. ;         on the regen display.
  226. ;
  227. @setcsr    proc    near
  228. ;
  229.     push    dx
  230.     mov    dx,tsk_disport
  231.     or    dx,dx
  232.     jz    no_cursor
  233.     mov    al,0eh
  234.     out    dx,al
  235.     jmp    $+2
  236.     mov    ax,tsk_regen_o
  237.     shr    ax,1
  238.     xchg    ah,al
  239.     inc    dx
  240.     out    dx,al
  241.     jmp    $+2
  242.     dec    dx
  243.     mov    al,0fh
  244.     out    dx,al
  245.     jmp    $+2
  246.     mov    al,ah
  247.     inc    dx
  248.     out    dx,al
  249. ;
  250. no_cursor:
  251.     pop    dx
  252.     ret
  253. ;
  254. @setcsr    endp
  255. ;
  256. ;
  257. ; disregen - local routine to write char directly into the display 
  258. ;    regen buffer. The following control characters 
  259. ;    are handled special:
  260. ;        08 \b (BS)      backspace one position (no erase)
  261. ;        09 \t (TAB)    tab to next 8th column
  262. ;        0D \r (CR)    carriage return
  263. ;        0A \n (LF)    line feed
  264. ;                Note: the printf routines will not pass
  265. ;                a single line feed unchanged.
  266. ;        0B \v (VT)    clear to end of line
  267. ;        0C \f (FF)    clear to end of screen
  268. ;
  269. ;
  270. ;    Entry:    AL = char to display
  271. ;    Uses:    AX
  272. ;
  273. @disregen    proc    near
  274. ;
  275.     push    ds
  276.     mov    ds,cs:ctdataseg        ; allow access to local vars
  277. ;
  278. ;    First, check for control characters
  279. ;
  280.     cmp    al,0eh            ; 08-0D are special
  281.     jae    no_special
  282.     cmp    al,08h
  283.     jb    no_special
  284.     je    dis_bs            ; 08 = Backspace
  285.     cmp    al,0ah
  286.     jb    dis_tab            ; 09 = Tab
  287.     je    dis_lf            ; 0A = Linefeed
  288.     cmp    al,0ch
  289.     jb    dis_vt            ; 0B = Clear to eol
  290.     jne    dis_cr            ; 0D = Carriage return
  291.     jmp    dis_ff            ; 0C = Clear screen
  292. ;
  293. ;    Carriage return
  294. ;
  295. dis_cr:
  296.     cmp    sc_clreol,0
  297.     jne    dis_vt
  298. discr1:
  299.     push    dx
  300.     cli
  301.     mov    ax,tsk_regen_o        ; current offset
  302.     xor    dx,dx            ; make into doubleword
  303.     div    sc_cols            ; divide by number of columns
  304.     sub    tsk_regen_o,dx        ; subtract remainder
  305.     sti
  306.     pop    dx
  307.     jmp    disreg_end
  308. ;
  309. no_special:
  310.     jmp    disregen_ok
  311. ;
  312. ;    Backspace
  313. ;
  314. dis_bs:
  315.     cli
  316.     cmp    tsk_regen_o,0        ; Handle wraparound
  317.     je    dis_bs2
  318.     sub    tsk_regen_o,2
  319.     sti
  320.     jmp    disreg_end
  321. dis_bs2:
  322.     mov    ax,sc_end        ; Wrap to end of screen
  323.     sub    ax,2
  324.     mov    tsk_regen_o,ax
  325.     sti
  326.     jmp    disreg_end
  327. ;
  328. ;    Tab
  329. ;
  330. dis_tab:
  331.     cli
  332.     mov    ax,tsk_regen_o
  333.     add    ax,16
  334.     and    ax,0fff0h        ; Tabs every 8 cols
  335.     mov    tsk_regen_o,ax
  336.     sti
  337.     jmp    disreg_end
  338. ;
  339. ;    Linefeed
  340. ;
  341. dis_lf:
  342.     cli
  343.     mov    ax,tsk_regen_o
  344.     add    ax,sc_cols        ; Add one line
  345.     mov    tsk_regen_o,ax
  346.     sti
  347.     cmp    ax,sc_end        ; did we get past the end?
  348.     jae    dislf_sc
  349.     jmp    disreg_end
  350. ;
  351. dislf_sc:
  352.     push    es            ; then setup regs and go scroll
  353.     push    di
  354.     mov    es,tsk_regen_s
  355.     mov    di,ax
  356.     jmp    short disreg_scroll
  357. ;
  358. ;    Vertical tab (clear to end of line)
  359. ;
  360. dis_vt:
  361.     push    es
  362.     push    di
  363.     push    cx
  364.     push    ax
  365.     les    di,tsk_regen
  366.     mov    cx,sc_cols        ; number of columns
  367.     mov    ax,di            ; current offset
  368.     xor    dx,dx            ; make into doubleword
  369.     div    cx            ; divide by number of columns
  370.     sub    cx,dx            ; subtract remainder
  371.     shr    cx,1            ; number of words
  372.     mov    ah,tsk_attrib
  373.     mov    al,' '
  374.     rep stosw
  375.     pop    ax
  376.     pop    cx
  377.     cmp    al,0dh
  378.     jne    disreg_ok
  379.     pop    di
  380.     pop    es
  381.     jmp    discr1
  382. ;
  383. ;    Formfeed (clear to end of screen)
  384. ;
  385. dis_ff:
  386.     push    es
  387.     push    di
  388.     push    cx
  389.     les    di,tsk_regen
  390.     mov    cx,sc_end        ; total number of chars
  391.     sub    cx,di            ; minus current offset
  392.     shr    cx,1            ; number of words
  393.     mov    ah,tsk_attrib
  394.     mov    al,' '
  395.     rep stosw
  396.     pop    cx
  397.     jmp    short disreg_ok
  398. ;
  399. ;    Normal character output
  400. ;
  401. disregen_ok:
  402.     push    es
  403.     push    di
  404.     cli
  405.     les    di,tsk_regen        ; load current regen buffer addr
  406.     mov    ah,tsk_attrib
  407.     stosw
  408.     mov    tsk_regen_o,di        ; new offset
  409.     sti
  410.     cmp    di,sc_end        ; past the end?
  411.     jb    disreg_ok
  412. ;
  413. ;    Scroll up one line
  414. ;
  415. disreg_scroll:
  416.     sub    di,sc_cols        ; one line up
  417.     mov    tsk_regen_o,di
  418.     push    cx
  419.     push    si
  420.     push    ds
  421.     mov    si,sc_cols        ; second line
  422.     mov    cx,sc_end
  423.     sub    cx,si            ; screen len minus one line
  424.     shr    cx,1            ; no. of words
  425.     mov    di,es
  426.     mov    ds,di
  427.     mov    di,0            ; first line
  428.     rep movsw
  429.     pop    ds
  430. ;
  431.     mov    cx,sc_cols        ; number of columns
  432.     shr    cx,1            ; number of words
  433.     mov    ah,tsk_attrib
  434.     mov    al,' '
  435.     rep stosw
  436. ;
  437.     pop    si
  438.     pop    cx
  439. ;
  440. disreg_ok:
  441.     pop    di
  442.     pop    es
  443. ;
  444. disreg_end:
  445.     call    @setcsr
  446.     pop    ds
  447.     ret
  448. ;
  449. @disregen    endp
  450. ;
  451. ;
  452. ; nodis - local dummy output routine.
  453. ;    This routine is called if the regen buffer adddress has not
  454. ;    been set, or if there is no secondary monitor.
  455. ;
  456. @nodis    proc    near
  457.     ret
  458. @nodis    endp
  459. ;
  460. ;
  461. ; dischar - local screen output routine.
  462. ;    This routine uses INT 10 TTY output to display the character.
  463. ;    Entry:    AL = char to display
  464. ;    Uses:    AX
  465. ;
  466. @dischar    proc    near
  467.     IF    IBM
  468.     push    bx
  469.     push    bp
  470.         mov    bl,7
  471.         mov     ah,14
  472.     int    10h
  473.     pop    bp
  474.     pop    bx
  475.     ELSE
  476.     push    dx
  477.     mov    dl,al
  478.     mov    ah,2
  479.     int    21h
  480.     pop    dx
  481.     ENDIF
  482.     ret
  483. @dischar    endp
  484. ;
  485. ;
  486. ; filechar - local file output routine.
  487. ;    Write character to file
  488. ;    Entry:    AL = char to display
  489. ;    Uses:    AX
  490. ;
  491. @filechar    proc    near
  492.     push    bx
  493.     push    si
  494.     mov    si,prargdx[bp]
  495.     mov    bl,ss:[si]
  496.     xor    bh,bh
  497.     inc    bx
  498.     mov    ss:[si+bx],al
  499.     cmp    bx,FILE_BUFSIZE - 1
  500.     jb    fcharend
  501.     xchg    si,dx
  502.     inc    dx
  503.     push    ds
  504.     push    ax
  505.     push    cx
  506.     mov    cx,bx
  507.     mov    bx,prargbx[bp]
  508.     mov    ax,ss
  509.     mov    ds,ax
  510.     mov    ah,40h
  511.     int    21h
  512.     pop    cx
  513.     pop    ax
  514.     pop    ds
  515.     xchg    dx,si
  516.     dec    si
  517.     xor    bl,bl
  518. fcharend:
  519.     mov    ss:[si],bl
  520.     pop    si
  521.     pop    bx
  522.     ret
  523. @filechar    endp
  524. ;
  525. ;
  526. @poll_com    proc    near
  527. poll_loop:
  528.     add    dl,5
  529.     in    al,dx
  530.     sub    dl,5
  531.     and    al,1
  532.     jz    pollc_end
  533.     in    al,dx
  534.     cmp    al,XON
  535.     je    pollc_xon
  536.     cmp    al,XOFF
  537.     je    pollc_xon
  538.     push    bx
  539.     mov    bx,tsk_comiptr
  540.     mov    tsk_combuf[bx],al
  541.     cmp    tsk_comcnt,16
  542.     je    pollc_end1
  543.     inc    bx
  544.     and    bx,0fh
  545.     mov    tsk_comiptr,bx
  546.     inc    tsk_comcnt
  547. pollc_end1:
  548.     pop    bx
  549.     jmp    poll_loop
  550. pollc_end:
  551.     ret
  552. ;
  553. pollc_xon:
  554.     mov    tsk_comxoff,al
  555.     jmp    poll_loop
  556. ;
  557. @poll_com    endp
  558. ;
  559. ;
  560. ; comchar - local comm output routine.
  561. ;    Write character to comm port
  562. ;    Entry:    AL = char to display
  563. ;    Uses:    AX
  564. ;
  565. @comchar    proc    near
  566.     push    ds
  567.     mov    ds,cs:ctdataseg        ; allow access to local vars
  568.     push    dx
  569.     mov    ah,al
  570. ;
  571.     mov    dx,tsk_comport
  572.     or    dx,dx
  573.     jz    cch_end
  574. cch_wxon:
  575.     call    @poll_com
  576.     cmp    tsk_comxoff,XOFF
  577.     je    cch_wxon
  578.     add    dx,5
  579. cch_wait:
  580.     in    al,dx
  581.     and    al,20h            ; THRE
  582.     jz    cch_wait
  583.     mov    dx,tsk_comport
  584.     mov    al,ah
  585.     out    dx,al
  586. ;
  587. cch_end:
  588.     pop    dx
  589.     pop    ds
  590.     ret
  591. @comchar    endp
  592. ;
  593. ;
  594. ; stringchar - local string output routine.
  595. ;    Entry:    AL = char to write to string
  596. ;        prargbx/dx set to point to destination
  597. ;
  598. ;    Uses:    AX
  599. ;
  600. @stringchar        proc    near
  601.     push    di
  602.     push    es
  603.     les    di,dword ptr prargbx[bp]
  604.     stosb
  605.     mov    prargbx[bp],di
  606.     pop    es
  607.     pop    di
  608.     ret
  609. @stringchar        endp
  610. ;
  611. ;
  612. ; hexdigbp - put hex digit in AL to SS:DI, increment DI and BL.
  613. ;
  614. @hexdigbp    proc    near
  615. ;
  616.     push    ax
  617.         and    al,0fh
  618.     add    al,'0'
  619.         cmp    al,'9'
  620.         jbe    hexbp1
  621.         add    al,prhexch[bp]
  622. hexbp1:
  623.     mov    byte ptr ss:[di],al
  624.     inc    di
  625.     inc    bl
  626.     pop    ax
  627.     ret
  628. ;
  629. @hexdigbp    endp
  630. ;
  631. ;
  632. ;    hexconv - convert hex
  633. ;    Entry:    DX,AX = number
  634. ;        SS:DI = Buffer pointer
  635. ;    Exit:    BX    = converted length
  636. ;        SS:DI = string start + 1
  637. ;    Uses:    CX
  638. ;
  639. @hexconv    proc    near
  640.     xor    bl,bl
  641.     mov    cl,4
  642.     mov    bh,4
  643.     or    dx,dx
  644.     jnz    hchiword
  645. ;
  646. hclp1:
  647.     call    @hexdigbp
  648.     shr    ax,cl
  649.     jz    hcend
  650.     dec    bh
  651.     jnz    hclp1
  652. ;
  653. hcend:
  654.     xor    bh,bh
  655.     ret
  656. ;
  657. hchiword:
  658.     call    @hexdigbp
  659.     shr    ax,cl
  660.     dec    bh
  661.     jnz    hchiword
  662.     mov    ax,dx
  663.     mov    bh,4
  664.     jmp    hclp1
  665. ;
  666. @hexconv    endp
  667. ;
  668. ;
  669. ;    binconv - convert binary
  670. ;    Entry:    DX,AX = number
  671. ;        SS:DI = Buffer pointer
  672. ;    Exit:    BX    = converted length
  673. ;        SS:DI = string start + 1
  674. ;    Uses:    CX
  675. ;
  676. @binconv    proc    near
  677.     xor    bx,bx
  678.     mov    cx,16
  679. bclp:
  680.     push    ax
  681.         and    al,1
  682.     add    al,'0'
  683.     mov    byte ptr ss:[di],al
  684.     inc    di
  685.     inc    bx
  686.     pop    ax
  687.     shr    ax,1
  688.     jz    bcend
  689.     loop    bclp
  690. ;
  691. bcend:
  692.     ret
  693. ;
  694. @binconv    endp
  695. ;
  696. ;
  697. ;    decconv - convert decimal
  698. ;
  699. ;    Entry:    DX,AX = number
  700. ;        SS:DI = Buffer top pointer
  701. ;    Exit:    BX    = converted length
  702. ;        SS:DI = string start + 1
  703. ;    Uses:    CX
  704. ;
  705. @decconv    proc    near
  706.     xor    bx,bx
  707.     mov    cx,10
  708.     or    dx,dx
  709.     jnz    dchiword
  710. ;
  711. dclp1:
  712.     xor    dx,dx
  713.     div    cx
  714.     add    dl,'0'
  715.     mov    byte ptr ss:[di],dl
  716.     inc    di
  717.     inc    bx
  718.     or    ax,ax
  719.     jnz    dclp1
  720.     ret
  721. ;
  722. dchiword:
  723.     push    si
  724.     mov    si,dx
  725. ;
  726. dchilp:
  727.     xchg    ax,si
  728.     xor    dx,dx
  729.     div    cx
  730.     xchg    ax,si
  731.     div    cx
  732.     add    dl,'0'
  733.     mov    byte ptr ss:[di],dl
  734.     inc    di
  735.     inc    bx
  736.     or    si,si
  737.     jnz    dchilp
  738. ;
  739.     pop    si
  740.     jmp    dclp1
  741. ;
  742. @decconv    endp
  743. ;
  744. ;
  745. ; getint - read integer at DS:SI
  746. ;    Entry: AL = first char
  747. ;    Exit:  AX = integer
  748. ;    Uses:  BX,DX
  749. ;
  750. @getint    proc    near
  751. ;
  752.     and    ax,0fh
  753.     mov    bl,10
  754. getintlp:
  755.     xchg    ax,dx
  756.     lodsb
  757.     cmp    al,'0'
  758.     jb    getint_end
  759.     cmp    al,'9'
  760.     ja    getint_end
  761.     and    ax,0fh
  762.     xchg    ax,dx
  763.     mul    bl
  764.     add    ax,dx
  765.     jmp    getintlp
  766. ;
  767. getint_end:
  768.     dec    si
  769.     mov    ax,dx
  770.     ret
  771. ;
  772. @getint    endp
  773. ;
  774. ;
  775. ;    padleft - local routine to pad output on the left side.
  776. ;
  777. @padleft    proc    near
  778. ;
  779.     push    cx
  780.     push    dx
  781.     xor    dx,dx
  782.     test    prflags[bp],F_PREC
  783.     jz    padleft_noprec
  784.     cmp    bx,prec[bp]
  785.     jae    padleft_noprec
  786. ;
  787.     mov    dx,prec[bp]
  788.     sub    dx,bx
  789.     test    prflags[bp],F_WIDTH
  790.     jz    padleft_noprec
  791.     sub    prwidth[bp],dx
  792.     jnc    padleft_noprec
  793.     and    prflags[bp],NOT F_WIDTH
  794. ;
  795. padleft_noprec:
  796.     test    prflags[bp],F_LEFTADJ
  797.     jnz    padleft_end
  798.     test    prflags[bp],F_WIDTH
  799.     jz    padleft_end
  800.     cmp    bx,prwidth[bp]
  801.     jae    padleft_end
  802. ;
  803.     mov    cx,prwidth[bp]
  804.     sub    cx,bx
  805.     add    procnt[bp],cx
  806.     mov    al,' '
  807.     test    prflags[bp],F_PADZERO
  808.     jz    padleftlp
  809.     mov    al,'0'
  810. ;
  811. padleftlp:
  812.     push    ax
  813.     call    prproc[bp]
  814.     pop    ax
  815.     loop    padleftlp
  816. ;
  817. padleft_end:
  818.     mov    cx,dx
  819.     jcxz    padleft_exit
  820.     add    procnt[bp],cx
  821. ;
  822. padleftprec:
  823.     mov    al,'0'
  824.     call    prproc[bp]
  825.     loop    padleftprec
  826. ;
  827. padleft_exit:
  828.     pop    dx
  829.     pop    cx
  830.     ret
  831. ;
  832. @padleft    endp
  833. ;
  834. ;    padright - local routine to pad output on the right side
  835. ;
  836. @padright    proc    near
  837. ;
  838.     test    prflags[bp],F_LEFTADJ
  839.     jz    padright_end
  840.     test    prflags[bp],F_WIDTH
  841.     jz    padright_end
  842.     cmp    bx,prwidth[bp]
  843.     jae    padright_end
  844. ;
  845.     push    cx
  846.     mov    cx,prwidth[bp]
  847.     sub    cx,bx
  848.     add    procnt[bp],cx
  849. ;
  850. padrightlp:
  851.     mov    al,' '
  852.     call    prproc[bp]
  853.     loop    padrightlp
  854.     pop    cx
  855. ;
  856. padright_end:
  857.     ret
  858. ;
  859. @padright    endp
  860. ;
  861. ;
  862. ; disprintf: display formatted string.
  863. ;
  864. ;     Entry:    DS:SI = format string
  865. ;         ES:DI = parameter pointer
  866. ;        CX    = output routine address
  867. ;        BX,DX = output routine parameter
  868. ;
  869. ;    Uses:    AX,BX,DX
  870. ;
  871. ;    Usually, the parameter pointer will point to the first
  872. ;    parameter on the stack. For added flexibility, ES:DI is
  873. ;    used here, so that the parameter list may be anywhere in
  874. ;    memory. This allows vprintf-style parameters.
  875. ;
  876. ;
  877. @disprintf    proc    near
  878.     push    bp
  879.     sub    sp,TYPE dislocrec
  880.     mov    bp,sp
  881.     mov    prproc[bp],cx
  882.     mov    prargbx[bp],bx
  883.     mov    prargdx[bp],dx
  884.     mov    procnt[bp],0
  885. ;
  886. disploop:
  887.     lodsb
  888.     or    al,al
  889.     jz    dispend            ; end of string
  890.     cmp    al,'%'
  891.     je    dispformat        ; jump if format character
  892.     cmp    al,0ah
  893.     jne    dispchar
  894.     mov    al,0dh
  895.     call    prproc[bp]        ; translate LF into CR+LF
  896.     inc    procnt[bp]
  897.     mov    al,0ah
  898. ;
  899. dispchar:
  900.     call    prproc[bp]
  901.     inc    procnt[bp]
  902.     jmp    disploop
  903. ;
  904. dispend:
  905.     mov    bx,prargbx[bp]
  906.     add    sp,TYPE dislocrec
  907.     pop    bp
  908.     ret
  909. ;
  910. disploop1:
  911.     pop    di
  912.     pop    es
  913.     add    di,arglen[bp]
  914.     jmp    disploop
  915. ;
  916. ;    Format character found, process conversion
  917. ;
  918. dispformat:
  919.     lodsb
  920.     cmp    al,'%'        ; %% means print single %
  921.     je    dispchar
  922. ;
  923.     push    es
  924.     push    di        ; save parameter pointer
  925.     mov    prflags[bp],0
  926.     mov    arglen[bp],2
  927. ;
  928.     cmp    al,'-'
  929.     jne    no_flags
  930.     or    prflags[bp],F_LEFTADJ
  931.     lodsb
  932. ;
  933. no_flags:
  934.     cmp    al,'0'
  935.     jne    no_zero
  936.     or    prflags[bp],F_PADZERO
  937.     lodsb
  938. ;
  939. no_zero:
  940.     cmp    al,'*'
  941.     je    loadwidth
  942.     cmp    al,'9'
  943.     ja    no_width
  944.     cmp    al,'0'
  945.     jb    no_width
  946.     call    @getint
  947.     jmp    short haswidth
  948. ;
  949. loadwidth:
  950.     mov    ax,word ptr es:[di]
  951.     add    di,2
  952.     add    arglen[bp],2
  953. ;
  954. haswidth:
  955.     or    prflags[bp],F_WIDTH
  956.     mov    prwidth[bp],ax
  957.     lodsb
  958. ;
  959. no_width:
  960.     cmp    al,'.'
  961.     jne    no_prec
  962.     lodsb
  963.     cmp    al,'*'
  964.     je    loadprec
  965.     cmp    al,'9'
  966.     ja    no_prec
  967.     cmp    al,'0'
  968.     jb    no_prec
  969.     call    @getint
  970.     jmp    short hasprec
  971. ;
  972. loadprec:
  973.     mov    ax,word ptr es:[di]
  974.     add    di,2
  975.     add    arglen[bp],2
  976. ;
  977. hasprec:
  978.     or    prflags[bp],F_PREC
  979.     mov    prec[bp],ax
  980.     lodsb
  981. ;
  982. ;    Process indirection.
  983. ;
  984. no_prec:
  985.     mov    dx,ds
  986.     cmp    al,'^'
  987.     je    indir_near
  988.     cmp    al,'@'
  989.     jne    no_indir
  990.     add    arglen[bp],2
  991. ;
  992. indir_near:
  993.     or    prflags[bp],F_INDIR
  994. ;
  995. indir_loop:
  996.     cmp    al,'^'
  997.     je    is_indir
  998.     cmp    al,'@'
  999.     jne    no_indir
  1000.     mov    dx,word ptr es:2[di]
  1001. is_indir:
  1002.     mov    di,word ptr es:[di]
  1003.     mov    es,dx
  1004.     lodsb            ; next conversion char
  1005.     jmp    indir_loop
  1006. ;
  1007. ;    Indirection finished, check for size modification
  1008. ;
  1009. no_indir:
  1010.     IF    DFLT_FAR
  1011.     cmp    al,'s'
  1012.     je    dfltsize0
  1013.     cmp    al,'n'
  1014.     je    dfltsize0
  1015.     cmp    al,'p'
  1016.     je    dfltsize0
  1017.     cmp    al,'P'
  1018.     jne    dfltsize1
  1019. ;
  1020. dfltsize0:
  1021.     or    prflags[bp],F_LONGARG
  1022.     jmp    short no_sizemod
  1023. ;
  1024. dfltsize1:
  1025.     ENDIF
  1026.     cmp    al,'F'
  1027.     je    sizemodl
  1028.     cmp    al,'N'
  1029.     jne    sizemod2
  1030.     lodsb
  1031.     jmp    short no_sizemod
  1032. ;
  1033. sizemod2:
  1034.     cmp    al,'h'
  1035.     je    sizemod2a
  1036.     cmp    al,'H'
  1037.     jne    sizemod3
  1038.     dec    arglen[bp]
  1039. sizemod2a:
  1040.     or    prflags[bp],F_SHORTARG
  1041.     lodsb
  1042.     jmp    short no_sizemod
  1043. ;
  1044. sizemod3:
  1045.     cmp    al,'l'
  1046.     jne    no_sizemod
  1047. ;
  1048. sizemodl:
  1049.     or    prflags[bp],F_LONGARG
  1050.     lodsb
  1051. ;
  1052. no_sizemod:
  1053.     xor    dx,dx
  1054.     test    prflags[bp],F_LONGARG
  1055.     jz    loadsingle
  1056.     mov    dx,word ptr es:2[di]
  1057.     test    prflags[bp],F_INDIR
  1058.     jnz    loadsingle
  1059.     add    arglen[bp],2
  1060. ;
  1061. loadsingle:
  1062.     mov    bl,al
  1063.     mov    ax,word ptr es:[di]
  1064.     test    prflags[bp],F_SHORTARG
  1065.     jz    noshort
  1066.     xor    ah,ah
  1067. ;
  1068. noshort:
  1069.     cmp    bl,'n'
  1070.     jne    convc0
  1071.     test    prflags[bp],F_LONGARG
  1072.     jz    gostorelen
  1073.     mov    ds,dx
  1074. gostorelen:
  1075.     mov    bx,ax
  1076.     mov    ax,procnt[bp]
  1077.     mov    [bx],ax
  1078.     jmp    disploop1
  1079. ;
  1080. convc0:
  1081.     lea    di,convbuf[bp]
  1082. ;
  1083.     cmp    bl,'c'
  1084.     jne    convc1
  1085.     mov    byte ptr ss:[di],al
  1086.     inc    di
  1087.     mov    bx,1
  1088.     and    prflags[bp],NOT (F_PREC OR F_PADZERO)
  1089.     jmp    out_conv
  1090. ;
  1091. convc1:
  1092.     cmp    bl,'s'
  1093.     jne    convc2
  1094.     test    prflags[bp],F_LONGARG
  1095.     jnz    gofmtstring
  1096.     mov    dx,ds
  1097. gofmtstring:
  1098.     and    prflags[bp],NOT F_PADZERO
  1099.     jmp    fmtstring
  1100. ;
  1101. convc2:
  1102.     cmp    bl,'b'
  1103.     je    fmtbin
  1104.     cmp    bl,'B'
  1105.     je    fmtbin
  1106.     cmp    bl,'x'
  1107.     je    fmthex
  1108.     cmp    bl,'X'
  1109.     je    fmthex
  1110.     cmp    bl,'p'
  1111.     je    fmtptr
  1112.     cmp    bl,'P'
  1113.     je    fmtptr
  1114.     cmp    bl,'u'
  1115.     je    fmtdec
  1116.     cmp    bl,'d'
  1117.     jne    badconv
  1118.     test    prflags[bp],F_LONGARG
  1119.     jnz    signedlong
  1120.     test    prflags[bp],F_SHORTARG
  1121.     jz    signedint
  1122.     cbw
  1123. ;
  1124. signedint:
  1125.     test    ah,80h
  1126.     jz    fmtdec
  1127.     or    prflags[bp],F_SIGNED
  1128.     neg    ax
  1129.     jmp    short fmtdec
  1130. ;
  1131. signedlong:
  1132.     test    dh,80h
  1133.     jz    fmtdec
  1134.     or    prflags[bp],F_SIGNED
  1135.     mov    cx,dx
  1136.     xor    dx,dx
  1137.     neg    ax
  1138.     sbb    dx,cx
  1139.     jmp    short fmtdec
  1140. ;
  1141. ;    Invalid conversion. Reset parameter pointer and output the
  1142. ;    char.
  1143. ;
  1144. badconv:
  1145.     pop    di
  1146.     pop    es
  1147.     mov    al,bl
  1148.     jmp    dispchar
  1149. ;
  1150. ;
  1151. fmtdec:
  1152.     call    @decconv
  1153.     test    prflags[bp],F_SIGNED
  1154.     jz    fmtdnosign
  1155.     mov    byte ptr ss:[di],'-'
  1156.     inc    di
  1157.     inc    bx
  1158. fmtdnosign:
  1159.     jmp    short out_conv
  1160. ;
  1161. fmtbin:
  1162.     call    @binconv
  1163.     jmp    short out_conv
  1164. ;
  1165. fmthex:
  1166.     mov    prhexch[bp],'a'-10-'0'
  1167.     cmp    bl,'x'
  1168.     je    fmthex1
  1169.     mov    prhexch[bp],'A'-10-'0'
  1170. fmthex1:
  1171.     call    @hexconv
  1172.     jmp    short out_conv
  1173. ;
  1174. fmtptr:
  1175.     mov    prhexch[bp],'a'-10-'0'
  1176.     cmp    bl,'p'
  1177.     je    fmtptr1
  1178.     mov    prhexch[bp],'A'-10-'0'
  1179. fmtptr1:
  1180.     and    prflags[bp],NOT (F_PREC OR F_PADZERO)
  1181.     mov    cl,4
  1182.     mov    bh,cl
  1183.     xor    bl,bl
  1184. ;
  1185. fmtplo:
  1186.     call    @hexdigbp
  1187.     shr    ax,cl
  1188.     dec    bh
  1189.     jnz    fmtplo
  1190.     test    prflags[bp],F_LONGARG
  1191.     jz    out_conv
  1192. ;
  1193.     mov    byte ptr ss:[di],':'
  1194.     inc    di
  1195.     inc    bl
  1196.     mov    bh,cl
  1197.     mov    ax,dx
  1198. ;
  1199. fmtphilp:
  1200.     call    @hexdigbp
  1201.     shr    ax,cl
  1202.     dec    bh
  1203.     jnz    fmtphilp
  1204. ;
  1205. ;
  1206. out_conv:
  1207.     mov    cx,bx
  1208.     call    @padleft
  1209.     add    procnt[bp],cx
  1210. outc_out:
  1211.     dec    di
  1212.     mov    al,byte ptr ss:[di]
  1213.     call    prproc[bp]
  1214.     loop    outc_out
  1215.     call    @padright
  1216.     jmp    disploop1
  1217. ;
  1218. ;
  1219. fmtstring:
  1220.     push    si
  1221.     push    ds
  1222.     mov    ds,dx
  1223.     mov    si,ax
  1224. ;
  1225.     mov    es,dx
  1226.     mov    di,ax
  1227.     xor    ax,ax
  1228.     mov    cx,-1
  1229.     repne scasb
  1230.     not    cx
  1231.     dec    cx
  1232.     test    prflags[bp],F_PREC
  1233.     jz    fmtstr_np
  1234.     cmp    cx,prec[bp]
  1235.     jbe    fmtstr_np
  1236.     mov    cx,prec[bp]
  1237. ;
  1238. fmtstr_np:
  1239.     and    prflags[bp],NOT F_PREC
  1240.     mov    bx,cx
  1241.     call    @padleft
  1242.     jcxz    fmtstr_end
  1243.     add    procnt[bp],cx
  1244. fmtstr_out:
  1245.     lodsb
  1246.     call    prproc[bp]
  1247.     loop    fmtstr_out
  1248. fmtstr_end:
  1249.     call    @padright
  1250.     pop    ds
  1251.     pop    si
  1252.     jmp    disploop1
  1253. ;
  1254. ;
  1255. @disprintf    endp
  1256. ;
  1257. ;
  1258. ; void tsk_printf (char far *format, ...)
  1259. ;
  1260. ;    Formatted output to console.
  1261. ;
  1262. CGlobalfunc tsk_printf,<uses ds si di, fmt: far ptr, varg: word>
  1263. ;
  1264.     mov    ax,ss
  1265.     mov    es,ax
  1266.     lds    si,fmt
  1267.     lea    di,varg
  1268.     mov    cx,offset @dischar
  1269.     call    @disprintf
  1270.     ret
  1271. tsk_printf    endp
  1272. ;
  1273. ;
  1274. ; void tsk_vprintf (char far *format, void far *arg)
  1275. ;
  1276. ;    Formatted output to console.
  1277. ;
  1278. Globalfunc tsk_vprintf,<uses ds si di, fmt: far ptr, varg: far ptr>
  1279. ;
  1280.     lds    si,fmt
  1281.     les    di,varg
  1282.     mov    cx,offset @dischar
  1283.     call    @disprintf
  1284.     ret
  1285. tsk_vprintf    endp
  1286. ;
  1287. ;
  1288. ; void tsk_fprintf (int handle, char far *format, ...)
  1289. ;
  1290. ;    Formatted output to file.
  1291. ;
  1292. CGlobalfunc tsk_fprintf    <uses ds si di, handle: word, fmt: far ptr, varg: word>
  1293. ;
  1294.     mov    ax,ss
  1295.     mov    es,ax
  1296.     lds    si,fmt
  1297.     lea    di,varg
  1298.     sub    sp,FILE_BUFSIZE
  1299.     mov    dx,sp
  1300.     mov    bx,sp
  1301.     mov    byte ptr ss:[bx],0
  1302.     mov    cx,offset @filechar
  1303.     mov    bx,handle
  1304.     call    @disprintf
  1305.     mov    si,sp
  1306.     mov    cl,ss:[si]
  1307.     xor    ch,ch
  1308.     jcxz    fprintfend
  1309.     mov    dx,si
  1310.     inc    dx
  1311.     mov    bx,handle
  1312.     mov    ax,ss
  1313.     mov    ds,ax
  1314.     mov    ah,40h
  1315.     int    21h
  1316. fprintfend:
  1317.     add    sp,FILE_BUFSIZE
  1318.     ret
  1319. tsk_fprintf    endp
  1320. ;
  1321. ;
  1322. ; void tsk_vfprintf (int handle, char far *format, void far *arg)
  1323. ;
  1324. ;    Formatted output to file.
  1325. ;
  1326. Globalfunc tsk_vfprintf,<uses ds si di, handle: word, fmt: far ptr, varg: far ptr>
  1327. ;
  1328.     lds    si,fmt
  1329.     les    di,varg
  1330.     sub    sp,FILE_BUFSIZE
  1331.     mov    dx,sp
  1332.     mov    bx,sp
  1333.     mov    byte ptr ss:[bx],0
  1334.     mov    cx,offset @filechar
  1335.     mov    bx,handle
  1336.     call    @disprintf
  1337.     mov    si,sp
  1338.     mov    cl,ss:[si]
  1339.     xor    ch,ch
  1340.     jcxz    vfprintfend
  1341.     mov    dx,si
  1342.     inc    dx
  1343.     mov    bx,handle
  1344.     mov    ax,ss
  1345.     mov    ds,ax
  1346.     mov    ah,40h
  1347.     int    21h
  1348. vfprintfend:
  1349.     add    sp,FILE_BUFSIZE
  1350.     ret
  1351. tsk_vfprintf    endp
  1352. ;
  1353. ;
  1354. ; void tsk_sprintf (char far *dest, char far *format, ...)
  1355. ;
  1356. ;    Formatted output to string.
  1357. ;
  1358. CGlobalfunc tsk_sprintf,<uses ds si di, dest: far ptr, fmt: far ptr, varg: word>
  1359. ;
  1360.     mov    ax,ss
  1361.     mov    es,ax
  1362.     lds    bx,dest
  1363.     mov    dx,ds
  1364.     lds    si,fmt
  1365.     lea    di,varg
  1366.     mov    cx,offset @stringchar
  1367.     call    @disprintf
  1368.     mov    es,word ptr(dest) + 2
  1369.     mov    byte ptr es:[bx],0
  1370.     sub    bx,word ptr(dest)
  1371.     mov    ax,bx
  1372.     ret
  1373. tsk_sprintf    endp
  1374. ;
  1375. ;
  1376. ; void tsk_vsprintf (char far *dest, char far *format, void far *arglist)
  1377. ;
  1378. ;    Formatted output to string.
  1379. ;
  1380. Globalfunc tsk_vsprintf,<uses ds si di, dest: far ptr, fmt: far ptr, varg: far ptr>
  1381. ;
  1382.     lds    bx,dest
  1383.     mov    dx,ds
  1384.     lds    si,fmt
  1385.     les    di,varg
  1386.     mov    cx,offset @stringchar
  1387.     call    @disprintf
  1388.     mov    es,word ptr(dest) + 2
  1389.     mov    byte ptr es:[bx],0
  1390.     sub    bx,word ptr(dest)
  1391.     mov    ax,bx
  1392.     ret
  1393. tsk_vsprintf    endp
  1394. ;
  1395. ;
  1396. ; void tsk_rprintf (char far *format, ...)
  1397. ;
  1398. ;    Formatted output to regen buffer (second display).
  1399. ;
  1400. CGlobalfunc tsk_rprintf,<uses ds si di, fmt: far ptr, varg: word>
  1401. ;
  1402.     IFDEF    LOAD_DS
  1403.     mov    ds,cs:ctdataseg
  1404.     ENDIF
  1405.     mov    cx,sc_proc
  1406.     mov    ax,ss
  1407.     mov    es,ax
  1408.     lds    si,fmt
  1409.     lea    di,varg
  1410.     call    @disprintf
  1411.     ret
  1412. tsk_rprintf    endp
  1413. ;
  1414. ;
  1415. ; void tsk_vrprintf (char far *format, void far *arglist)
  1416. ;
  1417. ;    Formatted output to regen buffer (second display).
  1418. ;
  1419. Globalfunc tsk_vrprintf,<uses ds si di, fmt: far ptr, varg: far ptr>
  1420. ;
  1421.     IFDEF    LOAD_DS
  1422.     mov    ds,cs:ctdataseg
  1423.     ENDIF
  1424.     mov    cx,sc_proc
  1425.     lds    si,fmt
  1426.     les    di,varg
  1427.     call    @disprintf
  1428.     ret
  1429. tsk_vrprintf    endp
  1430. ;
  1431. ;
  1432. ;
  1433. ; void tsk_cprintf (char far *format, ...)
  1434. ;
  1435. ;    Formatted output to comm port
  1436. ;
  1437. CGlobalfunc tsk_cprintf,<uses ds si di, fmt: far ptr, varg: word>
  1438. ;
  1439.     IFDEF    LOAD_DS
  1440.     mov    ds,cs:ctdataseg
  1441.     ENDIF
  1442.     mov    cx,offset @comchar
  1443.     mov    ax,ss
  1444.     mov    es,ax
  1445.     lds    si,fmt
  1446.     lea    di,varg
  1447.     call    @disprintf
  1448.     ret
  1449. tsk_cprintf    endp
  1450. ;
  1451. ;
  1452. ; void tsk_vcprintf (char far *format, void far *arglist)
  1453. ;
  1454. ;    Formatted output to comm port
  1455. ;
  1456. Globalfunc tsk_vcprintf,<uses ds si di, fmt: far ptr, varg: far ptr>
  1457. ;
  1458.     IFDEF    LOAD_DS
  1459.     mov    ds,cs:ctdataseg
  1460.     ENDIF
  1461.     mov    cx,offset @comchar
  1462.     lds    si,fmt
  1463.     les    di,varg
  1464.     call    @disprintf
  1465.     ret
  1466. tsk_vcprintf    endp
  1467. ;
  1468. ;
  1469. ; void tsk_putc (char c)
  1470. ;
  1471. ;    Output character to console.
  1472. ;    
  1473. Globalfunc tsk_putc,<chr: word>
  1474.     mov    ax,chr
  1475.     call    @dischar
  1476.     ret
  1477. tsk_putc    endp
  1478. ;
  1479. ;
  1480. ; void tsk_puts (char far *s)
  1481. ;
  1482. ;    Output string to console.
  1483. ;    
  1484. Globalfunc tsk_puts,<uses ds si, dstr: far ptr>
  1485. ;
  1486.     lds    si,dstr
  1487. putslp:
  1488.     lodsb
  1489.     or    al,al
  1490.     jz    putsend
  1491.     call    @dischar
  1492.     jmp    putslp
  1493. ;
  1494. putsend:
  1495.     mov    al,0dh
  1496.     call    @dischar
  1497.     mov    al,0ah
  1498.     call    @dischar
  1499.     ret
  1500. tsk_puts    endp
  1501. ;
  1502. ;
  1503. ; void tsk_rputc (char c)
  1504. ;
  1505. ;    Output character to regen buffer (second display).
  1506. ;    
  1507. Globalfunc tsk_rputc,<chr: word>
  1508. ;
  1509.     mov    ax,chr
  1510.     IFDEF    LOAD_DS
  1511.     push    ds
  1512.     mov    ds,cs:ctdataseg
  1513.     call    sc_proc
  1514.     pop    ds
  1515.     ELSE
  1516.     call    sc_proc
  1517.     ENDIF
  1518.     ret
  1519. tsk_rputc    endp
  1520. ;
  1521. ;
  1522. ; void tsk_rputs (char far *s)
  1523. ;
  1524. ;    Output string to regen buffer.
  1525. ;    
  1526. Globalfunc tsk_rputs,<uses si, dstr: far ptr>
  1527. ;
  1528.     IFDEF    LOAD_DS
  1529.     push    ds
  1530.     mov    ds,cs:ctdataseg
  1531.     ENDIF
  1532.     les    si,dstr
  1533. rputslp:
  1534.     lods    es:prflags
  1535.     or    al,al
  1536.     jz    rputsend
  1537.     call    sc_proc
  1538.     jmp    rputslp
  1539. ;
  1540. rputsend:
  1541.     mov    al,0dh
  1542.     call    sc_proc
  1543.     mov    al,0ah
  1544.     call    sc_proc
  1545.     IFDEF    LOAD_DS
  1546.     pop    ds
  1547.     ENDIF
  1548.     ret
  1549. tsk_rputs    endp
  1550. ;
  1551. ;
  1552. ; void tsk_cputc (char c)
  1553. ;
  1554. ;    Output character to comm port.
  1555. ;    
  1556. Globalfunc tsk_cputc,<chr: word>
  1557.     mov    ax,chr
  1558.     call    @comchar
  1559.     ret
  1560. tsk_cputc    endp
  1561. ;
  1562. ;
  1563. ; void tsk_cputs (char far *s)
  1564. ;
  1565. ;    Output string to comm port.
  1566. ;    
  1567. Globalfunc tsk_cputs,<uses ds si, dstr: far ptr>
  1568. ;
  1569.     lds    si,dstr
  1570. cputslp:
  1571.     lodsb
  1572.     or    al,al
  1573.     jz    cputsend
  1574.     call    @comchar
  1575.     jmp    cputslp
  1576. ;
  1577. cputsend:
  1578.     mov    al,0dh
  1579.     call    @comchar
  1580.     mov    al,0ah
  1581.     call    @comchar
  1582.     ret
  1583. tsk_cputs    endp
  1584. ;
  1585. ;
  1586. ; void tsk_setpos (int row, int col)
  1587. ;
  1588. ;    Set cursor position for regen output.
  1589. ;    First position on screen is (0, 0).
  1590. ;
  1591. Globalfunc tsk_setpos,<row: word, col: word>
  1592. ;
  1593.     IFDEF    LOAD_DS
  1594.     push    ds
  1595.     mov    ds,cs:ctdataseg
  1596.     ENDIF
  1597.     mov    ax,row
  1598.     mul    sc_cols
  1599.     add    ax,col
  1600.     add    ax,col
  1601.     mov    tsk_regen_o,ax
  1602.     call    @setcsr
  1603.     IFDEF    LOAD_DS
  1604.     pop    ds
  1605.     ENDIF
  1606.     ret
  1607. tsk_setpos    endp
  1608. ;
  1609. ;
  1610. ; void tsk_set_regen (int segment, int port, int rows, int cols)
  1611. ;
  1612. ;    Set regen buffer address and size, and display controller port.
  1613. ;    This routine can be used to force regen output to the
  1614. ;    primary screen for single-screen systems, and to modify
  1615. ;    the output parameters (number of rows and columns).
  1616. ;
  1617. Globalfunc tsk_set_regen,<reg: word, port: word, rows: word, cols: word>
  1618. ;
  1619.     IFDEF    LOAD_DS
  1620.     push    ds
  1621.     mov    ds,cs:ctdataseg
  1622.     ENDIF
  1623.     mov    ax,reg
  1624.     mov    tsk_regen_s,ax
  1625.     mov    ax,port
  1626.     mov    tsk_disport,ax
  1627.     mov    tsk_regen_o,0
  1628.     mov    ax,cols
  1629.     add    ax,ax
  1630.     mov    sc_cols,ax
  1631.     mul    rows
  1632.     mov    sc_end,ax
  1633.     mov    sc_proc,offset @disregen
  1634.     IFDEF    LOAD_DS
  1635.     pop    ds
  1636.     ENDIF
  1637.     ret
  1638. tsk_set_regen    endp
  1639. ;
  1640. ;
  1641. ; int tsk_set_dualdis (void)
  1642. ;
  1643. ;    Determine regen buffer address on second monitor.
  1644. ;    This routine first checks the current video mode. If it's
  1645. ;    mode 7, the regen buffer is set to B800 (the colour screen).
  1646. ;    For all other modes, the regen buffer is B000 (mono).
  1647. ;    Then a check is done to make sure that the secondary card
  1648. ;    exists. If it does, the regen output is initialized. Otherwise,
  1649. ;    any output through the regen routines will be discarded.
  1650. ;
  1651. ;    Returns 0 if there is no secondary monitor, else the
  1652. ;    regen buffer address.
  1653. ;
  1654. ;    No attempt is made to initialize the secondary monitor,
  1655. ;    the monitor must be in alpha mode.
  1656. ;
  1657. Globalfunc tsk_set_dualdis
  1658. ;
  1659.     IFDEF    LOAD_DS
  1660.     push    ds
  1661.     mov    ds,cs:ctdataseg
  1662.     ENDIF
  1663.     mov    ah,0fh
  1664.     push    bp
  1665.     int    10h        ; get video mode
  1666.     pop    bp
  1667.     mov    bx,0b800h    ; colour regen buffer
  1668.     mov    dx,3d4h        ; CGA 6845 I/O addr
  1669.     cmp    al,7        ; only mode 7 has regen at B000
  1670.     je    ddis_checks
  1671.     mov    bx,0b000h    ; mono regen buffer
  1672.     mov    dx,3b4h        ; mono 6845 I/O addr
  1673. ;
  1674. ddis_checks:
  1675.     mov    tsk_regen_s,bx
  1676.     mov    tsk_regen_o,0
  1677.     mov    tsk_disport,dx
  1678.     mov    sc_cols,80 * 2
  1679.     mov    sc_end,25 * 80 * 2
  1680.     mov    al,0fh
  1681.     out    dx,al
  1682.     inc    dx
  1683.     in    al,dx
  1684.     mov    ah,al
  1685.     mov    al,56h
  1686.     out    dx,al
  1687.     mov    cx,100h
  1688. ddis_wait:
  1689.     loop    ddis_wait
  1690.     in    al,dx
  1691.     xchg    ah,al
  1692.     out    dx,al
  1693.     cmp    ah,56h
  1694.     je    ddis_ok
  1695.     mov    sc_proc,offset @nodis
  1696.     xor    ax,ax
  1697.     mov    tsk_regen_s,ax
  1698.     jmp    short ddis_end
  1699. ;
  1700. ddis_ok:
  1701.     mov    sc_proc,offset @disregen
  1702.     mov    ax,bx
  1703. ;
  1704. ddis_end:
  1705.     IFDEF    LOAD_DS
  1706.     pop    ds
  1707.     ENDIF
  1708.     ret
  1709. ;
  1710. tsk_set_dualdis    endp
  1711. ;
  1712. ;
  1713. ; int tsk_set_currdis (void)
  1714. ;
  1715. ;    Determine regen buffer address on current monitor.
  1716. ;    This routine checks the current video mode. If it's
  1717. ;    mode 7, the regen buffer is set to B000 (the mono screen).
  1718. ;    For all other modes, the regen buffer is B800 (colour).
  1719. ;
  1720. ;    Returns the regen buffer address.
  1721. ;
  1722. ;    No attempt is made to initialize the monitor, or to check for
  1723. ;    special modes with different regen address. The monitor must 
  1724. ;    be in alpha mode.
  1725. ;
  1726. Globalfunc tsk_set_currdis
  1727. ;
  1728.     IFDEF    LOAD_DS
  1729.     push    ds
  1730.     mov    ds,cs:ctdataseg
  1731.     ENDIF
  1732.     mov    ah,0fh
  1733.     push    bp
  1734.     int    10h        ; get video mode
  1735.     pop    bp
  1736.     mov    bx,0b800h    ; colour regen buffer
  1737.     cmp    al,7        ; only mode 7 has regen at B000
  1738.     jne    curdis_ready
  1739.     mov    bx,0b000h    ; mono regen buffer
  1740. ;
  1741. curdis_ready:
  1742.     mov    tsk_regen_s,bx
  1743.     mov    tsk_regen_o,0
  1744.     mov    ax,SEG biosdata
  1745.     mov    es,ax
  1746.     assume    es:biosdata
  1747.     mov    ax,bios_chipad
  1748.     mov    tsk_disport,ax
  1749.     mov    ax,bios_cols
  1750.     add    ax,ax
  1751.     mov    sc_cols,ax
  1752.     mov    dl,bios_rows
  1753.     xor    dh,dh
  1754.     mul    dx
  1755.     mov    sc_end,ax
  1756.     mov    sc_proc,offset @disregen
  1757.     mov    ax,bx
  1758.     IFDEF    LOAD_DS
  1759.     pop    ds
  1760.     ENDIF
  1761.     ret
  1762. ;
  1763. tsk_set_currdis    endp
  1764. ;
  1765. ;
  1766. ; void tsk_set_colour (int rows, int cols)
  1767. ;
  1768. ;    Set regen buffer address to colour monitor.
  1769. ;
  1770. Globalfunc tsk_set_colour,<rows: word, cols: word>
  1771. ;
  1772.     IFDEF    LOAD_DS
  1773.     push    ds
  1774.     mov    ds,cs:ctdataseg
  1775.     ENDIF
  1776.     mov    tsk_regen_s,0b800h    ; colour regen buffer
  1777.     mov    tsk_regen_o,0
  1778.     mov    tsk_disport,3d4h    ; CGA 6845 I/O addr
  1779.     mov    ax,cols
  1780.     add    ax,ax
  1781.     mov    sc_cols,ax
  1782.     mul    rows
  1783.     mov    sc_end,ax
  1784.     mov    sc_proc,offset @disregen
  1785.     IFDEF    LOAD_DS
  1786.     pop    ds
  1787.     ENDIF
  1788.     ret
  1789. ;
  1790. tsk_set_colour    endp
  1791. ;
  1792. ;
  1793. ; void tsk_set_mono (int rows, int cols)
  1794. ;
  1795. ;    Set regen buffer address to monochrome monitor.
  1796. ;
  1797. Globalfunc tsk_set_mono,<rows: word, cols: word>
  1798. ;
  1799.     IFDEF    LOAD_DS
  1800.     push    ds
  1801.     mov    ds,cs:ctdataseg
  1802.     ENDIF
  1803.     mov    tsk_regen_s,0b000h    ; mono regen buffer
  1804.     mov    tsk_regen_o,0
  1805.     mov    tsk_disport,3b4h    ; mono 6845 I/O addr
  1806.     mov    ax,cols
  1807.     add    ax,ax
  1808.     mov    sc_cols,ax
  1809.     mul    rows
  1810.     mov    sc_end,ax
  1811.     mov    sc_proc,offset @disregen
  1812.     IFDEF    LOAD_DS
  1813.     pop    ds
  1814.     ENDIF
  1815.     ret
  1816. ;
  1817. tsk_set_mono    endp
  1818. ;
  1819. ;
  1820. ; void tsk_set_attr (int attr)
  1821. ;
  1822. ;    Set regen display attributes
  1823. ;
  1824. Globalfunc tsk_set_attr,<attr: word>
  1825. ;
  1826.     IFDEF    LOAD_DS
  1827.     push    ds
  1828.     mov    ds,cs:ctdataseg
  1829.     ENDIF
  1830.     mov    ax,attr
  1831.     mov    tsk_attrib,al
  1832.     IFDEF    LOAD_DS
  1833.     pop    ds
  1834.     ENDIF
  1835.     ret
  1836. ;
  1837. tsk_set_attr    endp
  1838. ;
  1839. ;
  1840. ; void tsk_set_clreol (int clr)
  1841. ;
  1842. ;    Set special handling of CR. If "clr" is nonzero, CR will clear
  1843. ;    to end of line before returning to the home position.
  1844. ;
  1845. Globalfunc tsk_set_clreol,<clr: word>
  1846. ;
  1847.     IFDEF    LOAD_DS
  1848.     push    ds
  1849.     mov    ds,cs:ctdataseg
  1850.     ENDIF
  1851.     mov    ax,clr
  1852.     mov    sc_clreol,al
  1853.     IFDEF    LOAD_DS
  1854.     pop    ds
  1855.     ENDIF
  1856.     ret
  1857. ;
  1858. tsk_set_clreol    endp
  1859. ;
  1860. ;
  1861. Globalfunc tsk_cprint_init,<port: word, baud: word>
  1862. ;
  1863.     IFDEF    LOAD_DS
  1864.     push    ds
  1865.     mov    ds,cs:ctdataseg
  1866.     ENDIF
  1867. ;
  1868.     mov    ax,port
  1869.     cmp    ax,4
  1870.     ja    compok
  1871.     mov    bx,ax
  1872.     or    bx,bx
  1873.     jz    comp1
  1874.     dec    bx
  1875.     add    bx,bx
  1876. comp1:
  1877.     mov    ax,40h
  1878.     mov    es,ax
  1879.     mov    ax,es:[bx]
  1880.     or    ax,ax
  1881.     jnz    compok
  1882.     mov    ax,3f8h
  1883. compok:
  1884.     mov    tsk_comport,ax
  1885.     mov    dx,ax
  1886.     mov    bx,48
  1887.     mov    ax,baud
  1888.     cmp    ax,24
  1889.     jbe    baudok
  1890.     mov    bx,12
  1891.     cmp    ax,96
  1892.     jbe    baudok
  1893.     mov    bx,6
  1894.     cmp    ax,192
  1895.     jbe    baudok
  1896.     mov    bx,3
  1897.     cmp    ax,384
  1898.     jbe    baudok
  1899.     mov    bx,1
  1900. baudok:
  1901.     add    dx,3        ; line control
  1902.     cli
  1903.     mov    al,83h        ; no par, 1 stop 8 data
  1904.     out    dx,al
  1905.     sub    dx,3        ; data
  1906.     jmp    $+2
  1907.     mov    al,bl
  1908.     out    dx,al
  1909.     jmp    $+2
  1910.     xor    al,al
  1911.     inc    dx
  1912.     out    dx,al
  1913.     jmp    $+2
  1914.     add    dx,2        ; line control
  1915.     mov    al,03h        ; no par, 1 stop 8 data
  1916.     out    dx,al
  1917.     jmp    $+2
  1918.     inc    dx        ; modem control
  1919.     mov    al,03h        ; DTR, RTS
  1920.     out    dx,al
  1921.     jmp    $+2
  1922.     sub    dx,3        ; int enable
  1923.     xor    al,al        ; no ints
  1924.     out    dx,al
  1925.     sti
  1926. ;
  1927.     IFDEF    LOAD_DS
  1928.     pop    ds
  1929.     ENDIF
  1930.     ret
  1931. ;
  1932. tsk_cprint_init    endp
  1933. ;
  1934. ;
  1935. Globalfunc tsk_cprint_getc
  1936. ;
  1937.     IFDEF    LOAD_DS
  1938.     push    ds
  1939.     mov    ds,cs:ctdataseg
  1940.     ENDIF
  1941. ;
  1942.     push    dx
  1943.     mov    dx,tsk_comport
  1944.     mov    ax,dx
  1945.     or    ax,ax
  1946.     jz    cgc_end
  1947.     call    @poll_com
  1948.     mov    ax,tsk_comcnt
  1949.     or    ax,ax
  1950.     jz    cgc_end
  1951.     push    bx
  1952.     mov    bx,tsk_comoptr
  1953.     mov    al,tsk_combuf[bx]
  1954.     inc    bx
  1955.     and    bx,0fh
  1956.     mov    tsk_comoptr,bx
  1957.     pop    bx
  1958.     dec    tsk_comcnt
  1959.     mov    ah,1
  1960.     or    ax,ax
  1961. ;
  1962. cgc_end:
  1963.     pop    dx
  1964.     IFDEF    LOAD_DS
  1965.     pop    ds
  1966.     ENDIF
  1967.     ret
  1968. ;
  1969. tsk_cprint_getc    endp
  1970. ;
  1971. ;
  1972. Globalfunc tsk_cprint_waitc
  1973. ;
  1974.     IFDEF    LOAD_DS
  1975.     push    ds
  1976.     mov    ds,cs:ctdataseg
  1977.     ENDIF
  1978. ;
  1979.     push    dx
  1980.     mov    dx,tsk_comport
  1981.     mov    ax,dx
  1982.     or    ax,ax
  1983.     jz    cwc_end
  1984. ;
  1985. cwc_loop:
  1986.     call    @poll_com
  1987.     cmp    tsk_comcnt,0
  1988.     je    cwc_loop
  1989.     push    bx
  1990.     mov    bx,tsk_comoptr
  1991.     mov    al,tsk_combuf[bx]
  1992.     inc    bx
  1993.     and    bx,0fh
  1994.     mov    tsk_comoptr,bx
  1995.     pop    bx
  1996.     dec    tsk_comcnt
  1997.     mov    ah,1
  1998. ;
  1999. cwc_end:
  2000.     pop    dx
  2001.     IFDEF    LOAD_DS
  2002.     pop    ds
  2003.     ENDIF
  2004.     ret
  2005. ;
  2006. tsk_cprint_waitc    endp
  2007. ;
  2008.     .tsk_ecode
  2009.     end
  2010.  
  2011.