home *** CD-ROM | disk | FTP | other *** search
-
- >>>>>>>>>>>>>>>>>>>>> CP/M-Net News <<<<<<<<<<<<<<<<<<<<<<<<
-
- ============================================================
- Number 3 March, 1981 Volume 1, Issue 3
- ============================================================
-
- In This Issue
- =============
-
- The Famous UP-Arrow Story - Michael J. Karas
-
- CP/M Bit Map File Allocation...EXPLAINED!
-
- A Simple 6 Byte Hexadecimal to ASCII Conversion Routine
-
- A CP/M 1.4 Parameter Display Program in Microsoft Basic
-
- CP/M-Net 'Tip-of-the-Month', 64 character wide DDT or SID
-
-
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-
- The Famous UP-Arrow Story
- =========================
- by
- Michael J. Karas
-
- Some time ago, while working at a job that I would just as
- soon forget, the famous up-arrow incident took place. My
- desk happened to be right next to that of Kelly Smith,
- editor of the CP/M Net (tm) News. Kelly had been spending a
- large amount of his time working on a diagnostics software
- package for the company's business computer. (The now known
- PCC 2000.) Building a diagnostics package can be creative
- and on one particular day Kelly wanted to show me how some
- of the softare worked. In other words he wanted me to see
- some of the creativity that he had put into this software
- package.
-
- I went over to his computer setup to look at the CRT screen
- while he showed me the Memory Display/Alter routine he had
- made. After observing for a short time I asked how do you
- back up to the previous memory address if you enter the
- wrong data. His response was that you terminated the current
- entry sequence and reentered the errored memory address. I
- decided that it would be nice if there was a key that would
- allow you to simply backup to the previous address.
-
- After lunch, (Kelly usually seemed to pound away at the
- keyboard all during lunch in those days;) Kelly asked me if
- a newly modified version of his Display Alter Routine solved
- my problem. I tried it out and found that while entering
- data with the memory display/alter command that use of the
- up-arrow (^) key would cause the displayed address to back
- up to the previous address. A very useful feature I decided.
- Kelly's only comment was that some people get their gibblets
- jiggled in the most strange ways. Anyway, to this day the
- monitors in all of my personal computers contain a memory
- display/alter routine with the up-arrow.
-
- These days I don't usually use the monitors anymore due to
- the fact that I have disks and thus access to DDT, Digital
- Research's Diagnostic Debugging Tool. The "S" command of DDT
- does not have the capability to offer the up-arrow attribute
- to ease the pain of putting in the wrong value for a memory
- byte. So I took it upon myself to change DDT so that it
- would do "Up-Arrow".
-
- If you should desire to "jiggle your giblets" while using
- the DDT Version 1.4 debugger package then you will have to
- do a little work for the "jigglin'". The rest of this
- article describes how to make DDT react to up-arrow.
- Operating instructions are at the end of the installation
- procedure. Note that this patch is specifically tailored to
- DDT Version 1.4 and may not work with other versions. The
- short program below should be edited into a file using your
- favorite editor with the name "DDTPATCH.ASM". It should then
- be assembled into a ".HEX" file using an assembler. Use
- particular care to get all of the strange equated numbers at
- the beginning exactly right.
-
- ;****************************************************************
- ; PATCH TO GIVE SET MEMORY COMMAND BACKUP CAPABILITY
- ; IN DDT VERSION 1.4.
- ;****************************************************************
- ;
- ;
- WBOOT EQU 00000H ;WARM BOOT ENTRY ADDRESS
- BDOS EQU 00005H ;BDOS ENTRY ADDRESS
- TPA EQU 00100H ;START OF TRANSIENT PROGRAM
- ;
- ;
- CMNDLP EQU 06FEH ;LOCATION OF COMMAND LOOP START
- ;(IN ABSOLUTE DDT IMAGE)
- ;
- DISPLP EQU 0A7EH ;LOCATION OF DISPLAY LOOP START
- ;(IN ABSOLUTE DDT IMAGE)
- ;
- PATCH EQU 0A91H ;LOCATION OF PATCH IN MEMORY ALTER
- ;(IN ABSOLUTE DDT IMAGE)
- ;
- ASCHEX EQU 0C53H ;LOCATION OF CONVERSION ROUTINE
- ;(IN ABSOLUTE DDT IMAGE)
- ;
- ENDDDT EQU 0FD0H ;LOCATION OF END OF DDT 1.4
- ;(IN ABSOLUTE DDT IMAGE)
- ;
- ORG TPA+1 ;FIX OLD DDT 1.4 MODULE SIZE
- ;
- DW 0FB6H+028H ;NEW MODULE SIZE WITH PATCH
- ;
- ORG PATCH+200H ;OFFSET ASSEMBLY AREA
- ;
-
- POP H
- CALL CHARIN-200H ;GO TO NEW ROUTINE TO GET CHAR
- ;
- CPI 0DH ;IS INPUT CHAR A CARRIAGE RETURN?
- JZ INCMADR-200H ;GO TO INCREMENT TO NEXT ADDRESS
- ;
- CPI '.' ;IS INPUT THE EXIT PERIOD?
- JZ CMNDLP ;GO BACK TO DDT'S COMMAND LOOP
- ;
- CPI '^' ;IS INPUT AN UPARROW TO BACKUP
- JZ DECMADR-200H ;GO TO DECREMENT TO PREV ADDRESS
- CALL ASCHEX ;GO TO ASCII TO HEX CONVERSION
- RLC ;ADJUST HEX FOR HIGH NIBBLE
- RLC
- RLC
- RLC
- MOV D,A ;SAVE HIGH NIBBLE
- CALL CHARIN-200H ;GET ASCII FOR LOW CHAR
- CALL ASCHEX ;GO TO ASCII TO HEX CONVERSION
- ORA D ;COMBINE LOW AND HIGH NIBBLES
- NOP ;FIX PATCH SIZE TO FIT IN DDT 1.4
- MOV M,A ;PUT NEW VALUE INTO MEMORY
- INCMADR:
- INX H ;INCREMENT FOR NEXT MEMORY ADDRESS
- JMP DISPLP ;GO DISPLAY NEXT MEM ADDRESS
- ;
- ;
- ;CODE TO BE PATCHED IN AT END OF DDT PROGRAM. THESE ROUTINES
- ;ADD THE CAPABILITY TO GET SINGLE CONSOLE CHARACTERS AND TO
- ;DECREMENT THE CURRENTLY DISPLAYED MEMORY ADDRESS IN THE DDT
- ;SET MEMORY COMMAND.
- ;
- ORG ENDDDT+200H
- ;
- CHARIN:
- PUSH D ;SAVE POSSIBLE HIGH NIBBLE
- PUSH H ;SAVE CURRENT MEMORY ADDRESS
- MVI C,01H ;SET BDOS FUNCTION FOR CONIN
- CALL BDOS ;USE BDOS FOR CONSOLE INPUT
- POP H
- POP D
- RET
- DECMADR:
- DCX H ;DECREMENT MEMORY ADDRESS
- JMP DISPLP ;GO DISPLAY THE PREVIOUS MEM ADDRESS
- ;
- END
- ;
- ;
-
- Once you have made the hex file, then put a copy of it on a
- CP/M system disk along with your copy of DDT version 1.4.
- Boot up this disk in drive A: and carefully follow the
- installation instructions below. If you are not currently
- familiar with the operation of DDT now would be a good time
- to get the manual out and read it. We will be using DDT to
- make a patched version of itself. The sequence below must be
- followed exactly. The notation <cr> indicates that you
- should enter carriage return. The part of the text that the
- system types versus the part that you type should be obvious
- if you are familiar with DDT.
-
- A>
- A>DDT<cr> <== Invoke DDT
- DDT VERS 1.4
- -IDDT.COM<cr>
- -R<cr> <== Read in a copy of DDT.COM
- NEXT PC
- 1400 0100
- -S1308<cr> <== Change bit map for patch
- 1308 92 88<cr>
- 1309 08 42<cr>
- 130A 44 12<cr>
- 130B 48 02<cr>
- 130C 40 .<cr>
- -F13AC,13B0,00<cr> <== Fill in new zeros to map
- -S13B1<cr> <== Add a new bit to map
- 13B1 00 04<cr>
- 13B2 00 .<cr>
- -M11B6,1400,1A00<cr> <== Move bit map out of way
- -IDDTPATCH.HEX<cr>
- -R<cr> <== OVerlay DDT.COM with patch
- NEXT PC
- 1400 0000
- -M1A00,2000,11DE<cr> <== Move bit map into place
- -^C <== Bale out of DDT to System
- A>SAVE 19 DDTP.COM<cr> <== Save patched DDT
-
- You are now ready to try out the patched version of DDT.
- For the most part DDT will operate just like before. The new
- version will modify the way that the "S" substitute memory
- command functions. The command is invoked just as before (-
- Saaaa<cr> aaaa=desired address). When DDT responds with a
- display of the memory address and its contents it will enter
- a mode waiting for operator input. Four different things can
- be entered at this point:
-
- a) A <cr> may be entered to cause the contents of the next
- memory address to be displayed.
-
- b) A "." may be entered to cause DDT to return back to the
- command mode. Note that the patched DDT does not need a
- <cr> after the "." to return to the command or prompt
- mode.
-
- c) A "^" may be entered to cause DDT to display the contents
- of the previous memory address. This is the back-up mode.
- Note that the backup is immediate and does not require a
- <cr> after it.
-
- d) A two digit hexadecimal value may be entered to modify
- the contents of the currently displayed memory location.
- The digits must be 0-9;A-F or DDT will display a "?" and
- return to the prompt mode. The second entered digit will
- be taken immediately and will change the memory contents.
- The next higher address will then be displayed.
-
- I hope you enjoy the up arrow feature as much as I do. Or
- as Kelly Smith would say, "Get your gibblets jiggled."
-
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- CP/M Bit Map File Allocation...EXPLAINED!
- =========================================
- by
- Kelly Smith
-
-
- What It's for...
-
- For each diskette "logged-on" to the CP/M Basic Disk
- Operating System (BDOS), physical diskette space is
- dynamically allocated to that diskette (for later write
- operations) and maintained in memory by Bit Mapped
- Allocation. When changing diskettes (and to avoid the "R/O"
- error message) you must enter Control-C to erase the
- previous diskettes Bit Map, and cause the BDOS to read the
- file directory to establish the new Bit Map. On subsequent
- write operations to the diskette, the Bit Map is modified,
- and the diskette File Control Block (FCB) for the (now
- closed file) is updated in the File Directory.
-
- What It Is...
-
- The Bit Map is actually a tight encoding of available (or
- not) sectors on the diskette. The Bit Map is an array of
- single bits which correspond to each block of eight sectors
- allocated for usage on the diskette. A blank (formatted)
- diskettes Bit Map Allocation array then looks like this:
-
- ("Standard" Single Density IBM Format Diskette)
-
- GROUP ALLOCATION MAP DRIVE - B
- 11000000000000000000000000000000
- 00000000000000000000000000000000
- 00000000000000000000000000000000
- 00000000000000000000000000000000
- 00000000000000000000000000000000
- 00000000000000000000000000000000
- 00000000000000000000000000000000
- 000000000000000000
- 240 GROUPS REMAINING ON DISK OUT OF 243
-
- Notice that two bits are 1's...this predefines allocation
- space for the CP/M Directory for the diskette (i.e., 16
- sectors or 2 groups), and insures that the directory is not
- overwritten when creating new files. All remaining 0's are
- free groups, ready to become allocated in the directory.
- When the BDOS receives a request to create a file, it first
- searches the Bit Map until it finds a bit containing a zero,
- and the number (this will be explained shortly) of this bit
- is the number of the first free group to be allocated for
- the file. The BDOS sets the bit map to a one and places a
- one byte hexadecimal group number into the FCB of the
- directory, created for the new file. As subsequent write
- operations occur for the file, the BDOS examines the last
- group number in the FCB (and also the Next Record count) and
- from the numbers automatically computes the next physical
- track and sector number where the diskette write is to
- occur. Keeping in mind that eight sectors equal one group,
- when all eight sectors of a group have been written, the
- BDOS searches the Bit Map again for the next bit containing
- a zero. When a free allocation is found, its group number is
- added to the FCB (not necessarily a sequential number) and
- the corresponding bit is set to a one. Also note that the
- minimum file size that a file will be, is one kilobyte...a
- file which has seven or fewer sectors will be shown (by STAT
- Filename.Typ<cr>) as utilizing one group (1k); a file which
- has eight sectors will be shown as utilizing two groups,
- even though the second group is empty.
-
- Here is an example of what one sector of the directory
- looks like, showing four FCB's for three files:
-
- Filename.Typ EX RC <--------------Group-------------->
- -------------------------------------------------------
- MACRO .LIB 00 80 45464748 494A4B4C 4D4E4F50 51525354
- MACRO .LIB 01 08 55000000 00000000 00000000 00000000
- PLINK .COM 00 0B 56570000 00000000 00000000 00000000
- DISKTEST.COM 00 09 58590000 00000000 00000000 00000000
-
- Specifically, note that the file MACRO.LIB has two
- entries...and also the Record Count (RC) for the first entry
- is set to 80 hexadecimal. As new records are written to the
- diskette, the RC is updated by the BDOS. When a transition
- occurs from 7F to 80, the BDOS adds a new FCB into the
- directory, and also creates a new extension (EX) to the
- file. Bit Map allocation then proceeds from the next
- available group.
-
- And Why...
-
- As I mentioned, the group allocations may not be sequential
- (even though my example shows sequential groups). As files
- are deleted from the diskette, they leave "holes" in the Bit
- Map to make space available for any new files to be created.
- The major advantage here, is that the disk is never required
- to be "packed down" (i.e., for iCOM FDOS users or UCSD
- Pascal users, you know what I mean!). For users of an
- operating system that utilizes Sequential or Linked
- Allocation methods, my heart goes out to you...nothing quite
- so "gut wrenching" as a disk error in the middle of a pack
- operation! The other advantage to Bit Map Allocation, is
- true random access to sectors (no "kludge" ISAM, as in MITS
- DOS or BASIC and no "rewind file pointers" as in PASCAL),
- and dynamic allocation of file size. Another source of
- frustration regarding Linked Allocations is when an isolated
- sector (which "forward references" the next sector in the
- file) is "bombed"...there is no way to recover the ENTIRE
- file intact...just up to the point of the offending sector!
-
- Now for some detail (as promised): To determine the group
- allocation from the Bit Map, we must first "split" the in
- half...then it all begins to make (I hope) good sense. To
- find the (hexadecimal) group number of an individual bit in
- the Bit Map, take the first digit from the even (or odd)
- half row and the digit from the column in the same half. As
- shown in the example below then, the next free group
- allocation is 02 and the last free group is F1:
-
- GROUP ALLOCATION MAP DRIVE - B
- Even Half Row Columns Odd Half Row
-
- 0123456789ABCDEF 0123456789ABCDEF
- ---------------------------------
- 0 :1100000000000000:0000000000000000: 1
- 2 :0000000000000000:0000000000000000: 3
- 4 :0000000000000000:0000000000000000: 5
- 6 :0000000000000000:0000000000000000: 7
- 8 :0000000000000000:0000000000000000: 9
- A :0000000000000000:0000000000000000: B
- C :0000000000000000:0000000000000000: D
- E :0000000000000000:00 : F
- 240 GROUPS REMAINING ON DISK OUT OF 243
-
- The PHYSICAL relationship of sectors to groups is such that
- Group 02 starts at Track 2/Sector 20, Group 03 starts at
- Track 02/Sector 13 (YES! Sector 13, because of the diskette
- "skew factor"...hmmm, a good topic for yet another mundane
- article on my part...OK, OK,...BORING!), and so on.
-
- In conclusion, Digital Research's CP/M BDOS makes the most
- efficient use of available space on the diskette. Other
- operating systems (let's cuss MITS DOS again!) often require
- that the file size be specified by the user...overcaution
- (and much guessing) results in large amounts of unused
- diskette space that is NOT AVAILABLE to other files. This
- space can only be recovered by copying the data to a new
- diskette with the proper file size specified, and WHATS EVEN
- WORSE is that this same procedure must be followed to EXPAND
- a file that has already utilized the space originally
- allocated to it! So anyway...NICE JOB Dr. Kildall!
-
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-
- A Simple 6 Byte Hexadecimal to ASCII Conversion Routine
- =======================================================
- by
- Kelly Smith (originator of routine unknown)
-
- Only six bytes of 8080 (or Z80) code can perform a
- hexadecimal (0 to F) to ASCII conversion. Assuming that the
- hexadecimal digit is in the A register, then:
-
- hex$to$ascii: ; convert low nibble hex digit in the
- ; the A reg., to ASCII character in the
- ; A reg.
- adi 90h ; first add
- daa ; adjust result, if carry
- aci 40h ; second add, adjust to ASCII
- daa ; adjust result, if carry
- .
- .
- .
-
- How does it work? There are two main considerations for
- hexadecimal to ASCII conversion: Is the A register less than
- ten, or is the A register greater than or equal to ten?
-
- The first DAA instruction (which operates on the lower four
- bits (low nibble)), adjusts the result of the ADI
- instruction to less than ten. Then the ACI instruction
- operates on the upper four bits (high nibble) by adding the
- carry out of the lower nibble. The second DAA instruction
- then adjusts the results of the high nibble to less than 10.
-
- If the A register is initially less than ten, the first add
- results in 9Xh...in this case, the DAA does not affect the A
- register. The second add (with carry) results in 9Xh+40h=DXh
- (D Hex = 13 Dec). After the second DAA, the result is 3Xh
- where 'X' is the decimal digits 0 through 9; thus the ASCII
- representation for decimal digit 9 results in 39
- hexadecimal.
-
- If the A register is initially ten or greater, the first
- add results in 9Xh (same as before), but the result of the
- foqst DAA is 0Yh (i.e., Yh=Xh-10d) and includes the setting
- of the carry flag. The next add (with carry) gives us
- oYh+40h+1=4Zh, where Z=Y+1. The last DAA has no affect...The
- hexadecimal digits 41 to 46 represent the ASCII alphabetics
- A to F...for example, let X=10d=Ah, then Y=X-10d=10d-10d=0
- and Z=Y+1=0+1=1...the result is 41 hexadecimal, the ASCII
- symbol for 'A'...the routine is simpler than the
- explanation!
-
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-
- A CP/M 1.4 Parameter Display Program in Microsoft Basic
- =======================================================
- by
- Kelly Smith (from a program by Rod Hart)
-
- Its not often that you find a really unique utility that
- "crosses boundries" between an operating system and a
- computer language...this one, is particularly "cute" (and
- useful), that I downloaded with XMODEM from Rod Hart's
- system...nice job Rod! My only changes were to make it all
- fit on a 24 by 80 screen display, without using clear screen
- codes that are terminal sensitive. Note also, this WILL NOT
- WORK on CP/M 2.2 parameters! So put your "thinking caps" on,
- write a version for CP/M 2.2, XMODEM it to Rod or myself and
- become FAMOUS (if not rich)!
-
- 10 REM CP/M Version 1.4 System Parameter Display Program
- 20 REM by Roderick W. Hart (WA3MEZ)
- 30 REM December 23, 1979
- 40 REM modified February 8, 1981 by Kelly Smith, CP/M-Net
- 50 PRINT TAB( 10) "Parameters unique to your CP/M Version 1.4 are:"
- 60 BD=PEEK(7)*256
- 70 SP=PEEK(BD+&H3A)
- 80 RB=PEEK(BD+&H3C)
- 90 LS=PEEK(BD+&H3D)
- 100 LB=PEEK(BD+&H3E)
- 110 DL=PEEK(BD+&H3F)
- 120 DT=PEEK(BD+&H40)
- 130 RE=PEEK(BD+&H3B)
- 140 TR=PEEK(BD+&H40)
- 150 MT=(BD+&H1A)
- 160 PRINT:PRINT TAB( 10) "Your BDOS starts at ";HEX$(BD);" hex"
- 180 PRINT TAB( 10) "Your sector map table is located at ";HEX$(MT);" hex"
- 190 PRINT TAB( 10) "Your directory allocation mask is ";HEX$(DL);" hex"
- 200 PRINT TAB( 10) "You have";TR;"tracks reserved for the system"
- 210 PRINT TAB( 10) "You have";SP;"sectors per track"
- 220 PRINT TAB( 10) "You have";RE;"records per extent"
- 230 PRINT TAB( 10) "You have";RB;"records per block"
- 240 PRINT TAB( 10) "Last sector in block is";LS
- 250 PRINT TAB( 10) "Last block on the disk is";LB
- 290 PRINT:PRINT TAB( 24);"Sector Map Table"
- 300 PRINT TAB( 24);"------ --- -----"
- 310 PRINT
- 320 FOR X=0 TO (SP-1)
- 330 MP=PEEK(MT+X)
- 340 Z=Z+5
- 350 IF Z<60 THEN 360 ELSE 390
- 360 PRINT TAB( Z);MP;
- 370 IF X=(SP-1) THEN 410
- 380 NEXT X
- 390 Z=5:PRINT CHR$(15)
- 400 GOTO 360
- 410 END
-
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-
- CP/M-Net "Tip-of-the-Month"
- ===========================
- by
- Kelly Smith and Eddie Currie
-
- Are you one of the "poor unfortunates" that has to contend
- with a 64 character wide screen display, and bashes your
- head against the CRT in front of you (while mumbeling "why
- did I EVER BUY this #`!%&$ THING...it SCREWS UP the DDT
- 'DUMP' display so badly, I can't even use it!"). Well, no
- more tears on the keyboard my friend...just put these
- patches into DDT or SID, and as if by magic (at no time do
- my fingers leave my hands), VOILA...a 64 character wide
- 'DUMP' that you can actually READ!!!...follow along:
-
- For users of DDT.COM version 1.4 or 2.2, make the following
- substitution...
-
- A>ddt ddt.com<cr> <--- patch DDT.COM using DDT
- DDT VER 2.2 <--- DDT announcing itself
- NEXT PC
- 1400 0100 <--- DDT telling us it's used 19 pages
- -sa17<cr> <--- Substitute at address 0A17 hex...
- 0A17 05 08<cr> <--- ...08 instead of 05!
- 0A18 08 .<cr> <--- end the substitution
- -g0<cr> <--- exit DDT and return to CP/M
- A>save 19 ddt64.com<cr> <--- save the 64 wide DDT.COM
-
- And for users of SID.COM...
- A>sid sid.com<cr> <--- patch SID.COM using SID
- SID VER 1.4 <--- SID announcing itself
- NEXT PC END
- 2D00 0100 B3FF <--- SID telling us it's used 44 pages
- #saa5<cr> <--- Substitute at address 0AA5 hex...
- 0AA5 93 96<cr> <--- ...96 instead of 93!
- 0AA6 08 .<cr> <--- end the substitution
- #g0<cr> <--- exit SID and return to CP/M
- A>save 44 sid64.com<cr> <--- save the 64 wide SID.COM
-
- What these patches do, is to throw out the space characters
- between each display of the hexadecimal representation of
- each memory content of the DDT or SID 'DUMP' display...it
- crunches the display format, and make it READABLE!
-
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++