Subversion Repositories Kolibri OS

Rev

Rev 4423 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4423 Rev 5565
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
; 20/11/2013 yogev_ezra: Initial version (Vortex86 SoC type detection)
8
; 20/11/2013 yogev_ezra: Initial version (Vortex86 SoC type detection)
9
; 26/11/2013 yogev_ezra: Added CPU speed modifier and MMX support flag detection
9
; 26/11/2013 yogev_ezra: Added CPU speed modifier and MMX support flag detection
10
; Thanks for help to: dunkaist, eAndrew, hidnplayr, Mario
10
; Thanks for help to: dunkaist, eAndrew, hidnplayr, Mario
11
 
11
 
12
$Revision: 4310 $
12
$Revision: 4310 $
13
 
13
 
14
VORTEX86DEBUG = 0                       ; For testing in emulators and in non-Vortex86 CPU computers, set this to 1
14
VORTEX86DEBUG = 0                       ; For testing in emulators and in non-Vortex86 CPU computers, set this to 1
15
VORTEX86DEBUGVALUE = 0x35504d44         ; FAKE port output = used for testing
15
VORTEX86DEBUGVALUE = 0x35504d44         ; FAKE port output = used for testing
16
NORTH_BRIDGE = 0x80000000               ; Base address of Vortex86 PCI North Bridge
16
NORTH_BRIDGE = 0x80000000               ; Base address of Vortex86 PCI North Bridge
17
SOUTH_BRIDGE = 0x80003800               ; Base address of Vortex86 PCI South Bridge
17
SOUTH_BRIDGE = 0x80003800               ; Base address of Vortex86 PCI South Bridge
18
 
18
 
19
; Detect Vortex86 CPU and generate CPU name in string format (PCI address at 93H~90H in Vortex86 North Bridge contains SoC type)
19
; Detect Vortex86 CPU and generate CPU name in string format (PCI address at 93H~90H in Vortex86 North Bridge contains SoC type)
20
; Available Vortex86 CPU codes taken from Coreboot project. New codes should be added to "Vortex86SoClist" below
20
; Available Vortex86 CPU codes taken from Coreboot project. New codes should be added to "Vortex86SoClist" below
21
; #define DMP_CPUID_SX      0x31504d44  ("DMP1")
21
; #define DMP_CPUID_SX      0x31504d44  ("DMP1")
22
; #define DMP_CPUID_DX      0x32504d44  ("DMP2")
22
; #define DMP_CPUID_DX      0x32504d44  ("DMP2")
23
; #define DMP_CPUID_MX      0x33504d44  ("DMP3")
23
; #define DMP_CPUID_MX      0x33504d44  ("DMP3")
24
; #define DMP_CPUID_DX2     0x34504d44  ("DMP4")
24
; #define DMP_CPUID_DX2     0x34504d44  ("DMP4")
25
; #define DMP_CPUID_MX_PLUS 0x35504d44  ("DMP5")
25
; #define DMP_CPUID_MX_PLUS 0x35504d44  ("DMP5")
26
; #define DMP_CPUID_EX      0x37504d44  ("DMP7")
26
; #define DMP_CPUID_EX      0x37504d44  ("DMP7")
27
 
27
 
28
iglobal
28
iglobal
29
Vortex86CPUcode dd ?                    ; Vortex86 CPU code in HEX format (4 bytes), can be shown as string if converted to ASCII characters
29
Vortex86CPUcode dd ?                    ; Vortex86 CPU code in HEX format (4 bytes), can be shown as string if converted to ASCII characters
30
Vortex86CPUid   db 0                    ; Vortex86 CPU id in integer format (1=Vortex86SX, 2=Vortex86DX, ...)
30
Vortex86CPUid   db 0                    ; Vortex86 CPU id in integer format (1=Vortex86SX, 2=Vortex86DX, ...)
31
Vortex86SoCname db 'Vortex86   ',0      ; This variable will hold the full name of Vortex86 SoC
31
Vortex86SoCname db 'Vortex86   ',0      ; This variable will hold the full name of Vortex86 SoC
32
Vortex86SoClist:                        ; List of Vortex86 CPUs known today. Add new record to this list when new CPU becomes available
32
Vortex86SoClist:                        ; List of Vortex86 CPUs known today. Add new record to this list when new CPU becomes available
33
        db      0x31, 'SX '     ; id=1
33
        db      0x31, 'SX '     ; id=1
34
        db      0x32, 'DX '     ; id=2
34
        db      0x32, 'DX '     ; id=2
35
        db      0x33, 'MX '     ; id=3  MMX is available starting from CPU code 'MX' (id=3)
35
        db      0x33, 'MX '     ; id=3  MMX is available starting from CPU code 'MX' (id=3)
36
        db      0x34, 'DX2'     ; id=4
36
        db      0x34, 'DX2'     ; id=4
37
        db      0x35, 'MX+'     ; id=5
37
        db      0x35, 'MX+'     ; id=5
38
        db      0x37, 'EX '     ; id=7
38
        db      0x37, 'EX '     ; id=7
39
Vortex86SoCnum = ($ - Vortex86SoClist) / 4      ; Calculate the total number of known Vortex86 CPUs
39
Vortex86SoCnum = ($ - Vortex86SoClist) / 4      ; Calculate the total number of known Vortex86 CPUs
40
endg
40
endg
41
 
41
 
42
; When in debug mode, perform SoC detection regardless of the actual CPU vendor (even for vendors other than DMP)
42
; When in debug mode, perform SoC detection regardless of the actual CPU vendor (even for vendors other than DMP)
43
; When in normal (not debug) mode, check the CPU vendor first, and perform SoC detection only if vendor is 'Vortex86 SoC'
43
; When in normal (not debug) mode, check the CPU vendor first, and perform SoC detection only if vendor is 'Vortex86 SoC'
44
if ~ VORTEX86DEBUG        
44
if ~ VORTEX86DEBUG        
45
        cmp     [cpu_vendor], 'Vort'
45
        cmp     [cpu_vendor], 'Vort'
46
        jnz     .Vortex86end            ; If the CPU vendor is not 'Vortex86 SoC', skip the SoC detection
46
        jnz     .Vortex86end            ; If the CPU vendor is not 'Vortex86 SoC', skip the SoC detection
47
end if
47
end if
48
 
48
 
49
        mov     eax, NORTH_BRIDGE+0x90  ; 0x80000090 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD)
49
        mov     eax, NORTH_BRIDGE+0x90  ; 0x80000090 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD)
50
        call    .Vortex86PCIreg         ; Get the CPU code from Vortex86 SoC North Bridge PCI register (Register Offset: 93H~90H)
50
        call    .Vortex86PCIreg         ; Get the CPU code from Vortex86 SoC North Bridge PCI register (Register Offset: 93H~90H)
51
 
51
 
52
if VORTEX86DEBUG                        ; When in debug mode, pretend that we received port output equal to "VORTEX86DEBUGVALUE"
52
if VORTEX86DEBUG                        ; When in debug mode, pretend that we received port output equal to "VORTEX86DEBUGVALUE"
53
        mov     eax, VORTEX86DEBUGVALUE
53
        mov     eax, VORTEX86DEBUGVALUE
54
end if
54
end if
55
        
55
        
56
        DEBUGF  1, "K : Vortex86 SoC type register (93H~90H) returned 0x"
56
        DEBUGF  1, "K : Vortex86 SoC type register (93H~90H) returned 0x"
57
        test    eax, eax                ; Check whether the port output was '\0'
57
        test    eax, eax                ; Check whether the port output was '\0'
58
        jz      .nullPCIoutput          ; In case the result is '\0' (NULL), skip further testing and exit
58
        jz      .nullPCIoutput          ; In case the result is '\0' (NULL), skip further testing and exit
59
        mov     [Vortex86CPUcode], eax                      ; Save HEX CPU code to Vortex86CPUcode (so it can be used later)
59
        mov     [Vortex86CPUcode], eax                      ; Save HEX CPU code to Vortex86CPUcode (so it can be used later)
60
        DEBUGF  1, "%x (%s): ", eax, Vortex86CPUcode        ; Print the CPU code (as HEX and as string) to debug log
60
        DEBUGF  1, "%x (%s): ", eax, Vortex86CPUcode        ; Print the CPU code (as HEX and as string) to debug log
61
 
61
 
62
        mov     ebx, 0x444d5000         ; Apply Vortex86 CPU code mask (all Vortex86 SoC have ID in form of "0xNN504d44")
62
        mov     ebx, 0x444d5000         ; Apply Vortex86 CPU code mask (all Vortex86 SoC have ID in form of "0xNN504d44")
63
        bswap   eax                     ; Assumed it is Vortex86 SoC, the highest byte identifies the exact CPU, so move it to the lowest byte
63
        bswap   eax                     ; Assumed it is Vortex86 SoC, the highest byte identifies the exact CPU, so move it to the lowest byte
64
        mov     bl, al                  ; Copy SoC type to BL since EAX (that includes AL) is used implicitly in "LODSD" command below
64
        mov     bl, al                  ; Copy SoC type to BL since EAX (that includes AL) is used implicitly in "LODSD" command below
65
        cmp     eax, ebx                ; Now see whether the 3 higher bytes were "0x504d44" (which means it's Vortex86)
65
        cmp     eax, ebx                ; Now see whether the 3 higher bytes were "0x504d44" (which means it's Vortex86)
66
        jnz     .notVortex86            ; If it's not Vortex86 - go say so and exit
66
        jnz     .notVortex86            ; If it's not Vortex86 - go say so and exit
67
 
67
 
68
        sub     al, 0x30                ; Current Vortex86 CPU codes are in the range of 31h-37h, so convert them to integer (1,2,...)
68
        sub     al, 0x30                ; Current Vortex86 CPU codes are in the range of 31h-37h, so convert them to integer (1,2,...)
69
        mov     [Vortex86CPUid], al     ; Save the CPUid (1=Vortex86SX, 2=Vortex86DX, ..., 7=Vortex86EX, ...)
69
        mov     [Vortex86CPUid], al     ; Save the CPUid (1=Vortex86SX, 2=Vortex86DX, ..., 7=Vortex86EX, ...)
70
        
70
        
71
        mov     esi, Vortex86SoClist    ; ESI points to the start of Vortex86SoClist (used implicitly in "LODSD" command below)
71
        mov     esi, Vortex86SoClist    ; ESI points to the start of Vortex86SoClist (used implicitly in "LODSD" command below)
72
        xor     ecx, ecx                ; Zero ECX (it is used as counter)
72
        xor     ecx, ecx                ; Zero ECX (it is used as counter)
73
        cld                             ; Clears the DF flag in the EFLAGS register (DF=0 --> String operations increment ESI)
73
        cld                             ; Clears the DF flag in the EFLAGS register (DF=0 --> String operations increment ESI)
74
@@:
74
@@:
75
        inc     ecx                     ; Increment our counter
75
        inc     ecx                     ; Increment our counter
76
        cmp     ecx, Vortex86SoCnum     ; Check if we iterated Vortex86SoCnum times already (i.e. went over the entire Vortex86SoClist)
76
        cmp     ecx, Vortex86SoCnum     ; Check if we iterated Vortex86SoCnum times already (i.e. went over the entire Vortex86SoClist)
77
        ja      .unknownVortex86        ; If the entire list was tested and our CPU is not in that list, it is unknown Vortex86 SoC
77
        ja      .unknownVortex86        ; If the entire list was tested and our CPU is not in that list, it is unknown Vortex86 SoC
78
        lodsd                           ; Load DWORD at address DS:ESI into EAX (puts 1 line from Vortex86SoClist into EAX, then increments ESI)
78
        lodsd                           ; Load DWORD at address DS:ESI into EAX (puts 1 line from Vortex86SoClist into EAX, then increments ESI)
79
        cmp     bl, al                  ; Check if our CPU matches the current record in the list
79
        cmp     bl, al                  ; Check if our CPU matches the current record in the list
80
        jne     @b                      ; No match --> repeat with next record
80
        jne     @b                      ; No match --> repeat with next record
81
 
81
 
82
        shr     eax, 8                              ; Match found --> drop the SoC type code from Vortex86SoClist name and replace it with \0
82
        shr     eax, 8                              ; Match found --> drop the SoC type code from Vortex86SoClist name and replace it with \0
83
        mov     dword [Vortex86SoCname+8], eax      ; Concatenate it with prefix to receive complete SoC name (\0 is string termination)
83
        mov     dword [Vortex86SoCname+8], eax      ; Concatenate it with prefix to receive complete SoC name (\0 is string termination)
84
 
84
 
85
        DEBUGF  1, "%s (id=%d)\n", Vortex86SoCname, [Vortex86CPUid]:1           ; Say what we have found (CPU name and id)
85
        DEBUGF  1, "%s (id=%d)\n", Vortex86SoCname, [Vortex86CPUid]:1           ; Say what we have found (CPU name and id)
86
        jmp     .Vortex86
86
        jmp     .Vortex86
87
 
87
 
88
.notVortex86:                           ; In case this register is used by other CPUs for other purpose, it's interesting what it contains
88
.notVortex86:                           ; In case this register is used by other CPUs for other purpose, it's interesting what it contains
89
        DEBUGF  1, "not a Vortex86 CPU\n"
89
        DEBUGF  1, "not a Vortex86 CPU\n"
90
        jmp     .Vortex86end
90
        jmp     .Vortex86end
91
 
91
 
92
.unknownVortex86:                       ; It is Vortex86 CPU, but it's not in the list above
92
.unknownVortex86:                       ; It is Vortex86 CPU, but it's not in the list above
93
        DEBUGF  1, "unknown Vortex86 CPU (id=%d)\n", [Vortex86CPUid]:1          ; Inform the user that the CPU is Vortex86 but name is unknown
93
        DEBUGF  1, "unknown Vortex86 CPU (id=%d)\n", [Vortex86CPUid]:1          ; Inform the user that the CPU is Vortex86 but name is unknown
94
 
94
 
95
.Vortex86:
95
.Vortex86:
96
        mov     eax, NORTH_BRIDGE+0x60  ; 0x80000060 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD)
96
        mov     eax, NORTH_BRIDGE+0x60  ; 0x80000060 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD)
97
        call    .Vortex86PCIreg         ; Get current flags of Vortex86SoC North Bridge STRAP Register (Register Offset: 63h~60h)
97
        call    .Vortex86PCIreg         ; Get current flags of Vortex86SoC North Bridge STRAP Register (Register Offset: 63h~60h)
98
        DEBUGF  1, "K : Vortex86 STRAP Register (63h~60h) returned 0x%x\n",eax
98
        DEBUGF  1, "K : Vortex86 STRAP Register (63h~60h) returned 0x%x\n",eax
99
 
99
 
100
        mov     eax, SOUTH_BRIDGE+0xC0  ; 0x800038C0 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD)
100
        mov     eax, SOUTH_BRIDGE+0xC0  ; 0x800038C0 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD)
101
        call    .Vortex86PCIreg         ; Flags of Vortex86 South Bridge Internal Peripheral Feature Control Register (Register Offset: C3h~C0h)
101
        call    .Vortex86PCIreg         ; Flags of Vortex86 South Bridge Internal Peripheral Feature Control Register (Register Offset: C3h~C0h)
102
        DEBUGF  1, "K : Vortex86 Internal Peripheral Feature Control Register (C3h~C0h) returned 0x%x\n",eax
102
        DEBUGF  1, "K : Vortex86 Internal Peripheral Feature Control Register (C3h~C0h) returned 0x%x\n",eax
103
 
103
 
104
        mov     eax, SOUTH_BRIDGE+0xCC  ; 0x800038CC = PCI Configuration Address Register to read from (8-bit register - accessed as BYTE)
104
        mov     eax, SOUTH_BRIDGE+0xCC  ; 0x800038CC = PCI Configuration Address Register to read from (8-bit register - accessed as BYTE)
105
        call    .Vortex86PCIreg         ; Flags of Vortex86 South Bridge Internal Peripheral Feature Control Register III (Register Offset: CCh)
105
        call    .Vortex86PCIreg         ; Flags of Vortex86 South Bridge Internal Peripheral Feature Control Register III (Register Offset: CCh)
106
        DEBUGF  1, "K : Vortex86 Internal Peripheral Feature Control Register III (CCh) returned 0x%x\n",al
106
        DEBUGF  1, "K : Vortex86 Internal Peripheral Feature Control Register III (CCh) returned 0x%x\n",al
107
        
107
        
108
        mov     eax, NORTH_BRIDGE+0xA0  ; 0x800000A0 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD)
108
        mov     eax, NORTH_BRIDGE+0xA0  ; 0x800000A0 = PCI Configuration Address Register to read from (32-bit register - accessed as DWORD)
109
        call    .Vortex86PCIreg         ; Get current flags of Vortex86SoC North Bridge Host Control Register (Register Offset: A3h~A0h)
109
        call    .Vortex86PCIreg         ; Get current flags of Vortex86SoC North Bridge Host Control Register (Register Offset: A3h~A0h)
110
        DEBUGF  1, "K : Vortex86 Host Control Register (A3h~A0h) returned 0x%x: CPU speed is ",eax
110
        DEBUGF  1, "K : Vortex86 Host Control Register (A3h~A0h) returned 0x%x: CPU speed is ",eax
111
        mov     bl, al                  ; The lower byte of Vortex86 Host Control Register contains CPU speed modifier and MMX support status
111
        mov     bl, al                  ; The lower byte of Vortex86 Host Control Register contains CPU speed modifier and MMX support status
112
        mov     bh, al                  ; Backup the current AL value, so later we can test whether the value has changed
112
        mov     bh, al                  ; Backup the current AL value, so later we can test whether the value has changed
113
        and     bl, 00000111b           ; CPU speed modifier is stored in bits 0-2. Value=0 means MAX speed, other values - speed reduction
113
        and     bl, 00000111b           ; CPU speed modifier is stored in bits 0-2. Value=0 means MAX speed, other values - speed reduction
114
        jz      .Vortex86CPUspeedMAX    ; 0s in bits 0-2: CPU is at MAX speed (no need to modify)
114
        jz      .Vortex86CPUspeedMAX    ; 0s in bits 0-2: CPU is at MAX speed (no need to modify)
115
        inc     ebx                     ; The actual value is 1 less than 'Divide by' setting (value '001' means 'Divide by 2', etc.)
115
        inc     ebx                     ; The actual value is 1 less than 'Divide by' setting (value '001' means 'Divide by 2', etc.)
116
        DEBUGF  1, "reduced (divide by %d).\nK : Vortex86 changing CPU speed to ", bl    ; Print the current CPU speed modifier to the log
116
        DEBUGF  1, "reduced (divide by %d).\nK : Vortex86 changing CPU speed to ", bl    ; Print the current CPU speed modifier to the log
117
        and     al, 11111000b           ; At least one of the bits 0-2 contains 1: CPU is at reduced speed. Set bits 0-2 to 0s to change to MAX
117
        and     al, 11111000b           ; At least one of the bits 0-2 contains 1: CPU is at reduced speed. Set bits 0-2 to 0s to change to MAX
118
.Vortex86CPUspeedMAX:
118
.Vortex86CPUspeedMAX:
119
        DEBUGF  1, "MAX\n"              ; Now the CPU should be running at MAX speed (don't write the value to PCI port yet)
119
        DEBUGF  1, "MAX\n"              ; Now the CPU should be running at MAX speed (don't write the value to PCI port yet)
120
 
120
 
121
        cmp     [Vortex86CPUid], 3      ; MMX is available starting from CPU code 'MX' (id=3)
121
        cmp     [Vortex86CPUid], 3      ; MMX is available starting from CPU code 'MX' (id=3)
122
        jb      .skipVortex86MMX        ; No MMX support - skip MMX support status detection (for id=1,2)
122
        jb      .skipVortex86MMX        ; No MMX support - skip MMX support status detection (for id=1,2)
123
        DEBUGF  1, "K : Vortex86 MMX support status: MMX is "                   ; Bits 5-6 in Host Control Register contain MMX status
123
        DEBUGF  1, "K : Vortex86 MMX support status: MMX is "                   ; Bits 5-6 in Host Control Register contain MMX status
124
        test    al, 100000b             ; On MMX-capable Vortex86 SoC, Bit5 = is MMX enabled? (1=Yes/0=No)
124
        test    al, 100000b             ; On MMX-capable Vortex86 SoC, Bit5 = is MMX enabled? (1=Yes/0=No)
125
        jnz     .Vortex86MMXenabled     ; MMX is already enabled (Bit5=1)
125
        jnz     .Vortex86MMXenabled     ; MMX is already enabled (Bit5=1)
126
        DEBUGF  1, "DISABLED - enabling it for this session\n"                  ; Print to the log that MMX is disabled
126
        DEBUGF  1, "DISABLED - enabling it for this session\n"                  ; Print to the log that MMX is disabled
127
        or      al, 100000b             ; Enable MMX support (don't write the value to PCI port yet)
127
        or      al, 100000b             ; Enable MMX support (don't write the value to PCI port yet)
128
        jmp     .AfterMMXenabled
128
        jmp     .AfterMMXenabled
129
.Vortex86MMXenabled:
129
.Vortex86MMXenabled:
130
        DEBUGF  1, "ENABLED\n"          ; Print to the log that MMX is enabled
130
        DEBUGF  1, "ENABLED\n"          ; Print to the log that MMX is enabled
131
.AfterMMXenabled:
131
.AfterMMXenabled:
132
        DEBUGF  1, "K : Vortex86 MMX report to CPUID: "                         ; Print to the log what CPUID command knowns about MMX support
132
        DEBUGF  1, "K : Vortex86 MMX report to CPUID: "                         ; Print to the log what CPUID command knowns about MMX support
133
        test    al, 1000000b            ; On MMX-capable Vortex86 SoC, Bit6 = report MMX support to CPUID? (1=Yes/0=No)        
133
        test    al, 1000000b            ; On MMX-capable Vortex86 SoC, Bit6 = report MMX support to CPUID? (1=Yes/0=No)        
134
        jnz     .Vortex86MMXreported    ; MMX is already reported to CPUID (Bit6=1)
134
        jnz     .Vortex86MMXreported    ; MMX is already reported to CPUID (Bit6=1)
135
        DEBUGF  1, "OFF - turning it ON for this session\n"                     ; Print to the log that MMX will now be reported to CPUID
135
        DEBUGF  1, "OFF - turning it ON for this session\n"                     ; Print to the log that MMX will now be reported to CPUID
136
        or      al, 1000000b            ; Turn on MMX reporting to CPUID (don't write the value to PCI port yet)
136
        or      al, 1000000b            ; Turn on MMX reporting to CPUID (don't write the value to PCI port yet)
137
        jmp     .skipVortex86MMX
137
        jmp     .skipVortex86MMX
138
.Vortex86MMXreported:
138
.Vortex86MMXreported:
139
        DEBUGF  1, "ON\n"               ; Print to the log that MMX reporting to CPUID is enabled
139
        DEBUGF  1, "ON\n"               ; Print to the log that MMX reporting to CPUID is enabled
140
 
140
 
141
.skipVortex86MMX:
141
.skipVortex86MMX:
142
        cmp     bh, al                  ; Check whether AL has changed before (if it did, we need to write it back to PCI port)
142
        cmp     bh, al                  ; Check whether AL has changed before (if it did, we need to write it back to PCI port)
143
        jz      .Vortex86end            ; No change - no need to write to the port
143
        jz      .Vortex86end            ; No change - no need to write to the port
144
        out     dx, al                  ; Write the changed data to PCI port
144
        out     dx, al                  ; Write the changed data to PCI port
145
        DEBUGF  1, "K : Vortex86 Host Control Register (A3h~A0h) new value is 0x%x\n",eax
145
        DEBUGF  1, "K : Vortex86 Host Control Register (A3h~A0h) new value is 0x%x\n",eax
146
        jmp     .Vortex86end
146
        jmp     .Vortex86end
147
 
147
 
148
.Vortex86PCIreg:                        ; Procedure receives input register value in EAX, and returns the output value also in EAX
148
.Vortex86PCIreg:                        ; Procedure receives input register value in EAX, and returns the output value also in EAX
149
        mov     dx, 0xcf8               ; CF8h = Vortex86 PCI Configuration Address port
149
        mov     dx, 0xcf8               ; CF8h = Vortex86 PCI Configuration Address port
150
        out     dx, eax                 ; Send request to PCI address port to retrieve data from this address
150
        out     dx, eax                 ; Send request to PCI address port to retrieve data from this address
151
        mov     dl, 0xfc                ; CFCh = Vortex86 PCI Configuration Data port
151
        mov     dl, 0xfc                ; CFCh = Vortex86 PCI Configuration Data port
152
        in      eax, dx                 ; Read data from PCI data port
152
        in      eax, dx                 ; Read data from PCI data port
153
        ret
153
        ret
154
        
154
        
155
.nullPCIoutput:                         ; Emulators and non-Vortex86 CPU computers will usually return \0 in this register
155
.nullPCIoutput:                         ; Emulators and non-Vortex86 CPU computers will usually return \0 in this register
156
        DEBUGF  1, "0 (NULL)\n"
156
        DEBUGF  1, "0 (NULL)\n"
157
 
157
 
158
.Vortex86end:
158
.Vortex86end: