Pedro Gimeno's gists (pastes with history), each in an independent (orphan) branch

Pedro Gimeno dbaaf6f50f Why LuaJIT 1 year ago
.gitignore 98c74363be Add .gitignore 1 year ago dbaaf6f50f Why LuaJIT 1 year ago
mode1to2.lua 044a64f5af Add license header 1 year ago

CD-ROM MODE1/2048 to MODE2/2352 converter

This LuaJIT program will convert a CD image file recorded with 2048 bytes per sector (typically with the .iso extension, though not necessarily), into a CD-XA Mode 2 image with 2352 bytes per sector.

However, only the error detection codes will be regenerated. The error correction codes won't be. This means that in case of read errors, the reader will be unable to correct them. For this reason:


The program needs LuaJIT. Both 2.0.4 or 2.1.0-beta3 have been verified to work. You need at least ~1 GB free memory, as the CD is loaded into memory. It uses some FFI features.


luajit mode1to2.lua <input_file> <output_file>


This was made in order to use a homebrew PlayStation® CD image which was recorded in MODE1/2048 format, with the Mednafen emulator, which requires it in MODE2/2352 format and with the right CRC values.

You may find some other use for it. Good luck!


In my system, it takes about 3.5 seconds to convert a 700 MB image, when the image is fully cached and the destination is an SSD drive.

Extra information

This utility sets the XA submode of the sectors as follows:

  • Sectors 12 to 15 are marked as FORM 2. The FORM 2 format is not respected, though, as the CRC is written at the wrong offset.
  • Sector 16 is marked as FORM 1, DATA and EOR.
  • All other sectors are marked as FORM 1, DATA.

I have not managed to find a specification of CD-ROM XA that details the meaning of the submode bits in the XA mode 2 subheader. The information I have on these bits comes only from the Mednafen source code. I have no idea what EOR is for, but it's that way in a PlayStation original CD, therefore I made it that way. And the resulting image works with Mednafen, which was my goal, so yay.

Why LuaJIT?

This is a complex question that can be divided into multiple subquestions.

Why not C/C++/any other language compiled to native code?

Reason 1: I don't trust binaries except from very few sources (like the Debian repository), and for the sake of those like me, I don't want to impose a binary.

Reason 2: I don't have the time or the means to compile it for every possible platform.

Why not Java/C#/any other language compiled to intermediate code?

In compiled form: See Reason 1 above.

In source form: Are you seriously telling me that I should tell everyone to compile it themselves?

Ok, so interpreted. Why not Python/Scheme/any other interpreted language?

I wrote the first version in Python. It took 1 minute 15 seconds to process the disk after I added the CRC code, and that's when I rewrote it in LuaJIT. So in other words: performance.

Later I tested my program with PyPy. It took ~6 seconds. It didn't occur to me to test it before the rewrite, because my past experience with PyPy has been that it rarely makes a really significant difference, of the kind that Lua vs LuaJIT consistently does. PyPy's speed seems to be very sensitive to the task at hand or the algorithms employed, and I have no idea how to write PyPy-friendly code; I'm far better at writing LuaJIT-friendly code. Anyway, in this case I would probably not have written the LuaJIT version if I tested it with PyPy first.

Additionally, PyPy is heavyweight compared to LuaJIT. For that reason, the requirement of installing it in order to run the program will deter more people than requiring installation of LuaJIT.

And what about JavaScript?

Only asm.js is fast enough to rival with LuaJIT's speed, and asm.js is a pain to write, or to read, for the matter.

Finally, why LuaJIT?

LuaJIT together with FFI provides means for writing programs that run at a speed just about 1/2 that of native C. Of the interpreted languages I know, only asm.js may be faster, and that's not an option for the aforementioned reasons.