3

I've FreeDos OS installed on VirtualBox on a windows xp, dual core, host machine. I installed FreeDos because I wanted to run a Pascal code using Turbo Pascal. When I run the code, it throws error 'Error 200: Division by zero.'. How can I solve this?

-Turbo Pascal 7.0, Free DOS 1.1, Virtual Box 4.3.6, Windows XP Service Pack 3 Host machine -This error is unfortunately caused by fast Pentium CPUs and I found a patch on the internet that will resolve the error. (www.filewatcher.com/m/bp7patch.zip.62550-0.html) Now the other problem is, when i was tracing the code, it hangs at 'RxWait procedure when trying to execute while not odd(port[RXTX + 5]) do;'

uses crt;

const
{ COM1: RS232 port address }
RXTX = $3F8; { $2F8 if COM2: is used }
ACK = 6;
NAK = 21;
ESC = 27;

var
dummy,
checkSum : integer;
key : char;
protocol : integer;

procedure InitComm;
{ Set baudrate to 9600, 8 bits, no parity, 1 stop bit }
var i : integer;
begin
i := 1843200 div 9600 div 16;
port[RXTX + 3] := $80;
port[RXTX + 1] := hi(i);
port[RXTX]:= lo(i);
port[RXTX + 3] := 3;
port[RXTX + 4] := $A;
while odd(port[RXTX + 5]) do
begin
dummy := port[RXTX];
delay(10);
end;
end; { InitComm }

procedure Tx(data : integer);
{ Transmit a character on serial channel }
begin
while port[RXTX + 5] and $20 = 0 do;
port[RXTX] := data and $FF;
end; { Tx }

function RxWait : integer;
{ Waits for a character from serial channel }
begin
while not odd(port[RXTX + 5]) do;
RxWait := port[RXTX];
end; { RxWait }

procedure Tx2(data : integer);
{ Transmit a char on serial channel + Calculate check sum }
begin
Tx(data);
checkSum := (checkSum + data) and $FF;
end; { Tx2 }

procedure TxCommand(c1, c2 : char;
sendCheckSum : boolean);
{ Transmit command (no data) on serial channel }
begin
Tx(ESC);
checkSum := 0;
Tx2(ord(c1));
Tx2(ord(c2));
if sendCheckSum then
begin
Tx2(checkSum);
dummy := RxWait;
end;
end; { TxCommand }

function ReadNumber(n : integer) : real;
{ Read n bytes from serial channel }
var
number: real;
i : integer;
begin
number := 0;
checkSum := 0;
for i := 1 to n do
number := number * 256 + RxWait;
dummy := RxWait;
ReadNumber := number;
end; { ReadNumber }

procedure Revisions;
var
tmp : integer;
sw,
prot : real;
begin
TxCommand('P', 'R', FALSE);
checkSum := 0;
tmp := RxWait;
sw := tmp + RxWait / 100.0;
protocol := RxWait;
prot := protocol + RxWait / 100.0;
dummy := RxWait;
tmp := RxWait;
writeln('Software revision: ', sw:4:2);
writeln('Protocol revision: ', prot:4:2);
end; { Revisions }

procedure ReadCountReg;
begin
TxCommand('R', 'C', FALSE);
writeln(ReadNumber(4):11:0, ' coins counted.');
dummy := RxWait;
end; { ReadCountReg }

procedure ReadAccReg;
begin
TxCommand('R', 'A', FALSE);
writeln(ReadNumber(4):11:0, ' coins in accumulator.');
dummy := RxWait;
end; { ReadAccReg }

procedure Setbatch(limit : longint);
begin
TxCommand('W', 'L', FALSE);
case protocol of
1 : begin
Tx2(limit div 256);
Tx2(limit mod 256);
end;
2 : begin
Tx2( limit div 16777216);
Tx2((limit div 65536) mod 256);
Tx2((limit div 256) mod 256);
Tx2( limit mod 256);
end;
end; { case protocol }
Tx2(checkSum);
dummy := RxWait;
end; { Setbatch }
Alex
  • 9,891
  • 11
  • 53
  • 87
Eliyah
  • 330
  • 4
  • 14
  • I think, that more data is needed. Version of turbo pascal, version of environment, operating system version, and best of all, fragments of code :). As near 99% errors saying division by 0 means division by 0... :D – Jacek Kowalewski Feb 08 '14 at 14:51
  • 1
    Totally with @Jacek. You should know the exact line where the error is thrown. Post in your answer the line throwing the exception. There will be a division most likely, altought I can't say for sure since I haven't seen the code. – El Marce Feb 08 '14 at 14:51
  • @Jacek okay. i've provided all info. Please see my edited question – Eliyah Feb 08 '14 at 15:00
  • Thx for the information. Now question looks great :). Is the compiler telling something about lines? Are You sure, that everywhere where You divide something by something, this second something can not be 0? I mean '/' operations and 'div' operations. I will take a look at this. Meanwhile, You can try before every division check if divisor == 0 and if yes, writeln something. Best regards. – Jacek Kowalewski Feb 08 '14 at 15:06
  • PS. I don't know how it is on FreeDos, But take a look here: http://wiki.freepascal.org/Integer. Isn't this: 1843200 too much for integer on Your machine? Just a thought. – Jacek Kowalewski Feb 08 '14 at 15:12
  • The problem is not from the source code. I saw this on the internet but the 'PATCHCRT' is not working for me. The symptom is a Divide-by-Zero error when the app is run on a fast CPU, or a Runtime Error 200 message, or a similar error. Unfortunately, the error message usually won't simply say that the CPU is too fast! The preferred solution is to use an updated version of CRT.ASM, or to contact the software developer, and request that an updated CRT.ASM be used to re-build the app/utility. – Eliyah Feb 08 '14 at 15:16
  • You may want to ask this question on Embarcadero's user forums. They market Delphi, Turbo Pascal's successor. Perhaps one of the regulars there know how to get your hands an updated CRT unit. – 500 - Internal Server Error Feb 08 '14 at 15:18
  • @500-InternalServerError Thanks for your reply. I was forced to run this code because the equivalent C# code i came up with was not working since it couldn't read any data back from the serial port. perhaps you could see my question http://stackoverflow.com/questions/21535967/how-to-interpret-r232c-interface-communication-written-using-pascal-to-c-net?noredirect=1#comment32627945_21535967 and help me out if there is something i could do about it? – Eliyah Feb 08 '14 at 15:22
  • @500-InternalServerError Okay I applied a patch from the internet and now the error is gone. But now, when i trace the code, it hangs at 'RxWait procedure when trying to execute 'while not odd(port [RXTX+5]) do;' What could this be?? – Eliyah Feb 08 '14 at 16:11
  • I wonder if you might have more luck (but slower execution) running this in [DOSBox](http://www.dosbox.com). – echristopherson Feb 08 '14 at 16:11
  • That would suggest that the value on that port is always even, no? – 500 - Internal Server Error Feb 08 '14 at 16:12
  • @500-InternalServerError how can i check whether it's even or not? – Eliyah Feb 08 '14 at 16:16
  • @echristopherson Direct port access does not work in DOSBox – Eliyah Feb 08 '14 at 16:16

3 Answers3

3

As far as I remember (more than 12 years ago), CRT unit had problems about Pentium CPUs and giving that division by zero error. I was using Turbo Pascal 7 those days. What I mean is that it may not be your coding error, but just CRT unit itself.

tcak
  • 2,142
  • 1
  • 16
  • 23
  • Yes, that's what I am thinking too. I have found patches on the internet like 'PATCHCRT' but that didn't work for me. – Eliyah Feb 08 '14 at 15:26
  • Yes. This happened at about the point when processor clock frequency exceeded 200 MHz. Several fixes were posted around that time. IIRC you needed a bit of familiarity with TPUMOVER to apply those. – Jyrki Lahtonen Sep 05 '20 at 18:43
1

Old question I know, but there is another way to write Turbo Pascal code without incurring the wrath of the infamous RTE 200 bug. FreePascal (www.freepascal.org) is fully TP7 compatible and runs under a number of OSes including DOS, Windows and Linux.

Hope this helps!

0

I solved it setting the Execution Cap to 20%. So the processor is probably as slower as expected in those days. You can play with percentages until the error disappear

Regards

Carlos Rafael Ramirez
  • 5,984
  • 1
  • 29
  • 36