News: 11 March 2016 - Forum Rules

Author Topic: The Minucce Yard  (Read 14643 times)

ShadowOne333

  • Hero Member
  • *****
  • Posts: 1727
    • View Profile
Re: The Minucce Yard
« Reply #80 on: November 19, 2021, 10:49:15 am »
Given how Zelda 2 allows more colors, I made some compromises and design changes.



https://github.com/minucce/workbox/blob/9c18924c360df4df273c41c5956f5f373bf00532/box17/menu_tweaks.ips

Nearly over but I could not draw a '?'; always looked terrible. Otherwise I think it's about release grade quality.

----

(...) When time allows. Zelda 2 ate a lot of time. :angel:

Oh man, I didn't know you were working on the Zelda 2 stuff already! :O
I gave it a test, and it looks great so far!

For the "?" thing, that one should be easy to address.
I took your IPS, patched it over and then further hacked it to implement a proper question mark into the PPU.
Here:
https://ufile.io/c3gg62cg

You can try it out with Copy and Erase, the question mark should appear now in each sentence and for all combinations possible :D

The way I did was as follows:
Zelda 2 separates its graphics into CHR banks depending on what will be loaded on screen.
The Title Screen and File Select screens use a specific CHR bank, which is exclusive to those screens only.
So, for this instance, I removed the "Small Key" graphic from the title screen CHR graphics, since the Small Key sprite isn't needed for the title screen nor the File Select at all, only when you get in-game it's needed, and replaced it with the custom "?" question mark I made way long ago that's being used for Town graphics/CHR.

The new "?" uses Tile ID $39 for background graphics, so I used $B9 instead of $BA that you were using for the dash, and that was it.
So if you want, simply replace the dash with Hex value $B9, and I'll handle the whole CHR stuff on my end, so you don't have to bother with the graphics editing.

I might also include both the comma and the new question mark into the Character box later on, but that's something for me to work on later, right now you've gone above and beyond with this project and Zelda 1, to the point where everything I wanted for both projects would now be complete.

Give the new changes a try, and if you feel comfortable with it, or any other change is required before going forward, let me know and I'll gladly lend a hand however possible.

Thanks again, minucce, can't thank you enough for all this work!


minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #81 on: November 19, 2021, 01:17:17 pm »
The "?" was the final piece holding it back. I'm greatly satisfied with how Zelda 2 looks. :)
https://github.com/minucce/workbox/raw/81c68a9df74ac64d48df0faf063bdb94c326c769/box17/menu_tweaks.txt

(replaced the - to $b9; no graphics edits since you can snugly fit everything together)

ShadowOne333

  • Hero Member
  • *****
  • Posts: 1727
    • View Profile
Re: The Minucce Yard
« Reply #82 on: November 19, 2021, 07:57:54 pm »
Awesome! Thank you SO much, minucce, seriously!
This was the last feature for Zelda 2 Redux, with it I can now consider it a complete project :D

Here's the transcribed code into xkas format:
https://github.com/ShadowOne333/Zelda2-Redux/blob/master/code/menus/menu_tweaks.asm

I made sure to make a proper byte by byte comparison, so everything should be working fine.
I didn't test the Continue/Save screen, but I'll try it out during the weekend properly.

Thanks again! :D

minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #83 on: November 19, 2021, 08:12:20 pm »
You're actually very welcome to the Redux menus! Personally it was worth my time and effort (and a burden lifted for everyone that worked on it). Thankfully the Zelda engines were flexible enough to handle the minor enhancements.

----

Ys 1 wip demos
https://github.com/minucce/workbox/raw/3af2157ed0a25b5ec990a00eb211edba7600e13b/box18/datchy%20-%20japan.ips  (Ys 1 + Datchy)
https://github.com/minucce/workbox/raw/3af2157ed0a25b5ec990a00eb211edba7600e13b/box18/datchy%20-%20english.ips  (Ys 1 + Datchy + English MakoKnight)


Apply Datchy first. Optional English. Then plus demo. It's unclear if the black burn fix affects other parts of the game or not.. so not full releasing yet.


1) Zepic Village roof fix

==>

Credit to Fray for this one; honestly it never occurred to me that the raw ppu tile is a static roof 8x8 pixel image. But because it shares the water code ($00), this incorrectly triggers the animation also.

Graphic artist likely didn't realize this either.


2) Portrait fixes

Full credit to Fray. Restores lots of missing details by assigning correct black color 0.

+ +

+ + +


As a bonus, Olman's tile corruption fixed by Fray. Sara and Pim's border frames had some color fixes.


Dios has an odd corruption I'm asking about.


That shield looks wrong? Lower-right corner? No idea how to redraw or replace that tile.

SomeOldGuy

  • Full Member
  • ***
  • Posts: 115
  • Game Changer
    • View Profile
Re: The Minucce Yard
« Reply #84 on: November 19, 2021, 11:31:05 pm »
Yes Sir, that tile was jacked up.  Does this look better?



Patch only fixes the one tile:

https://www.mediafire.com/file/8q9zymicrr8ts9e/Ys_-_Fixed_Shield_Tile.ips/file

 ;D
Good times create weak men, weak men create hard times.  Hard times create strong men, strong men create good times...

minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #85 on: November 20, 2021, 12:09:22 am »

Pethronos

  • Jr. Member
  • **
  • Posts: 50
    • View Profile
Re: The Minucce Yard
« Reply #86 on: November 20, 2021, 04:05:26 am »
Hi Minucce! Wow! Impressive both Zeldas works!!

