!	 SDOS 1.1 Diagnostic Part II -- Disk device and File diagnostic
!	 Tests SDOS for proper operation
!
!	Line Numbers are used within tests only for branch pts
!	or for parts of the code that actually perform the desired test
!	setup code is presumed to work perfectly; if it fails,
!	some other part of the diagnostic will fail!
!	All channels opened by a test are closed upon successful completion of test
!	DISK: must be write enabled to run these diagnostics
!	Note that various tests fiddle with disk tuning parameters

	Dim MinTestNumber/100/,MaxTestNumber/199/
	Dim OnDiskFile$/" on a Disk File"/,OnDiskDevice$/" on a Disk Device"/
	Dim Null$(0)
	Dim OneByte$(1),A5$/:a5/,TempFileName$/"Test.Tmp"/,Disk$/"Disk:",:d/
	Rem Temp$ and Temp1$ must be the same length!
	Rem Temp$ is 128 long so syscalls of max length can be constructed in it
	Dim Temp$(128),Temp1$(128)
	Dim ScratchDisk$(20)/""/


	Dim SyscallCreate$/1,14,0,0/
	Dim SyscallWriteB$/:d,8,0,0/
	Dim Rename$/3,14,0,0/
	Dim CCIllegal$/:e,:4,0,:ff/,SCIllegal$/:f,14,0,:FF/

	Dim SCGetPos$/:f,14,0,0/
	Dim SCGetCol$/:f,14,0,1/
	Dim SCGetEof$/:f,14,0,2/
	Dim SCGetFileSize$/:f,14,0,3/
	Dim SCGetType$/:f,14,0,4/
	Dim SCGetParams$/:f,14,0,5/

	Dim CCPosition$/:e,8,0,0/
	Dim CCDumpBuffers$/:e,4,0,1/

	Dim SCGetFileDate$/:f,14,0,:10/
	Dim SCGetFileProt$/:f,14,0,:11/

	Dim SCGetLastBadLsn$/:f,14,0,:10/
	Dim SCGetErrorStats$/:f,14,0,:11/


	Dim CCSetFileDate$/:e,8,0,:10/
	Dim CCSetFileProt$/:e,8,0,:11/
	Dim CCSetFileSize$/:e,4,0,:12/
	Dim CCPositionToEnd$/:e,4,0,:13/

	Dim CCUnlockDisk$/:e,4,0,:10/
	Dim CCDismount$/:e,4,0,:11/
	Dim CCSetMapAlgorithm$/:e,8,0,:12/

Def Value(Valuearg$)
	Rem Function that returns value of bytes in Valuearg$
	Let ValueResult=0
	For i=1 to len(Valuearg$)
		Let Valueresult=Valueresult*256+Valuearg$[i]
	Next i
	Return Valueresult
End

Def MSB(MSBarg)=Int(MSBarg/256)

Def LSB(LSBarg)=LSBarg-MSB(LSBarg)*256

! ******* Diagnostic Main program starts here

	Print "SDOS 1.1 Diagnostic V1.1: Test Disk Files and Device Syscalls"
AskTest: ! Ask for test to run next
	Input "Test number (default is 'all', '?' list test names): " Temp$
	! Assume we'll run a bunch of tests
	AutoPilot=True
	DontExecute=False
	If Temp$=""
	Then
		For TestNumber=MinTestNumber to MaxTestNumber
			Gosub BranchonTestNumber
		Next TestNumber
		Print "Diagnostic test completed."
		Goto AskTest
	Elseif Temp$="?"
	Then
		! Display all the options
		Dontexecute=true
		For TestNumber=MinTestNumber to MaxTestNumber
			Gosub BranchOnTestNumber
		Next TestNumber
		Goto AskTest
	Fi
	If Error When TestNumber=Val(Temp$)
	Then
		If Temp$[1,1]=">"
		Then
			For TestNumber=Val(Right$(Temp$,2))+1 to MaxTestNumber
				Gosub BranchOnTestNumber
			Next TestNumber
			Print "Partial Test completed."
		Else Print "Idiot..."
		Goto AskTest
	Else
		Autopilot=false
		If TestNumber=0 then Exit
		If TestNumber<MinTestNumber or TestNumber>MaxTestNumber
		Then Print "Can't test that in this Pass of the Diagnostic"
		Else Gosub BranchOnTestNumber
		Goto AskTest
	Fi

BranchOnTestNumber:
	Print "Test #";TestNumber;
	On TestNumber-99 Goto...
&	10000,10100,10200,10300,10400,10500,10600,10700,10800,10900,...
&	11000,11100,11200,11300,11400,11500,11600,11700,11800,11900,...
&	12000,12100,12200,12300,12400,12500,12600,12700,12800,12900,...
&	13000,13100,13200,13300,13400,13500,13600,13700,13800,13900,...
&	14000,14100,14200,14300,14400,14500,14600,14700,14800,14900,...
&	15000,15100,15200,15300,15400,15500,15600,15700,15800,15900,...
&	16000,16100,16200,16300,16400,16500,16600,16700,16800,16900,...
&	17000,17100,17200,17300,17400,17500,17600,17700,17800,17900,...
&	18000,18100,18200,18300,18400,18500,18600,18700,18800,18900,...
&	19000,19100,19200,19300,19400,19500,19600,19700,19800,19900
	Print "Can't perform that test in this pass..."
	Return

NonexistentTest: Print "Nonexistent test"
	Return

IncompleteTest:
	Print "This test is not yet complete!"
	Return

Fail:	! Test failed
	Print "Failed to pass"
	If not Autopilot
	then
		If Error When Close #1
		Then if Err<>1032 Then Error fi
		Gosub Pop 0\ Goto AskTest
	Fi
	Return

ScrambleTemp: ! Fill Temp$ with garbage so we can be sure that reply is returned
	For i= 1 to Maxlen(Temp$) do Temp$[i]=int(Rnd*255)
	Let Len(Temp$)=Maxlen(temp$)
	Return

!
!	Disk "device" tests
!
OpenScratchDisk:
	Rem routine to open a scratch disk; if none, ask for one
	If Len(ScratchDisk$)=0
	Then Input "Enter name of disk with scratch diskette in it: " ScratchDisk$
	Open #1,ScratchDisk$
	Syscall #1,CCUnlockDisk$
	Return
	
10000	Print "SYSCALL:OPEN";OnDiskDevice$
	If Dontexecute then return
	Rem check for "Dxxx:<CR>" being ref to disk device
10040	Open #1,Disk$
	If Eof(1) Then Fail
10050	Syscall #1,SCGettype$,Null$,Temp$
	If Temp$[1]<>1 Then Fail
10060	If Error When Write #1,A5$
	Then If Err<>1049 Then Fail fi
	Else Fail
	Close #1
	Return

10100	Print "SYSCALL:CREATE";OnDiskDevice$
	If Dontexecute then return
	Create #1,Disk$
	If Eof(1) Then Fail
	Goto 10050

10200	Print "SYSCALL:CLOSE";OnDiskDevice$
	If Dontexecute then return
	Goto 10040

10300	Print "SYSCALL:RENAME";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	! Rem attempt to rename disk to self
	If Error When Syscall #1,Rename$,Disk$,Temp$
	Then If Err<>1034 Then Fail Fi
	Else Fail
	Close #1
	Return

10400	Print "SYSCALL:DELETE";OnDiskDevice$
	If Dontexecute then return
	If Error When Delete Disk$
	Then If Err<>1034 then Fail fi
	Else Fail
	Return

10500	Print "SYSCALL:READA";OnDiskDevice$
	If Dontexecute then return
	Rem check col cnt adjust properly by print chars
	Rem check ff, cr, bs, tab
	Rem check ^C^C aborts READA thru nulls quickly
	Rem check read/write 0 bytes doesn't advance file pointer
	Rem check read/write n bytes does advance file pointer
	Rem check read with line mode flag on
	Goto IncompleteTest
	Return

10600	Print "SYSCALL:READB";OnDiskDevice$
	If Dontexecute then return
	Goto IncompleteTest
	Return

10700	Print "SYSCALL:WRITEA";OnDiskDevice$
	If Dontexecute then return
	Gosub OpenScratchDisk
	Rem check col cnt adjust properly by print chars
	Rem check ff, cr, bs, tab
	Close #1
	Goto IncompleteTest
	Return

10800	Print "SYSCALL:WRITEB";OnDiskDevice$
	If Dontexecute then return
	Gosub OpenScratchDisk
	Gosub TestWriteBinary
	Rem write across end of file?
	Rem write on un-readable sector?
	Rem Test postion and write past eof gives err
	Rem test positon and write before eof does not
	Close #1
	Return

TestWriteBinary: !  Write binary data into disk device/file
	Rem construct some good binary trash to write
	Gosub ScrambleTemp
	Let Len(temp$)=Maxlen(temp$)
	For i=1 to 500
		! assume disk is 90k bytes or more
10810		Write #1,Temp$
	Next i
	Position #1@0
	For i=1 to 500
10820		Read #1,Temp1$
		If Temp$<>Temp1$ then Fail
	Next i
	! Test write binary zeros column count
	Print #1@0,TempFileName$;\! make column count > 1
10825	If col(1)<=1 then Fail
	Write #1,Null$
10827	If col(1)<>1 then Fail
	! Test position and write
	Let Temp$=SyscallWriteB$
	Let Len(Temp$)=18
	Let Temp$[2]=18 \ ! Set size of system call block to 18
	For k=1 to 100
		let j=int(rnd*65536)
		let Temp$[15]=0
		let Temp$[16]=0
		let Temp$[17]=msb(j)
		let Temp$[18]=lsb(j)
		Syscall #1,Temp$,Temp$[15,4]
		Syscall #1,SCGetPos$,Null$,Temp1$
!		Print "j";j;value(temp1$)
10850		If j+4<>Value(Temp1$) Then Fail
		Read #1@j,Temp1$[1,4]
10855		If Temp$[15,4]<>Temp1$[1,4] Then Fail
	Next k
	Return

10900	Print "illegal SYSCALL:CONTROL";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	If Error When Syscall #1,CCIllegal$
	Then If Err<>1034 then Fail fi
	Else Fail
	Close #1
	Return

11000	Print "illegal SYSCALL:STATUS";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	If Error When Syscall #1,SCIllegal$
	Then If Err<>1034 then Fail fi
	Else Fail
	! Rem check that Status Syscall must include a reply buffer
	Let Temp$=SCGetcol$
!	is it possible that BASIC wont let me set a length smaller than 14?
	For i=2 to 13
		Let Len(Temp$)=i
		Let Temp$[2]=i
11020		If Error When Syscall #1,Temp$
		Then If Err<>1053 Then  Print i;Err\ Goto Fail fi
		Else Fail
	Next i
	Close #1
	Return

11100	Print "SC:GETPOS";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
11105	! Verify that newly-OPENed disk/file is at position zero
	Let Temp$=Time$ \ ! trash contents of Temp$
	Let len(Temp$)=0
11110	Syscall #1,SCGetpos$,Null$,Temp$
11120	If Len(Temp$)<>4 or Value(Temp$)<>0 Then Fail
	Rem check that randomly selected file position can be retreived
	Rem Assume disk has 90k bytes minimum!
	For i=1 to 100
		Let j=Int(rnd*90000)
		Position #1@j
11130		Syscall #1,SCGetpos$,Null$,Temp$
11140		If Value(Temp$)<>j then Fail
	Next i
11150	If Error When Call CheckStatusSyscallCommon(SCGetPos$,4,Temp$)
	Then Fail
	Close #1
	Return

11200	Print "SC:GETCOL";OnDiskDevice$
	If Dontexecute then return
	! This test assumes that the BASIC COL function = 1 + SDOS GETCOL value
	! Verify that Ascii:cr zeros the column count
	Gosub OpenScratchDisk
11210	Print #1
11230	If Col(1)<>1 then Fail
	! Verify that printing characters advance the column count
	Let j=1 \ ! Current column count
	For i=32 to 126
		Print #1,Chr$(i);
		j=j+1\ ! Where column count should be now
11240		If Col(1)<>j Then Fail
	Next i
	! Verify that printing characters with MSB set advance the column count
	Let Len(Temp$)=1
	For i=128+32 to 128+126
		Let Temp$[1]=i
		Print #1,Temp$;
		let j=j+1\ ! Where column count should be now
11250		If Col(1)<>j Then Fail
	Next i
	! Verify BS with or without parity works correctly
	For i=2 to j
		Let Temp$[1]=8+((i&1)**7)
		Print #1,Temp$;
		j=j-1\ ! Where column count should be now
11260		If Col(1)<>j then Fail
	Next i
	! Verify that BS at column zero doesn't decrement column counter
	For i=1 to 10
		Print #1,chr$(8);
11265		If Col(1)<>1 then Fail
	Next i
	! Verify that Form Feed zeros column counter
	Print #1,"Cat";chr$(12);
11270	If Col(1)<>1 Then Fail
	! Verify that Rubout doesn't affect column count
	Print #1,"Cat";chr$(:7f);
11275	If Col(1)<>4 Then Fail
	Let Temp$[1]=:ff
	! Assert: length of Temp$=1
	Print #1,Temp$;
11277	If Col(1)<>4 Then Fail
	! Test tab moves the column count by a multiple of 8
	Print #1 \ ! make column count = 1
	For i= 9 to 255 step 8
		for j=1 to 8*rnd
			print #1,"#";
		next j
		print #1,chr$(9);
11285		if col(1)<>i then Fail
	Next i
	Print #1,Chr$(:D);"Duck";
	! Set up Temp$ to contain proper reply
!	Print "col(1)=";col(1)
	Let Temp$[1]=4
11287	If Error When Call CheckStatusSyscallCommon(SCGetCol$,1,Temp$)
	Then Fail
	Close #1
	Return

ComputeDiskSize:
	! Rem compute size of disk
	Syscall #1,SCGetparams$,Null$,Temp$
	DiskSize=Value(Temp$[1,2])*Value(Temp$[3,2])*Value(Temp$[5,2])*Value(Temp$[7,2])
	Return

11300	Print "SC:GETEOF";OnDiskDevice$
	If Dontexecute then return
	Gosub OpenScratchDisk
	Gosub ComputeDiskSize
	! Verify not EOF when positioning to the very last byte
	Position #1@Disksize-1
	Temp$=Disk$ \ ! Make sure Temp$ gets changed
	Syscall #1,SCGeteof$,Null$,Temp$
11305	If len(Temp$)<>1 then Fail
11306	If Temp$[1]<>0 then Fail
	! Verify EOF when positioning to byte past the last one
	Position #1@Disksize
	Syscall #1,SCGeteof$,Null$,Temp$
11310	If len(Temp$)<>1 Then Fail
11311	If Temp$[1]<>1 Then Fail
	! Rem try a bunch of random positions
	For i= 1 to 100
		Let j=Disksize/2+int(Rnd*disksize)
		Position #1@j
		Syscall #1,SCGeteof$,Null$,Temp$
11315		If Len(temp$)<>1 then Fail
11316		If Temp$[1]<>(J>=DiskSize) then Fail
	Next i
	! Verify Reading near but not past eof leaves flag reset
		Read #1@Disksize-Maxlen(Temp$)-1,Temp$
		Syscall #1,SCGeteof$,Null$,Temp$
11320		If Temp$[1]<>0 Then Fail
	! Verify Reading last byte sets eof
		Read #1@DiskSize-1,Onebyte$
		Syscall #1,SCGeteof$,Null$,Temp$
11325		If Temp$[1]<>1 Then Fail
	! Verify Reading across last byte sets eof
		Temp$[1]=0
		Read #1@DiskSize-Maxlen(Temp1$)/2,Temp1$
		Syscall #1,SCGeteof$,Null$,Temp$
11330		If Temp$[1]<>1 Then Fail
	! Verify Writing near but not past eof leaves flag reset
		Let Len(Temp$)=Maxlen(Temp$)
		Write #1@Disksize-Maxlen(Temp$)-1,Temp$
		Syscall #1,SCGeteof$,Null$,Temp$
11335		If Temp$[1]<>0 Then Fail
	! Verify Writing last byte sets eof
		Write #1@DiskSize-1,A5$
		Syscall #1,SCGeteof$,Null$,Temp$
11340		If Temp$[1]<>1 Then Fail
	! Verify Writing across last byte sets and causes eof
		Temp$[1]=0
		Let len(Temp1$)=Maxlen(Temp1$)
		Position #1@DiskSize-Maxlen(Temp1$)/2
		! Verify that error occurs on write past eof
11342		If Error When Syscall #1,SyscallWriteB$,Temp1$
		Then If Err<>1001 Then Fail fi
		Else Fail
		! Verify that eof was set, too
		Syscall #1,SCGeteof$,Null$,Temp$
11345		If Temp$[1]<>1 Then Fail
		! Verify that desired data was actually written
		Read #1@DiskSize-Maxlen(Temp1$)/2,Temp$
11347		If len(Temp$)<>Maxlen(Temp1$)/2 then Fail
		let len(Temp1$)=len(Temp$) \ ! so we can compare for =
		If Temp$<>Temp1$ then Fail
	! Set up Temp$ to contain proper reply
	Len(Temp$)=1
	Temp$[1]=1
11360	If Error When Call CheckStatusSyscallCommon(SCGetEof$,1,Temp$)
	Then Fail
	Close #1
	Return

11400	Print "SC:GETFILESIZE";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	If Error When Syscall #1,SCGetFileSize$,Null$,Temp$
	Then If Err<>1034 Then Fail fi
	Else Fail
	Close #1
	Return

11500	Print "SC:GETTYPE";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	Let Len(Temp$)=0
	Let Temp$[1]=0
	Syscall #1,SCGetType$,Null$,Temp$
11510	If len(Temp$)<>1 then Fail
11520	If Temp$[1]<>1 then Fail
	If Error When Call CheckStatusSyscallCommon(SCGetType$,1,Temp$)
	Then Fail
	Close #1
	Return

11600	Print "SC:GETPARAMS";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	Len(Temp$)=0
	Syscall #1,SCGetparams$,Null$,Temp$
11610	If Len(Temp$)<>8 Then Fail
	Print "NBPS=";Value(Temp$[1,2]);"NSPT=";Value(Temp$[3,2]);...
&		"NTPC=";Value(Temp$[5,2]);"NCYL=";Value(Temp$[7,2])
	! Verify that reply buffer < 8 gives reply buffer error
	! Verify that reply buffer >= 8 is truncated to 8
	If Error When Call CheckStatusSyscallCommon(SCGetparams$,8,Temp$)
	Then Fail
	Close #1
	Return

11700
11800
11900
	Goto NonExistentTest

12000	Print "SC:GETLASTBADLSN";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	Syscall #1,CCDismount$ \ ! Clear last bad lsn
	Syscall #1,SCGetLastBadLsn$,Null$,Temp$
	If Len(Temp$)<>3 Then Fail
!	For i=1 to 3 do print Hex$(Temp$[i])[4,2];" ";
!	Print
	For i=1 to 3 do Temp$[i]=:FF
	If Error When Call CheckStatusSyscallCommon(SCGetLastBadLsn$,3,Temp$)
	Then Fail
	Close #1
	Return

12100	Print "SC:GETERRORSTATS";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	Syscall #1,CCDismount$ \ ! Clear last error statistic set
	Gosub ScrambleTemp
	Syscall #1,SCGetErrorStats$,Null$,Temp$
