📄 inst.cc
字号:
/* * Simulator of microcontrollers (inst.cc) * * some z80 code base from Karl Bongers karl@turbobit.com * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * *//* This file is part of microcontroller simulator: ucsim.UCSIM is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.UCSIM is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with UCSIM; see the file COPYING. If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA. *//*@1@*/#include "ddconfig.h"#include <stdlib.h>// local#include "z80cl.h"#include "regsz80.h"#include "z80mac.h"/* * No Instruction * NOP * 0000 0000 0000 0000 *---------------------------------------------------------------------------- */intcl_z80::inst_nop(t_mem code){ return(resGO);}/* * Load Instruction * LD * *---------------------------------------------------------------------------- */intcl_z80::inst_ld(t_mem code){ switch(code) { case 1: // LD BC,nnnn regs.BC = fetch2(); break; case 2: // LD (BC),A store1(regs.BC, regs.A); break; case 6: // LD B,nn regs.bc.h = fetch(); break; case 0xa: // LD A,(BC) regs.A = get1(regs.BC); break; case 0x0e: // LD C,nn regs.bc.l = fetch(); break; case 0x11: // LD DE,nnnn regs.DE = fetch2(); break; case 0x12: // LD (DE),A store1(regs.DE, regs.A); break; case 0x16: // LD D,nn regs.de.h = fetch(); break; case 0x1A: // LD A,(DE) regs.A = get1(regs.DE); break; case 0x1E: // LD E,nn regs.de.l = fetch(); break; case 0x21: // LD HL,nnnn regs.HL = fetch2(); break; case 0x22: // LD (nnnn),HL { unsigned short tw; tw = fetch2(); store2(tw, regs.HL); } break; case 0x26: // LD H,nn regs.hl.h = fetch(); break; case 0x2A: // LD HL,(nnnn) { unsigned short tw; tw = fetch2(); regs.HL = get2(tw); } break; case 0x2E: // LD L,nn regs.hl.l = fetch(); break; case 0x31: // LD SP,nnnn regs.SP = fetch2(); break; case 0x32: // LD (nnnn),A { unsigned short tw; tw = fetch2(); store1(tw, regs.A); } break; case 0x36: // LD (HL),nn store1(regs.HL, fetch()); break; case 0x3A: // LD A,(nnnn) regs.A = get1(fetch2()); break; case 0x3E: // LD A,nn regs.A = fetch(); break; case 0x40: // LD B,B break; case 0x41: // LD B,C regs.bc.h = regs.bc.l; break; case 0x42: // LD B,D regs.bc.h = regs.de.h; break; case 0x43: // LD B,E regs.bc.h = regs.de.l; break; case 0x44: // LD B,H regs.bc.h = regs.hl.h; break; case 0x45: // LD B,L regs.bc.h = regs.hl.l; break; case 0x46: // LD B,(HL) regs.bc.h = get1(regs.HL); break; case 0x47: // LD B,A regs.bc.h = regs.A; break; case 0x48: // LD C,B regs.bc.l = regs.bc.h; break; case 0x49: // LD C,C break; case 0x4A: // LD C,D regs.bc.l = regs.de.h; break; case 0x4B: // LD C,E regs.bc.l = regs.de.l; break; case 0x4C: // LD C,H regs.bc.l = regs.hl.h; break; case 0x4D: // LD C,L regs.bc.l = regs.hl.l; break; case 0x4E: // LD C,(HL) regs.bc.l = get1(regs.HL); break; case 0x4F: // LD C,A regs.bc.l = regs.A; break; case 0x50: // LD D,B regs.de.h = regs.bc.h; break; case 0x51: // LD D,C regs.de.h = regs.bc.l; break; case 0x52: // LD D,D break; case 0x53: // LD D,E regs.de.h = regs.de.l; break; case 0x54: // LD D,H regs.de.h = regs.hl.h; break; case 0x55: // LD D,L regs.de.h = regs.hl.l; break; case 0x56: // LD D,(HL) regs.de.h = get1(regs.HL); break; case 0x57: // LD D,A regs.de.h = regs.A; break; case 0x58: // LD E,B regs.de.l = regs.bc.h; break; case 0x59: // LD E,C regs.de.l = regs.bc.l; break; case 0x5A: // LD E,D regs.de.l = regs.de.h; break; case 0x5B: // LD E,E break; case 0x5C: // LD E,H regs.de.l = regs.hl.h; break; case 0x5D: // LD E,L regs.de.l = regs.hl.l; break; case 0x5E: // LD E,(HL) regs.de.l = get1(regs.HL); break; case 0x5F: // LD E,A regs.de.l = regs.A; break; case 0x60: // LD H,B regs.hl.h = regs.bc.h; break; case 0x61: // LD H,C regs.hl.h = regs.bc.l; break; case 0x62: // LD H,D regs.hl.h = regs.de.h; break; case 0x63: // LD H,E regs.hl.h = regs.de.l; break; case 0x64: // LD H,H regs.hl.h = regs.hl.h; break; case 0x65: // LD H,L regs.hl.h = regs.hl.l; break; case 0x66: // LD H,(HL) regs.hl.h = get1(regs.HL); break; case 0x67: // LD H,A regs.hl.h = regs.A; break; case 0x68: // LD L,B regs.hl.l = regs.bc.h; break; case 0x69: // LD L,C regs.hl.l = regs.bc.l; break; case 0x6A: // LD L,D regs.hl.l = regs.de.h; break; case 0x6B: // LD L,E regs.hl.l = regs.de.l; break; case 0x6C: // LD L,H regs.hl.l = regs.hl.h; break; case 0x6D: // LD L,L break; case 0x6E: // LD L,(HL) regs.hl.l = get1(regs.HL); break; case 0x6F: // LD L,A regs.hl.l = regs.A; break; case 0x70: // LD (HL),B store1(regs.HL, regs.bc.h); break; case 0x71: // LD (HL),C store1(regs.HL, regs.bc.l); break; case 0x72: // LD (HL),D store1(regs.HL, regs.de.h); break; case 0x73: // LD (HL),E store1(regs.HL, regs.de.l); break; case 0x74: // LD (HL),H store1(regs.HL, regs.hl.h); break; case 0x75: // LD (HL),L store1(regs.HL, regs.hl.l); break; case 0x76: // HALT return(resHALT); case 0x77: // LD (HL),A store1(regs.HL, regs.A); break; case 0x78: // LD A,B regs.A = regs.bc.h; break; case 0x79: // LD A,C regs.A = regs.bc.l; break; case 0x7A: // LD A,D regs.A = regs.de.h; break; case 0x7B: // LD A,E regs.A = regs.de.l; break; case 0x7C: // LD A,H regs.A = regs.hl.h; break; case 0x7D: // LD A,L regs.A = regs.hl.l; break; case 0x7E: // LD A,(HL) regs.A = get1(regs.HL); break; case 0x7F: // LD A,A break; case 0xF9: // LD SP,HL regs.SP = regs.HL; break; default: return(resINV_INST); break; } return(resGO);}intcl_z80::inst_inc(t_mem code){ switch(code) { case 0x03: // INC BC ++regs.BC; break; case 0x04: // INC B inc(regs.bc.h); break; case 0x0C: // INC C inc(regs.bc.l); break; case 0x13: // INC DE ++regs.DE; break; case 0x14: // INC D inc(regs.de.h); break; case 0x1C: // INC E inc(regs.de.l); break; case 0x23: // INC HL ++regs.HL; break; case 0x24: // INC H inc(regs.hl.h); break; case 0x2C: // INC L inc(regs.hl.l); break; case 0x33: // INC SP ++regs.SP; break; case 0x34: // INC (HL) {unsigned char t=get1(regs.HL); inc(t); store1(regs.HL, t); } break; case 0x3C: // INC A inc(regs.A); break; default: return(resINV_INST); break; } return(resGO);}intcl_z80::inst_dec(t_mem code){ switch(code) { case 0x05: // DEC B dec(regs.bc.h); break; case 0x0B: // DEC BC --regs.BC; break; case 0x0D: // DEC C dec(regs.bc.l); break; case 0x15: // DEC D dec(regs.de.h); break; case 0x1B: // DEC DE --regs.DE; break; case 0x1D: // DEC E dec(regs.de.l); break; case 0x25: // DEC H dec(regs.hl.h); break; case 0x2B: // DEC HL --regs.HL; break; case 0x2D: // DEC L dec(regs.hl.l); break; case 0x35: // DEC (HL) {unsigned char t=get1(regs.HL); dec(t); store1(regs.HL, t); } break; case 0x3B: // DEC SP --regs.SP; break; case 0x3D: // DEC A dec(regs.A); break; default: return(resINV_INST); break; } return(resGO);}intcl_z80::inst_rlca(t_mem code){ rlc_byte(regs.A); return(resGO);}intcl_z80::inst_rrca(t_mem code){ rrc_byte(regs.A); return(resGO);}intcl_z80::inst_ex(t_mem code){ /* 0x08 // EX AF,AF' */ unsigned char tmp; TYPE_UWORD tempw; switch (code) { case 0x08: // EX AF,AF' tmp = regs.aA; regs.aA = regs.A; regs.A = tmp; tmp = regs.aF; regs.aF = regs.F; regs.F = tmp; break; case 0xE3: // EX (SP),HL tempw = regs.HL; regs.HL = get2(regs.SP); store2(regs.SP, tempw); break; case 0xEB: // EX DE,HL tempw = regs.DE; regs.DE = regs.HL; regs.HL = tempw; break; default: return(resINV_INST); break; } return(resGO);}intcl_z80::inst_add(t_mem code){#define add_HL_Word(wr) { \ unsigned int tmp; \ regs.F &= ~(BIT_ALL); /* clear these */ \ tmp = (unsigned int)regs.HL + (unsigned int)(wr); \ if (tmp > 0xffff) regs.F |= BIT_C; \ regs.HL = (unsigned short) tmp; } switch(code) { case 0x09: // ADD HL,BC add_HL_Word(regs.BC); break; case 0x19: // ADD HL,DE add_HL_Word(regs.DE); break; case 0x29: // ADD HL,HL add_HL_Word(regs.HL); break; case 0x39: // ADD HL,SP add_HL_Word(regs.SP); break; case 0x80: // ADD A,B add_A_bytereg(regs.bc.h); break; case 0x81: // ADD A,C add_A_bytereg(regs.bc.l); break; case 0x82: // ADD A,D add_A_bytereg(regs.de.h); break; case 0x83: // ADD A,E add_A_bytereg(regs.de.l); break; case 0x84: // ADD A,H add_A_bytereg(regs.hl.h); break; case 0x85: // ADD A,L add_A_bytereg(regs.hl.l); break; case 0x86: // ADD A,(HL) { unsigned char utmp; utmp = get1(regs.HL); add_A_bytereg(utmp); } break; case 0x87: // ADD A,A add_A_bytereg(regs.A); break; case 0xC6: // ADD A,nn { unsigned char utmp1; utmp1 = fetch(); add_A_bytereg(utmp1); } break; default: return(resINV_INST); break; } return(resGO);}intcl_z80::inst_djnz(t_mem code){ signed char j; // 0x10: DJNZ dd j = fetch1(); if ((--regs.bc.h != 0)) { PC += j; } else { } return(resGO);}intcl_z80::inst_rra(t_mem code){ rr_byte(regs.A); return(resGO);}intcl_z80::inst_rla(t_mem code){ rl_byte(regs.A); return(resGO);}intcl_z80::inst_jr(t_mem code){ signed char j; j = fetch1(); switch(code) { case 0x18: // JR dd PC += j; break; case 0x20: // JR NZ,dd if (!(regs.F & BIT_Z)) { PC += j; } break; case 0x28: // JR Z,dd if ((regs.F & BIT_Z)) { PC += j; } break; case 0x30: // JR NC,dd if (!(regs.F & BIT_C)) { PC += j; } break; case 0x38: // JR C,dd if ((regs.F & BIT_C)) { PC += j; } break; default: return(resINV_INST); break; } return(resGO);}intcl_z80::inst_daa(t_mem code){ /************* from MH's z80ops.c: unsigned char incr=0, carry=cy; if((f&0x10) || (a&0x0f)>9) incr=6; if((f&1) || (a>>4)>9) incr|=0x60; if(f&2)suba(incr,0); else { if(a>0x90 && (a&15)>9)incr|=0x60; adda(incr,0); } f=((f|carry)&0xfb); ********/ /* I have not tried to understand this archaic bit of BCD logic(kpb), taking the lazy way out for now and just transcribing MH's code. */ unsigned char incr; if ((regs.F & BIT_A) || ((regs.A & 0x0f) > 9)) incr = 6; else incr = 0; if ((regs.F & BIT_C) || ((regs.A & 0xf0) > 0x90)) incr |= 0x60; if (regs.F & BIT_N) { /* not addition */ sub_A_bytereg(incr); } else { if ((regs.A > 0x90) && ((regs.A & 0x0f) >9)) incr |= 0x60; add_A_bytereg(incr); } return(resGO);}intcl_z80::inst_cpl(t_mem code){ regs.F |= (BIT_A | BIT_N); regs.A = ~regs.A; return(resGO);}intcl_z80::inst_scf(t_mem code){ /* Set Carry Flag */ regs.F |= BIT_C; return(resGO);}intcl_z80::inst_ccf(t_mem code){ /* Compliment Carry Flag */ regs.F ^= BIT_C; return(resGO);}intcl_z80::inst_halt(t_mem code)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -