From ff1d2f48a76842c4f7e1754375df2f81c63b2152 Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Wed, 20 Nov 2024 20:37:21 -0500 Subject: Modified how assembly array is addressed to avoid memory corruption. Address could change at any moment, especially when vars are created, so care is taken to never generate a variable when we need to call or modify instructions. --- asm/386q.asm | 7 +- asm/dosver.asm | 4 +- gwfetch.bas | 313 +++++++++++++++++++++++++++++---------------------------- 3 files changed, 167 insertions(+), 157 deletions(-) diff --git a/asm/386q.asm b/asm/386q.asm index 250825a..e95dabe 100644 --- a/asm/386q.asm +++ b/asm/386q.asm @@ -10,7 +10,8 @@ push bp - mov bp, sp + mov bp, sp ; needs to be &H8B, &HEC + pushf ; push zero onto the stack and pop it into flags. ; some bits won't change @@ -66,7 +67,7 @@ lessthantwoeightsix: ; INLINE assembler doesn't understand above - must be replaced after... ; because we need a lods with ES as a parameter ; so drop a 3-byte nonsense call to be replaced - mov cx, 0x0f99 ; replace with 0xF3, 0x26, 0xAC + mov cx, 0x0f99 ; replace with 0xF3, 0x26, 0xAC or &HF3, &H26, &HAC pop si @@ -113,5 +114,7 @@ alldone: mov di, [bp]+6 mov [di], dx + + popf pop bp retf 2 \ No newline at end of file diff --git a/asm/dosver.asm b/asm/dosver.asm index 8406663..9bbb0e0 100644 --- a/asm/dosver.asm +++ b/asm/dosver.asm @@ -1,5 +1,6 @@ push bp - mov bp, sp + mov bp, sp ; needs to be &H8B, &HEC + pushf mov al, 0 mov ah, 0x30 @@ -71,6 +72,7 @@ alldone: mov di, [bp]+8 mov [di], ax + popf pop bp retf 4 \ No newline at end of file diff --git a/gwfetch.bas b/gwfetch.bas index ac3caab..4d3e461 100644 --- a/gwfetch.bas +++ b/gwfetch.bas @@ -6,14 +6,17 @@ 29 REM battery or the time has been set 30 SHOWUPTIME = 1 +199 PRINT "GWFetch 0.1 (c) 2024 J.Armstrong - See LICENSE.txt" 200 PRINT "Working..." 210 TMPFILE$ = "TEST.TMP" +211 REM The array for our asm routines +212 DIM Q%(400) 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 +260 REMCMD$ = "chkdsk":GOSUB 5000:GOSUB 11000 270 REM CPU Detection 280 GOSUB 12000:GOSUB 12300 @@ -60,7 +63,7 @@ 1997 LOCATE ROWS, 41:PRINT "Press any key..."; 1998 WHILE LEN(INKEY$) = 0:WEND -1999 SYSTEM +1999 REM SYSTEM 2000 END 3000 REM Logo output @@ -130,26 +133,24 @@ 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 +12001 CPUQ = 0:CPUID% = 0 +12005 REM DEF SEG=VARSEG(Q%(1)) +12007 BWOFFSET = -1 : LASTBYTE = 0 : JC = 0 +12010 FOR I = 1 TO 102 +12020 READ JC:POKE I+VARPTR(Q%(1)), JC +12022 REM Detect where we need to insert an offset for bus width detection +12025 IF LASTBYTE=99 AND JC=0 THEN BWOFFSET = I - 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) +12040 TGTOFFSET = 0 +12045 TGTOFFSET = BWOFFSET + VARPTR(Q%(1)) + 16 +12050 POKE BWOFFSET + VARPTR(Q%(1)), (TGTOFFSET MOD 256) +12060 POKE BWOFFSET + VARPTR(Q%(1)) + 1, INT(TGTOFFSET / 256) -12080 CPUQ = 1 + OS% +12080 CPUQ = VARPTR(Q%(1)) + 1 12090 CALL CPUQ(CPUID%) -12097 DEF SEG - 12100 REM ; Results: 12101 REM ; 0 - 8088 12102 REM ; 1 - 8086 @@ -160,85 +161,88 @@ 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 +12110 DATA &H8B, &HEC : REM mov bp, sp ; needs to be &H8B, &HEC +12111 DATA &H9C : REM pushf +12112 REM ; push zero onto the stack and pop it into flags. +12113 REM ; some bits won't change +12114 DATA &H31, &HC0 : REM xor ax,ax +12115 DATA &H50 : REM push ax +12116 DATA &H9D : REM popf +12117 DATA &H9C : REM pushf +12118 DATA &H58 : REM pop ax +12119 DATA &H25, &H00, &HF0 : REM and ax, 0xf000 ;0f000h +12120 DATA &H3D, &H00, &HF0 : REM cmp ax, 0xf000 ;0f000h +12121 DATA &H74, &H13 : REM je lessthantwoeightsix +12122 REM ; marked as 286 (6) +12123 DATA &HB2, &H06 : REM mov dl, 6 +12124 DATA &HB8, &H00, &H70 : REM mov ax, 0x7000 ;7000h +12125 DATA &H50 : REM push ax +12126 DATA &H9D : REM popf +12127 DATA &H9C : REM pushf +12128 DATA &H58 : REM pop ax +12129 DATA &H25, &H00, &H70 : REM and ax, 0x7000 ;7000h +12130 DATA &H74, &H3A : REM jz alldone +12131 REM ; mark as 386 (7) +12132 DATA &HFE, &HC2 : REM inc dl +12133 DATA &HE9, &H35, &H00 : REM jmp alldone +12134 REM lessthantwoeightsix: +12135 REM ; Mark as 80188 (4) +12136 DATA &HB2, &H04 : REM mov dl, 4 +12137 DATA &HB0, &HFF : REM mov al, 0xff ;0ffh +12138 DATA &HB1, &H21 : REM mov cl, 0x21 ;21h +12139 DATA &HD2, &HE8 : REM shr al, cl +12140 REM ; if the shift leaves zero, it's a 8088 class cpu, else 8018 +12141 DATA &H75, &H14 : REM jnz buswidth +12142 REM ; Lets see if we have a V2 +12143 DATA &HB2, &H02 : REM mov dl, 2 +12144 DATA &HFB : REM sti +12145 DATA &H56 : REM push si +12146 DATA &HBE, &H00, &H00 : REM mov si, 0 +12147 DATA &HB9, &HFF, &HFF : REM mov cx, 0xffff ;0ffffh +12148 REM ;rep lods [BYTE PTR es:si] +12149 REM ; INLINE assembler doesn't understand above - must be replaced after... +12150 REM ; because we need a lods with ES as a parameter +12151 REM ; so drop a 3-byte nonsense call to be replaced +12152 DATA &HF3, &H26, &HAC : REM mov cx, 0x0f99 ; replace with &HF3, &H26, &HAC +12153 DATA &H5E : REM pop si +12154 DATA &H09, &HC9 : REM or cx, cx +12155 DATA &H74, &H02 : REM jz buswidth +12156 REM ; mark as a 808 +12157 DATA &HB2, &H00 : REM mov dl, 0 +12158 REM buswidth: +12159 REM ; we are destroying es now, must be restored later +12160 DATA &H0E : REM push cs +12161 DATA &H07 : REM pop es +12162 DATA &HFD : REM std +12163 REM ; The 99 _must_ be replaced with the true offset of qqend +12164 DATA &HBF, &H63, &H00 : REM mov di, 99 ; OFFSET qqend ;99 +12165 REM ;set up al and cx: 0xfb is the 'sti' instruction +12166 DATA &HB0, &HFB : REM mov al, 0xfb +12167 DATA &HB9, &H03, &H00 : REM mov cx, 3 +12168 REM ; disable interrupts +12169 DATA &HFA : REM cli +12170 DATA &HF2, &HAA : REM rep stosb +12171 DATA &HFC : REM cld 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 +12174 DATA &H90 : REM nop +12175 DATA &H42 : REM inc dx +12176 DATA &H90 : REM nop +12177 REM qqend: +12178 DATA &HFB : REM sti +12179 REM ; ES must be restored +12180 DATA &H1E : REM push ds +12181 DATA &H07 : REM pop es +12182 REM alldone: +12183 REM ; store in ax +12184 DATA &H30, &HF6 : REM xor dh, dh +12185 DATA &H8B, &H7E, &H06 : REM mov di, [bp]+6 +12186 DATA &H89, &H15 : REM mov [di], dx +12187 DATA &H9D : REM popf +12188 DATA &H5D : REM pop bp +12189 DATA &HCA, &H02, &H00 +12190 REM Total Bytes in Data: 102 + 12200 RETURN 12300 REM Interprets CPUID% and returns a CPU name @@ -253,72 +257,73 @@ 12390 RETURN 12500 REM DOS Version -12501 DIM Q2%(200) -12505 DEF SEG=VARSEG(Q2%(0)) -12506 OS%=VARPTR(Q2%(0)) -12510 FOR I = 1 TO 75 -12520 READ JC:POKE I+OS%, JC +12502 DVER%=0:OEM%=&HFF:DOSVER=0 +12510 FOR I = 1 TO 77 +12520 READ JC:POKE I+VARPTR(Q%(1)), JC 12530 NEXT I -12540 DOSVER = 1 + OS% +12540 DOSVER = 1 + VARPTR(Q%(1)) 12550 CALL DOSVER(DVER%, OEM%) -12560 DEF SEG +12565 print "okay: ";oem% 12570 TOTRIM$ = STR$(DVER% MOD 256):GOSUB 30000:DVERMAJOR$ = TOTRIM$ 12580 TOTRIM$ = STR$(INT(DVER% / 256)):GOSUB 30000:DVERMINOR$ = TOTRIM$ 12600 DATA &H55 : REM push bp -12601 DATA &H89, &HE5 : REM mov bp, sp -12602 DATA &HB0, &H00 : REM mov al, 0 -12603 DATA &HB4, &H30 : REM mov ah, 0x30 -12604 DATA &HCD, &H21 : REM int 0x21 -12605 REM ; Push actual version info onto stack -12606 DATA &H50 : REM push ax -12607 DATA &H80, &HFF, &H00 : REM cmp bh, 0x00 -12608 DATA &H75, &H0D : REM jne notdrdos -12609 REM ; Check if it is DR_DOS lying about being PC_DOS -12610 DATA &HB8, &H52, &H44 : REM mov ax, 0x4452 -12611 DATA &HCD, &H21 : REM int 0x21 -12612 DATA &H72, &H06 : REM jc notdrdos -12613 REM ; Mark drdos as 0xee -12614 DATA &HB7, &HEE : REM mov bh, 0xee -12615 REM ; clear the stack in a meaningless way -12616 DATA &H59 : REM pop cx -12617 REM ; DrDos version, or something like it, is already in the ax reggy -12618 DATA &HE9, &H1B, &H00 : REM jmp alldone -12619 REM notdrdos: -12620 REM ; pop the actual version into ax now that we're done -12621 REM ; with drdos checks -12622 DATA &H58 : REM pop ax -12623 DATA &H3C, &H05 : REM cmp al, 5 -12624 DATA &H74, &H0D : REM je five -12625 REM ; if al is still zero, it's dos 1 -12626 DATA &H3C, &H00 : REM cmp al, 0 -12627 DATA &H75, &H12 : REM jne alldone -12628 REM ; Mark it as MS-DOS 1.0 -12629 DATA &HB0, &H01 : REM mov al, 1 -12630 DATA &HB4, &H00 : REM mov ah, 0 -12631 DATA &HB7, &HFF : REM mov bh, 0xFF -12632 DATA &HE9, &H09, &H00 : REM jmp alldone -12633 REM five: -12634 REM ; Store the OEM version -12635 DATA &H53 : REM push bx -12636 DATA &HB8, &H06, &H33 : REM mov ax, 0x3306 -12637 DATA &HCD, &H21 : REM int 0x21 -12638 REM ; True version should have been in bx -12639 DATA &H53 : REM push bx -12640 DATA &H58 : REM pop ax -12641 DATA &H5B : REM pop bx -12642 REM alldone: -12643 DATA &HB1, &H08 : REM mov cl, 8 -12644 DATA &HD3, &HEB : REM shr bx, cl -12645 DATA &H30, &HFF : REM xor bh, bh -12646 REM ; second argument - OEM code in high byte -12647 DATA &H8B, &H7E, &H06 : REM mov di, [bp]+6 -12648 DATA &H89, &H1D : REM mov [di], bx -12649 REM ; first argument - major (al) minor(ah) versions -12650 DATA &H8B, &H7E, &H08 : REM mov di, [bp]+8 -12651 DATA &H89, &H05 : REM mov [di], ax -12652 DATA &H5D : REM pop bp -12653 DATA &HCA, &H04, &H00 : REM ); { retf 4} -12654 REM Total Bytes in Data: 75 +12601 DATA &H8B, &HEC : REM mov bp, sp ; needs to be &H8B, &HEC +12602 DATA &H9C : REM pushf +12603 DATA &HB0, &H00 : REM mov al, 0 +12604 DATA &HB4, &H30 : REM mov ah, 0x30 +12605 DATA &HCD, &H21 : REM int 0x21 +12606 REM ; Push actual version info onto stack +12607 DATA &H50 : REM push ax +12608 DATA &H80, &HFF, &H00 : REM cmp bh, 0x00 +12609 DATA &H75, &H0D : REM jne notdrdos +12610 REM ; Check if it is DR_DOS lying about being PC_DOS +12611 DATA &HB8, &H52, &H44 : REM mov ax, 0x4452 +12612 DATA &HCD, &H21 : REM int 0x21 +12613 DATA &H72, &H06 : REM jc notdrdos +12614 REM ; Mark drdos as 0xee +12615 DATA &HB7, &HEE : REM mov bh, 0xee +12616 REM ; clear the stack in a meaningless way +12617 DATA &H59 : REM pop cx +12618 REM ; DrDos version, or something like it, is already in the ax reggy +12619 DATA &HE9, &H1B, &H00 : REM jmp alldone +12620 REM notdrdos: +12621 REM ; pop the actual version into ax now that we're done +12622 REM ; with drdos checks +12623 DATA &H58 : REM pop ax +12624 DATA &H3C, &H05 : REM cmp al, 5 +12625 DATA &H74, &H0D : REM je five +12626 REM ; if al is still zero, it's dos 1 +12627 DATA &H3C, &H00 : REM cmp al, 0 +12628 DATA &H75, &H12 : REM jne alldone +12629 REM ; Mark it as MS-DOS 1.0 +12630 DATA &HB0, &H01 : REM mov al, 1 +12631 DATA &HB4, &H00 : REM mov ah, 0 +12632 DATA &HB7, &HFF : REM mov bh, 0xFF +12633 DATA &HE9, &H09, &H00 : REM jmp alldone +12634 REM five: +12635 REM ; Store the OEM version +12636 DATA &H53 : REM push bx +12637 DATA &HB8, &H06, &H33 : REM mov ax, 0x3306 +12638 DATA &HCD, &H21 : REM int 0x21 +12639 REM ; True version should have been in bx +12640 DATA &H53 : REM push bx +12641 DATA &H58 : REM pop ax +12642 DATA &H5B : REM pop bx +12643 REM alldone: +12644 DATA &HB1, &H08 : REM mov cl, 8 +12645 DATA &HD3, &HEB : REM shr bx, cl +12646 DATA &H30, &HFF : REM xor bh, bh +12647 REM ; second argument - OEM code in high byte +12648 DATA &H8B, &H7E, &H06 : REM mov di, [bp]+6 +12649 DATA &H89, &H1D : REM mov [di], bx +12650 REM ; first argument - major (al) minor(ah) versions +12651 DATA &H8B, &H7E, &H08 : REM mov di, [bp]+8 +12652 DATA &H89, &H05 : REM mov [di], ax +12653 DATA &H9D : REM popf +12654 DATA &H5D : REM pop bp +12655 DATA &HCA, &H04, &H00 +12656 REM Total Bytes in Data: 77 + 12699 RETURN 12700 REM Returns the DOS type from the OEM% value -- cgit v1.2.3