Re: Read full 8-bit character from serial port?



David Empson <dempson@xxxxxxxxxxxxx> wrote:

Looks like I'll have to do a real test with the IIgs (or an ESCC, which
I have access to at work) to prove it one way or the other.

David, I think this may help...

kACMD EQU $C039 //scc CHANNEL A
kADATA EQU $C03B
kBCMD EQU $C038 //scc CHANNEL B
kBDATA EQU $C03A
kReadKbd EQU $C000
kClearKbdStr EQU $C010
kBell EQU $FF3A
kVIDOUT EQU $FDF0


----------------------------------
//this is the entry point. It will wait for a keypress:
//a '3' will send 3 chars in a row through scc channel A
//a '4' will send 4 chars in a row through scc channel A
//a '5' will send 5 chars in a row through scc channel A
//any other key will just beep to let you know it's alive
//after the chars are sent,
//THEY ARE SUPPOSED TO ARRIVE TO CHANNEL B :
//for this to work you need to plug an imagewriter minidin8
//cable between port A and port B
//Then it pulls the chars from the scc channel B buffer until
//it's empty. For every rx char that has the overrun
//flag set, it will beep once. Every char is echoed to
//the screen directly via VIDOUT, not through (CSW).
//the idea is: a 3 should not beep.
//a 4 will beep if overrun happens with the 4th rx char.
//a 5 will beep if overrun happens with the 5th rx char.
//David, or anyother volunteer, I don't have a IIGS,
//if you can assemble this, please
//let me know what you find out.
//RECHECK THE CODE, IT'S NOT TESTED.
//Thanks, Jorge.



mainEntry JSR initSSC //'init' the 8530
LDA kClearKbdStr

waitKbd LDA kReadKbd //wait for keypress
BPL waitKbd

STA kClearKbdStr //clear kbd strobe
AND #$7F //clear kbd char bit 7

LDX #$03 // X==number of chars to send
CMP #'3'
BEQ doit
INX
CMP #'4'
BEQ doIt
INX
CMP #'5'
BEQ doIt
JSR kBell
JMP waitKbd

doIt JSR sendAChar //loop to send X chars
DEX
BNE doIt

JSR makeSureAllSent
JSR emptySCCBuffer //read the buffer & beep if err
JMP waitKbd

--------------------------------------
//sendAChar
//1.- checks to make sure that the tx buffer is empty
//2.- if it is, it writes a 'Z' to the tx buffer.
//****** OF CHANNEL *A* *******

sendAChar LDA kADATA // Wait for TX buffer empty
AND #$04 //rr0 bit 2 == TX buffer empty
BNE sendAChar

LDA #$08
STA kACMD //set pointer to wr8
LDA #'Z' //this can be whatever char
STA kACMD //TX buffer == wr8
RTS
---------------------------------------
//makeSureAllSent
//This makes sure that the chars that sendAChar has put
//into the TX buffer, made its way completely out of the
//scc. Writing to tx buffer initiates a transmission, but
//at low baud rates the transmission can take in fact quite
//a long time, much longer that the time it takes for the
//tx buffer to become empty. That's why checking for the TX
//buffer to be empty does not mean that the char has been sent.
//In order to know that, we have to check All Sent (rr1 bit 0)
//remember, we send through ***CHANNEL A***

makeSureAllSent LDA #$01
STA kACMD //set pointer to rr1
LDA kADATA
AND #$01 //RR1 BIT 0 == ALLSENT
BEQ makeSureAllSent //loop until all sent
RTS

---------------------------------------
//emptySCCBuffer
//1.- Check if there's anything in the rx buffer
//2.- If there's nothing, just return
//3.- If there's anything, check the overrun flag
//and if it is set, BEEP
//4.- Pull the char from the RX buffer
//5.- GOTO 1
//REMEMBER WE RECEIVE THE CHARS IN ****CHANNEL B****



emptySCCBuffer LDA kBDATA //READ 8530 READ REGISTER 0
AND #$01 //BIT 0 MEANS RX CHAR AVAILABLE
BNE pullIt
RTS


// THERE'S A CHAR IN THE 8530 RX BUFFER
pullIt LDA #$01 // SET 'POINTER' TO rr1
STA kBCMD
LDA kBDATA // READ rr1
AND #$20 // CHECK FOR bit 5=RX OVERRUN
BEQ itsOK
JSR kBeep //BEEP ON RX OVERRUN(BUFFER OVERFLOW)

itsOK LDA #$08 // WE WANT TO READ rr8
STA kBCMD // SET 'POINTER' TO rr8
LDA kBDATA // READ rr8
JSR kVIDOUT //should echo to the screen...
JMP emptySCCBuffer

___________________________________________
//initSSC
//1.- This does not really setup the SSC
//2.- It only disables the MasterIterruptEnable bits
//for both channels, in order to avoid the recently
//discovered BluRry's syndrome by which you always
//get late because the interrupts end up being faster
//than your own code... ugly.
//3.- So, the ports have to be opened beforehand by some other means
//for example by PR#, IN# or whatever, in order to get the
//scc clock source, divisor, brg, time constant etc properly
//setup. BOTH CHANNELS MUST BE SETUP TO THE SAME BAUD RATE,
//lenght, stop bits, etc. Once opened, they can be closed before
//running this whole thing. The relevant settings will (hopefully)
//remain set inside the scc.



initSSC LDA kACMD //READ TO RESET channelA POINTER TO 0
LDA #$09
STA $kACMD //SET 'POINTER' TO wr9
LDA #$00
STA $kACMD //Anti BluRry's syndrome medication

LDA kBCMD //READ TO RESET channelB POINTER TO 0
LDA #$09
STA $kBCMD //SET 'POINTER' TO wr9
LDA #$00
STA $kBCMD //Anti BluRry's syndrome medication

RTS

Regards,
Jorge.
--
Jorge Chamorro Bieling
.



Relevant Pages