Ready-Set-Go

From Wiki
Jump to: navigation, search
File: make.bat
 
@echo off
\dos_util\asmlink\asm51 rsg.asm %1
\dos_util\asmlink\link51 rsg
if exist rsg.rel del rsg.rel
if exist rsg.sym del rsg.sym
 
File: rsg.asm
 
;
;----------------------------------------------------------------------------
;
;  Copyright (c) 1992 Tiger Labs, Corp.  All Rights Reserved.
;
;  This Source File Represents An Unpublished Work Of Tiger Labs, And May
;  Not Be Copied, Duplicated Or Reproduced In Any Form Or Manner, Mechanical
;  Or Electronic, Or By Any Means Not Mentioned Here, Without Prior Written
;  Permission Of Tiger Labs, Corp.
;
;----------------------------------------------------------------------------
;
;  RSG.ASM - The Ready-Set-Go! Boat Racing Timer.  Version 1.00.
;
;  Notes:
;  
;    The LCD Is Connected Sort Of Funny.  The High Order Digit Is Used To
;  Control The 1, The LOBAT Symbol, And The Colon.  LCD Segments Are Numbered
;  Clockwise, With 'A' Being At The Top, 'F' Being The Upper Left Segment,
;  And 'G' Being The Center Horizontal Segment.
;
;
;----------------------------------------------------------------------------
;
;  EQUATES For This Module
;
P87C751	equ	-1		; 0 For Emulator, -1 For 87C751 Processor
;
PUPTIM	equ	180		; Unit Stays On For 3 Minutes Of Inactivity
PDNTIM	equ	 30		; If 0:00 And No Activity, 30 Seconds
HRNPON	equ	  5		; Horn Time At Power On
HRNEXP	equ	150		; Horn Time For 0:00 (# 20ms Intervals)
HRNWRN	equ	 50		; Horn Time For 5:00, 1:00
HRNLTS	equ	 25		; Horn Time For 0:10 ... 0:01
ELPTIM	equ	 50		; This Is 1 / Timer Rate 
;
DEFSEC	equ	 0		; 0 Seconds On Display At Startup
DEFMIN	equ	10		; 10 Minutes On Display At Startup
;
DIGIT0	equ	11000000b	; Bits To Select Digit 0
DIGIT1	equ	10000000b	; Bits To Select Digit 1
DIGIT2	equ	01000000b	; Bits To Select Digit 2
DIGIT3	equ	00000000b	; Bits To Select Digit 3
;
POS_GO	bit	acc.0		; Bit Position For GO Switch
POS_SET	bit	acc.1		; Bit Position For SET Switch
VAL_GO	equ	001h		; Value For GO Switch
VAL_SET	equ	002h		; Value For SET Switch
VAL_RST	equ	003h		; Value For RST Switch
;
;  Set Timing Constants
;
	if	P87C751
CLOCK	equ	3		; 1 For 12Mhz, 2 For 6Mhz, 3 For 4Mhz
TMRRATE	equ	0-(20000/CLOCK)	; Switch Polled Every 20 Milliseconds
;
	else
;
CLOCK	equ	1		; 1 For 12Mhz, 2 For 6Mhz, 3 For 4Mhz
TMRRATE	equ	0-(20000/CLOCK)	; Switch Polled Every 20 Milliseconds
	endif
;
;  Define Port Equates.  Determine If On 87C751 Or Emulator
;
	if	P87C751
DATA0	bit	p3.0		; Data Line 0 For LCD Controller
DATA1	bit	p3.1		; Data Line 1 For LCD Controller
DATA2	bit	p3.2		; Data Line 2 For LCD Controller
DATA3	bit	p3.3		; Data Line 3 For LCD Controller
DS1	bit	p3.4		; Data Register Select 0 For LCD Controller
DS2	bit	p3.5		; Data Register Select 1 For LCD Controller
LCDCS	bit	p3.6		; Chip Select For LCD Controller (Active Low)
HORN	bit	p3.7		; Piezo Horn Bit (Active Low)
;
SWT_GO	bit	p1.0		; GO Switch Input (Active Low)
SWT_SET	bit	p1.1		; SET Switch Input (Active Low)
LOW_BAT	bit	p1.2		; Low Battery Warning Input
CPU_ON	bit	p1.3		; CPU Power Control Output (Active Low)
;
	else
;
DATA0	bit	p1.0		; Data Line 0 For LCD Controller
DATA1	bit	p1.1		; Data Line 1 For LCD Controller
DATA2	bit	p1.2		; Data Line 2 For LCD Controller
DATA3	bit	p1.3		; Data Line 3 For LCD Controller
DS1	bit	p1.4		; Data Register Select 0 For LCD Controller
DS2	bit	p1.5		; Data Register Select 1 For LCD Controller
LCDCS	bit	p1.6		; Chip Select For LCD Controller (Active Low)
HORN	bit	p1.7		; Piezo Horn Bit (Active Low)
;
SWT_GO	bit	p3.2		; GO Switch Input (Active Low)
SWT_SET	bit	p3.3		; SET Switch Input (Active Low)
CPU_ON	bit	p3.4		; CPU Power Control Output (Active Low)
LOW_BAT	bit	p3.5		; Low Battery Warning Input
	endif
	page
;
;----------------------------------------------------------------------------
;
;  Equates For Registers Processor Doesn't Know About.  These Are In Lower Case
;  Since They're Processor Registers, And Not User Variables.
;
i2con	equ	098h		; I2C Bus Control Register
i2dat	equ	099h		; I2C Bus Data Register
i2cfg	equ	0d8h		; I2C Bus Configuration Register
i2str	equ	0f8h		; I2C Bus Status Register
i2ine	bit	ie.4		; I2C Interrupt Enable Bit
;
tl	equ	08ah		; Timer Low Byte
th	equ	08ch		; Timer High Byte
tlr	equ	08bh		; Timer Low Reload Byte
thr	equ	08dh		; Timer High Reload Byte
	page
;
;----------------------------------------------------------------------------
;
;  Data Storage Locations
;
	rseg	bit
TMRRUN	ds	1		; Timer Running In Interrupt Loop When Set
TMRDONE	ds	1		; Timer Has Reached 0 Flag When Set
PWROFF	ds	1		; Time To Power Off When Set
HRNSND	ds	1		; Sound Horn While Set
LBSTAT	ds	1		; Low Battery Status
MODESPG	ds	1		; Switch Press Good If Set
MODESWT	ds	1		; Current Mode Of Switch
;
	rseg	data
TIMSEC	ds	1		; Seconds Counter
TIMMIN	ds	1		; Minutes Counter
SWTSTAT	ds	1		; Switch Status
PWRTMR	ds	1		; Power Off Delay Counter
HRNTMR	ds	1		; Horn Timer
SECELP	ds	1		; 10 Millisecond Counter
TOS	ds	22		; Top Of Stack Pointer
	page
;
;----------------------------------------------------------------------------
;
; Systems Always Powers Up To Location 0.  Set Up Interrupt, Etc
;
	cseg
	ajmp	SSTART		; Reset Vector
	db	0		; 1 NOP
	reti			; Return From IE0 Interrupt
	db	0,0,0,0,0,0,0	; 7 NOPS
	ajmp	SWITCH		; Process TF0 Interrupt
	db	0,0,0,0,0,0	; 6 NOPS
	reti			; Return From IE1 Interrupt
	db	0,0,0,0,0,0,0	; 7 NOPS
	reti			; Return From TF1 Interrupt
	db	0,0,0,0,0,0,0	; 7 NOPS
	reti			; Return From I2C Interrupt
	page
;
;----------------------------------------------------------------------------
;
;  Copyright Notice (Even Though Security Bit Is Burned), And Obligatory
;  Self Praise, And Ownership Rights.
;
	db	'Copyright (c) 1992 By Tiger Labs, Corp.'
	db	'All Rights Reserved.'
	db	'Version 1.00'
	db	0
	db	'Tiger Labs Corporation'
	db	'100 Nobel Court'
	db	'Alpharetta, GA  30202'
	db	'404-475-8789'
	db	0
	db	'Written By John C. Wren'
	db	0
;
;----------------------------------------------------------------------------
;
; SSTART - System Entry Point.  Configure Parameters
;
SSTART	mov	sp,#TOS		; Set Stack Pointer
	mov	ie,#000h	; No Interrupts (Yet)
	mov	psw,#000h	; Clear Flags, Select Register Set 0
	mov	pcon,#000h	; No Power Down
;
;  Now Setup Timers Modes.  Actual Timer Rate Set By ISR
;
	acall	PTINIT		; Init Ports
	acall	E0INIT		; Init External Interrupt 0
	acall	E1INIT		; Init External Interrupt 1
	acall	ICINIT		; Init I2C Bus Interface
	acall	SWINIT		; Init Switches
	acall	PWINIT		; Init Power
	acall	TMINIT		; Init Second Counter
	acall	HNINIT		; Init Horn
	acall	LBINIT		; Init Low Battery Status
	acall	T0INIT		; Init Timer 0
	acall	T1INIT		; Init Timer 1
	setb	ea		; Enable Entire Interrupt Structure
	ajmp	USTART		; Go Start User Code
;
;----------------------------------------------------------------------------
;
;  USTART - Start Of User Code
;
USTART	mov	TIMSEC,#DEFSEC	; Default Seconds
	mov	TIMMIN,#DEFMIN	; Default Minutes
	acall	DSPDIG		; Display Current Timer
;
;  Power Down Processor.  Timer Events Wake Us Up.
;
UST1	clr	MODESPG		; Acknowledge Button Press, If Any
	orl	pcon,#00000001b	; Set Power Down Mode
	nop			; Safety Net
	jb	TMRDONE,UST2	; If Timer Done, Go Enable Horn
	jb	PWROFF,UST3	; Timer To Power Off?  Snooooooze.
	jb	MODESPG,UST4	; If Button Was Pressed, Deal With It...
	sjmp	UST1		; Huh?  Well, Just Go Back To Sleep...
;
;  Timer Expired, So Enable Horn
;
UST2	mov	HRNTMR,#HRNEXP	; Setup Horn Timer On Duration
	setb	HRNSND		; Enable Horn
	clr	TMRDONE		; Don't Keep Setting Off Horn
	mov	SECELP,#1	; Reset Counter
	sjmp	UST1		; And Go Back To Sleep
;
;  Power Timer Expired, So Shut Us Down
;
UST3	clr	CPU_ON		; Turn Us Off
	sjmp	UST3		; Don't Wander Around Memory
;
;  Must Have Had Button Press.  Figure Out What To Do.
;
UST4	mov	a,SWTSTAT	; Get Switch Value
	cjne	a,#VAL_RST,UST5	; If Not RST Switch, Skip
	clr	TMRRUN		; Timer Not Running
	clr	TMRDONE		; Timer Not Done
	mov	TIMSEC,#DEFSEC	; Default Seconds
	mov	TIMMIN,#DEFMIN	; Default Minutes
	acall	DSPDIG		; Display Current Timer
	sjmp	UST1		; Go Back To Sleep
;
UST5	cjne	a,#VAL_GO,UST6	; If Not Run Switch, Skip
	acall	CHKZERO		; See If Time At 0:00
	jz	UST1		; If So, Don't Do Anything
	mov	SECELP,#ELPTIM	; Setup Second Elapsed Counter
	setb	TMRRUN		; Start Timer Running
	sjmp	UST1		; Make It So, Number 1
;
UST6	cjne	a,#VAL_SET,UST7	; If Not Set Switch, Skip
	jb	TMRRUN,UST1	; Can't Change Timer While Running
	acall	SETDEC		; Decrement Minutes
	acall	DSPDIG		; Display Current Timer
	sjmp	UST1		; Go Back To Sleep
;
UST7	sjmp	UST1		; Go Back To Sleep
	page
;
;----------------------------------------------------------------------------
;
;  SWITCH - Handles Polling The Switch.
;
SWITCH	push	psw		; Save PSW
	push	acc		; Save A
;
;  If Running Emulator, Reload The Standard 8051 Style Timer
;
	if	!P87C751
	clr	tr0		; Stop Counter
	mov	a,#low (TMRRATE+7); Get Reset Value
	add	a,tl0		; Add Timer Overflow Count
	mov	tl0,a		; Reset Timer Low
	mov	a,#high (TMRRATE+7); Get Reset Value
	addc	a,th0		; Add Overflow Value
	mov	th0,a		; Reset Timer High
	setb	tr0		; Start Timer Running Again
	endif
;
;  Unless It's A 1 Second Interval, Don't Check The Timeout Timer, And Don't 
;  Decrement The Timer Display.
;
	mov	a,SECELP	; Get Second Counter
	dec	a		; Decrement It
	mov	SECELP,a	; Store It Back
	jnz	SWT2		; If Not 0, Don't Decrement Power Off Counter
	mov	SECELP,#ELPTIM	; Reset Counter
;
;  If Timer Running, Decrement The Timer Value, And Update Display.  If The
;  Timer Value Goes To 0, Set The TMRDONE Flag.
;
	jnb	TMRRUN,SWT1	; If Timer Not Running, Skip	
	acall	DECTIME		; Decrement The Time
	acall	DSPDIG		; Display Current Timer
	acall	CHKHORN		; See If We Need To Sound Horn Based On Time
;
;  If Timer Not Running, Horn Not Sounding, And No Keystrokes, Then Decrement
;  The Power Off Timer.  If It Goes To 0, Set The PWROFF Bit.  
;
SWT1	jb	TMRRUN,SWT2	; If Timer Running, Don't Do Power Off Timer
	jb	HRNSND,SWT2	; If Horn Sounding, Don't Do Power Off Timer
	mov	a,PWRTMR	; Get Power Off Counter
	dec	a		; Decrement It
	mov	PWRTMR,a	; Store It Back
	jnz	SWT2		; If Not 0, Don't Set Power Off
	setb	PWROFF		; Tell Unit To Go Sleepyby...
;
;  Check The HRNSND Bit.  If Set, Then Start Decrementing The Horn Timer.  Once
;  The Horn Timer Goes To 0, Disable The Horn, And Reset The Horn Timer.
;
SWT2	jnb	HRNSND,SWT3	; If Horn Not Sounding, Skip
	clr	HORN		; Enable Horn
	mov	a,HRNTMR	; Get Horn Duration Timer
	dec	a		; Decrement Horn Timer
	mov	HRNTMR,a	; Store Horn Duration Timer Back
	jnz	SWT6		; While Not 0, Don't Disable Horn
	clr	HRNSND		; Mark Horn As Not Sounding
	setb	HORN		; Disable Horn
;
;  Check Battery Low Status.  If A Change In It, And The Timer Isn't Running,
;  Update The Display.
;
SWT3	jb	TMRRUN,SWT4	; If Timer Running, It Updated Display
	clr	a		; Clear For Operation
	mov	c,LBSTAT	; Get Low Battery Status
	mov	acc.0,c		; Move To Acc
	mov	c,LOW_BAT	; Compare To Current Input Status
	addc	a,#0		; Acc Will Be 0 (No Change) 1 (Change) 2 (NC)
	cjne	a,#1,SWT4	; If Not Change, Don't Update Display
	acall	DSPDIG		; Display Timer
	mov	c,LOW_BAT	; Get Low Battery Input
	mov	LBSTAT,c	; Store Into Low Battery Status
;
;  Determine If A Button Has Been Pressed
;
SWT4	clr	a		; Clear For Load
	mov	c,SWT_GO	; Get GO Switch
	mov	POS_GO,c	; Move Into Acc.0
	mov	c,SWT_SET	; Get SET Switch
	mov	POS_SET,c	; Move Into Acc.1
	cjne	a,#003h,SWT5	; If Not 03, Switch Changing
	clr	MODESWT		; No Switches Being Pressed
	sjmp	SWT6		; Return
;
SWT5	mov	PWRTMR,#PUPTIM	; Pressing Buttons Sets The Long Duration Timer
	jb	MODESWT,SWT6	; If Switch Already Being Pressed, Skip
	jb	MODESPG,SWT6	; If Last Switch Not Read, Discard This One
	xrl	a,#00000011b	; Make Positive Logic
	mov	SWTSTAT,a	; Store Switch Reading
	setb	MODESWT		; Set Switch Status As Being Pressed
	setb	MODESPG		; Say This Is A Fresh Switch Reading
;
;  Recover Processor State, Return To Interruptee
;
SWT6	pop	acc		; Recover Acc
	pop	psw		; Recover PSW
	reti			; Return From Interrupt
	page
;
;----------------------------------------------------------------------------
;
;  SETDEC - Decrement The Minutes Portion Of The Timer.  This Is Called When
;	    The SET Switch Is Bumped.  Counter Starts At 10 Minutes, Goes
;	    Down To 1.  Going Below 1 Wraps Back To 10.
;
SETDEC	mov	a,TIMMIN	; Get Minutes
	jz	SET1		; If Already 0, Just Reset
	dec	a		; Subtract 1
	mov	TIMMIN,a	; Store It Back
	jnz	SET2		; If Not 0, Skip
SET1	mov	TIMMIN,#DEFMIN	; Else, Reset To Default Minutes
SET2	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  DECTIME - Decrement The Time In The TIMSEC And TIMMI Variables.  If The 
;	     Value Underflows, Set The TMRDONE Flag.  Otherwise, Return.
;
DECTIME	mov	a,TIMSEC	; Get Seconds
	dec	a		; Subtract 1
	mov	TIMSEC,a	; Store It Back
	cjne	a,#-1,DEC1	; If No Underflow, Exit
	mov	TIMSEC,#59	; Reset Seconds To 59
	mov	a,TIMMIN	; Get Minutes
	dec	a		; Subtract 1
	mov	TIMMIN,a	; Store It Back
;
DEC1	acall	CHKZERO		; See If Time At 0 Minutes, 0 Seconds
	jnz	DEC2		; If Not 0:00, Don't Mark As Done
	clr	TMRRUN		; Timer Not Running
	setb	TMRDONE		; Set The Timer Done Flag
	mov	PWRTMR,#PDNTIM	; Set Short Power Off Time
DEC2	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  CHKHORN - See If It's One Of Those Times When We Need To Sound The Horn.
;	     This Occurs At 5:00 And 1:00 (Horn On For 1 Full Second), Then
;	     At 0:10 ... 0:01 (Horn On For 500 Milliseconds).  Minutes Table
;	     Supports To 19 Minutes In Case We Ever Go That High (Max Display
;	     Range Of LCD)
;
CHKHORN	mov	a,TIMMIN	; Get Minutes
	mov	dptr,#CHKTAB	; Point To Base Of Table
	movc	a,@a+dptr	; Get Table Entry
	jb	acc.7,CHKH1	; If Bit 7 Set, Must Be A Minute Warning
	jb	acc.6,CHKH3	; If Bit 6 Set, Need To Only Test Seconds
	ret			; Otherwise, Nothing Doing...
;
CHKH1	mov	a,TIMSEC	; Get Seconds
	jnz	CHKH2		; If Not Even Minute, No Noise
	mov	HRNTMR,#HRNWRN	; Store Warning Duration
	setb	HRNSND		; Enable Horn
CHKH2	ret			; Return To Caller
;
CHKH3	mov	a,TIMSEC	; Get Seconds
	jz	CHKH5		; If 0 Seconds, No Horn Chirp
	cjne	a,#11,CHKH4	; Compare To 11
CHKH4	jnc	CHKH5		; If Greater Than 10 Seconds, Skip
	mov	HRNTMR,#HRNLTS	; Last 10 Seconds Chirp
	setb	HRNSND		; Enable Horn
CHKH5	ret			; Return To Caller
;
CHKTAB	db	01000000b	;  0 Minutes, Check Seconds
	db	10000000b	;  1 Minutes, Chirp At 1:00
	db	00000000b	;  2 Minutes, No Noise
	db	00000000b	;  3 Minutes, No Noise
	db	00000000b	;  4 Minutes, No Noise
	db	10000000b	;  5 Minutes, Chirp At 5:00
	db	00000000b	;  6 Minutes, No Noise
	db	00000000b	;  7 Minutes, No Noise
	db	00000000b	;  8 Minutes, No Noise
	db	00000000b	;  9 Minutes, No Noise
	db	00000000b	; 10 Minutes, No Noise
	db	00000000b	; 11 Minutes, No Noise
	db	00000000b	; 12 Minutes, No Noise
	db	00000000b	; 13 Minutes, No Noise
	db	00000000b	; 14 Minutes, No Noise
	db	00000000b	; 15 Minutes, No Noise
	db	00000000b	; 16 Minutes, No Noise
	db	00000000b	; 17 Minutes, No Noise
	db	00000000b	; 18 Minutes, No Noise
	db	00000000b	; 19 Minutes, No Noise
	page
;
;----------------------------------------------------------------------------
;
;  CHKZERO - Check To See If The Timer Is At 0 Minutes, 0 Seconds
;
CHKZERO	mov	a,TIMMIN	; Get The Minutes
	orl	a,TIMSEC	; OR In The Seconds
	ret			; Return To Caller
;
;----------------------------------------------------------------------------
;
;  DSPDIG - Display The Minutes And Seconds To The LCD Display.
;
DSPDIG	mov	a,TIMSEC	; Get Seconds
	mov	b,#10		; Divide By 10
	div	ab		; Do The Divide
	mov	a,b		; Get Low Part
	orl	a,#DIGIT0	; Select Digit 0
	acall	WRTDIG		; Write It
;
	mov	a,TIMSEC	; Get SEconds
	mov	b,#10		; Divide By 10
	div	ab		; Do The Divide
	orl	a,#DIGIT1	; Select Digit 1
	acall	WRTDIG		; Write It
;
	mov	a,TIMMIN	; Get Minutes
	mov	b,#10		; Divide By 10
	div	ab		; Do The Divide
	mov	a,b		; Get Low Part
	orl	a,#DIGIT2	; Select Digit 2
	acall	WRTDIG		; Write It
;
	mov	a,TIMMIN	; Get Minutes
	mov	b,#10		; Divide By 10
	div	ab		; Do The Divide
	mov	c,LOW_BAT	; Get Low Battery Indicator
	mov	acc.1,c		; Set Into C
	anl	a,#00000011b	; Redundant, But VERY Safe
	mov	dptr,#CNVTAB	; Point To Conversion Table
	movc	a,@a+dptr	; Get Conversion Value
	orl	a,#DIGIT3	; Select Digit 3
	acall	WRTDIG		; Write It
	ret			; Return To Caller
;
CNVTAB	db	004h		; Colon + LOBAT
	db	000h		; Colon + 1 + LOBAT
	db	001h		; Colon
	db	007h		; Colon + 1
	page
;
;----------------------------------------------------------------------------
;
;  WRTDIG - Write Digit.  Low 4 Bits Of Acc Has Digit To Display, Top 4
;	    Bits Are The Digit Number.  Digit 0 Is The Left Most Digit.
;
WRTDIG	mov	c,acc.6		; Get Low Order Bit Of Digit Select
	mov	DS1,c		; Set To LCD Controller
	mov	c,acc.7		; Get High Order Bit Of Digit Select
	mov	DS2,c		; Set To LCD Controller
	mov	c,acc.0		; Get Bit 0 Of Data
	mov	DATA0,c		; Set To LCD Controller
	mov	c,acc.1		; Get Bit 1 Of Data
	mov	DATA1,c		; Set To LCD Controller
	mov	c,acc.2		; Get Bit 2 Of Data
	mov	DATA2,c		; Set To LCD Controller
	mov	c,acc.3		; Get Bit 3 Of Data
	mov	DATA3,c		; Set To LCD Controller
	clr	LCDCS		; Drive Chip Select Low To Strobe
	setb	LCDCS		; Bring Back High
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  PTINIT - Set Chip Enables, Etc
;
PTINIT	setb	CPU_ON		; Make Sure We Stay Awake
	setb	LCDCS		; No Chip Select To LCD Controller
	setb	SWT_GO		; Make GO Switch An Input
	setb	SWT_SET		; Make SET Switch An Input
	setb	LOW_BAT		; Make Low Battery An Input
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  E0INIT - Initialize External Interrupt 0 Sub-System
;
E0INIT	clr	ex0		; No External Interrupt
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  E1INIT - Initialize External Interrupt 1 Sub-System
;
E1INIT	clr	ex1		; No External Interrupt
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  ICINIT - Initialize I2C Bus Interface Sub-System
;
ICINIT	clr	i2ine		; Make Sure No I2C Interrupts Occur
	ret			; Return To Caller
;
;----------------------------------------------------------------------------
;
;  SWINIT - Initialize The Switch Buttons
;
SWINIT	clr	MODESPG		; No Buttons Pressed
	clr	MODESWT		; No Switches Currently Pressed
	mov	SECELP,#ELPTIM	; Setup Second Elapsed Counter
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  PWINIT - Initalize Power Timer
;
PWINIT	clr	PWROFF		; Don't Power Off
	mov	PWRTMR,#PUPTIM	; Long Duration Time To Remain On
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  HNINIT - Turn Horn Off, 
;
HNINIT	clr	HORN		; Enable Horn
	setb	HRNSND		; Don't Sound Horn
	mov	HRNTMR,#HRNPON	; Turn 
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  TMINIT - Make Sure Timer Running Bit (TMRRUN) Is Cleared, Along With The
;	    Timer Done Status Bit (TMRDONE).
;
TMINIT	clr	TMRRUN		; Timer Not Running In ISR
	clr	TMRDONE		; Timer Not Done
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  LBINIT - Initialize Low Battery Status.  Make Sure Flags Different So
;	    At Least One Update Takes Place.
;
LBINIT	mov	c,LOW_BAT	; Get Low Battery Status
	cpl	c		; Switch States
	mov	LBSTAT,c	; Store Into Low Battery Status
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  T0INIT - Initialize Timer 0 Sub-System
;
T0INIT	mov	tcon,#00000000b	; Gate=0, C/T=0, TR=0, IT0, IT1 Level Sensitive
;
	if	P87C751
	mov	a,#low (TMRRATE); Get Low Of Interrupt Time
	mov	tlr,a		; Set Timer Reload Value Low
	mov	tl,a		; Set Timer Value Low
	mov	a,#high (TMRRATE); Get High Of Interrupt Time
	mov	thr,a		; Set Timer Reload Value High
	mov	th,a		; Set Timer Value High
;
	else
;
	mov	a,tmod		; Get TMOD status
	anl	a,#0f0h		; Don't Change Timer 1 Bits
	orl	a,#001h		; Set 16 Bit Timer/Counter
	mov	tmod,a		; Store To Real TMOD Register
	mov	a,#low (TMRRATE); Get Low Of Interrupt Time
	mov	tl0,a		; Set Timer Reload Value Low
	mov	a,#high (TMRRATE); Get High Of Interrupt Time
	mov	th0,a		; Set Timer Reload Value High
	endif
;
	setb	et0		; Allow Timer Overflow Interrupts
	setb	tr0		; Start Timer Running
	ret			; Return To Caller
	page
;
;----------------------------------------------------------------------------
;
;  T1INIT - Initialize Timer 1 Sub-System
;
T1INIT	clr	et1		; No Interrupt From Fixed Timer 1
	ret			; Return To Caller
	page
	end