Difference between revisions of "Writing applications for KolibriOS"

From KolibriOS wiki
Jump to navigation Jump to search
(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 returned in eax
+
 
 
 
 
         cmp    eax, 1                  ; Event redraw request ?
 
         cmp    eax, 1                  ; Event redraw request ?
 
         je      red                    ; Expl.: there has been activity on screen and
 
         je      red                    ; Expl.: there has been activity on screen and
Line 178: Line 171:
 
         je      key                    ; Expl.: User has pressed a key while the
 
         je      key                    ; Expl.: User has pressed a key while the
 
                                         ; app is at the top of the window stack.
 
                                         ; app is at the top of the window stack.
 
+
 
 
         cmp    eax, 3                  ; Event button in buffer ?
 
         cmp    eax, 3                  ; Event button in buffer ?
 
         je      button                  ; Expl.: User has pressed one of the
 
         je      button                  ; Expl.: User has pressed one of the
 
                                         ; applications buttons.
 
                                         ; applications buttons.
 
+
 
 
         jmp    event_wait
 
         jmp    event_wait
 
+
 
 
 
 
 
 
;  The next section reads the event and processes data.
 
;  The next section reads the event and processes data.
 
 
 
 
  red:                                  ; Redraw event handler
 
  
 +
red:                                    ; Redraw event handler
 
         call    draw_window            ; We call the window_draw function and
 
         call    draw_window            ; We call the window_draw function and
 
         jmp    event_wait              ; jump back to event_wait
 
         jmp    event_wait              ; jump back to event_wait
 
 
  key:                                  ; Keypress event handler
 
  
         mov    eax,2                   ; The key is returned in ah. The key must be
+
key:                                    ; Keypress event handler
 +
         mov    eax, 2                 ; The key is returned in ah. The key must be
 
         mcall                          ; read and cleared from the system queue.
 
         mcall                          ; read and cleared from the system queue.
 
         jmp    event_wait              ; Just read the key, ignore it and jump to event_wait.
 
         jmp    event_wait              ; Just read the key, ignore it and jump to event_wait.
 
 
  button:                              ; Buttonpress event handler
 
  
 +
button:                                ; Buttonpress event handler
 
         mov    eax,17                  ; The button number defined in window_draw
 
         mov    eax,17                  ; The button number defined in window_draw
 
         mcall                          ; is returned to ah.
 
         mcall                          ; is returned to ah.
Line 211: Line 198:
 
         mcall
 
         mcall
  
  noclose:
+
noclose:
 
+
         jmp     event_wait             ; This is for ignored events, useful at development
         jmp event_wait             ; This is for ignored events, useful
+
 
                                ; at development
 
 
 
 
 
 
;  *********************************************
 
;  *********************************************
 
;  ******  WINDOW DEFINITIONS AND DRAW  ********
 
;  ******  WINDOW DEFINITIONS AND DRAW  ********
Line 226: Line 210:
 
;
 
;
 
;  The static parts *must* be placed within the fn 12 , ebx = 1 and ebx = 2.
 
;  The static parts *must* be placed within the fn 12 , ebx = 1 and ebx = 2.
 
+
 
 
draw_window:
 
draw_window:
 
+
         mov     eax, 12                 ; function 12: tell os about windowdraw
 
+
         mov     ebx, 1                 ; 1, start of draw
         mov eax, 12                   ; function 12:tell os about windowdraw
 
         mov ebx, 1                     ; 1, start of draw
 
 
         mcall
 
         mcall
  
                                        ; DRAW WINDOW
+
         mov     eax, 0                 ; function 0 : define and draw window
         mov eax, 0                     ; function 0 : define and draw window
+
         mov     ebx, 100 * 65536 + 300 ; [x start] *65536 + [x size]
         mov ebx, 100*65536+300         ; [x start] *65536 + [x size]
+
         mov     ecx, 100 * 65536 + 120 ; [y start] *65536 + [y size]
         mov ecx, 100*65536+120         ; [y start] *65536 + [y size]
+
         mov     edx, 0x14ffffff         ; color of work area RRGGBB
         mov edx, 0x14ffffff           ; color of work area RRGGBB
 
 
                                         ; 0x02000000 = window type 4 (fixed size, skinned window)
 
                                         ; 0x02000000 = window type 4 (fixed size, skinned window)
         mov esi, 0x808899ff           ; color of grab bar  RRGGBB
+
         mov     esi, 0x808899ff         ; color of grab bar  RRGGBB
 
                                         ; 0x80000000 = color glide
 
                                         ; 0x80000000 = color glide
         mov edi, title
+
         mov     edi, title
 
         mcall
 
         mcall
  
 +
        mov    ebx, 25 * 65536 + 35    ; draw info text with function 4
 +
        mov    ecx, 0x224466
 +
        mov    edx, text
 +
        mov    esi, 40
 +
        mov    eax, 4
  
        mov  ebx, 25*65536+35          ; draw info text with function 4
+
  .newline:                            ; text from the DATA AREA
        mov  ecx, 0x224466
 
        mov  edx, text
 
        mov  esi, 40
 
        mov  eax, 4
 
  newline:                            ; text from the DATA AREA
 
 
         mcall
 
         mcall
         add ebx, 10
+
         add     ebx, 10
         add edx, 40
+
         add     edx, 40
         cmp byte [edx], 0
+
         cmp     byte[edx], 0
         jne newline
+
         jne     .newline
  
         mov eax,12                     ; function 12:tell os about windowdraw
+
         mov     eax, 12                 ; function 12:tell os about windowdraw
         mov ebx,2                     ; 2, end of draw
+
         mov     ebx, 2                 ; 2, end of draw
 
         mcall
 
         mcall
  
 
         ret
 
         ret
 
+
 
 
 
 
 
 
;  *********************************************
 
;  *********************************************
 
;  *************  DATA AREA  *****************
 
;  *************  DATA AREA  *****************
Line 272: Line 251:
 
; Data can be freely mixed with code to any parts of the image.
 
; Data can be freely mixed with code to any parts of the image.
 
; Only the header information is required at the beginning of the image.
 
; Only the header information is required at the beginning of the image.
 
+
 
 
 
 
text    db  "It look's like you have just compiled  "
 
text    db  "It look's like you have just compiled  "
 
         db  "your first program for KolibriOS.      "
 
         db  "your first program for KolibriOS.      "
Line 281: Line 259:
 
title  db  "Example application", 0
 
title  db  "Example application", 0
  
 
 
 
I_END:
 
I_END:
 
+
 
 
; The area after I_END is free for use as the application memory,  
 
; The area after I_END is free for use as the application memory,  
 
; just avoid the stack.
 
; just avoid the stack.
Line 304: Line 281:
 
; direct reference.
 
; direct reference.
 
; For example, mov [0x80000],byte 1 moves a byte above the stack area.
 
; For example, mov [0x80000],byte 1 moves a byte above the stack area.
 +
</syntaxhighlight>
  
</asm>
+
It should look like this (perhaps with other skin):
  
It should look like this (perhaps with other skin):<br>
 
 
[[Image:Example_1.png]]
 
[[Image:Example_1.png]]
 
+
 
 
KolibriOS's application structure is not specifically reserved for asm programming, the header can be produced with practically any other language. However, the overall application programming design is intended for easy 32 bit asm programming. The GUI is extremely easy to handle with especially asm language.
 
KolibriOS's application structure is not specifically reserved for asm programming, the header can be produced with practically any other language. However, the overall application programming design is intended for easy 32 bit asm programming. The GUI is extremely easy to handle with especially asm language.
  
 
 
 
 
 
== Using uniform system colours ==
 
== Using uniform system colours ==
 
+
 
 
+
While previous example concentrated on creating a basic application, in this section more attention is paid on the outlook of the window.
While previous example concentrated on creating a basic application,
+
 
in this section more attention is paid on the outlook of the window.
 
 
 
 
You can use uniform desktop colors defined by a colour setup application.
 
You can use uniform desktop colors defined by a colour setup application.
 
+
 
 
New fuction in this example is get_system_colours.
 
New fuction in this example is get_system_colours.
 
+
 
<asm>
+
<syntaxhighlight>
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;                                                  ;
 
;                                                  ;
Line 333: Line 305:
 
;                                                  ;
 
;                                                  ;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+
 
 
; The header
 
; The header
 
+
 
 
use32
 
use32
 
+
 
        org     0x0
+
org 0x0
 
+
 
        db     'MENUET01'
+
db 'MENUET01'
        dd     1, START, I_END, 0x100000, 0x7fff0, 0, 0
+
dd 1, START, I_END, 0x100000, 0x7fff0, 0, 0
 
+
 
 
 
 
; The code area
 
; The code area
 
 
 
 
window_size_X  equ  300
 
window_size_Y  equ  150
 
  
 +
window_size_X equ 300
 +
window_size_Y equ 150
 +
 +
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:
 
 
 
         mcall  10              ; function 10 : wait until event
 
         mcall  10              ; function 10 : wait until event
 
                                 ; event type is returned in eax
 
                                 ; event type is returned in eax
Line 376: Line 341:
 
; If eax is 2, it will take 2 time 'dec  eax' before zero flag will be set..
 
; If eax is 2, it will take 2 time 'dec  eax' before zero flag will be set..
  
 
 
 
         dec    eax            ; Event redraw request ?
 
         dec    eax            ; Event redraw request ?
 
         jz      red            ; Expl.: there has been activity on screen and
 
         jz      red            ; Expl.: there has been activity on screen and
 
                                 ; parts of the applications has to be redrawn.
 
                                 ; parts of the applications has to be redrawn.
 
+
 
 
         dec    eax            ; Event key in buffer ?
 
         dec    eax            ; Event key in buffer ?
 
         jz      key            ; Expl.: User has pressed a key while the
 
         jz      key            ; Expl.: User has pressed a key while the
 
                                 ; app is at the top of the window stack.
 
                                 ; app is at the top of the window stack.
 
+
 
 
         dec    eax            ; Event button in buffer ?
 
         dec    eax            ; Event button in buffer ?
 
         jz      button          ; Expl.: User has pressed one of the
 
         jz      button          ; Expl.: User has pressed one of the
 
                                 ; applications buttons.
 
                                 ; applications buttons.
 
+
 
 
         jmp    event_wait
 
         jmp    event_wait
 
+
 
 
 
 
 
 
;  The next section reads the event and processes data.
 
;  The next section reads the event and processes data.
 
 
 
 
  red:                          ; Redraw event handler
 
  
 +
red:                            ; Redraw event handler
 
         call    draw_window    ; We call the window_draw function and
 
         call    draw_window    ; We call the window_draw function and
 
         jmp    event_wait      ; jump back to event_wait
 
         jmp    event_wait      ; jump back to event_wait
  
 
+
key:                           ; Keypress event handler
  key:                         ; Keypress event handler
 
 
 
 
         mcall  2              ; The key is returned in ah. The key must be read and cleared from the system queue.
 
         mcall  2              ; The key is returned in ah. The key must be read and cleared from the system queue.
 
         jmp    event_wait      ; Just read the key, ignore it and jump to event_wait.
 
         jmp    event_wait      ; Just read the key, ignore it and jump to event_wait.
  
 
+
button:                         ; Buttonpress event handler
  button:                       ; Buttonpress event handler
+
        mcall  17              ; The button number defined in window_draw  is returned to ah.
  
        mcall  17              ; The button number defined in window_draw  is returned to ah.
 
 
 
 
         cmp    ah, 1          ; button id=1 ?
 
         cmp    ah, 1          ; button id=1 ?
 
         jne    event_wait      ; if not, go back and wait for other events
 
         jne    event_wait      ; if not, go back and wait for other events
Line 417: Line 373:
 
         mcall  -1              ; Function -1 : close this program
 
         mcall  -1              ; Function -1 : close this program
  
 
 
 
get_system_colours:
 
get_system_colours:
 
 
 
         pusha
 
         pusha
 
+
 
 
         mov    eax, 48                ; fn 48 system colours
 
         mov    eax, 48                ; fn 48 system colours
 
         mov    ebx, 3                  ; subfn 3 : get
 
         mov    ebx, 3                  ; subfn 3 : get
 
         mov    ecx, app_colours        ; pointer to return area
 
         mov    ecx, app_colours        ; pointer to return area
         mov    edx, 10*4               ; number of bytes to return
+
         mov    edx, 10 * 4             ; number of bytes to return
 
         mcall
 
         mcall
 
+
 
 
         popa
 
         popa
 
+
 
 
         ret
 
         ret
 
+
 
 
+
;*********************************************
app_colours:                            ; SYSTEM COLOURS TABLE
+
;******  WINDOW DEFINITIONS AND DRAW  ********
 
+
;*********************************************
w_frames            dd ?              ; - frames
 
w_grab              dd ?              ; - GRAB AREA
 
w_grab_button        dd ?              ;  grab area button
 
w_grab_button_text  dd ?              ;  grab area button text
 
w_grab_text          dd ?              ;  grab area text
 
w_work              dd ?              ; - WORK AREA
 
w_work_button        dd ?              ;  work area button
 
w_work_button_text  dd ?              ;  work area button text
 
w_work_text          dd ?              ;  work area text
 
w_work_graph        dd ?              ;   work area graphics
 
 
 
 
 
 
 
*********************************************
 
; ******  WINDOW DEFINITIONS AND DRAW  ********
 
; *********************************************
 
 
;
 
;
 
;  The static window parts are drawn in this function. The window canvas can
 
;  The static window parts are drawn in this function. The window canvas can
Line 461: Line 399:
 
;  When using system colours, the window colours are read from the
 
;  When using system colours, the window colours are read from the
 
;  SYSTEM COLOURS TABLE
 
;  SYSTEM COLOURS TABLE
;
+
 
 
 
 
 
 
draw_window:
 
draw_window:
 
 
 
 
 
         mcall  12, 1                          ; Tell OS about start of redraw
 
         mcall  12, 1                          ; Tell OS about start of redraw
 
+
 
 
         call    get_system_colours              ; fetches system colours from os
 
         call    get_system_colours              ; fetches system colours from os
 
+
 
                                                ; DRAW WINDOW
 
 
         mov    eax, 0                          ; function 0 : define and draw window
 
         mov    eax, 0                          ; function 0 : define and draw window
  
         mov    ebx, 100*65536+window_size_X   ; [x start] *65536 + [x size]
+
         mov    ebx, 100 * 65536 + window_size_X ; [x start] *65536 + [x size]
         mov    ecx, 100*65536+window_size_Y   ; [y start] *65536 + [y size]
+
         mov    ecx, 100 * 65536 + window_size_Y ; [y start] *65536 + [y size]
  
 
         mov    edx, [w_work]                  ; color of work area 0xRRGGBB
 
         mov    edx, [w_work]                  ; color of work area 0xRRGGBB
Line 484: Line 417:
 
         mcall
 
         mcall
  
         mov    ebx, 25*65536+35           ; draw info text with function 4
+
         mov    ebx, 25 * 65536 + 35           ; draw info text with function 4
 
         mov    ecx, [w_work_text]
 
         mov    ecx, [w_work_text]
         mov    edx, text
+
         mov    edx, text                       ; text from the DATA AREA
 
         mov    esi, 40
 
         mov    esi, 40
  
 
         mov    eax, 4
 
         mov    eax, 4
  newline:                        ; text from the DATA AREA
 
  
 +
  .newline:
 
         mcall
 
         mcall
 
         add    ebx, 10
 
         add    ebx, 10
 
         add    edx, 40
 
         add    edx, 40
 
         cmp    byte [edx], 0
 
         cmp    byte [edx], 0
         jne    newline
+
         jne    .newline
 
+
 
 +
        mcall  12, 2 ; end of redraw
 +
 
 +
        ret
  
        mcall  12, 2                  ; end of redraw
 
 
 
    ret
 
 
 
 
 
 
;  *********************************************
 
;  *********************************************
 
;  *************  DATA AREA  *****************
 
;  *************  DATA AREA  *****************
Line 510: Line 441:
 
; Data can be freely mixed with code to any parts of the image.
 
; Data can be freely mixed with code to any parts of the image.
 
; Only the header information is required at the beginning of the image.
 
; Only the header information is required at the beginning of the image.
 
+
 
 
text    db  'THIS PROGRAM USES UNIFORM SYSTEM COLOURS'
 
text    db  'THIS PROGRAM USES UNIFORM SYSTEM COLOURS'
 
         db  'RETURNED TO A TABLE                    ', 0
 
         db  'RETURNED TO A TABLE                    ', 0
 
+
 
 
 
 
title  db  'EXAMPLE APPLICATION', 0
 
title  db  'EXAMPLE APPLICATION', 0
  
 
I_END:
 
I_END:
  
</asm>
+
app_colours:                            ; SYSTEM COLOURS TABLE
 +
  w_frames          dd ?              ; - frames
 +
  w_grab            dd ?              ; - GRAB AREA
 +
  w_grab_button      dd ?              ;  grab area button
 +
  w_grab_button_text dd ?              ;  grab area button text
 +
  w_grab_text        dd ?              ;  grab area text
 +
  w_work            dd ?              ; - WORK AREA
 +
  w_work_button      dd ?              ;  work area button
 +
  w_work_button_text dd ?              ;  work area button text
 +
  w_work_text        dd ?              ;  work area text
 +
  w_work_graph      dd ?              ;  work area graphics
 +
</syntaxhighlight>
  
 
== Freeform window ==
 
== Freeform window ==
 
+
 
 
+
In this example we concentrate on shaping the window from rectangle to any form desired by the programmer. New fuction in this example is shape_window.
In this example we concentrate on shaping the window from rectangle
+
 
to any form desired by the programmer. New fuction in this example
+
<syntaxhighlight>
is shape_window.
 
 
 
<asm>
 
 
 
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;                                                  ;
 
;                                                  ;
Line 538: Line 474:
 
;                                                  ;
 
;                                                  ;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+
 
 
; The header
 
; The header
 
+
 
 
use32
 
use32
 
 
        org    0x0
 
 
 
        db    'MENUET01'
 
        dd    1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0
 
  
 +
org 0x0
  
        include 'macros.inc'
+
db 'MENUET01'
 +
dd 1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0
  
 +
include 'macros.inc'
  
 
 
 
START:                          ; start of execution
 
START:                          ; start of execution
 
 
 
         call    shape_window    ; function for shaping
 
         call    shape_window    ; function for shaping
 
 
 
         call    draw_window    ; at first, draw the window
 
         call    draw_window    ; at first, draw the window
 
+
 
 
still:
 
still:
 
 
 
         mcall  10              ; wait here for event
 
         mcall  10              ; wait here for event
  
Line 569: Line 499:
 
         je      key
 
         je      key
  
         dec     eax           ; button in buffer ?
+
         dec     eax             ; button in buffer ?
 
         je      button
 
         je      button
  
 
         jmp    still
 
         jmp    still
 
 
  red:                          ; redraw
 
  
 +
red:                            ; redraw
 
         call    draw_window
 
         call    draw_window
 
         jmp    still
 
         jmp    still
 
    
 
    
  key:                         ; key
+
key:                           ; key
 
 
 
         mcall  2              ; just read it and ignore
 
         mcall  2              ; just read it and ignore
 
         jmp    still
 
         jmp    still
 
    
 
    
  button:                       ; button
+
button:                         ; button
 
 
 
         mcall  17              ; get id
 
         mcall  17              ; get id
 
    
 
    
         cmp    ah,1           ; button id=1 ?
+
         cmp    ah, 1           ; button id=1 ?
 
         jne    noclose
 
         jne    noclose
  
 
         mcall  -1              ; close this program
 
         mcall  -1              ; close this program
  noclose:
+
 
 
+
noclose:
 
         jmp    still
 
         jmp    still
 
+
 
 
 
 
shape_window:
 
shape_window:
 
 
 
         pusha
 
         pusha
  
 
; give the shape reference area
 
; give the shape reference area
  
         mcall 50, 0, shape_reference
+
         mcall   50, 0, shape_reference
  
 
; give the shape scale  32 x 32  ->  128 x 128
 
; give the shape scale  32 x 32  ->  128 x 128
Line 609: Line 534:
 
; scale is set to 2^ecx
 
; scale is set to 2^ecx
  
         mcall 50, 1, 2
+
         mcall   50, 1, 2
 
+
 
 
         popa
 
         popa
 
 
 
         ret
 
         ret
 
+
 
 
+
shape_reference: ; 32 x 32, ( window_size_X + 1 ) * ( window_size_Y + 1 )
shape_reference:   ; 32 x 32   ( window_size_X + 1 ) * ( window_size_Y + 1 )
+
  db 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
 
+
  db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
    db   0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
+
  db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
    db   0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
+
  db 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
    db   0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
+
  db 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
    db   0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
+
  db 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
    db   0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
+
  db 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
    db   0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
+
  db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
    db   0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
+
  db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
    db   0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
+
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    db   0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
+
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
    db   0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
+
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
    db   0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
+
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
    db   0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
+
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
    db   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
+
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
    db   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
+
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
    db   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
+
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
    db   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
+
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
    db   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
+
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
    db   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
+
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
    db   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
+
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
    db   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
+
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    db   0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
+
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    db   0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
+
  db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
    db   0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
+
  db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
    db   0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
+
  db 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
    db   0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
+
  db 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
    db   0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
+
  db 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
    db   0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
+
  db 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
    db   0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
+
  db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
    db   0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
+
  db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
    db   0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
+
  db 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
    db   0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
+
 
    db   0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
+
;*********************************************
 
+
;*******  WINDOW DEFINITIONS AND DRAW ********
 
+
;*********************************************
;   *********************************************
+
 
;   *******  WINDOW DEFINITIONS AND DRAW ********
 
;   *********************************************
 
 
 
 
 
 
draw_window:
 
draw_window:
 
 
 
         mcall  12, 1                  ; notice os about start of redraw
 
         mcall  12, 1                  ; notice os about start of redraw
 
+
 
                                        ; DRAW WINDOW
+
         mov    eax, 0                  ; function 0: define and draw window
         mov    eax, 0                  ; function 0 : define and draw window
+
         mov    ebx, 100 * 65536       ; [x start] * 65536 + [x size]
         mov    ebx, 100*65536         ; [x start] *65536 + [x size]
+
         mov    ecx, 100 * 65536       ; [y start] * 65536 + [y size]
         mov    ecx, 100*65536         ; [y start] *65536 + [y size]
 
 
         mov    bx , [x_size]
 
         mov    bx , [x_size]
 
         mov    cx , [y_size]
 
         mov    cx , [y_size]
Line 671: Line 589:
 
         mov    edi, 0x00cccc00        ; color of frames    RRGGBB
 
         mov    edi, 0x00cccc00        ; color of frames    RRGGBB
 
         mcall
 
         mcall
 
+
 
                                        ; CLOSE BUTTON
+
         mov    eax, 8                  ; function 8: define and draw button
         mov    eax, 8                  ; function 8 : define and draw button
+
         mov    ebx, 78 * 65536 + 12   ; [x start] * 65536 + [x size]
         mov    ebx, 78*65536+12       ; [x start] *65536 + [x size]
+
         mov    ecx, 20 * 65536 + 12   ; [y start] * 65536 + [y size]
         mov    ecx, 20*65536+12       ; [y start] *65536 + [y size]
 
 
         mov    edx, 1                  ; button id
 
         mov    edx, 1                  ; button id
 
         mov    esi, 0x5599cc          ; button color RRGGBB
 
         mov    esi, 0x5599cc          ; button color RRGGBB
 
         mcall
 
         mcall
 
+
 
 
 
 
         mcall  12, 2                  ; end of redraw
 
         mcall  12, 2                  ; end of redraw
 
+
 
 
         ret
 
         ret
 
+
 
 
; DATA
 
; DATA
 
+
 
x_size dw 127
+
x_size dw 127
y_size dw 127
+
y_size dw 127
 
+
 
 
I_END:
 
I_END:
 
+
</syntaxhighlight>
</asm>
 
  
 
== Threads ==
 
== Threads ==
 
+
 
 
+
KolibriOS assembly threading has some great advantages over higher level languages. If you keep all the variables in registers, you can start as meny threads as desired with the _same_ code, since no memory is affected and needs no saving. The registers are saved to Task Switch Segments by KolibriOS. All you have to do is to set a new stack.
KolibriOS assembly threading has some great advantages over higher
+
 
level languages. If you keep all the variables in registers, you can
+
Threads have no difference with the main process and use the same memory area as the process which starts it. They can have their own independent windows etc. In the closing of application, all threads have to be terminated with the default (eax = -1) system call.
start as meny threads as desired with the _same_ code, since
 
no memory is affected and needs no saving. The registers are saved
 
to Task Switch Segments by KolibriOS. All you have to do is to
 
set a new stack.
 
 
 
Threads have no difference with the main process and use the same
 
memory area as the process which starts it. They can have their own
 
independent windows etc. In the closing of application, all threads
 
have to be terminated with the default (eax = -1) system call.
 
  
 
New function in this example is create_thread.
 
New function in this example is create_thread.
  
<asm>
+
<syntaxhighlight>
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;                                                      ;
 
;                                                      ;
Line 720: Line 625:
 
;                                                      ;
 
;                                                      ;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+
 
 
use32
 
use32
 
 
              org    0x0
 
 
 
              db    'MENUET01'  ; 8 byte id for application
 
              dd    1, START, I_END, 0x100000, 0x80000, 0x0, 0x0
 
 
 
 
 
  
        include 'macros.inc'   
+
org 0x0
 
+
 
START:                         ; start of execution
+
db 'MENUET01' ; 8 byte id for application
    
+
dd 1, START, I_END, 0x100000, 0x80000, 0x0, 0x0
    call draw_window           ; at first, draw the window
+
 
 +
include 'macros.inc'   
 +
 
 +
START:                                   ; start of execution
 +
        call   draw_window               ; at first, draw the window
 
    
 
    
 
event_wait:
 
event_wait:
 
+
        mov     eax, 10                   ; wait here for event
     mov  eax,10                 ; wait here for event
+
        mcall
    mcall
+
 
 
+
        cmp     eax, 1                   ; redraw request ?
     cmp  eax,1                 ; redraw request ?
+
        je     red
    je   red
+
        cmp     eax, 2                   ; key in buffer ?
     cmp  eax,2                 ; key in buffer ?
+
        je     key
    je   key
+
        cmp     eax, 3                   ; button in buffer ?
     cmp  eax,3                 ; button in buffer ?
+
        je     button
    je   button
+
 
 
+
        jmp     event_wait
     jmp  event_wait
+
 
 
+
red:                                     ; redraw
  red:                         ; redraw
+
        call   draw_window
    call draw_window
+
        jmp     event_wait
     jmp  event_wait
+
 
 
+
key:                                     ; key
  key:                         ; key
+
        mov     eax, 2                   ; just read it and ignore
     mov  eax,2                 ; just read it and ignore
+
        mcall
    mcall
+
        jmp     event_wait
     jmp  event_wait
+
 
 
+
button:                                   ; button
  button:                       ; button
+
        mov     eax, 17                   ; get id
     mov  eax,17                 ; get id
+
        mcall
    mcall
+
 
 
+
        cmp     ah, 1                     ; button id=1 ?
     cmp  ah,1                   ; button id=1 ?
+
        jne     noclose
     jne  noclose
+
        mov     eax, -1                   ; close this program (thread)
     mov  eax,-1                 ; close this program (thread)
+
        mcall
    mcall
+
 
  noclose:
+
noclose:
 
+
        cmp     ah, 2                     ; call create_thread
     cmp  ah,2                   ; call create_thread
+
        jne     no_thread
     jne  no_thread
+
        call   create_thread
    call create_thread
+
        jmp     event_wait
     jmp  event_wait
+
 
  no_thread:
+
no_thread:
 
+
        jmp     event_wait
     jmp  event_wait
+
 
 
 
 
 
 
; THREAD CREATION
 
; THREAD CREATION
 
;
 
;
 
; All we have to do is to give the thread entry address in ecx and
 
; All we have to do is to give the thread entry address in ecx and
 
; a new stack postition in edx with function eax=51, ebx=1
 
; a new stack postition in edx with function eax=51, ebx=1
 
+
 
 
create_thread:
 
create_thread:
 +
        cmp    [thread_stack], 0xf0000
 +
        jge    no_new_thread
 
    
 
    
     cmp  [thread_stack],0xf0000
+
        add     [thread_stack], 0x1000
    jge  no_new_thread
 
 
 
    add  [thread_stack],0x1000
 
 
 
    mov  eax,51                  ; thread_create system call
 
    mov  ebx,1
 
    mov  ecx,START
 
    mov  edx,[thread_stack]
 
    mcall
 
 
 
  no_new_thread:
 
 
 
    ret
 
 
    
 
    
 +
        mov    eax, 51                  ; thread_create system call
 +
        mov    ebx, 1
 +
        mov    ecx, START
 +
        mov    edx, [thread_stack]
 +
        mcall
 +
 +
no_new_thread:
 +
        ret
 +
 
thread_stack dd 0x80000
 
thread_stack dd 0x80000
 
+
 
 
+
;*********************************************
;   *********************************************
+
;*******  WINDOW DEFINITIONS AND DRAW ********
;   *******  WINDOW DEFINITIONS AND DRAW ********
+
;*********************************************
;   *********************************************
+
 
 
 
 
 
 
draw_window:
 
draw_window:
 
+
        mov     eax, 12                   ; function 12: tell os about windowdraw
     mov  eax,12                   ; function 12:tell os about windowdraw
+
        mov     ebx, 1                   ; 1, start of draw
     mov  ebx,1                     ; 1, start of draw
+
        mcall
    mcall
+
 
 
+
        mov     eax, 0                   ; function 0: define and draw window
                                  ; DRAW WINDOW
+
        mov     ebx, 10 * 65536 + 300     ; [x start] * 65536 + [x size]
     mov  eax,0                     ; function 0 : define and draw window
+
        mov     ecx, 10 * 65536 + 140     ; [y start] * 65536 + [y size]
     mov  ebx,10*65536+300         ; [x start] *65536 + [x size]
+
        mov     esi, [thread_stack]
     mov  ecx,10*65536+140         ; [y start] *65536 + [y size]
+
        sub     esi, 0x80000
     mov  esi,[thread_stack]
+
        shr     esi, 11
     sub  esi,0x80000
+
        shl     esi, 16
     shr  esi,11
+
        add     ebx, esi
     shl  esi,16
+
        add     ecx, esi
     add  ebx,esi
+
        mov     edx, 0x02ffffff           ; color of work area RRGGBB,8->color glide
     add  ecx,esi
+
        mov     esi, 0x808899ff           ; color of grab bar  RRGGBB,8->color glide
     mov  edx,0x02ffffff           ; color of work area RRGGBB,8->color glide
+
        mov     edi, 0x008899ff           ; color of frames    RRGGBB
     mov  esi,0x808899ff           ; color of grab bar  RRGGBB,8->color glide
+
        mcall
     mov  edi,0x008899ff           ; color of frames    RRGGBB
+
 
    mcall
+
        ; WINDOW LABEL
 
+
        mov     eax, 4                   ; function 4: write text to window
                                  ; WINDOW LABEL
+
        mov     ebx, 8 * 65536 + 8       ; [x start] * 65536 + [y start]
     mov  eax,4                     ; function 4 : write text to window
+
        mov     ecx, 0x00ddeeff           ; color of text RRGGBB
     mov  ebx,8*65536+8             ; [x start] *65536 + [y start]
+
        mov     edx, labelt               ; pointer to text beginning
     mov  ecx,0x00ddeeff           ; color of text RRGGBB
+
        mov     esi, labellen-labelt     ; text length
     mov  edx,labelt               ; pointer to text beginning
+
        mcall
     mov  esi,labellen-labelt       ; text length
+
 
    mcall
+
        ; CLOSE BUTTON
 
+
        mov     eax, 8                   ; function 8: define and draw button
                                  ; CLOSE BUTTON
+
        mov     ebx, (300 - 19) * 65536 + 12 ; [x start] * 65536 + [x size]
     mov  eax,8                     ; function 8 : define and draw button
+
        mov     ecx, 5 * 65536 + 12       ; [y start] * 65536 + [y size]
     mov  ebx,(300-19)*65536+12     ; [x start] *65536 + [x size]
+
        mov     edx, 1                   ; button id
     mov  ecx,5*65536+12           ; [y start] *65536 + [y size]
+
        mov     esi, 0x6677cc             ; button color RRGGBB
     mov  edx,1                     ; button id
+
        mcall
     mov  esi,0x6677cc             ; button color RRGGBB
+
 
    mcall
+
        ; NEW THREAD BUTTON
 
+
        mov     eax, 8
    mov  eax,8                    ; NEW THREAD BUTTON
+
        mov     ebx, 25 * 65536 + 128
     mov ebx,25*65536+128
+
        mov     ecx, 88 * 65536 + 20
     mov  ecx,88*65536+20
+
        mov     edx, 2
     mov  edx,2
+
        mov     esi, 0x6677cc
     mov  esi,0x6677cc
+
        mcall
    mcall
+
 
 
+
        mov     ebx, 25 * 65536 + 35     ; draw info text with function 4
     mov  ebx,25*65536+35           ; draw info text with function 4
+
        mov     ecx, 0x224466
     mov  ecx,0x224466
+
        mov     edx, text
     mov  edx,text
+
        mov     esi, 40
     mov  esi,40
+
 
   newline:
+
   .newline:
     mov  eax,4
+
        mov     eax, 4
    mcall
+
        mcall
     add  ebx,10
+
        add     ebx, 10
     add  edx,40
+
        add     edx, 40
     cmp  byte [edx], 0
+
        cmp     byte[edx], 0
     jne  newline
+
        jne     .newline
 
+
 
     mov  eax,12                   ; function 12:tell os about windowdraw
+
        mov     eax, 12                   ; function 12: tell os about windowdraw
     mov  ebx,2                     ; 2, end of draw
+
        mov     ebx, 2                   ; 2, end of draw
    mcall
+
        mcall
 
+
 
    ret
+
        ret
 
+
 
 
 
 
; DATA AREA
 
; DATA AREA
 
+
 
 
 
 
text:
 
text:
 
     db 'THIS EXAMPLE CREATES THREADS BY RUNNING '
 
     db 'THIS EXAMPLE CREATES THREADS BY RUNNING '
Line 882: Line 776:
 
     db '                                        '
 
     db '                                        '
 
     db '  CREATE NEW THREAD                    ', 0
 
     db '  CREATE NEW THREAD                    ', 0
 
+
 
 
 
 
labelt:
 
labelt:
    db  'THREAD EXAMPLE'
+
    db  'THREAD EXAMPLE'
 
labellen:
 
labellen:
 
+
 
 
I_END:
 
I_END:
 
+
</syntaxhighlight>   
</asm>   
+
 
 
 
 
 
 
 
 
== Real-Time data ==
 
== Real-Time data ==
  
 
+
The following example focuses on Real-Time data fetching and processing. Application informs the OS for all the ports and datatypes to read at a specific IRQ.
The following example focuses on Real-Time data fetching and processing.  
+
 
Application informs the OS for all the ports and datatypes to read  
 
at a specific IRQ.
 
 
 
 
Steps:
 
Steps:
 
+
# reserve I/O port area
1) reserve I/O port area
+
# reserve IRQ
2) reserve IRQ
+
# program IRQ
3) program IRQ
+
# program EVENT list for wanted IRQ
4) program EVENT list for wanted IRQ
+
# runtime processing of the data
 
+
# back to default events - free IRQ from EVENT list
5) runtime processing of the data
+
# free IRQ
 
+
# free port area
6) back to default events - free IRQ from EVENT list
+
# terminate program
7) free IRQ
 
8) free port area
 
9) terminate program
 
 
 
After IRQ's are programmed, the application has a new event for the
 
main event loop, number (IRQ+16).
 
  
When the application receives this event, the OS has recorded data
+
After IRQ's are programmed, the application has a new event for the main event loop, number (IRQ+16). When the application receives this event, the OS has recorded data ready for the application to process.
ready for the application to process.
 
 
 
The table below shows the main structure of processing real time data.
 
 
 
All the steps on the left of (A) are processed by the OS and the steps
 
right from (A) are processed by the application.
 
  
 +
The table below shows the main structure of processing real time data. All the steps on the left of (A) are processed by the OS and the steps right from (A) are processed by the application.
  
 
  IRQ          OWNER      =>  REC DATA  (A) SYS_EVENT => READ DATA => PROCESS
 
  IRQ          OWNER      =>  REC DATA  (A) SYS_EVENT => READ DATA => PROCESS
Line 945: Line 821:
 
  14 IDE        SYS
 
  14 IDE        SYS
 
  15 IDE        SYS
 
  15 IDE        SYS
 
+
 
 
An example of processing Real-Time data:
 
An example of processing Real-Time data:
 
 
  
<asm>
+
<syntaxhighlight>
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;                                                ;
 
;                                                ;
Line 958: Line 832:
 
;                                                ;
 
;                                                ;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+
 
 
 
 
use32
 
use32
 
 
        org    0x0
 
  
        db     'MENUET01'   ; 8 byte id for application
+
org 0x0
        dd     1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0
+
 
    
+
db 'MENUET01' ; 8 byte id for application
 +
dd 1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0
 +
 
 +
include 'macros.inc' 
 +
 
 +
START:                                ; start of execution
 +
        call   draw_window            ; at first, draw the window
 +
        call    program_real_time_data ; program the OS to receive real time data
 +
        call    program_com_port      ; program the com port for specific device
  
        include 'macros.inc' 
 
 
 
START:                          ; start of execution
 
 
 
    call draw_window            ; at first, draw the window
 
 
 
    call program_real_time_data ; program the OS to receive real time data
 
 
 
    call program_com_port      ; program the com port for specific device
 
 
 
 
event_wait:
 
event_wait:
 
+
        mov     eax, 10               ; wait here for event
     mov  eax,10                 ; wait here for event
+
        mcall
    mcall
+
 
 
+
        cmp     eax, 1                 ; redraw request ?
     cmp  eax,1                 ; redraw request ?
