Japanese
FAQGeneral program
BackForward
FAQ/Program General

CD access related



How to do overlay programming?

Q)
Please tell me how to overlay (read and execute a subprogram on the CDROM with the main program).

A)
Please refer to the example below (for SGL GNU environment).

1) Creation of resident department program

A resident program is used at least as a part to read files and store commonly used libraries.
The procedure is to load the non-resident program from the CD-ROM to the specified address, and then execute the non-resident program using one of the following two methods.

  1. How to call from a specified address
    Write the address at which the non-resident program will be executed in advance, and after loading the non-resident program, execute it from this address.

    Program description example

    fid = GFS_NameToId((Sint8 *)fname); /* fname is a non-resident program */
    GFS_Load(fid, 0, 0x6080000, GFS_BUFSIZ_INF);
    
    /* Get the start address from the map file of the non-resident program */
    ((volatile void (*)())(0x6081000))();  
    

    Declaration when linking a program

    GCC -m2 -Xlinker -Tkernal.cof -Xlinker -e -Xlinker ___Start ....
    

    In this example, if the address of the nonresident program's execution start function changes, the program must be recompiled.

  2. Define a function using an external declaration, and set the address for the externally declared function using the -defsym option when linking. The function is executed after loading the non-resident program.

    Program description example

    extern void SUB_main1( void );
    #define SUB_ADDR 0x06080000
    void main( void ) 
    {
            :
       /* Example of loading a non-resident program */
       buf[0].type = CDBUF_COPY;
       buf[0].trans.copy.addr = (Uint32)SUB_ADDR;
            :
       slCdLoadFile();
       /* Execute non-resident program */
       SUB_main1();
            :
    }
    

    Declaration when linking a program

    GCC -m2 -Xlinker -defsym -Xlinker _SUB_main1=0x06081000 ¥
       -Xlinker -Tkernal.cof -Xlinker -e -Xlinker ___Start ....
    

    The address of the execution start function of the non-resident part will be undefined, so set the address temporarily, create the non-resident program, then obtain the real execution start address from the map file of the non-resident part and set the address again. You may need to fix it and link it.

2) How to create a non-resident department program

Non-resident programs run programs that are only used on a stage-by-stage basis, rather than programs or data that are always used.
It is okay to have multiple non-resident programs, but please note the following points when creating them.

  1. Precautions when programming

  2. When programming, be careful not to create a function with the same name as the resident part in the object file. (For example, the main function may conflict.)

  3. Precautions when reading non-resident area

  4. Set the start address of the non-resident part to the same address as the reading start address of the resident part.

  5. Transfer of map information of resident program

  6. When creating the non-resident part, specify the linker's -R option and specify the executable file for the resident part (for example, Kernal.COF).

    GCC -m2 -Xlinker -R -Xlinker kernal.cof .....

    With this specification, symbols from the resident part are extracted and included in the non-resident program.
    If the same function exists even if the library to be used is linked in the same way as the resident part, the information in the COFF file specified with -R will take precedence.

3) Re-registering the execution start address of the non-resident part called from the resident part

After creating a non-resident program, check the address of the function called from the resident part from the map file, and reset the address of the function to start execution using the -defsym option when linking.
There is no need to do this if the address is already the same as when the resident program was created.


How to check CD tray open?

Q)
I would like to check the CD tray open, but how should I do it?

A)
Be sure to use the following method when checking the CD tray open.

if ( CDC_GetHirqReq() & CDC_HIRQ_DCHG ) {
   SYS_EXECDMP(); /* Call multiplayer */
} 

There is no problem with this process,

only. Operation cannot be guaranteed if the tray open check is performed using any other method.


How to extract the stream resident in the CD buffer sector by sector?

Q)
Please tell me how to cut the stream resident in the CD buffer into sectors and extract them to the host area.
Also, please tell me how to use it in conjunction with other CD libraries and extract them in the same way.

A)
In the CD buffer resident mode ( GFS_SetGmode function ), data in the CD buffer can be moved to the desired sector position using the GFS_Seek function and retrieved using the GFS_Fread function .
However, there is only a maximum of 200 sectors, so if you seek or read beyond this size, data will be read from the CD.

Is it possible that the return value of GFS_FRead is not returned correctly?

Q)
The return value of GFS_Fread() may not be returned correctly.
It seems that something goes wrong when the file is less than 1 sector and is about several hundred bytes.
please investigate.

A)
This is a bug up to GFS Ver2.00. Be sure to use GFS library Ver. 2.01 or higher , and SGL CD library version 2.0A or higher (96/02/06 02:01) provided by SGL.


How to find frame address (FAD) using CDC function group.

Q)
Please tell me how to obtain the frame address (FAD) from any file (name) using the CD communication interface.

A)
For files that can be handled on the GFS library, the FAD (Frame ADress) at the beginning of the file can be obtained using GFS_DIR_FAD in the GfsDirName *dir structure.
You can also use the following methods to obtain the beginning of a CDDA track.

/* Get the first frame address of the CDDA track specified by trackno */
Sint32 GetCDStartFrame(Uint8 trackno)
{
  CdcPos Pos;
  CdcStat stat;
  CDC_POS_PTYPE(&pos) = CDC_PTYPE_TNO;
  CDC_POS_TNO(&pos) = trackno;
  CDC_POS_IDX(&pos) = 1;
  CDC_CdSeek(&pos);
  while(1) {
    CDC_GetCurstat(&stat);
    if ( CDC_STAT_STATUS(&stat) == CDC_ST_PAUSE ) {
      break;
    }
  }
  return CDC_STAT_FAD(&stat);
}

Another method is to refer to the TOC (Table Of Contents) of the disk and refer to the obtained table.
This table stores 4 bytes for each track from track 1 to the lead-out start frame address.

Regarding the function CDC_TgetToc, which obtains the TOC,
"PROGRAMMER'S GUIDE CD Communication Interface User's Manual (CD Part)"
8.2 Function details No. 1.5

For information on the acquired TOC
"PROGRAMMER'S GUIDE CD Communication Interface User's Manual (CD Part)"
7.2 Data Details 7.2.3 TOC Information/Session Information No 3.0

There is a description in.


Please tell me how to play CDDA.

Q)
Regarding CDDA playback using the CDC function group, I do not know how to "play CDDA", "stop CDDA", "repeat playback of CDDA", and "pause CDDA".

A)
Please see the attached sample program.


What should I do if a CD-ROM read error occurs?

Q)
What should I do if a CD-ROM read error occurs?

A)
CD-ROM errors can occur under various conditions. If data that cannot be corrected appears due to dust etc. on the disk, an error will occur.
Additionally, the frequency of error occurrence varies depending on the disk and CD-ROM drive mechanism. To deal with this, instead of reading once, read again when an error occurs.

If you are using the GFS library, repeating GFS_Load() will accomplish your goal if the file is already open.
Normally, it is a good idea to perform retry processing several times. Avoid running the retry process in an infinite loop, and move the process to the multiplayer without displaying an error message.


Please tell me how to use CD buffer effectively.

Q)
Please tell me how to use CD buffer effectively.

A)
The CD buffer has a size that can be used as a data area of 200 sectors (one sector is 2048 bytes for Mode1, Mode2 Form1, and 2324 bytes for Mode2 Form2).
The Sega Saturn allows you to use this CD buffer like memory.

This is done by specifying the resident mode with the GFS_SetGmode function of the GFS library, reading the file once from the CD-ROM and making it resident, and then calling the GFS functions GFS_Seek, GFS_Fread, etc. in the same way as from the CD-ROM. It allows you to read from the CD buffer without accessing the CD-ROM again.

In the GFS library, the default value of the mode specified by the GFS_SetGmode function above is destroyed (GFS_GMODE_ERASE), and by making it resident (GFS_GMODE_RESIDENT), for example, after reading data from a CD-ROM in resident mode, CDDA playback is possible. Let it run.
During execution, you can use GFS functions to read data from the CD buffer and use it like a data buffer.

Please note that if you move (seek) or read (read) more than 200 sectors, the CD-ROM will be accessed, so please do so within the maximum 200 sectors.
Also, if you do not use this method, be sure to use the GFS_SetGmode function to return to discard mode.

example> CD
A sample program that makes data resident in a buffer and reads it during CDDA playback (However, since this program is only for explaining the flow, no error checking is performed. Be sure to add it when installing.)

/* Set resident mode */
GFS_SetGmode(gfs, GFS_GMODE_RESIDENT);

/* Read file into CD buffer */
fid = GFS_NameToId( "sample.dat");
if ( fid> = 0 ) {
    GFS_Open( fid);
    GFS_NwCdRead( gfs, 200 );
}
/* Play CDDA */
CDC_PLY_STYPE(&ply) = CDC_PTYPE_TNO;
CDC_PLY_STNO(&ply) = 2;
CDC_PLY_SIDX(&ply) = 0;
CDC_PLY_ETYPE(&ply) = CDC_PTYPE_TNO;
CDC_PLY_ETNO(&ply) = 3;
CDC_PLY_EIDX(&ply) = 0;
CDC_PLY_PMODE(&ply) = CDC_PM_DFL;
ret = CDC_CdPlay(&ply);

/* CDDA Read from CD buffer during playback */
GFS_Seek( gfs, GFS_SEEK_SET );
GFS_Fread( gfs, 10, buf, 10*2048 );

I want to stop CDDA playback in the middle of playback, retrieve other data from the CD, and then play CDDA from where it left off.

Q)
Please tell me how to stop the song during CDDA playback, read other CD data, and then restart the playback from the point where it was stopped earlier after the data has been read.

A)
There are three points to keep in mind when temporarily reading CD-ROM data during CDDA playback and restarting playback from the original position.

  1. Use CDC I/F library.

  2. Since CD-ROM access occurs midway through, set the CD-DA playback range and repeat count again.

  3. To resume playback after seeking to the original position, set "Do not change pickup position".

This setting can be specified in the playback mode of the CD playback parameter (CdcPly).
(Refer to CDC Manual No. 6.4 CD playback parameters - CdcPly.)
The method to obtain the frame address during restart processing is to obtain the frame address after executing the pause command.< PAUSE> Wait for the state, then get the CD status information and eject it.
Below is a sample program that demonstrates the above steps.
(This sample is written with emphasis on the processing flow, so please check the function values for errors in your actual program.)

Also, immediately before executing drive commands such as play and seek, the tray should be opened/closed (DCHG flag) and< FATAL> You should check the condition.

example
A simple sample program showing how to play CDDA and obtain pose positions.

  /* Initialization */
  Sint32 ret;
  Sint32 fad;
  CdcStat stat;
  CdcPly ply;
  CdcPos pos;
  // Play track numbers 5-17 infinite times
  CDC_PLY_STYPE(&ply)=CDC_PTYPE_TNO;
  CDC_PLY_STNO (&ply)=5;
  CDC_PLY_SIDX (&ply)=0;
  CDC_PLY_ETYPE(&ply)=CDC_PTYPE_TNO;
  CDC_PLY_ETNO (&ply)=17;
  CDC_PLY_EIDX (&ply)=0;
  CDC_PLY_PMODE(&ply)=0x0F;
  // Start playing
  CDC_CdPlay(&ply);
  while (1)
  {
  /* Main loop */
       :
       :
      /* CD access occurs using GFS or SGL */
      if (access==TRUE){
          CDC_POS_TYPE(&pos)=CDC_PTYPE_NOCHG; /* CD-CA PAUSE */
          CDC_CdSeek(&pos); /* PAUSE execution */
          /* Get the FAD of the pose position (with a few frames of error) */
          ret = CDC_GetCurStat(&stat);
          if (ret != CDC_ERR_OK) {
             return NG;
          }
          fad = CDC_STAT_FAD(&stat); :
          /* Perform CD access using GFS or SGL */
                   :
          /* CD-DA playback restart processing */
          CDC_POS_TYPE(&pos)=CDC_PTYPE_FAD; /* Specify restart position */
->        CDC_POS_FAD (&pos)=fad; /* Specified by FAD */
          CDC_CdSeek(&pos); /* Execute seek */
          /* Setting CD playback parameters */
          /* ・5 to 17 tracks */
          /* ・Repeat infinite times */
          /* ・Do not change the pickup position */
          CDC_PLY_STYPE(&ply)=CDC_PTYPE_TNO;
          CDC_PLY_STNO (&ply)=5;
          CDC_PLY_SIDX (&ply)=0;
          CDC_PLY_ETYPE(&ply)=CDC_PTYPE_TNO;
          CDC_PLY_ETNO (&ply)=17;
          CDC_PLY_EIDX (&ply)=0;
          CDC_PLY_PMODE(&ply)=(CDC_PM_PIC_NOCHG | 0x0F);
          CDC_CdPlay(&ply); /* Resume execution */
      }
                :
                :
                :
      slSynch(); /* etc. */
  }


BackForward
FAQGeneral program
Copyright SEGA ENTERPRISES, LTD. 1997