!	Call DisplayByteString$("ErrorStats",Temp$)
12110	If Len(Temp$)<>18 Then Fail
12120	For i=1 to 15 do If Temp$[i]<>0 Then Fail fi
	If Error When Call CheckStatusSyscallCommon(SCGetErrorStats$,18,Temp$)
	Then Fail
	Close #1
	Return

12200
12300
12400
12500
12600
12700
12800
12900
	Goto NonexistentTest

RandomPositionTest:
	! Create 90kb of sequentially written numbers
	! Randomly bounce around in this region to verify correct operation
	Position #1@0
	For i=0 to 14999 do Write #1,i
13010	For j=0 to 1000
		! Pick random place on disk
		Let k=int(rnd*15000)
		Read #1@k*6,i
		If k<>i then Print "Position ";k;"<>";i\Gosub Pop 1\Goto Fail
	Next j
	Return

13000	Print "CC:POSITION";OnDiskDevice$
	If Dontexecute then return
	! Check that eof occurs at or past end of disk
	! Check that eof does not occur prior to end of disk
	! Check that random file position can be read back exactly done by SC:GETPOS test
	Gosub OpenScratchDisk
	! Check that positioning re-zeros the column count
	Syscall #1,CCUnlockDisk$
	Print #1@0,"Hello"; \! Set column count to 5
13003	If Col(1)<>6 then Fail
	Position #1@5
!	print "Col(1)=";col(1)
13006	If Col(1)<>1 then Fail
	Gosub RandomPositionTest
	Gosub ComputeDiskSize
	! Verify that position to last byte on disk doesn't cause EOF
	Position #1@DiskSize-1
13012	If Eof(1) Then Fail
	! Verify that position to size of disk does cause EOF
	Position #1@DiskSize
13015	If Not Eof(1) Then Fail
	! Verify that position to places before EOF don't cause EOF error
	For j=0 to 1000
		Position #1@Int(DiskSize*rnd)
13020		If Eof(1) Then Fail
	Next j
	! Verify that position to places past EOF do cause EOF error
	For j=0 to 1000
		Position #1@Disksize+Int(DiskSize*Rnd)
13030		If Not eof(1) Then Fail
		Position #1@0
	Next j
	! Set up WRBUF for position control call
	For i=1 to 4 do Temp$[i]=0
	Let Len(Temp$)=4
13040	If Error When Call CheckControlSyscallWrbuf(CCPosition$,Temp$)
	Then Fail
	Close #1
	Return

13100	Print "CC:DUMPBUFFERS";OnDiskDevice$
	If Dontexecute then return
	Open #1,Disk$
	! Check ok to dumpbuffers while file is open
	Open #2,"Boot.sys"
	Read #2,OneByte$
	Write #2@0,OneByte$
	Close #2
13105	Syscall #1,CCDumpBuffers$
	! Verify that Dumpbuffers has caused all sectors to go to disk
	If Autopilot
	Then Print "This test requires manual intervention"
	Else
		! Verify that Dumpbuffers has caused all sectors to go to disk
		Input "Please remove DISK: and press <RETURN>" Temp$
		! Will cause write error if buffers not dumped properly
		Syscall #1,CCDismount$
		Input "Please re-insert DISK: and press <RETURN>" Temp$
	Fi
	! Check that dumpbuffers does not care if a file is open
	Create #2,TempFileName$
	Close #2
	Open #2,"Test.tmp"
	Write #2,A5$
13110	Syscall #1,CCDumpbuffers$
	Close #2
13190	If Error When Call CheckControlSyscallNoWRBUF(CCDumpBuffers$,4)
	Then Fail
	Close #1
	Return

13200
13300
13400
13500
	Goto NonexistentTest

13600	Print "CC:UNLOCKDISK";OnDiskDevice$
	If Dontexecute then return
	Gosub OpenScratchDisk
	Close #1
	Open #1,ScratchDisk$
	! Verify that disk device is Software Write locked when opened
13610	If Error When Write #1,A5$
	Then If Err<>1049 Then Fail fi
	Else Fail
	Syscall #1,CCUnlockDisk$
	Write #1,A5$
	Syscall #1,CCDismount$
	! Verify that full syscall block gets empty reply
	! Verify that RDBUF not necesary
	! Verify that WRBUf not necess
	! Verify that RDBUF, if given, is zerod
	Let Temp$=CCUnlockDisk$
	Let Len(Temp$)=127
13620	Syscall #1,CCUnlockDisk$,Null$,Temp1$
	If Len(Temp1$)<>0 Then Fail
13630	If Error When CheckControlSyscallNoWRBUF(CCUnlockDisk$,4)
	Then Fail
	Close #1
	Return

13700	Print "CC:DISMOUNTDISK";OnDiskDevice$
	If Dontexecute then return
	Rem check Errormsgs.sys is deleted properly if deleted
	Rem checks for open files and complains
	Rem does a DUMPBUFFERs
	Rem lets go of map, changes mapalgorithm to "1"
	Rem marks last bad lsn as no such
	rem zeros errorstats
	Open #2,Disk$
	! Verify Dismount yells if a file is open
	Gosub OpenScratchFile
13710	If Error When Syscall #2,CCDismount$
	Then if Err<>1002 then Fail fi
	Else Fail
	Close #1,#2
	Open #1,Disk$
	! Verify that ErrorMsgs.sys is deleted properly
	If Autopilot
	Then Print "Part of this test must be run manually!"
	Else
		Input "Test Deletion of Errormsgs.sys? " Temp$
		If Uppercase$(Temp$)="YES"
		Then
			Delete "ErrorMsgs.sys"
			Print "Deleted; run SDOSDISKVALIDATE and verify no lost blocks"
		Fi
	Fi
	! Verify that error stats are zeroed
	Syscall #1,CCDismount$
	Syscall #1,SCGetErrorStats$,Null$,Temp$
13730	For i=1 to 15 do if Temp$[i]<>0 then Fail
	! Verify that Last Bad Lsn is reset to :FFFFFF
	Syscall #1,SCGetLastBadLsn$,Null$,Temp$
13740	For i=1 to 3 do if Temp$[i]<>:ff then Fail
13790	Call CheckControlSyscallNoWRBUF(CCDismount$,4)
	Close #1
	Goto IncompleteTest
	Return

13800	Print "CC:SETMAPALGORITHM";OnDiskDevice$
	If Dontexecute then return
	Rem check marks all buffers invalid
	Rem check marks last bad lsn as no such
	Gosub OpenScratchDisk
	! Set up temp to hold WRBUF "Mapalgorithm 1"
	Temp$[1]=0
	Temp$[2]=1
	len(Temp$)=2
13890	If Error When Call CheckControlSyscallWrbuf(CCSetMapAlgorithm$,Temp$)
	Then Fail
	Goto IncompleteTest
	Close #1
	Return

13900
14000
14100
14200
14300
14400
14500
14600
14700
14800
14900
	Goto NonexistentTest
ManualTestRequired:
	Print "This test needs to be run manually"
	Return

Subroutine DisplayByteString(LiteralString$,StringtoDisplay$)
	! A subroutine to print size and hex contents of argument string
	Print LiteralString$;Len(StringtoDisplay$);"[";
	For i=1 to Len(StringToDisplay$) do print hex$(StringToDisplay$[i])[4,2];
	Print "]"
	Return Subroutine
End

!
!	Disk File Tests
!
OpenScratchFile:
	If Error When Open #1,TempFileName$
	Then if Err=1011 Then Create #1,TempFileName$ Else Error
	Return

15000	Print "SYSCALL:OPEN";OnDiskFile$
	If Dontexecute then return
	Rem check scans off proper # bytes
	Rem check leading blanks not ignored
	Rem check allows "(xxxx)" notation
	Goto IncompleteTest
	Return

15100	Print "SYSCALL:CREATE";OnDiskFile$
	If Dontexecute then return
	Rem check syscall extension specifies initizl file size
	If Autopilot Then Gosub ManualTestRequired
	Else
		Let Temp$=SyscallCreate$
		! Set up pre-allocation of 90kbytes
		Temp$[15]=0\Temp$[16]=1\Temp$[17]=:80\Temp$[19]=0
		Let len(Temp$)=18
		Syscall #1,Temp$,TempFileName$,Temp1$
		! Force updated DISKMAP.SYS sectors back to the disk
		Syscall #1,CCDumpBuffers$
		Print "Enter <CR> to complete this test,"
		Input "or Reset and SDOSDISKVALIDATE; should have lots of unowned clusters!" Temp$
		Close #1
	Fi
	Rem check sets date to current date, not legal if time is zero
	Rem checks clears backup bit
	Goto IncompleteTest
	Return

15200	Print "SYSCALL:CLOSE";OnDiskFile$
	If Dontexecute then return
	Goto IncompleteTest
	Return

15300	Print "SYSCALL:RENAME";OnDiskFile$
	If Dontexecute then return
	Rem Check Rename to self rehashes directory location
	Rem check Rename not legal if time is zero, set date, clears backup bit
	Goto IncompleteTest
	Return

15400	Print "SYSCALL:DELETE";OnDiskFile$
	If Dontexecute then return
	Goto IncompleteTest
	Return

15500	Print "SYSCALL:READA";OnDiskFile$
	If Dontexecute then return
	Rem check ^C^C aborts READA thru nulls quickly
	Rem check col cnt adjust properly by print chars
	Rem check ff, cr, bs, tab
	Goto IncompleteTest
	Return

15600	Print "SYSCALL:READB";OnDiskFile$
	If Dontexecute then return
	Goto IncompleteTest
	Return

15700	Print "SYSCALL:WRITEA";OnDiskFile$
	If Dontexecute then return
	Rem check updates date if <>0 else err, clears backup bit
	Rem check col cnt adjust properly by print chars
	Rem check ff, cr, bs, tab
	Goto IncompleteTest
	Return

15800	Print "SYSCALL:WRITEB";OnDiskFile$
	If Dontexecute then return
	Rem check updates date if <>0 else err, clears backup bit
	rem check zeros col cnt
	Gosub OpenScratchFile
	Gosub TestWriteBinary
	Close #1
	Goto IncompleteTest
	Return

15900	Print "illegal SYSCALL:CONTROL";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	If Error When Syscall #1,CCIllegal$,Null$,Temp$
	Then If Err<>1034 then Fail fi
	Else Fail
	Close #1
	Return

16000	Print "illegal SYSCALL:STATUS";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	If Error When Syscall #1,SCIllegal$,Null$,Temp$
	Then If Err<>1034 then Fail fi
	Else Fail
	Close #1
	Return

16100	PRINT "SC:GETPOS";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	Goto 11105 \ ! test is identical to disk device test

16200	PRINT "SC:GETCOL";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	Goto 11210 \ ! Test is identical to disk device test

16300	PRINT "SC:GETEOF";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	! Set file size to known value
	DiskSize=Int(Pi*10000)
	Write #1@DiskSize-1,A5$
	Syscall #1,CCSetFileSize$
	Close #1
	Gosub OpenScratchFile
	! Verify not EOF when positioning to the very last byte
	Position #1@Disksize-1
	Temp$=Disk$ \ ! Make sure Temp$ gets changed
	Syscall #1,SCGeteof$,Null$,Temp$
16305	If len(Temp$)<>1 then Fail
16306	If Temp$[1]<>0 then Fail
	! Verify EOF when positioning to byte past the last one
	Position #1@Disksize
	Syscall #1,SCGeteof$,Null$,Temp$
16310	If len(Temp$)<>1 Then Fail
16311	If Temp$[1]<>1 Then Fail
	! Rem try a bunch of random positions
	For i= 1 to 100
		Let j=Disksize/2+int(Rnd*disksize)
		Position #1@j
		Syscall #1,SCGeteof$,Null$,Temp$
16315		If Len(temp$)<>1 then Fail
16316		If Temp$[1]<>(J>=DiskSize) then Fail
	Next i
	! Verify Reading near but not past eof leaves flag reset
		Read #1@Disksize-Maxlen(Temp$)-1,Temp$
		Syscall #1,SCGeteof$,Null$,Temp$
16320		If Temp$[1]<>0 Then Fail
	! Verify Reading last byte sets eof
		Read #1@DiskSize-1,Onebyte$
		Syscall #1,SCGeteof$,Null$,Temp$
16325		If Temp$[1]<>1 Then Fail
	! Verify Reading across last byte sets eof
		Temp$[1]=0
		Read #1@DiskSize-Maxlen(Temp1$)/2,Temp1$
		Syscall #1,SCGeteof$,Null$,Temp$
16330		If Temp$[1]<>1 Then Fail
	! Verify Writing near but not past eof leaves flag reset
		Let Len(Temp$)=Maxlen(Temp$)
		Write #1@Disksize-Maxlen(Temp$)-1,Temp$
		Syscall #1,SCGeteof$,Null$,Temp$
16335		If Temp$[1]<>0 Then Fail
	! Verify Writing last byte sets eof
		Write #1@DiskSize-1,A5$
		Syscall #1,SCGeteof$,Null$,Temp$
16340		If Temp$[1]<>1 Then Fail
	! Verify Writing across last byte sets eof without causing error
		Temp$[1]=0
		Let len(Temp1$)=Maxlen(Temp1$)
		Write #1@DiskSize-Maxlen(Temp1$)/2,Temp1$
		Syscall #1,SCGeteof$,Null$,Temp$
16345		If Temp$[1]<>1 Then Fail
	If Error When Call CheckStatusSyscallCommon(SCGetEof$,1,Temp$)
	Then Fail
	Close #1
	Return

16400	PRINT "SC:GETFILESIZE";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	! Chop file size to 0 bytes
	Let len(Temp$)=4
	For i=1 to 4 do Temp$[i]=0\ Temp1$[i]=1
	Syscall #1,CCSetFileSize$,Temp$
	! Check that file size is correct read back
16410	Syscall #1,SCGetFileSize$,Null$,Temp1$
16420	If Len(Temp1$)<>4 Then Fail
16430	If Temp$<>Temp1$ Then Fail
	! Check that filesize is correctly read back when file is extended
	For i=1 to 65534
		Write #1,A5$
16440		Syscall #1,SCGetFileSize$,Null$,Temp1$
		Let Temp$[3]=i**-8
		Let Temp$[4]=i&:FF
16450		If Temp$<>Temp1$ Then Print i;Value(Temp1$)\Goto  Fail
	Next i
	! Rem check that writing prior to eof does not change filesize
	Write #1@i-5,Temp$
16460	Syscall #1,SCGetFileSize$,Null$,Temp1$
16465	If Temp$<>Temp1$ Then Fail
	If Error When Call CheckStatusSyscallCommon(SCGetfilesize$,4,Temp$)
	Then Fail
	Close #1
	Return

16500	PRINT "SC:GETTYPE";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	! Verify that disk file has been opened
	Gosub ScrambleTemp
	Syscall #1,SCGetType$,Null$,Temp$
	If Len(Temp$)<>1 or Temp$[1]<>0 Then Fail
	If Error When Call CheckStatusSyscallCommon(SCGetType$,1,Temp$)
	Then Fail
	Close #1
	Return

16600	PRINT "SC:GETPARAMS";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	Gosub ScrambleTemp
	Syscall #1,SCGetParams$,Null$,Temp$
16610	If len(Temp$)<>3 Then Fail
	Print "NBPS = ";Value(Temp$[1,2]);"NSPC = ";Temp$[3]
	! Check that NBPS returned is a multiple of 128
16620	If Value(Temp$[1,2])&:7f Then Fail
	If Error When Call CheckStatusSyscallCommon(SCGetParams$,3,Temp$)
	Then Fail
	Close #1
	Return

16700
16800
16900
	Goto NonexistentTest

Def BCD(BCDarg)=(BCDARG**-4)*10+(BCDARG&:F)

17000	Print "SC:GETFILEDATE";OnDiskFile$
	If Dontexecute then return
	If Error When Delete "Test.tmp" Then Rem who cares?
	Gosub OpenScratchFile
	Syscall #1,SCGetFileDate$,Null$,Temp$
17010	If len(Temp$)<>6 then Fail
	For i=1 to 6 do print hex$(Temp$(i));
	Print
	Let Ticks=Value(Temp$[1,3])
	Let Hours=Int(Ticks/(60*60*60))
	Let Ticks=Ticks-Hours*60*60*60
	Let Minutes=Int(Ticks/3600)
	Let Ticks=Ticks-Minutes*3600
	Let Seconds=Int(Ticks/60)
	Let Ticks=Ticks-60*Seconds
	Print "Test.tmp Creation Time= ";Hours;Minutes;Seconds;Ticks;...
&		"Date=";BCD(Temp$[4]);"/";BCD(Temp$[5]);"/";BCD(Temp$[6])
	Gosub TestSetGetFileDate
17030	If Error When Call CheckStatusSyscallCommon(ScGetFileDate$,6,Temp$)
	Then Fail
	Close #1
	Return

TestSetGetFileDate: ! Tests Set/Get File date system calls as a pair
	For j=1 to 100
		! Set file date to known garbage
		Gosub ScrambleTemp
		! Set time to midnite since SDOS 1.1 ignores it
		Let Temp$[1]=0
		Let Temp$[2]=0
		Let Temp$[3]=0
		Let Len(Temp$)=6
		Syscall #1,CCSetFileDate$,Temp$
		Close #1 \ ! Making the FCB for the file free
		Gosub OpenScratchFile
17020	 	Syscall #1,SCGetFileDate$,Null$,Temp1$
!	Call DisplayByteString("Temp$",Temp$)
!	Call DisplayByteString("Temp1$",Temp1$)
		If Temp$<>Temp1$ then Fail
	Next j
	Return

17100	Print "SC:GETFILEPROT";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	Gosub ScrambleTemp
	Syscall #1,SCGetFileProt$,Null$,Temp$
17110	If len(Temp$)<>1 Then Fail
	Print "File Protection bits = "; hex$(Temp$[1])
	Gosub TestSetGetFileProt
17130	If Error When Call CheckStatusSyscallCommon(SCGetFileProt$,1,Temp$)
	Then Fail
	Close #1
	Return

TestSetGetFileProt: ! Test Set/Get file protection system calls as a pair
	! Since there is only a limited number of protect bits, test all combinations!!!
	! Also, leave protection zeroed so Test.tmp file is deleteable
	For j=255 to 0 step -1
		Let Len(Temp$)=1
		Let Temp$[1]=j
		Syscall #1,CCSetFileProt$,Temp$
		Close #1 \ ! Forcing FCB containing protection bits to be free
		Gosub OpenScratchFile
17120		Syscall #1,SCGetFileProt$,Null$,Temp1$
!		Print len(temp$),hex$(Temp$[1]),len(temp1$),hex$(Temp1$[1])
		If Temp$<>Temp1$ Then Fail
	Next j
	Return

17200
17300
17400
17500
17600
17700
17800
17900
	Goto NonexistentTest

18000	Print "CC:POSITION";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	! Check that eof occurs at or past end of file
	! Check that eof does not occur prior to end of disk
	! Check that random file position can be read back exactly done by SC:GETPOS test
	! Check that positioning re-zeros the column count
	Print #1@0,"Hello"; \! Set column count to 5
18003	If Col(1)<>6 then Fail
	Position #1@5
!	print "Col(1)=";col(1)
18006	If Col(1)<>1 then Fail
	Gosub RandomPositionTest
	! Compute size of file we just tested
	Position #1@15000*6
	Syscall #1,CCSetFileSize$
	Syscall #1,SCGetFileSize$,Null$,Temp$
	DiskSize=Value(Temp$)
	! Verify that position to last byte of file doesn't cause EOF
	Position #1@DiskSize-1
18012	If Eof(1) Then Fail
	! Verify that position to size of file does cause EOF
	Position #1@DiskSize
18015	If Not Eof(1) Then Fail
	! Verify that position to places before EOF don't cause EOF error
	For j=0 to 1000
		Position #1@Int(DiskSize*rnd)
18020		If Eof(1) Then Fail
	Next j
	! Verify that position to places past EOF do cause EOF error
	For j=0 to 1000
		Position #1@Disksize+Int(DiskSize*Rnd)
18030		If Not eof(1) Then Fail
		Position #1@0
	Next j
	! Set up WRBUF for position control call
	For i=1 to 4 do Temp$[i]=0
	Let Len(Temp$)=4
18040	If Error When Call CheckControlSyscallWrbuf(CCPosition$,Temp$)
	Then Fail
	Close #1
	Return


18100	Print "CC:DUMPBUFFERS";OnDiskFile$
	If Dontexecute then return
	Rem check ok to do DUMPBUFFERS on file
	Rem Check move modified FCBs back to disk
	Gosub OpenScratchFile
	! Write new data into scratch file and do a Dumpbuffers on the file
	Gosub ScrambleTemp
	Write #1,Temp$
18110	Syscall #1,CCDumpBuffers$
	If Autopilot
	Then print "This test requires manual intervention"\ goto 18150
	Input "Please remove Disk: and press <Return>:" Temp1$
18115	Close #1\ ! after DumpBuffers, this should not cause a write!
18120	! Cause write error if Dumpbuffers didn't...
	Open #1,Disk$
18122	Syscall #1,CCDismount$
18124	Close #1
	Input "Please re-insert Disk: and press <Return>:" Temp1$
18130	! Read back the data we wrote into scratch file and verify it was dumped
	Gosub OpenScratchFile
	Read #1,Temp1$
	If Temp$<>Temp1$ Then Fail
18150	! Verify that Dumpbuffers doesn't use WRBUF, etc.
18140	If Error When Call CheckControlSyscallNoWRBUF(CCDumpBuffers$,4)
	Then Fail
	Close #1
	Return

18200
18300
18400
	Goto NonexistentTest

18500	Print "CC:SETFILEDATE";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	Gosub TestSetGetFileDate
	If Error When Call CheckControlSyscallWRBUF(CCSetFileDate$,Temp$)
	Then Fail
	Close #1
	Return

18600	Print "CC:SETFILEPROT";OnDiskFile$
	If Dontexecute then return
	Gosub OpenScratchFile
	Gosub TestSetGetFileProt
	If Error When Call CheckControlSyscallWRBUF(CCSetFileProt$,Temp$)
	Then Fail
	Close #1
	Return

18700	Print "CC:SETFILESIZE";OnDiskFile$
	If Dontexecute then return
	Rem check updates date if <>0 else err, clears backup bit
	Gosub OpenScratchFile
	! Set random file sizes
	For j=1 to 1000
		! Pick random size
		Let Disksize=Int(Rnd*90000)
		! Set file size to chosen size
		Position #1@DiskSize
		Syscall #1,CCSetFileSize$
		! Make sure that closing file causes new size to be recorded
		Close #1
		Gosub OpenScratchFile
		Syscall #1,SCGetFileSize$,Null$,Temp$
		! Verify that file size was changed
18710		If DiskSize<>Value(Temp$) Then Fail
		Position #1@DiskSize
18720		If not Eof(1) Then Fail
		Position #1@DiskSize-1
18730		If Eof(1) then fail
	Next j
18790	If Error When Call CheckControlSyscallNoWRBUF(CCSetFileSize$,4)
	Then Fail
	Close #1
	Return

18800	Print "CC:PositionToEnd";OnDiskFile$
	If DontExecute then Return
	Gosub OpenScratchFile
	! Set Random file sizes
	For j=1 to 1000
		! Pick Random size
		Let DiskSize=Int(Rnd*90000)
		! Set file size to chosen size
		Position #1@DiskSize
		Syscall #1,CCSetFileSize$
		! Position to zero
		Write #1@0,A5$
		! Position to end
		Syscall #1,CCPositionToEnd$
		Syscall #1,ScGetPos$,Null$,Temp$
18810		If DiskSize<>Value(Temp$) Then Fail
	Next j
18890	If Error When Call CheckControlSyscallNoWRBUF(CCPositionToEnd$,4)
	Then Fail fi
	Close #1
	Return

18900
19000
19100
19200
19300
19400
	Goto NonExistentTest

19500	Print "Sparse files"
	If Dontexecute then return
	Rem Perform the following, with MINALLOC=1 and MINALLOC=10
	Rem Create a new file, read parameters to get cluster size in bytes
	Rem Write to 1st byte of 1st cluster, middle byte of 3rd cluster
	Rem Verify file is correct, and that all bytes in between are zero
	Rem This ensures that last part of cluster at eof is correctly zeroed...
	Rem and that 1st part of cluster at new eof is correctly zeroed
	Rem Pass 1: Set MINALLOC=1, build sparse file and check it
	Rem Pass 2: Leave MINALLOC=1, write in sparse area and verify again
	Rem Pass 3: Set MINALLOC=10, build file and verify not sparse
	Print "Pass ";
	For Pass=1 to 3
		Print pass;
		If Pass=1
		Then
			Rem Set MINALLOC=1 (Force actual sparse file)
			Call SetMinAlloc(1)
		Elseif Pass=3
		Then
			! Force 2nd cluster to be zeroed
			Call SetMinAlloc(10)
		Fi
		Gosub 19505 \ ! Build Sparse file and test
	Next Pass
	Print
	Return
!
!	Guts of sparse file test
19505	Create #1,TempFileName$
	Syscall #1,Scgetparams$,Null$,Temp$
	Let Sectorsize=Value(Temp$[1,2])
	Let ClusterSize=Sectorsize*Temp$[3]
!	Print "clustersize=";clustersize
	Rem Compute address of byte in middle of sector in middle of 3rd cluster
19510	Write #1,A5$ \ ! Write byte to 1st byte of file
19520	Write #1@Clustersize*2.5+64,A5$\ ! Write byte in middle of sector in middle of 3rd cluster
19525	If Pass>1
	Then
		! Write byte to middle of 2nd cluster
		Write #1@Clustersize*1.5+64,A5$
	Fi
19530	Read #1@0,OneByte$
19540	If OneByte$<>A5$ Then Fail
	For I=1 to Clustersize*1.5+64-1
19550		Read #1,OneByte$
	!	Print Hex$(i)
		If OneByte$[1]<>0 Then Fail
	Next I
19553	Read #1,OneByte$
	If Pass=1
	Then If Onebyte$[1]<>0 Then Fail Fi
	Else If Onebyte$<>A5$ Then Fail
	For I=I+1 to Clustersize*2.5+64-1
19555		Read #1,OneByte$
!		Print Hex$(I)
		If OneByte$[1]<>0 Then Fail
	Next I
19560	Read #1,OneByte$
	If OneByte$<>A5$ Then Fail
19570	Read #1,OneByte$
	If not Eof(1) Then Fail
	Close #1
	Return

Subroutine SetMinAlloc(SetMinAllocNewValue)
	Open #1,Disk$
	Let Len(Temp$)=16
	Read #1@16,Temp$[1,16]
	Let Temp$[3]=SetMinAllocNewValue**-8
	Let Temp$[4]=SetMinAllocNewValue&:ff
	Let t=0 \ ! compute new checksum for boot sector
	For i=1 to 15 do Let t=(t+Temp$[i])&:FF
	Let Temp$[16]=:FF-t
	Syscall #1,CCUnlockDisk$ \ ! So we can write Minalloc to sector 0
	Write #1@16,Temp$
	Syscall #1,CCDismount$\ ! Force MinAlloc value use by forcing Mount
	Close #1
	Return Subroutine
End

19600
19700
19800
19900
	Goto NonexistentTest

20000	Print "Check for Illegal LSN"
	If Dontexecute then return
	! How do I cause this without busting the disk?
	Gosub OpenScratchFile
	Close #1
	Goto IncompleteTest
	Return

20100	Print "Check File system Mount logic"
	If Dontexecute then return
	Rem check use Boot:DIRLSN instae
	Rem check BOOT:DIRLSN points to DIRECTORY.SYS directory entry
	Gosub OpenScratchFile
	Close #1
	Goto IncompleteTest
	Return
Subroutine CheckStatusSyscallCommon(Syscalltotest$,Replysize,ProperResult$)
	! Do all checks that are common to all status calls
	Dim Response$(255)
	! Channel 1 is open to something
	! Check that all syscall blocks too short for reply complain properly
	! Check that syscall blocks longer than necessary operate correctly
	! Check that reply buffer must be at least Replysize bytes
	! Check each reply to make sure it is ProperResult$
	! Check reply buffer longer than necessary causes proper truncation
	Let Temp1$=Syscalltotest$
	For i=2 to 13
		Let Len(Temp1$)=i
		Let Temp1$[2]=i
50100		If Error When Syscall #1,Temp1$
		Then If Err<>1053 Then Error fi
		Else Error 1
	Next i
	For i=14 to 127
		Let Len(Temp1$)=i
		Let Temp1$[2]=i
50120		Syscall #1,Temp1$,Null$,Response$
		If Response$<>ProperResult$
		Then Error 1
	Next i
	For i=0 to Len(ProperResult$)-1
		Let Len(Response$)=i
50130		If Error When Syscall #1,SyscalltoTest$,Null$,Response$[1,i]
		Then If Err<>1054 Then Error fi
		Else Error 1
	Next i
	For i=Len(ProperResult$) to maxlen(Response$)
		Let Len(Response$)=i
50140		Syscall #1,SyscalltoTest$,Null$,Response$[1,i]
		If Response$[1,len(ProperResult$)]<>ProperResult$
		Then Error 1
	Next i
	Return Subroutine
End

Subroutine CheckControlSyscallNoWRBUF(ControlSyscalltoCheck$,CheckControlMinLength)
	! Channel 1 is open to something
	! Checks that RDBUF is not required, and if given, that RPLEN is zero
	! Checks that WRBUF is not required
	! Checks that syscall blocks shorter than MinLen gives Syscall too short error
	! Syscall must be repeatedly executable without giving error
	! Note: called by If Error when call... then fail
	Let Temp1$=ControlSyscalltoCheck$
	For i=2 to CheckControlMinLength-1
		Let Temp1$[2]=i
50200		If Error When Syscall #1,Temp1$,Null$,Temp$
		Then if Err<>1053 then Error fi
		Else Error 1
	Next i
	! Check that WRBUF is not required
	For i=CheckControlMinLength to 13
		Let Temp1$[2]=i
50210		Syscall #1,Temp1$,Null$,Temp$
	Next i
	! Check that RDBUF is not required, and that it is set to null if supplied
	For i=14 to 127
		Let Temp1$[2]=i
50220		Syscall #1,Temp1$,Null$,Temp$
		If len(Temp$)>0 Then Error 1\! Fail
	Next i
	Return Subroutine
End

Subroutine CheckControlSyscallWRBUF(ControlSyscalltoCheck1$,ControlSyscallWRBUF$)
	Dim ControlResponse$(255)
	! Channel 1 is open to something
	! Checks that RDBUF is not required, and if given, that RPLEN is zero
	! Checks that WRBUF is required, and must be at least LEN(ControlSyscallWRBUF$) long
	! Checks that syscall blocks shorter than req'd for WRBUF give error
	! Note: this routine can only test syscalls that can be repeatedly...
	! executed without giving an error!
	! Check that WRBUF is required
	Let Temp1$=ControlSyscalltoCheck1$
	For i=2 to 7
		Let Temp1$[2]=i
50300		If Error When Syscall #1,Temp1$,ControlSyscallWRBUF$
		Then If Err<>1053 Then Error Fi
		Else Error 1
	Next i
	! Check that syscall block does not need reply buffer
	For i=8 to 13
		Let Temp1$[2]=i
50310		Syscall #1,Temp1$,ControlSyscallWRBUF$
	Next i
	! Check that Reply buffer, if given, is "null" on completion
	For i=14 to 127
		Let Temp1$[2]=i
50320		Syscall #1,Temp1$,ControlSyscallWrbuf$,ControlResponse$
!		Call DisplayByteString("ControlResponse$",ControlResponse$)
		If len(ControlResponse$)>0 Then Error 1\! Fail
	Next i
	! Check that Write buffer must be at least Len(...WRBUF$)
	Let ControlResponse$=ControlSyscallWrbuf$
	For i=0 to Len(ControlSyscallWrbuf$)-1
		Let Len(ControlResponse$)=i
50340		If Error When Syscall #1,ControlSyscalltoCheck1$,ControlResponse$
		Then if Err<>1055 then Error fi
		Else Error 1
	Next i
	! Check that Write buffer longer than needed doesn't hurt anything...
	For i=Len(ControlSyscallWrbuf$) to MaxLen(ControlResponse$)
		Let Len(ControlResponse$)=i
50350		Syscall #1,ControlSyscalltoCheck1$,ControlResponse$
	Next i
	Return Subroutine
End
END
