⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.pas

📁 delphi编制的nes模拟器--tNes
💻 PAS
📖 第 1 页 / 共 5 页
字号:
unit cpu;
//{$DEFINE debug}

interface
uses
    SysUtils;
type
	TPS = record
		nf: byte; //negative flag
		off: byte; //overflow flag
		uf:Byte;
		bf: byte; //break flag
		dm: byte; //decimal mode
		id: byte; //interrupt disable
		zf: byte; //zero flag
		cf: byte; //carry flag
	end;

    TCPU = class
        pc: word; //program counter
        sp: word; //stack pointer
        a: byte; //accumulator
        x: byte; //index register
        y: byte; //index register
        Ps: tps; //processor status
        run: boolean;
        toggle: boolean;
        curIns: string;
        CPU_Mem: array[0..$7FFF] of byte;
        memread: function(address: word): byte;
        memwrite: procedure(address: word; data: byte);
        function CpuRun(var cycles: integer): boolean;
        procedure Reset;
        procedure NMI(var cc: integer);
    private
        procedure pswtops(psw: byte);
        function psTopsw(): byte;
        procedure setnz(data: byte);
        procedure push(data: byte);
        function pop: byte;
        function pscombine: byte;
		procedure pssplit(p: byte);


		function ZpAddress(pos:Word):Word;
		function IzpAddress(Pos:Word;offset:Byte):Word; //index zero page;
		function AbAddress(Pos:Word):Word;//absolute
		function IABAddress(Pos:Word;offset:Byte):Word;//indexed absolute
		function IIXAddress(Pos:Word;x:Byte):Word;//indexed indirect   ($xx,X)
		function IIYAddress(Pos:Word;y:Byte):Word;// indirect indexed   ($xx),Y

    end;
implementation
var
    BrkVector: word;
    ResetVector: word;
    NMIVector: word;

{ TCPU }



function TCPU.CpuRun(var cycles: integer): boolean;
var
    tempbyte, inst: byte;
	psw, acc, xr, yr,tempflag: byte;
    offset: shortint;
    taddr: word;
begin
    psw := 0;
    inst := memread(pc);
    case inst of


  //*                                       *
  //*       adc instruction 2005/12/20      *
  //*---------------start-------------------*
        $69: //ADC - Add with Carry Immediate
            begin


                tempbyte := memread(pc + 1);
{$IFDEF debug}
                curIns := 'ADC #$' + intToHex(tempbyte, 0);
{$ENDIF}

                acc := a;
                psw := psTopsw;
                asm
					  mov ah,psw
					  sahf
					  mov al,acc
					  adc al,tempbyte
					  lahf
					  mov psw,ah
					  jno @quit
					  or  psw,$20
					@quit:
					  mov acc,al
                end;

                a := acc;
                pswtops(psw);

                Inc(pc, 2);
                inc(cycles, 2);
            end;

        $65: //ADC - Add with Carry Zero Page
            begin

				taddr:=ZpAddress(pc);

				tempbyte := memread(taddr); //zero page
{$IFDEF debug}
				curIns := 'ADC $' + intToHex(taddr, 0);
{$ENDIF}

                acc := a;
                psw := psTopsw;

                asm
					  mov ah,psw
					  sahf
					  mov al,acc
					  adc al,tempbyte
					  lahf
					  mov psw,ah
					  jno @quit
					  or  psw,$20
					@quit:
					  mov acc,al
                end;
                a := acc;
                pswtops(psw);

                inc(cycles, 3);
                inc(pc, 2);
            end;

		$75: //ADC - Add with Carry Zero Page,X
            begin

				tempbyte := memread(izpaddress(pc,x)); //Zero Page,X
{$IFDEF debug}
                curIns := 'ADC $' + intToHex(memread(pc + 1), 0) + ',X';
{$ENDIF}


                acc := a;
                psw := psTopsw;
                asm
					  mov ah,psw
					  sahf
					  mov al,acc
					  adc al,tempbyte
					  lahf
					  mov psw,ah
					  jno @quit
					  or  psw,$20
					@quit:
					  mov acc,al
                end;
                a := acc;
                pswtops(psw);

                inc(cycles, 4);
                inc(pc, 2);
            end;

        $6D: //ADC - Add with Carry absolute
            begin
				taddr:=AbAddress(pc);
				tempbyte := memread(taddr);

{$IFDEF debug}
                curIns := 'ADC $' + intToHex(taddr, 0);
{$ENDIF}

                acc := a;
                psw := psTopsw;
                asm
				  mov ah,psw
				  sahf
				  mov al,acc
				  adc al,tempbyte
				  lahf
				  mov psw,ah
				  jno @quit
				  or  psw,$20
				@quit:
				  mov acc,al
                end;
                a := acc;
                pswtops(psw);

                inc(pc, 3);
                inc(cycles, 4);
            end;

        $7D: //ADC - Add with Carry absolute,x
            begin
				taddr:=IABAddress(pc,x);

				tempbyte := memread(taddr);
{$IFDEF debug}
				curIns := 'ADC $' + intToHex(taddr-x, 0) + ',X';
{$ENDIF}
                acc := a;
                psw := psTopsw;
                asm
				  mov ah,psw
				  sahf
				  mov al,acc
				  adc al,tempbyte
				  lahf
				  mov psw,ah
				  jno @quit
				  or  psw,$20
				@quit:
				  mov acc,al
                end;
                a := acc;
                pswtops(psw);

                inc(cycles, 4);
                inc(pc, 3);
            end;


        $79: //ADC - Add with Carry absolute,y
            begin

				taddr:=IABAddress(pc,y);

				tempbyte := memread(taddr);
{$IFDEF debug}
                curIns := 'ADC $' + intToHex(taddr-y, 0) + ' ' + ',Y';
{$ENDIF}
                acc := a;
                psw := psTopsw;
                asm
				  mov ah,psw
				  sahf
				  mov al,acc
				  adc al,tempbyte
				  lahf
				  mov psw,ah
				  jno @quit
				  or  psw,$20
				@quit:
				  mov acc,al
                end;
                a := acc;
                pswtops(psw);

                inc(cycles, 4);
                inc(pc, 3);
            end;


		$61: //ADC - Add with Carry (Indirect,X)
            begin


				tempbyte := memread(iixaddress(pc,x));

{$IFDEF debug}
                curIns := 'ADC ($' + intToHex(memread(pc + 1), 0) + ',X)';
{$ENDIF}

                acc := a;
                psw := psTopsw;
                asm
          mov ah,psw
          sahf
          mov al,acc
          adc al,tempbyte
          lahf
          mov psw,ah
          jno @quit
          or  psw,$20
        @quit:
          mov acc,al
                end;
                a := acc;
                pswtops(psw);

                inc(cycles, 6);
                inc(pc, 2);
            end;


		$71: //ADC - Add with Carry (Indirect),Y
            begin
{$IFDEF debug}
                curIns := 'ADC ($' + intToHex(memread(pc + 1), 0) + '),Y ';
{$ENDIF}


				tempbyte := memread(iiyaddress(pc,y));;
                acc := a;
                psw := psTopsw;
                asm
          mov ah,psw
          sahf
          mov al,acc
          adc al,tempbyte
          lahf
          mov psw,ah
          jno @quit
          or  psw,$20
        @quit:
          mov acc,al
                end;
                a := acc;
                pswtops(psw);

                inc(cycles, 6);
                inc(pc, 2);
            end;

  //*                                       *
  //*       adc instruction 2005/12/20      *
  //*---------------end---------------------*


  //*                                       *
  //*       and instruction 2005/12/21      *
  //*---------------start-------------------*
        $29: //AND immediate
            begin



{$IFDEF debug}
                curIns := 'AND #$' + intToHex(memread(pc + 1), 0);
{$ENDIF}
                tempbyte := memread(pc + 1);
                a := a and tempbyte;
                setnz(a);

                inc(cycles, 2);
                inc(pc, 2);
            end;

        $25: //AND zero page
			begin

				taddr:=ZpAddress(pc);
{$IFDEF debug}
				curIns := 'AND $' + intToHex(taddr, 0);
{$ENDIF}

				tempbyte := memread(taddr);
                a := a and tempbyte;

                inc(cycles, 3);
				inc(pc, 2);

                setnz(a);
            end;

		$35: //AND zero page x
            begin
{$IFDEF debug}
                curIns := 'AND $' + intToHex(memread(pc + 1), 0) + ',X';
{$ENDIF}

				tempbyte := memread(izpaddress(pc,x));

                a := a and tempbyte;
                setnz(a);

                inc(cycles, 4);
                inc(pc, 2);
            end;

        $2D: //AND absolute
            begin


				taddr:=AbAddress(pc);
				tempbyte :=memread(taddr);

{$IFDEF debug}
                curIns := 'AND $' + intToHex(taddr, 0);
{$ENDIF}



                a := a and tempbyte;
                setnz(a);

                inc(cycles, 4);
                inc(pc, 3);
            end;

        $3D: //AND absolute x
            begin

				taddr:=IABAddress(pc,x);
				tempbyte := memread(taddr);

{$IFDEF debug}
				curIns := 'AND $' + intToHex(taddr-x, 0) + ',X';
{$ENDIF}


				a := a and tempbyte;
				setnz(a);

				inc(cycles, 4);
				inc(pc, 3);
			end;

		$39: //AND absolute y
			begin

				taddr:=IABAddress(pc,y);
				tempbyte := memread(taddr);

{$IFDEF debug}
				curIns := 'AND $' + intToHex(taddr-y, 0) + ',Y';
{$ENDIF}

                a := a and tempbyte;
                setnz(a);

                inc(cycles, 4);
                inc(pc, 3);

            end;

        $21: //AND (indirect.x)
            begin
{$IFDEF debug}
                curIns := 'AND ($' + intToHex(memread(pc + 1), 0) + ',X)';
{$ENDIF}


				tempbyte :=memread(iixaddress(pc,x));


                a := a and tempbyte;
                setnz(a);

                inc(cycles, 6);
                inc(pc, 2);
            end;

        $31: //AND (indirect).y
            begin
{$IFDEF debug}
                curIns := 'AND ($' + intToHex(memread(pc + 1), 0) + '),Y';
{$ENDIF}

				tempbyte := memread(IIYaddress(pc,y));


                a := a and tempbyte;
                setnz(a);

                inc(cycles, 5);
                inc(pc, 2);
            end;
  //*                                       *
  //*       and instruction 2005/12/21      *
  //*---------------end---------------------*


  //*                                       *
  //*       asl instruction 2005/12/21      *
  //*---------------start-------------------*
        $0A: //asl accumulator
            begin
{$IFDEF debug}
                curIns := 'ASL';
{$ENDIF}

                ps.cf := a and $80;
                ps.cf := ps.cf shr 7;
                acc := a;
                asm
          shl acc,1;
                end;
                a := acc;
                setnz(a);

                inc(cycles, 2);
                inc(pc);
            end;

        $06: //asl zero page
			begin

				taddr:=ZpAddress(pc);
				tempbyte:=memread(taddr);
{$IFDEF debug}
				curIns := 'ASL $ ' + intToHex(taddr, 0) + ' zp  ';
{$ENDIF}


                ps.cf := tempbyte and $80;
                ps.cf := ps.cf shr 7;
                asm
					shl tempbyte,1;
                end;

                setnz(tempbyte);
                memwrite(taddr, tempbyte);

                inc(cycles, 5);
                inc(pc, 2);
            end;

		$16: //asl zero page.x
			begin

				taddr:=IzpAddress(pc,x);
				tempbyte:=memread(taddr);
{$IFDEF debug}
				curIns := 'ASL $' + intToHex(memread(pc + 1), 0) + ',X';
{$ENDIF}

                ps.cf := tempbyte and $80;
                ps.cf := ps.cf shr 7;
				asm
					shl tempbyte,1;
                end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -