Task 204: .F08 File Format
Task 204: .F08 File Format
.F08 File Format Specifications
The .F08 file format is a raw binary format used for DOS screen fonts with glyphs of 8-pixel height. It is a simple, header-less structure containing bitmap data for 256 glyphs, each 8 pixels wide and 8 pixels high. This format is associated with legacy DOS systems and is recognized in various font tools and documentation as a raw dump of font data from video adapter ROMs or similar sources.
1. List of Properties of the .F08 File Format Intrinsic to Its File System
- Glyph Width: 8 pixels
- Glyph Height: 8 pixels
- Number of Glyphs: 256
- Bytes per Glyph: 8
- Total File Size: 2048 bytes
- Pixel Format: 1-bit monochrome, with each byte representing a row of the glyph, most significant bit (bit 7) corresponding to the leftmost pixel (1 for pixel on, 0 for off)
- Character Set: Typically IBM Code Page 437 (extended ASCII)
- Header: None
- Footer: None
- Compression: None
- Endianness: Not applicable (byte-based structure)
- Bit Order: Most significant bit left
2. Two Direct Download Links for .F08 Files
- https://raw.githubusercontent.com/spacerace/romfont/master/VGA-ROM.F08 (IBM VGA ROM 8x8 font)
- http://ftp.lanet.lv/ftp/mirror/x2ftp/msdos/programming/misc/fntcol16.zip (This ZIP archive contains multiple .F08 files, such as CGA.F08 and EGA.F08; extract the desired .F08 file after download. A direct single-file link could not be located for a second distinct .F08, but this archive provides access to several.)
3. Ghost Blog Embedded HTML JavaScript for Drag-and-Drop .F08 File Processing
The following is a self-contained HTML document with embedded JavaScript that allows a user to drag and drop a .F08 file. Upon drop, it reads the file, verifies its size, and dumps the properties to the screen in a structured list.
4. Python Class for .F08 File Processing
The following Python class can open a .F08 file, decode and read its content (verifying the size), print the properties to the console, and write the data to a new file.
class F08File:
def __init__(self, filename):
with open(filename, 'rb') as f:
self.data = f.read()
if len(self.data) != 2048:
raise ValueError("Invalid .F08 file size: expected 2048 bytes")
self.properties = {
'Glyph Width': '8 pixels',
'Glyph Height': '8 pixels',
'Number of Glyphs': '256',
'Bytes per Glyph': '8',
'Total File Size': '2048 bytes',
'Pixel Format': '1-bit monochrome, MSB left',
'Character Set': 'Typically IBM Code Page 437',
'Header': 'None',
'Footer': 'None',
'Compression': 'None',
'Endianness': 'Not applicable',
'Bit Order': 'Most significant bit left'
}
def print_properties(self):
for key, value in self.properties.items():
print(f"{key}: {value}")
def write(self, filename):
with open(filename, 'wb') as f:
f.write(self.data)
# Example usage:
# f = F08File('example.F08')
# f.print_properties()
# f.write('new.F08')
5. Java Class for .F08 File Processing
The following Java class can open a .F08 file, decode and read its content (verifying the size), print the properties to the console, and write the data to a new file.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
public class F08File {
private byte[] data;
private Map<String, String> properties;
public F08File(String filename) throws IOException {
FileInputStream fis = new FileInputStream(filename);
data = fis.readAllBytes();
fis.close();
if (data.length != 2048) {
throw new IOException("Invalid .F08 file size: expected 2048 bytes");
}
properties = new LinkedHashMap<>();
properties.put("Glyph Width", "8 pixels");
properties.put("Glyph Height", "8 pixels");
properties.put("Number of Glyphs", "256");
properties.put("Bytes per Glyph", "8");
properties.put("Total File Size", "2048 bytes");
properties.put("Pixel Format", "1-bit monochrome, MSB left");
properties.put("Character Set", "Typically IBM Code Page 437");
properties.put("Header", "None");
properties.put("Footer", "None");
properties.put("Compression", "None");
properties.put("Endianness", "Not applicable");
properties.put("Bit Order", "Most significant bit left");
}
public void printProperties() {
for (Map.Entry<String, String> entry : properties.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
public void write(String filename) throws IOException {
FileOutputStream fos = new FileOutputStream(filename);
fos.write(data);
fos.close();
}
// Example usage:
// public static void main(String[] args) throws IOException {
// F08File f = new F08File("example.F08");
// f.printProperties();
// f.write("new.F08");
// }
}
6. JavaScript Class for .F08 File Processing
The following JavaScript class can open a .F08 file (using Node.js for file I/O), decode and read its content (verifying the size), print the properties to the console, and write the data to a new file.
const fs = require('fs');
class F08File {
constructor(filename) {
this.data = fs.readFileSync(filename);
if (this.data.length !== 2048) {
throw new Error('Invalid .F08 file size: expected 2048 bytes');
}
this.properties = {
'Glyph Width': '8 pixels',
'Glyph Height': '8 pixels',
'Number of Glyphs': '256',
'Bytes per Glyph': '8',
'Total File Size': '2048 bytes',
'Pixel Format': '1-bit monochrome, MSB left',
'Character Set': 'Typically IBM Code Page 437',
'Header': 'None',
'Footer': 'None',
'Compression': 'None',
'Endianness': 'Not applicable',
'Bit Order': 'Most significant bit left'
};
}
printProperties() {
for (const [key, value] of Object.entries(this.properties)) {
console.log(`${key}: ${value}`);
}
}
write(filename) {
fs.writeFileSync(filename, this.data);
}
}
// Example usage:
// const f = new F08File('example.F08');
// f.printProperties();
// f.write('new.F08');
7. C++ Class for .F08 File Processing
The following C++ class can open a .F08 file, decode and read its content (verifying the size), print the properties to the console, and write the data to a new file.
#include <fstream>
#include <iostream>
#include <vector>
#include <map>
class F08File {
private:
std::vector<char> data;
std::map<std::string, std::string> properties;
public:
F08File(const std::string& filename) {
std::ifstream file(filename, std::ios::binary | std::ios::ate);
if (!file.is_open()) {
throw std::runtime_error("Unable to open file");
}
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
data.resize(size);
if (!file.read(data.data(), size)) {
throw std::runtime_error("Error reading file");
}
if (size != 2048) {
throw std::runtime_error("Invalid .F08 file size: expected 2048 bytes");
}
properties = {
{"Glyph Width", "8 pixels"},
{"Glyph Height", "8 pixels"},
{"Number of Glyphs", "256"},
{"Bytes per Glyph", "8"},
{"Total File Size", "2048 bytes"},
{"Pixel Format", "1-bit monochrome, MSB left"},
{"Character Set", "Typically IBM Code Page 437"},
{"Header", "None"},
{"Footer", "None"},
{"Compression", "None"},
{"Endianness", "Not applicable"},
{"Bit Order", "Most significant bit left"}
};
}
void printProperties() const {
for (const auto& prop : properties) {
std::cout << prop.first << ": " << prop.second << std::endl;
}
}
void write(const std::string& filename) const {
std::ofstream file(filename, std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error("Unable to open file for writing");
}
file.write(data.data(), data.size());
}
};
// Example usage:
// int main() {
// try {
// F08File f("example.F08");
// f.printProperties();
// f.write("new.F08");
// } catch (const std::exception& e) {
// std::cerr << e.what() << std::endl;
// }
// return 0;
// }