Writing applications for KolibriOS
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:
;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; 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 DATA AREA: ;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; STATIC DATA ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;
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):
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,0x14000000 ; 0x02000000 = window type II ; 0x03000000 = skinned window 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 mov esi,40 newline: ; text from the DATA AREA 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 *****************
- *********************************************
- 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:
</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
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 ; 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 , [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 ; 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 mcall 12, 2 ; end of redraw ret
- DATA
x_size dw 127 y_size dw 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>