Writing applications for KolibriOS: Difference between revisions

From KolibriOS wiki
Jump to navigation Jump to search
(New page: = Writing applications for KolibriOS = == Structure of an application == Programming for KolibriOS is easy as you first learn the basic structure of an application. At this p...)
 
No edit summary
Line 299: Line 299:
window_size_X  equ  300
window_size_X  equ  300
window_size_Y  equ  150
window_size_Y  equ  150
        include 'macros.inc'
    
    
    
    
Line 695: Line 698:
    
    
    
    
 
 
        include 'macros.inc' 
    
    
START:                          ; start of execution
START:                          ; start of execution
Line 826: Line 830:
     add  ebx,10
     add  ebx,10
     add  edx,40
     add  edx,40
     cmp  [edx],byte 'x'
     cmp  byte [edx], 0
     jne  newline
     jne  newline
    
    
Line 846: Line 850:
     db '                                        '
     db '                                        '
     db '                                        '
     db '                                        '
     db '  CREATE NEW THREAD                    '
     db '  CREATE NEW THREAD                    ', 0
 
    db 'x <- END MARKER, DONT DELETE            '
    
    
    
    
Line 930: Line 932:
use32
use32
    
    
              org    0x0
        org    0x0


              db    'MENUET01'  ; 8 byte id for application
        db    'MENUET01'  ; 8 byte id for application
              dd    1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0
        dd    1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0
 
    
    
        include 'macros.inc' 
    
    
START:                          ; start of execution
START:                          ; start of execution

Revision as of 16:58, 27 December 2009

Writing applications for KolibriOS

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:

<asm>

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

START:

 call draw_window
  
 ;;;;;;;;;;;;;;;;::;;;;;;;
 ;                       ;
 ;   WAIT UNTIL EVENT    ;  <-----------------------------------------------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
  
  

DATA AREA:

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

</asm>


Assembly example

A heavily commented assembly language realization of the above structure.

KolibriOS system calls can be executed with the 'int 0x40' command, altough it is better to use the mcall macro. The function number should be in eax register and other registers are used if necessary. Details of all currently available system calls are at the section (1g) System functions.

<asm>

;
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'      ; 8 byte id for application
       dd      0x01            ; header version
       dd      START           ; start of execution
       dd      I_END           ; size of image
       dd      0x100000        ; Amount of memory to use
                               ; You can access memory from 0x0 to
                               ; value defined here. The relocation
                               ; of code is done with selectors
                               ; set by the OS.
       dd      0x7fff0         ; stack position in memory area
       dd      0x0             ; Parameter passing value
                               ; if set to other than zero, possible
                               ; parameters are transferred at start.
       dd      0x0             ; Path passing value, works same as parameter passing
  
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
                                       ; 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+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.

</asm>

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.

<asm>

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

use32  ; compiler to use 32 bit instructions

              org    0x0             ; the base address of code, always 0x0
  
              db     'MENUET01'      ; 8 byte id for application
              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:


   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
  
  

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
  
  

app_colours:  ; SYSTEM COLOURS TABLE

w_frames dd 0x0  ; - frames w_grab dd 0x0  ; - GRAB AREA w_grab_button dd 0x0  ; grab area button w_grab_button_text dd 0x0  ; grab area button text w_grab_text dd 0x0  ; grab area text w_work dd 0x0  ; - WORK AREA w_work_button dd 0x0  ; work area button w_work_button_text dd 0x0  ; work area button text w_work_text dd 0x0  ; work area text w_work_graph dd 0x0  ; work area graphics


*********************************************
****** 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:


   mov  eax,12                    ; function 12:tell os about windowdraw
   mov  ebx,1                     ; 1, start of draw
   mcall
  
   call get_system_colours        ; fetches system colours from os
  
                                  ; DRAW WINDOW
   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,0x02000000            ; 0x02000000 = window type II
                                  ; 0x03000000 = skinned window
   mov  esi,[w_grab]              ; color of grab bar 0xRRGGBB
   or   esi,0x80000000            ; 0x80000000 = colour glide
   mov  edi,[w_frames]            ; color of frames 0xRRGGBB
   mcall
                                  ; WINDOW LABEL
   mov  eax,4                     ; function 4 : write text to window
   mov  ebx,8*65536+8             ; [x start] *65536 + [y start]
   mov  ecx,[w_grab_text]         ; color of text RRGGBB
   mov  edx,labelt                ; pointer to text beginning
   mov  esi,labellen-labelt       ; text length
   mcall
  
   mov  ebx,25*65536+35           ; draw info text with function 4
   mov  ecx,[w_work_text]
   mov  edx,text
   mov  esi,40
  newline:                         ; text from the DATA AREA
   mov  eax,4
   mcall
   add  ebx,10
   add  edx,40
   cmp  [edx],byte 'x'
   jne  newline
  
                                  ; CLOSE BUTTON
   mov  eax,8                     ; function 8 : define and draw button
   mov  ebx,window_size_X
   sub  ebx,19
   shl  ebx,16
   mov  bx,12                     ; ebx = [x start] *65536 + [x size]
   mov  ecx,5*65536+12            ; [y start] *65536 + [y size]
   mov  edx,1                     ; button id
   mov  esi,[w_grab_button]       ; button color RRGGBB
   mcall
  
   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 'THIS PROGRAM USES UNIFORM SYSTEM COLOURS'

           db  'RETURNED TO A TABLE                     '
  
           db  'x <- END MARKER, DONT DELETE            '
  
  

labelt: db 'EXAMPLE APPLICATION' labellen:

I_END:

</asm>


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.

<asm>

;
FREEFORM EXAMPLE APPLICATION  ;
;
Compile with FASM  ;
;
The header

use32  ; compiler to use 32 bit instructions

              org    0x0          ; the base address of code, always 0x0
  
              db     'MENUET01'   ; 8 byte id for application
              dd     1, START, I_END, 0x100000, 0x7fff0, 0x0, 0x0


START:  ; start of execution

   call shape_window           ; function for shaping
  
   call draw_window            ; at first, draw the window
  

still:

   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  still
  
 red:                          ; redraw
   call draw_window
   jmp  still
  
 key:                          ; key
   mov  eax,2                  ; just read it and ignore
   mcall
   jmp  still
  
 button:                       ; button
   mov  eax,17                 ; get id
   mcall
  
   cmp  ah,1                   ; button id=1 ?
   jne  noclose
   mov  eax,-1                 ; close this program
   mcall
 noclose:
  
   jmp  still
  
  

shape_window:

   pusha
  
   mov  eax,50       ; give the shape reference area
   mov  ebx,0
   mov  ecx,shape_reference
   mcall
  
   mov  eax,50       ; give the shape scale  32 x 32  ->  128 x 128
   mov  ebx,1        ; you dont have to give this, scale is 1:1 by default
   mov  ecx,2        ; scale is set to 2^ecx
   mcall
  
   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:

   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             ; [x start] *65536 + [x size]
   mov  ecx,100*65536             ; [y start] *65536 + [y size]
   mov  bx,word [x_size]
   mov  cx,word [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
  
  
                                  ; CLOSE BUTTON
   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
  
  
   mov  eax,12                    ; function 12:tell os about windowdraw
   mov  ebx,2                     ; 2, end of draw
   mcall
  
   ret
  
DATA

x_size dd 127 y_size dd 127

I_END:

</asm>


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.

<asm>

;
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
  
                                  ; DRAW WINDOW
   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
  
   mov  eax,8                     ; NEW THREAD BUTTON
   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:

</asm>


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:


<asm>

;
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:

</asm>