
; *******************************************************
; *							*
; *          Graphic Functions for Turbo Pascal         *
; *                 version 0.2 alpha                   *
; *							*
; *          Copyright (c) 1999, 2000 fra.iesus         *
; *                                                     *
; *******************************************************

.286
        TITLE   GRAPH

DATA    SEGMENT WORD PUBLIC
        EXTRN GrSeg:WORD    ;gr. segment
                            ;mode info
        EXTRN GrMode:WORD
        EXTRN XLength:WORD
        EXTRN YLength:WORD
        EXTRN BitsPix:WORD
        EXTRN GPage:WORD
        EXTRN C_O_L:WORD
        EXTRN ExCol:WORD
        EXTRN LineLen:WORD
        EXTRN Granularity:WORD
        EXTRN InitMode:BYTE
                            ;VESA Info
        EXTRN VESA_Info:BYTE
                            ;"CACHE"
        EXTRN XDATA0:BYTE
        EXTRN XDATA1:BYTE
        EXTRN XDATA2:BYTE
        EXTRN XDATA3:BYTE

G_Mul   DW ?
D1X     DW ?
D1Y     DW ?
D2X     DW ?
D2Y     DW ?
S       DW ?
M       DW ?
N       DW ?

DATA    ENDS

CODE    SEGMENT BYTE PUBLIC

        ASSUME CS:CODE,DS:DATA

PPixProc        DW  OFFSET PutPixel2_4
GPixProc        DW  OFFSET GetPixel2_4
CScrProc        DW  OFFSET ClearScreen2_4
FScrProc        DW  OFFSET FillScreen2_4


        PUBLIC  GetVESAInfo
        PUBLIC  SetMode,CloseGraph,GetMode,GetPal ;,SetPal
        PUBLIC  PutPixel,PutPixel2_4,PutPixel8,PutPixel16
        PUBLIC  GetPixel,GetPixel2_4,GetPixel8,GetPixel16
        PUBLIC  SetLineLen,GetLineLen
        PUBLIC  SetDisplayStart,GetDisplayStart
        PUBLIC  ClearScreen,ClearScreen2_4,ClearScreen8,ClearScreen16
        PUBLIC  FillScreen,FillScreen2_4,FillScreen8,FillScreen16
        PUBLIC  ScrollLeft
        PUBLIC  SetActOfs
;        PUBLIC  Line


; Called as
; GetVesaInfo;
;
GetVESAInfo:
        PUSHA
        MOV     AX, SEG VESA_Info
        MOV     ES, AX
        MOV     DI, OFFSET VESA_Info
        MOV     AX, 4F00H
        INT     10H
        POPA
        RETF

; Called as:
; SetMode(ModeNum, XLen, YLen, Bpp:word):byte;
;
SetMode:
        PUSH    ES
        PUSH    BP
        MOV     BX,SP
        MOV     ax,SS:[BX+12]   ;set XLength
        MOV     XLength,ax
        MOV     ax,SS:[BX+10]   ;set YLength
        MOV     YLength,ax
        MOV     AX,SS:[BX+8]    ;set BitsPix
        MOV     BitsPix,AX
        MOV     AX,SS:[BX+14]   ;set ModeNum
        MOV     GrMode,AX
        CMP     AX,13H
        JB      @@SM1
        MOV     BX,AX
        MOV     AX,4F02H
        INT     10H
        MOV     InitMode,01H
        CMP     AX,4FH
        JE      @@SM2
        MOV     InitMode,00H
        JMP     @@SM2
@@SM1:
        INT     10H
        MOV     InitMode,01H
@@SM2:
        POP     BP
        POP     ES
        CMP     BitsPix,1
        JE      @@SM_2_4
        CMP     BitsPix,2
        JE      @@SM_2_4
        CMP     BitsPix,4
        JE      @@SM_2_4
        CMP     BitsPix,8
        JE      @@SM_8
        CMP     BitsPix,16
        JE      @@SM_16
        CMP     BitsPix,24
        JE      @@SM_24
        CMP     BitsPix,32
        JE      @@SM_32
@@SM_2_4:
        MOV     PPixProc, OFFSET PutPixel2_4
        MOV     GPixProc, OFFSET GetPixel2_4
        MOV     CScrProc, OFFSET ClearScreen2_4
        MOV     FScrProc, OFFSET FillScreen2_4
        JMP     @@SM_END
@@SM_8:
        MOV     PPixProc, OFFSET PutPixel8
        MOV     GPixProc, OFFSET GetPixel8
        MOV     CScrProc, OFFSET ClearScreen8
        MOV     FScrProc, OFFSET FillScreen8
        JMP     @@SM_END
@@SM_16:
        MOV     PPixProc, OFFSET PutPixel16
        MOV     GPixProc, OFFSET GetPixel16
        MOV     CScrProc, OFFSET ClearScreen16
        MOV     FScrProc, OFFSET FillScreen16
        JMP     @@SM_END
@@SM_24:
;        MOV     PPixProc, OFFSET PutPixel24
;        MOV     GPixProc, OFFSET GetPixel24
;        MOV     CScrProc, OFFSET ClearScreen24
;        MOV     FScrProc, OFFSET FillScreen24
        JMP     @@SM_END
@@SM_32:
;        MOV     PPixProc, OFFSET PutPixel32
;        MOV     GPixProc, OFFSET GetPixel32
;        MOV     CScrProc, OFFSET ClearScreen32
;        MOV     FScrProc, OFFSET FillScreen32
@@SM_END:
        MOV     BX, Granularity
        MOV     CX, BX
        MOV     AX, 0
@@SM_LOOP:
        INC     AX
        CMP     BX, 64
        JE      @@SM_LEND
        ADD     BX, CX
        JMP     @@SM_LOOP
@@SM_LEND:
        MOV     G_Mul, AX
        RETF    8

; Called as:
; CloseGraph;
;
CloseGraph:
        PUSH    ES
        PUSH    BP
        MOV     AX,03H
        INT     10H
        POP     BP
        POP     ES
        RETF

; Called as:
; CloseGraph:word;
;
GetMode:
        PUSH    ES
        PUSH    BP
        MOV     AX,4F03H
        INT     10H
        POP     BP
        POP     ES
        MOV     AX,BX
        RETF

; Called as:
; GetPal(Col:word;var R,G,B:byte);
;
GetPal:
        PUSH    BP
        PUSH    ES
        MOV     BX,SP
        MOV     AH,10H
        MOV     AL,15H
        MOV     BX,SS:[BX+16]
        INT     10H
        POP     ES
        POP     BP
        MOV     XDATA1, DH ; DH-R
        MOV     XDATA2, CH ; CH-G
        MOV     XDATA3, CL ; CL-B
        RETF

; Called as:
; SetPal(I,R,G,B:byte);
;
SetPal:
        MOV     DX,3C8H
        MOV     AX,SS:[BX+10]
        OUT     DX,AL
        NOP
        INC     DX
        MOV     AX,SS:[BX+8]
        OUT     DX,AL
        NOP
        MOV     AX,SS:[BX+6]
        OUT     DX,AL
        NOP
        MOV     AX,SS:[BX+4]
        OUT     DX,AL
        RETF    8

; Called as:
; PutPixel(X,Y:word;B:word);
;
PutPixel:
        JMP     PPixProc

; Called as:
; PutPixel2_4(X,Y,B:word);
; PutPixel for 1,2 and 4 bits gr. modes
;
PutPixel2_4:
        MOV     BX,SP
        MOV     CX,SS:[BX+8]
        MOV     DX,SS:[BX+6]
        MOV     AX,SS:[BX+4]
        XOR     BX,BX
        MOV     AH,0CH
        PUSHF
        PUSH    ES
        PUSH    BP
;        PUSHA
        INT     10H
;        POPA
        POP     BP
        POP     ES
        POPF
        RETF    6

; Called as:
; PutPixel8(X,Y,B:word);
;
PutPixel8:
        PUSH    BP
        MOV     BP,SP
@@PA1:  MOV     BX,SS:[BP+10]
        CMP     BX,XLength
        JNB     @@PA9
        PUSH    DS
        MOV     AX,SS:[BP+8]
        MUL     XLength
        MOV     CX,0FFFFH
        SUB     CX,AX
        CMP     CX,BX
        JNB     @@PA22
@@PA21: INC     DX
        SUB     BX,CX
        DEC     BX
        JMP     @@PA23
