( INTERRUPT DRIVEN SERIAL IO FOR HC11 ( RICK VANNORMAN ( NEW MICROS, INC ( 1601 CHALK HILL ROAD ( DALLAS, TX 75212 ( 214/339-2204 ( 12 JUNE 95 ( ROMABLE CODE ( BUFFERS=256 BYTES EACH COLD HEX ( ENABLE INTERRUPTS CODE-SUB CLI 0E C, ( CLI ) 39 C, ( RTS ) END-CODE ( DISABLE INTERRUPTS CODE-SUB SEI 0F C, ( SEI ) 39 C, ( RTS ) END-CODE ( CHANGE THESE ADDRESSES TO INCREASE/DECREASE BUFFER SIZES OR LOCATIONS 1000 CONSTANT IBUF ( INPUT BUFFER AND 1100 CONSTANT IEND ( ITS END 1100 CONSTANT OBUF ( OUTPUT BUFFER AND 1200 CONSTANT OEND ( ITS END ( THESE ARE HEAD AND TAIL POINTERS FOR THE BUFFERS. THEY MUST RESIDE ( IN RAM, BUT COULD BE INTERNAL RAM IF DESIRED 0FF0 CONSTANT IHEAD 0FF2 CONSTANT ITAIL 0FF4 CONSTANT OHEAD 0FF6 CONSTANT OTAIL ( SAVE A COPY OF THE ORIGINAL CODE VECTORS OF KEY, ETC SO WE CAN RESTORE ( THEM IF NEEDED. THE PLACE THEY ARE STORED IS NOT SACRED AND COULD BE ROM TIB 6 - 0FF8 6 CMOVE ( ----- ( RECEIVER ( A CHAR IS WAITING, PUT IT INTO BUFFER, WRAP WITH NO ERRORS ( CHARS ARE WRITTEN TO THE ADDRESS IN IHEAD. AFTER WRITING, IHEAD ( IS INCREMENTED [OR RESET]. IHEAD ALWAYS POINTS TO NEXT LOCATION CODE-SUB IRCV FE C, IHEAD , ( LDX IHEAD ;POINT TO THE NEXT BUFFER LOCATION B6 C, B02F , ( LDAA SPDR ;READ THE CHAR A7 C, 0 C, ( STAA 0,X ;WRITE IT INTO THE BUFFER 08 C, ( INX ;INCREMENT THE POINTER 8C C, IEND , ( CPX #IEND ;CHECK FOR END OF BUFFER 26 C, 03 C, ( BNE X: ; CE C, IBUF , ( LDX #IBUF ;RESET POINTER FF C, IHEAD , ( X: STX IHEAD ;SAVE NEW POINTER VALUE 39 C, ( RTS ;AND RETURN END-CODE ( TRANSMITTER ( GETS CALLED WHEN THE CURRENT CHARACTER IS FINISHED. IF OHEAD IS ( EQUAL TO OTAIL, THERE ARE NO MORE CHARS, SO DISABLE INTERRUPTS. ( IF CHARS WAITING, WRITE THE NEXT ONE, INCREMENT TAIL, AND CONTINUE CODE-SUB IXMT FE C, OTAIL , ( LDX OTAIL ;POINT TO THIS CHAR A6 C, 00 C, ( LDAA 0,X ;READ CHAR FROM BUFFER AT TAIL B7 C, B02F , ( STAA SPDR ;WRITE TO SERIAL CHANNEL 08 C, ( INX ;INCREMENT POINTER 8C C, OEND , ( CPX #OEND ;CHECK FOR WRAP 26 C, 03 C, ( BEQ Y ;BRANCH IF OK CE C, OBUF , ( LDX #OBUF ;RESET TO START OF BUFFER FF C, OTAIL , ( Y: STX OTAIL ;SAVE NEW POINTER BC C, OHEAD , ( CPX OHEAD ;HEAD. 26 C, 08 C, ( BNE X ;IF HEAD<>TAIL, DO NOTHING B6 C, B02D , ( LDAA SCCR2 ;ELSE, DISABLE TRANSMIT 84 C, 7F C, ( ANDA #7F ;INTERRUPTS B7 C, B02D , ( STAA SCCR2 ; 39 C, ( X: RTS END-CODE ( SERVICE THE SCI INTERRUPT. WE ARE ONLY ALLOWING FOR TRANSMIT ( AND RECEIVE INTERRUPTS, SO THE ROUTINE IGNORES ALL OTHERS CODE-SUB ISERV B6 C, B02E , ( LDAA SCSR ;GET SERIAL STATUS B4 C, B02D , ( ANDA SCCR2 ;MASK FOR WHAT IS ENABLED 84 C, A0 C, ( ANDA #A0 ;AND FOR WHAT WE WORRY ABOUT 2A C, 04 C, ( BPL X ;IF PLUS, IS A RECEIVE INT BD C, ' IXMT @ , ( JSR IXMT ;GO TO IXMT IF TDRE IS SET 3B C, ( RTI BD C, ' IRCV @ , ( X: JSR IRCV ;GO TO IRCV IF RD IS SET 3B C, ( RTI END-CODE ( NON-INTERRUPT INTERFACES TO THE INTERRUPT ROUTINES ( ----- ( CHARS ARE WAITING IF IHEAD IS NOT EQUAL TO ITAIL CODE-SUB RCV? ( -- flag ) CC C, FFFF , ( LDD #-1 ;START WITH TRUE FE C, IHEAD , ( LDX IHEAD ;GET HEAD BC C, ITAIL , ( CPX ITAIL ;COMPARE TO TAIL 26 C, 03 C, ( BNE X ;IF NOT EQUAL, IS TRUE, GO RTS C3 C, 0001 , ( ADDD #1 ;EQUAL, FALSE, -1 + 1 = 0 18 C, 09 C, ( DEY ;MAKE ROOM ON THE STACK 18 C, 09 C, ( DEY ; 18 C, ED C, 00 C, ( STD 0,Y ;WRITE 16 BIT CHAR TO STACK 39 C, ( X: RTS ;RETURN END-CODE ( WAIT FOR A CHAR, READ IT, THEN INCREMENT ITAIL, WRAP IF NEEDED CODE-SUB RCV ( -- flag ) 4F C, ( CLRA ;ZERO FOR 16 BIT VALUE LATER 18 C, 09 C, ( DEY ;MAKE ROOM ON THE STACK 18 C, 09 C, ( DEY ; FE C, ITAIL , ( LDX ITAIL ;GET TAIL BC C, IHEAD , ( X: CPX IHEAD ;SPIN TIL HEAD <> TAIL 27 C, FB C, ( BEQ X ; E6 C, 00 C, ( LDAB 0,X ;GET CHAR INTO B 18 C, ED C, 00 C, ( STD 0,Y ;WRITE 16 BIT CHAR TO STACK 08 C, ( INX ;INCREMENT BUFFER POINTER 8C C, IEND , ( CPX #IEND ;CHECK FOR END OF BUFFER 26 C, 03 C, ( BNE Y: ; CE C, IBUF , ( LDX #IBUF ;RESET POINTER FF C, ITAIL , ( Y: STX ITAIL ;SAVE NEW POINTER VALUE 39 C, ( RTS END-CODE ( PUT A CHARACTER INTO THE OBUF FOR TRANSMISSION. IF OHEAD IS JUST ( ABOUT TO OVERTAKE OTAIL, IE THE BUFFER IS _ALMOST_ FULL, WAIT FOR ( IT TO UNCLOG BEFORE WRITING THE CHARACTER. THE TRANSMITTER IDLES ( WITH AN INTERRUPT PENDING, SO THE FIRST CHAR IS SENT BY JUST PUTTING ( IT IN THE BUFFER AND ENABLING THE INTERRUPTS. XMT ALWAYS ENABLES ( THE TRANSMITTER INTERRUPT, JUST IN CASE IT WAS OFF. CODE-SUB XMT ( char -- ) 18 C, E6 C, 01 C, ( LDAB 1,Y ;GET CHAR FE C, OHEAD , ( LDX OHEAD ;GET WHERE TO PUT CHARS E7 C, 00 C, ( STAB 0,X ;WRITE INTO BUFFER AT X 08 C, ( INX ;INCREMENT BUFFER POINTER 8C C, OEND , ( CPX #OEND ;END OF BUFFER 26 C, 03 C, ( BNE Y: ;NO, SKIP RELOAD CE C, OBUF , ( LDX #OBUF ;RELOAD WITH START BC C, OTAIL , ( Y: CPX OTAIL ;COMPARE WHERE WE ARE TO TAIL 27 C, FB C, ( BEQ Z ;WAIT UNTIL BUFFER NOT FULL FF C, OHEAD , ( STX OHEAD ;AND SAVE IN POINTER B6 C, B02D , ( LDAA SCCR2 ;ENABLE XMT INTERRUPT 8A C, 80 C, ( ORAA #80 ; B7 C, B02D , ( STAA SCCR2 ; 18 C, 08 C, ( C: INY ;DISCARD CHARACTER 18 C, 08 C, ( INY 39 C, ( RTS END-CODE ( SETUP TO USE INTERRUPT DRIVING CONSOLE I/O : NEW SEI IBUF DUP IHEAD ! ITAIL ! OBUF DUP OHEAD ! OTAIL ! 7E B7BF EEC! [ ' ISERV @ ] LITERAL DUP >< FF AND B7C0 EEC! FF AND B7C1 EEC! 2C B02D C! TIB 6 - [ ' RCV @ ] LITERAL OVER ! 2+ [ ' XMT @ ] LITERAL OVER ! 2+ [ ' RCV? @ ] LITERAL SWAP ! CLI ; ( RESTORE POLLED CONSOLE I/O : OLD SEI 0FF8 TIB 6 - 6 CMOVE ;