// This may look like C code, but it is really -*- Asm -*-
/*
 *  smoke16/src16/fopen.s - Part of a sub-minimal SMOKE-16 I/O library.
 *  $Revision: 1.4 $
 *  Copyright 1997, 2000, Benjamin Sittler
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <smoke16/asm.h>
#include <smoke16/fcntl.h>

// FILE *fopen(char *path, char *mode)
	.rdata
fopen_types:
	.word 'r\0'
	.word O_RDONLY
	.word fopenD

	.word 'w\0'
	.word O_WRONLY|O_CREAT|O_TRUNC
	.word fopenD
	
	.word 'a\0'
	.word O_WRONLY|O_CREAT|O_APPEND
	.word fopenD
	
	.word 'r+'
	.word O_RDWR
	.word fopenD

	.word 'w+'
	.word O_RDWR|O_CREAT|O_TRUNC
	.word fopenD
	
	.word 'a+'
	.word O_RDWR|O_CREAT|O_APPEND
	.word fopenD
	
	.word 'rb'
	.word 0, fopenC

	.word 'wb'
	.word 0, fopenC
	
	.word 'ab'
	.word 0, fopenC

	.word 0, 0, fopenA
	
	.text
	.align 1
	FUNCTION(_fopen)
	push %t1
	push %t0
	push %a0
	push %a1
	mov __iob, %t0
	b fopen.try
fopen.next:
	add 4, %t0
fopen.try:
	mov __iob + 4 * 16, %a0
	cmpl %t0, %a0
	be fopenE
	mov [%t0], %a0
	cmp %a0, %0
	bl fopen.next
	mov -1, %a0
	mov %a0, [%t0+2]
	pop %a2
	mov fopen_types, %a0
fopenA:	mov [%a2], %a3
	add 1, %a2
fopenB:	mov %a0, %t1
fopen0:	mov [%t1], %a1
	cmpl %a1, %0
	be fopen1
	cmpl %a1, %a3
	be fopen1
	add 6, %t1
	b fopen0
fopen1:	mov [%t1 + 2], %a1
	mov [%t1 + 4], %t1
	j %t1
fopenC:	movb [%a2], %a3
	add 1, %a2
	b fopenB
fopenD:	pop %a0
	mov 0666, %a2
	call _open
	cmp %a0, %0
	bl fopenF
	mov %a0, [%t0]
	mov %t0, %a0
fopenE:	pop %t0
	pop %t1
	RET
fopenF:	mov -1, %a0
	mov %a0, [%t0]
	mov %0, %a0
	b fopenE
