-
Notifications
You must be signed in to change notification settings - Fork 0
/
other_op.c
94 lines (72 loc) · 2.22 KB
/
other_op.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "defines.h"
#include "internal.h"
/* Other opcodes:
* int
* reti
nop
brkp
stf
clf
*/
void opcodeCall( opcode_pointer );
OPCODE( int ) {
proc.sf = proc.flags;
proc.flags &= ~TF;
int interruptNumber = curopc.args[ 0 ];
interrupt_data *intdata = getInterruptData( interruptNumber );
if ( !intdata )
interruptNumber = -1;
if ( interruptNumber >= 0 ) {
if ( ( !( intdata->type & INTT_Unmaskable ) && !( proc.flags & IF ) ) )
return;
uint32 interruptCodePtr = * (uint32 *) &mem[ MEM_INTERRUPT_VECTOR_TABLE_START + interruptNumber * sizeof( uint32 ) ];
//printf( "op_int(). intCodeptr == mem[ 0x%04X ] == 0x%X.\n", interruptCodePtr, * (uint32 *) &mem[ interruptCodePtr ] );
// Interrupts are overridden only if address value in the IVT is not equal to zero:
if ( interruptCodePtr == 0 && intdata->defaddress ) {
intdata->defaddress();
proc.flags |= ( proc.sf & TF );
} else if ( interruptCodePtr != 0 ) {
// Save last instruction position:
proc.ra = proc.instructionptr;
proc.instructionptr = interruptCodePtr;
//printf( "op_int(). Interrupt address 0x%04X, return address 0x%04X.\n", proc.instructionptr, proc.ra );
} else {
interruptNumber = -1;
}
} // of if ( interruptNumber > 0 ) {}
if ( interruptNumber < 0 ) {
proc.ra = proc.instructionptr;
curopc.args[ 0 ] = findInterruptMatrixIndex( except_invalid_interrupt );
opcodeCall( op_int );
}
} // of OPCODE( int ) {}
OPCODE( int_ret ) {
if ( proc.sf & TF )
proc.flags = ( proc.sf & ~TF ) | PostTF;
else
proc.flags = proc.sf;
proc.instructionptr = proc.ra + RISC_INSTRUCTION_LENGTH;
}
OPCODE( nop ) {}
OPCODE( brkp ) {
except_breakpoint();
}
OPCODE( read_bva ) {
static int bvaindex = 0;
REGARG( 0 ) = proc.bva[ bvaindex ];
bvaindex = ( bvaindex + 1 ) % 64;
}
OPCODE( readwrite_tlb ) {
if ( REGARG( 1 ) < MAX_TLB ) {
if ( REGARG( 2 ) == 0 )
proc.tlb[ REGARG( 1 ) ] = REGARG( 0 );
else
REGARG( 0 ) = proc.tlb[ REGARG( 1 ) ];
} else {
proc.ra = proc.instructionptr;
curopc.args[ 0 ] = findInterruptMatrixIndex( except_tlb );
opcodeCall( op_int );
}
}
OPCODE( setflag ) { proc.flags |= ( curopc.args[ 0 ] & FLAGS_Storable ); }
OPCODE( clearflag ) { proc.flags &= ~( curopc.args[ 0 ] & FLAGS_Storable ); }