溢出关卡吧 关注:250贴子:3,572

关于SMB1相关问题的专属提问帖

只看楼主收藏回复

这个帖子实质和上一个帖子一样,就是换了个名字


IP属地:贵州1楼2021-08-28 22:05回复
    同样是之前那个帖子的第一个问题涉及到的一个ROM(80KB改过地图有2代元素),它用的是一个比较基础的切bank方式,Mapper1。在我比较详细了解Mapper后,我发现Mapper1可能是切bank最谜的一个方式:
    1.我自己把这个硬重置输入数据到SRAM的程序复制到了我自己的hack里,发现在一开始,程序是从$0000开始执行的,即读取到了一个BRK,跳转到了$FF00,执行输入程序。这是Mapper 1 的固定起始地址吗?如果在实际上执行,可能不能直接读到BRK,就会有问题吗?
    2.Mapper 1中对$8000,$A000,$C000和$E000设置了只写寄存器,当中每个寄存器最多用到D4,D7-D5不会用到,但在程序的一开始就用了一个LDA #$80 STA $8000,并且删了就不能正常运行...难道我查阅的帖子不全?
    3.对于输入到SRAM的8KB数据,是完全可以放在最后一个bank里,游戏中的$C000-$DFFF的,但是FCEUX可能会把3个PROM强制填充16KB的FF,导致游戏无法运行,这有什么解决方案吗...
    以下是关于游戏本身的问题:
    4.对于那个ROM和2代一类改版,都可以在城堡关过关结算时间,但我经过调试发现问题不简单:
    (1)最终它们都会通过$8E16的默认跳转程序跳到减时间的程序,但是和一般拉旗过关的不同地址,程序相同;而那个ROM会有一个$D31D的子程序入口,后面的代码我就理解不能了,ASL还改成了NOP,很是迷惑...
    (2)程序里有涉及到$0747,通过查阅Memory map,根本理解不了那个“master”是什么意思,就还是不知道这个内存地址是干嘛的...


    IP属地:贵州2楼2021-08-28 22:36
    收起回复
      Mapper的事情我还不太了解,所以前三个问题我没法回答;不过执行程序的起始地址是$0000?难道不应该是RES向量地址是$FF00,程序直接从$FF00开始执行么……如果真的是从$0000开始的,那你最好检查一下你对RES向量和IRQ向量分别是怎么设置的,你该不会是把RES向量写成了$0000,IRQ向量写成了$FF00吧
      4.(1)这个时间算分的程序确实是拉旗和踩斧过关通用的,入口就是这个$D31D;准确说,这个入口真正的起点应该是$D312,这是拉旗算分的入口,多出来的一段程序功能是判断时间是否已经归零了,而踩斧算分则是先“时间减1算成分数”,然后再判断时间是否归零的,也就是两者的判断时机不同,这也导致了“城堡关0时间过关会结算1000时间单位的得分”这一bug的出现不过,这段代码我没看到什么ASL啊,倒是NOP有一堆……
      (2)$0747是一个用途广泛的定时器和标志内存(既是定时器,也是某些事件的标志),目前我所知道的只有下面这个:当吃蘑菇、吃花、受伤、碰敌人死亡的时候,画面要定住一段时间,这时就会用到$0747。


      IP属地:上海3楼2021-08-29 14:07
      收起回复
        (以下内容提到的ROM:1XkL_54YyUsyMG8IJTGNGxQ 6502)
        在研究这些功能时,我才发现标题界面B键选关不显示,无论按多少下B都会显示2-1,但实际$075F的值没有问题,也能正常跳转;通过对程序的调试发现,一般在按下B键时会执行$80C3处的JSR $8EDD,而这时我改过的ROM直接跳过了这行代码,跳过了$8EDD这些程序,甚至可以说是$80C3附近整个程序都被跳过了...明明我也没改这段代码...
        (文件里mappertest1和2都有这个问题,没加mapper的那个文件没有问题)
        我下次再打开贴吧可能就是下周末了,要开学了


        IP属地:贵州4楼2021-08-29 22:10
        收起回复
          回复4楼:
          提取码6502好评
          看了一下你提到的那几个位置的程序,确实没发现什么问题(没有上模拟器调试),那么这个问题就不好说是什么原因了
          不过我多看了一下其他地方的修改,发现了一些很眼熟的东西这个我就想说一下了,既然已经扩容了,那么新加的功能就可以写到新的数据块当中了,没必要再牺牲原有的功能来做修改了
          至于你说的其他新增功能,城堡关结算时间不是2代日版本来就有的功能么,只是个抄程序的事吧“续关跳小关”这个似乎挺吸引人的,仔细看了代码确实也对$075C和$0760做了分别处理,不过下面这段程序似乎可以优化一下:
          CMP $6180,X
          BCC #$03
          CLC
          ADC #$01
          改成这样:
          CMP $6180,X
          ADC #$00
          立省3个字节(要学会巧用ADC指令,不要单纯地当成普通的加法指令,你要明白ADC的C是什么意思)
          还有,先把$013F的值存入$075C,然后再执行上面的代码并存入$0760,不就不用从$013F重新读取一次了么,又可以省3个字节


          IP属地:上海5楼2021-08-30 16:05
          回复
            我是服了这游戏了...
            (那些省字节的代码我还没来得及改)
            今天我又新增了些功能(像是拆分跳关区什么的),本来增加了一个“重置时把$075F和$075C写入$07FD和$013F”的功能,不知道怎么还是因为没保存,后来这个程序就没了,我就重新写了一次(地址和原来不同,ROM由于被覆盖找不到),就在这之后,这个事情发生了...
            在扩容区中,$6106在BNE #$0D(D0 0D)的D0的位置,这段程序负责在每次在初始化堆栈时会在非电源时跳过$013F的初始化,结果发现,软重置第一次后,$6106变成了D1,此时D1 0D组成的代码还能执行,然后再软重置一次后,$6106变成了D2,一个未定义指令,PC不走了,和FF一个效果...
            一开始我以为是程序哪里地址写错了,把$7Fxx的一个地方写成了$6106,但通过FCEUX的调试发现,这个地址在监测中除了LDA($02),Y的复制$C000-$DFFF到$6000-$7FFF外,$6106没有受到过任何别的寄存器修改(即STA/STX/STY),而它的值无故加1了...
            我尝试在PC不走崩溃后手动修改$6106,结果发现,修改为正常之后软重置,$6106会变回D0然后立即变成D1;当其值为44时,输入后很快会被改成45,改成48则直接重置(是内部重置,没有软重置)...在图中我发现,周围有一些地址的数值同样也是没受寄存器修改,但改成了PRGROM中的对应值...就算是Mapper1也不会对SRAM进行不经寄存器的修改吧?
            1B7ocz8ce5IPoNZeFZAtxXA unde


            IP属地:贵州6楼2021-09-04 22:50
            收起回复
              行了,破案了



              IP属地:贵州7楼2021-09-05 08:51
              收起回复
                花了一个多月研究写的专栏发了能看一下嘛
                cv13148196


                IP属地:贵州8楼2021-09-12 19:55
                回复
                  没有B站账号的路过
                  就在这里简单评论一下你的这些修改吧。
                  第一条不用说了,毕竟我也参与过排查工作不过有一个问题,说好的“JSR $2026后面会讲”,好像没看到哪里讲了啊……
                  第二条,关于刺猬的问题,实际上刺猬的初始化程序$C7A0是“持续型敌人”(ID范围是$12~$17,除去废弃敌人$13)的通用初始化程序,你要是仔细看看这段程序,会发现这里还有一个JSR $8E04,然后刺猬对应的跳转地址是$C3A4,内存表可以查到这个入口是快乐云和刺猬共同的生成程序,这也就是“加载刺猬会召唤快乐云”的原理。你的修改方法当然也可以(把这个召唤特性去掉了),但直接让刺猬不再是持续型敌人(即干脆不执行$C7A0的程序了),岂不更好?不过,“设置初始速度”这部分修改,我倒是也想做一个出来
                  第三条,关卡序号的显示,其实空格($24)没必要写入的吧?也就是原来写3个字节的显存,现在只需要写1个字节(就像选关的时候那样)。当然,这么修改虽然改出来的代码更简单,但是修改过程反而更复杂一些,修改量更大,像你这样偷懒一下也是可以的


                  IP属地:上海9楼2021-09-13 11:28
                  收起回复


                    不知道这些文字哪里又出问题了,懒得申请恢复,直接截图重发


                    IP属地:上海11楼2021-09-14 19:06
                    收起回复
                      这两天在学校闲着没事干就来写代码,肯定漏洞百出
                      另外貌似FF这个未定义指令码是“对后面两个字节所构成的地址后面第255位加1”,FF 07 60就是IN $6106(没有C),这似乎能解释为什么用那个版FCEUX打开VS版会有噪音,因为一直在执行FF FF FF即IN $00FE,就是不断设置它为01,金币音效(10才是结算分的音效)...不知道这个推论正不正确
                      之前因为FF 07 60导致的6106从C0变成C2,要是B2或D2,就是个JAM,肯定不会走;C2也不会走,这原因又是什么...又不是JAM


                      IP属地:贵州来自Android客户端12楼2021-09-17 21:38
                      收起回复
                        虽然没有回复,我想了一下还是来发帖了
                        改了个刹车音效,然后拉旗的时候马里奥图像不动了,还是跑步的姿势...找半天找不到问题在哪
                        1HJsZIw3j0PsulUyNDoGnkg 2333
                        修改途中有这个效果(没有这样的ROM,一拉旗就崩溃了)




                        IP属地:贵州13楼2021-09-20 17:55
                        回复
                          失踪人口回归
                          关于FF这个指令码的解释似乎挺合理的
                          13楼那个ROM,我随便拉到一个地方看了一眼,好像看到一个JMP的地址写错了,前后没有交换过来然后想仔细研究研究的,但是感觉指令有点多,懒得看了不过,为什么没有用到的ROM空间是用字符8填充的啊


                          IP属地:上海14楼2021-10-01 14:57
                          收起回复
                            经过一天,我终于来发帖了
                            才改的,本来限定W9也会有通关文字并且文字不一样(还没做,现在是乱码),结果W1-W7文字有都没有...我头都昏了
                            1K54z6RDM-IFrOH00lHylwA bbkk
                            填充全是8原因说不出来了,被吞了两次了


                            IP属地:贵州15楼2021-10-02 23:30
                            回复
                              回复15楼:
                              我很好奇到底是什么话百度不让说(不过没法说那就算了)
                              这次的修改……同样的,改动的地方比较多,无关的就不看了,只看了这两个位置:
                              文件偏移$00CF处,这里应该是“显存缓冲区指针高字节”,你把这个数据源的地址改了,相应的低字节数据源却没改……这波操作倒是挺有意思的;至于改后的地址$7280(这地址我一开始还以为你又写反了呢),这个应该对应文件偏移$D290,对吧?
                              文件偏移$0406起始的程序(运行时内存地址$83F6起始),就是用来显示通关文字的,改动还挺大的,加了4段程序调用啊其中,前两段是判断$075F的值,原来的条件是等于7(或者不等于7),你加了个8;第三段原版是将A的值加$0C,你改成了“如果$075F>7,则A额外加4(代码里是3,但是此时C必然等于1,因为任何无符号数都大于等于0)”;第四段是判断$0719的值(注意不是$075F),其实没必要改的。
                              表面上看没啥问题,不过你这里的堆栈操作么……本意当然是把JSR放进来的返回地址去掉,但是PLA可是会影响A的值的。看看第一段程序JMP回来之后的情况吧:
                              CMP #$02
                              BCC #$2B
                              TAY
                              BNE #$08
                              再往后就先不看了,有没有意识到什么问题?没错,这里还要继续使用之前的A的值,所以A是不能乱改的,一改自然就废了。所以,你还是要认真思考一下这里到底应该怎么改如果不想大段修改原版程序,可以用JMP代替JSR进行跳转(RTS也要改成JMP);如果还是想用JSR,倒是也有个投机的办法,给个提示:有两个指令TSX和TXS可以通过寄存器X修改堆栈指针的位置,先用TSX把值抄给X,然后让X加2(两次INX),再TXS抄回去,就解决了。
                              ……嘛,翻页的时候还是看到了一处无关的位置,然后唐突恶臭(你知道我说的是哪个位置的)


                              IP属地:上海16楼2021-10-03 11:17
                              收起回复