www.pudn.com > ctm.zip > CTM.ASM


;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² 
; 
; Totally Crap Linear Texture Mapping Routines !!! 
; 
; by Mandrill (mpersano@yahoo.com) - send me an E-Mail now !!! 
; 
; warning:  the code below sucks very much, and i know it. actually 
;   the whole thing was done at my workplace, while my boss was looking 
;   the other way - thank god i no longer work there ... it really looks 
;   like shit because of the "linear" texture mapping, there is no 
;   perspective correction. you can do what you want with it, i don't care - 
;   and, if you do use them, please don't credit me, i don't to be associated 
;   with such crap. as they say, use at your own risk. 
; 
; against this code: 
; (1) crap code 
; (2) slow, no optimizing 
; (3) no proper clipping 
; (4) low precision 
; (5) lots of floating point (sucks) 
; (6) almost no comments 
; 
; pro this code: 
; (1) free (about nothing else ...) 
; 
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² 
 
        .model small 
        .stack 200h 
        .data 
 
numcoords equ 8         ; a cube has 8 vertexes ... 
numfaces  equ 6         ; ... and 6 faces 
 
cube    equ     73      ; the cube size 
 
FrameBufferSeg dw       ? 
 
 
 
alfa    dd      0.2     ; sorry, angles in floating point ... 
beta    dd      0.4 
gama    dd      0.6 
 
coord   dw      ? 
 
 
xcoord  dd      ? 
ycoord  dd      ? 
zcoord  dd      ? 
 
sin_alfa dw     ? 
cos_alfa dw     ? 
sin_beta dw     ? 
cos_beta dw     ? 
sin_gama dw     ? 
cos_gama dw     ? 
 
xinclow dw      ? 
xinchigh dw     ? 
 
text_u1 dw      ? 
text_v1 dw      ? 
text_u2 dw      ? 
text_v2 dw      ? 
 
uinclow dw      ? 
uinchigh dw     ? 
u1      dw      ? 
u2      dw      ? 
 
vinclow dw      ? 
vinchigh dw     ? 
v1      dw      ? 
v2      dw      ? 
 
ka1      dd      0.015   
ka2      dd      0.025 
ka3      dd      0.012 
k32768        dd      32767.0 
 
slope   dw      200*8     dup (?) 
 
coords  label word 
        dw      -cube, -cube, -cube 
        dw      cube, -cube, -cube 
        dw      cube, -cube, cube 
        dw      -cube, -cube, cube 
        dw      -cube, cube, -cube 
        dw      cube, cube, -cube 
        dw      cube, cube, cube 
         
        dw      -cube, cube, cube 
 
faces   label   word 
        dw 2, 1, 5, 6 
        dw 4, 7, 6, 5 
        dw 6, 7, 3, 2 
        dw 0, 4, 5, 1 
        dw 0, 1, 2, 3 
        dw 0, 3, 7, 4 
 
poly2d  label   word 
        dw      8*8 dup (0) 
 
 
        .code 
        .386 
 
        mov ax, @data 
        mov ds, ax 
 
        mov ax, ss 
        add ax, 20h 
        mov FrameBufferSeg, ax  ; frame buffer segment           
 
        add ax, 64 * (1024 / 16) 
        mov fs, ax              ; texture segment in fs 
         
        mov ax, 13h 
        int 10h          
         
        call mandel             ; calculates texture 
 
        finit 
 
        xor dx, dx 
 
      @wait4esc: 
        fld alfa        ; calculates angle 
        fadd ka1         ; must be replaced by pre-calc table ... 
        fstp alfa 
 
        fld beta        ; calculates angle 
        fadd ka2         ; must be replaced by pre-calc table ... 
        fstp beta 
 
        fld gama        ; calculates angle 
        fadd ka3         ; must be replaced by pre-calc table ... 
        fstp gama 
 
        fld alfa 
        fsincos 
        fmul k32768 
        fistp cos_alfa 
        fmul k32768 
        fistp sin_alfa  ; sin and cos of angles in 1.15 fixed point format 
 
        fld beta 
        fsincos 
        fmul k32768 
        fistp cos_beta 
        fmul k32768 
        fistp sin_beta 
 
        fld gama 
        fsincos 
        fmul k32768 
        fistp cos_gama 
        fmul k32768 
        fistp sin_gama 
 
        call RotateCoords 
 
        mov ax, numfaces 
        mov coord, ax       
 
        call CleanBuffer 
 
      @face: 
        mov di, coord 
        dec di 
        shl di, 3 
        add di, offset faces 
 
        ; FaceShown - checks if you can see the face 
        ; (back-face culling) 
 
        mov si, [di] 
        shl si, 3 
        movsx ecx, word ptr poly2d[si] 
        mov si, [di+2] 
        shl si, 3 
        movsx ebx, word ptr poly2d[si] 
        sub ecx, ebx 
 
        mov si, [di+6] 
        shl si, 3 
        movsx eax, word ptr poly2d[si+2] 
        mov si, [di+2] 
        shl si, 3 
        movsx ebx, word ptr poly2d[si+2] 
        sub eax, ebx 
        imul ecx        ; ecx = a 
        mov ecx, eax 
 
        mov si, [di] 
        shl si, 3 
        movsx ebp, word ptr poly2d[si+2] 
        mov si, [di+2] 
        shl si, 3 
        movsx ebx, word ptr poly2d[si+2] 
        sub ebp, ebx 
 
        mov si, [di+6] 
        shl si, 3 
        movsx eax, word ptr poly2d[si] 
        mov si, [di+2] 
        shl si, 3 
        movsx ebx, word ptr poly2d[si] 
        sub eax, ebx 
        imul ebp        ; ecx = a 
 
        sub ecx, eax 
        jge @notshown 
 
        ; shows face 
        push di 
        call ClearSlope 
        pop di 
 
        mov ax, [di] 
        mov bx, [di + 2] 
 
        mov word ptr text_u1, 0 
        mov word ptr text_v1, 0 
        mov word ptr text_u2, 0 
        mov word ptr text_v2, 255 
 
        call CalcSlope 
 
        mov ax, [di + 2] 
        mov bx, [di + 4] 
 
        mov word ptr text_u1, 0 
        mov word ptr text_v1, 255 
        mov word ptr text_u2, 255 
        mov word ptr text_v2, 255 
 
        call CalcSlope 
 
        mov ax, [di + 4] 
        mov bx, [di + 6] 
 
        mov word ptr text_u1, 255 
        mov word ptr text_v1, 255 
        mov word ptr text_u2, 255 
        mov word ptr text_v2, 0 
 
        call CalcSlope 
 
        mov ax, [di + 6] 
        mov bx, [di] 
 
        mov text_u1, 255 
        mov text_v1, 0 
        mov text_u2, 0 
        mov text_v2, 0 
 
        call CalcSlope 
 
        mov dx, coord 
        add dl, 50 
        call FillShape 
 
      @notshown: 
        dec coord 
        jne @face 
 
        call CopyBuffer 
 
        in al, 60h      ; checks [esc] 
        cmp al, 1 
        je @finis 
        cmp al, 2 
        jne @wait4esc 
        call initcolors 
        jmp @wait4esc 
 
 
      @finis: 
        mov ax, 3       ; back to dos 
        int 10h 
 
        mov ax, 4c00h 
        int 21h 
 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
; 
; CleanBuffer - cleans frame buffer 
;        
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
 
CleanBuffer proc 
        mov ax, FrameBufferSeg 
        mov es, ax 
        xor eax, eax 
        xor di, di 
        mov cx, 16000 
        rep stosd 
        ret 
CleanBuffer endp 
 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
; 
; CopyBuffer - copies frame buffer to screen 
; 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
 
CopyBuffer proc 
        mov ax, 0a000h 
        mov es, ax 
        mov ax, FrameBufferSeg 
        mov ds, ax 
        xor di, di 
        xor si, si 
        mov cx, 16000 
        rep movsd 
 
        mov ax, @data 
        mov ds, ax      ; restore ds 
        ret 
CopyBuffer endp 
 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
; 
; RotateCoords 
; 
; in: sin_alfa, cos_alfa, sin_beta, cos_beta, sin_gama, cos_gama 
;     in 1:15 fixed-point format (*32768) 
; 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
 
RotateCoords proc 
        mov si, offset coords 
        mov di, offset poly2d 
        mov bp, numcoords 
 
      @rc:         
        ; gira ao redor de z 
        movsx ebx, cos_alfa 
        movsx eax, word ptr [si] 
        imul ebx 
        shl eax, 1              ; 16:16 
        mov ebx, eax 
 
        movsx ecx, sin_alfa 
        movsx eax, word ptr [si+2] 
        imul ecx 
        shl eax, 1              ; 16:16 
        sub eax, ebx             
        mov xcoord, eax 
 
        movsx ebx, sin_alfa 
        movsx eax, word ptr [si] 
        imul ebx 
        shl eax, 1              ; 16:16 
        mov ebx, eax 
 
        movsx ecx, cos_alfa 
        movsx eax, word ptr [si+2] 
        imul ecx 
        shl eax, 1 
        add eax, ebx 
        mov ycoord, eax 
 
        ; gira ao redor de y 
        movsx ebx, cos_beta 
        mov eax, xcoord 
        push eax 
        imul ebx 
        shrd eax, edx, 15 
        mov ebx, eax 
 
        movsx ecx, sin_beta 
        movsx eax, word ptr [si+4] 
        imul ecx 
        shl eax, 1 
        sub eax, ebx 
        mov xcoord, eax 
 
        movsx ebx, sin_beta 
        pop eax                 ; eax = xcoord 
        imul ebx 
        shrd eax, edx, 15 
        mov ebx, eax 
 
        movsx ecx, cos_beta 
        movsx eax, word ptr [si+4] 
        imul ecx 
        shl eax, 1 
        add eax, ebx 
        mov zcoord, eax 
 
        ; gira ao redor de x 
        movsx ebx, cos_gama 
        mov eax, ycoord 
        push eax 
        imul ebx 
        shrd eax, edx, 15 
        mov ebx, eax 
 
        movsx ecx, sin_gama 
        mov eax, zcoord 
        imul ecx 
        shrd eax, edx, 15 
        sub eax, ebx 
        mov ycoord, eax 
 
        movsx ebx, sin_gama 
        pop eax                 ; eax = ycoord 
        imul ebx 
        shrd eax, edx, 15 
        mov ebx, eax 
 
        movsx ecx, cos_gama 
        mov eax, zcoord 
        imul ecx 
        shrd eax, edx, 15 
        add eax, ebx 
        mov zcoord, eax 
 
        ; perspective transform 
        mov ax, word ptr xcoord + 2 
        xchg ah, al 
        xor al, al      ; ax *= 256 
        cwd 
        mov bx, word ptr zcoord + 2 
        add bx, 256 
        idiv bx 
        add ax, 160 
        mov [di], ax 
 
        mov ax, word ptr ycoord + 2 
        xchg ah, al 
        xor al, al      ; ax *= 256 
        cwd 
        mov bx, word ptr zcoord + 2 
        add bx, 256 
        idiv bx 
        add ax, 100 
        mov [di+2], ax 
 
        add di, 8 
        add si, 6 
        dec bp 
        je @fim_rc 
        jmp @rc 
      @fim_rc: 
        ret 
RotateCoords endp 
 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
; 
; CalcSlope 
; 
; ax = l1 
; bx = l2 
; 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
 
zcount  dw      ? 
x1      dw      ? 
y1      dw      ? 
x2      dw      ? 
y2      dw      ? 
 
