#!/usr/bin/perl

sub sys
{
	$what = shift;
	system "echo '$what' >>grab-of.log";
	system "$what >>grab-of.log 2>&1" and do {
		print "something is wrong.  check grab-of.log for details.\n";
		exit 1;
	}
}

open F, ">Makefile";
print F <<'HERE';
KERNEL_SOURCE := /lib/modules/`uname -r`/build
obj-m := grab-of.o

default:
	make -C ${KERNEL_SOURCE} SUBDIRS=`pwd` modules
clean:
	rm -f *.o *.ko *.mod.c

HERE

open F, ">grab-of.c";
print F <<'HERE';
/* Copyright 2002 Segher Boessenkool <segher@penguinppc.org> */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/io.h>
#include <asm/uaccess.h>


#define OFFSET 0xfff00000
#define SIZE 0x00100000
#define MISCMINOR ATARIMOUSE_MINOR
#define NAME "grab-of"


static unsigned char *rom;


static ssize_t of_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
	if (*ppos >= OFFSET)
		return 0;

	if (*ppos + count > SIZE)
		count = SIZE - *ppos;

	if (copy_to_user(buf, rom + *ppos, count))
		return -EFAULT;

	*ppos += count;

	return count;
}


static int of_open(struct inode *inode, struct file *filp)
{
	return 0; 
}


static int of_release(struct inode *inode, struct file *filp)
{
	return 0;
}	


static struct file_operations of_fops = {
        open:		of_open,
	release:	of_release,	
	read:		of_read,
}; 


static struct miscdevice of_misc = {
	minor:		MISCMINOR,
	name:		NAME,
	fops:		&of_fops,
};


int __init init_of(void)
{
	int ret;

	rom = ioremap(OFFSET, SIZE);
	ret = misc_register(&of_misc);

	if (ret)
		iounmap(rom);

	return ret;
}


void /* __exit */ cleanup_of(void)
{
	iounmap(rom);
	misc_deregister(&of_misc);
}


module_init(init_of);
module_exit(cleanup_of);
MODULE_LICENSE("GPL");
HERE

sys "make";

sys "/sbin/insmod -f grab-of.ko";

sys "dd if=/dev/atarimouse of=OF";

sys "/sbin/rmmod grab-of";

open F, "<OF";
seek F, 4, 0;
read F, $x, 4;
$version = unpack "H8", $x;
$version =~ s/^0*(.*)(.)(...)$/$1.$2.$3/;
read F, $x, 4;
$date = unpack "H8", $x;
$date =~ s/^(....)(..)(..)$/$1-$2-$3/;
print "version $version, built on $date\n";
close F;

rename "OF", "OF-$version-$date";

print "\nsuccessfully dumped firmware to OF-$version-$date\n";

sys "make clean";
