Character classes
File conventions
- The character set is always UTF-8.
- All integers are written using Unicode codepoints DIGIT ZERO - DIGIT NINE (and prefixed with HYPHEN-MINUS if negative)
Notations:
- "foo" is literal string foo as Unicode code points.
- () denote grouping.
- <space> is any space character (see section on spaces below)
- <linefeed> is any linefeed character (see section on linefeeds below)
- something* is something repeated zero or more times
- something+ is something repeated one or more times
- something? is something or empty.
- $foo denotes Metasyntactic variable.
- $foo... denotes Metasyntactic variable that may span multiple components.
- Space means either concatenation (in raw strings) or component split (in stuff that is component-encoded)
- <start-of-line> is special zero-length string at beginning of line.
- <end-of-line> is special zero-length string at end of line.
Spaces
Following Unicode codepoints act as spaces:
- Codepoints 0x20 (SPACE) and 0x09 (TAB)
- Codepoints 0x1680, 0x180E, 0x2028, 0x205F and 0x3000
- Codepoints 0x2000-0x200A.
Line feeds
Following Unicode codepoints act as line feeds:
- codepoint 0x0A
- codepoint 0x0D
- codepoint 0x1C-0x1E
- codepoint 0x85
- codepoint 0x2029
These characters all end line and begin the next.
File structure
JRSR file consists of magic and number of sections.
Magic
The JRSR file magic is "JRSR" <linefeed>+. This magic must be first thing in the file, and there can't be anything (including spaces or line feeds before it). After magic, there is no open section.
Blank lines
Blank lines are allowed anywhere after magic. They are ignored.
Starting section
Section named $foo is opened with line of form "!BEGIN" <space>+ $foo. If there is previous section open, it is implicitly closed.
Section line
If there is section open, section content lines are prefixed with "+". Such lines may only occur when section is open.
Ending section
Section is closed with line of form "!END". This line can appear at any time there is open section.
End of file
End of file can appear anywhere there is no open section. The file must not end inside open section.
Line (component) format
Not all sections follow this format, but many do. Empty lines are skipped. The purpose is to encode non-empty array of non-empty strings into single line.
Characters:
- <start-of-line>: Initialize depth counter to 0. Initialize current token to "", initialize array to empty.
- <space>: If current token is not empty string, append token to array and reset token to "".
- "(" and depth counter is 0: Increment depth counter to 1 and behave like <space> was read.
- "(" and depth counter is >0: Increment depth counter and append literal '(' to token.
- ")" and depth counter is >1: Decrement depth counter and append literal ')' to token.
- ")" and depth counter is 1: Decrement depth counter to 0 and behave like <space> was read.
- ")" and depth counter is 0: Parse error.
- "\" (backslash) followed by <end-of-line>: Parse error.
- "\" (backslash) followed by some character: Read next character and append it to token as-is. Don't process the next character further.
- <end of line> and depth counter is >0: Parse error.
- <end of line> and depth counter is 0: Behave like <space> was read. If the resulting array is empty, ignore the whole line. Otherwise the array is the parse result.
- anything else: Append character literally to current token.
Sections
"header" section
This section contains information about the whole movie. It is in component format. Of each line, first element in array gives its type. The rest are parameters.
Currently known header line types:
- "PROJECTID" $opaque:
- Multiplicity: 1
- Meaning: Project ID is $opaque. Project ID is used for keeping track if newly loaded savestate is from the same movie (for purposes of keeping rerecord count and not erroring out the load if it would result cross-movie rewind).
- "SAVESTATEID" $opaque:
- Multiplicity: 0-1
- Meaning if present: This is either savestate or movie starting from savestate. The $opaque must equal to ID of one of the savestate events in event section.
- Meaning if absent: This is movie starting from poweron.
- "RERECORDS" $count:
- Multiplicity: 1
- Meaning: Movie rerecord count is $count. $count must be nonnegative integer.
- "AUTHORS" $author...:
- Multiplicity: 0-(infinity)
- Meaning: Gives authors (real names) of run. Each component of $author... gives new author. The names listed are presumed to be real names.
- "AUTHORNICKS" $nick...:
- Multiplicity: 0-(infinity)
- Added in: R10.9.
- Meaning: Gives authors (nicknames) of run. Each component of $nick... gives new author. The authors listed are assumed to be nicknames and do not have real names.
- "AUTHORFULL" $fullname $nickname:
- Multiplicity: 0-(infinity)
- Added in R10.9.
- Meaning: Run has author with full name of $fullname and nickname of $nickname.
- "COMMENT" $opaque...:
- Multiplicity: 0-(infinity)
- Meaning: Comment. Not parsed by emulator.
- "SYSTEM" $system:
- Multiplicity: 0-1
- Added in R10.14.
- Meaning if absent: Ignored.
- Meaning if present: If $system is anything else than "PC-JPC-RR-r10" or "PC-JPC-RR-r11.3" (starting from r11.3), causes savestate/movie load error (as incompatible movie).
- "INITIALSTATE" $opaque:
- Multiplicity: 0-(infinity)
- Meaning: Denotes that "initialization-"$opaque is a valid initialization section to choose. If this is not present, "initialization" is assumed. If present, SYSTEM should be set to "PC-JPC-RR-r11.3".
"initialization" section
This section gives parameters for PC initial poweron. It is in component format. Of each line, first element in array gives its type. The rest are parameters.
Mandatory lines, must be present exactly once:
- "BIOS" $id: BIOS image ID is $id.
- "VGABIOS" $id: VGA BIOS image ID is $id.
- "INITIALTIME" $time: Number of milliseconds since Unix epoch when system is first powered on. $time must be integer 0-4 102 444 799 999.
- "CPUDIVIDER" $divider: Divide 1GHz by $divider to get CPU clock rate. $divider must be integer 1-256.
- "MEMORYSIZE" $pages: Number of 4KiB pages of memory present is $pages. $pages must be integer 256-262 144.
- "BOOT" $device: $device must be one of "FLOPPY", "HDD" or "CDROM". Sets the boot device. If $device is "CDROM", HDC must not be present. If $device is "HDD", HDA must be present.
Optional line types that can be present at most once:
- "HDA" $id: HDA image ID is $id.
- "HDB" $id: HDB image ID is $id.
- "HDC" $id: HDC image ID is $id.
- "HDD" $id: HDD image ID is $id.
- "FDA" $num: Upon poweron disk number $num is put into FDA. The specified disk must be of floppy type.
- "FDB" $num: Upon poweron disk number $num is put into FDB (the disk with same number must not be put into FDA too). The specified disk must be of floppy type.
- "CDROM" $num: Upon poweron disk number $num is put into CD-ROM drive. Mutually exclusive with HDC. The specified disk must be of cd-rom type.
- "IOPORTDELAY": Signals that I/O delay emulation is enabled.
- "VGAHRETRACE": Signals that VGA horizontal retrace emulation is enabled.
- "FLUSHONMODIFY": Signals that pipeline is to be flushed on detected code self-modification.
- "VGATIMINGMETHOD" $method: $method is either "0" or "1". If "0", classical force-60fps VGA timings are used. If "1", real VGA timings in accordance with timing registers are used.
- "SVGATYPE" $type: $type is either "0" or "1". If "0", emulated SVGA card is revision 2 BGA. If "1", emulated SVGA card is revision 5 BGA.
May be present multiple times:
- "DISK" $num $id: ID of image in image slot $num is $id. $num must be nonnegative integer. Only one entry for each $num may be present.
- "DISKNAME" $num $name: Set name of image in image slot $num to $name. The image slot must be defined before setting its name by DISK line.
- "LOADMODULEA" $module $parameters: Load module named $module, passing $parameters to it.
- "LOADMODULE" $module: Load module $module.
- "FPU" $class: Set FPU emulator class to $class. Obsolete but still supported.
"savestate" and "manifest" sections
These are savestate data and not documented here.
"events" section
This section gives the actual movie input data and is in component format.
The base time is always 0 (even if movie begins from savestate), and time unit is nanoseconds.
Event format is: "$timestamp $class $parameters...?" and there is one event per line. If $class consists only of 'A-Z' and '0-9' (capital letters and numbers) then it is either special event or reserved (error). Valid $parameters... depend on event class. Some events may also have timing restrictions. Events must be in time order from first to last.
Timestamps must be nonnegative integers. By default they are relative to initial poweron. When computing movie length, it is customary to ignore all special events.
Following event types are defined:
- Class "SAVESTATE":
- $opaque $rerecords: Savestate with identifier $opaque. $rerecords gives the rerecord count at point of saving (must be nonnegative integer).
- Class "OPTION":
- "RELATIVE": Further timestamps will be relative to last timestamp.
- "ABSOLUTE": Further timestamps will be relative to initial poweron (warning: buggy in versions R10.7 and before).
- Class "org.jpc.emulator.peripheral.Keyboard"
- "KEYEDGE" $keynumber: Specified key pressed or released (initially all keys are released). The $keynumber must be from ranges 1-83, 85-95, 129-197 or 199-233. Timestamp of event must be divisible by keyboard time unit (66 666ns), and there must not have been any keyboard events within certain number of units[1]
- "PAUSE": Pause is hit. The timing restrictions are the same as in KEYEDGE case.
- "MOUSEBUTTON" $button: Specified mouse button is pressed or released (initially all buttons are released). $button must be one of 0, 1, 2, 3 or 4.
- "XMOUSEMOTION" $motion: Specifies that mouse has moved by $motion mickeys (must be integer -255 - 255) in X direction (positive is right).
- "YMOUSEMOTION" $motion: Similar to XMOUSEMOTION, but gives motion in Y direction (positive is up).
- "ZMOUSEMOTION" $motion: Gives scrollwheel motion (positive is down?). $motion must be integer in range -7 - 7.
- Class "org.jpc.modules.Joystick" (joystick module required to use these):
- "BUTTONA" $state: Set joystick #1 button A state to $state ("0" if released, "1" if pressed).
- "BUTTONB" $state: The same as BUTTONA but for Joystick #1 button B.
- "BUTTONC" $state: The same as BUTTONA but for Joystick #2 button A.
- "BUTTOND" $state: The same as BUTTONA but for Joystick #2 button B.
- "AXISA" $hold: Set joystick #1 X axis monostable multivibrator hold time to $hold nanoseconds (must be positive integer).
- "AXISB" $hold: The same as AXISA, but for joystick #1 Y axis.
- "AXISC" $hold: The same as AXISA, but for joystick #2 X axis.
- "AXISD" $hold: The same as AXISA, but for joystick #2 Y axis.
- "org.jpc.emulator.PC$ResetButton":
- (none): Reboot the PC.
- "org.jpc.emulator.PC$DiskChanger":
- "FDA" $num: $num must be integer at least -1. If $num is "-1", disk in FDA is ejected (FDA must contain disk). Otherwise disk number $num is inserted into FDA (it must be valid disk number for disk of floppy type that's not already in FDB and FDA must be empty).
- "FDB" $num: Same as FDA, but roles of FDA and FDB swapped.
- "CDROM" $num: Similar to FDA but for CD-ROM drive (obivously images must be of CD-ROM type and such disks can't be in FDA or FDB). HDC may not be present.
- "WRITEPROTECT $num: Turn on write protect of disk number $num (must be valid image slot of floppy type and must not be inserted in either fda or fdb).
- "WRITEUNPROTECT" $num: Same as WRITEPROTECT, but turn off the write protect instead of on.
"diskinfo-<id>" sections
These sections are optional. They give information about images used. Component encoding is used, first array element gives the type, rest are parameters. Emulator does not parse these. What is present depends on image.
Currently following lines/types can be written:
- TYPE FLOPPY: This is floppy disk image
- TYPE HDD: This is HD image.
- TYPE CDROM: This is CDROM image (.iso)
- TYPE BIOS: This is BIOS image
- TYPE UNKNOWN: WTF???
- IMAGELENGTH $length: Raw image length is $length.
- IMAGEMD5: Raw image MD5.
- TOTALSECTORS: Total sectors in image.
- TRACKS: Tracks (cylinders) on disk (per side)
- SIDES: Sides on disk.
- SECTORS: Sectors per track on disk.
- COMMENT: Line from image comments.
"output-info" section
Emulator does not parse this. This gives information about outputs used. Compoenent encoding is used, first array element gives the type, rest are parameters. Emulator does not parse these.
- AUDIO $outputname: $outputname is audio output.
- VIDEO: Video output.
[1] PAUSE: Keyboard must be idle afterwards for 60 units (exception: If CTRL is held (codes 29 and 157), then only for 40 units). For keys with numbers <128, keyboard must be idle for 10 units afterwards. For keys with numbers >128, keyboard must be idle for 20 units afterwards (exception: number 183 if either ALT (codes 56 and 184) is held only takes 10).