home *** CD-ROM | disk | FTP | other *** search
- SUBTTL ST01 Module
- INCLUDE DEFS.INC
- include sysinfo.inc
-
- include debug.inc
-
- EnableFast equ 1 ;Fast transfer mode
- EnableBlock equ 0 ;Block transfer mode (not for 486)
- BlockSize equ 512 ;Max block transfer size
- WrtWait equ 12 ;Wait loop at fast write
-
- ;
- ; Register conventions:
- ;
- ; DS: data segment
- ; ES: available, not preserved
- ; FS: port segment, preserved
- ; GS: available, not preserved
- ;
- ; Caution: The device helper functions Block and Yield
- ; clear FS and GS - im Gegensatz zur Doku!
- ;
-
- if JR
- PhysIO equ 0C9A00h ;Physical address of ST01 I/O ports
- else
- PhysIO equ 0CFA00h ;Physical address of ST01 I/O ports
- endif
- IRQnum equ 5 ;IRQ number
- HostID equ 6 ;Host adapter SCSI ID
- if JR
- TargetID equ 4 ;Target SCSI ID
- else
- TargetID equ 4 ;Target SCSI ID
- endif
-
- TimeSlice equ 2000 ;Time to sleep in execution phase
-
- _cmd equ 0000h ;Control/status port
- _dat equ 0200h ;Data port (1KB)
-
- cmd equ byte ptr fs:[_cmd] ;usually
- dat equ byte ptr fs:[_dat]
-
- CEN equ 80h ;enable
- CIE equ 40h ;interrupt enable
- CPE equ 20h ;parity enable
- CARB equ 10h ;start arbitration
- CATN equ 08h
- CBSY equ 04h
- CSEL equ 02h
- CRST equ 01h
-
- SARB equ 80h ;arbitration complete
- SPE equ 40h ;parity error
- SSEL equ 20h
- SREQ equ 10h
- SCD equ 08h
- SIO equ 04h
- SMSG equ 02h
- SBSY equ 01h
-
- ; Message-In/Out Codes
- MsgComplete equ 00h
- MsgSavePointer equ 02h
- MsgRestPointer equ 03h
- MsgDisconnect equ 04h
- MsgError equ 05h
- MsgAbort equ 06h
- MsgReject equ 07h
- MsgNop equ 08h
- MsgParity equ 09h
- MsgLinkedCompl equ 0Ah
- MsgLinkedComplF equ 0Bh
- MsgReset equ 0Ch
- MsgIdentify equ 80h
-
- ;; MsgCanDisconn equ 0h
- MsgCanDisconn equ 40h
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- StartData
-
- public host_id
- public target_id
- public irq_num
- public phys_addr
-
- public sysinfo_seg
-
- extrn DevHlpPtr:dword
-
- ;
- ; Set by command line switches
- ;
- even
- phys_addr dd PhysIO ;Physical address of I/O ports
- irq_num dw IRQnum ;IRQ number
- host_id db 1 shl HostID ;Host adapter SCSI ID mask
- target_id db 1 shl TargetID ;Target SCSI ID mask
-
- ;
- ; Other data
- ;
- even
- port_seg dw 0 ;Protected mode I/O port selector
- sysinfo_seg dw 0 ;Bimodal sysinfo segment address
- yield_ptr dd 0 ;Bimodal ptr to yield flag
- timeout dd 0 ;Start time
- event_id dd 0 ;Dummy phys addr used as event ID
- data_ptr dd 0 ;Virtual data transfer address
- data_len dw 0 ;Requested transfer length
- actual_len dw 0 ;Actual transfer length
- cmdptr dw 0 ;Near pointer to next command byte
- xstatus dw 0 ;Execute returns this on completion
- status db 0 ;Status byte
- wait_for_int db 0 ;Waiting for reselection interrupt
- reconnect_flag db 0 ;Reconnection interrupt occurred
- msg_byte db 0 ;Send this in message out phase
- fast_xfer db 0 ;Fast block transfer mode
-
- EndData
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- StartCode
-
- public dev_interrupt
- public command
- public bus_reset
- public device_reset
- public init_io
- public delay
-
- public ST_INIT_null
- ST_INIT_null:
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;
- ; Set time to now + CX
- ;
- set_time proc near
- mov es, sysinfo_seg
- movzx ecx, cx
- add ecx, es:[0].msec_timer
- mov timeout, ecx
- ret
- set_time endp
-
- ;
- ; Compare time to saved time
- ;
- cmp_time proc near
- mov es, sysinfo_seg
- mov eax, es:[0].msec_timer
- cmp eax, timeout
- ret
- cmp_time endp
-
- ;
- ; Wait CX msec
- ;
- delay proc near
- outtext 10, 'Delay '
- outword 10, cx
- outchar 10, '$'
- push fs
- pusha
- mov ax, cs
- mov bx, offset delay
- sub di, di
- mov dh, 1 ;not interruptible
- DevHlp DevHlp_Block
- popa
- pop fs
- ret
- delay endp
-
- ;
- ; Wait for event (interruptible), max CX msec
- ; Return: C=0: event wakeup
- ; C=1: Z=1: timeout
- ; Z=0: interrupted
- ;
- sleep proc near
- outtext 5, 'Sleep '
- outword 5, cx
- push fs
- push di
- mov ax, event_id._hi
- mov bx, event_id._lo
- sub di, di
- mov dh, 0
- DevHlp DevHlp_Block
- pop di
- pop fs
- if trace
- pushf
- jc short sl_1
- outtext 5, ': event$'
- jmp short sl_2
- sl_1: outtext 5, ': timeout$'
- sl_2: popf
- endif
- ret
- sleep endp
-
- yield proc near
- push dx
- push bx
- les bx, yield_ptr
- cmp byte ptr es:[bx], 0
- je short yield1
- outtext 5, 'Yield$'
- push fs
- DevHlp DevHlp_Yield
- pop fs
- yield1: pop bx
- pop dx
- yield2: ret
- yield endp
-
- ;
- ; Wait for (status & DH) == DL, max CX msec
- ; C=1: timeout
- wait_for proc near
- outtext 10, 'Wait '
- outword 10, cx
- outtext 10, ' for (status & '
- outbyte 10, dh
- outtext 10, ') == '
- outbyte 10, dl
- outchar 10, '$'
- pusha
- popa
- mov al, cmd
- and al, dh
- cmp al, dl
- jne short wf_wait
- wf_ok: clc
- ret
- wf_wait:call set_time
- wf_loop: ;;!! call yield
- mov al, cmd
- and al, dh
- cmp al, dl
- je short wf_ok
- call cmp_time
- jb short wf_loop
- wf_to: stc
- ret
- wait_for endp
-
- waitfor macro mask, comp, time
- mov dx, (mask) * 256 + (comp)
- mov cx, time
- call wait_for
- endm
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;
- ; Device interrupt
- ; - Check for proper reselection and wakeup driver if
- ; waiting for reconnection.
- ; - Take care of race conditions in a system with
- ; multiple host adapters on the same bus.
- ; - The CIE bit does not to seem to be what its name
- ; suggests, so accept but ignore interrupts at other
- ; times.
- ; - Cannot use waitfor, since Yield is unusable at
- ; interrupt time.
- ;
- dev_interrupt proc far
- push fs
- push DevHlpPtr ;Setup for DevHlp calls.
- mov bp, sp
-
- outtext 3, '-IRQ-'
- cmp wait_for_int, 0 ;Perhaps unexpected?
- mov wait_for_int, 0
- je int_ign
-
- smsw ax ;Set I/O segment for each mode.
- test al, 1
- jnz short int_pm
- int_rm: mov eax, phys_addr ;The interrupt can occur in real mode.
- shr eax, 4
- mov fs, ax
- jmp short int_cont
- int_pm: mov fs, port_seg
- int_cont:
-
- mov cmd, CPE ;Disable ST01 interrupts
- mov ax, irq_num ;Allow all other interrupts
- DevHlp DevHlp_EOI ;to reduce interrupt latency.
-
- test cmd, SSEL ;The SEL line should be active since
- jz int_bad ;it triggered the interrupt.
-
- mov cx, 1000 ;Wait for release of BSY for IO
- int_1: test cmd, SBSY ;line and ID bits to become active.
- loopnz int_1
- jnz short int_bad
-
- mov al, cmd ;Check for a valid reselection.
- test al, SIO ;Is it a reselection?
- jz short int_bad
- test al, SPE ;Ignore reselections with bad parity.
- jnz short int_bad
-
- mov al, dat ;Check initiator & target IDs.
- xor al, host_id
- xor al, target_id
- jnz short int_bad
-
- test cmd, SSEL ;The SEL line should still be active
- jz short int_bad ;but maybe another host adapter
- ;got selected and the ID bits on the
- ;data bus were garbage. In this case,
- ;the SEL line should now be inactive.
-
- mov cmd, CEN+CPE+CBSY ;Acknowledge reselection.
- mov cx, 10000 ;Wait for end of SEL.
- int_2: test cmd, SSEL
- loopnz int_2
- jcxz int_bad
- mov cmd, CEN+CPE+CIE ;Now the targed controls BSY.
-
- mov ax, event_id._hi ;Wakeup waiting driver.
- mov bx, event_id._lo
- DevHlp DevHlp_Run
-
- mov reconnect_flag, 1 ;Show the world.
- outtext 10, 'OK-'
-
- int_r: lea sp, [bp+4]
- pop fs
- clc ;The interrupt is ok.
- ret
-
- int_ign:
- outtext 3, 'IGN-'
- mov ax, irq_num
- DevHlp DevHlp_EOI
- jmp short int_r
-
- int_bad:
- outtext 3, 'BAD-'
- mov cmd, CPE+CIE ;Rearm for next (re-)selection.
- jmp short int_r
-
- dev_interrupt endp
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;
- ; Initiate SCSI bus operations
- ; C=1, AX=error-code
- arbitrate proc near
- outtext 3, 'Arbitration$'
-
- arb_loop:
- mov cmd, CPE ;Clear pending parity errors.
- mov al, host_id ;Send host adapter SCSI ID.
- mov dat, al
- mov cmd, CEN+CPE+CARB ;Start bus arbitration.
- waitfor SARB, SARB, 100 ;Wait for success.
- jnc short arb_select
-
- mov cx, TimeSlice ;Takes long, go to sleep.
- call sleep
- jnc short arb_loop
- jz short arb_loop
-
- mov ax, STERR+11h ;Character I/O call interrupted.
- stc
- ret
-
- arb_select:
- outtext 4, 'Select target$'
-
- mov al, target_id ;Send both host & target SCSI IDs.
- or dat, al
- mov cmd, CEN+CPE+CATN+CSEL ;Signal target selection. Request
- waitfor SBSY, SBSY, 250 ;a message out phase via ATN.
- jc short dev_not_ready
- mov cmd, CEN+CPE+CATN ;Now target controls SEL.
-
- outtext 4, 'Arbitration done$'
- clc
- ret
-
- dev_not_ready:
- outtext 1, 'Initiation error$'
- mov ax, STERR+02h
- stc
- ret
-
- arbitrate endp
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;
- ; Disconnected. Wait for reselection
- ; Interrupts are disabled on entry.
- ; C=1, AX=error-code
- reconnect proc near
- outtext 3, 'Waiting for reselection$'
- res_loop:
- cli
- cmp reconnect_flag, 0 ;Check the flag to be sure
- jne res_ok ;the interrupt didn't get lost.
- mov cx, 1000 ;Wait for reselection.
- call sleep
- sti
- jnc short res_ok ;Event?
- jnz short res_int ;Interrupt?
- jmp short res_loop ;Timeout.
- res_ok:
- sti
- outtext 3, 'Reconnected$'
- mov wait_for_int, 0
- clc
- ret
- res_int:
- outtext 1, 'Reconnection interrupted$'
- mov ax, STERR+11h ;Character I/O call interrupted.
- mov wait_for_int, 0
- stc
- ret
- reconnect endp
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;
- ; On SCSI bus. Execute transfer as controlled by target.
- ; C=1, AX=error-code on error
- ;
- execute proc near
- outtext 3, 'Execute$'
-
- push di
- push si
- mov xstatus, 0
- jmp x_loop
-
- even ;CD IO MSG phase
- x_table dw x_data_out ;0 0 0 data out
- dw x_inv_bus ;0 0 1 -invalid-
- dw x_data_in ;0 1 0 data in
- dw x_inv_bus ;0 1 1 -invalid-
- dw x_cmd_out ;1 0 0 command
- dw x_msg_out ;1 0 1 message out
- dw x_stat_in ;1 1 0 status
- dw x_msg_in ;1 1 1 message in
-
- x_inv_bus:
- outtext 1, 'X: Invalid bus state$'
- call bus_reset ;Bus reset required.
- mov ax, STERR+0Ch ;General failure.
- jmp x_error
-
- x_parity:
- outtext 1, 'X: Parity error$'
- mov cmd, CEN+CPE+CATN ;Request message phase
- mov msg_byte, MsgError ;to inform the target of the problem.
- jmp x_loop ;Target should terminate the command.
-
- x_loop: mov bl, cmd ;First check for next byte.
- outtext 20, 'X_Loop '
- outbyte 20, bl
- outchar 20, '$'
- test bl, SBSY
- jz x_not_bsy
- test bl, SREQ
- jz short x_wait
- test bl, SPE
- jnz short x_parity
- x_jump: and bx, SCD+SIO+SMSG ;Execute next byte or block.
- jmp x_table[bx]
-
- x_wait: mov cx, 100 ;Not yet avail., setup for timeout.
- call set_time
- x_test: mov bl, cmd ;Wait for next byte or timeout.
- outtext 20, 'X_Loop '
- outbyte 20, bl
- outchar 20, '$'
- test bl, SBSY
- jz x_not_bsy
- test bl, SREQ
- jnz short x_jump
- test bl, SPE
- jnz x_parity
- call yield
- call cmp_time
- jb short x_test
-
- mov cx, TimeSlice ;Takes a long time
- call sleep ;so give up timeslices.
- jnc short x_test
- jnz short x_interrupted
-
- mov al, msg_byte ;Timeout.
- test al, MsgIdentify ;Message out phase pending?
- jnz short x_test
- cmp al, MsgReject
- je short x_test
- x_no_response:
- outtext 1, 'X: No response$' ;Target did not respond to message out.
- call bus_reset ;phase request. Reset the bus.
- mov ax, STERR+02h ;Device not ready
- jmp x_error
-
- x_interrupted:
- outtext 1, 'X: Interrupted$'
- cmp msg_byte, MsgAbort ;Repeated?
- je short x_no_response
- mov cmd, CEN+CPE+CIE+CATN ;Request message phase
- mov msg_byte, MsgAbort ;to abort the running command.
- mov xstatus, STERR+11h ;Character I/O call interrupted.
- jmp x_loop
-
- x_not_bsy:
- cmp msg_byte, MsgReset ;Bus free due to reset message?
- je short x_retx
- cmp msg_byte, MsgAbort ;Bus free due to abort message?
- je short x_retx
- outtext 1, 'X: Not BSY$' ;No, a real failure.
- mov ax, STERR+0Ch ;General failure.
- jmp x_error
-
- x_ovf:
- mov cmd, CEN+CPE+CIE+CATN ;Request message phase
- outtext 1, 'X: Overflow$'
- mov msg_byte, MsgAbort ;to abort the running command.
- mov xstatus, STERR+0Ch ;General failure.
- mov data_len, 0
- jmp x_loop
-
- x_error:
- pop si
- pop di
- stc
- ret
-
- x_retx: mov ax, xstatus
- test ax, ax
- jnz short x_error
- x_ret: pop si
- pop di
- clc
- ret
-
- x_data_in:
- cld
- if EnableFast
- cmp fast_xfer, 0
- jne x_fast_in
- endif
- mov al, dat
- sub data_len, 1
- jc x_ovf
- outtext 5, 'Slow data in: '
- outbyte 5, al
- outtext 5, ' at '
- outword 5, actual_len
- outchar 5, '$'
- les di, data_ptr
- stos byte ptr es:[di]
- mov data_ptr._off, di
- inc actual_len
- jmp x_loop
-
- if EnableFast
- x_fi_0: mov fast_xfer, 0
- jmp x_ovf
- x_fast_in:
- mov cx, data_len
- cmp cx, BlockSize
- jb short x_fi_1
- mov cx, BlockSize
- x_fi_1: jcxz x_fi_0
- outtext 4, 'Fast data in: '
- outword 4, cx
- outtext 4, ' at '
- outword 4, actual_len
- outchar 4, '$'
- add actual_len, cx
- sub data_len, cx
- mov si, _dat
- les di, data_ptr
- rep movs byte ptr es:[di], byte ptr fs:[si]
- mov data_ptr._off, di
- jmp x_loop
- endif
-
- x_data_out:
- cld
- if EnableFast
- cmp fast_xfer, 0
- jne x_fast_out
- endif
- sub data_len, 1
- jc x_do_0
- les si, data_ptr
- lods byte ptr es:[si]
- mov data_ptr._off, si
- mov dat, al
- outtext 5, 'Slow data out: '
- outbyte 5, al
- outtext 5, ' at '
- outword 5, actual_len
- outchar 5, '$'
- inc actual_len
- jmp x_loop
- x_do_0: mov dat, 0
- jmp x_ovf
-
- if EnableFast
- x_fo_0: mov fast_xfer, 0
- jmp x_ovf
- x_fast_out:
- mov cx, data_len
- cmp cx, BlockSize
- jb short x_fo_1
- mov cx, BlockSize
- x_fo_1: jcxz x_fo_0
- outtext 4, 'Fast data out: '
- outword 4, cx
- outtext 4, ' at '
- outword 4, actual_len
- outchar 4, '$'
- add actual_len, cx
- sub data_len, cx
- lgs si, data_ptr
- mov ax, fs
- mov es, ax
- mov di, _dat
- if EnableBlock
- rep movs byte ptr es:[di], byte ptr gs:[si]
- else
- x_fo_2: movs byte ptr es:[di], byte ptr gs:[si]
- push cx
- mov cx, WrtWait
- loop $
- pop cx
- loop x_fo_2
- endif
- mov data_ptr._off, si
- jmp x_loop
- endif
-
- x_msg_in:
- outtext 4, 'Message in: '
- cli
- mov wait_for_int, 1 ;Enable full interrupt management,
- mov reconnect_flag, 0
- mov cmd, CEN+CPE+CIE ;don't miss reselection interrupt.
- mov al, dat
- cmp al, MsgDisconnect
- je short x_disconnect
- mov wait_for_int, 0 ;Not a disconnect, forget about
- sti ;interrupts.
- cmp al, MsgComplete
- je short x_complete
- test al, MsgIdentify ;Check for other known messages.
- jnz short x_msg_ok
- cmp al, MsgSavePointer
- je short x_msg_ok
- cmp al, MsgRestPointer
- je short x_msg_ok
- mov cmd, CEN+CPE+CIE+CATN ;Unknown message, request message out
- mov msg_byte, MsgReject ;phase and signal message reject.
- outtext 4, 'Rejected '
- outbyte 4, al
- x_msg_ok:
- outchar 4, '$'
- jmp x_loop
-
- x_disconnect:
- outtext 4, 'Disconnect$'
- waitfor SBSY, 0, 100 ;Wait until bus free
- mov cmd, CPE+CIE ; and release bus.
- call reconnect
- jnc x_loop
- push ax ;Reconnection failed, abort command.
- call abort
- pop ax
- jmp x_error
-
- x_complete:
- outtext 4, 'Complete$'
- waitfor SBSY, 0, 100 ;Wait until bus free
- mov cmd, CPE+CIE ; and release bus.
- jmp x_retx
-
- x_msg_out:
- outtext 4, 'Message out: '
- outbyte 4, msg_byte
- outchar 4, '$'
- mov cmd, CEN+CPE+CIE ;Release message phase request.
- mov al, msg_byte
- mov dat, al
- jmp x_loop
-
- x_cmd_out:
- mov si, cmdptr
- lodsb
- mov dat, al
- mov cmdptr, si
- outtext 5, 'Command out: '
- outbyte 5, al
- outchar 5, '$'
- jmp x_loop
-
- x_stat_in:
- mov al, dat
- mov status, al
- outtext 4, 'Status in: '
- outbyte 4, al
- outchar 4, '$'
- jmp x_loop
-
- execute endp
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;
- ; Reset SCSI bus.
- ;
- bus_reset proc near
- push fs
- mov fs, port_seg
- outtext 2, 'Bus reset$'
- mov cmd, CEN+CPE+CRST
- mov cx, 100
- call delay
- mov cmd, 0
- mov cx, 100
- call delay
- pop fs
- clc
- ret
- bus_reset endp
-
- ;
- ; Reset device.
- ;
- device_reset proc near
- push fs
- mov fs, port_seg
- outtext 2, 'Device reset$'
- mov msg_byte, MsgReset
- call arbitrate
- jc short drst_r
- call execute
- drst_r: pop fs
- ret
- device_reset endp
-
- ;
- ; Abort command.
- abort proc near
- push fs
- mov fs, port_seg
- outtext 2, 'Abort command$'
- mov msg_byte, MsgAbort
- call arbitrate
- jc short abrt_r
- call execute
- abrt_r: pop fs
- ret
- abort endp
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;
- ; Execute SCSI command
- ; In:
- ; AL = 0 for slow, 1 for fast transfer
- ; EBX = virtual data transfer address
- ; CX = expected data length
- ; DX = pointer to command record
- ; Out:
- ; C = set on error
- ; AX = error code, 0 if no error
- ; CX = number of data bytes actually transferred
- ; DL = status byte, 0FFh if no status available
- ;
- command proc near
- push fs
- push es
-
- if trace
- pusha
- outtext 2, 'Command, len='
- outword 2, cx
- outtext 2, ', cmd:'
- mov si, dx
- mov cx, 6
- cmd1: lodsb
- outchar 2, ' '
- outbyte 2, al
- loop cmd1
- outchar 2, '$'
- popa
- endif
-
- mov fast_xfer, al
- mov data_ptr, ebx
- mov data_len, cx
- mov cmdptr, dx
- mov actual_len, 0
- mov status, 0FFh
- mov fs, port_seg
-
- mov msg_byte, MsgIdentify+MsgCanDisconn+0
- call arbitrate
- jc short cmd_e
- call execute
- jc short cmd_e
-
- mov dl, status
- mov cx, actual_len
- outtext 2, 'Command status='
- outbyte 2, dl
- outtext 2, ', length='
- outword 2, cx
- outchar 2, '$'
-
- pop es
- pop fs
- clc
- ret
-
- cmd_e: mov dl, status
- mov cx, actual_len
- outtext 2, 'Command error='
- outword 2, ax
- outtext 2, ', status='
- outbyte 2, dl
- outtext 2, ', length='
- outword 2, cx
- outchar 2, '$'
-
- pop es
- pop fs
- stc
- ret
- command endp
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- init_io proc near
- push di
- push si
-
- outtext 2, 'ST_Tape IO init$'
-
- mov ax, phys_addr._hi ;Clear cmd register.
- mov bx, phys_addr._lo
- mov cx, 1000h
- mov dh, 1
- DevHlp DevHlp_PhysToVirt
- jc init_r
- mov byte ptr es:[di+_cmd], 0
- DevHlp DevHlp_UnPhysToVirt
-
- mov al, 1 ;Get sysinfo segment (for msec timer).
- DevHlp DevHlp_GetDOSVar
- jc init_r
- mov es, ax
- mov ax, es:[bx]
- mov sysinfo_seg, ax
-
- mov al, 8 ;Get pointer to yield flag.
- DevHlp DevHlp_GetDOSVar
- jc init_r
- mov yield_ptr._seg, ax
- mov yield_ptr._off, bx
-
- sub si, si ;The physical address of the driver's
- DevHlp DevHlp_VirtToPhys ;data segment is used as event ID.
- mov event_id._hi, ax
- mov event_id._lo, bx
-
- mov ax, ds ;Allocate port I/O segment selector.
- mov es, ax
- mov di, offset port_seg
- mov cx, 1
- DevHlp DevHlp_AllocGDTSel
- jc short init_r
-
- mov ax, phys_addr._hi ;Set port I/O segment address.
- mov bx, phys_addr._lo
- mov cx, 1000h
- mov si, port_seg
- DevHlp DevHlp_PhysToGDTSel
- jc short init_r
-
- mov ax, offset dev_interrupt
- mov bx, irq_num ;Set interrupt handler.
- mov dh, 0
- DevHlp DevHlp_SetIRQ
- jc short init_r
-
- init_r: pop si
- pop di
- ret
- init_io endp
-
- EndCode
-
- end
-