mirror of
https://github.com/simonowen/apple1emu.git
synced 2025-01-14 14:33:40 +00:00
Added Makefile and make.bat to simplify building
This commit is contained in:
parent
847fc6bf4f
commit
9933a22881
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,2 @@
|
|||||||
.*
|
|
||||||
!.gitignore
|
|
||||||
apple1emu.dsk
|
apple1emu.dsk
|
||||||
|
apple1emu.sym
|
||||||
|
16
Makefile
Normal file
16
Makefile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
DISK=apple1emu.dsk
|
||||||
|
ROMS=apple1.rom applesoft-lite-0.4-ram.bin ehbasic.bin 65C02.rom.bin applesoft-lite-0.4.bin
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
|
||||||
|
$(DISK): apple1emu.asm font.bin opdefs.inc $(ROMS)
|
||||||
|
pyz80.py --exportfile=apple1emu.sym apple1emu.asm
|
||||||
|
|
||||||
|
font.bin: font.png png2bin.pl
|
||||||
|
./png2bin.pl font.png 6 8
|
||||||
|
|
||||||
|
opdefs.inc: opdefs.pl opimpl.inc apple1emu.asm
|
||||||
|
./opdefs.pl
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(DISK) apple1emu.sym
|
64
font.pl
64
font.pl
@ -1,64 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
#
|
|
||||||
# Convert PNG image to raw font binary for Apple 1 emulator
|
|
||||||
#
|
|
||||||
# Makes lots of assumptions about the input image!
|
|
||||||
|
|
||||||
use Compress::Zlib;
|
|
||||||
|
|
||||||
# Input image and output data file
|
|
||||||
my $input = 'font.png';
|
|
||||||
my $output = 'font.bin';
|
|
||||||
|
|
||||||
# Our characters are 6 pixels wide
|
|
||||||
$chrw = 6;
|
|
||||||
|
|
||||||
|
|
||||||
# Slurp the entire PNG image
|
|
||||||
open INPUT, "<$input" and binmode INPUT or die "$input: $!\n";
|
|
||||||
read INPUT, $data='', -s $input;
|
|
||||||
close INPUT;
|
|
||||||
|
|
||||||
# Find and extract the image dimensions
|
|
||||||
$data =~ /IHDR(.{8})/s;
|
|
||||||
($w,$h) = unpack "N2", $1;
|
|
||||||
|
|
||||||
# Extract and expand the compressed image data
|
|
||||||
($data) = $data =~ /IDAT(.*).{8}IEND/s;
|
|
||||||
$data = Compress::Zlib::uncompress($data);
|
|
||||||
|
|
||||||
# Remove the type byte from the start of each line
|
|
||||||
$w_2 = $w/2;
|
|
||||||
$data =~ s/.(.{$w_2})/$1/sg;
|
|
||||||
|
|
||||||
@data = ();
|
|
||||||
|
|
||||||
# Unpack the pixel nibbles
|
|
||||||
foreach (unpack "C*", $data) {
|
|
||||||
push @data, $_>>4, $_&1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
open OUTPUT, ">$output" and binmode OUTPUT or die "$output: $!\n";
|
|
||||||
|
|
||||||
# Process all characters
|
|
||||||
foreach $chr (0..$w/$chrw-1)
|
|
||||||
{
|
|
||||||
# Process the image line by line
|
|
||||||
foreach $y (0..$h-1)
|
|
||||||
{
|
|
||||||
# Locate the pixel data for the current character
|
|
||||||
my $x = $chr*$chrw + $w*$y;
|
|
||||||
my $b = 0;
|
|
||||||
|
|
||||||
# Pack the 1bpp data into a single byte
|
|
||||||
foreach (@data[$x..$x+$chrw-1]) {
|
|
||||||
$b = ($b << 1) | $_;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Left-align within the byte and output it
|
|
||||||
print OUTPUT chr($b << (8-$chrw));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close OUTPUT;
|
|
12
make.bat
Executable file
12
make.bat
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
if "%1"=="clean" goto clean
|
||||||
|
|
||||||
|
opimpl.pl
|
||||||
|
pyz80.py --exportfile=apple1emu.sym apple1emu.asm
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:clean
|
||||||
|
if exist apple1emu.dsk del apple1emu.dsk apple1emu.sym
|
||||||
|
|
||||||
|
:end
|
11
opdefs.pl
11
opdefs.pl
@ -1,10 +1,11 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
#
|
#
|
||||||
# Calculates opcode addresses for the inline instruction decoding table
|
# Calculates opcode addresses for the inline instruction decoding table
|
||||||
#
|
|
||||||
# Used by the Apple 1 emulator, available from:
|
# Allow -v option for verbose output
|
||||||
#
|
use Getopt::Std;
|
||||||
# http://simonowen.com/sam/apple1emu/
|
$opt_v = 0;
|
||||||
|
getopts('v');
|
||||||
|
|
||||||
$source = 'apple1emu.asm';
|
$source = 'apple1emu.asm';
|
||||||
$codeend = 0xd000;
|
$codeend = 0xd000;
|
||||||
@ -75,7 +76,7 @@ MSB:
|
|||||||
# Position base so code finishes at the required point
|
# Position base so code finishes at the required point
|
||||||
$base = $codeend - (($size + 0xff) & ~0xff);
|
$base = $codeend - (($size + 0xff) & ~0xff);
|
||||||
|
|
||||||
print "Size = $size, used = $used, slack = ", $size-$used, "\n";
|
print "Size = $size, used = $used, slack = ", $size-$used, "\n" unless !$opt_v;
|
||||||
|
|
||||||
# Output sorted list of calculated positions
|
# Output sorted list of calculated positions
|
||||||
foreach (sort { $a <=> $b } @todo) {
|
foreach (sort { $a <=> $b } @todo) {
|
||||||
|
89
png2bin.pl
Executable file
89
png2bin.pl
Executable file
@ -0,0 +1,89 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
#
|
||||||
|
# Convert PNG image to Spectrum format sprite image data
|
||||||
|
#
|
||||||
|
# Input image should be palettised 1-bit with no transparency
|
||||||
|
#
|
||||||
|
# Simon Owen <simon@simonowen.com>
|
||||||
|
|
||||||
|
use Compress::Zlib;
|
||||||
|
use Getopt::Std;
|
||||||
|
|
||||||
|
# Allow -v option for verbose output
|
||||||
|
getopts('v');
|
||||||
|
|
||||||
|
# Strip path from input filename, and check
|
||||||
|
$0 =~ s/.*\///;
|
||||||
|
die "Usage: $0 <image> <sprite-width> [<sprite-height>]\n" unless @ARGV == 2 or @ARGV == 3;
|
||||||
|
|
||||||
|
# Input image and output data file
|
||||||
|
($file,$w,$h) = (@ARGV,$ARGV[1]); # height defaults to width if not provided
|
||||||
|
die "Input image must be in PNG format\n" unless $file =~ /.png$/i;
|
||||||
|
die "Sprite width should be 2-16 pixels\n" unless $w >= 2 && $w <= 16;
|
||||||
|
die "Sprite height should be at least 1 pixel\n" unless $h > 0;
|
||||||
|
|
||||||
|
# Slurp the entire PNG image
|
||||||
|
open INPUT, "<$file" and binmode INPUT or die "$file: $!\n";
|
||||||
|
read INPUT, $data='', -s $file;
|
||||||
|
close INPUT;
|
||||||
|
|
||||||
|
# Extract and check the image dimensions
|
||||||
|
$data =~ /IHDR(.{8})/s;
|
||||||
|
($iw,$ih) = unpack "N2", $1;
|
||||||
|
die "Input image (${iw}x${ih}) must be an exact multiple of sprite size (${w}x${h})\n" if ($iw%$w) or ($ih%$h);
|
||||||
|
|
||||||
|
# Extract and expand the compressed image data
|
||||||
|
($data) = $data =~ /IDAT(.*).{8}IEND/s;
|
||||||
|
$data = Compress::Zlib::uncompress($data);
|
||||||
|
|
||||||
|
# Remove the type byte from the start of each line, leaving just 0+1 pixel values
|
||||||
|
if (length($data) == (($iw+1)*$ih)) { # 8bpp?
|
||||||
|
$data =~ s/.(.{$iw})/$1/sg;
|
||||||
|
@data = map { $_&1 } unpack("C*", $data);
|
||||||
|
} elsif (length($data) == (($iw/2+1)*$ih)) { # 4bpp?
|
||||||
|
my $iw_2 = $iw/2;
|
||||||
|
$data =~ s/.(.{$iw_2})/$1/sg;
|
||||||
|
foreach (unpack("C*", $data)) {
|
||||||
|
push @data, ($_>>4)&1, $_&1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
die "Image data format is unsupported (size = ".@data." bytes)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Calculate rows+columns and the expected size of the output data
|
||||||
|
($c,$r) = ($iw/$w,$ih/$h);
|
||||||
|
$size = int(($w+7)/8)*$h*$r*$c;
|
||||||
|
print "Input image ($file) = ${iw}x${ih}, sprite = ${w}x${h}\n" if $opt_v;
|
||||||
|
|
||||||
|
foreach $y (0..$r-1)
|
||||||
|
{
|
||||||
|
foreach $x (0..$c-1)
|
||||||
|
{
|
||||||
|
foreach $l (0..$h-1) # line
|
||||||
|
{
|
||||||
|
# Calculate the offset of the required bit sequence
|
||||||
|
my $o = ((($y*$h+$l)*$c) + $x) * $w;
|
||||||
|
|
||||||
|
# Convert the individual bits to a binary string then a decimal value
|
||||||
|
my $n = unpack("N", pack("B32", substr("0"x32 . join('', @data[$o..$o+$w-1]), -32)));
|
||||||
|
|
||||||
|
# Pack into 1 or 2 bytes, with the bits left-aligned (MSB)
|
||||||
|
$output .= pack(($w<=8)?"C":"n", $n << (8-($w & 7)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sanity check the output data size
|
||||||
|
die "Output data ", length($output), " is the wrong size! (should be $size)\n" unless length($output) == $size;
|
||||||
|
|
||||||
|
# The output file is the input filename with a .bin extension instead of .png
|
||||||
|
$file =~ s/png$/bin/i;
|
||||||
|
open OUTPUT, ">$file" and binmode OUTPUT or die "$file: $!\n";
|
||||||
|
|
||||||
|
# Determine the size of a single sprite, and strip blank sprites from the end of the data
|
||||||
|
$ss = length($output) / ($r*$c);
|
||||||
|
$output =~ s/(\0{$ss})*$//;
|
||||||
|
print "Output data ($file) = ", length($output), " bytes = ", length($output)/$ss, " sprites\n" if $opt_v;
|
||||||
|
|
||||||
|
print OUTPUT $output;
|
||||||
|
close OUTPUT;
|
Loading…
x
Reference in New Issue
Block a user