 *************************************************************************
 *         WAVCAP v1.2 plugin description file                           *
 *************************************************************************

   All plugins here has been written on assembler-language , so if you
   don't know what assembler is - you must read "Assembler ABC"
   else you can go straight to part 2 - about plugins.

   I'm really sorry about my english.
   I know it's sux...  Got any question - e-mail me:  hacker@icenet.fi
                                                      (Tarmo Pikaro)
 ************************************************************************
 WARNING !   Plugins are not so easy to undestand (well...  I mean it
             is not for a totals lamers)
             ALSO somekind of assembler must be installed.
 ************************************************************************

      1         Assembler-s ABC
      2         Plugins description
        2.1       General idea
        2.2       Compiling
        2.3       Plugin: making...
          2.31      Starting...
          2.32      Funtions between 0-100h
        2.4       Debugging...

Ŀ
  1         ASSEMBLER-s ABC                                            

  If you know assembler - you can go straight to part 2
  Assembler...

  I am very sorry about my bad, bad English. But it is better than nothing!
If you have some opinion about this FAQ, some question, suggestions or
something else about ASSEMBLER-s ABC or about wavcap, you can e-mail me
to address "mikved@opal.utu.fi"

  Ok...
  Let's see our PC...
         * Lower memory - a space , where all programms are executed...
                          it's 1 MB and you can use about 640 Kb space...
         * High memory  - a space , that have been used to swap -
                          that means , that when there are not enough
                          low memory - we can copy some stuff to high...
                          and later - copy it back...
                          space could be 4-1= 3 MB, 8-1= 7 MB, 16-1= 15 MB
                          or 32-1= 31 MB and so on...
         * disk         - a space , where all data is stored to.
           (floppy/       hard disk could be also used to swapping,
            hard)         BUT it will be much much slower , than
                          swap to high memory.
                          Total space could be any...
                          - floppy disks could be 1.4 MB , 0.7 MB...
                          - hard... - anything goes... (200 MB,1 GB...)


 Lesson A 

   After that lesson you will know what Hex, Binary, Decimal and char mean.


First you have to understand some differents way to mark data(byte).

 All computer signs are devided to 8 bits. One bit have two value,
1 or 0. So one sign, which take one byte space, have 2^8=256 differents
values.
 All 256 value could be expressed by few different way: decimal, hex, binary
and octal.



  -  Char : It is mode which you looking right now! It mean that all 256
values are expressed by characters : A, o, k, 5, &, >, |, ,  and others.



  -  Decimal : It is mode which is expressed by numbers from 0 to 255.
 They are marked with 'd' in the end of number: for example 49d, 90d, 122d
and so on... Usually nobody use 'd', but some do, so you sometime have to
know what does 'd' mean.
     For example 'P' = 80 , 'z' = 122 , 'Z' = 90 , '1' = 49  etc.



  -  Hex : It is mode which is expressed by two character for example
4F, 32, CD, A9 etc.
 They are marked with 'h' in the end of number: for example 4Fh, 32h, CDh
and so on. It is very important so you have to know what 'h' mean. Often
zero(0) is putted before number if it start with A,B,C,D,E or F:
for example 0A5h, 0FFh, 0CDh etc. In C/C++ programming language hex-number
is marked like that : 0xF5, 0x36, 0x2D, 0x01, 0xAC and so on... Also some
programs are using this mark-system, so it is important to know that.

Character could take 16 different value which are:
 0h,1h,2h,3h,4h,5h,6h,7h,8h,9h,Ah, Bh, Ch, Dh, Eh and Fh.  Whose character's
 |  |  |  |  |  |  |  |  |  |  |   |   |   |   |      |      values are  Ŀ
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,   15         <

So if you want to convert from hex to decimal you have to count like that:
              ķ
               Hex    Calculation    Decimal  Char 
                                                   
               4Fh   (4 * 16)  + 15    79      O   
               32h   (3 * 16)  + 2     50      2   
               0CDh  (12 * 16) + 13    205        
               0A9h  (10 * 16) + 9     169        
              Ľ



  -  Binary : As I had said, the characters are devided to 8 bits and one
bit could be 0 or 1. So in binary mode you can change each of the bit.
For example some of the binary number : 00100111b,  10010000b, 11011111b etc.
Binaries are marked by 'b', after number.>>>
    Each bit of course have it's own number. BUT numbers of the bits are not
in same order that you maybe was thinking... And numbers are not starting
by number 1, NO, they start by number 0 !(As always in computer!)

This table will clarify this case :
                                bit number 3
 bit number 7 > 0 0 1 0 0 1 1 1 b
                                
    bit number 6         bit number 0
       bit number 5       bit number 1
           bit number 4     bit number 2

  We need binary in many differents cases, so you will need this.
