Category : Files from Magazines
Archive   : ISSUE-53.ZIP
Filename : RS232.ASM

 
Output of file : RS232.ASM contained in archive : ISSUE-53.ZIP
*
* Register equates
*

PORTA EQU $00 Port A data register
PORTB EQU $01 Port B data register
PORTC EQU $02 Port C data register
PORTD EQU $03 Port D data register
DDRA EQU $04 Data direction, Port A
DDRB EQU $05 Data direction, Port B
DDRC EQU $06 Data direction, Port C
SPCR EQU $0A SPIE,SPE,-,MSTR;CPOL,CPHA,SPR1,SPR0
SPSR EQU $0B SPIF,WCOL,-,MODF;-,-,-,-
SPDR EQU $0C SPI Data
BAUD EQU $0D -,-,SCP1,SCP0;-,SCR2,SCR1,SCR0
SCCR1 EQU $0E R8,T8,-,M;WAKE,-,-,-
SCCR2 EQU $0F TIE,TCIE,RIE,ILIE;TE,RE,RWU,SBK
SCSR EQU $10 TDRE,TC,RDRF,IDLE;OR,NF,FE,-
SCDR EQU $11 SCI Data
RDR EQU $11 SCI Receive Data (same as SCDR)
TDR EQU $11 SCI Transmit Data (same as SCDR)
TCR EQU $12 ICIE,OCIE,TOIE,0;0,0,IEGE,OLVL
TSR EQU $13 ICF,OCF,TOF,0; 0,0,0,0

ICAP EQU $14 Input Capture Reg (Hi-$14, Lo-$15)
OCMP EQU $16 Output Compare Reg (Hi-$16, Lo-$17)
TCNT EQU $18 Timer Count Reg (Hi-$18, Lo-$19)
ALTCNT EQU $1A Alternate Count Reg (Hi-$1A, Lo-$1B)


* Equates

TICDLYL EQU $64 LSB OF 200US DELAY (4.0 MHZ XTAL)
TICDLYH EQU $00 MSB OF 200US DELAY
LCDPORT EQU PORTA PORT CONNECTED TO LCD
LCD.E EQU 5 BIT CONNECTED TO LCD E-LINE
LCD.RS EQU 4 BIT CONNECTED TO LCD RS-LINE
LLEN EQU 16 NUMBER OF CHARS PER LINE ON DISPLAY
SERSIZE EQU 20 NUMBER OF CHARS IN SERIAL INPUT QUEUE


*
* RAM storage
*
ORG $50 START OF PROGRAM RAM

LCDOUTA RMB 1 LCD TEMP STORAGE
LCDTMP RMB 1 LCD TEMP STORAGE
LCDTMP1 RMB 1 LCD TEMP STORAGE
WAIT$ RMB 1 # OF TICS TO WAIT; 0 = NO WAIT
LDAIND RMB 4 ROOM FOR LDAIND SUBROUTINE
CCOL RMB 1 CURRENT COL NUMBER (ON DISPLAY)
CCHAR RMB 1 CURRENT CHAR (FROM SERIAL PORT)
LINE1 RMB LLEN+1 ROOM FOR ONE LINE PLUS NULL
LINE2 RMB LLEN+1 ROOM FOR A SECOND LINE
SERQ RMB SERSIZE QUEUE FOR INCOMING SERIAL CHARS
OUTPTR RMB 1 OFFSET FOR OUTPUT ROUTINES
INPTR RMB 1 OFFSET FOR INPUT ROUTINES
KEY RMB 1 NON-ZERO MEANS KEY WAS PRESSED


ORG $0160 START OF EPROM CODE

START:
RSP SET THE STACK POINTER
LDA #$FF SET ALL BITS AS OUTPUT
STA DDRA PORT A = OOOO OOOO
STA DDRC PORT C = OOOO OOOO
LDA #$00 SET ALL BITS AS INPUT
STA DDRB PORT B = IIII IIII



*
* Initialize the OCMP system for interrupts, based on timer equates
* TICDLYL (lsb) and TICDLYH (msb).
*

OCMPINIT:
LDA OCMP+1 GET CURRENT TIMER VALUE
ADD #TICDLYL CALC VALUE FOR TIMER DELAY
TAX SAVE FOR LATER
LDA OCMP NOW GET HIGH TIMER BYTE
ADC #TICDLYH CALC NEW VALUE
STA OCMP UPDATE THE TIMER
LDA TSR CLEAR THE OCF BIT
STX OCMP+1 UPDATE BOTH BYTES
LDA #%01000000 ENABLE INTERRUPT FROM OCMP
STA TCR START IT UP
CLR WAIT$ SHOW NO WAITING

LDA #%00110000 9600 BAUD
STA BAUD
LDA #%00000000 1 START, 8 DATA, 1 STOP
STA SCCR1
LDA #%00101100 RCV INTR ENABLE, XMIT & RCVR ON
STA SCCR2

CLRA
STA INPTR CLEAR THE QUEUE
STA OUTPTR BOTH POINTERS
STA KEY SHOW NO KEY PRESSED YET

CLI TURN ON THE INTERRUPTS

JSR LCDINIT INITIALIZE THE LCD

LDA #$D6 GET OPCODE: LDA $FFFF,X
STA LDAIND WRITE TO RAM
LDA #$81 GET OPCODE: RTS
STA LDAIND+3 WRITE TO RAM

CLRX SET UP A POINTER
LDA #$20 GET A BLANK
INIT1:
STA LINE1,X CLEAR A LINE
STA LINE2,X CLEAR SECOND LINE
INCX COUNT THIS COL
CPX #LLEN DONE THE WHOLE LINE?
BLO INIT1 BRANCH IF NOT
CLRA NOW GET A NULL
STA LINE1,X MARK THE END
STA LINE2,X OF BOTH LINES

JSR HELLO WRITE INITIAL MESSAGE
LDA #$C0 SET ADDR TO LINE 2, COL 0
JSR LCDCMD SEND IT

CLR CCOL SHOW AT START OF LINE

INIT0:
LDX OUTPTR POINT TO NEXT CHAR
CPX INPTR ANYTHING IN QUEUE?
BEQ INIT2 BRANCH IF NOT
LDA SERQ,X GET THE CHAR
INCX BUMP THE POINTER
CPX #SERSIZE REACHED THE END?
BLO INIT1A BRANCH IF NOT
CLRX YES, REST THE POINTER
INIT1A:
STX OUTPTR SAVE THE NEW POINTER
CMP #$0D WAS CHAR CR?
BNE INIT1B BRANCH IF NOT
JSR SCROLL SCROLL AND UPDATE
BRA INIT2 DONE WITH THIS CHAR

INIT1B:
CMP #$0A WAS IT LF?
BEQ INIT2 BRANCH IF YES
CMP #$08 WAS IT BACKSPACE?
BNE INIT1C BRANCH IF NOT
LDX CCOL GET THE COLUMN COUNTER
BEQ INIT2 IGNORE IF AT START OF LINE
DECX BACKUP ONE
STX CCOL SAVE THE NEW POSITION
LDA #$10 SHIFT CURSOR LEFT
JSR LCDCMD SEND TO DISPLAY
BRA INIT2

INIT1C:
LDX CCOL GET THE CURRENT COLUMN
STA LINE2,X SAVE IN LINE BUFFER
JSR LCDCHAR NOW WRITE TO DISPLAY
INCX COUNT THIS COLUMN
CMPX #LLEN REACHED THE END?
BLO INIT1D BRANCH IF STILL OK
DECX TOO FAR, BACKUP
LDA #$10 MOVE CURSOR LEFT
JSR LCDCMD SEND TO DISPLAY
INIT1D:
STX CCOL SAVE THE NEW COLUMN COUNTER

INIT2:
BRCLR 7,PORTB,INIT3 BRANCH IF NO KEY PRESSED
TST KEY WAS THE KEY PRESSED LAST TIME?
BNE INIT3 YES, IGNORE THE KEY
LDA PORTB GET THE KEY
AND #%01111111 REMOVE THE STROBE BIT
STA KEY SAVE TO SHOW KEYPRESS
JSR PUTCH SEND TO SERIAL LINE

INIT3:
BRSET 7,PORTB,INIT4 BRANCH IF KEY IS PRESSED
CLR KEY SHOW THE KEY WAS RELEASED

INIT4:
JMP INIT0 BACK TO THE TOP






*
* SCROLL -- move the LINE2 text to the LINE1 buffer, clear the LINE2
* buffer, then update the display.
*

SCROLL:
CLRX ZERO THE POINTER
SCROLL1:
LDA LINE2,X MOVE A CHAR FROM LINE2
STA LINE1,X TO LINE1
LDA #$20 GET A BLANK
STA LINE2,X AND CLEAR THAT POSITION IN LINE2
INCX MOVE TO NEXT CHAR
CPX #LLEN DONE THE WHOLE LINE?
BLO SCROLL1 BRANCH IF NOT

*
* UPDATE -- refresh the display with the data held in buffers LINE1 and
* LINE2.
*

UPDATE:
LDA #$80 MOVE CURSOR TO LINE 1, COL 0
JSR LCDCMD
LDA #LINE1/256 GET MSB OF BUFFER ADDR
STA LDAIND+1 SAVE INTO ROUTINE
LDA #LINE1%256 GET LSB OF BUFFER ADDR
STA LDAIND+2 SAVE IT TOO
JSR LCDSTRING WRITE THE BUFFER
LDA #$C0 NOW MOVE TO LINE 2, COL 0
JSR LCDCMD
LDA #LINE2/256 GET MSB OF BUFFER ADDR
STA LDAIND+1 SAVE INTO ROUTINE
LDA #LINE2%256 GET LSB OF BUFFER ADDR
STA LDAIND+2 SAVE IT TOO
JSR LCDSTRING WRITE THE BUFFER
LDA #$C0 NOW MOVE TO LINE 2, COL 0
JSR LCDCMD
CLR CCOL SHOW CURRENT COLUMN IS 0
RTS



*
* HELLO -- print the first message to the display
*

HELLO:
LDA #HELLO$/256 GET ADDR OF TEXT (MSB)
STA LDAIND+1
LDA #HELLO$%256 GET ADDR OF TEXT (LSB)
STA LDAIND+2
JSR LCDSTRING SEND STRING TO DISPLAY
RTS



*
* PUTCH -- output char in AR to the SCI port
*

PUTCH:
BRCLR 7,SCSR,PUTCH WAIT FOR THE XMITR TO EMPTY
STA SCDR SEND THE CHAR
RTS



*
* LCD library
*
* These routines control a Hitachi-type LCD, connected with a 4-bit
* interface to a single 8-bit port on the 68HC705. The main routine
* must contain equates defining this connection:
*
* LCDPORT must contain the address of the '705 port.
* LCD.E must contain the bit connected to the display's E line.
* LCD.RS must contain the bit connected to the display's RS line.
*
* These routines assume that the low nybble of the LCDPORT is connected
* to the highest four data lines of the LCD.
*
* The main routine must also allocate RAM storage for these modules:
*
* LCDTMP RMB 1
* LCDTMP1 RMB 1
* LCDOUTA RMB 1
*
* The main routine must also use the RAM variable WAIT$ to indicate
* when it is safe to write to the display. These routines will not
* write to the display unless WAIT$ holds a 0; they will loop endlessly
* until WAIT$ is cleared.
*
* The logic in LCDCMD and LCDCHAR, that writes directly to the display,
* automatically selects the appropiate delay value for use with WAIT$.
* These values presume that WAIT$ decrements once each 200 usec. If
* you use a different time constant for decrementing WAIT$, adjust
* these routines accordingly.
*


*
* LCDINIT -- Initialize the LCD
*
* This routine configures the LCD for 4-bit interface, cleared display,
* two lines, 5x10 character font. Upon exit, the LCD RS line is low
* (command register selected).
*
* The initialization sequence given here was taken from the Hitachi
* manual. That manual recommends specific time delays between the
* first three commands that differ from the delays normally associated
* with those commands. Since LCDOUT is used to send these commands,
* this routine explicitly sets WAIT$ to the recommended values following
* each call to LCDOUT. The values used assume a 200 usec delay for
* each decrement of WAIT$.
*

LCDINIT:
LDA #0 DATA = XXXX, RS = 0, E = 0
STA LCDPORT SEND TO LCD

LDA #75 GET A 15 MS DELAY
STA WAIT$

LDA #$03 8-BIT INTERFACE
JSR LCDOUT SEND TO DISPLAY
LDA #22 GET A 4.2 MS DELAY
STA WAIT$

LDA #$03 SEND 8-BIT COMMAND AGAIN
JSR LCDOUT
LDA #1 GET A 120 US DELAY
STA WAIT$

LDA #$03 SEND 8-BIT COMMAND ONE LAST TIME
JSR LCDOUT
LDA #25 GET A 5 MS DELAY
STA WAIT$

LDA #$02 SET UP 4-BIT INTERFACE
JSR LCDOUT
LDA #25 GET A 5 MS DELAY
STA WAIT$


LDA #%00101100 2 LINES, 5X10 FONT, 4-BIT INTERFACE
JSR LCDCMD

LDA #%00001000 DISPLAY OFF, NO CURSOR, NO BLINK
JSR LCDCMD

LDA #%00000001 CLEAR DISPLAY, CURSOR TO ADDR 0
JSR LCDCMD

LDA #%00000110 INCREMENT CURSOR, NO DISPLAY SHIFT
JSR LCDCMD

LDA #%00001111 DISPLAY ACTIVE, CURSOR ACTIVE & BLINKS
JSR LCDCMD

RTS



*
* LCDOUT -- Send a nybble to the LCD
*
* This routine sends the data in AR to the display. The LCD's RS
* line must already be at the proper value. Upon exit, the AR is
* clobbered and the LCD's E line is low.
*

LCDOUT:
TST WAIT$ WAIT UNTIL OK TO PROCEED
BNE LCDOUT

BCLR LCD.E,LCDPORT DROP THE E LINE
AND #$0F LEAVE ONLY LOW NYBBLE
STA LCDOUTA SAVE IT
LDA LCDPORT GET CURRENT PORT VALUE
AND #$F0 LEAVE TOP NYBBLE AS IS
ORA LCDOUTA OR IN THE LOW NYBBLE
STA LCDPORT WRITE DATA TO PORT
BSET LCD.E,LCDPORT RAISE THE E LINE
NOP WAIT JUST A BIT
NOP
BCLR LCD.E,LCDPORT DROP THE E LINE AGAIN
RTS


*
* LCDCHAR -- send a character to the display
*
* Send the character, in AR upon entry, to the display. This
* routine sets the LCD's RS line high and leaves it that way
* upon exit. The AR is preserved.
*

LCDCHAR:
TST WAIT$ WAIT UNTIL OK TO PROCEED
BNE LCDCHAR

BSET LCD.RS,LCDPORT SET RS = 1
STA LCDTMP SAVE THE CHAR
LDA #1 GET A 120 US DELAY
LCDCHAR1:
STA LCDTMP1 SAVE THE WAIT VALUE
LDA LCDTMP RELOAD THE CHARACTER
RORA SHIFT TO HIGH NYBBLE
RORA
RORA
RORA
JSR LCDOUT SEND TO DISPLAY
LDA LCDTMP RELOAD THE CHARACTER
JSR LCDOUT SEND LOW NYBBLE TO DISPLAY
LDA LCDTMP1 NOW GET THE DELAY COUNT
STA WAIT$ AND SET UP WAIT$
LDA LCDTMP RESTORE THE AR
RTS


*
* LCDCMD -- send a display command to the LCD
*
* This routine sends a display command, in AR upon entry, to the
* LCD. Upon exit, the RS line is low and the AR is preserved.
*
* This routine jumps into the LCDCHAR routine to use common code.
* Note that when the jump is made, the AR holds the proper delay value
* to be stored in WAIT$ and the original value in the AR has been
* saved in LCDTMP.
*

LCDCMD:
TST WAIT$ WAIT UNTIL OK TO PROCEED
BNE LCDCMD

BCLR LCD.RS,LCDPORT SET RS = 0
STA LCDTMP SAVE THE COMMAND FOR NOW
CMP #$03 SEE WHAT KIND OF DELAY WE NEED
BHI LCDCMD1 BRANCH IF NEED SHORT DELAY
LDA #25 GET A 5 MS DELAY
BRA LCDCMD2
LCDCMD1:
LDA #1 GET A 120 US DELAY
LCDCMD2:
BRA LCDCHAR1 GO USE COMMON CODE


*
* LCDSTRING -- write a string to the display
*
* This routine writes a null-terminated string to the display. Upon
* entry, the main routine must have set up the LDAIND subroutine in
* low RAM:
*
* LDAIND:
* FCB $D6 LDA (IX2)
* RMB 1 MSB OF STRING ADDR
* RMB 1 LSB OF STRING ADDR
* FCB $81 RTS
*
* The calling routine must have positioned the cursor as desired.
*
* Upon exit, the AR and XR are destroyed. Note that no check is made
* as to string length, CR, LF or tabs.
*

LCDSTRING:
CLRX START AT BEGINNING
LCDSTR1:
JSR LDAIND GET A CHAR
BEQ LCDSTRX BRANCH IF DONE
JSR LCDCHAR SEND TO DISPLAY
INCX POINT TO NEXT CHAR
BRA LCDSTR1 LOOP UNTIL DONE
LCDSTRX:
RTS



*
* SCISV -- SCI server
*
* This routine moves the character from the SCI receive register
* into the queue of characters at SERQ. The variable INPTR serves
* as the pointer into the queue.
*

SCISV:
BRCLR 5,SCSR,SCISV CHECK THE STATUS REGISTER
LDX INPTR GET THE INPUT POINTER
LDA SCDR GET THE CHAR
STA SERQ,X PUT INTO THE QUEUE
INCX POINT TO NEXT ENTRY
CPX #SERSIZE REACHED THE END?
BLO SCISV1 BRANCH IF NOT
CLRX YES, RESET TO ZERO
SCISV1:
STX INPTR SAVE NEW POINTER
RTI





*
* OCMPSV -- OCMP server
*
* This routine updates the OCMP timer system. The address OCMPSV
* must be written into address $1FF8 so the interrupt system can pass
* control here on a output compare. The delay value used for the
* next timer interval will be taken from equates TICDLYL (lsb) and
* TICDLYH (msb).
*
* This routine also toggles the output level bit, which appears on
* the MCU chip as pin 35 (TCMP).
*
* This routine also decrements the WAIT$ variable, if it is not already
* at zero.
*

OCMPSV:
LDA OCMP+1 GET CURRENT TIMER VALUE
ADD #TICDLYL CALC VALUE FOR TIMER DELAY
TAX SAVE FOR A MOMENT
LDA OCMP NOW GET HIGH BYTE OF CURRENT TIMER
ADC #TICDLYH CALC HIGH BYTE
STA OCMP WRITE TO TIMER SYSTEM
LDA TSR CLEAR THE OCF BIT
STX OCMP+1 DO BOTH BYTES
LDA TCR GET THE TIMER CONTROL REG
EOR #%00000001 TOGGLE THE OUTPUT LEVEL BIT
STA TCR AND WRITE BACK
LDA WAIT$ GET THE WAIT FLAG
BEQ OCMPSVX BRANCH IF NOT COUNTING
DECA COUNT THIS TIC
STA WAIT$ AND PUT COUNT BACK
OCMPSVX:
RTI ALL DONE



*
* Text
*

HELLO$:
FCC 'Working...'
FCB 0



ORG $1FF6 ADDR OF SCI VECTOR
FDB SCISV POINT TO SCI SERVER

ORG $1FF8 ADDR OF TIMER INTERRUPT
FDB OCMPSV POINT TO OCMP SERVER

ORG $1FFE ADDR OF RESET VECTOR
FDB START POINT TO PROGRAM START LOC


  3 Responses to “Category : Files from Magazines
Archive   : ISSUE-53.ZIP
Filename : RS232.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/