; ******************************************** ; Knihovna pro Bresenhamovu interpolaci úseček ; Rozsah souřadnic [0,0] - [287,255] ; vstup: proměnné X0,Y0,X1,Y1 (unsigned int16) ; ******************************************** Interpol lhld X1 ; zajistit, aby bod [X0,Y0] byl vpravo call NegHL ; (lépe se testuje přechod z bajtu) xchg lhld X0 dad d mov a,h ana a jp InterpolNoReverse call NegHL ; dX musí být kladné push h lhld X0 ; prohodit X0<>X1 xchg lhld X1 shld X0 xchg shld X1 lhld Y0 ; prohodit Y0<>Y1 xchg lhld Y1 shld Y0 xchg shld Y1 pop h InterpolNoReverse shld dX ; uložit +dX call NegHL shld dmX ; uložit -dX dad h shld dm2X ; uložit -2dX call NegHL shld d2X ; uložit +2dX lxi h,+64 ; default přírůstek adresy shld YShift ; ve videoram v ose Y lhld Y0 ; výpočet dY a přírůstku v ose Y call NegHL xchg lhld Y1 dad d mov a,h ana a jp InterpolSetY ; úsečka klesá => YShift:=+64 call NegHL push h lxi h,-64 ; úsečka stoupá => YShift:=-64 shld YShift pop h InterpolSetY shld dY ; uložit +dY call NegHL shld dmY ; uložit -dY dad h shld dm2Y ; uložit -2dY call NegHL shld d2Y ; uložit +2dX lhld dY ; vyberu algoritmus dle poměru dX vs dY xchg lhld dX call HLvsDE jc InterpolY ; ************************************* ; Interpolace "ležatých" úseček (dX>dY) ; ************************************* InterpolX lxi h,0 ; uschovat obsah registru SP dad sp shld sp_tmp Call GetPixelAdr ; určit adresu a bitovou masku ; výchozího pixelu lhld dmX ; BC = délka úsečky mov b,h mov c,l xchg ; DE = 2*dY-dX (chybový člen) lhld d2Y dad d xchg lhld PixAdr InterHLoop lda Mask ; vykreslit aktuální pixel xra m mov m,a lda Mask ; posun pixelu doleva rar jnc InterHInitMask mvi a,20h ; a pokud vylezu z bajtu, dcx h ; přejdu do dalšího InterHInitMask sta Mask mov a,d ; test znaménka chybového člene ana a jm InterHNoStep sphl ; realizovat krok v ose Y lhld YShift dad sp xchg ; odečíst 2*dX sphl lhld dm2X dad sp xchg InterHNoStep xchg ; přičíst 2*dY sphl lhld d2Y dad sp xchg mov a,b ; test konce úsečky ora c inx b ; odpočet délky úsečky jnz InterHLoop lhld sp_tmp ; obnovit obsah registru SP sphl ret ; ************************************** ; Interpolace "stojatých" úseček (dY>dX) ; ************************************** InterpolY lxi h,0 ; uschovat obsah registru SP dad sp shld sp_tmp Call GetPixelAdr ; určit adresu a bitovou masku ; výchozího pixelu lhld dmY ; BC = délka úsečky mov b,h mov c,l xchg ; DE = 2*dX-dY (chybový člen) lhld d2X dad d xchg lhld PixAdr InterVLoop lda Mask ; vykreslit aktuální pixel xra m mov m,a sphl ; svislý posun pixelu lhld YShift dad sp mov a,d ; test znaménka chybového člene ana a jm InterVNoStep lda Mask ; realizovat krok v ose X (vždy doleva) rar jnc InterVInitMask mvi a,20h ; pokud vylezu z bajtu, dcx h ; přejdu do dalšího InterVInitMask sta Mask xchg ; odečíst 2*dY sphl lhld dm2Y dad sp xchg InterVNoStep xchg ; přičíst 2*dX sphl lhld d2X dad sp xchg mov a,b ; test konce úsečky ora c inx b ; odpočet délky úsečky jnz InterVLoop lhld sp_tmp ; obnovit obsah registru SP sphl ret ; ********************************************************** ; Pro pixel X0,Y0 vypočte adresu ve videoram a bitovou masku ; ********************************************************** GetPixelAdr lhld Y0 ; svislá složka adresy mvi h,0 ; DE:=64*Y0 dad h dad h dad h dad h dad h dad h xchg lhld X0 ; vodorovná složka adresy mov a,h ; dělení 6-ti se realizuje rar ; předdělením dvěma a výběrem mov a,l ; z tabulky dle indexu 0/2..287/2 rar push psw lxi h,tbXOfset call AddA2HL mov l,m ; načte se řádkový ofset mvi h,0c0h ; a při jednom i bázová adresa videoram dad d shld PixAdr ; uložit do proměnné pop psw ; výpočet bitové masky push psw ; obnovím (ale ještě uschovám) lxi h,tbXMask ; index X0/2 a v CY mám MOD(X0/2) call AddA2HL ; dle indexu načtu bitovou pozici mov e,m ; s krokem 2 do E pop psw ; obnovím MOD(X0/2) mov a,e ; A = 02h/08h/20h jc GetPixelFin rar ; a dle toho MOD(X0/2) dorotuji masku GetPixelFin ; (01h/02h/04h/08h/10h/20h) sta Mask ; a uložit do proměnné ret tbXOfset .db 00h,00h,00h,01h,01h,01h,02h,02h,02h,03h,03h,03h .db 04h,04h,04h,05h,05h,05h,06h,06h,06h,07h,07h,07h .db 08h,08h,08h,09h,09h,09h,0Ah,0Ah,0Ah,0Bh,0Bh,0Bh .db 0Ch,0Ch,0Ch,0Dh,0Dh,0Dh,0Eh,0Eh,0Eh,0Fh,0Fh,0Fh .db 10h,10h,10h,11h,11h,11h,12h,12h,12h,13h,13h,13h .db 14h,14h,14h,15h,15h,15h,16h,16h,16h,17h,17h,17h .db 18h,18h,18h,19h,19h,19h,1Ah,1Ah,1Ah,1Bh,1Bh,1Bh .db 1Ch,1Ch,1Ch,1Dh,1Dh,1Dh,1Eh,1Eh,1Eh,1Fh,1Fh,1Fh .db 20h,20h,20h,21h,21h,21h,22h,22h,22h,23h,23h,23h .db 24h,24h,24h,25h,25h,25h,26h,26h,26h,27h,27h,27h .db 28h,28h,28h,29h,29h,29h,2Ah,2Ah,2Ah,2Bh,2Bh,2Bh .db 2Ch,2Ch,2Ch,2Dh,2Dh,2Dh,2Eh,2Eh,2Eh,2Fh,2Fh,2Fh tbXMask .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h .db 02h,08h,20h,02h,08h,20h,02h,08h,20h,02h,08h,20h ; *************************** ; Vypočte dvojkový doplněk HL ; *************************** NegHL mov a,h ; HL:=-HL cma mov h,a mov a,l cma mov l,a inx h ret ; ************************************ ; Přičte A k HL (16-bitová aritmetika) ; ************************************ AddA2HL add l ; HL:=HL+ACC mov l,a rnc inr h ret ; ********************************* ; Porovná HL vs DE ve stylu CMP/CPI ; ********************************* HLvsDE mov a,h ; HL==DE => příznak Z=1 cmp d ; HL<>DE => příznak Z=0 rnz ; HL>=DE => příznak CY=0 mov a,l ; HL příznak CY=1 cmp e ret