#ifndef MP_included
#define MP_included

#include <iostream.h>
#include <iomanip.h>
#include <istream.h>

// Used in C (stdio) macros
#ifndef HEX
#define HEX "%08lx"
#endif

// Used in C++ (ostream) macros
#ifndef MBASEFLAG
#define MBASEFLAG ( ios::showbase | ios::internal)
#endif

#ifndef MHEX
#define MHEX setfill('0') << setw( 10 ) << hex 
#endif

#ifndef MHEX_BYTE
#define MHEX_BYTE setfill('0') << setw( 4 ) << hex 
#endif

//User simulated memory dialog formats (Part 1 Item 7)
const int MP_IndexRW = 0;
const int MP_IndexDI = 1;
const int MP_IndexWB = 2;

#define MP_ReadRequest(xyz, vaddr) \
   setiosflags( MBASEFLAG ) << \
   xyz << ' ' << MHEX << (vaddr) << '?' << endl << \
   dec

#define MP_ManualInputOverflow \
   "MP:Warning: The value you gave cannot fit in a byte." << endl;

#define MP_AcceptDataWord( data ) \
   resetiosflags( ios::hex | ios::oct | ios::dec ) >> ( data )

#define MP_AcceptOKcinmember \
  ignore( 3 )

#define MP_WriteRequestWord(xyz, vaddr, data) \
   setiosflags( MBASEFLAG ) << \
   (xyz) << ' ' << MHEX << vaddr << \
   ' ' << MHEX << (data) << endl << \
   dec

#define MP_WriteRequestByte(xyz, vaddr, data) \
   setiosflags( MBASEFLAG ) << \
   (xyz) << ' ' << MHEX << vaddr << \
   ' ' << MHEX_BYTE << (static_cast<int>(data)) << endl << \
   dec

// Errors detected by CPU

#define MP_BadOpcode(instr,PC) \
   setiosflags( MBASEFLAG ) << \
"Stop:Undefined or unimplemented opcode " << MHEX << (instr) << \
" with PC=" << MHEX << (PC) << endl << dec

#define MP_Trap(instr,PC) \
   setiosflags( MBASEFLAG ) << \
"Stop:BREAK or SYSCALL instr=" << MHEX << (instr) << \
" with PC=" << MHEX << (PC) << endl << dec

   //Use this message for illegal operands or other conditions NOT COVERED 
   //by previous messages
#define MP_BadOperation(instr,PC) \
   setiosflags( MBASEFLAG ) << \
"Stop:Other illegal operation of inst. " << MHEX << (instr) << \
" with PC=" << MHEX << (PC) << endl << dec

#define MP_CountOut \
"Stop:Option --limit count ran out." << endl 

#define MP_IntOverflow(PC) \
   setiosflags( MBASEFLAG ) << \
"Stop:Integer ALU Overflow at PC=" << MHEX << (PC) << endl << dec






#define MP_isn1(PC,instruction,op05) setiosflags(MBASEFLAG) << \
   MHEX << (PC) << ": " << MHEX << (instruction) << \
   " op=" << setw(4) << (op05) << \
   dec

#define C_DFM_isn1 \
HEX": "HEX" op=%02x "

#define MP_Itype(rs,rt,imm,NAME) setiosflags(MBASEFLAG) << dec << \
 " rs=" << setw(2) << (rs) << \
 " rt=" << setw(2) << (rt) << \
 " imm=" <<  hex << setw(4) << (imm) << \
 " " << (NAME) << endl << \
 dec

#define C_DFM_Itype \
DFM_isn1"rs=%02x rt=%02x imm=%04x %s\n"

#define MP_Jtype(disp,NAME) setiosflags(MBASEFLAG) << \
 " disp=" << hex << setw(7) << (disp) << \
 " " << (NAME) << endl << \
 dec

#define C_DFM_Jtype \
DFM_isn1"tar=%07lx %s\n"

#define MP_Rtype(rs,rt,rd,sha,fun,NAME) setiosflags(MBASEFLAG) << dec << \
 " rs=" << setw(2) << (rs) << \
 " rt=" << setw(2) << (rt) << \
 " rd=" << setw(2) << (rd) << \
 " sha=" << setw(2) << (sha) << \
 " fun=" << hex << setw(4) << (fun) << \
 " " << (NAME) << endl << \
 dec

#define C_DFM_Rtype \
DFM_isn1"rs=%02x rt=%02x rd=%02x sha=%02x fun=%02x %s\n"

#define MP_PCs(PC,IR,fetchPC) \
   setiosflags( MBASEFLAG ) << \
"      PC=" << MHEX << (PC) << \
"      IR=" << MHEX << (IR) << \
"  fetchPC=" << MHEX << (fetchPC) << endl

#define C_DFM_PCs \
"      PC="HEX"  fetchPC="HEX"  IR="HEX"\n"

#define MP_R0_R7(r0,r1,r2,r3,r4,r5,r6,r7) \
   setiosflags( MBASEFLAG ) << \
"$zero=$0=" << MHEX << (r0) << "  " << \
"$at=$1=" << MHEX << (r1) << "   " << \
"$v0=$2=" << MHEX << (r2) << "   " << \
"$v1=$3=" << MHEX << (r3) << endl << \
"  $a0=$4=" << MHEX << (r4) << "  " << \
"$a2=$5=" << MHEX << (r5) << "   " << \
"$a3=$6=" << MHEX << (r6) << "   " << \
"$a4=$7=" << MHEX << (r7) << endl

#define C_DFM_R0_7 \
"$zero=$0="HEX"   $at=$1="HEX"    $v0=$2="HEX"    $v1=$3="HEX"\n"\
"  $a0=$4="HEX"   $a1=$5="HEX"    $a2=$6="HEX"    $a3=$7="HEX"\n"

#define MP_R8_R15(r8,r9,r10,r11,r12,r13,r14,r15) \
   setiosflags( MBASEFLAG ) << \
"  $t0=$8=" << MHEX << (r8) << "  " << \
"$t1=$9=" << MHEX << (r9) << "  " << \
"$t2=$10=" << MHEX << (r10) << "  " << \
"$t3=$11=" << MHEX << (r11) << endl << \
" $t4=$12=" << MHEX << (r12) << " " << \
"$t5=$13=" << MHEX << (r13) << "  " << \
"$t6=$14=" << MHEX << (r14) << "  " << \
"$t7=$15=" << MHEX << (r15) << endl

#define C_DFM_R8_15 \
"  $t0=$8="HEX"   $t1=$9="HEX"   $t2=$10="HEX"   $t3=$11="HEX"\n"\
" $t4=$12="HEX"  $t5=$13="HEX"   $t6=$14="HEX"   $t7=$15="HEX"\n"

#define MP_R16_R23(r16,r17,r18,r19,r20,r21,r22,r23) \
   setiosflags( MBASEFLAG ) << \
" $s0=$16=" << MHEX << (r16) << " " << \
"$s1=$17=" << MHEX << (r17) << "  " << \
"$s2=$18=" << MHEX << (r18) << "  " << \
"$s3=$19=" << MHEX << (r19) << endl << \
" $s4=$20=" << MHEX << (r20) << " " << \
"$s5=$21=" << MHEX << (r21) << "  " << \
"$s6=$22=" << MHEX << (r22) << "  " << \
"$s7=$23=" << MHEX << (r23) << endl

#define C_DFM_R16_23 \
" $s0=$16="HEX"  $s1=$17="HEX"   $s2=$18="HEX"   $s3=$19="HEX"\n"\
" $s4=$20="HEX"  $s5=$21="HEX"   $s6=$22="HEX"   $s7=$23="HEX"\n"

#define MP_R24_R31(r24,r25,r26,r27,r28,r29,r30,r31) \
   setiosflags( MBASEFLAG ) << \
" $t8=$24=" << MHEX << (r24) << " " << \
"$t9=$25=" << MHEX << (r25) << " " << \
"$kt0=$26=" << MHEX << (r26) << " " << \
"$kt1=$27=" << MHEX << (r27) << endl << \
" $gp=$28=" << MHEX << (r28) << " " << \
"$sp=$29=" << MHEX << (r29) << "  " << \
"$s8=$30=" << MHEX << (r30) << "  " << \
"$ra=$31=" << MHEX << (r31) << endl

#define MP_HILO(hi,lo) \
   setiosflags( MBASEFLAG ) << \
"      HI=" << MHEX << (hi) << " " << \
"     LO=" << MHEX << (lo) << endl << dec


#define C_DFM_R24_31 \
" $t8=$24="HEX"  $t9=$25="HEX"  $kt0=$26="HEX"  $kt1=$27="HEX"\n"\
" $gp=$28="HEX"  $sp=$29="HEX"   $s8=$30="HEX"   $ra=$31="HEX"\n"

#define C_DFM_SysReg \
"   Cause="HEX"      EPC="HEX"  BadVaddr="HEX"\n\n"



#endif

