Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#76 2012-11-01 00:27:49

Sawakita
Administrator
Registered: 2010-10-16
Post 327/365

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

What are P14 and P15?

http://nocash.emubase.de/pandocs.htm#joypadinput

Danny-E 33 wrote:

How exactly is the joypad register getting involved in this?

Same link, under Usage in SGB software:

Pandoc wrote:

Beside for normal joypad input, SGB games mis-use the joypad register to output SGB command packets to the SNES, also, SGB programs may read out gamepad states from up to four different joypads which can be connected to the SNES.
See SGB description for details.


Danny-E 33 wrote:

What are low and high?

Low/High mean the bit is reset/set (in some different context their meaning might be used reversed).

Danny-E 33 wrote:

What are pulses?

Pulse is a single signal dispatch (it basically corresponds to a LD command when you load some value through I/O ports).

Danny-E 33 wrote:

What does LSB mean?

Least Significant Bit.

Danny-E 33 wrote:

And I still don't understand where exactly a packet is supposed to come from..

What do you mean?

---

Anyway, since you previously asked for better comments in the SendSGBPack routine, here it is.
Remember that when SendSGBPack is called, HL must contain the pointer to a SGB packet.

SendSGBPack: ;$5feb
;check number of packets
    ld a,[hl]
    and a,$07
    ret z

The first byte of a SGB packet is a mini-header that encodes both the packet type and the quantity (I already showed you the formula {packet type} << 3 | quantity). The previous chunk of code checks the quantity (the lowest 3 bits in the first byte). If quantity is zero the routine clearly returns.

; store number of packets in B
    ld b,a
.loop2\@
; save B for later use
    push bc
; load a non-zero value in $fff9 to disable the routine that checks actual
; joypad input (said routine, located at $15f, does nothing if $fff9 is not
; zero)
    ld a,$01
    ld [$fff9],a
; send RESET signal (P14=LOW, P15=LOW)
    xor a
    ld [$ff00],a
; set P14=HIGH, P15=HIGH
    ld a,$30
    ld [$ff00],a
;load length of packets (16 bytes)
    ld b,$10
.nextByte\@
;set bit counter (8 bits per byte)
    ld e,$08
; get next byte in the packet
    ld a,[hli]
    ld d,a
.nextBit0\@
    bit 0,d
; if 0th bit is not zero set P14=HIGH,P15=LOW (send bit 1)
    ld a,$10
    jr nz,.next0\@
; else (if 0th bit is zero) set P14=LOW,P15=HIGH (send bit 0)
    ld a,$20
.next0\@
    ld [$ff00],a
; must set P14=HIGH,P15=HIGH between each "pulse"
    ld a,$30
    ld [$ff00],a
; rotation will put next bit in 0th position (so  we can always use command
; "bit 0,d" to fetch the bit that has to be sent)
    rr d
; decrease bit counter so we know when we have sent all 8 bits of current byte
    dec e
    jr nz,.nextBit0\@
    dec b
    jr nz,.nextByte\@
; send bit 1 as a "stop bit" (end of parameter data)
    ld a,$20
    ld [$ff00],a
; set P14=HIGH,P15=HIGH
    ld a,$30
    ld [$ff00],a
    xor a
    ld [$fff9],a
; wait for about 70000 cycles
    call Wait7000
; restore (previously pushed) number of packets
    pop bc
    dec b
; return if there are no more packets
    ret z
; else send 16 more bytes
    jr .nextByte\@

;...

Wait7000: ;$614a
; each loop takes about 10 cycles so this routine actually loops through 70000
; cycles.
    ld de,$1b58    ; = 7000
.loop\@
    nop
    nop
    nop
    dec de
    ld a,d
    or e
    jr nz,.loop\@
    ret

Offline

#77 2012-11-01 02:04:48

540/704

Re: Pokemon Red: Palettes

In an attempt to make things slightly clearer:

Danny-E 33 wrote:

What are low and high?

0 and 1.

Danny-E 33 wrote:

What are pulses?

Say you have a bit that is 0, but you set it to 1 for a short time and then back to 0. That would be an example of a pulse.

Danny-E 33 wrote:

And I still don't understand where exactly a packet is supposed to come from..

Example: The SGB has four palettes of four colors each. Say you wanted to set SGB palette 0 to the player’s active Pokémon’s colors, and palette 1 to the enemy’s. (I’m just making up this example—the game probably doesn’t load those monster palettes to those exact locations.) SGB command PAL01 looks like what we want. The documentation says:

SGB Command 00h - PAL01

Transmit color data for SGB palette 0, color 0-3, and for SGB palette 1, color 1-3 (without separate color 0).

Byte    Content
  0     Command*8+Length (fixed length=01h)
  1-E   Color Data for 7 colors of 2 bytes (16bit) each:
          Bit 0-4   - Red Intensity   (0-31)
          Bit 5-9   - Green Intensity (0-31)
          Bit 10-14 - Blue Intensity  (0-31)
          Bit 15    - Not used (zero)
  F     Not used (00h)

The value transferred as color 0 will be applied for all eight palettes.

This describes the structure of a PAL01 packet.

The first byte is 0x01 (equivalent to “PAL01 << 4 | 1”), because all SGB packets start with the command and number of packets in the nybbles of the first byte.

The next two bytes are a color in RGB format. Color 0 of all four SGB palettes will be set to this color (probably white or black would be a good choice).

The next six bytes are three colors in RGB format, which make up colors 1–3 of palette 0. These could be pulled from the monster palette data in ROM.

The next six bytes are three colors in RGB format, which make up colors 1–3 of palette 1. Ditto.

Since this is 15 bytes but SGB packets are 16 bytes, the last byte is 00 for padding. Remember:

One byte for command and number of packets.
Fifteen bytes for data.

That’s a SGB packet. You could generate this at runtime, store it in RAM somewhere, and send the packet one bit at a time through JOYP. The function that Sawakita initially posted does this for us: just load hl with the pointer to the packet, and call 1c:5feb, and the packet will get sent to the SGB.

#78 2012-11-01 04:35:45

Danny-E 33
Administrator
Registered: 2012-06-09
Post 233/1,149

Re: Pokemon Red: Palettes

Okay okay okay.
I'm getting there. :P

So if, like Sawakita suggests, I inject a routine around the time the game saves when you try to switch boxes, I could load hl with the address of a packet that I've added to free space and call 1C:5FEB in order to change the palette of the whole screen to the red health bar palette. Then when you leave the change box screen, have it load hl with another packet and call the routine again to return the palette of the whole screen back to normal.. Right?

I see a couple problems though.
How can I use a debugger to find where I should add in the extra code for doing this?
You said there are 15 bytes of data in a packet because it includes the color information for two palettes, but is this totaly necessary if I'm just transfering one palette? Which one of the commands am I supposed to be using anyway?
Lastly, when the game exits the change box screen, how can I make sure it returns to the correct town palette based on the town that the Pokemon Center is in?

Last edited by Danny-E 33 (2012-11-01 04:37:18)

Offline

#79 2012-11-01 16:56:05

Sawakita
Administrator
Registered: 2010-10-16
Post 329/365

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

How can I use a debugger to find where I should add in the extra code for doing this?

You've already done something similar, didn't you? Start at a known point (if you're not sure, ROM/RAM maps and the disassembly are a huge source of information, and this forum itself is too), and step forward/backtrack from there (it's breakpoints all the way down).

Danny-E 33 wrote:

Which one of the commands am I supposed to be using anyway?
Lastly, when the game exits the change box screen, how can I make sure it returns to the correct town palette based on the town that the Pokemon Center is in?

I think I've already told you:

Sawakita wrote:

TL;DR
So, what you should need is define a PAL_SET packet with the color you want, somewhere in bank 0x1C. Right before the Bill's box list opens you inject your code where you load the pointer, that points to your custom PAL_SET packet, in HL and call the routine that sends SGB packets (1c:5feb). Likewise, when the box-list is closed you reload the map's specific palette.
The game as is, provides a set of routines (addressable by ID, since they are listed in a pointer table) that load PAL_SET and ATTR_BLK for all the needs (in-battle, overworld, town-map, etc.). To call one of these routines you load the predefined routine ID into b (for example the one that loads overworld-map-specific packets is 0x09) and call routine 0x3def, like this:

; Launch predefined PAL_SET + ATTR_BLK packet sending routine
    ld b, 9
    call $3def

Offline

#80 2012-11-02 02:48:25

Danny-E 33
Administrator
Registered: 2012-06-09
Post 235/1,149

Re: Pokemon Red: Palettes

Okay, so here's the description of PAL_SET:

SGB Command 0Ah - PAL_SET
Used to copy pre-defined palette data from SGB system color palette to actual SGB palette.
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1-2   System Palette number for SGB Color Palette 0 (0-511)
  3-4   System Palette number for SGB Color Palette 1 (0-511)
  5-6   System Palette number for SGB Color Palette 2 (0-511)
  7-8   System Palette number for SGB Color Palette 3 (0-511)
  9     Attribute File
          Bit 0-5 - Attribute File Number (00h-2Ch) (Used only if Bit7=1)
          Bit 6   - Cancel Mask           (0=No change, 1=Yes)
          Bit 7   - Use Attribute File    (0=No, 1=Apply above ATF Number)
  A-F   Not used (zero)

So is this what we've been calling a packet this whole time..?
So byte zero of my packet would be 0x0A*0x08+(length?). What is length here? Is it the number of bytes of this packet? So 0x0A? So 0x0A*0x08+0x0A=0x5A?
Then the next 8 bytes are simply the four palette colors. So this would be a copy of what the 8 bytes are for the red health bar palette from the palette table, correct?
And could someone explain the Attribute File byte, please? For instance, what is the Attribute File Number (0x00-0x2C) for? And what is the Cancel Mask for?

Once I fill in the blanks, the packet should be done, yes?

But I'm a bit confused on some things. Are there even any predefined packets in the game? Or is every packet "empty" and then somehow filled in with a palette from the palette table?

Also, I still don't think I would know how to switch the palette back to the correct OW town palette.. is there a simple enough way to do this?

One last thing. I know "&" is the operations symbol for "and". I think I've started to pick up on "|" means "or", is that correct? And what does "<<" mean??

Offline

#81 2012-11-02 03:10:22

stag019
Idea Killer
Registered: 2011-01-05
Post 233/630

Re: Pokemon Red: Palettes

>> and << are bit shifts (right and left respectively)

If you don't know what a bitshift is:

Say you had to solve (0x98 >> 2).
0x98 in binary is 10011000. To shift it twice to the right, you remove the last two bits, to get 100110, which in hex is 26. Whenever you shift left, you add 0 bits on the right (0x98 << 2 = 1001100000 = 0x260, which may or may not be truncated to 01100000 = 0x60 depending on the circumcisions).

Also, you may see ^ which is XOR.


You can try to hide yourself in this world of pretend; when the paper's crumpled up, it can't be perfect again.

Offline

#82 2012-11-02 03:28:09

Danny-E 33
Administrator
Registered: 2012-06-09
Post 237/1,149

Offline

#83 2012-11-02 05:40:39

542/704

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

One last thing. I know "&" is the operations symbol for "and". I think I've started to pick up on "|" means "or", is that correct? And what does "<<" mean??

It’s worth noting that these usages come from C.

#84 2012-11-02 11:34:41

Danny-E 33
Administrator
Registered: 2012-06-09
Post 239/1,149

Re: Pokemon Red: Palettes

Oooh. I really ought to get around to learning C..
But how come we use the notation for bitwise and, bitwise or, etc. but I always hear us say logical and, logical or, etc. which has different notation? What's the difference?

Offline

#85 2012-11-02 19:19:42

Tauwasser
Member
Registered: 2010-10-16
Post 316/458

Re: Pokemon Red: Palettes

Operations are called bitwise when talking about binary operations. This is contrary to logical operations, which involve truth values. For instance:

Bitwise and: (0xA0 and 0x80) = 0x80
Logical and: (0x05 == variableA and 0x07 == variableB) = false

This naming scheme is of course not diametrical. For instance, there are also arithmetic operations, which work on native number representations inside their corresponding CPUs. For example:

Logical shift right: sll 0xA0, 1 = 0xA0 >>> 1 = 0x50
Arithmetic shift right: sla 0xA0, 1 = 0xA0 >> 1 = D0

The latter works, because the most significant bit (in my representations) is the sign bit, hence 0xA0 = -96, while 0xD0 = -48. Notice that logical shifts are bitwise operations.

You should probably read some introductory material before continuing down this path. These are really basic questions and you will need to understand a lot more before you meddle with the inner workings of any game.

cYa,

Tauwasser

