dos33fsprogs/chiptune_player
2018-02-22 12:19:04 -05:00
..
chip_title.inc chiptune: move to own directory 2018-02-16 21:01:06 -05:00
chiptune_player.dsk chiptune_player: update disk 2018-02-21 23:32:29 -05:00
chiptune_player.s chiptune_player: end of song truncated, can't figure out why :( 2018-02-22 01:07:02 -05:00
chiptune.png chiptune: move to own directory 2018-02-16 21:01:06 -05:00
INTRO2.KRW chiptune_player: end of song truncated, can't figure out why :( 2018-02-22 01:07:02 -05:00
Makefile chiptune_player: reads in the KRW file 2018-02-21 20:32:40 -05:00
OUT.0 chiptune: move chunksize to 3 2018-02-18 00:13:30 -05:00
OUT.LZ4 chiptune: update binaries 2018-02-20 23:19:09 -05:00
rasterbars.s chitpune: add background rasterbars 2018-02-18 12:01:15 -05:00
README.chiptune dos33: update for a new SHOWFREE command 2018-02-22 12:19:04 -05:00
TODO chiptune_player: add LOADING message 2018-02-21 16:56:56 -05:00
volume_bars.s chiptune_player: move volume bars to own file 2018-02-19 23:05:02 -05:00
zp.inc chiptune_player: prepare for playing whole song 2018-02-21 23:01:33 -05:00

The Challenges of an Apple II chiptune player.

The goal is to design a chiptune player that can play large 
(150k+ uncompressed) chiptune files on an Apple II with 48k of RAM
and a Mockingboard sound card.

An interrupt routine wakes at 50Hz to write the registers and a few other
houskeeping things.

Not enough RAM to hold full raw ym5 sound data (one byte for each of 14
registers, every 50Hz).  This compresses amazingly.  Using LZ4 by at
least a factor of 10.  But it won't fit all in RAM so we have to load
the full file from disk (no way to do disk I/O, disk I/O disables interrupts)
then decompress in chunks.  So we need room for both the compressed file
plus uncompressed data.

The problem is decompression also takes a while, longer than the 50Hz.
So if we just decompress the next chunk when needed the sound will noticibly
pause for a fraction of a second.

One solution to that is to have two decompress areas and flip between them,
decompressing in the background to one while the other is playing.  The problem
is splitting the decompressed data into smaller chunks like this is that
it doesn't compress as well so it takes up more disk/memory space
for the raw file.



Memory Map
(not to scale)

 ------- $ffff
| ROM/IO|
 ------- $c000
|DOS3.3 |
 -------| $9600
|       |
|       |
|  FREE |
|       |
|       |
|------- $0c00
|GR pg 1|
|------- $0800
|GR pg 0|
 ------- $0400
|       |
 ------- $0200
|stack  | 
 ------- $0100
|zero pg|
 ------- $0000



Sizes

		time	ym5	KRW(3)	KRW(2)
		~~~~	~~~	~~~~~~	~~~~~~
KORO.KRW	0:54	?	2740
FIGHTING.KRW	1:40	?	3086
CAMOUFLAGE.KRW	1:32	1162	4054
DEMO4.KRW	2:05	1393	4061
SDEMO.KRW	2:12	1635	5266
CHRISTMAS.KRW	1:32	1751	4975
SPUTNIK.KRW	2:05	2164	8422
DEATH2.KRW	2:27	2560	8064
CRMOROS.KRW	1:29	2566	8045
TECHNO.KRW	2:23	2630	8934
WAVE.KRW	2:52	2655	8368
LYRA2.KRW	3:04	2870	9826
INTRO2.KRW	2:59	3217	9214
ROBOT.KRW	1:26	3448	7724
UNIVERSE.KRW	1:49	4320	9990
NEURO.KRW	3:47	8681	22376
AXELF.KRW	10:55	9692	47989









Interesting bugs that were hard to debug:

+ Bug in qkumba's LZ4 decoder, only happened when a copy-block size was
	exactly a multiple of 256, in which case it would copy
	an extra time.

+ Bug where the box-drawing was starting at 0 rather than at Y.
	Turns out I was padding the filename buffer with A0 but going
	one too far and it was writing A0 to the first byte of the
	hlin routine, and A0 is a LDY # instruction.