;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)