IMD 1.18: 21/11/2016 13:55:37 intel program management tools tutorial for series iv 114310-001 v 2.0  114310.001  SERIES IV y~VOL1 N 2 10 1 ;GET ALL THE EXTERNALS AND INCLUDE FILES FROM THE DATABASE RUN :F5:SVCS. GET :F4:REMOTE.DB(SERIAL,,CP) TO :F1:SERIAL.EXT RUN :F5:SVCS. GET :F4:REMOTE.DB(FILEIO,,CP) TO :F1:FILEIO.EXT RUN :F5:SVCS. GET :F4:REMOTE.DB(REMOTE) TO :F1:REMOTE.PLM :F2:PLM80 :F1:REMOTE.PLM RUN :F5:SVCS. PUT :F4:REMOTE.DB(REMOTE,,OJ) FROM :F1:REMOTE.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(FILEIO) TO :F1:FILEIO.PLM :F2:PLM80 :F1:FILEIO.PLM RUN :F5:SVCS. PUT :F4:REMOTE.DB(FILEIO,,OJ) FROM :F1:FILEIO.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(SERIAL) TO :F1:SERIAL.PLM :F2:PLM80 :F1:SERIAL.PLM RUN :F5:SVCS. PUT :F4:REMOTE.DB(SERIAL,,OJ) FROM :F1:SERIAL.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(RMRECV) TO :F1:RMRECV.PLM :F2:PLM80 :F1:RMRECV.PLM RUN :F5:SVCS. PUT :F4:REMOTE.DB(RMRECV,,OJ) FROM :F1:RMRECV.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(RMSEND) TO :F1:RMSEND.PLM :F2:PLM80 :F1:RMSEND.PLM RUN :F5:SVCS. PUT :F4:REMOTE.DB(RMSEND,,OJ) FROM :F1:RMSEND.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(REMOTE,,OJ) TO :F1:REMOTE.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(FILEIO,,OJ) TO :F1:FILEIO.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(SERIAL,,OJ) TO :F1:SERIAL.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(RMRECV,,OJ) TO :F1:RMRECV.OBJ RUN :F5:SVCS. GET :F4:REMOTE.DB(RMSEND,,OJ) TO :F1:RMSEND.OBJ :F2:LINK :F1:REMOTE.OBJ,:F1:FILEIO.OBJ,:F1:SERIAL.OBJ,:F1:RMRECV.OBJ, & :F1:RMSEND.OBJ,:F3:PLM80.LIB,:F3:SYSTEM.LIB TO :F1:REMOTE.LNK :F2:LOCATE :F1:REMOTE.LNK SYMBOLS LINES & MAP PRINT(:F1:REMOTE.MAP) RUN :F5:SVCS. PUT :F4:REMOTE.DB(EXEC,,OJ) FROM :F1:REMOTE RUN :F5:SVCS. GET :F4:REMOTE.DB(RECV) TO :F1:RECV.PLM :F2:PLM80 :F1:RECV.PLM RUN :F5:SVCS. PUT :F4:REMOTE.DB(RECV,,OJ) FROM :F1:RECV.OBJ :F2:LINK :F1:RECV.OBJ,:F3:SYSTEM.LIB,:F3:PLM80.LIB TO :F1:RECV.LNK :F2:LOCATE :F1:RECV.LNK RUN :F5:SVCS. GET :F4:REMOTE.DB(RECV,,CP) TO :BB: WRITE RUN :F5:SVCS. PUT :F4:REMOTE.DB(RECV,,CP) FROM :F1:RECV RUN :F5:SVCS. GET :F4:REMOTE.DB(SEND) TO :F1:SEND.PLM :F2:PLM80 :F1:SEND.PLM RUN :F5:SVCS. PUT :F4:REMOTE.DB(SEND,,OJ) FROM :F1:SEND.OBJ :F2:LINK :F1:SEND.OBJ,:F3:SYSTEM.LIB,:F3:PLM80.LIB TO :F1:SEND.LNK :F2:LOCATE :F1:SEND.LNK RUN :F5:SVCS. GET :F4:REMOTE.DB(SEND,,CP) TO :BB: WRITE RUN :F5:SVCS. PUT :F4:REMOTE.DB(SEND,,CP) FROM :F1:SEND  %get (%i) to %work_device%"i".plm %plm %work_device%"i".plm %put (%i,,oj) from %target $ END $END ; Check the remote executable file that runs on the iPDS system. $ IF %"work_device"remote > %all(%work_device%"remote_files".obj), $ %plmlib, %syslib THEN $ FOR i in %remote_files %get (%i,,oj) to %work_device%"i".obj $ END %link %depend to %"work_device"remote.lnk %locate %"work_device"remote.lnk code(103H) symbols lines & map print(%"work_device"remote.map) %put (exec,,oj) from %target $ END ; Now that the remote program has been checked, check the two programs ; that run on the network. $FOR i IN %nds2_files ; Check the NDS-II files RECV and SEND. $ IF %work_device%i > %work_device%"i".plm THEN %get (%i) to %depend %plm %depend %put (%i,,oj) from %work_device%"i".obj %link %work_device%"i".obj, %syslib, %plmlib to %work_device%"i".lnk %locate %work_device%"i".lnk %get (%i,,cp) to :bb: write %put (%i,,cp) from %target $ END $END ; Make file for the isis remote program that runs on the iPDS system. ; Author : B. Valentine DSSO Applications Engineering 6/25/83 ; First of all define the macros for the make file. ; Define the subsitution macros : ; Subsitution macros are used as constant defines. This way, if ; a major change is made, such as the source code device changes ; from :f1: to :f2:, the only update to the make file is to change ; the macro define. $ SET work_device to ':f1:' $ SET 8_bit_exe to ':f2:' $ SET 8_bit_lib to ':f3:' $ SET database to ':f4:remote.db' $ SET svcs_drive to 'run :f5:' $ SET plm to '%"8_bit_exe"plm80' ; Note how macros may be nested and the macro is used with the %"". $ SET locate to '%"8_bit_exe"locate' $ SET link to '%"8_bit_exe"link' $ SET syslib to '%"8_bit_lib"system.lib' $ SET plmlib to '%"8_bit_lib"plm80.lib' $ SET comlit  to '%"8_bit_lib"common.lit' $ SET get to '%"svcs_drive"svcs. get %database' $ SET put to '%"svcs_drive"svcs. put %database' ; Now define the enumeration macros : $ SET nds2_files to (recv,send) $ SET remote_files to (remote,fileio,serial,rmrecv,rmsend) $ SET files to (%all(%nds2_files),%all(%remote_files)) ; Tell make that we are going to be looking at the files in the database. $ FOR i in %files $ svcs %work_device%"i".plm = %database (%i) $ svcs %work_device%"i".obj = %database (%i,,oj) $ END $ svcs %"work_device"serial.ext = %database (serial,,cp) $ svcs %"work_device"fileio.ext = %database (fileio,,cp) $ svcs %"work_device"remote = %database (exec,,oj) $ svcs %"work_device"save = %database (save,,cp) $ svcs %"work_device"recv = %database (recv,,cp) ; The include files are always required, so get them with the header. $ HEADER ; Get all the externals and include files from the database %get (serial,,cp) to %"work_device"serial.ext %get (fileio,,cp) to %"work_device"fileio.ext $ END ; Now start the dependecies ; Set the dependency tree for three seperate executable files. $ IF all > %"work_device"remote, %all(%work_device%nds2_files) THEN $ END $FOR i IN %remote_files ; Build all the object files in the remote program. $ IF %work_device%"i".obj > %work_device%"i".plm, %comlit, $ %"work_device"fileio.ext, %"work_device"serial.ext THEN /* Front end externals for the serial.plm link to the remote logon */ Serial$Status: Procedure byte external; end Serial$Status; Serial$Input: Procedure byte external; end Serial$Input; Serial$Output: Procedure (char) external; Declare char byte; end Serial$Output; Serial$Control: Procedure (value) external; Declare value byte; end Serial$Control; $list ; Make file for the isis remote program that runs on the iPDS system. ; Author : B. Valentine DSSO Applications Engineering 6/25/83 ; First of all define the macros for the make file. ; Define the subsitution macros : ; Subsitution macros are used as constant defines. This way, if ; a major change is made, such as the source code device changes ; from :f1: to :f2:, the only update to the make file is to change ; the macro define. $ SET work_device to ':f1:' $ SET 8_bit_exe to ':f2:' $ SET 8_bit_lib to ':f3:' $ SET database to ':f4:remote.db' $ SET svcs_drive to 'run :f5:' $ SET plm to '%"8_bit_exe"plm80' ; Note how macros may be nested and the macro is used with the %"". $ SET locate to '%"8_bit_exe"locate' $ SET link to '%"8_bit_exe"link' $ SET syslib to '%"8_bit_lib"system.lib' $ SET plmlib to '%"8_bit_lib"plm80.lib' $ SET comlit  to '%"8_bit_lib"common.lit' $ SET get to '%"svcs_drive"svcs. get %database' $ SET put to '%"svcs_drive"svcs. put %database' ; Now define the enumeration macros : $ SET nds2_files to (recv,send) $ SET remote_files to (remote,fileio,serial,rmrecv,rmsend) $ SET files to (%all(%nds2_files),%all(%remote_files)) ; Tell make that we are going to be looking at the files in the database. $ FOR i in %files $ svcs %work_device%"i".plm = %database (%i) $ svcs %work_device%"i".obj = %database (%i,,oj) $ END $ svcs %"work_device"serial.ext = %database (serial,,cp) $ svcs %"work_device"fileio.ext = %database (fileio,,cp) $ svcs %"work_device"remote = %database (exec,,oj) $ svcs %"work_device"send = %database (send,,cp) $ svcs %"work_device"recv = %database (recv,,cp) ; The include files are always required, so get them with the header. $ HEADER ; Get all the externals and include files from trocedure (file$ptr,mode) byte external; Declare file$ptr pointer, mode byte; end Open$File; Create$file: Procedure (file$ptr) byte external; Declare file$ptr pointer; end Create$File; Read$sector: Procedure (file$id, buffer$ptr) byte external; Declare file$id byte, buffer$ptr pointer; end Read$sector; Write$sector: Procedure (file$id, buffer$ptr) byte external; Declare file$id byte, buffer$ptr pointer; end Write$sector; Close$file: Procedure (file$id) byte external; Declare file$id byte; end Close$File; $list he database %get (serial,,cp) to %"work_device"serial.ext %get (fileio,,cp) to %"work_device"fileio.ext $ END ; Now start the dependecies ; Set the dependency tree for three seperate executable files. $ IF all > %"work_device"remote, %all(%work_device%nds2_files) THEN $ END $FOR i IN %remote_files ; Build all the object files in the remote program. $ IF %work_device%"i".obj > %work_device%"i".plm, %comlit, $ %"work_device"fileio.ext, %"work_device"serial.ext THEN  %get (%i) to %work_device%"i".plm %plm %work_device%"i".plm %put (%i,,oj) from %target $ END $END ; Check the remote executable file that runs on the iPDS system. $ IF %"work_device"remote > %all(%work_device%"remote_files".obj), $ %plmlib, %syslib THEN $ FOR i in %remote_files %get (%i,,oj) to %work_device%"i".obj $ END %link %depend to %"work_device"remote.lnk %locate %"work_device"remote.lnk symbols lines & map print(%"work_device"remote.map) %put (exec,,oj) from %target $ END ; Now that the remote program has been checked, check the two programs ; that run on the network. $FOR i IN %nds2_files ; Check the NDS-II files RECV and SEND. $ IF %work_device%i > %work_device%"i".plm THEN %get (%i) to %depend %plm %depend %put (%i,,oj) from %work_device%"i".obj %link %work_device%"i".obj, %syslib, %plmlib to %work_device%"i".lnk %locate %work_device%"i".lnk %get (%i,,cp) to :bb: write %put (%i,,cp) from %target $ END $END /* In case of fatal errors */ Exit: Procedure external; end Exit; /* Operating system dependant Console Routines */ Console$Input: Procedure byte external; end Console$Input; Console$Output: Procedure (char) external; Declare char byte; end Console$Output; Console$Status: Procedure byte external; end Console$Status; Print$String: Procedure (string$ptr) external; Declare string$ptr pointer; end Print$String; /* Operating system dependant file routines */ Open$file: P REMOTELOGON@  MEMORY^ BUFFERPTRBUFFER SAVEBUFFER SAVEBUFFERPTR CHARACTERTIMEOUTSAVEDI UPPERCASEC CHAR PUTINBUFFERw CHARACTER? MATCHKEYWORDKEYWORDS0 SERIALSTATUS SERIALINPUT SERIALOUTPUT SERIALCONTROLEXIT CONSOLEINPUT CONSOLEOUTPUT CONSOLESTATUS PRINTSTRINGOPENFILE CREATEFILE READSECTOR WRITESECTOR CLOSEFILESENDRECEIVE@P0034@P0105 BUFFERPTRBUFFERUINDEX MATCH I| SEND RECV LOGOFF LOCAL 7j REMOTE LOGON TO NDS 2. X1.8 ---------------------------- Trying to establish connection...... $X;=> ?@)!q:a/>z!/H : :"$  ANCD$F,G0H1I1J9KALINTOXPaQbReSmUzV~W~X6u!q*M2:1:0!5: A!6~: e*& 6 `i+4 O# 6 ~: ~*& :w`i+4Ɋ""*7?Gck$!%-2:BJOfnswY.\]^_`abcdef!6>!! 6#6>! *& * & ~ ! :* & *& * & ! 6! 4•!4„>H"g$!p .ghijklmnopqrtuwxyz{|} ~ !/:AAHOOV^fkpuz k1!6!6>!ڪ*& 6 !4?>7  O2: A O! ^#V!! !!! !6>!A*& 6 !4&*M*M2: !6 !6!6>d!ڱ>Ҫ*& w!4!6!4!6:=!*& N!4¶*Mv">-?FTd$E")05;BI\_qv{$N b MPWinstus; Print$String: Procedure (string$ptr) public; Declare string$ptr pointer, text based string$ptr byte; do while text <> '$'; call co(text); string$ptr = string$ptr + 1; end; end Print$String; /* Operating system dependant file routines */ Open$file: Procedure (file$ptr,mode) byte public; /* Return 0FFH if file does not exist, otherwise return file ID */ Declare file$ptr pointer, mode byte, (aftn, status) word;  call rename(file$ptr, file$ptr, .status); if status = 13 then return 0FFH; /* File does not exist */ call open(.aftn, file$ptr, mode, 0, .status); if status = 12 then return file$id; /* 12 returned if file already open /* want it open, so it's ok. */ if status <> 0 then return 0FFH; return low(aftn); end Open$File; Create$file: Procedure (file$ptr) byte public; /* Return 0FFH if file already exists, otherwise return file ID */ Declare file$ptr pointer, (aftn, status) word; call rename(file$ptr, file$ptr, .status); if status <> 13 then return 0FFH; /* File already exists */ call open(.aftn, file$ptr, read$write, 0, .status); if status <> 0 then return 0FFH; return low(aftn); end Create$File; Read$sector: Procedure (file$id, buffer$ptr) byte public; Declare file$id byte, buffer$ptr pointer, (buffer based bufferecv: do; /* This is an ISIS utility ptogram for use with a Remote Computer. */ /* This utility will run on an ISIS cluster board which is connected to a remote computer rather than a dumb terminal. */ $nolist include(:f3:common.lit) $nolist include(:f3:isis.ext) Declare buffer(128) byte; Declare (actual, status, aftn) word; Declare (i, J, checksum, character) byte; /* Read the remainder of the command line */ call read(1, .buffer, 128, .actual, .status); /* Is the requested ISIS file available */ j = 0; do i = 0 to 2; /* Skip "RECV FROM" in the command word. /* Need to get the file on the NDS-II system. /* Don't need to check for syntax - it is already done /* by the program on the remote computer. */ do while buffer(j) <> ' '; j = j + 1; end; do while buffer(j) = ' '; j = j + 1; end; end; call open(.aftn, .buffer(J), 1, 0, .status); if status <> 0 then do; call write(0,.(cr,lf,' NDS-II file does not exist',cr,lf), 32, .status); call exit; end; /* File is OK */ /* Get the first buffer of information */ call read(aftn, .buffer, 128, .actual, .status); do while actual <> 0; /* and send it */ if actual <> 128 then do i = actual to 128; buffer(i-1) = ' '; end; call co(STX); checksum = 0; do i = 0 to 127; call co(buffer(i)); checksum = checksum + buffer(i); end; call co(checksum); call co(ETX); /* Did the Remote Computer receive this OK */ character = ci and 7FH; if character = EOT then call exit; /* Remote error */ if character = ACK then call read(aftn, .buffer, 128, .actual, .status); /* otherwise assume a transmission error and resend */ end; /* Arrive here when the complete file has been sent */ call close(aftn, .status); call co(ETX); call exit; end recv; $debug File$io: do; /* This version contains all of the fileio definitions for ISIS */ $nolist include (:f3:common.lit) $nolist include (:f3:isis.ext) declare file$id byte external; /* Operating system dependant Console Routines */ Console$Input: Procedure byte public; return ci; end Console$Input; Console$Output: Procedure (char) public; Declare char byte; call co(char); end Console$Output; Console$Status: Procedure byte public; return csts; end Console$Star$ptr)(1) byte, (actual, status, i) word; call read(double(file$id), buffer$ptr, 128, .actual, .status); if status <> 0 then return 0FFH; if actual = 0 then return 0FFH; if actual <> 128 then do i = actual to 128; buffer(i-1) = ' '; end; return 0; end Read$sector; Write$sector: Procedure (file$id, buffer$ptr) byte public; Declare file$id byte, buffer$ptr pointer, status word; call write(double(file$id), buffer$ptr, 128, .status); return not (status = 0); end Write$sector; Close$file: Procedure (file$id) byte public; Declare file$id byte, status word; call close(double(file$id), .status); return not (status = 0); end Close$File; end fileio; $DEBUG Serial$IO$for$SII: do; /* This module contains all of the SII specific serial IO routines */ Serial$Status: Procedure byte public; return ((input(0F7H) and 2) = 2); end Serial$Status; Serial$Input: Procedure byte public; do while not Serial$status; /* Wait */ end; return (input(0F6H)); end Serial$Input; Serial$Output: Procedure (char) public; Declare char byte; do while ((input(0F7H) and 1) = 0); /* Wait */ end; output(0F6H) = char; end Serial$Output; Serial$Control: Procedure (value) public; Declare value byte; output(0F7H) = value; end Serial$Control; end Serial$IO$for$SII; FILEIO@! MEMORY# CONSOLEINPUT CONSOLEOUTPUT CHAR" CONSOLESTATUS PRINTSTRING4 STRINGPTR5OPENFILEP'FILEPTRMODEAFTNSTATUSR CREATEFILEi FILEPTR AFTNSTATUSu READSECTOR2FILEID BUFFERPTRACTUALSTATUSIX WRITESECTOR#FILEID BUFFERPTRSTATUS$ CLOSEFILEISISOPENCLOSEREADWRITESEEKRESCANSPATHDELETERENAMEATTRIBCONSOLLOADWHOCONERRORDETIMEFILINFGETDEXITCICORIPOLOCSTSIODEFIOCHKIOSETMEMCKFILEID@P0101@P0103 CONSOLEINPUT CONSOLEOUTPUT CONSOLESTATUS PRINTSTRING5OPENFILE CREATEFILE READSECTORX WRITESECTOR CLOSEFILEKFILEIDSTATUS\ ]^.[ _ ab!q*MF$  c~ deK fwh#i*j1k4l%!p+q*~$4*N*#"k"!2$ $+/ (5mO*=oLpXq[rrs~tuvwxe5!s+p+q**DM> [>* O> ‚:>ʑ>*}"V|u$6>BGO\`ju  JRpxy"{|}~Q! p+q* * DM> ʺ> * >>* }"G$  . ,=HUX*y!r+s+q*&*>>> >>U*">!U*+*6 *"2>"  *;S$!#-05>CLP &8X`s-X!r+s+q*&*>/>$ Yagkv qyg#!q*&DM>/J$  #SERIALIOFORIPDS@7 MEMORY1 SERIALSTATUS SERIALINPUT SERIALOUTPUT CHAR- SERIALCONTROLB SERIALSTATUS SERIALINPUT SERIALOUTPUT- SERIALCONTROL VALUE^  ۑɀ     ې"   $ ',!qۑ':Ӑɸ""%$(- 16a-!q:ӑ$.2pRECEIVE@H" MEMORY DELIMITo CHARACTERIJMATCHSTATUSCOUNTCHECKSUMRECEIVEDCHECKSUM LOOPCOUNT ENDBUFFERWAITFORSERIALINPUT) NOTIMELIMIT CHARACTER TIMEOUT BUFALLBLANKSg BUFPTRI BUFFERPTRBUFFERFILEIDEXIT CONSOLEINPUT CONSOLEOUTPUT CONSOLESTATUS PRINTSTRINGOPENFILE CREATEFILE READSECTOR WRITESECTOR CLOSEFILE SERIALSTATUS SERIALINPUT SERIALOUTPUT SERIALCONTROL@P0029@P0105 <RECEIVE<RECEIVEUTRYAGAINFROM+ Serial line lost, Program aborted $?+ Receive V2.3 $W<Command syntax error. Correct format is : RECV FROM $?WCommand syntax error. Correct syntax is : RECV FROM $ Local File already exists $o!Local disk write-protected $ File transfer complete $6Local disk full $ZGMissing . Correct syntax is:- RECV FROM $5>78:;<=>?@ABCDEF]! q! 6>d! 2 : >: ! 6! 4¦"$ " G"IJK#L&M6N9O<PRJ!p+q!6*&* ~ ~ H&!4*&* ~ 9>>"$4X$ '-H<QbF<RBSGTJUYV]W`XhZn[s\t]t^y_abcdefghiklmnopqrstuvw-x2y9z@|E}M~UU]eow (.3449<<BG<+!6#6* & ~ `! 4J: t<!6*& DMҗ*& ~ ­!4×*& DM2:*& ~ !4*& ~ !4!6+6>!9:!O! *& 2!6!4:< ͝2͝2͝2:‡*M2:€Æ:ʐ!6!6>!͝2*& :w:!w!4š͝2͝2!:?U:0O:<_! !s*M2:4*M26UGv"T=W^fi $+7>HPXcux~):=a$aCKZauz .3:KS[^mp& @Plq Cf j{   #,17@Edo for$ever; IF waiting$char <> 0 THEN return waiting$char; dummy = console$status; end; end Console$Input; Console$Output: Procedure (char) public; Declare char byte; call BDOSN(6,double(char)); end Console$Output; Print$String: Procedure (string$ptr) public; Declare string$ptr pointer; call BDOSN(9,string$ptr); end Print$String; /* Operating system dependant file routines */ Declare FCB$free(6) byte initial (1,1,1,1,1,1); Declare FCB(6) structure (item(36) byte); Declare Blank$FCB(36) byte data (1,' ',0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0); Get$FCB: Procedure byte; Declare i byte; do i = 0 to 5; if FCB$free(i) then do; FCB$free(i) = false; return i; end; end; call Print$String(.(cr,lf,'Too many files open, Program aborted',cr,lf,'$')); call exit; end Get$FCB; Format$FCB: Procedure(index, file$ptr); Declare (index, i) byte, file$ptr pointer; Declare (text based file$ptr)(1) byte; /* Clear all the required fields */ call move(36,.blank$FCB,.FCB(index)); /* Skip over any leading spaces */ do while text(0) = ' '; file$ptr = file$ptr + 1; end; /* Has a drive been specified ? */ if text(1) = ':' then do; FCB(index).item(0) = text(0) - 'A' + 1; file$ptr = file$ptr + 2; end; file$ptr = file$ptr - 1; $DEBUG CPM$Interface$library: do; /* This module contains all of the definitions for FILEIO.EXT for CPM 80 */ $nolist include(:f3:common.lit) $list Declare bdos$jump address data ( 5 ); /* Set up the address of where to /* go in memory to get to the CPM BDOS routines. This is done /* by using a call by address with parameters of which bdos routine /* and to the routine. This is a clumsy way to do it because /* there is no way to read the return value of the routine. So  /* as you will see in the procedure bdos, how the compiler is fooled into /* generating the asm code for a return value. */ /* PLM 80 Declarations for CPM 80 functions */ BDOS: Procedure (type, parameter) byte; Declare type byte, parameter word; if 1 = 2 then return 1; /* Let pass 2 of the compiler see a return for the /* typed procedure. Then pass 3 will see 1 is /* never = 2, so it will throw out the statement. /* Now bdos has put the return value in the Acc., /* and the calling procedure that called this /* procedure will get it out of the Acc. /* Real clumsy but works. */ call bdos$jump (type,parameter); end BDOS; /* Some BDOS calls return a word; to conform to good PLM syntax we use:....*/ BDOSW:Procedure (type, parameter) word; Declare type byte, parameter word; if 1 = 2 then return 1; call bdos$jump (type,parameter); end BDOSW; /* Some BDOS calls return nothing; to conform to good PLM syntax we use:....*/ BDOSN:Procedure (type, parameter); Declare type byte, parameter word; call bdos$jump (type,parameter); end BDOSN; /* In case of fatal errors */ Exit: Procedure public; call BDOSN(0,0); end Exit; /* Operating system dependant Console Routines */ Declare waiting$char byte; /* This is the buffer for the CO,CI and /* CSTS BDOS routines */ Console$Status: Procedure byte public; waiting$char = BDOS(6,0FFH); IF waiting$char = 0 THEN return false; return true; end Console$Status; Console$Input: Procedure byte public; /* One problem with the ISIS to CPM BDOS is in the console /* inputs, ISIS dosen't echo and CPM does. So, using the CPM /* BDOS direct console I/O to get around the echo problem. */ Declare dummy byte;  do i = 1 to 11; if text(i) = ' ' then return; if text(i) = cr then return; if text(i) = '.' then do; file$ptr = file$ptr + i - 8; i = 8; end; else FCB(index).item(i) = text(i); end; end Format$FCB; Set$DMA$Address: Procedure (value); Declare value word; call BDOSN(26,value); end Set$DMA$Address; Select$disk: Procedure (disk); Declare disk byte; call BDOSN(14,double(disk)); end Select$disk; Open$file: Procedure (file$ptr,mode) byte public; Declare mode byte, (file$ptr, FCB$ptr) pointer, (index, status) byte; index = get$FCB; call format$FCB(index, file$ptr); call Select$disk(FCB(index).item(0)-1); FCB(index).item(0) = 0; status = BDOS(15,.FCB(index)); if status = 0FFH then return 0FFH; return index; end Open$File; Create$file: Procedure (file$ptr) byte public; Declare (file$ptr, FCB$ptr) pointer, (index, status) byte; index = get$FCB; call format$FCB(index, file$ptr); call Select$disk(FCB(index).item(0)-1); FCB(index).item(0) = 0; status = BDOS(22,.FCB(index)); if status = 0FFH then return 0FFH; return index; end Create$File; Read$sector: Procedure (file$id, buffer$ptr) byte public; Declare file$id byte, buffer$ptr pointer; call Set$DMA$Address(buffer$ptr); return BDOS(20,.FCB(file$id)); end Read$sector; Write$sector: Procedure (file$id, buffer$ptr) byte public; Declare file$id byte, buffer$ptr pointer; call Set$DMA$Address(buffer$ptr); return BDOS(21,.FCB(file$id)); end Write$sector; Close$file: Procedure (file$id) byte public; Declare file$id byte; FCB$free(file$id) = true; return BDOS(16,.FCB(file$id)); end Close$File; end CPM$Interface$library; /* Some useful defines for the remote program */ declare lit literally 'literally'; declare word lit 'address'; declare pointer lit 'address'; declare connection lit 'address'; declare cr lit '0dh', lf lit '0ah', TAB lit '09h', SOH lit '01h', STX lit '02h', ETX lit '03h', EOT lit '04h', ACK lit '06h', NAK lit '15h', XON lit '11h', XOF lit '13h', CAN lit '18h', SUB lit '1ah', RUBOUT lit '7fh'; declare forever lit 'while 1'; declare false lit '0', true lit 'not false'; declare read$only lit '1', write$only lit '2', read$write lit '3'; $list  | | | | (Optional) Modem | | | Remote | ___ ___ | Cluster Board | | Computer | Serial | |----| ~ |----| | | |------------| | |____________|----------|___| |___|-------|__________________| Line REMOTE, for the most part, turns the remote computer into a dumb terminal. ie. Characters entered on the remote computer keyboard are sent down the serial line and characters received up are echoed to the remote computers screen. REMOTE internally collects the characters typed on by the remote computer user and saves them in a buffer. When a is entered, REMOTE scans the buffer looking for three special commands - SEND, RECV and LOCAL. If these commands are not found - operation as a dumb terminal continues. If one of these special commands are intercepted, REMOTE flips into file transfer mode (SEND or RECV commands) or back to standalone operation. Also, SEND or RECV cause a program to be activated on the cluster board to effect the file transfer. A simple protocol is used (STX, 128 data bytes, CHECKSUM, ETX) so some error checking is done. REMOTE is written to be configurable. The I/O system is defined in FILEIO.PLM and the serial line configuration is SERIAL.PLM. All of the software is written in PLM. The systems currently supported are : FILEIO.PLM - ISIS and CPM80 SERIAL.PSEND@  MEMORY FILEID- DELIMIT] CHARACTERIMATCHSTATUSCOUNTCHECKSUMRECEIVEDCHECKSUM LOOPCOUNT BUFFERPTRBUFFEREXIT CONSOLEINPUT CONSOLEOUTPUT CONSOLESTATUS PRINTSTRINGOPENFILE CREATEFILE READSECTOR WRITESECTOR CLOSEFILE SERIALSTATUS SERIALINPUT SERIALOUTPUT SERIALCONTROL@P0029 MSENDd FILEID) MSENDh TO  Send V2.1 $ Local file does not exist $X#. Could not close Local file $M5oM6S7X8g9v;<=>?ABCDEFGHIKLMNOPQRSTU V'W.X3Y9ZA\J]\^i_laqbvcvdyefghijklVM!6!6:!ڞ*& ~ —*& ~ Œ!4v*& DM2:³ 222:*M*M2:y!6!6>!'*& ~2!w*M!4*M2:l:0O:<_! !s*M2v?!6*M2:ʑ.!4]"$Net%?jwv$OTYahw!(7:BKY]grz vQ^m|   ,1 4HUa do ~This is the users manual for the PMT tutorial Remote program. REMOTE is a program that runs on a remote computer connected to an NDS2 via an ISIS cluster board. The connection is an RS232 line and may include modems as shown below. Series II or III __________________ ISIS or CPM80 | | ____________ Modem LM - Series II and PDS Thus four variants are currently available. NOTE : Device 0 on the network must contain the SEND and RECV executable files. $DEBUG Remote$Logon: do; /* This program runs on a remote computer connected via a serial line to an ISIS Cluster board on an NDS 2 system. The remote computer may be connected to the ISIS cluster board via a modem. It enables the remote computer to use all of the facilities of the NDS 2. For the most part the remote computer behaves as a dumb terminal; two commands (SEND and RECV) are intercepted to enable file transfer between the remote computers file system and the NDS 2 file system. Most remote computers will not be able to keep up with a high speed serial line so a XON/XOF protocol is used to slow the serial line down if required. Author: B. Valentine 6/22/83 - DSSO Applications Engineering */ $nolist include(:f3:common.lit) $include(:f1:serial.ext) $nolist include(:f1:fileio.ext) Declare buffer$ptr byte public; Declare buffer(128) byte public; Declare save$buffer(128) byte; Declare save$buffer$ptr  byte; Declare character byte; Declare time$out byte; Declare saved byte; Declare i byte; Send: Procedure external; end Send; Receive: Procedure external; end Receive; Uppercase: Procedure (char) byte; /* If the character passed in is lowercase then convert it to uppercase. */ Declare char byte; if ((char >= 'a') AND (char <= 'z')) then return (char - 20h); return char; end Uppercase; Put$in$buffer: Procedure (character); /* Put the character passed in into the input buffer, checking for EOLN /* and rubout. */ Declare character byte; character = uppercase(character); if character = RUBOUT then do; if buffer$ptr <> 0 then buffer$ptr = buffer$ptr - 1; return; end; if character = cr then buffer$ptr = 0; else if character = lf then do; /* Mark end of the buffer */ buffer(buffer$ptr) = ' '; buffer$ptr = buffer$ptr + 1; buffer(buffer$buffer(0) = lf; save$buffer$ptr = 1; do time$out = 0 to 100; call time(2); /* 100 microseconds */ if Serial$Status then do; save$buffer(save$buffer$ptr) = Serial$Input; save$buffer$ptr = save$buffer$ptr + 1; time$out = 0; /* Reset the timeout */ end; end; /* Get here once no characters are waiting. Send saved characters to screen */ do saved = 0 to save$buffer$ptr - 1; call Console$Output(save$buffer(saved)); end; /* We have now caught up so.... */ call Serial$Output(XON); end; ELSE call console$output(character); end; end; /* Do forever */ end Remote$Logon; ptr) = lf; return; end; else if character >= ' ' then do; buffer(buffer$ptr) = character; buffer$ptr = buffer$ptr + 1; end; end Put$in$buffer; Match$Keyword: Procedure byte; /* Check command to see if it's one to process or just send down to the /* Network. */ Declare Keywords(4) structure (text(7) byte) data ('SEND ', 'RECV ', 'LOGOFF ', 'LOCAL '); Declare (index,match,i) byte; do index = 0 to 3; match = true;  do i = 0 to 6; if (Keywords(index).text(i) = ' ') and (match) then return index; if buffer(i) <> Keywords(index).text(i) then match = false; end; end; return 4; /* No match */ end Match$Keyword; /*************************** Program starts here **************************/ buffer$ptr = 0; do i = 0 to 127; buffer(i) = ' '; end; /* Say Hello to the user */ call Print$String(.(cr,lf, 'REMOTE LOGON TO NDS 2. X1.8',cr,lf, '----------------------------',cr,lf,lf, 'Trying to establish connection......',cr,lf,'$')); /* Kick start the serial line */ /* Send a BREAK */ call Serial$Control(00111111b); call time(200); call Serial$Control(00110111b); call Serial$Output(cr); call Serial$Output(cr); /* Set up as a transparent terminal */ do forever; if Console$Status then do; character = Console$Input and 7FH; /* Need to scan for SEND and RECV commands */ if character = cr then do; call put$in$buffer(lf); /* Mark end of buffer */ do case match$keyword; call send; call receive; do; /* User typed Logoff, so do it */ call Serial$Output(cr); end; do; call Serial$Output(CAN); call Exit; end; ; /* Do nothing */ end; do i = 0 to 127; /* Clear buffer after comparison */ buffer(i) = ' '; end; end; call put$in$buffer(character); call Serial$Output(character); end; if Serial$Status then do; character = Serial$Input and 7FH; /* We need time to deal with a LF */ if character = lf then do; call Serial$Output(XOF); call Serial$Output(XOF); /* Stop characters being sent to me, note that a few will be on the way... Collect them... */ save$ REMOTE"KCI COCSTSIOCHKIODEFIOSET@ISISLO PORI;9 CONSOLEINPUT9 CONSOLEOUTPUT9 CONSOLESTATUS9 PRINTSTRING9OPENFILE: CREATEFILEg: READSECTOR: WRITESECTOR; CLOSEFILE$; SERIALSTATUS.; SERIALINPUT;; SERIALOUTPUTQ; SERIALCONTROL=RECEIVE?SENDBA@P0029DA@P0030aA@P0034cA@P0035uA@P0101xA@P0102A@P0103A@P0104A@P0105AATTRIBACLOSEACONSOLADELETEAEXITBLOAD*BMEMCK0BOPENTBREADxBRENAMEBRESCANBSEEKBWHOCONBWRITECSPATH"CERROR0CGETD3CFILINF6CDETIME#C BUFFERPTRCBUFFERDFILEID REMOTELOGON 8EMEMORY^C BUFFERPTRCBUFFERD SAVEBUFFERD SAVEBUFFERPTRD CHARACTERDTIMEOUTDSAVEDDIi8 UPPERCASE DCHAR8 PUTINBUFFERD CHARACTERq8 MATCHKEYWORD6KEYWORDSDINDEXDMATCHDIi8;m8=8>8?8@8AN8C8D8F8G8H8I8J8K8L8N8O8P8Q8R8S8U8V8W8X8Yb.8\ 9]9^9_C9`G9an9bs9cz9d9e9f7g 7h7i#7j*7k07l57m:7n?7oD7pI7qI7rP7tX7u`7we7xu7y{7z7{7|7}7~777777777777777777778 88!8%8*8*818A8N8U8Z8]8d8d8g8FILEIO* 8EMEMORY#9 CONSOLEINPUT9 CONSOLEOUTPUT DCHAR"9 CONSOLESTATUS9 PRINTSTRINGD STRINGPTR,9OPENFILE'DFILEPTRDMODEDAFTNDSTATUS: CREATEFILEDFILEPTRDAFTNDSTATUSg: READSECTORG2DFILEIDD BUFFERPTRDACTUALDSTATUSDI: WRITESECTORa#DFILEIDD BUFFERPTRDSTATUS; CLOSEFILEDFILEIDDSTATUSF9\ 9]9^9_ 9a9b9c 9d9e9f9h9i9j9k9lS9m*9o9p9q9r9s:t:u:v:w:x:y%" :{/:|;:}>:~S:_:b:g:g:.o::::::::::: :L::;; ;;$;.SERIALIOFORIPDSa 8EMEMORY1$; SERIALSTATUS.; SERIALINPUT;; SERIALOUTPUT DCHARQ; SERIALCONTROLa DVALUEc$; $;.;.;.;5;8;;; ;; r?; H; K;P;Q;V U;Z; RECEIVE 8EMEMORY [;DELIMIT<oD CHARACTERDIDJDMATCHDSTATUSDCOUNTDCHECKSUMDRECEIVEDCHECKSUMD LOOPCOUNTD ENDBUFFER<WAITFORSERIALINPUT$)D NOTIMELIMITD CHARACTERDTIMEOUTQ= BUFALLBLANKSDBUFPTRDI=RECEIVE>TRYAGAIN<5><7 =8=:=;!=<$==$=>+=?/=@4=A;=B@=CG=DM=EP=FQ=G"W=I\=Jz=K~=L=M=N=O=P=QF=R=S=T=U=V=W=X=Z=[=\=]=^=_=a=b=c=d=e>f>g>h>i!>k'>l,>m->n->o<>p@>qC>rR>sV>tY>u^>vj>w>x>y>z>|>}>~>>>>>>>>>>>>>>>???"?*?2?B@?J@AP@BU@CV@DV@E[@Fa@Gg@Hm@Iu@K|@L}@M}@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@\@]@^ A_AaAbAcAdAe&Af.Ag4Ah9Ai:Aj:AkAAl 6SEND RECV LOGOFF LOCAL REMOTE LOGON TO NDS 2. X1.8 ---------------------------- Trying to establish connection...... $1C!C6!D6>!D*7*D&C 6 !D476͘9?Q;>͌A7Q; ;; ;;͔97̈́92D:D 7 ͎88O!7 ^#V?á7͗=á7 ;;á7;;Aá7á7u7{7777!D6>!D7*D&C 6 !D4¦7*DM͎8*DM;;$;d8.;2D:D ]8;;;;!D6 !D6!D6>d!D18>͌A$;*8.;*D&D w!D4!D6!D47!D6:D=!DU8*D&D N͈9!D468;;d8*DM͈9I7v!Dq:Da/>z!D/HҊ8:D :D!Dq*DMi82D:D±8:Cʰ8!C5:D 8!C68:D 8*C&C 6 `i+4 O# 6 8:D 8*C&C :Dw`i+4!D6>!Dځ9!D6#6>!Dz9*D&aA6 *D& ~ !D2E7G9:D*D&C *D&aA6 *D& s9!D6!D49!D49>!Dq*DM !Dp+q*D~$ʸ9*DN *D#"DÞ9!Ds+p+q*D*DDMDxB> DuA9>D*D OD0B> DuA::D>DuA:>*D}!Dp+q*D*DDMDxB> DuA>:>D*DD0B>DuAb:>*D}!Dr+s+q*D&*DDDTB>DuAʕ:>>DuA¤:>>DuA:*D"D>!D̀A:*D+*D6 *D"DҶ:>!Dr+s+q*D&*DDB>DuA/!Dq*D&DMDͷA>DuA/ۑ$;8;.;ې!DqK;?;:DӐ!Dq:DӑFROM Serial line lost, Program aborted $ Receive V2.3 $Command syntax error. Correct format is : RECV FROM $Command syntax error. Correct syntax is : RECV FROM $Local File already exists $Local disk write-protected $ File transfer complete $Local disk full $Missing . Correct syntax is:- RECV FROM $!Dq!D6>d!DG=͔9$=̈́92D:D$=A$;/=.;>͌A:D@=!D6!D4=_;͘9A!Dp+q!D6*D&*D~ ~ Hҁ=!D4\=*D&*D~ ”=>>;͘9!D6#6*D&C ~ ʻ=!D4å=:D=;͘9;;!D6*D&C DMQ==;͘9;;*D&C ~ >!D4=*D&C DM:2D:D->=<͘9;;*D&C ~ C>!D4->*D&C ~ Y>!D4C>!D6+6>!Dڔ>:D!DO!C *D&[; ʍ>!D6!D4a>:Dҗ? ;;<2D<2D<2D:D>*DM;2D:D>Y<͘9>v<͘9:D>!D6!D6>!D"?<2D*D&C :Dw:D!Dw!D4><2D<2D!D:DI??͈9;;ð>:D0O͈9:D<_! BA!Ds*DMC:2D:Dʏ?*DM;2D<͘9;;;;ð><͘9;; TO Send V2.1 $Local file does not exist $ Could not close Local file $?͘9!D6!D6:C!DAA*D&C ~ :A*D&C ~ /@!D4@*D&C DM͹92D:DV@?͘9;; ;;.;2D.;2D.;2D:D}@*DM͈9*DMCg:2D:DA;;!D6!D6>!D@*D&C ~2D!Dw*DM;;!D4¡@*DM;;;;.;2D:DA:D0O͈9:D<_! BA!Ds*DMCg:2DA?͈9!D6Ê@*DM;2D:D4A?͘9;;!D4@DM!>))덑o|g[A =IADM!>))pA =hAo&og_{_z#W H A=ŽA!Dr+s+p+q+p+q+p+qD @!Dr+s+p+qD@!Dr+s+p+q+p+qD@!Dr+s+p+qD@!D"DD @!Dr+s+p+q+p+q+p+q+p+qD@`o!Dr+s+p+q+p+q+p+q+p+qD@! Er+s+p+q+p+q+p+q+p+qE@!Er+s+p+q+p+q E@!Er+s+p+qE @!Er+s+p+q+p+q+p+q+p+qE@!!Er+s+p+q!"E""EE @!+Er+s+p+q+p+q+p+q$E@@!1Er+s+p+q+p+q,E!!C*C> !6E+p+qO@6E$DEBUG Rec$eive: do; /* This is part of the REMOTE-LOGON program. This module is called if the /* remote computer is to receive a file from the Network. */ /* Declare the variables used from Remote$Logon */ Declare buffer$ptr byte external; Declare buffer(128) byte external; Declare file$id byte external; $nolist include(:f3:common.lit) $nolist include(:f1:fileio.ext) $nolist include(:f1:serial.ext) Declare delimit(4) byte data ('FROM'); Declare (character, i, j, match ,status) byte; Declare (count, checksum, received$checksum, loop$count, end$buffer) byte; Wait$for$serial$input: Procedure (no$time$limit) byte; Declare (no$time$limit, character, time$out) byte; do time$out = 0 to 100; /* Has the user aborted the command? */ if Console$Status then do; character = Console$Input and 7FH; if character = CAN then call Exit; end; if Serial$Status then return Serial$Input; call time(2); /* 100 microseconds */ if no$time$limit then timeout = 0; end; call Print$String(.(cr,lf,lf,'Serial line lost, Program aborted', cr,lf,'$')); call Exit; end Wait$for$serial$input; buf$all$blanks: Procedure (Buf$ptr) byte; /* Check to see if the remainder of the buffer is blanks. */ Declare buf$ptr address, (buf based buf$ptr)(1) byte, i byte; i = 0; do while (buf(i) <> lf) and (buf(i) = ' '); i = i + 1; end; if buf(i) = lf then return true; return false; end buf$all$blanks; Receive: Procedure public; /* Copy a file from the NDS 2 to the Remote Computer */ /* Say HELLO */ call Print$String(.(cr,lf,'Receive V2.3',cr,lf,'$')); /* Skip through the command line looking for Remote Computer filename */ loop$count = 0; end$buffer = 0; /* Find the end of good characters in the buffer */ do while buffer(end$buffer) <> lf; end$buffer = end$buffer + 1; end; if end$buffer < 14 then do; /* Not enough characters in buffer to even get started. Must have /* at least "RECV A FROM B ", which is 14 characters. */ call Print$String(.('Command syntax error. Correct format is :',cr,lf, 'RECV FROM ',cr,lf,'$')); call Serial$Output(CAN); return; end; i = 5; /* Skip over the recv command word */ if buf$all$blanks(.buffer(i)) then do; /* Buffer passed the length requirement but is all blanks after /* the RECV command word. */ call Print$String(.('Command syntax error. Correct syntax is :',cr,lf, 'RECV FROM ',cr,lf,'$')); call Serial$Output(CAN); return; end; do while buffer(i) = ' '; /* Skip blanks before local file name */ i = i + 1; end; /* We have found the filename */ /* Check if it exists */ file$id = Create$File(.buffer(i));  if file$id = 0ffh then do; call Print$String(.('Local File already exists',cr,lf,'$')); call Serial$Output(CAN); /* Abort ISIS command */ return; end; /* Now that the file is good - see if FROM is in the command string */ do while buffer(i) <> ' '; /* Skip the local file name */ i = i + 1; end; do while buffer(i) = ' '; /* Skipp blanks before */ i = i + 1; end; match = true; do j = 0 to 3; /* Check for in command string */ if buffer(i+j) <> delimit(j) then match = false; end; if match then do; /* File OK, activate the ISIS RECV command */ call Serial$Output(cr); /* Skip passed CR,LF sent from ISIS. If no problems at ISIS end of the link then we will be sent a STX. */ character = Wait$for$serial$input(true); /* CR */ character = Wait$for$serial$input(true); /* LF */ do forever; Try$Again: character = Wait$for$se rial$input(true); /* STX? */ if character = ETX then do; status = Close$File(file$id); if status = 0ffh then call Print$String(.( 'Local disk write-protected',cr,lf,'$')); else call Print$String(.( cr,lf,'File transfer complete',cr,lf,'$')); return; end; if character <> STX THEN DO; return; END; /* ISIS is about to send us a buffer */ checksum = 0; do i = 0 to 127; character = Wait$for$serial$input(false); buffer(i) = character; checksum = checksum + character; end; received$checksum = Wait$for$serial$input(false); character = Wait$for$serial$input(false); /* ETX */ if checksum <> received$checksum then do; /* Checksum error - request retransmission */  call Console$Output('?'); call Serial$Output(NAK); goto Try$Again; end; /* Buffer received OK */ /* Write to disk */ call Console$Output(loop$count + '0'); loop$count = (loop$count + 1) MOD 10; status = Write$Sector(file$id, .buffer); if status <> 0 then do; status = Close$File(file$id); call Print$String(.('Local disk full',cr,'$')); call Serial$Output(EOT); return; end; /* Buffer written to disk, Look for some more..... */ call Serial$Output(ACK); end; /* Do forever */ /* String did not match, keep looking */ end; /* Have now scanned the complete command line */ call Print$String(.('Missing . Correct syntax is:-',cr,lf,lf, 'RECV FROM ',cr,lf,'$')); /* Abort ISIS command too */ call Serial$Output(CAN);  end Receive; end Receive;  $DEBUG Se$nd: do; /* This is part of the REMOTE-LOGON program. This module called if /* user is going to send a file from the remote computer to the /* NDS 2. */ /* Declare the variables used from Remote$Logon */ Declare buffer$ptr byte external; Declare buffer(128) byte external; Declare file$id byte public; $nolist include(:f3:common.lit) $nolist include(:f1:fileio.ext) $nolist include(:f1:serial.ext) Declare delimit(4) byte data (' TO '); Declare (character, i, match, status, count) byte; Declare (checksum, received$checksum, loop$count) byte; Send: Procedure public; /* Copy a file from the Remote Computer to the NDS 2 */ /* Say HELLO */ call Print$String(.(cr,lf,'Send V2.1',cr,lf,'$')); /* Skip through the command line looking for Remote Computer filename */ loop$count = 0; do i = 0 to buffer$ptr; if buffer(i) = ' ' then do; do while buffer(i) = ' '; i = i + 1; end;  file$id = Open$File(.buffer(i),read$only); if file$id = 0ffh then do; call Print$String(.('Local file does not exist',cr,lf,'$')); call Serial$Output(CAN); /* Abort ISIS command */ return; end; /* File OK, activate the ISIS SEND command */ call Serial$Output(cr); /* Skip passed CR,LF sent from ISIS. If no problems at ISIS end of the link then we will be sent a ACK. */ character = Serial$Input; /* CR */ character = Serial$Input; /* LF */ character = Serial$Input; /* ACK? */ if character <> ACK then do; call console$output(character); return; end; /* Get a buffer ready to send */ status = Read$sector(file$id, .buffer); do while status = 0; call Serial$Output(STX); checksum = 0; do i = 0 to 127;  character = buffer(i); checksum = checksum + character; call Serial$Output(character); end; call Serial$Output(checksum); call Serial$Output(ETX); /* Buffer sent OK. Was it received OK */ character = Serial$Input; if character = ACK then do; call console$output(loop$count + '0'); loop$count = (loop$count + 1) MOD 10;  status = Read$sector(file$id, .buffer); end; else do; call Console$Output('?'); status = 0; /* Retransmit */ end; end; /* File sent */ status = Close$file(file$id); if status <> 0 then call Print$String(.(cr,lf, 'Could not close Local file',cr,lf,'$')); call Serial$Output(ETX); return; end;  end; end Send; end Send;  6!6>!E*& N*& :2!4*M2:d:**DMv"$GV]lszC_j$g(039CJOY`eov}"'/48<?FWZemqy|($! J6 ,JORbt $DEBUG Serial$IO$for$iPDS: do; /* This module contains all of the iPDS specific serial IO routines */ Serial$Status: Procedure byte public; return ((input(091H) and 2) = 2); end Serial$Status; Serial$Input: Procedure byte public; do while not Serial$status; /* Wait */ end; return (input(090H)); end Serial$Input; Serial$Output: Procedure (char) public; Declare char byte; do while ((input(091H) and 1) = 0); /* Wait */ end; output(090H) = char; end Serial$Output; Serial$Control: Procedure (value) public; Declare value byte; output(091H) = value; end Serial$Control; end Serial$IO$for$iPDS; RECV@/ISISOPENCLOSEREADWRITESEEKRESCANSPATHDELETERENAMEATTRIBCONSOLLOADWHOCONERRORDETIMEFILINFGETDEXITCICORIPOLOCSTSIODEFIOCHKIOSETMEMCK@P0101#$ NDS-II file does not exist z} 1!6+6>!|*& ~ _!4I*& ~ u!4_!4@*& >ʷ *>ʄ> *!s>! :=O! 6 !4! send: do; /* This is an ISIS utility ptogram for use with a Remote Computer. */ /* This utility will run on an ISIS cluster board which is connected to a remote computer rather than a dumb terminal. */ $nolist include(:f3:common.lit) $nolist include(:f3:isis.ext) Declare buffer(128) byte; Declare (actual, status, aftn) word; Declare (i, j, match, count, checksum, received$checksum, character) byte; Declare delimit(4) byte data (' TO '); Uppercase: Procedure (char) byte; Declare char byte; if ((char >= 'a') AND (char <= 'z')) then return (char - 20h); return char; end Uppercase; /* Read the remainder of the command line */ call read(1, .buffer, 128, .actual, .status); do i = 0 to actual-1; if buffer(i) = ' ' then do; match = true; do j = 0 to 3; if uppercase(buffer(i+j)) <> delimit(j) then match = false; end; if match then do; /* We have found the filename */ i = i + 3;  do while buffer(i) = ' '; i = i + 1; end; call open(.aftn, .buffer(i), 3, 0, .status); /* Did the file already exist? */ call read(aftn, .buffer, 1, .actual, .status); if actual = 1 then do; call write(0,.(cr,lf,'NDS-II file already exists',cr,lf), 30, .status); call exit; end; /* File is OK, tell Remote Computer to proceed */ call co(ACK); /* Receive the first buffer of information */ do forever; character = ci; /* STX or ETX */ if character = ETX then do; call close(aftn,.status); call write(0,.(cr,lf,'File transfer complete',cr,lf), 26, .status); call exit; end; checksum = 0; do i = 0 to 127; buffer(i) = ci; checksum = checksum + buffer(i);  end; received$checksum = ci; character = ci; /* ETX */ if received$checksum <> checksum then call co(NAK); else do; call write(aftn, .buffer, 128, .status); call co(ACK); end; end; end; /* No match, keep looking */ end; end; /* End of line */ call write(0, .(cr, lf,CR,LF, 'Missing . Correct syntax is:-',cr,lf, 'SEND TO ',cr,lf), 84, .status); call exit; end send;  ite: procedure (conn, buff$p, count, status$p) external; declare (conn, buff$p, count, status$p) address; end write; seek: procedure (conn, mode, block$p, byte$p, status$p) external; declare (conn, mode, block$p, byte$p, status$p) address; end seek; rescan: procedure (conn, status$p) external; declare (conn, status$p) address; end rescan; spath: procedure (path$p, info$p, status$p) external; declare (path$p, info$p, status$p) address; end spath; delete: procedure (path$p, status$p) external; declare (path$p, status$p) address; end delete; rename: procedure (old$p, new$p, status$p) external; declare (old$p, new$p, status$p) address; end rename; attrib: procedure (path$p, attrib, on$off, status$p) external; declare (path$p, attrib, on$off, status$p) address; end attrib; consol: procedure (ci$p, co$p, status$p) external; declare (ci$p, co$p, status$p) address; end consol; load: procedure (path$p, load$offset, switch, entry$p, status$p) external; declare (path$p, load$offset, switch, entry$p, status$p) address; end load; whocon: procedure (conn, buff$p) external; declare (conn, buff$p) address; end whocon; error: procedure (error$num) external; declare (error$num) address; end error; de$time: procedure (dt$p, status$p) external; declare (dt$p, status$p) address; end de$time; filinf: procedure (file$table$p, mode, file$info$p, status$p) external; declare (file$table$p, file$info$p, status$p) address, RECVKCI COCSTSIOCHKIODEFIOSET@ISISLO PORI;8ATTRIB88CLOSEK8CONSOLe8DELETEx8EXIT8LOAD8MEMCK8OPEN8READ8RENAME9RESCAN&9SEEKJ9WHOCONc9WRITE9SPATH9ERROR9GETD9FILINF9DETIME9@P01019@P0102CI6 NDS-II file does not exist 1 : :::8!:6+6>!:6*:& : ~ 6!:46*:& : ~ 6!:46!:46:*:& : :ͱ8>:ͺ9776: c9x8*: :::8>:ͺ98>:ͺ9ʉ7*:!:s>!:ډ7::=O! : 6 !:4l7 !:6!:6>!:7*:& : N *:& : ::2:!:4˜7*:M  2:::7x8::8*: :::8L7*:DM:88 x8v!:r+s+p+q+p+q+p+q: @!:r+s+p+q:@!:r+s+p+q+p+q:@!:r+s+p+q:@!:":: @!:r+s+p+q+p+q+p+q+p+q:@`o!:r+s+p+q+p+q+p+q+p+q:@!:r+s+p+q+p+q+p+q+p+q:@!:r+s+p+q+p+q:@!:r+s+p+q: @!:r+s+p+q+p+q+p+q+p+q:@!:r+s+p+q!:":: @!:r+s+p+q+p+q+p+q:@@!:r+s+p+q+p+q:!9*9> !:+p+qO@o&ogT::6 isis: procedure (type, parameter$ptr) external; declare type byte, parameter$ptr address; end isis; open: procedure (conn$p, path$p, access, echo, status$p) external; declare (conn$p, path$p, access, echo, status$p) address; end open; close: procedure (conn, status$p) external; declare (conn, status$p) address; end close; read: procedure (conn, buff$p, count, actual$p, status$p) external; declare (conn, buff$p, count, actual$p, status$p) address; end read; wr  mode byte; end filinf; getd: procedure (did, conn$p, count, actual$p, table$p, status$p) external; declare (did, conn$p, count, actual$p, table$p, status$p) address; end getd; exit: procedure external; end exit; ci: procedure byte external; end ci; co: procedure (char) external; declare (char) byte; end co; ri: procedure byte external; end ri; po: procedure (char) external; declare (char) byte; end po; lo: procedure (char) external; declare (char) byte; end lo; csts: procedure byte external; end csts; iodef: procedure (type, entry) external; declare type byte, entry address; end iodef; iochk: procedure byte external; end iochk; ioset: procedure (value) external; declare value byte; end ioset; memck: procedure address external; end memck; $list SEND@]lISISOPENCLOSEREADWRITESEEKRESCANSPATHDELETERENAMEATTRIBCONSOLLOADWHOCONERRORDETIMEFILINFGETDEXITCICORIPOLOCSTSIODEFIOCHKIOSETMEMCK@P0096@P0101 TO " NDS-II file already exists " File transfer complete X< Missing . Correct syntax is:- SEND TO x)8!q:a/>z!/HY: :"Q$ 9=GTZU1!6*+:"*& ~ !6+6>!:!O! N8*& !6!4::2*& ~ +!4*& *>{2:­*DM"!6!6>!*& w*& :2!4·22!:*À!4­<Tv", ")el '$s%,05>GKSV^p +$@ RDYavy~14e , GET it to ; the byte bucket. :f5:svcs. get :f4:remote.db(serial,,cp) to :bb: write :f5:svcs. put :f4:remote.db(serial,,cp) from :f1:serial.ext ; Create and fill the remaining units of the database :f5:svcs. admin :f4:remote.db add(unit = fileio from :f1:fileio.plm) :f5:svcs. put :f4:remote.db(fileio,,oj) from :f1:fileio.obj :f5:svcs. get :f4:remote.db(fileio,,cp) to :bb: write :f5:svcs. put :f4:remote.db(fileio,,cp) from :f1:fileio.ext  :f5:svcs. admin :f4:remote.db add(unit = send from :f1:send.plm) :f5:svcs. put :f4:remote.db(send,,oj) from :f1:send.obj :f5:svcs. get :f4:remote.db(send,,cp) to :bb: write :f5:svcs. put :f4:remote.db(send,,cp) from :f1:send :f5:svcs. admin :f4:remote.db add(unit = recv from :f1:recv.plm) :f5:svcs. put :f4:remote.db(recv,,oj) from :f1:recv.obj :f5:svcs. get :f4:remote.db(recv,,cp) to :bb: write :f5:svcs. put :f4:remote.db(recv,,cp) from :f1:recv :f5:svcs. admin :f4:remote.db add(unit = common from :f3:common.lit) :f5:svcs. admin :f4:remote.db add(unit = isis from :f3:isis.ext) :f5:svcs. admin :f4:remote.db add(unit = exec from :f1:remote.mke) :f5:svcs. put :f4:remote.db(exec,,oj) from :f1:remote :f5:svcs. get :f4:remote.db(exec,,cp) to :bb: write :f5:svcs. put :f4:remote.db(exec,,cp) from :f1:user.man ; Now the database is built, filled ; Submit file to create and fill the remote database from initial sources. ; It is submitted one time only. Once the database is created and filled, ; future changes are made using the SVCS ADD, PUT and GET commands. ; Device assignments are as follows : ; :f0: - Directory containing ISIS system files ; :f1: - Directory containing files supplied on tutorial disk ; :f2: - Directory containing 8 bit system software files. Such ; as PL/M-80, (8 bit) SVCS and MAKE compiler. ; :f3: - Directory containing 8 bit libraries. Such as system.lib. ; common.lit and isis.ext, suppiled on the tutorial disk, ; must be moved to this directory. ; :f4: - Directory where all the database files will be created. ; :f5: - Directory containing the 16 bit system software. Such as ; PL/M-86, (16 bit) SVCS and MAKE. ; Author : B. Valentine - DSSO Applications Engineering 6/22/83 ; Create the data base run :f5:svcs. admin :f4:remote.db create ; Since more than one person will access the database - make it shareable ; SVCS will propagate these access rights across all database files. access :f4:remote.db wr1 ww1 ; Now that the database is created, fill it with the files suppiled on the ; tutorial disk. The WORK variant will then contain the version of REMOTE ; for the iPDS running under ISIS.. ; ADD may be used to initialize SOURCE files, but ; PUT must be used to initialize OBJECT,HISTORY or COMPOSITION files. run ; Create a unit called remote and fill it with the source file remote.plm :f5:svcs. admin :f4:remote.db add(unit = remote from :f1:remote.plm) ; Now fill the object class of the remote unit :f5:svcs. put :f4:remote.db(remote,,oj) from :f1:remote.obj ; Note that if the variant name is not specified (remote,,oj), WORK is the ; default. ; Continue creating units and filling them with the files. :f5:svcs. admin :f4:remote.db add(unit = rmsend from :f1:rmsend.plm) :f5:svcs. put :f4:remote.db(rmsend,,oj) from :f1:rmsend.obj :f5:svcs. admin :f4:remote.db add(unit = rmrecv from :f1:rmrecv.plm) :f5:svcs. put :f4:remote.db(rmrecv,,oj) from :f1:rmrecv.obj :f5:svcs. admin :f4:remote.db add(unit = serial from :f1:serial.plm) :f5:svcs. put :f4:remote.db(serial,,oj) from :f1:serial.obj ; Note in the next command how you must GET (write permission) a composition ; unit before you can PUT to it. Since it has nothing in it yet and saved in :f4: ; exit SENDKCI COCSTSIOCHKIODEFIOSET@ISISLO PORI;8ATTRIB8CLOSE9CONSOL)9DELETE<9EXITK9LOADo9MEMCKu9OPEN9READ9RENAME9RESCAN9SEEK:WHOCON':WRITEH:SPATHg:ERRORu:GETDx:FILINF{:DETIME~:@P0096:@P0097:@P0101:@P01026 TO NDS-II file already exists File transfer complete Missing . Correct syntax is:- SEND TO 1::Y;W;͙9!];6*W;+:];~:ڢ8*];&: ~ ›8!_;6+6>!^;چ7:^;!];O!: N͸8*^;&6 7!_;6!^;4R7:_;қ8:];2];*];&: ~ «7!];4Õ7[;*];&: Y;u9*[;:Y;W;͙9>W;͈:76Y;':<9 2c;:c;-8*[;DMY;86Y;':<9!a;6!];6>!];d8*];&: w*];&: :a;2a;!];4782b;2c;!a;:b;ʂ8 Ø8*[;:Y;': 8!];4-76Y;T':<9v!d;q:d;a/>z!d;/H8:d; :d;!l;r+s+p+q+p+q+p+qe; @!p;r+s+p+qm;@!v;r+s+p+q+p+qq;@!z;r+s+p+qw;@!{;"{;{; @!;r+s+p+q+p+q+p+q+p+q};@`o!;r+s+p+q+p+q+p+q+p+q;@!;r+s+p+q+p+q+p+q+p+q;@!;r+s+p+q+p+q;@!;r+s+p+q; @!;r+s+p+q+p+q+p+q+p+q;@!;r+s+p+q!;";; @!;r+s+p+q+p+q+p+q;@@!;r+s+p+q+p+q;!f:*F:> !;+p+qO@O{ozgo&ogɞ;;7 so note how some of the files have the same right hand size dependencies ; accept for the changing of the file name. Pass 2 of the make file will ; show how these can be combined into an iteration loop. $IF :f1:serial.obj > :f1:serial.plm, :f3:common.lit THEN :f2:plm80 :f1:serial.plm $END $IF :f1:fileio.obj > :f1:fileio.plm, :f3:common.lit THEN :f2:plm80 :f1:fileio.plm $END $IF :f1:remote.obj > :f1:remote.plm, :f3:common.lit, :f1:serial.ext , $:f1:fileio.ext THEN :f2:plm80 :f1:remote.plm $END $IF :f1:rmsend.obj > :f1:rmsend.plm, :f3:common.lit, :f1:fileio.ext, $:f1:serial.ext THEN :f2:plm80 :f1:rmsend.plm $END $IF :f1:rmrecv.obj > :f1:rmrecv.plm, :f3:common.lit, :f1:fileio.ext, $:f1:serial.ext THEN :f2:plm80 :f1:rmrecv.plm $END ; Check the status of the remote executable file. $IF :f1:remote > :f1:remote.obj, :f1:rmsend.obj, :f1:rmrecv.obj, $:f1:fileio.obj, :f1:serial.obj, :f3:plm80.lib, :f3:system.lib THEN :f2:link :f1:remote.obj, :f1:rmsend.obj, :f1:rmrecv.obj, & :f1:fileio.obj, :f1:serial.obj, :f3:plm80.lib, :f3:system.lib to & :f1:remote.lnk :f2:locate :f1:remote.lnk symbols lines map print(:f1:remote.map) $END ; Now that the remote program has been checked, check the two programs ; that run on the network. ; Check the NDS-II files RECV and SEND. ; Check SEND ; Since there is only one module to the send program, we can test the ; executable file against the source code. $IF send > :f1:send.plm, :f3:common.lit, :f3:is; Submit file to generate the remote executable file that runs on the ; iPDS system under ISIS. ; Author : B. Valentine DSSO Applications Engineering 6/23/83 ; Generate REMOTE file to run on the iPDS system ; First of all, compile all the source code. :f2:plm80 :f1:remote.plm :f2:plm80 :f1:rmsend.plm :f2:plm80 :f1:rmrecv.plm :f2:plm80 :f1:fileio.plm :f2:plm80 :f1:serial.plm ; Now link them together :f2:link :f1:remote.obj,:f1:rmsend.obj,:f1:rmrecv.obj,:f1:fileio.obj, & :f1:serial.obj,:f3:plm80.lib,:f3:system.lib to :f1:remote.lnk ; Now locate the link file :f2:locate :f1:remote.lnk symbols lines map print(:f1:remote.map) ; Move the file to the system directory copy :f1:remote to remote b ; Generate SEND that runs on the network :f2:plm80 :f1:send.plm :f2:link :f1:send.obj,:f3:system.lib,:f3:plm80.lib to :f1:send.lnk :f2:locate :f1:send.lnk copy :f1:send to send b ; Generate RECV that runs on the network :f2:plm80 :f1:recv.plm :f2:link :f1:recv.obj,:f3:system.lib,:f3:plm80.lib to :f1:recv.lnk :f2:locate :f1:recv.lnk copy :f1:recv to recv b ; Make file for the isis remote program ; This make program uses the least complicated make constructs to test the ; the dependencies. ; Author : B. Valentine DSSO Applications Engineering 6/25/83 ; Set the dependency tree for three seperate executable files. ; Fool the make utility into building the dependency tree for three ; unrelated (executable) programs by using all. $IF all > :f1:remote, send, recv THEN $END ; Note how in the next construct the source code include files are added. ; Al is.ext THEN :f2:plm80 :f1:send.plm :f2:link :f1:send.obj,:f3:system.lib, :f3:plm80.lib to :f1:send.lnk :f2:locate :f1:send.lnk copy :f1:send to send b $END ; Check RECV $IF recv > :f1:recv.plm, :f3:common.lit, :f3:isis.ext THEN :f2:plm80 :f1:recv.plm :f2:link :f1:recv.obj,:f3:system.lib, :f3:plm80.lib to :f1:recv.lnk :f2:locate :f1:recv.lnk copy :f1:recv to recv b $END ; Second pass of the make file for the remote program. ; This pass has added the make constructs of macros and iteration to ; pass one of the make file. ; Author : B. Valentine DSSO Applications Engineering 6/25/83 ; First of all define the macros for the make file. ; Define the subsitution macros : ; Subsitution macros are used as constant defines. This way, if ; a major change is made, such as the source code device changes ; from :f1: to :f2:, the only update to the make file is to change ; the macro definition. $ SET work_device to ':f1:' $ SET 8_bit_exe to ':f2:' $ SET 8_bit_lib to ':f3:' ; Note how macros may be nested and the macro is used with the %"". $ SET plm to '%"8_bit_exe"plm80' $ SET locate to '%"8_bit_exe"locate' $ SET link to '%"8_bit_exe"link' $ SET syslib to '%"8_bit_lib"system.lib' $ SET plmlib to '%"8_bit_lib"plm80.lib' $ SET comlit  to '%"8_bit_lib"common.lit' $ SET isis to '%"8_bit_lib"isis.ext' ; Now define the enumeration macros : $ SET nds2_files to (recv,send) $ SET remote_files to (rmrecv,rmsend) ; Now start the dependecies ; Set the dependency tree for three seperate executable files. $IF all > %"work_device"remote, send, recv THEN $END $IF %"work_device"serial.obj > %"work_device"serial.plm, %comlit THEN %plm %"work_device"serial.plm $END $IF %"work_device"fileio.obj > %"work_device"fileio.plm, %comlit THEN %plm %"work_device"fileio.plm $END $IF %"work_device"remote.obj > %"work_device"remote.plm, $%comlit, %"work_device"serial.ext , %"work_device"fileio.ext THEN %plm %"work_device"remote.plm $END $FOR i IN %remote_files ; Build the send and receive modules for the remote system. $ IF %work_device%"i".obj > %work_device%"i".plm, %comlit, $ %"work_device"fileio.ext, %"work_device"serial.ext THEN %plm %work_device%"i".plm $  END $END ; Check the remote executable file $IF %"work_device"remote > %"work_device"remote.obj, $%"work_device"rmsend.obj, %"work_device"rmrecv.obj, $%"work_device"fileio.obj, %"work_device"serial.obj, $%plmlib, %syslib THEN %"link" %"work_device"remote.obj, & %"work_device"rmsend.obj, %"work_device"rmrecv.obj, & %"work_device"fileio.obj, %"work_device"serial.obj, & %plmlib, %syslib to %"work_device"remote.lnk %locate %"work_device"remote.lnk symbols lines &  map print(%"work_device"remote.map) $END ; Now that the remote program has been checked, check the two programs ; that run on the network. $FOR i IN %nds2_files ; Check the NDS-II files RECV and SEND. $ IF %i > %work_device%"i".plm, %comlit, %isis THEN %plm %work_device%"i".plm %link %work_device%"i".obj,%syslib, %plmlib to %work_device%"i".lnk %locate %work_device%"i".lnk copy %work_device%"i" to %i b $ END $END "RMSEND.OBJ#USER.MAN$REMOTE.PLM%REMOTE&RMRECV.PLM'RMSEND.PLM(SERIAL.PLM)RECV.OBJ*SEND.PLM+RECV,ISIS.EXT-SEND.OBJ.MAKEDB.CSD/SEND0REMCSD.EXM1REMMKE.EXM2RMMKE1.EXMr?SPACEMAPr?FNODEMAPr?ACCOUNTINGr?BADBLOCKMAPr?ISOLABELr?VOLUMELABELr?DUPFNODE r?DUPSPACEMAP r?DUPFNODEMAP r?DUPBADBLOCK r?DUPBLOCKZERO OS88.RESIDENTOS88.OVERLAYWORKSTATION.OSWORKSTATION.OVVERIFYFIXr?RESERVED1r?RESERVED2REMOTE.CSDREMOTE.CPMSERIAL.EXTREMOTE.MKEFILEIO.EXTREMOTE.OBJRECV.PLMFILEIO.PLMSERIAL.S2FILEIO.OBJSERIAL.OBJRMRECV.OBJ FILEIO.CPM!COMMON.LITd22d%} vd22d% ]}  % b}  L % f}  % k} A?%$ o} ) X %- t} 1 i$ %5 x} 8 ,%< |} A  0 %ᔹ } 唹 O%锹 } 픹  % }  %E } H 8%L } O }<%S } U @%Y } ] e D %a } f i L%j } m #X%q } u 8\%y } | ` % } : h% t% }  % } ' J% } % } |% } Y  % % } Ŕ [  %ɔ } ͔ %є } Ք  %ٔ ݔ ݔ b    d22d%} v%E } H 8%L } O }<%S } U @%Y } ] e D %a } f i L%j } m #X%q } u 8\%y } | ` % } : h% t% }  % } ' Jd22d% ]}  % b}  L % f}  % k} A?%$ o} ) X %- t} 1 i$ %5 x} 8 ,%< |} A  0 % } % } |% } Y  % % } Ŕ [  %ɔ } ͔ %є } Ք  %ٔ ݔ ݔ b%ᔹ } 唹 O%锹 } 픹  % }        !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOO114310.001  SERIES IV y~