Last edited by Tauwasser (2012-11-02 23:51:49)

Offline

#86 2012-11-02 19:51:01

543/704

Re: Pokemon Red: Palettes

Tauwasser wrote:

Operations are called logical when talking about binary operations. This is contrary to boolean operations, which involve truth values. For instance:

Logical and: (0xA0 and 0x80) = 0x80
Boolean and: (0x05 == variableA and 0x07 == variableB) = false

You have this reversed: at least in C, the logical operators are the ones used in conditionals (e.g., “if (a == b && c != d)”). “Boolean” is broad enough to apply to either case; the non‐logical operators are usually called “bitwise”. (By definition, “logical” is also broad enough to refer to both, but in practice it mostly refers to the kind used in conditionals.)

#87 2012-11-02 23:05:10

Danny-E 33
Administrator
Registered: 2012-06-09
Post 240/1,149

Re: Pokemon Red: Palettes

Okay, well that would explain things.
IIMarckus, Sawakita, do you have any further explination on SGB packets? I'm still not very close to fully understanding.

Offline

#88 2012-11-02 23:48:27

Tauwasser
Member
Registered: 2010-10-16
Post 318/458

Re: Pokemon Red: Palettes

Well, I guess I shouldn't reply past my bedtime :] Also, I swear I looked this up before finally hitting the post button and the Wikipedia page looked very different to my sleepy eyes... :(

cYa,

Tauwasser

Last edited by Tauwasser (2012-11-02 23:49:02)

Offline

#89 2012-11-03 00:30:38

Sawakita
Administrator
Registered: 2010-10-16
Post 330/365

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

Okay, so here's the description of PAL_SET:

SGB Command 0Ah - PAL_SET
Used to copy pre-defined palette data from SGB system color palette to actual SGB palette.
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1-2   System Palette number for SGB Color Palette 0 (0-511)
  3-4   System Palette number for SGB Color Palette 1 (0-511)
  5-6   System Palette number for SGB Color Palette 2 (0-511)
  7-8   System Palette number for SGB Color Palette 3 (0-511)
  9     Attribute File
          Bit 0-5 - Attribute File Number (00h-2Ch) (Used only if Bit7=1)
          Bit 6   - Cancel Mask           (0=No change, 1=Yes)
          Bit 7   - Use Attribute File    (0=No, 1=Apply above ATF Number)
  A-F   Not used (zero)

So is this what we've been calling a packet this whole time..?

This is one of the possible SGB packets.

Danny-E 33 wrote:

So byte zero of my packet would be 0x0A*0x08+(length?).

I really dislike that representation of byte 0. Although semantically correct, in my opinion it's formally inaccurate. And that's why I prefer another form, more adherent to the way the ASM routine decodes it:

byte 0 := (SGB Packet type ID) << 3 | (number of packets)

Also, PAL_SET sets all the (four) active palettes at once, so it makes no sense sending more than a single packet at once.

Danny-E 33 wrote:

What is length here? Is it the number of bytes of this packet? So 0x0A? So 0x0A*0x08+0x0A=0x5A?