@@PA22: ADD     BX,AX
@@PA23: ;DX=GPage, BX=Ofs
        MOV     AX, G_Mul
        MUL     DX
        MOV     DX, AX
        CMP     DX,GPage
        JE      @@PA6
        PUSH    BX
        PUSHF
        MOV     GPage,DX
        MOV     AX,4F05H
        XOR     BX,BX
        INT     10H
        POPF
        POP     BX
@@PA6:  MOV     AX,SS:[BP+6]
        PUSH    ES
        MOV     ES,GrSeg
        MOV     ES:[BX],AL
@@PA8:  POP     ES
        POP     DS
@@PA9:  POP     BP
        RETF    6

; Called as:
; PutPixel16(X,Y:word;B:word);
;
PutPixel16:
        PUSH    BP
        MOV     BP,SP
@@PB1:  MOV     BX,SS:[BP+10]
        CMP     BX,XLength
        JNB     @@PB9
        PUSH    DS
        MOV     AX,SS:[BP+8]
        SHL     BX,1
        SHL     AX,1
        MUL     XLength
        MOV     CX,0FFFFH
        SUB     CX,AX
        CMP     CX,BX
        JNB     @@PB22
@@PB21: INC     DX
        SUB     BX,CX
        DEC     BX
        JMP     @@PB23
@@PB22: ADD     BX,AX
@@PB23: ;DX=GPage, BX=Ofs
        MOV     AX, G_Mul
        MUL     DX
        MOV     DX, AX
        CMP     DX,GPage
        JE      @@PB6
        PUSH    BX
        PUSHF
        MOV     GPage,DX
        MOV     AX,4F05H
        XOR     BX,BX
        INT     10H
        POPF
        POP     BX
@@PB6:  MOV     AX,SS:[BP+6]
        PUSH    ES
        MOV     ES,GrSeg
        MOV     WORD PTR ES:[BX],AX
@@PB8:  POP     ES
        POP     DS
@@PB9:  POP     BP
        RETF    6

; Called as:
; GetPixel(X,Y:word):word;
;
GetPixel:
        JMP     GPixProc

GetPixel2_4:
        MOV     BX, SP
        MOV     CX, SS:[BX+6]
        MOV     DX, SS:[BX+4]
        XOR     BX, BX
        MOV     AX, 0D00H
        PUSHF
        PUSH    ES
        PUSH    BP
        INT     10H
        POP     BP
        POP     ES
        POPF
        RETF    4

; Called as:
; GetPixel8(X,Y:word):word;
;
GetPixel8:
        PUSH    BP
        MOV     BP,SP
@@GA1:  MOV     BX,SS:[BP+8]
        CMP     BX,XLength
        JNB     @@GA9
        PUSH    DS
        MOV     AX,SS:[BP+6]
        MUL     XLength
        MOV     CX,0FFFFH
        SUB     CX,AX
        CMP     CX,BX
        JNB     @@GA22
@@GA21: INC     DX
        SUB     BX,CX
        DEC     BX
        JMP     @@GA23
@@GA22: ADD     BX,AX
@@GA23: ;DX=Page, BX=Ofs
        MOV     AX, G_Mul
        MUL     DX
        MOV     DX, AX
        CMP     DX,GPage
        JE      @@GA6
        PUSH    BX
        PUSHF
        MOV     GPage,DX
        MOV     AX,4F05H
        XOR     BX,BX
        INT     10H
        POPF
        POP     BX
@@GA6:  XOR     AX,AX
        PUSH    ES
        MOV     ES,GrSeg
        MOV     AL,ES:[BX]
@@GA8:  POP     ES
        POP     DS
@@GA9:  POP     BP
        RETF    4

; Called as:
; GetPixel16(X,Y:word):word;
;
GetPixel16:
        PUSH    BP
        MOV     BP,SP
@@GB1:  MOV     BX,SS:[BP+8]
        CMP     BX,XLength
        JNB     @@GB9
        PUSH    DS
        MOV     AX,SS:[BP+6]
        SHL     BX,1
        SHL     AX,1
        MUL     XLength
        MOV     CX,0FFFFH
        SUB     CX,AX
        CMP     CX,BX
        JNB     @@GB22
