sanyo-centered-circle
Sanyo - centered circle
org 0
cpu 8086
COLS equ 72
CENTER EQU 25*288+144
setup:
push cs
pop ds
mov ax,0x0800 ; GREEN
mov es,ax
call circle
hlt
scale_bx:
; in : BL, BH ∈ [-127..127]
; out: BL, BH ∈ [-100..100]
; trashes: AX
; preserves: CX
push cx
; BL -> [-100..100]
mov al, bl
mov cl, 100
imul cl ; AX = BL * 100 (signed)
mov cl, 127
idiv cl ; AL = (BL*100)/127 (truncate toward 0)
mov bl, al
; BH -> [-100..100]
mov al, bh
mov cl, 100
imul cl ; AX = BH * 100
mov cl, 127
idiv cl ; AL = (BH*100)/127
mov bh, al
pop cx
ret
circle:
mov cx,255
.lp:
push cx
mov al,cl
call sin
mov bh,al
mov al,cl
call cos
mov bl,al
call scale_bx ; from -127..127 to -100..100
call dot
pop cx
loop .lp
ret
dot:
call calc_di_dl_for_pixel
or [es:di + CENTER],dl ; set pixel
ret
;;;;; DEZE WERKT OOK MET NEGATIEVE GETALLEN DUS -127..127
;;; ZOU IK HIER OOK EEN LOOKUP TABLE VAN KUNNEN MAKEN?
; bijv BL=x en BH=y en dan een LUT van BX naar DI
; elke DI zal 8x voorkomen omdat telkens 8 pixels dezelfde DI hebben. Dat maakt de LUT wel behoorlijk groot.. maar dat is niet erg.
; BL=-127..127, BH=-127..127 (BH zal nooit onder -100 of boven 100 mogen komen want dat valt buiten beeld)
; en BL heeft dus een schaling van 2 vanwege de aspect ratio.
; en dan ook de sinus en cosinus in een lookup ; met input 0..255 en output -127,127
; de output van die sinus wil je dan nog wel schalen naar -100..100 voordat je er een coordinaat van maakt.
; COLS EQU 72
; in : BL = x (signed 8-bit), BH = y (signed 8-bit)
; out: DI = (y\4)*(4*COLS) + (y%4) + ((2x)\8)*4 (relatief t.o.v. CENTER)
; DL = 2^(7 - ((2x) % 8))
; preserves: CX
; trashes : AX, DX, SI
calc_di_dl_for_pixel:
push cx
; ----- y uit BH: qy=floor(y/4), ry=y&3
mov al, bh
cbw
mov si, ax ; SI = y
mov di, ax
and di, 3 ; DI = ry
mov ax, si
sar ax, 1
sar ax, 1 ; AX = qy
mov si, ax ; SI = qy
; DI += qy*(4*COLS) = qy*288 = (qy<<5) + (qy<<8)
mov ax, si
mov cl, 5
shl ax, cl
add di, ax
mov ax, si
mov cl, 8
shl ax, cl
add di, ax
; ----- x uit BL met aspectratio: x' = 2*x
mov al, bl
cbw ; AX = x (signed)
mov si, ax ; SI = x
; qx2 = floor(x'/8) = floor((2*x)/8) = floor(x/4)
sar ax, 1
sar ax, 1 ; AX = qx2
; rx2 = x' - qx2*8
mov dx, si
shl dx, 1 ; DX = x' = 2*x
mov cx, ax
shl cx, 1
shl cx, 1
shl cx, 1 ; CX = qx2*8
sub dx, cx ; DX = rx2 (0..7)
mov cl, dl ; CL = rx2
and cl, 7
; DL = bitmask 1<<(7-rx2)
mov dl, 128
shr dl, cl
; DI += (qx2*4)
shl ax, 1
shl ax, 1 ; AX = qx2*4
add di, ax
pop cx
ret
; in: AL = hoek 0..255
; uit: AL = sin(hoek) in bereik -128..127 (feitelijk -126..126 op basis van tabel)
; gebruikt: CL, DL, BL, BX
cos:
add al,64
sin:
push cx
push bx
mov cl,al ; deze ontbrak.......
mov al,255
sub al,cl ; 0..255 ipv 255..0
mov dl,al ; dl = hoek
mov cl,6
shr dl,cl ; q = hoek>>6 (0..3)
and al,63 ; i = hoek & 63 (0..63 binnen kwart)
test dl,1 ; odd quadrants (1 of 3)?
jz .no_reflect
mov bl,63
sub bl,al ; i = 63 - i
mov al,bl
.no_reflect:
mov bx, qsin
xlat ; al = amplitude (0..~126)
test dl,2 ; kwadranten 2 en 3 -> negatief
jz .done
neg al
.done:
pop bx
pop cx
ret
qsin: db 0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,59,62,65,67,70,73,75,78,80,82,85,87,89,91,94,96,98,100,102,103,105,107,108,110,112,113,114,116,117,118,119,120,121,122,123,123,124,125,125,126,126,126,126,126
%assign num $-$$
%warning total num
times (180*1024)-num db 0 ; fill up with zeros until file size=180k