     1                                  ; TRDOS 386 Version (22/08/2016)
     2                                  ; NASM Version: Erdogan Tan (22/08/2016)
     3                                  
     4                                  ; 4ge's Xmas 94 Intro fractalzoom source
     5                                  ; ======================================
     6                                  
     7                                  ; Copyright (C) 1994/5 Samuel Marshall. All rights reserved. 
     8                                  
     9                                  ; Text and program code by Samuel Marshall, a.k.a. CuteElf / 4ge.
    10                                  
    11                                  ; Contact me at the following email address:
    12                                  
    13                                  ; Samuel.Marshall@durham.ac.uk
    14                                  
    15                                  ; and if you don't get a response, probably it's not during termtime, and
    16                                  ; I am at home - in which case, I check email here only about once a month
    17                                  ; (if that). You will get a reply eventually.
    18                                  
    19                                  ; My WWW homepage is
    20                                  
    21                                  ; http://www.dur.ac.uk/~d405ua/
    22                                  
    23                                  ; Enjoy the program... hope it helps you. Don't expect a wonderfully-
    24                                  ; optimised piece of code, because 1) the zoom routine wasn't really time-
    25                                  ; critical, and 2) this is the first time I ever wrote a fractal program,
    26                                  ; in my entire life, and 3) I didn't know how to do fixed-point numbers
    27                                  ; properly when I wrote this ;)
    28                                  
    29                                  ; General Principles for a real-time fractalzoom using this method
    30                                  ; ================================================================
    31                                  ;
    32                                  ; First, we calculate a fractal at twice the size, each way (i.e. 4 times
    33                                  ; the area) as the screen display area.
    34                                  ;
    35                                  ; We then display that fractal, zoomed-out to half size each way, so that
    36                                  ; it will exactly fill the screen display area.
    37                                  ;
    38                                  ; Then, we calculate another fractal twice the size of the display area,
    39                                  ; but this one is calculated "zoomed in" so that this fractal is a more
    40                                  ; detailed view of one-quarter of the area of the fractal just calculated.
    41                                  ;
    42                                  ; While we are calculating this, which takes a few seconds, we gradually
    43                                  ; zoom in the fractal we already have - using standard bitmap-zoom 
    44                                  ; techniques - until eventually by the time the new fractal is finished,
    45                                  ; the old fractal will be showing at 1:1 size, and will can then be 
    46                                  ; seamlessly replaced on the display by the new fractal at 1:2. Then
    47                                  ; repeat.
    48                                  ;
    49                                  ; Note: the fractal being DISPLAYED, i.e. the one that's already been
    50                                  ; calculated, can be zoomed to any point at all within the region, but
    51                                  ; this decision must be known in advance so that the next fractal is
    52                                  ; calculated from the right point. That's why you can't change the direction
    53                                  ; "realtime", only every so often.
    54                                  
    55                                  ; I would include references here but I worked the method out myself with
    56                                  ; no help from anything or anyone, so there aren't any... (oh, by the
    57                                  ; way, I assume this is the standard method everyone else uses too, it's
    58                                  ; nothing special or anything, just that I reinvented the wheel one more
    59                                  ; time ;)
    60                                  
    61                                  ; More details are included in the individual function descriptions.
    62                                  
    63                                  ; ---- TRDOS 386 --------------------------------------------------------
    64                                  
    65                                  ; 19/05/2016
    66                                  ; 29/04/2016
    67                                  ; TRDOS 386 system calls (temporary list!)
    68                                  _ver 	equ 0
    69                                  _exit 	equ 1
    70                                  _fork 	equ 2
    71                                  _read 	equ 3
    72                                  _write	equ 4
    73                                  _open	equ 5
    74                                  _close 	equ 6
    75                                  _wait 	equ 7
    76                                  _creat 	equ 8
    77                                  _link 	equ 9
    78                                  _unlink	equ 10
    79                                  _exec	equ 11
    80                                  _chdir	equ 12
    81                                  _time 	equ 13
    82                                  _mkdir 	equ 14
    83                                  _chmod	equ 15
    84                                  _chown	equ 16
    85                                  _break	equ 17
    86                                  _stat	equ 18
    87                                  _seek	equ 19
    88                                  _tell 	equ 20
    89                                  _mount	equ 21
    90                                  _umount	equ 22
    91                                  _setuid	equ 23
    92                                  _getuid	equ 24
    93                                  _stime	equ 25
    94                                  _quit	equ 26	
    95                                  _intr	equ 27
    96                                  _fstat	equ 28
    97                                  _emt 	equ 29
    98                                  _mdate 	equ 30
    99                                  _video	equ 31
   100                                  _audio	equ 32
   101                                  _timer	equ 33
   102                                  _sleep	equ 34
   103                                  _msg    equ 35
   104                                  _geterr equ 36
   105                                  _rsrvd1	equ 37
   106                                  _pri	equ 38
   107                                  _rele 	equ 39
   108                                  
   109                                  %macro sys 1-4
   110                                      ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)	
   111                                      ; 03/09/2015	
   112                                      ; 13/04/2015
   113                                      ; Retro UNIX 386 v1 system call.	
   114                                      %if %0 >= 2   
   115                                          mov ebx, %2
   116                                          %if %0 >= 3    
   117                                              mov ecx, %3
   118                                              %if %0 = 4
   119                                                 mov edx, %4   
   120                                              %endif
   121                                          %endif
   122                                      %endif
   123                                      mov eax, %1
   124                                      ;int 30h
   125                                      int 40h ; TRDOS 386 (TRDOS v2.0)	   
   126                                  %endmacro
   127                                  
   128                                  ; TRDOS 386 (and Retro UNIX 386 v1) system call format:
   129                                  ; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
   130                                  
   131                                  [BITS 32] ; 80386 Protected Mode (32 bit) intructions
   132                                  
   133                                  [ORG 0] 
   134                                  
   135 00000000 E946090000              jmp Start
   136                                  
   137                                  Getch:
   138 00000005 66B80000                mov ax, 0
   139                                  ;int 16h
   140 00000009 CD32                    int 32h  ; TRDOS 386 Keyborad Interrupt
   141 0000000B C3                      retn
   142                                  
   143                                  ; You can probably change height without messing things up, but
   144                                  ; changing the width will I think need some work.
   145                                  
   146                                  FRACWIDTH equ 256
   147                                  FRACHEIGHT equ 128
   148                                  
   149                                  ; Fractal parameter
   150 0000000C 03000000                frac:    dd 3
   151                                  
   152                                  ; Memory
   153 00000010 00000000                enlargebufferseg:        dd 0    ; segment address of the 64*32 enlarge buf.
   154 00000014 00000000                textureseg:              dd 0    ; the segment address of texture to display.
   155 00000018 00000000                fractalseg:              dd 0    ; the segment address of texture to create
   156                                  
   157                                  ;====================================================================
   158                                  ;ZOOMTEXTURE - display picture at given zoom fraction
   159                                  ;--------------------------------------------------------------------
   160                                  
   161                                  ; This is pretty obvious; just a standard, fixed-point bitmap
   162                                  ; display routine. The only extra bit you might notice is that
   163                                  ; it doubles each pixel, so as to get a larger screen display without
   164                                  ; taking too long to calculate the fractals.
   165                                  
   166                                  ; Data_______________________________________________________________
   167                                  
   168 0000001C 0000                    lfrac:   dw 0    
   169 0000001E 0000                    hfrac:   dw 0    ; texture pixels per real pixel
   170 00000020 00                      hfracb:  db 0    ; same but a byte
   171                                  
   172 00000021 00                      ystart:  db 0
   173 00000022 00                      xstart:  db 0    ; where to start, in texturemap
   174                                  
   175 00000023 0000                    oldbx:   dw 0
   176                                  
   177 00000025 0000                    yfracpos: dw 0   ; fractional y-position
   178                                  
   179 00000027 00000000                stopat:  dd 0    ; where to stop in screen ram
   180                                  
   181                                  ; Source_____________________________________________________________
   182                                  
   183                                  ZoomTexture:
   184 0000002B 50                      push eax
   185 0000002C 53                      push ebx
   186 0000002D 51                      push ecx
   187 0000002E 52                      push edx
   188 0000002F 56                      push esi
   189 00000030 57                      push edi
   190 00000031 55                      push ebp
   191                                  
   192 00000032 8B3D[82030000]          mov edi, [screenstart]      ; start position on display memory
   193 00000038 893D[27000000]          mov [stopat], edi
   194 0000003E 8105[27000000]00A0-     add dword [stopat], FRACHEIGHT*320 ; stop position on display memory
   194 00000046 0000               
   195 00000048 0FB61D[22000000]        movzx ebx, byte [xstart]           ; start position on texture memory
   196 0000004F 8A3D[21000000]          mov bh, [ystart]
   197 00000055 8B2D[14000000]          mov ebp, [textureseg]
   198                                  
   199 0000005B A0[1E000000]            mov al, [hfrac]
   200 00000060 A2[20000000]            mov [hfracb], al
   201                                  
   202 00000065 668B15[1C000000]        mov dx, [lfrac]
   203                                  
   204                                    ZoomYLoop:
   205                                  
   206 0000006C 66BE8000                  mov si, FRACWIDTH/2
   207 00000070 66891D[23000000]          mov [oldbx], bx
   208                                    ;mov cx, 0
   209 00000077 31C9                      xor ecx, ecx	
   210                                  
   211                                      ZoomXLoop:
   212                                  
   213 00000079 8A042B                      mov al, [ebx+ebp]
   214 0000007C 88C4                        mov ah, al
   215 0000007E 668907                      mov [edi], ax
   216 00000081 66898740010000              mov [edi+320], ax
   217 00000088 6683C702                    add di, 2
   218 0000008C 66030D[1C000000]            add cx, [lfrac]
   219 00000093 66131D[1E000000]            adc bx, [hfrac]
   220                                  
   221 0000009A 664E                        dec si
   222 0000009C 75DB                        jnz short ZoomXLoop
   223                                  
   224 0000009E 668B1D[23000000]          mov bx, [oldbx]
   225                                  
   226 000000A5 660115[25000000]          add [yfracpos], dx
   227 000000AC 123D[20000000]            adc bh, [hfracb]
   228                                  
   229 000000B2 81C780010000              add edi, 640-FRACWIDTH
   230 000000B8 3B3D[27000000]            cmp edi, [stopat]
   231 000000BE 72AC                      jb short ZoomYLoop
   232                                  
   233                                  ; Check for keypress
   234 000000C0 B401                    mov ah,1
   235                                  ;int 16h
   236 000000C2 CD32                    int 32h ; TRDOS 386 Keyborad Interrupt
   237 000000C4 7405                    jz short zt_afterkeyhit  
   238                                  
   239 000000C6 E909070000              jmp dfs_keyhit
   240                                  
   241                                  zt_afterkeyhit:
   242                                  
   243 000000CB 5D                      pop ebp
   244 000000CC 5F                      pop edi
   245 000000CD 5E                      pop esi
   246 000000CE 5A                      pop edx
   247 000000CF 59                      pop ecx
   248 000000D0 5B                      pop ebx
   249 000000D1 58                      pop eax
   250 000000D2 C3                      retn
   251                                  
   252                                  ;====================================================================
   253                                  ;CALCULATE - work out one pixel of Mandelbrot fractal
   254                                  ;--------------------------------------------------------------------
   255                                  
   256                                  ; The fractal formula used, with coordinates x,y, is:
   257                                  ; A = B = 0. Colour=starting colour.
   258                                  ;
   259                                  ; new A = a squared - b squared - x
   260                                  ; new B = 2 * a * b - y
   261                                  ;
   262                                  ; If A squared + B squared > some number frac, then stop.
   263                                  ; If been round loop more than colour limit (64) times, then stop too.
   264                                  ;
   265                                  ; Otherwise, work out next A and B, and increment the colour we're going
   266                                  ; to use for the pixel.
   267                                  ;
   268                                  ; When we get out of the loop, that colour value is the one to draw at
   269                                  ; this pixel.
   270                                  
   271                                  ; Note:
   272                                  ; The fixed point sections of this are pretty crap; there are proper ways
   273                                  ; to do fixed point (I think...) so for god's sake don't copy those
   274                                  ; bits for your own fixed point code.
   275                                  
   276                                  ; Data_______________________________________________________________
   277                                  
   278 000000D3 00                      colour:  db 0    ; colour to plot the pixel
   279                                  
   280 000000D4 00                      esign:    db 0    ; esign of multiplication result
   281                                  
   282 000000D5 00000000                la:      dd 0
   283 000000D9 00000000                ha:      dd 0    
   284 000000DD 00000000                lb:      dd 0
   285 000000E1 00000000                hb:      dd 0    ; a,b from a+bi. Low and high words thereof.
   286                                  
   287 000000E5 00000000                lasq:    dd 0
   288 000000E9 00000000                hasq:    dd 0
   289 000000ED 00000000                lbsq:    dd 0
   290 000000F1 00000000                hbsq:    dd 0    ; a squared, b squared, low and high words.
   291                                  
   292 000000F5 00000000                lnewa:   dd 0
   293 000000F9 00000000                hnewa:   dd 0    ; temporary storage for `new' veresion of `a'.
   294                                  
   295 000000FD 00000000                lx:      dd 0
   296 00000101 00000000                hx:      dd 0
   297 00000105 00000000                ly:      dd 0
   298 00000109 00000000                hy:      dd 0    ; co-oredinates in complex plane of this point
   299                                  
   300                                  ; Source_____________________________________________________________
   301                                  
   302                                  Calculate:
   303 0000010D 50                        push eax
   304 0000010E 53                        push ebx
   305 0000010F 51                        push ecx
   306 00000110 52                        push edx
   307 00000111 56                        push esi
   308 00000112 57                        push edi
   309                                  
   310                                  ; 0) Fix up the x,y data to specific point
   311                                  ;  mov dword [lx], 2621
   312                                  ;  mov dword [hx], 1
   313                                  ;  mov dword [ly], 11107
   314                                  ;  mov dword [hy], 1
   315                                  
   316                                  ; 1) setup colour
   317 00000113 C605[D3000000]20          mov byte  [colour], 32
   318                                  
   319                                  ; 2) clear the a,b and squared variables,
   320 0000011A 31C0                      xor eax, eax ; 0
   321 0000011C A3[D5000000]              mov [la], eax
   322 00000121 A3[D9000000]              mov [ha], eax
   323 00000126 A3[DD000000]              mov [lb], eax
   324 0000012B A3[E1000000]              mov [hb], eax
   325 00000130 A3[E5000000]              mov [lasq], eax
   326 00000135 A3[E9000000]              mov [hasq], eax
   327 0000013A A3[ED000000]              mov [lbsq], eax
   328 0000013F A3[F1000000]              mov [hbsq], eax
   329                                  
   330                                    CalcLoop:
   331                                  
   332                                    ; 3) increment colour
   333 00000144 FE05[D3000000]            inc byte [colour]
   334                                  
   335                                    ; 4) set up a-squared
   336                                  asquared:  
   337 0000014A A1[E5000000]              mov eax, [lasq]
   338 0000014F 8B15[E9000000]            mov edx, [hasq]
   339                                  
   340                                  minusbsquared:
   341                                    ; 5) subtract b-squared
   342 00000155 2B05[ED000000]            sub eax, [lbsq]
   343 0000015B 1B15[F1000000]            sbb edx, [hbsq]
   344                                  
   345                                  minusx:  
   346                                    ; 6) subtract x and store result in new-a
   347 00000161 2B05[FD000000]            sub eax, [lx]
   348 00000167 1B15[01010000]            sbb edx, [hx]
   349 0000016D A3[F5000000]              mov [lnewa], eax
   350 00000172 8915[F9000000]            mov [hnewa], edx
   351                                  
   352                                    ; 7) multiply a and b
   353                                    
   354                                  atimesb:
   355                                    ; a. setup variables
   356 00000178 8B1D[D5000000]            mov ebx, [la]
   357 0000017E 8B0D[D9000000]            mov ecx, [ha]
   358 00000184 8B35[DD000000]            mov esi, [lb]
   359 0000018A 8B3D[E1000000]            mov edi, [hb]
   360                                  
   361                                  fixesigns:  
   362                                    ; b. sort out esigns to be poesitive
   363 00000190 C605[D4000000]00          mov byte [esign], 0
   364 00000197 83F900                    cmp ecx, 0
   365 0000019A 7D12                      jge short ecxok_1
   366 0000019C 83F1FF                      xor ecx, 0ffffffffh
   367 0000019F 83F3FF                      xor ebx, 0ffffffffh
   368 000001A2 83C301                      add ebx, 1
   369 000001A5 83D100                      adc ecx, 0
   370 000001A8 FE05[D4000000]              inc byte [esign]
   371                                    ecxok_1:
   372 000001AE 83FF00                    cmp edi, 0
   373 000001B1 7D12                      jge short ediok_1
   374 000001B3 83F7FF                      xor edi, 0ffffffffh
   375 000001B6 83F6FF                      xor esi, 0ffffffffh
   376 000001B9 83C601                      add esi, 1
   377 000001BC 83D700                      adc edi, 0
   378 000001BF FE05[D4000000]              inc byte [esign]
   379                                    ediok_1:
   380                                  
   381                                  multiply:
   382                                    ; c. multiply the two numbers
   383 000001C5 C705[E1000000]0000-       mov dword [hb], 0
   383 000001CD 0000               
   384 000001CF 89D8                      mov eax, ebx
   385 000001D1 89F2                      mov edx, esi
   386 000001D3 F7E2                      mul edx
   387 000001D5 8915[DD000000]            mov [lb], edx
   388 000001DB 89D8                      mov eax, ebx
   389 000001DD 89FA                      mov edx, edi
   390 000001DF F7E2                      mul edx
   391 000001E1 0105[DD000000]            add [lb], eax
   392 000001E7 1115[E1000000]            adc [hb], edx
   393 000001ED 89C8                      mov eax, ecx
   394 000001EF 89F2                      mov edx, esi
   395 000001F1 F7E2                      mul edx
   396 000001F3 0105[DD000000]            add [lb], eax
   397 000001F9 1115[E1000000]            adc [hb], edx
   398 000001FF 89C8                      mov eax, ecx
   399 00000201 89FA                      mov edx, edi
   400 00000203 F7E2                      mul edx
   401 00000205 0105[E1000000]            add [hb], eax
   402                                  
   403                                  fixresultesign:
   404                                    ; d. fix the esign of the result
   405 0000020B F605[D4000000]01          test byte [esign], 1
   406 00000212 741C                      jz short esignok_1
   407 00000214 8335[E1000000]FF            xor dword [hb], 0ffffffffh
   408 0000021B 8335[DD000000]FF            xor dword [lb], 0ffffffffh
   409 00000222 8305[FD000000]01            add dword [lx], 1
   410 00000229 8315[E1000000]00            adc dword [hb], 0
   411                                    esignok_1:
   412                                  
   413                                  doublenumber:
   414                                    ; 8) Add this to itself, (with carry)
   415 00000230 A1[DD000000]              mov eax, [lb]
   416 00000235 8B15[E1000000]            mov edx, [hb]
   417 0000023B 01C0                      add eax, eax
   418 0000023D 11D2                      adc edx, edx
   419                                  
   420                                  subtracty:
   421                                    ; 9) Subtract y and store in b
   422 0000023F 2B05[05010000]            sub eax, [ly]
   423 00000245 1B15[09010000]            sbb edx, [hy]
   424 0000024B A3[DD000000]              mov [lb], eax
   425 00000250 8915[E1000000]            mov [hb], edx
   426                                  
   427                                    ; 10) Update a from new-a : combined with
   428                                    ; 11) Square a and store in a-squared
   429                                    ; a. setup variable
   430                                  starttosquare:  
   431 00000256 8B1D[F5000000]            mov ebx, [lnewa]
   432 0000025C 8B0D[F9000000]            mov ecx, [hnewa]
   433 00000262 891D[D5000000]            mov [la], ebx
   434 00000268 890D[D9000000]            mov [ha], ecx
   435                                  
   436                                  fixesign:
   437                                    ; b. sort out esign to be poesitive
   438 0000026E 83F900                    cmp ecx, 0
   439 00000271 7D0C                      jge short ecxok_2
   440 00000273 83F1FF                      xor ecx, 0ffffffffh
   441 00000276 83F3FF                      xor ebx, 0ffffffffh
   442 00000279 83C301                      add ebx, 1
   443 0000027C 83D100                      adc ecx, 0
   444                                    ecxok_2:
   445                                  
   446                                  squareit:
   447                                    ; c. square data
   448 0000027F C705[E9000000]0000-       mov dword [hasq], 0
   448 00000287 0000               
   449 00000289 89D8                      mov eax, ebx
   450 0000028B F7E0                      mul eax
   451 0000028D 8915[E5000000]            mov [lasq], edx
   452 00000293 89D8                      mov eax, ebx
   453 00000295 F7E1                      mul ecx
   454 00000297 0105[E5000000]            add [lasq], eax
   455 0000029D 1115[E9000000]            adc [hasq], edx
   456 000002A3 0105[E5000000]            add [lasq], eax
   457 000002A9 1115[E9000000]            adc [hasq], edx
   458 000002AF 89C8                      mov eax, ecx
   459 000002B1 F7E0                      mul eax
   460 000002B3 0105[E9000000]            add [hasq], eax
   461                                  
   462                                  sametosquareb:
   463                                    ; 12) Square b and store in b-squared
   464                                    ; a. setup variable
   465 000002B9 8B1D[DD000000]            mov ebx, [lb]
   466 000002BF 8B0D[E1000000]            mov ecx, [hb]
   467                                  
   468                                    ; b. sort out esign to be poesitive
   469 000002C5 83F900                    cmp ecx, 0
   470 000002C8 7D0C                      jge short ecxok_3
   471 000002CA 83F1FF                      xor ecx, 0ffffffffh
   472 000002CD 83F3FF                      xor ebx, 0ffffffffh
   473 000002D0 83C301                      add ebx, 1
   474 000002D3 83D100                      adc ecx, 0
   475                                    ecxok_3:
   476                                  
   477                                    ; c. square data
   478 000002D6 C705[F1000000]0000-       mov dword [hbsq], 0
   478 000002DE 0000               
   479 000002E0 89D8                      mov eax, ebx
   480 000002E2 F7E0                      mul eax
   481 000002E4 8915[ED000000]            mov [lbsq], edx
   482 000002EA 89D8                      mov eax, ebx
   483 000002EC F7E1                      mul ecx
   484 000002EE 0105[ED000000]            add [lbsq], eax
   485 000002F4 1115[F1000000]            adc [hbsq], edx
   486 000002FA 0105[ED000000]            add [lbsq], eax
   487 00000300 1115[F1000000]            adc [hbsq], edx
   488 00000306 89C8                      mov eax, ecx
   489 00000308 F7E0                      mul eax
   490 0000030A 0105[F1000000]            add [hbsq], eax
   491                                  
   492                                  asquaredaddbsquared:  
   493                                    ; 13) Setup a-squared
   494 00000310 A1[E5000000]              mov eax, [lasq]
   495 00000315 8B15[E9000000]            mov edx, [hasq]
   496                                  
   497                                    ; 14) Add b-squared
   498 0000031B 0305[ED000000]            add eax, [lbsq]
   499 00000321 1315[F1000000]            adc edx, [hbsq]
   500                                  
   501                                    ; 15) Compare with *n*, stop if >
   502 00000327 3B15[0C000000]            cmp edx, [frac]
   503 0000032D 7F0E                      jg short CalcFinish
   504                                  
   505                                    ; 16) If colour > *c*, stop
   506 0000032F 803D[D3000000]3F          cmp byte [colour], 63
   507 00000336 7F05                      jg short CalcFinish
   508                                  
   509 00000338 E907FEFFFF              jmp CalcLoop
   510                                  
   511                                  CalcFinish:
   512                                  ; 17) Return pixel colour
   513 0000033D 5F                      pop edi
   514 0000033E 5E                      pop esi
   515 0000033F 5A                      pop edx
   516 00000340 59                      pop ecx
   517 00000341 5B                      pop ebx
   518 00000342 58                      pop eax
   519 00000343 A0[D3000000]            mov al, [colour]
   520 00000348 C3                      retn
   521                                  
   522                                  ;====================================================================
   523                                  ;FRACTAL - loop round to draw a 256x256 fractal using Calculate
   524                                  ;--------------------------------------------------------------------
   525                                  
   526                                  ; Basically, this just uses fixed-point to go through all the 
   527                                  ; x and y coordinates corresponding to SCREEN x and y.
   528                                  ; If you're confused about the "normaltime", "othertime", etc crap
   529                                  ; in the zooming-in section, well, I *think* this is because the
   530                                  ; Y-position sometimes needs to start at a half-pixel (i.e. "othertime")
   531                                  ; but usually ("normaltime") starts on a whole pixel.
   532                                  
   533                                  ; Note, it would be possible to speed this up by 1/4, simply by re-using
   534                                  ; the relevant pixels from the fractal calculated last: see this diagram
   535                                  
   536                                  ; We're zooming in to top left corner.
   537                                  
   538                                  ; Original fractal      Fractal needs calculating next
   539                                  ;
   540                                  ; abcd....              a?b?c?d?
   541                                  ; efgh....              ????????
   542                                  ; ijkl....              e?f?g?h?
   543                                  ; mnop....              ????????
   544                                  ; ........              i?j?k?l?
   545                                  ; ........              ????????
   546                                  ; ........              m?n?o?p?
   547                                  ; ........              ????????
   548                                  ;
   549                                  ; where "." has been calculated on original fractal, but will not be used
   550                                  ; for the new one, and ? represents what actually needs to be calculated
   551                                  ; in the new one. (a,b,c,... could be copied from the old one).
   552                                  ;
   553                                  ; Actually, this routine doesn't copy over a,b,c,..., they are recalculated.
   554                                  
   555                                  ; Data_______________________________________________________________
   556                                  
   557 00000349 00000000                lxcentre:    dd 0
   558 0000034D 00000000                hxcentre:    dd 0
   559 00000351 00000000                lycentre:    dd 0
   560 00000355 00000000                hycentre:    dd 0    ; co-ordinates of the window's centre, not used here
   561                                                       ; (they are used in the main loop...)
   562 00000359 00000000                lxs:     dd 0
   563 0000035D 00000000                hxs:     dd 0
   564 00000361 00000000                lys:     dd 0
   565 00000365 00000000                hys:     dd 0    ; co-oredinates of the window's top left corner
   566                                  
   567 00000369 00000000                lxi:     dd 0
   568 0000036D 00000000                hxi:     dd 0
   569 00000371 00000000                lyi:     dd 0
   570 00000375 00000000                hyi:     dd 0    ; amount to increment fractal parameter per pixel
   571                                  
   572 00000379 0000                    ycount:  dw 0
   573 0000037B 0000                    xcount:  dw 0    ; loop counters
   574                                  
   575 0000037D 01                      nodraw:  db 1    ; whether or not to draw the last one
   576                                  
   577 0000037E 01                      ydirection: db 1
   578 0000037F 01                      xdirection: db 1 ; direction of the zoom (0 = left/up, 1=centre, 2=rt/down)
   579 00000380 01                      newxdirection: db 1
   580 00000381 01                      newydirection: db 1
   581                                  
   582 00000382 00000000                screenstart:   dd 0    ; screen edisplay offset
   583                                  
   584                                  ; Source_____________________________________________________________
   585                                  
   586                                  Fractal:
   587 00000386 50                      push eax
   588 00000387 53                      push ebx
   589 00000388 51                      push ecx
   590 00000389 52                      push edx
   591 0000038A 56                      push esi
   592 0000038B 57                      push edi
   593                                  
   594                                  ; 1) Initialise x and y parameters of fractal to xstart,ystart
   595 0000038C A1[59030000]            mov eax, [lxs]
   596 00000391 8B15[5D030000]          mov edx, [hxs]
   597 00000397 A3[FD000000]            mov [lx], eax
   598 0000039C 8915[01010000]          mov [hx], edx
   599 000003A2 A1[61030000]            mov eax, [lys]
   600 000003A7 8B15[65030000]          mov edx, [hys]
   601 000003AD A3[05010000]            mov [ly], eax
   602 000003B2 8915[09010000]          mov [hy], edx
   603                                  
   604                                  ; 1.5) Initialise zoom parameters
   605 000003B8 66C705[1C000000]00-     mov word [lfrac], 1024*63
   605 000003C0 FC                 
   606 000003C1 66C705[1E000000]01-     mov word [hfrac], 1
   606 000003C9 00                 
   607 000003CA C605[21000000]00        mov byte [ystart], 0
   608 000003D1 C605[22000000]00        mov byte [xstart], 0
   609                                  
   610                                  ; 2) Set up screen pointer
   611 000003D8 8B3D[18000000]          mov edi, [fractalseg]
   612                                  
   613 000003DE 66C705[79030000]80-     mov word [ycount], FRACHEIGHT
   613 000003E6 00                 
   614                                    FracYLoop:
   615                                  
   616 000003E7 66C705[7B030000]00-       mov word [xcount], FRACWIDTH
   616 000003EF 01                 
   617                                      FracXLoop:
   618                                      
   619                                      ; 3) Calculate pixel
   620 000003F0 E818FDFFFF                  call Calculate
   621                                  
   622                                      ; 4) Draw pixel
   623 000003F5 8807                        mov [edi], al
   624                                  
   625                                      ; 5) Add X increment to X
   626 000003F7 A1[69030000]                mov eax, [lxi]
   627 000003FC 8B15[6D030000]              mov edx, [hxi]
   628 00000402 0105[FD000000]              add [lx], eax
   629 00000408 1115[01010000]              adc [hx], edx
   630                                  
   631                                      ; 6) Increment screen position
   632 0000040E 6647                        inc di
   633                                      
   634                                      ; 7) If count >127, stop
   635 00000410 66FF0D[7B030000]            dec word [xcount]
   636 00000417 75D7                        jnz short FracXLoop
   637                                  
   638                                    ; 8) Set X to xstart
   639 00000419 A1[59030000]              mov eax, [lxs]
   640 0000041E 8B15[5D030000]            mov edx, [hxs]
   641 00000424 A3[FD000000]              mov [lx], eax
   642 00000429 8915[01010000]            mov [hx], edx
   643                                  
   644                                    ; 10) Add Y increment to Y
   645 0000042F A1[69030000]              mov eax, [lxi]
   646 00000434 8B15[6D030000]            mov edx, [hxi]
   647 0000043A 0105[05010000]            add [ly], eax
   648 00000440 1115[09010000]            adc [hy], edx
   649                                  
   650                                    ; 10.5) Draw zoomed last fractal if count%2==0
   651 00000446 66A1[79030000]            mov ax, [ycount]
   652 0000044C 2401                      and al, 1
   653 0000044E 7561                      jnz short notthistime
   654                                    ; Update zoom position
   655 00000450 66C705[25000000]00-         mov word [yfracpos], 0
   655 00000458 00                 
   656 00000459 A0[7F030000]                mov al, [xdirection]
   657 0000045E 0005[22000000]              add [xstart], al
   658 00000464 803D[7E030000]00            cmp byte [ydirection], 0
   659 0000046B 742D                        je short normaltime
   660 0000046D 803D[7E030000]02            cmp byte [ydirection], 2
   661 00000474 7508                        jne short ydirection1
   662 00000476 FE05[21000000]              inc byte [ystart]
   663 0000047C EB1C                        jmp short normaltime
   664                                      ydirection1:
   665 0000047E 66F705[79030000]02-         test word [ycount], 2
   665 00000486 00                 
   666 00000487 7408                        jz short othertime
   667 00000489 FE05[21000000]              inc byte [ystart]
   668 0000048F EB09                        jmp short normaltime
   669                                    
   670                                    othertime:
   671 00000491 66C705[25000000]00-         mov word [yfracpos], 8000h
   671 00000499 80                 
   672                                  
   673                                    normaltime:
   674 0000049A 803D[7D030000]00            cmp byte [nodraw], 0
   675 000004A1 7505                        jne short dontdraw
   676 000004A3 E883FBFFFF                  call ZoomTexture
   677                                      dontdraw:
   678 000004A8 66812D[1C000000]00-         sub word [lfrac], 1024
   678 000004B0 04                 
   679                                  
   680                                    notthistime:
   681                                  
   682                                    ; 11) If count>127, stop
   683 000004B1 66FF0D[79030000]          dec word [ycount]
   684 000004B8 0F8529FFFFFF              jnz FracYLoop
   685                                  
   686 000004BE 5F                      pop edi
   687 000004BF 5E                      pop esi
   688 000004C0 5A                      pop edx
   689 000004C1 59                      pop ecx
   690 000004C2 5B                      pop ebx
   691 000004C3 58                      pop eax
   692 000004C4 C3                      retn
   693                                  
   694                                  ;====================================================================
   695                                  ; SWITCHTEXTURES - switch around the two buffers
   696                                  ;--------------------------------------------------------------------
   697                                  
   698                                  ; This just changes the two buffers when one has been finished; so
   699                                  ; that the new fractal becomes the one that gets drawn to screen, and 
   700                                  ; the old fractal will get written over by the one newly being
   701                                  ; calculated.
   702                                  
   703                                  ; This is a separate function, because if you decide to implement
   704                                  ; the 25% saving described above, you'll need to copy over those
   705                                  ; re-cycled pixels at some point, and this is a good time to do that.
   706                                  
   707                                  ; Source_____________________________________________________________
   708                                  
   709                                  SwitchTextures:
   710 000004C5 50                      push eax
   711 000004C6 52                      push edx
   712                                  
   713 000004C7 A1[18000000]            mov eax, [fractalseg]
   714 000004CC 8B15[14000000]          mov edx, [textureseg]
   715 000004D2 8915[18000000]          mov [fractalseg], edx
   716 000004D8 A3[14000000]            mov [textureseg], eax
   717                                  
   718 000004DD 5A                      pop edx
   719 000004DE 58                      pop eax
   720 000004DF C3                      retn
   721                                  
   722                                  ;====================================================================
   723                                  ;DOBACKGROUND - the background for lo-res part of demo
   724                                  ;--------------------------------------------------------------------
   725                                  
   726                                  ; Just draws the swirly background things, very simple.
   727                                  
   728                                  DoBackground:
   729 000004E0 50                      push eax
   730 000004E1 53                      push ebx
   731 000004E2 51                      push ecx
   732 000004E3 57                      push edi
   733                                  
   734 000004E4 29DB                    sub ebx, ebx ;0        ; bh=y, bl=x
   735                                  
   736 000004E6 BF00000A00              mov edi, 0A0000h
   737 000004EB 89FE                    mov esi, edi
   738 000004ED 66B900FA                mov cx, 64000 ; ecx = 64000
   739 000004F1 88D8                    mov al, bl ;0
   740 000004F3 F3AA                    rep stosb
   741 000004F5 89F7                    mov edi, esi ; 0A0000h
   742                                  
   743                                  db_loop:
   744 000004F7 88F8                      mov al, bh
   745 000004F9 F6E3                      mul bl
   746 000004FB 240F                      and al, 0fh
   747 000004FD 0410                      add al, 16
   748 000004FF 8807                      mov [edi], al
   749 00000501 6647                      inc di
   750 00000503 6643                      inc bx
   751 00000505 80FB00                    cmp bl, 0
   752 00000508 7504                      jne short notnextline
   753 0000050A 6683C740                  add di, 320-256
   754                                  notnextline:
   755 0000050E 6681FB00C1                cmp bx, 256*193
   756 00000513 72E2                      jb short db_loop
   757                                  
   758 00000515 66BF0001                mov di, 256
   759 00000519 66BAC000                mov dx, 192
   760                                  
   761                                  copy_loop:
   762 0000051D 66B92000                  mov cx, 32
   763 00000521 F366A5                    rep movsw
   764 00000524 6681C60001                add si, 320-64
   765 00000529 6681C70001                add di, 320-64
   766 0000052E 664A                      dec dx
   767 00000530 75EB                      jnz short copy_loop
   768                                  
   769                                  ;mov di, 256*193
   770                                  ;mov cx, 8*320
   771                                  ;mov al, 0
   772                                  ;rep stosb
   773                                  
   774 00000532 5F                      pop edi
   775 00000533 59                      pop ecx
   776 00000534 5B                      pop ebx
   777 00000535 58                      pop eax
   778                                  
   779 00000536 C3                      retn
   780                                  
   781                                  ;====================================================================
   782                                  ;DRAWSQUARE - fills a square, for showing which way things are going
   783                                  ;--------------------------------------------------------------------
   784                                  
   785                                  ; I won't bother explaining this, you can all manage to draw a square
   786                                  ; by now...
   787                                  
   788                                  DrawSquare:
   789 00000537 50                      push eax
   790 00000538 52                      push edx
   791 00000539 56                      push esi
   792 0000053A 57                      push edi
   793                                  
   794 0000053B 6689C6                  mov si, ax
   795                                  
   796                                  ; bh=starty, ax(now si)=startx
   797                                  ; dx=width and height
   798                                  ; cl=colour
   799 0000053E 6652                    push dx
   800 00000540 6689DF                  mov di, bx
   801 00000543 66C1EF08                shr di, 8
   802 00000547 66B84001                mov ax, 320
   803 0000054B 66F7E7                  mul di
   804 0000054E 6601F0                  add ax, si
   805                                  
   806 00000551 BF00000A00              mov edi, 0A0000h
   807 00000556 6689C7                  mov di, ax
   808 00000559 665A                    pop dx
   809                                  
   810 0000055B 88C8                    mov al, cl
   811                                  
   812 0000055D 6689D6                  mov si, dx
   813                                  ds_yloop:
   814 00000560 6689D1                    mov cx, dx
   815 00000563 F3AA                      rep stosb
   816 00000565 6681C74001                add di, 320
   817 0000056A 6629D7                    sub di, dx
   818 0000056D 664E                      dec si
   819 0000056F 75EF                      jnz short ds_yloop
   820                                  
   821 00000571 5F                      pop edi
   822 00000572 5E                      pop esi
   823 00000573 5A                      pop edx
   824 00000574 58                      pop eax
   825 00000575 C3                      retn
   826                                  
   827                                  ;====================================================================
   828                                  ;DRAWDIRECTIONSQUARES - draw the motion direction indicators
   829                                  ;--------------------------------------------------------------------
   830                                  
   831                                  ; this is pretty trivial too.
   832                                  
   833                                  DrawDirectionSquares:
   834 00000576 50                      push eax
   835 00000577 53                      push ebx
   836 00000578 51                      push ecx
   837 00000579 52                      push edx
   838 0000057A 56                      push esi
   839 0000057B 57                      push edi
   840                                  
   841                                  ; Clear all squares
   842 0000057C B700                    mov bh, 0        ; was 16
   843 0000057E 66B80000                mov ax, 0        ; was 16
   844 00000582 B100                    mov cl, 0
   845 00000584 66BA2000                mov dx, 32
   846                                  
   847 00000588 66BE0300                mov si, 3
   848                                  dds_yloop:
   849 0000058C 66BF0300                  mov di, 3
   850                                    dds_xloop:
   851 00000590 6683FF02                    cmp di, 2
   852 00000594 7506                        jne short dds_drawit
   853 00000596 6683FE02                    cmp si, 2
   854 0000059A 7405                        je short dds_skipit
   855                                  
   856                                      dds_drawit:
   857 0000059C E896FFFFFF                  call DrawSquare
   858                                  
   859                                      dds_skipit:
   860 000005A1 66059000                    add ax, 9*16
   861 000005A5 664F                        dec di
   862 000005A7 75E7                        jnz short dds_xloop
   863 000005A9 66B80000                  mov ax, 0      
   864 000005AD 80C750                    add bh, 5*16   
   865 000005B0 664E                      dec si
   866 000005B2 75D8                      jnz short dds_yloop
   867                                  
   868                                  ; Draw chosen square
   869 000005B4 803D[81030000]01        cmp byte [newydirection], 1
   870 000005BB 7509                    jne short drawchosen
   871 000005BD 803D[80030000]01        cmp byte [newxdirection], 1 
   872 000005C4 7438                    je short afterchosen
   873                                  
   874                                  drawchosen:
   875 000005C6 B400                    mov ah, 0
   876 000005C8 A0[81030000]            mov al, [newydirection]
   877 000005CD 666BC050                imul ax, 5*16    
   878 000005D1 88C7                    mov bh, al
   879                                  ;mov eax, 0
   880                                  ;mov al, [newxdirection]
   881 000005D3 0FB605[80030000]        movzx eax, byte [newxdirection]
   882 000005DA 66BE9000                mov si, 9*16
   883 000005DE 66F7E6                  mul si
   884 000005E1 66BA2000                mov dx, 32               ; square side length
   885 000005E5 B101                    mov cl, 1
   886 000005E7 E84BFFFFFF              call DrawSquare
   887 000005EC 80C704                  add bh, 4
   888 000005EF 6683C004                add ax, 4
   889 000005F3 6683EA08                sub dx, 8
   890 000005F7 B100                    mov cl, 0
   891 000005F9 E839FFFFFF              call DrawSquare         ; clear the inside
   892                                  
   893                                  afterchosen:
   894                                  ; Draw actual (current) square
   895 000005FE 803D[7E030000]01        cmp byte [ydirection], 1
   896 00000605 7509                    jne short drawcurrent
   897 00000607 803D[7F030000]01        cmp byte [xdirection], 1
   898 0000060E 7431                    je short aftercurrent
   899                                  
   900                                  drawcurrent:
   901 00000610 B400                    mov ah, 0
   902 00000612 A0[7E030000]            mov al, [ydirection]
   903 00000617 666BC050                imul ax, 5*16  
   904 0000061B 6683C000                add ax, 0        
   905 0000061F 88C7                    mov bh, al
   906 00000621 B400                    mov ah, 0
   907 00000623 A0[7F030000]            mov al, [xdirection]
   908 00000628 66BE9000                mov si, 9*16
   909 0000062C 66F7E6                  mul si
   910 0000062F 80C704                  add bh, 4
   911 00000632 6683C004                add ax, 4                ; current square start now in bx.
   912 00000636 66BA1800                mov dx, 24               ; square side length
   913 0000063A B102                    mov cl, 2
   914 0000063C E8F6FEFFFF              call DrawSquare
   915                                  
   916                                  aftercurrent:
   917 00000641 5F                      pop edi
   918 00000642 5E                      pop esi
   919 00000643 5A                      pop edx
   920 00000644 59                      pop ecx
   921 00000645 5B                      pop ebx
   922 00000646 58                      pop eax
   923 00000647 C3                      retn
   924                                  
   925                                  ;====================================================================
   926                                  ;DOFRACTALSECTION - the controllable fractals part of the demo
   927                                  ;--------------------------------------------------------------------
   928                                  
   929                                  ; hopefully what with the background you have already read, this
   930                                  ; routine is self-explanatory.
   931                                  
   932                                  DoFractalSection:
   933                                  ; Now setup fractal parameters
   934                                  ; Start at preplanned position
   935 00000648 C705[4D030000]0000-     mov dword [hxcentre], 000000000h
   935 00000650 0000               
   936 00000652 C705[49030000]FFDF-     mov dword [lxcentre], 04afadfffh
   936 0000065A FA4A               
   937 0000065C C705[55030000]FEFF-     mov dword [hycentre], 0fffffffeh
   937 00000664 FFFF               
   938 00000666 C705[51030000]FFBF-     mov dword [lycentre], 08f71bfffh
   938 0000066E 718F               
   939                                  
   940                                  ; and increment by 1/64 per pixel
   941 00000670 C705[6D030000]0000-     mov dword [hxi], 0
   941 00000678 0000               
   942 0000067A C705[69030000]0000-     mov dword [lxi], 1024*65536
   942 00000682 0004               
   943 00000684 C705[75030000]0000-     mov dword [hyi], 0
   943 0000068C 0000               
   944 0000068E C705[71030000]0000-     mov dword [lyi], 1024*65536
   944 00000696 0004               
   945                                  
   946 00000698 C705[82030000]6029-     mov dword [screenstart], 0A0000h + (33*320+32)
   946 000006A0 0A00               
   947                                  
   948                                  dfs_fracloop:
   949                                  
   950                                  ; Calculate new hxcentre etc depending on xdirection,ydirection
   951                                  ; (new position = FW/4*(xdirection+1),FH/4*(ydirection+1) on the display)
   952                                  
   953                                  ; xcentre=xcentre+fw/4*(xdirection-1)*xi 
   954 000006A2 803D[7F030000]01        cmp byte [xdirection], 1
   955 000006A9 742F                    je short xchangedone
   956 000006AB BA80000000              mov edx, FRACWIDTH/2
   957 000006B0 A1[69030000]            mov eax, [lxi]
   958 000006B5 F7E2                    mul edx
   959 000006B7 803D[7F030000]02        cmp byte [xdirection], 2
   960 000006BE 750E                    jne short xchangeminus
   961 000006C0 0105[49030000]            add [lxcentre], eax
   962 000006C6 1115[4D030000]            adc [hxcentre], edx
   963 000006CC EB0C                      jmp short xchangedone
   964                                  xchangeminus:
   965 000006CE 2905[49030000]            sub [lxcentre], eax
   966 000006D4 1915[4D030000]            sbb [hxcentre], edx
   967                                  xchangedone:
   968                                  
   969                                  ; Same for Y:
   970 000006DA 803D[7E030000]01        cmp byte [ydirection], 1
   971 000006E1 742F                    je short ychangedone
   972 000006E3 BA40000000              mov edx, FRACHEIGHT/2
   973 000006E8 A1[71030000]            mov eax, [lyi]
   974 000006ED F7E2                    mul edx
   975 000006EF 803D[7E030000]02        cmp byte [ydirection], 2
   976 000006F6 750E                    jne short ychangeminus
   977 000006F8 0105[51030000]            add [lycentre], eax
   978 000006FE 1115[55030000]            adc [hycentre], edx
   979 00000704 EB0C                      jmp short ychangedone
   980                                  ychangeminus:
   981 00000706 2905[51030000]            sub [lycentre], eax
   982 0000070C 1915[55030000]            sbb [hycentre], edx
   983                                  ychangedone:
   984                                  
   985                                  ; Calculate start hxs,lxs hys,lys to keep hxcentre in middle (at 128,128)
   986                                  
   987                                  ; xs=xcentre-128*xi ys=ycentre-128*yi
   988 00000712 A1[69030000]            mov eax, [lxi]
   989 00000717 BA80000000              mov edx, FRACWIDTH/2
   990 0000071C F7E2                    mul edx
   991 0000071E 89C3                    mov ebx, eax     ; bx is l(xi*128)
   992 00000720 89D1                    mov ecx, edx     ; cx is h(xi*128)
   993 00000722 83F3FF                  xor ebx, 0ffffffffh
   994 00000725 83F1FF                  xor ecx, 0ffffffffh
   995 00000728 41                      inc ecx         ; cx:bx now negative'd
   996 00000729 031D[49030000]          add ebx, [lxcentre]
   997 0000072F 130D[4D030000]          adc ecx, [hxcentre]
   998 00000735 891D[59030000]          mov [lxs], ebx
   999 0000073B 890D[5D030000]          mov [hxs], ecx
  1000                                  
  1001                                  ; Same for Y:
  1002 00000741 A1[71030000]            mov eax, [lyi]
  1003 00000746 BA40000000              mov edx, FRACHEIGHT/2
  1004 0000074B F7E2                    mul edx
  1005 0000074D 89C3                    mov ebx, eax     ; bx is l(xi*128)
  1006 0000074F 89D1                    mov ecx, edx     ; cx is h(xi*128)
  1007 00000751 83F3FF                  xor ebx, 0ffffffffh
  1008 00000754 83F1FF                  xor ecx, 0ffffffffh
  1009 00000757 41                      inc ecx         ; cx:bx now negative'd
  1010 00000758 031D[51030000]          add ebx, [lycentre]
  1011 0000075E 130D[55030000]          adc ecx, [hycentre]
  1012 00000764 891D[61030000]          mov [lys], ebx
  1013 0000076A 890D[65030000]          mov [hys], ecx
  1014                                  
  1015                                  ; Calculate next fractal while we zoom the last one
  1016 00000770 E811FCFFFF              call Fractal
  1017                                  
  1018                                  ; Switch the texture buffers, including copying 1/4 of the pixels
  1019 00000775 E84BFDFFFF              call SwitchTextures
  1020                                  
  1021 0000077A 31C9                    xor ecx, ecx ; 0
  1022 0000077C 803D[7D030000]01        cmp byte [nodraw], 1
  1023 00000783 750C                    jne alreadydrawing
  1024 00000785 C605[7D030000]00        mov byte [nodraw], 0
  1025 0000078C E84FFDFFFF              call DoBackground
  1026                                  ;mov cx, 0
  1027                                  alreadydrawing:
  1028                                  ; Double magnification
  1029 00000791 A1[69030000]            mov eax, [lxi]
  1030 00000796 8B15[6D030000]          mov edx, [hxi]
  1031 0000079C D1E8                    shr eax, 1
  1032 0000079E D1EA                    shr edx, 1
  1033 000007A0 A3[69030000]            mov [lxi], eax
  1034 000007A5 8915[6D030000]          mov [hxi], edx
  1035 000007AB A3[71030000]            mov [lyi], eax
  1036 000007B0 8915[75030000]          mov [hyi], edx
  1037                                  
  1038                                  ; Update direction
  1039 000007B6 A0[80030000]            mov al, [newxdirection]
  1040 000007BB A2[7F030000]            mov [xdirection], al
  1041 000007C0 A0[81030000]            mov al, [newydirection]
  1042 000007C5 A2[7E030000]            mov [ydirection], al
  1043                                  
  1044 000007CA E8A7FDFFFF              call DrawDirectionSquares
  1045                                  
  1046 000007CF E9CEFEFFFF              jmp dfs_fracloop
  1047                                  
  1048                                  dfs_keyhit:
  1049                                  
  1050 000007D4 E82CF8FFFF              call Getch
  1051                                  
  1052 000007D9 3C37                    cmp al,'7'
  1053 000007DB 750E                    jne short not7
  1054 000007DD C605[80030000]00        mov byte [newxdirection], 0
  1055 000007E4 C605[81030000]00        mov byte [newydirection], 0
  1056                                  not7:
  1057                                  
  1058 000007EB 3C34                    cmp al,'4'
  1059 000007ED 750E                    jne short not4
  1060 000007EF C605[80030000]00        mov byte [newxdirection], 0
  1061 000007F6 C605[81030000]01        mov byte [newydirection], 1
  1062                                  not4:
  1063                                  
  1064 000007FD 3C31                    cmp al,'1'
  1065 000007FF 750E                    jne short not1
  1066 00000801 C605[80030000]00        mov byte [newxdirection], 0
  1067 00000808 C605[81030000]02        mov byte [newydirection], 2
  1068                                  not1:
  1069                                  
  1070 0000080F 3C38                    cmp al,'8'
  1071 00000811 750E                    jne short not8
  1072 00000813 C605[80030000]01        mov byte [newxdirection], 1
  1073 0000081A C605[81030000]00        mov byte [newydirection], 0
  1074                                  not8:
  1075                                  
  1076 00000821 3C35                    cmp al,'5'
  1077 00000823 750E                    jne short not5
  1078 00000825 C605[80030000]01        mov byte [newxdirection], 1
  1079 0000082C C605[81030000]01        mov byte [newydirection], 1
  1080                                  not5:
  1081                                  
  1082 00000833 3C32                    cmp al,'2'
  1083 00000835 750E                    jne short not2
  1084 00000837 C605[80030000]01        mov byte [newxdirection], 1
  1085 0000083E C605[81030000]02        mov byte [newydirection], 2
  1086                                  not2:
  1087                                  
  1088 00000845 3C39                    cmp al, '9'
  1089 00000847 750E                    jne short not9
  1090 00000849 C605[80030000]02        mov byte [newxdirection], 2
  1091 00000850 C605[81030000]00        mov byte [newydirection], 0
  1092                                  not9:
  1093                                  
  1094 00000857 3C36                    cmp al, '6'
  1095 00000859 750E                    jne short not6
  1096 0000085B C605[80030000]02        mov byte [newxdirection], 2
  1097 00000862 C605[81030000]01        mov byte [newydirection], 1
  1098                                  not6:
  1099                                  
  1100 00000869 3C33                    cmp al,'3'
  1101 0000086B 750E                    jne not3
  1102 0000086D C605[80030000]02        mov byte [newxdirection],2
  1103 00000874 C605[81030000]02        mov byte [newydirection],2
  1104                                  not3:
  1105                                  
  1106 0000087B 3C1B                    cmp al, 27
  1107 0000087D 0F84DC000000            je breakout
  1108                                  
  1109 00000883 E8EEFCFFFF              call DrawDirectionSquares
  1110                                  
  1111                                  donethecentrechange:
  1112 00000888 E93EF8FFFF              jmp zt_afterkeyhit    
  1113                                  
  1114                                  ;====================================================================
  1115                                  ;MAIN SECTION & MISC
  1116                                  ;--------------------------------------------------------------------
  1117                                  
  1118                                  Init:
  1119                                  ; 1) Setup ES segment
  1120                                  ; 2) Allocate RAM
  1121 0000088D C705[14000000]0000-     mov dword [textureseg], 10000h ; textureseg is 64k above our segment
  1121 00000895 0100               
  1122 00000897 C705[18000000]0000-     mov dword [fractalseg], 20000h ; and fractalseg is 128k above
  1122 0000089F 0200               
  1123 000008A1 C705[10000000]-         mov dword [enlargebufferseg], _end
  1123 000008A7 [84090000]         
  1124                                  ; 3) Do graphics mode
  1125 000008AB 66B81300                mov ax, 0013h
  1126                                  ; Int 10h
  1127 000008AF CD31                    int 31h ; TRDOS 386 Video Interrupt
  1128 000008B1 C3                      retn
  1129                                  
  1130                                  Shutdown:
  1131 000008B2 66B80300                mov ax, 0003h
  1132                                  ;int 10h
  1133 000008B6 CD31                    int 31h ; TRDOS 386 Video Interrupt
  1134 000008B8 C3                      retn
  1135                                  
  1136                                  message:
  1137 000008B9 5468616E6B7320666F-     db 'Thanks for watching the modified version of 4ge',39,'S XMaS 94 iNTRo.'
  1137 000008C2 72207761746368696E-
  1137 000008CB 6720746865206D6F64-
  1137 000008D4 696669656420766572-
  1137 000008DD 73696F6E206F662034-
  1137 000008E6 6765275320584D6153-
  1137 000008EF 20393420694E54526F-
  1137 000008F8 2E                 
  1138 000008F9 0D0A0D0A                db 13,10,13,10
  1139 000008FD 476574203467652D78-     db 'Get 4ge-xmas.zip from ftp.cdrom.com for the full version, Tseng gfx only.',13,10,13,10, 0
  1139 00000906 6D61732E7A69702066-
  1139 0000090F 726F6D206674702E63-
  1139 00000918 64726F6D2E636F6D20-
  1139 00000921 666F72207468652066-
  1139 0000092A 756C6C207665727369-
  1139 00000933 6F6E2C205473656E67-
  1139 0000093C 20676678206F6E6C79-
  1139 00000945 2E0D0A0D0A00       
  1140                                  
  1141                                  Start:
  1142                                  ; DIRECT VGA MEMORY ACCESS
  1143                                  ;xor ebx, ebx
  1144 0000094B B705                    mov bh, 5 ; Direct access/map to VGA memory (0A0000h)
  1145                                  ;mov eax, _video ; 1Fh
  1146 0000094D B01F                    mov al, 1Fh ; sys _video ; TRDOS 386 Video functions
  1147 0000094F CD40                    int 40h   ; TRDOS 386 system call
  1148                                  ; eax = 0A0000h
  1149 00000951 21C0                    and eax, eax
  1150 00000953 7425                    jz short terminate ; error (eax = 0)
  1151                                  
  1152 00000955 E833FFFFFF              call Init
  1153 0000095A E8E9FCFFFF              call DoFractalSection
  1154                                  breakout:
  1155 0000095F E84EFFFFFF              call Shutdown
  1156 00000964 B409                    mov ah, 09h
  1157 00000966 BE[B9080000]            mov esi, message
  1158                                  print_msg:
  1159 0000096B 66BB0700                mov bx, 7
  1160 0000096F B40E                    mov ah, 0Eh
  1161                                  pmsg_loop:
  1162 00000971 AC                      lodsb
  1163 00000972 20C0                    and al, al
  1164 00000974 7404                    jz short terminate
  1165 00000976 CD31                    int 31h	; TRDOS 386 video interrupt
  1166 00000978 EBF7                    jmp short pmsg_loop	
  1167                                  terminate:
  1168                                  sys _exit   ; INT 40h
  1168                              <1> 
  1168                              <1> 
  1168                              <1> 
  1168                              <1> 
  1168                              <1>  %if %0 >= 2
  1168                              <1>  mov ebx, %2
  1168                              <1>  %if %0 >= 3
  1168                              <1>  mov ecx, %3
  1168                              <1>  %if %0 = 4
  1168                              <1>  mov edx, %4
  1168                              <1>  %endif
  1168                              <1>  %endif
  1168                              <1>  %endif
  1168 0000097A B801000000          <1>  mov eax, %1
  1168                              <1> 
  1168 0000097F CD40                <1>  int 40h
  1169                                  here:
  1170 00000981 EBFE                    jmp short here
  1171                                  
  1172 00000983 90                      align 2
  1173                                  
  1174                                  _end:
