Created
November 7, 2019 03:47
-
-
Save tschak909/85800a8da72cd69ddc33143aabf83b97 to your computer and use it in GitHub Desktop.
current COMMAND-less gist implemented as FSM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Atari ESP01 Firmware | |
*/ | |
enum {GET_ID, GET_COMMAND, GET_AUX1, GET_AUX2, GET_CKSUM, ACK, NAK, PROCESS} sio_cmd_frame_state = GET_ID; | |
/** | |
sio2wifi disk image here, 4 128 byte sectors. | |
*/ | |
#define PIN_LED 2 | |
byte cmd[5]; // Command frame. | |
byte disk[128] = | |
{ | |
0x00, 0x01, 0x00, 0x07, 0x00, 0x07, 0xa9, 0x9a, 0x8d, 0xc4, 0x02, 0xa9, | |
0x45, 0x8d, 0xc8, 0x02, 0xa9, 0x31, 0x8d, 0x30, 0x02, 0xa9, 0x07, 0x8d, | |
0x31, 0x02, 0x4c, 0x1a, 0x07, 0x00, 0x00, 0x00, 0x25, 0x33, 0x30, 0x18, | |
0x12, 0x16, 0x16, 0x00, 0x22, 0x2f, 0x2f, 0x34, 0x25, 0x24, 0x00, 0x00, | |
0x00, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, | |
0x70, 0x47, 0x1d, 0x07, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
}; | |
//byte disk[512] = { | |
// 0x00, 0x04, 0x00, 0x07, 0x09, 0x07, 0x4c, 0xd9, 0x08, 0xa2, 0x00, 0xe8, | |
// 0xe8, 0xe8, 0xbd, 0x1a, 0x03, 0xf0, 0x04, 0xc9, 0x52, 0xd0, 0xf4, 0xa9, | |
// 0x52, 0x9d, 0x1a, 0x03, 0xa9, 0x27, 0x9d, 0x1b, 0x03, 0xa9, 0x07, 0x9d, | |
// 0x1c, 0x03, 0x60, 0x32, 0x07, 0x80, 0x07, 0x9c, 0x07, 0xe6, 0x07, 0xf8, | |
// 0x07, 0x0e, 0x08, 0xa9, 0x00, 0x8d, 0x00, 0x07, 0x8d, 0x01, 0x07, 0xa9, | |
// 0xb3, 0x8d, 0x02, 0x07, 0x8d, 0x87, 0x08, 0x8d, 0xbd, 0x07, 0xa9, 0x08, | |
// 0x8d, 0x03, 0x07, 0x8d, 0x88, 0x08, 0x8d, 0xbe, 0x07, 0xa9, 0xb3, 0x8d, | |
// 0x04, 0x07, 0xa9, 0x09, 0x8d, 0x05, 0x07, 0xa9, 0x7b, 0x8d, 0x0a, 0x02, | |
// 0xa9, 0x08, 0x8d, 0x0b, 0x02, 0xa9, 0x73, 0x8d, 0x0f, 0xd2, 0xa9, 0x78, | |
// 0x8d, 0x08, 0xd2, 0xa5, 0x10, 0x29, 0xc7, 0x09, 0x20, 0x85, 0x10, 0x8d, | |
// 0x0e, 0xd2, 0xa9, 0x34, 0x8d, 0x02, 0xd3, 0xd0, 0x63, 0xa5, 0x10, 0x29, | |
// 0xc7, 0x8d, 0x0e, 0xd2, 0x85, 0x10, 0xad, 0x06, 0x07, 0x8d, 0x0a, 0x02, | |
// 0xad, 0x07, 0x07, 0x8d, 0x0b, 0x02, 0xa9, 0x3c, 0x8d, 0x02, 0xd3, 0xd0, | |
// 0x47, 0xad, 0x00, 0x07, 0x0d, 0x01, 0x07, 0xf0, 0xf8, 0xad, 0x00, 0x07, | |
// 0xd0, 0x03, 0xce, 0x01, 0x07, 0xce, 0x00, 0x07, 0xad, 0x00, 0x07, 0x0d, | |
// 0x01, 0x07, 0xd0, 0x04, 0xa9, 0x00, 0x85, 0x42, 0xae, 0x00, 0x10, 0xee, | |
// 0xbd, 0x07, 0xd0, 0x03, 0xee, 0xbe, 0x07, 0xad, 0xbe, 0x07, 0xcd, 0x05, | |
// 0x07, 0xd0, 0x14, 0xad, 0xbd, 0x07, 0xcd, 0x04, 0x07, 0xd0, 0x0c, 0xad, | |
// 0x02, 0x07, 0x8d, 0xbd, 0x07, 0xad, 0x03, 0x07, 0x8d, 0xbe, 0x07, 0x8a, | |
// 0xa0, 0x01, 0x60, 0xaa, 0xa9, 0x08, 0x2c, 0x0e, 0xd2, 0xd0, 0xfb, 0x8e, | |
// 0x0d, 0xd2, 0x2c, 0x0e, 0xd2, 0xf0, 0xfb, 0xd0, 0xeb, 0xad, 0x00, 0x07, | |
// 0x8d, 0xeb, 0x02, 0xad, 0x01, 0x07, 0x8d, 0xec, 0x02, 0xa9, 0x00, 0x8d, | |
// 0xea, 0x02, 0x8d, 0xed, 0x02, 0xf0, 0xd5, 0xa5, 0x22, 0xc9, 0x28, 0xf0, | |
// 0x31, 0xc9, 0x26, 0xf0, 0x59, 0xc9, 0x24, 0xd0, 0xc7, 0xa5, 0x2a, 0x29, | |
// 0x07, 0xaa, 0xbd, 0x3e, 0x08, 0x8d, 0x06, 0xd2, 0x8d, 0x02, 0xd2, 0xbd, | |
// 0x36, 0x08, 0x8d, 0x04, 0xd2, 0x8d, 0x00, 0xd2, 0xd0, 0xae, 0x5a, 0xcc, | |
// 0xe4, 0xeb, 0x6e, 0xb4, 0x57, 0x28, 0x0b, 0x05, 0x02, 0x01, 0x01, 0x00, | |
// 0x00, 0x00, 0xa5, 0x2a, 0xf0, 0x9a, 0x18, 0xbd, 0x44, 0x03, 0x8d, 0x02, | |
// 0x07, 0x8d, 0xbd, 0x07, 0x8d, 0x87, 0x08, 0x7d, 0x48, 0x03, 0x8d, 0x04, | |
// 0x07, 0xbd, 0x45, 0x03, 0x8d, 0x03, 0x07, 0x8d, 0xbe, 0x07, 0x8d, 0x88, | |
// 0x08, 0x7d, 0x49, 0x03, 0x8d, 0x05, 0x07, 0xa0, 0x01, 0x60, 0xa5, 0x2a, | |
// 0xc9, 0x20, 0xf0, 0xf7, 0xa0, 0x92, 0x60, 0xad, 0x0d, 0xd2, 0xee, 0x00, | |
// 0x07, 0xd0, 0x03, 0xee, 0x01, 0x07, 0x8d, 0x00, 0x10, 0xee, 0x87, 0x08, | |
// 0xd0, 0x03, 0xee, 0x88, 0x08, 0xad, 0x88, 0x08, 0xcd, 0x05, 0x07, 0xd0, | |
// 0x14, 0xad, 0x87, 0x08, 0xcd, 0x04, 0x07, 0xd0, 0x0c, 0xad, 0x02, 0x07, | |
// 0x8d, 0x87, 0x08, 0xad, 0x03, 0x07, 0x8d, 0x88, 0x08, 0xa9, 0x01, 0x85, | |
// 0x42, 0x68, 0x40, 0x7d, 0x53, 0x49, 0x4f, 0x32, 0x57, 0x69, 0x46, 0x69, | |
// 0x20, 0x52, 0x3a, 0x48, 0x41, 0x4e, 0x44, 0x4c, 0x45, 0x52, 0x20, 0x28, | |
// 0x63, 0x29, 0x20, 0x4d, 0x72, 0x2e, 0x41, 0x74, 0x61, 0x72, 0x69, 0x20, | |
// 0x32, 0x30, 0x31, 0x39, 0x9b, 0xa2, 0xb3, 0xa0, 0x08, 0x8e, 0x44, 0x03, | |
// 0x8c, 0x45, 0x03, 0x8e, 0x48, 0x03, 0xa2, 0x00, 0xa9, 0x09, 0x8d, 0x42, | |
// 0x03, 0x20, 0x56, 0xe4, 0xad, 0x0a, 0x02, 0x8d, 0x06, 0x07, 0xad, 0x0b, | |
// 0x02, 0x8d, 0x07, 0x07, 0x18, 0x60, 0x00, 0x00 | |
//}; | |
/** | |
Calculate a SIO checksum | |
*/ | |
byte sio_checksum(byte* chunk, int length) | |
{ | |
int chkSum = 0; | |
for (int i = 0; i < length; i++) { | |
chkSum = ((chkSum + chunk[i]) >> 8) + ((chkSum + chunk[i]) & 0xff); | |
} | |
return (byte)chkSum; | |
} | |
/** | |
Setup | |
*/ | |
void setup() | |
{ | |
Serial.begin(19200); | |
Serial.swap(); | |
pinMode(PIN_LED, OUTPUT); | |
} | |
/** | |
Get the Device ID | |
*/ | |
void sio_get_device_id() | |
{ | |
if (Serial.available() > 0) | |
{ | |
cmd[0] = Serial.read(); | |
if (cmd[0] == 0x31) // hard wired to drive 1 | |
sio_cmd_frame_state = GET_COMMAND; | |
} | |
} | |
/** | |
Get the command | |
*/ | |
void sio_get_command() | |
{ | |
if (Serial.available() > 0) | |
cmd[1] = Serial.read(); | |
if ((cmd[1] == 'R') || (cmd[1] == 'S')) | |
sio_cmd_frame_state = GET_AUX1; | |
else | |
sio_cmd_frame_state = GET_ID; // revert to initial state | |
} | |
/** | |
Get the first aux byte. | |
*/ | |
void sio_get_aux1() | |
{ | |
if (Serial.available() > 0) | |
{ | |
cmd[2] = Serial.read(); | |
if (cmd[2] == 0) // assuming we only need to address first 256 sectors. | |
sio_cmd_frame_state = GET_AUX2; | |
else | |
sio_cmd_frame_state = GET_ID; // revert to initial state | |
} | |
} | |
/** | |
Get the second aux byte | |
*/ | |
void sio_get_aux2() | |
{ | |
if (Serial.available() > 0) | |
{ | |
cmd[3] = Serial.read(); | |
if (cmd[3] < 4) // aux2 should not be more than 4 sectors. | |
sio_cmd_frame_state = GET_CKSUM; | |
else | |
sio_cmd_frame_state = GET_ID; // revert to initial state | |
} | |
} | |
/** | |
Get the checksum | |
*/ | |
void sio_get_cksum() | |
{ | |
byte ck = sio_checksum((byte *)&cmd, 4); | |
if (Serial.available() > 0) | |
{ | |
cmd[4] = Serial.read(); | |
if (cmd[4] == ck) | |
sio_cmd_frame_state = ACK; | |
else | |
sio_cmd_frame_state = NAK; | |
} | |
} | |
/** | |
Checksum matched, send ack. | |
*/ | |
void sio_ack() | |
{ | |
digitalWrite(PIN_LED, LOW); | |
Serial.write('A'); | |
Serial.flush(); | |
sio_cmd_frame_state = PROCESS; | |
} | |
/** | |
Checksum not matched, send nak. | |
*/ | |
void sio_nak() | |
{ | |
Serial.write('N'); | |
Serial.flush(); | |
delay(1); | |
sio_cmd_frame_state = GET_ID; // Revert to initial state. | |
} | |
/** | |
SIO read | |
*/ | |
void sio_read() | |
{ | |
byte sector[128]; | |
int offset = 0; | |
byte ck; | |
for (int i = 0; i < 128; i++) | |
sector[i] = disk[offset + i]; | |
ck = sio_checksum((byte *)§or, 128); | |
Serial.write('C'); // command complete | |
Serial.flush(); | |
delay(1); | |
for (int i = 0; i < 128; i++) | |
Serial.write(sector[i]); | |
Serial.write(ck); // write the checksum | |
Serial.flush(); | |
} | |
/** | |
SIO status | |
*/ | |
void sio_status() | |
{ | |
byte status[4]; | |
byte ck; | |
status[0] = 0x00; | |
status[1] = 0xFF; | |
status[2] = 0xFE; | |
status[3] = 0x00; | |
ck = sio_checksum((byte *)&status, 4); | |
Serial.write('C'); // complete | |
Serial.flush(); | |
delay(1); | |
for (int i = 0; i < 4; i++) | |
Serial.write(status[i]); | |
// Write checksum | |
Serial.write(ck); | |
Serial.flush(); | |
} | |
/** | |
Process SIO command | |
*/ | |
void sio_process() | |
{ | |
switch (cmd[1]) | |
{ | |
case 'R': | |
sio_read(); | |
break; | |
case 'S': | |
sio_status(); | |
break; | |
} | |
} | |
/** | |
Primary loop | |
*/ | |
void loop() | |
{ | |
switch (sio_cmd_frame_state) | |
{ | |
case GET_ID: | |
sio_get_device_id(); | |
break; | |
case GET_COMMAND: | |
sio_get_command(); | |
break; | |
case GET_AUX1: | |
sio_get_aux1(); | |
break; | |
case GET_AUX2: | |
sio_get_aux2(); | |
break; | |
case GET_CKSUM: | |
sio_get_cksum(); | |
break; | |
case ACK: | |
sio_ack(); | |
delay(1); | |
break; | |
case NAK: | |
sio_nak(); | |
delay(1); | |
break; | |
case PROCESS: | |
sio_process(); | |
break; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment