Writing applications for KolibriOS: Difference between revisions

From KolibriOS wiki
Jump to navigation Jump to search
No edit summary
(formatting fixes)
Line 1: Line 1:
= Structure of an application =
= Structure of an application =
     
 
Programming for KolibriOS is easy as you first learn the basic structure of an application. At this point I assume you have some experience in assembly language.
Programming for KolibriOS is easy as you first learn the basic structure of an application. At this point I assume you have some experience in assembly language. The KolibriOS API (Application Programming Interface) is a easy-to-learn set of functions with practically no hierarchial accesses.
 
 
The KolibriOS API (Application Programming Interface) is a easy-to-learn set of functions with practically no hierarchial accesses.
The operating of an application is based on events. The application is notified by the OS with the event type and the application acts accordingly. There are three event types an application is expected to handle by default: window redraw, keypress and buttonpress.
 
 
The operating of an application is based on events.
 
The application is notified by the OS with the event type and the application acts accordingly. There are three event types an application is expected to handle by default: window redraw, keypress and buttonpress.
 
Flow chart and structure of an application with default events:
Flow chart and structure of an application with default events:
 
 
  ;;;;;;;;;;;;;;;;;;;;;;;;;
<syntaxhighlight>
  ;                      ;
;;;;;;;;;;;;;;;;;;;;;;;;;
  ;    HEADER DATA      ;
;                      ;
  ;                      ;
;    HEADER DATA      ;
  ;;;;;;::;;;;;;;;;;;;;;;;;
;                      ;
 
;;;;;;::;;;;;;;;;;;;;;;;;
START:
 
    
START:
  call draw_window
        call   draw_window
 
 
  ;;;;;;;;;;;;;;;;::;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
  ;                      ;
;                      ;
  ;  WAIT UNTIL EVENT    ;  <-----------------------------------------------I
;  WAIT UNTIL EVENT    ;  <-----------------------------------------------I
  ;                      ;                                                  I
;                      ;                                                  I
  ;;;;;::;;;;;;;;;;;;;;;;;;                                                  I
;;;;;;;;;;;;;;;;;;;;;;;;;                                                  I
                                                                            I
;                                                                          I
  ;;;;;;;::;;;;;;;;;;;;;;;;                                                  I
;;;;;;;;;;;;;;;;;;;;;;;;;                                                  I
  ;                      ;    redraw  ->  call draw_window            -> I
;                      ;    redraw  ->  call draw_window            -> I
  ;    READ EVENT TYPE    ; ->  key      ->  read keypress    -> process  -> I
;    READ EVENT TYPE    ; ->  key      ->  read keypress    -> process  -> I
  ;                      ;    button  ->  read buttonpress -> process  -> I
;                      ;    button  ->  read buttonpress -> process  -> I
  ;;;;;::;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 
draw_window:
draw_window:
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                            ;
  ;                            ;
;  DRAW STATIC WINDOW PARTS  ;
  ;  DRAW STATIC WINDOW PARTS  ;
;                            ;
  ;                            ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
        ret
  ret
 
 
;;;;;;;;;;;;;;;;;;;;;;;;
 
;                      ;
DATA AREA:
;    STATIC DATA      ;
 
;                      ;
  ;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;
  ;                      ;
</syntaxhighlight>
  ;    STATIC DATA      ;
  ;                      ;
  ;;;;;;;;;;;;;;;;;;;;;;;;


= The header =
= The header =


<asm>
<syntaxhighlight>
        db     'MENUET01'    
db 'MENUET01'
</asm>
</syntaxhighlight>
Since KolibriOS still is more or less API compatible with MenuetOS, it has the same header.<br>
 
There is also an older version of the header wich uses 'MENUET00' but it should not be used anymore.
Since KolibriOS still is more or less API compatible with MenuetOS, it has the same header. There is also an older version of the header wich uses 'MENUET00' but it should not be used anymore.
<asm>
 
        dd     0x01           ; header version
<syntaxhighlight>
</asm>
dd 0x01 ; header version
</syntaxhighlight>
 
Speaks for itself.
Speaks for itself.
<asm>
 
        dd     START           ; start of execution
<syntaxhighlight>
</asm>
dd START ; start of execution
START is the label in your program where kernel will jump to after loading the program.<br>
</syntaxhighlight>
You could use another name, but it's convenient to always use the same..
 
<asm>
START is the label in your program where kernel will jump to after loading the program. You could use another name, but it's convenient to always use the same.
        dd     I_END           ; size of image
 
</asm>
<syntaxhighlight>
dd I_END ; size of image
</syntaxhighlight>
 
This is the total size of the program code in bytes, its easy to use a label wich you place at the end of the code.
This is the total size of the program code in bytes, its easy to use a label wich you place at the end of the code.
<asm>
 
        dd     0x100000      
<syntaxhighlight>
</asm>
dd 0x100000
This is the amount of ram that will be reserved for your app.<br>
</syntaxhighlight>
You could use a static value as shown here, or you could use IM_END + xx bytes<br>
 
There, IM_END would be the label to the end of code + all static declarations you made after the code.<br>
This is the amount of ram that will be reserved for your app. You could use a static value as shown here, or you could use I_END + xx bytes. There, I_END would be the label to the end of code + all static declarations you made after the code. The xx bytes then are the number of bytes you want to use for the stack. Also note, this value can later be changed by using system functions.
The xx bytes then are the number of bytes you want to use for the stack.<br><br>
 
Also note, this value can later be changed by using system functions
<syntaxhighlight>
<asm>
dd 0x100000 ; stack position in memory area
        dd     0x100000         ; stack position in memory area
</syntaxhighlight>
</asm>
 
Where the end of stack is (the value of esp at start of program).<br>
Where the end of stack is (the value of esp at start of program). Logically, this would be the same as the previous value.
Logically, this would be the same as the previous value.
 
<asm>
<syntaxhighlight>
        dd     0x0             ; Parameters
dd 0x0 ; Parameters
</asm>
</syntaxhighlight>
If you want to use parameters, this should be a pointer to a 1024 byte buffer, in wich those parameters will be written by the kernel. <br>
 
If you dont want to use them, set this dword to 0
If you want to use parameters, this should be a pointer to a 1024 byte buffer, in wich those parameters will be written by the kernel. If you dont want to use them, set this dword to 0.
<asm>
 
        dd     0x0             ; Path  
<syntaxhighlight>
</asm>
dd 0x0 ; Path  
</syntaxhighlight>
 
Path value, works the same as parameter.
Path value, works the same as parameter.


= System calls =
= System calls =


The System calls (API) are explained in various sources. There is the file syscalls.txt wich you can find in kolibrios itself, but also in the zip file of the distribution.<br>
The System calls (API) are explained in various sources. There is the file syscalls.txt wich you can find in kolibrios itself, but also in the zip file of the distribution.< If you understand russian, you can also find system calls on this wiki.
If you understand russian, you can also find system calls on this wiki.<br><br>
 
To execute a system call, you first need to fill the registers with the correct value.
To execute a system call, you first need to fill the registers with the correct value. Say we want to wait a couple of milliseconds, we need to use system function 5 and place the time we want to wait in ebx.
Say we want to wait a couple of milliseconds, we need to use system function 5 and place the time we want to wait in ebx.
 
<asm>
<syntaxhighlight>
      mov    eax, 5
        mov    eax, 5
      mov    ebx, 10
        mov    ebx, 10
</asm>
</syntaxhighlight>
Now, we need to execute the function, this can be done with int 0x40
 
<asm>
Now, we need to execute the function, this can be done with int 0x40:
      int    0x40
 
</asm>
<syntaxhighlight>
But also with more modern instructions such as syscall, sysenter etc.<br>
        int    0x40
It's convenient to use the mcall macro from macros.inc, then you can chose to use int 0x40 or another method, at compile time.<br>
</syntaxhighlight>
This macro also accepts parameters, first is eax, second is ebx, ...<br>
 
Code for the above would be:
But also with more modern instructions such as syscall, sysenter etc. It's convenient to use the mcall macro from macros.inc, then you can chose to use int 0x40 or another method, at compile time. This macro also accepts parameters, first is eax, second is ebx, ... Code for the above would be:
<asm>
 
      mcall   5, 10
<syntaxhighlight>
</asm>
        mcall   5, 10
</syntaxhighlight>


= Coding Style =
= Coding Style =
Line 125: Line 126:


== Simple example ==
== Simple example ==
 
 
<asm>
<syntaxhighlight>
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                  ;
;                                                  ;
Line 135: Line 135:
;                                                  ;
;                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; The header
; The header
 
use32                          ; Tell compiler to use 32 bit instructions


        org     0x0             ; the base address of code, always 0x0
use32                                  ; Tell compiler to use 32 bit instructions
 
org 0x0                                 ; the base address of code, always 0x0


        db     'MENUET01'    
db 'MENUET01'
        dd     0x01        
dd 0x01
        dd     START        
dd START
        dd     I_END        
dd I_END
        dd     0x100000      
dd 0x100000
        dd     0x7fff0      
dd 0x7fff0
        dd     0, 0  
dd 0, 0
 


; The code area
; The code area


        include 'macros.inc'
include 'macros.inc'
 
 
 
START:                                  ; start of execution
START:                                  ; start of execution
 
         call    draw_window            ; draw the window
         call    draw_window            ; draw the window


 
; After the window is drawn, it's practical to have the main loop.
; After the window is drawn, it's practical to have the main loop.
; Events are distributed from here.
; Events are distributed from here.
 
 
event_wait:
event_wait:
 
 
         mov    eax, 10                ; function 10 : wait until event
         mov    eax, 10                ; function 10 : wait until event
         mcall
         mcall                           ; event type is returned in eax
                                        ; event type is r