proc CalcSlope 
        push di 
 
        mov di, ax 
        shl di, 3 
        add di, offset poly2d 
        mov si, bx 
        shl si, 3 
        add si, offset poly2d 
 
        mov ax, [di+2]  ; [di + 2] = y1 
        mov cx, [si+2]  ; [si + 2] = y2 
        cmp ax, cx 
        jle @cs1 
 
          xchg ax, cx 
          xchg si, di 
 
          mov bx, text_u1 
          xchg bx, text_u2 
          mov text_u1, bx 
 
          mov bx, text_v1 
          xchg bx, text_v2 
          mov text_v1, bx 
 
        @cs1:             ; di -> l1, si -> l2 
        sub cx, ax      ; cx = counter 
        jz @zero 
 
        mov ax, [di+2] 
        cmp ax, 199 
        jge @zero 
        mov y1, ax 
 
        mov ax, [si+2] 
        cmp ax, 1 
        jle @zero 
        mov y2, ax 
 
        movsx ecx, cx 
 
        mov ax, [di] 
        mov x1, ax 
 
        mov ax, [si] 
        mov x2, ax 
 
        sub ax, x1 
        movsx eax, ax 
        shl eax, 16 
        cdq 
        idiv ecx 
        mov dword ptr xinclow, eax 
 
        mov ax, text_u2 
        sub ax, text_u1 
        shl eax, 16 
        cdq 
        idiv ecx 
        mov dword ptr uinclow, eax 
 
        mov ax, text_v2 
        sub ax, text_v1 
        shl eax, 16 
        cdq 
        idiv ecx 
        mov dword ptr vinclow, eax 
 
        mov ax, y1 
        cmp ax, 0 
        jge @noclip2 
 
        ; x2 - x1     x - x1 
        ;--------- = --------- 
        ; y2 - y1     y - y1 
 
        ; x = (y-y1)*(x2-x1)/(y2-y1) + x1 
 
        mov ax, y1 
        neg ax 
        mov dx, x2 
        sub dx, x1 
        imul dx 
        mov bx, y2 
        sub bx, y1 
        idiv bx 
        add x1, ax 
 
        mov ax, y1 
        neg ax 
        mov dx, text_u2 
        sub dx, text_u1 
        imul dx 
        mov bx, y2 
        sub bx, y1 
        idiv bx 
        add text_u1, ax 
 
        mov ax, y1 
        neg ax 
        mov dx, text_v2 
        sub dx, text_v1 
        imul dx 
        mov bx, y2 
        sub bx, y1 
        idiv bx 
        add text_v1, ax 
 
        xor ax, ax 
        mov y1, ax 
 
        mov cx, y2 
        sub cx, y1 
 
      @noclip2: 
        mov ax, y2 
        cmp ax, 200 
        jl @noclip1 
        mov cx, 199 
        sub cx, y1 
      @noclip1: 
        mov zcount, cx 
 
        mov si, y1 
        shl si, 3 
        add si, offset slope 
 
        xor eax, eax 
        mov ax, x1    ; eax ok 
 
        xor ebx, ebx 
        mov bl, byte ptr text_u1 
        mov bh, byte ptr text_v1 ; ebx ok 
 
        mov cx, vinclow 
        shl ecx, 16 
        mov cx, uinchigh ; ecx ok 
 
        mov bp, uinclow 
        shl ebp, 16 
        mov bp, xinchigh 
 
        xor edx, edx 
        mov dx, vinchigh 
 
        mov di, xinclow 
        shl edi, 16 
 
        ;              ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ 
        ;              ³UPPER 16BIT ³       LOWER 16BIT       ³ 
        ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ´ 
        ; ³    REG     ³  HI WORD   ³  HI BYTE   ³ LOW BYTE   ³ 
        ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ´ 
        ; ³    EAX     ³   U-LOW    ³            X            ³ 
        ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ´ 
        ; ³    EBX     ³   V-LOW    ³     V      ³     U      ³ 
        ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ´ 
        ; ³    ECX     ³ V-INC-LOW  ³          U-INC          ³ 
        ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ´ 
        ; ³    EDX     ³   X-LOW    ³     --     ³   V-INC    ³ 
        ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ´ 
        ; ³    EBP     ³ U-INC-LOW  ³          X-INC          ³ 
        ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ´ 
        ; ³    EDI     ³ X-INC-LOW  ³     --     ³     --     ³ 
        ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ 
 
      @inner_loop: 
        add edx, edi 
        adc eax, ebp 
        adc ebx, ecx 
        adc bh, dl 
 
        cmp word ptr [si], 8000h 
        jne @skp             
        mov [si], ax 
        mov [si+4], bx 
      @skp: 
        mov [si+2], ax 
        mov [si+6], bx 
 
        add si, 8 
        dec zcount 
        jne @inner_loop 
 
      @zero: 
        pop di 
        ret 
CalcSlope endp 
 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
; 
; ClearSlope - clear slope-table 
; 
; i/o: nothing 
; destroys es ! 
; 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
 
ClearSlope proc 
        mov cx, 200 
        mov ax, @data 
        mov es, ax 
        mov di, offset slope 
      @clsl: 
        mov eax, 80008000h 
        stosd 
        xor eax, eax 
        stosd 
        loop @clsl 
        ret 
ClearSlope endp 
 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
; 
; FillShape - fills horizontal spans 
; 
; in: dl = color of the polygon 
; 
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° 
 
 
FillShape proc 
        mov ax, FrameBufferSeg 
        mov es, ax 
 
        xor bp, bp 
 
        mov si, offset slope 
        mov zcount, 200 
 
      @loop: 
        cmp word ptr [si], 8000h 
        jz @skip1        ; no hline to draw 
        mov ax, [si] 
        mov cx, [si+2] 
        xor bx, bx 
        cmp ax, cx 
        jle @skip2 
        xchg ax, cx 
                mov bx, [si+6]  ; redo this ! 
                 shr bx, 8 
                 xor bh, bh 
                mov v1, bx 
                mov bx, [si+4] 
                 shr bx, 8 
                 xor bh, bh 
                mov v2, bx 
                mov bx, [si+6]  ; redo this ! 
                 xor bh, bh 
                mov u1, bx 
                mov bx, [si+4] 
                 xor bh, bh 
                mov u2, bx 
 
                jmp @skip3 
        @skip2: 
                mov bx, [si+4] 
                 shr bx, 8 
                 xor bh, bh 
                mov v1, bx 
                mov bx, [si+6] 
                 shr bx, 8 
                 xor bh, bh 
                mov v2, bx 
 
                mov bx, [si+4] 
                 xor bh, bh 
                mov u1, bx 
                mov bx, [si+6] 
                 xor bh, bh 
                mov u2, bx 
      @skip3: 
        mov di, bp 
        add di, ax 
        sub cx, ax 
 
        jz @skip1 
 
        movsx ecx, cx 
 
        push bp 
        push si 
 
        mov ax, u2 
        sub ax, u1 
        shl eax, 16 
        cdq 
        idiv ecx 
        mov dword ptr uinclow, eax 
 
        mov ax, v2 
        sub ax, v1 
        shl eax, 16 
        cdq 
        idiv ecx 
        mov dword ptr vinclow, eax 
 
        xor si, si         
        mov bp, uinclow 
 
        mov dx, vinclow 
        shl edx, 16 
 
        mov dx, uinchigh 
        mov ah, byte ptr vinchigh 
        xor ebx, ebx 
        mov bl, byte ptr u1 
        mov bh, byte ptr v1 
 
      ; this is it: the INNER LOOP !!! 
      ; lots of fun, try to figure out what's in each register 
         
      @fs: 
        add si, bp 
        adc ebx, edx 
        adc bh, ah 
        mov al, fs:[bx] 
        stosb 
        loop @fs 
 
      @skip_il: 
        pop si 
        pop bp 
      @skip1: 
        add si, 8 
        add bp, 320 
        dec zcount 
        jne @loop 
        ret 
FillShape endp 
 
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² 
 
proc initcolors 
        mov si, offset poly2d 
        mov cx, 8 
 
      @ic: 
        call rand 
        ;shr al, 4 
        mov [si+4], al 
         call rand 
        ; shr al, 4 
         mov [si+6], al 
        add si, 8 
        loop @ic 
        ret 
initcolors endp 
 
MULTIPLIER equ 015a4e35h 
INCREMENT  equ 1 
 
Seed    dd      1 
 
; 
; pseudo-random number generator (number in ax) - ripped from Borland 
; 
 
