Calling Amstrad firmware routines

Amstrad CPC and NC systems
Post Reply
Juan Luis
Member
Posts: 10
Joined: Wed May 20, 2020 7:30 pm

Calling Amstrad firmware routines

Post by Juan Luis »

I'm trying to call several Amstrad firmware routines from C code, but the call is unsuccessful. After calling set_move Amstrad CPC is reset.

Is it possible to call to Amstrad firmware routines?

The code is compiled with following command:
zcc +cpc -lndos -create-app -o gfx.bin main.c

Code: Select all

#include <conio.h>

#define SCR_SET_MODE                 0xBC0E        // A=mode (0, 1, 2)
#define GRA_MOVE_ABSOLUTE        0xBBC0        // DE=x, HL=y
#define GRA_LINE_ABSOLUTE        0xBBF6        // DE=x, HL=y
#define GRA_LINE_RELATIVE        0xBBF9        // DE=x, HL=y
#define GRA_SET_ORIGIN                0xBBC9         // DE=x, HL=y

void set_mode(unsigned m) {
#asm
        // m parameter SP+2
        //ld hl,2
        //add hl,sp
        //ld a,(hl)
        ld a,2                         // Forcing mode 2
        
        // in : A = mode (0=160x200x16, 1=320x200x4, 2=640x200x2)
        // out: A = mode
        call SCR_SET_MODE
#endasm
}

void move(int x, int y) {
#asm
        // x parameter SP+4
        // y parameter SP+2        
        ld hl,4
        add hl,sp
        ld e,(hl)
        inc hl
        ld d,(hl)        // DE = x

        ld hl,2
        add hl,sp
        ld c,(hl)
        inc hl
        ld b,(hl)        // BC = y
        ld l,c
        ld h,b                // HL = BC = y
        call GRA_MOVE_ABSOLUTE
#endasm
}

void line(int x, int y) {
#asm
        // x parameter SP+4
        // y parameter SP+2        
        ld hl,4
        add hl,sp
        ld e,(hl)
        inc hl
        ld d,(hl)        // DE = x

        ld hl,2
        add hl,sp
        ld c,(hl)
        inc hl
        ld b,(hl)        // BC = y
        ld l,c
        ld h,b                // HL = BC = y
        call GRA_LINE_ABSOLUTE
#endasm
}

void main() {
        set_mode(2); // Fails in this call. Video mode is not set
        move(0,0);
        line(100,100);
        
        while (!kbhit());
}
User avatar
dom
Well known member
Posts: 1194
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

The crt0 exposes a function called "firmware" that should restore the registers to values that the firmware requires. Use it as follows:

Code: Select all

EXTERN firmware
; Setup registers
call firmware
defw FIRMWARE_ADDRESS
Juan Luis
Member
Posts: 10
Joined: Wed May 20, 2020 7:30 pm

Post by Juan Luis »

dom wrote:The crt0 exposes a function called "firmware" that should restore the registers to values that the firmware requires. Use it as follows:

Code: Select all

EXTERN firmware
; Setup registers
call firmware
defw FIRMWARE_ADDRESS
Ok. It works find as you have written. I have modified my code setting SRC_SET_MODE as FIRMWARE_ADDRESS, and an equivalent thing in the other functions:

Code: Select all

...
void set_mode(unsigned m) {
#asm
        // m parameter SP+2
        ld hl,2
        add hl,sp
        ld a,(hl)
        
        // in : A = mode (0=160x200x16, 1=320x200x4, 2=640x200x2)
        // out: A = mode
        EXTERN firmware
        call firmware
        defw SCR_SET_MODE
#endasm
}
...
Thanks for your help.
stefano
Well known member
Posts: 1534
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

You should also have some of them ready made , e.g. cpc_SetMode
We imported the cpcsrlib but some advanced option which was recently introduced.
Post Reply