; ---- File Routines for Ultrabasic
; ---- Gabriel Fernandez
; ---- You are not allowed to use this code without permission
; ---- Win32 version

; ---- CloseAll
CloseAll:
  mov dword [curclose], 0
closeloop:
  inc dword [curclose]
  mov eax, [curclose]
  shl eax, 2
  mov ebx, [eax+filehandle]
  cmp ebx, 0
  JE skipclose
    mov eax, [curclose]    
    CALL CloseFile
skipclose
  cmp dword [curclose], 255
  JNGE closeloop
RET

; ---- Setfilepos
; Eax - Filenum
; Ebx - New position
Setfilepos:
  SHL eax, 2
  mov [eax+filepos], ebx
  ADD eax, filehandle
  PUSH dword FILE_BEGIN
  PUSH dword 0
  PUSH ebx
  PUSH dword [eax]
  CALL [SetFilePointer]
  CMP EAX, 0FFFFFFFFh
  MOV EAX, 3
  JE ErrorEndProgram
RET

; ---- Getfilepos
; EAX - Filenum
; RETS: EAX - Filepos
Getfilepos:
  SHL eax, 2
  ADD eax, filehandle
  PUSH dword FILE_CURRENT
  PUSH dword 0
  PUSH dword 0
  PUSH dword [eax]
  CALL [SetFilePointer]
RET

; ---- File Open
; EAX - Num
; EBX - String
; 
; RETS: Nothing

OpenFile:
  PUSH EAX
  PUSH dword 0
  Push dword FILE_ATTRIBUTE_NORMAL
  Push dword OPEN_ALWAYS
  Push dword 0
  Push dword FILE_SHARE_READ
  Push dword GENERIC_READ + GENERIC_WRITE
  Add ebx, 4
  Push ebx
  CALL [CreateFileA]
  CMP eax, INVALID_HANDLE_VALUE
  JE openerror
  
  POP EBX
  shl ebx, 2
  mov edx, ebx
  mov ecx, ebx
  add ebx, filehandle
  add edx, filepos
  add ecx, fileeof
  mov dword [edx], 0
  mov dword [ecx], 0
  mov [ebx], eax
  RET
openerror:
  POP EAX
  mov eax, 4
  CALL NEAR ErrorEndProgram
RET

; ---- File Close
; EAX - Num

CloseFile:
  shl eax, 2
  add eax, filehandle
  PUSH dword [eax]
  mov dword [eax], 0
  CALL [CloseHandle]
  cmp eax, 0
  JE closeerror
  RET
closeerror:
  mov eax, 6
  Call NEAR ErrorEndProgram
RET

; ---------------------------
; File Get(Read, binary mode)
; ---------------------------
; Eax - File number
; Ebx - Offset
; Ecx - Bytes to copy/write
FileGet:
PUSH eax
SHL EAX, 2
ADD EAX, filehandle

PUSH dword 0
PUSH dword bytesread
PUSH ecx
PUSH ebx
mov ebx, ecx
PUSH dword [EAX]
CALL [ReadFile]
CMP EAX, 0
MOV EAX, 1
JE ErrorEndProgram

POP eax
Cmp ebx, [bytesread]
JE skipreof
  mov ecx, eax
  shl ecx, 2
  add ecx, fileeof
  mov dword [ecx], 1
skipreof:
mov ebx, [bytesread]
shl eax, 2
add eax, filepos
add [eax], ebx
RET

; ----------------------------
; File Put(write, binary mode)
; ----------------------------
; Eax - File number
; Ebx - Offset
; Ecx - Bytes to copy/write
FilePut:
PUSH eax
PUSH dword 0
PUSH dword byteswritten
PUSH ecx
PUSH ebx
  SHL EAX, 2
  ADD EAX, filehandle
PUSH dword [EAX]
CALL [WriteFile]
CMP EAX, 0
mov eax, 2
JE ErrorEndProgram
POP ebx
shl ebx, 2
add ebx, filepos
mov ecx, [byteswritten]
add [ebx], ecx
RET

; --- LOF
; EAX - File num
; Rets: Eax - Size
Lof:
  PUSH EDI
  PUSH ESI
  mov ebx, eax
  SHL eax, 2
  add eax, filehandle
  mov edx, [eax]
  PUSH edx
  PUSH dword FILE_END
  PUSH dword 0
  PUSH dword 0
  PUSH edx
  CALL [SetFilePointer]
  POP edx
  PUSH EAX

  PUSH dword FILE_BEGIN
  shl ebx, 2
  add ebx, filepos
  PUSH dword [ebx]
  PUSH dword 0
  PUSH edx
  CALL [SetFilePointer]
  POP eax
  POP ESI
  POP EDI
RET