News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Help with floating point

Started by normcook, August 07, 2009, 05:34:50 PM

Previous topic - Next topic

normcook

Hi experts, trying to write an MP3 player.  Got most of it done, just
trying to add some refinements.

From my TimerProc routine, I'm trying to display the Current Minute:Second
So far I have

  LOCAL Bytes:QWORD      ;for the ChannelBytes2Seconds call below
  invoke BASS_ChannelGetPosition,Channel, BASS_POS_BYTE          ;returns curr byte pos in eax
  mov dword ptr Bytes,eax          ;load the qword
  mov dword ptr Bytes+4,0

  invoke BASS_ChannelBytes2Seconds,Channel,Bytes              ;returns a double
  ; here eax is always 1

I suspect I need some fplib calls to get the actual seconds, which I can easily
convert to MM:SS.

BTW if interested in the Bass.Inc and Bass.Lib, see
http://www.un4seen.com/
The download is at the very top of the page

dedndave

Quote// format position HH:MM:SS write in to lblTime
lblTime.Text = GetTime((int)(Bass.BASS_ChannelBytes2Seconds(Stream, Bass.BASS_ChannelGetPosition(Stream, BASSMode.BASS_POS_BYTES))));

#region GetTime()

public string GetTime(int seconds)
{
    string returnValue;

    float hour;
    float min;
    float sec;

    hour = seconds / 3600;
    sec = seconds % 60;
    min = seconds / 60;

    returnValue = string.Format("{0:00}:{1:00}:{2:00}", (int)hour, (int)min, (int)sec);

    return returnValue;
}

#endregion GetTime()
it appears that you use BASS_ChannelBytes2Seconds to convert the output to string format

jj2007

No floating point needed if you get the seconds as an integer:

include \masm32\include\masm32rt.inc

.data
AppName db "Masm32 is so easy:", 0
buffer db "hh:mm:ss", 0
dd 0

.code
start:
push 81224 ; 22:33:44
call ShowTime
MsgBox 0, offset buffer, addr AppName, MB_OK

push 45296 ; 12:34:56
call ShowTime
MsgBox 0, offset buffer, addr AppName, MB_OK

exit

ShowTime proc
mov eax, [esp+4]
push esi
push ebx
mov esi, offset buffer+10
m2m ebx, 60
Pos=6
REPEAT 3
cdq
div ebx
add edx, 100
push eax
invoke dwtoa, edx, esi
movzx eax, word ptr [esi+1]
mov word ptr buffer[Pos], ax
pop eax
Pos=Pos-3
ENDM
pop ebx
pop esi
ret 4
ShowTime endp

end start

jj2007

I realised that my snippet was horribly bloated at 94 bytes for the proc. Here is a version that weighs in at only 54 bytes.
Output:
22:33:44
12:34:56
Time since last boot: 7581312 milliseconds, 02:06:21
Size of ShowHMS=54 bytes

.nolist
include \masm32\include\masm32rt.inc

ShowHMS PROTO: DWORD, :DWORD

.data?
bufferHMS dd 4 dup (?) ; 15 bytes minimum

.code
AppName db "Masm32 is so easy...", 0
start:
invoke ShowHMS, 81224, offset bufferHMS ; 22:33:44
print offset bufferHMS, 13, 10

invoke ShowHMS, 45296, offset bufferHMS ; 12:34:56
print offset bufferHMS, 13, 10
print "Time since last boot: "
invoke GetTickCount
push eax
print str$(eax), " milliseconds, "
pop eax
cdq
mov ecx, 1000
div ecx
invoke ShowHMS, eax, offset bufferHMS
print offset bufferHMS, 13, 10, "Size of ShowHMS="
mov eax, ShowHMS_END
sub eax, ShowHMS
print str$(eax), " bytes", 13, 10
print chr$(13, 10)
print offset AppName, 13, 10
getkey
exit

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
ShowHMS proc st_secs, st_bufferHMS
  pop edx ; pop return address
  pop eax ; pop seconds
  xchg edx, [esp] ; exchange ret address with buffer pointer
  push esi
  push ebx
  mov esi, edx ; get the buffer pointer
  mov dword ptr [esi+2], ":__:" ; do some formatting inside the buffer
  add esi, 9 ; we write the number+100, e.g. 123, after the print buffer
  m2m ebx, 2
  .Repeat
cdq ; edx must be cleared
push 60 ; seconds, minutes, hours
pop ecx
div ecx
add edx, 100 ; we want a nicely formatted 2-digits number
push eax ; save current number
invoke dwtoa, edx, esi
inc esi ; oops, the buffer moves a little bit ;-)
mov eax, [esi] ; get the two digits after 1xx
mov [esi+4*ebx-12], ax ; move two digits into the buffer
pop eax
dec ebx
  .Until Sign?
  pop ebx
  pop esi
  ret
ShowHMS endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
ShowHMS_END:
end start

MichaelW

Norm,

BASS_ChannelBytes2Seconds returns a floating-point value on the FPU stack in ST(0), but this could easily be handled in your procedure with something like this:

LOCAL seconds:DWORD   ; allocate a DWORD variable
...
fistp seconds         ; store ST(0) into the variable


eschew obfuscation

normcook

MichaelW  -- thanks much, that did the trick. :clap: