Programming with MenuetOS
=========================
1) Application programming
1a) Structure of an application
1b) Assembly example
1c) Using uniform system colours
1d) Free form window
1e) Threads
1f) Real-Time data
1) APPLICATION PROGRAMMING FOR MENUET-OS
========================================
1a) Structure of an application
===============================
Programming for Menuet 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 MenuetOS 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
;;;;;;;::;;;;;;;;;;;;;;;; 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 ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;
(end of image)
1b) Assembly example
====================
A heavily commented assembly language realization of the above structure (1a).
Menuet system calls are executed with the 'int 0x40' command with function
number in register eax and other registers are used if necessary.
Details of all currently available system calls are at the section (1g)
System functions.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; EXAMPLE APPLICATION ;
; ;
; Compile with FASM for Menuet ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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 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 ; Reserved for icon
; The code area
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
int 0x40
; 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
int 0x40 ; 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
int 0x40 ; is returned to ah.
cmp ah,1 ; button id=1 ?
jne noclose
mov eax,-1 ; Function -1 : close this program
int 0x40
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
int 0x40
; 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,0x02ffffff ; color of work area RRGGBB
; 0x02000000 = window type 2
mov esi,0x808899ff ; color of grab bar RRGGBB
; 0x80000000 = color glide
mov edi,0x008899ff ; color of frames RRGGBB
int 0x40
; 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
int 0x40
; 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
int 0x40
mov ebx,25*65536+35 ; draw info text with function 4
mov ecx,0x224466
mov edx,text
mov esi,40
newline: ; text from the DATA AREA
mov eax,4
int 0x40
add ebx,10
add edx,40
cmp [edx],byte 'x'
jne newline
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,2 ; 2, end of draw
int 0x40
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 IS AN EXAMPLE PROGRAM YOU COULD '
db 'USE, A:\EXAMPLE.ASM CODE IS COMMENTED '
db 'AND CLEAR. SYSTEM FUNCTIONS ARE IN FILE '
db 'SYSFUNCS.TXT AND COMMANDS IN CMD.TXT '
db 'x <- END MARKER, DONT DELETE '
labelt: db 'EXAMPLE APPLICATION'
labellen:
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.
Menuet'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.
1c) 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 for Menuet ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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 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 relocatn of
; of the 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 ; Reserved for icon
; The code area
window_size_X equ 300
window_size_Y equ 150
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
int 0x40
; 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
int 0x40 ; 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
int 0x40 ; is returned to ah.
cmp ah,1 ; button id=1 ?
jne noclose
mov eax,-1 ; Function -1 : close this program
int 0x40
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
int 0x40
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
int 0x40
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
int 0x40
; 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
int 0x40
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
int 0x40
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
int 0x40
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,2 ; 2, end of draw
int 0x40
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:
1d) 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 for Menuet ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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 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 the code is done with selectors
; set by the OS.
dd 0x7fff0 ; stack position in memory area
dd 0x0 ; Parameter passing area
; if set to other than zero, poss
; parameters are transferred at start
dd 0x0 ; Reserved for icon
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
int 0x40
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
int 0x40
jmp still
button: ; button
mov eax,17 ; get id
int 0x40
cmp ah,1 ; button id=1 ?
jne noclose
mov eax,-1 ; close this program
int 0x40
noclose:
jmp still
shape_window:
pusha
mov eax,50 ; give the shape reference area
mov ebx,0
mov ecx,shape_reference
int 0x40
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
int 0x40
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
int 0x40
; 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
int 0x40
; 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
int 0x40
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,2 ; 2, end of draw
int 0x40
ret
; DATA
x_size dd 127
y_size dd 127
I_END:
1e) Threads
===========
MenuetOS 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 MenuetOS. 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
dd 0x01 ; header version
dd START ; start of code
dd I_END ; size of image
dd 0x100000 ; memory for app
dd 0x80000 ; esp
dd 0x0 , 0x0 ; I_Param , I_Icon
START: ; start of execution
call draw_window ; at first, draw the window
event_wait:
mov eax,10 ; wait here for event
int 0x40
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
int 0x40
jmp event_wait
button: ; button
mov eax,17 ; get id
int 0x40
cmp ah,1 ; button id=1 ?
jne noclose
mov eax,-1 ; close this program (thread)
int 0x40
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]
int 0x40
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
int 0x40
; 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
int 0x40
; 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
int 0x40
; 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
int 0x40
mov eax,8 ; NEW THREAD BUTTON
mov ebx,25*65536+128
mov ecx,88*65536+20
mov edx,2
mov esi,0x6677cc
int 0x40
mov ebx,25*65536+35 ; draw info text with function 4
mov ecx,0x224466
mov edx,text
mov esi,40
newline:
mov eax,4
int 0x40
add ebx,10
add edx,40
cmp [edx],byte 'x'
jne newline
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,2 ; 2, end of draw
int 0x40
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 '
db 'x <- END MARKER, DONT DELETE '
labelt:
db 'THREAD EXAMPLE'
labellen:
I_END:
1f) 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 'MENUET00' ; 8 byte id
dd 56 ; required os
dd START ; program start
dd I_END ; program image size
dd 0x100000 ; required amount of memory
; esp = 0x7FFF0
dd 0x00000000 ; reserved=no extended header
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
int 0x40
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 ;
int 0x40 ; 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
int 0x40
jmp event_wait
button: ; button
mov eax,17 ; get id
int 0x40
cmp ah,1 ; button id=1 ?
jne noclose
call free_real_time_data
mov eax,-1 ; close this program
int 0x40
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
int 0x40
mov eax,45 ; reserve irq 4
mov ebx,0
mov ecx,4
int 0x40
mov eax,44 ; set read ports for irq 4
mov ebx,irqtable
mov ecx,4
int 0x40
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)
int 0x40
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
int 0x40
mov eax,45 ; free irq
mov ebx,1
mov ecx,4
int 0x40
mov eax,46 ; free ports 0x3f0-0x3ff
mov ebx,1
mov ecx,0x3f0
mov edx,0x3ff
int 0x40
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
int 0x40
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]
int 0x40
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
int 0x40
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
int 0x40
mov cx,0x3f1+8
mov bl,0
mov eax,43
int 0x40
mov cx,0x3f0+8
mov bl,0x30 / 4
mov eax,43
int 0x40
mov cx,0x3f3+8
mov bl,3
mov eax,43
int 0x40
mov cx,0x3f4+8
mov bl,0xB
mov eax,43
int 0x40
mov cx,0x3f1+8
mov bl,1
mov eax,43
int 0x40
mov eax,5
mov ebx,100
int 0x40
mov cx,0x3f8
mov bl,'I'
mov eax,43
int 0x40
mov eax,5
mov ebx,10
int 0x40
mov cx,0x3f8
mov bl,'R'
mov eax,43
int 0x40
ret
; *********************************************
; ******* WINDOW DEFINITIONS AND DRAW ********
; *********************************************
draw_window:
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,1 ; 1, start of draw
int 0x40
; 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
int 0x40
; 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
int 0x40
; 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
int 0x40
call draw_text
mov eax,12
mov ebx,2
int 0x40
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:
eof
|