; Svga functions for GABASIC
; Gabriel Fernandez
; RETS: EAX

Detectvesa:
mov dword [c_eax], 4F00h
mov ax, [rmodeblock]
mov [c_es], ax
mov dword [c_edi], 0
mov ax, 300h
mov bx, 10h
mov cx, 0
mov edi, c_edi
int 31h
mov eax, [c_eax]
ret

Setsvgamode:
PUSH EAX
mov dword [c_eax], 4F01h
mov [c_ecx], eax
add dword [c_edi], 100
mov ax, 300h
mov bx, 10h
mov cx, 0
mov edi, c_edi
PUSH word [c_es]
int 31h
cmp dword [c_eax], 4Fh
je slabel1
  mov ax, 1
  Call EndProgram
slabel1:
; ---- To emulate 64k banks and other stuff
mov edi, 0
POP di
shl edi, 4
add edi, 100
mov ebx, 0
mov eax, 64
mov edx, 0
mov bx, [edi+4]
div ebx
mov [wingran], ax
mov bx, [edi+18]
mov [xres], ebx
mov dword [curbank], 1000
; ----
mov ax, 4F02h
POP EBX
int 10h
ret

; ----- SVGA PSET
; EAX - X  EBX - Y  ECX - Col
SPset:
  mov esi, eax
  mov edx, 0
  mov eax, [xres]
  mul ebx
  add eax, esi    ; offset = xres * y + x
  mov edi, eax
  shr eax, 16
  cmp [curbank], eax
  JE drawpixel
    mov [curbank], eax
    mov bx, [wingran]
    mov dx, 0
    mul bx
    mov edx, eax
    mov ebx, 0
    mov eax, 4F05h
    INT 10h
drawpixel:
  AND edi, 0FFFFh
  add edi, 0A0000h
  mov [edi], cl
RET

; EAX - x
; EBX - y

SPoint:
  mov esi, eax
  mov edx, 0
  mov eax, [xres]
  mul ebx
  add eax, esi    ; offset = xres * y + x
  mov edi, eax
  shr eax, 16
  cmp [curbank], eax
  JE getpixel
    mov [curbank], eax
    mov bx, [wingran]
    mov dx, 0
    mul bx
    mov edx, eax
    mov ebx, 0
    mov eax, 4F05h
    INT 10h
getpixel:
  AND edi, 0FFFFh
  add edi, 0A0000h
  mov eax, 0
  mov al, [edi]
RET

; --- Hline
; EAX - x1   EBX - x2  ECX - Col  EDX - y
SHline:
  mov [sxlen], ebx
  sub [sxlen], eax
  inc dword [sxlen]
  mov [scol], ecx
  xchg edx, ebx
  mov esi, eax
  mov edx, 0
  mov eax, [xres]
  mul ebx
  add eax, esi    ; offset = xres * y + x
  mov edi, eax
  shr eax, 16
  cmp [curbank], eax
JE drawhline
    mov [curbank], eax
    mov bx, [wingran]
    mov dx, 0
    mul bx
    mov edx, eax
    mov ebx, 0
    mov eax, 4F05h
    INT 10h
drawhline:
  AND edi, 0FFFFh
  mov eax, edi
  add eax, [sxlen]
  cmp eax, 65536

JG bankhlinemode

; MODE SIN TENER QUE CAMBIAR DE BANCOS

  add edi, 0A0000h
  mov ecx, [sxlen]
  mov eax, [scol]
  REP STOSB
RET

bankhlinemode:

; TENIENDO QUE CAMBIAR DE BANCOS

 sub eax, 65536
 mov ecx, eax
 sub [sxlen], ecx
 mov eax, [sxlen]
 mov [sxlen], ecx
 mov ecx, eax
 mov eax, [scol]
 add edi, 0A0000h
 REP STOSB

 ; Cambiamos al siguiente banco

    inc dword [curbank]
    mov eax, [curbank]
    mov bx, [wingran]
    mov dx, 0
    mul bx
    mov edx, eax
    mov ebx, 0
    mov eax, 4F05h
    INT 10h

 mov edi, 0A0000h
 mov ecx, [sxlen]
 mov eax, [scol]
 REP STOSB

shskip:
RET

; --- SVline
; EAX - y1    EBX - y2   ECX - Col   EDX- x
SVline:
  mov [scol], ecx
  mov [sy1], eax
  mov [sy2], ebx
  mov ebx, eax
  mov esi, edx
  mov edx, 0
  mov eax, [xres]
  mul ebx
  add eax, esi    ; offset = xres * y + x
  mov edi, eax
  shr eax, 16
  cmp [curbank], eax
  JE svline
    mov [curbank], eax
    mov bx, [wingran]
    mov dx, 0
    mul bx
    mov edx, eax
    mov ebx, 0
    mov eax, 4F05h
    INT 10h
svline:
; -----------------------
; MAIN LOOP             *
; -----------------------
  MOV ESI, edi
  sub esi, [xres]
  mov dword [lastoff], 0

nextvy:
  INC dword [sy1]
  add esi, [xres]
  mov edi, esi  

  AND edi, 0FFFFh
  CMP edi, [lastoff]
JNL drawpixelv
    inc dword [curbank]
    mov eax, [curbank]
    mov bx, [wingran]
    mov dx, 0
    mul bx
    mov edx, eax
    mov ebx, 0
    mov eax, 4F05h
    INT 10h
drawpixelv:
  mov [lastoff], edi
  add edi, 0A0000h
  mov eax, [scol]
  mov [edi], al
  mov eax, [sy1]
  cmp eax, [sy2]
JNG nextvy
RET
