Jump to content
VinsCool

RMT Hacking Ideas and Progress

Recommended Posts

4 hours ago, ivop said:

Yes, perhaps we need to expand the SAP-R format anyway. It does not support anything other than full frames, either PAL or NTSC, and IIRC it does not support stereo. And it lacks SKCTL. Probably call it SAP-R2 or something. And indeed a "loop back to location x" variable would be great, too. But for now, let's see if I can implement a simple mono 1x recorder, and perhaps some tools to remove the cruft at the beginning of the capture, and maybe the end. A SAP-R editor? :D

stereo isn't really essential 👹 and it's just 2 mono files really so just save 2 SAPR? SKCTL just needs a single value, so that could be stored in the header as well... but indeed no need to worry about that yet! 

 

4 hours ago, ivop said:

BTW even though the sa_pokey_libatari800 experiment failed, don't underestimate libatari800. If you want, you could link it with RMT2LZSS and play sound. At least for 1x PAL/NTSC players. Multispeed would need more work.

I added the ASAP Pokey to Wav converter a while back to RMT2LZSS and it worked fine (meaning RMT2WAV without 6502 emulation), but I never finished it because there wasn't much point to it... The inital goal was to have the ASAP player as well and potentially use that as the basis for a potential new tracker but a new tracker editor is just too much work.

  • Like 1

Share this post


Link to post
Share on other sites
2 hours ago, rensoup said:

stereo isn't really essential 👹 and it's just 2 mono files really so just save 2 SAPR?

How would they be synchronised, however? I'm curious about this.

Could the SAPR format handle more than 1 POKEY at the time, now that I think of it?

Or could it also work at speeds that are not 50/60hz? I've wondered for the latter especially while I was doing some cross region LZSS conversion experiments.

I noticed that multispeed did not seem to be taken into account, but to be fair I didn't really try things any further since, so I can't really tell for sure.

 

2 hours ago, rensoup said:

SKCTL just needs a single value, so that could be stored in the header as well... but indeed no need to worry about that yet! 

SKCTL could totally be changed on the fly, and there's nothing wrong about it I believe.

Nothing stops a musician (or maybe more a programmer at this point? XD) from changing what value is used to achieve all sort of effects, mainly, the Two-Tone Filter!

There are also some other POKEY registers that could have a useful purpose, for example, doing Hard Reset effects that could manipulate the Polycounter for really precise Distortion C tones. :P 

 

2 hours ago, rensoup said:

I added the ASAP Pokey to Wav converter a while back to RMT2LZSS and it worked fine (meaning RMT2WAV without 6502 emulation), but I never finished it because there wasn't much point to it...

👀

  • Like 2

Share this post


Link to post
Share on other sites
1 hour ago, VinsCool said:

How would they be synchronised, however? I'm curious about this.

not sure what you mean but there's nothing that plays stereo sapr anyway 🙂

1 hour ago, VinsCool said:

Could the SAPR format handle more than 1 POKEY at the time, now that I think of it?

Not sure how it would do that...

1 hour ago, VinsCool said:

Or could it also work at speeds that are not 50/60hz? I've wondered for the latter especially while I was doing some cross region LZSS conversion experiments.

I noticed that multispeed did not seem to be taken into account, but to be fair I didn't really try things any further since, so I can't really tell for sure.

SAPR doesn't know anything about multispeed,... SAPR output by Altirra is only 50/60hz (Although A800 might support SAPR multispeed, but @ivop would know about that )

1 hour ago, VinsCool said:

SKCTL could totally be changed on the fly, and there's nothing wrong about it I believe.

Nothing stops a musician (or maybe more a programmer at this point? XD) from changing what value is used to achieve all sort of effects, mainly, the Two-Tone Filter!

There are also some other POKEY registers that could have a useful purpose, for example, doing Hard Reset effects that could manipulate the Polycounter for really precise Distortion C tones. :P 

yeah crazy features that probably nobody will use (remember AUDCTL control per envelope step ) 😏.  Though it could be added of course !

  • Like 1

Share this post


Link to post
Share on other sites
44 minutes ago, rensoup said:

(remember AUDCTL control per envelope step ) 😏

Hey that one is a thing I would totally abuse! hahaha

  • Haha 2

Share this post


Link to post
Share on other sites
12 hours ago, rensoup said:

SAPR doesn't know anything about multispeed,... SAPR output by Altirra is only 50/60hz (Although A800 might support SAPR multispeed, but @ivop would know about that )

Yes, atari800 supports multispeed Pokey recording

 

	-pokeyrec                  Enable Pokey registers recording
	-pokeyrec-interval <n>     Sampling interval in scanlines (default: 312)
	-pokeyrec-ascii            Store ascii values (default: raw)
	-pokeyrec-file <filename>  Specify output filename (default: pokeyrec.dat)
	-pokeyrec-stereo           Record second Pokey, too (default: mono)

1x/2x/3x/4x PAL equals intervals of 312, 156, 104, and 78.

1x/2x/3x/4x NTSC equals intervals of 262, 131, 87, and 65.

 

With stereo enabled, it just dumps the left Pokey first, and then the right Pokey, and then continue to the next interval.

 

I'm thinking about adding -pokeyrec-format raw, sapr, sapr2. Currently it's only raw and you have to add the SAPR header yourself.

 

  • Like 1

Share this post


Link to post
Share on other sites
17 hours ago, VinsCool said:

There are also some other POKEY registers that could have a useful purpose, for example, doing Hard Reset effects that could manipulate the Polycounter for really precise Distortion C tones. :P

You mean STIMER? I agree. So, SAP-R2 should capture $D200-$D209 + $D20F, which is 11 bytes per interval. 22 bytes for stereo. And support 1x/2x/3x/4x players, so we need a new header entry, besides signaling being SAP-R2. And a loop setting.

Edited by ivop
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

SAP already supports multispeed!

 

FASTPLAY

    Number of scanlines between calls of the player routine. A scanline
is defined to be 114 Atari clock cycles. FASTPLAY defaults to one frame:
312 scanlines for PAL (about 50 Hz), 262 for NTSC (about 60 Hz). Most
songs don't include this tag. Common values are 156 (twice per frame),
104 (three times per frame) and 78 (four times per frame). ASAP 3.0.0 and
above supports FASTPLAY up to 32767. Other SAP players may limit the
value to 312.

...

TYPE R
    The data part is a raw dump of the POKEY registers (D200-D208)
in FASTPLAY intervals, instead of an Atari executable. No mainstream
SAP player supports this type at the time of writing.

 

Never knew that, even though I implemented pokeyrec based on intervals :)

  • Like 4

Share this post


Link to post
Share on other sites

Good news everyone :)

 

You remember when I mentioned wanting an AUDCTL envelope? Well, I figured it out, it was a lot easier to implement than I expected.

I have no concrete example to show yet, but basically, I hijacked the RMT command 7 to set an audctl value from the XY parameter loaded in memory, combined to the existing Volume Only output code already in place, and replaced the other function described in the manual:

Quote

Set the base note to $XY value directly. Play base note (new value). If $XY=$80, then use the current volume for VOLUME ONLY forced output.

So, set base note may be gone, but to be honest I don't remember seeing a single module using such a feature, let alone volume only. :D 

 

Here's my simple code edit for now: 

cmd7
	IFT FEAT_COMMAND7SETNOTE||FEAT_COMMAND7VOLUMEONLY
	IFT FEAT_COMMAND7SETNOTE
	lda reg3
	IFT FEAT_COMMAND7VOLUMEONLY
	;cmp #$80
	cmp #$FF ; FF is unlikely with AUDCTL in normal situation
	beq cmd7a
	EIF
	sta trackn_audctl,x
	lda trackn_note,x ; addition, to bypass the hijack value in accumulator possibly breaking stuff
	jmp cmd0a
	EIF
	IFT FEAT_COMMAND7VOLUMEONLY

cmd7a
	lda trackn_audc,x
	ora #$f0
	sta trackn_audc,x
	lda trackn_note,x
	jmp cmd0a
	EIF
	EIF

I've tested very quickly in RMT from a binary, and so far this is promising, because it's literally doing what I want: change the AUDCTL parameter on the fly.

 

More on that a bit later today :) 

  • Like 2

Share this post


Link to post
Share on other sites

Ok so... I gave a quick test to it, and now I have a major (minor but annoying) issue that is a lot more obvious this time.

 

You remember when I mentioned that an AUDCTL change would affect the notes playback in a way where a change can only happen 1 frame after an instrument was initialised? 

Well now this is a lot more obvious with an immediate change such as an AUDCTL envelope.

It does, in fact, work perfectly with the Command 7 hijack! BUT, it does come with a compromise: immediate changes, regardless of how they're done in the tracker, still carries over 1 frame late.

 

The main reason why? The order of operation itself. 

1- Instrument initialisation, 2- fetch the note table pointer (my hijack code is here), 3- write the trackn_audc value,  4- process the effects, 5- write the trackn_audf value, 6- combine all the individual AUDCTL parameter into v_audctl (and v_audctl2 in stereo), and finally, 7- write all the previous values into the POKEY registers at the start of the next rmtplayr call, in that order.

 

Because of how I hijacked my own tables, this had the side effect of executing the RMT code off timing, but this is only because of how I did my hack in the first place, things worked perfectly fine in the original.

So... yeah... something must be done, and I do have an idea, but that may break a lot of things, so I have no promise for the moment.

 

In the meantime, if anyone wants to try the experimental AUDCTL envelope. just use this along with the Stripped RMT.exe and ivop's c6502.dll binary loader.

It does work, like I said, but all changes will be processed 1 frame late, so be aware, any garbage sounds happening during a change is entirely my fault, this is not a buggy POKEY emulation problem, and not a problem by the .exe itself!

 

Rename the file to 'tracker.obx', put in the same folder the RMT.exe is located, and run.

Usage: Command 7 will process any XY value as direct AUDCTL parameter. A value of $FF will switch to the Volume Only Mode, in replacing $80.

 

For now, I'm just going to think of a way to change things around in a way that wouldn't break everything... :D 

 

 

rmtplayr Patch16 Beta7.obx

Share this post


Link to post
Share on other sites

Not sure what you mean about being one frame late.

 

A proper player does this, each frame:

 

1.) copy shadow pokey to real pokey, i.e. always at the same time

2.) run player routine that writes to shadow pokey registers

 

So basically, you are always one frame behind programmatically, but audibly you are in sync. Do you mean your AUDCTL changes are an additional frame behind?

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, ivop said:

Not sure what you mean about being one frame late.

 

A proper player does this, each frame:

 

1.) copy shadow pokey to real pokey, i.e. always at the same time

2.) run player routine that writes to shadow pokey registers

 

So basically, you are always one frame behind programmatically, but audibly you are in sync. Do you mean your AUDCTL changes are an additional frame behind?

What I mean is, everything works as intended, but if it were in a slightly different order, that issue would be worked around.

 

To fetch my note tables into account, it depends on the audctl values in memory, which is only something done AFTER the instruments were initialised, and written into the shadow registers.

So the next frame, things are updated accordingly, but the AUDC/AUDF values are 1 frame late, because they do not know the AUDCTL changes were applied yet.

 

That goes back to the Command 7 hijack, it works perfectly to write the AUDCTL in memory, programmatically speaking it works perfectly, it's all the hijacked stuff that is 1 frame late.

 

Ideally, AUDCTL and Commands should be should be processed BEFORE the notes tables are loaded and used accordingly.

After that, shadow AUDC and AUDF registers could be written, and things will be in-sync between player calls.

 

The reason why this never was a problem before is simply because RMT literally never needed to take that stuff into consideration, since it never needed to in the first place.

There were like, 3 actually useful tables of notes (and that doesn't include 16-bit bass that did work around with its own method, with the caveats it also introduced).

 

So yeah, some big changes will be necessary, and thankfully the binary loader solves the major problem: memory.

If it can fit into the real thing, it should work, we've proven it already :P

 

---

 

TLDR my approach depends on the AUDCTL directly, and it is processed after notes were loaded into memory and ready to be output, the next frame the process is done again but the AUDCTL stuff is written before the notes were actually aware of any change, causing 1 frame of lag between the values intended to be used vs what is actually used.

Share this post


Link to post
Share on other sites

Hmmm so I'm onto something that is interesting right now.

 

You probably remember ivop having to add back a RTS at a specific memory location, $35FC

I was looking at the disassembly of the remaining code at the end of the tracker binary in RMT.exe, and just noticed something I overlooked last time I played in the disassembler:

817             org $3D00
818 ;
819             sta L3060,X            ; 9D 60 30
820             sta L3150,X            ; 9D 50 31
821             tya                    ; 98
822             asl                    ; 0A
823             sta L30A8,X            ; 9D A8 30
824             bmi L3D11              ; 30 04
825             tay                    ; A8
826             jmp L3576              ; 4C 76 35
827 L3D11       rts                    ; 60
828 ;
829             org $35FC
830 ;
831             rts                    ; 60
832 ;
833             org $3E00
834 ;
835             asl                    ; 0A
836             asl                    ; 0A
837             asl                    ; 0A
838             asl                    ; 0A
839             sta L3068,X            ; 9D 68 30
840             rts                    ; 60
841 ;
842             org $3E80
843 ;
844             lda #$00               ; A9 00
845             sta L3068,X            ; 9D 68 30
846             sta L30B8,X            ; 9D B8 30
847             sta L30B0,X            ; 9D B0 30
848             sta L3168,X            ; 9D 68 31
849             rts                    ; 60
850 ;
851             org $3F00 ; RMT8 HEADER and some other placeholder stuff?

Specifically, this part:

826             jmp L3576              ; 4C 76 35
827 L3D11       rts                    ; 60
828 ;
829             org $35FC
830 ;
831             rts                    ; 60

There are 2 things that just came to me as a realisation: that entire block is basically, jumping to the SetUpInstrumentY2 label from the rmtplayr code, and try to jump at an RTS that is supposed to be at the end of that block! 

So that would likely explain why everything broke when I edited code just around that part: stuff did no longer align to the expected locations.

 

Hopefully, if my theory is right, that could be worked around very easily.

First of all, the ORG to $35FC that simply writes a RTS... could just be replaced by a RTS directly, at the end of the block, avoiding conflicts to the memory locations?

As for the jump to the location $3576, it could either be replaced by the address that may be a different one when necessary, or avoided altogether, but then, where would it be? So I will go with the first option. for now.

 

This is what lies at the end of the SetUpInstrumentY2 block:

xata_rtshere
	IFT FEAT_SFX
	rts
	ELS
	jmp p2x0
	EIF

I suppose there would be no harm to make it a RTS directly when it's assembled for the TRACKER part, right? :P 

 

The reasoning for this observation is simple: everything I tried to change around that block would break RMT regardless of the changes, and I do know a RTS is being forced to $35FC.

I was really lucky most things still aligned after all the fucking around I did so far. so this must be solved at once, hehe

 

I'll keep poking around and keep you all updated, I learn something new everyday.

Share this post


Link to post
Share on other sites
23 minutes ago, VinsCool said:

I suppose there would be no harm to make it a RTS directly when it's assembled for the TRACKER part, right? :P 

Looks like my assumption was correct: I've assembled the code leaving a RTS at the end of SetUpInstrumentY2, and everything works. as expected.

I even NOPed the part that was doing ORG $35FC, RTS, and things still appear to work as expected, so this is pretty awesome.

 

Now I'll purposefully move things in the code itself (simply add NOPs for padding, assemble it, and also edit the Set Instrument address accordingly, if the edit made things align to work, that would mean I was indeed correct with my theory :D 

 

[Edit] I also had to edit the sa_c6502.dll a little bit to remove the hardcoded write of RTS at $35FC, by the way, so I know for sure this is not false positive results.

Edited by VinsCool

Share this post


Link to post
Share on other sites

And I was indeed correct!

So this is another problem solved it looks like :) 

 

In this edit, I changed few things in the .exe: I changed the JMP $3576 to $3596-- else things were broken, as expected. Then I NOPed the entire part doing ORG $35FC, RTS, since I had assembled the block with a RTS at the end.

Then I assembled the .obx with an arbitrary amount of NOPs in the middle of the code, just after a JMP, which just added padding, essentially, moving addresses around. 

 

Things work exactly like they were just before as far as I could tell.

I also edited the .dll to not write a RTS at $35FC, so that's something, now I know I can safely hack the code a bit deeper :D 

 

Also the rmtplayr is the same Command 7 hack I did earlier today, so now I have a good base to try doing some bigger edits to work around my "1 frame late" problem :P 

Now I know I was mostly rambling so here's a simple test tune I did testing the AUDCTL "envelope" hack:

 

 