As for that last English patch, which is the right patching order?

Thanks in advance!  :beer: :beer: :beer:

EDIT: Ok, I had forgotten that Datchy font changes are "too agressive" over the translation  :laugh:

Right patching order: Datchy->English->Repair  :thumbsup:

EDIT 2: I don't get the new changes to the girl's face. Datchy's version's black pixels give a different amount of her face's shadow on the neck. It's fine to me as it is (humble opinion)
« Last Edit: November 20, 2021, 04:45:07 am by Pethronos »

minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #87 on: November 20, 2021, 08:27:30 am »
Datchy -> English / Spanish -> Repair


Quote
EDIT 2: I don't get the new changes to the girl's face. Datchy's version's black pixels give a different amount of her face's shadow on the neck. It's fine to me as it is (humble opinion)

I didn't edit Datchy's title screen, so my patching engine is foo'd (and I obviously overlooked it). Let me fix it hopefully today. :(

Thanks for bringing this up quickly! I'll release a Datchy-Spanish-Repair tester also as a bonus.

November 20, 2021, 08:55:28 am - (Auto Merged - Double Posts are not allowed before 7 days.)
https://github.com/minucce/workbox/raw/764c1523dc2ef21699105c31f8c910c2c14915d4/box18/datchy%20-%20japan.ips
https://github.com/minucce/workbox/raw/764c1523dc2ef21699105c31f8c910c2c14915d4/box18/datchy%20-%20english.ips
https://github.com/minucce/workbox/raw/764c1523dc2ef21699105c31f8c910c2c14915d4/box18/datchy%20-%20spanish.ips
« Last Edit: November 20, 2021, 08:55:28 am by minucce »

Pethronos

  • Jr. Member
  • **
  • Posts: 50
    • View Profile
Re: The Minucce Yard
« Reply #88 on: November 20, 2021, 09:41:11 am »
The Minucce Yard, Efficiency at your Service (Repair)  :beer: :thumbsup: :laugh:

ShadowOne333

  • Hero Member
  • *****
  • Posts: 1727
    • View Profile
Re: The Minucce Yard
« Reply #89 on: November 20, 2021, 02:22:54 pm »
Hey Minucce!
I've been playing Z2R, and everything seems good so far!
I did notice that the Continue screen still responds only to the Select button, so I wanted to attempt making the change myself.

The pointer for the routine is at $1C336 (85CA, with the routine itself being at $1CA85).
It seems to be using a comparison towards AND #$30 (possibly Start & Select?), but for some reason changing it to anything else makes the cursor not respond anymore.
This routine seems to load addresses $F7 and $0744 for inputs on Controller #1 (which I wasn't even aware the game used for button input too).

Since the Continue screen only has two options (Continue and Save), I think having both Up and Down behave as Select would do the same, since no matter if you press Up or Down, any of the two would actually end up moving you to the next option lol. So that's why I thought $0C instead of $30 would be the desired value, since Up is $08 and Down is $04, thus the $0C.

I gave it a bit of a debug, and since Bank 0 seems to load up when this screen appears, I decided to change the pointer from 85CA to 00AE ($2E00), and copied the entirety of the code from $1CA85 up to $1CB17. (I made this change because Bank 7 is already bloated as hell with no free space to work with).
I changed both ANDs at $1CA87 and $1CA90 to a AND #$0C, and I made 4 ASLs instead of the 2 in that routine, since I think the result in accumulator should be $80 in order for the cursor to actually move.
I tried doing just that, changing the pointer to 00 AE and moving the entirety of the code to $2E00, with the changed ANDs and the added ASLs in there, and sure enough, pressing Up does move the cursor now, however Start now no longer responds, and pressing Down behaves as Start haha.

I was wondering if you might have any suggestions in this regard. I do admit my ASM skills are not the most knowledgeable of all, but I try my best to understand the little bit I do know to attempt things on my own.

Here's the modified routine I had at $2E00 btw:
Spoiler:
0000   A5 F7                LDA $F7
0002   29 0C                AND #$0C
0004   0A                   ASL A
0005   0A                   ASL A
0006   0A                   ASL A
0007   0A                   ASL A
0008   85 00                STA $00
000A   AD 44 07             LDA $0744
000D   29 0C                AND #$0C
000F   0A                   ASL A
0010   0A                   ASL A
0011   0A                   ASL A
0012   0A                   ASL A
0013   C5 00                CMP $00
0015   F0 5E                BEQ L0075
0017   24 00                BIT $00
0019   50 5B                BVC L0076
001B   20 A0 D3             JSR $D3A0
001E   C9 FF                CMP #$FF
0020   F0 03                BEQ L0025
0022   EE 9F 07             INC $079F
0025   A2 0F      L0025     LDX #$0F
0027   A9 00                LDA #$00
0029   95 E0      L0029     STA $E0,X
002B   CA                   DEX
002C   10 FB                BPL L0029
002E   A0 C0                LDY #$C0
0030   99 00 07   L0030     STA $0700,Y
0033   C8                   INY
0034   D0 FA                BNE L0030
0036   AD 88 04             LDA $0488
0039   F0 08                BEQ L0043
003B   A9 40                LDA #$40
003D   8D B0 07             STA $07B0
0040   4C 05 CF             JMP $CF05
0043   8D 75 07   L0043     STA $0775
0046   8D 76 07             STA $0776
0049   8D 56 07             STA $0756
004C   8D 55 07             STA $0755
004F   20 10 AB             JSR $AB10
0052   C9 03                CMP #$03
0054   B0 07                BCS L005D
0056   A9 00                LDA #$00
0058   A0 01                LDY #$01
005A   4C F0 CA             JMP $CAF0
005D   20 14 AB   L005D     JSR $AB14
0060   A9 00                LDA #$00
0062   EA                   NOP
0063   EA                   NOP
0064   EA                   NOP
0065   8D 01 07             STA $0701
0068   8D 5C 07             STA $075C
006B   A9 01                LDA #$01
006D   A0 02                LDY #$02
006F   8D 6C 07             STA $076C
0072   8C 5F 07             STY $075F
0075   60         L0075     RTS
0076   10 FD      L0076     BPL L0075
0078   A9 10                LDA #$10
007A   85 EF                STA $EF
007C   A0 06                LDY #$06
007E   B9 74 69   L007E     LDA $6974,Y
0081   99 02 03             STA $0302,Y
0084   88                   DEY
0085   10 F7                BPL L007E
0087   AD 88 04             LDA $0488
008A   49 01                EOR #$01
008C   8D 88 04             STA $0488
008F   0A                   ASL A
0090   A8                   TAY
0091   A9 9C                LDA #$9C
0093   99 05 03             STA $0305,Y
0096   60                   RTS

minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #90 on: November 20, 2021, 02:53:43 pm »
Honestly forgot about Game Over routine.

Code: [Select]
07:ca85

lda $f7 ; current input
cmp $744 ; previous input
beq $caf6 ; wait for unique press

and #$10 ; start = confirm
bne $ca9c

lda $f7 ; down, up, select = move cursor
and #($04|$08|$20)
beq $caf6
bne $caf9

nop #4

warnpc $ca9c


They move cursor on button release (adds delay); I changed it to button press. Old method of bit testing (znv flags) are overly complicated; do directly.

November 20, 2021, 03:38:26 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
I'd better explain old code some more.


and #$30 = select (20), start (10)
asl = select(40), start(20)
asl = select(80), start(40)
-- note: this only sets the (z)ero, (n)egative, (c)arry


If you "bit $f7", then it sets (o)verflow and (n)egative
- (o)verflow = $40 (implies start)
- (n)egative = $80 (implies select)


This won't work for d-pad (08, 04, 02, 01) ==> (20, 10, 08, 04).


EDIT:
You're right. Another two "asl" would shift up, down into 80,40 range. So it would be like .

asl
asl

asl (select = carry, start = 80, up = 40, down = 20)
bcs ==> cursor routine (select)
bmi ==> button routine (start)
bvs ==> cursor routine (up)

asl (start = carry, up = 80, down = 40)
bcs ==> button routine (start)
bmi ==> cursor routine (up)
bvs ==> cursor routine (down)

Complicated but workable.

November 21, 2021, 10:01:21 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
RoboCop - ED-209


It can walk backwards now. Hopefully SomeOldGuy can submit the other 4 walking chr + tilemaps to complete the loop.

There's still some stray bugs to wrinkle out and post-battle retreating animation uses old chr banks.

It also walks closer to left edge. And garbage tiles when restarting the walk is gone.
« Last Edit: November 21, 2021, 10:01:21 pm by minucce »

ShadowOne333

  • Hero Member
  • *****
  • Posts: 1727
    • View Profile
Re: The Minucce Yard
« Reply #91 on: November 22, 2021, 01:31:34 pm »
Honestly forgot about Game Over routine.

Code: [Select]
07:ca85

lda $f7 ; current input
cmp $744 ; previous input
beq $caf6 ; wait for unique press

and #$10 ; start = confirm
bne $ca9c

lda $f7 ; down, up, select = move cursor
and #($04|$08|$20)
beq $caf6
bne $caf9

nop #4

warnpc $ca9c


They move cursor on button release (adds delay); I changed it to button press. Old method of bit testing (znv flags) are overly complicated; do directly.

Sorry I took a brief break during the weekend.
I tested this out, and it works nicely!
I'll push the changes to the repository and if nothing arises, I'll send the update to the RH.net page for Zelda 2 Redux.

I'd better explain old code some more.


and #$30 = select (20), start (10)
asl = select(40), start(20)
asl = select(80), start(40)
-- note: this only sets the (z)ero, (n)egative, (c)arry


If you "bit $f7", then it sets (o)verflow and (n)egative
- (o)verflow = $40 (implies start)
- (n)egative = $80 (implies select)


This won't work for d-pad (08, 04, 02, 01) ==> (20, 10, 08, 04).


EDIT:
You're right. Another two "asl" would shift up, down into 80,40 range. So it would be like .

asl
asl

asl (select = carry, start = 80, up = 40, down = 20)
bcs ==> cursor routine (select)
bmi ==> button routine (start)
bvs ==> cursor routine (up)

asl (start = carry, up = 80, down = 40)
bcs ==> button routine (start)
bmi ==> cursor routine (up)
bvs ==> cursor routine (down)

Complicated but workable.

Oh so part of what I did actually worked?
Now that you explain it, I do get why Down was being registered as Start now.
It's because 04 is one bit to the right of 08 (Up), that's why it was being registered as being Start, and Start no longer working. It partially worked, but not fully, and now I see why.

Thanks again for the extra work, and for the explanation! It certainly helped me understand better what that part of the code was doing, and it's good to know my attempt wasn't entirely a misstep.

As a side (and possible more personal) question, I was wondering, how many assembly languages do you know?
And how did you end up learning them throughout the years?
I am really curious as to how you managed to get that much experience with all this.
Of course, it's just a curious question, it's okay if you don't want to respond to it :P
« Last Edit: November 22, 2021, 01:51:17 pm by ShadowOne333 »

minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #92 on: November 22, 2021, 04:23:46 pm »
Nothing professional, just a self-taught hobby. Tried everything (graphics, sound, japanese, programming) - was terrible at all of them. Got tired of asking others and being shamed (vanity projects), so I forced myself to slowly learn code (6502, z80, 68000, 65c816, x86, *mips, *arm, *risc, *??) as it seemed like something I could level up. Depended on what system at the time (there's lots).


Over time, tried lots of different things. Cheats, trainers, basic protection, bugfix, unlockers, anti-hacking, improvements, briefly translations, emulators. Whatever I wanted at the immediate time. But I've learned not to work with others as I greatly disliked the disruptive conflicts that came up (there's many burned in my mind, one about catching a cheating partner and expecting *me!!?* to do something about it).


That aside, I still make lots of asm mistakes. Plenty. Over time you start to get a "muscle memory" of what not to do anymore for awhile. And I tend to forget a lot about the other systems I'm not working on. :laugh:

I don't have any tricks on how to get better at coding, other than failure and reading others' work, then experimenting plus understanding what goofy logic they used. Reading an opcode or technical manual does nothing for me unless I have a visual thinking what's going on.


EDIT:
And people greatly overestimate my skill level. There's lots I'm not capable of.

ShadowOne333

  • Hero Member
  • *****
  • Posts: 1727
    • View Profile
Re: The Minucce Yard
« Reply #93 on: November 22, 2021, 05:58:49 pm »
Nothing professional, just a self-taught hobby. Tried everything (graphics, sound, japanese, programming) - was terrible at all of them. Got tired of asking others and being shamed (vanity projects), so I forced myself to slowly learn code (6502, z80, 68000, 65c816, x86, *mips, *arm, *risc, *??) as it seemed like something I could level up. Depended on what system at the time (there's lots).


Over time, tried lots of different things. Cheats, trainers, basic protection, bugfix, unlockers, anti-hacking, improvements, briefly translations, emulators. Whatever I wanted at the immediate time. But I've learned not to work with others as I greatly disliked the disruptive conflicts that came up (there's many burned in my mind, one about catching a cheating partner and expecting *me!!?* to do something about it).


That aside, I still make lots of asm mistakes. Plenty. Over time you start to get a "muscle memory" of what not to do anymore for awhile. And I tend to forget a lot about the other systems I'm not working on. :laugh:

I don't have any tricks on how to get better at coding, other than failure and reading others' work, then experimenting plus understanding what goofy logic they used. Reading an opcode or technical manual does nothing for me unless I have a visual thinking what's going on.


EDIT:
And people greatly overestimate my skill level. There's lots I'm not capable of.

Oh wow, so you've basically learned assembly through self-taught process?
That's quite the achievement, and more so the number of assembly languages you have tackled, it's impressive.
I barely know my way through basic 6502, 65816 I kinda understand but pretty basic, and MIPS is something I can only dream of for my OoT/MM projects lol. I have tried learning more, but the most I can understand is 6502 to an extend.

I can relate to your experiences working with other people, I've had my few shares of unpleasant moments as well, and in this regard it is better to work at your own leisure and time frame.

It's always interesting to hear how someone delved into this kind of scene, and what gave the push to continue learning and working on it. Thanks for the response!

PS: Don't worry, people overestimate what I can do too, a lot :laugh:
But your work certainly impresses time and time again, more so since not many in this community are willing to do some sort of public or community work, much less for free, so that's really appreciated.

minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #94 on: November 22, 2021, 07:54:58 pm »
I do get lots of private requests, which enough don't publicly end up in the Yard. Nothing to show off yet for the Konami SGB borders (which I'm actively working on and have mapped out).


It's good that you can see the error you made with Z2 menu, and was able to redesign afterward. That's promising because that's how I learn to get asm better, from fixing my own mess of mistakes.

But I am interested in the Z1 hearts routine, as in trying to guide you through this one for a (slow) learning exercise. Let's start with what (you) already know (not like I know everything either).


0) Started a new game, lost some life, and manual save. Clicked "save" and save state before it ends.


1) We know hearts are at $66f and $670. Put read breakpoint and you should end at 05:8B6D.

Code: [Select]
>05:8B6D: AD 6F 06  LDA $066F = #$22
 05:8B70: 29 F0     AND #$F0
 05:8B72: 09 02     ORA #$02
 05:8B74: 8D 6F 06  STA $066F = #$22


 05:8B77: A9 FF     LDA #$FF
 05:8B79: 8D 70 06  STA $0670 = #$7F

Looks important!


2) Another read takes us here

Code: [Select]
>02:A6C6: B9 57 06  LDA $0657,Y @ $0670 = #$7F
 02:A6C9: 91 C0     STA ($C0),Y @ $68D9 = #$00
 02:A6CB: 88        DEY
 02:A6CC: 10 F8     BPL $A6C6

You've possibly seen this before.


3) Then we end up here.

Code: [Select]
>02:A6F3: AD 6F 06  LDA $066F = #$22
 02:A6F6: 29 F0     AND #$F0
 02:A6F8: 48        PHA
 02:A6F9: 4A        LSR
 02:A6FA: 4A        LSR
 02:A6FB: 4A        LSR
 02:A6FC: 4A        LSR
 02:A6FD: 85 0A     STA $0A = #$19

 02:A6FF: 68        PLA
 02:A700: 05 0A     ORA $0A = #$19
 02:A702: 8D 6F 06  STA $066F = #$22

 02:A705: A9 FF     LDA #$FF
 02:A707: 8D 70 06  STA $0670 = #$7F

 02:A70A: 20 19 A8  JSR $A819

