; -------- String Functions For GABasic --------
; Gabriel Fernandez 2000

; ---- MoveString
; EAX, dest
; EBX, src
MoveString:
  MOV ECX, [EBX]
  MOV EDX, [EAX]

  MOV EDI, EAX
  ADD EDI, EDX

  ADD EDX, ECX
  MOV [EAX], EDX
  
  MOV ESI, EBX
  ADD EDI, 4
  ADD ESI, 4
  REP MOVSB       
RET        ; END MoveString

; ---- MoveInmd
; EAX, dest
; EBX, src
; ECX, Len

MoveInmd:
  MOV EDX, [EAX]
  MOV EDI, EAX
  ADD EDI, EDX

  ADD EDX, ECX
  MOV [EAX], EDX
  
  MOV ESI, EBX
  ADD EDI, 4
  REP MOVSB       
RET        ; END MoveInmd

; CHR$
; - EAX, dest
; - EBX, char
CHR$:
 MOV EDX, [eax]
 INC EDX
 MOV [eax], edx
 add eax, edx
 add eax, 3
 mov [eax], bl
RET

; MID$
; - EAX, src
; - EBX, startpos
; - ECX, len          EDX, dest
MID$:
  DEC EBX
  PUSH EBX
  MOV ebx, [edx]
  add ebx, ecx
  mov [edx], ebx
  add eax, 4
  add edx, 4
  mov esi, eax
  mov edi, edx
  POP EBX
  add esi, ebx
  REP MOVSB
RET

; - Compare strings
; EAX, 1- EBX, 2
CmpStrings:
  mov ecx, [eax]
  mov edx, [ebx]
  cmp ecx, edx
  jne notequal
  cmp ecx, 0
  je equal
    add eax, 3
    add ebx, 3
Cmpnextbyte:
  dec ecx
    inc eax
    inc ebx
  mov dl, [eax]
  mov dh, [ebx]
  cmp dl, dh
  jne notequal
  cmp ecx, 0
  jne Cmpnextbyte
equal:
    mov eax, 1
    mov ebx, 1
  RET
notequal:
  mov eax, 1
  mov ebx, 2
RET

; - STR$
; - EAX, DEST
; - EBX, Value

STR$:
  PUSH EAX
  mov edi, 0
  CMP ebx, 0
  JGE positive2
    NEG EBX
    inc edi
positive2:
  inc edi
  xor ecx, ecx
  mov eax, ebx
  mov ebx, 10
Nextn:
  inc cx
  xor edx, edx
  DIV ebx
    PUSH DX
  CMP EAX, 0
JNE Nextn
  mov eax, tmp
  mov dx, cx
  CMP edi, 1
  JE skipneg
    mov byte [eax], 45
    inc cx
    inc eax
skipneg:
  
Nextn2:
  dec dx
    POP BX
    add bl, 48
    mov [eax], BL
    inc eax
  cmp dx, 0
JNE Nextn2
  POP EAX
  mov ebx, tmp
  Call MoveInmd
RET

; --- Val
; EBX, Dest
; RET: EAX, Value

Val:
  mov esi, 0
  mov ecx, [ebx]
  add ebx, 3
  mov al, [ebx+1]
  cmp al, 45
JNE noneg
   mov esi, 1
   dec ecx
   inc ebx
noneg:
  mov eax, 0
  mov edx, 0
next1:
   INC EBX
   INC EDX
   DEC ECX
     mov al, [ebx]
     sub al, 48
     PUSH EAX
   CMP ECX, 0
 JNE next1
  MOV ecx, edx
  MOV EBX, 1
  MOV EDI, 0
next2:
  DEC ECX
    POP EAX
    mov edx, 0
    MUL EBX
      add edi, eax
    MOV EDX, EBX
    Shl ebx, 1
    shl edx, 3
    add ebx, edx
  CMP ECX, 0
 JNE next2
mov eax, edi
cmp esi, 0
JE vskipneg
  neg eax
vskipneg:
RET

; - Getcommandline
Getcommandline:
  mov ebx, commandline
  mov ecx, [commandlen]
  cmp ecx, 0
  JE skipcmd
    CALL MoveInmd
skipcmd:
RET

Getexepath:
  mov ebx, exepath
  mov ecx, [exepathlen]
  cmp ecx, 0
  JE skipexe
    CALL MoveInmd
skipexe:
RET

; LCase$, Ucase$
; EAX - dest
; EBX - src

Lcase$:
  mov ecx, [ebx]
  mov edx, [eax]
  cmp ecx, 0
  je skiplcase$
  add ebx, 3
  add [eax], ecx
  add eax, 3
  add eax, edx
nextlc:
  DEC ecx
  inc eax
  inc ebx
  mov dl, [ebx]

  cmp dl, 65
  JNGE cmpnc
  cmp dl, 90
  JNLE cmpnc
  add dl, 32
cmpnc:
  mov [eax], dl
  cmp ecx, 0
JNE nextlc

skiplcase$:
ret

Ucase$:
  mov ecx, [ebx]
  mov edx, [eax]
  cmp ecx, 0
  je skipucase$
  add ebx, 3
  add [eax], ecx
  add eax, 3
  add eax, edx
nextuc:
  DEC ecx
  inc eax
  inc ebx
  mov dl, [ebx]

  cmp dl, 97
  JNGE ucmpnc
  cmp dl, 122
  JNLE ucmpnc
  sub dl, 32
ucmpnc:
  mov [eax], dl
  cmp ecx, 0
JNE nextuc

skipucase$:
ret


; String$
; EAX - dest, EBX - char, ECX - times

String$:
  mov edi, eax
  MOV edx, [eax]
  add edi, edx
  add edi, 4
  Add edx, ecx
  MOV [eax], edx

  mov eax, ebx
  REP STOSB
RET
