[Back to MISC SWAG index] [Back to Main SWAG index] [Original]

    {
    > I saw a message from someone that said you had compiled a list of all the
    > bugs with BP 7.0... is it possible I could get a copy?

    Look around for BP7BUGS2.ZIP.  That's the currently released version.  It's
    available for Internet ftp from garbo.uwasa.fi:/pc/turbopas; it's also on
    Compuserve, but in the CLMFORUM in the PC Techniques area, because Borland
    didn't want it on BPASCAL.  It should also be available on a lot of BBS
    systems.
    That version isn't quite up to date; here are the newer entries:

    54.  SetVisualPage doesn't take effect immediately, so writes to the old page
    after the page change may show up on the screen.  Put in a delay or a wait for
    the retrace if you intend to draw to the hidden page.

    55.  In protected mode when using BGI with linked in fonts, repeated font
    changes eventually cause the BGI driver to get messed up and abort.  There's no
    problem if the .CHR files are available in the directory given to InitGraph.

    56.  In BASM, "dw @variable" will not assemble properly.  BP and BPC abort,
    while TURBO and TPC give a wrong answer.
    58.  An array of zero length records (e.g. array[boolean] of record end;) gives
    a spurious "structure too large error".
    59.  Real numbers aren't parsed as the manual describes -- the decimal part and
    number part of the scale factor are sometimes optional.  For example, "(1. )"
    is a legal expression, but "(1.)" is not; both "1e +1" and "1e+1" are legal,
    but have different values (2 and 10).
    60.  Hardware interrupts during memory allocations in protected mode can cause
    general protection faults.  For details and a patch, see PROTINT.FIX.

    61.  Inline procedures are treated like forward declarations:  you can have a
    duplicate definition of the same identifier later, and the compiler won't
    declare an error unless the form of the declaration is different.  It's the
    inline definition that will be used.
    62.  The TEMSStream.Done destructor doesn't reset EMSCurhandle to $FFFF, so
    that the next TEMSStream may work on the wrong page frame at first.  Fix: After
    calling Done, manually set EMSCurhandle to $FFFF.

    63.  OutText and OutTextXY don't update the current pointer properly in all
    justification modes.  Use MoveTo(GetX,GetY) after a call if you want to be sure
    to have CP act properly.
    64.  For certain very rare pairs x and y, a $N+ division x/y will only be
    accurate to about 4 decimal digits when calculated on a Pentium produced before
    Fall 1994.  (This is the famous Pentium FDIV bug, not a BP bug.)

    And here's the PROTINT.FIX file:

     #: 252543 S7/DOS Programming  [BPASCAL]
         14-Mar-94  04:01:44
     Sb: #252502-Increment Bug in BP7
     Fm: Peter Petersen 100120,1363
     To: DJ Murdoch 71631,122

    DJ,

    A protected mode program will crash when the first access to a newly allocated
    segment is interrupted by a hardware interrupt. The following test program
    demonstrates the bug within a few seconds:
    }
       PROGRAM DPMIBug;
       USES
          DOS, CRT;
       CONST
          COM = 1;  { may be set to 1..4 }
          IRQ : ARRAY [1..4] OF byte = (4, 3, 4, 3);
          RXB  = $00; TXB  = $00; IER  = $01; IIR  = $02; LCR  = $03;
          MCR  = $04; LSR  = $05; MSR  = $06; DLL  = $00; DLM  = $01;
       VAR
          Base: Word;
          Count: LongInt;
          OrgHandler: Pointer;

          {$S- ------------------------------}
          PROCEDURE IntCOM; INTERRUPT;
          VAR
             Dummy: Byte;
          BEGIN
             Inc(Count);
             WHILE Port[Base+IIR] <> 1 DO
             BEGIN
                Dummy:=Port[Base+LSR];
                Dummy:=Port[Base+RXB];
                Port[Base+TXB]:=Ord(' ')
             END;
             Port[$20]:=$20
          END;

          {----------------------------------}
          PROCEDURE InitPort(P: Byte; Baud: LongInt);
          CONST
             MaxBaudRate = 115200;
          VAR
             Divider  : Word;
          BEGIN
             Base:=MemW[Seg0040:SizeOf(Word) * (P-1)];
             IF Base = 0 THEN
             BEGIN
                WriteLn('Port COM', P, ' not installed.');
                Halt(1)
             END;
             Port[Base + LCR]:=$80;
             Divider:=(MaxBaudRate + MaxBaudRate MOD Baud) DIV Baud;
             Port[Base + DLL]:=Lo(Divider);
             Port[Base + DLM]:=Hi(Divider);
             Port[Base + LCR]:=(8-5) + ((1-1) SHL 2) + 0;
             GetIntVec(8+IRQ[P], OrgHandler);
             SetIntVec(8+IRQ[P], Addr(IntCom));
             Port[$20+1]:=Port[$20+1] AND NOT (1 SHL IRQ[P]);
             Port[Base + MCR]:=$01 + $01 + $04 + $08;
             Port[Base + IER]:=$0F
          END;

          {----------------------------------}
          PROCEDURE DisableCOMInterrupt (P: Byte);
          BEGIN
             Port[Base + IER]:=0;
             SetIntVec(8+IRQ[P], OrgHandler)
          END;

       VAR
          P: ^Word;
       BEGIN
          System.Test8086:=0;
          {$IFDEF DPMI }
          System.HeapLimit:=0;
          {$ENDIF }
          Count:=0;
          InitPort(COM, 38400);
          Port[Base+TXB]:=Ord(' ');
          WHILE NOT keypressed DO
          BEGIN
             Write(^M, count);
             New(P);
             IF P = NIL THEN WriteLn('error in alloc!');
             IF p^ = 7 THEN ;  { read access }
             Dispose(P)
          END;
          DisableCOMInterrupt(COM);
          WHILE Keypressed DO IF ReadKey = ' ' THEN
       END.
    {
    The problem can be worked around by disabling interrupts during the first
    access to the segment. This is achieved with the following changes to file
    WMEM.ASM (part of unit System):
       Comparing files WMEM.ASM and C:\BP70\RTL\SYS\WMEM.ASM
       ***** WMEM.ASM
               OR      AX,AX
               JE      @@2                     ; line number 253
               STC                             ; error and return
               RET
       @@2:    PUSH    AX                      ; save return value
               MOV     AX, 0900H               ; DPMI ints off
               INT     31H                     ; leave int state in AX
               MOV     ES, DX                  ; load seg-reg to load segment
               INT     31H                     ; DPMI restore int state
               POP     AX                      ; restore return value
           ENDIF
       ***** C:\BP70\RTL\SYS\WMEM.ASM
               OR      AX,AX
               JE      @@1
               STC
           ENDIF
       *****

    Please note that this fix only affects allocations of the heap. Others (such as
    LoadLibrary, InitGraph, GlobalAlloc, etc.) are still affected.
    }

[Back to MISC SWAG index] [Back to Main SWAG index] [Original]