01 ; LZW unpacker v1.0 source code 02 ; by WosFilm 1991-12-01 03 .OPT NO LIST 04 ; Input and output filenames at 05 ; lines 9100 and 9105 07 BITS = 10 08 TBL = $9000 09 ;END = TBL+$0300 10 END = TBL+$0900 11 ;END = TBL+$1500 12 ;END = TBL+$2D00 13 ;END = TBL+$5D00 20 CIO = $E456 21 ICCOM = $0342 22 ICBAD = $0344 23 ICBLN = $0348 24 ICAUX = $034A 25 P1 = $80 26 NEXT = $82 30 ; .Start of STRING buffer. 31 ; Max length of STRING=256 bytes! 32 STRING = $0600 0900 *= $5000 1000 RUNAD LDX #$10 ; Open input 1005 LDA #3 ; file 1010 STA ICCOM,X 1015 LDA #IFILE&255 1020 STA ICBAD,X 1025 LDA #IFILE/256 1030 STA ICBAD+1,X 1035 LDA #4 1040 STA ICAUX,X 1045 LDA #0 1050 STA ICAUX+1,X 1055 JSR CIO 1060 LDX #$20 ; Open output 1065 LDA #3 ; file 1070 STA ICCOM,X 1075 LDA #OFILE&255 1080 STA ICBAD,X 1085 LDA #OFILE/256 1090 STA ICBAD+1,X 1095 LDA #8 1100 STA ICAUX,X 1105 LDA #0 1110 STA ICAUX+1,X 1115 JSR CIO 1120 JSR WRITE ; Write TEXT 1125 JSR UNPACK 1130 LDX #$10 ; Close input 1135 LDA #$0C ; file 1140 STA ICCOM,X 1145 JSR CIO 1150 LDX #$20 ; Close output 1155 LDA #$0C ; file 1160 STA ICCOM,X 1165 JSR CIO 1170 RTS ; Return to DOS 2000 UNPACK JSR USETUP 2005 JSR GETC ; Get CODE 2010 LDA CODE+1 ; OLD=CODE 2015 STA OLD+1 2020 LDA CODE 2025 STA OLD 2026 STA CHR ; CHR=CODE 2030 JSR PUTBYT 2035 U10 JSR GETC ; Get code 2040 BCS U13 ; End of file? 2045 LDX #$FF 2050 LDA CODE+1 ; Is CODE a 2055 BEQ U12 ; character? 2060 CMP NXTL+1 ; Has CODE been 2065 BCC U11 ; defined yet? 2070 LDA CODE 2075 CMP NXTL 2080 BCC U11 2085 LDA OLD ; CODE=OLD 2090 STA CODE 2095 LDA OLD+1 2100 STA CODE+1 2105 LDA CHR ; Append CHR 2110 JMP U14 2115 U11 JSR DECODE ; Get character 2120 U14 INX ; appended to CODE 2125 STA STRING,X ; Build STRING 2130 LDA CODE+1 ; End of string? 2135 BNE U11 2140 U12 LDA CODE 2145 INX 2150 STA STRING,X 2155 STX TMP ; Save offset 2160 JSR OUTPUT ; Output STRING 2165 JSR ADDTBL ; Add OLD+CHR 2170 LDA NEW ; to table 2175 STA OLD ; OLD=NEW 2180 LDA NEW+1 2185 STA OLD+1 2190 JMP U10 2195 U13 RTS ; Finished! 2200 DECODE DEC CODE+1 2205 LDA CODE+1 ; P1=CODE*3+TBL 2210 STA P1+1 2215 LDA CODE 2220 STA P1 2225 ASL P1 2230 ROL P1+1 2235 CLC 2240 ADC P1 2245 STA P1 2250 LDA CODE+1 2255 ADC P1+1 2260 STA P1+1 2265 LDA P1 2270 CLC 2275 ADC #TBL&255 2280 STA P1 2285 LDA P1+1 2290 ADC #TBL/256 2295 STA P1+1 2300 LDY #0 2305 LDA (P1),Y ; Get link to 2310 STA CODE ; next CODE 2315 INY 2320 LDA (P1),Y 2325 STA CODE+1 2330 INY 2335 LDA (P1),Y ; Get character 2340 RTS 2365 ADDTBL LDA NEXT+1 ; Reached end 2370 CMP #END/256 ; of table? 2375 BNE A10 2380 LDA NEXT 2385 CMP #END&255 2390 BCC A10 2395 LDA #TBL&255 ; Re-init NEXT 2400 STA NEXT ; and NXTL 2405 LDA #TBL/256 2410 STA NEXT+1 2411 LDA #1 2412 STA NXTL+1 2413 LDA #0 2414 STA NXTL 2415 A10 LDY #0 2420 LDA OLD ; Write link 2425 STA (NEXT),Y 2430 INY 2435 LDA OLD+1 2440 STA (NEXT),Y 2445 INY 2448 LDX TMP+1 ; CHR=first 2449 LDA STRING,X ; character in 2450 STA CHR ; STRING 2455 STA (NEXT),Y ; Append CHR 2460 LDA NEXT ; Increase NEXT 2465 CLC ; and NXTL 2470 ADC #3 2475 BCC A11 2480 INC NEXT+1 2485 A11 STA NEXT 2490 INC NXTL 2491 BNE A12 2492 INC NXTL+1 2493 A12 RTS 2495 USETUP LDA #TBL&255 ; Init NEXT 2500 STA NEXT ; and NXTL 2505 LDA #TBL/256 2510 STA NEXT+1 2515 LDA #1 2520 STA NXTL+1 2525 LDA #0 2530 STA NXTL 2535 RTS 3000 PUTBYT STA OBYTE ; Write byte 3004 LDX #$20 ; to output 3005 LDA #$0B ; file 3010 STA ICCOM,X 3015 LDA #1 3020 STA ICBLN,X 3025 LDA #0 3030 STA ICBLN+1,X 3035 LDA #OBYTE&255 3040 STA ICBAD,X 3045 LDA #OBYTE/256 3050 STA ICBAD+1,X 3055 JSR CIO 3060 INC OUT 3062 BNE P10 3064 INC OUT+1 3066 P10 LDY #54 3068 LDA OUT ; Write current 3070 JSR WRTHEX ; output file 3072 LDY #52 ; length 3074 LDA OUT+1 3076 JSR WRTHEX 3078 RTS 3100 OUTPUT LDA TMP 3101 STA TMP+1 3104 O10 LDX TMP 3105 LDA STRING,X ; Output STRING 3110 JSR PUTBYT 3115 LDA TMP 3120 BEQ O11 3125 DEC TMP 3130 JMP O10 3135 O11 RTS 4000 GETC LDA #0 4001 STA CODE 4002 STA CODE+1 4004 LDA #BITS 4005 STA CNT 4010 G10 ASL BIT1 4015 BCC G11 4020 ROL BIT1 4025 JSR GETBYT ; Get byte to 4026 BCC G11 ; IBYTE 4027 RTS 4030 G11 ASL IBYTE ; Transfer bits 4035 ROL CODE ; from IBYTE to 4040 ROL CODE+1 ; CODE 4045 DEC CNT 4050 BNE G10 4055 LDA CODE ; NEW=CODE 4060 STA NEW 4065 LDA CODE+1 4070 STA NEW+1 4071 CLC 4075 RTS 4110 GETBYT LDX #$10 ; Get byte from 4115 LDA #$07 ; input file 4120 STA ICCOM,X 4125 LDA #IBYTE&255 4130 STA ICBAD,X 4135 LDA #IBYTE/256 4140 STA ICBAD+1,X 4145 LDA #1 4150 STA ICBLN,X 4155 LDA #0 4160 STA ICBLN+1,X 4165 JSR CIO 4170 BMI G21 ; End of file? 4175 INC IN 4180 BNE G20 4185 INC IN+1 4190 G20 LDY #46 4195 LDA IN ; Write how many 4200 JSR WRTHEX ; bytes has been 4205 LDY #44 ; input 4210 LDA IN+1 4215 JSR WRTHEX 4220 CLC 4225 RTS 4230 G21 SEC ; End of file 4235 RTS 4500 WRITE LDA #0 ; Write TEXT 4505 STA CNT 4510 WRT1 LDX CNT 4515 LDA TEXT,X 4520 CMP #$FF 4525 BEQ WRT2 4530 JSR WRTCHA 4535 INC CNT 4540 JMP WRT1 4545 WRT2 RTS 4550 WRTCHA STA TMP ; Write 4555 LDA $E407 ; character to 4560 PHA ; E: 4565 LDA $E406 4570 PHA 4575 LDA TMP 4580 RTS 4600 WRTHEX PHA ; Write hex 4605 AND #$0F ; digits 4610 TAX 4615 LDA HEX,X 4620 STA ($58),Y 4625 DEY 4630 PLA 4635 LSR A 4640 LSR A 4645 LSR A 4650 LSR A 4655 TAX 4660 LDA HEX,X 4665 STA ($58),Y 4670 RTS 9000 CODE .WORD $00 9005 NEW .WORD $00 9010 OLD .WORD $00 9020 CHR .BYTE 0 9025 IBYTE .BYTE 0 9030 OBYTE .BYTE 0 9035 TMP .BYTE 0,0 9040 CNT .BYTE 0 9045 BIT1 .BYTE $80 9050 NXTL .WORD $0100 9055 TEXT .CBYTE "$)Input Output.","$0000 $0000.",$FF 9060 HEX .BYTE $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$21,$22,$23,$24,$25,$26 9065 IN .WORD $00 9070 OUT .WORD $00 9100 ;IFILE .CBYTE "Dn:input.LZW." 9105 ;OFILE .CBYTE "Dn:output.ext." 9900 *= $02E0 9905 .WORD RUNAD