                .SEQ
CODE            Segment WORD PUBLIC 'CODE'
CODE            EndS

include vga.inc

CODE            Segment
                Assume  CS:Code, DS:ABS40

                Org     80h
Params          db      ?

                Org     100h
Start:          Mov     Ax, 40h
                Mov     Ds, Ax

                Mov     Bl, 10h
                Mov     Ah, 12h;        Test for VGA/EGA
                Int     10h
                Cmp     Bl, 10h
                Je      Bad;            Neither VGA/EGA

                Mov     Si, Offset Cs:Params
                Lods    Cs:Params
                Xor     Ah, Ah
                Mov     Bx, Ax
                Mov     Byte Ptr Cs:[Si+Bx], 0

P_Loop:         Lods    Cs:Params
                Cmp     Al, ' '
                Je      P_Loop
                Cmp     Al, 0
                Je      NoArgs
                Xor     Bx, Bx
                Jmp     TryNumber

NoArgs:         Mov     Al, video_rows
                Inc     Al
                Cmp     Al, 25
                Jne     Return_Rows
                Xor     Al, Al

Return_Rows:    Mov     Ah, 4Ch
                Int     21h

Bad:            Mov     Al, 0FFh
                Jmp     Return_Rows

No_Change:      Xor     Al, Al
                Jmp     Return_Rows

TryNumber:      Sub     Al, '0'
                Jb      Bad
                Cmp     Al, 9
                Ja      Bad
                Mov     Cx, Bx
                Shl     Cx, 1
                Shl     Cx, 1
                Add     Bx, Cx
                Shl     Bx, 1
                Add     Bl, Al

MoreDigits:     Lods    Cs:Params
                Cmp     Al, 0
                Je      Check_Which
                Cmp     Al, ' '
                Je      Check_Which
                Cmp     Al, ','
                Je      Check_Which
                Cmp     Al, ';'
                Je      Check_Which
                Jmp     TryNumber

Check_Which:    Cmp     Bx, 25
                Jbe     StdMode
                Jmp     HiDensityMode

SaveRows        db      ?
CurPosition     dw      ?
CurChar         dw      ?
ScrollCount     db      ?

StdMode:        Mov     Al, video_rows
                Mov     SaveRows, Al

                Call    Near Ptr GetCurrentChar
                Mov     CurChar, Ax
                Mov     CurPosition, Dx
                
                Inc     Dh
                Cmp     Dh, video_rows
                Ja      NoClear

                Mov     Cx, Dx
                Mov     Dh, video_rows
                Mov     Dl, Byte Ptr crt_cols
                Dec     Dl
                Mov     Bx, CurChar
                Mov     Ax, 0600h
                Int     10h
                
NoClear:        Xor     Cx, Cx
                Mov     Dx, CurPosition
                Mov     Dl, Byte Ptr crt_cols
                Dec     Dl
                Mov     Bx, CurChar
                Mov     Ah, 06h
                Mov     Al, Dh
                Sub     Al, 24
                Jle     NoScroll
                Mov     ScrollCount, Al
                Int     10h
                Jmp     ChangeTo_Std

NoScroll:       Xor     Al, Al
                Mov     ScrollCount, Al

ChangeTo_Std:   Mov     Ax, 1A00h; Check Vga/Ega
                Int     10h
                Cmp     Al, 1Ah
                Jne     Ega_8x14

                Mov     Ax, 1114h; Load 9x16 charset, program controller
                Mov     Bl, 0
                Int     10h

                Mov     Ax, 1200h;  Enable cursor emulation
                Mov     Bl, 34h
                Int     10h
                Jmp     SetCursor_Std

Ega_8x14:       Mov     Ax, 1111h; Load 8x14 charset, program controller
                Mov     Bl, 0
                Int     10h
                And     info, 0FEh

SetCursor_Std:  Mov     Ah, 1;  Set cursor type
                Mov     Cx, 0707h
                Int     10h

                Mov     Ah, 2;  Move cursor
                Mov     Bh, active_page
                Mov     Dx, CurPosition
                Sub     Dh, ScrollCount
                Int     10h

                Jmp     Finish

HiDensityMode:  Mov     Al, video_rows
                Mov     SaveRows, Al
                Call    Near Ptr GetCurrentChar
                Mov     CurChar, Ax
                Mov     CurPosition, Dx
                Mov     Ax, 1112h; Load 8x8 charset; program controller
                Mov     Bl, 0
                Int     10h

                Mov     Ax, 1200h; Select alternate print screen routine
                Mov     Bl, 20h
                Int     10h
                
                Mov     Ax, 1A00h; Check Vga/Ega
                Int     10h
                Cmp     Al, 01Ah
                Jne     Ega_8x8

                Mov     Ax, 1201h;  Disable cursor emulation
                Mov     Bl, 34h
                Int     10h
                Jmp     SetCursor_8x8

Ega_8x8:        Or      info, 1   

SetCursor_8x8:  Mov     Ah, 1;  Set cursor type
                Mov     Cx, 0707h
                Int     10h

                Mov     Ah, 2;  Position cursor
                Mov     Bh, active_page
                Mov     Dx, CurPosition
                Int     10h

                Mov     Cx, CurPosition
                Inc     Ch
                Cmp     Ch, video_rows
                Ja      NoClearExcess

                Xor     Cl, Cl
                Mov     Dh, video_rows
                Mov     Dl, Byte Ptr crt_cols
                Dec     Dl
                Mov     Bx, CurChar
                Mov     Ax, 0600h
                Int     10h

NoClearExcess:  Jmp     Finish

Finish:         Mov     Al, SaveRows
                Cmp     Al, video_rows
                Jne     Changed
                Jmp     No_Change

Changed:        Mov     Al, 1
                Jmp     Return_Rows


;      Returns: Ax - current char & attribute
;               Dx - current position


GetCurrentChar  Proc    Near

                Mov     Ax, crt_start
                Shr     Ax, 1
                Shr     Ax, 1
                Shr     Ax, 1
                Shr     Ax, 1
                Mov     Ah, 0B8h
                Mov     Es, Ax

                Xor     Bx, Bx
                Mov     Bl, active_page
                Shl     Bx, 1
                Mov     Dx, cursor_posn[Bx]

                Xor     Bx, Bx
                Mov     Bl, Dl
                Shl     Bx, 1
                Mov     Al, Byte Ptr crt_cols
                Mul     Dh
                Add     Bx, Ax
                Mov     Ax, Es:[Bx]

                Ret

GetCurrentChar  EndP

CODE            Ends                

                End     Start
