viernes, 28 de mayo de 2010

Acceso a funciones Asm desde C


Además del "assembler in line" que permite añadir directamente código ensamblador de Z80 en nuestras funciones en C, podemos acceder a funciones incluidas en fuentes totalmente en assembler. Si este código esta creado para compiladores como el asMSX, antes tendremos que adaptarlo para que lo acepte el compilador de SDCC. Algunos de estos cambios son:
Los valores deberán de preceder del caracter almohadilla.
0ffh --> #0xFF

Los corchetes de las instrucciones que apuntan a direcciones de memoria, habrá que cambiarlo por paréntesis.
ld a,[#FAFE] --> ld a,(#0xFAFE)

Las variables con la instrucción "equ" por un igual.
initmem equ 0E000h --> initmem = #0xE000

En mi caso, lo he necesitado para utilizar las rutinas de Ramones para el control de ratón.

Una vez adaptado el código, el siguiente paso, sera marcar de alguna forma, que funciones son a las que queremos acceder desde C. Para ello tendremos que poner al inicio de la etiqueta usada, un subrayado y al final dos veces el caracter de dos puntos.
_checkmouse::

Una vez hecho todo esto compilaremos el fuente, obteniendo un fichero object (".rel"):
sdasz80 -o mouse.asm

Luego desde nuestro editor, crearemos un fichero "header" donde definiremos las funciones que acceden a las de assembler. Utilizaremos la instrucción "extern" y pondremos el nombre de la etiqueta sin los caracteres añadidos (el tema parámetros, en estos momentos desconozco como funciona).
extern void checkmouse(void);

Incluiremos el include en nuestro fuente y llamaremos a la función utilizando el nombre dado en la definición.
checkmouse();

Para finalizar, compilaremos nuestro proyecto incluyendo el objet:
sdcc -mz80 -o --no-std-crt0 --code-loc 0x4010 --data-loc 0xC000 mouse.rel PSGed_v06a.c

Para conseguir este "item", quiero agradecer la ayuda de Andrear, Ramones y Avelino.

2 comentarios:

  1. Interesante, me pregunto si funcionará en el CC65

    ResponderEliminar
  2. funciones ASM aceptan parámetros en los registros libremente elegido por el programador de la función.

    Los parámetros de una función C de SDCC serán almacenados en posición (IX + 4), (IX + 5) ...

    Llamar a una función ASM de C entonces un bloque __asm/__endasm, o alternativamente crear una función C contenedora (wrapper), similar a:

    void wrapper_c_function_calling_asm_function(char c) {
    __asm
    ld a, 4(ix)
    call asm_function_using_param_in_reg_A
    __endasm;
    return;
    }

    ResponderEliminar