home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / 439 / LOADGIF / LOADGIF.ASM < prev    next >
Assembly Source File  |  1993-10-07  |  45KB  |  1,459 lines

  1. ;LOADGIF.ASM v1.0 - Optimized GIF Loader for EGA and VGA Video Modes
  2. ;By Rich Geldreich, Jr.
  3. ;Last Modified August 20, 1993
  4. ;Assembled with TASM v2.0
  5.  
  6. IDEAL
  7. MODEL SMALL
  8.  
  9. ;-------------------------------------------------------------------------------
  10. MACRO           PushaMacro
  11.                 Push    ax
  12.                 Push    bx
  13.                 Push    cx
  14.                 Push    dx
  15.                 Push    si
  16.                 Push    di
  17.                 Push    bp
  18. ENDM            PushaMacro
  19. ;-------------------------------------------------------------------------------
  20. MACRO           PopaMacro
  21.                 Pop     bp
  22.                 Pop     di
  23.                 Pop     si
  24.                 Pop     dx
  25.                 Pop     cx
  26.                 Pop     bx
  27.                 Pop     ax
  28. ENDM            PopaMacro
  29. ;-------------------------------------------------------------------------------
  30. ;This equate specifies the size the disk I/O buffer.
  31. ;Make sure it's at least 1024 or so bytes long.
  32. DiskIOSize      = 8192
  33. ;-------------------------------------------------------------------------------
  34. RP              = 0
  35. ;-------------------------------------------------------------------------------
  36. ;I/O Control.
  37. BufferOffset    = RP
  38. RP = RP + 2
  39. BufferLeft      = RP
  40. RP = RP + 2
  41. BufferHandle    = RP
  42. RP = RP + 2
  43. EOFFlag         = RP
  44. RP = RP + 2
  45. ;-------------------------------------------------------------------------------
  46. ;GIF Decoding & Image Size.
  47. TotalX          = RP
  48. RP = RP + 2
  49. TotalY          = RP
  50. RP = RP + 2
  51. NumColors       = RP
  52. RP = RP + 2
  53. XStart          = RP
  54. RP = RP + 2
  55. YStart          = RP
  56. RP = RP + 2
  57. XLength         = RP
  58. RP = RP + 2
  59. YLength         = RP
  60. RP = RP + 2
  61. XEnd            = RP
  62. RP = RP + 2
  63. YEnd            = RP
  64. RP = RP + 2
  65. X               = RP
  66. RP = RP + 2
  67. Y               = RP
  68. RP = RP + 2
  69. ;-------------------------------------------------------------------------------
  70. ;View window & Upper left hand corner of GIF image.
  71. XOrg            = RP
  72. RP = RP + 2
  73. YOrg            = RP
  74. RP = RP + 2
  75. X0              = RP
  76. RP = RP + 2
  77. Y0              = RP
  78. RP = RP + 2
  79. X1              = RP
  80. RP = RP + 2
  81. Y1              = RP
  82. RP = RP + 2
  83. ;-------------------------------------------------------------------------------
  84. ;Hardware parameters.
  85. VidColors       = RP
  86. RP = RP + 2
  87. Handler         = RP
  88. RP = RP + 2
  89. ScrOffset       = RP
  90. RP = RP + 2
  91. ScrWidth        = RP
  92. RP = RP + 2
  93. ScrX            = RP
  94. RP = RP + 2
  95. ScrY            = RP
  96. RP = RP + 2
  97. PixsLeft        = RP
  98. RP = RP + 2
  99. AdapterType     = RP
  100. RP = RP + 2
  101. PalIgnore       = RP
  102. RP = RP + 2
  103. ;-------------------------------------------------------------------------------
  104. ;LZW Decompression.
  105. PassNumber      = RP
  106. RP = RP + 2
  107. PassStep        = RP
  108. RP = RP + 2
  109. Background      = RP
  110. RP = RP + 2
  111. NoPalette       = RP
  112. RP = RP + 2
  113. Interlaced      = RP
  114. RP = RP + 2
  115. FirstCode       = RP
  116. RP = RP + 2
  117. StartCode       = RP
  118. RP = RP + 2
  119. StartMaxCode    = RP
  120. RP = RP + 2
  121. NextCode        = RP
  122. RP = RP + 2
  123. LastCode        = RP
  124. RP = RP + 2
  125. LastPixel       = RP
  126. RP = RP + 2
  127. StartCodeMask   = RP
  128. RP = RP + 2
  129. StartCodeSize   = RP
  130. RP = RP + 2
  131. ;-------------------------------------------------------------------------------
  132. ;Scanline buffer. A maximum of 1536 pixels per scanline should be enough.
  133. LineBuffer      = RP
  134. RP = RP + 1536
  135. ;-------------------------------------------------------------------------------
  136. ;LZW string tables. The Suffix table MUST come directly before Prefix in memory!
  137. Suffix          = RP
  138. RP = RP + 4096*2
  139. Prefix          = RP
  140. RP = RP + 4096*2
  141. PStack          = RP
  142. RP = RP + 4096+128
  143. ;-------------------------------------------------------------------------------
  144. ;GIF's palette.
  145. Palette         = RP
  146. RP = RP + 768
  147. ;-------------------------------------------------------------------------------
  148. ;Disk I/O buffer.
  149. RP = RP + 16
  150. DiskBuffer      = RP
  151. RP = RP + DiskIOSize
  152. ;-------------------------------------------------------------------------------
  153. ;For 16 color pixel plotting.
  154. Plane0          = RP
  155. RP = RP + 80
  156. Plane1          = RP
  157. RP = RP + 80
  158. Plane2          = RP
  159. RP = RP + 80
  160. Plane3          = RP
  161. RP = RP + 80
  162. ;-------------------------------------------------------------------------------
  163. ;The value of RP here determines how much memory the function requires.
  164. ;-------------------------------------------------------------------------------
  165. SEGMENT         GIFCODE PARA PUBLIC 'CODE'
  166. ;-------------------------------------------------------------------------------
  167. ASSUME          DS:@DATA, ES:@DATA, CS:GIFCODE, SS:@DATA
  168. ;-------------------------------------------------------------------------------
  169. ;In ERROR.ASM
  170. EXTRN           ErrorCode:WORD
  171. EXTRN           Hook24:NEAR, Unhook24:NEAR, CheckError:NEAR
  172. ;-------------------------------------------------------------------------------
  173. PUBLIC          LoadGIF
  174. PROC            LoadGIF
  175.  
  176. ;Stack organization.
  177. MemPointer      EQU     [ss:bp+42]
  178. FileSeg         EQU     [ss:bp+40]
  179. FileOfs         EQU     [ss:bp+38]
  180.  
  181. PScrType        EQU     [ss:bp+36]
  182. PScrOffset      EQU     [ss:bp+34]
  183. PScrWidth       EQU     [ss:bp+32]
  184. PXRes           EQU     [ss:bp+30]
  185. PYRes           EQU     [ss:bp+28]
  186.  
  187. PX0             EQU     [ss:bp+26]
  188. PY0             EQU     [ss:bp+24]
  189. PX1             EQU     [ss:bp+22]
  190. PY1             EQU     [ss:bp+20]
  191. PXOrg           EQU     [ss:bp+18]
  192. PYOrg           EQU     [ss:bp+16]
  193.  
  194. PAdapterType    EQU     [ss:bp+14]
  195. PPalIgnore      EQU     [ss:bp+12]
  196.  
  197. PPalSeg         EQU     [ss:bp+10]
  198. PPalOfs         EQU     [ss:bp+08]
  199. PPalColors      EQU     [ss:bp+06]
  200.  
  201. Parameters      = 19
  202.  
  203.                 Cld
  204.                 Push    bp
  205.                 Mov     bp, sp
  206.                 Push    ds es si di
  207.  
  208.                 Call    Hook24          ;Install critical error handler.
  209.  
  210.                 Mov     ax, MemPointer
  211.                 Mov     ds, ax
  212.                 Mov     es, ax
  213.  
  214.                 Call    Init            ;Fetch passed parameters.
  215.                 Jc      @@OpenError
  216.  
  217.                 Call    CheckOpts       ;Check passed window coordinates.
  218.                 Jc      @@NothingToDo
  219.  
  220.                 Call    IOOpen          ;Open GIF file.
  221.                 Jc      @@OpenError
  222.  
  223.                 Call    IOReadInit      ;Initialize disk I/O buffer.
  224.                 Jc      @@Error
  225.  
  226.                 Call    GetGIFHeader    ;Fetch GIF sig, tables, etc.
  227.                 Jc      @@Error
  228.  
  229.                 Call    SetPalette      ;Set GIF's palette.
  230.  
  231.                 Call    DecodeGIF       ;Decompress GIF.
  232.                 Jc      @@Error
  233.  
  234.                 Xor     ax, ax          ;No error.
  235.  
  236. @@Exit0:        Push    ax
  237.                 Call    IOClose         ;Close input file.
  238.                 Pop     ax
  239.  
  240. @@Exit1:        Call    Unhook24        ;Uninstall critical error handler.
  241.                 Cld
  242.                 Pop     di si es ds bp
  243.                 Retf    Parameters*2
  244.  
  245. @@Error:        Mov     ax, -1
  246.                 Jmp     @@Exit0
  247. @@OpenError:    Mov     ax, -1
  248.                 Jmp     @@Exit1
  249. @@NothingToDo:  Xor     ax, ax
  250.                 Jmp     @@Exit1
  251. ENDP            LoadGIF
  252. ;-------------------------------------------------------------------------------
  253. PROC            Init
  254. ;---------------
  255. ;Clear work space.
  256.                 Xor     ax, ax
  257.  
  258.                 Mov     di, offset BufferOffset
  259.                 Mov     cx, RP                  ;Clear memory block.
  260.  
  261.                 Shr     cx, 1
  262.                 Rep     Stosw
  263.                 Rcl     cx, 1
  264.                 Rep     Stosb
  265. ;---------------
  266. ;Fetch & check passed parameters from stack.
  267.                 Mov     ax, PScrType
  268.                 Cmp     ax, 2
  269.                 Ja      @@Error1
  270.  
  271.                 Mov     bx, offset WPIX1        ;assume mode 13
  272.                 Mov     cx, 256
  273.  
  274.                 And     ax, ax
  275.                 Jnz     @@10
  276.  
  277.                 Mov     bx, offset WPIX0        ;16 color modes
  278.                 Mov     cx, 16
  279. @@10:
  280.                 Cmp     al, 2
  281.                 Jne     @@20
  282.                 Mov     bx, offset WPIX2        ;mode-x
  283. @@20:
  284.                 Mov     [ds:Handler], bx
  285.                 Mov     [ds:VidColors], cx
  286.  
  287.                 Mov     ax, PScrOffset
  288.                 Mov     [ds:ScrOffset], ax
  289.  
  290.                 Mov     ax, PScrWidth
  291.                 Mov     [ds:ScrWidth], ax
  292.  
  293.                 Mov     ax, PXRes
  294.                 Mov     [ds:ScrX], ax
  295.  
  296.                 Mov     ax, PYRes
  297.                 Mov     [ds:ScrY], ax
  298.  
  299.                 Mov     ax, PAdapterType
  300.                 Cmp     ax, 1
  301.                 Ja      @@Error2
  302.  
  303.                 And     ax, ax
  304.                 Jnz     @@VGAPal
  305.                 Cmp     [word ds:VidColors], 16
  306.                 Ja      @@Error2
  307.  
  308. @@VGAPal:       Mov     [byte ds:AdapterType], al
  309.  
  310.                 Mov     al, PPalIgnore
  311.                 Mov     [byte ds:PalIgnore], al
  312.  
  313.                 Clc
  314.                 Ret
  315.  
  316. @@Error1:       Mov     [cs:ErrorCode], -6      ;Bad Screen type.
  317.                 Stc
  318.                 Ret
  319. @@Error2:       Mov     [cs:ErrorCode], -7      ;Bad adapter type.
  320.                 Stc
  321.                 Ret
  322. ENDP            Init
  323. ;-------------------------------------------------------------------------------
  324. ;Clip view window to screen boundry.
  325. PROC            CheckOpts
  326.                 Mov     ax, PXOrg
  327.                 Mov     [ds:XOrg], ax
  328.                 Mov     ax, PYOrg
  329.                 Mov     [ds:YOrg], ax
  330.  
  331.                 Mov     ax, PX0
  332.                 Mov     bx, PY0
  333.                 Mov     cx, PX1
  334.                 Mov     dx, PY1
  335.  
  336.                 Cmp     ax, cx
  337.                 Jle     @@XOk
  338.                 Xchg    ax, cx
  339. @@XOk:
  340.                 Cmp     bx, dx
  341.                 Jle     @@YOk
  342.                 Xchg    bx, dx
  343. @@YOk:
  344.                 And     cx, cx
  345.                 Jl      @@ByeBye
  346.                 Cmp     ax, [ds:ScrX]
  347.                 Jg      @@ByeBye
  348.  
  349.                 And     dx, dx
  350.                 Jl      @@ByeBye
  351.                 Cmp     bx, [ds:ScrY]
  352.                 Jg      @@ByeBye
  353.  
  354.                 And     ax, ax
  355.                 Jnl     @@XOk1
  356.                 Xor     ax, ax
  357. @@XOk1:
  358.                 And     bx, bx
  359.                 Jnl     @@YOk1
  360.                 Xor     bx, bx
  361. @@YOk1:
  362.                 Cmp     cx, [ds:ScrX]
  363.                 Jng     @@XOk2
  364.                 Mov     cx, [ds:ScrX]
  365. @@XOk2:
  366.                 Cmp     dx, [ds:ScrY]
  367.                 Jng     @@YOk2
  368.                 Mov     dx, [ds:ScrY]
  369. @@YOk2:
  370.                 Mov     [ds:X0], ax
  371.                 Mov     [ds:Y0], bx
  372.                 Mov     [ds:X1], cx
  373.                 Mov     [ds:Y1], dx
  374.  
  375.                 Clc
  376.                 Ret
  377.  
  378. @@ByeBye:       Stc                             ;Exit if GIF invisible.
  379.                 Ret
  380. ENDP            CheckOpts
  381. ;-------------------------------------------------------------------------------
  382. ;Refresh disk input buffer.
  383. PROC            IOReadInit
  384.                 PushaMacro
  385.                 Mov     cx, DiskIOSize
  386.                 Mov     ah, 03Fh
  387.                 Mov     bx, [ds:BufferHandle]
  388.                 Mov     dx, offset DiskBuffer
  389.                 Mov     [ds:BufferOffset], dx
  390.                 Int     021h
  391.                 Mov     [ds:BufferLeft], ax
  392.                 Call    CheckError
  393.                 Pushf
  394.                 Mov     [byte ds:EOFFlag], 0
  395.                 And     ax, ax
  396.                 Jnz     @@Exit
  397.                 Mov     [byte ds:EOFFlag], -1
  398. @@Exit:         Popf
  399.                 PopaMacro
  400.                 Mov     si, offset DiskBuffer
  401.                 Ret
  402. ENDP            IOReadInit
  403. ;-------------------------------------------------------------------------------
  404. ;Open input file.
  405. PROC            IOOpen
  406.                 Push    ds
  407.                 Mov     ds, FileSeg
  408.                 Mov     dx, FileOfs
  409.                 Mov     ax, 03D00h
  410.                 Int     021h
  411.                 Pop     ds
  412.                 Mov     [ds:BufferHandle], ax
  413.                 Call    CheckError
  414.                 Ret
  415. ENDP            IOOpen
  416. ;-------------------------------------------------------------------------------
  417. ;Close input file.
  418. PROC            IOClose
  419.                 Mov     ax, 03E00h
  420.                 Mov     bx, [ds:BufferHandle]
  421.                 Int     021h
  422.                 Call    CheckError
  423.                 Ret
  424. ENDP            IOClose
  425. ;-------------------------------------------------------------------------------
  426. ;Read one byte from input file(not used in main LZW decode loop).
  427. ALIGN 4
  428. PROC            IOReadByte
  429.                 Xchg    si, [ds:BufferOffset]
  430.                 Xor     ax, ax
  431.                 Lodsb
  432.                 Xchg    [ds:BufferOffset], si
  433.  
  434.                 Dec     [word ds:BufferLeft]
  435.                 Jz      @@Refresh
  436.                 Ret
  437. @@Refresh:      Push    si
  438.                 Call    IOReadInit
  439.                 Pop     si
  440.                 Ret
  441. ENDP            IOReadByte
  442. ;-------------------------------------------------------------------------------
  443. ;Read one word from input file.
  444. PROC            IOReadWord
  445.                 Push    bx
  446.                 Call    IOReadByte
  447.                 Push    ax
  448.                 Call    IOReadByte
  449.                 Pop     bx
  450.                 Mov     ah, al
  451.                 Mov     al, bl
  452.                 Pop     bx
  453.                 Ret
  454. ENDP            IOReadWord
  455. ;-------------------------------------------------------------------------------
  456. ;Fetch GIF sig, header, and find first image.
  457. PROC            GetGIFHeader
  458.                 Call    CheckGIFHeader
  459.                 Jc      @@Exit
  460.  
  461.                 Call    GetScreenDescriptor
  462.                 Jc      @@Exit
  463.  
  464.                 Call    GetImageDescriptor
  465.  
  466. @@Exit:         Ret
  467. ENDP            GetGIFHeader
  468. ;-------------------------------------------------------------------------------
  469. ;Check for the string "GIF" at the beginning of the file. The version number,
  470. ;usually "87a" or "89a", is ignored.
  471. PROC            CheckGIFHeader
  472.                 Call    IOReadWord
  473.                 Cmp     ax, 'G'+'I'*256
  474.                 Jne     @@BadHeader
  475.  
  476.                 Call    IOReadByte
  477.                 Cmp     al, 'F'
  478.                 Jne     @@BadHeader
  479.  
  480.                 Call    IOReadWord      ;skip GIF version #
  481.                 Call    IOReadByte
  482.  
  483.                 Clc
  484.                 Ret
  485.  
  486. @@BadHeader:    Mov     [word cs:ErrorCode], -3
  487.                 Stc
  488.                 Ret
  489. ENDP            CheckGIFHeader
  490. ;-------------------------------------------------------------------------------
  491. ;Fetch screen descriptor. Exits if GIF image has too many colors for
  492. ;the given video mode.
  493. PROC            GetScreenDescriptor
  494.                 Call    IOReadWord
  495.                 Mov     [ds:TotalX], ax
  496.                 Call    IOReadWord
  497.                 Mov     [ds:TotalY], ax
  498.  
  499.                 Call    IOReadByte
  500.                 Mov     cl, al
  501.                 And     al, 128
  502.                 Jnz     @@Palette
  503.                 Mov     [byte ds:NoPalette], -1
  504. @@Palette:      And     cl, 7
  505.                 Inc     cl
  506.                 Mov     ax, 1
  507.                 Shl     ax, cl
  508.                 Mov     [ds:NumColors], ax
  509.  
  510.                 Cmp     ax, [ds:VidColors]
  511.                 Ja      @@BadDescriptor
  512.  
  513.                 Mov     bx, PPalColors ;store # colors
  514.                 Cmp     [byte ds:NoPalette], -1
  515.                 Jne     @@05
  516.                 Neg     ax
  517. @@05:           Mov     [ss:bx], ax
  518.  
  519.                 Call    IOReadByte
  520.                 Mov     [byte ds:Background], al
  521.  
  522.                 Call    IOReadByte
  523.  
  524.                 Cmp     [byte ds:NoPalette], -1
  525.                 Je      @@NoPalette
  526.  
  527.                 Mov     cx, [ds:NumColors]
  528.                 Mov     di, offset Palette
  529. @@10:           REPT    3                       ;Fetch palette
  530.                 Call    IOReadByte
  531.                 Stosb
  532.                 ENDM
  533.                 Loop    @@10
  534.  
  535.                 Cmp     PPalSeg, cx
  536.                 Je      @@NoPalette
  537.  
  538.                 Push    es
  539.                 Les     di, PPalOfs
  540.                 Mov     si, offset Palette
  541.                 Mov     cx, [ds:NumColors]
  542.                 Mov     ax, cx
  543.                 Shl     cx, 1
  544.                 Add     cx, ax
  545.                 Rep     Movsb
  546.                 Pop     es
  547.  
  548. @@NoPalette:    Clc
  549.                 Ret
  550.  
  551. @@BadDescriptor:
  552.                 Mov     [word cs:ErrorCode], -4
  553.                 Stc
  554.                 Ret
  555. ENDP            GetScreenDescriptor
  556. ;-------------------------------------------------------------------------------
  557. ;Find first image. Ignores all GIF extensions.
  558. PROC            GetImageDescriptor
  559.  
  560. @@05:           Call    IOReadByte
  561.                 Cmp     al, 44
  562.                 Je      @@Found
  563.  
  564.                 Cmp     al, 33
  565.                 Jne     @@BadImageDescriptor
  566.                 Call    IOReadByte
  567.  
  568. @@10:           Call    IOReadByte
  569.                 Mov     cx, ax
  570.                 Jcxz    @@05
  571. @@20:           Call    IOReadByte
  572.                 Loop    @@20
  573.                 Jmp     @@10
  574. @@Found:
  575.                 Call    IOReadWord
  576.                 Add     ax, offset LineBuffer
  577.                 Mov     [ds:XStart], ax
  578.                 Call    IOReadWord
  579.                 Mov     [ds:YStart], ax
  580.  
  581.                 Call    IOReadWord
  582.                 Mov     [ds:XLength], ax
  583.                 Add     ax, [ds:XStart]
  584.                 Cmp     ax, 1536+offset LineBuffer ;If GIF is larger than 1536
  585.                 Ja      @@BadImageDescriptor       ;pixels per scanline then
  586.                 Mov     [ds:XEnd], ax              ;exit.
  587.  
  588.                 Call    IOReadWord
  589.                 Mov     [ds:YLength], ax
  590.                 Add     ax, [ds:YStart]
  591.                 Mov     [ds:YEnd], ax
  592.  
  593.                 Call    IOReadByte
  594.                 Test    al, 128
  595.                 Jnz     @@BadImageDescriptor
  596.  
  597.                 Test    al, 64
  598.                 Jz      @@NotInterlaced
  599.                 Mov     [byte ds:Interlaced], -1   ;Initialize vars needed
  600.                 Mov     [byte ds:PassNumber], 0    ;for interlaced GIF's.
  601.                 Mov     [byte ds:PassStep], 8
  602. @@NotInterlaced:
  603.                 Clc
  604.                 Ret
  605. @@BadImageDescriptor:
  606.                 Mov     [word cs:ErrorCode], -5
  607.                 Stc
  608.                 Ret
  609. ENDP            GetImageDescriptor
  610. ;-------------------------------------------------------------------------------
  611. PROC            DecodeGIF
  612.                 Call    InitDecode              ;Setup SM code.
  613.                 Call    Decode                  ;Decompress LZW data stream.
  614.                 Ret
  615. ENDP            DecodeGIF
  616. ;-------------------------------------------------------------------------------
  617. PROC            Decode
  618.                 ;Read # bytes left in this block.
  619.                 Call    IOReadByte
  620.                 Mov     bp, ax                  ;BP always holds bytes left in
  621.                 Mov     si, [ds:BufferOffset]   ;current block.
  622.                 Mov     [byte ds:si-1], 0
  623.                 Jmp     @@MainLoop
  624. ;-------------------------------------------------------------------------------
  625. @@ClearCode:    Je      @@Done
  626.                 Mov     ax, [ds:FirstCode]      ;Clear code received, reset
  627.                 Mov     [ds:NextCode], ax       ;tables.
  628.                 Mov     ax, [ds:StartCodeSize]
  629.                 Mov     [byte cs:CodeSizeA], al
  630.                 Mov     ax, [ds:StartMaxCode]
  631.                 Mov     [word cs:MaxCode], ax
  632.                 Mov     ax, [ds:StartCodeMask]
  633.                 Mov     [word cs:CodeMaskA1], ax
  634.                 Mov     [word cs:CodeMaskA2], ax
  635.  
  636.                 Call    GetCode1                ;Get next code as a special
  637.                 Mov     [ds:LastCode], dx       ;case.
  638.                 Shr     dx, 1
  639.                 Mov     [ds:LastPixel], dx
  640.  
  641.                 Mov     di, [ds:X]
  642.                 Xchg    ax, dx
  643.                 Stosb
  644.                 Cmp     di, [ds:XEnd]
  645.                 Jne     @@NoFlush
  646.  
  647.                 Call    FlushLine
  648.                 Jnc     @@NoFlush
  649. @@Done:         Clc
  650.                 Ret
  651. @@NoFlush:      Mov     [ds:X], di
  652.                 Jmp     short @@MainLoop
  653. ;-------------------------------------------------------------------------------
  654. @@CodeError:    Mov     [word cs:ErrorCode], -2         ;Bad LZW code received,
  655.                 Stc                                     ;exit.
  656.                 Ret
  657.  
  658. @@Check:        Ja      @@CodeError
  659.                 Mov     di, offset PStack+4095
  660.                 Std
  661.                 Mov     al, [byte ds:LastPixel]
  662.                 Stosb
  663.                 Mov     si, [ds:LastCode]
  664.                 Jmp     @@CheckBack
  665. ;--------------- Standard LZW decoding algorithm
  666. ALIGN 4
  667. @@MainLoop:     Call    GetCode1                        ;Fetch LZW code.
  668.                 Mov     si, dx
  669.  
  670.                 Cmp     dx, [ds:NextCode]               ;Not in table?
  671.                 Jae     @@Check
  672.  
  673. ClearCode       =       $+2
  674.                 Sub     dx, 09999h                      ;Clear code or EOF code?
  675.                 Cmp     dx, 02h
  676.                 Jbe     @@ClearCode
  677. ;---------------
  678.                 Mov     di, offset PStack+4095
  679.                 Std
  680.  
  681. FirstCde        =       $+2
  682. @@CheckBack:    Cmp     si, 09999h
  683.                 Jb      @@Char
  684.  
  685.                 Add     si, offset Suffix
  686.                 Mov     bx, 8192+1
  687. CompareCode     =       $+1
  688.                 Mov     dx, 09999h
  689.  
  690. @@PushLoop:     REPT 14
  691.                 Movsb                                   ;Decode string
  692.                 Mov     si, [ds:si+bx]
  693.                 Cmp     si, dx
  694.                 Jnae    @@PLDone
  695.                 ENDM
  696.                 Movsb
  697.                 Mov     si, [ds:si+bx]
  698.                 Cmp     si, dx
  699.                 Jae     @@PushLoop
  700. ALIGN 4
  701. @@PLDone:       Sub     si, offset Suffix
  702. ;---------------
  703. @@Char:         Mov     ax, si
  704.                 Shr     ax, 1
  705.                 Mov     [ds:LastPixel], ax
  706.                 Stosb
  707.                 Cld
  708.  
  709.                 Mov     bx, offset PStack+4095
  710.                 Sub     bx, di
  711.                 Mov     si, di
  712.                 Inc     si
  713.                 Mov     di, [ds:X]
  714.  
  715. @@SlowCopy:     Mov     cx, [ds:XEnd]
  716.                 Sub     cx, di
  717.                 Cmp     cx, bx
  718.                 Jbe     @@Ok
  719.                 Mov     cx, bx
  720. @@Ok:
  721.                 Sub     bx, cx
  722.                 Rep     Movsb
  723.  
  724.                 Cmp     di, [ds:XEnd]
  725.                 Je      @@GoNextLine
  726.  
  727. @@GotNextLine:  And     bx, bx
  728.                 Jnz     @@SlowCopy
  729.  
  730.                 Mov     [ds:X], di
  731.  
  732.                 ;Update dictionary
  733.                 Mov     ax, [ds:LastPixel]
  734.                 Mov     bx, [ds:NextCode]
  735.                 Cmp     bx, 4096*2                      ;Dictionary filled?
  736.                 Jae     @@GoRound
  737.                 Mov     si, [ds:LastCode]
  738.                 Add     si, offset Suffix
  739.                 Mov     [ds:bx+offset Prefix], si
  740.                 Mov     [ds:bx+offset Suffix], ax
  741.                 Inc     bx
  742.                 Inc     bx
  743. MaxCode         =       $+2
  744.                 Cmp     bx, 09999h
  745.                 Je      @@IncCode
  746. @@Inced:        Mov     [ds:NextCode], bx
  747.  
  748. @@GoRound:
  749. Code            =       $+4
  750.                 Mov     [word ds:LastCode], 09999h
  751.                 Jmp     @@MainLoop
  752. ;-------------------------------------------------------------------------------
  753. @@GoNextLine:   Call    FlushLine
  754.                 Jnc     @@GotNextLine
  755.                 Clc
  756.                 Ret
  757. ;-------------------------------------------------------------------------------
  758. ;Increment LZW code size.
  759. @@IncCode:      Cmp     [byte cs:CodeSizeA], 12
  760.                 Jae     @@Inced
  761.                 Inc     [byte cs:CodeSizeA]
  762.                 Shl     [word cs:MaxCode], 1
  763.                 Shl     [word cs:CodeMaskA1],1
  764.                 Inc     [word cs:CodeMaskA1]
  765.                 Shl     [word cs:CodeMaskA2],1
  766.                 Inc     [word cs:CodeMaskA2]
  767.                 Jmp     @@Inced
  768. ;-------------------------------------------------------------------------------
  769. ENDP            Decode
  770. ;-------------------------------------------------------------------------------
  771. PROC            FlushLine
  772.                 Cld
  773.                 Push    es
  774.                 PushaMacro
  775.  
  776.                 Call    WPIX
  777.  
  778.                 Mov     ax, [ds:Y]
  779.  
  780.                 Cmp     [byte ds:Interlaced], 0
  781.                 Jne     @@Interlaced
  782.  
  783.                 Inc     ax
  784.                 Mov     bx, ax
  785.                 Add     bx, [ds:YOrg]
  786.                 Cmp     bx, [ds:Y1]
  787.                 Jg      @@Done
  788.  
  789.                 Clc
  790. @@Return:       Mov     [ds:Y], ax
  791.                 PopaMacro
  792.                 Pop     es
  793.                 Mov     di, [ds:XStart]
  794.                 Ret
  795.  
  796. @@Done:         Stc
  797.                 Jmp     @@Return
  798. ;---------------
  799. @@Interlaced:   Add     ax, [ds:PassStep]
  800.                 Cmp     ax, [ds:YEnd]
  801.                 Jnge    @@N
  802.  
  803.                 Inc     [word ds:PassNumber]
  804.                 Mov     bl, [byte ds:PassNumber]
  805.                 Cmp     bl, 1
  806.                 Jne     @@10
  807.                 Mov     ax, 4
  808.                 Mov     [byte ds:PassStep], 8
  809.                 Jmp     @@N
  810. @@10:           Cmp     bl, 2
  811.                 Jne     @@20
  812.                 Mov     ax, 2
  813.                 Mov     [byte ds:PassStep], 4
  814.                 Jmp     @@N
  815. @@20:           Cmp     bl, 3
  816.                 Jne     @@N
  817.                 Mov     ax, 1
  818.                 Mov     [byte ds:PassStep], 2
  819.  
  820. @@N:            Clc
  821.                 Jmp     @@Return
  822. ENDP            FlushLine
  823. ;-------------------------------------------------------------------------------
  824. PROC            SetPalette
  825.                 Cmp     [byte ds:PalIgnore], 0 ;Ignore palette flag.
  826.                 Jne     @@Exit
  827.                 Cmp     [byte ds:NoPalette], 0 ;No palette in GIF?
  828.                 Jne     @@Exit
  829.  
  830.                 Mov     cx, [ds:NumColors]
  831.                 Mov     si, offset Palette
  832.                 Xor     bx, bx
  833.  
  834.                 Cmp     [byte ds:AdapterType], 1        ;VGA palette?
  835.                 Je      @@VGAPalette
  836.  
  837. ;---------------
  838. @@EGAPalette:   Xor     bh, bh                          ;Make EGA palette.
  839.                 Lodsb
  840.                 Test    al, 128
  841.                 Jz      @@10
  842.                 Or      bh, 4
  843. @@10:           Test    al, 64
  844.                 Jz      @@20
  845.                 Or      bh, 32
  846. @@20:           Lodsb
  847.                 Test    al, 128
  848.                 Jz      @@30
  849.                 Or      bh, 2
  850. @@30:           Test    al, 64
  851.                 Jz      @@40
  852.                 Or      bh, 16
  853. @@40:           Lodsb
  854.                 Test    al, 128
  855.                 Jz      @@50
  856.                 Or      bh, 1
  857. @@50:           Test    al, 64
  858.                 Jz      @@60
  859.                 Or      bh, 8
  860. @@60:           Mov     ax, 01000h
  861.                 Int     010h
  862.                 Inc     bx
  863.                 Loop    @@EGAPalette
  864. @@Exit:         Ret
  865. ;---------------
  866. @@VGAPalette:   Mov     dx, si
  867.  
  868.                 Push    cx
  869.                 Mov     ax, cx
  870.                 Shl     cx, 1
  871.                 Add     cx, ax
  872.                 Mov     di, si
  873. @@70:           Lodsb
  874.                 Shr     al, 1
  875.                 Shr     al, 1
  876.                 Stosb
  877.                 Loop    @@70
  878.                 Pop     cx
  879.  
  880.                 Mov     ax, 01012h
  881.                 Int     010h
  882.                 Ret
  883. ENDP            SetPalette
  884. ;-------------------------------------------------------------------------------
  885. ;This subroutine clips each line to the view window's edges and then
  886. ;calls lower level functions to plot the pixels onto the screen.
  887. ALIGN 4
  888. Skip:           Ret
  889. ALIGN 4
  890. PROC            WPIX
  891.  
  892.                 Mov     ax, [ds:Y]
  893.                 Add     ax, [ds:YOrg]
  894.                 Cmp     ax, [ds:Y0]
  895.                 Jl      Skip
  896.                 Cmp     ax, [ds:Y1]
  897.                 Jg      Skip
  898.  
  899.                 Mov     di, [ds:XStart]
  900.                 Mov     dx, [ds:XEnd]
  901.  
  902.                 Mov     si, di
  903.                 Sub     di, offset LineBuffer
  904.                 Sub     dx, offset LineBuffer+1
  905.                 Add     di, [ds:XOrg]
  906.                 Add     dx, [ds:XOrg]
  907.  
  908. ;di = physical image start X
  909. ;dx = physical image end X
  910.  
  911.                 Mov     bp, [ds:X0]
  912.                 Mov     bx, [ds:X1]
  913.  
  914.                 Cmp     di, bx  ;IF startx>x1 THEN exit
  915.                 Jg      Skip
  916.                 Cmp     dx, bp
  917.                 Jl      Skip    ;IF endx<x0 THEN exit
  918.  
  919.                 Cmp     di, bp
  920.                 Jge     @@NoClipLowX
  921.                 Sub     di, bp
  922.                 Sub     si, di
  923.                 Mov     di, bp
  924. @@NoClipLowX:
  925.                 Cmp     dx, bx
  926.                 Jle     @@NoClipHighX
  927.                 Mov     dx, bx
  928. @@NoClipHighX:
  929.  
  930.                 Mov     cx, dx
  931.                 Sub     cx, di
  932.                 Inc     cx
  933.  
  934.                 Jmp     [word ds:Handler]
  935.  
  936. ENDP            WPIX
  937. ;-------------------------------------------------------------------------------
  938. ;Fast pixel plotter for 16 color modes. (Boy do I hate this thing!)
  939. MACRO           SepPlanes
  940.                 Lodsb
  941.                 Shr     al, 1
  942.                 Rcl     bl, 1
  943.                 Shr     al, 1
  944.                 Rcl     bh, 1
  945.                 Shr     al, 1
  946.                 Rcl     dl, 1
  947.                 Shr     al, 1
  948.                 Rcl     dh, 1
  949. ENDM
  950.  
  951. MACRO           SepPlanes2
  952.                 Lodsw
  953.                 Shr     al, 1
  954.                 Rcl     bl, 1
  955.                 Shr     al, 1
  956.                 Rcl     bh, 1
  957.                 Shr     al, 1
  958.                 Rcl     cl, 1
  959.                 Shr     al, 1
  960.                 Rcl     ch, 1
  961.  
  962.                 Shr     ah, 1
  963.                 Rcl     bl, 1
  964.                 Shr     ah, 1
  965.                 Rcl     bh, 1
  966.                 Shr     ah, 1
  967.                 Rcl     cl, 1
  968.                 Shr     ah, 1
  969.                 Rcl     ch, 1
  970. ENDM
  971.  
  972. PROC            WPIX0
  973.                 Mov     bp, cx
  974.  
  975.                 Push    es 0A000h
  976.                 Pop     es
  977.  
  978.                 Mul     [word ds:ScrWidth]
  979.                 Add     ax, [ds:ScrOffset]
  980.  
  981.                 Xchg    ax, di
  982.                 Mov     cx, ax
  983.                 Shr     ax, 1
  984.                 Shr     ax, 1
  985.                 Shr     ax, 1
  986.                 Add     di, ax
  987.  
  988.                 Mov     [ds:PixsLeft], bp
  989.  
  990.                 Mov     dx, 03C4h
  991.                 Mov     al, 2
  992.                 Out     dx, al
  993.  
  994.                 Mov     dl, 0CEh
  995.                 Mov     al, 8
  996.                 Out     dx, al
  997. ;-------------------------------------------------------------------------------
  998.                 And     cx, 7
  999.                 Jz      @@ByteAligned
  1000.  
  1001.                 Neg     cx
  1002.                 Add     cx, 8
  1003.  
  1004.                 Xor     bx, bx
  1005.                 Mov     dx, bx
  1006.                 Mov     ah, 0ffh
  1007. ALIGN 4
  1008. @@EG1:          SepPlanes
  1009.                 Shl     ah, 1
  1010.                 Dec     bp
  1011.                 Loopnz  @@EG1
  1012.                 Shl     bx, cl
  1013.                 Shl     dx, cl
  1014.                 Rol     ah, cl
  1015.                 Mov     [ds:PixsLeft], bp
  1016.  
  1017.                 Mov     bp, dx
  1018.                 Mov     dx, 03CFh
  1019.                 Mov     al, ah
  1020.                 Not     al
  1021.                 Out     dx, al
  1022.                 Mov     dl, 0C5h
  1023.                 Mov     al, [es:di]
  1024.  
  1025.                 Mov     al, 1
  1026.                 Out     dx, al
  1027.                 Mov     [es:di], bl
  1028.                 Shl     al, 1
  1029.                 Out     dx, al
  1030.                 Mov     [es:di], bh
  1031.                 Shl     al, 1
  1032.                 Out     dx, al
  1033.                 Mov     bx, bp
  1034.                 Mov     [es:di], bl
  1035.                 Shl     al, 1
  1036.                 Out     dx, al
  1037.                 Mov     [es:di], bh
  1038.  
  1039.                 Mov     dl, 0CFh
  1040.                 Mov     al, 0FFh
  1041.                 Out     dx, al
  1042.  
  1043.                 Inc     di
  1044. ;-------------------------------------------------------------------------------
  1045. ALIGN 4
  1046. @@ByteAligned:  Mov     bp, [ds:PixsLeft]
  1047.                 Shr     bp, 1
  1048.                 Shr     bp, 1
  1049.                 Shr     bp, 1
  1050.                 And     bp, bp
  1051.                 Jnz     @@DoRuns
  1052.                 Jmp     @@NoRuns
  1053. ALIGN 4
  1054. @@DoRuns:       Push    di
  1055.                 Mov     di, offset Plane0
  1056.                 Mov     ax, ds
  1057.                 Mov     es, ax
  1058.  
  1059.                 Shr     bp, 1
  1060.                 Jnc     @@EG2
  1061.                 Inc     bp
  1062.                 Jmp     @@Middle
  1063. ALIGN 4
  1064. @@EG2:
  1065. REPT    4
  1066.                 SepPlanes2
  1067. ENDM
  1068.                 Mov     [ds:di+80*1], bh
  1069.                 Mov     [ds:di+80*2], cl
  1070.                 Mov     [ds:di+80*3], ch
  1071.                 Mov     al, bl
  1072.                 Stosb
  1073. @@Middle:
  1074. REPT    4
  1075.                 SepPlanes2
  1076. ENDM
  1077.                 Mov     [ds:di+80*1], bh
  1078.                 Mov     [ds:di+80*2], cl
  1079.                 Mov     [ds:di+80*3], ch
  1080.                 Mov     al, bl
  1081.                 Stosb
  1082.  
  1083.                 Dec     bp
  1084.                 Jz      @@AllDone
  1085.                 Jmp     @@EG2
  1086. ALIGN 4
  1087. @@AllDone:      Mov     cx, di
  1088.                 Pop     di
  1089.  
  1090.                 Mov     ax, 0A000h
  1091.                 Mov     es, ax
  1092.  
  1093.                 Push    si
  1094.                 Mov     si, offset Plane0
  1095.                 Sub     cx, si
  1096.                 Mov     dx, 03C5h
  1097.                 Mov     al, 1
  1098.                 Mov     bp, 4
  1099.  
  1100. @@10:           Out     dx, al
  1101.                 Push    si di cx
  1102.                 Shr     cx, 1
  1103.                 Rep     Movsw
  1104.                 Rcl     cx, 1
  1105.                 Rep     Movsb
  1106.                 Pop     cx di si
  1107.                 Shl     al, 1
  1108.                 Add     si, 80
  1109.                 Dec     bp
  1110.                 Jnz     @@10
  1111.                 Add     di, cx
  1112.                 Pop     si
  1113. ;-------------------------------------------------------------------------------
  1114. @@NoRuns:       Mov     cx, [ds:PixsLeft]
  1115.                 And     cx, 7
  1116.                 Jz      @@Exit
  1117.                 Mov     bp, 03C5h
  1118.  
  1119.                 Xor     bx, bx
  1120.                 Mov     dx, bx
  1121.  
  1122.                 Mov     ah, 0FFh
  1123.                 Shl     ah, cl
  1124.  
  1125.                 Push    cx
  1126. ALIGN 4
  1127. @@EG3:          SepPlanes
  1128.                 Loop    @@EG3
  1129.                 Pop     cx
  1130.  
  1131.                 Neg     cl
  1132.                 Add     cl, 8
  1133.                 Shl     bx, cl
  1134.                 Shl     dx, cl
  1135.                 Rol     ah, cl
  1136.  
  1137.                 Xchg    bp, dx
  1138.                 Mov     dl, 0CFh
  1139.                 Mov     al, ah
  1140.                 Not     al
  1141.                 Out     dx, al
  1142.                 Mov     dl, 0C5h
  1143.                 Mov     al, [es:di]
  1144.  
  1145.                 Mov     al, 1
  1146.                 Out     dx, al
  1147.                 Mov     [es:di], bl
  1148.                 Shl     al, 1
  1149.                 Out     dx, al
  1150.                 Mov     [es:di], bh
  1151.                 Shl     al, 1
  1152.                 Out     dx, al
  1153.                 Mov     bx, bp
  1154.                 Mov     [es:di], bl
  1155.                 Shl     al, 1
  1156.                 Out     dx, al
  1157.                 Mov     [es:di], bh
  1158.  
  1159.                 Mov     dl, 0CFh
  1160.                 Mov     al, 0FFh
  1161.                 Out     dx, al
  1162.  
  1163. @@Exit:         Mov     dx, 03C5h
  1164.                 Mov     al, 0Fh
  1165.                 Out     dx, al
  1166.  
  1167.                 Pop     es
  1168.                 Ret
  1169.  
  1170. ENDP            WPIX0
  1171. ;-------------------------------------------------------------------------------
  1172. ;Pixel plotter for screen 13.
  1173. PROC            WPIX1
  1174.                 Push    es
  1175.  
  1176.                 Mov     dx, 0A000h
  1177.                 Mov     es, dx
  1178.  
  1179.                 Mul     [word ds:ScrWidth]
  1180.                 Add     ax, [ds:ScrOffset]
  1181.                 Add     di, ax
  1182.  
  1183.                 Shr     cx, 1
  1184.                 Rep     Movsw
  1185.                 Rcl     cx, 1
  1186.                 Rep     Movsb
  1187.  
  1188.                 Pop     es
  1189.                 Ret
  1190. ENDP            WPIX1
  1191. ;-------------------------------------------------------------------------------
  1192. ;Pixel plotter for MODEX.
  1193. PROC            WPIX2
  1194.                 Push    es
  1195.                 Mov     dx, 0A000h
  1196.                 Mov     es, dx
  1197.  
  1198.                 Push    cx
  1199.                 Mul     [word ds:ScrWidth]
  1200.                 Add     ax, [ds:ScrOffset]
  1201.  
  1202.                 Mov     cx, di
  1203.                 Shr     di, 1
  1204.                 Shr     di, 1
  1205.                 Add     di, ax
  1206.  
  1207.                 Mov     dx, 03C4h
  1208.                 Mov     al, 2
  1209.                 Out     dx, al
  1210.                 Dec     ax
  1211.                 And     cl, 3
  1212.                 Shl     al, cl
  1213.  
  1214.                 Pop     cx
  1215.                 Mov     bp, 4
  1216.  
  1217. @@10:           Mov     dx, 03C5h
  1218.                 Out     dx, al
  1219.  
  1220.                 Push    si di cx
  1221.  
  1222.                 Add     cx, 3
  1223.                 Shr     cx, 1
  1224.                 Shr     cx, 1
  1225.  
  1226.                 Mov     dx, cx
  1227.                 Shr     cx, 1
  1228.                 Shr     cx, 1
  1229.                 Shr     cx, 1
  1230.                 Inc     cx
  1231.  
  1232.                 And     dx, 7
  1233.                 Mov     bx, dx
  1234.                 Shl     dx, 1
  1235.                 Add     dx, bx
  1236.                 Neg     dx
  1237.                 Add     dx, offset @@20
  1238.                 Mov     bx, 3
  1239.                 Jmp     dx
  1240.  
  1241. ALIGN 4
  1242. @@30:           REPT    8
  1243.                 Movsb
  1244.                 Add     si, bx
  1245.                 ENDM
  1246. @@20:           Loop    @@30
  1247. @@40:           Pop     cx di si
  1248.                 Inc     si
  1249.  
  1250.                 Shl     al, 1
  1251.                 Cmp     al, 16
  1252.                 Je      @@Sp1
  1253.  
  1254.                 Dec     bp
  1255.                 Loopnz  @@10
  1256.  
  1257.                 Pop     es
  1258.                 Ret
  1259.  
  1260. @@Sp1:          Inc     di
  1261.                 Mov     al, 1
  1262.                 Dec     bp
  1263.                 Loopnz  @@10
  1264.                 Pop     es
  1265.                 Ret
  1266.  
  1267. ENDP            WPIX2
  1268. ;-------------------------------------------------------------------------------
  1269. ALIGN 4
  1270. PROC            GetCode1
  1271. BitsInA         = $+1
  1272. CodeSizeA       = $+2
  1273.                 Mov     cx, 09999h
  1274.                 Mov     si, [ds:BufferOffset]
  1275.                 Xor     dx, dx
  1276.                 Mov     dl, [ds:si-1]
  1277.  
  1278.                 Shl     dx, cl
  1279.                 Mov     dl, dh
  1280.                 Xor     dh, dh
  1281.  
  1282.                 Cmp     ch, cl
  1283.                 Jna     @@NoMore
  1284.  
  1285. @@10:           Lodsb
  1286.                 Dec     bp
  1287.                 Jz      @@FillBlock
  1288. @@30:           Xor     ah, ah
  1289.                 Shl     ax, cl
  1290.                 Or      dx, ax
  1291.                 Add     cl, 8
  1292.                 Cmp     ch, cl
  1293.                 Ja      @@NeedMore
  1294.                 Mov     [ds:BufferOffset], si
  1295.  
  1296. @@NoMore:       Sub     cl, ch
  1297.                 Mov     [byte cs:BitsInA], cl
  1298. CodeMaskA1      =       $+2
  1299.                 And     dx, 09999h
  1300.                 Shl     dx, 1
  1301.                 Mov     [word cs:Code], dx
  1302.                 Ret
  1303. ;-------------------------------------------------------------------------------
  1304. ALIGN 4
  1305. @@NeedMore:     Lodsb
  1306.                 Dec     bp
  1307.                 Jz      @@FillBlock1
  1308. @@70:           Xor     ah, ah
  1309.                 Shl     ax, cl
  1310.                 Or      dx, ax
  1311.                 Add     cl, 8
  1312.  
  1313.                 Mov     [ds:BufferOffset], si
  1314.  
  1315.                 Sub     cl, ch
  1316.                 Mov     [byte cs:BitsInA], cl
  1317. CodeMaskA2      =       $+2
  1318.                 And     dx, 09999h
  1319.                 Shl     dx, 1
  1320.                 Mov     [word cs:Code], dx
  1321.                 Ret
  1322. ;-------------------------------------------------------------------------------
  1323. ALIGN 4
  1324. @@FillBlock1:   Xchg    ax, bp
  1325.                 Xor     ax, ax
  1326.                 Lodsb
  1327.                 Xchg    ax, bp
  1328.                 Mov     [byte ds:si-1], al
  1329.                 Cmp     si, offset DiskBuffer+(DiskIOSize-768)
  1330.                 Jnae    @@70
  1331.                 Call    IOReadFill
  1332.                 Mov     [byte ds:si-1], al
  1333.                 Jmp     @@70
  1334. ;-------------------------------------------------------------------------------
  1335. ALIGN 4
  1336. @@FillBlock:    Xchg    ax, bp
  1337.                 Xor     ax, ax
  1338.                 Lodsb
  1339.                 Xchg    ax, bp
  1340.                 Mov     [byte ds:si-1], al
  1341. @@Check:        Cmp     si, offset DiskBuffer+(DiskIOSize-768)
  1342.                 Jnae    @@30
  1343.                 Call    IOReadFill
  1344.                 Mov     [byte ds:si-1], al
  1345.                 Jmp     @@30
  1346. ;-------------------------------------------------------------------------------
  1347. ENDP            GetCode1
  1348. ;-------------------------------------------------------------------------------
  1349. PROC            IOReadFill
  1350.                 PushaMacro
  1351.  
  1352.                 Mov     cx, offset DiskBuffer+DiskIOSize
  1353.                 Sub     cx, si
  1354.                 Mov     di, offset DiskBuffer
  1355.                 Mov     [ds:BufferOffset], di
  1356.  
  1357.                 Push    cx
  1358.                 Jcxz    @@NoCopy
  1359.                 Test    si, 1
  1360.                 Jz      @@Skip
  1361.                 Movsb
  1362.                 Dec     cx
  1363. @@Skip:         Shr     cx, 1
  1364.                 Rep     Movsw
  1365.                 Rcl     cx, 1
  1366.                 Rep     Movsb
  1367. @@NoCopy:       Pop     ax
  1368.                 Mov     dx, di
  1369.  
  1370.                 Mov     cx, DiskIOSize
  1371.                 Sub     cx, ax
  1372.  
  1373.                 Mov     [ds:BufferLeft], ax
  1374.  
  1375.                 Mov     ah, 03Fh
  1376.                 Mov     bx, [ds:BufferHandle]
  1377.                 Int     021h
  1378.                 Call    CheckError
  1379.  
  1380.                 Add     [ds:BufferLeft], ax
  1381.                 Mov     [byte ds:EOFFlag], 0
  1382.                 Cmp     [word ds:BufferLeft], 0
  1383.                 Jnz     @@Exit
  1384.                 Mov     [byte ds:EOFFlag], -1
  1385. @@Exit:
  1386.                 PopaMacro
  1387.                 Cmp     [byte ds:EOFFlag], 0
  1388.                 Jne     @@GoStopDecode
  1389.                 Cmp     [word cs:ErrorCode], 0
  1390.                 Jne     @@GoStopDecode
  1391.                 Mov     si, [ds:BufferOffset]
  1392.                 Ret
  1393. ;-------------------------------------------------------------------------------
  1394. @@GoStopDecode: Pop     ax
  1395.                 Pop     ax
  1396.                 Cmp     [byte ds:EOFFlag], 0
  1397.                 Je      @@NOEOFInStream
  1398.                 Mov     [word cs:ErrorCode], -1
  1399. @@NOEOFInStream:
  1400.                 Stc
  1401.                 Ret
  1402. ENDP            IOReadFill
  1403. ;-------------------------------------------------------------------------------
  1404. PROC            InitDecode
  1405.  
  1406.                 ;Fetch LZW starting code size.
  1407.                 Call    IOReadByte
  1408.                 Mov     cl, al
  1409.                 Inc     cl
  1410.                 Mov     [byte ds:StartCodeSize], cl
  1411.                 Mov     [byte cs:CodeSizeA], cl
  1412.  
  1413.                 Mov     bx, 1
  1414.                 Shl     bx, cl
  1415.  
  1416.                 Mov     ax, bx
  1417.                 Dec     ax
  1418.                 Mov     [ds:StartCodeMask], ax
  1419.                 Mov     [word cs:CodeMaskA1], ax
  1420.                 Mov     [word cs:CodeMaskA2], ax
  1421.                 Inc     ax
  1422.                 Shl     ax, 1
  1423.                 Mov     [ds:StartMaxCode], ax
  1424.                 Mov     [word cs:MaxCode], ax
  1425.  
  1426.                 Mov     [word cs:ClearCode], bx
  1427.                 Add     bx, 4
  1428.                 Mov     [ds:FirstCode], bx
  1429.                 Mov     [word cs:FirstCde], bx
  1430.                 Mov     [ds:NextCode], bx
  1431.                 Add     bx, offset Suffix
  1432.                 Mov     [word cs:CompareCode], bx
  1433.  
  1434.                 Xor     ax, ax
  1435.                 Mov     [byte cs:BitsInA], al
  1436.  
  1437.                 Mov     ax, [ds:YStart]
  1438.                 Mov     [ds:Y], ax
  1439.  
  1440.                 Mov     ax, [ds:XStart]
  1441.                 Mov     [ds:X], ax
  1442.  
  1443.                 Clc
  1444.                 Ret
  1445. ENDP            InitDecode
  1446. ;-------------------------------------------------------------------------------
  1447. ;Returns the number of 16 byte pages required by the LoadGIF function.
  1448. PUBLIC          LoadGIFMem
  1449. PROC            LoadGIFMem
  1450. P               =       0
  1451.                 Mov     ax, ((RP+15)/16)+1 ;round up
  1452.                 Retf    P*2
  1453. ENDP            LoadGIFMem
  1454. ;-------------------------------------------------------------------------------
  1455. ENDS            GIFCODE
  1456. ;-------------------------------------------------------------------------------
  1457. END
  1458.  
  1459.