Add support for soft reset.

This can occur when control-reset is pressed in P8 mode. It’s supposed to reinitialize the AppleTalk stack. In our case, we mark connections to be reset once we're back in GS/OS, since we can't call Marinetti in P8 mode.
This commit is contained in:
Stephen Heumann 2017-04-16 13:36:01 -05:00
parent 7d2c225d2f
commit 9d6dad03b4
5 changed files with 55 additions and 5 deletions

View File

@ -14,6 +14,7 @@
const char bootInfoString[] = "AFPBridge v1.0b1";
extern Word *unloadFlagPtr;
extern void resetRoutine(void);
FSTInfoRecGS fstInfoRec;
@ -41,6 +42,11 @@ static struct NotificationProcRec {
NotifyProcRecGS addNotifyProcRec;
LongWord *SoftResetPtr = (LongWord *)0xE11010;
extern LongWord oldSoftReset;
#define JML 0x5C
void setUnloadFlag(void) {
if (*unloadFlagPtr == 0)
*unloadFlagPtr = 1;
@ -91,18 +97,21 @@ int main(void) {
runQRec.period = 1;
runQRec.signature = 0xA55A;
runQRec.jml = 0x5C;
runQRec.jml = JML;
runQRec.proc = pollTask;
AddToRunQ((Pointer)&runQRec);
notificationProcRec.Signature = 0xA55A;
notificationProcRec.Event_flags = 0x20; /* shutdown */
notificationProcRec.jml = 0x5C;
notificationProcRec.jml = JML;
notificationProcRec.proc = notificationProc;
addNotifyProcRec.pCount = 1;
addNotifyProcRec.procPointer = (ProcPtr)&notificationProcRec;
AddNotifyProcGS(&addNotifyProcRec);
oldSoftReset = *SoftResetPtr;
*SoftResetPtr = ((LongWord)&resetRoutine << 8) | JML;
return;
error:

View File

@ -1,13 +1,24 @@
case on
dummy private
jml InitStart
bra InitStart
end
unloadFlagPtr data
ds 4
end
* This gets called when control-reset is pressed in P8 mode.
* It's intended to basically reinitialize the whole AppleTalk stack.
resetRoutine start
jsl oldSoftReset
jml ResetAllSessions
end
oldSoftReset start
ds 4 ; to be modified
end
InitStart private
tay
tsc

View File

@ -62,6 +62,10 @@ LongWord DispatchASPCommand(SPCommandRec *commandRec) {
goto callOrig;
}
for (i = 0; i < MAX_SESSIONS; i++) {
if (sessionTbl[i].dsiStatus == needsReset)
EndSession(&sessionTbl[i], 0);
}
for (i = 0; i < MAX_SESSIONS; i++) {
if (sessionTbl[i].dsiStatus == unused)
break;
@ -399,8 +403,15 @@ void PollAllSessions(void) {
unsigned int i;
for (i = 0; i < MAX_SESSIONS; i++) {
if (sessionTbl[i].dsiStatus != unused) {
switch (sessionTbl[i].dsiStatus) {
case awaitingHeader:
case awaitingPayload:
PollForData(&sessionTbl[i]);
break;
case needsReset:
EndSession(&sessionTbl[i], 0);
break;
}
}
}
@ -419,3 +430,20 @@ void CloseAllSessions(Byte attentionCode) {
}
}
/*
* Reset the state of all sessions.
* Used when control-reset is pressed in P8 mode. We can't call Marinetti
* in P8 mode, but we also don't want to just leak any ipids in use, so
* we flag sessions that should be reset when we're back in GS/OS.
*/
#pragma databank 1
void ResetAllSessions(void) {
unsigned int i;
for (i = 0; i < MAX_SESSIONS; i++) {
if (sessionTbl[i].dsiStatus != unused) {
sessionTbl[i].dsiStatus = needsReset;
}
}
}
#pragma databank 0

View File

@ -20,5 +20,6 @@ void FinishASPCommand(Session *sess);
void FlagFatalError(Session *sess, Word errorCode);
void PollAllSessions(void);
void CloseAllSessions(Byte attentionCode);
void ResetAllSessions(void);
#endif

View File

@ -19,7 +19,8 @@ typedef enum DSISessionStatus {
unused = 0,
awaitingHeader,
awaitingPayload,
error
error,
needsReset /* set after control-reset in P8 mode */
} DSISessionStatus;
typedef struct Session {