\n");
sleep(1);
window( 1, 1, 80, 25);
gotoxy(1, 11);
MWrite( 0xFFFC, 0x00 ); /*
Default ProgramCounter value at Start */
MWrite( 0xFFFD, 0x00 );
MWrite( 0xBFFF, 0x07 ); /*
Select rom 7 */
fn[0] = '\0';
for (c = 1; c < argc; c++)
{
if (argv[c][0] == '-' ||
argv[c][0] == '/')
switch(tolower(argv[c][1]))
{
case 'b' :
sscanf(&(argv[c][2]), "%x", &la); /* Load Address */
b = 'b';
break;
case 'r' :
sscanf(&(argv[c][2]), "%x", &r); /* Rom Number */
MWrite( 0xBFFF, r );
cprintf ("Eprom selected : %d\r\n", r);
b = 'r';
break;
case 'i' :
b = 'i';
break;
case 'd' :
dflag = 1;
*dn = '\0';
sscanf(&(argv[c][2]), "%s", &dn); /* Debug Output */
break;
case 'm' :
RunMode = 1;
break;
case 'p' :
pflag = 1;
*pn = '\0';
sscanf(&(argv[c][2]), "%s", &pn); /* Printer Output */
break;
}
else
{
strcpy(fn, argv[c]);
if (access(fn, 0) == 0)
{
if (b == 'b')
LoadProg( fn, la );
else if (b == 'i')
HexRead( fn );
}
else
if (!ProcessIni( fn ))
cprintf("File/Label '%s' not found\r\n", fn);
else
ini++;
fn[0] = '\0';
}
}
if (!ini)
if (!ProcessIni( "ATOM9"
))
cprintf("Label '%s' not found\r\n", fn);
if (dflag)
if (strlen(dn) > 0)
{
if ((f_out = fopen( dn, "w")) == NULL)
{
fprintf(stderr, "Debug file can't open\n");
exit(1);
}
else
cprintf("Debug file = %s\r\n", dn);
}
if (pflag)
if (strlen(pn) > 0)
{
if ((printer = fopen( pn, "w")) == NULL)
{
fprintf(stderr, "Print file can't open\n");
exit(1);
}
else
if (RunMode)
cprintf("Printer = %s\r\n", pn);
}
else
{
printer = stdprn;
cprintf("Printer = %s\r\n", stdprn);
}
if (RunMode)
{
cprintf("\r\n\nPress any
key to continue");
bioskey(0);
}
crta80 = (MRead( 0x0209 ) << 8 ) + MRead( 0x0208
);
fast6502();
if (pflag)
fclose(printer);
if (dflag)
fclose(f_out);
if (fd != NULL)
fclose(fd);
gotoxy(1, 24);
}
void fast6502( void )
{
clrscr();
gettext(1, 1, 80, 25, crt80);
crt_col8 = 1;
crt_row8 = 1;
CrtOutput = TRUE;
MWrite( 0xBFFE, 1 );
Init_6502();
Stop = 0;
kb->kf01 = 0;
kb->kf02 = 0;
kb->kf03 = 0;
kb->kf07 = 1;
kb->kf09 = 0;
kb->kf14 = 0;
kb->kf15 = 0;
org = getvect(0x09);
setvect(0x09, kbint);
cb = 0x00;
ProcessOpcode();
setvect(0x09, org);
kb->kf01 = 0;
kb->kf02 = 0;
kb->kf03 = 0;
kb->kf07 = 0;
kb->kf09 = 0;
kb->kf14 = 0;
kb->kf15 = 0;
SwitchCrt( TRUE );
}
void SwitchCrt( int Mode )
{
unsigned i;
if (Mode == FALSE)
/* Set mode to 0 : Atom Crt */
{
if (CrtOutput)
{
gettext(1, 1, 80, 25, crt80);
crt_col8 = wherex();
crt_row8 = wherey();
}
grafix();
/*
regs.x.ax = 0x0004;
int86(0x10, ®s, ®s);
crta80 = (MRead( 0x0209
) << 8 ) + MRead( 0x0208 );
MWrite( 0x0208, crta32 &
0xFF );
MWrite( 0x0209, crta32 >>
8 );
MWrite( 0xFF9E, crta32 &
0xFF );
MWrite( 0xFF9F, crta32 >>
8 );
*/
CrtOutput = FALSE;
for (i = 0x8000; i <
0x9800; i++)
MWrite( i, MRead( i ));
}
else if (Mode == TRUE)
/* Set mode to 1 : 80 Coloms */
{
/*
regs.x.ax = 0x0003;
int86(0x10, ®s, ®s);
*/
text8();
puttext(1, 1, 80, 25, crt80);
gotoxy( crt_col8, crt_row8);
/*
crta32 = (MRead( 0x0209
) << 8 ) + MRead( 0x0208 );
MWrite( 0x0208, crta80 &
0xFF );
MWrite( 0x0209, crta80 >>
8 );
MWrite( 0xFF9E, crta80 &
0xFF );
MWrite( 0xFF9F, crta80 >>
8 );
*/
CrtOutput = TRUE;
}
}
void Init_6502( void )
{
if (kb->kf03) /* Control Key */
PC = MRead( 0xFFFC) + (MRead(
0xFFFD ) << 8);
else
PC = AltBoot;
SP = 0xFF;
P.P= 0x0000;
P.F.I = 1;
X = 0x00;
Y = 0x00;
A = 0x00;
/* Atom specific
Functions */
MWrite( 0xB000, 0x00 ); /* Set
KB Scan counter */
MWB00T( 0xB001, 0xFF ); /* No
key pressed */
MWB00T( 0xB002, 0xFF ); /* No
Repeat key */
MWrite( 0xB80C, 0x00 ); /* Zet
printer uit */
MWrite( 0xBFFF, 0x07 ); /* Set
RomSwitch to 7 */
MWrite( 0x9FFF, 0x07 ); /* and
mirror address to 7 */
MWrite( 0xE0, 0x00 );
/* Atom Bugje ?? */
cb = 0x00;
/* No KB Scan code */
nmi_set = 0;
/* No more NMI */
nmi_cnt = 20;
}
void Modes( int m )
{
int x, y;
x = wherex();
y = wherey();
if ( m & 1 )
{
gotoxy(60,1);
cprintf("Step mode ");
if (Step)
cprintf("ON \r\n");
else
cprintf("OFF\r\n");
}
if ( m & 2 )
{
gotoxy(60,2);
cprintf("Xray mode ");
if (Debug)
cprintf("ON \r\n");
else
cprintf("OFF\r\n");
}
if ( m & 4 )
{
gotoxy(60,3);
cprintf("BreakDetect ");
if (BreakDetect)
cprintf("ON \r\n");
else
cprintf("OFF\r\n");
}
gotoxy(x, y);
}
#ifdef DEBUG
void DebugDisp( void )
{
unsigned val;
unsigned char OpC = MRead( PC );
char work[80], pline[80];
sprintf(pline, "\rPC:%04X ", PC);
sprintf(work, "Op:%02X%c ", OpC, (OpC != Code[OpC].object)
? '*' : ' ');
strcat(pline, work);
sprintf(work, "A:%02X ", A);
strcat(pline, work);
sprintf(work, "X:%02X ", X);
strcat(pline, work);
sprintf(work, "Y:%02X ", Y);
strcat(pline, work);
sprintf(work, "SP:%02X ", SP);
strcat(pline, work);
sprintf(work, "P:%02X ", P.P);
strcat(pline, work);
sprintf(work, "%c", P.F.S ? 'S' : 's');
strcat(pline, work);
sprintf(work, "%c", P.F.V ? 'V' : 'v');
strcat(pline, work);
sprintf(work, "%c", '.');
strcat(pline, work);
sprintf(work, "%c", P.F.B ? 'B' : 'b');
strcat(pline, work);
sprintf(work, "%c", P.F.D ? 'D' : 'd');
strcat(pline, work);
sprintf(work, "%c", P.F.I ? 'I' : 'i');
strcat(pline, work);
sprintf(work, "%c", P.F.Z ? 'Z' : 'z');
strcat(pline, work);
sprintf(work, "%c", P.F.C ? 'C' : 'c');
strcat(pline, work);
sprintf(work, " Next: ");
strcat(pline, work);
if (Code[OpC].length > 0)
val = MRead( PC + 1 );
if (Code[OpC].length > 1)
val += MRead( PC + 2 ) <<
8;
sprintf(work, Code[OpC].asmx, val);
strcat(pline, work);
if (Code[OpC].flag == 1)
{
sprintf(work, " -> #%04X",
(val < 128) ? (PC + 2 + val) : ((PC + 2) - (0x100 - val)));
strcat(pline, work);
}
if (dflag)
fputs(pline, f_out);
else
cprintf("%s\r\n", pline);
if (cb == 0x3E) // F4
** Toggle On / Off Debug Loop
{
while(cb == 0x3E)
;
while(cb != 0x3E)
;
while(cb == 0x3E)
;
}
}
#endif
/********************* INCLUDE R65C02 PROCESSOR PART *********************/
#include "R65C02_9.c"
void FunKey( void )
{
switch (cb)
{
case 0x43 :
/* F9 Atom Break */
while(cb == 0x43)
;
Init_6502();
break;
case 0x3D :
/* F3 Switch crt 32 - 80 */
while(cb == 0x3D)
;
if ( CrtOutput == FALSE )
SwitchCrt( TRUE );
else
SwitchCrt( FALSE );
break;
#ifdef DEBUG
case 0x3F :
/* F5 Switch Debug Mode */
while(cb == 0x3F)
;
if (!DebugSet)
DebugSet = TRUE ;
else
DebugSet = FALSE ;
break;
case 0x40 :
/* F6 Debug Menu */
while(cb == 0x3F)
;
DebugMenu();
break;
#endif
case 0x3C :
/* F2 MENU */
if (!nmi_set)
{
while(cb == 0x3C)
;
setvect(0x09, org);
FileMenu();
setvect(0x09, kbint);
cb = 0x00;
if (Stop)
return;
}
break;
case 0x3B :
/* F1 Help menu */
if (!nmi_set)
{
while(cb == 0x3C)
;
setvect(0x09, org);
HelpMenu();
setvect(0x09, kbint);
cb = 0x00;
}
break;
}
}
/***** Atom Floppy Disk Controler Emulation *****/
unsigned FDC( int write, int address, unsigned value )
{
unsigned retval = 0xFF;
static unsigned status = 0x00, result = 0x10, i;
static unsigned command, parameter[10], ptr = 0;
static unsigned track, sector, head, seclen, secnum,
count;
static long filepos;
address &= 0xFF;
if (write)
switch (address)
{
case 0 :
/* Command */
command = value & 0x3F;
i = value >> 6;
if (i == 0x01)
fd = fd0;
if (i == 0x02)
fd = fd1;
ptr = 0;
break;
case 1 :
/* Parameters */
parameter[ptr++] = value;
switch(command)
{
case 0x35 : /* Specify */
break;
case 0x3A : /* Special (Start Motor) */
if (ptr == 2)
switch (value & 0xF0)
{
case 0x40 : fd = fd0; break;
case 0x80 : fd = fd1; break;
}
break;
case 0x29 : /* Seek */
if (ptr == 1)
track = value;
break;
case 0x23 : /* Format */
if (ptr == 1)
track = value;
if (ptr == 3)
{
seclen = (value >> 5);
secnum = (value & 0x1F);
filepos = (track * 2560L);
count = secnum * 256;
}
if (ptr == 5)
{
fseek(fd, filepos, 0);
status |= 0x84;
while (count-- > 0)
putc(0xE5, fd);
status &= 0x7F;
}
break;
case 0x1F : /* Verify & Deleted Data */
break;
case 0x0B : /* Write Data */
case 0x13 : /* Read Data */
if (ptr == 1)
track = value;
if (ptr == 2)
sector = value;
if (ptr == 3)
{
seclen = (value >> 5);
secnum = (value & 0x1F);
filepos = (track * 2560L) + (sector * 256L);
count = secnum * 256;
fseek(fd, filepos, 0);
status |= 0x84;
nmi_set = 1;
}
break;
}
break;
case 2 :
/* Reset */
status = 0;
result = 0;
ptr = 0;
track = 0;
head = 0;
fd = fd0;
break;
case 4 :
/* Write */
if (fd != NULL)
putc(value & 0xFF, fd);
status |= 0x84;
if (count == 0)
status &= 0x7B;
else
count--;
break;
}
else
switch (address)
{
case 0 :
/* Status */
if (nmi_set)
{
if (fd == NULL)
status &= 0xFC; /* warning for drive problem */
}
else
status &= 0x7F;
retval = status;
break;
case
1 :
/* Result */
if (command == 0x2C) /* Drive Status */
{
retval = (track == 0) ? 0x02 : 0x00;
retval |= 0x44;
}
else
{
if (nmi_set)
{
status &= 0x7B;
nmi_set = 0;
}
result = (fd == NULL) ? 0x10 : 0x00;
retval = result;
}
break;
case 4 :
if (fd == NULL)
{
status &= 0x7B;
retval = 0x00;
}
else
{
retval = getc(fd);
status |= 0x84;
if (count == 0)
{
status &= 0x7B;
}
else
count--;
}
break;
default
:
retval = 0xFF;
break;
}
return(retval);
}
/***********************************************************/
char ReadLine( char *s, int *l )
{
int p = 0, q = *l - 1;
char c;
while (( c = getch()) != '\r' && p < q)
{
if (c == 0x1B)
break;
else if (c == 0x00)
getch();
else if (c == '\b' &&
p)
{
cprintf("\b \b");
p--;
}
else if (c >=' ' &&
c <= '~')
{
s[p++] = c;
putch(c);
}
}
s[p] = '\0';
*l = p;
return(c);
}
void HelpMenu( void )
{
int x, y, Crt = CrtOutput;
if (Crt == FALSE)
SwitchCrt( TRUE );
gettext(1, 1, 80, 25, save);
x = wherex();
y = wherey();
clrscr();
cprintf("
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\r\n");
cprintf("
º Acorn Atom Help Menu
º\r\n");
cprintf("
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\r\n\n");
cprintf(" F1 = Dit
HELP Menu\r\n");
cprintf(" F2 = Bestands
Invoer, uitvoer en verlaten AtomEmulator\r\n");
cprintf(" F3 = Omschakelen
tussen 80 Koloms en 32 Koloms/Grafics\r\n");
cprintf(" F9 = Atom
Break toets, springt naar alternatief adres\r\n");
cprintf(" Ctrl-F9 = Atom Break toets, springt naar
standaard adres\r\n\n");
cprintf(" INS = Atom
COPY toets\r\n");
cprintf(" ALT = Atom
REPT (repeat) toets\r\n\n");
cprintf(" BFFE is
schakel adres voor 80/32 koloms mode\r\n");
cprintf(" B010 schrijf/lees
byte op 80 koloms scherm\r\n");
cprintf(" B011 schrijf/lees
cursor positie in 80 koloms mode\r\n");
cprintf(" B012 schrijf/lees
cursor regel in 80 koloms mode\r\n");
getch();
puttext(1, 1, 80, 25, save);
gotoxy(x, y);
if (Crt == FALSE)
SwitchCrt( Crt );
}
void FileMenu( void )
{
int x, y, c, Crt = CrtOutput;
if (Crt == FALSE)
SwitchCrt( TRUE );
gettext(1, 1, 80, 25, save);
x = wherex();
y = wherey();
do
{
clrscr();
cprintf("
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\r\n");
cprintf("
º Acorn Atom File I/O Menu º\r\n");
cprintf("
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ");
cprintf("\r\n\n
1 = Atom Diskette emulatie");
cprintf("\r\n\n
2 = Atom Programma lezen van DOS disk");
cprintf("\r\n\n
3 = Intel Hex bestand lezen van DOS disk");
cprintf("\r\n\n
4 = Atom Programma schrijven naar DOS disk");
cprintf("\r\n\n\n
Q = * AtomEmulator verlaten *");
cprintf("\r\n\n\n
<Esc> = Klaar");
cprintf("\r\n\n
Keuze : *\b");
c = tolower( getch() );
switch(c)
{
case '1' :
OpenFlex();
break;
case '2' :
ReadFile();
break;
case '3' :
ReadFileHex();
break;
case '4' :
WriteFile();
break;
case 'q' :
Stop = 1;
c = 0x1B;
break;
}
}
while( c != 0x1B );
puttext(1, 1, 80, 25, save);
gotoxy(x, y);
if (Crt == FALSE)
SwitchCrt( Crt );
}
void OpenFlex( void )
{
int aw, drive, len;
long count;
FILE *fdx;
clrscr();
cprintf("
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\r\n");
cprintf("
º Atom Diskette (bestand) Openen / Sluiten
º\r\n");
cprintf("
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ");
cprintf("\r\n\n
Geef DriveNummer (0/1) voor ATOM Diskette : ");
drive = 9;
while (drive > 1)
{
drive = getch();
if (drive == 0x1B)
return;
if (drive >= '0' &&
drive <= '1')
drive = drive - '0';
}
cprintf("%d\r\n\n", drive);
fdx = fd0;
if (drive)
fdx = fd1;
if (fdx != NULL)
fclose(fdx);
fdx = NULL;
cprintf("
Geef Bestandsnaam van ATOM Diskette : \r\n\n
>");
cprintf("\r
>");
len = 64;
if ( ReadLine( af_name, &len ) == 0x1B)
return;
if (strchr(af_name, '*') || strchr(af_name, '?'))
if (GetFileMenu(af_name)
== 2)
return;
cprintf("%s", af_name);
if ( len > 0 )
{
strcpy(atom_dsk0, af_name);
if ((fdx = fopen(atom_dsk0,
"rb+")) == NULL)
{
cprintf("\r\n\n
DISK niet gevonden, AANMAKEN (j/n) ? ");
while ((aw = tolower(getch())) != 'n' && aw != 'j')
;
putch(aw);
if (aw == 'j')
{
if ((fdx = fopen(atom_dsk0, "wb")) == NULL)
{
cprintf("\r\n\n
*** Disk kan niet aangemaakt worden ***");
getch();
}
else
{
count = 40L * 10L * 256L;
while (count--)
putc('\0', fdx);
fclose(fdx);
if ((fdx = fopen(atom_dsk0, "r+")) == NULL)
{
cprintf("\r\n\n
*** Disk kan niet aangemaakt worden ***");
getch();
}
}
}
}
}
if (drive)
fd1 = fdx;
else
fd0 = fdx;
MWrite( 0xEE, MRead( 0xEE ) & 0x7F );
}
void WriteFile( void )
{
FILE *fb;
int c, len;
unsigned addr, tot;
long ptr1, ptr2;
clrscr();
cprintf("
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\007\r\n");
cprintf("
º Atom bestand naar DOS Disk schrijven º\007\r\n");
cprintf("
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹\007\r\n");
cprintf("
ÈÍÍÍÍÍ< Basis : %04X >ÍÍ<
Top : %04X >ÍÍÍÍͼ", MRead(18)*256,
MRead(13)+(MRead(14)*256));
cprintf("\r\n\n
Bestandsnaam : ");
len = 64;
if (ReadLine( af_name, &len ) == 0x1B || len
== 0)
return;
if (access( af_name, 0 ) == 0)
{
cprintf("\r\n\n\007
!!! Bestand bestaat al : Overschrijven (J/N) ? ");
while ( ( c = tolower( getch()
) ) != 'n' && c != 'j' && c != 0x1B )
;
if ( c == 'n' || c == 0x1B)
return;
}
if ((fb = fopen( af_name, "wb" )) == NULL)
{
cprintf("\r\n\n\007
!!! Bestand kan niet worden aangemaakt !!!");
getch();
return;
}
cprintf("\r\n\n
Start adres : ");
len = 5;
if (ReadLine( af_name, &len ) == 0x1B)
{
fclose(fb);
return;
}
if (!len)
{
addr = (unsigned) MRead(18)*256;
cprintf("%04X", addr);
}
else
sscanf(af_name, "%x", &addr);
cprintf("\r\n\n
Eind adres : ");
len = 5;
if (ReadLine( af_name, &len ) == 0x1B)
{
fclose(fb);
return;
}
if (!len)
{
tot = (unsigned) MRead(13)+(MRead(14)*256);
cprintf("%04X", tot);
}
else
sscanf(af_name, "%x", &tot);
if (tot <= addr)
{
cprintf("\r\n\n\007
!!! Eind adres moet groter zijn dan Start adres !!!");
getch();
fclose(fb);
return;
}
ptr1 = addr;
ptr2 = tot;
while (ptr1++ <= ptr2)
fputc( MRead( addr++ ),
fb );
fclose(fb);
cprintf("\r\n\n
Bestand is weggeschreven");
getch();
}
void ReadFile( void )
{
FILE *fb;
unsigned addr;
int c, len;
clrscr();
cprintf("
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\r\n");
cprintf("
º Atom bestand van DOS Disk Lezen º\r\n");
cprintf("
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹\r\n");
cprintf("
ÈÍÍÍÍÍÍÍÍÍÍÍ<
Basis : %04X >ÍÍÍÍÍÍÍÍÍͼ",
MRead(18)*256);
cprintf("\r\n\n
Bestandsnaam : ");
len = 64;
if (ReadLine( af_name, &len ) == 0x1B)
return;
cprintf("\r
Bestandsnaam : ");
if (strchr(af_name, '*') || strchr(af_name, '?')
|| strlen(af_name) == 0)
if (GetFileMenu(af_name)
== 2)
return;
cprintf("%s", af_name);
if ((fb = fopen( af_name, "rb" )) == NULL)
{
cprintf("\r\n\n\007
!!! Bestand kan niet worden geopend !!!");
getch();
return;
}
cprintf("\r\n\n
Start adres : ");
len = 5;
if (ReadLine( af_name, &len ) == 0x1B)
{
fclose(fb);
return;
}
if (!len)
{
addr = (unsigned) MRead(18)*256;
cprintf("%04X", addr);
}
else
sscanf(af_name, "%x", &addr);
while ((c = fgetc(fb)) != EOF)
MWrite( addr++, c );
fclose(fb);
cprintf("\r\n\n
Top = %04X <Any key>", --addr);
getch();
}
void ReadFileHex( void )
{
int len;
clrscr();
cprintf("
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\r\n");
cprintf("
º Intel Hex bestand van DOS Disk Lezen º\r\n");
cprintf("
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ");
cprintf("\r\n\n
Bestandsnaam : ");
cprintf("\r
Bestandsnaam : ");
len = 64;
if (ReadLine( af_name, &len ) == 0x1B)
return;
if (strchr(af_name, '*') || strchr(af_name, '?')
|| strlen(af_name) == 0)
if (GetFileMenu(af_name)
== 2)
return;
cprintf("%s", af_name);
cprintf("\r\n\n");
HexRead( af_name );
getch();
}
int HexRead( char *fn )
{
FILE *fi;
unsigned char c;
unsigned len, p, r = 0, chk, rec_type = 0;
unsigned teller = 0;
unsigned addr;
struct hexrec
{
unsigned char dp;
unsigned char size[2];
unsigned char addr[4];
unsigned char type[2];
unsigned char data[120];
} rec;
if (RunMode)
cprintf("Load '%s' : ",
fn);
if (access(fn, 0) == 0)
{
if ((fi = fopen(fn, "r"))
!= NULL)
{
while(rec_type != 1)
{
fgets( (char *) &rec, sizeof(struct hexrec), fi);
r++;
if (rec.dp != ':')
{
cprintf("Read out of sync in record : %d\r\n", r);
return(1);
}
chk = len = ctob( rec.size, 0 );
if (len == 0)
break;
addr = 0;
for (p = 0; p < 4; p += 2)
{
chk += c = ctob( rec.addr, p );
addr = (addr << 8) + c;
}
chk += rec_type = ctob( rec.type, 0 );
if (rec_type == 0)
{
for (p = 0; p < (len * 2) ; p += 2)
{
chk += c = ctob( rec.data, p );
MWrite( addr++, c);
teller++;
}
if (((chk += ctob( rec.data, p )) & 0xFF) != 0 )
cprintf(">> Checksum Error %02X in record %d\r\n", chk & 0xFF, r );
}
}
if (RunMode)
cprintf("Loaded (%u bytes)\r\n", teller);
}
else
cprintf("\007*** Can't open file : '%s' ***\007\r\n", fn);
}
else
cprintf("\007*** File not
found : '%s' ***\007\r\n", fn);
fclose(fi);
return(0);
}
unsigned char ctob( unsigned char *data, unsigned p )
{
unsigned char c, w;
c = (data[p] - '0');
if (c > 9)
c -= 7;
w = (data[p + 1] - '0');
if (w > 9)
w -= 7;
c = ( c << 4 ) + w;
return(c);
}
void LoadProg( char *fn, unsigned la )
{
long teller = 0L;
unsigned p = la;
int k;
FILE *fp;
if (RunMode)
cprintf("Load '%s' : ",
fn);
if (access(fn, 0) == 0)
{
if ((fp = fopen(fn, "rb"))
!= NULL)
{
while (( k = getc(fp)) != EOF )
{
MWrite( p++, k );
teller++;
}
fclose(fp);
if (RunMode)
cprintf("Loaded (%lu bytes) at address %04X\r\n", teller, la);
}
else
cprintf("Can't open file \r\n");
}
}
void LoadKeyboardDef( char *kbrd_def )
{
FILE *fk;
int i;
if ((fk = fopen(kbrd_def, "rb")) == NULL)
cprintf("\007*** Can' open
keyboard definition file %s\007 ***\r\n", kbrd_def);
else
for (i = 0; i < 128;
i++)
fscanf(fk, "%c%c%c%c%c%c", &ak[i].b001, &ak[i].b000, &ak[i].shift,
&ak[i].b001s, &ak[i].b000s, &ak[i].shifts);
fclose(fk);
if (RunMode)
cprintf("Loaded keyboard
definition : %s\r\n", kbrd_def);
}
int ProcessIni( char *ctlname )
{
FILE *fc;
char pline[512], *p, ctln[80], parm[80], *q;
int step = 0, srom = 7, ok = 0;
unsigned la;
if ((fc = fopen("ATOM.INI", "r")) == NULL)
{
fprintf(stderr, "\nCan't
open %s\n\n", "ATOM.INI");
exit(1);
}
strcpy(ctln, "[");
strcat(ctln, ctlname);
strcat(ctln, "]");
strupr(ctln);
while (fgets(pline, sizeof(pline), fc) != NULL)
{
if (!step)
/* Look for [LABEL] */
{
strupr(pline);
if (!strncmp(pline, ctln, strlen(ctln)))
step++;
}
else
{
ok = 1;
p = pline;
pline[strlen(pline) - 1] = '\0';
if
(*p == '[')
break;
if (*p == ';')
continue;
while (*p == ' ')
p++;
q = parm;
while (*p != ' ' && *p != '=' && *p != '\0')
*q++ = *p++;
*q = '\0';
while (*p == ' ')
p++;
strupr(parm);
if (!strcmp(parm, "ADDRESS") || !strcmp(parm, "ADRES"))
{
if (*p == '=')
p++;
else
continue;
while (*p == ' ')
p++;
sscanf(p, "%x", &la);
}
else if (!strcmp(parm, "ALTBOOT"))
{
if (*p == '=')
p++;
else
continue;
while (*p == ' ')
p++;
sscanf(p, "%x", &AltBoot);
if (RunMode)
printf("Alternate Boot Address = %04X\r\n", AltBoot);
}
else if (!strcmp(parm, "LOADBIN") || !strcmp(parm, "LAADBIN"))
{
if (*p == '=')
p++;
else
continue;
while (*p == ' ')
p++;
LoadProg(p, la);
}
else if (!strcmp(parm, "LOADHEX") || !strcmp(parm, "LAADHEX"))
{
if (*p == '=')
p++;
else
continue;
while (*p == ' ')
p++;
HexRead(p);
}
else if (!strcmp(parm, "KEYBOARD") || !strcmp(parm, "TOETSENBORD"))
{
if (*p == '=')
p++;
else
continue;
while (*p == ' ')
p++;
LoadKeyboardDef( p );
}
else if (!strcmp(parm, "PRINTER") || !strcmp(parm, "SPOOL"))
{
if (*p == '=')
p++;
else
continue;
while (*p == ' ')
p++;
pflag = 1;
strcpy(pn, p);
}
else if (!strcmp(parm, "SCHAKEL") || !strcmp(parm, "ROM") || !strcmp(parm,
"SWITCH"))
{
if (*p == '=')
p++;
else
continue;
while (*p == ' ')
p++;
la = 0xA000;
sscanf(p, "%d", &srom);
MWrite( 0xBFFF, srom );
if (RunMode)
cprintf ("Eprom selected : %d\r\n", srom);
}
else if (!strcmp(parm, "MODE") || !strcmp(parm, "RUNMODE"))
{
if (*p == '=')
p++;
else
continue;
while (*p == ' ')
p++;
if (toupper(*p) == 'D')
RunMode = 1;
else if (toupper(*p) == 'Y')
RunMode = 1;
}
else if (strlen(parm))
{
fprintf(stderr, "Unknown parameter : %s\n", pline);
}
}
}
if (!step)
{
fprintf(stderr, "Label %s
not found\n", ctln);
exit(1);
}
fclose(fc);
return( ok );
}
/********************** Select filename **************************/
int GetFileMenu( char *fname )
{
int RetCode, x, y;
char temp[4096];
gettext(1, 1, 80, 25, temp);
x = wherex();
y = wherey();
RetCode = GetFile( fname );
puttext(1, 1, 80, 25, temp);
gotoxy( x, y);
return( RetCode );
}
struct dl
/* Structure for storing directory entries */
{
struct dl *fp; /*
forward pointer */
struct dl *bp; /*
backward pointer */
int l;
/* display line */
int p;
/* display position */
int n;
/* last entry on page */
char fn[13];
/* filename to display */
} *begin, *first, *last, *rec, *prev;
int GetFile( char *fname )
{
struct ffblk ffblk;
int done, count = 0, flags, line = 3, pos = 1, stop
= 0, RetCode = 0;
unsigned k;
char drive[MAXDRIVE],
dir[MAXDIR],
file[MAXFILE],
ext[MAXEXT],
work[MAXPATH];
flags = fnsplit(fname, drive, dir, file, ext);
if ( !((flags & FILENAME) && (flags
& EXTENSION)))
{
strcpy(file, "*");
strcpy(ext, ".*");
}
fnmerge(fname, drive, dir, file, ext);
clrscr();
cprintf("PATH = %s\n\n", fname);
if ((done = findfirst( fname, &ffblk, 0 )) !=
0)
return(1);
while ( !done )
{
prev = rec;
if ((rec = malloc( sizeof(
struct dl ))) == NULL)
{
fprintf(stderr, "\nOut of memory\n");
prev = begin;
do
{
rec = prev;
prev = rec->fp;
free(rec);
}
while (prev->fp != NULL);
return(1);
}
if ( !count )
{
begin = rec;
prev = NULL;
}
else
{
rec->bp = prev;
prev->fp = rec;
}
rec->bp = prev;
strcpy( rec->fn, ffblk.ff_name
);
rec->fp = NULL;
rec->l = line++;
rec->p = pos;
rec->n = 0;
if (line > 24)
{
line = 3;
if (( pos += 15 ) > 68 )
{
pos = 1;
rec->n = 1;
}
}
count++;
done = findnext( &ffblk
);
}
prev = rec = begin;
GetFilePage( fname );
rec = prev;
while (!stop)
{
gotoxy( prev->p, prev->l
);
cprintf(" %s", prev->fn);
gotoxy( rec->p, rec->l );
cprintf(">%s", rec->fn);
prev = rec;
k = bioskey(0) >> 8;
switch(k)
{
case 0x01 :
/* Esc */
RetCode = 2;
stop = 1;
break;
case 0x1C :
/* Return */
stop = 1;
fnsplit(rec->fn, work, work, file, ext);
fnmerge(fname, drive, dir, file, ext);
break;
case 0x48 :
/* CurUp */
if (rec != first)
rec = rec->bp;
break;
case 0x50 :
/* CurDown */
if (rec != last)
rec = rec->fp;
break;
case 0x4B :
/* CurLeft */
line = rec->l;
if (rec->p > 1)
do
{
if (rec == first)
break;
rec = rec->bp;
}
while (rec->l != line);
break;
case 0x4D :
/* CurRight */
line = rec->l;
if (rec->p < last->p)
do
{
if (rec == last)
break;
rec = rec->fp;
}
while (rec->l != line);
break;
case 0x47 :
/* Home */
rec = first;
break;
case 0x4F :
/* End */
rec = last;
break;
case 0x49 :
/* PgUp */
if ( first->bp != NULL )
{
rec = first->bp;
while (rec->bp != NULL)
{
rec = rec->bp;
if (rec->n)
break;
}
GetFilePage( fname );
prev = rec = first;
}
break;
case 0x51 :
/* PgDn */
if ( last->fp != NULL )
{
rec = last->fp;
GetFilePage( fname );
prev = rec = first;
}
break;
}
}
/* Release allocated memory */
prev = begin;
do
{
rec = prev;
prev = rec->fp;
free(rec);
}
while (prev->fp != NULL);
return(RetCode);
}
void GetFilePage( char *fname )
{
clrscr();
cprintf( "%s", fname );
first = rec;
while ( rec != NULL)
{
gotoxy(rec->p, rec->l);
cprintf( " %s", rec->fn
);
last = rec;
if (rec->n)
break;
rec = rec->fp;
}
}
/******************************* Debug Menu ******************************/
#ifdef DEBUG
void DebugMenu( void )
{
unsigned uptr = PC, rptr = PC, eptr = PC, dptr =
PC, qptr = PC;
long size = 0L, work;
unsigned i, j, k;
char c, line[80], reg[80], b;
int Loop = TRUE;
FILE *fp;
setvect(0x09, org);
Modes( 7 );
PCd = PC;
Op = MRead( PC );
DebugDisp();
do
{
cprintf("\r-");
line[0] = 78;
cgets(line);
sscanf(&line[2], "%c%x",
&c, &qptr);
switch (tolower(c))
{
case 't' :
PCd = PC;
Step = TRUE;
Loop = FALSE;
break;
case 'q' :
PCd = PC;
Step = FALSE;
Loop = FALSE;
Stop = TRUE;
break;
case 'f' :
if (line[1] > 1)
PC = qptr;
DebugSet = FALSE;
Loop = FALSE;
break;
case 'd' :
if (line[1] > 1)
dptr = qptr;
cprintf("\r\n");
for (i = 0; i < 8; i++)
{
reg[0] = '|';
for (j = 0; j < 16; j++)
{
if (j == 0)
cprintf("%04X: ", (unsigned) dptr + (i << 4) + j);
if (j == 8)
cprintf("- ");
k = MRead( (unsigned) dptr + ((i << 4) + j) );
cprintf("%02X ", (k & 0xFF));
if (k < ' ' || k > '~')
k = '.';
reg[j + 1] = k;
}
reg[j + 1] = '|';
reg[j + 2] = '\0';
cprintf("%s\r\n", reg);
}
dptr += 0x80;
cprintf("\r\n");
break;
case 'e' :
if (line[1] > 1)
eptr = qptr;
cprintf("\r\n");
if (eptr % 0x08)
{
cprintf("%04X:", eptr);
for (j = 0; j < eptr % 8; j++)
printf(" ");
}
do
{
if (!(eptr % 0x08))
cprintf("\r\n%04X:", eptr);
cprintf(" %02X.", MRead( eptr ));
for (j = 0; j < 3;)
{
c = toupper(getch());
if (((c >= '0' && c <= '9') || (c >= 'A' && c <=
'F')) && j < 2)
{
line[j++] = c;
putchar(c);
}
if (c == '\b' && j > 0)
{
j--;
cprintf("\b \b");
}
if (c == '\r' || c == ' ')
{
if (j == 0)
cprintf(" ");
if (j == 1)
putchar(' ');
break;
}
if (c == '\r')
{
break;
}
}
if (j > 0)
{
line[j] = '\0';
sscanf(line, "%x", &i);
MWrite( eptr, i & 0xFF);
}
eptr++;
}
while (c != '\r');
cprintf("\r\n");
cprintf("\r\n");
break;
case 'u' :
if (line[1] > 1)
uptr = qptr;
cprintf("\r\n");
for (i = 0; i < 8; i++)
{
j = MRead( uptr++ );
cprintf("%04X: %02X", uptr - 1, j);
if (Code[j].length == 1)
{
k = MRead( uptr );
cprintf(" %02X", k);
}
else if (Code[j].length == 2)
{
k = MRead( uptr ) + (MRead( uptr + 1 ) << 8);
cprintf(" %04X", ((MRead( uptr )) << 8) + MRead( uptr + 1 ));
}
else
cprintf(" ");
cprintf(" -> ");
cprintf(Code[j].asmx, k);
if (Code[j].flag == 1)
printf(" -> #%04X", (k < 128) ? (uptr + 1 + k) : ((uptr + 1) - (0x100
- k)));
cprintf("\r\n");
uptr += Code[j].length;
}
cprintf("\r\n");
break;
case 'r' :
cprintf("\r\n");
reg[0] = '\0';
sscanf(&line[2], "%c%s%x", &c, ®, &rptr);
strupr(reg);
if (!strcmp(reg, "X"))
{
X = rptr & 0xFF;
cprintf("X: %02X\r\n", X);
}
else if (!strcmp(reg, "Y"))
{
Y = rptr & 0xFF;
cprintf("Y: %02X\r\n", Y);
}
else if (!strcmp(reg, "A"))
{
A = rptr & 0xFF;
cprintf("A: %02X\r\n", A);
}
else if (!strcmp(reg, "P"))
{
P.P = rptr & 0xFF;
cprintf("P: %02X\r\n", P.P);
}
else if (!strcmp(reg, "PC"))
{
PC = rptr;
cprintf("PC: %04X\r\n", PC);
}
else if (!strcmp(reg, "SP"))
{
SP = rptr;
cprintf("SP: %04X\r\n", SP);
}
else
DebugDisp();
break;
case 's' :
if (Step)
Step = 0;
else
Step = 1;
Modes( 1 );
break;
case 'x' :
if (Debug)
Debug = 0;
else
Debug = 1;
Modes( 2 );
break;
case 'b' :
if (BreakDetect)
BreakDetect = 0;
else
BreakDetect = 1;
Modes( 4 );
break;
case '@' :
cprintf("\r\n");
sscanf(&line[2], "%c%u", &c, &qptr);
if (line[1] > 1)
Pause = qptr;
cprintf(">> Pause = %d milliseconds\r\n\r\n", Pause);
break;
case 'h' :
if (line[1] > 1)
xhalt = qptr;
else
cprintf("Halt at : %04X", xhalt);
cprintf("\r\n");
break;
case 'p' :
if (line[1] > 1)
MWrite( 0xBFFF, qptr & 0x07 );
else
cprintf(" Eprom selected : %d\n", MRead( 0xBFFF));
cprintf("\r\n");
break;
case 'l' :
cprintf("\r\n");
b = 'b';
sscanf(&line[2], "%c %s %x %c", &c, reg, &qptr, &b);
if (line[1] > 1)
{
if (access(reg, 0) == 0)
if (tolower(b) == 'i')
HexRead( reg );
else
LoadProg( reg, qptr );
else
cprintf("File '%s' : ** Not found **\r\n", reg);
}
else
cprintf(">> No file <<\r\n");
cprintf("\r\n");
break;
case 'w' :
cprintf("\r\n");
qptr = 0;
work = 0L;
sscanf(&line[2], "%c %s %x %lx", &c, reg, &qptr, &work);
if (qptr == 0)
qptr = (MRead( 0x12 ) << 8);
if (work == 0L)
work = (long) (MRead( 0x0D ) + (MRead( 0x0E ) << 8)) - qptr;
if (line[1] > 1)
{
cprintf(">> Write to file '%s' : ", reg);
if ((fp = fopen(reg, "wb")) != NULL)
{
size = ((long) qptr + work > 65536L) ? 65536L - (long) qptr : work;
work = 0;
while (size-- > 0L)
{
k = MRead( qptr++ );
putc( k, fp);
work++;
}
fclose(fp);
cprintf("Saved %ld bytes\r\n", work);
}
else
cprintf("** Open error **\r\n");
}
else
cprintf(">> No file <<\r\n");
cprintf("\r\n");
break;
case 'c' :
Continue = 1;
Loop = FALSE;
break;
case 'g' :
clrscr();
if (line[1] > 1)
PC = qptr;
gotoxy( 1, 25);
Continue = 0;
Loop = FALSE;
break;
case '?' :
cprintf("\r\n6502 Emulator in Maintenance mode\r\n");
cprintf(" r [PC|SP|A|X|Y|P] <val> load register\r\n");
cprintf(" d [<addr>]
display memory\r\n");
cprintf(" u [<addr>]
unassemble\r\n");
cprintf(" e [<addr>]
edit address contents\r\n");
cprintf(" p [<nmbr>]
eProm selection\r\n");
cprintf(" l <file> [<addr>] [i|b] load file into memory\r\n");
cprintf(" w <file> [<addr>] <size> write memory to file\r\n");
cprintf(" h [<addr>]
halt at address\r\n");
cprintf(" s
step mode on/off\r\n");
cprintf(" x
xray (debug) mode on/off\r\n");
cprintf(" b
breakdetect on/off\r\n");
cprintf(" t
trace\r\n");
cprintf(" c
continue after BRK stop\r\n");
cprintf(" @ <msec>
pause between steps\r\n");
cprintf(" g <[addr]>
goto run mode (at addr)\r\n");
cprintf(" f <[addr]>
fast (?) run (at addr)\r\n");
cprintf("\r\n");
Modes( 7 );
break;
}
}
while (Loop == TRUE);
setvect(0x09, kbint);
cb = 0x00;
}
#endif