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

$INCLUDE(8086LIB.D)

$INCLUDE(DI8274.DEC)

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

; #include	"ec.h"

; extern Block();

; extern EnableInt();

; extern CallDebugger();

; extern InitRingBuffer();

; extern WriteRingBuffer();

; extern RingBufferEmpty();

; extern ReadRingBuffer();

; extern OutByte();

; extern InByte();

; extern /* FORWARD */ mySIOInt();

; static struct CBuf rb[2];

; static struct CBuf tb[2];

; static int busy[2];

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

;   {

;   FlushInput(0);
XOR BX,BX
CALL ←FlushInput

;   FlushInput(1);
MOV BX,1
CALL ←FlushInput

;   InitRingBuffer(&tb[0], tb[0].abuf, CBS-2);
LEA BX,←tb
PUSH BX
MOV BX,03EX
LEA CX,←tb+8
CALL ←InitRingBuffer
POP DX

;   InitRingBuffer(&tb[1], tb[1].abuf, CBS-2);
LEA BX,←tb+048X
PUSH BX
MOV BX,03EX
LEA CX,←tb+050X
CALL ←InitRingBuffer
POP DX

;   busy[0] = busy[1] = false;
MOV ←busy+2,0
MOV ←busy,0

;   Baud(1200, 0);
XOR BX,BX
MOV CX,04B0X
CALL ←Baud

;   Baud(1200, 1);
MOV BX,1
MOV CX,04B0X
CALL ←Baud

;   EnableInt(&mySIOInt, SIOTyp);
MOV BX,3
MOV CX,OFFSET ←mySIOInt
CALL ←EnableInt

;   };
MOV SP,BP
POP BP
RET;

; FlushInput(ch)
←FlushInput:

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

;   {

;   if (ch) InitRingBuffer(&rb[1], rb[1].abuf, CBS-2);

;	BX ← ←ch
POP BX
PUSH BX
OR BX,BX
JZ X1
LEA BX,←rb+048X
PUSH BX
MOV BX,03EX
LEA CX,←rb+050X
CALL ←InitRingBuffer
POP DX

;   else InitRingBuffer(&rb[0], rb[0].abuf, CBS-2);
JR X2
X1:
LEA BX,←rb
PUSH BX
MOV BX,03EX
LEA CX,←rb+8
CALL ←InitRingBuffer
POP DX
X2:

;   };
MOV SP,BP
POP BP
RET;

; nbPutChar(c)
←nbPutChar:

;   char c;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   struct CBuf *p;
PUSH DX

;   p = &tb[0];
LEA BX,←tb

;	←p ← BX
POP DX
PUSH BX

;   while (!WriteRingBuffer(p, c));
X3:

;	AX ← ←c
MOV AX,[BP-2]
CBW
MOV BX,AX

;	CX ← ←p
POP CX
PUSH CX
CALL ←WriteRingBuffer
OR BX,BX
JNZ X4
JR X3
X4:

;   if (!busy[0] && !RingBufferEmpty(p)) {
MOV BX,←busy
OR BX,BX
JNZ X6

;	BX ← ←p
POP BX
PUSH BX
CALL ←RingBufferEmpty
OR BX,BX
X6:
JNZ X5

;     busy[0] = 1;
MOV ←busy,1

;     SIOPutC(0, ReadRingBuffer(p));

;	BX ← ←p
POP BX
PUSH BX
CALL ←ReadRingBuffer
XOR CX,CX
CALL ←SIOPutC

;     };
X5:

;   };
MOV SP,BP
POP BP
RET;

; PutChar(c)
←PutChar:

;   char c;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   PutC(0, c);

;	AX ← ←c
POP AX
PUSH AX
CBW
MOV BX,AX
XOR CX,CX
CALL ←PutC

;   };
MOV SP,BP
POP BP
RET;

; PutCRChar(c)
←PutCRChar:

;   char c;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   PutChar(c);

;	AX ← ←c
POP AX
PUSH AX
CBW
MOV BX,AX
CALL ←PutChar

;   if (c=='\r') PutChar('\n');

;	AL ← ←c
POP AX
PUSH AX
CMP AL,0DX
JNZ X7
MOV BX,0AX
CALL ←PutChar
X7:

;   };
MOV SP,BP
POP BP
RET;

; PutC(ch, c)
←PutC:

;   int ch;

;   char c;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   struct CBuf *p;
PUSH DX

;   p = &tb[ch];

