;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
; Real 2 SuperReal Demo June/July 1995                                    ;
; SuperReal (my first SVGA demo)                                          ;
;                                                                         ;
; combo routines by Adam Seychell and Jason Nunn(JsNO)                    ;
;                                                                         ;
; Contacts:                                                               ;
;                                                                         ;
; Email: jsno@turtle.apana.org.au or root@superr.apana.org.au             ;
; Snail: 32 Rothdale Rd,Darwin,NT,0810,Australia                          ;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SCREEN_X              = 640
SCREEN_Y              = 480

struc VbeInfoBlock
  VbeSignature        db   "VESA"    ; VBE Signature
  VbeVersion          dw   0200h     ; VBE Version
  OemStringPtr        dd   ?         ; Pointer to OEM String
  Capabilities        db   4 dup (?) ; Capabilities of graphics cont.
  VideoModePtr        dd   ?         ; Pointer to Video Mode List
  TotalMemory         dw   ?         ; Number of 64kb memory blocks
                                     ; Added for VBE 2.0
  OemSoftwareRev      dw   ?         ; VBE implementation Software revision
  OemVendorNamePtr    dd   ?         ; Pointer to Vendor Name String
  OemProductNamePtr   dd   ?         ; Pointer to Product Name String
  OemProductRevPtr    dd   ?         ; Pointer to Product Revision String
  _Reserved_          db   222 dup (?); Reserved for VBE implementation
                                     ; scratch area
  OemData             db   256 dup (?); Data Area for OEM Strings
ends

; Data structure for VESA function 4F01h ( Get mode Information )
struc ModeInfoBlock
  ; Mandatory information for all VBE revisions
  ModeAttributes      dw ?      ; mode attributes
  WinAAttributes      db ?      ; window A attributes
  WinBAttributes      db ?      ; window B attributes
  WinGranularity      dw ?      ; window granularity
  WinSize             dw ?      ; window size
  WinASegment         dw ?      ; window A start segment
  WinBSegment         dw ?      ; window B start segment
  WinFuncPtr          dd ?      ; pointer to window function
  BytesPerScanLine    dw ?      ; bytes per scan line

  ; Mandatory information for VBE 1.2 and above
  XResolution         dw ?      ; horizontal resolution in pixels or chars
  YResolution         dw ?      ; vertical resolution in pixels or chars
  XCharSize           db ?      ; character cell width in pixels
  YCharSize           db ?      ; character cell height in pixels
  NumberOfPlanes      db ?      ; number of memory planes
  BitsPerPixel        db ?      ; bits per pixel
  NumberOfBanks       db ?      ; number of banks
  MemoryModel         db ?      ; memory model type
  BankSize            db ?      ; bank size in KB
  NumberOfImagePages  db ?      ; number of images
  _Reserved           db ?      ; reserved for page function

  ; Direct Color fields (required for direct/6 and YUV/7 memory models)
  RedMaskSize         db ?      ; size of direct color red mask in bits
  RedFieldPosition    db ?      ; bit position of lsb of red mask
  GreenMaskSize       db ?      ; size of direct color green mask in bits
  GreenFieldPosition  db ?      ; bit position of lsb of green mask
  BlueMaskSize        db ?      ; size of direct color blue mask in bits
  BlueFieldPosition   db ?      ; bit position of lsb of blue mask
  RsvdMaskSize        db ?      ; size of direct color reserved mask in bits
  RsvdFieldPosition   db ?      ; bit position of lsb of reserved mask
  DirectColorModeInfo db ?      ; direct color mode attributes

  ; Mandatory information for VBE 2.0 and above
  PhysBasePtr         dd ?      ; physical address for flat frame buffer
  OffScreenMemOffset  dd ?      ; pointer to start of off screen memory
  OffScreenMemSize    dw ?      ; amount of off screen memory in 1k units
  __Reserved          db 206 dup (?)  ; remainder of ModeInfoBlock
ends

BankSetTable          DD 128 DUP (?)
VideoModeNumber       DW ?
Total64Kbocks         DW ?
label DOS_segs DWORD
Real_ES               DW  ?
Real_DS               DW  ?
VESA_SetBank          dd VESA_1_xR_setbank
VESA_SetStart         dd VESA_1_xR_set_addr
update_screen         dd banked_update_screen
sync_screen           dd banked_sync_screen

