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