// Automatically generated C++ file on Mon Aug 19 07:36:46 2024 // // To build with Digital Mars C++ Compiler: // // dmc -mn -WD swopampx.cpp kernel32.lib #include extern "C" __declspec(dllexport) int (*Display)(const char *format, ...) = 0; union uData { bool b; char c; unsigned char uc; short s; unsigned short us; int i; unsigned int ui; float f; double d; long long int i64; unsigned long long int ui64; char *str; unsigned char *bytes; }; // int DllMain() must exist and return 1 for a process to load the .DLL // See https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain for more // information. int __stdcall DllMain(void *module, unsigned int reason, void *reserved) { return 1; } void bzero(void *ptr, unsigned int count) { unsigned char *first = (unsigned char *)ptr; unsigned char *last = first + count; while (first < last) *first++ = '\0'; } // #undef pin names lest they collide with names in any header file(s) you might // include. #undef inP #undef inN #undef out struct sSWOPAMPX { // declare the structure here double lastOut; }; extern "C" __declspec(dllexport) void swopampx( struct sSWOPAMPX **opaque, double t, union uData *data) { // Implement module evaluation code here: double inP = data[0].d; // input double inN = data[1].d; // input double A = data[2].d; // input parameter double &out = data[3].d; // output if (!*opaque) { *opaque = (struct sSWOPAMPX *)malloc(sizeof(struct sSWOPAMPX)); bzero(*opaque, sizeof(struct sSWOPAMPX)); } struct sSWOPAMPX *inst = *opaque; // Implement module evaluation code here: out = A * (inP - inN); inst->lastOut = out; } extern "C" __declspec(dllexport) void Trunc(struct sSWOPAMPX *inst, double t, union uData *data, double *timestep) { // limit the timestep to a tolerance if the circuit // causes a change in struct sSWOPAMPX const double ttol = 1e-5; // 1ns default tolerance // this is a simplistic approach to limiting timestep based on a hard-coded // max output voltage change. a more sophisticated approach might save the // timestamp (t) in the evaluation function, calculate the slope, and base the // returned timestep on the slope.... const double maxVoltChange = 0.075; if (*timestep > ttol) { struct sSWOPAMPX tmp = *inst; swopampx(&(&tmp), t, data); // we're deliberately fixing only the rising edge for demo purposes double vChange = tmp.lastOut - inst->lastOut; if (vChange > maxVoltChange) { *timestep = ttol; } } } extern "C" __declspec(dllexport) void Destroy(struct sSWOPAMPX *inst) { free(inst); }