Hello! Someone knows how to edit the tone of PSG Square Wave under C4 note? I have an issue with a B.O.B song with the PSG channel 11 and 12 with the note and I cannot find how to edit the tone of the PSG.
Thank you.

Anyway, I'll cut to the chase.
I've drastically increased the size of the drop at the start of Scrap Brain Zone Act 3, and Sonic's standing animation just won't cut it anymore.

I tried to make a check to see whether it was SBZ3, but as usual I failed.
That's why I'm here asking for help again.
Sorry if it's annoying by now.

Thanks in advance.

Click to expand...

You should get in the habit of posting code for the things you've tried. It helps people help you.

However, I can say that when I did this for my hacks, I changed the Dynamic Level Events for the relevant level so that, within a certain screen positioning, Sonic is forced into his falling animation. When Sonic is out of this screen range, the code moves on to the next routine (which no longer overrides the animation).

Attached Files:

I think you'll get it then based on what you currently know. I will try to keep the details low and get to the point. Let's start by setting the VDP.

If you want to write data into VRAM, CRAM, VSRAM, or to one of the internal VDP registers, you have to move a word of data into the VDP control port at address C00004-C00005 or C00006-C00007:

Code:

move.w #$????,($C00004).l
move.w #$????,($C00006).l

Alternatively, you can move two words at a time via a long-word:

Code:

move.l #$????????,($C00004).l

Now, we'll look at setting the VDP to VRAM write mode, here is an example:

Code:

move.l #$58600000,($C00004).l

5B60 and 0000 are being moved into the VDP control port, to understand what these values are, we need to break them up into binary; 0101100001100000 0000000000000000, now some of these bits are setting the VDP into a specific mode, be it read, write, to/from VRAM, CRAM, VSRAM, etc, and some of these bits are the VRAM address we're writing to or reading from, below in a code table is our bits followed below it by a key system:

Code:

0101100001100000 0000000000000000
MMAAAAAAAAAAAAAA --------MMMM--AA

M = Mode
A = Address
- = Unknown/invalid (leave as 0)

We'll start with the mode, I have numbered all of the M's below:

Code:

0101100001100000 0000000000000000
10AAAAAAAAAAAAAA --------5432--AA

Depending on which of these bits (0 - 5) are set, depends on what mode you are setting the VDP to, here is a table of possible modes:

Now that the address/mode is set, the VDP data port address at C00000-C00001 and C00002-C00003 can be written to, again, you can do them as words, or as a single long-word, a long-word is preferable since it's smaller and quicker for the 68k CPU as an instruction:

Code:

move.l #$00000000,($C00000).l

This has now moved 0000 and 0000 into the VDP FIFO, the VDP will then copy these words into VRAM 1860 - 1863, it will then automatically advance the address ready for the next words of data:

Code:

move.l #$045670FE,($C00000).l

This has now moved 0456 and 70FE into VRAM 1864 - 1867, the address has incremented again. This is a repeating process, and so long as you keep moving data into the VDP data port (C00000 - C00003), the data will be copied into VRAM incrementally.

Here is an example of writing a single tiles' worth of art into VRAM 1860:

Evertime a tile is written, the dbf instruction will subtract 1 from d1, and as long as it hasn't gone below 0, it will jump back to "LoadTiles" over and over again, 8, 7, 6, 5, 4, 3, 2, 1, 0... Then it'll resume below and continue. Notice how the VDP data port was loaded into address register a6, when data is moved into a6 while it has brackets around it, the data is actually moved to the address that a6 has, so "move.w #$0123,(a6)" will move 0123 to address C00000.

Now, I noticed in some code before, you had the following line "locVRAM $F2E0 ; set VRAM address", so I assume by this, the VRAM address these ring numbers are meant to go at F2E0? I am also going to assume that object's sprites are already mapping these tiles on-screen, and that all we need to do is write the uncompressed art to this VRAM address and everything will be solid. If this is not the case, then we may have found yet another issue which needs resolving (you can write art into VRAM perfectly, but it means nothing if there are no sprites or planes mapping out those art tiles).

For now, let's just look at loading the uncompressed numbers correctly into VRAM F2E0+.

The ring count, lives counter, and score, are all hexadecimal/binary numbers, and are not decimal, but, we would like to display them as decimal since the average human (let alone player) deals with numbers on a base 10 system rather than base 2 or 16. So we need to convert the hex numbers into decimal.

The subroutines in Sonic games for displaying the HUD numbers, don't just copy uncompressed number art into VRAM, they actually realtime convert the hex number into decimal while writing the numbers to VRAM. This is done by subtracting the decimal 100's, 10's and units from the hex number. Remember the Hud_100 that's loaded into a2 in your code?

Code:

Hud_100: dc.l 100
dc.l 10
dc.l 1

These are the decimal digit places, notice how they lack a $ sign these are decimal numbers, when the assembler goes to assemble these, it'll convert them to hex, so these numbers are actually:

Code:

Hud_100: dc.l $64
dc.l $0A
dc.l $01

Now here's how it works... Let's say you have 619 rings. In RAM, this will be $26B, so we need to convert this hex number into decimal 619. Start by subtracting the 100 units (this is $64 in hex):

Now, keep in mind as you well know, the HUD humbers are two tiles tall, this means two tiles need to be copied per digit. Lucky for you, we can reuse Sonic 1's subroutine for rendering the ring numbers, however, the subroutine expects you to provide it some information first, here's how it works:

The subroutine "Hud_Rings" needs a6 to have the address of the VDP data port, it needs d0 to have the long-word VDP VRAM write address inside of it, and it needs d1 to have the number to convert and display. The subroutine will move the long-word address from d0 into the VDP control port, and it'll then convert the value in d1 into decimal, and write the correct tile art depending on the digit, into the VDP data port inside a6.

The jsr will jump to Hud_Rings, and then once the conversion and dumping is done, it will return back to just after the jsr, and continue going down. But... we'll cross that bridge once we get to it.

This is by no means the solution to your problem, but it should supply you with at least a decent amount of understanding and make fixing it a little bit easier. Get back to me on things like, where in VRAM the numbers are being dumped to, and whether or not the sprites are setup to display those numbers and so on, I would also like to know where (VRAM addres) and how (68k code) exactly you loaded the "RINGS" text art, this could be important.

Thanks again for your reply; I'll have to give it a more detailed read when I have more time tomorrow. In the mean time, here's some of the information you requested.

In order to load the 'RINGS' art, I first made modified versions of both the mappings and art for the HUD that only include the 'RINGS' portion, and 'included' them within 'sonic.asm' near the other HUD files.

Then, I added a check to the beginning of the HUD object, to make it load the alternate mappings and art, if the current gamemode is 'Special Stage' (this causes a small cosmetic issue when the stage is completed, but I plan to also solve that afterward):

According to the SCHG, the numbers patterns use 24 tiles ($300 bytes), so I assumed that that they would fit where the unused 'ZONE 1-3' Blocks currently are, since those currently take up a combined total of 27 tiles ($360 bytes).

That is why in the subroutine, I attempted to use 'locVRAM' (as honestly a bit of a shot in the dark there) to set the location for the art to $F2E0, where the free space is and dump it there, to no avail.

I'll try again tomorrow though, using the new info provided above.

Click to expand...

Progress update:

After reading these more carefully, and rigorously tinkering around, I've gotten the ring counter to be somewhat functional (thanks again to all who responded, especially MJ).

Some observations/process notes:

-Since my special stages don't constantly rotate, I was able to save a ton of VRAM space by reducing that art to just the first 9 tiles. This allows for the sufficient space needed (although there are still some graphical problems occurring in the bubble art for some reason.)

-Although I edited the new Special Stage's HUD art to only include 'RINGS', I didn't account for the the sprite for the numbers in the mapping file (since SonMapEd doesn't/can't load the numbers at the same time), so when calling Hud_Base in the special stage init code, it would only show garbage. By changing the sprite count to '3' rather than '2' in the map file, I was able to display the '0', but no other numbers.

-I experimented further, and found that what Firerat meant, was to add Hud_Update to Vbla_0A, the routine that the special stages use (Git disassembly), because it does not call for it already, like in the normal stages. I then set the f_ringcount flag to '1' prior to the Special Stage's looping routine.

-Although I could not get more numbers to load, I decided to create a duplicate Hud_Update routine for the special stages, and edited it to trim out anything unneeded:

This subroutine did not work either, so I was a bit unsure of what was going on. Initially I attempted a few combinations of both to no avail, but when I called for both routines within particular subroutines ('Hud_UpdateSS' in 'Vbla_0A', and 'SSRing_HudNumbers' in 'SS_MainLoop'), it worked. When testing the rom (in Regen), however, I would get a crash after getting around 30-ish rings. So then I moved Hud_UpdateSS to run directly after the 'WaitforVbla' instruction and it functions without crashing:

The odd thing now, is that it doesn't seem to count every ring; it sort of 'skips' for some reason, as if it's updating slower than how often I collect rings. Anybody have any insight on why this is happening? (I'm probably being rather sloppy with my code) [EDIT:] Removing the ringcount check from Hud_UpdateSS seems to do the trick, but this may just be a 'band-aid' measure, and not the best solution.

Other than that, (and some minor graphical issues), it works! Thanks again for the patient responses and help.

The source code up to this point:https://gist.github.com/TannerGhosen/01f10db3b8a06e77e62033d70474a62c
To be clear, I used a different compiler basing off of another repo that used the Sonic 2 Clone Driver for Sonic 1, and it compiled with the settings it defined. All I know is that it has a lot less errors than before.
EDIT: I also slightly altered my code to match what was done in that repo, altering endcs to endifs and all that jazz.
I don't know what or why @Clownacy, but the compiler that comes with these GitHub repos just do NOT like your clone driver.
EDIT 2: Just a rant, why does this dude's repo use 16-128 maps instead of the normal 256? Is there a big difference between the two?
EDIT 3: EDIT Glore! Anyhow, the clone driver does compile without errors, it's the sonic.asm that errors out as far as the compiler is concerned, and it fully executes them.

Unrelated to this:
I want to edit the level order for Sonic 1, but I found out that the file I need to edit is a .bin file (Level Order.bin). This is probably a dumb question with an obvious answer, but what program am I looking at to open this up and alter the hex code that's in it?