
/*************************************************************************
**
** o5_Simple.c
** Copyright (c) 1995,1996 Daniel Kahlin <tlr@stacken.kth.se>
**
** Commands: SIMPLEWRITE, SIMPLEREAD, BOOT, TEST
**
** NOT MACHINE DEPENDENT
**
******/

#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <string.h>

#include "Main_rev.h"

#include "Block.h"
#include "Protocol.h"
#include "Main.h"
#include "copytail64.h"
#include "booter.h"
#include "Convert.h"

#include "mach.h"

#define SW_TEMPLATE "FROM/A,OLD/S"

struct sw_args {
	UBYTE *as_from;
	ULONG as_old;
};

#define SR_TEMPLATE "TO/A,OLD/S"

struct sr_args {
	UBYTE *as_to;
	ULONG as_old;
};

#define BT_TEMPLATE "FROM/A,SAFEADDR,NEW/S"

struct bt_args {
	UBYTE *as_from;
	UBYTE *as_safeaddr;
	ULONG as_new;
};

#define TS_TEMPLATE "BLOCK/S,FILE/S,DEBUG/S"

struct ts_args {
	ULONG as_block;
	ULONG as_file;
	ULONG as_debug;
};

struct sr_args sr_argarray;
struct sw_args sw_argarray;
struct bt_args bt_argarray;
struct ts_args ts_argarray;

/*************************************************************************
**
** SIMPLEWRITE
**
******/
void o5_SimpleWrite(char *myparams)
{
	UBYTE *filename=NULL;
	UBYTE *inbuffer=NULL;
	ULONG len=NULL;

	if (!(mach_rdargs(SW_TEMPLATE,(LONG *)&sw_argarray,myparams)))
		panic("error in args");

	filename=sw_argarray.as_from;

	inbuffer=LoadFile(filename);
	len=jsize(inbuffer);
	if (sw_argarray.as_old)
		sendfile_old(inbuffer,len);
	else
		sendfile(inbuffer,len);

}





/*************************************************************************
**
** SIMPLEREAD
**
******/
void o5_SimpleRead(char *myparams)
{
	UBYTE *filename=NULL;
	UBYTE *inbuffer=NULL;
	ULONG len=NULL;

	if (!(mach_rdargs(SR_TEMPLATE,(LONG *)&sr_argarray,myparams)))
		panic("error in args");

	filename=sr_argarray.as_to;

	if (sr_argarray.as_old)
		receivefile_old(&inbuffer,&len);
	else
		receivefile(&inbuffer,&len);

	SaveFile(filename,inbuffer,len);
}





/*************************************************************************
**
** BOOT
**
******/
void o5_Boot(char *myparams)
{
	UBYTE *filename=NULL;
	UBYTE *buffer=NULL;
	UBYTE *newbuffer=NULL;
	ULONG addr,endaddr;
	ULONG newaddr,safeaddr;
	UBYTE *dataptr,*ptr;
	ULONG datalen;
	ULONG len=NULL;
	ULONG newlen;
	int i,stuff;
	UBYTE last,sum,chk;

	if (!(mach_rdargs(BT_TEMPLATE,(LONG *)&bt_argarray,myparams)))
		panic("error in args");

	if (!(newbuffer=jalloc(32768)))
		panic("no mem");

	filename=bt_argarray.as_from;
	buffer=LoadFile(filename);
	len=jsize(buffer);

	if (!bt_argarray.as_new) {
/*** old boot ***/

	/* c64 safeaddr */
		safeaddr=0xc000;

		if (bt_argarray.as_safeaddr) {
			safeaddr=makenum(bt_argarray.as_safeaddr);
		}	

	/*** calculate relevant info ***/
		dataptr=buffer+2;
		datalen=len-2;
		addr=*buffer+(*(buffer+1)<<8);
		endaddr=addr+datalen;
		printf("Loaded $%04x-$%04x, relocating and appending copytail...\n",addr,endaddr);

	/*** setnewaddr ***/
		newaddr=safeaddr-datalen;

	/*** build new file ***/
		*newbuffer=newaddr&0xff;
		*(newbuffer+1)=newaddr>>8;
		memcpy((newbuffer+2),dataptr,datalen);
		ptr=newbuffer+2+datalen;

	/*** append copytail ***/
		memcpy(ptr,tail,sizeof(tail));
		ptr+=sizeof(tail);

	/*** append params ***/
		*ptr++=newaddr&0xff;
		*ptr++=newaddr>>8;
		*ptr++=addr&0xff;
		*ptr++=addr>>8;
		*ptr++=endaddr&0xff;
		*ptr++=endaddr>>8;
		*ptr++=(datalen+255)>>8;
		newlen=ptr-newbuffer;
	
	/*** send away ***/
		slowsend(newbuffer,newlen);
	} else {

/*** new boot ***/
		ptr=newbuffer;
		last=0x00;
		stuff=FALSE;
		for (i=0; i<sizeof(booter); i++) {
			if (booter[i]==last && last==0xea)
				stuff=TRUE;
			last=booter[i];

			if (stuff) {
				switch (booter[i]) {
					case 0x00:
						*ptr++=0x11;
						*ptr++=0x80;
						break;
					case 0x11:
						*ptr++=0x11;
						*ptr++=0x11;
						break;
					default:
						*ptr++=booter[i];
						break;
				}
			} else {
				*ptr++=booter[i];
			}
		}

  /*** make sum ***/
	ptr=newbuffer;
	sum=0;
	for (i=0; i<0x1fe; i++) {
		sum+=*ptr++;
	}
	chk=-sum;

	if (chk!=1) {
		*(newbuffer+0x1fe)=0x01;
		*(newbuffer+0x1ff)=chk-1;
	}	else {
		*(newbuffer+0x1fe)=0x02;
		*(newbuffer+0x1ff)=chk-2;
	}
	/*** send away booter ***/
		/*SaveFile("ram:apan",newbuffer,512);*/
		slowsendnew(newbuffer,512);
	}

}


/*************************************************************************
**
** TEST
**
******/
void o5_Test(char *myparams)
{

	if (!(mach_rdargs(TS_TEMPLATE,(LONG *)&ts_argarray,myparams)))
		panic("error in args");

	if (!(ts_argarray.as_block || ts_argarray.as_file))
		panic("error in args");

	if (ts_argarray.as_debug)
		debug=DBG_FULL;
	if (ts_argarray.as_block)
		bl_blocktest();
	if (ts_argarray.as_file)
		bl_filetest();

}


