skookum as frig!

This commit is contained in:
Jorge Chamorro Bieling / @jorgechamorro 2017-10-06 14:23:03 +02:00
parent 8585d41dfd
commit 7fb870937f
14 changed files with 1158 additions and 0 deletions

BIN
demo_site/6502.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

434
demo_site/demo.js Normal file
View File

@ -0,0 +1,434 @@
//2017-09-17 Jorge Chamorro Bieling, jorge@jorgechamorro.com
window.onload= function boot () {
Array.prototype.shuffle= function shuffle (a,b,i) {
a= [];
b= this;
while (b.length) {
i= rnd(b.length);
a[a.length]= b[i];
b.splice(i,1);
}
return a;
};
function $ (id) { return document.getElementById(id) }
function rnd (i) {
return Math.floor(i* Math.random());
}
[ 'homer 1.png',
'homer 2.png',
'homer 3.png',
'homer 4.png',
'homer 5.png',
'homer 6.png',
'homer 7.png',
'homer 8.png',
'f666.png',
'6502.png',
'6502.png',
'6502.png'].shuffle().forEach(setup);
function setup (src) {
var div= document.createElement('div');
div.className= 'crop';
var canvas= div.appendChild(document.createElement('canvas'));
canvas.width= 280;
canvas.height= 192;
var img= document.createElement('img');
img.onload= function onload (h,v) {
img.onload= h= v= 0;
if ((img.width>280) && (img.height>192)) {
h= rnd(img.width-280);
v= rnd(img.height-192);
}
canvas.getContext('2d').drawImage(img, -h, -v);
div._hex= foto2hex(canvas);
div.onclick= function onclick () {
var samples= silence(48000/10)+ idle_turbo();
for (var i=0 ; i<8192 ; i+=256) {
var hex= div._hex.substr(2*i, 2*256);
samples+= sync_turbo();
samples+= hex_to_samples_turbo(hex);
samples+= idle_turbo();
}
samples+= silence(48000/10);
play(samples);
}
};
img.src= src;
div._img= img;
div._canvas= canvas;
document.body.appendChild(div);
function foto2hex (canvas) {
var data= canvas.getContext('2d').getImageData(0,0,280,192);
var bytes= [];
for (var y=0 ; y<192 ; y+=1) {
for (var x=0 ; x<280 ; x+=7) {
var byte= 0;
for (var i=6 ; i>=0 ; i-=1) {
var pixel= data.data[4*((y*280)+(x+i))];
byte= (2*byte)+ (pixel ? 1 : 0);
}
byte= byte.toString(16);
while (byte.length<2) byte= '0'+ byte;
bytes[get_hgr_offset(x,y)]= byte;
}
}
var hex= '';
for (var i=0 ; i<8192 ; i++) hex+= bytes[i] ? bytes[i] : '00';
return hex;
}
var hgr_offsets= [0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 128, 1152,
2176, 3200, 4224, 5248, 6272, 7296, 256, 1280, 2304, 3328, 4352,
5376, 6400, 7424, 384, 1408, 2432, 3456, 4480, 5504, 6528, 7552,
512, 1536, 2560, 3584, 4608, 5632, 6656, 7680, 640, 1664, 2688,
3712, 4736, 5760, 6784, 7808, 768, 1792, 2816, 3840, 4864, 5888,
6912, 7936, 896, 1920, 2944, 3968, 4992, 6016, 7040, 8064, 40, 1064,
2088, 3112, 4136, 5160, 6184, 7208, 168, 1192, 2216, 3240, 4264,
5288, 6312, 7336, 296, 1320, 2344, 3368, 4392, 5416, 6440, 7464,
424, 1448, 2472, 3496, 4520, 5544, 6568, 7592, 552, 1576, 2600,
3624, 4648, 5672, 6696, 7720, 680, 1704, 2728, 3752, 4776, 5800,
6824, 7848, 808, 1832, 2856, 3880, 4904, 5928, 6952, 7976, 936,
1960, 2984, 4008, 5032, 6056, 7080, 8104, 80, 1104, 2128, 3152,
4176, 5200, 6224, 7248, 208, 1232, 2256, 3280, 4304, 5328, 6352,
7376, 336, 1360, 2384, 3408, 4432, 5456, 6480, 7504, 464, 1488,
2512, 3536, 4560, 5584, 6608, 7632, 592, 1616, 2640, 3664, 4688,
5712, 6736, 7760, 720, 1744, 2768, 3792, 4816, 5840, 6864, 7888,
848, 1872, 2896, 3920, 4944, 5968, 6992, 8016, 976, 2000, 3024,
4048, 5072, 6096, 7120, 8144];
function get_hgr_offset (x,y) {
return hgr_offsets[y]+ Math.floor(x/7);
}
}
// Audio cosas comunes
var playing= [];
var audio_context = new (window.AudioContext || window.webkitAudioContext)();
var sample_rate= audio_context.sampleRate;
var invert= 0;
function mute () {
while (playing.length) {
var f= playing.pop();
try { f() } catch (e) { ; }
}
}
function silence (how_much) {
var str= '';
while (how_much--) str+= '0';
return str;
}
function play (samples) {
mute();
var channels= 1;
var audio_buffer = audio_context.createBuffer(channels, samples.length, sample_rate);
var channel_data= audio_buffer.getChannelData(0);
var symbol2level= {H:1, h:0.5, 0:0, L:-1, l:-0.5};
for (var i=0 ; i<samples.length ; i++) {
var c= samples[i];
if (invert) {
if (c === 'L') c= 'H';
else if (c === 'H') c= 'L';
}
channel_data[i]= symbol2level[c];
}
var audio_node = audio_context.createBufferSource();
audio_node.buffer= audio_buffer;
audio_node.connect(audio_context.destination);
audio_node.onended= cleanup;
playing.push(cleanup);
console.log("START PLAY");
audio_node.start();
function cleanup () {
audio_node.disconnect(audio_context.destination);
//audio_context.suspend();
//audio_context.close();
var where= playing.indexOf(cleanup);
if (where >= 0) playing.splice(where, 1);
console.log("END PLAY");
};
}
// **** Audio turbo
function idle_turbo () {
return 'LLLLLLLLLLLLHHHHHHHHHHH';
}
function sync_turbo () {
return 'HHLLLLLLLLHHHHHHHLL';
};
function hex_to_samples_turbo (hex) {
hex= hex.toLowerCase();
var hex2value= { 0:0, 1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7,
8:8, 9:9, a:10, b:11, c:12, d:13, e:14, f:15 };
var bin= '';
for (var i=0 ; i<hex.length ; i++) {
var nibble= hex2value[hex[i]].toString(2);
while (nibble.length<4) nibble= '0'+ nibble;
bin+= nibble;
}
hex= '';
var manchester= '';
var bit2samples= { 0:'LLHH', 1:'HHLL' };
for (var i=0 ; i<bin.length ; i++) manchester+= bit2samples[bin[i]];
bin= '';
var tweaked= '';
var hi_ctr= 0;
for (var i=0 ; i<manchester.length ; i++) {
var c= manchester[i];
if (c === 'L') {
for (var j=1 ; j<hi_ctr ; j++) c= 'H'+ c;
tweaked+= c;
hi_ctr= 0;
}
else hi_ctr+= 1;
}
for (var j=1 ; j<hi_ctr ; j++) tweaked+= 'H';
manchester= ''
return tweaked;
}
// Audio normal
function applesoft_hex_to_samples (hex) {
hex= hex.toLowerCase();
//4s @770 + sync + bytes + eor(bytes)
var samples= '';
samples+= silence(sample_rate/5); //0.2 s
samples+= header_770_normal(4);
samples+= sync_bit_normal();
samples+= applesoft_header(hex);
samples+= end_cycle(samples);
samples+= extend_last(sample_rate/10, samples);
samples+= header_770_normal(5);
samples+= sync_bit_normal();
var eor= 0xff;
var hex2value= {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8,
9:9, a:10, b:11, c:12, d:13, e:14, f:15};
for (var i=0 ; (i+1)<hex.length ; i+=2) {
var hi_nibble= hex2value[hex[i]];
var lo_nibble= hex2value[hex[i+1]];
var byte= lo_nibble+ (16* hi_nibble);
eor^= byte;
samples+= byte_normal(byte);
}
samples+= byte_normal(eor);
samples+= end_cycle(samples);
samples+= extend_last(10, samples);
samples+= silence(sample_rate/5); //0.2 s
return samples;
}
function assembly_hex_to_samples (hex) {
hex= hex.toLowerCase();
//4s @770 + sync + bytes + eor(bytes)
var samples= '';
samples+= silence(sample_rate/5); //0.2 s
samples+= header_770_normal(4);
samples+= sync_bit_normal();
var eor= 0xff;
var hex2value= {0:0, 1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8,
9:9, a:10, b:11, c:12, d:13, e:14, f:15};
for (var i=0 ; (i+1)<hex.length ; i+=2) {
var hi_nibble= hex2value[hex[i]];
var lo_nibble= hex2value[hex[i+1]];
var byte= lo_nibble+ (16* hi_nibble);
eor^= byte;
samples+= byte_normal(byte);
}
samples+= byte_normal(eor);
samples+= end_cycle(samples);
samples+= extend_last(10, samples);
samples+= silence(sample_rate/5); //0.2 s
return samples;
}
function header_770_normal (segundos) {
//~segundos @770 Hz
var samples= '';
var ciclos= 770*segundos;
var samples_por_semiciclo= Math.round(sample_rate/(770*2));
var samples_total= ciclos* (2*samples_por_semiciclo);
for (var i=0 ; i<samples_total ; i++) {
var bit= !(Math.floor(i/samples_por_semiciclo)%2);
samples+= bit ? 'H' : 'L';
}
return samples;
}
function sync_bit_normal () {
//1 pulso de 200µs + 1 pulso de 250µs
var samples= '';
var up= Math.round(sample_rate*200e-6);
var down= Math.round(sample_rate*250e-6);
for (var i=0 ; i<up ; i++) samples+= 'H';
for (var i=0 ; i<down ; i++) samples+= 'L';
return samples;
}
function bit_nomal (bit) {
var samples= '';
var len= Math.round(sample_rate* (+bit ? 500e-6 : 250e-6));
for (var i=0 ; i<len ; i++) samples+= 'H';
for (var i=0 ; i<len ; i++) samples+= 'L';
return samples;
}
function byte_normal (byte) {
var samples= '';
byte= byte.toString(2);
while (byte.length<8) byte= '0'+ byte;
for (var i=0 ; i<8 ; i++) samples+= bit_nomal(byte[i]);
return samples;
}
function applesoft_header (hex) {
var samples= '';
var eor= 0xff;
var lock= 0x80;
var len= (hex.length/2)-1;
var hi= Math.floor(len/256);
var lo= len%256;
eor^= lo;
samples+= byte_normal(lo);
eor^= hi;
samples+= byte_normal(hi);
eor^= lock;
samples+= byte_normal(lock);
samples+= byte_normal(eor);
return samples;
}
function end_cycle (samples) {
var last= samples[samples.length-1];
return (last === 'H') ? 'L' : 'H';
}
function extend_last (n, samples) {
var s= '';
var last= samples[samples.length-1];
for ( var i=0 ; i<n ; i++) s+= last;
return s;
}
var prgm_applesoft= "13080a00b938322c303a8c323038303a800000000a27272727272727272727";
var prgm_assembly= "203aff8d10c020b009204608ad00c03005b0ed4c29088d10c0297fc91bd0e18d53c08d51c060a9208dc2088dd8084c640900a200a00838ad60c0305dad60c03058ad60c03053ad60c0304ead60c03049ad60c03044ad60c0303fad60c03040ad60c0303bad60c03036ad60c03031ad60c0302cad60c03027ad60c03022ad60c0301dad60c03018ad60c03013ad60c0300ead60c030094c47099004184cea08183e00203888d028e8f07da0084cf4089004184c5c08383e00203888d084e8f067a0084c6608ad60c010e5ad60c010e0ad60c010dbad60c010d6ad60c010d1ad60c010ccad60c010c7ad60c010c8ad60c010c3ad60c010bead60c010b9ad60c010b4ad60c010afad60c010aaad60c010a5ad60c010a0ad60c0109bad60c01096ad60c010914c4709c000d015e000d011aec208e8e040f00b8ec2088ed8084c640938601860ad30c0a209ad60c08d5108ad00c030ecad60c04d510810f3ad510810e3ca3007ad60c010f830d9a209ca30d4ad60c010f83000a209ca3007ad60c030f810c1a209ca30bcad60c030f84c520820e2f38d52c0a9018d9a3a8d3a268dba2d8dc1248d19378dc1208d42248d37378d3d3d8d3a228d9b338d9b3f8dbb288d9b3b8d373b8d363a8dba298d9a3e8d42308d363e8d9b378dbb2ca9028dbd208db733a9038db7238db73a8d3f308d383a8d42288d3f208d1a278d383e8dbb228db7368d5e288dbb308dbc298dbd248d422c8d3f2c8d3f288d1a2b8d38368d3a2a8d353b8d35338db6268db8228db8268dbc2d8dbb348d3a2e8dbc318d3f248d98338d352f8d373f8db6228d35378d1a23a9048d383ba9068d3c2d8d3f298d973b8d98278d973f8d3c29a9078dbd288d1a2f8d982f8db62a8db72e8d3f218d392b8db72f8d38328dbd218d382e8db72a8dbb388db82a8d193f8db62e8d982b8d382f8db72b8d983b8dbc398d98378dbd2c8db7328d352b8d5e248d3f348db7278db82e8dbc358d1a338dbb3c8d3a328d3b3e8d193ba9088dbc2ca90c8dbc348d1a3f8dbc30a90e8d3f3c8d382a8dbc3c8db63a8dbc388d3c228db8368d3c258d3c218d99278d1a3b8d3c318dbd348d40208d3c268db6368d1a378dbd308d3b25a90f8d39278dbc3d8d3e3d8d3b3a8db73e8db8328d5e208d3f388d3f258d983f8d38338d3b218d99238db6328d3a36a9188db6378d99228d9a238d9a27a91c8d3b268d3b2a8dbf288d3e388dbb398d3e348d3b2d8dbb3d8d992f8db62f8d36238db63e8dbf248dbd3c8dbd2d8d3b328dbb358d3b2e8db63b8d99268d3b228d4028a91e8d3b298dbd388db62b8d992b8d98238db63f8d40248dbf208d38378db83a8d3c358d3b36a91f8d39238d3e398d3a3a8dbd258d3723a9308db53ea9388d39368d3b358dbe208d99378d3e3c8d992e8d40308db6338d3d258db93a8d3b398d393aa9398dbf308dbf2ca93c8d3d218d99338d402c8d3b318db83e8db93e8d992aa93e8dbd298d3523a93f8d35278d3e318d3e35a9408dbe3c8db9218d34338d342f8d34378d41308d412c8d343f8dbe388d3e218dbc288dba388dba348dba288d192b8db5268d343b8db9258db52a8d3e258d37368dbc24a9418d37338d4220a9438dbc258dba25a9448d373aa9468db7228d373ea9478db726a94e8dbb318d3e2ca94f8dbb2d8db623a95c8d3932a95e8d3e308d392ea95f8db627a9608dbe2c8db9318d35328db9298d353e8d972b8d19278d41288d9a2f8dbe308d3e298db9398d363b8d3d398dc0208dc0248dba2c8dc0288d41248d19238dba308d3e248db9358db92d8d5d288d9a3f8d3d358db5228d5d208dbe34a9618d372f8d382b8db93da9638dbc21a9678dbb298d39228d363f8dbb25a96c8d3e28a96f8d392a8d3926a9708d38278d3e208db9368db92a8db83d8d18378dbe288d993f8dbe248d3d2d8d993a8db9268d35368d353a8d41208d993e8d393e8d36338dba268d40388d9a338d403c8d5d248db9228d3e2d8d9a378db9328db92e8d9a3b8d99368d3d318d3637a9718d3b3da9738dbf388dbb21a9778dbf3ca9788d38228d183b8d362f8d38238d362b8d3d298d993b8d40348d99328d972f8d3627a9798d372ba97b8d3c3d8dbf34a97c8dba228d183f8d3a398d9733a97e8d3c398d38268d3a3d8d3a3e8d9737a97f8d37278d353f8dba218db5238db52760000000";
// Listeners
(function setup_listeners () {
$("b_mute").onclick= mute;
$("b_load_applesoft").onclick= function () {
play(applesoft_hex_to_samples(prgm_applesoft+prgm_assembly));
};
$("b_load_assembly").onclick= function () {
play(assembly_hex_to_samples(prgm_assembly));
};
$("b_reset").onclick= function () {
var samples= '';
samples+= silence(sample_rate/10);
samples+= idle_turbo();
samples+= sync_turbo();
samples+= extend_last(10, samples);
samples+= silence(sample_rate/10);
play(samples);
};
$("b_invert").onclick= function () {
invert= !invert;
$("b_invert").value= invert ? 'NOW INVERTED' : 'NOW NOT INVERTED';
};
$("b_reload").onclick= function () { location.reload() };
$("b_github").onclick= function () { location.href= 'https://github.com/xk/Turbo-Cassette-for-the-Apple-II' };
$("b_csa2").onclick= function () { location.href= 'https://groups.google.com/forum/#!topic/comp.sys.apple2/V_S7-0pv3CA/discussion' };
$("b_loop").onclick= function () { alert('Sorry not yet.') };
$("o_sample_rate").innerHTML= "Sample rate is "+ sample_rate+ " sps";
})();
};

BIN
demo_site/f666.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
demo_site/homer 1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
demo_site/homer 2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
demo_site/homer 3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
demo_site/homer 4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
demo_site/homer 5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
demo_site/homer 6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

BIN
demo_site/homer 7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
demo_site/homer 8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

20
demo_site/index.html Normal file
View File

@ -0,0 +1,20 @@
<!doctype html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>TURBO-CASSETTE DEMO</title>
<meta name="description" content="Apple II faster cassette transfer">
<meta name="keywords" content="6502 , Apple II, cassette, Jorge Chamorro">
<link rel="stylesheet" type="text/css" media="all" charset="utf-8" href="style.css">
<script src="demo.js"></script>
</head><body><h1>TURBO-CASSETTE Demo</h1><h3 id="o_sample_rate">Sample rate is ¿?</h3><div>
<input type="button" id="b_mute" value=" MUTE ">
<input type="button" id="b_load_applesoft" value=" ]LOAD ">
<input type="button" id="b_load_assembly" value=" *820.E3AR ">
<input type="button" id="b_reset" value=" RESET ">
<input type="button" id="b_invert" value=" NORMAL/INVERTED ">
<input type="button" id="b_reload" value=" reload ">
<input type="button" id="b_github" value=" goto github ">
<input type="button" id="b_csa2" value=" goto c.s.a2 ">
<input type="button" id="b_loop" value=" LOOP 4 EVER "></div>
</body></html>

49
demo_site/style.css Normal file
View File

@ -0,0 +1,49 @@
body {
background-color: #002543;
color: #ffffff;
margin: 0;
zoom: 1.1;
}
.crop {
margin: 0;
margin-left: 10px;
margin-bottom: 10px;
width: 280px;
height: 192px;
overflow: hidden;
border: 2px solid white;
float: left;
}
img {
margin: 0;
padding: 0;
}
input {
margin: 10px;
padding: 5px;
font-size: 0.8em;
}
h1 {
font-family: arial,helvetica,sans-serif;
font-size: 32px;
color: white;
font-weight: normal;
letter-spacing: 2px;
margin: 3px;
}
h3 {
font-family: arial,helvetica,sans-serif;
font-size: 14px;
color: white;
font-weight: normal;
letter-spacing: 2px;
margin: 3px;
}
.crop:hover {
border: 2px solid #fdc632;
}

655
src/receive_hgr_demo_site.s Normal file
View File

@ -0,0 +1,655 @@
; Apple II TURBO CASSETTE LOADER
; 13569 bps @44100 sps
; 14769 bps @48000 sps
; Jorge Chamorro Bieling, SEPT 2017
; jorge@jorgechamorro.com
; See the thread "Gentlemen, 14+ kbps" @ comp.sys.apple2 :
; https://groups.google.com/forum/#!topic/comp.sys.apple2/V_S7-0pv3CA/discussion
; Source files: github.com/xk/Turbo-Cassette-for-the-Apple-II
; Compile with: apple2.duckdns.org/assembler/
; Connect the PC to the Apple II cassette in port, set the volume at 50% or more.
; Transfer directly from the assembler page to the Apple II and then 820G
; Go to the demo page at: apple2.duckdns.org/turbodemo/
; Click on an image to xfer it
; On the Apple II the space bar resets the decoder an clears the HGR screen, ESC quits.
; Report issues on c.s.a2 or @ the github repo.
* = $820
buffer = $2000
spkr = $c030
cout = $fded
hgr = $f3e2
bell = $ff3a
bits = 8
sync_min = 9
sync_max = 9
reset jsr bell
sta $c010
jsr skookum
entry jsr go
lda $c000
bmi key
bcs reset
jmp entry
key sta $c010
and #$7f
cmp #27 ;ESC is quit
bne reset ;any other key is reset
sta $c053
sta $c051
rts
go lda #>buffer
sta buffer_hi_1
sta buffer_hi_2
jmp sync
last_sample
.byte 0
decode ldx #0 ;x= buffer index
ldy #bits ;y= bit number
sec ;C means last edge was a clock
sample_lo lda $c060 ;4
bmi short_lo ;2..3
sl_1 lda $c060 ;4
bmi short_lo ;2..3
sl_2 lda $c060 ;4
bmi short_lo ;2..3
sl_3 lda $c060 ;4
bmi short_lo ;2..3
sl_4 lda $c060 ;4
bmi short_lo ;2..3
sl_5 lda $c060 ;4
bmi short_lo ;2..3
sl_6 lda $c060 ;4
bmi short_lo ;2..3
w_hi_clk lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_1 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_2 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_3 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_4 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_5 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_6 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_7 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_8 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_9 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_10 lda $c060 ;4
bmi clk_rising ;2..3
hi_clk_11 lda $c060 ;4
bmi clk_rising ;2..3
jmp eof_frame
short_lo bcc clk_rising
clc
jmp sh_1
clk_rising clc ;2 rising edge es un 0
.byte $3e ;7 rol buffer,x ;7
.byte <buffer
buffer_hi_1
.byte >buffer
sec
dey
bne sh_2
inx
beq eof_frame
ldy #bits
jmp sh_3
short_hi bcc clk_falling ;2..3
clc ;2
jmp sl_1 ;3
clk_falling sec ;2 falling edge es un 1
.byte $3e ;7 rol buffer,x ;7
.byte <buffer
buffer_hi_2
.byte >buffer
sec
dey ;2
bne sl_2 ;2..3
inx
beq eof_frame
ldy #bits
jmp sl_3 ;4
sample_hi lda $c060 ;4
bpl short_hi ;2..3
sh_1 lda $c060 ;4
bpl short_hi ;2..3
sh_2 lda $c060 ;4
bpl short_hi ;2..3
sh_3 lda $c060 ;4
bpl short_hi ;2..3
sh_4 lda $c060 ;4
bpl short_hi ;2..3
sh_5 lda $c060 ;4
bpl short_hi ;2..3
sh_6 lda $c060 ;4
bpl short_hi ;2..3
w_lo_clk lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_1 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_2 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_3 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_4 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_5 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_6 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_7 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_8 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_9 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_10 lda $c060 ;4
bpl clk_falling ;2..3
lo_clk_11 lda $c060 ;4
bpl clk_falling ;2..3
jmp eof_frame
eof_frame cpy #0
bne quit_err
cpx #0
bne quit_err
ok ldx buffer_hi_1
inx
cpx #$40
beq quit_ok
stx buffer_hi_1 ;self-modifying code FTW
stx buffer_hi_2
jmp sync
quit_err sec
rts
quit_ok clc
rts
;ALGORITMO DE SYNC:
;1.- buscar un falling edge
;2.- contar bucles hasta el próximo flanco
;3.- si son más de sync_max o menos de sync_min goto 1
;4.- si son entre sync_min y sync_max => ok, y si ocurren 2 seguidos => ok: Al final del segundo empiezan los datos.
;5.- si el último pulso da error probablemente la señal esté invertida.
;6.- los samples de los pulsos de sync serían LLLLLLLLHHHHHHHLL (8L7H2L)
sync lda spkr
ldx #sync_min
lda $c060
sta last_sample
wait_edge lda $c000
bmi quit_err
no_key lda $c060
eor last_sample
bpl wait_edge
lda last_sample
bpl sync ;buscamos falling edge
sync_1_1 dex
bmi sync_2 ;min length ok
lda $c060
bpl sync_1_1
bmi sync ;too short
sync_2 ldx #sync_max
sync_2_1 dex
bmi sync ;too long
lda $c060
bpl sync_2_1
bmi sync_3
;1st pulse (LO) ok
sync_3 ldx #sync_min
sync_3_1 dex
bmi sync_4 ;min length ok
lda $c060
bmi sync_3_1
bpl sync ;too short
sync_4 ldx #sync_max
sync_4_1 dex
bmi sync ;too long
lda $c060
bmi sync_4_1
jmp decode ;2nd pulse (HI) ok
skookum jsr hgr
sta $c052
lda #1
sta $3a9a
sta $263a
sta $2dba
sta $24c1
sta $3719
sta $20c1
sta $2442
sta $3737
sta $3d3d
sta $223a
sta $339b
sta $3f9b
sta $28bb
sta $3b9b
sta $3b37
sta $3a36
sta $29ba
sta $3e9a
sta $3042
sta $3e36
sta $379b
sta $2cbb
lda #2
sta $20bd
sta $33b7
lda #3
sta $23b7
sta $3ab7
sta $303f
sta $3a38
sta $2842
sta $203f
sta $271a
sta $3e38
sta $22bb
sta $36b7
sta $285e
sta $30bb
sta $29bc
sta $24bd
sta $2c42
sta $2c3f
sta $283f
sta $2b1a
sta $3638
sta $2a3a
sta $3b35
sta $3335
sta $26b6
sta $22b8
sta $26b8
sta $2dbc
sta $34bb
sta $2e3a
sta $31bc
sta $243f
sta $3398
sta $2f35
sta $3f37
sta $22b6
sta $3735
sta $231a
lda #4
sta $3b38
lda #6
sta $2d3c
sta $293f
sta $3b97
sta $2798
sta $3f97
sta $293c
lda #7
sta $28bd
sta $2f1a
sta $2f98
sta $2ab6
sta $2eb7
sta $213f
sta $2b39
sta $2fb7
sta $3238
sta $21bd
sta $2e38
sta $2ab7
sta $38bb
sta $2ab8
sta $3f19
sta $2eb6
sta $2b98
sta $2f38
sta $2bb7
sta $3b98
sta $39bc
sta $3798
sta $2cbd
sta $32b7
sta $2b35
sta $245e
sta $343f
sta $27b7
sta $2eb8
sta $35bc
sta $331a
sta $3cbb
sta $323a
sta $3e3b
sta $3b19
lda #8
sta $2cbc
lda #12
sta $34bc
sta $3f1a
sta $30bc
lda #14
sta $3c3f
sta $2a38
sta $3cbc
sta $3ab6
sta $38bc
sta $223c
sta $36b8
sta $253c
sta $213c
sta $2799
sta $3b1a
sta $313c
sta $34bd
sta $2040
sta $263c
sta $36b6
sta $371a
sta $30bd
sta $253b
lda #15
sta $2739
sta $3dbc
sta $3d3e
sta $3a3b
sta $3eb7
sta $32b8
sta $205e
sta $383f
sta $253f
sta $3f98
sta $3338
sta $213b
sta $2399
sta $32b6
sta $363a
lda #24
sta $37b6
sta $2299
sta $239a
sta $279a
lda #28
sta $263b
sta $2a3b
sta $28bf
sta $383e
sta $39bb
sta $343e
sta $2d3b
sta $3dbb
sta $2f99
sta $2fb6
sta $2336
sta $3eb6
sta $24bf
sta $3cbd
sta $2dbd
sta $323b
sta $35bb
sta $2e3b
sta $3bb6
sta $2699
sta $223b
sta $2840
lda #30
sta $293b
sta $38bd
sta $2bb6
sta $2b99
sta $2398
sta $3fb6
sta $2440
sta $20bf
sta $3738
sta $3ab8
sta $353c
sta $363b
lda #31
sta $2339
sta $393e
sta $3a3a
sta $25bd
sta $2337
lda #48
sta $3eb5
lda #56
sta $3639
sta $353b
sta $20be
sta $3799
sta $3c3e
sta $2e99
sta $3040
sta $33b6
sta $253d
sta $3ab9
sta $393b
sta $3a39
lda #57
sta $30bf
sta $2cbf
lda #60
sta $213d
sta $3399
sta $2c40
sta $313b
sta $3eb8
sta $3eb9
sta $2a99
lda #62
sta $29bd
sta $2335
lda #63
sta $2735
sta $313e
sta $353e
lda #64
sta $3cbe
sta $21b9
sta $3334
sta $2f34
sta $3734
sta $3041
sta $2c41
sta $3f34
sta $38be
sta $213e
sta $28bc
sta $38ba
sta $34ba
sta $28ba
sta $2b19
sta $26b5
sta $3b34
sta $25b9
sta $2ab5
sta $253e
sta $3637
sta $24bc
lda #65
sta $3337
sta $2042
lda #67
sta $25bc
sta $25ba
lda #68
sta $3a37
lda #70
sta $22b7
sta $3e37
lda #71
sta $26b7
lda #78
sta $31bb
sta $2c3e
lda #79
sta $2dbb
sta $23b6
lda #92
sta $3239
lda #94
sta $303e
sta $2e39
lda #95
sta $27b6
lda #96
sta $2cbe
sta $31b9
sta $3235
sta $29b9
sta $3e35
sta $2b97
sta $2719
sta $2841
sta $2f9a
sta $30be
sta $293e
sta $39b9
sta $3b36
sta $393d
sta $20c0
sta $24c0
sta $2cba
sta $28c0
sta $2441
sta $2319
sta $30ba
sta $243e
sta $35b9
sta $2db9
sta $285d
sta $3f9a
sta $353d
sta $22b5
sta $205d
sta $34be
lda #97
sta $2f37
sta $2b38
sta $3db9
lda #99
sta $21bc
lda #103
sta $29bb
sta $2239
sta $3f36
sta $25bb
lda #108
sta $283e
lda #111
sta $2a39
sta $2639
lda #112
sta $2738
sta $203e
sta $36b9
sta $2ab9
sta $3db8
sta $3718
sta $28be
sta $3f99
sta $24be
sta $2d3d
sta $3a99
sta $26b9
sta $3635
sta $3a35
sta $2041
sta $3e99
sta $3e39
sta $3336
sta $26ba
sta $3840
sta $339a
sta $3c40
sta $245d
sta $22b9
sta $2d3e
sta $379a
sta $32b9
sta $2eb9
sta $3b9a
sta $3699
sta $313d
sta $3736
lda #113
sta $3d3b
lda #115
sta $38bf
sta $21bb
lda #119
sta $3cbf
lda #120
sta $2238
sta $3b18
sta $2f36
sta $2338
sta $2b36
sta $293d
sta $3b99
sta $3440
sta $3299
sta $2f97
sta $2736
lda #121
sta $2b37
lda #123
sta $3d3c
sta $34bf
lda #124
sta $22ba
sta $3f18
sta $393a
sta $3397
lda #126
sta $393c
sta $2638
sta $3d3a
sta $3e3a
sta $3797
lda #127
sta $2737
sta $3f35
sta $21ba
sta $23b5
sta $27b5
rts
.byte 0
.byte 0
.byte 0
.end