home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / news / cpmnet81.feb < prev    next >
Text File  |  1994-07-13  |  21KB  |  567 lines

  1.  
  2. >>>>>>>>>>>>>>>>>>>>> CP/M-Net News <<<<<<<<<<<<<<<<<<<<<<<<
  3.  
  4. ============================================================
  5. Number 2          February,1981       Volume 1, Issue 2
  6. ============================================================
  7.  
  8.  Printed  monthly  (at worst quarterly) to inform user's  of
  9. RCPM Systems to the latest software news,  information,  and
  10. updates   of   public    domain     software   accessible     via
  11. telephone/modem transfer.  Yearly subscription for copies of
  12. the  CP/M-Net News may be obtained by mailing $18.00  (check
  13. or money orders only) to Kelly Smith,  CP/M-Net,  3055    Waco
  14. Street,  Simi Valley,  California 93063.  CP/M-Net is a non-
  15. profit    orginization and all money received on subscriptions
  16. are utilized for the sustaining and enhancments of the CP/M-
  17. Net System.
  18.  
  19.  If  you  would  like to contribute an    article,  include  a
  20. column    containing your area of interest and  expertise,  or
  21. participate  in an open forum for conversation and  transfer
  22. of  ideas,  feel free to send it to the CP/M-Net System  and
  23. indicate that you would like it to be included in the  CP/M-
  24. Net  News...if possible,  use WordStar (trademark,  MicroPro
  25. International)    or  Electric  Pencil   (trademark,   Micheal
  26. Shrayer) in 60 column format.
  27.  
  28. NOTE: CP/M is a registered trademark of Digital Research
  29.  
  30. ============================================================
  31.  
  32.                On the Stack
  33.                ============
  34.  
  35.  Many  thanks to the following supporting subscribers to the
  36. CP/M-Net News:
  37.  
  38. Brent Crable, Crable Enterprises
  39. Eddie Currie
  40. John T. Powers, Jr.
  41. Pete Mack, Mack Associates
  42.  
  43.  Note:     Back  issues  for  the  CP/M-Net  News  Letter  are
  44. available  for    two  dollars  each.  Back  issues  currently
  45. available are:
  46.  
  47.     January 1981, Number 1, Volume 1, Issue 1
  48.  
  49. MODEM/XMODEM Protocol Explained
  50. Software Tricks for the 8080/Z80
  51. CP/M Tip-of-the-Month, 'Changing logged disks in DDT or SID'
  52.  
  53. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  54.  
  55.             Software "Bug" Report
  56.  
  57.     Microsoft MBASIC.COM version 5.03 [CP/M Compatible]
  58.  
  59. Reported By: Kelly Smith, January 11, 1981
  60. Application: Any
  61.  
  62.  When  utilizing the SAVE function under MBASIC.COM  version
  63. 5.03,  DO  NOT use lower case for the filename...it will  be
  64. placed    in  the  CP/M  directory  in  lower  case,  and  any
  65. subsequent  attempt  to "read-it-in" again with MBASIC    will
  66. result in a "File not found" error!  The only way to get rid
  67. of  it (kill it in the directory) is to ERA  *.BAS<cr>,  and
  68. this  will (of course) clobber all other ".BAS"  files.  Sam
  69. Singer's  DUMP.COM (CPMUG Volume 14.7) program can  also  be
  70. used to "erradicate" the file...
  71.  
  72. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  73.  
  74.        What to do about CP/M's "SYNCRONIZATION ERROR"
  75.        (SYSGENing CP/M Version 2.2, from Version 1.4)
  76.           by Kelly Smith, CP/M-Net "SYSOP"
  77.  
  78.  
  79. Question:
  80.  
  81.  "How in the #*@%!  do I SYSGEN CP/M Version 2.2 on my    CP/M
  82. 1.4 system, when using it's MOVCPM (to generate a new system
  83. image),   and  the  &%#"*@  thing  keeps  coming  back    with
  84. SYNCRONIZATION ERROR, and then promptly HALTS!"
  85.  
  86. The Problem:
  87.  
  88.  Those    clever people at Digital Research have embedded  the
  89. serial    number    (issued to YOU I hope!)  in  MOVCPM.COM,  to
  90. discourage  the "rip-off" of CP/M by someone other than  the
  91. rightful  owner...when    MOVCPM is executed,  it looks for  a
  92. match of it's serial number to that of the host system (your
  93. CP/M  Version  1.4)  as it appears in  your  system  memory,
  94. detects that a "mismatch" has occurred,  and promptly locks-
  95. up  your  computer...ARGH!   "You mean I have to write    that
  96. crummy "GETSY" and "PUTSYS" stuff to SYSGEN from 1.4 to  2.2
  97. ???" we ask ourselves...
  98.  
  99. The Solution:
  100.  
  101.  Fake-out  #1...your CP/M Version 2.2 as supplied by Digital
  102. Research,  is  SYSGEN'd  for a 20 Kilo-byte  Intel  MDS  800
  103. system...so write a 20 Kilobyte BIOS (and BOOT loader), then
  104. do as follows to get a 20 Kilo-byte CP/M 2.2 system image...
  105.  
  106. A>B:<cr>    <--- Switch from A (CP/M 1.4) to B (CP/M 2.2)
  107. B>SYSGEN    <--- Use CP/M 2.2's SYSGEN to get a system image    
  108. SYSGEN VER 2.0
  109. SOURCE DRIVE NAME (OR RETURN TO SKIP)B <--- Get it...
  110. FUNCTION COMPLETE
  111. DESTINATION DRIVE NAME (OR RETURN TO REBOOT)<cr> <--- Return
  112. A>SAVE 34 B:CPM20.COM <--- Save the CP/M 2.2 system image
  113.  
  114.  O.K.,    now  SYSGEN normally on the B drive,  with  your  20
  115. Kilo-byte BIOS (and BOOT loader)...
  116.  
  117.  Fake-out  #2...Ah  hah,  so this is NOT your copy (I  know,
  118. your  doing this for a friend...) of CP/M Version  2.2,  and
  119. it's  been SYSGEN'd for something OTHER THAN a 20  Kilo-byte
  120. system...double ARGH!  All is not lost however,  just follow
  121. the  (less  than  simple) sequence that  follows  using  the
  122. MOVPATCH.ASM   file   that  is    listed    after    the   SYSGEN
  123. sequence...  A word of CAUTION however! Some implementations
  124. of MOVCPM.COM NOT DIRECTLY SUPPLIED by Digital Research have
  125. been "fiddled"...the address referenced in MOVPATCH.ASM that
  126. follows  WILL  NOT  be the  same...Lifeboat  Associates  has
  127. modified   MOST  versions  of MOVCPM.COM that I  have  seen,
  128. for particular applications (i.e., double density, etc.).
  129.  
  130. A>DDT B:MOVCPM.COM<cr> <--- Get the CP/M 2.2 MOVCPM in...
  131. DDT VERS 1.4
  132. NEXT  PC
  133. 2800 0100
  134. -IMOVPATCH.HEX <--- Set-up the MOVCPM patch
  135. -R<cr> <--- Read it in
  136. NEXT  PC
  137. 2800 0000
  138. -XP<cr> <--- We need to reset the program counter
  139. P=0000 100<cr> <--- Set it back to address 0100 Hexadecimal
  140. -G<cr> <--- Go execute MOVCPM...
  141.  
  142. CONSTRUCTING 56k CP/M VERS 2.2 <--- Making my system size...
  143. READY FOR "SYSGEN" OR
  144. "SAVE 34 CPM56.COM"
  145. A>B: <--- It was faked-out, switch to drive B
  146. B>SAVE 34 CPM56.COM<cr> <--- Save the CP/M 2.2 system image
  147. B>DDT CPM56.COM<cr> <--- Bring in the new system image
  148. DDT VERS 2.2 <--- The "new" DDT announcing itself...
  149. NEXT  PC
  150. 2300 0100
  151. -ISBOOT56.HEX<cr> <--- My BOOT loader
  152. -R900<cr> <--- Offset required for BOOT loader position
  153. NEXT  PC
  154. 2300 0000
  155. -ICBIOS56.HEX<cr> <--- My 56 Kilo-byte BIOS
  156. -R4580<cr> <--- Offset for 56 Kilo-byte BIOS position
  157. NEXT  PC
  158. 2300 0000
  159. -G0<cr> <--- "Warm boot" your CP/M 1.4 system...
  160. B>SYSGEN<cr> <--- Use CP/M 2.2 SYSGEN to generate the system
  161. SYSGEN VER 2.0 <--- The "new" SYSGEN announcing itself...
  162. SOURCE DRIVE NAME (OR RETURN TO SKIP)<cr> <--- Return
  163. DESTINATION DRIVE NAME (OR RETURN TO REBOOT)B <--- Put on B
  164. DESTINATION ON B, THEN TYPE RETURN<cr> <--- Return
  165. FUNCTION COMPLETE
  166. DESTINATION DRIVE NAME (OR RETURN TO REBOOT)<cr> <--- Return
  167. A> <--- Return to your "old" CP/M version 1.4...
  168.  
  169.  O.K.,    now remove the CP/M 1.4 disk from the A  drive,  and
  170. remove    the  CP/M 2.2 from the B drive,  insert it in the  A
  171. drive and do a "cold boot"...hereafter,  MOVCPM will operate
  172. normally, so no need to go thru the MOVPATCH routine...
  173.  
  174.  
  175.     MOVPATCH.ASM for MOVCPM.COM CP/M Version 2.2
  176.  
  177. Note:  you MUST SET "msize" for your intended system  memory
  178. size  to  make this work...assemble normally with  the    CP/M
  179. Version  1.4  "ASM.COM"  file.    MOVPATCH.ASM  may  not    work
  180. with  copies of MOVCPM.COM that are NOT SUPPLIED by  Digital
  181. Research.
  182.  
  183.  
  184. msize    equ    56    ;put your memory size HERE...
  185.  
  186.     org    05ch    ;absolute file control block address
  187.  
  188.     db    20h,'0'+msize/10,'0'+msize mod 10,20h
  189.  
  190.     org    232h    ;serial number string length check
  191.  
  192.     xra    a    ;set flags
  193.  
  194.     org    2c4h    ;serial number match check
  195.  
  196.     lxi    h,1200h ;force MOVCPM to look at it's
  197.             ;own serial number...
  198.  
  199.     end
  200.  
  201. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  202.  
  203.        Loading DDT Without 'Clobbering' the CCP
  204.            by Kelly Smith, CP/M-Net "SYSOP"
  205.               January 25, 1981
  206.  
  207.  
  208.  From  time  to time,  I need to do  some  'special  tricks'
  209. within    CP/M itself to modify it's operation to do something
  210. other  than  what  Digital Research  had  intended.  If  you
  211. attempt  to load DDT 'normally',  it 'clobbers' the  Console
  212. Command   Processor  by  overlaying  it  with    DDT...making
  213. modification (using DDT) impossible.  This program will load
  214. Digital  Research's  Dynamic Debugging    Tool  (DDT)  without
  215. overlaying the CP/M Console Command Processor, and works for
  216. CP/M  version 1.4 AND 2.0 through 2.2...Be sure and set  the
  217. equate    MSIZE  for  your particular CP/M  system  size,  for
  218. proper operation...name it to something like  'DDTLOAD.ASM',
  219. assemble and load...then execute it as follows:
  220.  
  221.               A>DDTLOAD<cr>
  222.  
  223.  DDT  will  now  load into memory  'nomally',  but  will  be
  224. relocated BELOW the CCP. Here's the software to do it...
  225.  
  226. true    equ    -1    ;define true
  227. false    equ    not true;define false
  228. cpm14    equ    false    ;true if CP/M vers 1.4
  229. cpm22    equ    true    ;true if CP/M vers 2.2
  230. ;
  231. msize    equ    56    ;must be set for YOUR CP/M system size
  232. ;
  233. base    equ    0    ;CP/M system base address
  234. ;
  235.     if    cpm14
  236. cbase    equ    base+2900h    ;base of 16k CP/M 1.4 CCP
  237. bias    equ    (msize-16)*1024 ;offset for system
  238. nbase    equ    cbase+bias-10h    ;new base address
  239.     endif
  240. ;
  241.     if    cpm22
  242. cbase    equ    base+3400h    ;base of 20k CP/M 2.X CCP
  243. bias    equ    (msize-20)*1024 ;offset for system
  244. nbase    equ    cbase+bias-10h    ;new base address
  245.     endif
  246. ;
  247.     org    base+100h
  248. ;
  249.     lhld    base+6    ;move old BDOS address to new BDOS entry
  250.     shld    nbase+1 ;swap new base address into original base
  251.     shld    base+6
  252.     mvi    m,jmp    ;make 'jump' opcode to new base address
  253.     lxi    h,'3D'-'0'    ;create DDT command in
  254.                 ;console input buffer
  255.     shld    cbase+bias+7
  256.     lxi    h,'DT'
  257.     shld    cbase+bias+9
  258.     xra    a    ;make 'EOL' as null for message end
  259.     sta    cbase+bias+11
  260.     mvi    a,8    ;reset command pointer
  261.     sta    cbase+bias+136
  262.     lda    base+4    ;select current drive
  263.     mov    c,a
  264.     jmp    cbase+bias    ;all parameters set, load DDT
  265.  
  266.     end
  267.  
  268. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  269.  
  270.     Using CP/M's Undocumented "Autoload" Feature
  271.            by Kelly Smith, CP/M-Net "SYSOP"
  272.  
  273.  Ever wished you could just slam a diskette into your drive,
  274. boot it,  and have it immediately start executing a  program
  275. for you...or the kids want to play some nifty game, but your
  276. tired  of having your diskettes trashed 'cause your 14    year
  277. old   boy  does not understand the full implications of  ERA
  278. *.*...?!?  Well here's a little known feature of CP/M that's
  279. worth knowing...it has a BUILT IN AUTOLOAD!
  280.  
  281.  I  don't know why Digital Research fails to document  this,
  282. for public consumption (?),  they include the information in
  283. their  OEM  distribution  documentation,  but  not  anywhere
  284. else...and how many of us are OEM distributers?  Well,    here
  285. are  the details of "autoload",  and how to implement it  on
  286. your CP/M system.
  287.  
  288.  First, take a "scratch" diskette and do a full disk copy of
  289. your CP/M system diskette (this includes the system tracks).
  290. If you don't have a disk copy program,    SYSGEN the "scratch"
  291. diskette  and PIP all the stuff to it.    Now,  stick the  new
  292. diskette  (to be set-up for "autoload") in drive  A:,  "warm
  293. boot"  it  (Control-C)    and let's assume  that    we  want  to
  294. "autoload"   Microsoft's   MBASIC   and  have    it   execute
  295. STARTREK...Here's what you do:
  296.  
  297.  
  298. A>ddt movcpm.com<cr> <--- We need to "patch" MOVCPM.COM
  299. DDT VERS 2.2
  300. NEXT  PC
  301. 2800 0100         <--- Write down '2800' someplace
  302. -d0a00<cr>         <--- Dump starting at address 0A00 Hex
  303.  
  304.  Here  is the start of CP/M (this is CP/M Version  2.2,  but
  305. this "method" will work for CP/M Version 1.4 just as well):
  306.  
  307.      .___ CCP jump entry (normal entry)
  308.      :
  309.      :          .___ CCP jump entry to bypass "autoload"
  310.      :          :
  311.      :          :        .___ 128 characters allowed for command
  312.      :          :        :
  313.      :          :        :  .___ Number of characters in filename
  314.      :          :        :  :
  315.      :          :        :  :  .___ Start of filename to "autoload"
  316.      :          :        :  :  :
  317.      :          :        :  :  :
  318. 0A00 C3 5C 03 C3 58 03 7F 00 20 20 20 20 20 20 20 20 .\..X...    
  319. 0A10 20 20 20 20 20 20 20 20 43 4F 50 59 52 49 47 48         COPYRIGH
  320. 0A20 54 20 28 43 29 20 31 39 37 39 2C 20 44 49 47 49 T (C) 1979, DIGI
  321. 0A30 54 41 4C 20 52 45 53 45 41 52 43 48 20 20 00 00 TAL RESEARCH  ..
  322. 0A40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  323. 0A50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  324. 0A60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  325. 0A70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  326. .
  327. .
  328. .
  329.  
  330.  O.k.,    now that we see that much, let's patch MOVCPM.COM to
  331. do the "autoload" of MBASIC.COM and STARTREK.BAS...
  332.  
  333. -s0a07<cr>    <--- Substitute, starting at address 0A07 Hex
  334. 0A07 00 0f<cr>    <--- 15 characters in filenames to "autoload"
  335. 0A08 20 4d<cr>    <--- ASCII 'M'
  336. 0A09 20 42<cr>    <--- ASCII 'B'
  337. 0A0A 20 41<cr>    <--- ASCII 'A'
  338. 0A0B 20 53<cr>    <--- ASCII 'S'
  339. 0A0C 20 49<cr>    <--- ASCII 'I'
  340. 0A0D 20 43<cr>    <--- ASCII 'C'
  341. 0A0E 20 <cr>    <--- We needed a 'SPACE', so leave as is...
  342. 0A0F 20 53<cr>    <--- ASCII 'S'
  343. 0A10 20 54<cr>    <--- ASCII 'T'
  344. 0A11 20 41<cr>    <--- ASCII 'A'
  345. 0A12 20 52<cr>    <--- ASCII 'R'
  346. 0A13 20 53<cr>    <--- ASCII 'T'
  347. 0A14 20 54<cr>    <--- ASCII 'R'
  348. 0A15 20 45<cr>    <--- ASCII 'E'
  349. 0A16 20 4B<cr>    <--- ASCII 'K'
  350. 0A17 20 .<cr>    <--- Quit substituting
  351. -d0a00<cr>    <--- Let's "Dump" what we just entered...
  352.  
  353.  
  354.               .___ 15 characters in MBASIC STARTREK
  355.               :
  356.               :  .___ Start of MBASIC STARTREK
  357.               :  :
  358.               :  :
  359. 0A00 C3 5C 03 C3 58 03 7F 0F 4D 42 41 53 49 43 20 53 .\..X...MBASIC.S
  360. 0A10 54 41 52 54 52 45 4A 20 43 4F 50 59 52 49 47 48 TARTREK.COPYRIGH
  361. 0A20 54 20 28 43 29 20 31 39 37 39 2C 20 44 49 47 49 T (C) 1979, DIGI
  362. 0A30 54 41 4C 20 52 45 53 45 41 52 43 48 20 20 00 00 TAL RESEARCH  ..
  363. 0A40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  364. 0A50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  365. 0A60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  366. 0A70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  367. .
  368. .
  369. .
  370.  
  371.  Keep    in  mind,   that  you  are  not  limited   to    just
  372. filenames...you  could    just as well "autoload"  and  envoke
  373. submit files (including command strings),  whatever, and can
  374. completely "overlay" Digital Research's copyright notice and
  375. use  as many ASCII character entries as are required...don't
  376. substitute passed address 0A7F Hex however!
  377.  
  378.  Now  exit DDT (Control-C<cr> or G0<cr>),  and let's look at
  379. the  number that you wrote down...it's there on that   piece
  380. of paper, next to the beer can...
  381.  
  382.  Hmmm...says  2800...o.k.,  multiply the 2  by 16 (for those
  383. that are on beer number 7,  that's 32...the number 7 is  (as
  384. everyone  knows) "Kelly's Konstant").  Now since the  8 ends
  385. in two zeros,  subtract 1 from 8 (that leaves  7,  for those
  386. of  you  that smoke the "funny stuff")...now add 32   and  7
  387. together...errr...ahhhh...FAR  OUT!...39!   Now follow along
  388. closely:
  389.  
  390. A>save 39 trekload.com<cr>
  391.  
  392.  We  just  saved 39 pages (256 bytes/page)  of    the  patched
  393. MOVCPM.COM...and    for    reference,     renamed    it      to
  394. TREKLOAD.COM...now  SYSGEN  your  diskette (however  you  do
  395. that) with TREKLOAD instead of MOVCPM,    and "cold boot"  the
  396. diskette.
  397.  
  398.  It  should "boot" with MBASIC being executed,    then  MBASIC
  399. takes over and loads in STARTREK,  and then you are ready to
  400. "zap" some Klingons!
  401.  
  402. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  403.  
  404.       A Simple Subroutine to Check for "Stack Overflow"
  405.            by Kelly Smith, CP/M-Net "SYSOP"
  406.  
  407.  Here    is  a  simple  subroutine  to  be  CALLed  in    your
  408. applications   program    to  check  for    a  possible   "stack
  409. overflow"  condition.  This  subroutine might be  especially
  410. helpful during the "debug stage" of your software where  you
  411. may not be sure of your total stack requirements...you could
  412. make  CALLs  to "check$stack" from numerous places  in    your
  413. software  as  a monitor of stack allocation,  and  by  using
  414. conditional assemblies, REMOVE all the CALLs when your debug
  415. is  completed.    Other applications,  include stack  oriented
  416. languages such as STOIC,  FORTH or PASCAL where some heavily
  417. "compute   bound"  applications  programs  could  eventually
  418. "gobble up" memory and clobber the operating system.
  419.  
  420.  I  wrote  a simple test program with which you can  use  to
  421. verify    the operation of "check$stack"...the exit  on  "blow
  422. up",  resets  the stack pointer to the "old stack"  pointer,
  423. then displays 'Stack Over-Flow, Depth = nn' (where nn equals
  424. the  "stack  depth"  in  hexadecimal for  up  to  256  stack
  425. "levels").  Remember  that  the  stack    works  DOWN  towards
  426. (typically)  your  applications  program...leave  sufficient
  427. code  between the "stack$end" and "oldstk" so (at worst) you
  428. can  exit  on  stack  overflow    "gracefully"...you   clobber
  429. "oldstk", and all bets are off.
  430.  
  431. ;
  432. ;This  is the test for "check$stack"...with 'debug' false,
  433. ;the  program  will exit to CP/M with the  stack  overflow
  434. ;message.
  435. ;
  436. true    equ    -1    ;define true
  437. false    equ    not true;define false
  438. debug    equ    false    ;define debug (if true, makes sufficient stack)
  439.  
  440.     org    100h
  441.  
  442.     lxi    h,0    ;save "old" CP/M stack pointer
  443.     dad    sp
  444.     shld    oldstk
  445.     lxi    sp,stack;set "local" stack
  446.     call    test
  447.     lhld    oldstk
  448.     sphl
  449.     ret
  450. ;
  451. test:    call    test1
  452.     call    check$stack
  453. test1:    call    test2
  454.     call    check$stack
  455. test2:    call    test3
  456.     call    check$stack
  457.     ret
  458. test3:    ret
  459. ;
  460. ;end  of test on "check$stack",  incorporate the following code 
  461. ;for your particular application...with a little more  thought, 
  462. ;you  could also display the address of the last CALL prior  to 
  463. ;the  "stack overflow",   and thereby let your program tell you 
  464. ;WHERE it BLEW UP...I will leave that exercise for you.
  465. ;
  466. check$stack:        ;check to see if stack pointer is below STACK$END
  467. ;
  468.     push    h    ;save H$L Regs.
  469.     lxi    h,-stack$end    ;won't work for STACK$END = 0000
  470.     dad    sp
  471.     pop    h    ;restore H$L Regs.
  472.     rc        ;return if still o.k.
  473. ;
  474. ;come here on stack over-flow
  475. ;
  476.     lxi    h,0    ;clear H&L Regs.
  477.     dad    sp    ;stack pointer to H&L Regs.
  478.     lxi    d,stack ;get original stack top address
  479.     mov    a,e    ;do 16 bit subtract, to calculate "stack depth"
  480.     sub    l
  481.     mov    e,a
  482.     mov    a,d
  483.     sbb    h
  484.     mov    d,a    ;16 bit result in D&E Regs.
  485.     lhld    oldstk    ;restore "old" CP/M stack pointer
  486.     sphl
  487.     push    d    ;save "stack depth"
  488.     lxi    d,stack$overflow$message
  489.     mvi    c,9    ;display string function
  490.     call    5    ;let CP/M do the work...
  491.     pop    d    ;recover "stack depth"
  492. ;
  493. display$stack$depth:    ;display up to 256 deep stack digits
  494. ;
  495.     mvi    c,2    ;display 2 digits
  496.     push b ! push d ;save 2 digit count and "stack depth"
  497.     mov    a,e    ;get hexadecimal digit
  498.     rar ! rar ! rar ! rar    ;display high nibble first...
  499. ;
  500. hexascii:        ;convert 1 digit hexadecimal to 1 digit ASCII
  501. ;
  502.     ani    0fh    ;mask for low nibble position
  503.     adi    90h    ;convert hex digit to ASCII digit
  504.     daa
  505.     aci    40h
  506.     daa
  507.     mov    e,a    ;pass to CP/M in E reg.
  508.     mvi    c,2    ;display character function
  509.     call    5    ;let CP/M do the work...
  510.     pop d ! pop b    ;get "stack depth" and digit count
  511.     dcr    c    ;debump digit count
  512.     rz        ;return to CP/M, if both digits displayed
  513.     push b ! push d ;not yet, so display second digit
  514.     mov    a,e    ;get hexadecimal digit
  515.     jmp    hexascii;display and exit to CP/M, next time thru...
  516. ;
  517. stack$overflow$message: ;indicate stack overflow
  518. ;
  519.     db    0dh,0ah,'Stack Over-Flow, Depth = $'
  520. ;
  521. oldstk: ds    2    ;storage for "old" CP/M stack pointer
  522. ;
  523.     ds    32    ;"dummy" program storage
  524. ;
  525. stack$end    equ    $    ;stack end
  526.  
  527.     if    debug    ;if debug,
  528.     ds    32    ;16 level stack
  529.     else        ;else,
  530.     ds    2    ;1 level stack
  531.     endif
  532.  
  533. stack    equ    $    ;stack starts here
  534. ;
  535.     end
  536.  
  537. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  538.  
  539.          CP/M-Net "Tip-of-the-Month"
  540.  
  541.  Ever  wished  you  could REPEAT  a  program  over-and-over,
  542. without  having  to go through typing in  the  filename  and
  543. waiting for it to load? This "program" uses no memory space,
  544. and "loads" very fast...it WILL NOT WORK however on programs
  545. that require secondary commands (e.g.,    where the program is
  546. instructed  to operate on some file or parameter,  after the
  547. invocation  of the initial program name at the    CP/M  system
  548. prompt).  Let's  assume that you are logged on to drive  A:,
  549. then:
  550.  
  551. A>SAVE 0 @.COM     <--- save the arbitrary filename "@.COM"
  552. A>FORMAT<cr>     <--- we want to FORMAT a stack of diskettes
  553. A>@<cr>      <--- we want to do it again...
  554. A>@<cr>      <--- ...and again...
  555. A>@<cr>      <--- ......and again!
  556.  
  557.  What  happens,  is that the Console Command Processor (CCP)
  558. picks-up  the  filename "@"...passes it to  the  Basic    Disk
  559. Operating  SYSTEM (BDOS),  the BDOS "matches" it as being  a
  560. valid  file  in  the directory of your    diskette,  loads  it
  561. (nothing to load,  because it has "0" file size), then jumps
  562. to  address  100 Hex (where the previous file  is  still  in
  563. memory), and executes the "old" file...Simple!
  564.  
  565. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  566.  
  567.