home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / CIS / DOW12.MAC < prev    next >
Text File  |  2000-06-30  |  15KB  |  490 lines

  1. ;****************************************************************************
  2. ; FILE DOWNLOAD UTILITY FOR CIS A PROTOCOL.
  3. ; WRITTEN 3/10/82 BY BOB RICHARDSON
  4. ; COPYRIGHT (C) 1982 PERFORMANCE BUSINESS MACHINES
  5. ; Made available by permission - further distribution must include
  6. ; the original copyright notice and author's name
  7. ; INVOKED BY "DOW FNAME.FTP" AND USES DEFAULT FCB AND COMMAND LINE 
  8. ;         
  9. ;  THIS PROGRAM IS DEPENDENT ON BIOS TO PROVIDE PROPER SUPPORT FOR THE   
  10. ;  MODEM AS A CONSOLE, READER AND PUNCH. THE IOBYTE IS NOT USED.  BYE
  11. ;  WILL PROBABLY WORK, OR THE SOURCE MAY BE MODIFIED TO ACCESS THE SERIAL
  12. ;  STUFF DIRECTLY AND ADD THE CODE TO HANDLE THE UART OR SIO OR WHATEVER
  13. ;            
  14. ;            3/24/82 -- FIRST SOURCE RELEASE
  15. .z80
  16. ;    equates
  17. soh    equ    01h    ; start of header
  18. etx    equ    03h    ; end of text 
  19. eot    equ    04h    ; end of transmission
  20. enq    equ    05h    ; enq char - not used
  21. si    equ    0fh    ; shift in - starts protocol on terminal
  22. so    equ    0eh    ; shift out - ends protocol
  23. ;
  24. knak    equ    15h    ; nak
  25. dle    equ    10h    ; data link escape - used to mask chars for transparency
  26. esc    equ    1bh    ; escape
  27. eof    equ    1ah    ; ctl-z
  28. ctlz    equ    1ah    ; also
  29. cr    equ    0dh    ; carriage return
  30. lf    equ    0ah    ; line feed
  31. tof    equ    0ch    ; top of form
  32. ;
  33. cldboot    equ    00h    ; bios coldboot vector
  34. iobyte    equ    0003h    ; addr of iobyte
  35. deffcb    equ    05ch    ; addr of default fcb
  36. command    equ    080h    ; addr of command line    
  37. bdos    equ    05h    ; addr of bdos jmp 
  38. ; BDOS FUNCTIONS
  39. pstrg    equ    09h    ; print string function
  40. rdcbuf    equ    0ah    ; read console buffer
  41. fn$opn    equ    0fh    ; open file function
  42. fn$rds    equ    014h    ; read sequential disk
  43. fn$std  equ    01ah    ; set dma addr
  44. fn$cls    equ    010h    ; close file
  45. ;
  46. ;
  47. ; BIOS OFFSETS FOR VARIOUS CALLS
  48. const    equ    03h    ; constat call
  49. conin    equ    06h    ; conin
  50. conout    equ    09h    ; character out to console
  51. list    equ    0ch    ; character to line printer
  52. punch    equ    0fh    ; char to punch device
  53. rdr    equ    12h    ; get char from reader device
  54. ;
  55. ;
  56. ; Version Info
  57. vers    equ    '1'    ; ascii version
  58. rev    equ    '2'    ; ascii rev level
  59. ;
  60. ; Historical information
  61. ;        3-21-1982      First complete version assembled and released 
  62. ;                       by the author, Bob Richardson of Micropro Corp.
  63. ;                       any and all source copys must retain this notice and
  64. ;            the copyright notice - this file made available by
  65. ;            permission. 
  66. ;
  67. ;****************************************************************************
  68. ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  69. ;   CODE BEGINS:
  70. ;   MAIN DRIVER LOOP-
  71. downld:
  72.     ld    sp,downld    ; set up local stack for Charlie Strom
  73.     call    announce    ; give copyright notice and rev,vers info    
  74.     call     procol        ; turn on protocol, open file, and start
  75. dowrty:
  76.     call    sndhdr        ; then send or resend protocol header
  77.     call    waitack        ; and wait for ack response
  78.     jp    c,dowrty    ; retry if nak response
  79.     jp    nz,comfail    ; error so dump job
  80. downlp:
  81.     call    getrec        ; get disk record
  82.     jp    nz,fin        ; eof - send eot record
  83. downl1:
  84.     call    putrec        ; send rec
  85.     call    waitack        ; and wait for ack
  86.     jp    c,downl1    ; try resend if nak
  87.     jp    nz,comfail    ; send com failure and abort
  88.     jp    downlp        ; loop till eof
  89. ;
  90. fin:
  91.     call    puteot        ; send eot message
  92.     call    waitack        ; and wait for ack
  93.     jp    c,fin        ; resend if nak
  94.     jp    nz,comfail    ; abort if knak
  95.     call    complete    ; turn off protocol and send all done message 
  96.     jp     cldboot     ; terminate
  97. ;****************************************************************************
  98. ; end of driver - start of worker routines
  99. ;
  100. ;
  101. biosvct:
  102.     ld    hl,(cldboot+1)    ;get start of bios table
  103.     add    hl,de        ; get addr for branch
  104.     jp    (hl)        ; return handled to inline location
  105. ;
  106. ;************************************************************************
  107. ; Get rev and version and copyright notice to operator
  108. announce:
  109.     ld    de,cpyrite        ; copyright notice
  110.     call    prnmes            ; to console
  111.     ret                ; to caller
  112. ;
  113. cpyrite:
  114.     defb    cr,lf,'Download Vers. ',vers,'.',rev,cr,lf
  115.     defb    ' Copyright (C) 1982  PBM Division MicroPro International Corporation ','$'
  116. ;
  117. ;
  118. ;
  119. ;****************************************************************************;
  120. ; test for errors and then kick it off
  121. ;
  122. procol:
  123.     ld    de,deffcb    ; get default fcb
  124.     ld    c,fn$opn    ; open file function
  125.     call    bdos        ; see if we can open file
  126.     cp    04h        ; test for successful open
  127.     jp    nc,nofil    ; send no file message if not found
  128.     ld    a,0        ; get zero
  129.     ld    (deffcb+32),a    ; to current record
  130.     ld    (masking),a    ; and start masking ctl chars in msg text
  131.     call    rmtnm        ; get name for remote terminal
  132.     ld    a,(conbuff+1)    ; start of data in buffer
  133.     ld    c,a        ; is count for move
  134.     ld    b,0        ; with high order=0
  135.     ld    hl,conbuff+2    ; start of actual name
  136.     call    noblnk        ; bypass all blanks
  137.     jp    z,comfail    ; if this passes, we are in TROUBLE - processor
  138.                 ; or operator are down!
  139.     ld    de,filespec    ; addr in esc a message
  140.     push    bc        ; save number of bytes(non space)
  141.     ldir            ; move filespec to message
  142.     pop    hl        ; restore operator count
  143.     ld    a,cr        ; terminate the string with cr
  144.     ld    (de),a        ; in esc a message
  145.     inc    hl        ; correct count to show cr included
  146.     ld    (tmpsav),hl    ; and save for header xmit
  147.     ret            ; and return to caller
  148. ;
  149. ;
  150. ;
  151. tmpsav:
  152.     defw    00h        ; temporary save for count of chars in name
  153. ;
  154. ;*************************************************************************
  155. ; this routine actually turns the protocol on and sends header to terminal
  156. sndhdr:  
  157.     ld    a,si        ; get shift in char
  158.     call     punout        ; send it
  159.     ld    a,esc        ; send esc
  160.     call    punout        ; charge
  161.     ld    a,'A'        ; esc a for message
  162.     call    punout        ; mush ye huskies mush
  163.     ld    hl,(tmpsav)    ; get the restored count from save area
  164.     push    hl        ; compatibility - yes, I know - could be less
  165.     ld    hl,escames    ; get message balance addr
  166.     pop    bc        ; restore count from command line
  167.     ld    a,c        ; get count in accumulator
  168.     add    a,escalen    ; and add in normal length
  169.     ld    b,a        ; get in byte counter
  170.     call    prmesout    ; send message as normal
  171.     xor    a        ; set z flag
  172.     ret            ; and return
  173. ;
  174. noblnk:
  175.     ld    a,(hl)        ; get char
  176.     cp    20h        ; test blank
  177.     ret    nz        ; non blank
  178.     dec    c        ; reduce count
  179.     ret    z        ; return with error
  180.     inc    hl        ; increment buffer pointer
  181.     jp    noblnk
  182.  
  183. ;
  184. nofil:
  185.     ld    de,noflmes    ; file not found message
  186.     call    prnmes        ; to console
  187.     jp    cldboot        ; and terminate abnormally
  188. ;
  189. noflmes:
  190.     defb    cr,lf,'FILE NOT AVAILABLE ON HOST- CHECK DIRECTORY$'
  191. ;
  192. ;***********************************************************************
  193. ; control record for a-protocol
  194. escames:
  195.     defb    'D'        ; Download
  196.     defb    'B'        ; Binary transfer is always used! why save time
  197. escalen equ    $-escames    ; length for send routine
  198. filespec:
  199.     defs    16h         ; name of file to download
  200. ;
  201. ;***************************************************************************
  202. ;get name for remote computer
  203. ;
  204. rmtnm:
  205.     ld    de,remquery        ; ask the terminal what it wants to call it
  206.     call    prnmes            ; to the operating system such as it is
  207.     ld    de,conbuff        ; get a response
  208.     call    mesinp            ; and then
  209.     ld    hl,conbuff+2        ; convert to insure upper case
  210.     ld    a,(conbuff+1)        ; get char count xferred
  211.     cp    0            ; insure some characters
  212.     jp    z,naminv        ; else name is invalid
  213.     ld    c,a            ; blank test counter
  214.     call    noblnk            ; insure some non blank stuff
  215.     jp    z,naminv        ; else name is invalid
  216.     ld    b,a            ; in byte counter
  217. ; roll lower to upper case if necessary
  218. rmtnm1:
  219.     ld    a,(hl)            ; pick up char    
  220.     cp    061h            ; test for lower case
  221.     jr    c,rmtntl        ; not lower if carry
  222.     cp    07bh            ; still looking if less than z
  223.     jr    nc,rmtntl        ; so go on about business
  224.     and    05fh            ; else roll
  225.     ld    (hl),a            ; and save
  226. rmtntl:
  227.     inc    hl            ; bump character pointer
  228.     djnz    rmtnm1            ; and get next character
  229.     ret                ; and return to caller
  230. ; and then open and setup for further code
  231. ;
  232. naminv:
  233.     ld    hl,command+1        ; use the command line input
  234.     ld    de,conbuff+2        ; for the remote name
  235.     ld    a,(command)        ; length
  236.     ld    c,a            ; to counter with
  237.     ld    (conbuff+1),a        ; count in command line
  238.     ld    b,0            ; zero high order
  239.     ldir                ; move characters
  240.     ret                ; to caller
  241. ;
  242.  
  243. conbuff:
  244.     defb    010h            ; sixteen bytes max I'll allow
  245.     defb    00h            ; initial count
  246.     defs    16            ; and blank buffer
  247. ;
  248. remquery:
  249.     defb    cr,lf,' I need a file name for your computer',cr,lf,'->','$'
  250. ;
  251.  
  252. ;**************************************************************************
  253. ; send a record in Cis protocol format
  254. ; <soh> <rn>    text    <etx><chksum>
  255. ;
  256. prmesout:
  257.     push    bc        ; save byte count
  258.     push    hl        ; save buffer pointer    
  259.     xor    a        ; get zero
  260.     ld    (chksum),a    ; and init checksum
  261.     ld    a,soh        ; get start of header char
  262.     call    punout        ; and send it
  263.     ld    a,(currec)    ; get current record
  264.     call    sumupd        ; and update checksum
  265.     call    punout        ; and send it
  266.     pop    hl        ; restore buffer addr
  267.     pop    bc        ; restore count to b
  268. ;
  269. pmeslp:
  270.     push    hl        ; save pointer
  271.     push    bc        ; and char count
  272.     ld    a,(hl)        ; get char
  273.     call    sumupd        ; update checksum
  274.     call    tstmsk        ; test if masking necessary
  275.     call    punout        ; send char
  276.     pop    bc        ; restore count
  277.     pop    hl        ; get buffer pointer
  278.     inc    hl        ; increment it
  279.     djnz    pmeslp        ; and loop until all done
  280. ;
  281.     ld    a,etx        ; get etx char
  282.     call    punout        ; send it
  283.     ld    a,(chksum)    ; get check sum
  284.     cp    020h        ; test for < ascii space
  285.     jp    nc,pmesl1    ; if = or greater, do not mask
  286.     or    040h        ; else add to supply transparency
  287.     push    af        ; save checksum
  288.     ld    a,dle        ; send dle
  289.     call    punout        ; to remote
  290.     pop    af        ; restore char
  291. pmesl1: 
  292.     call    punout        ; send it
  293.     ret            ; and return
  294. ;*************************************************************************
  295. ; Test here for masking of control chars, handle if necessary
  296. ; masking is selective, and in any case EOT is not masked 
  297. tstmsk:
  298.     push    af        ; save char
  299.     ld    a,(masking)    ; get switch value
  300.     cp    00h        ; test for on status
  301.     jp    nz,tstmsr    ; if off return immediate
  302.     pop    af        ; restore original char
  303.     push    af
  304.     cp    05h        ; test if one of the offending chars
  305. ;                  NUL SOH STX ETX or EOT
  306.     jp    c,tstms1    ; mask if so
  307.     cp    dle        ; or if equal the dle
  308.     jp    z,tstms1    ; go masked
  309.     cp    knak        ; or if = to 
  310.     jp    z,tstms1    ; the fatal nak mask it
  311. ; common return
  312. tstmsr:
  313.     pop    af
  314.     ret            ; common return if no masking necessary
  315. ;
  316. tstms1:
  317.     ld    a,dle        ; send dle char first
  318.     call    punout        ; and send it
  319.     pop    af        ; followed by char+40
  320.     or    040h        ; to insure transparecy
  321.     ret     
  322. ;
  323. masking:
  324.     defb    00h        ; flag for control char masking
  325. ;
  326. ;******************************************************************
  327. ; Update the checksum
  328. ;
  329. sumupd:
  330.     push    af        ; save char
  331.     ld    e,a        ; and leave it in reg
  332.     ld    a,(chksum)    ; get old checksum
  333.     rlca            ; and rotate it
  334.     add    a,e        ; add new byte 
  335.     adc    a,0        ; and possible carry
  336.     ld    (chksum),a    ; and save it
  337.     pop    af        ; restore character
  338.     ret            ; and return        
  339. ;
  340. ;
  341. ;**************************************************************************
  342. ; Read a record from the disk and prepare to send it 
  343. ;
  344. getrec:
  345.     ld    de,buffer    ; buffer address
  346.     ld    c,fn$std    ; set dma function
  347.     call    bdos        ; set bufferaddr
  348.     ld    de,deffcb    ; get fcb addr
  349.     ld    c,fn$rds    ; read a record  
  350.     call    bdos        ; helps to take this step
  351.     or    a        ; set z flag if not eof
  352.     ret    
  353. ;****************************************************************************
  354. ; Actually send the record to the terminal
  355. putrec:
  356.     ld    hl,buffer    ; get buffer address
  357.     ld    b,128        ; get buffer length
  358.     call    prmesout    ; and send record to terminal
  359.     ret
  360. ;**************************************************************************
  361. ; communications failure!!!
  362. comfail:
  363.     ld    a,knak        ; turn off protocol mode
  364.     call    punout        ; at terminal end
  365.     ld    de,failmes    ; get comm failure message
  366.     call    prnmes        ; send message
  367.     jp    cldboot        ; and abort
  368. ;
  369. failmes:
  370.     defb    CR,LF,' Communications Failure - Download aborted','$'
  371.  
  372. ; *******************************************************************
  373. ; send an eot message
  374. puteot:
  375.     ld    a,0ffh        ; turn of the switch to insure
  376.     ld    (masking),a    ; that eot is sent unmasked
  377. ;
  378.     ld    hl,eotmes    ; get addr of eot char
  379.     ld    b,1        ; setup
  380.     call    prmesout    ; and send it
  381.     ret
  382. ;************************************************************************
  383. ; FINISHED - SEND SHIFT OUT TO TURN OFF PROTOCOL MODE AT REMOTE
  384. complete:
  385.     ld    a,so        ; turn off protocol mode at term
  386.     call    punout        ; now
  387.     ld    de,dcommes    ; get download complete
  388.     call    prnmes        ; send it 
  389. ;
  390.     ret
  391. dcommes:
  392.     defb    cr,lf,' DOWNLOAD COMPLETE ','$'
  393. eotmes:
  394.     defb    eot
  395. ;*************************************************************************
  396. ; WAIT FOR AN ACK OR NAK FROM HOST - RETURN WHEN WE SEE ONE 
  397. ;    THIS ROUTINE ALLOWS EASILY INSERTING TIME OUT CODE 
  398. ;
  399. waitack:
  400.     call    pcharin        ; get protocol char
  401.     cp    '.'        ; is it ack
  402.     jp    z,gotack    ; then handle
  403.     cp    '/'        ; is it nak?
  404.     jp    z,rexmit    ; then retransmit
  405.     cp    knak        ; check for abort
  406.     jp    nz,waitack    ; else loop
  407. ;
  408.     ld    a,01        ; set nz, clear carry
  409.     or    a        ; and return
  410.     ret
  411. ; received a nak
  412. rexmit:
  413.     scf            ; return carry set
  414.     ret
  415. ; received an ack - record ok - from terminal 
  416. gotack:
  417.     call    updrnum        ; update current record number
  418.     scf            ; return carry clear
  419.     ccf
  420.     xor    a        ; set zero flag
  421.     ret    
  422. ;*********************************************************************
  423. ; SUBROUTINE TO UPDATE THE CURRENT RECORD NUMBER - NUMBER IS ASCII CHAR
  424. ;
  425. updrnum:
  426.     ld    a,(currec)    ; get current record number
  427.     inc    a        ; and increment
  428.     cp    '9'+1        ; test for overflow
  429.     jr    c,updrok    ; still valid if carry
  430.     ld    a,'0'        ; else change it
  431. updrok:        
  432.     ld    (currec),a    ; and save result
  433.     ret            ; then return
  434. ;*************************************************************************
  435. ;USER CONFIGURATION AREA - THESE ARE THE IO ROUTINES WHICH ARE USER MODIFIABLE
  436. ; AT LEAST TO SOME EXTENT
  437. ;
  438. ;***********************************************************************
  439. ; This routine uses the bios punch call to access the console port
  440. ;  it could be changed easily to access the port directly
  441. ;  it must send the char in the accumulator to the modem port as 8 bit byte
  442. punout:
  443.     push    af        ; save char
  444.     ld    c,a        ; get char in proper register
  445.     ld    de,punch    ; get offset
  446.     call    biosvct        ; go doit
  447.     pop    af        ; restore char
  448.     ret
  449. ;
  450. ;
  451. ;
  452. ;********************************************************************
  453. ; SUBROUTINE TO READ 1 CHAR FROM THE INPUT STREAM IN PROTOCOL MODE
  454. ; CHAR IS NOT CHECKSUMMED, AND PARITY MAY BE STRIPPED - RETURN CHAR  IN  A
  455. pcharin:
  456.     ld    de,conin    ; get 1 char via bios
  457.     call    biosvct        ; and return
  458.     ret            ; to caller
  459. ;
  460. ;
  461.  
  462. ;
  463. ;**************************************************************************
  464. ; ROUTINE TO PRINT A MESSAGE ON THE CONSOLE DEVICE- uses standard cp/m convention
  465. ;
  466. prnmes:
  467.     ld    c,pstrg        ; print string function    
  468.     call    bdos        ; to cpm
  469.     ret            ; to caller
  470. ;
  471. ;
  472. ;**************************************************************************
  473. ; ROUTINE TO READ A BUFFER FROM OPERATOR - RETURNS STANDARD CONSOLE BUFFER
  474. mesinp:
  475.     ld    c,rdcbuf    ; read console buffer function    
  476.     call    bdos        ; call op/sys
  477.     ret            ; to caller
  478.  
  479. ; data areas
  480. ;    
  481. currec:
  482.     defb    '1'        ; initial record number
  483. chksum:
  484.     defb    00h        ; initial check sum
  485. buffer  equ    $
  486. ; record buffer for diskrecord
  487. ;***************************************************************************
  488. ; BEST OF LUCK AND BEST REGARDS  - BOB R.
  489.     end
  490.