Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 30 → Rev 31

/programs/aclock/trunk/Readme.txt
0,0 → 1,85
AClock 1.1
Copyright (c) 2002,2003 Thomas Mathys
killer@vantage.ch
 
 
what the hell is this ?
-----------------------
 
this is aclock, a silly analog clock application
for menuetos (http://www.menuetos.org).
 
 
why do i need it ?
------------------
 
well, this is certainly one of the last programs on
earth you'd ever need. anyway, it demonstrates how
how to do certain things:
 
- writing menuet apps that parse the command line.
includes a strtok-like function that you might
want to use in own projects. or maybe rather not.
- writing menuet apps that are aware of the current
window size and that have no problems with different
skin heights.
- how to write menuet apps with nasm instead of fasm
(there should be a gas version aswell, don't you think ?)
and how to write kick-ass code with nasm in general =)
 
 
compiling instructions
----------------------
 
yes, it's still written for nasm.
i really can't be bothered to work with fasm.
 
oh yes, you wanted to know how to compile aclock:
 
nasm -t -f bin -o aclock aclock.asm
if you get error messages like
 
nasm: unrecognised option `-t
type `nasm -h' for help
 
then you've got an old version of nasm.
get a newer version (0.98.36 or later) from
http://nasm.sourceforge.net
 
 
configuration
-------------
 
you might want to change some of the constants defined
somewhere at the top of aclock.asm. the following might
be useful:
 
- DEFAULT_XPOS
- DEFAULT_YPOS
- DEFAULT_WIDTH
- DEFAULT_HEIGHT
- MIN_WIDTH
- MIN_HEIGHT
for more info about DEFAULT_XPOS/DEFAULT_YPOS see next
section.
 
 
usage
-----
 
this version of AClock introduces command line parameters.
here's an example command line:
 
aclock w128 h128 x20 y-20
this creates a window that is 128 pixels wide and 128 pixels
high (that's for the work area, without border/title bar).
the window is placed at x=20, y=screen resolution-20
(because of the minus sign after the y).
 
all parameters are optional and may appear in any order.
you can't have any whitespaces in a parameter, e.g.
"w 128" is an invalid parameter (which will simply be ignored).
the command line parser is case sensitive.
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/aclock.asm
0,0 → 1,223
; aclock 1.1
; Copyright (c) 2002 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
bits 32
%include 'mos.inc'
section .text
 
 
;********************************************************************
; configuration stuff
;********************************************************************
 
%define APPNAME "AClock 1.1"
%define STACKSIZE 1024
 
; default window position/dimensions (work area)
%define DEFAULT_XPOS -20
%define DEFAULT_YPOS 20
%define DEFAULT_WIDTH 80
%define DEFAULT_HEIGHT 80
 
; minimal size (horizontal and vertical) of work area
%define MIN_WIDTH 80
%define MIN_HEIGHT 80
 
 
;********************************************************************
; header
;********************************************************************
MOS_HEADER01 main,image_end,memory_end,stacktop-4,cmdLine,0
 
; these includes introduce code and thus mustn't stand
; before the menuet header =)
%include 'dbgboard.inc'
%include 'strlen.inc'
%include 'str2dwrd.inc'
%include 'strtok.inc'
%include 'cmdline.inc'
%include 'adjstwnd.inc'
%include 'draw.inc'
 
;********************************************************************
; main program
;********************************************************************
main:
call getDefaultWindowColors
call parseCommandLine
 
; check minimal window dimensions
cmp dword [wndWidth],MIN_WIDTH
jae .widthok
mov dword [wndWidth],MIN_WIDTH
.widthok:
cmp dword [wndHeight],MIN_HEIGHT
jae .heightok
mov dword [wndHeight],MIN_HEIGHT
.heightok:
 
; adjust window dimensions
mov eax,ADJSTWND_TYPE_SKINNED
mov ebx,[wndXPos]
mov ecx,[wndYPos]
mov edx,[wndWidth]
mov esi,[wndHeight]
call adjustWindowDimensions
mov [wndXPos],ebx
mov [wndYPos],ecx
mov [wndWidth],edx
mov [wndHeight],esi
 
call drawWindow
.msgpump:
call drawClock
 
; wait up to a second for next event
mov eax,MOS_SC_WAITEVENTTIMEOUT
mov ebx,100
int 0x40
 
cmp eax,MOS_EVT_REDRAW
je .redraw
cmp eax,MOS_EVT_KEY
je .key
cmp eax,MOS_EVT_BUTTON
je .button
jmp .msgpump
 
.redraw:
call drawWindow
jmp .msgpump
.key:
mov eax,MOS_SC_GETKEY
int 0x40
jmp .msgpump
.button:
mov eax,MOS_SC_EXIT
int 0x40
jmp .msgpump
 
 
;********************************************************************
; get default window colors
; input : nothing
; output : wndColors contains default colors
; destroys : nothing
;********************************************************************
getDefaultWindowColors:
pushad
pushfd
mov eax,MOS_SC_WINDOWPROPERTIES
mov ebx,3
mov ecx,wndColors
mov edx,MOS_WNDCOLORS_size
int 0x40
popfd
popad
ret
 
 
;********************************************************************
; define and draw window
; input nothing
; output nothing
; destroys flags
;********************************************************************
align 4
drawWindow:
pusha
 
; start window redraw
mov eax,MOS_SC_REDRAWSTATUS
mov ebx,1
int 0x40
 
; create window
mov eax,MOS_SC_DEFINEWINDOW
mov ebx,[wndXPos]
shl ebx,16
or ebx,[wndWidth]
mov ecx,[wndYPos]
shl ecx,16
or ecx,[wndHeight]
mov edx,[wndColors+MOS_WNDCOLORS.work]
or edx,0x03000000
mov esi,[wndColors+MOS_WNDCOLORS.grab]
mov edi,[wndColors+MOS_WNDCOLORS.frame]
int 0x40
 
; draw window label
mov eax,MOS_SC_WRITETEXT
mov ebx,MOS_DWORD(8,8)
mov ecx,[wndColors+MOS_WNDCOLORS.grabText]
mov edx,label
mov esi,LABEL_LEN
int 0x40
call drawClock
; end window redraw
mov eax,MOS_SC_REDRAWSTATUS
mov ebx,2
int 0x40
popa
ret
 
 
;********************************************************************
; initialized data
;********************************************************************
 
; window position and dimensions.
; dimensions are for work area only.
wndXPos dd DEFAULT_XPOS
wndYPos dd DEFAULT_YPOS
wndWidth dd DEFAULT_WIDTH
wndHeight dd DEFAULT_HEIGHT
 
; window label
label db APPNAME,0
LABEL_LEN equ ($-label-1)
 
; token delimiter list for command line
delimiters db 9,10,11,12,13,32,0
 
; don't insert anything after this label
image_end:
 
 
;********************************************************************
; uninitialized data
;********************************************************************
section .bss
 
wndColors resb MOS_WNDCOLORS_size
procInfo resb MOS_PROCESSINFO_size
 
; space for command line. at the end we have an additional
; byte for a terminating zero, just to be sure...
cmdLine resb 257
 
alignb 4
stack resb STACKSIZE
stacktop:
 
; don't insert anything after this label
memory_end:
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/aclock.bmp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/programs/aclock/trunk/adjstwnd.inc
0,0 → 1,147
; adjustWindowDimensions
; adjust menut window dimensions to get a certain work area size.
; or so. who on earth cares anyway, i certinaly don't, i'm just
; writing this code because i've got to kill time somehow...
;
; Copyright (c) 2002 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
%ifndef _ADJSTWND_INC
%define _ADJSTWND_INC
 
 
;window types
ADJSTWND_TYPE_SKINNED equ 0
 
 
;********************************************************************
; adjust window dimensions to get a certain work area size
;
; - first the window width and height are adjusted
; and clamped if they're too large for the screen.
; - then the window positions are adjusted, if the
; window goes out of the screen.
;
; input:
; eax window type, one of the ADJSTWND_TYPE_xxx constants
; ebx window x position
; ecx window y position
; edx desired work area width
; esi desired work area height
;
; output:
; eax return code. 0 = ok, -1 = invalid window type
; ebx adjusted window x position
; ecx adjusted window y position
; edx window width to get desired work area width
; esi window height to get desired work area height
;
; destroys:
; nothing
;
; normally x and y are the upper left corner of the window,
; relative to the upper left corner of the screen.
; if you pass a negative x or y it will be treated as the
; lower right corner of the window, relative to the lower
; right corner of the screen.
;********************************************************************
adjustWindowDimensions:
push edi
push ebp
pushfd
 
; adjust window dimensions, depending on the window type
cmp eax,ADJSTWND_TYPE_SKINNED
je .adjust_skinned
mov eax,-1 ; invalid window type,
jmp .bye ; return error code
 
; clamp window dimensions
.clamp:
mov eax,MOS_SC_GETSCREENMAX ; get screen dimensions
int 0x40
mov edi,eax ; edi = screen width
shr edi,16
mov ebp,eax ; ebp = screen height
and ebp,0xffff
cmp edx,edi ; window width > screen width ?
jna .widthok
mov edx,edi ; yes -> use screen width
.widthok:
cmp esi,ebp ; wnd height > screen height ?
jna .heightok
mov esi,ebp ; yes -> use screen height
.heightok:
 
; adjust x position
or ebx,ebx ; do the lower right corner
jns .foo ; stuff if x is negative.
add ebx,edi
sub ebx,edx
.foo:
or ebx,ebx ; x < 0 ?
jns .xnotnegative
xor ebx,ebx ; yes -> x = 0
.xnotnegative:
mov eax,ebx ; x + width > screen width ?
add eax,edx
cmp eax,edi
jna .xok
sub eax,edi ; yes -> adjust
sub ebx,eax
.xok:
 
; adjust y position
or ecx,ecx ; do the lower right corner
jns .bar ; stuff if y is negative.
add ecx,ebp
sub ecx,esi
.bar:
or ecx,ecx ; y < 0 ?
jns .ynotnegative
xor ecx,ecx ; yes -> y = 0
.ynotnegative:
mov eax,ecx ; y + height > screen height ?
add eax,esi
cmp eax,ebp
jna .yok
sub eax,ebp ; yes -> adjust
sub ecx,eax
.yok:
 
.done:
xor eax,eax
.bye:
popfd
pop ebp
pop edi
ret
 
.adjust_skinned:
; adjust width (edx)
add edx,MOS_WND_SKIN_BORDER_LEFT+MOS_WND_SKIN_BORDER_RIGHT
; adjust height (esi). we need the skin height to do this.
push ebx
mov eax,MOS_SC_WINDOWPROPERTIES
mov ebx,4
int 0x40
lea esi,[esi+eax+MOS_WND_SKIN_BORDER_BOTTOM]
pop ebx
jmp .clamp
 
%endif
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/cmdline.inc
0,0 → 1,151
; command line parsing code for aclock
;
; Copyright (c) 2003 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
%ifndef _CMDLINE_INC
%define _CMDLINE_INC
 
 
;********************************************************************
; parse the command line
; input : nothing
; output : wndXPos, wndYPos, wndWidth, wndHeight
; are changed.
; destroys : nothing
;********************************************************************
parseCommandLine:
pushad
pushfd
 
; terminate command line, just to be sure
mov byte [cmdLine + 256],0
 
; go through all tokens
mov eax,cmdLine ; eax -> command line
.parseloop:
mov ebx,delimiters ; ebx -> token delimiter list
call strtok ; get next parameter
or eax,eax ; no more parameters ?
jz .nomoretokens
mov cl,[eax] ; get 1st char of parameter
cmp cl,'x' ; which parameter is it ?
je .param_x
cmp cl,'y'
je .param_y
cmp cl,'w'
je .param_w
cmp cl,'h'
je .param_h
; if we reach this line it's an unknown parameter, ignore it
.nextparam:
xor eax,eax ; set eax = 0 to continue
jmp .parseloop ; after last token.
.nomoretokens:
DBG_BOARD_PRINTDWORD [wndXPos]
DBG_BOARD_PRINTCHAR 32
DBG_BOARD_PRINTDWORD [wndYPos]
DBG_BOARD_PRINTCHAR 32
DBG_BOARD_PRINTDWORD [wndWidth]
DBG_BOARD_PRINTCHAR 32
DBG_BOARD_PRINTDWORD [wndHeight]
DBG_BOARD_PRINTNEWLINE
popfd
popad
ret
 
; eax -> first character of the parameter
.param_x:
push eax
call parsePositionParam
mov [wndXPos],eax
pop eax
jmp .nextparam
 
; eax -> first character of the parameter
.param_y:
push eax
call parsePositionParam
mov [wndYPos],eax
pop eax
jmp .nextparam
 
; eax -> first character of the parameter
.param_w:
push eax
call parseSizeParam
mov [wndWidth],eax
pop eax
jmp .nextparam
 
; eax -> first character of the parameter
.param_h:
push eax
call parseSizeParam
mov [wndHeight],eax
pop eax
jmp .nextparam
 
; parse position parameter
; input : eax = address of first character of parameter
; output : eax contains position
; destroys : nothing
parsePositionParam:
push ebx
push esi
pushfd
 
; is the second char of the parameter a '-' ?
inc eax
xor ebx,ebx ; assume it isn't
cmp byte [eax],'-'
jne .nominus
mov ebx,1 ; yes -> set flag...
inc eax ; ...and move to next char
.nominus:
 
; convert rest of parameter to doubleword
mov esi,eax
call string2dword
 
; negate if necessary
or ebx,ebx
jz .rotationshyperboloid
neg eax
.rotationshyperboloid:
 
popfd
pop esi
pop ebx
ret
 
; parse dimension parameter
; input : eax = address of first char of parameter
; output : eax contains dimension
; destroys : nothing
parseSizeParam:
push esi
pushfd
lea esi,[eax + 1] ; esi -> 2nd char of parameter
call string2dword
popfd
pop esi
ret
 
 
%endif
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/dbgboard.inc
0,0 → 1,200
; macros to write stuff to menuet's debug message board.
; the macros don't change any registers, not even flags.
; they take only effect if DEBUG is defined.
;
; Copyright (c) 2003 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
%ifndef _DBGBOARD_INC
%define _DBGBOARD_INC
 
 
%ifdef DEBUG
 
 
;********************************************************************
; print newline
; no input
;********************************************************************
%macro DBG_BOARD_PRINTNEWLINE 0
call dbg_board_printnewline
%endm
 
 
;********************************************************************
; print a character
;
; examples : DBG_BOARD_PRINTCHAR '?'
; DBG_BOARD_PRINTCHAR 65
; DBG_BOARD_PRINTCHAR cl
; DBG_BOARD_PRINTCHAR [esi]
; DBG_BOARD_PRINTCHAR [somevariable]
;********************************************************************
%macro DBG_BOARD_PRINTCHAR 1
push ecx
mov cl,byte %1
call dbg_board_printchar
pop ecx
%endm
 
 
 
;********************************************************************
; print a dword (in hex)
;
; examples: DBG_BOARD_PRINTDWORD esp
; DBG_BOARD_PRINTDWORD 0xdeadbeef
; DBG_BOARD_PRINTDWORD [somevariable]
;********************************************************************
%macro DBG_BOARD_PRINTDWORD 1
push dword %1
call dbg_board_printdword
%endm
 
 
;********************************************************************
; print a string literal
; a terminating zero is automagically appended to the string.
;
; examples DBG_BOARD_PRINTSTRINGLITERAL "foo",0
; DBG_BOARD_PRINTSTRINGLITERAL "bar",10,13,0
;********************************************************************
%macro DBG_BOARD_PRINTSTRINGLITERAL 1+
jmp %%bar
%%foo db %1, 0 ; terminate string, just to be sure
%%bar:
push dword %%foo
call dbg_board_printstring
%endm
 
 
;********************************************************************
; print a string (asciiz)
;
; examples DBG_BOARD_PRINTSTRING addressofstring
; DBG_BOARD_PRINTSTRING esi
; DBG_BOARD_PRINTSTRING [ebx]
;********************************************************************
%macro DBG_BOARD_PRINTSTRING 1
push dword %1
call dbg_board_printstring
%endm
 
 
; no input
dbg_board_printnewline:
pushad
pushfd
mov eax,MOS_SC_DEBUGBOARD
mov ebx,1
mov ecx,10
int 0x40
mov ecx,13
int 0x40
popfd
popad
ret
; input : cl = character to print
dbg_board_printchar:
pushad
pushfd
mov eax,MOS_SC_DEBUGBOARD
mov ebx,1
and ecx,0xff
int 0x40
popfd
popad
ret
 
; input : dword to print on stack
dbg_board_printdword:
enter 0,0
pushad
pushfd
mov eax,MOS_SC_DEBUGBOARD
mov ebx,1
mov ecx,'0' ; print 0x prefix
int 0x40
mov ecx,'x'
int 0x40
mov edx,[ebp + 8] ; get dword to print
mov esi,8 ; iterate through all nibbles
.loop:
mov ecx,edx ; display hex digit
shr ecx,28
movzx ecx,byte [dbg_board_printdword_digits + ecx]
int 0x40
shl edx,4 ; next nibble
dec esi
jnz .loop
popfd
popad
leave
ret 4
dbg_board_printdword_digits:
db '0','1','2','3','4','5','6','7'
db '8','9','a','b','c','d','e','f'
 
; input : address of string (asciiz) to print on stack
dbg_board_printstring:
enter 0,0
pushad
pushfd
cld
mov esi,[ebp + 8] ; esi -> string
mov ebx,1
.loop:
lodsb ; get character
or al,al ; zero ?
je .done ; yeah -> get outta here
movzx ecx,al ; nope -> display character
mov eax,MOS_SC_DEBUGBOARD
int 0x40
jmp .loop
.done:
popfd
popad
leave
ret 4
%else
 
 
%macro DBG_BOARD_PRINTNEWLINE 0
%endm
 
%macro DBG_BOARD_PRINTCHAR 1
%endm
 
%macro DBG_BOARD_PRINTDWORD 1
%endm
 
%macro DBG_BOARD_PRINTSTRINGLITERAL 1+
%endm
 
%macro DBG_BOARD_PRINTSTRING 1
%endm
 
%endif
 
 
%endif
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/draw.inc
0,0 → 1,430
; drawing code for aclock
;
; Copyright (c) 2003 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
%ifndef _DRAW_INC
%define _DRAW_INC
 
 
TMR1_FACTOR dd 0.45
TMR2_FACTOR dd 0.426315789
SECR_FACTOR dd 0.378947368
MINR_FACTOR dd 0.355263158
HOURR_FACTOR dd 0.189473684
DATE_FACTOR dd 0.1
 
 
monthNames:
db "Jan"
db "Feb"
db "Mar"
db "Apr"
db "May"
db "Jun"
db "Jul"
db "Aug"
db "Sep"
db "Oct"
db "Nov"
db "Dec"
 
 
;********************************************************************
; draws the clock
; input : nothing
; output : nothing
; destroys : nothing
;********************************************************************
drawClock:
%push drawClock_context
%stacksize flat
%assign %$localsize 0
 
%local i:dword, \
TMR1X:dword, \
TMR1Y:dword, \
TMR2X:dword, \
TMR2Y:dword, \
SECRX:dword, \
SECRY:dword, \
MINRX:dword, \
MINRY:dword, \
HOURRX:dword, \
HOURRY:dword, \
workwidth:dword, \
workheight:dword, \
foo:dword
enter %$localsize,0
pushad
pushfd
 
; get window dimensions
mov eax,MOS_SC_GETPROCESSINFO
mov ebx,procInfo
mov ecx,-1
int 0x40
 
; calculate work area size (width/height = ecx/edx)
; if the work area is too small (maybe the window is shaded)
; we don't draw anything.
mov eax,MOS_SC_WINDOWPROPERTIES
mov ebx,4 ; get skin height (eax)
int 0x40
mov ecx,[procInfo + MOS_PROCESSINFO.wndWidth]
sub ecx,MOS_WND_SKIN_BORDER_LEFT+MOS_WND_SKIN_BORDER_RIGHT
mov edx,[procInfo + MOS_PROCESSINFO.wndHeight]
sub edx,eax
sub edx,MOS_WND_SKIN_BORDER_BOTTOM
cmp ecx,0 ; width too small ?
jle .bye
cmp edx,0 ; height too small ?
jnle .continue
.bye:
jmp .byebye
.continue:
mov [workwidth],ecx ; save for later (for fpu)
mov [workheight],edx
 
; calculate center of clock (x/y = esi/edi)
mov esi,[procInfo + MOS_PROCESSINFO.wndWidth]
shr esi,1
mov edi,[procInfo + MOS_PROCESSINFO.wndHeight]
sub edi,MOS_WND_SKIN_BORDER_BOTTOM
sub edi,eax
shr edi,1
add edi,eax
 
; clear work area
pushad
mov ebx,(MOS_WND_SKIN_BORDER_LEFT)*0x10000 ; x start
or ebx,ecx ; width
mov ecx,eax ; y start
shl ecx,16 ; (=skin height)
or ecx,edx ; height
mov edx,[wndColors + MOS_WNDCOLORS.work]
mov eax,MOS_SC_DRAWBAR
int 0x40
popad
 
; calculate second hand radii
fild dword [workwidth]
fmul dword [SECR_FACTOR]
fstp dword [SECRX]
fild dword [workheight]
fmul dword [SECR_FACTOR]
fstp dword [SECRY]
 
; calculate minute hand radii
fild dword [workwidth]
fmul dword [MINR_FACTOR]
fstp dword [MINRX]
fild dword [workheight]
fmul dword [MINR_FACTOR]
fstp dword [MINRY]
 
; calculate hour hand radii
fild dword [workwidth]
fmul dword [HOURR_FACTOR]
fstp dword [HOURRX]
fild dword [workheight]
fmul dword [HOURR_FACTOR]
fstp dword [HOURRY]
 
; calculate tick mark radii
fild dword [workwidth]
fmul dword [TMR1_FACTOR]
fstp dword [TMR1X]
fild dword [workheight]
fmul dword [TMR1_FACTOR]
fstp dword [TMR1Y]
fild dword [workwidth]
fmul dword [TMR2_FACTOR]
fstp dword [TMR2X]
fild dword [workheight]
fmul dword [TMR2_FACTOR]
fstp dword [TMR2Y]
 
; get system clock (edx)
mov eax,MOS_SC_GETSYSCLOCK
int 0x40
mov edx,eax
 
; draw second hand
push edx
mov eax,edx
shr eax,16
call bcdbin
mov ecx,eax ; save seconds for later
push ecx
push eax
fpush32 0.104719755 ; 2*pi/60
push dword [SECRX]
push dword [SECRY]
push esi
push edi
call getHandCoords
mov eax,MOS_SC_DRAWLINE
shl ebx,16
or ebx,esi
shl ecx,16
or ecx,edi
mov edx,[wndColors + MOS_WNDCOLORS.workText]
int 0x40
pop ecx
pop edx
 
; draw minute hand
push edx
mov eax,edx
shr eax,8
call bcdbin
mov edx,60
mul edx
add eax,ecx
mov ecx,eax ; save for later
push ecx
push eax
fpush32 0.001745329 ; 2*pi/60/60
push dword [MINRX]
push dword [MINRY]
push esi
push edi
call getHandCoords
mov eax,MOS_SC_DRAWLINE
shl ebx,16
or ebx,esi
shl ecx,16
or ecx,edi
mov edx,[wndColors + MOS_WNDCOLORS.workText]
int 0x40
pop ecx
pop edx
 
; draw hour hand
push edx
mov eax,edx
call bcdbin
cmp eax,11 ; % 12 (just to be sure)
jnae .hoursok
sub eax,12
.hoursok:
mov edx,60*60
mul edx
add eax,ecx
push eax
fpush32 0.000145444 ; 2*pi/60/60/12
push dword [HOURRX]
push dword [HOURRY]
push esi
push edi
call getHandCoords
mov eax,MOS_SC_DRAWLINE
shl ebx,16
or ebx,esi
shl ecx,16
or ecx,edi
mov edx,[wndColors + MOS_WNDCOLORS.workText]
int 0x40
pop edx
; draw tick marks
mov dword [i],11 ; draw 12 marks
.drawtickmarks:
push dword [i] ; calculate start point
fpush32 0.523598776 ; 2*pi/12
push dword [TMR1X]
push dword [TMR1Y]
push esi
push edi
call getHandCoords
mov eax,ebx ; save in eax and edx
mov edx,ecx
push dword [i]
fpush32 0.523598776 ; 2*pi/12
push dword [TMR2X]
push dword [TMR2Y]
push esi
push edi
call getHandCoords
shl eax,16
shl edx,16
or ebx,eax ; ebx = x start and end
or ecx,edx ; ecx = y start and end
mov edx,[wndColors + MOS_WNDCOLORS.workText]
mov eax,MOS_SC_DRAWLINE
int 0x40
dec dword [i]
jns .drawtickmarks
 
%define DATE_WIDTH 48
 
; calculate text start position
mov eax,[procInfo+MOS_PROCESSINFO.wndWidth]
sub eax,DATE_WIDTH ; x = (wndwidth-textwidth)/2
shr eax,1 ; eax = x
fild dword [workheight] ; y = DATE_FACTOR*workheight...
fmul dword [DATE_FACTOR]
mov [foo],edi ; ... + y_clockcenter
fiadd dword [foo]
fistp dword [foo]
mov ebx,[foo] ; ebx = y
 
; draw text at all ?
cmp dword [workwidth],DATE_WIDTH ; text too wide ?
jb .goodbye
mov ecx,ebx ; text too high ?
add ecx,10-1
mov edx,[procInfo+MOS_PROCESSINFO.wndHeight]
sub edx,MOS_WND_SKIN_BORDER_BOTTOM
cmp ecx,edx
jnae .yousuck
.goodbye:
jmp .bye
.yousuck:
 
 
; ebx = (x << 16) | y
shl eax,16
or ebx,eax
; get date (edi)
mov eax,MOS_SC_GETDATE
int 0x40
mov edi,eax
 
; display month
mov eax,edi ; get month
shr eax,8
call bcdbin
; ebx contains already position
mov ecx,[wndColors+MOS_WNDCOLORS.workText]
lea edx,[monthNames-3+eax*2+eax]; -3 because eax = 1..12 =]
mov esi,3 ; text length
mov eax,MOS_SC_WRITETEXT
int 0x40
 
; display date
add ebx,MOS_DWORD(3*6+3,0)
mov eax,edi ; get date
shr eax,16
call bcdbin
mov edx,ebx ; position must be in edx
mov ebx,0x00020000 ; number, display two digits
mov ecx,eax ; number to display
mov esi,[wndColors+MOS_WNDCOLORS.workText]
mov eax,MOS_SC_WRITENUMBER
int 0x40
 
; display year. the way we avoid the y2k bug is even
; simpler, yet much better than in the last version:
; now we simply display the last two digits and let the
; user decide wether it's the year 1903 or 2003 =]
add edx,MOS_DWORD(2*6+3,0)
mov eax,edi ; get year
call bcdbin
mov ebx,0x00020000 ; number, display two digits
mov ecx,eax ; number to display
; edx contains already position
mov esi,[wndColors+MOS_WNDCOLORS.workText]
mov eax,MOS_SC_WRITENUMBER
int 0x40
 
.byebye:
popfd
popad
leave
ret
%pop
 
 
;**********************************************************
; bcdbin
; converts a 8 bit bcd number into a 32 bit binary number
;
; in al = 8 bit bcd number
; out eax = 32 bit binary number
; destroys dl,flags
;**********************************************************
bcdbin:
push edx
pushfd
mov dl,al ; save bcd number
shr al,4 ; convert upper nibble
mov ah,10
mul ah
and dl,15 ; add lower nibble
add al,dl
and eax,255 ; !
popfd
pop edx
ret
 
 
;********************************************************************
; getHandCoords
; calculates the end point of a hand
;
; input (on stack, push from top to bottom):
; ANGLE angle (integer)
; DEG2RAD conversion factor for ANGLE (32 bit real)
; RADIUSX x radius (32 bit real)
; RADIUSY y radius (32 bit real)
; CENTERX x center of the clock (integer)
; CENTERY y center of the clock (integer)
;
; output:
; ebx x coordinate in bits 0..15, bits 16..31 are zero
; ecx y coordinate in bits 0..15, bits 16..31 are zero
;
; destroys:
; nothing
;********************************************************************
getHandCoords:
 
