;====================================================================
;
;    P L O T  -  Assembly language point plot for Turbo Pascal
;
;====================================================================
;
;    by Jeff Duntemann     6-Feb-86
;
; PLOT is a high-speed replacement for Turbo Pascal's rather slow
; point-plotting routine of the same name.  This PLOT takes the same
; parameters as Turbo's own PLOT but CAN ONLY BE USED IN HIGH
; RESOLUTION GRAPHICS MODE.  It won't crash you in medium res but it
; won't plot colors correctly either.
;
; This .ASM file is intended to be assembled with Microsoft's MASM,
; and was developed under MASM V4.0.  Nothing fancy is going on here
; so presumably it will assemble correctly using earlier versions of
; MASM.  Once assembled, link it, EXE2BIN it, and then include it
; into your Turbo Pascal programs by calling it as External:
;
;    PROCEDURE Plot(X,Y,Color : Integer); External('PLOT.COM');
;
; In COMPLETE TURBO PASCAL, there are also instructions for turning
; the PLOT.COM file into an INLINE statement so that you no longer
; need to have PLOT.COM on your source code disk as a separate file.
;
; This is by no means the fastest possible point plot routine for
; the IBM PC.  Certainly you patient clock-cycle pinchers could
; squeeze a little more performance out of it.  Do try, and let me
; know how well you do!
;
; FROM:    COMPLETE TURBO PASCAL by Jeff Duntemann
;          Scott, Foresman & Co.  1986   ISBN 0-673-18600-1
;
;

BUFBASE   EQU     0B800H               ; BASE OF VIDEO RAM

CODE      SEGMENT PUBLIC
          ASSUME  CS:CODE
          PUBLIC  PLOT
;
;
;  EQUATES FOR ARGUMENTS TO PLOT
;
COLOR     EQU     4[BP]                ; OFFSET OF COLOR PARM
Y         EQU     6[BP]                ; OFFSET OF Y COORDINATE
X         EQU     8[BP]                ; OFFSET OF X COORDINATE

PLOT      PROC    NEAR
          PUSH    BP
          MOV     BP,SP
          PUSH    DS

;
;  FIRST WE CALCULATE THE Y OFFSET INTO THE VIDEO BUFFER
;
BEGIN:    MOV     AX,Y                 ; PUT Y IN AX REGISTER
          MOV     AH,AL                ;  AND LOW BYTE IN AH TOO
          AND     AX,01FEH             ; MASK AX WITH $01FE
          MOV     CL,3                 ; MULTIPLY AX BY 8 VIA SHIFT
          SHL     AX,CL
          MOV     BX,AX                ; COPY NEW VALUE INTO BX
          AND     BH,7                 ; ZERO OUT HIGH 5 BITS OF BH
          MOV     CL,2                 ; BY NOW AX HAS BEEN MULTIPLIED
          SHL     AX,CL                ;   BY 32...
          ADD     BX,AX                ; ADD AX TO BX; BX NOW CONTAINS
                                       ;   Y VALUE MUTIPLIED BY 40

;
;  NOW WE CALCULATE THE X OFFSET INTO THE VIDEO BUFFER
;
          MOV     AX,X                 ; PUT X IN AX REGISTER
          MOV     CX,AX                ;   AND IN THE CX REGISTER
          SHR     AX,1                 ; WE CAN'T USE CL TO SHIFT HERE
          SHR     AX,1                 ;   SO WE SHIFT BY 1 THREE TIMES
          SHR     AX,1                 ;   TO DIVIDE AX BY 8
                                       ;   WHICH IS THE X OFFSET
          ADD     BX,AX                ; ADD X AND Y OFFSETS INTO BUFFER

;
;  HERE WE FETCH THE VIDEO BUFFER BYTE AND MODIFY THE DESIRED PIXEL
;
          AND     CX,7                 ; LOW 3 BITS OF CX CONTAIN BIT #
                                       ;   OF DESIRED PIXEL
          MOV     AL,080H              ; STORE SINGLE BIT INTO AL BIT 7
          SHR     AL,CL                ; SHIFT BIT DOWN BY PIXEL NUMBER
          MOV     DX,BUFBASE           ; SET DS TO SEGMENT OF VIDEO BUFFER
          MOV     DS,DX
          MOV     CL,[DS:BX]           ; BRING BYTE IN FROM BUFFER
          MOV     DX,COLOR             ; PUT COLOR PARM INTO DX
          CMP     DL,0                 ; IS COLOR=0?
          JE      PRESET

PSET:     OR      CL,AL                ; OR IN THE NEW PIXEL
          MOV     [DS:BX],CL           ; AND PUT IT BACK IN THE BUFFER
          JMP     BYE

PRESET:   XOR     AL,0FFH              ; INVERT THE PIXEL MASK
          AND     CL,AL                ; AND THE MASK AGAINST THE BYTE
          MOV     [DS:BX],CL           ; AND PUT IT BACK IN THE BUFFER
;
;  DONE...CLEAN UP THE STACK AND LEAVE
;
BYE:      POP     DS                   ; RESTORE DS
          MOV     SP,BP                ; CLEAN UP STACK AND LEAVE
          POP     BP                   ; RESTORE BP

          RET     6                    ; TRASH 6 BYTES FOR PARMS

PLOT      ENDP
CODE      ENDS
          END