I suppose you want to know how to count value of the character...
It is pretty easy...
   If bit is "online"(have value 1), it increase to character some value.
So character value depends on how many bits are "online" and which is
number if the bit... This table will clarify this.
        ķ
         number of bit  position of bit  hex value  decimal value 
        Ķ
              0            00000001b        1h           1        
              1            00000010b        2h           2        
              2            00000100b        4h           4        
              3            00001000b        8h           8        
              4            00010000b        10h          16       
              5            00100000b        20h          32       
              6            01000000b        40h          64       
              7            10000000b        80h          128      
        Ľ
As you have maybe notice, if "online" bit number is increased by one -->
character value is twice as many than it was before.
 ͻ
     Q: Wait a minute! Byte's maximum value is 255, but if biggest      
  bit(number 7) is "online", byte's value is just 128!                  
     A: Right, but in that case just one bit is online! And 7 other are 
  "offline". If you put 1 to each bit, you will get:                    
  1h+2h+4h+8h+10h+20h+40h+80h = 0FFh = 1+2+4+8+16+32+64+128 = 255  !!!  
 ͼ
      Example : Convert 10001001b to hex, decimal and char.

    128 = 80h  1 0 0 0 1 0 1 1 b
       8 = 8h      1 = 1h
        2 = 2h 
     80h+8h+2h+1h = 8Bh = 128+8+2+1 = 139 =   Char
                                      
        Hex                   Decimal


 Lesson B 

 Here I will tell you about computer-addresses and about registers.

 All references to computer memory are doing with two addresses. First
address, segment-address, order begin of the memory where memory-evidence
happen. Second address order offset in segment. They are in form XXXX:YYYY,
where XXXX is segment and YYYY is offset. All numbers in XXXX:YYYY form
are always in hex-mode!!!
 You can convert this address to normal memory-address by multiplier segment
by 10h(16) and adding offset.
        Example:  1234h:5678h  -->  1234h*10h = 12340h
                                    12340h+5678h = 179B8h

 You can convert this normal memory-address to segment-address by dividing
segment by 10h(16). Result is segment and division-remainder is offset.
        Example:  Address 12345h give segment-address 1234h and offset 5h.
                  Final address is 1234:5(same as 1234h:5h).

This segmented memory-evidence system make possible many special-situations,
where two fully differents numbers are point to same place.
        Example:  0:1000     100:0   and    80:800










  What is...
   1  bit/binary mode
   2  hex mode (decimal, octal and other modes)
   3  registers
   4  interrupts


   <Here will be finished later...>


Ŀ
  2         PLUGINS DESCRIPTION                                        

  2.1     General idea
  Basicly every plugin is a com-file (executable) , that CANNOT BE
  executed like every normal programm...

  Plugin source is an *.ASM -file - like every assembler's programm
  also some *.INC (include files) - you can find in current dirrectory.
  WCPLG.INC -is a basic include , that has been used in every plugin.
  (This does not mean you have to use it - just it will be easier so.)

  2.2     Compiling

  I assume ,that you have Turbo Assembler or MASM installed
    tasm /m9 MY.ASM                /m9 - means multiple pass -
                                         code will have smaller size...
    tlink /t /x MY.OBJ             /t - to COM-file
                                   /x - no MAP-file... (who needs it anyway ?)
    ***************************************************
    WARNING ! DO NOT EXECUTE ANY PLUGIN AFTER COMPILING
    ***************************************************
    rename MY.COM MY.PLG           rename to plugin file...

  You can also use   PLGMAKE.BAT MY      (your ASM-file without extension)


  2.3     Plugin: making...

  Well...
  Making...
  huh huh...

  Ok - let's take a look at the memory on plugin execution.

  offset         what is there...
   0             here usualy goes some stuff, that
                 is used by dos , BUT I have changed and put here
                 some functions  and parameters , that can
                 be used in your programms (plugins)

                 For example look lower...

   100h (256)    Offsets to functions

                 Function1:
                        ...
                 Function2:
                        ...
   P.S. Maximum that your plugin can take space is 65535-100h=65279

   End Of this segment

 ͻ
  Important note...              
 ͼ
 When your plugin gets control (executes)
 DS=ES=CS , direction flag is cleared
 all others registers could have any value. (ax,bx,cx,dx,si,di,bp,sp,ss=??)

 YOU MAY DESTROY ALL REGISTERS ,EXEPT SS and SP
 so !!!!!!     REMEMBER that every PUSH must always have POP

  2.31      Starting...
            at start of your plugin may have these offsets
            (I said "may have" - this means , that not always
            is nessasary to create all these functions...)
            like this:
                ;Basic 3 offsets
                DW offset To_Check_For_Correct_Format_Function
                DW offset To_Find_First_Function
                DW offset To_Find_Next_Function
                ;Advanced 2 offsets
                DW offset To_Get_Info
                DW offset To_Get_Raw
                

To_Check_For_Correct_Format_Function:
            This routine must check file for correct format
            and return TRUE or FALSE , depending of format.
            P.S.   CurFile - pointer to filename
            Example:    ZIP - detector:
                xor ax,ax              ;AX=0 -just need to be done.
                mov cx,4               ;How many bytes to compare ? - 4
                lds dx,CurFile         ;DS:DX -> to Current filename
                mov di,offset Hdr      ;ES:DI -> to header
                                       ;P.S. - ES is already equal CS
                call Check_header      ;Call our function
                retf                   ;Return from this function
                ;NB !    We haven't returned any value - this is because
                ; Check_header returns it.
ZIPHDR          DB 'PK',03,04          ;Zip - file header

To_Find_First_Function:
To_Find_Next_Function:
            This routines must fill the following block:
;typedef struct{                        Default values:
;   char fname[13];                     "NONAME.FIL"
;   char fattr;                         Attr_None        no attributes
;   long fsize;                         0
;   long pos;                           0
;   int  filetype;                      TYPE_autodetect
;}FILES;
    This block must be in Buffer.
    so - you could use
            les di,Buffer               ;ES:DI - pointer to destination
            mov si,MyStruct             ;DS:SI - to source in plugin
            mov cx,24                   ;How many bytes ?
            rep movsb                   ;Copy...

>>> fname - here must be somekind a filename
            note: '?'-char will be replaced with '%' - so
                  you could use C-language like numbering.
                  (what number is used - is for WAVCAP to decide)
            for instance:
            mark:                       could be:
            aaa?d.fil   (simple)         aaa1.fil    aaa5.fil    aaa100.fil
            bbb?03d.fil (zero-filled)    bbb001.fil  bbb005.fil  bbb100.fil
            note: Filename must be zero ended !
>>> fattr - File attributes...
        Attr_None   - gives you no attributes at all - you
                      you can only watch what files there are inside...
        Attr_Read   - gives file read access -
                      if  Attr_StanRetrMeth - bit is set
                          then file could be retrived by
                               seeking to pos
                               and reading from there fsize-bytes
                          else plugin must have special routine
                               (working on it.)
        Attr_Write  - under construction
        Attr_Execute- under construction
        Attr_StanRetrMeth - standart Retriving Method
                      => fseek to pos
                         read  fsize-bytes
        For example:
            lds si,Buffer
            add si,ToAttr
            mov byte ptr ds:[si],Attr_Read or Attr_Execute or Attr_StanRetrMeth
        -sets Read/Execute/StdRM- attributes
>>> fsize - must be showing file size.
            BUT.
            if Attr_StanRetrMeth is not set - it may have any value -
            but it will be better , if it will be closer to original size.
>>> pos   - needed if Attr_StanRetrMeth is set
            in other case may be used in any purpose.
>>> filetype
            could be:
            TYPE_autodetect
            TYPE_sounds
            TYPE_music
            TYPE_pics
            TYPE_anim
            TYPE_other
            Do I need to say more ?
Must return values:
like this:  mov ax, <return value>
            retf
Return Values:
            0            - all ok - buffer is filled with file information
            NoMoreFiles  - no more files to be found in this file
                           note:  before returning this value
                           you'll must close all files , that
                           you have opened.
            IOErrorState - if there was an error
            StillProcessing   for long scanning - like search for
                           VOC/WAV headers...
            NB ! - if you are returning this value
                   you must set cs:0FCh-pointer to
                   following struct...
    example:
                    mov ax,cs
                    mov ReportState_SEG,ax
                    mov ReportState_OFF,offset InfoAboutScanning
                    ...

   InfoAboutScanning:          ;Here goes your struct...
                    DB 0
    PersentsLeft    DB ?       ;If WAVCAP try to abort you - then
                               ; it will put in PersentsLeft 100
                               ; - so you must have checking routine
                               ; for a 100 %