VideoPtr              dd ?
Rendbuff              dd ?
Rendbuff2             dd ?
Rendbuff3             dd ?
DOS_Ptr               dd ?

;------------------------------------------------------------
; Procudure to call a DOS interrupt.
;
; Expects the intrrupt number pushed on the stack.
;
;  e.g    push  10h
;         call  DOSinterrupt
;         jc   error
; Real mode ES and DS registers are passed via varibles Real_ES and Real_DS.
;
;
; As explained in the DOS32 documentaion, DOS32 initally handles all interrupts
; such that calling a protected mode interrupt will automatically call
; the same interrupt number in real mode.  However, using this method there
; is no way to specify the values of the real mode SEGMENT registers.
; Some of the VESA calls require ES:DI to point to buffers and so
; we need to use INT31h AX=300h service to call a real mode interrupt.
; The procedure below does exactly that...
;
;------------------------------------------------------------
proc DOSinterrupt
  push    0                       ; ignore  SS, SP
  lea     esp,[esp - 8]           ; ignore  CS, IP ,FS, GS
  push    [DOS_segs]              ; push DS and ES
  pushfw
  pushad
  mov     edi,esp
  mov     ax,0300h
  xor     cx,cx
  movzx   Ebx,[Byte esp+36h]      ; Get int number from stack param
  int     31h                     ; Emulate Real Mode Interrupt
  popad
  popfw
  pop     [DOS_segs]              ; get DS and ES
  lea     esp,[esp+12]            ; Ignore SS,SP,CS,IP,FS,GS
  ret                             ; return ingnoring parameter
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                          ;
; VESA1.xR callings                                                        ;
;                                                                          ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;edx = bank
proc VESA_1_xR_setbank
  int    10h
  ret
endp

;edx = set ptr value
proc VESA_1_xR_set_addr
  int    10h
  ret
endp

;edx = bank
macro @set_vesa_bank
  mov    edx,[edx*4+BankSetTable]
  xor    ebx,ebx
  mov    eax,4f05h
  call   [VESA_SetBank]
endm

;edx = set ptr value
macro @set_vesa_addr
local @@dont_adj_ofs
  xor    ecx,ecx
  mov    eax,offset VESA_1_xR_set_addr
  cmp    eax,[VESA_SetStart]
  je     @@dont_adj_ofs
  mov    eax,SCREEN_X/4
  mul    edx
  mov    ecx,eax
  mov    edx,eax
  and    ecx,0ffffh
  shr    edx,16
@@dont_adj_ofs:
  xor    ebx,ebx
  mov    eax,4f07h
  call   [VESA_SetStart]
endm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                          ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MACRO @WaitVert
LOCAL @@VR
  mov    edx,3dah
@@VR:
  in     al,dx
  test   al,8
  jz     @@VR
ENDM

MACRO @WaitVertEnd
LOCAL @@NVR
  mov    edx,3dah
@@NVR:
  in     al,dx
  test   al,8
  jnz    @@NVR
ENDM

;esi = offset to palette
;ecx = number of color values to write
;al = starting palette register
MACRO @WritePalette
  cli
  mov    edx,03c8h
  out    dx,al
  inc    edx
  rep    outsb
  sti
ENDM

macro @clear_pal
  cli
  mov    edx,03c8h
  out    dx,al
  inc    edx
  mov    ecx,768
  xor    al,al
@@l:
  out    dx,al
  dec    ecx
  jnz    @@l
  sti
endm

PIPED_CPU             = 1

macro @fast_copy
local @@fl
IF PIPED_CPU
  shr    ecx,4
@@fl:
  jxx = 0
rept 16
  mov    eax,[jxx+esi]
  mov    [jxx+edi],eax
  jxx = jxx + 4
endm
  add    esi,4*16
  add    edi,4*16
  dec    ecx
  jnz    @@fl
ELSE
  rep    movsd
ENDIF
endm

scr_flip_ptr          db 1

proc banked_update_screen
  mov    esi,[Rendbuff]
  xor    [scr_flip_ptr],1
  jz     @@flip2
  mov    edx,0
@@upd1:
  push   edx
  @set_vesa_bank
  mov    edi,[VideoPtr]
  mov    ecx,10000h/4
  @fast_copy
  pop    edx
  inc    edx
  cmp    edx,4
  jb     @@upd1
  @set_vesa_bank
  mov    edi,[VideoPtr]
  mov    ecx,(((SCREEN_X*SCREEN_Y)-(10000h*4))/4)
  @fast_copy
  xor    edx,edx
  @set_vesa_addr
  ret
@@flip2:
  mov    edx,5
@@upd2:
  push   edx
  @set_vesa_bank
  mov    edi,[VideoPtr]
  mov    ecx,10000h/4
  @fast_copy
  pop    edx
  inc    edx
  cmp    edx,5+4
  jb     @@upd2
  @set_vesa_bank
  mov    edi,[VideoPtr]
  mov    ecx,(((SCREEN_X*SCREEN_Y)-(10000h*4))/4)
  @fast_copy
  mov    edx,512
  @set_vesa_addr
  ret
endp

proc linear_update_screen
  mov    esi,[RendBuff]
  mov    edi,[VideoPtr]
  mov    ecx,(SCREEN_X*SCREEN_Y)/4
  xor    [scr_flip_ptr],1
  jz     @@flip2
@@upd1:
  @fast_copy
  xor    edx,edx
  @set_vesa_addr
  ret
@@flip2:
  add    edi,(SCREEN_X*SCREEN_Y)
  @fast_copy
  mov    edx,480
  @set_vesa_addr
  ret
endp

proc clear_screen
  mov    edi,[Rendbuff]
  mov    ecx,(SCREEN_X*SCREEN_Y)/4
  xor    eax,eax
  rep    stosd
  ret
endp

proc totally_clear_screen
  call   clear_screen
  call   [update_screen]
  call   [update_screen]
  ret
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
vrtv                   dw ?
old_IRQ00_sel          dw ?
old_IRQ00_ofs          dd ?
sync_screen_flag       db 0
fg_calc                dd fg_calc_default

proc set_IRQ00
  xor    bl,bl
  call   getirqvector
  mov    [dword old_IRQ00_ofs],edx
  mov    [word old_IRQ00_sel],cx
  xor    bl,bl
  lea    edx,[IRQ00_int]
  mov    cx,cs
  call   setirqvector
  cli
  mov    al,30h
  out    43h,al
  mov    eax,8000h
  out    40h,al
  mov    al,ah
  out    40h,al
  mov    al,30h
  out    43h,al
  mov    edx,3dah
  in     al,dx
  test   al,8
  jnz    $-3
  in     al,dx
  test   al,8
  jz     $-3
  xor    al,al
  out    40h,al
  out    40h,al
  in     al,dx
  test   al,8
  jnz    $-3
  in     al,dx
  test   al,8
  jz     $-3
  in     al,40h
  mov    ah,al
  in     al,40h
  xchg   al,ah
  neg    ax
  sub    ax,0c0h
  mov    [vrtv],ax
  mov    bx,ax
  in     al,dx
  test   al,8
  jz     $-3
  in     al,dx
  test   al,8
  jnz    $-3
  mov    al,bl
  out    40h,al
  mov    al,bh
  out    40h,al
  sti
  ret
endp

proc reset_IRQ00
  xor    bl,bl
  mov    edx,[dword old_IRQ00_ofs]
  mov    cx,[word old_IRQ00_sel]
  call   setirqvector
  cli
  mov    al,36h
  out    43h,al
  mov    al,0
  out    40h,al
  mov    al,0
  out    40h,al
  sti
  ret
endp

proc fg_calc_default
  ret
endp

proc IRQ00_int
  cld
  push   ds es fs gs
  pusha
  mov    ax,DGROUP
  mov    ds,ax
  mov    es,ax
  mov    edx,3dah
  in     al,dx
  and    eax,8
  dec    eax
  neg    eax
  add    [vrtv],ax
  in     al,dx
  test   al,8
  jz     $-3
  mov    ax,[vrtv]
  out    40h,al
  mov    al,ah
  out    40h,al
  mov    [byte sync_screen_flag],0
  call   [dword fg_calc]
  mov    al,20h
  out    20h,al
  popa
  pop    gs fs es ds
  iretd