;	BX ← ←ch
MOV BX,[BP-2]
LEA CX,←tb
MOV AX,048X
IMUL AX,BX
ADD AX,CX

;	←p ← AX
POP DX
PUSH AX

;   while (!WriteRingBuffer(p, c)) Block();
X8:

;	AX ← ←c
MOV AX,[BP-4]
CBW
MOV BX,AX

;	CX ← ←p
POP CX
PUSH CX
CALL ←WriteRingBuffer
OR BX,BX
JNZ X9
CALL ←Block
JR X8
X9:

;   if (!busy[ch] && !RingBufferEmpty(p)) {

;	BX ← ←ch
MOV BX,[BP-2]
LEA CX,←busy
SAL BX
ADD BX,CX
MOV CX,[BX]
OR CX,CX
JNZ X11

;	BX ← ←p
POP BX
PUSH BX
CALL ←RingBufferEmpty
OR BX,BX
X11:
JNZ X10

;     busy[ch] = 1;

;	BX ← ←ch
MOV BX,[BP-2]
LEA CX,←busy
SAL BX
ADD BX,CX
MOV WORD PTR [BX],1

;     SIOPutC(ch, ReadRingBuffer(p));

;	BX ← ←p
POP BX
PUSH BX
CALL ←ReadRingBuffer

;	CX ← ←ch
MOV CX,[BP-2]
CALL ←SIOPutC

;     };
X10:

;   };
MOV SP,BP
POP BP
RET;

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

;   {

;   return(GetC(0));
XOR BX,BX
CALL ←GetC
MOV SP,BP
POP BP
RET;

;   };

; int GetC(ch)
←GetC:

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

;   {

;   struct CBuf *p;
PUSH DX

;   p = &rb[ch];

;	BX ← ←ch
MOV BX,[BP-2]
LEA CX,←rb
MOV AX,048X
IMUL AX,BX
ADD AX,CX

;	←p ← AX
POP DX
PUSH AX

;   while (RingBufferEmpty(p)) Block();
X12:

;	BX ← ←p
POP BX
PUSH BX
CALL ←RingBufferEmpty
OR BX,BX
JZ X13
CALL ←Block
JR X12
X13:

;   return(ReadRingBuffer(p) & 0177);

;	BX ← ←p
POP BX
PUSH BX
CALL ←ReadRingBuffer
AND BX,07FX
MOV SP,BP
POP BP
RET;

;   };

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

;   {

;   return(AvC(0));
XOR BX,BX
CALL ←AvC
MOV SP,BP
POP BP
RET;

;   };

; int AvC(ch)
←AvC:

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

;   {

;   return(!RingBufferEmpty(&rb[ch]));

;	BX ← ←ch
POP BX
PUSH BX
LEA CX,←rb
MOV AX,048X
IMUL AX,BX
ADD AX,CX
MOV BX,AX
CALL ←RingBufferEmpty
OR BX,BX
JNZ X14
MOV BX,1
JR X15
X14:
XOR BX,BX
X15:
MOV SP,BP
POP BP
RET;

;   };

; Baud(mbr, ch)
←Baud:

;   int mbr, ch;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   int dr, load, hold;

;   if (ch == 0) {  /* use 9513 channel 0 (FOUT) */
ADD SP,0FFFAX

;	BX ← ←ch
MOV BX,[BP-4]
OR BX,BX
JNZ X16

;     if (mbr == 300) { MM(0x0ac0); WR4(ch, 0x008c); };

;	BX ← ←mbr
MOV BX,[BP-2]
CMP BX,012CX
JNZ X17
MOV BX,0AC0X
CALL ←MM
MOV BX,08CX

;	CX ← ←ch
MOV CX,[BP-4]
CALL ←WR4

;     else WR4(ch, 0x4c);
JR X18
X17:
MOV BX,04CX

;	CX ← ←ch
MOV CX,[BP-4]
CALL ←WR4
X18:

;     if (mbr==600) MM(0x0ac0);

;	BX ← ←mbr
MOV BX,[BP-2]
CMP BX,0258X
JNZ X19
MOV BX,0AC0X
CALL ←MM
X19:

;     if (mbr==1200) MM(0x088c0);

;	BX ← ←mbr
MOV BX,[BP-2]
CMP BX,04B0X
JNZ X20
MOV BX,088C0X
CALL ←MM
X20:

;     if (mbr==2400) MM(0x084c0);

;	BX ← ←mbr
MOV BX,[BP-2]
CMP BX,0960X
JNZ X21
MOV BX,084C0X
CALL ←MM
X21:

;     if (mbr==4800) MM(0x082c0);

;	BX ← ←mbr
MOV BX,[BP-2]
CMP BX,012C0X
JNZ X22
MOV BX,082C0X
CALL ←MM
X22:

;     if (mbr==9600) MM(0x08a00);

;	BX ← ←mbr
MOV BX,[BP-2]
CMP BX,02580X
JNZ X23
MOV BX,08A00X
CALL ←MM
X23:

;     if (mbr==19200) MM(0x08500);

;	BX ← ←mbr
JR $+5
X16:
JMP X25
MOV BX,[BP-2]
CMP BX,04B00X
JNZ X24
MOV BX,08500X
CALL ←MM
X24:

;     };
X25:

;   if (ch==1) {  /* use 9513 channel 4 */

;	BX ← ←ch
MOV BX,[BP-4]
CMP BX,1
JNZ X26

;     WR4(ch, 0x4c);  /* always use /16 mode */
MOV BX,04CX

;	CX ← ←ch
MOV CX,[BP-4]
CALL ←WR4

;     mbr = mbr/100;

;	AX ← ←mbr
MOV AX,[BP-2]
MOV BX,064X
CWD
IDIV AX,BX

;	←mbr ← AX
MOV [BP-2],AX

;     dr = 960/mbr;  /* 960 = 15360/16 (16 for 8274 division ratio)  */
MOV AX,03C0X

;	BX ← ←mbr
MOV BX,[BP-2]
CWD
IDIV AX,BX

;	←dr ← AX
MOV [BP-6],AX

;     hold = dr/2;

;	BX ← ←dr
MOV BX,[BP-6]
SAR BX

;	←hold ← BX
POP DX
PUSH BX

;     load = dr-hold;

;	BX ← ←hold
POP BX
PUSH BX

;	CX ← ←dr
MOV CX,[BP-6]
SUB CX,BX

;	←load ← CX
MOV [BP-8],CX

;     OutByte(TimCtl, 0xc8);  /* disarm ch 4 */
MOV BX,0C8X
MOV CX,060X
CALL ←OutByte

;     OutByte(TimCtl, 0x04);  /* set data pointer for ch 4 */
MOV BX,4
MOV CX,060X
CALL ←OutByte

;     OutWord(TimData, 0x1b62);  /* Mode J, src F1, toggle, count up, binary */
MOV BX,01B62X
MOV CX,062X
CALL ←OutWord

;     OutWord(TimData, load);

;	BX ← ←load
MOV BX,[BP-8]
MOV CX,062X
CALL ←OutWord

;     OutWord(TimData, hold);

;	BX ← ←hold
POP BX
PUSH BX
MOV CX,062X
CALL ←OutWord

;     OutByte(TimCtl, 0x48);  /* load ch 4 */
MOV BX,048X
MOV CX,060X
CALL ←OutByte

;     OutByte(TimCtl, 0x28);  /* arm ch 4 */
MOV BX,028X
MOV CX,060X
CALL ←OutByte

;     };
X26:

;   };
MOV SP,BP
POP BP
RET;

; static int iretCode;

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

;   {

;   int type;
PUSH DX

;   type = RR2(1) & 07;
MOV BX,1
CALL ←RR2
AND BX,7

;	←type ← BX
POP DX
PUSH BX

;   switch (type) {

;	BX ← ←type
POP BX
PUSH BX
JR X27

;     case 0: txe(1); break;
X29:
MOV BX,1
CALL ←txe
JR X28

;     case 1: CallD(ecInt+2); break;
X30:
MOV BX,06002X
CALL ←CallD
JR X28

;     case 2: rxa(1); break;
X31:
MOV BX,1
CALL ←rxa
JR X28

;     case 3: sprx(1); break;
X32:
MOV BX,1
CALL ←sprx
JR X28

;     case 4: txe(0); break;
X33:
XOR BX,BX
CALL ←txe
JR X28

;     case 5: CallD(ecInt+3); break;
X34:
MOV BX,06003X
CALL ←CallD
JR X28

;     case 6: rxa(0); break;
X35:
XOR BX,BX
CALL ←rxa
JR X28

;     case 7: sprx(0); break;
X36:
XOR BX,BX
CALL ←sprx
JR X28

;     default: CallD(ecInt+1);
X37:
MOV BX,06001X
CALL ←CallD

;     };
JR X28
X27:
MOV AL,BH
OR AL,AL
JNZ X37
MOV AL,BL
CMP AL,0
JZ X29
CMP AL,1
JZ X30
CMP AL,2
JZ X31
CMP AL,3
JZ X32
CMP AL,4
JZ X33
CMP AL,5
JZ X34
CMP AL,6
JZ X35
CMP AL,7
JZ X36
JR X37
X28:

;   if (iretCode) WR0(0, 0x38);  /* eoi */
MOV BX,←iretCode
OR BX,BX
JZ X38
MOV BX,038X
XOR CX,CX
CALL ←WR0
X38:

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

;   };

; CallD(n)
←CallD:

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

;   {

;   WR0(0, 0x38);  /* eoi */
MOV BX,038X
XOR CX,CX
CALL ←WR0

;   DoEOI();
CALL ←DoEOI

;   iretCode = false;
MOV ←iretCode,0

;   CallDebugger(n);

;	BX ← ←n
POP BX
PUSH BX
CALL ←CallDebugger

;   };
MOV SP,BP
POP BP
RET;

; static rxa(ch)
←rxa:

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

;   {

;   char c;
PUSH DX

;   iretCode = true;
MOV ←iretCode,0FFFFX

;   c = SIOGetC(ch);

;	BX ← ←ch
MOV BX,[BP-2]
CALL ←SIOGetC

;	←c ← BL
POP DX
PUSH BX

;   if (c == 0) CallD(0);

;	AL ← ←c
POP AX
PUSH AX
OR AL,AL
JNZ X39
XOR BX,BX
CALL ←CallD

;   else WriteRingBuffer(&rb[ch], c);
JR X40
X39:

;	BX ← ←ch
MOV BX,[BP-2]
LEA CX,←rb
MOV AX,048X
IMUL AX,BX
ADD AX,CX

;	BX ← ←c
POP BX
PUSH BX
PUSH AX
MOV AL,BL
CBW
MOV BX,AX
POP AX
MOV CX,AX
CALL ←WriteRingBuffer
X40:

;   };
MOV SP,BP
POP BP
RET;

; static txe(ch)
←txe:

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

;   {

;   struct CBuf *p;
PUSH DX

;   iretCode = true;
MOV ←iretCode,0FFFFX

;   p = &tb[ch];

;	BX ← ←ch
MOV BX,[BP-2]
LEA CX,←tb
MOV AX,048X
IMUL AX,BX
ADD AX,CX

;	←p ← AX
POP DX
PUSH AX

;   if (RingBufferEmpty(p)) {

;	BX ← ←p
POP BX
PUSH BX
CALL ←RingBufferEmpty
OR BX,BX
JZ X41

;     WR0(ch, 0x28);
MOV BX,028X

;	CX ← ←ch
MOV CX,[BP-2]
CALL ←WR0

;     busy[ch] = 0;

;	BX ← ←ch
MOV BX,[BP-2]
LEA CX,←busy
SAL BX
ADD BX,CX
MOV WORD PTR [BX],0

;     };

;   else SIOPutC(ch, ReadRingBuffer(p));
JR X42
X41:

;	BX ← ←p
POP BX
PUSH BX
CALL ←ReadRingBuffer

;	CX ← ←ch
MOV CX,[BP-2]
CALL ←SIOPutC
X42:

;   };
MOV SP,BP
POP BP
RET;

; static sprx(ch)
←sprx:

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

;   {

;   iretCode = true;
MOV ←iretCode,0FFFFX

;   WR0(ch, 0xf0);	/* forget it */
MOV BX,0F0X

;	CX ← ←ch
POP CX
PUSH CX
CALL ←WR0

;   };
MOV SP,BP
POP BP
RET;

; static WR0(ch, rv)
←WR0:

;   int ch, rv;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   ch = SIOCmdP(ch);

;	BX ← ←ch
MOV BX,[BP-2]
CALL ←SIOCmdP

;	←ch ← BX
MOV [BP-2],BX

;   OutByte(ch, rv&0xff);

;	BX ← ←rv
POP BX
PUSH BX
AND BX,0FFX

;	CX ← ←ch
MOV CX,[BP-2]
CALL ←OutByte

;   };
MOV SP,BP
POP BP
RET;

; static int RR2(ch)
←RR2:

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

;   {

;   ch = SIOCmdP(ch);

;	BX ← ←ch
POP BX
PUSH BX
CALL ←SIOCmdP

;	←ch ← BX
POP DX
PUSH BX

;   OutByte(ch, 2);
MOV BX,2

;	CX ← ←ch
POP CX
PUSH CX
CALL ←OutByte

;   return(InByte(ch) & 0xff);

;	BX ← ←ch
POP BX
PUSH BX
CALL ←InByte
AND BX,0FFX
MOV SP,BP
POP BP
RET;

;   };

; static SIOGetC(ch)
←SIOGetC:

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

;   {

;   ch = SIODataP(ch);

;	BX ← ←ch
POP BX
PUSH BX
CALL ←SIODataP

;	←ch ← BX
POP DX
PUSH BX

;   return(InByte(ch)&0177);

;	BX ← ←ch
POP BX
PUSH BX
CALL ←InByte
AND BX,07FX
MOV SP,BP
POP BP
RET;

;   };

; static SIOPutC(ch, v)
←SIOPutC:

;   int ch;

;   char v;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   ch = SIODataP(ch);

;	BX ← ←ch
MOV BX,[BP-2]
CALL ←SIODataP

;	←ch ← BX
MOV [BP-2],BX

;   OutByte(ch, v);

;	AX ← ←v
POP AX
PUSH AX
CBW
MOV BX,AX

;	CX ← ←ch
MOV CX,[BP-2]
CALL ←OutByte

;   };
MOV SP,BP
POP BP
RET;

; static SIOCmdP(ch)
←SIOCmdP:

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

;   {

;   if (ch==0) ch = sioctla;

;	BX ← ←ch
POP BX
PUSH BX
OR BX,BX
JNZ X43
MOV WORD PTR [BP-2],032X

;   else ch = sioctlb;
JR X44
X43:
MOV WORD PTR [BP-2],030X
X44:

;   return(ch);

;	BX ← ←ch
POP BX
PUSH BX
MOV SP,BP
POP BP
RET;

;   };

; static SIODataP(ch)
←SIODataP:

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

;   {

;   if (ch==0) ch = siodata;

;	BX ← ←ch
POP BX
PUSH BX
OR BX,BX
JNZ X45
MOV WORD PTR [BP-2],036X

;   else ch = siodatb;
JR X46
X45:
MOV WORD PTR [BP-2],034X
X46:

;   return(ch);

;	BX ← ←ch
POP BX
PUSH BX
MOV SP,BP
POP BP
RET;

;   };

; static MM(rv)
←MM:

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

;   {

;   OutByte(TimCtl, 0x17);
MOV BX,017X
MOV CX,060X
CALL ←OutByte

;   OutWord(TimData, rv);

;	BX ← ←rv
POP BX
PUSH BX
MOV CX,062X
CALL ←OutWord

;   };
MOV SP,BP
POP BP
RET;

; static WR4(ch, rv)
←WR4:

;   int ch, rv;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   ch = SIOCmdP(ch);

;	BX ← ←ch
MOV BX,[BP-2]
CALL ←SIOCmdP

;	←ch ← BX
MOV [BP-2],BX

;   OutByte(ch, 0x04);
MOV BX,4

;	CX ← ←ch
MOV CX,[BP-2]
CALL ←OutByte

;   OutByte(ch, rv&0xff);

;	BX ← ←rv
POP BX
PUSH BX
AND BX,0FFX

;	CX ← ←ch
MOV CX,[BP-2]
CALL ←OutByte

;   };
MOV SP,BP
POP BP
RET;

; static OutWord(port, val)
←OutWord:

;   int port, val;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   OutByte(port, val&0xff);

;	BX ← ←val
POP BX
PUSH BX
AND BX,0FFX

;	CX ← ←port
MOV CX,[BP-2]
CALL ←OutByte

;   OutByte(port, (val >> 8)&0xff);
MOV CX,8

;	BX ← ←val
POP BX
PUSH BX
SHR BX,CX
AND BX,0FFX

;	CX ← ←port
MOV CX,[BP-2]
CALL ←OutByte

;   };
MOV SP,BP
POP BP
RET;

; Externals Declared Here
PUBLIC ←Init8274
PUBLIC ←FlushInput
PUBLIC ←Baud
PUBLIC ←nbPutChar
PUBLIC ←PutChar
PUBLIC ←PutC
PUBLIC ←PutCRChar
PUBLIC ←GetChar
PUBLIC ←GetC
PUBLIC ←Chav
PUBLIC ←AvC
PUBLIC ←CallD

C←CODE ENDS

; Number of Bytes of Code = 053BX, (1339)