mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-24 17:41:51 +01:00
sync to dosbox svn
This commit is contained in:
parent
5a5a73d009
commit
be010fae52
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) */
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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)",
|
||||
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user