01 ; LZW packer v1.0 source code 02 ; by WosFilm 1991-12-01 03 .OPT NO LIST 05 ; Input and output filenames at 06 ; lines 9100 and 9105 07 BITS = 10 ; #bits in CODE 08 TBL = $9000 ; Stard of table 09 ;END = TBL+$0300 ; 9-bit CODEs 10 END = TBL+$0900 ; 10 bits 11 ;END = TBL+$1500 ; 11 bits 12 ;END = TBL+$2D00 ; 12 bits 13 ;END = TBL+$5D00 ; 13 bits 20 CIO = $E456 21 ICCOM = $0342 22 ICBAD = $0344 23 ICBLN = $0348 24 ICAUX = $034A 25 P1 = $80 26 NEXT = $82 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 PACK 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 PACK JSR PSETUP ; Init NEXT 2005 JSR GETCHA ; Get byte from 2010 STA STRING ; input file 2015 P10 LDA #0 ; 0=1 byte in 2020 STA SFLG ; STRING 2025 P11 JSR GETCHA ; Get byte 2030 BCS P13 ; End of file? 2035 STA CHR 2040 JSR SEARCH ; Is STRING+CHR 2045 BCS P12 ; in the table? 2050 LDA #1 ; 1=2 or more 2055 STA SFLG ; bytes in STRING 2060 LDA CHR ; STRING=STRING+ 2065 STA STRING ; CHR 2070 JMP P11 2075 P12 JSR OUTPUT ; Output CODE 2080 JSR ADDTBL ; Add STRING +CHR 2085 LDA CHR ; to string table 2090 STA STRING ; STRING=CHR 2091 STA CODE ; CODE=CHR 2092 LDA #0 2093 STA CODE+1 2095 JMP P10 2096 P13 JSR OUTPUT ; Output CODE 2097 P14 LDA BIT1 ; Output all 2098 LSR A ; bits left 2099 BCS P15 2100 INC CNT 2101 JSR O10 2102 JMP P14 2105 P15 RTS ; Finished! 2110 SEARCH LDA SFLG ; Is STRING a 2115 BNE S10 ; code? 2120 LDA #0 ; STRING is a 2125 STA LINK ; character 2130 STA CODE+1 2135 LDA #1 2140 STA LINK+1 2145 LDA STRING 2150 STA CODE 2155 LDA #TBL&255 ; Init P1 to 2160 STA P1 ; start of 2165 LDA #TBL/256 ; string table 2170 STA P1+1 2175 S10 LDA P1+1 ; Has P1 reached 2180 CMP NEXT+1 ; the end of the 2185 BNE S11 ; string table? 2190 LDA P1 2195 CMP NEXT 2200 BCC S11 2205 RTS ; No match found 2210 S11 LDY #0 ; Search for CODE 2215 LDA CODE ; in the string 2220 CMP (P1),Y ; table 2225 BNE S12 2230 INY 2235 LDA CODE+1 2240 CMP (P1),Y 2245 BNE S12 2250 INY 2255 LDA CHR ; Is CHR 2260 CMP (P1),Y ; appended to 2265 BNE S12 ; CODE? 2270 LDA LINK ; CODE=LINK 2275 STA CODE 2280 LDA LINK+1 2285 STA CODE+1 2290 JSR INCP1 2295 CLC ; Match found 2300 RTS 2305 S12 JSR INCP1 2310 JMP S10 2315 INCP1 LDA P1 ; Increase P1 2320 CLC ; to point to 2325 ADC #3 ; next link 2330 BCC I01 2335 INC P1+1 2340 I01 STA P1 2345 INC LINK ; Increase LINK 2350 BNE I02 2355 INC LINK+1 2360 I02 RTS 2365 ADDTBL LDA NEXT+1 ; Is end of 2370 CMP #END/256 ; string table 2375 BNE A10 ; reached? 2380 LDA NEXT 2385 CMP #END&255 2390 BCC A10 2395 LDA #TBL&255 ; Reinit NEXT 2400 STA NEXT ; (new string 2405 LDA #TBL/256 ; table) 2410 STA NEXT+1 2415 A10 LDY #0 2420 LDA CODE ; Write a link 2425 STA (NEXT),Y ; to STRING 2430 INY 2435 LDA CODE+1 2440 STA (NEXT),Y 2445 INY 2450 LDA CHR ; Append CHR to 2455 STA (NEXT),Y ; STRING 2460 LDA NEXT ; Increase NEXT 2465 CLC ; pointer 2470 ADC #3 2475 BCC A11 2480 INC NEXT+1 2485 A11 STA NEXT 2490 RTS 2495 PSETUP LDA #TBL&255 2500 STA NEXT 2505 LDA #TBL/256 2510 STA NEXT+1 2515 RTS 3000 GETCHA LDX #$10 ; Get byte from 3005 LDA #7 ; input file 3010 STA ICCOM,X 3015 LDA #1 3020 STA ICBLN,X 3025 LDA #0 3030 STA ICBLN+1,X 3035 LDA #BYTE&255 3040 STA ICBAD,X 3045 LDA #BYTE/256 3050 STA ICBAD+1,X 3055 JSR CIO 3060 BMI G11 ; End of file? 3061 INC IN 3062 BNE G10 3063 INC IN+1 3065 G10 LDY #46 ; Write how many 3070 LDA IN ; bytes has been 3075 JSR WRTHEX ; input 3080 LDY #44 3085 LDA IN+1 3090 JSR WRTHEX 3095 LDA BYTE 3100 CLC 3105 RTS 3110 G11 SEC ; End of file 3115 RTS 4000 OUTPUT LDA CODE 4005 STA TMP 4010 LDA CODE+1 4015 STA TMP+1 4020 LDX #BITS-8 4025 O01 JSR ROTATE ; Transfer CODE 4030 DEX ; to high bits 4035 BNE O01 ; of TMP 4050 LDA #BITS 4055 STA CNT 4060 O10 ASL TMP+2 ; Transfer TMP 4065 ROL TMP ; bit by bit to 4070 ROL OBYTE ; output byte 4075 ASL BIT1 4080 BCC O11 ; Is OBYTE 4085 ROL BIT1 ; filled? 4090 JSR PUTCHA ; Output OBYTE 4095 O11 DEC CNT 4100 BNE O10 4105 RTS 4110 PUTCHA LDX #$20 ; Write OBYTE 4115 LDA #$0B ; to output 4120 STA ICCOM,X ; file 4125 LDA #OBYTE&255 4130 STA ICBAD,X 4135 LDA #OBYTE/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 INC OUT 4175 BNE O12 4180 INC OUT+1 4185 O12 LDY #54 4190 LDA OUT ; Write current 4195 JSR WRTHEX ; length of 4200 LDY #52 ; output file 4205 LDA OUT+1 4210 JSR WRTHEX 4215 RTS 4320 ROTATE LSR TMP+1 4325 ROR TMP 4330 ROR TMP+2 4335 RTS 4500 WRITE LDA #0 ; Write TEXT 4505 STA CNT 4510 WRT01 LDX CNT 4515 LDA TEXT,X 4520 CMP #$FF 4525 BEQ WRT02 4530 JSR WRTCHA 4535 INC CNT 4540 JMP WRT01 4545 WRT02 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 LINK .WORD $00 9010 SFLG .BYTE 0 9015 STRING .BYTE 0 9020 CHR .BYTE 0 9025 BYTE .BYTE 0 9030 OBYTE .BYTE 0 9035 TMP .BYTE 0,0,0 9040 CNT .BYTE 0 9045 BIT1 .BYTE 1 9050 TEXT .CBYTE "$)Input Output.","$0000 $0000.",$FF 9055 IN .WORD $00 9060 OUT .WORD $00 9065 HEX .BYTE $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$21,$22,$23,$24,$25,$26 9100 ;IFILE .CBYTE "Dn:input.ext." 9105 ;OFILE .CBYTE "Dn:output.LZW." 9900 *= $02E0 9905 .WORD RUNAD