daVinci FEOS for 68EZ328

Application Development Guide.
 
 






Index.


Introduction.

The purpose of this document is to aid in the development of applications for the FEOS operanting system.

This document want to be a precise reference for the system calls and library functions provided by the FEOS O.S. Version 2.3.


PIC files.

The only currently supported executable file format is the Position Independent Code (PIC) one. PIC files are a simple chunk of flash memory containing the code and constants for a particular application. The operating system can place these files in any flash position, so the code of PIC files must be position independent. This means that all the branches must be PC relative, the static variables must reside into a rightly allocated RAM area, and constants must be addressed relative to the PC register.

The execution of a PIC file takes the following steps:

  1. The kernel allocates a 4096 byte block for the stack area of the application.
  2. The kernel starts a new user mode task. The entry point is the first data word of the file.

Cross-Compilers.

In order to obtain PIC files from a high-level language, like 'C', a cross-compiler is needed. The cross-compiler runs on a development computer, normally a Intel-PC, but generates code for a 68000 based target: the daVinci. The generation of PIC files requires an specific compiler. The only PIC cross-compiler for 68000 tested by the author is the one from the ucLinux Project. This Compiler is a little buggy, but it's still usable.

Before to the execution of compiled C files, a small initialitation code is needed in order to set the things as it's expected in the compiler. This includes:

  1. Allocating RAM space for all the static variables.
  2. Setting the A5 register to the base of allocated RAM area.
  3. Copying the initialitated static variables (.data) from the PIC file to RAM.
  4. Zeroing the un-initialitated static variables (.bss).
  5. Branching to the 'main' function.
This code is included in the file "pic/init.h" as inline assembler. All my attempts to link this code as a separate object file failed, so the current approach to the solution is to start any program with:
#include "init.h"

In order to allocate the space required for the '.data' area in the file automatically a linker script is used (pic/user.ld). In this script the .data area is defined as:

  .data 0:
  AT ( ADDR(.text) + SIZEOF ( .text ) )
  {
    _data = .;
    *(.data)
    _edata = .;
  }
 

The linker resolves the addressing of a '.data' variable as it were located at offset 0, but its value is stored  following the '.text' area in the PIC file.


System Calls.

System Calls transfer the execution from a PIC application file to the kernel. This is the way used to access the system resources provided by the FEOS OS.

A syscall is started with the execution of any of the following assembler instructions in an user application:

These instructions are normally embedded into a 'C' function like the main syscall one:
int syscall(int cix,...)
{
        asm volatile ("trap #0");
}

This function takes a variable number of 32 bit arguments, and returns a 32 bit result. The exact number of arguments, the pourpose of each argument, and the significance of the returned value depends on the syscall code provided as the first argument to 'syscall'. The syscall codes are defined in the 'syscall.h' file.

The current supported syscalls are:



Task Management:
 
 

Title:               TASK EXIT
Syscall code:        0
Syscall code name:   TASK_EXIT
Format:              syscall(TASK_EXIT);
Return value:        no return
Description:

TASK_EXIT terminates the execution of the current task. The resources allocated by the current task (memory, virtual terminal, etc) are released.
This call does not return.
 
 

Title:               MAKING A DELAY
Syscall code:        1
Syscall code name:   TASK_SLEEP
Format:              syscall(TASK_SLEEP,ntics);
Return value:        0
Description:
 

TASK_SLEEP puts the current task in the 'SLEEPED' state during 'ntics' system tics. If the value of 'ntics' is 0 the task remains in the 'SLEEPED' status indefinitelly.
The tic lenght is 1/64 seconds.
 

Title:               GETTING THE CPU TIME OF A TASK
Syscall code:        40
Syscall code name:   TASK_GET_TIME
Format:              syscall(TASK_GET_TIME,&tv);
Return value:        integer
Description:

This syscall writes the CPU time of the current task in the 64 bit variable at the address '&tv'. The value returned can be 0 if no errors or -1 if the pointer is wrong. The CPU time is measured in units of 8 clock cycles. In order to convert this time to seconds the operation is: time_seconds=tv/2072576;
 
 



Memory Allocation.
 
 

Title:               MEMORY ALLOCATION
Syscall code:        2
Syscall code name:   KMALLOC
Format:              buf=(char *)syscall(KMALLOC,nbytes);
Return value:        pointer
Description:

KMALLOC search the davinci user memory for a free block of 'nbytes' lenght. If such block is found a pointer to its start is returned. Otherwise a 0 (NULL) is returned.

The memory is allocated in blocks of 128 bytes, so syscall(KMALLOC,1) allocates the same amount of memory that syscall(KMALLOC,128);
 
 

