/programs/media/ac97snd/ac97snd/ac97snd.vcproj |
---|
0,0 → 1,265 |
<?xml version="1.0" encoding="windows-1251"?> |
<VisualStudioProject |
ProjectType="Visual C++" |
Version="8,00" |
Name="ac97snd" |
ProjectGUID="{5146AAEE-C15C-47C5-A245-64050C820145}" |
RootNamespace="ac97snd" |
Keyword="Win32Proj" |
> |
<Platforms> |
<Platform |
Name="Win32" |
/> |
</Platforms> |
<ToolFiles> |
<ToolFile |
RelativePath="../fasm.rules" |
/> |
</ToolFiles> |
<Configurations> |
<Configuration |
Name="Debug|Win32" |
OutputDirectory="$(SolutionDir)$(ConfigurationName)" |
IntermediateDirectory="$(ConfigurationName)" |
ConfigurationType="1" |
CharacterSet="2" |
WholeProgramOptimization="1" |
> |
<Tool |
Name="VCPreBuildEventTool" |
/> |
<Tool |
Name="VCCustomBuildTool" |
/> |
<Tool |
Name="FASM" |
/> |
<Tool |
Name="VCXMLDataGeneratorTool" |
/> |
<Tool |
Name="VCWebServiceProxyGeneratorTool" |
/> |
<Tool |
Name="VCMIDLTool" |
/> |
<Tool |
Name="VCCLCompilerTool" |
Optimization="1" |
OmitFramePointers="true" |
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" |
MinimalRebuild="false" |
ExceptionHandling="0" |
BasicRuntimeChecks="0" |
RuntimeLibrary="0" |
StructMemberAlignment="1" |
BufferSecurityCheck="false" |
FloatingPointModel="2" |
UsePrecompiledHeader="0" |
WarningLevel="3" |
Detect64BitPortabilityProblems="false" |
DebugInformationFormat="0" |
/> |
<Tool |
Name="VCManagedResourceCompilerTool" |
/> |
<Tool |
Name="VCResourceCompilerTool" |
/> |
<Tool |
Name="VCPreLinkEventTool" |
/> |
<Tool |
Name="VCLinkerTool" |
AdditionalDependencies="$(OutDir)\mpg.lib $(OutDir)\sound.lib" |
LinkIncremental="1" |
GenerateManifest="false" |
IgnoreAllDefaultLibraries="true" |
GenerateDebugInformation="false" |
SubSystem="1" |
OptimizeReferences="2" |
EnableCOMDATFolding="2" |
OptimizeForWindows98="1" |
EntryPointSymbol="crtStartUp" |
BaseAddress="0x00000000" |
MergeSections=".rdata=.text " |
TargetMachine="1" |
FixedBaseAddress="2" |
/> |
<Tool |
Name="VCALinkTool" |
/> |
<Tool |
Name="VCManifestTool" |
/> |
<Tool |
Name="VCXDCMakeTool" |
/> |
<Tool |
Name="VCBscMakeTool" |
/> |
<Tool |
Name="VCFxCopTool" |
/> |
<Tool |
Name="VCAppVerifierTool" |
/> |
<Tool |
Name="VCWebDeploymentTool" |
/> |
<Tool |
Name="VCPostBuildEventTool" |
/> |
</Configuration> |
<Configuration |
Name="Release|Win32" |
OutputDirectory="$(SolutionDir)$(ConfigurationName)" |
IntermediateDirectory="$(ConfigurationName)" |
ConfigurationType="1" |
CharacterSet="2" |
WholeProgramOptimization="1" |
> |
<Tool |
Name="VCPreBuildEventTool" |
/> |
<Tool |
Name="VCCustomBuildTool" |
/> |
<Tool |
Name="FASM" |
/> |
<Tool |
Name="VCXMLDataGeneratorTool" |
/> |
<Tool |
Name="VCWebServiceProxyGeneratorTool" |
/> |
<Tool |
Name="VCMIDLTool" |
/> |
<Tool |
Name="VCCLCompilerTool" |
Optimization="2" |
EnableIntrinsicFunctions="true" |
FavorSizeOrSpeed="1" |
OmitFramePointers="true" |
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" |
ExceptionHandling="0" |
RuntimeLibrary="0" |
StructMemberAlignment="1" |
BufferSecurityCheck="false" |
FloatingPointModel="2" |
UsePrecompiledHeader="0" |
WarningLevel="3" |
Detect64BitPortabilityProblems="false" |
DebugInformationFormat="0" |
/> |
<Tool |
Name="VCManagedResourceCompilerTool" |
/> |
<Tool |
Name="VCResourceCompilerTool" |
/> |
<Tool |
Name="VCPreLinkEventTool" |
/> |
<Tool |
Name="VCLinkerTool" |
AdditionalDependencies="$(OutDir)\sound.lib $(OutDir)\mpg.lib" |
LinkIncremental="1" |
GenerateManifest="false" |
IgnoreAllDefaultLibraries="true" |
GenerateDebugInformation="false" |
SubSystem="1" |
LargeAddressAware="1" |
TerminalServerAware="1" |
Driver="0" |
OptimizeReferences="2" |
EnableCOMDATFolding="2" |
EntryPointSymbol="crtStartUp" |
BaseAddress="0x00000000" |
MergeSections=".rdata=.text " |
TargetMachine="1" |
FixedBaseAddress="2" |
Profile="false" |
/> |
<Tool |
Name="VCALinkTool" |
/> |
<Tool |
Name="VCManifestTool" |
/> |
<Tool |
Name="VCXDCMakeTool" |
/> |
<Tool |
Name="VCBscMakeTool" |
/> |
<Tool |
Name="VCFxCopTool" |
/> |
<Tool |
Name="VCAppVerifierTool" |
/> |
<Tool |
Name="VCWebDeploymentTool" |
/> |
<Tool |
Name="VCPostBuildEventTool" |
/> |
</Configuration> |
</Configurations> |
<References> |
</References> |
<Files> |
<Filter |
Name="Source Files" |
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" |
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" |
> |
<File |
RelativePath=".\ac97wav.c" |
> |
</File> |
<File |
RelativePath=".\crt.c" |
> |
</File> |
<File |
RelativePath=".\k_lib.asm" |
> |
</File> |
</Filter> |
<Filter |
Name="Header Files" |
Filter="h;hpp;hxx;hm;inl;inc;xsd" |
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" |
> |
<File |
RelativePath=".\ac97wav.h" |
> |
</File> |
<File |
RelativePath=".\crt.h" |
> |
</File> |
<File |
RelativePath="..\kolibri.h" |
> |
</File> |
<File |
RelativePath="..\sound.h" |
> |
</File> |
</Filter> |
<Filter |
Name="Resource Files" |
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" |
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" |
> |
</Filter> |
</Files> |
<Globals> |
</Globals> |
</VisualStudioProject> |
/programs/media/ac97snd/ac97snd/ac97wav.c |
---|
0,0 → 1,722 |
// |
// This file is part of the AC97 mp3 player. |
// (C) copyright Serge 2006 |
// email: infinity_sound@mail.ru |
// |
// 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. |
#include "../kolibri.h" |
#include "string.h" |
#include "ac97wav.h" |
#include "../mpg/mpg123.h" |
#include "../sound.h" |
typedef struct |
{ |
int sender; |
int size; |
int code; |
char data[1]; |
} IPC; |
int ipc_client = 0; |
#define MP3_ERROR_OUT_OF_BUFFER 5 |
int m_last_error; |
void _stdcall thread_proc(void *param); |
void _stdcall create_thread(void *proc, void *param, int stack_size); |
void _stdcall init_ipc(void); |
void _stdcall send_ipc(int dst, DWORD code); |
IPC * _stdcall recieve_ipc(void); |
void touch(char *buf, int size); |
int mp3FindSync(byte* buf, int size, int* sync); |
int stream_read_raw(struct reader *rd,unsigned char *buf, int size); |
char *fname; |
struct reader rd; |
struct frame fr; |
void draw_window(); |
void draw_progress_bar(); |
void do_ipc(); |
void exit(); |
DWORD hDrv; |
DWORD hSound; |
SNDBUF hBuff; |
volatile int snd_init=0; |
CTRL_INFO info; |
FILEINFO fileinfo; |
int m_vol; |
int l_vol=-700; //-7db |
int r_vol=-700; |
int pan =0; |
DWORD status; |
DWORD offset; |
DWORD first_sync; |
unsigned char *testbuff; |
unsigned char *outbuf; |
unsigned char *inpbuf; |
unsigned char *outPtr; |
int inpsize; |
int outsize; |
int outremain; |
int totalout; |
int done; |
char path[1024]; |
char header[] = "AC97 MP3 player"; |
char buttons_text[]=" Play Stop << >> Vol- Vol+"; |
void (*snd_play)(); |
int main(int argc, char *argv[]) //int argc, char *argv[]) |
{ |
int err; |
int ver; |
int evnt; |
int key; |
int pos; |
int msg; |
int cnt; |
IPC *incom; |
_asm |
{ |
mov eax, 40 |
mov ebx, 0x47 ;recieve ipc |
int 0x40 |
mov eax, 66 |
mov ebx, 1 |
mov ecx, 1 |
int 0x40 |
}; |
init_ipc(); |
InitHeap(0); |
if(err = InitSound(&ver)) |
{ debug_out_str("Sound service not installed\n\r"); |
return 0; |
} |
if( (SOUND_VERSION>(ver&0xFFFF)) || |
(SOUND_VERSION<(ver >> 16))) |
{ debug_out_str("Sound service version mismatch\n\r"); |
return 0; |
} |
make_decode_tables(32767); |
init_layer2(); |
init_layer3(32); |
fr.single = -1; |
outremain = 0x40000 ; |
if( !(outbuf=UserAlloc(outremain))) |
return 0; |
touch(outbuf, outremain); |
if ( !(testbuff=UserAlloc(4096))) |
return 0; |
if (! (inpbuf=UserAlloc(0x10000))) |
return 0; |
touch(inpbuf, 0x10000); |
create_reader(&rd, inpbuf, 0x10000); |
fname = argv[1]; |
if(get_fileinfo(fname, &fileinfo)==FILE_NOT_FOUND) |
{ |
_asm |
{ |
mov eax, 23 |
mov ebx, 100 |
int 0x40 |
mov [msg], eax |
} |
if (msg != 7) |
{ |
debug_out_str("\n\rfile not found\n\r"); |
return 0; |
}; |
incom = recieve_ipc(); |
if(incom->code != 'CNCT') |
{ |
debug_out_str("\n\rinvalid ipc code\n\r"); |
status = ST_EXIT; |
return 0; |
}; |
ipc_client = incom->sender; |
send_ipc(ipc_client,'CNCT'); |
}; |
snd_init=0; |
create_thread(thread_proc, 0, 4096); |
for(snd_init=0,cnt=100; (snd_init==0)&&(cnt!=0); cnt--) |
delay(10); |
if (!snd_init) |
return 0; |
draw_window(); |
while(1) |
{ if(status==ST_PLAY) |
{ draw_progress_bar(); |
evnt = wait_for_event(80); |
} |
else |
evnt = wait_for_event_infinite(); |
switch(evnt) |
{ |
case EV_REDRAW: |
draw_window(); |
break; |
case EV_KEY: |
if(!get_key(&key)) |
{ |
switch(key) |
{ case 0xE0: |
case 0xE1: |
break; |
default: |
switch (key) |
{ |
case 0x01: //Esc |
status = ST_EXIT; |
exit(); |
break; |
case 0x47: //Home |
if(l_vol < 0) |
{ l_vol+=100; |
r_vol+=100; |
SetVolume(hBuff,l_vol,r_vol); |
}; |
break; |
case 0x4F: //End |
if(l_vol > -10000) |
{ l_vol-=100; |
r_vol-=100; |
SetVolume(hBuff,l_vol,r_vol); |
}; |
break; |
case 0x53: |
if(pan > -10000) |
{ pan -=100; |
SetPan(hBuff,pan); |
}; |
break; |
case 0x51: |
if(pan < 10000) |
{ pan +=100; |
SetPan(hBuff,pan); |
}; |
break; |
} |
}; |
}; |
break; |
case EV_BUTTON: |
switch(get_button_id()) |
{ case 1: |
status = ST_EXIT; |
exit(); |
break; |
case 0x10: |
status = ST_PLAY; |
continue; |
case 0x11: |
status = ST_STOP; |
break; |
// case 0x12: |
// case 0x13: |
case 0x14: |
if(l_vol > -10000) |
{ |
l_vol-=100; |
r_vol-=100; |
SetVolume(hBuff,l_vol,r_vol); |
}; |
break; |
case 0x15: |
if(l_vol < 0) |
{ l_vol+=100; |
r_vol+=100; |
SetVolume(hBuff,l_vol,r_vol); |
}; |
break; |
case 0x30: |
if(status==ST_DONE) |
break; |
pos = (GetMousePos(REL_WINDOW)>>16)-7; |
offset = ((fileinfo.size-44)/286*pos+44)&0xFFFFFFFC; |
set_reader(&rd, offset); |
draw_progress_bar(); |
break; |
}; |
break; |
case EV_IPC: |
do_ipc(); |
break; |
}; |
}; |
return 0; |
}; |
void draw_window() |
{ |
BeginDraw(); |
DrawWindow(100,100,299,72,0x404040,3,0,0,0); |
make_button(7,24,45,13, 0x10|BT_NORMAL,0x808080); |
make_button(56,24,45,13, 0x11|BT_NORMAL,0x808080); |
make_button(104,24,45,13, 0x12|BT_NORMAL,0x808080); |
make_button(152,24,45,13, 0x13|BT_NORMAL,0x808080); |
make_button(200,24,45,13, 0x14|BT_NORMAL,0x808080); |
make_button(248,24,45,13, 0x15|BT_NORMAL,0x808080); |
make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,0x404040); |
draw_bar(7,41,286,11,0x404040); |
draw_bar(7,55,286,11,0x404040); |
write_text(12,58,0x004000|FONT0, fname, strlen(fname)); |
write_text(11,57,0x00FF20|FONT0, fname, strlen(fname)); |
write_text(8,8,0xFFFFFF|FONT0, header, strlen(header)); |
write_text(12,28,0x404040|FONT0,buttons_text,strlen(buttons_text)); |
write_text(11,27,0xA0FFA0|FONT0,buttons_text,strlen(buttons_text)); |
EndDraw(); |
}; |
void draw_progress_bar() |
{ DWORD x; |
x = 287.0f * (float)(rd.filepos-rd.strremain)/(float)fileinfo.size; |
if(x==0) return; |
draw_bar(7,41,x,11,0xA0A0A0); |
draw_bar(x+7,41,287-x,11,0x404040); |
}; |
void debug_out_str(char* str) |
{ |
while (*str != 0) |
{ |
debug_out(*str); |
str++; |
} |
} |
void touch(char *buf, int size) |
{ int i; |
char a; |
for ( i = 0;i < size; i+=4096) |
a = buf[i]; |
}; |
DWORD test_mp3(char *buf) |
{ unsigned long hdr; |
WAVEHEADER whdr; |
while (1) |
{ if(rd.filepos > 102400) |
return 0; |
if(!rd.head_read(&rd,&hdr)) |
return 0; |
if(!decode_header(&fr,hdr)) |
{ |
if((hdr & 0xffffff00) == 0x49443300) |
{ |
int id3length = 0; |
id3length = parse_new_id3(&rd, hdr); |
continue; |
}; |
rd.strpos-=3; |
rd.stream-=3; |
rd.strremain+=3; |
continue; |
}; |
break; |
}; |
first_sync = rd.filepos-rd.strremain-4; |
whdr.riff_id = 0x46464952; |
whdr.riff_format = 0x45564157; |
whdr.wFormatTag = 0x01; |
whdr.nSamplesPerSec = freqs[fr.sampling_frequency]; |
whdr.nChannels = 2; //mpginfo.channels; |
whdr.wBitsPerSample = 16; |
return test_wav(&whdr); |
}; |
void play_mp3() |
{ char *outPtr; |
int totalout; |
int outcount; |
fr.down_sample_sblimit = 32; |
fr.single = -1; |
reset_mpg(); |
outPtr = outbuf; |
totalout=0; |
done = 0; |
outremain=0x40000; |
memset(outbuf,0,0x40000); |
set_reader(&rd, 0); //;first_sync); |
while(1) |
{ if(status!=ST_PLAY) |
break; |
for(;;) |
{ outcount = 0; |
if( !read_frame(&rd, &fr)) |
{ done = 1; |
break; |
}; |
fr.do_layer(&fr, outPtr,&outcount); |
outPtr+= outcount; |
totalout+=outcount; |
outremain-=outcount; |
if(outremain < outcount*2) |
break; |
}; |
if(done) |
{ if(totalout < 4096) |
{ memset(outPtr,0,4096-totalout); |
totalout = 4096; |
}; |
} |
else if(totalout < 8192) continue; |
outPtr = outbuf; |
while (totalout >= 4096) |
{ |
WaveOut(hBuff,outPtr,4096); |
if(status!=ST_PLAY) |
{ StopBuffer(hBuff); |
return; |
}; |
totalout-=4096; |
outPtr+=4096; |
outremain+=4096; |
}; |
if(done) |
{ status = ST_STOP; |
if( ipc_client) |
send_ipc(ipc_client,'DONE'); |
return; |
} |
memmove(outbuf,outPtr, totalout); |
outPtr = outbuf+totalout; |
}; |
}; |
int play_track(char *path) |
{ |
DWORD fmt; |
DWORD r_bytes; |
int retval; |
int err; |
// int err; |
retval = ST_DONE; |
get_fileinfo(path, &fileinfo); |
offset = 0; |
err=read_file (path,testbuff,0,2048,&r_bytes); |
if (err) |
return ST_DONE; |
init_reader(&rd,path); |
fmt = test_wav((WAVEHEADER*)testbuff); |
if (fmt != 0) |
{ |
snd_play = &play_wave; |
set_reader(&rd, 44); |
retval = ST_PLAY; |
} |
else |
{ fmt = test_mp3(testbuff); |
if(fmt ==0) |
return ST_DONE; |
snd_play = &play_mp3; |
outremain = 0x40000; |
retval = ST_PLAY; |
}; |
SetFormat(hBuff, fmt); |
return retval; |
}; |
void play_wave() |
{ int retval; |
set_reader(&rd,44); |
retval = 0; |
while(1) |
{ |
if(status!=ST_PLAY) |
break; |
if( !stream_read_raw(&rd,outbuf,32768)) |
{ done = 1; |
break; |
}; |
WaveOut(hBuff,outbuf,32768); |
}; |
if(status != ST_EXIT) |
status = ST_STOP; |
}; |
void snd_stop() |
{ |
StopBuffer(hBuff); |
}; |
void do_ipc() |
{ |
IPC *incom; |
incom = recieve_ipc(); |
switch(incom->code) |
{ |
case 'PLAY': |
fname = incom->data; |
status = ST_TRACK; |
return; |
case 'STOP': |
status = ST_STOP; |
return; |
case 'EXIT': |
status = ST_EXIT; |
exit(); |
}; |
}; |
void _stdcall thread_proc(void *param) |
{ |
int err; |
if (err = CreateBuffer(PCM_ALL|PCM_OUT,0, &hBuff)) |
{ |
debug_out_str("create buffer return error\n\r"); |
exit(); |
}; |
SetVolume(hBuff,l_vol,r_vol); |
GetVolume(hBuff,&l_vol,&r_vol); |
// debug_out_hex(l_vol); |
// debug_out_str("\n\r"); |
// debug_out_hex(r_vol); |
// debug_out_str("\n\r"); |
if(fname[0] !='/0') |
status = play_track(fname); |
debug_out_str("\n\rPlay file "); |
debug_out_str(fname); |
debug_out_str("\n\r"); |
snd_init = 1; |
while(1) |
{ delay(10); |
switch(status) |
{ |
case ST_TRACK: |
strcpy(path, fname); |
status = play_track(fname); |
if( ipc_client & (status == ST_DONE)) |
{ send_ipc(ipc_client,'DONE'); |
continue; |
}; |
case ST_PLAY: |
snd_play(); |
continue; |
case ST_STOP: |
StopBuffer(hBuff); |
status = ST_DONE; |
continue; |
case ST_EXIT: |
StopBuffer(hBuff); |
DestroyBuffer(hBuff); |
if (ipc_client) |
send_ipc(ipc_client,'EXIT'); |
return; |
}; |
}; |
}; |
void delay (int val) |
{ |
_asm |
{ mov eax,5 |
mov ebx, [val] |
int 0x40 |
}; |
} |
int wait_for_event(int time) |
{ int retval; |
_asm |
{ mov eax,23 |
mov ebx,[time] |
int 0x40 |
mov [retval], eax |
}; |
return retval; |
}; |
int wait_for_event_infinite() |
{ int retval; |
_asm |
{ mov eax,10 |
int 0x40 |
mov [retval], eax |
}; |
return retval; |
}; |
void BeginDraw() |
{_asm |
{ mov eax,12 |
mov ebx, 1 |
int 0x40 |
}; |
}; |
void EndDraw() |
{ _asm |
{ mov eax,12 |
mov ebx, 2 |
int 0x40 |
}; |
}; |
///********* |
void *memmove ( void * dst, void * src, int count) |
{ void *ret; |
ret = dst; |
if (dst <= src || (char *)dst >= ((char *)src + count)) |
{ |
while (count--) |
{ *(char *)dst = *(char *)src; |
dst = (char *)dst + 1; |
src = (char *)src + 1; |
} |
} |
else |
{ |
dst = (char *)dst + count - 1; |
src = (char *)src + count - 1; |
while (count--) |
{ *(char *)dst = *(char *)src; |
dst = (char *)dst - 1; |
src = (char *)src - 1; |
} |
} |
return ret; |
}; |
//**********/ |
void * __cdecl mem_cpy(void * dst,const void * src,size_t count) |
{ void * ret = dst; |
while (count--) |
{ *(char *)dst = *(char *)src; |
dst = (char *)dst + 1; |
src = (char *)src + 1; |
}; |
return(ret); |
} |
// debug_out_str(formats[fmt]); |
// debug_out_str("\x0D\x0A\x00"); |
// debug_out_str("pci cmd: "); |
// debug_out_hex(info.pci_cmd); |
// debug_out_str("\x0D\x0A\x00"); |
// debug_out_str("irq line: "); |
// debug_out_hex(info.irq); |
// debug_out_str("\x0D\x0A\x00"); |
// debug_out_str("global control: "); |
// debug_out_hex(info.glob_cntrl); |
// debug_out_str("\x0D\x0A\x00"); |
// debug_out_str("global status: "); |
// debug_out_hex(info.glob_sta); |
// debug_out_str("\x0D\x0A\x00"); |
// call _print_volume |
// debug_out_hex(whdr.nChannels); |
// debug_out_str("\x0D\x0A\x00"); |
// debug_out_hex(whdr.nSamplesPerSec); |
// debug_out_str("\x0D\x0A\x00"); |
// debug_out_hex(fmt); |
// debug_out_str("\x0D\x0A\x00"); |
/programs/media/ac97snd/ac97snd/ac97wav.h |
---|
0,0 → 1,32 |
// |
// This file is part of the AC97 mp3 player. |
// (C) copyright Serge 2006 |
// email: infinity_sound@mail.ru |
// |
// 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. |
#define ST_DONE 0x0 |
#define ST_PLAY 0x1 |
#define ST_EXIT 0x2 |
#define ST_STOP 0x4 |
#define ST_TRACK 0x5 |
DWORD test_mp3(char *buf); |
//void (*snd_play)(); |
void wave_out(char* buff); |
void play_wave(); |
void play_mp3(); |
void snd_stop(); |
/programs/media/ac97snd/ac97snd/crt.c |
---|
0,0 → 1,74 |
#include "crt.h" |
#define atexitBufferSize 32 |
char pureCallMessage[] = "PURE function call!"; |
char *__argv[2]; |
int __argc; |
void (__cdecl *atExitList[atexitBufferSize])(); |
int atExitFnNum = 0; |
int main(int argc, char *argv[]); |
void exit() |
{ int i; |
for ( i = atExitFnNum - 1; i >= 0; i-- ) |
atExitList[i](); |
__asm |
{ |
mov eax, -1 |
int 0x40 |
}; |
}; |
int __cdecl atexit( void (__cdecl *func )( void )) |
{ |
// |
if ( atExitFnNum < atexitBufferSize ) |
{ |
// |
atExitList[atExitFnNum++] = func; |
return 0; |
} |
else |
{ |
return 1; |
} |
} |
int __cdecl _purecall() |
{ |
exit(); |
return 0; |
} |
#pragma section(".CRT$XCA",long,read,write) |
#pragma section(".CRT$XCZ",long,read,write) |
typedef void (__cdecl *_PVFV)(void); |
__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[1] = { 0 }; |
__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[1] = { 0 }; |
// |
#pragma comment(linker, "/merge:.CRT=.rdata") |
// |
void crtStartUp() |
{_PVFV *pbegin; |
_asm {fninit}; |
for ( pbegin = __xc_a; pbegin < __xc_z; pbegin++ ) |
{ |
// |
if ( *pbegin != 0 ) |
(**pbegin)(); |
} |
__argc = 2; |
__argv[0] = *((char **)0x20); |
__argv[1] = *((char **)0x1C); |
main(__argc, __argv); |
exit(); |
} |
/programs/media/ac97snd/ac97snd/crt.h |
---|
0,0 → 1,13 |
typedef unsigned __int32 Dword; |
typedef unsigned __int16 Word; |
typedef unsigned __int8 Byte; |
typedef unsigned __int32 size_t; |
extern char *__argv[2]; |
void crtStartUp(); |
int __cdecl _purecall(); |
int __cdecl atexit( void (__cdecl *func )( void )); |
void exit(); |
int main(); |
/programs/media/ac97snd/ac97snd/k_lib.asm |
---|
0,0 → 1,545 |
format MS COFF |
include "proc32.inc" |
section '.text' code readable executable |
public _InitHeap@4 |
public _UserAlloc@4 |
public _CreateThread@8 |
public _GetMousePos@4 |
public _get_fileinfo@8 |
public _read_file@20 |
public _get_key@4 |
public _get_button_id |
public _DrawWindow@36 |
public _make_button@24 |
public _draw_bar@20 |
public _write_text@20 |
public _debug_out@4 |
public _debug_out_hex@4 |
public _create_thread@12 |
public _init_ipc@0 |
public _recieve_ipc@0 |
public _send_ipc@8 |
public _memset |
struc FILEIO |
{ .cmd dd ? |
.offset dd ? |
dd ? |
.count dd ? |
.buff dd ? |
db ? |
.name dd ? |
}; |
align 4 |
_create_thread@12: |
.thr_proc equ esp+4 |
.param equ esp+8 |
.stack_size equ esp+12 |
mov eax, 68 |
mov ebx, 12 |
mov ecx, [.stack_size] |
add ecx, 4095 |
and ecx, -4096 |
int 0x40 |
test eax, eax |
jz .fail |
lea edx, [eax+ecx-12] |
mov [edx], dword .exit_point |
mov ebx, [.param] |
mov [edx+4], ebx |
mov [edx+8], ecx |
mov eax, 51 |
mov ebx, 1 |
mov ecx, [.thr_proc] |
int 0x40 |
ret 12 |
.fail: |
not eax |
ret 12 |
align 4 |
.exit_point: |
pop ecx |
mov eax, 68 |
mov ebx, 13 |
int 0x40 |
mov eax, -1 |
int 0x40 |
restore .thr_proc |
restore .param |
restore .stack_size |
align 4 |
proc _get_button_id |
mov eax,17 |
int 0x40 |
test al,al |
jnz @F |
shr eax,8 |
ret |
@@: |
xor eax,eax |
dec eax |
ret |
endp |
align 4 |
proc _get_fileinfo@8 stdcall, name:dword, info:dword |
push ebx |
push esi |
push edi |
xor eax, eax |
mov ebx, [name] |
mov ecx, [info] |
mov [fileio.cmd], 5 |
mov [fileio.offset], eax |
mov [fileio.offset+4], eax |
mov [fileio.count], eax |
mov [fileio.buff], ecx |
mov byte [fileio.buff+4], al |
mov [fileio.name], ebx |
mov eax, 70 |
lea ebx, [fileio] |
int 0x40 |
pop edi |
pop esi |
pop ebx |
ret |
endp |
align 4 |
proc _read_file@20 stdcall,name:dword, buff:dword, offset:dword,\ |
count:dword,reads:dword |
push ebx |
push esi |
push edi |
xor eax, eax |
mov ebx, [name] |
mov edx, [offset] |
mov esi, [buff] |
mov edi, [count] |
mov [fileio.cmd], eax |
mov [fileio.offset], edx |
mov [fileio.offset+4], eax |
mov [fileio.count], edi |
mov [fileio.buff], esi |
mov byte [fileio.buff+4], al |
mov [fileio.name], ebx |
mov eax, 70 |
lea ebx, [fileio] |
int 0x40 |
mov esi, [reads] |
test esi, esi |
jz @f |
mov [esi], ebx |
@@: |
pop edi |
pop esi |
pop ebx |
ret |
endp |
align 4 |
proc _get_key@4 stdcall, key:dword |
push ebx |
push ecx |
mov eax, 2 |
int 0x40 |
mov ebx, [key] |
mov ecx, eax |
shr ecx, 8 |
mov [ebx], ecx |
movzx eax, al |
pop ecx |
pop ebx |
ret |
endp |
align 4 |
proc _InitHeap@4 stdcall, heap_size:dword |
push ebx |
mov eax, 68 |
mov ebx, 11 |
mov ecx, [heap_size] |
int 0x40 |
pop ebx |
ret |
endp |
align 4 |
proc _UserAlloc@4 stdcall, alloc_size:dword |
push ebx |
mov eax, 68 |
mov ebx, 12 |
mov ecx, [alloc_size] |
int 0x40 |
pop ebx |
ret |
endp |
align 4 |
proc _CreateThread@8 stdcall, fn:dword, p_stack:dword |
push ebx |
mov eax, 51 |
mov ebx, 1 |
mov ecx, [fn] |
mov edx,[p_stack] |
int 0x40 |
pop ebx |
ret |
endp |
align 4 |
proc _GetMousePos@4 stdcall,rel_type:dword |
push ebx |
mov eax, 37 |
mov ebx, [rel_type] |
int 0x40 |
pop ebx |
ret |
endp |
align 4 |
proc _DrawWindow@36 stdcall, x:dword, y:dword, sx:dword, sy:dword,\ |
workcolor:dword, style:dword, captioncolor:dword,\ |
windowtype:dword, bordercolor:dword |
push ebx edi esi |
mov ebx, [x] |
mov ecx, [y] |
shl ebx, 16 |
shl ecx, 16 |
mov bx, word [sx] |
mov cx, word [sy] |
mov edx,[style] |
shl edx,24 |
add edx,[workcolor] |
mov esi,[windowtype] |
shl esi,24 |
add esi,[captioncolor] |
mov edi,[bordercolor] |
xor eax,eax |
int 0x40 |
pop esi edi ebx |
ret |
endp |
align 4 |
_make_button@24: |
;arg1 - x |
;arg2 - y |
;arg3 - xsize |
;arg4 - ysize |
;arg5 - id |
;arg6 - color |
push ebx esi |
mov ebx,[esp+12] |
shl ebx,16 |
mov bx,[esp+20] |
mov ecx,[esp+16] |
shl ecx,16 |
mov cx,[esp+24] |
mov edx,[esp+28] |
mov esi,[esp+32] |
mov eax,8 |
int 0x40 |
pop esi ebx |
ret 24 |
align 4 |
_draw_bar@20: |
;arg1 - x |
;arg2 - y |
;arg3 - xsize |
;arg4 - ysize |
;arg5 - color |
push ebx |
mov eax,13 |
mov ebx,[esp+8] |
shl ebx,16 |
mov bx,[esp+16] |
mov ecx,[esp+12] |
shl ecx,16 |
mov cx,[esp+20] |
mov edx,[esp+24] |
int 0x40 |
pop ebx |
ret 20 |
_write_text@20: |
;arg1 - x |
;arg2 - y |
;arg3 - color |
;arg4 - text |
;arg5 - len |
push ebx esi |
mov eax,4 |
mov ebx,[esp+12] |
shl ebx,16 |
mov bx,[esp+16] |
mov ecx,[esp+20] |
mov edx,[esp+24] |
mov esi,[esp+28] |
int 0x40 |
pop esi ebx |
ret 20 |
align 4 |
proc _debug_out@4 stdcall, val:dword |
push ebx |
mov ecx,[val] |
mov ebx,1 |
mov eax,63 |
int 0x40 |
pop ebx |
ret |
endp |
align 4 |
proc _debug_out_hex@4 stdcall val:dword |
locals |
count dd ? |
endl |
mov [count], 8 |
.new_char: |
rol [val], 4 |
mov ecx, [val] |
and ecx, 0x0f |
mov cl,byte [__hexdigits+ecx] |
mov eax, 63 |
mov ebx, 1 |
int 0x40 |
dec [count] |
jnz .new_char |
ret |
endp |
align 4 |
_memset: |
mov edx,[esp + 0ch] |
mov ecx,[esp + 4] |
test edx,edx |
jz short toend |
xor eax,eax |
mov al,[esp + 8] |
push edi |
mov edi,ecx |
cmp edx,4 |
jb tail |
neg ecx |
and ecx,3 |
jz short dwords |
sub edx,ecx |
adjust_loop: |
mov [edi],al |
add edi,1 |
sub ecx,1 |
jnz adjust_loop |
dwords: |
mov ecx,eax |
shl eax,8 |
add eax,ecx |
mov ecx,eax |
shl eax,10h |
add eax,ecx |
mov ecx,edx |
and edx,3 |
shr ecx,2 |
jz tail |
cld |
rep stosd |
main_loop_tail: |
test edx,edx |
jz finish |
tail: |
mov [edi],al |
add edi,1 |
sub edx,1 |
jnz tail |
finish: |
mov eax,[esp + 8] |
pop edi |
ret |
toend: |
mov eax,[esp + 4] |
ret |
public _allmul |
_allmul: |
mov eax, [esp+8] |
mov ecx, [esp+16] |
or ecx,eax |
mov ecx, [esp+12] |
jnz .hard |
mov eax, [esp+4] |
mul ecx |
ret 16 |
.hard: |
push ebx |
mul ecx |
mov ebx,eax |
mov eax, [esp+8] |
mul dword [esp+20] |
add ebx,eax |
mov eax,[esp+8] |
mul ecx |
add edx,ebx |
pop ebx |
ret 16 |
align 4 |
_allshr: |
cmp cl,64 |
jae .sign |
cmp cl, 32 |
jae .MORE32 |
shrd eax,edx,cl |
sar edx,cl |
ret |
.MORE32: |
mov eax,edx |
sar edx,31 |
and cl,31 |
sar eax,cl |
ret |
.sign: |
sar edx,31 |
mov eax,edx |
ret |
public __ftol2_sse |
align 4 |
__ftol2_sse: |
push ebp |
mov ebp, esp |
sub esp, 20 |
and esp, 0xFFFFFFF0 |
fld st0 |
fst dword [esp+18] |
fistp qword [esp+10] |
fild qword [esp+10] |
mov edx, [esp+18] |
mov eax, [esp+10] |
test eax, eax |
jz .QnaNZ |
.not_QnaNZ: |
fsubp st1, st0 |
test edx, edx |
jns .pos |
fstp dword [esp] |
mov ecx, [esp] |
xor ecx, 0x80000000 |
add ecx, 0x7FFFFFFF |
adc eax, 0 |
mov edx, [esp+14] |
adc edx, 0 |
jmp .exit |
.pos: |
fstp dword [esp] |
mov ecx, [esp] |
add ecx, 0x7FFFFFFF |
sbb eax, 0 |
jmp .exit |
.QnaNZ: |
mov edx, [esp+14] |
test edx, 0x7FFFFFFF |
jne .not_QnaNZ |
fstp dword [esp+18] |
fstp dword [esp+18] |
.exit: |
leave |
ret |
public __fltused |
__fltused dd 0 |
align 4 |
__hexdigits db '0123456789ABCDEF' |
align 4 |
fileio FILEIO |
align 4 |
_init_ipc@0: |
push ebx |
mov eax, 60 |
mov ebx, 1 |
mov ecx, ipc_buff |
mov edx, (5*4+1024) |
int 0x40 |
pop ebx |
ret |
align 4 |
_recieve_ipc@0: |
mov [ipc_buff.size], 8 |
mov eax, ipc_buff.sender |
ret |
align 4 |
proc _send_ipc@8 stdcall, dst:dword, code:dword |
push ebx |
push esi |
mov eax, 60 |
mov ebx, 2 |
mov ecx, [dst] |
lea edx, [code] |
mov esi, 4 |
int 0x40 |
pop esi |
pop ebx |
ret |
endp |
;align 4 |
;ipc_ctrl: |
; .pid dd ? |
; .size dd 4 |
; .msg dd ? |
align 4 |
ipc_buff: |
.lock dd 0 |
.size dd 8 |
.sender dd ? |
.msg_size dd ? |
.msg dd ? |
.data rb 1024 |
/programs/media/ac97snd/ac97snd/proc32.inc |
---|
0,0 → 1,268 |
; Macroinstructions for defining and calling procedures |
macro stdcall proc,[arg] ; directly call STDCALL procedure |
{ common |
if ~ arg eq |
reverse |
pushd arg |
common |
end if |
call proc } |
macro invoke proc,[arg] ; indirectly call STDCALL procedure |
{ common |
if ~ arg eq |
reverse |
pushd arg |
common |
end if |
call [proc] } |
macro ccall proc,[arg] ; directly call CDECL procedure |
{ common |
size@ccall = 0 |
if ~ arg eq |
reverse |
pushd arg |
size@ccall = size@ccall+4 |
common |
end if |
call proc |
if size@ccall |
add esp,size@ccall |
end if } |
macro cinvoke proc,[arg] ; indirectly call CDECL procedure |
{ common |
size@ccall = 0 |
if ~ arg eq |
reverse |
pushd arg |
size@ccall = size@ccall+4 |
common |
end if |
call [proc] |
if size@ccall |
add esp,size@ccall |
end if } |
macro proc [args] ; define procedure |
{ common |
match name params, args> |
\{ define@proc name,<params \} } |
prologue@proc equ prologuedef |
macro prologuedef procname,flag,parmbytes,localbytes,reglist |
{ if parmbytes | localbytes |
push ebp |
mov ebp,esp |
if localbytes |
sub esp,localbytes |
end if |
end if |
irps reg, reglist \{ push reg \} } |
epilogue@proc equ epiloguedef |
macro epiloguedef procname,flag,parmbytes,localbytes,reglist |
{ irps reg, reglist \{ reverse pop reg \} |
if parmbytes | localbytes |
leave |
end if |
if flag and 10000b |
retn |
else |
retn parmbytes |
end if } |
macro define@proc name,statement |
{ local params,flag,regs,parmbytes,localbytes,current |
if used name |
name: |
match =stdcall args, statement \{ params equ args |
flag = 11b \} |
match =stdcall, statement \{ params equ |
flag = 11b \} |
match =c args, statement \{ params equ args |
flag = 10001b \} |
match =c, statement \{ params equ |
flag = 10001b \} |
match =params, params \{ params equ statement |
flag = 0 \} |
virtual at ebp+8 |
match =uses reglist=,args, params \{ regs equ reglist |
params equ args \} |
match =regs =uses reglist, regs params \{ regs equ reglist |
params equ \} |
match =regs, regs \{ regs equ \} |
match =,args, params \{ defargs@proc args \} |
match =args@proc args, args@proc params \{ defargs@proc args \} |
parmbytes = $ - (ebp+8) |
end virtual |
name # % = parmbytes/4 |
all@vars equ |
current = 0 |
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \} |
macro locals |
\{ virtual at ebp-localbytes+current |
macro label . \\{ deflocal@proc .,:, \\} |
struc db [val] \\{ \common deflocal@proc .,db,val \\} |
struc dw [val] \\{ \common deflocal@proc .,dw,val \\} |
struc dp [val] \\{ \common deflocal@proc .,dp,val \\} |
struc dd [val] \\{ \common deflocal@proc .,dd,val \\} |
struc dt [val] \\{ \common deflocal@proc .,dt,val \\} |
struc dq [val] \\{ \common deflocal@proc .,dq,val \\} |
struc rb cnt \\{ deflocal@proc .,rb cnt, \\} |
struc rw cnt \\{ deflocal@proc .,rw cnt, \\} |
struc rp cnt \\{ deflocal@proc .,rp cnt, \\} |
struc rd cnt \\{ deflocal@proc .,rd cnt, \\} |
struc rt cnt \\{ deflocal@proc .,rt cnt, \\} |
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} |
macro endl |
\{ purge label |
restruc db,dw,dp,dd,dt,dq |
restruc rb,rw,rp,rd,rt,rq |
restruc byte,word,dword,pword,tword,qword |
current = $-(ebp-localbytes) |
end virtual \} |
macro ret operand |
\{ match any, operand \\{ retn operand \\} |
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> |
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} |
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 |
end if \} } |
macro defargs@proc [arg] |
{ common |
if ~ arg eq |
forward |
local ..arg,current@arg |
match argname:type, arg |
\{ current@arg equ argname |
label ..arg type |
argname equ ..arg |
if dqword eq type |
dd ?,?,?,? |
else if tbyte eq type |
dd ?,?,? |
else if qword eq type | pword eq type |
dd ?,? |
else |
dd ? |
end if \} |
match =current@arg,current@arg |
\{ current@arg equ arg |
arg equ ..arg |
..arg dd ? \} |
common |
args@proc equ current@arg |
forward |
restore current@arg |
common |
end if } |
macro deflocal@proc name,def,[val] |
{ common |
match vars, all@vars \{ all@vars equ all@vars, \} |
all@vars equ all@vars name |
forward |
local ..var,..tmp |
..var def val |
match =?, val \{ ..tmp equ \} |
match any =dup (=?), val \{ ..tmp equ \} |
match tmp : value, ..tmp : val |
\{ tmp: end virtual |
initlocal@proc ..var,def value |
virtual at tmp\} |
common |
match first rest, ..var, \{ name equ first \} } |
macro initlocal@proc name,def |
{ virtual at name |
def |
size@initlocal = $ - name |
end virtual |
position@initlocal = 0 |
while size@initlocal > position@initlocal |
virtual at name |
def |
if size@initlocal - position@initlocal < 2 |
current@initlocal = 1 |
load byte@initlocal byte from name+position@initlocal |
else if size@initlocal - position@initlocal < 4 |
current@initlocal = 2 |
load word@initlocal word from name+position@initlocal |
else |
current@initlocal = 4 |
load dword@initlocal dword from name+position@initlocal |
end if |
end virtual |
if current@initlocal = 1 |
mov byte [name+position@initlocal],byte@initlocal |
else if current@initlocal = 2 |
mov word [name+position@initlocal],word@initlocal |
else |
mov dword [name+position@initlocal],dword@initlocal |
end if |
position@initlocal = position@initlocal + current@initlocal |
end while } |
macro endp |
{ purge ret,locals,endl |
finish@proc |
purge finish@proc |
restore regs@proc |
match all,args@proc \{ restore all \} |
restore args@proc |
match all,all@vars \{ restore all \} } |
macro local [var] |
{ common |
locals |
forward done@local equ |
match varname[count]:vartype, var |
\{ match =BYTE, vartype \\{ varname rb count |
restore done@local \\} |
match =WORD, vartype \\{ varname rw count |
restore done@local \\} |
match =DWORD, vartype \\{ varname rd count |
restore done@local \\} |
match =PWORD, vartype \\{ varname rp count |
restore done@local \\} |
match =QWORD, vartype \\{ varname rq count |
restore done@local \\} |
match =TBYTE, vartype \\{ varname rt count |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
rq count+count |
restore done@local \\} |
match , done@local \\{ virtual |
varname vartype |
end virtual |
rb count*sizeof.\#vartype |
restore done@local \\} \} |
match :varname:vartype, done@local:var |
\{ match =BYTE, vartype \\{ varname db ? |
restore done@local \\} |
match =WORD, vartype \\{ varname dw ? |
restore done@local \\} |
match =DWORD, vartype \\{ varname dd ? |
restore done@local \\} |
match =PWORD, vartype \\{ varname dp ? |
restore done@local \\} |
match =QWORD, vartype \\{ varname dq ? |
restore done@local \\} |
match =TBYTE, vartype \\{ varname dt ? |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
dq ?,? |
restore done@local \\} |
match , done@local \\{ varname vartype |
restore done@local \\} \} |
match ,done@local |
\{ var |
restore done@local \} |
common |
endl } |
/programs/media/ac97snd/ac97snd/struct.inc |
---|
0,0 → 1,220 |
;***************************************************************************** |
;* |
;* Open Watcom Project |
;* |
;* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
;* |
;* ======================================================================== |
;* |
;* This file contains Original Code and/or Modifications of Original |
;* Code as defined in and that are subject to the Sybase Open Watcom |
;* Public License version 1.0 (the 'License'). You may not use this file |
;* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
;* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
;* provided with the Original Code and Modifications, and is also |
;* available at www.sybase.com/developer/opensource. |
;* |
;* The Original Code and all software distributed under the License are |
;* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
;* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
;* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
;* NON-INFRINGEMENT. Please see the License for the specific language |
;* governing rights and limitations under the License. |
;* |
;* ======================================================================== |
;* |
;* Description: Structured macros for MASM/WASM. |
;* |
;***************************************************************************** |
__label = 0 |
__depth = 0 |
__inner_loop = 0 |
_guess macro name |
__depth = __depth + 1 |
__label = __label + 1 |
_set __astk,%__depth,__label,<> |
__label = __label + 1 |
_set __estk,%__depth,__label,<> |
ifnb <name> |
name = __label |
endif |
endm |
_quif macro cc,name |
ifnb <name> |
_set __elbl,,name,<> |
_j cc,_l,%__elbl |
else |
_set __albl,,__astk,%__depth |
_j cc,_l,%__albl |
endif |
endm |
_quit macro name |
_quif ,name |
endm |
_admit macro |
_set __albl,,__astk,%__depth |
__label = __label + 1 |
_set __astk,%__depth,__label,<> |
_set __elbl,,__estk,%__depth |
_j ,_l,%__elbl |
_label _l,%__albl |
endm |
_endguess macro |
_set __albl,,__astk,%__depth |
_label _l,%__albl |
_set __elbl,,__estk,%__depth |
_label _l,%__elbl |
__depth = __depth - 1 |
endm |
_loop macro name |
_guess name |
_set __albl,,__astk,%__depth |
_label _m,%__albl |
_set __elbl,,__estk,%__depth |
_label _m,%__elbl |
_set __llbl,%__depth,%__inner_loop,<> |
_set __inner_loop,,%__depth,<> |
endm |
_loopif macro cc,name |
ifnb <name> |
_set __elbl,,name,<> |
_j cc,_m,%__elbl |
else |
_set __albl,,__astk,%__inner_loop |
_j cc,_m,%__albl |
endif |
endm |
_until macro cc |
_set __albl,,__astk,%__depth |
_jn cc,_m,%__albl |
_set __inner_loop,,__llbl,%__depth |
_endguess |
endm |
_endloop macro |
_set __albl,,__astk,%__depth |
_j ,_m,%__albl |
_set __inner_loop,,__llbl,%__depth |
_endguess |
endm |
_if macro cc |
_guess |
_set __albl,,__astk,%__depth |
_jn cc,_l,%__albl |
endm |
_else macro |
_admit |
endm |
_endif macro |
_endguess |
endm |
_set macro base1,ext1,base2,ext2 |
base1&ext1 = base2&ext2 |
endm |
_label macro base,ext |
base&ext: |
endm |
_j macro cc,base,ext |
j&cc base&ext |
endm |
_jn macro cc,base,ext |
jn&cc base&ext |
endm |
jnna macro label |
ja label |
endm |
jnnae macro label |
jae label |
endm |
jnnb macro label |
jb label |
endm |
jnnbe macro label |
jbe label |
endm |
jnnc macro label |
jc label |
endm |
jnne macro label |
je label |
endm |
jnng macro label |
jg label |
endm |
jnnge macro label |
jge label |
endm |
jnnl macro label |
jl label |
endm |
jnnle macro label |
jle label |
endm |
jnno macro label |
jo label |
endm |
jnnp macro label |
jp label |
endm |
jnns macro label |
js label |
endm |
jnnz macro label |
jz label |
endm |
jnpe macro label |
jpo label |
endm |
jnpo macro label |
jpe label |
endm |
j macro label |
jmp label |
endm |
jn macro label |
nop |
endm |
_shl macro reg,count |
add reg,reg |
endm |
_rcl macro reg,count |
adc reg,reg |
endm |