@@GB21: INC     DX
        SUB     BX,CX
        DEC     BX
        JMP     @@GB23
@@GB22: ADD     BX,AX
@@GB23: ;DX=Page, BX=Ofs
        MOV     AX, G_Mul
        MUL     DX
        MOV     DX, AX
        CMP     DX,GPage
        JE      @@GB6
        PUSH    BX
        PUSHF
        MOV     GPage,DX
        MOV     AX,4F05H
        XOR     BX,BX
        INT     10H
        POPF
        POP     BX
@@GB6:  XOR     AX,AX
        PUSH    ES
        MOV     ES,GrSeg
        MOV     AX,WORD PTR ES:[BX]
        POP     ES
        POP     DS
@@GB9:  POP     BP
        RETF    4

; Called as:
; SetActOfs(Ofs:word);
;
SetActOfs:
        PUSH    BP
        MOV     BP,SP
        MOV     DX,SS:[BP+6]
        POP     BP
        MOV     AX,G_Mul
        MUL     DX
        MOV     DX,AX
        PUSHF
        MOV     GPage,DX
        MOV     AX,4F05H
        XOR     BX,BX
        INT     10H
        POPF
        RETF    2

; Called as:
; SetLineLen(Len:word);
;
SetLineLen:
        PUSH    ES
        PUSH    BP
        MOV     BX,SP
        MOV     AX,4F06H
        MOV     CX,SS:[BX+8]
        MOV     XLength,CX
        MOV     BX,0
        INT     10H          ; dx:=maximum number of scan lines
        POP     BP
        POP     ES
        RETF    2

; Called as:
; GetLineLen:Word;
;
GetLineLen:
        PUSH    ES
        PUSH    BP
        MOV     AX,4F06H
        MOV     BL,1
        INT     10H          ; dx:=maximum number of scan lines
        MOV     AX,CX
        MOV     XLength,AX
        POP     BP
        POP     ES
        RETF

; Called as:
; SetDisplayStart(pixel,line:word);
;
SetDisplayStart:
        PUSH    BP
        PUSH    ES
        MOV     BX,SP
        MOV     AX,4F07H
        MOV     CX,SS:[BX+10]
        MOV     DX,SS:[BX+8]
        MOV     BX,0
        INT     10H
        POP     ES
        POP     BP
        RETF    4

; Called as:
; GetDisplayStart(var pixel,line:word);
;
GetDisplayStart:
        PUSH    BP
        PUSH    ES
        MOV     AX,4F07H
        MOV     BX,1
        INT     10H
;CX-pixel
;DX-line
        POP     ES
        POP     BP
        RETF

; Called as:
; ClearScreen;
;
ClearScreen:
        JMP     CScrProc

ClearScreen2_4:
        PUSHF
        PUSH    ES
        PUSH    BP
        MOV     AX, YLength
@C240:
        MOV     CX, XLength
@C241:
        ;CX-X
        ;DX-Y
        ;AX-Color
        PUSH    AX
        PUSH    CX
        MOV     DX, AX
        XOR     BX,BX
        MOV     AX,0C00H
        INT     10H
        POP     CX
        POP     AX
        ;Dalsi bod
        LOOPNZ  @C241
        DEC     AX
        JNZ     @C240
@C243:
        POP     BP
        POP     ES
        POPF
        RETF

; Called as:
; ClearScreen8;
;
ClearScreen8:
        XOR     DX,DX                ;Nuluj DX
        PUSHF                        ;Uloz priznaky
        MOV     GPage,0              ;Nactav aktivni stranku na nultou
        MOV     AX,4F05H             ;Graf. sluzba VESA BIOSu SetOffset
        XOR     BX,BX                ;Nuluj BX
        INT     10H                  ;Preruseni 10H - sluzby graf. adapteru
        POPF                         ;Obnov priznaky
        MOV     AX,XLength           ;Vypocet velikosti obrazovky
        MUL     YLength              ;DX - pocet stranek, AX - bytu na posl. strance
        PUSH    AX
        XOR     BX,BX                ;BX = nula = aktivni stranka
        XCHG    DX,BX                ;Zamena BX a DX (aktivni str. a celkem stranek)
@@C81:  XOR     AX,AX                ;AX = nula = poradi bytu na strance
        CMP     DX,BX                ;Porovnej aktivni a celkovy pocet
        JB      @@C812               ;Je-li aktivni mensi, pak skok na @@C812
        POP     CX                   ;Jinak je pocet bytu na strance = poctu
        JMP     @@C813               ;bytu na posledni strance (ulozene AX)
@@C812: MOV     CX,0FFFFH            ;Pocet bytu na str. = 64KB-1B
@@C813:
        CMP     DX,GPage             ;Porovnej DX se sktecnou aktivni strankou
        JE      @@C82                ;Jsou-li shodne, pak skoc na @@C82
        PUSH    AX                   ;Ulozeni registru
        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSHF                        ;Ulozeni priznaku
        MOV     GPage,DX             ;Nastav aktivni stranku
        MOV     AX,G_Mul
        MUL     DX
        XCHG    AX,DX
        MOV     AX,4F05H
        XOR     BX,BX                ;Nulovani BX
        INT     10H
        POPF                         ;Obnova priznaku
        POP     DX
        POP     CX                   ;Obnova registru
        POP     BX
        POP     AX
@@C82:
        PUSH    ES                   ;Ulozeni ES
        PUSH    BX                   ;Ulozeni BX = celkovy pocet stran
        XCHG    BX,AX                ;Zamena BX za AX
        XOR     AL,AL                ;AL = 0 - cislo barvy
        MOV     ES,GrSeg             ;Do ES segment graficke pameti
        MOV     ES:[BX],AL           ;Zapsani bodu na obrazovku
        XCHG    BX,AX                ;Zamena BX za AX => puvodni hodnota AX je zpet
        POP     BX                   ;BX je zpet
        POP     ES                   ;Obnova ES
        CMP     AX,CX                ;Porovnej akt. byte s celk. poctem
        JNB     @@C83                ;Je-li rovny nebo vetsi, skok na @@C83,
        INC     AX                   ;AX = AX+1
        JMP     @@C82                ;cyklus vykresleni cele stranky
@@C83:  ADD     DX, G_Mul            ;DX = DX+1 - dalsi stranka
        CMP     DX,BX                ;Porovnani celkoveho poctu str. a akt. str.
        JBE     @@C81                ;Je-li mensi nebo rovny, pak jdi na @@C81
@@C84:  RETF                         ;Konec procedury

; Called as:
; ClearScreen16;
;
ClearScreen16:
        XOR     DX,DX                ;Nuluj DX
        PUSHF                        ;Uloz priznaky
        MOV     GPage,0              ;Nactav aktivni stranku na nultou
        MOV     AX,4F05H
        XOR     BX,BX                ;Nuluj BX
        INT     10H                  ;Preruseni 10H - sluzby graf. adapteru
        POPF                         ;Obnov priznaky
        MOV     AX,XLength           ;Vypocet velikosti obrazovky
        MUL     YLength              ;DX - pocet stranek/2, AX - bytu na posl. strance/2
        SHL     DX,1                 ;DX - pocet stranek, AX - bytu na posl. strance
        SHL     AX,1
        PUSH    AX
        XOR     BX,BX                ;BX = nula = aktivni stranka
        XCHG    DX,BX                ;Zamena BX a DX (aktivni str. a celkem stranek)
@@CF1:  XOR     AX,AX                ;AX = nula = poradi bytu na strance
        CMP     DX,BX                ;Porovnej aktivni a celkovy pocet
        JB      @@CF12               ;Je-li aktivni mensi, pak skok na @@CF12
        POP     CX                   ;Jinak je pocet bytu na strance = poctu
        JMP     @@CF13               ;bytu na posledni strance (ulozene AX)
@@CF12: MOV     CX,0FFFFH            ;Pocet bytu na str. = 64KB
@@CF13:
        CMP     DX,GPage             ;Porovnej DX se sktecnou aktivni strankou
        JE      @@CF2                ;Jsou-li shodne, pak skoc na @@CF2
        PUSH    AX                   ;Ulozeni registru
        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSHF                        ;Ulozeni priznaku
        MOV     GPage,DX             ;Nastav aktivni stranku
        MOV     AX,G_Mul
        MUL     DX
        XCHG    AX,DX
        MOV     AX,4F05H
        XOR     BX,BX                ;Nulovani BX
        INT     10H
        POPF                         ;Obnova priznaku
        POP     DX
        POP     CX                   ;Obnova registru
        POP     BX
        POP     AX
@@CF2:
        PUSH    ES                   ;Ulozeni ES
        PUSH    BX                   ;Ulozeni BX = celkovy pocet stran
        XCHG    BX,AX                ;Zamena BX za AX
        XOR     AL,AL                ;AX = 0 - cislo barvy
        MOV     ES,GrSeg             ;Do ES segment graficke pameti
        MOV     ES:[BX],AL           ;Zapsani bodu na obrazovku
        XCHG    BX,AX                ;Zamena BX za AX => puvodni hodnota AX je zpet
        POP     BX                   ;BX je zpet
        POP     ES                   ;Obnova ES
        CMP     AX,CX                ;Porovnej akt. byte s celk. poctem
        JNB     @@CF3                ;Je-li rovny nebo vetsi, skok na @@CF3,
        INC     AX                   ;AX = AX+1
        JMP     @@CF2                ;cyklus vykresleni cele stranky
@@CF3:  ADD     DX, G_Mul            ;DX = DX+1 - dalsi stranka
        CMP     DX,BX                ;Porovnani celkoveho poctu str. a akt. str.
        JBE     @@CF1                ;Je-li mensi nebo rovny, pak jdi na @@CF1
@@CF4:  RETF                         ;Konec procedury

; Called as:
; FillScreen;
;
FillScreen:
        JMP     FScrProc

FillScreen2_4:
        PUSHF
        PUSH    ES
        PUSH    BP
        MOV     AX, YLength
@F240:
        MOV     CX, XLength
@F241:
        ;CX-X
        ;DX-Y
        ;AX-Color
        PUSH    AX
        PUSH    CX
        MOV     DX, AX
        MOV     AX, C_O_L
        XOR     BX,BX
        MOV     AH,0CH
        INT     10H
        POP     CX
        POP     AX
        ;Dalsi bod
        LOOPNZ  @F241
        DEC     AX
        JNZ     @F240
@F243:
        POP     BP
        POP     ES
        POPF
        RETF

; Called as:
; FillScreen8;
;
FillScreen8:
        XOR     DX,DX                ;Nuluj DX
        PUSHF                        ;Uloz priznaky
        MOV     GPage,0              ;Nactav aktivni stranku na nultou
        MOV     AX,4F05H
        XOR     BX,BX                ;Nuluj BX
        INT     10H                  ;Preruseni 10H - sluzby graf. adapteru
        POPF                         ;Obnov priznaky
        MOV     AX,XLength           ;Vypocet velikosti obrazovky
        MUL     YLength              ;DX - pocet stranek po 64k, AX - bytu na posl. strance
        PUSH    AX
        XOR     BX,BX                ;BX = nula = aktivni stranka
        XCHG    DX,BX                ;Zamena BX a DX (aktivni str. a celkem stranek)
@@F81:  XOR     AX,AX                ;AX = nula = poradi bytu na strance
        CMP     DX,BX                ;Porovnej aktivni a celkovy pocet
        JB      @@F812               ;Je-li aktivni mensi, pak skok na @@F812
        POP     CX                   ;Jinak je pocet bytu na strance = poctu
        JMP     @@F813               ;bytu na posledni strance (ulozene AX)
@@F812: MOV     CX,0FFFFH            ;Pocet bytu na str. = 64KB
@@F813:
        CMP     DX,GPage             ;Porovnej DX se sktecnou aktivni strankou
        JE      @@F82                ;Jsou-li shodne, pak skoc na @@F82
        PUSH    AX                   ;Ulozeni registru
        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSHF                        ;Ulozeni priznaku
        MOV     GPage,DX             ;Nastav aktivni stranku
        MOV     AX,G_Mul
        MUL     DX
        XCHG    AX,DX
        MOV     AX,4F05H
        XOR     BX,BX                ;Nulovani BX
        INT     10H
        POPF                         ;Obnova priznaku
        POP     DX
        POP     CX                   ;Obnova registru
        POP     BX
        POP     AX
@@F82:
        PUSH    ES                   ;Ulozeni ES
        PUSH    BX                   ;Ulozeni BX = celkovy pocet stran
        XCHG    BX,AX                ;Zamena BX za AX
        mov     AX,C_O_L             ;AL = cislo barvy
        MOV     ES,GrSeg             ;Do ES segment graficke pameti
        MOV     ES:[BX],AL           ;Zapsani bodu na obrazovku
        XCHG    BX,AX                ;Zamena BX za AX => puvodni hodnota AX je zpet
        POP     BX                   ;BX je zpet
        POP     ES                   ;Obnova ES
        CMP     AX,CX                ;Porovnej akt. byte s celk. poctem
        JNB     @@F83                ;Je-li rovny nebo vetsi, skok na @@F83,
        INC     AX                   ;AX = AX+1
        JMP     @@F82                ;cyklus vykresleni cele stranky
@@F83:  ADD     DX, G_Mul            ;DX = DX+1 - dalsi stranka
        CMP     DX,BX                ;Porovnani celkoveho poctu str. a akt. str.
        JBE     @@F81                ;Je-li mensi nebo rovny, pak jdi na @@F81
@@F84:  RETF                         ;Konec procedury

; Called as:
; FillScreen16;
;
FillScreen16:
        XOR     DX,DX                ;Nuluj DX
        PUSHF                        ;Uloz priznaky
        MOV     GPage,0              ;Nactav aktivni stranku na nultou
        MOV     AX,4F05H
        XOR     BX,BX                ;Nuluj BX
        INT     10H                  ;Preruseni 10H - sluzby graf. adapteru
        POPF                         ;Obnov priznaky
        MOV     AX,XLength           ;Vypocet velikosti obrazovky
        MUL     YLength              ;DX - pocet stranek/2, AX - bytu na posl. strance/2
        SHL     DX,1                 ;DX - pocet stranek, AX - bytu na posl. strance
        SHL     AX,1
        PUSH    AX
        XOR     BX,BX                ;BX = nula = aktivni stranka
        XCHG    DX,BX                ;Zamena BX a DX (aktivni str. a celkem stranek)
@@FF1:  XOR     AX,AX                ;AX = nula = poradi bytu na strance
        CMP     DX,BX                ;Porovnej aktivni a celkovy pocet
        JB      @@FF12               ;Je-li aktivni mensi, pak skok na @@FF12
        POP     CX                   ;Jinak je pocet bytu na strance = poctu
        JMP     @@FF13               ;bytu na posledni strance (ulozene AX)
@@FF12: MOV     CX,0FFFFH            ;Pocet bytu na str. = 64KB
@@FF13:
        CMP     DX,GPage             ;Porovnej DX se sktecnou aktivni strankou
        JE      @@FF2                ;Jsou-li shodne, pak skoc na @@FF2
        PUSH    AX                   ;Ulozeni registru
        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSHF                        ;Ulozeni priznaku
        MOV     GPage,DX             ;Nastav aktivni stranku
        MOV     AX,G_Mul
        MUL     DX
        XCHG    AX,DX
        MOV     AX,4F05H
        XOR     BX,BX                ;Nulovani BX
        INT     10H
        POPF                         ;Obnova priznaku
        POP     DX
        POP     CX                   ;Obnova registru
        POP     BX
        POP     AX
@@FF2:
        PUSH    ES                   ;Ulozeni ES
        PUSH    BX                   ;Ulozeni BX = celkovy pocet stran
        XCHG    BX,AX                ;Zamena BX za AX
        AND     AX,01H               ;Je suda adresa ?
        CMP     AX,00H               ;
        MOV     AX,C_O_L             ;AX = cislo barvy
        JNE     @@FF22               ;Ne, v AL je nizsi byte, skok na @@FF22
        XCHG    AL,AH                ;Ano, do AL vyssi byte barvy
@@FF22: MOV     ES,GrSeg             ;Do ES segment graficke pameti
        MOV     ES:[BX],AL           ;Zapsani bodu na obrazovku
        XCHG    BX,AX                ;Zamena BX za AX => puvodni hodnota AX je zpet
        POP     BX                   ;BX je zpet
        POP     ES                   ;Obnova ES
        CMP     AX,CX                ;Porovnej akt. byte s celk. poctem
        JNB     @@FF3                ;Je-li rovny nebo vetsi, skok na @@FF3,
        INC     AX                   ;AX = AX+1
        JMP     @@FF2                ;cyklus vykresleni cele stranky
