File: dos\lsysaf.asm

    1 ; LSYSAF.ASM: assembler support routines for optimized L-System code
    2 ; (floating-point version)
    3 ; Nicholas Wilt, 7/93.
    4 
    5 .MODEL  MEDIUM,C
    6 
    7 lsys_turtlestatef   STRUC
    8 counter             DB      ?
    9 angle               DB      ?
   10 reverse             DB      ?
   11 stackoflow          DB      ?
   12 maxangle            DB      ?
   13 dmaxangle           DB      ?
   14 curcolor            DB      ?
   15 dummy               DB      ?
   16 ssize               DT      ?
   17 realangle           DT      ?
   18 xpos                DT      ?
   19 ypos                DT      ?
   20 xmin                DT      ?
   21 ymin                DT      ?
   22 xmax                DT      ?
   23 ymax                DT      ?
   24 aspect              DT      ?
   25 num                 DD      ?
   26 lsys_turtlestatef   ENDS
   27 
   28 EXTRN   overflow:WORD
   29 EXTRN   draw_line:FAR
   30 EXTRN   FPUsincos:FAR
   31 EXTRN   cpu:WORD
   32 
   33 EXTRN   boxy:TBYTE
   34 
   35 sins_f  equ     boxy
   36 coss_f  equ     boxy + 500      ; 50 * 10 bytes
   37 
   38 .CODE
   39 
   40 DECANGLE MACRO
   41         LOCAL   @1
   42         dec     al
   43         jge     @1
   44         mov     al,[bx.dmaxangle]
   45 @1:     mov     [bx.angle],al
   46         ENDM
   47 
   48 INCANGLE MACRO
   49         LOCAL   @1
   50         inc     al
   51         cmp     al,[bx.maxangle]
   52         jne     @1
   53         xor     ax,ax
   54 @1:     mov     [bx.angle],al
   55         ENDM
   56 
   57         PUBLIC  lsysf_doplus
   58 
   59 lsysf_doplus    PROC    lsyscmd:ptr
   60         mov     bx,lsyscmd
   61         mov     al,[bx.angle]
   62         cmp     [bx.reverse],0
   63         jnz     PlusIncAngle
   64         DECANGLE
   65         ret
   66 PlusIncAngle:
   67         INCANGLE
   68         ret
   69 lsysf_doplus    ENDP
   70 
   71         PUBLIC  lsysf_dominus
   72 
   73 lsysf_dominus   PROC    lsyscmd:ptr
   74         mov     bx,lsyscmd      ; Get pointer
   75         mov     al,[bx.angle]
   76         cmp     [bx.reverse],0
   77         jnz     MinusDecAngle
   78         INCANGLE
   79         ret
   80 MinusDecAngle:
   81         DECANGLE
   82         ret
   83 lsysf_dominus   ENDP
   84 
   85         PUBLIC  lsysf_doplus_pow2
   86 
   87 lsysf_doplus_pow2       PROC    lsyscmd:ptr
   88         mov     bx,lsyscmd      ; Get pointer
   89         mov     al,[bx.angle]
   90         cmp     [bx.reverse],0
   91         jnz     Plus2IncAngle
   92         dec     al
   93         and     al,[bx.dmaxangle]
   94         mov     [bx.angle],al
   95         ret
   96 Plus2IncAngle:
   97         inc     al
   98         and     al,[bx.dmaxangle]
   99         mov     [bx.angle],al
  100         ret
  101 lsysf_doplus_pow2       ENDP
  102 
  103         PUBLIC  lsysf_dominus_pow2
  104 
  105 lsysf_dominus_pow2       PROC   lsyscmd:ptr
  106         mov     bx,lsyscmd      ; Get pointer
  107         mov     al,[bx.angle]
  108         cmp     [bx.reverse],0
  109         jz      Minus2IncAngle
  110         dec     al
  111         and     al,[bx.dmaxangle]
  112         mov     [bx.angle],al
  113         ret
  114 Minus2IncAngle:
  115         inc     al
  116         and     al,[bx.dmaxangle]
  117         mov     [bx.angle],al
  118         ret
  119 lsysf_dominus_pow2       ENDP
  120 
  121         PUBLIC  lsysf_dopipe_pow2
  122 
  123 lsysf_dopipe_pow2       PROC    lsyscmd:ptr
  124         mov     bx,lsyscmd      ; Get pointer
  125         xor     ax,ax
  126         mov     al,[bx.maxangle]
  127         shr     ax,1
  128         xor     dx,dx
  129         mov     dl,[bx.angle]
  130         add     ax,dx
  131         and     al,[bx.dmaxangle]
  132         mov     [bx.angle],al
  133         ret
  134 lsysf_dopipe_pow2       ENDP
  135 
  136         PUBLIC  lsysf_dobang
  137 
  138 lsysf_dobang    PROC    lsyscmd:ptr
  139         mov     bx,lsyscmd      ; Get pointer
  140         mov     al,[bx.reverse] ; reverse = ! reverse;
  141         dec     al              ; -1 if was 0; 0 if was 1
  142         neg     al              ; 1 if was 0; 0 if was 1
  143         mov     [bx.reverse],al ;
  144         ret
  145 lsysf_dobang    ENDP
  146 
  147         PUBLIC  lsysf_doat
  148 
  149 lsysf_doat      PROC    lsyscmd:ptr
  150         mov     bx,lsyscmd      ; Get pointer
  151         fld     tbyte ptr [bx.num] ; Get N.
  152                                 ; FPU stk: N xpos ypos size aspect
  153         fmulp   st(3),st        ; Multiply size by it.
  154         ret
  155 lsysf_doat      ENDP
  156 
  157 .386
  158 
  159 LSYS_SINCOS     MACRO   OFFS
  160         LOCAL   UseSinCos, Done
  161 
  162         cmp     cpu,386         ; If CPU >= 386, we can use fsincos.
  163         jge     UseSinCos       ;
  164 
  165                                 ; Otherwise we use FPUsincos.
  166 
  167         sub     sp,50+24        ; Save enough room for entire state
  168                                 ; plus parameter to sin or cos
  169         fstp    tbyte ptr [bp-OFFS-10] ; Save state
  170         fstp    tbyte ptr [bp-OFFS-20] ;
  171         fstp    tbyte ptr [bp-OFFS-30] ;
  172         fstp    tbyte ptr [bp-OFFS-40] ;
  173         fld     st              ; realangle remains on FPU stack
  174         fstp    tbyte ptr [bp-OFFS-50] ;
  175         fstp    qword ptr [bp-OFFS-50-8] ; Store as parameter to FPUsincos
  176 
  177         lea     ax,[bp-OFFS-50-16]      ; Push pointer to cosine
  178         push    ax              ;
  179         lea     ax,[bp-OFFS-50-24]      ; Push pointer to sine
  180         push    ax              ;
  181         lea     ax,[bp-OFFS-50-8]       ; Push pointer to parameter
  182         push    ax              ;
  183         call    FPUsincos       ; Call it.
  184 
  185         add     sp,6            ; Restore stack
  186 
  187         fld     tbyte ptr [bp-OFFS-50] ; Restore state
  188         fld     tbyte ptr [bp-OFFS-40] ;
  189         fld     tbyte ptr [bp-OFFS-30] ;
  190         fld     tbyte ptr [bp-OFFS-20] ;
  191         fld     tbyte ptr [bp-OFFS-10] ;
  192         fld     qword ptr [bp-OFFS-50-24] ; Get sine
  193         fld     qword ptr [bp-OFFS-50-16] ; Get cosine
  194 
  195         add     sp,50+24        ; Restore stack
  196 
  197         jmp     short Done      ;
  198 UseSinCos:
  199         fld     st(4)           ; Get angle
  200         fsincos                 ; c s xpos ypos size aspect realangle
  201 Done:
  202         ENDM
  203 
  204         PUBLIC  lsysf_dosizedm
  205 
  206 lsysf_dosizedm  PROC    lsyscmd:ptr
  207         LSYS_SINCOS 0           ; Get sine and cosine of angle.
  208         mov     bx,lsyscmd      ; Get pointer to structure
  209         fmul    st,st(5)        ; c*aspect s xpos ypos size aspect
  210         fmul    st,st(4)        ; c*size*aspect s xpos ypos size aspect
  211         faddp   st(2),st        ; s xpos ypos size aspect
  212         fmul    st,st(3)        ; s*size xpos ypos size aspect
  213         faddp   st(2),st        ; xpos ypos size aspect
  214 
  215         push    ax              ; Allocate a local for FP status word
  216 
  217         fld     [bx.xmin]       ; Compare xpos to xmin
  218         fcomp                   ;
  219         fstsw   [bp-2]          ; Store status word
  220         mov     ax,[bp-2]       ;
  221         sahf                    ;
  222         jb      SizeDM1         ; Jump if ST > xmin
  223         fld     st              ;
  224         fstp    [bx.xmin]       ;
  225         jmp     short SizeDM2   ;
  226 SizeDM1:
  227         fld     [bx.xmax]       ; Compare to xmax
  228         fcomp                   ;
  229         fstsw   [bp-2]          ; Store status word
  230         mov     ax,[bp-2]       ;
  231         sahf                    ;
  232         ja      SizeDM2         ; Jump if ST < xmax
  233         fld     st              ;
  234         fstp    [bx.xmax]       ;
  235 SizeDM2:
  236         fxch                    ; Swap xpos and ypos
  237         fld     [bx.ymin]       ; Compare ypos to ymin
  238         fcomp                   ;
  239         fstsw   [bp-2]          ; Store status word
  240         mov     ax,[bp-2]       ;
  241         sahf                    ;
  242         jb      SizeDM3         ; Jump if ST > ymin
  243         fld     st              ;
  244         fstp    [bx.ymin]       ;
  245         jmp     short SizeDM4   ;
  246 SizeDM3:
  247         fld     [bx.ymax]       ; Compare ypos to ymax
  248         fcomp                   ;
  249         fstsw   [bp-2]          ;
  250         mov     ax,[bp-2]       ;
  251         sahf                    ;
  252         ja      SizeDM4         ;
  253         fld     st              ;
  254         fstp    [bx.ymax]       ;
  255 SizeDM4:
  256         fxch                    ; Swap xpos and ypos back
  257         pop     ax              ; Deallocate local for FPU status word
  258 
  259         ret                     ; Done.
  260 lsysf_dosizedm  ENDP
  261 
  262         PUBLIC  lsysf_dosizegf
  263 
  264 lsysf_dosizegf  PROC    USES SI,lsyscmd:ptr
  265         mov     si,lsyscmd      ;
  266         xor     bx,bx           ; BX <- angle * sizeof(long double)
  267         mov     bl,[si.angle]   ;
  268         shl     bx,1            ;
  269         mov     ax,bx           ;
  270         shl     ax,1            ;
  271         shl     ax,1            ;
  272         add     bx,ax           ;
  273         fld     st(2)           ; size xpos ypos size aspect
  274         fld     coss_f[bx]      ; size*cmd->coss[cmd->angle]
  275         fmul                    ;
  276         faddp   st(1),st        ; xpos ypos size aspect
  277         fld     st(2)           ; size xpos ypos size aspect
  278         fld     sins_f[bx]      ; size*cmd->sins[cmd->angle]
  279         fmul                    ;
  280         faddp   st(2),st        ; xpos ypos size aspect
  281 
  282         push    ax              ; Allocate a local for FPU status word
  283 
  284         fld     [si.xmin]       ; Compare xpos to xmin
  285         fcomp                   ;
  286         fstsw   [bp-4]          ; Store status word
  287         mov     ax,[bp-4]       ;
  288         sahf                    ;
  289         jb      SizeGF1         ; Jump if ST > xmin
  290         fld     st              ;
  291         fstp    [si.xmin]       ;
  292         jmp     short SizeGF2   ;
  293 SizeGF1:
  294         fld     [si.xmax]       ; Compare to xmax
  295         fcomp                   ;
  296         fstsw   [bp-4]          ; Store status word
  297         mov     ax,[bp-4]       ;
  298         sahf                    ;
  299         ja      SizeGF2         ; Jump if ST < xmax
  300         fld     st              ;
  301         fstp    [si.xmax]       ;
  302 SizeGF2:
  303         fxch                    ; Swap xpos and ypos
  304         fld     [si.ymin]       ; Compare ypos to ymin
  305         fcomp                   ;
  306         fstsw   [bp-4]          ; Store status word
  307         mov     ax,[bp-4]       ;
  308         sahf                    ;
  309         jb      SizeGF3         ; Jump if ST > ymin
  310         fld     st              ;
  311         fstp    [si.ymin]       ;
  312         jmp     short SizeGF4   ;
  313 SizeGF3:
  314         fld     [si.ymax]       ; Compare ypos to ymax
  315         fcomp                   ;
  316         fstsw   [bp-4]          ;
  317         mov     ax,[bp-4]       ;
  318         sahf                    ;
  319         ja      SizeGF4         ;
  320         fld     st              ;
  321         fstp    [si.ymax]       ;
  322 SizeGF4:
  323         fxch                    ; Swap xpos and ypos back
  324         pop     ax              ; Deallocate local for FPU status word
  325         ret
  326 lsysf_dosizegf  ENDP
  327 
  328         PUBLIC  lsysf_dodrawg
  329 
  330 lsysf_dodrawg   PROC    USES SI,lsyscmd:ptr
  331         mov     si,lsyscmd      ; Get pointer to structure
  332         xor     bx,bx           ; Get angle offset
  333         mov     bl,[si.angle]   ;
  334         mov     al,10           ;
  335         mul     bl              ;
  336         xchg    ax,bx           ;
  337         fld     coss_f[bx]      ; xpos += cmd->size * cmd->coss[cmd->angle]
  338         fmul    st,st(3)        ;
  339         fadd                    ;
  340         fld     sins_f[bx]      ; ypos += cmd->size * cmd->sins[cmd->angle]
  341         fmul    st,st(3)        ;
  342         faddp   st(2),st        ;
  343         ret                     ;
  344 lsysf_dodrawg   ENDP
  345 
  346         PUBLIC  lsysf_dodrawd
  347 
  348 lsysf_dodrawd   PROC    lsyscmd:PTR
  349         mov     bx,lsyscmd      ; Get pointer to structure
  350         xor     ax,ax           ; Push last parm to draw_line
  351         mov     al,[bx.curcolor]
  352         push    ax              ;
  353         sub     sp,8            ; Allocate the rest of draw_line's parms
        fist    word ptr [bp-10] ; Store xpos
        fxch                    ; Store ypos
        fist    word ptr [bp-8] ;
        fxch                    ;

        LSYS_SINCOS 10          ; c s xpos ypos size aspect

        fmul    st,st(5)        ; c*aspect s xpos ypos size aspect
        fmul    st,st(4)        ; size*c*aspect s xpos ypos size aspect
        faddp   st(2),st        ; s xpos ypos size aspect
        fmul    st,st(3)        ; s*size xpos ypos size aspect
        faddp   st(2),st        ; xpos ypos size aspect

        fist    word ptr [bp-6] ; Store xpos
        fxch                    ; Store ypos
        fist    word ptr [bp-4] ;
        fxch                    ;

        call    far ptr draw_line       ;
        add     sp,10           ; Remove parameters
        ret                     ;
lsysf_dodrawd   ENDP

        PUBLIC  lsysf_dodrawm

lsysf_dodrawm   PROC    lsyscmd:ptr
        mov     bx,lsyscmd      ; Get pointer to structure, to quiet warning
        LSYS_SINCOS 0           ;
        fmul    st,st(5)        ; c*aspect s xpos ypos size aspect
        fmul    st,st(4)        ; size*c*aspect s xpos ypos size aspect
        faddp   st(2),st        ; s xpos ypos size aspect
        fmul    st,st(3)        ; s*size xpos ypos size aspect
        faddp   st(2),st        ; xpos ypos size aspect
        ret                     ;
lsysf_dodrawm   ENDP

        PUBLIC  lsysf_dodrawf

lsysf_dodrawf   PROC    USES SI, lsyscmd:ptr
        mov     si,lsyscmd              ; Get pointer to structure
        xor     ax,ax                   ; Push curcolor for draw_line
        mov     al,[si.curcolor]        ;
        push    ax                      ;
        sub     sp,8                    ; Allocate the rest of the draw_line call
        fist    word ptr [bp-12]        ; Store xpos in draw_line parms
        fxch                            ; Store ypos in draw_line parms
        fist    word ptr [bp-10]        ;
        fxch                            ;

        xor     bx,bx                   ; BX <- offset into cos/sin arrays
        mov     bl,[si.angle]           ;
        mov     al,10                   ;
        mul     bl                      ;
        xchg    ax,bx                   ;

        fld     st(2)           ; xpos += size*cmd->coss[cmd->angle]
        fld     coss_f[bx]      ;
        fmul
        fadd                    ;
        fist    word ptr [bp-8] ; Store new xpos in draw_line parms

        fld     st(2)           ; ypos += size*cmd->sins[cmd->angle]
        fld     sins_f[bx]      ;
        fmul                    ;
        faddp   st(2),st        ;
        fxch                    ; Store new ypos in draw_line parms
        fist    word ptr [bp-6] ;
        fxch                    ;
        call    far ptr draw_line       ; Call the line-drawing routine
        add     sp,10           ; Deallocate the stuff we pushed
        ret                     ;
lsysf_dodrawf   ENDP

        PUBLIC  lsysf_doslash

lsysf_doslash   PROC    lsyscmd:ptr
        mov     bx,lsyscmd      ; Get pointer
        fld     tbyte ptr [bx.num]
        cmp     [bx.reverse],0
        jnz     DoSlashDec
        faddp   st(5),st
        ret
DoSlashDec:
        fsubp   st(5),st
        ret
lsysf_doslash   ENDP

        PUBLIC  lsysf_dobslash

lsysf_dobslash   PROC    lsyscmd:ptr
        mov     bx,lsyscmd      ; Get pointer
        fld     tbyte ptr [bx.num]
        cmp     [bx.reverse],0
        jz      DoBSlashDec
        faddp   st(5),st
        ret
DoBSlashDec:
        fsubp   st(5),st
        ret
lsysf_dobslash   ENDP

        PUBLIC  lsys_prepfpu

lsys_prepfpu    PROC    lsyscmd:ptr
        mov     bx,lsyscmd      ; Get pointer to structure
        fld     [bx.realangle]  ; Load: xpos ypos size aspect realangle
        fld     [bx.aspect]     ;
        fld     [bx.ssize]      ;
        fld     [bx.ypos]       ;
        fld     [bx.xpos]       ;
        ret                     ; Return.
lsys_prepfpu    ENDP

        PUBLIC  lsys_donefpu

lsys_donefpu    PROC    lsyscmd:ptr
        mov     bx,lsyscmd      ; Get pointer to structure
        fstp    [bx.xpos]       ; Save: xpos ypos size aspect realangle
        fstp    [bx.ypos]       ;
        fstp    [bx.ssize]      ;
        fstp    [bx.aspect]     ;
        fstp    [bx.realangle]  ;
        ret
lsys_donefpu    ENDP

        END