; ********************************************************** ; demonstrace kreslicích rutin obrázků pro PMD-85 ; a možnosti akcelerace ; ********************************************************** ; show1 - 3986T 100% (základní kreslicí rutina) ; show2 - 2678T 67% (rozklad místo vnitřní smyčky FOR/NEXT) ; show3 - 2252T 56% (proměnná vnější FOR/NEXT v registru) ; show4 - 1944T 49% (minimalizace instrukcí DAD) ; show5 - 1457T 37% (čtení dat pomocí POP) ; ********************************************************** ; datum: 15.7.2017 ; ********************************************************** uartdat .equ 01eh ; datový registr UARTu uartcwr .equ 01fh ; řídicí registr UARTu ctc1ch .equ 05dh ; kanál 1 čítače 8253 ctccwr .equ 05fh ; řídicí registr čítače 8253 prtout .equ 8500h ; tisk ASCII znaku (procedura BIOSu) .org 0 ; začátek překladu mvi a,1ch ; vymazat obrazovku call prtout mvi a,76h ; kanál 1 čítače 8253 out ctccwr ; nastavit na 1200Hz mvi a,0abh ; pro časování UARTu out ctc1ch mvi a,006h out ctc1ch mvi a,080h ; inicializace UARTu out uartcwr out uartcwr rrc out uartcwr mvi a,0fdh ; nastavit 10,8msec out uartcwr mvi a,23h ; povolit časování via TX out uartcwr lxi h,0c105h ; výchozí pozice postaviček lxi d,8 ; na startovní čáře nahoře shld height1 ; v rastru 8 znaků na šířku dad d shld height2 dad d shld height3 dad d shld height4 dad d shld height5 ; ********************************* ; multitasking pěti animačních úloh ; ********************************* init: mvi a,0ffh ; inicializace systému úloh sta tasknr ; (stav před první úlohou) nexttask: out uartdat ; nastartovat okno 10,8msec lda tasknr ; posunout se na další úlohu inr a sta tasknr doevents: in uartcwr ; uplynul čas přidělený úloze? ani 4 jnz nexttask ; pokud ano, předat systémový ; čas další úloze v pořadí lda tasknr ; podle čísla aktivní úlohy add a mov e,a mvi d,0 lxi h,task ; a tabulky začátků úloh dad d mov a,m ; načíst adresu začátku úlohy inx h mov h,m mov l,a lxi d,64 pchl ; a předat úloze strojový čas tasknr: .db 0 ; číslo aktivní úlohy ; adresy začátků úloh task: .dw show1,show2,show3,show4,show5,init ; ********************************************* ; základní kreslicí procedura bez optimalizace ; - předloha adresována dvěma smyčkami FOR/NEXT ; - registr SP není využíván pro data ; - řazení dat předlohy je lineární ; (není minimalizován počet instrukcí DAD) ; ********************************************* ; délka: 34 bajtů ; taktů: 3986 ; ********************************************* show1: lhld height1 ; načíst pozici postavičky dad d ; posun o mikrořádek dolů shld height1 ; uložit pozici postavičky lxi d,i_man ; adresa předlohy postavičky mvi c,64-3 ; konstanta posunu v ose Y ; během kreslení do videoram mvi a,23 ; 23 mikrořádků na výšku loop11: push psw ; uschovat počitadlo mikrořádků mvi b,3 ; 3 znaky (18 pix) na šířku loop12: ldax d ; načíst bajt předlohy inx d ; a posun na další bajt mov m,a ; zapsat do videoram inr l ; a posun na pozici vpravo dcr b ; byl tento bajt poslední? jnz loop12 ; ne, další bajt mikrořádku dad b ; ano => další mikrořádek pop psw ; obnovit počitadlo mikrořádků dcr a ; snížit o jeden jnz loop11 ; nebyl poslední => next jmp doevents ; byl poslední => konec ; ********************************************* ; kreslicí procedura - optimalizace č.1 ; - předloha adresována jednou smyčkou FOR/NEXT ; - registr SP není využíván pro data ; - řazení dat předlohy je lineární ; (není minimalizován počet instrukcí DAD) ; ********************************************* ; délka: 36 bajtů ; taktů: 2678 ; ********************************************* show2: lhld height2 ; načíst pozici postavičky dad d ; posun o mikrořádek dolů shld height2 ; uložit pozici postavičky lxi d,i_man ; adresa předlohy postavičky lxi b,64-2 ; konstanta posunu v ose Y ; během kreslení do videoram mvi a,23 ; 23 mikrořádků na výšku loop2: push psw ; uschovat počitadlo mikrořádků ldax d ; načíst bajt předlohy inx d ; a posun na další bajt mov m,a ; zapsat do videoram (X=0) inr l ; a posun na pozici vpravo ldax d ; načíst bajt předlohy inx d ; a posun na další bajt mov m,a ; zapsat do videoram (X=1) inr l ; a posun na pozici vpravo ldax d ; načíst bajt předlohy inx d ; a posun na další bajt mov m,a ; zapsat do videoram (X=2) dad b ; další mikrořádek a X=0 pop psw ; obnovit počitadlo mikrořádků dcr a ; snížit o jeden jnz loop2 ; nebyl poslední => next jmp doevents ; byl poslední => konec ; ********************************************* ; kreslicí procedura - optimalizace č.2 ; - předloha adresována jednou smyčkou FOR/NEXT ; - registr SP je využíván pro data ; (řídicí proměnná FOR/NEXT je v registru) ; - řazení dat předlohy je lineární ; (není minimalizován počet instrukcí DAD) ; ********************************************* ; délka: 45 bajtů ; taktů: 2252 ; ********************************************* show3: lxi h,0 ; uschovat obsah registru SP dad sp shld sp_temp lhld height3 ; načíst pozici postavičky dad d ; posun o mikrořádek dolů shld height3 ; uložit pozici postavičky lxi d,i_man ; adresa předlohy postavičky lxi sp,64-2 ; konstanta posunu v ose Y ; během kreslení do videoram mvi b,23 ; 23 mikrořádků na výšku loop3: ldax d ; načíst bajt předlohy inx d ; a posun na další bajt mov m,a ; zapsat do videoram (X=0) inr l ; a posun na pozici vpravo ldax d ; načíst bajt předlohy inx d ; a posun na další bajt mov m,a ; zapsat do videoram (X=1) inr l ; a posun na pozici vpravo ldax d ; načíst bajt předlohy inx d ; a posun na další bajt mov m,a ; zapsat do videoram (X=2) dad sp ; další mikrořádek a X=0 dcr b ; snížit počitadlo mikrořádků jnz loop3 ; nebyl poslední => next lhld sp_temp ; jinak obnovit obsah sphl ; registru SP jmp doevents ; a konec ; ********************************************* ; kreslicí procedura - optimalizace č.3 ; - předloha adresována jednou smyčkou FOR/NEXT ; - registr SP je využíván pro data ; (řídicí proměnná FOR/NEXT je v registru) ; - řazení dat předlohy je nelineární ; (je minimalizován počet instrukcí DAD) ; ********************************************* ; délka: 105 bajtů ; taktů: 1944 ; ********************************************* show4: lxi h,0 ; uschovat obsah registru SP dad sp shld sp_temp lhld height4 ; načíst pozici postavičky dad d ; posun o mikrořádek dolů shld height4 ; uložit pozici postavičky lxi d,i_mano ; adresa předlohy postavičky lxi sp,-(19*64) ; konstanta posunu v ose Y ; během kreslení do videoram mvi b,4 ; celkem 4 průchody obrázkem loop4: ldax d ; načíst bajt předlohy inx d ; a posun na další bajt mov m,a ; zápis do videoram (X=0,Y=0) inr l ; posun doprava ldax d inx d mov m,a ; zápis do videoram (X=1,Y=0) inr l ; posun doprava ldax d inx d mov m,a ; zápis do videoram (X=2,Y=0) inr h ; posun dolů o 4 mikrořádky ldax d inx d mov m,a ; zápis do videoram (X=2,Y=4) dcr l ; posun doleva ldax d inx d mov m,a ; zápis do videoram (X=1,Y=4) dcr l ; posun doleva ldax d inx d mov m,a ; zápis do videoram (X=0,Y=4) inr h ; posun dolů o 4 mikrořádky ldax d inx d mov m,a ; zápis do videoram (X=0,Y=8) inr l ; posun doprava ldax d inx d mov m,a ; zápis do videoram (X=1,Y=8) inr l ; posun doprava ldax d inx d mov m,a ; zápis do videoram (X=2,Y=8) inr h ; posun dolů o 4 mikrořádky ldax d inx d mov m,a ; zápis do videoram (X=2,Y=12) dcr l ; posun doleva ldax d inx d mov m,a ; zápis do videoram (X=1,Y=12) dcr l ; posun doleva ldax d inx d mov m,a ; zápis do videoram (X=0,Y=12) inr h ; posun dolů o 4 mikrořádky ldax d inx d mov m,a ; zápis do videoram (X=0,Y=16) inr l ; posun doprava ldax d inx d mov m,a ; zápis do videoram (X=1,Y=16) inr l ; posun doprava ldax d inx d mov m,a ; zápis do videoram (X=2,Y=16) inr h ; posun dolů o 4 mikrořádky ldax d inx d mov m,a ; zápis do videoram (X=2,Y=20) dcr l ; posun doleva ldax d inx d mov m,a ; zápis do videoram (X=1,Y=20) dcr l ; posun doleva ldax d inx d mov m,a ; zápis do videoram (X=0,Y=20) dad sp ; posun vlevo nahoru (dY=-19) dcr b ; snížit počitadlo mikrořádků jnz loop4 ; nebyl poslední => next lhld sp_temp ; jinak obnovit obsah sphl ; registru SP jmp doevents ; a konec ; ********************************************* ; kreslicí procedura - optimalizace č.4 ; - předloha adresována jednou smyčkou FOR/NEXT ; - registr SP je využíván pro data ; (řídicí proměnná FOR/NEXT je v registru) ; - řazení dat předlohy je nelineární ; (je minimalizován počet instrukcí DAD) ; - načítání předlohy realizováno instrukcí POP ; ********************************************* ; délka: 82bajtů ; taktů: 1457 ; ********************************************* show5: lxi h,0 ; uschovat obsah registru SP dad sp shld sp_temp lhld height5 ; načíst pozici postavičky dad d ; posun o mikrořádek dolů shld height5 ; uložit pozici postavičky mov a,h ; test výškové pozice nejrychlejší cpi 0f8h ; postavičky na cílovou pásku rnc ; jsem v cíli => konec programu lxi d,-(19*64) ; konstanta posunu v ose Y lxi sp,i_mano ; adresa předlohy postavičky mvi a,4 ; celkem 4 průchody obrázkem loop5: pop b ; načíst první dva bajty mov m,c ; zápis do videoram (X=0,Y=0) inr l mov m,b ; zápis do videoram (X=1,Y=0) inr l pop b ; načíst další dva bajty mov m,c ; zápis do videoram (X=2,Y=0) inr h mov m,b ; zápis do videoram (X=2,Y=4) dcr l pop b ; načíst další dva bajty mov m,c ; zápis do videoram (X=1,Y=4) dcr l mov m,b ; zápis do videoram (X=0,Y=4) inr h pop b ; načíst další dva bajty mov m,c ; zápis do videoram (X=0,Y=8) inr l mov m,b ; zápis do videoram (X=1,Y=8) inr l pop b ; načíst další dva bajty mov m,c ; zápis do videoram (X=2,Y=8) inr h mov m,b ; zápis do videoram (X=2,Y=12) dcr l pop b ; načíst další dva bajty mov m,c ; zápis do videoram (X=1,Y=12) dcr l mov m,b ; zápis do videoram (X=0,Y=12) inr h pop b ; načíst další dva bajty mov m,c ; zápis do videoram (X=0,Y=16) inr l mov m,b ; zápis do videoram (X=1,Y=16) inr l pop b ; načíst další dva bajty mov m,c ; zápis do videoram (X=2,Y=16) inr h mov m,b ; zápis do videoram (X=2,Y=20) dcr l pop b ; načíst další dva bajty mov m,c ; zápis do videoram (X=1,Y=20) dcr l mov m,b ; zápis do videoram (X=0,Y=20) dad d ; posun vlevo nahoru (dY=-19) dcr a ; snížit počitadlo mikrořádků jnz loop5 ; nebyl poslední => next lhld sp_temp ; jinak obnovit obsah sphl ; registru SP jmp doevents ; a konec ; ************************************** ; neoptimalizovaný obrázek s lineárním ; řazením dat zleva doprava a shora dolů ; ************************************** i_man: .db 000h,000h,000h ; 0. mikrořádek .db 000h,03eh,000h ; 1. mikrořádek .db 020h,03fh,003h ; 2. mikrořádek .db 030h,03fh,007h ; 3. mikrořádek .db 038h,03fh,00fh ; 4. mikrořádek .db 038h,000h,00eh ; 5. mikrořádek .db 018h,022h,00ch ; 6. mikrořádek .db 018h,022h,00ch ; 7. mikrořádek .db 018h,022h,00ch ; 8. mikrořádek .db 038h,000h,00eh ; 9. mikrořádek .db 030h,03fh,007h ; 10. mikrořádek .db 028h,03fh,00bh ; 11. mikrořádek .db 024h,000h,012h ; 12. mikrořádek .db 014h,000h,014h ; 13. mikrořádek .db 03eh,023h,03fh ; 14. mikrořádek .db 012h,000h,024h ; 15. mikrořádek .db 01ch,000h,01ch ; 16. mikrořádek .db 010h,01ch,004h ; 17. mikrořádek .db 030h,03fh,007h ; 18. mikrořádek .db 018h,014h,00ch ; 19. mikrořádek .db 034h,037h,017h ; 20. mikrořádek .db 028h,02ah,00ah ; 21. mikrořádek .db 000h,015h,001h ; 22. mikrořádek ; ********************************************* ; optimalizovaný obrázek s křížovým řazením dat ; se střídáním vodorovného směru a zápisem ; mikrořádků v pořadí 0-4-8-12-16-20 ; ********************************************* i_mano: .db 000h,000h,000h ; 0. mikrořádek --> .db 00fh,03fh,038h ; 4. mikrořádek <-- .db 018h,022h,00ch ; 8. mikrořádek --> .db 012h,000h,024h ; 12. mikrořádek <-- .db 01ch,000h,01ch ; 16. mikrořádek --> .db 017h,037h,034h ; 20. mikrořádek <-- .db 000h,03eh,000h ; 1. mikrořádek --> .db 00eh,000h,038h ; 5. mikrořádek <-- .db 038h,000h,00eh ; 9. mikrořádek --> .db 014h,000h,014h ; 13. mikrořádek <-- .db 010h,01ch,004h ; 17. mikrořádek --> .db 00ah,02ah,028h ; 21. mikrořádek <-- .db 020h,03fh,003h ; 2. mikrořádek --> .db 00ch,022h,018h ; 6. mikrořádek <-- .db 030h,03fh,007h ; 10. mikrořádek --> .db 03fh,023h,03eh ; 14. mikrořádek <-- .db 030h,03fh,007h ; 18. mikrořádek --> .db 001h,015h,000h ; 22. mikrořádek <-- .db 030h,03fh,007h ; 3. mikrořádek --> .db 00ch,022h,018h ; 7. mikrořádek <-- .db 028h,03fh,00bh ; 11. mikrořádek --> .db 024h,000h,012h ; 15. mikrořádek <-- .db 018h,014h,00ch ; 19. mikrořádek --> .db 000h,000h,000h ; 23. mikrořádek <-- ; ******** ; proměnné ; ******** sp_temp .dw 0 ; odkládací místo pro SP height1 .dw 0 ; pozice postavičky #1 height2 .dw 0 ; pozice postavičky #2 height3 .dw 0 ; pozice postavičky #3 height4 .dw 0 ; pozice postavičky #4 height5 .dw 0 ; pozice postavičky #5 .end