mirror of
https://github.com/sheumann/AFPBridge.git
synced 2024-11-01 01:05:06 +00:00
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:
parent
65da8f895e
commit
9720f37531
10
Makefile.mk
10
Makefile.mk
@ -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
40
afpbridge.c
Normal 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;
|
||||
}
|
16
asmglue.asm
16
asmglue.asm
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
23
cmdproc.asm
Normal 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
3
dsi.c
@ -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
50
installcmds.c
Normal 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
6
installcmds.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef INSTALLCMDS_H
|
||||
#define INSTALLCMDS_H
|
||||
|
||||
void installCmds(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user