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

$INCLUDE(8086LIB.D)

$INCLUDE(d8274.DEC)

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

; extern OutByte();

; extern InByte();

; extern Block();

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

;   {

;   };
MOV SP,BP
POP BP
RET;

; nbPutChar(c)
←nbPutChar:

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

;   {

;   while (!SIOFree(0));
X1:
XOR BX,BX
CALL ←SIOFree
OR BX,BX
JNZ X2
JR X1
X2:

;   SIOPutC(0, c);

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

;   };
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 X3
MOV BX,0AX
CALL ←PutChar
X3:

;   };
MOV SP,BP
POP BP
RET;

; PutC(ch, c)
←PutC:

;   int ch;

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

;   {

;   while (!SIOFree(ch)) Block();
X4:

;	BX ← ←ch
MOV BX,[BP-2]
CALL ←SIOFree
OR BX,BX
JNZ X5
CALL ←Block
JR X4
X5:

;   SIOPutC(ch, c);

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

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

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

;   {

;   while (!AvC(ch)) Block();
X6:

;	BX ← ←ch
POP BX
PUSH BX
CALL ←AvC
OR BX,BX
JNZ X7
CALL ←Block
JR X6
X7:

;   return(SIOGetC(ch) & 0177);

;	BX ← ←ch
POP BX
PUSH BX
CALL ←SIOGetC
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

;   {

;   ch = SIOCmdP(ch);

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

;	←ch ← BX
POP DX
PUSH BX

;   return(InByte(ch)&01);

;	BX ← ←ch
POP BX
PUSH BX
CALL ←InByte
AND BX,1
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 X8

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

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

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

;     else WR4(ch, 0x4c);
JR X10
X9:
MOV BX,04CX

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

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

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

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

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

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

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

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

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

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

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

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

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

;     };
X17:

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

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

;     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

;     };
X18:

;   };
MOV SP,BP
POP BP
RET;

; static SIOFree(ch)
←SIOFree:

;   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

;   return(InByte(ch)&04);

;	BX ← ←ch
POP BX
PUSH BX
CALL ←InByte
AND BX,4
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 X19
MOV WORD PTR [BP-2],032X

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

;   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 X21
MOV WORD PTR [BP-2],036X

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

;   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 ←nbPutChar
PUBLIC ←PutChar
PUBLIC ←PutC
PUBLIC ←PutCRChar
PUBLIC ←GetChar
PUBLIC ←GetC
PUBLIC ←AvC
PUBLIC ←Chav
PUBLIC ←Baud

C←CODE ENDS

; Number of Bytes of Code = 02C2X, (706)