endp

proc sync_screen_nochg
  mov    [byte sync_screen_flag],1
@@wait:
  cmp    [byte sync_screen_flag],1
  je     @@wait
  ret
endp

proc banked_sync_screen
  mov    esi,[Rendbuff]
  xor    [scr_flip_ptr],1
  jz     @@flip2
  mov    edx,0
@@upd1:
  push   edx
  @set_vesa_bank
  mov    edi,[VideoPtr]
  mov    ecx,10000h/4
  @fast_copy
  pop    edx
  inc    edx
  cmp    edx,4
  jb     @@upd1
  @set_vesa_bank
  mov    edi,[VideoPtr]
  mov    ecx,(((SCREEN_X*SCREEN_Y)-(10000h*4))/4)
  @fast_copy
  mov    [byte sync_screen_flag],1
@@wait:
  cmp    [byte sync_screen_flag],1
  je     @@wait
  xor    edx,edx
  @set_vesa_addr
  ret
@@flip2:
  mov    edx,5
@@upd2:
  push   edx
  @set_vesa_bank
  mov    edi,[VideoPtr]
  mov    ecx,10000h/4
  @fast_copy
  pop    edx
  inc    edx
  cmp    edx,5+4
  jb     @@upd2
  @set_vesa_bank
  mov    edi,[VideoPtr]
  mov    ecx,(((SCREEN_X*SCREEN_Y)-(10000h*4))/4)
  @fast_copy
  mov    [byte sync_screen_flag],1
@@wait2:
  cmp    [byte sync_screen_flag],1
  je     @@wait2
  mov    edx,512
  @set_vesa_addr
  ret
endp

proc linear_sync_screen
  mov    esi,[RendBuff]
  mov    edi,[VideoPtr]
  mov    ecx,(SCREEN_X*SCREEN_Y)/4
  xor    [scr_flip_ptr],1
  jz     @@flip2
@@upd1:
  @fast_copy
  mov    [byte sync_screen_flag],1
@@wait:
  cmp    [byte sync_screen_flag],1
  je     @@wait
;  @WaitVertEnd
  xor    edx,edx
  @set_vesa_addr
;  @WaitVert
  ret
@@flip2:
  mov    [byte sync_screen_flag],1
@@wait2:
  cmp    [byte sync_screen_flag],1
  je     @@wait2
  add    edi,(SCREEN_X*SCREEN_Y)
  @fast_copy
;  @WaitVertEnd
  mov    edx,480
  @set_vesa_addr
;  @WaitVert
  ret
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                          ;
; input bl = 0 0 0 0 0 0 0 0                                               ;
;                        | |- Force Real mode calling                      ;
;                        \--- Force banked mode                            ;
;                                                                          ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc CheckVbeMode
  mov    [@@mode_force],bl
@@re_do_on_fail:
  mov    [VideoModeNumber],101h
  mov    eax,0EE02h       ; GET REAL MODE SEGMENT OF FILE I/O BUFFER
  int    31h
  mov    [Real_ES],ax
  And    eax,0FFFFh
  shl    eax,4
  sub    eax,ebx
  Mov    [@@file_buffer],eax   ; save near address of 8Kb file buffer.
;  GET VESA INFORMATION
  mov    eax,4F00h
  mov    edi,0              ; (real mode) ES:DI -> 256 byte buffer
  push   10h
  call   DOSinterrupt
  add    esp,4
  Cmp    eax,004Fh
  jne    @@j_no_vesa
;verfiy driver version
  mov    esi,[@@file_buffer]                       ; save video mem size
  cmp    [dword esi+vbeInfoBlock.VbeSignature],"ASEV"
  jne    @@j_no_vesa
  cmp    [word esi+vbeInfoBlock.VbeVersion],0101h
  jb     @@j_defunc_vesa
  test   [@@mode_force],10b
  jnz    @@no_vbe2
  cmp    [word esi+vbeInfoBlock.VbeVersion],0200h
  jb     @@no_vbe2
  or     [VideoModeNumber],4000h
  mov    edx,offset @@vbem_bve2_found
  mov    ah,9
  int    21h
