home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_49.arc / PS-FR386.ARC / MAND.A next >
Text File  |  1989-07-11  |  12KB  |  278 lines

  1. ; Micro Cornucopia Magazine Issue #49
  2. ; PostScriptals article code
  3. ;
  4. ; This is a pruned version of Harlan Stockman's 386 specific code originally
  5. ; run in Micro Cornucopia Issue #43. I used it for the PostScriptal article
  6. ; in Issue #49. The code that's left has not been altered - I just removed
  7. ; the stuff I didn't need and reassembled with DeSmet.
  8. ;                                           Larry Fogg - June 28, 1989
  9.  
  10. ; This file is mand.a ... DeSmet asm88 functions for fr386.c,
  11. ; a fixed-pt 386 version of Mandelbrot ...
  12. ; mandwhile.a replaces inner "while" loop of mandelbrot calculation...
  13.  
  14. ;==============386-SPECIFIC FUNCTIONS===================================
  15. ; int  mandwhile(long P, long Q, int nmax)
  16. ; Performs all calculations for "while" loop in L.Fogg's mandel()
  17. ; function, using fixed pt math with binary pt between bits 23 and 24...
  18. ;
  19. ; FOR: DeSmet C/asm88 small case...
  20. ;
  21. ; In REAL MODE; uses 32-bit overrides on register length and addressing to
  22. ; gain performance of 32-bit regs and instructions...
  23. ; Returns # iterations before divergence (16-bit int returned in ax).
  24. ; Note 1/3 rd of instructions are for rounding, to get small amount extra
  25. ; accuracy; if you aren't that picky, dump these instructions for 10% or more
  26. ; extra speed...
  27. ;
  28. ; REGISTERS:            ebp     ...ytemp at top of loop, modulus_sqrd
  29. ;                                  at bottom of loop
  30. ;                   edx:eax     ...multiplication and temporary storage
  31. ;                       edi     ...P
  32. ;                       esi     ...Q
  33. ;                       ebx     ...x
  34. ;                       ecx     ...y
  35. ;
  36. ; RETURNS stopping number of iterations in ax.
  37.  
  38.  dseg
  39.  public    counter
  40.  counter   dw   0
  41.  cseg
  42.  public    mandwhile_
  43.  mandwhile_:
  44.           db 66h, 55h                      ;push ebp
  45.          ;---get P ...
  46.           db 67h, 66h, 8Bh, 7Ch, 24h, 06h  ;mov edi,dword  [esp+6]
  47.          ;---get Q ...
  48.           db 67h, 66h, 8Bh, 74h, 24h, 0Ah  ;mov esi,dword  [esp+10]
  49.          ;---get nmax...
  50.           db 67h, 8Bh, 44h, 24h, 0Eh       ;mov ax,word  [esp+14]
  51.          ;---initialize counter ...
  52.           mov word  counter,ax
  53.          ;---zero out x and y storage ...
  54.           db 66h, 33h, 0DBh                ;xor ebx,ebx
  55.           db 66h, 33h, 0C9h                ;xor ecx,ecx
  56.  
  57.  looper:  ;---ytemp=x*y---
  58.           db 66h, 8Bh, 0C3h                ;mov eax,ebx
  59.           db 66h, 0F7h, 0E9h               ;imul ecx
  60.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H   ;for rounding...
  61.           db 66h, 83h, 0D2h, 00h           ;adc edx,0         ;for rounding...
  62.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8    ;div by 2**24...
  63.           db 66h, 8Bh, 0EAh                ;mov ebp,edx
  64.          ;---x=x*x - y*y + P------
  65.           db 66h, 8Bh, 0C3h                ;mov eax,ebx
  66.           db 66h, 0F7h, 0EBh               ;imul ebx
  67.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H
  68.           db 66h, 83h, 0D2h, 00h           ;adc edx,0
  69.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8
  70.           db 66h, 8Bh, 0DAh                ;mov ebx,edx
  71.           ;---
  72.           db 66h, 8Bh, 0C1h                ;mov eax,ecx
  73.           db 66h, 0F7h, 0E9h               ;imul ecx
  74.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H
  75.           db 66h, 83h, 0D2h, 00h           ;adc edx,0
  76.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8
  77.           db 66h, 2Bh, 0DAh                ;sub ebx,edx
  78.           db 66h, 03h, 0DFh                ;add ebx,edi     ;add P...
  79.          ;---y=(ytemp<<1) + Q----
  80.           db 66h, 0D1h, 0E5h               ;shl ebp,1
  81.           db 66h, 03h, 0EEh                ;add ebp,esi     ;add Q...
  82.           db 66h, 8Bh, 0CDh                ;mov ecx,ebp
  83.          ;---modsqrd = x*x + y*y---
  84.           db 66h, 8Bh, 0C3h                ;mov eax,ebx
  85.           db 66h, 0F7h, 0EBh               ;imul ebx
  86.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H
  87.           db 66h, 83h, 0D2h, 00h           ;adc edx,0
  88.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8
  89.           db 66h, 8Bh, 0EAh                ;mov ebp,edx
  90.          ;---
  91.           db 66h, 8Bh, 0C1h                ;mov eax,ecx
  92.           db 66h, 0F7h, 0E9h               ;imul ecx
  93.           db 66h, 05h, 00h, 00h, 80h, 00h  ;add eax,800000H
  94.           db 66h, 83h, 0D2h, 00h           ;adc edx,0
  95.           db 66h, 0Fh, 0A4h, 0C2h, 08h     ;shld edx,eax,8
  96.           db 66h, 03h, 0EAh                ;add ebp,edx
  97.          ;---test if modsqrd > "4"---(67108864 = 4*(1 << 24))---
  98.           db 66h, 81h, 0FDh, 00h,00h,00h,04h  ;cmp ebp,67108864
  99.           jae home
  100.           dec word  counter
  101.           jnz looper
  102.  home:    mov ax,word  counter
  103.           neg ax
  104.           db 67h, 03h, 44h, 24h, 0Eh       ;add ax, word  [esp+14]
  105.           db 66h, 5Dh                      ;pop ebp
  106.           ret
  107.  
  108.  
  109. ; long  muldiv(long A, int b, int c)
  110. ; Multiplies 32-bit "a" by 16-bit "b", then divides by
  111. ; 16-bit "c" such that abs(c) >= abs(b)...NO CHECK FOR 0 DIVISOR...
  112. ;
  113. ; NOTE how DeSmet figures stack upon entry:
  114. ; 16-bit return address at sp, "A" at sp+2, b at sp+6, c at sp+8 ...
  115. ;
  116. ; REGISTERS:            eax     ...initially holds "A"
  117. ;                       ebx     ...holds b
  118. ;                       ecx     ...holds c
  119. ;                   edx:eax     ...product A*b (before idiv)
  120. ;
  121. ; RETURNS long result in dx:ax.
  122.  
  123. cseg
  124. public    muldiv_
  125. muldiv_:
  126.      db 67h,66h,8bh,44h,24h,02h        ;mov eax,dword ptr [esp+2]
  127.      db 67h,66h,0fh,0bfh,5ch,24h,06h   ;movsx ebx,word ptr [esp+6]
  128.      db 67h,66h,0fh,0bfh,4ch,24h,08h   ;movsx ecx,word ptr [esp+8]
  129.      db 66h,0f7h,0ebh                  ;imul ebx
  130.      db 66h,0f7h,0f9h                  ;idiv ecx
  131.      db 66h,0fh,0a4h,0c2h,10h          ;shld edx,eax,16
  132.      ret                               ;short return...
  133.  
  134.  
  135.  
  136.  
  137.  
  138. ;==============TEST FOR 386===============================
  139. ; int is_386()
  140. ; 2-20-88 checks for presence of 386 -- returns 0 if not found, else
  141. ; returns non-zero ...
  142. ; note short return for DeSmet asm88 small case ...
  143. ; REF: Juan E. Jimenez, Turbo Technix Jan/Feb 88, p. 55 ...
  144.  
  145. cseg
  146. public    is_386_
  147. is_386_:            pop di         ;return address ...
  148.                     pushf
  149.                     xor ax,ax
  150.                     push ax
  151.                     popf
  152.                     pushf
  153.                     pop ax
  154.                     and ax,8000h
  155.                     sub ax,8000h
  156.                     jz home2
  157.                     ;------
  158.                     mov ax,7000h   ;if here, either 286 or 386 ...
  159.                     push ax
  160.                     popf
  161.                     pushf
  162.                     pop ax
  163.                     and ax,7000h
  164.           home2:    jmp di
  165.  
  166.  
  167. ;==============DESMET KEYBOARD POLLING ROUTINES===========
  168. ; int scr_ci() and int scr_csts()
  169. ; These functions read the keyboard; scr_ci() waits until
  170. ; a key is typed, and returns the key; scr_csts() does not wait and returns
  171. ; 0 if no key is available. Unlike DeSmet functions ci() and csts(), these
  172. ; functions can read and translate extended keyboard codes (e.g., cursors
  173. ; and function keys). NOTE these are slightly faster than scr_ci() and
  174. ; scr_csts() given in DeSmet's optional PCIO.a file .
  175. ;
  176. ; FOR TURBO C: replace with combination of kbhit() and getch()...
  177.  
  178. dseg
  179. ; TABLES to convert (scan_code - 59) to char code...
  180. table1:               db      210          ;F1   scan= 59
  181.                       db      211          ;F2         60
  182.                       db      212          ;F3         61
  183.                       db      213          ;F4         62
  184.                       db      214          ;F5         63
  185.                       db      215          ;F6         64
  186.                       db      216          ;F7         65
  187.                       db      217          ;F8         66
  188.                       db      218          ;F9         67
  189.                       db      219          ;F10        68
  190.                       db      0            ;NumLock    69   ...not used
  191.                       db      0            ;ScrollL    70   ...not used
  192.                       db      200          ;bol_char   71
  193.                       db      30           ;up_arrow   72
  194.                       db      202          ;page_up    73
  195.                       db      0            ;grey(-)    74   ...not used
  196.                       db      29           ;left_arrow 75
  197.                       db      0            ;NumPad5    76   ...not used
  198.                       db      28           ;right_arrow77   
  199.                       db      0            ;           78   ...not used
  200.                       db      201          ;eol_char   79
  201.                       db      31           ;down_arrow 80
  202.                       db      203          ;page_down  81
  203.                       db      206          ;Insert     82
  204.                       db      207          ;Delete     83
  205. public table2
  206. table2:               db      209          ;left_word  115
  207.                       db      208          ;right_word 116
  208.                       db      205          ;end_of_file117
  209.                       db      0            ;           118   ..not used
  210.                       db      204          ;begin_file 119
  211. cseg
  212. public scr_ci_
  213. scr_ci_:                      push bp
  214.                               mov ah,0
  215.                               int 16H
  216.                               cmp al,0
  217.                               jne not_special
  218.                               mov bl,ah
  219.                               xor bh,bh
  220.                               cmp bx,114
  221.                               ja  use_table2
  222.                               sub bx,59
  223.                               mov al,byte table1[bx]
  224.                               jmp not_special
  225.         use_table2:           sub bx,115
  226.                               mov al,byte table2[bx]
  227.         not_special:          xor ah,ah
  228.                               pop bp
  229.                               ret
  230.  
  231.  
  232. public scr_csts_
  233. scr_csts_:                    push bp
  234.                               mov ah,1
  235.                               int 16H
  236.                               mov ax,0
  237.                               jz csts_over
  238.                               call scr_ci_
  239.         csts_over:            pop bp
  240.                               ret
  241.  
  242. ;==============LOG COLOR TRANSFORM===================================
  243. ; 2-20-88 transform(int iter, int switchpt) ... DeSmet asm88 ...
  244. ; for frac386.c ...
  245. ; ...returns the "color" then anded with (maxcolors-1)...
  246. ; converts the iterations returned by mand() to a log scaling, starting at 
  247. ; the switchpt. Equiv. to C coding:
  248. ; if(iter < switchpt) color = iter;
  249. ; else for(color=i=switchpt,inc=1; i<iter; i=switchpt+(inc<<=1),color++);
  250. ; ...However, 386 is so fast we need to translate to asm to get full benefit!
  251.  
  252. cseg
  253. public    transform_
  254. transform_:         pop di         ;return address...
  255.                     pop cx         ;iter...
  256.                     pop bx         ;switchpt...
  257.                     sub sp,4       ;required by DeSmet for short return...
  258.                     cmp cx,bx
  259.                     ja do_loop
  260.                     mov ax,cx
  261.                     jmp di         ;short return...
  262.                     ;------
  263.           do_loop:  mov ax,bx      ;init color (ax) with switchpt...
  264.                     mov si,2       ;si = inc...  (originally = 1)
  265.                     mov dx,bx      ;init i (dx) with switchpt...
  266.                     ;------
  267.           loopit:   cmp dx,cx      ;compare i (dx) to iter (cx)...
  268.                     jge done
  269.                     shl si,1       ;inc <<= 1...
  270.                     mov dx,bx
  271.                     add dx,si      ;i = switchpt + inc...
  272.                     inc ax
  273.                     jmp loopit
  274.                     ;------
  275.           done:     jmp di         ;short return, color in ax...
  276.  
  277.  
  278.