• R/O
  • HTTP
  • SSH
  • HTTPS

common_source_project-fm7: Commit

Common Source Code Project for Qt (a.k.a for FM-7).


Commit MetaInfo

Revisionc91e965dadcf9dc4c837c391c53054c699344e58 (tree)
Zeit2019-04-22 05:44:12
AutorK.Ohta <whatisthis.sowhat@gmai...>
CommiterK.Ohta

Log Message

[VM][I386] Make some functions around address translation INLINE.
[VM][I386] Fix unexpected page fault when accessing memories.
[VM][I386] Try to call pseudo-bios even within protected mode (inside of i386_trap()).
[VM][UPD7220] Temporally disable some debug messages.

Ändern Zusammenfassung

Diff

--- a/source/src/vm/i386.cpp
+++ b/source/src/vm/i386.cpp
@@ -229,7 +229,7 @@ typedef UINT32 offs_t;
229229
230230 //#ifdef I386_PSEUDO_BIOS
231231 #define BIOS_INT(num) if(cpustate->bios != NULL) { \
232- if(((cpustate->cr[0] & 0x0001) == 0) || (cpustate->VM != 0)) { /* VM8086 or Not Protected */ \
232+ /*if(((cpustate->cr[0] & 0x0001) == 0) || (cpustate->VM != 0)) */{ /* VM8086 or Not Protected */ \
233233 uint16_t regs[10], sregs[4]; \
234234 regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); \
235235 regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); \
@@ -253,6 +253,7 @@ if(cpustate->bios->bios_int_i86(num, regs, sregs, &ZeroFlag, &CarryFlag, &(cpust
253253 } \
254254 }
255255
256+
256257 #define BIOS_CALL_FAR(address) if(cpustate->bios != NULL) { \
257258 if(((cpustate->cr[0] & 0x0001) == 0) || (cpustate->VM != 0)) { /* VM8086 or Not Protected */ \
258259 uint16_t regs[10], sregs[4]; \
@@ -277,6 +278,33 @@ if(cpustate->bios->bios_int_i86(num, regs, sregs, &ZeroFlag, &CarryFlag, &(cpust
277278 } \
278279 } \
279280 }
281+
282+
283+#define BIOS_TRAP(address,stat) if(cpustate->bios != NULL) { \
284+ if(((cpustate->cr[0] & 0x0001) == 0) || (cpustate->VM != 0)) { /* VM8086 or Not Protected */ \
285+ uint16_t regs[10], sregs[4]; \
286+ regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); \
287+ regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); \
288+ regs[8] = 0x0000; regs[9] = 0x0000; \
289+ sregs[0] = cpustate->sreg[ES].selector; sregs[1] = cpustate->sreg[CS].selector; \
290+ sregs[2] = cpustate->sreg[SS].selector; sregs[3] = cpustate->sreg[DS].selector; \
291+ int32_t ZeroFlag = cpustate->ZF, CarryFlag = cpustate->CF; \
292+ stat = 0; \
293+ if(cpustate->bios->bios_call_far_i86(address, regs, sregs, &ZeroFlag, &CarryFlag, &(cpustate->cycles), &(cpustate->total_cycles))) { \
294+ REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; \
295+ REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; \
296+ cpustate->ZF = (UINT8)ZeroFlag; cpustate->CF = (UINT8)CarryFlag; \
297+ /*CYCLES(cpustate,CYCLES_RET_INTERSEG);*/ \
298+ if((regs[8] != 0x0000) || (regs[9] != 0x0000)) { \
299+ uint32_t hi = regs[9]; \
300+ uint32_t lo = regs[8]; \
301+ uint32_t addr = (hi << 16) | lo; \
302+ cpustate->eip = addr; \
303+ } \
304+ stat = 1; \
305+ } \
306+ } \
307+ }
280308 //#endif
281309
282310 static CPU_TRANSLATE(i386);
--- a/source/src/vm/mame/emu/cpu/i386/i386.c
+++ b/source/src/vm/mame/emu/cpu/i386/i386.c
@@ -524,7 +524,7 @@ static void i386_check_sreg_validity(i386_state* cpustate, int reg)
524524 i386_load_segment_descriptor(cpustate,reg);
525525 }
526526 }
527-
527+#if 0
528528 static int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32 size)
529529 {
530530 if(PROTECTED_MODE && !V8086_MODE)
@@ -549,7 +549,7 @@ static int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32
549549 }
550550 return 0;
551551 }
552-
552+#endif
553553 static void i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, bool *fault)
554554 {
555555 // Checks done when MOV changes a segment register in protected mode
@@ -1112,6 +1112,50 @@ static void i386_trap(i386_state *cpustate,int irq, int irq_gate, int trap_level
11121112 //cpustate->eflags &= ~0xffc00002;
11131113 cpustate->eflags = get_flags(cpustate);
11141114 set_flags(cpustate, cpustate->eflags);
1115+#if 1
1116+ if((irq >= 0x10) && (irq_gate == 1) && (cpustate->ext == 0)) {
1117+ // Try to call pseudo bios
1118+ i386_load_segment_descriptor(cpustate,CS);
1119+ UINT32 tmp_pc = i386_translate(cpustate, CS, cpustate->eip, -1, 1 );
1120+ int stat = 0;
1121+ BIOS_TRAP(tmp_pc, stat);
1122+ if(stat != 0) { // HIT
1123+ try
1124+ {
1125+ // this is ugly but the alternative is worse
1126+ if(/*type != 0x0e && type != 0x0f*/ (type & 0x08) == 0) // if not 386 interrupt or trap gate
1127+ {
1128+ cpustate->eip = POP16(cpustate);
1129+ cpustate->sreg[CS].selector = POP16(cpustate);
1130+ UINT32 __flags = POP16(cpustate);
1131+ cpustate->eflags = (get_flags(cpustate) & 0xffff0000) | (__flags & 0x0000ffff);
1132+ set_flags(cpustate, cpustate->eflags);
1133+ }
1134+ else
1135+ {
1136+ cpustate->eip = POP32(cpustate);
1137+ UINT32 sel;
1138+ sel = POP32(cpustate);
1139+ cpustate->sreg[CS].selector = sel; // ToDo: POP32SEG()
1140+ UINT32 __flags = POP32(cpustate);
1141+ cpustate->eflags = (get_flags(cpustate) & 0xff000000) | (__flags & 0x00ffffff);
1142+ set_flags(cpustate, cpustate->eflags);
1143+ }
1144+ }
1145+ catch(UINT64 e)
1146+ {
1147+ REG32(ESP) = tempSP;
1148+ logerror("THROWN EXCEPTION %08X at i386_trap() IRQ=%02x EIP=%08x V8086_MODE=%s line %d\n", e, irq, cpustate->eip, (V8086_MODE) ? "Yes" : "No", __LINE__);
1149+ throw e;
1150+ }
1151+ return;
1152+ }
1153+ // Not HIT
1154+ CHANGE_PC(cpustate,cpustate->eip);
1155+ return;
1156+ }
1157+#endif
1158+
11151159 }
11161160
11171161 i386_load_segment_descriptor(cpustate,CS);
@@ -3665,7 +3709,10 @@ static CPU_EXECUTE( i386 )
36653709 while( cpustate->cycles > 0 && !cpustate->busreq )
36663710 {
36673711 //#ifdef USE_DEBUGGER
3668- bool now_debugging = cpustate->debugger->now_debugging;
3712+ bool now_debugging = false;
3713+ if(cpustate->debugger != NULL) {
3714+ now_debugging = cpustate->debugger->now_debugging;
3715+ }
36693716 if(now_debugging) {
36703717 cpustate->debugger->check_break_points(cpustate->pc);
36713718 if(cpustate->debugger->now_suspended) {
@@ -3766,7 +3813,7 @@ static CPU_EXECUTE( i386 )
37663813 int old_tf = cpustate->TF;
37673814
37683815 //#ifdef USE_DEBUGGER
3769- cpustate->debugger->add_cpu_trace(cpustate->pc);
3816+ if(cpustate->debugger != NULL) cpustate->debugger->add_cpu_trace(cpustate->pc);
37703817 //#endif
37713818 cpustate->segment_prefix = 0;
37723819 cpustate->prev_eip = cpustate->eip;
--- a/source/src/vm/mame/emu/cpu/i386/i386ops.c
+++ b/source/src/vm/mame/emu/cpu/i386/i386ops.c
@@ -2523,19 +2523,19 @@ static void I386OP(int_16)(i386_state *cpustate) // Opcode 0xcd
25232523 CYCLES(cpustate,CYCLES_INT);
25242524 if(V8086_MODE) {
25252525 //logerror("INT %02xh @V8086(16bit) mode PC=%08X\n", interrupt, cpustate->pc - 1);
2526- if((!cpustate->IOP1 || !cpustate->IOP2))
2527- {
2528- logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
2529- FAULT(FAULT_GP,0);
2530- } else {
2526+// if((!cpustate->IOP1 || !cpustate->IOP2))
2527+// {
2528+// logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
2529+// FAULT(FAULT_GP,0);
2530+// } else {
25312531 BIOS_INT(interrupt);
2532- }
2532+// }
25332533 } else {
25342534 //logerror("INT %02xh @16bit mode PC=%08X\n", interrupt, cpustate->pc - 1);
2535- UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
2536- if(!(PROTECTED_MODE && (cpustate->CPL > IOPL))) {
2535+// UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
2536+// if(!(PROTECTED_MODE && (cpustate->CPL > IOPL))) {
25372537 BIOS_INT(interrupt);
2538- }
2538+// }
25392539 }
25402540 cpustate->ext = 0; // not an external interrupt
25412541 i386_trap(cpustate,interrupt, 1, 0);
@@ -2549,19 +2549,19 @@ static void I386OP(int_32)(i386_state *cpustate) // Opcode 0xcd
25492549 #if 1
25502550 if(V8086_MODE) {
25512551 //logerror("INT %02xh @V8086(32bit) mode PC=%08X\n", interrupt, cpustate->pc - 1);
2552- if((!cpustate->IOP1 || !cpustate->IOP2))
2553- {
2554- logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
2555- FAULT(FAULT_GP,0);
2556- } else {
2552+// if((!cpustate->IOP1 || !cpustate->IOP2))
2553+// {
2554+// logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
2555+// FAULT(FAULT_GP,0);
2556+// } else {
25572557 BIOS_INT(interrupt);
2558- }
2558+// }
25592559 } else {
25602560 //logerror("INT %02xh @32bit mode PC=%08X\n", interrupt, cpustate->pc - 1);
2561- UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
2562- if(!(PROTECTED_MODE && (cpustate->CPL > IOPL))) {
2561+// UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
2562+// if(!(PROTECTED_MODE && (cpustate->CPL > IOPL))) {
25632563 BIOS_INT(interrupt);
2564- }
2564+// }
25652565 }
25662566 #endif
25672567 cpustate->ext = 0; // not an external interrupt
--- a/source/src/vm/mame/emu/cpu/i386/i386priv.h
+++ b/source/src/vm/mame/emu/cpu/i386/i386priv.h
@@ -561,7 +561,7 @@ struct i386_state
561561 };
562562
563563 extern int i386_parity_table[256];
564-static int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32 size);
564+//static int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32 size);
565565
566566 #define FAULT_THROW(fault,error) { \
567567 /*logerror("FAULT_THROW(%s , %s)\n", #fault , #error );*/ \
@@ -664,6 +664,31 @@ extern MODRM_TABLE i386_MODRM_table[256];
664664
665665 /***********************************************************************************/
666666
667+INLINE int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32 size)
668+{
669+ if(PROTECTED_MODE && !V8086_MODE)
670+ {
671+ if((cpustate->sreg[seg].flags & 0x0018) == 0x0010 && cpustate->sreg[seg].flags & 0x0004) // if expand-down data segment
672+ {
673+ // compare if greater then 0xffffffff when we're passed the access size
674+ if(((offset + size - 1) <= cpustate->sreg[seg].limit) || ((cpustate->sreg[seg].d)?0:((offset + size - 1) > 0xffff)))
675+ {
676+ logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x (expand-down)\n",cpustate->pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
677+ return 1;
678+ }
679+ }
680+ else
681+ {
682+ if((offset + size - 1) > cpustate->sreg[seg].limit)
683+ {
684+ logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x\n",cpustate->pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
685+ return 1;
686+ }
687+ }
688+ }
689+ return 0;
690+}
691+
667692 INLINE UINT32 i386_translate(i386_state *cpustate, int segment, UINT32 ip, int rwn, UINT32 size)
668693 {
669694 // TODO: segment limit access size, execution permission, handle exception thrown from exception handler
@@ -693,7 +718,7 @@ INLINE vtlb_entry get_permissions(UINT32 pte, int wp)
693718 return ret;
694719 }
695720
696-static int i386_translate_address(i386_state *cpustate, int intention, offs_t *address, vtlb_entry *entry)
721+INLINE int i386_translate_address(i386_state *cpustate, int intention, offs_t *address, vtlb_entry *entry)
697722 {
698723 UINT32 a = *address;
699724 UINT32 pdbr = cpustate->cr[3] & 0xfffff000;// I386_CR3_PD_MASK
@@ -781,7 +806,7 @@ static int i386_translate_address(i386_state *cpustate, int intention, offs_t *a
781806 return ret;
782807 }
783808
784-static int i386_translate_address_with_width(i386_state *cpustate, int intention, int width, offs_t *address, vtlb_entry *entry)
809+INLINE int i386_translate_address_with_width(i386_state *cpustate, int intention, int width, offs_t *address, vtlb_entry *entry)
785810 {
786811 UINT32 a = *address;
787812 UINT32 pdbr = cpustate->cr[3] & 0xfffff000;// I386_CR3_PD_MASK
@@ -878,7 +903,7 @@ static int i386_translate_address_with_width(i386_state *cpustate, int intention
878903
879904 //#define TEST_TLB
880905
881-static /*INLINE*/ int translate_address(i386_state *cpustate, int pl, int type, UINT32 *address, UINT32 *error)
906+INLINE int translate_address(i386_state *cpustate, int pl, int type, UINT32 *address, UINT32 *error)
882907 {
883908 if(!(cpustate->cr[0] & I386_CR0_PG)) // Some (very few) old OS's won't work with this
884909 return TRUE;
@@ -921,7 +946,7 @@ static /*INLINE*/ int translate_address(i386_state *cpustate, int pl, int type,
921946 }
922947
923948
924-static /*INLINE */int translate_address_with_width(i386_state *cpustate, int pl, int type, UINT32 width, UINT32 *address, UINT32 *error)
949+INLINE int translate_address_with_width(i386_state *cpustate, int pl, int type, UINT32 width, UINT32 *address, UINT32 *error)
925950 {
926951 if(!(cpustate->cr[0] & I386_CR0_PG)) // Some (very few) old OS's won't work with this
927952 return TRUE;
@@ -971,8 +996,15 @@ INLINE void CHANGE_PC(i386_state *cpustate, UINT32 pc)
971996 INLINE void NEAR_BRANCH(i386_state *cpustate, INT32 offs)
972997 {
973998 /* TODO: limit */
974- cpustate->eip += offs;
999+// if(i386_limit_check(cpustate, CS, cpustate->eip + offs, 1) != 0) {
1000+// FAULT_THROW(FAULT_GP, 0); //OK?
1001+// }
1002+// UINT32 mask = cpustate->a20_mask;
1003+// cpustate->eip = (cpustate->eip + offs) & mask;
1004+ cpustate->eip = cpustate->eip + offs;
9751005 cpustate->pc += offs;
1006+ // ToDo: Translate a20 mask
1007+// cpustate->pc = i386_translate(cpustate, CS, cpustate->pc + offs, -1, 1 );
9761008 }
9771009
9781010 INLINE UINT8 FETCH(i386_state *cpustate)
@@ -998,15 +1030,16 @@ INLINE UINT16 FETCH16(i386_state *cpustate)
9981030 UINT32 address = cpustate->pc, error;
9991031
10001032 if( !WORD_ALIGNED(address) ) { /* Unaligned read */
1001- if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_FETCH,2,&address,&error))
1002- PF_THROW(error);
1003- UINT32 mask = cpustate->a20_mask;
1004- value = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
1005- value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
1006- cpustate->eip += 2;
1007- cpustate->pc += 2;
1008- //value = (FETCH(cpustate) << 0);
1009- //value |= (FETCH(cpustate) << 8);
1033+ if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_FETCH,2,&address,&error)) {
1034+ value = (FETCH(cpustate) << 0);
1035+ value |= (FETCH(cpustate) << 8);
1036+ } else {
1037+ UINT32 mask = cpustate->a20_mask;
1038+ value = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
1039+ value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
1040+ cpustate->eip += 2;
1041+ cpustate->pc += 2;
1042+ }
10101043 } else {
10111044 if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_FETCH,&address,&error))
10121045 PF_THROW(error);
@@ -1023,19 +1056,26 @@ INLINE UINT32 FETCH32(i386_state *cpustate)
10231056 UINT32 address = cpustate->pc, error;
10241057
10251058 if( !DWORD_ALIGNED(cpustate->pc) ) { /* Unaligned read */
1026- if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_FETCH,4,&address,&error))
1027- PF_THROW(error);
1028- UINT32 mask = cpustate->a20_mask;
1029- value = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
1030- value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
1031- value |= ((cpustate->program->read_data8((address + 2) & mask)) << 16);
1032- value |= ((cpustate->program->read_data8((address + 3) & mask)) << 24);
1033- cpustate->eip += 4;
1034- cpustate->pc += 4;
1035- //value = (FETCH(cpustate) << 0);
1036- //value |= (FETCH(cpustate) << 8);
1037- //value |= (FETCH(cpustate) << 16);
1038- //value |= (FETCH(cpustate) << 24);
1059+ if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_FETCH,4,&address,&error)) {
1060+ value = (FETCH(cpustate) << 0);
1061+ value |= (FETCH(cpustate) << 8);
1062+ value |= (FETCH(cpustate) << 16);
1063+ value |= (FETCH(cpustate) << 24);
1064+ // PF_THROW(error);
1065+ } else {
1066+ UINT32 mask = cpustate->a20_mask;
1067+ if(WORD_ALIGNED(cpustate->pc)) {
1068+ value = ((cpustate->program->read_data16((address + 0) & mask)) << 0);
1069+ value |= ((cpustate->program->read_data16((address + 2) & mask)) << 16);
1070+ } else {
1071+ value = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
1072+ value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
1073+ value |= ((cpustate->program->read_data8((address + 2) & mask)) << 16);
1074+ value |= ((cpustate->program->read_data8((address + 3) & mask)) << 24);
1075+ }
1076+ cpustate->eip += 4;
1077+ cpustate->pc += 4;
1078+ }
10391079 } else {
10401080 if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_FETCH,&address,&error))
10411081 PF_THROW(error);
@@ -1064,13 +1104,15 @@ INLINE UINT16 READ16(i386_state *cpustate,UINT32 ea)
10641104 UINT32 address = ea, error;
10651105
10661106 if( !WORD_ALIGNED(ea) ) { /* Unaligned read */
1067- if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,2,&address,&error))
1068- PF_THROW(error);
1069- UINT32 mask = cpustate->a20_mask;
1070- value = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
1071- value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
1072- //value = (READ8( cpustate, address+0 ) << 0);
1073- //value |= (READ8( cpustate, address+1 ) << 8);
1107+ if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,2,&address,&error)) {
1108+ // PF_THROW(error);
1109+ value = (READ8( cpustate, address+0 ) << 0);
1110+ value |= (READ8( cpustate, address+1 ) << 8);
1111+ } else {
1112+ UINT32 mask = cpustate->a20_mask;
1113+ value = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
1114+ value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
1115+ }
10741116 } else {
10751117 if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_READ,&address,&error))
10761118 PF_THROW(error);
@@ -1086,17 +1128,23 @@ INLINE UINT32 READ32(i386_state *cpustate,UINT32 ea)
10861128 UINT32 address = ea, error;
10871129
10881130 if( !DWORD_ALIGNED(ea) ) { /* Unaligned read */
1089- if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,4,&address,&error))
1090- PF_THROW(error);
1091- UINT32 mask = cpustate->a20_mask;
1092- value = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
1093- value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
1094- value |= ((cpustate->program->read_data8((address + 2) & mask)) << 16);
1095- value |= ((cpustate->program->read_data8((address + 3) & mask)) << 24);
1096- //value = (READ8( cpustate, address+0 ) << 0);
1097- //value |= (READ8( cpustate, address+1 ) << 8);
1098- //value |= (READ8( cpustate, address+2 ) << 16),
1099- //value |= (READ8( cpustate, address+3 ) << 24);
1131+ if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,4,&address,&error)) {
1132+ value = (READ8( cpustate, address+0 ) << 0);
1133+ value |= (READ8( cpustate, address+1 ) << 8);
1134+ value |= (READ8( cpustate, address+2 ) << 16);
1135+ value |= (READ8( cpustate, address+3 ) << 24);
1136+ } else {
1137+ UINT32 mask = cpustate->a20_mask;
1138+ if(WORD_ALIGNED(ea)) {
1139+ value = ((cpustate->program->read_data16((address + 0) & mask)) << 0);
1140+ value |= ((cpustate->program->read_data16((address + 2) & mask)) << 16);
1141+ } else {
1142+ value = ((cpustate->program->read_data8((address + 0) & mask)) << 0);
1143+ value |= ((cpustate->program->read_data8((address + 1) & mask)) << 8);
1144+ value |= ((cpustate->program->read_data8((address + 2) & mask)) << 16);
1145+ value |= ((cpustate->program->read_data8((address + 3) & mask)) << 24);
1146+ }
1147+ }
11001148 } else {
11011149 if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_READ,&address,&error))
11021150 PF_THROW(error);
@@ -1113,30 +1161,39 @@ INLINE UINT64 READ64(i386_state *cpustate,UINT32 ea)
11131161 UINT32 address = ea, error;
11141162
11151163 if( !QWORD_ALIGNED(ea) ) { /* Unaligned read */
1116- if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,8,&address,&error))
1117- PF_THROW(error);
1118- UINT32 mask = cpustate->a20_mask;
1119- if(!DWORD_ALIGNED(ea)) {
1120- value = (((UINT64)cpustate->program->read_data8((address + 0) & mask)) << 0);
1121- value |= (((UINT64)cpustate->program->read_data8((address + 1) & mask)) << 8);
1122- value |= (((UINT64)cpustate->program->read_data8((address + 2) & mask)) << 16);
1123- value |= (((UINT64)cpustate->program->read_data8((address + 3) & mask)) << 24);
1124- value |= (((UINT64)cpustate->program->read_data8((address + 4) & mask)) << 32);
1125- value |= (((UINT64)cpustate->program->read_data8((address + 5) & mask)) << 40);
1126- value |= (((UINT64)cpustate->program->read_data8((address + 6) & mask)) << 48);
1127- value |= (((UINT64)cpustate->program->read_data8((address + 7) & mask)) << 56);
1128- } else { // Align of 4
1129- value = (((UINT64) cpustate->program->read_data32( (address+0) & mask )) << 0);
1130- value |= (((UINT64) cpustate->program->read_data32( (address+4) & mask )) << 32);
1131- }
1132-// value = (((UINT64) READ8( cpustate, address+0 )) << 0);
1133-// value |= (((UINT64) READ8( cpustate, address+1 )) << 8);
1134-// value |= (((UINT64) READ8( cpustate, address+2 )) << 16);
1135-// value |= (((UINT64) READ8( cpustate, address+3 )) << 24);
1136-// value |= (((UINT64) READ8( cpustate, address+4 )) << 32);
1137-// value |= (((UINT64) READ8( cpustate, address+5 )) << 40);
1138-// value |= (((UINT64) READ8( cpustate, address+6 )) << 48);
1139-// value |= (((UINT64) READ8( cpustate, address+7 )) << 56);
1164+ if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_READ,8,&address,&error)) {
1165+ value = (((UINT64) READ8( cpustate, address+0 )) << 0);
1166+ value |= (((UINT64) READ8( cpustate, address+1 )) << 8);
1167+ value |= (((UINT64) READ8( cpustate, address+2 )) << 16);
1168+ value |= (((UINT64) READ8( cpustate, address+3 )) << 24);
1169+ value |= (((UINT64) READ8( cpustate, address+4 )) << 32);
1170+ value |= (((UINT64) READ8( cpustate, address+5 )) << 40);
1171+ value |= (((UINT64) READ8( cpustate, address+6 )) << 48);
1172+ value |= (((UINT64) READ8( cpustate, address+7 )) << 56);
1173+ } else {
1174+ // PF_THROW(error);
1175+ UINT32 mask = cpustate->a20_mask;
1176+ if(!DWORD_ALIGNED(ea)) {
1177+ if(WORD_ALIGNED(ea)) { // Aligned by 2
1178+ value = (((UINT64)cpustate->program->read_data16((address + 0) & mask)) << 0);
1179+ value |= (((UINT64)cpustate->program->read_data16((address + 2) & mask)) << 16);
1180+ value |= (((UINT64)cpustate->program->read_data16((address + 4) & mask)) << 32);
1181+ value |= (((UINT64)cpustate->program->read_data16((address + 6) & mask)) << 48);
1182+ } else { // never aligned
1183+ value = (((UINT64)cpustate->program->read_data8((address + 0) & mask)) << 0);
1184+ value |= (((UINT64)cpustate->program->read_data8((address + 1) & mask)) << 8);
1185+ value |= (((UINT64)cpustate->program->read_data8((address + 2) & mask)) << 16);
1186+ value |= (((UINT64)cpustate->program->read_data8((address + 3) & mask)) << 24);
1187+ value |= (((UINT64)cpustate->program->read_data8((address + 4) & mask)) << 32);
1188+ value |= (((UINT64)cpustate->program->read_data8((address + 5) & mask)) << 40);
1189+ value |= (((UINT64)cpustate->program->read_data8((address + 6) & mask)) << 48);
1190+ value |= (((UINT64)cpustate->program->read_data8((address + 7) & mask)) << 56);
1191+ }
1192+ } else { // Align of 4
1193+ value = (((UINT64) cpustate->program->read_data32( (address+0) & mask )) << 0);
1194+ value |= (((UINT64) cpustate->program->read_data32( (address+4) & mask )) << 32);
1195+ }
1196+ }
11401197 } else {
11411198 if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_READ,&address,&error))
11421199 PF_THROW(error);
@@ -1164,10 +1221,13 @@ INLINE UINT16 READ16PL0(i386_state *cpustate,UINT32 ea)
11641221
11651222 if( !WORD_ALIGNED(ea) ) { /* Unaligned read */
11661223 UINT32 mask = cpustate->a20_mask;
1167- if(!translate_address_with_width(cpustate,0,TRANSLATE_READ,2,&address,&error))
1168- PF_THROW(error);
1169- value = cpustate->program->read_data8((address + 0) & mask);
1170- value |= (cpustate->program->read_data8((address + 1) & mask) << 8);
1224+ if(!translate_address_with_width(cpustate,0,TRANSLATE_READ,2,&address,&error)) {
1225+ value = READ8PL0(cpustate, ea + 0);
1226+ value |= (READ8PL0(cpustate, ea + 1) << 8);
1227+ } else {
1228+ value = cpustate->program->read_data8((address + 0) & mask);
1229+ value |= (cpustate->program->read_data8((address + 1) & mask) << 8);
1230+ }
11711231 } else {
11721232 if(!translate_address(cpustate,0,TRANSLATE_READ,&address,&error))
11731233 PF_THROW(error);
@@ -1185,12 +1245,22 @@ INLINE UINT32 READ32PL0(i386_state *cpustate,UINT32 ea)
11851245
11861246 if( !DWORD_ALIGNED(ea) ) { /* Unaligned read */
11871247 UINT32 mask = cpustate->a20_mask;
1188- if(!translate_address_with_width(cpustate,0,TRANSLATE_READ,4,&address,&error))
1189- PF_THROW(error);
1190- value = cpustate->program->read_data8((address + 0) & mask);
1191- value |= (cpustate->program->read_data8((address + 1) & mask) << 8);
1192- value |= (cpustate->program->read_data8((address + 2) & mask) << 16);
1193- value |= (cpustate->program->read_data8((address + 3) & mask) << 24);
1248+ if(!translate_address_with_width(cpustate,0,TRANSLATE_READ,4,&address,&error)) {
1249+ value = READ8PL0(cpustate, ea + 0);
1250+ value |= (READ8PL0(cpustate, ea + 1) << 8);
1251+ value |= (READ8PL0(cpustate, ea + 2) << 16);
1252+ value |= (READ8PL0(cpustate, ea + 3) << 24);
1253+ } else {
1254+ if(WORD_ALIGNED(ea)) {
1255+ value = cpustate->program->read_data16((address + 0) & mask);
1256+ value |= (cpustate->program->read_data16((address + 2) & mask) << 16);
1257+ } else {
1258+ value = cpustate->program->read_data8((address + 0) & mask);
1259+ value |= (cpustate->program->read_data8((address + 1) & mask) << 8);
1260+ value |= (cpustate->program->read_data8((address + 2) & mask) << 16);
1261+ value |= (cpustate->program->read_data8((address + 3) & mask) << 24);
1262+ }
1263+ }
11941264 } else {
11951265 if(!translate_address(cpustate,0,TRANSLATE_READ,&address,&error))
11961266 PF_THROW(error);
@@ -1223,8 +1293,14 @@ INLINE void WRITE16(i386_state *cpustate,UINT32 ea, UINT16 value)
12231293 UINT32 address = ea, error;
12241294
12251295 if( !WORD_ALIGNED(ea) ) { /* Unaligned write */
1226- WRITE8( cpustate, address+0, value & 0xff );
1227- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
1296+ if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_WRITE,2,&address,&error)) {
1297+ WRITE8( cpustate, address+0, value & 0xff );
1298+ WRITE8( cpustate, address+1, (value >> 8) & 0xff );
1299+ } else {
1300+ uint32_t mask = cpustate->a20_mask;
1301+ cpustate->program->write_data8((address + 0) & mask, value & 0xff);
1302+ cpustate->program->write_data8((address + 1) & mask, (value >> 8) & 0xff);
1303+ }
12281304 } else {
12291305 if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_WRITE,&address,&error))
12301306 PF_THROW(error);
@@ -1238,10 +1314,23 @@ INLINE void WRITE32(i386_state *cpustate,UINT32 ea, UINT32 value)
12381314 UINT32 address = ea, error;
12391315
12401316 if( !DWORD_ALIGNED(ea) ) { /* Unaligned write */
1241- WRITE8( cpustate, address+0, value & 0xff );
1242- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
1243- WRITE8( cpustate, address+2, (value >> 16) & 0xff );
1244- WRITE8( cpustate, address+3, (value >> 24) & 0xff );
1317+ if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_WRITE,4,&address,&error)) {
1318+ WRITE8( cpustate, address+0, value & 0xff );
1319+ WRITE8( cpustate, address+1, (value >> 8) & 0xff );
1320+ WRITE8( cpustate, address+2, (value >> 16) & 0xff );
1321+ WRITE8( cpustate, address+3, (value >> 24) & 0xff );
1322+ } else {
1323+ uint32_t mask = cpustate->a20_mask;
1324+ if(!WORD_ALIGNED(ea)) {
1325+ cpustate->program->write_data8((address + 0) & mask, value & 0xff);
1326+ cpustate->program->write_data8((address + 1) & mask, (value >> 8) & 0xff);
1327+ cpustate->program->write_data8((address + 2) & mask, (value >> 16) & 0xff);
1328+ cpustate->program->write_data8((address + 3) & mask, (value >> 24) & 0xff);
1329+ } else { // Aligned by 2
1330+ cpustate->program->write_data16((address + 0) & mask, value & 0xffff);
1331+ cpustate->program->write_data16((address + 2) & mask, (value >> 16) & 0xffff);
1332+ }
1333+ }
12451334 } else {
12461335 if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_WRITE,&address,&error))
12471336 PF_THROW(error);
@@ -1256,14 +1345,36 @@ INLINE void WRITE64(i386_state *cpustate,UINT32 ea, UINT64 value)
12561345 UINT32 address = ea, error;
12571346
12581347 if( !QWORD_ALIGNED(ea) ) { /* Unaligned write */
1259- WRITE8( cpustate, address+0, value & 0xff );
1260- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
1261- WRITE8( cpustate, address+2, (value >> 16) & 0xff );
1262- WRITE8( cpustate, address+3, (value >> 24) & 0xff );
1263- WRITE8( cpustate, address+4, (value >> 32) & 0xff );
1264- WRITE8( cpustate, address+5, (value >> 40) & 0xff );
1265- WRITE8( cpustate, address+6, (value >> 48) & 0xff );
1266- WRITE8( cpustate, address+7, (value >> 56) & 0xff );
1348+ if(!translate_address_with_width(cpustate,cpustate->CPL,TRANSLATE_WRITE,8,&address,&error)) {
1349+ WRITE8( cpustate, address+0, value & 0xff );
1350+ WRITE8( cpustate, address+1, (value >> 8) & 0xff );
1351+ WRITE8( cpustate, address+2, (value >> 16) & 0xff );
1352+ WRITE8( cpustate, address+3, (value >> 24) & 0xff );
1353+ WRITE8( cpustate, address+4, (value >> 32) & 0xff );
1354+ WRITE8( cpustate, address+5, (value >> 40) & 0xff );
1355+ WRITE8( cpustate, address+6, (value >> 48) & 0xff );
1356+ WRITE8( cpustate, address+7, (value >> 56) & 0xff );
1357+ } else {
1358+ uint32_t mask = cpustate->a20_mask;
1359+ if(DWORD_ALIGNED(ea)) { // Aligned by 4
1360+ cpustate->program->write_data32((address + 0) & mask, value & 0xffffffff);
1361+ cpustate->program->write_data32((address + 4) & mask, (value >> 32) & 0xffffffff);
1362+ } else if(!WORD_ALIGNED(ea)) { // Never aligned
1363+ cpustate->program->write_data8((address + 0) & mask, value & 0xff);
1364+ cpustate->program->write_data8((address + 1) & mask, (value >> 8) & 0xff);
1365+ cpustate->program->write_data8((address + 2) & mask, (value >> 16) & 0xff);
1366+ cpustate->program->write_data8((address + 3) & mask, (value >> 24) & 0xff);
1367+ cpustate->program->write_data8((address + 4) & mask, (value >> 32) & 0xff);
1368+ cpustate->program->write_data8((address + 5) & mask, (value >> 40) & 0xff);
1369+ cpustate->program->write_data8((address + 6) & mask, (value >> 48) & 0xff);
1370+ cpustate->program->write_data8((address + 7) & mask, (value >> 56) & 0xff);
1371+ } else { // Aligned by 2
1372+ cpustate->program->write_data16((address + 0) & mask, value & 0xffff);
1373+ cpustate->program->write_data16((address + 2) & mask, (value >> 16) & 0xffff);
1374+ cpustate->program->write_data16((address + 4) & mask, (value >> 32) & 0xffff);
1375+ cpustate->program->write_data16((address + 6) & mask, (value >> 48) & 0xffff);
1376+ }
1377+ }
12671378 } else {
12681379 if(!translate_address(cpustate,cpustate->CPL,TRANSLATE_WRITE,&address,&error))
12691380 PF_THROW(error);
--- a/source/src/vm/upd7220.cpp
+++ b/source/src/vm/upd7220.cpp
@@ -582,7 +582,7 @@ void UPD7220::write_io8(uint32_t addr, uint32_t data)
582582 {
583583 switch(addr & 3) {
584584 case 0: // set parameter
585- this->out_debug_log(_T("\tPARAM = %2x\n"), data);
585+ //this->out_debug_log(_T("\tPARAM = %2x\n"), data);
586586 //if(cmd_ready) { // OK?
587587 if(cmdreg != -1) {
588588 cmd_fifo->write(data & 0xff);
@@ -605,7 +605,7 @@ void UPD7220::write_io8(uint32_t addr, uint32_t data)
605605 vectw_ptr = 0;
606606 csrw_ptr = 0;
607607 cmdreg = (int)data & 0xff;
608- this->out_debug_log(_T("CMDREG = %2x\n"), cmdreg);
608+ //this->out_debug_log(_T("CMDREG = %2x\n"), cmdreg);
609609 // params_count = 0;
610610 cmd_fifo->clear(); // OK?
611611 check_cmd();
@@ -1252,7 +1252,7 @@ void UPD7220::draw_vectl()
12521252 {
12531253 pattern = ra[8] | (ra[9] << 8);
12541254
1255- out_debug_log(_T("DRAW VECTL: X=%d Y=%d to DC=%d DIR=%d PATTERN=%04x MODE=%d\n"), dx, dy, dc, dir, pattern, mod);
1255+ //out_debug_log(_T("DRAW VECTL: X=%d Y=%d to DC=%d DIR=%d PATTERN=%04x MODE=%d\n"), dx, dy, dc, dir, pattern, mod);
12561256 if(dc) {
12571257 int x = dx;
12581258 int y = dy;
Show on old repository browser