/******************************************************************************/ /* PROBE.C Version 1 Revision 02 2 January 85 */ /******************************************************************************/ /******************************************************************************/ /* include files */ /******************************************************************************/ #include "bdosdef.h" /* CP/M and MP/M BDOS Definitions file */ #include "cbiosdef.h" /* CP/M and MP/M CBIOS Definitions file */ /******************************************************************************/ /* Definitions */ /******************************************************************************/ #define TRUE 0x01 /* logical true constant */ #define FALSE 0x00 /* logical false constant */ #define YES TRUE #define NO FALSE #define EOS 0x00 /* 'c' uses null for EOS marker */ #define ERROR -1 /* general purpose error constant */ /* The following constant, if defined, adds code in showdpb() to display */ /* the H/Z CDR-BIOS Version 2.8 extended disk parameter block */ /* #define CDR_BIOS TRUE */ /******************************************************************************/ /* Global Variable Declarations */ /******************************************************************************/ unsigned sysversn; /* operating system version number (word) as returned */ /* by BDOS call */ char *opsystem[5]; /* "CP/M" or "MP/M" returned from getsysversn() */ char sys_version; /* operating system version level = high order nybble */ char sys_revision; /* operating system revision level = low order nybble */ /******************************************************************************/ /* Main function */ /******************************************************************************/ main() { signon(); /* name, version, date, purpose of program, */ /* language, author's name, credits */ getsysversn(); /* get operating system version and decode */ shosysversn(); /* print operating system version */ cpm_ser_num(); /* get and display operating system ser # */ showiobyte(); /* show IOBYTE */ tell(); /* show the CBIOS jump addresses CP/M 1-3 */ /* show the XIOS jump addresses MP/M II */ showdpb(); /* get and show those parms for all 16 */ /* possible disks. */ exit(); } /******************************************************************************/ /* showiobyte() */ /* Copyright (c) 1984 by Paul M. Sittler */ /******************************************************************************/ showiobyte() { /******************************************************************************/ /* local variables */ /******************************************************************************/ char io_byte; /* value of io_byte */ char io_binstr[10]; /* represents io_byte as binary string */ char lst; char lstbinstr[10]; /* represents LST: as binary string */ char pun; char punbinstr[10]; /* represents PUN: as binary string */ char rdr; char rdrbinstr[10]; /* represents RDR: as binary string */ char con; char conbinstr[10]; /* represents CON: as binary string */ char *lst_dev[4]; /* = {"TTY","CRT","LPT","UL1"}; */ char *pun_dev[4]; /* = {"TTY","PTP","UP1","UP2"}; */ char *rdr_dev[4]; /* = {"TTY","PTR","UR1","UR2"}; */ char *con_dev[4]; /* = {"TTY","CRT","BAT","UC1"}; */ lst_dev[0] = "TTY"; lst_dev[1] = "CRT"; lst_dev[2] = "LPT"; lst_dev[3] = "UL1"; pun_dev[0] = "TTY"; pun_dev[1] = "PTP"; pun_dev[2] = "UP1"; pun_dev[3] = "UP2"; rdr_dev[0] = "TTY"; rdr_dev[1] = "PTR"; rdr_dev[2] = "UR1"; rdr_dev[3] = "UR2"; con_dev[0] = "TTY"; con_dev[1] = "CRT"; con_dev[2] = "BAT"; con_dev[3] = "UC1"; if (sysversn > 0xff) /* MP/M returns 01 as high order byte */ { puts("\n\tMP/M does not implement the I/O BYTE"); return; /* so cannot show it */ } io_byte = bdos(GETIOBYTE,0); /* grab i/obyte and store in io_byte */ asciitobin(io_byte,io_binstr); /* represent io_byte as binary string */ printf("\nI/O Byte value is currently %d decimal,",io_byte); printf("\n%x hexadecimal or [%s] binary\n",io_byte,io_binstr); /* bitwise manipulation experiment follows: first we mask the appropriate bits by ANDing, next we shift the bits right the appropriate number of places. */ lst = (io_byte & 0xC0) >> 6; /* mask i/obyte for bits 7, 6 */ pun = (io_byte & 0x30) >> 4; /* mask i/obyte for bits 5, 4 */ rdr = (io_byte & 0x0C) >> 2; /* mask i/obyte for bits 3, 2 */ con = (io_byte & 0x03); /* mask i/obyte for bits 1, 0 */ asciitobin(lst,lstbinstr); /* represent LST: as binary string */ asciitobin(pun,punbinstr); /* represent PUN: as binary string */ asciitobin(rdr,rdrbinstr); /* represent RDR: as binary string */ asciitobin(con,conbinstr); /* represent CON: as binary string */ printf("\n\tLST: is currently %02x hex or [%s ] binary, or %s:", lst,lstbinstr+7,lst_dev[lst]); printf("\n\tPUN: is currently %02x hex or [ %s ] binary, or %s:", pun,punbinstr+7,pun_dev[pun]); printf("\n\tRDR: is currently %02x hex or [ %s ] binary, or %s:", rdr,rdrbinstr+7,rdr_dev[rdr]); printf("\n\tCON: is currently %02x hex or [ %s] binary, or %s:", con,conbinstr+7,con_dev[con]); puts ( "\n\t -----------"); printf("\n\tMaking the IOBYTE %02x hex or [%s] binary",io_byte,io_binstr); puts("\n\nwhere, for the following devices:\n"); puts("\n\tDevice LST: PUN: RDR: CON:"); printf("\n\tValue %s %s %s %s ", lstbinstr+7,punbinstr+7,rdrbinstr+7,conbinstr+7); puts("\n\t 00 assigns TTY: TTY: TTY: TTY:"); puts("\n\t 01 assigns CRT: PTP: PTR: CRT:"); puts("\n\t 10 assigns LPT: UP1: UR1: BAT:"); puts("\n\t 11 assigns UL1: UP2: UR2: UC1:\n"); printf( "\n[%s] assigns %3s: %3s: %3s: %3s:\n", io_binstr,lst_dev[lst],pun_dev[pun],rdr_dev[rdr],con_dev[con]); } /******************************************************************************/ /* tell() */ /* Copyright (c) 1984 by Paul M. Sittler */ /******************************************************************************/ tell() /* is a utility that tells you where your CCP starts, */ /* what your bdos entry address is, and where your */ /* CBIOS jump table begins, as well as other useful */ /* information. It essentially shows you the jump */ /* addresses and reproduces the CBIOS jump table. */ { /******************************************************************************/ /* local variables */ /******************************************************************************/ char *ptr; /* needs to be set to char, not int!! */ /* CP/M jumps variable initialization */ int Ccp; /* CCP starting address */ int Bdos; /* Bdos entry address */ int Cbios; /* CBIOS jump table address */ int Wbootjmp; /* Warm boot jump table address */ /* CBIOS jump table variable initialization */ /* CBIOS jump table address variables have first letter capitalized */ /* Used by CP/M 1.x + */ /* cold and warm start addresses */ int Boot; /* [1] arrive here from cold start system load */ int Wboot; /* [2] arrive here from warm start */ /* Used by CP/M 1.x + */ /* input/output device access */ int Const; /* [3] check for console character ready */ int Conin; /* [4] read console character in */ int Conout; /* [5] write console character out */ int List; /* [6] write list device character out */ int Punch; /* [7] write punch device character out */ int Reader; /* [8] read reader device character in */ /* Used by CP/M 1.x + */ /* mass storage device access */ int Home; /* [9] move to track 0 on selected disk */ int Seldsk; /* [10] select disk drive */ int Settrk; /* [11] set track number */ int Setsec; /* [12] set sector number */ int Setdma; /* [13] set dma address */ int Read; /* [14] write selected sector */ int Write; /* [15] write selected sector */ /* added by CP/M 2.xx */ int Listst; /* [16] check for list device not busy */ int Sectran; /* [17] translate logical to physical sector */ /* added by CP/M+ (3.xx) (at least some) depending */ /* on the features incorporated */ int Conost; /* [18] check output status of console */ int Auxist; /* [19] check input status of auxiliary device */ int Auxost; /* [20] check output status of auxiliary device */ int Devtbl; /* [21] get address of character i/o table */ int Devini; /* [22] initialize character i/o devices */ int Drvtbl; /* [23] get address of disk drive table */ int Multio; /* [24] set number of multi-R/W sectors */ int Flush; /* [25] flush host buffer (user-supplied blocking */ int Move; /* [26] memory-to-memory block move */ int Time; /* [27] get or set time clock */ int Selmem; /* [28] set memory bank -- absolute */ int Setbnk; /* [29] set memory bank for next DMA move */ int Xmove; /* [30] set memory bank numbers for next move call */ int Userf; /* [31] reserved for system integrator */ int Reserv1; /* [32] reserved for future use */ int Reserv2; /* [33] reserved for future use */ puts("\n This portion will tell you where your CCP starts, what"); puts("\nyour BDOS entry address is, and where your CBIOS jump table"); puts("\nbegins. The CBIOS jump table is also displayed.\n"); ptr = 1; /* set ptr to CBIOS jump address */ /* which is the Wboot jump address */ Wbootjmp = (*ptr++) + (*ptr++ << 8); /* Wboot address */ Cbios = Wbootjmp - 3; /* making Cbios address three less */ /* which is the Boot jump address */ ptr = 6; /* set ptr to BDOS jump address */ Bdos = (*ptr++) + (*ptr++ << 8) - 6; /* Bdos address */ Ccp = Bdos - 0x800; /* CCP address is 800H below BDOS */ /* Probably system dependent and */ /* therefor needs work */ ptr = Cbios + 1; Boot = (*ptr++) + (*ptr++ << 8); /* [1] cold start system load */ ptr++; Wboot = (*ptr++) + (*ptr++ << 8); /* [2] arrive here from warm start */ ptr++; Const = (*ptr++) + (*ptr++ << 8); /* [3] check for cons char ready */ ptr++; Conin = (*ptr++) + (*ptr++ << 8); /* [4] read cons char in */ ptr++; Conout = (*ptr++) + (*ptr++ << 8); /* [5] write cons char out */ ptr++; List = (*ptr++) + (*ptr++ << 8); /* [6] write list dev char out */ ptr++; Punch = (*ptr++) + (*ptr++ << 8); /* [7] write punch dev char out */ ptr++; Reader = (*ptr++) + (*ptr++ << 8); /* [8] read reader dev char in */ /* Used by CP/M 1.x + */ /* mass storage device access */ ptr++; Home = (*ptr++) + (*ptr++ << 8); /* [9] move to track 0 on sel disk */ ptr++; Seldsk = (*ptr++) + (*ptr++ << 8); /* [10] select disk drive */ ptr++; Settrk = (*ptr++) + (*ptr++ << 8); /* [11] set track number */ ptr++; Setsec = (*ptr++) + (*ptr++ << 8); /* [12] set sector number */ ptr++; Setdma = (*ptr++) + (*ptr++ << 8); /* [13] set dma address */ ptr++; Read = (*ptr++) + (*ptr++ << 8); /* [14] write selected sector */ ptr++; Write = (*ptr++) + (*ptr++ << 8); /* [15] write selected sector */ if (sysversn) /* CP/M 2.xx or higher */ { /* added by CP/M 2.xx */ ptr++; Listst = (*ptr++) + (*ptr++ << 8); /* [16] list dev not busy? */ ptr++; Sectran = (*ptr++) + (*ptr++ << 8); /* [17] log to phys sector trans */ if ( (sysversn > 0xff) || /* if MP/M */ (sys_version == 3) ) /* or CP/M 3.xx (CP/M+) */ { /* added by CP/M+ (3.xx) (at least some) depending */ /* on the features incorporated by the system */ /* implementor. Note that these variables do */ /* double duty as the XIOS jump table for MP/M. */ ptr++; Conost = (*ptr++) + (*ptr++ << 8); /* output stat of cons? */ ptr++; Auxist = (*ptr++) + (*ptr++ << 8); /* inp stat of aux dev? */ ptr++; Auxost = (*ptr++) + (*ptr++ << 8); /* outp stat of aux dev? */ ptr++; Devtbl = (*ptr++) + (*ptr++ << 8); /* get addr of char i/o tbl */ ptr++; Devini = (*ptr++) + (*ptr++ << 8); /* [22] init char i/o devices */ ptr++; Drvtbl = (*ptr++) + (*ptr++ << 8); /* [23] get addr of drive tbl */ ptr++; Multio= (*ptr++) + (*ptr++ << 8); /* set # of multi-R/W sectors */ ptr++; Flush = (*ptr++) + (*ptr++ << 8); /* [25] flush host buffer */ ptr++; Move = (*ptr++) + (*ptr++ << 8); /* [26] mem-to-mem block move */ ptr++; Time = (*ptr++) + (*ptr++ << 8); /* [27] get or set time clock */ ptr++; Selmem = (*ptr++) + (*ptr++ << 8); /* set mem bank -- absolute */ ptr++; Setbnk= (*ptr++) + (*ptr++ << 8); /* set mem for nxt DMA move */ ptr++; Xmove = (*ptr++) + (*ptr++ << 8); /* set mem bank # for nxt mv */ ptr++; Userf = (*ptr++) + (*ptr++ << 8); /* [31] res for sys integr */ ptr++; Reserv1 = (*ptr++) + (*ptr++ << 8); /* [32] res for future use */ ptr++; Reserv2 = (*ptr++) + (*ptr++ << 8); /* [33] res for future use */ } } printf("\nYour CCP beginning address is: \t%04xH.",Ccp); printf("\nYour BDOS beginning address is: \t%04xH.",Bdos); printf("\nYour BDOS entry address is: \t%04xH.",Bdos+6); printf("\nYour CBIOS jump table begins at: \t%04xH.",Cbios); printf("\nCold start routine address is: \t%04xH.",Boot); printf("\nWarm start routine address is: \t%04xH.",Wboot); printf("\nConsole Status routine address is: \t%04xH.",Const); printf("\nConsole Input routine (waits for char.): \t%04xH.",Conin); printf("\nConsole Output routine address is: \t%04xH.",Conout); printf("\nList device output routine address is: \t%04xH.",List); printf("\nPunch device output routine address is: \t%04xH.",Punch); printf("\nReader device input routine address is: \t%04xH.",Reader); printf("\nHome disk routine address is: \t%04xH.",Home); printf("\nSelect disk routine address is: \t%04xH.",Seldsk); printf("\nThe set track disk routine address is: \t%04xH.",Settrk); printf("\nThe set sector disk routine address is: \t%04xH.",Setsec); printf("\nThe set DMA disk routine address is: \t%04xH.",Setdma); printf("\nThe read disk routine address is: \t%04xH.",Read); printf("\nThe write disk routine address is: \t%04xH.",Write); if (sysversn) /* CP/M 2.xx or higher */ { printf("\nList device status routine address is: \t%04xH.",Listst); printf("\nSector translate disk routine address is:\t%04xH.",Sectran); if (sys_version == 3) /* if CP/M 3.xx (CP/M+) */ { puts("\n\nCP/M+ (3.x) extended bios calls follow. Note that"); puts("\nsome of these may NOT have been implemented by your"); puts("\nsystem integrator. Check carefully with your manual"); puts("\nbefore trying to use them.\n"); printf("\nConsole output status check routine at: \t%04xH.", Conost); printf("\nAux device input status check routine at: \t%04xH.", Auxist); printf("\nAux device output status check routine at: \t%04xH.", Auxost); printf("\nCharacter i/o table addr check routine at: \t%04xH.", Devtbl); printf("\nCharacter i/o devices init routine at: \t%04xH.", Devini); printf("\nGet disk drive table address routine at: \t%04xH.", Drvtbl); printf("\nSet # of multi-R/W sectors routine at: \t%04xH.", Multio); printf("\nFlush host buffer routine address at: \t%04xH.", Flush); printf("\nMemory-to-memory block move routine at: \t%04xH.", Move); printf("\nGet or set time clock routine at: \t%04xH.", Time); printf("\nSet memory bank -- absolute routine at: \t%04xH.", Selmem); printf("\nSet mem bank for next DMA move routine at: \t%04xH.", Setbnk); printf("\nSet mem bank #s for next move routine at: \t%04xH.", Xmove); printf("\nBios call reserved for system integr at: \t%04xH.", Userf); printf("\nBios call 1 reserved for future use \t%04xH.", Reserv1); printf("\nBios call 2 reserved for future use \t%04xH.", Reserv2); } if (sysversn > 0xff) /* MP/M system XIOS calls */ { puts("\n\nMP/M II XIOS call jump addresses follow.\n"); printf("\nSelect memory segment routine at: \t%04xH.", Conost); printf("\nDevice Polling routine at: \t%04xH.", Auxist); printf("\nStart clock routine at: \t%04xH.", Auxost); printf("\nStop clock routine at: \t%04xH.", Devtbl); printf("\nExit critical region routine at: \t%04xH.", Devini); printf("\nMaximum console number check routine at: \t%04xH.", Drvtbl); printf("\nSystem initialization cold boot routine at:\t%04xH.", Multio); printf("\nOptional idle procedure routine at: \t%04xH.", Flush); } } } /******************************************************************************/ /* getsysversn() */ /* Copyright (c) 1984 by Paul M. Sittler */ /******************************************************************************/ getsysversn() { /******************************************************************************/ /* Following variables are declared globally by the calling program: */ /* */ /* int sysversn = operating system version returned from bdos call */ /* as one two byte word. */ /* These two bytes are decoded as follows: */ /* high order byte low order byte */ /* System Type Version # and Revision # */ /* [0000 0000] [0000|0000] */ /* CP/M = 0, MP/M = 1 Version # | Revision # */ /* */ /* The next two variables come from the low order byte of sysversn */ /* char sys_version = high nybble of sysversn that is version number */ /* char sys_revision = low nybble of sysversion that is revision number */ /* char *opsystem[5] = pointer to "CP/M" or "MP/M" string */ /******************************************************************************/ sysversn = bdos(RETURNVER,0); /* bdos call to get system version */ sprintf(opsystem,"%s", ( (sysversn >> 8) ? "MP/M" : "CP/M") ); /* check high order byte of sysversn */ /* It is MP/M if one, CP/M if zero */ /* opsystem[5] holds system name */ if (!sysversn) /* CP/M 1.4 and return a zero (0) */ { sys_version = 1; /* version # = 1 */ sys_revision = 4; /* revision # = 4 */ } else /* must be CP/M 2.xx or higher */ { sys_version = (sysversn & 0x0f); /* mask for low order nybble */ sys_revision = (sysversn >> 4) & 0x0f; /* shift sysversn right four */ /* bits and mask for low */ /* order nybble */ } } /******************************************************************************/ /* shosysversn() */ /* Copyright (c) 1984 by Paul M. Sittler */ /******************************************************************************/ shosysversn() { printf("\n\tThis is %s %d.%d.\n", opsystem, sys_version, sys_revision); }