No, what they call length is actually the number of packets (these following packets aren't preceeded by the aformentioned mini-header). The first byte of a PAL_SET packet should always be:

0x51 ← (0x0A << 3 | 1)
Danny-E 33 wrote:

Then the next 8 bytes are simply the four palette colors. So this would be a copy of what the 8 bytes are for the red health bar palette from the palette table, correct?

No, as I've already told you, in PAL_SET you specify the IDs of the palettes you want to load among the ones that have been loaded, at the beginning of the game, via the PAL_TRN packet.

Danny-E 33 wrote:

And could someone explain the Attribute File byte, please? For instance, what is the Attribute File Number (0x00-0x2C) for? And what is the Cancel Mask for?

You ain't gonna need it, because RGBY don't use it (as a consequence of not using ATTR_TRN), and just put a zero in that byte's place in PAL_SET packets. If you are interested anyway I (or someone else) will explain it, in case the documentation (that you already can read) isn't clear enough.

Danny-E 33 wrote:

Once I fill in the blanks, the packet should be done, yes?

But I'm a bit confused on some things. Are there even any predefined packets in the game? Or is every packet "empty" and then somehow filled in with a palette from the palette table?

Already mentioned. Twice.

Danny-E 33 wrote:

Also, I still don't think I would know how to switch the palette back to the correct OW town palette.. is there a simple enough way to do this?

Already explained, twice (I provided explicit code, which you'll agree is simple, since it's just two ASM instructions).

Offline

#90 2012-11-03 13:19:03

Danny-E 33
Administrator
Registered: 2012-06-09
Post 241/1,149

Re: Pokemon Red: Palettes

Sawakita wrote:
Danny-E 33 wrote:

Okay, so here's the description of PAL_SET:

SGB Command 0Ah - PAL_SET
Used to copy pre-defined palette data from SGB system color palette to actual SGB palette.
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1-2   System Palette number for SGB Color Palette 0 (0-511)
  3-4   System Palette number for SGB Color Palette 1 (0-511)
  5-6   System Palette number for SGB Color Palette 2 (0-511)
  7-8   System Palette number for SGB Color Palette 3 (0-511)
  9     Attribute File
          Bit 0-5 - Attribute File Number (00h-2Ch) (Used only if Bit7=1)
          Bit 6   - Cancel Mask           (0=No change, 1=Yes)
          Bit 7   - Use Attribute File    (0=No, 1=Apply above ATF Number)
  A-F   Not used (zero)

So is this what we've been calling a packet this whole time..?

This is one of the possible SGB packets.

Well to be fair, this is where so much of my confusion was coming from. This was always called a command. It was never explained that it was a packet. Until now, I didn't know what a palette was supposed to look like at all cause I didn't know the structure of a command and a packet were the same thing. No one told me. I'm sorry it wasn't so obvious to me. Can you blame me for getting confused?

Sawakita wrote:
Danny-E 33 wrote:

So byte zero of my packet would be 0x0A*0x08+(length?).

I really dislike that representation of byte 0. Although semantically correct, in my opinion it's formally inaccurate. And that's why I prefer another form, more adherent to the way the ASM routine decodes it:

byte 0 := (SGB Packet type ID) << 3 | (number of packets)

Also, PAL_SET sets all the (four) active palettes at once, so it makes no sense sending more than a single packet at once.

Danny-E 33 wrote:

What is length here? Is it the number of bytes of this packet? So 0x0A? So 0x0A*0x08+0x0A=0x5A?

No, what they call length is actually the number of packets (these following packets aren't preceeded by the aformentioned mini-header). The first byte of a PAL_SET packet should always be:

0x51 ← (0x0A << 3 | 1)

Okay, that all makes sense.

Sawakita wrote:
Danny-E 33 wrote:

Then the next 8 bytes are simply the four palette colors. So this would be a copy of what the 8 bytes are for the red health bar palette from the palette table, correct?

No, as I've already told you, in PAL_SET you specify the IDs of the palettes you want to load among the ones that have been loaded, at the beginning of the game, via the PAL_TRN packet.

Oh my gosh! I'm really sorry. Hopefully you will understand what was confusing me and understand that it messed up alot of things in my head which is why none of what I've been saying has made any sense.. In the PAL_SET command, there are two bytes (as you said) for the 4 palette IDs.

Byte  Content
  0     Command*8+Length (fixed length=1)
  *1-2   System Palette number for SGB Color Palette 0 (0-511)*
  *3-4   System Palette number for SGB Color Palette 1 (0-511)*
  *5-6   System Palette number for SGB Color Palette 2 (0-511)*
  *7-8   System Palette number for SGB Color Palette 3 (0-511)*
  9     Attribute File
          Bit 0-5 - Attribute File Number (00h-2Ch) (Used only if Bit7=1)
          Bit 6   - Cancel Mask           (0=No change, 1=Yes)
          Bit 7   - Use Attribute File    (0=No, 1=Apply above ATF Number)
  A-F   Not used (zero)

Until now, I thought those were supposed to be two bytes each of the actual palette information. Like, each two bytes was the RGB number of that color, and all four were colors 0, 1, 2, and 3 of an entire palette that all goes straight into a packet... Hopefully you'll understand that it caused me to be very confused... I'm sorry.

Sawakita wrote:
Danny-E 33 wrote:

Once I fill in the blanks, the packet should be done, yes?

But I'm a bit confused on some things. Are there even any predefined packets in the game? Or is every packet "empty" and then somehow filled in with a palette from the palette table?

Already mentioned. Twice.

Again, it makes perfect sense to me now that my confusion is gone. I'm really sorry..

Sawakita wrote:
Danny-E 33 wrote:

Also, I still don't think I would know how to switch the palette back to the correct OW town palette.. is there a simple enough way to do this?

Already explained, twice (I provided explicit code, which you'll agree is simple, since it's just two ASM instructions).

Yeah, I had forgot that part. In my defense, I've had so much information thrown at me.. And so much extraneous information.. It's been real hard to keep any of it straight. I'm sorry for not being able to keep up with this confusing mess..

I think I know what the packet is supposed to look like now. All that's left is finding where to inject this code appropriately. I'll try this out on my own for a while and let you know what I come up with.

Thank you for all your patience.

Offline

#91 2012-11-07 17:04:39

Danny-E 33
Administrator
Registered: 2012-06-09
Post 250/1,149

Re: Pokemon Red: Palettes

Well I tried finding the location of how the Box list is loaded using a similar process like the Scavenger hunt but I can't figure it out.
I play the game normally until I get to the point that it prompts a Yes/No box and displays "Is that okay?".
Then I added an access breakpoint at FF00 and press F7 until I get to line 018F and change the value in register a to DE to simulate pressing the A button.
Then I put an access breakpoint at FFF8 for when it checks if the A button was pressed.
But I don't know what to do from here. I can't follow along with the code.
And how come address 02B4 is executed like a hundred times in a row?? O_o

Offline

#92 2012-11-09 14:51:53

Sawakita
Administrator
Registered: 2010-10-16
Post 333/365

Re: Pokemon Red: Palettes

You might have more luck if you try to break into the code at a higher level than the I/O port handler.

If you look into the disassembly you can find out that there's a routine, at address 0x1922, that draws textboxes on the "screen buffer" (RAM:c3a0-c507). It can help your research because you want to break into the code right before the textbox that shows the twelve PC boxes is displayed.
If you set a breakpoint at the address 0x1922 you can find where the calling code is, and try to figure out from there (although you'll notice it's called several times before the "PC boxes" textbox is displayed, because several "dialog boxes" and "yes/no boxes" are displayed before).

You might also look (in the disassembly) where the saving routine is at, and set a breakpoint for when it's called (because it's called right before the PC boxes list is loaded). It should be somewhere in bank 0x1C.

Danny-E 33 wrote:

And how come address 02B4 is executed like a hundred times in a row?? O_o

Actually, 0x02B4 is not code, it's data (it's in the area where map pointers are stored).

Offline

#93 2012-11-09 16:16:59

Danny-E 33
Administrator
Registered: 2012-06-09
Post 252/1,149

Re: Pokemon Red: Palettes

Sawakita wrote:

You might have more luck if you try to break into the code at a higher level than the I/O port handler.

If you look into the disassembly you can find out that there's a routine, at address 0x1922, that draws textboxes on the "screen buffer" (RAM:c3a0-c507). It can help your research because you want to break into the code right before the textbox that shows the twelve PC boxes is displayed.
If you set a breakpoint at the address 0x1922 you can find where the calling code is, and try to figure out from there (although you'll notice it's called several times before the "PC boxes" textbox is displayed, because several "dialog boxes" and "yes/no boxes" are displayed before).

I'll try this out when I get home.

Sawakita wrote:

You might also look (in the disassembly) where the saving routine is at, and set a breakpoint for when it's called (because it's called right before the PC boxes list is loaded). It should be somewhere in bank 0x1C.

Isn't the save routine called right after PC boxes list is loaded? Before it's loaded, it asks if it's okay to save. But it doesn't save until you've chosen a new box. Right? So wouldn't this be a good way of finding where to put the second palette change to return the palette to the OW palette?

Sawakita wrote:
Danny-E 33 wrote:

And how come address 02B4 is executed like a hundred times in a row?? O_o

Actually, 0x02B4 is not code, it's data (it's in the area where map pointers are stored).

I don't really understand. I've run across this alot of times before this in the debugger. When I'm pressing F7 to go only one line at a time, I end up at 0x02B4 and continue pressing F7 but it keeps executing the same line.. And each time, I see all the random looking numbers at the right side of the debugging screen change but I don't know what any of these numbers mean.
If you say it's just data, why is the executing line even show up there?

