News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Dragon Warrior 1, 2 & 3 Hacking Discussion  (Read 148961 times)

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #300 on: August 05, 2020, 01:37:56 pm »
Ok, I assume that a write command would be an STA, a STY or a STX, followed by a memory address. I would want to see the $04 or the $06 in one of the registers prior to that store command, and then see the store command execute writing it to a 3 byte (24 bit) memory space. This concept confuses me because I don't see why the game would need a 3 byte space to store a one byte value.

**EDIT Thinking through this more carefully, I realize that the game would definitely need a wider space for XP storage since there are creatures that provide 5 digit experience values.

But in any case, I was looking for something like STA $16 BA 24 as an example of the formatting. Did not see this in my logs. But I will take another more careful look tonight.

Quote
RAM xx+0, xx+1, xx+2.
I'm pretty confused by this. What does the +0 / +1 / +2 mean? I think seeing a hypothetical example of what I'm looking for would be helpful.

Quote
Did you accidentally skip past the answer? What did log look like at breakpoint when EXP was read?
There was a small variance between the English and Japanese logs just a handful of lines after the breakpoint for the first read of $04. I'll look at it again, but I didn't see any evidence of a 3 byte (24 bit) write command.
« Last Edit: August 05, 2020, 02:48:36 pm by Chicken Knife »

Cyneprepou4uk

  • Hero Member
  • *****
  • Posts: 504
  • I am the baldest romhacker
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #301 on: August 05, 2020, 03:30:37 pm »
How many instructions does debugger execute between hits of read breakpoint for enemy exp and write breakpoint for your exp? Number is below flags in brackets
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Euyira

  • Jr. Member
  • **
  • Posts: 14
  • I am not nice. :|
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #302 on: August 05, 2020, 06:46:06 pm »
By time this message is approved by moderator, Cyneprepou4uk has already provided the answers.
« Last Edit: August 05, 2020, 09:36:59 pm by Euyira »

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #303 on: August 05, 2020, 07:23:52 pm »
How many instructions does debugger execute between hits of read breakpoint for enemy exp and write breakpoint for your exp? Number is below flags in brackets
English version:  +3902477 instructions
Japanese version: +3902646 instructions

Trace Logger seems to be skipping lines interestingly. It wasn't doing this when I was working on the ERDRICK check, but if it's filtering out timing stuff, that's fine by me.
English trace log has 3809 lines
Japanese trace log has 3907 lines

It's interesting that the Japanese operations are greater in quantity. I would have expected it to be the other way based on the routine introduced for increasing the values.

Cyneprepou4uk

  • Hero Member
  • *****
  • Posts: 504
  • I am the baldest romhacker
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #304 on: August 05, 2020, 07:36:43 pm »
That's a lot, I was hoping these hits will happen during the same frame. Ok, never mind.

Tracer skips lines if you have "log only new code" checkmark enabled.



Find out which one of 3 exp adresses triggers last (probably it has to be address with highest exp digits) when you gain exp, and post several dozens of log lines before that last trigger happens.

Also post some log from code which reads enemy exp addresses.
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #305 on: August 05, 2020, 08:30:06 pm »
Maybe it's easier if I just link to the complete English & Japanese trace logs.

https://www.dropbox.com/sh/20kwx353wplbcv4/AADvP7VMwqumHZhlwonKv928a?dl=0

They both begin with reading 04 experience from the Slime data and end at the write operation to the first byte of character experience.

I did another scan through the English log and all the operations I saw were either 1, 2 or 3 bytes total. I didn't see anything with a 1 byte operation and a 3 byte operand.

Cyneprepou4uk

  • Hero Member
  • *****
  • Posts: 504
  • I am the baldest romhacker
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #306 on: August 05, 2020, 09:08:35 pm »
NES doesn't have instructions with 3 byte operands. And even if it had, it wouldn't make much difference in your case, because you can load/write only 1 address at a time, not 3 at once.

Exp is stored at 0744-0746. 3 addresses (24 bits). Initially you have 000000 exp. When you kill a slime, you gain 0004 exp by default. So 000000 + 0004 = 000004. If for example you currently had 00FFFF exp, your total would be 00FFFF + 0004 = 010003 exp. Note that game stores exp in little-endian, so it would actually look like 03 00 01.

Lets look at the last lines of jap log. Loop copies 0744-0746 (current exp) into 0004-0006 (temp addresses).
Code: [Select]
f19031  A:80 X:00 Y:34 S:E0 P:NvUBdizc                                $956A:A0 00     LDY #$00
f19031  A:80 X:00 Y:00 S:E0 P:nvUBdiZc                                $956C:BD 44 07  LDA $0744,X @ $0744 = #$FE
f19031  A:FE X:00 Y:00 S:E0 P:NvUBdizc                                $956F:99 04 00  STA $0004,Y @ $0004 = #$80
f19031  A:FE X:00 Y:00 S:E0 P:NvUBdizc                                $9572:E8        INX
f19031  A:FE X:01 Y:00 S:E0 P:nvUBdizc                                $9573:C8        INY
f19031  A:FE X:01 Y:01 S:E0 P:nvUBdizc                                $9574:C0 03     CPY #$03
f19031  A:FE X:01 Y:01 S:E0 P:NvUBdizc                                $9576:D0 F4     BNE $956C

Then 00CF-00D1 (your gained exp) is added to 0004-0006
Code: [Select]
f19031  A:09 X:03 Y:03 S:E2 P:nvUBdiZC                              $9585:18        CLC
f19031  A:09 X:03 Y:03 S:E2 P:nvUBdiZc                              $9586:A5 04     LDA $0004 = #$FE
f19031  A:FE X:03 Y:03 S:E2 P:NvUBdizc                              $9588:65 CF     ADC $00CF = #$04
f19031  A:02 X:03 Y:03 S:E2 P:nvUBdizC                              $958A:85 04     STA $0004 = #$FE
f19031  A:02 X:03 Y:03 S:E2 P:nvUBdizC                              $958C:A5 05     LDA $0005 = #$B3
f19031  A:B3 X:03 Y:03 S:E2 P:NvUBdizC                              $958E:65 D0     ADC $00D0 = #$00
f19031  A:B4 X:03 Y:03 S:E2 P:NvUBdizc                              $9590:85 05     STA $0005 = #$B3
f19031  A:B4 X:03 Y:03 S:E2 P:NvUBdizc                              $9592:A5 06     LDA $0006 = #$09
f19031  A:09 X:03 Y:03 S:E2 P:nvUBdizc                              $9594:65 D1     ADC $00D1 = #$00
f19031  A:09 X:03 Y:03 S:E2 P:nvUBdizc                              $9596:85 06     STA $0006 = #$09

At 9598 it checks for overflow, but there wasn't any. And finally code writes total exp from 0004-0006 back into 0744-0746.
Code: [Select]
f97711  A:22 X:00 Y:03 S:E2 P:nvUBdIzc                              $95DE:A0 00     LDY #$00
f97711  A:22 X:00 Y:00 S:E2 P:nvUBdIZc                              $95E0:B9 04 00  LDA $0004,Y @ $0004 = #$3E
You didn't log enough here, I expected you to find the last trigger. But it looks basically the same as 956A, so no big deal.



The difference between both version is gained exp
Code: [Select]
eng
$95A9:65 CF     ADC $00CF = #$06

jap
$9588:65 CF     ADC $00CF = #$04

So you need to trace back in the log where value at 00CF is coming from.

Here is an answer for how to disable additional exp if you get tired of this task.
Spoiler:

f97678  A:01 X:5D Y:00 S:EA P:nvUBdIzC                      $8A98:20 CB 8C  JSR $8CCB
f97678  A:01 X:5D Y:00 S:E8 P:nvUBdIzC                        $8CCB:75 00     ADC $00,X @ $005D = #$04
f97678  A:06 X:5D Y:00 S:E8 P:nvUBdIzc                        $8CCD:95 00     STA $00,X @ $005D = #$04
f97678  A:06 X:5D Y:00 S:E8 P:nvUBdIzc                        $8CCF:98        TYA
f97678  A:00 X:5D Y:00 S:E8 P:nvUBdIZc                        $8CD0:75 01     ADC $01,X @ $005E = #$00
f97678  A:00 X:5D Y:00 S:E8 P:nvUBdIZc                        $8CD2:95 01     STA $01,X @ $005E = #$00
f97678  A:00 X:5D Y:00 S:E8 P:nvUBdIZc                        $8CD4:A9 00     LDA #$00
f97678  A:00 X:5D Y:00 S:E8 P:nvUBdIZc                        $8CD6:75 02     ADC $02,X @ $005F = #$00
f97678  A:00 X:5D Y:00 S:E8 P:nvUBdIZc                        $8CD8:95 02     STA $02,X @ $005F = #$00
f97678  A:00 X:5D Y:00 S:E8 P:nvUBdIZc                        $8CDA:60        RTS (from $8CCB)

NOP out that JSR $8CCB to disable additional exp
« Last Edit: August 05, 2020, 09:14:08 pm by Cyneprepou4uk »
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #307 on: August 06, 2020, 12:08:15 am »
@Cyneprepou4uk
Your basic descriptions of those sections of code were helpful. I spent hours reasoning through each step in them to gain familiarity with how these things work, and it was very interesting.

By searching backwards in the log, I followed the trail of gained experience from the CF memory location to the 5D location, where I saw the value there be changed from $04 to $06. At that point, I knew that that was the area where I needed to disable something with EA, and I was looking closely at the operation that added the 1 in the accumulator along with the carry flag to the 04 in 5D to get 06. But based on the other operations attached to that, I felt like disabling just that one line of code would make a mess of things. I was thinking of disabling a whole bunch of lines, but I remembered storall mentioning that he disabled just one. At that point, I looked at your spoiler and realized that yes, disabling the jump into that whole subroutine was the correct way. The code would just pass right over it without anything getting mucked up.

This was a painful but very good exercise. The most important thing I learned was the value of following the trail of data moving from memory location to memory location.

Now, I'm willing to bet that a nearly identical routine exists for increasing the gold. Tomorrow evening, I'm going to follow a very similar set of steps and work to disable that one myself.

Thanks for the support with this.

August 06, 2020, 03:19:18 am - (Auto Merged - Double Posts are not allowed before 7 days.)
Woke up in the middle of the night feeling the need to take a stab at uncovering the gold increase routine, so I did. I had some success following the trail, but I got a bit lost at a point and would like some help.

Here's a link for a new log file that cuts off very slightly after the write to your gold.

https://www.dropbox.com/s/t6xmn6qklagoqx2/log%20before%20and%20after%20slime%20gold%20write%20EDITED.txt?dl=0

My new gold value being written down at the bottom near the break was 55 and that was coming from the RAM address $04. Searching backwards, that 55 value came from 07BC (52 - existing gold) & $CE (3 acquired gold)
Searching backwards, the 3 acquired gold seemed to come from $60 (address 8C0C).
Searching backwards, the 3 in $60 seems to come from $04 again, where it was a value of 02, only changed by the addition of a carry flag. Here's that bit of code that puzzles me:

Code: [Select]
f97657  A:02 X:60 Y:00 S:E8 P:nvUBdIzc                        $C0B5:60        RTS (from $C07F) ---------------------------
f97657  A:02 X:60 Y:00 S:EA P:nvUBdIzc                      $8BF6:C9 01     CMP #$01
f97657  A:02 X:60 Y:00 S:EA P:nvUBdIzC                      $8BF8:A5 04     LDA $0004 = #$02
f97657  A:02 X:60 Y:00 S:EA P:nvUBdIzC                      $8BFA:65 60     ADC $0060 = #$00
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8BFC:85 60     STA $0060 = #$00
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8BFE:A5 05     LDA $0005 = #$00
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C00:65 61     ADC $0061 = #$00
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C02:85 61     STA $0061 = #$00
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C04:90 06     BCC $8C0C
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C0C:A5 60     LDA $0060 = #$03
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8C0E:8D 3F 06  STA $063F = #$04
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8C11:85 CE     STA $00CE = #$03
I find this pretty odd, because the number got adjusted from the Japanese value of 02 to the English version value of 03 without the kind of complex subroutine that adjusted the experience. It makes me feel like I lost the trail or there is something I'm missing.



August 06, 2020, 04:02:16 am - (Auto Merged - Double Posts are not allowed before 7 days.)
I did some work to make sure that the English version isn't just adjusting gold values by one. After making several comparisons, it would seem that the English gold values are being adjusted to 120% of the Japanese values. So there is definitely a routine doing this that has so far evaded me.
« Last Edit: August 06, 2020, 04:03:29 am by Chicken Knife »

Cyneprepou4uk

  • Hero Member
  • *****
  • Posts: 504
  • I am the baldest romhacker
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #308 on: August 06, 2020, 06:56:35 am »
You have found code correctly, but it is not the most convenient location to edit. Here is the easiest way in my opinion



I replced 00CE-00CF (gained gold with addition) with 0004-0005 (default gained gold). It seems like 0004-0005 keep default gold the whole time.
Code: [Select]
f97657  A:FF X:4A Y:00 S:EA P:nvUBdIZC                      $8BE7:A5 60     LDA $0060 = #$02
f97657  A:02 X:4A Y:00 S:EA P:nvUBdIzC                      $8BE9:85 04     STA $0004 = #$00
f97657  A:02 X:4A Y:00 S:EA P:nvUBdIzC                      $8BEB:A5 61     LDA $0061 = #$00
f97657  A:00 X:4A Y:00 S:EA P:nvUBdIZC                      $8BED:85 05     STA $0005 = #$00

However I didn't change 00D0 to 0006, because 00D0 is always forced to store 00
Code: [Select]
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C1E:A9 00     LDA #$00
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C20:8D 41 06  STA $0641 = #$00
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C23:85 D0     STA $00D0 = #$00

On the other hand, 0006 might still keep some garbage value, presumably from exp, so it's save to keep 00D0.

August 06, 2020, 07:19:53 am - (Auto Merged - Double Posts are not allowed before 7 days.)
Actually, no. I forgot that this code I've changed only affects ram gold value, but the screen still displays +3 gold gained.

August 06, 2020, 07:26:45 am - (Auto Merged - Double Posts are not allowed before 7 days.)


Here is a better way. CMP 01 is for affecting C flag, but I've deleted additions and now store 0004-0005 directly at 0060-0061 (gold for displaying and copying into 00CE-00CF)
Code: [Select]
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C0C:A5 60     LDA $0060 = #$03
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8C0E:8D 3F 06  STA $063F = #$04
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8C11:85 CE     STA $00CE = #$03
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8C13:05 61     ORA $0061 = #$00
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8C15:F0 58     BEQ $8C6F
f97657  A:03 X:60 Y:00 S:EA P:nvUBdIzc                      $8C17:A5 61     LDA $0061 = #$00
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C19:8D 40 06  STA $0640 = #$00
f97657  A:00 X:60 Y:00 S:EA P:nvUBdIZc                      $8C1C:85 CF     STA $00CF = #$04

, so there is no need for it. Instead I replace it with CLC, which forces C = 0, which results in BCC to always branch and skip overflow correction.
« Last Edit: August 06, 2020, 07:30:13 am by Cyneprepou4uk »
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #309 on: August 06, 2020, 08:05:34 am »
This fix took some finesse I see, but there's a problem. I'm testing if the new values come out correctly compared to my Japanese guidebook.

For instance, Al-mi'raj, or Spiked Hare in the original localization gave 10 gold per in the English version. Japanese version is supposed to give 8 gold per. I just killed four of them and got 38 pieces of gold. Original English would have been 40, Japanese would have been 32.

It seems like the new code subtracted 2 from one of them (which is correct) but perhaps didn't extend that benefit to the other 3? 38 doesn't divide by four after all.

Cyneprepou4uk

  • Hero Member
  • *****
  • Posts: 504
  • I am the baldest romhacker
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #310 on: August 06, 2020, 08:15:54 am »
Game doesn't add to each monster separately, it gets a sum of all monsters and works with it.
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #311 on: August 06, 2020, 08:31:24 am »
I just did a direct comparison of the Japanese version and our patch for the English version.

Near Romalia / Romaly, I killed 4 grey cloaked Magicians in the Japanese version and got 13 exp, 40 gold.

Then, I killed four of those Magicians in the patched English version and got 13 exp, 48 gold.

The new gold calculation is definitely not sufficiently emulating the way the Japanese game handles it.

FYI, heading to work so I won't be able to do anything more with this until tonight.

Cyneprepou4uk

  • Hero Member
  • *****
  • Posts: 504
  • I am the baldest romhacker
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #312 on: August 06, 2020, 08:35:02 am »
40 and 48, sound like you didn't apply the patch, still +20%.

I've tested it on 2 ravens and 5 slimes, works for me. 2 ravens = 4 gold instead of 5, 5 slimes = 10 gold instead of 12. Didn't compare to jap thought.

August 06, 2020, 07:11:12 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Quote
RAM xx+0, xx+1, xx+2.
I'm pretty confused by this.

Since no one else explained it. In assemblers such as ca65 you can do stuff like
Code: [Select]
ram_exp = $0744    ; creating a label

LDA #$00
STA ram_exp        ; 0744, ram_exp + 0 also works
STA ram_exp + 1    ; 0745
STA ram_exp + 2    ; 0746

So it was just a way to tell you about 3 nearby addresses with exp.
« Last Edit: August 06, 2020, 07:11:12 pm by Cyneprepou4uk »
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #313 on: August 07, 2020, 12:29:19 am »
@Cyneprepou4uk
Apologies for giving you that bad info regarding the gold code not working. The reason it wasn't working is because I missed a couple of the byte swaps. I didn't realize how many there were because I looked at it quickly. I shouldn't have even touched that this morning with such limited time. Anyway, I got it all sorted out a few hours ago.

After that, I decided to address the next thing on my list, the Parry / Cancel bug (causes character to retain double defense from parry even after cancelling action). Knowing that Zombero managed to fix this bug for his Hardtype hack, I figured I'd take a look at his code.

I did a couple of trace logs to compare and I tracked down the subroutine he incorporated surprisingly quickly. It's a routine that already seems to exist at $4842 but he copied it over to some blank space later in the rom. I plugged that small fix into my rom, and it works perfectly.

I had actually sent Zombero a PM over a year ago requesting permission to incorporate the parry fix patch and never heard back. I sent him an email tonight requesting permission again. I'm a little unclear on whether or not it's acceptable to use part of someone's work and provide credit if you can't get through to them to obtain permission. I feel like I've seen this covered in the rules at some point, but I can't seem to find it now.

**EDIT I sent the admin team an email describing the scenario and asking how things like this should be handled.

If using Zombero's parry fix is ultimately kosher, that should solve everything remaining on my list except for one more big one: restoring censored Japanese nametables in three locations: the white cross in the big temple in Lanceal, the  white cross in the shrine of Necrogond and finally the Buddhist symbol behind the altar at the Temple of Dharma.

I played around for hours with the data for these maps several months ago, and I simply couldn't crack the format of how the engine draws the maps. I was unable to just swap in the Japanese instructions because the space for them is smaller in the English rom. Now that I have a little skill with debugging / trace logging, I can hopefully get further with this. Perhaps even part of the drawing routine could be jumped over to another section of code if the space isn't enough. abw mentioned the idea of writing the code to be more efficient, but that would appear to be quite beyond me right now. How would you guys go about approaching this?
« Last Edit: August 07, 2020, 11:36:24 am by Chicken Knife »

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #314 on: August 15, 2020, 11:07:24 pm »
@ Cyneprepou4uk
A bug turned up and I've confirmed that it's a direct result of your code changes that remove the extra gold. While the battle gold acquisition is working fine, now when you go to sell an item at the shop, you end up getting a massive amount of money. Try selling a medical herb. The shop keeper will tell you the correct price he will buy it for, but then you get 33000+ gold as a result of the sale.

In other matters, the admin team messaged me back that having fixed the Parry bug via referencing Zombero's fix shouldn't be an issue, primarily since he copied an existing routine and simply made a jump to it and a return.

Also, I became aware of a DQ3 bug where you learn Snowstorm/Mafrosto at 26 and Icespears/Frostdain at 32, when it was supposed to happen in reverse. Based on menu placement and spell damage, I thought that fixing would be a significant improvement. I spent the last week doing my own disassembly work on the somewhat complex routine structure for spell learning. Today I was able to locate the bytes that needed switching. Submitted as a separate hack. I thought that players of the standard game would appreciate this bug fixed.

Didn't even start working on decensoring the nametables until tonight, and barely got anywhere. But I should be able to make some progress based on having a larger tool box.



August 16, 2020, 02:24:21 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
I started from scratch trying to fix the gold issue without looking at your work. It seems that a smaller scale fix does the job, without making a mess of anything else. I just targeted the two instructions that add the $60 / $61 values, replaced the first with a CLC and EA, and the second with an ADC #$00.

ROM address $0x04C0A should have $18 $EA written
ROM address $0x04C10 should have $69 $00 written

I've tested on both low and high gold generating monsters, and I've also bought and sold things. Everything seems in order.
« Last Edit: August 16, 2020, 02:26:37 pm by Chicken Knife »

abw

  • Hero Member
  • *****
  • Posts: 554
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #315 on: August 28, 2020, 07:11:11 pm »
The other problem we all have is that I missed a detail in how DW2's text engine handles transitioning from the first text bank to the second text bank - it actually requires a copy of the first byte of the second text bank to be placed after the last byte of the first bank. In the original game, this means that $05:$BFD7 (0x017FE7) has to have the same byte value as $02:$B7B2 (0x00B7C2); Choppasmith's version will require $05:$BFD7 to be a copy of $0C:$8000 instead.

The bad news is that abcde can't currently handle this for you, so you'll have to copy your second bank's first script byte to 0x017FE7 on your own in the meantime.
I finally got around to doing something about this - the latest version of abcde (v0.0.9) now has enough power to handle copying a byte from one address to another (total rocket science going on here, I know :P) if you supply the right insertion commands anywhere after the end of the main script, like so:
Code: [Select]
// due to the way the game's bank bridging code works, the first byte of the second script bank needs to be copied to the byte after the last byte of the first script bank in order to ensure consistency between banks
#VAR(copy, CALCVAR)
#READ(copy, $B7C2)
#JMP($17FE7)
#PRINT(copy, 8)
Basically that just does what you'd expect - creates a variable to hold a value, reads a byte from ROM into that variable, jumps to the address you need to the value to be copied to, then inserts the value there.

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #316 on: August 28, 2020, 09:04:21 pm »
I finally got around to doing something about this - the latest version of abcde (v0.0.9) now has enough power to handle copying a byte from one address to another (total rocket science going on here, I know :P)
Glad this is a feature now! I'm sure the need will come up again at some point for us.

And since you've shown up here, you know that I have to pick your brain a bit, right? As you can see above, this thread went from cacophonous to deadly silent over the last few weeks.

So! After solving everything on my wish list but maps, it sort of became an absolute requirement for me to solve the maps, hell or high water. I'm progressing with my disassembly/documentation process, but I worry that it will take me something like 6 months at the rate it feels like it's going. The structure of what's going on here seems to be a lot more complex than the above issues that I figured out.

I've been working on the Necrogond Shrine first and foremost (because small) and we know the nametable data is 1AB4E-1AB82 ROM, AB3E-AB72 RAM. I've ran a trace log that breaks on every read on that RAM range and captures all the code forward until the map is drawn. The values move through a hell of a complex structure of loop routines, and I'm trying to map that all out so that I can understand and manipulate the data, still operating on your idea that if I understand what's going on, I might be able to increase map complexity in the same data space via greater efficiency. And if that can't be done, I then look to the idea of having the code do a bank switch (something I haven't figured out yet) and read that map data from another bank that actually has free space. I might need to move the attribute table as well, I imagine. Does that plan seem prudent? If you have any ideas that could save me weeks or months, do tell. I know you solved something similar with the maps in DQ2, and I'm very curious how equivalent the map drawing routines are between the two games. I was trying to figure out which thread it was on that we discussed that over a year ago, but alas.

If you wanted to take a glace at the trace log I refer to: https://www.dropbox.com/s/ck4n9qxr034wh8b/log%20for%20entering%20necrogond%20READ%20HITS%20FROM%20MAP%20DATA.log?dl=0
« Last Edit: August 29, 2020, 10:39:55 am by Chicken Knife »

abw

  • Hero Member
  • *****
  • Posts: 554
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #317 on: August 29, 2020, 09:54:09 pm »
I know you solved something similar with the maps in DQ2, and I'm very curious how equivalent the map drawing routines are between the two games. I was trying to figure out which thread it was on that we discussed that over a year ago, but alas.
I think you're looking for this thread: http://www.romhacking.net/forum/index.php?topic=26112.msg378684#msg378684. After taking ROM 0x1AB4E-0x1AB82 and plugging it into my DW2 map building visualizer, I get something that looks very much like the Necrogond Shrine (same layout, but the 2 games use different graphics per tile ID, so e.g. tile ID $14 is a treasure chest in DW2 but a star in DW3), so without looking at DW3's code, I'd say the map building routines are likely to be virtually identical between the two games. http://datacrystal.romhacking.net/wiki/Dragon_Warrior_II::ROM_map/ASM_bank_02 has a fair bit of commentary on DW2's map building code, so assuming the code actually is as similar as I expect, that commentary should be quite helpful for DW3 too.

I'm progressing with my disassembly/documentation process, but I worry that it will take me something like 6 months at the rate it feels like it's going. The structure of what's going on here seems to be a lot more complex than the above issues that I figured out.
Yup, the map building routine is definitely "special" ;). I think it took me a couple of multi-hour sessions to work through it enough to understand what was going on, and then several more sessions to document it.

Chicken Knife

  • Sr. Member
  • ****
  • Posts: 456
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #318 on: September 06, 2020, 10:43:48 am »
@abw

I'm continuing to have an extremely hard time grasping the structure of the map drawing, even with the DQ2 disassembly. It's hard for me to even know how to ask for specific help on this, but here's a list of questions that I hope will help clarify.


VOCABULARY

Some terminology / conceptuals I could use clarifaction on:

Control flow target: google would indicate that the control flow is the main program sequence and the targets are the subroutines that get called per the control flow. Is that the right idea?

Map buffer: this is a function of the PPU I would assume?

Map data handler: not finding much in my research for this terminology

"map stack": is this different than the normal stack register?

index to top of "map stack": not sure what indexing means

popping the bottom of the "map stack": also not clear on meaning

process next control code: is this referring to the next step in the main flow of the program?

flag for whether xxxx handler wrote tile IDs: I would assume that flag means write a yes or no indication?

read the next text token and interpolate any variable control codes: not clear on this concept of interpolating.


FORMATTING

A question about how your disassembly is formatted:

Example:
0x00AE5B|$02:$AE4B:B0 03      BCS $AE50     ; read 2 bits of map data: if #$00 or #$01, rotate in that direction and draw the current tile ID; if #$02, push to "map stack" then read 1 bit of map data, rotate in that direction, and draw current tile ID; if #$03, read 1 bit of map data and if set, pop from "map stack", else loop to 0b10 handler to start drawing at a new co-ordinate

Your description here seems to describe a routine, but the notes seems to correspond to a single instruction to branch if carry is set. Are you describing the function of the routine that gets branched to if the criteria is met? I imagine this must be the case.


CONCEPTS

Here are some high level questions about what is going on.

Is it correct to say that *ALL* all of the drawing instructions are ultimately found in the cluster of map data, and that the code / routines involved in the map drawing go through the same structure of processes for every map? Therefore, as long as I understand what purpose each byte in the map data serves, I should be able enact changes? This was my hope, but when I read the disassembly, I have a hard time determining exactly which bytes of map data are getting read from and how it all translates in to the routine structure.

Am I correct in my suspicion that the material in this disassembly most relevant to my map drawing concerns is located about 2/3 of the way down the file?

Ok, that's all I have for now, but I suspect there will be additional rounds of questions coming.

Yup, the map building routine is definitely "special" ;). I think it took me a couple of multi-hour sessions to work through it enough to understand what was going on, and then several more sessions to document it.
Why again am I even attempting something that even the likes of you finds difficult?  :P
« Last Edit: September 06, 2020, 01:45:55 pm by Chicken Knife »

abw

  • Hero Member
  • *****
  • Posts: 554
    • View Profile
Re: Dragon Warrior 1, 2 & 3 Hacking Discussion
« Reply #319 on: September 07, 2020, 07:44:53 pm »
Rapid Fire Answer Round!

Control flow target: google would indicate that the control flow is the main program sequence and the targets are the subroutines that get called per the control flow. Is that the right idea?
Yup, that's exactly it means.

Map buffer: this is a function of the PPU I would assume?
Nope, that's just the area of cartridge RAM starting at $7800 that the game uses to hold the map data while it's being constructed.

Map data handler: not finding much in my research for this terminology
This just refers to the code for handling map data.

"map stack": is this different than the normal stack register?
Yup. As I said earlier in the linked thread, the map building routine manages its own stack in cartridge RAM via software, and this is completely separate from the CPU's hardware stack that gets used for PHA/PLA/JSR/RTS/etc. operations.

index to top of "map stack": not sure what indexing means
https://en.wikipedia.org/wiki/Array_index

popping the bottom of the "map stack": also not clear on meaning
https://en.wikipedia.org/wiki/Stack_(abstract_data_type)

process next control code: is this referring to the next step in the main flow of the program?
Probably yes, depending on how you choose to break up the flow of a program into steps. Usually it means the program is finished its current (sub-)task and is moving on to the next one.

flag for whether xxxx handler wrote tile IDs: I would assume that flag means write a yes or no indication?
Yup.

read the next text token and interpolate any variable control codes: not clear on this concept of interpolating.
https://en.wikipedia.org/wiki/String_interpolation

Your description here seems to describe a routine, but the notes seems to correspond to a single instruction to branch if carry is set. Are you describing the function of the routine that gets branched to if the criteria is met? I imagine this must be the case.
Yup. Usually the interesting thing about branches and subroutine calls is what code they end up executing, so that's the information my comments tend to provide, though if there's something strange going on like branching based on incorrect logic, that'll be noted somewhere too.

Is it correct to say that *ALL* all of the drawing instructions are ultimately found in the cluster of map data, and that the code / routines involved in the map drawing go through the same structure of processes for every map? Therefore, as long as I understand what purpose each byte in the map data serves, I should be able enact changes? This was my hope, but when I read the disassembly, I have a hard time determining exactly which bytes of map data are getting read from and how it all translates in to the routine structure.
There is some code that runs earlier and reads a separate block of what I've referred to as map header data from $02:$8018, but aside from providing the pointer to the map data, it's not really relevant for the tricky part of map construction. The world map data is handled separately, but all the other maps go through this routine. Also, keep in mind that the map building instructions have many different bit lengths, and almost none of them are 8 bits long.

Am I correct in my suspicion that the material in this disassembly most relevant to my map drawing concerns is located about 2/3 of the way down the file?
As I said earlier in the linked thread, $02:$AB89 is the entry point for the map building routine.

Why again am I even attempting something that even the likes of you finds difficult?  :P
Because it's good practice :D. There is something to be said for the old adage that whatever does not kill you makes you stronger; overcoming challenges is one of the ways in which we grow.


Apparently there already is a Dragon Quest III Map Viewer, though for me it crashes immediately after loading a ROM with what looks like a Shift-JIS-encoded error message; does that program help any?

I've put some time into adding various bells and whistles to my DW2 map building visualizer and added a bunch of DW3 map data; I've labelled the first few maps and added some DW3 tile images, but the majority of the maps are still unlabelled, I haven't gone looking for the separate map header data (assuming it exists), and the tilesets are pretty messed up (the complete town tileset includes more than 32 different tiles, so there's logic somewhere for deciding which tiles get loaded into VRAM and thus what image a given tile ID will end up producing). Even as a WIP, though, it's still a bit fun and should be educational. Here's a link!