+
        je     red
    je   red
+
        cmp     eax, 2                 ; key in buffer ?
     cmp  eax,2                 ; key in buffer ?
+
        je     key
    je   key
+
        cmp     eax, 3                 ; button in buffer ?
     cmp  eax,3                 ; button in buffer ?
+
        je     button
    je   button
+
 
 
+
        cmp     eax, 16 + 4           ; RT: new event for wanted IRQ data (16+IRQ)
     cmp  eax,16+4               ; RT: new event for wanted IRQ data (16+IRQ)
+
        je     read_rt
    je   read_rt
+
 
 
+
        jmp     event_wait
     jmp  event_wait
+
 
 
 
 
 
 
;  The next section reads the event and processes data.
 
;  The next section reads the event and processes data.
 +
 +
read_rt:                              ; RT data
 +
        mov    eax, 42                ; Function 42 returns recorded data for IRQ 4
 +
        mov    ebx, 4                ;
 +
        mcall                          ; OS returns the recorded data.
 +
                                      ; eax  number of bytes in buffer left
 +
                                      ; bl  data
 +
                                      ; ecx  0 = success, other = no data in buf.
 +
 +
        call    process_data
 +
        jmp    event_wait
 +
 +
red:                                  ; redraw
 +
        call    draw_window
 +
        jmp    event_wait
 +
 +
key:                                  ; key
 +
        mov    eax, 2                ; just read it and ignore
 +
        mcall
 +
        jmp    event_wait
 +
 +
button:                                ; button
 +
        mov    eax, 17                ; get id
 +
        mcall
 +
 +
        cmp    ah, 1                  ; button id=1 ?
 +
        jne    noclose
 
    
 
    
 +
        call    free_real_time_data
 
    
 
    
  read_rt:                      ; RT data
+
        mov    eax, -1               ; close this program
    mov  eax,42                ; Function 42 returns recorded data for IRQ 4
+
        mcall
    mov ebx,4                  ;
+
 
    mcall                  ; OS returns the recorded data.
+
noclose:
                                ; eax  number of bytes in buffer left
+
        jmp     event_wait
                                ; bl  data
+
 
                                ; ecx  0 = success, other = no data in buf.
 
 
 
    call process_data
 
    jmp  event_wait
 
 
 
  red:                          ; redraw
 
    call draw_window
 
    jmp  event_wait
 
 
 
  key:                          ; key
 
     mov  eax,2                  ; just read it and ignore
 
    mcall
 
    jmp  event_wait
 
 
 
  button:                      ; button
 
    mov  eax,17                ; get id
 
    mcall
 
 
 
 
 
    cmp  ah,1                  ; button id=1 ?
 
    jne  noclose
 
 
 
    call free_real_time_data
 
 
 
    mov  eax,-1                 ; close this program
 
    mcall
 
  noclose:
 
 
 
     jmp  event_wait
 
 
 
 
 
 
 
 
program_real_time_data:
 
program_real_time_data:
 
+
        ; Program the Real-Time data fetch
 
+
        ;
    ;   Program the Real-Time data fetch
+
        ; 1) reserve I/O port area
    ;
+
        ; 2) reserve IRQ
    ;   1) reserve I/O port area
+
        ; 3) program IRQ
    ;   2) reserve IRQ
+
        ; 4) program EVENT list for wanted IRQ
    ;   3) program IRQ
+
 
    ;   4) program EVENT list for wanted IRQ
+
        pusha
    ;
+
 
 
+
        mov     eax, 46               ; reserve ports 0x3f0 - 0x3ff
 
+
        mov     ebx, 0
    pusha
+
        mov     ecx, 0x3f0
 
+
        mov     edx, 0x3ff
     mov  eax,46           ; reserve ports 0x3f0 - 0x3ff
