; LINES 0.1, switch to 80x25, 80x43, or 80x50 text mode in DOS.
; Copyright (C) 2018, Seth Simon ([email protected])
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program.  If not, see <https://www.gnu.org/licenses/>.
;
   org     0x100
   cpu     8086
start:
   ; Command tail is a Pascal-style string at 0x80, with an 0xd
   ; appended (not included in the length)
   cld
   mov     di, 0x81
   mov     ch, 0
   mov     cl, byte [di - 1]
   mov     al, ' '
   repe    scasb
   mov     dx, usage_str
   loop    print_str
   mov     ax, word [di - 1]

   cmp     ax, 0x3532      ; 25?
   je      .l25
   inc     cx
   inc     cx              ; CX = 25 lines ? 0 : 2
   cmp     ax, 0x3334      ; 43?
   je      .l43
   cmp     ax, 0x3035      ; 50?
   jne     print_str

   ; 80x25: 400 scan lines, each char is 16 pixels tall
   ; 80x50: 400 scan lines, each char is 8 pixels tall
   ; 80x43: 350 scan lines, each char is 8 pixels tall
l25:
   mov     al, 2
   db      0x3d            ; CMP AX,IMMED16
l43:
   mov     al, 1           ; AL = 0/1/2 => 200/350/400 scan lines
   mov     ah, 0x12
   mov     bl, 0x30
   int     0x10        ; Select vertical resolution. Takes place
                       ; on the next mode set
   cmp     al, 0x12
   mov     dx, need_vga_str
   jne     print_str
   mov     ax, 0x0500
   int     0x10        ; Select page 0 (req'd for INT 10/AH=11)
   mov     ax, 3       ; AH=0, AL=mode=3
   int     0x10        ; Mode set

   mov     ax, 0x1114
   sub     al, cl      ; AX = 25 lines ? 1114 (8x16) : 1112 (8x8)
   mov     bl, 0       ; Block 0
   int     0x10        ; Select font. This function is designed to
   ret                 ; be executed immediately after a mode set.

print_str:
   mov     ah, 9
   int     0x21
   ret
need_vga_str:
   db "Error: This program requires a VGA adapter$"
usage_str:
   db "LINES 0.1, Copyright (C) 2018, Seth Simon ([email protected]).",13,10
   db "This program comes with ABSOLUTELY NO WARRANTY. This is free",13,10
   db "software, and you are welcome to redistribute it under certain",13,10
   db "conditions; see the GNU GPLv3 for details.",13,10
   db 13,10
   db "Usage: lines <command>",13,10
   db "Commands:",13,10
   db "      25      Switch to 80x25",13,10
   db "      43      Switch to 80x43",13,10
   db "      50      Switch to 80x50$"