Getting old, getting stupid. Can't even make "Hello World" to run correctly anymore

Página 1/2
| 2

Por Thom

Hero (592)

imagem de Thom

07-09-2019, 15:59

I used to know Z80-assembly and I thought well, after about 20 years I should be able to do it again. For fun. However, my brains have not aged well, it seems.

I managed to construct a tasks.json for VS Code which runs a cmd-file which compiles using Glass and then executes the resulting ROM-file using OpenMSX. So far, so good.

It even says "Hello world!" on screen. Running Naked in a Field of Flowers
But then I want to go to MSX BASIC after a keypress. CHGET is easy enough. However, after a keypress the RET instruction starts the ROM again. A second keypress does result in MSX-BASIC.

Obviously, it's my fault. But I don't get it. It's not the CHGET, as replacing it by RET also runs the ROM twice.

; Hello world! for MSX

; MSX bios calls
CHPUT: equ 0A2H  
CHGET: equ 09FH 
CHGMOD: equ 05FH 
    
    org 4000H                       ; start at 4000H                  
ROM_PAGE: ds 4000H                  ; 16 kB

    SECTION ROM_PAGE                ; use full PAGE
    db "AB"                         ; expansion ROM header
    dw execute                      ; start of the init code, 0 if no initcode
    dw 0                            ; pointer to CALL statement handler, 0 if no such handler
    dw 0                            ; pointer to expansion device handler, 0 if no such handler
    dw 0                            ; pointer to the start of a tokenized basicprogram, 0 if no basicprogram
    ds 6, 0                         ; room reserved for future extensions

execute:
    xor a                           ; A = 0
    call CHGMOD                     ; Select screen mode 0
    ld hl, text                     ; HL = Character Message Address
    call print                      ; print text
    call CHGET                      ; wait for keypress
    ret                             ; return to MSX-BASIC

print:
    ld a, (hl)                      ; A = Character
    or a                            ; A |= A
    ret z                           ; IF (Character == Zero) return
    call CHPUT                      ; CALL System Routine To Display A Character To The Screen
    inc hl                          ; Character Message Address++
    jr print                        ; Continue Printing

text:   db "Hello, World!", 13, 10, 0
    ENDS
Entrar ou registrar-se para comentar

Por Timmy

Expert (114)

imagem de Timmy

07-09-2019, 16:34

... removed ... Tongue

Por Grauw

Ascended (8515)

imagem de Grauw

07-09-2019, 18:18

I could reproduce it but didn’t see anything wrong, so I opened the debugger to see what happens.

The first run, on the stack I see 4004H, and the second run it is 8004H. A-ha. The 16K ROM you made for page 1 is mirrored in page 2 (by the mapper that openMSX has auto-selected), so the ROM header is encountered again in page 2 and executes once more.

You can also see this when you type the “slotmap” command in the openMSX console.

In this case can explicitly specify the mapper type with -romtype Page1 on the command line. Or you can make the ROM a 32K one.

One interesting thing to me is that 4000H was still selected, so it ran again rather than crashing. Normally when you make a 32K ROM you need to manually select the slot in page 2 before it can be used fully. But I wonder if you put the ROM header at 8000H, whether page 1 is guaranteed to be already pre-selected to the same slot.

Por zPasi

Champion (474)

imagem de zPasi

07-09-2019, 21:28

Grauw wrote:

One interesting thing to me is that 4000H was still selected, so it ran again rather than crashing. Normally when you make a 32K ROM you need to manually select the slot in page 2 before it can be used fully.

Indeed. Weird.

Por Thom

Hero (592)

imagem de Thom

07-09-2019, 23:12

Nice, thanks a lot Grauw. So it is also kind of weird it didn't crash. I really enjoy this.

Grauw wrote:

I could reproduce it but didn’t see anything wrong, so I opened the debugger to see what happens.

The first run, on the stack I see 4004H, and the second run it is 8004H. A-ha. The 16K ROM you made for page 1 is mirrored in page 2 (by the mapper that openMSX has auto-selected), so the ROM header is encountered again in page 2 and executes once more.

You can also see this when you type the “slotmap” command in the openMSX console.

In this case can explicitly specify the mapper type with -romtype Page1 on the command line. Or you can make the ROM a 32K one.

Indeed, now it works :-)
However, slotmap doesn't give different results?
slot 0:
0000: MSX BIOS with BASIC ROM
4000: MSX BIOS with BASIC ROM
8000:
C000:

slot 1:
0000: helloworld.com
4000: helloworld.com
8000: helloworld.com
C000: helloworld.com

and Main RAM in all pages of slot 3-2.
(I selected the Philips VG 8020/20)

Quote:

One interesting thing to me is that 4000H was still selected, so it ran again rather than crashing. Normally when you make a 32K ROM you need to manually select the slot in page 2 before it can be used fully. But I wonder if you put the ROM header at 8000H, whether page 1 is guaranteed to be already pre-selected to the same slot.

Do you mean changing org 4000H to org 8000H? I tried that, but exactly the same thing happened.

Por NYYRIKKI

Enlighted (5399)

imagem de NYYRIKKI

08-09-2019, 09:24

I've been in your situation, so I can relate to it. Smile

Thom wrote:

Obviously, it's my fault. But I don't get it.

Well not really... The reason is that ROM-files don't include information about how they are physically connected to the MSX. In this case you expect that the /CS is connected to /SLTSEL and /OE leg of the chip is connected to /CS1, but emulator expects that /OE is connected to /RD signal... It is good default assumption as usually it does not cause problems, but indeed if you want to exit the ROM-program this will cause the double start problem.