+
        mcall
     mov  ebx,0
+
 
     mov  ecx,0x3f0
+
        mov     eax, 45               ; reserve irq 4
     mov  edx,0x3ff
+
        mov     ebx, 0
    mcall
+
        mov     ecx, 4
 
+
        mcall
     mov  eax,45           ; reserve irq 4
+
 
     mov  ebx,0
+
        mov     eax, 44               ; set read ports for irq 4
     mov  ecx,4
+
        mov     ebx, irqtable
    mcall
+
        mov     ecx, 4
 
+
        mcall
     mov  eax,44           ; set read ports for irq 4
+
 
     mov  ebx,irqtable
+
        mov     eax, 40                             ; get com 1 data with irq 4
     mov  ecx,4
+
        mov     ebx, 0000000000010000b shl 16 + 111b ; after this we have a new event (16+4)
    mcall
+
        mcall
 
+
 
     mov  eax,40                                 ; get com 1 data with irq 4
+
        popa
     mov  ebx,0000000000010000b shl 16 + 111b   ; after this we have a new
+
        ret
                                                ; event (16+4)
+
 
    mcall
 
 
 
    popa
 
 
 
    ret
 
 
 
 
 
 
 
 
irqtable:
 
irqtable:
 
 
 
     dd  0x3f8+0x01000000 ; 3f8 =port to read  : 01 =read byte, 02 =read word
 
     dd  0x3f8+0x01000000 ; 3f8 =port to read  : 01 =read byte, 02 =read word
 
+
 
 
     dd  0x0              ; 0x0 = termintes read per IRQ event
 
     dd  0x0              ; 0x0 = termintes read per IRQ event
 
     dd  0x0
 
     dd  0x0
Line 1,097: Line 951:
 
     dd  0x0
 
     dd  0x0
 
     dd  0x0
 
     dd  0x0
 
+
 
 
 
 
free_real_time_data:
 
free_real_time_data:
 
+
        ; Free the used resources
    ; Free the used resources
+
        ;
    ;
+
        ; 1) get default events
    ; 1) get default events
+
        ; 2) free irq with function 45,1
    ; 2) free irq with function 45,1
+
        ; 3) free port area with function 46,1
    ; 3) free port area with function 46,1
+
 
    ;
+
        pusha
 
+
 
 
+
        mov     eax, 40               ; default events - disable irq 4 event
    pusha
+
        mov     ebx, 111b
 
+
        mcall
     mov  eax,40                 ; default events - disable irq 4 event
+
 
     mov  ebx,111b
+
        mov     eax, 45               ; free irq
    mcall
+
        mov     ebx, 1
 
+
        mov     ecx, 4
     mov  eax,45                 ; free irq
+
        mcall
     mov  ebx,1
+
 
     mov  ecx,4
+
        mov     eax, 46               ; free ports 0x3f0-0x3ff
    mcall
+
        mov     ebx, 1
 
+
        mov     ecx, 0x3f0
     mov  eax,46                 ; free ports 0x3f0-0x3ff
+
        mov     edx, 0x3ff
     mov  ebx,1
+
        mcall
     mov  ecx,0x3f0
 
     mov  edx,0x3ff
 
    mcall
 
 
 
    popa
 
 
 
    ret
 
 
 
  
 +
        popa
 +
        ret
  
 
; The following functions are for processing device specific data.
 
; The following functions are for processing device specific data.
 
+
 
 
 
 
process_data:
 
process_data:
 
+
        cmp     ebx, 80
     cmp  ebx,80
+
        jne     .nocd
     jne  nocd
+
 
 
+
        mov     eax, 19
     mov  eax,19
+
        mov     ebx, cdplayer
     mov  ebx,cdplayer
+
        mov     ecx, 0
     mov  ecx,0
+
        mcall
    mcall
+
 
 
+
   .nocd:
 
+
        push   ebx
   nocd:
+
        mov     eax, [pos]
    
+
        add     eax, 1
    push ebx
+
        cmp     eax, 10 * 20 + 1
     mov  eax,[pos]
+
        jb     .noeaxz
     add  eax,1
+
        mov     esi, text + 10 * 4
     cmp  eax,10*20+1
+
        mov     edi, text
    jb   noeaxz
+
        mov     ecx, 10 * 21 * 4
     mov  esi,text+10*4
+
        cld
     mov  edi,text
+
        rep     movsb
     mov  ecx,10*21*4
+
        mov     eax, 13
    cld
+
        mov     ebx, 20 * 65536 + 260
     rep  movsb
+
        mov     ecx, 22 * 65536 + 220
     mov  eax,13
+
        mov     edx, [wcolor]
     mov  ebx,20*65536+260
+
        mcall
     mov  ecx,22*65536+220
+
        mov     eax,10*19+1
     mov  edx,[wcolor]
+
 
    mcall
+
   .noeaxz:
     mov  eax,10*19+1
+
        mov     [pos],eax
   noeaxz:
+
        pop     ebx
     mov  [pos],eax
+
        and     ebx,0xff
     pop  ebx
+
 
     and  ebx,0xff
+
        call   draw_data
 
 
    call draw_data
 
 
 
    ret
 
  
 +
        ret
  
 
 
 
draw_data:
 
draw_data:
 
+
        pusha
    pusha
+
 
 
+
        xchg   eax, ebx
    xchg eax,ebx
+
 
 
+
        mov     ecx, 10
     mov  ecx,10
+
        shl     ebx, 2
     shl  ebx,2
+
        mov     esi, 3
     mov  esi,3
+
 
   newnum:
+
   .newnum:
     xor  edx,edx
+
        xor     edx, edx
     div  ecx
+
        div     ecx
     add  edx,48
+
        add     edx, 48
     mov  [ebx+text-1],dl
+
        mov     [ebx + text - 1], dl
     dec  ebx
+
        dec     ebx
     dec  esi
+
        dec     esi
     jnz  newnum
+
        jnz     .newnum
 
+
 
    call draw_text
+
        call   draw_text
 
+
 
    popa
+
        popa
 
 
    ret
 
  
+
        ret
  
 
draw_text:
 
draw_text:
 +
        pusha
 
    
 
    
     pusha
+
        mov     ebx, 25 * 65536 + 35   ; draw info text with function 4
 
+
        mov     ecx, 0xffffff
    mov  ebx,25*65536+35           ; draw info text with function 4
+
        mov     edx, text
     mov  ecx,0xffffff
+
        mov     esi, 40
     mov  edx,text
+
        mov     edi, 20
     mov  esi,40
+
 
     mov  edi,20
+
   .newline:
   newline:
+
        mov     eax,4
     mov  eax,4
+
        mcall
    mcall
+
        add     ebx,10
     add  ebx,10
+
        add     edx,40
     add  edx,40
+
        dec     edi
     dec  edi
+
        jne     .newline
     jne  newline
+
 
 
+
        popa
    popa
+
 
 
+
        ret
    ret
 
 
 
  
 
 
 
program_com_port:
 
program_com_port:
 
+
        ; the following sequence programs COM port for infrared receiver
    ; the following sequence programs COM port for infrared receiver
+
 
 
+
        mov     cx, 0x3f3 + 8
     mov  cx,0x3f3+8
+
        mov     bl, 0x80
     mov  bl,0x80
+
        mov     eax, 43
     mov  eax,43
+
        mcall
    mcall
+
 
 
+
        mov     cx, 0x3f1 + 8
     mov  cx,0x3f1+8
+
        mov     bl, 0
     mov  bl,0
+
        mov     eax, 43
     mov  eax,43
+
        mcall
    mcall
+
 
 
+
        mov     cx, 0x3f0 + 8
     mov  cx,0x3f0+8
+
        mov     bl, 0x30 / 4
     mov  bl,0x30 / 4
+
        mov     eax, 43
     mov  eax,43
+
        mcall
    mcall
+
 
 
+
        mov     cx, 0x3f3 + 8
     mov  cx,0x3f3+8
+
        mov     bl, 3
     mov  bl,3
+
        mov     eax, 43
     mov  eax,43
+
        mcall
    mcall
+
 
 
+
        mov     cx, 0x3f4 + 8
     mov  cx,0x3f4+8
+
        mov     bl, 0xB
     mov  bl,0xB
+
        mov     eax, 43
     mov  eax,43
+
        mcall
    mcall
+
 
 
+
        mov     cx, 0x3f1 + 8
     mov  cx,0x3f1+8
+
        mov     bl, 1
     mov  bl,1
+
        mov     eax, 43
     mov  eax,43
+
        mcall
    mcall
+
 
 
+
        mov     eax, 5
     mov  eax,5
+
        mov     ebx, 100
     mov  ebx,100
+
        mcall
    mcall
+
   
 
+
        mov     cx, 0x3f8
     mov  cx,0x3f8
+
        mov     bl, 'I'
     mov  bl,'I'
+
        mov     eax, 43
     mov  eax,43
+
        mcall
    mcall
+
 
 
+
        mov     eax, 5
     mov  eax,5
+
        mov     ebx, 10
     mov  ebx,10
+
        mcall
    mcall
+
 
 
+
        mov     cx, 0x3f8
     mov  cx,0x3f8
+
        mov     bl, 'R'
     mov  bl,'R'
+
        mov     eax, 43
     mov  eax,43
+
        mcall
    mcall
+
 
 
+
        ret
    ret
+
 
 
+
;*********************************************
 
+
;*******  WINDOW DEFINITIONS AND DRAW ********
 +
;*********************************************
  
 
 
 
 
;  *********************************************
 
;  *******  WINDOW DEFINITIONS AND DRAW ********
 
;  *********************************************
 
 
 
 
 
 
draw_window:
 
draw_window:
 +
        mov    eax, 12                ; function 12:tell os about windowdraw
 +
        mov    ebx, 1                ; 1, start of draw
 +
        mcall
 
    
 
    
     mov  eax,12                    ; function 12:tell os about windowdraw
+
        ; DRAW WINDOW
     mov  ebx,1                    ; 1, start of draw
+
        mov     eax, 0                ; function 0 : define and draw window
     mcall
+
        mov     ebx, 100 * 65536 + 300 ; [x start] *65536 + [x size]
 +
        mov    ecx, 100 * 65536 + 250 ; [y start] *65536 + [y size]
 +
        mov    edx, [wcolor]          ; color of work area RRGGBB,8->color
 +
        mov    esi, 0x8099bbff        ; color of grab bar  RRGGBB,8->color glide
 +
        mov     edi, 0x00ffffff        ; color of frames    RRGGBB
 +
        mcall
 
    
 
    
                                  ; DRAW WINDOW
