;Alto->8086 small-c compiler rev 2.0
C←CODE SEGMENT

$INCLUDE(8086LIB.D)

$INCLUDE(larkeload.DEC)

ASSUME CS:C←CODE, DS:C←DATA

; #include <Ec.h>

; struct Core {

;   int advice, addrlo, addrhi, count;

;   char data[1];

;   };

; extern MoveBlock();

; extern ByteBlt();

; extern Swab();

; extern DoubleEQ();

; extern OpenLevel1Socket();

; extern SendPup();

; extern ReleasePBI();

; extern CheckCheckSum();

; extern SwapSourceAndDest();

; extern int localNet;

; extern int localHost;

; extern int lenPup;

; static struct Port elPort;

; static int elSoc;

; ELoadProc(pbi)
←ELoadProc:

;   struct PBI *pbi;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   struct Pup *p;

;   char *caddr;

;   char *cdata;

;   int ccount;

;   int ptype;

;   int maxLength;

;   struct Core *core;
ADD SP,0FFF2X

;   p = pbi->pup;

;	BX ← ←pbi
MOV BX,[BP-2]
MOV CX,[BX+6]

;	←p ← CX
MOV [BP-4],CX

;   ptype = p->type;

;	BX ← ←p
MOV BX,[BP-4]
MOV AL,[BX+3]
XOR AH,AH

;	←ptype ← AX
MOV [BP-12],AX

;   if ((p->dPort.host == 0) && (ptype != ELStateRead)) goto reject;

;	BX ← ←p
MOV BX,[BP-4]
MOV AL,[BX+9]
OR AL,AL
JNZ X2

;	BX ← ←ptype
MOV BX,[BP-12]
CMP BX,0C6X
JZ X2
MOV AL,1
JR X3
X2:
XOR AL,AL
X3:
OR AL,AL
JZ X1
JMP ←reject
X1:

;   core = (struct Core *) &p->data;

;	BX ← ←p
MOV BX,[BP-4]
ADD BX,014X

;	←core ← BX
POP DX
PUSH BX

;   caddr = Swab(core->addrlo);

;	BX ← ←core
POP BX
PUSH BX
MOV CX,[BX+2]
MOV BX,CX
CALL ←Swab

;	←caddr ← BX
MOV [BP-6],BX

;   maxLength = ((lenPup - pupOvWords) - 3) << 1;
MOV BX,←lenPup
ADD BX,0FFF5X
ADD BX,0FFFDX
SAL BX

;	←maxLength ← BX
MOV [BP-14],BX

;   ccount = Swab(core->count);

;	BX ← ←core
POP BX
PUSH BX
MOV CX,[BX+6]
MOV BX,CX
CALL ←Swab

;	←ccount ← BX
MOV [BP-10],BX

;   if (ccount < 0) goto reject;

;	BX ← ←ccount
MOV BX,[BP-10]
CMP BX,0
JGE X4
JMP ←reject
X4:

;   if (ccount > maxLength) {

;	BX ← ←maxLength
MOV BX,[BP-14]

;	CX ← ←ccount
MOV CX,[BP-10]
CMP CX,BX
JLE X5

;     ccount = maxLength;

;	BX ← ←maxLength
MOV BX,[BP-14]

;	←ccount ← BX
MOV [BP-10],BX

;     core->count = Swab(maxLength);

;	BX ← ←core
POP BX
PUSH BX
PUSH BX

;	BX ← ←maxLength
MOV BX,[BP-14]
CALL ←Swab
MOV CX,BX
POP BX
MOV [BX+6],CX

;     };
X5:

;   cdata = &core->data[0];

;	BX ← ←core
POP BX
PUSH BX
ADD BX,8

;	←cdata ← BX
MOV [BP-8],BX

;   if (core->addrhi) goto reject;

;	BX ← ←core
POP BX
PUSH BX
MOV CX,[BX+4]
OR CX,CX
JZ X6
JMP ←reject
X6:

;   if (!CheckCheckSum(p)) goto reject;

;	BX ← ←p
MOV BX,[BP-4]
CALL ←CheckCheckSum
OR BX,BX
JNZ X7
JMP ←reject
X7:

;   switch (ptype) {

;	BX ← ←ptype
MOV BX,[BP-12]
JR X8

;     case ELWrite:
X10:

;       ByteBlt(caddr, cdata, ccount);

;	BX ← ←caddr
MOV BX,[BP-6]
PUSH BX

;	BX ← ←ccount
MOV BX,[BP-10]

;	CX ← ←cdata
MOV CX,[BP-8]
CALL ←ByteBlt
POP DX

;     case ELRead:
X11:

;       if (Ugt(caddr, 0xffcf)) goto reject;
MOV BX,0FFCFX

;	CX ← ←caddr
MOV CX,[BP-6]
CALL ←Ugt
OR BX,BX
JZ X12
JMP ←reject
X12:

;       if (Ugt(ccount, 0xffd0 - ((int) caddr))) goto reject;

;	BX ← ←caddr
MOV BX,[BP-6]
MOV CX,0FFD0X
SUB CX,BX
MOV BX,CX

;	CX ← ←ccount
MOV CX,[BP-10]
CALL ←Ugt
OR BX,BX
JZ X13
JMP ←reject
X13:

;       ByteBlt(cdata, caddr, ccount);

;	BX ← ←cdata
MOV BX,[BP-8]
PUSH BX

;	BX ← ←ccount
MOV BX,[BP-10]

;	CX ← ←caddr
MOV CX,[BP-6]
CALL ←ByteBlt
POP DX

;       SwapSourceAndDest(p);

;	BX ← ←p
MOV BX,[BP-4]
CALL ←SwapSourceAndDest

;       p->length = Swab((31 + ccount) & 0xfffe);

;	BX ← ←ccount
MOV BX,[BP-10]
ADD BX,01FX
AND BX,0FFFEX
CALL ←Swab
MOV CX,BX

;	BX ← ←p
MOV BX,[BP-4]
MOV [BX],CX

;       Block();
CALL ←Block

;       p->type = p->type + 1;

;	BX ← ←p
MOV BX,[BP-4]

;	CX ← ←p
MOV CX,[BP-4]
MOV DI,CX
MOV AL,[DI+3]
INC AL
MOV [BX+3],AL

;       SendPup(pbi);

;	BX ← ←pbi
MOV BX,[BP-2]
CALL ←SendPup

;       return;
JR $+5
X8:
JMP X14
MOV SP,BP
POP BP
RET;

;     case ELSWrite:
X15:

;       SlaveBLT(caddr, cdata, ccount);  /* how tell when it is done ? */

;	BX ← ←caddr
MOV BX,[BP-6]
PUSH BX

;	BX ← ←ccount
MOV BX,[BP-10]

;	CX ← ←cdata
MOV CX,[BP-8]
CALL ←SlaveBLT
POP DX

;     case ELSRead:
X16:

;       SlaveBLT(cdata, caddr, ccount);

;	BX ← ←cdata
MOV BX,[BP-8]
PUSH BX

;	BX ← ←ccount
MOV BX,[BP-10]

;	CX ← ←caddr
MOV CX,[BP-6]
CALL ←SlaveBLT
POP DX

;       SwapSourceAndDest(p);

;	BX ← ←p
MOV BX,[BP-4]
CALL ←SwapSourceAndDest

;       p->length = Swab((31 + ccount) & 0xfffe);

;	BX ← ←ccount
MOV BX,[BP-10]
ADD BX,01FX
AND BX,0FFFEX
CALL ←Swab
MOV CX,BX

;	BX ← ←p
MOV BX,[BP-4]
MOV [BX],CX

;       Block();
CALL ←Block

;       p->type = p->type + 1;

;	BX ← ←p
MOV BX,[BP-4]

;	CX ← ←p
MOV CX,[BP-4]
MOV DI,CX
MOV AL,[DI+3]
INC AL
MOV [BX+3],AL

;       SendPup(pbi);

;	BX ← ←pbi
MOV BX,[BP-2]
CALL ←SendPup

;       return;
MOV SP,BP
POP BP
RET;

;     case ELCall:
X17:

;       ClientCallPkt(cdata);

;	BX ← ←cdata
MOV BX,[BP-8]
CALL ←ClientCallPkt

;       SwapSourceAndDest(p);

;	BX ← ←p
MOV BX,[BP-4]
CALL ←SwapSourceAndDest

;       p->type = p->type + 1;

;	BX ← ←p
MOV BX,[BP-4]

;	CX ← ←p
MOV CX,[BP-4]
MOV DI,CX
MOV AL,[DI+3]
INC AL
MOV [BX+3],AL

;       SendPup(pbi);

;	BX ← ←pbi
MOV BX,[BP-2]
CALL ←SendPup

;       return;
MOV SP,BP
POP BP
RET;

;     case ELStateRead: 
X18:

;       if ((int) caddr != 1) goto reject;

;	BX ← ←caddr
MOV BX,[BP-6]
CMP BX,1
JZ X19
JMP ←reject
X19:

;       ByteBlt(cdata, 0xda00, ccount);

;	BX ← ←cdata
MOV BX,[BP-8]
PUSH BX

;	BX ← ←ccount
MOV BX,[BP-10]
MOV CX,0DA00X
CALL ←ByteBlt
POP DX

;       SwapSourceAndDest(p);

;	BX ← ←p
MOV BX,[BP-4]
CALL ←SwapSourceAndDest

;       p->length = Swab((31 + ccount) & 0xfffe);

;	BX ← ←ccount
MOV BX,[BP-10]
ADD BX,01FX
AND BX,0FFFEX
CALL ←Swab
MOV CX,BX

;	BX ← ←p
MOV BX,[BP-4]
MOV [BX],CX

;       Block();
CALL ←Block

;       p->type = p->type + 1;

;	BX ← ←p
MOV BX,[BP-4]

;	CX ← ←p
MOV CX,[BP-4]
MOV DI,CX
MOV AL,[DI+3]
INC AL
MOV [BX+3],AL

;       SendPup(pbi);

;	BX ← ←pbi
MOV BX,[BP-2]
CALL ←SendPup

;       return;
MOV SP,BP
POP BP
RET;

;     case ELDebug: { CallDebugger(ecPup1+21); goto reject; };
X20:
MOV BX,04015X
CALL ←CallDebugger
JMP ←reject

;     default: goto reject;
X21:
JMP ←reject

;     };
JR X9
X14:
MOV AL,BH
OR AL,AL
JNZ X21
MOV AL,BL
CMP AL,0C0X
JMPZ X10
CMP AL,0C2X
JMPZ X11
CMP AL,0CEX
JMPZ X15
CMP AL,0D0X
JMPZ X16
CMP AL,0D2X
JMPZ X17
CMP AL,0C6X
JMPZ X18
CMP AL,0C8X
JZ X20
JR X21
X9:
←reject:

;   reject: ReleasePBI(pbi);

;	BX ← ←pbi
MOV BX,[BP-2]
CALL ←ReleasePBI

;   };
MOV SP,BP
POP BP
RET;

; ELoad()
←ELoad:
PUSH BP
MOV BP,SP

;   {

;   elPort.net = localNet;
MOV AX,←localNet
MOV ←elPort,AL

;   elPort.host = localHost;
MOV AX,←localHost
MOV ←elPort+1,AL

;   elPort.socket.LS = 0;
MOV WORD PTR ←elPort+2,0

;   elPort.socket.ms = 0x3000;
MOV WORD PTR ←elPort+4,03000X

;   elSoc = OpenLevel1Socket(&elPort, &ELoadProc, 0);
LEA BX,←elPort
PUSH BX
XOR BX,BX
MOV CX,OFFSET ←ELoadProc
CALL ←OpenLevel1Socket
POP DX
MOV ←elSoc,BX

;   if (!elSoc) CallDebugger(ecPup1+10);
MOV BX,←elSoc
OR BX,BX
JNZ X22
MOV BX,0400AX
CALL ←CallDebugger
X22:

;   };
MOV SP,BP
POP BP
RET;

; struct CCPArgs {

;   int proc;

;   int nargs;

;   int returnSlot;

;   int args[5];

;   };

; ClientCallPkt(cp)
←ClientCallPkt:

;   struct CCPArgs *cp;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   BlockSwab(cp, 8);
MOV BX,8

;	CX ← ←cp
POP CX
PUSH CX
CALL ←BlockSwab

;   if (cp->nargs > 5) return;

;	BX ← ←cp
POP BX
PUSH BX
MOV CX,[BX+2]
MOV BX,CX
CMP BX,5
JLE X23
MOV SP,BP
POP BP
RET;
X23:

;   cp->returnSlot = Apply(&cp->args[0], cp->proc, cp->nargs);

;	BX ← ←cp
POP BX
PUSH BX
PUSH BX

;	BX ← ←cp
MOV BX,[BP-2]
ADD BX,6
PUSH BX

;	DI ← ←cp
MOV DI,[BP-2]
MOV BX,[DI]

;	CX ← ←cp
MOV CX,[BP-2]
MOV DI,CX
MOV CX,[DI+2]
XCHG BX,CX
CALL ←Apply
POP DX
MOV CX,BX
POP BX
MOV [BX+4],CX

;   BlockSwab(cp, 8);
MOV BX,8

;	CX ← ←cp
POP CX
PUSH CX
CALL ←BlockSwab

;   };
MOV SP,BP
POP BP
RET;

; Externals Declared Here
PUBLIC ←ELoadProc
PUBLIC ←ClientCallPkt
PUBLIC ←ELoad

C←CODE ENDS

; Number of Bytes of Code = 02DCX, (732)