; LSYSA.ASM: assembler support routines for optimized L-System code ; Nicholas Wilt, 11/13/91. ; .MODEL MEDIUM,C EXTRN reverse:BYTE,angle:BYTE,maxangle:BYTE,dmaxangle:BYTE EXTRN xpos:DWORD,ypos:DWORD,ssize:DWORD EXTRN realangle:DWORD EXTRN lsys_Xmin:DWORD,lsys_Xmax:DWORD,lsys_Ymin:DWORD,lsys_Ymax:DWORD EXTRN sins:DWORD EXTRN coss:DWORD EXTRN overflow:WORD .CODE decangle PROC NEAR mov al,angle or al,al jz DecAngle0 dec angle ret DecAngle0: mov al,dmaxangle mov angle,al ret decangle ENDP incangle PROC NEAR mov al,angle inc al cmp al,maxangle jnz IncWriteAngle xor ax,ax IncWriteAngle: mov angle,al ret incangle ENDP PUBLIC lsys_doplus lsys_doplus PROC cmp reverse,0 jnz PlusIncAngle call decangle ret PlusIncAngle: call incangle ret lsys_doplus ENDP PUBLIC lsys_dominus lsys_dominus PROC cmp reverse,0 jnz MinusDecAngle call incangle ret MinusDecAngle: call decangle ret lsys_dominus ENDP PUBLIC lsys_doplus_pow2 lsys_doplus_pow2 PROC mov al,angle cmp reverse,0 jnz Plus2IncAngle dec al and al,dmaxangle mov angle,al ret Plus2IncAngle: inc al and al,dmaxangle mov angle,al ret lsys_doplus_pow2 ENDP PUBLIC lsys_dominus_pow2 lsys_dominus_pow2 PROC mov al,angle cmp reverse,0 jz Minus2IncAngle dec al and al,dmaxangle mov angle,al ret Minus2IncAngle: inc al and al,dmaxangle mov angle,al ret lsys_dominus_pow2 ENDP PUBLIC lsys_dopipe_pow2 lsys_dopipe_pow2 PROC xor ax,ax mov al,maxangle shr ax,1 xor dx,dx mov dl,angle add ax,dx and al,dmaxangle mov angle,al ret lsys_dopipe_pow2 ENDP PUBLIC lsys_dobang lsys_dobang PROC mov al,reverse ; reverse = ! reverse; dec al ; -1 if was 0; 0 if was 1 neg al ; 1 if was 0; 0 if was 1 mov reverse,al ; ret lsys_dobang ENDP ; Some 386-specific leaf functions go here. .386 PUBLIC lsys_doslash_386 lsys_doslash_386 PROC N:DWORD mov eax,N cmp reverse,0 jnz DoSlashDec add realangle,eax ret DoSlashDec: sub realangle,eax ret lsys_doslash_386 ENDP PUBLIC lsys_dobslash_386 lsys_dobslash_386 PROC N:DWORD mov eax,N cmp reverse,0 jz DoBSlashDec add realangle,eax ret DoBSlashDec: sub realangle,eax ret lsys_dobslash_386 ENDP PUBLIC lsys_doat_386 lsys_doat_386 PROC N:DWORD mov eax,ssize ; Get size imul N ; Mul by n shrd eax,edx,19 ; Shift right 19 bits mov ssize,eax ; Save back ret lsys_doat_386 ENDP PUBLIC lsys_dosizegf_386 lsys_dosizegf_386 PROC mov ecx,ssize ; Get size; we'll need it twice xor bx,bx ; BX <- angle*sizeof(int) mov bl,angle ; shl bx,1 ; shl bx,1 ; mov eax,coss[bx] ; eax <- coss[angle] imul ecx ; Mul by size shrd eax,edx,29 ; eax <- multiply(size, coss[angle], 29) add eax,xpos ; jno nooverfl ; check for overflow mov overflow,1 ; oops - flag the user later nooverfl: cmp eax,lsys_Xmax ; If xpos <= lsys_Xmax, jle GF1 ; jump mov lsys_Xmax,eax ; GF1: cmp eax,lsys_Xmin ; If xpos >= lsys_Xmin jge GF2 ; jump mov lsys_Xmin,eax ; GF2: mov xpos,eax ; Save xpos mov eax,sins[bx] ; eax <- sins[angle] imul ecx ; shrd eax,edx,29 ; add eax,ypos ; cmp eax,lsys_Ymax ; If ypos <= lsys_Ymax, jle GF3 ; jump mov lsys_Ymax,eax ; GF3: cmp eax,lsys_Ymin ; If ypos >= lsys_Ymin jge GF4 ; jump mov lsys_Ymin,eax ; GF4: mov ypos,eax ; ret lsys_dosizegf_386 ENDP PUBLIC lsys_dodrawg_386 lsys_dodrawg_386 PROC mov ecx,ssize ; Because we need it twice xor bx,bx ; BX <- angle * sizeof(int) mov bl,angle ; shl bx,1 ; shl bx,1 ; mov eax,coss[bx] ; eax <- coss[angle] imul ecx ; shrd eax,edx,29 ; add xpos,eax ; xpos += size*coss[angle] >> 29 mov eax,sins[bx] ; eax <- sins[angle] imul ecx ; ypos += size*sins[angle] >> 29 shrd eax,edx,29 ; add ypos,eax ; ret ; lsys_dodrawg_386 ENDP END