[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ANNOUNCE: Apple Game Server Online!
On Dec 13, 1:22 am, "Michael J. Mahon" <mjma...@aol.com> wrote:
> BLuRry wrote:
> > On Dec 10, 11:10 pm, Egan Ford <dataj...@gmail.com> wrote:
>
> >>Happy Holidays,
>
> >>I've completely my cassette port research and achieved gains of 6x
> >>(12x with compression). I did have an application in mind. Inspired
> >>by the Apple Game Server, I created a web-based version. There is a
> >>video tutorial if you just want to see it in action (single take, be
> >>kind).
>
> >>http://asciiexpress.net/gameserver
>
> >>I've tested the iPhone 4, iPad 2, Mac Firefox, Mac Chrome, and Mac
> >>Safari. If you have a browser that does not work please let me know.
> >>Thanks.
>
> > Very cool. I wonder if it is possible to make a more efficient tape
> > loader routine? The original load could be used as a first stage
> > bootstrap too.
>
> I think that's exactly what "hi-fi" does...
>
> -michael
>
> NadaNet 3.1 for Apple II parallel computing!
> Home page: http://home.comcast.net/~mjmahon/
>
> "The wastebasket is our most important design
> tool--and it's seriously underused."
Michael,
Exactly.
BLuRay,
I am writing an article about the cassette ports and how
asciiexpress.net/gameserver works. I should be done in about a week,
and I will release all of the source code.
Here is the very short version:
Prioritized objectives:
1. Make it simple for the user.
2. Make it as fast as possible.
Unfortunately there is no simpler way to get audio formatted data into
a diskless ][+ or //e than the "LOAD" command. "LOAD" is a native in-
ROM BASIC "shell" command.
The LOAD command requires at least 3.5 seconds of 770 Hz tone. In
practice I've found 4.0 seconds to be consistently reliable with
various players. It's not an Apple II issue, but an issue with the
players (e.g. iPhone, iPod, Browser, etc...).
Following the initial 770 Hz 4.0 second tone is a 4 byte header that
takes about 24 milliseconds (ms) to transfer. That header defines the
size of the BASIC program to follow, whether it should auto run or
not, and a checksum. That is then followed by 4.0 seconds of 770 Hz
(3.9 seconds was the minimum that would work), then the BASIC program,
which is nothing more than CALL 2060 followed by 1/2 page (LOFI) or
3/2 pages (HIFI) of machine code.
Both sets of code relocate themselves to high memory and then start to
read and process the audio stream. This is where things start to
differ.
LOFI uses the standard cassette interface routines in ROM. Again 4.0
seconds of 770 Hz is required before I can read and process the data.
Average bits/second is 1333 (1/1000 second for "1"s and 1/2000 of a
second "0"s. 1333 = 1/((1/1000 + 1/2000)/2).
HIFI uses newly developed cassette interface code that is based on 6
KHz and 12 KHz tones for a 6x improvement in time (8000 bps). And
this code does not require 4.0 seconds of 770Hz; just a few cycles of
2000 Hz is required. I am using 0.1 seconds of 2KHz before starting
the load and processing of the data.
If you listen to both streams (LOFI and HIFI) you can hear exactly
what I just described.
Benchmarks:
All the games come directly from the a2gameserver zip file and are not
modified. I'll use Super Packman (30719 bytes) as my benchmark:
LOFI: 156.48 seconds
HIFI: 26.08 seconds
The numbers are estimates. I've computed the times based on the
actual bits used. Times with header/loader code:
LOFI: 156 + 13 = 169 seconds, effective bits/s = 1454
HIFI: 26 + 10 = 36 seconds, effective bits/s = 6825
The overhead clearly impacts HIFI. The higher than average LOFI bits/
s is because there are more zeros (faster) than ones (slower) in the
data.
Compression:
To get better times I used Huffman+LZ compression. This requires that
I append to the data stream an extra 512 bytes and load the stream
into high memory so that it can inflate into low memory.
This reduces the total load time (actual length of the audio file in
seconds) to:
LOFI: 90 seconds, effective bits/s = 2730
HIFI: 24 seconds, effective bits/s = 10238
The HIFI speed up is 3.75x when compared to LOFI compressed (24 vs. 90
seconds) and 7x when compared to LOFI uncompressed (24 vs. 169
seconds). The header is about 11 seconds of the 24 seconds. However
decompression time is not factored in. The average inflate time is 7
seconds (measured range 4.5 - 9.5).
Not every game is compressed. My code-to-tape program computes the
estimated download/inflate times and if compression increases time,
then it is processed without compression and a warning issued.
CRC:
The HIFI method also includes CRC code. I added this when testing
because the iPhone 4 was not working correctly (iPad, browsers, Mac,
etc... no problem). I got paranoid and added 16-bit CRC checking only
if the data is not compressed. If the data is compressed, then the
CRC only checks the 512 bytes of inflate code. The inflate code will
most likely fail if the data is corrupted. There is a check at the
end of both the CRC and the inflate code: On error report ERROR and do
not launch game.
Now that I added the CRC code, the iPhone 4 refuses to fail. I fixed
something along the away without knowing it. But to be sure it was
not a bug in the CRC checking code I did send a crap stream. You can
test yourself by adding sound to the stream while it is playing (e.g.
mail alert sound).
BLuRay, et al.,
If you can think of any way to speed this up please let me know. Some
of the data from a2gameserver is exo compressed making hard to get
much gain from Huffman+LZ. I speculate that if the exo compressed
files were uncompressed that I may get a minor gain.
I am open to any other ideas. However and I running out of time on
this project (got others in the queue).
Things I tried that failed:
1. Multiple frequencies and half-cycle encoding of data. The problem
here is that the frequencies ranges have to be spaced far enough apart
so that they can be detected by the Apple II accurately (via
polling). This worked in practice with Virtual ][, but in the real
world I had a lot of problems. Many of them were with the players,
not the II. I was able to get my //e to detect 24KHz frequencies, but
devices such as the iPhone would not transmit them. Furthermore using
a 96KHz sampling rate to get a better range of frequencies and shorter
pulses to increase speed to 19200 bps wasn't supported by browsers
(e.g. Safari will not play anything more than a 48000Khz sample
rate). BTW, I could only model 96KHz. I could not test with Virtual ]
[ since it was limited by 64KHz sample rates.
2. Faster 1-bit frequencies. The objective here was to use something
like 22K/11K, or 12K/9K, etc... The first challenge was the time to
process a bit after detecting the shift from positive to negative (via
polling). I needed ~1/24000 of a second (~42 clock cycles) to process
the data. This limited the max frequency to 12000 Hz. If I can get
that code down to 20 or so cycles, then I can use higher frequencies.
I'd really like to use 16K and 8K or perhaps 16K and 12K. The
challenge with something like 12K/9K is that the number of pulses and
pulse length is harder to detect. There is often overlap in the
polling count. It is not impossible however.
Currently the shortest HIFI audio (measured in seconds) is 11s, the
longest is 37s, and the average is 23s. The overhead is about 10s
that I do not think I can remove without asking the user to type
CALL-151, ... That leaves the data in the range of 1s to 27s. I
think that is pretty good. I do not think it can be beat with ADTpro
creating a floppy of a game or CFFA3000 USB meatnet/meatspace
transfer. An agile nerd equipped with CFFA3000 may have a shot.
The question is, is 23 seconds too long?
BLuRay, I fixed your name on the site. Very sorry about that.