NOTICE TEXTE n° 1 (12.17 Ko)
org #9000
jp cru
jp unc
jp ze_ldir
jp i_unc
cru: di
ld a,(IX+4) ; on recupere les parametres (source,dest,insize)
ld l,a
ld a,(ix+5)
ld h,a
ld (inbuffer),hl
ld a,(IX+2)
ld l,a
ld a,(ix+3)
ld h,a
ld (outbuffer),hl ; on se reserve 3 octets pour la taille finale + premier rcode
ld a,(IX+0)
ld l,a
ld a,(ix+1)
ld h,a
ld (insize),hl
ld hl,dictio ; WORD lng ; WORD pos ; ...
ld bc,1024
call razmem
ld hl,0
ld (ptin),hl
ld hl,3
ld (ptout),hl
xor a
ld (rcode),a
ld (curkey),a
ld a,1
ld (cycle),a
ld hl,(ptin)
ld (lptin),hl
ld hl,(inbuffer)
ld de,(ptin)
add hl,de
ld a,(hl)
inc de
ld (ptin),de
ld hl,(outbuffer)
ld de,(ptout)
add hl,de
ld (hl),a
inc de
ld (ptout),de
cruncher:xor a
ld (key),a
ld hl,1
ld (mlkey),hl ; on mettrai pas 1 des fois ?
xor a
chk_keys:ld (curtstkey),a
ld h,0
ld a,(curtstkey)
ld l,a
add hl,hl
add hl,hl
ld de,dictio
add hl,de ; &dictio[curtstkey].lng
ld e,(hl)
inc hl
ld d,(hl)
ld a,e ; controle de la longeur de clef (non nul)
or a
jr nz,okctlkey
ld a,d
or a
jr z,nxtphz
okctlkey:inc hl
ld (lmax),de ; de=longueur max a tester
ld e,(hl)
inc hl
ld d,(hl) ; de=dictio[i].pos
ld hl,(inbuffer)
add hl,de
push hl ; PUSH &inbuffer[dictio[i].pos]
ld hl,(ptin)
ld bc,(inbuffer)
add hl,bc ; hl=&inbuffer[ptin]
push hl ; PUSH
ld hl,(lmax)
ld de,(ptin)
add hl,de
ld de,(insize)
or a
sbc hl,de
jr c,oktst
ld hl,(insize)
ld de,(ptin)
sbc hl,de
ld (lmax),hl ; on en teste moins
oktst: ld bc,0
pop hl
pop de
tstloop: ld a,(de)
cp (hl)
jr nz,notstkey
inc de
inc hl
inc bc
push hl
ld hl,(lmax)
or a ; voir si necessaire
sbc hl,bc
pop hl
jr nz,tstloop
oktstkey:ld hl,(mlkey)
or a
sbc hl,bc ; si ikey>mlkey
jr nc,notstkey
ld (mlkey),bc ; la clef est meilleure, on la garde!
ld a,(curtstkey)
ld (numkey),a
ld a,1
ld (key),a
notstkey:ld a,(curtstkey)
inc a
jr nz,chk_keys ; de 0 a 255
; ecriture dans outbuffer
nxtphz: ld hl,(lptin)
ld (llptin),hl
ld hl,(ptin)
ld (lptin),hl
ld a,(key)
or a
jr z,copydata
copykey: ld hl,(outbuffer)
ld de,(ptout)
add hl,de
ld a,(numkey)
ld (hl),a
inc de
ld (ptout),de
ld hl,(ptin)
ld de,(mlkey)
add hl,de
ld (ptin),hl
ld a,(rcode)
or 1
ld (rcode),a
jr builddic
copydata:ld hl,(inbuffer)
ld de,(ptin)
add hl,de
ld a,(hl)
inc de
ld (ptin),de
ld hl,(outbuffer)
ld de,(ptout)
add hl,de
ld (hl),a
inc de
ld (ptout),de
; construction du dictionnaire !
builddic:ld hl,(ptin)
ld bc,(llptin)
or a
sbc hl,bc
push hl
ld de,dictio
ld h,0
ld a,(curkey)
ld l,a
add hl,hl
add hl,hl
add hl,de
pop de
ld (hl),e
inc hl
ld (hl),d ; dictio[curkey].lng=ptin-llptin
inc hl
ld (hl),c
inc hl
ld (hl),b ; dictio[curkey].pos=llptin
inc a
ld (curkey),a ; curkey=(curkey+1)%256
ld a,(cycle)
inc a
ld (cycle),a
cp 8
jr z,initcycl
ld a,(rcode)
add a,a
ld (rcode),a
jr finaltst
initcycl:ld hl,(outbuffer)
ld de,-9
add hl,de
ld de,(ptout)
add hl,de ; hl=&outbuffer[ptout-9]
ld a,(rcode)
ld (hl),a
inc de
ld (ptout),de ; +1 pour la reservation du suivant !
xor a
ld (rcode),a
ld (cycle),a
finaltst:ld hl,(ptin)
ld de,(insize)
or a
sbc hl,de ; a priori egal au maximum !
jr z,okcomp
jr nc,okcomp ; de toutes facons, le decompacteur est nickel!
ld hl,(ptout)
or a
sbc hl,de
jr z,nocomp
jr nc,nocomp
jp cruncher
nocomp: ei
ret ; misere, on se souviendra de toi jusqu'a la fin des temps
okcomp: ld a,(cycle)
or a
jr z,drop_res
ld d,0
ld e,a
inc e
ld hl,(ptout)
sbc hl,de
ld de,(outbuffer)
add hl,de
push hl ; PUSH emplacement du dernier rcode
ld a,7
ld hl,cycle
sub (hl)
ld b,a
ld a,(rcode)
fdec: add a,a
djnz fdec
pop hl
ld (hl),a
jr fini
drop_res:ld hl,(ptout)
dec hl
ld (ptout),hl
fini: ld de,(insize)
ld hl,(outbuffer)
ld (hl),e
inc hl
ld (hl),d
ld hl,(ptout)
ld (#FFFE),hl ; pratique de savoir la taille du resultat !
ei
ret
razmem: push bc
push de
push hl
dec bc
ld d,0
ld (hl),d
ld d,h
ld e,l
inc de
ldir
pop hl
pop de
pop bc
ret
;####################################################################################
;*** Note Le dictionnaire n'a pas besoin d'etre efface ! ***
i_unc: ld (inbuffer),hl
ld (outbuffer),de
ld de,320
ld (outsize),de
xor a
ld (curkey),a
inc a
ld (cycle),a
ld de,0
ld (lptout),de
jp unc2
unc:
ld a,(ix+2) ; on recupere les parametres (source,dest)
ld l,a
ld a,(ix+3)
ld h,a
ld (inbuffer),hl
ld a,(ix+0) ; on recupere les parametres (source,dest)
ld l,a
ld a,(ix+1)
ld h,a
ld (outbuffer),hl
xor a
ld (curkey),a
inc a
ld (cycle),a
ld hl,0
ld (lptout),hl
ld hl,(inbuffer)
ld e,(hl)
inc hl
ld d,(hl)
ld (outsize),de
inc hl
unc2:
ld a,(hl)
inc hl
add a,a
ld (rcode),a ; rcode<<=1 car premier bit toujours nul
ld a,(hl)
inc hl
ld (inbuffer),hl ; ptin=4
ld hl,(outbuffer)
ld (hl),a
ld hl,1
ld (ptout),hl ; ptout=1
decrunch:ld hl,(lptout)
ld (llptout),hl ; llptout=lptout
ld hl,(ptout)
ld (lptout),hl ; lptout=ptout
ld a,(rcode)
and 128 ; on regarde seulement le bit du haut
or a
jr z,nokey ; 0 -> pas de clef, on copie
ld hl,(inbuffer) ; c'est une clef, allons-y !
ld a,(hl) ; on la lit
inc hl
ld (inbuffer),hl ; ptin++
ld (key),a ; on sauve dans key
ld de,dictio
ld h,0
ld l,a ; hl=key
add hl,hl
add hl,hl
add hl,de ; hl=&dictio[key].lng
ld c,(hl)
inc hl
ld b,(hl)
inc hl ; bc=dictio[key].lng
push hl ; PUSH &dictio[key].pos
ld hl,(ptout)
add hl,bc ; ptout+dictio[key].lng
ld de,(outsize)
or a
sbc hl,de
jr c,okcopy ; si outsize>ptout+dictio[key].lng OK
tronque: ld hl,(outsize) ; sinon on va couper la clef !
ld de,(ptout)
or a
sbc hl,de
ld b,h
ld c,l ; bc=outsize-ptout on ne copie pas tout
okcopy:
pop hl ; POP &dictio[key].pos
push bc ; PUSH longueur de clef a copier
ld e,(hl)
inc hl
ld d,(hl) ; de=dictio[key].pos
ld hl,(outbuffer)
add hl,de
ex de,hl ; de=(uchar*)(outbuffer+dictio[key].pos)
ld hl,(outbuffer)
ld bc,(ptout)
add hl,bc ; hl=(uchar*)(outbuffer+ptout)
ex de,hl ; puisqu'on copie de HL vers DE
pop bc ; POP longueur de clef a copier
push bc ; on voudrait garde la longueur
ldir ; la copie de la clef
pop bc
ld hl,(ptout)
add hl,bc ; on ajoute la longueur a ptout
ld (ptout),hl ; on a copie bc elements
jr bldddic ; on saute au dico
nokey: ld hl,(inbuffer) ; ici on copie betement et mechamment
ld a,(hl) ; outbuffer[ptout]=inbuffer[ptin]
inc hl
ld (inbuffer),hl ; ptin++
ld hl,(outbuffer)
ld bc,(ptout)
add hl,bc
ld (hl),a
inc bc
ld (ptout),bc ; ptout++
bldddic:ld a,(curkey) ; mise a jour du dictionnaire
ld de,dictio
ld h,0
ld l,a ; hl=key
add hl,hl
add hl,hl
add hl,de ; hl=&dictio[curkey].lng
push hl ; PUSH dictio
or a
ld hl,(ptout)
ld de,(llptout)
sbc hl,de ; ptout-llptout est toujours positif !
ex de,hl
pop hl ; POP dictio
ld (hl),e
inc hl
ld (hl),d ; de=ptout-llptout
inc hl ; hl=&dictio[curkey].pos
ld de,(llptout)
ld (hl),e
inc hl
ld (hl),d ; de=llptout (position de la clef)
inc a
ld (curkey),a ; curkey=(curkey+1) % 256
ld a,(cycle)
inc a
ld (cycle),a
cp 8
jr nz,nextbit ; if cycle!=8 alors on passe au bit suivant
newrcode:ld hl,(inbuffer)
ld a,(hl)
ld (rcode),a
inc hl
ld (inbuffer),hl
xor a
ld (cycle),a
jr testfin
nextbit: ld a,(rcode)
add a,a
ld (rcode),a ; rcode<<=1
testfin: ld hl,(outsize)
ld de,(ptout)
or a
sbc hl,de
jr z,enddec
jp nc,decrunch
enddec:
ret
ze_ldir: di
ld a,(IX+4) ; on recupere les parametres (source,dest,insize)
ld l,a
ld a,(ix+5)
ld h,a
ld a,(IX+2)
ld e,a
ld a,(ix+3)
ld d,a
ld a,(IX+0)
ld c,a
ld a,(ix+1)
ld b,a
ldir
ei
ret
;*** Variables ***********************************
key: defb #00
rcode: defb #00
cycle: defb #00
curkey: defb #00
numkey: defb #00
curtstkey: defb #00
mlkey: defw #0000
lmax: defw #0000
ptin: defw #0000
ptout: defw #0000
lptin: defw #0000
lptout: defw #0000
llptin: defw #0000
llptout: defw #0000
insize: defw #0000
outsize: defw #0000
inbuffer: defw #0000
outbuffer: defw #0000
dictio: