0

I don't have a lot of experience troubleshooting C code, let alone on an ancient compiler. I didn't write this code and I'm attempting to reverse engineer it so that I can make small tweaks to its functionality. I appreciate the help!

When I build I get the following errors.

Error EDOE05.CPP 55:Cannot convert 'void (interrupt *)(***)' to 'void (*)() in function main()
Error EDOE05.CPP 136:Cannot convert 'void (*)()' to 'void (interrupt *)(***)' in function main()
Error EDOE05.CPP 136:Type mismatch in parameter '__isr' in call to 'setvect(int,void(interrupt*)(***))' in function main()

I've inserted a '55' and '136' in bold in the code below to show where the issue is happening.

int main(void)
{
    // version printout
    printf("\nS11-36E FIRMWARE EDOE05 TEST EDIT#05 2018-12-14\n\n");

    initMasterDMM32(DMM32M);
    printf("Master Analog Initialized\n");
    initSlaveDMM32(DMM32S);
    printf("Slave Analog Initialized\n");

    void (*oldIRQ5handler)();
    /*55*/ oldIRQ5handler = getvect(IRQ5);    // Save old interrupt handler.**
    setvect(IRQ5, adcHandlerTest);         // Install new interrupt handler.
    printf("VECOTOR old:%04X new:%04X\n", oldIRQ5handler, adcHandlerTest);
    outportb(PIC1 + 1, inportb(PIC1 + 1) & ~0x20);   // Read interrupt mask register and unmask IRQ5.

    //initSerial(COM3, baudrate);

    mainLoops = 0;
    printf("Program initiated\n");
    //=========== MAIN LOOP============
    uint key;
    do {
        mainLoops++;
        printf ("mainLoops: %u, interruptCount: %d\n",  mainLoops, interruptCount);

        // Test for ESC keypress.
        key = _bios_keybrd(_KEYBRD_READY)? _bios_keybrd(_KEYBRD_READ): 0;
        key &= 0x00FF;
            
    } while (key != ESC);
    //=========== /MAIN LOOP============
    
    outportb(DMM32M + 9, 0x00);    // disable timer 0 interrupt.
    outportb(DMM32M + 8, 0x09);  // reset interrupt (Master analog board INTRST)
    outportb(PIC1, EOI);

    /*136*/ setvect(IRQ5, oldIRQ5handler);   // Restore default IRQ5 handler.
    
    printf("Program terminated\n");
    return 0;
}

EDOE05.h

#include <dos.h>
#include <stdio.h>
#include <mem.h>
#include <bios.h>
#include <stdlib.h>
extern "C" {
#include "tcp.h"
}

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

const uint scanRate = 1000;  // Number of A/D scans per second.
const int DMM32M = 0x300;
const int DMM32S = 0x280;
const int COM3 = 0x3E8;
const ulong baudrate = 19200;
const int PIC1 = 0x20;
const int WDT = 0x1EE;
const int IRQ5 = 0xD;
const int ESC = 0x001B;
const int EOI = 0x20;


// Global variables
unsigned int mainLoops;
uchar oldGate = 0;
uchar newGate = 0;
int outputVoltage[18] = {0};
int outputCurrent[18] = {0};
int temperature[3];
int channelSel = -32767;
int refVoltage = -32767;
uchar faults = 0;
ulong elapsedTime = 0;
int msgTimer = 0;
int meterTimer = 0;
int xmtComplete = 0;
int powerFail = 0;
const int reset[18] = {-32767, -32767, -32767, -32767, -32767, -32767,
                              -32767, -32767, -32767, -32767, -32767, -32767,
                              -32767, -32767, -32767, -32767, -32767, -32767};


// Function prototypes
void interrupt (*oldIRQ5handler)(...);
void interrupt adcHandler(...);
int initMasterDMM32(const int base);
int initSlaveDMM32(const int base);
int sendVoltageCurrentMsg(char *buf);
int sendTimeTempMsg(char *buf);
int updateMeters(int *voltage, int *current);
int pollSerialRcvr(void);
int adjustTime(char *buffer);
int InitIP(void);
int initCom(const ulong baud);

// Rob troubleshooting etc
void interrupt adcHandlerTest(...);
int interruptCount;
void sendData(void);

// Ethernet link variables
udp_Socket usock;
char bigbuf[4096];
char txBuf[256];
char rxBuf[32];
uint lport = 50000U;
uint rport = 50000U;
ulong remote_addr = 0xFFFFFFFFLU;  // inet_addr("192.168.1.2");

ulong pkt_count = 0;  // DEBUG CODE

Borland C++ Screenshot

Syrinx
  • 9
  • 4
  • 1
    Wow! *Borland C++ 4.52 (1995): Official support for Windows 95* – Déjà vu Sep 02 '22 at 15:47
  • 2
    Wow. That is one antique system you have there. Sorry I can't help, but you have my sympathy, both for the difficulty of your situation, and the number of unhelpful comments you're about to get suggesting that you just upgrade to a newer compiler. (I'm sure you'd love to.) – Steve Summit Sep 02 '22 at 15:50
  • 2
    Note that, in those parentheses, that's `...` not `***`. Have you tried changing the signatures of your function pointers to match the actual types of interrupts? – Thomas Jager Sep 02 '22 at 15:50
  • A [mre] might be helpful here. The errors mentioning lines 55 and 136 indicate that the code shown here isn't _really_ the code producing these errors. – Drew Dormann Sep 02 '22 at 15:52
  • 1
    Wild guess: IRQ5() should be declared as *interrupt* (keyword). Something like `void interrupt IRQ5( ... ) {` or the opposite (remove *interrupt*), not sure how Borland "works". Did you include all includes? – Déjà vu Sep 02 '22 at 15:53
  • "Wow. That is one antique system you have there. Sorry I can't help, but you have my sympathy, both for the difficulty of your situation, and the number of comments you're about to get suggesting that you just upgrade to a newer compiler. (I'm sure you'd love to.)" Is there an easy way to switch to a newer compiler? – Syrinx Sep 02 '22 at 15:53
  • Just added the one header file that's called out in the .CPP. – Syrinx Sep 02 '22 at 15:58
  • *Is there an easy way to switch to a newer compiler?* That all depends on your target environment. Given that you're dealing with interrupt routines, I'm guessing this is embedded, bare-metal programming. Although, if you're using Turbo C, maybe your target processor is an 80*86. If so, it shouldn't be impossible to use the very modern and popular gcc, perhaps in one of its cross-compilation variants. But there will be details to work out, depending on the nature of your development environment and, as I said, target platform. – Steve Summit Sep 02 '22 at 16:00
  • it looks like it should be `void (*oldIRQ5handler)(...)` instead of `void (*oldIRQ5handler)()` – dewaffled Sep 02 '22 at 16:02
  • it seems the compiler is happy with `setvect(IRQ5, adcHandlerTest)` line and it is defined in the header as `void interrupt adcHandlerTest(...)`. Maybe this is because of other errors but anyway `adcHandlerTest` and `oldIRQ5handler` signatures definitely be the same. – dewaffled Sep 02 '22 at 16:06
  • @dewaffled I tried changing it to void (*oldIRQ5handler)(...) instead of void (*oldIRQ5handler)() and still received the same errors. – Syrinx Sep 02 '22 at 16:31
  • 2
    In contrast to C, which is more "relaxed" without going into details, for C++ a function pointer type of `void (*)(...)` is incompatible to `void (*)()` and to `void (*)(***)`. Are you sure that this should be compiled as C++? Did you try to compile it as C? – the busybee Sep 02 '22 at 16:37
  • Have you tried declaring it as `void interrupt (*oldIRQ5Handler)(...);`? Is there any reason why you cannot use the global variable `oldIRQ5Handler` declared in EDOE05.h instead of declaring your own local variable? – Ian Abbott Sep 02 '22 at 16:47
  • 1
    Using a newer compiler probably won't help. C++ and the Windows OSes have changed a LOT since those days. I'm not sure the code will port to a newer system or the output from a newer compiler would run correctly on an older system. – user4581301 Sep 02 '22 at 17:27
  • I highly recommend against mixing C and C++ languages. They are distinct languages. For example, C++ allows overloading of operators and functions. The C language doesn't. In C++, you don't need the `typedef struct` and you don't need to specify `struct` when creating variables (instances) of the class or struct. Also, you should use `#include ` instead of ``. There is no requirement in C++ that header files have a ".h" extension. – Thomas Matthews Sep 02 '22 at 17:27
  • @ThomasJager I'm not familiar with changing the signatures of the function pointers to match the actual style of interrupts. What would that consist of? – Syrinx Sep 02 '22 at 17:30
  • @thebusybee In the notes of the code it mentions that Borland C++ 4.52 was the compiler used. Is there a way to specify within Borland if the code should be specifically compiled as C? Thanks! – Syrinx Sep 02 '22 at 17:33
  • This is *ancient* and really not very interesting at all. Unless you intend to run it on real mode MS-DOS with some device on the parallel port, this code has no use at all. Besides that, the difference between a "procedure" and an "interrupt procedure" is that the latter sets up the processor's segment registers to match the program's use of segments. If you don't know segment registers, this is a good time to give up on this. – BoP Sep 02 '22 at 19:16
  • @bop I agree that it's ancient. And out in the real world I wouldn't be spending time on this. But here at work we have PC/104 computers that run on DOS that run the code I'm trying to figure out. These systems are still used to control a lot of our products. So I'm forced to work with it. – Syrinx Sep 02 '22 at 19:23
  • I still maintain a 386SX-16 at work because the hardware it runs lives and dies by the exact timing of the loops in the code. Replacing this PC would be monumentally expensive, so we live with it until the magic smoke finally escapes the CPU and it functions no more. It's been running non-stop since about 1986. We built smurf to last back in the old days. – user4581301 Sep 02 '22 at 19:28
  • @Syrinx - Oh, sorry to hear that. I used to do things like this in the mid 1980s, but then Windows came along and direct hardware access was no longer something you did. I just remember the `interrupt procedure` from Borland Pascal that I used briefly. Don't remember much else about the hardware details you would have to know to do anythiing properly. – BoP Sep 02 '22 at 19:37
  • @user4581301 same thing going on here. We have a Windows 98 laptop with the original hard drive still spinning in it that runs one of our test stations. The LCD screen has died, so we use an external monitor, but for now there's no need to change anything. – Syrinx Sep 02 '22 at 19:40
  • Without having used Borland C in the 90s (QuickC was the product used in the company), I'd assume that renaming the source from *.cpp to *.c may suffice. Alternatively there could be a language option. – the busybee Sep 02 '22 at 20:04

0 Answers0