home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / BYTE24.ZIP / WINSUBS.ASM < prev   
Assembly Source File  |  1990-05-13  |  37KB  |  2,671 lines

  1. ; character windows
  2. ;
  3. ; Windowing subroutines for the byte benchmarks. These may be extended
  4. ; for use in a general purpose windowing library, but as they stand they
  5. ; are suited only for this task.
  6. ;
  7. ; This code is for the interface only, and has no effect on benchmark
  8. ; results.
  9. ;
  10. ; MASM, TASM compatible subroutines
  11. ;
  12. ; includes:
  13. ;    _mk_window, _kill_window, _link_array, _new_cursor, _hide_window
  14. ;    scroll, _chattr, _winputch, _win_set_curpos, _clearscreen
  15. ;    _win_erase_region, _cgainit
  16. ;
  17. ; style of asm subroutines ( the stack frame struc) is adapted
  18. ; from Michael J. Young's _MS-DOS_Advanced_Programming_ c.1988 by Sybex
  19. ;
  20.  
  21. ; equates for offsets in handle structure
  22.  
  23.     made            equ    [di+0]    
  24.     ptr_win_name        equ    [di+1]
  25.     handx1            equ    [di+3]
  26.     handy1            equ    [di+4]
  27.     ulx            equ    [di+5]
  28.     uly            equ    [di+6]
  29.     frame_flag        equ    [di+7]
  30.     immortal_flag        equ    [di+8]
  31.     hidden_flag        equ    [di+9]
  32.     ptr_behind_window    equ    [di+10]
  33.     w            equ    [di+12]
  34.     h            equ    [di+13]
  35.     image_w            equ    [di+14]
  36.     image_h            equ    [di+15]
  37.     hand_frame_attrib    equ    [di+16]
  38.     interior_attrib        equ    [di+17]
  39.     ptr_displayed_array    equ    [di+18]
  40.     dax            equ    [di+20]
  41.     day            equ    [di+22]
  42.     dax_off_log        equ    [di+24]
  43.     day_off_log        equ    [di+26]
  44.     dax_off_ul        equ    [di+28]
  45.     day_off_ul        equ    [di+30]
  46.     da_ulx            equ    [di+32]
  47.     da_uly            equ    [di+33]
  48.     da_im_w            equ    [di+34]
  49.     da_im_h            equ    [di+35]
  50.     num_valid        equ    [di+36]
  51.     ptr_valid_lines        equ    [di+37]
  52.  
  53.  
  54. _data    segment word public 'DATA'
  55.  
  56.     extrn    _machine_config: BYTE
  57.  
  58. graphics_type    equ    word ptr [_machine_config+15]
  59. snowflag    equ    word ptr [_machine_config+25]
  60.  
  61.     line_buffer    dw    80 dup (?)
  62.     video_seg    dw    0b000h
  63.     win_ul_x    db    0
  64.     win_ul_y    db    0
  65.     screen_image    dw    ?
  66.     win_width    db    0
  67.     win_height    db    0
  68.     win_clip_width    db    0
  69.     win_clip_height    db    0
  70.     frame_attrib    db    0
  71.     int_attrib    db    0
  72.     win_clip_x1    db    0
  73.     win_clip_x2    db    0
  74.     win_clip_y1    db    0
  75.     win_clip_y2    db    0
  76.     win_name_len    db    0
  77.     ul_sym        db    0
  78.     hori_sym    db    0
  79.     l_nm_bnd_sym    db    0
  80.     r_nm_bnd_sym    db    0
  81.     ur_sym        db    0
  82.     vert_sym    db    0
  83.     ll_sym        db    0
  84.     lr_sym        db    0
  85.  
  86.  
  87. _data    ends
  88.  
  89. dgroup    group    _data
  90. assume    cs:_text, ds:dgroup
  91. public     _mk_window, _kill_window, _link_array, _new_cursor, _hide_window
  92. public  _scroll, _chattr, _winputch, _win_set_curpos, _clearscreen
  93. public  _win_erase_region, _winstrlen, _cgainit
  94. public  video_seg
  95.  
  96. _text    segment byte public 'CODE'
  97.  
  98. ; sleazy data for cga snow stuff
  99.  
  100.     snow_write_type    db    ?
  101.     cga_timeout    dw    ?
  102.     localsnow    dw    ?
  103.  
  104. _mk_window    proc    near
  105.  
  106. ; win_handle *mk_window(win_handle *handle,
  107. ;            char * win_name,
  108. ;            int x1, int y1,
  109. ;                    int x2, int y2,
  110. ;                    int frame_bg, int frame_fg,
  111. ;                int int_bg, int int_fg,
  112. ;            int frameflag, int immortalflag);
  113.  
  114. ; returns window handle for later operations
  115. ;
  116.  
  117.     stackframe    struc
  118.     bptr        dw    ?
  119.     raddr        dw    ?
  120.     handle        dw    ?
  121.     win_name    dw    ?
  122.     x1        db    ?
  123.                         db      ?
  124.     y1        db    ?
  125.                         db      ?
  126.     x2        db    ?
  127.                         db      ?
  128.     y2        db    ?
  129.                         db      ?
  130.     fr_bg        dw    ?
  131.     fr_fg        dw    ?
  132.     int_bg        dw    ?
  133.     int_fg        dw    ?
  134.     frameflag    dw    ?
  135.     immortalflag    dw    ?
  136.     stackframe    ends
  137.  
  138.  
  139. frame        equ    [bp-bptr]
  140.  
  141.     push     bp        ; Stack frame manipulations
  142.     mov     bp,sp
  143.     sub    sp,bptr
  144.     push    es
  145.     push    di
  146.     push    si
  147.  
  148.  
  149.     push    ds
  150.     pop    es
  151.     mov    ax, frame.handle
  152.     mov    di, ax
  153.     xor    ax, ax
  154.     or    al, made
  155.     je    NOTMADE
  156.     jmp    ERREXIT
  157.  
  158. NOTMADE:
  159.  
  160. ; zero calculated values, just in case
  161.  
  162.     xor    ax,ax
  163.  
  164.     mov    di, offset dgroup:win_ul_x
  165.     stosw
  166.     inc     di
  167.     inc    di
  168.     mov    cx,11
  169. rep    stosb
  170.  
  171. ; symbols if frame requested
  172.  
  173.     or    ax,frame.frameflag
  174.     jnz    FRAME_REQ
  175.     mov    cx,8
  176. rep    stosb
  177.     jmp    short    NO_FRAME_REQ
  178.  
  179. FRAME_REQ:
  180.  
  181.     mov    al, 0c9h
  182.     stosb
  183.     mov    al, 0cdh
  184.     stosb
  185.     mov    al, 0b5h
  186.     stosb
  187.     mov    al, 0c6h
  188.     stosb
  189.     mov    al, 0bbh
  190.     stosb
  191.     mov    al, 0bah
  192.     stosb
  193.     mov    al, 0c8h
  194.     stosb
  195.     mov    al, 0bch
  196.     stosb
  197.  
  198. NO_FRAME_REQ:
  199.  
  200. ; calculate window parameters
  201.  
  202.  
  203.     mov    ah, frame.x2
  204.     mov    al, frame.x1
  205.     mov    bx, ax
  206.     cmp    al, 79
  207.     jg    BAD_WINDOW
  208.     cmp    ah, 0
  209.     jl    BAD_WINDOW
  210.  
  211. ; window width
  212.  
  213.     sub    ah, al
  214.     cmp    ah, 7
  215.     jle    BAD_WINDOW
  216.     mov    win_width, ah
  217.  
  218. ; window x clips
  219.  
  220.     mov    ax,bx
  221.     cmp    ah, 80
  222.     jl    NOCLIP
  223.     sub    ah, 80
  224.     mov    win_clip_x2, ah
  225. NOCLIP:
  226.     cmp    al, 0
  227.     jge    NOCLIP2
  228.     neg    al
  229.     mov    win_clip_x1, al
  230. NOCLIP2:
  231.  
  232. ; window ul_x
  233.  
  234.     mov    al, frame.x1
  235.     add    al, win_clip_x1
  236.     mov    win_ul_x, al
  237.  
  238. ; visible width
  239.  
  240.     mov    ah, win_width
  241.     sub    ah, win_clip_x1
  242.     sub    ah, win_clip_x2
  243.     mov    win_clip_width, ah
  244.     
  245. ; window height
  246.  
  247.     mov    ah, frame.y2
  248.     mov    al, frame.y1
  249.     mov    bx, ax
  250.     cmp    al, 25
  251.     jg    BAD_WINDOW
  252.     cmp    ah, 0
  253.     jl    BAD_WINDOW
  254.  
  255.     sub    ah, al
  256.     cmp    ah, 2
  257.     jle    BAD_WINDOW
  258.     mov    win_height, ah
  259.     jmp    LBL0
  260.  
  261. BAD_WINDOW:
  262.     xor    ax, ax
  263.     pop    si
  264.     pop    di
  265.     pop    es
  266.         pop    bp
  267.            ret
  268. LBL0:
  269.  
  270. ; window y clips
  271.  
  272.     mov    ax,bx
  273.     cmp    ah, 25
  274.     jl    NOCLIP3
  275.     sub    ah, 25
  276.     mov    win_clip_y2, ah
  277. NOCLIP3:
  278.     cmp    al, 0
  279.     jge    NOCLIP4
  280.     neg    al
  281.     mov    win_clip_y1, al
  282. NOCLIP4:
  283.  
  284. ; window ul_x
  285.  
  286.     mov    al,frame.y1
  287.     add    al, win_clip_y1
  288.     mov    win_ul_y, al
  289.  
  290. ; visible height
  291.  
  292.     mov    ah, win_height
  293.     sub    ah, win_clip_y1
  294.     sub    ah, win_clip_y2
  295.     mov    win_clip_height, ah
  296.  
  297. ; win_name length
  298.  
  299.     mov    cl, win_width
  300.     sub    cl, 4
  301.     jle    NONAME
  302.     xor    ch, ch
  303.     mov    dx, cx
  304.     mov    di, frame.win_name
  305.     or    di, di
  306.     je    NONAME
  307.     xor    al, al
  308.     dec    di
  309. L0:
  310.     inc    di
  311.     cmp    al, [di]
  312.     loopne    L0
  313.     inc    cx
  314.     sub    dx, cx
  315.     mov    win_name_len, dl
  316. NONAME:
  317.  
  318. ; get attributes together
  319.  
  320.     mov    ax, frame.fr_bg
  321.     mov    ah, al
  322.     xor    al, al
  323.     or    ax, frame.fr_fg
  324.     mov    bx, frame.int_bg
  325.     mov    bh, bl
  326.     xor    bl, bl
  327.     or    bx, frame.int_fg
  328.  
  329. ; truncate... for backgrounds, shave off blink bits, too
  330.  
  331.     and    ah, 07h
  332.     and    bh, 07h
  333.     and    bl, 0fh
  334.     and    al, 0fh
  335.  
  336. ; if monochrome, convert all but white backgrounds to no backgrounds
  337.  
  338.     push    ax
  339.     push    bx
  340.     mov    ah, 0fh
  341.     int    10h
  342.     cmp    al, 07h
  343.     pop    bx
  344.     pop    ax
  345.     je    MDAMODE
  346.     cmp    graphics_type, 4
  347.     jl    COLOR
  348. MDAMODE:
  349.     cmp    ah, 07h
  350.     jz    SET_BG
  351.     xor    ah, ah
  352.  
  353. ; if you clear the background, make sure foreground is not black
  354.  
  355.     or    al, 02h
  356.     jmp    short    CLR_BG
  357.  
  358. ; if you set it, make foreground black
  359.  
  360. SET_BG:
  361.  
  362.     xor    al,al
  363.  
  364. CLR_BG:
  365.     cmp    bh, 07h
  366.     jz    SET_BG2
  367.     xor    bh,bh
  368.     or    bl, 02h
  369.     jmp    short    CLR_BG2
  370.  
  371. SET_BG2:
  372.     xor    bl,bl
  373. CLR_BG2:
  374.  
  375. ; and all foregrounds but white foregrounds to low intensity
  376.  
  377.     cmp    al, 0fh
  378.     jz    SET_FRCLR
  379.     and    al, 07h
  380.  
  381. SET_FRCLR:
  382.     cmp    bl, 0fh
  383.     jz    SET_FRCLR2
  384.     and    bl, 07h
  385.  
  386. SET_FRCLR2:
  387.  
  388. ; zap underline bits
  389.  
  390.     and    al, 0eh
  391.     and    bl, 0eh
  392.  
  393. COLOR:
  394.     mov    cl, 4
  395.     shl    ah, cl
  396.     or    al, ah
  397.     shl    bh, cl
  398.     or    bl, bh
  399.     mov    frame_attrib, al
  400.     mov    int_attrib, bl
  401.  
  402. ; if not immortal, get some memory for screen image
  403.  
  404.     mov    ax, frame.immortalflag
  405.     or    ax, 0
  406.     jne    IMMORTAL
  407.  
  408.     mov    bl, win_clip_height
  409.     mov    al, win_clip_width
  410.     mul    bl
  411.     mov    bx, ax
  412.     dec    cl
  413.     shr    bx, cl
  414.     inc    bx    ; paranoia
  415.     mov    ah, 48h
  416.     int    21h
  417.     jnc    GOT_MEMORY
  418.  
  419. ; lose with memory
  420.  
  421.     xor    ax, ax
  422.     pop    si
  423.     pop    di
  424.     pop    es
  425.         pop    bp
  426.            ret
  427.  
  428. IMMORTAL:
  429.  
  430.     xor    ax, ax
  431.  
  432. GOT_MEMORY:
  433.  
  434.     mov    screen_image, ax
  435.  
  436. ; calculate addresses
  437.  
  438.     mov    cl, win_clip_height
  439.     xor    ch, ch
  440.     mov    bh, win_ul_x
  441.     mov    bl, win_ul_y
  442.     mov    dl, win_clip_width
  443.  
  444. ; if not immortal, make copy
  445.  
  446.     or    ax, 0
  447.     je    IMMORTAL2
  448.  
  449.     mov    es, ax
  450.     call    stow_screen_image
  451.  
  452.     push    ds
  453.     pop    es
  454.  
  455. IMMORTAL2:
  456.  
  457. ; if top is clipped, don't bother with titlebar
  458.  
  459.     or    win_clip_y1, 0
  460.     jnz    NOTB
  461.     
  462. ; create titlebar
  463.  
  464.     push    cx
  465.     mov    al, ul_sym
  466.     mov    ah, frame_attrib
  467.     mov    di, offset dgroup:line_buffer
  468.     stosw
  469.  
  470. ; now for the interior
  471.  
  472.     push    ds
  473.     pop    es
  474.     mov    cl, win_clip_width
  475.     mov    al, win_name_len
  476.     or    al, al
  477.     jnz    HASNAME
  478.     sub    cl, 2
  479.     mov    al, hori_sym
  480. rep    stosw
  481.     jmp    short    NONAME2
  482.  
  483.  
  484. HASNAME:
  485.     sub    cl, 4
  486.     sub    cl, al
  487.     sar     cl, 1
  488.     push    cx
  489.     jnc    NO_ROUNDOFF
  490.     inc    cl
  491.  
  492. NO_ROUNDOFF:
  493.  
  494.     mov    al, hori_sym
  495. rep    stosw
  496.     mov    al, l_nm_bnd_sym
  497.     stosw
  498.  
  499.     mov    cl, win_name_len
  500.     mov    dx, frame.win_name
  501.     mov    si, dx
  502. L3:
  503.     mov    al, [si]
  504.     mov    [di], ax
  505.     inc    si
  506.     inc    di
  507.     inc    di
  508.     loop     L3
  509.  
  510.     mov    al, r_nm_bnd_sym
  511.     stosw
  512.     pop    cx
  513.     mov    al, hori_sym
  514. rep    stosw
  515.  
  516. ; and the right frame
  517.  
  518.  
  519. NONAME2:
  520.     mov    al, ur_sym
  521.     mov    [di], ax
  522.  
  523. ; screen it
  524.     mov    al, win_clip_x1
  525.     shl    al, 1
  526.     xor    ah, ah
  527.     add    ax, offset dgroup:line_buffer
  528.     mov    si, ax
  529.     mov    cl, win_clip_width
  530.     xor    ch, ch
  531.     mov    ax, video_seg
  532.     call    sho_word_buff
  533.  
  534. ; fix counters
  535.     pop    cx
  536.     dec    cx
  537.     jcxz    EXIT_JUMPOFF
  538.     inc    bl
  539.     jmp    short    CONT0
  540.  
  541. EXIT_JUMPOFF:
  542.     jmp    EXIT
  543.  
  544. CONT0:
  545. NOTB:
  546. ; create generic middle line
  547.  
  548.     push    cx
  549.     mov    al, vert_sym
  550.     mov    ah, frame_attrib
  551.     mov    di, offset dgroup:line_buffer
  552.     stosw
  553.  
  554. ; now for the interior
  555.  
  556.     xor    al,al
  557.     mov    ah, int_attrib
  558.     push    ds
  559.     pop    es
  560.     mov    cl, win_clip_width
  561.     sub    cl, 2
  562. rep    stosw
  563.  
  564. ; and the right frame
  565.  
  566.     mov    al, vert_sym
  567.     mov    ah, frame_attrib
  568.     mov    word ptr [di], ax
  569.     pop    cx
  570.  
  571. ; if bottom is not clipped, reserve last line
  572.  
  573.     or    win_clip_y2, 0
  574.     jnz    NOLASTLINE
  575.     dec    cl
  576. NOLASTLINE:
  577.  
  578. ; screen it
  579.     mov    al, win_clip_x1
  580.     shl    al, 1
  581.     xor    ah, ah
  582.     add    ax, offset dgroup:line_buffer
  583.     mov    dx, ax
  584.     mov    ax, video_seg
  585. L1:
  586.     push    cx
  587.     mov    si, dx
  588.     mov    cl, win_clip_width
  589.     call    sho_word_buff
  590.     inc    bl
  591.     pop    cx
  592.     loop    L1
  593.  
  594. ; if bottom is not clipped, continue
  595.  
  596.     or    win_clip_y2, 0
  597.     jnz    EXIT
  598.  
  599. ; create bottom line
  600.  
  601.     mov    al, ll_sym
  602.     mov    ah, frame_attrib
  603.     mov    di, offset dgroup:line_buffer
  604.     stosw
  605.  
  606. ; now for the interior
  607.  
  608.     mov    al, hori_sym
  609.     push    ds
  610.     pop    es
  611.     mov    cl, win_clip_width
  612.     sub    cl, 2
  613. rep    stosw
  614.  
  615. ; and the right frame
  616.  
  617.     mov    al, lr_sym
  618.     stosw
  619.  
  620. ; screen it
  621.  
  622.     mov    al, win_clip_x1
  623.     shl    al, 1
  624.     xor    ah, ah
  625.     add    ax, offset dgroup:line_buffer
  626.     mov    si, ax
  627.     mov    cl, win_clip_width
  628.     xor    ch, ch
  629.     mov    ax, video_seg
  630.     call    sho_word_buff
  631. EXIT:
  632.  
  633. ; give handle information
  634.  
  635.     push    ds
  636.     pop    es
  637.     mov    ax, frame.handle
  638.     mov    di, ax
  639.     mov    al, 1
  640.     stosb
  641.     mov    ax, frame.win_name
  642.     stosw
  643.     mov    al, frame.x1
  644.     stosb
  645.     mov    al, frame.y1
  646.     stosb
  647.     mov    al, win_ul_x
  648.     stosb
  649.     mov    al, win_ul_y
  650.     stosb
  651.     mov    ax, frame.frameflag
  652.     stosb
  653.     mov    ax, frame.immortalflag
  654.     stosb
  655.     xor    al, al    ; clear hidden flag
  656.     stosb
  657.     mov    si, offset dgroup:screen_image
  658.     movsw
  659.     mov    cx, 6
  660. rep    movsb
  661.     xor    ax, ax    ; clear array
  662.     stosw
  663.  
  664. ; outta  here
  665.  
  666. ERREXIT:
  667.  
  668.     pop    si
  669.     pop    di
  670.     pop    es
  671.         pop    bp
  672.            ret
  673.  
  674. _mk_window    ENDP
  675.  
  676. ; ------------------------------------------
  677.  
  678. stow_screen_image    proc    near
  679.  
  680. ; on entry, registers should be
  681. ; bh - x coordinate
  682. ; bl - y coordinate
  683. ; cl - height of image
  684. ; dl - length of image
  685. ; es - destination segment
  686.  
  687.     push    ax
  688.     push    bx
  689.     push    cx
  690.     push    ds
  691.     push    di
  692.     push    si
  693.  
  694. ; get segment stuff straight
  695.  
  696.     xor    ax, ax
  697.     mov    di, ax
  698.     mov    ax, video_seg
  699.     mov    ds, ax
  700.  
  701. ; calculate initial offset
  702.  
  703.     mov    al, 160
  704.     mul    bl
  705.     mov    bl,bh
  706.     xor    bh, bh
  707.     shl    bl,1
  708.     add    ax, bx
  709. SSIL0:
  710.     mov    si, ax
  711.     push    cx
  712.     mov    cl, dl
  713. rep    movsw
  714.     pop    cx
  715.     add    ax, 160
  716.     loop    SSIL0
  717.  
  718.     pop    si
  719.     pop    di
  720.     pop    ds
  721.     pop    cx
  722.     pop    bx
  723.     pop    ax
  724.  
  725.     ret
  726.  
  727. stow_screen_image    ENDP
  728.  
  729. ; ---------------------------------------------
  730.  
  731. sho_word_buff    proc    near
  732.  
  733. ; on entry, registers should be
  734. ; ax - video segment
  735. ; bh - x coordinate
  736. ; bl - y coordinate
  737. ; cx - length of string
  738. ; ds - source string segment
  739. ; si - source offset
  740.  
  741.  
  742.     push    ax
  743.     push    bx
  744.     push    es
  745.     push    di
  746.  
  747.     mov    es, ax
  748.  
  749.     mov    al, 160
  750.     mul    bl
  751.     mov    bl,bh
  752.     xor    bh, bh
  753.     shl    bl,1
  754.     add    ax, bx
  755.     mov    di, ax
  756.  
  757. ; kludge for snow
  758.  
  759.     cmp    cs:localsnow, 0
  760.     je    SWNOSNOW
  761.     mov    cs:snow_write_type, 2
  762.     call    snowwrite
  763.     jmp    short    SWBEXIT
  764.  
  765. SWNOSNOW:
  766. rep    movsw
  767.  
  768. SWBEXIT:
  769.     pop    di
  770.     pop    es
  771.     pop    bx
  772.     pop    ax
  773.  
  774.     ret
  775.  
  776. sho_word_buff    ENDP
  777.  
  778. ; ---------------------------------------------
  779.  
  780. _kill_window    proc    near
  781.  
  782. ; void kill_window( win_handle *)
  783.  
  784.     killframe    struc
  785.     kbptr        dw    ?
  786.     kraddr        dw    ?
  787.     khandle        dw    ?
  788.     killframe    ends
  789.  
  790.     kframe    equ    [bp - kbptr]
  791.  
  792.     push     bp        ; Stack frame manipulations
  793.     mov     bp,sp
  794.     sub    sp,kbptr
  795.     push    di
  796.     push    si
  797.     push    ds
  798.     push    es
  799.  
  800.     mov    ax, kframe.khandle
  801.     mov    di, ax
  802.  
  803. ; unlinked, immortal or hidden?
  804.  
  805.     xor    al, al
  806.     cmp    al, made
  807.     je    KANTKILL
  808.     or    al, immortal_flag
  809.     jne    KANTKILL
  810.  
  811. ; committed to removing window -- set made flag
  812.  
  813.     mov    made, al
  814.  
  815. ; determine if hidden
  816.  
  817.     or    al, hidden_flag
  818.     je    KNOTHIDDEN
  819.  
  820.     mov    ax, ptr_behind_window
  821.     mov    es, ax
  822.     jmp    short    KHIDDEN
  823.  
  824. KNOTHIDDEN:
  825.     mov    ax, video_seg
  826.     push    ax
  827.  
  828.     mov    ah, ulx    ; ulx
  829.     mov    al, uly    ; uly
  830.     mov    cl, image_h    ; image_h
  831.     mov    bl, image_w    ; image_w
  832.     mov    dx, ptr_behind_window    ; allocated_segment
  833.     mov    ds, dx
  834.     mov    dl, bl
  835.  
  836.     xor    ch, ch
  837.  
  838.     mov    bx, ax
  839.     xor    ax, ax
  840.     mov    si, ax
  841.     pop    ax
  842.  
  843. KB0:
  844.     push    cx
  845.     mov    cl, dl
  846.     call    sho_word_buff
  847.     inc    bl
  848.     pop    cx
  849.     loop    KB0
  850.  
  851. ; try to put  memory back
  852.  
  853.     push    ds
  854.     pop    es
  855.  
  856. KHIDDEN:
  857.  
  858.     mov    ah, 49h
  859.     int    21h
  860.  
  861. KANTKILL:
  862.  
  863.     pop    es
  864.     pop    ds
  865.  
  866.     pop    si
  867.     pop    di
  868.         pop    bp
  869.  
  870.     ret
  871.  
  872. _kill_window    ENDP
  873.  
  874. ; ---------------------------------------------
  875.  
  876. _link_array    proc    near
  877.  
  878. ; void link_array( win_handle *, 
  879. ;           char * ary_ptr,
  880. ;           int aryx,
  881. ;           int aryy,
  882. ;           int aryoffx,
  883. ;           int aryoffy
  884. ;               )
  885.  
  886.     linkframe    struc
  887.     lbptr        dw    ?
  888.     lraddr        dw    ?
  889.     lhandle        dw    ?
  890.     ary_ptr        dw    ?
  891.     aryx        dw    ?
  892.     aryy        dw    ?
  893.     aryoffx        dw    ?
  894.     aryoffy        dw    ?
  895.     linkframe    ends
  896.  
  897.     lframe    equ    [bp - lbptr]
  898.  
  899.     push     bp        ; Stack frame manipulations
  900.     mov     bp,sp
  901.     sub    sp,lbptr
  902.     push    di
  903.     push    si
  904.     push    ds
  905.  
  906. ;     made?
  907.  
  908.     mov     ax, lframe.lhandle
  909.     mov    di, ax
  910.     xor    ax, ax
  911.     cmp    al, made
  912.     jne    LMADE
  913.     jmp    BAD_LINK
  914.  
  915. LMADE:
  916.  
  917. ;    calculate x, y point for array display
  918.  
  919.     mov    bh, handx1
  920.     mov    bl, handy1
  921.     mov    ah, w    ; w
  922.     mov    al, h    ; h
  923.     mov    cl, image_h
  924.     mov    dl, image_w
  925.  
  926.     xor    ch, ch
  927.     xor    dh, dh
  928.  
  929. ;    correct image widths and heights
  930.  
  931.     push    bx
  932.     
  933.     cmp    bh, 0
  934.     jl    LCLIP0
  935.     dec    dl
  936. LCLIP0:
  937.     add    bh, ah
  938.     cmp    bh, 80
  939.     jge    LCLIP1
  940.     dec    dl
  941. LCLIP1:
  942.     cmp    bl, 0
  943.     jl    LCLIP2
  944.     dec    cl
  945. LCLIP2:
  946.     add    bl, al
  947.     cmp    bl, 80
  948.     jge    LCLIP3
  949.     dec    cl
  950. LCLIP3:
  951.  
  952.     pop    bx
  953.     
  954. ; dump off some handle stuff
  955.  
  956.     mov    ax, lframe.lhandle
  957.     mov    di, ax
  958.     mov    da_im_h, cl    ; da_im_h
  959.     mov    da_im_w, dl    ; da_im_w
  960.     xor    ax, ax
  961.  
  962. ; calculate addresses for bx and offsets for si
  963.  
  964.     inc    bh
  965.     inc    bl
  966.  
  967.     cmp    bh, 0
  968.     jge    LNOCLIP0
  969.     neg    bh
  970.     mov    ah, bh
  971.     xor    bh, bh
  972. LNOCLIP0:
  973.     cmp    bl, 0
  974.     jge    LNOCLIP1
  975.     neg    bl
  976.     mov    al, bl
  977.     xor    bl, bl
  978. LNOCLIP1:
  979.  
  980. ; total offsets
  981.  
  982.     push    bx
  983.  
  984.     push    ax
  985.  
  986.     xor    ah,ah
  987.     add    ax, lframe.aryoffy
  988.     mov    bx, lframe.aryy        ; total y dimension
  989.     sub    bx, ax
  990.     jg    LOK0
  991.     pop    ax
  992.     pop    bx
  993.     jmp    BAD_LINK
  994. LOK0:
  995.     cmp    cx, bx
  996.     jl    LCXSMALLER
  997.     mov    cx, bx
  998. LCXSMALLER:
  999.     mov    bx, lframe.lhandle
  1000.     mov    di, bx
  1001.     mov    day_off_ul, ax    ; day_off_ul
  1002.  
  1003.     mov    bx, lframe.aryx    ; total x dimension
  1004.     push    dx
  1005.     mul    bx
  1006.     pop    dx
  1007.     mov    si, ax        ; row offset acounted for
  1008.                 ; borrow si for a spell    
  1009.  
  1010.     pop    ax
  1011.     mov    al, ah
  1012.     xor    ah,ah
  1013.     add    ax, lframe.aryoffx    ; x offset
  1014.     mov    bx, lframe.aryx     ; total x dimension
  1015.     sub    bx, ax
  1016.     jg    LOK1
  1017.     pop    bx
  1018.     jmp    BAD_LINK
  1019. LOK1:
  1020.     cmp    dx, bx
  1021.     jl    LDXSMALLER
  1022.     mov    dx, bx
  1023. LDXSMALLER:
  1024.  
  1025.     mov    bx, lframe.lhandle
  1026.     mov    di, bx
  1027.     mov    dax_off_ul, ax          ; dax_off_ul
  1028.  
  1029.     mov    bx,si
  1030.     add    ax, bx
  1031.     add    ax, lframe.ary_ptr
  1032.     mov    si, ax        ; column offset acounted for
  1033.  
  1034.     pop    bx
  1035.  
  1036. ; give params to handle
  1037.  
  1038.     mov    ax, lframe.lhandle
  1039.     mov    di, ax
  1040.     mov    da_ulx, bh    ; da_ulx
  1041.     mov    da_uly, bl    ; da_uly
  1042.  
  1043. ; now, si is okay, dl is width counter, cl is height counter
  1044.  
  1045.     mov    dh, interior_attrib    ; interior_attrib
  1046.     mov    ax, si
  1047.  
  1048. LLB0:
  1049.     push    cx
  1050.     mov    cl, dl
  1051.     push    ax
  1052.     mov    ax, video_seg
  1053.     call    showbuffer
  1054.     pop    ax
  1055.     add    ax, lframe.aryx
  1056.     mov    si, ax
  1057.     inc    bl
  1058.     pop    cx
  1059.     loop    LLB0
  1060.  
  1061. ; scroll bar?
  1062.  
  1063.     push    ds
  1064.     pop    es
  1065.  
  1066.     mov    ax, lframe.lhandle
  1067.     mov    di, ax
  1068.  
  1069.     mov    al, h
  1070.     mov    bx, lframe.aryy
  1071.     dec    al
  1072.     dec    al
  1073.     xor    bh, bh
  1074.     cmp    al, bl
  1075.     jge    NOSCROLLBAR
  1076.  
  1077.     mov    ax, video_seg
  1078.     mov    bh, handx1
  1079.     add    bh, w
  1080.     dec    bh
  1081.     dec    bh
  1082.     mov    bl, handy1
  1083.     inc    bl
  1084.     mov    cx, lframe.aryy
  1085.     mov    ch, cl
  1086.     mov    cl, h
  1087.     mov    dx, lframe.aryoffy
  1088.     call    scrollbar
  1089.  
  1090. NOSCROLLBAR:
  1091.  
  1092. ; fix handle stuff
  1093.  
  1094.     mov    ax, lframe.lhandle
  1095.     push    ax
  1096.     add    ax, 18
  1097.     mov    di, ax
  1098.  
  1099.     mov    ax, lframe.ary_ptr
  1100.     stosw
  1101.     mov    ax, lframe.aryx
  1102.     stosw
  1103.     mov    ax, lframe.aryy
  1104.     stosw
  1105.     mov    ax, lframe.aryoffx
  1106.     stosw
  1107.     mov    ax, lframe.aryoffy
  1108.     stosw
  1109.  
  1110.     pop    ax
  1111.     jmp    short    LEXIT
  1112.  
  1113. BAD_LINK:
  1114.     xor    ax, ax
  1115.  
  1116. LEXIT:
  1117.     pop    ds
  1118.     pop    si
  1119.     pop    di
  1120.         pop    bp
  1121.  
  1122.     ret
  1123.  
  1124. _link_array    ENDP
  1125.  
  1126. ; ---------------------------------------------
  1127.  
  1128. showbuffer    proc    near
  1129.  
  1130. ; on entry, registers should be
  1131. ; ax - video segment
  1132. ; bh - x coordinate
  1133. ; bl - y coordinate
  1134. ; cx - length of string
  1135. ; ds - source string segment
  1136. ; si - source offset
  1137. ; dh - attribute
  1138.  
  1139.     push    es
  1140.     push    di
  1141.  
  1142.     push    ds
  1143.     pop    es
  1144.  
  1145.     push    ax
  1146.     push    cx
  1147.     mov    ax, offset dgroup:line_buffer
  1148.     mov    di, ax
  1149.     mov    ah, dh
  1150.     push    di
  1151.  
  1152.  
  1153. SBL0:
  1154.     lodsb
  1155.     stosw
  1156.     loop    SBL0
  1157.  
  1158.     pop    si
  1159.     pop    cx
  1160.     pop    ax
  1161.     call    sho_word_buff
  1162.  
  1163.     pop    di
  1164.     pop    es
  1165.     ret
  1166.  
  1167. showbuffer    ENDP
  1168.  
  1169. ; ---------------------------------------------
  1170.  
  1171. scrollbar    proc    near
  1172.  
  1173. ; on entry, registers should be
  1174. ; ax - video segment
  1175. ; bh - x coordinate
  1176. ; bl - y coordinate
  1177. ; cl - window height
  1178. ; ch - array length
  1179. ; dx - height offset into array
  1180.  
  1181.     push    es
  1182.     push    di
  1183.  
  1184.     mov    es, ax
  1185.     cmp    bh, 79
  1186.     jg    SBAREXIT
  1187.     cmp    bl, 25
  1188.     jg    SBAREXIT
  1189.     dec    cl
  1190.     dec    cl
  1191.     sub    ch, cl
  1192.     jle    SBAREXIT
  1193.  
  1194.     mov    ax, 25
  1195.     sub    al, bl
  1196.     push    ax       ;  screen limitation
  1197.     mov    ax, cx
  1198.     xor    ah, ah
  1199.     push    ax     ;  window height
  1200.     mul    dl     ;
  1201.  
  1202.     mov    cl, ch
  1203.     xor    ch, ch     ; number of lines available
  1204.     div    cl     ; number of 'empty blocks'
  1205.     xor    ah, ah
  1206.     mov    cx, ax
  1207.     pop    ax
  1208.     sub    ax, cx    ;  number of 'full blocks'
  1209.     push    ax
  1210.  
  1211.     mov    dx, 160
  1212.     mov    al, bl
  1213.     mov    bl, bh
  1214.     xor    ah, ah
  1215.     xor    bh, bh
  1216.     mul    dl
  1217.     shl    bx, 1
  1218.     add    ax, bx
  1219.     mov    di, ax    ; offset into video seg
  1220.  
  1221.     pop    bx    ; number of full blocks
  1222.     pop    dx    ; screen limitation
  1223.     cmp    cx, dx
  1224.     jle    SBCXISMALL
  1225.     mov    cx, dx
  1226. SBCXISMALL:
  1227.     push    dx
  1228.     mov    dx, di
  1229.     push    cx     ; do empty blocks cx times
  1230.     mov    ax, 02b0h
  1231.     jcxz    SCRDONEL0
  1232. SCRBL0:
  1233.     stosw
  1234.     add    dx, 160
  1235.     mov    di, dx
  1236.     loop    SCRBL0
  1237.  
  1238. SCRDONEL0:
  1239.  
  1240.     pop    cx
  1241.     pop    dx
  1242.     sub    dx, cx
  1243.     jle    SBAREXIT
  1244.  
  1245.     mov    cx, bx
  1246.     cmp    cx, dx
  1247.     jle    SBCXISMALL2
  1248.     mov    cx, dx
  1249.  
  1250. SBCXISMALL2:
  1251.     ; do full blocks cx times
  1252.     mov    dx, di
  1253.     mov    ax, 0cb2h
  1254.     jcxz    SBAREXIT
  1255. SCRBL1:
  1256.     stosw
  1257.     add    dx, 160
  1258.     mov    di, dx
  1259.     loop    SCRBL1
  1260.  
  1261. SBAREXIT:
  1262.     pop    di
  1263.     pop    es
  1264.     ret
  1265.  
  1266. scrollbar    ENDP
  1267. ;---------------------------------------------
  1268.  
  1269. _new_cursor    proc    near
  1270.  
  1271. ; int new_cursor ( int value)
  1272.  
  1273.     ncurseframe    struc
  1274.     ncbptr        dw    ?
  1275.     ncraddr        dw    ?
  1276.     ncvalue        dw    ?
  1277.     ncurseframe    ends
  1278.  
  1279.     ncframe    equ    [bp - ncbptr]
  1280.  
  1281.     push     bp        ; Stack frame manipulations
  1282.     mov     bp,sp
  1283.     sub    sp,ncbptr
  1284.     push    di
  1285.     push    si
  1286.  
  1287.     mov    ah, 0fh
  1288.     int    10h        ; status
  1289.  
  1290.     mov    ah, 03h
  1291.     int    10h        ; get type
  1292.  
  1293.     push    cx
  1294.     mov    cx, ncframe.ncvalue
  1295.     mov    ah, 01h
  1296.     int    10h
  1297.  
  1298.     pop    ax
  1299.  
  1300.     pop    si
  1301.     pop    di
  1302.         pop    bp
  1303.  
  1304.     ret
  1305.  
  1306. _new_cursor    ENDP
  1307.  
  1308. ; ---------------------------------------------
  1309.  
  1310. _hide_window    proc    near
  1311.  
  1312. ; void hide_window( win_handle *)
  1313.  
  1314.     hideframe    struc
  1315.     hbptr        dw    ?
  1316.     hraddr        dw    ?
  1317.     hhandle        dw    ?
  1318.     hideframe    ends
  1319.  
  1320.     hframe    equ    [bp - hbptr]
  1321.  
  1322.     push     bp        ; Stack frame manipulations
  1323.     mov     bp,sp
  1324.     sub    sp,hbptr
  1325.     push    di
  1326.     push    si
  1327.     push    ds
  1328.  
  1329. ; grab some temorary memory
  1330.  
  1331.  
  1332.     mov    ax, hframe.hhandle
  1333.     mov    di, ax
  1334.  
  1335. ; made?
  1336.  
  1337.     xor    al, al
  1338.     cmp    al, made
  1339.     je    CANTHIDE
  1340.  
  1341. ; immortal?
  1342.  
  1343.     mov    al, immortal_flag
  1344.     or    al, 0
  1345.     jne    CANTHIDE
  1346.  
  1347.     mov    bl, image_h    ; image_h
  1348.     mov    al, image_w    ; image_w
  1349.     mul    bl
  1350.     mov    bx, ax
  1351.  
  1352.     push    bx    ; length of screen image in words
  1353.  
  1354.     mov    cl, 3
  1355.     shr    bx, cl
  1356.     inc    bx    ; paranoia
  1357.     mov    ah, 48h
  1358.     int    21h
  1359.     jc    HIDELOSER
  1360.     jmp    short    GOT_TEMP_BUFFER
  1361.  
  1362. HIDELOSER:
  1363.  
  1364. ; debug
  1365.     mov    ax, 5900h
  1366.     xor    bx, bx
  1367.     int    21h
  1368.  
  1369.     pop    bx
  1370.  
  1371. ; lose with memory, or it's immortal
  1372.  
  1373. CANTHIDE:
  1374.  
  1375.     pop    ds
  1376.     pop    si
  1377.     pop    di
  1378.         pop    bp
  1379.            ret
  1380.  
  1381. GOT_TEMP_BUFFER:
  1382.  
  1383. ; store screen in temp buffer
  1384.  
  1385.     push    ax    ; save address of temporary buffer
  1386.  
  1387.     mov    es, ax
  1388.     mov    ax, hframe.hhandle
  1389.     mov    di, ax
  1390.  
  1391.     mov    bh, ulx    ; ulx
  1392.     mov    bl, uly    ; uly
  1393.     mov    cl, image_h    ; image_h
  1394.     mov    dl, image_w    ; image_w
  1395.     xor    ch, ch
  1396.  
  1397.     call    stow_screen_image
  1398.  
  1399. ; dump old buffer on screen
  1400.  
  1401.     mov    ax, video_seg
  1402.     push    ax
  1403.  
  1404.     mov    ax, ptr_behind_window    ; segment of old screen
  1405.     mov    ds, ax
  1406.  
  1407.     xor    ax, ax
  1408.     mov    si, ax
  1409.     pop    ax
  1410.  
  1411. H0:
  1412.     push    cx
  1413.     mov    cl, dl
  1414.     call    sho_word_buff
  1415.     inc    bl
  1416.     pop    cx
  1417.     loop    H0
  1418.  
  1419. ; now put temp buffer into old location
  1420.  
  1421.     push    ds    ; old screen
  1422.     pop    es    ; old screen
  1423.     pop    ds    ; temp buffer
  1424.     pop    cx    ; length of screen image, in words
  1425.  
  1426.     xor    ax, ax
  1427.     mov    di, ax
  1428.     mov    si, ax
  1429. rep    movsw
  1430.  
  1431. ; put temp  memory back
  1432.  
  1433.     push    ds
  1434.     pop    es    ; temp_buffer
  1435.  
  1436.     mov    ah, 49h
  1437.     int    21h
  1438.  
  1439.     pop    ds
  1440.  
  1441. ;  toggle hidden flag
  1442.  
  1443.     mov    ax, hframe.hhandle
  1444.     mov    di, ax
  1445.     not    byte ptr hidden_flag
  1446.  
  1447. ; go home
  1448.  
  1449.     pop    si
  1450.     pop    di
  1451.         pop    bp
  1452.  
  1453.     ret
  1454.  
  1455. _hide_window    ENDP
  1456.  
  1457. ; ---------------------------------------------
  1458.  
  1459. _scroll        proc    near
  1460.  
  1461. ; int scroll( win_handle *, int upflag)
  1462. ; returns non-zero if successful, zero on failure
  1463.  
  1464.     scrollframe    struc
  1465.     sbptr        dw    ?
  1466.     sraddr        dw    ?
  1467.     shandle        dw    ?
  1468.     upflag        dw    ?
  1469.     scrollframe    ends
  1470.  
  1471.     sframe    equ    [bp - sbptr]
  1472.  
  1473.     push     bp        ; Stack frame manipulations
  1474.     mov     bp,sp
  1475.     sub    sp,sbptr
  1476.     push    di
  1477.     push    si
  1478.     push    es
  1479.  
  1480. ;    check if window is made and linked
  1481.  
  1482.     mov    ax, sframe.shandle
  1483.     mov    di, ax
  1484.  
  1485.     xor    ax, ax
  1486.  
  1487.     cmp    al, made
  1488.     jnz    C0
  1489.     cmp    ax, ptr_displayed_array
  1490.     jnz    C0
  1491.     jmp    SCROLL_FAILED
  1492.  
  1493. C0:
  1494.     cmp    ax, sframe.upflag
  1495.     jz    SCROLL_DOWN
  1496.  
  1497. ;    check if array is at scroll limit
  1498.  
  1499.     cmp    ax, day_off_ul    ; day_off_log
  1500.     jnz    C1
  1501.     jmp    SCROLL_FAILED
  1502.  
  1503. C1:
  1504.  
  1505.     mov    bx, da_ulx    ; bh=da_uly, bl=da_ulx
  1506.     xchg    bh, bl
  1507.     mov    ax, da_im_w    ; ah=da_im_h, al=da_im_w
  1508.     xchg    ah, al
  1509.     add    ax, bx
  1510.     dec    al        ; now ah=lrx, al=lry
  1511.     mov    dx, bx
  1512.     inc    dl
  1513.  
  1514.     call    charblit
  1515.     push    ds
  1516.     pop    es
  1517.  
  1518.      sub    ah, bh
  1519.     dec    ah        ; now ah=length
  1520.  
  1521. ; call showbuffer with pointer to row above
  1522.  
  1523.     mov    cx, dax
  1524.     or    ch, 0
  1525.     jnz    CAHSMALLER
  1526.     cmp    ah, cl
  1527.     jl    CAHSMALLER
  1528.     jmp    short    CCLSMALLER
  1529.  
  1530. CAHSMALLER:
  1531.     mov    cl, ah
  1532.     xor    ch, ch
  1533.  
  1534. CCLSMALLER:
  1535.  
  1536.     push    bx
  1537.     mov    ax,day_off_ul    ; day_off_ul
  1538.     dec    ax
  1539.     mov    bx, dax    ; dax
  1540.     mul    bx
  1541.     add    ax, dax_off_ul    ; dax_off_ul
  1542.     add    ax, ptr_displayed_array    ; array pointer
  1543.     mov    si, ax
  1544.     mov    ax, video_seg
  1545.     mov    dh, interior_attrib    ; interior attrib
  1546.     pop    bx
  1547.  
  1548.     call     showbuffer
  1549.  
  1550. ; update offsets
  1551.  
  1552.     dec    word ptr day_off_log
  1553.     dec    word ptr day_off_ul
  1554.     jmp    short    SBUPDATE
  1555.  
  1556. SCROLL_DOWN:
  1557.  
  1558.     mov    ax, day    ; day
  1559.     sub    ax, day_off_log    ; day_off_log
  1560.     or    ah, 0        ; if difference is greater than 128, forget it
  1561.     jne    SCROLL_FAILED
  1562.     inc    al
  1563.     inc    al        ; trick for height - frame
  1564.     cmp    al, h    ; logical height
  1565.     jle    SCROLL_FAILED
  1566.  
  1567.     mov    bx, da_ulx    ; bh=da_uly, bl=da_ulx
  1568.     xchg    bh, bl
  1569.     mov    ax, da_im_w    ; ah=da_im_h, al=da_im_w
  1570.     xchg    ah, al
  1571.     add    ax, bx
  1572.     mov    dx, bx
  1573.     inc    bl
  1574.  
  1575.     call    charblit
  1576.     push    ds
  1577.     pop    es
  1578.  
  1579.     sub    ah, bh
  1580.     dec    ah        ; now ah=length
  1581.     mov    bl, al        ; now bl = destination
  1582.     dec    bl
  1583.     push    bx
  1584.  
  1585. ; call showbuffer with pointer to row below
  1586.  
  1587.     mov    cx, dax    ; dax
  1588.     or    ch, 0
  1589.     jnz    CAHSMALLER2
  1590.     cmp    ah, cl
  1591.     jl    CAHSMALLER2
  1592.     jmp    short    CCLSMALLER2
  1593.  
  1594. CAHSMALLER2:
  1595.     mov    cl, ah
  1596.     xor    ch, ch
  1597.  
  1598. CCLSMALLER2:
  1599.  
  1600.     xor    ah, ah
  1601.     mov    al, da_im_h
  1602.     add    ax, day_off_ul    ; day_off_ul
  1603.     mov    bx, dax    ; dax
  1604.     mul    bx
  1605.     add    ax, dax_off_ul    ; dax_off_ul
  1606.     add    ax, ptr_displayed_array    ; array pointer
  1607.     mov    si, ax
  1608.     mov    ax, video_seg
  1609.     mov    dh, interior_attrib    ; interior attrib
  1610.     pop    bx
  1611.  
  1612.     call     showbuffer
  1613.  
  1614. ; update offsets
  1615.  
  1616.     inc    word ptr day_off_log
  1617.     inc    word ptr day_off_ul
  1618.     jmp    short    SBUPDATE
  1619.  
  1620. SCROLL_FAILED:
  1621.     xor    ax, ax
  1622.     jmp    short    SEXIT
  1623.  
  1624. SBUPDATE:
  1625.     push    ds
  1626.     pop    es
  1627.     mov    ax, sframe.shandle
  1628.     mov    di, ax
  1629.  
  1630.     mov    ax, video_seg
  1631.     mov    bh, handx1
  1632.     add    bh, w
  1633.     dec    bh
  1634.     dec    bh
  1635.     mov    bl, handy1
  1636.     inc    bl
  1637.     mov    cx, day
  1638.     mov    ch, cl
  1639.     mov    cl, h
  1640.     mov    dx, day_off_log
  1641.     call    scrollbar
  1642.  
  1643. SEXIT:
  1644.     pop    es
  1645.     pop    si
  1646.     pop    di
  1647.         pop    bp
  1648.  
  1649.     ret
  1650.  
  1651. _scroll    ENDP
  1652.  
  1653. ; ---------------------------------------------
  1654.  
  1655. charblit    proc    near
  1656.  
  1657. ; on entry, registers should be
  1658. ; bh - source x ul
  1659. ; bl - source y ul
  1660. ; ah - source x lr
  1661. ; al - source y lr
  1662. ; dh - dest x ul
  1663. ; dl - dest y ul
  1664.  
  1665.     push    ds
  1666.     push    ax
  1667.     push    bx
  1668.     push    cx
  1669.     push    dx
  1670.     push    di
  1671.  
  1672. ; check for y-overlap
  1673.  
  1674.     xor    ch, ch
  1675.     cmp    bl, dl
  1676.     jg    NOVERLAP
  1677.     inc    ch
  1678. NOVERLAP:
  1679.  
  1680.     push    dx
  1681.     push    bx
  1682.  
  1683.     sub    bl, al
  1684.     jg    CNN1
  1685.     neg    bl
  1686. CNN1:
  1687.     mov    cl, bl        ; height
  1688.  
  1689.     xor    dh, dh
  1690.     sub    bh, ah
  1691.     jg    CNN2
  1692.     neg    bh
  1693. CNN2:
  1694.     mov    dl, bh        ; length
  1695.  
  1696. ; get source offset, move into si
  1697.  
  1698.     pop    bx
  1699.     mov    al, bl
  1700.     or    ch, 0
  1701.     jz    NOVERLAP1
  1702.     add    al, cl
  1703.     dec    al
  1704.  
  1705. NOVERLAP1:
  1706.     mov    bl, 160
  1707.     mul    bl
  1708.     mov    bl, bh
  1709.     xor    bh, bh
  1710.     shl    bx,1
  1711.     add    ax, bx
  1712.     mov    si, ax
  1713.  
  1714. ; get destination offset, move into di
  1715.  
  1716.     pop    bx
  1717.     mov    al, bl
  1718.     or    ch, 0
  1719.     jz    NOVERLAP2
  1720.     add    al, cl
  1721.     dec    al
  1722.  
  1723. NOVERLAP2:
  1724.     mov    bl, 160
  1725.     mul    bl
  1726.     mov    bl, bh
  1727.     xor    bh, bh
  1728.     shl    bx,1
  1729.     add    ax, bx
  1730.     mov    di, ax
  1731.  
  1732. ; determine positive or negative updating
  1733.  
  1734.     mov    bx, 160
  1735.     or    ch, 0
  1736.     jz    NOVERLAP3
  1737.     neg    bx
  1738.  
  1739. NOVERLAP3:
  1740.     xor    ch, ch
  1741.  
  1742.  
  1743.     mov    ax, video_seg
  1744.     mov    es, ax
  1745.  
  1746.     cmp    cs:localsnow, 0
  1747.     je    CBNOSNOW
  1748.     mov    cs:snow_write_type, 2
  1749.  
  1750.     mov    ds, ax
  1751. CBSNOW0:
  1752.     push    si
  1753.     push    di
  1754.  
  1755.     push    cx
  1756.     mov    cl, dl
  1757.     call    snowwrite
  1758.     pop    cx
  1759.  
  1760.     pop    ax
  1761.     add    ax, bx
  1762.     mov    di, ax
  1763.     pop    ax
  1764.     add    ax, bx
  1765.     mov    si, ax
  1766.  
  1767.     loop    CBSNOW0
  1768.  
  1769.     jmp    short    CBEXIT
  1770.  
  1771. CBNOSNOW:
  1772.  
  1773.     mov    ds, ax
  1774. CB0:
  1775.     push    si
  1776.     push    di
  1777.  
  1778.     push    cx
  1779.     mov    cl, dl
  1780. rep    movsw
  1781.     pop    cx
  1782.  
  1783.     pop    ax
  1784.     add    ax, bx
  1785.     mov    di, ax
  1786.     pop    ax
  1787.     add    ax, bx
  1788.     mov    si, ax
  1789.  
  1790.     loop    CB0
  1791.  
  1792. CBEXIT:
  1793.     pop    di
  1794.     pop    dx
  1795.     pop    cx
  1796.     pop    bx
  1797.     pop    ax
  1798.     pop    ds
  1799.  
  1800.     ret
  1801.  
  1802. charblit    ENDP
  1803.  
  1804. ; ---------------------------------------------
  1805.  
  1806. _chattr        proc    near
  1807.  
  1808. ; int chattr( win_handle *, int chxoff, int chyoff,
  1809. ;             int chw, int chh, int ch_bg_attr, ch_fg_attr)
  1810. ;
  1811. ; if both attribute ints are zeroes, resets default color
  1812. ;
  1813. ; returns non-zero if successful, zero on failure
  1814.  
  1815.     chattrframe    struc
  1816.     chbptr        dw    ?
  1817.     chraddr        dw    ?
  1818.     chhandle    dw    ?
  1819.     chxoff        db    ?
  1820.             db    ?
  1821.     chyoff        db    ?
  1822.             db    ?
  1823.     chw        db    ?
  1824.             db    ?
  1825.     chh        db    ?
  1826.             db    ?
  1827.     ch_bg_attr    db    ?
  1828.             db    ?
  1829.     ch_fg_attr    db    ?
  1830.             db    ?
  1831.     chattrframe    ends
  1832.  
  1833.     chframe    equ    [bp - chbptr]
  1834.  
  1835.     push     bp        ; Stack frame manipulations
  1836.     mov     bp,sp
  1837.     sub    sp,chbptr
  1838.     push    di
  1839.     push    si
  1840.     push    es
  1841.  
  1842.     mov    ax, chframe.chhandle
  1843.     mov    di, ax
  1844.  
  1845.     xor    ax, ax
  1846.     cmp    al, made
  1847.     je    BAD_CHATTR
  1848.  
  1849. ; determine screen location to be chattred
  1850.  
  1851.     mov    bh, handx1    ; handx1
  1852.     inc    bh
  1853.     mov    bl, handy1    ; handy1
  1854.     inc    bl
  1855.     add    bl, chframe.chyoff
  1856.     jc    BAD_CHATTR
  1857.     jl    BAD_CHATTR
  1858.     add    bh, chframe.chxoff
  1859.     jc    BAD_CHATTR
  1860.     jl    BAD_CHATTR
  1861.  
  1862.     mov    cl, chframe.chh
  1863.     mov    dl, chframe.chw
  1864.     or    cl, 0
  1865.     je    BAD_CHATTR
  1866.     or    dl, 0
  1867.     je    BAD_CHATTR
  1868.     xor    dh, dh
  1869.     xor    ch, ch
  1870.  
  1871. ; check limits
  1872.  
  1873.     mov    ax, bx
  1874.     add    bl, cl
  1875.     jc    BAD_CHATTR
  1876.     cmp    bl, 25
  1877.     jg    BAD_CHATTR
  1878.     add    bh, dl
  1879.     jc    BAD_CHATTR
  1880.     cmp    bl, 80
  1881.     jg    BAD_CHATTR
  1882.     mov    bx, ax
  1883.     jmp    short    GOOD_CHATTR
  1884.  
  1885. BAD_CHATTR:
  1886.  
  1887.     xor    ax, ax
  1888.     pop    es
  1889.     pop    si
  1890.     pop    di
  1891.         pop    bp
  1892.     ret
  1893.  
  1894. GOOD_CHATTR:
  1895.  
  1896. ; get attributes together
  1897.  
  1898.     mov    ah, chframe.ch_bg_attr
  1899.     mov    al, chframe.ch_fg_attr
  1900.     or    ax, 0
  1901.     jnz    NOT_RESET
  1902.     mov    al, interior_attrib
  1903.     jmp    short    CHRESETREADY
  1904.  
  1905.  
  1906. NOT_RESET:
  1907. ; truncate... for background, shave off blink bits, too
  1908.  
  1909.     and    ax, 070fh
  1910.  
  1911. ; if monochrome, convert all but white backgrounds to no backgrounds
  1912.  
  1913.     cmp    graphics_type, 4
  1914.     jl    CHCOLOR
  1915.     cmp    ah, 07h
  1916.     jz    CHSET_BG
  1917.     xor    ah, ah
  1918.  
  1919. ; if you clear the background, make sure foreground is not black
  1920.  
  1921.     or    al, 02h
  1922.     jmp    short    CHCLR_BG
  1923.  
  1924. ; if you set it, make foreground black
  1925.  
  1926. CHSET_BG:
  1927.  
  1928.     xor    al,al
  1929.  
  1930. CHCLR_BG:
  1931.  
  1932. ; and all foregrounds but white foregrounds to low intensity
  1933.  
  1934.     cmp    al, 0fh
  1935.     jz    CHSET_FRCLR
  1936.     and    al, 07h
  1937.  
  1938. CHSET_FRCLR:
  1939.  
  1940. ; zap underline bits
  1941.  
  1942.     and    al, 0eh
  1943. CHCOLOR:
  1944.  
  1945.     push    cx
  1946.     mov    cl, 4
  1947.     shl    ah, cl
  1948.     or    al, ah
  1949.     pop    cx
  1950.  
  1951. CHRESETREADY:
  1952.     push    ax
  1953.  
  1954.     mov    al, 160
  1955.     mul    bl
  1956.     mov    bl,bh
  1957.     xor    bh, bh
  1958.     shl    bl,1
  1959.     add    ax, bx
  1960.     mov    di, ax
  1961.     mov    bx, ax
  1962.  
  1963.     mov    ax, video_seg
  1964.     mov    es, ax
  1965.  
  1966.     pop    ax
  1967.  
  1968. CHL0:
  1969.     push    cx
  1970.     mov    cl, dl
  1971.  
  1972. ; since chattr is almost always one line, put snow check in here.
  1973.  
  1974.     cmp    cs:localsnow, 0
  1975.     je    CHL1
  1976.  
  1977.     mov    cs:snow_write_type, 0
  1978. CHLSNOW1:
  1979.     inc    di
  1980.     call    snowwrite
  1981.     loop    CHLSNOW1
  1982.     jmp    short    CHLCONTINUE
  1983.  
  1984. CHL1:
  1985.     inc    di
  1986.     stosb
  1987.     loop    CHL1
  1988.  
  1989.  
  1990. CHLCONTINUE:
  1991.     pop    cx
  1992.     add    bx, 160
  1993.     mov    di, bx
  1994.     loop    CHL0
  1995.  
  1996.     pop    es
  1997.     pop    si
  1998.     pop    di
  1999.         pop    bp
  2000.     ret
  2001.  
  2002. _chattr    ENDP
  2003. ; ---------------------------------------------
  2004.  
  2005.  
  2006. _winputch        proc    near
  2007.  
  2008. ; int winputch(win_handle *, int wpxoff, int wpyoff, char wpch)
  2009. ; returns non-zero if successful, zero on failure
  2010.  
  2011.     winputchframe    struc
  2012.     wpbptr        dw    ?
  2013.     wpraddr        dw    ?
  2014.     wphandle    dw    ?
  2015.     wpxoff        db    ?
  2016.             db    ?
  2017.     wpyoff        db    ?
  2018.             db    ?
  2019.     wpch        db    ?
  2020.             db    ?
  2021.     winputchframe    ends
  2022.  
  2023.     wpframe    equ    [bp - wpbptr]
  2024.  
  2025.     push     bp        ; Stack frame manipulations
  2026.     mov     bp,sp
  2027.     sub    sp,wpbptr
  2028.     push    di
  2029.     push    si
  2030.     push    es
  2031.  
  2032.     mov    ax, wpframe.wphandle
  2033.     mov    di, ax
  2034.  
  2035. ; check if window valid
  2036.  
  2037.     xor    ax, ax
  2038.     cmp    al, made
  2039.     jne    NOT_BAD_WP
  2040.     jmp    BAD_WP
  2041.  
  2042. NOT_BAD_WP:
  2043. ; check array width if linked
  2044.  
  2045.     xor    ax, ax
  2046.     cmp    ax, ptr_displayed_array ; array pointer
  2047.     jz    WPNOTLINKED
  2048.  
  2049.     mov    bl, wpframe.wpxoff
  2050.     add    bx, dax_off_log    ; dax_off_log
  2051.     mov    dx, dax    ; dax
  2052.     cmp    bx, dx
  2053.     jl    WPNOTLINKED
  2054.     jmp    BAD_WP
  2055.  
  2056. WPNOTLINKED:
  2057.     mov    bh, handx1    ; handx1
  2058.     inc    bh
  2059.     mov    bl, handy1    ; handy1
  2060.     inc    bl
  2061.     mov    ax, bx
  2062.  
  2063.     add    bl, wpframe.wpyoff
  2064.     jc    BAD_WP
  2065.     jl    BAD_WP
  2066.     add    bh, wpframe.wpxoff
  2067.     jc    BAD_WP
  2068.     jl    BAD_WP
  2069.  
  2070.     add    al, h    ; h
  2071.     add    ah, w    ; w
  2072.     dec    al
  2073.     dec    al
  2074.     dec    ah
  2075.     dec    ah
  2076.  
  2077.     cmp    bh, ah
  2078.     jge    BAD_WP
  2079.     cmp    bl, al
  2080.     jge    BAD_WP
  2081.  
  2082. ; write to screen
  2083.  
  2084.     push    di
  2085.     mov    al, 160
  2086.     mul    bl
  2087.     mov    bl,bh
  2088.     xor    bh, bh
  2089.     shl    bl,1
  2090.     add    ax, bx
  2091.     mov    di, ax
  2092.     mov    ax, video_seg
  2093.     mov    es, ax
  2094.     mov    al, wpframe.wpch
  2095.  
  2096.     cmp    cs:localsnow, 0
  2097.     je    WPNOSNOW
  2098.     mov    cs:snow_write_type, 0
  2099.     call    snowwrite
  2100.     jmp    short    WPDONESCREEN
  2101.  
  2102. WPNOSNOW:
  2103.     stosb
  2104.  
  2105. WPDONESCREEN:
  2106.  
  2107. ; write to array, if linked
  2108.  
  2109.     push    ds
  2110.     pop    es
  2111.     pop    di
  2112.  
  2113.     xor    bx, bx
  2114.     cmp    bx, ptr_displayed_array ; array pointer
  2115.     jz    WPEXIT
  2116.  
  2117.  
  2118.     xor    ah, ah
  2119.     mov    al, wpframe.wpyoff
  2120.     mov    bl, wpframe.wpxoff
  2121.     add    ax, day_off_log    ; day_off_log
  2122.     add    bx, dax_off_log    ; dax_off_log
  2123.     mov    cx, dx        ; dax
  2124.  
  2125.     mul    cx
  2126.     add    ax, bx
  2127.     add    ax, ptr_displayed_array    ; array_pointer
  2128.     mov    di, ax
  2129.     mov    al, wpframe.wpch
  2130.     stosb
  2131.     jmp    short    WPEXIT
  2132.  
  2133. BAD_WP:
  2134.     xor    ax, ax
  2135.  
  2136. WPEXIT:
  2137.     pop    es
  2138.     pop    si
  2139.     pop    di
  2140.         pop    bp
  2141.     ret
  2142.  
  2143. _winputch    ENDP
  2144. ; ---------------------------------------------
  2145.  
  2146. _win_set_curpos    proc    near
  2147.  
  2148. ; void win_set_curpos ( win_handle *, int scxoff, int scyoff)
  2149.  
  2150.     scurseframe    struc
  2151.     scbptr        dw    ?
  2152.     scraddr        dw    ?
  2153.     schandle    dw    ?
  2154.     scxoff        db    ?
  2155.             db    ?
  2156.     scyoff        db    ?
  2157.             db    ?
  2158.     scurseframe    ends
  2159.  
  2160.     scframe    equ    [bp - scbptr]
  2161.  
  2162.     push     bp        ; Stack frame manipulations
  2163.     mov     bp,sp
  2164.     sub    sp,scbptr
  2165.     push    di
  2166.     push    si
  2167.  
  2168.     mov    ax, scframe.schandle
  2169.     mov    di, ax
  2170.  
  2171. ; check if made
  2172.     xor    ax, ax
  2173.     cmp    al, made
  2174.     je    BAD_SC
  2175.  
  2176.     mov    bh, handx1    ; handx1
  2177.     inc    bh
  2178.     mov    bl, handy1    ; handy1
  2179.     inc    bl
  2180.     mov    ax, bx
  2181.  
  2182.     add    bl, scframe.scyoff
  2183.     jc    BAD_SC
  2184.     jl    BAD_SC
  2185.     add    bh, scframe.scxoff
  2186.     jc    BAD_SC
  2187.     jl    BAD_SC
  2188.  
  2189.     add    al, h    ; h
  2190.     add    ah, w    ; w
  2191.     dec    al
  2192.     dec    ah
  2193.  
  2194.     cmp    bh, ah
  2195.     jg    BAD_SC
  2196.     cmp    bl, al
  2197.     jg    BAD_SC
  2198.  
  2199. ; write to screen
  2200.  
  2201.     mov    dx, bx
  2202.     xchg    dh, dl
  2203.  
  2204.     mov    ah, 0fh
  2205.     int    10h        ; status
  2206.  
  2207.     mov    ah, 02h
  2208.     int    10h        ; move it
  2209.  
  2210.     jmp    short    SCEXIT
  2211.  
  2212. BAD_SC:
  2213.     xor    ax, ax
  2214.  
  2215. SCEXIT:
  2216.     pop    si
  2217.     pop    di
  2218.         pop    bp
  2219.     ret
  2220.  
  2221. _win_set_curpos    ENDP
  2222.  
  2223. ; ---------------------------------------------
  2224.  
  2225. _clearscreen    proc    near
  2226.  
  2227. ; void clearscreen ( void )
  2228.  
  2229.     clsframe    struc
  2230.     clsbptr        dw    ?
  2231.     clsraddr    dw    ?
  2232.     clsframe    ends
  2233.  
  2234.     push     bp        ; Stack frame manipulations
  2235.     mov     bp,sp
  2236.     sub    sp,clsbptr
  2237.  
  2238.     mov    ah, 0fh
  2239.     int    10h        ; status
  2240.     push    bx        ; save display page (bh)
  2241.  
  2242.     xor    ah, ah
  2243.     int    10h        ; reset current mode
  2244.  
  2245.     pop    bx
  2246.     xor    dx, dx        ; set cursor position to 0,0
  2247.     mov    ah, 02h
  2248.     int    10h
  2249.  
  2250.         pop    bp
  2251.     ret
  2252.  
  2253. _clearscreen    ENDP
  2254.  
  2255. ; ---------------------------------------------
  2256.  
  2257. _win_erase_region    proc    near
  2258.  
  2259. ; void win_erase_region ( win_handle *, int erxoff, int eryoff
  2260. ;              erw, erh )
  2261.  
  2262.     eraseframe    struc
  2263.     erbptr        dw    ?
  2264.     erraddr        dw    ?
  2265.     erhandle    dw    ?
  2266.     erxoff        db    ?
  2267.             db    ?
  2268.     eryoff        db    ?
  2269.             db    ?
  2270.     erw        db    ?
  2271.             db    ?
  2272.     erh        db    ?
  2273.             db    ?
  2274.     eraseframe    ends
  2275.  
  2276.     erframe    equ    [bp - erbptr]
  2277.  
  2278.     push     bp        ; Stack frame manipulations
  2279.     mov     bp,sp
  2280.     sub    sp,erbptr
  2281.     push    di
  2282.     push    si
  2283.     push    es
  2284.  
  2285.     mov    ax, erframe.erhandle
  2286.     mov    di, ax
  2287.  
  2288. ; check if made
  2289.     xor    ax, ax
  2290.     cmp    al, made
  2291.     jne    ERDUMMY0
  2292.     jmp    BAD_ER
  2293.  
  2294. ERDUMMY0:
  2295.     mov    bh, handx1    ; handx1
  2296.     inc    bh
  2297.     mov    bl, handy1    ; handy1
  2298.     inc    bl
  2299.     mov    ax, bx
  2300.  
  2301. ; make sure offsets in widow
  2302.  
  2303.     add    bl, erframe.eryoff
  2304.     jc    BAD_ER
  2305.     jl    BAD_ER
  2306.     add    bh, erframe.erxoff
  2307.     jc    BAD_ER
  2308.     jl    BAD_ER
  2309.     push    bx
  2310.  
  2311. ; and offsets plus h and w are in window
  2312.  
  2313.     add    bl, erframe.erh
  2314.     jc    BAD_ER_JMPOFF
  2315.     add    bh, erframe.erw
  2316.     jc    BAD_ER_JMPOFF
  2317.  
  2318.     add    al, h    ; h
  2319.     add    ah, w    ; w
  2320.     dec    al
  2321.     dec    ah
  2322.  
  2323.     cmp    bh, ah
  2324.     jg    BAD_ER_JMPOFF
  2325.     cmp    bl, al
  2326.     jg    BAD_ER_JMPOFF
  2327.  
  2328.     pop    bx
  2329.     jmp    short    SLOOP
  2330.  
  2331. BAD_ER_JMPOFF:
  2332.     pop    bx
  2333.     jmp    short    BAD_ER
  2334.  
  2335. SLOOP:
  2336. ; setup loop
  2337.  
  2338.     mov    ah, interior_attrib
  2339.     xor    al, al
  2340.     push    ax
  2341.  
  2342.     xor    ch, ch
  2343.     xor    dh, dh
  2344.     mov    dl, erframe.erw
  2345.     mov    cl, erframe.erh
  2346.  
  2347.     mov    al, 160
  2348.     mul    bl
  2349.     mov    bl,bh
  2350.     xor    bh, bh
  2351.     shl    bl,1
  2352.     add    ax, bx
  2353.     mov    di, ax
  2354.     mov    bx, ax
  2355.  
  2356.     mov    ax, video_seg
  2357.     mov    es, ax
  2358.     pop    ax
  2359.  
  2360.     cmp    cs:localsnow, 0
  2361.     je    ERL0
  2362.     mov    cs:snow_write_type, 1
  2363. ERSNOWL0:
  2364.     push    cx
  2365.     mov    cl, dl
  2366.     call    snowwrite
  2367.     add    bx,160
  2368.     mov    di, bx
  2369.     pop    cx
  2370.     loop    ERSNOWL0
  2371.     jmp    short    DONE_ER
  2372.  
  2373. ERL0:
  2374.     push    cx
  2375.     mov    cl, dl
  2376. rep    stosw
  2377.     add    bx,160
  2378.     mov    di, bx
  2379.     pop    cx
  2380.     loop    ERL0
  2381.  
  2382. DONE_ER:
  2383. BAD_ER:
  2384.     pop    es
  2385.     pop    si
  2386.     pop    di
  2387.         pop    bp
  2388.     ret
  2389.  
  2390. _win_erase_region    ENDP
  2391.  
  2392. ; -----------------------------------------------
  2393.  
  2394. _winstrlen    proc    near
  2395.  
  2396. ; int winstrlen (win_handle * hand, int x, int y)
  2397. ;   window based strlen. finds length of asciiz string located 
  2398. ;   at x, y within a given window
  2399. ;
  2400. ; returns -1 on error
  2401. ;
  2402.     stlenframe    struc
  2403.     slbptr        dw    ?
  2404.     slraddr        dw    ?
  2405.     slhandle    dw    ?
  2406.     slx        db    ?
  2407.             db    ?
  2408.     sly        db    ?
  2409.             db    ?
  2410.     stlenframe    ends
  2411.  
  2412.     slframe    equ    [bp - slbptr]
  2413.  
  2414.     push     bp        ; Stack frame manipulations
  2415.     mov     bp,sp
  2416.     sub    sp,slbptr
  2417.     push    di
  2418.     push    si
  2419.     push    es
  2420.  
  2421.     mov    ax, slframe.slhandle
  2422.     mov    di, ax
  2423.  
  2424. ; check if made
  2425.     xor    ax, ax
  2426.     cmp    al, made
  2427.     je    BAD_SLN
  2428.  
  2429.     mov    bh, handx1    ; handx1
  2430.     inc    bh
  2431.     mov    bl, handy1    ; handy1
  2432.     inc    bl
  2433.     mov    ax, bx
  2434.  
  2435. ; make sure offsets in window
  2436.  
  2437.     add    bl, slframe.sly
  2438.     jc    BAD_SLN
  2439.     jl    BAD_SLN
  2440.     add    bh, slframe.slx
  2441.     jc    BAD_SLN
  2442.     jl    BAD_SLN
  2443.  
  2444.     xor    ah, ah
  2445.     mov    al, w
  2446.     dec    al
  2447.     dec    al
  2448.     sub    al, slframe.slx
  2449.     jc    BAD_SLN
  2450.     shl    ax, 1        ; words
  2451.     mov    cx, ax
  2452.     push    cx
  2453.  
  2454.     mov    ax, video_seg
  2455.     mov    es, ax
  2456.  
  2457. ; calculate initial offset
  2458.  
  2459.     mov    al, 160
  2460.     mul    bl
  2461.     mov    bl,bh
  2462.     xor    bh, bh
  2463.     shl    bl,1
  2464.     add    ax, bx
  2465.  
  2466.     mov    di, ax
  2467.  
  2468.     xor    al, al
  2469. repne    scasb
  2470.     pop    ax    ; original cx
  2471.     sub    ax, cx
  2472.     shr    ax, 1
  2473.     jmp    short    SLNEXIT
  2474.  
  2475. BAD_SLN:
  2476.     mov    ax, -1
  2477.  
  2478. SLNEXIT:
  2479.     pop    es
  2480.     pop    si
  2481.     pop    di
  2482.         pop    bp
  2483.     ret
  2484.  
  2485. _winstrlen    ENDP
  2486.  
  2487. ; -----------------------------------------------
  2488.  
  2489. snowwrite    proc    near
  2490.  
  2491. ; registers preserved (except flags)
  2492. ; function is determined by cs:snow_write_type, which is a last-minute
  2493. ; kludge.
  2494. ;
  2495. ; Method adapted from Richard Wilton's video book.
  2496. ;
  2497. ; type = 0 ; do a stosb
  2498. ; type =1  ; do a rep stosw
  2499. ; type =2  ; do a rep movsw
  2500.  
  2501.     push    ax
  2502.     push    bx
  2503.     push    dx
  2504.  
  2505.     mov    dx, 3dah
  2506.  
  2507.     cmp    cs:snow_write_type, 0
  2508.     jne    REPS
  2509.     push    cx
  2510.     mov    cx, 1
  2511.  
  2512. REPS:
  2513.     mov    bx, cx
  2514.     mov    cx, cs:cga_timeout
  2515.     push    ax
  2516.     cli
  2517. SW0:
  2518.     in    al, dx
  2519.     test    al, 1
  2520.     loopnz    SW0
  2521.     pop    ax
  2522.     jz    HORIZ
  2523.  
  2524.     cmp    cs:snow_write_type, 2
  2525.     jne    ONEOR2
  2526.     lodsw
  2527. ONEOR2:
  2528.     cmp    cs:snow_write_type, 0
  2529.     je    TYPE0
  2530.     stosw
  2531.     jmp    short    V0DONE
  2532. TYPE0:
  2533.     stosb
  2534. V0DONE:
  2535.     sti
  2536.     mov    cx, bx
  2537.     loop    REPS
  2538.  
  2539.     jmp    short    SWEXIT
  2540.  
  2541. ; dummy horizontal blanking write
  2542.  
  2543. HORIZ:
  2544.     push    ax
  2545.     sti
  2546. HORILOOP:
  2547.     mov    cx, cs:cga_timeout
  2548.     cli
  2549. SWH0:
  2550.     in    al, dx
  2551.     test    al, 1
  2552.     loopnz    SWH0
  2553.     jnz    VERT2
  2554. SWH1:
  2555.     in    al, dx
  2556.     test    al, 1
  2557.     jz    SWH1
  2558.  
  2559.     sti
  2560.     jmp    short    HORILOOP
  2561.  
  2562.  
  2563. VERT2:
  2564.  
  2565.     sti
  2566.  
  2567.     pop    ax
  2568.     mov    cx, bx
  2569.  
  2570.     cmp    cs:snow_write_type, 2
  2571.     jl    SWNEXT0
  2572.     rep    movsw
  2573.     jmp    short    SWEXIT
  2574. SWNEXT0:
  2575.     cmp    cs:snow_write_type, 1
  2576.     jl    SWNEXT1
  2577.     rep    stosw
  2578.     jmp    short    SWEXIT
  2579. SWNEXT1:
  2580.     stosb
  2581. SWEXIT:
  2582.     cmp    cs:snow_write_type, 0
  2583.     jne    NOPOPCX
  2584.     pop    cx
  2585. NOPOPCX:
  2586.     pop    dx
  2587.     pop    bx
  2588.     pop    ax
  2589.     ret
  2590.  
  2591. snowwrite    ENDP
  2592.  
  2593. ; -----------------------------------------------
  2594.  
  2595. _cgainit    proc    near
  2596.  
  2597. ; int cgainit (void)
  2598. ;
  2599. ; determines timeout value
  2600. ; puts snowflag in local code segment
  2601. ;
  2602. ;
  2603.     cinitframe    struc
  2604.     cgabptr        dw    ?
  2605.     cgaraddr    dw    ?
  2606.     cinitframe    ends
  2607.  
  2608.     cgaframe    equ    [bp - cgabptr]
  2609.  
  2610.     push     bp        ; Stack frame manipulations
  2611.     mov     bp,sp
  2612.     sub    sp,cgabptr
  2613.  
  2614.     push    es
  2615.  
  2616.     mov    ax, snowflag
  2617.     mov    cs:localsnow, ax
  2618.  
  2619.     mov    ax, video_seg
  2620.     mov    dx, 3dah
  2621.  
  2622.     cmp    graphics_type, 3
  2623.     jne    CGAINOTCGA
  2624.  
  2625.     mov    es, ax
  2626.  
  2627. CGAI0:
  2628.     in    al, dx
  2629.     test    al, 8
  2630.     jz    CGAI0
  2631. CGAI1:
  2632.     in    al, dx
  2633.     test    al, 8
  2634.     jnz    CGAI1
  2635.  
  2636.     mov    cx, 0ffffh
  2637.     cli
  2638.  
  2639. CGAI2:
  2640.     in    al, dx
  2641.     test    al, 1
  2642.     jnz    CGAI2
  2643. CGAI3:
  2644.     in    al, dx
  2645.     test    al, 1
  2646.     jz    CGAI3
  2647. CGAI4:
  2648.     in    al, dx
  2649.     test    al, 1
  2650.     loopnz    CGAI4
  2651.  
  2652.     sti
  2653.  
  2654.     neg    cx
  2655.     shl    cx, 1
  2656.  
  2657.     mov    cs:cga_timeout, cx
  2658.  
  2659. CGAINOTCGA:
  2660.  
  2661.     pop    es
  2662.         pop    bp
  2663.     ret
  2664.  
  2665. _cgainit    ENDP
  2666. ; ---------------------------------------------
  2667. _text    ends
  2668.     END
  2669.  
  2670.