X16Community / x16-emulator

Emulator for the Commander X16 8-bit computer
BSD 2-Clause "Simplified" License
183 stars 40 forks source link

Unclear behaviour when running trace on custom rom #229

Closed stefanoborini closed 6 months ago

stefanoborini commented 7 months ago

I am doing something a bit crazy so I am not surprised it's giving me some strange results, but I am trying to create an extremely simplified unix-like kernel just for fun, and I need to start from somewhere.

I created a rom image with the following map:

MEMORY {
    EMPTY:    start = $0000, size = $BFFF, fill=yes, fillval=$00;
    KERNAL:   start = $C000, size = $3E98, fill=yes, fillval=$00;
    VECTORS:  start = $FFFA, size = $0006, fill=yes, fillval=$00;
}

SEGMENTS {
    INIT:     load = KERNAL,   type = ro;
    NMI:      load = KERNAL,   type = ro;
    IRQ:      load = KERNAL,   type = ro;
    VECTORS:  load = VECTORS,  type = ro;
}

xxd confirms the content to be correct

$ xxd -a build/x16/rom.bin 
00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
0000bff0: 0000 0000 0000 0000 0000 0000 0000 00a2  ................
0000c000: ff78 9a58 38ea 4c06 c040 4000 0000 0000  .x.X8.L..@@.....
0000c010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
0000fe90: 0000 0000 0000 000a c000 c00b c0         .............

The segment content is very trivial and just does basic initialisation and a nop loop

.feature labels_without_colons

.segment "VECTORS"
.word nmi
.word start 
.word irq

.segment "IRQ"
irq
    rti

.segment "NMI"
nmi
    rti

.segment "INIT"
start
    ldx #$ff
    sei 
    txs
    cli 
    sec

loop
    nop
    jmp loop

I tried starting the emu with the following line:

$ x16emu_macos-r46/x16emu -rom build/x16/rom.bin -trace

and I assumed I would see the trace of my code, but this is not the case. I get:

Unable to find KERNAL cbdos_flags
[       0]                      --:.,0000 59 55 4b eor $4b55,y    a=$00 x=$00 y=$00 s=$fd p=--.b-i-- m=$4b55 
[       1]                      --:.,0003 e5 a9    sbc $a9        a=$15 x=$00 y=$00 s=$fd p=--.b-i-- m=$00a9 
[       2]                      --:.,0005 a7 4b    smb2 $4b       a=$b0 x=$00 y=$00 s=$fd p=n-.b-i-- m=$004b 
[       3]                      --:.,0007 4f 57 8a bbr4 $57, $fff a=$b0 x=$00 y=$00 s=$fd p=n-.b-i--         
[       4]                      00:.,ff94 00 00    brk            a=$b0 x=$00 y=$00 s=$fd p=n-.b-i--         
[       5]                      --:.,0000 59 55 4b eor $4b55,y    a=$b0 x=$00 y=$00 s=$fa p=n-.b-i-- m=$4b55 
[       6]                      --:.,0003 e5 a9    sbc $a9        a=$a5 x=$00 y=$00 s=$fa p=n-.b-i-- m=$00a9 
[       7]                      --:.,0005 a7 4b    smb2 $4b       a=$40 x=$00 y=$00 s=$fa p=-v.b-i-c m=$004b 
[       8]                      --:.,0007 4f 57 8a bbr4 $57, $fff a=$40 x=$00 y=$00 s=$fa p=-v.b-i-c         
[       9]                      00:.,ff94 00 00    brk            a=$40 x=$00 y=$00 s=$fa p=-v.b-i-c         

and this repeats forever

Is this some preamble that the emu inserts? I don't get this when I start a normal x16 rom.

I guess there's something I don't understand of the architecture, but as far as I know this is all that's required for a bootstrapped barebone system.

mooinglemur commented 6 months ago

ROM banks are 16k. You should omit the EMPTY MEMORY region as it's being prepended to your file. What you've effectively done is create a ROM with 4 banks. Banks 0-2 are empty (fillval=$00) and bank 3 is your custom kernel. This is obviously not what you want.

Your ROM output should be 16k in size, not 64k, so hexdump would put your vectors at $3FFA, but since the beginning of the ROM is loaded at $C000, and is run from $C000, it will all work out.

mooinglemur commented 6 months ago

Actually, at second glance, you don't quite have that, even. Your EMPTY region is BFFF long rather than C000, so the first byte of ROM ended up at position BFFF in the .rom file rather than C000.

stefanoborini commented 6 months ago

@mooinglemur Thanks. I'm trying to make it work but I am still figuring it out.

But I still don't get from where those opcodes in the trace come from. It's not even an alignment issue. Nowhere in the rom image I have a $59 or a $55. Something else must be providing those bytes, and I have a suspicion that the emulator is actually going through zero page after being redirected by a boot up vector that is... well... empty and thus pointing at $0000, so it jumps to zero page.

I suspect this is what's I'm seeing in the trace, but I am not sure.

stefanoborini commented 6 months ago

This works!

MEMORY {
    #include "x16.cfginc"
    KERNAL:   start = $C000, size = $3FFA, fill=yes, fillval=$00;
    VECTORS:  start = $FFFA, size = $0006, fill=yes, fillval=$00;
}

SEGMENTS {
    INIT:     load = KERNAL,   type = ro; 
    VECTORS:  load = VECTORS,  type = ro; 
}
.feature labels_without_colons

.segment "VECTORS"
.word nmi
.word init
.word irq

.segment "INIT"
nmi
    rti
irq
    rti
init
    ldx $01
init2
    inx
    jmp init2

Gives this image

xxd -a build/x16/rom.bin 
00000000: 4040 a601 e84c 04c0 0000 0000 0000 0000  @@...L..........
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00003ff0: 0000 0000 0000 0000 0000 00c0 02c0 01c0  ................

Which, as you said, it must be 16k. The trace now gives the right opcodes

Unable to find KERNAL cbdos_flags
[       0]                      00:.,c002 a6 01    ldx $01        a=$00 x=$00 y=$00 s=$fd p=--.b-i-- m=$0001 
[       1]                      00:.,c004 e8       inx            a=$00 x=$ca y=$00 s=$fd p=n-.b-i--         
[       2]                      00:.,c005 4c 04 c0 jmp $c004      a=$00 x=$cb y=$00 s=$fd p=n-.b-i-- m=$c004 
[       3]                      00:.,c004 e8       inx            a=$00 x=$cb y=$00 s=$fd p=n-.b-i--         
[       4]                      00:.,c005 4c 04 c0 jmp $c004      a=$00 x=$cc y=$00 s=$fd p=n-.b-i-- m=$c004 
[       5]                      00:.,c004 e8       inx            a=$00 x=$cc y=$00 s=$fd p=n-.b-i--         
[       6]                      00:.,c005 4c 04 c0 jmp $c004      a=$00 x=$cd y=$00 s=$fd p=n-.b-i-- m=$c004 
[       7]                      00:.,c004 e8       inx            a=$00 x=$cd y=$00 s=$fd p=n-.b-i--         
mooinglemur commented 6 months ago

But I still don't get from where those opcodes in the trace come from.

RAM is uninitialized and has random values at start. Your reset vector (at offset $3FFC in the ROM file, running at $FFFC) pointed to $0000, and thus you began executing random code.

stefanoborini commented 6 months ago

Thanks!