1
0
mirror of synced 2026-02-17 05:08:02 +00:00

Uploaded_7_9_2025

This commit is contained in:
Ted Fried
2025-07-09 16:05:45 -07:00
parent 4cfb953c3b
commit 172fcb3090

View File

@@ -18,6 +18,9 @@
// Revision 1 12/26/2024 // Revision 1 12/26/2024
// Initial revision // Initial revision
// //
// Revision 2 7/9/2025
// Fixed a number of bugs found when running core against the MartyPC 8086 test suite.
//
// //
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// //
@@ -806,6 +809,7 @@ inline uint8_t BIU_Bus_Cycle(uint8_t biu_operation, uint32_t local_address , uin
// -------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------
// ------------------------------------------------------ // ------------------------------------------------------
// Calculate full address allowing for segment override // Calculate full address allowing for segment override
// ------------------------------------------------------ // ------------------------------------------------------
@@ -849,7 +853,6 @@ uint16_t Biu_Operation(uint8_t biu_operation , uint8_t segment_overridable ,uint
if (biu_operation==INTERRUPT_ACK) { if (biu_operation==INTERRUPT_ACK) {
assert_lock=1;
read_data = BIU_Bus_Cycle(biu_operation, 0x00000 , 0x00 ); read_data = BIU_Bus_Cycle(biu_operation, 0x00000 , 0x00 );
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
@@ -942,7 +945,6 @@ uint16_t pfq_fetch_word() {
// ------------------------------------------------------ // ------------------------------------------------------
// //
void reset_sequence() { void reset_sequence() {
uint32_t writeback_data7=0;
while (direct_reset_raw!=0) {} // Stay here until RESET is de-aserted while (direct_reset_raw!=0) {} // Stay here until RESET is de-aserted
@@ -951,10 +953,6 @@ void reset_sequence() {
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
writeback_data7 = (0xBFFFCFFF & GPIO6_DR); // Read in current GPIOx register value and clear the bits we intend to update
GPIO6_DR = writeback_data7 | 0x40003000; // Set S[2:0] to "111"
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
@@ -1486,12 +1484,12 @@ void opcode_0xE4() {
return; return;
} }
void opcode_0xED() { clock_counter = clock_counter + 12; register_ax = Biu_Operation(IO_READ_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , register_dx , 0x00 ); return; } // 0xED - IN - ac,DX - Variable Port - Word void opcode_0xED() { clock_counter = clock_counter + 12; register_ax = Biu_Operation(IO_READ_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , register_dx , 0x00 ); return; } // 0xED - IN - ac,DX - Variable Port - Word
void opcode_0xE5() { clock_counter = clock_counter + 14; register_ax = Biu_Operation(IO_READ_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , (0xFF&pfq_fetch_byte()) , 0x00 ); return; } // [ 0xE5 0xpp ] - IN - ac,Opcode Port - Word void opcode_0xE5() { clock_counter = clock_counter + 14; register_ax = Biu_Operation(IO_READ_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , (0xFF&pfq_fetch_byte()) , 0x00 ); return; } // [ 0xE5 0xpp ] - IN - ac,Opcode Port - Word
void opcode_0xEE() { clock_counter = clock_counter + 8; Biu_Operation(IO_WRITE_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , register_dx , register_ax ); return; } // 0xEE - OUT - DX - Variable Port - Byte void opcode_0xEE() { clock_counter = clock_counter + 8; Biu_Operation(IO_WRITE_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , register_dx , register_ax ); return; } // 0xEE - OUT - DX - Variable Port - Byte
void opcode_0xEF() { clock_counter = clock_counter + 12; Biu_Operation(IO_WRITE_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , register_dx , register_ax ); return; } // 0xEF - OUT - DX - Variable Port - Word void opcode_0xEF() { clock_counter = clock_counter + 12; Biu_Operation(IO_WRITE_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , register_dx , register_ax ); return; } // 0xEF - OUT - DX - Variable Port - Word
void opcode_0xE6() { clock_counter = clock_counter + 10; Biu_Operation(IO_WRITE_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , (0xFF&pfq_fetch_byte()) , register_ax ); return; } // [ 0xE6 0xpp ] - OUT - Opcode Port - Byte void opcode_0xE6() { clock_counter = clock_counter + 10; Biu_Operation(IO_WRITE_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , (0xFF&pfq_fetch_byte()) , register_ax ); return; } // [ 0xE6 0xpp ] - OUT - Opcode Port - Byte
void opcode_0xE7() { clock_counter = clock_counter + 14; Biu_Operation(IO_WRITE_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , (0xFF&pfq_fetch_byte()) , register_ax ); return; } // [ 0xE7 0xpp ] - OUT - Opcode Port - Word void opcode_0xE7() { clock_counter = clock_counter + 14; Biu_Operation(IO_WRITE_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , (0xFF&pfq_fetch_byte()) , register_ax ); return; } // [ 0xE7 0xpp ] - OUT - Opcode Port - Word
@@ -1916,8 +1914,7 @@ void opcode_0x3D() {clock_counter=clock_counter+4;
// Shifts // Shifts
// ------------------------------------------------------ // ------------------------------------------------------
uint8_t ROL8(uint8_t local_data , uint8_t local_count) { uint8_t ROL8(uint8_t local_data , uint8_t local_count) {
uint8_t old_msb=0; uint8_t old_msb=0, new_msb=0;
uint8_t new_msb=0;
while (local_count != 0) { while (local_count != 0) {
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
@@ -1927,16 +1924,15 @@ uint8_t ROL8(uint8_t local_data , uint8_t local_count) {
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
new_msb = (local_data&0x80) >> 7; new_msb = (local_data&0x80) >> 7;
register_flags=(register_flags | old_msb); // Set C flag register_flags=(register_flags | old_msb); // Set C flag
if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag
return local_data; return local_data;
} }
// ------------------------------------------------------ // ------------------------------------------------------
uint16_t ROL16(uint16_t local_data , uint8_t local_count) { uint16_t ROL16(uint16_t local_data , uint8_t local_count) {
uint8_t old_msb=0; uint8_t old_msb=0, new_msb=0;
uint8_t new_msb=0;
while (local_count != 0) { while (local_count != 0) {
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
@@ -1946,8 +1942,9 @@ uint16_t ROL16(uint16_t local_data , uint8_t local_count) {
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
new_msb = (local_data&0x8000) >> 15; new_msb = (local_data&0x8000) >> 15;
register_flags=(register_flags | old_msb); // Set C flag register_flags=(register_flags | old_msb); // Set C flag
if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag
return local_data; return local_data;
} }
@@ -1961,10 +1958,12 @@ uint8_t ROR8(uint8_t local_data , uint8_t local_count) {
local_data = old_lsb | (local_data >> 1); local_data = old_lsb | (local_data >> 1);
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
}
new_msb = (local_data&0x80) >> 7; new_msb = (local_data&0x80) >> 7;
register_flags=(register_flags | new_msb); // Set C flag register_flags=(register_flags | new_msb); // Set C flag
}
if ( (local_data&0x80) != ((local_data&0x40)<<1)) register_flags=(register_flags|0x0800); // Set O flag if ( (local_data&0x80) != ((local_data&0x40)<<1)) register_flags=(register_flags|0x0800); // Set O flag
return local_data; return local_data;
} }
@@ -1980,44 +1979,48 @@ uint16_t ROR16(uint16_t local_data , uint8_t local_count) {
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
new_msb = (local_data&0x8000) >> 15; new_msb = (local_data&0x8000) >> 15;
register_flags=(register_flags | new_msb); // Set C flag register_flags=(register_flags | new_msb); // Set C flag
if ( (local_data&0x8000) != ((local_data&0x4000)<<1)) register_flags=(register_flags|0x0800); // Set O flag if ( (local_data&0x8000) != ((local_data&0x4000)<<1)) register_flags=(register_flags|0x0800); // Set O flag
return local_data; return local_data;
} }
// ------------------------------------------------------ // ------------------------------------------------------
uint8_t RCL8(uint8_t local_data , uint8_t local_count) { uint8_t RCL8(uint8_t local_data , uint8_t local_count) {
uint8_t tempcf, old_msb, new_msb; uint8_t tempcf, old_msb=0, new_msb=0;
while (local_count != 0) { while (local_count != 0) {
tempcf = flag_c; tempcf = flag_c;
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_msb = (local_data&0x80) >> 7; old_msb = (local_data&0x80) >> 7;
register_flags=(register_flags | old_msb); // Set C flag register_flags=(register_flags | old_msb); // Set C flag
local_data = (local_data << 1) | tempcf; local_data = (local_data << 1) | tempcf;
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
new_msb = (local_data&0x80) >> 7; new_msb = (local_data&0x80) >> 7;
if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag
return local_data; return local_data;
} }
// ------------------------------------------------------ // ------------------------------------------------------
uint16_t RCL16(uint16_t local_data , uint8_t local_count) { uint16_t RCL16(uint16_t local_data , uint8_t local_count) {
uint16_t tempcf, old_msb, new_msb; uint16_t tempcf, old_msb=0, new_msb=0;
while (local_count != 0) { while (local_count != 0) {
tempcf = flag_c; tempcf = flag_c;
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_msb = (local_data&0x8000) >> 15; old_msb = (local_data&0x8000) >> 15;
register_flags=(register_flags | old_msb); // Set C flag register_flags=(register_flags | old_msb); // Set C flag
local_data = (local_data << 1) | tempcf; local_data = (local_data << 1) | tempcf;
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
new_msb = (local_data&0x8000) >> 15; new_msb = (local_data&0x8000) >> 15;
if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag
return local_data; return local_data;
} }
@@ -2029,12 +2032,14 @@ uint8_t RCR8(uint8_t local_data , uint8_t local_count) {
tempcf = flag_c << 7; tempcf = flag_c << 7;
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_lsb = local_data&0x1; old_lsb = local_data&0x1;
register_flags=(register_flags | old_lsb); // Set C flag register_flags=(register_flags | old_lsb); // Set C flag
local_data = tempcf | (local_data >> 1); local_data = tempcf | (local_data >> 1);
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
if ( (local_data&0x80) != ((local_data&0x40)<<1)) register_flags=(register_flags|0x0800); // Set O flag if ( (local_data&0x80) != ((local_data&0x40)<<1)) register_flags=(register_flags|0x0800); // Set O flag
return local_data; return local_data;
} }
@@ -2046,47 +2051,51 @@ uint16_t RCR16(uint16_t local_data , uint8_t local_count) {
tempcf = flag_c << 15; tempcf = flag_c << 15;
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_lsb = local_data&0x1; old_lsb = local_data&0x1;
register_flags=(register_flags | old_lsb); // Set C flag register_flags=(register_flags | old_lsb); // Set C flag
local_data = tempcf | (local_data >> 1); local_data = tempcf | (local_data >> 1);
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
if ( (local_data&0x8000) != ((local_data&0x4000)<<1)) register_flags=(register_flags|0x0800); // Set O flag if ( (local_data&0x8000) != ((local_data&0x4000)<<1)) register_flags=(register_flags|0x0800); // Set O flag
return local_data; return local_data;
} }
// ------------------------------------------------------ // ------------------------------------------------------
uint8_t SAL8(uint8_t local_data , uint8_t local_count) { uint8_t SAL8(uint8_t local_data , uint8_t local_count) {
uint8_t old_msb, new_msb; uint8_t old_msb=0, new_msb=0;
while (local_count != 0) { while (local_count != 0) {
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7EE); // Zero C ,O, A Flags
old_msb = (local_data&0x80) >> 7; old_msb = (local_data&0x80) >> 7;
register_flags=(register_flags | old_msb); // Set C flag register_flags=(register_flags | old_msb); // Set C flag
local_data = (local_data << 1); // Perform the shift local_data = (local_data << 1); // Perform the shift
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
new_msb = (local_data&0x80) >> 7; new_msb = (local_data&0x80) >> 7;
if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag
Set_Flags_Byte_SZP(local_data); Set_Flags_Byte_SZP(local_data);
return local_data; return local_data;
} }
// ------------------------------------------------------ // ------------------------------------------------------
uint16_t SAL16(uint16_t local_data , uint8_t local_count) { uint16_t SAL16(uint16_t local_data , uint8_t local_count) {
uint16_t old_msb, new_msb; uint8_t old_msb=0, new_msb=0;
while (local_count != 0) { while (local_count != 0) {
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_msb = (local_data&0x8000) >> 15; old_msb = (local_data&0x8000) >> 15;
register_flags=(register_flags | old_msb); // Set C flag register_flags=(register_flags | old_msb); // Set C flag
local_data = (local_data << 1); // Perform the shift local_data = (local_data << 1); // Perform the shift
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
new_msb = (local_data&0x8000) >> 15; new_msb = (local_data&0x8000) >> 15;
if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag if (new_msb != flag_c) register_flags=(register_flags|0x0800); // Set O flag
Set_Flags_Word_SZP(local_data); Set_Flags_Word_SZP(local_data);
return local_data; return local_data;
} }
@@ -2098,17 +2107,18 @@ uint8_t SHR8(uint8_t local_data , uint8_t local_count) {
while (local_count != 0) { while (local_count != 0) {
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_lsb = local_data&0x1; old_lsb = local_data&0x1;
register_flags=(register_flags | old_lsb); // Set C flag register_flags=(register_flags | old_lsb); // Set C flag
local_data = (local_data >> 1); local_data = (local_data >> 1);
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
if ( (local_data&0x80) != ((local_data&0x40)<<1)) register_flags=(register_flags|0x0800); // Set O flag if ( (local_data&0x80) != ((local_data&0x40)<<1)) register_flags=(register_flags|0x0800); // Set O flag
Set_Flags_Byte_SZP(local_data); Set_Flags_Byte_SZP(local_data);
return local_data; return local_data;
} }
// ------------------------------------------------------ // ------------------------------------------------------
uint16_t SHR16(uint16_t local_data , uint8_t local_count) { uint16_t SHR16(uint16_t local_data , uint8_t local_count) {
uint16_t old_lsb; uint16_t old_lsb;
@@ -2116,13 +2126,15 @@ uint16_t SHR16(uint16_t local_data , uint8_t local_count) {
while (local_count != 0) { while (local_count != 0) {
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_lsb = local_data&0x1; old_lsb = local_data&0x1;
register_flags=(register_flags | old_lsb); // Set C flag register_flags=(register_flags | old_lsb); // Set C flag
local_data = (local_data >> 1); local_data = (local_data >> 1);
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
if ( (local_data&0x8000) != ((local_data&0x4000)<<1)) register_flags=(register_flags|0x0800); // Set O flag if ( (local_data&0x8000) != ((local_data&0x4000)<<1)) register_flags=(register_flags|0x0800); // Set O flag
Set_Flags_Word_SZP(local_data); Set_Flags_Word_SZP(local_data);
return local_data; return local_data;
} }
@@ -2134,13 +2146,14 @@ uint8_t SAR8(uint8_t local_data , uint8_t local_count) {
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_msb = local_data&0x80; old_msb = local_data&0x80;
old_lsb = local_data&0x01; old_lsb = local_data&0x01;
register_flags=(register_flags | old_lsb); // Set C flag register_flags=(register_flags | old_lsb); // Set C flag
local_data = old_msb | (local_data >> 1); local_data = old_msb | (local_data >> 1);
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
if ( (local_data&0x80) != ((local_data&0x40)<<1)) register_flags=(register_flags|0x0800); // Set O flag if ( (local_data&0x80) != ((local_data&0x40)<<1)) register_flags=(register_flags|0x0800); // Set O flag
Set_Flags_Byte_SZP(local_data); Set_Flags_Byte_SZP(local_data);
return local_data; return local_data;
} }
@@ -2153,13 +2166,14 @@ uint16_t SAR16(uint16_t local_data , uint8_t local_count) {
register_flags=(register_flags&0xF7FE); // Zero C ,O Flags register_flags=(register_flags&0xF7FE); // Zero C ,O Flags
old_msb = local_data&0x8000; old_msb = local_data&0x8000;
old_lsb = local_data&0x0001; old_lsb = local_data&0x0001;
register_flags=(register_flags | old_lsb); // Set C flag register_flags=(register_flags | old_lsb); // Set C flag
local_data = old_msb | (local_data >> 1); local_data = old_msb | (local_data >> 1);
local_count--; local_count--;
clock_counter=clock_counter+4; // Add four clocks per bit clock_counter=clock_counter+4; // Add four clocks per bit
} }
if ( (local_data&0x8000) != ((local_data&0x4000)<<1)) register_flags=(register_flags|0x0800); // Set O flag if ( (local_data&0x8000) != ((local_data&0x4000)<<1)) register_flags=(register_flags|0x0800); // Set O flag
Set_Flags_Word_SZP(local_data); Set_Flags_Word_SZP(local_data);
return local_data; return local_data;
} }
@@ -2176,7 +2190,7 @@ void opcode_0xD0() {
case 0x3: Writeback_EA(RCR8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[3] - RCR REG8/MEM8 , 1 case 0x3: Writeback_EA(RCR8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[3] - RCR REG8/MEM8 , 1
case 0x4: Writeback_EA(SAL8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[4] - SAL REG8/MEM8 , 1 case 0x4: Writeback_EA(SAL8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[4] - SAL REG8/MEM8 , 1
case 0x5: Writeback_EA(SHR8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[5] - SHR REG8/MEM8 , 1 case 0x5: Writeback_EA(SHR8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[5] - SHR REG8/MEM8 , 1
case 0x6: Writeback_EA(0xFF); break; // # 0xD0 REG[6] - ** SETMO ** R3 case 0x6: Writeback_EA(SAL8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[4] - SAL REG8/MEM8 , 1
case 0x7: Writeback_EA(SAR8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[7] - SAR REG8/MEM8 , 1 case 0x7: Writeback_EA(SAR8(Fetch_EA(),0x1) ); break; // # 0xD0 REG[7] - SAR REG8/MEM8 , 1
} }
return; return;
@@ -2195,7 +2209,7 @@ void opcode_0xD1() {
case 0x3: Writeback_EA(RCR16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[3] - RCR REG16/MEM16 , 1 case 0x3: Writeback_EA(RCR16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[3] - RCR REG16/MEM16 , 1
case 0x4: Writeback_EA(SAL16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[4] - SAL REG16/MEM16 , 1 case 0x4: Writeback_EA(SAL16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[4] - SAL REG16/MEM16 , 1
case 0x5: Writeback_EA(SHR16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[5] - SHR REG16/MEM16 , 1 case 0x5: Writeback_EA(SHR16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[5] - SHR REG16/MEM16 , 1
case 0x6: Writeback_EA(0xFFFF); break; // # 0xD1 REG[6] - ** SETMO ** R3 case 0x6: Writeback_EA(SAL16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[4] - SAL REG16/MEM16 , 1
case 0x7: Writeback_EA(SAR16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[7] - SAR REG16/MEM16 , 1 case 0x7: Writeback_EA(SAR16(Fetch_EA(),0x1) ); break; // # 0xD1 REG[7] - SAR REG16/MEM16 , 1
} }
return; return;
@@ -2214,7 +2228,7 @@ void opcode_0xD2() {
case 0x3: Writeback_EA(RCR8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[3] - RCR REG8/MEM8 , CL case 0x3: Writeback_EA(RCR8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[3] - RCR REG8/MEM8 , CL
case 0x4: Writeback_EA(SAL8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[4] - SAL REG8/MEM8 , CL case 0x4: Writeback_EA(SAL8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[4] - SAL REG8/MEM8 , CL
case 0x5: Writeback_EA(SHR8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[5] - SHR REG8/MEM8 , CL case 0x5: Writeback_EA(SHR8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[5] - SHR REG8/MEM8 , CL
case 0x6: Writeback_EA(0xFFFF); break; // # 0xD2 REG[6] - ** SETMO ** R3 case 0x6: Writeback_EA(SAL8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[4] - SAL REG8/MEM8 , CL
case 0x7: Writeback_EA(SAR8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[7] - SAR REG8/MEM8 , CL case 0x7: Writeback_EA(SAR8(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD2 REG[7] - SAR REG8/MEM8 , CL
} }
return; return;
@@ -2233,7 +2247,7 @@ void opcode_0xD3() {
case 0x3: Writeback_EA(RCR16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[3] - RCR REG16/MEM16 , CL case 0x3: Writeback_EA(RCR16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[3] - RCR REG16/MEM16 , CL
case 0x4: Writeback_EA(SAL16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[4] - SAL REG16/MEM16 , CL case 0x4: Writeback_EA(SAL16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[4] - SAL REG16/MEM16 , CL
case 0x5: Writeback_EA(SHR16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[5] - SHR REG16/MEM16 , CL case 0x5: Writeback_EA(SHR16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[5] - SHR REG16/MEM16 , CL
case 0x6: Writeback_EA(0xFFFF); break; // # 0xD3 REG[6] - ** SETMO ** R3 case 0x6: Writeback_EA(SAL16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[4] - SAL REG16/MEM16 , CL
case 0x7: Writeback_EA(SAR16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[7] - SAR REG16/MEM16 , CL case 0x7: Writeback_EA(SAR16(Fetch_EA(),(register_cx&0x00FF)) ); break; // # 0xD3 REG[7] - SAR REG16/MEM16 , CL
} }
return; return;
@@ -2273,7 +2287,8 @@ void opcode_0xA4() {
if (prefix_rep==0) clock_counter=clock_counter+1; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_rep==0) clock_counter=clock_counter+1; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_rep==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -2287,7 +2302,7 @@ void opcode_0xA4() {
else { register_si=register_si - 1; register_di=register_di - 1; } else { register_si=register_si - 1; register_di=register_di - 1; }
} while (prefix_rep==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -2302,7 +2317,8 @@ void opcode_0xA5() {
if (prefix_rep==0) clock_counter=clock_counter+1; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_rep==0) clock_counter=clock_counter+1; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_rep==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip -(prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip -(prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -2316,7 +2332,7 @@ void opcode_0xA5() {
else { register_si=register_si - 2; register_di=register_di - 2; } else { register_si=register_si - 2; register_di=register_di - 2; }
} while (prefix_rep==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -2396,7 +2412,9 @@ void opcode_0xAA() {
if (prefix_rep==0) clock_counter=clock_counter+1; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_rep==0) clock_counter=clock_counter+1; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_rep==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
printf("prefix_repnz: %x register_cx: %x \n,",prefix_repnz,register_cx);
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -2409,7 +2427,7 @@ void opcode_0xAA() {
else { register_di=register_di - 1; } else { register_di=register_di - 1; }
} while (prefix_rep==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -2423,7 +2441,8 @@ void opcode_0xAB() {
if (prefix_rep==0) clock_counter=clock_counter+1; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_rep==0) clock_counter=clock_counter+1; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_rep==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -2436,7 +2455,7 @@ void opcode_0xAB() {
else { register_di=register_di - 2; } else { register_di=register_di - 2; }
} while (prefix_rep==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -2451,7 +2470,8 @@ void opcode_0xAC() {
if (prefix_rep==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_rep==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_rep==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -2465,7 +2485,7 @@ void opcode_0xAC() {
else { register_si=register_si - 1; } else { register_si=register_si - 1; }
} while (prefix_rep==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -2480,7 +2500,8 @@ void opcode_0xAD() {
if (prefix_rep==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_rep==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_rep==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -2494,7 +2515,7 @@ void opcode_0xAD() {
else { register_si=register_si - 2; } else { register_si=register_si - 2; }
} while (prefix_rep==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -2510,7 +2531,8 @@ void opcode_0xAE() {
if ( (prefix_repz == 1) || (prefix_repnz == 1) ) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts if ( (prefix_repz == 1) || (prefix_repnz == 1) ) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if ( (prefix_repz==1) || (prefix_repnz==1) ) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -2524,7 +2546,7 @@ void opcode_0xAE() {
else { register_di=register_di - 1; } else { register_di=register_di - 1; }
} while ( (prefix_repz==1 && flag_z==1) || (prefix_repnz==1 && flag_z==0) ); } while ( (prefix_repz==1 && flag_z==1) || (prefix_repnz==1 && flag_z==0) || (prefix_repc==1 && flag_c==1) || (prefix_repnc==1 && flag_c==0) );
return; return;
} }
@@ -2540,13 +2562,14 @@ void opcode_0xAF() {
if ( (prefix_repz == 1) || (prefix_repnz == 1) ) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts if ( (prefix_repz == 1) || (prefix_repnz == 1) ) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if ( (prefix_repz==1) || (prefix_repnz==1) ) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
clock_counter=clock_counter+15; // Add clocks per loop iteration clock_counter=clock_counter+15; // Add clocks per loop iteration
local_data = Biu_Operation(MEM_READ_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_ES , register_di , 0x00 ); // Read data from source local_data = Biu_Operation(MEM_READ_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_ES , register_di , 0x00 ); // Read data from source
SUB_Words(register_ax , local_data ); // Perform comparison which sets Flags SUB_Words(register_ax , local_data ); // Perform comparison which sets Flags
if ( (nmi_latched==1) || (direct_intr_raw!=0 && (flag_i)!=0) ) interrupt_pending=1; else interrupt_pending=0; if ( (nmi_latched==1) || (direct_intr_raw!=0 && (flag_i)!=0) ) interrupt_pending=1; else interrupt_pending=0;
@@ -2554,7 +2577,7 @@ void opcode_0xAF() {
else { register_di=register_di - 2; } else { register_di=register_di - 2; }
} while ( (prefix_repz==1 && flag_z==1) || (prefix_repnz==1 && flag_z==0) ); } while ( (prefix_repz==1 && flag_z==1) || (prefix_repnz==1 && flag_z==0) || (prefix_repc==1 && flag_c==1) || (prefix_repnc==1 && flag_c==0) );
return; return;
} }
@@ -2595,6 +2618,7 @@ void opcode_0xF6() {
int16_t signed_local_quo; int16_t signed_local_quo;
int8_t signed_local_rem; int8_t signed_local_rem;
Calculate_EA(); Calculate_EA();
switch (REG_field) { switch (REG_field) {
case 0x0: clock_counter=clock_counter+11; Boolean_AND(Fetch_EA(),pfq_fetch_byte()); break; // # 0xF6 REG[0] - TEST REG8/MEM8,IMM8 case 0x0: clock_counter=clock_counter+11; Boolean_AND(Fetch_EA(),pfq_fetch_byte()); break; // # 0xF6 REG[0] - TEST REG8/MEM8,IMM8
@@ -2612,24 +2636,34 @@ void opcode_0xF6() {
if ( ((register_ax&0xFF80)==0xFF80) || ((register_ax&0xFF80)==0x0000) ) { register_flags=(register_flags&0xF7FE); } // Clear O,C flags if ( ((register_ax&0xFF80)==0xFF80) || ((register_ax&0xFF80)==0x0000) ) { register_flags=(register_flags&0xF7FE); } // Clear O,C flags
else { register_flags=(register_flags|0x0801); } // Set O,C flags else { register_flags=(register_flags|0x0801); } // Set O,C flags
break; break;
case 0x6: if (ea_is_a_register==1) clock_counter=clock_counter+85; else clock_counter=clock_counter+91; // # 0xF6 REG[6] - DIV REG8/MEM8 case 0x6: if (ea_is_a_register==1) clock_counter=clock_counter+85; else clock_counter=clock_counter+91; // # 0xF6 REG[6] - DIV REG8/MEM8
local_divr=Fetch_EA(); local_divr=Fetch_EA();
printf("\nDIVISOR %x \n",local_divr);
if (local_divr==0) DIV0_Handler(); if (local_divr==0) DIV0_Handler();
else { else {
local_quo = register_ax / local_divr; local_quo = register_ax / local_divr;
local_rem = register_ax % local_divr; local_rem = register_ax % local_divr;
if (local_quo> 0xFF) { DIV0_Handler(); } if (local_quo> 0xFF) { DIV0_Handler(); }
printf("register_ax %x \n",register_ax);
printf("local_quo %x \n",local_quo);
printf("local_rem %x \n",local_rem);
register_ax = local_rem << 8; register_ax = local_rem << 8;
Write_Register(REG_AL , local_quo); Write_Register(REG_AL , local_quo);
} }
break; break;
case 0x7: if (ea_is_a_register==1) clock_counter=clock_counter+107; else clock_counter=clock_counter+114; // # 0xF6 REG[7] - IDIV REG8/MEM8 case 0x7: if (ea_is_a_register==1) clock_counter=clock_counter+107; else clock_counter=clock_counter+114; // # 0xF6 REG[7] - IDIV REG8/MEM8
signed_local_divr=(int8_t)Fetch_EA(); signed_local_divr=(int8_t)Fetch_EA();
printf("signed_local_divr %x \n",signed_local_divr);
if (signed_local_divr==0) DIV0_Handler(); if (signed_local_divr==0) DIV0_Handler();
else { else {
signed_local_quo = (int16_t)register_ax / signed_local_divr; signed_local_quo = (int16_t)register_ax / signed_local_divr;
signed_local_rem = (int16_t)register_ax % signed_local_divr; signed_local_rem = (int16_t)register_ax % signed_local_divr;
if (signed_local_quo> 0xFF) { DIV0_Handler(); } if ( (signed_local_divr>0) && (signed_local_divr>0x7F) ) {DIV0_Handler(); }
if ( (signed_local_divr<0) && (signed_local_divr<(0x7F-1) )) {DIV0_Handler(); }
printf("register_ax %x \n",register_ax);
printf("local_quo %x \n",signed_local_quo);
printf("local_rem %x \n",signed_local_rem);
register_ax = signed_local_rem << 8; register_ax = signed_local_rem << 8;
Write_Register(REG_AL , signed_local_quo); Write_Register(REG_AL , signed_local_quo);
} }
@@ -2655,7 +2689,8 @@ void opcode_0xF7() {
uint64_t local_overflow_test; uint64_t local_overflow_test;
Calculate_EA(); Calculate_EA(); printf("REG_field: %x ",REG_field);
switch (REG_field) { switch (REG_field) {
case 0x0: clock_counter=clock_counter+11; Boolean_AND(Fetch_EA(),pfq_fetch_word()); break; // # 0xF7 REG[0] - TEST REG16/MEM16 , IMM16 case 0x0: clock_counter=clock_counter+11; Boolean_AND(Fetch_EA(),pfq_fetch_word()); break; // # 0xF7 REG[0] - TEST REG16/MEM16 , IMM16
case 0x1: clock_counter=clock_counter+11; Boolean_AND(Fetch_EA(),pfq_fetch_word()); break; // # 0xF7 REG[1] - TEST REG16/MEM16 , IMM16 ** Duplicate ** case 0x1: clock_counter=clock_counter+11; Boolean_AND(Fetch_EA(),pfq_fetch_word()); break; // # 0xF7 REG[1] - TEST REG16/MEM16 , IMM16 ** Duplicate **
@@ -2670,6 +2705,7 @@ void opcode_0xF7() {
else { register_flags=(register_flags&0xF7FE); } // Clear O,C flags else { register_flags=(register_flags&0xF7FE); } // Clear O,C flags
break; break;
case 0x5: if (ea_is_a_register==1) clock_counter=clock_counter+141; else clock_counter=clock_counter+147; // # 0xF7 REG[5] - IMUL REG16/MEM16 case 0x5: if (ea_is_a_register==1) clock_counter=clock_counter+141; else clock_counter=clock_counter+147; // # 0xF7 REG[5] - IMUL REG16/MEM16
local_data = (int16_t)Fetch_EA() * (int16_t)register_ax; local_data = (int16_t)Fetch_EA() * (int16_t)register_ax;
register_dx = (local_data >> 16); register_dx = (local_data >> 16);
register_ax = (local_data&0x0000FFFF); register_ax = (local_data&0x0000FFFF);
@@ -2678,64 +2714,87 @@ void opcode_0xF7() {
else { register_flags=(register_flags|0x0801); } // Set O,C flags else { register_flags=(register_flags|0x0801); } // Set O,C flags
break; break;
case 0x6: if (ea_is_a_register==1) clock_counter=clock_counter+153; else clock_counter=clock_counter+167; // # 0xF7 REG[6] - DIV REG16/MEM16 case 0x6: if (ea_is_a_register==1) clock_counter=clock_counter+153; else clock_counter=clock_counter+167; // # 0xF7 REG[6] - DIV REG16/MEM16
local_numr = (register_dx<<16) | register_ax; local_numr = (register_dx<<16) | register_ax;
local_divr=Fetch_EA(); local_divr=Fetch_EA();
if (local_divr==0) DIV0_Handler(); if (local_divr==0) DIV0_Handler();
else { else {
local_overflow_test = local_numr / local_divr; local_overflow_test = local_numr / local_divr;
if (local_overflow_test> 0xFFFF) { DIV0_Handler(); }
register_ax = local_numr / local_divr; register_ax = local_numr / local_divr;
register_dx = local_numr % local_divr; register_dx = local_numr % local_divr;
if (local_overflow_test> 0xFFFF) { DIV0_Handler(); }
} }
break; break;
case 0x7: if (ea_is_a_register==1) clock_counter=clock_counter+175; else clock_counter=clock_counter+181; // # 0xF7 REG[7] - IDIV REG16/MEM16 case 0x7: if (ea_is_a_register==1) clock_counter=clock_counter+175; else clock_counter=clock_counter+181; // # 0xF7 REG[7] - IDIV REG16/MEM16
signed_local_numr = (int32_t)(register_dx<<16) | (int32_t)register_ax; signed_local_numr = (int32_t)(register_dx<<16) | (int32_t)register_ax;
signed_local_divr=(int16_t)Fetch_EA(); signed_local_divr=(int16_t)Fetch_EA();
if (signed_local_divr==0) DIV0_Handler(); if (signed_local_divr==0) DIV0_Handler();
else { else {
local_overflow_test = signed_local_numr / signed_local_divr; local_overflow_test = signed_local_numr / signed_local_divr;
//if (local_overflow_test> 0xFFFF) { DIV0_Handler(); }
if ( (signed_local_divr>0) && (signed_local_divr>0x7FFF) ) { DIV0_Handler(); }
if ( (signed_local_divr<0) && (signed_local_divr<(0x7FFF-1) )) { DIV0_Handler(); }
register_ax = signed_local_numr / signed_local_divr; register_ax = signed_local_numr / signed_local_divr;
register_dx = signed_local_numr % signed_local_divr; register_dx = signed_local_numr % signed_local_divr;
if (local_overflow_test> 0xFFFF) { DIV0_Handler(); }
} }
break; break;
} }
return; return;
} }
// ------------------------------------------------------ // ------------------------------------------------------
// 0x27 - DAA - Decimal Adjust for Addition // 0x27 - DAA - Decimal Adjust for Addition
// ------------------------------------------------------ // ------------------------------------------------------
void opcode_0x27() { void opcode_0x27() {
uint16_t local_al; uint16_t local_temp = (register_ax&0x00FF);
clock_counter=clock_counter+4;
local_al = register_ax&0x00FF;
if ( ((0x0F&local_al) > 0x09) || (flag_a==1) ) { local_al=local_al+0x06; register_flags=(register_flags|0x0010);} else register_flags=(register_flags&0xFFEF); // Set A Flag if ( ((register_ax&0x000F) > 0x9) || (flag_a==1) ) { temp16 = (register_ax&0x00FF) + 0x6;
if ( ((0xFF&local_al) > 0x9F) || (flag_c==1) ) { local_al=local_al+0x60; register_flags=(register_flags|0x0001);} else register_flags=(register_flags&0xFFFE); // Set C Flag Write_Register(REG_AL, temp16);
Write_Register(REG_AL, local_al); register_flags=(register_flags|0x0010); // Set A Flag
Set_Flags_Byte_SZP(local_al); if ( (flag_c==1) || (temp16&0x100) ) register_flags=(register_flags|0x0001); // Set C Flag
}
if ( ((local_temp&0x00FF) > 0x9F) || (flag_c==1) )
{ temp16=(register_ax&0x00FF)+0x60;
Write_Register(REG_AL, temp16);
register_flags=(register_flags|0x0001); // Set C Flag
}
Set_Flags_Byte_SZP(register_ax);
return; return;
} }
// ------------------------------------------------------ // ------------------------------------------------------
// 0x2F - DAS - Decimal Adjust for Subtraction // 0x2F - DAS - Decimal Adjust for Subtraction
// ------------------------------------------------------ // ------------------------------------------------------
void opcode_0x2F() { void opcode_0x2F() {
uint16_t local_al; uint16_t local_al;
uint16_t local_al1;
clock_counter=clock_counter+4;
local_al = register_ax&0x00FF; local_al = register_ax&0x00FF;
local_al1 = register_ax&0x00FF;
if ( ((0x0F&local_al) > 0x09) || (flag_a==1) ) { local_al=local_al-0x06; register_flags=(register_flags|0x0010);} else register_flags=(register_flags&0xFFEF); // Set A Flag if ( ((local_al&0x000F) > 0x9) || (flag_a==1) ) { local_al=local_al-0x6;
if ( ((0xFF&local_al) > 0x9F) || (flag_c==1) ) { local_al=local_al-0x60; register_flags=(register_flags|0x0001);} else register_flags=(register_flags&0xFFFE); // Set C Flag //if ((flag_c==1) || (flag_a==1)) register_flags=(register_flags|0x0001); // Set C Flag
register_flags=(register_flags|0x0010); // Set A Flag
}
if ( ((local_al1&0x00FF) > 0x9F) || (flag_c==1) ) { local_al=local_al-0x60;
register_flags=(register_flags|0x0001); // Set C Flag
}
Write_Register(REG_AL, local_al); Write_Register(REG_AL, local_al);
Set_Flags_Byte_SZP(local_al); Set_Flags_Byte_SZP(register_ax);
return; return;
} }
// ------------------------------------------------------ // ------------------------------------------------------
// 0x37 - AAA - ASCII Adjust for Addition // 0x37 - AAA - ASCII Adjust for Addition
// ------------------------------------------------------ // ------------------------------------------------------
@@ -2752,7 +2811,7 @@ void opcode_0x37() {
register_ax = register_ax + 0x0100; // AH = AH + 1 register_ax = register_ax + 0x0100; // AH = AH + 1
register_flags = (register_flags | 0x0010); // Set A Flag register_flags = (register_flags | 0x0010); // Set A Flag
} }
if (local_flag_a==1) register_flags = (register_flags | 0x0001); else register_flags=(register_flags & 0xFFFE); // CF = AF if (flag_a==1) register_flags = (register_flags | 0x0001); else register_flags=(register_flags & 0xFFFE); // CF = AF
register_ax = register_ax & 0xFF0F; // AL = AL & 0x0F register_ax = register_ax & 0xFF0F; // AL = AL & 0x0F
return; return;
} }
@@ -2773,7 +2832,7 @@ void opcode_0x3F() {
Write_Register(REG_AL, local_al); // Update AL Write_Register(REG_AL, local_al); // Update AL
register_flags = (register_flags | 0x0010); // Set A Flag register_flags = (register_flags | 0x0010); // Set A Flag
} }
if (local_flag_a==1) register_flags = (register_flags | 0x0001); else register_flags=(register_flags & 0xFFFE); // CF = AF if (flag_a==1) register_flags = (register_flags | 0x0001); else register_flags=(register_flags & 0xFFFE); // CF = AF
register_ax = register_ax & 0xFF0F; // AL = AL & 0x0F register_ax = register_ax & 0xFF0F; // AL = AL & 0x0F
return; return;
} }
@@ -2798,6 +2857,7 @@ void opcode_0xD4() {
Set_Flags_Byte_SZP(local_al); Set_Flags_Byte_SZP(local_al);
register_ax = (local_ah<<8) | local_al; register_ax = (local_ah<<8) | local_al;
return; return;
} }
@@ -2918,7 +2978,6 @@ void opcode_0xF4() {
if (direct_intr_raw!=0) direct_intr=1; else direct_intr=0; if (direct_intr_raw!=0) direct_intr=1; else direct_intr=0;
} while (direct_intr==0 && nmi_latched==0 && direct_reset_raw==0 ); } while (direct_intr==0 && nmi_latched==0 && direct_reset_raw==0 );
GPIO6_DR = GPIO6_raw_data | 0x40003000; // Set S[2:0] back to "111"
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
wait_for_CLK_falling_edge(); wait_for_CLK_falling_edge();
@@ -3020,7 +3079,7 @@ void opcode_0xC8() {
FP = register_sp; FP = register_sp;
if (level > 0) { if (level > 0) {
for (i=1; i<(level-1); i++) { for (i=0; i<(level-1); i++) {
register_bp = register_bp - 0x2; register_bp = register_bp - 0x2;
Push(Biu_Operation(MEM_READ_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_SS , register_bp, 0x00) ); Push(Biu_Operation(MEM_READ_WORD , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_SS , register_bp, 0x00) );
} }
@@ -3156,12 +3215,13 @@ void opcode_0x6C() {
uint8_t interrupt_pending=0; uint8_t interrupt_pending=0;
if (prefix_repz==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_repz==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_repz==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 printf("prefix_repc: %x prefix_repnc: %x flag_z: %x flag_c: %x register_cx: %x \n",prefix_repc,prefix_repnc,flag_z,flag_c,register_cx);
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
register_cx--; if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
} if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--;
}
clock_counter=clock_counter+12; // Add clocks per loop iteration clock_counter=clock_counter+12; // Add clocks per loop iteration
local_data = Biu_Operation(IO_READ_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , register_dx , 0x00 ); // Fetch the IO byte data at address DX local_data = Biu_Operation(IO_READ_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_00 , register_dx , 0x00 ); // Fetch the IO byte data at address DX
@@ -3169,11 +3229,12 @@ void opcode_0x6C() {
if ( (nmi_latched==1) || (direct_intr_raw!=0 && (flag_i)!=0) ) interrupt_pending=1; else interrupt_pending=0; if ( (nmi_latched==1) || (direct_intr_raw!=0 && (flag_i)!=0) ) interrupt_pending=1; else interrupt_pending=0;
if (flag_d==0) { register_si=register_di + 1; } if (flag_d==0) { register_di=register_di + 1; }
else { register_si=register_di - 1; } else { register_di=register_di - 1; }
} while (prefix_repz==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
//} while ( (prefix_repz==1 && flag_z==1) );
return; return;
@@ -3189,7 +3250,8 @@ void opcode_0x6D() {
if (prefix_repz==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_repz==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_repz==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -3200,11 +3262,11 @@ void opcode_0x6D() {
if ( (nmi_latched==1) || (direct_intr_raw!=0 && (flag_i)!=0) ) interrupt_pending=1; else interrupt_pending=0; if ( (nmi_latched==1) || (direct_intr_raw!=0 && (flag_i)!=0) ) interrupt_pending=1; else interrupt_pending=0;
if (flag_d==0) { register_si=register_di + 2; } if (flag_d==0) { register_di=register_di + 2; }
else { register_si=register_di - 2; } else { register_di=register_di - 2; }
} while (prefix_repz==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -3221,7 +3283,8 @@ void opcode_0x6E() {
if (prefix_repz==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_repz==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_repz==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -3236,7 +3299,7 @@ void opcode_0x6E() {
else { register_si=register_si - 1; } else { register_si=register_si - 1; }
} while (prefix_repz==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -3253,7 +3316,8 @@ void opcode_0x6F() {
if (prefix_repz==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts if (prefix_repz==0) clock_counter=clock_counter+0; else clock_counter=clock_counter+9; // Add initial clock counts
do { do {
if (prefix_repz==1) { if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0 if ( (prefix_repz==1) || (prefix_repnz==1) || (prefix_repc==1) || (prefix_repnc==1) ) {
if (register_cx==0) return; // Exit from loop if repeat prefix and CX=0
if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix if (interrupt_pending==1) { register_ip = register_ip - (prefix_count+1); return; } // Exit from loop to service interrupt - adjusting IP to address of prefix
register_cx--; register_cx--;
} }
@@ -3268,7 +3332,7 @@ void opcode_0x6F() {
else { register_si=register_si - 2; } else { register_si=register_si - 2; }
} while (prefix_repz==1); } while ( (prefix_repz==1 ) || (prefix_repnz==1) || (prefix_repc==1 ) || (prefix_repnc==1 ) );
return; return;
} }
@@ -3283,6 +3347,8 @@ void opcode_0xC0() {
Calculate_EA(); Calculate_EA();
local_byte = pfq_fetch_byte(); local_byte = pfq_fetch_byte();
printf("REG_FIELD %x", REG_field);
if (ea_is_a_register==1) clock_counter=clock_counter-2; else clock_counter=clock_counter+13; if (ea_is_a_register==1) clock_counter=clock_counter-2; else clock_counter=clock_counter+13;
switch (REG_field) { switch (REG_field) {
case 0x0: Writeback_EA(ROL8(Fetch_EA(),local_byte) ); break; // # 0xC0 REG[0] - ROL REG8/MEM8 , IMM8 case 0x0: Writeback_EA(ROL8(Fetch_EA(),local_byte) ); break; // # 0xC0 REG[0] - ROL REG8/MEM8 , IMM8
@@ -3306,6 +3372,8 @@ void opcode_0xC1() {
Calculate_EA(); Calculate_EA();
local_byte = pfq_fetch_byte(); local_byte = pfq_fetch_byte();
printf("REG_FIELD %x", REG_field);
if (ea_is_a_register==1) clock_counter=clock_counter-2; else clock_counter=clock_counter+21; if (ea_is_a_register==1) clock_counter=clock_counter-2; else clock_counter=clock_counter+21;
switch (REG_field) { switch (REG_field) {
case 0x0: Writeback_EA(ROL16(Fetch_EA(),local_byte) ); break; // # 0xC1 REG[0] - ROL REG16/MEM16 , IMM8 case 0x0: Writeback_EA(ROL16(Fetch_EA(),local_byte) ); break; // # 0xC1 REG[0] - ROL REG16/MEM16 , IMM8
@@ -3363,7 +3431,7 @@ void Test1( uint16_t local_data , uint8_t local_bitsel ) {
local_bitmask = (0x01 << local_bitsel); local_bitmask = (0x01 << local_bitsel);
register_flags = (register_flags & 0xF7FF); // Clear O Flag register_flags = (register_flags & 0xF7FE); // Clear O and C Flags
if ( (local_bitmask&local_data) != 0) { register_flags = (register_flags & 0xFFBF); } // Clear Z Flag if ( (local_bitmask&local_data) != 0) { register_flags = (register_flags & 0xFFBF); } // Clear Z Flag
else { register_flags = (register_flags | 0x0040); } // Set Z Flag else { register_flags = (register_flags | 0x0040); } // Set Z Flag
@@ -3399,7 +3467,19 @@ uint16_t Set1( uint16_t local_data , uint8_t local_bitsel ) {
void opcode_0x0F() { void opcode_0x0F() {
uint16_t local_temp; uint16_t ax_temp;
uint16_t ea_temp;
uint16_t temp_si=0;
uint16_t temp_di=0;
uint8_t local_count;
uint8_t local_temp1;
uint8_t local_temp2;
uint8_t local_data1;
uint8_t local_data2;
uint8_t local_sum;
uint8_t local_carry=0;
wait_for_CLK_falling_edge(); // V20 waits one clock between first and second opcode wait_for_CLK_falling_edge(); // V20 waits one clock between first and second opcode
opcode_first_byte = pfq_fetch_byte(); opcode_first_byte = pfq_fetch_byte();
@@ -3427,12 +3507,131 @@ void opcode_0x0F() {
case 0x1D: Calculate_EA();Writeback_EA(Set1(Fetch_EA(),(pfq_fetch_byte()&0x0F) )); break; // Set1 REG16/MEM16 , IMM4 case 0x1D: Calculate_EA();Writeback_EA(Set1(Fetch_EA(),(pfq_fetch_byte()&0x0F) )); break; // Set1 REG16/MEM16 , IMM4
case 0x20: wait_for_CLK_falling_edge(); break; // ADD4S case 0x20: // ADD4S
case 0x22: wait_for_CLK_falling_edge(); break; // SUB4S clock_counter=clock_counter+7; // initial clock count
case 0x26: wait_for_CLK_falling_edge(); break; // CMP4S local_count = ((register_cx & 0x00FF)+1)>>1;
temp_si = register_si;
temp_di = register_di;
register_flags=(register_flags | 0x0040); // Set Z Flag
for (uint8_t i = 0; i < local_count; i++) {
clock_counter=clock_counter+19;
local_data1 = Biu_Operation(MEM_READ_BYTE , SEGMENT_OVERRIDABLE_TRUE , SEGMENT_DS , temp_si , 0x00 ); // Read data from source
local_data2 = Biu_Operation(MEM_READ_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_ES , temp_di , 0x00 ); // Read data from source
local_temp1 = (local_data1>>4)*10 + (local_data1&0xf);
local_temp2 = (local_data2>>4)*10 + (local_data2&0xf);
local_sum = local_temp1 + local_temp2 + local_carry;
if (local_sum>99) local_carry=1; else local_carry=0;
local_sum = local_sum % 100;
local_sum = ((local_sum/10)<<4) | (local_sum % 10);
register_flags = (register_flags & 0xFFFE); // Zero out Flags: C
if (local_carry == 0x1) register_flags=(register_flags | 0x0001); // Set C Flag
if (local_sum != 0x0) register_flags = (register_flags & 0xFFBF); // Zero out Flags: Z
printf("local_sum %x \n",local_sum);
Biu_Operation(MEM_WRITE_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_ES , temp_di , local_sum );
temp_si++;
temp_di++;
}
break;
case 0x22: // SUB4S
clock_counter=clock_counter+7; // initial clock count
local_count = ((register_cx & 0x00FF)+1)>>1;
temp_si = register_si;
temp_di = register_di;
register_flags=(register_flags | 0x0040); // Set Z Flag
for (uint8_t i = 0; i < local_count; i++) {
clock_counter=clock_counter+19;
local_data1 = Biu_Operation(MEM_READ_BYTE , SEGMENT_OVERRIDABLE_TRUE , SEGMENT_DS , temp_si , 0x00 ); // Read data from source
local_data2 = Biu_Operation(MEM_READ_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_ES , temp_di , 0x00 ); // Read data from source
local_temp1 = (local_data1>>4)*10 + (local_data1&0xf);
local_temp2 = (local_data2>>4)*10 + (local_data2&0xf);
if (local_temp1 < (local_temp2+local_carry)) {
local_temp1 = local_temp1 + 100;
local_sum = local_temp1 - (local_temp2+local_carry);
local_carry = 1;
}
else {
local_sum = local_temp1 - (local_temp2+local_carry);
local_carry = 0;
}
local_sum = ((local_sum/10)<<4) | (local_sum % 10);
register_flags = (register_flags & 0xFFFE); // Zero out Flags: C
if (local_carry == 0x1) register_flags=(register_flags | 0x0001); // Set C Flag
if (local_sum != 0x0) register_flags = (register_flags & 0xFFBF); // Zero out Flags: Z
Biu_Operation(MEM_WRITE_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_ES , temp_di , local_sum );
temp_si++;
temp_di++;
}
break;
case 0x26: // CMP4S
clock_counter=clock_counter+7; // initial clock count
local_count = ((register_cx & 0x00FF)+1)>>1;
temp_si = register_si;
temp_di = register_di;
register_flags=(register_flags | 0x0040); // Set Z Flag
for (uint8_t i = 0; i < local_count; i++) {
clock_counter=clock_counter+19;
local_data1 = Biu_Operation(MEM_READ_BYTE , SEGMENT_OVERRIDABLE_TRUE , SEGMENT_DS , temp_si , 0x00 ); // Read data from source
local_data2 = Biu_Operation(MEM_READ_BYTE , SEGMENT_OVERRIDABLE_FALSE , SEGMENT_ES , temp_di , 0x00 ); // Read data from source
local_temp1 = (local_data1>>4)*10 + (local_data1&0xf);
local_temp2 = (local_data2>>4)*10 + (local_data2&0xf);
if (local_temp1 < (local_temp2+local_carry)) {
local_temp1 = local_temp1 + 100;
local_sum = local_temp1 - (local_temp2+local_carry);
local_carry = 1;
}
else {
local_sum = local_temp1 - (local_temp2+local_carry);
local_carry = 0;
}
local_sum = ((local_sum/10)<<4) | (local_sum % 10);
register_flags = (register_flags & 0xFFFE); // Zero out Flags: C
if (local_carry == 0x1) register_flags=(register_flags | 0x0001); // Set C Flag
if (local_sum != 0x0) register_flags = (register_flags & 0xFFBF); // Zero out Flags: Z
temp_si++;
temp_di++;
}
break;
case 0x28: Calculate_EA();
ax_temp = register_ax;
ea_temp = Fetch_EA();
temp16 = (register_ax<<4) | ((ea_temp>>4) & 0x000F) ;
Writeback_EA( (ea_temp<<4) | (ax_temp&0x000F) );
Write_Register(REG_AL, temp16);
break; // ROL4
case 0x2A: Calculate_EA();
ax_temp = register_ax;
ea_temp = Fetch_EA();
temp16 = (ea_temp>>4) | ((register_ax<<4) & 0x00F0);
Writeback_EA( temp16);
Write_Register(REG_AL, (ax_temp&0xFF00) | (ea_temp&0x00FF) );
break; // ROR4
case 0x31: wait_for_CLK_falling_edge(); break; // Invalid
case 0x33: wait_for_CLK_falling_edge(); break; // Invalid
case 0x39: wait_for_CLK_falling_edge(); break; // Invalid
case 0x3B: wait_for_CLK_falling_edge(); break; // Invalid
case 0x28: Calculate_EA(); local_temp=( (Fetch_EA()<<4) | (register_ax&0xF) ); Write_Register(REG_AL, (local_temp>>8)); Writeback_EA(local_temp); break; // ROL4
case 0x2A: Calculate_EA(); local_temp=Fetch_EA(); Writeback_EA( (register_ax<<4)|(local_temp>>4) ); Write_Register(REG_AL, (local_temp&0xF)); break; // ROR4
} }
return; return;
} }
@@ -3557,7 +3756,7 @@ void execute_new_instruction() {
case 0x64: opcode_0x64(); break; case 0x64: opcode_0x64(); break;
case 0x65: opcode_0x65(); break; case 0x65: opcode_0x65(); break;
case 0x66: opcode_0x66(); break; case 0x66: opcode_0x66(); break;
case 0x67: opcode_0x66(); break; case 0x67: opcode_0x77(); break;
case 0x68: opcode_0x68(); break; case 0x68: opcode_0x68(); break;
case 0x69: opcode_0x69(); break; case 0x69: opcode_0x69(); break;
case 0x6A: opcode_0x6A(); break; case 0x6A: opcode_0x6A(); break;