************************* GLOBAL LABELS *************************************** 


_IRAM   EQU   $0000       Internal RAM $0000..$00FF (256byte). 
_PORTA  EQU   $1000       Port A Data register.
_PIOC   EQU   $1002       Parallel I/O Control Register.
_PORTC  EQU   $1003       Port C Data register.
_PORTB  EQU   $1004       Port B Data register.
_PORTCL EQU   $1005       PPort C Alternate Latched.
_DDRC   EQU   $1007       Port C Data Direction Register.
_PORTD  EQU   $1008       Port D Data Register.
_DDRD   EQU   $1009       Port D Data Direction Register.
_PORTE  EQU   $100A       Port E Data Register.
_CFROC  EQU   $100B       Timer: Compare Force.
_OC1M   EQU   $100C       Timer: Output Compare 1 Mask.
_OC1D   EQU   $100D       Timer: Output Compare 2 Data.
_TCNT   EQU   $100E       Timer: 16 bit free running counter.
_TIC1   EQU   $1010       Timer: Input Capture Register 1.
_TIC2   EQU   $1012       Timer: Input Capture Register 2.
_TIC3   EQU   $1014       Timer: Input Capture Register 3.
_TOC1   EQU   $1016       Timer: Output Compare Register 1.
_TOC2   EQU   $1018       Timer: Output Compare Register 2.
_TOC3   EQU   $101A       Timer: Output Compare Register 3.
_TOC4   EQU   $101C       Timer: Output Compare Register 4.
_TOC5   EQU   $101E       Timer: Output Compare Register 5.
_TCTL1  EQU   $1020       Timer: Control Register 1.
_TCTL2  EQU   $1021       Timer: Control Register 2.
_TMSK1  EQU   $1022       Timer: Interrupt Mask Register 1.
_TFLG1  EQU   $1023       Timer: Interrupt Flag Register 1.
_TMSK2  EQU   $1024       Timer: Interrupt Mask Register 2.
_TFLG2  EQU   $1025       Timer: Interrupt Flag Register 2.
_PACTL  EQU   $1026       Timer: Pulse Accumulator Control.
_PACNT  EQU   $1027       Timer: Pulse Accumulator Count Register.
_SPCR   EQU   $1028       SPI: Control Register.
_SPSR   EQU   $1029       SPI: Status Register.
_SPDR   EQU   $102A       SPI: Data Register.
_BAUD   EQU   $102B       SCI: Baud Rate Register.
_SCCR1  EQU   $102C       SCI: Control Register 1.
_SCCR2  EQU   $102D       SCI: Control Register 2.
_SCSR   EQU   $102E       SCI: Status Register.
_SCDR   EQU   $102F       SCI: Data Register.
_ADCTL  EQU   $1030       A/D: Control Register.
_ADR1   EQU   $1031       A/D: Result Register 1.
_ADR2   EQU   $1032       A/D: Result Register 2.
_ADR3   EQU   $1033       A/D: Result Register 3.
_ADR4   EQU   $1034       A/D: Result Register 4.
_OPTION EQU   $1039       System Configuration Option.
_COPRST EQU   $103A       Arm/Reset COP Timer Circuitry.
_PPROG  EQU   $103B       EEPROM Programming Register.
_HPRIO  EQU   $103C       Highest Priority I bit.
_INIT   EQU   $103D       RAM and I/O Mapping Register.
_TEST1  EQU   $103E       Testing Functions Control Register.
_CONFIG EQU   $103F       System Configuration.
_DPRA   EQU   $1800       PIA: Data direction / Periferial register A.
_CRA    EQU   $1801       PIA: Control register A.
_DPRB   EQU   $1802       PIA: Data direction / Periferial register B.
_CRB    EQU   $1803       PIA: Control register B.
_XRAM   EQU   $2000       External RAM $2000..$3FFF (8192byte).
_EEPROM EQU   $B600       Internal EEPROM $B600..$B7FF (512byte).
_EPROM  EQU   $E000       User EPROM $E000..$FFFF (8192byte).
                              
