Here is the user manual for the SCC.
There are many ways to use it, so providing code to "control it directly" probably isn't terribly useful without knowing what you're trying to do. There's also differences in how it can be accessed across machine models like the IIfx and the Q9x0 machines.
Then, depending on what has been initialized, you may need to initialize some ancillary machine specific hardware.
I used the serial port for some ROM debugging, which just initialized the SCC hardware (and VIA1 since I was running before much was initialized), didn't use interrupts, and write out debugging information a character at a time.
This makes sure the hardware is ready to transmit, sends the character, and polls to make sure it has been sent:
There are many ways to use it, so providing code to "control it directly" probably isn't terribly useful without knowing what you're trying to do. There's also differences in how it can be accessed across machine models like the IIfx and the Q9x0 machines.
Then, depending on what has been initialized, you may need to initialize some ancillary machine specific hardware.
I used the serial port for some ROM debugging, which just initialized the SCC hardware (and VIA1 since I was running before much was initialized), didn't use interrupts, and write out debugging information a character at a time.
Code:
; This code initializes the serial access on a IIsi
; It should work for II, IIx, SE/30, IIci, IIcx, and the Iisi, but so far
; testing is limited to the IIsi.
; The VIA1 initialization values are taken from the ProductInfo table
; Some minimal VIA1 initialization is required for the SCC to work.
move.l #$50F00600, A0 ; vDirA
move.b #$2F, (A0)
move.l #$50F00200, A0 ; vBufA
move.b #$26, (A0)
; SCC port A is the "Modem" port.
move.l #$50F04002, A0 ; SCC aCtl
move.b #9, (A0)
move.b #$C0, (A0) ; resets SCC (both ports)
move.b #1, (A0)
move.b #0, (A0) ; disable rx/tx
move.b #4, (A0)
move.b #$44, (A0) ; x16 clock, 8 bit sync char, 1 stop bit/char, no parity
move.b #11, (A0)
move.b #$50, (A0) ; BR generated timing
move.b #12, (A0)
move.b #10, (A0) ; lower byte of time constant (9600 baud)
move.b #13, (A0)
move.b #0, (A0) ; upper byte of time constant (9600 baud)
move.b #14, (A0)
move.b #1, (A0) ; BR generator enable
move.b #15, (A0)
move.b #0, (A0) ; No interrupts
move.b #9, (A0)
move.b #0, (A0) ; No interrupts
move.b #3, (A0)
move.b #$C1, (A0) ; Rx 8 bits/char, Rx enable
move.b #5, (A0)
move.b #$6A, (A0) ; Tx 8 bits/char, Tx enable, RTS (RTS enables the line driver)
Code:
; This code sends a byte from D0 and returns through A6
move.l #$50F04002, A0 ; SCC aCtl
checkstatus:
move.b #0, (A0)
btst #3, (A0) ; check for Tx Ready
beq checkstatus
move.l #$50F04006, A0 ; SCC aData
move.b D0, (A0) ; transmit
move.l #40000, D1
Loop:
dbra D1, Loop ; Wait for send
jmp (a6)