MEGA65/open-roms

mega65_ftp has some niggling problems with OpenROM

Closed this issue · 10 comments

Falk mentioned he was having issues getting mega65_ftp to communicate with OpenROM.

I had experienced something similar recently and had a workaround, so the issue, and the workaround got described in this recent discord thread:

I recall that I had recently updated the mega65-core's open-rom reference to your latest (21032520), so I tried reverting to the version that was used prior to that (20092520), but a similar issue occurred there.

If I understand correctly - Open ROMs is able to run the helper code, but the problem is with starting it up by the tool itself ( https://github.com/MEGA65/mega65-tools/blob/master/src/tools/mega65_ftp.c )?

I have briefly looked into the tool source code - the first place I would suspect is this one (currently lines 742-747):

detect_mode()

if ((!saw_c64_mode)) {
  start_cpu();
  switch_to_c64mode();
}

I'm not sure how this does the job, but Open ROMs is very different from C65 ROM, and IMHO this is likely to fail - I don't know how C65 ROMs realizes switching to C64 mode internally, and I didn't provide any compatibility for this.

  1. Open ROMs native mode was designed to allow easy porting of the C64 code (BASIC starts at $0801, like on the C64) - does your workaround function properly if you start the helper with GO SYS 2061 instead of RUN? This will prevent switching to C64 compatibility mode; if the helper does not manually write anything to screen memory ($0400-$07FF) but uses Kernal routines, it is likely to still work.

  2. If point 1. worked, try to remove the lines I have mentioned from mega65_ftp.c - does it work?

We should simply add OpenROMs detection to the m65common framework, and improve the various tools to properly recognise when OpenROMs is running, and not try to switch modes in that case, since OpenROMs is effectively in both modes at the same time.

Yep, that "mega65_ftp.c" is the right file of interest:

Having a look at your suggestions now:

  1. After uploading the program, I manually typed GO SYS 2061 and it worked. On another occasion, I tried manually typing SYS 2061, and that worked too.
  2. After stepping through this part, I noticed that detect_mode() already checks for open-rom's existence and sets saw_c64_mode=1, so the section of code you indicated is getting skipped over already.

While stepping through, I also noticed the point where it triggers that BRK AT $0009 message is due to this point:

      // Launch helper programme
      snprintf(cmd, 1024, "g080d\r");
      slow_write(fd, cmd, strlen(cmd));

So it seems like the uart-monitor simply forcing PC=080D isn't equating to calling BASIC's SYS or GO SYS.

For now, I've managed to work around the problem by adding some open-rom specific logic like this:

      if (saw_openrom) {
        stuff_keybuffer("RUN\r");
      }
      else {
        // Launch helper programme
        snprintf(cmd, 1024, "g080d\r");
        slow_write(fd, cmd, strlen(cmd));
        wait_for_prompt();
      }

Actually, when I tried using the stuff_keybuffer("RUN\r"); trick with closed-rom, it worked there too, so perhaps I should just use that technique for all cases and get rid of the g080d uart-monitor command entirely.

That's really strange - if "GO SYS 2061" worked, I see no reason why jump to $080D could fail. Open ROMs does not usually map anything into this memory region (I think the built-in BSMON port and the Z80 simulator are the only components that does this). One would have to check what the 'g' command really does.

Ok, will aim to dig a little deeper into it soon.

I thought I'd try debug it via xemu today. I put the openrom mega65.rom into the sdcard image for xemu, and tried to debug there.

Ok, when the g080d command is issued:

  • I see the start of the program executing fine.
$080D        M_nn:1 A5 01    LDA $01
$080F      M_nnnn:2 8D 5F 59 STA $595F
$0812     M_immnn:1 29 F8    AND #$F8
$0814     M_immnn:1 09 06    ORA #$06
$0816        M_nn:1 85 01    STA $01
$0818      M_impl:0 BA       TSX
$0819      M_nnnn:2 8E 60 59 STX $5960
$081C      M_nnnn:2 20 87 59 JSR $5987
  • But it's that JSR $5987 that proves to be problematic. Instead of jumping to that part of the program, it seems to have jumped into OpenROM instead:
$5987        M_rr:1 D0 05    BNE $598E
$5989        M_nn:1 C6 D3    DEC $D3
$598B      M_impl:0 3B       DEZ
$598C        M_rr:1 10 F4    BPL $5982
$598E      M_impl:0 FB       PLZ

Taking a look at the MAPL and MAPH values in the monitor:

PC   A  X  Y  Z  B  SP   MAPL MAPH LAST-OP     P  P-FLAGS   RGP uS IO
5991 00 F7 08 1E 00 01F6 0200 4000 A5       22 00 --E---Z-

Hmm, so a MAPL of 0200 seems to indicate that nothing ought to be mapped in at this point in time, so it's puzzling as to why it is pointing to the ROM at this point.

Aah, but if the upper nibble of MAPL and MAPH inside xemu has been mixed up (and if MAPL is really 4200), then yeah, that'd mean there's a ROM mapped into that $4000-$6000 chunk.

I'll assess the xemu code for this xemu output to confirm...

Ah yep, taking a look at the xemu-code, I think the MAPL and MAPH have the upper nibble muddled, so it should have read as MAPL=4200, MAPH=0000.

Took a look at MAPL and MAPH on my devkit hardware just now, and it reported that in openrom, it starts with this value:

PC   A  X  Y  Z  B  SP   MAPH MAPL LAST-OP In     P  P-FLAGS   RGP uS IO ws h RECA8LHC
5670 00 FF 0A 00 00 01F6 0000 4200 2068FA  00     23 ..E...ZC ...P 3C -  00 - .....lhc

Aah, so xemu even has the ordering of MAPL and MAPH wrong in this list, I'll chase this up with Gabor :)

But yep, this confirms that the region $4000-$6000 is getting mapped to the ROM, and looks to be why mega65_ftp chokes.

So perhaps BASIC commands like SYS and RUN are doing some extra work to un-map this area during the program's execution?

Ah yep, as a test of this, in xemu, when I tried adding a breakpoint on 080d, and then typed RUN, the MAPL and MAPH were set like this:

PC   A  X  Y  Z  B  SP   MAPL MAPH LAST-OP     P  P-FLAGS   RGP uS IO
080F 27 00 00 00 00 01F5 0000 0000 A5       20 00 --E-----

So yeah, seems like doing a g080d won't equate to RUN or SYS, so I'm feeling it's safer for mega65_ftp just to type in RUN instead.

That's because native mode CHRIN is operating. The legacy mode one operates from standard C64 Kernal ROM area, but there is no space there for additional, native VIC-IV screen editor - it is placed in extra ROM bank and mapped in from $4000 when needed.

Ok, fair enough, given that, I'll stick with the approach of fixing this on the mega65_ftp-side, by replacing g080d with RUN.

Happy to close this ticket.