ANGLE equ 28
DEG2RAD equ 24
RADIUSX equ 20
RADIUSY equ 16
CENTERX equ 12
CENTERY equ 8
 
enter 0,0
pushfd
 
fild dword [ebp+ANGLE] ; get angle
fmul dword [ebp+DEG2RAD] ; convert to radians
fsincos
fmul dword [ebp+RADIUSY] ; -y * radius + clockcy
fchs
fiadd dword [ebp+CENTERY]
fistp dword [ebp+CENTERY]
fmul dword [ebp+RADIUSX] ; x * radius + clockcx
fiadd dword [ebp+CENTERX]
fistp dword [ebp+CENTERX]
mov ebx,[ebp+CENTERX]
mov ecx,[ebp+CENTERY]
 
popfd
leave
ret 4*6
 
 
%endif
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/make.bat
0,0 → 1,2
@rem nasm -t -f bin -o aclock -l aclock.lst aclock.asm -DDEBUG
nasm -t -f bin -o aclock aclock.asm
/programs/aclock/trunk/mos.inc
0,0 → 1,334
; mos.inc 0.03
; Copyright (c) 2002 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
%ifndef _MOS_INC
%define _MOS_INC
 
 
;**********************************************************
; generates a menuetos 01 header
; takes 6 parameters:
;
; MOS_HEADER01 start, end, appmem, esp, i_param, i_icon
;**********************************************************
 
