MEGA65 / mega65-rom-public

MEGA65 ROM public issue reporting
4 stars 0 forks source link

SETBNK not working for banks > 0 #124

Closed ki-bo closed 3 weeks ago

ki-bo commented 4 months ago

Test Environment (required) You can use MEGA65INFO to retrieve this.

Describe the bug When trying to load a file to a dedicated load address > $FFFF, I noticed that the documented kernel API to configure the bank of the load address is available (see C65 specification), but it just won't work. The file still got loaded as if the bank was still configured to 0.

To Reproduce Steps to reproduce the behaviour:

  1. Try to load a file to an upper bank address, eg. like this:

    
    // Loading file "M11" to $45001
    // (but seems to be loaded to $05001 instead...)
    lda #$03
    ldx #<filename
    ldy #>filename
    jsr $ffbd        // SETNAM
    lda #$00
    ldx #$08
    ldy #$00
    jsr $ffba        // SETLFS
    lda #$04
    ldx #$00
    jsr $ff6b        // SETBNK
    lda #$00
    ldx #$01
    ldy #$50
    jsr $ffd5        // LOAD
    
    bcc loadok
    lda #2
    sta $d020
    jmp *
    loadok:
    inc $d020
    jmp loadok

filename: .text "M11"


2. Make sure the file `"M11"` as specified at label `filename` is available on the disk and run the program
3. If the file can be found  (no red border will appear) it will get loaded but to the wrong address

**Expected behaviour**
The file contents (excluding the first two bytes in the file) should appear at address $45001. Instead, they get loaded to address $5001.

**Additional context**
I learned via discord that a while ago this behaviour was changed intentionally. Still, I am questioning the decisions from back then looking at it now that I learned about what was changed.
The new implementation is expecting the user to configure two high-bytes of the LOAD target address via direct access to undocumented ZP addresses. This is not-intuitive and does not match the idea of having a clear kernal API. Additionally, it is unclear why the functionality of the SETBNK API needs to be disabled completely in this case, although it would be perfectly fine to still use it for chip ram target addresses.

I understand the motivation was to support addresses >24 Bits, as SETBNK only supports a single byte for the bank, but the MEGA65 supports 28 bit addresses (which is needed to be able to load to attic ram, for example). The bug report is about restoring the original behaviour of the kernal API and find another way to extend the API to allow for loading files to addresses > 1MB.
ki-bo commented 4 months ago

Proposal to support load addresses > 1MB in a backwards compatible way:

  1. As the C65 only supported 8MB of address space (it has 23 address lines), we could assume that the MSB of the bank byte would have stayed unused, anyway. I even believe there were other occasions where commodore used the upper bit of bank for some other information.
  2. We could use the MSB of the bank byte to indicate that we want to configure an address >23 bits.
  3. The unused y register could be used to provide the additional bits of the address. We need five more bits for the address (MEGA65 supports 28 bit addresses vs. 23 bit addresses on C65). The lower five bits of the y register could be used for that purpose, keeping the upper three bits defined as "reserved, shall be set to 0, should be ignored by implementations"
ki-bo commented 4 months ago

An alternative proposal which might be easier to use from a user perspective:

  1. Values A=0..127 are treated as BANK, allowing for addressing 8MB of address space, just like on the C65 (see above)
  2. If A > 127, then we take bits 0..3 from A as MSB (bits 27..24) of the 28 bit address, and take Y as bits 23..16

This will allow for backwards compatible setting of larger addresses, and does not need shifting of bits for the user.

; Three examples:

; Setting BANK for address $4xxxx
LDA #$04    ; set bank for load to $04
LDX #$00    ; bank for filename address
JSR $FF6B

; Setting BANK for address $800xxxx (attic ram)
LDA #$08    ; bits 27..24 of address
ORA #$80    ; mark as 28 bit address
LDY #$00    ; bits 23..16 of address
LDX #$00    ; bank of filename address
JSR $FF6B

; Setting BANK for address $FF8xxxx (colour ram)
LDA #$0F    ; bits 27..24 of address
ORA #$80    ; mark as 28 bit address
LDY #$F8    ; bits 23..16 of address
LDX #$00    ; bank of filename address
JSR $FF6B
dansanderson commented 4 weeks ago

Adding the relevant details here because I want to fix this soon. I like the A > 127 proposal.

"direct page 32 bit pointer eal ($ad,$ae,$af,$b0)" https://discord.com/channels/719326990221574164/782757495180361778/1028680048204587068

dansanderson commented 4 weeks ago

... For completeness, I think the filename bank could also be made 28-bit in the same way with the Z register. The routine that accesses it would have to be rewritten to use lda [zp4],z instead of lda_far.

dansanderson commented 3 weeks ago

This is now implemented. The test program passes as written, and the proposed 28-bit API for both data and filename now works.

dansanderson commented 3 weeks ago

Now documented in the new jump table reference: https://github.com/MEGA65/mega65-user-guide/commit/44cebcb5f374c1ecb15f8b89cb4aa1b807d0c8b8

(ROM 920398 will be released soon.)