aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2014-05-16 18:14:02 -0700
committerH. Peter Anvin <hpa@zytor.com>2014-05-16 18:14:02 -0700
commit81f02dd08a3879cce12754d8f4ec1b260bd210a5 (patch)
tree12601acc2c7c866ac14fe1b2ac00f55a8e7e65e6
parent002a8c757003dd7e67d79ba6c420b7a377b23221 (diff)
downloadabc80-81f02dd08a3879cce12754d8f4ec1b260bd210a5.tar.gz
abc80-81f02dd08a3879cce12754d8f4ec1b260bd210a5.tar.xz
abc80-81f02dd08a3879cce12754d8f4ec1b260bd210a5.zip
data: Add script to produce an ABS file, generate cpm.abs
Generate cpm.abs as an alternative to cpm.bas. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--data/Makefile9
-rw-r--r--data/bin2abs.pl77
2 files changed, 83 insertions, 3 deletions
diff --git a/data/Makefile b/data/Makefile
index 9048cc6..5f1fba0 100644
--- a/data/Makefile
+++ b/data/Makefile
@@ -2,14 +2,14 @@ PERL = perl
BIN2MIF = bin2mif.pl
Z80ASM = ../tools/z80asm/z80asm
-.SUFFIXES: .bdf .asm .obj .bin .mif .bas .rom .pl .inc
+.SUFFIXES: .bdf .asm .obj .bin .mif .bas .rom .pl .inc .abs
.asm.bin:
$(Z80ASM) -o$@ -l$*.lst $<
all : keyboard.mif abc80rom.bin basic80.mif \
mmu.mif chargen.mif videoram.mif fgcol.mif sddrom.mif \
- abcsefi.bas abcdkno.bas abcintl.bas cpm.bas
+ abcsefi.bas abcdkno.bas abcintl.bas cpm.bas cpm.abs
abc80rom.bin : buildrom.pl abcbasic.rom ufddos.bin printer.bin
$(PERL) buildrom.pl $@ 32768 \
@@ -64,6 +64,9 @@ cpm.bas: cpm.bin
$(PERL) bin2poke.pl $< 32768 100 'Z%=CALL(32768%)' > $@ \
|| ( rm -f $@ ; exit 1 )
+cpm.abs: cpm.bin
+ $(PERL) bin2abs.pl $< 32768 > $@ || ( rm -f $@ ; exit 1 )
+
.bin.bas:
$(PERL) bin2poke.pl $< 16384 100 RETURN | cat charpoke.bah - > $@ \
|| ( rm -f $@ ; exit 1 )
@@ -81,7 +84,7 @@ fgcol.mif : fgcol.pl
$(PERL) fgcol.pl > $@ || ( rm -f $@ ; exit 1 )
clean:
- rm -f *.obj *.bin *.mif *.bas
+ rm -f *.obj *.bin *.mif *.bas *.abs
dist: all
rm -f *.obj
diff --git a/data/bin2abs.pl b/data/bin2abs.pl
new file mode 100644
index 0000000..6cc8aec
--- /dev/null
+++ b/data/bin2abs.pl
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+#
+# Convert a binary file to an ABC-DOS ABS file
+#
+
+use bytes;
+
+($file, $org, $entry) = @ARGV;
+
+$org = oct $org if ( $org =~ /^0/ );
+
+$entry = $org unless ( defined($entry) );
+
+open(FILE, '<:raw', $file) or die "$0: $file: $!\n";
+
+while ( ($l = read(FILE, $dd, 65536)) > 0 ) {
+ $free = 0;
+ $pad = 0;
+ $csum = 0;
+ $written = 0;
+ for ( $i = 0 ; $i < $l ; $i++ ) {
+ $c = ord(substr($dd,$i,1));
+
+ if ( !$free ) {
+ if ( $written ) {
+ # Write record terminator
+ print pack("CCC", $csum, 0xff, 0x00);
+ $csum = 0;
+ }
+ # Write ABS record header
+ $free = $l - $i;
+ # 7 bytes for header, 1 byte csum, 2 bytes temination (FF 00)
+ $free = 253-10 if ( $free > 253-10 );
+ $ah = ($org >> 8) & 0xff;
+ $al = $org & 0xff;
+ print pack("CCCCCCC", 0, $free, 0, $ah, ~$ah, $al, ~$al);
+ $written = 7;
+ }
+
+ print pack("C", $c);
+ $csum = ($csum + $c) & 0xff;
+ $org++;
+ $free--;
+ $written++;
+ }
+
+ # Terminate the final record
+ if ( $written ) {
+ print pack("C", $csum);
+ $written++;
+
+ # Not enough space for the entry point record, pad to next sector
+ if ($written > 253-9) {
+ print pack("CC", $csum, 0xff, 0x00);
+ $written += 2;
+ while ($written < 253) {
+ print pack("C", 0xe5);
+ $written++;
+ }
+ $written = 0;
+ }
+ }
+
+ # Write entry point record plus sector terminator
+ $ah = ($entry >> 8) & 0xff;
+ $al = $entry & 0xff;
+ print pack("CCCCCCCCC", 0, 0, 0, $ah, ~$ah, $al, ~$al, 0xff, 0x00);
+ $written += 9;
+ while ($written < 253) {
+ print pack("C", 0xe5);
+ $written++;
+ }
+
+ close(FILE);
+}
+
+exit 0;