[MSX-C] Q&A official thread

Страница 56/56
49 | 50 | 51 | 52 | 53 | 54 | 55 |

By DarkSchneider

Paladin (939)

Аватар пользователя DarkSchneider

26-06-2020, 11:01

Well calling the main ROM BIOS can be done directly as noted.

The problem is the SUBROM, that requires a special way due to DOS behavior. If we look at the calling SUBROM routine, notice that it puts the code on the stack, then call it, and removes from it. Then, as the stack goes from higher to lower memory address, it has to push the routine code backwards. As the stack is 16-bit aligned, it adds something like a NOP to fill, not because is required.
Notice that here:

         ld     hl,0
         add    hl,sp        ; HL = offset of routine
         ld     a,#C3
         ld     (H_NMI),a
         ld     (H_NMI+1),hl ; JP  in NMI hook

What it does is get the routine address (that is at the stack address), and then set a JP (#C3 = JP opcode) on the NMI hook.

The truth is that is a bit weird, pushing the routine into the stack on each call, I think the calling SUBROM would be a good candidate for creating it as routine to put at page 3, as said, at program start. This is, at the very start push the routine and set the NMI hook.

By melovictor

Supporter (5)

Аватар пользователя melovictor

27-06-2020, 19:57

melovictor wrote:

Hi All,
Newbie here!
I learned how to program in a MSX back in the 80s. Today I work as a Java developer (boring I know). Because I also learned a little bit of C, I started writing programs for MSX in that language. Version 1.20 to be precise.
The question:
Is it possible to call a subrom routine from C (I am trying to stay away from Assembly)?
Basically I want to convert the code bellow into C programming.

;--- REDCLK ------------------------------------------------------------------
;Address  : #01F5
;Function : Read clock-RAM
;Input    : C  - clock-RAM address
;                xxBBAAAA
;                  ||++++-- address
;                  ++------ Block-number
;Output   : A  - Read value in lowest four bits
;Registers: F

REDCLK	equ	01F5h

			public RdClck
			
			extrn  _CALSUB

RdClck:	ld 	c,a
			ld 	ix,REDCLK
			jp 	_CALSUB
			
			end

Thanks!

Hi all,

I found the answer to my own question! :-)

MSX-C example to get the system's current data without messing with Assembly:

#include 
#include 

#define GETIME 0x2c
#define getTime(rTime) rTime.bc = GETIME, callx(5, &rTime)

main()
{
    REGS rTime;
    printf("\xc");
    for ( ;!kbhit(); )
    {
        getTime(rTime);
        printf("\xb %02d:%02d:%02d\n", rTime.hl / 256, (int)rTime.a, rTime.de / 256);
    }
}

Thanks for the insights!

By melovictor

Supporter (5)

Аватар пользователя melovictor

27-06-2020, 20:21

Another variant just for fun:

#include 
#include 

#define GETIME 0x2c

VOID now(regs)
REGS *regs;
{
    regs->bc = GETIME;
    callx(5, regs);
    printf("\xb %02d:%02d:%02d\n", regs->hl / 256, (int)regs->a, regs->de / 256);
    now(regs);
}

main()
{
    REGS *regs;
    printf("\xc");
    now(regs);
}
Страница 56/56
49 | 50 | 51 | 52 | 53 | 54 | 55 |