;        ЩЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЛ
;        КлппппппппппппппппппппппппппппппппппппппппппппппппппппппппппплК
;        Кл                                                           лК
;        Кл                 Meridian Software Systems                 лК
;        Кл                                                           лК
;        Кл                    Copyright (C)  1990                    лК
;        Кл                                                           лК
;        Кл                    ALL RIGHTS RESERVED                    лК
;        Кл                                                           лК
;        КлмммммммммммммммммммммммммммммммммммммммммммммммммммммммммммлК
;        ШЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭМ

              TITLE     'ADA Utility Routines'
              NAME      Ada_Util
              PAGE      55, 132


ARGx1         EQU       WORD PTR [BP+ 6]  ; Stack frame addressing
ARGy1         EQU       WORD PTR [BP+ 8]
ARGx2         EQU       WORD PTR [BP+10]
ARGy2         EQU       WORD PTR [BP+12]
ARGn          EQU       WORD PTR [BP+14]
VARleafincr   EQU       WORD PTR [BP- 6]
VARincr1      EQU       WORD PTR [BP- 8]
VARincr2      EQU       WORD PTR [BP-10]
VARroutine    EQU       WORD PTR [BP-12]

ByteOffShift  EQU       3                 ; Used to convert pixels to byte off

COMMENT *

DGROUP        GROUP     $$DATA

*

$$DATA        SEGMENT  PARA PUBLIC 'DATA'


START_X       DW ?
END_X         DW ?
START_Y       DW ?
END_Y         DW ?
COLOR         DB ?
W_UPPER_X     DW ?
W_UPPER_Y     DW ?
W_LOWER_X     DW ?
W_LOWER_Y     DW ?
CLP_ENBL      DW ?
VIDEO_PAGE    DB ?
DIAGONAL_Y_INCREMENT DW ?
DIAGONAL_X_INCREMENT DW ?
SHORT_DISTANCE       DW ?
STRAIGHT_X_INCREMENT DW ?
STRAIGHT_Y_INCREMENT DW ?
STRAIGHT_COUNT       DW ?
DIAGONAL_COUNT       DW ?


CRTCParms     DB        00H,35H
	      DB        01H,2DH
	      DB        02H,2EH
	      DB        03H,07H
	      DB        04H,5BH
	      DB        05H,02H
	      DB        06H,57H
	      DB        07H,57H
	      DB        09H,03H


CRTCParmsLen  EQU       ($-CRTCParms)/2

BIOSData      DB        7
	      DW        80
	      DW        8000H
	      DW        0
	      DW        0
	      DW        0
	      DW        0
	      DW        0
	      DW        0
	      DW        0
	      DW        0
	      DW        0
	      DW        0
              DB        0
CRTCAddr      DW        3B4H
CRTMode       DB        0AH
              DB        0

BIOSDataLen   EQU       $-BIOSData

$$DATA        ENDS


ASM_PACKAGE   SEGMENT   PARA PUBLIC 'CODE'
	      ASSUME    CS: ASM_PACKAGE, DS: $$DATA

              PUBLIC    HERC_GRAPH_MODE
HERC_GRAPH_MODE PROC      FAR

	      PUSH      BP
	      MOV       BP,SP
	      PUSH      SI
	      PUSH      DI

	      MOV       AX,40H
	      MOV       ES,AX
	      MOV       DI,49H

	      MOV       SI,OFFSET $$DATA: BIOSData
	      MOV       CX,BIOSDataLen
	      REP       MOVSB

	      MOV       DX,3BFH
	      MOV       AL,1
	      OUT       DX,AL

	      MOV       DX,3B8H
	      XOR       AL,AL
	      OUT       DX,AL

	      SUB       DL,4
	      MOV       SI,OFFSET $$DATA: CRTCParms
	      MOV       CX,CRTCParmsLen

