home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_36.arc / SIOLIB.INC < prev    next >
Text File  |  1979-12-31  |  8KB  |  310 lines

  1. { KAYPRO 4/83 INTERRUPT DRIVEN SERIAL I/O }
  2. { INTERFACE FOR TURBO PASCAL              }
  3.  
  4. { FRANK A. KURUCZ }
  5. { 2360 PASEO DE LAURA #20 }
  6. { OCEANSIDE CA,  92056 }
  7. { H- (619) 721-8530 }
  8. { W- (619) 433-6406 }
  9.  
  10. { THIS PROGRAM INTERFACES WITH AN ASSEMBLY LANGUAGE PROGRAM }
  11. { SIOINT.ASM, TO  PROVIDE BUFFERED SERIAL I/O }
  12.  
  13. { THE PROGRAMMER HAS 3 PROCEDURES/FUNCTIONS AT HIS DISPOSITION: }
  14.  
  15. { INITSIO - INITIALIZES SIO, SETS UP INTERRUPTS AND FIFOS }
  16. { WRITEBYTE - OUTPUTS A BYTE TO SERIAL OUTPUT }
  17. { READBYTE -  IF ANY DATA PRESENT IN FIFO, IT IS RETURNED }
  18.  
  19. { NOTE ************************************************************* }
  20.  
  21. { WHEN COMPILING THE COM FILE MAKE SURE THAT THE END OF MEMORY }
  22. { PARAMETER IS SET BELOW THE INTERRUPT VECTOR }
  23. { OTHERWISE THE INTERRUPT PROCEDURES ARE AT RISK OF BEING OVERWRITTEN }
  24.  
  25.  
  26.  
  27. {$A+}
  28. Const
  29.  
  30.      { ADDRESSES OF POINTERS, COUNTERS AND BUFFERS USED BY INTERRUPTS }
  31.  
  32.      VectorAddr =         $E000;        { INTERRUPT VECTOR }
  33.  
  34.      InSerialFifoAddr =   $E100;        { SERIAL INPUT FIFO }
  35.      InFifoCountAddr =    $E300;        { FIFO COUNTER }
  36.      InFifoInPtrAddr =    $E301;        { INPUT POINTER }
  37.      InFifoOutPtrAddr =   $E303;        { OUTPUT POINTER }
  38.  
  39.      OutSerialFifoAddr =  $E200;        { SERIAL OUTPUT FIFO }
  40.      OutFifoCountAddr =   $E305;        { FIFO COUNTER }
  41.      OutFifoInPtrAddr =   $E306;        { INPUT POINTER }
  42.      OutFifoOutPtrAddr =  $E308;        { OUTPUT POINTER }
  43.  
  44.      OutIntExpectedAddr = $E30A;        { OUTPUT INTERRUPT ENABLED FLAG }
  45.  
  46.  
  47.      { I/O PORT ADDRESSES }
  48.  
  49.      Control_Port_A =     $06;
  50.      Control_Port_B =     $07;
  51.      Baud_Port =          $00;
  52.      Data_Port_A =        $04;
  53.  
  54.  
  55.  
  56.  
  57. { ######################################################################## }
  58. { ######################################################################## }
  59.  
  60. { INITIALIZE THE SIO }
  61. { PARAMETERS }
  62.  
  63. { BAUD:     0 = 50          8 = 1800     }
  64. {           1 = 75          9 = 2000     }
  65. {           2 = 110        10 = 2400     }
  66. {           3 = 134        11 = 3600     }
  67. {           4 = 150        12 = 4800     }
  68. {           5 = 300        13 = 7200     }
  69. {           6 = 600        14 = 9600     }
  70. {           7 = 1200       15 = 19200    }
  71.  
  72. { DATASIZE: 5 =   5 DATA BITS }
  73. {           6 =   6 DATA BITS }
  74. {           7 =   7 DATA BITS }
  75. {           8 =   8 DATA BITS }
  76.  
  77. { PARITY:   0 =  NO   PARITY  }
  78. {           1 =  ODD  PARITY  }
  79. {           2 =  NO   PARITY  }
  80. {           3 =  EVEN PARITY  }
  81.  
  82. { STOPBITS: 0 =  ILLEGAL VALUE  }
  83. {           1 =  1   STOP BIT   }
  84. {           2 =  1.5 STOP BITS  }
  85. {           3 =  2   STOP BITS  }
  86.  
  87.  
  88. Procedure InitSIO(Baud,DataSize,Parity,StopBits:Integer);
  89.  
  90. Var
  91.    Vector:    Byte;
  92.  
  93.  
  94.     { INITIALIZE THE INPUT AND OUTPUT FIFOS AND COUNTERS AS WELL AS }
  95.     { OUTPUT INTERRUPT EXPECTED FLAG }
  96.  
  97. {1} Procedure InitFifos;
  98.     Var
  99.        InFifoCount:    Byte     Absolute  InFifoCountAddr;
  100.        InFifoInPtr:    Integer  Absolute  InFifoInPtrAddr;
  101.        InFifoOutPtr:   Integer  Absolute  InFifoOutPtrAddr;
  102.  
  103.        OutFifoCount:   Byte     Absolute  OutFifoCountAddr;
  104.        OutFifoInPtr:   Integer  Absolute  OutFifoInPtrAddr;
  105.        OutFifoOutPtr:  Integer  Absolute  OutFifoOutPtrAddr;
  106.  
  107.        OutIntExpected: Byte     Absolute  OutIntExpectedAddr;
  108.  
  109.  
  110.     Begin
  111.          InFifoCount:=     0;
  112.          OutFifoCount:=    0;
  113.  
  114.          InFifoInPtr:=     InSerialFifoAddr;
  115.          InFifoOutPtr:=    InSerialFifoAddr;
  116.  
  117.          OutFifoInPtr:=    OutSerialFifoAddr;
  118.          OutFifoOutPtr:=   OutSerialFifoAddr;
  119.  
  120.          OutIntExpected:=  0;
  121.     End;
  122.  
  123.  
  124. { NOW INITIALIZE THE SIO }
  125.  
  126. Begin
  127.  
  128.     Inline($F3);         { DISABLE INTERRUPTS }
  129.  
  130.     InitFifos;           { SET UP FIFOS }
  131.  
  132.     { SET UP THE INTERRUPT VECTOR REGISTER TO THE MOST SIGNIFICANT }
  133.     { BYTE OF THE INTERRUPT VECTOR ADDDRESS }
  134.     { AND SET UP INTERRUPT MODE 2 }
  135.  
  136.     Vector:=  VectorAddr Div $100;
  137.     Inline($3A/Vector/   { LD   A,(Vector) }
  138.            $ED/$47/      { LD   I,A    }
  139.            $ED/$5E);     { IM   2      }
  140.  
  141.     { RESET THE SIO }
  142.  
  143.     Port[Control_Port_A]:=$18;
  144.  
  145.  
  146.     { PROGRAM THE SIO FOR INTERRUPTS }
  147.  
  148.     Port[Control_Port_B]:= 2;
  149.     Port[Control_Port_B]:= 0;
  150.     Port[Control_Port_B]:= 1;
  151.     Port[Control_Port_B]:= 4;
  152.  
  153.  
  154.     { SET UP THE SERIAL CHARACTERISTICS OF PORT A }
  155.     { CAUTION - PORT B IS USED FOR KEYBOARD DATA ENTRY }
  156.     { SO DON'T MESS WITH IT }
  157.  
  158.     { MAKE SURE STOP BITS HAS A VALID VALUE }
  159.  
  160.     StopBits:=(StopBits Mod 4) Shl 2;
  161.     If (StopBits = 0) Then Stopbits:=4;
  162.  
  163.     { MAKE SURE PARITY HAS A VALID VALUE AND PROGRAM IT }
  164.     { ALONG WITH STOPBITS AND CLOCK MODE = 32X }
  165.  
  166.     Port[Control_Port_A]:=4;
  167.     Port[Control_Port_A]:= $40 Or (Parity Mod 4) Or StopBits;
  168.  
  169.     { PROGRAM RECEIVE DATA BYTE SIZE }
  170.  
  171.     Case (DataSize) Of
  172.          5: DataSize:=   0;
  173.          6: DataSize:=   $40;
  174.          7: DataSize:=   $80;
  175.          8: DataSize:=   $C0;
  176.          Else
  177.             DataSize:=   $C0;
  178.     End;
  179.  
  180.     { AND ENABLE RECEIVE }
  181.  
  182.     Port[Control_Port_A]:=3;
  183.     Port[Control_Port_A]:=DataSize Or 1;
  184.  
  185.  
  186.     { ALSO PROGRAM TRANSMIT DATA SIZE }
  187.     { SETTING DTR AND CTS TO 1 AND ENABLING TRANSMISSION }
  188.  
  189.     Port[Control_Port_A]:=5;
  190.     Port[Control_Port_A]:=$8A Or (DataSize Shr 1);
  191.  
  192.     { ENABLE TRANSMIT AND RECEIVE INTERRUPTS }
  193.  
  194.     Port[Control_Port_A]:=1;
  195.     Port[Control_Port_A]:=$1B;
  196.  
  197.     { SET THE BAUD RATE, MAKING SURE THE PARAMETER IS VALID }
  198.  
  199.     Baud:=Baud Mod 16;
  200.     Port[Baud_Port]:=Baud;
  201.  
  202.     Inline($FB);        { RE-ENABLE INTERRUPTS }
  203. End;
  204.  
  205.  
  206.  
  207.  
  208. { ######################################################################### }
  209. { ######################################################################### }
  210.  
  211. { WRITE A BYTE TO SERIAL OUTPUT }
  212.  
  213. Procedure WriteByte(Data:Byte);
  214.  
  215. Var
  216.    OutFifoCount:      Byte     Absolute   OutFifoCountAddr;
  217.    OutFifoInPtr:      Integer  Absolute   OutFifoInPtrAddr;
  218.    OutFifoInPtrByte:  Byte     Absolute   OutFifoInPtrAddr;
  219.    OutIntExpected:    Byte     Absolute   OutIntExpectedAddr;
  220.  
  221. Begin
  222.      { IF FIFO IS FULL WAIT FOR OUTPUT INTERRUPT TO MAKE ROOM }
  223.  
  224.      While (OutFifoCount = $FF) Do ;
  225.  
  226.      { DISABLE INTERRUPTS }
  227.  
  228.      Inline($F3);
  229.  
  230.      { ARE WE EXPECTING AN OUTPUT INTERRUPT ?}
  231.  
  232.      If (OutIntExpected <> 0) Then
  233.      Begin
  234.           { YES, INSERT DATA IN TO THE OUTPUT FIFO }
  235.  
  236.           { INCREMENT THE FIFO COUNT }
  237.           OutFifoCount:= OutFifoCount + 1;
  238.  
  239.           { SAVE THE DATA IN THE FIFO }
  240.           Mem[OutFifoInptr]:= Data;
  241.  
  242.           { INCREMENT THE FIFO POINTER }
  243.           OutFifoInPtrByte:= OutFifoInPtrByte + 1;
  244.      End
  245.      Else
  246.      Begin
  247.           { OUTPUT INTERRUPTS HAVE BEEN SUSPENDED }
  248.           { OUTPUT DATA AND RE-ENABLE THE INETRRUPT }
  249.  
  250.           Port[Data_Port_A]:= Data;
  251.           OutIntExpected:=$FF;
  252.      End;
  253.  
  254.      { RE-ENABLE INTERRUPTS }
  255.  
  256.      Inline($FB);
  257. End;
  258.  
  259.  
  260. { ######################################################################## }
  261. { ######################################################################## }
  262.  
  263. { RETURNS A BYTE }
  264. { IF THERE IS DATA IN THE SERIAL INPUT FIFO THEN THE FUNCTION }
  265. { RETURNS THE FIRST BYTE IN THE FIFO AND NODATA = FALSE }
  266. { OTHERWISE A GARBAGE BYTE IS RETURNED AND NODATA = TRUE }
  267.  
  268.  
  269. Function ReadByte(Var NoData:Boolean):Byte;
  270. Var
  271.    InFifoCount:       Byte     Absolute  InFifoCountAddr;
  272.    InFifoOutPtr:      Integer  Absolute  InFifoOutPtrAddr;
  273.    InFifoOutPtrByte:  Byte     Absolute  InFifoOutPtrAddr;
  274.  
  275.    Data:              Byte;
  276.  
  277.  
  278.  
  279. Begin
  280.      { DISABLE INTERRUPTS }
  281.      Inline($F3);
  282.  
  283.      { IS THE FIFO EMPTY ? }
  284.      If (InFifoCount <> 0) Then
  285.      Begin
  286.           { THERE IS DATA }
  287.  
  288.           { DECREMENT THE FIFO COUNTER }
  289.           InFifoCount:= InFifoCount - 1;
  290.  
  291.           { GET THE DATA FROM THE FIFO }
  292.           Data:= Mem[InFifoOutPtr];
  293.  
  294.           { INCREMENT THE FIFO POINTER WITH WRAP AROUND }
  295.           InFifoOutPtrByte:= InFifoOutPtrByte+1;
  296.  
  297.           { LOWER NODATA FLAG }
  298.           NoData:=False;
  299.      End
  300.         { IT IS EMPTY, RAISE THE NODATA FLAG }
  301.      Else NoData:=True;
  302.  
  303.      { RE-ENABLE INTERRUPTS }
  304.      Inline($FB);
  305.  
  306.      { RETURN THE BYTE }
  307.      ReadByte:=Data;
  308. End;
  309.  
  310.