@@FF3:  ADD     DX, G_Mul            ;DX = DX+1 - dalsi stranka
        CMP     DX,BX                ;Porovnani celkoveho poctu str. a akt. str.
        JBE     @@FF1                ;Je-li mensi nebo rovny, pak jdi na @@FF1
@@FF4:  RETF                         ;Konec procedury

; Called as:
; ScrollLeft(Cnt:word);
;
ScrollLeft:
        PUSH    BP
        MOV     BP,SP
        MOV     AX,0             ; Y
@@SL1:  MOV     CX,0             ; Dest X
        MOV     BX,SS:[BP+4]     ; Src X
@@SL2:  PUSH    AX
        PUSH    BX
        PUSH    CX
;
        PUSH    DS
        MUL     XLength
        MOV     CX,0FFFFH
        SUB     CX,AX
        CMP     CX,BX
        JNB     @@S22
        INC     DX
        SUB     BX,CX
        DEC     BX
        JMP     @@S23
@@S22:  ADD     BX,AX
@@S23:  ;DX=Page, BX=Ofs
        CMP     DX,GPage
        JE      @@S6
        PUSH    BX
        PUSHF
        MOV     GPage,DX
        MOV     AX,4F05H
        XOR     BX,BX
        INT     10H
        POPF
        POP     BX
@@S6:   XOR     AX,AX
        PUSH    ES
        MOV     ES,GrSeg
@@S708: MOV     AL,ES:[BX]
@@S8:   POP     ES
        POP     DS
;
        MOV     DX,AX            ; DX = Color
        POP     CX
        POP     BX
        POP     AX
        PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    CX               ; Dest X
        PUSH    AX               ; Y
        PUSH    DX               ; Color
        CALL    FAR PTR PutPixel
        POP     CX
        POP     BX
        POP     AX
        INC     BX
        INC     CX
        CMP     BX,XLength
        JB      @@SL2
        INC     AX
        CMP     AX,YLength
        JB      @@SL1
        POP     BP
        RETF    2                    ;Konec procedury

; Called as:
; Line(X1, Y1, X2, Y2:integer);
;
Line:
        PUSH    BP
        MOV     BP, SP
        MOV     AX, SS:[BP+10]
        MOV     BX, SS:[BP+8]
        MOV     CX, SS:[BP+6]
        MOV     DX, SS:[BP+4]
        SUB     CX, AX
        SUB     DX, BX
        CMP     CX, 0
        JL      @1L
        JG      @1G
        MOV     D1X, 0
        JMP     @1E
@1L:    MOV     D1X, -1
        JMP     @1E
@1G:    MOV     D1X, 1
@1E:    CMP     DX, 0
        JL      @2L
        JG      @2G
        MOV     D1Y, 0
        JMP     @2E
@2L:    MOV     D1Y, -1
        JMP     @2E
@2G:    MOV     D1Y, 1
@2E:    PUSH    AX
        MOV     AX, D1X
        MOV     D2X, AX
        POP     AX
        MOV     D2Y, 0
        AND     CX, 32767
        AND     DX, 32767
        CMP     CX, DX
        JG      @3E
        MOV     D2X, 0
        PUSH    AX
        MOV     AX, D1Y
        MOV     D2Y, AX
        POP     AX
        XCHG    CX, DX
@3E:    MOV     S, CX
        SHR     S, 1
        MOV     M, CX
        MOV     N, DX
        INC     CX
@LOOP:  PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSH    AX
        PUSH    BX
        MOV     AX, C_O_L
        PUSH    AX
        CALL    PPixProc
        POP     CX
        POP     CX
        POP     BX
        POP     AX
        ADD     S, DX
        PUSH    DX
        MOV     DX, M
        CMP     S, DX
        JL      @4E
        SUB     S, DX
        ADD     AX, D1X
        ADD     BX, D1Y
        JMP     @4E2
@4E:    ADD     AX, D2X
        ADD     BX, D2Y
@4E2:   POP     DX
        LOOP    @LOOP

        RETF    8



CODE    ENDS

        END
