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

$INCLUDE(8086LIB.D)

$INCLUDE(FixedAlloc.DEC)

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

; #include	"env.h"

; struct Pool {

;   struct Queue freeList;

;   int owner;

;   int numItems;

;   int lenItem;

;   };

; struct GFOb {

;   int owner;

;   int owner2;

;   int length;

;   int data[1];

;   };

; extern int end;	/* See endml.asm; end of static storage */

; int *endFixed;

; int totAv;

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

;   {

;   int ans;
PUSH DX

;   ans = (int) &end;
LEA BX,←end

;	←ans ← BX
POP DX
PUSH BX

;   ans = (ans + 1) & -2;  /* round up */

;	BX ← ←ans
POP BX
INC BX
AND BX,0FFFEX

;	←ans ← BX
PUSH BX

;   endFixed = (int *) ans;

;	BX ← ←ans
POP BX
PUSH BX
MOV ←endFixed,BX

;   Zero(endFixed, FixedLeft());
CALL ←FixedLeft
MOV CX,←endFixed
CALL ←Zero

;   };
MOV SP,BP
POP BP
RET;

; int FixedLeft()
←FixedLeft:
PUSH BP
MOV BP,SP

;   {

;   int ans;
PUSH DX

;   ans = (int) endFixed;
MOV BX,←endFixed

;	←ans ← BX
POP DX
PUSH BX

;   totAv = (memTop - ans) >> 1;

;	BX ← ←ans
POP BX
PUSH BX
MOV CX,0CFFEX
SUB CX,BX
SHR CX
MOV ←totAv,CX

;   return (totAv);
MOV BX,←totAv
MOV SP,BP
POP BP
RET;

;   };

; int *GetFixed(nWords)
←GetFixed:

;   int nWords;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   struct GFOb *fp;

;   if (Ugt(endFixed + nWords + lenGFOb + lenGFOb, memTop)) CallDebugger(ecAllocate+5);
PUSH DX

;	BX ← ←nWords
MOV BX,[BP-2]
ADD BX,6
MOV CX,←endFixed
SAL BX
ADD BX,CX
PUSH BX
MOV BX,0CFFEX
POP CX
CALL ←Ugt
OR BX,BX
JZ X1
MOV BX,01005X
CALL ←CallDebugger
X1:

;   fp = (struct GFOb *) endFixed;
MOV BX,←endFixed

;	←fp ← BX
POP DX
PUSH BX

;   endFixed += lenGFOb;
ADD ←endFixed,6

;   endFixed += nWords;

;	BX ← ←nWords
MOV BX,[BP-2]
SAL BX
ADD ←endFixed,BX

;   Zero(fp, lenGFOb + nWords + lenGFOb);

;	BX ← ←nWords
MOV BX,[BP-2]
ADD BX,3
ADD BX,3

;	CX ← ←fp
POP CX
PUSH CX
CALL ←Zero

;   fp->length = nWords;

;	BX ← ←fp
POP BX
PUSH BX

;	CX ← ←nWords
MOV CX,[BP-2]
MOV [BX+4],CX

;   fp->owner = ReturnLoc(MyFrame());
CALL ←MyFrame
CALL ←ReturnLoc
MOV CX,BX

;	BX ← ←fp
POP BX
PUSH BX
MOV [BX],CX

;   fp->owner2 = ReturnLoc(CallersFrame(MyFrame()));

;	BX ← ←fp
POP BX
PUSH BX
PUSH BX
CALL ←MyFrame
CALL ←CallersFrame
CALL ←ReturnLoc
MOV CX,BX
POP BX
MOV [BX+2],CX

;   return(&fp->data[0]);

;	BX ← ←fp
POP BX
PUSH BX
ADD BX,6
MOV SP,BP
POP BP
RET;

;   };

; struct Pool *CreatePool(itemSize, nItems)
←CreatePool:

;   int itemSize, nItems;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   struct Pool *pool;

;   int i;
ADD SP,0FFFCX

;   pool = (struct Pool *) GetFixed(lenPool);
MOV BX,5
CALL ←GetFixed

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

;   InitQueue(&pool->freeList);

;	BX ← ←pool
MOV BX,[BP-6]
CALL ←InitQueue

;   pool->owner = ReturnLoc(MyFrame());

;	BX ← ←pool
MOV BX,[BP-6]
PUSH BX
CALL ←MyFrame
CALL ←ReturnLoc
MOV CX,BX
POP BX
MOV [BX+4],CX

;   pool->numItems = nItems;

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

;	CX ← ←nItems
MOV CX,[BP-4]
MOV [BX+6],CX

;   pool->lenItem = itemSize;

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

;	CX ← ←itemSize
MOV CX,[BP-2]
MOV [BX+8],CX

;   for (i = 0; i < nItems; i += 1) Enqueue(&pool->freeList, GetFixed(itemSize));
MOV WORD PTR [BP-8],0
X4:

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

;	CX ← ←i
POP CX
PUSH CX
CMP CX,BX
JGE X3
JR X2
X5:
INC WORD PTR [BP-8]
JR X4
X2:

;	BX ← ←itemSize
MOV BX,[BP-2]
CALL ←GetFixed

;	CX ← ←pool
MOV CX,[BP-6]
CALL ←Enqueue
JR X5
X3:

;   };
MOV SP,BP
POP BP
RET;

; int *GetItem(pool)
←GetItem:

;   struct Pool *pool;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   return(Dequeue(&pool->freeList));

;	BX ← ←pool
POP BX
PUSH BX
CALL ←Dequeue
MOV SP,BP
POP BP
RET;

;   };

; FreeItem(pool, item)
←FreeItem:

;   struct Pool *pool;

;   int *item;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   Enqueue(&pool->freeList, item);

;	BX ← ←item
POP BX
PUSH BX

;	CX ← ←pool
MOV CX,[BP-2]
CALL ←Enqueue

;   };
MOV SP,BP
POP BP
RET;

; Externals Declared Here
PUBLIC ←endFixed
PUBLIC ←totAv
PUBLIC ←InitFA
PUBLIC ←FixedLeft
PUBLIC ←GetFixed
PUBLIC ←CreatePool
PUBLIC ←GetItem
PUBLIC ←FreeItem

C←CODE ENDS

; Number of Bytes of Code = 0138X, (312)