wudsn / wudsn-ide

WUDSN IDE
https://www.wudsn.com/index.php/ide
23 stars 9 forks source link

Merlin DSK ESDOS Error #15

Open imirisola opened 1 year ago

imirisola commented 1 year ago

Hi,

I am trying to compile a simple source code with Merlin32 and run it with AppleWin1.30.13.0. The compilation process works and it automatically creates a DSK file that can be used to run the application on the emulator. However, this DSK is formatted with ESDOS(??) and the file attributes are kind of weird. If I create an empty ProDOS1.4.1 and copy the ".b" file with CiderPres into it I am able to run it by changing the file type to $06 and Aux Type set to the same address value as what I have in my ORG directive (ORG $8000). While examining the DSK generated by WUDSN the file has the correct file type but the Aux Type is wrong. Instead of having it with 8000 (same as ORG in the source code) it has the value 1620. If I open it with CiderPress and view this binary file it displays the code starting at $1620. In addition to it, the code stored on this file is very different. The first opcode used on my program should be "20 EC 80" and instead the file starts with "7F". So when I run this disk on the emulator, I get a monitor prompt instead of the application running: The emulator states "Loading Balls" 80F0 - A-16 X=9D Y=00 P=36 S=F0 If I go to address $1620 I see the same opcodes I see via CidePress which is probably what is performing a jump to subroutine at address $80EC (which kind of looks like why it terminates at address 80F0).

Am I missing something or doing anything that is not supported?

Would it make more sense to have settings related to disk image (OS templates to be used for the disk) and file attributes, etc? This way we could control how the disk image gets generated. It would also allow you to have a Hard Disk Image (2mg format) to run on the emulator which would contain additional tools and your binary file.

BTW: I am using Eclipse Version: 2023-06 (4.28) with the following plugins: WUDSN Base Feature 1.7.2.202303171941 com.wudsn.ide.base.feature.feature.group WUDSN WUDSN IDE 1.7.2.202303171941 com.wudsn.ide.feature.feature.group WUDSN

Best regards, Ivan

imirisola commented 1 year ago

Just some update on this:

I've modified my code in order to make it work properly, but I still need to modify the DSK and the BASIC program so it really works as expected.

1) I have to add a 4 byte header into the assembly language like so:

hex 00,20,ff,ff

Those bytes will be completely ignored once the dsk image gets generated. Hence the program will start at the indicated ORG instruction.

2) Every label reference will require a 4 byte 'subtraction' so it really references the correct address, since we added those 4 bytes at the beginning of the code. Hence I had to use the following:

lda mySTR-4,x

instead of

lda mySTR,x

which should be the correct way of coding IMHO.

3) I still have to modify the disk's contents so it runs as expected. I have to change the Aux type (hex) from 2000 to 0300. I don't really know where this 2000 comes from (2000 in both hex or dec have no relation to 300 whatsoever). But whenever I change the ORG of my code, this value changes as well. So, once I modify it to 0300 via CiderPress, the program gets loaded into memory the right way at $0300.

4) Since the value 2000 is injected into the disk, its decimal value is going to be injected into the BASIC program that gets called when the machine boots. So, after the disk loads, I still get an error. But after adjusting the BASIC program with: CALL 768, it works perfectly.

It seems that the code responsible for generating the dsk is not correct.

Here is the complete code modified:



        DSK HELLO.b
    SAV HELLO.b

     TYP $06 ; binary file type

         org   $300

     hex 00,20,ff,ff

COUT     equ   $FDED      ; Char out std subroutine
         ldx   #0         ; load x-register with zero
lp       lda   mySTR-4,x    ; start loop, load char number x from myStr
         beq   theEND     ; exit loop if $00 at end of string
         jsr   COUT       ; output character to screen
         inx              ; icrement counter (x-reg)
         bne   lp         ; goto lp if not zero
theEND   rts              ; quit back to system

mySTR    asc   "Hello World from Brazil."00```

Best regards,
Ivan
imirisola commented 1 year ago

Hi,

I believe I understand now what is happening. I modified my code a bit and now there is no need to modify the disk via CiderPress and now the BASIC program is getting created correctly. My program was missing the ADR directive and it seems this defaults to 2000.

I still think there is something wrong with the way the disk gets created. I am having to add a 4 byte to my string as well as an initial opcode that gets stripped out from the file in disk.

My working code now is:

* Simple Hello World for the 6502
; @com.wudsn.ide.lng.hardware=APPLE2

        ORG $0300

        TYP $06     ; binary file type // MANDATORY
        ADR $0300   ; Aux Type must be same as ORG // MANDATORY
                ; this 3 bytes will be stripped out from the actual file on disk.

        DSK HELLO.b

; Apple Routines        
COUT    equ   $FDED     ; Char out std subroutine

        NOP     ; this 1 byte will be stripped out from the actual file on disk.

; Main Program
        ldx   #0    ; load x-register with zero
lp      lda   mySTR,x   ; start loop, load char number x from myStr
        beq   theEND    ; exit loop if $00 at end of string
        jsr   COUT  ; output character to screen
        inx     ; icrement counter (x-reg)
        bne   lp    ; goto lp if not zero
theEND  rts         ; quit back to system

; Data
mySTR   asc   00,00,00,00,"Hello World from Brazil.",00 ; Because Apple Disks require a 4 byte header, 
                            ; all relative addresses will move 4 bytes as well.
                            ; so we need to add 4 bytes before the actual string starts
                            ; zero byte at the end of the string is required to detect when to stop

The ADR and NOP opcodes should be listed on the disk's binary file. However, they get lost when the binary code gets transferred to disk. So the first line at address 300 will actually be the LDX - which is the main program.

Everything else gets generated as it was supposed to be, except the ASC data. Since there is an "extra" 4 bytes in the binary code generated by Merlin32, I had to add an extra 4 bytes before the actual string. So the LDA will point to mySTR at position 4 instead of 0 which would string 4 characters from the word Hello.

All of this seems to be a workaround situation and shouldn't be required in a simple Merlin code as this.

Best regards, Ivan

peterdell commented 10 months ago

Thanks for the report. I m currently busy with my job and will reply here as soon as I can.