MIB2 low-level access

Posts about Input & Output Cards for the Coleco Adam
User avatar
Wmaalouli
Posts: 155
Joined: Sat Jul 20, 2019 2:09 pm

MIB2 low-level access

Post by Wmaalouli » Wed Jul 24, 2019 8:52 pm

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?

User avatar
Milli
Site Admin
Posts: 224
Joined: Fri Jul 19, 2019 3:13 pm
Location: Beaver Falls PA
Contact:

Re: MIB2 low-level access

Post by Milli » Wed Jul 24, 2019 9:49 pm

I have some source code I’ll post
Milli

User avatar
Milli
Site Admin
Posts: 224
Joined: Fri Jul 19, 2019 3:13 pm
Location: Beaver Falls PA
Contact:

Re: MIB2 low-level access

Post by Milli » Thu Aug 01, 2019 8:29 am

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

User avatar
Milli
Site Admin
Posts: 224
Joined: Fri Jul 19, 2019 3:13 pm
Location: Beaver Falls PA
Contact:

Re: MIB2 low-level access

Post by Milli » Thu Aug 01, 2019 8:32 am

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

User avatar
Milli
Site Admin
Posts: 224
Joined: Fri Jul 19, 2019 3:13 pm
Location: Beaver Falls PA
Contact:

Re: MIB2 low-level access

Post by Milli » Thu Aug 01, 2019 8:33 am

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

User avatar
Wmaalouli
Posts: 155
Joined: Sat Jul 20, 2019 2:09 pm

Re: MIB2 low-level access

Post by Wmaalouli » Thu Aug 01, 2019 2:05 pm

Ah thank you! I'll have to look at this closely.
Is this your own code and is it taken from some other source?

User avatar
pearsoe
Posts: 11
Joined: Sun Jul 21, 2019 3:28 pm

Re: MIB2 low-level access

Post by pearsoe » Fri Aug 02, 2019 4:04 pm

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.
Coleco ADAM Port List Updated.zip
(123.06 KiB) Downloaded 308 times

User avatar
Milli
Site Admin
Posts: 224
Joined: Fri Jul 19, 2019 3:13 pm
Location: Beaver Falls PA
Contact:

Re: MIB2 low-level access

Post by Milli » Fri Aug 02, 2019 4:51 pm

I thought the MIB was Eve/Orphanware compatible
Milli

User avatar
Wmaalouli
Posts: 155
Joined: Sat Jul 20, 2019 2:09 pm

Re: MIB2 low-level access

Post by Wmaalouli » Fri Aug 02, 2019 5:33 pm

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?

User avatar
pearsoe
Posts: 11
Joined: Sun Jul 21, 2019 3:28 pm

Re: MIB2 low-level access

Post by pearsoe » Fri Aug 02, 2019 5:43 pm

Milli wrote:
Fri Aug 02, 2019 4:51 pm
I thought the MIB was Eve/Orphanware compatible
I don't see how it could be if the EVE/Orphanware use the 8251 and those ports.

Post Reply