/*	$NetBSD: dos_file.S,v 1.1 2024/06/29 13:45:14 rin Exp $	*/
	
/* extracted from Tor Egge's patches for NetBSD boot */

#include <machine/asm.h>

/*
# MSDOS call "INT 0x21 Function 0x3d" to open a file.
# Call with	%ah = 0x3d
# 		%al = 0x0  (access and sharing modes)
#		%ds:%dx = ASCIZ filename
#		%cl = attribute mask of files to look for
*/

	.globl _C_LABEL(doserrno)
_C_LABEL(doserrno):	.long 1

ENTRY(dosopen)
	.code32
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edx
	pushl	%ebx
	pushl	%esi
	pushl	%edi
	
	movl	0x8(%ebp), %edx		# File name.

	call	_C_LABEL(prot_to_real)	# enter real mode
	.code16

	push	%ds
	movl	%edx, %eax
	shrl	$4, %eax
	mov	%ds, %si
	add	%si, %ax
	mov	%ax, %ds
	and	$0xf, %dx

	movb	$0x3d, %ah		# Open existing file.
	movb	$0x0 , %al		# ro

	sti
	int	$0x21
	cli
	pop	%ds

	jnc	ok1
	mov	%ax, _C_LABEL(doserrno)
	movl	$-1, %edx
	jmp err1
ok1:
	movl	$0,%edx
	mov	%ax, %dx
err1:
	calll	_C_LABEL(real_to_prot) # back to protected mode
	.code32

	movl	%edx, %eax		# return value in %eax

	popl	%edi
	popl	%esi
	popl	%ebx
	popl	%edx
	popl	%ebp
	ret

ENTRY(dosread)
	.code32
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	pushl	%ecx
	pushl	%edx
	pushl	%esi
	pushl	%edi
	
	movl	0x8(%ebp), %ebx		# File handle
	movl	0xc(%ebp), %edx		# Buffer.
	movl	0x10(%ebp), %ecx	# Bytes to read

	call	_C_LABEL(prot_to_real)	# enter real mode
	.code16

	push	%ds
	movl	%edx, %eax
	shrl	$4, %eax
	mov	%ds, %si
	add	%si, %ax
	mov	%ax, %ds
	and	$0xf, %dx

	movb	$0x3f, %ah		# Read from file or device

	sti
	int	$0x21
	cli
	pop	%ds

	jnc	ok2
	mov	%ax, _C_LABEL(doserrno)
	movl	$-1, %edx
	jmp	err2
ok2:
	movl	$0,%edx
	mov	%ax, %dx
err2:
	calll	_C_LABEL(real_to_prot)	# back to protected mode
	.code32

	movl	%edx, %eax		# return value in %eax

	popl	%edi
	popl	%esi
	popl	%edx
	popl	%ecx
	popl	%ebx
	popl	%ebp
	ret

ENTRY(dosclose)
	.code32
	pushl %ebp
	movl  %esp, %ebp
	pushl	%ebx
	pushl	%esi
	pushl	%edi
	
	movl	0x8(%ebp), %ebx		# File handle

	call	_C_LABEL(prot_to_real)	# enter real mode
	.code16

	movb	$0x3e, %ah		# Close file.

	sti
	int	$0x21
	cli

	jnc	ok3
	mov	%ax, _C_LABEL(doserrno)
	movl	$-1, %ebx
	jmp	err3
ok3:
	movl	$0, %ebx
err3:
	calll	_C_LABEL(real_to_prot) # back to protected mode
	.code32

	movl	%ebx, %eax		# return value in %eax

	popl	%edi
	popl	%esi
	popl	%ebx
	popl	%ebp
	ret

ENTRY(dosseek)
	.code32
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	pushl	%ecx
	pushl	%edx
	pushl	%esi
	pushl	%edi
	
	movl	0x8(%ebp), %ebx		# File handle
	movl	0xc(%ebp), %ecx		# Offset
	movl	0x10(%ebp) , %edx	# whence

	call	_C_LABEL(prot_to_real)	# enter real mode
	.code16

	movb	$0x42, %ah		# Seek
	movb	%dl, %al		# whence
	mov	%cx, %dx		#offs lo
	shrl	$0x10, %ecx		#offs hi

	sti
	int	$0x21
	cli

	jnc	ok4
	mov	%ax, _C_LABEL(doserrno)
	movl	$-1, %edx
	jmp	err4
ok4:
	shll	$0x10, %edx	#new ofs hi
	mov	%ax, %dx	#new ofs lo
err4:
	calll	_C_LABEL(real_to_prot) # back to protected mode
	.code32

	movl	%edx, %eax		# return value in %eax

	popl	%edi
	popl	%esi
	popl	%edx
	popl	%ecx
	popl	%ebx
	popl	%ebp
	ret
