OldComp.cz http://oldcomp.cz/ |
|
ZX7 Dekoder pro i8080 (PMD) http://oldcomp.cz/viewtopic.php?f=47&t=3544 |
Stránka 1 z 1 |
Autor: | mmartinka [ 13.01.2016, 02:37 ] |
Předmět příspěvku: | ZX7 Dekoder pro i8080 (PMD) |
Potřebuji zapakovat grafická data pro PMD o velikosti 1kb. Nejprve jsem použili RLE komprimaci, výsledek byl cca 125 bajtů. Ale raději bych něco mačkavějšího a tak jsem použil ZX7 komprimaci, výsledek 72 bajtů. A to je hezké Adresa source na WOSu http://www.worldofspectrum.org/infoseekid.cgi?id=0027996 Následně jsem přepsal dekoder ZX7 pro i8080, a tím přepsal jako že doslova, prostě jsem nic nevymýšlel. Jenže kód se díky tomu dost protáhl a rozpakování dat něco trvá. Mohla by se nějaká dobrá duše na to podívat a poradit. Aby se nám to trochu zrychlilo. Tady soubor http://mujweb.cz/mmartinka/dzx7_turbo.a80 a výpis: Kód: ; -----------------------------------------------------------------------------
; ZX7 decoder by Einar Saukas & Urusergi ; "Turbo" version (88 bytes, 25% faster) ; ----------------------------------------------------------------------------- ; Parameters: ; HL: source address (compressed data) ; DE: destination address (decompressing) ; ----------------------------------------------------------------------------- .org 0 zaloha .equ 0x0FFE ;zaloha reg A snimek .equ 0x1000 ;rozbalena data data .equ 0x2000 ;komprimovana data lxi h,data lxi d,snimek dzx7_turbo: mvi a,0x80 dzx7t_copy_byte_loop: ;ldi ; copy literal byte sta zaloha mov a,m stax d inx h inx d dcx b lda zaloha dzx7t_main_loop: add a ; check next bit cz dzx7t_load_bits ; no more bits left? jnc dzx7t_copy_byte_loop ; next bit indicates either literal or sequence ; determine number of bits used for length (Elias gamma coding) push d lxi b, 1 mov d,b dzx7t_len_size_loop: inr d add a ; check next bit cz dzx7t_load_bits ; no more bits left? jnc dzx7t_len_size_loop jmp dzx7t_len_value_start ; determine length dzx7t_len_value_loop: add a ; check next bit cz dzx7t_load_bits ; no more bits left? sta zaloha ; rl c mov a,c ral mov c,a ; rl b mov a,b ral mov b,a lda zaloha jc dzx7t_exit ; check end marker dzx7t_len_value_start: dcr d jnz dzx7t_len_value_loop inx b ; adjust length ; determine offset mov e,m ; load offset flag (1 bit) + offset value (7 bits) inx h ; sll e ; opcode for undocumented instruction "SLL E" aka "SLS E" sta zaloha mov a,e ral jc ccr ori 0x01 stc cmc mov e,a lda zaloha jnc dzx7t_offset_end ; if offset flag is set, load 4 extra bits ccr: ori 0x01 ; pridat 1 na konec dokončení SLL mov e,a lda zaloha stc add a ; check next bit cz dzx7t_load_bits ; no more bits left? ; rl d ; insert first bit into D sta zaloha mov a,d ral mov d,a lda zaloha add a ; check next bit cz dzx7t_load_bits ; no more bits left? ; rl d ; insert second bit into D sta zaloha mov a,d ral mov d,a lda zaloha add a ; check next bit cz dzx7t_load_bits ; no more bits left? ; rl d ; insert third bit into D sta zaloha mov a,d ral mov d,a lda zaloha add a ; check next bit cz dzx7t_load_bits ; no more bits left? cmc ; negativní Carry Flag jc dzx7t_offset_end inr d ; equivalent to adding 128 to DE dzx7t_offset_end: ; rr e ; insert inverted fourth bit into E sta zaloha mov a,e rar mov e,a lda zaloha ; copy previous sequence xthl ; store source, restore destination push h ; store destination ; sbc hl, de ; HL = destination - offset - 1 sta zaloha mov a,l sub e mov l,a mov a,h sbb d mov h,a lda zaloha dcx h pop d ; DE = destination ; ldir sta zaloha ldir: mov a,m stax d inx h inx d dcx b mov a,c ora c jnz ldir lda zaloha dzx7t_exit: pop h ; restore source address (compressed data) jnc dzx7t_main_loop jmp end dzx7t_load_bits: jc jecarry mov a,m ; load another group of 8 bits inx h ral ;rla cmc ;vymazat carry flag ret jecarry: mov a,m ; load another group of 8 bits inx h ral ;rla ret |
Autor: | Busy [ 13.01.2016, 15:40 ] |
Předmět příspěvku: | Re: ZX7 Dekoder pro i8080 (PMD) |
Skus k dlzke skomprimovanych dat pripocitat aj dlzku dekomprimacnej rutiny - ci sa vobec vyplati pouzit ZX7. Inak ja by som isiel radsej do toho najkratsieho ZX7 dekomprimatora, ono 25% rozdiel v rychlosti nie je zase az tak vyznamny, skor usetrenych zopar bajtov dlzky by som videl ako dolezitejsich. Btw1. MOV M,r nema 5 taktov Dalsia, taka cisto prakticka vec: Akym kompilerom to kompilujes ? Pokial nejakym co podporuje aj Z80 syntax (napr. AS...) tak by som ten kod nechal v Z80 notacii a kompiloval ho ako pre Z80 procesor. Je to potom prehladnejsie (aspon pre mna) a unifikovanejsie (jednotny assembler pre 8080 aj Z80). Btw2. Ked som v tom vypise zbadal instrukcie ako LDA zaloha, STA zaloha, INX, ORA... tak ma napadlo: Ved on to prepisal do 6502 |
Autor: | mmartinka [ 13.01.2016, 21:56 ] |
Předmět příspěvku: | Re: ZX7 Dekoder pro i8080 (PMD) |
Busy píše: Skus k dlzke skomprimovanych dat pripocitat aj dlzku dekomprimacnej rutiny - ci sa vobec vyplati pouzit ZX7. Tak to už jsem zvážil, vzhledem k tomu že obrázků je víc jak 3-4, tak se mi to vyplatí. Busy píše: Inak ja by som isiel radsej do toho najkratsieho ZX7 dekomprimatora, ono 25% rozdiel v rychlosti nie je zase az tak vyznamny, skor usetrenych zopar bajtov dlzky by som videl ako dolezitejsich. Skusím tu nejratší verzi, ono je dost možné že při převodu na i8080 se rozdíl v rychlosti ještě sníží. Nejvíce mě zlobí neustálé ukládání registru A....kdybych se toho zbavil, bylo by to kratší a rychlejší. Busy píše: Btw1. MOV M,r nema 5 taktov No jo, když já umím jen do pěti Na své testy s programováním používám IDE80, docela jsem si zvykl ať na webovou verzi tak jako program. |
Autor: | rombor [ 13.01.2016, 22:30 ] |
Předmět příspěvku: | Re: ZX7 Dekoder pro i8080 (PMD) |
Ja som svojho času (už sú to 3 roky) portoval Standard rozpakovaciu rutinu ZX7 pre i8080 (PMD 85). Keď ale autor vtedy takmer každý týždeň vydával stále novú zrýchlenú/optimalizovanú verziu, u ktorej sa vzhľadom na zmenený formát výstupných pakovaných dát zmenila aj rozpakovacia rutina, prestalo ma baviť stále to upravovať. Takže to, čo mám, je zrejme s aktuálnou verziu ZX7 nekompatibilné. Rozpakovacie rutiny ZX7 majú jeden neduh. Neumožňujú, aby sa zdrojová a cieľová oblasť 1:1 prekrývali. Teda, aby som to objasnil. Na ZX Spectre bolo/je zvykom, že väčšina komprimačných programov pripravila rutinu a výsledný spakovaný blok tak, že Rutina+Spakované dáta sa nahrali na cieľovú adresu a od nej sa spustilo rozpakovanie. Rozpakovacia rutina preniesla svoje jadro na predom určené miesto a data sa rozpakovali a zaberali pôvodnú oblasť, ako pred spakovaním. Podstatné pri rozpakovávaní je to, aby sa ukazatele na zdrojové a cieľové dáta nikdy v priebehu rozpakovania nestretli (až na koniec), a teda aby nikdy nedošlo k prepisu zdrojových dát pri zápise cieľových. Táto filozofia sa pri rozpakovacích rutinách ZX7 nedá aplikovať, pretože vždy dôjde spoľahlivo k poškodeniu posledných 2 až 6 bytov. Pri ZX7 by sa teda zdrojový a cieľový blok nemali prekrývať. Toto som trochu rozoberal tu: http://www.oldcomp.cz/viewtopic.php?f=37&t=433 |
Autor: | mmartinka [ 20.01.2016, 20:09 ] |
Předmět příspěvku: | Re: ZX7 Dekoder pro i8080 (PMD) |
Zkusil jsem tu standard verzi a je to o cca 6% pomalejší (v mém podaní ) než turbo. přikládám: Kód: :
; ----------------------------------------------------------------------------- ; ZX7 decoder by Einar Saukas, Antonio Villena & Metalbrain ; "Standard" version ( i8080 / 160 bytes ) ; ----------------------------------------------------------------------------- ; Parameters: ; HL: source address (compressed data) ; DE: destination address (decompressing) ; ----------------------------------------------------------------------------- zaloha .equ 0x0FFE ;zaloha reg A snimek .equ 0x1000 ;rozbalena data data .equ 0x2000 ;komprimovana data DZX7_STANDARD: MVI a,0x80 DZX7S_COPY_BYTE_LOOP: STA zaloha MOV a,m ; ldi - copy literal byte STAX d INX h INX d DCX b LDA zaloha DZX7S_MAIN_LOOP: CALL dzx7s_next_bit JNC dzx7s_copy_byte_loop ; next bit indicates either literal or sequence ; determine number of bits used for length (Elias gamma coding) PUSH d LXI b,0 MOV d,b DZX7S_LEN_SIZE_LOOP: INR d CALL dzx7s_next_bit JNC dzx7s_len_size_loop ; determine length DZX7S_LEN_VALUE_LOOP: CNC dzx7s_next_bit STA zaloha MOV a,c ; rl c RAL MOV c,a MOV a,b ; rl b RAL MOV b,a LDA zaloha JC dzx7s_exit ; check end marker DCR d JNZ dzx7s_len_value_loop INX b ; adjust length ; determine offset MOV e,m ; load offset flag (1 bit) + offset value (7 bits) INX h STA zaloha ; sll e - opcode for undocumented instruction "SLL E" aka "SLS E" MOV a,e RAL JC cf ORI 0x01 STC CMC MOV e,a LDA zaloha JNC dzx7s_offset_end ; if offset flag is set, load 4 extra bits CF: ORI 0x01 ; pridat 1 na konec dokončení SLL MOV e,a STC LDA zaloha MVI d,0x10 ; bit marker to load 4 bits DZX7S_RLD_NEXT_BIT: CALL dzx7s_next_bit STA zaloha ; rl d - insert first bit into D MOV a,d RAL MOV d,a LDA zaloha JNC dzx7s_rld_next_bit ; repeat 4 times, until bit marker is out INR d ; add 128 to DE STA zaloha MOV a,d ;srl d - retrieve fourth bit from D STC CMC RAR MOV d,a LDA zaloha DZX7S_OFFSET_END: STA zaloha MOV a,e ; rr e - insert inverted fourth bit into E RAR MOV e,a ; copy previous sequence XTHL ; store source, restore destination PUSH h ; store destination ; sbc hl, de ; HL = destination - offset - 1 MOV a,l SUB e MOV l,a MOV a,h SBB d MOV h,a DCX h POP d ; DE = destination LDIR: MOV a,m STAX d INX h INX d DCX b MOV a,c ORA c JNZ ldir LDA zaloha DZX7S_EXIT: POP h ; restore source address (compressed data) JNC dzx7s_main_loop JMP end DZX7S_NEXT_BIT: ADD a ; check next bit RNZ ; no more bits left? JC cf1 MOV a,m ; load another group of 8 bits INX h RAL CMC ;vymazat carry flag RET CF1: MOV a,m ; load another group of 8 bits INX h RAL ;rla RET END: |
Autor: | rombor [ 28.01.2016, 22:04 ] |
Předmět příspěvku: | Re: ZX7 Dekoder pro i8080 (PMD) |
Keďže sám potrebujem pakovať nejaké dáta a potreboval som vyskúšať aj ZX7, ako jednu z alternatív, tak som oprášil to moje snaženie spred troch rokov. Tu je čistá Standard rutina pre i8080. Nie sú tam teda tie špeciality potrebné na rozpakovanie "On the place", ktoré som už popisoval. Kód: ;-----------------------------------------------------------------------------
; ZX7 decoder by Einar Saukas ; "Standard" version ; i8080 port Roman Borik (108 bytov) ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Parameters: ; HL: source address (compressed data) ; DE: destination address (decompressing) ;------------------------------------------------------------------------------ dzx7: mvi a,80h sta next_bit+1 copy_byte_loop: mov a,m ; copy literal byte stax d inx h inx d main_loop: call next_bit jnc copy_byte_loop ; next bit indicates either literal or sequence ; determine number of bits used for length (Elias gamma coding) push d ; destination onto stack lxi b,0 ; zero length mov d,b length_size_loop: inr d call next_bit jnc length_size_loop ; determine length length_value_loop: cnc next_bit mov a,c ral mov c,a mov a,b ral mov b,a jc exit ; check end marker dcr d jnz length_value_loop inx b ; adjust length ; determine offset mov a,m ; load offset flag (1 bit) + offset value (7 bits) inx h stc ral mov e,a jnc offset_end ; if offset flag is set, load 4 extra bits mvi d,0E0h ; bit marker to load 4 bits rld_next_bit: call next_bit mov a,d ; insert next bit into D ral mov d,a jc rld_next_bit ; repeat 4 times, until bit marker is out inr d ; add 128 to DE mov a,d ; retrieve fourth bit from D rar mov d,a offset_end: mov a,e ; insert fourth bit into E rar mov e,a ; copy previous sequence xthl ; store source, restore destination push h ; store destination mov a,l sbb e mov l,a mov a,h sbb d mov h,a ; HL = destination - offset - 1 pop d ; DE = destination, BC = length copy_loop: mov a,m stax d inx h inx d dcx b mov a,b ora c jnz copy_loop exit: pop h ; restore source address (compressed data) jnc main_loop ret next_bit: mvi a,0 add a ; check next bit sta next_bit+1 rnz ; no more bits left? mov a,m ; load another group of 8 bits inx h ral sta next_bit+1 ret ;----------------------------------------------------------------------------- dzx7_len equ $-dzx7 ;----------------------------------------------------------------------------- |
Stránka 1 z 1 | Všechny časy jsou v UTC + 1 hodina [ Letní čas ] |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |