;***************************************************************************

;* 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

 

 

 

Используются технологии uCoz