L01:          LODSW
	      OUT       DX,AX
	      LOOP      L01

	      ADD       DL,4
	      MOV       AL,CRTMode
	      OUT       DX,AL

	      POP       DI
	      POP       SI
	      MOV       SP,BP
	      POP       BP
	      RET

HERC_GRAPH_MODE ENDP


	      PUBLIC    VIDEO_MODE
VIDEO_MODE    PROC      FAR

	      PUSH      BP
	      MOV       BP,SP
	      MOV       AX, 6[BP]         ; Get Video mode
	      MOV       AH, 00H
	      INT       10H
	      POP       BP
	      RET       02H

VIDEO_MODE    ENDP


	      PUBLIC    PLOT
PLOT          PROC      FAR

	      PUSH      BP                ; Save base pointer
	      MOV       BP,SP
	      MOV       CX,  6[BP]        ; Get column of pixel
	      MOV       DX,  8[BP]        ; Get row    of pixel
	      MOV       AX, 10[BP]        ; Get color
	      MOV       BX, 12[BP]        ; Get Video Page
	      XCHG      BH, BL
	      MOV       AH,0CH            ; Plot pixel
	      INT       10H
	      POP       BP
	      RET       08H

PLOT          ENDP

;----------------------------------------------------------------
PAGE
;----------------------------------------------------------------
;
; This subroutine draws a straight line between two points in
; preset video mode, and location parameters passed from calling routine
;
;----------------------------------------------------------------

	      PUBLIC    DRAW
DRAW          PROC      FAR

	      PUSH      BP
	      MOV       BP,SP             ; Save Stack
	      MOV       AX,  6[BP]        ; Get X1
	      MOV       START_X,AX
	      MOV       AX,  8[BP]        ; Get Y1
	      MOV       START_Y,AX
	      MOV       AX, 10[BP]        ; Get X2
	      MOV       END_X,AX
	      MOV       AX, 12[BP]        ; Get Y2
	      MOV       END_Y,AX
	      MOV       AX, 14[BP]        ; Get color
	      MOV       COLOR,AL
	      MOV       AX, 16[BP]        ; Get window_upper_x coordinate
	      MOV       W_UPPER_X,AX
	      MOV       AX, 18[BP]        ; Get window_upper_y coordinate
	      MOV       W_UPPER_Y,AX
	      MOV       AX, 20[BP]        ; Get window_lower_x coordinate
	      MOV       W_LOWER_X,AX
	      MOV       AX, 22[BP]        ; Get window_lower_y coordinate
	      MOV       W_LOWER_Y,AX
	      MOV       AX, 24[BP]        ; Get window clipping (boolean)
	      MOV       CLP_ENBL,AX
	      MOV       AX, 26[BP]        ; Get Video Page
	      MOV       VIDEO_PAGE,AL
	      MOV       AX,START_X        ; Are the points the same?
	      CMP       AX,END_X
	      JNE       NOT_SAME
	      MOV       AX,START_Y
	      CMP       AX,END_Y
	      JNE       NOT_SAME
	      MOV       CX,START_X        ; Yes, then just plot one point
	      MOV       DX,START_Y
	      MOV       AL,COLOR
	      MOV       BH,VIDEO_PAGE
	      MOV       AH,0CH
	      INT       10H
	      POP       BP
	      RET       14H               ; No, then draw a line between them
NOT_SAME:
	      MOV       CX,01H
	      MOV       DX,01H
	      MOV       DI,END_Y
	      SUB       DI,START_Y        ; Get DeltaY = EndY - StartY
	      JGE       KEEP_Y
	      NEG       DX
	      NEG       DI                ; Otherwise force DeltaY positive
KEEP_Y:
	      MOV       DIAGONAL_Y_INCREMENT,DX
	      MOV       SI,END_X
	      SUB       SI,START_X        ; Get DeltaX = EndX - StartX
	      JGE       KEEP_X
	      NEG       CX
	      NEG       SI                ; Force DeltaX positive
