#define INCL_DOS #include #include #include #include static UCHAR BusCount; static HFILE hPCI; #pragma pack(1) static int PCIBIOSPresent (char *VersionMajor, char *VersionMinor, char *BusCount) { struct { BYTE SubFunction; } Parm = {0} ; ULONG ParmLen = sizeof (Parm); struct { BYTE rc; BYTE Mechanism; BYTE VMajor, VMinor; BYTE LastBus; } Data; ULONG DataLen = sizeof (Data); DosDevIOCtl (hPCI, 0x80, 0x0B, &Parm, ParmLen, &ParmLen, &Data, DataLen, &DataLen); if (0 == Data.rc) { *VersionMajor = Data.VMajor; *VersionMinor = Data.VMinor; *BusCount = Data.LastBus; } return (Data.rc); } static int PCIFindDevice (char Class, char SubClass, char ProgIF, int Occurence, char *Bus, char *Device, char *Function) { struct { BYTE SubFunction; BYTE ProgIF; BYTE SubClass; BYTE Class; BYTE filler; BYTE Index; } Parm = {2, 0, 0, 0, 0}; ULONG ParmLen = sizeof (Parm); struct { BYTE rc; BYTE Bus; BYTE DevFunc; } Data; ULONG DataLen = sizeof (Data); Parm.Class = Class; Parm.SubClass = SubClass; Parm.ProgIF = ProgIF; Parm.Index = Occurence; DosDevIOCtl (hPCI, 0x80, 0x0B, &Parm, ParmLen, &ParmLen, &Data, DataLen, &DataLen); if (0 == Data.rc) { *Bus = Data.Bus; *Device = (Data.DevFunc >> 3) & 0x1F; *Function = Data.DevFunc & 0x07; } return (Data.rc); } static int PCIReadConfigB (char Bus, char Device, char Function, int Reg, char *Value) { struct { BYTE SubFunction; BYTE Bus, DevFunc; BYTE Register; BYTE Size; } Parm = {3, 0, 0, 0, 1}; ULONG ParmLen = sizeof (Parm); struct { BYTE rc; ULONG Data; } Data; ULONG DataLen = sizeof (Data); Parm.Bus = Bus; Parm.DevFunc = (Device << 3) | (Function & 0x07); Parm.Register = Reg; DosDevIOCtl (hPCI, 0x80, 0x0B, &Parm, ParmLen, &ParmLen, &Data, DataLen, &DataLen); if (0 == Data.rc) { *Value = Data.Data; } return (Data.rc); } static int PCIReadConfigW (char Bus, char Device, char Function, int Reg, USHORT *Value) { struct { BYTE SubFunction; BYTE Bus, DevFunc; BYTE Register; BYTE Size; } Parm = {3, 0, 0, 0, 2}; ULONG ParmLen = sizeof (Parm); struct { BYTE rc; ULONG Data; } Data; ULONG DataLen = sizeof (Data); Parm.Bus = Bus; Parm.DevFunc = (Device << 3) | (Function & 0x07); Parm.Register = Reg; DosDevIOCtl (hPCI, 0x80, 0x0B, &Parm, ParmLen, &ParmLen, &Data, DataLen, &DataLen); if (0 == Data.rc) { *Value = Data.Data; } return (Data.rc); } static int PCIReadConfigL (char Bus, char Device, char Function, int Reg, ULONG *Value) { struct { BYTE SubFunction; BYTE Bus, DevFunc; BYTE Register; BYTE Size; } Parm = {3, 0, 0, 0, 4}; ULONG ParmLen = sizeof (Parm); struct { BYTE rc; ULONG Data; } Data; ULONG DataLen = sizeof (Data); Parm.Bus = Bus; Parm.DevFunc = (Device << 3) | (Function & 0x07); Parm.Register = Reg; DosDevIOCtl (hPCI, 0x80, 0x0B, &Parm, ParmLen, &ParmLen, &Data, DataLen, &DataLen); if (0 == Data.rc) { *Value = Data.Data; } return (Data.rc); } int GetDevice (int Interactive) { APIRET rc; ULONG Action; int i; UCHAR VersionMajor, VersionMinor; UCHAR Bus, Dev, Fnc; USHORT VendorID, DeviceID = 0; char c; rc = DosOpen ("OEMHLP$", &hPCI, &Action, 0, 0, FILE_OPEN, OPEN_SHARE_DENYNONE | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_ACCESS_READWRITE, NULL); if (rc != 0) exit (98); rc = PCIBIOSPresent (&VersionMajor, &VersionMinor, &BusCount); if (rc != 0) { printf ("PCI BIOS not present (rc=%02Xh).\n", rc); return (0); } else { printf ("PCI BIOS V%X.%02X detected\n", VersionMajor, VersionMinor); } #define VENDORID_YAMAHA 0x1073 for (i = 0; !PCIFindDevice (0x04, 0x01, 0x00, i, &Bus, &Dev, &Fnc); i++) { if (PCIReadConfigW (Bus, Dev, Fnc, 0, &VendorID)) continue; if (VendorID != VENDORID_YAMAHA) continue; if (PCIReadConfigW (Bus, Dev, Fnc, 2, &DeviceID)) continue; switch (DeviceID) { case 0x04 : printf ("found Yamaha PCI sound chip YMF724D (DS-1)\n"); break; case 0x0D : printf ("found Yamaha PCI sound chip YMF724F (DS-1)\n"); break; case 0x0C : printf ("found Yamaha PCI sound chip YMF740C (DS-1L)\n"); break; case 0x10 : printf ("found Yamaha PCI sound chip YMF744B (DS-1S)\n"); break; case 0x12 : printf ("found Yamaha PCI sound chip YMF754 (DS-1E)\n"); break; default : printf ("found unknown Yamaha PCI sound chip (DevID:%04X)\n", DeviceID); break; } if (Interactive) { printf ("accept ? (Y/n)\n"); for (c = toupper (getchar()); (c != 'N') && (c != 'Y') && (c != 0x0D); c = toupper (getchar())); if (c == 'N') { DeviceID = 0; } else break; } } DosClose (hPCI); return (DeviceID); } char Buffer[128*1024]; int main (int argc, char *argv[]) { int DeviceID; char *FileName = NULL; FILE *f; long FileSize; static unsigned long VID[] = {0x88BE, 0x88CE, 0x904A, 0x905E, 0xF4DC, 0x11FDB, 0x12024, 0x1203B}; static unsigned long DID[] = {0x88BC, 0x88CC, 0x9044, 0x904E, 0xF4E4, 0x11FD9, 0x12021, 0x12038}; int i, NumPatches; switch (argc) { case 1: GetDevice (0); exit (0); case 2: FileName = argv[1]; DeviceID = GetDevice (1); if (DeviceID == 0) exit (0); break; case 3: FileName = argv[1]; DeviceID = strtol (argv[2], NULL, 0); break; } if ((DeviceID <= 0) || (DeviceID > 0x7F)) { printf ("Device ID out of bounds\n"); exit (1); } f = fopen (FileName, "rb"); if (f == NULL) { printf ("Could not open file <%s>\n", FileName); exit (2); } FileSize = fread (Buffer, 1, sizeof (Buffer), f); fclose (f); NumPatches = (sizeof (VID) / sizeof (VID[0])) - 1; if (FileSize < VID[NumPatches]) { printf ("Patch target is not acceptable\n"); exit (3); } for (i = NumPatches; i >= 0; i--) { if (*(unsigned short *)&Buffer[VID[i]] != VENDORID_YAMAHA) break; } if (i >= 0) { printf ("Patch target is not acceptable\n"); exit (3); } for (i = NumPatches; i >= 0; i--) { Buffer[DID[i]] = DeviceID; } f = fopen (FileName, "wb"); if (f == NULL) { printf ("Could not open file <%s>\n", FileName); exit (4); } i = fwrite (Buffer, 1, FileSize, f); fclose (f); if (i != FileSize) { printf ("Couldn't write modified target\n"); exit (5); } return (0); }