Offline

#94 2012-11-11 00:58:28

Sawakita
Administrator
Registered: 2010-10-16
Post 334/365

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

Isn't the save routine called right after PC boxes list is loaded? Before it's loaded, it asks if it's okay to save. But it doesn't save until you've chosen a new box. Right? So wouldn't this be a good way of finding where to put the second palette change to return the palette to the OW palette

Likely. I haven't checked.

Danny-E 33 wrote:
Sawakita wrote:
Danny-E 33 wrote:

And how come address 02B4 is executed like a hundred times in a row?? O_o

Actually, 0x02B4 is not code, it's data (it's in the area where map pointers are stored).

I don't really understand. I've run across this alot of times before this in the debugger. When I'm pressing F7 to go only one line at a time, I end up at 0x02B4 and continue pressing F7 but it keeps executing the same line.. And each time, I see all the random looking numbers at the right side of the debugging screen change but I don't know what any of these numbers mean.
If you say it's just data, why is the executing line even show up there?

I'm very positive that you don't mean 0x2B4, but 0x20B4 instead, which is part of the routine that waits for a VBlank interrupt to occur (which happens averagely once every 60 millisecond).

Offline

#95 2012-11-11 03:08:47

Danny-E 33
Administrator
Registered: 2012-06-09
Post 255/1,149

Re: Pokemon Red: Palettes

Sawakita wrote:
Danny-E 33 wrote:
Sawakita wrote:

Actually, 0x02B4 is not code, it's data (it's in the area where map pointers are stored).

I don't really understand. I've run across this alot of times before this in the debugger. When I'm pressing F7 to go only one line at a time, I end up at 0x02B4 and continue pressing F7 but it keeps executing the same line.. And each time, I see all the random looking numbers at the right side of the debugging screen change but I don't know what any of these numbers mean.
If you say it's just data, why is the executing line even show up there?

I'm very positive that you don't mean 0x2B4, but 0x20B4 instead, which is part of the routine that waits for a VBlank interrupt to occur (which happens averagely once every 60 millisecond).

Oh my gosh! I haate making stupid mistakes. Yes, I mean 0x20B4. But I don't get why the line is executed over and over as I press F7. It's just a load command. What makes it so special that the program counter doesn't increase?

Offline

#96 2012-11-11 13:34:32

Sawakita
Administrator
Registered: 2010-10-16
Post 335/365

Re: Pokemon Red: Palettes

The fact is that it's not executed over and over. If you notice, the preceeding instruction is halt: this command halts code execution, reducing power consumption. No instruction is executed until an interrupt occurs. In that routine's case it's useful because all we want to do is wait for a VBlank interrupt, which means we don't need any code to be executed until that.

Check pandocs' halt description:

GMB CPU-Controlcommands
  ...
  halt           76         N*4 ---- halt until interrupt occurs (low power)

Last edited by Sawakita (2012-11-11 13:37:23)

Offline

#97 2012-11-11 20:49:46

Danny-E 33
Administrator
Registered: 2012-06-09
Post 256/1,149

Re: Pokemon Red: Palettes

Alright! So the call to 0x1922 that is for the Box list text box is at 1C:796C.
If I changed that call at 1C:796C to:

call $66EA

which is the only free space that remains in bank 1C for me, then at 1C:66EA I could write:

ld hl, $66F4 ; address of packet
call $5FEB   ; SendSBGPack
call $1922   ; re-insert the call to the text box drawing routine
ret          ; return to 1C:796F

Then the packet would be at 1C:66F4:

db 51
dw 00 21
dw 00 21
dw 00 21
dw 00 21
dw 00 00
dw 00 00
dw 00 00
db 00

I tried this out and it made the whole screen go black when I open the Box list.. :P
I have a feeling the packet is incorrect. Are the palette ID's referenced correctly and am I supposed to include four of them?

P.S. this was my 0x100th post! :D

Last edited by Danny-E 33 (2012-11-12 05:32:06)

Offline

#98 2012-11-11 21:58:09

Sawakita
Administrator
Registered: 2010-10-16
Post 336/365

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

Alright! So the call to 0x1922 that is for the Box list text box is at 1C:796C.
If I changed that call at 1C:796C to:

call $66EA

which is the only free space that remains in bank 1C for me

1c:66ea is not free space. Instead the typical bank ending's free space begins at 1c:7b9d.

Danny-E 33 wrote:

then at 1C:66EA I could write:

ld hl, $66F4 ; address of packet
call $5FEB   ; SendSBGPack
call $1922   ; re-insert the call to the text box drawing routine
ret          ; return to 1C:796F

Then the packet would be at 1C:66F4:

51
00 21
00 21
00 21
00 21
00 00
00 00
00 00
00

You used big-endian format. You must use little-endian format for 16-bit values (i.e. "00 21" should be "21 00").
Also, you're having another problem. Before calling 0x1922, values for registers b and c are specified. If you insert code between the parameters setup and the routine call, you should preserve registers values (pushing/popping them before/after the inserted code). In this case a simple push bc/pop bc will do the job.

Offline

#99 2012-11-11 22:06:47

558/704

Re: Pokemon Red: Palettes

Danny-E 33 wrote:

dw 00 21

dw takes a single 16‐bit (big‐endian) argument, not two 8‐bit arguments.

#100 2012-11-12 04:24:09

Danny-E 33
Administrator
Registered: 2012-06-09
Post 257/1,149

Re: Pokemon Red: Palettes

Sawakita wrote:
Danny-E 33 wrote:

Alright! So the call to 0x1922 that is for the Box list text box is at 1C:796C.
If I changed that call at 1C:796C to:

call $66EA

which is the only free space that remains in bank 1C for me

1c:66ea is not free space. Instead the typical bank ending's free space begins at 1c:7b9d.

1C:66EA used to be in the middle of the palette table. I moved that table to 0x73BA0 which is the free space you are reffering to and expanded it all the way to the end of the bank.
The table used to start at 1C:6660 but now that location is where my Pokemon/trainer palette assignment routine, player/Ivysaur/Vensaur backsprite palette assignment routine, and trainer palette id assignment table are located. So currently, my very limited free space in bank 1C begins at 1C:66EA.

Sawakita wrote:
Danny-E 33 wrote:

then at 1C:66EA I could write:

ld hl, $66F4 ; address of packet
call $5FEB   ; SendSBGPack
call $1922   ; re-insert the call to the text box drawing routine
ret          ; return to 1C:796F

Then the packet would be at 1C:66F4:

51
00 21
00 21
00 21
00 21
00 00
00 00
00 00
00

You used big-endian format. You must use little-endian format for 16-bit values (i.e. "00 21" should be "21 00").
Also, you're having another problem. Before calling 0x1922, values for registers b and c are specified. If you insert code between the parameters setup and the routine call, you should preserve registers values (pushing/popping them before/after the inserted code). In this case a simple push bc/pop bc will do the job.

You were very right. I just changed all the IDs to little-endian and the palette change worked just fine.
You were also correct in that b and c were specific parameters for the next routine. This caused there to be no text border in the top-left corner around the text telling you what box was currently selected.
However, when push bc and pop bc were added, there was still no text box. hl also contained a specific parameter for the text box drawing routine.
So I changed the code at 1C:66EA to:

push bc
push hl
ld hl, $66F8
call $5FEB
pop hl
pop bc
call $1922
ret

And here is the result! :D
tyIXUnN.png
Thank you for helping make this a reality! Now I'm gonna dive right in and find where to return the palette to the correct OW palette. But I don't think this will be too hard.
Although, I've realized, I don't think I'll know where to inject the routine to correct the OW palette if the player presses the B button and the save routine is never called.
Any tips? I suppose I could try finding more calls to $1922 after the B button is pressed but I don't know if that will be as successful..

EDIT: So after taking a look at the disassembly, I have no idea where the save routine is. There's a line in the disassembly that says:

call Predef ; save the game

and that call is to 0x3E6D. But that is certainly not the save routine.
I feel like the disassembly may be full of tons of information, but it is just impossible to navigate. I don't know, maybe I'm not doing it right. But any time I've trying looking into it, I've just gotten confused and frustrated cause there's no easy way to find anything I'm looking for. Is there supposed to be an easy way to take advantage of what's in the disassembly?

And trying to use calls to 0x1922 when exiting the Box list isn't helpful because the same calls are used for both entering and exiting to the previous menu.

Last edited by Danny-E 33 (2013-06-08 11:34:54)

Offline

Board footer

Powered by FluxBB