home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Commodore Disk User Volume 3 #7
/
Commodore_Disk_User_Vol.3_7_1990_-.d64
/
compression
(
.txt
)
< prev
next >
Wrap
Commodore BASIC
|
2022-10-26
|
7KB
|
349 lines
10 ;**********************************
15 ;* data compression *
20 ;*--------------------------------*
25 ;* n.higgins 1989 *
30 ;*--------------------------------*
35 ;* method: run length encoding *
40 ;* using : marker(count,char) *
45 ;**********************************
50 ;* first call the routines at:- *
55 ;* *
60 ;* compress - sys $c000 *
65 ;* decomper - sys $c0b8 *
70 ;* *
75 ;* now enter the monitor and use *
80 ;* the command (mc110 c170) to *
85 ;* see the results. *
90 ;**********************************
95 ;
100 ;
105 ;
110 ;
115 ;--------------------------------
120 ;pointer to the end of the data
125 ;to be compressed.
130 ;--------------------------------
135 ;
140 textend=text+16
145 ;
150 marker=$ef
155 datpnt=$fb
160 stopnt=$fd
165 ;
170 ;
175 *=49152
180 ;
185 ;
190 ;--------------------------------
195 ;set pointer to data to be
200 ;compressed (text)
205 ;set pointer to store the
210 ;compressed data (storage)
215 ;--------------------------------
220 ;
225 compress lda #<text
230 sta datpnt
235 lda #>text
240 sta datpnt+1
245 lda #<storage
250 sta stopnt
255 lda #>storage
260 sta stopnt+1
265 ;
270 ;
275 ;---------------------------------
280 ;set (endflag) to zero
285 ;set (count) to 1
290 ;get byte/is carry set?
295 ;yes:goto [e]
300 ;store byte
305 ;[a] get next byte/is carry set?
310 ;yes:goto [e]
315 ;is byte same as previous?
320 ;no :goto [c]
325 ;yes:increment (count)
330 ;is (count) =0
335 ;yes:output marker($ff,char)
340 ;set (count)=1/goto [a]
345 ;no :goto [a]
350 ;---------------------------------
355 ;
360 ldy #0
365 sty endflag
370 lda #1
375 sta count
380 jsr getbyte
385 bcs finish
390 sta character
395 ;
400 again jsr getbyte
405 bcs loop
410 cmp character
415 bne loop2
420 continue inc count
425 bne again
430 lda #marker
435 jsr putbyte
440 lda #$ff
445 jsr putbyte
450 lda character
455 jsr putbyte
460 jmp continue
465 ;
470 ;
475 ;--------------------------------
480 ;[c] store byte
485 ;get previous byte/is it a marker?
490 ;yes:goto [f]
495 ;no :is (count) <4
500 ;yes:goto [g]
505 ;no :goto [f]
510 ;--------------------------------
515 ;
520 loop2 sta store
525 loop lda character
530 cmp #marker
535 beq loop9
540 lda count
545 cmp #4
550 bcc loop5
555 ;
560 ;
565 ;--------------------------------
570 ;[f] output marker(count,char)
575 ;--------------------------------
580 ;
585 loop9 lda #marker
590 jsr putbyte
595 lda count
600 jsr putbyte
605 lda character
610 jsr putbyte
615 ;
620 ;
625 ;--------------------------------
630 ;[d] check flag/is it set?
635 ;yes:goto [e]
640 ;no :get stored byte
645 ;set (count) to 1/goto [a]
650 ;--------------------------------
655 ;
660 loop6 lda endflag
665 bmi finish
670 lda store
675 sta character
680 lda #1
685 sta count
690 jmp again
695 ;
700 ;
705 ;--------------------------------
710 ;[g] output char
715 ;decrement (count)
720 ;is (count)=0
725 ;yes:goto [d]
730 ;no :goto [g]
735 ;--------------------------------
740 ;
745 loop5 lda character
750 jsr putbyte
755 dec count
760 beq loop6
765 jmp loop5
770 ;
775 ;
780 ;--------------------------------
785 ;[e] when finished we store the
790 ;end address+1 of the compacted
795 ;data for the decompress routine.
800 ;--------------------------------
805 ;
810 finish lda stopnt
815 sta compend
820 lda stopnt+1
825 sta compend+1
830 rts
835 ;
840 ;
845 ;--------------------------------
850 ;check if reached the end of data
855 ;no :get next byte/clr carry/return
860 ;yes:set (endflag)/set carry/return
865 ;--------------------------------
870 ;
875 getbyte lda datpnt
880 cmp #<textend
885 bne loop12
890 lda datpnt+1
895 cmp #>textend
900 bne loop12
905 lda #$ff
910 sta endflag
915 sec
920 rts
925 ;
930 loop12 lda (datpnt),y
935 inc datpnt
940 bne loop14
945 inc datpnt+1
950 loop14 clc
955 rts
960 ;
965 ;
970 ;---------------------------------
975 ;output byte
980 ;---------------------------------
985 ;
990 putbyte sta (stopnt),y
995 inc stopnt
1000 bne loop15
1005 inc stopnt+1
1010 loop15 rts
1015 ;
1020 ;
1025 ;
1030 ;*********************************
1035 ;* decompress routine *
1040 ;*********************************
1045 ;* this must be called after the *
1050 ;* compression routine,it will *
1055 ;* restore the compressed data *
1060 ;* at 'storage' back to its *
1065 ;* original values and place it *
1070 ;* at 'newtext'. *
1075 ;*********************************
1080 ;* you can then compare both *
1085 ;* 'text' & 'newtext' to see *
1090 ;* that they match. *
1095 ;*********************************
1100 ;
1105 ;
1110 ;-------------------------------
1115 ;set pointers to start of
1120 ;compressed data (storage) &
1125 ;decompressed data (newtext)
1130 ;-------------------------------
1135 ;
1140 decomper lda #<storage
1145 sta datpnt
1150 lda #>storage
1155 sta datpnt+1
1160 lda #<newtext
1165 sta stopnt
1170 lda #>newtext
1175 sta stopnt+1
1180 ;
1185 ;-------------------------------
1190 ;get compressed data
1195 ;is it a marker?
1200 ;no:output it/increment (newtext)
1205 ;increment pointer (storage)
1210 ;is it end of comp.data?
1215 ;no:go back get next byte
1220 ;yes:exit
1225 ;-------------------------------
1230 ;
1235 ldy #0
1240 reloop lda (datpnt),y
1245 cmp #marker
1250 beq loop40
1255 sta (stopnt),y
1260 jsr pnt1
1265 loop50 jsr pnt2
1270 lda datpnt
1275 cmp compend
1280 bne reloop
1285 lda datpnt+1
1290 cmp compend+1
1295 bne reloop
1300 rts
1305 ;
1310 ;-------------------------------
1315 ;if a marker is found then
1320 ;put (count) in x
1325 ;put (char) in a
1330 ;output (char) until x=0
1335 ;-------------------------------
1340 ;
1345 loop40 jsr pnt2
1350 lda (datpnt),y
1355 tax
1360 jsr pnt2
1365 lda (datpnt),y
1370 loop42 sta (stopnt),y
1375 jsr pnt1
1380 dex
1385 bne loop42
1390 beq loop50
1395 ;
1400 ;
1405 ;-----------------------------
1410 ;increment pointers
1415 ;-----------------------------
1420 ;
1425 pnt1 inc stopnt
1430 bne loop43
1435 inc stopnt+1
1440 loop43 rts
1445 ;
1450 pnt2 inc datpnt
1455 bne loop44
1460 inc datpnt+1
1465 loop44 rts
1470 ;
1475 ;
1480 ;
1485 ;
1490 ;
1495 compend byt 0,0
1500 store byt 0
1505 count byt 0
1510 character byt 0
1515 endflag byt 0
1520 ;
1525 ;--------------------------------
1530 ;these are the bytes to be
1535 ;compressed...you can use your
1540 ;own instead but if you extend
1545 ;its size then make sure you
1550 ;alter the other storage area's
1555 ;and pointers accordingly...
1560 ;--------------------------------
1565 ;
1570 text ;
1575 ;
1580 byt $01,$01,$01,$01
1585 byt $01,$01,$01,$01
1590 byt $01,$01,$01,$01
1595 byt $01,$01,$ef,$01
1600 ;
1605 ;--------------------------------
1610 ;the bytes above are compressed
1615 ;and stored here..............
1620 ;(3 bytes/for every 1 in text)
1625 ;--------------------------------
1630 storage ;
1635 ;
1640 byt 0,0,0,0,0,0,0,0
1645 byt 0,0,0,0,0,0,0,0
1650 byt 0,0,0,0,0,0,0,0
1655 byt 0,0,0,0,0,0,0,0
1660 byt 0,0,0,0,0,0,0,0
1665 byt 0,0,0,0,0,0,0,0
1670 ;
1675 ;--------------------------------
1680 ;the compressed data in 'storage'
1685 ;is decompressed & placed here...
1690 ;--------------------------------
1695 ;
1700 newtext ;
1705 ;
1710 byt 0,0,0,0,0,0,0,0
1715 byt 0,0,0,0,0,0,0,0
1720 byt 0,0,0,0,0,0,0,0
1725 byt 0,0,0,0,0,0,0,0
1730 byt 0,0,0,0,0,0,0,0
1735 byt 0,0,0,0,0,0,0,0
1740 ;
1745 ;