PODH    EQU   $2010
PODL    EQU   $2011
VSOTAL  EQU   $2012
VSOTAH  EQU   $2013
VSOTAC  EQU   $2014
STEVEC  EQU   $2015
ENA     EQU   $2016
DESET   EQU   $2017
STO     EQU   $2018
TISOC   EQU   $2019
MEANL   EQU   $2020
MEANH   EQU   $2021
ENAB    EQU   $2022
DESETB  EQU   $2023
STOB    EQU   $2024
TISOCB  EQU   $2025

************************* HC11 INTERRUPT VECTORS ****************************** 


_ISCI   EQU   $FFD6       Serial Communication Interface (SCI)
_ISPI   EQU   $FFD8       Serial Peripherial Interface (SPI)
_IPAIE  EQU   $FFDA       Pulse Accumulator Input Edge
_IPAO   EQU   $FFDC       Pulse Accumulator Overflow
_ITOF   EQU   $FFDE       Timer Overflow
_ITOC5  EQU   $FFE0       Timer Output Compare 5
_ITOC4  EQU   $FFE2       Timer Output Compare 4
_ITOC3  EQU   $FFE4       Timer Output Compare 3
_ITOC2  EQU   $FFE6       Timer Output Compare 2
_ITOC1  EQU   $FFE8       Timer Output Compare 1
_ITIC3  EQU   $FFEA       Timer Input Capture 3
_ITIC2  EQU   $FFEC       Timer Input Capture 2
_ITIC1  EQU   $FFEE       Timer Input Capture 1
_IRTI   EQU   $FFF0       Real Time Interrupt (RTI)
_IIRQ   EQU   $FFF2       IRQ Pin
_IXIRQ  EQU   $FFF4       XIRQ Pin (Pseudo Non-Maskable Interrupt)
_ISWI   EQU   $FFF6       Software Interrupt (SWI)
_IILLOP EQU   $FFF8       Illegal Opcode Trap
_ICOP   EQU   $FFFA       COP Failure (Reset)
_ICLKM  EQU   $FFFC       Clock Monitor Fail (Reset)
_IRESET EQU   $FFFE       Reset


************************* INTERRUPT VECTOR TABLE ****************************** 


        ORG   _ITOC1      Set Output Compare 1 interrupt
        FDB   _SCHINT        to the scheduler interrupt rutine.
        ORG   _IRESET     Upon reset
        FDB   _START         go to START.


        ORG   _EPROM


************************ TASK SCHEDULE ***************************************


SCHTAB  FDB   SCHRTS
        FDB   SCHRTS       
        FDB   SCHRTS      Void task.             ~ =  5
        FDB   LED_0 
        FDB   TIM
        FDB   SCHRTS
        FDB   SCHRTS	
        FDB   LED_1
        FDB   SCHRTS      Void task.             ~ =  5
        FDB   SCHRTS
        FDB   SCHRTS		             
        FDB   LED_2
        FDB   SCHRTS      Void task.             ~ =  5
        FDB   SCHRTS
        FDB   SCHRTS      Void task.             ~ =  5
        FDB   LED_3
SCHRTS  rts               Void task.


************************* THE SCHEDULER INTERRUPT RUTINE (~=80) ***************


_SCHINT brclr SCHTST $01 SCHERR  6 Branch if previous interrupt running.
        inc   SCHTST      6 Set test bit to indicate running interrupt.
        ldd   _TOC1       5 Load timer output compare register 1,
        addd  #1200       4    increment it by time slice
        std   _TOC1       5    and restore it to TOC1.
        ldx   SCHPTR      5 Get pointer to current 1/64s period task.
        ldx   0,X         5 Get the task's entry address.
        ldaa  #$80        2 Clear currently pending 
        staa  _TFLG1      4    OC1F interrupt and
        cli               2    allow interrupts.
        jsr   0,X         6 EXECUTE THE TASK.
        ldaa  SCHPTR+1    4 Get high byte of SCHPTR,
        adda  #2          2    increment it, 
        anda  #%00011110  2    overlay 0's
        staa  SCHPTR+1    4    and restore it to SCHPTR.
        clr   SCHTST      6 Reset test bit to indicate end of interrupt.
        rti               12 Return from OC1 interrupt
SCHERR  bra   SCHERR      Fatal error, can't continue!


************************* ENABLE THE SCHEDULER ********************************


SCHON   clr   SCHTST      6 Reset test bit to indicate no interrupt running.
        ldx   #SCHTAB     3 Initialize pointer
        stx   SCHPTR      5    to first 1/64s period tasks. 
        ldd   _TCNT       5 Load free running counter
        addd  #1200       4    increment it by time slice
        std   _TOC1       5    and store it to output compare register 1. 
        ldaa  #$80        2 Select OC1,
        staa  _TFLG1      4    clear any pending OC1F,
        staa  _TMSK1      4    enable OC1 interrupt and
        cli               2    start interrupts.
        rts               5 Return(Scheduler running).


************************* TIMER TASK (~<=77) **********************************
*  This is a real-time clock driver. TIM should be placed into the task
*  schedule at a 1/256 second duty cycle. TIM updates four global variables
*  TIMH (Hours 0..23), TIMM (minutes 0..59), TIMS (seconds 0..59) and
*  TIMF (second fractions 0..255).
*******************************************************************************


TIM     inc   TIMF        6 Increment fraction counter,
        bne   TIMRTS      3 Branch down if no overflow
        inc   TIMS        6 Increment second counter,
        ldaa  TIMS        4    load it to A
        cmpa  #60         2    and compare with 60.
        bcs   TIMRTS      3 Branch down if no overflow
        clr   TIMS        6    and reset second counter otherwise.
        inc   TIMM        6 Increment minute counter,

        ldaa  TIMM        4    load it to A
        cmpa  #60         2    and compare with 60.
        bcs   TIMRTS      3 Branch down if no overflow
        clr   TIMM        6    and reset minute counter otherwise.
        inc   TIMH        6 Increment hour counter,
        ldaa  TIMH        4    load it to A 
        cmpa  #24         2    and compare with 24.
        bcs   TIMRTS      3 Branch down if no overflow
        clr   TIMH        6    and reset hour counter otherwise.
TIMRTS  rts               5 Return().


************************* SYNCHRONIZE WITH SCHEDULER ************************** 
*  Call this subroutine from any non-realtime routine to request D<1100
*  uninterrupted subsequent maschine cycles. Upon return, you have the
*  requested number of uninterrupted cycles, plus D extra cycles. Use D=0 to
*  find out the number of cycles left until next scheduler interrupt.
*******************************************************************************


SCHSYN  pshx              4  Push X.
        addd  #$0020      4  Add the system overhead of 32 machine cycles.
        pshb              3  Push number of machine cycles
        psha              3     from D to stack
        tsx               3     and make X point to it.
SCHWAI  ldd   _TOC1       4  Load output compare register,
        subd  _TCNT       5     subtract free running counter
        subd  0,X         6     and number of cycles.
        bmi   SCHWAI      3  Loop back if not enough cycles until interrupt.
        pulx              5  Dummy pull X to clear D from stack.
        pulx              5  Restore X.
        rts               5  Return(D=extra cycles left).


************************* RESET ***********************************************


_START  lds   #$3FFF      Define stack segment.
        jsr   INIT        Initialize RAM variables.
        jsr   SCHON       Start scheduler.
        jsr   MAIN        Call MAIN -- there should be no return.
HALT    bra   HALT        Dead loop!


************************* INITIALIZE RAM VARIABLES ****************************


