; Probably universal 80x30 text mode for DOS
; v2 (C) 2024-2025 Pegasus Epsilon <pegasus@pimpninjas.org>
; Distribute Unmodified - https://pegasus.pimpninjas.org/license
;
; v1: first working version
; v2: saved 2 bytes
;
; this command should do you:
;
; masm> ml 80x30.asm
.model tiny
.286
.code
.startup
; 80x30 is based on mode 3 (80x25 text mode)
mov al, 3
int 10h
push ds ; save data segment for later
; mess with BIOS data area to reconfigure video mode
; DOS' screen printing won't work right without this
mov dx, 40h
push dx
pop ds
; set current video regen buffer in bytes. By
; default VGA mode 3 sets this to 1000h, wasting 96
; bytes per page, for page alignment purposes. we
; have a choice. Either we waste over 3kB per page
; (exactly 3,392 bytes) and maintain alignment, or we
; throw alignment out and gain two extra pages. I
; chose the former. Four pages ought to be enough, and
; we risk less weird VGA slowdowns on obscure adapters.
; If your VGA is fast, and you want two more pages,
; feel free to change this to 1556h. You gain two
; pages and two spare bytes at the end of video memory,
; at the cost of possibly being slower on some adapters.
mov word ptr ds:[4Ch], 2000h
; set number of lines on screen, minus one
; 18h (24) by default, we want 30, so 30 - 1 = 29 or 1Dh
mov byte ptr ds:[84h], 1Dh
mov dx, ds:[63h] ; fetch CRTC register
pop ds ; restore saved data segment
; program CRTC for modified video mode
mov cx, 8
mov si, offset regdata
rep outsw
; miscellaneous output register
mov dx, 03CCh ; read current value
in al, dx
or al, 40h ; set vsync polarity (bit 6) negative
; hsync (bit 7) doesn't seem to matter
; i/o address select (bit 0) seems to always be
; clear in mode 3, or we'd clear it ourselves
mov dx, 03C2h ; write modified value
out dx, al
; empty stack, jmp to PSP's int 20h at address 0 and exit
ret
regdata:
; CRTC = Cathode Ray Tube Controller
; info: http://www.osdever.net/FreeVGA/vga/crtcreg.htm
; mirror: https://pegasus.pimpninjas.org/static/crtcreg.htm
; format: db register, value
db 11h, 00Ch ; clear CRTC protection
db 06h, 00Dh ; vertical total scanlines
db 07h, 03Eh ; overflow register
db 10h, 0EAh ; vertical retrace start
db 11h, 08Ch ; set CRTC protection
db 12h, 0DFh ; vertical display end
db 15h, 0E7h ; vertical blanking start
db 16h, 006h ; vertical blanking end
end