%macro MOS_HEADER01 6
org 0x0
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd %1 ; start of code
dd %2 ; image size
dd %3 ; application memory
dd %4 ; esp
dd %5 ; i_param
dd %6 ; i_icon
%endmacro
 
 
;**********************************************************
; MOS_DWORD
; packs 2 words into a double word
;**********************************************************
 
%define MOS_DWORD(hi,lo) ((((hi) & 0xffff) << 16) + ((lo) & 0xffff))
 
 
;**********************************************************
; MOS_RGB
; creates a menuet os compatible color (0x00RRGGBB)
;**********************************************************
 
%define MOS_RGB(r,g,b) ((((r) & 255) << 16) + (((g) & 255) << 8) + ((b) & 255))
 
 
;**********************************************************
; window stuff
;**********************************************************
 
; default window colors
struc MOS_WNDCOLORS
.frame: resd 1
.grab: resd 1
.grabButton: resd 1
.grabButtonText: resd 1
.grabText: resd 1
.work: resd 1
.workButton: resd 1
.workButtonText: resd 1
.workText: resd 1
.workGraphics: resd 1
endstruc
 
; skinned window borders
MOS_WND_SKIN_BORDER_LEFT equ 5
MOS_WND_SKIN_BORDER_RIGHT equ 5
MOS_WND_SKIN_BORDER_BOTTOM equ 5
 
 
;**********************************************************
; process info structure
;**********************************************************
 
