Author
| whats the best programm for compressing data?
| ARTRAG msx master Posts: 1587 | Posted: January 02 2006, 12:09   | look at this part of the code:
exx ; 5
dec b ; 5
ld a,15 ; 8
and b ; 5
jp nz,waitA ; 11
next b ; 79
1 dec d ; 5
ld a,15 ; 8
and d ; 5
jp nz,waitB ; 11
next d ; 79
2 dec e ; 5
ld a,15 ; 8
and e ; 5
jp nz,waitC ; 11
next e ; 79
3 exx ; 5
AFAI understand this part can be unrolled in 8 independent branches,
in each branch you KNOW how much spare time it rests to reach 447Tcycles
so you can spend it in RLE activities, that unfortunately should be performed
on statisticall basis, in fact, in the worst case you have 10Tcycle spare, in the
best case you have 267Tcycles spare.
I know this is a very hard task, nevertheless the cpu time (in averege) is there
and can be used somehow...
Enjoy
| | AuroraMSX
 msx master Posts: 1227 | Posted: January 03 2006, 12:24   | ARTRAG: Something like this -- Untested, no clock cycles checked, need to fill in the WaitXX -- just to get an idea
; File format:
; stream of (NL pP PP PP .. PP) pattern records, where
; N - nr of repetitions of the pattern
; L - length of pattern
; p - pattern nibble if L is even, 0 if L is odd
; P - pattern nibble
;
; !! CAUTION !! For odd pattern lengths, a 0 nibble is to be inserted at
; the *start* of the pattern! This means that the uncompressed stream
;
; ABABAB CCCCC DEAD 54321
;
; is 'compressed' as:
;
; 32AB 510C 14DEAD 15054321
; ^-----------^-------padding!
;
; (Or as 32AB 510C 190DEAD54321 :-))
; IN:
; (pointer) points to compressed data
; (end) points to first byte after compressed data
;
play:
call startplay
ld c,#A1
playloop:
call getnibble
ld b,a
call getnibble
ld d,a
call getnibble
ld e,a
ld a,(pointer)
or (pointer+1)
ret z
ld a,8
out (#A0),a
inc a
out (c),b
out (#A0),a
inc a
out (c),d
out (#A0),a
inc a
out (c),e
jr playloop
startplay:
exx
jr 4f
getnibble:
exx
; -- read byte ---
ld a,(hl)
bit 0,b
jr z,1f
; -- lo nibble read -> move to next byte in stream
inc hl
jr 2f
; -- hi nibble read -> shift it
1: rra
rra
rra
rra
2: and #0F
; -- decrease pattern length
dec b
jr z,3f
WaitXX ; TODO TODO TODO
jr 5f
; -- end of pattern reached
3: dec c
jr z,4f
; -- start next repetition
ld b,d
ld hl,(pointer)
WaitXX ; TODO TODO TODO
jr 5f
; -- start next pattern
4: ex af,af'
ld a,h ; end of data stream?
cp (end+1)
jr nz,41f
ld a,l
cp (end)
jr nz,41
ld hl,0
jr 42f
41: ld a,(hl)
ld b,a
and #0F
ld c,a
ld a,b
rra
rra
rra
rra
and #0F
ld b,a
ld d,a
ex af,af'
inc hl
42:
ld (pointer),hl
; -- done
5: exx
ret
| | AuroraMSX
 msx master Posts: 1227 | Posted: January 03 2006, 12:29   | As said, no cycles counted, but I'm afraid it's a bit more than 447 :-/
| | ARTRAG msx master Posts: 1587 | Posted: January 03 2006, 12:43   | at first glance you get a 1KHz replayer :-)
actually i do not understand if each cycle can
have the same duration, but i need do study
it more.
at first glance, i would avoid call/ret & i
would resort ixh,ixl,iyh,iyl in order to not to
ram i/o (but the speed depends case by case)
Why not unrolling the branches?
| | AuroraMSX
 msx master Posts: 1227 | Posted: January 03 2006, 13:45   | Quote:
| at first glance you get a 1KHz replayer :-)
|
Heheh, I already thought I'd get an answer like that
Quote:
| Why not unrolling the branches?
|
I doubt it would make much of a difference. | | AuroraMSX
 msx master Posts: 1227 | Posted: January 03 2006, 14:41   | Hm. A first quick T-cycle count reveals that my main loop, excluding the calls to 'getnibble', takes about 160 T-cycles.
That leaves about 80 (79?  ) T-cycles for the 'getnibble' routine, which is currently about 40 instructions long. For that to work, each instruction should take 1 T-cycle (+1 for the wait state - except on msd's machine, which doesn't do wait states anymore  ).'
Conclusion: nice idea, but it ain't gonna work  | | ARTRAG msx master Posts: 1587 | Posted: January 04 2006, 00:53   | On statistical basis, it could work.
beside the other things I told you about the min/max
spare time, consider that if a channel isn't going to change
you can skip also its out (c),x part.
| | ARTRAG msx master Posts: 1587 | Posted: January 04 2006, 11:46   | I was thinking to this:
; 0 => update
; 1 => don't update
;T EDB
;T XXX
.root:
dec b ; 5
jp nz,TXX1 ; 11
TXX0 dec d ; 5
jp nz,TX10 ; 11
TX00 dec e ; 5
jp nz,T100 ; 11
T000 update e,b,d
worksparetimeT000
play e,b,d
loop .root ; tot = 447T
ret
;----------------------
TXX1 dec d ; 5
jp nz,TX11 ; 11
TX01 dec e ; 5
jp nz,T101 ; 11
T001 update b,e
worksparetimeT001 ;
play b,e
loop .root ; tot = 447T
ret
;----------------------
TX10 dec e ; 5
jp nz,T110 ; 11
T010 update e,d
worksparetimeT010 ;
play e,d
loop .root ; tot = 447T
ret
;----------------------
TX11 dec e ; 5
jp nz,T111 ; 11
T011 update e
worksparetimeT011
play e
loop .root ; tot = 447T
ret
;----------------------
T100 update b,d
worksparetimeT100
play b,d
loop .root ; tot = 447T
ret
;----------------------
T101 update b
worksparetimeT101
play b
loop .root ; tot = 447T
ret
;----------------------
T110 update d
worksparetimeT110
play d
loop .root ; tot = 447T
ret
;----------------------
T111 worksparetimeT111
loop .root ; tot = 447T
ret
;----------------------
Where each worksparetimeTXYZ has a different but fixed amount of time processing depending on the branch where it is
The same for play u,v,w and for update u,v,w that spend different amounts of time depending on how many PSG levels changes/are updated.
My idea is that worksparetimeTXYZ decompress in a RAM (circular??) buffer pointed by a pointer register (maybe IX or HL ??), while update u,v,w and play u,v,w read from this buffer with a different pointer register (maybe IY or HL' ??).
In this way you can use the statistically available spare time for decompressing next samples!!!
Now, it is up to the encoder to guarantee that the replayer does not run out of samples, but this extra complexity is outside the Z80, so hopefully, I think could be managed.
| | norakomi msx professional Posts: 861 | Posted: January 05 2006, 15:31   |  me happy | |
| |
| |