proc rand 
      ; Seed = MULTIPLIER * Seed + INCREMENT; 
     mov eax, Seed 
     mov ebx, MULTIPLIER 
     imul ebx 
     add eax, INCREMENT 
     mov Seed, eax 
 
      ; return((int)(Seed >> 16) & 0x7fff); 
     shr eax, 16 
     and ax, 7fffh 
     ret 
rand endp 
 
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² 
; 
; Crappy Mandelbrot Set Generator 
; 
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² 
 
        ; int 
x       dw      0 
y       dw      0 
dummy   dw      ? 
 
        ; float 
xl      dd      ? 
yl      dd      ? 
px      dd      ? 
py      dd      ? 
npx     dd      ? 
npy     dd      ? 
 
 
deltax      dd      0.012 
deltay      dd      0.012 
 
k1      dd      -2.00 
k2      dd      -1.50 
 
        i       dw      ? 
        j       dw      ? 
 
        step_xl dw      1 
        step_yl dw      1 
 
mandel  proc 
        mov ax, 0a000h 
        mov es, ax 
 
        ; xl = -2! 
        fld dword ptr [k1] 
        fstp dword ptr [xl] 
 
        ; FOR x = 0 TO 200 
        xor ax, ax 
        mov [x], ax 
next_x: 
        ;  yl = -1.5 
        fld dword ptr [k2] 
        fstp dword ptr [yl] 
 
        ; xl = xl + (3 / 200) 
        fld dword ptr [xl] 
        fadd dword ptr [deltax] 
        fstp dword ptr [xl] 
 
        ; FOR y = 0 TO 200 
        xor ax, ax 
        mov [y], ax 
 
        mov di, [x] 
next_y: 
        ; yl = yl + (3 / 200) 
        fld dword ptr [yl] 
        fadd dword ptr [deltay] 
        fstp dword ptr [yl] 
 
        ; px = xl 
        mov eax, [xl] 
        mov [px], eax 
 
        ;  py = yl 
        mov eax, [yl] 
        mov [py], eax 
 
        ; i% = 0 
        xor ax, ax 
        mov [i], ax 
          
my_while: 
        ;    WHILE (((px * px + py * py) < 4) AND (i% < 128)) 
        fld dword ptr [px] 
        fmul st, st 
        fld dword ptr [py] 
        fmul st, st 
        fadd 
        fistp word ptr [dummy] 
        mov ax, [dummy] 
        cmp ax, 4 
        jg my_wend 
 
        mov ax, [i] 
        cmp ax, 64 
        je my_wend 
 
        ; npx = (px * px - py * py) + xl 
        fld dword ptr [px] 
        fmul st, st 
        fld dword ptr [py] 
        fmul st, st 
        fsub 
        fadd dword ptr [xl] 
        fstp dword ptr [npx] 
 
        ; npy = (2! * px * py) + yl 
        fld dword ptr [px] 
        fmul dword ptr [py] 
        fadd st, st 
        fadd dword ptr [yl] 
        fstp dword ptr [npy] 
 
        ; px = npx 
        mov eax, [npx] 
        mov [px], eax 
 
        ; py = npy 
        mov eax, [npy] 
        mov [py], eax 
 
        ; i% = i% + 1 
        inc [i] 
         
        ; WEND 
        jmp my_while 
my_wend: 
        ; PSET (x, y), i% + 32 
        mov al, byte ptr [i] 
        cmp al, 64 
        jne mw0 
        xor al, al 
        jmp mw1 
mw0: 
        add al, 32 
mw1: 
        mov fs:[di], al 
        mov es:[di], al 
 
        add di, 256 
      
        ; IF (i% = 128) THEN PSET (x, y), 0 
        mov ax, [y] 
        inc ax 
        mov [y], ax 
        cmp ax, 256 
        jne next_y 
         
        ;  NEXT y 
        mov ax, [x] 
        inc ax 
        mov [x], ax 
        cmp ax, 256 
        jne next_x 
 
        ; NEXT x 
inkey: 
        ret 
mandel  endp 
 
        end