MaxZ80 - Chapter 17 Let's talk about RDUMP. Here's a screen shot. 6:16 A0:MOUSE>rdump sil:rdump12k.sil -p -l1 Rec 58 0 1 2 3 4 5 6 7 8 9 A B C D E F 1D00: 29 20 0D 0A 63 68 61 72 20 2A 6F 70 3B 0D 0A 7B ) ..char *op;..{ 1D10: 0D 0A 69 66 20 28 2A 6F 70 3D 3D 27 42 27 29 20 ..if (*op=='B') 1D20: 7B 0D 0A 20 70 75 74 73 74 72 28 22 59 6F 75 20 {.. putstr("You 1D30: 6D 61 79 20 75 73 65 20 65 69 74 68 65 72 20 2D may use either - 1D40: 73 6E 6E 20 6F 72 20 2D 6C 6E 6E 2C 20 62 75 74 snn or -lnn, but 1D50: 20 6E 6F 74 20 62 6F 74 68 21 22 29 3B 0D 0A 20 not both!");.. 1D60: 71 75 69 74 28 29 3B 0D 0A 20 7D 0D 0A 69 66 20 quit();.. }..if 1D70: 28 21 73 65 61 72 63 68 28 2A 6F 70 2C 22 48 53 (!search(*op,"HS Dumping SIL:RDUMP12K.SIL - ^C, Esc, X or Q to quit; Any other key to continue Rec 59 0 1 2 3 4 5 6 7 8 9 A B C D E F 1D80: 4C 50 22 2C 34 29 29 20 7B 0D 0A 20 70 75 74 73 LP",4)) {.. puts 1D90: 74 72 28 22 55 6E 72 65 63 6F 67 6E 69 7A 65 64 tr("Unrecognized 1DA0: 20 6F 70 74 69 6F 6E 20 6F 72 20 6E 6F 20 66 69 option or no fi 1DB0: 6C 65 20 6E 61 6D 65 20 67 69 76 65 6E 21 20 55 le name given! U 1DC0: 73 65 20 2D 68 20 66 6F 72 20 68 65 6C 70 2E 22 se -h for help." 1DD0: 29 3B 0D 0A 20 71 75 69 74 28 29 3B 0D 0A 20 7D );.. quit();.. } 1DE0: 0D 0A 7D 0D 0A 0D 0A 1A 1A 1A 1A 1A 1A 1A 1A 1A ..}............. 1DF0: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................ 6:16 A0:MOUSE> As you can see, RDUMP "dumps" records of a file, in hex and ASCII. Text files may be viewed with the builtin TYPE or transient TYPE.COM, so RDUMP is usually run against .COM files (although our example is showing it dumping its own source code). RDUMP is worth talking about at this stage because it introduces several new things and, hopefully, now that you've read sixteen Chapters, gives you a second look at many old ones. 1. RDUMP is written in a language called SIL which is both a subset of C and an extension to C. It has several non-standard elements you need to watch out for. The documentation (SIL.DOC and SILNOTES.DOC) is excellent. For example, single, not double, ampersands and long vertical marks are used to do logical comparisons. It's an extension to C because of the supplied relocatable library SILLIB.REL which among other things has many CP/M specific functions. We use bdos(), cmndline() and search(). 2. RDUMP is our second example of how to link a tiny "Z3HDR" file into an executable so you can access the Z-System environment segment. It's written in assembler language and assembled into a .rel file. cseg zentry:: jp $+0dh db 'Z3ENV' db 3 dw 0 dw zentry end Here's the code that declares the needed variables and loads the environment address that the command processor stuffs into location hex 109. int *z3envp; char *z3env; z3envp=zentry+9;z3env=*z3envp; /* get z3 environment address */ Here's one of the lines that uses the above. if (z3env>0) showname();else putstr("RDUMP"); The showname() function, which needed to be written, includes, among other things, the following: char *efcb; efcbp=*z3envp+@24; /* get ext fcb ptr */ efcb=*efcbp; /* get external fcb */ i=1; putstr(" "); while ((*(efcb+i)&@7f)!=' '&i<9) { /* mask off hi bit and stop after 8 - note: sil uses & instead of && */ putchar(*(efcb+i)&@7f); i++; } The @ in front of the 24 is the way SIL codes hex numbers. Note the "bitwise" and (&) in the while condition as well as the "logical" and (also &, which in standard C is &&). This is just "our old friend" External File Control Block that we saw in Chapter 11 when we were getting the name the BASIC program SKUNK was invoked with. 3. CP/M can be counted on to put, at hex address 5c, a copy of any string which starts with the first non-blank character following your command itself. The string ends as soon as a blank is found. CP/M also puts, at hex address 6c, a copy of any string following this string. These two addresses are called FCB1 and FCB2, which stands for File Control Block. RDUMP used to use this fact to grab the name of the file to be dumped and also an optional command line parameter. The single original command line parameter was +offset or -offset, where offset was a decimal number of records. This supported dumping starting at 3 records past the beginning of a file to the end of the file or 9 records before the end of a file to the end of the file. Unfortunately, if you want to have more than one option, you can't use this FCB approach. The 36 bytes starting at hex 5c are still used by RDUMP, in fact, quite heavily, as, not only is the name of the file stored here, but disc allocation block information and a few other things are here as well. 4. We added a sorely needed pause option, -p, as well as ways to abort a dump. 5. Take a look at SIL.SUB. Here's what it looks like after the comments are stripped out. SIL $1 N E P300 SOP $1 XIZ $1 ZDE $1.Z80 ZASM $1 PROLINK READ RDK The first line compiles the program, generating an .ASM file, which is an assembler language source file. The next line optimizes this .ASM file. The next line converts the .ASM into a Zilog mnemonics .Z80 file. The next line runs the full screen editor ZDE against the file, allowing you to do last minute adjustments, specifically, letting you change the line that reads MACLIB SILZ80 to one that reads *MACLIB SILZ80 a requirement of ZASM, a Z80 assembler. The MACLIB library statement loads SILZ80.LIB which defines many MACROs that SIL generates. Finally PROLINK runs, an L80-like linker. PROLINK is well documented here as well. One of the things PROLINK can do is READ a "link script," in this case, RDK.LNK. This file has commands that PROLINK understands. .+ .4/9/2006 ORIGIN 100 LINK Z3HDR,RDUMP12K SEARCH SILLIB OUTFIL RDUMP12K EXIT So, not only is RDUMP a handy tool, but the tools used to build it are impressive as well! |