home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / c128 / text / examples.arc / CSARC.A < prev    next >
Text File  |  1989-12-01  |  41KB  |  1,046 lines

  1. ;csarc.asm
  2. ;=====================================================================
  3. ; MS-DOS archive create for CS-DOS             (C)1988 - Ampere Metal
  4. ;=====================================================================
  5.                                   
  6. strend      = $0033               
  7. fretop      = $0035               
  8. status      = $0090               
  9. fnadr       = $00bb               
  10. fnlen       = $00b7               
  11. fnbank      = $00c7               
  12. primm       = $ff7d               
  13. setlfs      = $ffba               
  14. setnam      = $ffbd               
  15. open        = $ffc0               
  16. close       = $ffc3               
  17. chkin       = $ffc6               
  18. chkout      = $ffc9               
  19. clrchn      = $ffcc               
  20. chrin       = $ffcf               
  21. chrout      = $ffd2               
  22. int01       = $1701               
  23. int04       = $1704               
  24. int05       = $1705               
  25. int0a       = $170a               
  26. int0c       = $170c               
  27. int0d       = $170d               
  28. int0e       = $170e               
  29. int16       = $1716               
  30. int17       = $1717               
  31. cl          = $1bf7               
  32.                                   
  33. star        = $1c01               
  34.             dw star
  35.             * = star              
  36.                                   
  37.             dw there,10
  38.             db $9e
  39.             db "(7183)",0
  40. there       dw 0
  41.                                   
  42.             lda $1bff             
  43.             cmp #$13              
  44.             bcs main              
  45.             jsr primm             
  46.             db 13,"Requires CS-DOS 1.4 or higher",13,0
  47.             lda #4                
  48.             jmp int0e             
  49.                                   
  50. main        ldx #2                ;start with %2 and work up
  51.             stx parm              
  52.             jsr int04             ;Make sure at least one
  53.             bcc m0                ;ok
  54.             jsr primm             
  55.             db 13,"MS-DOS archive creator. (C)1988 - Ampere Metal",13
  56.             db "Version 0.01",13
  57.             db 13,"Syntax: csarc[/n] archive[.arc]"
  58.             db " pattern pattern ...",13
  59.             db 0
  60.             lda #0                
  61.             jmp int0e             
  62.                                   
  63. m0          jsr opnarc            ;open output file
  64. m1          ldx parm              
  65.             jsr int16             
  66.             lda cl                
  67.             sta cll               
  68.             bcs m3                
  69. m2          jsr arcit             
  70.             jsr int17             
  71.             bcc m2                
  72. m3          inc parm              
  73.             ldx parm              
  74.             jsr int04             
  75.             bcc m1                
  76.             ldx arcla             
  77.             jsr chkout            
  78.             lda #$1a              
  79.             jsr chrout            
  80.             lda #0                
  81.             jsr chrout            
  82.             jsr clrchn            
  83.             lda #0                
  84.             jmp int0e             
  85.                                   
  86. parm        db 0                ;Current parameter for int16
  87. cll         db 0                ;Save drive from int16
  88. datala      db 0                ;Save data file la
  89. datafl      db 0                ;Data filename length
  90. stat        db 0                ;Save status
  91. bufcnt      db 0                ;How many times buffer got filled. 0=only once
  92. pass        db 0                ;Pass, 0=2, $ff=1
  93. bs          dw 0                ;Temp. buffer size
  94.                                   
  95. ;------------
  96. ; ARC a file
  97. ;------------
  98.                                   
  99. arcit       lda cll               
  100.             sta $1b01             
  101.             lda #":"              
  102.             sta $1b02             
  103.             lda #13               
  104.             jsr chrout            
  105.             ldy #0                
  106. aa0         lda $1b01,y           
  107.             cmp #$a0              
  108.             beq aa1               
  109.             jsr chrout            
  110.             iny                   
  111.             cpy #18               
  112.             bcc aa0               
  113. aa1         cpy #15               
  114.             bcc aa2               
  115.             jsr primm             
  116.             db " <-- Can't ARC it. Name is too long",0
  117.             rts                   
  118.                                   
  119. aa2         lda #","              
  120.             sta $1b01,y           
  121.             iny                   
  122.             lda #"r"              
  123.             sta $1b01,y           
  124.             iny                   
  125.             tya                   
  126.             sta datafl            
  127.             ldx #<$1b01           
  128.             ldy #>$1b01           
  129.             jsr setnam            
  130.             jsr int0a             
  131.             jsr setlfs            
  132.             sta datala            
  133.             jsr open              
  134.             bcc aa3               
  135. dskerr      jsr primm             
  136.             db " <-- Disk Error: ",0
  137.             jsr int0c             
  138.             jmp int0d             
  139.                                   
  140. aa3         jsr lzinit            
  141.             jsr inihdr            
  142.             lda #1                ;1 for codesize at start
  143.             sta lzsize            
  144.             lda #$ff              
  145.             sta store             
  146.             sta bufcnt            
  147.             sta pass              
  148.             sta stat              
  149.             inc stat              
  150.             ldx datala            
  151.             jsr chkin             
  152.             bcs dskerr            
  153.             jsr clrchn            
  154.             jsr primm             
  155.             db " Analyzing,",0
  156. aa4         jsr getbuf            
  157.             bcs aa7               
  158.             sec                   
  159.             lda bp+1              
  160.             sbc strend            
  161.             sta bs                
  162.             lda bp+2              
  163.             sbc strend+1          
  164.             sta bs+1              
  165.             clc                   
  166.             lda usql              
  167.             adc bs                
  168.             sta usql              
  169.             lda usql+1            
  170.             adc bs+1              
  171.             sta usql+1            
  172.             bcc aa5               
  173.             inc usql+2            
  174.             bne aa5               
  175.             inc usql+3            
  176. aa5         inc bufcnt            
  177.             jsr crnbuf            
  178.             jmp aa4               
  179.                                   
  180. aa7         lda datala            
  181.             jsr close             
  182.             jsr flush             ;Flush crunch
  183. mr          jsr getbyt            
  184.             bcc gocr              
  185.             inc lzsize            
  186.             bne mr                
  187.             inc lzsize+1          
  188.             bne mr                
  189.             inc lzsize+2          
  190.             bne mr                
  191.             inc lzsize+3          
  192.             bne mr                ;Always!
  193. gocr        jsr chksiz            ;Check if crunch'd size is bigger
  194.             bcs gcr               ;its not, crunch
  195.             jsr primm             
  196.             db "Storing,",0
  197.             lda #2                
  198.             sta store             
  199.             sta header+1          
  200.             ldy #3                
  201. ty          lda usql,y            
  202.             sta lzsize,y          
  203.             dey                   
  204.             bpl ty                
  205.             jmp ggccrr            
  206.                                   
  207. gcr         jsr primm             
  208.             db "Crunching,",0
  209.             lda #$ff              
  210.             sta store             
  211.             lda #8                
  212.             sta header+1          
  213. ggccrr      jsr wrthdr            
  214.             jsr lzinit            
  215.             inc pass              
  216.             lda bufcnt            ;is file entirely within the buffer?
  217.             beq mor               
  218.             lda #0                
  219.             sta stat              
  220.             lda datafl            
  221.             ldx #<$1b01           
  222.             ldy #>$1b01           
  223.             jsr setnam            
  224.             jsr int0a             
  225.             jsr setlfs            
  226.             sta datala            
  227.             jsr open              
  228. more        jsr getbuf            
  229.             bcs done              
  230. mor         jsr crnbuf            
  231.             jmp more              
  232.                                   
  233. done        lda datala            
  234.             jsr close             
  235.             bit store             
  236.             bpl flshd             
  237.             jsr flush             ;Flush crunch
  238.             ldx arcla             
  239.             jsr chkout            
  240. flsh        jsr getbyt            
  241.             bcc flshd             
  242.             jsr chrout            
  243.             jmp flsh              
  244. flshd       jsr clrchn            
  245.             jsr primm             
  246.             db "Done.",0
  247.             rts                   
  248.                                   
  249. ;-------------------
  250. ; Fill input buffer
  251. ;-------------------
  252.                                   
  253. getbuf      bit stat              
  254.             bvs gb4               
  255.             bmi gb4               
  256.             lda strend            
  257.             sta bp+1              
  258.             lda strend+1          
  259.             sta bp+2              
  260.             ldx datala            
  261.             jsr chkin             
  262. gb0         jsr chrin             ;get byte
  263.             bit pass              
  264.             bpl bbp               
  265.             jsr updcrc            
  266. bbp         sta $ff02             ;Buffer is in bank 1
  267. bp          sta $4000             ;Store it
  268.             lda #0                
  269.             sta $ff00             
  270.             inc bp+1              ;Bump pointer
  271.             bne gb1               
  272.             inc bp+2              
  273. gb1         lda bp+2              ;Buffer full?
  274.             cmp fretop+1          
  275.             bne mbst              
  276.             lda bp+1              
  277.             cmp fretop            
  278.             beq gb3               ;Yes, quit
  279. mbst        bit status            ;EOF?
  280.             bvc gb0               ;No, get more
  281. gb3         lda status            ;Done...save status
  282.             sta stat              
  283.             jsr clrchn            ;And return OK
  284.             clc                   
  285.             rts                   
  286. gb4         sec                   
  287.             rts                   
  288.                                   
  289. ;---------------
  290. ; Crunch buffer
  291. ;---------------
  292.                                   
  293. crnbuf      lda strend            
  294.             sta pp+1              
  295.             lda strend+1          
  296.             sta pp+2              
  297.             bit pass              
  298.             bmi cb0               
  299.             ldx arcla             
  300.             jsr chkout            
  301. cb0         lda pp+2              ;Past end of buffer?
  302.             cmp bp+2              
  303.             bne cb4               ;No, continue
  304.             lda pp+1              
  305.             cmp bp+1              
  306.             bne cb4               
  307.             lda #0                
  308.             sta $ff00             
  309.             jmp clrchn            ;Else done
  310.                                   
  311. cb4         sta $ff02             ;Fetch from bank 0
  312. pp          lda $4000             
  313.             ldy #0                
  314.             sty $ff00             
  315.             bit store             
  316.             bpl cb9               
  317.             jsr crunch            ;Crunch it
  318.             bcc cb1               ;No output, get next
  319. cb2         jsr getbyt            ;Else get crunched output
  320.             bcc cb1               ;No more
  321.             bit pass              
  322.             bmi analyz            
  323.             jsr chrout            ;Send to output
  324.             jmp cb2               
  325.                                   
  326. analyz      inc lzsize            
  327.             bne cb2               
  328.             inc lzsize+1          
  329.             bne cb2               
  330.             inc lzsize+2          
  331.             bne cb2               
  332.             inc lzsize+3          
  333.             jmp cb2               
  334.                                   
  335. cb9         jsr chrout            
  336. cb1         inc pp+1              
  337.             bne cb3               
  338.             inc pp+2              
  339. cb3         jmp cb0               
  340.                                   
  341. ;--------------
  342. ; Write header
  343. ;--------------
  344.                                   
  345. wrthdr      ldx arcla             
  346.             jsr chkout            
  347.             ldy #0                
  348.             sty $ff00             
  349.             ldx #30               
  350.             bit store             
  351.             bmi wh1               
  352.             ldx #29               
  353. wh1         stx wh2+1             
  354. wh0         lda header,y          
  355.             jsr chrout            
  356.             iny                   
  357. wh2         cpy #30               
  358.             bcc wh0               
  359.             jmp clrchn            
  360.                                   
  361. ;---------------------------------------
  362. ; Check if store is smaller than crunch
  363. ;---------------------------------------
  364.                                   
  365. store       db 0                ;flag
  366.                                   
  367. chksiz      lda $1bfc             ;sw1
  368.             cmp #"n"              
  369.             bne chksz             
  370.             clc                   
  371.             rts                   
  372.                                   
  373. chksz       sec                   
  374.             lda usql              
  375.             sbc lzsize            
  376.             lda usql+1            
  377.             sbc lzsize+1          
  378.             lda usql+2            
  379.             sbc lzsize+2          
  380.             lda usql+3            
  381.             sbc lzsize+3          
  382.             rts                   
  383.                                   
  384. ;=========================================================================
  385. ; Misc subroutines for crunch                 (C)1987,1988 - Ampere Metal
  386. ;=========================================================================
  387.                                   
  388. ; Archive entry header
  389.                                   
  390. header      db $1a,8
  391. fname       db 0,0,0,0,0,0,0,0,0,0,0,0,0 ;Filename
  392. lzsize      db 0,0,0,0          ;Crunched size
  393. date        dw 0                ;Date
  394. time        dw 0                ;time
  395. crc         dw 0
  396. usql        dw 0,0              ;Unsqueezed length
  397.             db 12
  398.                                   
  399. arcla       db 0
  400.                                   
  401. ;-------------------
  402. ; Initialize header
  403. ;-------------------
  404.                                   
  405. inihdr      clc                   ;Get date, use CS-DOS date
  406.             jsr $1714             
  407.             stx date              
  408.             sty date+1            
  409.             lda $dc0b             ;Stop clock, get hours
  410.             php                   ;save AM/PM
  411.             sed                   
  412.             ldx #0                
  413.             and #$1f              
  414.             beq ini0              
  415. ini1        inx                   
  416.             sbc #1                
  417.             bne ini1              
  418. ini0        txa                   
  419.             plp                   
  420.             bpl ini2              
  421.             cld                   
  422.             clc                   
  423.             adc #12               
  424.             sed                   
  425. ini2        asl a                 
  426.             asl a                 
  427.             asl a                 
  428.             sta time+1            
  429.             ldx #0                
  430.             lda $dc0a             
  431.             beq ini4              
  432. ini3        inx                   
  433.             sbc #1                
  434.             bne ini3              
  435. ini4        txa                   
  436.             lsr a                 
  437.             lsr a                 
  438.             lsr a                 
  439.             lsr a                 
  440.             ora time+1            
  441.             sta time+1            
  442.             txa                   
  443.             asl a                 
  444.             asl a                 
  445.             asl a                 
  446.             asl a                 
  447.             asl a                 
  448.             sta time              
  449.             ldx #0                
  450.             lda $dc09             
  451.             beq ini6              
  452. ini5        inx                   
  453.             sbc #1                
  454.             bne ini5              
  455. ini6        cld                   
  456.             txa                   
  457.             ora time              
  458.             sta time              
  459.             lda $dc08             
  460.             lda #0                ;Finally zero CRC and lengths
  461.             sta crc               
  462.             sta crc+1             
  463.             ldy #3                
  464. ini7        sta usql,y            
  465.             sta lzsize,y          
  466.             dey                   
  467.             bpl ini7              
  468.             iny                   
  469. ini8        lda $1b03,y           
  470.             cmp #","              
  471.             beq ini9              
  472.             jsr p2a               
  473.             sta fname,y           
  474.             iny                   
  475.             bne ini8              
  476. ini9        lda #0                
  477.             sta fname,y           
  478.             rts                   
  479.                                   
  480. ;------------------------
  481. ; subroutine: Update CRC
  482. ;------------------------
  483.                                   
  484. updcrc      pha                   ;save char
  485.             sty uc+1              ;save .y
  486.             eor crc               
  487.             tay                   
  488.             lda crclo,y           
  489.             eor crc+1             
  490.             sta crc               
  491.             lda crchi,y           
  492.             sta crc+1             
  493. uc          ldy #0                
  494.             pla                   
  495.             rts                   
  496.                                   
  497. crclo       db $00, $c1, $81, $40, $01, $c0, $80, $41
  498.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  499.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  500.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  501.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  502.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  503.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  504.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  505.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  506.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  507.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  508.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  509.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  510.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  511.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  512.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  513.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  514.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  515.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  516.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  517.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  518.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  519.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  520.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  521.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  522.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  523.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  524.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  525.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  526.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  527.             db $00, $c1, $81, $40, $01, $c0, $80, $41
  528.             db $01, $c0, $80, $41, $00, $c1, $81, $40
  529.                                   
  530. crchi       db $00, $c0, $c1, $01, $c3, $03, $02, $c2
  531.             db $c6, $06, $07, $c7, $05, $c5, $c4, $04
  532.             db $cc, $0c, $0d, $cd, $0f, $cf, $ce, $0e
  533.             db $0a, $ca, $cb, $0b, $c9, $09, $08, $c8
  534.             db $d8, $18, $19, $d9, $1b, $db, $da, $1a
  535.             db $1e, $de, $df, $1f, $dd, $1d, $1c, $dc
  536.             db $14, $d4, $d5, $15, $d7, $17, $16, $d6
  537.             db $d2, $12, $13, $d3, $11, $d1, $d0, $10
  538.             db $f0, $30, $31, $f1, $33, $f3, $f2, $32
  539.             db $36, $f6, $f7, $37, $f5, $35, $34, $f4
  540.             db $3c, $fc, $fd, $3d, $ff, $3f, $3e, $fe
  541.             db $fa, $3a, $3b, $fb, $39, $f9, $f8, $38
  542.             db $28, $e8, $e9, $29, $eb, $2b, $2a, $ea
  543.             db $ee, $2e, $2f, $ef, $2d, $ed, $ec, $2c
  544.             db $e4, $24, $25, $e5, $27, $e7, $e6, $26
  545.             db $22, $e2, $e3, $23, $e1, $21, $20, $e0
  546.             db $a0, $60, $61, $a1, $63, $a3, $a2, $62
  547.             db $66, $a6, $a7, $67, $a5, $65, $64, $a4
  548.             db $6c, $ac, $ad, $6d, $af, $6f, $6e, $ae
  549.             db $aa, $6a, $6b, $ab, $69, $a9, $a8, $68
  550.             db $78, $b8, $b9, $79, $bb, $7b, $7a, $ba
  551.             db $be, $7e, $7f, $bf, $7d, $bd, $bc, $7c
  552.             db $b4, $74, $75, $b5, $77, $b7, $b6, $76
  553.             db $72, $b2, $b3, $73, $b1, $71, $70, $b0
  554.             db $50, $90, $91, $51, $93, $53, $52, $92
  555.             db $96, $56, $57, $97, $55, $95, $94, $54
  556.             db $9c, $5c, $5d, $9d, $5f, $9f, $9e, $5e
  557.             db $5a, $9a, $9b, $5b, $99, $59, $58, $98
  558.             db $88, $48, $49, $89, $4b, $8b, $8a, $4a
  559.             db $4e, $8e, $8f, $4f, $8d, $4d, $4c, $8c
  560.             db $44, $84, $85, $45, $87, $47, $46, $86
  561.             db $82, $42, $43, $83, $41, $81, $80, $40
  562.                                   
  563.                                   
  564. ;------------------------------------
  565. ; Subroutine: Open archive for write
  566. ;------------------------------------
  567.                                   
  568. dcolon      db "a:"
  569. arcnam      db "--------.arc  "
  570. dotarc      db ".arc"
  571.                                   
  572. opnarc      ldx #1                
  573.             jsr int04             
  574.             bcc opna1             
  575.             jsr primm             
  576.             .asc 13,"No archive name given",13,0
  577.             lda #0                
  578.             jmp int0e             
  579.                                   
  580. opna1       ldx #0                
  581. opna2       sta arcnam,x          
  582.             inx                   
  583.             cpx #14               
  584.             bcs tolong            
  585.             jsr int05             
  586.             bcc opna2             
  587.             stx fnlen             
  588.             cpx #4                
  589.             bcc addarc            
  590.             ldy #3                
  591. opna3       lda dotarc,y          
  592.             cmp arcnam,x          
  593.             bne addarc            
  594.             dex                   
  595.             dey                   
  596.             bpl opna3             
  597.             bmi opnit             
  598.                                   
  599. tolong      jsr primm             
  600.             db 13,"12 character maximum ARC name",13,0
  601.             lda #3                
  602.             jmp int0e             
  603.                                   
  604. addarc      ldx fnlen             
  605.             ldy #0                
  606. opna4       lda dotarc,y          
  607.             sta arcnam,x          
  608.             inx                   
  609.             iny                   
  610.             cpy #4                
  611.             bcc opna4             
  612.             stx fnlen             
  613. opnit       lda #<arcnam          
  614.             sta fnadr             
  615.             lda #>arcnam          
  616.             sta fnadr+1           
  617.             lda #0                
  618.             sta fnbank            
  619.             jsr int0a             
  620.             sta arcla             
  621.             ldy #1                
  622.             jsr setlfs            
  623.             lda arcnam+1          
  624.             cmp #":"              
  625.             beq oagn              
  626.             inc fnlen             
  627.             inc fnlen             
  628.             jsr int01             
  629.             sta dcolon            
  630.             lda #<dcolon          
  631.             sta fnadr             
  632.             lda #>dcolon          
  633.             sta fnadr+1           
  634. oagn        jsr open              
  635.             bcc opna5             ;ok
  636.             jsr int0c             ;get ds$
  637.             pha                   
  638.             jsr primm             
  639.             db 13,"Error opening archive: ",0
  640.             jsr int0d             
  641.             pla                   
  642.             jmp int0e             
  643.                                   
  644. opna5       rts                   
  645.                                   
  646. ;-----------------------------
  647. ;Convert PETSCII to true ASCII
  648. ;-----------------------------
  649.                                   
  650. p2a         cmp #"a"              ;petscii to ascii
  651.             bcc p2ax              
  652.             cmp #$5b              
  653.             bcs p2a2              
  654.             ora #$20              
  655.             rts                   
  656.                                   ;
  657. p2a2        cmp #$c1              
  658.             bcc p2ax              
  659.             cmp #$db              
  660.             bcs p2ax              
  661.             and #$7f              
  662. p2ax        rts                   
  663.                                   
  664. ;=========================================================================
  665. ; Lempel Zev Crunch routine for CS-DOS       12Feb88 - CS
  666. ;=========================================================================
  667.                                   
  668. max         db 12,$10           ;Max number of bits per code and number of codes high
  669. ext         db $70              ;Extension. 4k bytes
  670. pfx         db $80              ;Prefix.    8k bytes
  671. ncsp        db $a0              ;NextCodeSamePrefix. 8k bytes
  672. nctp        db $c0              ;NextCodeThisPrefix. 8k bytes
  673.                                   
  674. omega       dw 0                ;Current prefix
  675. kay         dw 0                ;Current extension
  676. ncodes      dw 0                ;Number of codes currently in string table
  677. wtcl        dw 0                ;Flag. When to bump code length
  678. codsiz      db 0                ;Number of bits in code
  679. p           db 0                ;Flag
  680. check       dw 0                ;Temp
  681. save        dw 0                ;Temp
  682. temp        dw 0                ;Temp
  683. first       db 0                ;Flag. First char for LZW
  684. prev        dw 0                ;Previous character for pack
  685. count       db 0                ;count for pack
  686. outpos      db 0                ;Position in 'output' for 'codout'
  687. getpos      db 0                ;Position in 'output' for 'get'
  688. outp        db 0                ;Code counter
  689. output      jsr omega             ;Output buffer
  690.             bcc omega+1           
  691.             jsr kay               
  692.             bcc kay+1             
  693.             jmp save              
  694.             pla                   
  695.             pla                   
  696.             jmp check             
  697.             txs                   
  698.             rti                   
  699.             sta $ff00             
  700.             jmp $2e45             
  701.                                   
  702. ;----------------------------
  703. ; Initialize LZW Compression
  704. ;----------------------------
  705.                                   
  706. lzinit      stx temp              
  707.             sty temp+1            
  708.             lda #0                
  709.             sta outpos            
  710.             sta outp              
  711.             sta getpos            
  712.             lda #$80              
  713.             sta output            
  714.             lda #0                
  715.             db $2c
  716. lzini       lda #$40              
  717.             sta first             
  718.             lda #<257             ;First code will be 257
  719.             sta ncodes            
  720.             lda #>257             
  721.             sta ncodes+1          
  722.             lda #9                ;9 bits per code
  723.             sta codsiz            
  724.             lda #>512             ;Bump length when we reach 512 codes
  725.             sta wtcl              
  726.             lda ncsp              ;Clear ncsp array
  727.             jsr lzi1              
  728.             lda nctp              ;And nctp array
  729. lzi1        ldx #32               ;Clear 32 pages
  730.             ldy #0                
  731.             sta lzi0+2            
  732.             lda $ff00             
  733.             pha                   
  734.             lda #$ff              
  735.             sta $ff01             
  736. lzi0        sta $ff00,y           
  737.             iny                   
  738.             bne lzi0              
  739.             inc lzi0+2            
  740.             dex                   
  741.             bne lzi0              
  742.             ldx temp              
  743.             ldy temp+1            
  744.             pla                   
  745.             sta $ff00             
  746.             rts                   
  747.                                   
  748. ;-----------------------------------------------
  749. ; Crunch a byte subroutine: Crunches byte in .a
  750. ;-----------------------------------------------
  751.                                   
  752. crunch      bit first             ;First time here?
  753.             bmi cr00              ;No
  754.             sta omega             ;Yes, w=char
  755.             bvs c0r               
  756.             sta prev              ;prev=char
  757. c0r         lda #0                
  758.             sta omega+1           
  759.             sta count             ;set count for pack=1
  760.             inc count             
  761.             lda #$ff              
  762.             sta first             ;change flag
  763.             lda omega             
  764.             clc                   ;No output
  765.             rts                   
  766.                                   
  767. cr00        sta prev+1            ;Was last char an RL control char?
  768.             lda prev              
  769.             cmp #$90              
  770.             bne cr03              
  771.             lda #0                ;If so, send a zero
  772.             jsr cr02              
  773.             lda #1                
  774.             sta count             
  775. cr03        lda prev+1            ;Now handle this char
  776.             cmp #$90              ;Also a control?
  777.             beq cr06              
  778.                                   
  779. cr05        cmp prev              
  780.             beq cr01              
  781. cr06        sta prev              
  782.             lda count             
  783.             cmp #1                
  784.             bne cpc               
  785.             lda prev              
  786.             jmp cr0               
  787. cr01        inc count             
  788.             lda count             
  789.             cmp #254              
  790.             bcs cpc               
  791.             lda prev              
  792.             rts                   
  793.                                   
  794. cpc         lda #$90              ;already sent char...now send control code
  795.             jsr cr02              
  796.             lda count             ;And count
  797.             jsr cr02              
  798.             lda #1                ;Set new count to 1
  799.             sta count             
  800.             lda prev              
  801. cr0         sta prev              
  802. cr02        sta kay               ;k=char
  803.             lda $ff00             
  804.             pha                   
  805.             sta $ff01             
  806.             stx temp              
  807.             sty temp+1            
  808.             ldx #0                ;For (*,x)
  809.             ldy #1                ;For (*),y
  810.             jsr findwk            ;Look for omega-kay in table
  811.             bcc cr1               ;Didn't find it, gotta output something
  812.             lda check             ;Else w=wk
  813.             sta omega             
  814.             lda check+1           
  815.             sta omega+1           
  816.             clc                   ;no output
  817. crx         ldx temp              
  818.             ldy temp+1            
  819.             pla                   
  820.             sta $ff00             
  821.             lda kay               ;Restore .a
  822.             rts                   
  823.                                   
  824. cr1         ldx omega             ;Output omega
  825.             ldy omega+1           
  826.             jsr codout            
  827.             ldx #0                
  828.             ldy #1                
  829.             jsr addwk             ;Add omega-kay to string table
  830.             lda ncodes+1          ;Table full?
  831.             cmp max+1             
  832.             bcc cr3               ;no. continue
  833.             lda count             ;on a run?
  834.             cmp #1                
  835.             bne cr3               
  836.             lda prev              
  837.             cmp #$90              
  838.             beq cr3               
  839.             ldx kay               ;yes, send k
  840.             ldy #0                
  841.             jsr codout            
  842.             ldx #<256             ;also RESET code
  843.             ldy #>256             
  844.             jmp cr9               
  845. cr8         ldx #0                
  846.             ldy #0                
  847. cr9         jsr codout            
  848.             bne cr8               
  849.             jsr lzini             
  850.             sec                   
  851.             bcs crx               
  852.                                   
  853. cr3         lda #0                ;w=k
  854.             sta omega+1           
  855.             lda kay               
  856.             sta omega             
  857.             sec                   ;Flag output
  858.             bcs crx               
  859.                                   
  860. ;--------------------------------------------------
  861. ; Subroutine: Search for omega-kay in string table
  862. ;--------------------------------------------------
  863.                                   
  864. findwk      lda omega             ;check=nctp(omega)
  865.             asl a                 
  866.             sta save              ;save=omega
  867.             sta $24               
  868.             lda omega+1           
  869.             rol a                 
  870.             sta save+1            
  871.             ora nctp              
  872.             sta $24+1             
  873.             lda ($24,x)           
  874.             sta check             
  875.             lda ($24),y           
  876.             sta check+1           
  877.             lda #0                
  878.             sta p                 
  879. fwk0        lda check+1           ;if w is unextended, then return not found
  880.             bpl fwk1              
  881.             clc                   
  882.             rts                   
  883.                                   
  884. fwk1        ora ext               ;is ext(check)=k?
  885.             sta $24+1             
  886.             lda check             
  887.             sta $24               
  888.             lda ($24,x)           
  889.             cmp kay               
  890.             beq fwk2              ;Yes, found wk
  891.             lda check             ;Else save=check
  892.             asl a                 ;  and check=ncsp(check)
  893.             sta save              
  894.             sta $24               
  895.             lda check+1           
  896.             rol a                 
  897.             sta save+1            
  898.             ora ncsp              
  899.             sta $24+1             
  900.             lda ($24,x)           
  901.             sta check             
  902.             lda ($24),y           
  903.             sta check+1           
  904.             sty p                 
  905.             jmp fwk0              ;And try again
  906.                                   
  907. fwk2        sec                   ;Found it.
  908.             rts                   
  909.                                   
  910. ;-------------------------------------------
  911. ; Subroutine: Add omega-kay to string table
  912. ;-------------------------------------------
  913.                                   
  914. addwk       lda ncodes+1          ;Table full?
  915.             cmp max+1             
  916.             bcc awk0              ;No. Add it
  917.             rts                   
  918.                                   
  919. awk0        lda ncodes            ;ext(ncodes)=kay
  920.             sta $24               
  921.             lda ncodes+1          
  922.             ora ext               
  923.             sta $24+1             
  924.             lda kay               
  925.             sta ($24,x)           
  926.             lda ncodes            ;prefix(ncodes)=omega
  927.             asl a                 
  928.             sta $24               
  929.             lda ncodes+1          
  930.             rol a                 
  931.             ora pfx               
  932.             sta $24+1             
  933.             lda omega             
  934.             sta ($24,x)           
  935.             lda omega+1           
  936.             sta ($24),y           
  937.             lda p                 ;if p then ncsp(save)=ncodes else nctp(save)=ncodes
  938.             bne awk1              
  939.             lda nctp              
  940.             bne awk2              
  941.                                   
  942. awk1        lda ncsp              
  943. awk2        sta $24+1             
  944.             lda save              
  945.             sta $24               
  946.             lda save+1            
  947.             ora $24+1             
  948.             sta $24+1             
  949.             lda ncodes            
  950.             sta ($24,x)           
  951.             lda ncodes+1          
  952.             sta ($24),y           
  953.             lda wtcl              ;Bump codesize if nessessary
  954.             and ncodes+1          
  955.             beq awk9              
  956.             inc codsiz            
  957.             asl wtcl              
  958.             lda #0                
  959.             sta outp              
  960.             lda max               ;But not past max codesize
  961.             cmp codsiz            
  962.             bcs awk9              
  963.             sta codsiz            
  964. awk9        inc ncodes            ;ncodes=ncodes+1
  965.             bne awk3              
  966.             inc ncodes+1          
  967. awk3        rts                   
  968.                                   
  969. ;-------------------------------------------
  970. ; Subroutine: Send LZW code in xy to output
  971. ;-------------------------------------------
  972.                                   
  973. codout      stx $24               
  974.             sty $24+1             
  975.             ldx outpos            
  976.             ldy codsiz            
  977. cdo0        lsr $24+1             
  978.             ror $24               
  979.             ror output,x          
  980.             bcc cdo1              
  981.             inx                   
  982.             lda #$80              
  983.             sta output,x          
  984. cdo1        dey                   
  985.             bne cdo0              
  986.             stx outpos            
  987.             inc outp              
  988.             lda outp              
  989.             and #7                
  990.             rts                   
  991.                                   
  992. getbyt      sty temp              
  993.             ldy getpos            
  994.             cpy outpos            
  995.             bne get0              
  996.             lda output,y          
  997.             sta output            
  998.             ldy #0                
  999.             sty outpos            
  1000.             sty getpos            
  1001.             ldy temp              
  1002.             clc                   
  1003.             rts                   
  1004.                                   
  1005. get0        lda output,y          
  1006.             iny                   
  1007.             sty getpos            
  1008.             ldy temp              
  1009.             sec                   
  1010.             rts                   
  1011.                                   
  1012. ;-------------------------------------------------------
  1013. ; Flush: all done crunching...gotta flush omega and quit
  1014. ;-------------------------------------------------------
  1015.                                   
  1016. flush       stx temp              
  1017.             sty temp+1            
  1018.             bit first             ;Just reset table?
  1019.             bmi fl00              ;No. Flush
  1020.             clc                   
  1021.             rts                   
  1022.                                   
  1023. fl00        lda count             ;are we on a run?
  1024.             cmp #1                
  1025.             beq fl0               ;No...just exit
  1026.             lda #$90              ;Else do sequence
  1027.             jsr cr02              
  1028.             lda count             
  1029.             jsr cr02              
  1030. fl0         ldx omega             ;flush omega
  1031.             ldy omega+1           
  1032.             jsr codout            
  1033.             ldx outpos            ;At byte boundary?
  1034.             lda output,x          
  1035.             cmp #$80              
  1036.             beq atbb              ;yes
  1037. bb          lsr output,x          
  1038.             bcc bb                
  1039.             inc outpos            
  1040. atbb        sec                   ;always some output
  1041.             ldx temp              
  1042.             ldy temp+1            
  1043.             rts                   
  1044.                                   
  1045.             .end                  
  1046.