Title:               MEMORY RELEASE
Syscall code:        3
Syscall code name:   KFREE
Format:              syscall(KFREE,buf,nbytes);
Return value:        0
Description:

KFREE releases the block of memory pointed by 'buf', with the lenght 'nbytes', to the system. The memory is released in blocks of 128 bytes.


Virtual Terminals.

A virtual terminal (VT) is a data structure that includes a memory block for the screen and an event FIFO. The VT is the main input/output resource for applications.
 
 

Title:               VIRTUAL TERMINAL OPEN
Syscall code:        7
Syscall code name:   OPEN_VT
Format:              vt=(vt *)syscall(OPEN_VT,vmode);
Return value:        pointer
Description:

OPEN_VT allocates a VT for the current task. The 'vmode' parameter selects the screen depth for the current task as: 0 = 1 bit/pixel (2 gray levels) , 1 = 2 bits/pixel (4 gray levels) and 2 = 4 bits/pixel (16 gray levels). The return value can be (vt *)0 if the call fails or a pointer to the vt structure. The VT structure cannot be addrressed by user applications. Only one VT can be open by a given task.
 
 

Title:               VIRTUAL TERMINAL CLOSE
Syscall code:        8
Syscall code name:   CLOSE_MY_VT
Format:              syscall(CLOSE_MY_VT);
Return value:        0
Description:

CLOSE_MY_VT returns the VT allocated resources to the system. If the current task is running in foreground the terminal is switched to the shell VT.
 
 

Title:               VIRTUAL TERMINAL TO FOREGROUNG
Syscall code:        9
Syscall code name:   VT_TO_FG
Format:              syscall(VT_TO_FG);
Return value:        0
Description:

The terminal is switched to the current task VT.
 
 

Title:               GETTING EVENTS FROM VT'S
Syscall code:        10
Syscall code name:   VT_GET_EVENT
Format:              ev=syscall(VT_GET_EVENT);
Return value:        integer
Description:

VT_GET_EVENT syscall waits until an event code is avaiable in the VT event FIFO. This syscall only reads a byte from the FIFO. The possible values for the returned event codes are:

Title:               GETTING EVENTS FROM VT'S WITHOUT BLOCKING
Syscall code:        11
Syscall code name:   VT_GET_EVENT_NB
Format:              ev=syscall(VT_GET_EVENT_NB);
Return value:        integer
Description:

VT_GET_EVENT_NB runs like VT_GET_EVENT, but, if no event was found in the VT FIFO a value of -1 is returned. VT_GET_EVENT_NB does not wait.
 
 

Title:              GETTING THE ADDRESS OF THE VIDEO RAM
Syscall code:       12
Syscall code name:   VT_GET_SCREEN_BASE
Format:              video=(char *)syscall(VT_GET_SCREEN_BASE);
Return value:        pointer
Description:

VT_GET_SCREEN_BASE returns the address of the video RAM for the current task VT.
 
 

Title:               SETTING THE BASE ADDRESS OF VIDEO RAM
Syscall code:        13
Syscall code name:   VT_SET_SCREEN_BASE
Format:              syscall(VT_SET_SCREEN_BASE,(int)address);
Return value:        integer
Description:

VT_SET_SCREEN_BASE changes the video memory of the current task VT to the 'address' value. The return value may be 0 if no errors or -1 if the new RAM address is not owned by the current task.


Text & graphics

A few syscalls are provided for the drawing of text and graphics on the screen.
 

Title:               PRINTING A CHARACTER ON THE VT SCREEN
Syscall code:        14
Syscall code name:   PUTCHAR
Format:              syscall(PUTCHAR,ch);
Return value:        0
Description:

PUTCHAR the character 'ch' on the screen using the system 8x8 font. PUTCHAR runs on any video depth.
 

Title:               PRINTING AN STRING ON THE VT SCREEN
Syscall code:        15
Syscall code name:   PUTS
Format:              syscall(PUTS,buf);
Return value:        0
Description:

PUTS syscall prints the zero-terminated string 'buf' on the screen.
 

Title:               HIDDING THE CURSOR
Syscall code:        16
Syscall code name:   CURSOR_OFF
Format:              syscall(CURSOR_OFF);
Return value:        0
Description:

This syscall removes the cursor from the screen. Note: the PUTCHAR & PUTS syscalls activates the cursor.
 

Title:               ACTIVATING THE CURSOR
Syscall code:        17
Syscall code name:   CURSOR_ON
Format:              syscall(CURSOR_ON);
Return value:        0
Description:

CURSOR_ON activates the cursor.
 

Title:               POSITIONING THE CURSOR
Syscall code:        18
Syscall code name:   GOTOXY
Format:              syscall(GOTOXY,x,y);
Return value:        0
Description:

This syscall places the cursor at the ('x','y') coordinates. The upper-left corner of the screen is at (0,0) and the lower-right corner is at (19,19).
 

Title:               CLEARING THE SCREEN
Syscall code:        19
Syscall code name:   CLS
Format:              syscall(CLS);
Return value:        0
Description:

This syscall clears the VT screen filling all the video memory with zeroes.
 

Title:               DRAWING A PIXEL
Syscall code:        20
Syscall code name:   PUTPIXEL
Format:              syscall(PUTPIXEL,x,y,gs);
Return value:        0
Description:

This syscall draws a pixel at the ('x','y') coordinates with the grayscale level 'gs'. The screen is 160x160 pixels wide.
 

Title:               DRAWING A LINE
Syscall code:        21
Syscall code name:   LINE
Format:              syscall(LINE,x0,y0,x1,y1,gs);
Return value:        0
Description:

This syscall draws a line from ('x0','y0') to ('x1','y1') with the grayscale level 'gs'.
 

Title:               FAST HORIZONTAL LINE
Syscall code:        22
Syscall code name:   HLINE
Format:              syscall(HLINE,x0,x1,y,gs);
Return value:        0
Description:

This syscall draws an horizontal line 8 pixels at a time when possible. A lot faster than LINE.
 

Title:               FAST VERTICAL LINE
Syscall code:        23
Syscall code name:   VLINE
Format:              syscall(VLINE,x,y0,y1,gs);
Return value:        0
Description:

This syscall draws a vertical line using a fast addresing scheme.
 

Title:               DRAWING A CIRCLE
Syscall code:        24
Syscall code name:   CIRCLE
Format:              syscall(CIRCLE,x,y,rad,gs);
Return value:        0
Description:

This syscall draws an empty circle centered at ('x','y') with radius 'rad' and with the grayscale level 'gs'.
 

Title:               DRAWING A FILLED CIRCLE
Syscall code:        25
Syscall code name:   FILLED_CIRCLE
Format:              syscall(FILLED_CIRCLE,x,y,rad,gs);
Return value:        0
Description:

This syscall draws a filled circle.
 

Title:               DRAWING A RECTANGLE
Syscall code:        26
Syscall code name:   RECTANGLE
Format:              syscall(RECTANGLE,x0,y0,x1,y1,gs);
Return value:        0
Description:

This syscall draws an empty rectangle. The ('x0','y0') are the coordinates for the upper-left corner, ('x1','y1') are the coordinates for the lower-right corner and 'gs' is the grayscale level.
 

Title:               DRAWING A FILLED RECTANGLE
Syscall code:        27
Syscall code name:   FILLED_RECTANGLE
Format:              syscall(FILLED_RECTANGLE,x0,y0,x1,y1,gs);
Return value:        0
Description:

This syscall draws a filled rectangle.



SOUNDS

A few syscalls are provided in order to make simple beeps in the daVinci speaker. All of these sounds are rectangular waves generated by the dragonball's PWM engine. The parameters that defines a sound are its frecuency and its duty cycle. The duty cycle can be used to control the volume of the generated wave.

Title:               STARTING TO PLAY A BEEP
Syscall code:        29
Syscall code name:   SOUND
Format:              syscall(SOUND,freq,vol);
Return value:        0
Description:

This syscall starts playing a sound at the 'freq' frequency (Hz) with the volume 'vol'. Accepted volume values ranges from 1 to 15.
 

Title:               CHANGING THE BEEP VOLUME
Syscall code:        30
Syscall code name:   SOUND_VOL
Format:              syscall(SOUND_VOL,vol);
Return value:        0
Description:

This syscall changes the volume of the current beep by adjusting its duty cycle.
 

Title:               STOP THE BEEP
Syscall code:        31
Syscall code name:   SOUND_OFF
Format:              syscall(SOUND_OFF);
Return value:        0
Description:
 

This syscall stops the current beep.


Files.

A file is a block of FLASH memory preceded by an header. This header contains information related to the file and its format is:

typedef struct {
        unsigned int magic;       // Allways 0xFA12AB34
        unsigned int size;        // The size of the file in bytes
        unsigned char type;       // Type of the file
        unsigned char subtype;    // Subtype of the file
        char name[16];            // An ASCIIZ string to identify the file.
}file_header;

Inmediatelly after the header, that is 26 bytes long, follows the file data. The file header and data always starts at an even address boundary.
The currently planned file types and subtypes are:

The files are handled via the following syscalls:

Title:               LOCATING A FILE IN THE FLASH
Syscall code:        33
Syscall code name:   FILE_SEL_IX
Format:              fp=(file_header *)syscall(FILE_SEL_IX,type,subt,ix);
Return value:        pointer
Description:

This syscall returns a pointer to the header of the file that has been found according to the calling parameters. The 'type' and 'subt' parameters acts as filters, and a value of 0 can be used as a wildcard. The 'ix' parameter is the numerical position of the file in the list of all the files with the 'type' type and 'subt' subtype. If no file is found a 0 (NULL) pointer is returned.
 

Title:               LOCATING THE NEXT FILE
Syscall code:        34
Syscall code name:   FILE_SEL_NEXT
Format:              fp=(file_header *)syscall(FILE_SEL_NEXT,type,subt,fpointer);
Return value:        pointer
Description:

This syscall search for the next file with the type 'type' and subtype 'subt', starting at the 'fpointer' address. If no file is found a 0 (NULL) pointer is returned.
 

Title:               GETTING THE NUMBER OF FILES
Syscall code:        35
Syscall code name:   FILE_GET_NFILES
Format:              nf=syscall(FILE_GET_NFILES,type,subt);
Return value:        integer
Description:

This syscall returns the number of files with the type 'type' and subtype 'subt' found in the filesystems.
 

Title:               SELECTING A FILE FROM A MENU
Syscall code:        36
Syscall code name:   FILE_SEL_INT
Format:              ix=syscall(FILE_SEL_INT,type,subt,def_ix);
Return value:        integer
Description:

This syscall opens a menu with the files of the requested type and subtype. The 'def_ix' parameter is the default selection. Before to execute this syscall a VT must be opened by the current task. The returned value is the numerical position of the selected file in the filtered file list or -1 if no files are found or the user refuses to select one. All the screen but the first character line is cleared, so the first line can be used as a banner to instruct the user about the selection.



 

Audio capture & PWM output.

The audio capture requires an external circuit in order to operate. When the daVinci is connected to this circuit it can capture unsigned, 8 bit, audio samples at a rate about 8 KHz. The kernel interrupt routine that handles the capture stores the samples in a circular buffer located in the application memory. In this way the application don't need to move the recorded data. The syscalls related to the audio capture are:

Title:               STARTING THE AUDIO CAPTURE
Syscall code:        37
Syscall code name:   AUDIO_START
Format:              syscall(AUDIO_START,buffer,len);
Return value:        integer
Description:

The AUDIO_START syscall starts the recording of audio samples in the user buffer pointed by 'buffer' that is 'len' bytes long. This syscall returns a -1 if it fails.

Title:               STOPPING THE AUDIO CAPTURE
Syscall code:        38
Syscall code name:   AUDIO_STOP
Format:              syscall(AUDIO_STOP);
Return value:        0
Description:

This syscall stops the audio capture.

Title:               MEASURING THE SAMPLING RATE
Syscall code:        39
Syscall code name:   AUDIO_MEAS_FREC
Format:              f=syscall(AUDIO_MEAS_FREC);
Return value:        integer
Description:

The AUDIO_MEAS_FREC syscall takes an accurate measure of the converter sampling rate and returns the result in hertz. Before to the execution of this syscall the audio capture must be started.

The current position of the recording pointer can be read via the fast syscall: TRAP #2, as it is done in the following example:

extern inline unsigned char *get_audio_pointer()
{
char *pa;
asm volatile("trap #2\n move.l %%d0,%0":"=a"(pa));
return pa;
}

The audio playback is done via the PWM output of the dragonball processor. The samples are 8 bits wide, unsigned, and the sampling rate is 8096 Hz. The related syscalls are:

Title:               STARTING THE AUDIO PLAYBACK
Syscall code:        41
Syscall code name:   PWM_START
Format:              syscall(PWM_START,buffer,len);
Return value:        integer
Description:

The PWM_START syscall starts the audio playback reading the samples from a circular buffer pointed by 'buffer', 'len' bytes wide. This syscall can return a value -1 if it fails.

Title:               STOPPING THE AUDIO PLAYBACK
Syscall code:        42
Syscall code name:   PWM_STOP
Format:              syscall(PWM_STOP);
Return value:        0
Description:

This syscall stops the audio playback.

The current position of the playback pointer can be read via the fast syscall: TRAP #3, as it is done in the following example:

extern inline unsigned char *get_PWM_pointer()
{
char *pa;
asm volatile("trap #3\n move.l %%d0,%0":"=a"(pa));
return pa;
}


Miscelaneous

Title:               READING THE PEN COORDINATES
Syscall code:        28
Syscall code name:   GET_PEN_XY
Format:              syscall(GET_PEN_XY,&x,&y);
Return value:        integer
Description:

The GET_PEN_XY syscall reads the coordinates of the pen in the touch-screen and stores them in the variables 'x' and 'y'. The return value can be -1 if the pen is not on the screen. The coordinates are measured in pixels from the upper-left corner of the screen.
 

Title:               READING THE TIME (CPU TICS)
Syscall code:        32
Syscall code name:   RDTSC
Format:              tics=syscall(RDTSC);
Return value:        integer
Description:

The RDTSC syscall returns the number of CPU tics since the last reset. Each tic accounts for 1/64 seconds. No tics are received while the daVinci is off.
 
 

Title:               READING THE TIME (Real Time Clock DATE)
Syscall code:        43
Syscall code name:   TIME_GET_RTC
Format:              syscall(TIME_GET_RTC, &time_st);
Return value:        integer
Description:

The TIME_GET_RTC syscall copies the time and date from the Dragonball's RTC to the 'time_st' structure. This structure has the following format:

typedef struct
{
        unsigned short year;
        unsigned char month;
        unsigned char day;
        unsigned char hour;
        unsigned char min;
        unsigned char sec;
} time;

This syscall can return a 0 value if it was OK, or -1 if 'time_st' pointer is invalid.
 

Title:               UNCOMPRESSING PHOTOS
Syscall code:        44
Syscall code name:   ZIP_GET_DCT_ADDRESS
Format:              showimage=(void (*)(unsigned char *,unsigned char *,
                                ,int,int))=syscall(ZIP_GET_DCT_ADDRESS);
Return value:        pointer to function
Description:

The ZIP_GET_DCT_ADDRESS syscall returns a pointer to the kernel photo decompression routine. This routine is reentrant and can be called from user applications directly. The function prototype is:

void (*showimage)(unsigned char *dst,unsigned char *src,int off_x,int off_y);

'dst' must point to a 4 bit/pixel video memory area.
'src' must point to a DCT compressed photo.
'off_x' and 'off_y' are displacements from upper-left photo corner to screen origin in 8-pixel units.
 


ROM Library

The FEOS O.S. includes a user mode library that can be called from applications. This library wants to reduce the application size by sharing the code of the most commonly called routines like long-integer & floating point emulation, string manipulation, math functions, printf and more. Most of these functions are compiled from the 'newlib' sources.

All the ROMLIB functions must be reentrant. This allows the simultaneous calling from several applications without problems. I hope that all the included functions are reentrant. I don't get the patiente needed to test all the routines.

The entry points for the ROMLIB functions are stored in a table at a the address 0x10c20000 (see 'userland/table.s'). The ROMLIB call from a user application is then (assembler code):

putchar:    movea.l    0x10c20010,%a0
            jmp        (%a0)

From the point of view of the GCC compiler the register '%a0' can be altered by the called function, so its corruption is no problem.

In order to make easy the calling to these routines a library is generated automatically from the 'userland/table.s' file: 'lib/librom.a'. This library must be then linked with any application that wants to call the ROMLIB functions.

The list of some interesting functions from the ROMLIB follows:

0x10c2000c      syscall
0x10c20010      putchar
0x10c20014      puts
0x10c20018      printf
0x10c2001c      sputch
0x10c20020      sprintf
0x10c20024      atof

0x10c20028      sin
0x10c2002c      pow
0x10c20030      sqrt
0x10c20034      log
0x10c20038      log10
0x10c2003c      cos
0x10c20040      tan
0x10c20044      exp
0x10c20048      asin
0x10c2004c      acos
0x10c20050      atan
0x10c20054      atan2
0x10c20058      fabs
0x10c2005c      rint
0x10c20060      floor

0x10c20064      bcmp
0x10c20068      bcopy
0x10c2006c      bzero
0x10c20070      index
0x10c20074      memchr
0x10c20078      memcmp
0x10c2007c      memcpy
0x10c20080      memmove
0x10c20084      memset
0x10c20088      rindex
0x10c2008c      strcasecmp
0x10c20090      strcat
0x10c20094      strchr
0x10c20098      strcmp
0x10c2009c      strcoll
0x10c200a0      strcpy
0x10c200a4      strcspn
0x10c200a8      strerror
0x10c200ac      strlen
0x10c200b0      strncasecmp
0x10c200b4     strncat
0x10c200b8      strncmp
0x10c200bc      strncpy
0x10c200c0      strpbrk
0x10c200c4      strrchr
0x10c200c8      strspn
0x10c200cc      strstr
0x10c200d0      strxfrm