FAQProgram in general
BackForward
FAQ / Program in general

CD access related



How to do overlay programming?

Q)
Please tell me how to overlay (the main program reads and executes the subprogram on the CDROM).

A)
Please refer to the following as an example (in the case of SGL GNU environment).

1) Creating a resident program

Resident programs are used as a minimum part for reading files and storing commonly used libraries.
The procedure is to read the non-resident program from the CD-ROM to the specified address and execute the non-resident program by one of the following two methods.

  1. How to call from a specified address Write the address to execute the non-resident program in advance, load the non-resident program, and then execute 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 the program>

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

    In this example, if the address of the execution start function of the non-resident program changes, this program will need to be recompiled.

  2. Define the function with an external declaration, and set the address for the function declared externally with the -defsym option at link time. The function is executed after the non-resident program is loaded.

    <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 ();
       / * Execution of non-resident program * /
       SUB_main1 ();
            ::
    }
    

    <Declaration when linking the program>

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

    Since the address of the execution start function of the non-resident part becomes undefined, temporarily set the address, create a non-resident program, 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 and link.

2) How to create a non-resident program

Non-resident programs should run programs that are used only on a stage-by-stage basis, for example, rather than programs and data that are used all the time.
There may be multiple non-resident programs, but please note the following points when creating them.

  1. Precautions when programming <BR> Be careful not to create the function name in the object file with the same function name as the resident part. (For example, the main function may collide.)

  2. Precautions when reading the non-resident part <BR> Set the start address of the non-resident part to the same address as the read start address of the resident part.

  3. Passing the map information of the resident part program <BR> When creating the non-resident part, specify the executable file of the resident part (Kernal.COF as an example) by specifying the -R option of the linker.

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

    By this specification, the symbol of the resident part is extracted and incorporated into 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 by -R has priority.

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

After creating the non-resident program, check the address of the function called from the resident part from the map file, and reset the address of the execution start function again with the -defsym option at the time of linking.
If it is already the same as the address when the resident program was created, there is no need to do it.


How to check the CD tray open?

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

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

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

There is no problem with this process

only. If the tray open check is performed by any other method, the operation cannot be guaranteed.


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

Q)
Please tell me how to divide the stream resident in the CD buffer into sector units and extract it to the host area.
Also, please tell me how to use it with other CD libraries and take it out in the same way.

A)
Mode that resides on the CD buffer ( GFS_SetGmode function ) case, the data in the CD buffer, GFS_Seek function moved to the sector position of the objective in GFS_Fread function you can get the data in.
However, since there are only a maximum of 200 sectors, if you seek or read beyond this size, data will be read from the CD.

Is the return value of GFS_FRead not returned normally?

Q)
The return value of GFS_Fread () may not be returned normally.
It seems that it may be strange when the file is less than one sector of about several hundred bytes.
please investigate.

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


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

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

A)
For files that can be handled on the GFS library, the FAD (Frame A Dress) at the beginning of the file can be obtained by GFS_DIR_FAD in the structure of GfsDirName * dir.
You can also get the beginning of a CDDA track as follows.

/ * 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);
}

As another method, you can refer to the TOC (Table Of Contents) of the disk and refer to it from the obtained table.
This table stores 4 bytes for each track from track 1 to the start frame address of the readout.

Function to acquire TOC For the CDC_TgetToc function, see "PROGRAMMER'S GUIDE CD Communication Interface User's Manual (CD Part)"
8.2 Function details No 1.5

For the acquired TOC information, see "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)
About playing CDDA using CDC functions I don't know how to "play CDDA", "stop CDDA", "repeat CDDA", and "pause CDDA".

A)
Please see the attached sample program.


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

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

A)
CD-ROM errors can occur under a variety of conditions. An error will occur if uncorrectable data appears due to dust adhering to the disc.
In addition, the frequency of error occurrence varies depending on the disk and CD-ROM drive mechanism. To deal with this, read again when an error occurs instead of reading once.

If you are using the GFS library, you can repeat GFS_Load () if the file is already open to achieve your goal.
Normally, you should try several retries. Avoid continuing to rotate the retry process in an infinite loop, and move the process to the multiplayer without displaying an error.


Please tell me how to use the CD buffer effectively.

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

A)
The CD buffer has a size that can be used as a data area of 200 sectors (1 sector is 2048 bytes for Mode1 and Mode2 Form1 and 2324 bytes for Mode2 Form2).
Sega Saturn can 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 from the CD-ROM once and making it resident, and then using the GFS_Seek function and GFS_Fread function of the GFS function in the same way as from the normal CD-ROM. You can use it to read from the CD buffer without accessing it from the CD-ROM again.

In the GFS library, the default value of the mode specified by the above GFS_SetGmode function is discarded (GFS_GMODE_ERASE), and by making it resident (GFS_GMODE_RESIDENT), for example, after reading data from the CD-ROM in resident mode, CDDA playback To execute.
It can be used like a data buffer by reading data from a CD buffer using the GFS function during its execution.

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

<Example> CD
A sample program that makes data resident in the buffer and reads it during CDDA playback (However, since this program explains the flow, error checking is not performed. Be sure to add it when embedding.)

/ * Resident mode setting * /
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);
}
/ * CDDA playback * /
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);

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

I want to stop playback in the middle of CDDA playback, take another data from the CD, and continue playing CDDA.

Q)
Please tell me how to stop the song once during CDDA playback, read other CD data, and after the reading is completed, play it from the position where it was stopped halfway.

A)
The following three points are required when temporarily reading the CD-ROM data during CDDA playback and restarting playback from the original position.

  1. Use the CDC I / F library.

  2. Since the CD-ROM access is entered in the middle, reset the CD-DA playback range and the number of repeats.

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

This setting can be specified in the playback mode of the CD playback parameter (CdcPly).
(See CDC Manual No6.4 CD Playback Parameters-CdcPly.)
The method of acquiring the frame address in the restart process is to wait for the <PAUSE> state after executing the pause command, and then acquire and retrieve the CD status information.
Below is a sample program that shows the above procedure.
(Since this sample is written with an emphasis on the processing flow, please check the function value for errors in the actual program.)

Also, just before executing drive commands such as play and seek, you should check the open / close (DCHG flag) and <FATAL> status of the tray.

<Example>
A simple sample program that shows how to play CDDA and get the pause position.

  /* Initialize */
  Sint32 ret;
  Sint32 fad;
  CdcStat stat;
  CdcPly ply;
  CdcPos pos;
  // Play track numbers 5 to 17 infinitely 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 playback CDC_CdPlay (& ply);
  while (1)
  {
  /* Main loop */
       :
       :
      / * Occurrence of CD access by GFS or SGL * /
      if (access == TRUE) {
          CDC_POS_TYPE (& pos) = CDC_PTYPE_NOCHG; / * CD-CA PAUSE * /
          CDC_CdSeek (& pos); / * Execute PAUSE * /
          / * Get the FAD of the pause position (with an error of several frames) * /
          ret = CDC_GetCurStat (& stat);
          if (ret! = CDC_ERR_OK) {
             return NG;
          }
          fad = CDC_STAT_FAD (& stat) ;:
          / * Executing CD access by GFS or SGL * /
                   :
          / * CD-DA playback restart processing * /
          CDC_POS_TYPE (& pos) = CDC_PTYPE_FAD; / * Specify restart position * /
-> CDC_POS_FAD (& pos) = fad; / * Specify with FAD * /
          CDC_CdSeek (& pos); / * Seek execution * /
          / * CD playback parameter settings * /
          / * ・ 5 to 17 tracks * /
          / * ・ Infinite repeat * /
          / * ・ Without changing 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
FAQProgram in general
Copyright SEGA ENTERPRISES, LTD ,. 1997