sceLibc: sprintf()

This commit is contained in:
Nekotekina 2015-01-23 04:47:55 +03:00
parent b4c4c4cc89
commit ca3e82341d
4 changed files with 80 additions and 50 deletions

View file

@ -50,7 +50,7 @@ struct ARMv7Context
u32 C : 1; //Carry condition code flag
u32 V : 1; //Overflow condition code flag
u32 Q : 1; //Set to 1 if an SSAT or USAT instruction changes (saturates) the input value for the signed or unsigned range of the result
u32: 27;
u32 dummy : 27;
};
u32 APSR;
@ -61,7 +61,7 @@ struct ARMv7Context
{
struct
{
u32: 24;
u32 dummy : 24;
u32 exception : 8;
};

View file

@ -257,14 +257,12 @@ bool ARMv7_instrs::ConditionPassed(ARMv7Context& context, u32 cond)
// instructions
void ARMv7_instrs::UNK(ARMv7Context& context, const ARMv7Code code)
{
LOG_ERROR(HLE, "Unknown/illegal opcode: 0x%04x 0x%04x", code.code1, code.code0);
Emu.Pause();
throw fmt::format("Unknown/illegal opcode: 0x%04x 0x%04x", code.code1, code.code0);
}
void ARMv7_instrs::NULL_OP(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
LOG_ERROR(HLE, "Null opcode found: 0x%04x 0x%04x", code.code1, code.code0);
Emu.Pause();
throw fmt::format("Null opcode found: 0x%04x 0x%04x", code.code1, code.code0);
}
void ARMv7_instrs::HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
@ -294,6 +292,54 @@ void ARMv7_instrs::HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7
}
}
void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 cond = context.ITSTATE.advance();
u32 t = 0;
u32 cp = 0;
u32 opc1 = 0;
u32 opc2 = 0;
u32 cn = 0;
u32 cm = 0;
switch (type)
{
case T1:
case A1:
{
t = (code.data & 0xf000) >> 12;
cp = (code.data & 0xf00) >> 8;
opc1 = (code.data & 0xe00000) >> 21;
opc2 = (code.data & 0xe0) >> 5;
cn = (code.data & 0xf0000) >> 16;
cm = (code.data & 0xf);
if (cp - 10 < 2)
{
throw "MRC_(T1/A1): Advanced SIMD and VFP";
}
break;
}
default: throw __FUNCTION__;
}
if (ConditionPassed(context, cond))
{
if (cp == 15 && opc1 == 0 && cn == 13 && cm == 0 && opc2 == 3)
{
LOG_ERROR(ARMv7, "TODO: TLS requested");
if (t < 15)
{
context.GPR[t] = 0;
return;
}
}
throw fmt::format("Bad instruction: mrc p%d,%d,r%d,c%d,c%d,%d", cp, opc1, t, cn, cm, opc2);
}
}
void ARMv7_instrs::ADC_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
switch (type)
@ -4755,34 +4801,3 @@ void ARMv7_instrs::YIELD(ARMv7Context& context, const ARMv7Code code, const ARMv
default: throw __FUNCTION__;
}
}
void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 cond = context.ITSTATE.advance();
u32 t = 0;
u32 cp = 0;
switch (type)
{
case T1:
case A1:
{
t = (code.data & 0xf000) >> 12;
cp = (code.data & 0xf00) >> 8;
if (cp - 10 < 2)
{
throw "MRC_(T1/A1): Advanced SIMD and VFP";
}
break;
}
default: throw __FUNCTION__;
}
if (ConditionPassed(context, cond))
{
LOG_ERROR(ARMv7, "Bad instruction (MRC): 0x%04x 0x%04x", code.code1, code.code0);
throw __FUNCTION__;
}
}

View file

@ -99,6 +99,8 @@ namespace ARMv7_instrs
void HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
void MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
void ADC_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
void ADC_REG(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
void ADC_RSR(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
@ -515,6 +517,4 @@ namespace ARMv7_instrs
void WFE(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
void WFI(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
void YIELD(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
void MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
};

View file

@ -54,16 +54,9 @@ namespace sce_libc_func
});
}
void printf(ARMv7Context& context, vm::psv::ptr<const char> fmt) // va_args...
std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr<const char> fmt, u32 g_count, u32 f_count, u32 v_count)
{
sceLibc.Error("printf(fmt=0x%x)", fmt);
sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr());
std::string result;
u32 g_count = 1;
u32 f_count = 0;
u32 v_count = 0;
for (char c = *fmt++; c; c = *fmt++)
{
@ -105,7 +98,7 @@ namespace sce_libc_func
}
default:
{
throw fmt::Format("printf(): unknown formatting: '%s'", start.get_ptr());
throw fmt::Format("armv7_fmt(): unknown formatting: '%s'", start.get_ptr());
}
}
}
@ -114,7 +107,29 @@ namespace sce_libc_func
result += c;
}
LOG_NOTICE(TTY, result);
return result;
}
void printf(ARMv7Context& context, vm::psv::ptr<const char> fmt) // va_args...
{
sceLibc.Error("printf(fmt=0x%x)", fmt);
sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr());
LOG_NOTICE(TTY, armv7_fmt(context, fmt, 1, 0, 0));
}
void sprintf(ARMv7Context& context, vm::psv::ptr<char> str, vm::psv::ptr<const char> fmt) // va_args...
{
sceLibc.Error("sprintf(str=0x%x, fmt=0x%x)", str, fmt);
sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr());
const std::string& result = armv7_fmt(context, fmt, 2, 0, 0);
sceLibc.Notice("*** res -> '%s'", result);
::memcpy(str.get_ptr(), result.c_str(), result.size() + 1);
}
void __cxa_set_dso_handle_main(vm::psv::ptr<void> dso)
@ -247,7 +262,7 @@ psv_log_base sceLibc("SceLibc", []()
//REG_FUNC(0x395490DA, setbuf);
//REG_FUNC(0x2CA980A0, setvbuf);
//REG_FUNC(0xA1BFF606, snprintf);
//REG_FUNC(0x7449B359, sprintf);
REG_FUNC(0x7449B359, sprintf);
//REG_FUNC(0xEC585241, sscanf);
//REG_FUNC(0x2BCB3F01, ungetc);
//REG_FUNC(0xF7915685, vfprintf);