KEEP_X:
	      MOV       DIAGONAL_X_INCREMENT,CX
	      CMP       SI,DI
	      JGE       HORZ_SEG
	      MOV       CX,0
	      XCHG      SI,DI
	      JMP       SAVE_VALUES
HORZ_SEG:
	      MOV       DX,00H
SAVE_VALUES:
	      MOV       SHORT_DISTANCE,DI
	      MOV       STRAIGHT_X_INCREMENT,CX
	      MOV       STRAIGHT_Y_INCREMENT,DX
	      MOV       AX,SHORT_DISTANCE
	      SHL       AX,1
	      MOV       STRAIGHT_COUNT,AX
	      SUB       AX,SI
	      MOV       BX,AX
	      SUB       AX,SI
	      MOV       DIAGONAL_COUNT,AX
	      MOV       CX,START_X
	      MOV       DX,START_Y
	      INC       SI
MAINLOOP:
	      DEC       SI
	      JZ        LINE_FINISHED
	      MOV       AX,CLP_ENBL       ; If window clipping is enable
	      CMP       AL,00H            ; then have to check boundaries
	      JZ        PLOT_THE_POINT    ; otherwise just plot the point
	      CMP       CX,W_UPPER_X      ; Check for LEFT boundary
	      JLE       BYPASS            ; if less than then don't plot it
	      CMP       CX,W_LOWER_X      ; Check for RIGHT boundary
	      JGE       BYPASS            ; if less than then don't plot it
	      CMP       DX,W_UPPER_Y      ; Check for UPPER boundary
	      JLE       BYPASS            ; if less than then don't plot it
	      CMP       DX,W_LOWER_Y      ; Check for LOWER boundary
	      JGE       BYPASS            ; if less than then don't plot it
PLOT_THE_POINT:
	      MOV       AH,12
	      MOV       AL,COLOR
	      PUSH      BX                ; Save BX
	      MOV       BH,VIDEO_PAGE
	      INT       10H
	      POP       BX                ; Restore BX
BYPASS:
	      CMP       BX,0
	      JGE       DIAGONAL_LINE
	      ADD       CX,STRAIGHT_X_INCREMENT
	      ADD       DX,STRAIGHT_Y_INCREMENT
	      ADD       BX,STRAIGHT_COUNT
	      JMP       SHORT MAINLOOP
DIAGONAL_LINE:
	      ADD       CX,DIAGONAL_X_INCREMENT
	      ADD       DX,DIAGONAL_Y_INCREMENT
	      ADD       BX,DIAGONAL_COUNT
	      JMP       SHORT MAINLOOP
LINE_FINISHED:
	      POP       BP
	      RET       16H

DRAW          ENDP


	      PUBLIC    BEEP
BEEP          PROC      FAR

	      IN        AL,61H            ; Access sound port
	      AND       AL,0FEH           ; Clear audio bit only
	      XOR       AL,2              ; Toggle audio gate bit to beep
	      OUT       61H,AL            ; Do it
	      RET

BEEP          ENDP

	      PUBLIC    READPIX
READPIX       PROC      FAR

	      PUSH      BP
	      MOV       BP,SP
	      MOV       CX, 6[BP]         ; Get pixel x-coordinate
	      MOV       DX, 8[BP]         ; Get pixel y-coordinate
	      MOV       AH,0DH            ; Read attribute mode
	      MOV       BH,00H            ; Video page 0 only
	      INT       10H               ; Call video intr
	      MOV       CL,AL             ; Return attribute in CX for Meridian Ada
	      MOV       CH,0H
	      POP       BP
	      RET       4H

READPIX       ENDP


	      PUBLIC    CLRSCR
CLRSCR        PROC      FAR

	      MOV       AX,0619H          ; AH = scroll up    AL = 25 rows
	      MOV       BH,00H            ; BH = black
	      MOV       CX,0000H          ; Left corner
	      MOV       DX,184FH          ; Right corner
	      INT       10H
	      RET

CLRSCR        ENDP

ASM_PACKAGE   ENDS


	      END