struc MOS_PROCESSINFO
.CPUUsage: resd 1
.windowStackPos: resw 1
.windowStackVal: resw 1
.reserved1: resw 1
.processName: resb 12
.memStart: resd 1
.memUsed: resd 1
.pid: resd 1
.wndXPos resd 1
.wndYPos resd 1
.wndWidth resd 1
.wndHeight resd 1
.reserved2: resb (1024 - 50)
endstruc
 
 
 
;**********************************************************
; system call numbers
;**********************************************************
 
MOS_SC_EXIT equ -1
MOS_SC_DEFINEWINDOW equ 0
MOS_SC_PUTPIXEL equ 1
MOS_SC_GETKEY equ 2
MOS_SC_GETSYSCLOCK equ 3
MOS_SC_WRITETEXT equ 4
MOS_SC_DELAY equ 5
MOS_SC_OPENFILEFLOPPY equ 6 ; obsolete
MOS_SC_PUTIMAGE equ 7
MOS_SC_DEFINEBUTTON equ 8
MOS_SC_GETPROCESSINFO equ 9
MOS_SC_WAITEVENT equ 10
MOS_SC_CHECKEVENT equ 11
MOS_SC_REDRAWSTATUS equ 12
MOS_SC_DRAWBAR equ 13
MOS_SC_GETSCREENMAX equ 14
MOS_SC_SETBACKGROUND equ 15
MOS_SC_GETPRESSEDBUTTON equ 17
MOS_SC_SYSTEMSERVICE equ 18
MOS_SC_STARTPROGRAM equ 19 ; obsolete
MOS_SC_MIDIINTERFACE equ 20
MOS_SC_DEVICESETUP equ 21
MOS_SC_WAITEVENTTIMEOUT equ 23
MOS_SC_CDAUDIO equ 24
MOS_SC_SB16MIXER1 equ 25
MOS_SC_GETDEVICESETUP equ 26
MOS_SC_WSS equ 27
MOS_SC_SB16MIXER2 equ 28
MOS_SC_GETDATE equ 29
MOS_SC_READHD equ 30 ; obsolete
MOS_SC_STARTPROGRAMHD equ 31 ; obsolete
MOS_SC_DELETEFILEFLOPPY equ 32
MOS_SC_SAVEFILERAMDISK equ 33 ; obsolete
MOS_SC_READDIRRAMDISK equ 34 ; obsolete
MOS_SC_GETSCREENPIXEL equ 35
MOS_SC_GETMOUSEPOSITION equ 37
MOS_SC_DRAWLINE equ 38
MOS_SC_GETBACKGROUND equ 39
MOS_SC_SETEVENTMASK equ 40
MOS_SC_GETIRQOWNER equ 41
MOS_SC_GETDATAREADBYIRQ equ 42
MOS_SC_SENDDATATODEVICE equ 43
MOS_SC_PROGRAMIRQS equ 44
MOS_SC_RESERVEFREEIRQ equ 45
MOS_SC_RESERVEFREEPORTS equ 46
MOS_SC_WRITENUMBER equ 47
MOS_SC_WINDOWPROPERTIES equ 48
MOS_SC_SHAPEDWINDOWS equ 50
MOS_SC_CREATETHREAD equ 51
MOS_SC_STACKDRIVERSTATE equ 52
MOS_SC_SOCKETINTERFACE equ 53
MOS_SC_SOUNDINTERFACE equ 55
MOS_SC_WRITEFILEHD equ 56 ; obsolete
MOS_SC_DELETEFILEHD equ 57
MOS_SC_SYSTREEACCESS equ 58
MOS_SC_SYSCALLTRACE equ 59
MOS_SC_IPC equ 60
MOS_SC_DIRECTGRAPHICS equ 61
MOS_SC_PCI equ 62
MOS_SC_DEBUGBOARD equ 63
 
 
;**********************************************************
; event numbers
;**********************************************************
 
MOS_EVT_NONE equ 0
MOS_EVT_REDRAW equ 1
MOS_EVT_KEY equ 2
MOS_EVT_BUTTON equ 3
 
 
;**********************************************************
; event bits
;**********************************************************
 
MOS_EVTBIT_REDRAW equ (1 << 0)
MOS_EVTBIT_KEY equ (1 << 1)
MOS_EVTBIT_BUTTON equ (1 << 2)
MOS_EVTBIT_ENDREQUEST equ (1 << 3)
MOS_EVTBIT_BGDRAW equ (1 << 4)
MOS_EVTBIT_MOUSECHANGE equ (1 << 5)
MOS_EVTBIT_IPCEVENT equ (1 << 6)
MOS_EVTBIT_IRQ0 equ (1 << 16)
MOS_EVTBIT_IRQ1 equ (1 << 17)
MOS_EVTBIT_IRQ2 equ (1 << 18)
MOS_EVTBIT_IRQ3 equ (1 << 19)
MOS_EVTBIT_IRQ4 equ (1 << 20)
MOS_EVTBIT_IRQ5 equ (1 << 21)
MOS_EVTBIT_IRQ6 equ (1 << 22)
MOS_EVTBIT_IRQ7 equ (1 << 23)
MOS_EVTBIT_IRQ8 equ (1 << 24)
MOS_EVTBIT_IRQ9 equ (1 << 25)
MOS_EVTBIT_IRQ10 equ (1 << 26)
MOS_EVTBIT_IRQ11 equ (1 << 27)
MOS_EVTBIT_IRQ12 equ (1 << 28)
MOS_EVTBIT_IRQ13 equ (1 << 29)
MOS_EVTBIT_IRQ14 equ (1 << 30)
MOS_EVTBIT_IRQ15 equ (1 << 31)
 
 
;**********************************************************
; exit application (syscall -1)
;**********************************************************
 
