;***************************************************************************
;*
VIDEODVM.ASM
;*
;* a
digital volt meter that displays data directly on your TV!
;*
---> composite video output showing giant digits
;*
---> comprehensive data display with current reading, max and min
;*
---> analog type bar-display, graduated from 0 to 100%, for quick checks
;*
---> selectable decimal point position
;*
---> 1200 baud, ASCII serial output is also provided
;*
;*
Copyright (c) 1997 by Alberto Ricci Bitti
;*
e-mail: a.riccibitti@ra.nettuno.it
;***************************************************************************
.DEVICE
AT90S1200
;***************************************************************************
;* a
few, very useful macros
;***************************************************************************
.LISTMAC
.MACROа ADDIааа
ааааа subi @0, -@1
.ENDMACRO
;skip
next instruction if not equal to zero
.MACRO
skipneаааааааааааааааааа
.SETааа _skipne = PC+2
ааааа brneааа
_skipne
.ENDMACRO
;skip
next instruction if carry set
.MACRO
skipcsаааааааааааааааааа
.SETааа _skipcs = PC+2
ааааа brcsааа
_skipcs
.ENDMACRO
;skip
next instruction if carry clear
.MACRO
skipcc
.SETааа _skipcc = PC+2
ааааа brccааа
_skipcc
.ENDMACRO
;skip
next instruction if equal to zero
.MACROа skipeq
.SETааа _skipeq = PC+2
ааааа breqааа
_skipeq
.ENDMACRO
;skip
next instruction if lower
.MACRO
skiploаааааааааааааааааа
.SETааа _skiplo = PC+2
ааааа brloааа
_skiplo
.ENDMACRO
;wait
two cycles but waste only one instruction
.MACROа doublenop
.SETааа _doublenop = PC+1
ааааа rjmpааа
_doublenop
.ENDMACRO
;***************************************************************************
;include
AT90S1200 registers definitions
.include
"1200def.inc"
;include
font definitions
;fonts
are stored in a EEPROM table, edit fonts.inc to modify it as you wish
.include
"fonts.inc"
;***************************************************************************
;*
VARIABLE ASSIGNEMENTS
;***************************************************************************
.CSEG
ааааа .defааа
SaveStatus =ааа r0ааааа ;status buffer during interrupts
ааааа .defааа
CharHeight =ааа r1ааааа ;character height (reload value)
ааааа .defааа
CurrHeight =ааа r2ааааа ;character height (running counter)
ааааа .defааа
PrintAB =аааааа r3ааааа ;print buffer for BCD charachters,
ааааа .defааа
PrintCD =аааааа r4ааааа ;the sequence is A B C D + measurement
unit
ааааа .defааа
PointPosition = r5ааааа ;decimal
point position
ааааа .defааа
BarLenghtHigh = r6ааааа ;lenght of
analog bar, high byte
ааааа .defааа
BarLenght =аааа r7аа ;lenght of analog bar, low byte
ааааа .defааа
AdcLow =ааааааа r8ааааа ;ADC result, low byte
ааааа .defааа
AdcHigh =аааааа r9ааааа ;ADC result, high byte
ааааа .defааа
AdcLowMax =аааа r10аааа ;max value memory
ааааа .defааа
AdcHighMax =ааа r11
ааааа .defааа
AdcLowMin =аааа r12аааа ;min value memory
ааааа .defааа
AdcHighMin =ааа r13
ааааа .defааа
TimeLow =аааааа r14аааа ;time counter
ааааа .defааа
TimeHigh =ааааа r15
ааааа
ааааа
ааааа .defааа
Position =ааааа r16аааа ;identifies wich of the four line position
аааааааааааааааааааааааааааа ;we are on (3=end
of line, 0=sync pulse) when
аааааааааааааааааааааааааааа ;an interrupt
occurs
аааааааааааааааааааааааааааа ;used by timer
interrupt routine
ааааа .defааа
Delay =аааааааа r17аааа ;used for delays - decremented each field
ааааа .defааа
RowsModFour =аа r18а ;raster rows counter, split in two for
ааааа .defааа
RowsDivFour =аа r19аааа ;convenience of use. Counts up to 312
ааааа ;common data space used under interrupt
ааааа .defааа
Arg1 =ааааааааа r20аааа ;Temp variable used by interrupt
ааааа .defааа
Arg2 =ааааааааа r21аааа ; "ааааа "ааааа "ааааааааа "
ааааа .defааа
Arg3 =ааааааааа r22аааа ; "ааааа "ааааа "ааааааааа "
ааааа .defааа
Arg4 =ааааааааа r23аааа ; "ааааа "ааааа "ааааааааа "
ааааа ;common data space used by main program
ааааа .defааа
Main1 =аааааааа r24аааа ;Temp variable used by main program
ааааа .defааа
Main2 =аааааааа r25аааа ; "ааааа "ааааа "аааааа "ааааа "
ааааа .defааа
Main3 =аааааааа r26аааа ; "ааааа "ааааа "аааааа "ааааа "
ааааа .defааа
Main4 =аааааааа r27аааа ; "ааааа "ааааа "аааааа "ааааа "
ааааа .defааа
MiscFlags =аааа r28аааа ;Assorted flags
ааааа ;flags bit definition
ааааа .equааа
SerialReqBit =а 1аааааа ;
;***************************************************************************
;*
Constants
;***************************************************************************
ааааа .equааа
DisplayRow =ааа 150/4аа ;counter value for display start
ааааа .equааа
StartRetrace = (312/4)-1;counter value at wich retrace starts
ааааа .equааа
StopRetrace = (312/4)аа ;maximum
counter value
ааааа .equааа
BAUDRATE =ааааа 13ааааа ;lines between bits: 15625/13=1200 baud
ааааа ;useful global constants
ааааа .equааа
ASCII_ZERO =ааа 48ааааа ;ascii value for '0'
ааааа .equааа
ASCII_RETURN =а 13ааааа ;ascii value for carriage return
;***************************************************************************
;* Port
Pin Assignements
;***************************************************************************
ааааа ;port D bit definitions (OUTPUTS)
ааааа .equааа
CSyncBit =ааааа 0аааааа ;set video output to composite sync
level when low
ааааа .equааа
VideoBit =ааааа 1аааааа ;set video level to white when high,
black when low
ааааа .equааа
SCLKBit =аааааа 2аааааа ;ADC serial clock output
ааааа .equааа
CSBit =аааааааа 3аааааа ;ADC chip select (active low)
ааааа .equааа
DINBit =ааааааа 4аааааа ;ADC serial data
ааааа .equааа
LedBit =ааааааа 5аааааа ;board led, 0 = ON
ааааа .equааа
RS232Bit =ааааа 6аааааа ;1200 baud TTL level serial data
ааааа ;port B bit definitions (INPUTS)
ааааа .equааа
DOUTBit =аааааа 0аааааа ;ADC serial data
ааааа .equааа
DPSel1Bit =аааа 1аааааа ;board jumpers: 1, 2 & 3, select
ааааа .equааа
DPSel2Bit =аааа 2аааааа ;decimal point position
ааааа .equааа
DPSel3Bit =аааа 3аааааа ;а
ааааа .equа ClearButton
=аа 4 ;Max
Min Clear pushbutton
;***************************************************************************
;*
VECTORS
;***************************************************************************
ааааа rjmpааа
RESETаааааааааа ;Reset Handle
ааааа rjmpааа
RESETаааааааааа ;Ext. interrupt
request 0
ааааа rjmpааа
TIMERаааааааааа ;Timer
;***************************************************************************
;*
;* MAIN
PROGRAM
;*
;***************************************************************************
;*
INITAILIZATION
;***************************************************************************
RESET:а
ааааааааааа cltаааа ;clear T bit flagаааааа ;VERY important:
аааааааааааааааааааааааааааааааааа ;clear T flag,
here used to
аааааааааааааааааааааааааааааааааа ;verify if we
were sleeping
ааааааааааа ldiаааа Arg1, 0b01111111ааааааа ;set port D bits to outputs
ааааааааааа outаааа DDRD, Arg1
ааааааааааа ldiаааа Arg1, 0b00000001ааааааа ;presetа
output state
ааааааааааа outаааа PortD, Arg1
ааааааааааа ldiаааа Arg1, 0b00000000ааааааа ;set port B to inputs
ааааааааааа outаааа DDRB, Arg1
ааааааааааа ldiаааа Arg1,а
0b11111111аааааа ;turn on pullups
on inputs
ааааааааааа outаааа PortB, Arg1
ааааааааааа ldiаааа Arg1, 1
ааааааааааа outаааа TCCR0, Arg1аааааааааааа ;dont'use timer prescalerаааааааааааа
ааааааааааа ldiаааа Arg1, 32
ааааааааааа outаааа MCUCR, Arg1аааааааааааа ;enable sleep idle mode
ааааааааааа ldiаааа Arg1, 2
ааааааааааа outаааа TIMSK, Arg1аааааааааааа ;enable timer interrupt
ааааааааааа ldiаааа Arg1, 10ааааааа ;preset
display variables
ааааааааааа movаааа CharHeight, Arg1
ааааааааааа movаааа CurrHeight, CharHeight
ааааааааааа ldiаааа Delay, 5
ааааааааааа ldiаа Arg1,
0x99ааааааа ;preset minimum to
"9999"
ааааааааааа movаа ADCLowMin,а Arg1
ааааааааааа movаа ADCHighMin,
Arg1
ааааааааааа clrаа ADCLowMaxаааааааа ;preset maximum to "0000"
ааааааааааа clrаа ADCHighMax
ааааааааааа clrаааа Arg1аааааааааааааааа ;and
clear interrupt variables
ааааааааааа clrаааа Arg2
ааааааааааа clrаааа Arg3
ааааааааааа clrаааа Arg4
ааааааааааа clrааа аMiscFlags
ааааааааааа
ааааааааааа seiаааааааааааааааааааа аааа ;at last, allow interrupts
ааааааааааа
;***************************************************************************
;* MAIN
LOOP
;***************************************************************************
FOREVER:ааааааааааааааа
ааааааааааа
j2:аааааааааааа cpiаааа Delay, 1
ааааааааааа brneааа j1
ааааааааааа cbiаааа PortD, LedBit
j1:ааааааааааааааа cpiаааа Delay, 0
ааааааааааа brneааа FOREVER
ааааааааааа ldiаааа Delay, 10
ааааааааааа sbiаааа PortD, LedBit
ааааааааааа incаааа TimeLow
ааааааааааа skipne
ааааааааааа incаааа TimeHigh
ааааааааааа ;*******************************
ааааааааааа ;* ADC CONVERSION
ааааааааааа ;*******************************
ааааааааааа ldiаааа Main1, 0ааааааааааааааа ;select ADC channel 0
ааааааааааа rcallаа READADCааааааааааааа ;ADC
conversion, return result in Main3-4
ааааааааааа ;*******************************
ааааааааааа ;* BAR DISPLAY
ааааааааааа ;*******************************
ааааааааааа movаааа BarLenght, Main3аааааа ;get binary data into
ааааааааааа movаааа BarLenghtHigh, Main4аа ;BarLenght storage area
ааааааааааа lsrаааа BarLenghtHighааааааааа ;and divide by 32 (shift 5
ааааааааааа rorаааа BarLenghtааааааааааааа ;times) to adapt to our
ааааааааааа lsrаааа BarLenghtHighааааааааа ;routine range (0-127)
ааааааааааа rorаааа BarLenght
ааааааааааа lsrаааа BarLenghtHigh
ааааааааааа rorаааа BarLenght
ааааааааааа lsrаааа BarLenghtHigh
ааааааааааа rorаааа BarLenght
ааааааааааа lsrаааа BarLenghtHigh
ааааааааааа rorаааа BarLenght
ааааааааааа ;*******************************
ааааааааааа ;* CONVERSION TO BCD
ааааааааааа ;*******************************
ааааааааааа movаааа Main1, Main3ааааааааааа ;set up parameters
ааааааааааа movаааа Main2, Main4
ааааааааааа rcallаа BIN_BCDаааааааааааааааа ;and go convert
ааааааааааа movаааа ADCLow, Main3аааааааааа ;store result
ааааааааааа movаааа ADCHigh, Main4
ааааааааааа ;*******************************
ааааааааааа ;* PEAK RECORDER
ааааааааааа ;*******************************
ааааааааааа cpааа ADCLowMax,
ADCLow ;if current ADC value
ааааааааааа cpcаа ADCHighMax,
ADCHigh
ааааааааааа brshа CHECK_MINаааааааа ;is greater than Max value
ааааааааааа mov а ADCLowMax,а ADCLowааааа ;then
Max = Current value
ааааааааааа mov а ADCHighMax,
ADCHighаааа ;
CHECK_MIN:
ааааааааааа cpааа ADCLowMin,
ADCLow ;if current ADC value
ааааааааааа cpcаа ADCHighMin,
ADCHigh
ааааааааааа brloа CHECK_CLEARаааааа ;is less than Max value
ааааааааааа mov а ADCLowMin,а ADCLowааааа ;then
Min = Current value
ааааааааааа mov а ADCHighMin,
ADCHighаааа ;
CHECK_CLEAR:
ааааааааааа sbicааа PinB, ClearButtonааа ;if Max-Min clear button pressed
ааааааааааа rjmp DONTCLEARаааааааа ;
ааааааааааа mov а ADCLowMax,а ADCLowааааа ;then
reset Max value
ааааааааааа mov а ADCHighMax,
ADCHighаааа ;
ааааааааааа mov а ADCLowMin,а ADCLowааааа ;and
Min value
ааааааааааа mov а ADCHighMin,
ADCHighаааа ;
DONTCLEAR:
ааааааааааа ;*******************************
ааааааааааа ;* SERIAL COMMUNICATIONS
ааааааааааа ;*******************************
ааааааааааа movаааа Main1, ADCHighааааааааа ;send data to serial interface
ааааааааааа swapааа Main1аааааааааааааааааа ;select first BCD digit
ааааааааааа andiаа аMain1, 0b00001111аааааа ;cut out unwanted bits
ааааааааааа ADDIааа Main1, ASCII_ZEROаааааа ;convert to ASCII
ааааааааааа rcallаа SENDSERIALааааааааааааа ;and send to serial
ааааааааааа movаааа Main1, ADCHighааааааааа ;do the same for the following 3
digits
ааааааааааа andiааа Main1, 0b00001111аааааа ;hundreds...
ааааааааааа ADDIааа Main1, ASCII_ZERO
ааааааааааа rcallаа SENDSERIAL
ааааааааааа movаааа Main1, ADCLowаааааааааа ;tens...
ааааааааааа swapааа Main1
ааааааааааа andiааа Main1, 0b00001111
ааааааааааа ADDIааа Main1, ASCII_ZERO
ааааааааааа rcallаа SENDSERIAL
ааааааааааа movаааа Main1, ADCLowаааааааааа ;and units
ааааааааааа andiааа Main1, 0b00001111
ааааааааааа ADDIааа Main1, ASCII_ZERO
ааааааааааа rcallаа SENDSERIAL
ааааааааааа ldiаааа Main1, ASCII_RETURNаааа ;add a carriage return (perfect
ааааааааааа rcallаа SENDSERIALааааааааааааа ;for QBasic programs...)
ааааааааааа rjmpааа FOREVERаааааааааааааааа ;loop forever
;****************************************************************************
;*
;* Timer Interrupt: occurs four times in each video line.
;*ааааа The
Position records which of four interrupt stages we are on.
;*ааааа At the
third stage, we go in sleep mode, in order to have constant
;*ааааа servicing
time for the fourth, crucial interrupt were we will output
;*ааааа the sync
waveform.
;*ааааа This is the
very heart of sync generation.
;*
;****************************************************************************
TIMER:
ааааа ;if we were
sleeping, then this is a synchronizing cycle: just return
ааааа brtcааа TIMER_NOSLEEPаа ;if T cleared, do timer routine
ааааа retiааааааааааааааааааа ;otherwise return (sync
sleep)
TIMER_NOSLEEP:ааа аааа
ааааа inааааа SaveStatus, SREG
ааааа ;if not at
line start,simply decrement position counter and return
ааааа ;otherwise do
the real thing...
ааааа decаааа Positionааааааааааааааа ;Position range from 2 down to
-1
ааааа breqааа WAITNEWLINEаааааааааааа ;if Position = 0 then wait
(sleeping) for new line
TIMER_EXIT:ааааааа
ааааа outаааа SREG, SaveStatusааааааа ;otherwise do nothing
ааааа reti
WAITNEWLINE:
ааааа
ааааа setаааааааааааааааааааааааааааа ;set T flag to
tell we are sleeping
ааааа seiаааааааааааааааааааааааааааа ;re-enable
interrupts, otherwise we sleep forever!
ааааа sleepаааааааааааааааааааааааааа ;wait sleeping the
next timer interrupt
ааааа nopаааааааааааааааааааааааааааа ;(during sleep we
have constant interrupt recovery time)
ааааа cliаааааааааааааааааааааааааааа ;disable further
interrupts
ааааа cltаааааааааааааааааааааааааааа ;clear T, used for
sleep flag
NEWLINE:ааааааааааааааааааааааааааааааа ;when awaken,
we will restart here
ааааа ldiаааа Position, 3аааааааааааа ;reset position index
ааааа inааааа Arg1, PortDаааааааааааа ;read previous CSync level
ааааа ldiаааа Arg2, 0b00000001ааааааа ;load mask for toggle csync bit
TOGGLESYNC:
ааааа eorаааа Arg1, Arg2ааааааааааааа ;toggle CSync output
ааааа outаааа PortD, Arg1аааааааааааа ;now we are in the horizontal sync
pulse
HOUSEKEEPING:ааааааа
ааааа ;once in
horizontal sync pulse space, we have
ааааа ;enough time
to do some housekeepying routines...
ааааа incаааа RowsModFourаааааааааааа ;increment row counters
ааааа cpiаааа RowsModFour, 4ааааааааа ;if RowsModFour == 4
ааааа brneааа _1аааааааааа
ааааа incаааа RowsDivFourаааааааааааа ;then increment RowsDivFour
_1:аааа andiааа RowsModFour, 0b00000011 ;clear anyway bit 2
CHECKLASTLINE:ааааааа
ааааа ;when at last
line, the sync pulse is stretched to half line
аааааа cpiаааа RowsDivFour, StopRetraceааааааа ;if at last line
аааааа brshа ааLASTLINEааааааааааа ;the sync pulse stops at half line
WAITSYNCEND:ааааааааааааааааааааааааааа ;else wait sync
pulse end
ааааа inааааа Arg1, TCNT0аааааааааааа ;note that now we are perfectly in
ааааа cpiаааа Arg1, 64ааааааааааааааа ;sync with timer.ааааааа 64 = 4 uS
ааааа brloааа WAITSYNCEND
ааааа ldiаааа Arg2, 0b00000001аааааааа ;prepare mask for csync toggle
VERTICALRETRACE:ааааааа
ааааа ldiаааа Arg1, StartRetrace
ааааа cpiаааа RowsModFour, 0ааааааааа ;if at start of vertical retrace
pulse
ааааа cpcаааа RowsDivFour, Arg1 аааааааааааааааааа
ааааа brneааа HSYNCENDааааааааааааааа ;then leave CSync low
ааааа ldiаааа Arg2, 0
HSYNCEND:ааааааа
ааааа inааааа Arg1, PortDаааааааааааа ;
ааааа eorаааа Arg1, Arg2ааааааааааааа ;toggle CSync output
ааааа outаааа PortD, Arg1аааааааааааа ;now we are in the color burst
space
ааааа rcallаа SERIALDRIVER
WAITVISIBLEPORTION:ааааааа
ааааа inааааа Arg1, TCNT0аааааааааааа ;wait for start of visible area
ааааа cpiаааа Arg1, 220аааааааааааааа ;decreasing this moves display
left
ааааа brloааа WAITVISIBLEPORTION
ааааа rjmpа BUILDSCREENаааааа ;go
to display building table
LASTLINE:
ааааа ;this is a
good time to make slow (1/50 sec.) housekeepings,
ааааа ;or to do
things that are made once every screen picture
ааааа clrаааа RowsDivFourаааааааааааа ;reset row counters
ааааа clrаааа RowsModFourаааааааааааа
ааааа tstаааа Delayаааааааааааааааааа ;if Delay <> 0
ааааа breqааа WAITHALFLINE
ааааа decаааа Delayаааааааааааааааааа ;then decrement it
WAITHALFLINE:
ааааа inааааа Arg1, TIFRааааааааааааа ;wait for two timer overflows
ааааа sbrsааа Arg1, TOV0ааааааааааааа ;(each overflow is a quarter
line)
ааааа rjmpааа WAITHALFLINE
ааааа ldiаааа Arg1, EXP2(TOV0)ааааааа ;reset timer overflow bit
ааааа outаааа TIFR, Arg1
SECONDQUARTER:
ааааа inааааа Arg1, TIFRааааааааааааа ;wait second overflow
ааааа sbrsааа Arg1, TOV0ааааааааааааа ;
ааааа rjmpааа SECONDQUARTER
ааааа ldiаааа Arg1, EXP2(TOV0)ааааааа ;reset timer overflow bit
ааааа outаааа TIFR, Arg1
ааааа ldiаааа Position, 1аааааааааааа ;and align position counter
ааааа sbiаааа PortD, CSyncBitаааааааа ;and end composite sync
ааааа rjmpааа TIMER_EXIT
;****************************************************************************
;* SCREEN MAKEUP JUMP STRUCTURE
;* This compare and jump table determines the appearence
of the display
;* at each step, the current line number is examinated to
decide
;* which display routine to use
;****************************************************************************
BUILDSCREEN:
ааааа ;it's time to
decide what to display, depending on current line
ааааа
ааааа cpiаааа RowsDivFour, 278/4аа ;from line 268 on, blank display
ааааа brloааа _A
ааааа rjmpааа VOIDLINE ааааааа
_A:аааа cpiаааа RowsDivFour, 254/4 ;at line 244, display minimum
ааааа brloааа _A2
ааааа ldiаааа Arg1, 3
ааааа movаааа CharHeight, Arg1
ааааа movаааа PrintCD, ADCLowMin
ааааа movаааа PrintAB, ADCHighMin
ааааа ldiаааа Arg1, 9
ааааа rjmpааа DISPLAYDIGITS
_A2:ааа cpiаааа RowsDivFour, 234/4
ааааа brloааа _A1
ааааа rjmpааа VOIDLINEааааааа
_A1:ааа cpiаааа RowsDivFour, 210/4 ;at line 220, display maximum
ааааа brloааа _B
ааааа ldiаааа Arg1, 3
ааааа movаааа CharHeight, Arg1
ааааа movаааа PrintCD, ADCLowMax
ааааа movаааа PrintAB, ADCHighMax
ааааа ldiаааа Arg1, 10
ааааа rjmpааа DISPLAYDIGITS
_B:аааа cpiаааа RowsDivFour, 182/4
ааааа brloааа _C
ааааа rjmpааа VOIDLINEааааааа
_C:аааа cpiаааа RowsDivFour, 178/4
ааааа brloааа _C2
ааааа ldiаааа Arg1, 26
ааааа nop
ааааа rjmpааа DISPLAY_FINERULER
_C2:аааа cpiаааа RowsDivFour, 174/4
ааааа brloааа _D
ааааа ldiаааа Arg1, 25
_C1:ааа rjmpааа DISPLAY_COARSERULER
_D:аааа cpiаааа RowsDivFour, 150/4
ааааа brloааа _E
ааааа ldiаааа Arg1, 24
ааааа rjmpааа DISPLAYBAR
_E:аааа cpiаааа RowsDivFour, 146/4
ааааа brloааа _F
ааааа ldiаааа Arg1, 23
ааааа rjmpааа DISPLAY_COARSERULER
_F:аааа cpiаааа RowsDivFour, 125/4
ааааа brloааа _G
ааааа rjmpааа VOIDLINE
_G:аааа cpiаааа RowsDivFour, 45/4
ааааа brloааа VOIDLINE
ааааа movаааа PrintCD, ADCLow
ааааа movаааа PrintAB, ADCHigh
ааааа ldiаааа Arg1, 10
ааааа movаааа CharHeight, Arg1
ааааа ldiаааа Arg1, 1
ааааа rjmp аааDISPLAYDIGITS
VOIDLINE:аааа
ааааа clrаааа Arg4ааааааааааа ;reset pixel mask
ааааа rjmpааа TIMER_EXIT
ааааааааааааааааааааааа аааа
;****************************************************************************
;* ON SCREEN DISPLAY ROUTINES
;****************************************************************************
DISPLAYDIGITS:
ааааа decаааа Arg1аааааааааааааа а ;delay
loop for alignment purpose
ааааа brneааа DISPLAYDIGITSааааааа ;this is the "print" routine
ааааа
ааааа tstаааа CurrHeightаааааааааа ;that
prints a ROW of pixels
ааааа breqааа _7ааааааааааааа ;according
to the buffer PrintAB-CD
ааааа nopаааааааааааааааааааа ;and the height specified
in CharHeight
ааааа rjmpааа _8
_7:аааа movаааа CurrHeight, CharHeight
ааааа lslаааа Arg4
_8:аааа skipne
ааааа incаааа Arg4
ааааа
ааааа ldiаааа Arg3, 0b00010000ааааа аааа ;set
decimal point position mask
ааааа sbisааа PinB, DPSel1Bitааааа ;if jumper 1 closed
ааааа lslаааа Arg3аааааааааааааааа ;shift
decimal point mask one place
ааааа sbisааа PinB, DPSel2Bitааааа ;if jumper 2 closed
ааааа lslаааа Arg3аааааааааааааааа ;shift
decimal point two places
ааааа sbisааа PinB, DPSel2Bit
ааааа lslаааа Arg3
ааааа sbisааа PinB, DPSel3Bitааааа ;if jumper 3 closed
ааааа lslаааа Arg3аааааааааааааааа ;shift
decimal point one place
ааааа movаааа PointPosition, Arg3а ;
ааааа
ааааа movаааа Arg3, PrintABааааааа ;load single charachters in Arg3
ааааа swapааа Arg3аааааааааааааааа ;and
call the display charachter
ааааа rcallаа DISPLAYCHARааааааааа ;routine:
character A
ааааа movаааа Arg3, PrintABааааааа ;then
charachter B
ааааа rcallаа DISPLAYCHAR
ааааа movаааа Arg3, PrintCD аааааа ;then character C
ааааа swapааа Arg3
ааааа rcallаа DISPLAYCHAR
ааааа movаааа Arg3, PrintCDааааааа ;then
caharacter D
ааааа rcallаа DISPLAYCHAR
ааааа ldiаааа Arg3, 10аааааа ааааа ;after characters ABCD, display the
ааааа rcallаа DISPLAYCHARааааааааа ;measurement
units character, too
ааааа
ааааа decаааа CurrHeightаааааааааа ;decrease
the height counter
ааааа rjmpааа DISPLAYLINERESTARTааааа ;end line
;****************************************************************************
;* DISPLAYCHAR: prints on screen the row set by Arg4 of
the character Arg3
;* Character matrix is 5 x 7 dots, and is stored by
column in eeprom
;* Arg3= character to display
;* Arg4 = mask for vertical pixel selection
;****************************************************************************
INSERTPOINT:ааааааааааааааааааааааааааа ;insert decimal
point between digits
ааааа movаааа PointPosition, Arg3аааа ;Save character to print
ааааа ldiаааа Arg3, 60ааааааааааааааа ;substitute it with point
ааааа ldiаааа Arg2, 2аааааааааааааааа ;preload reduced width
ааааа rjmpааа DISPLAYCOLUMNаааааааааа ;go print it
DISPLAYCHAR:
ааааа andiааа Arg3, 0b00001111ааааааа ;clear high nibble
ааааа lslаааа PointPositionааааааа ;if point insertion request
ааааа brcsааа INSERTPOINTааааааааа ;go
swapoing the charachter with dot
ааааа movаааа Arg1, Arg3ааааааааааааа ;otherwise if point not requested
ааааа lslаааа Arg1ааааааааааааааааааа ;multiply character by 5
ааааа lslаааа Arg1ааааааааааааааааааа ;to get offset in font
table
ааааа addаааа Arg3, Arg1аааааааааа ааа;now Arg3 is the table offset
ааааа ldiаааа Arg2, 5аааааааааааааааа ;Arg2 = column number
DISPLAYCOLUMN:ааааааа
ааааа outаааа EEAR,а
Arg3аааааааааааа ;set eeprom
address register
ааааа sbiаааа EECR, 0аааааааааааааааа ;send read command
ааааа inааааа Arg1, EEDRаааааа ааааааа;read font table in EEPROM
ааааа andаааа Arg1, Arg4ааааааааааааа ;mask unwanted pixels
ааааа skipeqааааааааааааааааааааааааа ;according to table
ааааа sbiаааа PortD, VideoBitаааааааа ;turn pixel on or...
ааааа skipne
ааааа cbiаааа PortD, VideoBitаааааааа ;...turn pixel off
ааааа incаааа Arg3ааааааааааааааааааа ;next column in table
ааааа decаааа Arg2ааааааааааааааааааа ;if not last column
ааааа brneааа DISPLAYCOLUMNаааааааааа ;then display next one
аааааааааааааааааааааааааааа ;otherwise
this is the
ааааа doublenopаааааааааааааааааааааа ;last pixel, waste time...
ааааа doublenop
ааааа doublenop
ааааа ldiаааа Arg1, 0аааааааааааааааа ;
ааааа cpiаааа Arg3, 61ааааааааааааааа ;if table offset > 60 (point
done)
ааааа movаааа Arg3, PointPositionаааа ;then restore character saved in
PointPosition
ааааа skiploааааааааааааааааааааааааа ;(if point inserted
reset PointPosition)
ааааа movаааа PointPosition, Arg1аааа ;(dont use clear, test pending)
ааааа cbiаааа PortD, VideoBitаааааааа ;turn pixel off
ааааа brshааа DISPLAYCHARаааааааааааа ;and go print it
ааааа
ааааа retаааааааааааааааааааааааааааа ;else exit
;****************************************************************************
;* DISPLAYBAR: builds the analog bar display. The bar has
a resolution
;* of 128 steps, each step takes 4 clock cycles to
display.
;* The bar lenght is 32 uS.
;****************************************************************************
DISPLAYBAR:
ааааа decаааа Arg1ааааааааааааааааааа ;delay loop to align ruler
and bar
ааааа brneааа DISPLAYBAR
ааааа
ааааа ldiаааа Arg1, 0b01111111
ааааа andаааа Arg1, BarLenght
ааааа ldiаааа Arg2, 0b01111111
ааааа eorаа ааArg2, Arg1
ааааа ;wait for
ruler start position
ааааа ;Arg1 Value/8;
Arg2=127-Value/8-1
ааааа tstаааа Arg1
ааааа breqааа BLACKBAR
ааааа sbiаааа PortD, VideoBit
WHITEBAR:ааааааа
ааааа decаааа Arg1
ааааа nop
ааааа brneааа WHITEBAR
BLACKBAR:
ааааа cbiаааа PortD, VideoBit
ааааа nop
ааааа rjmpааа WAITBARENDааааааааааааа ;waste time
WAITBAREND:ааааааа
ааааа decаааа Arg2
ааааа nop
ааааа brgeааа WAITBAREND
ааааа rjmpааа DISPLAYLINERESTART
;****************************************************************************
;* DISPLAY RULER ROUTINES: the coarse ruler has 10 tiks,
the fine one
;* has 100 ticks, calibrated for input range from 0=0 to
4000=100
;****************************************************************************
DISPLAY_COARSERULER:
ааааа decаааа Arg1ааааааааааааааааааа ;delay loop to align ruler
to bar
ааааа brneааа DISPLAY_COARSERULER
ааааа ldiаааа Arg1, 11ааааааааааааааа ;load ticks counter
ааааа ldiаааа Arg2, 11ааааааааааааааа ;amount of black between ticks
ааааа inааааа Arg4, PortDаааааааааааа ;Arg4 = actual output (tick off)
ааааа movаааа Arg3, Arg4
ааааа sbr ааааArg3, EXP2(VideoBit)ааа ;Arg3 = output with tick on
COARSETICK:аааааааааааааааааааааааааааа ;for Arg1 = 1 to
11аа
ааааа outаааа PortD, Arg3аааааааааааа ;аааааа make a tick 1 pixel wide
ааааа outаааа PortD, Arg4аааааааааааа ;аааааа (sbi would take 2 cycles)
BLACKSPACE:ааааааа
ааааа decаааа Arg2ааааааааааааааааааа ;аааааа for Arg2 = 1 to 11
ааааа nopаааааааааааааааааааааааааааа ;аааааааааааааа wait 4 cycles
ааааа brneааа BLACKSPACEааааааааааааа ;аааааа next
ааааа ldiаааа Arg2, 11ааааааааааааааа ;аа (reload tick spacing)
ааааа decаааа Arg1ааааааааааааааааааа ;аа (this takes another 4 cycles)
ааааа nopаааааааааааааааааааааааааааа ;аа
ааааа brneааа COARSETICKааааааааааааа ;next tick
ааааа rjmpааа DISPLAYLINERESTART
DISPLAY_FINERULER:
ааааа decаааа Arg1ааааааааааааааааааа ;delay loop to align ruler
to bar
ааааа brneааа DISPLAY_FINERULER
ааааа ldiаааа Arg1, 101аааааааааааааа ;load ticks counter
ааааа inааааа Arg4, PortDаааааааааааа ;Arg4 = actual output (tick off)
ааааа movаааа Arg3, Arg4
ааааа sbrаааа Arg3, EXP2(VideoBit)ааа ;Arg3 = output with tick on
FINETICK:аааааааааааааааааааааааааааааа ;for Arg1 = 1 to
101аа
ааааа outаааа PortD, Arg3аааааааааааа ;аааааа make a tick 1 pixel wide
ааааа outаааа PortD, Arg4аааааааааааа ;аааааа (sbi would take 2 cycles)
ааааа decаааа Arg1ааааааааааааааааааа ;
ааааа brneааа FINETICKаааа
ааааааааааа;next
ааааа rjmpааа DISPLAYLINERESTART
;****************************************************************************
;* Official line exit point for all display routines
;****************************************************************************
DISPLAYLINERESTART:
ааааа ldiаааа Arg1, EXP2(TOV0)ааааааа ;clear timer overflow bit
ааааа outаааа TIFR, Arg1ааааааааааааа ;
ааааа rjmpа WAITNEWLINE
ааааа
ааааа ;setааааааааааааааааааа ;T flag tells that we are
going to sleep
ааааа ;sei
ааааа ;sleepаааааааааааааааааааааа ;sleep until awaken by
timer interrupt
ааааа ;nop
ааааа ;cli
ааааа ;cltааааааааааааааааааа ;with T flag low, subsequent
ааааа ;rjmp
NEWLINEааааааааааааааааааа ;jump directly
to another video line,
аааааааааааааааааааааааааааа
ааааа
;****************************************************************************
;* BIN_BCD:а
Transforms binary data in Main1-2 to Main3-4
;* Works from 0 to 9999 - Argument in Main1-2 is
destroyed
;****************************************************************************
BIN_BCD:
ааааа clrаааа Main3
ааааа clrаааа Main4
MORE_THOUSANDS:а
ааааа cpiаааа Main2, HIGH(1000)ааа ;argument > 1000?
ааааа brloааа HUNDREDS
ааааа brneааа DEC_1000
ааааа cpiаааа Main1, LOW(1000)
ааааа brloааа HUNDREDS
DEC_1000:ааааааааааааааааааа ;yes,
then add 1 to thousands digit
ааааа incаааа Main4ааааааааааааааа ;and
subtract 1000 to argument
ааааа subiааа Main1,а
LOW(1000)
ааааа sbciааа Main2, HIGH(1000)
ааааа rjmpааа MORE_THOUSANDSаааааа ;repeat until argument > 1000
HUNDREDS:
ааааа swapааа Main4
MORE_HUNDREDS:ааааааа
аааааааааааа ;argument > 100?
ааааа cpiаааа Main2, HIGH(100)
ааааа brloааа TENS
ааааа brneааа DEC_100
ааааа cpiаааа Main1, LOW(100)
ааааа brloааа TENS
DEC_100:аааааааааааааааааааа ;yes,
then add 1 to hundreds digit
ааааа incаааа Main4ааааааааааааааа ;and
subtract 100 to argument
ааааа subiааа Main1,а
LOW(100)
ааааа sbciааа Main2, HIGH(100)
ааааа rjmpааа MORE_HUNDREDSааааааа ;repeat until argument > 100
ааааа
TENS:
MORE_TENS:
ааааа cpiаааа Main1, 10аааааа ;argument
> 10?
ааааа brloааа UNITSааааааааааааааа ;yes,
then add 1 to tens counter
ааааа incаааа Main3ааааааааааааааа ;and
subtract 10 to argument
ааааа subiааа Main1, 10
ааааа rjmpааа MORE_TENSаааааа ;repeat
until argument > 10
UNITS:
ааааа swapааа Main3ааааааааааааааа ;now
argument is reduced to units...
ааааа addаааа Main3, Main1ааааааааааа ;add units to result
ааааа ret
;****************************************************************************
;* SENDSERIAL: sends byte Main1 to serial line
;* Uses Main2 and Main3; Main1 is destroyed
;****************************************************************************
SENDSERIAL:
ааааа ldiаааа Main2, 0b00000001аааааа ;load stop bit
ааааа lslаааа Main1аааааааааааааааааа ;add start bit
ааааа rolаааа Main2аааааааааааааааааа ;to get the bit image of
RS232 word
ааааа ldiаааа Main3, BAUDRATEаааааааа ;bit time (in video lines)
ааааа sbrаааа MiscFlags, EXP2(SerialReqBit)аа ;request interrupt servicing
WAITTX:
ааааа sbrcааа MiscFlags, SerialReqBit ;wait for interrupt
acknowledge
ааааа rjmpааа WAITTX
ааааа ret
SERIALDRIVER:аааааааааааааааааааааааааа ;called once a line
ааааа sbrsааа MiscFlags, SerialReqBit ;is serial tx
pending?
ааааа rjmpааа EXITSERIALDRIVERааааааа ;no, exit routine
ааааа decаааа Main3аааааааааааааааааа ;yes, decrease bit interval
timer
ааааа doublenopаааааааааааааааааааааа ;time balancing
ааааа brneааа EXITSERIALDRIVERааааааа ;is it time to send another bit?аа
ааааа ldiаааа Main3, BAUDRATEаааааааа ;yes, reload bit timer
ааааа lsrаааа Main2аааааааааааааааааа ;shift buffer into carry
ааааа rorаааа Main1
ааааа skipcc
ааааа cbiаааа PortD, RS232Bitаааааааа ;send ONE
ааааа skipcs
ааааа sbiаааа PortD, RS232Bitаааааааа ;send ZERO
ааааа cpiаааа Main1, 0ааааааааааааааа ;if buffer = 0x0000, done
ааааа cpcаааа Main2, Main1
ааааа skipne
ааааа cbrаааа MiscFlags, EXP2(SerialReqBit)аа ;acknowledge caller
ааааа nopаааааааааааааааааааааааааааа ;time balancing
EXITSERIALDRIVER:
ааааа ret
ааааааааааа аааа
;****************************************************************************
;*а READADC: reads
ADC channel specified by Main1 into Main3-4
;*а Range is
0-4096. Uses Main2
;****************************************************************************
.MACROа ADC_CLOCKPULSE
аааааааааааааааааааааааааааа ;makes
a clock pulse: implemented
аааааааааааааааааааааааааааа ;as
macro because stack is exausted
ааааа sbiаааа PortD, SCLKBitааааааааа ;SCLK high
.SETааа _nextstep =
PC+1ааааааааааааааа ;wait at least 200 nS
ааааа rjmpааа _nextstep
.SETааа _nextstep =
PC+1
ааааа rjmpааа _nextstep
ааааа cbiаааа PortD, SCLKBitааааааааа ;SCLK low
.ENDMACRO
READADC:
ааааа cbiаааа PortD, SCLKBitааааааааа ;clear the clock line
ааааа cbiаааа PortD, CSBitааааааааааа ;chip-select the ADC
ааааа swapааа Main1аааааааааааааааааа ;setup ADC commmand word
ааааа andiааа Main1, 0b01110000аааааа ;(unipolar, single ended conversion
ааааа oriаааа Main1, 0b10001110аааааа ;with internal clocking)
ааааа ldiаааа Main2, 50
ааааа ldiаааа Main2,8аааааааааааааааа ;prepare bit counter
ADC_SENDCOMMAND:
ааааа rolаааа Main1аааааааааааааааааа ;shift out 8-bit command
ааааа skipcc
ааааа sbiаааа PortD, DINBitаааааааааа ;set output pin accordingly
ааааа skipcs
ааааа cbiаааа PortD, DINBit
ааааа ADC_CLOCKPULSEааааааааааааааааа ;start a clock pulse (macro
does
ааааа decаааа Main2аааааааааааааааааа ;not need stack space)
ааааа brneааа ADC_SENDCOMMANDаааааааа ;loop untils all the 8 bits sent
ааааа
ааааа ldiаааа Main2, 50аааааааааааааа ;setup wait time
_WAITLOOP:ааааааааааааааааааааааааааааа ;wait 12.5 uS to
allow conversion ends
ааааа decаааа Main2
ааааа nopаааааааааааааааааааааааааааа ;waste time
ааааа brneааа _WAITLOOP
ааааа clrаааа Main3аааааааааааааааааа ;clear result (high byte
will be overwritten)
ааааа ldiаааа Main2, 13аааааааааааааа ;shift in 10+2 bit result plus
one more clock
ADC_RECEIVEDATA:
ааааа ADC_CLOCKPULSEааааааааааааааааа ;clock the ADC for next bit
ааааа clcаааааааааааааааааааааааааааа ;carry cleared
ааааа sbicааа PinB, DOUTBitаааааааааа ;if ADC data pin is high, set carry
ааааа sec
ааааа rolаааа Main3аааааааааааааааааа ;shift carry into data
buffer
ааааа rolаааа Main4
ааааа decаааа Main2
ааааа brneааа ADC_RECEIVEDATAаааааааа ;repeat until all bits read
ааааа sbiаааа PortD, CSBitааааааааааа ;release ADC chip select
ааааа ret