forked from KolibriOS/kolibrios
266 lines
9.5 KiB
NASM
266 lines
9.5 KiB
NASM
|
; MINI.ASM
|
||
|
; --------
|
||
|
; Shows how to place data and code inside (!!!) the XM track.
|
||
|
|
||
|
.386
|
||
|
.model flat
|
||
|
|
||
|
include ufmod.inc ; uFMOD API
|
||
|
|
||
|
.CODE
|
||
|
|
||
|
PE_BASE db "MENUET01"
|
||
|
dd 1
|
||
|
dd OFFSET _START ; Entry point
|
||
|
dd OFFSET BSS_START ; End of code and initialized data
|
||
|
dd OFFSET BSS_END ; End of uninitialized (BSS) data
|
||
|
dd OFFSET STACK_B ; Bottom of the stack
|
||
|
dd 0 ; Args
|
||
|
dd 0 ; Reserved
|
||
|
|
||
|
err_txt db "Error"
|
||
|
err_txt_l EQU $ - err_txt
|
||
|
|
||
|
_START:
|
||
|
; Start playback.
|
||
|
push XM_MEMORY
|
||
|
push xm_length
|
||
|
push BYTE PTR xm
|
||
|
|
||
|
; Let's place the stream right inside the code section.
|
||
|
xm_length EQU 905
|
||
|
xm EQU $ - PE_BASE
|
||
|
xm_unused_000 LABEL BYTE
|
||
|
|
||
|
; *** The following 60 bytes are not used. So, we'll place
|
||
|
; *** some code here.
|
||
|
; (the actual size and location of such gaps may be
|
||
|
; found out using the Eff utility)
|
||
|
|
||
|
call uFMOD_LoadSong
|
||
|
xor ebp,ebp ; global 0
|
||
|
|
||
|
; Stack fixing is required here, but in this simple
|
||
|
; example leaving ESP as it is won't harm. In a real
|
||
|
; application you should uncomment the following line:
|
||
|
; add esp,12
|
||
|
|
||
|
test eax,eax
|
||
|
jz error
|
||
|
|
||
|
; Wait for user input.
|
||
|
push uFMOD_WaveOut ; cbProc <- continue fetching data!
|
||
|
push BYTE PTR msg_txt_l ; cbString
|
||
|
push OFFSET msg_txt ; lpString
|
||
|
push OFFSET msg_cap ; szCap
|
||
|
call MessageBoxCB
|
||
|
; add esp,16
|
||
|
|
||
|
; Stop playback.
|
||
|
call uFMOD_StopSong
|
||
|
|
||
|
r: ; Exit.
|
||
|
lea eax,[ebp-1]
|
||
|
int 40h
|
||
|
|
||
|
error:
|
||
|
push ebp ; cbProc <- no callback
|
||
|
push BYTE PTR err_txt_l ; cbString
|
||
|
push BYTE PTR (err_txt - PE_BASE) ; lpString
|
||
|
push OFFSET err_cap ; szCap
|
||
|
call MessageBoxCB
|
||
|
; add esp,16
|
||
|
jmp r
|
||
|
|
||
|
org xm_unused_000 + 60
|
||
|
db 034h,000h,000h,000h,020h,000h,000h,000h,002h,000h,00Dh,000h,001h,000h,001h,000h
|
||
|
db 00Ah,000h,091h,000h,000h,001h,002h,003h,004h,005h,006h,007h,000h,001h,002h,003h
|
||
|
db 004h,005h,006h,007h,008h,009h,00Ah,00Bh,008h,009h,00Ch,00Bh,008h,009h,00Ah,00Bh
|
||
|
db 008h,009h,00Ch,00Bh,009h,000h,000h,000h,000h,004h,000h,001h,000h,083h,016h,001h
|
||
|
db 080h,080h,02Eh,001h,000h,00Eh,060h,080h,03Ah,001h,000h,00Eh,062h,081h,061h,083h
|
||
|
db 035h,001h,009h,000h,000h,000h,000h,004h,000h,001h,000h,083h,016h,001h,080h,080h
|
||
|
db 02Eh,001h,000h,00Eh,060h,080h,035h,001h,000h,00Eh,062h,081h,061h,083h,038h,001h
|
||
|
db 009h,000h,000h,000h,000h,004h,000h,001h,000h,083h,016h,001h,080h,080h,02Eh,001h
|
||
|
db 000h,00Eh,060h,080h,038h,001h,000h,00Eh,062h,080h,083h,033h,001h,009h,000h,000h
|
||
|
db 000h,000h,006h,000h,001h,000h,083h,016h,001h,080h,080h,02Eh,001h,000h,00Eh,060h
|
||
|
db 080h,033h,001h,000h,00Eh,061h,081h,061h,083h,035h,001h,083h,00Dh,001h,083h,036h
|
||
|
db 001h,080h,083h,036h,001h,009h,000h,000h,000h,000h,004h,000h,001h,000h,083h,00Fh
|
||
|
db 001h,080h,080h,02Eh,001h,000h,00Eh,060h,080h,036h,001h,000h,00Eh,062h,081h,061h
|
||
|
db 083h,033h,001h,009h,000h,000h,000h,000h,006h,000h,001h,000h,083h,00Fh,001h,080h
|
||
|
db 080h,02Eh,001h,000h,00Eh,060h,080h,033h,001h,000h,00Eh,061h,081h,061h,083h,02Eh
|
||
|
db 001h,083h,012h,001h,083h,033h,001h,080h,083h,035h,001h,009h,000h,000h,000h,000h
|
||
|
db 006h,000h,001h,000h,083h,016h,001h,080h,080h,02Eh,001h,000h,00Eh,060h,080h,035h
|
||
|
db 001h,000h,00Eh,061h,081h,061h,083h,02Eh,001h,083h,00Dh,001h,083h,031h,001h,080h
|
||
|
db 083h,02Eh,001h,009h,000h,000h,000h,000h,008h,000h,001h,000h,083h,012h,001h,098h
|
||
|
db 00Ah,001h,083h,019h,001h,088h,00Ah,083h,01Eh,001h,081h,061h,083h,012h,001h,080h
|
||
|
db 083h,014h,001h,080h,083h,01Bh,001h,080h,083h,020h,001h,080h,083h,014h,001h,080h
|
||
|
db 009h,000h,000h,000h,000h,008h,000h,001h,000h,083h,012h,001h,081h,061h,083h,019h
|
||
|
db 001h,080h,083h,01Eh,001h,080h,083h,012h,001h,080h,083h,019h,001h,083h,031h,001h
|
||
|
db 083h,01Eh,001h,080h,083h,012h,001h,083h,031h,001h,083h,019h,001h,080h,009h,000h
|
||
|
db 000h,000h,000h,008h,000h,001h,000h,083h,014h,001h,083h,033h,001h,083h,01Bh,001h
|
||
|
db 080h,083h,020h,001h,083h,031h,001h,083h,014h,001h,080h,083h,01Bh,001h,083h,030h
|
||
|
db 001h,083h,020h,001h,080h,083h,014h,001h,083h,031h,001h,083h,01Bh,001h,080h,009h
|
||
|
db 000h,000h,000h,000h,008h,000h,001h,000h,083h,016h,001h,083h,030h,001h,083h,01Dh
|
||
|
db 001h,083h,031h,001h,083h,022h,001h,083h,035h,001h,083h,016h,001h,098h,00Ah,001h
|
||
|
db 083h,01Dh,001h,088h,00Ah,083h,022h,001h,081h,061h,083h,016h,001h,080h,083h,01Dh
|
||
|
db 001h,080h,009h,000h,000h,000h,000h,008h,000h,001h,000h,083h,016h,001h,080h,083h
|
||
|
db 01Dh,001h,080h,083h,022h,001h,080h,083h,016h,001h,080h,083h,018h,001h,080h,083h
|
||
|
db 01Dh,001h,080h,083h,011h,001h,080h,083h,018h,001h,080h,009h,000h,000h,000h,000h
|
||
|
db 008h,000h,001h,000h,083h,016h,001h,083h,030h,001h,083h,01Dh,001h,083h,031h,001h
|
||
|
db 083h,019h,001h,083h,02Eh,001h,083h,016h,001h,098h,00Ah,001h,083h,01Dh,001h,088h
|
||
|
db 00Ah,083h,019h,001h,081h,061h,083h,016h,001h,080h,083h,01Dh,001h,080h,0F1h,000h
|
||
|
db 000h,000h
|
||
|
xm_unused_001 LABEL BYTE
|
||
|
|
||
|
; The following 23 bytes are not used.
|
||
|
; So, let's place the MessageBox text and caption instead.
|
||
|
; UI text messages.
|
||
|
msg_txt db "uFMOD ruleZ!"
|
||
|
msg_txt_l equ $ - msg_txt
|
||
|
msg_cap db "MASM32",0
|
||
|
err_cap db ":-(",0
|
||
|
|
||
|
org xm_unused_001 + 23
|
||
|
db 001h,000h,012h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
|
||
|
db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
|
||
|
db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
|
||
|
db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
|
||
|
db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
|
||
|
db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
|
||
|
db 000h,000h,000h,000h,000h,000h,000h,000h,040h,000h,008h,000h,02Ch,000h,00Eh,000h
|
||
|
db 008h,000h,018h,000h,016h,000h,020h,000h,008h,000h,02Dh,000h,00Dh,000h,032h,000h
|
||
|
db 004h,000h,03Ch,000h,007h,000h,044h,000h,004h,000h,05Ah,000h,000h,000h,064h,000h
|
||
|
db 000h,000h,06Eh,000h,000h,000h,000h,000h,020h,000h,00Ah,000h,028h,000h,01Eh,000h
|
||
|
db 018h,000h,032h,000h,020h,000h,03Ch,000h,020h,000h,046h,000h,020h,000h,050h,000h
|
||
|
db 020h,000h,05Ah,000h,020h,000h,064h,000h,020h,000h,06Eh,000h,020h,000h,078h,000h
|
||
|
db 020h,000h,082h,000h,020h,000h,009h,006h,001h,002h,004h,002h,003h,005h,001h,000h
|
||
|
db 000h,000h,000h,000h,080h,000h,00Ch,000h,000h,000h,000h,000h,000h,000h,00Ch,000h
|
||
|
db 000h,000h,040h,000h,001h,080h,0F9h,000h,0BFh,000h,0C3h,000h,00Ah,000h,057h,000h
|
||
|
db 06Eh,000h,023h,000h
|
||
|
|
||
|
; ----------------------------------------------------------
|
||
|
; void MessageBoxCB(szCap, lpString, cbString, cbProc);
|
||
|
; ----------------------------------------------------------
|
||
|
|
||
|
; This is similar to a Win32 MessageBox. The box is centered
|
||
|
; on screen. It contains a single-line text message and an
|
||
|
; "OK" button. This function returns when user closes the
|
||
|
; box (via the X button or via the OK button). An optional
|
||
|
; callback subroutine may be specified to be called when no
|
||
|
; events are pending in the event queue.
|
||
|
|
||
|
; NOTE: Doesn't work if you already have defined a window
|
||
|
; in the current process! Doesn't modify the event mask. So,
|
||
|
; make sure keyboard events are enabled before calling this
|
||
|
; function. This function doesn't check the validity of the
|
||
|
; supplied parameters!
|
||
|
|
||
|
; Parameters:
|
||
|
; szCap - A pointer to the ASCIIz string containing the
|
||
|
; caption. A trailing zero char IS required.
|
||
|
; lpString - A pointer to an ASCII string containing a single
|
||
|
; line message to pop up in the box. No trailing
|
||
|
; zero char is required.
|
||
|
; cbString - number of characters in string.
|
||
|
; cbProc - Address of the callback subroutine. Can be NULL.
|
||
|
|
||
|
sOK db "OK"
|
||
|
MessageBoxCB:
|
||
|
; EBP = 0
|
||
|
mov esi,[esp+12] ; cbString
|
||
|
mov edi,[esp+4] ; szCap
|
||
|
|
||
|
; Get screen metrics.
|
||
|
lea eax,[ebp+14]
|
||
|
int 40h
|
||
|
mov ecx,eax
|
||
|
movzx eax,ax
|
||
|
shr ecx,16 ; screen w
|
||
|
xchg eax,edx ; screen h
|
||
|
lea ebx,[esi*2+esi]
|
||
|
lea ebx,[ebx*2+28] ; w = string len * 6 + 28
|
||
|
sub ecx,ebx
|
||
|
shr ecx,1
|
||
|
shl ecx,16
|
||
|
or ebx,ecx
|
||
|
lea ecx,[ebp+52h] ; h = 52h
|
||
|
sub edx,ecx
|
||
|
shr edx,1
|
||
|
shl edx,16
|
||
|
or ecx,edx ; y = (screen h - window h) / 2
|
||
|
mov edx,ebx ; x = (screen w - window w) / 2
|
||
|
|
||
|
_MessageBoxCB_redraw:
|
||
|
; Start redraw.
|
||
|
push edx
|
||
|
lea eax,[ebp+12]
|
||
|
lea ebx,[ebp+1]
|
||
|
int 40h
|
||
|
|
||
|
; Define and draw window.
|
||
|
xor eax,eax
|
||
|
mov ebx,edx ; x, w (ECX: y, h)
|
||
|
mov edx,34C0C0C0h ; style and BG color
|
||
|
int 40h
|
||
|
|
||
|
; Define the OK button.
|
||
|
push esi
|
||
|
lea eax,[ebp+8]
|
||
|
sub ebx,28+0Ah
|
||
|
shr bx,1
|
||
|
shl ebx,16 ; x = (window w - button w) / 2
|
||
|
mov bx,18+0Ah ; w = 18 + 0Ah
|
||
|
mov ecx,001C0012h ; y = 1Ch, h = 12h
|
||
|
lea edx,[ebp+1] ; ID = close
|
||
|
mov esi,0C0C0C0h ; color
|
||
|
int 40h
|
||
|
|
||
|
; Draw the OK label.
|
||
|
lea eax,[ebp+4]
|
||
|
add ebx,90000h ; x = button x + 9
|
||
|
mov bx,22h ; y = 22h
|
||
|
xor ecx,ecx ; style, font and color
|
||
|
mov edx,OFFSET sOK ; string
|
||
|
lea esi,[ebp+2] ; length
|
||
|
int 40h
|
||
|
pop esi
|
||
|
|
||
|
; Draw text string.
|
||
|
lea eax,[ebp+4]
|
||
|
mov ebx,000A000Ah ; x = 0Ah, y = 0Ah
|
||
|
xor ecx,ecx ; style, font and color
|
||
|
mov edx,[esp+12] ; lpString
|
||
|
int 40h
|
||
|
|
||
|
; End redraw.
|
||
|
lea eax,[ebp+12]
|
||
|
lea ebx,[ebp+2]
|
||
|
int 40h
|
||
|
|
||
|
_MessageBoxCB_eventloop:
|
||
|
mov edx,[esp+20] ; cbProc
|
||
|
test edx,edx
|
||
|
lea eax,[ebp+10]
|
||
|
jz _MessageBoxCB_peekevent
|
||
|
|
||
|
; Invoke the callback.
|
||
|
call edx
|
||
|
|
||
|
lea eax,[ebp+23]
|
||
|
lea ebx,[ebp+10] ; wait for at most 0.1 sec
|
||
|
_MessageBoxCB_peekevent:
|
||
|
int 40h
|
||
|
dec eax
|
||
|
js _MessageBoxCB_eventloop
|
||
|
|
||
|
pop edx
|
||
|
jz _MessageBoxCB_redraw
|
||
|
ret
|
||
|
|
||
|
.DATA?
|
||
|
BSS_START LABEL BYTE
|
||
|
db 1020 dup (?)
|
||
|
STACK_B dd ? ; Stack bottom
|
||
|
BSS_END LABEL BYTE
|
||
|
|
||
|
END _START
|