|
Post by Xalphenos on Nov 23, 2013 9:24:28 GMT -5
LDA sets the zero flag if the accumulator becomes zero. So a BEQ will branch if you load 0x00 into a.
|
|
|
Post by Ascended Mermaid on Nov 23, 2013 9:41:55 GMT -5
LDA sets the zero flag if the accumulator becomes zero. So a BEQ will branch if you load 0x00 into a. That's perfect! The next trap after this is to make it nicely interrupt break, bring up the text one line, print the last line, repeat 3 more times, and interrupt break again if necessary. Interrupt break as in an auto stop after every 4 lines, request player input. I don't want to simply blank the window.
Also, I know you asked if I had the original code. If by this, you meant the original vanilla Faxanadu (J) code I replaced from F601 to F647, here it is. 0F:F601:EE 16 02 INC byte_216 = #$00 0F:F604:AD 16 02 LDA byte_216 = #$00 0F:F607:C9 10 CMP #$10 0F:F609:90 27 BCC $F632 0F:F60B:AD 16 02 LDA byte_216 = #$00 0F:F60E:F0 B7 BEQ $F5C7 0F:F610:A9 00 LDA #$00 0F:F612: 16 02 STA byte_216 = #$00 0F:F615:CE 1B 02 DEC byte_21B = #$04 0F:F618:D0 19 BNE $F633 0F:F61A:AD 18 02 LDA byte_218 = #$00 0F:F61D:85 EC STA byte_EC = #$40 0F:F61F:AD 19 02 LDA byte_219 = #$9C 0F:F622:85 ED STA byte_ED = #$84 0F:F624:AC 14 02 LDY byte_214 = #$DA 0F:F627:B1 EC LDA ($EC),Y @ $8519 = #$60 0F:F629:C9 FF CMP #$FF 0F:F62B:F0 15 BEQ $F642 0F:F62D:A9 FF LDA #$FF 0F:F62F: 15 02 STA byte_215 = #$00 0F:F632:60 RTS 0F:F633:AC 17 02 LDY byte_217 = #$00 0F:F636:C8 INY 0F:F637:C0 04 CPY #$04 0F:F639:F0 04 BEQ $F63F 0F:F63B:8C 17 02 STY byte_217 = #$00 0F:F63E:60 RTS 0F:F63F:4C 85 F6 JMP $F685 0F:F642:A9 00 LDA #$00 0F:F644: 13 02 STA MessageID = #$71 0F:F647:60 RTS
I've moved 0F:F5F6-0F:F63E to Bank 10, and copied up to 0F:F660 to Bank 10 as well. I may leave a copy of data in 0F, just to prevent broken jumps and branches. 10:BF5A:B1 EC LDA ($EC),Y @ $851F = #$01 10:BF5C:C9 FA CMP #$FA 10:BF5E:D0 16 BNE $BF76 10:BF60:A9 0F LDA #$0F 10:BF62: 16 02 STA LetterPos = #$53 10:BF65:A9 04 LDA #$04 10:BF67: 17 02 STA LinePos = #$00 10:BF6A:A9 01 LDA #$01 10:BF6C: 1B 02 STA byte_21B = #$03 10:BF6F:A9 02 LDA #$02 10:BF71: 1A 02 STA byte_21A = #$00 10:BF74:A9 FE LDA #$FE 10:BF76:C9 FF CMP #$FF 10:BF78:F0 65 BEQ $BFDF 10:BF7A:C9 FE CMP #$FE 10:BF7C:F0 36 BEQ $BFB4 10:BF7E:C9 FD CMP #$FD 10:BF80:F0 22 BEQ $BFA4 10:BF82:C9 FC CMP #$FC 10:BF84:F0 5F BEQ $BFE5 10:BF86:C9 FB CMP #$FB 10:BF88:F0 64 BEQ $BFEE 10:BF8A:AE 12 02 LDX byte_212 = #$01 10:BF8D:F0 07 BEQ $BF96 10:BF8F:48 PHA 10:BF90:A9 01 LDA #$01 10:BF92:20 E4 D0 JSR PlaySound 10:BF95:68 PLA 10:BF96:20 32 F7 JSR $F732 10:BF99:AD 16 02 LDA LetterPos = #$53 10:BF9C:F0 06 BEQ $BFA4 10:BF9E:AD 17 02 LDA LinePos = #$00 10:BFA1:F0 01 BEQ $BFA4 10:BFA3:60 RTS 10:BFA4:EE 16 02 INC LetterPos = #$53 10:BFA7:EE 16 02 INC LetterPos = #$53 10:BFAA:4C 6E F5 JMP SwitchToBank10 10:BFAD:AD 16 02 LDA LetterPos = #$53 10:BFB0:C9 1F CMP #$1F 10:BFB2:90 F0 BCC $BFA4 10:BFB4:AC 16 02 LDY LetterPos = #$53 10:BFB7:C0 1F CPY #$1F 10:BFB9:B0 06 BCS $BFC1 10:BFBB:C8 INY 10:BFBC:C8 INY 10:BFBD:C0 1F CPY #$1F 10:BFBF:90 FA BCC $BFBB 10:BFC1:CE 1B 02 DEC byte_21B = #$03 10:BFC4:98 TYA 10:BFC5:E9 1F SBC #$1F 10:BFC7: 16 02 STA LetterPos = #$53 10:BFCA:D0 DE BNE $BFAA 10:BFCC:EE 17 02 INC LinePos = #$00 10:BFCF:EE 17 02 INC LinePos = #$00 10:BFD2:AD 17 02 LDA LinePos = #$00 10:BFD5:C9 04 CMP #$04 10:BFD7:90 D1 BCC $BFAA 10:BFD9:4C 32 F7 JMP $F732 10:BFDC:4C 85 F6 JMP $F685 10:BFDF:A9 00 LDA #$00 10:BFE1: 13 02 STA MessageID = #$A0 10:BFE4:60 RTS 10:BFE5:AD C2 04 LDA PlayerName1 = #$46 10:BFE8:EE 1C 02 INC byte_21C = #$00 10:BFEB:4C F2 F5 JMP $F5F2 10:BFEE:A9 81 LDA #$81 10:BFF0: 1C 02 STA byte_21C = #$00 10:BFF3:AD 37 04 LDA Title = #$0D 10:BFF6:0A ASL 10:BFF7:0A ASL 10:BFF8:0A ASL 10:BFF9:AA TAX 10:BFFA:BD 91 F7 LDA sub_F791,X @ $F796 = #$04 10:BFFD:4C F2 F5 JMP $F5F2
I think this might have to do with why it won't print if LinePos>=2 0F:F735:A9 00 LDA #$00 0F:F737:85 E9 STA byte_E9 = #$00 0F:F739:AD 16 02 LDA LetterPos = #$02 0F:F73C:0A ASL 0F:F73D:0A ASL 0F:F73E:0A ASL 0F:F73F:0A ASL 0F:F740:EA NOP 0F:F741:EA NOP 0F:F742:26 E9 ROL byte_E9 = #$00 0F:F744:85 E8 STA byte_E8 = #$20 0F:F746:AD 1A 02 LDA byte_21A = #$00 0F:F749:4A LSR 0F:F74A:4D 17 02 EOR LinePos = #$02 0F:F74D:29 03 AND #$03[/u] 0F:F74F:EA NOP 0F:F750:05 E9 ORA byte_E9 = #$00 0F:F752:69 14 ADC #$14 0F:F754:85 E9 STA byte_E9 = #$00 I have to wonder.
I just flashed back to something important. Memory. I need to follow from 0216 to 021B. One of them leads to something that will simplify the process. I also think that the PPU character code for 16 x 16 that was in my last post may be a red Herring. // Maybe 213 or so. Something about that sticks out in my mind.
|
|
|
Post by Xalphenos on Nov 23, 2013 21:18:30 GMT -5
What data is at byte 21A?
|
|
|
Post by Ascended Mermaid on Nov 24, 2013 8:37:46 GMT -5
What data is at byte 21A? When I don't have a label for a memory location, it's important that I explore it. 21A is a good place to start.
Okay, so I've figured out almost everything... except how to stop it. It prints almost perfectly, but it needs to return to the proper code after. Here's the new Bank 10. 10:BF5A:B1 EC LDA ($EC),Y @ $8679 = #$00 10:BF5C:C9 FA CMP #$FA 10:BF5E:D0 16 BNE $BF76 10:BF60:A9 04 LDA #$04 10:BF62: 15 02 STA byte_215 = #$04 10:BF65:A9 1F LDA #$1F 10:BF67: 16 02 STA LetterPos = #$00 10:BF6A:A9 04 LDA #$04 10:BF6C: 17 02 STA LinePos = #$00 10:BF6F:A9 04 LDA #$04 10:BF71: 1B 02 STA byte_21B = #$04 10:BF74:A9 FE LDA #$FE 10:BF76:C9 FF CMP #$FF 10:BF78:F0 65 BEQ $BFDF 10:BF7A:C9 FE CMP #$FE 10:BF7C:F0 36 BEQ $BFB4 10:BF7E:C9 FD CMP #$FD 10:BF80:F0 22 BEQ $BFA4 10:BF82:C9 FC CMP #$FC 10:BF84:F0 5F BEQ $BFE5 10:BF86:C9 FB CMP #$FB 10:BF88:F0 64 BEQ $BFEE 10:BF8A:AE 12 02 LDX byte_212 = #$01 10:BF8D:F0 07 BEQ $BF96 10:BF8F:48 PHA 10:BF90:A9 01 LDA #$01 10:BF92:20 E4 D0 JSR PlaySound 10:BF95:68 PLA 10:BF96:20 32 F7 JSR $F732 10:BF99:AD 16 02 LDA LetterPos = #$00 10:BF9C:D0 05 BNE $BFA3 10:BF9E:AD 17 02 LDA LinePos = #$00 10:BFA1:F0 01 BEQ $BFA4 10:BFA3:60 RTS 10:BFA4:EE 16 02 INC LetterPos = #$00 10:BFA7:EE 16 02 INC LetterPos = #$00 10:BFAA:20 6E F5 JSR SwitchToBank10 10:BFAD:AD 16 02 LDA LetterPos = #$00 10:BFB0:C9 1F CMP #$1F 10:BFB2:90 F0 BCC $BFA4 10:BFB4:AC 16 02 LDY LetterPos = #$00 10:BFB7:C0 1F CPY #$1F 10:BFB9:B0 06 BCS $BFC1 10:BFBB:C8 INY 10:BFBC:C8 INY 10:BFBD:C0 1F CPY #$1F 10:BFBF:90 FA BCC $BFBB 10:BFC1:CE 15 02 DEC byte_215 = #$04 10:BFC4:F0 19 BEQ $BFDF 10:BFC6:98 TYA 10:BFC7:E9 1F SBC #$1F 10:BFC9: 16 02 STA LetterPos = #$00 10:BFCC:D0 DC BNE $BFAA 10:BFCE:EE 17 02 INC LinePos = #$00 10:BFD1:EE 17 02 INC LinePos = #$00 10:BFD4:AD 17 02 LDA LinePos = #$00 10:BFD7:C9 04 CMP #$04 10:BFD9:90 CF BCC $BFAA 10:BFDB:60 RTS 10:BFDC:4C 85 F6 JMP $F685 10:BFDF:A9 00 LDA #$00 10:BFE1: 13 02 STA MessageID = #$22 10:BFE4:60 RTS 10:BFE5:AD C2 04 LDA PlayerName1 = #$46 10:BFE8:EE 1C 02 INC byte_21C = #$00 10:BFEB:4C F2 F5 JMP $F5F2 10:BFEE:A9 81 LDA #$81 10:BFF0: 1C 02 STA byte_21C = #$00 10:BFF3:AD 37 04 LDA Title = #$0D 10:BFF6:0A ASL 10:BFF7:0A ASL 10:BFF8:0A ASL 10:BFF9:AA TAX 10:BFFA:BD 91 F7 LDA sub_F791,X @ $F792 = #$0E 10:BFFD:4C F2 F5 JMP $F5F2
So 215 is neat. It takes care of the interrupt break when it reaches 0. It used to do it if not 0, but I changed that. Now that the text engine is handled completely new, however, it will keep printing without interruption.
|
|
|
Post by Xalphenos on Nov 24, 2013 14:06:23 GMT -5
So everything prints correctly now? You just need the routine to stop now?
|
|
|
Post by Ascended Mermaid on Nov 24, 2013 14:10:49 GMT -5
Correct. My routine needs to stop and the original routine needs to finish the job.
|
|
|
Post by Xalphenos on Nov 24, 2013 14:23:32 GMT -5
So the routine will stop when 215 is zero?
|
|
|
Post by Ascended Mermaid on Nov 24, 2013 15:21:01 GMT -5
So the routine will stop when 215 is zero? If it were still using the original routine. RTS isn't enough, though. I think we have some sort of redundant cycle going, since it prints endlessly. It disregards message ending control codes, and disregards any wait for player input, because of this.
When I say the original code, I mean what it used to go to when the letters were just printing in place. Before I fixed the checksum, it would RTS to the original code. I should probably write another check before aforementioned checksum, RTS on control codes and on 215=0.
|
|
|
Post by Xalphenos on Nov 24, 2013 15:54:36 GMT -5
I can see that when 215 = zero it will branch to $BFDF, load zero into the accumulator, store it to the message ID and then RTS. So Where does it RTS to?
EDIT: Didn't see your edit. Yeah I'm thinking there is some check on 215 or message id that needs to be altered to be compliant with your new code.
|
|
|
Post by Ascended Mermaid on Nov 24, 2013 15:58:57 GMT -5
I can see that when 215 = zero it will branch to $BFDF, load zero into the accumulator, store it to the message ID and then RTS. So Where does it RTS to? EDIT: Didn't see your edit. Yeah I'm thinking there is some check on 215 or message id that needs to be altered to be compliant with your new code. Ah! Thank you, yes MessageID should be part of that grand check.
It bothers me because anything after 0 letterpos and linepos should RTS. Maybe I should insert remaining checks after the print jump at bfaa. That way it checks and RTS if necessary.
Also, the game already has an all caps ASCII mode. I don't know why I didn't bother with it, but anyway... I must copy that ppu line to bank 10 and repair the old one. Add in the name screen check I found.
Given the circumstances, I probably don't need the name screen check. Just having a copy of that routine in Bank 10 should be enough.
Any tips on effective data moving? Breaking and fixing branches and jumps is a vicious cycle.
So for next time... Lda 215 Bne Lda messageid Bne Lda character Cmp fa Bcc RTS
|
|
|
Post by Xalphenos on Nov 25, 2013 14:49:01 GMT -5
Ah! Thank you, yes MessageID should be part of that grand check.
It bothers me because anything after 0 letterpos and linepos should RTS. Maybe I should insert remaining checks after the print jump at bfaa. That way it checks and RTS if necessary.
Also, the game already has an all caps ASCII mode. I don't know why I didn't bother with it, but anyway... I must copy that ppu line to bank 10 and repair the old one. Add in the name screen check I found.
Given the circumstances, I probably don't need the name screen check. Just having a copy of that routine in Bank 10 should be enough.
Any tips on effective data moving? Breaking and fixing branches and jumps is a vicious cycle.
So for next time... Lda 215 Bne Lda messageid Bne Lda character Cmp fa Bcc RTS Sorry Not sure how much more help I can be. I just don't have the intimate knowledge of the game that you do. So most of the points you've brought up here I just can't even guess about. About that last bit of code you posted. Isn't 215 = messageid? If it is there's no need to check it twice. About fixing branches and whatnot. This is beyond me on your platform of choice. On PC it's simple. Search for all references to a selected command or byte. I'm not sure if any NES debuggers has a feature like that or not. You could probably use IDA Pro. It supports just about every cpu there is at the cost of about 500 USD. FCE UX was recently updated with better debugging. If you're not using the latest it might be worth checking out.
|
|
|
Post by Ascended Mermaid on Nov 25, 2013 14:59:09 GMT -5
Ah! Thank you, yes MessageID should be part of that grand check.
It bothers me because anything after 0 letterpos and linepos should RTS. Maybe I should insert remaining checks after the print jump at bfaa. That way it checks and RTS if necessary.
Also, the game already has an all caps ASCII mode. I don't know why I didn't bother with it, but anyway... I must copy that ppu line to bank 10 and repair the old one. Add in the name screen check I found.
Given the circumstances, I probably don't need the name screen check. Just having a copy of that routine in Bank 10 should be enough.
Any tips on effective data moving? Breaking and fixing branches and jumps is a vicious cycle.
So for next time... Lda 215 Bne Lda messageid Bne Lda character Cmp fa Bcc RTS Sorry Not sure how much more help I can be. I just don't have the intimate knowledge of the game that you do. So most of the points you've brought up here I just can't even guess about. About that last bit of code you posted. Isn't 215 = messageid? If it is there's no need to check it twice. About fixing branches and whatnot. This is beyond me on your platform of choice. On PC it's simple. Search for all references to a selected command or byte. I'm not sure if any NES debuggers has a feature like that or not. You could probably use IDA Pro. It supports just about every cpu there is at the cost of about 500 USD. FCE UX was recently updated with better debugging. If you're not using the latest it might be worth checking out. 215, in terms of my hack, is a countdown of the lines. At 0, it will wait and request player input before displaying anything further. Wow, that's pricey! I'll definitely update fceux, though I keep older versions for speed. Also, you'be been a tremendous help! I've been keeping a thorough list of thanks for everyone who has assisted me. You've been there since last year or so.
Also, to save myself undue stress, I've made backups. I refuse to repeat any past work again.
|
|
|
Post by Xalphenos on Nov 26, 2013 15:10:12 GMT -5
Also, to save myself undue stress, I've made backups. I refuse to repeat any past work again. That's a good idea. I remember when I worked at walmart during college we were supposed to tell customers that "multiple copies keeps things safe." In an attempt to sell external hard drives with laptops and extra flash memory with cameras.
|
|
|
Post by Ascended Mermaid on Nov 26, 2013 16:32:55 GMT -5
Also, to save myself undue stress, I've made backups. I refuse to repeat any past work again. That's a good idea. I remember when I worked at walmart during college we were supposed to tell customers that "multiple copies keeps things safe." In an attempt to sell external hard drives with laptops and extra flash memory with cameras. Also include "save often". Laptops with faulty batteries and faulty home wiring can be disastrous! My APC is the best money I've spent last year. Also, the Faxanadu speed art on YouTube is pretty impressive, and I was surprised to watch someone play the old collaboration hack from start to finish. Stuff like this makes me proud of my accomplishments and inspired. I wonder what adoru has been up to.
On the ropes about handling the King bug. First, the death; should I restore you to startup HP and zero MP, or let those max as usual for death? I'll wipe any inventory if the restart point is Eolis. Second, I have to take care of the possibility that the player will buy to 0 gold and talk to the king again. Finding free RAM could be useful. I could probably wipe a byte of unused SRAM on new game and death, use that for the King check instead of gold, and set it if the player receives gold. I may have to find free RAM.
I'll probably just stick with the normal respawn health for the Eolis respawn point. There's no reason to deny anyone that much. I suppose that kind of challenge should be a choice.
Then there's the whole thing about the ointment not protecting against magic unless you aren't wearing a shield. I could add an invisible shield with 0 defense for unequipped, and there would be no reason to avoid wearing a shield. Whether or not ointment should protect against magic is debatable, and hard to say if it's an oversight on the developer's end or if it is as it should be. Like my argument before, level design and ointment placement suggest that it was intended to protect against spells.
I know I don't want to change the game too much, but I intend to squash every bug I am able to. This is the hard part - deciphering between bugs and intent.
I'd like to poll these two questions. Unfortunately doing so from mobile isn't working.
I also don't want to forget to eliminate the password screen entirely. The music switches and the screen is drawn ever so briefly.
|
|
RyuKisargi
Chryolos
Beating a Dead Horse
BAP BAP BAP BAP BAP BAP!
Posts: 554
|
Post by RyuKisargi on Nov 27, 2013 23:42:49 GMT -5
I still can't wait for this. You're an amazing person being able to mess with a ROM.
|
|
|
Post by Ascended Mermaid on Nov 28, 2013 20:57:43 GMT -5
Nah, just a hands on learner. Between using the fceux debugger, reading sp's Faxanadu notes, and merely examining a list of opcodes and functions somehow gave me this ability. I was merely dabbling when I undertook this task. I'm sure a more experienced hacker could've done my 4 (?) year job in under a month. You can see in a lot of my posts that I had a hard time understanding what I was looking at. In the end it became instinctive experimentation. Searching, finding, tweaking, testing, learning, and loop.
My 5 year project.
|
|
|
Post by Ascended Mermaid on Dec 1, 2013 15:03:28 GMT -5
It's working now. I just need to clean up my code, fix some minor bugs (which means yet again changing my jumps and branches), handle the King and Ointment bugs somehow, and make the text break a little more neat.
Found a routine for handling end of window line breaks and applied it. Some breaks wipe the window blank, so I plan on eliminating that from FA breaks. Also, I have to fix more bugs when I get back -- sometimes the window stays open and resumes gameplay. At least it stopped crashing.
|
|
|
Post by Xalphenos on Dec 2, 2013 19:46:21 GMT -5
I also have these from the script: オイルでダメ一ジをうけなくなった
オイルの こうかがきれた
ウィングブ一ツの こうかがきれた
アワ一グラスの こうかがきれた Translation courtesy of Google Translate: I no longer receive a bad one in the oil storage
The effect of oil has expired
The effect of one ツ U~ingubu has expired
The effect of one glass bubble has expired Translation courtesy of Hudson USA: I am free from injury because of the ointment.
The power of the ointment is gone.
The power of the Wing Boots is gone.
The power of the Hour Glass is gone. I was looking back to see what you where talking about with the oil and king bug and noticed this. It seems you've mixed up the chouonpu "ー" with one "一". That's why you got a weird google translation. With "a bad one" instead of "damage" and "one ツ U~ingubu" instead of something along the lines of "Wingboots." Just thought you should know so you can fix your table. I saw a translator on RHDN get upset when someone posted a script dump with messed up "ー" probably an isolated case though.
|
|
|
Post by Ascended Mermaid on Dec 2, 2013 20:32:19 GMT -5
Ah! Thank you very much, I'll be sure to fix this. As for the oil and king bugs...
Ointment: If you have a shield, the ointment won't protect from magic damage. If you don't have a shield, magic will pass through you.
King: If you talk to him with 0 gold, you receive 1500 more. You can buy and die (or spend to 0) to your heart's content.
I must add that having "no shield" also counts when you are wearing the battle helmet. I think I may make sure the battle helmet works as intended.
I mean it protects against "almost" all magic damage. I'm merely asking the question "...or does it?"
|
|
|
Post by Xalphenos on Dec 2, 2013 21:55:33 GMT -5
I don't yet have an opinion on the ointment or battle helmet. The king bug seems like a classic easter egg to me. I personally would leave that bug intact, even if it wasn't intended. Bugs like that where so fun to track down back in the day.
|
|