INIT    ldx   #$0000      Clear
        stx   TIMH           hours, minutes,
        stx   TIMS           seconds and fractions.
        stx   LED0        Clear the
        stx   LED2           4 digit LED display.
        ldx   #KBDB+2     Clear the
        stx   KBDB           keyboard
        stx   KBDE           buffer.
        clr   KBDKEY      Indicate no key pressed.
        ldx   #TRAB+2     Clear the
        stx   TRAB           SCI transmitting
        stx   TRAE           buffer.
        ldx   #RECB+2     Clear the
        stx   RECB           SCI receiveing
        stx   RECE           buffer.
        clr   _CRA        Enable Data direction register A and
        clr   _CRB           Data direction register B.    
        ldaa  #$0F        Set lower bits of port A
        staa  _DPRA          to output, higher bits to input.
        ldaa  #$FF        Set all bits of port B
        staa  _DPRB          to output.
        ldaa  #$04        Enable Data registers
        staa  _CRA           of port A and
        staa  _CRB           port B.
        ldaa  #%00001110  Initialize port A
        staa  _DPRA          to activate LED0.
        clr   _DPRB       Clear port B.
        ldaa  _OPTION     Get system options,
        oraa  #%10000000     set A/D power on
        staa  _OPTION        and store options.

************  RESET ZA ADP *******

	ldaa  #%00111010	nastavi DDRD
	staa  _DDRD
	ldaa  #%01111111	nastavi SPI kontr. reg. na HC11
	staa  _SPCR

	jsr   CSYES	
	ldaa  #%11111111  1. byte enic	RESET ADP
	staa  _SPDR
	jsr   ST
	jsr   CSNO
	jsr   CSYES	
	ldaa  #%11111111	2. byte enic
       	staa  _SPDR
	jsr   ST
	jsr   CSNO
	jsr   CSYES	
	ldaa  #%11111111	3. byte enic
       	staa  _SPDR
	jsr   ST
	jsr   CSNO
	jsr   CSYES	
	ldaa  #%11111111	4. byte enic
       	staa  _SPDR   
	jsr   ST
	jsr   CSNO

	jsr   CSYES	
	ldaa  #$00010000	vpis v kom.reg. + naslednji vpis je v nast.reg.
	staa  _SPDR
	jsr   ST
	jsr   CSNO

	jsr   CSYES	
       	ldaa  #$01101000	vpis v nastavitveni reg.
	staa  _SPDR
	jsr   ST
	jsr   CSNO

************* NASTAVITEV KONSTANT ***********
	
	ldaa  #$00	nastavi zacetne vrednosti
	staa  VSOTAC
	staa  VSOTAL
	staa  VSOTAH
	staa  MEANL
	staa  MEANH
	ldaa  #%00111111
	staa  ENAB
	staa  DESETB
	staa  STOB
	staa  TISOCB
	ldaa  #%01000000
	staa  STEVEC
	
        rts               Return().                                            


***********************************************************************************
************************  Pisanje na LED display  *********************************
***********************************************************************************

LED_0   ldaa  LED0
        staa  _DPRB
        ldaa  #%11110111
        staa  _DPRA
        rts

LED_1   ldaa  LED1
        staa  _DPRB
        ldaa  #%11111011
        staa  _DPRA
        rts

LED_2   ldaa  LED2
        staa  _DPRB
        ldaa  #%11111101
        staa  _DPRA
        rts

LED_3   ldaa  LED3
        staa  _DPRB
        ldaa  #%11111110
        staa  _DPRA
        rts


*********************************************************************************
******************************  GLAVNI PROGRAM  *********************************
*********************************************************************************

MAIN    
	ldaa  ENAB
	staa  LED3
	ldaa  DESETB
	staa  LED2
	ldaa  STOB
	staa  LED1
	ldaa  TISOCB
	staa  LED0
         jsr   BRANJE
	jsr   B2BCD
	jsr   WRITE
	jmp   MAIN

	
*********************************************************************************
************************* PISANJE NA LED DISPLAY ********************************
*********************************************************************************

WRITE	ldaa  ENA	rutina, ki na display poslje podatek
	jsr   CHECK
	staa  ENAB	shrani ENAB
	
	ldaa  DESET	rutina, ki na display poslje podatek
	jsr   CHECK
	staa  DESETB	shrani DESETB
	
	ldaa  STO	rutina, ki na display poslje podatek
	jsr   CHECK
	staa  STOB	shrani STOB

	ldaa  TISOC	rutina, ki na display poslje podatek
	jsr   CHECK
	staa  TISOCB	shrani TISOCB

	rts

CHECK	cmpa  #%00000000	subrutina za ugotavljanje, kateri znak naj prikaze
	bne   S1
	ldaa  #%00111111	prikazi 0
	jmp   S

S1	cmpa  #%00000001
	bne   S2
	ldaa  #%00000110
	jmp   S

S2	cmpa  #%00000010
	bne   S3
	ldaa  #%01011011
	jmp   S

S3	cmpa  #%00000011
	bne   S4
	ldaa  #%01001111
	jmp   S

S4	cmpa  #%00000100
	bne   S5
	ldaa  #%01100110
	jmp   S

S5	cmpa  #%00000101
	bne   S6
	ldaa  #%01101101
	jmp   S

S6	cmpa  #%00000110
	bne   S7
	ldaa  #%01111101
	jmp   S

S7	cmpa  #%00000111
	bne   S8
	ldaa  #000000111
	jmp   S

S8	cmpa  #%00001000
	bne   S9
	ldaa  #%01111111
	jmp   S

S9	cmpa  #%00001001
	bne   S
	ldaa  #%01100111

S	rts

*********************************************************************************
************************* PRETVORBA IZ BIN V BCD ********************************
*********************************************************************************

B2BCD	ldaa   MEANL	**** ENICE ****
	anda   #%00001111	zbrisi zg. stiri bite
	cmpa   #%00001010	primerjaj z 9
	bmi    B1	skoci, ce je manjse od 9
	ldaa   MEANL
	adda   #%00000110	pristej 6
	staa   MEANL
	bcc    B1	skoci, ce ni prenosa
	ldab   MEANH	
	addb   #%00000001
	stab   MEANH
B1	anda   #%00001111
	staa   ENA	shrani pod enice

	ldaa   MEANL	**** DESETICE ****
	anda   #%11110000	zbrisi spodnje 4 bite
	cmpa   #%10100000 primerjaj z "9"
	bmi    B2	skoci, ce je manjse od 9
	adda   #%01100000	pristej "6"
	bcc    B2	skoci, ce ni prenosa
	ldab   MEANH
	addb   #%00000001 pristej 1
	stab   MEANH
B2	lsra 		4 x shiftaj v desno
	lsra
	lsra
	lsra
	staa   DESET

	ldaa   MEANH	**** STOTICE ****
	anda   #%00001111	zbrisi zg. stiri bite
	cmpa   #%00001010	primerjaj z 9
	bmi    B3	skoci, ce je manjse od 9
	ldaa   MEANH
	adda   #%00000110	pristej 6
	staa   MEANH
	anda   #%00001111
B3	staa   STO	shrani pod stotice

	ldaa   MEANH	**** TISOCICE ****
	lsra 		4 x shiftaj v desno
	lsra
	lsra
	lsra
	staa   TISOC
	rts
	
*********************************************************************************
******************************** BRANJE Z ADP ***********************************
*********************************************************************************

BRANJE	jsr   BERI
	ldaa  PODL
	adda  VSOTAL      pristej 1 byte k VSOTAL 
	staa  VSOTAL
	ldaa  VSOTAH
	adca  PODH
	staa  VSOTAH
	bcc   C1		skoci, ce ni prenosa
	ldaa  #%00000001	VSOTIC pristej 1, ker je prislo do prenosa
	adda  VSOTAC
	staa  VSOTAC
