10 TMPFILE$ = "TEST.TMP" 19 REM Determine the OS and interpretter 20 REM CMD$ = "ver":GOSUB 5000:GOSUB 10000 30 PRINT "INTERPRETER: ";INTERP$ 40 IF LEN(VERSION$) > 0 THEN PRINT "VERSION: ";VERSION$ 100 REM Determine memory 110 REM CMD$ = "chkdsk":GOSUB 5000:GOSUB 11000 120 PRINT "MEMORY: ";MEMFREE$;"/";MEMTOTAL$ 130 GOSUB 12000 140 PRINT "CPUID: ";CPUID% 1000 END 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 10025 REM ON ERROR GOTO 10040 10030 INPUT#2, VERLINE$ 10035 IF LEN(G$) = 0 THEN GOTO 10030 ELSE GOTO 10050 10040 RESUME 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 INTERP$ = VERLINE$:VERSION$="":RETURN 10120 IDX = IDX - 1 10130 INTERP$ = LEFT$(VERLINE$, IDX - 1) 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 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$ = "" 11025 ON ERROR GOTO 11100 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) 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 print "Calling!" 12095 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 30000 REM String Trim Function 30010 REM input/output: TOTRIM$ 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