PORTA = $6001 DDRA = $6003 T1LCL = $6004 T1LCH = $6005 ACR = $600b PCR = $600c IFR = $600d IER = $600e SER = %00000001 RCLK = %00000010 SRCLK = %00000100 INTERVAL = 33 ; increase counter 3 times per scond CURRENT = $0 ; current counter VISIBLE = $1 ; visible counter (as last printed to the 7-segment display) TICKS = $2 ; internal ticks counter (on overflow increment counter) .org #$f800 reset: sei ; disallow interrupts during initialization ldx #$FF ; initialize call stack to $1FF txs lda #%11000010 ; enable CA1 and timer1 interrupts sta IER lda #$0 ; negative edge triggering sta PCR lda ACR and #$7F ora #%01000000 ; setup timer for free running timer1, no PB7 sta ACR lda #%00000111 ; set output on 7seg control pins of PORTA sta DDRA lda #$0 ; initialize 8-bit counter and tick counter sta CURRENT lda #$FF ; the visible counter is different at init, so we force sta VISIBLE ; the drawing of the initial value lda #INTERVAL sta TICKS lda ACR lda #$0F ; initialize counter of VIA timer1 ($270f = 9999 at 1MHz) sta T1LCL lda #$27 sta T1LCH cli ; allow interrupts now mainloop: ; main loop, just print value of counter sei lda CURRENT cmp VISIBLE cli beq mainloop jsr print7seg ; update value sei lda CURRENT sta VISIBLE cli jmp mainloop print7seg: ldy #$8 ; 8 bits to shift loop7seg: rol a bcc zerobit ; C=0, bang a zero to SER onebit: ldx #(SER) ; C=1, bang a one to SER stx PORTA ldx #(SER | SRCLK) stx PORTA ldx #(SER) stx PORTA jmp next zerobit: ldx #$0 ; C=0, bang a zero to SER stx PORTA ldx #SRCLK stx PORTA ldx #$0 stx PORTA jmp next next: dey bne loop7seg rol a ; restore A register output: ldx #0 ; bang RCLK to store output in latch stx PORTA ldx #RCLK stx PORTA ldx #0 stx PORTA rts nmi: rti irq: pha txa pha tya pha bit T1LCL ; clear timer1 interrupt bit PORTA ; clear CA1 interrupt dec TICKS bne irq_done lda #INTERVAL sta TICKS inc CURRENT ; increment internal counter irq_done: pla tay pla tax pla cli rti .org #$fffa .word nmi .word reset .word irq