This commit is contained in:
Thaddeus-Maximus
2026-04-03 15:58:58 -05:00
commit f3953d66ae
1516 changed files with 586639 additions and 0 deletions

340
5i24/utils/dos/source/M32UART.PAS Executable file
View File

@@ -0,0 +1,340 @@
{ mesa fpga UART 32 BIT }
{I HM2LOW}
const
MesaUARTBaseAdd = $6000;
{ registers }
MesaUARTRxTxStride = $10;
MesaUARTRegStride = $04;
MesaUARTTxData1 = $00; { 1 byte push }
MesaUARTTxData2 = $04; { 2 byte push }
MesaUARTTxData3 = $08; { 3 byte push }
MesaUARTTxData4 = $0C; { 4 byte push }
MesaUARTRxData1 = $400; { 1 byte pop }
MesaUARTRxData2 = $404; { 2 byte pop }
MesaUARTRxData3 = $408; { 3 byte pop }
MesaUARTRxData4 = $40C; { 4 byte pop }
MesaUARTTxFIFOCount = $100;
MesaUARTTxMode = $300;
MesaUARTRxFIFOCount = $500;
MesaUARTRxMode = $700;
{ setup mode register map }
MesaUARTTxBitRate = $200;
MesaUARTRxBitRate = $600;
MesaUARTBitRateMask= $FFFFF; { 20 bits }
MesaUARTRxFIFOSize = 16; { bytes }
MesaUARTTxFIFOSize = 16; { slots }
MesaUARTNumUARTs = 8;
MesaUARTFIFOMask = $1F;
{ bits }
MesaUARTTxFIFOError = $0010; { fifo push overflow }
MesaUARTTxDriveEnableAuto = $0020;
MesaUARTDriveEnableBit = $0040;
MesaUARTRxFalseStartBit = $0001;
MesaUARTRxOverRun = $0002;
MesaUARTRxMaskEnableBit = $0004;
MesaUARTRxFIFOError = $0010; { read more than there }
MesaUARTRxLostData = $0020;
MesaUARTRxMask = $0040;
MesaUARTRxFIFOHasData = $0080;
var
MesaUARTClock : longint;
function BrAccumval(br,bm : real) : longint;
var baud : real;
begin
baud := ((br*1048576.0)/MesaUARTClock)/bm;
{writeln('MesaUARTClock ',MesaUARTClock);
writeln('Braccum ',baud:10:3);}
BrAccumval := trunc(baud);
end;
function RxCharsAvailable : integer;
var ouraddress : word;
begin
ouraddress :=TheComport*MesaUartRegStride+MesaUARTBaseAdd+MesaUARTRxFIFOCount;
RxCharsAvailable := Read32(ouraddress) and MesaUARTFIFOMask;
end;
function TxSlotsAvailable : integer;
var ouraddress : word;
begin
ouraddress := TheComport*MesaUartRegStride+MesaUARTBaseAdd+MesaUARTTxFIFOCount;
TxSlotsAvailable := MesaUARTTxFIFOSize - (Read32(ouraddress) and MesaUARTFIFOMask);
end;
procedure MesaSerTossChars(comport : word);
begin
Write32(comport*MesaUartRegStride+MesaUARTBaseAdd+MesaUARTRxFifoCount,0);
end;
procedure MesaUARTSetBitrate(comPort : word; bitrate : longint);
begin
Write32((comport*MesaUartRegStride)+MesaUARTBaseAdd+MesaUARTTxBitRate,bitrate);
Write32((comport*MesaUartRegStride)+MesaUARTBaseAdd+MesaUARTRxBitRate,bitrate);
end;
procedure MesaUARTGetBitrate(comport : word; var bitrate : longint);
begin
bitrate := MesaUartBitrateMask and Read32((comport*MesaUartRegStride)+MesaUARTBaseAdd+MesaUARTTxBitRate);
end;
procedure MesaUARTSetBaud(comport : word;br,bm : real);
begin
MesaUARTSetBitrate(comport,BrAccumval(br,bm));
end;
function MesaBaudRateValid(br,bm : real) : boolean;
var ourbaud,testbaud,ratio : real;
value : real;
begin
MesaBaudRateValid := true;
ourbaud := br / bm;
value := BrAccumval(br,bm);
testbaud := MesaUARTClock * value / 65536.0;
ratio := ourbaud / testbaud;
if (ratio > 1.0) and (ratio > 1.03) then MesaBaudRateValid := false;
if (ratio < 1.0) and (ratio < 0.97) then MesaBaudRateValid := false;
end;
function MesaSerRecvChar(var c : char) : boolean;
var timeout : longint;
ouraddress : word;
begin
timeout := CharTimeout;
while ((RxCharsAvailable = 0) and (timeout<>0)) do timeout:=timeout-1;
if timeout <> 0 then
begin
ouraddress := TheComport*MesaUartRxTxStride+MesaUARTBaseAdd+MesaUARTRxData1;
c := char(Read32(ouraddress));
MesaSerRecvChar := true;
end
else MesaSerRecvChar := false;
end;
function MesaSerRecvString(n : integer;var s : string) : boolean;
var
count : integer;
is : string;
timeout : longint;
begin
timeout := CharTimeout;
MesaSerRecvString := false;
is := '';
while ((RxCharsAvailable < n) and (timeout<>0)) do timeout:=timeout-1;
if timeout <> 0 then
begin
for count := 1 to n do
begin
is := is + char(Read32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTRxData1));
end;
MesaSerRecvString := true;
end
else for count := 1 to n do is := is + 'E';
s := is;
end;
procedure MesaSerSendChar(c : char);
begin
while MesaUARTTxFIFOSize = Read32((TheComport*MesaUartRegStride)+MesaUARTBaseAdd+MesaUARTTxFIFOCount) do;
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData1,word(byte(c)));
end;
procedure MesaSnailSerSendChar(c : char);
begin
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData1,word(byte(c)));
end;
procedure MesaSnailSendString(s : string);
var index : byte;
begin
DisableInterrupts;
for index := 1 to length(s) do
begin
MesaSnailSerSendChar(s[index]);
end;
EnableInterrupts;
end;
procedure FastMesaSendString(s : string);
var len,index,lindex : integer;
data : longint;
longs,remains,rem : integer;
begin
DisableInterrupts;
len := length(s);
longs := len div 4;
remains := len mod 4;
index := 1;
if remains <> 0 then rem := 1 else rem := 0;
while TxSlotsAvailable < longs+rem do;
for lindex := 1 to longs do
begin
LongIntByteRec(data).Byte0 := byte(s[index+0]);
LongIntByteRec(data).Byte1 := byte(s[index+1]);
LongIntByteRec(data).Byte2 := byte(s[index+2]);
LongIntByteRec(data).Byte3 := byte(s[index+3]);
index := index + 4;
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData4,data);
end;
case remains of
3 :
begin
LongIntByteRec(data).Byte0 := byte(s[index+0]);
LongIntByteRec(data).Byte1 := byte(s[index+1]);
LongIntByteRec(data).Byte2 := byte(s[index+2]);
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData3,data);
end;
2 :
begin
LongIntByteRec(data).Byte0 := byte(s[index+0]);
LongIntByteRec(data).Byte1 := byte(s[index+1]);
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData2,data);
end;
1 :
begin
LongIntByteRec(data).Byte0 := byte(s[index+0]);
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData1,data);
end;
end;
EnableInterrupts;
end;
procedure SlowMesaSendString(s : string);
var len,index,lindex : integer;
data : longint;
longs,remains : integer;
begin
DisableInterrupts;
len := length(s);
longs := len div 4;
remains := len mod 4;
index := 1;
for lindex := 1 to longs do
begin
while TxSlotsAvailable = 0 do;
LongIntByteRec(data).Byte0 := byte(s[index+0]);
LongIntByteRec(data).Byte1 := byte(s[index+1]);
LongIntByteRec(data).Byte2 := byte(s[index+2]);
LongIntByteRec(data).Byte3 := byte(s[index+3]);
index := index + 4;
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData4,data);
end;
while TxSlotsAvailable = 0 do;
case remains of
3 :
begin
LongIntByteRec(data).Byte0 := byte(s[index+0]);
LongIntByteRec(data).Byte1 := byte(s[index+1]);
LongIntByteRec(data).Byte2 := byte(s[index+2]);
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData3,data);
end;
2 :
begin
LongIntByteRec(data).Byte0 := byte(s[index+0]);
LongIntByteRec(data).Byte1 := byte(s[index+1]);
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData2,data);
end;
1 :
begin
LongIntByteRec(data).Byte0 := byte(s[index+0]);
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData1,data);
end;
end;
EnableInterrupts;
end;
procedure MesaSendString(s : string);
begin
if length(s) > 64 then SlowMesaSendString(s) else FastMesaSendString(s);
end;
procedure oldMesaSendString(s : string);
var len,i : integer;
slots : word;
data : word;
begin
DisableInterrupts;
len := length(s);
i := 1;
while i < (len+1) do
begin
slots := TXSlotsAvailable;
while (slots <> 0) and (i < (len+1)) do
begin
if len-i > 0 then
begin
WordRec(data).LowByte := byte(s[i]);
i := i + 1;
WordRec(data).HighByte := byte(s[i]);
i := i + 1;
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData2,word(data));
slots := slots-1;
end
else
begin
WordRec(data).LowByte := byte(s[i]);
i := i + 1;
Write32((TheComport*MesaUartRxTxStride)+MesaUARTBaseAdd+MesaUARTTxData1,data);
slots := slots-1;
end;
end;
end;
EnableInterrupts;
end;
function MesaComportThere(comport : word) : boolean;
var data : longint;
ok : boolean;
index : word;
begin
ok := false;
FillHM2Array;
MesaUARTClock := Read32(HostMotClockLowOffset);
ZeroMasks;
MakeOutputMasks(UARTTXTag,comport);
for index := 0 to MaxConns -1 do
begin
if OutputMasks[index] <> 0 then
begin
Write32($1100+index*4,OutputMasks[index]); { ddr }
Write32($1200+index*4,OutputMasks[index]); { altsource }
ok := true
end;
end;
MesaComPortThere := ok;
{ check for uart present }
end;
procedure MesaSerOpen(TheComport : word; br,bm : real);
begin
Write32((TheComport*MesaUartRegStride)+MesaUARTBaseAdd+MesaUARTTxMode,MesaUARTDriveEnableBit + $0); { no delay }
Write32((TheComport*MesaUartRegStride)+MesaUARTBaseAdd+MesaUARTTxFIFOCount,0); { clear Tx FIFO}
MesaSerTossChars(TheComport); { make real sure there are no pending chars }
MesaUARTSetBaud(TheComport,br,bm);
Write32((TheComport*MesaUartRegStride)+MesaUARTBaseAdd+MesaUARTRxMode,$0000); { full duplex }
end;
function MesaCanRead(ms : integer) : boolean;
var ctimeout : longint;
begin
if ms <> 0 then
begin
ctimeout := LoopsPermS * longint(ms);
while ((RxCharsAvailable = 0) and (ctimeout <> 0)) do ctimeout := ctimeout -1;
if ctimeout <> 0 then MesaCanRead := true else MesaCanRead := false;
end
else if (RxCharsAvailable <> 0) then MesaCanRead := true else MesaCanRead := false
end;