+
        ; WINDOW LABEL
     mov  eax,0                    ; function 0 : define and draw window
+
        mov     eax, 4                ; function 4 : write text to window
     mov  ebx,100*65536+300        ; [x start] *65536 + [x size]
+
        mov     ebx, 8 * 65536 + 8    ; [x start] *65536 + [y start]
    mov  ecx,100*65536+250        ; [y start] *65536 + [y size]
+
        mov     ecx, 0x00ffffff        ; color of text RRGGBB
     mov  edx,[wcolor]              ; color of work area RRGGBB,8->color
+
        mov     edx, labelt           ; pointer to text beginning
     mov  esi,0x8099bbff           ; color of grab bar  RRGGBB,8->color glide
+
        mov     esi, labellen - labelt ; text length
     mov  edi,0x00ffffff            ; color of frames    RRGGBB
+
        mcall
    mcall
 
 
    
 
    
                                  ; WINDOW LABEL
+
        ; CLOSE BUTTON
     mov  eax,4                    ; function 4 : write text to window
+
        mov     eax, 8                ; function 8 : define and draw button
     mov  ebx,8*65536+8            ; [x start] *65536 + [y start]
+
        mov     ebx, (300 - 19) * 65536 + 12 ; [x start] *65536 + [x size]
     mov  ecx,0x00ffffff            ; color of text RRGGBB
+
        mov     ecx, 5 * 65536 + 12    ; [y start] *65536 + [y size]
     mov  edx,labelt                ; pointer to text beginning
+
        mov     edx, 1                ; button id
     mov  esi,labellen-labelt      ; text length
+
        mov     esi, 0x5599cc          ; button color RRGGBB
    mcall
+
        mcall
 
    
 
    
                                  ; CLOSE BUTTON
+
        call    draw_text
    mov  eax,8                    ; function 8 : define and draw button
 
    mov  ebx,(300-19)*65536+12    ; [x start] *65536 + [x size]
 
    mov  ecx,5*65536+12            ; [y start] *65536 + [y size]
 
    mov  edx,1                    ; button id
 
    mov  esi,0x5599cc              ; button color RRGGBB
 
    mcall
 
 
    
 
    
     call draw_text
+
        mov     eax, 12
 
+
        mov     ebx, 2
    mov  eax,12
+
        mcall
     mov  ebx,2
 
    mcall
 
 
 
    ret
 
 
    
 
    
 +
        ret
  
 +
; DATA AREA
  
 
 
; DATA AREA
 
 
 
 
wcolor  dd  0x0
 
wcolor  dd  0x0
 
pos      dd  0x0
 
pos      dd  0x0
 
+
 
 
cdplayer db  'CDPLAY    '
 
cdplayer db  'CDPLAY    '
 
labelt  db  'INFRARED RECEIVER FOR IRMAN IN COM 1'
 
labelt  db  'INFRARED RECEIVER FOR IRMAN IN COM 1'
 
labellen:
 
labellen:
 
+
 
 
text:
 
text:
 
+
 
 
I_END:
 
I_END:
 
+
</syntaxhighlight>
</asm>
 
  
 
[[Category:Coding]]
 
[[Category:Coding]]

Revision as of 18:57, 15 December 2011

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. 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.

Flow chart and structure of an application with default events:

;;;;;;;;;;;;;;;;;;;;;;;;;
;                       ;
;     HEADER DATA       ;
;                       ;
;;;;;;::;;;;;;;;;;;;;;;;;

START:
        call    draw_window

;;;;;;;;;;;;;;;;;;;;;;;;;
;                       ;
;   WAIT UNTIL EVENT    ;  <-----------------------------------------------I
;                       ;                                                  I
;;;;;;;;;;;;;;;;;;;;;;;;;                                                  I
;                                                                          I
;;;;;;;;;;;;;;;;;;;;;;;;;                                                  I
;                       ;     redraw   ->  call draw_window             -> I
;    READ EVENT TYPE    ; ->  key      ->  read keypress    -> process  -> I
;                       ;     button   ->  read buttonpress -> process  -> I
;;;;;;;;;;;;;;;;;;;;;;;;;

draw_window:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                            ;
;  DRAW STATIC WINDOW PARTS  ;
;                            ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        ret

;;;;;;;;;;;;;;;;;;;;;;;;
;                      ;
;     STATIC DATA      ;
;                      ;
;;;;;;;;;;;;;;;;;;;;;;;;

The header

db 'MENUET01'

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.

dd 0x01 ; header version

Speaks for itself.

dd START ; start of execution

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

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.

dd 0x100000

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.

dd 0x100000 ; stack position in memory area

Where the end of stack is (the value of esp at start of program). Logically, this would be the same as the previous value.

dd 0x0 ; Parameters

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.

dd 0x0 ; Path

Path value, works the same as parameter.

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.< If you understand russian, you can also find system calls on this wiki.

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.

        mov     eax, 5
        mov     ebx, 10

Now, we need to execute the function, this can be done with int 0x40:

        int     0x40

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:

        mcall   5, 10

Coding Style

It's adviseable to use the coding style, as descibed here: Style

Assembly examples

Simple example

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                  ;
;      EXAMPLE APPLICATION                         ;
;                                                  ;
;      Compile with FASM                           ;
;                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; The header

use32                                   ; Tell compiler to use 32 bit instructions

org 0x0                                 ; the base address of code, always 0x0

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

; The code area

include 'macros.inc'

START:                                  ; start of execution
        call    draw_window             ; draw the window

; After the window is drawn, it's practical to have the main loop.
; Events are distributed from here.

event_wait:
        mov     eax, 10                 ; function 10 : wait until event
        mcall                           ; event type is returned in eax

        cmp     eax, 1                  ; Event redraw request ?
        je      red                     ; Expl.: there has been activity on screen and
                                        ; parts of the applications has to be redrawn.

        cmp     eax, 2                  ; Event key in buffer ?
        je      key                     ; Expl.: User has pressed a key while the
                                        ; app is at the top of the window stack.

        cmp     eax, 3                  ; Event button in buffer ?
        je      button                  ; Expl.: User has pressed one of the
                                        ; applications buttons.

        jmp     event_wait

;  The next section reads the event and processes data.

red:                                    ; Redraw event handler
        call    draw_window             ; We call the window_draw function and
        jmp     event_wait              ; jump back to event_wait

key:                                    ; Keypress event handler
        mov     eax, 2                  ; The key is returned in ah. The key must be
        mcall                           ; read and cleared from the system queue.
        jmp     event_wait              ; Just read the key, ignore it and jump to event_wait.

button:                                 ; Buttonpress event handler
        mov     eax,17                  ; The button number defined in window_draw
        mcall                           ; is returned to ah.
   
        cmp     ah,1                    ; button id=1 ?
        jne     noclose
        mov     eax,-1                  ; Function -1 : close this program
        mcall

noclose:
        jmp     event_wait              ; This is for ignored events, useful at development

;  *********************************************
;  ******  WINDOW DEFINITIONS AND DRAW  ********
;  *********************************************
;
;  The static window parts are drawn in this function. The window canvas can
;  be accessed later from any parts of this code (thread) for displaying
;  processes or recorded data, for example.
;
;  The static parts *must* be placed within the fn 12 , ebx = 1 and ebx = 2.

draw_window:
        mov     eax, 12                 ; function 12: tell os about windowdraw
        mov     ebx, 1                  ; 1, start of draw
        mcall

        mov     eax, 0                  ; function 0 : define and draw window
        mov     ebx, 100 * 65536 + 300  ; [x start] *65536 + [x size]
        mov     ecx, 100 * 65536 + 120  ; [y start] *65536 + [y size]
        mov     edx, 0x14ffffff         ; color of work area RRGGBB
                                        ; 0x02000000 = window type 4 (fixed size, skinned window)
        mov     esi, 0x808899ff         ; color of grab bar  RRGGBB
                                        ; 0x80000000 = color glide
        mov     edi, title
        mcall

        mov     ebx, 25 * 65536 + 35    ; draw info text with function 4
        mov     ecx, 0x224466
        mov     edx, text
        mov     esi, 40
        mov     eax, 4

  .newline:                             ; text from the DATA AREA
        mcall
        add     ebx, 10
        add     edx, 40
        cmp     byte[edx], 0
        jne     .newline

        mov     eax, 12                 ; function 12:tell os about windowdraw
        mov     ebx, 2                  ; 2, end of draw
        mcall

        ret

;  *********************************************
;  *************   DATA AREA   *****************
;  *********************************************
;
; Data can be freely mixed with code to any parts of the image.
; Only the header information is required at the beginning of the image.

text    db  "It look's like you have just compiled   "
        db  "your first program for KolibriOS.       "
        db  "                                        "
        db  "Congratulations!                        ", 0

title   db  "Example application", 0

I_END:

; The area after I_END is free for use as the application memory, 
; just avoid the stack.
;
; Application memory structure, according to the used header, 1 Mb.
;
; 0x00000   - Start of compiled image
; I_END     - End of compiled image           
;
;           + Free for use in the application
;
; 0x7ff00   - Start of stack area
; 0x7fff0   - End of stack area                 - defined in the header
;
;           + Free for use in the application
;
; 0xFFFFF   - End of freely useable memory      - defined in the header
;
; All of the the areas can be modified within the application with a
; direct reference.
; For example, mov [0x80000],byte 1 moves a byte above the stack area.

It should look like this (perhaps with other skin):

Example 1.png

KolibriOS's application structure is not specifically reserved for asm programming, the header can be produced with practically any other language. However, the overall application programming design is intended for easy 32 bit asm programming. The GUI is extremely easy to handle with especially asm language.

Using uniform system colours

While previous example concentrated on creating a basic application, in this section more attention is paid on the outlook of the window.

You can use uniform desktop colors defined by a colour setup application.

New fuction in this example is get_system_colours.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                  ;
;      UNIFORM SYSTEM COLOURS EXAMPLE              ;
;                                                  ;
;      Compile with FASM                           ;
;                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; The header

use32

org 0x0

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

; The code area

window_size_X equ 300
window_size_Y equ 150

include 'macros.inc'

START:                          ; start of execution
        call    draw_window     ; draw the window

; After the window is drawn, it's practical to have the main loop.
; Events are distributed from here.

event_wait:
        mcall   10              ; function 10 : wait until event
                                ; event type is returned in eax

