ChanServ changed the topic of ##yamahasynths to: Channel dedicated to questions and discussion of Yamaha FM Synthesizer internals and corresponding REing. Discussion of synthesis methods similar to the Yamaha line of chips, Sound Blasters + clones, PCM chips like RF5C68, and CD theory of operation are also on-topic. Channel logs: https://freenode.irclog.whitequark.org/~h~yamahasynths
<kode54> I didn't even know that was a thing
<cr1901_modern> 10 minute bikeshed... choosing the project directory
<cr1901_modern> (historically I've separated vintage and modern stuff, but nowadays I throw everything into $HOME/src folder
<cr1901_modern> And since rsync isn't "mv"-aware I dare not touch the old projects unless I want to waste like 20GB of space for no good reason. Blargh.
<cr1901_modern> waste 20GB of space of backups*
<cr1901_modern> (that feels like low-hanging fruit patch for rsync?)
<whitequark> rsync --delete ?
andlabs has joined ##yamahasynths
<cr1901_modern> Does delete remove all hard links for the given file or just the hard link found in --compare-dest?
<cr1901_modern> Because if it only deletes one hard link, that doesn't help me
<cr1901_modern> --link-dest* sorry
<cr1901_modern> whitequark: I use this script https://github.com/laurent22/rsync-time-backup/blob/master/rsync_tmbackup.sh Each week it creates a new directory, using the previous most-recent directory as --link-dest
<cr1901_modern> if the files match, create a hard link to link-dest
<cr1901_modern> if they don't, copy the entire file to the hard disk. rsync w/ incremental backup essentially
<cr1901_modern> Current ghidra status... I uploaded genecyst.exe into Ghidra, opened the CodeBrowser, and I got a whole helluva lot of... nothing!
futarisIRCcloud has joined ##yamahasynths
<cr1901_modern> Oh that's because I have to right+click and select "open the default tool"
[JethroDawnfine] has quit [Quit: Bye]
<cr1901_modern> Cool, analyzing worked without crashing... looks reasonable.
* cr1901_modern does a search for the Adlib ports
<whitequark> wtf is this page
<cr1901_modern> A concentrated fragment of "the 90s".
<whitequark> excuse me but what the fuck
<cr1901_modern> I don't suggest viewing for long periods
<kode54> also links to troma dot com
<cr1901_modern> bahahahaha
<kode54> I see that doesn't appear to be a shock site any more
<cr1901_modern> That's the Toxic Avenger studio, right?
<cr1901_modern> And of course. of f***ing course it uses "out dx, al" for all but one I/O port access
<cr1901_modern> there goes static analysis being simple
<TD-Linux> uhh ghidra should be able to figure that out easily
<whitequark> yeah, binja can definitely figure it out
<cr1901_modern> it doesn't put the value of DX next to the instruction, even when DX is loaded with a memory address that Ghidra claims is read only
<whitequark> can you give me the binary
<whitequark> if binja can do it i can just give you my license
<whitequark> it doesn't really care how many "seats" are using it
<cr1901_modern> yea sure, hold on two secs
<TD-Linux> oh I see. it might not be displaying it in the disassembly view because it might not treat io space as an address space
<TD-Linux> the decompile window should do the right thing
<cr1901_modern> I'm looking for writes to 0388 and 0389
<cr1901_modern> the code itself is doing 32-bit loads to load EDX before doing "OUT DX, AL", so looking for the data 0388 and 0389 isn't working
andlabs has quit [Ping timeout: 245 seconds]
<whitequark> oh what the heck
<whitequark> binja now supports x86_16 out of the box
<whitequark> but that's fine, it's not like i wanted to maintain that plugin
<whitequark> but... it can't load 16-bit EXEs?
<whitequark> well carry on then
<whitequark> i'm not about to write an NE loader
<cr1901_modern> NE?
<cr1901_modern> this isn't a 16-bit EXE, per say... it uses DPMI
<cr1901_modern> so the 32-bit plugin should work?
<whitequark> isn't it NE and not PE?
<whitequark> i think binja only knows how to parse PE
<whitequark> oh wait
<cr1901_modern> It's MZ executable
<whitequark> right, I forgot the sequencing here
<whitequark> it can't do either NE or MZ
<cr1901_modern> Ahhh
<whitequark> it can only do COM because I taught it to
<cr1901_modern> haha
<cr1901_modern> well, I'm probably doing something wrong (tm)
<cr1901_modern> that's making this harder than it needs to be
<cr1901_modern> if I get truly desperate I'll fire up DOSBOX-debug and do dynamic analysis
<cr1901_modern> but that's a PITA
<TD-Linux> weird ghidra's MZ loader isn't kicking in for me
<cr1901_modern> I chose x86, 32-bit, system management mode
<cr1901_modern> The 16-bit loader won't load this binary
<TD-Linux> oh it's using some extender I suppose
<cr1901_modern> DOS4GW
<cr1901_modern> It was written "mostly in assembly with some C++"
<whitequark> cr1901_modern: do you have a single function you want to know things about?
<whitequark> if yes can you give me file offset?
<cr1901_modern> whitequark: not yet, I'll let you know when I do
<cr1901_modern> whitequark, actually try this one
<cr1901_modern> offset 0x00028320
<cr1901_modern> it should start with 53 51 88 d1 in hex
<whitequark> cr1901_modern: is that a 16-bit or 32-bit function?
<cr1901_modern> 32-bit
<cr1901_modern> all flow control is relative, and this is a relatively short function
<cr1901_modern> just want to confirm that it's loading DX from memory location 0x00004170
<cr1901_modern> err EDX*
<whitequark> yes
<whitequark> that's what it's doing
<cr1901_modern> well, ghidrah _claims_ at present nothing writes to 0x4170
<whitequark> cr1901_modern: https://imgur.com/a/3OvBjoG
<cr1901_modern> And it has the value 0x79180202
<whitequark> hmm
<cr1901_modern> what's at 0x202?
<cr1901_modern> (answer- nothing)
<cr1901_modern> the game port is officially at 0x201
<whitequark> that function confuses me
<whitequark> did they forget to turn on optimization?
<cr1901_modern> Good question, and I have no idea... why is there even a need to load EDX, when "DX" would've sufficed?
<cr1901_modern> okay this is completely wrong
<cr1901_modern> first off, there's no reason to _write_ to the game port
<whitequark> cr1901_modern: okay so, i defined a variable at 0x4170 as "const int32_t"
<whitequark> now binja shows it to me like this
<whitequark> see how it folded that add into %edx_2 ?
<whitequark> and propagated the constant
<whitequark> that's what i expected it to do
<whitequark> now it does choke on `out` which is a bit annoying, i'd expect it to lift that into an intrinsic
<cr1901_modern> ahhh that's cool
<cr1901_modern> and ghidra didn't do that; it doesn't know whether 0x4170 is actually constant or not. I suspect there's some code it missed where there's an actual write to 0x4170
<TD-Linux> cr1901_modern, the write is for triggering the 558 timer
<whitequark> cr1901_modern: I told binja explicitly that it's a constant
<TD-Linux> then you loop and count how long it takes for the bit to become 1
<whitequark> like, defined the type of that memory location as "const int32_t" instad of the default "int32_t"
<cr1901_modern> 558 timer on what?
<cr1901_modern> whitequark: Ahhh, right
<TD-Linux> on the game port
<cr1901_modern> boch's list of I/O ports sucks
<TD-Linux> it's le classic timer based adc
<cr1901_modern> right and I forgot about that
<cr1901_modern> I'm not perfect :P
<cr1901_modern> TD-Linux: The code bothers me because the game port address is hex 201, not 202
<TD-Linux> second game port?
<cr1901_modern> Is there such a thing? Hmmm
<ej5> it works at 0x202 fyi
<ej5> all the way up to 0x20F iirc
<TD-Linux> bochs says that some cards don't check the low bits there
<ej5> ok so the SB 1.0 checks 0x200-0x207 and decodes those as the joystick port
<ej5> looks like the IBM game card is picky and requires 0x201
<cr1901_modern> one cool thing about ghidra is that it can kinda "autodetect" a function's calling convention by examining which registers are used before being written to
<cr1901_modern> even if you move the value to another register b/c you intend to clobber it, ghidra will remember it was an input parameter
<cr1901_modern> http://ix.io/1Evq This is ghidra's decompilation
<cr1901_modern> svar2 has the value of "79180202h"
<whitequark> binja can do this too
<whitequark> see how it detected arg1 and arg2?
<whitequark> actually it's funny how similar these are
<cr1901_modern> whitequark: Yes I see it... that's cool!
<whitequark> can't wait for binja decompiler to something c-like
<whitequark> i hope they don't fuck it up by only including it in more expensive tiers
<Lord_Nightmare> i'm hoping very hard that the full source of ghidra gets pushed soon
<Lord_Nightmare> since there's no way to recompile it at the moment, though i believe the archive with the executables contains most of the 'missing' source as .zip files
<cr1901_modern> I really don't think that this function is game-port related, and that the initial value of the binary is a coincidence. It is very possible I don't have the base address set properly
<cr1901_modern> but I don't know enough about DPMI
<cr1901_modern> to know where that would get loaded
<cr1901_modern> Does DOS strip the MZ header when loading a binary or keep it?
<cr1901_modern> (yes for someone who writes DOS code for fun I don't actually know much about MZ)
<whitequark> The DS (data segment) register normally contains the same value as the CS (code segment) register and is not loaded with the actual segment address of the data segment when an EXE file is initialized; it is necessary for the programmer to set it themselves, generally done via the following instructions:
<whitequark> EXE files normally have separate segments for the code, data, and stack. Program execution begins at address 0 of the code segment,
<cr1901_modern> Okay it's uncommon, but there is some DS shuffling in this binary
<cr1901_modern> so maybe DPMI binaries do use a separate data segment rather than a flat binary
andlabs has joined ##yamahasynths
andlabs has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
andlabs has joined ##yamahasynths
<cr1901_modern> >Does DOS strip the MZ header when loading a binary or keep it?
<cr1901_modern> Strips it. So all offsets are off
<cr1901_modern> TD-Linux: Do you know how to tell ghidra to ignore a certain number of bytes at the beginning of a program?
<cr1901_modern> Answer: Raw Binary has an option called "File offset. I set that to 0x60 to strip the MZ header."
<TD-Linux> correct
<cr1901_modern> Okay this is way too much work/not worth the effort. I can't even find the place where the jump to protected mode is made
<cr1901_modern> ghidra does not appear to have support for "real mode, but using 32-bit insns"
<cr1901_modern> Guess I'll fire up dosbox debugger to find where the jump is made tomorrow
ej5 has quit [Read error: Connection reset by peer]
<ValleyBell> cr1901_modern: The driver has a feature that is often called "modulation", which lets you do vibrato and glissando.
<ValleyBell> Simplified, you have 3 parameters: delay, freq_delta and delta_time
<ValleyBell> For each note, it waits "delay" frames before starting.
<ValleyBell> Then it adds "freq_delta" to the note's frequency every frame.
<ValleyBell> after "delta_time" frames have passed, freq_delta is multiplied with -1.
<ValleyBell> So if note has frequency 0, delay=2, freq_delta=1, delta_time=2, then you get something like:
<ValleyBell> umm.. let's say delta_time=4
<ValleyBell> 0 0 +1 +2 +1 0 -1 -2 -1 +0 +1 +2 +1 0 ...
<ValleyBell> Yon can do glissando by setting delta_time to a high value like 255.
<ValleyBell> For Sonic 1 SMS FM, I took the original sequence data and changed the format to be more compact. And I added a few special features I needed for better control of OPLL stuff.
<ValleyBell> But FM and PSG songs use the same sequence data and in PSG mode the output is almost identical to the original game.
<ValleyBell> cr1901_modern: If Genecyst requires OPL3, you need to look out for writes to ports 220h..223h as well 388h..38Bh.
<ValleyBell> On a SoundBlaster 16, writing to 220h definitely works as well.
<cr1901_modern> It requires OPL3, but my main problem is that Genecyst is a dual real-mode/protect-mode binary (that may actually use different segment descriptors in protected mode rather than the flat mode everyone else uses). And Idk if ghidra can handle that
<cr1901_modern> https://youtu.be/a5CRANc2u4A?t=492 #corruptionaday
<cr1901_modern> okay, so half of the linked time is samples, but... it sounds like a completely different track
<cr1901_modern> (From what I understand Genesis games are harder to corrupt because you have to install an "on error resume next" handler for illegal instructions)
<Sarayan> Does somebody have the yamaha mu50 service manual?
<cr1901_modern> it's not on bitsavers or archive?
<ValleyBell> Yamaha's website only has user manuals, right?
futarisIRCcloud has quit [Quit: Connection closed for inactivity]
andlabs has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
andlabs has joined ##yamahasynths
l_oliveira has joined ##yamahasynths
andlabs has quit [Client Quit]
andlabs has joined ##yamahasynths
andlabs has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
andlabs has joined ##yamahasynths
<superctr> <ValleyBell> Simplified, you have 3 parameters: delay, freq_delta and delta_time <- Mucom88's LFO works exactly like that
<superctr> That's yuzo koshiro's own PC88 driver, of course
<superctr> The Sonic 1 SMS sound driver could actually be based on Mucom88 source code, if it is indeed Ancient custom
<superctr> since the mucom88 source code is available, i could check
<superctr> with the disassembly
<superctr> it looks like it's functionally similar but the code has been rewritten (probably to keep the cycle count down)
<cr1901_modern> LFO is definitely much more intelligent than what I was thinking lol
<cr1901_modern> Is there an OPLL tracker (yes, Adlib Tracker could also work)
<superctr> in Mucom88, the LFO command is M<delay>,<time multiplier>,<amplitude>,<invert delay>
<superctr> FAC Soundtracker
<superctr> for MSX
<cr1901_modern> Oh right, there's also tinyMML
<superctr> there are plenty of MML compilers if that's your thing
<cr1901_modern> Right, I keep thinking MML might be better for me. I can write a tinyMML interface to libvgm's OPLL/VRC7 code
<cr1901_modern> I've also been meaning to add a Rust shim for libvgm
<superctr> i am working on my own MML compiler
<cr1901_modern> (Disclaimer for the room: I actually love C. I wish I could hate it and I've tried many times to do so. But for stuff that only needs to run on x86/ARM, Rust is easier even if there are some things I don't care about it)
<superctr> maybe i should call it "hugeMML" because it's written in C++ and actually generates bytecode for further parsing by a sound tracker
<cr1901_modern> Happy to try hugeMML when it's ready
<superctr> sound driver^
<cr1901_modern> Well, as happy as I can be writing C++ code ;)
<superctr> though right now it actually generates VGM files, for YM2612 and SN76489
<superctr> the bytecode is just between the MML frontend and VGM driver
<superctr> the advantages of this is of course that if i get tired of MML, i can write a frontend for MIDI or whatever tracker format and still be able to generate the same bytecode
<cr1901_modern> My problem w/ MML is that chords are difficult to handle
<cr1901_modern> well in tinymml anyway
<superctr> heh, i thought about that too
<cr1901_modern> one can always compose channels separately and then do a sanity check to ensure every channel ends at the same tim
<cr1901_modern> e*
<cr1901_modern> but it's not what I'd call enjoyable
<superctr> in my MML format, i can enter something like "ABC {c/e/g}" and it will play a C major chord and keep it all synchronized
<superctr> I also added a "reverse rest" command that steals time from the previous note/tie/rest which is pretty handy when you have a delayed track and need to use the channel for something else for a moment
<cr1901_modern> reminds me of how wq's player steals time from future commands to account for delay of real chips
<Ultrasauce> stealing from tomorrow to pay for today
<Ultrasauce> moood af
<Xyz_39809> how to do MML chords https://www.mmlshare.com/tracks/view/604
<Xyz_39809> channels MQR and S
<cr1901_modern> thanks
<superctr> i should probably add a "retrigger" command too
<superctr> looking at that
<superctr> putting loop commands on multiple lines is already possible though
<Xyz_39809> I wish more psg/ssg drivers had note release envelopes. afaik only ppmck does it
<superctr> here's one of my PSG envelopes "@5 psg 15>10:5 / 10>0:20"
<superctr> 15>10:5 is a slide from 15 to 10 over 5 frames, / is the sustain hold
<Xyz_39809> looks like XPMCK
<Xyz_39809> although its 3rd parameter is the amount of volume change per step, rather than number of steps.
<superctr> yeah
<cr1901_modern> ValleyBell (or whoever is familiar w/ libvgm): What's the correct invocation for building for a minimal library without audio support? Basically I want "pure functions" of input reg writes to 16-bit samples output
<superctr> in that case you want to include the libvgm/emu directory in your cmakelists and link with vgm-emu
<cr1901_modern> Oh TIL CMake allows nested projects
<whitequark> cmake is surprisingly useful for how bad it is
<superctr> i'm pushing VB to make the emu part installable (on a unix system at least) so you won't need cmake to use the emulation part
<balrog> whitequark: cmake is bad, but everything else is worse
<superctr> Well, cmake is still 1000 times better than autoconf at least
<whitequark> balrog: superctr: yeah, my opinion too
<whitequark> i really hate cmake. i hate other build systems significantly more
<balrog> though what about bazel?
<cr1901_modern> I like meson personally
<balrog> and yeah, meson
<balrog> do those work well for cross compilation and dependency/lib handling?
<balrog> that's where most things fall apart
<balrog> autoconf is good except on windows where it's useless
<whitequark> balrog: i tried using basel
<cr1901_modern> balrog: meson works well for cross as long as your compiler is named gcc :P
<whitequark> i ... gave up trying to make it do what i wanted
<whitequark> ie make a c++ executable/library project
<superctr> personally, if i can get away with it, i prefer plain makefiles
<cr1901_modern> sdcc is something I want to add, but EYAKSTACKOVERFLOW
<superctr> they get hard to use with huge projects though
<balrog> btw there was an update to ghidra released yesterday
<superctr> i use scons at work and that's also meh
<balrog> yeah scons sucks
<balrog> autotools works well for large projects
<balrog> so does cmake
<balrog> superctr: huge projects? look at what MAME uses (lolololol no don't)
<balrog> there's talk about moving MAME to cmake
<cr1901_modern> why not meson :P?
<cr1901_modern> I used to love scons
<cr1901_modern> but they took too long to implement Python 3 support
<cr1901_modern> so it was too little too late
<superctr> that genie thing?
<balrog> superctr: ....yeah.
<superctr> i had to dive through that to find a specific build config a while ago
<cr1901_modern> >Lord_Nightmare: I'm hoping whenever plogue releases their 4-op synth product that they have some way to 'observe' the intermediate signals since it would help visually creating an instrument by hand
<cr1901_modern> >cr1901_modern: I know of an OPM simulator that allows you to do that
<cr1901_modern> https://www.youtube.com/watch?v=0VL2mfTLD2k It's a soundfont, but sounds really good
Stilett0 is now known as Stilett0-afk
kode54 has quit [Quit: ZNC 1.7.2 - https://znc.in]
ej5 has joined ##yamahasynths
kode54 has joined ##yamahasynths
__sen has joined ##yamahasynths
<cr1901_modern> Hi __sen :)
<__sen> Hi! I kept seeing you mention this channel on IRC so figured I'd come hang out.
<__sen> Err, on Twitter. This is IRC.
<cr1901_modern> >I kept seeing
<cr1901_modern> Too much blatant advertising :P?
<cr1901_modern> thanks for stopping by!
<__sen> Nah, just the right amount of blatant advertising IMHO.
<cr1901_modern> Excellent!
<ValleyBell> This should be a minimal example of how to setup libvgm with sound chip emulation + audio output.
<cr1901_modern> ValleyBell: I still want Rust bindings :P
<cr1901_modern> anyways that's pretty good