C1	ldaa  STEVEC	nalozi in preveri, ce je stevec ze 0
	deca
	staa  STEVEC
	bne   BRANJE		ce stevec ni 0, zakljuci 
	jsr   POVP
	ldaa  #$00	nastavi zacetne vrednosti
	staa  VSOTAC
	staa  VSOTAL
	staa  VSOTAH
	ldaa  #%01000000
	staa  STEVEC	
C4	rts	


POVP 	ldaa  VSOTAL	SUBRUTINA za povprecenje rezultata
	lsra		6 x shiftaj v desno
	lsra
	lsra
	lsra
	lsra
	lsra
	staa  VSOTAL	
	ldaa  VSOTAH	
	asla 		2 x shiftaj v levo
	asla		
	adda  VSOTAL	pristej VSOTAL
	staa  MEANL
	ldaa  VSOTAH
	lsra		6 x shiftaj v desno
	lsra
	lsra
	lsra
	lsra
	lsra
	staa  VSOTAH	
	ldaa  VSOTAC	
	asla 		2 x shiftaj v levo
	asla		
	adda  VSOTAH	pristej VSOTAH
	staa  MEANH
	rts


BERI	jsr   CSYES	subrutina za branje enega podatka iz ADP
	ldaa  #%00001011	vpis v kom.reg. in doloci branje iz kom.reg.
	staa  _SPDR
	jsr   ST
	jsr   CSNO

	ldaa  #%00110000
	staa  _DDRD
	jsr   CSYES
	ldaa  #%00000000 	beri SPDR
	staa  _SPDR
	jsr   ST
	jsr   CSNO
	ldaa  #%00111000
	staa  _DDRD	

	ldaa  _SPDR	
	anda  #%11000000	preveri bita DRDY in ZERO
	beq   BERI	skoci na BERI, ce podatki se niso pripravljeni

	jsr   CSYES
	ldaa  #%00111011	nastavi pod. reg. za branje
	staa  _SPDR
	jsr   ST
	jsr   CSNO

	jsr   CSYES	
       	ldaa  #%00000000  beri SPDR
	staa  _SPDR
	jsr   ST
	jsr   CSNO
	ldaa  _SPDR	preberi zg. byte pod. reg.
	anda  #%01111111  prvi bit postavi na 0 ??????
	staa  PODH

	jsr   CSYES
	ldaa  #%00000000	beri SPDR
	staa  _SPDR 	
	jsr   ST
	jsr   CSNO
	ldaa  _SPDR	preberi sp. byte pod. reg. 
	staa  PODL
	rts


**************************************************************************************
************************************  SUBRUTINE  *************************************
**************************************************************************************

ST       ldaa  _SPSR	subrutina, ki preverja, ce je bilo sporocilo uspesno poslano
	bpl   ST		
	rts

CSYES	ldaa  _PORTD	subrutina, enabla ADP 
	anda  #%11011111
	staa  _PORTD
	rts

CSNO	ldaa  _PORTD	subrutina, ki disabla ADP
	eora  #%00100000
	staa  _PORTD
	rts


************************* KERNEL VARIABLES (7 bytes) **************************


SCHPTR  RMB   2           16 bit pointer to current task in SCHTAH.
SCHTST  RMB   1           Test task on exceeding time slice.
TIMH    RMB   1           Hours (0..23),
TIMM    RMB   1           minutes (0..59),
TIMS    RMB   1           seconds (0..59),
TIMF    RMB   1           and fractions (0..255).


************************* DRIVER VARIABLES (100 bytes) ************************


LED0    RMB   1           The four
LED1    RMB   1              digits
LED2    RMB   1              of the
LED3    RMB   1              LED display.
KBDB    RMB   3+8         KBD buffer
KBDE    RMB   2              with a capacity of 8 characters.
KBDKEY  RMB   1           KBD status variable: keypressed?
TRAB    RMB   3+64        SCI transmitting buffer
TRAE    RMB   2              with a capacity of 64 characters.
RECB    RMB   3+8         SCI receiveing buffer
RECE    RMB   2              with a capacity of 8 characters.

        END