DOS+ has provision for application interception and handling of errors. THESE SHOULD ONLY BE USED ON DOS+. The following code is a reliable detection method, which discriminates against CPM 1.4, CPM 2.2, CPM3, and MPM, yet detects DOS+ running in compatibility mode. "msgxit" is your exit code whenever DOS+ is not running. mvi c,12; CPMVER, ensure running DOS+ 2.5 up call 5 inr h dcr h jnz msgxit; not MPM etc cpi 22h jc msgxit; < 2.2, cant be compatible mode cpi 30h jnc msgxit; Can't use CPM 3 cpi 25h jnc bgn2; ok, 2.5 thru 2.f mvi c,210 mvi e,0 call 5; getbase of DOS+, if running mov a,h; DOS+ returns base pointer ora a; CPM returns 0 jz msgxit; not in compatible mode ; " " ; DOS+ running, check parameters and execute bgn2: call trade; to set application error traps The error handling vector is located at DOS+ base + 9 (as in CPM 2.2). The table contains, in order, the address of routines for bad sectors, select errors, drive read-only, and file read- only. The fundamental intercept mechanism is to replace these addresses with pointers to routines in the application. IT IS ESSENTIAL that the original table contents be restored before the application exits, and usually before the application performs any DOS+ calls during error handling. When an application error handler is entered, the stack pointer will be set to a location withing DOS+. From here the application caller may be determined by: lxi h,0 dad sp mvi l,0feh mov a,m inx h mov h,m mov l,a; points to application stack mov a,m inx h mov h,m mov l,a; get application return point and hl now contains the return address for the original DOS+ call. Record this by: shld callrtn; an application storage location and reset the stack pointer. no returns to DOS+ are legal now, except for i/o errors, discussed below lxi sp,apstack; a suitable application stack Which error was triggered is identified by which application error handler was entered. The error vector should now be restored by call trade; The same routine called to set and further processing is application dependant. Another call to "trade" will re-install the application error vectors if processing is to continue. ------------ To set, or restore, the error vector the following is recommended: ; Application table, dynamically modified. Originally contains ; pointers to application error handlers. tbl: dw secerr; i/o errors dw selerr; drive select errors dw rdonly; drive read-only error dw frdonly; file read-only error ; ; Error trap setting mechanism (with DOS+ running). ; This functions even when RSX mechanisms have been installed ; a,f,b,c,d,e,h,l (registers modified) trade: mvi c,210; DOS+ getinfo call mvi e,0; get base address of running DOS+ call 5 mvi l,9; addresses DOS+ error table lxi d,tbl; addresses application table mvi b,8; bytes to exchange trade1: mov c,m; dos+ table byte ldax d; application table byte mov m,a; to dos+ table mov a,c stax d; dos+ byte to application table inx h inx d dcr b jnz trade1; more to do ret ----------- Disk I/O errors in DOS+ may be retried or ignored PROVIDED that the IX and IY registers are not altered, by executing a return from the error handler (without resetting the DOS+ stack pointer). If, on return, the Z flag is set DOS+ will retry, otherwise it will ignore the error (leaving bad data). Note that some bios implementations have filled a buffer, and that a retry will not actually do a physical retry on read, but will simply transfer the (bad) data from the buffer. For such operations the application must decide whether or not the DOS+ error table should be reset ------------- In general, it may be fatal to abort DOS+ with a CTL-C (or the user break) while the error table is altered. (only safe if no RSX or similar mechanisms are installed, and DOS+ is reloaded from the system tracks). This can be prevented by disabling all user breaks with: mvi c,210; DOS+ getinfo call mvi e,0; get base address call 5 mvi l,18h; address the configuration byte mov a,m ani NOT 40h; reset the break enable bit mov m,a and breaks may later be re-enabled by replacing the "ani .. " line with "ori 040h" When breaks are disabled any CTL-C handling is entirely up to the application program. --------- DOS+ also has the ability to trap all errors and CTL-C interrupts (the latter assuming user breaks are enabled, above) to an external error handler. This trap occurs AFTER the error message has been emitted and the user response made. To enable: mvi c,210; DOS+ getinfo call mvi e,0; get base address call 5 mvi l,1eh; address the error exit lxi d,errhandle; the address of your own handler mov m,e; (usually 038h for a DDTZ trap) inx h mov m,d and the next error will transfer control to location 'errhandle'. At this point the C and DE registers will contain the values they held when DOS+ was called, and the stack is reset to the application stack, so that a 'RET' instruction would complete the DOS+ call. DO NOT DO SO - some data is in an indeterminate state. The internal pointer (in DOS+) which was set by the above code, has been reset. If an application sets such a trap, and it is not executed, the application should reset it before completion. Simply repeat the code above, with 'errhandle' replaced by 0 (to cause the normal reboot after errors or CTL-C's). The usual usage is in DDTZ, to find the offensive call in an appli- cation. The operator will be confident that DOS+ is executing, and will probably already know the address returned by the 210 call above, say 'E800'. Thus, with the application loaded, in DDTZ, do -s e81e E81E 00 38 (to trap to DDTZ step mechanism) E81F 00 . -g100 (to start the application, possibly after an 'I' command to set the command line) and the error will trap to DDTZ. At this point the displayed instruction, stack etc. will be that AFTER the DOS+ call would have completed normally (DDTZ has processed the stack top to extract this information), and the CDE registers hold the calling state. Any further error or CTL-C will now behave normally (trap is reset). This process is logically equivalent to setting a trap at location 5 which only executes when the DOS+ call would have created an error. BEWARE that FCB's passed may now be in an invalid state. No file operations should be performed until DOS+ has rebooted (or a disk reset call executed). É