home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / cd32 / cd32-tools / cdxl-1 / asyncxlfile.c next >
C/C++ Source or Header  |  1993-08-12  |  7KB  |  253 lines

  1. /***************************************
  2.           AsyncXLFile.c
  3.  
  4.              930508
  5.  
  6.   Based upon Martin Taillefer's
  7.   asyncio.c - See AmigaMail
  8.   Vol.2 Section 2 P77 for more details.
  9.  
  10. ****************************************/
  11.  
  12. /*
  13.  * COPYRIGHT: Unless otherwise noted, all files are Copyright (c) 1993
  14.  * Commodore-Amiga, Inc.  All rights reserved.
  15.  *
  16.  * DISCLAIMER: This software is provided "as is".  No representations or
  17.  * warranties are made with respect to the accuracy, reliability, performance,
  18.  * currentness, or operation of this software, and all use is at your own risk.
  19.  * Neither commodore nor the authors assume any responsibility or liability
  20.  * whatsoever with respect to your use of this software.
  21.  */
  22.  
  23.  
  24. #include <exec/types.h>
  25. #include <exec/exec.h>
  26. #include <dos/dos.h>
  27. #include <dos/dosextens.h>
  28.  
  29. #include <graphics/gfx.h>
  30.  
  31. #include <hardware/custom.h>
  32. #include <hardware/intbits.h>
  33.  
  34. #include <stdio.h>
  35.  
  36. #include <clib/exec_protos.h>
  37. #include <clib/dos_protos.h>
  38.  
  39. #include <pragmas/exec_pragmas.h>
  40. #include <pragmas/dos_pragmas.h>
  41.  
  42. #include "devices/cd.h"
  43.  
  44. #include "cdxl/asyncXL.h"
  45.  
  46. #include "cdxl/cdxlob.h"
  47.  
  48. #include "cdxl/debugsoff.h"
  49.  
  50. /*    // Uncomment to get debug output turned on
  51. #define KPRINTF
  52. #include "cdxl/debugson.h"
  53. */
  54.  
  55. int kprintf(const char *, ...);
  56. VOID StartAudio( VOID );
  57.  
  58. IMPORT struct Library *DOSBase;
  59. IMPORT struct Library *SysBase;
  60.  
  61. IMPORT    CDXLOB * CDXL_OB;    // Global CDXLOB
  62. IMPORT    struct Custom far custom;
  63. IMPORT    ULONG    Count;
  64.  
  65.  
  66. VOID
  67. WaitPacket(ASYNCXLFILE *xlfile)
  68. {
  69.     if ( !xlfile->af_PacketPending )
  70.     return;
  71.  
  72.     /* This enables signalling when a packet comes back to the port */
  73.     xlfile->af_PacketPort.mp_Flags = PA_SIGNAL;
  74.  
  75.     /* Wait for the packet to come back, and remove it from the message
  76.      * list. Since we know no other packets can come in to the port, we can
  77.      * safely use Remove() instead of GetMsg(). If other packets could come in,
  78.      * we would have to use GetMsg(), which correctly arbitrates access in such
  79.      * a case
  80.      */
  81.     Remove((struct Node *)WaitPort(&xlfile->af_PacketPort));
  82.  
  83.     if ( CDXL_OB->AudioSize ) {
  84.     // disable AUD0 interrupt
  85.     custom.intreq = INTF_AUD0;
  86.  
  87.     Count++;
  88.  
  89.     if ( Count==1 ) {
  90. /*
  91.         CDXL_OB->curVideo = 0;
  92.         CDXL_OB->curAudio = 0;
  93. */
  94.         CDXL_OB->curVideo ^= 1;
  95.         StartAudio();
  96.  
  97.         D(PRINTF("(%ld,%ld) ",CDXL_OB->curAudio,CDXL_OB->curVideo);)
  98.     } else {
  99.         CDXL_OB->curVideo ^= 1;
  100.         // enable AUD0 interrupt
  101.         D(PRINTF("(%ld,%ld) ",CDXL_OB->curAudio,CDXL_OB->curVideo);)
  102.         custom.intena = INTF_SETCLR|INTF_AUD0;
  103.     }
  104.  
  105.     } else {
  106.     CDXL_OB->curVideo ^= 1;
  107.     Count++;
  108.     }
  109.  
  110.     /* set the port type back to PA_IGNORE so we won't be bothered with
  111.      * spurious signals
  112.      */
  113.     xlfile->af_PacketPort.mp_Flags = PA_IGNORE;
  114.  
  115.     /* packet is no longer pending, we got it */
  116.     xlfile->af_PacketPending = FALSE;
  117.  
  118. } // WaitPacket()
  119.  
  120.  
  121. VOID
  122. SendAsync(ASYNCXLFILE *xlfile, APTR arg2)
  123. {
  124.     /* send out an async packet to the file system. */
  125.  
  126.     xlfile->af_Packet.sp_Pkt.dp_Port = &xlfile->af_PacketPort;
  127.     xlfile->af_Packet.sp_Pkt.dp_Arg2 = (LONG)arg2;
  128.     PutMsg(xlfile->af_Handler, &xlfile->af_Packet.sp_Msg);
  129.     xlfile->af_PacketPending = TRUE;
  130.  
  131. } // SendAsync()
  132.  
  133.  
  134. LONG
  135. CloseAsyncXL( ASYNCXLFILE *xlfile, CDXLOB * CDXL_ob )
  136. {
  137.     LONG result;
  138.     LONG result2;
  139.  
  140.     result = 0;
  141.     if (xlfile)
  142.     {
  143.         if (xlfile->af_PacketPending) {
  144.             WaitPacket(xlfile);
  145.     }
  146.  
  147.         result  = xlfile->af_Packet.sp_Pkt.dp_Res1;
  148.         result2 = xlfile->af_Packet.sp_Pkt.dp_Res2;
  149.  
  150.         Close(xlfile->af_File);
  151.         FreeVec(xlfile);
  152.  
  153.     CDXL_ob->Buffer[0] = CDXL_ob->Buffer[1] = NULL;
  154.  
  155.         SetIoErr(result2);
  156.     }
  157.  
  158.     return(result);
  159.  
  160. } // CloseAsyncXL()
  161.  
  162.  
  163. ASYNCXLFILE *
  164. OpenAsyncXL(const STRPTR fileName, CDXLOB * CDXL_ob, LONG position)
  165. {
  166.     ASYNCXLFILE  * xlfile;
  167.     struct FileHandle * fh;
  168.     BPTR                handle;
  169.     BPTR                lock;
  170.     LONG                bufferSize = CDXL_ob->BufSize << 1;
  171.  
  172.     handle = NULL;
  173.     xlfile   = NULL;
  174.     lock   = NULL;
  175.  
  176.     if (handle = Open(fileName,MODE_OLDFILE)) {
  177.  
  178.     if ( position && (Seek(handle,position,OFFSET_BEGINNING) < 0) ) {
  179.         Close(handle);
  180.         return( NULL );
  181.     }
  182.  
  183.         /* now allocate the ASyncFile structure, as well as the read buffers.
  184.          * Add 15 bytes to the total size in order to allow for later
  185.          * quad-longword alignement of the buffers
  186.          */
  187.  
  188.     if (xlfile = AllocVec(sizeof(ASYNCXLFILE) + bufferSize+15 ,MEMF_CHIP|MEMF_CLEAR)) {
  189.         xlfile->af_File      = handle;
  190.  
  191.         fh                     = BADDR(xlfile->af_File);
  192.         xlfile->af_Handler       = fh->fh_Type;
  193. //        xlfile->af_BufferSize    = bufferSize / 2;
  194.         xlfile->af_BufferSize    = CDXL_ob->FrameSize;
  195.         xlfile->af_Buffers[0]    = CDXL_ob->Buffer[0]
  196.                                = (APTR)(((ULONG)xlfile + sizeof(ASYNCXLFILE) + 15) & 0xfffffff0);
  197.         xlfile->af_Buffers[1]    = CDXL_ob->Buffer[1]
  198.                    = (APTR)((ULONG)xlfile->af_Buffers[0] + CDXL_ob->BufSize /*xlfile->af_BufferSize*/);
  199.         xlfile->af_CurrentBuf    = 0;
  200.         xlfile->af_PacketPending = FALSE;
  201.  
  202.         /* this is the port used to get the packets we send out back.
  203.          * It is initialized to PA_IGNORE, which means that no signal is
  204.          * generated when a message comes in to the port. The signal bit
  205.          * number is initialized to SIGB_SINGLE, which is the special bit
  206.          * that can be used for one-shot signalling. The signal will never
  207.          * be set, since the port is of type PA_IGNORE. We'll change the
  208.          * type of the port later on to PA_SIGNAL whenever we need to wait
  209.          * for a message to come in.
  210.          *
  211.          * The trick used here avoids the need to allocate an extra signal
  212.          * bit for the port. It is quite efficient.
  213.          */
  214.  
  215.         xlfile->af_PacketPort.mp_MsgList.lh_Head     = (struct Node *)&xlfile->af_PacketPort.mp_MsgList.lh_Tail;
  216.         xlfile->af_PacketPort.mp_MsgList.lh_Tail     = NULL;
  217.         xlfile->af_PacketPort.mp_MsgList.lh_TailPred = (struct Node *)&xlfile->af_PacketPort.mp_MsgList.lh_Head;
  218.         xlfile->af_PacketPort.mp_Node.ln_Type        = NT_MSGPORT;
  219.         xlfile->af_PacketPort.mp_Flags               = PA_IGNORE;
  220.         xlfile->af_PacketPort.mp_SigBit              = SIGB_SINGLE;
  221.         xlfile->af_PacketPort.mp_SigTask             = FindTask(NULL);
  222.  
  223.         xlfile->af_Packet.sp_Pkt.dp_Link          = &xlfile->af_Packet.sp_Msg;
  224.         xlfile->af_Packet.sp_Pkt.dp_Arg1          = fh->fh_Arg1;
  225.         xlfile->af_Packet.sp_Pkt.dp_Arg3          = xlfile->af_BufferSize;
  226.         xlfile->af_Packet.sp_Pkt.dp_Res1          = 0;
  227.         xlfile->af_Packet.sp_Pkt.dp_Res2          = 0;
  228.         xlfile->af_Packet.sp_Msg.mn_Node.ln_Name  = (STRPTR)&xlfile->af_Packet.sp_Pkt;
  229.         xlfile->af_Packet.sp_Msg.mn_Node.ln_Type  = NT_MESSAGE;
  230.         xlfile->af_Packet.sp_Msg.mn_Length        = sizeof(struct StandardPacket);
  231.  
  232.        /* Send out the first read packet to
  233.         * the file system. While the application is getting ready to
  234.         * read data, the file system will happily fill in this buffer
  235.         * with DMA transfers, so that by the time the application
  236.         * needs the data, it will be in the buffer waiting
  237.         */
  238.  
  239.         xlfile->af_Packet.sp_Pkt.dp_Type = ACTION_READ;
  240. /*
  241.         if (xlfile->af_Handler)
  242.         SendAsync(xlfile,xlfile->af_Buffers[0]);
  243. */
  244.     } else {
  245.         Close(handle);
  246.     }
  247.     }
  248.  
  249.     return(xlfile);
  250.  
  251. } // OpenAsyncXL()
  252.  
  253.