Dear,
I have a procedure which use to read data at I/O Address but this Address is lower or equal 0xFFFFF (16 bit addresss):
; _ioread
;
; This procedure reads data from the io port specified. Data can
; be a byte, word or long word as specified by the size parameter.
;
; C Prototype
;
; short ioread(unsigned long addr, unsigned long * data, short size);
;
; addr - io address to write to
; data - location where data will be stored.
; size - size of data to read in bytes. {1, 2, 4}
;
_ioread PROC FAR
push bp
mov bp,sp
push ebx ; save registers
push edx
push di
push es
; get io address and check to make sure it's in range
mov edx,[bp+6] ; address
cmp edx,0000FFFFH
jg ioread_err_range
xor eax,eax ; prepare to recieve data
mov bx,[bp+0EH] ; size
cmp bx,4 ; write long word
jne ioread_check_word
in eax,dx
jmp ioread_err_ok
ioread_check_word: ; write word
cmp bx,2
jne ioread_check_byte
in ax,dx
jmp ioread_err_ok
ioread_check_byte: ; write byte
cmp bx,1
jne ioread_err_range
in al,dx
jmp ioread_err_ok
ioread_err_ok: ; successful procedure
mov edx,[bp+0AH] ; data
mov di,dx
shr edx,16
mov es,dx
mov es:[di],eax ; store result
xor ax,ax
jmp ioread_omega
ioread_err_range: ; range error in procedure
mov ax,0FFFFH
ioread_omega:
pop es ; restore registers
pop di
pop edx
pop ebx
mov sp,bp
pop bp
ret
_ioread ENDP
At the current, I want to read data at I/O Address higher 0xFFFF (or 32 bit address), but i can't modify this procedure to execute this function.
Please help me to modify this procedure to read data with 32 bit I/O Address.
There are no I/O ports greater then FFFFh, maybe you mean memory-mapped I/O (e.g. PCI bus)?
Thanks sinsi, I thinks so, too.
But i have a problem:
+ I have PCI Express Card.
+ this card has Base Address: 0xE100 0000 (memory-mapped I/O address)
+ Using memory read to read data at this address but i can't read exactly data. (Because i has read data in linux and compare with DOS).
+ This is proceduce to read memory-mapped I/O:
; _memread
;
; This procedure reads data from the specified memory location. Data can
; be a byte, word or long word as specified by the size parameter.
;
; C Prototype
;
; short memread(unsigned long addr, unsigned long * data, short size);
;
; addr - memory address to read from in SEG:OFF format
; data - location where data will be stored in SEG:OFF format.
; size - size of data to read in bytes. {1, 2, 4}
;
_memread PROC FAR
push bp
mov bp,sp
push ebx ; save registers
push edx
push di
push es
; get memory address
mov edx,[bp+6] ; address
; convert address to es:di form
mov di,dx
shr edx,16
mov es,dx
mov edx,[bp+0AH] ; data address
mov bx,[bp+0EH] ; size
xor eax,eax ; prepare to recieve data
cmp bx,4 ; write long word
jne memread_check_word
mov eax,es:[di]
jmp memread_err_ok
memread_check_word: ; write word
cmp bx,2
jne memread_check_byte
mov ax,es:[di]
jmp memread_err_ok
memread_check_byte: ; write byte
cmp bx,1
jne memread_err_range
mov al,es:[di]
jmp memread_err_ok
memread_err_ok: ; successful procedure
mov di,dx
shr edx,16
mov es,dx
mov es:[di],eax ; store result
xor ax,ax
jmp memread_omega
memread_err_range: ; range error in procedure
mov ax,0FFFFH
memread_omega:
pop es ; restore registers
pop di
pop edx
pop ebx
mov sp,bp
pop bp
ret
_memread ENDP
Please give me some of advises
> Please give me some of advises
You cannot access extended memory so easy in real-mode. The most common way to read extended memory is INT 15h, ah=87h:
-----------------------------------------------------------------------------------------------------
INT 15 - SYSTEM - COPY EXTENDED MEMORY
AH = 87h
CX = number of words to copy (max 8000h)
ES:SI -> global descriptor table (see #00499)
Return: CF set on error
CF clear if successful
AH = status (see #00498)
Notes: copy is done in protected mode with interrupts disabled by the default
BIOS handler; many 386 memory managers perform the copy with
interrupts enabled
on the PS/2 30-286 & "Tortuga" this function does not use the port 92h
for A20 control, but instead uses the keyboard controller (8042).
Reportedly this may cause the system to crash when access to the
8042 is disabled in password server mode (see also PORT 0064h,#P0398)
this function is incompatible with the OS/2 compatibility box
SeeAlso: AH=88h,AH=89h,INT 1F/AH=90h
(Table 00498)
Values for extended-memory copy status:
00h source copied into destination
01h parity error
02h interrupt error
03h address line 20 gating failed
80h invalid command (PC,PCjr)
86h unsupported function (XT,PS30)
Format of global descriptor table:
Offset Size Description (Table 00499)
00h 16 BYTEs zeros (used by BIOS)
10h WORD source segment length in bytes (2*CX-1 or greater)
12h 3 BYTEs 24-bit linear source address, low byte first
15h BYTE source segment access rights (93h)
16h WORD (286) zero
(386+) extended access rights and high byte of source address
18h WORD destination segment length in bytes (2*CX-1 or greater)
1Ah 3 BYTEs 24-bit linear destination address, low byte first
1Dh BYTE destination segment access rights (93h)
1Eh WORD (286) zero
(386+) extended access rights and high byte of destin. address
20h 16 BYTEs zeros (used by BIOS to build CS and SS descriptors)
-----------------------------------------------------------------------------------------------------
As an alternative, one may use "unreal" mode, but this is less flexible because it won't work in v86-mode.
Or use a DOS-Extender, use DPMI or the features of the extender to access whatever memory you want. It is certainly possible to build and test 32-bit drivers, normally hosted by Windows or Linux, under DOS. Booted too DOS mind you, it won't work in the virtual DOS boxes.
Hey japheth, can this function be used to access the APIC from real mode?
Hmm, might give it a try.
This was all recently covered in this thread: http://www.masm32.com/board/index.php?topic=13564.0
Also, like clive said, these suggestions are for REAL real mode, not NTVDM. Doing it inside a DOS box is much tricker (but in some ways, actually easier).
-r
Thanks for all.
hey clive, I use Win98 (support DOS).
I'm newcommer in Assembly Language, please hepl me modify this procedure.
I have tried to read at many high address, so it always return 0xFFFFFFFF (4 bytes).
Quote from: sinsi on October 25, 2010, 02:34:54 PM
Hey japheth, can this function be used to access the APIC from real mode?
Hmm, might give it a try.
I've once implemented memory access via int 15h, ah=87h in good old FD Debug's DX command.