mirror of
https://github.com/open-goal/jak-project
synced 2026-07-07 06:05:15 -04:00
[Decompiler] bitfield support and clean up of DMA (#350)
* get to vif * support basic bitfield access * make bitfields in dma work * clean up dma * fix merge conflict
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "common/util/Range.h"
|
||||
|
||||
constexpr int BITS_PER_BYTE = 8;
|
||||
template <typename T>
|
||||
std::optional<Range<int>> get_bit_range(T value) {
|
||||
enum State { INITIAL_ZEROS, ONES, TRAILING_ZEROS } state = INITIAL_ZEROS;
|
||||
|
||||
int start_bit = 0;
|
||||
int end_bit = 0;
|
||||
int max_bit = BITS_PER_BYTE * sizeof(T);
|
||||
|
||||
for (int i = 0; i < max_bit; i++) {
|
||||
bool bit = (value) & (T(1) << i);
|
||||
if (state == INITIAL_ZEROS) {
|
||||
if (bit) {
|
||||
start_bit = i;
|
||||
state = ONES;
|
||||
}
|
||||
} else if (state == ONES) {
|
||||
if (!bit) {
|
||||
end_bit = i;
|
||||
state = TRAILING_ZEROS;
|
||||
}
|
||||
} else if (state == TRAILING_ZEROS) {
|
||||
if (bit) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state == INITIAL_ZEROS) {
|
||||
return std::nullopt;
|
||||
} else if (state == ONES) {
|
||||
end_bit = max_bit;
|
||||
}
|
||||
|
||||
return Range<int>{start_bit, end_bit};
|
||||
}
|
||||
@@ -24,6 +24,10 @@ class Range {
|
||||
bool contains(T& val) const { return val >= m_start && val < m_end; }
|
||||
bool empty() const { return m_end <= m_start; }
|
||||
T size() const { return m_end - m_start; }
|
||||
bool operator==(const Range<T>& other) const {
|
||||
return m_start == other.m_start && m_end == other.m_end;
|
||||
}
|
||||
bool operator!=(const Range<T>& other) const { return !((*this) == other); }
|
||||
|
||||
struct Iterator {
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
@@ -36,6 +36,7 @@ add_library(
|
||||
IR2/AtomicOp.cpp
|
||||
IR2/AtomicOpForm.cpp
|
||||
IR2/AtomicOpTypeAnalysis.cpp
|
||||
IR2/BitfieldForms.cpp
|
||||
IR2/Env.cpp
|
||||
IR2/Form.cpp
|
||||
IR2/FormExpressionAnalysis.cpp
|
||||
|
||||
@@ -43,7 +43,7 @@ InstructionParser::InstructionParser() {
|
||||
InstructionKind::BGTZ, InstructionKind::BLTZL, InstructionKind::BGTZL,
|
||||
InstructionKind::BGEZL, InstructionKind::MTC1, InstructionKind::MFC1,
|
||||
InstructionKind::MFLO, InstructionKind::MFHI, InstructionKind::MTLO1,
|
||||
InstructionKind::MFLO1}) {
|
||||
InstructionKind::MFLO1, InstructionKind::SYNCL}) {
|
||||
auto& info = gOpcodeInfo[int(i)];
|
||||
if (info.defined) {
|
||||
m_opcode_name_lookup[info.name] = int(i);
|
||||
|
||||
@@ -33,6 +33,13 @@ goos::Object RegisterAccess::to_form(const Env& env, Print mode) const {
|
||||
m_mode == AccessMode::READ ? 'r' : 'w'));
|
||||
case Print::AS_VARIABLE:
|
||||
return env.get_variable_name_with_cast(m_reg, m_atomic_idx, m_mode);
|
||||
case Print::AS_VARIABLE_NO_CAST:
|
||||
if (env.has_local_vars()) {
|
||||
return pretty_print::to_symbol(env.get_variable_name(*this));
|
||||
} else {
|
||||
return pretty_print::to_symbol(fmt::format("{}-{:03d}-{}", m_reg.to_charp(), m_atomic_idx,
|
||||
m_mode == AccessMode::READ ? 'r' : 'w'));
|
||||
}
|
||||
case Print::AUTOMATIC:
|
||||
if (env.has_local_vars()) {
|
||||
return env.get_variable_name_with_cast(m_reg, m_atomic_idx, m_mode);
|
||||
|
||||
@@ -310,6 +310,11 @@ class AsmOp : public AtomicOp {
|
||||
DecompilerTypeSystem& dts) override;
|
||||
void collect_vars(RegAccessSet& vars) const override;
|
||||
const Instruction& instruction() const { return m_instr; }
|
||||
const std::optional<RegisterAccess> dst() const { return m_dst; }
|
||||
const std::optional<RegisterAccess> src(int i) const {
|
||||
assert(i < 4);
|
||||
return m_src[i];
|
||||
}
|
||||
|
||||
private:
|
||||
Instruction m_instr;
|
||||
|
||||
@@ -391,7 +391,8 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||
}
|
||||
|
||||
std::string cast_type;
|
||||
if (input_type.typespec() == TypeSpec("pointer") && ro.offset == 0) {
|
||||
if (ro.offset == 0 && (input_type.typespec() == TypeSpec("pointer") ||
|
||||
input_type.kind == TP_Type::Kind::OBJECT_PLUS_PRODUCT_WITH_CONSTANT)) {
|
||||
switch (m_size) {
|
||||
case 1:
|
||||
cast_type = "int8";
|
||||
@@ -419,6 +420,10 @@ FormElement* StoreOp::get_as_form(FormPool& pool, const Env& env) const {
|
||||
}
|
||||
}
|
||||
|
||||
if (m_kind == Kind::FLOAT) {
|
||||
cast_type = "float";
|
||||
}
|
||||
|
||||
auto source = pool.alloc_single_element_form<SimpleExpressionElement>(
|
||||
nullptr, SimpleAtom::make_var(ro.var).as_expr(), m_my_idx);
|
||||
auto cast_source = pool.alloc_single_element_form<CastElement>(
|
||||
@@ -540,8 +545,8 @@ Form* LoadVarOp::get_load_src(FormPool& pool, const Env& env) const {
|
||||
return pool.alloc_single_element_form<DerefElement>(nullptr, source, rd.addr_of, tokens);
|
||||
}
|
||||
|
||||
if (input_type.typespec() == TypeSpec("pointer") ||
|
||||
input_type.kind == TP_Type::Kind::OBJECT_PLUS_PRODUCT_WITH_CONSTANT) {
|
||||
if (ro.offset == 0 && (input_type.typespec() == TypeSpec("pointer") ||
|
||||
input_type.kind == TP_Type::Kind::OBJECT_PLUS_PRODUCT_WITH_CONSTANT)) {
|
||||
std::string cast_type;
|
||||
switch (m_size) {
|
||||
case 1:
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
#include "Form.h"
|
||||
#include "common/goos/PrettyPrinter.h"
|
||||
#include "common/util/Range.h"
|
||||
#include "common/util/BitUtils.h"
|
||||
|
||||
namespace decompiler {
|
||||
|
||||
////////////////////////////////
|
||||
// BitfieldStaticDefElement
|
||||
////////////////////////////////
|
||||
|
||||
BitfieldStaticDefElement::BitfieldStaticDefElement(const TypeSpec& type,
|
||||
const std::vector<BitFieldDef>& field_defs)
|
||||
: m_type(type), m_field_defs(field_defs) {}
|
||||
|
||||
goos::Object BitfieldStaticDefElement::to_form_internal(const Env&) const {
|
||||
std::vector<goos::Object> result;
|
||||
|
||||
result.push_back(pretty_print::to_symbol(fmt::format("new 'static '{}", m_type.print())));
|
||||
|
||||
for (auto& def : m_field_defs) {
|
||||
if (def.is_signed) {
|
||||
result.push_back(
|
||||
pretty_print::to_symbol(fmt::format(":{} {}", def.field_name, (s64)def.value)));
|
||||
} else {
|
||||
result.push_back(
|
||||
pretty_print::to_symbol(fmt::format(":{} #x{:x}", def.field_name, def.value)));
|
||||
}
|
||||
}
|
||||
|
||||
return pretty_print::build_list(result);
|
||||
}
|
||||
|
||||
void BitfieldStaticDefElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
f(this);
|
||||
}
|
||||
|
||||
void BitfieldStaticDefElement::apply_form(const std::function<void(Form*)>&) {}
|
||||
void BitfieldStaticDefElement::collect_vars(RegAccessSet&, bool) const {}
|
||||
void BitfieldStaticDefElement::get_modified_regs(RegSet&) const {}
|
||||
|
||||
ModifiedCopyBitfieldElement::ModifiedCopyBitfieldElement(
|
||||
const TypeSpec& type,
|
||||
Form* base,
|
||||
const std::vector<BitfieldFormDef>& field_modifications)
|
||||
: m_type(type), m_base(base), m_field_modifications(field_modifications) {
|
||||
m_base->parent_element = this;
|
||||
}
|
||||
|
||||
goos::Object ModifiedCopyBitfieldElement::to_form_internal(const Env& env) const {
|
||||
std::vector<goos::Object> result = {pretty_print::to_symbol("copy-and-set-bf")};
|
||||
result.push_back(m_base->to_form(env));
|
||||
for (auto& def : m_field_modifications) {
|
||||
result.push_back(pretty_print::to_symbol(fmt::format(":{}", def.field_name)));
|
||||
result.push_back(def.value->to_form(env));
|
||||
}
|
||||
return pretty_print::build_list(result);
|
||||
}
|
||||
|
||||
void ModifiedCopyBitfieldElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
f(this);
|
||||
for (auto& mod : m_field_modifications) {
|
||||
mod.value->apply(f);
|
||||
}
|
||||
m_base->apply(f);
|
||||
}
|
||||
|
||||
void ModifiedCopyBitfieldElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
for (auto& mod : m_field_modifications) {
|
||||
mod.value->apply_form(f);
|
||||
}
|
||||
m_base->apply_form(f);
|
||||
}
|
||||
|
||||
void ModifiedCopyBitfieldElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
if (recursive) {
|
||||
for (auto& mod : m_field_modifications) {
|
||||
mod.value->collect_vars(vars, recursive);
|
||||
}
|
||||
m_base->collect_vars(vars, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
void ModifiedCopyBitfieldElement::get_modified_regs(RegSet& regs) const {
|
||||
for (auto& mod : m_field_modifications) {
|
||||
mod.value->get_modified_regs(regs);
|
||||
}
|
||||
m_base->get_modified_regs(regs);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// BitfieldReadElement
|
||||
////////////////////////////////
|
||||
|
||||
BitfieldReadElement::BitfieldReadElement(Form* base_value, const TypeSpec& ts)
|
||||
: m_base(base_value), m_type(ts) {
|
||||
m_base->parent_element = this;
|
||||
}
|
||||
|
||||
goos::Object BitfieldReadElement::to_form_internal(const Env& env) const {
|
||||
return pretty_print::build_list("incomplete-bitfield-access", m_base->to_form(env));
|
||||
}
|
||||
|
||||
void BitfieldReadElement::apply(const std::function<void(FormElement*)>& f) {
|
||||
f(this);
|
||||
m_base->apply(f);
|
||||
}
|
||||
|
||||
void BitfieldReadElement::apply_form(const std::function<void(Form*)>& f) {
|
||||
m_base->apply_form(f);
|
||||
}
|
||||
|
||||
void BitfieldReadElement::collect_vars(RegAccessSet& vars, bool recursive) const {
|
||||
m_base->collect_vars(vars, recursive);
|
||||
}
|
||||
|
||||
void BitfieldReadElement::get_modified_regs(RegSet& regs) const {
|
||||
m_base->get_modified_regs(regs);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const BitField& find_field(const TypeSystem& ts,
|
||||
const BitFieldType* type,
|
||||
int start_bit,
|
||||
int size,
|
||||
std::optional<bool> looking_for_unsigned) {
|
||||
for (auto& field : type->fields()) {
|
||||
if (field.size() == size && field.offset() == start_bit) {
|
||||
bool is_int = ts.tc(TypeSpec("integer"), field.type());
|
||||
bool is_uint = ts.tc(TypeSpec("uinteger"), field.type());
|
||||
// allow sign match, or unsigned+not a number.
|
||||
|
||||
if (looking_for_unsigned) {
|
||||
bool want_unsigned = *looking_for_unsigned;
|
||||
if ((is_int && !want_unsigned) || (is_uint && want_unsigned) ||
|
||||
(!is_int && !is_uint && want_unsigned)) {
|
||||
// matched!
|
||||
return field;
|
||||
}
|
||||
} else {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw std::runtime_error(
|
||||
fmt::format("Unmatched field: start bit {}, size {}, signed? {}, type {}", start_bit, size,
|
||||
!looking_for_unsigned, type->get_name()));
|
||||
}
|
||||
|
||||
std::optional<BitField> find_field_from_mask(const TypeSystem& ts,
|
||||
const BitFieldType* type,
|
||||
uint64_t mask) {
|
||||
// try to find a field that is masked by this:
|
||||
auto mask_range = get_bit_range(mask);
|
||||
if (!mask_range) {
|
||||
// it wasn't even a valid mask...
|
||||
return {};
|
||||
}
|
||||
|
||||
return find_field(ts, type, mask_range->first(), mask_range->size(), {});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T extract_bitfield(T input, int start_bit, int size) {
|
||||
int end_bit = start_bit + size;
|
||||
T left_shifted = input << (64 - end_bit);
|
||||
return left_shifted >> (64 - size);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/*!
|
||||
* Add a step to the bitfield access. If this completes the access, returns a form representing the
|
||||
* access
|
||||
*/
|
||||
FormElement* BitfieldReadElement::push_step(const BitfieldManip step,
|
||||
const TypeSystem& ts,
|
||||
FormPool& pool) {
|
||||
if (m_steps.empty() && step.kind == BitfieldManip::Kind::LEFT_SHIFT) {
|
||||
// for left/right shift combo to get a field.
|
||||
m_steps.push_back(step);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (m_steps.empty() && step.is_right_shift()) {
|
||||
// could be a single step right shift to get a field
|
||||
bool is_unsigned = step.right_shift_unsigned();
|
||||
int shift_size = step.get_shift_start_bit();
|
||||
int size = shift_size - step.amount;
|
||||
int start_bit = shift_size - size;
|
||||
auto type = ts.lookup_type(m_type);
|
||||
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
|
||||
assert(as_bitfield);
|
||||
auto field = find_field(ts, as_bitfield, start_bit, size, is_unsigned);
|
||||
return pool.alloc_element<DerefElement>(m_base, false,
|
||||
DerefToken::make_field_name(field.name()));
|
||||
}
|
||||
|
||||
if (m_steps.size() == 1 && m_steps.at(0).kind == BitfieldManip::Kind::LEFT_SHIFT) {
|
||||
// second op in left/right shift combo
|
||||
int end_bit = 64 - m_steps.at(0).amount;
|
||||
if (!step.is_right_shift()) {
|
||||
throw std::runtime_error("Unexpected step 1");
|
||||
}
|
||||
bool is_unsigned = step.right_shift_unsigned();
|
||||
|
||||
int size = 64 - step.amount;
|
||||
int start_bit = end_bit - size;
|
||||
assert(start_bit >= 0);
|
||||
|
||||
auto type = ts.lookup_type(m_type);
|
||||
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
|
||||
assert(as_bitfield);
|
||||
auto field = find_field(ts, as_bitfield, start_bit, size, is_unsigned);
|
||||
return pool.alloc_element<DerefElement>(m_base, false,
|
||||
DerefToken::make_field_name(field.name()));
|
||||
}
|
||||
|
||||
if (m_steps.empty() && step.kind == BitfieldManip::Kind::LOGAND) {
|
||||
// and with mask
|
||||
m_steps.push_back(step);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (m_steps.size() == 1 && m_steps.at(0).kind == BitfieldManip::Kind::LOGAND &&
|
||||
step.kind == BitfieldManip::Kind::NONZERO_COMPARE) {
|
||||
auto type = ts.lookup_type(m_type);
|
||||
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
|
||||
assert(as_bitfield);
|
||||
auto field = find_field_from_mask(ts, as_bitfield, m_steps.at(0).amount);
|
||||
if (field) {
|
||||
auto get_field = pool.alloc_element<DerefElement>(m_base, false,
|
||||
DerefToken::make_field_name(field->name()));
|
||||
get_field->inline_nested();
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_compare(IR2_Condition::Kind::NONZERO),
|
||||
pool.alloc_single_form(nullptr, get_field));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_steps.size() == 1 && m_steps.at(0).kind == BitfieldManip::Kind::LOGAND &&
|
||||
step.kind == BitfieldManip::Kind::LOGIOR_WITH_CONSTANT_INT) {
|
||||
// this is setting a bitfield.
|
||||
// first, let's check that the mask is used properly:
|
||||
u64 mask = m_steps.at(0).amount;
|
||||
u64 value = step.amount;
|
||||
if ((mask & value) != 0) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Got invalid bitmask set: mask was 0x{:x} and value was 0x{:x}", mask, value));
|
||||
}
|
||||
auto type = ts.lookup_type(m_type);
|
||||
auto as_bitfield = dynamic_cast<BitFieldType*>(type);
|
||||
assert(as_bitfield);
|
||||
// use the mask to figure out the field.
|
||||
auto field = find_field_from_mask(ts, as_bitfield, ~mask);
|
||||
assert(field);
|
||||
bool is_signed =
|
||||
ts.tc(TypeSpec("int"), field->type()) && !ts.tc(TypeSpec("uint"), field->type());
|
||||
|
||||
// use the field to figure out what value is being set.
|
||||
u64 set_value;
|
||||
if (is_signed) {
|
||||
set_value = extract_bitfield<s64>(value, field->offset(), field->size());
|
||||
} else {
|
||||
set_value = extract_bitfield<u64>(value, field->offset(), field->size());
|
||||
}
|
||||
|
||||
BitfieldFormDef def;
|
||||
def.field_name = field->name();
|
||||
def.value = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(set_value));
|
||||
return pool.alloc_element<ModifiedCopyBitfieldElement>(m_type, m_base,
|
||||
std::vector<BitfieldFormDef>{def});
|
||||
}
|
||||
|
||||
throw std::runtime_error("Unknown state in BitfieldReadElement");
|
||||
}
|
||||
|
||||
std::vector<BitFieldDef> decompile_static_bitfield(const TypeSpec& type,
|
||||
const TypeSystem& ts,
|
||||
u64 value) {
|
||||
u64 touched_bits = 0;
|
||||
std::vector<BitFieldDef> result;
|
||||
|
||||
auto type_info = dynamic_cast<BitFieldType*>(ts.lookup_type(type));
|
||||
assert(type_info);
|
||||
|
||||
for (auto& field : type_info->fields()) {
|
||||
u64 bitfield_value;
|
||||
bool is_signed = ts.tc(TypeSpec("int"), field.type()) && !ts.tc(TypeSpec("uint"), field.type());
|
||||
if (is_signed) {
|
||||
// signed
|
||||
s64 signed_value = value;
|
||||
bitfield_value = extract_bitfield<s64>(signed_value, field.offset(), field.size());
|
||||
} else {
|
||||
// unsigned
|
||||
bitfield_value = extract_bitfield<u64>(value, field.offset(), field.size());
|
||||
}
|
||||
|
||||
if (bitfield_value != 0) {
|
||||
BitFieldDef def;
|
||||
def.value = bitfield_value;
|
||||
def.field_name = field.name();
|
||||
def.is_signed = is_signed;
|
||||
result.push_back(def);
|
||||
}
|
||||
|
||||
for (int i = field.offset(); i < field.offset() + field.size(); i++) {
|
||||
touched_bits |= (u64(1) << i);
|
||||
}
|
||||
}
|
||||
|
||||
u64 untouched_but_set = value & (~touched_bits);
|
||||
|
||||
if (untouched_but_set) {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Failed to decompile static bitfield of type {}. Original value is 0x{:x} but "
|
||||
"we didn't touch",
|
||||
type.print(), value, untouched_but_set));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace decompiler
|
||||
@@ -2097,7 +2097,9 @@ goos::Object LetElement::to_form_internal(const Env& env) const {
|
||||
std::vector<goos::Object> def_list;
|
||||
|
||||
for (auto& entry : m_entries) {
|
||||
def_list.push_back(pretty_print::build_list(entry.dest.to_form(env), entry.src->to_form(env)));
|
||||
def_list.push_back(pretty_print::build_list(
|
||||
entry.dest.to_form(env, RegisterAccess::Print::AS_VARIABLE_NO_CAST),
|
||||
entry.src->to_form(env)));
|
||||
}
|
||||
|
||||
outer.push_back(pretty_print::build_list(def_list));
|
||||
@@ -2288,6 +2290,10 @@ void VectorFloatLoadStoreElement::collect_vf_regs(RegSet& regs) const {
|
||||
regs.insert(m_vf_reg);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// Utilities
|
||||
////////////////////////////////
|
||||
|
||||
std::optional<SimpleAtom> form_as_atom(const Form* f) {
|
||||
auto as_single = f->try_as_single_element();
|
||||
auto as_atom = dynamic_cast<SimpleAtomElement*>(as_single);
|
||||
|
||||
@@ -156,6 +156,27 @@ class SimpleExpressionElement : public FormElement {
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects);
|
||||
void update_from_stack_left_shift(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects);
|
||||
void update_from_stack_right_shift_logic(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects);
|
||||
void update_from_stack_right_shift_arith(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects);
|
||||
void update_from_stack_logor_or_logand(const Env& env,
|
||||
FixedOperatorKind kind,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects);
|
||||
|
||||
const SimpleExpression& expr() const { return m_expr; }
|
||||
|
||||
@@ -443,6 +464,10 @@ class ConditionElement : public FormElement {
|
||||
FormPool& pool,
|
||||
const std::vector<Form*>& source_forms,
|
||||
const std::vector<TypeSpec>& types);
|
||||
FormElement* make_nonzero_check_generic(const Env& env,
|
||||
FormPool& pool,
|
||||
const std::vector<Form*>& source_forms,
|
||||
const std::vector<TypeSpec>& types);
|
||||
FormElement* make_equal_check_generic(const Env& env,
|
||||
FormPool& pool,
|
||||
const std::vector<Form*>& source_forms,
|
||||
@@ -1285,6 +1310,115 @@ class VectorFloatLoadStoreElement : public FormElement {
|
||||
bool m_is_load = false;
|
||||
};
|
||||
|
||||
struct BitfieldManip {
|
||||
enum class Kind {
|
||||
LEFT_SHIFT,
|
||||
RIGHT_SHIFT_LOGICAL,
|
||||
RIGHT_SHIFT_LOGICAL_32BIT,
|
||||
RIGHT_SHIFT_ARITH,
|
||||
LOGAND,
|
||||
LOGIOR_WITH_CONSTANT_INT,
|
||||
NONZERO_COMPARE,
|
||||
INVALID
|
||||
} kind = Kind::INVALID;
|
||||
s64 amount = -1;
|
||||
|
||||
bool is_right_shift() const {
|
||||
return kind == Kind::RIGHT_SHIFT_ARITH || kind == Kind::RIGHT_SHIFT_LOGICAL ||
|
||||
kind == Kind::RIGHT_SHIFT_LOGICAL_32BIT;
|
||||
}
|
||||
|
||||
bool right_shift_unsigned() const {
|
||||
assert(is_right_shift());
|
||||
return kind == Kind::RIGHT_SHIFT_LOGICAL || kind == Kind::RIGHT_SHIFT_LOGICAL_32BIT;
|
||||
}
|
||||
|
||||
bool is_64bit_shift() const {
|
||||
return kind == Kind::RIGHT_SHIFT_LOGICAL || kind == Kind::RIGHT_SHIFT_ARITH ||
|
||||
kind == Kind::LEFT_SHIFT;
|
||||
}
|
||||
|
||||
int get_shift_start_bit() const {
|
||||
if (is_64bit_shift()) {
|
||||
return 64;
|
||||
} else {
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
|
||||
BitfieldManip(Kind k, s64 imm) : kind(k), amount(imm) {}
|
||||
};
|
||||
|
||||
class BitfieldReadElement : public FormElement {
|
||||
public:
|
||||
BitfieldReadElement(Form* base_value, const TypeSpec& ts);
|
||||
goos::Object to_form_internal(const Env& env) const override;
|
||||
void apply(const std::function<void(FormElement*)>& f) override;
|
||||
void apply_form(const std::function<void(Form*)>& f) override;
|
||||
void collect_vars(RegAccessSet& vars, bool recursive) const override;
|
||||
void get_modified_regs(RegSet& regs) const override;
|
||||
FormElement* push_step(const BitfieldManip step, const TypeSystem& ts, FormPool& pool);
|
||||
|
||||
private:
|
||||
Form* m_base = nullptr;
|
||||
TypeSpec m_type;
|
||||
std::vector<BitfieldManip> m_steps;
|
||||
};
|
||||
|
||||
struct BitFieldDef {
|
||||
bool is_signed = false;
|
||||
u64 value = -1;
|
||||
std::string field_name;
|
||||
};
|
||||
|
||||
std::vector<BitFieldDef> decompile_static_bitfield(const TypeSpec& type,
|
||||
const TypeSystem& ts,
|
||||
u64 value);
|
||||
|
||||
class BitfieldStaticDefElement : public FormElement {
|
||||
public:
|
||||
BitfieldStaticDefElement(const TypeSpec& type, const std::vector<BitFieldDef>& field_defs);
|
||||
goos::Object to_form_internal(const Env& env) const override;
|
||||
void apply(const std::function<void(FormElement*)>& f) override;
|
||||
void apply_form(const std::function<void(Form*)>& f) override;
|
||||
void collect_vars(RegAccessSet& vars, bool recursive) const override;
|
||||
void get_modified_regs(RegSet& regs) const override;
|
||||
|
||||
private:
|
||||
TypeSpec m_type;
|
||||
std::vector<BitFieldDef> m_field_defs;
|
||||
};
|
||||
|
||||
struct BitfieldFormDef {
|
||||
Form* value;
|
||||
std::string field_name;
|
||||
};
|
||||
|
||||
/*!
|
||||
* This represents copying a bitfield object, then modifying the type.
|
||||
* It's an intermediate step to modifying a bitfield in place and it's not expected to appear
|
||||
* in the final output.
|
||||
*/
|
||||
class ModifiedCopyBitfieldElement : public FormElement {
|
||||
public:
|
||||
ModifiedCopyBitfieldElement(const TypeSpec& type,
|
||||
Form* base,
|
||||
const std::vector<BitfieldFormDef>& field_modifications);
|
||||
goos::Object to_form_internal(const Env& env) const override;
|
||||
void apply(const std::function<void(FormElement*)>& f) override;
|
||||
void apply_form(const std::function<void(Form*)>& f) override;
|
||||
void collect_vars(RegAccessSet& vars, bool recursive) const override;
|
||||
void get_modified_regs(RegSet& regs) const override;
|
||||
|
||||
Form* base() const { return m_base; }
|
||||
const std::vector<BitfieldFormDef> mods() const { return m_field_modifications; }
|
||||
|
||||
private:
|
||||
TypeSpec m_type;
|
||||
Form* m_base = nullptr;
|
||||
std::vector<BitfieldFormDef> m_field_modifications;
|
||||
};
|
||||
|
||||
/*!
|
||||
* A Form is a wrapper around one or more FormElements.
|
||||
* This is done for two reasons:
|
||||
|
||||
@@ -200,6 +200,32 @@ void pop_helper(const std::vector<RegisterAccess>& vars,
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* This should be used to generate all casts.
|
||||
*/
|
||||
Form* cast_form(Form* in, const TypeSpec& new_type, FormPool& pool, const Env& env) {
|
||||
auto in_as_cast = dynamic_cast<CastElement*>(in->try_as_single_element());
|
||||
if (in_as_cast && in_as_cast->type() == new_type) {
|
||||
return in;
|
||||
}
|
||||
|
||||
auto in_as_atom = form_as_atom(in);
|
||||
if (in_as_atom && in_as_atom->is_int()) {
|
||||
auto type_info = env.dts->ts.lookup_type(new_type);
|
||||
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
|
||||
if (bitfield_info) {
|
||||
// GOT BITFIELD:
|
||||
// fmt::print("Integer constant {} is likely a static bitfield of type {}\n",
|
||||
// in_as_atom->get_int(), bitfield_info->get_name());
|
||||
|
||||
auto fields = decompile_static_bitfield(new_type, env.dts->ts, in_as_atom->get_int());
|
||||
return pool.alloc_single_element_form<BitfieldStaticDefElement>(nullptr, new_type, fields);
|
||||
}
|
||||
}
|
||||
|
||||
return pool.alloc_single_element_form<CastElement>(nullptr, new_type, in);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Pop each variable in the input list into a form. The variables should be given in the order
|
||||
* they are evaluated in the source. It is safe to put the result of these in the same expression.
|
||||
@@ -238,7 +264,8 @@ std::vector<Form*> pop_to_forms(const std::vector<RegisterAccess>& vars,
|
||||
// only cast if we didn't get a var (compacting expressions).
|
||||
// there is a separate system for casting variables that will do a better job.
|
||||
if (cast && !is_var) {
|
||||
forms[i] = pool.alloc_single_element_form<CastElement>(nullptr, *cast, forms[i]);
|
||||
forms[i] = cast_form(forms[i], *cast, pool, env);
|
||||
// pool.alloc_single_element_form<CastElement>(nullptr, *cast, forms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,27 +365,26 @@ void FormElement::update_from_stack(const Env& env,
|
||||
}
|
||||
|
||||
namespace {
|
||||
Form* make_cast(Form* in, const TypeSpec& in_type, const TypeSpec& out_type, FormPool& pool) {
|
||||
Form* make_cast_if_needed(Form* in,
|
||||
const TypeSpec& in_type,
|
||||
const TypeSpec& out_type,
|
||||
FormPool& pool,
|
||||
const Env& env) {
|
||||
if (in_type == out_type) {
|
||||
return in;
|
||||
}
|
||||
|
||||
auto in_as_cast = dynamic_cast<CastElement*>(in->try_as_single_element());
|
||||
if (in_as_cast && in_as_cast->type() == out_type) {
|
||||
return in;
|
||||
}
|
||||
|
||||
return pool.alloc_single_element_form<CastElement>(nullptr, out_type, in);
|
||||
return cast_form(in, out_type, pool, env);
|
||||
}
|
||||
|
||||
std::vector<Form*> make_cast(const std::vector<Form*>& in,
|
||||
const std::vector<TypeSpec>& in_types,
|
||||
const TypeSpec& out_type,
|
||||
FormPool& pool) {
|
||||
std::vector<Form*> make_casts_if_needed(const std::vector<Form*>& in,
|
||||
const std::vector<TypeSpec>& in_types,
|
||||
const TypeSpec& out_type,
|
||||
FormPool& pool,
|
||||
const Env& env) {
|
||||
std::vector<Form*> out;
|
||||
assert(in.size() == in_types.size());
|
||||
for (size_t i = 0; i < in_types.size(); i++) {
|
||||
out.push_back(make_cast(in.at(i), in_types.at(i), out_type, pool));
|
||||
out.push_back(make_cast_if_needed(in.at(i), in_types.at(i), out_type, pool, env));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -543,7 +569,8 @@ void SimpleExpressionElement::update_from_stack_si_1(const Env& env,
|
||||
auto in_type = env.get_types_before_op(m_my_idx).get(m_expr.get_arg(0).var().reg()).typespec();
|
||||
auto arg = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
|
||||
result->push_back(pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(kind), make_cast(arg, in_type, TypeSpec("int"), pool)));
|
||||
GenericOperator::make_fixed(kind),
|
||||
make_cast_if_needed(arg, in_type, TypeSpec("int"), pool, env)));
|
||||
}
|
||||
|
||||
void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
|
||||
@@ -855,6 +882,180 @@ void SimpleExpressionElement::update_from_stack_copy_first_int_2(const Env& env,
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleExpressionElement::update_from_stack_logor_or_logand(const Env& env,
|
||||
FixedOperatorKind kind,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects) {
|
||||
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
|
||||
BitfieldManip::Kind manip_kind;
|
||||
if (kind == FixedOperatorKind::LOGAND) {
|
||||
manip_kind = BitfieldManip::Kind::LOGAND;
|
||||
} else if (kind == FixedOperatorKind::LOGIOR) {
|
||||
manip_kind = BitfieldManip::Kind::LOGIOR_WITH_CONSTANT_INT;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
auto type_info = env.dts->ts.lookup_type(arg0_type);
|
||||
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
|
||||
if (bitfield_info && m_expr.get_arg(1).is_int()) {
|
||||
// andi, bitfield
|
||||
auto base = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
|
||||
auto read_elt = dynamic_cast<BitfieldReadElement*>(base->try_as_single_element());
|
||||
if (!read_elt) {
|
||||
read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
|
||||
}
|
||||
BitfieldManip step(manip_kind, m_expr.get_arg(1).get_int());
|
||||
auto other = read_elt->push_step(step, env.dts->ts, pool);
|
||||
if (other) {
|
||||
result->push_back(other);
|
||||
} else {
|
||||
result->push_back(read_elt);
|
||||
}
|
||||
return;
|
||||
|
||||
} else if (!m_expr.get_arg(1).is_var()) {
|
||||
// andi, something else (don't think this can happen?)
|
||||
update_from_stack_copy_first_int_2(env, kind, pool, stack, result, allow_side_effects);
|
||||
} else {
|
||||
// and, two forms
|
||||
auto arg0_i = is_int_type(env, m_my_idx, m_expr.get_arg(0).var());
|
||||
auto arg0_u = is_uint_type(env, m_my_idx, m_expr.get_arg(0).var());
|
||||
auto arg1_i = is_int_type(env, m_my_idx, m_expr.get_arg(1).var());
|
||||
auto arg1_u = is_uint_type(env, m_my_idx, m_expr.get_arg(1).var());
|
||||
|
||||
auto args = pop_to_forms({m_expr.get_arg(0).var(), m_expr.get_arg(1).var()}, env, pool, stack,
|
||||
allow_side_effects);
|
||||
|
||||
if (bitfield_info) {
|
||||
// mask didn't fit in imm
|
||||
auto arg1_atom = form_as_atom(args.at(1));
|
||||
if (arg1_atom && arg1_atom->is_int()) {
|
||||
auto read_elt = dynamic_cast<BitfieldReadElement*>(args.at(0)->try_as_single_element());
|
||||
if (!read_elt) {
|
||||
read_elt = pool.alloc_element<BitfieldReadElement>(args.at(0), arg0_type);
|
||||
}
|
||||
BitfieldManip step(manip_kind, arg1_atom->get_int());
|
||||
auto other = read_elt->push_step(step, env.dts->ts, pool);
|
||||
assert(!other); // shouldn't be complete.
|
||||
result->push_back(read_elt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((arg0_i && arg1_i) || (arg0_u && arg1_u)) {
|
||||
// types already good
|
||||
auto new_form = pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind),
|
||||
args.at(0), args.at(1));
|
||||
result->push_back(new_form);
|
||||
} else {
|
||||
// types bad, insert cast.
|
||||
auto cast = pool.alloc_single_element_form<CastElement>(
|
||||
nullptr, TypeSpec(arg0_i ? "int" : "uint"), args.at(1));
|
||||
auto new_form =
|
||||
pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind), args.at(0), cast);
|
||||
result->push_back(new_form);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleExpressionElement::update_from_stack_left_shift(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects) {
|
||||
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
|
||||
|
||||
auto type_info = env.dts->ts.lookup_type(arg0_type);
|
||||
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
|
||||
if (bitfield_info && m_expr.get_arg(1).is_int()) {
|
||||
auto base = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
|
||||
auto read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
|
||||
BitfieldManip step(BitfieldManip::Kind::LEFT_SHIFT, m_expr.get_arg(1).get_int());
|
||||
auto other = read_elt->push_step(step, env.dts->ts, pool);
|
||||
assert(!other); // shouldn't be complete.
|
||||
result->push_back(read_elt);
|
||||
} else {
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SHL, pool, stack, result,
|
||||
allow_side_effects);
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleExpressionElement::update_from_stack_right_shift_logic(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects) {
|
||||
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
|
||||
auto type_info = env.dts->ts.lookup_type(arg0_type);
|
||||
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
|
||||
if (bitfield_info && m_expr.get_arg(1).is_int()) {
|
||||
auto base = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
|
||||
auto read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
|
||||
BitfieldManip step(BitfieldManip::Kind::RIGHT_SHIFT_LOGICAL, m_expr.get_arg(1).get_int());
|
||||
auto other = read_elt->push_step(step, env.dts->ts, pool);
|
||||
assert(other); // should be a high field.
|
||||
result->push_back(other);
|
||||
} else {
|
||||
auto arg0_i = is_int_type(env, m_my_idx, m_expr.get_arg(0).var());
|
||||
auto arg0_u = is_uint_type(env, m_my_idx, m_expr.get_arg(0).var());
|
||||
if (m_expr.get_arg(1).is_int()) {
|
||||
auto arg =
|
||||
pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
|
||||
auto as_bitfield_access = dynamic_cast<BitfieldReadElement*>(arg->try_as_single_element());
|
||||
|
||||
if (as_bitfield_access) {
|
||||
BitfieldManip step(BitfieldManip::Kind::RIGHT_SHIFT_LOGICAL, m_expr.get_arg(1).get_int());
|
||||
auto next = as_bitfield_access->push_step(step, env.dts->ts, pool);
|
||||
if (next) {
|
||||
result->push_back(next);
|
||||
} else {
|
||||
result->push_back(as_bitfield_access);
|
||||
}
|
||||
} else {
|
||||
if (!arg0_i && !arg0_u) {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::SHR),
|
||||
pool.alloc_single_element_form<CastElement>(nullptr, TypeSpec("int"), arg),
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
} else {
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::SHR), arg,
|
||||
pool.alloc_single_element_form<SimpleAtomElement>(nullptr, m_expr.get_arg(1)));
|
||||
result->push_back(new_form);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SHR, pool, stack, result,
|
||||
allow_side_effects);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleExpressionElement::update_from_stack_right_shift_arith(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects) {
|
||||
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
|
||||
auto type_info = env.dts->ts.lookup_type(arg0_type);
|
||||
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
|
||||
if (bitfield_info && m_expr.get_arg(1).is_int()) {
|
||||
auto base = pop_to_forms({m_expr.get_arg(0).var()}, env, pool, stack, allow_side_effects).at(0);
|
||||
auto read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
|
||||
BitfieldManip step(BitfieldManip::Kind::RIGHT_SHIFT_ARITH, m_expr.get_arg(1).get_int());
|
||||
auto other = read_elt->push_step(step, env.dts->ts, pool);
|
||||
assert(other); // should be a high field.
|
||||
result->push_back(other);
|
||||
} else {
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SAR, pool, stack, result,
|
||||
allow_side_effects);
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleExpressionElement::update_from_stack_lognot(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
@@ -991,12 +1192,12 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
|
||||
allow_side_effects, false);
|
||||
break;
|
||||
case SimpleExpression::Kind::AND:
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::LOGAND, pool, stack, result,
|
||||
allow_side_effects);
|
||||
update_from_stack_logor_or_logand(env, FixedOperatorKind::LOGAND, pool, stack, result,
|
||||
allow_side_effects);
|
||||
break;
|
||||
case SimpleExpression::Kind::OR:
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::LOGIOR, pool, stack, result,
|
||||
allow_side_effects);
|
||||
update_from_stack_logor_or_logand(env, FixedOperatorKind::LOGIOR, pool, stack, result,
|
||||
allow_side_effects);
|
||||
break;
|
||||
case SimpleExpression::Kind::NOR:
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::LOGNOR, pool, stack, result,
|
||||
@@ -1010,16 +1211,13 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
|
||||
update_from_stack_lognot(env, pool, stack, result, allow_side_effects);
|
||||
break;
|
||||
case SimpleExpression::Kind::LEFT_SHIFT:
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SHL, pool, stack, result,
|
||||
allow_side_effects);
|
||||
update_from_stack_left_shift(env, pool, stack, result, allow_side_effects);
|
||||
break;
|
||||
case SimpleExpression::Kind::RIGHT_SHIFT_LOGIC:
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SHR, pool, stack, result,
|
||||
allow_side_effects);
|
||||
update_from_stack_right_shift_logic(env, pool, stack, result, allow_side_effects);
|
||||
break;
|
||||
case SimpleExpression::Kind::RIGHT_SHIFT_ARITH:
|
||||
update_from_stack_copy_first_int_2(env, FixedOperatorKind::SAR, pool, stack, result,
|
||||
allow_side_effects);
|
||||
update_from_stack_right_shift_arith(env, pool, stack, result, allow_side_effects);
|
||||
break;
|
||||
case SimpleExpression::Kind::MUL_UNSIGNED:
|
||||
update_from_stack_force_ui_2(env, FixedOperatorKind::MULTIPLICATION, pool, stack, result,
|
||||
@@ -1115,11 +1313,31 @@ void SetVarElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
}
|
||||
}
|
||||
|
||||
void SetFormFormElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
||||
// todo - is the order here right?
|
||||
void SetFormFormElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||
assert(m_popped);
|
||||
assert(m_real_push_count == 0);
|
||||
m_real_push_count++;
|
||||
|
||||
// check for bitfield setting:
|
||||
auto src_as_bf_set = dynamic_cast<ModifiedCopyBitfieldElement*>(m_src->try_as_single_element());
|
||||
if (src_as_bf_set && src_as_bf_set->mods().size() == 1) {
|
||||
auto dst_form = m_dst->to_form(env);
|
||||
auto src_form = src_as_bf_set->base()->to_form(env);
|
||||
if (dst_form == src_form) {
|
||||
// success!
|
||||
auto value = src_as_bf_set->mods().at(0).value;
|
||||
|
||||
// make the (-> thing bitfield)
|
||||
auto field_token = DerefToken::make_field_name(src_as_bf_set->mods().at(0).field_name);
|
||||
auto loc_elt = pool.alloc_element<DerefElement>(m_dst, false, field_token);
|
||||
loc_elt->inline_nested();
|
||||
auto loc = pool.alloc_single_form(nullptr, loc_elt);
|
||||
|
||||
m_dst = loc;
|
||||
m_src = value;
|
||||
}
|
||||
}
|
||||
|
||||
stack.push_form_element(this, true);
|
||||
}
|
||||
|
||||
@@ -1159,14 +1377,13 @@ void StoreInPairElement::push_to_stack(const Env& env, FormPool& pool, FormStack
|
||||
}
|
||||
|
||||
namespace {
|
||||
Form* make_optional_cast(const std::optional<TypeSpec>& cast_type, Form* in, FormPool& pool) {
|
||||
if (cast_type) {
|
||||
auto in_as_cast = dynamic_cast<CastElement*>(in->try_as_single_element());
|
||||
if (in_as_cast && in_as_cast->type() == cast_type) {
|
||||
return in;
|
||||
}
|
||||
|
||||
return pool.alloc_single_element_form<CastElement>(nullptr, *cast_type, in);
|
||||
Form* make_optional_cast(const std::optional<TypeSpec>& cast_type,
|
||||
Form* in,
|
||||
FormPool& pool,
|
||||
const Env& env) {
|
||||
if (cast_type) {
|
||||
return cast_form(in, *cast_type, pool, env);
|
||||
} else {
|
||||
return in;
|
||||
}
|
||||
@@ -1179,24 +1396,26 @@ void StorePlainDeref::push_to_stack(const Env& env, FormPool& pool, FormStack& s
|
||||
// this matches the order in Compiler::compile_set
|
||||
auto vars = std::vector<RegisterAccess>({m_expr.var(), m_base_var});
|
||||
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||
m_dst->set_base(make_optional_cast(m_dst_cast_type, popped.at(1), pool));
|
||||
m_dst->set_base(make_optional_cast(m_dst_cast_type, popped.at(1), pool, env));
|
||||
m_dst->mark_popped();
|
||||
m_dst->inline_nested();
|
||||
auto fr = pool.alloc_element<SetFormFormElement>(
|
||||
pool.alloc_single_form(nullptr, m_dst),
|
||||
make_optional_cast(m_src_cast_type, popped.at(0), pool));
|
||||
make_optional_cast(m_src_cast_type, popped.at(0), pool, env));
|
||||
// so the bitfield set check can run
|
||||
fr->mark_popped();
|
||||
stack.push_form_element(fr, true);
|
||||
fr->push_to_stack(env, pool, stack);
|
||||
} else {
|
||||
auto vars = std::vector<RegisterAccess>({m_base_var});
|
||||
auto popped = pop_to_forms(vars, env, pool, stack, true);
|
||||
m_dst->set_base(make_optional_cast(m_dst_cast_type, popped.at(0), pool));
|
||||
m_dst->set_base(make_optional_cast(m_dst_cast_type, popped.at(0), pool, env));
|
||||
m_dst->mark_popped();
|
||||
m_dst->inline_nested();
|
||||
auto val = pool.alloc_single_element_form<SimpleExpressionElement>(nullptr, m_expr, m_my_idx);
|
||||
val->mark_popped();
|
||||
auto fr = pool.alloc_element<SetFormFormElement>(
|
||||
pool.alloc_single_form(nullptr, m_dst), make_optional_cast(m_src_cast_type, val, pool));
|
||||
auto fr =
|
||||
pool.alloc_element<SetFormFormElement>(pool.alloc_single_form(nullptr, m_dst),
|
||||
make_optional_cast(m_src_cast_type, val, pool, env));
|
||||
fr->mark_popped();
|
||||
stack.push_form_element(fr, true);
|
||||
}
|
||||
@@ -1992,6 +2211,27 @@ FormElement* ConditionElement::make_zero_check_generic(const Env&,
|
||||
}
|
||||
}
|
||||
|
||||
FormElement* ConditionElement::make_nonzero_check_generic(const Env& env,
|
||||
FormPool& pool,
|
||||
const std::vector<Form*>& source_forms,
|
||||
const std::vector<TypeSpec>&) {
|
||||
// for (nonzero? (-> obj bitfield))
|
||||
FormElement* bitfield_compare = nullptr;
|
||||
assert(source_forms.size() == 1);
|
||||
auto as_bitfield_op =
|
||||
dynamic_cast<BitfieldReadElement*>(source_forms.at(0)->try_as_single_element());
|
||||
if (as_bitfield_op) {
|
||||
bitfield_compare = as_bitfield_op->push_step(
|
||||
BitfieldManip(BitfieldManip::Kind::NONZERO_COMPARE, 0), env.dts->ts, pool);
|
||||
}
|
||||
|
||||
if (bitfield_compare) {
|
||||
return bitfield_compare;
|
||||
} else {
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_compare(m_kind), source_forms);
|
||||
}
|
||||
}
|
||||
|
||||
FormElement* ConditionElement::make_equal_check_generic(const Env&,
|
||||
FormPool& pool,
|
||||
const std::vector<Form*>& source_forms,
|
||||
@@ -2031,7 +2271,7 @@ FormElement* ConditionElement::make_not_equal_check_generic(const Env&,
|
||||
}
|
||||
|
||||
FormElement* ConditionElement::make_less_than_zero_signed_check_generic(
|
||||
const Env&,
|
||||
const Env& env,
|
||||
FormPool& pool,
|
||||
const std::vector<Form*>& source_forms,
|
||||
const std::vector<TypeSpec>& types) {
|
||||
@@ -2052,7 +2292,7 @@ FormElement* ConditionElement::make_less_than_zero_signed_check_generic(
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::PAIRP),
|
||||
shift_match.maps.forms.at(0));
|
||||
} else {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("int"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(nullptr,
|
||||
SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
@@ -2062,7 +2302,7 @@ FormElement* ConditionElement::make_less_than_zero_signed_check_generic(
|
||||
}
|
||||
|
||||
FormElement* ConditionElement::make_geq_zero_signed_check_generic(
|
||||
const Env&,
|
||||
const Env& env,
|
||||
FormPool& pool,
|
||||
const std::vector<Form*>& source_forms,
|
||||
const std::vector<TypeSpec>& types) {
|
||||
@@ -2086,7 +2326,7 @@ FormElement* ConditionElement::make_geq_zero_signed_check_generic(
|
||||
nullptr, GenericOperator::make_fixed(FixedOperatorKind::PAIRP),
|
||||
shift_match.maps.forms.at(0)));
|
||||
} else {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("int"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(nullptr,
|
||||
SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
@@ -2102,8 +2342,9 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
switch (m_kind) {
|
||||
case IR2_Condition::Kind::ZERO:
|
||||
return make_zero_check_generic(env, pool, source_forms, types);
|
||||
case IR2_Condition::Kind::TRUTHY:
|
||||
case IR2_Condition::Kind::NONZERO:
|
||||
return make_nonzero_check_generic(env, pool, source_forms, types);
|
||||
case IR2_Condition::Kind::TRUTHY:
|
||||
case IR2_Condition::Kind::FALSE:
|
||||
case IR2_Condition::Kind::IS_PAIR:
|
||||
case IR2_Condition::Kind::IS_NOT_PAIR:
|
||||
@@ -2122,28 +2363,28 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
case IR2_Condition::Kind::LESS_THAN_SIGNED:
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::LT),
|
||||
make_cast(source_forms, types, TypeSpec("int"), pool));
|
||||
make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env));
|
||||
case IR2_Condition::Kind::LESS_THAN_UNSIGNED:
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::LT),
|
||||
make_cast(source_forms, types, TypeSpec("uint"), pool));
|
||||
make_casts_if_needed(source_forms, types, TypeSpec("uint"), pool, env));
|
||||
|
||||
case IR2_Condition::Kind::GEQ_UNSIGNED:
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::GEQ),
|
||||
make_cast(source_forms, types, TypeSpec("uint"), pool));
|
||||
make_casts_if_needed(source_forms, types, TypeSpec("uint"), pool, env));
|
||||
|
||||
case IR2_Condition::Kind::GEQ_SIGNED:
|
||||
return pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::GEQ),
|
||||
make_cast(source_forms, types, TypeSpec("int"), pool));
|
||||
make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env));
|
||||
|
||||
case IR2_Condition::Kind::LESS_THAN_ZERO_SIGNED: {
|
||||
return make_less_than_zero_signed_check_generic(env, pool, source_forms, types);
|
||||
}
|
||||
|
||||
case IR2_Condition::Kind::LEQ_ZERO_SIGNED: {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("int"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
@@ -2156,7 +2397,7 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
}
|
||||
|
||||
case IR2_Condition::Kind::GREATER_THAN_ZERO_UNSIGNED: {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("uint"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("uint"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
@@ -2165,7 +2406,7 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
}
|
||||
|
||||
case IR2_Condition::Kind::GREATER_THAN_ZERO_SIGNED: {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("int"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("int"), pool, env);
|
||||
auto zero = pool.alloc_single_element_form<SimpleAtomElement>(
|
||||
nullptr, SimpleAtom::make_int_constant(0));
|
||||
casted.push_back(zero);
|
||||
@@ -2174,31 +2415,31 @@ FormElement* ConditionElement::make_generic(const Env& env,
|
||||
}
|
||||
|
||||
case IR2_Condition::Kind::FLOAT_NOT_EQUAL: {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::NEQ),
|
||||
casted);
|
||||
}
|
||||
|
||||
case IR2_Condition::Kind::FLOAT_EQUAL: {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::EQ),
|
||||
casted);
|
||||
}
|
||||
|
||||
case IR2_Condition::Kind::FLOAT_LEQ: {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::LEQ),
|
||||
casted);
|
||||
}
|
||||
|
||||
case IR2_Condition::Kind::FLOAT_LESS_THAN: {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::LT),
|
||||
casted);
|
||||
}
|
||||
|
||||
case IR2_Condition::Kind::FLOAT_GEQ: {
|
||||
auto casted = make_cast(source_forms, types, TypeSpec("float"), pool);
|
||||
auto casted = make_casts_if_needed(source_forms, types, TypeSpec("float"), pool, env);
|
||||
return pool.alloc_element<GenericElement>(GenericOperator::make_fixed(FixedOperatorKind::GEQ),
|
||||
casted);
|
||||
}
|
||||
@@ -2322,7 +2563,42 @@ void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta
|
||||
stack.push_form_element(this, true);
|
||||
}
|
||||
|
||||
void AtomicOpElement::push_to_stack(const Env& env, FormPool&, FormStack& stack) {
|
||||
namespace {
|
||||
void push_asm_srl_to_stack(const AsmOp* op,
|
||||
FormElement* form_elt,
|
||||
const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack) {
|
||||
// we will try to convert this into a bitfield operation. If this fails, fall back to assembly.
|
||||
auto var = op->src(0);
|
||||
assert(var.has_value()); // srl should always have this.
|
||||
|
||||
auto dst = op->dst();
|
||||
assert(dst.has_value());
|
||||
|
||||
auto integer_atom = op->instruction().get_src(1);
|
||||
assert(integer_atom.is_imm());
|
||||
auto integer = integer_atom.get_imm();
|
||||
|
||||
auto arg0_type = env.get_variable_type(*var, true);
|
||||
auto type_info = env.dts->ts.lookup_type(arg0_type);
|
||||
auto bitfield_info = dynamic_cast<BitFieldType*>(type_info);
|
||||
if (bitfield_info) {
|
||||
auto base = pop_to_forms({*var}, env, pool, stack, true).at(0);
|
||||
auto read_elt = pool.alloc_element<BitfieldReadElement>(base, arg0_type);
|
||||
BitfieldManip step(BitfieldManip::Kind::RIGHT_SHIFT_LOGICAL_32BIT, integer);
|
||||
auto other = read_elt->push_step(step, env.dts->ts, pool);
|
||||
assert(other); // should be a high field.
|
||||
stack.push_value_to_reg(*dst, pool.alloc_single_form(nullptr, other), true,
|
||||
env.get_variable_type(*dst, true));
|
||||
} else {
|
||||
stack.push_form_element(form_elt, true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void AtomicOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||
mark_popped();
|
||||
auto as_end = dynamic_cast<const FunctionEndOp*>(m_op);
|
||||
if (as_end) {
|
||||
@@ -2343,15 +2619,30 @@ void AtomicOpElement::push_to_stack(const Env& env, FormPool&, FormStack& stack)
|
||||
|
||||
auto as_asm = dynamic_cast<const AsmOp*>(m_op);
|
||||
if (as_asm) {
|
||||
stack.push_form_element(this, true);
|
||||
switch (as_asm->instruction().kind) {
|
||||
case InstructionKind::SRL:
|
||||
push_asm_srl_to_stack(as_asm, this, env, pool, stack);
|
||||
break;
|
||||
default:
|
||||
stack.push_form_element(this, true);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error("Can't push atomic op to stack: " + m_op->to_string(env));
|
||||
}
|
||||
|
||||
void AsmOpElement::push_to_stack(const Env&, FormPool&, FormStack& stack) {
|
||||
void AsmOpElement::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||
mark_popped();
|
||||
stack.push_form_element(this, true);
|
||||
|
||||
switch (m_op->instruction().kind) {
|
||||
case InstructionKind::SRL:
|
||||
push_asm_srl_to_stack(m_op, this, env, pool, stack);
|
||||
break;
|
||||
default:
|
||||
stack.push_form_element(this, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GenericElement::update_from_stack(const Env& env,
|
||||
|
||||
@@ -64,10 +64,11 @@ class RegisterAccess {
|
||||
RegisterAccess(AccessMode mode, Register reg, int atomic_idx, bool allow_all = false);
|
||||
|
||||
enum class Print {
|
||||
AS_REG, // print as a PS2 register name
|
||||
FULL, // print as a register name, plus an index, plus read or write
|
||||
AS_VARIABLE, // print local variable name, error if impossible
|
||||
AUTOMATIC, // print as variable, but if that's not possible print as reg.
|
||||
AS_REG, // print as a PS2 register name
|
||||
FULL, // print as a register name, plus an index, plus read or write
|
||||
AS_VARIABLE, // print local variable name, error if impossible
|
||||
AS_VARIABLE_NO_CAST, // same as above, but no cast
|
||||
AUTOMATIC, // print as variable, but if that's not possible print as reg.
|
||||
};
|
||||
|
||||
goos::Object to_form(const Env& env, Print mode = Print::AUTOMATIC) const;
|
||||
|
||||
@@ -1665,11 +1665,9 @@
|
||||
|
||||
|
||||
;(define-extern sound-rpc-set-falloff-curve object) ;; unknown type
|
||||
;;(define-extern *sound-bank-2* object) ;; unknown type
|
||||
;;(define-extern sound-rpc-reload-info object) ;; unknown type
|
||||
;;(define-extern sound-rpc-stop-sound object) ;; unknown type
|
||||
;;(define-extern sound-rpc-list-sounds object) ;; unknown type
|
||||
;;(define-extern *current-sound-id* object) ;; unknown type
|
||||
;;(define-extern sound-bank-id object) ;; unknown type
|
||||
;;(define-extern sound-rpc-get-irx-version object) ;; unknown type
|
||||
;;(define-extern sound-rpc-load-music object) ;; unknown type
|
||||
@@ -1688,6 +1686,8 @@
|
||||
:flag-assert #xa00000004
|
||||
)
|
||||
|
||||
(define-extern *current-sound-id* sound-id)
|
||||
|
||||
(deftype sound-bank-id (uint32)
|
||||
()
|
||||
:flag-assert #x900000004
|
||||
@@ -1701,7 +1701,8 @@
|
||||
;;(define-extern sound-rpc-load-bank object) ;; unknown type
|
||||
;;(define-extern sound-rpc-set-master-volume object) ;; unknown type
|
||||
;;(define-extern sound-rpc-set-param object) ;; unknown type
|
||||
;;(define-extern *sound-bank-1* object) ;; unknown type
|
||||
(define-extern *sound-bank-1* symbol)
|
||||
(define-extern *sound-bank-2* symbol)
|
||||
;;(define-extern sound-rpc-stop-group object) ;; unknown type
|
||||
;;(define-extern sound-rpc-play object) ;; unknown type
|
||||
;;(define-extern sound-rpc-cmd object) ;; unknown type
|
||||
@@ -2203,7 +2204,7 @@
|
||||
(deftype vif-bank (structure)
|
||||
((stat uint32 :offset-assert 0)
|
||||
(fbrst uint32 :offset 16)
|
||||
(err uint32 :offset 32)
|
||||
(err vif-err :offset 32)
|
||||
(mark uint32 :offset 48)
|
||||
(cycle uint32 :offset 64)
|
||||
(mode uint32 :offset 80)
|
||||
@@ -2353,18 +2354,18 @@
|
||||
)
|
||||
|
||||
;; dma-h
|
||||
|
||||
(deftype vif-tag (uint32)
|
||||
((imm uint16 :offset 0 :size 16)
|
||||
(num uint8 :offset 16 :size 8)
|
||||
(cmd uint8 :offset 24 :size 8)
|
||||
(cmd uint8 :offset 24 :size 7)
|
||||
(msk uint8 :offset 28 :size 1)
|
||||
(irq uint8 :offset 31 :size 1) ;;?
|
||||
(msk uint8 :offset 15 :size 1)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
(deftype dma-enable (uint32)
|
||||
()
|
||||
:flag-assert #x900000004
|
||||
@@ -2479,6 +2480,9 @@
|
||||
:flag-assert #x900000014
|
||||
)
|
||||
|
||||
(define-extern *vu1-enable-user-menu* int)
|
||||
(define-extern *vu1-enable-user* int)
|
||||
|
||||
|
||||
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -2536,10 +2540,10 @@
|
||||
(define-extern *video-parms* video-parms) ;; unknown type
|
||||
;;(define-extern video-parms object) ;; unknown type
|
||||
;;(define-extern generic-bucket-state object) ;; unknown type
|
||||
;;(define-extern *vu1-enable-user-menu* object) ;; unknown type
|
||||
;; unknown type
|
||||
(define-extern dma-foreground-sink type)
|
||||
(define-extern dma-foreground-sink-group type)
|
||||
;;(define-extern *vu1-enable-user* object) ;; unknown type
|
||||
;; ;; unknown type
|
||||
(define-extern generic-dma-foreground-sink type)
|
||||
|
||||
|
||||
@@ -3243,7 +3247,7 @@
|
||||
(define-extern vector-vector-distance-squared (function vector vector float))
|
||||
(define-extern vector-vector-xz-distance (function vector vector float))
|
||||
(define-extern vector-vector-xz-distance-squared (function vector vector float))
|
||||
(define-extern vector-normalize! (function vector vector vector))
|
||||
(define-extern vector-normalize! (function vector float vector))
|
||||
(define-extern vector-normalize-ret-len! (function vector float float))
|
||||
(define-extern vector-normalize-copy! (function vector vector float vector))
|
||||
(define-extern vector-xz-normalize! (function vector float vector))
|
||||
|
||||
@@ -108,6 +108,12 @@
|
||||
["L136", "float", true]
|
||||
],
|
||||
|
||||
"timer": [["L20", "float", true]],
|
||||
|
||||
"dma": [["L56", "uint64", true]],
|
||||
|
||||
"video-h": [["L1", "video-parms", true]],
|
||||
|
||||
"pad": [
|
||||
["L44", "float", true],
|
||||
["L42", "float", true],
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
[132, "gp", "(array int8)"], // bug in game
|
||||
[150, "gp", "(array int16)"],
|
||||
[168, "gp", "(array uint16)"],
|
||||
[190, "gp", "(array uint128)"],
|
||||
[191, "gp", "(array uint128)"],
|
||||
[207, "gp", "(array int32)"],
|
||||
[226, "gp", "(array float)"],
|
||||
[243, "gp", "(array basic)"]
|
||||
@@ -49,9 +49,7 @@
|
||||
// GKERNEL-H
|
||||
"(method 2 handle)": [
|
||||
[10, "a2", "(pointer process)"],
|
||||
[11, "a3", "process"],
|
||||
[12, "v1", "int"],
|
||||
[16, "gp", "int"]
|
||||
[11, "a3", "process"]
|
||||
],
|
||||
|
||||
// GKERNEL
|
||||
@@ -120,6 +118,33 @@
|
||||
"vector-y-quaternion!": [[10, "v1", "(pointer uint128)"]],
|
||||
"vector-z-quaternion!": [[10, "v1", "(pointer uint128)"]],
|
||||
|
||||
// Matrix
|
||||
//"eul->matrix": [[[110, 228], "gp", "(pointer float)"]],
|
||||
|
||||
// DMA
|
||||
"dma-send-to-spr": [[[0, 32], "s5", "dma-bank-spr"]],
|
||||
"dma-send-to-spr-no-flush": [[[0, 32], "s5", "dma-bank-spr"]],
|
||||
"dma-send-from-spr": [[[0, 32], "s5", "dma-bank-spr"]],
|
||||
"dma-send-from-spr-no-flush": [[[0, 32], "s5", "dma-bank-spr"]],
|
||||
"dma-initialize": [
|
||||
[1, "v1", "vif-bank"],
|
||||
[8, "v1", "vif-bank"],
|
||||
[6, "a0", "vif-bank"],
|
||||
[13, "a0", "vif-bank"]
|
||||
],
|
||||
|
||||
"clear-vu1-mem": [[[0, 11], "v1", "(pointer uint32)"]],
|
||||
"clear-vu0-mem": [[[0, 11], "v1", "(pointer uint32)"]],
|
||||
|
||||
"dump-vu1-mem": [[[0, 49], "gp", "(pointer uint32)"]],
|
||||
|
||||
"dump-vu1-range": [[[0, 54], "s4", "(pointer uint32)"]],
|
||||
|
||||
"ultimate-memcpy": [
|
||||
[[0, 54], "s4", "dma-bank-spr"],
|
||||
[[0, 54], "s3", "dma-bank-spr"]
|
||||
],
|
||||
|
||||
// LEVEL
|
||||
"lookup-level-info": [
|
||||
[3, "a1", "symbol"],
|
||||
|
||||
@@ -578,14 +578,18 @@
|
||||
"args": ["tf", "dst-mat"]
|
||||
},
|
||||
|
||||
"quaternion-axis-angle!":{
|
||||
"quaternion-axis-angle!": {
|
||||
"args": ["quat", "x", "y", "z", "angle"]
|
||||
},
|
||||
|
||||
"quaternion-vector-angle!":{
|
||||
"quaternion-vector-angle!": {
|
||||
"args": ["quat", "axis", "angle"]
|
||||
},
|
||||
|
||||
"vector-flatten!": {
|
||||
"args": ["dst", "src", "plane-normal"]
|
||||
},
|
||||
|
||||
"deg-seek": {
|
||||
"args": ["in", "target", "max-diff"],
|
||||
"vars": {
|
||||
|
||||
@@ -10,14 +10,17 @@
|
||||
;; The PS2 supports several types of DMA, including simple chunk transfer and more complicated
|
||||
;; "chain" transfers, where the hardware can follow a linked data-structure.
|
||||
|
||||
;; In OpenGOAL, "DMA" will be instant. By default, DMA syncs will be disabled by this flag.
|
||||
;; In OpenGOAL, "DMA" will be instant, meaning the game code will stop, wait until the
|
||||
;; DMA is finished, and then continue. As a result, there is no need for DMA synchronization.
|
||||
;; When this flag is set, all DMA syncs will be instantaneous.
|
||||
(defglobalconstant INSTANT_DMA #t)
|
||||
|
||||
;; count returned by dma-sync-with-count
|
||||
;; when instant dma is enabled.
|
||||
;; Some DMA sync functions return a count for how long it took.
|
||||
;; When INSTANT_DMA is enabled, these functions will return this value.
|
||||
(defglobalconstant INSTANT_DMA_COUNT 123)
|
||||
|
||||
;; DMA Channel Control Register. This starts the DMA and can be checked to see if it done.
|
||||
;; There is one CHCR per DMA channel.
|
||||
(deftype dma-chcr (uint32)
|
||||
((dir uint8 :offset 0 :size 1) ;; 1 - from memory
|
||||
(mod uint8 :offset 2 :size 2) ;; normal, chain, interleave
|
||||
@@ -43,7 +46,8 @@
|
||||
obj
|
||||
)
|
||||
|
||||
;; Most basic DMA register layout
|
||||
;; Each DMA Channel has a bank of registers with the following layout.
|
||||
;; Some channels have more advanced features, but all support at least these three.
|
||||
(deftype dma-bank (structure)
|
||||
((chcr dma-chcr :offset 0) ;; control register
|
||||
(madr uint32 :offset 16) ;; memory address
|
||||
@@ -84,6 +88,8 @@
|
||||
:flag-assert #x900000084
|
||||
)
|
||||
|
||||
;; These addresses are the location of DMA banks for each channel.
|
||||
;; These do not exist in OpenGOAL.
|
||||
(defconstant VIF0_DMA_BANK (the dma-bank-vif #x10008000))
|
||||
(defconstant VIF1_DMA_BANK (the dma-bank-vif #x10009000))
|
||||
(defconstant GIF_DMA_BANK (the dma-bank #x1000a000))
|
||||
@@ -91,7 +97,14 @@
|
||||
(defconstant SPR_FROM_BANK (the dma-bank-spr #x1000d000))
|
||||
(defconstant SPR_TO_BANK (the dma-bank-spr #x1000d400))
|
||||
|
||||
;; D_CTRL, master DMA control register, shraed for all channels.
|
||||
(defconstant VU0_DATA_MEM_MAP (the (pointer uint32) #x11004000))
|
||||
(defconstant VU1_DATA_MEM_MAP (the (pointer uint32) #x1100c000))
|
||||
|
||||
|
||||
;; The DMA system also has some shared control registers that
|
||||
;; apply to all channels.
|
||||
|
||||
;; D_CTRL, master DMA control register, shared for all channels.
|
||||
(deftype dma-ctrl (uint32)
|
||||
()
|
||||
:method-count-assert 9
|
||||
@@ -202,9 +215,9 @@
|
||||
(deftype vif-tag (uint32)
|
||||
((imm uint16 :offset 0 :size 16)
|
||||
(num uint8 :offset 16 :size 8)
|
||||
(cmd uint8 :offset 24 :size 8)
|
||||
(cmd uint8 :offset 24 :size 7)
|
||||
(msk uint8 :offset 28 :size 1)
|
||||
(irq uint8 :offset 31 :size 1) ;;?
|
||||
(msk uint8 :offset 15 :size 1)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
@@ -252,7 +265,8 @@
|
||||
Makes sure any ongoing transfer on the channel is done
|
||||
Flushes the cache. Sets dir to 0, so I don't expect
|
||||
this to be used for VIF1 transfers.
|
||||
Madr should not be a scratchpad address."
|
||||
Madr should not be a scratchpad address.
|
||||
This function is unused."
|
||||
((inline dma-sync-fast) bank)
|
||||
(flush-cache 0)
|
||||
;; (.sync.l)
|
||||
@@ -272,7 +286,8 @@
|
||||
(count (pointer int32)))
|
||||
"Wait for DMA to finish, incrementing count.
|
||||
This doesn't seem like a very accurate way
|
||||
to find out how long it takes..."
|
||||
to find out how long it takes...
|
||||
This function is unused."
|
||||
(#cond
|
||||
(INSTANT_DMA
|
||||
(set! (-> count) INSTANT_DMA_COUNT)
|
||||
@@ -294,7 +309,8 @@
|
||||
|
||||
(defun dma-count-until-done ((bank dma-bank)
|
||||
(count (pointer int32)))
|
||||
"Like the previous one, kinda"
|
||||
"Like the previous one, kinda.
|
||||
This function is unused."
|
||||
(#cond
|
||||
(INSTANT_DMA
|
||||
(set! (-> count) INSTANT_DMA_COUNT)
|
||||
|
||||
+59
-84
@@ -17,14 +17,12 @@
|
||||
;; these functions are just here for completeness and won't work properly on PC.
|
||||
;; DMA sync functions will succeed and return instantly, so it's safe to leave those in.
|
||||
|
||||
(defconstant SPR_FROM_BANK (the dma-bank-spr #x100D000))
|
||||
(defconstant SPR_TO_BANK (the dma-bank-spr #x1000D400))
|
||||
|
||||
(defun dma-sync-hang ((bank dma-bank))
|
||||
"Hang here until the dma transfer is completed.
|
||||
This is worse than the dma-sync-fast because it ends
|
||||
up spamming the DMA bank register more often, and reduces
|
||||
the speed of the DMA transfer."
|
||||
the speed of the DMA transfer.
|
||||
This function is unused."
|
||||
(#cond
|
||||
(INSTANT_DMA
|
||||
0)
|
||||
@@ -38,59 +36,68 @@
|
||||
)
|
||||
|
||||
(defun dma-sync-crash ((arg0 dma-bank))
|
||||
"Try to sync DMA for a bit, then crash if we can't"
|
||||
(local-vars (count int))
|
||||
(#when INSTANT_DMA
|
||||
(return 0)
|
||||
"Wait for DMA to finish for a while, then crash if we can't.
|
||||
This function is unused."
|
||||
(#cond
|
||||
(INSTANT_DMA
|
||||
(return 0)
|
||||
)
|
||||
)
|
||||
(set! count 5000000)
|
||||
;; checking str
|
||||
(while (nonzero? (logand (the-as int (-> arg0 chcr)) 256))
|
||||
(if (zero? count)
|
||||
(segfault)
|
||||
(set! count (+ count -1))
|
||||
)
|
||||
(let ((v1-0 5000000))
|
||||
(while (nonzero? (-> arg0 chcr str))
|
||||
(if (zero? v1-0)
|
||||
(crash!)
|
||||
(+! v1-0 -1)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
(defmacro make-madr-addr (addr)
|
||||
"Convert an address to one suitable for MADR.
|
||||
This works with Main RAM (all mappings) and for spad"
|
||||
`(let ((int-addr (the-as int ,addr)))
|
||||
(logior (logand #xfffffff int-addr) ;; mask off spad/mapping bits
|
||||
(if (= (logand #x70000000 int-addr) #x70000000)
|
||||
#x80000000 ;; if we're in spad, set high bit.
|
||||
0 ;; otherwise nothing.
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
(defun dma-send ((arg0 dma-bank) (madr uint) (qwc uint))
|
||||
"Send DMA! madr can be a scratchpad address.
|
||||
Like dma-send-no-scratch, this sets chcr to zero, which may be undesirable."
|
||||
"Send DMA given an address and a quadword count.
|
||||
The madr can be in main memory or scratchpad.
|
||||
This is appropriate for VIF0/GIF transfers.
|
||||
It can be used for VIF1, but will do VIF -> madr, which is probably
|
||||
not what you want."
|
||||
(dma-sync (the-as pointer arg0) 0 0)
|
||||
(flush-cache 0)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 madr)
|
||||
(logior (logand #xfffffff (the-as int madr)) ;; lower 28 bits are untouched
|
||||
;; if we are transferring to the scratchpad (at 70000000)
|
||||
;; we should set bit 31 in madr, per the manual.
|
||||
(if (= (logand #x70000000 (the-as int madr)) #x70000000)
|
||||
(shl #x8000 16) ;; set bit 31
|
||||
0)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 madr) (make-madr-addr madr))
|
||||
(set! (-> arg0 qwc) qwc)
|
||||
(.sync.l)
|
||||
;; set str!
|
||||
;; begin DMA!
|
||||
(set! (-> arg0 chcr) (new 'static 'dma-chcr :str 1))
|
||||
(.sync.l)
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun dma-send-chain ((arg0 dma-bank-source) (tadr uint))
|
||||
"Send DMA! tadr should be a tag address, possibly in spad ram."
|
||||
"Send DMA! tadr should be a tag address, possibly in spad ram.
|
||||
This is useful for sending to VIF.
|
||||
Tag transfer is enabled, and DIR is set so a VIF1 transfer
|
||||
goes from tadr -> VIF."
|
||||
(dma-sync (the-as pointer arg0) 0 0)
|
||||
(flush-cache 0)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 qwc) 0)
|
||||
;; adjust address
|
||||
(set! (-> arg0 tadr)
|
||||
(logior (logand #xfffffff (the-as int tadr))
|
||||
(if (= (logand #x70000000 (the-as int tadr)) #x70000000)
|
||||
(shl #x8000 16)
|
||||
0)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 tadr) (make-madr-addr tadr))
|
||||
(.sync.l)
|
||||
;;(set! (-> arg0 chcr) 325)
|
||||
(set! (-> arg0 chcr)
|
||||
@@ -105,21 +112,13 @@
|
||||
)
|
||||
|
||||
(defun dma-send-chain-no-tte ((arg0 dma-bank-source) (arg1 uint))
|
||||
"Send DMA chain! TTE bit is not set, don't transfer tags."
|
||||
"Send DMA chain! TTE bit is not set, don't transfer tags.
|
||||
This is never used."
|
||||
(dma-sync (the-as pointer arg0) 0 0)
|
||||
(flush-cache 0)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 qwc) 0)
|
||||
(set!
|
||||
(-> arg0 tadr)
|
||||
(logior
|
||||
(logand #xfffffff (the-as int arg1))
|
||||
(the-as
|
||||
uint
|
||||
(if (= (logand #x70000000 (the-as int arg1)) #x70000000) (shl #x8000 16) 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 tadr) (make-madr-addr arg1))
|
||||
(.sync.l)
|
||||
(set! (-> arg0 chcr)
|
||||
(new 'static 'dma-chcr
|
||||
@@ -138,16 +137,7 @@
|
||||
(dma-sync (the-as pointer arg0) 0 0)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 qwc) 0)
|
||||
(set!
|
||||
(-> arg0 tadr)
|
||||
(logior
|
||||
(logand #xfffffff (the-as int arg1))
|
||||
(the-as
|
||||
uint
|
||||
(if (= (logand #x70000000 (the-as int arg1)) #x70000000) (shl #x8000 16) 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 tadr) arg1)
|
||||
(.sync.l)
|
||||
;;(set! (-> arg0 chcr) 325)
|
||||
(set! (-> arg0 chcr)
|
||||
@@ -158,7 +148,6 @@
|
||||
:str 1)
|
||||
)
|
||||
(.sync.l)
|
||||
(set! v0-1 0)
|
||||
(none)
|
||||
)
|
||||
|
||||
@@ -232,49 +221,35 @@
|
||||
(defun dma-initialize ()
|
||||
"Due to a bug in the PS2 hardware, you must always disable the DMAtag mismatch
|
||||
error. This is done here."
|
||||
|
||||
;; (declare (print-asm))
|
||||
(#when PC_PORT
|
||||
(format 0 "[dma.gc] skipping dma-initialize for PC port~%")
|
||||
(return 0)
|
||||
)
|
||||
|
||||
(set! (-> VIF0_BANK err)
|
||||
(logior (logand (-> VIF0_BANK err) (the-as uint -3)) 2)
|
||||
)
|
||||
(set! (-> (the vif-bank #x10003c00) err)
|
||||
(logior (logand (-> VIF1_BANK err) (the-as uint -3)) 2)
|
||||
)
|
||||
(set! (-> (the-as vif-bank #x10003800) err me0) 1)
|
||||
(set! (-> (the-as vif-bank #x10003c00) err me0) 1)
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun clear-vu0-mem ()
|
||||
"Clear the data memory of VU0, filling it with abadbeef
|
||||
This uses the slow memory mapping of VU0's data memory at 0x11004000"
|
||||
(local-vars
|
||||
(v1-0 (pointer uint32))
|
||||
(a0-0 int)
|
||||
)
|
||||
(set! v1-0 (the (pointer uint32) #x11004000))
|
||||
(set! a0-0 0)
|
||||
(while (< a0-0 1024)
|
||||
"Set the vu0 data memory to 0xabadbeef. This uses the slow EE mapping of VU memory."
|
||||
(let ((v1-0 VU0_DATA_MEM_MAP))
|
||||
(dotimes (a0-0 1024)
|
||||
(set! (-> v1-0 a0-0) #xabadbeef)
|
||||
(set! a0-0 (+ a0-0 1))
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun clear-vu1-mem ()
|
||||
"Clear the data memory of VU1, filling it with abadbeef
|
||||
This uses the slow memory mapping of VU1's data memory at 0x1100C000"
|
||||
(local-vars
|
||||
(v1-0 (pointer uint32))
|
||||
(a0-0 int)
|
||||
)
|
||||
(set! v1-0 (the (pointer uint32) #x1100c000))
|
||||
(set! a0-0 0)
|
||||
(while (< a0-0 4096)
|
||||
"Set the vu1 data memory to 0xabadbeef. This uses the slow EE mapping of VU memory."
|
||||
(let ((v1-0 VU1_DATA_MEM_MAP))
|
||||
(dotimes (a0-0 4096)
|
||||
(set! (-> v1-0 a0-0) #xabadbeef)
|
||||
(set! a0-0 (+ a0-0 1))
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
(define EulNext (new 'static 'boxed-array int32 4 1 2 0 1))
|
||||
|
||||
;; just uses the same xyzw and data array as vector.
|
||||
;; the w stores a float that should be an integer that seems to have
|
||||
;; bitfields for... something? Like maybe the order?
|
||||
(deftype euler-angles (vector)
|
||||
()
|
||||
:method-count-assert 9
|
||||
|
||||
@@ -5,3 +5,252 @@
|
||||
;; name in dgo: euler
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; In general, the euler angle stuff is really inefficient. I don't think it's really used outside of
|
||||
;; a few camera debugging functions.
|
||||
|
||||
(defun set-eul! ((arg0 euler-angles) (arg1 float) (arg2 float) (arg3 float) (arg4 int))
|
||||
"Set the euler angles. The 4th argument is for flags."
|
||||
(set! (-> arg0 data 0) arg1)
|
||||
(set! (-> arg0 data 1) arg2)
|
||||
(set! (-> arg0 data 2) arg3)
|
||||
(set! (-> arg0 data 3) (the float arg4))
|
||||
arg0
|
||||
)
|
||||
|
||||
(defun eul->matrix ((arg0 matrix) (arg1 euler-angles))
|
||||
"Convert euler angles to rotation matrix."
|
||||
(matrix-identity! arg0)
|
||||
(let ((s5-0 (new 'stack 'vector)))
|
||||
;; copy to temp storage.
|
||||
(set! (-> s5-0 quad) (-> arg1 quad))
|
||||
(if (= (logand (the int (-> s5-0 data 3)) 1) 1)
|
||||
(let ((f0-2 (-> s5-0 data 0)))
|
||||
(set! (-> s5-0 data 0) (-> s5-0 data 2))
|
||||
(set! (-> s5-0 data 2) f0-2)
|
||||
)
|
||||
)
|
||||
(when (= (logand (sar (the int (-> s5-0 data 3)) 2) 1) 1)
|
||||
(set! (-> s5-0 data 0) (- (-> s5-0 data 0)))
|
||||
(set! (-> s5-0 data 1) (- (-> s5-0 data 1)))
|
||||
(set! (-> s5-0 data 2) (- (-> s5-0 data 2)))
|
||||
)
|
||||
(let* ((f26-0 (cos (-> s5-0 data 0)))
|
||||
(f30-0 (cos (-> s5-0 data 1)))
|
||||
(f22-0 (cos (-> s5-0 data 2)))
|
||||
(f24-0 (sin (-> s5-0 data 0)))
|
||||
(f28-0 (sin (-> s5-0 data 1)))
|
||||
(f4-0 (sin (-> s5-0 data 2)))
|
||||
(f0-17 (* f26-0 f22-0))
|
||||
(f1-1 (* f26-0 f4-0))
|
||||
(f2-0 (* f24-0 f22-0))
|
||||
(f3-0 (* f24-0 f4-0))
|
||||
)
|
||||
(let* ((v1-12 (logand (sar (the int (-> s5-0 data 3)) 2) 1))
|
||||
(a1-2 (-> EulSafe (logand (sar (the int (-> s5-0 data 3)) 3) 3)))
|
||||
(a0-21 (-> EulNext (+ a1-2 v1-12)))
|
||||
(v1-17 (-> EulNext (+ (- 1 v1-12) a1-2)))
|
||||
)
|
||||
(cond
|
||||
((= (logand (sar (the int (-> s5-0 data 3)) 1) 1) 1)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl a1-2 2)) (the-as int arg0))))
|
||||
f30-0
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl a0-21 2)) (the-as int arg0))))
|
||||
(* f28-0 f24-0)
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl v1-17 2)) (the-as int arg0))))
|
||||
(* f28-0 f26-0)
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl a1-2 2)) (the-as int arg0))))
|
||||
(* f28-0 f4-0)
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl a0-21 2)) (the-as int arg0))))
|
||||
(- f0-17 (* f30-0 f3-0))
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl v1-17 2)) (the-as int arg0))))
|
||||
(- (- f2-0) (* f30-0 f1-1))
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl a1-2 2)) (the-as int arg0))))
|
||||
(- (* f28-0 f22-0))
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl a0-21 2)) (the-as int arg0))))
|
||||
(+ f1-1 (* f30-0 f2-0))
|
||||
)
|
||||
(let ((f0-19 (+ (- f3-0) (* f30-0 f0-17))))
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl v1-17 2)) (the-as int arg0))))
|
||||
f0-19
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl a1-2 2)) (the-as int arg0))))
|
||||
(* f30-0 f22-0)
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl a0-21 2)) (the-as int arg0))))
|
||||
(+ (- f1-1) (* f28-0 f2-0))
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a1-2 4) (shl v1-17 2)) (the-as int arg0))))
|
||||
(+ f3-0 (* f28-0 f0-17))
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl a1-2 2)) (the-as int arg0))))
|
||||
(* f30-0 f4-0)
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl a0-21 2)) (the-as int arg0))))
|
||||
(+ f0-17 (* f28-0 f3-0))
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl a0-21 4) (shl v1-17 2)) (the-as int arg0))))
|
||||
(+ (- f2-0) (* f28-0 f1-1))
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl a1-2 2)) (the-as int arg0))))
|
||||
(- f28-0)
|
||||
)
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl a0-21 2)) (the-as int arg0))))
|
||||
(* f30-0 f24-0)
|
||||
)
|
||||
(let ((f0-25 (* f30-0 f26-0)))
|
||||
(set! (-> (the-as (pointer float) (+ (+ (shl v1-17 4) (shl v1-17 2)) (the-as int arg0))))
|
||||
f0-25
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
arg0
|
||||
)
|
||||
|
||||
(defun matrix->eul ((arg0 euler-angles) (arg1 matrix) (arg2 int))
|
||||
"Conver matrix to euler angles. Takes some weird flag for what kind of euler angles"
|
||||
(let* ((v1-4 (logand (sar arg2 2) 1))
|
||||
(s3-0 (-> EulSafe (logand (sar arg2 3) 3)))
|
||||
(s2-0 (-> EulNext (+ s3-0 v1-4)))
|
||||
(s1-0 (-> EulNext (+ (- 1 v1-4) s3-0)))
|
||||
)
|
||||
(if (= (logand (sar arg2 1) 1) 1)
|
||||
(let* ((f0-0 (-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s3-0 4)) (the-as int arg1)))))
|
||||
(f0-2 (* f0-0 f0-0))
|
||||
(f1-0 (-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s3-0 4)) (the-as int arg1)))))
|
||||
(f30-0 (sqrtf (+ f0-2 (* f1-0 f1-0))))
|
||||
)
|
||||
(cond
|
||||
((< 0.00001 f30-0)
|
||||
(set! (-> arg0 data 0)
|
||||
(atan (-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s3-0 4)) (the-as int arg1))))
|
||||
(-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s3-0 4)) (the-as int arg1))))
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 1)
|
||||
(atan f30-0 (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1)))))
|
||||
)
|
||||
(let ((f0-13 (atan
|
||||
(-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))))
|
||||
(- (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1)))))
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 2) f0-13)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set! (-> arg0 data 0)
|
||||
(atan (- (-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s2-0 4)) (the-as int arg1)))))
|
||||
(-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s2-0 4)) (the-as int arg1))))
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 1)
|
||||
(atan
|
||||
f30-0
|
||||
(-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))))
|
||||
)
|
||||
)
|
||||
(let ((f0-20 0.0))
|
||||
(set! (-> arg0 data 2) f0-20)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let* ((f0-21 (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1)))))
|
||||
(f0-23 (* f0-21 f0-21))
|
||||
(f1-3 (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1)))))
|
||||
(f30-1 (sqrtf (+ f0-23 (* f1-3 f1-3))))
|
||||
)
|
||||
(cond
|
||||
((< 0.00001 f30-1)
|
||||
(set! (-> arg0 data 0)
|
||||
(atan
|
||||
(-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s1-0 4)) (the-as int arg1))))
|
||||
(-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s1-0 4)) (the-as int arg1))))
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 1)
|
||||
(atan
|
||||
(- (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1)))))
|
||||
f30-1
|
||||
)
|
||||
)
|
||||
(let ((f0-34 (atan
|
||||
(-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))))
|
||||
(-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))))
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 2) f0-34)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set! (-> arg0 data 0)
|
||||
(atan
|
||||
(- (-> (the-as (pointer float) (+ (+ (shl s1-0 2) (shl s2-0 4)) (the-as int arg1)))))
|
||||
(-> (the-as (pointer float) (+ (+ (shl s2-0 2) (shl s2-0 4)) (the-as int arg1))))
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 1)
|
||||
(atan
|
||||
(- (-> (the-as (pointer float) (+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1)))))
|
||||
f30-1
|
||||
)
|
||||
)
|
||||
(let ((f0-42 0.0))
|
||||
(set! (-> arg0 data 2) f0-42)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (= (logand (sar arg2 2) 1) 1)
|
||||
(set! (-> arg0 data 0) (- (-> arg0 data 0)))
|
||||
(set! (-> arg0 data 1) (- (-> arg0 data 1)))
|
||||
(let ((f0-48 (- (-> arg0 data 2))))
|
||||
(set! (-> arg0 data 2) f0-48)
|
||||
)
|
||||
)
|
||||
(if (= (logand arg2 1) 1)
|
||||
(let ((f0-49 (-> arg0 data 0)))
|
||||
(set! (-> arg0 data 0) (-> arg0 data 2))
|
||||
(set! (-> arg0 data 2) f0-49)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 3) (the float arg2))
|
||||
arg0
|
||||
)
|
||||
|
||||
(defun eul->quat ((arg0 quaternion) (arg1 euler-angles))
|
||||
"Convert euler angles to quaternion"
|
||||
(let ((s5-0 (new 'stack 'matrix)))
|
||||
(eul->matrix s5-0 arg1)
|
||||
(matrix->quaternion arg0 s5-0)
|
||||
)
|
||||
arg0
|
||||
)
|
||||
|
||||
(defun quat->eul ((arg0 euler-angles) (arg1 quaternion) (arg2 int))
|
||||
"Convert quaternion to euler angles. The last argument is euler flags"
|
||||
(let ((s5-0 (new 'stack 'matrix)))
|
||||
(quaternion->matrix s5-0 arg1)
|
||||
(matrix->eul arg0 s5-0 arg2)
|
||||
)
|
||||
arg0
|
||||
)
|
||||
|
||||
|
||||
@@ -686,3 +686,6 @@
|
||||
(define-extern vector-length (function vector float))
|
||||
(define-extern vector-xz-normalize! (function vector float vector))
|
||||
(define-extern vector-xz-length (function vector float))
|
||||
(defun-extern vector+float*! vector vector vector float vector)
|
||||
(defun-extern vector-normalize! vector float vector)
|
||||
(defun-extern vector-float*! vector vector float vector)
|
||||
|
||||
@@ -464,32 +464,6 @@
|
||||
;; (.svf a0-0 vf1)
|
||||
;; (ret-value v0-0)))
|
||||
|
||||
(defun vector-normalize! ((arg0 vector) (arg1 vector))
|
||||
"TODO"
|
||||
(local-vars (v1-0 vector))
|
||||
(rlet ((acc :class vf)
|
||||
(Q :class vf)
|
||||
(vf0 :class vf)
|
||||
(vf1 :class vf)
|
||||
(vf2 :class vf)
|
||||
(vf3 :class vf))
|
||||
(.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0))
|
||||
(.lvf vf1 arg0)
|
||||
(.mul.vf vf2 vf1 vf1 :mask #b1110)
|
||||
(set! v1-0 arg1)
|
||||
(.mov vf3 v1-0)
|
||||
(.mul.x.vf acc vf0 vf2 :mask #b1)
|
||||
(.add.mul.y.vf acc vf0 vf2 acc :mask #b1)
|
||||
(.add.mul.z.vf vf2 vf0 vf2 acc :mask #b1)
|
||||
(.isqrt.vf Q vf3 vf2 :ftf #b0 :fsf #b11)
|
||||
(.wait.vf)
|
||||
(.mul.vf vf1 vf1 Q :mask #b1110)
|
||||
(.nop.vf)
|
||||
(.nop.vf)
|
||||
(.nop.vf)
|
||||
(.svf arg0 vf1)
|
||||
arg0))
|
||||
|
||||
(defun vector-vector-xz-distance-squared ((arg0 vector) (arg1 vector))
|
||||
"TODO"
|
||||
(local-vars (v0-0 int))
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
(deftype vif-bank (structure)
|
||||
((stat uint32 :offset-assert 0)
|
||||
(fbrst uint32 :offset 16)
|
||||
(err uint32 :offset 32)
|
||||
(err vif-err :offset 32)
|
||||
(mark uint32 :offset 48)
|
||||
(cycle uint32 :offset 64)
|
||||
(mode uint32 :offset 80)
|
||||
|
||||
@@ -177,6 +177,11 @@
|
||||
`(/ 0 0)
|
||||
)
|
||||
|
||||
(defmacro crash! ()
|
||||
"Cause a crash by attempting to deference 0x0"
|
||||
`(-> (the (pointer uint8) 0))
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
;; GOAL Syntax
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@@ -118,6 +118,9 @@
|
||||
(define-extern quaternion-from-two-vectors-max-angle! (function quaternion vector vector float quaternion))
|
||||
(define-extern vector-xz-length (function vector float))
|
||||
|
||||
(defmacro .sync.l ()
|
||||
`(none))
|
||||
|
||||
;; display-h
|
||||
(deftype display-env (structure)
|
||||
((pmode uint64 :offset-assert 0)
|
||||
@@ -216,4 +219,4 @@
|
||||
)
|
||||
)
|
||||
|
||||
(define-extern *display* display)
|
||||
(define-extern *display* display)
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition of type dma-chcr
|
||||
(deftype dma-chcr (uint32)
|
||||
((dir uint8 :offset 0 :size 1)
|
||||
(mod uint8 :offset 2 :size 2)
|
||||
(asp uint8 :offset 4 :size 2)
|
||||
(tte uint8 :offset 6 :size 1)
|
||||
(tie uint8 :offset 7 :size 1)
|
||||
(str uint8 :offset 8 :size 1)
|
||||
(tag uint16 :offset 16 :size 16)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-chcr
|
||||
(defmethod inspect dma-chcr ((obj dma-chcr))
|
||||
(format #t "[~8x] ~A~%" obj 'dma-chcr)
|
||||
(format #t "~Tdir: ~D~%" (-> obj dir))
|
||||
(format #t "~Tmod: ~D~%" (-> obj mod))
|
||||
(format #t "~Tasp: ~D~%" (-> obj asp))
|
||||
(format #t "~Ttte: ~D~%" (-> obj tte))
|
||||
(format #t "~Ttie: ~D~%" (-> obj tie))
|
||||
(format #t "~Tstr: ~D~%" (-> obj str))
|
||||
(format #t "~Ttag: #x~X~%" (-> obj tag))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type dma-bank
|
||||
(deftype dma-bank (structure)
|
||||
((chcr dma-chcr :offset 0)
|
||||
(madr uint32 :offset 16)
|
||||
(qwc uint32 :offset 32)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x24
|
||||
:flag-assert #x900000024
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-bank
|
||||
(defmethod inspect dma-bank ((obj dma-bank))
|
||||
(format #t "[~8x] ~A~%" obj 'dma-bank)
|
||||
(format #t "~Tchcr: #x~X~%" (-> obj chcr))
|
||||
(format #t "~Tmadr: #x~X~%" (-> obj madr))
|
||||
(format #t "~Tqwc: #x~X~%" (-> obj qwc))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type dma-bank-source
|
||||
(deftype dma-bank-source (dma-bank)
|
||||
((tadr uint32 :offset 48)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x34
|
||||
:flag-assert #x900000034
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-bank-source
|
||||
(defmethod inspect dma-bank-source ((obj dma-bank-source))
|
||||
(format #t "[~8x] ~A~%" obj 'dma-bank-source)
|
||||
(format #t "~Tchcr: #x~X~%" (-> obj chcr))
|
||||
(format #t "~Tmadr: #x~X~%" (-> obj madr))
|
||||
(format #t "~Tqwc: #x~X~%" (-> obj qwc))
|
||||
(format #t "~Ttadr: #x~X~%" (-> obj tadr))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type dma-bank-vif
|
||||
(deftype dma-bank-vif (dma-bank-source)
|
||||
((as0 uint32 :offset 64)
|
||||
(as1 uint32 :offset 80)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x54
|
||||
:flag-assert #x900000054
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-bank-vif
|
||||
(defmethod inspect dma-bank-vif ((obj dma-bank-vif))
|
||||
(format #t "[~8x] ~A~%" obj 'dma-bank-vif)
|
||||
(format #t "~Tchcr: #x~X~%" (-> obj chcr))
|
||||
(format #t "~Tmadr: #x~X~%" (-> obj madr))
|
||||
(format #t "~Tqwc: #x~X~%" (-> obj qwc))
|
||||
(format #t "~Ttadr: #x~X~%" (-> obj tadr))
|
||||
(format #t "~Tas0: #x~X~%" (-> obj as0))
|
||||
(format #t "~Tas1: #x~X~%" (-> obj as1))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type dma-bank-spr
|
||||
(deftype dma-bank-spr (dma-bank-source)
|
||||
((sadr uint32 :offset 128)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x84
|
||||
:flag-assert #x900000084
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-bank-spr
|
||||
(defmethod inspect dma-bank-spr ((obj dma-bank-spr))
|
||||
(format #t "[~8x] ~A~%" obj 'dma-bank-spr)
|
||||
(format #t "~Tchcr: #x~X~%" (-> obj chcr))
|
||||
(format #t "~Tmadr: #x~X~%" (-> obj madr))
|
||||
(format #t "~Tqwc: #x~X~%" (-> obj qwc))
|
||||
(format #t "~Ttadr: #x~X~%" (-> obj tadr))
|
||||
(format #t "~Tsadr: #x~X~%" (-> obj sadr))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type dma-ctrl
|
||||
(deftype dma-ctrl (uint32)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition of type dma-enable
|
||||
(deftype dma-enable (uint32)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition of type dma-sqwc
|
||||
(deftype dma-sqwc (uint32)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition of type dma-bank-control
|
||||
(deftype dma-bank-control (structure)
|
||||
((ctrl dma-ctrl :offset 0)
|
||||
(stat uint32 :offset 16)
|
||||
(pcr uint32 :offset 32)
|
||||
(sqwc dma-sqwc :offset 48)
|
||||
(rbsr uint32 :offset 64)
|
||||
(rbor uint32 :offset 80)
|
||||
(stadr uint32 :offset 96)
|
||||
(enabler uint32 :offset 5408)
|
||||
(enablew uint32 :offset 5520)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x1594
|
||||
:flag-assert #x900001594
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-bank-control
|
||||
(defmethod inspect dma-bank-control ((obj dma-bank-control))
|
||||
(format #t "[~8x] ~A~%" obj 'dma-bank-control)
|
||||
(format #t "~Tctrl: #x~X~%" (-> obj ctrl))
|
||||
(format #t "~Tstat: #x~X~%" (-> obj stat))
|
||||
(format #t "~Tpcr: #x~X~%" (-> obj pcr))
|
||||
(format #t "~Tsqwc: #x~X~%" (-> obj sqwc))
|
||||
(format #t "~Trbsr: #x~X~%" (-> obj rbsr))
|
||||
(format #t "~Trbor: #x~X~%" (-> obj rbor))
|
||||
(format #t "~Tstadr: #x~X~%" (-> obj stadr))
|
||||
(format #t "~Tenabler: ~D~%" (-> obj enabler))
|
||||
(format #t "~Tenablew: ~D~%" (-> obj enablew))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type vu-code-block
|
||||
(deftype vu-code-block (basic)
|
||||
((name basic :offset-assert 4)
|
||||
(code uint32 :offset-assert 8)
|
||||
(size int32 :offset-assert 12)
|
||||
(dest-address uint32 :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x14
|
||||
:flag-assert #x900000014
|
||||
)
|
||||
|
||||
;; definition for method 3 of type vu-code-block
|
||||
(defmethod inspect vu-code-block ((obj vu-code-block))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tname: ~A~%" (-> obj name))
|
||||
(format #t "~Tcode: #x~X~%" (-> obj code))
|
||||
(format #t "~Tsize: ~D~%" (-> obj size))
|
||||
(format #t "~Tdest-address: ~D~%" (-> obj dest-address))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type vu-stat
|
||||
(deftype vu-stat (uint64)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; definition of type dma-tag
|
||||
(deftype dma-tag (uint64)
|
||||
((qwc uint16 :offset 0 :size 16)
|
||||
(pce uint8 :offset 26 :size 2)
|
||||
(id uint8 :offset 28 :size 3)
|
||||
(irq uint8 :offset 31 :size 1)
|
||||
(addr uint32 :offset 32 :size 31)
|
||||
(spr uint8 :offset 63 :size 1)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-tag
|
||||
(defmethod inspect dma-tag ((obj dma-tag))
|
||||
(format #t "[~8x] ~A~%" obj 'dma-tag)
|
||||
(format #t "~Tqwc: ~D~%" (-> obj qwc))
|
||||
(format #t "~Tpce: ~D~%" (-> obj pce))
|
||||
(format #t "~Tid: ~D~%" (-> obj id))
|
||||
(format #t "~Tirq: ~D~%" (-> obj irq))
|
||||
(format #t "~Taddr: #x~X~%" (-> obj addr))
|
||||
(format #t "~Tspr: ~D~%" (-> obj spr))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type dma-bucket
|
||||
(deftype dma-bucket (structure)
|
||||
((tag dma-tag :offset-assert 0)
|
||||
(last (pointer uint64) :offset-assert 8)
|
||||
(dummy uint32 :offset-assert 12)
|
||||
(next uint32 :offset 4)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-bucket
|
||||
(defmethod inspect dma-bucket ((obj dma-bucket))
|
||||
(format #t "[~8x] ~A~%" obj 'dma-bucket)
|
||||
(format #t "~Ttag: ~D~%" (-> obj tag))
|
||||
(format #t "~Tlast: #x~X~%" (-> obj last))
|
||||
(format #t "~Tdummy: ~D~%" (-> obj dummy))
|
||||
(format #t "~Tnext: #x~X~%" (-> obj next))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type vif-mask
|
||||
(deftype vif-mask (uint32)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition of type vif-stcycl-imm
|
||||
(deftype vif-stcycl-imm (uint16)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x2
|
||||
:flag-assert #x900000002
|
||||
)
|
||||
|
||||
;; definition of type vif-unpack-imm
|
||||
(deftype vif-unpack-imm (uint16)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x2
|
||||
:flag-assert #x900000002
|
||||
)
|
||||
|
||||
;; definition of type vif-tag
|
||||
(deftype vif-tag (uint32)
|
||||
((imm uint16 :offset 0 :size 16)
|
||||
(num uint8 :offset 16 :size 8)
|
||||
(cmd uint8 :offset 24 :size 7)
|
||||
(msk uint8 :offset 28 :size 1)
|
||||
(irq uint8 :offset 31 :size 1)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type vif-tag
|
||||
(defmethod inspect vif-tag ((obj vif-tag))
|
||||
(format #t "[~8x] ~A~%" obj 'vif-tag)
|
||||
(format #t "~Timm: #x~X~%" (-> obj imm))
|
||||
(format #t "~Tnum: ~D~%" (-> obj num))
|
||||
(format #t "~Tcmd: #x~X~%" (-> obj cmd))
|
||||
(format #t "~Tmsk: ~D~%" (-> obj msk))
|
||||
(format #t "~Tirq: ~D~%" (-> obj irq))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for function dma-sync-fast
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
;; definition for function dma-send-no-scratch
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
;; definition for function dma-sync-with-count
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
;; definition for function dma-count-until-done
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,419 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition for function dma-sync-hang
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
;; definition for function dma-sync-crash
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
(defun dma-sync-crash ((arg0 dma-bank))
|
||||
(let ((v1-0 #x4c4b40))
|
||||
(while (nonzero? (-> arg0 chcr str))
|
||||
(cond
|
||||
((zero? v1-0)
|
||||
(crash!)
|
||||
(let ((a1-0 0))
|
||||
)
|
||||
)
|
||||
(else
|
||||
(+! v1-0 -1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((v0-0 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-send
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun dma-send ((arg0 dma-bank) (arg1 uint) (arg2 uint))
|
||||
(dma-sync (the-as pointer arg0) 0 0)
|
||||
(flush-cache 0)
|
||||
(.sync.l)
|
||||
(set!
|
||||
(-> arg0 madr)
|
||||
(logior
|
||||
(logand #xfffffff (the-as int arg1))
|
||||
(the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)
|
||||
(shl #x8000 16)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 qwc) arg2)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 chcr) (new 'static 'dma-chcr :str #x1))
|
||||
(.sync.l)
|
||||
(let ((v0-1 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-send-chain
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun dma-send-chain ((arg0 dma-bank-source) (arg1 uint))
|
||||
(dma-sync (the-as pointer arg0) 0 0)
|
||||
(flush-cache 0)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 qwc) (the-as uint 0))
|
||||
(set!
|
||||
(-> arg0 tadr)
|
||||
(logior
|
||||
(logand #xfffffff (the-as int arg1))
|
||||
(the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)
|
||||
(shl #x8000 16)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(.sync.l)
|
||||
(set!
|
||||
(-> arg0 chcr)
|
||||
(new 'static 'dma-chcr :dir #x1 :mod #x1 :tte #x1 :str #x1)
|
||||
)
|
||||
(.sync.l)
|
||||
(let ((v0-1 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-send-chain-no-tte
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun dma-send-chain-no-tte ((arg0 dma-bank-source) (arg1 uint))
|
||||
(dma-sync (the-as pointer arg0) 0 0)
|
||||
(flush-cache 0)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 qwc) (the-as uint 0))
|
||||
(set!
|
||||
(-> arg0 tadr)
|
||||
(logior
|
||||
(logand #xfffffff (the-as int arg1))
|
||||
(the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)
|
||||
(shl #x8000 16)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 chcr) (new 'static 'dma-chcr :dir #x1 :mod #x1 :str #x1))
|
||||
(.sync.l)
|
||||
(let ((v0-1 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-send-chain-no-flush
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun dma-send-chain-no-flush ((arg0 dma-bank-source) (arg1 uint))
|
||||
(dma-sync (the-as pointer arg0) 0 0)
|
||||
(.sync.l)
|
||||
(set! (-> arg0 qwc) (the-as uint 0))
|
||||
(set!
|
||||
(-> arg0 tadr)
|
||||
(logior
|
||||
(logand #xfffffff (the-as int arg1))
|
||||
(the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)
|
||||
(shl #x8000 16)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(.sync.l)
|
||||
(set!
|
||||
(-> arg0 chcr)
|
||||
(new 'static 'dma-chcr :dir #x1 :mod #x1 :tte #x1 :str #x1)
|
||||
)
|
||||
(.sync.l)
|
||||
(let ((v0-1 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-send-to-spr
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun dma-send-to-spr ((sadr uint) (madr uint) (qwc uint) (sync symbol))
|
||||
(let ((s5-0 (the-as dma-bank-spr #x1000d400)))
|
||||
(dma-sync (the-as pointer s5-0) 0 0)
|
||||
(flush-cache 0)
|
||||
(.sync.l)
|
||||
(set! (-> s5-0 madr) (logand #xfffffff (the-as int madr)))
|
||||
(set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr)))
|
||||
(set! (-> s5-0 qwc) qwc)
|
||||
(.sync.l)
|
||||
(set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1))
|
||||
(.sync.l)
|
||||
(if sync
|
||||
(dma-sync (the-as pointer s5-0) 0 0)
|
||||
)
|
||||
)
|
||||
(let ((v0-2 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-send-to-spr-no-flush
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun
|
||||
dma-send-to-spr-no-flush
|
||||
((sadr uint) (madr uint) (qwc uint) (sync symbol))
|
||||
(let ((s5-0 (the-as dma-bank-spr #x1000d400)))
|
||||
(dma-sync (the-as pointer s5-0) 0 0)
|
||||
(.sync.l)
|
||||
(set! (-> s5-0 madr) (logand #xfffffff (the-as int madr)))
|
||||
(set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr)))
|
||||
(set! (-> s5-0 qwc) qwc)
|
||||
(.sync.l)
|
||||
(set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1))
|
||||
(.sync.l)
|
||||
(if sync
|
||||
(dma-sync (the-as pointer s5-0) 0 0)
|
||||
)
|
||||
)
|
||||
(let ((v0-2 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-send-from-spr
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun dma-send-from-spr ((madr uint) (sadr uint) (qwc uint) (sync symbol))
|
||||
(let ((s5-0 (the-as dma-bank-spr #x1000d000)))
|
||||
(dma-sync (the-as pointer s5-0) 0 0)
|
||||
(flush-cache 0)
|
||||
(.sync.l)
|
||||
(set! (-> s5-0 madr) (logand #xfffffff (the-as int madr)))
|
||||
(set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr)))
|
||||
(set! (-> s5-0 qwc) qwc)
|
||||
(.sync.l)
|
||||
(set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1))
|
||||
(.sync.l)
|
||||
(if sync
|
||||
(dma-sync (the-as pointer s5-0) 0 0)
|
||||
)
|
||||
)
|
||||
(let ((v0-2 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-send-from-spr-no-flush
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun
|
||||
dma-send-from-spr-no-flush
|
||||
((madr uint) (sadr uint) (qwc uint) (sync symbol))
|
||||
(let ((s5-0 (the-as dma-bank-spr #x1000d000)))
|
||||
(dma-sync (the-as pointer s5-0) 0 0)
|
||||
(.sync.l)
|
||||
(set! (-> s5-0 madr) (logand #xfffffff (the-as int madr)))
|
||||
(set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr)))
|
||||
(set! (-> s5-0 qwc) qwc)
|
||||
(.sync.l)
|
||||
(set! (-> s5-0 chcr) (new 'static 'dma-chcr :str #x1))
|
||||
(.sync.l)
|
||||
(if sync
|
||||
(dma-sync (the-as pointer s5-0) 0 0)
|
||||
)
|
||||
)
|
||||
(let ((v0-2 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dma-initialize
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
(defun dma-initialize ()
|
||||
(set! (-> (the-as vif-bank #x10003800) err me0) 1)
|
||||
(set! (-> (the-as vif-bank #x10003c00) err me0) 1)
|
||||
(let ((v0-0 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function clear-vu0-mem
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
(defun clear-vu0-mem ()
|
||||
(let ((v1-0 (the-as (pointer uint32) #x11004000)))
|
||||
(dotimes (a0-0 1024)
|
||||
(set! (-> v1-0 a0-0) #xabadbeef)
|
||||
)
|
||||
)
|
||||
(let ((v0-0 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function clear-vu1-mem
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
(defun clear-vu1-mem ()
|
||||
(let ((v1-0 (the-as (pointer uint32) #x1100c000)))
|
||||
(dotimes (a0-0 4096)
|
||||
(set! (-> v1-0 a0-0) #xabadbeef)
|
||||
)
|
||||
)
|
||||
(let ((v0-0 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dump-vu1-mem
|
||||
;; INFO: Return type mismatch symbol vs none.
|
||||
(defun dump-vu1-mem ()
|
||||
(let ((gp-0 (the-as (pointer uint32) #x1100c000)))
|
||||
(dotimes (s5-0 1024)
|
||||
(format
|
||||
0
|
||||
"~4,'0X: ~8,'0X ~8,'0X ~8,'0X ~8,'0X"
|
||||
s5-0
|
||||
(-> gp-0 (shl s5-0 2))
|
||||
(-> gp-0 (+ (shl s5-0 2) 1))
|
||||
(-> gp-0 (+ (shl s5-0 2) 2))
|
||||
(-> gp-0 (+ (shl s5-0 2) 3))
|
||||
)
|
||||
(format
|
||||
0
|
||||
" ~F ~F ~F ~F ~%"
|
||||
(-> gp-0 (shl s5-0 2))
|
||||
(-> gp-0 (+ (shl s5-0 2) 1))
|
||||
(-> gp-0 (+ (shl s5-0 2) 2))
|
||||
(-> gp-0 (+ (shl s5-0 2) 3))
|
||||
)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function dump-vu1-range
|
||||
(defun dump-vu1-range ((start uint) (total-count uint))
|
||||
(let ((s4-0 (the-as (pointer uint32) #x1100c000)))
|
||||
(dotimes (s3-0 (the-as int total-count))
|
||||
(let ((s2-0 (+ s3-0 (the-as int start))))
|
||||
(format
|
||||
0
|
||||
"~4,'0X: ~8x ~8x ~8x ~8x"
|
||||
s2-0
|
||||
(-> s4-0 (shl s2-0 2))
|
||||
(-> s4-0 (+ (shl s2-0 2) 1))
|
||||
(-> s4-0 (+ (shl s2-0 2) 2))
|
||||
(-> s4-0 (+ (shl s2-0 2) 3))
|
||||
)
|
||||
(format
|
||||
0
|
||||
" ~F ~F ~F ~F ~%"
|
||||
(-> s4-0 (shl s2-0 2))
|
||||
(-> s4-0 (+ (shl s2-0 2) 1))
|
||||
(-> s4-0 (+ (shl s2-0 2) 2))
|
||||
(-> s4-0 (+ (shl s2-0 2) 3))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
#f
|
||||
)
|
||||
|
||||
;; definition for symbol *video-reset-parm*, type int
|
||||
(define *video-reset-parm* 2)
|
||||
|
||||
;; definition for function reset-vif1-path
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
(defun reset-vif1-path ()
|
||||
((method-of-type dma-bank-vif inspect) (the-as dma-bank-vif #x10009000))
|
||||
((method-of-type vif-bank inspect) (the-as vif-bank #x10003c00))
|
||||
(reset-path)
|
||||
(reset-graph 1 1 *video-reset-parm* 1)
|
||||
(format 0 "gkernel: vif1 path reset!~%")
|
||||
(let ((v0-3 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function ultimate-memcpy
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun ultimate-memcpy ((dst pointer) (src pointer) (size-bytes uint))
|
||||
(let ((spr-to-bank (the-as dma-bank-spr #x1000d400))
|
||||
(spr-from-bank (the-as dma-bank-spr #x1000d000))
|
||||
(qwc-remaining (shr size-bytes 4))
|
||||
)
|
||||
(flush-cache 0)
|
||||
(dma-sync (the-as pointer spr-to-bank) 0 0)
|
||||
(dma-sync (the-as pointer spr-from-bank) 0 0)
|
||||
(while (> qwc-remaining 0)
|
||||
(let ((qwc-transferred-now (the-as int qwc-remaining)))
|
||||
(if (< (the-as uint 1024) (the-as uint qwc-transferred-now))
|
||||
(set! qwc-transferred-now 1024)
|
||||
)
|
||||
(set! qwc-remaining (- qwc-remaining (the-as uint qwc-transferred-now)))
|
||||
(.sync.l)
|
||||
(set! (-> spr-to-bank madr) (the-as uint src))
|
||||
(set! (-> spr-to-bank sadr) (the-as uint 0))
|
||||
(set! (-> spr-to-bank qwc) (the-as uint qwc-transferred-now))
|
||||
(.sync.l)
|
||||
(set! (-> spr-to-bank chcr) (new 'static 'dma-chcr :str #x1))
|
||||
(.sync.l)
|
||||
(dma-sync (the-as pointer spr-to-bank) 0 0)
|
||||
(&+! src (shl qwc-transferred-now 4))
|
||||
(set! (-> spr-from-bank madr) (the-as uint dst))
|
||||
(set! (-> spr-from-bank sadr) (the-as uint 0))
|
||||
(set! (-> spr-from-bank qwc) (the-as uint qwc-transferred-now))
|
||||
(.sync.l)
|
||||
(set! (-> spr-from-bank chcr) (new 'static 'dma-chcr :str #x1))
|
||||
(.sync.l)
|
||||
(dma-sync (the-as pointer spr-from-bank) 0 0)
|
||||
(&+! dst (shl qwc-transferred-now 4))
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((v0-4 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function symlink2
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
;; definition for function symlink3
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(dma-initialize)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,516 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition for function set-eul!
|
||||
(defun
|
||||
set-eul!
|
||||
((arg0 euler-angles) (arg1 float) (arg2 float) (arg3 float) (arg4 int))
|
||||
(set! (-> arg0 data 0) arg1)
|
||||
(set! (-> arg0 data 1) arg2)
|
||||
(set! (-> arg0 data 2) arg3)
|
||||
(set! (-> arg0 data 3) (the float arg4))
|
||||
arg0
|
||||
)
|
||||
|
||||
;; definition for function eul->matrix
|
||||
;; Used lq/sq
|
||||
(defun eul->matrix ((arg0 matrix) (arg1 euler-angles))
|
||||
(matrix-identity! arg0)
|
||||
(let ((s5-0 (new 'stack 'vector)))
|
||||
(set! (-> s5-0 quad) (-> arg1 quad))
|
||||
(if (= (logand (the int (-> s5-0 data 3)) 1) 1)
|
||||
(let ((f0-2 (-> s5-0 data 0)))
|
||||
(set! (-> s5-0 data 0) (-> s5-0 data 2))
|
||||
(set! (-> s5-0 data 2) f0-2)
|
||||
)
|
||||
)
|
||||
(when (= (logand (sar (the int (-> s5-0 data 3)) 2) 1) 1)
|
||||
(set! (-> s5-0 data 0) (- (-> s5-0 data 0)))
|
||||
(set! (-> s5-0 data 1) (- (-> s5-0 data 1)))
|
||||
(let ((f0-10 (- (-> s5-0 data 2))))
|
||||
(set! (-> s5-0 data 2) f0-10)
|
||||
)
|
||||
)
|
||||
(let* ((f26-0 (cos (-> s5-0 data 0)))
|
||||
(f30-0 (cos (-> s5-0 data 1)))
|
||||
(f22-0 (cos (-> s5-0 data 2)))
|
||||
(f24-0 (sin (-> s5-0 data 0)))
|
||||
(f28-0 (sin (-> s5-0 data 1)))
|
||||
(f4-0 (sin (-> s5-0 data 2)))
|
||||
(f0-17 (* f26-0 f22-0))
|
||||
(f1-1 (* f26-0 f4-0))
|
||||
(f2-0 (* f24-0 f22-0))
|
||||
(f3-0 (* f24-0 f4-0))
|
||||
)
|
||||
(let ((v1-7 0))
|
||||
)
|
||||
(let ((v1-8 0))
|
||||
)
|
||||
(let ((v1-9 0))
|
||||
)
|
||||
(let* ((v1-12 (logand (sar (the int (-> s5-0 data 3)) 2) 1))
|
||||
(a1-2 (-> EulSafe (logand (sar (the int (-> s5-0 data 3)) 3) 3)))
|
||||
(a0-21 (-> EulNext (+ a1-2 v1-12)))
|
||||
(v1-17 (-> EulNext (+ (- 1 v1-12) a1-2)))
|
||||
)
|
||||
(cond
|
||||
((= (logand (sar (the int (-> s5-0 data 3)) 1) 1) 1)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a1-2 4) (shl a1-2 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
f30-0
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a1-2 4) (shl a0-21 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(* f28-0 f24-0)
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a1-2 4) (shl v1-17 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(* f28-0 f26-0)
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a0-21 4) (shl a1-2 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(* f28-0 f4-0)
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a0-21 4) (shl a0-21 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(- f0-17 (* f30-0 f3-0))
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a0-21 4) (shl v1-17 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(- (- f2-0) (* f30-0 f1-1))
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-17 4) (shl a1-2 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(- (* f28-0 f22-0))
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-17 4) (shl a0-21 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(+ f1-1 (* f30-0 f2-0))
|
||||
)
|
||||
(let ((f0-19 (+ (- f3-0) (* f30-0 f0-17))))
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-17 4) (shl v1-17 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
f0-19
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a1-2 4) (shl a1-2 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(* f30-0 f22-0)
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a1-2 4) (shl a0-21 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(+ (- f1-1) (* f28-0 f2-0))
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a1-2 4) (shl v1-17 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(+ f3-0 (* f28-0 f0-17))
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a0-21 4) (shl a1-2 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(* f30-0 f4-0)
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a0-21 4) (shl a0-21 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(+ f0-17 (* f28-0 f3-0))
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a0-21 4) (shl v1-17 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(+ (- f2-0) (* f28-0 f1-1))
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-17 4) (shl a1-2 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(- f28-0)
|
||||
)
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-17 4) (shl a0-21 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
(* f30-0 f24-0)
|
||||
)
|
||||
(let ((f0-25 (* f30-0 f26-0)))
|
||||
(set!
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-17 4) (shl v1-17 2)) (the-as int arg0))
|
||||
)
|
||||
)
|
||||
f0-25
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
arg0
|
||||
)
|
||||
|
||||
;; definition for function matrix->eul
|
||||
(defun matrix->eul ((arg0 euler-angles) (arg1 matrix) (arg2 int))
|
||||
(let ((v1-0 0))
|
||||
)
|
||||
(let ((v1-1 0))
|
||||
)
|
||||
(let ((v1-2 0))
|
||||
)
|
||||
(let* ((v1-4 (logand (sar arg2 2) 1))
|
||||
(s3-0 (-> EulSafe (logand (sar arg2 3) 3)))
|
||||
(s2-0 (-> EulNext (+ s3-0 v1-4)))
|
||||
(s1-0 (-> EulNext (+ (- 1 v1-4) s3-0)))
|
||||
)
|
||||
(if (= (logand (sar arg2 1) 1) 1)
|
||||
(let*
|
||||
((f0-0
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s2-0 2) (shl s3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(f0-2 (* f0-0 f0-0))
|
||||
(f1-0
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s1-0 2) (shl s3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(f30-0 (sqrtf (+ f0-2 (* f1-0 f1-0))))
|
||||
)
|
||||
(cond
|
||||
((< 0.00001 f30-0)
|
||||
(set!
|
||||
(-> arg0 data 0)
|
||||
(atan
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s2-0 2) (shl s3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s1-0 2) (shl s3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> arg0 data 1)
|
||||
(atan
|
||||
f30-0
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let
|
||||
((f0-13
|
||||
(atan
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(-
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 2) f0-13)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set!
|
||||
(-> arg0 data 0)
|
||||
(atan
|
||||
(-
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s1-0 2) (shl s2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s2-0 2) (shl s2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> arg0 data 1)
|
||||
(atan
|
||||
f30-0
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((f0-20 0.0))
|
||||
(set! (-> arg0 data 2) f0-20)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let*
|
||||
((f0-21
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(f0-23 (* f0-21 f0-21))
|
||||
(f1-3
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(f30-1 (sqrtf (+ f0-23 (* f1-3 f1-3))))
|
||||
)
|
||||
(cond
|
||||
((< 0.00001 f30-1)
|
||||
(set!
|
||||
(-> arg0 data 0)
|
||||
(atan
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s2-0 2) (shl s1-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s1-0 2) (shl s1-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> arg0 data 1)
|
||||
(atan
|
||||
(-
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
f30-1
|
||||
)
|
||||
)
|
||||
(let
|
||||
((f0-34
|
||||
(atan
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 2) f0-34)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set!
|
||||
(-> arg0 data 0)
|
||||
(atan
|
||||
(-
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s1-0 2) (shl s2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s2-0 2) (shl s2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> arg0 data 1)
|
||||
(atan
|
||||
(-
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl s3-0 2) (shl s1-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
f30-1
|
||||
)
|
||||
)
|
||||
(let ((f0-42 0.0))
|
||||
(set! (-> arg0 data 2) f0-42)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (= (logand (sar arg2 2) 1) 1)
|
||||
(set! (-> arg0 data 0) (- (-> arg0 data 0)))
|
||||
(set! (-> arg0 data 1) (- (-> arg0 data 1)))
|
||||
(let ((f0-48 (- (-> arg0 data 2))))
|
||||
(set! (-> arg0 data 2) f0-48)
|
||||
)
|
||||
)
|
||||
(if (= (logand arg2 1) 1)
|
||||
(let ((f0-49 (-> arg0 data 0)))
|
||||
(set! (-> arg0 data 0) (-> arg0 data 2))
|
||||
(set! (-> arg0 data 2) f0-49)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data 3) (the float arg2))
|
||||
arg0
|
||||
)
|
||||
|
||||
;; definition for function eul->quat
|
||||
(defun eul->quat ((arg0 quaternion) (arg1 euler-angles))
|
||||
(let ((s5-0 (new 'stack 'matrix)))
|
||||
(eul->matrix s5-0 arg1)
|
||||
(matrix->quaternion arg0 s5-0)
|
||||
)
|
||||
arg0
|
||||
)
|
||||
|
||||
;; definition for function quat->eul
|
||||
(defun quat->eul ((arg0 euler-angles) (arg1 quaternion) (arg2 int))
|
||||
(let ((s5-0 (new 'stack 'matrix)))
|
||||
(quaternion->matrix s5-0 arg1)
|
||||
(matrix->eul arg0 s5-0 arg2)
|
||||
)
|
||||
arg0
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -816,7 +816,7 @@
|
||||
#t
|
||||
"~T [~D] #x~X~%"
|
||||
s5-8
|
||||
(-> (the-as (pointer uint128) (+ (shl s5-8 4) (the-as int obj))))
|
||||
(-> (the-as (array uint128) obj) s5-8)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -279,8 +279,8 @@
|
||||
;; definition for method 3 of type handle
|
||||
(defmethod inspect handle ((obj handle))
|
||||
(format #t "[~8x] ~A~%" obj 'handle)
|
||||
(format #t "~Tprocess: #x~X~%" (shr (shl (the-as int obj) 32) 32))
|
||||
(format #t "~Tpid: ~D~%" (sar (the-as int obj) 32))
|
||||
(format #t "~Tprocess: #x~X~%" (-> obj process))
|
||||
(format #t "~Tpid: ~D~%" (-> obj pid))
|
||||
obj
|
||||
)
|
||||
|
||||
@@ -295,17 +295,17 @@
|
||||
(a1-0 "#<handle :process ~A :pid ~D>")
|
||||
(v1-0 obj)
|
||||
)
|
||||
(.subu a2-0 (the-as handle v1-0) s7-0)
|
||||
(.subu a2-0 v1-0 s7-0)
|
||||
(t9-0 a0-1 a1-0 (and (nonzero? a2-0) (begin
|
||||
(.sllv a2-2 (the-as handle v1-0) r0-0)
|
||||
(.sllv a2-2 v1-0 r0-0)
|
||||
(let ((a3-0 (-> a2-2 0)))
|
||||
(if (= (sar v1-0 32) (-> a3-0 pid))
|
||||
(if (= (-> v1-0 pid) (-> a3-0 pid))
|
||||
a3-0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(sar (the-as int obj) 32)
|
||||
(-> obj pid)
|
||||
)
|
||||
)
|
||||
(format #t "#<handle :process 0 :pid 0>")
|
||||
|
||||
@@ -0,0 +1,796 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition of type sound-id
|
||||
(deftype sound-id (uint32)
|
||||
()
|
||||
:method-count-assert 10
|
||||
:size-assert #x4
|
||||
:flag-assert #xa00000004
|
||||
(:methods
|
||||
(dummy-9 () none 9)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition of type sound-bank-id
|
||||
(deftype sound-bank-id (uint32)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition of type sound-name
|
||||
(deftype sound-name (uint128)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-cmd
|
||||
(deftype sound-rpc-cmd (structure)
|
||||
((rsvd1 uint16 :offset-assert 0)
|
||||
(command uint16 :offset-assert 2)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-cmd
|
||||
(defmethod inspect sound-rpc-cmd ((obj sound-rpc-cmd))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-cmd)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-play-parms
|
||||
(deftype sound-play-parms (structure)
|
||||
((mask uint16 :offset-assert 0)
|
||||
(pitch-mod int16 :offset-assert 2)
|
||||
(bend int16 :offset-assert 4)
|
||||
(fo-min int16 :offset-assert 6)
|
||||
(fo-max int16 :offset-assert 8)
|
||||
(fo-curve int8 :offset-assert 10)
|
||||
(priority int8 :offset-assert 11)
|
||||
(volume int32 :offset-assert 12)
|
||||
(trans float 3 :offset-assert 16)
|
||||
(group uint8 :offset-assert 28)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x1d
|
||||
:flag-assert #x90000001d
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-play-parms
|
||||
(defmethod inspect sound-play-parms ((obj sound-play-parms))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-play-parms)
|
||||
(format #t "~Tmask: ~D~%" (-> obj mask))
|
||||
(format #t "~Tpitch-mod: ~D~%" (-> obj pitch-mod))
|
||||
(format #t "~Tbend: ~D~%" (-> obj bend))
|
||||
(format #t "~Tfo-min: ~D~%" (-> obj fo-min))
|
||||
(format #t "~Tfo-max: ~D~%" (-> obj fo-max))
|
||||
(format #t "~Tfo-curve: ~D~%" (-> obj fo-curve))
|
||||
(format #t "~Tpriority: ~D~%" (-> obj priority))
|
||||
(format #t "~Tvolume: ~D~%" (-> obj volume))
|
||||
(format #t "~Ttrans[3] @ #x~X~%" (-> obj trans))
|
||||
(format #t "~Tgroup: ~D~%" (-> obj group))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-bank-cmd
|
||||
(deftype sound-rpc-bank-cmd (sound-rpc-cmd)
|
||||
((bank-name uint128 :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-bank-cmd
|
||||
;; Used lq/sq
|
||||
(defmethod inspect sound-rpc-bank-cmd ((obj sound-rpc-bank-cmd))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-bank-cmd)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tbank-name: ~D~%" (-> obj bank-name))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-sound-cmd
|
||||
(deftype sound-rpc-sound-cmd (sound-rpc-cmd)
|
||||
((id uint32 :offset-assert 4)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-sound-cmd
|
||||
(defmethod inspect sound-rpc-sound-cmd ((obj sound-rpc-sound-cmd))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-sound-cmd)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tid: ~D~%" (-> obj id))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-group-cmd
|
||||
(deftype sound-rpc-group-cmd (sound-rpc-cmd)
|
||||
((group uint8 :offset-assert 4)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x5
|
||||
:flag-assert #x900000005
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-group-cmd
|
||||
(defmethod inspect sound-rpc-group-cmd ((obj sound-rpc-group-cmd))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-group-cmd)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tgroup: ~D~%" (-> obj group))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-load-bank
|
||||
(deftype sound-rpc-load-bank (sound-rpc-bank-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-load-bank
|
||||
;; Used lq/sq
|
||||
(defmethod inspect sound-rpc-load-bank ((obj sound-rpc-load-bank))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-load-bank)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tbank-name: ~D~%" (-> obj bank-name))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-load-music
|
||||
(deftype sound-rpc-load-music (sound-rpc-bank-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-load-music
|
||||
;; Used lq/sq
|
||||
(defmethod inspect sound-rpc-load-music ((obj sound-rpc-load-music))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-load-music)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tbank-name: ~D~%" (-> obj bank-name))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-unload-bank
|
||||
(deftype sound-rpc-unload-bank (sound-rpc-bank-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-unload-bank
|
||||
;; Used lq/sq
|
||||
(defmethod inspect sound-rpc-unload-bank ((obj sound-rpc-unload-bank))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-unload-bank)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tbank-name: ~D~%" (-> obj bank-name))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-play
|
||||
(deftype sound-rpc-play (sound-rpc-sound-cmd)
|
||||
((name uint128 :offset-assert 16)
|
||||
(parms sound-play-parms :inline :offset-assert 32)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x3d
|
||||
:flag-assert #x90000003d
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-play
|
||||
;; Used lq/sq
|
||||
(defmethod inspect sound-rpc-play ((obj sound-rpc-play))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-play)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tid: ~D~%" (-> obj id))
|
||||
(format #t "~Tname: ~D~%" (-> obj name))
|
||||
(format #t "~Tparms: #<sound-play-parms @ #x~X>~%" (-> obj parms))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-pause-sound
|
||||
(deftype sound-rpc-pause-sound (sound-rpc-sound-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-pause-sound
|
||||
(defmethod inspect sound-rpc-pause-sound ((obj sound-rpc-pause-sound))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-pause-sound)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tid: ~D~%" (-> obj id))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-stop-sound
|
||||
(deftype sound-rpc-stop-sound (sound-rpc-sound-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-stop-sound
|
||||
(defmethod inspect sound-rpc-stop-sound ((obj sound-rpc-stop-sound))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-stop-sound)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tid: ~D~%" (-> obj id))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-continue-sound
|
||||
(deftype sound-rpc-continue-sound (sound-rpc-sound-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-continue-sound
|
||||
(defmethod inspect sound-rpc-continue-sound ((obj sound-rpc-continue-sound))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-continue-sound)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tid: ~D~%" (-> obj id))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-set-param
|
||||
(deftype sound-rpc-set-param (sound-rpc-sound-cmd)
|
||||
((parms sound-play-parms :inline :offset-assert 8)
|
||||
(auto-time int32 :offset-assert 40)
|
||||
(auto-from int32 :offset-assert 44)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x30
|
||||
:flag-assert #x900000030
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-set-param
|
||||
(defmethod inspect sound-rpc-set-param ((obj sound-rpc-set-param))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-param)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tid: ~D~%" (-> obj id))
|
||||
(format #t "~Tparms: #<sound-play-parms @ #x~X>~%" (-> obj parms))
|
||||
(format #t "~Tauto-time: ~D~%" (-> obj auto-time))
|
||||
(format #t "~Tauto-from: ~D~%" (-> obj auto-from))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-set-master-volume
|
||||
(deftype sound-rpc-set-master-volume (sound-rpc-group-cmd)
|
||||
((volume int32 :offset-assert 8)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #xc
|
||||
:flag-assert #x90000000c
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-set-master-volume
|
||||
(defmethod
|
||||
inspect
|
||||
sound-rpc-set-master-volume
|
||||
((obj sound-rpc-set-master-volume))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-master-volume)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tgroup: ~D~%" (-> obj group))
|
||||
(format #t "~Tvolume: ~D~%" (-> obj volume))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-pause-group
|
||||
(deftype sound-rpc-pause-group (sound-rpc-group-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x5
|
||||
:flag-assert #x900000005
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-pause-group
|
||||
(defmethod inspect sound-rpc-pause-group ((obj sound-rpc-pause-group))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-pause-group)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tgroup: ~D~%" (-> obj group))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-stop-group
|
||||
(deftype sound-rpc-stop-group (sound-rpc-group-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x5
|
||||
:flag-assert #x900000005
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-stop-group
|
||||
(defmethod inspect sound-rpc-stop-group ((obj sound-rpc-stop-group))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-stop-group)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tgroup: ~D~%" (-> obj group))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-continue-group
|
||||
(deftype sound-rpc-continue-group (sound-rpc-group-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x5
|
||||
:flag-assert #x900000005
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-continue-group
|
||||
(defmethod inspect sound-rpc-continue-group ((obj sound-rpc-continue-group))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-continue-group)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tgroup: ~D~%" (-> obj group))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-get-irx-version
|
||||
(deftype sound-rpc-get-irx-version (sound-rpc-cmd)
|
||||
((major uint32 :offset-assert 4)
|
||||
(minor uint32 :offset-assert 8)
|
||||
(ee-addr uint32 :offset-assert 12)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-get-irx-version
|
||||
(defmethod inspect sound-rpc-get-irx-version ((obj sound-rpc-get-irx-version))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-get-irx-version)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tmajor: ~D~%" (-> obj major))
|
||||
(format #t "~Tminor: ~D~%" (-> obj minor))
|
||||
(format #t "~Tee-addr: ~D~%" (-> obj ee-addr))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-set-language
|
||||
(deftype sound-rpc-set-language (sound-rpc-cmd)
|
||||
((lang uint32 :offset-assert 4)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-set-language
|
||||
(defmethod inspect sound-rpc-set-language ((obj sound-rpc-set-language))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-language)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tlang: ~D~%" (-> obj lang))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-set-falloff-curve
|
||||
(deftype sound-rpc-set-falloff-curve (sound-rpc-cmd)
|
||||
((curve int32 :offset-assert 4)
|
||||
(falloff int32 :offset-assert 8)
|
||||
(ease int32 :offset-assert 12)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-set-falloff-curve
|
||||
(defmethod
|
||||
inspect
|
||||
sound-rpc-set-falloff-curve
|
||||
((obj sound-rpc-set-falloff-curve))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-falloff-curve)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tcurve: ~D~%" (-> obj curve))
|
||||
(format #t "~Tfalloff: ~D~%" (-> obj falloff))
|
||||
(format #t "~Tease: ~D~%" (-> obj ease))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-set-sound-falloff
|
||||
(deftype sound-rpc-set-sound-falloff (sound-rpc-cmd)
|
||||
((name uint128 :offset-assert 16)
|
||||
(curve int32 :offset-assert 32)
|
||||
(min int32 :offset-assert 36)
|
||||
(max int32 :offset-assert 40)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x2c
|
||||
:flag-assert #x90000002c
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-set-sound-falloff
|
||||
;; Used lq/sq
|
||||
(defmethod
|
||||
inspect
|
||||
sound-rpc-set-sound-falloff
|
||||
((obj sound-rpc-set-sound-falloff))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-sound-falloff)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tname: ~D~%" (-> obj name))
|
||||
(format #t "~Tcurve: ~D~%" (-> obj curve))
|
||||
(format #t "~Tmin: ~D~%" (-> obj min))
|
||||
(format #t "~Tmax: ~D~%" (-> obj max))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-reload-info
|
||||
(deftype sound-rpc-reload-info (sound-rpc-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-reload-info
|
||||
(defmethod inspect sound-rpc-reload-info ((obj sound-rpc-reload-info))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-reload-info)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-set-reverb
|
||||
(deftype sound-rpc-set-reverb (sound-rpc-cmd)
|
||||
((core uint8 :offset-assert 4)
|
||||
(reverb int32 :offset-assert 8)
|
||||
(left uint32 :offset-assert 12)
|
||||
(right uint32 :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x14
|
||||
:flag-assert #x900000014
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-set-reverb
|
||||
(defmethod inspect sound-rpc-set-reverb ((obj sound-rpc-set-reverb))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-reverb)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tcore: ~D~%" (-> obj core))
|
||||
(format #t "~Treverb: ~D~%" (-> obj reverb))
|
||||
(format #t "~Tleft: ~D~%" (-> obj left))
|
||||
(format #t "~Tright: ~D~%" (-> obj right))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-set-ear-trans
|
||||
(deftype sound-rpc-set-ear-trans (sound-rpc-cmd)
|
||||
((ear-trans float 3 :offset-assert 4)
|
||||
(cam-trans float 3 :offset-assert 16)
|
||||
(cam-angle int32 :offset-assert 28)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-set-ear-trans
|
||||
(defmethod inspect sound-rpc-set-ear-trans ((obj sound-rpc-set-ear-trans))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-ear-trans)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tear-trans[3] @ #x~X~%" (-> obj ear-trans))
|
||||
(format #t "~Tcam-trans[3] @ #x~X~%" (-> obj cam-trans))
|
||||
(format #t "~Tcam-angle: ~D~%" (-> obj cam-angle))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-set-flava
|
||||
(deftype sound-rpc-set-flava (sound-rpc-cmd)
|
||||
((flava uint8 :offset-assert 4)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x5
|
||||
:flag-assert #x900000005
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-set-flava
|
||||
(defmethod inspect sound-rpc-set-flava ((obj sound-rpc-set-flava))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-set-flava)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
(format #t "~Tflava: ~D~%" (-> obj flava))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-shutdown
|
||||
(deftype sound-rpc-shutdown (sound-rpc-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-shutdown
|
||||
(defmethod inspect sound-rpc-shutdown ((obj sound-rpc-shutdown))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-shutdown)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-list-sounds
|
||||
(deftype sound-rpc-list-sounds (sound-rpc-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-list-sounds
|
||||
(defmethod inspect sound-rpc-list-sounds ((obj sound-rpc-list-sounds))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-list-sounds)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-unload-music
|
||||
(deftype sound-rpc-unload-music (sound-rpc-cmd)
|
||||
()
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-unload-music
|
||||
(defmethod inspect sound-rpc-unload-music ((obj sound-rpc-unload-music))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-unload-music)
|
||||
(format #t "~Trsvd1: ~D~%" (-> obj rsvd1))
|
||||
(format #t "~Tcommand: ~D~%" (-> obj command))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-rpc-union
|
||||
(deftype sound-rpc-union (structure)
|
||||
((data uint32 20 :offset-assert 0)
|
||||
(load-bank sound-rpc-load-bank :offset 0)
|
||||
(unload-bank sound-rpc-unload-bank :offset 0)
|
||||
(play sound-rpc-play :offset 0)
|
||||
(pause-sound sound-rpc-pause-sound :offset 0)
|
||||
(stop-sound sound-rpc-stop-sound :offset 0)
|
||||
(continue-sound sound-rpc-continue-sound :offset 0)
|
||||
(set-param sound-rpc-set-param :offset 0)
|
||||
(set-master-volume sound-rpc-set-master-volume :offset 0)
|
||||
(pause-group sound-rpc-pause-group :offset 0)
|
||||
(stop-group sound-rpc-stop-group :offset 0)
|
||||
(continue-group sound-rpc-continue-group :offset 0)
|
||||
(get-irx-version sound-rpc-get-irx-version :offset 0)
|
||||
(set-falloff-curve sound-rpc-set-falloff-curve :offset 0)
|
||||
(set-sound-falloff sound-rpc-set-sound-falloff :offset 0)
|
||||
(reload-info sound-rpc-reload-info :offset 0)
|
||||
(set-language sound-rpc-set-language :offset 0)
|
||||
(set-reverb sound-rpc-set-reverb :offset 0)
|
||||
(set-ear-trans sound-rpc-set-ear-trans :offset 0)
|
||||
(set-flava sound-rpc-set-flava :offset 0)
|
||||
(shutdown sound-rpc-shutdown :offset 0)
|
||||
(list-sounds sound-rpc-list-sounds :offset 0)
|
||||
(unload-music sound-rpc-unload-music :offset 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x50
|
||||
:flag-assert #x900000050
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-rpc-union
|
||||
(defmethod inspect sound-rpc-union ((obj sound-rpc-union))
|
||||
(format #t "[~8x] ~A~%" obj 'sound-rpc-union)
|
||||
(format #t "~Tdata[20] @ #x~X~%" (-> obj data))
|
||||
(format #t "~Tload-bank: #<sound-rpc-load-bank @ #x~X>~%" (-> obj data 0))
|
||||
(format #t "~Tunload-bank: #<sound-rpc-unload-bank @ #x~X>~%" (-> obj data 0))
|
||||
(format #t "~Tplay: #<sound-rpc-play @ #x~X>~%" (-> obj data 0))
|
||||
(format #t "~Tpause-sound: #<sound-rpc-pause-sound @ #x~X>~%" (-> obj data 0))
|
||||
(format #t "~Tstop-sound: #<sound-rpc-stop-sound @ #x~X>~%" (-> obj data 0))
|
||||
(format
|
||||
#t
|
||||
"~Tcontinue-sound: #<sound-rpc-continue-sound @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
(format #t "~Tset-param: #<sound-rpc-set-param @ #x~X>~%" (-> obj data 0))
|
||||
(format
|
||||
#t
|
||||
"~Tset-master-volume: #<sound-rpc-set-master-volume @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
(format #t "~Tpause-group: #<sound-rpc-pause-group @ #x~X>~%" (-> obj data 0))
|
||||
(format #t "~Tstop-group: #<sound-rpc-stop-group @ #x~X>~%" (-> obj data 0))
|
||||
(format
|
||||
#t
|
||||
"~Tcontinue-group: #<sound-rpc-continue-group @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
(format
|
||||
#t
|
||||
"~Tget-irx-version: #<sound-rpc-get-irx-version @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
(format
|
||||
#t
|
||||
"~Tset-falloff-curve: #<sound-rpc-set-falloff-curve @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
(format
|
||||
#t
|
||||
"~Tset-sound-falloff: #<sound-rpc-set-sound-falloff @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
(format #t "~Treload-info: #<sound-rpc-reload-info @ #x~X>~%" (-> obj data 0))
|
||||
(format
|
||||
#t
|
||||
"~Tset-language: #<sound-rpc-set-language @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
(format #t "~Tset-reverb: #<sound-rpc-set-reverb @ #x~X>~%" (-> obj data 0))
|
||||
(format
|
||||
#t
|
||||
"~Tset-ear-trans: #<sound-rpc-set-ear-trans @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
(format #t "~Tset-flava: #<sound-rpc-set-flava @ #x~X>~%" (-> obj data 0))
|
||||
(format #t "~Tshutdown: #<sound-rpc-shutdown @ #x~X>~%" (-> obj data 0))
|
||||
(format #t "~Tlist-sounds: #<sound-rpc-list-sounds @ #x~X>~%" (-> obj data 0))
|
||||
(format
|
||||
#t
|
||||
"~Tunload-music: #<sound-rpc-unload-music @ #x~X>~%"
|
||||
(-> obj data 0)
|
||||
)
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type sound-spec
|
||||
(deftype sound-spec (basic)
|
||||
((mask uint16 :offset-assert 4)
|
||||
(num float :offset-assert 8)
|
||||
(group uint8 :offset-assert 12)
|
||||
(sound-name-char uint8 16 :offset 16)
|
||||
(sound-name uint128 :offset 16)
|
||||
(trans float 4 :offset-assert 32)
|
||||
(volume int32 :offset-assert 48)
|
||||
(pitch-mod int32 :offset-assert 52)
|
||||
(bend int32 :offset-assert 56)
|
||||
(fo-min int16 :offset-assert 60)
|
||||
(fo-max int16 :offset-assert 62)
|
||||
(fo-curve int8 :offset-assert 64)
|
||||
(priority int8 :offset-assert 65)
|
||||
(auto-time int32 :offset-assert 68)
|
||||
(auto-from int32 :offset-assert 72)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4c
|
||||
:flag-assert #x90000004c
|
||||
)
|
||||
|
||||
;; definition for method 3 of type sound-spec
|
||||
;; Used lq/sq
|
||||
(defmethod inspect sound-spec ((obj sound-spec))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tmask: ~D~%" (-> obj mask))
|
||||
(format #t "~Tnum: ~f~%" (-> obj num))
|
||||
(format #t "~Tgroup: ~D~%" (-> obj group))
|
||||
(format #t "~Tsound-name-char[16] @ #x~X~%" (-> obj sound-name-char))
|
||||
(format #t "~Tsound-name: ~D~%" (-> obj sound-name))
|
||||
(format #t "~Ttrans[4] @ #x~X~%" (-> obj trans))
|
||||
(format #t "~Tvolume: ~D~%" (-> obj volume))
|
||||
(format #t "~Tpitch-mod: ~D~%" (-> obj pitch-mod))
|
||||
(format #t "~Tbend: ~D~%" (-> obj bend))
|
||||
(format #t "~Tfo-min: ~D~%" (-> obj fo-min))
|
||||
(format #t "~Tfo-max: ~D~%" (-> obj fo-max))
|
||||
(format #t "~Tfo-curve: ~D~%" (-> obj fo-curve))
|
||||
(format #t "~Tpriority: ~D~%" (-> obj priority))
|
||||
(format #t "~Tauto-time: ~D~%" (-> obj auto-time))
|
||||
(format #t "~Tauto-from: ~D~%" (-> obj auto-from))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for symbol *current-sound-id*, type sound-id
|
||||
(define *current-sound-id* (the-as sound-id #x10000))
|
||||
|
||||
;; definition of type ambient-sound
|
||||
(deftype ambient-sound (basic)
|
||||
((spec basic :offset-assert 4)
|
||||
(playing-id uint32 :offset-assert 8)
|
||||
(trans vector :inline :offset-assert 16)
|
||||
(name uint128 :offset-assert 32)
|
||||
(play-time uint64 :offset-assert 48)
|
||||
(time-base uint64 :offset-assert 56)
|
||||
(time-random uint64 :offset-assert 64)
|
||||
(volume int32 :offset-assert 72)
|
||||
(pitch int32 :offset-assert 76)
|
||||
(falloff-near int32 :offset-assert 80)
|
||||
(falloff-far int32 :offset-assert 84)
|
||||
(falloff-mode int32 :offset-assert 88)
|
||||
(params uint32 :offset-assert 92)
|
||||
(param-count int32 :offset-assert 96)
|
||||
(entity basic :offset-assert 100)
|
||||
(sound-count int32 :offset-assert 104)
|
||||
)
|
||||
:method-count-assert 14
|
||||
:size-assert #x6c
|
||||
:flag-assert #xe0000006c
|
||||
(:methods
|
||||
(dummy-9 () none 9)
|
||||
(dummy-10 () none 10)
|
||||
(dummy-11 () none 11)
|
||||
(dummy-12 () none 12)
|
||||
(dummy-13 () none 13)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 3 of type ambient-sound
|
||||
;; Used lq/sq
|
||||
(defmethod inspect ambient-sound ((obj ambient-sound))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tspec: ~A~%" (-> obj spec))
|
||||
(format #t "~Tplaying-id: ~D~%" (-> obj playing-id))
|
||||
(format #t "~Ttrans: ~`vector`P~%" (-> obj trans))
|
||||
(format #t "~Tname: ~D~%" (-> obj name))
|
||||
(format #t "~Tplay-time: ~D~%" (-> obj play-time))
|
||||
(format #t "~Ttime-base: ~D~%" (-> obj time-base))
|
||||
(format #t "~Ttime-random: ~D~%" (-> obj time-random))
|
||||
(format #t "~Tvolume: ~D~%" (-> obj volume))
|
||||
(format #t "~Tpitch: ~D~%" (-> obj pitch))
|
||||
(format #t "~Tfalloff-near: ~D~%" (-> obj falloff-near))
|
||||
(format #t "~Tfalloff-far: ~D~%" (-> obj falloff-far))
|
||||
(format #t "~Tfalloff-mode: ~D~%" (-> obj falloff-mode))
|
||||
(format #t "~Tparams: #x~X~%" (-> obj params))
|
||||
(format #t "~Tparam-count: ~D~%" (-> obj param-count))
|
||||
(format #t "~Tentity: ~A~%" (-> obj entity))
|
||||
(format #t "~Tsound-count: ~D~%" (-> obj sound-count))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for symbol *sound-bank-1*, type symbol
|
||||
(define *sound-bank-1* #f)
|
||||
|
||||
;; definition for symbol *sound-bank-2*, type symbol
|
||||
(define *sound-bank-2* #f)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let ((v0-34 0))
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition of type timer-mode
|
||||
(deftype timer-mode (uint32)
|
||||
((clks uint8 :offset 0 :size 2)
|
||||
(gate uint8 :offset 2 :size 1)
|
||||
(gats uint8 :offset 3 :size 1)
|
||||
(gatm uint8 :offset 4 :size 2)
|
||||
(zret uint8 :offset 6 :size 1)
|
||||
(cue uint8 :offset 7 :size 1)
|
||||
(cmpe uint8 :offset 8 :size 1)
|
||||
(ovfe uint8 :offset 9 :size 1)
|
||||
(equf uint8 :offset 10 :size 1)
|
||||
(ovff uint8 :offset 11 :size 1)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition of type timer-bank
|
||||
(deftype timer-bank (structure)
|
||||
((count uint32 :offset-assert 0)
|
||||
(mode timer-mode :offset 16)
|
||||
(comp uint32 :offset 32)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x24
|
||||
:flag-assert #x900000024
|
||||
)
|
||||
|
||||
;; definition for method 3 of type timer-bank
|
||||
(defmethod inspect timer-bank ((obj timer-bank))
|
||||
(format #t "[~8x] ~A~%" obj 'timer-bank)
|
||||
(format #t "~Tcount: #x~X~%" (-> obj count))
|
||||
(format #t "~Tmode: #x~X~%" (-> obj mode))
|
||||
(format #t "~Tcomp: #x~X~%" (-> obj comp))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type timer-hold-bank
|
||||
(deftype timer-hold-bank (timer-bank)
|
||||
((hold uint32 :offset 48)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x34
|
||||
:flag-assert #x900000034
|
||||
)
|
||||
|
||||
;; definition for method 3 of type timer-hold-bank
|
||||
(defmethod inspect timer-hold-bank ((obj timer-hold-bank))
|
||||
(format #t "[~8x] ~A~%" obj 'timer-hold-bank)
|
||||
(format #t "~Tcount: #x~X~%" (-> obj count))
|
||||
(format #t "~Tmode: #x~X~%" (-> obj mode))
|
||||
(format #t "~Tcomp: #x~X~%" (-> obj comp))
|
||||
(format #t "~Thold: #x~X~%" (-> obj hold))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type stopwatch
|
||||
(deftype stopwatch (basic)
|
||||
((prev-time-elapsed uint64 :offset-assert 8)
|
||||
(start-time uint64 :offset-assert 16)
|
||||
(begin-level int32 :offset-assert 24)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x1c
|
||||
:flag-assert #x90000001c
|
||||
)
|
||||
|
||||
;; definition for method 3 of type stopwatch
|
||||
(defmethod inspect stopwatch ((obj stopwatch))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tprev-time-elapsed: ~D~%" (-> obj prev-time-elapsed))
|
||||
(format #t "~Tstart-time: ~D~%" (-> obj start-time))
|
||||
(format #t "~Tbegin-level: ~D~%" (-> obj begin-level))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for symbol *ticks-per-frame*, type int
|
||||
(define *ticks-per-frame* 9765)
|
||||
|
||||
;; definition for function timer-init
|
||||
(defun timer-init ((arg0 timer-bank) (arg1 timer-mode))
|
||||
(set! (-> arg0 mode) arg1)
|
||||
(set! (-> arg0 count) (the-as uint 0))
|
||||
0
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(timer-init (the-as timer-bank #x10000800) (the-as timer-mode 130))
|
||||
|
||||
;; definition of type profile-frame
|
||||
(deftype profile-frame (structure)
|
||||
((name basic :offset-assert 0)
|
||||
(time-stamp uint32 :offset-assert 4)
|
||||
(color uint32 :offset-assert 8)
|
||||
(r uint8 :offset 8)
|
||||
(g uint8 :offset 9)
|
||||
(b uint8 :offset 10)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #xc
|
||||
:flag-assert #x90000000c
|
||||
)
|
||||
|
||||
;; definition for method 3 of type profile-frame
|
||||
;; INFO: this function exists in multiple non-identical object files
|
||||
(defmethod inspect profile-frame ((obj profile-frame))
|
||||
(format #t "[~8x] ~A~%" obj 'profile-frame)
|
||||
(format #t "~Tname: ~A~%" (-> obj name))
|
||||
(format #t "~Ttime-stamp: ~D~%" (-> obj time-stamp))
|
||||
(format #t "~Tcolor: ~D~%" (-> obj color))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for method 3 of type profile-frame
|
||||
;; INFO: this function exists in multiple non-identical object files
|
||||
(defmethod inspect profile-frame ((obj profile-frame))
|
||||
(format #t "[~8x] profile-frame~%" obj)
|
||||
(format #t "~Tname: ~A~%" (-> obj name))
|
||||
(format #t "~Ttime-stamp: ~D~%" (-> obj time-stamp))
|
||||
(format
|
||||
#t
|
||||
"~Tcolor: ~D ~D ~D~%"
|
||||
(shr (shl (-> obj color) 56) 56)
|
||||
(shr (shl (-> obj color) 48) 56)
|
||||
(shr (shl (-> obj color) 40) 56)
|
||||
)
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type profile-bar
|
||||
(deftype profile-bar (basic)
|
||||
((profile-frame-count int32 :offset-assert 4)
|
||||
(cache-time uint64 :offset-assert 8)
|
||||
(data profile-frame 1024 :inline :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 14
|
||||
:size-assert #x4010
|
||||
:flag-assert #xe00004010
|
||||
(:methods
|
||||
(get-last-frame-time-stamp (profile-bar) uint 9)
|
||||
(dummy-10 () none 10)
|
||||
(dummy-11 () none 11)
|
||||
(dummy-12 () none 12)
|
||||
(dummy-13 () none 13)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 3 of type profile-bar
|
||||
(defmethod inspect profile-bar ((obj profile-bar))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tprofile-frame-count: ~D~%" (-> obj profile-frame-count))
|
||||
(format #t "~Tcache-time: ~D~%" (-> obj cache-time))
|
||||
(format #t "~Tdata[1024] @ #x~X~%" (-> obj data))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for method 9 of type profile-bar
|
||||
(defmethod get-last-frame-time-stamp profile-bar ((obj profile-bar))
|
||||
(-> obj data (+ (-> obj profile-frame-count) -2) time-stamp)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let ((v0-7 0))
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition for function timer-reset
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun timer-reset ((arg0 timer-bank))
|
||||
(.sync.l)
|
||||
(set! (-> arg0 count) (the-as uint 0))
|
||||
(.sync.l)
|
||||
(let ((v0-0 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function timer-count
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
|
||||
(defun timer-count ((arg0 timer-bank))
|
||||
(.sync.l)
|
||||
(let ((v0-0 (-> arg0 count)))
|
||||
(.sync.l)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for function disable-irq
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v0, Status]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mtc0 Status, v0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.p]
|
||||
(defun disable-irq ()
|
||||
(local-vars (v0-0 int))
|
||||
(let ((v1-0 (l.d L21)))
|
||||
(.mfc0 v0-0 Status)
|
||||
(let ((v0-1 (logand v0-0 (the-as int v1-0))))
|
||||
(.mtc0 Status v0-1)
|
||||
)
|
||||
)
|
||||
(.sync.p)
|
||||
(let ((v0-2 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function enable-irq
|
||||
;; INFO: Return type mismatch int vs none.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v0, Status]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mtc0 Status, v0]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [sync.p]
|
||||
(defun enable-irq ()
|
||||
(local-vars (v0-0 int))
|
||||
(.mfc0 v0-0 Status)
|
||||
(let ((v0-1 (logior v0-0 1)))
|
||||
(.mtc0 Status v0-1)
|
||||
)
|
||||
(.sync.p)
|
||||
(let ((v0-2 0))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function stopwatch-init
|
||||
(defun stopwatch-init ((arg0 stopwatch))
|
||||
(set! (-> arg0 begin-level) 0)
|
||||
(set! (-> arg0 prev-time-elapsed) (the-as uint 0))
|
||||
0
|
||||
)
|
||||
|
||||
;; definition for function stopwatch-reset
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
|
||||
(defun stopwatch-reset ((arg0 stopwatch))
|
||||
(local-vars (v1-3 int))
|
||||
(set! (-> arg0 prev-time-elapsed) (the-as uint 0))
|
||||
(when (> (-> arg0 begin-level) 0)
|
||||
(let ((v1-2 0))
|
||||
)
|
||||
(.mfc0 v1-3 Count)
|
||||
(set! (-> arg0 start-time) (the-as uint v1-3))
|
||||
)
|
||||
0
|
||||
)
|
||||
|
||||
;; definition for function stopwatch-start
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
|
||||
(defun stopwatch-start ((arg0 stopwatch))
|
||||
(local-vars (v1-4 int))
|
||||
(when (zero? (-> arg0 begin-level))
|
||||
(set! (-> arg0 begin-level) 1)
|
||||
(let ((v1-3 0))
|
||||
)
|
||||
(.mfc0 v1-4 Count)
|
||||
(set! (-> arg0 start-time) (the-as uint v1-4))
|
||||
)
|
||||
0
|
||||
)
|
||||
|
||||
;; definition for function stopwatch-stop
|
||||
;; INFO: Return type mismatch int vs uint.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfc0 a1, Count]
|
||||
(defun stopwatch-stop ((arg0 stopwatch))
|
||||
(local-vars (a1-0 int))
|
||||
(when (> (-> arg0 begin-level) 0)
|
||||
(set! (-> arg0 begin-level) 0)
|
||||
(let ((v1-2 0))
|
||||
)
|
||||
(.mfc0 a1-0 Count)
|
||||
(set!
|
||||
(-> arg0 prev-time-elapsed)
|
||||
(+
|
||||
(-> arg0 prev-time-elapsed)
|
||||
(the-as uint (- a1-0 (the-as int (-> arg0 start-time))))
|
||||
)
|
||||
)
|
||||
)
|
||||
(the-as uint 0)
|
||||
)
|
||||
|
||||
;; definition for function stopwatch-begin
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
|
||||
(defun stopwatch-begin ((arg0 stopwatch))
|
||||
(local-vars (v1-3 int))
|
||||
(when (zero? (-> arg0 begin-level))
|
||||
(let ((v1-2 0))
|
||||
)
|
||||
(.mfc0 v1-3 Count)
|
||||
(set! (-> arg0 start-time) (the-as uint v1-3))
|
||||
)
|
||||
(set! (-> arg0 begin-level) (+ (-> arg0 begin-level) 1))
|
||||
0
|
||||
)
|
||||
|
||||
;; definition for function stopwatch-end
|
||||
;; INFO: Return type mismatch int vs uint.
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfc0 a1, Count]
|
||||
(defun stopwatch-end ((arg0 stopwatch))
|
||||
(local-vars (a1-0 int))
|
||||
(set! (-> arg0 begin-level) (+ (-> arg0 begin-level) -1))
|
||||
(when (zero? (-> arg0 begin-level))
|
||||
(let ((v1-4 0))
|
||||
)
|
||||
(.mfc0 a1-0 Count)
|
||||
(set!
|
||||
(-> arg0 prev-time-elapsed)
|
||||
(+
|
||||
(-> arg0 prev-time-elapsed)
|
||||
(the-as uint (- a1-0 (the-as int (-> arg0 start-time))))
|
||||
)
|
||||
)
|
||||
)
|
||||
(the-as uint 0)
|
||||
)
|
||||
|
||||
;; definition for function stopwatch-elapsed-ticks
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
|
||||
(defun stopwatch-elapsed-ticks ((arg0 stopwatch))
|
||||
(local-vars (v1-3 int))
|
||||
(let ((v0-0 (-> arg0 prev-time-elapsed)))
|
||||
(when (> (-> arg0 begin-level) 0)
|
||||
(let ((v1-2 0))
|
||||
)
|
||||
(.mfc0 v1-3 Count)
|
||||
(+! v0-0 (the-as uint (- v1-3 (the-as int (-> arg0 start-time)))))
|
||||
)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for function stopwatch-elapsed-seconds
|
||||
(defun stopwatch-elapsed-seconds ((arg0 stopwatch))
|
||||
(let ((v1-0 (stopwatch-elapsed-ticks arg0)))
|
||||
(* 0.0000000033333334 (the float v1-0))
|
||||
)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition of type video-parms
|
||||
(deftype video-parms (structure)
|
||||
((set-video-mode basic :offset-assert 0)
|
||||
(reset-video-mode basic :offset-assert 4)
|
||||
(screen-sy int32 :offset-assert 8)
|
||||
(screen-hy int32 :offset-assert 12)
|
||||
(screen-miny int32 :offset-assert 16)
|
||||
(screen-maxy int32 :offset-assert 20)
|
||||
(screen-masky int32 :offset-assert 24)
|
||||
(display-dx int32 :offset-assert 28)
|
||||
(display-dy int32 :offset-assert 32)
|
||||
(screen-pages-high int32 :offset-assert 36)
|
||||
(_pad int64 :offset-assert 40)
|
||||
(relative-x-scale float :offset-assert 48)
|
||||
(relative-y-scale float :offset-assert 52)
|
||||
(_pad2 int64 :offset-assert 56)
|
||||
(relative-x-scale-reciprical float :offset-assert 64)
|
||||
(relative-y-scale-reciprical float :offset-assert 68)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x48
|
||||
:flag-assert #x900000048
|
||||
)
|
||||
|
||||
;; definition for method 3 of type video-parms
|
||||
(defmethod inspect video-parms ((obj video-parms))
|
||||
(format #t "[~8x] ~A~%" obj 'video-parms)
|
||||
(format #t "~Tset-video-mode: ~A~%" (-> obj set-video-mode))
|
||||
(format #t "~Treset-video-mode: ~A~%" (-> obj reset-video-mode))
|
||||
(format #t "~Tscreen-sy: ~D~%" (-> obj screen-sy))
|
||||
(format #t "~Tscreen-hy: ~D~%" (-> obj screen-hy))
|
||||
(format #t "~Tscreen-miny: ~D~%" (-> obj screen-miny))
|
||||
(format #t "~Tscreen-maxy: ~D~%" (-> obj screen-maxy))
|
||||
(format #t "~Tscreen-masky: ~D~%" (-> obj screen-masky))
|
||||
(format #t "~Tdisplay-dx: ~D~%" (-> obj display-dx))
|
||||
(format #t "~Tdisplay-dy: ~D~%" (-> obj display-dy))
|
||||
(format #t "~Tscreen-pages-high: ~D~%" (-> obj screen-pages-high))
|
||||
(format #t "~Trelative-x-scale: ~f~%" (-> obj relative-x-scale))
|
||||
(format #t "~Trelative-y-scale: ~f~%" (-> obj relative-y-scale))
|
||||
(format
|
||||
#t
|
||||
"~Trelative-x-scale-reciprical: ~f~%"
|
||||
(-> obj relative-x-scale-reciprical)
|
||||
)
|
||||
(format
|
||||
#t
|
||||
"~Trelative-y-scale-reciprical: ~f~%"
|
||||
(-> obj relative-y-scale-reciprical)
|
||||
)
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for symbol *video-parms*, type video-parms
|
||||
(define
|
||||
*video-parms*
|
||||
(new 'static 'video-parms
|
||||
:set-video-mode #f
|
||||
:reset-video-mode #f
|
||||
:screen-sy #xe0
|
||||
:screen-hy #x70
|
||||
:screen-miny #x720
|
||||
:screen-maxy #x8e0
|
||||
:screen-masky #xdf
|
||||
:display-dy 8
|
||||
:screen-pages-high 7
|
||||
:relative-x-scale 1.0
|
||||
:relative-y-scale 1.0
|
||||
:relative-x-scale-reciprical 1.0
|
||||
)
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let ((v0-1 0))
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition of type vif-stat
|
||||
(deftype vif-stat (uint32)
|
||||
((vps uint8 :offset 0 :size 2)
|
||||
(vew uint8 :offset 2 :size 1)
|
||||
(mrk uint8 :offset 6 :size 1)
|
||||
(vss uint8 :offset 8 :size 1)
|
||||
(vfs uint8 :offset 9 :size 1)
|
||||
(vis uint8 :offset 10 :size 1)
|
||||
(int uint8 :offset 11 :size 1)
|
||||
(er0 uint8 :offset 12 :size 1)
|
||||
(er1 uint8 :offset 13 :size 1)
|
||||
(fqc uint8 :offset 24 :size 4)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type vif-stat
|
||||
(defmethod inspect vif-stat ((obj vif-stat))
|
||||
(format #t "[~8x] ~A~%" obj 'vif-stat)
|
||||
(format #t "~Tvps: ~D~%" (-> obj vps))
|
||||
(format #t "~Tvew: ~D~%" (-> obj vew))
|
||||
(format #t "~Tmrk: ~D~%" (-> obj mrk))
|
||||
(format #t "~Tvss: ~D~%" (-> obj vss))
|
||||
(format #t "~Tvfs: ~D~%" (-> obj vfs))
|
||||
(format #t "~Tvis: ~D~%" (-> obj vis))
|
||||
(format #t "~Tint: ~D~%" (-> obj int))
|
||||
(format #t "~Ter0: ~D~%" (-> obj er0))
|
||||
(format #t "~Ter1: ~D~%" (-> obj er1))
|
||||
(format #t "~Tfqc: ~D~%" (-> obj fqc))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type vif-fbrst
|
||||
(deftype vif-fbrst (uint32)
|
||||
((rst uint8 :offset 0 :size 1)
|
||||
(fbk uint8 :offset 1 :size 1)
|
||||
(stp uint8 :offset 2 :size 1)
|
||||
(stc uint8 :offset 3 :size 1)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition of type vif-err
|
||||
(deftype vif-err (uint32)
|
||||
((mii uint8 :offset 0 :size 1)
|
||||
(me0 uint8 :offset 1 :size 1)
|
||||
(me1 uint8 :offset 2 :size 1)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition of type vif-bank
|
||||
(deftype vif-bank (structure)
|
||||
((stat uint32 :offset-assert 0)
|
||||
(fbrst uint32 :offset 16)
|
||||
(err vif-err :offset 32)
|
||||
(mark uint32 :offset 48)
|
||||
(cycle uint32 :offset 64)
|
||||
(mode uint32 :offset 80)
|
||||
(num uint32 :offset 96)
|
||||
(mask uint32 :offset 112)
|
||||
(code uint32 :offset 128)
|
||||
(itops uint32 :offset 144)
|
||||
(base uint32 :offset 160)
|
||||
(offset uint32 :offset 176)
|
||||
(tops uint32 :offset 192)
|
||||
(itop uint32 :offset 208)
|
||||
(top uint32 :offset 224)
|
||||
(r0 uint32 :offset 256)
|
||||
(r1 uint32 :offset 272)
|
||||
(r2 uint32 :offset 288)
|
||||
(r3 uint32 :offset 304)
|
||||
(c0 uint32 :offset 320)
|
||||
(c1 uint32 :offset 336)
|
||||
(c2 uint32 :offset 352)
|
||||
(c3 uint32 :offset 368)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x174
|
||||
:flag-assert #x900000174
|
||||
)
|
||||
|
||||
;; definition for method 3 of type vif-bank
|
||||
(defmethod inspect vif-bank ((obj vif-bank))
|
||||
(format #t "[~8x] ~A~%" obj 'vif-bank)
|
||||
(format #t "~Tstat: #x~X~%" (-> obj stat))
|
||||
(format #t "~Tfbrst: #x~X~%" (-> obj fbrst))
|
||||
(format #t "~Terr: #x~X~%" (-> obj err))
|
||||
(format #t "~Tmark: #x~X~%" (-> obj mark))
|
||||
(format #t "~Tcycle: #x~X~%" (-> obj cycle))
|
||||
(format #t "~Tmode: #x~X~%" (-> obj mode))
|
||||
(format #t "~Tnum: #x~X~%" (-> obj num))
|
||||
(format #t "~Tmask: #x~X~%" (-> obj mask))
|
||||
(format #t "~Tcode: #x~X~%" (-> obj code))
|
||||
(format #t "~Titops: #x~X~%" (-> obj itops))
|
||||
(format #t "~Tbase: #x~X~%" (-> obj base))
|
||||
(format #t "~Toffset: #x~X~%" (-> obj offset))
|
||||
(format #t "~Ttops: #x~X~%" (-> obj tops))
|
||||
(format #t "~Titop: #x~X~%" (-> obj itop))
|
||||
(format #t "~Ttop: #x~X~%" (-> obj top))
|
||||
(format #t "~Tr0: #x~X~%" (-> obj r0))
|
||||
(format #t "~Tr1: #x~X~%" (-> obj r1))
|
||||
(format #t "~Tr2: #x~X~%" (-> obj r2))
|
||||
(format #t "~Tr3: #x~X~%" (-> obj r3))
|
||||
(format #t "~Tc0: #x~X~%" (-> obj c0))
|
||||
(format #t "~Tc1: #x~X~%" (-> obj c1))
|
||||
(format #t "~Tc2: #x~X~%" (-> obj c2))
|
||||
(format #t "~Tc3: #x~X~%" (-> obj c3))
|
||||
obj
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let ((v0-4 0))
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; definition for symbol *vu1-enable-user-menu*, type int
|
||||
(define *vu1-enable-user-menu* #x1ffff8)
|
||||
|
||||
;; definition for symbol *vu1-enable-user*, type int
|
||||
(define *vu1-enable-user* 0)
|
||||
|
||||
;; definition of type dma-foreground-sink
|
||||
(deftype dma-foreground-sink (basic)
|
||||
((bucket int32 :offset-assert 4)
|
||||
(foreground-texture-page int8 :offset-assert 8)
|
||||
(foreground-texture-level int8 :offset-assert 9)
|
||||
(foreground-output-bucket int8 :offset-assert 10)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #xb
|
||||
:flag-assert #x90000000b
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-foreground-sink
|
||||
(defmethod inspect dma-foreground-sink ((obj dma-foreground-sink))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tbucket: ~D~%" (-> obj bucket))
|
||||
(format #t "~Tforeground-texture-page: ~D~%" (-> obj foreground-texture-page))
|
||||
(format
|
||||
#t
|
||||
"~Tforeground-texture-level: ~D~%"
|
||||
(-> obj foreground-texture-level)
|
||||
)
|
||||
(format
|
||||
#t
|
||||
"~Tforeground-output-bucket: ~D~%"
|
||||
(-> obj foreground-output-bucket)
|
||||
)
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type generic-bucket-state
|
||||
(deftype generic-bucket-state (structure)
|
||||
((gifbuf-adr uint32 :offset-assert 0)
|
||||
(inbuf-adr uint32 :offset-assert 4)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
;; definition for method 3 of type generic-bucket-state
|
||||
(defmethod inspect generic-bucket-state ((obj generic-bucket-state))
|
||||
(format #t "[~8x] ~A~%" obj 'generic-bucket-state)
|
||||
(format #t "~Tgifbuf-adr: ~D~%" (-> obj gifbuf-adr))
|
||||
(format #t "~Tinbuf-adr: ~D~%" (-> obj inbuf-adr))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type generic-dma-foreground-sink
|
||||
(deftype generic-dma-foreground-sink (dma-foreground-sink)
|
||||
((state generic-bucket-state :inline :offset-assert 12)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x14
|
||||
:flag-assert #x900000014
|
||||
)
|
||||
|
||||
;; definition for method 3 of type generic-dma-foreground-sink
|
||||
(defmethod
|
||||
inspect
|
||||
generic-dma-foreground-sink
|
||||
((obj generic-dma-foreground-sink))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tbucket: ~D~%" (-> obj bucket))
|
||||
(format #t "~Tforeground-texture-page: ~D~%" (-> obj foreground-texture-page))
|
||||
(format
|
||||
#t
|
||||
"~Tforeground-texture-level: ~D~%"
|
||||
(-> obj foreground-texture-level)
|
||||
)
|
||||
(format
|
||||
#t
|
||||
"~Tforeground-output-bucket: ~D~%"
|
||||
(-> obj foreground-output-bucket)
|
||||
)
|
||||
(format #t "~Tstate: #<generic-bucket-state @ #x~X>~%" (-> obj state))
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition of type dma-foreground-sink-group
|
||||
(deftype dma-foreground-sink-group (basic)
|
||||
((sink dma-foreground-sink 3 :offset-assert 4)
|
||||
(merc-sink dma-foreground-sink :offset 4)
|
||||
(generic-sink generic-dma-foreground-sink :offset 8)
|
||||
(level basic :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x14
|
||||
:flag-assert #x900000014
|
||||
)
|
||||
|
||||
;; definition for method 3 of type dma-foreground-sink-group
|
||||
(defmethod inspect dma-foreground-sink-group ((obj dma-foreground-sink-group))
|
||||
(format #t "[~8x] ~A~%" obj (-> obj type))
|
||||
(format #t "~Tsink[3] @ #x~X~%" (-> obj sink))
|
||||
(format #t "~Tmerc-sink: ~A~%" (-> obj sink 0))
|
||||
(format #t "~Tgeneric-sink: ~A~%" (-> obj sink 1))
|
||||
(format #t "~Tlevel: ~A~%" (-> obj level))
|
||||
obj
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(let ((v0-4 0))
|
||||
)
|
||||
|
||||
;; failed to figure out what this is:
|
||||
(none)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -325,4 +325,467 @@ TEST_F(FormRegressionTest, IterateProcessTree) {
|
||||
" s4-0\n"
|
||||
" )";
|
||||
test_with_stack_vars(func, type, expected, "[]");
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, InspectVifStatBitfield) {
|
||||
std::string func =
|
||||
"sll r0, r0, 0\n"
|
||||
|
||||
" daddiu sp, sp, -32\n"
|
||||
" sd ra, 0(sp)\n"
|
||||
" sd fp, 8(sp)\n"
|
||||
" or fp, t9, r0\n"
|
||||
" sq gp, 16(sp)\n"
|
||||
|
||||
" or gp, a0, r0\n"
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L37\n"
|
||||
" or a2, gp, r0\n"
|
||||
" daddiu a3, s7, vif-stat\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L36\n"
|
||||
" dsll32 v1, gp, 30\n"
|
||||
" dsrl32 a2, v1, 30\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L35\n"
|
||||
" dsll32 v1, gp, 29\n"
|
||||
" dsrl32 a2, v1, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L34\n"
|
||||
" dsll32 v1, gp, 25\n"
|
||||
" dsrl32 a2, v1, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L33\n"
|
||||
" dsll32 v1, gp, 23\n"
|
||||
" dsrl32 a2, v1, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L32\n"
|
||||
" dsll32 v1, gp, 22\n"
|
||||
" dsrl32 a2, v1, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L31\n"
|
||||
" dsll32 v1, gp, 21\n"
|
||||
" dsrl32 a2, v1, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L30\n"
|
||||
" dsll32 v1, gp, 20\n"
|
||||
" dsrl32 a2, v1, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L29\n"
|
||||
" dsll32 v1, gp, 19\n"
|
||||
" dsrl32 a2, v1, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L28\n"
|
||||
" dsll32 v1, gp, 18\n"
|
||||
" dsrl32 a2, v1, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L27\n"
|
||||
" dsll32 v1, gp, 4\n"
|
||||
" dsrl32 a2, v1, 28\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" or v0, gp, r0\n"
|
||||
" ld ra, 0(sp)\n"
|
||||
" ld fp, 8(sp)\n"
|
||||
" lq gp, 16(sp)\n"
|
||||
" jr ra\n"
|
||||
" daddiu sp, sp, 32";
|
||||
std::string type = "(function vif-stat vif-stat)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (format #t \"[~8x] ~A~%\" arg0 (quote vif-stat))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 vps))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 vew))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 mrk))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 vss))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 vfs))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 vis))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 int))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 er0))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 er1))\n"
|
||||
" (format #t \"~T ~D~%\" (-> arg0 fqc))\n"
|
||||
" arg0\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected, false, "",
|
||||
{{"L37", "[~8x] ~A~%"},
|
||||
{"L36", "~T ~D~%"},
|
||||
{"L35", "~T ~D~%"},
|
||||
{"L34", "~T ~D~%"},
|
||||
{"L33", "~T ~D~%"},
|
||||
{"L32", "~T ~D~%"},
|
||||
{"L31", "~T ~D~%"},
|
||||
{"L30", "~T ~D~%"},
|
||||
{"L29", "~T ~D~%"},
|
||||
{"L28", "~T ~D~%"},
|
||||
{"L27", "~T ~D~%"}});
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, InspectHandleBitfield) {
|
||||
std::string func =
|
||||
"sll r0, r0, 0\n"
|
||||
" daddiu sp, sp, -32\n"
|
||||
" sd ra, 0(sp)\n"
|
||||
" sd fp, 8(sp)\n"
|
||||
" or fp, t9, r0\n"
|
||||
" sq gp, 16(sp)\n"
|
||||
|
||||
" or gp, a0, r0\n"
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L79\n"
|
||||
" or a2, gp, r0\n"
|
||||
" daddiu a3, s7, handle\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L32\n"
|
||||
" dsll32 v1, gp, 0\n"
|
||||
" dsrl32 a2, v1, 0\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L31\n"
|
||||
" dsra32 a2, gp, 0\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" or v0, gp, r0\n"
|
||||
" ld ra, 0(sp)\n"
|
||||
" ld fp, 8(sp)\n"
|
||||
" lq gp, 16(sp)\n"
|
||||
" jr ra\n"
|
||||
" daddiu sp, sp, 32";
|
||||
std::string type = "(function handle handle)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (format #t \"[~8x] ~A~%\" arg0 (quote handle))\n"
|
||||
" (format #t \"~Tprocess: #x~X~%\" (-> arg0 process))\n"
|
||||
" (format #t \"~Tpid: ~D~%\" (-> arg0 pid))\n"
|
||||
" arg0\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected, false, "",
|
||||
{{"L79", "[~8x] ~A~%"}, {"L32", "~Tprocess: #x~X~%"}, {"L31", "~Tpid: ~D~%"}});
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, InspectDmaTagBitfield) {
|
||||
std::string func =
|
||||
"sll r0, r0, 0\n"
|
||||
" daddiu sp, sp, -32\n"
|
||||
" sd ra, 0(sp)\n"
|
||||
" sd fp, 8(sp)\n"
|
||||
" or fp, t9, r0\n"
|
||||
" sq gp, 16(sp)\n"
|
||||
|
||||
" or gp, a0, r0\n"
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L65\n"
|
||||
" or a2, gp, r0\n"
|
||||
" daddiu a3, s7, dma-tag\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L37\n"
|
||||
" dsll32 v1, gp, 16\n"
|
||||
" dsrl32 a2, v1, 16\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L36\n"
|
||||
" dsll32 v1, gp, 4\n"
|
||||
" dsrl32 a2, v1, 30\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L35\n"
|
||||
" dsll32 v1, gp, 1\n"
|
||||
" dsrl32 a2, v1, 29\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L34\n"
|
||||
" srl a2, gp, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L33\n"
|
||||
" dsll v1, gp, 1\n"
|
||||
" dsrl32 a2, v1, 1\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, format(s7)\n"
|
||||
" daddiu a0, s7, #t\n"
|
||||
" daddiu a1, fp, L32\n"
|
||||
" dsrl32 a2, gp, 31\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" or v0, gp, r0\n"
|
||||
" ld ra, 0(sp)\n"
|
||||
" ld fp, 8(sp)\n"
|
||||
" lq gp, 16(sp)\n"
|
||||
" jr ra\n"
|
||||
" daddiu sp, sp, 32";
|
||||
std::string type = "(function dma-tag dma-tag)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (format #t \"[~8x] ~A~%\" arg0 (quote dma-tag))\n"
|
||||
" (format #t \"~Ta: ~D~%\" (-> arg0 qwc))\n"
|
||||
" (format #t \"~Ta: ~D~%\" (-> arg0 pce))\n"
|
||||
" (format #t \"~Ta: ~D~%\" (-> arg0 id))\n"
|
||||
" (format #t \"~Ta: ~D~%\" (-> arg0 irq))\n"
|
||||
" (format #t \"~Ta: ~D~%\" (-> arg0 addr))\n"
|
||||
" (format #t \"~Ta: ~D~%\" (-> arg0 spr))\n"
|
||||
" arg0\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected, false, "",
|
||||
{
|
||||
{"L65", "[~8x] ~A~%"},
|
||||
{"L37", "~Ta: ~D~%"},
|
||||
{"L36", "~Ta: ~D~%"},
|
||||
{"L35", "~Ta: ~D~%"},
|
||||
{"L34", "~Ta: ~D~%"},
|
||||
{"L33", "~Ta: ~D~%"},
|
||||
{"L32", "~Ta: ~D~%"},
|
||||
});
|
||||
}
|
||||
|
||||
// Tests nonzero-check on bitfield
|
||||
TEST_F(FormRegressionTest, DmaSyncCrash) {
|
||||
std::string func =
|
||||
"sll r0, r0, 0\n"
|
||||
"L46:\n"
|
||||
" lui v1, 76\n"
|
||||
" ori v1, v1, 19264\n"
|
||||
" beq r0, r0, L49\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L47:\n"
|
||||
" bne v1, r0, L48\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" sd r0, 2(r0)\n"
|
||||
" or a1, r0, r0\n"
|
||||
" beq r0, r0, L49\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L48:\n"
|
||||
" daddiu v1, v1, -1\n"
|
||||
" or a1, v1, r0\n"
|
||||
|
||||
"L49:\n"
|
||||
" lwu a1, 0(a0)\n"
|
||||
" andi a1, a1, 256\n"
|
||||
" bne a1, r0, L47\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" or v1, s7, r0\n"
|
||||
" or v0, r0, r0\n"
|
||||
" jr ra\n"
|
||||
" daddu sp, sp, r0";
|
||||
std::string type = "(function dma-bank int)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (let ((v1-0 #x4c4b40))\n"
|
||||
" (while (nonzero? (-> arg0 chcr str))\n"
|
||||
" (cond\n"
|
||||
" ((zero? v1-0)\n"
|
||||
" (crash!)\n"
|
||||
" (let ((a1-0 0))\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (else\n"
|
||||
" (+! v1-0 -1)\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" 0\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected);
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, DmaSend) {
|
||||
std::string func =
|
||||
"sll r0, r0, 0\n"
|
||||
" daddiu sp, sp, -64\n"
|
||||
" sd ra, 0(sp)\n"
|
||||
" sq s4, 16(sp)\n"
|
||||
" sq s5, 32(sp)\n"
|
||||
" sq gp, 48(sp)\n"
|
||||
|
||||
" or gp, a0, r0\n"
|
||||
" or s4, a1, r0\n"
|
||||
" or s5, a2, r0\n"
|
||||
" lw t9, dma-sync(s7)\n"
|
||||
" or a0, gp, r0\n"
|
||||
" addiu a1, r0, 0\n"
|
||||
" addiu a2, r0, 0\n"
|
||||
" jalr ra, t9\n"
|
||||
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, flush-cache(s7)\n"
|
||||
" addiu a0, r0, 0\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" sync.l\n"
|
||||
" lui v1, 4095\n"
|
||||
" ori v1, v1, 65535\n"
|
||||
" and v1, v1, s4\n"
|
||||
" lui a0, 28672\n"
|
||||
" lui a1, 28672\n"
|
||||
" and a1, a1, s4\n"
|
||||
" bne a1, a0, L44\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
" ori a0, r0, 32768\n"
|
||||
" dsll a0, a0, 16\n"
|
||||
" beq r0, r0, L45\n"
|
||||
" sll r0, r0, 0\n"
|
||||
|
||||
"L44:\n"
|
||||
" addiu a0, r0, 0\n"
|
||||
|
||||
"L45:\n"
|
||||
" or v1, v1, a0\n"
|
||||
" sw v1, 16(gp)\n"
|
||||
" sw s5, 32(gp)\n"
|
||||
" sync.l\n"
|
||||
" addiu v1, r0, 256\n"
|
||||
" sw v1, 0(gp)\n"
|
||||
" sync.l\n"
|
||||
" or v0, r0, r0\n"
|
||||
" ld ra, 0(sp)\n"
|
||||
" lq gp, 48(sp)\n"
|
||||
" lq s5, 32(sp)\n"
|
||||
" lq s4, 16(sp)\n"
|
||||
" jr ra\n"
|
||||
" daddiu sp, sp, 64";
|
||||
std::string type = "(function dma-bank uint uint int)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (dma-sync (the-as pointer arg0) 0 0)\n"
|
||||
" (flush-cache 0)\n"
|
||||
" (.sync.l)\n"
|
||||
" (set!\n"
|
||||
" (-> arg0 madr)\n"
|
||||
" (logior\n"
|
||||
" (logand #xfffffff (the-as int arg1))\n"
|
||||
" (the-as uint (if (= (logand #x70000000 (the-as int arg1)) #x70000000)\n"
|
||||
" (shl #x8000 16)\n" // note: maybe this should be #x80000000? Not sure.
|
||||
" 0\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" )\n"
|
||||
" (set! (-> arg0 qwc) arg2)\n"
|
||||
" (.sync.l)\n"
|
||||
" (set! (-> arg0 chcr) (new 'static 'dma-chcr :str 1))\n"
|
||||
" (.sync.l)\n"
|
||||
" 0\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected);
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, DmaInitialize) {
|
||||
std::string func =
|
||||
"sll r0, r0, 0\n"
|
||||
" lui v1, 4096\n"
|
||||
" ori v1, v1, 14336\n"
|
||||
" lwu v1, 32(v1)\n"
|
||||
" addiu a0, r0, -3\n"
|
||||
" and v1, v1, a0\n"
|
||||
" ori v1, v1, 2\n"
|
||||
" lui a0, 4096\n"
|
||||
" ori a0, a0, 14336\n"
|
||||
" sw v1, 32(a0)\n"
|
||||
" lui v1, 4096\n"
|
||||
" ori v1, v1, 15360\n"
|
||||
" lwu v1, 32(v1)\n"
|
||||
" addiu a0, r0, -3\n"
|
||||
" and v1, v1, a0\n"
|
||||
" ori v1, v1, 2\n"
|
||||
" lui a0, 4096\n"
|
||||
" ori a0, a0, 15360\n"
|
||||
" sw v1, 32(a0)\n"
|
||||
" or v0, r0, r0\n"
|
||||
" jr ra\n"
|
||||
" daddu sp, sp, r0";
|
||||
std::string type = "(function int)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (set! (-> (the-as vif-bank #x10003800) err me0) 1)\n"
|
||||
" (set! (-> (the-as vif-bank #x10003c00) err me0) 1)\n"
|
||||
" 0\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected, false, "", {},
|
||||
"[[1, \"v1\", \"vif-bank\"], [8, \"v1\", \"vif-bank\"], [6, \"a0\", "
|
||||
"\"vif-bank\"], [13, \"a0\", \"vif-bank\"]]");
|
||||
}
|
||||
@@ -15,6 +15,8 @@ const std::unordered_set<std::string> g_object_files_to_decompile = {
|
||||
/*"pskernel",*/ "gstring", "dgo-h", "gstate", "types-h", "vu1-macros", "math", "vector-h",
|
||||
"bounding-box-h", "matrix-h", "quaternion-h", "euler-h", "transform-h", "geometry-h",
|
||||
"trigonometry-h", /* transformq-h */ "matrix", "transform", "quaternion",
|
||||
"euler", /* geometry, trigonometry, */
|
||||
"gsound-h", "timer-h", "timer", "vif-h", "dma-h", "video-h", "vu1-user-h", "dma",
|
||||
/* gap */
|
||||
"bounding-box",
|
||||
/* gap */
|
||||
@@ -27,9 +29,9 @@ const std::vector<std::string> g_object_files_to_check_against_reference = {
|
||||
"math", "vector-h", "bounding-box-h", "matrix-h", "quaternion-h", "euler-h", "transform-h",
|
||||
"geometry-h", "trigonometry-h",
|
||||
/* transformq-h, */
|
||||
"matrix", "transform", "quaternion",
|
||||
/* gap */
|
||||
"bounding-box",
|
||||
"matrix", "transform", "quaternion", "euler", /* geometry, trigonometry */
|
||||
"gsound-h", "timer-h", /* timer, */ "vif-h", "dma-h", "video-h", "vu1-user-h", "dma",
|
||||
/* gap */ "bounding-box",
|
||||
/* gap */
|
||||
"sync-info-h", "sync-info"};
|
||||
|
||||
@@ -62,6 +64,11 @@ const std::unordered_set<std::string> expected_skip_in_decompiler = {
|
||||
// matrix
|
||||
"(method 9 matrix)", // handwritten asm loop
|
||||
"matrix-axis-sin-cos!", "matrix-axis-sin-cos-vu!",
|
||||
// dma-h
|
||||
"dma-count-until-done", // dma asm loop
|
||||
"dma-sync-with-count", "dma-send-no-scratch", "dma-sync-fast",
|
||||
// dma
|
||||
"symlink2", "symlink3", "dma-sync-hang", // handwritten asm
|
||||
// sync-info
|
||||
"(method 15 sync-info)", // needs *res-static-buf*
|
||||
"(method 15 sync-info-eased)", // needs *res-static-buf*
|
||||
@@ -106,11 +113,12 @@ const std::unordered_set<std::string> skip_in_compiling = {
|
||||
"matrix-with-scale->quaternion", // fpu acc
|
||||
"quaternion-delta-y", // fpu acc
|
||||
|
||||
"(method 3 profile-frame)", // double definition.
|
||||
|
||||
// sync-info
|
||||
"(method 15 sync-info)", // needs display stuff first
|
||||
"(method 15 sync-info-eased)", // needs display stuff first
|
||||
"(method 15 sync-info-paused)", // needs display stuff first
|
||||
|
||||
};
|
||||
|
||||
// default location for the data. It can be changed with a command line argument.
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/util/FileUtil.h"
|
||||
#include "common/util/Trie.h"
|
||||
#include "common/util/BitUtils.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/all_jak1_symbols.h"
|
||||
#include "common/util/json_util.h"
|
||||
#include "common/util/Range.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "third-party/fmt/core.h"
|
||||
|
||||
TEST(CommonUtil, get_file_path) {
|
||||
std::vector<std::string> test = {"cabbage", "banana", "apple"};
|
||||
@@ -77,4 +80,18 @@ TEST(CommonUtil, RangeIterator) {
|
||||
EXPECT_FALSE(Range<int>(3, 4).empty());
|
||||
EXPECT_EQ(1, Range<int>(3, 4).size());
|
||||
EXPECT_EQ(4, Range<int>(4, 8).size());
|
||||
}
|
||||
|
||||
TEST(CommonUtil, BitRange) {
|
||||
for (int x : {0, 0b1001, 0b1010, 0b01110001, 0b000100110}) {
|
||||
EXPECT_EQ(get_bit_range(x), std::nullopt); // invalids
|
||||
}
|
||||
|
||||
EXPECT_EQ(get_bit_range(0b1), Range<int>(0, 1));
|
||||
EXPECT_EQ(get_bit_range(0b10), Range<int>(1, 2));
|
||||
EXPECT_EQ(get_bit_range(0b11), Range<int>(0, 2));
|
||||
EXPECT_EQ(get_bit_range(0b110), Range<int>(1, 3));
|
||||
EXPECT_EQ(get_bit_range(UINT64_MAX), Range<int>(0, 64));
|
||||
EXPECT_EQ(get_bit_range(UINT64_MAX - 1), Range<int>(1, 64));
|
||||
EXPECT_EQ(get_bit_range(UINT64_MAX / 2), Range<int>(0, 63));
|
||||
}
|
||||
Reference in New Issue
Block a user