        ORG     100H

JMP     START

CURRENTPAGE     DB      0
ACTIVEPAGE      DB      0
VISUALPAGE      DB      0

X1              DW      0
Y1              DW      0
X2              DW      0
Y2              DW      0
COLOR           DB      0

START:
        MOV     AL,0DH
        CALL    SETMODE

        CALL    CLEARDEVICE

        MOV     [X1],160-32
        MOV     [Y1],100-32
        MOV     [X2],160+32
        MOV     [Y2],100+32
        MOV     [COLOR],07H
        CALL    LINE

        MOV     [X1],160+32
        MOV     [Y1],100-32
        MOV     [X2],160-32
        MOV     [Y2],100+32
        MOV     [COLOR],07H
        CALL    LINE

START100:
        CALL    KBHIT
        JZ      START100

        MOV     AL,03H
        CALL    SETMODE

        RET



DELAY:
        ; CX:DX <- MICRO SECONDS
        MOV     AH,86H
        INT     15H
        RET



SETMODE:
        ; AL <- MODE
        MOV     AH,00H
        INT     10H
        RET



CLEARDEVICE:
        ; AL <- LINES
        ; BH <- ATTRIB
        ; CX <- FROM ROW COL
        ; DX <- TO ROW COL
        MOV     AH,06H
        MOV     AL,00H
        MOV     BH,00H
        MOV     CX,0000H
        MOV     DX,1950H
        INT     10H
        RET



PUTPIXEL:
        ; AL <- COLOR
        ; BH <- PAGE
        ; CX <- COL
        ; DX <- ROW
        MOV     AH,0CH
        INT     10H
        RET



SETVISUALPAGE:
        ; AL <- PAGE
        MOV     AH,05H
        INT     10H
        RET



FLIP:
        MOV     AL,[CURRENTPAGE]
        MOV     [ACTIVEPAGE],AL

        MOV     AL,1
        SUB     AL,[CURRENTPAGE]
        MOV     [CURRENTPAGE],AL

        MOV     [VISUALPAGE],AL

        CALL    SETVISUALPAGE

        RET



KBHIT:
        ; ZF -> SET IF NO KEYSTROKE AVAILABLE
        ; ZF -> CLEAR IF KEYSTROKE AVAILABLE
        MOV     AH,01H
        INT     16H
        RET



LINE:

.CX     DW      0
.CY     DW      0
.XI     DW      0
.YI     DW      0
.DX     DW      0
.DY     DW      0
.TDX    DW      0
.TDY    DW      0
.TDXAE  DW      0
.TDYAE  DW      0

        MOV     [LINE.CX],0
        MOV     [LINE.CY],0
        MOV     [LINE.XI],0
        MOV     [LINE.YI],0
        MOV     [LINE.DX],0
        MOV     [LINE.DY],0
        MOV     [LINE.TDX],0
        MOV     [LINE.TDY],0
        MOV     [LINE.TDXAE],0
        MOV     [LINE.TDYAE],0
        
        MOV     AX,[X2]
        SUB     AX,[X1]
        MOV     [LINE.DX],AX

        MOV     AX,[Y2]
        SUB     AX,[Y1]
        MOV     [LINE.DY],AX

        MOV     AX,[LINE.DX]
        ADD     AX,[LINE.DX]
        MOV     [LINE.TDX],AX

        MOV     AX,[LINE.DY]
        ADD     AX,[LINE.DY]
        MOV     [LINE.TDY],AX

        MOV     AX,[X1]
        MOV     [LINE.CX],AX

        MOV     AX,[Y1]
        MOV     [LINE.CY],AX

        MOV     [LINE.XI],1
        MOV     [LINE.YI],1

        MOV     AX,[LINE.DX]
        CMP     AX,0
        JGE     LINE100
        MOV     [LINE.XI],-1
        NEG     [LINE.DX]
        NEG     [LINE.TDX]

LINE100:
        MOV     AX,[LINE.DY]
        CMP     AX,0
        JGE     LINE200
        MOV     [LINE.YI],-1
        NEG     [LINE.DY]
        NEG     [LINE.TDY]

LINE200:
        MOV     AL,[COLOR]
        MOV     BH,[ACTIVEPAGE]
        MOV     CX,[X1]
        MOV     DX,[Y1]
        CALL    PUTPIXEL

        MOV     AX,[LINE.DX]
        CMP     AX,0
        JNE     LINE300
        MOV     AX,[LINE.DY]
        CMP     AX,0
        JNE     LINE300
        JMP     LINE1000        
LINE300:
        MOV     AX,[LINE.DY]
        CMP     AX,[LINE.DX]
        JG      LINE400
        MOV     [LINE.TDXAE],0
LINE310:
        MOV     AX,[LINE.CX]
        ADD     AX,[LINE.XI]
        MOV     [LINE.CX],AX

        MOV     AX,[LINE.TDXAE]
        ADD     AX,[LINE.TDY]
        MOV     [LINE.TDXAE],AX

        CMP     AX,[LINE.DX]
        JLE     LINE320

        MOV     AX,[LINE.CY]
        ADD     AX,[LINE.YI]
        MOV     [LINE.CY],AX

        MOV     AX,[LINE.TDXAE]
        SUB     AX,[LINE.TDX]
        MOV     [LINE.TDXAE],AX
LINE320:
        MOV     AL,[COLOR]
        MOV     BH,[ACTIVEPAGE]
        MOV     CX,[LINE.CX]
        MOV     DX,[LINE.CY]
        CALL    PUTPIXEL

        MOV     AX,[LINE.CX]
        CMP     AX,[X2]
        JNE     LINE310
        JMP     LINE1000
LINE400:
        MOV     [LINE.TDYAE],0
LINE410:
        MOV     AX,[LINE.CY]
        ADD     AX,[LINE.YI]
        MOV     [LINE.CY],AX

        MOV     AX,[LINE.TDYAE]
        ADD     AX,[LINE.TDX]
        MOV     [LINE.TDYAE],AX

        CMP     AX,[LINE.DY]
        JLE     LINE420

        MOV     AX,[LINE.CX]
        ADD     AX,[LINE.XI]
        MOV     [LINE.CX],AX

        MOV     AX,[LINE.TDYAE]
        SUB     AX,[LINE.TDY]
        MOV     [LINE.TDYAE],AX
LINE420:
        MOV     AL,[COLOR]
        MOV     BH,[ACTIVEPAGE]
        MOV     CX,[LINE.CX]
        MOV     DX,[LINE.CY]
        CALL    PUTPIXEL

        MOV     AX,[LINE.CY]
        CMP     AX,[Y2]
        JNE     LINE410

LINE1000:
        RET
        
