comment +

For compilation  use:

Turbo  Assembler 2.02
tasm /m2 modex.asm
tlink /t modex.obj

code: bitl/7dump

comment end! +

SEGMENT_OFFSET=360*180/16
MAX_ITERATIONS=2

d     = 0
v50   = 2
xd    = 4
yd    = 6
xx    = 8
yy    = 10
speed = 12
q     = 14
qq    = 16
x     = 18
y     = 20
m     = 22


.model tiny
.data
d_     DW 32   ; 0
v50_   DW 50   ; 2
xd_    DW 110  ; 4
yd_    DW 30   ; 6
xx_    DW 180  ; 8
yy_    DW 87   ; 10
speed_ DW 50   ; 12
;q_     DW 0    ; 14
;qq_    DW 0    ; 16
;x_     DW 0    ; 18
;y_     DW 0    ; 20
;m_     DW 0    ; 22

.code
.486
org 0100h

start:
     mov     al, 13h         ;{ start with standard mode 13h }
     int     10h             ;{ let the bios set the mode    }

     add dh, al
     mov gs, dx              ; use segment cs+1300h for framebuffer
     call restoreFSES


;set x-mode 360x480 ----------------------------------------------

        mov     dx,3c4h         ;{ alter sequencer registers    }
        mov     ax,0604h        ;{ disable chain 4              }
        out     dx,ax
        mov     ax,0100h        ;{ synchronous reset      }
        out     dx,ax           ;{ asserted               }
        mov     dx,3c2h         ;{ misc output            }
        mov     al,0e7h         ;{ use 28 mHz dot clock   }
        out     dx,al           ;{ select it              }
        mov     dx,3c4h         ;{ sequencer again        }
        mov     ax,0300h        ;{ restart sequencer      }
        out     dx,ax           ;{ running again          }
        mov     dx,3d4h         ;{ alter crtc registers   }
        mov     al,11h          ;{ cr11                   }
        out     dx,al           ;{ current value          }
        inc     dx              ;{ point to data          }
        in      al,dx           ;{ get cr11 value         }
        and     al,7fh          ;{ remove cr0 -> cr7      }
        out     dx,al           ;{    write protect       }
        dec     dx              ;{ point to index         }
        mov     si, offset @vptbl
        xor     ax, ax
        mov     cl, 18
        @loop_init:
             cmp al, 0Ah
             jne @skip_init
                 mov al, 10h
             @skip_init:
             out dx, al
             inc dx
             outsb
             dec dx
             inc ax
        loop @loop_init
;----------------------------------------------------------


;Set palette ----------------------------------------------

     xor dx, dx
;     xor cx, cx
     mov ax, 1010h           ; cl=blue, ch=green, dh=red
@pal:
     pusha
     mov cl, bl
     int 10h
     popa
     pusha
     add bl, 64
     mov ch, bl
     int 10h
     popa
     pusha
     add bl, 128
     mov dh, bl
     int 10h
     popa
     inc bx
     cmp bl, 64
jb @pal
;----------------------------------------------------

                                 ; clear frame-buffer
     mov dl, 4
     @l3:
        dec cx                   ; we mean that CX=0
        xor ax, ax
        rep stosb
      call offsetES
      dec dx
      jnz @l3


@mainloop:

call restoreFSES

lea si, d_
inc word ptr [si+q]


     fninit
     fild word ptr [si+q]
     fidiv word ptr [si+speed]
     fld st
     FLDLN2
     fmulp st(1), st(0)
     fcos
     fimul word ptr [si+xd]
     fiadd word ptr [si+xx]
     fistp word ptr [si+x]

     FLDLG2
     fmulp st(1), st(0)
     fsin
     fimul word ptr [si+yd]
     fiadd word ptr [si+yy]
     fistp word ptr [si+y]



xor bx, bx
xor dx, dx
call fractal



call restoreFSES

; Blur framebuffer --------------------------------------------------
;     mov bx, 0
     mov dl, 3
@bl3:
     mov si, 3
     mov di, 4
     mov cx, 360*168/4
     @blur:
        db 64h
        lodsd
        add al, fs:[si+1]
        add al, fs:[si-360]
        add al, fs:[si+360]
        shr al, 2
        stosd
     loop @blur

     call offsetES
     mov fs, ax
dec dx
jnz @bl3
;---------------------------------------------------------------

call restoreFSES


     mov ax, 0102h           ; set mask to first plan

     and bp, 3  ;and plan, 3             ; if plan>3 then plan=0
     mov cx, bp ;plan
     shl ah, cl              ; set plan bit mask
                             ; (one plan per frame, for fasted)
     mov     dx, 3c4h        ; setup plan for write
     out     dx, ax

                             ; lets draw linear buffer to planar vram
     xor ebx, ebx
     mov dx, 3
     @rgb:
        push 0a000h
        pop es
        xor si, si
        imul di, dx, 360/4  ; call start offset for output current(DL) color-layer
        mov dh, 160         ; count lines of one color-layer

        @copy:
             mov cl, 22  ;360/4/4+1
             @copyline:
               mov al, fs:[si+8]
               mov ah, fs:[si+12]
               rol eax, 16
               mov al, fs:[si]
               mov ah, fs:[si+4]

               add eax, ebx
               stosd
               add si, 16
             loop @copyline

           mov al, fs:[si]
           mov ah, fs:[si+4]
           add ax, bx
           stosw
           add si, 8

           add di, (360/4)*2  ; skip two lines
           dec dh
         jnz @copy

       add ebx, 40404040h  ; next pallete section (+64 for every pixel)

       mov ax, fs
       add ax, SEGMENT_OFFSET
       mov fs, ax

       dec dl
     jnz @rgb

     inc bp ;inc plan



;wait for vertical retrace
     mov  dx, 3DAh
@w1:
;     in   al, dx
;     test al, 8
;     jnz  @w1
@w2:
     in   al, dx
     test al, 8
     jz   @w2


in al, 60h          ; wait for ESC
dec al
jnz @mainloop


;EXIT
mov ax, 3           ; back to text-mode
int 10h
;int 20h             ; exit


PROC restoreFSES
     push gs
     pop es
     push es
     pop fs
     ret
ENDP

PROC offsetES
     mov ax, es
     add ax, SEGMENT_OFFSET
     mov es, ax
     ret
ENDP

PROC fractal
  cmp bx, MAX_ITERATIONS
  jbe @skip_draw

     imul di, [si+y], 360
     add di, [si+x]
     mov cl, 3
     @drawdot:
     mov eax, 3f3f3f3fh
     stosd
     stosw
     add di, 360-8
     loop @drawdot

     call offsetES
     inc dx

     cmp dl, 3
     jb @skip_reset
        call restoreFSES
        xor dx, dx
     @skip_reset:


  @skip_draw:

  ;{if depth>2 then exit;}
  cmp bx, MAX_ITERATIONS
  ja @exit


   mov cl, 5
   @l:
     push word ptr [si+x]
     push word ptr [si+y]
     push word ptr [si+d]
     push bx
     push cx

     ;{inc(bp)}
     ;{qq:=q*depth;}
     mov ax, word ptr [si+q]
     inc bx
     imul ax, bx
     mov word ptr [si+qq], ax

    ;{fractal_circle(round(cos(qq/50+(pi*2/3)*m)*dd+xx),
    ; round(sin(qq/50+(pi*2/3)*m)*dd+yy), dd div 2, depth+1);}
      shl cx, 1
      mov word ptr [si+m], cx

      fild  word ptr [si+qq]
      fidiv word ptr [si+v50]
      fiadd word ptr [si+m]

      fsincos
      fimul word ptr [si+d]
      fiadd word ptr [si+x]
      fistp word ptr [si+x]
      fimul word ptr [si+d]
      fiadd word ptr [si+y]
      fistp word ptr [si+y]

      shr word ptr [si+d], 1


      call fractal

      pop cx
      pop bx
      pop word ptr [si+d]
      pop word ptr [si+y]
      pop word ptr [si+x]

  dec cx
  jnz @l

  @exit:
  ret
ENDP fractal



@vptbl: db      06bh  ;{ horz total }
        db      059h  ;{ horz displayed }
        db      05ah  ;{ start horz blanking }
        db      08eh  ;{ end horz blanking }
        db      05eh  ;{ start h sync }
        db      08ah  ;{ end h sync }
        db      00dh  ;{ vertical total }
        db      03eh  ;{ overflow }
        db      000h  ;{             }
        db      040h  ;{ cell height }
        db      0eah  ;{ v sync start }
        db      0ach  ;{ v sync end and protect cr0-cr7 }
        db      0dfh  ;{ vertical displayed }
        db      02dh  ;{ offset }
        db      000h  ;{ turn off dword mode }
        db      0e7h  ;{ v blank start }
        db      006h  ;{ v blank end }
        db      0e3h  ;{ turn on byte mode }
@vpend:

end start
