/* LarkELoad.c
Pup package based download and teledebugging
L. Stewart, December 27, 1982 10:59 PM, created from cmeload.c
L. Stewart, February 24, 1983 8:46 PM, new protocol
L. Stewart, April 29, 1983 8:12 PM, slave and call stuff
*/
#include <Ec.h>
#include <Env.h>
#include <Queue.h>
#include <Pup.h>
#include <LarkSlave.h>
/* the format of junk is
struct Advice {
bit setAddr;
bit setAdvice;
bit(14) advice;
};
*/
struct Core {
int advice, addrlo, addrhi, count;
char data[1];
};
/* from runtime */
extern MoveBlock();
extern ByteBlt();
extern Swab();
extern DoubleEQ();
/* from Pup package */
extern OpenLevel1Socket();
extern SendPup();
extern ReleasePBI();
extern CheckCheckSum();
extern SwapSourceAndDest();
extern int localNet;
extern int localHost;
extern int lenPup;
/* local variables */
static struct Port elPort;
static int elSoc;
#define ELWrite 0x00c0
#define ELRead 0x00c2
#define ELStateRead 0x00c6
#define ELDebug 0x00c8
/* read and write the slave address space */
#define ELSWrite 0x00ce
#define ELSRead 0x00d0
/* call a procedure */
#define ELCall 0x00d2
ELoadProc(pbi)
struct PBI *pbi;
{
struct Pup *p;
char *caddr;
char *cdata;
int ccount;
int ptype;
int maxLength;
struct Core *core;
p = pbi->pup;
ptype = p->type;
if ((p->dPort.host == 0) && (ptype != ELStateRead)) goto reject;
core = (struct Core *) &p->data;
caddr = Swab(core->addrlo);
maxLength = ((lenPup - pupOvWords) - 3) << 1;
ccount = Swab(core->count);
if (ccount < 0) goto reject;
if (ccount > maxLength) {
ccount = maxLength;
core->count = Swab(maxLength);
};
cdata = &core->data[0];
if (core->addrhi) goto reject;
if (!CheckCheckSum(p)) goto reject;
switch (ptype) {
case ELWrite:
ByteBlt(caddr, cdata, ccount);
case ELRead:
if (Ugt(caddr, 0xffcf)) goto reject;
if (Ugt(ccount, 0xffd0 - ((int) caddr))) goto reject;
ByteBlt(cdata, caddr, ccount);
/* swap source and destination */
SwapSourceAndDest(p);
p->length = Swab((31 + ccount) & 0xfffe);
Block();
p->type = p->type + 1;
SendPup(pbi);
return;
case ELSWrite:
SlaveBLT(caddr, cdata, ccount); /* how tell when it is done ? */
case ELSRead:
SlaveBLT(cdata, caddr, ccount);
SwapSourceAndDest(p);
p->length = Swab((31 + ccount) & 0xfffe);
Block();
p->type = p->type + 1;
SendPup(pbi);
return;
case ELCall:
ClientCallPkt(cdata);
SwapSourceAndDest(p);
p->type = p->type + 1;
SendPup(pbi);
return;
case ELStateRead:
if ((int) caddr != 1) goto reject;
ByteBlt(cdata, 0xda00, ccount);
/* swap source and destination */
SwapSourceAndDest(p);
p->length = Swab((31 + ccount) & 0xfffe);
Block();
p->type = p->type + 1;
SendPup(pbi);
return;
case ELDebug: { CallDebugger(ecPup1+21); goto reject; };
default: goto reject;
};
reject: ReleasePBI(pbi);
};
/* call ELoad to set up a TeleDebug server */
ELoad()
{
elPort.net = localNet;
elPort.host = localHost;
elPort.socket.LS = 0;
elPort.socket.ms = 0x3000;
elSoc = OpenLevel1Socket(&elPort, &ELoadProc, 0);
if (!elSoc) CallDebugger(ecPup1+10);
};
struct CCPArgs {
int proc;
int nargs;
int returnSlot;
int args[5];
};
ClientCallPkt(cp)
struct CCPArgs *cp;
{
BlockSwab(cp, 8);
if (cp->nargs > 5) return;
cp->returnSlot = Apply(&cp->args[0], cp->proc, cp->nargs);
BlockSwab(cp, 8);
};