home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / C-ASM_VI.ARJ / PROGASM.ZIP / PROG086P.ASM < prev    next >
Assembly Source File  |  1988-04-17  |  7KB  |  329 lines

  1.  
  2. ;************************************************************************
  3. ; Line (x0, y0, x1, y1,c ): draw line from (x0,y0) to (x1,y1)        *
  4. ;        with a color (c).                    *
  5. ;        This routine is divided into three parts. Horizontal    *
  6. ;        lines are done in the first part, vertical lines in    *
  7. ;        second part, and rest in the third part.  The lines    *
  8. ;        in the third part are done using the Bresenhams     *
  9. ;        algorithm.                        *
  10. ; entry : sp + 2 = x0                            *
  11. ;      sp + 4 = y0                            *
  12. ;      sp + 6 = x1                            *
  13. ;      sp + 8 = y1                            *
  14. ;      sp + 10= color                        *
  15. ;************************************************************************
  16.  
  17. X0    EQU    [BP+14]
  18. Y0    EQU    [BP+12]
  19. X1    EQU    [BP+10]
  20. Y1    EQU    [BP+8]
  21. Color    EQU    [BP+6]
  22.  
  23.     PUBLIC    Line
  24.  
  25. Line    PROC    FAR
  26.     PUSH    BP
  27.     MOV    BP,SP
  28.     SUB    SP,6            ;Declare three local variables
  29.  
  30.     PUSH    DI
  31.     PUSH    SI
  32.     PUSH    DS
  33.     PUSH    ES
  34.  
  35.     MOV    AX,X0            ; make sure that x1 >= x0
  36.     MOV    CX,X1
  37.     CMP    CX,AX
  38.     JGE    Get_Offset
  39.     MOV    BX,Y0
  40.     MOV    DX,Y1
  41.     MOV    X0,CX
  42.     MOV    Y0,DX
  43.     MOV    X1,AX
  44.     MOV    Y1,BX
  45.  
  46. ;-------COMPUTE ADDRESS AND MASK FOR FIRST PIXEL -------------
  47. Get_Offset:
  48.     ;--- Compute offset and save on stack
  49.     MOV    CL,4            ; offset = 80 * y + x/8
  50.     MOV    AX,Y0
  51.     SHL    AX,CL
  52.     MOV    BX,AX
  53.     SHL    AX,1
  54.     SHL    AX,1
  55.     ADD    AX,BX
  56.     MOV    BX,X0            ; + x/8
  57.     MOV    CL,3
  58.     SHR    BX,CL
  59.     ADD    AX,BX
  60.     PUSH    AX            ; save offset on stack, later pop to DI
  61.  
  62.     ;--- Compute mask and save on the stack
  63.  
  64.     MOV    CX,X0            ; compute which bit (x mod 8) to modify
  65.     AND    CL,7
  66.     MOV    BX,80h
  67.     SHR    BX,CL
  68.     PUSH    BX            ; save mask on stack, later pop to SI
  69.     MOV    DX,03CEh        ; enable only the bit(within a byte)
  70.     MOV    AL,08H            ; to be changed
  71.     OUT    DX,AL
  72.     INC    DX
  73.     MOV    AL,BL            ; ... reg-bx has the correct bit
  74.     OUT    DX,AL
  75.  
  76.     ;--- Load set/reset registers with current color
  77.  
  78.     MOV    DX,03CEh        ; move color into reset register
  79.     XOR    AL,AL
  80.     OUT    DX,AL
  81.     INC    DX
  82.     MOV    AX,Color
  83.     OUT    DX,AL
  84.     DEC    DX            ; enable use of reset register
  85.     MOV    AL,1
  86.     OUT    DX,AL
  87.     INC    DX
  88.     MOV    AL,0FH
  89.     OUT    DX,AL
  90.     MOV    DX,03C4h        ; enable all four planes for writting
  91.     MOV    AL,2
  92.     OUT    DX,AL
  93.     INC    DX
  94.     MOV    AL,0FH
  95.     OUT    DX,AL
  96.  
  97.     ;--- Load segment register
  98.  
  99.     MOV    DX,0A000h
  100.     MOV    DS,DX
  101.     MOV    ES,DX
  102.  
  103. ;-------COMPUTE  DX AND DY ----------------------------------------
  104. ;    DETERMINE IF HORIZONTAL, VERTICAL OR DIAGONNAL LINE
  105.  
  106.     MOV    AX,80            ; set raster increment
  107.     MOV    [bp-6],AX
  108.     MOV    SI,X1            ; compute dx           reg-si
  109.     SUB    SI,X0
  110.     MOV    DI,Y1            ; compute dy           reg-di
  111.     SUB    DI,Y0
  112.     JGE    DyIsPos
  113.     NEG    AX
  114.     MOV    [bp-6],AX
  115.     NEG    DI
  116. DyIsPos:
  117.     CMP    SI,0            ; jump according to type of line
  118.     JZ    Vert
  119.     CMP    DI,0
  120.     JZ    Horiz
  121.     JMP    Diag
  122.  
  123. ;-------GENERATE A VERTICAL LINE -----------------
  124.  
  125. Vert:    MOV    cx,di            ; set up counter
  126.     INC    cx
  127.     MOV    bx,[bp-6]
  128.  
  129.     POP    SI            ; fetch mask
  130.     MOV    DX,03CEh        ; set mask
  131.     MOV    AL,08h
  132.     OUT    DX,AL
  133.     INC    DX
  134.     MOV    AX,SI
  135.     OUT    DX,AL
  136.  
  137.     POP    DI            ; fetch offset
  138. LoopVert:
  139.     MOV    AL,[DI]         ; latch data(to preserve other 7 bits i
  140.     MOV    [DI],AL         ; write new data (only one bit will be
  141.     ADD    DI,BX            ; update offset
  142.     LOOP    LoopVert
  143.     JMP    LineDone
  144.  
  145. ;-------GENERATE A HORIZONTAL LINE ---------------
  146.  
  147. Horiz:    MOV    CX,SI            ; set counter of pixels
  148.     POP    SI            ; fetch mask
  149.     POP    DI            ; fetch offset
  150.  
  151.     ;---    draw pixels from the leading partial byte
  152.  
  153.     MOV    AX,X0
  154.     AND    AX,07h            ; check for partial byte
  155.     JZ    FullBytes
  156.     MOV    BX,0FFh         ; compute the mask
  157.     PUSH    CX
  158.     MOV    CX,AX
  159.     SHR    BX,CL
  160.     POP    CX
  161.     ADD    CX,AX            ; update counter
  162.     SUB    CX,08h
  163.     JGE    MaskSet         ; modify mask if only one byte
  164.     NEG    CX
  165.     SHR    BX,CL
  166.     SHL    BX,CL
  167.     XOR    CX,CX            ; restore counter
  168. MaskSet:
  169.     MOV    DX,03CEh        ; set the mask
  170.     MOV    AL,08h
  171.     OUT    DX,AL
  172.     INC    DX
  173.     MOV    AL,BL
  174.     OUT    DX,AL
  175.     MOV    AH,[DI]         ; latch data
  176.     MOV    [DI],AL         ; write new data
  177.     INC    DI            ; update offset
  178.  
  179.     ;---    draw pixels from the middle complete bytes
  180. FullBytes:                ;
  181.     MOV    BX,CX            ; check if any bytes to set
  182.     CMP    DX,8
  183.     JL    TrailBytes
  184.     SHR    CX,1            ; compute count
  185.     SHR    CX,1
  186.     SHR    CX,1
  187.     MOV    DX,03CEh        ; set the mask
  188.     MOV    AL,08h
  189.     OUT    DX,AL
  190.     INC    DX
  191.     MOV    AL,0FFh
  192.     OUT    DX,AL
  193.  
  194.     REP    STOSB            ; fill complete bytes
  195.  
  196.     ;---    draw pixels from the trailing partial byte
  197. TrailBytes:
  198.     AND    BX,07h
  199.     JZ    HorizDone
  200.     MOV    AX,0FFFFh         ; compute mask
  201.     MOV    CX,BX
  202.     SHR    AX,CL
  203.     XOR    AH,0FFh          ; set the mask
  204.     MOV    DX,03CEh
  205.     MOV    AL,08h
  206.     OUT    DX,AL
  207.     INC    DX
  208.     MOV    AL,AH
  209.     OUT    DX,AL
  210.     MOV    AL,[DI]          ; latch data
  211.     MOV    [DI],AL          ; set new data
  212. HorizDone:
  213.     JMP    LineDone
  214.  
  215. ;----------------------- GENERATE A DIAGONAL LINE -----------------
  216.  
  217.     ;--- figure out which quarter does the line lie in
  218.  
  219. Diag:    CMP    SI,DI            ; Is dy > dx
  220.     JLE    oct12            ; ...Yes, do processing in octants
  221.                     ;    1 and 2
  222.     ; Compute constants for octant zero and three
  223.     ; This is where x is the major direction and y is minor
  224.  
  225. oct03:    MOV    CX,SI            ; set counter to dx+1
  226.     INC    CX
  227.     SAL    DI,1            ; d1 = dy*2        reg-di
  228.     MOV    BX,DI            ; d  = dy*2-dx        reg-bx
  229.     SUB    BX,SI
  230.     NEG    SI            ; d2 = dy*2-dx-dx    reg-si
  231.     ADD    SI,BX
  232.  
  233.     MOV    [bp-2],di        ; save d1
  234.     MOV    [bp-4],si        ; save d2
  235.     MOV    DX,03CEh        ; select BIT MASK register
  236.     MOV    AL,08h
  237.     OUT    DX,AL
  238.     INC    DX
  239.     POP    AX            ; fetch mask
  240.     POP    DI            ; fetch address
  241.  
  242.     ;-------------- GENERATE LINE IN THE OCTANT ZERO AND THREE ------
  243.  
  244. next0:    OUT    DX,AL            ; enable a bit in a byte
  245.     MOV    AH,[DI]         ; latch old data
  246.     MOV    [DI],AH         ; modify (enabled bits)
  247.  
  248.     ROR    AL,1            ; update mask
  249.     ADC    DI,0            ; update byte address
  250.  
  251.     TEST    BX,8000H        ; if d >= 0 then ...
  252.     JNZ    dneg0
  253.     ADD    BX,[BP-4]        ; ... d = d + d2
  254.     ADD    DI,[BP-6]        ; update offset to next scan line
  255.     LOOP    next0
  256.     JMP    LineDone
  257.  
  258. dneg0:    ADD    BX,[BP-2]        ; if d < 0 then d = d + d1
  259.     LOOP    next0
  260.     JMP    LineDone
  261.  
  262.     ;----------------------------------------------------------------
  263.  
  264.     ;---    Compute constants for octant one and two
  265.  
  266. oct12:    MOV    CX,DI            ; set counter to dy+1
  267.     INC    CX
  268.     SAL    SI,1            ; d1 = dx * 2
  269.     MOV    BX,SI            ; d  = dx * 2 - dy
  270.     SUB    BX,DI
  271.     NEG    DI            ; d2 = -dy + dx * 2 - dy
  272.     ADD    DI,BX
  273.  
  274.     MOV    [BP-4],DI        ; save d2
  275.     MOV    [BP-2],SI        ; save d1
  276.     MOV    dx,03CEh        ; select BIT MASK register
  277.     MOV    al,08h
  278.     OUT    DX,AL
  279.     INC    DX
  280.     POP    AX            ; fetch mask
  281.     POP    DI            ; fetch address
  282.     OUT    DX,AL            ; enable a bit in a byte
  283.  
  284.     ;-----GENERATE A LINE IN THE OCTANT ONE AND TWO -----------------
  285.  
  286. next1:    MOV    AH,[DI]         ; latch old data
  287.     MOV    [DI],AH         ; modify (enabled bits)
  288.  
  289.     ADD    DI,[BP-6]        ; update offset (y = y+1)
  290.  
  291.     TEST    BX,8000H        ; if d >= 0 then ...
  292.     JNZ    dneg1
  293.  
  294.     ADD    BX,[BP-4]        ; ... d = d + d2
  295.     ROR    AL,1            ; ... update mask (x = x+1)
  296.     ADC    DI,0            ; ... update offset
  297.     OUT    DX,AL            ; Enable next bit within a byte
  298.     LOOP    next1
  299.     JMP    LineDone
  300.  
  301. dneg1:    ADD    BX,[BP-2]        ; if d < 0 then d = d + d1
  302.     LOOP    next1
  303.  
  304.     ;----------------------------------------------------------------
  305.     ;--- Restore PLANE ENABLE and BIT MASK registers
  306. LineDone:
  307.     MOV    DX,03CEh        ; Enable all 8-bits in a byte for write
  308.     MOV    AL,08h            ; by setting BIT MASK register to Fhex
  309.     OUT    DX,AL
  310.     INC    DX
  311.     MOV    AL,0FFh
  312.     OUT    DX,AL
  313.  
  314.     DEC    DX            ; Disable SET/RESET function
  315.     MOV    AL,1
  316.     OUT    DX,AL
  317.     INC    DX
  318.     XOR    AX,AX
  319.     OUT    DX,AL
  320.  
  321.     POP    ES
  322.     POP    DS
  323.     POP    SI
  324.     POP    DI
  325.     MOV    SP,BP
  326.     POP    BP
  327.     RET    10
  328. Line    ENDP
  329.