terug.gif

#include <stdio.h>
#include <io.h>
#include <ctype.h>
#include <string.h>
#include <conio.h>
#include <bios.h>
#include <dos.h>
#include <alloc.h>
#include <stdlib.h>
#include <dir.h>

#include "proto9.h"
#include "R65C02_9.h"
#include "kb8us.h"
#include "grafix2.h"

enum
{
    READ = 0,
    WRITE,
    FALSE = 0,
    TRUE,
    IRQ = 0,
    NMI
};

int Step = FALSE;
int Debug = FALSE;
int DebugSet = FALSE;
int First = TRUE;
int Stop = FALSE;
int Continue = FALSE;
int BreakDetect = FALSE;
char Db_txt[40] = "";
unsigned Pause = 0;
unsigned xhalt = 0xffff;
union REGS rg;
unsigned char kb_bf[32];
unsigned char kbsz = sizeof(kb_bf), kbp1 = 0, kbp2 = 0;

union REGS regs;

FILE *f_out;
int dflag = 0;
FILE *printer;
int pflag = 0;
int RunMode = 0;        /* Progress Display */
char pn[64] = "";       /* Printer Name */
char dn[64] = "";       /* Debug Output File Name */
int VideoMode = 0;      /* 0x00 - 0x0F : Atom video mode */
int CrtOutput = FALSE;  /* FALSE = Atom Crt, TRUE = 80 Colom Crt  */
unsigned AltBoot = 0xFF3F;  /* Alternate Boot Address */
int FKey = FALSE;       /* Function key flag for fast mode */

FILE *fd = NULL;
FILE *fd0 = NULL;
FILE *fd1 = NULL;
int nmi_set = 0;
int nmi_cnt = 20;
char atom_dsk0[64];

int ca, cb = 0x00, ck, Shift = 0x00, SFlag = 0, Control = 0xFF;

char save[4096], crt80[4096], af_name[66];

struct kb_flags
{
    unsigned kf01 : 1; /* shift right down  */
    unsigned kf02 : 1; /* shift left  down  */
    unsigned kf03 : 1; /* control     down  */
    unsigned kf04 : 1; /* alt         down  */
    unsigned kf05 : 1; /* scroll lock state */
    unsigned kf06 : 1; /* num lock    state */
    unsigned kf07 : 1; /* caps lock   state */
    unsigned kf08 : 1; /* ins         state */
    unsigned kf09 : 1; /* control     down  */
    unsigned kf10 : 1; /* alt         down  */
    unsigned kf11 : 1; /* sys_req     down  */
    unsigned kf12 : 1; /* not used          */
    unsigned kf13 : 1; /* scroll lock down  */
    unsigned kf14 : 1; /* num lock    down  */
    unsigned kf15 : 1; /* caps lock   down  */
    unsigned kf16 : 1; /* ins         down  */
} far *kb = MK_FP(0x0000, 0x0417);

unsigned char far *crt_row = MK_FP(0x0040, 0x0050);
unsigned char far *crt_col = MK_FP(0x0040, 0x0051);

unsigned char crt_row8, crt_col8;
unsigned crta32 = 0xFE52, crta80;

/******************************************************/

void interrupt (*org)();

void interrupt kbint()
{
    static int c;

    c = inportb(0x60);
    ck = inportb(0x61);
    outportb(0x61, ck | 0x80);
    outportb(0x61, ck);

    switch(c)
    {
        case 0x4B :         /* Arrow Left */
            kb->kf02 = 1;
            cb = c;
            break;
        case 0xCB :
            kb->kf02 = 0;
            cb = 0;
            break;
        case 0x50 :         /* Arrow Down */
            kb->kf02 = 1;
            cb = c;
            break;
        case 0xD0 :
            kb->kf02 = 0;
            cb = 0;
            break;
        case 0x2A :         /* Shift Left */
            kb->kf02 = 1;
            SFlag = 1;
            break;
        case 0xAA :
            kb->kf02 = 0;
            SFlag = 0;
            break;
        case 0x36 :         /* Shift Right */
            kb->kf01 = 1;
            SFlag = 1;
            break;
        case 0xB6 :
            kb->kf01 = 0;
            SFlag = 0;
            break;
        case 0x38 :         /* Alt */
            kb->kf04 = 1;
            MWB00T( 0xB002, MRead( 0xB002 ) & 0xBF );
            break;
        case 0xB8 :
            kb->kf04 = 0;
            MWB00T( 0xB002, MRead( 0xB002 ) | 0x40 );
            break;

//        case 0x3A :         /* Caps Lock */
//            kb->kf15 = 1;
//            break;
//        case 0xBA :
//            kb->kf07 = !kb->kf07;
//            kb->kf15 = 0;
//            break;
//        case 0x45 :         /* Num Lock */
//            kb->kf14 = 1;
//            break;
//        case 0xC5 :
//            kb->kf06 = !kb->kf06;
//            kb->kf14 = 0;
//            break;

        case 0x1D :         /* Control */
            kb->kf03 = 1;
            kb->kf09 = 1;
            Control = 0xBF;
            break;
        case 0x9D :
            kb->kf03 = 0;
            kb->kf09 = 0;
            Control = 0xFF;
            break;
        case 0xE0 :         /* Enhanced Kb Code */
            break;
        default:
            if (c < 0x80)
            {
                if (c > 0x3A && c < 0x45)  /* F1 = 0x3B ... F10 = 0x44 */
                    FKey = TRUE;
                else
                    FKey = FALSE;
                cb = c;
            }
            else
                cb = 0x00;
            break;
    }

    outportb(0x20, 0x20);
}

/********************************************************/

void main( int argc, char **argv )
{
    char fn[64];
    int c, ini = 0, r;
    char b;
    unsigned la = 0x2900;  /* Default Load Address */

    clrscr();
    fprintf(stderr, "

Acorn Atom Emulator version 0.9
with R65C02 Processor

ACORN
ATOM
>

(c) Dick Bronsdijk
Graphics (c) Roland Leurs

ACORN
ATOM
>
\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, &regs, &regs);
        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, &regs, &regs);
 */
        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, &reg, &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
 

terug.gif