;                          test_7seg.asm

;To demonstrate controlling the two 7 Segment displays
;on the 6502 MP Kit.
; Changes by Jeff Rosengarden
; 22-OCT-2018



;assembler directives
  .LOCALLABELCHAR "?"

;MAIN CONSTANTS 
PORT1   = $8002       ;74HC573 for common cathode pins (U12 in circuit)
PORT2   = $8003       ;74HC573 for digits (U11 in circuit)
STALL1  = $0005       ;timing counter #1 (inner loop)
STALL2  = $0006       ;timing counter #2 (outer loop)
STALL3  = $0007       ;timing counter #3 (Master loop - approx seconds)

TBL     = $0008       ;SEGTAB address LSB,MSB (for indirect addressing)

;U12 (74HC573 data latch) pin assignments
;for 7 Segment common cathode lines
SEG1D1  = %10011111   ;PC5 
SEG1D2  = %10101111   ;PC4
SEG1D3  = %10110111   ;PC3
SEG1D4  = %10111011   ;PC2
SEG2D1  = %10111101   ;PC1
SEG2D2  = %10111110   ;PC0



;       EXECUTION BEGINS AT ADDRESS $0200
;
;         +++
    *= $0200

;sample code from work book 
;to work with SEG2D4
;requires a jumper between Pin #1 & Pin #2 on J2  
;     LDA #$BF
;     STA PORT1

;LOOP:  LDA #$3F
;     STA PORT2
;     JSR DELAYON
;     LDA #%00000000
;     STA PORT2
;     JSR DELAYOFF
;     JMP LOOP


START:  JSR TSTSEG
        BRK
  
;Test routine to display all characters on 7Seg Display 
;in rolling left fashion
    
TSTSEG: CLD             ;always CLD before starting

        LDA #$03        ;STALL3 is the approx seconds counter
                        ;change this value for longer/shorter delays
                        ;of the displayed characters
        STA STALL3
        LDX #$00        ;clear out X Reg
        LDY #$FF        ;start our table offset with $FF
        STY STALL2      ;STALL2 is the outer loop counter
        
        LDA #$84        ;stuff our 7 segment char tbl (SEGTAB) address
        STA TBL         ;into TBL (LSB) and TBL+1 (MSB)
        LDA #$02        ;for indirect address access into the table
        STA TBL+1
        
        
LOOP:   INY             ;increment table offset
        LDA (TBL),Y     ;load 1st character indirectly
        TAX             ;transfer it to the X Reg
        LDA SEG,Y       ;7Seg digit to display it on
        JSR COUT        ;go display it

        CPY #$05        ;is Y Reg = 5 ??
                        ;   have we lit up all 6 digits?
        BNE LOOP        ;NO - go display next character

        JMP STALL       ;YES - so now we stall so you can see it

;STALL routine consists of 
; 1) Master (approx seconds) counter of STALL3
; 2) Outer loop (from $FF to $00) of STALL2
; 3) Inner loop (from $FF to $00) of STALL1             
STALL:  LDY #$FF        ;reset table offset for next loop

        DEC STALL2      ;decrement outer loop
        BEQ FIN         ;outer loop = 0 ??
S1:     LDA #$FF        ;NO  
        STA STALL1      ;reload inner loop
S1A:    DEC STALL1      ;decrement inner loop
        BNE S1A         ;inner loop <> 0 ??
                        ;YES -decrement it again
        JMP LOOP        ;NO - light up digits again
        
FIN:    DEC STALL3      ;dec master counter 
        BEQ FIN1        ;master counter = 0 yet??
        LDA #$FF        ;NO - reload outloop with $FF
        STA STALL2
        JMP LOOP        ;light up digits again
        
FIN1:   LDA #$03        ;reload master counter
        STA STALL3
        LDX #$00        ;clear out X Reg
        LDY #$FF        ;start our table offset with $FF
        STY STALL2      ;reload our outer loop
        
        INC TBL         ;increment our 7Seg table address by 1
        LDA #$8F        
        CMP TBL         ;have we displayed 0-F yet?   
        BNE LOOP        ;NO - go light 'em up but starting
                        ;   one character higher in table
        RTS             ;YES - we're done get out of dodge    


;delay routines for PWM (pulse width modulation) 
;to control brightness of 7SEG display
;Ratio between ON and OFF can be adjusted 
;with the value in the Y register.
;Currently it's a 1:10 ratio (10%)
DELAYON:  LDY #1        
DELAY2:   DEY
          BNE DELAY2
          RTS
          
DELAYOFF: LDY #10
DELAY3:   DEY
          BNE DELAY3
          RTS
          
;7Segment Handling Routines (using PWM)
          
DIGONOFF: JSR DELAYON         ;run the DELAYON loop
          LDA #%00000000      ;turn the segment off
          STA PORT2
          JSR DELAYOFF        ;run the DELAYOFF loop
          RTS
          
          
;cout requires Segment control value in Accum
;     requires char to display in X Reg         
COUT:     STA PORT1           ;indicate which digit to activate
          TXA
          STA PORT2           ;indicate which character to display
          TYA
          PHA                 ;push current Y Reg value to stack
          JSR DIGONOFF        ;turn digit on & off using PWM
          PLA
          TAY                 ;restore our Y Reg value from stack
          RTS                 ;we're done - get out of dodge


      
;DATA SEGMENT
;
;         Dig1 Dig2 Dig3 Dig4 Dig5 Dig6
SEG .byte $9F, $AF, $B7, $BB, $BD, $BE

SEGTAB: ;7 segment bit patterns for character display 
  .BYTE 0BDH    ;'0'
  .BYTE 030H    ;'1'
  .BYTE 09BH    ;'2'
  .BYTE 0BAH    ;'3'
  .BYTE 036H    ;'4'
  .BYTE 0AEH    ;'5'
  .BYTE 0AFH    ;'6'
  .BYTE 038H    ;'7'
  .BYTE 0BFH    ;'8'
  .BYTE 0BEH    ;'9'
  .BYTE 03FH    ;'A'
  .BYTE 0A7H    ;'B'
  .BYTE 08DH    ;'C'
  .BYTE 0B3H    ;'D'
  .BYTE 08FH    ;'E'
  .BYTE 00FH    ;'F'
  

  .END
  
  
  