; How the 'dec' instruction in the following code works:
;
; example: If a window redraw is needed, eax will be 1
; So if we decrement eax, eax will become 0
; 'dec' instruction will set Zero-Flag because eax is now zero
; So now we can use jz (jump if zero flag is set) to detect this..
;
; If eax is 2, it will take 2 time 'dec  eax' before zero flag will be set..

        dec     eax             ; Event redraw request ?
        jz      red             ; Expl.: there has been activity on screen and
                                ; parts of the applications has to be redrawn.

        dec     eax             ; Event key in buffer ?
        jz      key             ; Expl.: User has pressed a key while the
                                ; app is at the top of the window stack.

        dec     eax             ; Event button in buffer ?
        jz      button          ; Expl.: User has pressed one of the
                                ; applications buttons.

        jmp     event_wait

;  The next section reads the event and processes data.

red:                            ; Redraw event handler
        call    draw_window     ; We call the window_draw function and
        jmp     event_wait      ; jump back to event_wait

key:                            ; Keypress event handler
        mcall   2               ; The key is returned in ah. The key must be read and cleared from the system queue.
        jmp     event_wait      ; Just read the key, ignore it and jump to event_wait.

button:                         ; Buttonpress event handler
        mcall   17              ; The button number defined in window_draw  is returned to ah.

        cmp     ah, 1           ; button id=1 ?
        jne     event_wait      ; if not, go back and wait for other events

        mcall   -1              ; Function -1 : close this program

get_system_colours:
        pusha

        mov     eax, 48                 ; fn 48 system colours
        mov     ebx, 3                  ; subfn 3 : get
        mov     ecx, app_colours        ; pointer to return area
        mov     edx, 10 * 4             ; number of bytes to return
        mcall

        popa

        ret

;*********************************************
;******  WINDOW DEFINITIONS AND DRAW  ********
;*********************************************
;
;  The static window parts are drawn in this function. The window canvas can
;  be accessed later from any parts of this code (thread) for displaying
;  processed or recorded data, for example.
;
;  The static parts *must* be placed within the fn 12 , ebx = 1 and ebx = 2.
;
;
;  When using system colours, the window colours are read from the
;  SYSTEM COLOURS TABLE

draw_window:
        mcall   12, 1                           ; Tell OS about start of redraw

        call    get_system_colours              ; fetches system colours from os

        mov     eax, 0                          ; function 0 : define and draw window

        mov     ebx, 100 * 65536 + window_size_X ; [x start] *65536 + [x size]
        mov     ecx, 100 * 65536 + window_size_Y ; [y start] *65536 + [y size]

        mov     edx, [w_work]                   ; color of work area 0xRRGGBB
        or      edx, 0x14000000                 ; 0x14000000 = window type 4, with title
        mov     esi, [w_grab]                   ; color of grab bar 0xRRGGBB
        or      esi, 0x80000000                 ; 0x80000000 = colour glide
        mov     edi, title
        mcall

        mov     ebx, 25 * 65536 + 35            ; draw info text with function 4
        mov     ecx, [w_work_text]
        mov     edx, text                       ; text from the DATA AREA
        mov     esi, 40

        mov     eax, 4

  .newline:
        mcall
        add     ebx, 10
        add     edx, 40
        cmp     byte [edx], 0
        jne     .newline

        mcall   12, 2 ; end of redraw

        ret

;  *********************************************
;  *************   DATA AREA   *****************
;  *********************************************
;
; Data can be freely mixed with code to any parts of the image.
; Only the header information is required at the beginning of the image.

text    db  'THIS PROGRAM USES UNIFORM SYSTEM COLOURS'
        db  'RETURNED TO A TABLE                     ', 0

title   db  'EXAMPLE APPLICATION', 0

I_END:

app_colours:                            ; SYSTEM COLOURS TABLE
  w_frames           dd ?               ; - frames
  w_grab             dd ?               ; - GRAB AREA
  w_grab_button      dd ?               ;   grab area button
  w_grab_button_text dd ?               ;   grab area button text
  w_grab_text        dd ?               ;   grab area text
  w_work             dd ?               ; - WORK AREA
  w_work_button      dd ?               ;   work area button
  w_work_button_text dd ?               ;   work area button text
  w_work_text        dd ?               ;   work area text
  w_work_graph       dd ?               ;   work area graphics

Freeform window

In this example we concentrate on shaping the window from rectangle to any form desired by the programmer. New fuction in this example is shape_window.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                  ;
;      FREEFORM EXAMPLE APPLICATION                ;
;                                                  ;
;      Compile with FASM                           ;
;                                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; The header

use32

org 0x0

db 'MENUET01'
dd 1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0

include 'macros.inc'

START:                          ; start of execution
        call    shape_window    ; function for shaping
        call    draw_window     ; at first, draw the window

still:
        mcall   10              ; wait here for event

        dec     eax             ; redraw request ?
        jz      red

        dec     eax             ; key in buffer ?
        je      key

        dec     eax             ; button in buffer ?
        je      button

        jmp     still

red:                            ; redraw
        call    draw_window
        jmp     still
   
key:                            ; key
        mcall   2               ; just read it and ignore
        jmp     still
   
button:                         ; button
        mcall   17              ; get id
   
        cmp     ah, 1           ; button id=1 ?
        jne     noclose

        mcall   -1              ; close this program

noclose:
        jmp     still

shape_window:
        pusha

; give the shape reference area

        mcall   50, 0, shape_reference

; give the shape scale  32 x 32  ->  128 x 128
; you dont have to give this, scale is 1:1 by default   
; scale is set to 2^ecx

        mcall   50, 1, 2

        popa
        ret

shape_reference: ; 32 x 32, ( window_size_X + 1 ) * ( window_size_Y + 1 )
  db 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
  db 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
  db 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
  db 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
  db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
  db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
  db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
  db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
  db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
  db 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0
  db 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0
  db 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0
  db 0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
  db 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
  db 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0

;*********************************************
;*******  WINDOW DEFINITIONS AND DRAW ********
;*********************************************

draw_window:
        mcall   12, 1                   ; notice os about start of redraw

        mov     eax, 0                  ; function 0: define and draw window
        mov     ebx, 100 * 65536        ; [x start] * 65536 + [x size]
        mov     ecx, 100 * 65536        ; [y start] * 65536 + [y size]
        mov     bx , [x_size]
        mov     cx , [y_size]
        mov     edx, 0x00cccc00         ; color of work area RRGGBB,8->color glide
        mov     esi, 0x00cccc00         ; color of grab bar  RRGGBB,8->color glide
        mov     edi, 0x00cccc00         ; color of frames    RRGGBB
        mcall

        mov     eax, 8                  ; function 8: define and draw button
        mov     ebx, 78 * 65536 + 12    ; [x start] * 65536 + [x size]
        mov     ecx, 20 * 65536 + 12    ; [y start] * 65536 + [y size]
        mov     edx, 1                  ; button id
        mov     esi, 0x5599cc           ; button color RRGGBB
        mcall

        mcall   12, 2                   ; end of redraw

        ret

; DATA

x_size dw 127
y_size dw 127

I_END:

Threads

KolibriOS assembly threading has some great advantages over higher level languages. If you keep all the variables in registers, you can start as meny threads as desired with the _same_ code, since no memory is affected and needs no saving. The registers are saved to Task Switch Segments by KolibriOS. All you have to do is to set a new stack.

Threads have no difference with the main process and use the same memory area as the process which starts it. They can have their own independent windows etc. In the closing of application, all threads have to be terminated with the default (eax = -1) system call.

New function in this example is create_thread.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                      ;
;   THREAD EXAMPLE                                     ;
;                                                      ;
;   Compile with FASM for Menuet                       ;
;                                                      ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

use32

org 0x0

db 'MENUET01' ; 8 byte id for application
dd 1, START, I_END, 0x100000, 0x80000, 0x0, 0x0

include 'macros.inc'   

START:                                    ; start of execution
        call    draw_window               ; at first, draw the window
   
event_wait:
        mov     eax, 10                   ; wait here for event
        mcall

        cmp     eax, 1                    ; redraw request ?
        je      red
        cmp     eax, 2                    ; key in buffer ?
        je      key
        cmp     eax, 3                    ; button in buffer ?
        je      button

        jmp     event_wait

red:                                      ; redraw
        call    draw_window
        jmp     event_wait

key:                                      ; key
        mov     eax, 2                    ; just read it and ignore
        mcall
        jmp     event_wait

button:                                   ; button
        mov     eax, 17                   ; get id
        mcall

        cmp     ah, 1                     ; button id=1 ?
        jne     noclose
        mov     eax, -1                   ; close this program (thread)
        mcall

noclose:
        cmp     ah, 2                     ; call create_thread
        jne     no_thread
        call    create_thread
        jmp     event_wait

no_thread:
        jmp     event_wait

; THREAD CREATION
;
; All we have to do is to give the thread entry address in ecx and
; a new stack postition in edx with function eax=51, ebx=1

create_thread:
        cmp     [thread_stack], 0xf0000
        jge     no_new_thread
   
        add     [thread_stack], 0x1000
   
        mov     eax, 51                   ; thread_create system call
        mov     ebx, 1
        mov     ecx, START
        mov     edx, [thread_stack]
        mcall

no_new_thread:
        ret

thread_stack dd 0x80000

;*********************************************
;*******  WINDOW DEFINITIONS AND DRAW ********
;*********************************************

draw_window:
        mov     eax, 12                   ; function 12: tell os about windowdraw
        mov     ebx, 1                    ; 1, start of draw
        mcall

        mov     eax, 0                    ; function 0: define and draw window
        mov     ebx, 10 * 65536 + 300     ; [x start] * 65536 + [x size]
        mov     ecx, 10 * 65536 + 140     ; [y start] * 65536 + [y size]
        mov     esi, [thread_stack]
        sub     esi, 0x80000
        shr     esi, 11
        shl     esi, 16
        add     ebx, esi
        add     ecx, esi
        mov     edx, 0x02ffffff           ; color of work area RRGGBB,8->color glide
        mov     esi, 0x808899ff           ; color of grab bar  RRGGBB,8->color glide
        mov     edi, 0x008899ff           ; color of frames    RRGGBB
        mcall

        ; WINDOW LABEL
        mov     eax, 4                    ; function 4: write text to window
        mov     ebx, 8 * 65536 + 8        ; [x start] * 65536 + [y start]
        mov     ecx, 0x00ddeeff           ; color of text RRGGBB
        mov     edx, labelt               ; pointer to text beginning
        mov     esi, labellen-labelt      ; text length
        mcall

        ; CLOSE BUTTON
        mov     eax, 8                    ; function 8: define and draw button
        mov     ebx, (300 - 19) * 65536 + 12 ; [x start] * 65536 + [x size]
        mov     ecx, 5 * 65536 + 12       ; [y start] * 65536 + [y size]
        mov     edx, 1                    ; button id
        mov     esi, 0x6677cc             ; button color RRGGBB
        mcall

        ; NEW THREAD BUTTON
        mov     eax, 8
        mov     ebx, 25 * 65536 + 128
        mov     ecx, 88 * 65536 + 20
        mov     edx, 2
        mov     esi, 0x6677cc
        mcall

        mov     ebx, 25 * 65536 + 35      ; draw info text with function 4
        mov     ecx, 0x224466
        mov     edx, text
        mov     esi, 40

  .newline:
        mov     eax, 4
        mcall
        add     ebx, 10
        add     edx, 40
        cmp     byte[edx], 0
        jne     .newline

        mov     eax, 12                   ; function 12: tell os about windowdraw
        mov     ebx, 2                    ; 2, end of draw
        mcall

        ret

; DATA AREA

text:
    db 'THIS EXAMPLE CREATES THREADS BY RUNNING '
    db 'THE SAME CODE MULTIPLE TIMES. ALL WE    '
    db 'NEED IS A NEW STACK FOR EACH THREAD.    '
    db 'ALL THREADS SHARE THE SAME MEMORY.      '
    db '                                        '
    db '                                        '
    db '  CREATE NEW THREAD                     ', 0

labelt:
    db   'THREAD EXAMPLE'
labellen:

I_END:

Real-Time data

The following example focuses on Real-Time data fetching and processing. Application informs the OS for all the ports and datatypes to read at a specific IRQ.

Steps:

  1. reserve I/O port area
  2. reserve IRQ
  3. program IRQ
  4. program EVENT list for wanted IRQ
  5. runtime processing of the data
  6. back to default events - free IRQ from EVENT list
  7. free IRQ
  8. free port area
  9. terminate program

After IRQ's are programmed, the application has a new event for the main event loop, number (IRQ+16). When the application receives this event, the OS has recorded data ready for the application to process.

The table below shows the main structure of processing real time data. All the steps on the left of (A) are processed by the OS and the steps right from (A) are processed by the application.

IRQ           OWNER      =>  REC DATA  (A) SYS_EVENT => READ DATA => PROCESS
  
 0 TIMER       SYS
 1 KEYBOARD    SYS
 2             free      ->
 3 COM MOUSE   SYS/free  ?>
 4 COM MOUSE   SYS/free  ?>
 5 SOUND BL.   SYS
 6 FLOPPY      SYS
 7             free      ->
 8             free      ->
 9             free      ->
10             free      ->
11             free      ->
12 PS2 MOUSE   SYS/free  ?>
13 MATH PR.    SYS
14 IDE         SYS
15 IDE         SYS

An example of processing Real-Time data:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                ;
;    REAL-TIME DATA                              ;
;                                                ;
;    Compile with FASM for Menuet                ;
;                                                ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

use32

org 0x0

db 'MENUET01' ; 8 byte id for application
dd 1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0

include 'macros.inc'   

START:                                 ; start of execution
        call    draw_window            ; at first, draw the window
        call    program_real_time_data ; program the OS to receive real time data
        call    program_com_port       ; program the com port for specific device

event_wait:
        mov     eax, 10                ; wait here for event
        mcall

        cmp     eax, 1                 ; redraw request ?
        je      red
        cmp     eax, 2                 ; key in buffer ?
        je      key
        cmp     eax, 3                 ; button in buffer ?
        je      button

        cmp     eax, 16 + 4            ; RT: new event for wanted IRQ data (16+IRQ)
        je      read_rt

        jmp     event_wait

;  The next section reads the event and processes data.

read_rt:                               ; RT data
        mov     eax, 42                ; Function 42 returns recorded data for IRQ 4
        mov     ebx, 4                 ;
        mcall                          ; OS returns the recorded data.
                                       ; eax  number of bytes in buffer left
                                       ; bl   data
                                       ; ecx  0 = success, other = no data in buf.

        call    process_data
        jmp     event_wait

red:                                   ; redraw
        call    draw_window
        jmp     event_wait

key:                                   ; key
        mov     eax, 2                 ; just read it and ignore
        mcall
        jmp     event_wait

button:                                ; button
        mov     eax, 17                ; get id
        mcall

        cmp     ah, 1                  ; button id=1 ?
        jne     noclose
   
        call    free_real_time_data
   
        mov     eax, -1                ; close this program
        mcall

noclose:
        jmp     event_wait

program_real_time_data:
        ; Program the Real-Time data fetch
        ;
        ; 1) reserve I/O port area
        ; 2) reserve IRQ
        ; 3) program IRQ
        ; 4) program EVENT list for wanted IRQ

        pusha

        mov     eax, 46                ; reserve ports 0x3f0 - 0x3ff
        mov     ebx, 0
        mov     ecx, 0x3f0
        mov     edx, 0x3ff
        mcall

        mov     eax, 45                ; reserve irq 4
        mov     ebx, 0
        mov     ecx, 4
        mcall

        mov     eax, 44                ; set read ports for irq 4
        mov     ebx, irqtable
        mov     ecx, 4
        mcall

        mov     eax, 40                              ; get com 1 data with irq 4
        mov     ebx, 0000000000010000b shl 16 + 111b ; after this we have a new event (16+4)
        mcall

        popa
        ret

irqtable:
    dd  0x3f8+0x01000000 ; 3f8 =port to read  : 01 =read byte, 02 =read word

    dd  0x0              ; 0x0 = termintes read per IRQ event
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0
    dd  0x0

free_real_time_data:
        ; Free the used resources
        ;
        ; 1) get default events
        ; 2) free irq with function 45,1
        ; 3) free port area with function 46,1

        pusha

        mov     eax, 40                ; default events - disable irq 4 event
        mov     ebx, 111b
        mcall

        mov     eax, 45                ; free irq
        mov     ebx, 1
        mov     ecx, 4
        mcall

        mov     eax, 46                ; free ports 0x3f0-0x3ff
        mov     ebx, 1
        mov     ecx, 0x3f0
        mov     edx, 0x3ff
        mcall

        popa
        ret

; The following functions are for processing device specific data.

process_data:
        cmp     ebx, 80
        jne     .nocd

        mov     eax, 19
        mov     ebx, cdplayer
        mov     ecx, 0
        mcall

  .nocd:
        push    ebx
        mov     eax, [pos]
        add     eax, 1
        cmp     eax, 10 * 20 + 1
        jb      .noeaxz
        mov     esi, text + 10 * 4
        mov     edi, text
        mov     ecx, 10 * 21 * 4
        cld
        rep     movsb
        mov     eax, 13
        mov     ebx, 20 * 65536 + 260
        mov     ecx, 22 * 65536 + 220
        mov     edx, [wcolor]
        mcall
        mov     eax,10*19+1

  .noeaxz:
        mov     [pos],eax
        pop     ebx
        and     ebx,0xff

        call    draw_data

        ret

draw_data:
        pusha

        xchg    eax, ebx

        mov     ecx, 10
        shl     ebx, 2
        mov     esi, 3

  .newnum:
        xor     edx, edx
        div     ecx
        add     edx, 48
        mov     [ebx + text - 1], dl
        dec     ebx
        dec     esi
        jnz     .newnum

        call    draw_text

        popa

        ret

draw_text:
        pusha
   
        mov     ebx, 25 * 65536 + 35   ; draw info text with function 4
        mov     ecx, 0xffffff
        mov     edx, text
        mov     esi, 40
        mov     edi, 20

  .newline:
        mov     eax,4
        mcall
        add     ebx,10
        add     edx,40
        dec     edi
        jne     .newline

        popa

        ret

program_com_port:
        ; the following sequence programs COM port for infrared receiver

        mov     cx, 0x3f3 + 8
        mov     bl, 0x80
        mov     eax, 43
        mcall

        mov     cx, 0x3f1 + 8
        mov     bl, 0
        mov     eax, 43
        mcall

        mov     cx, 0x3f0 + 8
        mov     bl, 0x30 / 4
        mov     eax, 43
        mcall

        mov     cx, 0x3f3 + 8
        mov     bl, 3
        mov     eax, 43
        mcall

        mov     cx, 0x3f4 + 8
        mov     bl, 0xB
        mov     eax, 43
        mcall

        mov     cx, 0x3f1 + 8
        mov     bl, 1
        mov     eax, 43
        mcall

        mov     eax, 5
        mov     ebx, 100
        mcall
    
        mov     cx, 0x3f8
        mov     bl, 'I'
        mov     eax, 43
        mcall

        mov     eax, 5
        mov     ebx, 10
        mcall

        mov     cx, 0x3f8
        mov     bl, 'R'
        mov     eax, 43
        mcall

        ret

;*********************************************
;*******  WINDOW DEFINITIONS AND DRAW ********
;*********************************************

draw_window:
        mov     eax, 12                ; function 12:tell os about windowdraw
        mov     ebx, 1                 ; 1, start of draw
        mcall
   
        ; DRAW WINDOW
        mov     eax, 0                 ; function 0 : define and draw window
        mov     ebx, 100 * 65536 + 300 ; [x start] *65536 + [x size]
        mov     ecx, 100 * 65536 + 250 ; [y start] *65536 + [y size]
        mov     edx, [wcolor]          ; color of work area RRGGBB,8->color
        mov     esi, 0x8099bbff        ; color of grab bar  RRGGBB,8->color glide
        mov     edi, 0x00ffffff        ; color of frames    RRGGBB
        mcall
   
        ; WINDOW LABEL
        mov     eax, 4                 ; function 4 : write text to window
        mov     ebx, 8 * 65536 + 8     ; [x start] *65536 + [y start]
        mov     ecx, 0x00ffffff        ; color of text RRGGBB
        mov     edx, labelt            ; pointer to text beginning
        mov     esi, labellen - labelt ; text length
        mcall
   
        ; CLOSE BUTTON
        mov     eax, 8                 ; function 8 : define and draw button
        mov     ebx, (300 - 19) * 65536 + 12 ; [x start] *65536 + [x size]
        mov     ecx, 5 * 65536 + 12    ; [y start] *65536 + [y size]
        mov     edx, 1                 ; button id
        mov     esi, 0x5599cc          ; button color RRGGBB
        mcall
   
        call    draw_text
   
        mov     eax, 12
        mov     ebx, 2
        mcall
   
        ret

; DATA AREA

wcolor   dd  0x0
pos      dd  0x0

cdplayer db  'CDPLAY     '
labelt   db  'INFRARED RECEIVER FOR IRMAN IN COM 1'
labellen:

text:

I_END: