Skip to content

Commit a6b59a0

Browse files
committed
[iec] sync and troubleshooting protocol
1 parent a6f49ce commit a6b59a0

File tree

20 files changed

+293
-168
lines changed

20 files changed

+293
-168
lines changed

data/BUILD_IEC/ml.0.spr

-66 Bytes
Binary file not shown.

data/BUILD_IEC/mlb.prg

-10.9 KB
Binary file not shown.

lib/FileSystem/fnFsTNFSvfs.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ int vfs_tnfs_fstat(void* ctx, int fd, struct stat * st)
242242
// New basepath will be stored in basepath
243243
esp_err_t vfs_tnfs_register(tnfsMountInfo &m_info, char *basepath, int basepathlen)
244244
{
245-
// Trying to initialze the struct as coumented (e.g. ".write_p = &function")
245+
// Trying to initialze the struct as docoumented (e.g. ".write_p = &function")
246246
// results in compiloer error "non-trivial desginated initializers not supported"
247247
esp_vfs_t vfs;
248248
memset(&vfs, 0, sizeof(vfs));
@@ -258,7 +258,7 @@ esp_err_t vfs_tnfs_register(tnfsMountInfo &m_info, char *basepath, int basepathl
258258
vfs.rename_p = &vfs_tnfs_rename;
259259

260260
// We'll use the address of our tnfsMountInfo to provide a unique base path
261-
// for this instance wihtout keeping track of how many we create
261+
// for this instance without keeping track of how many we create
262262
snprintf(basepath, basepathlen, "/tnfs%p", &m_info);
263263
esp_err_t e = esp_vfs_register(basepath, &vfs, &m_info);
264264

lib/bus/iec/iec.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -339,11 +339,12 @@ void IRAM_ATTR systemBus::service()
339339
detected_protocol = PROTOCOL_SERIAL;
340340
protocol = selectProtocol();
341341
//release ( PIN_IEC_SRQ );
342+
}
342343

343-
if ( status ( PIN_IEC_ATN ) )
344-
{
345-
state = BUS_ACTIVE;
346-
}
344+
// Let's check ATN again before we exit and clean up
345+
if ( status ( PIN_IEC_ATN ) )
346+
{
347+
state = BUS_ACTIVE;
347348
}
348349

349350
} while( state > BUS_IDLE );
@@ -499,12 +500,12 @@ void systemBus::read_command()
499500
// Sometimes ATN isn't released immediately. Wait for ATN to be
500501
// released before trying to process the command.
501502
// Long ATN delay (>1.5ms) seems to occur more frequently with VIC-20.
502-
pull ( PIN_IEC_SRQ );
503+
//pull ( PIN_IEC_SRQ );
503504
protocol->timeoutWait ( PIN_IEC_ATN, RELEASED, TIMEOUT_DEFAULT, false );
504505

505506
// Delay after ATN is RELEASED
506507
//protocol->wait( TIMING_Ttk, false );
507-
release ( PIN_IEC_SRQ );
508+
//release ( PIN_IEC_SRQ );
508509
}
509510

510511

@@ -835,14 +836,14 @@ void IRAM_ATTR systemBus::deviceListen()
835836
void IRAM_ATTR systemBus::deviceTalk()
836837
{
837838
// Now do bus turnaround
838-
//pull(PIN_IEC_SRQ);
839+
pull(PIN_IEC_SRQ);
839840
if (!turnAround())
840841
{
841842
Debug_printv("error flags[%d]", flags);
842843
state = BUS_ERROR;
843844
return;
844845
}
845-
//release(PIN_IEC_SRQ);
846+
release(PIN_IEC_SRQ);
846847

847848
// We have recieved a CMD and we should talk now:
848849
state = BUS_PROCESS;
@@ -871,7 +872,7 @@ bool IRAM_ATTR systemBus::turnAround()
871872
*/
872873

873874
// Wait for CLK to be released
874-
pull ( PIN_IEC_SRQ );
875+
//pull ( PIN_IEC_SRQ );
875876
if (protocol->timeoutWait(PIN_IEC_CLK_IN, RELEASED, TIMEOUT_Ttlta) == TIMEOUT_Ttlta)
876877
{
877878
Debug_printv("Wait until the computer releases the CLK line\r\n");
@@ -881,7 +882,7 @@ bool IRAM_ATTR systemBus::turnAround()
881882
}
882883
release ( PIN_IEC_DATA_OUT );
883884
pull ( PIN_IEC_CLK_OUT );
884-
release ( PIN_IEC_SRQ );
885+
//release ( PIN_IEC_SRQ );
885886

886887
// 80us minimum delay after TURNAROUND
887888
// *** IMPORTANT!

lib/bus/iec/ieee-488.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//
2+
// https://www.pagetable.com/?p=1023
3+
// https://ia601902.us.archive.org/9/items/PET_and_the_IEEE488_Bus_1980_McGraw-Hill/PET_and_the_IEEE488_Bus_1980_McGraw-Hill.pdf
4+
//

lib/bus/iec/protocol/_protocol.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ IECProtocol::IECProtocol() {
2424
esp_timer_create_args_t args = {
2525
.callback = onTimer,
2626
.arg = this,
27-
.name = nullptr
27+
.dispatch_method = ESP_TIMER_ISR,
28+
.name = "onTimer"
2829
};
2930
esp_timer_create(&args, &timer_handle);
3031
};
@@ -40,13 +41,14 @@ IECProtocol::~IECProtocol() {
4041
void IECProtocol::timer_start(uint64_t timeout_us)
4142
{
4243
timer_timedout = false;
43-
esp_timer_stop(timer_handle);
44+
timer_started = esp_timer_get_time();
4445
esp_timer_start_once(timer_handle, timeout_us);
4546
//IEC.pull( PIN_IEC_SRQ );
4647
}
4748
void IECProtocol::timer_stop()
4849
{
4950
esp_timer_stop(timer_handle);
51+
timer_elapsed = esp_timer_get_time() - timer_started;
5052
//IEC.release( PIN_IEC_SRQ );
5153
}
5254

@@ -93,7 +95,6 @@ int16_t IRAM_ATTR IECProtocol::timeoutWait(uint8_t pin, bool target_status, size
9395
uint64_t start = 0;
9496
uint64_t current = 0;
9597
uint64_t elapsed = 0;
96-
bool atn_status = false;
9798

9899
#ifndef IEC_SPLIT_LINES
99100
IEC.release ( pin );
@@ -113,9 +114,9 @@ int16_t IRAM_ATTR IECProtocol::timeoutWait(uint8_t pin, bool target_status, size
113114
IEC.release ( PIN_IEC_ATN );
114115
#endif
115116

116-
// // Sample ATN and set flag to indicate COMMAND or DATA mode
117-
// atn_status = IEC.status ( PIN_IEC_ATN );
118-
// if ( atn_status ) IEC.flags |= ATN_PULLED;
117+
// Sample ATN and set flag to indicate COMMAND or DATA mode
118+
if( IEC.status ( PIN_IEC_ATN ) )
119+
IEC.flags |= ATN_PULLED;
119120
}
120121

121122
//IEC.pull ( PIN_IEC_SRQ );
@@ -134,9 +135,10 @@ int16_t IRAM_ATTR IECProtocol::timeoutWait(uint8_t pin, bool target_status, size
134135
return wait_us;
135136
}
136137

137-
if ( watch_atn && (IEC.flags & ATN_PULLED) )
138+
if ( watch_atn )
138139
{
139-
return -1;
140+
if ( IEC.flags & ATN_PULLED )
141+
return -1;
140142
}
141143

142144
if ( IEC.state < BUS_ACTIVE || elapsed > FOREVER )

lib/bus/iec/protocol/_protocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace Protocol
2525
};
2626

2727
bool timer_timedout = false;
28+
uint64_t timer_started = 0;
2829
uint64_t timer_elapsed = 0;
2930

3031

lib/bus/iec/protocol/cpbstandardserial.cpp

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ CPBStandardSerial::CPBStandardSerial()
7474
.callback = onSendBits,
7575
.arg = this,
7676
.dispatch_method = ESP_TIMER_ISR,
77-
.name = "Send"
77+
.name = "onSendBits"
7878
};
7979
esp_timer_create(&args, &timer_send_h);
8080
//Debug_printv("send_timer_create");
@@ -119,6 +119,7 @@ uint8_t CPBStandardSerial::receiveByte()
119119
// to accept data. What happens next is variable.
120120

121121
// Wait for all other devices to release the data line
122+
//IEC.release( PIN_IEC_DATA_IN );
122123
if ( timeoutWait ( PIN_IEC_DATA_IN, RELEASED, FOREVER, false ) == TIMED_OUT )
123124
{
124125
Debug_printv ( "Wait for all other devices to release the data line" );
@@ -131,10 +132,8 @@ uint8_t CPBStandardSerial::receiveByte()
131132
// will do nothing. The listener should be watching, and if 200 microseconds pass
132133
// without the Clock line going to true, it has a special task to perform: note EOI.
133134

134-
//IEC.pull ( PIN_IEC_SRQ );
135+
IEC.pull ( PIN_IEC_SRQ );
135136
if ( timeoutWait ( PIN_IEC_CLK_IN, PULLED, TIMING_Tye, false ) == TIMING_Tye )
136-
// timer_start( TIMING_Tye );
137-
// while ( IEC.status ( PIN_IEC_CLK_IN ) != PULLED )
138137
{
139138
// INTERMISSION: EOI
140139
// If the Ready for Data signal isn't acknowledged by the talker within 200 microseconds, the
@@ -152,30 +151,23 @@ uint8_t CPBStandardSerial::receiveByte()
152151

153152
//IEC.pull ( PIN_IEC_SRQ );
154153

155-
//if ( timer_timedout )
156-
{
157-
timer_timedout = false;
158-
IEC.flags |= EOI_RECVD;
159-
160-
// Acknowledge by pull down data more than 60us
161-
//wait ( TIMING_Th );
162-
IEC.pull ( PIN_IEC_DATA_OUT );
163-
wait ( TIMING_Tei );
164-
IEC.release ( PIN_IEC_DATA_OUT );
154+
timer_timedout = false;
155+
IEC.flags |= EOI_RECVD;
165156

166-
// Wait for clock line to be pulled
167-
timeoutWait ( PIN_IEC_CLK_IN, PULLED, TIMING_Tye, false );
168-
}
157+
// Acknowledge by pull down data more than 60us
158+
//wait ( TIMING_Th );
159+
IEC.pull ( PIN_IEC_DATA_OUT );
160+
wait ( TIMING_Tei );
161+
IEC.release ( PIN_IEC_DATA_OUT );
169162

170-
//usleep( 2 );
171-
//IEC.release ( PIN_IEC_SRQ );
172-
//usleep( 2 );
163+
// Wait for clock line to be pulled
164+
//timeoutWait ( PIN_IEC_CLK_IN, PULLED, TIMING_Tye, false );
173165
}
174-
//IEC.release ( PIN_IEC_SRQ );
166+
IEC.release ( PIN_IEC_SRQ );
175167

176-
// Sample ATN and set flag to indicate COMMAND or DATA mode
177-
if ( IEC.status ( PIN_IEC_ATN ) )
178-
IEC.flags |= ATN_PULLED;
168+
// // Sample ATN and set flag to indicate COMMAND or DATA mode
169+
// if ( IEC.status ( PIN_IEC_ATN ) )
170+
// IEC.flags |= ATN_PULLED;
179171

180172
// STEP 3: RECEIVING THE BITS
181173
//IEC.pull ( PIN_IEC_SRQ );
@@ -229,18 +221,23 @@ uint8_t CPBStandardSerial::receiveBits ()
229221
{
230222
IEC.bit = 0;
231223
IEC.byte = 0;
232-
timer_start( TIMEOUT_DEFAULT );
233224

225+
timer_start( TIMEOUT_DEFAULT );
234226
while ( IEC.bit < 7 )
235227
{
236228
if ( timer_timedout )
237229
{
230+
Debug_printv ( "Timeout bit[%d]", IEC.bit );
238231
IEC.flags |= ERROR;
239232
return 0;
240233
}
241234

242-
usleep( 2 );
235+
IEC.pull( PIN_IEC_SRQ );
236+
usleep( 1 );
237+
IEC.release( PIN_IEC_SRQ );
238+
usleep( 1 );
243239
}
240+
timer_stop();
244241

245242
// If there is a 218us delay before bit 7, the controller uses JiffyDOS
246243
timer_start( TIMING_PROTOCOL_DETECT );
@@ -270,8 +267,12 @@ uint8_t CPBStandardSerial::receiveBits ()
270267
}
271268
}
272269

273-
usleep( 2 );
270+
IEC.pull( PIN_IEC_SRQ );
271+
usleep( 1 );
272+
IEC.release( PIN_IEC_SRQ );
273+
usleep( 1 );
274274
}
275+
timer_stop();
275276

276277
// Wait for CLK to be pulled after last bit
277278
if ( timeoutWait ( PIN_IEC_CLK_IN, PULLED, FOREVER, false ) == TIMED_OUT )
@@ -396,7 +397,7 @@ bool CPBStandardSerial::sendByte(uint8_t data, bool eoi)
396397
// line to false. Suppose there is more than one listener. The Data line will go false
397398
// only when all listeners have RELEASED it - in other words, when all listeners are ready
398399
// to accept data.
399-
IEC.pull ( PIN_IEC_SRQ );
400+
//IEC.pull ( PIN_IEC_SRQ );
400401
if ( timeoutWait ( PIN_IEC_DATA_IN, RELEASED, FOREVER ) == TIMED_OUT )
401402
{
402403
if ( !(IEC.flags & ATN_PULLED) )
@@ -407,7 +408,7 @@ bool CPBStandardSerial::sendByte(uint8_t data, bool eoi)
407408

408409
return false; // return error because of ATN or timeout
409410
}
410-
IEC.release ( PIN_IEC_SRQ );
411+
//IEC.release ( PIN_IEC_SRQ );
411412

412413
// What happens next is variable. Either the talker will pull the
413414
// Clock line back to true in less than 200 microseconds - usually within 60 microseconds - or it
@@ -471,33 +472,33 @@ bool CPBStandardSerial::sendByte(uint8_t data, bool eoi)
471472

472473
// Wait for listener to accept data
473474
//IEC.pull ( PIN_IEC_SRQ );
474-
// if ( timeoutWait ( PIN_IEC_DATA_IN, PULLED, TIMEOUT_Tf ) == TIMEOUT_Tf )
475+
if ( timeoutWait ( PIN_IEC_DATA_IN, PULLED, TIMEOUT_Tf ) == TIMEOUT_Tf )
476+
{
477+
// RECIEVER TIMEOUT
478+
// If no receiver pulls DATA within 1000 µs at the end of the transmission of a byte (after step 28), a receiver timeout is raised.
479+
Debug_printv ( "Wait for listener to acknowledge byte received (pull data) [%02X]", data );
480+
Debug_printv ( "RECEIVER TIMEOUT" );
481+
IEC.flags |= ERROR;
482+
//IEC.release ( PIN_IEC_SRQ );
483+
return false; // return error because timeout
484+
}
485+
//IEC.release ( PIN_IEC_SRQ );
486+
//IEC.pull ( PIN_IEC_SRQ );
487+
// timer_start( TIMEOUT_Tf );
488+
// while ( IEC.status ( PIN_IEC_DATA_IN ) != PULLED )
475489
// {
476-
// // RECIEVER TIMEOUT
477-
// // If no receiver pulls DATA within 1000 µs at the end of the transmission of a byte (after step 28), a receiver timeout is raised.
478-
// Debug_printv ( "Wait for listener to acknowledge byte received (pull data) [%02x]", data );
479-
// Debug_printv ( "RECEIVER TIMEOUT" );
480-
// IEC.flags |= ERROR;
481-
// IEC.release ( PIN_IEC_SRQ );
482-
// return false; // return error because timeout
490+
// if ( timer_timedout )
491+
// {
492+
// // RECIEVER TIMEOUT
493+
// // If no receiver pulls DATA within 1000 µs at the end of the transmission of a byte (after step 28), a receiver timeout is raised.
494+
// Debug_printv ( "Wait for listener to acknowledge byte received (pull data) [%02X]", data );
495+
// Debug_printv ( "RECEIVER TIMEOUT" );
496+
// IEC.flags |= ERROR;
497+
// //IEC.release ( PIN_IEC_SRQ );
498+
// return false; // return error because timeout
499+
// }
483500
// }
484501
//IEC.release ( PIN_IEC_SRQ );
485-
IEC.pull ( PIN_IEC_SRQ );
486-
timer_start( TIMEOUT_Tf );
487-
while ( IEC.status ( PIN_IEC_DATA_IN ) != PULLED )
488-
{
489-
if ( timer_timedout )
490-
{
491-
// RECIEVER TIMEOUT
492-
// If no receiver pulls DATA within 1000 µs at the end of the transmission of a byte (after step 28), a receiver timeout is raised.
493-
Debug_printv ( "Wait for listener to acknowledge byte received (pull data) [%02x]", data );
494-
Debug_printv ( "RECEIVER TIMEOUT" );
495-
IEC.flags |= ERROR;
496-
IEC.release ( PIN_IEC_SRQ );
497-
return false; // return error because timeout
498-
}
499-
}
500-
IEC.release ( PIN_IEC_SRQ );
501502

502503
// STEP 5: START OVER
503504
// We're finished, and back where we started. The talker is holding the Clock line true,

lib/device/iec/drive.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -355,15 +355,8 @@ void iecDrive::iec_command()
355355
{
356356
Debug_printv("command[%s]", payload.c_str());
357357

358-
// if (mstr::startsWith(payload, "cd"))
359-
// set_prefix();
360-
// else if (pt[0] == "pwd")
361-
// get_prefix();
362-
// else if (pt[0] == "id")
363-
// set_device_id();
364-
365358
// Drive level commands
366-
// CBM DOS 2.5
359+
// CBM DOS 2.6
367360
switch ( payload[0] )
368361
{
369362
case 'B':

lib/device/iec/drive.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,9 @@ class iecDrive : public virtualDevice
3737
std::unique_ptr<MFile> _base; // Always points to current directory/image
3838
std::string _last_file; // Always points to last loaded file
3939

40-
// Named Channel functions
41-
//std::shared_ptr<MStream> currentStream;
42-
bool registerStream (uint8_t channel);
43-
std::shared_ptr<MStream> retrieveStream ( uint8_t channel );
44-
bool closeStream ( uint8_t channel, bool close_all = false );
45-
uint16_t retrieveLastByte ( uint8_t channel );
46-
void storeLastByte( uint8_t channel, char last);
47-
void flushLastByte( uint8_t channel );
40+
// RAM/ROM
41+
// std::streambuf ram;
42+
std::unique_ptr<MFile> rom; // ROM File for current drive model if available
4843

4944
// Directory
5045
uint16_t sendHeader(std::string header, std::string id);
@@ -58,6 +53,14 @@ class iecDrive : public virtualDevice
5853
bool saveFile();
5954
void sendFileNotFound();
6055

56+
// Named Channel functions
57+
bool registerStream (uint8_t channel);
58+
std::shared_ptr<MStream> retrieveStream ( uint8_t channel );
59+
bool closeStream ( uint8_t channel, bool close_all = false );
60+
uint16_t retrieveLastByte ( uint8_t channel );
61+
void storeLastByte( uint8_t channel, char last);
62+
void flushLastByte( uint8_t channel );
63+
6164
struct _error_response
6265
{
6366
unsigned char errnum = 73;

0 commit comments

Comments
 (0)