diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index 1d1b71010..736700930 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -666,50 +666,9 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) addbyte(0x8b); /*MOVL EDX, seg->base*/ addbyte(0x05 | (REG_EDX << 3)); addlong((uint32_t)&seg->base); - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x0f); /*MOVZX EAX, B[EDX+EDI]*/ - addbyte(0xb6); - addbyte(0x04); - addbyte(0x3a); - addbyte(0xeb); /*JMP done*/ - addbyte(4+3+5+4+6+3); - addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addbyte(0x89); /*MOV [ESP], ESI*/ - addbyte(0x34); - addbyte(0x24); - addbyte(0xe8); /*CALL readmemb386l*/ - addlong((uint32_t)readmemb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - addbyte(0x0f); /*MOVZX EAX, AL*/ - addbyte(0xb6); - addbyte(0xc0); - /*done:*/ + addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ + addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + host_reg_mapping[0] = 8; } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) @@ -717,57 +676,9 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) addbyte(0x8b); /*MOVL EDX, seg->base*/ addbyte(0x05 | (REG_EDX << 3)); addlong((uint32_t)&seg->base); - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 1[EDX]*/ - addbyte(0x7a); - addbyte(0x01); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ - addbyte(0xc7); - addlong(0xfff); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); - addbyte(0x0f); /*MOVZX EAX, -1[EDX+EDI]W*/ - addbyte(0xb7); - addbyte(0x44); - addbyte(0x3a); - addbyte(-1); - addbyte(0xeb); /*JMP done*/ - addbyte(4+3+5+4+6+3); - addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addbyte(0x89); /*MOV [ESP], ESI*/ - addbyte(0x34); - addbyte(0x24); - addbyte(0xe8); /*CALL readmemwl*/ - addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); - addbyte(0x85); /*JNE end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - addbyte(0x0f); /*MOVZX EAX, AX*/ - addbyte(0xb7); - addbyte(0xc0); - /*done:*/ + addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ + addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + host_reg_mapping[0] = 8; } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) @@ -775,53 +686,10 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) addbyte(0x8b); /*MOVL EDX, seg->base*/ addbyte(0x05 | (REG_EDX << 3)); addlong((uint32_t)&seg->base); - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 3[EDX]*/ - addbyte(0x7a); - addbyte(0x03); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ - addbyte(0xc7); - addlong(0xffc); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x8b); /*MOV EAX, -3[EDX+EDI]*/ - addbyte(0x44); - addbyte(0x3a); - addbyte(-3); - addbyte(0xeb); /*JMP done*/ - addbyte(4+3+5+4+6); - addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addbyte(0x89); /*MOV [ESP], ESI*/ - addbyte(0x34); - addbyte(0x24); - addbyte(0xe8); /*CALL readmemll*/ - addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); - addbyte(0x85); /*JNE end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ + addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; } @@ -830,57 +698,9 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) addbyte(0x8b); /*MOVL EDX, seg->base*/ addbyte(0x05 | (REG_EDX << 3)); addlong((uint32_t)&seg->base); - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 7[EDX]*/ - addbyte(0x7a); - addbyte(0x07); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ - addbyte(0xc7); - addlong(0xff8); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+4+2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+4+2); - addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x44); - addbyte(0x3a); - addbyte(-7); - addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ - addbyte(0x54); - addbyte(0x3a); - addbyte(-7+4); - addbyte(0xeb); /*JMP done*/ - addbyte(4+3+5+4+6); - addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addbyte(0x89); /*MOV [ESP], ESI*/ - addbyte(0x34); - addbyte(0x24); - addbyte(0xe8); /*CALL readmemql*/ - addlong((uint32_t)readmemql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); - addbyte(0x85); /*JNE end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ + addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + host_reg_mapping[0] = 8; } @@ -908,230 +728,57 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(0x8b); /*MOVL ESI, seg->base*/ addbyte(0x05 | (REG_ESI << 3)); addlong((uint32_t)&seg->base); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x88); /*MOV [EDI+ESI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(4+5+4+3+5+4+6); - addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addbyte(0xa1); /*MOV EAX, seg->base*/ - addlong((uint32_t)&seg->base); - addbyte(0x89); /*MOV [ESP+8], host_reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(0x24); - addbyte(0x08); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xe8); /*CALL writememb386l*/ - addlong((uint32_t)writememb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + if (host_reg != REG_ECX) + { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ + addlong(mem_store_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { addbyte(0x8b); /*MOVL ESI, seg->base*/ addbyte(0x05 | (REG_ESI << 3)); addlong((uint32_t)&seg->base); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 1[ESI]*/ - addbyte(0x7e); - addbyte(0x01); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ - addbyte(0xc7); - addlong(0xfff); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); - addbyte(0x66); /*MOV -1[EDI+ESI],host_reg*/ - addbyte(0x89); - addbyte(0x44 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); - addbyte(0xeb); /*JMP done*/ - addbyte(4+5+4+3+5+4+6); - addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addbyte(0xa1); /*MOV EAX, seg->base*/ - addlong((uint32_t)&seg->base); - addbyte(0x89); /*MOV [ESP+8], host_reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(0x24); - addbyte(0x08); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xe8); /*CALL writememwl*/ - addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + if (host_reg != REG_ECX) + { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_w*/ + addlong(mem_store_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { addbyte(0x8b); /*MOVL ESI, seg->base*/ addbyte(0x05 | (REG_ESI << 3)); addlong((uint32_t)&seg->base); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 3[ESI]*/ - addbyte(0x7e); - addbyte(0x03); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ - addbyte(0xc7); - addlong(0xffc); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x89); /*MOV -3[EDI+ESI],host_reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); - addbyte(0xeb); /*JMP done*/ - addbyte(4+5+4+3+5+4+6); - addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addbyte(0xa1); /*MOV EAX, seg->base*/ - addlong((uint32_t)&seg->base); - addbyte(0x89); /*MOV [ESP+8], host_reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(0x24); - addbyte(0x08); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xe8); /*CALL writememll*/ - addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + if (host_reg != REG_ECX) + { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_l*/ + addlong(mem_store_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) { + if (host_reg != REG_EBX) + { + addbyte(0x89); /*MOV EBX, host_reg*/ + addbyte(0xc0 | REG_EBX | (host_reg << 3)); + } + if (host_reg2 != REG_ECX) + { + addbyte(0x89); /*MOV ECX, host_reg2*/ + addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); + } addbyte(0x8b); /*MOVL ESI, seg->base*/ addbyte(0x05 | (REG_ESI << 3)); addlong((uint32_t)&seg->base); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 7[ESI]*/ - addbyte(0x7e); - addbyte(0x07); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ - addbyte(0xc7); - addlong(0xff8); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+4+2); - addbyte(0x89); /*MOV [EDI+ESI],host_reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); - addbyte(0x89); /*MOV [EDI+ESI+4],host_reg2*/ - addbyte(0x44 | (host_reg2 << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7+0x04); - addbyte(0xeb); /*JMP done*/ - addbyte(4+5+4+4+3+5+4+6); - addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addbyte(0xa1); /*MOV EAX, seg->base*/ - addlong((uint32_t)&seg->base); - addbyte(0x89); /*MOV [ESP+8], host_reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(0x24); - addbyte(0x08); - addbyte(0x89); /*MOV [ESP+12], host_reg2*/ - addbyte(0x44 | (host_reg2 << 3)); - addbyte(0x24); - addbyte(0x0c); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xe8); /*CALL writememql*/ - addlong((uint32_t)writememql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ + addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } static void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) diff --git a/src/codegen_x86.c b/src/codegen_x86.c index a0288fcd5..6a688b407 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -59,6 +59,452 @@ static uint32_t last_op32; static x86seg *last_ea_seg; static int last_ssegs; +static uint32_t mem_abrt_rout; +uint32_t mem_load_addr_ea_b; +uint32_t mem_load_addr_ea_w; +uint32_t mem_load_addr_ea_l; +uint32_t mem_load_addr_ea_q; +uint32_t mem_store_addr_ea_b; +uint32_t mem_store_addr_ea_w; +uint32_t mem_store_addr_ea_l; +uint32_t mem_store_addr_ea_q; + +static uint32_t gen_MEM_LOAD_ADDR_EA_B() +{ + uint32_t addr = &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t)readlookup2); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4+1); + addbyte(0x0f); /*MOVZX EAX, B[EDX+EDI]*/ + addbyte(0xb6); + addbyte(0x04); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x50); /*slowpath: PUSH EAX*/ + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmembl*/ + addlong((uint32_t)readmemb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte(cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*MOVZX EAX, AL*/ + addbyte(0xb6); + addbyte(0xc0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t gen_MEM_LOAD_ADDR_EA_W() +{ + uint32_t addr = &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x8d); /*LEA EDI, 1[EDX]*/ + addbyte(0x7a); + addbyte(0x01); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xc7); + addlong(0xfff); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t)readlookup2); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+2+5+1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(5+1); + addbyte(0x0f); /*MOVZX EAX, -1[EDX+EDI]W*/ + addbyte(0xb7); + addbyte(0x44); + addbyte(0x3a); + addbyte(-1); + addbyte(0xc3); /*RET*/ + + addbyte(0x50); /*slowpath: PUSH EAX*/ + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemwl*/ + addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte(cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*MOVZX EAX, AX*/ + addbyte(0xb7); + addbyte(0xc0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t gen_MEM_LOAD_ADDR_EA_L() +{ + uint32_t addr = &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x8d); /*LEA EDI, 3[EDX]*/ + addbyte(0x7a); + addbyte(0x03); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xc7); + addlong(0xffc); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t)readlookup2); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+2+4+1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4+1); + addbyte(0x8b); /*MOV EAX, -3[EDX+EDI]*/ + addbyte(0x44); + addbyte(0x3a); + addbyte(-3); + addbyte(0xc3); /*RET*/ + + addbyte(0x50); /*slowpath: PUSH EAX*/ + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemll*/ + addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte(cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t gen_MEM_LOAD_ADDR_EA_Q() +{ + uint32_t addr = &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x8d); /*LEA EDI, 7[EDX]*/ + addbyte(0x7a); + addbyte(0x07); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xc7); + addlong(0xff8); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t)readlookup2); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+2+4+4+1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4+4+1); + addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ + addbyte(0x44); + addbyte(0x3a); + addbyte(-7); + addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ + addbyte(0x54); + addbyte(0x3a); + addbyte(-7+4); + addbyte(0xc3); /*RET*/ + + addbyte(0x50); /*slowpath: PUSH EAX*/ + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemql*/ + addlong((uint32_t)readmemql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte(cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t gen_MEM_STORE_ADDR_EA_B() +{ + uint32_t addr = &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t)writelookup2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+1); + addbyte(0x88); /*MOV [EDI+ESI],CL*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x50); /*PUSH EAX*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememb386l*/ + addlong((uint32_t)writememb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 12*/ + addbyte(0xc4); + addbyte(12); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte(cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t gen_MEM_STORE_ADDR_EA_W() +{ + uint32_t addr = &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x8d); /*LEA EDI, 1[ESI]*/ + addbyte(0x7e); + addbyte(0x01); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xc7); + addlong(0xfff); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t)writelookup2); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+2+5+1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(5+1); + addbyte(0x66); /*MOV -1[EDI+ESI],CX*/ + addbyte(0x89); + addbyte(0x44 | (REG_CX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(-1); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x50); /*PUSH EAX*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememwl*/ + addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 12*/ + addbyte(0xc4); + addbyte(12); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte(cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t gen_MEM_STORE_ADDR_EA_L() +{ + uint32_t addr = &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x8d); /*LEA EDI, 3[ESI]*/ + addbyte(0x7e); + addbyte(0x03); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xc7); + addlong(0xffc); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t)writelookup2); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+2+4+1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4+1); + addbyte(0x89); /*MOV -3[EDI+ESI],ECX*/ + addbyte(0x44 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(-3); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x50); /*PUSH EAX*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememll*/ + addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 12*/ + addbyte(0xc4); + addbyte(12); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte(cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t gen_MEM_STORE_ADDR_EA_Q() +{ + uint32_t addr = &codeblock[block_current].data[block_pos]; + + /*dat = EBX/ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EDX, ESI*/ + addbyte(0xf2); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x8d); /*LEA EDI, 7[ESI]*/ + addbyte(0x7e); + addbyte(0x07); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xc7); + addlong(0xff8); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t)writelookup2); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+2+4+4+1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4+4+1); + addbyte(0x89); /*MOV -7[EDI+ESI],EBX*/ + addbyte(0x44 | (REG_EBX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(-7); + addbyte(0x89); /*MOV -7[EDI+ESI],EBX*/ + addbyte(0x44 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(-7+4); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0x50); /*PUSH EAX*/ + addbyte(0x52); /*PUSH EDX*/ + addbyte(0xe8); /*CALL writememql*/ + addlong((uint32_t)writememql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 16*/ + addbyte(0xc4); + addbyte(16); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte(cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + void codegen_init() { int c; @@ -70,18 +516,18 @@ void codegen_init() #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); #endif codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); #ifdef __linux__ start = (void *)((long)codeblock & pagemask); - len = ((BLOCK_SIZE * sizeof(codeblock_t)) + pagesize) & pagemask; + len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); @@ -89,6 +535,34 @@ void codegen_init() } #endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + + block_current = BLOCK_SIZE; + block_pos = 0; + mem_abrt_rout = &codeblock[block_current].data[block_pos]; + addbyte(0x83); /*ADDL $16+4,%esp*/ + addbyte(0xC4); + addbyte(0x10+4); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + block_pos = 128; + mem_load_addr_ea_l = gen_MEM_LOAD_ADDR_EA_L(); + block_pos = 256; + mem_load_addr_ea_w = gen_MEM_LOAD_ADDR_EA_W(); + block_pos = 384; + mem_load_addr_ea_b = gen_MEM_LOAD_ADDR_EA_B(); + block_pos = 512; + mem_load_addr_ea_q = gen_MEM_LOAD_ADDR_EA_Q(); + block_pos = 640; + mem_store_addr_ea_l = gen_MEM_STORE_ADDR_EA_L(); + block_pos = 768; + mem_store_addr_ea_w = gen_MEM_STORE_ADDR_EA_W(); + block_pos = 896; + mem_store_addr_ea_b = gen_MEM_STORE_ADDR_EA_B(); + block_pos = 1024; + mem_store_addr_ea_q = gen_MEM_STORE_ADDR_EA_Q(); } void codegen_reset() diff --git a/src/codegen_x86.h b/src/codegen_x86.h index bb4a16dbc..67f51b15c 100644 --- a/src/codegen_x86.h +++ b/src/codegen_x86.h @@ -1,6 +1,3 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ #define BLOCK_SIZE 0x4000 #define BLOCK_MASK 0x3fff #define BLOCK_START 0 @@ -22,3 +19,12 @@ enum extern int host_reg_mapping[NR_HOST_REGS]; #define NR_HOST_XMM_REGS 7 extern int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; + +extern uint32_t mem_load_addr_ea_b; +extern uint32_t mem_load_addr_ea_w; +extern uint32_t mem_load_addr_ea_l; +extern uint32_t mem_load_addr_ea_q; +extern uint32_t mem_store_addr_ea_b; +extern uint32_t mem_store_addr_ea_w; +extern uint32_t mem_store_addr_ea_l; +extern uint32_t mem_store_addr_ea_q; diff --git a/src/disc_86f.c b/src/disc_86f.c index 9a6ba30ea..1911947f2 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -634,15 +634,6 @@ void d86f_readsector(int drive, int sector, int track, int side, int rate, int s d86f[drive].req_sector.id.n = sector_size; d86f[drive].index_count = 0; -#if 0 - if (sector == SECTOR_FIRST) - d86f[drive].state = STATE_READ_FIND_FIRST_SECTOR; - else if (sector == SECTOR_NEXT) - d86f[drive].state = STATE_READ_FIND_NEXT_SECTOR; - else - d86f[drive].state = STATE_READ_FIND_SECTOR; -#endif - d86f[drive].state = STATE_READ_FIND_SECTOR; } @@ -657,6 +648,7 @@ void d86f_writesector(int drive, int sector, int track, int side, int rate, int if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { + pclog("Wrong side\n"); fdc_notfound(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -692,11 +684,12 @@ void d86f_prepare_track_layout(int drive, int side) { int i = 0; int j = 0; + int perp_wg = fdc_get_perp() & 3; int real_gap0_len = d86f_is_mfm(drive) ? 80 : 40; int sync_len = d86f_is_mfm(drive) ? 12 : 6; int am_len = d86f_is_mfm(drive) ? 4 : 1; int real_gap1_len = d86f_is_mfm(drive) ? 50 : 26; - int real_gap2_len = (fdc_get_bit_rate() >= 1000) ? 41 : 22; + int real_gap2_len = (perp_wg == 3) ? 41 : 22; int real_gap3_len = fdc_get_gap(); memset(d86f[drive].track_layout[side], BYTE_GAP4, d86f_get_raw_size(drive)); @@ -722,7 +715,6 @@ void d86f_prepare_track_layout(int drive, int side) } for (j = 0; j < fdc_get_format_sectors(); j++) { - // pclog("Sector %i (%i)\n", j, s->n); memset(d86f[drive].track_layout[side] + i, BYTE_ID_SYNC, sync_len); i += sync_len; if (d86f_is_mfm(drive)) @@ -756,6 +748,17 @@ void d86f_prepare_track_layout(int drive, int side) } } +int d86f_can_format(int drive) +{ + int temp; + temp = !writeprot[drive]; + temp = temp && !swwp; + temp = temp && fdd_can_read_medium(drive ^ fdd_swap); + temp = temp && d86f_valid_bit_rate(drive); + pclog("Bit rate is %svalid\n", d86f_valid_bit_rate(drive) ? "" : "not "); + return temp; +} + void d86f_format(int drive, int track, int side, int rate, uint8_t fill) { int full_size = 25000; @@ -772,8 +775,10 @@ void d86f_format(int drive, int track, int side, int rate, uint8_t fill) d86f[drive].req_sector.id.c = d86f[drive].cur_track; d86f[drive].req_sector.id.h = side; - if ((side && (d86f_get_sides(drive) == 1)) || !d86f_valid_bit_rate(drive)) + if ((side && (d86f_get_sides(drive) == 1)) || !(d86f_can_format(drive))) { + if (side && (d86f_get_sides(drive) == 1)) pclog("Wrong side\n"); + if (!(d86f_can_format(drive))) pclog("Can't format\n"); fdc_notfound(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -782,6 +787,7 @@ void d86f_format(int drive, int track, int side, int rate, uint8_t fill) if ((d86f[drive].cur_track < 0) || (d86f[drive].cur_track > 256)) { + pclog("Track below 0 or above 256\n"); fdc_writeprotect(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -870,16 +876,6 @@ int d86f_should_write_am(int drive) return temp; } -int d86f_can_format(int drive) -{ - int temp; - temp = !writeprot[drive]; - temp = temp && !swwp; - temp = temp && fdd_can_read_medium(drive ^ fdd_swap); - temp = temp & d86f_valid_bit_rate(drive); - return temp; -} - int d86f_find_state_nf(int drive) { int temp; @@ -1011,7 +1007,7 @@ int d86f_poll_check_notfound(int drive) /* The index hole has been hit twice and we're still in a find state. This means sector finding has failed for whatever reason. Abort with sector not found and set state to idle. */ - // pclog("d86f_poll(): Sector not found (%i %i %i %i) (%i, %i)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive)); + pclog("d86f_poll(): Sector not found (%i %i %i %i) (%i, %i)\n", d86f[drive].req_sector.id.c, d86f[drive].req_sector.id.h, d86f[drive].req_sector.id.r, d86f[drive].req_sector.id.n, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive)); fdc_notfound(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -1272,23 +1268,12 @@ void d86f_poll_find_nf(int drive, int side) void d86f_poll_find_format(int drive, int side) { - if (!(d86f_can_format(drive))) - { - fdc_notfound(); - d86f_poll_reset(drive, side); - d86f_poll_advancebyte(drive, side); - return; - } - d86f_poll_advancebyte(drive, side); - if (d86f_poll_check_notfound(drive)) return; - if (d86f[drive].track_index) { - // pclog("Index hole hit, formatting track...\n"); + pclog("Index hole hit, formatting track...\n"); d86f[drive].state = STATE_FORMAT; - // d86f_poll_advancebyte(drive, side); return; } } @@ -1323,22 +1308,23 @@ void d86f_poll_format(int drive, int side) break; case BYTE_ID_SYNC: d86f[drive].id_pos = d86f[drive].track_pos - d86f[drive].section_pos; - if (d86f[drive].id_pos > 3) + + if (d86f[drive].id_pos <= 3) { - break; - } - data = fdc_getdata(0); - if ((data == -1) && (d86f[drive].id_pos < 3)) - { - data = 0; - } - d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos] = data & 0xff; - // pclog("format_sector_id[%i] = %i\n", cur_id_pos, d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos]); - if (d86f[drive].id_pos == 3) - { - fdc_stop_id_request(); - // pclog("Formatting sector: %08X...\n", d86f[drive].format_sector_id.dword); + data = fdc_getdata(0); + if ((data == -1) && (d86f[drive].id_pos < 3)) + { + data = 0; + } + d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos] = data & 0xff; + // pclog("format_sector_id[%i] = %i\n", cur_id_pos, d86f[drive].format_sector_id.byte_array[d86f[drive].id_pos]); + if (d86f[drive].id_pos == 3) + { + fdc_stop_id_request(); + // pclog("Formatting sector: %08X...\n", d86f[drive].format_sector_id.dword); + } } + case BYTE_I_SYNC: case BYTE_DATA_SYNC: if (!disable_write) @@ -1392,12 +1378,11 @@ void d86f_poll_format(int drive, int side) if (d86f[drive].track_index) { - // pclog("Index hole hit again, format finished\n"); + pclog("Index hole hit again, format finished\n"); d86f[drive].state = STATE_IDLE; if (!disable_write) d86f_writeback(drive); fdc_sector_finishread(drive); d86f[drive].index_count = 0; - // d86f_poll_advancebyte(drive, side); return; } diff --git a/src/disc_img.c b/src/disc_img.c index 7d4f556c6..254229524 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -37,19 +37,17 @@ static uint16_t xdf_track0_layout[3][92] = { { 0x8100, 0x8200, 0x8300, 0x8400, 0 0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0, 0, 0, 0, 0, 0x9001, 0x9101, 0x9201, 0x9301 }, /* 3.5" 2HD */ { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800, - 0x8900, 0x8A00, 0x8B00, 0x8C00, 0x0100, 0x0200, 0x0300, 0x0400, - 0x0500, 0x0600, 0x0700, 0x0800, 0x9500, 0x9600, 0x9700, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0x8D00, 0x8E00, 0x8F00, 0x9000, 0, 0, + 0x8900, 0x8A00, 0x8B00, 0x8C00, 0x8D00, 0x8E00, 0x8F00, 0x9000, + 0x9100, 0x9200, 0x9300, 0x9400, 0x9500, 0x9600, 0x9700, 0x0100, + 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x9800, 0x9900, 0x9A00, 0x9B00, 0x9C00, 0x9D00, 0x9E00, 0x8101, 0x8201, 0x8301, 0x8401, - 0x8501, 0x8601, 0x8701, 0x9100, 0x9200, 0x9300, 0x9400, 0x8801, + 0x8501, 0x8601, 0x8701, 0x8801, 0, 0, 0, 0, 0x8901, 0x8A01, 0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0x9001, 0x9101, 0x9201, 0x9301, 0x9401, 0x9501, 0x9601, 0x9701, 0x9801, 0x9901, 0x9A01, 0x9B01, 0x9C01, 0x9D01, 0x9E01, 0x9F01, 0xA001, - 0xA101, 0xA201, 0xA301, 0xA401 }, /* 3.5" 2ED - sectors 0x91 to 0x94 of side 0 are not written to the IMG file but - we read them in from the null-filled areas in order to have them as XDFCOPY - still expects their existence even if it does nothing with them. */ + 0xA101, 0xA201, 0xA301, 0xA401 }, }; /* First dimension is possible sector sizes (0 = 128, 7 = 16384), second is possible bit rates (250/360, 250, 300, 500/360, 500, 1000). */ @@ -434,6 +432,7 @@ void img_load(int drive, char *fn) { case 19: /* High density XDF @ 360 rpm */ img[drive].xdf_type = 1; + raw_tsize[drive] = 10521; /* Rotate at 356.4 RPM in order to fit the data. */ break; case 23: /* High density XDF @ 300 rpm */ img[drive].xdf_type = 2; @@ -446,6 +445,7 @@ void img_load(int drive, char *fn) fclose(img[drive].f); return; } + pclog("XDF type: %i\n", img[drive].xdf_type); } else /* Amount of sectors per track that fits into a track, therefore not XDF */ { @@ -548,7 +548,7 @@ void img_seek(int drive, int track) uint8_t sectors_fat, effective_sectors, sector_gap; /* Needed for XDF */ - int sector, current_pos, sh, sr, spos, sside; + int sector, current_pos, sh, sr, sside, total; if (!img[drive].f) return; @@ -582,29 +582,24 @@ void img_seek(int drive, int track) sectors_fat = xdf_track0[current_xdft][0]; effective_sectors = xdf_track0[current_xdft][1]; sector_gap = xdf_track0[current_xdft][2]; + total = img[drive].sectors; if (!track) { /* Track 0, register sectors according to track 0 layout. */ current_pos = 0; - for (sector = 0; sector < (img[drive].sectors * 2); sector++) + for (sector = 0; sector < (total << 1); sector++) { + current_pos = (sector % total) << 9; + sside = (sector >= total) ? 1 : 0; if (xdf_track0_layout[current_xdft][sector]) { sh = xdf_track0_layout[current_xdft][sector] & 0xFF; sr = xdf_track0_layout[current_xdft][sector] >> 8; - spos = current_pos; - sside = 0; - if (spos >= (img[drive].sectors * img[drive].sector_size)) - { - spos -= (img[drive].sectors * img[drive].sector_size); - sside = 1; - } disc_sector_add(drive, sh, track, sh, sr, 2, img[drive].bitcell_period_300rpm, - &img[drive].track_data[sside][spos]); + &img[drive].track_data[sside][current_pos]); } - current_pos += 512; } } else diff --git a/src/disc_sector_86box.c b/src/disc_sector_86box.c index 6239c280e..2d5a2979c 100644 --- a/src/disc_sector_86box.c +++ b/src/disc_sector_86box.c @@ -263,6 +263,7 @@ void disc_sector_prepare_track_layout(int drive, int side, int track) memset(track_layout[drive][side] + i, BYTE_GAP3, disc_sector_get_gap3_size(drive, side, track)); i += disc_sector_get_gap3_size(drive, side, track); } + // pclog("Track length: %i bytes\n", i); if (side == 0) disc_sector_state[drive] = STATE_IDLE; } @@ -378,6 +379,7 @@ void disc_sector_poll() int cur_id_pos = 0; int cur_data_pos = 0; int cur_gap3_pos = 0; + int max_gap = 0; uint8_t track_byte = 0; uint8_t track_index = 0; @@ -515,7 +517,12 @@ void disc_sector_poll() break; case BYTE_GAP3: cur_gap3_pos = cur_track_pos[drive] - section_pos[drive]; - if (cur_gap3_pos == (fdc_get_gap() - 1)) + max_gap = fdc_get_gap(); + if (max_gap > disc_sector_get_gap3_size(drive, side, disc_sector_track[drive])) + { + max_gap = disc_sector_get_gap3_size(drive, side, disc_sector_track[drive]); + } + if (cur_gap3_pos == (max_gap - 1)) { if (disc_sector_read_state(drive) && (last_sector[drive] != NULL)) { diff --git a/src/fdc.c b/src/fdc.c index 162a39079..029e04cf7 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -104,6 +104,11 @@ void fdc_reset() int fdc_get_bitcell_period(); +int fdc_get_perp() +{ + return fdc.perp; +} + int fdc_get_format_n() { return fdc.format_n; @@ -366,7 +371,7 @@ void fdc_update_rate(int drive) } fdc.bitcell_period = 1000000 / bit_rate*2; /*Bitcell period in ns*/ -// pclog("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period); + pclog("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period); } int fdc_get_bit_rate() @@ -732,6 +737,13 @@ bad_command: disctime = 0; break; + case 0x12: + fdc.stat=0x80; + fdc.perp = fdc.params[0]; + pclog("PERPENDICULAR: Set to: %02X\n", fdc.perp); + disctime = 0; + return; + case 4: fdd_set_head(fdc.drive, (fdc.params[0] & 4) ? 1 : 0); break; @@ -810,6 +822,7 @@ bad_command: fdc.gap = fdc.params[3]; fdc.dtl = 4000000; fdc.format_sectors = fdc.params[2]; + pclog("Formatting with %i sectors per track\n", fdc.format_sectors); fdc.format_n = fdc.params[1]; fdc.format_state = 1; fdc.pos = 0; @@ -1219,13 +1232,17 @@ void fdc_callback() disctime = 0; return; +#if 0 case 0x12: fdc.perp = fdc.params[0]; + pclog("PERPENDICULAR: Set to: %02X\n", fdc.perp); fdc.stat = 0x80; disctime = 0; // picint(0x40); return; - case 0x13: /*Configure*/ +#endif + + case 0x13: /*Configure*/ fdc.config = fdc.params[1]; fdc.pretrk = fdc.params[2]; fdc.fifo = (fdc.params[1] & 0x20) ? 0 : 1; diff --git a/src/fdc.h b/src/fdc.h index 7c479ebd0..6424ea315 100644 --- a/src/fdc.h +++ b/src/fdc.h @@ -31,6 +31,7 @@ void fdc_update_densel_force(int densel_force); void fdc_update_drvrate(int drive, int drvrate); void fdc_update_drv2en(int drv2en); +int fdc_get_perp(); int fdc_get_format_n(); int fdc_is_mfm(); double fdc_get_hut(); diff --git a/src/pc.c b/src/pc.c index 1a94ddb67..7a89e25fc 100644 --- a/src/pc.c +++ b/src/pc.c @@ -245,8 +245,6 @@ void initpc(int argc, char *argv[]) if (config_file) saveconfig(); - codegen_init(); - cpuspeed2=(AT)?2:1; // cpuspeed2=cpuspeed; atfullspeed=0; @@ -256,6 +254,8 @@ void initpc(int argc, char *argv[]) loadbios(); mem_add_bios(); + codegen_init(); + device_init(); timer_reset(); diff --git a/src/w83877f.c b/src/w83877f.c index f97168868..7f8f959a2 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -347,6 +347,11 @@ void w83877f_write(uint16_t port, uint8_t val, void *priv) process_value: switch(w83877f_curreg) { + case 1: + if (valxor & 0x80) + { + fdd_setswap((w83877f_regs[1] & 0x80) ? 1 : 0); + } case 4: if (valxor & 0x10) { @@ -515,7 +520,7 @@ void w83877f_init() swwp = 0; disable_write = 0; fdc_update_drv2en(1); - fdd_swap = 0; + fdd_setswap(0); serial1_set(0x3f8, 4); serial2_set(0x2f8, 3); w83877f_remap();