* lcd.asm * RT Praktikum FH-Augsburg (Bayer, Hoegl) * Steve Moser, Marcus Stegner * Write text to 16x2 LCD display. * $Id: lcd.asm,v 1.1 2002/10/14 12:34:30 dosuser Exp dosuser $ * Addressmap RAM EQU $0 ;RAM section STACK EQU RAM+$800 ;Stack section PGM EQU RAM+$C00 ;Program start ROM EQU $800000 ;ROM section STACKSZ EQU 1024 ;Max stack size * Definitions * * 68332 global register definitions * * SIM SIMCR EQU $FFFA00 ;SIM Configuration Register SYPCR EQU $FFFA20 ;System Protection Register CSBARBT EQU $FFFA48 ;Chip Select Base Address Boot Register CSBAR0 EQU $FFFA4C ;Chip Select Base Address Register 0 CSBAR5 EQU $FFFA60 ;LCD connected to CS5 CSOR5 EQU $FFFA62 CSPAR0 EQU $FFFA44 ;Chip Select Pin Assignment *PORT E PEPAR EQU $FFFA16 ;Pin Assignment Register DDRE EQU $FFFA14 ;Data Direction Register PORTE EQU $FFFA12 ;Port E is decoded on 2 *PORT F PFPAR EQU $FFFA1E ;Pin Assignment Register DDRF EQU $FFFA1C ;Data Direction Register PORTF EQU $FFFA1A ;Port F is decoded on 2 *LCD LCD_IR EQU $200000 ;LCD Instruction Register LCD_DR EQU $200001 ;LCD Data Register * Place FEPROM at $800000, because unused org CSBARBT ;set on CSBARBT dc.w $8003 ;at 8M, size 64KB * Place ext. RAM at $0, 256KB, 0WS org CSBAR0 ;Set on SIM CSs dc.w $0005 ;CSBAR0, ext. RAM_RD dc.w $6830 ;CSOR0 dc.w $0005 ;CSBAR1, ext. RAM_WR_LO dc.w $3030 ;CSOR1 dc.w $0005 ;CSBAR2, ext. RAM_WR_HI dc.w $5030 ;CSOR2 * Initialize SIM and system protection * Switch off watchdogs, also while FREEZE is active org SIMCR dc.w $60CF ;FREEZE settings org SYPCR dc.w $0000 ;no system protection * Define Stack org STACK ;Stack from STACK to STACK + STACKSZ sseg ds.b STACKSZ cseg org PGM ;Programcode at $C00 * Initialize stack pointer move.l #sseg+STACKSZ,a7 ;load stack pointer * Initial Program Counter is initialized by the corresponding * DO-File * Initialize Port E move.w #$0000,PEPAR ;I/O instead of systembus move.w #$000F,DDRE ;4 bit as output * Initialize Port F move.w #$0000,PFPAR ;I/O instead of systembus move.w #$0000,DDRF ;all 8 bit as input * Init LCD Chipselect or.w #$2000,CSPAR0 ;CS5 Enable move.w #$2000,CSBAR5 ;Basisadresse LCD, 2K Block move.w #$7D30,CSOR5 ;CS Options main bsr main_own forever bra forever * Initialize the LCD display lcd_init move.b #$38,LCD_IR ; DL=1 (8-Bit), N=1, F=0 bsr lcd_busy move.b #$0f,LCD_IR ; 1 D C B (Display, Cursor, Blink) bsr lcd_busy move.b #$01,LCD_IR ; Clear Display, Cursor Home bsr lcd_busy move.b #$06,LCD_IR ; 1 I/D S bsr lcd_busy rts * Write a data character to the LCD display lcd_char move.b d0,LCD_DR bsr lcd_busy rts * Wait until LCD display is ready for another read/write cycle lcd_busy btst #7,LCD_IR ; Bit 7 ist 1 falls LCD Busy bne.b lcd_busy ; Z-Bit ist invertiertes Bit-7 rts * Move cursor one position to the right cu_right move.b #$14,LCD_IR bsr lcd_busy rts *Output of a given String--------------------------------------- LCD_STRING lea STRING1,A0 go move.b (A0),d0 ;load content of A0 to D0 (Stringbegining) cmp.b #0,d0 ;compare if str end beq back ;if yes return bsr lcd_char ;else put to display add #1,A0 ;next char bra go ;goto begining of subroutine back rts *--------------------------------------------------------------- *Output of an integer------------------------------------------- LCD_INT lea INT,A0 move.l (A0),D0 move.l #0,d1 ;init d1 as counter testbit8 btst #15,D0 ;test bit 16, cause of word.lenght (int) bne ifminus ;if zero bit is invertet,(minus(F)) goto bra divoutput ;else ifminus move.l d0,d4 ;save d0 (integer) to D4 move.b #'-',D0 ;put a char to D0 bsr lcd_char ;put to display move.l d4,d0 ;move back integer to d0 neg.l D0 ,negate complete register divoutput divu.w #10,d0 ;divide d0 trought 10, modulo in d0 high move.l d0,d2 ;save in another register to modify lsr.l #8,d2 ; shifte 8 bit (16 not allowed) lsr.l #8,d2 add #'0',d2 ;add 30 to make a char move.b d2,-(a7) ;push to stack add #1,d1 ;add counter d1 one and.l #$0000FFFF,d0 ;delete d0 high (make high16bit zero) cmp.l #0,d0 ;if mod == 0, ready to go to displayoutput bne divoutput output_number move.b (a7)+,d0 ;pop stack to displayregister bsr lcd_char ;display char sub #1,d1 ;decrement counter cmp.l #0,d1 ;if zero go back to call routine bne output_number ;else branch once rts *---------------------------------------------------------------- INT_BLINK move.l #50,d5 ;d5 as counteregister bsr LCD_INT ;put integer to screen loop1 bsr SHUTDSP ;display off bsr wait ;wait bevor display on bsr SHOWDSP ;Display on bsr wait dbra d5,loop1 ;loop rts *---------------------------------------------------------------- STRING_BLINK move.l #10,d5 bsr LCD_STRING loop bsr SHUTDSP bsr wait bsr SHOWDSP bsr wait dbra d5,loop rts *---------------------------------------------------------------- CLRDSP move.b #$01,LCD_IR ; Clear Display, Cursor Home bsr lcd_busy rts *________________________________________________________________ *---------------------------------------------------------------- SHUTDSP move.b #$08,LCD_IR bsr lcd_busy rts *________________________________________________________________ *---------------------------------------------------------------- SHOWDSP move.b #$0C,LCD_IR bsr lcd_busy rts *________________________________________________________________ *proof pressed button and loop----------------------------------- PROOF_INPUT anfang MOVE.W PORTE,D4 AND.W #$00F0,D4 taste1 BTST #4,D4 bne taste2 bsr CLRDSP bsr LCD_STRING bra anfang taste2 BTST #5,D4 bne taste3 bsr CLRDSP bsr LCD_INT bra anfang taste3 BTST #6,D4 bne taste4 bsr CLRDSP bsr INT_BLINK bra anfang taste4 BTST #7,D4 bne anfang bsr CLRDSP bsr STRING_BLINK bra PROOF_INPUT rts *Own main main_own bsr lcd_init ;init display (clear, set cursor,...) bsr PROOF_INPUT rts * Wait loop wait move.W #$9000,D3 ;Zaehler aussen -->Testpunkt (SP,PC, D3) move.W #$FFFF,D2 ;Zaehler innen LOOP1 dbra D2,LOOP1 LOOP2 dbra D3,LOOP2 rts ;return -->Testpunkt (D2,D3) ever dc.b 'H','a','l','l','o','1', 0 STRING1 dc.b 'G','u','t','e','n',' ','T','a','g', 0 even INT dc.l -1234 end