mirror of
https://github.com/Pecusx/libretro-atari800.git
synced 2026-05-21 06:39:36 +02:00
initial commit
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
|
||||
if (@ARGV == 0) {
|
||||
print "Usage: perl act2html.pl INPUT.act... > OUTPUT.html\n";
|
||||
exit;
|
||||
}
|
||||
my @files = glob "@ARGV";
|
||||
@files > 0 or die "act2html.pl: no input file\n";
|
||||
|
||||
my @palettes;
|
||||
for (@files) {
|
||||
my $pal;
|
||||
open IN, $_ and read IN, $pal, 769 and close IN or die "act2html.pl: $_: $!\n";
|
||||
die "act2html.pl: $_ is too short\n" if length($pal) < 768;
|
||||
die "act2html.pl: $_ is too long\n" if length($pal) > 768;
|
||||
push @palettes, $pal;
|
||||
}
|
||||
|
||||
print qq{<html>\n<head>\n<title>Generated by act2html.pl</title>\n</head>\n};
|
||||
print qq{<body>\n<table width="100%">\n<tr><th>file</th>};
|
||||
print qq{<th width="5%">$_</th>} for 0 .. 15;
|
||||
print qq{</tr>\n};
|
||||
for my $hue (0 .. 15) {
|
||||
print qq{<tr><th colspan="17">Hue: $hue</th></tr>\n};
|
||||
for my $i (0 .. $#files) {
|
||||
print qq{<tr><td>$files[$i]</td>};
|
||||
for (my $color = $hue * 16; ; ) {
|
||||
my $rgb = substr($palettes[$i], $color * 3, 3);
|
||||
my $colspan = 1;
|
||||
while (($color & 0xf) < 0xf && $rgb eq substr($palettes[$i], $color * 3 + 3, 3)) {
|
||||
$colspan++;
|
||||
$color++;
|
||||
}
|
||||
print qq{<td bgcolor="#}, unpack('H6', $rgb);
|
||||
print qq{" colspan="$colspan} if $colspan > 1;
|
||||
print qq{"></td>};
|
||||
++$color & 0xf or last;
|
||||
}
|
||||
print qq{</tr>\n};
|
||||
}
|
||||
}
|
||||
print qq{</table>\n</body>\n</html>\n};
|
||||
@@ -0,0 +1,65 @@
|
||||
.include equates.m65
|
||||
*= $0600
|
||||
PHA
|
||||
TXA
|
||||
PHA
|
||||
TYA
|
||||
PHA
|
||||
LDA 1536
|
||||
STA WSYNC
|
||||
;
|
||||
STA WSYNC
|
||||
STA WSYNC
|
||||
STA WSYNC
|
||||
STA WSYNC
|
||||
STA WSYNC
|
||||
STA WSYNC
|
||||
STA WSYNC
|
||||
LDY RANDOM ;sta $D20B ;POTGO
|
||||
STA WSYNC
|
||||
;NOP
|
||||
;NOP
|
||||
;NOP
|
||||
;NOP
|
||||
;NOP
|
||||
;NOP
|
||||
;NOP
|
||||
;LDX 203
|
||||
;
|
||||
;STA COLPF0+2
|
||||
.byte 99 ;change this to -1 in the data statements
|
||||
LDA RANDOM;LDA $D207 ;POT7
|
||||
STA 207
|
||||
;STA 204
|
||||
LDA VCOUNT
|
||||
STA 205
|
||||
STY 206 ;save old random
|
||||
LDA 208 ;disable dli flag
|
||||
CMP #$0
|
||||
BEQ SKIP
|
||||
LDA #64
|
||||
STA NMIEN
|
||||
SKIP sta wsync
|
||||
sta wsync
|
||||
lda 1537
|
||||
sta HPOSP0
|
||||
lda 1538
|
||||
sta SIZEP0
|
||||
lda 1539
|
||||
sta GRAFP0
|
||||
PLA
|
||||
TAY
|
||||
PLA
|
||||
TAX
|
||||
PLA
|
||||
RTI
|
||||
;jmp SKIP2
|
||||
;REG
|
||||
;.dbyte $0001
|
||||
;SKIP2
|
||||
;LDA REG
|
||||
;ror a
|
||||
;STA REG
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
T7.bas a test program for cycle-counting.
|
||||
The basic idea: we can find out how the real Atari does things by
|
||||
changing a register after a certain number of NOP's on a certain
|
||||
scanline. By aligning a player with the colour change, the horizontal
|
||||
position can be determined and checked on the emulator.
|
||||
Second idea: We can use RANDOM as a cycle-timer. Set the 9-bit
|
||||
random number generator (repeating 511 different values in a sequence),
|
||||
then generate all 511 values and store them in an array, with
|
||||
the value as the index and the index as the value.
|
||||
Then given two different readings of RANDOM at different times,
|
||||
look up the index of both in the table, and the difference , mod 511
|
||||
is the number of cycles elapsed between the readings.
|
||||
Only problem is that we can only read 8 bits of RANDOM, so there's
|
||||
two possible values for each reading, giving 4 possible offsets.
|
||||
But only one of these will remain constant if the procedure is
|
||||
repeated.
|
||||
The 4 values printed by the program at the bottom are the computed
|
||||
possible offsets, the one which remains constant is the acutal
|
||||
offset.
|
||||
|
||||
N=# of NOP cycles
|
||||
P=HPOSP0
|
||||
C=register to change (0=player 0, 9=COLBK, 10=DMACTL, 11-13 HPOS,SIZE,GRAF)
|
||||
V=value to change to
|
||||
PG=player graphics
|
||||
M=antic IR mode
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#define SIZE 10
|
||||
/*bdata.c: convert binary file to Atari basic data statements*/
|
||||
int main(int argc,char *argv[]){
|
||||
int buf[SIZE];
|
||||
int i;
|
||||
int c;
|
||||
int num;
|
||||
int linenum=30000;
|
||||
int end=0;
|
||||
FILE *fpin,*fpout;
|
||||
if(argc!=3){
|
||||
printf("usage: %s infile outfile\n",argv[0]);
|
||||
}
|
||||
fpin=fopen(argv[1],"rb");
|
||||
fpout=fopen(argv[2],"wb");
|
||||
/*fopen(argv[2],"wb");*/
|
||||
|
||||
while(!end){
|
||||
num=0;
|
||||
for(i=0;i<SIZE;i++){
|
||||
c=fgetc(fpin);
|
||||
if(c==EOF){
|
||||
end=1;
|
||||
buf[num]=-1;
|
||||
num++;
|
||||
break;
|
||||
}
|
||||
buf[num]=c;
|
||||
num++;
|
||||
|
||||
}
|
||||
fprintf(fpout,"%d DATA ",linenum);
|
||||
for(i=0;i<num;i++){
|
||||
if(i!=0){
|
||||
fprintf(fpout,", ");
|
||||
}
|
||||
fprintf(fpout,"%d",buf[i]);
|
||||
}
|
||||
fprintf(fpout,"%c",155);
|
||||
linenum+=10;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
#!/usr/bin/perl -w
|
||||
# Performance tester for the Atari800 emulator
|
||||
# by Piotr Fusik <fox@scene.pl>
|
||||
use strict;
|
||||
|
||||
# defaults
|
||||
my $test = '';
|
||||
my $target = '';
|
||||
my $cflags = '';
|
||||
my $default_cflags = '-O2 -Wall';
|
||||
my @features = ();
|
||||
my $reference_program = 'dc.xex'; # "Drunk Chessboard"
|
||||
my $frames = 3 * 60 * 50; # 3 Atari minutes
|
||||
# note that "Drunk Chessboard" ends after 3 minutes
|
||||
my $output = '';
|
||||
|
||||
|
||||
# create 'benchmark' directory under 'src/'
|
||||
sub make_directory() {
|
||||
unless (-d 'benchmark') {
|
||||
print "'benchmark' directory does not exist, creating\n";
|
||||
mkdir 'benchmark' or die "Failed to create 'benchmark' directory\n";
|
||||
}
|
||||
}
|
||||
|
||||
# runs a command (the output goes to the console)
|
||||
sub run_command(@) {
|
||||
print "Running: @_\n";
|
||||
system @_ and die "$_[0] failed\n";
|
||||
}
|
||||
|
||||
# runs a command and captures its output
|
||||
sub pipe_command(@) {
|
||||
print "Running: @_\n";
|
||||
my $result = `@_`;
|
||||
die "$_[0] failed\n" if $?;
|
||||
return $result;
|
||||
}
|
||||
|
||||
# addresses of Atari hardware registers
|
||||
my @hwregs = (
|
||||
0xd000 .. 0xd01f, # GTIA
|
||||
0xd200 .. 0xd21f, # POKEY (stereo)
|
||||
0xd300 .. 0xd303, # PIA
|
||||
0xd400 .. 0xd40f # ANTIC
|
||||
);
|
||||
# built-in Atari programs
|
||||
my %programs = (
|
||||
# yes, I really wrote them here directly in the machine language
|
||||
'blank.xex' =>
|
||||
"\xFF\xFF\x00\x06\x39\x06" .
|
||||
"\x78\xEE\x0E\xD4\xEE\x00\xD4" .
|
||||
"\x8D\x0A\xD4" x 16 .
|
||||
"\x4C\x07\x06" .
|
||||
"\xE0\x02\xE1\x02\x00\x06",
|
||||
'incD01A.xex' =>
|
||||
"\xFF\xFF\x00\x06\x39\x06" .
|
||||
"\x78\xEE\x0E\xD4\xEE\x00\xD4" .
|
||||
"\xEE\x1A\xD0" x 16 .
|
||||
"\x4C\x07\x06" .
|
||||
"\xE0\x02\xE1\x02\x00\x06",
|
||||
'flash.xex' =>
|
||||
"\xFF\xFF\x00\x06\x1B\x06" .
|
||||
"\x78\xA9\x00\x8D\x0E\xD4\x8D\x00\xD4" .
|
||||
"\x8D\x0A\xD4\x8D\x0A\xD4" .
|
||||
"\xAE\x0B\xD4\xD0\xF5" .
|
||||
"\x8D\x1A\xD0\x49\xA4" .
|
||||
"\x4C\x09\x06" .
|
||||
"\xE0\x02\xE1\x02\x00\x06",
|
||||
'ramread.xex' =>
|
||||
"\xFF\xFF\x00\x06" . pack('v', 0x060b + 3 * @hwregs) .
|
||||
"\x78\xA9\x00\x8D\x0E\xD4\x8D\x00\xD4" .
|
||||
"\xAD\xFF\x05" x @hwregs .
|
||||
"\x4C\x09\x06" .
|
||||
"\xE0\x02\xE1\x02\x00\x06",
|
||||
'ramstore.xex' =>
|
||||
"\xFF\xFF\x00\x06" . pack('v', 0x060b + 3 * @hwregs) .
|
||||
"\x78\xA9\x00\x8D\x0E\xD4\x8D\x00\xD4" .
|
||||
"\x8D\xFF\x05" x @hwregs .
|
||||
"\x4C\x09\x06" .
|
||||
"\xE0\x02\xE1\x02\x00\x06",
|
||||
'hwread.xex' =>
|
||||
"\xFF\xFF\x00\x06" . pack('v', 0x060b + 3 * @hwregs) .
|
||||
"\x78\xA9\x00\x8D\x0E\xD4\x8D\x00\xD4" .
|
||||
join('', map("\xAD" . pack('v', $_), @hwregs)) .
|
||||
"\x4C\x09\x06" .
|
||||
"\xE0\x02\xE1\x02\x00\x06",
|
||||
'hwstore.xex' =>
|
||||
"\xFF\xFF\x00\x06" . pack('v', 0x060b + 3 * @hwregs) .
|
||||
"\x78\xA9\x00\x8D\x0E\xD4\x8D\x00\xD4" .
|
||||
join('', map("\x8D" . pack('v', $_), @hwregs)) .
|
||||
"\x4C\x09\x06" .
|
||||
"\xE0\x02\xE1\x02\x00\x06"
|
||||
);
|
||||
|
||||
# write a built-in program to a file
|
||||
sub generate_program($) {
|
||||
my $program = shift;
|
||||
print "Generating $program\n";
|
||||
open XEX, ">benchmark/$program"
|
||||
and binmode XEX
|
||||
and print XEX $programs{$program}
|
||||
and close XEX
|
||||
or die "$!\n";
|
||||
}
|
||||
|
||||
# we will be working in the src directory
|
||||
if (-e 'atari.c') {
|
||||
# ok
|
||||
}
|
||||
elsif (-e '../src/atari.c') {
|
||||
# script was run from the util/ directory
|
||||
chdir '../src' or die "Can't chdir to '../src'\n";
|
||||
}
|
||||
else {
|
||||
die "atari.c not found\n";
|
||||
}
|
||||
|
||||
# supported targets
|
||||
my @targets = qw(
|
||||
default falcon windx x11 x11-motif x11-shm
|
||||
x11-xview x11-xview-shm motif shm xview xview-shm
|
||||
);
|
||||
|
||||
my $help_me = 0;
|
||||
|
||||
# get command line options
|
||||
for (@ARGV) {
|
||||
if (/^--test=(.+)/) {
|
||||
$test = $1;
|
||||
}
|
||||
elsif (/^--target=(.+)/) {
|
||||
$target = $1;
|
||||
grep $target eq $_, @targets or die "$target is not a valid target\n";
|
||||
}
|
||||
elsif (/^--cflags=(.+)/) {
|
||||
$cflags = $1;
|
||||
}
|
||||
elsif (/^--program=(.+)/) {
|
||||
$reference_program = $1;
|
||||
}
|
||||
elsif (/^--frames=(\d+)$/) {
|
||||
$frames = $1;
|
||||
}
|
||||
elsif (/^--output=(.+)/) {
|
||||
$output = $1;
|
||||
}
|
||||
elsif ($_ eq '--generate-programs') {
|
||||
make_directory();
|
||||
generate_program($_) for sort keys %programs;
|
||||
exit;
|
||||
}
|
||||
elsif (/^-?-h(elp)?$/) {
|
||||
$help_me = 1;
|
||||
}
|
||||
else {
|
||||
push @features, $_;
|
||||
}
|
||||
}
|
||||
|
||||
# gfx-generating target: windx on Win32, default otherwise
|
||||
my $gfx_target = 'default';
|
||||
if ($^O =~ /win/i) {
|
||||
$gfx_target = 'windx';
|
||||
}
|
||||
|
||||
# must initialize this after parsing the command line
|
||||
# in order to fill in $reference_program
|
||||
my %tests = (
|
||||
'default' => {
|
||||
'target' => $gfx_target,
|
||||
'cflags' => '-D DONT_DISPLAY',
|
||||
'run' => [ $reference_program, 'blank.xex' ]
|
||||
},
|
||||
'basic' => {
|
||||
'target' => 'default',
|
||||
'run' => [ $reference_program, 'blank.xex' ]
|
||||
},
|
||||
'monitorbreak' => {
|
||||
'target' => 'default',
|
||||
'config' => [ '--disable-monitorbreak', '--enable-monitorbreak' ],
|
||||
'run' => [ $reference_program ],
|
||||
},
|
||||
'pagedattrib' => {
|
||||
'target' => 'default',
|
||||
'config' => [ '--disable-pagedattrib', '--enable-pagedattrib' ],
|
||||
'run' => [ $reference_program, 'ramread.xex', 'ramstore.xex', 'hwread.xex', 'hwstore.xex' ],
|
||||
},
|
||||
'cycleexact' => {
|
||||
'target' => $gfx_target,
|
||||
'cflags' => '-D DONT_DISPLAY',
|
||||
'config' => [ '--disable-newcycleexact', '--enable-newcycleexact' ],
|
||||
'run' => [ $reference_program, 'incD01A.xex' ]
|
||||
},
|
||||
'display' => {
|
||||
'target' => $gfx_target,
|
||||
'run' => [ $reference_program, 'blank.xex', 'flash.xex' ]
|
||||
}
|
||||
);
|
||||
|
||||
if (@ARGV == 0 || $help_me) {
|
||||
# display help and exit
|
||||
print <<EOF;
|
||||
benchmark.pl tests performance of the Atari800 emulator with different
|
||||
configuration options and/or different Atari programs.
|
||||
|
||||
Available options:
|
||||
--test=<test> Choose test (required)
|
||||
--target=<target> Choose Atari800 target for the test
|
||||
--cflags="<cflags>" Override CFLAGS (default: "-O2 -Wall" + test-specific)
|
||||
--program=<filename> Choose Atari program to be run (defaults to $reference_program)
|
||||
--frames=<frames> Set number of frames to be run (defaults to $frames)
|
||||
--output=<filename> Output the results to the specified file
|
||||
--generate-programs Just generate all the built-in Atari programs
|
||||
Any other options are passed to the configure script. Use it to affect the set
|
||||
of optional features and external libraries used during the test.
|
||||
|
||||
Available tests:
|
||||
default Compare chosen Atari program with one that does nothing,
|
||||
using default configuration (may be modified
|
||||
with "--enable-<feature>", "--disable-<feature>")
|
||||
(default target: $gfx_target)
|
||||
basic Compare chosen Atari program with one that does nothing
|
||||
(default target: default)
|
||||
monitorbreak Compare configurations with/without MONITOR_BREAK
|
||||
(default target: default)
|
||||
pagedattrib Compare configurations with/without PAGED_ATTRIB
|
||||
(default target: default)
|
||||
cycleexact Compare configurations with/without NEW_CYCLE_EXACT
|
||||
(default target: $gfx_target)
|
||||
display Compare display performance with different Atari programs
|
||||
(default target: $gfx_target)
|
||||
|
||||
Available Atari800 targets:
|
||||
@targets[0..5]
|
||||
@targets[6..11]
|
||||
|
||||
EOF
|
||||
exit;
|
||||
}
|
||||
|
||||
unless (exists $tests{$test}) {
|
||||
die "$test is not an available test\n";
|
||||
}
|
||||
|
||||
# autoconf stuff
|
||||
unless (-e 'config.h.in') {
|
||||
print "'config.h.in' not found\n";
|
||||
run_command('autoheader');
|
||||
}
|
||||
unless (-e 'configure') {
|
||||
print "'configure' not found\n";
|
||||
run_command('autoconf');
|
||||
}
|
||||
|
||||
# create our directory under 'src/'
|
||||
make_directory();
|
||||
|
||||
# create Atari800 config file with ROM paths
|
||||
unless (-r 'benchmark/atari800.cfg') {
|
||||
print "'benchmark/atari800.cfg' does not exist, creating\n";
|
||||
open CFG, '>benchmark/atari800.cfg'
|
||||
and print CFG <<EOF
|
||||
Atari 800 Emulator, Version 1.4.0
|
||||
OS/A_ROM=benchmark/atariosa.rom
|
||||
OS/B_ROM=benchmark/atariosb.rom
|
||||
XL/XE_ROM=benchmark/atarixl.rom
|
||||
BASIC_ROM=benchmark/ataribas.rom
|
||||
5200_ROM=benchmark/atari5200.rom
|
||||
MACHINE_TYPE=Atari XL/XE
|
||||
RAM_SIZE=64
|
||||
EOF
|
||||
and close CFG
|
||||
or die "$!\n";
|
||||
}
|
||||
|
||||
# check if ROMs are configured
|
||||
print "Checking 'benchmark/atari800.cfg'\n";
|
||||
open CFG, 'benchmark/atari800.cfg' or die "$!\n";
|
||||
while (<CFG>) {
|
||||
m!^(?:XL/XE|BASIC)_ROM=(.*?)\s*$! or next;
|
||||
my $romfile = $1;
|
||||
unless (-r $romfile) {
|
||||
die <<EOF;
|
||||
$romfile not found.
|
||||
Place ROM files in the 'benchmark' directory or edit 'benchmark/atari800.cfg',
|
||||
then re-run this script.
|
||||
EOF
|
||||
}
|
||||
}
|
||||
close CFG;
|
||||
|
||||
# create output file
|
||||
unless ($output) {
|
||||
my ($sec, $min, $hour, $mday, $mon, $year) = localtime;
|
||||
$output = sprintf 'benchmark/%s_%04d-%02d-%02d_%02d-%02d-%02d.txt', $test,
|
||||
$year + 1900, $mon + 1, $mday, $hour, $min, $sec;
|
||||
}
|
||||
|
||||
print "Writing output to: $output\n";
|
||||
open OUT, ">$output" or die "$!\n";
|
||||
|
||||
print "Running test: $test\n";
|
||||
print OUT "Test: $test\n";
|
||||
|
||||
# get test settings
|
||||
my $test_settings = $tests{$test};
|
||||
|
||||
$target ||= $test_settings->{'target'};
|
||||
|
||||
$cflags ||= exists($test_settings->{'cflags'})
|
||||
? $default_cflags . ' ' . $test_settings->{'cflags'}
|
||||
: $default_cflags;
|
||||
$cflags .= ' -D BENCHMARK=' . $frames;
|
||||
$ENV{'CFLAGS'} = $cflags;
|
||||
print "Using CFLAGS: $cflags\n";
|
||||
print OUT "CFLAGS=$cflags\n";
|
||||
|
||||
# compile each configuration
|
||||
my @configs = $test_settings->{'config'} ? @{$test_settings->{'config'}} : ('');
|
||||
for my $config (@configs) {
|
||||
print '-' x 76, "\n";
|
||||
# "@{[]}" trick in this print is to avoid two consecutive spaces when @features is empty
|
||||
print OUT "./configure --target=$target --without-sound @{[@features, $config]}\n";
|
||||
run_command('sh', './configure', "--target=$target", '--without-sound', @features, split(' ', $config));
|
||||
run_command('make', 'clean');
|
||||
run_command('make');
|
||||
# run each program
|
||||
for my $program (@{$test_settings->{'run'}}) {
|
||||
if (-r $program) {
|
||||
# ok
|
||||
}
|
||||
elsif (-r "benchmark/$program") {
|
||||
$program = "benchmark/$program";
|
||||
}
|
||||
elsif (exists $programs{$program}) {
|
||||
generate_program($program);
|
||||
$program = "benchmark/$program";
|
||||
}
|
||||
else {
|
||||
die "$program does not exist\n";
|
||||
}
|
||||
my $result = pipe_command('./atari800', '-config', 'benchmark/atari800.cfg', $program);
|
||||
print $result;
|
||||
# parse result
|
||||
$result =~ /\d+ frames emulated in ([0-9.]+) seconds/
|
||||
or die "Expected 'frames emulated in'\n";
|
||||
my $speed_msg = "$1 seconds";
|
||||
# avoid division by zero
|
||||
if ($1 != 0) {
|
||||
# assuming PAL, real Atari needs (0.02 * $frames) time
|
||||
$speed_msg .= sprintf ' (%d%% of real Atari speed)', 100 * 0.02 * $frames / $1;
|
||||
}
|
||||
print "$speed_msg\n\n";
|
||||
printf OUT "./atari800 %-23s # %s\n", $program, $speed_msg;
|
||||
}
|
||||
}
|
||||
|
||||
print OUT "Test complete.\n";
|
||||
close OUT;
|
||||
@@ -0,0 +1,114 @@
|
||||
; Displays all pairs of hues
|
||||
; to test PAL delay line
|
||||
|
||||
org $8000
|
||||
main
|
||||
ldx $d40b
|
||||
rne
|
||||
stx $2c6
|
||||
mwa #dl $230
|
||||
mva #$a1 $22f
|
||||
mva #$20 $d000
|
||||
mva #$c0 $d001
|
||||
mva #$28 $d002
|
||||
dex
|
||||
txs
|
||||
txa
|
||||
ldy #8
|
||||
sta:rne $d007,y-
|
||||
sec
|
||||
init
|
||||
pha
|
||||
pha
|
||||
sbc #$11
|
||||
bcs init
|
||||
|
||||
frame
|
||||
lda $2fc
|
||||
and #$3f
|
||||
|
||||
ldx hlum+1
|
||||
cmp #$06
|
||||
bne nohdec
|
||||
dex:dex
|
||||
bpl seth
|
||||
nohdec
|
||||
cmp #$07
|
||||
bne nohinc
|
||||
cpx #$e
|
||||
bcs nokey
|
||||
inx:inx
|
||||
seth
|
||||
stx hlum+1
|
||||
mvy hex,x txt+18
|
||||
nohinc
|
||||
|
||||
ldx vlum+1
|
||||
cmp #$0e
|
||||
bne novdec
|
||||
dex:dex
|
||||
bpl setv
|
||||
novdec
|
||||
cmp #$0f
|
||||
bne novinc
|
||||
cpx #$e
|
||||
bcs nokey
|
||||
inx:inx
|
||||
setv
|
||||
stx vlum+1
|
||||
mvy hex,x txt+25
|
||||
novinc
|
||||
|
||||
cmp #$21
|
||||
bne nolin
|
||||
lda <dl2^dl
|
||||
eor:sta $230
|
||||
lda <$d40a^$d40b
|
||||
eor:sta delay+1
|
||||
lda #1
|
||||
eor:sta txt+31
|
||||
nolin
|
||||
nokey
|
||||
mva #$ff $2fc
|
||||
|
||||
hlum
|
||||
lda #$08
|
||||
ldy #15
|
||||
cpy $d40b
|
||||
rne
|
||||
sei
|
||||
mvx #1 dle
|
||||
delay
|
||||
sta $d40b
|
||||
clc
|
||||
bar
|
||||
ldy #6
|
||||
line
|
||||
sta $d40a
|
||||
sta $d01a
|
||||
sta $d014
|
||||
mvx #$00 $d01b
|
||||
sta $d40a
|
||||
vlum
|
||||
mvx #$08 $d01a
|
||||
stx $d014
|
||||
mvx #$c0 $d01b
|
||||
dey
|
||||
bne line
|
||||
adc #$10
|
||||
bcc bar
|
||||
mva #$41 dle
|
||||
sta $d40a
|
||||
sty $d014
|
||||
cli
|
||||
jmp frame
|
||||
|
||||
dl2 dta 0
|
||||
dl
|
||||
dta $70,$42,a(txt),$70
|
||||
dll dta $4f,a($1e0)
|
||||
dle dta 1,a(dll)
|
||||
txt dta d'ColorMix 1.0 HLum:8 VLum:8 Lin:0'
|
||||
hex dta d'0123456789ABCDEF'
|
||||
|
||||
run main
|
||||
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
; Displays 256 colors
|
||||
|
||||
org $8000
|
||||
main
|
||||
ldx $d40b
|
||||
rne
|
||||
mwa #dl $230
|
||||
mva #$a1 $22f
|
||||
asl @
|
||||
sta $26f
|
||||
mva #$20 $d000
|
||||
mva #$c0 $d001
|
||||
dex
|
||||
txs
|
||||
txa
|
||||
ldy #7
|
||||
sta:rne $d007,y-
|
||||
init
|
||||
pha
|
||||
pha
|
||||
sbc #$11
|
||||
bcs init
|
||||
tya
|
||||
|
||||
frame
|
||||
ldy #16
|
||||
cpy $d40b
|
||||
rne
|
||||
clc
|
||||
bar
|
||||
ldy #12
|
||||
ldx <dl+3
|
||||
line
|
||||
sta $d40a
|
||||
stx $d402
|
||||
dey
|
||||
bne line
|
||||
adc #$10
|
||||
sta $d01a
|
||||
bcc bar
|
||||
sty $d400
|
||||
bcs frame
|
||||
|
||||
dl
|
||||
dta $70,$70,$70,$4f,a($1e0)
|
||||
|
||||
run main
|
||||
Binary file not shown.
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/bin/sh
|
||||
# This scripts helps with building the source .tar.gz file
|
||||
|
||||
VER_MAJOR=3
|
||||
VER_MINOR=1
|
||||
VER_MICRO=0
|
||||
#
|
||||
VERSION=$VER_MAJOR"."$VER_MINOR"."$VER_MICRO
|
||||
TAG="ATARI800_"$VER_MAJOR"_"$VER_MINOR"_"$VER_MICRO
|
||||
#upper case the tag
|
||||
TAG=`echo $TAG | tr [:lower:] [:upper:]`
|
||||
FOLDER="atari800-"$VERSION
|
||||
FNAME=$FOLDER".tar.gz"
|
||||
#
|
||||
echo "download from CVS? (y/N)"
|
||||
read key
|
||||
if [ "x"$key = "xy" ]; then
|
||||
cvs -z9 -d:ext:joy@atari800.cvs.sourceforge.net:/cvsroot/atari800 export -r $TAG atari800
|
||||
fi
|
||||
#
|
||||
grep Atari800_TITLE atari800/src/atari.h | grep $VERSION >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: increase version in src/atari.h"
|
||||
exit 1
|
||||
fi
|
||||
grep "[Vv]ersion "$VERSION atari800/README.1ST >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: increase version in README.1ST"
|
||||
exit 1
|
||||
fi
|
||||
grep "[Vv]ersion "$VERSION atari800/DOC/README >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: increase version in DOC/README"
|
||||
exit 1
|
||||
fi
|
||||
grep "Atari800 "$VERSION atari800/src/atari800.man >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: increase version in src/atari800.man"
|
||||
exit 1
|
||||
fi
|
||||
grep "%define ver" atari800/atari800.spec | grep $VERSION >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: increase version in atari800.spec"
|
||||
exit 1
|
||||
fi
|
||||
grep "AC_INIT(Atari800, "$VERSION atari800/src/configure.ac | grep $VERSION >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: increase version in src/configure.ac"
|
||||
exit 1
|
||||
fi
|
||||
#
|
||||
cd atari800/src
|
||||
./autogen.sh
|
||||
# remove leftovers from autogen process
|
||||
rm -f autogen.sh config.cache config.log
|
||||
rm -rf autom4te.cache
|
||||
cd ../..
|
||||
mv atari800 $FOLDER
|
||||
GZIP=--best tar chozvf $FNAME $FOLDER
|
||||
@@ -0,0 +1,185 @@
|
||||
10 REM Atari BASIC program to test emulator's H: device.
|
||||
20 REM Usage: atari800 -hreadwrite -H1 /path/to/test/dir hdevtest.lst
|
||||
30 REM Be patient! It takes ca. 40 seconds to load this program.
|
||||
40 REM You can also boot SpartaDOS and select e.g. "D1:" to be tested.
|
||||
50 REM
|
||||
90 DIM DEV$(10),LOGFN$(200),FN$(200),T1$(20),T2$(20),T3$(20),D$(300),C$(5)
|
||||
100 ? "Device to be tested (Return=H1:) ";:INPUT DEV$
|
||||
110 IF DEV$="" THEN DEV$="H1:"
|
||||
120 IF LEN(DEV$)<>3 OR DEV$(3)<>":" THEN ? "Must be of form: Xn:":END
|
||||
130 ? "Output report to which file"
|
||||
140 ? "(Return=H6:hdevtest.log) ";:INPUT LOGFN$
|
||||
150 IF LOGFN$="" THEN LOGFN$="H6:hdevtest.log"
|
||||
160 TRAP 10100:OPEN #2,8,0,LOGFN$:? #2;"Testing: ";DEV$
|
||||
200 ? "Test: Write binary: ";:? #2;"Test: Write binary: ";
|
||||
210 TRAP 10200:FN$=DEV$:FN$(4)="DELETE.ME":OPEN #1,8,0,FN$:RESTORE 10250
|
||||
220 READ BYTE:IF BYTE<0 THEN 240
|
||||
230 PUT #1,BYTE:GOTO 220
|
||||
240 CLOSE #1:? "Passed":? #2;"Passed"
|
||||
300 ? "Test: Read binary: ";:? #2;"Test: Read binary: ";
|
||||
310 BYTE=0:TRAP 10300:OPEN #1,4,0,FN$:RESTORE 10250
|
||||
320 READ BYTE:GET #1,FROMFILE:IF FROMFILE=BYTE THEN 320
|
||||
330 ? "FAILED: Wrong data":? #2;"FAILED: Wrong data":CLOSE #1:GOTO 400
|
||||
340 CLOSE #1:? "Passed":? #2;"Passed"
|
||||
400 ? "Test: Append binary: ";:? #2;"Test: Append binary: ";
|
||||
410 TRAP 10400:OPEN #1,9,0,FN$:RESTORE 10450
|
||||
420 READ BYTE:IF BYTE<0 THEN 440
|
||||
430 PUT #1,BYTE:GOTO 420
|
||||
440 CLOSE #1:? "Passed":? #2;"Passed"
|
||||
500 ? "Test: Read binary: ";:? #2;"Test: Read binary: ";
|
||||
510 BYTE=0:TRAP 10500:OPEN #1,4,0,FN$:RESTORE 10250
|
||||
520 READ BYTE:IF BYTE=-1 THEN READ BYTE
|
||||
530 GET #1,FROMFILE:IF FROMFILE=BYTE THEN 520
|
||||
540 ? "FAILED: Wrong data":? #2;"FAILED: Wrong data":CLOSE #1:GOTO 600
|
||||
550 CLOSE #1:? "Passed":? #2;"Passed"
|
||||
600 ? "Test: Update+Note+Point: ";:? #2;"Test: Update binary + Note + Point: ";
|
||||
610 TRAP 10600:OPEN #1,12,0,FN$:RESTORE 10250
|
||||
620 READ BYTE:IF BYTE<0 THEN 650
|
||||
630 GET #1,FROMFILE:IF FROMFILE=BYTE THEN 620
|
||||
640 ? "FAILED: Wrong data":? #2;"FAILED: Wrong data":CLOSE #1:GOTO 700
|
||||
650 NOTE #1,OFS1,OFS2:GET #1,FROMFILE:PUT #1,16:PUT #1,17:POINT #1,OFS1,OFS2
|
||||
660 GET #1,B1:GET #1,B2:GET #1,B3:GET #1,B4:IF B1=5 AND B2=16 AND B3=17 AND B4=8 THEN 690
|
||||
670 ? "FAILED: Wrong data: ";B1;",";B2;",";B3;",";B4
|
||||
680 ? #2;"FAILED: Wrong data: ";B1;",";B2;",";B3;",";B4:CLOSE #1:GOTO 700
|
||||
690 CLOSE #1:? "Passed":? #2;"Passed"
|
||||
700 IF DEV$(1,1)<>"H" THEN 1000
|
||||
710 ? "Test: Write text: ";:? #2;"Test: Write text: ";
|
||||
720 TRAP 10700:FN$(2,2)=CHR$(ASC(FN$(2,2))+5):OPEN #1,8,0,FN$
|
||||
730 REM Don't write CRLF, because it may get translated to CRCRLF
|
||||
740 ? #1;"Native EOL":? #1;"CR";CHR$(13);"LF";CHR$(10);
|
||||
750 CLOSE #1:? "Passed":? #2;"Passed"
|
||||
800 ? "Test: Read text: ";:? #2;"Test: Read text: ";
|
||||
810 TRAP 10800:OPEN #1,4,0,FN$:INPUT #1,T1$,T2$,T3$:CLOSE #1
|
||||
820 IF T1$<>"Native EOL" OR T2$<>"CR" OR T3$<>"LF" THEN ? "FAILED: Wrong data":? #2;"FAILED: Wrong data":GOTO 1000
|
||||
830 ? "Passed":? #2;"Passed"
|
||||
1000 ? "Test: Make directory: ";:? #2;"Test: Make directory: ";
|
||||
1010 TRAP 11000:FN$=DEV$:FN$(4)="TEMP.DIR":XIO 42,#1,0,0,FN$
|
||||
1020 ? "Passed":? #2;"Passed"
|
||||
1100 ? "Test: Directory handling: ";:? #2;"Test: Directory handling: ";
|
||||
1110 TRAP 11100:FN$(4)="TEMP.DIR>REMOVE.ME":OPEN #1,8,0,FN$:PUT #1,5:CLOSE #1
|
||||
1120 FN$(4)="TEMP.DIR>REMOVE.ME":GOSUB 1200:FN$(4)="TEMP.DIR\REMOVE.ME":GOSUB 1200
|
||||
1130 IF DEV$(1,1)="H" THEN FN$(4)="TEMP.DIR/REMOVE.ME":GOSUB 1200:FN$(4)="TEMP.DIR:REMOVE.ME":GOSUB 1200
|
||||
1140 FN$(4)="TEMP.DIR":XIO 44,#1,0,0,FN$:REM Change directory
|
||||
1150 FN$(4)="REMOVE.ME":GOSUB 1200:FN$(4)="<TEMP.DIR>REMOVE.ME":GOSUB 1200
|
||||
1160 FN$(4)="..\TEMP.DIR\REMOVE.ME":GOSUB 1200:IF DEV$(1,1)="H" THEN FN$(4)="../TEMP.DIR/REMOVE.ME":GOSUB 1200
|
||||
1170 FN$(4)="..":XIO 44,#1,0,0,FN$:REM Change directory
|
||||
1180 ? "Passed":? #2;"Passed":GOTO 1300
|
||||
1200 OPEN #1,4,0,FN$:GET #1,FROMFILE:CLOSE #1
|
||||
1210 IF FROMFILE<>5 THEN ? "FAILED: Wrong data":? #2;"FAILED: Wrong data":POP:GOTO 1300
|
||||
1220 RETURN
|
||||
1300 ? "Test: Read directory:":? #2;"Test: Read directory:"
|
||||
1310 AUX2=0:FN$(4)="*.*":GOSUB 1400:FN$(4)="*.M?":GOSUB 1400:FN$(4)=">?EL??E.M*":GOSUB 1400
|
||||
1320 FN$(4)="NOMATCH.*":GOSUB 1400:FN$(4)="TEMP.DIR>*.*":GOSUB 1400:FN$(4)="TEMP.DIR\NOMATCH.*":GOSUB 1400
|
||||
1330 AUX2=128:FN$(4)="*.*":GOSUB 1400:FN$(4)="*.M?":GOSUB 1400:FN$(4)=">?EL??E.M*":GOSUB 1400
|
||||
1340 FN$(4)="TEMP.DIR>*.*":GOSUB 1400:FN$(4)="TEMP.DIR>*.*":GOSUB 1400:FN$(4)="TEMP.DIR\NOMATCH.*":GOSUB 1400
|
||||
1350 ? "Finished":? #2;"Finished":GOTO 1500
|
||||
1400 IF AUX2>=128 THEN ? "Extended directory of ";FN$:? #2;"Extended directory of ";FN$:GOTO 1420
|
||||
1410 ? "Directory of ";FN$:? #2;"Directory of ";FN$
|
||||
1420 TRAP 11400:OPEN #1,6,AUX2,FN$
|
||||
1430 INPUT #1,D$:? D$:? #2;D$:GOTO 1430
|
||||
1500 IF DEV$(1,1)<>"H" THEN 1600
|
||||
1510 ? "Test: Access outside: ";:? #2;"Test: Access outside: ";
|
||||
1520 TRAP 1530:FN$(4)="..\*.*":OPEN #1,6,0,FN$:CLOSE #1:? "FAILED: Possible":? #2;"FAILED: Possible":GOTO 1600
|
||||
1530 TRAP 1550:FN$(4)=">..>*.*":CLOSE #1:OPEN #1,6,0,FN$:CLOSE #1
|
||||
1540 ? "FAILED: Possible":? #2;"FAILED: Possible":GOTO 1600
|
||||
1550 CLOSE #1:? "Passed (not allowed)":? #2;"Passed (not allowed)"
|
||||
1600 ? "Test: File length: ";:? #2;"Test: File length: ";
|
||||
1610 TRAP 11600:FN$(4)="RENAME.ME":OPEN #1,8,0,FN$:PUT #1,1:PUT #1,2:PUT #1,3:CLOSE #1
|
||||
1620 OPEN #1,4,0,FN$:XIO 39,#1,0,0,FN$:LEN=PEEK(860)+256*PEEK(861)+65536*PEEK(862):CLOSE #1
|
||||
1630 IF LEN<>3 THEN ? "FAILED: Returned ";LEN:? #2;"FAILED: Returned ";LEN:GOTO 1700
|
||||
1640 ? "Passed":? #2;"Passed"
|
||||
1700 ? "Test: Rename: ";:? #2;"Test: Rename: ";
|
||||
1710 TRAP 11700:FN$(4)="RENAME.ME,R?????D":XIO 32,#1,0,0,FN$
|
||||
1720 TRAP 1730:FN$(4)="RENAME.ME":OPEN #1,4,0,FN$:CLOSE #1:? "FAILED":? #2;"FAILED":GOTO 1800
|
||||
1730 TRAP 11700:FN$(4)="RENAMED":CLOSE #1:OPEN #1,4,0,FN$:CLOSE #1
|
||||
1740 ? "Passed":? #2;"Passed"
|
||||
1800 ? "Test: Lock: ";:? #2;"Test: Lock: ";
|
||||
1810 TRAP 11800:FN$(4)="LOCK.ME":OPEN #1,8,0,FN$:CLOSE #1:XIO 35,#1,0,0,FN$
|
||||
1820 TRAP 1830:OPEN #1,8,0,FN$:CLOSE #1:? "FAILED: Overwritten":? #2;"FAILED: Overwritten":GOTO 2000
|
||||
1830 CLOSE #1:TRAP 1840:XIO 33,#1,0,0,FN$:? "FAILED: Deleted":? #2;"FAILED: Deleted":GOTO 2000
|
||||
1840 TRAP 1850:FN$(4)="LOCK.ME,OHNO":XIO 32,#1,0,0,FN$:? "FAILED: Renamed":? #2;"FAILED: Renamed":GOTO 2000
|
||||
1850 ? :? #2:FN$(4)="*.*":? "Directory of ";FN$:? #2;"Directory of ";FN$:TRAP 11810:OPEN #1,6,0,FN$
|
||||
1860 INPUT #1,D$:? D$:? #2;D$:GOTO 1860
|
||||
1870 CLOSE #1:? "Finished":? #2;"Finished"
|
||||
2000 ? "Test: Disk info: ";:? #2;"Test: Disk info: ";
|
||||
2010 TRAP 12000:FN$(4)="ANYTHING":CMD=47:L=16:GOSUB 2090:GOTO 2200
|
||||
2080 ? CHR$(34);FN$;CHR$(34);"=";:? #2;CHR$(34);FN$;CHR$(34);"=";:L=0
|
||||
2090 POKE 850,CMD:FN$(LEN(FN$)+1)=CHR$(155):INBUF=ADR(FN$):POKE 852,ASC(CHR$(INBUF)):POKE 853,INT(INBUF/256):I=0
|
||||
2100 D$="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx":OUTBUF=ADR(D$):POKE 856,ASC(CHR$(OUTBUF)):POKE 857,INT(OUTBUF/256)
|
||||
2110 POKE 960,104:POKE 961,162:POKE 962,16:POKE 963,76:POKE 964,86:POKE 965,228:I=USR(960)
|
||||
2120 IF PEEK(851)>=128 THEN POP:POKE 195,PEEK(851):GOTO PEEK(188)+256*PEEK(189):REM Goto TRAP handler
|
||||
2130 IF L>0 THEN 2150
|
||||
2140 IF L<30 AND ASC(D$(L+1,L+1))<>0 THEN L=L+1:GOTO 2140
|
||||
2150 ? CHR$(34);:? #2;CHR$(34);:IF L=0 THEN 2190
|
||||
2160 FOR I=1 TO L:C$=D$(I,I):C=ASC(C$)
|
||||
2170 IF C<32 OR C>122 THEN C$="\x":C$(3)=CHR$(48+INT(C/16)+7*(C>159)):C=C-16*INT(C/16):C$(4)=CHR$(48+C+7*(C>9))
|
||||
2180 ? C$;:? #2;C$;:NEXT I
|
||||
2190 ? CHR$(34):? #2;CHR$(34):RETURN
|
||||
2200 ? "Test: To absolute path:":? #2;"Test: To absolute path:"
|
||||
2210 TRAP 12200:CMD=48:FN$(4)="":GOSUB 2080:FN$(4)=">":GOSUB 2080
|
||||
2220 FN$(4)="TEMP.DIR":GOSUB 2080:FN$(4)="TEMP.DIR>":GOSUB 2080
|
||||
2230 FN$(4)="TEMP.DIR":? "Changing directory to ";FN$:? #2;"Changing directory to ";FN$:XIO 44,#1,0,0,FN$
|
||||
2240 FN$(4)="":GOSUB 2080:FN$(4)="\":GOSUB 2080:FN$(4)="..":GOSUB 2080
|
||||
2250 FN$(4)="<":GOSUB 2080:FN$(4)="<TEMP.DIR":GOSUB 2080
|
||||
2260 FN$(4)="..\TEMP.DIR\":GOSUB 2080:IF DEV$(1,1)="H" THEN FN$(4)="../TEMP.DIR":GOSUB 2080
|
||||
2270 FN$(4)=">":XIO 44,#1,0,0,FN$:REM Change directory
|
||||
2280 ? "Finished":? #2;"Finished"
|
||||
2300 ? "Test: Delete file: ";:? #2;"Test: Delete file: ";
|
||||
2310 TRAP 12300:FN$(4)="DELETE.ME":XIO 33,#1,0,0,FN$:FN$(4)="RENAMED":XIO 33,#1,0,0,FN$
|
||||
2320 TRAP 2330:OPEN #1,4,0,FN$:CLOSE #1:? "FAILED: File exists":? #2;"FAILED: File exists":GOTO 2400
|
||||
2330 TRAP 12300:FN$(4)="TEMP.DIR>REMO*.*":XIO 33,#1,0,0,FN$:FN$(4)="TEMP.DIR>REMOVE.ME"
|
||||
2340 TRAP 2350:OPEN #1,4,0,FN$:CLOSE #1:? "FAILED: File exists":? #2;"FAILED: File exists":GOTO 2400
|
||||
2350 CLOSE #1:TRAP 2370:FN$(4)="LOCK.ME":XIO 33,#1,0,0,FN$
|
||||
2360 ? "FAILED: Deleted locked file":? #2;"FAILED: Deleted locked file":GOTO 2400
|
||||
2370 TRAP 12300:XIO 36,#1,0,0,FN$:XIO 33,#1,0,0,FN$
|
||||
2380 ? "Passed":? #2;"Passed"
|
||||
2400 ? "Test: Remove directory: ";:? #2;"Test: Remove directory: ";
|
||||
2410 TRAP 12400:FN$(4)="TEMP.DIR":XIO 43,#1,0,0,FN$
|
||||
2420 TRAP 2430:XIO 44,#1,0,0,FN$:? "FAILED: Can CD":? #2;"FAILED: Can CD":FN$(4)=">":XIO 44,#1,0,0,FN$:GOTO 2500
|
||||
2430 ? "Passed":? #2;"Passed"
|
||||
2500 ? "Test: Load executable (Sparta): ";:? #2;"Test: Load executable (Sparta): ";
|
||||
2510 TRAP 12500:FN$(4)="TEMP.XEX":OPEN #1,8,0,FN$:PUT #1,255:PUT #1,255
|
||||
2520 PUT #1,192:PUT #1,3:PUT #1,192:PUT #1,3:PUT #1,15:CLOSE #1:XIO 40,#1,0,128,FN$
|
||||
2530 IF PEEK(960)<>15 THEN ? "FAILED: Not loaded":? #2;"FAILED: Not loaded":GOTO 2600
|
||||
2540 IF DEV$(1,1)<>"H" THEN 2590
|
||||
2550 FN$(4)=">DOS":XIO 42,#1,0,0,FN$:FN$(4)=">DOS>ONPATH.XEX":OPEN #1,8,0,FN$:PUT #1,255:PUT #1,255
|
||||
2560 PUT #1,192:PUT #1,3:PUT #1,192:PUT #1,3:PUT #1,25:CLOSE #1:FN$(4)="ONPATH.XEX":XIO 40,#1,0,128,FN$
|
||||
2570 FN$(4)=">DOS>ONPATH.XEX":XIO 33,#1,0,0,FN$:FN$(4)=">DOS":XIO 43,#1,0,0,FN$:REM Delete file and directory
|
||||
2580 IF PEEK(960)<>25 THEN ? "FAILED: Not found on PATH":? #2;"FAILED: Not found on PATH":GOTO 2600
|
||||
2590 ? "Passed":? #2;"Passed"
|
||||
2600 IF DEV$(1,1)<>"H" THEN FN$(4)="TEMP.XEX":XIO 33,#1,0,0,FN$:GOTO 2700
|
||||
2610 ? "Test: Load executable (MyDOS): ";:? #2;"Test: Load executable (MyDOS): ";
|
||||
2620 TRAP 12600:POKE 960,0:FN$(4)="TEMP.XEX":XIO 39,#1,7,0,FN$:XIO 33,#1,0,0,FN$:REM Load and delete
|
||||
2630 IF PEEK(960)<>15 THEN ? "FAILED: Not loaded":? #2;"FAILED: Not loaded":GOTO 2700
|
||||
2640 ? "Passed":? #2;"Passed"
|
||||
2700 REM
|
||||
9000 ? "End of tests":? #2;"End of tests":CLOSE #2:END
|
||||
10100 ? "Error ";PEEK(195);" opening ";LOGFN$
|
||||
10110 IF LOGFN$(1,1)="H" AND PEEK(195)=163 THEN ? "You should enable write to H: devices"
|
||||
10120 END
|
||||
10200 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 300
|
||||
10250 DATA 0,1,2,3,4,13,10,26,65,96,155,255,-1
|
||||
10300 IF PEEK(195)=136 AND BYTE<0 THEN 340
|
||||
10310 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 400
|
||||
10400 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 500
|
||||
10450 DATA 5,6,7,8,9,13,10,26,66,98,155,255,-2
|
||||
10500 IF PEEK(195)=136 AND BYTE<0 THEN 550
|
||||
10510 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 600
|
||||
10600 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 700
|
||||
10700 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 800
|
||||
10800 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 1000
|
||||
11000 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 1100
|
||||
11100 ? "FAILED: Error ";PEEK(195);" for ";FN$:? #2;"FAILED: Error ";PEEK(195);" for ";FN$:CLOSE #1:GOTO 1300
|
||||
11400 IF PEEK(195)=136 THEN CLOSE #1:RETURN
|
||||
11410 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 1500
|
||||
11600 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 1700
|
||||
11700 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 1800
|
||||
11800 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 2000
|
||||
11810 IF PEEK(195)=136 THEN 1870
|
||||
11820 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 2000
|
||||
12000 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 2200
|
||||
12200 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 2300
|
||||
12300 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 2400
|
||||
12400 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 2500
|
||||
12500 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 2600
|
||||
12600 ? "FAILED: Error ";PEEK(195):? #2;"FAILED: Error ";PEEK(195):CLOSE #1:GOTO 2700
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,376 @@
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* Atari800 Atari 800XL, etc. emulator *
|
||||
* ---------------------------------------------------------------------- *
|
||||
* POKEY Chip Emulator, *
|
||||
* "POKEYBENCH" Test and benchmark program for developers, V1.3 *
|
||||
* by Michael Borisov *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* License Information and Copyright Notice *
|
||||
* ======================================== *
|
||||
* *
|
||||
* Pokeybench is Copyright(c) 2002 by Michael Borisov *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||
* Boston, MA 02110-1301, USA. *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "pokeysnd.h"
|
||||
#include "mzpokeysnd.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
/* How many seconds of sound to generate per each test trial */
|
||||
#define MZM_TRIAL_TIME 2
|
||||
|
||||
/* How many samples per each buffer run */
|
||||
#define MZM_BUF_SAMPLES 100
|
||||
|
||||
/* How many test trials to run for statistics */
|
||||
#define TEST_TRIALS 5
|
||||
|
||||
/* How many seconds of sound to save in the outfile */
|
||||
#define MZM_SAVE_TIME 10
|
||||
|
||||
|
||||
/* Wrapper for fgets, removes trailing whitespace */
|
||||
char* fgetl(char* s, int len, FILE* fs)
|
||||
{
|
||||
char* s2;
|
||||
int i;
|
||||
|
||||
s2 = fgets(s,len,fs);
|
||||
if(s2 == NULL)
|
||||
return s2;
|
||||
for(i=strlen(s)-1; i>=0; i--)
|
||||
if(isspace(s[i]))
|
||||
s[i] = '\0';
|
||||
return s2;
|
||||
}
|
||||
|
||||
int pktest(unsigned char *audf, unsigned char *audc, unsigned char audctl,
|
||||
const char* ofn8, const char* ofn16,
|
||||
unsigned short samplerate)
|
||||
{
|
||||
unsigned char* buf;
|
||||
short* buf16;
|
||||
double rate;
|
||||
double rasum;
|
||||
double rasum2;
|
||||
double varian;
|
||||
double stddev;
|
||||
unsigned long samremain, samproc;
|
||||
int i;
|
||||
time_t start,finish;
|
||||
FILE* ft;
|
||||
|
||||
buf = malloc(MZM_BUF_SAMPLES);
|
||||
if(buf == NULL)
|
||||
{
|
||||
printf("Out of memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(i=Pokey_sound_init(1790000,samplerate,1,0,1))
|
||||
{
|
||||
printf("Error initializing Pokey sound: %d\n",i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Update_pokey_sound(_AUDF1,audf[0],0,1);
|
||||
Update_pokey_sound(_AUDC1,audc[0],0,1);
|
||||
Update_pokey_sound(_AUDF2,audf[1],0,1);
|
||||
Update_pokey_sound(_AUDC2,audc[1],0,1);
|
||||
Update_pokey_sound(_AUDF3,audf[2],0,1);
|
||||
Update_pokey_sound(_AUDC3,audc[2],0,1);
|
||||
Update_pokey_sound(_AUDF4,audf[3],0,1);
|
||||
Update_pokey_sound(_AUDC4,audc[3],0,1);
|
||||
Update_pokey_sound(_AUDCTL,audctl,0,1);
|
||||
Pokey_debugreset(0);
|
||||
|
||||
|
||||
rasum = 0.0;
|
||||
rasum2 = 0.0;
|
||||
|
||||
for(i=0; i<TEST_TRIALS; i++)
|
||||
{
|
||||
rate = 0.0;
|
||||
/* Wait for a change in system time (seconds)
|
||||
to ensure start when a full second begins */
|
||||
time(&start);
|
||||
do
|
||||
{
|
||||
time(&finish);
|
||||
} while(difftime(finish,start) == 0.0);
|
||||
|
||||
start = finish; /* Test start time */
|
||||
/* Generate until test time elapses */
|
||||
do
|
||||
{
|
||||
Pokey_process(buf,MZM_BUF_SAMPLES);
|
||||
rate += MZM_BUF_SAMPLES;
|
||||
time(&finish);
|
||||
} while(difftime(finish,start) < MZM_TRIAL_TIME);
|
||||
|
||||
rate /= MZM_TRIAL_TIME;
|
||||
|
||||
printf("Trial %2d: %10.0f samples/sec\n",
|
||||
i+1, rate);
|
||||
fflush(stdout);
|
||||
rasum += rate;
|
||||
rasum2 += rate*rate;
|
||||
}
|
||||
|
||||
printf("\nAverage %10.0f samples/sec\n",rasum/TEST_TRIALS);
|
||||
|
||||
varian = (rasum2 - rasum*rasum/TEST_TRIALS)/(TEST_TRIALS-1);
|
||||
stddev = sqrt(varian);
|
||||
|
||||
printf("Standard deviation: %10.0f samples/sec\n",stddev);
|
||||
|
||||
printf("Gen/play ratio = %3.1f\n",rasum/TEST_TRIALS/samplerate);
|
||||
|
||||
/* And now, write 8-bit output file */
|
||||
|
||||
if(i=Pokey_sound_init(1790000,samplerate,1,0,1))
|
||||
{
|
||||
printf("Error initializing Pokey sound: %d\n",i);
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
Update_pokey_sound(_AUDF1,audf[0],0,1);
|
||||
Update_pokey_sound(_AUDC1,audc[0],0,1);
|
||||
Update_pokey_sound(_AUDF2,audf[1],0,1);
|
||||
Update_pokey_sound(_AUDC2,audc[1],0,1);
|
||||
Update_pokey_sound(_AUDF3,audf[2],0,1);
|
||||
Update_pokey_sound(_AUDC3,audc[2],0,1);
|
||||
Update_pokey_sound(_AUDF4,audf[3],0,1);
|
||||
Update_pokey_sound(_AUDC4,audc[3],0,1);
|
||||
Update_pokey_sound(_AUDCTL,audctl,0,1);
|
||||
Pokey_debugreset(0);
|
||||
|
||||
if(!(ft=fopen(ofn8,"wb")))
|
||||
{
|
||||
perror(ofn8);
|
||||
free(buf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
samremain = samplerate*MZM_SAVE_TIME;
|
||||
while(samremain>0)
|
||||
{
|
||||
if(samremain>=MZM_BUF_SAMPLES)
|
||||
{
|
||||
samproc = MZM_BUF_SAMPLES;
|
||||
}
|
||||
else
|
||||
{
|
||||
samproc = samremain;
|
||||
}
|
||||
Pokey_process(buf,(unsigned short)samproc);
|
||||
i = fwrite(buf,1,samproc,ft);
|
||||
if(i<samproc)
|
||||
{
|
||||
perror(ofn8);
|
||||
free(buf);
|
||||
fclose(ft);
|
||||
return 2;
|
||||
}
|
||||
samremain -= samproc;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
fclose(ft);
|
||||
|
||||
/* Write 16-bit output file */
|
||||
|
||||
if(i=Pokey_sound_init(1790000,samplerate,1,SND_BIT16,1))
|
||||
{
|
||||
printf("Error initializing Pokey sound: %d\n",i);
|
||||
return 1;
|
||||
}
|
||||
Update_pokey_sound(_AUDF1,audf[0],0,1);
|
||||
Update_pokey_sound(_AUDC1,audc[0],0,1);
|
||||
Update_pokey_sound(_AUDF2,audf[1],0,1);
|
||||
Update_pokey_sound(_AUDC2,audc[1],0,1);
|
||||
Update_pokey_sound(_AUDF3,audf[2],0,1);
|
||||
Update_pokey_sound(_AUDC3,audc[2],0,1);
|
||||
Update_pokey_sound(_AUDF4,audf[3],0,1);
|
||||
Update_pokey_sound(_AUDC4,audc[3],0,1);
|
||||
Update_pokey_sound(_AUDCTL,audctl,0,1);
|
||||
Pokey_debugreset(0);
|
||||
|
||||
|
||||
buf16 = malloc(2*MZM_BUF_SAMPLES);
|
||||
if(buf16 == NULL)
|
||||
{
|
||||
printf("Out of memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!(ft=fopen(ofn16,"wb")))
|
||||
{
|
||||
perror(ofn16);
|
||||
free(buf16);
|
||||
return 2;
|
||||
}
|
||||
|
||||
samremain = samplerate*MZM_SAVE_TIME;
|
||||
while(samremain>0)
|
||||
{
|
||||
if(samremain>=MZM_BUF_SAMPLES)
|
||||
{
|
||||
samproc = MZM_BUF_SAMPLES;
|
||||
}
|
||||
else
|
||||
{
|
||||
samproc = samremain;
|
||||
}
|
||||
Pokey_process(buf16,(unsigned short)samproc);
|
||||
i = fwrite(buf16,2,samproc,ft);
|
||||
if(i<samproc)
|
||||
{
|
||||
perror(ofn16);
|
||||
free(buf16);
|
||||
fclose(ft);
|
||||
return 2;
|
||||
}
|
||||
samremain -= samproc;
|
||||
}
|
||||
|
||||
free(buf16);
|
||||
fclose(ft);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char paramfn[256];
|
||||
char ofn8[256];
|
||||
char ofn16[256];
|
||||
FILE* fs;
|
||||
unsigned int params[10];
|
||||
unsigned char audf[4];
|
||||
unsigned char audc[4];
|
||||
unsigned int tmp;
|
||||
int i;
|
||||
int ecode;
|
||||
|
||||
printf("PokeyBench (c) 2002 by Michael Borisov\n\n");
|
||||
|
||||
/* Get command-line parameters */
|
||||
if(argc<2)
|
||||
{
|
||||
printf("Enter parameter file name: ");
|
||||
fflush(stdout);
|
||||
if(fgetl(paramfn,256,stdin) == NULL)
|
||||
{
|
||||
printf("Bad input\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(paramfn,argv[1],255);
|
||||
paramfn[255] = '\0';
|
||||
}
|
||||
|
||||
if(argc<3)
|
||||
{
|
||||
printf("Enter output file name (8-bit): ");
|
||||
fflush(stdout);
|
||||
if(fgetl(ofn8,256,stdin) == NULL)
|
||||
{
|
||||
printf("Bad input\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(ofn8,argv[2],255);
|
||||
ofn8[255] = '\0';
|
||||
}
|
||||
|
||||
if(argc<4)
|
||||
{
|
||||
printf("Enter output file name (16-bit): ");
|
||||
fflush(stdout);
|
||||
if(fgetl(ofn16,256,stdin) == NULL)
|
||||
{
|
||||
printf("Bad input\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(ofn16,argv[3],255);
|
||||
ofn16[255] = '\0';
|
||||
}
|
||||
|
||||
|
||||
/* Read parameter file */
|
||||
if(!(fs = fopen(paramfn,"r")))
|
||||
{
|
||||
perror(paramfn);
|
||||
return 2;
|
||||
}
|
||||
|
||||
for(i=0; i<10; i++)
|
||||
{
|
||||
ecode = fscanf(fs,"%u",&tmp);
|
||||
if(ecode == EOF)
|
||||
{
|
||||
if(ferror(fs))
|
||||
{
|
||||
perror(paramfn);
|
||||
fclose(fs);
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s: Unexpected end of file\n", paramfn);
|
||||
fclose(fs);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else if(ecode != 1)
|
||||
{
|
||||
printf("%s: Error in file format\n", paramfn);
|
||||
fclose(fs);
|
||||
return 2;
|
||||
}
|
||||
params[i] = tmp;
|
||||
}
|
||||
fclose(fs);
|
||||
|
||||
for(i=0; i<4; i++)
|
||||
{
|
||||
audf[i] = params[i*2];
|
||||
audc[i] = params[i*2+1];
|
||||
}
|
||||
|
||||
return pktest(audf,audc,(unsigned char)params[8],ofn8, ofn16, (unsigned short)params[9]);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
This directory contains various utility scripts, tests and graphics files:
|
||||
|
||||
act2html.pl: creates an HTML page from *.act palette files, for easy comparison
|
||||
|
||||
*.ico: Win32 icons
|
||||
|
||||
bdata.c: converts binary file to Atari BASIC "DATA" statements
|
||||
|
||||
benchmark.pl: tests emulator performance with different compile-time options
|
||||
|
||||
colors.asx, colors.xex: displays all 256 colors
|
||||
|
||||
export: helps with making a release
|
||||
|
||||
hdevtest.lst: tests H: device
|
||||
|
||||
keyboard.png: Atari XE keyboard picture drawn by Zdenek Eisenhammer
|
||||
|
||||
pokeybench.c: tests POKEY sound emulation
|
||||
|
||||
atari/t7.*: tests cycle-exact timing
|
||||
Reference in New Issue
Block a user