home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
games
/
fr386.zip
/
MAND.A
< prev
Wrap
Text File
|
1988-05-20
|
24KB
|
616 lines
; This file is mand.a ... DeSmet asm88 functions for fr386.c,
; a fixed-pt 386 version of Mandelbrot ....
; mandwhile.a replaces inner "while" loop of mandelbrot calculation...
;==============386-SPECIFIC FUNCTIONS===================================
; int mandwhile(long P, long Q, int nmax)
; Performs all calculations for "while" loop in L.Fogg's mandel()
; function, using fixed pt math with binary pt between bits 23 and 24...
;
; FOR: DeSmet C/asm88 small case...
;
; In REAL MODE; uses 32-bit overrides on register length and addressing to
; gain performance of 32-bit regs and instructions...
; Returns # iterations before divergence (16-bit int returned in ax).
; Note 1/3 rd of instructions are for rounding, to get small amount extra
; accuracy; if you aren't that picky, dump these instructions for 10% or more
; extra speed...
;
; REGISTERS: ebp ...ytemp at top of loop, modulus_sqrd
; at bottom of loop
; edx:eax ...multiplication and temporary storage
; edi ...P
; esi ...Q
; ebx ...x
; ecx ...y
;
; RETURNS stopping number of iterations in ax.
dseg
public counter
counter dw 0
cseg
public mandwhile_
mandwhile_:
db 66h, 55h ;push ebp
;---get P ...
db 67h, 66h, 8Bh, 7Ch, 24h, 06h ;mov edi,dword [esp+6]
;---get Q ...
db 67h, 66h, 8Bh, 74h, 24h, 0Ah ;mov esi,dword [esp+10]
;---get nmax...
db 67h, 8Bh, 44h, 24h, 0Eh ;mov ax,word [esp+14]
;---initialize counter ...
mov word counter,ax
;---zero out x and y storage ...
db 66h, 33h, 0DBh ;xor ebx,ebx
db 66h, 33h, 0C9h ;xor ecx,ecx
looper: ;---ytemp=x*y---
db 66h, 8Bh, 0C3h ;mov eax,ebx
db 66h, 0F7h, 0E9h ;imul ecx
db 66h, 05h, 00h, 00h, 80h, 00h ;add eax,800000H ;for rounding...
db 66h, 83h, 0D2h, 00h ;adc edx,0 ;for rounding...
db 66h, 0Fh, 0A4h, 0C2h, 08h ;shld edx,eax,8 ;div by 2**24...
db 66h, 8Bh, 0EAh ;mov ebp,edx
;---x=x*x - y*y + P------
db 66h, 8Bh, 0C3h ;mov eax,ebx
db 66h, 0F7h, 0EBh ;imul ebx
db 66h, 05h, 00h, 00h, 80h, 00h ;add eax,800000H
db 66h, 83h, 0D2h, 00h ;adc edx,0
db 66h, 0Fh, 0A4h, 0C2h, 08h ;shld edx,eax,8
db 66h, 8Bh, 0DAh ;mov ebx,edx
;---
db 66h, 8Bh, 0C1h ;mov eax,ecx
db 66h, 0F7h, 0E9h ;imul ecx
db 66h, 05h, 00h, 00h, 80h, 00h ;add eax,800000H
db 66h, 83h, 0D2h, 00h ;adc edx,0
db 66h, 0Fh, 0A4h, 0C2h, 08h ;shld edx,eax,8
db 66h, 2Bh, 0DAh ;sub ebx,edx
db 66h, 03h, 0DFh ;add ebx,edi ;add P...
;---y=(ytemp<<1) + Q----
db 66h, 0D1h, 0E5h ;shl ebp,1
db 66h, 03h, 0EEh ;add ebp,esi ;add Q...
db 66h, 8Bh, 0CDh ;mov ecx,ebp
;---modsqrd = x*x + y*y---
db 66h, 8Bh, 0C3h ;mov eax,ebx
db 66h, 0F7h, 0EBh ;imul ebx
db 66h, 05h, 00h, 00h, 80h, 00h ;add eax,800000H
db 66h, 83h, 0D2h, 00h ;adc edx,0
db 66h, 0Fh, 0A4h, 0C2h, 08h ;shld edx,eax,8
db 66h, 8Bh, 0EAh ;mov ebp,edx
;---
db 66h, 8Bh, 0C1h ;mov eax,ecx
db 66h, 0F7h, 0E9h ;imul ecx
db 66h, 05h, 00h, 00h, 80h, 00h ;add eax,800000H
db 66h, 83h, 0D2h, 00h ;adc edx,0
db 66h, 0Fh, 0A4h, 0C2h, 08h ;shld edx,eax,8
db 66h, 03h, 0EAh ;add ebp,edx
;---test if modsqrd > "4"---(67108864 = 4*(1 << 24))---
db 66h, 81h, 0FDh, 00h,00h,00h,04h ;cmp ebp,67108864
jae home
dec word counter
jnz looper
home: mov ax,word counter
neg ax
db 67h, 03h, 44h, 24h, 0Eh ;add ax, word [esp+14]
db 66h, 5Dh ;pop ebp
ret
; long muldiv(long A, int b, int c)
; Multiplies 32-bit "a" by 16-bit "b", then divides by
; 16-bit "c" such that abs(c) >= abs(b)...NO CHECK FOR 0 DIVISOR...
;
; NOTE how DeSmet figures stack upon entry:
; 16-bit return address at sp, "A" at sp+2, b at sp+6, c at sp+8 ...
;
; REGISTERS: eax ...initially holds "A"
; ebx ...holds b
; ecx ...holds c
; edx:eax ...product A*b (before idiv)
;
; RETURNS long result in dx:ax.
cseg
public muldiv_
muldiv_:
db 67h,66h,8bh,44h,24h,02h ;mov eax,dword ptr [esp+2]
db 67h,66h,0fh,0bfh,5ch,24h,06h ;movsx ebx,word ptr [esp+6]
db 67h,66h,0fh,0bfh,4ch,24h,08h ;movsx ecx,word ptr [esp+8]
db 66h,0f7h,0ebh ;imul ebx
db 66h,0f7h,0f9h ;idiv ecx
db 66h,0fh,0a4h,0c2h,10h ;shld edx,eax,16
ret ;short return...
;==============HERCULES GRAPHICS ROUTINES=========================
; void tmode(), gmode()
; For hercules graphics; set text and graphics modes...
; 2-17-88 attempt to translate hercules asm to DeSmet...
dseg
index equ 03b4h
cntrl equ 03b8h
scrn_on equ 8
grph equ 2
text equ 20h
public gtable
public ttable
gtable db 35h,2dh,2eh,07h,5bh,02h,57h,57h,02h,03h,00h,00h
ttable db 61h,50h,52h,0fh,19h,06h,19h,19h,02h,0dh,0bh,0ch
cseg
public gmode_
gmode_: push es
push ds
mov al,grph
lea si,gtable
xor bx,bx
mov cx,4000h
call setmd
pop ds
pop es
ret
public tmode_
tmode_: push es
push ds
mov al,text
lea si,ttable
mov bx,720h
mov cx,2000
call setmd
pop ds
pop es
ret
public setmd
setmd: push ds
push es
push ax
push bx
push cx
mov dx,cntrl
out dx,al
mov ax,ds
mov es,ax
mov dx,index
mov cx,12
xor ah,ah
;---------
parms: mov al,ah
out dx,al
inc dx
lodsb
out dx,al
inc ah
dec dx
loop parms
;---------
pop cx
mov ax,0b000h
cld
mov es,ax
xor di,di
pop ax
rep stosw
mov dx,cntrl
pop ax
add al,scrn_on
out dx,al
pop es
pop ds
ret
; void hplotpt(int column, int row, int color)
; Hercules point plot routine for general 80x86...
; FOR: DeSmet c88/asm88 small case...
; ...if(color>0) fill point; else if (color==0) blank pt; else xor pt;
; 2-16-88 quick hercules card driver to plot a point ...
; REGISTER USAGE: AX for mul, mask
; CX for column = x
; DX for row = y
; SI for offset of byte to alter
; BX for color
; DI return address
; Asm translation of MicroC article in Dec 87/Jan 88, cf for explanation of
; comments...
; NOTE since we only plan on running this on 386, we could turn repeated
; shr ax,1 ... etc., into shr ax,n ...though DeSmet asm88 would require
; db encoding ...
; NOTE fast return via jmp di instead of ret !!!
cseg
public hplotpt_
hplotpt_: pop di ;return address...
pop cx ;column = x...
pop dx ;row = y...
pop bx ;color ...
sub sp,6 ; DeSmet requires
;===set up segment===============
mov ax,0B000H
mov es,ax
;===end segment setup============
;===calc byte_ofs================
;---1st calc 90*(row / 4)--------
mov ax,dx ;copy y...
shr ax,1
shr ax,1
mov ah,90
mul ah ;result now in ax
;---2nd calc 0x2000*(row % 4)----
mov si,dx ;copy y...
and si,3 ;clear all but lowest 2 bits...
ror si,1 ;mul by 0x2000...
ror si,1
ror si,1 ;(mul finished)...
;---add results of above two calcs
add si,ax ;ax now free...
;---calc (col / 8)---------------
mov ax,cx
shr ax,1
shr ax,1
shr ax,1
;---sum for final byte_ofs in si
add si,ax
;===end calc of byte_ofs=========
;===calc mask====================
;---cx has col = x---------------
not cx
and cx,7 ;now cx = (7-(col % 8))...
mov ax,1
shl ax,cl ;now al = mask ....
;===end mask calc================
;===get and alter byte @ byte_ofs
;---check for color--------------
or bx,bx
jz blank
js xorit
;---we're filling point----------
or byte es:[si],al
jmp di ;short return...
;---we're blanking point---------
blank: not al
and byte es:[si],al
jmp di ;short return...
;---we're xoring pt--------------
xorit: xor byte es:[si],al
jmp di ;short return...
;===end get and alter============
; void is_herc()
; 2-20-88 check for presence of Hercules 720*348 card ...
; REF: L. Fogg, Jan/Feb 1988 MicroC ...
cseg
public is_herc_
is_herc_: pop di ;return address ...
int 11h ;equipment check ...
and ax,30h ;check for mono text or herc ...
sub ax,30h
jnz not_there
;-----
mov cx,1000h ;test for scan result 1000h times ...
mov dx,3bah ;address status reg on MC6845 ...
;-----
test_status: in al,dx
and al,80h
jnz there
loop test_status
;-----
not_there: xor ax,ax
there: jmp di
;==============TEST FOR 386===============================
; int is_386()
; 2-20-88 checks for presence of 386 -- returns 0 if not found, else
; returns non-zero ...
; note short return for DeSmet asm88 small case ...
; REF: Juan E. Jimenez, Turbo Technix Jan/Feb 88, p. 55 ...
cseg
public is_386_
is_386_: pop di ;return address ...
pushf
xor ax,ax
push ax
popf
pushf
pop ax
and ax,8000h
sub ax,8000h
jz home2
;------
mov ax,7000h ;if here, either 286 or 386 ...
push ax
popf
pushf
pop ax
and ax,7000h
home2: jmp di
;==============DESMET KEYBOARD POLLING ROUTINES===========
; int scr_ci() and int scr_csts()
; These functions read the keyboard; scr_ci() waits until
; a key is typed, and returns the key; scr_csts() does not wait and returns
; 0 if no key is available. Unlike DeSmet functions ci() and csts(), these
; functions can read and translate extended keyboard codes (e.g., cursors
; and function keys). NOTE these are slightly faster than scr_ci() and
; scr_csts() given in DeSmet's optional PCIO.a file .
;
; FOR TURBO C: replace with combination of kbhit() and getch()...
dseg
; TABLES to convert (scan_code - 59) to char code...
table1: db 210 ;F1 scan= 59
db 211 ;F2 60
db 212 ;F3 61
db 213 ;F4 62
db 214 ;F5 63
db 215 ;F6 64
db 216 ;F7 65
db 217 ;F8 66
db 218 ;F9 67
db 219 ;F10 68
db 0 ;NumLock 69 ...not used
db 0 ;ScrollL 70 ...not used
db 200 ;bol_char 71
db 30 ;up_arrow 72
db 202 ;page_up 73
db 0 ;grey(-) 74 ...not used
db 29 ;left_arrow 75
db 0 ;NumPad5 76 ...not used
db 28 ;right_arrow77
db 0 ; 78 ...not used
db 201 ;eol_char 79
db 31 ;down_arrow 80
db 203 ;page_down 81
db 206 ;Insert 82
db 207 ;Delete 83
public table2
table2: db 209 ;left_word 115
db 208 ;right_word 116
db 205 ;end_of_file117
db 0 ; 118 ..not used
db 204 ;begin_file 119
cseg
public scr_ci_
scr_ci_: push bp
mov ah,0
int 16H
cmp al,0
jne not_special
mov bl,ah
xor bh,bh
cmp bx,114
ja use_table2
sub bx,59
mov al,byte table1[bx]
jmp not_special
use_table2: sub bx,115
mov al,byte table2[bx]
not_special: xor ah,ah
pop bp
ret
public scr_csts_
scr_csts_: push bp
mov ah,1
int 16H
mov ax,0
jz csts_over
call scr_ci_
csts_over: pop bp
ret
;==============LOG COLOR TRANSFORM===================================
; 2-20-88 transform(int iter, int switchpt) ... DeSmet asm88 ...
; for frac386.c ...
; ...returns the "color" then anded with (maxcolors-1)...
; converts the iterations returned by mand() to a log scaling, starting at
; the switchpt. Equiv. to C coding:
; if(iter < switchpt) color = iter;
; else for(color=i=switchpt,inc=1; i<iter; i=switchpt+(inc<<=1),color++);
; ...However, 386 is so fast we need to translate to asm to get full benefit!
cseg
public transform_
transform_: pop di ;return address...
pop cx ;iter...
pop bx ;switchpt...
sub sp,4 ;required by DeSmet for short return...
cmp cx,bx
ja do_loop
mov ax,cx
jmp di ;short return...
;------
do_loop: mov ax,bx ;init color (ax) with switchpt...
mov si,1 ;si = inc...
mov dx,bx ;init i (dx) with switchpt...
;------
loopit: cmp dx,cx ;compare i (dx) to iter (cx)...
jge done
shl si,1 ;inc <<= 1...
mov dx,bx
add dx,si ;i = switchpt + inc...
inc ax
jmp loopit
;------
done: jmp di ;short return, color in ax...
;==============EGA ROUTINES==========================================
; void egapt(int x, int y, int color)
;
; EGA point plot in general 80x86 assembly language; from
; G.Entsminger's Tidbits article, Jan 88 MicroC, translated from C...
; See below for functions to turn on/off mode 16, text mode, etc...
;
; FOR: DeSmet small case c88/asm88...
;
; NOTE this is really a point XOR routine !!!
; NOTE we are using jmp di in place of ret !!!
;
dseg
; define table to translate EGA default palette into pleasing sequence...
trans dw 0,8,7,15,11,3,9,1,2,10,14,6,4,12,13,5
cseg
public egapt_
egapt_: mov ax,0a000h
mov es,ax
pop di ;return address...
pop cx ;x...
pop bx ;y...
pop si ;color...
sub sp,6 ;DeSmet requires for jmp return...
and si,15 ;allow only 16 colors...
shl si,1 ;adjust to word length...
mov si,trans[si] ;translate to pleasant order...
;---offset = y*80 + x/8---------------------
mov ax,80
mul bx ;ax=80*y, dx still empty...
mov bx,cx ;y into bx...
shr bx,1
shr bx,1
shr bx,1
add bx,ax ;bx = offset = y*80 + x/8...
;---calc mask------------------------------
and cx,7
xor cx,7
mov ch,1
shl ch,cl ;mask now in ch...
;---latch bit planes-----------------------
mov al,es:[bx] ;phony read...
;---1st four "OUTINDEXes"------------------
mov dx,3ceh
mov al,0
out dx,al
mov dx,3cfh
mov ax,si ;color into al...
out dx,al
mov dx,3ceh
mov al,1
out dx,al
mov dx,3cfh
mov al,0fh ;enable...
out dx,al
mov dx,3ceh
mov al,8
out dx,al
mov dx,3cfh
mov al,ch ;mask in ch...
out dx,al
mov dx,3ceh
mov al,3
out dx,al
mov dx,3cfh ;This sets xor mode...
mov al,18h
out dx,al
;---*base &= -1;---set all bits------------
and byte es:[bx],-1 ;set all bits...
jmp di ;fast return...
; void egatext()
; restore write mode 0 and text mode...
public egatext_
egatext_:
mov dx,3ceh ;reset write mode 0...
mov al,0
out dx,al
mov dx,3cfh
mov al,0
out dx,al
mov dx,3ceh
mov al,1
out dx,al
mov dx,3cfh
mov al,0
out dx,al
mov dx,3ceh ;this appears to be reset
mov al,8 ;of write mode 1; I'm still
out dx,al ;not sure if this junk is needed...
mov dx,3cfh
mov al,-1
out dx,al
mov dx,3ceh
mov al,3
out dx,al
mov dx,3cfh
mov al,0
out dx,al
mov ax,3
int 10h
ret
; void mode16()
; turn on 640*350 16 color mode...
public mode16_
mode16_: mov ax,16
int 10h
ret
; is_ega()
; Test if EGA is in system; this basically stupid routine is from
; DDJ Nov 87 p 34-35; it tests the "EGA byte", and is NOT a fool-proof
; method, since it depends on vagaries of IBM BIOS...unfortunately,
; methods that look for "IBM" characters in BIOS don't work with VGA...
public is_ega_
is_ega_: mov ax,40h
mov es,ax
mov bx,87h
xor ax,ax
mov al,byte es:[bx]
cmp al,240 ;check for AT&T (kludge)...
je clear
cmp al,16 ;check for Compaq (kludge)...
je clear
ret
clear: mov al,0 ;clear AT&T/Compaq byte...
ret ;ax not 0 if EGA present...