To_Get_Info:
To_Get_Raw:
   <description will be added later>



  2.32      Funtions between 0-100h

  If you look in WCPLG.INC there you can find this:
    Check_header      equ   dword ptr cs:[0]
    Buffer            equ   dword ptr cs:[4]
    Fopen             equ   dword ptr cs:[8]
    FSeek             equ   dword ptr cs:[12]
    Fread             equ   dword ptr cs:[16]
    Fclose            equ   dword ptr cs:[20]
    CurFile           equ   dword ptr cs:[24]         ;char * to filename
    ReportState       equ   dword ptr cs:[28]

  This means that you can write in to your plugin
       call Fopen
           and it will be compiled like
       call dword ptr cs:[8]
           or
       lds dx,Buffer
           to
       lds dx,dword ptr cs:[4]

  Ok...
  Now full description...
  ͻ
   NAME          WHAT IS IT?   MORE                                  
  ͼ
  Check_header     A subprogramm  This subprogramm open file given at
                                  DS:DX , reads from there CX-bytes
                                  and compares them with string given
                                  at ES:DI

                                  IN-parameters:
                                     AX=0   (for future purposes)
                                     DS:DX  -points to filename
                                     ES:DI  -to string
                                     CX     -bytes to compare
                                  OUT-returns AX=1- if correct
                                              AX=0- if not
                                  Registers destroed: ax,bx,cx,dx,di
                                     almoust all registers...
                                     sorry for that
                   Also have macro  "TestHeader macro FileN,Hdr,Bytes"
                   that you can use like this:

                ;***********************************************
                Check_for_correct_format:
                       TestHeader aFileName,aHeader,4    ;Is it ZIP-archive ?
                       retf                              ;End of our function

                     aFileName    DB 'file2tst.zip',0    ;Some stupid filename
                     aHeader      DB 'PK',3,4            ;ZIP-archive header
                ;***********************************************


  Buffer           A pointer to buffer , that you can use and where
                   you must put info for functions findfirst and findnext
                   also you can read there , anything , that you'll need
                   P.S. BufferSize        equ   8000
                   means that in this buffer are 8 Kb space...

  Fopen            uses DOS funktion 3Dh to open a file for a reading only
                   Fopen / Fseek / Fread - are not very useful functions -
                   if you wanna open more , that 1 file - you'll must use
                   DOS interrupt.
                   ;   mov ax,3D00h
                   ;   int 21h
                   ;   jc Retfloc
                   ;   mov cs:[OFhandl],ax
                   ; Retfloc:
                   ;   retf
                                              IN: DS:DX -> to filename
                                             OUT: Carry flag - if cannot open
                                              On sucess - handle returned in AX
                                              P.S. You don't have to remember
                                              handle !
                                             Registers destroed:
                                                user: DS,DX
                                                sys:  AX

  Fseek            Move read / write position.
                                              IN:   CX:DX - position.
                                                AL - mode:
                                                SEEK_SET=0 - from start of file
                                                SEEK_CUR=1 - from current position
                                                SEEK_END=2 - from end of file
                                              OUT:  DX:AX - new position
                                                    carry flag set if error
                                              Registers destroed:
                                                user: CX,DX
                                                sys:  AX

  Fread            Read from file
                                              IN:   DS:DX - pointer to where
                                                you wanna read
                                                CX - how mush bytes...
                                              OUT:  carry flag set on error
                                                    AX - how much bytes actually
                                              readed (if AX=0 - end of file has
                                              been reached)
                                              Registers destroed:
                                                user: DS,DX,CX
                                                sys:  BX,AX
  Fclose           Closes your file handle
                   You can run this function
                   as many times you wanna to - because
                   after file has been closed
                   it don't have to do it again.
                   NB !!!!!!    IT is VERY important
                   to close file - because if you won't
                   WAVCAP after few scans will give you
                   "Cannot open file"-error
                   (too many file handles...)
                                              IN:   nothing
                                              OUT:  nothing
                                              Registers destroed:
                                                user: -
                                                sys:  AX,BX

  CurFile          A pointer to filename , that have
                   been currently found by WAVCAP
                   for example you can use:
                       lds dx,CurFile
                       call Fopen
                       jc IO_Error

  FGetbytes        Read bytes from file some     IN:  DS:SI - pointer , where
                   position , restoring after         to read
                   reading original position          CX- bytes
                                                      ES:DI pointer to 4 bytes long
                                                      position , where you must to read
                                              OUT: carry if error
                                              Registers destroed:
                                                      user: DS,SI,CX,ES,DI
                                                      sys:  AX,BX,CX,DX,SI,DI
  2.4       Debugging...

     How can you debug your plugin ?
     well - it's very simple...
     you must insert into your plugin at start of routine,
     that must be debugged "int 3" - this works like
     breakpoint in turbo debugger.

     and then just run wavcap with Turbo debugger.

     when "int 3" will be executed turbo debugger halts on it.
     Cool - isn't it ?

     It is VERY recomend for you to put "int 3" , if you have
     just have created your plugin.

     P.S. Look in other plugins - there you can see
     some "int 3" - sometimes - I forgot them...  huh huh...

