NT4/private/ntos/nthals/halcbus/i386/cbioacc.asm
2020-09-30 17:12:29 +02:00

562 lines
12 KiB
NASM

title "Cbus ioaccess"
;++
;
; Copyright (c) 1992, 1993, 1994 Corollary Inc
;
; Module Name:
;
; cbioacc.asm
;
; Abstract:
;
; Procedures to correctly touch I/O registers.
; This is different from that of the standard PC HAL because
; we support multiple I/O buses as part of Cbus2.
;
; Author:
;
; Landy Wang (landy@corollary.com) 19 Mar 1994
;
; Environment:
;
; User or Kernel, although privilege (IOPL) may be required.
;
; Revision History:
;
;--
.386p
.xlist
include hal386.inc
include callconv.inc ; calling convention macros
.list
_TEXT$00 SEGMENT DWORD PUBLIC 'CODE'
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
;++
;
; I/O port space read and write functions.
;
; These have to be actual functions on the 386, because we need
; to use assembler, but cannot return a value if we inline it.
;
; This set of functions manipulates I/O registers in PORT space.
; (Uses x86 in and out instructions)
;
; WARNING: Port addresses must always be in the range 0 to 64K, because
; that's the range the hardware understands. Any address with
; the high bit on is assumed to be a HAL-memory-mapped equivalent
; of an I/O address, so it can just (and must!) be read/written
; directly.
;
;--
;++
;
; UCHAR
; READ_PORT_UCHAR(
; PUCHAR Port
; )
;
; Arguments:
; (esp+4) = Port
;
; Returns:
; Value in Port.
;
;--
cPublicProc _READ_PORT_UCHAR ,1
cPublicFpo 1, 0
mov edx,[esp+4] ; (dx) = Port
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
in al,dx
stdRET _READ_PORT_UCHAR
align 4
@@:
mov al, [edx]
stdRET _READ_PORT_UCHAR
stdENDP _READ_PORT_UCHAR
;++
;
; USHORT
; READ_PORT_USHORT(
; PUSHORT Port
; )
;
; Arguments:
; (esp+4) = Port
;
; Returns:
; Value in Port.
;
;--
cPublicProc _READ_PORT_USHORT ,1
cPublicFpo 1, 0
mov edx,[esp+4] ; (dx) = Port
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
in ax,dx
stdRET _READ_PORT_USHORT
align 4
@@:
mov ax, [edx]
stdRET _READ_PORT_USHORT
stdENDP _READ_PORT_USHORT
;++
;
; ULONG
; READ_PORT_ULONG(
; PULONG Port
; )
;
; Arguments:
; (esp+4) = Port
;
; Returns:
; Value in Port.
;
;--
cPublicProc _READ_PORT_ULONG ,1
cPublicFpo 1, 0
mov edx,[esp+4] ; (dx) = Port
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
in eax,dx
stdRET _READ_PORT_ULONG
align 4
@@:
mov eax, [edx]
stdRET _READ_PORT_ULONG
stdENDP _READ_PORT_ULONG
;++
;
; VOID
; READ_PORT_BUFFER_UCHAR(
; PUCHAR Port,
; PUCHAR Buffer,
; ULONG Count
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Buffer address
; (esp+12) = Count
;
;--
cPublicProc _READ_PORT_BUFFER_UCHAR ,3
cPublicFpo 3, 0
mov eax, edi ; Save edi
mov edx,[esp+4] ; (dx) = Port
mov edi,[esp+8] ; (edi) = buffer
mov ecx,[esp+12] ; (ecx) = transfer count
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
rep insb
mov edi, eax
stdRET _READ_PORT_BUFFER_UCHAR
align 4
@@:
push eax ; save eax (really the orig edi)
;
; this code to handle I/O to the extra busses should be written better
;
align 4
@@:
mov al, [edx]
mov [edi], al
inc edi
dec ecx
jnz @b
pop edi ; restore caller's edi
stdRET _READ_PORT_BUFFER_UCHAR
stdENDP _READ_PORT_BUFFER_UCHAR
;++
;
; VOID
; READ_PORT_BUFFER_USHORT(
; PUSHORT Port,
; PUSHORT Buffer,
; ULONG Count
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Buffer address
; (esp+12) = Count (in 2-byte word units)
;
;--
cPublicProc _READ_PORT_BUFFER_USHORT ,3
cPublicFpo 3, 0
mov eax, edi ; Save edi
mov edx,[esp+4] ; (dx) = Port
mov edi,[esp+8] ; (edi) = buffer
mov ecx,[esp+12] ; (ecx) = transfer count
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
rep insw
mov edi, eax
stdRET _READ_PORT_BUFFER_USHORT
align 4
@@:
push eax ; save eax (really the orig edi)
;
; this code to handle I/O to the extra busses should be written better
;
align 4
@@:
mov ax, [edx]
mov [edi], ax
add edi, 2
dec ecx
jnz @b
pop edi ; restore caller's edi
stdRET _READ_PORT_BUFFER_USHORT
stdENDP _READ_PORT_BUFFER_USHORT
;++
;
; VOID
; READ_PORT_BUFFER_ULONG(
; PULONG Port,
; PULONG Buffer,
; ULONG Count
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Buffer address
; (esp+12) = Count (in 4-byte dword units)
;
;--
cPublicProc _READ_PORT_BUFFER_ULONG ,3
cPublicFpo 3, 0
mov eax, edi ; Save edi
mov edx,[esp+4] ; (dx) = Port
mov edi,[esp+8] ; (edi) = buffer
mov ecx,[esp+12] ; (ecx) = transfer count
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
rep insd
mov edi, eax
stdRET _READ_PORT_BUFFER_ULONG
align 4
@@:
push eax ; save eax (really the orig edi)
;
; this code to handle I/O to the extra busses should be written better
;
align 4
@@:
mov eax, [edx]
mov [edi], eax
add edi, 4
dec ecx
jnz @b
pop edi ; restore caller's edi
stdRET _READ_PORT_BUFFER_ULONG
stdENDP _READ_PORT_BUFFER_ULONG
;++
;
; VOID
; WRITE_PORT_UCHAR(
; PUCHAR Port,
; UCHAR Value
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Value
;
;--
cPublicProc _WRITE_PORT_UCHAR ,2
cPublicFpo 2, 0
mov edx,[esp+4] ; (dx) = Port
mov al,[esp+8] ; (al) = Value
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
out dx,al
stdRET _WRITE_PORT_UCHAR
align 4
@@:
mov [edx], al
stdRET _WRITE_PORT_UCHAR
stdENDP _WRITE_PORT_UCHAR
;++
;
; VOID
; WRITE_PORT_USHORT(
; PUSHORT Port,
; USHORT Value
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Value
;
;--
cPublicProc _WRITE_PORT_USHORT ,2
cPublicFpo 2, 0
mov edx,[esp+4] ; (dx) = Port
mov eax,[esp+8] ; (ax) = Value
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
out dx,ax
stdRET _WRITE_PORT_USHORT
align 4
@@:
mov [edx], ax
stdRET _WRITE_PORT_USHORT
stdENDP _WRITE_PORT_USHORT
;++
;
; VOID
; WRITE_PORT_ULONG(
; PULONG Port,
; ULONG Value
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Value
;
;--
cPublicProc _WRITE_PORT_ULONG ,2
cPublicFpo 2, 0
mov edx,[esp+4] ; (dx) = Port
mov eax,[esp+8] ; (eax) = Value
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
out dx,eax
stdRET _WRITE_PORT_ULONG
align 4
@@:
mov [edx], eax
stdRET _WRITE_PORT_ULONG
stdENDP _WRITE_PORT_ULONG
;++
;
; VOID
; WRITE_PORT_BUFFER_UCHAR(
; PUCHAR Port,
; PUCHAR Buffer,
; ULONG Count
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Buffer address
; (esp+12) = Count
;
;--
cPublicProc _WRITE_PORT_BUFFER_UCHAR ,3
cPublicFpo 3, 0
mov eax,esi ; Save esi
mov edx,[esp+4] ; (dx) = Port
mov esi,[esp+8] ; (esi) = buffer
mov ecx,[esp+12] ; (ecx) = transfer count
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
rep outsb
mov esi,eax
stdRET _WRITE_PORT_BUFFER_UCHAR
align 4
@@:
push eax ; save eax (really the orig esi)
;
; this code to handle I/O to the extra busses should be written better
;
align 4
@@:
mov al, byte ptr [esi]
mov byte ptr [edx], al
inc esi
dec ecx
jnz @b
pop esi ; restore caller's esi
stdRET _WRITE_PORT_BUFFER_UCHAR
stdENDP _WRITE_PORT_BUFFER_UCHAR
;++
;
; VOID
; WRITE_PORT_BUFFER_USHORT(
; PUSHORT Port,
; PUSHORT Buffer,
; ULONG Count
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Buffer address
; (esp+12) = Count
;
;--
cPublicProc _WRITE_PORT_BUFFER_USHORT ,3
cPublicFpo 3, 0
mov eax,esi ; Save esi
mov edx,[esp+4] ; (dx) = Port
mov esi,[esp+8] ; (esi) = buffer
mov ecx,[esp+12] ; (ecx) = transfer count
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
rep outsw
mov esi,eax
stdRET _WRITE_PORT_BUFFER_USHORT
align 4
@@:
push eax ; save eax (really the orig esi)
;
; this code to handle I/O to the extra busses should be written better
;
align 4
@@:
mov ax, word ptr [esi]
mov word ptr [edx], ax
add esi, 2
dec ecx
jnz @b
pop esi ; restore caller's esi
stdRET _WRITE_PORT_BUFFER_USHORT
stdENDP _WRITE_PORT_BUFFER_USHORT
;++
;
; VOID
; WRITE_PORT_BUFFER_ULONG(
; PULONG Port,
; PULONG Buffer,
; ULONG Count
; )
;
; Arguments:
; (esp+4) = Port
; (esp+8) = Buffer address
; (esp+12) = Count
;
;--
cPublicProc _WRITE_PORT_BUFFER_ULONG ,3
cPublicFpo 3, 0
mov eax,esi ; Save esi
mov edx,[esp+4] ; (dx) = Port
mov esi,[esp+8] ; (esi) = buffer
mov ecx,[esp+12] ; (ecx) = transfer count
test edx, 080000000h ; high bit on?
jnz short @f ; yes, it is memory-mapped
rep outsd
mov esi,eax
stdRET _WRITE_PORT_BUFFER_ULONG
align 4
@@:
push eax ; save eax (really the orig esi)
;
; this code to handle I/O to the extra busses should be written better
;
align 4
@@:
mov eax, dword ptr [esi]
mov dword ptr [edx], eax
add esi, 4
dec ecx
jnz @b
pop esi ; restore caller's esi
stdRET _WRITE_PORT_BUFFER_ULONG
stdENDP _WRITE_PORT_BUFFER_ULONG
_TEXT$00 ends
end