In openMSX I think you can fix this by giving "-romtype Page1" parameter when you insert your cartridge. You can also make your cartridge size 32kB as Grauw suggested or sometimes I just check what start instance is going by starting the routine with something like:

INIT:
	LD A,H
	CP $40
	RET NZ

... I'm not sure though this is "standard way", but seems to work.

Grauw wrote:

I wonder if you put the ROM header at 8000H, whether page 1 is guaranteed to be already pre-selected to the same slot.

No, it is not on same slot. The system works so that it checks the "AB" header first from #4000 and then from #8000. If this is found then the init address is read from address +2 and then interslot call is executed to that address, so the two most significant bits of INIT address are actually what defines the slot layout. The header does not need to be on same page as INIT address. Without this interslot call the slot layout is like in BASIC.

Por Thom

Hero (592)

imagem de Thom

08-09-2019, 22:03

It's still difficult for me to follow what's happening. I'm using the openmsx-debugger from Fixato. For some reason, nothing gets updated while running. So I start the emulator, I start the debugger and press the connect button. When I press the any key in the emulated MSX (CHGET), nothing gets changed in the debugger. The regs and the stack stay the same. If I reconnect the debugger, then there will be changes. And indeed, the 4004H then becomes 8004H.

The slotmap command in the openMSX console doesn't give me different results when I add the -romtype Page1 option.

@NYYRIKKI: although it's a very technical story for me, it's sounds plausible. So, the /CS of the cartridge is connected to /SLTSEL of the cartridge connector to be able to select the correct bank through software? Is that correct? And /OE should be connected to /CS1 (#4000-#7FFF) initially, but it is waiting for a write through the /RD? I'm sure I got this wrong. If there's no point in explaining these things to people like me without this kind of hardware knowledge, I understand. (I tried to find some info myself though).

Por Manuel

Ascended (15829)

imagem de Manuel

08-09-2019, 23:18

Things only update if you're debugging (you're in BREAKED mode, press the break button or set up a break point). I bet you wouldn't want to see the Debugger GUI updated about a million times per second, right? Smile

Por Thom

Hero (592)

imagem de Thom

09-09-2019, 00:05

Manuel wrote:

Things only update if you're debugging (you're in BREAKED mode, press the break button or set up a break point). I bet you wouldn't want to see the Debugger GUI updated about a million times per second, right? Smile

Whahaha!! I guess that could create a black hole and suck the whole universe, which would be a pity. Ok, good point.

I feel stupid all the time now, but I learn a lot and once these hurdles are gone it will become easier.

Por NYYRIKKI

Enlighted (5399)

imagem de NYYRIKKI

09-09-2019, 08:10

Thom wrote:

The slotmap command in the openMSX console doesn't give me different results when I add the -romtype Page1 option.

Indeed... I think this is for Manuel to explain: If I use debugger to view hex dump of "slotted memory" I can see for sure that the "-romtype Page1" is effective, how ever in "slotmap" I also get false result... When I look in to my "scripts"-folder, in my case this comes down to problem that ie. "machine_info slot 1 0 0" seems to return false information... at least from user perspective (In my head I could imagine it might be related to problem that you can't insert more than one physical cartridge to one physical slot at a time, so the cartridge reserves all of the slot address space, but it still seems a bit weird and misleading.)

Quote:

@NYYRIKKI: although it's a very technical story for me, it's sounds plausible. So, the /CS of the cartridge is connected to /SLTSEL of the cartridge connector to be able to select the correct bank through software? Is that correct?

Indeed this is way beyond what you need to know, but I guess some extra information doesn't hurt. Smile
Actually what this means is that the ROM chip wakes up when the correct slot is selected. (Each slot has their own /SLTSEL signal) From the ROM chip both /CE and /OE needs to be active in order to make it output data to databus.

Quote:

And /OE should be connected to /CS1 (#4000-#7FFF) initially, but it is waiting for a write through the /RD?

Very close... The /CS1 signal becomes active when address is in range #4000-#7FFF and /RD (read) is also active. This signal is there exactly for what you are trying to do. If the ROM /OE (output enable) is connected only to /RD then the ROM chip will output content in case any address is read. Since the A14 and A15 pins are not connected to anywhere (as the 16kB chip does not have such pins) this effectively makes the data visible 4 times trough out the whole 64kB address space. This effect is commonly called as ROM mirroring in MSX scene.

So, why to expect /RD instead of /CS1 ? This is because we don't know how the ROM was originally connected and some games may be using /CS2 (#8000-#BFFF) On a normal day expecting /RD usually covers both situations without problems... but then you come and want to exit also. Smile

Por Grauw

Ascended (8515)

imagem de Grauw

09-09-2019, 09:23

In essence the problem was the mapping mode; the 16k ROM you made was presented by openMSX in pages 0, 1, 2 and 3 (ranges 0-3FFFh, 4000h-7FFFh, 8000h-BFFFh, C000h-FFFFh) (mirrored), whereas you expected it to be only in page 1. The emulator's automatic mapper type guessing isn't (can't be) perfect so sometimes you gotta specify it manually.

The BIOS scans for the ROM "AB" header in each slot at address 4000h and then 8000h, so if your ROM is mirrored it will find it in both places and just execute the 2nd (mirror) when you return from the 1st.

Página 1/2
| 2