Annotation of generator/docs/GNMformat, revision 1.1.1.2

1.1       root        1: The Generator GNM log format is:
                      2: 
                      3: header:
                      4:   0: 'G'
                      5:   1: 'N'
                      6:   2: 'M'
                      7:   3: fields per second (e.g. 50 or 60)
                      8: 
                      9: interval = 0;
                     10: while (!EOF) {
                     11:   data = readbyte()) // readbyte() reads the next byte from the file
                     12:   if ((data & 0xF0) == 0) {
                     13:     switch (data) {
                     14:       case 0: /* start of field marker (1/50th or 1/60th second elapsed) */
                     15:               sampsperfield=(readbyte() << 8) + readbyte();
                     16:       case 1: /* FM port 0 */
                     17:               ymport=0; ymreg=readbyte(); ymdata=readbyte();
                     18:       case 2: /* FM port 1 */
                     19:               ymport=1; ymreg=readbyte(); ymdata=readbyte();
                     20:       case 3: /* PSG */
                     21:               write readbyte() to psg port;
                     22:       case 4: /* escaped sample data and mark of interval */
                     23:               ymport=0; ymreg=0x2A; ymdata=readbyte(); interval=1;
                     24:       case 5: /* no sample data this interval */
                     25:               interval=1; /* no change of register 0x2A */
                     26:     }
                     27:   } else {
1.1.1.2 ! root       28:     /* unescaped sample data and mark of interval */
        !            29:     ymport=0; ymreg=0x2A; ymdata=data; interval=1;
1.1       root       30:   }
                     31:   if (interval) {
                     32:     interval = 0;
                     33:     update sound;
                     34:   }
                     35: }
                     36: 
                     37: Rationale
                     38: 
                     39: The GYM file format does not support samples.  Where sample data has been
                     40: added to the GYM file format it is not possible to know where within the
                     41: time period of a field the sample(s) occured, so any players have to make
                     42: a guess.  Samples within a GYM file are represented using an FM write which
                     43: consists of three bytes, this is a huge waste of space.
                     44: 
                     45: Design
                     46: 
                     47: The field is split into a distinct number of intervals in order to
                     48: increase accuracy.  As an emulation format, the idea was to output X
                     49: intervals where X is the number of lines of display, as emulators work
                     50: in terms of video lines.  The GNM format has been modified however to
                     51: cope with any number of intervals within a field.  You could divide a
                     52: field into 4 events for example.  This would mean 4 times the accuracy
                     53: in placing events (in time) than the GYM format.  Of course, the higher
                     54: the number of intervals, the bigger the resulting file format.
                     55: 
                     56: You can only accurately have one sample per interval because the interval
                     57: is the only thing that tells you where in time you are within a field.
                     58: Therefore, the GNM format uses the samples themselves as a marker for
                     59: each interval.  If there is no sample, then a special marker is inserted
                     60: to represent no change.  This makes the file format as concise as possible.
                     61: 
                     62: Encoding
                     63: 
                     64: Each field starts with a $0 byte marker followed by two bytes that indicate
                     65: the number of intervals for this field.
                     66: 
                     67: Each interval is marked by a sample.  The samples are placed directly in
                     68: the stream except for byte vales $0 to $f, in which case they are escaped
                     69: with a $4 byte.  If there was no sample written in the interval period then
                     70: a $5 byte is inserted.
                     71: 
                     72: Generator's implementation
                     73: 
                     74: Generator works on a field at a time basis.  Generator allocates a block
                     75: of memory, which expands if required, that contains what we would write
                     76: to disk assuming maximum samples are necessary (maximum in Generator's
                     77: case is the number of lines in the display, i.e. 262 for NTSC).  Nominally
                     78: 8k is allocated for this purpose.
                     79: 
                     80: YM/PSG writes are written into this block, however writes to FM address
                     81: $2a are held pending until the end of each line.  At the end of the line
                     82: we write the (last) sample into the block (as-is or escaped with a $4 if
                     83: necessary, or $5 if no change to FM register $2a was made).
                     84: 
                     85: At the end of a field we can then decide the number of intervals that we
                     86: wish to output into the file.  If there were no samples in the entire
                     87: period then we remove all interval markers ($5 bytes) and set the number
                     88: of intervals to 0 for this field.  We could leave a few intervals in to
                     89: make FM more accurate, but Generator doesn't do this (not sure if it's
                     90: necessary).
                     91: 
                     92: Generator is of course open source so you are free to look at the
                     93: actual implementation.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.