pic32 cp/m emulator source code

/******************************************************************************/
/* Files to Include */
/******************************************************************************/
#ifdef __XC32
#include /* Defines special funciton registers, CP0 regs */
#endif

#include /* Include to use PIC32 peripheral libraries */
#include /* For uint32_t definition */
#include /* For true/false definition */

#include “system.h” /* System funct/params, like osc/periph config */
#include “user.h” /* User funct/params, such as InitApp */

/******************************************************************************/
/* Global Variable Declaration */
/******************************************************************************/

#define regs_B 0
#define regs_C 1
#define regs_D 2
#define regs_E 3
#define regs_H 4
#define regs_L 5
#define regs_ACCU 7

unsigned char regs[8];
union _8080_sp
{
struct _8080_sp_hl
{
unsigned char h;
unsigned char l;
}hl8;
unsigned int hl16;
}sp_8080,pc_8080,offset_8080;

unsigned int pc,psw,offset;
unsigned char* prgmem;
unsigned char* prgmem_base;
unsigned char prg_opcode;

void f_op_NOP(){;}

void f_op_HLT(){;}

void f_op_DI(){;}

void f_op_EI(){;}

void f_op_OUT(){;}
void f_op_IN(){;}
void f_op_SPHL(){;}
void f_op_XTHL(){;}
void f_op_POP(){;}

void f_op_PUSH(){;}
void f_op_PCHL(){;}
void f_op_RST(){;}
void f_op_RCCC(){;}
void f_op_RET(){;}
void f_op_CCCC(){;}
void f_op_CALL(){;}
void f_op_JCCC(){;}
void f_op_JMP(){;}
void f_op_STC(){;}
void f_op_CMC(){;}
void f_op_CMA(){;}
void f_op_RAR(){;}
void f_op_RAL(){;}
void f_op_RRC(){;}
void f_op_RLC(){;}
void f_op_CPI(){;}
void f_op_CMP(){;}
void f_op_XRI(){;}
void f_op_XRA(){;}
void f_op_ORA(){;}
void f_op_ORI(){;}
void f_op_ANI(){;}
void f_op_ANA(){;}
void f_op_DAA(){;}
void f_op_DAD(){;}
void f_op_INX(){;}
void f_op_DCX(){;}
void f_op_INR(){;}
void f_op_DCR(){;}
void f_op_SBI(){;}
void f_op_SBB(){;}
void f_op_SUI(){;}
void f_op_SUB(){;}
void f_op_ACI(){;}
void f_op_ADC(){;}
void f_op_ADI(){;}
void f_op_ADD(){;}
void f_op_XCHG(){;}

void f_op_STAXB()
{
offset_8080.hl8.h=regs[regs_B];
offset_8080.hl8.l=regs[regs_C];
*(prgmem_base+offset_8080.hl16)=regs[regs_ACCU];
}

void f_op_STAXD()
{
offset_8080.hl8.h=regs[regs_D];
offset_8080.hl8.l=regs[regs_E];
*(prgmem_base+offset_8080.hl16)=regs[regs_ACCU];
}

void f_op_LDAXB()
{//Load indirect through BC
offset_8080.hl8.h=regs[regs_B];
offset_8080.hl8.l=regs[regs_C];
regs[regs_ACCU]=*(prgmem_base+offset_8080.hl16);
}

void f_op_LDAXD()
{//Load indirect through DE
offset_8080.hl8.h=regs[regs_D];
offset_8080.hl8.l=regs[regs_E];
regs[regs_ACCU]=*(prgmem_base+offset_8080.hl16);
}

void f_op_SHLD()
{// store H:L to memory
offset_8080.hl8.l=*prgmem++;offset_8080.hl8.h=*prgmem++;
*(prgmem_base+offset_8080.hl16)=regs[regs_L];
*(prgmem_base+offset_8080.hl16+1)=regs[regs_H];
pc+=3;
}

void f_op_LHLD()
// Load H:L from memory
{
offset_8080.hl8.l=*prgmem++;offset_8080.hl8.h=*prgmem++;
regs[regs_L]=*(prgmem_base+offset_8080.hl16);
regs[regs_H]=*(prgmem_base+offset_8080.hl16+1);
pc+=3;
}

void f_op_STA()
{// store Accumulator into memory
offset_8080.hl8.l=*prgmem++;
offset_8080.hl8.h=*prgmem++;
*(prgmem_base+offset)=regs[regs_ACCU];
pc+=3;
}

void f_op_LDA()
{// load Accumulator from memory
offset_8080.hl8.l=*prgmem++;
offset_8080.hl8.h=*prgmem++;
regs[regs_ACCU]=*(prgmem_base+offset_8080.hl16);
pc+=3;
}

void f_op_LXI_BC()
{
regs[regs_C]=*prgmem++;
regs[regs_B]=*prgmem++;
pc+=3;
}

void f_op_LXI_DE()
{
regs[regs_E]=*prgmem++;
regs[regs_D]=*prgmem++;
pc+=3;
}

void f_op_LXI_HL()
{
regs[regs_L]=*prgmem++;
regs[regs_H]=*prgmem++;
pc+=3;
}

void f_op_LXI_SP()
{
sp_8080.hl8.l=*prgmem++;
sp_8080.hl8.h=*prgmem++;
pc+=3;
}

void f_op_MVI()
{// move immediate to register
regs[(prg_opcode&0b00111000)>>3]=*prgmem++;
}

void f_op_MOV()
{// move register to register
regs[(prg_opcode&0b00111000)>>3]=regs[prg_opcode&0b00000111];
}

void (*opc_d[256])();

//void (*fparr[])(int, float) = {
/* initializers */
// };
/* then call one */

//fparr[5](1, 3.4);

//MOV D,S 01DDDSSS – Move register to register
#define i_op_MOV 0b01000000

//MVI D,# 00DDD110 db – Move immediate to register
#define i_op_MVI 0b00000110

//LXI RP,# 00RP0001 lb hb – Load register pair immediate
#define i_op_LXI 0b00000001

//LDA a 00111010 lb hb – Load A from memory
#define i_op_LDA 0b00111010

//STA a 00110010 lb hb – Store A to memory
#define i_op_STA 0b00110010

//LHLD a 00101010 lb hb – Load H:L from memory
#define i_op_LHLD 0b00101010

//SHLD a 00100010 lb hb – Store H:L to memory
#define i_op_SHLD 0b00100010

//LDAX RP 00RP1010 *1 – Load indirect through BC or DE
#define i_op_LDAXB 0b00001010
#define i_op_LDAXD 0b00011010

//STAX RP 00RP0010 *1 – Store indirect through BC or DE
#define i_op_STAXB 0b00000010
#define i_op_STAXD 0b00010010

//XCHG 11101011 – Exchange DE and HL content
#define i_op_XCHG 0b11101011

//ADD S 10000SSS ZSPCA Add register to A
#define i_op_ADD 0b10000000

//ADI # 11000110 db ZSCPA Add immediate to A
#define i_op_ADI 0b11000110

//ADC S 10001SSS ZSCPA Add register to A with carry
#define i_op_ADC 0b10001000

//ACI # 11001110 db ZSCPA Add immediate to A with carry
#define i_op_ACI 0b11001110

//SUB S 10010SSS ZSCPA Subtract register from A
#define i_op_SUB 0b10010000

//SUI # 11010110 db ZSCPA Subtract immediate from A
#define i_op_SUI 0b11010110

//SBB S 10011SSS ZSCPA Subtract register from A with borrow
#define i_op_SBB 0b10011000

//SBI # 11011110 db ZSCPA Subtract immediate from A with borrow
#define i_op_SBI 0b11011110

//INR D 00DDD100 ZSPA Increment register
#define i_op_INR 0b00000100

//DCR D 00DDD101 ZSPA Decrement register
#define i_op_DCR 0b00000101

//INX RP 00RP0011 – Increment register pair
#define i_op_INX 0b00000011

//DCX RP 00RP1011 – Decrement register pair
#define i_op_DCX 0b00001011

//DAD RP 00RP1001 C Add register pair to HL (16 bit add)
#define i_op_DAD 0b00001001

//DAA 00100111 ZSPCA Decimal Adjust accumulator
#define i_op_DAA 0b00100111

//ANA S 10100SSS ZSCPA AND register with A
#define i_op_ANA 0b10100000

//ANI # 11100110 db ZSPCA AND immediate with A
#define i_op_ANI 0b11100110

//ORA S 10110SSS ZSPCA OR register with A
#define i_op_ORA 0b10110000

//ORI # 11110110 ZSPCA OR immediate with A
#define i_op_ORI 0b11110110

//XRA S 10101SSS ZSPCA ExclusiveOR register with A
#define i_op_XRA 0b10101000

//XRI # 11101110 db ZSPCA ExclusiveOR immediate with A
#define i_op_XRI 0b11101110

//CMP S 10111SSS ZSPCA Compare register with A
#define i_op_CMP 0b10111000

//CPI # 11111110 ZSPCA Compare immediate with A
#define i_op_CPI 0b11111110

//RLC 00000111 C Rotate A left
#define i_op_RLC 0b00000111

//RRC 00001111 C Rotate A right
#define i_op_RRC 0b00001111

//RAL 00010111 C Rotate A left through carry
#define i_op_RAL 0b00010111

//RAR 00011111 C Rotate A right through carry
#define i_op_RAR 0b00011111

//CMA 00101111 – Compliment A
#define i_op_CMA 0b00101111

//CMC 00111111 C Compliment Carry flag
#define i_op_CMC 0b00111111

//STC 00110111 C Set Carry flag
#define i_op_STC 0b00110111
// WR

//JMP a 11000011 lb hb – Unconditional jump
#define i_op_JMP 0b11000011
// WR

//Jccc a 11CCC010 lb hb – Conditional jump
#define i_op_JCCC 0b11000010
// WR

//CALL a 11001101 lb hb – Unconditional subroutine call
#define i_op_CALL 0b11001101
// WR

//Cccc a 11CCC100 lb hb – Conditional subroutine call
#define i_op_CCCC 0b11000100
// WR

//RET 11001001 – Unconditional return from subroutine
#define i_op_RET 0b11001001
// WR

//Rccc 11CCC000 – Conditional return from subroutine
#define i_op_RCCC 0b11000000
// WR

//RST n 11NNN111 – Restart (Call n*8)
#define i_op_RST 0b11000111
// WR

//PCHL 11101001 – Jump to address in H:L
#define i_op_PCHL 0b11101001
// WR

//PUSH RP 11RP0101 *2 – Push register pair on the stack
#define i_op_PUSH 0b11000101
// WR

//POP RP 11RP0001 *2 *2 Pop register pair from the stack
#define i_op_POP 0b11000001
// WR

//XTHL 11100011 – Swap H:L with top word on stack
#define i_op_XTHL 0b11100011
// WR

//SPHL 11111001 – Set SP to content of H:L
#define i_op_SPHL 0b11111001
// WR

//IN p 11011011 pa – Read input port into A
#define i_op_IN 0b11011011
// WR

//OUT p 11010011 pa – Write A to output port
#define i_op_OUT 0b11010011
// WR

//EI 11111011 – Enable interrupts
#define i_op_EI 0b11111011
// WR

//DI 11110011 – Disable interrupts
#define i_op_DI 0b11110011
// WR

//HLT 01110110 – Halt processor
#define i_op_HLT 0b01110110
// WR

//NOP 00000000 – No operation
#define i_op_NOP 0b00000000
// WR

/* i.e. uint32_t ; */

/******************************************************************************/
/* Main Program */
/******************************************************************************/

int32_t main(void)
{unsigned char i;

opc_d[i_op_NOP]=f_op_NOP;
opc_d[i_op_HLT]=f_op_HLT;

opc_d[i_op_DI]=f_op_DI;
opc_d[i_op_EI]=f_op_EI;

opc_d[i_op_OUT]=f_op_OUT;
opc_d[i_op_IN]=f_op_IN;

opc_d[i_op_SPHL]=f_op_SPHL;
opc_d[i_op_XTHL]=f_op_XTHL;

opc_d[i_op_POP]=f_op_POP;
opc_d[i_op_PUSH]=f_op_PUSH;
opc_d[i_op_PCHL]=f_op_PCHL;
opc_d[i_op_RST]=f_op_RST;
opc_d[i_op_RCCC]=f_op_RCCC;
opc_d[i_op_RET]=f_op_RET;
opc_d[i_op_CCCC]=f_op_CCCC;
opc_d[i_op_CALL]=f_op_CALL;
opc_d[i_op_JCCC]=f_op_JCCC;
opc_d[i_op_JMP]=f_op_JMP;
opc_d[i_op_STC]=f_op_STC;
opc_d[i_op_CMC]=f_op_CMC;
opc_d[i_op_CMA]=f_op_CMA;

opc_d[i_op_RAR]=f_op_RAR;
opc_d[i_op_RAL]=f_op_RAL;
opc_d[i_op_RRC]=f_op_RRC;
opc_d[i_op_RLC]=f_op_RLC;

opc_d[i_op_CPI]=f_op_CPI;
opc_d[i_op_CMP]=f_op_CMP;

opc_d[i_op_XRI]=f_op_XRI;
opc_d[i_op_XRA]=f_op_XRA;
opc_d[i_op_ORA]=f_op_ORA;
opc_d[i_op_ORI]=f_op_ORI;
opc_d[i_op_ANI]=f_op_ANI;
opc_d[i_op_ANA]=f_op_ANA;

opc_d[i_op_DAA]=f_op_DAA;
opc_d[i_op_DAD]=f_op_DAD;

opc_d[i_op_INX]=f_op_INX;
opc_d[i_op_DCX]=f_op_DCX;
opc_d[i_op_DCR]=f_op_DCR;
opc_d[i_op_INR]=f_op_INR;
opc_d[i_op_SBI]=f_op_SBI;
opc_d[i_op_SBB]=f_op_SBB;
opc_d[i_op_SUI]=f_op_SUI;
opc_d[i_op_SUB]=f_op_SUB;
opc_d[i_op_ACI]=f_op_ACI;
opc_d[i_op_ADC]=f_op_ADC;
opc_d[i_op_ADI]=f_op_ADI;
opc_d[i_op_ADD]=f_op_ADD;
opc_d[i_op_XCHG]=f_op_XCHG;

opc_d[i_op_STAXB]=f_op_STAXB;
opc_d[i_op_LDAXB]=f_op_LDAXB;
opc_d[i_op_STAXB]=f_op_STAXD;
opc_d[i_op_LDAXB]=f_op_LDAXD;

opc_d[i_op_SHLD]=f_op_SHLD;
opc_d[i_op_LHLD]=f_op_LHLD;
opc_d[i_op_LDA]=f_op_LDA;
opc_d[i_op_STA]=f_op_STA;

opc_d[i_op_LXI]=f_op_LXI_BC;
opc_d[i_op_LXI+1]=f_op_LXI_DE;
opc_d[i_op_LXI+2]=f_op_LXI_HL;
opc_d[i_op_LXI+3]=f_op_LXI_SP;

for(i=0;i<64;i+=8)opc_d[i_op_MVI+i]=f_op_MVI; for(i=0;i<64;i++)opc_d[i_op_MOV+i]=f_op_MOV; #ifndef PIC32_STARTER_KIT /*The JTAG is on by default on POR. A PIC32 Starter Kit uses the JTAG, but for other debug tool use, like ICD 3 and Real ICE, the JTAG should be off to free up the JTAG I/O */ DDPCONbits.JTAGEN = 0; #endif /*Refer to the C32 peripheral library documentation for more information on the SYTEMConfig function. This function sets the PB divider, the Flash Wait States, and the DRM /wait states to the optimum value. It also enables the cacheability for the K0 segment. It could has side effects of possibly alter the pre-fetch buffer and cache. It sets the RAM wait states to 0. Other than the SYS_FREQ, this takes these parameters. The top 3 may be '|'ed together: SYS_CFG_WAIT_STATES (configures flash wait states from system clock) SYS_CFG_PB_BUS (configures the PB bus from the system clock) SYS_CFG_PCACHE (configures the pCache if used) SYS_CFG_ALL (configures the flash wait states, PB bus, and pCache)*/ /* TODO Add user clock/system configuration code if appropriate. */ SYSTEMConfig(SYS_FREQ, SYS_CFG_ALL); /* Initialize I/O and Peripherals for application */ InitApp(); /*Configure Multivector Interrupt Mode. Using Single Vector Mode is expensive from a timing perspective, so most applications should probably not use a Single Vector Mode*/ INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR); /* TODO */

while(1)
{

}
}

Leave a Reply

Your email address will not be published. Required fields are marked *

*