apple1/Controllers drivers/Hi-Res Video Driver Source/video processor source and hex/SBCVideo.asm

375 lines
11 KiB
NASM

;/**********************************************************************************/
;/ 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<<CONFIG_PAL | 0<<CONFIG_8_OR_4_BIT | 1<<CONFIG_N_TWI | 1<<CONFIG_80_CHAR_PER_LINE | 1<<CONFIG_SINGLE_HEIGHT | 0<<CONFIG_BOLD
; mov configByte,J
;---------------------------------------------------------------------------------------------------------------------------
; Set default font
ldi J, 0x00
sbrc configByte,CONFIG_80_CHAR_PER_LINE ; 80 if high
ori J, 1<<ATT_80_CHAR_PER_LINE
sbrc configByte,CONFIG_BOLD ; Bold if high
ori J, 1<<ATT_BOLD
sbrs configByte,CONFIG_SINGLE_HEIGHT ; Double if low
ori J, 1<<ATT_DBL_HEIGHT
mov activeLineAtt, J
;---------------------------------------------------------------------------------------------------------------------------
; Select PAL/NTSC System
sbrs configByte, CONFIG_PAL ; low = NTSC
rjmp setNTSC ; Yes, set NTSC mode
setPAL:
ldi J, 0x38 ; 0x0138 Last vertical line 312
mov lastline, J ;
ldi J, 0x40 ; first vertical line of active disp
mov line1, J ;
ldi J, 0x04 ; 0x0400 = 1024 clocks per line
sts OCR1AH, J
ldi J, 0x00 ; 0x0400 = 1024 clocks per line
sts OCR1AL, J ; set Counter 1 to cycle from 0 to 1024 and IRQ
rjmp palOrNtscSet ;
setNTSC: ; no, set NTSC mode
ldi J, 0x06 ; 0x0106 Last vertical line 262
mov lastline, J ;
ldi J, 0x28 ; first vertical line of active disp
mov line1, J ;
ldi J, 0x03 ; 0x03f8 = 1016 clocks per line (63.5us)
sts OCR1AH, J
ldi J, 0xf8 ; 0x03f8 = 1016 clocks per line (63.5us)
sts OCR1AL, J ; set Counter 1 to cycle from 0 to 1016 and IRQ
palOrNtscSet:
;---------------------------------------------------------------------------------------------------------------------------
; Initialise TWI if used otherwise setup ack/avail pins
sbrs configByte,CONFIG_N_TWI ; low = TWI
rjmp twoWireSelected ; Yes, set TWI mode otherwise setup ack/avail pins
twoWireNotUsed:
LDI J, 0x18 ; pins 3,4 of port C are outputs
out DDRC, J
rjmp twiSet
twoWireSelected:
LDI J, 0x08 ; only pin 3 of port C is an output
out DDRC, J
ldi J, 0x02 ; Set address to 0x01, format aaaaaaag (a=address, g=general call enable)
sts TWAR, J ;
ldi J, (1<<TWEA)|(1<<TWEN)
sts TWCR, J ; Enable TWI and allow ACK when slave is addressed.
twiSet:
;---------------------------------------------------------------------------------------------------------------------------
; Reset Timer 1 and clear Busy Status Flag
ldi J, 0x00 ; clear timer 1
sts TCNT1H, J ;
sts TCNT1L, J ;
ldi J, 0x1C ; clear timer 1 IRQ's
out TIFR1, J ; clear timer 1 IRQ's
; Set the default attributes for each line (Screen 0100-08CF (2000 bytes), Attributes for each line 08D0-08E9 (25 bytes) )
ldi ZL, 0xD0
ldi ZH, 0x08 ; set to start of attribute SRAM
ldi YL, 0x19
ldi YH, 0x00 ; set Y to 25 (19 HEX)
loop1:
st Z+, activeLineAtt ; save to attribute SRAM
sbiw YL, 0x01 ; dec Y
brne loop1
ldi inpt,0x0C ; CLS
rcall processChar
SEI ; Initialisation complete. Enable IRQ's
;---------------------------------------------------------------------------------------------------------------------------
; Main Loop
main:
cpi cursorChar, 0x00 ; is the cursor turned on?
breq endOfCursor ; no, skip cursor code
cpi cursorClk, 0xff ; is clk at 0xFF?
breq solidCursor ; yes - solid cursor (no blink)
cpi cursorClk, 0x1C ; is it above 28 frames?
brpl blinkCursor ; if >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<<TWINT)|(1<<TWEA)|(1<<TWEN) ; clear the TWINT flag immediately to allow two wire transmission to resume
sts TWCR,J
rcall processChar ; process the host data
rjmp main ; back to main loop
noTWIdata:
ldi J, (1<<TWINT)|(1<<TWEA)|(1<<TWEN) ; clear the TWINT flag (logic 1)
sts TWCR,J
toMain:
rjmp main ; back to main loop
;---------------------------------------------------------------------------------------------------------------------------
; IRQ Service routine for the video line generation
TIM1_COMPA: ; IRQ service for OCR1A
.include "vidgen.inc" ; file that holds the video generation code
reti ; done
;---------------------------------------------------------------------------------------------------------------------------
; include subroutines and fonts
.include "ProcChr.inc"
.include "CGANormalFont.inc"
.include "CGANormalFontWide.inc"
.include "CGABoldfont.inc"
.include "CGABoldFontWide.inc"
.include "BlockFont.inc"