#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/io.h>
#include <curses.h> 
#include <termios.h>
#define PAR1 0x378
#define PAR2 0x379
#define PAR3 0x37a
#define DELAY1 32000 
int main(){
FILE *fp;
unsigned int inb;
char c;
int i,j,pcount;
unsigned int hextowrite;
unsigned char mem[2048],p1,p2,ti,lo1,rho1,ho1,accumulator;
pcount=0;
(void) initscr();      /* initialize the curses library */
keypad(stdscr, TRUE);  /* enable keyboard mapping */
(void) nonl();         /* tell curses not to do NL->CR/NL on output */
(void) cbreak();       /* take input chars one at a time, no wait for \n */
(void) noecho();       /* don't echo input */
if((fp=fopen("mem","r")) == NULL){
	printf("cannot open file\n");
	endwin();
	exit(1);
}
for(i=0;i<2048;i++){
	mem[i]=getc(fp);
}
fclose(fp);
for(i=0;i<7;i++){
	mvprintw(0,24+i*8,"Mem OC");
}
mvprintw(4,0,"Accumulator:");
mvprintw(6,6,"Port1:");
mvprintw(8,6,"Port2:");
resetcpu();
while(pcount<0x1ff){
        stat(&ti,&p1,&p2,&pcount);
	for(i=0;i<23;i++){
		for(j=0;j<7;j++){
		mvprintw(1+i,24+j*8,"%03x:%02x",i+j*23,mem[i+j*23]);
	if(pcount==i+j*23)
		mvaddch(i+1,23+j*8,'*'); 
	else
		mvaddch(i+1,23+j*8,' ');
	}
	}
	get_accumulator(&accumulator,pcount);
	mvprintw(4,13,"%02x",accumulator);
	mvprintw(6,13,"%02x",p1);
	mvprintw(8,13,"%02x",p2);
        out1 (mem[pcount+1]);
        delay();
	latchnext();
	out1(mem[pcount]);    
	delay();
        out3(0);
	delay();
        out3(8);
	move(0,0);	
	refresh(); 
}
for (;;){
	}
endwin();
}
int get_accumulator(unsigned char *accumulator,int count){
	unsigned char counttriml,counttrimh,alo,ahi;
	counttriml=count & 0x0000ff;
	counttrimh=(count >> 8) & 0x00000f;
        out3 (8);
        delay();
        out1(0x90);
        delay();
        out3 (0);
        delay();
        out3 (8);
        delay();
        out3(0xf);
        delay();
        alo=in2();
        delay();
        out1(0x47);
        delay();
        out3 (0);
        delay();
        out3 (8);
        delay();
        out1(0x90);
        delay();
        out3 (0);
        delay();
        out3 (8);
        delay();
        out3(0xf);
        delay();
        ahi=in2();
        delay();
        out1(0x47);
        delay();
        out3 (0);
        delay();
        out3 (8);
        delay();
        *accumulator=ahi*16+alo;
        out1 (counttriml);
        delay();
	latchnext();
        out1(counttrimh << 5 | 04);
        delay();
        out3 (0);
        delay();
        out3 (8);
        delay();
}	
int delay () {
	int i;
	for(i=1;i<DELAY1;i++){}
}
int latchnext () {
	out3(0xf);
        delay();
        out3 (8);
	delay();
}
int stat (unsigned char *ti, unsigned char *p1, unsigned char *p2, int *pcount) {
	unsigned char rho,ho,lo,p1lo,p1hi,p2lo,p2hi;
	out3(0xe);
	delay();
	rho=in2();
	rho=rho & 0x7;
	delay();
	out3(9);
	delay();
	ho=in2();
	delay();
	out3(0x8);
	delay();
	lo=in2();
	delay();
	*pcount=rho*256+ho*16+lo;
	out3(0xb);
	delay();
	p1hi=in2();
	delay();
	out3(0xa);
	delay();
	p1lo=in2();
	*p1=p1hi*16+p1lo;
	out3(0xd);
	delay();
	p2hi=in2();
	delay();
	out3(0xc);
	delay();
	p2lo=in2();
	*p2=(p2hi*16+p2lo);
	delay();
	out3(0x8);
	delay();
	return 0;
}
	
int resetcpu()
{
	out3 (8);
	delay();
	out1(00);
	delay();
	latchnext();
	out1 (04);
	delay();
	out3 (0);
	delay();
	out3 (8);
	delay();
}
int in2()
{
	unsigned char inbt;
        ioperm(PAR2,1,1);
        inbt=inb(PAR2);
	inbt=(((inbt & 0xf8) / 0x8) & 0xf);
        return inbt;
}
int out1(unsigned char bcout)
{
        unsigned int hextowrite;
        ioperm(PAR1,1,1);
        outb(bcout,PAR1);
        return 0;
}
int out3(unsigned char beout)
{
        ioperm(PAR3,1,1);
        beout=~beout;
        beout=beout & 0x0f;
        if((beout & 0x04) == 0x04){
                beout=beout-4;
        }
        else{
                beout=beout+4;
        }
        outb(beout,PAR3);
        return 0;
	
}

