sync to dosbox svn

This commit is contained in:
dborth 2009-06-30 04:14:25 +00:00
parent 5a5a73d009
commit be010fae52
31 changed files with 1526 additions and 1313 deletions

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: callback.cpp,v 1.40 2009/03/03 18:30:41 c2woody Exp $ */
/* $Id: callback.cpp,v 1.41 2009/06/11 16:05:17 c2woody Exp $ */
#include <stdlib.h>
#include <string.h>
@ -26,7 +26,7 @@
#include "mem.h"
#include "cpu.h"
/* CallBack are located at 0xF100:0 (see CB_SEG in callback.h)
/* CallBack are located at 0xF000:0x1000 (see CB_SEG and CB_SOFFSET in callback.h)
And they are 16 bytes each and you can define them to behave in certain ways like a
far return or and IRET
*/
@ -87,8 +87,8 @@ static Bitu stop_handler(void) {
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) {
reg_sp-=4;
mem_writew(SegPhys(ss)+reg_sp,call_stop*CB_SIZE);
mem_writew(SegPhys(ss)+reg_sp+2,CB_SEG);
mem_writew(SegPhys(ss)+reg_sp,RealOff(CALLBACK_RealPointer(call_stop)));
mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(CALLBACK_RealPointer(call_stop)));
Bit32u oldeip=reg_eip;
Bit16u oldcs=SegValue(cs);
reg_eip=off;
@ -101,7 +101,7 @@ void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) {
void CALLBACK_RunRealInt(Bit8u intnum) {
Bit32u oldeip=reg_eip;
Bit16u oldcs=SegValue(cs);
reg_eip=(CB_MAX*CB_SIZE)+(intnum*6);
reg_eip=CB_SOFFSET+(CB_MAX*CB_SIZE)+(intnum*6);
SegSet16(cs,CB_SEG);
DOSBOX_RunMachine();
reg_eip=oldeip;
@ -141,7 +141,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02, callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xC3); //A RETN Instruction
@ -150,7 +150,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02, callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xCB); //A RETF Instruction
@ -159,7 +159,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02, callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xCA); //A RETF 8 Instruction
@ -169,7 +169,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction
@ -178,7 +178,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x66); //An IRETD Instruction
@ -189,7 +189,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x03, callback); //The immediate word
phys_writew(physAddress+0x03,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
@ -198,7 +198,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
@ -213,7 +213,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
@ -238,7 +238,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
phys_writew(physAddress+0x08,(Bit16u)0x0473); // jc skip
phys_writeb(physAddress+0x0a,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x0b,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x0c,callback); //The immediate word
phys_writew(physAddress+0x0c,(Bit16u)callback); //The immediate word
// jump here to (skip):
physAddress+=6;
}
@ -252,7 +252,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
@ -272,13 +272,13 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
phys_writeb(physAddress+0x05,(Bit8u)0xfb); // sti
phys_writeb(physAddress+0x06,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x07,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x08,callback); //The immediate word
phys_writew(physAddress+0x08,(Bit16u)callback); //The immediate word
return 0x0a;
case CB_IRQ12_RET: // ps2 mouse int74 return
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xfa); // cli
@ -298,7 +298,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
phys_writew(physAddress+0x05,(Bit16u)0x0674); // je skip
phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x09,callback); //The immediate word
phys_writew(physAddress+0x09,(Bit16u)callback); //The immediate word
physAddress+=4;
} else {
phys_writew(physAddress+0x05,(Bit16u)0x0274); // je skip
@ -318,7 +318,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction
@ -328,7 +328,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x03, callback); //The immediate word
phys_writew(physAddress+0x03,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
@ -339,7 +339,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
@ -357,7 +357,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x05,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x06,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x07,callback); //The immediate word
phys_writew(physAddress+0x07,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x05,(Bit8u)0xCB); //A RETF Instruction
@ -366,7 +366,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x02,callback); //The immediate word
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
@ -388,7 +388,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
phys_writeb(physAddress+0x06,(Bit8u)0x60); // pusha
phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x09,callback); //The immediate word
phys_writew(physAddress+0x09,(Bit16u)callback); //The immediate word
phys_writeb(physAddress+0x0b,(Bit8u)0xCB); //A RETF Instruction
return 0x0c;
case CB_IPXESR_RET: // IPX ESR return
@ -409,7 +409,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
if (use_cb) {
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x03, callback); //The immediate word
phys_writew(physAddress+0x03,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
@ -502,7 +502,7 @@ void CALLBACK_HandlerObject::Set_RealVec(Bit8u vec){
} else E_Exit ("double usage of vector handler");
}
void CALLBACK_Init(Section* sec) {
void CALLBACK_Init(Section* /*sec*/) {
Bitu i;
for (i=0;i<CB_MAX;i++) {
CallBack_Handlers[i]=&illegal_handler;
@ -514,7 +514,7 @@ void CALLBACK_Init(Section* sec) {
CALLBACK_SetDescription(call_stop,"stop");
phys_writeb(CALLBACK_PhysPointer(call_stop)+0,0xFE);
phys_writeb(CALLBACK_PhysPointer(call_stop)+1,0x38);
phys_writew(CALLBACK_PhysPointer(call_stop)+2,call_stop);
phys_writew(CALLBACK_PhysPointer(call_stop)+2,(Bit16u)call_stop);
/* Setup the idle handler */
call_idle=CALLBACK_Allocate();
@ -523,7 +523,7 @@ void CALLBACK_Init(Section* sec) {
for (i=0;i<=11;i++) phys_writeb(CALLBACK_PhysPointer(call_idle)+i,0x90);
phys_writeb(CALLBACK_PhysPointer(call_idle)+12,0xFE);
phys_writeb(CALLBACK_PhysPointer(call_idle)+13,0x38);
phys_writew(CALLBACK_PhysPointer(call_idle)+14,call_idle);
phys_writew(CALLBACK_PhysPointer(call_idle)+14,(Bit16u)call_idle);
/* Default handlers for unhandled interrupts that have to be non-null */
call_default=CALLBACK_Allocate();
@ -531,18 +531,21 @@ void CALLBACK_Init(Section* sec) {
call_default2=CALLBACK_Allocate();
CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default");
/* Only setup default handler for first half of interrupt table */
for (i=0;i<0x40;i++) {
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
/* Only setup default handler for first part of interrupt table */
for (Bit16u ct=0;ct<0x60;ct++) {
real_writed(0,ct*4,CALLBACK_RealPointer(call_default));
}
for (Bit16u ct=0x68;ct<0x70;ct++) {
real_writed(0,ct*4,CALLBACK_RealPointer(call_default));
}
/* Setup block of 0xCD 0xxx instructions */
PhysPt rint_base=(CB_SEG << 4)+CB_MAX*CB_SIZE;
PhysPt rint_base=CALLBACK_GetBase()+CB_MAX*CB_SIZE;
for (i=0;i<=0xff;i++) {
phys_writeb(rint_base,0xCD);
phys_writeb(rint_base+1,i);
phys_writeb(rint_base+1,(Bit8u)i);
phys_writeb(rint_base+2,0xFE);
phys_writeb(rint_base+3,0x38);
phys_writew(rint_base+4,call_stop);
phys_writew(rint_base+4,(Bit16u)call_stop);
rint_base+=6;
}

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: decoder_opcodes.h,v 1.9 2009/06/25 19:31:43 c2woody Exp $ */
/*
The functions in this file are called almost exclusively by decoder.h,
@ -544,8 +546,8 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) {
MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
}
MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op);
if (immediate) gen_mov_byte_to_reg_low_imm(FC_RETOP,decode_fetchb());
else MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_ECX,0);
if (immediate) gen_mov_byte_to_reg_low_imm(FC_OP3,decode_fetchb());
else MOV_REG_BYTE_TO_HOST_REG_LOW(FC_OP3,DRC_REG_ECX,0);
if (decode.big_op) dyn_dpshift_dword_gencall(left);
else dyn_dpshift_word_gencall(left);

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: operators.h,v 1.8 2009/06/25 19:31:43 c2woody Exp $ */
static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) DRC_FC;
static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) {
@ -1297,20 +1299,20 @@ static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u
static void dyn_dpshift_word_gencall(bool left) {
if (left) {
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_word,FC_RETOP);
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_word,FC_OP3);
InvalidateFlagsPartially((void*)&dynrec_dshl_word_simple,proc_addr,t_DSHLw);
} else {
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_word,FC_RETOP);
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_word,FC_OP3);
InvalidateFlagsPartially((void*)&dynrec_dshr_word_simple,proc_addr,t_DSHRw);
}
}
static void dyn_dpshift_dword_gencall(bool left) {
if (left) {
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_dword,FC_RETOP);
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_dword,FC_OP3);
InvalidateFlagsPartially((void*)&dynrec_dshl_dword_simple,proc_addr,t_DSHLd);
} else {
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_dword,FC_RETOP);
DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_dword,FC_OP3);
InvalidateFlagsPartially((void*)&dynrec_dshr_dword_simple,proc_addr,t_DSHRd);
}
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-o3.h,v 1.4 2009/05/16 21:52:47 c2woody Exp $ */
/* $Id: risc_armv4le-o3.h,v 1.6 2009/06/27 12:51:10 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */
@ -24,11 +24,11 @@
// temporary registers
#define temp1 HOST_ip
#define temp2 HOST_v5
#define temp2 HOST_v3
#define temp3 HOST_v4
// register that holds function return values
#define FC_RETOP HOST_v3
#define FC_RETOP HOST_a1
// register used for address calculations,
#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG
@ -39,6 +39,9 @@
// register that holds the second parameter
#define FC_OP2 HOST_a2
// special register that holds the third parameter for _R3 calls (byte accessible)
#define FC_OP3 HOST_v2
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_a1
@ -624,7 +627,6 @@ static void INLINE gen_call_function_raw(void * func) {
cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4
cache_addd( BX(temp1) ); // bx temp1
cache_addd((Bit32u)func); // .int func
cache_addd( MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 0) ); // mov FC_RETOP, a1
}
// generate a call to a function with paramcount parameters
@ -783,7 +785,7 @@ static void INLINE gen_fill_branch_long(Bit32u data) {
static void gen_run_code(void) {
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8}
cache_addd(0xe92d0cf0); // stmfd sp!, {v1-v4,v7,v8}
// adr: 8
cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)]
@ -794,7 +796,7 @@ static void gen_run_code(void) {
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd( BX(HOST_r0) ); // bx r0
cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8}
cache_addd(0xe8bd0cf0); // ldmfd sp!, {v1-v4,v7,v8}
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd( BX(HOST_lr) ); // bx lr
@ -815,7 +817,6 @@ static void gen_run_code(void) {
// return from a function
static void gen_return_function(void) {
cache_addd( MOV_REG_LSL_IMM(HOST_a1, FC_RETOP, 0) ); // mov a1, FC_RETOP
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd( BX(HOST_lr) ); // bx lr
}
@ -832,31 +833,41 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_ADDw:
case t_ADDd:
*(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_CMPb:
case t_CMPw:
@ -864,106 +875,105 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit32u*)pos=B_FWD(12); // b (pc+3*4)
*(Bit32u*)pos=B_FWD(8); // b (pc+2*4)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_SHRb:
*(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff
*(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_SHRw:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_SHRd:
*(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_SARb:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24
*(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_SARw:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16
*(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_SARd:
*(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_RORb:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8
*(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_RORw:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_RORd:
*(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
break;
case t_ROLb:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32
*(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8
*(Bit32u*)(pos+12)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+16)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_ROLw:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32
*(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_ROLd:
*(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32
*(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
default:
*(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-s3.h,v 1.4 2009/05/16 21:52:47 c2woody Exp $ */
/* $Id: risc_armv4le-s3.h,v 1.6 2009/06/27 12:51:10 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */
@ -24,11 +24,11 @@
// temporary registers
#define temp1 HOST_ip
#define temp2 HOST_v5
#define temp2 HOST_v3
#define temp3 HOST_v4
// register that holds function return values
#define FC_RETOP HOST_v3
#define FC_RETOP HOST_a1
// register used for address calculations,
#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG
@ -39,6 +39,9 @@
// register that holds the second parameter
#define FC_OP2 HOST_a2
// special register that holds the third parameter for _R3 calls (byte accessible)
#define FC_OP3 HOST_v2
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_a1
@ -472,7 +475,6 @@ static void INLINE gen_call_function_raw(void * func) {
cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4
cache_addd( BX(temp1) ); // bx temp1
cache_addd((Bit32u)func); // .int func
cache_addd( MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 0) ); // mov FC_RETOP, a1
}
// generate a call to a function with paramcount parameters
@ -619,7 +621,7 @@ static void INLINE gen_fill_branch_long(Bit32u data) {
static void gen_run_code(void) {
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8}
cache_addd(0xe92d0cf0); // stmfd sp!, {v1-v4,v7,v8}
// adr: 8
cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)]
@ -630,7 +632,7 @@ static void gen_run_code(void) {
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd( BX(HOST_r0) ); // bx r0
cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8}
cache_addd(0xe8bd0cf0); // ldmfd sp!, {v1-v4,v7,v8}
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd( BX(HOST_lr) ); // bx lr
@ -651,7 +653,6 @@ static void gen_run_code(void) {
// return from a function
static void gen_return_function(void) {
cache_addd( MOV_REG_LSL_IMM(HOST_a1, FC_RETOP, 0) ); // mov a1, FC_RETOP
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd( BX(HOST_lr) ); // bx lr
}
@ -668,31 +669,41 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_ADDw:
case t_ADDd:
*(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_CMPb:
case t_CMPw:
@ -700,106 +711,105 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit32u*)pos=B_FWD(12); // b (pc+3*4)
*(Bit32u*)pos=B_FWD(8); // b (pc+2*4)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_SHRb:
*(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff
*(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_SHRw:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_SHRd:
*(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_SARb:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24
*(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_SARw:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16
*(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_SARd:
*(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_RORb:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8
*(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_RORw:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_RORd:
*(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
break;
case t_ROLb:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32
*(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8
*(Bit32u*)(pos+12)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+16)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
case t_ROLw:
*(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32
*(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_ROLd:
*(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32
*(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
*(Bit32u*)(pos+16)=NOP; // nop
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0
*(Bit32u*)(pos+4)=B_FWD(8); // b (pc+2*4)
*(Bit32u*)(pos+4)=NOP; // nop
*(Bit32u*)(pos+8)=NOP; // nop
*(Bit32u*)(pos+12)=NOP; // nop
break;
default:
*(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-thumb-iw.h,v 1.3 2009/05/16 21:52:47 c2woody Exp $ */
/* $Id: risc_armv4le-thumb-iw.h,v 1.5 2009/06/27 12:51:10 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (thumb version with data pool, requires -mthumb-interwork switch when compiling dosbox) */
@ -25,15 +25,10 @@
// temporary "lo" registers
#define templo1 HOST_v3
#define templo2 HOST_v4
// temporary "lo" register - value must be preserved when using it
#define templosav HOST_a3
// temporary "hi" register
#define temphi1 HOST_ip
#define templo3 HOST_v2
// register that holds function return values
#define FC_RETOP HOST_v2
#define FC_RETOP HOST_a1
// register used for address calculations,
#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG
@ -44,6 +39,9 @@
// register that holds the second parameter
#define FC_OP2 HOST_a2
// special register that holds the third parameter for _R3 calls (byte accessible)
#define FC_OP3 HOST_a4
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_a1
@ -83,8 +81,6 @@
#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) )
// add dst, src1, src2
#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) )
// add dst, src
#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) )
// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0
#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) )
// sub dst, src1, src2
@ -499,11 +495,9 @@ static void gen_extend_word(bool sign,HostReg reg) {
// add a 32bit value from memory to a full register
static void gen_add(HostReg reg,void* op) {
gen_mov_word_to_reg(templo3, op, 1);
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg
gen_mov_word_to_reg(reg, op, 1);
cache_checkinstr(2);
cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1
cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3
}
// add a 32bit constant value to a full register
@ -525,12 +519,8 @@ static void gen_and_imm(HostReg reg,Bit32u imm) {
// move a 32bit constant value into memory
static void gen_mov_direct_dword(void* dest,Bit32u imm) {
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templosav, imm);
gen_mov_word_from_reg(templosav, dest, 1);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_dword_to_reg_imm(templo3, imm);
gen_mov_word_from_reg(templo3, dest, 1);
}
// move an address into memory
@ -541,19 +531,15 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) {
// add an 8bit constant value to a dword memory value
static void gen_add_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, 1, templo2);
gen_mov_word_to_reg_helper(templo3, dest, 1, templo2);
cache_checkinstr(2);
if (imm >= 0) {
cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm)
cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm)
} else {
cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm)
cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm)
}
gen_mov_word_from_reg_helper(templosav, dest, 1, templo2);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_word_from_reg_helper(templo3, dest, 1, templo2);
}
// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value
@ -563,38 +549,30 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) {
gen_add_direct_byte(dest,(Bit8s)imm);
return;
}
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, dword, templo2);
gen_mov_word_to_reg_helper(templo3, dest, dword, templo2);
if (dword) {
gen_mov_dword_to_reg_imm(templo1, imm);
} else {
gen_mov_word_to_reg_imm(templo1, (Bit16u)imm);
}
cache_checkinstr(2);
cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1
gen_mov_word_from_reg_helper(templosav, dest, dword, templo2);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1
gen_mov_word_from_reg_helper(templo3, dest, dword, templo2);
}
// subtract an 8bit constant value from a dword memory value
static void gen_sub_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, 1, templo2);
gen_mov_word_to_reg_helper(templo3, dest, 1, templo2);
cache_checkinstr(2);
if (imm >= 0) {
cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm)
cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm)
} else {
cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm)
cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm)
}
gen_mov_word_from_reg_helper(templosav, dest, 1, templo2);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_word_from_reg_helper(templo3, dest, 1, templo2);
}
// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value
@ -604,20 +582,16 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) {
gen_sub_direct_byte(dest,(Bit8s)imm);
return;
}
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, dword, templo2);
gen_mov_word_to_reg_helper(templo3, dest, dword, templo2);
if (dword) {
gen_mov_dword_to_reg_imm(templo1, imm);
} else {
gen_mov_word_to_reg_imm(templo1, (Bit16u)imm);
}
cache_checkinstr(2);
cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1
gen_mov_word_from_reg_helper(templosav, dest, dword, templo2);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1
gen_mov_word_from_reg_helper(templo3, dest, dword, templo2);
}
// effective address calculation, destination is dest_reg
@ -670,12 +644,11 @@ static void gen_call_function_helper(void * func) {
// after_call:
// thumb state from now on
cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1
}
// generate a call to a parameterless function
static void INLINE gen_call_function_raw(void * func) {
cache_checkinstr(14);
cache_checkinstr(12);
gen_call_function_helper(func);
}
@ -683,13 +656,13 @@ static void INLINE gen_call_function_raw(void * func) {
// note: the parameters are loaded in the architecture specific way
// using the gen_load_param_ functions below
static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
cache_checkinstr(14);
cache_checkinstr(12);
Bit32u proc_addr = (Bit32u)cache.pos;
gen_call_function_helper(func);
return proc_addr;
// if proc_addr is on word boundary ((proc_addr & 0x03) == 0)
// then length of generated code is 14 bytes
// otherwise length of generated code is 12 bytes
// then length of generated code is 12 bytes
// otherwise length of generated code is 10 bytes
}
#if (1)
@ -720,33 +693,31 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) {
// jump to an address pointed at by ptr, offset is in imm
static void gen_jmp_ptr(void * ptr,Bits imm=0) {
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_word_to_reg(templosav, ptr, 1);
gen_mov_word_to_reg(templo3, ptr, 1);
if (imm) {
gen_mov_dword_to_reg_imm(templo2, imm);
cache_checkinstr(2);
cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2
cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2
}
#if (1)
// (*ptr) should be word aligned
if ((imm & 0x03) == 0) {
cache_checkinstr(8);
cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav]
cache_checkinstr(6);
cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3]
} else
#endif
{
cache_checkinstr(26);
cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav]
cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1]
cache_checkinstr(24);
cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3]
cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1]
cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2]
cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2]
cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3]
cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3]
cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
}
@ -754,8 +725,6 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) {
// increase jmp address to keep thumb state
cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( BX(templo2) ); // bx templo2
}
@ -895,8 +864,7 @@ static void gen_run_code(void) {
// return from a function
static void gen_return_function(void) {
cache_checkinstr(6);
cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP
cache_checkinstr(4);
cache_addw(0xbc08); // pop {r3}
cache_addw( BX(HOST_r3) ); // bx r3
}
@ -930,35 +898,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_ADDb:
case t_ADDw:
case t_ADDd:
*(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_CMPb:
case t_CMPw:
@ -966,117 +931,107 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit16u*)pos=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=B_FWD(8); // b after_call (pc+8)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_SHRb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+10)=NOP; // nop
break;
case t_SHRw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+10)=NOP; // nop
break;
case t_SHRd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_SARb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+10)=NOP; // nop
break;
case t_SARw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+10)=NOP; // nop
break;
case t_SARd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
case t_RORb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_RORw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+4)=NOP; // nop
*(Bit16u*)(pos+6)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+8)=NOP; // nop
*(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_RORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
/*case t_ROLb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
break;*/
case t_ROLw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_ROLd:
*(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+4)=NOP; // nop
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=NOP; // nop
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+12)=NOP; // nop
*(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+10)=NOP; // nop
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1
*(Bit16u*)(pos+2)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
break;
default:
*(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func
@ -1090,35 +1045,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_ADDb:
case t_ADDw:
case t_ADDd:
*(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_CMPb:
case t_CMPw:
@ -1126,121 +1078,85 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit16u*)pos=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=B_FWD(6); // b after_call (pc+6)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_SHRb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
break;
case t_SHRw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
break;
case t_SHRd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_SARb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
break;
case t_SARw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
break;
case t_SARd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4)
break;
case t_RORb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_RORw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+4)=NOP; // nop
*(Bit16u*)(pos+6)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+8)=NOP; // nop
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+6)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_RORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(4); // b after_call (pc+4)
break;
/*case t_ROLb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
break;*/
case t_ROLw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
case t_ROLd:
*(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+2)=NOP; // nop
*(Bit16u*)(pos+4)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1
*(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1
*(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4)
break;
default:
*(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-thumb-niw.h,v 1.3 2009/05/16 21:52:47 c2woody Exp $ */
/* $Id: risc_armv4le-thumb-niw.h,v 1.5 2009/06/27 12:51:10 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (thumb version with data pool) */
@ -25,15 +25,10 @@
// temporary "lo" registers
#define templo1 HOST_v3
#define templo2 HOST_v4
// temporary "lo" register - value must be preserved when using it
#define templosav HOST_a3
// temporary "hi" register
#define temphi1 HOST_ip
#define templo3 HOST_v2
// register that holds function return values
#define FC_RETOP HOST_v2
#define FC_RETOP HOST_a1
// register used for address calculations,
#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG
@ -44,6 +39,9 @@
// register that holds the second parameter
#define FC_OP2 HOST_a2
// special register that holds the third parameter for _R3 calls (byte accessible)
#define FC_OP3 HOST_a4
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_a1
@ -83,8 +81,6 @@
#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) )
// add dst, src1, src2
#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) )
// add dst, src
#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) )
// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0
#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) )
// sub dst, src1, src2
@ -499,11 +495,9 @@ static void gen_extend_word(bool sign,HostReg reg) {
// add a 32bit value from memory to a full register
static void gen_add(HostReg reg,void* op) {
gen_mov_word_to_reg(templo3, op, 1);
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg
gen_mov_word_to_reg(reg, op, 1);
cache_checkinstr(2);
cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1
cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3
}
// add a 32bit constant value to a full register
@ -525,12 +519,8 @@ static void gen_and_imm(HostReg reg,Bit32u imm) {
// move a 32bit constant value into memory
static void gen_mov_direct_dword(void* dest,Bit32u imm) {
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templosav, imm);
gen_mov_word_from_reg(templosav, dest, 1);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_dword_to_reg_imm(templo3, imm);
gen_mov_word_from_reg(templo3, dest, 1);
}
// move an address into memory
@ -541,19 +531,15 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) {
// add an 8bit constant value to a dword memory value
static void gen_add_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, 1, templo2);
gen_mov_word_to_reg_helper(templo3, dest, 1, templo2);
cache_checkinstr(2);
if (imm >= 0) {
cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm)
cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm)
} else {
cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm)
cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm)
}
gen_mov_word_from_reg_helper(templosav, dest, 1, templo2);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_word_from_reg_helper(templo3, dest, 1, templo2);
}
// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value
@ -563,38 +549,30 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) {
gen_add_direct_byte(dest,(Bit8s)imm);
return;
}
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, dword, templo2);
gen_mov_word_to_reg_helper(templo3, dest, dword, templo2);
if (dword) {
gen_mov_dword_to_reg_imm(templo1, imm);
} else {
gen_mov_word_to_reg_imm(templo1, (Bit16u)imm);
}
cache_checkinstr(2);
cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1
gen_mov_word_from_reg_helper(templosav, dest, dword, templo2);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1
gen_mov_word_from_reg_helper(templo3, dest, dword, templo2);
}
// subtract an 8bit constant value from a dword memory value
static void gen_sub_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, 1, templo2);
gen_mov_word_to_reg_helper(templo3, dest, 1, templo2);
cache_checkinstr(2);
if (imm >= 0) {
cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm)
cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm)
} else {
cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm)
cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm)
}
gen_mov_word_from_reg_helper(templosav, dest, 1, templo2);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_word_from_reg_helper(templo3, dest, 1, templo2);
}
// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value
@ -604,20 +582,16 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) {
gen_sub_direct_byte(dest,(Bit8s)imm);
return;
}
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, dword, templo2);
gen_mov_word_to_reg_helper(templo3, dest, dword, templo2);
if (dword) {
gen_mov_dword_to_reg_imm(templo1, imm);
} else {
gen_mov_word_to_reg_imm(templo1, (Bit16u)imm);
}
cache_checkinstr(2);
cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1
gen_mov_word_from_reg_helper(templosav, dest, dword, templo2);
cache_checkinstr(2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1
gen_mov_word_from_reg_helper(templo3, dest, dword, templo2);
}
// effective address calculation, destination is dest_reg
@ -672,12 +646,11 @@ static void gen_call_function_helper(void * func) {
cache_addd(0xe12fff10 + (templo1)); // bx templo1
// thumb state from now on
cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1
}
// generate a call to a parameterless function
static void INLINE gen_call_function_raw(void * func) {
cache_checkinstr(20);
cache_checkinstr(18);
gen_call_function_helper(func);
}
@ -685,13 +658,13 @@ static void INLINE gen_call_function_raw(void * func) {
// note: the parameters are loaded in the architecture specific way
// using the gen_load_param_ functions below
static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
cache_checkinstr(20);
cache_checkinstr(18);
Bit32u proc_addr = (Bit32u)cache.pos;
gen_call_function_helper(func);
return proc_addr;
// if proc_addr is on word boundary ((proc_addr & 0x03) == 0)
// then length of generated code is 18 bytes
// otherwise length of generated code is 20 bytes
// then length of generated code is 16 bytes
// otherwise length of generated code is 18 bytes
}
#if (1)
@ -722,33 +695,31 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) {
// jump to an address pointed at by ptr, offset is in imm
static void gen_jmp_ptr(void * ptr,Bits imm=0) {
cache_checkinstr(2);
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_word_to_reg(templosav, ptr, 1);
gen_mov_word_to_reg(templo3, ptr, 1);
if (imm) {
gen_mov_dword_to_reg_imm(templo2, imm);
cache_checkinstr(2);
cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2
cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2
}
#if (1)
// (*ptr) should be word aligned
if ((imm & 0x03) == 0) {
cache_checkinstr(8);
cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav]
cache_checkinstr(6);
cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3]
} else
#endif
{
cache_checkinstr(26);
cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav]
cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1]
cache_checkinstr(24);
cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3]
cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1]
cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2]
cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2]
cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3]
cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3]
cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
}
@ -756,8 +727,6 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) {
// increase jmp address to keep thumb state
cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( BX(templo2) ); // bx templo2
}
@ -897,8 +866,7 @@ static void gen_run_code(void) {
// return from a function
static void gen_return_function(void) {
cache_checkinstr(6);
cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP
cache_checkinstr(4);
cache_addw(0xbc08); // pop {r3}
cache_addw( BX(HOST_r3) ); // bx r3
}
@ -932,35 +900,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_ADDb:
case t_ADDw:
case t_ADDd:
*(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_CMPb:
case t_CMPw:
@ -968,118 +933,110 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit16u*)pos=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=B_FWD(12); // b after_call (pc+12)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_SHRb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24
*(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6)
break;
case t_SHRw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16
*(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6)
break;
case t_SHRd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_SARb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24
*(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6)
break;
case t_SARw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16
*(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6)
break;
case t_SARd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_RORb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+8)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+14)=NOP; // nop
*(Bit16u*)(pos+16)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+14)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_RORw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+8)=B_FWD(4); // b after_call (pc+4)
break;
case t_RORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
case t_ROLb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+14)=NOP; // nop
*(Bit16u*)(pos+16)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+14)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_ROLw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+12)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+14)=NOP; // nop
*(Bit16u*)(pos+16)=NOP; // nop
break;
case t_ROLd:
*(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6)
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1
*(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10)
break;
default:
*(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func
@ -1093,35 +1050,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_ADDb:
case t_ADDw:
case t_ADDd:
*(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_CMPb:
case t_CMPw:
@ -1129,115 +1083,113 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit16u*)pos=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=B_FWD(14); // b after_call (pc+14)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_SHRb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24
*(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
break;
case t_SHRw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16
*(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
break;
case t_SHRd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_SARb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24
*(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
break;
case t_SARw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16
*(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
break;
case t_SARd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_RORb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=NOP; // nop
*(Bit16u*)(pos+8)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+14)=NOP; // nop
*(Bit16u*)(pos+16)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_RORw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6)
break;
case t_RORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
case t_ROLb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+12)=NOP; // nop
*(Bit16u*)(pos+14)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+16)=NOP; // nop
*(Bit16u*)(pos+18)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+14)=NOP; // nop
*(Bit16u*)(pos+16)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_ROLw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+14)=NOP; // nop
*(Bit16u*)(pos+16)=NOP; // nop
break;
case t_ROLd:
*(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8)
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1
*(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12)
break;
default:
*(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-thumb.h,v 1.4 2009/05/16 21:52:47 c2woody Exp $ */
/* $Id: risc_armv4le-thumb.h,v 1.6 2009/06/27 12:51:10 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (thumb version) */
@ -25,15 +25,10 @@
// temporary "lo" registers
#define templo1 HOST_v3
#define templo2 HOST_v4
// temporary "lo" register - value must be preserved when using it
#define templosav HOST_a3
// temporary "hi" register
#define temphi1 HOST_ip
#define templo3 HOST_v2
// register that holds function return values
#define FC_RETOP HOST_v2
#define FC_RETOP HOST_a1
// register used for address calculations,
#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG
@ -44,6 +39,9 @@
// register that holds the second parameter
#define FC_OP2 HOST_a2
// special register that holds the third parameter for _R3 calls (byte accessible)
#define FC_OP3 HOST_a4
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_a1
@ -83,8 +81,6 @@
#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) )
// add dst, src1, src2
#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) )
// add dst, src
#define ADD_LO_HI(dst, src) (0x4440 + (dst) + (((src) - HOST_r8) << 3) )
// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0
#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) )
// sub dst, src1, src2
@ -361,9 +357,8 @@ static void gen_extend_word(bool sign,HostReg reg) {
// add a 32bit value from memory to a full register
static void gen_add(HostReg reg,void* op) {
cache_addw( MOV_HI_LO(temphi1, reg) ); // mov temphi1, reg
gen_mov_word_to_reg(reg, op, 1);
cache_addw( ADD_LO_HI(reg, temphi1) ); // add reg, temphi1
gen_mov_word_to_reg(templo3, op, 1);
cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3
}
// add a 32bit constant value to a full register
@ -383,10 +378,8 @@ static void gen_and_imm(HostReg reg,Bit32u imm) {
// move a 32bit constant value into memory
static void gen_mov_direct_dword(void* dest,Bit32u imm) {
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templosav, imm);
gen_mov_word_from_reg(templosav, dest, 1);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_dword_to_reg_imm(templo3, imm);
gen_mov_word_from_reg(templo3, dest, 1);
}
// move an address into memory
@ -397,16 +390,14 @@ static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) {
// add an 8bit constant value to a dword memory value
static void gen_add_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, 1, templo2);
gen_mov_word_to_reg_helper(templo3, dest, 1, templo2);
if (imm >= 0) {
cache_addw( ADD_IMM8(templosav, (Bit32s)imm) ); // add templosav, #(imm)
cache_addw( ADD_IMM8(templo3, (Bit32s)imm) ); // add templo3, #(imm)
} else {
cache_addw( SUB_IMM8(templosav, -((Bit32s)imm)) ); // sub templosav, #(-imm)
cache_addw( SUB_IMM8(templo3, -((Bit32s)imm)) ); // sub templo3, #(-imm)
}
gen_mov_word_from_reg_helper(templosav, dest, 1, templo2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_word_from_reg_helper(templo3, dest, 1, templo2);
}
// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value
@ -416,32 +407,28 @@ static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) {
gen_add_direct_byte(dest,(Bit8s)imm);
return;
}
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, dword, templo2);
gen_mov_word_to_reg_helper(templo3, dest, dword, templo2);
if (dword) {
gen_mov_dword_to_reg_imm(templo1, imm);
} else {
gen_mov_word_to_reg_imm(templo1, (Bit16u)imm);
}
cache_addw( ADD_REG(templosav, templosav, templo1) ); // add templosav, templosav, templo1
gen_mov_word_from_reg_helper(templosav, dest, dword, templo2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1
gen_mov_word_from_reg_helper(templo3, dest, dword, templo2);
}
// subtract an 8bit constant value from a dword memory value
static void gen_sub_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, 1, templo2);
gen_mov_word_to_reg_helper(templo3, dest, 1, templo2);
if (imm >= 0) {
cache_addw( SUB_IMM8(templosav, (Bit32s)imm) ); // sub templosav, #(imm)
cache_addw( SUB_IMM8(templo3, (Bit32s)imm) ); // sub templo3, #(imm)
} else {
cache_addw( ADD_IMM8(templosav, -((Bit32s)imm)) ); // add templosav, #(-imm)
cache_addw( ADD_IMM8(templo3, -((Bit32s)imm)) ); // add templo3, #(-imm)
}
gen_mov_word_from_reg_helper(templosav, dest, 1, templo2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
gen_mov_word_from_reg_helper(templo3, dest, 1, templo2);
}
// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value
@ -451,17 +438,15 @@ static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) {
gen_sub_direct_byte(dest,(Bit8s)imm);
return;
}
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest);
gen_mov_word_to_reg_helper(templosav, dest, dword, templo2);
gen_mov_word_to_reg_helper(templo3, dest, dword, templo2);
if (dword) {
gen_mov_dword_to_reg_imm(templo1, imm);
} else {
gen_mov_word_to_reg_imm(templo1, (Bit16u)imm);
}
cache_addw( SUB_REG(templosav, templosav, templo1) ); // sub templosav, templosav, templo1
gen_mov_word_from_reg_helper(templosav, dest, dword, templo2);
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1
gen_mov_word_from_reg_helper(templo3, dest, dword, templo2);
}
// effective address calculation, destination is dest_reg
@ -509,7 +494,6 @@ static void INLINE gen_call_function_raw(void * func) {
cache_addd(0xe12fff10 + (templo1)); // bx templo1
// thumb state from now on
cache_addw( MOV_REG(FC_RETOP, HOST_a1) ); // mov FC_RETOP, a1
}
// generate a call to a function with paramcount parameters
@ -520,8 +504,8 @@ static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fa
gen_call_function_raw(func);
return proc_addr;
// if proc_addr is on word boundary ((proc_addr & 0x03) == 0)
// then length of generated code is 22 bytes
// otherwise length of generated code is 24 bytes
// then length of generated code is 20 bytes
// otherwise length of generated code is 22 bytes
}
#if (1)
@ -552,29 +536,28 @@ static void INLINE gen_load_param_mem(Bitu mem,Bitu param) {
// jump to an address pointed at by ptr, offset is in imm
static void gen_jmp_ptr(void * ptr,Bits imm=0) {
cache_addw( MOV_HI_LO(temphi1, templosav) ); // mov temphi1, templosav
gen_mov_word_to_reg(templosav, ptr, 1);
gen_mov_word_to_reg(templo3, ptr, 1);
if (imm) {
gen_mov_dword_to_reg_imm(templo2, imm);
cache_addw( ADD_REG(templosav, templosav, templo2) ); // add templosav, templosav, templo2
cache_addw( ADD_REG(templo3, templo3, templo2) ); // add templo3, templo3, templo2
}
#if (1)
// (*ptr) should be word aligned
if ((imm & 0x03) == 0) {
cache_addw( LDR_IMM(templo2, templosav, 0) ); // ldr templo2, [templosav]
cache_addw( LDR_IMM(templo2, templo3, 0) ); // ldr templo2, [templo3]
} else
#endif
{
cache_addw( LDRB_IMM(templo2, templosav, 0) ); // ldrb templo2, [templosav]
cache_addw( LDRB_IMM(templo1, templosav, 1) ); // ldrb templo1, [templosav, #1]
cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3]
cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1]
cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
cache_addw( LDRB_IMM(templo1, templosav, 2) ); // ldrb templo1, [templosav, #2]
cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2]
cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
cache_addw( LDRB_IMM(templo1, templosav, 3) ); // ldrb templo1, [templosav, #3]
cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3]
cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24
cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1
}
@ -582,8 +565,6 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) {
// increase jmp address to keep thumb state
cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1
cache_addw( MOV_LO_HI(templosav, temphi1) ); // mov templosav, temphi1
cache_addw( BX(templo2) ); // bx templo2
}
@ -718,7 +699,6 @@ static void gen_run_code(void) {
// return from a function
static void gen_return_function(void) {
cache_addw( MOV_REG(HOST_a1, FC_RETOP) ); // mov a1, FC_RETOP
cache_addw(0xbc08); // pop {r3}
cache_addw( BX(HOST_r3) ); // bx r3
}
@ -736,35 +716,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_ADDb:
case t_ADDw:
case t_ADDd:
*(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_CMPb:
case t_CMPw:
@ -772,116 +749,110 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit16u*)pos=B_FWD(18); // b after_call (pc+18)
*(Bit16u*)pos=B_FWD(16); // b after_call (pc+16)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_SHRb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24
*(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
break;
case t_SHRw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16
*(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
break;
case t_SHRd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_SARb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24
*(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
break;
case t_SARw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16
*(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
break;
case t_SARd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_RORb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4)
break;
case t_RORw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8)
break;
case t_RORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
case t_ROLb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+12)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+14)=NOP; // nop
*(Bit16u*)(pos+16)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+18)=NOP; // nop
*(Bit16u*)(pos+20)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+16)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+18)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_ROLw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6)
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4)
break;
case t_ROLd:
*(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10)
*(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10)
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1
*(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14)
break;
default:
*(Bit32u*)(pos+8)=(Bit32u)fct_ptr; // simple_func
@ -895,35 +866,32 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_ADDb:
case t_ADDw:
case t_ADDd:
*(Bit16u*)pos=ADD_REG(FC_RETOP, HOST_a1, HOST_a2); // add FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18)
*(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ORR(FC_RETOP, HOST_a2); // orr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=AND(FC_RETOP, HOST_a2); // and FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit16u*)pos=SUB_REG(FC_RETOP, HOST_a1, HOST_a2); // sub FC_RETOP, a1, a2
*(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18)
*(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=EOR(FC_RETOP, HOST_a2); // eor FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_CMPb:
case t_CMPw:
@ -931,114 +899,111 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit16u*)pos=B_FWD(20); // b after_call (pc+20)
*(Bit16u*)pos=B_FWD(18); // b after_call (pc+18)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit16u*)pos=ADD_IMM3(FC_RETOP, HOST_a1, 1); // add FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18)
*(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit16u*)pos=SUB_IMM3(FC_RETOP, HOST_a1, 1); // sub FC_RETOP, a1, #1
*(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18)
*(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSL_REG(FC_RETOP, HOST_a2); // lsl FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_SHRb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 24); // lsr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24
*(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
break;
case t_SHRw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, FC_RETOP, 16); // lsr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16
*(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
break;
case t_SHRd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=LSR_REG(FC_RETOP, HOST_a2); // lsr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_SARb:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 24); // lsl FC_RETOP, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 24); // asr FC_RETOP, FC_RETOP, #24
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24
*(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
break;
case t_SARw:
*(Bit16u*)pos=LSL_IMM(FC_RETOP, HOST_a1, 16); // lsl FC_RETOP, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(FC_RETOP, FC_RETOP, 16); // asr FC_RETOP, FC_RETOP, #16
*(Bit16u*)(pos+4)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+6)=B_FWD(14); // b after_call (pc+14)
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16
*(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
break;
case t_SARd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ASR_REG(FC_RETOP, HOST_a2); // asr FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_RORb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+6)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+12)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6)
break;
case t_RORw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+4)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+8)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10)
break;
case t_RORd:
*(Bit16u*)pos=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+2)=ROR_REG(FC_RETOP, HOST_a2); // ror FC_RETOP, a2
*(Bit16u*)(pos+4)=B_FWD(16); // b after_call (pc+16)
*(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
case t_ROLb:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 8); // lsr FC_RETOP, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, FC_RETOP); // orr a1, FC_RETOP
*(Bit16u*)(pos+10)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+12)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+14)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+16)=B_FWD(4); // b after_call (pc+4)
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=NOP; // nop
*(Bit16u*)(pos+12)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+14)=NOP; // nop
*(Bit16u*)(pos+16)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+18)=NOP; // nop
*(Bit16u*)(pos+20)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
break;
case t_ROLw:
*(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16
*(Bit16u*)(pos+2)=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+4)=LSR_IMM(FC_RETOP, HOST_a1, 16); // lsr FC_RETOP, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+8)=ORR(FC_RETOP, HOST_a1); // orr FC_RETOP, a1
*(Bit16u*)(pos+10)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+12)=B_FWD(8); // b after_call (pc+8)
*(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16
*(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1
*(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6)
break;
case t_ROLd:
*(Bit16u*)pos=NEG(templo1, HOST_a2); // neg templo1, a2
*(Bit16u*)(pos+2)=MOV_REG(FC_RETOP, HOST_a1); // mov FC_RETOP, a1
*(Bit16u*)(pos+4)=ADD_IMM8(templo1, 32); // add templo1, #32
*(Bit16u*)(pos+6)=ROR_REG(FC_RETOP, templo1); // ror FC_RETOP, templo1
*(Bit16u*)(pos+8)=B_FWD(12); // b after_call (pc+12)
*(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2
*(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32
*(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2
*(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12)
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit16u*)pos=NEG(FC_RETOP, HOST_a1); // neg FC_RETOP, a1
*(Bit16u*)(pos+2)=B_FWD(18); // b after_call (pc+18)
*(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1
*(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16)
break;
default:
*(Bit32u*)(pos+10)=(Bit32u)fct_ptr; // simple_func

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_mipsel32.h,v 1.5 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: risc_mipsel32.h,v 1.6 2009/06/25 19:31:43 c2woody Exp $ */
/* MIPS32 (little endian) backend by crazyc */
@ -74,6 +74,9 @@ typedef Bit8u HostReg;
// register that holds the second parameter
#define FC_OP2 HOST_a1
// special register that holds the third parameter for _R3 calls (byte accessible)
#define FC_OP3 HOST_???
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_t5

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_x64.h,v 1.12 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: risc_x64.h,v 1.13 2009/06/25 19:31:43 c2woody Exp $ */
// some configuring defines that specify the capabilities of this architecture
@ -63,6 +63,9 @@ typedef Bit8u HostReg;
// register that holds the second parameter
#define FC_OP2 HOST_ESI
// special register that holds the third parameter for _R3 calls (byte accessible)
#define FC_OP3 HOST_EAX
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_ECX
@ -290,12 +293,11 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im
imm_size=4; rm_base=0x80; //Signed dword imm
}
// ea_reg := ea_reg+TEMP_REG_DRC*(2^scale)+imm
// ea_reg := op1 + op2 *(2^scale)+imm
// ea_reg := ea_reg+scale_reg*(2^scale)+imm
cache_addb(0x48);
cache_addb(0x8d); //LEA
cache_addb(0x04+(dest_reg << 3)+rm_base); //The sib indicator
cache_addb(dest_reg+(TEMP_REG_DRC<<3)+(scale<<6));
cache_addb(dest_reg+(scale_reg<<3)+(scale<<6));
switch (imm_size) {
case 0: break;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_x86.h,v 1.9 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: risc_x86.h,v 1.10 2009/06/25 19:31:43 c2woody Exp $ */
// some configuring defines that specify the capabilities of this architecture
@ -70,6 +70,9 @@ enum HostReg {
// register that holds the second parameter
#define FC_OP2 HOST_EDX
// special register that holds the third parameter for _R3 calls (byte accessible)
#define FC_OP3 HOST_EAX
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_ECX
@ -267,11 +270,10 @@ static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits im
imm_size=4; rm_base=0x80; //Signed dword imm
}
// ea_reg := ea_reg+TEMP_REG_DRC*(2^scale)+imm
// ea_reg := op1 + op2 *(2^scale)+imm
// ea_reg := ea_reg+scale_reg*(2^scale)+imm
cache_addb(0x8d); //LEA
cache_addb(0x04+(dest_reg << 3)+rm_base); //The sib indicator
cache_addb(dest_reg+(TEMP_REG_DRC<<3)+(scale<<6));
cache_addb(dest_reg+(scale_reg<<3)+(scale<<6));
switch (imm_size) {
case 0: break;
@ -425,7 +427,9 @@ static void gen_fill_branch_long(Bit32u data) {
static void gen_run_code(void) {
cache_addd(0x0424448b); // mov eax,[esp+4]
cache_addb(0x53); // push ebx
cache_addb(0x56); // push esi
cache_addw(0xd0ff); // call eax
cache_addb(0x5e); // pop esi
cache_addb(0x5b); // pop ebx
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: core_prefetch.cpp,v 1.2 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: core_prefetch.cpp,v 1.3 2009/06/26 16:43:30 c2woody Exp $ */
#include <stdio.h>
@ -115,7 +115,7 @@ static Bit8u prefetch_buffer[MAX_PQ_SIZE];
static bool pq_valid=false;
static Bitu pq_start;
static INLINE Bit8u Fetchb() {
static Bit8u Fetchb() {
Bit8u temp;
if (pq_valid && (core.cseip>=pq_start) && (core.cseip<pq_start+CPU_PrefetchQueueSize)) {
temp=prefetch_buffer[core.cseip-pq_start];
@ -140,7 +140,7 @@ static INLINE Bit8u Fetchb() {
return temp;
}
static INLINE Bit16u Fetchw() {
static Bit16u Fetchw() {
Bit16u temp;
if (pq_valid && (core.cseip>=pq_start) && (core.cseip+2<pq_start+CPU_PrefetchQueueSize)) {
temp=prefetch_buffer[core.cseip-pq_start]|
@ -166,7 +166,7 @@ static INLINE Bit16u Fetchw() {
return temp;
}
static INLINE Bit32u Fetchd() {
static Bit32u Fetchd() {
Bit32u temp;
if (pq_valid && (core.cseip>=pq_start) && (core.cseip+4<pq_start+CPU_PrefetchQueueSize)) {
temp=prefetch_buffer[core.cseip-pq_start]|
@ -274,7 +274,7 @@ restart_opcode:
if (len>16) len=16;
char tempcode[16*2+1];char * writecode=tempcode;
for (;len>0;len--) {
sprintf(writecode,"%X",mem_readb(core.cseip++));
sprintf(writecode,"%02X",mem_readb(core.cseip++));
writecode+=2;
}
LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode);

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_files.cpp,v 1.110 2009/04/26 19:13:32 harekiet Exp $ */
/* $Id: dos_files.cpp,v 1.111 2009/06/18 18:17:54 c2woody Exp $ */
#include <string.h>
#include <stdlib.h>
@ -356,9 +356,8 @@ bool DOS_ReadFile(Bit16u entry,Bit8u * data,Bit16u * amount) {
DOS_SetError(DOSERR_INVALID_HANDLE);
return false;
};
//TODO maybe another code :)
/*
if (!(Files[handle]->flags & OPEN_READ)) {
if ((Files[handle]->flags & 0x0f) == OPEN_WRITE)) {
DOS_SetError(DOSERR_INVALID_HANDLE);
return false;
}
@ -379,9 +378,8 @@ bool DOS_WriteFile(Bit16u entry,Bit8u * data,Bit16u * amount) {
DOS_SetError(DOSERR_INVALID_HANDLE);
return false;
};
//TODO maybe another code :)
/*
if (!(Files[handle]->flags & OPEN_WRITE)) {
if ((Files[handle]->flags & 0x0f) == OPEN_READ)) {
DOS_SetError(DOSERR_INVALID_HANDLE);
return false;
}
@ -1059,7 +1057,9 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) {
*/
DOS_FCB fcb(seg,offset);
Bit32u random;Bit16u old_block;Bit8u old_rec;
Bit32u random;
Bit16u old_block=0;
Bit8u old_rec=0;
Bit8u error=0;
/* Set the correct record from the random data */
@ -1082,7 +1082,9 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) {
Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) {
/* see FCB_RandomRead */
DOS_FCB fcb(seg,offset);
Bit32u random;Bit16u old_block;Bit8u old_rec;
Bit32u random;
Bit16u old_block=0;
Bit8u old_rec=0;
Bit8u error=0;
/* Set the correct record from the random data */

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_memory.cpp,v 1.44 2009/06/08 17:20:02 c2woody Exp $ */
#include "dosbox.h"
#include "mem.h"
#include "dos_inc.h"
@ -45,7 +47,7 @@ static void DOS_CompressMemory(void) {
void DOS_FreeProcessMemory(Bit16u pspseg) {
Bit16u mcb_segment=dos.firstMCB;
DOS_MCB mcb(mcb_segment);
while (true) {
for (;;) {
if (mcb.GetPSPSeg()==pspseg) {
mcb.SetPSPSeg(MCB_FREE);
}
@ -64,7 +66,7 @@ void DOS_FreeProcessMemory(Bit16u pspseg) {
Bit16u umb_start=dos_infoblock.GetStartOfUMBChain();
if (umb_start==UMB_START_SEG) {
DOS_MCB umb_mcb(umb_start);
while (true) {
for (;;) {
if (umb_mcb.GetPSPSeg()==pspseg) {
umb_mcb.SetPSPSeg(MCB_FREE);
}
@ -394,8 +396,8 @@ void DOS_SetupMemory(void) {
* buggy games, which compare against the interrupt table. (probably a
* broken linked list implementation) */
callbackhandler.Allocate(&DOS_default_handler,"DOS default int");
Bitu ihseg = 0x70;
Bitu ihofs = 0x08;
Bit16u ihseg = 0x70;
Bit16u ihofs = 0x08;
real_writeb(ihseg,ihofs+0x00,(Bit8u)0xFE); //GRP 4
real_writeb(ihseg,ihofs+0x01,(Bit8u)0x38); //Extra Callback instruction
real_writew(ihseg,ihofs+0x02,callbackhandler.Get_callback()); //The immediate word
@ -434,12 +436,12 @@ void DOS_SetupMemory(void) {
if (machine==MCH_TANDY) {
/* memory up to 608k available, the rest (to 640k) is used by
the tandy graphics system's variable mapping of 0xb800 */
mcb.SetSize(0x97FE - DOS_MEM_START - mcb_sizes);
mcb.SetSize(0x97FF - DOS_MEM_START - mcb_sizes);
} else if (machine==MCH_PCJR) {
/* memory from 128k to 640k is available */
mcb_devicedummy.SetPt((Bit16u)0x2000);
mcb_devicedummy.SetPSPSeg(MCB_FREE);
mcb_devicedummy.SetSize(0x9FFE - 0x2000);
mcb_devicedummy.SetSize(0x9FFF - 0x2000);
mcb_devicedummy.SetType(0x5a);
/* exclude PCJr graphics region */
@ -453,6 +455,7 @@ void DOS_SetupMemory(void) {
mcb.SetType(0x4d);
} else {
/* complete memory up to 640k available */
/* last paragraph used to add UMB chain to low-memory MCB chain */
mcb.SetSize(0x9FFE - DOS_MEM_START - mcb_sizes);
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_programs.cpp,v 1.93 2009/04/16 12:28:30 qbix79 Exp $ */
/* $Id: dos_programs.cpp,v 1.94 2009/06/12 20:10:09 c2woody Exp $ */
#include "dosbox.h"
#include <stdlib.h>
@ -142,7 +142,7 @@ public:
return;
}
/* In secure mode don't allow people to change mount points.
/* In secure mode don't allow people to change mount points.
* Neither mount nor unmount */
if(control->SecureMode()) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
@ -157,7 +157,7 @@ public:
switch (DriveManager::UnmountDrive(i_drive)) {
case 0:
Drives[i_drive] = 0;
if(i_drive == DOS_GetDefaultDrive())
if(i_drive == DOS_GetDefaultDrive())
DOS_SetDrive(toupper('Z') - 'A');
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]);
break;
@ -173,7 +173,7 @@ public:
}
return;
}
// Show list of cdroms
if (cmd->FindExist("-cd",false)) {
int num = SDL_CDNumDrives();
@ -218,7 +218,7 @@ public:
}
str_size=teststr;
}
cmd->FindString("-size",str_size,true);
char number[20];const char * scan=str_size.c_str();
Bitu index=0;Bitu count=0;
@ -231,7 +231,7 @@ public:
scan++;
}
number[index]=0;sizes[count++]=atoi(number);
// get the drive letter
cmd->FindCommand(1,temp_line);
if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) goto showusage;
@ -307,7 +307,7 @@ public:
if (type=="cdrom") {
int num = -1;
cmd->FindInt("-usecd",num,true);
int error;
int error = 0;
if (cmd->FindExist("-aspi",false)) {
MSCDEX_SetCDInterface(CDROM_USE_ASPI, num);
} else if (cmd->FindExist("-ioctl_dio",false)) {
@ -354,8 +354,8 @@ public:
} else {
/* Give a warning when mount c:\ or the / */
#if defined (WIN32) || defined(OS2)
if( (temp_line == "c:\\") || (temp_line == "C:\\") ||
(temp_line == "c:/") || (temp_line == "C:/") )
if( (temp_line == "c:\\") || (temp_line == "C:\\") ||
(temp_line == "c:/") || (temp_line == "C:/") )
WriteOut(MSG_Get("PROGRAM_MOUNT_WARNING_WIN"));
#else
if(temp_line == "/") WriteOut(MSG_Get("PROGRAM_MOUNT_WARNING_OTHER"));
@ -381,7 +381,7 @@ public:
/* For hard drives set the label to DRIVELETTER_Drive.
* For floppy drives set the label to DRIVELETTER_Floppy.
* This way every drive except cdroms should get a label.*/
else if(type == "dir") {
else if(type == "dir") {
label = drive; label += "_DRIVE";
newdrive->dirCache.SetLabel(label.c_str(),iscdrom,true);
} else if(type == "floppy") {
@ -450,7 +450,7 @@ public:
if (!reg_bl) {
WriteOut(MSG_Get("PROGRAM_MEM_EXTEND"),reg_dx);
}
}
}
/* Test for and show free EMS */
Bit16u handle;
char emm[9] = { 'E','M','M','X','X','X','X','0',0 };
@ -473,7 +473,7 @@ extern Bit32u floppytype;
class BOOT : public Program {
private:
FILE *getFSFile_mounted(char const* filename, Bit32u *ksize, Bit32u *bsize, Bit8u *error) {
//if return NULL then put in error the errormessage code if an error was requested
bool tryload = (*error)?true:false;
@ -485,7 +485,7 @@ private:
localDrive* ldp=0;
if (!DOS_MakeName(const_cast<char*>(filename),fullname,&drive)) return NULL;
try {
try {
ldp=dynamic_cast<localDrive*>(Drives[drive]);
if(!ldp) return NULL;
@ -519,7 +519,7 @@ private:
return NULL;
}
}
FILE *getFSFile(char const * filename, Bit32u *ksize, Bit32u *bsize,bool tryload=false) {
Bit8u error = tryload?1:0;
FILE* tmpfile = getFSFile_mounted(filename,ksize,bsize,&error);
@ -568,11 +568,11 @@ private:
}
public:
void Run(void) {
//Hack To allow long commandlines
ChangeToLongCmd();
/* In secure mode don't allow people to boot stuff.
/* In secure mode don't allow people to boot stuff.
* They might try to corrupt the data on it */
if(control->SecureMode()) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
@ -581,7 +581,7 @@ public:
FILE *usefile_1=NULL;
FILE *usefile_2=NULL;
Bitu i=0;
Bitu i=0;
Bit32u floppysize;
Bit32u rombytesize_1=0;
Bit32u rombytesize_2=0;
@ -800,7 +800,7 @@ public:
/* boot cartridge (int18) */
SegSet16(cs,RealSeg(new_int18));
reg_ip = RealOff(new_int18);
}
}
} else {
if (cfound_at>0) {
/* run cartridge setup */
@ -827,7 +827,7 @@ public:
SegSet16(es, 0);
/* set up stack at a safe place */
SegSet16(ss, 0x7000);
reg_esp = 0x400;
reg_esp = 0x100;
reg_esi = 0;
reg_ecx = 1;
reg_ebp = 0;
@ -855,7 +855,7 @@ public:
localDrive* ldp=0;
if (!DOS_MakeName((char *)temp_line.c_str(),fullname,&drive)) return;
try {
try {
ldp=dynamic_cast<localDrive*>(Drives[drive]);
if(!ldp) return;
@ -906,7 +906,7 @@ public:
void Run(void);
};
void LOADFIX::Run(void)
void LOADFIX::Run(void)
{
Bit16u commandNr = 1;
Bit16u kb = 64;
@ -948,15 +948,15 @@ void LOADFIX::Run(void)
break;
strcat(args,temp_line.c_str());
strcat(args," ");
} while (ok);
} while (ok);
// Use shell to start program
DOS_Shell shell;
shell.Execute(filename,args);
DOS_FreeMemory(segment);
DOS_FreeMemory(segment);
WriteOut(MSG_Get("PROGRAM_LOADFIX_DEALLOC"),kb);
}
} else {
WriteOut(MSG_Get("PROGRAM_LOADFIX_ERROR"),kb);
WriteOut(MSG_Get("PROGRAM_LOADFIX_ERROR"),kb);
}
}
@ -971,7 +971,7 @@ public:
void Run(void);
};
void RESCAN::Run(void)
void RESCAN::Run(void)
{
// Get current drive
Bit8u drive = DOS_GetDefaultDrive();
@ -995,7 +995,7 @@ public:
WriteOut(MSG_Get("PROGRAM_INTRO_MOUNT_WII"));
#elif (WIN32)
WriteOut(MSG_Get("PROGRAM_INTRO_MOUNT_WINDOWS"));
#else
#else
WriteOut(MSG_Get("PROGRAM_INTRO_MOUNT_OTHER"));
#endif
WriteOut(MSG_Get("PROGRAM_INTRO_MOUNT_END"));
@ -1038,7 +1038,7 @@ public:
void Run(void) {
//Hack To allow long commandlines
ChangeToLongCmd();
/* In secure mode don't allow people to change imgmount points.
/* In secure mode don't allow people to change imgmount points.
* Neither mount nor unmount */
if(control->SecureMode()) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
@ -1059,7 +1059,7 @@ public:
switch (DriveManager::UnmountDrive(i_drive)) {
case 0:
Drives[i_drive] = 0;
if (i_drive == DOS_GetDefaultDrive())
if (i_drive == DOS_GetDefaultDrive())
DOS_SetDrive(toupper('Z') - 'A');
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]);
break;
@ -1086,17 +1086,17 @@ public:
if (type=="floppy" || type=="hdd" || type=="iso") {
Bit16u sizes[4];
bool imgsizedetect=false;
std::string str_size;
mediaid=0xF8;
if (type=="floppy") {
mediaid=0xF0;
mediaid=0xF0;
} else if (type=="iso") {
str_size="650,127,16513,1700";
mediaid=0xF8;
mediaid=0xF8;
fstype = "iso";
}
}
cmd->FindString("-size",str_size,true);
if ((type=="hdd") && (str_size.size()==0)) {
imgsizedetect=true;
@ -1104,7 +1104,7 @@ public:
char number[20];
const char * scan=str_size.c_str();
Bitu index=0;Bitu count=0;
while (*scan) {
if (*scan==',') {
number[index]=0;sizes[count++]=atoi(number);
@ -1114,7 +1114,7 @@ public:
}
number[index]=0;sizes[count++]=atoi(number);
}
if(fstype=="fat" || fstype=="iso") {
// get the drive letter
if (!cmd->FindCommand(1,temp_line) || (temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) {
@ -1141,10 +1141,10 @@ public:
WriteOut_NoParsing(MSG_Get("PROGRAM_IMGMOUNT_FORMAT_UNSUPPORTED"));
return;
}
// find all file parameters, assuming that all option parameters have been removed
while(cmd->FindCommand((unsigned int)(paths.size() + 2), temp_line) && temp_line.size()) {
struct stat test;
if (stat(temp_line.c_str(),&test)) {
//See if it works if the ~ are written out
@ -1187,7 +1187,7 @@ public:
}
if (paths.size() == 0) {
WriteOut(MSG_Get("PROGRAM_IMGMOUNT_SPECIFY_FILE"));
return;
return;
}
if (paths.size() == 1)
temp_line = paths[0];
@ -1253,7 +1253,7 @@ public:
}
if (!newdrive) {WriteOut(MSG_Get("PROGRAM_IMGMOUNT_CANT_CREATE"));return;}
Drives[drive-'A']=newdrive;
// Set the correct media byte in the table
// Set the correct media byte in the table
mem_writeb(Real2Phys(dos.tables.mediaid)+(drive-'A')*2,mediaid);
WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,temp_line.c_str());
if(((fatDrive *)newdrive)->loadedDisk->hardDrive) {
@ -1308,10 +1308,10 @@ public:
DriveManager::AppendDisk(drive - 'A', isoDisks[ct]);
}
DriveManager::InitializeDrive(drive - 'A');
// Set the correct media byte in the table
// Set the correct media byte in the table
mem_writeb(Real2Phys(dos.tables.mediaid) + (drive - 'A') * 2, mediaid);
// Print status message (success)
WriteOut(MSG_Get("MSCDEX_SUCCESS"));
std::string tmp(paths[0]);
@ -1319,7 +1319,7 @@ public:
tmp += "; " + paths[i];
}
WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"), drive, tmp.c_str());
} else if (fstype=="none") {
if(imageDiskList[drive-'0'] != NULL) delete imageDiskList[drive-'0'];
imageDiskList[drive-'0'] = newImage;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_fat.cpp,v 1.27 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: drive_fat.cpp,v 1.28 2009/06/19 18:28:10 c2woody Exp $ */
#include <stdio.h>
#include <stdlib.h>
@ -105,6 +105,10 @@ fatFile::fatFile(const char* /*name*/, Bit32u startCluster, Bit32u fileLen, fatD
}
bool fatFile::Read(Bit8u * data, Bit16u *size) {
if ((this->flags & 0xf) == OPEN_WRITE) { // check if file opened in write-only mode
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
Bit16u sizedec, sizecount;
if(seekpos >= filelength) {
*size = 0;
@ -156,6 +160,11 @@ bool fatFile::Read(Bit8u * data, Bit16u *size) {
bool fatFile::Write(Bit8u * data, Bit16u *size) {
/* TODO: Check for read-only bit */
if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
direntry tmpentry;
Bit16u sizedec, sizecount;
sizedec = *size;
@ -767,7 +776,7 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) {
char dirName[DOS_NAMELENGTH_ASCII];
char pathName[11];
Bitu save_errorcode=dos.errorcode;
Bit16u save_errorcode=dos.errorcode;
/* Check if file already exists */
if(getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) {
@ -793,6 +802,7 @@ bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) {
/* Empty file created, now lets open it */
/* TODO: check for read-only flag and requested write access */
*file = new fatFile(name, fileEntry.loFirstClust, fileEntry.entrysize, this);
(*file)->flags=OPEN_READWRITE;
((fatFile *)(*file))->dirCluster = dirClust;
((fatFile *)(*file))->dirIndex = subEntry;
/* Maybe modTime and date should be used ? (crt matches findnext) */
@ -810,12 +820,13 @@ bool fatDrive::FileExists(const char *name) {
return true;
}
bool fatDrive::FileOpen(DOS_File **file, char *name, Bit32u /*flags*/) {
bool fatDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) {
direntry fileEntry;
Bit32u dirClust, subEntry;
if(!getFileDirEntry(name, &fileEntry, &dirClust, &subEntry)) return false;
/* TODO: check for read-only flag and requested write access */
*file = new fatFile(name, fileEntry.loFirstClust, fileEntry.entrysize, this);
(*file)->flags = flags;
((fatFile *)(*file))->dirCluster = dirClust;
((fatFile *)(*file))->dirIndex = subEntry;
/* Maybe modTime and date should be used ? (crt matches findnext) */

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_iso.cpp,v 1.25 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: drive_iso.cpp,v 1.26 2009/06/19 18:28:10 c2woody Exp $ */
#include <cctype>
#include <cstring>
@ -46,8 +46,7 @@ private:
Bit16u info;
};
isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset)
{
isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset) {
this->drive = drive;
time = stat->time;
date = stat->date;
@ -61,8 +60,7 @@ isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u
SetName(name);
}
bool isoFile::Read(Bit8u *data, Bit16u *size)
{
bool isoFile::Read(Bit8u *data, Bit16u *size) {
if (filePos + *size > fileEnd)
*size = (Bit16u)(fileEnd - filePos);
@ -99,13 +97,11 @@ bool isoFile::Read(Bit8u *data, Bit16u *size)
return true;
}
bool isoFile::Write(Bit8u *data, Bit16u *size)
{
bool isoFile::Write(Bit8u* /*data*/, Bit16u* /*size*/) {
return false;
}
bool isoFile::Seek(Bit32u *pos, Bit32u type)
{
bool isoFile::Seek(Bit32u *pos, Bit32u type) {
switch (type) {
case DOS_SEEK_SET:
filePos = fileBegin + *pos;
@ -126,14 +122,12 @@ bool isoFile::Seek(Bit32u *pos, Bit32u type)
return true;
}
bool isoFile::Close()
{
bool isoFile::Close() {
if (refCtr == 1) open = false;
return true;
}
Bit16u isoFile::GetInformation(void)
{
Bit16u isoFile::GetInformation(void) {
return 0x40; // read-only drive
}
@ -143,8 +137,7 @@ void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit);
bool MSCDEX_HasDrive(char driveLetter);
bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name);
isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error)
{
isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) {
nextFreeDirIterator = 0;
memset(dirIterators, 0, sizeof(dirIterators));
memset(sectorHashEntries, 0, sizeof(sectorHashEntries));
@ -199,9 +192,8 @@ void isoDrive::Activate(void) {
UpdateMscdex(driveLetter, fileName, subUnit);
}
bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags)
{
if (flags == OPEN_WRITE) {
bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags) {
if ((flags & 0x0f) == OPEN_WRITE) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
@ -221,38 +213,32 @@ bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags)
return success;
}
bool isoDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes)
{
bool isoDrive::FileCreate(DOS_File** /*file*/, char* /*name*/, Bit16u /*attributes*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::FileUnlink(char *name)
{
bool isoDrive::FileUnlink(char* /*name*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::RemoveDir(char *dir)
{
bool isoDrive::RemoveDir(char* /*dir*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::MakeDir(char *dir)
{
bool isoDrive::MakeDir(char* /*dir*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::TestDir(char *dir)
{
bool isoDrive::TestDir(char *dir) {
isoDirEntry de;
return (lookup(&de, dir) && IS_DIR(de.fileFlags));
}
bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst)
{
bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst) {
isoDirEntry de;
if (!lookup(&de, dir)) {
DOS_SetError(DOSERR_PATH_NOT_FOUND);
@ -285,8 +271,7 @@ bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst)
return FindNext(dta);
}
bool isoDrive::FindNext(DOS_DTA &dta)
{
bool isoDrive::FindNext(DOS_DTA &dta) {
Bit8u attr;
char pattern[DOS_NAMELENGTH_ASCII];
dta.GetSearchParams(attr, pattern);
@ -324,14 +309,12 @@ bool isoDrive::FindNext(DOS_DTA &dta)
return false;
}
bool isoDrive::Rename(char *oldname, char *newname)
{
bool isoDrive::Rename(char* /*oldname*/, char* /*newname*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::GetFileAttr(char *name, Bit16u *attr)
{
bool isoDrive::GetFileAttr(char *name, Bit16u *attr) {
*attr = 0;
isoDirEntry de;
bool success = lookup(&de, name);
@ -343,8 +326,7 @@ bool isoDrive::GetFileAttr(char *name, Bit16u *attr)
return success;
}
bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters)
{
bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters) {
*bytes_sector = 2048;
*sectors_cluster = 1; // cluster size for cdroms ?
*total_clusters = 60000;
@ -352,14 +334,12 @@ bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit1
return true;
}
bool isoDrive::FileExists(const char *name)
{
bool isoDrive::FileExists(const char *name) {
isoDirEntry de;
return (lookup(&de, name) && !IS_DIR(de.fileFlags));
}
bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block)
{
bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block) {
isoDirEntry de;
bool success = lookup(&de, name);
@ -374,18 +354,15 @@ bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block)
return success;
}
Bit8u isoDrive::GetMediaByte(void)
{
Bit8u isoDrive::GetMediaByte(void) {
return mediaid;
}
bool isoDrive::isRemote(void)
{
bool isoDrive::isRemote(void) {
return true;
}
bool isoDrive::isRemovable(void)
{
bool isoDrive::isRemovable(void) {
return true;
}
@ -397,8 +374,7 @@ Bits isoDrive::UnMount(void) {
return 2;
}
int isoDrive::GetDirIterator(const isoDirEntry* de)
{
int isoDrive::GetDirIterator(const isoDirEntry* de) {
int dirIterator = nextFreeDirIterator;
// get start and end sector of the directory entry (pad end sector if necessary)
@ -418,8 +394,7 @@ int isoDrive::GetDirIterator(const isoDirEntry* de)
return dirIterator;
}
bool isoDrive::GetNextDirEntry(const int dirIteratorHandle, isoDirEntry* de)
{
bool isoDrive::GetNextDirEntry(const int dirIteratorHandle, isoDirEntry* de) {
bool result = false;
Bit8u* buffer = NULL;
DirIterator& dirIterator = dirIterators[dirIteratorHandle];
@ -450,8 +425,7 @@ bool isoDrive::GetNextDirEntry(const int dirIteratorHandle, isoDirEntry* de)
return result;
}
void isoDrive::FreeDirIterator(const int dirIterator)
{
void isoDrive::FreeDirIterator(const int dirIterator) {
dirIterators[dirIterator].valid = false;
// if this was the last aquired iterator decrement nextFreeIterator
@ -460,8 +434,7 @@ void isoDrive::FreeDirIterator(const int dirIterator)
}
}
bool isoDrive::ReadCachedSector(Bit8u** buffer, const Bit32u sector)
{
bool isoDrive::ReadCachedSector(Bit8u** buffer, const Bit32u sector) {
// get hash table entry
int pos = sector % ISO_MAX_HASH_TABLE_SIZE;
SectorHashEntry& he = sectorHashEntries[pos];
@ -479,13 +452,11 @@ bool isoDrive::ReadCachedSector(Bit8u** buffer, const Bit32u sector)
return true;
}
inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector)
{
inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector) {
return CDROM_Interface_Image::images[subUnit]->ReadSector(buffer, false, sector);
}
int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data)
{
int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data) {
// copy data into isoDirEntry struct, data[0] = length of DirEntry
// if (data[0] > sizeof(isoDirEntry)) return -1;//check disabled as isoDirentry is currently 258 bytes large. So it always fits
memcpy(de, data, data[0]);//Perharps care about a zero at the end.
@ -525,8 +496,7 @@ int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data)
return de->length;
}
bool isoDrive :: loadImage()
{
bool isoDrive :: loadImage() {
isoPVD pvd;
dataCD = false;
readSector((Bit8u*)(&pvd), ISO_FIRST_VD);
@ -538,8 +508,7 @@ bool isoDrive :: loadImage()
return false;
}
bool isoDrive :: lookup(isoDirEntry *de, const char *path)
{
bool isoDrive :: lookup(isoDirEntry *de, const char *path) {
if (!dataCD) return false;
*de = this->rootEntry;
if (!strcmp(path, "")) return true;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_local.cpp,v 1.79 2009/04/26 18:24:36 qbix79 Exp $ */
/* $Id: drive_local.cpp,v 1.81 2009/06/18 18:17:54 c2woody Exp $ */
#include <stdio.h>
#include <stdlib.h>
@ -48,7 +48,7 @@ private:
};
bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) {
bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u /*attributes*/) {
//TODO Maybe care for attributes but not likely
char newname[CROSS_LEN];
strcpy(newname,basedir);
@ -74,22 +74,21 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) {
if(!existing_file) dirCache.AddEntry(newname, true);
/* Make the 16 bit device information */
*file=new localFile(name,hand);
(*file)->flags=OPEN_READWRITE;
return true;
}
bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
const char* type;
switch (flags &3) {
switch (flags&0xf) {
case OPEN_READ:type="rb"; break;
case OPEN_WRITE:type="rb+"; break;
case OPEN_WRITE:type="wb"; break;
case OPEN_READWRITE:type="rb+"; break;
default:
//TODO FIX IT
type="rb+";
// return false;
};
DOS_SetError(DOSERR_ACCESS_CODE_INVALID);
return false;
}
char newname[CROSS_LEN];
strcpy(newname,basedir);
strcat(newname,name);
@ -99,7 +98,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
FILE * hand=fopen(newname,type);
// Bit32u err=errno;
if (!hand) {
if((flags&3) != OPEN_READ) {
if((flags&0xf) != OPEN_READ) {
FILE * hmm=fopen(newname,"rb");
if (hmm) {
fclose(hmm);
@ -136,7 +135,6 @@ bool localDrive::GetSystemFilename(char *sysName, char const * const dosName) {
}
bool localDrive::FileUnlink(char * name) {
char newname[CROSS_LEN];
strcpy(newname,basedir);
strcat(newname,name);
@ -175,11 +173,9 @@ bool localDrive::FileUnlink(char * name) {
dirCache.DeleteEntry(newname);
return true;
}
return false;
}
bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) {
char tempDir[CROSS_LEN];
strcpy(tempDir,basedir);
strcat(tempDir,_dir);
@ -193,8 +189,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) {
if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end);
Bitu id;
if (!dirCache.FindFirst(tempDir,id))
{
if (!dirCache.FindFirst(tempDir,id)) {
DOS_SetError(DOSERR_PATH_NOT_FOUND);
return false;
}
@ -279,8 +274,8 @@ again:
find_size=(Bit32u) stat_block.st_size;
struct tm *time;
if((time=localtime(&stat_block.st_mtime))!=0){
find_date=DOS_PackDate(time->tm_year+1900,time->tm_mon+1,time->tm_mday);
find_time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec);
find_date=DOS_PackDate((Bit16u)(time->tm_year+1900),(Bit16u)(time->tm_mon+1),(Bit16u)time->tm_mday);
find_time=DOS_PackTime((Bit16u)time->tm_hour,(Bit16u)time->tm_min,(Bit16u)time->tm_sec);
} else {
find_time=6;
find_date=4;
@ -399,8 +394,8 @@ bool localDrive::FileStat(const char* name, FileStat_Block * const stat_block) {
/* Convert the stat to a FileStat */
struct tm *time;
if((time=localtime(&temp_stat.st_mtime))!=0) {
stat_block->time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec);
stat_block->date=DOS_PackDate(time->tm_year+1900,time->tm_mon+1,time->tm_mday);
stat_block->time=DOS_PackTime((Bit16u)time->tm_hour,(Bit16u)time->tm_min,(Bit16u)time->tm_sec);
stat_block->date=DOS_PackDate((Bit16u)(time->tm_year+1900),(Bit16u)(time->tm_mon+1),(Bit16u)time->tm_mday);
} else {
}
@ -441,6 +436,10 @@ localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors
//TODO Maybe use fflush, but that seemed to fuck up in visual c
bool localFile::Read(Bit8u * data,Bit16u * size) {
if ((this->flags & 0xf) == OPEN_WRITE) { // check if file opened in write-only mode
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
if (last_action==WRITE) fseek(fhandle,ftell(fhandle),SEEK_SET);
last_action=READ;
*size=(Bit16u)fread(data,1,*size,fhandle);
@ -453,6 +452,10 @@ bool localFile::Read(Bit8u * data,Bit16u * size) {
}
bool localFile::Write(Bit8u * data,Bit16u * size) {
if ((this->flags & 0xf) == OPEN_READ) { // check if file opened in read-only mode
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
if (last_action==READ) fseek(fhandle,ftell(fhandle),SEEK_SET);
last_action=WRITE;
if(*size==0){
@ -509,20 +512,13 @@ Bit16u localFile::GetInformation(void) {
localFile::localFile(const char* _name, FILE * handle) {
fhandle=handle;
struct stat temp_stat;
fstat(fileno(handle),&temp_stat);
struct tm * ltime;
if((ltime=localtime(&temp_stat.st_mtime))!=0) {
time=DOS_PackTime(ltime->tm_hour,ltime->tm_min,ltime->tm_sec);
date=DOS_PackDate(ltime->tm_year+1900,ltime->tm_mon+1,ltime->tm_mday);
} else {
time=1;date=1;
}
open=true;
UpdateDateTimeFromHost();
attr=DOS_ATTR_ARCHIVE;
last_action=NONE;
read_only_medium=false;
open=true;
name=0;
SetName(_name);
}
@ -537,8 +533,8 @@ bool localFile::UpdateDateTimeFromHost(void) {
fstat(fileno(fhandle),&temp_stat);
struct tm * ltime;
if((ltime=localtime(&temp_stat.st_mtime))!=0) {
time=DOS_PackTime(ltime->tm_hour,ltime->tm_min,ltime->tm_sec);
date=DOS_PackDate(ltime->tm_year+1900,ltime->tm_mon+1,ltime->tm_mday);
time=DOS_PackTime((Bit16u)ltime->tm_hour,(Bit16u)ltime->tm_min,(Bit16u)ltime->tm_sec);
date=DOS_PackDate((Bit16u)(ltime->tm_year+1900),(Bit16u)(ltime->tm_mon+1),(Bit16u)ltime->tm_mday);
} else {
time=1;date=1;
}
@ -569,9 +565,9 @@ cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _byt
}
bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
if ((flags&3)==OPEN_READWRITE) {
if ((flags&0xf)==OPEN_READWRITE) {
flags &= ~OPEN_READWRITE;
} else if ((flags&3)==OPEN_WRITE) {
} else if ((flags&0xf)==OPEN_WRITE) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
@ -580,27 +576,27 @@ bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
return retcode;
}
bool cdromDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) {
bool cdromDrive::FileCreate(DOS_File * * /*file*/,char * /*name*/,Bit16u /*attributes*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool cdromDrive::FileUnlink(char * name) {
bool cdromDrive::FileUnlink(char * /*name*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool cdromDrive::RemoveDir(char * dir) {
bool cdromDrive::RemoveDir(char * /*dir*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool cdromDrive::MakeDir(char * dir) {
bool cdromDrive::MakeDir(char * /*dir*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool cdromDrive::Rename(char * oldname,char * newname) {
bool cdromDrive::Rename(char * /*oldname*/,char * /*newname*/) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
@ -611,7 +607,7 @@ bool cdromDrive::GetFileAttr(char * name,Bit16u * attr) {
return result;
}
bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) {
bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta,bool /*fcb_findfirst*/) {
// If media has changed, reInit drivecache.
if (MSCDEX_HasMediaChanged(subUnit)) {
dirCache.EmptyCache();

View File

@ -16,9 +16,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cmos.cpp,v 1.28 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: cmos.cpp,v 1.29 2009/06/16 18:19:18 qbix79 Exp $ */
#include <time.h>
#include <math.h>
#include "dosbox.h"
#include "timer.h"
@ -27,6 +28,7 @@
#include "mem.h"
#include "bios_disk.h"
#include "setup.h"
#include "cross.h" //fmod on certain platforms
static struct {
Bit8u regs[0x40];
@ -64,8 +66,9 @@ static void cmos_checktimer(void) {
cmos.timer.delay=(1000.0f/(32768.0f / (1 << (cmos.timer.div - 1))));
if (!cmos.timer.div || !cmos.timer.enabled) return;
LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %.2f hz",1000.0/cmos.timer.delay);
PIC_AddEvent(cmos_timerevent,cmos.timer.delay);
// PIC_AddEvent(cmos_timerevent,(double)cmos.timer.delay-fmod(PIC_FullIndex(),(double)cmos.timer.delay)); //Should be more like a real pc. Check
// PIC_AddEvent(cmos_timerevent,cmos.timer.delay);
/* A rtc is always running */
PIC_AddEvent(cmos_timerevent,(double)cmos.timer.delay-fmod(PIC_FullIndex(),(double)cmos.timer.delay)); //Should be more like a real pc. Check
// status reg A reading with this (and with other delays actually)
}

View File

@ -32,6 +32,8 @@
//DUNNO Keyon in 4op, switch to 2op without keyoff.
*/
/* $Id: dbopl.cpp,v 1.10 2009/06/10 19:54:51 harekiet Exp $ */
#include <math.h>
#include <stdlib.h>
@ -472,7 +474,7 @@ void Operator::Write20( const Chip* chip, Bit8u val ) {
}
}
void Operator::Write40( const Chip* chip, Bit8u val ) {
void Operator::Write40( const Chip* /*chip*/, Bit8u val ) {
if (!(reg40 ^ val ))
return;
reg40 = val;
@ -803,46 +805,33 @@ INLINE void Channel::GeneratePercussion( Chip* chip, Bit32s* output ) {
}
Bit32s sample = Op(1)->GetSample( mod );
Operator* op2 = ( this + 1 )->Op(0);
Operator* op4 = ( this + 2 )->Op(0);
//Precalculate stuff used by other outputs
Bit32u noiseBit = (chip->ForwardNoise() & 0x1) << 1;
Bit32u c2 = op2->ForwardWave();
//(bit 7 ^ bit 2) | bit 3 -> combined in bit 1
Bit32u phaseBit = ( (c2 >> 6) ^ ( c2 >> 1 ) ) | ( c2 >> 2 );
Bit32u c4 = op4->ForwardWave();
//bit 5 ^ bit 3 to bit 1
Bit32u gateBit = ( c4 >> 4 ) ^ ( c4 >> 3 );
phaseBit = (phaseBit | gateBit) & 0x2;
Bit32u noiseBit = chip->ForwardNoise() & 0x1;
Bit32u c2 = Op(2)->ForwardWave();
Bit32u c5 = Op(5)->ForwardWave();
Bit32u phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00;
//Hi-Hat
Bit32u hhVol = op2->ForwardVolume();
Bit32u hhVol = Op(2)->ForwardVolume();
if ( !ENV_SILENT( hhVol ) ) {
/* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */
/* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */
Bit32u hhIndex = ( phaseBit << 8 ) | ( 0xd0 >> ( phaseBit ^ noiseBit ) );
sample += op2->GetWave( hhIndex, hhVol );
Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 )));
sample += Op(2)->GetWave( hhIndex, hhVol );
}
//Snare Drum
Operator* op3 = ( this + 1 )->Op(1);
Bit32u sdVol = op3->ForwardVolume();
Bit32u sdVol = Op(3)->ForwardVolume();
if ( !ENV_SILENT( sdVol ) ) {
Bit32u sdBits = 0x100 + (c2 & 0x100);
Bit32u sdIndex = sdBits ^ ( noiseBit << 7 );
sample += op3->GetWave( sdIndex, sdVol );
Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 );
sample += Op(3)->GetWave( sdIndex, sdVol );
}
//Tom-tom
Bit32u ttVol = op4->ForwardVolume();
if ( !ENV_SILENT( ttVol ) ) {
sample += op4->GetWave( c4, ttVol );
}
sample += Op(4)->GetSample( 0 );
//Top-Cymbal
Operator* op5 = ( this + 2 )->Op(1);
Bit32u tcVol = op5->ForwardVolume();
Bit32u tcVol = Op(5)->ForwardVolume();
if ( !ENV_SILENT( tcVol ) ) {
Bit32u tcIndex = (1 + phaseBit) << 8;
sample += op5->GetWave( tcIndex, tcVol );
sample += Op(5)->GetWave( tcIndex, tcVol );
}
sample <<= 1;
if ( opl3Mode ) {
@ -1261,7 +1250,7 @@ void Chip::Setup( Bit32u rate ) {
Bit32s original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale);
Bit32s guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 )));
Bit32s bestAdd;
Bit32s bestAdd = guessAdd;
Bit32u bestDiff = 1 << 30;
for( Bit32u passes = 0; passes < 16; passes ++ ) {
Bit32s volume = ENV_MAX;
@ -1368,7 +1357,7 @@ void InitTables( void ) {
for ( int i = 0; i < 384; i++ ) {
int s = i * 8;
//TODO maybe keep some of the precision errors of the original table?
double val = ( 0.5 + ( pow(2, -1 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH ));
double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH ));
MulTable[i] = (Bit16u)(val);
}
@ -1379,7 +1368,7 @@ void InitTables( void ) {
}
//Exponential wave
for ( int i = 0; i < 256; i++ ) {
WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2, -1 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 );
WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 );
WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ];
}
#endif

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: sblaster.cpp,v 1.73 2009/04/25 07:02:28 qbix79 Exp $ */
/* $Id: sblaster.cpp,v 1.76 2009/06/10 17:44:59 c2woody Exp $ */
#include <iomanip>
#include <sstream>
@ -62,7 +62,7 @@ bool MIDI_Available(void);
#define SB_SH 14
#define SB_SH_MASK ((1 << SB_SH)-1)
enum {DSP_S_RESET,DSP_S_NORMAL,DSP_S_HIGHSPEED};
enum {DSP_S_RESET,DSP_S_RESET_WAIT,DSP_S_NORMAL,DSP_S_HIGHSPEED};
enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6};
enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU};
@ -117,6 +117,7 @@ struct SB_INFO {
Bit8u cmd_in_pos;
Bit8u cmd_in[DSP_BUFSIZE];
struct {
Bit8u lastval;
Bit8u data[DSP_BUFSIZE];
Bitu pos,used;
} in,out;
@ -145,7 +146,7 @@ struct SB_INFO {
struct {
Bitu base;
Bitu irq;
Bitu dma8,dma16;
Bit8u dma8,dma16;
} hw;
struct {
Bits value;
@ -246,13 +247,22 @@ static void DSP_SetSpeaker(bool how) {
static INLINE void SB_RaiseIRQ(SB_IRQS type) {
LOG(LOG_SB,LOG_NORMAL)("Raising IRQ");
PIC_ActivateIRQ(sb.hw.irq);
switch (type) {
case SB_IRQ_8:
if (sb.irq.pending_8bit) {
E_Exit("SB: 8bit irq pending");
return;
}
sb.irq.pending_8bit=true;
PIC_ActivateIRQ(sb.hw.irq);
break;
case SB_IRQ_16:
if (sb.irq.pending_16bit) {
E_Exit("SB: 16bit irq pending");
return;
}
sb.irq.pending_16bit=true;
PIC_ActivateIRQ(sb.hw.irq);
break;
default:
break;
@ -316,7 +326,7 @@ static INLINE Bit8u decode_ADPCM_4_sample(Bit8u sample,Bit8u & reference,Bits& s
Bits ref = reference + scaleMap[samp];
if (ref > 0xff) reference = 0xff;
else if (ref < 0x00) reference = 0x00;
else reference = ref;
else reference = (Bit8u)(ref&0xff);
scale = (scale + adjustMap[samp]) & 0xff;
return reference;
@ -345,7 +355,7 @@ static INLINE Bit8u decode_ADPCM_2_sample(Bit8u sample,Bit8u & reference,Bits& s
Bits ref = reference + scaleMap[samp];
if (ref > 0xff) reference = 0xff;
else if (ref < 0x00) reference = 0x00;
else reference = ref;
else reference = (Bit8u)(ref&0xff);
scale = (scale + adjustMap[samp]) & 0xff;
return reference;
@ -377,7 +387,7 @@ INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) {
Bits ref = reference + scaleMap[samp];
if (ref > 0xff) reference = 0xff;
else if (ref < 0x00) reference = 0x00;
else reference = ref;
else reference = (Bit8u)(ref&0xff);
scale = (scale + adjustMap[samp]) & 0xff;
return reference;
@ -573,7 +583,7 @@ static void DSP_ChangeMode(DSP_MODES mode) {
sb.mode=mode;
}
static void DSP_RaiseIRQEvent(Bitu val) {
static void DSP_RaiseIRQEvent(Bitu /*val*/) {
SB_RaiseIRQ(SB_IRQ_8);
}
@ -678,13 +688,23 @@ static void DSP_AddData(Bit8u val) {
}
static void DSP_FinishReset(Bitu /*val*/) {
DSP_FlushData();
DSP_AddData(0xaa);
sb.dsp.state=DSP_S_NORMAL;
}
static void DSP_Reset(void) {
LOG(LOG_SB,LOG_ERROR)("DSP:Reset");
PIC_DeActivateIRQ(sb.hw.irq);
DSP_ChangeMode(MODE_NONE);
DSP_FlushData();
sb.dsp.cmd_len=0;
sb.dsp.in.pos=0;
sb.dsp.write_busy=0;
PIC_RemoveEvents(DSP_FinishReset);
sb.dma.left=0;
sb.dma.total=0;
sb.dma.stereo=false;
@ -693,6 +713,7 @@ static void DSP_Reset(void) {
sb.dma.mode=DSP_DMA_NONE;
sb.dma.remain_size=0;
if (sb.dma.chan) sb.dma.chan->Clear_Request();
sb.freq=22050;
sb.time_constant=45;
sb.dac.used=0;
@ -706,29 +727,28 @@ static void DSP_Reset(void) {
PIC_RemoveEvents(END_DMA_Event);
}
static void DSP_DoReset(Bit8u val) {
if ((val&1)!=0) {
if (((val&1)!=0) && (sb.dsp.state!=DSP_S_RESET)) {
//TODO Get out of highspeed mode
DSP_Reset();
sb.dsp.state=DSP_S_RESET;
} else {
DSP_FlushData();
DSP_AddData(0xaa);
sb.dsp.state=DSP_S_NORMAL;
} else if (((val&1)==0) && (sb.dsp.state==DSP_S_RESET)) { // reset off
sb.dsp.state=DSP_S_RESET_WAIT;
PIC_RemoveEvents(DSP_FinishReset);
PIC_AddEvent(DSP_FinishReset,20.0f/1000.0f,0); // 20 microseconds
}
}
static void DSP_E2_DMA_CallBack(DmaChannel * chan, DMAEvent event) {
static void DSP_E2_DMA_CallBack(DmaChannel * /*chan*/, DMAEvent event) {
if (event==DMA_UNMASKED) {
Bit8u val=sb.e2.value;
Bit8u val=(Bit8u)(sb.e2.value&0xff);
DmaChannel * chan=GetDMAChannel(sb.hw.dma8);
chan->Register_Callback(0);
chan->Write(1,&val);
}
}
static void DSP_ADC_CallBack(DmaChannel * chan, DMAEvent event) {
static void DSP_ADC_CallBack(DmaChannel * /*chan*/, DMAEvent event) {
if (event!=DMA_UNMASKED) return;
Bit8u val=128;
DmaChannel * ch=GetDMAChannel(sb.hw.dma8);
@ -1047,14 +1067,13 @@ static void DSP_DoWrite(Bit8u val) {
static Bit8u DSP_ReadData(void) {
/* Static so it repeats the last value on succesive reads (JANGLE DEMO) */
static Bit8u data = 0;
if (sb.dsp.out.used) {
data=sb.dsp.out.data[sb.dsp.out.pos];
sb.dsp.out.lastval=sb.dsp.out.data[sb.dsp.out.pos];
sb.dsp.out.pos++;
if (sb.dsp.out.pos>=DSP_BUFSIZE) sb.dsp.out.pos-=DSP_BUFSIZE;
sb.dsp.out.used--;
}
return data;
return sb.dsp.out.lastval;
}
//The soundblaster manual says 2.0 Db steps but we'll go for a bit less
@ -1337,7 +1356,7 @@ static Bit8u CTMIXER_Read(void) {
}
static Bitu read_sb(Bitu port,Bitu iolen) {
static Bitu read_sb(Bitu port,Bitu /*iolen*/) {
switch (port-sb.hw.base) {
case MIXER_INDEX:
return sb.mixer.index;
@ -1360,6 +1379,7 @@ static Bitu read_sb(Bitu port,Bitu iolen) {
if (sb.dsp.write_busy & 8) return 0xff;
return 0x7f;
case DSP_S_RESET:
case DSP_S_RESET_WAIT:
return 0xff;
}
return 0xff;
@ -1372,19 +1392,20 @@ static Bitu read_sb(Bitu port,Bitu iolen) {
return 0xff;
}
static void write_sb(Bitu port,Bitu val,Bitu iolen) {
static void write_sb(Bitu port,Bitu val,Bitu /*iolen*/) {
Bit8u val8=(Bit8u)(val&0xff);
switch (port-sb.hw.base) {
case DSP_RESET:
DSP_DoReset(val);
DSP_DoReset(val8);
break;
case DSP_WRITE_DATA:
DSP_DoWrite(val);
DSP_DoWrite(val8);
break;
case MIXER_INDEX:
sb.mixer.index=val;
sb.mixer.index=val8;
break;
case MIXER_DATA:
CTMIXER_Write(val);
CTMIXER_Write(val8);
break;
default:
LOG(LOG_SB,LOG_NORMAL)("Unhandled write to SB Port %4X",port);
@ -1392,8 +1413,21 @@ static void write_sb(Bitu port,Bitu val,Bitu iolen) {
}
}
static void adlib_gusforward(Bitu port,Bitu val,Bitu iolen) {
adlib_commandreg=val;
static void adlib_gusforward(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
adlib_commandreg=(Bit8u)(val&0xff);
}
bool SB_Get_Address(Bitu& sbaddr, Bitu& sbirq, Bitu& sbdma) {
sbaddr=0;
sbirq =0;
sbdma =0;
if (sb.type == SBT_NONE) return false;
else {
sbaddr=sb.hw.base;
sbirq =sb.hw.irq;
sbdma = sb.hw.dma8;
return true;
}
}
static void SBLASTER_CallBack(Bitu len) {
@ -1422,6 +1456,7 @@ static void SBLASTER_CallBack(Bitu len) {
break;
}
}
class SBLASTER: public Module_base {
private:
/* Data */
@ -1469,10 +1504,16 @@ public:
SBLASTER(Section* configuration):Module_base(configuration) {
Bitu i;
Section_prop * section=static_cast<Section_prop *>(configuration);
sb.hw.base=section->Get_hex("sbbase");
sb.hw.irq=section->Get_int("irq");
sb.hw.dma8=section->Get_int("dma");
sb.hw.dma16=section->Get_int("hdma");
Bitu dma8bit=section->Get_int("dma");
if (dma8bit>0xff) dma8bit=0xff;
sb.hw.dma8=(Bit8u)(dma8bit&0xff);
Bitu dma16bit=section->Get_int("hdma");
if (dma16bit>0xff) dma16bit=0xff;
sb.hw.dma16=(Bit8u)(dma16bit&0xff);
sb.mixer.enabled=section->Get_bool("sbmixer");
sb.mixer.stereo=false;
OPL_Mode opl_mode = OPL_none;
@ -1493,9 +1534,12 @@ public:
OPL_Init(section,opl_mode);
break;
}
if (sb.type==SBT_NONE) return;
sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB");
sb.dsp.state=DSP_S_NORMAL;
sb.dsp.out.lastval=0xaa;
sb.dma.chan=NULL;
for (i=4;i<=0xf;i++) {
@ -1508,8 +1552,10 @@ public:
for (i=0;i<256;i++) ASP_regs[i] = 0;
ASP_regs[5] = 0x01;
ASP_regs[9] = 0xf8;
DSP_Reset();
CTMIXER_Reset();
// The documentation does not specify if SB gets initialized with the speaker enabled
// or disabled. Real SBPro2 has it disabled.
sb.speaker=false;
@ -1520,8 +1566,8 @@ public:
// Create set blaster line
ostringstream temp;
temp << "SET BLASTER=A" << setw(3)<< hex << sb.hw.base
<< " I" << dec << sb.hw.irq << " D"<< sb.hw.dma8;
if (sb.type==SBT_16) temp << " H" << sb.hw.dma16;
<< " I" << dec << (Bitu)sb.hw.irq << " D" << (Bitu)sb.hw.dma8;
if (sb.type==SBT_16) temp << " H" << (Bitu)sb.hw.dma16;
temp << " T" << static_cast<unsigned int>(sb.type) << ends;
autoexecline.Install(temp.str());
@ -1559,7 +1605,7 @@ public:
static SBLASTER* test;
void SBLASTER_ShutDown(Section* sec) {
void SBLASTER_ShutDown(Section* /*sec*/) {
delete test;
}

View File

@ -27,10 +27,10 @@
#include "setup.h"
#include "pic.h"
#include "dma.h"
#include "hardware.h"
#include <cstring>
#include <math.h>
#define DAC_CLOCK 3570000
#define MAX_OUTPUT 0x7fff
#define STEP 0x10000
@ -56,8 +56,7 @@ Hope that helps the System E stuff, more news on the PSG as and when!
#define NG_PRESET 0x0f35
struct SN76496
{
struct SN76496 {
int SampleRate;
unsigned int UpdateStep;
int VolTable[16]; /* volume table */
@ -72,18 +71,36 @@ struct SN76496
};
static struct SN76496 sn;
#define TDAC_DMA_BUFSIZE 1024
static struct {
MixerChannel * chan;
bool enabled;
Bitu last_write;
struct {
bool playing;
Bitu rate;
MixerChannel * chan;
bool enabled;
struct {
Bitu base;
Bit8u irq,dma;
} hw;
struct {
Bitu rate;
Bit8u buf[TDAC_DMA_BUFSIZE];
Bit8u last_sample;
DmaChannel * chan;
bool transfer_done;
} dma;
Bit8u mode,control;
Bit16u frequency;
Bit8u amplitude;
bool irq_activated;
} dac;
} tandy;
static void SN76496Write(Bitu port,Bitu data,Bitu iolen) {
static void SN76496Write(Bitu /*port*/,Bitu data,Bitu /*iolen*/) {
struct SN76496 *R = &sn;
tandy.last_write=PIC_Ticks;
@ -160,8 +177,7 @@ static void SN76496Write(Bitu port,Bitu data,Bitu iolen) {
}
}
static void SN76496Update(Bitu length)
{
static void SN76496Update(Bitu length) {
if ((tandy.last_write+5000)<PIC_Ticks) {
tandy.enabled=false;
tandy.chan->Enable(false);
@ -250,7 +266,7 @@ static void SN76496Update(Bitu length)
if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP;
*(buffer++) = out / STEP;
*(buffer++) = (Bit16s)(out / STEP);
count--;
}
@ -259,11 +275,9 @@ static void SN76496Update(Bitu length)
static void SN76496_set_clock(int clock)
{
static void SN76496_set_clock(int clock) {
struct SN76496 *R = &sn;
/* the base clock for the tone generators is the chip clock divided by 16; */
/* for the noise generator, it is clock / 256. */
/* Here we calculate the number of steps which happen during one sample */
@ -274,20 +288,11 @@ static void SN76496_set_clock(int clock)
}
static void TandyDACWrite(Bitu port,Bitu data,Bitu iolen) {
LOG_MSG("Write tandy dac %X val %X",port,data);
}
static void SN76496_set_gain(int gain)
{
static void SN76496_set_gain(int gain) {
struct SN76496 *R = &sn;
int i;
double out;
gain &= 0xff;
/* increase max output basing on gain (0.2 dB per step) */
@ -308,14 +313,185 @@ static void SN76496_set_gain(int gain)
}
bool TS_Get_Address(Bitu& tsaddr, Bitu& tsirq, Bitu& tsdma) {
tsaddr=0;
tsirq =0;
tsdma =0;
if (tandy.dac.enabled) {
tsaddr=tandy.dac.hw.base;
tsirq =tandy.dac.hw.irq;
tsdma =tandy.dac.hw.dma;
return true;
}
return false;
}
static void TandyDAC_DMA_CallBack(DmaChannel * /*chan*/, DMAEvent event) {
if (event == DMA_REACHED_TC) {
tandy.dac.dma.transfer_done=true;
PIC_ActivateIRQ(tandy.dac.hw.irq);
}
}
static void TandyDACModeChanged(void) {
switch (tandy.dac.mode&3) {
case 0:
// joystick mode
break;
case 1:
break;
case 2:
// recording
break;
case 3:
// playback
tandy.dac.chan->FillUp();
if (tandy.dac.frequency!=0) {
float freq=3579545.0f/((float)tandy.dac.frequency);
tandy.dac.chan->SetFreq((Bitu)freq);
float vol=((float)tandy.dac.amplitude)/7.0f;
tandy.dac.chan->SetVolume(vol,vol);
if ((tandy.dac.mode&0x0c)==0x0c) {
tandy.dac.dma.transfer_done=false;
tandy.dac.dma.chan=GetDMAChannel(tandy.dac.hw.dma);
if (tandy.dac.dma.chan) {
tandy.dac.dma.chan->Register_Callback(TandyDAC_DMA_CallBack);
tandy.dac.chan->Enable(true);
// LOG_MSG("Tandy DAC: playback started with freqency %f, volume %f",freq,vol);
}
}
}
break;
}
}
static void TandyDACDMAEnabled(void) {
TandyDACModeChanged();
}
static void TandyDACDMADisabled(void) {
}
static void TandyDACWrite(Bitu port,Bitu data,Bitu /*iolen*/) {
switch (port) {
case 0xc4: {
Bitu oldmode = tandy.dac.mode;
tandy.dac.mode = (Bit8u)(data&0xff);
if ((data&3)!=(oldmode&3)) {
TandyDACModeChanged();
}
if (((data&0x0c)==0x0c) && ((oldmode&0x0c)!=0x0c)) {
TandyDACDMAEnabled();
} else if (((data&0x0c)!=0x0c) && ((oldmode&0x0c)==0x0c)) {
TandyDACDMADisabled();
}
}
break;
case 0xc5:
switch (tandy.dac.mode&3) {
case 0:
// joystick mode
break;
case 1:
tandy.dac.control = (Bit8u)(data&0xff);
break;
case 2:
break;
case 3:
// direct output
break;
}
break;
case 0xc6:
tandy.dac.frequency = tandy.dac.frequency & 0xf00 | (Bit8u)(data&0xff);
switch (tandy.dac.mode&3) {
case 0:
// joystick mode
break;
case 1:
case 2:
case 3:
TandyDACModeChanged();
break;
}
break;
case 0xc7:
tandy.dac.frequency = tandy.dac.frequency & 0x00ff | (((Bit8u)(data&0xf))<<8);
tandy.dac.amplitude = (Bit8u)(data>>5);
switch (tandy.dac.mode&3) {
case 0:
// joystick mode
break;
case 1:
case 2:
case 3:
TandyDACModeChanged();
break;
}
break;
}
}
static Bitu TandyDACRead(Bitu port,Bitu /*iolen*/) {
switch (port) {
case 0xc4:
return (tandy.dac.mode&0x77) | (tandy.dac.irq_activated ? 0x08 : 0x00);
case 0xc6:
return (Bit8u)(tandy.dac.frequency&0xff);
case 0xc7:
return (Bit8u)(((tandy.dac.frequency>>8)&0xf) | (tandy.dac.amplitude<<5));
}
LOG_MSG("Tandy DAC: Read from unknown %X",port);
return 0xff;
}
static void TandyDACGenerateDMASound(Bitu length) {
if (length) {
Bitu read=tandy.dac.dma.chan->Read(length,tandy.dac.dma.buf);
tandy.dac.chan->AddSamples_m8(read,tandy.dac.dma.buf);
if (read < length) {
if (read>0) tandy.dac.dma.last_sample=tandy.dac.dma.buf[read-1];
for (Bitu ct=read; ct < length; ct++) {
tandy.dac.chan->AddSamples_m8(1,&tandy.dac.dma.last_sample);
}
}
}
}
static void TandyDACUpdate(Bitu length) {
if (tandy.dac.enabled && ((tandy.dac.mode&0x0c)==0x0c)) {
if (!tandy.dac.dma.transfer_done) {
Bitu len = length;
TandyDACGenerateDMASound(len);
} else {
for (Bitu ct=0; ct < length; ct++) {
tandy.dac.chan->AddSamples_m8(1,&tandy.dac.dma.last_sample);
}
}
} else {
tandy.dac.chan->AddSilence();
}
}
class TANDYSOUND: public Module_base {
private:
IO_WriteHandleObject WriteHandler[3];
IO_WriteHandleObject WriteHandler[4];
IO_ReadHandleObject ReadHandler[4];
MixerObject MixerChan;
MixerObject MixerChanDAC;
public:
TANDYSOUND(Section* configuration):Module_base(configuration){
Section_prop * section=static_cast<Section_prop *>(configuration);
bool enable_hw_tandy_dac=true;
Bitu sbport, sbirq, sbdma;
if (SB_Get_Address(sbport, sbirq, sbdma)) {
enable_hw_tandy_dac=false;
}
real_writeb(0x40,0xd4,0x00);
if (IS_TANDY_ARCH) {
/* enable tandy sound if tandy=true/auto */
@ -330,18 +506,47 @@ public:
/* ports from second DMA controller conflict with tandy ports */
CloseSecondDMAController();
WriteHandler[2].Install(0x1e0,SN76496Write,IO_MB,2);
if (enable_hw_tandy_dac) {
WriteHandler[2].Install(0x1e0,SN76496Write,IO_MB,2);
WriteHandler[3].Install(0x1e4,TandyDACWrite,IO_MB,4);
// ReadHandler[3].Install(0x1e4,TandyDACRead,IO_MB,4);
}
}
WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2);
WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4);
Bit32u sample_rate = section->Get_int("tandyrate");
tandy.chan=MixerChan.Install(&SN76496Update,sample_rate,"TANDY");
WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2);
if (enable_hw_tandy_dac) {
// enable low-level Tandy DAC emulation
WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4);
ReadHandler[1].Install(0xc4,TandyDACRead,IO_MB,4);
tandy.dac.enabled=true;
tandy.dac.chan=MixerChanDAC.Install(&TandyDACUpdate,sample_rate,"TANDYDAC");
tandy.dac.hw.base=0xc4;
tandy.dac.hw.irq =7;
tandy.dac.hw.dma =1;
} else {
tandy.dac.enabled=false;
tandy.dac.hw.base=0;
tandy.dac.hw.irq =0;
tandy.dac.hw.dma =0;
}
tandy.dac.control=0;
tandy.dac.mode =0;
tandy.dac.irq_activated=false;
tandy.dac.frequency=0;
tandy.dac.amplitude=0;
tandy.dac.dma.last_sample=0;
tandy.enabled=false;
real_writeb(0x40,0xd4,0xff); /* tandy DAC initialization value */
real_writeb(0x40,0xd4,0xff); /* BIOS Tandy DAC initialization value */
Bitu i;
struct SN76496 *R = &sn;
@ -371,7 +576,7 @@ public:
static TANDYSOUND* test;
void TANDYSOUND_ShutDown(Section* sec) {
void TANDYSOUND_ShutDown(Section* /*sec*/) {
delete test;
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_attr.cpp,v 1.30 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: vga_attr.cpp,v 1.31 2009/06/28 14:56:13 c2woody Exp $ */
#include "dosbox.h"
#include "inout.h"
@ -43,12 +43,14 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) {
VGA_DAC_CombineColor(index,val);
}
Bitu read_p3c0(Bitu port,Bitu iolen) {
//Wcharts
return 0x0;
Bitu read_p3c0(Bitu /*port*/,Bitu /*iolen*/) {
// Wcharts, Win 3.11 & 95 SVGA
Bitu retval = attr(index) & 0x1f;
if (attr(enabled)) retval |= 0x20;
return retval;
}
void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
if (!vga.internal.attrindex) {
attr(index)=val & 0x1F;
vga.internal.attrindex=true;
@ -67,7 +69,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
if (!attr(enabled)) VGA_ATTR_SetPalette(attr(index),val);
if (!attr(enabled)) VGA_ATTR_SetPalette(attr(index),(Bit8u)val);
/*
0-5 Index into the 256 color DAC table. May be modified by 3C0h index
10h and 14h.
@ -77,7 +79,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
if (!IS_VGA_ARCH) val&=0x1f; // not really correct, but should do it
if ((attr(mode_control) ^ val) & 0x80) {
attr(mode_control)^=0x80;
for (Bitu i=0;i<0x10;i++) {
for (Bit8u i=0;i<0x10;i++) {
VGA_ATTR_SetPalette(i,vga.attr.palette[i]);
}
}
@ -85,11 +87,11 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
VGA_SetBlinking(val & 0x8);
}
if ((attr(mode_control) ^ val) & 0x04) {
attr(mode_control)=val;
attr(mode_control)=(Bit8u)val;
VGA_DetermineMode();
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) VGA_StartResize();
} else {
attr(mode_control)=val;
attr(mode_control)=(Bit8u)val;
VGA_DetermineMode();
}
@ -111,12 +113,12 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
*/
break;
case 0x11: /* Overscan Color Register */
attr(overscan_color)=val;
attr(overscan_color)=(Bit8u)val;
/* 0-5 Color of screen border. Color is defined as in the palette registers. */
break;
case 0x12: /* Color Plane Enable Register */
/* Why disable colour planes? */
attr(color_plane_enable)=val;
attr(color_plane_enable)=(Bit8u)val;
/*
0 Bit plane 0 is enabled if set.
1 Bit plane 1 is enabled if set.
@ -133,7 +135,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
case M_TEXT:
if ((val==0x7) && (svgaCard==SVGA_None)) vga.config.pel_panning=7;
if (val>0x7) vga.config.pel_panning=0;
else vga.config.pel_panning=val+1;
else vga.config.pel_panning=(Bit8u)(val+1);
break;
case M_VGA:
case M_LIN8:
@ -163,8 +165,8 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
break;
}
if (attr(color_select) ^ val) {
attr(color_select)=val;
for (Bitu i=0;i<0x10;i++) {
attr(color_select)=(Bit8u)val;
for (Bit8u i=0;i<0x10;i++) {
VGA_ATTR_SetPalette(i,vga.attr.palette[i]);
}
}
@ -187,7 +189,7 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
}
}
Bitu read_p3c1(Bitu port,Bitu iolen) {
Bitu read_p3c1(Bitu /*port*/,Bitu iolen) {
// vga.internal.attrindex=false;
switch (attr(index)) {
/* Palette */

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_draw.cpp,v 1.107 2009/04/11 08:02:23 qbix79 Exp $ */
/* $Id: vga_draw.cpp,v 1.109 2009/06/29 18:43:33 c2woody Exp $ */
#include <string.h>
#include <math.h>
@ -616,7 +616,7 @@ static void VGA_ProcessSplit() {
}
static void VGA_DrawSingleLine(Bitu /*blah*/) {
if(vga.attr.enabled || (!(vga.mode==M_VGA || vga.mode==M_EGA))) {
if (vga.attr.enabled) {
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
RENDER_DrawLine(data);
} else {
@ -1044,6 +1044,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
clock = 14318180;
break;
}
vga.draw.delay.hdend = hdend*1000.0/clock; //in milliseconds
}
#if C_DEBUG
LOG(LOG_VGA,LOG_NORMAL)("h total %d end %d blank (%d/%d) retrace (%d/%d)",

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_other.cpp,v 1.25 2009/01/25 12:00:51 c2woody Exp $ */
/* $Id: vga_other.cpp,v 1.27 2009/06/29 18:43:33 c2woody Exp $ */
#include <string.h>
#include <math.h>
@ -28,57 +28,57 @@
#include "render.h"
#include "mapper.h"
static void write_crtc_index_other(Bitu port,Bitu val,Bitu iolen) {
vga.other.index=val;
static void write_crtc_index_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
vga.other.index=(Bit8u)val;
}
static Bitu read_crtc_index_other(Bitu port,Bitu iolen) {
static Bitu read_crtc_index_other(Bitu /*port*/,Bitu /*iolen*/) {
return vga.other.index;
}
static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) {
static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
switch (vga.other.index) {
case 0x00: //Horizontal total
if (vga.other.htotal ^ val) VGA_StartResize();
vga.other.htotal=val;
vga.other.htotal=(Bit8u)val;
break;
case 0x01: //Horizontal displayed chars
if (vga.other.hdend ^ val) VGA_StartResize();
vga.other.hdend=val;
vga.other.hdend=(Bit8u)val;
break;
case 0x02: //Horizontal sync position
vga.other.hsyncp=val;
vga.other.hsyncp=(Bit8u)val;
break;
case 0x03: //Horizontal and vertical sync width
vga.other.syncw=val;
vga.other.syncw=(Bit8u)val;
break;
case 0x04: //Vertical total
if (vga.other.vtotal ^ val) VGA_StartResize();
vga.other.vtotal=val;
vga.other.vtotal=(Bit8u)val;
break;
case 0x05: //Vertical display adjust
if (vga.other.vadjust ^ val) VGA_StartResize();
vga.other.vadjust=val;
vga.other.vadjust=(Bit8u)val;
break;
case 0x06: //Vertical rows
if (vga.other.vdend ^ val) VGA_StartResize();
vga.other.vdend=val;
vga.other.vdend=(Bit8u)val;
break;
case 0x07: //Vertical sync position
vga.other.vsyncp=val;
vga.other.vsyncp=(Bit8u)val;
break;
case 0x09: //Max scanline
if (vga.other.max_scanline ^ val) VGA_StartResize();
vga.other.max_scanline=val;
vga.other.max_scanline=(Bit8u)val;
break;
case 0x0A: /* Cursor Start Register */
vga.other.cursor_start = val & 0x3f;
vga.draw.cursor.sline = val&0x1f;
vga.other.cursor_start = (Bit8u)(val & 0x3f);
vga.draw.cursor.sline = (Bit8u)(val&0x1f);
vga.draw.cursor.enabled = ((val & 0x60) != 0x20);
break;
case 0x0B: /* Cursor End Register */
vga.other.cursor_end = val&0x1f;
vga.draw.cursor.eline = val&0x1f;
vga.other.cursor_end = (Bit8u)(val&0x1f);
vga.draw.cursor.eline = (Bit8u)(val&0x1f);
break;
case 0x0C: /* Start Address High Register */
vga.config.display_start=(vga.config.display_start & 0x00FF) | (val << 8);
@ -88,23 +88,25 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) {
break;
case 0x0E: /*Cursor Location High Register */
vga.config.cursor_start&=0x00ff;
vga.config.cursor_start|=val << 8;
vga.config.cursor_start|=((Bit8u)val) << 8;
break;
case 0x0F: /* Cursor Location Low Register */
vga.config.cursor_start&=0xff00;
vga.config.cursor_start|=val;
vga.config.cursor_start|=(Bit8u)val;
break;
case 0x10: /* Light Pen High */
vga.other.lpen_high = val & 0x1f; //only 6 bits
vga.other.lightpen &= 0xff;
vga.other.lightpen |= (val & 0x3f)<<8; // only 6 bits
break;
case 0x11: /* Light Pen Low */
vga.other.lpen_low = val;
vga.other.lightpen &= 0xff00;
vga.other.lightpen |= (Bit8u)val;
break;
default:
LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Write %X to illegal index %x",val,vga.other.index);
}
}
static Bitu read_crtc_data_other(Bitu port,Bitu iolen) {
static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) {
switch (vga.other.index) {
case 0x00: //Horizontal total
return vga.other.htotal;
@ -129,21 +131,21 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) {
case 0x0B: /* Cursor End Register */
return vga.other.cursor_end;
case 0x0C: /* Start Address High Register */
return vga.config.display_start >> 8;
return (Bit8u)(vga.config.display_start >> 8);
case 0x0D: /* Start Address Low Register */
return vga.config.display_start;
return (Bit8u)(vga.config.display_start & 0xff);
case 0x0E: /*Cursor Location High Register */
return vga.config.cursor_start>>8;
return (Bit8u)(vga.config.cursor_start >> 8);
case 0x0F: /* Cursor Location Low Register */
return vga.config.cursor_start;
return (Bit8u)(vga.config.cursor_start & 0xff);
case 0x10: /* Light Pen High */
return vga.other.lpen_high;
return (Bit8u)(vga.other.lightpen >> 8);
case 0x11: /* Light Pen Low */
return vga.other.lpen_low;
return (Bit8u)(vga.other.lightpen & 0xff);
default:
LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Read from illegal index %x",vga.other.index);
}
return ~0;
return (Bitu)(~0);
}
static double hue_offset = 0.0;
@ -206,7 +208,7 @@ static void update_cga16_color(void) {
G = Y - 0.272*I - 0.647*Q; if (G < 0.0) G = 0.0; if (G > 1.0) G = 1.0;
B = Y - 1.105*I + 1.702*Q; if (B < 0.0) B = 0.0; if (B > 1.0) B = 1.0;
RENDER_SetPal(index,static_cast<Bit8u>(R*baseR),static_cast<Bit8u>(G*baseG),static_cast<Bit8u>(B*baseB));
RENDER_SetPal((Bit8u)index,static_cast<Bit8u>(R*baseR),static_cast<Bit8u>(G*baseG),static_cast<Bit8u>(B*baseB));
}
}
}
@ -303,7 +305,7 @@ static void TandyCheckLineMask(void ) {
vga.tandy.line_shift = 13;
vga.tandy.addr_mask = (1 << 13) - 1;
} else {
vga.tandy.addr_mask = ~0;
vga.tandy.addr_mask = (Bitu)(~0);
vga.tandy.line_shift = 0;
}
}
@ -352,10 +354,10 @@ static void write_tandy_reg(Bit8u val) {
}
}
static void write_cga(Bitu port,Bitu val,Bitu iolen) {
static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) {
switch (port) {
case 0x3d8:
vga.tandy.mode_control=val;
vga.tandy.mode_control=(Bit8u)val;
if (vga.tandy.mode_control & 0x2) {
if (vga.tandy.mode_control & 0x10) {
if (!(val & 0x4) && machine==MCH_CGA) {
@ -371,36 +373,48 @@ static void write_cga(Bitu port,Bitu val,Bitu iolen) {
VGA_SetBlinking(val & 0x20);
break;
case 0x3d9:
write_color_select(val);
write_color_select((Bit8u)val);
break;
}
}
static void write_tandy(Bitu port,Bitu val,Bitu iolen) {
static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) {
switch (port) {
case 0x3d8:
vga.tandy.mode_control=val;
vga.tandy.mode_control=(Bit8u)val;
TandyCheckLineMask();
VGA_SetBlinking(val & 0x20);
TANDY_FindMode();
break;
case 0x3d9:
write_color_select(val);
write_color_select((Bit8u)val);
break;
case 0x3da:
vga.tandy.reg_index=val;
vga.tandy.reg_index=(Bit8u)val;
break;
// case 0x3db: //Clear lightpen latch
case 0x3db: // Clear lightpen latch
vga.other.lightpen_triggered = false;
break;
// case 0x3dc: //Preset lightpen latch
case 0x3dc: // Preset lightpen latch
if (!vga.other.lightpen_triggered) {
vga.other.lightpen_triggered = true; // TODO: this shows at port 3ba/3da bit 1
double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart;
double timeInLine = fmod(timeInFrame,vga.draw.delay.htotal);
Bitu current_scanline = (Bitu)(timeInFrame / vga.draw.delay.htotal);
vga.other.lightpen = (Bit16u)((vga.draw.address_add/2) * (current_scanline/2));
vga.other.lightpen += (Bit16u)((timeInLine / vga.draw.delay.hdend) *
((float)(vga.draw.address_add/2)));
}
break;
// case 0x3dd: //Extended ram page address register:
break;
case 0x3de:
write_tandy_reg(val);
write_tandy_reg((Bit8u)val);
break;
case 0x3df:
vga.tandy.line_mask = val >> 6;
vga.tandy.line_mask = (Bit8u)(val >> 6);
vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
TandyCheckLineMask();
@ -409,18 +423,18 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) {
}
}
static void write_pcjr(Bitu port,Bitu val,Bitu iolen) {
static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) {
switch (port) {
case 0x3d9:
write_color_select(val);
write_color_select((Bit8u)val);
break;
case 0x3da:
if (vga.tandy.pcjr_flipflop) write_tandy_reg(val);
else vga.tandy.reg_index=val;
if (vga.tandy.pcjr_flipflop) write_tandy_reg((Bit8u)val);
else vga.tandy.reg_index=(Bit8u)val;
vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop;
break;
case 0x3df:
vga.tandy.line_mask = val >> 6;
vga.tandy.line_mask = (Bit8u)(val >> 6);
vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
vga.tandy.draw_base = &MemBase[vga.tandy.draw_bank * 16 * 1024];
@ -431,7 +445,7 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) {
}
}
static void write_hercules(Bitu port,Bitu val,Bitu iolen) {
static void write_hercules(Bitu port,Bitu val,Bitu /*iolen*/) {
switch (port) {
case 0x3b8: {
// the protected bits can always be cleared but only be set if the
@ -466,7 +480,7 @@ static void write_hercules(Bitu port,Bitu val,Bitu iolen) {
break;
}
case 0x3bf:
vga.herc.enable_bits=val;
vga.herc.enable_bits=(Bit8u)val;
break;
}
}
@ -476,7 +490,7 @@ static void write_hercules(Bitu port,Bitu val,Bitu iolen) {
return 0;
} */
Bitu read_herc_status(Bitu port,Bitu iolen) {
Bitu read_herc_status(Bitu /*port*/,Bitu /*iolen*/) {
// 3BAh (R): Status Register
// bit 0 Horizontal sync
// 1 Light pen status (only some cards)
@ -507,6 +521,8 @@ Bitu read_herc_status(Bitu port,Bitu iolen) {
void VGA_SetupOther(void) {
Bitu i;
memset( &vga.tandy, 0, sizeof( vga.tandy ));
vga.attr.enabled = true;
//Initialize values common for most machines, can be overwritten
vga.tandy.draw_base = vga.mem.linear;
vga.tandy.mem_base = vga.mem.linear;
@ -527,6 +543,8 @@ void VGA_SetupOther(void) {
if (machine==MCH_CGA) {
IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB);
IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB);
IO_RegisterWriteHandler(0x3db,write_tandy,IO_MB);
IO_RegisterWriteHandler(0x3dc,write_tandy,IO_MB);
MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue");
MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue");
}
@ -580,4 +598,3 @@ void VGA_SetupOther(void) {
}
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: bios.cpp,v 1.74 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: bios.cpp,v 1.77 2009/06/23 17:46:05 c2woody Exp $ */
#include "dosbox.h"
#include "mem.h"
@ -26,6 +26,7 @@
#include "callback.h"
#include "inout.h"
#include "pic.h"
#include "hardware.h"
#include "joystick.h"
#include "mouse.h"
#include "setup.h"
@ -69,49 +70,40 @@ static struct {
Bit8u irq;
Bit8u dma;
} tandy_sb;
static bool Tandy_ProbeSBPort(Bit16u sbport) {
IO_Write(sbport+0x6,1);
IO_Write(sbport+0x6,0);
while (!(IO_Read(sbport+0xe)&0x80)) ;
if (IO_Read(sbport+0xa)==0xaa) return true;
else return false;
}
static struct {
Bit16u port;
Bit8u irq;
Bit8u dma;
} tandy_dac;
static bool Tandy_InitializeSB() {
/* see if soundblaster module available and at what port */
if (Tandy_ProbeSBPort(0x220)) tandy_sb.port=0x220;
else if (Tandy_ProbeSBPort(0x230)) tandy_sb.port=0x230;
else if (Tandy_ProbeSBPort(0x210)) tandy_sb.port=0x210;
else if (Tandy_ProbeSBPort(0x240)) tandy_sb.port=0x240;
else if (Tandy_ProbeSBPort(0x250)) tandy_sb.port=0x250;
else if (Tandy_ProbeSBPort(0x260)) tandy_sb.port=0x260;
else {
/* see if soundblaster module available and at what port/IRQ/DMA */
Bitu sbport, sbirq, sbdma;
if (SB_Get_Address(sbport, sbirq, sbdma)) {
tandy_sb.port=(Bit16u)(sbport&0xffff);
tandy_sb.irq =(Bit8u)(sbirq&0xff);
tandy_sb.dma =(Bit8u)(sbdma&0xff);
return true;
} else {
/* no soundblaster accessible, disable Tandy DAC */
tandy_sb.port=0;
return false;
}
}
/* try to detect IRQ setting */
IO_Write(tandy_sb.port+0x4,0x80);
Bit8u rval=IO_Read(tandy_sb.port+0x5);
if (rval && (rval!=0xff)) {
if (rval&1) tandy_sb.irq=0x02;
else if (rval&2) tandy_sb.irq=0x05;
else if (rval&4) tandy_sb.irq=0x07;
else tandy_sb.irq=0x10;
} else tandy_sb.irq=0x07; /* assume irq=7 for older soundblaster settings */
/* try to detect DMA setting */
IO_Write(tandy_sb.port+0x4,0x81);
rval=IO_Read(tandy_sb.port+0x5);
if (rval && (rval!=0xff)) {
if (rval&1) tandy_sb.dma=0x00;
else if (rval&2) tandy_sb.dma=0x01;
else tandy_sb.dma=0x03;
} else tandy_sb.dma=0x01; /* assume dma=1 for older soundblaster settings */
return true;
static bool Tandy_InitializeTS() {
/* see if Tandy DAC module available and at what port/IRQ/DMA */
Bitu tsport, tsirq, tsdma;
if (TS_Get_Address(tsport, tsirq, tsdma)) {
tandy_dac.port=(Bit16u)(tsport&0xffff);
tandy_dac.irq =(Bit8u)(tsirq&0xff);
tandy_dac.dma =(Bit8u)(tsdma&0xff);
return true;
} else {
/* no Tandy DAC accessible */
tandy_dac.port=0;
return false;
}
}
/* check if Tandy DAC is still playing */
@ -119,9 +111,13 @@ static bool Tandy_TransferInProgress(void) {
if (real_readw(0x40,0xd0)) return true; /* not yet done */
if (real_readb(0x40,0xd4)==0xff) return false; /* still in init-state */
Bit8u tandy_dma = 1;
if (tandy_sb.port) tandy_dma = tandy_sb.dma;
else if (tandy_dac.port) tandy_dma = tandy_dac.dma;
IO_Write(0x0c,0x00);
Bit16u datalen=IO_ReadB(tandy_sb.dma*2+1);
datalen|=(IO_ReadB(tandy_sb.dma*2+1)<<8);
Bit16u datalen=(Bit8u)(IO_ReadB(tandy_dma*2+1)&0xff);
datalen|=(IO_ReadB(tandy_dma*2+1)<<8);
if (datalen==0xffff) return false; /* no DMA transfer */
else if ((datalen<0x10) && (real_readb(0x40,0xd4)==0x0f) && (real_readw(0x40,0xd2)==0x1c)) {
/* stop already requested */
@ -134,27 +130,44 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) {
Bitu length=real_readw(0x40,0xd0);
if (length==0) return; /* nothing to do... */
if (tandy_sb.port==0) return;
if ((tandy_sb.port==0) && (tandy_dac.port==0)) return;
Bit8u tandy_irq = 7;
if (tandy_sb.port) tandy_irq = tandy_sb.irq;
else if (tandy_dac.port) tandy_irq = tandy_dac.irq;
Bit8u tandy_irq_vector = tandy_irq;
if (tandy_irq_vector<8) tandy_irq_vector += 8;
else tandy_irq_vector += (0x70-8);
/* revector IRQ-handler if necessary */
RealPt current_irq=RealGetVec(tandy_sb.irq+8);
RealPt current_irq=RealGetVec(tandy_irq_vector);
if (current_irq!=tandy_DAC_callback[0]->Get_RealPointer()) {
real_writed(0x40,0xd6,current_irq);
RealSetVec(tandy_sb.irq+8,tandy_DAC_callback[0]->Get_RealPointer());
RealSetVec(tandy_irq_vector,tandy_DAC_callback[0]->Get_RealPointer());
}
IO_Write(tandy_sb.port+0xc,0xd0); /* stop DMA transfer */
IO_Write(0x21,IO_Read(0x21)&(~(1<<tandy_sb.irq))); /* unmask IRQ */
IO_Write(tandy_sb.port+0xc,0xd1); /* turn speaker on */
IO_Write(0x0a,0x04|tandy_sb.dma); /* mask DMA channel */
IO_Write(0x0c,0x00); /* clear DMA flipflop */
if (isplayback) IO_Write(0x0b,0x48|tandy_sb.dma);
else IO_Write(0x0b,0x44|tandy_sb.dma);
Bit8u tandy_dma = 1;
if (tandy_sb.port) tandy_dma = tandy_sb.dma;
else if (tandy_dac.port) tandy_dma = tandy_dac.dma;
if (tandy_sb.port) {
IO_Write(tandy_sb.port+0xc,0xd0); /* stop DMA transfer */
IO_Write(0x21,IO_Read(0x21)&(~(1<<tandy_irq))); /* unmask IRQ */
IO_Write(tandy_sb.port+0xc,0xd1); /* turn speaker on */
} else {
IO_Write(tandy_dac.port,IO_Read(tandy_dac.port)&0x60); /* disable DAC */
IO_Write(0x21,IO_Read(0x21)&(~(1<<tandy_irq))); /* unmask IRQ */
}
IO_Write(0x0a,0x04|tandy_dma); /* mask DMA channel */
IO_Write(0x0c,0x00); /* clear DMA flipflop */
if (isplayback) IO_Write(0x0b,0x48|tandy_dma);
else IO_Write(0x0b,0x44|tandy_dma);
/* set physical address of buffer */
Bit8u bufpage=(Bit8u)((bufpt>>16)&0xff);
IO_Write(tandy_sb.dma*2,(Bit8u)(bufpt&0xff));
IO_Write(tandy_sb.dma*2,(Bit8u)((bufpt>>8)&0xff));
switch (tandy_sb.dma) {
IO_Write(tandy_dma*2,(Bit8u)(bufpt&0xff));
IO_Write(tandy_dma*2,(Bit8u)((bufpt>>8)&0xff));
switch (tandy_dma) {
case 0: IO_Write(0x87,bufpage); break;
case 1: IO_Write(0x83,bufpage); break;
case 2: IO_Write(0x81,bufpage); break;
@ -169,32 +182,48 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) {
tlength--;
/* set transfer size */
IO_Write(tandy_sb.dma*2+1,(Bit8u)(tlength&0xff));
IO_Write(tandy_sb.dma*2+1,(Bit8u)((tlength>>8)&0xff));
IO_Write(0x0a,tandy_sb.dma); /* enable DMA channel */
IO_Write(tandy_dma*2+1,(Bit8u)(tlength&0xff));
IO_Write(tandy_dma*2+1,(Bit8u)((tlength>>8)&0xff));
Bitu delay=real_readw(0x40,0xd2)&0xfff;
/* set frequency */
IO_Write(tandy_sb.port+0xc,0x40);
IO_Write(tandy_sb.port+0xc,256-delay*100/358);
/* set playback type to 8bit */
if (isplayback) IO_Write(tandy_sb.port+0xc,0x14);
else IO_Write(tandy_sb.port+0xc,0x24);
/* set transfer size */
IO_Write(tandy_sb.port+0xc,(Bit8u)(tlength&0xff));
IO_Write(tandy_sb.port+0xc,(Bit8u)((tlength>>8)&0xff));
Bit16u delay=(Bit16u)(real_readw(0x40,0xd2)&0xfff);
Bit8u amplitude=(Bit8u)((real_readw(0x40,0xd2)>>13)&0x7);
if (tandy_sb.port) {
IO_Write(0x0a,tandy_dma); /* enable DMA channel */
/* set frequency */
IO_Write(tandy_sb.port+0xc,0x40);
IO_Write(tandy_sb.port+0xc,256-delay*100/358);
/* set playback type to 8bit */
if (isplayback) IO_Write(tandy_sb.port+0xc,0x14);
else IO_Write(tandy_sb.port+0xc,0x24);
/* set transfer size */
IO_Write(tandy_sb.port+0xc,(Bit8u)(tlength&0xff));
IO_Write(tandy_sb.port+0xc,(Bit8u)((tlength>>8)&0xff));
} else {
if (isplayback) IO_Write(tandy_dac.port,(IO_Read(tandy_dac.port)&0x7c) | 0x03);
else IO_Write(tandy_dac.port,(IO_Read(tandy_dac.port)&0x7c) | 0x02);
IO_Write(tandy_dac.port+2,(Bit8u)(delay&0xff));
IO_Write(tandy_dac.port+3,(Bit8u)(((delay>>8)&0xf) | (amplitude<<5)));
if (isplayback) IO_Write(tandy_dac.port,(IO_Read(tandy_dac.port)&0x7c) | 0x1f);
else IO_Write(tandy_dac.port,(IO_Read(tandy_dac.port)&0x7c) | 0x1e);
IO_Write(0x0a,tandy_dma); /* enable DMA channel */
}
if (!isplayback) {
/* mark transfer as recording operation */
real_writew(0x40,0xd2,delay|0x1000);
real_writew(0x40,0xd2,(Bit16u)(delay|0x1000));
}
}
static Bitu IRQ_TandyDAC(void) {
if (tandy_dac.port) {
IO_Read(tandy_dac.port);
}
if (real_readw(0x40,0xd0)) { /* play/record next buffer */
/* acknowledge IRQ */
IO_Write(0x20,0x20);
IO_Read(tandy_sb.port+0xe);
if (tandy_sb.port) {
IO_Read(tandy_sb.port+0xe);
}
/* buffer starts at the next page */
Bit8u npage=real_readb(0x40,0xd4)+1;
@ -210,11 +239,20 @@ static Bitu IRQ_TandyDAC(void) {
Tandy_SetupTransfer(npage<<16,true);
}
} else { /* playing/recording is finished */
RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6));
Bit8u tandy_irq = 7;
if (tandy_sb.port) tandy_irq = tandy_sb.irq;
else if (tandy_dac.port) tandy_irq = tandy_dac.irq;
Bit8u tandy_irq_vector = tandy_irq;
if (tandy_irq_vector<8) tandy_irq_vector += 8;
else tandy_irq_vector += (0x70-8);
RealSetVec(tandy_irq_vector,real_readd(0x40,0xd6));
/* turn off speaker and acknowledge soundblaster IRQ */
IO_Write(tandy_sb.port+0xc,0xd3);
IO_Read(tandy_sb.port+0xe);
if (tandy_sb.port) {
IO_Write(tandy_sb.port+0xc,0xd3);
IO_Read(tandy_sb.port+0xe);
}
/* issue BIOS tandy sound device busy callout */
SegSet16(cs, RealSeg(tandy_DAC_callback[1]->Get_RealPointer()));
@ -224,10 +262,14 @@ static Bitu IRQ_TandyDAC(void) {
}
static void TandyDAC_Handler(Bit8u tfunction) {
if (!tandy_sb.port) return;
if ((!tandy_sb.port) && (!tandy_dac.port)) return;
switch (tfunction) {
case 0x81: /* Tandy sound system check */
reg_ax=0xc4;
if (tandy_dac.port) {
reg_ax=tandy_dac.port;
} else {
reg_ax=0xc4;
}
CALLBACK_SCF(Tandy_TransferInProgress());
break;
case 0x82: /* Tandy sound system start recording */
@ -256,6 +298,9 @@ static void TandyDAC_Handler(Bit8u tfunction) {
CALLBACK_SCF(false);
break;
case 0x85: /* Tandy sound system reset */
if (tandy_dac.port) {
IO_Write(tandy_dac.port,(Bit8u)(IO_Read(tandy_dac.port)&0xe0));
}
reg_ah=0x00;
CALLBACK_SCF(false);
break;
@ -439,8 +484,8 @@ static Bitu INT14_Handler(void)
IO_ReadB(port+2);
// get result
reg_ah=IO_ReadB(port+5);
reg_al=IO_ReadB(port+6);
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
CALLBACK_SCF(false);
}
break;
@ -458,7 +503,7 @@ static Bitu INT14_Handler(void)
timeout = !serialports[reg_dx]->Putchar(reg_al,true,true,
mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000);
// get result
reg_ah=IO_ReadB(port+5);
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
if(timeout) reg_ah |= 0x80;
}
CALLBACK_SCF(false);
@ -479,7 +524,7 @@ static Bitu INT14_Handler(void)
// RTS off
IO_WriteB(port+4,0x1);
// get result
reg_ah=IO_ReadB(port+5);
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
if(timeout) reg_ah |= 0x80;
else reg_al=buffer;
}
@ -488,8 +533,8 @@ static Bitu INT14_Handler(void)
}
case 0x03: // get status
{
reg_ah=IO_ReadB(port+5);
reg_al=IO_ReadB(port+6);
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
CALLBACK_SCF(false);
}
break;
@ -498,7 +543,7 @@ static Bitu INT14_Handler(void)
}
static Bitu INT15_Handler(void) {
static Bitu biosConfigSeg=0;
static Bit16u biosConfigSeg=0;
switch (reg_ah) {
case 0x06:
LOG(LOG_BIOS,LOG_NORMAL)("INT15 Unkown Function 6");
@ -767,7 +812,7 @@ void BIOS_ZeroExtendedSize(bool in) {
#define RAM_REFRESH_DELAY 16.7f
static void RAMRefresh_Event(Bitu val) {
static void RAMRefresh_Event(Bitu /*val*/) {
PIC_ActivateIRQ(5);
PIC_AddEvent(RAMRefresh_Event,RAM_REFRESH_DELAY);
}
@ -787,9 +832,11 @@ public:
for (Bit16u i=0;i<0x200;i++) real_writeb(0x40,i,0);
/* Setup all the interrupt handlers the bios controls */
/* INT 8 Clock IRQ Handler */
callback[0].Install(INT8_Handler,CB_IRQ0,"Int 8 Clock");
callback[0].Set_RealVec(0x8);
Bitu call_irq0=CALLBACK_Allocate();
CALLBACK_Setup(call_irq0,INT8_Handler,CB_IRQ0,Real2Phys(BIOS_DEFAULT_IRQ0_LOCATION),"IRQ 0 Clock");
RealSetVec(0x08,BIOS_DEFAULT_IRQ0_LOCATION);
// pseudocode for CB_IRQ0:
// callback INT8_Handler
// push ax,dx,ds
@ -863,15 +910,12 @@ public:
phys_writew(0xFFFF3,RealSeg(rptr)); // segment
/* Irq 2 */
RealPt irq2pt=RealMake(0xf000,0xff55); /* Ghost busters 2 mt32 mode */
Bitu call_irq2=CALLBACK_Allocate();
CALLBACK_Setup(call_irq2,NULL,CB_IRET_EOI_PIC1,Real2Phys(irq2pt),"irq 2 bios");
RealSetVec(0x0a,irq2pt);
CALLBACK_Setup(call_irq2,NULL,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ2_LOCATION),"irq 2 bios");
RealSetVec(0x0a,BIOS_DEFAULT_IRQ2_LOCATION);
/* Some hardcoded vectors */
phys_writeb(0xfff53,0xcf); /* bios default interrupt vector location */
phys_writeb(0xfe987,0xea); /* original IRQ1 location (Defender booter) */
phys_writed(0xfe988,RealGetVec(0x09));
phys_writeb(Real2Phys(BIOS_DEFAULT_HANDLER_LOCATION),0xcf); /* bios default interrupt vector location -> IRET */
phys_writew(Real2Phys(RealGetVec(0x12))+0x12,0x20); //Hack for Jurresic
if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff) ; /* Tandy model */
@ -893,9 +937,17 @@ public:
for(Bitu i = 0; i < strlen(b_date); i++) phys_writeb(0xffff5+i,b_date[i]);
phys_writeb(0xfffff,0x55); // signature
tandy_sb.port=0;
tandy_dac.port=0;
if (use_tandyDAC) {
/* tandy DAC sound requested, see if soundblaster device is available */
Bitu tandy_dac_type = 0;
if (Tandy_InitializeSB()) {
tandy_dac_type = 1;
} else if (Tandy_InitializeTS()) {
tandy_dac_type = 2;
}
if (tandy_dac_type) {
real_writew(0x40,0xd0,0x0000);
real_writew(0x40,0xd2,0x0000);
real_writeb(0x40,0xd4,0xff); /* tandy DAC init value */
@ -915,9 +967,16 @@ public:
// pop ax
// iret
RealPt current_irq=RealGetVec(tandy_sb.irq+8);
Bit8u tandy_irq = 7;
if (tandy_dac_type==1) tandy_irq = tandy_sb.irq;
else if (tandy_dac_type==2) tandy_irq = tandy_dac.irq;
Bit8u tandy_irq_vector = tandy_irq;
if (tandy_irq_vector<8) tandy_irq_vector += 8;
else tandy_irq_vector += (0x70-8);
RealPt current_irq=RealGetVec(tandy_irq_vector);
real_writed(0x40,0xd6,current_irq);
for (Bitu i=0; i<0x10; i++) phys_writeb(PhysMake(0xf000,0xa084+i),0x80);
for (Bit16u i=0; i<0x10; i++) phys_writeb(PhysMake(0xf000,0xa084+i),0x80);
} else real_writeb(0x40,0xd4,0x00);
}
@ -971,8 +1030,8 @@ public:
/* Setup equipment list */
// look http://www.bioscentral.com/misc/bda.htm
//Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel
Bitu config = 0x0;
//Bit16u config=0x4400; //1 Floppy, 2 serial and 1 parallel
Bit16u config = 0x0;
// set number of parallel ports
// if(ppindex == 0) config |= 0x8000; // looks like 0 ports are not specified
@ -1004,7 +1063,7 @@ public:
// Gameport
config |= 0x1000;
mem_writew(BIOS_CONFIGURATION,config);
CMOS_SetRegister(0x14,config); //Should be updated on changes
CMOS_SetRegister(0x14,(Bit8u)(config&0xff)); //Should be updated on changes
/* Setup extended memory size */
IO_Write(0x70,0x30);
size_extended=IO_Read(0x71);
@ -1024,7 +1083,14 @@ public:
Bit32u orig_vector=real_readd(0x40,0xd6);
if (orig_vector==tandy_DAC_callback[0]->Get_RealPointer()) {
/* set IRQ vector to old value */
RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6));
Bit8u tandy_irq = 7;
if (tandy_sb.port) tandy_irq = tandy_sb.irq;
else if (tandy_dac.port) tandy_irq = tandy_dac.irq;
Bit8u tandy_irq_vector = tandy_irq;
if (tandy_irq_vector<8) tandy_irq_vector += 8;
else tandy_irq_vector += (0x70-8);
RealSetVec(tandy_irq_vector,real_readd(0x40,0xd6));
real_writed(0x40,0xd6,0x00000000);
}
delete tandy_DAC_callback[0];
@ -1058,7 +1124,7 @@ void BIOS_SetComPorts(Bit16u baseaddr[]) {
static BIOS* test;
void BIOS_Destroy(Section* sec){
void BIOS_Destroy(Section* /*sec*/){
delete test;
}

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: bios_keyboard.cpp,v 1.36 2009/06/11 16:05:17 c2woody Exp $ */
#include "dosbox.h"
#include "callback.h"
#include "mem.h"
@ -382,7 +384,7 @@ static Bitu IRQ1_Handler(void) {
}
if(flags1 &0x08) {
Bit8u token = mem_readb(BIOS_KEYBOARD_TOKEN);
token= token*10 + scan_to_scanascii[scancode].alt;
token = token*10 + (Bit8u)(scan_to_scanascii[scancode].alt&0xff);
mem_writeb(BIOS_KEYBOARD_TOKEN,token);
} else if (flags1 &0x04) {
add_key(scan_to_scanascii[scancode].control);
@ -601,12 +603,12 @@ void BIOS_SetupKeyboard(void) {
/* Allocate/setup a callback for int 0x16 and for standard IRQ 1 handler */
call_int16=CALLBACK_Allocate();
CALLBACK_Setup(call_int16,&INT16_Handler,CB_INT16,"keyboard");
CALLBACK_Setup(call_int16,&INT16_Handler,CB_INT16,"Keyboard");
RealSetVec(0x16,CALLBACK_RealPointer(call_int16));
call_irq1=CALLBACK_Allocate();
CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRQ1,"keyboard irq");
RealSetVec(0x9,CALLBACK_RealPointer(call_irq1));
CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRQ1,Real2Phys(BIOS_DEFAULT_IRQ1_LOCATION),"IRQ 1 Keyboard");
RealSetVec(0x09,BIOS_DEFAULT_IRQ1_LOCATION);
// pseudocode for CB_IRQ1:
// push ax
// in al, 0x60

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: ems.cpp,v 1.62 2009/05/14 17:51:47 qbix79 Exp $ */
/* $Id: ems.cpp,v 1.64 2009/06/24 17:44:52 c2woody Exp $ */
#include <string.h>
#include <stdlib.h>
@ -43,8 +43,9 @@
#define EMM_VERSION 0x40
#define GEMMIS_VERSION 0x0001 // Version 1.0
#define NULL_HANDLE 0xffff
#define NULL_PAGE 0xffff
#define EMM_SYSTEM_HANDLE 0x0000
#define NULL_HANDLE 0xffff
#define NULL_PAGE 0xffff
#define ENABLE_VCPI 1
#define ENABLE_V86_STARTUP 0
@ -71,6 +72,25 @@
#define EMM_MOVE_OVLAPI 0x97
#define EMM_NOT_FOUND 0xa0
struct EMM_Mapping {
Bit16u handle;
Bit16u page;
};
struct EMM_Handle {
Bit16u pages;
MemHandle mem;
char name[8];
bool saved_page_map;
EMM_Mapping page_map[EMM_MAX_PHYS];
};
static EMM_Handle emm_handles[EMM_MAX_HANDLES];
static EMM_Mapping emm_mappings[EMM_MAX_PHYS];
static EMM_Mapping emm_segmentmappings[0x40];
static Bit16u GEMMIS_seg;
class device_EMM : public DOS_Device {
@ -144,8 +164,13 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco
mem_writew(GEMMIS_addr+0x18d,0x0000); // system handle
mem_writed(GEMMIS_addr+0x18f,0); // handle name
mem_writed(GEMMIS_addr+0x193,0); // handle name
mem_writew(GEMMIS_addr+0x197,0x0010); // system handle
mem_writed(GEMMIS_addr+0x199,0x00110000); // physical address
if (emm_handles[EMM_SYSTEM_HANDLE].pages != NULL_HANDLE) {
mem_writew(GEMMIS_addr+0x197,(emm_handles[EMM_SYSTEM_HANDLE].pages+3)/4);
mem_writed(GEMMIS_addr+0x199,emm_handles[EMM_SYSTEM_HANDLE].mem<<12); // physical address
} else {
mem_writew(GEMMIS_addr+0x197,0x0001); // system handle
mem_writed(GEMMIS_addr+0x199,0x00110000); // physical address
}
/* fill buffer with import structure */
mem_writed(bufptr+0x00,GEMMIS_seg<<4);
@ -163,23 +188,6 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco
return false;
}
struct EMM_Mapping {
Bit16u handle;
Bit16u page;
};
struct EMM_Handle {
Bit16u pages;
MemHandle mem;
char name[8];
bool saved_page_map;
EMM_Mapping page_map[EMM_MAX_PHYS];
};
static EMM_Handle emm_handles[EMM_MAX_HANDLES];
static EMM_Mapping emm_mappings[EMM_MAX_PHYS];
static EMM_Mapping emm_segmentmappings[0x40];
static struct {
bool enabled;
Bit16u ems_handle;
@ -239,7 +247,7 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle,bool can_allocate_
static Bit8u EMM_AllocateSystemHandle(Bit16u pages) {
/* Check for enough free pages */
if ((MEM_FreeTotal()/ 4) < pages) { return EMM_OUT_OF_LOG;}
Bit16u handle = 0; // emm system handle (reserved for OS usage)
Bit16u handle = EMM_SYSTEM_HANDLE; // emm system handle (reserved for OS usage)
/* Release memory if already allocated */
if (emm_handles[handle].pages != NULL_HANDLE) {
MEM_ReleasePages(emm_handles[handle].mem);
@ -664,7 +672,7 @@ static Bitu INT67_Handler(void) {
reg_ah=EMM_NO_ERROR;
break;
case 0x42: /* Get number of pages */
reg_dx=MEM_TotalPages()/4; //Not entirely correct but okay
reg_dx=(Bit16u)(MEM_TotalPages()/4); //Not entirely correct but okay
reg_bx=EMM_GetFreePages();
reg_ah=EMM_NO_ERROR;
break;
@ -1093,11 +1101,11 @@ static Bitu V86_Monitor() {
}
break;
case 0xe4: // IN AL,Ib
reg_al=IO_ReadB(mem_readb((v86_cs<<4)+v86_ip+1));
reg_al=(Bit8u)(IO_ReadB(mem_readb((v86_cs<<4)+v86_ip+1))&0xff);
mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2);
break;
case 0xe5: // IN AX,Ib
reg_ax=IO_ReadW(mem_readb((v86_cs<<4)+v86_ip+1));
reg_ax=(Bit16u)(IO_ReadW(mem_readb((v86_cs<<4)+v86_ip+1))&0xffff);
mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2);
break;
case 0xe6: // OUT Ib,AL
@ -1109,11 +1117,11 @@ static Bitu V86_Monitor() {
mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+2);
break;
case 0xec: // IN AL,DX
reg_al=IO_ReadB(reg_dx);
reg_al=(Bit8u)(IO_ReadB(reg_dx)&0xff);
mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1);
break;
case 0xed: // IN AX,DX
reg_ax=IO_ReadW(reg_dx);
reg_ax=(Bit16u)(IO_ReadW(reg_dx)&0xffff);
mem_writew(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask),v86_ip+1);
break;
case 0xee: // OUT DX,AL
@ -1167,13 +1175,16 @@ static Bitu V86_Monitor() {
}
static void SetupVCPI() {
vcpi.enabled=false;
/* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */
if (EMM_AllocateMemory(1,vcpi.ems_handle,false) != EMM_NO_ERROR) return;
vcpi.enabled=true;
vcpi.pic1_remapping=0x08; // master PIC base
vcpi.pic2_remapping=0x70; // slave PIC base
/* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */
EMM_AllocateMemory(1,vcpi.ems_handle,false);
vcpi.private_area=emm_handles[vcpi.ems_handle].mem<<12;
/* GDT */
@ -1304,7 +1315,8 @@ public:
emm_segmentmappings[i].handle=NULL_HANDLE;
}
EMM_AllocateSystemHandle(4); // allocate OS-dedicated handle (ems handle zero)
EMM_AllocateSystemHandle(4); // allocate OS-dedicated handle (ems handle zero, 16kb)
if (!ENABLE_VCPI) return;
@ -1315,6 +1327,8 @@ public:
/* Initialize private data area and set up descriptor tables */
SetupVCPI();
if (!vcpi.enabled) return;
/* Install v86-callback that handles interrupts occuring
in v86 mode, including protection fault exceptions */
call_v86mon.Install(&V86_Monitor,CB_IRET,"V86 Monitor");
@ -1363,10 +1377,16 @@ public:
char buf[32]= { 0 };
MEM_BlockWrite(PhysMake(emsnameseg,0),buf,32);
RealSetVec(0x67,old67_pointer);
/* Release memory allocated to system handle */
if (emm_handles[EMM_SYSTEM_HANDLE].pages != NULL_HANDLE) {
MEM_ReleasePages(emm_handles[EMM_SYSTEM_HANDLE].mem);
}
/* Clear handle and page tables */
//TODO
if (!ENABLE_VCPI) return;
if ((!ENABLE_VCPI) || (!vcpi.enabled)) return;
/* Free private data area in expanded memory */
EMM_ReleaseMemory(vcpi.ems_handle);

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_modes.cpp,v 1.85 2009/01/25 12:00:52 c2woody Exp $ */
/* $Id: int10_modes.cpp,v 1.86 2009/06/28 14:56:14 c2woody Exp $ */
#include <string.h>
@ -357,20 +357,19 @@ static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) {
static void FinishSetMode(bool clearmem) {
Bitu i;
/* Clear video memory if needs be */
if (clearmem) {
switch (CurMode->type) {
case M_CGA4:
case M_CGA2:
case M_TANDY16:
for (i=0;i<16*1024;i++) {
real_writew( 0xb800,i*2,0x0000);
for (Bit16u ct=0;ct<16*1024;ct++) {
real_writew( 0xb800,ct*2,0x0000);
}
break;
case M_TEXT: {
Bit16u seg = (CurMode->mode==7)?0xb000:0xb800;
for (i=0;i<16*1024;i++) real_writew(seg,i*2,0x0720);
for (Bit16u ct=0;ct<16*1024;ct++) real_writew(seg,ct*2,0x0720);
break;
}
case M_EGA:
@ -386,13 +385,13 @@ static void FinishSetMode(bool clearmem) {
}
}
/* Setup the BIOS */
if (CurMode->mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode);
else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode-0x98); //Looks like the s3 bios
real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth);
real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength);
if (CurMode->mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,(Bit8u)CurMode->mode);
else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,(Bit8u)(CurMode->mode-0x98)); //Looks like the s3 bios
real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,(Bit16u)CurMode->twidth);
real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,(Bit16u)CurMode->plength);
real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,((CurMode->mode==7 )|| (CurMode->mode==0x0f)) ? 0x3b4 : 0x3d4);
real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1);
real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight);
real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(Bit8u)(CurMode->theight-1));
real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit16u)CurMode->cheight);
real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem?0:0x80)));
real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09);
real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
@ -402,11 +401,11 @@ static void FinishSetMode(bool clearmem) {
real_writed(BIOSMEM_SEG,BIOSMEM_VS_POINTER,int10.rom.video_save_pointers);
// Set cursor shape
if(CurMode->type==M_TEXT) {
if (CurMode->type==M_TEXT) {
INT10_SetCursorShape(0x06,07);
}
// Set cursor pos for page 0..7
for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i);
for (Bit8u ct=0;ct<8;ct++) INT10_SetCursorPos(0,0,ct);
// Set active page 0
INT10_SetActivePage(0);
/* Set some interrupt vectors */
@ -420,7 +419,6 @@ static void FinishSetMode(bool clearmem) {
}
bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
Bitu i;
switch (machine) {
case MCH_CGA:
if (mode>6) return false;
@ -479,9 +477,9 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
}
IO_WriteW(crtc_base,0x09 | (scanline-1) << 8);
//Setup the CGA palette using VGA DAC palette
for (i=0;i<16;i++) VGA_DAC_SetEntry(i,cga_palette[i][0],cga_palette[i][1],cga_palette[i][2]);
for (Bit8u ct=0;ct<16;ct++) VGA_DAC_SetEntry(ct,cga_palette[ct][0],cga_palette[ct][1],cga_palette[ct][2]);
//Setup the tandy palette
for (i=0;i<16;i++) VGA_DAC_CombineColor(i,i);
for (Bit8u ct=0;ct<16;ct++) VGA_DAC_CombineColor(ct,ct);
//Setup the special registers for each machine type
Bit8u mode_control_list[0xa+1]={
0x2c,0x28,0x2d,0x29, //0-3
@ -696,9 +694,9 @@ bool INT10_SetVideoMode(Bitu mode) {
seq_data[4]|=0xc; //Graphics - odd/even - Chained
break;
}
for (i=0;i<SEQ_REGS;i++) {
IO_Write(0x3c4,i);
IO_Write(0x3c5,seq_data[i]);
for (Bit8u ct=0;ct<SEQ_REGS;ct++) {
IO_Write(0x3c4,ct);
IO_Write(0x3c5,seq_data[ct]);
}
vga.config.compatible_chain4 = true; // this may be changed by SVGA chipset emulation
@ -707,19 +705,19 @@ bool INT10_SetVideoMode(Bitu mode) {
IO_Write(crtc_base,0x11);
IO_Write(crtc_base+1,IO_Read(crtc_base+1)&0x7f);
/* Clear all the regs */
for (i=0x0;i<=0x18;i++) {
IO_Write(crtc_base,i);IO_Write(crtc_base+1,0);
for (Bit8u ct=0x0;ct<=0x18;ct++) {
IO_Write(crtc_base,ct);IO_Write(crtc_base+1,0);
}
Bit8u overflow=0;Bit8u max_scanline=0;
Bit8u ver_overflow=0;Bit8u hor_overflow=0;
/* Horizontal Total */
IO_Write(crtc_base,0x00);IO_Write(crtc_base+1,CurMode->htotal-5);
IO_Write(crtc_base,0x00);IO_Write(crtc_base+1,(Bit8u)(CurMode->htotal-5));
hor_overflow|=((CurMode->htotal-5) & 0x100) >> 8;
/* Horizontal Display End */
IO_Write(crtc_base,0x01);IO_Write(crtc_base+1,CurMode->hdispend-1);
IO_Write(crtc_base,0x01);IO_Write(crtc_base+1,(Bit8u)(CurMode->hdispend-1));
hor_overflow|=((CurMode->hdispend-1) & 0x100) >> 7;
/* Start horizontal Blanking */
IO_Write(crtc_base,0x02);IO_Write(crtc_base+1,CurMode->hdispend);
IO_Write(crtc_base,0x02);IO_Write(crtc_base+1,(Bit8u)CurMode->hdispend);
hor_overflow|=((CurMode->hdispend) & 0x100) >> 6;
/* End horizontal Blanking */
Bitu blank_end=(CurMode->htotal-2) & 0x7f;
@ -730,7 +728,7 @@ bool INT10_SetVideoMode(Bitu mode) {
if ((CurMode->special & _EGA_HALF_CLOCK) && (CurMode->type!=M_CGA2)) ret_start = (CurMode->hdispend+3);
else if (CurMode->type==M_TEXT) ret_start = (CurMode->hdispend+5);
else ret_start = (CurMode->hdispend+4);
IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,ret_start);
IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,(Bit8u)ret_start);
hor_overflow|=(ret_start & 0x100) >> 4;
/* End Horizontal Retrace */
@ -742,10 +740,10 @@ bool INT10_SetVideoMode(Bitu mode) {
} else if (CurMode->type==M_TEXT) ret_end = (CurMode->htotal-3) & 0x1f;
else ret_end = (CurMode->htotal-4) & 0x1f;
IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,ret_end | (blank_end & 0x20) << 2);
IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,(Bit8u)(ret_end | (blank_end & 0x20) << 2));
/* Vertical Total */
IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(CurMode->vtotal-2));
IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(Bit8u)(CurMode->vtotal-2));
overflow|=((CurMode->vtotal-2) & 0x100) >> 8;
overflow|=((CurMode->vtotal-2) & 0x200) >> 4;
ver_overflow|=((CurMode->vtotal-2) & 0x400) >> 10;
@ -770,7 +768,7 @@ bool INT10_SetVideoMode(Bitu mode) {
}
/* Vertical Retrace Start */
IO_Write(crtc_base,0x10);IO_Write(crtc_base+1,vretrace);
IO_Write(crtc_base,0x10);IO_Write(crtc_base+1,(Bit8u)vretrace);
overflow|=(vretrace & 0x100) >> 6;
overflow|=(vretrace & 0x200) >> 2;
ver_overflow|=(vretrace & 0x400) >> 6;
@ -779,7 +777,7 @@ bool INT10_SetVideoMode(Bitu mode) {
IO_Write(crtc_base,0x11);IO_Write(crtc_base+1,(vretrace+2) & 0xF);
/* Vertical Display End */
IO_Write(crtc_base,0x12);IO_Write(crtc_base+1,(CurMode->vdispend-1));
IO_Write(crtc_base,0x12);IO_Write(crtc_base+1,(Bit8u)(CurMode->vdispend-1));
overflow|=((CurMode->vdispend-1) & 0x100) >> 7;
overflow|=((CurMode->vdispend-1) & 0x200) >> 3;
ver_overflow|=((CurMode->vdispend-1) & 0x400) >> 9;
@ -804,13 +802,13 @@ bool INT10_SetVideoMode(Bitu mode) {
}
/* Vertical Blank Start */
IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(CurMode->vdispend+vblank_trim));
IO_Write(crtc_base,0x15);IO_Write(crtc_base+1,(Bit8u)(CurMode->vdispend+vblank_trim));
overflow|=((CurMode->vdispend+vblank_trim) & 0x100) >> 5;
max_scanline|=((CurMode->vdispend+vblank_trim) & 0x200) >> 4;
ver_overflow|=((CurMode->vdispend+vblank_trim) & 0x400) >> 8;
/* Vertical Blank End */
IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(CurMode->vtotal-vblank_trim-2));
IO_Write(crtc_base,0x16);IO_Write(crtc_base+1,(Bit8u)(CurMode->vtotal-vblank_trim-2));
/* Line Compare */
Bitu line_compare=(CurMode->vtotal < 1024) ? 1023 : 2047;
@ -881,7 +879,7 @@ bool INT10_SetVideoMode(Bitu mode) {
/* Extended System Control 2 Register */
/* This register actually has more bits but only use the extended offset ones */
IO_Write(crtc_base,0x51);
IO_Write(crtc_base + 1,(offset & 0x300) >> 4);
IO_Write(crtc_base + 1,(Bit8u)((offset & 0x300) >> 4));
/* Clear remaining bits of the display start */
IO_Write(crtc_base,0x69);
IO_Write(crtc_base + 1,0);
@ -995,9 +993,9 @@ bool INT10_SetVideoMode(Bitu mode) {
}
break;
}
for (i=0;i<GFX_REGS;i++) {
IO_Write(0x3ce,i);
IO_Write(0x3cf,gfx_data[i]);
for (Bit8u ct=0;ct<GFX_REGS;ct++) {
IO_Write(0x3ce,ct);
IO_Write(0x3cf,gfx_data[ct]);
}
Bit8u att_data[ATT_REGS];
memset(att_data,0,ATT_REGS);
@ -1025,16 +1023,16 @@ bool INT10_SetVideoMode(Bitu mode) {
default:
if ( CurMode->type == M_LIN4 )
goto att_text16;
for (i=0;i<8;i++) {
att_data[i]=i;
att_data[i+8]=i+0x10;
for (Bit8u ct=0;ct<8;ct++) {
att_data[ct]=ct;
att_data[ct+8]=ct+0x10;
}
break;
}
break;
case M_TANDY16:
att_data[0x10]=0x01; //Color Graphics
for (i=0;i<16;i++) att_data[i]=i;
for (Bit8u ct=0;ct<16;ct++) att_data[ct]=ct;
break;
case M_TEXT:
if (machine==MCH_EGA) {
@ -1054,9 +1052,9 @@ att_text16:
att_data[i+8]=0x18;
}
} else {
for (i=0;i<8;i++) {
att_data[i]=i;
att_data[i+8]=i+0x38;
for (Bit8u ct=0;ct<8;ct++) {
att_data[ct]=ct;
att_data[ct+8]=ct+0x38;
}
if (IS_VGA_ARCH) att_data[0x06]=0x14; //Odd Color 6 yellow/brown.
}
@ -1078,8 +1076,8 @@ att_text16:
att_data[5]=0x04;
att_data[6]=0x06;
att_data[7]=0x07;
for (i=0x8;i<0x10;i++)
att_data[i] = i + 0x8;
for (Bit8u ct=0x8;ct<0x10;ct++)
att_data[ct] = ct + 0x8;
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30);
break;
case M_VGA:
@ -1087,15 +1085,15 @@ att_text16:
case M_LIN15:
case M_LIN16:
case M_LIN32:
for (i=0;i<16;i++) att_data[i]=i;
for (Bit8u ct=0;ct<16;ct++) att_data[ct]=ct;
att_data[0x10]=0x41; //Color Graphics 8-bit
break;
}
IO_Read(mono_mode ? 0x3ba : 0x3da);
if ((modeset_ctl & 8)==0) {
for (i=0;i<ATT_REGS;i++) {
IO_Write(0x3c0,i);
IO_Write(0x3c0,att_data[i]);
for (Bit8u ct=0;ct<ATT_REGS;ct++) {
IO_Write(0x3c0,ct);
IO_Write(0x3c0,att_data[ct]);
}
vga.config.pel_panning = 0;
IO_Write(0x3c0,0x20); IO_Write(0x3c0,0x00); //Disable palette access
@ -1173,10 +1171,10 @@ dac_text16:
}
}
} else {
for (i=0x10;i<ATT_REGS;i++) {
if (i==0x11) continue; // skip overscan register
IO_Write(0x3c0,i);
IO_Write(0x3c0,att_data[i]);
for (Bit8u ct=0x10;ct<ATT_REGS;ct++) {
if (ct==0x11) continue; // skip overscan register
IO_Write(0x3c0,ct);
IO_Write(0x3c0,att_data[ct]);
}
vga.config.pel_panning = 0;
IO_Write(0x3c0,0x20); //Disable palette access
@ -1222,11 +1220,11 @@ dac_text16:
IO_Write(crtc_base+1,0);
/* Setup the linear frame buffer */
IO_Write(crtc_base,0x59);
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24));
IO_Write(crtc_base+1,(Bit8u)((S3_LFB_BASE >> 24)&0xff));
IO_Write(crtc_base,0x5a);
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16));
IO_Write(crtc_base+1,(Bit8u)((S3_LFB_BASE >> 16)&0xff));
IO_Write(crtc_base,0x6b); // BIOS scratchpad
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24));
IO_Write(crtc_base+1,(Bit8u)((S3_LFB_BASE >> 24)&0xff));
/* Setup some remaining S3 registers */
IO_Write(crtc_base,0x41); // BIOS scratchpad
@ -1255,7 +1253,7 @@ dac_text16:
}
IO_WriteB(crtc_base,0x50); IO_WriteB(crtc_base+1,reg_50);
Bitu reg_31, reg_3a;
Bit8u reg_31, reg_3a;
switch (CurMode->type) {
case M_LIN15:
case M_LIN16:
@ -1303,6 +1301,11 @@ dac_text16:
}
FinishSetMode(clearmem);
/* Set vga attrib register into defined state */
IO_Read(mono_mode ? 0x3ba : 0x3da);
IO_Write(0x3c0,0x20);
/* Load text mode font */
if (CurMode->type==M_TEXT) {
if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16);

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: mouse.cpp,v 1.79 2009/04/16 12:11:45 qbix79 Exp $ */
/* $Id: mouse.cpp,v 1.80 2009/06/16 19:00:26 qbix79 Exp $ */
#include <string.h>
#include <math.h>
@ -898,6 +898,12 @@ static Bitu INT33_Handler(void) {
reg_cx=(Bit16u)mouse.max_x;
reg_dx=(Bit16u)mouse.max_y;
break;
case 0x31: /* Get Current Minimum/Maximum virtual coordinates */
reg_ax=(Bit16u)mouse.min_x;
reg_bx=(Bit16u)mouse.min_y;
reg_cx=(Bit16u)mouse.max_x;
reg_dx=(Bit16u)mouse.max_y;
break;
default:
LOG(LOG_MOUSE,LOG_ERROR)("Mouse Function %04X not implemented!",reg_ax);
break;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: messages.cpp,v 1.22 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: messages.cpp,v 1.23 2009/06/17 08:52:35 qbix79 Exp $ */
#include <stdio.h>
#include <stdlib.h>
@ -99,8 +99,11 @@ static void LoadMessageFile(const char * fname) {
strcpy(name,linein+1);
/* End of string marker */
} else if (linein[0]=='.') {
/* Replace/Add the string to the internal langaugefile */
MSG_Replace(name,string);
/* Replace/Add the string to the internal langaugefile */
/* Remove last newline (marker is \n.\n) */
size_t ll = strlen(string);
if(ll && string[ll - 1] == '\n') string[ll - 1] = 0; //Second if should not be needed, but better be safe.
MSG_Replace(name,string);
} else {
/* Normal string to be added */
strcat(string,linein);
@ -125,7 +128,7 @@ void MSG_Write(const char * location) {
FILE* out=fopen(location,"w+t");
if(out==NULL) return;//maybe an error?
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
fprintf(out,":%s\n%s.\n",(*tel).name.c_str(),(*tel).val.c_str());
fprintf(out,":%s\n%s\n.\n",(*tel).name.c_str(),(*tel).val.c_str());
}
fclose(out);
}