Пример #1
0
        protected override bool ExecutePatch()
        {
            if (base.PC == 0xFFD2) // CHROUT
            {
                CBM_Console.WriteChar((char)A);
                // fall through to draw character in screen memory too
            }
            else if (base.PC == 0xFFCF) // CHRIN
            {
                A = CBM_Console.ReadChar();

                // SetA equivalent for flags
                Z = (A == 0);
                N = ((A & 0x80) != 0);
                C = false;

                // RTS equivalent
                byte lo = base.Pop();
                byte hi = base.Pop();
                base.PC = (ushort)(((hi << 8) | lo) + 1);

                return(true); // overriden, so don't execute
            }
            return(false);    // execute normally
        }
Пример #2
0
        protected override bool ExecutePatch()
        {
            if (base.PC == (ushort)(memory[0xFFFC] | (memory[0xFFFD] << 8)))
            {
                CBM_Console.WriteChar((char)147, true); // PET 2001 doesn't initialize screen with chr$(147), so must do it here, supressing next home
            }
            else if (base.PC == 0xFFD2)                 // CHROUT
            {
                CBM_Console.WriteChar((char)A);
                // fall through to draw character in screen memory too
            }
            else if (base.PC == 0xFFCF) // CHRIN
            {
                A = CBM_Console.ReadChar();

                // SetA equivalent for flags
                Z = (A == 0);
                N = ((A & 0x80) != 0);
                C = false;

                // RTS equivalent
                byte lo = base.Pop();
                byte hi = base.Pop();
                base.PC = (ushort)(((hi << 8) | lo) + 1);

                return(true); // overriden, so don't execute
            }
            return(false);    // execute normally
        }
Пример #3
0
        protected override bool ExecutePatch()
        {
            if (PC == 0xFFD2) // CHROUT
            {
                CBM_Console.WriteChar((char)A);
                // fall through to draw character in screen memory too
            }
            else if (PC == 0xFFCF) // CHRIN
            {
                A = CBM_Console.ReadChar();

                // SetA equivalent for flags
                Z = (A == 0);
                N = ((A & 0x80) != 0);
                C = false;

                // RTS equivalent
                byte lo = Pop();
                byte hi = Pop();
                PC = (ushort)(((hi << 8) | lo) + 1);

                return(true);                         // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
            }
            else if (PC == 0xA474 || PC == LOAD_TRAP) // READY
            {
                if (StartupPRG != null)               // User requested program be loaded at startup
                {
                    bool is_basic;
                    if (PC == LOAD_TRAP)
                    {
                        is_basic = (
                            FileVerify == false &&
                            FileSec == 0 && // relative load, not absolute
                            LO(FileAddr) == memory[43] && // requested load address matches BASIC start
                            HI(FileAddr) == memory[44]);
                        byte err;
                        if (!FileLoad(out err))
                        {
                            System.Diagnostics.Debug.WriteLine(string.Format("FileLoad() failed: err={0}, file {1}", err, StartupPRG));
                            C = true; // signal error
                            A = err;  // FILE NOT FOUND or VERIFY

                            // so doesn't repeat
                            StartupPRG = null;
                            LOAD_TRAP  = -1;

                            return(true); // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
                        }
                    }
                    else
                    {
                        is_basic = ((C64Memory)memory).LoadStartupPrg(StartupPRG, out FileAddr);
                    }

                    StartupPRG = null;

                    if (is_basic)
                    {
                        //UNNEW that I used in late 1980s, should work well for loading a program too, probably gleaned from BASIC ROM
                        //listed here as reference, adapted to use in this state machine, ExecutePatch()
                        //ldy #0
                        //lda #1
                        //sta(43),y
                        //iny
                        //sta(43),y
                        //jsr $a533 ; LINKPRG
                        //clc
                        //lda $22
                        //adc #2
                        //sta 45
                        //lda $23
                        //adc #0
                        //sta 46
                        //lda #0
                        //jsr $a65e ; CLEAR/CLR
                        //jmp $a474 ; READY

                        // initialize first couple bytes (may only be necessary for UNNEW?)
                        ushort addr = (ushort)(memory[43] | (memory[44] << 8));
                        memory[addr] = 1;
                        memory[(ushort)(addr + 1)] = 1;

                        // JSR equivalent
                        ushort retaddr = (ushort)(PC - 1);
                        Push(HI(retaddr));
                        Push(LO(retaddr));
                        PC = 0xA533;       // LINKPRG

                        startup_state = 1; // should be able to regain control when returns...

                        return(true);      // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
                    }
                    else
                    {
                        LOAD_TRAP = -1;
                        X         = LO(FileAddr);
                        Y         = HI(FileAddr);
                        C         = false;
                    }
                }
                else if (startup_state == 1)
                {
                    ushort addr = (ushort)(memory[0x22] | (memory[0x23] << 8) + 2);
                    memory[45] = (byte)addr;
                    memory[46] = (byte)(addr >> 8);

                    // JSR equivalent
                    ushort retaddr = (ushort)(PC - 1);
                    Push(HI(retaddr));
                    Push(LO(retaddr));
                    PC = 0xA65E; // CLEAR/CLR
                    A  = 0;

                    startup_state = 2; // should be able to regain control when returns...

                    return(true);      // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
                }
                else if (startup_state == 2)
                {
                    if (PC == LOAD_TRAP)
                    {
                        X = LO(FileAddr);
                        Y = HI(FileAddr);
                    }
                    else
                    {
                        CBM_Console.Push("RUN\r");
                        PC = 0xA47B;       // skip READY message, but still set direct mode, and continue to MAIN
                    }
                    C             = false; // signal success
                    startup_state = 0;
                    LOAD_TRAP     = -1;
                    return(true); // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
                }
            }
            else if (PC == 0xF13E) // GETIN
            {
                //BASIC TEST:
                //10 GET K$ : REM GETIN
                //20 IF K$<> "" THEN PRINT ASC(K$)
                //25 IF K$= "Q" THEN END
                //30 GOTO 10

                A = CBM_Console.GetIn();
                if (A == 0)
                {
                    Z = true;
                    C = false;
                }
                else
                {
                    X = A;
                    Z = false;
                    C = false;
                }

                // RTS equivalent
                byte lo = Pop();
                byte hi = Pop();
                PC = (ushort)(((hi << 8) | lo) + 1);

                return(true);      // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
            }
            else if (PC == 0xF6ED) // STOP
            {
                Z = CBM_Console.CheckStop();

                // RTS equivalent
                byte lo = Pop();
                byte hi = Pop();
                PC = (ushort)(((hi << 8) | lo) + 1);

                return(true);      // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
            }
            else if (PC == 0xFE00) // SETLFS
            {
                FileNum = A;
                FileDev = X;
                FileSec = Y;
                System.Diagnostics.Debug.WriteLine(string.Format("SETLFS {0},{1},{2}", FileNum, FileDev, FileSec));
            }
            else if (PC == 0xFDF9) // SETNAM
            {
                StringBuilder name = new StringBuilder();
                ushort        addr = (ushort)(X + (Y << 8));
                for (int i = 0; i < A; ++i)
                {
                    name.Append((char)memory[(ushort)(addr + i)]);
                }
                System.Diagnostics.Debug.WriteLine(string.Format("SETNAM {0}", name.ToString()));
                FileName = name.ToString();
            }
            else if (PC == 0xF49E) // LOAD
            {
                FileAddr = (ushort)(X + (Y << 8));
                string op;
                if (A == 0)
                {
                    op = "LOAD";
                }
                else if (A == 1)
                {
                    op = "VERIFY";
                }
                else
                {
                    op = string.Format("LOAD (A={0}) ???", A);
                }
                FileVerify = (A == 1);
                System.Diagnostics.Debug.WriteLine(string.Format("{0} @{1:X4}", op, FileAddr));

                // RTS equivalent
                byte lo = Pop();
                byte hi = Pop();
                PC = (ushort)(((hi << 8) | lo) + 1);

                if (A == 0 || A == 1)
                {
                    StartupPRG = FileName;
                    FileName   = null;
                    LOAD_TRAP  = PC;

                    // Set success
                    C = false;
                }
                else
                {
                    A = 14;   // ILLEGAL QUANTITY message
                    C = true; // failure
                }

                return(true);      // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
            }
            else if (PC == 0xF5DD) // SAVE
            {
                ushort addr1 = (ushort)(memory[A] + (memory[(ushort)(A + 1)] << 8));
                ushort addr2 = (ushort)(X + (Y << 8));
                System.Diagnostics.Debug.WriteLine(string.Format("SAVE {0:X4}-{1:X4}", addr1, addr2));

                // RTS equivalent
                byte lo = Pop();
                byte hi = Pop();
                PC = (ushort)(((hi << 8) | lo) + 1);

                // Set success
                C = !FileSave(FileName, addr1, addr2);

                return(true); // overriden, and PC changed, so caller should reloop before execution to allow breakpoint/trace/ExecutePatch/etc.
            }
            return(false);    // execute normally
        }