aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2024-11-06 16:47:33 -0500
committerJeffrey Armstrong <jeff@approximatrix.com>2024-11-06 16:47:33 -0500
commitf1d017401b0efef229a45d1b4ffeca95a287594b (patch)
treebebdddcf994342af0c4188a2d8cc864e56e51317
downloadGWFetch-f1d017401b0efef229a45d1b4ffeca95a287594b.tar.gz
GWFetch-f1d017401b0efef229a45d1b4ffeca95a287594b.zip
Initial commit with functioning CPU detection code
-rw-r--r--LICENSE.txt9
-rw-r--r--asm/386q.asm70
-rw-r--r--gwfetch.bas155
-rw-r--r--support/in2data.py52
4 files changed, 286 insertions, 0 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..84a9f29
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,9 @@
+Copyright (c) 2024 Jeffrey Armstrong <jeff@rainbow-100.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/asm/386q.asm b/asm/386q.asm
new file mode 100644
index 0000000..4496d66
--- /dev/null
+++ b/asm/386q.asm
@@ -0,0 +1,70 @@
+ push bp
+ mov bp, sp
+
+ ; push zero onto the stack and pop it into flags.
+ ; some bits won't change
+ xor ax,ax
+ push ax
+ popf
+ pushf
+ pop ax
+
+ and ax, 0xf000 ;0f000h
+ cmp ax, 0xf000 ;0f000h
+ je lessthantwoeightsix
+
+ ; marked as 286 (2)
+ mov dl, 2
+
+ mov ax, 0x7000 ;7000h
+ push ax
+ popf
+
+ pushf
+ pop ax
+ and ax, 0x7000 ;7000h
+ jz alldone
+
+ ; mark as 386 (3)
+ inc dl
+
+ jmp alldone
+
+lessthantwoeightsix:
+
+ mov dl, 1
+
+ mov al, 0xff ;0ffh
+ mov cl, 0x21 ;21h
+ shr al, cl
+
+ ; if the shift leaves zero, it's a 8088 class cpu, else 80186/88
+ jnz alldone
+
+ ; Lets see if we have a V20/V30 (V)
+ mov dl, 0x56 ;056h
+
+ sti
+ push si
+
+ mov si, 0
+ mov cx, 0xffff ;0ffffh
+ ;rep lods [BYTE PTR es:si]
+ rep lodsb
+
+ pop si
+
+ or cx, cx
+ jz alldone
+
+ ; mark as a 8088/8086 (0)
+ mov dl, 0
+
+alldone:
+ ; store in ax
+ xor dh, dh
+
+ mov di, [bp]+6
+ mov [di], dx
+ pop bp
+ retf 2 \ No newline at end of file
diff --git a/gwfetch.bas b/gwfetch.bas
new file mode 100644
index 0000000..b7b509d
--- /dev/null
+++ b/gwfetch.bas
@@ -0,0 +1,155 @@
+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))
+12010 FOR I = 1 TO 76
+12020 READ JC:POKE I+OS%, JC
+12025 print i, peek(i+OS%)
+12030 NEXT I
+12040 CPUQ = 1 + OS%
+12041 print "Calling!"
+12045 CALL CPUQ(CPUID%)
+12047 DEF SEG
+
+12048 REM CPUID% = PEEK(3)
+
+12050 DATA &H55 : REM push bp
+12051 DATA &H89, &HE5 : REM mov bp, sp
+12052 REM ; push zero onto the stack and pop it into flags.
+12053 REM ; some bits won't change
+12054 DATA &H31, &HC0 : REM xor ax,ax
+12055 DATA &H50 : REM push ax
+12056 DATA &H9D : REM popf
+12057 DATA &H9C : REM pushf
+12058 DATA &H58 : REM pop ax
+12059 DATA &H25, &H00, &HF0 : REM and ax, 0xf000 ;0f000h
+12060 DATA &H3D, &H00, &HF0 : REM cmp ax, 0xf000 ;0f000h
+12061 DATA &H74, &H13 : REM je lessthantwoeightsix
+12062 REM ; marked as 286 (2)
+12063 DATA &HB2, &H02 : REM mov dl, 2
+12064 DATA &HB8, &H00, &H70 : REM mov ax, 0x7000 ;7000h
+12065 DATA &H50 : REM push ax
+12066 DATA &H9D : REM popf
+12067 DATA &H9C : REM pushf
+12068 DATA &H58 : REM pop ax
+12069 DATA &H25, &H00, &H70 : REM and ax, 0x7000 ;7000h
+12070 DATA &H74, &H22 : REM jz alldone
+12071 REM ; mark as 386 (3)
+12072 DATA &HFE, &HC2 : REM inc dl
+12073 DATA &HE9, &H1D, &H00 : REM jmp alldone
+12074 REM lessthantwoeightsix:
+12075 DATA &HB2, &H01 : REM mov dl, 1
+12076 DATA &HB0, &HFF : REM mov al, 0xff ;0ffh
+12077 DATA &HB1, &H21 : REM mov cl, 0x21 ;21h
+12078 DATA &HD2, &HE8 : REM shr al, cl
+12079 REM ; if the shift leaves zero, it's a 8088 class cpu, else 8018
+12080 DATA &H75, &H13 : REM jnz alldone
+12081 REM ; Lets see if we have a V2
+12082 DATA &HB2, &H56 : REM mov dl, 0x56 ;056h
+12083 DATA &HFB : REM sti
+12084 DATA &H56 : REM push si
+12085 DATA &HBE, &H00, &H00 : REM mov si, 0
+12086 DATA &HB9, &HFF, &HFF : REM mov cx, 0xffff ;0ffffh
+12087 REM ;rep lods [BYTE PTR es:si]
+12088 DATA &HF2, &HAC : REM rep lodsb
+12089 DATA &H5E : REM pop si
+12090 DATA &H09, &HC9 : REM or cx, cx
+12091 DATA &H74, &H02 : REM jz alldone
+12092 REM ; mark as a 808
+12093 DATA &HB2, &H00 : REM mov dl, 0
+12094 REM alldone:
+12095 REM ; store in ax
+12096 DATA &H30, &HF6 : REM xor dh, dh
+12097 DATA &H8B, &H7E, &H06 : REM mov di, [bp]+6
+12098 DATA &H89, &H15 : REM mov [di], dx
+12099 DATA &H5D : REM pop bp
+12100 DATA &HCA, &H02, &H00 : REM ); { retf 2}
+12101 REM Total Bytes in Data: 76
+
+
+
+
+12200 RETURN
+
+
+13000 REM CPU Identity via dim
+13010 dim A%(37)
+13030 FOR I = 0 TO 14-1
+13040 READ JC:PRINT JC:POKE (VARPTR(A%(1))+I), JC
+13045 PRINT I
+13050 NEXT I
+13060 CPUQ = VARPTR(A%(1))
+
+13080 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
+
diff --git a/support/in2data.py b/support/in2data.py
new file mode 100644
index 0000000..5f497a9
--- /dev/null
+++ b/support/in2data.py
@@ -0,0 +1,52 @@
+import sys
+
+def pascal_to_basic(line):
+ if len(line.strip()) == 0:
+ return "", 0
+
+ ret = ""
+ bytes = 0
+ commands = line.strip().split("/")
+
+ for c in commands:
+ c = c.strip()
+ if c.startswith("$"):
+ if c == commands[0]:
+ ret = "DATA "
+ else:
+ ret = ret + ", "
+
+ cnum = c[1:]
+ ret = ret + "&H" + cnum
+ bytes = bytes + 1
+
+ elif c.startswith("{"):
+ if c != commands[0]:
+ ret = ret + " : "
+ ret = ret + "REM " + c.strip()[1:-1]
+
+ return ret, bytes
+
+
+def inline_to_basic(input_file, output_file, line_start):
+ total_bytes = 0
+ line_number = line_start
+ for line in input_file:
+ line = line.strip()
+
+ basline, line_bytes = pascal_to_basic(line)
+ if basline is not None and len(basline) > 0:
+ output_file.write("{0} {1}\r\n".format(line_number, basline))
+ total_bytes = total_bytes + line_bytes
+ line_number = line_number + 1
+
+ output_file.write("{0} REM Total Bytes in Data: {1}\r\n".format(line_number, total_bytes))
+
+if __name__ == "__main__":
+ fpin = open(sys.argv[1], "r")
+ fpout = open(sys.argv[2], "w")
+
+ inline_to_basic(fpin, fpout, int(sys.argv[3]))
+
+ fpin.close()
+ fpout.close()