10 REM Customization! 19 REM Maybe you want to name the computer? 20 COMPNAME$ = ENVIRON$("HOSTNAME") 28 REM Uptime can be shown, but is meaningless if the system has a clock 29 REM battery or the time has been set 30 SHOWUPTIME = 1 200 PRINT "Working..." 210 TMPFILE$ = "TEST.TMP" 219 REM Determine the OS and interpretter 220 CMD$ = "ver":GOSUB 5000:GOSUB 10000 230 REM PRINT "INTERPRETER: ";INTERP$ 240 REM IF LEN(VERSION$) > 0 THEN PRINT "VERSION: ";VERSION$ 250 REM Determine memory 260 CMD$ = "chkdsk":GOSUB 5000:GOSUB 11000 270 REM CPU Detection 280 GOSUB 12000:GOSUB 12300 290 REM Get a machine name 300 GOSUB 14000 500 REM Just produce an MSDOS logo for now 510 DIM LOGO$(25) 520 GOSUB 20000 1000 REM Output time 1001 CLS 1002 GOSUB 30100 1003 GOSUB 3000 1010 R = 2:C=41 1020 IF LEN(COMPNAME$) = 0 THEN GOTO 1100 1030 LOCATE R,C:PRINT COMPNAME$; 1035 R = R + 1 1040 LOCATE R,C:PRINT STRING$(LEN(COMPNAME$),"-"); 1095 R = R + 1 1100 REM Normal output 1180 IF LEN(MACHINE$) = 0 THEN GOTO 1200 1190 LOCATE R,C:PRINT "Host: ";MACHINE$; 1195 R = R + 1 1199 REM Uptime really only makes sense if the time was never set 1200 IF SHOWUPTIME <> 1 THEN GOTO 1220 1201 LOCATE R,C:PRINT "Uptime Today: ";:GOSUB 13000 1205 R = R + 1 1220 LOCATE R,C:PRINT "Shell: ";INTERP$; 1222 IF LEN(VERSION$) > 0 THEN PRINT " ";VERSION$; 1225 R = R + 1 1230 LOCATE R,C:PRINT "CPU: ";CPU$; 1235 R = R + 1 1240 LOCATE R,C:PRINT "Memory: ";MEMFREE$;" / ";MEMTOTAL$; 1998 LOCATE ROWS, 41:PRINT "Press any key..."; 1999 WHILE LEN(INKEY$) = 0:WEND 2000 END 3000 REM Logo output 3010 FOR I = 1 TO ROWS 3020 LOCATE I, 1:PRINT LOGO$(I); 3030 NEXT I 3040 RETURN 5000 REM Run and pipe command 5010 REM TMPFILE$ contains the file for capture 5020 REM CMD$ contains the command to run 5030 SHELL CMD$ + " > " + TMPFILE$ 5040 RETURN 10000 REM 'ver' output parser 10010 REM TMPFILE$ contains the file to open 10011 REM output: INTERP$ is the interpeter 10012 REM VERSION$ is the version 10020 OPEN TMPFILE$ FOR INPUT AS #2 10030 IF EOF(2) THEN GOTO 10060 10040 INPUT#2, VERLINE$ 10050 IF LEN(G$) = 0 THEN GOTO 10030 ELSE GOTO 10060 10060 CLOSE#2 10070 REM VERLINE$ now contains the first non-blank version 10080 REM output. Technically it is just the command 10090 REM interpreter version. 10100 IDX = INSTR(VERLINE$, "ersion") 10110 IF IDX = 0 THEN GOTO 10210 10120 IDX = IDX - 1 10130 INTERP$ = LEFT$(VERLINE$, IDX - 2) 10140 IDX = IDX + 7 10150 VERSION$ = RIGHT$(VERLINE$, LEN(VERLINE$) - IDX) 10160 FOR IDX = 1 TO LEN(VERSION$) 10170 IF MID$(VERSION$, IDX, 1) = " " THEN VERSION$ = LEFT$(VERSION$,IDX-1) 10180 NEXT IDX 10190 IF INTERP$ = "MS-DOS" OR INTERP$="PC-DOS" THEN INTERP$ = INTERP$ + " Command" 10200 RETURN 10210 REM If we're here, the word "version" wasn't found, but no worries 10220 SPACED = 0:IDX=0:VERSION$ = "" 10230 FOR IDX = 2 TO LEN(VERLINE$) 10240 C$ = MID$(IDX, 1) 10250 GOSUB 30200 10240 IF SPACED > 0 AND ISNUM = 1 THEN VERSION$ = VERSION$ + C$ ELSE GOTO 10270 10250 IF SPACED = 0 AND C$ = " " THEN SPACED = IDX 10260 NEXT IDX 10270 IF LEN(VERSION$) > 0 AND SPACED > 0 THEN INTERP$ = LEFT$(VERLINE$, SPACED - 1) ELSE INTERP$ = VERLINE$ 10280 RETURN 11000 REM 'chkdsk' output parser 11010 REM TMPFILE$ contains the file to open 11011 REM output: MEMTOTAL$ is the total memory in bytes 11012 REM MEMFREE$ is the available memory in bytes 11020 MEMTOTAL$ = "":MEMFREE$ = "" 11030 OPEN TMPFILE$ FOR INPUT AS #2 11040 INPUT#2, MEMLINE$ 11050 IDX = INSTR(MEMLINE$, "bytes total memory") 11060 IF IDX > 0 THEN MEMTOTAL$ = LEFT$(MEMLINE$, IDX-1):GOTO 11090 11070 IDX = INSTR(MEMLINE$, "bytes free") 11080 IF IDX > 0 THEN MEMFREE$ = LEFT$(MEMLINE$, IDX-1) 11085 IF EOF(2) THEN GOTO 11110 11090 IF LEN(MEMTOTAL$) = 0 OR LEN(MEMFREE$) = 0 THEN GOTO 11040 ELSE GOTO 11110 11100 RESUME 11110 11110 CLOSE#2 11120 TOTRIM$ = MEMTOTAL$:GOSUB 30000:MEMTOTAL$ = TOTRIM$ 11130 TOTRIM$ = MEMFREE$:GOSUB 30000:MEMFREE$ = TOTRIM$ 11140 RETURN 12000 REM CPU Identity 12001 DIM Q%(400) 12005 DEF SEG=VARSEG(Q%(0)) 12006 OS%=VARPTR(Q%(0)) 12007 BWOFFSET = -1 : LASTBYTE = 0 12010 FOR I = 1 TO 100 12020 READ JC:POKE I+OS%, JC 12021 REM Detect where we need to insert an offset for bus width detection 12022 IF LASTBYTE=99 AND JC=0 THEN BWOFFSET = I+OS% - 1 12029 LASTBYTE = JC 12030 NEXT I 12039 REM Need to set the offset for bus width 12040 TGTOFFSET = BWOFFSET + 16 12050 POKE BWOFFSET, (TGTOFFSET MOD 256) 12060 POKE BWOFFSET+1, INT(TGTOFFSET / 256) 12080 CPUQ = 1 + OS% 12090 CALL CPUQ(CPUID%) 12097 DEF SEG 12100 REM ; Results: 12101 REM ; 0 - 8088 12102 REM ; 1 - 8086 12103 REM ; 2 - V20 12104 REM ; 3 - V30 12105 REM ; 4 - 80188 12106 REM ; 5 - 80186 12107 REM ; 6 - 80286 12108 REM ; 7 - 80386+ 12109 DATA &H55 : REM push bp 12110 DATA &H89, &HE5 : REM mov bp, sp 12111 REM ; push zero onto the stack and pop it into flags. 12112 REM ; some bits won't change 12113 DATA &H31, &HC0 : REM xor ax,ax 12114 DATA &H50 : REM push ax 12115 DATA &H9D : REM popf 12116 DATA &H9C : REM pushf 12117 DATA &H58 : REM pop ax 12118 DATA &H25, &H00, &HF0 : REM and ax, 0xf000 ;0f000h 12119 DATA &H3D, &H00, &HF0 : REM cmp ax, 0xf000 ;0f000h 12120 DATA &H74, &H13 : REM je lessthantwoeightsix 12121 REM ; marked as 286 (6) 12122 DATA &HB2, &H06 : REM mov dl, 6 12123 DATA &HB8, &H00, &H70 : REM mov ax, 0x7000 ;7000h 12124 DATA &H50 : REM push ax 12125 DATA &H9D : REM popf 12126 DATA &H9C : REM pushf 12127 DATA &H58 : REM pop ax 12128 DATA &H25, &H00, &H70 : REM and ax, 0x7000 ;7000h 12129 DATA &H74, &H3A : REM jz alldone 12130 REM ; mark as 386 (7) 12131 DATA &HFE, &HC2 : REM inc dl 12132 DATA &HE9, &H35, &H00 : REM jmp alldone 12133 REM lessthantwoeightsix: 12134 REM ; Mark as 80188 (4) 12135 DATA &HB2, &H04 : REM mov dl, 4 12136 DATA &HB0, &HFF : REM mov al, 0xff ;0ffh 12137 DATA &HB1, &H21 : REM mov cl, 0x21 ;21h 12138 DATA &HD2, &HE8 : REM shr al, cl 12139 REM ; if the shift leaves zero, it's a 8088 class cpu, else 8018 12140 DATA &H75, &H14 : REM jnz buswidth 12141 REM ; Lets see if we have a V2 12142 DATA &HB2, &H02 : REM mov dl, 2 12143 DATA &HFB : REM sti 12144 DATA &H56 : REM push si 12145 DATA &HBE, &H00, &H00 : REM mov si, 0 12146 DATA &HB9, &HFF, &HFF : REM mov cx, 0xffff ;0ffffh 12147 REM ;rep lods [BYTE PTR es:si] 12148 REM ; INLINE assembler doesn't understand above - must be replaced after... 12149 REM ; because we need a lods with ES as a parameter 12150 REM ; so drop a 3-byte nonsense call to be replaced 12151 DATA &HF3, &H26, &HAC : REM mov cx, 0x0f99 ; replace with 0xF3, 0x26, 0xAC 12152 DATA &H5E : REM pop si 12153 DATA &H09, &HC9 : REM or cx, cx 12154 DATA &H74, &H02 : REM jz buswidth 12155 REM ; mark as a 808 12156 DATA &HB2, &H00 : REM mov dl, 0 12157 REM buswidth: 12158 REM ; we are destroying es now, must be restored later 12159 DATA &H0E : REM push cs 12160 DATA &H07 : REM pop es 12161 DATA &HFD : REM std 12162 REM ; The 99 _must_ be replaced with the true offset of qqend 12163 DATA &HBF, &H63, &H00 : REM mov di, 99 ; OFFSET qqend ;99 12164 REM ;set up al and cx: 0xfb is the 'sti' instruction 12165 DATA &HB0, &HFB : REM mov al, 0xfb 12166 DATA &HB9, &H03, &H00 : REM mov cx, 3 12167 REM ; disable interrupts 12168 DATA &HFA : REM cli 12169 DATA &HF2, &HAA : REM rep stosb 12170 DATA &HFC : REM cld 12171 DATA &H90 : REM nop 12172 DATA &H90 : REM nop 12173 DATA &H90 : REM nop 12174 DATA &H42 : REM inc dx 12175 DATA &H90 : REM nop 12176 REM qqend: 12177 DATA &HFB : REM sti 12178 REM ; ES must be restored 12179 DATA &H1E : REM push ds 12180 DATA &H07 : REM pop es 12181 REM alldone: 12182 REM ; store in ax 12183 DATA &H30, &HF6 : REM xor dh, dh 12184 DATA &H8B, &H7E, &H06 : REM mov di, [bp]+6 12185 DATA &H89, &H15 : REM mov [di], dx 12186 DATA &H5D : REM pop bp 12187 DATA &HCA, &H02, &H00 : REM ); { retf 2} 12188 REM Total Bytes in Data: 100 12200 RETURN 12300 REM Interprets CPUID% and returns a CPU name 12310 DIM CPUNAME$(7) 12320 CPUNAME$(0) = "8088" : CPUNAME$(1) = "8086" 12330 CPUNAME$(2) = "V20" : CPUNAME$(3) = "V30" 12340 CPUNAME$(4) = "80188" : CPUNAME$(5) = "80186" 12350 CPUNAME$(6) = "80286" 12360 CPUNAME$(7) = "80386" 12370 IF CPUID% = 2 OR CPUID% = 3 THEN MFG$ = "NEC" ELSE MFG$ = "Intel" 12380 CPU$ = MFG$+" "+CPUNAME$(CPUID%) 12390 RETURN 13000 REM Create an Uptime string 13010 HOURS = INT(TIMER / 3600) 13020 MINUTES = INT(TIMER / 60) MOD 60 13040 IF HOURS > 0 THEN PRINT HOURS;" hours "; 13050 PRINT MINUTES;" minutes"; 13060 RETURN 14000 REM Guess machine 14010 REM output: MACHINE$ 14015 MACHID = 0 14020 REM Check for Rainbow video memory first 14030 DEF SEG=&HEE00 14040 IF PEEK(0) = &HFF AND PEEK(1) = 3 AND PEEK(3) = &HFF AND PEEK(4) = 18 THEN MACHID=100 14050 DEF SEG 14099 IF MACHID > 0 THEN GOTO 14200 14100 REM Detect using the machine id from the IBM bios 14110 DEF SEG=&HF000 14120 MACHID = PEEK(&HFFFE) 14130 DEF SEG 14200 REM Parse Machine ID 14210 IF MACHID = 100 THEN MACHINE$="Digital Rainbow 100":GOTO 14299 14220 IBMID = MACHID - &HF8 14230 DIM IBMMODELS$(7) 14240 IBMMODELS$(0) = "PS/2 Model 80":IBMMODELS$(1) = "Convertible PC":IBMMODELS$(2) = "PS/2 Model 30" 14241 IBMMODELS$(3) = "PC/XT":IBMMODELS$(4) = "PC/AT or Compatible":IBMMODELS$(5) = "PCjr":: 14242 IBMMODELS$(6) = "PC/XT":IBMMODELS$(7) = "PC" 14250 IF IBMID >= 0 THEN MACHINE$ = "IBM "+IBMMODELS$(IBMID):GOTO 14299 14260 IF MACHID = 154 OR MACHID = 46 THEN MACHINE$ = "Compaq PC":GOTO 14299 14270 IF MACHID = 49 THEN MACHINE$ = "Sperry PC":GOTO 14299 14299 RETURN 20000 REM MS-DOS Logo 20010 LOGO$(1) = " " 20011 LOGO$(2) = " &&&&&& &&&&&& &&&&&&&&" 20012 LOGO$(3) = " &&&&&&. &&&&&&& &&&&&&&&&&&&" 20013 LOGO$(4) = " &&&&&&& &&&&&&&.&&&& &&&&" 20014 LOGO$(5) = " &&&&&&& &&&&&&&&&&&+" 20015 LOGO$(6) = " &&&&&&&; &&&&&&&& &&&&&&&&" 20016 LOGO$(7) = " &&&&&&&& &&& &&&& &&&&&&&&&&" 20017 LOGO$(8) = " &&&& &&&&&&& &&&& &&&&&&& 20018 LOGO$(9) = " &&&& &&&&&&& &&&&&&&& &&&& 20019 LOGO$(10) = " &&&& ;&&&&& &&&& &&&&+ &&&&& 20020 LOGO$(11) = " &&&& &&&&& &&&& &&&&&&&&&&&$" 20021 LOGO$(12) = " &&&&. &&&& &&&& &&&&&&" 20022 LOGO$(13) = " $$$$$$$$$$ $$$$$$$ :::::::." 20023 LOGO$(14) = " $$$$$$$$.$$$$$$$$.::::::::::::" 20024 LOGO$(15) = " $$$$ $$$$$X :::: &$$ .::::" 20025 LOGO$(16) = " $$$$ $$$$$ $$ .::: $$$$& ...." 20026 LOGO$(17) = " $$$$ $$$$;$$$$ ::::&$$$$" 20027 LOGO$(18) = " $$$$ $$$$ $$$$ ::;$$$$ ::." 20028 LOGO$(19) = " $$$$ . $$$$ $$$$ &$$$$ ::::" 20029 LOGO$(20) = " $$$$ $$$&$$$$$:::: $$$$& .::::" 20030 LOGO$(21) = " $$$$.. $$$$$$::::: $$$ ..::::" 20031 LOGO$(22) = " $$$$$$$$$$$$$$$$&::::::::::::::" 20032 LOGO$(23) = " $$$$$$$$$$$$$$$$$$..::::::::.." 20033 LOGO$(24) = " " 20034 LOGO$(25) = " " 20035 RETURN 30000 REM String Trim Function 30010 REM input/output: TOTRIM$ 30015 IF LEN(TOTRIM$) = 0 THEN RETURN 30016 IF INSTR(TOTRIM$, " ") = 0 THEN RETURN 30020 FOR IDX = 1 TO LEN(TOTRIM$):IF MID$(TOTRIM$, IDX, 1) <> " " THEN GOTO 30030:NEXT IDX 30030 FOR RDX = LEN(TOTRIM$) TO IDX STEP -1:IF MID$(TOTRIM$, RDX, 1) <> " " THEN GOTO 30050:NEXT RDX 30040 TOTRIM$ = MID$(TOTRIM$, IDX, RDX - IDX) 30050 RETURN 30100 REM Row check 30110 REM output: ROWS - number of screen rows 30120 ON ERROR GOTO 30150 30130 LOCATE 25,1 30140 ROWS=25:GOTO 30170 30150 RESUME 30160 30160 ROWS=24 30170 ON ERROR GOTO 0 30180 RETURN 30200 REM Character is number or dot 30210 REM input: C$ 30220 REM output: ISNUM 30230 IF C$ = "." THEN ISNUM = 1:RETURN 30240 IF ASC(C$) >= ASC("0") AND ASC(C$) <= ASC("9") THEN ISNUM = 1:RETURN 30250 ISNUM = 0:RETURN