MIB2 low-level access
MIB2 low-level access
So a few months ago I bought an MIB2 serial card, primarily as a way to potentially interface th Adam to the real world. However, it turns out that the documentation that comes with it does not discuss low-level access from assembly so that the parallel or serial ports could be interfaced to things like a raspberry Pi, Arduino, or motor controllers for example.
Is there any document out there on this?
Is there any document out there on this?
Re: MIB2 low-level access
Here is code I use - should be self explanatory
Code: Select all
; Serial communications
; Eve / Orphanware compatible 8251 on ports 44h - 47h
DataPort .equ 044h ; Data port (in/out)
StatPort .equ 045h ; Status port (in)
BaudRatePort .equ 046h ; Baud rate port (out)
ControlPort .equ 047h ; Control port (out)
InMask .equ 2 ; 8251 RxRDY
OutMask .equ 1 ; 8251 TxRDY
ChipSet .equ 037h ; 8251 RTS,ER,RxE,DTR,TxEN
ChipOff .equ 035h ; 8251 RTS,ER,RxE,TxEN (no dtr)
Break .equ ChipSet | 8 ; ChipSet OR send break
Freeze .equ 022h
Reset .equ 027h
n71 .equ 001001010b ; 7n1
n81 .equ 001001110b ; 8n1
n72 .equ 011001010b ; 7n2
n82 .equ 011001110b ; 8n2
e71 .equ 001111010b ; 7e1
e81 .equ 001111110b ; 8e1
e72 .equ 011111010b ; 7e2
e82 .equ 011111110b ; 8e2
o71 .equ 001011010b ; 7o1
o81 .equ 001011110b ; 8o1
o72 .equ 011011010b ; 7o2
o82 .equ 011011110b ; 8o2
b19200 .equ 03fh ; 19200
b9600 .equ 03eh ; 9600
b4800 .equ 03ch ; 4800
b2400 .equ 03ah ; 2400
b1200 .equ 037h ; 1200
b600 .equ 036h ; 600
b300 .equ 035h ; 300
BitParityStop .equ n81
BaudRate .equ b300
Echo .equ FALSE
SerialTest: .module SerialTest
ld a,BaudRate ; Setup the serial port
call SetBaudRate
ld a,BitParityStop
call SetBitSetup
call DTROn
call BreakOff
_keyLoop:
call STARTREADKEY ; Setup the keyboard read
jr nz,_keyboardError ; Keyboard error so exit
_loop:
call CharInput ; Get any character from the Serial port
jr nc,_noSC ; Jump if none
call PrintByte ; Display what we got
_noSC:
call ENDREADKEY ; End the keyboard reading
jr nc,_loop ; No key so continue
jr nz,_keyboardError ; Keyboard error so exit
call CharOutput ; Send the character in A
#if Echo = TRUE
call PrintByte ; Echo to our screen
#endif
jr _keyLoop ; Reset the keyboard read
_keyboardError:
ld hl,Serial_KB_Error
call PrintString
Stop
Serial_KB_Error:
.text "Keyboard Error"
.db NULL
; Gets a character from the Serial input if there is one and returns it in A
; If NC set then no character
CharInput: .module CharInput
in a,(StatPort) ; Get the input status
and InMask
rra ; Rotate into carry
rra
jr nc,_exit ; No character so exit
in a,(DataPort) ; Get data
_exit:
ret
; Send the character in A out the serial port, waiting till it is ready to go
CharOutput: .module CharOutput
push af ; Save character
_loop:
in a,(StatPort) ; Get the output status
and OutMask
rra ; Rotate into carry
jr nc,_loop ; Not ready, check again
pop af ; Get character back
out (DataPort),a ; Put data
ret
; Get serial data into A
SerialInput:
in a,(DataPort) ; Get data
ret
; A = 2 if data has been received (RxRDY)
SerialInputStatus:
in a,(StatPort) ; Get the input status
and InMask
ret
; Put serial data from A
SerialOutput:
out (DataPort),a ; Put data
ret
; A = 1 if ready to send data (TxRDY)
SerialOutputStatus:
in a,(StatPort) ; Get the output status
and OutMask
ret
; Turn DTR On
DTROn:
push af
ld a,ChipSet
out (ControlPort),a
pop af
ret
; Turn DTR Off
DTROff:
push af
ld a,ChipOff
out (ControlPort),a
pop af
ret
; Start serial port break
BreakOn:
push af
ld a,Break
out (ControlPort),a
pop af
ret
; Stop serial port break
BreakOff:
push af
ld a,ChipSet
out (ControlPort),a
pop af
ret
; Set the baud rate to the value in A
SetBaudRate:
push af
push bc
ld b,a
in a,(BaudRatePort)
ld c,a
in a,(BaudRatePort)
ld a,Freeze
out (ControlPort),a
ld a,c
out (BaudRatePort),a
ld a,b
out (BaudRatePort),a
ld a,Reset
out (ControlPort),a
pop bc
pop af
ret
; Set the bit setup to the value in A
SetBitSetup:
push af
push bc
ld b,a
in a,(BaudRatePort)
in a,(BaudRatePort)
ld c,a
ld a,Freeze
out (ControlPort),a
ld a,b
out (BaudRatePort),a
ld a,c
out (BaudRatePort),a
ld a,Reset
out (ControlPort),a
pop bc
pop af
ret
Milli
Re: MIB2 low-level access
And here is some routines I wrote for talking to the adam link modem
Code: Select all
; Setup AdamLink and then answer the phone
.org 0100H
; Setup UART for 8N1 300 baud
ld a,080H ; Get UART's attention
out (05FH),a
out (05FH),a
ld a,040H
out (05FH),a
ld a,0CH ; 8 bits, no parity is assumed since we are not setting it
or 03H ; 64x clock rate, 300 baud
or 040H ; 1 stop bit
out (05FH),a ; Now setup UART
ld de,Title ; Send prompt
ld c,9
call 5
ld c,1 ; Go wait for a key to be pressed so we know to answer the phone
call 5
cp 3 ; Ctrl-C?
jp Z,0 ; Yes, exit
ld a,025H ; RXE(4h) + TXE(1H) + RTS(20H) to hang up phone
out (05FH),a
ld a,07H ; RXE(4h) + TXE(1H) + DTR(2H) set - toggle RTS to answer
out (05FH),a
ld a,027H ; RXE(4h) + TXE(1H) + DTR(2H) + RTS(20H) set - grab phone line and enable carrier
out (05FH),a
; Display modem info till ^C pressed
ModIn:
call KeyIn ; Get Key if any
jr Z,NoKey ; No Key jump
cp 3 ; Ctrl-C?
jp Z,0 ; Yes, exit
NoKey:
in a,(05FH) ; Read status
rra ; Rotate RXREADY into CF
rra
jr NC,ModIn ; Wait for a byte
in a,(05EH) ; Get character
ld e,a ; Display what we received
ld c,2
call 5
jr ModIn ; do more
KeyIn:
ld c,0bH ; Check if character available
call 5
cp 0
jp Z,KeyInExit ; No Key
ld c,1 ; Get actual key in A
call 5
ld c,a
or 1 ; Clear Z flag
ld a,c
KeyInExit:
ret
Title:
.db "Answer 1.0",13,10
.db 13,10
.db "Press any key to answer,",13,10
.db "CTRL+C to exit"
.db "$"
Milli
Re: MIB2 low-level access
Additional Adam Link routines
Code: Select all
.org 0100H
jp Loop
; **** Subroutines ****
; Check if a key is available and return
; it in A. Z is zet if no character
KeyIn:
push bc
push de
push hl
ld c,0bH ; Check if character available
call 5
cp 0
jp Z,KeyInExit ; No Key
ld c,1 ; Get actual key in A
call 5
ld c,a
or 1 ; Clear Z flag
ld a,c
KeyInExit:
pop hl
pop de
pop bc
ret
; Send character in A out to screen
ConOut:
push af
push bc
push de
ld e,a
ld c,2
call 5
pop de
pop bc
pop af
ret
; Send character in A out to modem
ModOut:
push af
ModOutLoop:
in a,(05FH)
rra
jr NC,ModOutLoop
pop af
out (05EH),a
ret
; Check if a byte is available and return
; it in A. NC set if no character
ModIn:
in a,(05FH) ; Read status
rra ; Rotate RXREADY into CF
rra
jr NC,ModInExit
in a,(05EH) ; Get character
ModInExit:
ret
; Check if character in A is CR and if so send a line feed
LineFeed:
push af
cp 13
jp NZ,LineFeedExit
ld a,10 ; Line feed
call ConOut
LineFeedExit:
pop af
ret
nop
nop
nop
nop
nop
Loop:
call KeyIn ;Get Key & Echo
jp Z,NoKey ;No Key jump
cp 3 ; Ctrl-C?
jp Z,0 ; Yes, exit
call ModOut ; Send Key
call LineFeed ; See if Linefeed is needed locally
NoKey:
call ModIn ;Get Modem
jp NC,Loop ;No Modem start over
call ConOut ;Display Modem
call LineFeed ; See if Linefeed is needed locally
jp Loop
Milli
Re: MIB2 low-level access
Ah thank you! I'll have to look at this closely.
Is this your own code and is it taken from some other source?
Is this your own code and is it taken from some other source?
Re: MIB2 low-level access
Does that code really work with the MIB2? I ask because the MIB2 and MIB3 do not use an 8251 USART they use a Phillips SCN2681 DUART and when I was dissembling ADAMLink V it uses ports 10H-1DH to communicate with the SCN2681 (see attached port list) when in MIB2/MIB3 mode.
Re: MIB2 low-level access
This is one aspect of the ADAM which I find annoying: No standard serial or parallel port. How about using the Adamnet network? Any documents on how to access and decode the signals?