By the way I recorded the video from that "memory hack" .exe. doesn't seem to sound any different from the same old version I was using a moment ago when I did this test tune.

It probably does not look like much in video, but trust me, the AUDCTL was updated in several key moments in a bunch of instruments.

I also included the .rmt so it makes a little more sense, make sure to run in NTSC speed too!

Please don't mind the random patterns unused in song, I was experimenting with other stuff a bit earlier yesterday, hehe.

Despite that 1 frame of delay causing few artifacts, things usually get lost in the mix so it seems work fine in most cases, thankfully :) 

RMT STRIPPED OFF BINARIES NOPED 35FC ORG AND JMP EDIT.exe sa_c6502.dll tracker.obx filter test.rmt

  • Like 10

Share this post


Link to post
Share on other sites

More on what I was observing last night, I've come to an even better setup :) 

So now I can tell for sure: all the addresses that were hardcoded to the end of where the tracker binary was loaded can be fully manipulated directly from that same .obx itself!

In order to achieve it, I simply converted the disassembled code I posted a few posts above into its own thing but made it point to the expected addresses, and then assembled at the end of the usual TRACKER binary output, and that's it!

 

Full control on the pointers, nothing seems to break it, unless it was purposefully done so, or incorrectly done in the first place.

No more necessity for writing a RTS by force this time, or even point to the SetUpInstrumentY2 address either--, it's all done in the .obx using the disassembled code I have re-assembled with the expected pointers pointing the right stuff :D 

That also means the same old Stripped Binary from the very first tests will work perfectly fine for the purpose; the memory will be overwritten anyway.

I also recorded myself fucking around with the memory addresses hack I just created, as well as purposefully breaking stuff, and then just playing around for over 20 minutes with the custom AUDCTL commands.
As soon as I loaded the "non broken on purpose" binary, it was a smooth sailing, and kinda got carried over lol

 

By the way, that .obx is kind of a joke on purpose, it does work, but it was made to prove a point ;) 

I will make the proper edits for the next RMT changes I could be able to do, because now that the memory addresses are not going to be a problem anymore, I can finally try to get much bigger changes in the rmtplayr code.

(also btw ivop I sent a pull request for the sa_c6502.dll code to match these changes accordingly :P )

tracker.obx

  • Like 5
  • Thanks 1

Share this post


Link to post
Share on other sites
11 hours ago, VinsCool said:

(also btw ivop I sent a pull request for the sa_c6502.dll code to match these changes accordingly :P )

Merged.

 

So you're saying I wasted a whole evening to find this bug, and now it's not needed anymore? 😠 ;)

 

Really liking where this is going!

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

but the cool thing is that this process has caused the code made to be allowed tighter... and now this can go forward with some re ordering and expansion. Just when you think it's all that can be done or fixed... boom! you can now do so much more and add what you needed and fixed as well. Nothing is truly wasted, and a great deal was gained and learned.

  • Like 2

Share this post


Link to post
Share on other sites
17 minutes ago, ivop said:

Merged.

 

So you're saying I wasted a whole evening to find this bug, and now it's not needed anymore? 😠 ;)

 

Really liking where this is going!

 

Hehe I couldn't have known either, I was the first to be surprised by this!

In fact, that fix turned out to be a problem as soon as I was no longer aligned to the memory addresses, so it makes more sense to have yet another tracker exclusive bit of code to work around that and solve this issue in 1 step.

 

Having a RTS was one thing, but pointing to the right location for the SetInstrumentY2 routine was another, and so one or the other was going to break regardless 😛

 

Thankfully, the proof of concept and yesterday's playaround seem to be conclusive evidences to me that stuff is even less likely to break for unknown reasons that were seemingly unrelated :D

 

 

  • Like 1

Share this post


Link to post
Share on other sites
4 minutes ago, VinsCool said:

Hehe I couldn't have known either, I was the first to be surprised by this!

In fact, that fix turned out to be a problem as soon as I was no longer aligned to the memory addresses, so it makes more sense to have yet another tracker exclusive bit of code to work around that and solve this issue in 1 step.

I was just kidding. I doubt if we would be at this point, if I didn't find that bug at the time. And now the workaround isn't needed anymore, which is basically a good thing!

 

4 minutes ago, VinsCool said:

Thankfully, the proof of concept and yesterday's playaround seem to be conclusive evidences to me that stuff is even less likely to break for unknown reasons that were seemingly unrelated :D

Great! :)

 

  • Thanks 1

Share this post


Link to post
Share on other sites
31 minutes ago, _The Doctor__ said:

but the cool thing is that this process has caused the code made to be allowed tighter... and now this can go forward with some re ordering and expansion. Just when you think it's all that can be done or fixed... boom! you can now do so much more and add what you needed and fixed as well. Nothing is truly wasted, and a great deal was gained and learned.

Certainly! Without all those fake DLL's to determine what RMT is actually doing, and then the code injector, and this RTS oddity fix, this project might have been a dead end.

 

And now Vinscool isn't limited by memory anymore. Code does not have to be tighter. All memory outside of where the .rmt data resides is available for code or data. Even the ROM area, but that might complicate creating a .xex ;)  The sa_c6502.dll emulation doesn't have any notion of ROM. I could add banked memory though, if Vinscool runs out of space in the normal non-DOS, non-screen memory RAM that's available ;)

Edited by ivop
typoos
  • Like 3

Share this post


Link to post
Share on other sites

Up to right now I think the major problem was that things were breaking if they were not aligned, and now this appears to no longer be problematic :)

 

Concerning memory itself, there definitely is plenty available now.

I've purposefully left RMT start at its same old address of $3182, but moved all tables to $B000 to prevent any overwrite, and have a lot more memory available for making tables.

The .rmt modules still load to $4000, and the Visual Player project on top of it was itself moved to $8000, so a module up to 16kb will work without any problem there, my biggest modules never came close to this size yet, so that seems to be plenty for everything. :D

  • Like 1

Share this post


Link to post
Share on other sites
Quote

  1 hour ago, VinsCool said:
I don't like the idea of using AUDC volume bits as a toggle, because it would under normal circumstances be intended to set volume or volume only output.

I already have had a proof of concept toggle, but ultimately, it was writing to SKCTL to work at all.

 

Quote

 

OK, listen to the users. I have never used volume-only at 50-200Hz speed, but if it has a purpose, it should not be overloaded. On the other hand, there are eight ranges of volume only. One of them might be used to signal other things to RMT2LZSS, instead of adding another channel to the nine per pokey we already have, just for a single bit in SKCTL and/or a write to STIMER.

 

I didn't mean to cram the 2 tone bit into SAPR AUDCx, it could be an extra channel in a SAPR2 format like @ivop mentioned.

Then when compressing with LZSS the 2 tone bit could be set as an invalid AUDC0 combination (those that LZSS removes by default because they provide better compression ). The LZSS player could just check for those invalid AUDC0 values and enable/disable 2 tone mode.

 

Same could be done with AUDC1 for STIMER (or AUDC0 if there are enough bit available)

 

Small drawback: the tune would have to be compressed with "better compression" setting for this to work.

 

 

Quote

52 minutes ago, VinsCool said:
Assuming this is a theoretical WebPOKEY exclusive feature, that could totally work, and in fact, that could easily be done even with the RMT player code itself... By repurposing the Volume Only toggle               


On a little tangent here:


I was actually thinking about this earlier and had the idea of using a variant of my Command 7 hack to allow the output of Volume Only, Two-Tone and AUDCTL, all baked into a single command.

The XY parameters would take care of what becomes what, in this setup.


My idea was to reserve $FF to the usual Volume Only mode toggle, $FE for Enabling Two-Tone, and then $FD for disabling it, keeping any other values for the AUDCTL itself.

My reasoning for this idea was that it would be incredibly unlikely to have all AUDCTL bits enabled at once in a single instrument, and so, that would leave a lot more creativity with virtually no penality to the user               

 

Not a WebPokey feature, just a SAPR channel extension... where would that channel come from is a different story (the tracker would need to be able to output SAPR2).

 

Hacking existing commands is never great (but of course that's all that's available)... a bit like the E command in protracker:

 

Exy Subcommands:
E0x Amiga LED Filter toggle *
E1x Fine portamento up
E2x Fine portamento down
E3x Glissando control **
E4x Vibrato control **

...

 

Note: storing the 2 tone bit in AUDC would be to avoid having an extra LZSS channel which would cost an extra 256 bytes... (So yeah this is more LZSS related than RMT).

Edited by rensoup
note
  • Like 2

Share this post


Link to post
Share on other sites
50 minutes ago, rensoup said:

I didn't mean to cram the 2 tone bit into SAPR AUDCx, it could be an extra channel in a SAPR2 format like @ivop mentioned.

Then when compressing with LZSS the 2 tone bit could be set as an invalid AUDC0 combination (those that LZSS removes by default because they provide better compression ). The LZSS player could just check for those invalid AUDC0 values and enable/disable 2 tone mode.

 

Same could be done with AUDC1 for STIMER (or AUDC0 if there are enough bit available)

Emphasize mine again :)  What is an invalid AUDC0 combination? All 256 values are valid, unless we overload some of the volume-only combinations, right?

 

53 minutes ago, rensoup said:

Not a WebPokey feature, just a SAPR channel extension... where would that channel come from is a different story (the tracker would need to be able to output SAPR2).

We'll work on that :) First I want to establish what would be the best format for SAPR2/SAPQ (perhaps it is better to stick to a single letter? not sure about current parsers, Altirra, WebPokey). I think one extra channel should be enough to capture the two-tone bit and a write to STIMER for every frame.

 

Creating such files could be done with atari800 (I'll add it to pokeyrec once we agree on the format), and possibly a SAP writer inside sa_c6502.dll with the code injector. That would circumvent all the timing issues in RMT.

  • Like 1

Share this post


Link to post
Share on other sites
13 minutes ago, rensoup said:

Note: storing the 2 tone bit in AUDC would be to avoid having an extra LZSS channel which would cost an extra 256 bytes... (So yeah this is more LZSS related than RMT).

Oh I see! I thought it was about SAPR, being LZSS exclusive makes more sense in this case.

RMT was irrelevant about that anyway: it was only an idea regarding the way Two-Tone could be toggled making use of the existing code.

18 minutes ago, rensoup said:

Hacking existing commands is never great (but of course that's all that's available)... a bit like the E command in protracker:

 

Exy Subcommands:
E0x Amiga LED Filter toggle *
E1x Fine portamento up
E2x Fine portamento down
E3x Glissando control **
E4x Vibrato control **

...

If it works, why not? 

Most trackers do this, and that rarely was a problem, it only makes certain commands more difficult to memorise.

 

If we think about what a command does, and what it could be used for outside of its XY values that could be "valid", there are definitely quite a bunch of commands that really could get some extra abilities with virtually no drawback over compatibility.

That was precisely the reason I targeted the RMT Command 7 in the first place: Its purpose was both very rarely used, AND had barely any impact for being edited.

 

Have a look at the RMT Commands, from the manual.htm itself:

Envelope command (COMMAND parameter)
0	Play the base note shifted by $XY semitones. If resulting note by reason of note shifting is out of C-1 to C-6 range (hex values $00 to $3D), then output volume will be zero.
1	Play the frequency $XY directly.
2	Play the base note shifted by frequency $XY.
3	Add $XY semitones to base note. Play base note (new value). If resulting note by reason of note shifting is out of C-1 to C-6 range (hex values $00 to $3D), then output volume will be zero.
4	Add frequency $XY to FSHIFT register. Play base note.
5	Set up portamento speed $X, step $Y (each $X vbi will be "volatile portamento frequency" shifted up or down by $Y value in a direction of actual frequency). If $XY=$00, then set current frequency directly to volatile portamento frequency.
6	Add $XY value to FILTER_SHFRQ. (Whenever the new note in track is getting started, FILTER_SHFRQ is initialized to $01, so that default join filter generator frequency is higher by 1.)
7	Set the base note to $XY value directly. Play base note (new value). If $XY=$80, then use the current volume for VOLUME ONLY forced output.

There are many candidates for multiple usages, and that's why I was looking into earlier-- There's plenty of potential sitting in front of us right there :P 

 

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, rensoup said:

I didn't mean to cram the 2 tone bit into SAPR AUDCx, it could be an extra channel in a SAPR2 format like @ivop mentioned.

Glad we agree. As I said in the WebPokey thread, the SAP format is different from what RMT does. And what happens between RMT and RMT2LZSS stays in Vegas ;) or something like that. If you can pack the tenth channel in one of the other nine in your LZSS stream, go for it! :)

  • Haha 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...