Code: [Select]
>02:A819: A4 16     LDY $16 = #$01
 02:A81B: B9 A1 A6  LDA $A6A1,Y @ $A7A0 = #$48
 02:A81E: 85 0C     STA $0C = #$40
 02:A820: B9 A4 A6  LDA $A6A4,Y @ $A7A3 = #$48
 02:A823: 85 0D     STA $0D = #$06


 02:A825: A0 01     LDY #$01
>02:A827: B9 6F 06  LDA $066F,Y @ $0670 = #$7F
 02:A82A: 91 0C     STA ($0C),Y @ $0653 = #$FF ====
 02:A82C: 88        DEY
 02:A82D: 10 F8     BPL $A827
 02:A82F: 60        RTS -----------------------------------------

Okay. That's more interesting.

I marked A82A as I thought it was interesting.


4) I chose to stop refilling $670 and got a crash. So I looked at 0653.

Code: [Select]
02:A509: B9 50 06  LDA $0650,Y @ $0653 = #$7F
 02:A50C: 85 0E     STA $0E = #$22
 02:A50E: C8        INY
>02:A50F: B9 50 06  LDA $0650,Y @ $0653 = #$7F
 02:A512: 85 0F     STA $0F = #$00


Code: [Select]
>  :6EC4: A5 0F     LDA $0F = #$7F
   :6EC6: F0 0D     BEQ $6ED5
   :6EC8: C9 C0     CMP #$C0
   :6ECA: B0 F4     BCS $6EC0
   :6ECC: A9 00     LDA #$00
   :6ECE: 8D 29 05  STA $0529 = #$00
   :6ED1: 4C BC BE  JMP $BEBC


 02:BEBC: FF        UNDEFINED
 02:BEBD: FF        UNDEFINED
 02:BEBE: FF        UNDEFINED
 02:BEBF: FF        UNDEFINED
 02:BEC0: FF        UNDEFINED
 02:BEC1: FF        UNDEFINED


I'll stop here. If you have questions about any code or answers to give, ask away.


EDIT:
Something I thought about. How do I actually do these things.
1) Recon and map out first what I think are useful areas.
2) Build an abstract blueprint of the what and how to do.
3) Try mucking around with debugger -- zapping code, changing registers, testing branches.
4) Conjure up some test code.
5) Learn to squash and optimize the result, if space is a problem. Sometimes the ROM is Superman-packed and better to expand than go for the neat-and-quaint "it's tiny!" thinking.

Similar to working on car / lawn repairs. Rush in too fast and you're looking at lots more painful hours of undoing that mistake. Some pictures, matching up parts, checking they fit, videotaping the disasm + reasm, and hoping something else broken doesn't flub up your plan.

Not as methodical as iFixit but they're helpful with electronic repairs. Too many tiny pieces.
« Last Edit: November 23, 2021, 08:43:18 am by minucce »

ShadowOne333

  • Hero Member
  • *****
  • Posts: 1727
    • View Profile
Re: The Minucce Yard
« Reply #95 on: November 23, 2021, 12:01:16 pm »
0) Started a new game, lost some life, and manual save. Clicked "save" and save state before it ends.


1) We know hearts are at $66f and $670. Put read breakpoint and you should end at 05:8B6D.

Code: [Select]
>05:8B6D: AD 6F 06  LDA $066F = #$22
 05:8B70: 29 F0     AND #$F0
 05:8B72: 09 02     ORA #$02
 05:8B74: 8D 6F 06  STA $066F = #$22


 05:8B77: A9 FF     LDA #$FF
 05:8B79: 8D 70 06  STA $0670 = #$7F

Looks important!


2) Another read takes us here

Code: [Select]
>02:A6C6: B9 57 06  LDA $0657,Y @ $0670 = #$7F
 02:A6C9: 91 C0     STA ($C0),Y @ $68D9 = #$00
 02:A6CB: 88        DEY
 02:A6CC: 10 F8     BPL $A6C6

You've possibly seen this before.


3) Then we end up here.

Code: [Select]
>02:A6F3: AD 6F 06  LDA $066F = #$22
 02:A6F6: 29 F0     AND #$F0
 02:A6F8: 48        PHA
 02:A6F9: 4A        LSR
 02:A6FA: 4A        LSR
 02:A6FB: 4A        LSR
 02:A6FC: 4A        LSR
 02:A6FD: 85 0A     STA $0A = #$19

 02:A6FF: 68        PLA
 02:A700: 05 0A     ORA $0A = #$19
 02:A702: 8D 6F 06  STA $066F = #$22

 02:A705: A9 FF     LDA #$FF
 02:A707: 8D 70 06  STA $0670 = #$7F

 02:A70A: 20 19 A8  JSR $A819

Code: [Select]
>02:A819: A4 16     LDY $16 = #$01
 02:A81B: B9 A1 A6  LDA $A6A1,Y @ $A7A0 = #$48
 02:A81E: 85 0C     STA $0C = #$40
 02:A820: B9 A4 A6  LDA $A6A4,Y @ $A7A3 = #$48
 02:A823: 85 0D     STA $0D = #$06


 02:A825: A0 01     LDY #$01
>02:A827: B9 6F 06  LDA $066F,Y @ $0670 = #$7F
 02:A82A: 91 0C     STA ($0C),Y @ $0653 = #$FF ====
 02:A82C: 88        DEY
 02:A82D: 10 F8     BPL $A827
 02:A82F: 60        RTS -----------------------------------------

Okay. That's more interesting.

I marked A82A as I thought it was interesting.


4) I chose to stop refilling $670 and got a crash. So I looked at 0653.

Code: [Select]
02:A509: B9 50 06  LDA $0650,Y @ $0653 = #$7F
 02:A50C: 85 0E     STA $0E = #$22
 02:A50E: C8        INY
>02:A50F: B9 50 06  LDA $0650,Y @ $0653 = #$7F
 02:A512: 85 0F     STA $0F = #$00


Code: [Select]
>  :6EC4: A5 0F     LDA $0F = #$7F
   :6EC6: F0 0D     BEQ $6ED5
   :6EC8: C9 C0     CMP #$C0
   :6ECA: B0 F4     BCS $6EC0
   :6ECC: A9 00     LDA #$00
   :6ECE: 8D 29 05  STA $0529 = #$00
   :6ED1: 4C BC BE  JMP $BEBC


 02:BEBC: FF        UNDEFINED
 02:BEBD: FF        UNDEFINED
 02:BEBE: FF        UNDEFINED
 02:BEBF: FF        UNDEFINED
 02:BEC0: FF        UNDEFINED
 02:BEC1: FF        UNDEFINED


I'll stop here. If you have questions about any code or answers to give, ask away.

I think I had most of the routines you have listed there in here:
https://github.com/ShadowOne333/The-Legend-of-Zelda-Redux/blob/master/MMC1/code/gameplay/hearts.asm
(I have further modified the file to accommodate your points and the routines)

I only had that for archival purposes, since all that does is overwrite the original routines with the same code, but I had it in place just for when I got around to it.

Almost all code you mentioned is included to some extend in there.
I think the only one which I didn't have included was the one here:
Code: [Select]
02:A509: B9 50 06  LDA $0650,Y @ $0653 = #$7F
 02:A50C: 85 0E     STA $0E = #$22
 02:A50E: C8        INY
>02:A50F: B9 50 06  LDA $0650,Y @ $0653 = #$7F
 02:A512: 85 0F     STA $0F = #$00

As for the one at $6EC4 up to $6ED1...
That one I remember modifying way earlier in the project, when I was doing changes to the original Automap code by Snarfblam.

I remember making changes there specifically for Automap.
The CMP at $6EC8 is the one that determines at what health value the heart sprite will change. In the original it was $80, since it only had sprites for full heart, half heart or empty, but I modified Automap to add 1/4 heart decrements, hence the $C0, so it changes the sprite to 3/4 hearts at $C0.
There's also the JMP there at $6ED1, which is also part of Automap (Partial Heart Routine).
I think that whole part of the code is related to in-game handling of the health/hearts.
Here you can see the specific changes in there from Automap:
https://github.com/ShadowOne333/The-Legend-of-Zelda-Redux/blob/master/MMC1/code/gameplay/automap.asm#L818-L828

Outside of that, from the little I can gather, it seems like the routine at bank 5, $8B6D seems to be the one that's modifying the max value of the hearts at $066F. It's right after the STA $066F at $8B74 that the value changes from whatever the current amount is, to the default of $X2, with the 2 being the value for the default 3 hearts.

By the time the loads from accumulator of bank 2 read the value at $066F, that value has already changed to $X2, so I am inclined to say the one at bank 5 might be key, but I could still be wrong of course.

As for the others, I am not sure how the change/read of $FFs in the $650~ range (and $0670) are modified to #$7F.
For $C0 in RAM, that one seems to be a table of sorts, but I am still not sure what that table is for precisely.
However, one thing I did notice, is that the values at $0650 up to $0655 is a table for the values of the Max Amount of Hearts based on the Save Slot, with $0651, $0653 and $0655 possibly being a terminator, since it's $FF for all 3 instances.
$0650=Max hearts for Save 1
$0652=Max hearts for Save 2
$0653=Max hearts for Save 3

If I modify the amount of hearts manually of a given save slot, and then save, the value at the determined address changes from the default $22 (3 hearts) to whatever the new amount is ($33, $44, etc.).

One other routine I found that seems to write the value at $066F upon save load is the one at $A606, which sets whatever value is at that address to $X2 on load, and this seems to be loading it from the SRAM addresses related to the save file, at $6032:

Code: [Select]
02:A606: B1 00     LDA ($00),Y @ $6032 = #$92
>02:A608: 99 57 06  STA $0657,Y @ $066F = #$99
 02:A60B: 88        DEY
 02:A60C: 10 F8     BPL $A606

So far this is what I have found.
I do get bits and glimpses, but I am not 100% sure if my assumption that the code at bank 5 is the sole one that might need a rework, and/or if the others at bank 2 might be directly related to saving the value to SRAM.

Please do let me know if I am on the right track, and if I missed any pivotal information that could point towards the right direction.

minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #96 on: November 23, 2021, 02:23:37 pm »
SGB(C) is running.

+

So they'll all get triple compatible treatment (gb, sgb, gbc). I'll post the source code when they pass client testing, just so others can understand the procedure I followed which is similar to Kirby DX but extended.

But 15 more borders and colors to dig out.

---

Back to Z1. I'll be more long-winded about my descriptions for conversation.

1) Is saving partial hearts important, or just full hearts?

2)
Code: [Select]
05:8B6D

lda.w $066F
and.b #$F0
ora.b #$02
sta.w $066F

There could be others but it's the 1st gatekeeper we encountered, so requires a patch.

I set a breakpoint there.
- Note that I was using Save #2


- Mine says $21. Ran code and wrote $22 back in. Checked menu. 3/3 hearts on load.


- Reload. Changed it to $87. $80 | $02 = $82. Menu has 9 hearts. Game loads with 3/9 full hearts.


- Documented earlier that $68D8-$68D9 is receiving the health values. Repeat last $87 experiment.
  At menu, $68d8 hex edit to $76. Load game. 3 filled hearts.


- Chasing $68d8 around for awhile, you'll see some checksums. A $605a table. Then $68d8 gets discarded later.


- At menu, edit $605a from $22 to $75. Load save 2. 6/8 full hearts.
  A breakpoint at $605a reveals:

Code: [Select]
>02:A606: B1 00     LDA ($00),Y @ $605A = #$75
 02:A608: 99 57 06  STA $0657,Y @ $066F = #$77
 02:A60B: 88        DEY
 02:A60C: 10 F8     BPL $A606


- So we know changing 05:8B6D affects # hearts in menu. But not on load.
  And changing $605a at menu gives us # hearts on load.

  Where do we look next? See who writes to $605a then.


- Repeat save breakpoint. $21 ==> $76. And we catch

Code: [Select]
02:A782: B1 C0     LDA ($C0),Y @ $68D8 = #$72
>02:A784: 91 00     STA ($00),Y @ $605A = #$22
 02:A786: 88        DEY
 02:A787: 10 F9     BPL $A782

which I didn't document earlier. So the traveler went from $66f ==> $68d8 ==> $605a.


- Time to asm experiment.

Code: [Select]
05:8B6D

lda.w $066F
and.b #$F0  ==>  #$FF
ora.b #$02  ==>  #$02
sta.w $066F

Start the tracking. $66f ($22, edit to $76) ==> $68d8 ($76) ==> $605a ($76).

Looks good. Load game. $605a ($76) ==> $66f ($76). Menu shows 7/8 hearts.


- Lose another heart in-game. Re-save and re-load. 6/8 hearts.


- So in short. I just verified what you already discovered and suspected.
  You just needed to take a leap of faith and see where you land.

  When in error like I was above, I backtracked and learned more about other doors to try.

  Maybe make a written diary of the path you took. It's not all useless, just not precisely the exact path to winning.

  And you could've just patched the code and skipped the rest of the detective work. :laugh:

ShadowOne333

  • Hero Member
  • *****
  • Posts: 1727
    • View Profile
Re: The Minucce Yard
« Reply #97 on: November 23, 2021, 03:52:47 pm »
Back to Z1. I'll be more long-winded about my descriptions for conversation.

1) Is saving partial hearts important, or just full hearts?

2)
Code: [Select]
05:8B6D

lda.w $066F
and.b #$F0
ora.b #$02
sta.w $066F

There could be others but it's the 1st gatekeeper we encountered, so requires a patch.

I set a breakpoint there.
- Note that I was using Save #2


- Mine says $21. Ran code and wrote $22 back in. Checked menu. 3/3 hearts on load.


- Reload. Changed it to $87. $80 | $02 = $82. Menu has 9 hearts. Game loads with 3/9 full hearts.


- Documented earlier that $68D8-$68D9 is receiving the health values. Repeat last $87 experiment.
  At menu, $68d8 hex edit to $76. Load game. 3 filled hearts.


- Chasing $68d8 around for awhile, you'll see some checksums. A $605a table. Then $68d8 gets discarded later.


- At menu, edit $605a from $22 to $75. Load save 2. 6/8 full hearts.
  A breakpoint at $605a reveals:

Code: [Select]
>02:A606: B1 00     LDA ($00),Y @ $605A = #$75
 02:A608: 99 57 06  STA $0657,Y @ $066F = #$77
 02:A60B: 88        DEY
 02:A60C: 10 F8     BPL $A606


- So we know changing 05:8B6D affects # hearts in menu. But not on load.
  And changing $605a at menu gives us # hearts on load.

  Where do we look next? See who writes to $605a then.


- Repeat save breakpoint. $21 ==> $76. And we catch

Code: [Select]
02:A782: B1 C0     LDA ($C0),Y @ $68D8 = #$72
>02:A784: 91 00     STA ($00),Y @ $605A = #$22
 02:A786: 88        DEY
 02:A787: 10 F9     BPL $A782

which I didn't document earlier. So the traveler went from $66f ==> $68d8 ==> $605a.


- Time to asm experiment.

Code: [Select]
05:8B6D

lda.w $066F
and.b #$F0  ==>  #$FF
ora.b #$02  ==>  #$02
sta.w $066F

Start the tracking. $66f ($22, edit to $76) ==> $68d8 ($76) ==> $605a ($76).

Looks good. Load game. $605a ($76) ==> $66f ($76). Menu shows 7/8 hearts.


- Lose another heart in-game. Re-save and re-load. 6/8 hearts.


- So in short. I just verified what you already discovered and suspected.
  You just needed to take a leap of faith and see where you land.

  When in error like I was above, I backtracked and learned more about other doors to try.

  Maybe make a written diary of the path you took. It's not all useless, just not precisely the exact path to winning.

  And you could've just patched the code and skipped the rest of the detective work. :laugh:

Oh interesting.
So I wasn't far off with the assumption I had.

I do have a couple questions regarding this:

1) Where did you get the $68D8 address from? That's the only RAM address I didn't bump into from what I recall. (Or maybe I'm forgetting some documentation posted earlier).
2) Changing the AND #$F0 to #$FF does seem to make it load the proper value last saved upon loading (who would have guessed it was a one byte change?).
There's a side-effect to this, however, is that if you save near the maximum amount of hearts, when you load the amount gets added +2 to $066F (the ORA #$02). I tested this with $99 at $066F.
I tried giving this a try with a little subroutine, but I'm not sure exactly how to make the comparison here work so that it makes ORA #$02 only when below #$X2 in health, and make it ORA #$00 when it's anything equal or above it.

This is what I have so far:

Code: [Select]
bank 5;
// Routine in charge of saving hearts on manual save or game over
org $8B66 // 0x14B76
ldy.b $13 // Routine index
lda.w $8AE9,y
sta.b $12 // Game mode
jsr save_hearts
nop #07

// Untouched
lda.b #$FF // Load value #$FF
sta.w $0670 // Store $FF in "Partial hearts"
// Jump to $EBA3 (close routine?)

org $85D0 // 0x145E0
save_hearts:
lda.w $066F // Load Hearts address
and.b #$FF // Bitwise AND with #$FF (Org. AND #$F0)
cmp.b #$22 // Compare against #$22 (3 hearts)
bcs not_three
ora.b #$02 // Bitwise OR to #$02 (Org. ORA #$02)
sta.w $066F // Store in address $066F (Hearts)
rts
not_three:
ora.b #$00
sta.w $066F
rts

Right now what it does is simply save up the amount of hearts you had when you saved, but it doesn't default to 3 hearts if the health is 3, 2 or 1 heart. It saves the amount no matter what.
I know BCS is similar to using "Greater than or equal" in 6502 (with BCC being less than), but the problem I might be having is how to use the CMP correctly in this instance.

minucce

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: The Minucce Yard
« Reply #98 on: November 23, 2021, 05:02:48 pm »
Quote
There's a side-effect to this, however, is that if you save near the maximum amount of hearts, when you load the amount gets added +2 to $066F (the ORA #$02).

Yup! Was quietly hoping you'd notice and write up a real fix; I just wanted to do a hot and dirty test to make sure it was the right code to attack. It is your exercise which you've already mostly completed without my help.

----

Code: [Select]
>02:A6C6: B9 57 06  LDA $0657,Y @ $066F = #$72
 02:A6C9: 91 C0     STA ($C0),Y @ $68B0 = #$00
 02:A6CB: 88        DEY
 02:A6CC: 10 F8     BPL $A6C6

68B0 = save1
68D8 = save2

----

Code: [Select]
save_hearts:
lda.w $066F // Load Hearts address
and.b #$FF // Bitwise AND with #$FF (Org. AND #$F0)
cmp.b #$22 // Compare against #$22 (3 hearts)
bcs not_three

ora.b #$02 // Bitwise OR to #$02 (Org. ORA #$02)
sta.w $066F // Store in address $066F (Hearts)
rts

not_three:
ora.b #$00
sta.w $066F
rts

You are close! So I will just give some commentary and hints.

1) Post-cleanup: When you're done, you can save some space (6+ bytes).


2) Let's write out what's going on.

Code: [Select]
LDA #$22
CMP #$22

$22 >= $22. The debugger (!) flags tells us: Z,C. So bcs = jumps not_three


Code: [Select]
LDA #$21
CMP #$22

$21 < $22. Debugger tells us: N. ($21 - $22 = $FF). No bcs. ora #$02.


Code: [Select]
LDA #$31
CMP #$22    SEC, SBC #$22

$31 > $22. Debugger tells us: C. ($31 - $22 >= $00). bcs not_three. Error.



3) Reminder that $66f is stored as 2 parts ($f0 and $0f).
- Left is max health
- Right is current health


The left value is concrete fixed, won't change. No reason to modify it.
The right value is our problem. It might be easier to isolate it (and #$0f).


If you post a working solution, we can examine whether it can be reduced further. This is where clever people continue to surprise me.

ShadowOne333

  • Hero Member
  • *****
  • Posts: 1727
    • View Profile
Re: The Minucce Yard
« Reply #99 on: November 23, 2021, 05:58:58 pm »
I think I now have a working code that behaves like I wanted it to.
It's somewhat rough, and for sure it could be polished up, but from the tests I made, it works properly.

Here's the code:
Code: [Select]
org $85D0 // 0x145E0
save_hearts:
lda.w $066F // Load Hearts address
and.b #$0F // Mask higher nibble (only consider current health, not max amount of hearts)
cmp.b #$02 // Compare result to #$02 (3 hearts)
bcs not_three // Branch if equal or greater than 3 hearts

lda.w $066F // Load Hearts address
and.b #$F0 // Mask lower nibble (to avoid the case of heart value $01 loading as $03)
ora.b #$02 // Bitwise OR to #$02 (Org. ORA #$02)
sta.w $066F // Store in address $066F (Hearts)
rts

not_three:
lda.w $066F // Load Hearts address
and.b #$FF // Bitwise AND with #$FF (Org. AND #$F0)
ora.b #$00 // Bitwise OR to #$00
sta.w $066F // Store in address $066F (Hearts)
rts

I tried several combinations, and they all result in the proper amount of hearts being loaded, and if 3 or lower, it defaults to 3 hearts in all instances (3, 2 and 1 heart, then re-load the game).

Let me know if you have any suggestions or insights on this code!
This has been a really nice experience for sure.