Would someone convert this code to masm for me?
http://msdn.microsoft.com/en-us/library/ms713937(VS.85).aspx
void CALLBACK OneShotTimer(UINT wTimerID, UINT msg,
DWORD dwUser, DWORD dw1, DWORD dw2)
{
NPSEQ npSeq; // pointer to sequencer data
npSeq = (NPSEQ)dwUser;
npSeq->wTimerID = 0; // invalidate timer ID (no longer in use)
TimerRoutine(npSeq); // handle tasks
}
This is even more cryptic than your normal c code.
OneShotTimer:
mov eax,[esp+0Ch]
mov WORD PTR [eax + SEQ.wTimerID],0
invoke TimerRoutine,eax
retn 14h
Hello,
And if you Have other questions like that,add the option "/FA" (like Flat Assembler) to the C compiler and .... you have an .asm file.
Thanks Infro_X.
ToutEnMasm- I don't have a C compiler, and I can just barely read and guess at what half the code I see is doing.
I take that back. I bought Quick-C about 20 years ago, just to use the Quick-Assembler option. Not C++ at all.
Yup, I just looked at the books. Copyright 1988.
Quote from: Infro_X on March 10, 2009, 10:23:21 AM
OneShotTimer:
mov eax,[esp+0Ch]
mov WORD PTR [eax + SEQ.wTimerID],0
invoke TimerRoutine,eax
retn 14h
Is it not this instead :
mov eax,[esp+16]
First argument is ESP+8
Next is ESP +12
Third is ESP + 16
After spending about an hour searching, I can't find a declaration for NPSEQ and the structure it points to, and without that I can't see any way to actually use the code.
Thank you Michael, that was my experience also. It was never my intention anyone waste an hour, even though I have wasted ten trying to get a multimedia timer that is more accurate than a simple timer. I no longer need it urgently, but I hope to get back to it some time.
I spent an hour on it mostly because I'm stubborn. In the Windows Server 2003 PSDK there are three instances of NPSEQ, including one in a copy of the code you posted, so it must be defined in a header file somewhere. A search on NPSEQ turns up pages that do not appear to contain NPSEQ or anything related, so I'm guessing that it's so frequently searched for that it's being inserted somehow to fool the search engines.
It seems it's simply a pointer to a user-defined data structure. And it's oooold - this is from Win 3.1 SDK:
This section describes how an application might use the timer services. First, the application calls the timeGetDevCaps function to determine the minimum and maximum resolution supported by the timer services. Before setting up any timer events, the application uses timeBeginPeriod to establish the minimum timer resolution it will use, as shown in the following code fragment:
#define TARGET_RESOLUTION 1 // Try for 1-millisecond accuracy
TIMECAPS tc;
UINT wTimerRes;
if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR)
{
// Error; application can't continue
}
wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
timeBeginPeriod(wTimerRes);
To start the timer event, the application specifies the amount of time before the callback occurs, the required resolution, the address of the callback function, and user data to supply with the callback. The application might use a function like the following to start a one-time timer event:
UINT SetTimerCallback(NPSEQ npSeq, // Sequencer data
UINT msInterval) // Event interval
{
npSeq->wTimerID = timeSetEvent(
msInterval, // Delay
wTimerRes, // Resolution (global variable)
OneShotCallback, // Callback function
(DWORD)npSeq, // User data
TIME_ONESHOT ); // Event type (one-time)
if(! npSeq->wTimerID)
return ERR_TIMER;
else
return ERR_NOERROR;
}
The following callback function resides in a fixed code segment in a DLL. It is limited to calling those functions that are interrupt-callable. The TimerIntRoutine procedure it calls also resides in a fixed code segment.
void FAR PASCAL
OneShotTimer(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
NPSEQ npSeq; // Pointer to sequencer data
npSeq = (NPSEQ)dwUser;
npSeq->wTimerID = 0; // Invalidate timer id, since no longer in use
TimerIntRoutine(npSeq); // Handle interrupt-time tasks
}
Before freeing the DLL that contains the callback function, the application cancels any outstanding timers. To cancel one timer event, it might call the following function:
void DestroyTimer(NPSEQ npSeq)
{
if(npSeq->wTimerID) // If timer event is pending
{
timeKillEvent(npSeq->wTimerID); // Cancel the event
npSeq->wTimerID = 0;
}
}
Finally, to cancel the minimum timer resolution it established, the application calls timeEndPeriod as follows:
timeEndPeriod(wTimerRes);
Nice. How long before you convert that to Masm?
How about learning some C ?
Plain C is so easy...
Irony aside, if it seems clean and straightforward to you, then there is clearly no reason for me to say anything further.
I learned assembly language studying the assembly output of my C programs. I'm a special case I guess.
Quote from: mitchi on March 11, 2009, 03:02:56 AM
I learned assembly language studying the assembly output of my C programs. I'm a special case I guess.
Ironic; I actually learned C by studying assembly. Basically, i was looking for something that could do low level Win32 API, but retain the high level macro features of MASM, and automatically do array scaling and such; it's actually a little scary how similar low level C and MASM w/ high-level macros are to each other...
-ac
Quote from: mitchi on March 11, 2009, 03:02:56 AM
I learned assembly language studying the assembly output of my C programs. I'm a special case I guess.
I did the same, back on the days of turbo C, 3.0
Quote from: redskull on March 11, 2009, 03:25:24 AM
it's actually a little scary how similar low level C and MASM w/ high-level macros are to each other...
-ac
Hmmm... that depends strongly on which macros you use :green
OPEN "O", #1, offset txGfaFile ; open a file for output
PRINT #1, MID$(CAT$("We use a CAT$ for doing this test: ", chr$(13,10), offset txTestbed), 25)
PRINT #1, offset txGpStr ; print another string to the file
CLOSE ; close all files opened with OPEN
OPEN "I", #1, offset txGfaFile ; open again for input
.if eax!=INVALID_HANDLE_VALUE
INPUT #1, My$, LOF(#1) ; read all bytes to My$
MsgBox 0, My$, STR$("Here are %3f kBytes from the file we just wrote to:", LOF(#1)/1024), MB_OK
CLOSE #1 ; close only file No. 1 (the # is optional for CLOSE)
.endif
OPEN "O", #1, offset txGfaFileUc ; open a file for output
PRINTW #1, offset MyW$ ; print a wide (Unicode) string to the file
CLOSE 1 ; close only file No. 1
OPEN "I", #2, offset txGfaFileUc ; open again for input
INPUT #2, My$, LOF(#2) ; read all bytes to My$
CLOSE ; close all files opened with OPEN
BURN THE HERETIC !!!
:cheekygreen: