Initial code for installing our commands.

This code works to some extent, but tends to cause system hangs.

Also includes some DSI implementation fixes.
This commit is contained in:
Stephen Heumann 2017-03-31 18:04:57 -05:00
parent 65da8f895e
commit 9720f37531
10 changed files with 186 additions and 13 deletions

View File

@ -1,6 +1,6 @@
CFLAGS = -i -w
DSITEST_OBJS = dsitest.o aspinterface.o dsi.o readtcp.o endian.o tcpconnection.o atipmapping.o
DSITEST_OBJS = dsitest.o aspinterface.o dsi.o readtcp.o endian.o tcpconnection.o atipmapping.o asmglue.o
DSITEST_PROG = dsitest
AFPMOUNTER_OBJS = afpmounter.o callat.o endian.o
@ -9,7 +9,10 @@ AFPMOUNTER_PROG = afpmounter
DUMPCMDTBL_OBJS = dumpcmdtbl.o asmglue.o
DUMPCMDTBL_PROG = dumpcmdtbl
PROGS = $(DSITEST_PROG) $(AFPMOUNTER_PROG) $(DUMPCMDTBL_PROG)
AFPBRIDGE_OBJS = afpbridge.o aspinterface.o dsi.o readtcp.o endian.o tcpconnection.o atipmapping.o asmglue.o installcmds.o cmdproc.o callat.o
AFPBRIDGE_PROG = afpbridge
PROGS = $(DSITEST_PROG) $(AFPMOUNTER_PROG) $(DUMPCMDTBL_PROG) $(AFPBRIDGE_PROG)
.PHONY: $(PROGS)
default: $(PROGS)
@ -23,6 +26,9 @@ $(AFPMOUNTER_PROG): $(AFPMOUNTER_OBJS)
$(DUMPCMDTBL_PROG): $(DUMPCMDTBL_OBJS)
occ $(CFLAGS) -o $@ $(DUMPCMDTBL_OBJS)
$(AFPBRIDGE_PROG): $(AFPBRIDGE_OBJS)
occ $(CFLAGS) -o $@ $(AFPBRIDGE_OBJS)
%.macros: %.asm
macgen $< $@ /lang/orca/Libraries/ORCAInclude/m16.*

40
afpbridge.c Normal file
View File

@ -0,0 +1,40 @@
#include <locator.h>
#include <tcpip.h>
#include <orca.h>
#include <stdlib.h>
#include "installcmds.h"
#include "aspinterface.h"
#include "dsi.h"
#include "asmglue.h"
int main(void) {
Boolean loadedTCP = FALSE;
Boolean startedTCP = FALSE;
if (!TCPIPStatus()) {
LoadOneTool(54, 0x0300); /* load Marinetti 3.0+ */
if (toolerror())
goto error;
loadedTCP = TRUE;
TCPIPStartUp();
if (toolerror())
goto error;
startedTCP = TRUE;
}
installCmds();
while (TRUE) {
IncBusyFlag();
PollAllSessions();
DecBusyFlag();
asm { cop 0x7f }
}
error:
if (startedTCP)
TCPIPShutDown();
if (loadedTCP)
UnloadOneTool(54);
return;
}

View File

@ -1,6 +1,7 @@
case on
mcopy asmglue.macros
ROMIN gequ $C081
LCBANK2 gequ $C083
STATEREG gequ $C068
@ -15,6 +16,17 @@ ForceLCBank2 start
rtl
end
ForceRomIn start
short i,m
lda >STATEREG ;get original state reg.
tax
lda >ROMIN ;force ROM in to Language Card space
lda >ROMIN
long i,m
txa
rtl
end
RestoreStateReg start
short m
plx
@ -27,3 +39,7 @@ RestoreStateReg start
long m
rtl
end
completionRtn data
ds 4
end

View File

@ -4,6 +4,7 @@
#include <types.h>
extern Word ForceLCBank2(void);
extern Word ForceRomIn(void);
extern void RestoreStateReg(Word);
void IncBusyFlag(void) inline(0, 0xE10064);

View File

@ -9,6 +9,7 @@
#include "tcpconnection.h"
#include "endian.h"
#include "readtcp.h"
#include "asmglue.h"
static void CompleteCommand(Session *sess, Word result);
static void EndSession(Session *sess, Boolean callAttnRoutine);
@ -22,9 +23,13 @@ static void DoSPWrite(Session *sess, ASPWriteRec *commandRec);
Session sessionTbl[MAX_SESSIONS];
#pragma databank 1
void DispatchASPCommand(SPCommandRec *commandRec) {
Session *sess;
unsigned int i;
Word stateReg;
stateReg = ForceRomIn();
if (commandRec->command == aspGetStatusCommand
|| commandRec->command==aspOpenSessionCommand)
@ -35,21 +40,22 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
}
if (i == MAX_SESSIONS) {
CompleteCommand(sess, aspTooManySessions);
return;
goto ret;
}
sess = &sessionTbl[i];
sess->spCommandRec = commandRec;
if (!StartTCPConnection(sess)) {
FlagFatalError(sess, 0);
return;
goto ret;
}
sess->dsiStatus = awaitingHeader;
InitReadTCP(sess, DSI_HEADER_SIZE, &sess->reply);
} else {
if (commandRec->refNum < SESSION_NUM_START) {
// TODO call original AppleTalk routine (or do it earlier)
return;
commandRec->result = atInvalidCmdErr;
goto ret;
}
i = commandRec->refNum - SESSION_NUM_START;
sess = &sessionTbl[i];
@ -61,7 +67,7 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
if (commandRec->command != aspCloseSessionCommand) {
if (sess->commandPending) {
CompleteCommand(sess, aspSessNumErr);
return;
goto ret;
}
sess->commandPending = TRUE;
}
@ -86,7 +92,7 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
if ((commandRec->async & AT_ASYNC) && sess->commandPending) {
commandRec->result = aspBusyErr; // indicate call in process
return;
goto ret;
}
// if we're here, the call is synchronous -- we must complete it
@ -98,7 +104,11 @@ void DispatchASPCommand(SPCommandRec *commandRec) {
PollForData(sess);
}
}
ret:
RestoreStateReg(stateReg);
}
#pragma databank 0
static void DoSPGetStatus(Session *sess, ASPGetStatusRec *commandRec) {
static const Word kFPGetSrvrInfo = 15;
@ -143,10 +153,13 @@ static void DoSPCommand(Session *sess, ASPCommandRec *commandRec) {
sess->request.requestID = htons(sess->nextRequestID++);
sess->request.writeOffset = 0;
sess->request.totalDataLength = htonl(commandRec->cmdBlkLength);
sess->replyBuf = (void*)commandRec->replyBufferAddr;
sess->replyBuf = (void*)(commandRec->replyBufferAddr & 0x00FFFFFF);
sess->replyBufLen = commandRec->replyBufferLen;
SendDSIMessage(sess, &sess->request, (void*)commandRec->cmdBlkAddr, NULL);
/* Mask off high byte of addresses because PFI (at least) may
* put junk in them, and this can cause Marinetti errors. */
SendDSIMessage(sess, &sess->request,
(void*)(commandRec->cmdBlkAddr & 0x00FFFFFF), NULL);
}
static void DoSPWrite(Session *sess, ASPWriteRec *commandRec) {
@ -156,11 +169,12 @@ static void DoSPWrite(Session *sess, ASPWriteRec *commandRec) {
sess->request.writeOffset = htonl(commandRec->cmdBlkLength);
sess->request.totalDataLength =
htonl(commandRec->cmdBlkLength + commandRec->writeDataLength);
sess->replyBuf = (void*)commandRec->replyBufferAddr;
sess->replyBuf = (void*)(commandRec->replyBufferAddr & 0x00FFFFFF);
sess->replyBufLen = commandRec->replyBufferLen;
SendDSIMessage(sess, &sess->request, (void*)commandRec->cmdBlkAddr,
(void*)commandRec->writeDataAddr);
SendDSIMessage(sess, &sess->request,
(void*)(commandRec->cmdBlkAddr & 0x00FFFFFF),
(void*)(commandRec->writeDataAddr & 0x00FFFFFF));
}
@ -231,7 +245,10 @@ static void CompleteCommand(Session *sess, Word result) {
EndSession(sess, FALSE);
} else {
sess->commandPending = FALSE;
InitReadTCP(sess, DSI_HEADER_SIZE, &sess->reply);
if (sess->dsiStatus != error) {
sess->dsiStatus = awaitingHeader;
InitReadTCP(sess, DSI_HEADER_SIZE, &sess->reply);
}
}
commandRec->result = result;
@ -248,3 +265,13 @@ static void EndSession(Session *sess, Boolean callAttnRoutine) {
EndTCPConnection(sess);
memset(sess, 0, sizeof(*sess));
}
void PollAllSessions(void) {
unsigned int i;
for (i = 0; i < MAX_SESSIONS; i++) {
if (sessionTbl[i].dsiStatus != unused) {
PollForData(&sessionTbl[i]);
}
}
}

View File

@ -17,5 +17,6 @@ extern Session sessionTbl[MAX_SESSIONS];
void DispatchASPCommand(SPCommandRec *commandRec);
void FinishASPCommand(Session *sess);
void FlagFatalError(Session *sess, Word errorCode);
void PollAllSessions(void);
#endif

23
cmdproc.asm Normal file
View File

@ -0,0 +1,23 @@
case on
* Location of command rec ptr on entry to an AppleTalk command procedure
* (in the system zero page, which is the current direct page)
cmdRecPtr gequ $80
* Bogus segment to go into the .root file and force generation of .a/.o file
bogus private
nop
end
* AppleTalk command procedure (which acts as a dispatcher for all commands)
cmdProc start
lda 3,s
pha
lda 3,s
pha
lda cmdRecPtr
sta 4,s
lda cmdRecPtr+2
sta 6,s
jml DispatchASPCommand
end

3
dsi.c
View File

@ -166,6 +166,9 @@ top:
FlagFatalError(sess, aspNetworkErr);
return;
}
sess->dsiStatus = awaitingHeader;
InitReadTCP(sess, DSI_HEADER_SIZE, &sess->reply);
}
else
{

50
installcmds.c Normal file
View File

@ -0,0 +1,50 @@
#pragma noroot
#include <types.h>
#include <AppleTalk.h>
#include "asmglue.h"
extern void cmdProc(void);
extern LongWord completionRtn;
typedef struct NewCmd {
Word cmdNum;
void (*cmdAddr)(void);
} NewCmd;
NewCmd newCmds[] = {
{aspGetStatusCommand, cmdProc},
{aspOpenSessionCommand, cmdProc},
{aspCloseSessionCommand, cmdProc},
{aspCommandCommand, cmdProc},
{aspWriteCommand, cmdProc},
{0, 0}
};
LongWord *cmdTable = (LongWord *)0xE1D600;
#define MAX_CMD rpmFlushSessionCommand
LongWord oldCmds[MAX_CMD + 1]; /* holds old entries for commands we changed */
ATGetInfoRec getInfoRec;
void installCmds(void) {
Word savedStateReg;
NewCmd *cmd;
getInfoRec.async = 0;
getInfoRec.command = atGetInfoCommand;
_CALLAT(&getInfoRec);
completionRtn = getInfoRec.completionRtn;
savedStateReg = ForceLCBank2();
for (cmd = newCmds; cmd->cmdNum != 0; cmd++) {
oldCmds[cmd->cmdNum] = cmdTable[cmd->cmdNum];
cmdTable[cmd->cmdNum] =
(oldCmds[cmd->cmdNum] & 0xFF000000) | (LongWord)cmd->cmdAddr;
}
RestoreStateReg(savedStateReg);
}

6
installcmds.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef INSTALLCMDS_H
#define INSTALLCMDS_H
void installCmds(void);
#endif