File: dos\lsysa.asm

    1 ; LSYSA.ASM: assembler support routines for optimized L-System code
    2 ; Nicholas Wilt, 11/13/91.
    3 ; Updated to work with integer/FP code, 7/93.
    4 
    5 ifdef ??version
    6    masm51
    7    quirks
    8 endif
    9 
   10 .MODEL  MEDIUM,C
   11 
   12 lsys_turtlestatei   STRUC
   13 counter             DB      ?
   14 angle               DB      ?
   15 reverse             DB      ?
   16 stackoflow          DB      ?
   17 maxangle            DB      ?
   18 dmaxangle           DB      ?
   19 curcolor            DB      ?
   20 dummy               DB      ?
   21 ssize               DD      ?
   22 realangle           DD      ?
   23 xpos                DD      ?
   24 ypos                DD      ?
   25 xmin                DD      ?
   26 ymin                DD      ?
   27 xmax                DD      ?
   28 ymax                DD      ?
   29 aspect              DD      ?
   30 num                 DD      ?
   31 lsys_turtlestatei   ENDS
   32 
   33 EXTRN   overflow:WORD
   34 EXTRN   boxy:DWORD
   35 
   36 sins    equ     boxy
   37 coss    equ     boxy + 200      ; 50 * 4 bytes
   38 
   39 .CODE
   40 
   41 DECANGLE MACRO
   42         LOCAL   @1
   43         dec     al
   44         jge     @1
   45         mov     al,[bx.dmaxangle]
   46 @1:     mov     [bx.angle],al
   47         ENDM
   48 
   49 INCANGLE MACRO
   50         LOCAL   @1
   51         inc     al
   52         cmp     al,[bx.maxangle]
   53         jne     @1
   54         xor     ax,ax
   55 @1:     mov     [bx.angle],al
   56         ENDM
   57 
   58         PUBLIC  lsysi_doplus
   59 
   60 lsysi_doplus    PROC    lsyscmd:ptr
   61         mov     bx,lsyscmd
   62         mov     al,[bx.angle]
   63         cmp     [bx.reverse],0
   64         jnz     PlusIncAngle
   65         DECANGLE
   66         ret
   67 PlusIncAngle:
   68         INCANGLE
   69         ret
   70 lsysi_doplus    ENDP
   71 
   72         PUBLIC  lsysi_dominus
   73 
   74 lsysi_dominus   PROC    lsyscmd:ptr
   75         mov     bx,lsyscmd      ; Get pointer
   76         mov     al,[bx.angle]
   77         cmp     [bx.reverse],0
   78         jnz     MinusDecAngle
   79         INCANGLE
   80         ret
   81 MinusDecAngle:
   82         DECANGLE
   83         ret
   84 lsysi_dominus   ENDP
   85 
   86         PUBLIC  lsysi_doplus_pow2
   87 
   88 lsysi_doplus_pow2       PROC    lsyscmd:ptr
   89         mov     bx,lsyscmd      ; Get pointer
   90         mov     al,[bx.angle]
   91         cmp     [bx.reverse],0
   92         jnz     Plus2IncAngle
   93         dec     al
   94         and     al,[bx.dmaxangle]
   95         mov     [bx.angle],al
   96         ret
   97 Plus2IncAngle:
   98         inc     al
   99         and     al,[bx.dmaxangle]
  100         mov     [bx.angle],al
  101         ret
  102 lsysi_doplus_pow2       ENDP
  103 
  104         PUBLIC  lsysi_dominus_pow2
  105 
  106 lsysi_dominus_pow2       PROC   lsyscmd:ptr
  107         mov     bx,lsyscmd      ; Get pointer
  108         mov     al,[bx.angle]
  109         cmp     [bx.reverse],0
  110         jz      Minus2IncAngle
  111         dec     al
  112         and     al,[bx.dmaxangle]
  113         mov     [bx.angle],al
  114         ret
  115 Minus2IncAngle:
  116         inc     al
  117         and     al,[bx.dmaxangle]
  118         mov     [bx.angle],al
  119         ret
  120 lsysi_dominus_pow2       ENDP
  121 
  122         PUBLIC  lsysi_dopipe_pow2
  123 
  124 lsysi_dopipe_pow2       PROC    lsyscmd:ptr
  125         mov     bx,lsyscmd      ; Get pointer
  126         xor     ax,ax
  127         mov     al,[bx.maxangle]
  128         shr     ax,1
  129         xor     dx,dx
  130         mov     dl,[bx.angle]
  131         add     ax,dx
  132         and     al,[bx.dmaxangle]
  133         mov     [bx.angle],al
  134         ret
  135 lsysi_dopipe_pow2       ENDP
  136 
  137         PUBLIC  lsysi_dobang
  138 
  139 lsysi_dobang    PROC    lsyscmd:ptr
  140         mov     bx,lsyscmd      ; Get pointer
  141         mov     al,[bx.reverse] ; reverse = ! reverse;
  142         dec     al              ; -1 if was 0; 0 if was 1
  143         neg     al              ; 1 if was 0; 0 if was 1
  144         mov     [bx.reverse],al ;
  145         ret
  146 lsysi_dobang    ENDP
  147 
  148 ; Some 386-specific leaf functions go here.
  149 
  150 .386
  151 
  152         PUBLIC  lsysi_doslash_386
  153 
  154 lsysi_doslash_386       PROC    lsyscmd:ptr
  155         mov     bx,lsyscmd      ; Get pointer
  156         mov     eax,[bx.num]
  157         cmp     [bx.reverse],0
  158         jnz     DoSlashDec
  159         add     [bx.realangle],eax
  160         ret
  161 DoSlashDec:
  162         sub     [bx.realangle],eax
  163         ret
  164 lsysi_doslash_386       ENDP
  165 
  166         PUBLIC  lsysi_dobslash_386
  167 
  168 lsysi_dobslash_386       PROC    lsyscmd:ptr
  169         mov     bx,lsyscmd      ; Get pointer
  170         mov     eax,[bx.num]
  171         cmp     [bx.reverse],0
  172         jz      DoBSlashDec
  173         add     [bx.realangle],eax
  174         ret
  175 DoBSlashDec:
  176         sub     [bx.realangle],eax
  177         ret
  178 lsysi_dobslash_386       ENDP
  179 
  180         PUBLIC  lsysi_doat_386
  181 
  182 lsysi_doat_386  PROC    lsyscmd:ptr ; not used, N:DWORD
  183         mov     bx,lsyscmd      ; Get pointer
  184         mov     eax,[bx.ssize]  ; Get size
  185         imul    [bx.num]        ; Mul by n
  186         shrd    eax,edx,19
  187         mov     [bx.ssize],eax  ; Save back
  188         ret
  189 lsysi_doat_386  ENDP
  190 
  191         PUBLIC  lsysi_dosizegf_386
  192 
  193 lsysi_dosizegf_386      PROC    USES SI,lsyscmd:ptr
  194         mov     si,lsyscmd      ;
  195         mov     ecx,[si.ssize]  ; Get size; we'll need it twice
   movzx ebx,[si.angle]
ifndef ??version
        mov     eax,coss[ebx*4] ; eax <- coss[angle]
else
   ; TASM-only (this is slower but it should work)
   shl   bx,2
   add   bx,offset DGROUP:coss
        mov     eax,[ebx]       ; eax <- coss[angle]
endif
        imul    ecx             ; Mul by size
        shrd    eax,edx,29      ; eax <- multiply(size, coss[angle], 29)
        add     eax,[si.xpos]   ;
        jno     nooverfl        ;   check for overflow
        mov     overflow,1      ;    oops - flag the user later
nooverfl:
        cmp     eax,[si.xmax]   ; If xpos <= [si.xmax,
        jle     GF1             ;   jump
        mov     [si.xmax],eax   ;
GF1:    cmp     eax,[si.xmin]   ; If xpos >= [si.xmin
        jge     GF2             ;   jump
        mov     [si.xmin],eax   ;
GF2:    mov     [si.xpos],eax   ; Save xpos
ifndef ??version
        mov     eax,sins[ebx*4] ; eax <- sins[angle]
else     ; sins table is 200 bytes before coss
        mov     eax,[ebx-200]   ; eax <- sins[angle]
endif
        imul    ecx             ;
        shrd    eax,edx,29      ;
        add     eax,[si.ypos]   ;
        cmp     eax,[si.ymax]   ; If ypos <= [si.ymax,
        jle     GF3             ;   jump
        mov     [si.ymax],eax   ;
GF3:    cmp     eax,[si.ymin]   ; If ypos >= [si.ymin
        jge     GF4             ;   jump
        mov     [si.ymin],eax   ;
GF4:    mov     [si.ypos],eax   ;
        ret
lsysi_dosizegf_386      ENDP

        PUBLIC  lsysi_dodrawg_386

lsysi_dodrawg_386       PROC    USES SI,lsyscmd:ptr
        mov     si,lsyscmd      ; Get pointer to structure
        mov     ecx,[si.ssize]  ; Because we need it twice
   movzx ebx,[si.angle]
ifndef ??version
        mov     eax,coss[ebx*4] ; eax <- coss[angle]
else
   ; TASM-only (this is slow but it should work)
   shl   bx,2
   add   bx,offset DGROUP:coss
        mov     eax,[ebx]       ; eax <- coss[angle]
endif
        imul    ecx             ;
        shrd    eax,edx,29      ;
        add     [si.xpos],eax   ; xpos += size*coss[angle] >> 29
ifndef ??version
        mov     eax,sins[ebx*4] ; eax <- sins[angle]
else     ; sins table is 200 bytes before coss
        mov     eax,[ebx-200]   ; eax <- sins[angle]
endif
        imul    ecx             ; ypos += size*sins[angle] >> 29
        shrd    eax,edx,29      ;
        add     [si.ypos],eax   ;
        ret                     ;
lsysi_dodrawg_386       ENDP

        END