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

  1. >>>>>>>>>>>>>>>>>>>>> CP/M-Net News <<<<<<<<<<<<<<<<<<<<<<<<
  2.  
  3. ============================================================
  4. Number 1              January, 1980        Volume 1, Issue 1
  5. ============================================================
  6.  
  7.  Printed  monthly  (at worst quarterly) to inform user's  of 
  8. RCPM Systems to the latest software news,  information,  and 
  9. updates   of   public   domain   software   accessible   via 
  10. telephone/modem transfer.  Yearly subscription for copies of 
  11. the  CP/M-Net News may be obtained by mailing $18.00  (check 
  12. or money orders only) to Kelly Smith,  CP/M-Net,  3055  Waco 
  13. Avenue,  Simi Valley,  California 93063.  CP/M-Net is a non-
  14. profit  orginization and all money received on subscriptions 
  15. are utilized for the sustaining and enhancments of the CP/M-
  16. Net System.
  17.  
  18.  If  you  would  like to contribute an  article,  include  a 
  19. column containing your area of interest and   expertise,  or 
  20. participate  in an open forum for conversation and  transfer 
  21. of  ideas,  feel free to send it to the CP/M-Net System  and 
  22. indicate  that you would like it to be included in the CP/M-
  23. Net News...if possible,   use WordStar (trademark,  MicroPro 
  24. International)  or  Electric  Pencil   (trademark,   Micheal 
  25. Shrayer) in 60 column format.
  26.  
  27. Note: CP/M is a registered trademark of Digital Research
  28.  
  29.  
  30.                MODEM/XMODEM Protocol Explained
  31.                by Kelly Smith, CP/M-Net "SYSOP"
  32.                       January 8,1980
  33.  
  34.  I  thought that it may be of some interest to those of  you 
  35. that  use  the MODEM/XMODEM file transfer capability of  the 
  36. CP/M-Net,  to get a little insight as to the  communications 
  37. protocol  (i.e.  "handshaking  method") used by the  system. 
  38.  
  39.  Herein  lies the details of a very good (not perfect)  data 
  40. communications  protocol  that  has become  the  "de  facto" 
  41. standard  for various remote CP/M systems (RCPM's) that  are 
  42. accessible across the country (refer to RCPMLST5.DOC on  all 
  43. RCPM's  for access numbers and note that the "digit  number" 
  44. in that list changes as new system are listed).  I also wish 
  45. to give credit to Ward Christensen (the "original" CBBS) for 
  46. writing  MODEM.ASM (CPMUG Volume 25.11) and Keith  Petersen, 
  47. Bruce Ratoff, Dave Hardy, Rod Hart, Tom "C" (we know who you 
  48. are Tom!),  and others,  for enhancements to Ward's original 
  49. program that we now call XMODEM (external modem).
  50.  
  51.  Data is sent in 128 byte blocks with sequentially  numbered 
  52. blocks, and appended by a single checksum at the end of each 
  53. block. As the receiving computer acquires the incoming data, 
  54. it  performs it's own checksum and upon each completion of a 
  55. block,  it  compares it's checksum result with that  of  the 
  56. sending  computers.  If  the receiving computer matches  the 
  57. checksum of the sending computer, it transmits an ACK (ASCII 
  58. code protocol character for ACKNOWLEDGE (04 Hex, Control-F)) 
  59. back to the sending computer.  The ACK therefore means "alls 
  60. well  on  this  end,  send  some  more...".  Notice  in  the 
  61. following example,  that the sending computer will  transmit 
  62. an  "initial  NAK"  (ASCII protocol character  for  NEGATIVE 
  63. ACKNOWLEDGE (15 Hex,  Control-U))...or,  "that wasn't  quite 
  64. right, please send again". Due to the asynchronous nature of 
  65. the  initial  "hook-up"  between  the  two  computers,   the 
  66. receiving  computer  will "time-out" looking for  data,  and 
  67. send the NAK as the "cue" for the sending computer to  begin 
  68. transmission. The  sending computer knows that the receiving 
  69. computer  will  "time-out",  and uses this fact to  "get  in 
  70. sync"...The  sending computer responds to the "initial  NAK" 
  71. with  a  SOH  (ASCII code protocol character  for  START  OF 
  72. HEADING (01 Hex,  Control-A)), sends the first block number, 
  73. sends the 2' complement of the block number (VERY important, 
  74. I will discuss this later...), sends 128 bytes of 8 bit data 
  75. (thats  why  we can transfer ".COM" files),  and  finally  a 
  76. checksum,  where  the checksum is calculated by summing  the 
  77. SOH,  the block number, the block number 2's complement, and 
  78. the 128 bytes of data.
  79.  
  80. Receiving Computer:
  81.  
  82. ----/NAK/------------------------/ACK/----------------------
  83.      15H                          06H 
  84.  
  85. Sending Computer:
  86.  
  87. --------/SOH/BLK#/BLK#/DATA/CSUM/---/SOH/BLK#/BLK#/DATA/etc.
  88.          01H 001H 0FEH 8bit 8bit     01H 002H 0FDH 8bit ....  
  89.  
  90.  This  process continues,  with the next 128 bytes,  IF  the 
  91. block  was ACK'ed by the receiving computer,  and  then  the 
  92. next sequential block number and it's 2's complement, etc.
  93.  
  94.  But  what  happens  if the  block  is  NAK'ed?...easy,  the 
  95. sending computer just re-sends the previous block.  Now  the 
  96. hard  part...what if the sending computer transmits a block, 
  97. the  receiving computer gets it and sends an  ACK,  but  the 
  98. sender  does not see it?...The sending computer thinks  that 
  99. it   has  failed  and  after  10  seconds  re-transmits  the 
  100. block...ARGH!...the  receiving  computer has  "stashed"  the 
  101. data  in  memory or on disk (data is written to  disk  after 
  102. receiving 16 blocks),  the receiving computer is now 1 block 
  103. AHEAD of the transmiting computer!  Here comes the operation 
  104. of the block numbers...The receiver detects that this is the 
  105. last  block  (all over again),  and transmits back  an  ACK, 
  106. throws   away   the  block,   and   (effectively)   "catches 
  107. up"...clever!  Whats more, the integrity of the block number 
  108. is verified by the receiving computer, because it "sums" the 
  109. SOH  (01 Hex) with the block number plus the 2's  complement 
  110. of  the  block number),  and the result MUST BE zero  for  a 
  111. proper  transfer  (e.g.  01+01+FE hex =  00,  on  the  first 
  112. block). The sequence of events then, looks like this: 
  113.  
  114. Receiving Computer:
  115.  
  116. ----/ACK/-----------------------/NAK/-----------------------
  117.      06H                         15H  
  118.  
  119. Sending Computer:
  120.  
  121. CSUM/---/SOH/BLK#/BLK#/DATA/CSUM/---/SOH/BLK#/BLK#/DATA/etc.
  122. 8bit     01H 003H 0FCH 8bit 8bit     01H 003H 0FCH 8bit ....
  123.  
  124.  Normal completion of data transfers will then conclude with 
  125. an  EOT (ASCII code protocol END OF  TRANSMISSION,  04  Hex, 
  126. Control-D)  from the sending computer,  and a final ACK from 
  127. the  receiving computer.  Unfortunately,  if  the  receiving 
  128. computer  misses the EOT,  it will continue to wait for  the 
  129. next block (sending NAK's every 10 seconds,  up to 10 times) 
  130. and eventually "time-out".  This is rarely the case however, 
  131. and  although  not  "bullet-proof",  it is a  very  workable 
  132. protocol.
  133.  
  134. Receiving Computer:
  135.  
  136. ----/ACK/---/ACK/"Transfer Complete"/A>(or B>)
  137.      06H     06H ................................
  138.  
  139. Sending Computer:
  140.  
  141. CSUM/---/EOT/---/A>(or B>)
  142. 8bit     04H .............
  143.  
  144.  In   some  case,   where  the  telephone  transmission   is 
  145. repeatedly  "trashed" (weak signals,  multiple noise "hits", 
  146. etc.),   the  receiving  computer  (and  operator)  will  be 
  147. provided the option to quit.  Here,  the operator enters "R" 
  148. or  "Q" in response to "Retry or Quit?" (after 10  retries), 
  149. and  if quit is envoked by the operator,  a CAN (ASCII  code 
  150. protocol CANCEL, 18 Hex, Control-X) is sent by the receiving 
  151. computer to cancel the entire transfer session (Note:  is is 
  152. possible   to  "garble"  an  ACK  to  a   CAN,   and   abort 
  153. prematurley):
  154.  
  155. Receiving Computer:
  156.  
  157. ----/NAK/...NAK's ten times.../"Retry or Quit?"(Q)/CAN/A>...
  158.      15H                                           18H
  159.  
  160. Sending Computer:
  161.  
  162. CSUM/---/...Garbled Data....../-----------------------/A>...
  163. 8bit
  164.  
  165.  A final considerations when using the MODEM program,  is  a 
  166. timing related problems when transfer status messages and/or 
  167. textual  data is directed to the screen of a slow (4800 Baud 
  168. or less) terminal or to a hard copy printer. This problem is 
  169. readily  apparent (multiple NAK's) when using MODEM for  the 
  170. first time, and can usually be "cured" by NOT SPECIFYING the 
  171. "V"  (video)  sub-option when sending  or  receiving  files. 
  172. Users  of  Lifeboat  Associates  BSTAM  encounter  the  same 
  173. problem, but this is easily fixed with the files TQPATCH.ASM 
  174. and  RQPATCH.ASM  (transfer quiet/receive quiet) that  Keith 
  175. Petersen (Royal Oak CP/M,  "call-back" remote system, (313)-
  176. 588-7054)  wrote to solve the problem of low speed  terminal 
  177. I/O.
  178.  
  179.  For users of CBBS's that do not have MODEM.ASM (but DO HAVE 
  180. a  CP/M disk system...ESSENTIAL!),  let me suggest that  you 
  181. "data  capture" the file MBOOT3.ASM from one of  the  RCPM's 
  182. (it's  a small 8 kilo-byte file that "fits" in most system's 
  183. memory) to get the larger MODEM.ASM (40  kilo-bytes).  Check 
  184. it  very carefully for errors using the "data capture" (read 
  185. ERROR  PRONE method here).  Then edit and assemble for  your 
  186. modem  configuration.
  187.  
  188.  If  you are tired of buying software where the advertisment 
  189. is written better than the program, then the RCPM's are just 
  190. what you have been looking for...and FREE!
  191.  
  192. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  193.  
  194.  
  195.              Software Tricks for the 8080/Z80
  196.  
  197.                            by
  198.  
  199.                Kelly Smith, CP/M-Net "SYSOP"
  200.  
  201.                      January 8, 1980
  202.  
  203.  In  my  travels  through the  software  written  by  others 
  204. (articles,  disassemblies,  etc.),  I  occasionaly find some 
  205. "tricks"   incorporated  to  either  optimize  the   storage 
  206. requirements of the code (typically ROM based) or to attempt 
  207. to  confuse  disassembly...although they are not recommended 
  208. routines, I think you may find them of interest...
  209.  
  210.                       The LXI Trick
  211.  
  212.  Many  large mainframe computers (mini's and maxi's) have  a 
  213. SKIP   instruction...but   most   micro's   are   multi-byte 
  214. instruction  oriented,  and  therefore it  is  difficult  to 
  215. provide    a   SKIP   when   the   instruction   length   is 
  216. indeterminate. First, an example of "straight" coding:
  217.  
  218. error1:   mvi  a,1  ; set-up error code 1
  219.           jmp  error$handler
  220. error2:   mvi  a,2  ; set-up error code 2
  221.           jmp  error$handler
  222. error3:   mvi  a,3  ; set-up error code 3, and fall into it
  223. ;
  224. error$handler:      ; all error codes come here
  225. ;
  226.           lxi  d,error$message     ; point to error message,
  227.                                    ; error code in A reg.
  228.           .
  229.           .
  230.           .
  231.  
  232.  
  233.  This  is easy enough to understand (right?),  but  consider 
  234. this:
  235.  
  236. lxib      equ  1    ; equate first byte of LXI b,nnnn
  237. ;
  238. error1:   mvi  A,1  ; set-up error code 1
  239.           db   lxib ; first byte of LXI B,nnnn
  240. error2:   mvi  A,2  ; set-up error code 2
  241.           db   lxib ; first byte of LXI B,nnnn
  242. error3:   mvi  A,3  ; set-up error code 3
  243.           lxi  d,error$message     ; point to error message,
  244.                                    ; error code in A reg.  
  245.           .
  246.           .
  247.           .
  248.  
  249.  If a jump is made to ERROR1, the E Reg. is set-up, then the 
  250. LXIB will be executed, the B&C Regs. will be given "garbage" 
  251. code that follows it,  and finally the program counter  will 
  252. be  incremented  past the next instruction...it  SKIP's  and 
  253. falls   into  the  eventual  output  routine...insidious  to 
  254. disassemblers!  This  was  one of the "favorite's"  at  MITS 
  255. (remember the Altair?).
  256.  
  257.                      The ORI Trick
  258.  
  259. You might code:
  260.  
  261. and$function:       ; indicate boolean AND
  262. ;
  263.           mvi  a,1       ; set flags to non-zero, this is AND
  264.           jmp  do$boolean; do boolean function
  265. ;
  266. or$function:        ; indicate boolean OR
  267. ;
  268.           xra  a         ; set flags to zero, this is OR
  269. ;
  270. do$boolean:         ; boolean functions come here
  271. ;
  272.           your code...   ; do something...anything!
  273.           .
  274.           .
  275.           .
  276.  
  277.  
  278. But consider the following:
  279.  
  280. ori  equ  0f6h      ; equate first byte of ORI n
  281. ;
  282. and$function:       ; indicate boolean AND
  283. ;
  284.           db   ori       ; set flags with A reg. not zero,
  285.                     ; first byte of ORI
  286. or$function:        ; indicate boolean OR
  287. ;
  288.           xra  a         ; set flags to zero, this is OR
  289. ;
  290. do$boolean:         ; boolean functions come here
  291. ;
  292.           your code...   ; is everyone confused?
  293.           .
  294.           .
  295.           .
  296.  
  297.  This   one  is  particulary  clever;   when   entering   at 
  298. AND$FUCTION,  the  ORI picks-up the "XRA A" as F6  Hex,  and 
  299. automatically  set's the flags non-zero. Let me suggest that  
  300. if  you actually use the LXI or ORI trick...comment  it WELL  
  301. in   your   source  code...you may  have   to   patch   your 
  302. program YEARS LATER, and will this look strange !?!
  303.  
  304.  
  305.                       Using XTHL
  306.  
  307.  A  "cute"  (not fast) example for register "swapping"  when 
  308. all  registers  are  used and must be  saved,  is  shown  as 
  309. follows:
  310.  
  311. exchange$bc$with$hl:     ; exchange B&C Regs. with H&L Regs.
  312. ;
  313.           push b    ; put B&C Regs. on the stack
  314.           xthl      ; H&L Regs. = top stack entry = B&C Regs.
  315.           pop  b    ; B&C Regs. = original H&L Regs.
  316.  
  317.  Very  often you will code a routine to pass a constant to a 
  318. subroutine, such as:
  319.  
  320.           mvi  c,1
  321.           call dumb$subroutine
  322.           .
  323.           .
  324.           .
  325.           mvi  c,2
  326.           call dumb$subroutine
  327.           .
  328.           .
  329.           .
  330.           mvi  c,3
  331.           call dumb$subroutine
  332.           .
  333.           .
  334.           .
  335. ;
  336. dumb$subroutine:    ; use argument passed in C reg.
  337.           .
  338.           .
  339.           .
  340.  
  341.  
  342.  By manipulating the return address,  you can save one  byte 
  343. per CALL as follows:
  344.  
  345.           call trick$subroutine
  346.           db   1       ; put constant in "return" location
  347.           .
  348.           .
  349.           .
  350.           call trick$subroutine
  351.           db   2       ; put constant in "return" location
  352.           .
  353.           .
  354.           .
  355.           call trick$subroutine
  356.           db   3       ; put constant in "return" location
  357.           .
  358.           .    
  359.           .
  360. ;
  361. trick$subroutine:   ; trick subroutine to get constant
  362. ;
  363.           xthl      ; H&L Regs. = return address
  364.           mov  c,m  ; get constant pointed to by H&L Regs.
  365.           inx  h    ; bump for return address
  366.           xthl      ; restore the return address and H&L Regs.
  367. ;
  368. dumb$subroutine:    ; use argument passed in the C Reg.
  369. ;
  370.           .
  371.           .
  372.           .
  373.  
  374.  
  375.                The "Indirect Jump" via the Stack
  376.  
  377.  Try  this trick to save a few bytes,  by faking a "indirect 
  378. jump" via the stack...you might code this routine:
  379.  
  380.           call get$data$word
  381.           jmp  use$data$word
  382. ;
  383. get$data$word: ; get word into H&L regs.
  384. ;
  385.           lhld my$data$word   ; fetch my data word
  386.           ret
  387. ;
  388. use$data$word: ; use data word in H&L Regs.
  389.  
  390.  
  391.  But a more "elegant" (though obtuse) method could be  coded 
  392. as this:
  393.  
  394.           lxi  h,use$data$word     ; make "indirect address"
  395.           push h    ; save it on the stack
  396. ;
  397. get$data$word: ; get word into H&L Regs.
  398. ;
  399.           lhld my$data$word   ; fetch my data word
  400.           ret        ; pop stack for address and "jump"
  401.  
  402.  This  can lead to even trickier manipulations on the  stack 
  403. for return address's...everyone (at one time or another) has 
  404. coded  a  routine to "filter" keyboard  characters,  and  it 
  405. usual looks like this:
  406.  
  407.           cpi  '.'  ; period character?
  408.           jz   filter
  409.           cpi  ','  ; comma character?
  410.           jz   filter
  411.           cpi  ';'  ; semicolon character?
  412.           jz   filter
  413.           cpi  ':'  ; colon character?
  414.           jz   filter
  415.           .
  416.           .
  417.           .
  418.  
  419.  
  420.  But  we  need  to save some bytes,  so we get  tricky  with 
  421. coding like this:
  422.  
  423.           lxi  b,filter  ; make "FILTER" address
  424.           push b    ; put "FILTER" address on the stack
  425.           cpi  '.'  ; period character?
  426.           rz        ; pop stack and go, if match
  427.           cpi  ','  ; comma character?
  428.           rz        ; pop stack and go, if match
  429.           cpi  ';'  ; semicolon character?
  430.           rz        ; pop stack and go, if match
  431.           cpi  ':'  ; colon character?
  432.           rz        ; pop stack and go, if match
  433.           pop  b    ; no match...adjust the stack
  434.           .
  435.           .
  436.           .
  437.  
  438.  A popular method for "In line" printing of messages in CP/M 
  439. applications program, is as follows:
  440.  
  441.           call start     ; go to START, after message
  442.           db   'My Junk Program, Version 1$'
  443. ;
  444. start:    pop  d    ; get address of message string
  445.           mvi  c,2  ; CP/M print string function
  446.           call 5    ; let CP/M do the work
  447.           .
  448.           .
  449.           .
  450.  
  451.  
  452.                     Register "Moving"
  453.  
  454.  The tricky way to move the D&E Regs.  to B&C Regs might  be 
  455. as follows:
  456.  
  457.           push d
  458.           pop  b
  459.  
  460. But the obvious way (and faster) is just:
  461.  
  462.           mov  d,b
  463.           mov  e,c
  464.  
  465.  
  466.  A really tricky programmer could use the PUSH/POP method to 
  467. affect   the   condition   code...this   "blows-away"   even 
  468. experienced  programmers when they encounter it in  someones 
  469. code!...watch this:
  470.  
  471.           mvi  c,081h    ; the "flags"
  472.           .
  473.           .
  474.           .
  475.           push b         ; use "cunning set-up" to confuse
  476.           .
  477.           .
  478.           .
  479.           pop  psw       ; do it to it!
  480.           .
  481.           .
  482.           .
  483.  
  484.  This  has the effect of moving the B reg.  into the A Reg., 
  485. and moving the C Reg.  into the PSW (flags),  with the carry 
  486. and sign bits SET (sign is minus), and all other flags reset
  487. to zero's...this trick causes most programmers to mumble for 
  488. hours...
  489.  
  490. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  491.  
  492.               Helpful CP/M Tip-of-the-Month
  493.  
  494.  Have  you  ever  fired-up Digital  Research's  DDT  or  SID 
  495. program  debugger's,  specifying the program to debug...It's 
  496. loads,  then goes '?' ,  because it can't find the file, and 
  497. it's  really  on the other diskette (let's say B:)  in  your 
  498. system !?!  So you Control-C out (back to CP/M) and PIP  the 
  499. program to the proper diskette...ARGH!
  500.  
  501.  So use DDT or SID,  to CHANGE the logged in drive number to 
  502. get  to the file you want...Let's assume that we are  logged 
  503. on  to  the A:  drive,  and our target file to debug  is  on 
  504. B:...follow along:
  505.  
  506. A>DDT BUMBFILE.COM<cr>
  507. DDT VERS 2.0
  508. ?
  509. -
  510.  
  511.  So  here we sit (not the least bit  amused),  contemplating 
  512. our navels...DO THIS!
  513.  
  514. -IBUMBFILE.COM<cr>  {set-up temporary FCB with filename.typ}
  515. -S5C<cr>            {Substitute starting at address 5C Hex}
  516. 005C 00 02<cr>      {set drive number 2 (B: disk)}
  517. 005D 42 .<cr>       {quit substituting}
  518. -R<cr>              {Read BUMBFILE.COM}
  519.  
  520.  As  if by magic,  the debugger will log on to the B:  disk, 
  521. grab the file,  and read it in for your debug  session!  All 
  522. you have to remember, is that at address 5C Hex is the start 
  523. of the temporary file control block, and that:
  524.  
  525.      01 equals A: disk
  526.      02 equals B: disk
  527.      03 equals C: disk
  528.      .
  529.      .
  530.      .
  531.      So on, and so on for up to 16 disk drives...
  532.  
  533.  
  534. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  535.