#include <stdio.h>
#include <X11/Xlib.h>
#include <stdlib.h>
#include <string.h>
#include "memtype.h"
#include "mem.h"
#include "6502.h"
#include "atari.h"
#include "vdisk.h"
#include "atarimap.h"


/* Atari OS traps
 *  by Frank Barrus
 */


int trap_siov = True;


int emu_siov(void)
{
word sec, bufadr;
byte buf[256];
byte cmd;
byte dev;
word n;
int i;
char str[20];
	MEM_READ(B_DDEVIC, dev);
	if(dev < 0x31 || dev > 0x39)	/* if it's not a disk */
		return False;		/* don't trap it */
	dev -= 0x30;
	MEM_WREAD(B_DAUX1, sec);
	MEM_WREAD(W_DBUFLO, bufadr);
	MEM_READ(B_DCOMND, cmd);
	MEM_WREAD(W_DBYTLO, n);
	switch(cmd) {
	case 0x52:	/* read */
		if(n != vdisk_read_sec(dev, sec, buf))
			return False;
		for(i=0; i<n; i++)
			MEM_WRITE(bufadr+i, buf[i]);
		MEM_WRITE(B_DSTATS, 1);
		cpu.flags &= ~FLAG_N;
		printf("D%d: Read %d @%4x (%d)\n", dev, sec, bufadr, n);
		sprintf(str, "RD %05d", sec);
		interface_device_cmd('D',dev,str); 
		break;
	case 0x57:	/* write */
		for(i=0; i<n; i++)
			MEM_READ(bufadr+i, buf[i]);
		vdisk_write_sec(dev, sec, buf);
		MEM_WRITE(B_DSTATS, 1);
		cpu.flags &= ~FLAG_N;
		printf("D%d: Write %d @%4x (%d)\n", dev, sec, bufadr, n);
		sprintf(str, "WR %05d", sec);
		interface_device_cmd('D',dev,str); 
		break;
	case 0x53:	/* status */
		printf("D%d: Status\n", dev);
	case 0x21:	/* format */
	default:
		return False;
	}
	return True;
}


void ostrap(word addr)
{
	switch(addr) {
	case C_SIOV: if(trap_siov) { if(emu_siov()) return; } break;
/*
	case C_CIOV: if(trap_ciov) { if(emu_ciov()) return; } break;
*/
	default:		
	}
	DECW(cpu.pc);
	PUSHW(cpu.pc);
	cpu.pc = addr;
}


int ostrap_init(int argc, char **argv)
{
int narg = 0;
char **argp = argv;
char enab[2] = {'-','+'};

	while(argc--) {
		if(!strcmp(*argv, "-trap_siov")) {
			trap_siov = False;
		} else if(!strcmp(*argv, "+trap_siov")) {
			trap_siov = True;
		} else {
			*argp++ = *argv; narg++;
		}
		if(!strcmp(*argv++,"-h")) {
			printf("O.S. Trap options: (+ to enable, - to disable)\n");
			printf("\t%ctrap_siov\t\tSerial I/O\n", enab[trap_siov]);
			return narg;
		}
	}
	return narg;
}


