Материал из Wiki.
<!-- start content -->
SuperIO чип имеет несколько режимов работы: работа с/через LDN (Logical_Device_Number) и через Environment Controller регистры.
До начала обмена с чипом SuperIO через LDN его нужно инициализировать, иначе команды будут проигнорированы. У разных м/с (разных производителей) существуют различные последовательности для инициализации чипа.
Нижеследующий отрывок безжалостно сдёрнут с форума wasm.ru
IT8702F
87h,01h,55h,55h
IT8712F
87h,01h,55h,55h
IT8706R
87h,06h,55h,55h
IT8710F
87h,87h
W83977EF
87h,87h
W83627HF
87h,87h
W83627HF
87h,87h
PC8739x
01h,00h
FDC37M70x
55h
Пример инициализации SIO IT8712F. Имеем таблицу инициализации и собственно циклический код:
initSIO_string db 87h ;
db 1 ;
db 55h ;
db 55h ;
.
.
.
_SIO_init_
mov si, offset initSIO_string
mov dx, 2Eh
mov cx, 4
Loop_Init_SuperIO: ;
mov al, cs:[si]
out dx, al
inc si ; Increment by 1
loop Loop_Init_SuperIO ; Loop while CX != 0
Вместо циклического кода можно увидеть и просто линейный код, где числа инициализации прописаны прямо в программе.
LDN
2Eh(4Eh) - регистр адреса
2Fh(4Fh) - регистр данных
Так, проинициализировали. Хорошо. Теперь далее.
Для работы с LDN его нуна сначала задать, то есть сообщить чипу, в каком направлении хотим наследить. Для IT8712F это делается записью номера LDN в 7 регистр. То есть 7 пишем в порт 2Eh, в порт 2Fh пишем нужное значение LDN.
set_LDN_SIO proc near | rd_SIO_ proc near | wr_SIO_ proc near |
Environment Controller регистры
А для этого случая инициализация уже не нужна.
Адреса этих регистров задаются при первоначальном программировании SuperIO, но как бы являются стандартом.
295h - регистр адреса
296h - регистр данных
Может быть реализовано в виде подпрограммы. Вход в подпрограмму с параметром - номер регистра, а если еще и пишем - тогда данные для записи.
rd_295h proc near | wr_295h proc near |
Оператор out 0EBh, al - программная задержка.
_F000:3C52 ; =============== S U B R O U T I N E ======================================= _F000:3C52 _F000:3C52 ; Stack Less version _F000:3C52 _F000:3C52 SIO_port_setup_SL proc near ; CODE XREF: SIO_port_setup_S+5j _F000:3C52 ; ReadSIO_SL+3j ... _F000:3C52 8B C8 mov cx, ax _F000:3C54 2E 8B 16 49 71 mov dx, cs:BCPMCD.baseaddr _F000:3C59 2E F6 06 48 71 01 test cs:BCPMCD.flags, 1 ; Logical Compare _F000:3C5F 74 34 jz short return ; Jump if Zero (ZF=1) _F000:3C5F _F000:3C61 BA 98 03 mov dx, 398h _F000:3C61 _F000:3C64 _F000:3C64 setup_loop: ; CODE XREF: SIO_port_setup_SL+3Ej _F000:3C64 EC in al, dx _F000:3C65 86 E0 xchg ah, al ; Exchange Register/Memory with Register _F000:3C67 B0 05 mov al, 5 _F000:3C69 EE out dx, al _F000:3C6A F6 D0 not al ; One's Complement Negation _F000:3C6C E6 ED out IODELAY_PORT, al _F000:3C6E EC in al, dx _F000:3C6F 3C 05 cmp al, 5 ; Compare Two Operands _F000:3C71 86 E0 xchg ah, al ; Exchange Register/Memory with Register _F000:3C73 EE out dx, al _F000:3C74 75 11 jnz short second_stage ; Jump if Not Zero (ZF=0) _F000:3C74 _F000:3C76 86 E0 xchg ah, al ; Exchange Register/Memory with Register _F000:3C78 B0 03 mov al, 3 _F000:3C7A EE out dx, al _F000:3C7B F6 D0 not al ; One's Complement Negation _F000:3C7D E6 ED out IODELAY_PORT, al _F000:3C7F EC in al, dx _F000:3C80 3C 03 cmp al, 3 ; Compare Two Operands _F000:3C82 86 E0 xchg ah, al ; Exchange Register/Memory with Register _F000:3C84 EE out dx, al _F000:3C85 74 0E jz short return ; Jump if Zero (ZF=1) _F000:3C85 _F000:3C87 _F000:3C87 second_stage: ; CODE XREF: SIO_port_setup_SL+22j _F000:3C87 81 FA 5C 01 cmp dx, 15Ch ; Compare Two Operands _F000:3C8B 74 05 jz short set_default_0x2E ; Jump if Zero (ZF=1) _F000:3C8B _F000:3C8D BA 5C 01 mov dx, 15Ch _F000:3C90 EB D2 jmp short setup_loop ; Jump _F000:3C90 _F000:3C92 ; --------------------------------------------------------------------------- _F000:3C92 _F000:3C92 set_default_0x2E: ; CODE XREF: SIO_port_setup_SL+39j _F000:3C92 BA 2E 00 mov dx, 2Eh ; '.' _F000:3C92 _F000:3C95 _F000:3C95 return: ; CODE XREF: SIO_port_setup_SL+Dj _F000:3C95 ; SIO_port_setup_SL+33j _F000:3C95 8B C1 mov ax, cx _F000:3C97 FF E7 jmp di ; Indirect Near Jump _F000:3C97 _F000:3C97 SIO_port_setup_SL endp _F000:3C97 _F000:3C99 _F000:3C99 ; =============== S U B R O U T I N E ======================================= _F000:3C99 _F000:3C99 ; Stack version _F000:3C99 _F000:3C99 SIO_port_setup_S proc near ; CODE XREF: sub_F2B1Ap _F000:3C99 52 push dx _F000:3C9A 57 push di _F000:3C9B BF A0 3C mov di, offset return _F000:3C9E EB B2 jmp short SIO_port_setup_SL ; Stack Less version _F000:3C9E _F000:3CA0 ; --------------------------------------------------------------------------- _F000:3CA0 _F000:3CA0 return: ; DATA XREF: SIO_port_setup_S+2o _F000:3CA0 8B DA mov bx, dx _F000:3CA2 B9 02 00 mov cx, 2 _F000:3CA5 5F pop di _F000:3CA6 5A pop dx _F000:3CA7 C3 retn ; Return Near from Procedure _F000:3CA7 _F000:3CA7 SIO_port_setup_S endp _F000:3CA7