KL_FIND_COMMAND within a ROM

Started by HAL6128, 16:18, 06 March 17

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

HAL6128


I try to create a ROM which should do the KL_FIND_COMMAND, but it doesn't work.


The Firmware KL_FIND_COMMAND (&BCD4) searches for a RSX command. The entry = HL which contains the address of the command Name (RAM only) is being searched. If I use a label within the code KL_FIND_COMMAND looks in RAM instead of the ROM.

How is it possible to execute such command out of a ROM? Do I have to write that command name in RAM during initializing the ROM (below HIMEM)?

Thanks.
Kind regards.
HAL6128
...proudly supported Schnapps Demo, Pentomino and NQ-Music-Disc with GFX

Docent

Quote from: HAL 6128 on 16:18, 06 March 17
I try to create a ROM which should do the KL_FIND_COMMAND, but it doesn't work.


The Firmware KL_FIND_COMMAND (&BCD4) searches for a RSX command. The entry = HL which contains the address of the command Name (RAM only) is being searched. If I use a label within the code KL_FIND_COMMAND looks in RAM instead of the ROM.

How is it possible to execute such command out of a ROM? Do I have to write that command name in RAM during initializing the ROM (below HIMEM)?

Thanks.
Kind regards.
HAL6128

According to docs, the command name to search for must be in RAM. The simplest way is to push the name onto the stack before calling KL FIND COMMAND, so you'll not need to store it in another ram address that may be already used or reserve any additional ram for it.

pacomix

Ha! I'm in a similar situation. I'm trying to reduce the code of DskTool and I need to reach to some FDC routines.
When I call KL_FIND_COMMAND (the value is in the stack and HL points to it) it always return 0.
More specifically I'm trying to discover the address and rom to build a farcall table to be used later with the RST 18h instruction. But no luck... any idea?

m_dr_m

Quote from: pacomix on 21:25, 03 May 22When I call KL_FIND_COMMAND (the value is in the stack and HL points to it) it always return 0.
Did you properly capitalise the RSX NAME (usually uppercase) and set the bit 7 of the last character?

