[Enter Andy Roony] Did you ever call a *DOS BOARD* with a *CP/M MACHINE* and get screen full of *GIBBERISH* that looked something like *THIS*?: ZZDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?? 33 NEW DOORS AND AN RLE CONFERENCE HAVE BEEN SET UP.... 33 @@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDYY ZZDDDDDDDDDDDDDDDDDDD?DD?? ZDOOR...... 33TRY THEM OUT.......3 33 ZDOOR... BATCH transfers @@DDDDDDDDDDDDDDDDDDDYDDYY ZZDDDDDDDDDDDDDDDDDDDD??DD????DD?? 33THEY NEED USER INPUT33 3333 33 ADVENTURES!!! * -QWIKMAIL>>>>> @@DDDDDDDDDDDDDDDDDDDDYYDDYYYYDDYY [Exit A.R] Well, those screens look OK with the IBM extended character set, but what about the rest of us? Well, no miracles, but surely the situa- tion could be improved somewhat: ++------------------------------------------------------++ || NEW DOORS AND AN RLE CONFERENCE HAVE BEEN SET UP.... || ++------------------------------------------------------++ ++-------------------+--++ ZDOOR...... ||TRY THEM OUT.......| || ZDOOR... BATCH transfers ++-------------------+--++ ++--------------------++--++++--++ ||THEY NEED USER INPUT|| |||| || ADVENTURES!!! * -QWIKMAIL>>>>> ++--------------------++--++++--++ ---- Those aren't really "D"'s, etc. coming thru in the first example- they just appear that way after stripping the valuable 8th bit identi- fying it as a deviant graphic character. Contained herein is a tiny (1/2k) program that will sit in the top of your memory and remap these characters into more useful ones. It turns out that a fairly aesthe- tic approximation of the originally desired effect can be achieved with a combination of only three standard characters: "-", "|", and "+". As supplied, the program does exactly such an remapping of char- acters. All codes intercepted with values higher than 128 decimal are instantly remapped into an appropriate substitute, in real time. The RUN-DMC, uh, RUN-ZMP program provided will quietly locate itself in high memory and then automatically load the ZMP modem program (the specifics can be changed, as described later). You may then call DOS boards and enjoy a much, er, somewhat healthier experience. [Note: You must configure ZMP *not* to remove the parity bit for this to work. This is done by setting the (P)arity selection to NO in the (S)ystem submenu of the (C)onfiguration menu]. Fortunately, ZMP has this option and it thus works quite nicely with this program. In theory, the concept can be extended to work with MEX or IMP as well. Unfortunately, experiments seem to indicate that both of those communication programs strip the high bit before sending it to the console, regardless of the setting of the their respective 'control character filter' switches, so someone will have to find a byte some- where to patch preventing this if successful operation is expected. Technical details: The resident portion of CORK is written as 'position independent' code; it will run *anywhere* in memory (no page boundarys even requir- ed). When initiated, the CORK loader section moves the resident part to a position 1/2k below BDOS, reducing your TPA by that small amount. It then patches several vectors (details below). Control is then transferred to the high memory code, which then searches for a speci- fied file (eg ZMP.COM). The current drive/user is searched first; then a user defined alternate drive and user. When the target program is found, it is loaded at 100H and control is transferred to it, where it runs normally - 'unaware' that CORK is intercepting and converting console characters on their way out. CORK also intercepts whatever method the program chooses to exit with; when this occurs, CORK re- stores all vectors to their original values ('releasing' memory in the process) and then actually does exit back to the operating system. CORK patches the BDOS jump vector at 0005, both to enable it to inter- cept BDOS console output calls and to properly reflect the reduced TPA size. The program will intercept both BDOS calls 2 (Console Output) and 6 (Direct Console I/O). It will also intercept console output made via the BIOS jump table. For exit purposes, the program will intercept a plain RET, a jump to zero or BIOS+3, or a BDOS call 0, in case anyone does that. One other thing: Immediately after it is initiated, CORK copies all of the low memory area containing the 'command tail' information (FCB's, command tail itself, etc.) to the page of memory just below where it is about relocate itself. Later, just before handing control over to the 'target' program, this information is restored. Thus the target program will be supplied with any filenames or other information spec- ified on the command line when CORK was initiated, just as if the program had been initiated normally. This LBR contains the CORK source and two assembled COM files, subse- quently renamed. The COM files are identical except that one (RUN- ZMP) was assembled from CORK.Z80 with "ZMP.COM" filled in as the as the target program, and the other (TIPE) was assembled with "TYPE.COM" as the target (both were assembled with "A0" as the alternate DU, btw). Typing RUN-ZMP (perhaps rename it ZM or something) will bring up the ZMP modem program ('available separately' -:) but allow easier communication with DOS boards. The other program is really more of a demo, but could actually be used in to type files with DOS character graphics (a small section of one such file I ran across is included). The TYPE.COM included is simply C. Falconer's LT28, though a line which strips the high bit was removed before assembly. TIPE will call TYPE, and makes use of the command tail transfer described above. Try "TYPE DEMO.TXT" and then "TIPE DEMO.TXT" and notice the difference. Disclaimer: This program was written partly as a solution for myself to a specific problem and partly just as a seed for the idea of remap- ping graphics characters. While I have every reason to believe the program should run on any standard CP/M system and it has been tried by a number of people, keep in mind that it is 'messing with your system' a bit so, as they say, "Standard disclaimers apply"... If it doesn't work, figure out why and let me know.... NOTE: The program will not even *come close* to running without a Z80; for one thing it is inherently based on relative jumps. The program *will* check the Z80 condition, and abort gracefully with no message if running on an 8080/8085. (In fact, it will abort quietly with no message if almost anything else is wrong also, but there isn't much to go wrong. Most likely it can't find the target program to run). Assembly: If you want to change the alternate DU's or the name of the target program to be loaded or the character remapping table, you will need to reassemble the source code provided. Also note an assembly option that should be set to TRUE if your terminal will display the 7F character ('rubout') as a solid grey or white box. This will result in improved performance, and is *not* assumed in the COM files con- tained here. First edit any changes desired into CORK.Z80; it's pret- ty self explanatory. Then assemble. The nature of the position inde- pendent code makes this a snap; no PRL's, ZRL's, RSX's, GENSYS's, weird linker commands, debuggers, special programs, etc. With SLR: Z80ASM CORK That's it; wait 2 seconds for the resulting COM file. For M80: M80 =CORK.Z80 and then, with either L80 or LINK L80 CORK/N,CORK/E or: LINK CORK You may want to rename the resulting CORK.COM to something convenient. Obvious enhancement: While "+", "-", and "|" do an adequate job, my console, like many others, does have some character graphic capabili- ties. The program as it stands now cannot make use of these because of it's limitation of one-to-one character mapping (I was also inter- ested in keeping the initial version generic). For a system that requires a 'go into graphics mode' escape sequence, the program could be modified to put out that sequence when necessary. A flag internal to the remapping program could keep track of the current mode, and only inject the extra characters when necessary to switch back and forth. Obvious dumbness: Thanks to Ross Pressser who pointed out that my code was organized in a dumb way. While the program must relocate itself to get "out of the way" before loading the target program, there is no reason for the 'target program loader' code to hang out after it's job is done. If it were at the bottom of the relocated section, this would be easy. But alas, for the current version anyway, I added up the bytes and could not quite save a full page (ie make the resident portion 1/4k) and I did not want to change the BDOS jump by some odd amount and I really hope no one needs TPA *that* badly and mostly I was too lazy to rearrange the code at this point... But if enhance- ments get made by myself or anyone else, that's where the extra room can come from. - Steven Greenberg 14 December 1988