Skip to content

Instantly share code, notes, and snippets.

View yupferris's full-sized avatar

Jake Taylor yupferris

View GitHub Profile
@yupferris
yupferris / vf-notes.asm
Created February 12, 2017 13:03
Some Vertical Force reverse-engineering notes
- Lots of things seem to be indexed with r4; looks like it's always 0x05008000
- This is consistent with the "global data pointer" info in the tech scroll
- Looks like the offset into this mem is always negative
- Known globals (as negative offsets from r4):
-1402 (0x05007a86) - Effective OBJ group 3 ptr
Routine that hits obj group ptr's (occurs once per frame)
- r6 = data pointer. Appears to be 0x05007a80 every time (I believe this is only called from the code below).
- Looks like this just copies the 8 bytes starting at r6 into the OBJ group ptr reg's
@yupferris
yupferris / tennis.rs
Created February 23, 2017 21:08
You know the drill
use std::io::{self, Read};
use std::fs::File;
use std::path::Path;
fn main() {
let rom_file_name = "C:\\msys64\\home\\ferris\\dev\\projects\\vb-rs-corpus\\Mario's Tennis (Japan, USA).vb";
let buf = load(rom_file_name).unwrap();
let src = 0xfff9fb4c;
let dst = 0x00078000;
@yupferris
yupferris / pinball.rs
Last active February 25, 2017 19:59
Sample extraction for Galactic Pinball
use std::io::{self, Write, Read, BufWriter};
use std::fs::File;
use std::path::Path;
const NUM_CHANNELS: usize = 1;
const BITS_PER_SAMPLE: usize = 16;
fn main() {
let rom_file_name = "C:\\msys64\\home\\ferris\\dev\\projects\\vb-rs-corpus\\Galactic Pinball (Japan, USA).vb";
let buf = load(rom_file_name).unwrap();
@yupferris
yupferris / tesoft.asm
Created March 2, 2017 20:35
Sample playback routine info for T&E soft logo in Red Alarm
// Super high-level playroutine overview:
// Timer reload set to 0x0004
// Timer int fires every 120us (sample rate of ~8333.3hz)
// Store 0x15 in timer control (small interval, zero interrupt disable, clear zero status, timer enable)
// Output volumes to VOICE_1_VOLUME - VOICE_5_VOLUME
// Store 0x19 in timer control (small interval, zero interrupt enable, timer enable)
* 0xfffffe10 7c44 add 28, r3
0xfffffe12 23dc0000 st.w r1, 0[r3]
0xfffffe16 20bc0207 movhi 0x702, r0, r1
@yupferris
yupferris / bowling.asm
Last active March 9, 2017 21:00
Virtual Bowling sample playback routine reversing notes
// Super high-level playroutine overview:
// Timer reload set to 12, 13, 5 (depending on sample)
// Timer int fires every ??us (sample rate of ??hz)
// Store 0x1d in timer control (small interval, zero interrupt enable, clear zero status, timer enable)
// Output volume to VOICE_1_ENVELOPE_DATA
// Sample value -> register value lookup table:
0xffffd258 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0
// Sample playback routine (only thing the timer is used for in this game)
@yupferris
yupferris / stuff.rs
Created June 25, 2017 19:29
wavy stuff
extern crate minifb;
extern crate time;
use minifb::{Key, Scale, WindowOptions, Window};
use std::f64::consts::PI;
fn circle(x: f64, y: f64, x_offset: f64, y_offset: f64, rad: f64) -> bool {
let x_distance = x - x_offset;
let y_distance = y - y_offset;
@yupferris
yupferris / vic.txt
Created September 10, 2017 20:09
VIC pseudocode (not necessarily accurate/rigorous, but useful enough to explain stuff)
// Sometime outside of display area..
VCBASE := 0
VIDEO_COLOR_BUFFER := 0
for RASTER in 0..312 {
for line_cycle in 0..63 {
badline_condition := (RASTER & 0x07) == (YSCROLL & 0x07)
if (badline_condition) {
MODE = MODE_DISPLAY
}
@yupferris
yupferris / ends_with_case_insensitive.rs
Last active November 4, 2017 22:17
ffs windows, ruining my file watching with your case-insensitivity..
// This is kindof a crazy way to compare paths, and in certain unicode corner cases will not be entirely correct,
// but it's a workaround for file name case insensitivity on Windows and should be good enough for most cases.
// The general idea (matching path component suffixes) mimicks Rust's Path::ends_with.
fn ends_with_case_insensitive(path: &PathBuf, suffix: &PathBuf) -> bool {
let path_comps = path.components().map(|x| String::from(x.as_os_str().to_string_lossy()).to_lowercase()).rev();
let suffix_comps = suffix.components().map(|x| String::from(x.as_os_str().to_string_lossy()).to_lowercase()).rev();
let matching_suffix_pairs = path_comps.zip(suffix_comps).filter(|&(ref x, ref y)| x == y);
matching_suffix_pairs.count() == suffix.components().count()
}
@yupferris
yupferris / mt.rs
Last active August 20, 2018 08:44
Mario's Tennis graphics decompression routine in Rust-like pseudo-code. Manual decompilation is a bitch. :)
fn decompress(mut src: *const u8, dst: *mut u8) {
// Skip first 2 bytes (they're always zero)
src += 2;
let original_dst = dst;
// Load bytes_left
let mut bytes_left = ((*src as i32) << 8) + 1;
src += 1;
bytes_left += *src as i32;
@yupferris
yupferris / pinball-sample-playback-notes.asm
Last active November 22, 2018 13:25
Galactic Pinball sample playback disassembly/notes
// Super high-level playroutine overview:
// Timer reload set to 0x0002
// Timer int fires every ~50us (no, that's not a typo)
// Store 0x00 in timer control (large interval, zero interrupt disable, timer disable)
// Store 0x19 in timer control (small interval, zero interrupt enable, timer enable)
// Output volume to VOICE_1_ENVELOPE_DATA and VOICE_2_ENVELOPE_DATA
// Data stream
// 0xXX where 0xXX != 0x0f => envelope data <- 0xXX << 4 (reload value = 0xXX & 0x0f; count down to 0)
// 0x0f 0xXX 0xYY where 0xXX != 0x0f => voice volume <- 0xXX; envelope data <- 0xYY << 4