Do you try to do that at ROM-init-time?
In which case you could only search in the ROMs already seen (the ones with greater ROM #), and I'm not even sure about that.
It would be brittle anyway. 

pacomix

Quote from: m_dr_m on 06:14, 04 May 22
Quote from: pacomix on 21:25, 03 May 22When I call KL_FIND_COMMAND (the value is in the stack and HL points to it) it always return 0.
Did you properly capitalise the RSX NAME (usually uppercase) and set the bit 7 of the last character?

Do you try to do that at ROM-init-time?
In which case you could only search in the ROMs already seen (the ones with greater ROM #), and I'm not even sure about that.
It would be brittle anyway.
I just have my C program not disabling the firmware.
Then I try to execute the KL_FIND_COMMAND without success.
RSX NAME and +80h are all correct.

I'm trying to find the Disk routines (01h-09h) to build a FARCALL table in order to use it as described here => https://www.cpcwiki.eu/imgs/8/8a/S968se19.pdf and there https://www.cpcwiki.eu/imgs/f/f6/S968se10.pdf

As a curiosity I created the FARCALL table by hand (2 bytes address of the routine+1 byte for the ROM number, 7 in this case) and apparently a couple of routines I tried did return fine. That's the AMSDOS and BIOS firmware routines.

It might be the emulator? I remember that DskTest does not work with RVM (it hangs) when having the motor option OFF and try to use the option 2 and 3 for example.

I will give another try in another emulator tomorrow.

pacomix

So tried in another emulator without any luck. It would be of great help if any of you could help with my problem. It is strange to see that a simple function fails miserably even by following all the given examples.

Regards!

m_dr_m

C program? Emulator?  That might not be the issue, but that's a problem!

Show us your code!

pacomix

Quote from: m_dr_m on 22:55, 05 May 22C program? Emulator?  That might not be the issue, but that's a problem!



Show us your code!



I prepared a bit of code showing the problem. the code_loc 0x4006 magic number comes from the space of the boot section of the crt0. Below you have the instructions to build it. I did it from my Mac with the tools compiled for it although it shouldn't be a problem to build it from windows with the same tools.

Run it from the emulator with a simple run"klfind in a CPC6128 config.

I tried WinAPE and Retro Virtual Machine 2 and both returns always from KL FIND COMMAND without the Carry flag set. Any suggestion?


crt0_cpc.s
;; FILE: crt0_cpc.s
;; Based on the crt0.s by H. Hansen 2003 provided in SDCC

  .module crt0_cpc

  .globl    s__INITIALIZER
  .globl    l__INITIALIZER
  .globl    s__INITIALIZED

    .globl    _main

    .area _HEADER (ABS)
  .area _BOOT (ABS)

  ;; Reset vector
    .org     0x4000

  call _main      ;; and call our entry point.
    jp   _exit      ;; Exit our program finally

    ;; Ordering of segments for the linker.
    .area    _HOME
    .area    _CODE
  .area _INITIALIZER
  .area   _GSINIT
  .area   _GSFINAL

    .area    _DATA
  .area _INITIALIZED
  .area   _BSS
  .area   _HEAP

  .area   _CODE
__clock::
    ret

_exit::
    ret

  .area   _GSINIT
  .area   _GSFINAL
  ret


main.c file
typedef unsigned char U8;
typedef unsigned int U16;
typedef signed char S8;
typedef signed int S16;

#define false 0
#define true 1
#define FALSE false
#define TRUE true
#define bool U8
#define BOOL bool


#define KL_FIND_COMMAND 0xBCD4
void* pFarCommand;
U8    uFarRom;

// __sdcccall(1)
// Params: 16bit value - Reg. HL
// Return: 8bit value - Reg. A
//
bool firm_kl_find_cmd(U8* uCmd) __sdcccall(1) {
__asm
  call  KL_FIND_COMMAND
  xor   a
  ret   nc  ; Carry = 0 if failed

  ; Save the value although we never get here
  ld    (_pFarCommand), hl
  ld    a,  c
  ld    (_uFarRom), a
  ld    a, #TRUE               ; set return code to true
__endasm;
}


void main() {
  U8 uCmd;

  uCmd = 0x81; firm_kl_find_cmd(&uCmd);
  uCmd = 0x82; firm_kl_find_cmd(&uCmd);
  uCmd = 0x83; firm_kl_find_cmd(&uCmd);
  uCmd = 0x84; firm_kl_find_cmd(&uCmd);
  uCmd = 0x85; firm_kl_find_cmd(&uCmd);
  uCmd = 0x86; firm_kl_find_cmd(&uCmd);
  uCmd = 0x87; firm_kl_find_cmd(&uCmd);
  uCmd = 0x88; firm_kl_find_cmd(&uCmd);
  uCmd = 0x89; firm_kl_find_cmd(&uCmd);
}


// build with sdcc 4.2.0
//
// rm -rf out
// mkdir out
// sdasz80 -o out/crt0_cpc.rel crt0_cpc.s
// sdcc -c -mz80 --opt-code-speed --code-loc 0x4006 --data-loc 0x4100 --no-std-crt0 --allow-unsafe-read -o out/klfind.rel main.c
// sdcc -mz80 --opt-code-speed --code-loc 0x4006 --data-loc 0x4100 --no-std-crt0 --allow-unsafe-read -o out/klfind.ihx out/crt0_cpc.rel out/klfind.rel
// hex2bin out/klfind.ihx
// iDSK out/klfind.dsk -n
// iDSK out/klfind.dsk -i out/klfind.bin -e 0x4000 -c 0x4000
//


m_dr_m


pacomix

Quote from: m_dr_m on 01:04, 07 May 22Well, if you put 'XOR A', of course Carry will be cleared.

See https://64nops.wordpress.com/2021/01/13/perfectly-accurate-z80-flags-and-cpc-timing/
LOL thanks a lot for pointing that out but it doesn't matter. Carry is always 0 immediately after returning from KL FIND COMMAND. Compile it and see it by yourself. I can't attach files to the post but if you give me a mail address I can send you the .dsk

I've debugged a bit the KL FIND COMMAND routine and I even see that the ROM7 gets at some point active in #C000 in order to iterate through the list of available commands, but getting to that point it never starts with the string comparisons and skips to the next ROM number instead.
 

pacomix

Finally found the problem. KL ROM WALK needs to be called in order to initialise all the background ROMs prior calling KL FIND COMMAND.

What is funny is that when debugging, KL FIND COMMAND searches commands in all ROMs from 0 to 15 but skipping the Background type ones. I still didn't find any example that explicitly says to call KL ROM WALK or it was written in a language I don't understand.

Whatever... thanks a lot though for the interest and answers given :)

m_dr_m

Oh yes, KL ROM WALK is done at boot time.
The RUN basic command used against a binary clears that, to give maximum memory possible to programs.
With a BASIC loader, which LOAD + CALL, you don't have to do that.

Go job investigating! 

Powered by SMFPacks Menu Editor Mod