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

$INCLUDE(8086LIB.D)

$INCLUDE(LarkMon.DEC)

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

; #include	"Env.h"

; extern StartM();   /* execute using register save area */

; extern int mState[15];  /* register save area */

; extern int monRelays;

; extern int lastIP;

; extern int lastNMI;

; extern int bootSwitches;

; extern int rtcLow;

; extern StoreB();   /*  store(byte, address)  */

; extern SetTmr();  /* SetTmr(interval, &timer) */

; extern TmrExp();  /* if (TmrExp(&timer)) { ... } */

; extern KickWDT();  /* kick watchdog timer */

; extern InitAnalog();

; extern GetBootSwitches();

; extern GetPIO();

; extern FirstSendState();

; extern StartEL();

; extern CheckEL();

; extern int tlNet;

; extern int tlHost;

; extern int tlImHost;

; extern int localNet;

; struct regs {

;   int ax, bx, cx, dx;

;   int sp, bp, si, di;

;   int cs, ds, ss, es;

;   int ip, fl, why;

;   };

; struct regs *regp;  /* register save area */

; int ssCount;   /* number of tries at single stepping */

; int breakSS;   /* BOOLEAN -- proceeding from a breakpoint */

; int wdtTimer;  /* timer for scheduling WDT kicks */

; MonMain(why)
←MonMain:

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

;   {

;   regp = (struct regs *) mState;  /* use mstate later */
LEA BX,←mState
MOV ←regp,BX

;   PokeWDT();
CALL ←PokeWDT

;   switch (why) {

;	BX ← ←why
POP BX
PUSH BX
JR X1

;     case WDTBoot: { InitAnalog(); break; };
X3:
CALL ←InitAnalog
JR X2

;     case RESET: { MonInit(); break; };
X4:
CALL ←MonInit
JR X2

;     case TRACE: { MonTrace(); break; };
X5:
CALL ←MonTrace
JR X2

;     case NMI: { MonNMI(); break; };
X6:
CALL ←MonNMI
JR X2

;     };
JR X2
X1:
MOV DX,8
ADD BX,DX
MOV AL,BH
OR AL,AL
JNZ X2
MOV AL,BL
CMP AL,0
JZ X3
CMP AL,7
JZ X4
CMP AL,9
JZ X5
CMP AL,0AX
JZ X6
X2:

;   monRelays = 0;
MOV ←monRelays,0

;   if (GetPIO(iapioa) & 0x0080) monRelays |= 8;  /* revert */
MOV BX,3
CALL ←GetPIO
AND BX,080X
OR BX,BX
JZ X7
OR ←monRelays,8
X7:

;   if (!(GetPIO(iapioa) & 0x0040)) monRelays |= 4;  /* off hook */
MOV BX,3
CALL ←GetPIO
AND BX,040X
OR BX,BX
JNZ X8
OR ←monRelays,4
X8:

;   if (!(GetPIO(ipioc) & 0x0010)) monRelays |= 2; /* a relay */
MOV BX,2
CALL ←GetPIO
AND BX,010X
OR BX,BX
JNZ X9
OR ←monRelays,2
X9:

;   if (GetPIO(ipioc) & 0x0020) monRelays |= 1; /* revert hs relay */
MOV BX,2
CALL ←GetPIO
AND BX,020X
OR BX,BX
JZ X10
OR ←monRelays,1
X10:

;   Revert(true);
MOV BX,0FFFFX
CALL ←Revert

;   RevertHS(true);
MOV BX,0FFFFX
CALL ←RevertHS

;   GoOffHook(false);
XOR BX,BX
CALL ←GoOffHook

;   ARelay(false);
XOR BX,BX
CALL ←ARelay

;   bootSwitches = GetBootSwitches();
CALL ←GetBootSwitches
MOV ←bootSwitches,BX

;   FirstSendState();
CALL ←FirstSendState

;   StartEL();
CALL ←StartEL

;   for (;;) {
X11:

;     CheckState();  /* keep trying until get an answer */
CALL ←CheckState

;     CheckWDT();
CALL ←CheckWDT

;     CheckEL();
CALL ←CheckEL

;     };
JR X11
X12:

;   };
MOV SP,BP
POP BP
RET;

; static MonInit()
←MonInit:
PUSH BP
MOV BP,SP

;   {

;   InitAnalog();
CALL ←InitAnalog

;   tlHost = 0;  /* broadcast */
MOV ←tlHost,0

;   tlNet = 0;  /* local */
MOV ←tlNet,0

;   tlImHost = 0; /* broadcast */
MOV ←tlImHost,0

;   localNet = 0;  /* local */
MOV ←localNet,0

;   };
MOV SP,BP
POP BP
RET;

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

;   {

;   regp->fl = regp->fl | 0x0100;
MOV BX,←regp
MOV CX,←regp
MOV DI,CX
MOV CX,[DI+26]
PUSH BX
MOV BX,CX
OR BX,0100X
MOV CX,BX
POP BX
MOV [BX+26],CX

;   breakSS = 0;
MOV ←breakSS,0

;   ssCount = 0;
MOV ←ssCount,0

;   PokeWDT();
CALL ←PokeWDT

;   StartM();
CALL ←StartM

;   };
MOV SP,BP
POP BP
RET;

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

;   {

;   regp->fl = regp->fl & 0xfeff;  /* clear single step */
MOV BX,←regp
MOV CX,←regp
MOV DI,CX
MOV CX,[DI+26]
PUSH BX
MOV BX,CX
AND BX,0FEFFX
MOV CX,BX
POP BX
MOV [BX+26],CX

;   breakSS = 0;
MOV ←breakSS,0

;   ssCount = 0;
MOV ←ssCount,0

;   PokeWDT();
CALL ←PokeWDT

;   StartM();
CALL ←StartM

;   };
MOV SP,BP
POP BP
RET;

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

;   {

;   regp->fl = regp->fl | 0x0100;  /* set single step */
MOV BX,←regp
MOV CX,←regp
MOV DI,CX
MOV CX,[DI+26]
PUSH BX
MOV BX,CX
OR BX,0100X
MOV CX,BX
POP BX
MOV [BX+26],CX

;   breakSS = -1;
MOV ←breakSS,0FFFFX

;   ssCount = 0;
MOV ←ssCount,0

;   PokeWDT();
CALL ←PokeWDT

;   StartM();
CALL ←StartM

;   };
MOV SP,BP
POP BP
RET;

; static MonTrace()
←MonTrace:
PUSH BP
MOV BP,SP

;   {

;   if (regp->ip == lastIP) {
MOV BX,←regp
MOV CX,[BX+24]
MOV BX,←lastIP
CMP CX,BX
JNZ X13

;     if (ssCount >= 20) CRestart(SSFAIL);
MOV BX,←ssCount
CMP BX,014X
JL X14
MOV BX,0FFFBX
CALL ←CRestart
X14:

;     ssCount = ssCount + 1;
MOV BX,←ssCount
INC BX
MOV ←ssCount,BX

;     StartM();
CALL ←StartM

;     };
X13:

;   if (breakSS != 0) {  /* proceeding from breakpoint */
MOV BX,←breakSS
OR BX,BX
JZ X15

;     StoreB(0xcc, lastIP);  /* replace breakpoint */
MOV BX,←lastIP
MOV CX,0CCX
CALL ←StoreB

;     regp->fl = regp->fl & 0xfeff; /* clear single step */
MOV BX,←regp
MOV CX,←regp
MOV DI,CX
MOV CX,[DI+26]
PUSH BX
MOV BX,CX
AND BX,0FEFFX
MOV CX,BX
POP BX
MOV [BX+26],CX

;     StartM();  /* continue */
CALL ←StartM

;     };
X15:

;   };
MOV SP,BP
POP BP
RET;

; static MonNMI()
←MonNMI:
PUSH BP
MOV BP,SP

;   {

;   while(!(GetPIO(2) & 1)) CheckWDT();
X16:
MOV BX,2
CALL ←GetPIO
AND BX,1
OR BX,BX
JNZ X17
CALL ←CheckWDT
JR X16
X17:

;   lastNMI = 0;
MOV ←lastNMI,0

;   };
MOV SP,BP
POP BP
RET;

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

;   {

;   KickWDT();
CALL ←KickWDT

;   SetTmr(200, &wdtTimer);
LEA BX,←wdtTimer
MOV CX,0C8X
CALL ←SetTmr

;   };
MOV SP,BP
POP BP
RET;

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

;   {

;   if (TmrExp(&wdtTimer)) PokeWDT();
LEA BX,←wdtTimer
CALL ←TmrExp
OR BX,BX
JZ X18
CALL ←PokeWDT
X18:

;   };
MOV SP,BP
POP BP
RET;

; Externals Declared Here
PUBLIC ←regp
PUBLIC ←ssCount
PUBLIC ←breakSS
PUBLIC ←wdtTimer
PUBLIC ←MonMain
PUBLIC ←PokeWDT
PUBLIC ←CheckWDT
PUBLIC ←SingleStep
PUBLIC ←GoNormal
PUBLIC ←GoFromBreak

C←CODE ENDS

; Number of Bytes of Code = 0225X, (549)