; exit application
%macro MOS_EXIT 0
mov eax,MOS_SC_EXIT
int 0x40
%endmacro
 
; exit application, smaller version
%macro MOS_EXIT_S 0
xor eax,eax
dec eax
int 0x40
%endmacro
 
 
;**********************************************************
; wait event stuff
; (MOS_SC_WAITEVENT, syscall 10)
;**********************************************************
 
; wait for event
; destroys : nothing
; returns : eax = event type
%macro MOS_WAITEVENT 0
mov eax,MOS_SC_WAITEVENT
int 0x40
%endmacro
 
; wait for event, smaller version
; destroys : flags
; returns : eax = event type
%macro MOS_WAITEVENT_S 0
xor eax,eax
mov al,MOS_SC_WAITEVENT
int 0x40
%endmacro
 
 
;**********************************************************
; window redraw status stuff
; (MOS_SC_REDRAWSTATUS, syscall 12)
;**********************************************************
 
MOS_RS_STARTREDRAW equ 1
MOS_RS_ENDREDRAW equ 2
 
; start window redraw
; destroys: eax,ebx
%macro MOS_STARTREDRAW 0
mov ebx,MOS_RS_STARTREDRAW
mov eax,MOS_SC_REDRAWSTATUS
int 0x40
%endmacro
 
; start window redraw, smaller version
; destroys: eax,ebx,flags
%macro MOS_STARTREDRAW_S 0
xor ebx,ebx
inc ebx
xor eax,eax
mov al,MOS_SC_REDRAWSTATUS
int 0x40
%endmacro
 
; end window redraw
; destroys: eax,ebx
%macro MOS_ENDREDRAW 0
mov ebx,MOS_RS_ENDREDRAW
mov eax,MOS_SC_REDRAWSTATUS
int 0x40
%endmacro
 
; end window redraw, smaller version
; destroys: eax,ebx,flags
%macro MOS_ENDREDRAW_S 0
xor ebx,ebx
mov bl,MOS_RS_ENDREDRAW
xor eax,eax
mov al,MOS_SC_REDRAWSTATUS
int 0x40
%endmacro
 
 
;**********************************************************
; get screen max stuff (syscall 14)
;**********************************************************
 
; get screen dimensions in eax
; destroys: nothing
%macro MOS_GETSCREENMAX 0
mov eax,MOS_SC_GETSCREENMAX
int 0x40
%endmacro
 
; get screen dimensions in eax, smaller version
; destroys: flags
%macro MOS_GETSCREENMAX_S 0
xor eax,eax
mov al,MOS_SC_GETSCREENMAX
int 0x40
%endmacro
 
 
;********************************************************************
; opcode hacks
;********************************************************************
 
; nasm refuses to assemble stuff like
; push dword 4.44
; with the following macro this becomes possible:
; fpush32 9.81
; don't forget to use a decimal point. things like
; fpush32 1
; will probably not do what you expect. instead, write:
; fpush32 1.0
%macro fpush32 1
db 0x68 ; push imm32
dd %1
%endm
 
%endif
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/str2dwrd.inc
0,0 → 1,92
; string2dword - a useless string to double word conversion routine
;
; Copyright (c) 2003 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
 
 
;********************************************************************
; converts an asciiz string into an unsigned doubleword.
; (base 10 is assumed)
;
; - first, leading whitespaces are skipped
; - then the function converts the string, until it
; finds the terminating zero, another character it
; cannot convert or the number becomes too large.
;
; input : esi = pointer to string
; output : eax = unsigned doubleword
; the function tries to convert as
; many digits as possible, before it
; stops. if the value of the dword
; becomes too large, 0xffffffff is
; returned.
; destroys : nothing
;********************************************************************
string2dword:
push ebx
push ecx
push edx
push esi
pushfd
 
xor ebx,ebx ; ebx : dword
 
; skip leading whitespaces
.skipspaces:
lodsb
cmp al,32 ; space
je .skipspaces
cmp al,12 ; ff
je .skipspaces
cmp al,10 ; lf
je .skipspaces
cmp al,13 ; cr
je .skipspaces
cmp al,9 ; ht
je .skipspaces
cmp al,11 ; vt
je .skipspaces
 
; convert string
dec esi ; esi -> 1st non-whitespace
.convert:
xor eax,eax ; get character
lodsb
sub al,'0' ; convert to digit
cmp al,9 ; is digit in range [0,9] ?
ja .done ; nope -> stop conversion
mov ecx,eax ; save new digit
mov eax,10 ; dword = dword * 10
mul ebx
jc .overflow
add eax,ecx ; + new digit
jc .overflow
mov ebx,eax
jmp .convert
 
.overflow:
mov ebx,0xffffffff
.done:
mov eax,ebx
popfd
pop esi
pop edx
pop ecx
pop ebx
ret
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/strlen.inc
0,0 → 1,49
; strlen function
;
; Copyright (c) 2003 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
%ifndef _STRLEN_INC
%define _STRLEN_INC
 
 
;********************************************************************
; returns the length of an asciiz string
; input : esi = pointer to string
; output : eax = string length
; destroys : nothing
;********************************************************************
strlen:
push ecx
push edi
pushfd
cld ; !
mov ecx,-1
mov edi,esi ; find terminating zero
xor al,al
repne scasb
mov eax,edi ; calculate string length
sub eax,esi
dec eax
popfd
pop edi
pop ecx
ret
 
 
%endif
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/programs/aclock/trunk/strtok.inc
0,0 → 1,125
; some strtok-like function
;
; Copyright (c) 2003 Thomas Mathys
; killer@vantage.ch
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
%ifndef _STRTOK_INC
%define _STRTOK_INC
 
 
;********************************************************************
; strtok
; this function works like strtok from a c runtime library.
; note that it is not threadsafe. it would be an easy task
; to make it threadsafe, though:
; .adx must be removed, instead the last search address is
; stored at some location provided by the user (passed as
; a third parameter in ecx or so)
;
; input:
;
; eax : address of string to be searched (asciiz), or
; 0 to get the next token of the current string
; ebx : address of delimiter list (asciiz)
;
; output:
;
; eax : pointer to the next token, or 0 if there
; aren't any tokens anymore.
;
; destroys: nothing
;
;********************************************************************
strtok:
pushad
pushfd
 
; get start address
; if the new start address is 0, and the old address (.adx)
; is also 0, then there's nothing to do and we return 0.
or eax,eax ; new address = 0 ?
jz .nonewstring ; nope -> use old string
mov [.adx],eax ; yeah -> store new string adx
.nonewstring:
mov esi,[.adx] ; load string address
or esi,esi ; 0 ?
jnz .startadxok ; nope -> ok
xor eax,eax ; yeah -> return 0
je .bye
.startadxok:
 
; skip leading delimiters
.skipdelimiters:
lodsb ; read character
mov edi,ebx ; edi -> delimiter list
.foo:
mov cl,[edi] ; get delimiter
inc edi
or cl,cl ; end of delimiter list
jz .endofdelimiterlist
cmp al,cl ; if AL is a delimiter, then
je .skipdelimiters ; we need to skip it too...
jmp .foo ; otherwise try next delimiter
.endofdelimiterlist:
 
; end of string reached without finding any non-delimiters ?
or al,al ; character = 0 ?
jnz .bar ; nope -> continue
mov dword [.adx],0 ; yeah -> remember this
xor eax,eax ; and return 0
jmp .bye
.bar:
 
; found the start of a token, let's store its address
mov edx,esi
dec edx ; edx = start address of token
 
; find the end of the token
.abraham:
lodsb ; get character
mov edi,ebx ; edi -> delimiter list
.bebraham:
mov cl,[edi] ; get delimiter
inc edi
cmp al,cl ; is AL a delimiter ?
jne .cebraham ; nope -> continue
or al,al ; terminating zero found ?
jnz .argle
xor esi,esi ; yeah -> remember this
jmp .bargle
.argle:
mov byte [esi-1],0 ; nope -> mark end of token
.bargle:
mov [.adx],esi ; remember search address
mov eax,edx ; return token address
jmp .bye
.cebraham:
or cl,cl ; end of delimiter list ?
jnz .bebraham ; nope -> try next delimiter
jmp .abraham
; write return value into stack, so that when popad
; gets executed, eax will receive the return value.
.bye:
mov [esp+4*8],eax
popfd
popad
ret
.adx dd 0
 
%endif
 
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property