/************************************************************
 *
 * Alcuin: A HP48 emulator for Amiga Computer
 *
 * Copyright (c) 1995 by Stephan Schupfer <schupfer@sbox.tu-graz.ac.at>
 *
 */

#include <stdio.h>
#include <exec/memory.h>
#include <dos/dos.h>

#include "romio.h"

unsigned int opt_gx = 0;
unsigned int rom_size = 0;

int read_rom_file(char *name, unsigned char **mem, int *size)
{
struct FileInfoBlock FIB;
APTR *filepointer;
unsigned char *tmp_mem;
unsigned char byte;
unsigned char four[4];
int i, j;

*mem = NULL;
*size = 0;
if (!(filepointer = (APTR *)Open(name,MODE_OLDFILE)))
	stirb ("Can't open %s.",9,name);
if (ExamineFH(filepointer, &FIB)==0)
	stirb ("Can't open %s.",9,"FileInfoBlock");
if (Read(filepointer,four,4) != 4) {
	Close(filepointer);
	stirb("File %s is not a Alcuin ROM.",13,name);
	}
if (four[0] == 0x02 && four[1] == 0x03 && four[2] == 0x06 && four[3] == 0x09)
	*size = FIB.fib_Size;
else {
	if (four[0] == 0x32 && four[1] == 0x96 && four[2] == 0x1b && four[3] == 0x80)
		*size = 2 * FIB.fib_Size;
	else {
		Close(filepointer);
		stirb ("File %s is not a Alcuin ROM.",13,name);
		}
	}
if (Seek(filepointer,0,OFFSET_BEGINNING) < 0) {
	Close(filepointer);
	stirb ("File %s is not a Alcuin ROM.",13,name);
	}
if ((*mem = (unsigned char *)AllocMem(*size,MEMF_CLEAR))==NULL)
	stirb("Can't alloc mem for %s.",11,"Alcuin ROM");
if (FIB.fib_Size == *size) {
	/*
	 * size is same as memory size, old version file
	 */

	if (Read(filepointer,*mem,(size_t)*size) != *size) {
		FreeMem(*mem,*size);
		*mem = NULL;
		*size = 0;
		Close(filepointer);
		stirb("File %s is corrupt.",14,name);
		}
	}
else {
	/*
	 * size is different, check size and decompress memory
	 */

	if (FIB.fib_Size != *size / 2) {
		FreeMem(*mem,*size);
		*mem = NULL;
		*size = 0;
		Close(filepointer);
		stirb("File %s is corrupt.",14,name);
		}
	if ((tmp_mem = (unsigned char *)AllocMem(FIB.fib_Size,MEMF_CLEAR))==NULL) {
		for (i = 0, j = 0; i < *size / 2; i++) {
			if (1 != Read(filepointer,&byte, 1)) {
				FreeMem(*mem,*size);
				*mem = NULL;
				*size = 0;
				Close(filepointer);
				stirb("File %s is corrupt.",14,name);
				}
			(*mem)[j++] = byte & 0xf;
			(*mem)[j++] = (byte >> 4) & 0xf;
			}
		}
	else {
		if (Read(filepointer,tmp_mem,*size / 2) != *size / 2) {
			FreeMem(*mem,*size);
			*mem = NULL;
			*size = 0;
			Close(filepointer);
			FreeMem(tmp_mem,FIB.fib_Size);
			stirb("File %s is corrupt.",14,name);
			}
		for (i = 0, j = 0; i < *size / 2; i++) {
			(*mem)[j++] = tmp_mem[i] & 0xf;
			(*mem)[j++] = (tmp_mem[i] >> 4) & 0xf;
			}
		FreeMem(tmp_mem,FIB.fib_Size);
		}
	}

Close(filepointer);
if ((*mem)[0x29] == 0x00) {
	if (*size == ROM_SIZE_GX) {
		opt_gx = 1;
		rom_size=*size;
		}
	else {
		FreeMem(*mem,*size);
		*mem = NULL;
		*size = 0;
		stirb ("File %s has wrong size.",15,name);
		}
	}
else {
	if (*size == ROM_SIZE_SX) {
		opt_gx = 0;
		rom_size=*size;
		}
	else {
		FreeMem(*mem,*size);
		*mem = NULL;
		*size = 0;
		stirb ("File %s has wrong size.",15,name);
		}
	}
return 1;
}
