;/**********************************************************************************/ ;/ NTSC/PAL Video Display (40/80 character x 25 line monochrome text/graphics) / ;/ / ;/ Original 40x25 text designed and written by Daryl Rictor (c)2003-2004 / ;/ / ;/ Modified by Grant Searle 2007-2013 / ;/ - 80x25 or 40x25 display / ;/ - Handshaking/data transfer rewritten / ;/ - 8bit and 4bit and I2C interface (with help from Dave Curran) / ;/**********************************************************************************/ ; include program specific definitions and macros .include "defs.inc" ;--------------------------------------------------------------------------------------------------------------------------- ; Standard ATmega328 jump vectors jmp RESET ; Reset Handler jmp EXT_INT0 ; IRQ0 Handler jmp EXT_INT1 ; IRQ1 Handler jmp PC_INT0 ; PCINT0 Handler jmp PC_INT1 ; PCINT1 Handler jmp PC_INT2 ; PCINT2 Handler jmp WDT ; Watchdog Timer Handler jmp TIM2_COMPA ; Timer2 Compare A Handler jmp TIM2_COMPB ; Timer2 Compare B Handler jmp TIM2_OVF ; Timer2 Overflow Handler jmp TIM1_CAPT ; Timer1 Capture Handler jmp TIM1_COMPA ; Timer1 Compare A Handler jmp TIM1_COMPB ; Timer1 Compare B Handler jmp TIM1_OVF ; Timer1 Overflow Handler jmp TIM0_COMPA ; Timer0 Compare A Handler jmp TIM0_COMPB ; Timer0 Compare B Handler jmp TIM0_OVF ; Timer0 Overflow Handler jmp SPI_STC ; SPI Transfer Complete Handler jmp USART_RXC ; USART, RX Complete Handler jmp USART_UDRE ; USART, UDR Empty Handler jmp USART_TXC ; USART, TX Complete Handler jmp ADCC ; ADC Conversion Complete Handler jmp EE_RDY ; EEPROM Ready Handler jmp ANA_COMP ; Analog Comparator Handler jmp TWI ; 2-wire Serial Interface Handler jmp SPM_RDY ; Store Program Memory Ready Handler ;--------------------------------------------------------------------------------------------------------------------------- ; unused vectors point to software reset code EXT_INT0: EXT_INT1: PC_INT0: PC_INT1: PC_INT2: WDT: TIM2_COMPA: TIM2_COMPB: TIM2_OVF: TIM1_CAPT: ;TIM1_COMPA: //used elsewhere TIM1_COMPB: TIM1_OVF: TIM0_COMPA: TIM0_COMPB: TIM0_OVF: SPI_STC: USART_RXC: USART_UDRE: USART_TXC: ADCC: EE_RDY: ANA_COMP: TWI: SPM_RDY: ;--------------------------------------------------------------------------------------------------------------------------- ; Program start RESET: CLI ; disable interupts ; Initialize the I/O Ports LDI J, 0xFF out PORTB, J ; enable pullups out PORTC, J ; enable pullups out PORTD, J ; enable pullups LDI J, 0x00 ; pins 0 - 7 of port D out DDRD, J ; set PORTD pins to inputs TEMPORARILY to read config bits LDI J, 0x01 ; pin 1 of port B is output (sync) out DDRB, J ; Initialize Timer 1 ; OCR1A will hold the value of 1016/1024 and be used to reset the counter and ; cause an IRQ that will start the HSYNC process ; The counter will count each clock cycle (16MHz - no prescaling) ldi J, 0x00 sts TCCR1A, J ldi J, 0x09 ; set timer 1 to CTC mode 4 sts TCCR1B, J ldi J, 0x02 ; allow OCR1A IRQ's sts TIMSK1, J ; Initialise other registers ldi J,0x00 sts UCSR0B,J ; Turn off serial ldi J, 0x80 out ACSR, J ; turn off comparator ldi J, 0x08 ; set stack pointer to top of SRAM out SPH, J ; ldi J, 0xFF ; out SPL, J ; ; Initialise Program Variables ldi chrln, 0x00 ; keeps track of font gen line (0-7) ldi vlineh, 0x00 ; vertical line counter 0-262 ldi vline, 0x00 ; " ldi YL, 0x00 ; ldi YH, 0x01 ; init y pointer ldi column, 0x00 ; keeps track of horizontal chr pos (0-79) ldi row, 0x00 ; keeps track of vertical chr pos (0-24) ldi cursorClk, 0x00 ; init cursor blink timer ld charUnderCursor, Y ; init cursor character ldi cursorChar, 0x5F ; init cursor '_' character ldi J, 0xFF mov previousInpt, J ldi J, 0x00 mov cmdVal, J ;--------------------------------------------------------------------------------------------------------------------------- ; Set configuration from PORTD in configByte,PIND ; Read configuration bits (PORTD pins) ; Configuration now read, so set PORTD pins to outputs ldi J, 0x00 ; out PORTD, J ; set port D outputs to 0 LDI J, 0xFF ; pins 0 - 7 of port B out DDRD, J ; set PORTD pins to outputs ; HARD CODED OVERRIDE IF PREFERRED ; ldi J, 1<25, show Cursor mov inpt,charUnderCursor call setYfromRowCol call putCharAtY rjmp endOfCursor solidCursor: mov inpt,cursorChar call setYfromRowCol call putCharAtY rjmp endOfCursor blinkCursor: mov inpt,cursorChar call setYfromRowCol call putCharAtY cpi cursorClk, 0x37 ; is clock >56 brmi endOfCursor ; no clr cursorClk ; reset timer endOfCursor: sbrs configByte,CONFIG_N_TWI ; low = TWI rjmp twiMode ; Yes, set TWI mode eightOrFourBit: ; If the ack and data rdy are the same state then there is no ; data waiting in J,PORTC andi J,0x10 in K,PINC andi K,0x20 lsr K eor J,K breq Main ; Data ready, so check if 4bit or 8bit data transfer is being used sbrs configByte,CONFIG_8_OR_4_BIT rjmp fourBit ; Low = 4 bit eightBit: ; 8 bit Input is split between portB and portC ; so read both, shift then OR together to form the 8 bit data in J,PINB andi J,0x3E lsr J in inpt,PINC andi inpt,0x07 lsl inpt lsl inpt lsl inpt lsl inpt lsl inpt or inpt,J ; Data read, so flip the ack bit in K,PORTC ldi J,0x10 eor K,J out PORTC,K rcall processChar ; process the host data rjmp Main ; repeat fourBit: ; 4 bit Input is on portB only sbis PINC,availpin rjmp Nibble2 ; Process lower 4 bits if clear nibble1: in inpt,PINB andi inpt,0x1E lsl inpt ; Move to upper 4 bits lsl inpt lsl inpt mov nibbleTemp,inpt ; Data read, so flip the ack bit in K,PORTC ldi J,0x10 eor K,J out PORTC,K rjmp Main ; repeat nibble2: in J,PINB andi J,0x1E lsr J ; Move to lower 4 bits or nibbleTemp,J ; Combine it with the first 4 bits mov inpt,nibbleTemp ; Data read, so flip the ack bit in K,PORTC ldi J,0x10 eor K,J out PORTC,K rcall processChar ; process the host data rjmp main ; repeat twiMode: lds J, TWCR ; check the twi status register sbrs J, TWINT ; is the twint bit set? rjmp main ; no, back to main loop lds J, TWSR ; Check status register andi J, 0xF8 ; Ignore bits 0..2 (prescaler and reserved bit) ; cpi J, 0xA0 ; Stop - ignore ; breq toMain ; no new data cpi J, TW_SR_DATA_ACK ; 0x80 - address already received received, ACK had been returned brne noTWIdata ; no new data lds inpt, TWDR ; Store the received data ldi J, (1<