0 'Club 100 Library - 415/939-1246 BBS, 937-5039 Newsletter, 932-8856 Voice 1 'TDDCMD.BA by Woods Martin 09/06/86 2 'TDD COMMANDS gleaned from DSKL.PDD by Richard Haw, DIRDSK.TDD by Tony Anderson, FORMAT.TDD & ERASER.TDD by Afterhours Software and TANDY DOS DISASSEMBLED by Scott Turner... and a lot of my own experimentation. 3 'TDDCMD is designed to be a runable program to demonstrate the commands as well as to illustrate how they may be used. It is implemented in BASIC for the M100 but should work on the M200 by correcting the CB and CN addresses in lines 20 and 25. 4 'The foregoing programs all work but contain some conflicting information which I have attempted to resolve. Tandy could make things easier by publishing a TDD technical reference manual but the secrets will come out one way or the other. 5 'CAUTION: THIS IS AN ONGOING LEARNING EXPERIENCE -- THESE ROUTINES ARE FULLY CAPABLE OF EATING FILES AND DISKS. ENJOY -- BUT AT YOUR OWN RISK. 6 ' 7 'This file is posted as a start toward compiling a complete command set for the TDD and all corrections, additions and comments are most welcome and will be included in later versions. 8 'Most needed is a RS232 input routine capable of handling 131 character messages from the TDD at 19200 baud under BASIC. Experimentation with other QUERY and QParameter values than those used here may well reveal more TDD features than we know about. 9 ' 10 'INITIALIZATION - All variables used will be explicitly typed but "real programs" will probably predefine them to save space. 15 MAXFILES=2:CLEAR1000:ONERRORGOTO300:CP$="COM:98N1DNN":GOSUB76 20 CB=65350' M100:address of RS232 buffer. 25 CN=65414' M100:address of number of bytes in RS232 buffer at CB, yet to receive INPUT. CN+1 is address of pointer in CB to last byte already has INPUT. CN+2 is address of pointer in CB to last byte, yet to receive INPUT. 30 CB$="":CV=VARPTR(CB$):CA%=CB/256:POKECV+1,CB-256*CA%:POKECV+2,CA%:POKECV,64' string pointing to RS232 buffer for use by INPUT bypass routine. See line 92. 40 RS%=0:CLS:PRINT" TDD Commands [c] by Woods Martin" 50 PRINT"S=Status of drive W=Write to file" 51 PRINT"L=List directory A=Append to file" 52 PRINT"N=Number 1 file R=Retrieve data" 53 PRINT"G=Get next file I=Input data" 54 PRINT"O=Open to read D=Delete file" 55 PRINT"C=Close file F=Format disk" 60 S%=0:PRINT@280,"M=Menu (Hit ENTER to Return) Select:";:GOSUB62 61 CLS:IFS$="-"THEN40ELSEONINSTR("SsMmLlNnGgOoAaRrWwCcIiDdFf",S$)+1GOSUB100,100,110,110,120,120,125,125,130,130,140,140,150,150,160,160,170,170,180,180,190,190,200,200,210,210,220,220:GOTO60 62 S$=INPUT$(1):S$=CHR$(ASC(S$)OR32):RETURN 64 BEEP:PRINTMG$" - are you sure ? ";:GOSUB62:PRINTS$:MG%=(S$="y"):RETURN 66 QF$="":INPUT"File Name & Ext (use CAPS) ";QF$:RETURN 68 I%=INSTR(1,QF$,"."):IFI%<2ORI%>7THENQF$=""ELSEQF$=LEFT$(QF$,I%-1)+SPACE$(7-I%)+MID$(QF$,I%)' Pad file name to 6 characters plus extension to agree with BASIC. The TDD doesn't seem to care and will accept Upper or Lower case up to 24 characters. 69 QS$=QF$+SPACE$(24-LEN(QF$))+"F"+CHR$(QP%):RETURN' Build filename string for open QUERY=0 padded to 24 characters and followed by "F" and the QUERY=0 QParameter. 70 CK%=0:FORC1%=1TOLEN(S$):CK%=CK%+ASC(MID$(S$,C1%)):NEXT:CK%=(CK%MOD256)XOR255:RETURN' Calculate checksum on string S$. 72 IFLEN(CK$)=0THENCK%=0:RETURNELSEGOSUB70:CK%=(CK%=ASC(CK$)):RETURN' Compare calculated checksum with received checksum byte CK$. 76 CLOSE:OPENCP$FORINPUTAS1:OPENCP$FOROUTPUTAS2:RETURN' Open COM: for output/input to/from TDD. 78 FORI%=1TO100:NEXT:RETURN' Time delay routine 80 QS$=CHR$(QU%)+CHR$(LEN(QS$))+QS$:S$=QS$:GOSUB70:QS$="ZZ"+S$+CHR$(CK%):PRINT#2,QS$;:RETURN' Send 'ZZ' QUERY=QU% QueryString QS$ and checksum to TDD. 90 RS%=0:S$=INPUT$(4,1):RS%=ASC(S$):RP%=ASC(MID$(S$,3)):RETURN' Get status RESPONSE from TDD. RS%=response type, RP%=response RParameter. 92 RS%=0:RF%=0:S$=INPUT$(2,1):RS%=ASC(S$):RL%=ASC(MID$(S$,2)):IFRS%<>17ORRL%<>28THEN97ELSER1%=PEEK(CN+1)+1:RF%=ASC(MID$(CB$,R1%)):RS$=MID$(CB$,R1%,28):S$=S$+RS$:CK$=MID$(CB$,R1%+28,1):GOSUB72:IFCK%THEN98ELSEPRINT"Cker ";:GOTO98 93 'If RF%=17 get file name from TDD, RF%=0 means file does not exist. Since the response string, RS$ contains file length and free sectors which might contain a ASCII "26" (BASIC's EOF) the INPUT$ statement is not used. 94 'RS$ is checked for correct checksum and (for this demo) "Cker " is printed if error. 95 ' 97 IFRS%=18ANDRL%>0THENS$=INPUT$(2,1):RP%=ASC(MID$(S$,2)) 98 POKECN,0:POKECN+1,0:POKECN+2,0:RETURN' Reset pointers to RS232 buffer to indicate that all characters have been processed. 100 PRINT"Error":BEEP:RETURN 109 ' 110 'QUERY 7 - Drive Status 111 RS%=0:QU%=7:QS$="":GOSUB80:PRINT#2,CHR$(13);:GOSUB78:IFPEEK(CN)>3THENGOSUB90:IFS%ANDRS%=18ANDRP%=0THENRETURN' Send QUERY=7, a RETURN and wait for time delay. Be sure at least 4 characters have been received and then read them. 112 'RP%=18 "Drive OK". RP%=0 "Disk OK". If S% is true, return to caller, otherwise print message. 113 PRINT"Drive";:IFRS%=67THENPRINT" Wrong mode - try switch":PRINT#2%,"M1"CHR$(13);:GOSUB78:GOTO110ELSEIFRS%<>18THENPRINT":No response - turn drive off/ON":PRINT"Press ENTER "INPUT$(1):GOSUB76:RETURNELSEPRINT" OK - Disk "; 114 IFRP%=0THENA$="OK"ELSEIFRP%=16THENA$="File not found"ELSEIFRP%=48THENA$="End of File"ELSEIFRP%=64THENA$="I/O Error"ELSEIFRP%=80THENA$="Write protected"ELSEIFRP%=96THENA$="No space"ELSEIFRP%=113THENA$="out, check door!"ELSE117 115 GOTO118 117 IFRP%=167THENA$="needs Formatting"ELSEA$="Error"+STR$(RP%) 118 PRINTA$:RETURN 120 GOSUB190:MAXFILES=1:MENU 124 ' 125 'DIRECTORY using QUERY=0 QParameters 1 and 2 126 GOSUB130:IFS%=0ORRF%=0THENRETURN' Get first file name. 127 GOSUB140:IFS%=0ORRF%=0THENRETURNELSE127' Get next file name until "File not found" message. 129 ' 130 'QUERY=0 QParameter 1 - Find first file 131 QP%=1:GOSUB142:IFS%=0ORRF%THENRETURNELSEPRINT"Disk empty":RETURN 139 ' 140 'QUERY=0 QParameter 2 - Find next file 141 QP%=2 142 GOSUB148:IFS%=0THENRETURNELSEQF$=""' Check drive status. Null filename QF$ for QUERY=0 QParameters 1 & 2 143 QU%=0:GOSUB68:GOSUB80:GOSUB92:IFRS%<>17THEN113ELSEIFRF%=0%THEN146' Process QS query string and send QUERY=0 to TDD and expect RESP=17. 144 PRINTUSING"\ \ ##### ###";MID$(RS$,1,10),256*ASC(MID$(RS$,26))+ASC(MID$(RS$,27)),ASC(MID$(RS$,28)):RETURN' Sample use of data received. The first 6 characters are the BASIC filename plus a 2 character extension (3 for Floppy_Sys). 145 'Character 26 is the HIGH byte and character 27 the LOW byte of the file length (reverse of M100 convention). Character 28 is the number of free sectors on the disk and is returned with every filename! 146 BEEP:PRINT"File not found":RETURN 148 S%=1:GOSUB110:IFRS%=0ORRP%<>0THENS%=0:RETURNELSERETURN' Check drive status, in these examples this is done before every QUERY but many programmers seem to bypass this step after the first time -- at their own peril, I might say. 149 ' 150 'QUERY=0 QParameter 0 - Open file QF$ QUERY=1 QParameter 3 - Position to read 151 QP%=3:GOSUB154:IFS%=0THENRETURNELSEIFRF%ANDRP%=0THENPRINT"Ready to Read":RETURNELSERETURN' Try to open file, then position for reading with QUERY=1 QP 3. 154 GOSUB156:IFS%=0THENRETURNELSEGOSUB158:RETURN 156 GOSUB148:IFS%=0THENRETURNELSEGOSUB66:IFQF$=""THENS%=0:PRINT"Illegal file name":BEEP:RETURNELSEQT%=QP%:QP%=0:GOSUB143:QP%=QT%:RETURN'Open file. 158 QU%=1:QS$=CHR$(QP%):GOSUB80:GOSUB90:RETURN' Position file. 159 ' 160 'QUERY=0 QParameter 0 - Open file QUERY=1 QParameter 2 - Position to append 161 QP%=2:GOSUB154:IFS%=0THENRETURNELSEIFRF%ANDRP%=0THENPRINT"Ready to Append":GOTO201ELSERETURN 169 ' 170 'QUERY=3 - Get data string 171 QU%=3:QS$="":GOSUB80:GOSUB78:A$=INPUT$(PEEK(CN),1):IFASC(A$)=16THENPRINTMID$(A$,3) 172 RETURN 173 'This is a crude input routine which handless only the first 64 characters of each 131 character response string. The 131 characters come in at 19200 baud in one big rush and the 64 character RS232 buffer overflows losing the last 67. 174 'Assignment: Write a 131 (min) character input routine in ML and poked into a BASIC string which can capture all 131 characters. 179 ' 180 'QUERY=0 QParameter 0 - Open file QUERY=1 QParameter 1 - Position to write 181 QP%=1:GOSUB154:IFS%=0OR(RP%ANDRP%<>48)THENRETURN 183 IFRF%=0THENPRINT"Ready to Write New File":GOTO201ELSEMG$="File already exists":GOSUB64:IFMG%THENRF%=0:GOTO183ELSERETURN 189 ' 190 'QUERY=2 - Close file 191 QU%=2:QS$="":GOSUB80:GOSUB90:IFRS%=18ANDRP%=0THENPRINT"File Closed":RETURNELSE113 199 ' 200 'QUERY=4 - Input data string 201 PRINT"Type Data to be stored, ending lines":PRINT"with a RETURN. "CHR$(34)"Extra"CHR$(34)" RETURN to END." 203 PRINT:QS$="":LINEINPUTQS$:IFQS$=""THEN191 205 S%=1:QU%=4:GOSUB80:GOSUB90:IFRS%<>18ORRP%<>0THEN113ELSE203 206 'A file could be transferred here, QS$ should not be longer than 128 characters. 209 ' 210 'QUERY=0 QParameter 0 - Open file QUERY=5 - Delete file 211 GOSUB 156:IFS%=0THENRETURNELSEIFRF%=0THENRETURNELSEMG$="Delete "+QF$:GOSUB64:IFMG%=0THENRETURNELSEQU%=5:QS$="":GOSUB80:GOSUB90:IFRS%=18ANDRP%=0THENPRINT"File Deleted":RETURNELSE113 212 STOP 219 ' 220 'QUERY=6 - Format disk 221 S%=1:GOSUB130:IFS%=0THENRETURNELSEMG$="":IFRF%THENMG$="Contains Data" 223 MG$="Format":GOSUB64:IFMG%=0THENRETURNELSEQU%=6:QU$="":GOSUB80:GOSUB90:IFRS%=18ANDRP%=0THENPRINT"Formatted OK":RETURNELSE113 300 IFERL=171ANDERR=5THENRESUME172 310 ONERRORGOTO0