@@no_vbe2:
; Search video mode list for 640x480x256 ( VESA mode 101h )
  mov    dx,[esi+VbeInfoBlock.TotalMemory]
  mov    [Total64Kbocks],dx
; Get the real mode far pointer of the video mode list and
  Movzx  edx,[Word esi+2+VbeInfoBlock.VideoModePtr]
  shl    edx,4
  Movzx  ebx,[Word esi+VbeInfoBlock.VideoModePtr]
  add    edx,ebx                      ; EDX points to video mode list.
  add    edx,[Zero_Addr]
  mov    bx,[VideoModeNumber]
  and    bx,0111111111b               ; read bits 0..8
@@Loop01:
  Mov    ax,[Edx]                     ; Read video mode from list
  Cmp    Ax,0FFFFh
  je     @@j_101_defunc
  add    Edx,2
  cmp    Ax,Bx
  jne    @@Loop01
  mov    edx,offset @@vbem_101_found
  mov    ah,9
  int    21h
; Get VBE MODE information;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  mov    eax,4F01h
  mov    cx,[VideoModeNumber]
  and    cx,0111111111b               ; read bits 0..8
  mov    edi,0                         ; ES:DI -> 256 byte buffer
  push   10h
  call   DOSinterrupt
  add    esp,4
  Cmp    ax,004Fh
  jne    @@j_defunc_vesa
; If 32bit VBE inteface is availible then use the bloody thing
  test   [@@mode_force],1b
  jnz    @@No32bitInterface
  mov    eax,4F0Ah
  mov    BL,0                 ; return pmode interface
  push   10h
  call   DOSinterrupt
  add    esp,4
  Cmp    AX,004Fh
  jne    @@No32bitInterface
  movzx  Esi,[Real_ES]              ; convert ES:DI to 32bit near ptr
  shl    esi,4
  and    edi,0ffffh
  add    esi,edi
  add    esi,[Zero_Addr]   ; ESI -> protected mode table.
  movzx  eax,[Word ESI]
  add    eax,esi
  mov    [VESA_SetBank],eax         ; save Set Bank code address.
  movzx  eax,[Word 2+ESI]
  add    eax,esi
  mov    [VESA_SetStart],eax        ; save Set dsiplay start code address.
;finally, addr offset adjuster
  mov    edx,offset @@vbem_32biti_used
  jmp    @@no32biti_c
@@No32bitInterface:
  mov    edx,offset @@vbem_32biti_n_used
@@no32biti_c:
  mov    ah,9
  int    21h
; Determine to use windowing or linear memory mapping.
  test   [VideoModeNumber],0100000000000000b
  jz     @@DoWithBanks
; ******************************************************
; Setup for linear memory mapping mode.
; ******************************************************
  Mov    esi,[@@file_buffer]              ; EBP -> ModeInfoBlock
  Test   [word esi+ModeInfoBlock.ModeAttributes],10000000b
  jz     @@j_lmf
; Calulate a near pointer to physical linear mapping address.
  Mov    ebx,[esi+ModeInfoBlock.PhysBasePtr]
  Mov    eax,[@@Old_PhysBasePtr]
  cmp    eax,ebx
  je     @@Jskip06
  mov    [@@Old_PhysBasePtr],ebx
  mov    cx,bx
  shr    ebx,16
  mov    si,[Total64Kbocks]
  xor    edi,edi
  mov    ax,0800h                ; map physical memory
  int    31h
  jc     @@j_bad_lin_addr
  shl    ebx,16
  mov    bx,cx
  mov    eax,ebx                 ; eax = linear address
@@Jskip06:
  add    eax,[Zero_Addr]   ; ESI -> protected mode table.
  mov    [VideoPtr],eax
  mov    edx,offset @@vbem_linm_done
  mov    ah,9
  int    21h
  jmp    @@Finished
@@DoWithBanks:
; ******************************************************
; Setup for windowing mode.
; ******************************************************
; check is windowing is avalible ( writable and availible )
  Mov    esi,[@@file_buffer]              ; EBP -> ModeInfoBlock
  Test   [word esi+ModeInfoBlock.ModeAttributes],01000000b
  jnz    @@j_bmf
  Mov    bl,[esi+ ModeInfoBlock.WinAAttributes]
  and    bl,0000101b
  cmp    bl,0000101b
  jne    @@j_bmf
; Setup Bank Numbering table
  Movzx  eax,[esi+ModeInfoBlock.WinSize]
  Movzx  ebx,[esi+ModeInfoBlock.WinGranularity]
  xor    edx,edx
  div    ebx
  xor    edx,edx
  xor    ecx,ecx
@@loop02:
  mov    [ecx*4+BankSetTable],edx
  add    edx,eax
  inc    ecx
  cmp    ecx,length BankSetTable
  jb     @@loop02
; Calulate 32bit linear pointer to CPU video memory WindowA
  Movzx  eax,[esi+ModeInfoBlock.WinASegment]
  shl    eax,4
  add    eax,[Zero_Addr]   ; ESI -> protected mode table.
  mov    [VideoPtr],eax
  mov    edx,offset @@vbem_bankm_done
  mov    ah,9
  int    21h
@@Finished:
  clc
  ret
@@j_no_vesa:
  mov    edx,offset @@vbem_no_vesa
  jmp    @@message
@@j_defunc_vesa:
  mov    edx,offset @@vbem_defunc_vesa
  jmp    @@message
@@j_101_defunc:
  mov    edx,offset @@vbem_101_defunc
  jmp    @@message
@@j_lmf:
  mov    edx,offset @@vbem_lmf
  mov    ah,9
  int    21h
  or     [byte @@mode_force],10b
  jmp    @@re_do_on_fail
@@j_bad_lin_addr:
  mov    edx,offset @@vbem_bad_lin_addr
  mov    ah,9
  int    21h
  or     [byte @@mode_force],10b
  jmp    @@re_do_on_fail
@@j_bmf:
  mov    edx,offset @@vbem_bmf
  jmp    @@message
@@message:
  mov    ah,9
  int    21h
  xor    eax,eax
  stc
  ret
@@vbem_no_vesa        db "Vbe: Driver not found.",13,10,"$"
@@vbem_defunc_vesa    db "Vbe: Obsolete/bogus driver found.. but can't use it.",13,10,"$"
@@vbem_bve2_found     db "Vbe: Vbe2.0 found.. super fast Linear Mode will be attempted.",13,10,"$"
@@vbem_101_defunc     db "Vbe: 101h mode (640x480x256c) not supported.",13,10,"$"
@@vbem_101_found      db "Vbe: 101h mode found..",13,10,"$"
@@vbem_32biti_used    db "Vbe: Using Vbe2.0 Protected Mode calling.",13,10,"$"
@@vbem_32biti_n_used  db "Vbe: Using Vbe1.x Real Mode interrupt calling.",13,10,"$"
@@vbem_lmf            db "Vbe: Tried to initiate Linear mode, but failed.... retrying with banked mode.",13,10,"$"
@@vbem_bad_lin_addr   db "Vbe: Bogus Linear address??... Will Now try Banked Mode instead.",13,10,"$"
@@vbem_linm_done      db "Vbe: Using Vbe2.0 Linear mode.",13,10,"$"
@@vbem_bmf            db "Vbe: Tried to initiate Banked mode, but failed.. VESA init failed.",13,10,"$"
@@vbem_bankm_done     db "Vbe: Using Vbe1.x Banked mode.",13,10,"$"
@@Old_PhysBasePtr     dd -1
@@file_buffer         dd ?
@@mode_force          db ?
endp

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                          ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc setvbemode
  mov    bx,[VideoModeNumber]
  mov    eax,4F02h
  Int    10h
  test   [VideoModeNumber],0100000000000000b
  jz     @@DoWithBanks
@@linear:
  mov    eax,offset linear_update_screen
  mov    [update_screen],eax
  mov    eax,offset linear_sync_screen
  mov    [sync_screen],eax
@@DoWithBanks:
  mov    edx,SCREEN_X*SCREEN_Y
  mov    eax,0EE42h                                     ; allocate a DOS32 memory block
  Int    31h
  mov    [Rendbuff],edx
@@clr_scr:
  @clear_pal
  call   totally_clear_screen
  ret
endp
