home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / tegl_ii / svga / grhercbw.asm < prev    next >
Encoding:
Assembly Source File  |  1991-10-14  |  63.1 KB  |  3,118 lines

  1.  
  2.         include grphdrvr.inc
  3.  
  4. ;******************************************************************************}
  5. ;                TEGL Windows ToolKit II                   }
  6. ;           Copyright (C) 1990, TEGL Systems Corporation            }
  7. ;                 All Rights Reserved.                   }
  8. ;******************************************************************************}
  9.  
  10.         .code
  11.  
  12.         db   'RT',8,8,'TGI Device Driver (EGA640x350x16/VGA640x480x16) 1.00 - Dec 15 1990',13,10
  13.         db   'Copyright (c) 1989,1990 TEGL Systems Corporation',13,10
  14.         db   01ah         ; end of file for TYPE
  15.         db   00          ; end of Copyright Header
  16.  
  17.         db   8,'GRHERCBW',0  ; driver module name
  18.  
  19. mode0:        db    13,'HERC720x348x2',0,0,0,0,0,0,0,0
  20.         dw    0         ; Mode Number
  21.         dw    719         ; Device Full Resolution in X
  22.         dw    347         ; Device Full Resolution in Y
  23.         dw    8         ; Standard char size X
  24.         dw    8         ; Standard char size Y
  25.         dw    1         ; Number of colors
  26.         dw    2         ; Number of pages
  27.         dw    1         ; max palette
  28.         dw    0         ; buffer offset for 2 page
  29.         dw    0B000h         ; Screen Segment
  30.         dw    90         ; bytes per line
  31.         dw    7000         ; x aspect
  32.         dw    10000         ; y aspect
  33.         dd    0         ; Driver Pointer
  34.         dd    0         ; Driver Name Pointer
  35.         dd    0         ; Driver Jump Table
  36.         dd    0         ; Graphics Work Buffer
  37.         dw    0         ; Graphics Buffer Size
  38.         dw    0         ; Read/Write modes
  39.         db    0         ; transparency on-$ff/off-$00
  40.         db    0         ; jagged characters
  41.         dd    0         ; pointer to font table
  42.         db    0         ; allow EGA palette changes
  43.         db    0         ; allow VGA 256 palette changes
  44.         db    1         ; proportional font switch
  45.         dw    0ffffh         ; fillmask for lines
  46.         dw    0         ; viewport - minx
  47.         dw    0         ; viewport - miny
  48.         dw    719         ; viewport - maxx
  49.         dw    347         ; viewport - maxy
  50.         db    1         ; viewport - clipping on/off
  51.         dw    15         ; Mouse color
  52.         dw    0         ; Mouse hotspot
  53.         dw    0         ; Mouse hotspot
  54.         dd    0         ; Mouse Cursor Mask
  55.         dd    0         ; Next VideoMode
  56.  
  57. mode1:        db    13,'HGC1720x348x2',0,0,0,0,0,0,0,0
  58.         dw    1         ; Mode Number
  59.         dw    719         ; Device Full Resolution in X
  60.         dw    347         ; Device Full Resolution in Y
  61.         dw    8         ; Standard char size X
  62.         dw    8         ; Standard char size Y
  63.         dw    1         ; Number of colors
  64.         dw    1         ; Number of pages
  65.         dw    1         ; max palette
  66.         dw    0         ; buffer offset for 2 page
  67.         dw    0B000h         ; Screen Segment
  68.         dw    90         ; bytes per line
  69.         dw    7000         ; x aspect
  70.         dw    10000         ; y aspect
  71.         dd    0         ; Driver Pointer
  72.         dd    0         ; Driver Name Pointer
  73.         dd    0         ; Driver Jump Table
  74.         dd    0         ; Graphics Work Buffer
  75.         dw    0         ; Graphics Buffer Size
  76.         dw    0         ; Read/Write modes
  77.         db    0         ; transparency on-$ff/off-$00
  78.         db    0         ; jagged characters
  79.         dd    0         ; pointer to font table
  80.         db    0         ; allow EGA palette changes
  81.         db    0         ; allow VGA 256 palette changes
  82.         db    1         ; proportional font switch
  83.         dw    0ffffh         ; fillmask for lines
  84.         dw    0         ; viewport - minx
  85.         dw    0         ; viewport - miny
  86.         dw    719         ; viewport - maxx
  87.         dw    347         ; viewport - maxy
  88.         db    1         ; viewport - clipping on/off
  89.         dw    15         ; Mouse color
  90.         dw    0         ; Mouse hotspot
  91.         dw    0         ; Mouse hotspot
  92.         dd    0         ; Mouse Cursor Mask
  93.         dd    0         ; Next VideoMode
  94.  
  95. modeend:    dw    0ffffh         ; 0ffff - last mode
  96.  
  97.         dw   initvideomode   ; mode:word,TEGLTable:dword,initflg:byte
  98.         dw   setxlattable    ; XlatTable:dword
  99.         dw   setvideotable   ; TEGLTable:dword
  100.         dw   getvideotable   ; returns pointer to TEGLTable
  101.         dw   imagesize         ; argx1:word,argy1:word,argx2:word,argy2:word
  102.         dw   fastline         ; argx1:word,argy1:word,argx2:word,argy2:word,color:word
  103.         dw   scanborder      ; argx:word,argy:word,bordercolor:word,scan:word
  104.         dw   putpixs         ; argx:word,argy:word,color:word
  105.         dw   getpixs         ; argx:word,argy:word
  106.         dw   getbiti         ; argx0:word,argy0:word,argx1:word,argy1:word,addrbuf:dword
  107.         dw   putbiti         ; argx:word,argy:word,addrbuf:dword,rmwb:word
  108.         dw   extractimg      ; argx0:word,argy0:word,argx1:word,argy1:word,addrbuf1:dword,addrbuf2:dword
  109.         dw   overlayimg      ; argx0:word,argy0:word,addrbuf1:dword,addrbuf2:dword
  110.         dw   extractpixs     ; argx0:word,argy0:word,addrbuff:dword
  111.         dw   wrtchar         ; argc:word,argx:word,argy:word,argfgd:word
  112.         dw   mcursoroff      ;
  113.         dw   mcursoron         ; argx:word,argy:word
  114.         dw   msetpos         ; argx:word,argy:word
  115.         dw   movevideopixels ; argx0:word,argy0:word,argx1:word,argy1:word,argx2:word,argy2:word,vertlines:word,horzlines:word,spage:word,tpage:word
  116.         dw   setvpage         ; pagen:word
  117.         dw   setapage         ; pagen:word
  118.  
  119.         db   16 dup (0) ;required for driver alignment
  120.  
  121. ; 3 bytes/row * 17rows + 5 byte header
  122. mcursorsavearea db   60 dup (0)
  123. mflag        dw   0
  124. scradrofs    dw   0
  125. scradrseg    dw   0
  126. TDTable     dd   0
  127. XLTable     dd   0
  128.  
  129.  
  130. nextinterleave    =    2000h
  131. firstinterleave =    90-8000h
  132.  
  133.  
  134. CRTCParms    DB    00h,35h ; Horizontal Total:  54 characters
  135.         DB    01h,2Dh ; Horizontal Displayed:  45 characters
  136.         DB    02h,2Eh ; Horizontal Sync Position:  at 46th character
  137.         DB    03h,07h ; Horizontal Sync Width:  7 character clocks
  138.         DB    04h,5Bh ; Vertical Total:  92 characters (368 lines)
  139.         DB    05h,02h ; Vertical Adjust:  2 scan lines
  140.         DB    06h,57h ; Vertical Displayed:  87 character rows (348 lines)
  141.         DB    07h,57h ; Vertical Sync Position:  after 87th char row
  142.         DB    09h,03h ; Max Scan Line:  4 scan lines per char
  143. CRTCParmsLen    EQU    ($-CRTCParms)/2
  144.  
  145. BIOSData    DB    6    ; CRT_MODE
  146.         DW    80    ; CRT_COLS
  147.         DW    8000h    ; CRT_LEN
  148.         DW    0    ; CRT_START
  149.         DW    8 dup(0) ; CURSOR_POSN
  150.         DW    0    ; CURSOR_MODE
  151.         DB    0    ; ACTIVE_PAGE
  152. CRTCAddr    DW    3B4h    ; ADDR_6845
  153. CRTMode     DB    0Ah    ; CRT_MODE_SET (value for port 3B8h)
  154.         DB    0    ; CRT_PALETTE (unused)
  155. BIOSDataLen    EQU    $-BIOSData
  156.  
  157.  
  158. initvideomode    proc    far
  159.         local    crtcptr:word
  160.  
  161.         push    ds
  162.         push    si
  163.         push    es
  164.         push    di
  165.  
  166.         mov    ax,-10
  167.  
  168.         lds    si,cs:TDTable
  169.         mov    cx,8000h
  170.  
  171.         mov    bx,ds:[si].vmodenum
  172.         or    bx,bx
  173.         jnz    isonepage
  174.  
  175.         push    si
  176.         add    si,CRTCParms-Mode0
  177.         mov    crtcptr,si
  178.         pop    si
  179.         add    si,BIOSData-Mode0
  180.         jmp    short clearvid
  181.  
  182. isonepage:    cmp    bx,1
  183.         jne    noinitmode
  184.  
  185.         shr    cx,1
  186.         push    si
  187.         add    si,CRTCParms-Mode1
  188.         mov    crtcptr,si
  189.         pop    si
  190.         add    si,BIOSData-Mode1
  191.  
  192.  
  193.         ; clear hercules memory
  194. clearvid:    mov    ax,0b000h
  195.         mov    es,ax
  196.         xor    di,di
  197.         xor    ax,ax
  198.  
  199.         cld
  200.         rep    stosw
  201.  
  202. ; Update Video BIOS Data Area
  203.         mov    ax,40h
  204.         mov    es,ax
  205.         mov    di,49h
  206.  
  207.         mov    cx,BIOSDataLen
  208.         cld
  209.         rep    movsb
  210.  
  211. ; Set Configuration Switch
  212.         mov    dx,3bfh     ; configuration port
  213.         mov    al,3        ; set to two pages
  214.         test    bx,1        ;
  215.         jz    settwopage
  216.         shr    al,1        ; set to one page
  217. settwopage:    out    dx,al
  218.  
  219. ; set Control Port
  220.         mov    dx,3b8h     ; control port
  221.         xor    al,al        ; disable video signal
  222.         out    dx,al        ; blank screen
  223.  
  224. ; Program CRTC
  225.         mov    dx,3b4h     ; Indexport
  226.  
  227.         mov    si,crtcptr
  228.         mov    cx,CRTCParmsLen
  229.  
  230. HGCMode0_001:    lodsw            ; AL := CRTC index
  231.                     ; AH := data
  232.         out    dx,ax
  233.         loop    HGCMode0_001
  234.  
  235. ; set Graphic Mode
  236.         mov    dx,3b8h     ; control port
  237.         mov    al,10
  238.         out    dx,al
  239.         xor    ax,ax
  240.  
  241. noinitmode:    pop    di
  242.         pop    es
  243.         pop    si
  244.         pop    ds
  245.         ret
  246. initvideomode    endp
  247.  
  248.  
  249. setxlattable    proc    far XlatTable:dword
  250.         push    es
  251.         push    di
  252.  
  253.         les    di,XlatTable
  254.         mov    word ptr cs:XLTable,di
  255.         mov    word ptr cs:XLTable+2,es
  256.  
  257.         pop    di
  258.         pop    es
  259.         ret
  260. setxlattable    endp
  261.  
  262. setvideotable    proc    far TEGLTable:dword
  263.         push    es
  264.         push    di
  265.  
  266.         les    di,TEGLTable
  267.         mov    word ptr cs:TDTable,di
  268.         mov    word ptr cs:TDTable+2,es
  269.  
  270.         pop    di
  271.         pop    es
  272.         ret
  273. setvideotable    endp
  274.  
  275. getvideotable    proc    far
  276.  
  277.         mov    ax,word ptr cs:TDTable
  278.         mov    dx,word ptr cs:TDTable+2
  279.  
  280.         ret
  281. getvideotable    endp
  282.  
  283.  
  284. imagesize    proc    far argx1:word,argy1:word,argx2:word,argy2:word
  285.         push    bx
  286.  
  287.         mov    ax,argx2        ;x1-x+1
  288.         sub    ax,argx1
  289.         inc    ax
  290.  
  291.         mov    dx,ax
  292.         mov    cl,3
  293.         shr    ax,cl            ; /8
  294.  
  295.         and    dl,07h            ; check for byte
  296.         jz    hisz01            ; boundary
  297.         inc    ax
  298. hisz01:     mov    bx,argy2        ;y1-y+1
  299.         sub    bx,argy1
  300.         inc    bx
  301.         mul    bx            ;rows x bytes per row
  302.         add    ax,6            ;add 6 for header
  303.         adc    dx,0
  304.  
  305.         pop    bx
  306.         ret
  307. imagesize    endp
  308.  
  309.  
  310. fastline    proc    far argx1:word,argy1:word,argx2:word,argy2:word,color:word
  311.         local    varleafincr:word,varincr1:word,varincr2:word,varroutine:word
  312.         local    rmwb:byte,fillmask:byte,bpline:word,transparent:byte
  313.  
  314.         push    ds
  315.         push    si
  316.         push    es
  317.         push    di
  318.  
  319.         cld
  320.         colorxlat color
  321.  
  322.         lds    si,cs:TDtable
  323.         mov    ax,ds:[si].rmwbits
  324.         mov    rmwb,al
  325.  
  326.         mov    ax,ds:[si].vbytesperline
  327.         mov    bpline,ax
  328.  
  329.         mov    ax,ds:[si].teglfillmask
  330.         mov    fillmask,al
  331.  
  332.         mov    al,ds:[si].transparency
  333.         mov    transparent,al
  334.  
  335.         mov    si,nextinterleave ; increment for video buffer interleave
  336.         mov    di,firstinterleave ; increment from last to first interleave
  337.  
  338.         mov    cx,argx2
  339.         sub    cx,argx1    ; cx := x2 - x1
  340.         jz    vertlinehgc    ; jump if vertical line
  341.  
  342. ; force x1 < x2
  343.  
  344.         jns    hgl01        ; jump if x2 > x1
  345.  
  346.         neg    cx        ; cx := x1 - x2
  347.  
  348.         mov    bx,argx2    ; exchange x1 and x2
  349.         xchg    bx,argx1
  350.         mov    argx2,bx
  351.  
  352.         mov    bx,argy2    ; exchange y1 and y2
  353.         xchg    bx,argy1
  354.         mov    argy2,bx
  355.  
  356. ; calculate dy = abs(y2-y1)
  357.  
  358. hgl01:        mov    bx,argy2
  359.         sub    bx,argy1    ; bx := y2 - y1
  360.         jnz    hgl02
  361.  
  362.         jmp    horizlinehgc    ; jump if horizontal line
  363.  
  364. hgl02:        jns    hgl03
  365.  
  366.         neg    bx        ; bx := y1 - y2
  367.         neg    si        ; negate increments for buffer interleave
  368.         neg    di
  369.  
  370. ; select appropriate routine for slope of line
  371.  
  372. hgl03:        mov    varleafincr,di    ; save increment for buffer interleave
  373.  
  374.         mov    varroutine,0    ; loslopelinehgc
  375.         cmp    bx,cx
  376.         jle    hgl04        ; jump if dy <= dx (slope <= 1)
  377.         not    varroutine    ; hislopelinehgc
  378.         xchg    bx,cx        ; exchange dy and dx
  379.  
  380. ; calculate initial decision variable and increments
  381.  
  382. hgl04:        shl    bx,1        ; bx := 2 * dy
  383.         mov    varincr1,bx    ; incr1 := 2 * dy
  384.         sub    bx,cx
  385.         mov    di,bx        ; di := d = 2 * dy - dx
  386.         sub    bx,cx
  387.         mov    varincr2,bx    ; incr2 := 2 * (dy - dx)
  388.  
  389. ; calculate first pixel address
  390.  
  391.         push    cx        ; preserve this register
  392.         mov    ax,argy1    ; ax := y
  393.         mov    bx,argx1    ; bx := x
  394.         call    activeaddr    ; ah := bit mask
  395.                     ; es:bx -> buffer
  396.                     ; cl := # bits to shift left
  397.  
  398.         rol    fillmask,cl    ; ***********fillmask
  399.  
  400.         mov    al,byte ptr [color] ; al := unshifted pixel value
  401.  
  402.         cmp    rmwb,80h
  403.         jnz    oknot
  404.         not    al
  405. oknot:        and    al,1
  406.         shl    ax,cl        ; ah := bit mask in proper position
  407.                     ; al := pixel value in proper position
  408.  
  409.         mov    dx,ax        ; dh := bit mask
  410.                     ; dl := pixel value
  411.         not    dh        ; dh := inverse bit mask
  412.  
  413.         pop    cx        ; restore this register
  414.         inc    cx        ; cx := # of pixels to draw
  415.  
  416.         test    varroutine,1    ; jump to appropriate routine for slope
  417.         jnz    jmphislopeline
  418.         jmp    loslopelinehgc
  419. jmphislopeline: jmp    hislopelinehgc
  420.  
  421.  
  422. ; routine for vertical lines
  423.  
  424. vertlinehgc:    mov    ax,argy1    ; ax := y1
  425.         mov    bx,argy2    ; bx := y2
  426.         mov    cx,bx
  427.         sub    cx,ax        ; cx := dy
  428.         jge    hgl31        ; jump if dy >= 0
  429.  
  430.         neg    cx        ; force dy >= 0
  431.         mov    ax,bx        ; ax := y2
  432.  
  433. hgl31:        inc    cx        ; cx := # of pixels to draw
  434.         mov    bx,argx1    ; bx := x
  435.         push    cx        ; preserve this register
  436.         call    activeaddr    ; ah := bit mask
  437.                     ; es:bx -> video buffer
  438.                     ; cl := # bits to shift left
  439.  
  440.         rol    fillmask,cl    ; ***********fillmask
  441.  
  442.         mov    al,byte ptr [color] ; al := unshifted pixel value
  443.  
  444.         cmp    rmwb,80h
  445.         jnz    oknot2
  446.         not    al
  447. oknot2:     and    al,1
  448.         shl    ax,cl        ; ah := bit mask in proper position
  449.                     ; al := pixel value in proper position
  450.         not    ah        ; ah := inverse bit mask
  451.         pop    cx        ; restore this register
  452.  
  453. ; draw the line
  454.         cmp    rmwb,18h    ; fgxor
  455.         jz    hgl36a        ; jump if pixel should be xored
  456.  
  457.         test    rmwb,08h    ; fgand
  458.         jnz    hgl35a        ; jump if pixel should be anded
  459.  
  460.         test    rmwb,10h    ; fgor
  461.         jnz    hgl37a        ; jump if pixel should be ored
  462.  
  463. ;------------------ [fgnorm] set bit
  464. hgl32:        and    es:[bx],ah
  465.  
  466.         mov    dh,al
  467.         and    al,fillmask
  468.  
  469.         or    es:[bx],al    ; set pixel values in buffer
  470.         mov    al,dh
  471.  
  472.         ror    fillmask,1    ; pattern
  473.         add    bx,si        ; increment to next portion of interleave
  474.         jns    hgl33
  475.         add    bx,di        ; increment to first portion of interleave
  476. hgl33:        loop    hgl32
  477.         jmp    short hgl36
  478.  
  479. ;------------------ [fgand] set bit
  480. hgl35a:     mov    dh,es:[bx]
  481.  
  482.         mov    dl,al
  483.         and    al,fillmask
  484.  
  485.         and    dh,al
  486.         and    es:[bx],ah
  487.         or    es:[bx],dh
  488.  
  489.         mov    al,dl
  490.         ror    fillmask,1    ; pattern
  491.  
  492.         add    bx,si        ; increment to next portion of interleave
  493.         jns    hgl35c
  494.         add    bx,di        ; increment to first portion of interleave
  495. hgl35c:     loop    hgl35a
  496.         jmp    short hgl36
  497.  
  498. ;------------------ [fgxor] set bit
  499. hgl36a:
  500.         mov    dl,al
  501.         and    al,fillmask
  502.  
  503.         xor    es:[bx],al
  504.         mov    al,dl
  505.         ror    fillmask,1    ; pattern
  506.  
  507.         add    bx,si        ; increment to next portion of interleave
  508.         jns    hgl36c
  509.         add    bx,di        ; increment to first portion of interleave
  510. hgl36c:     loop    hgl36a
  511.         jmp    short hgl36
  512.  
  513. ;------------------ [fgor] set bit
  514. hgl37a:     mov    dh,ah
  515.         not    dh        ; reverse bits
  516.  
  517. hgl37b:     push    dx
  518.         push    ax
  519.  
  520.         and    al,fillmask
  521.         mov    dl,es:[bx]    ; get original screen pixel
  522.         and    dl,dh        ; and with required pixel
  523.         or    al,dl        ; set it on or off
  524.         and    al,dh
  525.         jz    hgl37and
  526.         or    es:[bx],al    ; reset pixel values in buffer
  527.         jmp    short hgl37n
  528. hgl37and:    and    es:[bx],ah    ; reset pixel values in buffer
  529.  
  530. hgl37n:     pop    ax
  531.         pop    dx
  532.  
  533.         ror    fillmask,1    ; pattern
  534.         add    bx,si        ; increment to next portion of interleave
  535.         jns    hgl37c
  536.         add    bx,di        ; increment to first portion of interleave
  537. hgl37c:     loop    hgl37b
  538. ;------------------
  539. hgl36:        jmp    hglexit
  540.  
  541.  
  542. ; routine for horizontal lines (slope = 0)
  543.  
  544. horizlinehgc:    mov    ax,argy1
  545.         mov    bx,argx1
  546.         call    activeaddr    ; ah := bit mask
  547.                     ; es:bx -> video buffer
  548.                     ; cl := # bits to shift left
  549.         mov    di,bx        ; es:di -> buffer
  550.  
  551.         mov    dh,ah
  552.         not    dh        ; dh := unshifted bit mask for leftmost
  553.                     ;     byte
  554.         mov    dl,0ffh     ; dl := unshifted bit mask for
  555.                     ;     rightmost byte
  556.  
  557.         shl    dh,cl        ; dh := reverse bit mask for first byte
  558.         not    dh        ; dh := bit mask for first byte
  559.  
  560.         test    transparent,0ffh
  561.         jnz    backfill    ; leave the mask alone if pattern fill
  562.         ror    fillmask,cl    ; ***********fillmask
  563.         ror    fillmask,1    ; ***********fillmask
  564.  
  565. backfill:    mov    cx,argx2
  566.         and    cl,7
  567.         xor    cl,7        ; cl := number of bits to shift left
  568.         shl    dl,cl        ; dl := bit mask for last byte
  569.  
  570. ; determine byte offset of first and last pixel in the line
  571.  
  572.         mov    ax,argx2    ; ax := x2
  573.         mov    bx,argx1    ; bx := x1
  574.  
  575.         mov    cl,3        ; number of bits to shift to
  576.                         ;  convert pixels to bytes
  577.  
  578.         shr    ax,cl        ; ax := byte offset of x2
  579.         shr    bx,cl        ; bx := byte offset of x1
  580.         mov    cx,ax
  581.         sub    cx,bx        ; cx := (# bytes in line) - 1
  582.  
  583.         mov    al,byte ptr [color] ; al := pixel value
  584.         mov    ah,byte ptr [fillmask]
  585.         not    ah
  586.  
  587.         xor    al,ah
  588.         test    byte ptr [color],0ffh
  589.         jnz    hglcolored
  590.         xor    al,al
  591.  
  592. hglcolored:    cmp    rmwb,18h    ; fgxor
  593.         jz    hglxor        ; jump if pixel should be xored
  594.  
  595.         test    rmwb,08h    ; fgand
  596.         jnz    hgland        ; jump if pixel should be anded
  597.  
  598.         test    rmwb,10h    ; fgor
  599.         jz    chknot
  600.         jmp    hglor        ; jump if pixel should be ored
  601.  
  602. chknot:     cmp    rmwb,80h
  603.         jnz    hglnorm
  604.         not    al
  605.  
  606. ;------------------ [fgnorm] set bit
  607. hglnorm:    or    dh,dh
  608.         js    hgl43        ; jump if byte-aligned (x1 is leftmost
  609.                     ;  pixel in byte)
  610.         or    cx,cx
  611.         jnz    hgl42        ; jump if more than one byte in the line
  612.         and    dl,dh        ; bit mask for the line
  613.         jmp    short hgl44
  614. hgl42:        mov    ah,al
  615.         and    ah,dh        ; ah := masked pixel bits
  616.         not    dh        ; dh := reverse bit mask for 1st byte
  617.         and    es:[di],dh    ; zero masked pixels in buffer
  618.         or    es:[di],ah    ; update masked pixels in buffer
  619.         inc    di
  620.         dec    cx
  621. hgl43:        rep    stosb        ; update all pixels in the line
  622. hgl44:        and    al,dl        ; al := masked pixels for last byte
  623.         not    dl
  624.         and    es:[di],dl    ; zero masked pixels in buffer
  625.         or    es:[di],al    ; update masked pixels in buffer
  626.         jmp    hglexit
  627.  
  628. ;------------------ [fgxor] set bit
  629. hglxor:
  630.         or    cx,cx
  631.         jnz    hlxor42     ; jump if more than one byte in the line
  632.         and    dl,dh        ; bit mask for the line
  633.         jmp    short hlxor44
  634. hlxor42:    mov    ah,al
  635.         xor    ah,es:[di]
  636.         and    ah,dh        ; ah := masked pixel bits
  637.         not    dh        ; dh := reverse bit mask for 1st byte
  638.         and    es:[di],dh    ; zero masked pixels in buffer
  639.         or    es:[di],ah    ; update masked pixels in buffer
  640.         inc    di
  641.         dec    cx
  642.         jz    hlxor44
  643. hlxor43:    xor    es:[di],al
  644.         inc    di
  645.         loop    hlxor43     ; update all pixels in the line
  646. hlxor44:    xor    al,es:[di]
  647.         and    al,dl        ; al := masked pixels for last byte
  648.         not    dl
  649.         and    es:[di],dl    ; zero masked pixels in buffer
  650.         or    es:[di],al    ; update masked pixels in buffer
  651.         jmp    hglexit
  652.  
  653. ;------------------ [fgand] set bit
  654. hgland:
  655.         or    cx,cx
  656.         jnz    hland42     ; jump if more than one byte in the line
  657.         and    dl,dh        ; bit mask for the line
  658.         jmp    short hland44
  659. hland42:    mov    ah,al
  660.         and    ah,es:[di]
  661.         and    ah,dh        ; ah := masked pixel bits
  662.         not    dh        ; dh := reverse bit mask for 1st byte
  663.         and    es:[di],dh    ; zero masked pixels in buffer
  664.         or    es:[di],ah    ; update masked pixels in buffer
  665.         inc    di
  666.         dec    cx
  667.         jz    hland44
  668. hland43:    and    es:[di],al
  669.         inc    di
  670.         loop    hland43     ; update all pixels in the line
  671. hland44:    and    al,es:[di]
  672.         and    al,dl        ; al := masked pixels for last byte
  673.         not    dl
  674.         and    es:[di],dl    ; zero masked pixels in buffer
  675.         or    es:[di],al    ; update masked pixels in buffer
  676.         jmp    hglexit
  677.  
  678. ;------------------ [fgor] set bit
  679. hglor:
  680.         or    cx,cx
  681.         jnz    hlor42        ; jump if more than one byte in the line
  682.         and    dl,dh        ; bit mask for the line
  683.         jmp    short hlor44
  684. hlor42:     mov    ah,al
  685.         or    ah,es:[di]
  686.         and    ah,dh        ; ah := masked pixel bits
  687.         not    dh        ; dh := reverse bit mask for 1st byte
  688.         and    es:[di],dh    ; zero masked pixels in buffer
  689.         or    es:[di],ah    ; update masked pixels in buffer
  690.         inc    di
  691.         dec    cx
  692.         jz    hlor44
  693. hlor43:     or    es:[di],al
  694.         inc    di
  695.         loop    hlor43        ; update all pixels in the line
  696. hlor44:     or    al,es:[di]
  697.         and    al,dl        ; al := masked pixels for last byte
  698.         not    dl
  699.         and    es:[di],dl    ; zero masked pixels in buffer
  700.         or    es:[di],al    ; update masked pixels in buffer
  701.         jmp    hglexit
  702.  
  703.  
  704.  
  705. ; routine for dy <= dx (slope <= 1)    ; es:bx -> video buffer
  706.                     ; cx = #pixels to draw
  707.                     ; dh = inverse bit mask
  708.                     ; dl = pixel value in proper position
  709.                     ; si = buffer interleave increment
  710.                     ; di = decision variable
  711. loslopelinehgc:
  712.  
  713. hgl10:        mov    ah,es:[bx]    ; ah := byte from video buffer
  714.  
  715. hgl11:
  716. ;****************** check for norm/and/or/xor/not
  717.         test    rmwb,0ffh    ; fgnorm
  718.         jz    hgl14d
  719.  
  720.         test    rmwb,08h    ; fgand
  721.         jz    hgl14b
  722.  
  723.         test    rmwb,10h    ; fgxor
  724.         jnz    hgl14a
  725.  
  726.         push    dx
  727.         and    dl,fillmask
  728.         mov    al,ah        ; screen
  729.         and    ah,dl        ; and with bit
  730.         and    al,dh        ; mask screen to zero
  731.         or    ah,al        ; or with new and bit
  732.         pop    dx
  733.         jmp    short hgl14e
  734.  
  735. hgl14a:     mov    al,dl
  736.         and    al,fillmask
  737.         xor    ah,al
  738.         jmp    short hgl14e
  739.  
  740. hgl14b:     test    rmwb,80h    ; fgnot (implemented above)
  741.         jz    hgl14c
  742.         jmp    short hgl14d
  743.  
  744. hgl14c:     test    rmwb,10h    ; fgor
  745.         jz    hgl14d
  746.         jmp    short hgl14f
  747.  
  748. ;        mov    al,dl
  749. ;        and    al,fillmask
  750. ;        or    ah,al        ; set pixel value in byte
  751. ;        jmp    short hgl14e
  752.  
  753. hgl14d:     and    ah,dh        ; zero pixel value at current bit offset
  754. hgl14f:     mov    al,dl
  755.         and    al,fillmask
  756.         or    ah,al        ; set pixel value in byte
  757.  
  758. ;************************************************
  759. hgl14e:     ror    dl,1        ; rotate pixel value
  760.         ror    dh,1        ; rotate bit mask
  761.         jnc    hgl14        ; jump if bit mask rotated to
  762.                     ;  leftmost pixel position
  763.  
  764. ; bit mask not shifted out
  765.  
  766.         or    di,di        ; test sign of d
  767.         jns    hgl12        ; jump if d >= 0
  768.  
  769.         add    di,varincr1    ; d := d + incr1
  770.         loop    hgl11
  771.  
  772.         mov    es:[bx],ah    ; store remaining pixels in buffer
  773.         jmp    hglexit
  774.  
  775. hgl12:        add    di,varincr2    ; d := d + incr2
  776.         mov    es:[bx],ah    ; update buffer
  777.         jmp    short hgl15b
  778.  
  779. ;        add    bx,si        ; increment y
  780. ;        jns    hgl13        ; jump if not in last interleave
  781. ;
  782. ;        add    bx,varleafincr    ; increment into next interleave
  783. ;
  784. ;hgl13:      loop     hgl10
  785. ;         jmp     hglexit
  786.  
  787. ; bit mask shifted out
  788.  
  789. hgl14:        mov    es:[bx],ah    ; update buffer
  790.         inc    bx        ; bx := offset of next byte
  791.  
  792.         or    di,di        ; test sign of d
  793.         jns    hgl15        ; jump if non-negative
  794.  
  795.         add    di,varincr1    ; d := d + incr1
  796.         loop    hgl10
  797.         jmp    short hglexit
  798.  
  799. hgl15:        add    di,varincr2    ; d := d + incr2
  800.  
  801. hgl15b:     add    bx,si        ; increment y
  802.         jns    hgl16        ; jump if not in last interleave
  803.  
  804.         add    bx,varleafincr    ; increment into next interleave
  805.  
  806. hgl16:        loop    hgl10        ; loop until all pixels are set
  807.         jmp    short hglexit
  808.  
  809.  
  810. ; routine for dy > dx (slope > 1)    ; es:bx -> video buffer
  811.                     ; cx = #pixels to draw
  812.                     ; dh = inverse bit mask
  813.                     ; dl = pixel value in proper position
  814.                     ; si = buffer interleave increment
  815.                     ; di = decision variable
  816. hislopelinehgc:
  817.  
  818. hgl21:
  819. ;****************** check for norm/and/or/xor/not
  820.         test    rmwb,0ffh    ; fgnorm
  821.         jz    hgl21d
  822.  
  823.         test    rmwb,08h    ; fgand
  824.         jz    hgl21b
  825.  
  826.         test    rmwb,10h    ; fgxor
  827.         jnz    hgl21a
  828.  
  829.         push    dx
  830.         and    dl,fillmask
  831.         mov    al,es:[bx]    ; screen
  832.         and    al,dl        ; and with bit
  833.         and    es:[bx],dh    ; mask screen to zero
  834.         or    es:[bx],al    ; or with new and bit
  835.         pop    dx
  836.         jmp    short hgl21e
  837.  
  838. hgl21a:     push    dx
  839.         and    dl,fillmask
  840.         xor    es:[bx],dl
  841.         pop    dx
  842.         jmp    short hgl21e
  843.  
  844. hgl21b:     test    rmwb,80h    ; fgnot (implemented above)
  845.         jz    hgl21c
  846.         jmp    short hgl21d
  847.  
  848. hgl21c:     test    rmwb,10h    ; fgor
  849.         jz    hgl21d
  850.         push    dx
  851.         and    dl,fillmask
  852.         or    es:[bx],dl    ; set pixel value in byte
  853.         pop    dx
  854.         jmp    short hgl21e
  855.  
  856. hgl21d:     push    dx
  857.         and    dl,fillmask
  858.         and    es:[bx],dh    ; zero pixel value in video buffer
  859.         or    es:[bx],dl    ; set pixel value in byte
  860.         pop    dx
  861.  
  862. ;************************************************
  863.  
  864. hgl21e:     add    bx,si        ; increment y
  865.         jns    hgl22        ; jump if not in last interleave
  866.  
  867.         add    bx,varleafincr    ; increment into next interleave
  868.  
  869. hgl22:        or    di,di
  870.         jns    hgl23        ; jump if d >= 0
  871.  
  872.         add    di,varincr1    ; d := d + incr1
  873.         loop    hgl21
  874.         jmp    short hglexit
  875.  
  876.  
  877. hgl23:        add    di,varincr2    ; d := d + incr2
  878.  
  879.         ror    dl,1        ; rotate pixel value
  880.         ror    dh,1        ; rotate bit mask
  881.         cmc            ; cf set if bit mask not rotated to
  882.                     ;  leftmost pixel position
  883.         adc    bx,0        ; bx := offset of next byte
  884.  
  885.         loop    hgl21
  886.  
  887. hglexit:    pop    di
  888.         pop    es
  889.         pop    si
  890.         pop    ds
  891.         ret
  892. fastline    endp
  893.  
  894.  
  895. putpixs     proc    far argx:word,argy:word,color:word
  896.         local    rmwb:word
  897.  
  898.         push    ds
  899.         push    si
  900.         push    es
  901.         push    di
  902.  
  903.         colorxlat color
  904.  
  905.         lds    si,cs:TDtable
  906.         mov    ax,ds:[si].rmwbits
  907.         mov    rmwb,ax
  908.  
  909.         mov    ax,ds:[si].wminy
  910.         cmp    argy,ax
  911.         jl    pix14e
  912.  
  913.         mov    ax,ds:[si].wmaxy
  914.         cmp    argy,ax
  915.         jg    pix14e
  916.  
  917.         mov    ax,ds:[si].wminx
  918.         cmp    argx,ax
  919.         jl    pix14e
  920.  
  921.         mov    ax,ds:[si].wmaxx
  922.         cmp    argx,ax
  923.         jg    pix14e
  924.  
  925.         mov    al,byte ptr [color] ; al := unshifted pixel value
  926.         cmp    rmwb,80h
  927.         jnz    pixnot
  928.         not    al
  929. pixnot:     mov    byte ptr [color],al
  930.  
  931.         mov    ax,argy     ; ax := y
  932.         mov    bx,argx     ; bx := x
  933.         call    activeaddr    ; ah := bit mask
  934.                     ; es:bx -> buffer
  935.                     ; cl := # bits to shift left
  936.  
  937. ; set the pixel value
  938.         shl    ah,cl        ; ah := bit mask in proper position
  939.         mov    al,ah
  940.         not    ah
  941.         and    al,byte ptr [color]
  942.  
  943. ;****************** check for norm/and/or/xor/not
  944.         test    rmwb,0ffh    ; fgnorm
  945.         jz    pix14d
  946.  
  947.         test    rmwb,08h    ; fgand
  948.         jz    pix14b
  949.  
  950.         test    rmwb,10h    ; fgxor
  951.         jnz    pix14a
  952.  
  953.         mov    dl,es:[bx]    ; screen
  954.         and    dl,al        ; and with bit
  955.         and    es:[bx],ah    ; mask screen to zero
  956.         or    es:[bx],dl    ; or with new and bit
  957.         jmp    short pix14e
  958.  
  959. pix14a:     xor    es:[bx],al
  960.         jmp    short pix14e
  961.  
  962. pix14b:     test    rmwb,80h    ; fgnot (implemented above)
  963.         jz    pix14c
  964.         jmp    short pix14d
  965.  
  966. pix14c:     test    rmwb,10h    ; fgor
  967.         jz    pix14d
  968.         or    es:[bx],al
  969.         jmp    short pix14e
  970.  
  971. pix14d:     and    es:[bx],ah
  972.         or    es:[bx],al
  973. ;************************************************
  974. pix14e:
  975.         pop    di
  976.         pop    es
  977.         pop    si
  978.         pop    ds
  979.         ret
  980. putpixs     endp
  981.  
  982.  
  983. scanborder    proc    far argx:word,argy:word,bordercolor:word,scan:word
  984.         local    swminx:word,swmaxx:word,bwminx:word,bwmaxx:word
  985.         push    ds
  986.         push    si
  987.         push    es
  988.         push    di
  989.  
  990.         mov    cl,3
  991.         lds    si,cs:TDtable
  992.         mov    ax,ds:[si].wminx
  993.         mov    swminx,ax
  994.         shr    ax,cl
  995.         mov    bwminx,ax
  996.         mov    ax,ds:[si].wmaxx
  997.         mov    swmaxx,ax
  998.         shr    ax,cl
  999.         mov    bwmaxx,ax
  1000.  
  1001.  
  1002.         mov    ax,argy     ; ax := y
  1003.         xor    bx,bx        ; bx := x = 0
  1004.         call    activeaddr    ; ah := bit mask
  1005.                     ; es:bx -> buffer
  1006.                     ; cl := #bits to shift
  1007.         mov    di,bx        ; es:di -> buffer
  1008.  
  1009.         mov    ax,argx
  1010.         mov    si,ax
  1011.         mov    cl,3
  1012.         shr    si,cl
  1013.         add    di,si
  1014.  
  1015.         test    scan,8000h
  1016.         jz    forwscan
  1017.  
  1018.         ; inspect first byte
  1019. backscan:    mov    cx,argx         ;create mask to check
  1020.         not    cl            ;first byte
  1021.         and    cl,7
  1022.         mov    ch,0ffh
  1023.         shl    ch,cl
  1024.  
  1025.         mov    al,es:[di]
  1026.         dec    di
  1027.         and    al,ch
  1028.         jnz    scanl05
  1029.  
  1030.         ;scan remainder of line for border pixels
  1031.         mov    cx,si
  1032.         inc    cx
  1033.         sub    cx,bwminx
  1034.         jle    scanl05
  1035.         jcxz    scanl05
  1036.  
  1037.         std
  1038.         repe    scasb
  1039.         mov    al,es:[di+1]
  1040.         cld
  1041.  
  1042. scanl05:    sub    di,bx
  1043.         inc    di
  1044.         mov    cl,3
  1045.         shl    di,cl
  1046.         mov    cx,7
  1047.  
  1048. scanl06:    shr    al,1
  1049.         jc    scanl07
  1050.         loop    scanl06
  1051.  
  1052. scanl07:    add    di,cx
  1053.         jmp    scanl08
  1054.  
  1055.  
  1056.  
  1057.         ; inspect first byte
  1058. forwscan:    mov    cx,argx         ;create mask to check
  1059.         and    cl,7            ;first byte
  1060.         mov    ch,0ffh
  1061.         shr    ch,cl
  1062.  
  1063.         mov    al,es:[di]
  1064.         inc    di
  1065.         and    al,ch
  1066.         jnz    scanl01
  1067.  
  1068.         ;scan remainder of line for border pixels
  1069.  
  1070.         mov    cx,bwmaxx
  1071.         inc    cx
  1072.         sub    cx,si
  1073.         jle    scanl01
  1074.         jcxz    scanl01
  1075.         dec    cx
  1076.  
  1077.         cld
  1078.         repe    scasb
  1079.         mov    al,es:[di-1]
  1080.  
  1081. scanl01:    sub    di,bx
  1082.         mov    cl,3
  1083.         shl    di,cl
  1084.         mov    cx,8
  1085.  
  1086. scanl02:    shl    al,1
  1087.         jc    scanl03
  1088.         loop    scanl02
  1089.  
  1090. scanl03:    sub    di,cx
  1091.  
  1092. scanl08:    mov    ax,swminx
  1093.         dec    ax
  1094.         cmp    di,ax
  1095.         jle    scanl04
  1096.         mov    ax,swmaxx
  1097.         inc    ax
  1098.         cmp    di,ax
  1099.         jge    scanl04
  1100.  
  1101.         mov    ax,di
  1102. scanl04:
  1103.         pop    di
  1104.         pop    es
  1105.         pop    si
  1106.         pop    ds
  1107.         ret
  1108. scanborder    endp
  1109.  
  1110.  
  1111. getpixs     proc    far argx:word,argy:word
  1112.         push    si
  1113.  
  1114.         mov    ax,argy     ; ax := y
  1115.         mov    bx,argx     ; bx := x
  1116.         call    activeaddr    ; ah := bit mask
  1117.                     ; es:bx -> buffer
  1118.                     ; cl := #bits to shift
  1119.  
  1120.         mov    al,es:[bx]
  1121.         shr    al,cl
  1122.         and    al,ah
  1123.         xor    ah,ah
  1124.  
  1125.         pop    si
  1126.         ret
  1127. getpixs     endp
  1128.  
  1129.  
  1130. getbiti     proc    far argx0:word,argy0:word,argx1:word,argy1:word,addrbuf:dword
  1131.         local    varpixelrows : word, varpixelrowlen : word
  1132.  
  1133.         push    ds
  1134.         push    si
  1135.         push    di
  1136.  
  1137.         cld
  1138. ; compute dimensions of bit block
  1139.  
  1140.         mov    ax,argx1
  1141.         sub    ax,argx0
  1142.         mov    cx,0ff07h    ; ch := unshifted bit mask
  1143.                     ; cl := and mask for al
  1144.         and    cl,al        ; cl := number of pixels in last
  1145.                     ;  byte of row
  1146.         xor    cl,7        ; cl := number of bits to shift
  1147.         shl    ch,cl        ; ch := bit mask for last byte of row
  1148.         mov    cl,ch
  1149.         push    cx        ; save on stack
  1150.  
  1151.         mov    cl,3
  1152.         shr    ax,cl
  1153.         inc    ax        ; ax := number of bytes per row
  1154.         push    ax        ; save on stack
  1155.  
  1156.         mov    ax,argy1
  1157.         sub    ax,argy0
  1158.         inc    ax        ; ax := number of pixel rows
  1159.         push    ax        ; save on stack
  1160.  
  1161. ; establish addressing
  1162.  
  1163.         mov    ax,argy0
  1164.         mov    bx,argx0
  1165.         call    activeaddr    ; es:bx -> x0,y0 in video buffer
  1166.         xor    cl,7        ; cl := number of bits to shift left
  1167.         push    es
  1168.         pop    ds
  1169.         mov    si,bx        ; ds:si -> video buffer
  1170.  
  1171.         les    di,addrbuf    ; es:di -> buffer in system ram
  1172.  
  1173. ; build 5-byte bit block header
  1174.  
  1175.         pop    ax
  1176.         mov    varpixelrows,ax
  1177.         stosw            ; byte 0-1 := number of pixel rows
  1178.         pop    ax
  1179.         mov    varpixelrowlen,ax
  1180.         stosw            ; byte 2-3 := bytes per pixel row
  1181.         pop    ax
  1182.         mov    ch,al        ; ch := bit mask for last byte
  1183.         stosb            ; byte 4 := bit mask for last byte
  1184.  
  1185. ; copy from video buffer to system ram
  1186.  
  1187. getbl02:    mov    bx,varpixelrowlen
  1188.         push    si        ; preserve si at start of pixel row
  1189.  
  1190. getbl03:    lodsw            ; al := next byte in video buffer
  1191.                     ; ah := (next byte) + 1
  1192.         dec    si        ; ds:si -> (next byte) + 1
  1193.         rol    ax,cl        ; al := next 4 pixels in row
  1194.         stosb            ; copy to system ram
  1195.         dec    bx        ; loop across row
  1196.         jnz    getbl03
  1197.  
  1198.         and    es:[di-1],ch    ; mask last byte of row
  1199.         pop    si        ; ds:si -> start of row
  1200.         add    si,nextinterleave ; ds:si -> start of next row
  1201.         jns    gbl03a
  1202.         add    si,firstinterleave
  1203. gbl03a:     dec    varpixelrows
  1204.         jnz    getbl02     ; loop down rows
  1205.  
  1206.  
  1207.         pop    di
  1208.         pop    si
  1209.         pop    ds
  1210.         ret
  1211. getbiti     endp
  1212.  
  1213.  
  1214. putbiti     proc    far argx:word,argy:word,addrbuf:dword,rmwb:word
  1215.         local    varpixelrows:word,varpixelrowlen:word
  1216.  
  1217.         ; rmwbits -   normalput        00h
  1218.         ;          xorput           18h
  1219.         ;          orput           10h
  1220.         ;          andput           08h
  1221.         ;          notput           80h
  1222.  
  1223.         push    ds
  1224.         push    si
  1225.         push    di
  1226.  
  1227.         cld
  1228. ; establish addressing
  1229.  
  1230.         mov    ax,argy
  1231.         mov    bx,argx
  1232.         call    activeaddr    ; es:bx -> byte offset of x,y
  1233.         xor    cl,7        ; cl := number of bits to shift right
  1234.  
  1235.         mov    di,bx        ; es:di -> x,y in video buffer
  1236.         lds    si,addrbuf    ; es:di -> buffer in system ram
  1237.  
  1238. ; obtain dimensions of bit block from header
  1239.  
  1240.         lodsw            ; ax := number of pixel rows
  1241.         mov    varpixelrows,ax
  1242.         lodsw            ; ax := bytes per pixel row
  1243.         mov    varpixelrowlen,ax
  1244.         lodsb            ; al := bit mask for last byte in row
  1245.         mov    ch,al
  1246.  
  1247. ;****************** check for norm/and/or/xor/not
  1248.         test    rmwb,0ffh    ; fgnorm
  1249.         jz    replacebitblock
  1250.  
  1251.         cmp    rmwb,18h    ; fgxor
  1252.         jnz    puttst00
  1253.         jmp    xorbitblock
  1254.  
  1255. puttst00:    test    rmwb,08h    ; fgand
  1256.         jz    puttst01
  1257.         jmp    andbitblock
  1258.  
  1259. puttst01:    test    rmwb,10h    ; fgor
  1260.         jz    puttst02
  1261.         jmp    orbitblock
  1262.  
  1263. puttst02:    test    rmwb,80h    ; fgnot (implemented above)
  1264.         jz    replacebitblock
  1265.         jmp    notbitblock
  1266. ;************************************************
  1267.  
  1268. replacebitblock:
  1269.         cmp    cx,0ff00h    ; if mask <> 0ffh or bits to shift <> 0
  1270.         jne    putbl15     ;  jump if not byte-aligned
  1271.  
  1272. ; routine for byte-aligned bit blocks
  1273.  
  1274.         mov    cx,varpixelrowlen
  1275.  
  1276. putbl10:    push    di        ; preserve di and cx
  1277.         push    cx
  1278.  
  1279.         shr    cx,1        ; copy one pixel row into video buffer
  1280.         rep    movsw
  1281.         adc    cx,0
  1282.         rep    movsb
  1283.  
  1284.         pop    cx        ; restore di and cx
  1285.         pop    di
  1286.         add    di,nextinterleave ; es:di -> next pixel row in buffer
  1287.         jns    pbl10a
  1288.         add    di,firstinterleave
  1289. pbl10a:     dec    varpixelrows
  1290.         jnz    putbl10     ; loop down pixel rows
  1291.  
  1292.         jmp    lexit2
  1293.  
  1294. ; routine for all other bit blocks
  1295.  
  1296. putbl15:    not    ch        ; ch := mask for end of row
  1297.         mov    dx,0ff00h
  1298.         ror    dx,cl        ; dx := rotated mask for each byte
  1299.  
  1300.         mov    bx,varpixelrowlen
  1301.         dec    bx        ; bx := bytes per row - 1
  1302.  
  1303. putbl16:    push    di
  1304.         test    bx,bx
  1305.         jz    putbl18     ; jump if only one byte per row
  1306.  
  1307.         push    bx
  1308.  
  1309. putbl17:    and    es:[di],dx    ; mask next 8 pixels in video buffer
  1310.         lodsb            ; al := pixels in bit block
  1311.         xor    ah,ah
  1312.         ror    ax,cl        ; ax := pixels rotated into position
  1313.         or    es:[di],ax    ; set pixels in video buffer
  1314.         inc    di        ; es:di -> next byte in bit block
  1315.         dec    bx
  1316.         jnz    putbl17
  1317.  
  1318.         pop    bx
  1319.  
  1320. putbl18:    mov    al,ch
  1321.         mov    ah,0ffh     ; ax := mask for last pixels in row
  1322.         ror    ax,cl        ; ax := mask rotated into position
  1323.         and    es:[di],ax    ; mask last pixels in video buffer
  1324.         lodsb            ; al := last byte in row
  1325.         xor    ah,ah
  1326.         ror    ax,cl        ; ax := pixels rotated into position
  1327.         or    es:[di],ax    ; set pixels in video buffer
  1328.  
  1329.         pop    di
  1330.         add    di,nextinterleave ; es:di -> next pixel row in buffer
  1331.         jns    pbl18a
  1332.         add    di,firstinterleave
  1333. pbl18a:     dec    varpixelrows
  1334.         jnz    putbl16     ; loop down pixel rows
  1335.  
  1336.         jmp    lexit2
  1337.  
  1338.  
  1339. xorbitblock:
  1340.         mov    bx,varpixelrowlen
  1341.  
  1342. putbl20:    push    di
  1343.         push    bx
  1344.  
  1345. putbl21:    lodsb            ; al := pixels in bit block
  1346.         xor    ah,ah
  1347.         ror    ax,cl        ; ax := pixels rotated into position
  1348.         xor    es:[di],ax    ; xor pixels into video buffer
  1349.         inc    di        ; es:di -> next byte in bit block
  1350.         dec    bx
  1351.         jnz    putbl21
  1352.  
  1353.         pop    bx
  1354.         pop    di
  1355.         add    di,nextinterleave ; es:di -> next pixel row in buffer
  1356.         jns    pbl21a
  1357.         add    di,firstinterleave
  1358. pbl21a:     dec    varpixelrows
  1359.         jnz    putbl20     ; loop down pixel rows
  1360.  
  1361.         jmp    lexit2
  1362.  
  1363. andbitblock:
  1364.         not    ch        ; ch := mask for end of row
  1365.  
  1366.         mov    bx,varpixelrowlen
  1367.         dec    bx        ; bx := bytes per row - 1
  1368.  
  1369. putbl30:    push    di
  1370.         test    bx,bx
  1371.         jz    putbl32     ; jump if only one byte per row
  1372.  
  1373.         push    bx
  1374.  
  1375. putbl31:    lodsb            ; al := pixels in bit block
  1376.         mov    ah,0ffh
  1377.         ror    ax,cl        ; ax := pixels rotated into position
  1378.         and    es:[di],ax    ; and pixels into video buffer
  1379.         inc    di        ; es:di -> next byte in bit block
  1380.         dec    bx
  1381.         jnz    putbl31
  1382.  
  1383.         pop    bx
  1384.  
  1385. putbl32:    lodsb            ; al := last byte in row
  1386.         or    al,ch        ; mask last pixels in row
  1387.         mov    ah,0ffh
  1388.         ror    ax,cl        ; ax := pixels rotated into position
  1389.         and    es:[di],ax    ; and pixels into video buffer
  1390.  
  1391.         pop    di
  1392.         add    di,nextinterleave ; es:di -> next pixel row in buffer
  1393.         jns    pbl32a
  1394.         add    di,firstinterleave
  1395. pbl32a:     dec    varpixelrows
  1396.         jnz    putbl30     ; loop down pixel rows
  1397.  
  1398.         jmp    lexit2
  1399.  
  1400.  
  1401. orbitblock:
  1402.         mov    bx,varpixelrowlen
  1403.  
  1404. putbl40:    push    di
  1405.         push    bx
  1406.  
  1407. putbl41:    lodsb            ; al := pixels in bit block
  1408.         xor    ah,ah
  1409.         ror    ax,cl        ; ax := pixels rotated into position
  1410.         or    es:[di],ax    ; or pixels into video buffer
  1411.         inc    di        ; es:di -> next byte in bit block
  1412.         dec    bx
  1413.         jnz    putbl41
  1414.  
  1415.         pop    bx
  1416.         pop    di
  1417.         add    di,nextinterleave ; es:di -> next pixel row in buffer
  1418.         jns    pbl41a
  1419.         add    di,firstinterleave
  1420. pbl41a:     dec    varpixelrows
  1421.         jnz    putbl40     ; loop down pixel rows
  1422.         jmp    lexit2
  1423.  
  1424. notbitblock:
  1425.         not    ch        ; ch := mask for end of row
  1426.         mov    dx,0ff00h
  1427.         ror    dx,cl        ; dx := rotated mask for each byte
  1428.  
  1429.         mov    bx,varpixelrowlen
  1430.         dec    bx        ; bx := bytes per row - 1
  1431.  
  1432. notbl16:    push    di
  1433.         test    bx,bx
  1434.         jz    notbl18     ; jump if only one byte per row
  1435.  
  1436.         push    bx
  1437.  
  1438. notbl17:    and    es:[di],dx    ; mask next 8 pixels in video buffer
  1439.         lodsb            ; al := pixels in bit block
  1440.         not    al
  1441.         xor    ah,ah
  1442.         ror    ax,cl        ; ax := pixels rotated into position
  1443.         or    es:[di],ax    ; set pixels in video buffer
  1444.         inc    di        ; es:di -> next byte in bit block
  1445.         dec    bx
  1446.         jnz    notbl17
  1447.  
  1448.         pop    bx
  1449.  
  1450. notbl18:    mov    al,ch
  1451.         mov    ah,0ffh     ; ax := mask for last pixels in row
  1452.         ror    ax,cl        ; ax := mask rotated into position
  1453.         and    es:[di],ax    ; mask last pixels in video buffer
  1454.         lodsb            ; al := last byte in row
  1455.         not    al
  1456.         not    ch
  1457.         and    al,ch
  1458.         not    ch
  1459.         xor    ah,ah
  1460.         ror    ax,cl        ; ax := pixels rotated into position
  1461.         or    es:[di],ax    ; set pixels in video buffer
  1462.  
  1463.         pop    di
  1464.         add    di,nextinterleave ; es:di -> next pixel row in buffer
  1465.         jns    nbl18a
  1466.         add    di,firstinterleave
  1467. nbl18a:     dec    varpixelrows
  1468.         jnz    notbl16     ; loop down pixel rows
  1469.  
  1470.  
  1471. lexit2:     pop    di
  1472.         pop    si
  1473.         pop    ds
  1474.         ret
  1475.  
  1476. putbiti     endp
  1477.  
  1478.  
  1479.  
  1480. extractimg    proc    far argx0:word,argy0:word,argx1:word,argy1:word,addrbuf1:dword,addrbuf2:dword
  1481.         local    var1pixelrows : word, var1pixelrowlen  : word
  1482.         local    var2pixelrows : word, var2pixelrowlen  : word
  1483.  
  1484.         push    ds
  1485.         push    si
  1486.         push    es
  1487.         push    di
  1488.  
  1489.         les    di,addrbuf1
  1490.         lds    si,addrbuf2
  1491.  
  1492.         cld
  1493.         lodsw                ; var2pixelrows
  1494.         mov    var2pixelrows,ax
  1495.         lodsw                ; var2pixelrows
  1496.         mov    var2pixelrowlen,ax
  1497.         lodsb
  1498.  
  1499.  
  1500. ; compute dimensions of bit block
  1501. ; build 5-byte bit block header
  1502.  
  1503.         ; number of pixel rows
  1504.         mov    ax,argy1
  1505.         sub    ax,argy0
  1506.         inc    ax
  1507.         mov    var1pixelrows,ax
  1508.         stosw
  1509.  
  1510.         ; number of bytes per row
  1511.         mov    ax,argx1
  1512.         sub    ax,argx0
  1513.         push    ax
  1514.         mov    cl,3            ; divide by 8 pix per byte
  1515.         shr    ax,cl
  1516.         inc    ax            ; ax := number of bytes per row
  1517.         mov    var1pixelrowlen,ax
  1518.         stosw
  1519.         pop    ax
  1520.  
  1521.         ; last byte in row bit mask
  1522.         mov    cx,0ff07h        ; ch := unshifted bit mask
  1523.                         ; cl := and mask for al
  1524.         and    cl,al            ; cl := remaining pixels in
  1525.                         ; last byte of row
  1526.         xor    cl,7
  1527.         shl    ch,cl            ; create the last byte mask
  1528.  
  1529.         mov    al,ch
  1530.         stosb
  1531.  
  1532. ; establish addressing
  1533.  
  1534.         mov    ax,argy0
  1535.         mov    bx,argx0
  1536.         mov    cl,bl
  1537.  
  1538.         mov    dx,var2pixelrowlen
  1539.         mul    dx            ; multiply rows by bytesperrow
  1540.  
  1541.         shr    bx,1            ; divide x coordinate by 8
  1542.         shr    bx,1
  1543.         shr    bx,1
  1544.         add    bx,ax            ; add to address
  1545.         add    si,bx
  1546.  
  1547.         and    cl,7            ; bits remainder
  1548.  
  1549. ; copy from bit block2 to bit block1
  1550.         mov    dx,var1pixelrows
  1551. extrc07:    mov    bx,var1pixelrowlen
  1552.         push    si
  1553.  
  1554. extrc08:    lodsw
  1555.         dec    si
  1556.         rol    ax,cl
  1557.         stosb
  1558.         dec    bx
  1559.         jnz    extrc08
  1560.  
  1561.         and    es:[di-1],ch
  1562.         pop    si
  1563.         add    si,var2pixelrowlen
  1564.  
  1565.         dec    dx
  1566.         jnz    extrc07
  1567.  
  1568.  
  1569.         pop    di
  1570.         pop    es
  1571.         pop    si
  1572.         pop    ds
  1573.         ret
  1574.  
  1575. extractimg    endp
  1576.  
  1577.  
  1578.  
  1579. overlayimg    proc    far argx0:word,argy0:word,addrbuf1:dword,addrbuf2:dword
  1580.         local    var1pixelrows : word, var1pixelrowlen  : word
  1581.         local    var2pixelrows : word, var2pixelrowlen  : word
  1582.         local    varstartmask  : byte, varendmaskl      : byte
  1583.         local    varendmaskr   : byte, screenmask       : byte
  1584.  
  1585.         push    ds
  1586.         push    si
  1587.         push    es
  1588.         push    di
  1589.  
  1590.         cld
  1591.  
  1592.         lds    si,addrbuf2
  1593.         lodsw            ; var2pixelrows
  1594.         mov    var2pixelrows,ax
  1595.         lodsw            ; var2pixelrows
  1596.         mov    var2pixelrowlen,ax
  1597.         lodsb
  1598.  
  1599.         push    ds
  1600.         push    si
  1601.         pop    di        ; es:di -> addrbuf2
  1602.         pop    es
  1603.  
  1604.         lds    si,addrbuf1
  1605.         lodsw            ; var1pixelrows
  1606.         mov    var1pixelrows,ax
  1607.         lodsw            ; var1pixelrows
  1608.         mov    var1pixelrowlen,ax
  1609.         lodsb
  1610.         mov    ch,al        ; ds:si -> addrbuf1
  1611.                     ; ch    -> last byte mask
  1612.  
  1613. ; establish addressing
  1614.  
  1615.         mov    ax,argy0
  1616.         mov    bx,argx0
  1617.         mov    cl,bl
  1618.  
  1619.         mov    dx,var2pixelrowlen
  1620.         mul    dx        ; multiply rows by bytesperrow
  1621.  
  1622.         shr    bx,1        ; divide x coordinate by 8
  1623.         shr    bx,1
  1624.         shr    bx,1
  1625.         add    bx,ax
  1626.         add    di,bx        ; add to address of addrbuf2
  1627.  
  1628.         and    cl,7
  1629.         xor    cl,7
  1630.         inc    cl
  1631.         and    cl,7        ; bits remainder
  1632.  
  1633.         cmp    cx,0ff00h
  1634.         jne    overl15
  1635.  
  1636. ; routine for byte-aligned bit blocks
  1637.         mov    cx,var1pixelrowlen
  1638.  
  1639.         mov    bx,var1pixelrows
  1640.  
  1641. overl11:    push    di
  1642.         push    cx
  1643.  
  1644.         shr    cx,1
  1645.         rep    movsw
  1646.         adc    cx,0
  1647.         rep    movsb
  1648.  
  1649.         pop    cx
  1650.         pop    di
  1651.         add    di,var2pixelrowlen
  1652.         dec    bx
  1653.         jnz    overl11
  1654.         jmp    overlexit
  1655.  
  1656.  
  1657. ; copy from bit block2 to bit block1
  1658.  
  1659. overl15:    mov    bx,0ffh     ; bh := 0 (mask for first byte in row
  1660.                     ; bl := 0ffh
  1661.         mov    al,ch        ; al := mask for last byte in pixel row
  1662.         cbw            ; ah := 0ffh (mask for last-1 byte)
  1663.  
  1664.         cmp    var1pixelrowlen,1
  1665.         jne    overl16     ; jump if more than one byte per row
  1666.  
  1667.         mov    bl,ch
  1668.         mov    ah,ch        ; ah := mask for last-1 byte
  1669.         xor    al,al        ; al := 0 (mask for last byte)
  1670.  
  1671. overl16:    shl    ax,cl        ; shift masks into position
  1672.         shl    bx,cl
  1673.  
  1674.  
  1675. ;        use not to invert mask
  1676.         not    ax
  1677.         mov    varendmaskl,ah
  1678.         mov    varendmaskr,al
  1679.         not    bh
  1680.         mov    varstartmask,bh
  1681.  
  1682.         mov    bx,var1pixelrowlen
  1683.  
  1684. ; set pixels row by row in the bit planes
  1685.  
  1686.         mov    ax,var1pixelrows
  1687. overl18:    push    ax
  1688.         push    di        ; offset of start of pixel row
  1689.         push    si        ; offset of row in bit block
  1690.         push    bx        ; bytes per pixel row
  1691.  
  1692.         mov    al,varstartmask ; mask first byte of row
  1693.         mov    screenmask,al
  1694.  
  1695.         lodsw            ; ah := 2nd byte of pixels
  1696.                     ; al := 1st byte of pixels
  1697.         dec    si        ; ds:si -> 2nd byte of pixels
  1698.         test    cl,cl
  1699.         jnz    overl19     ; jump if not left-aligned
  1700.  
  1701.         dec    bx        ; bx := bytes per row - 1
  1702.         jnz    overl20     ; jump if at least 2 bytes per row
  1703.         jmp    short overl22    ; jump if only one byte per row
  1704.  
  1705. overl19:    rol    ax,cl        ; ah := left part of 1st byte,
  1706.                     ;    right part of 2nd byte
  1707.  
  1708.         mov    dl,screenmask
  1709.         push    ax
  1710.         and    es:[di],dl
  1711.         not    dl
  1712.         and    ah,dl
  1713.         or    es:[di],ah    ; or pixels for left part of first byte
  1714.         pop    ax
  1715.  
  1716.         inc    di
  1717.         dec    bx        ; bx := bytes per row - 2
  1718.  
  1719. overl20:    ; set up bit mask for succeeding bytes
  1720.  
  1721.         mov    screenmask,0
  1722.  
  1723.         dec    bx
  1724.         jng    overl22     ; jump if only 1 or 2 bytes in pixel
  1725.  
  1726. ; set pixels in middle of row
  1727.  
  1728. overl21:    mov    dl,screenmask
  1729.         and    es:[di],dl    ; set pixels in right part of current
  1730.         not    dl
  1731.         and    al,dl
  1732.         or    es:[di],al    ; set pixels in right part of current
  1733.         inc    di        ; byte and left part of next byte
  1734.  
  1735.         lodsw            ; ah := next+1 byte of pixels
  1736.         dec    si        ; al := next byte of pixels
  1737.         rol    ax,cl        ; ah := left part of next byte, right
  1738.                     ;    part of next+1 byte
  1739.         dec    bx
  1740.         jnz    overl21     ; loop across pixel row
  1741.  
  1742. ; set pixels at end of row
  1743.  
  1744. overl22:    mov    bx,ax
  1745.         mov    al,varendmaskl
  1746.         and    es:[di],al
  1747.         not    al
  1748.         and    bl,al
  1749.         or    es:[di],bl
  1750.  
  1751.         mov    al,varendmaskr
  1752.         and    es:[di+1],al
  1753.         not    al
  1754.         and    bh,al
  1755.         or    es:[di+1],bh
  1756.  
  1757.         pop    bx
  1758.         pop    si
  1759.         add    si,bx
  1760.         pop    di
  1761.         add    di,var2pixelrowlen
  1762.  
  1763.         pop    ax
  1764.         dec    ax
  1765.         jnz    overl18
  1766.  
  1767. overlexit:    pop    di
  1768.         pop    es
  1769.         pop    si
  1770.         pop    ds
  1771.         ret
  1772. overlayimg    endp
  1773.  
  1774.  
  1775. extractpixs    proc    far argx0:word,argy0:word,addrbuff:dword
  1776.         local    varpixelrows : word, varpixelrowlen  : word
  1777.  
  1778.         push    ds
  1779.         push    si
  1780.         lds    si,addrbuff
  1781.  
  1782.         cld
  1783.         lodsw                ; varpixelrows
  1784.         mov    varpixelrows,ax
  1785.         lodsw                ; varpixelrows
  1786.         mov    varpixelrowlen,ax
  1787.         lodsb
  1788.  
  1789. ; establish addressing
  1790.         mov    ax,argy0
  1791.         mov    bx,argx0
  1792.         mov    cl,bl
  1793.  
  1794.         mov    dx,varpixelrowlen
  1795.         mul    dx            ; multiply rows by bytesperrow
  1796.  
  1797.         shr    bx,1            ; divide x coordinate by 8
  1798.         shr    bx,1
  1799.         shr    bx,1
  1800.         add    bx,ax            ; add to address
  1801.         add    si,bx
  1802.  
  1803.         and    cl,7            ; bits remainder
  1804.         xor    cl,7
  1805.  
  1806.         xor    ax,ax
  1807.  
  1808.         mov    al,ds:[si]
  1809.         shr    al,cl
  1810.         and    al,1
  1811.  
  1812.         pop    si
  1813.         pop    ds
  1814.         ret
  1815.  
  1816. extractpixs    endp
  1817.  
  1818.  
  1819. wrtchar     proc    far argc:word,argx:word,argy:word,argfgd:word,argbgd:word
  1820.         local    varshift:word,jaggy:word,transparent:byte,charshift:byte
  1821.         local    rmwb:word,bpline:word,bpchar:byte,lastbytemask:byte
  1822.         local    jaghold:byte
  1823.  
  1824.         push    ds
  1825.         push    si
  1826.         push    es
  1827.         push    di
  1828.  
  1829.         colorxlat argfgd
  1830.  
  1831. ; set up character definition table addressing
  1832.  
  1833.         lds    si,cs:TDtable
  1834.         les    di,ds:[si].fonttable
  1835.  
  1836.         mov    ax,argc     ; al := character code
  1837.         xor    ah,ah
  1838.         cmp    al,es:[di].FontAsciiStart
  1839.         jb    nowrtjmp
  1840.         cmp    al,es:[di].FontAsciiEnd
  1841.         jbe    okwrtjmp
  1842.  
  1843. nowrtjmp:    jmp    wrtcexit
  1844. okwrtjmp:
  1845.  
  1846.         mov    ax,ds:[si].rmwbits
  1847.         mov    rmwb,ax
  1848.  
  1849.         mov    ax,ds:[si].vbytesperline
  1850.         mov    bpline,ax
  1851.  
  1852.         mov    al,ds:[si].transparency
  1853.         mov    transparent,al
  1854.  
  1855.         xor    ax,ax
  1856.         mov    al,ds:[si].jagged
  1857.         and    al,1
  1858.         xchg    al,ah
  1859.         mov    jaggy,ax
  1860.  
  1861. ; calculate first pixel address
  1862.         push    es
  1863.  
  1864.         mov    ax,argy     ; ax := y
  1865.         mov    bx,argx     ; bx := x
  1866.         call    activeaddr    ; es:bx -> buffer
  1867.                     ; cl := # bits to shift left to mask
  1868.                     ;  pixel
  1869.         inc    cx
  1870.         and    cl,7        ; cl := # bits to shift to mask char
  1871.  
  1872.         mov    ch,0ffh
  1873.         shl    ch,cl        ; ch := bit mask for right side of char
  1874.         mov    varshift,cx
  1875.  
  1876.         push    es        ; transfer es to ds
  1877.         pop    ds
  1878.         mov    si,bx        ; si := video buffer offset
  1879.  
  1880. ; set up character definition table addressing
  1881.         pop    es
  1882.  
  1883.         xor    ax,ax
  1884.         mov    al,es:[di].FontHeight ;Multiply fontheight by fontwidth
  1885.         mov    cx,ax
  1886.  
  1887.         xor    bx,bx
  1888.         mov    bl,es:[di].fontbytewidth
  1889.         mov    bpchar,bl
  1890.         mul    bx
  1891.  
  1892.         mov    dx,argc     ; dl := character code
  1893.         sub    dl,es:[di].FontAsciiStart
  1894.         mul    dx        ; ax := offset into char def table
  1895.                     ;  (points * char code)
  1896.  
  1897.         add    di,255 + size TEGLFontInfo ;skip font table info
  1898.         add    di,ax        ; add character offset
  1899.  
  1900.  
  1901.         xor    bx,bx
  1902.         mov    bl,bpchar    ; bytes per character
  1903.         mov    al,byte ptr [argfgd] ; al := pixel value
  1904.  
  1905.         cmp    rmwb,80h
  1906.         jnz    oknot5
  1907.         not    al
  1908. oknot5:     mov    byte ptr [argfgd],al
  1909.  
  1910. ; select output routine depending on whether character is byte-aligned
  1911.  
  1912.         test    byte ptr [varshift],0ffh ; test # bits to shift
  1913.         jne    I20a        ; jump if character is not byte-aligned
  1914.  
  1915.  
  1916. ; routine for byte-aligned characters
  1917.  
  1918.         mov    dx,jaggy
  1919.         xchg    cl,dl
  1920. wrtcl10:    mov    ah,es:[di]    ; ah := pattern for next row of pixels
  1921.  
  1922.         shr    ah,cl        ; jaggies
  1923.  
  1924.         mov    al,ah
  1925.         and    al,byte ptr [argfgd]
  1926.  
  1927.         cmp    rmwb,18h    ; fgxor
  1928.         jz    wrt14a
  1929.         cmp    rmwb,10h    ; fgor
  1930.         jz    wrt14c
  1931.         test    rmwb,88h    ; fgand and fgnot
  1932.         jz    wrt14b
  1933.         and    al,ds:[si]
  1934.  
  1935. wrt14b:     not    ah
  1936.         and    ds:[si],ah    ; clear bit pixels
  1937.         not    ah
  1938. wrt14c:     or    ds:[si],al
  1939.  
  1940. wrt14e:     inc    di        ; es:di -> next byte in char def table
  1941.         inc    si
  1942.         dec    bl
  1943.         jnz    wrtcl10
  1944.  
  1945.         mov    bl,bpchar
  1946.         sub    si,bx
  1947.         add    si,nextinterleave ; increment to next line in video buffer
  1948.         jns    l20a
  1949.         add    si,firstinterleave ; increment from last to first interleave
  1950. l20a:
  1951.         xchg    cl,dh
  1952.         dec    dl
  1953.         jnz    wrtcl10
  1954.         jmp    short wrtcexit
  1955.  
  1956.  
  1957. wrt14a:     xor    ds:[si],al
  1958.         jmp    short wrt14e
  1959.  
  1960.  
  1961. wrt20a:     xor    ds:[si],dx
  1962.         jmp    short wrt20e
  1963.  
  1964. ; routine for non-byte-aligned characters
  1965.  
  1966. I20a:        mov    ch,cl        ; preserve loop counter
  1967. I20:        mov    cl,byte ptr varshift
  1968.                     ; ch := mask for left side of character
  1969.                     ; cl := # bits to shift left
  1970.  
  1971.         mov    al,es:[di]    ; al := bits for next row of pixels
  1972.         xor    ah,ah
  1973.         shl    ax,cl        ; ah := bits for left side of char
  1974.                     ; al := bits for right side of char
  1975.  
  1976.         mov    cl,byte ptr jaggy ; jaggies
  1977.         shr    ax,cl
  1978.  
  1979.         xchg    al,ah
  1980.         mov    dx,ax
  1981.         and    dl,byte ptr [argfgd]
  1982.         and    dh,byte ptr [argfgd]
  1983.  
  1984.         cmp    rmwb,18h    ; fgxor
  1985.         jz    wrt20a
  1986.         cmp    rmwb,10h    ; fgor
  1987.         jz    wrt20c
  1988.         test    rmwb,88h    ; fgand / fgnot
  1989.         jz    wrt20d
  1990.         and    dx,ds:[si]
  1991.  
  1992. wrt20d:     not    ax
  1993.         and    ds:[si],ax    ; clear bit pixels
  1994.         not    ax
  1995. wrt20c:     or    ds:[si],dx
  1996.  
  1997. wrt20e:     inc    di        ; es:di -> next byte in char def table
  1998.         inc    si
  1999.         dec    bl
  2000.         jnz    I20
  2001.  
  2002.         mov    bl,bpchar
  2003.         sub    si,bx
  2004.  
  2005.         add    si,nextinterleave ; increment to next line in video buffer
  2006.         jns    l20b
  2007.         add    si,firstinterleave ; increment from last to first interleave
  2008. l20b:
  2009.         mov    dx,jaggy
  2010.         xchg    dh,dl
  2011.         mov    jaggy,dx
  2012.         dec    ch
  2013.         jnz    I20
  2014.  
  2015. wrtcexit:
  2016.         pop    di
  2017.         pop    es
  2018.         pop    si
  2019.         pop    ds
  2020.  
  2021.         ret
  2022. wrtchar     endp
  2023.  
  2024.  
  2025. activeaddr    proc    near
  2026.  
  2027.         mov    cl,bl
  2028.  
  2029.         shr    ax,1            ; ax := y/2
  2030.         rcr    bx,1            ; bx := 8000h*(y&1)+x/2
  2031.         shr    ax,1            ; ax := y/4
  2032.         rcr    bx,1            ; bx := 4000h*(y&3)+x/4
  2033.         shr    bx,1            ; bx := 2000h*(y&3)+x/8
  2034.         mov    ah,90            ;<---constant bytesperline
  2035.         mul    ah
  2036.         add    bx,ax
  2037.  
  2038.         push    ds
  2039.         push    si
  2040.         lds    si,cs:TDtable
  2041.         mov    ax,ds:[si].activepage
  2042.         shr    ax,1
  2043.         shr    ax,1
  2044.         shr    ax,1
  2045.         shr    ax,1
  2046.         add    ax,0b000h
  2047.         mov    es,ax
  2048.         pop    si
  2049.         pop    ds
  2050.  
  2051.         and    cl,7
  2052.         xor    cl,7
  2053.         mov    ah,1
  2054.         ret
  2055.  
  2056. activeaddr    endp
  2057.  
  2058.  
  2059. mcursoroff    proc    far
  2060.         push    es
  2061.         push    di
  2062.         push    ds
  2063.         push    si
  2064.  
  2065. ; replace mouse cursor area
  2066.         test    cs:mflag,1
  2067.         jz    nomoff
  2068.  
  2069.         mov    cs:mflag,0
  2070.         les    di,dword ptr cs:scradrofs
  2071.         push    cs
  2072.         pop    ds
  2073.         mov    si,offset mcursorsavearea
  2074.         call    mputblock
  2075.  
  2076. nomoff:     pop    si        ; restore caller registers and return
  2077.         pop    ds
  2078.         pop    di
  2079.         pop    es
  2080.         ret
  2081. mcursoroff    endp
  2082.  
  2083.  
  2084. mcursoron    proc    far argx:word,argy:word
  2085.         local    varshift:word,wordmask:word,mscolor:byte
  2086.         push    es
  2087.         push    di
  2088.         push    ds
  2089.         push    si
  2090.  
  2091. ; save mouse cursor area
  2092.         lds    si,cs:TDtable
  2093.         mov    ax,ds:[si].mousecolor
  2094.         or    al,al
  2095.         jz    okcolor
  2096.         mov    al,0ffh
  2097. okcolor:    mov    mscolor,al
  2098.  
  2099.         mov    ax,argy     ; ax := y
  2100.         sub    ax,ds:[si].mousehotspot_yofs
  2101.         jnc    hotset1
  2102.         mov    ax,argy
  2103.  
  2104. hotset1:    mov    bx,argx     ; bx := x
  2105.         sub    bx,ds:[si].mousehotspot_xofs
  2106.         jnc    hotset2
  2107.         mov    bx,argx
  2108.  
  2109. hotset2:    call    hercvisualaddr    ; es:bx -> screen buffer
  2110.         inc    cx
  2111.         and    cl,7        ; cl := # bits to shift to mask char
  2112.         mov    ch,0ffh
  2113.         shl    ch,cl        ; ch := bit mask for right side of char
  2114.         mov    varshift,cx
  2115.  
  2116.         mov    cs:scradrseg,es
  2117.         mov    cs:scradrofs,bx
  2118.         mov    cs:mflag,1     ; mouse cursor on
  2119.  
  2120.         push    es
  2121.         push    ds
  2122.         pop    es
  2123.         pop    ds
  2124.  
  2125.         mov    si,bx
  2126.         mov    di,offset mcursorsavearea
  2127.         call    mgetblock
  2128.  
  2129.  
  2130. ; set up mouse cursor table addressing
  2131.  
  2132.         les    di,cs:TDtable
  2133.         les    di,es:[di].mousemask
  2134.         mov    cx,16        ; number of pixel rows in cursor
  2135.  
  2136. ; set up graphics controller registers
  2137. ; select output routine depending on whether character is byte-aligned
  2138.  
  2139.         test    byte ptr [varshift],0ffh ; test # bits to shift
  2140.         jne    mcl20        ; jump if character is not byte-aligned
  2141.  
  2142.  
  2143. ; routine for byte-aligned characters
  2144. l10:        mov    ax,es:[di]         ; mouse mask
  2145.         and    byte ptr [si],ah     ; ah := bits for left side of char
  2146.         and    byte ptr [si+1],al   ; al := bits for right side of char
  2147.  
  2148.         mov    bl,mscolor
  2149.         mov    ax,es:[di+32]
  2150.         and    al,bl             ;sets it to black or white
  2151.         and    ah,bl
  2152.         or    byte ptr [si],ah
  2153.         or    byte ptr [si+1],al
  2154.  
  2155.         inc    di
  2156.         inc    di
  2157.  
  2158.         add    si,nextinterleave
  2159.         jns    l10a
  2160.         add    si,firstinterleave
  2161.  
  2162. l10a:        loop    l10
  2163.         jmp    short lexit
  2164.  
  2165.  
  2166. ; routine for non-byte-aligned characters
  2167. mcl20:        push    cx        ; preserve loop counter
  2168.         mov    cx,varshift    ; ch := mask for left side of character
  2169.                     ; cl := # bits to shift left
  2170. ; left side of mask
  2171.         mov    ax,es:[di]
  2172.         push    ax
  2173.  
  2174.         mov    al,ah
  2175.         mov    ah,0ffh
  2176.         rol    ax,cl        ; ah := bits for left side of char
  2177.                     ; al := bits for right side of char
  2178.  
  2179.         and    byte ptr [si],ah
  2180.         and    byte ptr [si+1],al
  2181.  
  2182.         pop    ax
  2183.         mov    ah,0ffh
  2184.         rol    ax,cl        ; ah := bits for left side of char
  2185.                     ; al := bits for right side of char
  2186.         and    byte ptr [si+1],ah
  2187.         and    byte ptr [si+2],al
  2188.  
  2189.  
  2190. ; colorize
  2191.         mov    bl,mscolor
  2192.         mov    ax,es:[di+32]
  2193.         and    al,bl             ;sets it to black or white
  2194.         and    ah,bl
  2195.  
  2196.         push    ax
  2197.         mov    al,ah
  2198.         xor    ah,ah
  2199.         shl    ax,cl        ; ah := bits for left side of char
  2200.                     ; al := bits for right side of char
  2201.         or    byte ptr [si],ah
  2202.         or    byte ptr [si+1],al
  2203.  
  2204.         pop    ax
  2205.         xor    ah,ah
  2206.         shl    ax,cl        ; ah := bits for left side of char
  2207.                     ; al := bits for right side of char
  2208.         or    byte ptr [si+1],ah
  2209.         or    byte ptr [si+2],al
  2210.  
  2211. ; increment to next row of pixels in character
  2212.         inc    di
  2213.         inc    di
  2214.  
  2215.         add    si,nextinterleave  ; ds:si -> next line in video buffer
  2216.         jns    mcl20a
  2217.         add    si,firstinterleave
  2218. mcl20a:
  2219.         pop    cx
  2220.         loop    mcl20
  2221.  
  2222.  
  2223. lexit:        pop    si        ; restore caller registers and return
  2224.         pop    ds
  2225.         pop    di
  2226.         pop    es
  2227.         ret
  2228. mcursoron    endp
  2229.  
  2230.  
  2231. msetpos     proc    far argx:word,argy:word
  2232.  
  2233.         test    cs:mflag,1
  2234.         jz    nomset
  2235.  
  2236.         call    mcursoroff
  2237.  
  2238.         mov    ax,argx
  2239.         push    ax
  2240.         mov    ax,argy
  2241.         push    ax
  2242.         call    mcursoron
  2243.  
  2244. nomset:     ret
  2245. msetpos     endp
  2246.  
  2247.  
  2248. ; assume ds:si=addrbuf    es:di=screenadr
  2249. mputblock    proc    near
  2250.         cld
  2251.         push    si
  2252.         push    di
  2253.  
  2254.         mov    cx,16
  2255. hcputbl10:    push    di
  2256.         movsw
  2257.         movsb
  2258.         pop    di
  2259.  
  2260.         add    di,nextinterleave
  2261.         jns    bl10a
  2262.         add    di,firstinterleave
  2263. bl10a:
  2264.         loop    hcputbl10
  2265.  
  2266.         pop    di
  2267.         pop    si
  2268.         ret
  2269. mputblock    endp
  2270.  
  2271.  
  2272. ; assume es:di=addrbuf    ds:si=screenadr
  2273. mgetblock    proc    near
  2274.         cld
  2275.         push    si
  2276.         push    di
  2277.  
  2278.         mov    cx,16
  2279. getbl01:    push    si
  2280.         movsw
  2281.         movsb
  2282.         pop    si
  2283.  
  2284.         add    si,nextinterleave  ; ds:si -> next line in video buffer
  2285.         jns    bl01a
  2286.         add    si,firstinterleave
  2287. bl01a:
  2288.         loop    getbl01
  2289.  
  2290.         pop    di
  2291.         pop    si
  2292.         ret
  2293. mgetblock    endp
  2294.  
  2295.  
  2296. hercvisualaddr    proc    near
  2297.  
  2298.         mov    cl,bl
  2299.  
  2300.         shr    ax,1            ; ax := y/2
  2301.         rcr    bx,1            ; bx := 8000h*(y&1)+x/2
  2302.         shr    ax,1            ; ax := y/4
  2303.         rcr    bx,1            ; bx := 4000h*(y&3)+x/4
  2304.         shr    bx,1            ; bx := 2000h*(y&3)+x/8
  2305.         mov    ah,90            ;<----constant bytesperline
  2306.         mul    ah
  2307.         add    bx,ax
  2308.  
  2309.         push    ds
  2310.         mov    ax,40h            ;determine page
  2311.         mov    ds,ax
  2312.         mov    ax,ds:[4eh]
  2313.         shr    ax,1
  2314.         shr    ax,1
  2315.         shr    ax,1
  2316.         shr    ax,1
  2317.         add    ax,0b000h
  2318.         mov    es,ax
  2319.         pop    ds
  2320.  
  2321.         and    cl,7
  2322.         xor    cl,7
  2323.         mov    ah,1
  2324.         ret
  2325.  
  2326. hercvisualaddr    endp
  2327.  
  2328.  
  2329. incnextline    macro    cofs
  2330.         local    cofsjmp
  2331.  
  2332.         add    cofs,nextinterleave
  2333.         jns    cofsjmp
  2334.         add    cofs,firstinterleave
  2335. cofsjmp:
  2336.         endm
  2337.  
  2338.  
  2339. decnextline    macro    cofs
  2340.         local    cofsjmp
  2341.  
  2342.         sub    cofs,nextinterleave
  2343.         jae    cofsjmp
  2344.         sub    cofs,firstinterleave
  2345. cofsjmp:
  2346.         endm
  2347.  
  2348.  
  2349. movevideopixels proc    far argx0:word,argy0:word,argx1:word,argy1:word,argx2:word,argy2:word,vertlines:word,horzlines:word,spage:dword,tpage:dword
  2350.         local    bpline:word,varpixelrows:word,varpixelrowlen:word
  2351.         local    varstartmask:byte,varendmaskl:byte,varendmaskr:byte
  2352.         local    sourcescr:dword,sourceshft:byte,lastbytemask:byte
  2353.         local    targetscr:dword,targetshft:byte,workbuffer:dword
  2354.         local    varpixelcontlen:word
  2355.  
  2356.         push    ds
  2357.         push    es
  2358.         push    si
  2359.         push    di
  2360.  
  2361. ;-----------------------------------------------
  2362.         cld
  2363.  
  2364.         lds    si,cs:TDtable
  2365.         mov    ax,ds:[si].vbytesperline
  2366.         mov    bpline,ax
  2367.  
  2368.         les    di,ds:[si].vgraphbuffer
  2369.         mov    word ptr [workbuffer],di
  2370.         mov    word ptr [workbuffer+2],es
  2371.  
  2372.  
  2373. ;-----------------------------------------------
  2374.         mov    ax,horzlines
  2375.         or    ax,ax
  2376.         jz    noadj_89
  2377.         mov    ax,horzlines
  2378.         test    ah,80h
  2379.         jz    notneg1     ;scroll left?    ;   +-+--------+
  2380.                             ;   | <<<< -1  |
  2381.                             ;   +-+--------+
  2382.         mov    bx,argx0
  2383.         sub    bx,ax
  2384.         mov    argx0,bx
  2385.         jmp    short noadj_89
  2386.  
  2387. notneg1:    mov    bx,argx2    ;scroll right?    ;   +--------+-+
  2388.         add    bx,ax                ;   | 1   >>>> |
  2389.         mov    argx2,bx            ;   +--------+-+
  2390.  
  2391.         mov    bx,argx1
  2392.         sub    bx,ax
  2393.         mov    argx1,bx
  2394.  
  2395. noadj_89:
  2396.  
  2397.         mov    al,byte ptr [argx0]
  2398.         mov    ah,byte ptr [argx2]
  2399.         and    ax,0707h
  2400.         cmp    ah,al
  2401.         jne    movevideobits
  2402.         jmp    movevideobytes
  2403.  
  2404. ;-----------------------------------------------
  2405. movevideobits:    mov    ax,argx1
  2406.         sub    ax,argx0
  2407.         mov    cx,0ff07h
  2408.         and    cl,al
  2409.         xor    cl,7
  2410.         shl    ch,cl        ;last byte mask in ch
  2411.         mov    lastbytemask,ch
  2412.  
  2413.         shr    ax,1        ;number of bytes to mov
  2414.         shr    ax,1
  2415.         shr    ax,1
  2416.         inc    ax
  2417.         mov    varpixelrowlen,ax
  2418.  
  2419.         mov    ax,argy1    ;number of lines
  2420.         sub    ax,argy0    ;number of lines
  2421.         inc    ax
  2422.  
  2423. ;-----------------------------------------------
  2424. ; extablish addressing
  2425.         test    vertlines,8000h
  2426.         jnz    bottomupmove
  2427.  
  2428.         sub    ax,vertlines
  2429.         mov    varpixelrows,ax
  2430.  
  2431.         mov    ax,argy0    ;source     ;   +----------+
  2432.         add    ax,vertlines            ;   +----/\----+
  2433.         mov    si,argx0            ;   |           |
  2434.                             ;   |           |
  2435.                             ;   +----------+
  2436.         mov    cx,si
  2437.         and    cl,7
  2438.         mov    sourceshft,cl
  2439.  
  2440.         shr    ax,1            ; ax := y/2
  2441.         rcr    si,1            ; bx := 8000h*(y&1)+x/2
  2442.         shr    ax,1            ; ax := y/4
  2443.         rcr    si,1            ; bx := 4000h*(y&3)+x/4
  2444.         shr    si,1            ; bx := 2000h*(y&3)+x/8
  2445.         mov    ah,90            ;<---constant bytesperline
  2446.         mul    ah
  2447.         add    si,ax
  2448.  
  2449.         mov    ax,word ptr [spage]
  2450.         and    ax,000fh
  2451.         add    si,ax
  2452.  
  2453.         mov    ax,word ptr [spage]
  2454.         shr    ax,1
  2455.         shr    ax,1
  2456.         shr    ax,1
  2457.         shr    ax,1
  2458.         add    ax,word ptr [spage+2]
  2459.         mov    ds,ax
  2460.  
  2461. ;-------
  2462.  
  2463.         mov    ax,argy2    ;target
  2464.         mov    di,argx2
  2465.  
  2466.         mov    cx,di
  2467.         xor    cl,7
  2468.         inc    cl
  2469.         and    cl,7
  2470.         mov    targetshft,cl
  2471.  
  2472.         shr    ax,1            ; ax := y/2
  2473.         rcr    di,1            ; bx := 8000h*(y&1)+x/2
  2474.         shr    ax,1            ; ax := y/4
  2475.         rcr    di,1            ; bx := 4000h*(y&3)+x/4
  2476.         shr    di,1            ; bx := 2000h*(y&3)+x/8
  2477.         mov    ah,90            ;<---constant bytesperline
  2478.         mul    ah
  2479.         add    di,ax
  2480.  
  2481.         mov    ax,word ptr [tpage]
  2482.         and    ax,000fh
  2483.         add    di,ax
  2484.  
  2485.         mov    ax,word ptr [tpage]
  2486.         shr    ax,1
  2487.         shr    ax,1
  2488.         shr    ax,1
  2489.         shr    ax,1
  2490.         add    ax,word ptr [tpage+2]
  2491.         mov    es,ax
  2492.  
  2493.         jmp    movevideobl_23
  2494.  
  2495. bottomupmove:    add    ax,vertlines
  2496.         mov    varpixelrows,ax
  2497.  
  2498.         mov    ax,argy0    ;source     ;   +----------+
  2499.         add    ax,varpixelrows         ;   |           |
  2500.         dec    ax                ;   |           |
  2501.         mov    si,argx0            ;   +----\/----+
  2502.                             ;   +----------+
  2503.         mov    cx,si
  2504.         and    cl,7
  2505.         mov    sourceshft,cl
  2506.  
  2507.         shr    ax,1            ; ax := y/2
  2508.         rcr    si,1            ; bx := 8000h*(y&1)+x/2
  2509.         shr    ax,1            ; ax := y/4
  2510.         rcr    si,1            ; bx := 4000h*(y&3)+x/4
  2511.         shr    si,1            ; bx := 2000h*(y&3)+x/8
  2512.         mov    ah,90            ;<---constant bytesperline
  2513.         mul    ah
  2514.         add    si,ax
  2515.  
  2516.         mov    ax,word ptr [spage]
  2517.         and    ax,000fh
  2518.         add    si,ax
  2519.  
  2520.         mov    ax,word ptr [spage]
  2521.         shr    ax,1
  2522.         shr    ax,1
  2523.         shr    ax,1
  2524.         shr    ax,1
  2525.         add    ax,word ptr [spage+2]
  2526.         mov    ds,ax
  2527.  
  2528.  
  2529.         mov    ax,argy1
  2530.         sub    ax,argy0
  2531.         add    ax,argy2
  2532.         mov    di,argx2    ;target
  2533.  
  2534.         mov    cx,di
  2535.         xor    cl,7
  2536.         inc    cl
  2537.         and    cl,7
  2538.         mov    targetshft,cl
  2539.  
  2540.         shr    ax,1            ; ax := y/2
  2541.         rcr    di,1            ; bx := 8000h*(y&1)+x/2
  2542.         shr    ax,1            ; ax := y/4
  2543.         rcr    di,1            ; bx := 4000h*(y&3)+x/4
  2544.         shr    di,1            ; bx := 2000h*(y&3)+x/8
  2545.         mov    ah,90            ;<---constant bytesperline
  2546.         mul    ah
  2547.         add    di,ax
  2548.  
  2549.         mov    ax,word ptr [tpage]
  2550.         and    ax,000fh
  2551.         add    di,ax
  2552.  
  2553.         mov    ax,word ptr [tpage]
  2554.         shr    ax,1
  2555.         shr    ax,1
  2556.         shr    ax,1
  2557.         shr    ax,1
  2558.         add    ax,word ptr [tpage+2]
  2559.         mov    es,ax
  2560.  
  2561.         xor    ax,ax
  2562.         sub    ax,bpline        ; negate bpline
  2563.         mov    bpline,ax
  2564.  
  2565. ;-----------------------------------------------
  2566. movevideobl_23:
  2567.         mov    word ptr [sourcescr],si
  2568.         mov    word ptr [sourcescr+2],ds
  2569.         mov    word ptr [targetscr],di
  2570.         mov    word ptr [targetscr+2],es
  2571.  
  2572.         mov    cl,targetshft
  2573.         mov    ch,lastbytemask
  2574.         mov    bx,0ffh     ; bx = 00000000 11111111
  2575.         mov    al,ch        ; al = 11110000
  2576.         cbw            ; ax = 11111111 11110000
  2577.  
  2578.         cmp    varpixelrowlen,1 ;if only 1 byte to move then
  2579.         jne    movevideobl_16
  2580.  
  2581.                     ; create start and end mask based
  2582.                     ; on one byte
  2583.         mov    bl,ch        ; bx = 00000000 11110000
  2584.         mov    ah,ch        ;
  2585.         xor    al,al        ; ax = 11110000 00000000
  2586.  
  2587. movevideobl_16: shl    ax,cl
  2588.         shl    bx,cl
  2589.  
  2590.         mov    varendmaskl,ah    ; ah=endmask left
  2591.         mov    varendmaskr,al    ; al=endmask right
  2592.         mov    varstartmask,bh ; bh=startmask
  2593.  
  2594.  
  2595. ;-----------------------------------------------
  2596. ;----move from screen to buffer
  2597. movevideobl_01: lds    si,sourcescr
  2598.         les    di,workbuffer
  2599.  
  2600.         mov    bx,varpixelrowlen
  2601.         mov    cl,sourceshft
  2602.  
  2603.         or    cl,cl        ; bit shifts?
  2604.         jz    mvetobuf_06
  2605.  
  2606.         ; routine for non-aligned bit blocks
  2607. mvetobuf_04:    lodsw
  2608.         dec    si
  2609.         rol    ax,cl
  2610.         stosb
  2611.         dec    bx
  2612.         jnz    mvetobuf_04
  2613.         jmp    short mvetoscr_09
  2614.  
  2615.         ; routine for byte-aligned bit blocks
  2616. mvetobuf_06:    mov    cx,bx
  2617.  
  2618.         shr    cx,1
  2619.         rep    movsw
  2620.         adc    cx,0
  2621.         rep    movsb
  2622.  
  2623. ;----move from buffer to screen
  2624. mvetoscr_09:    lds    si,workbuffer
  2625.         les    di,targetscr
  2626.  
  2627.         mov    bx,varpixelrowlen
  2628.         mov    ch,lastbytemask
  2629.         mov    cl,targetshft
  2630.  
  2631.         cmp    cx,0ff00h    ; start and end must be byte aligned
  2632.         jne    mvetoscr_17
  2633.  
  2634.         ; routine for byte-aligned bit blocks
  2635.         mov    cx,bx
  2636.  
  2637.         shr    cx,1
  2638.         rep    movsw
  2639.         adc    cx,0
  2640.         rep    movsb
  2641.  
  2642.         ; routine for non-aligned bit blocks
  2643. mvetoscr_17:
  2644.         lodsw                ; eg. 10101110 11111111
  2645.         dec    si            ;      <junk>    8 bits
  2646.         or    cl,cl            ; shift?
  2647.         jnz    mvetoscr_shf        ; go shift
  2648.  
  2649.         dec    bx            ; no shift, just dec bx
  2650.         jnz    mvetoscr_mid        ; more bytes
  2651.         jmp    short mvetoscr_end    ; do end bytes
  2652.  
  2653. mvetoscr_shf:    rol    ax,cl            ; eg. 01110111 11111101
  2654.         mov    dl,varstartmask
  2655.         and    ah,dl
  2656.         not    dl
  2657.         and    es:[di],dl        ; and screen 11111000
  2658.         or    es:[di],ah        ; or  screen 00000111
  2659.         inc    di
  2660.         dec    bx            ; bx = 0
  2661.  
  2662. mvetoscr_mid:    dec    bx            ; bx < 0
  2663.         jng    mvetoscr_end
  2664.  
  2665. mvetoscr_loop:    mov    es:[di],al
  2666.         inc    di
  2667.         lodsw
  2668.         dec    si
  2669.         rol    ax,cl
  2670.         dec    bx
  2671.         jnz    mvetoscr_loop
  2672.  
  2673.         ; set pixels at end of row
  2674. mvetoscr_end:    mov    dl,varendmaskl
  2675.         and    al,dl
  2676.         not    dl
  2677.         and    es:[di],dl
  2678.         or    es:[di],al
  2679.         inc    di
  2680.  
  2681.         mov    dl,varendmaskr        ; eg. 00000000
  2682.         and    ah,dl
  2683.         not    dl
  2684.         and    es:[di],dl
  2685.         or    es:[di],ah
  2686. ;-----------------------------------------------------move buffer to screen
  2687.  
  2688. mvetoscr_20:    test    byte ptr [bpline+1],80h
  2689.         jnz    mvetoscr_20a
  2690.  
  2691.         incnextline <word ptr [targetscr]>
  2692.         incnextline <word ptr [sourcescr]>
  2693.  
  2694.         dec    varpixelrows
  2695.         jz    movevideobl_02
  2696.         jmp    movevideobl_01
  2697. movevideobl_02: jmp    vertmove_12
  2698.  
  2699.  
  2700. mvetoscr_20a:    decnextline <word ptr [targetscr]>
  2701.         decnextline <word ptr [sourcescr]>
  2702.  
  2703.         dec    varpixelrows
  2704.         jz    movevideobl_02
  2705.         jmp    movevideobl_01
  2706.  
  2707.  
  2708. ; movevideobytes allows for direct latch block moves of pixel lines, rather
  2709. ; than having to (move and shift) a block of pixels to memory and back.
  2710.  
  2711. movevideobytes: mov    ax,argx1
  2712.         mov    cx,0ff07h
  2713.         and    cl,al
  2714.         xor    cl,7
  2715.         shl    ch,cl        ;mask for last byte
  2716.         mov    varendmaskl,ch
  2717.         push    cx
  2718.  
  2719.         mov    bx,argx0
  2720.         mov    cx,0ff07h
  2721.         and    cl,bl
  2722.         shr    ch,cl        ;mask for start byte
  2723.         mov    varstartmask,ch
  2724.  
  2725.         pop    cx
  2726.         shr    bx,1        ;number of bytes to mov
  2727.         shr    bx,1
  2728.         shr    bx,1
  2729.         shr    ax,1
  2730.         shr    ax,1
  2731.         shr    ax,1
  2732.         sub    ax,bx
  2733.         shl    ch,1
  2734.         adc    ax,0        ;1 byte   - start and end bytes same
  2735.                     ;2 bytes  - start and end bytes
  2736.                     ;>2 bytes - start, mid, end bytes
  2737.         mov    varpixelrowlen,ax
  2738.  
  2739.         cmp    ax,1        ;if 1 byte then
  2740.         jne    vertmove_01
  2741.         mov    al,varstartmask
  2742.         and    al,varendmaskl    ;combine both mask together
  2743.         mov    varstartmask,al
  2744.         mov    varendmaskl,0
  2745.  
  2746. vertmove_01:    mov    ah,varstartmask
  2747.         xor    ah,0ffh
  2748.         jnz    vertmove_07
  2749.         mov    varstartmask,ah
  2750. vertmove_07:    mov    ah,varendmaskl
  2751.         xor    ah,0ffh
  2752.         jnz    vertmove_08
  2753.         mov    varendmaskl,ah
  2754. vertmove_08:
  2755.         mov    ax,argy1    ;number of lines
  2756.         sub    ax,argy0
  2757.         inc    ax
  2758.  
  2759. ;-----------------------------------------------
  2760. ; extablish addressing
  2761.         test    vertlines,8000h
  2762.         jnz    vertmove_00
  2763.  
  2764.         sub    ax,vertlines    ;subtract number of lines to scroll
  2765.         mov    varpixelrows,ax
  2766.  
  2767.         mov    ax,argy0    ;source     ;   +----------+
  2768.         add    ax,vertlines            ;   +----/\----+
  2769.         mov    si,argx0            ;   |           |
  2770.                             ;   |           |
  2771.                             ;   +----------+
  2772.  
  2773.         shr    ax,1            ; ax := y/2
  2774.         rcr    si,1            ; bx := 8000h*(y&1)+x/2
  2775.         shr    ax,1            ; ax := y/4
  2776.         rcr    si,1            ; bx := 4000h*(y&3)+x/4
  2777.         shr    si,1            ; bx := 2000h*(y&3)+x/8
  2778.         mov    ah,90            ;<---constant bytesperline
  2779.         mul    ah
  2780.         add    si,ax
  2781.  
  2782.         mov    ax,word ptr [spage]
  2783.         and    ax,000fh
  2784.         add    si,ax
  2785.  
  2786.         mov    ax,word ptr [spage]
  2787.         shr    ax,1
  2788.         shr    ax,1
  2789.         shr    ax,1
  2790.         shr    ax,1
  2791.         add    ax,word ptr [spage+2]
  2792.         mov    ds,ax
  2793.  
  2794.  
  2795.         mov    ax,argy2    ;target
  2796.         mov    di,argx2
  2797.  
  2798.         shr    ax,1            ; ax := y/2
  2799.         rcr    di,1            ; bx := 8000h*(y&1)+x/2
  2800.         shr    ax,1            ; ax := y/4
  2801.         rcr    di,1            ; bx := 4000h*(y&3)+x/4
  2802.         shr    di,1            ; bx := 2000h*(y&3)+x/8
  2803.         mov    ah,90            ;<---constant bytesperline
  2804.         mul    ah
  2805.         add    di,ax
  2806.  
  2807.         mov    ax,word ptr [tpage]
  2808.         and    ax,000fh
  2809.         add    di,ax
  2810.  
  2811.         mov    ax,word ptr [tpage]
  2812.         shr    ax,1
  2813.         shr    ax,1
  2814.         shr    ax,1
  2815.         shr    ax,1
  2816.         add    ax,word ptr [tpage+2]
  2817.         mov    es,ax
  2818.  
  2819.         mov    bx,bpline
  2820.         sub    bx,varpixelrowlen
  2821.         mov    varpixelcontlen,bx
  2822.  
  2823.         jmp    short vertmove_31
  2824.  
  2825.  
  2826. vertmove_00:    add    ax,vertlines    ;subtract number of lines to scroll
  2827.         mov    varpixelrows,ax
  2828.  
  2829.         mov    ax,argy0    ;source     ;   +----------+
  2830.         add    ax,varpixelrows         ;   |           |
  2831.         dec    ax                ;   |           |
  2832.         mov    si,argx0            ;   +----\/----+
  2833.                             ;   +----------+
  2834.  
  2835.         shr    ax,1            ; ax := y/2
  2836.         rcr    si,1            ; bx := 8000h*(y&1)+x/2
  2837.         shr    ax,1            ; ax := y/4
  2838.         rcr    si,1            ; bx := 4000h*(y&3)+x/4
  2839.         shr    si,1            ; bx := 2000h*(y&3)+x/8
  2840.         mov    ah,90            ;<---constant bytesperline
  2841.         mul    ah
  2842.         add    si,ax
  2843.  
  2844.         mov    ax,word ptr [spage]
  2845.         and    ax,000fh
  2846.         add    si,ax
  2847.  
  2848.         mov    ax,word ptr [spage]
  2849.         shr    ax,1
  2850.         shr    ax,1
  2851.         shr    ax,1
  2852.         shr    ax,1
  2853.         add    ax,word ptr [spage+2]
  2854.         mov    ds,ax
  2855.  
  2856.  
  2857.         mov    ax,argy1
  2858.         sub    ax,argy0
  2859.         add    ax,argy2
  2860.         mov    di,argx2    ;target
  2861.  
  2862.         shr    ax,1            ; ax := y/2
  2863.         rcr    di,1            ; bx := 8000h*(y&1)+x/2
  2864.         shr    ax,1            ; ax := y/4
  2865.         rcr    di,1            ; bx := 4000h*(y&3)+x/4
  2866.         shr    di,1            ; bx := 2000h*(y&3)+x/8
  2867.         mov    ah,90            ;<---constant bytesperline
  2868.         mul    ah
  2869.         add    di,ax
  2870.  
  2871.         mov    ax,word ptr [tpage]
  2872.         and    ax,000fh
  2873.         add    di,ax
  2874.  
  2875.         mov    ax,word ptr [tpage]
  2876.         shr    ax,1
  2877.         shr    ax,1
  2878.         shr    ax,1
  2879.         shr    ax,1
  2880.         add    ax,word ptr [tpage+2]
  2881.         mov    es,ax
  2882.  
  2883.         mov    ax,bpline
  2884.         not    ax
  2885.         inc    ax
  2886.         sub    ax,varpixelrowlen
  2887.         mov    varpixelcontlen,ax
  2888.  
  2889. ;-----------------------------------------------
  2890. vertmove_31:
  2891.         mov    word ptr [sourcescr],si
  2892.         mov    word ptr [sourcescr+2],ds
  2893.         mov    word ptr [targetscr],di
  2894.         mov    word ptr [targetscr+2],es
  2895.  
  2896.         ; check if we need to move backwards
  2897.  
  2898.         mov    ax,argy0
  2899.         cmp    ax,argy2        ;compare vertical y's
  2900.         jne    vertmove_02        ;jump if not same line
  2901.  
  2902.         mov    ax,word ptr [spage]    ;compare base video segs
  2903.         cmp    ax,word ptr [tpage]
  2904.         jne    vertmove_02        ;jump if different pages
  2905.  
  2906.         mov    ax,word ptr [spage+2]    ;compare base video segs
  2907.         cmp    ax,word ptr [tpage+2]
  2908.         jne    vertmove_02        ;jump if different pages
  2909.  
  2910.         mov    ax,argx0        ;compare end and start segments
  2911.         cmp    ax,argx2
  2912.         jge    vertmove_02        ;jump if tail < begining
  2913.  
  2914.         std
  2915.         mov    ax,varpixelrowlen
  2916.         dec    ax
  2917.         add    si,ax
  2918.         add    di,ax
  2919.         inc    ax
  2920.  
  2921.         add    ax,bpline
  2922.         mov    varpixelcontlen,ax
  2923.         jmp    vertmove_20
  2924.  
  2925. vertmove_02:   mov     cx,varpixelrowlen
  2926.            lds     si,sourcescr
  2927.            les     di,targetscr
  2928.  
  2929.         mov    ah,varstartmask  ; ah := 0ffh (value for bit mask reg)
  2930.         or    ah,ah
  2931.         jz    vertmove_09
  2932.  
  2933. vertmove_03:
  2934.         mov    dh,varstartmask
  2935.         mov    dl,ds:[si]    ; get start byte
  2936.         and    dl,dh
  2937.         not    dh
  2938.         and    es:[di],dh    ; latch destination bytes
  2939.         or    es:[di],dl    ; mask new info
  2940.  
  2941.         shr    bh,1
  2942.         dec    ah
  2943.         jns    vertmove_03
  2944.  
  2945.         dec    cx        ; 1 byte   - start and end bytes same
  2946.         jcxz    vertmove_06    ; 2 bytes  - start and end bytes
  2947.                     ;>2 bytes  - start, mid, end bytes
  2948.         inc    si
  2949.         inc    di
  2950.  
  2951. vertmove_09:    test    varendmaskl,0ffh
  2952.         jz    vertmove_10
  2953.         dec    cx
  2954. vertmove_10:    jcxz    vertmove_04    ;do end part of scroll
  2955.  
  2956. ; middle part of direct memory scroll
  2957.         shr    cx,1
  2958.         rep    movsw
  2959.         adc    cx,0
  2960.         rep    movsb
  2961.  
  2962. ; end part of direct memory scroll
  2963. vertmove_04:    mov    dh,varendmaskl    ; ah := 0ffh (value for bit mask reg)
  2964.         or    dh,dh
  2965.         jz    vertmove_06
  2966.  
  2967.         mov    dl,ds:[si]    ; get end byte
  2968.         and    dl,dh
  2969.         not    dh
  2970.         and    es:[di],dh    ; mask new info
  2971.         or    es:[di],dl
  2972.  
  2973. vertmove_06:
  2974.         test    byte ptr [varpixelcontlen+1],80h
  2975.         jnz    vertmove_12_S
  2976.  
  2977.         incnextline <word ptr [targetscr]>
  2978.         incnextline <word ptr [sourcescr]>
  2979.  
  2980.         dec    varpixelrows
  2981.         jz    vertmove_12_F
  2982.         jmp    vertmove_02
  2983. vertmove_12_F:    jmp    vertmove_12
  2984.  
  2985.  
  2986. vertmove_12_S:
  2987.         decnextline <word ptr [targetscr]>
  2988.         decnextline <word ptr [sourcescr]>
  2989.  
  2990.         dec    varpixelrows
  2991.         jz    vertmove_12_F
  2992.         jmp    vertmove_02
  2993.  
  2994. ;-----------------------------------------------
  2995. vertmove_20:    mov    cx,varpixelrowlen
  2996.         lds    si,sourcescr
  2997.         les    di,targetscr
  2998.  
  2999.         mov    al,varendmaskl    ; ah := 0ffh (value for bit mask reg)
  3000.         or    al,al
  3001.         jz    vertmove_21
  3002.  
  3003. vertmove_22:    mov    dl,ds:[si]    ; get start byte
  3004.         and    dl,al
  3005.         not    al
  3006.         and    es:[di],al
  3007.         or    es:[di],dl    ; mask new info
  3008.  
  3009.         dec    cx        ; 1 byte   - start and end bytes same
  3010.         jcxz    vertmove_23    ; 2 bytes  - start and end bytes
  3011.                     ;>2 bytes  - start, mid, end bytes
  3012.  
  3013.         dec    si
  3014.         dec    di
  3015.  
  3016. vertmove_21:    test    varstartmask,0ffh
  3017.         jz    vertmove_24
  3018.         dec    cx
  3019. vertmove_24:    jcxz    vertmove_25    ;do begining part of scroll
  3020.  
  3021. ; middle part of direct memory scroll
  3022.  
  3023.         shr    cx,1
  3024.         rep    movsw
  3025.         adc    cx,0
  3026.         rep    movsb
  3027.  
  3028. ; end part of direct memory scroll
  3029. vertmove_25:
  3030.         mov    al,varstartmask ; ah := 0ffh (value for bit mask reg)
  3031.         test    al,0ffh
  3032.         jz    vertmove_23
  3033.  
  3034. vertmove_26:
  3035.         mov    dl,ds:[si]    ; get start byte
  3036.         and    dl,al
  3037.         not    al
  3038.         and    es:[di],al
  3039.         or    es:[di],dl    ; mask new info
  3040.  
  3041.  
  3042. vertmove_23:
  3043.         decnextline <word ptr [targetscr]>
  3044.         decnextline <word ptr [sourcescr]>
  3045.  
  3046.         dec    varpixelrows
  3047.         jnz    vertmove_20
  3048.  
  3049.  
  3050. vertmove_12:
  3051.         cld
  3052.         pop    di
  3053.         pop    si
  3054.         pop    es
  3055.         pop    ds
  3056.         ret
  3057.  
  3058. movevideopixels endp
  3059.  
  3060. setvpage    proc    far pagen:word
  3061.         push    ds
  3062.         push    si
  3063.         push    es
  3064.         push    di
  3065.  
  3066.         lds    si,cs:TDtable
  3067.         mov    ax,pagen
  3068.         cmp    ax,ds:[si].vmaxpages
  3069.  
  3070.         mov    bx,40h
  3071.         mov    ds,bx
  3072.         mov    si,62h
  3073.         mov    ds:[si],al
  3074.         mov    si,4eh
  3075.  
  3076.         mov    dx,03B8h
  3077.         xor    bx,bx
  3078.         or    al,al
  3079.         mov    al,0ah
  3080.         jz    vpageit
  3081.  
  3082.         mov    bx,8000h
  3083.         mov    al,8ah
  3084. vpageit:    out    dx,al
  3085.         mov    ds:[si],bx
  3086.  
  3087. novpage:    pop    di
  3088.         pop    es
  3089.         pop    si
  3090.         pop    ds
  3091.         ret
  3092. setvpage    endp
  3093.  
  3094. setapage    proc    far pagen:word
  3095.         push    ds
  3096.         push    si
  3097.         push    es
  3098.         push    di
  3099.  
  3100.         lds    si,cs:TDtable
  3101.         mov    ax,pagen
  3102.         cmp    ax,ds:[si].vmaxpages
  3103.         jg    noapage
  3104.  
  3105.         or    al,al        ; if 0 then mov 0 to activepage
  3106.         mov    ds:[si].activepage,0
  3107.         jz    noapage
  3108.         mov    ds:[si].activepage,8000h
  3109.  
  3110. noapage:    pop    di
  3111.         pop    es
  3112.         pop    si
  3113.         pop    ds
  3114.         ret
  3115. setapage    endp
  3116.  
  3117.         end
  3118.