!	MUCONFIG.BAS
!
!  CONFIGURATION PROGRAM V2.0
!  THIS PROGRAM PRINTS THE CURRENT CONFIURATION OF THE SDOS FILE
!  SPECIFIED, THEN ALLOWS FOR RECONFIGURATION. RENAMING PERIPHERALS,
!  AND CHANGING THE DEFAULT DISK ARE THE TWO FUNCTIONS.
!  WRITTEN BY ED WELLS
!  MODIFIED BY GLENN TAYLOR
!  LAST EDIT: 11/16/79
!
!	Further Edited 8/15/84 by E.M. Harper to seek CONFIGTABLE.
	DIM LOOPEN,LOOPENMAX,POINTER,DEVICES$(256),DISKS$(256),DEVICES,DISKS
	DIM NAME$(8),NULL$/:0,:0,:0,:0,:0,:0,:0,:0/,NEWNAME$(8),CLOCK$/'CLOCK:'/
	DIM FILENAME$(24),OLDNAME$(8),RECONFIG$(50),Q$(10),FLAG,POINT,OLDNAMENUM
	DIM DISKNAME(32),DEVICENAME(32),DISKPOINT(32),SDOSCONFIG/:9483/
	DIM SDOSORG/:8E00/

	DIM DISKPNTR,NAMEPNTR,NEWDCB,CONFIG,DEVICEPNTR,NAMELEN/8/
	DIM DISKNUM,DEVICENUM,START,TEMP,DISK/1/,DEVICE/1/,COLON$/':'/

	DIM ADDRESS,ADDRESSIN,ADDRESSOUT,BYTEIN$(1),BYTEOUT$(1)
	DIM RECORDBASE,WRFLAG/0/,SIXTEENBITS$(2),TYPE$(1)
	DIM THISRECORDADDRESS/:FFFF/,THISRECORDSIZE/:0/

	DEF NAMESTART(ARGUMENT) = (ARGUMENT-1)*NAMELEN+1

	ON ERROR GOTO 9000

	LEN(BYTEOUT$)=1
	INPUT '' FILENAME$
	IF FIND(FILENAME$,COLON$)=LEN(FILENAME$)
		THEN FILENAME$=FILENAME$ CAT "SDOS.SYS"
	PRINT
	PRINT 'SDOS Configuration Program, V2.0a'
	OPEN #1,FILENAME$
10	PRINT
	PRINT 'Configuration of ';FILENAME$
	DISKS = 1
	DEVICES = 1

! FOR SDOS 1.1, SDOS PROPER STARTS AT $8E00.  THE CONFIG TABLE
! ADDRESS IS AT $8E03
!
!	$8E03	FDB	CNFGTABLE
!
! CNFGTABLE	FDB	DISKDCBS
!		FDB	TTYDCB
!		FDB	IOCBPOINTERS
!		FCB	NIOCHANNELS
!		FDB	DSKBUFFERPOOL
!		FDB	DSKPOOLSIZE
!		FDB	ATTNCHECK
!		FDB	DEBUGSYSCALL
!		FDB	DRIVERBASE
!		FDB	INTSETUP

20	ADDRESS=SDOSORG + 3
	GOSUB 51000
	CONFIG = ADDRESSIN

	ADDRESS=CONFIG
	GOSUB 51000
	DISKPNTR=ADDRESSIN

100	ADDRESS=DISKPNTR+3
	GOSUB 51000
	NAMEPNTR=ADDRESSIN
	DISKNAME(DISKS)=NAMEPNTR

	FOR LOOPEN = 0 TO NAMELEN-1
	ADDRESS=NAMEPNTR+LOOPEN
	WRFLAG=0
	GOSUB 52000
	DISKS$[NAMESTART(DISKS)+LOOPEN] = BYTEIN$(1)
	NEXT LOOPEN

	DISKPOINT(DISKS) = DISKPNTR
	ADDRESS = DISKPNTR+5
	GOSUB 51000
	NEWDCB=ADDRESSIN
	DISKS = DISKS + 1
	DISKPNTR = NEWDCB
	IF NEWDCB <> 0 THEN 100
	LEN(DISKS$) = NAMESTART(DISKS)-1
	DISKPOINT(DISKS) = 0
	DISKS = DISKS - 1

	ADDRESS=CONFIG+2
	GOSUB 51000
	DEVICEPNTR=ADDRESSIN

200	ADDRESS=DEVICEPNTR+3
	GOSUB 51000
	NAMEPNTR=ADDRESSIN
	DEVICENAME(DEVICES)=NAMEPNTR

	FOR LOOPEN = 0 TO NAMELEN-1
	ADDRESS=NAMEPNTR+LOOPEN
	WRFLAG=0
	GOSUB 52000
	DEVICES$[NAMESTART(DEVICES)+LOOPEN] = BYTEIN$(1)
	NEXT LOOPEN

	ADDRESS=DEVICEPNTR+5
	GOSUB 51000
	NEWDCB=ADDRESSIN
	DEVICES = DEVICES + 1
	DEVICEPNTR = NEWDCB
	IF NEWDCB <> 0 THEN 200
	LEN(DEVICES$) = NAMESTART(DEVICES)-1
	DEVICES = DEVICES - 1



300	PRINT 'Active Disks: ';TAB(40);'Active Devices:'
	PRINT

	IF DISKS < DEVICES THEN LOOPENMAX=DEVICES ELSE LOOPENMAX=DISKS
	FOR LOOPEN=1 TO LOOPENMAX
	IF LOOPEN > DISKS THEN 310
	GOSUB 1000
	PRINT TAB(5);NAME$;
	IF LOOPEN = 1 THEN PRINT TAB(15);"(Default Disk)";
310	IF LOOPEN > DEVICES THEN 320
	GOSUB 2000
	PRINT TAB(45);NAME$;
320	PRINT
	NEXT LOOPEN
	PRINT
	PRINT
	INPUT 'Reconfiguration desired? ' Q$
	IF Q$='' OR Q$[1,1]<>'Y' THEN 9900
	PRINT
	PRINT 'Enter OLDNAME:=NEWNAME:'
	PRINT 'Enter DISK:=DEFDISK: to change default disk'
	PRINT 'Press <ESC> to exit'
	PRINT 'Press <CR> to review the configuration'
400	INPUT RECONFIG$
	IF RECONFIG$='' THEN 10
	POINT=FIND(RECONFIG$,'=')
	IF POINT<>0 THEN 420
410	PRINT 'Invalid name or missing "="'
	GOTO 400
420	OLDNAME$=RECONFIG$[1,POINT-1]
	NEWNAME$=NULL$
	NEWNAME$=RECONFIG$[POINT+1,LEN(RECONFIG$)-POINT]
	IF FIND(OLDNAME$,COLON$)=0 OR FIND(NEWNAME$,COLON$)=0
		THEN 410
	OLDNAME$=OLDNAME$[1,FIND(OLDNAME$,COLON$)]
	NEWNAME$=NEWNAME$[1,FIND(NEWNAME$,COLON$)]

	IF OLDNAME$ = "DISK:" THEN 500
	FLAG=0
	FOR LOOPEN=1 TO DISKS
	GOSUB 1000
	IF OLDNAME$=NAME$ THEN 430
	NEXT LOOPEN
	FLAG=1
	FOR LOOPEN=1 TO DEVICES
	GOSUB 2000
	IF OLDNAME$=NAME$ THEN 430
	NEXT LOOPEN
	PRINT OLDNAME$;" does not exist"
	GOTO 400
430	OLDNAMENUM=LOOPEN
	FOR LOOPEN=1 TO DISKS
	GOSUB 1000
	IF NEWNAME$=NAME$ THEN 432
	NEXT LOOPEN
	FOR LOOPEN=1 TO DEVICES
	GOSUB 2000
	IF NEWNAME$=NAME$ THEN 432
	NEXT LOOPEN
	GOTO 437
432	PRINT NEWNAME$;" exists"
	GOTO 400

437	FOR LOOPEN=1 TO LEN(NEWNAME$)-1
	IF NEWNAME$[LOOPEN,1]>='A' AND NEWNAME$[LOOPEN,1]<='Z' OR...
&		NEWNAME$[LOOPEN,1]>='0' AND NEWNAME$[LOOPEN,1]<='9'
		THEN GOTO 438
		ELSE PRINT 'Name not alphanumeric'\GOTO 400
438		NEXT LOOPEN
440	IF OLDNAME$=CLOCK$ THEN PRINT "Cannot rename CLOCK:"\GOTO 400

	START=NAMESTART(OLDNAMENUM)
	IF FLAG=0 THEN DISKS$[START,NAMELEN]=NEWNAME$
		ELSE DEVICES$[START,NAMELEN]=NEWNAME$
	IF FLAG=0 THEN NAMEPNTR=DISKNAME(OLDNAMENUM)
		ELSE NAMEPNTR=DEVICENAME(OLDNAMENUM)
	WRFLAG=1
	FOR LOOPEN = 0 TO NAMELEN-1
	ADDRESS = NAMEPNTR+LOOPEN
	BYTEOUT$(1)=NEWNAME$(LOOPEN+1)
	GOSUB 52000
	NEXT LOOPEN
	GOTO 400

500	FOR LOOPEN = 1 TO DISKS
	GOSUB 1000
	IF NEWNAME$ = NAME$ THEN 520
	NEXT LOOPEN
	FOR LOOPEN = 1 TO DEVICES
	GOSUB 2000
	IF NEWNAME$ = NAME$ THEN 510
	NEXT LOOPEN
	PRINT NEWNAME$;" does not exist"
	GOTO 400
510	PRINT 'Cannot default to non-disk device'
	GOTO 400

520	START = NAMESTART(LOOPEN)
	DISKS$[START,NAMELEN] = DISKS$[1,NAMELEN]
	DISKS$[1,NAMELEN] = NAME$
	DISKPNTR = LOOPEN
	TEMP = DISKNAME(DISKPNTR)
	DISKNAME(DISKPNTR) = DISKNAME(1)
	DISKNAME(1) = TEMP
	TEMP = DISKPOINT(DISKPNTR)
	DISKPOINT(DISKPNTR) = DISKPOINT(1)
	DISKPOINT(1) = TEMP

	ADDRESS = CONFIG
	ADDRESSOUT = DISKPOINT(1)
	GOSUB 50000

	FOR LOOPEN = 1 TO DISKS
	ADDRESS = DISKPOINT(LOOPEN)+5
	ADDRESSOUT = DISKPOINT(LOOPEN+1)
	GOSUB 50000
	NEXT LOOPEN

	GOTO 400

1000	START = NAMESTART(LOOPEN)
	TEMP = FIND(DISKS$[START,NAMELEN],COLON$)
	NAME$ = DISKS$[START,TEMP]
	RETURN

2000	START = NAMESTART(LOOPEN)
	TEMP = FIND(DEVICES$[START,NAMELEN],COLON$)
	NAME$ = DEVICES$[START,TEMP]
	RETURN

9000	IF ERR > 1 THEN ERROR

9900	PRINT
	PRINT 'Reconfiguration of ';FILENAME$;' complete.'
	PRINT
	ON ERROR GOTO 0
	CHAIN 'DEFAULTPROGRAM'


	REM	SUBROUTINE TO WRITE TWO BYTES

50000	BYTEOUT$(1) = INT(ADDRESSOUT/256)
	WRFLAG = 1
	LEN(BYTEOUT$) = 1
	GOSUB 52000
	ADDRESS = ADDRESS + 1
	BYTEOUT$(1) = ADDRESSOUT-(INT(ADDRESSOUT/256)*256)
	WRFLAG = 1
	LEN(BYTEOUT$) = 1
	GOSUB 52000
	ADDRESS = ADDRESS - 1
	RETURN

	REM	SUBROUTINE TO FETCH TWO BYTES

51000	WRFLAG=0
	GOSUB 52000
	ADDRESSIN = BYTEIN$(1)*256
	ADDRESS = ADDRESS + 1
	GOSUB 52000
	ADDRESSIN = ADDRESSIN + BYTEIN$(1)
	ADDRESS = ADDRESS - 1
	RETURN

	REM	SUBROUTINE TO FETCH AND STORE BYTES

52000	IF THISRECORDADDRESS<=ADDRESS AND...
&		 THISRECORDADDRESS+THISRECORDSIZE>ADDRESS THEN 58000
	RESTORE #1,0
	READ #1,TYPE$
	IF TYPE$(1)<>1 THEN PRINT 'Not SDOS Load Record Format'\STOP
	READ #1,SIXTEENBITS$
	READ #1,SIXTEENBITS$
	RECORDBASE=5
53000	REM PROCESS NEXT RECORD
	RESTORE #1,RECORDBASE
	READ #1,TYPE$
	ON TYPE$(1)+1 GOTO 54000,55000,56000,57000
	PRINT 'Illegal Record Type Encountered'
	STOP
54000	REM SKIP RECORD
	GOSUB 59000
	LET RECORDBASE=RECORDBASE+THISRECORDSIZE+3
	GOTO 53000

55000	PRINT 'Type 1 record encountered in wrong place'
	STOP

56000	REM DATA RECORD
	GOSUB 60000
	GOSUB 59000
	IF THISRECORDADDRESS<= ADDRESS AND...
&		 ADDRESS < THISRECORDADDRESS+THISRECORDSIZE
	THEN 58000
	RECORDBASE=RECORDBASE+THISRECORDSIZE+5
	GOTO 53000

57000 	REM LAST DATA RECORD
	GOSUB 60000
	GOSUB 59000
	IF THISRECORDADDRESS<= ADDRESS AND...
&		 ADDRESS < THISRECORDADDRESS +THISRECORDSIZE
	THEN 58000
	PRINT 'Address not found'
	STOP

58000	REM WE FOUND THE RIGHT RECORD!
	RESTORE #1,RECORDBASE+5+ADDRESS-THISRECORDADDRESS
	IF WRFLAG = 0 THEN READ #1, BYTEIN$
			ELSE WRITE #1,BYTEOUT$
	RESTORE #1,RECORDBASE+5+ADDRESS-THISRECORDADDRESS
	RETURN


59000	REM READ THISRECORDSIZE
	READ #1,SIXTEENBITS$
	LET THISRECORDSIZE=SIXTEENBITS$(1)**8+SIXTEENBITS$(2)
	RETURN

60000	REM READ THISRECORDADDRESS
	GOSUB 59000
	LET THISRECORDADDRESS=THISRECORDSIZE
	RETURN

	END
