        segment code
        align 16
        call start
start:  pop bx
        mov ax, cs
        shr bx, 4
        add ax, bx
        mov ds, ax
        mov es, ax

findvesa:
        mov ax, 4F00h
        mov di, data
        int 10h
        cmp ax, 004Fh
        je   .good
        mov  si, bad
        call prins
        jmp  finish
.good:  mov  si, data
        mov  cx, 4
        call prinsn
        call nline
        les  si, [data+6]
        call prins
        mov  ax, ds
        mov  es, ax
        call nline
modes:  mov  si, head
        call prins
        lgs  di, [data+14]
.loop:  mov  ax, [gs:di]
        cmp  ax, 0FFFFh
        je   setmd
        call phex4
        push ax
        mov  al, 'h'
        call princ
        pop  ax
        call space
        push di
        mov  cx, ax
        mov  ax, 4F01h
        mov  di, data
        int  10h
        mov  ax, ds
        mov  es, ax
        mov  ax, [data+18]
        call prinum
        call space
        mov  ax, [data+20]
        call prinum
        call space
        xor  ax, ax
        mov  al, [data+25]
        call prinum
        call space
        mov  ax, [data+6]
        call prinum
        call space
        mov  ax, [data+4]
        call prinum
        call nline
        pop  di
        add  di, 4
      ;  call waitk
        jmp  .loop
setmd:  call waitk
        mov  ax, 4F02h
        mov  bx, 0140h ; vesa mode
        int  10h
        mov  di, 29
bigloop:
        mov  ax, 4F05h
        xor  bx, bx
        mov  dx, di  ; bank number
        int  10h
fillup: 
        mov  ax, 0A000h
        mov  es, ax
        mov  si, 0000h
        mov  cx, 4000h
        mov  edx, 0
.loop:  mov  [es:si], edx
        add  si, 4
        dec  cx
        jne  .loop
        dec  di
        jge  bigloop
        call waitk
color:
        mov  ax, 4F05h
        xor  bx, bx
        mov  dx, 28  ; bank number
        int  10h

        mov  ax, 0A000h
        mov  es, ax
        mov  si, 4000h
        mov  cx, 1000h
        mov  edx, 0FF0000h
.loop:  mov  [es:si], edx
        add  si, 4
        dec  cx
        jne  .loop

finish: call waitk
        call dosmode
        mov si, done
        call prins
        mov ax, 4C00h  ; exit(0) line 1
        int 21h        ; exit line 2

waitk:  push ax
        xor  ax, ax
        int  16h
        pop  ax
        ret

dosmode:
        push ax
        mov ax, 0003h
        int 10h
        pop  ax
        ret

space:  push ax
        mov  al, 32
        call princ
        pop  ax
        ret

nline:  push ax
        mov  al, 13
        call princ
        mov  al, 10
        call princ
        pop  ax
        ret

princ:  push ax
        push bx
        mov  ah, 0Eh
        mov  bx, 0007h
        int  10h
        pop  bx
        pop  ax
        ret

prins:                 ; address of string in si
        push ax
        push si
.loop:  mov  al, [es:si]
        cmp  al, 0
        je   .end
        inc  si
        call princ
        jmp  .loop
.end:   pop  si
        pop  ax
        ret

prinsn:                ; address of string in si, len in cx
        pusha
.loop:  cmp  cx, 0
        je   .end
        dec  cx
        mov  al, [es:si]
        inc  si
        call princ
        jmp  .loop
.end:   popa
        ret

phex:   push ax
        push si
        push ax
        mov  si, ax
        and  si, 00F0h
        shr  si, 4
        add  si, hex
        mov  al, [si]
        call princ
        pop  si
        and  si, 000Fh
        add  si, hex
        mov  al, [si]
        call princ
        pop  si
        pop  ax
        ret

phex4:  push ax
        shr  ax, 8
        call phex
        pop  ax
        call phex
        ret

phexn:  push cx
        push si
        push ax
.loop:  cmp  cx, 0
        je   .end
        mov  al, [es:si]
        call phex
        call space
        inc  si
        dec  cx
        jmp  .loop
.end:   pop  ax
        pop  si
        pop  cx
        ret

prinum: pusha
        mov  bx, 10000
        xor  dx, dx
        idiv bx
        add  al, 48
        call princ
        mov  bx, 1000
        mov  ax, dx
        xor  dx, dx
        idiv bx
        add  al, 48
        call princ
        mov  bx, 100
        mov  ax, dx
        xor  dx, dx
        idiv bx
        add  al, 48
        call princ
        mov  bx, 10
        mov  ax, dx
        xor  dx, dx
        idiv bx
        add  al, 48
        call princ
        mov  al, dl
        add  al, 48
        call princ
        popa
        ret

        segment data
head:   db "Mode  width height bits winsz granu", 13, 10,
        db "-----------------------------------", 13, 10, 0
hex:    db "0123456789ABCDEF"
hello:  db "hello!", 13, 10, 0
done:   db "all over.", 13, 10, 0
smod:   db "set mode 013E", 13, 10, 0
bad:    db "no vesa detected", 13, 10, 0
data:   dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0




