
;Scrolling software idea for a 8 x 80bit LED matrix. Through this LED
;matrix a much bigger pixel matrix is scrolled. 

;The pixel matrix contains 8 rows, each 48 bytes wide. The first 10 bytes
;represent the blank information, the remaining 38 bytes represent the
;text to be scrolled.

;From the pixel matrix, stored at address 7168, an 11 byte wide block is
;selected. The first 10 bytes of this block are fully shifted into the
;4096. From the 11th byte only a certain number (represented by "SHIFT"
;(=0..7)) is shifted into the 4094.

;The start address of this block depends on STRT_BYTE (=0..47),ROW_OFS_L,
;ROW_OFS_H (=0,48,96,144...336, by other words =ROW * 48) and the start
;address of pixel matrix (MATRX_STRT_L, MATRX_STRT_H).
;ROW (=0..7) defines the row to be shifted and displayed.

;The actual scroll position is represented by INDEX_L,INDEX_H (=0..383).
;This INDEX is "0", when the blank block is fully shifted into the 4094
;and the text is just not yet visible.

;REFRESH is incremented when a full set of 8 rows has been displayed.
;When REFRESH equals SCRL-RATE, then the display is scrolled by one
;pixel column. This is every 16 * 8 * 950µsec = 0.12sec here, assuming
;11.0592MHz clock speed. Adjust SCRL_RATE to change the scroll speed.




                $NOMOD51
                $INCLUDE (89s52.mcu)


                DATA_OUT        BIT     P1.0
                CLOCK           BIT     P1.1
                STROBE          BIT     P1.2

                ANODE_DRIV      DATA    30H
                INDEX_L         DATA    31H
                INDEX_H         DATA    32H
                REFRESH         DATA    33H
                ROW             DATA    34H
                ROW_OFS_L       DATA    35H
                ROW_OFS_H       DATA    36H
                SHIFT           DATA    37H
                STRT_BYTE       DATA    38H

                SCRL_RATE       EQU      16
                MATRX_STRT_L    EQU     00H 
                MATRX_STRT_H    EQU     1CH


                ORG 0
            
                SJMP Start

                ORG 002BH

Start:          MOV AUXR,#00011001B   ;AT89S52 specific status byte           
                MOV TMOD,#00000001B   ;Configure Timer 0 (Mode 1)
                MOV TH0,#252          ;Set 950µsec
                MOV TL0,#148   
                SETB TR0              ;Start Timer 0
                CLR CLOCK             ;Prepare the first shifting

Initialize:     CLR A                 ;Set registers to "0"    
                MOV STRT_BYTE,A       
                MOV ROW,A
                MOV ROW_OFS_L,A
                MOV ROW_OFS_H,A
                MOV INDEX_L,A
                MOV INDEX_H,A
                MOV REFRESH,A
                MOV SHIFT,A
                MOV ANODE_DRIV,#11111110B   ;Prepare ANODE_DRIV for first
                                            ;row.

Main_loop:      MOV WDTRST,#01EH      ;Feed the watchdog
                MOV WDTRST,#0E1H
                MOV R6,#10            ;10 pixel bytes to be selected and
                                      ;shifted.
                MOV R7,STRT_BYTE      ;Copy STRT_BYTE into R7
                MOV A,MATRX_STRT_L    ;Fabricate the start address of 11
                ADD A,ROW_OFS_L       ;bytes wide block.
                MOV DP0L,A            ;Feed the DPTR with the base address
                MOV A,MATRX_STRT_H    ;and use R7 as a "looping" address
                ADDC A,ROW_OFS_H      ;offset.
                MOV DP0H,A

Get_bytes:      MOV A,R7              ;R7 contains the address offset
                MOV AUXR1,#0          ;89S52 needs DPTR to be defined
                MOVC A,@A+DPTR        ;Fetch the pixel byte

                MOV R5,#8             ;All 8 bits of pixel byte
Shift_loop1:    RLC A                 ;Shift the pixel byte fully into
                MOV DATA_OUT,C        ;the 4094.    
                SETB CLOCK
                CLR CLOCK
                DJNZ R5,Shift_loop1   ;All 8 bits shifted?

                INC R7                ;Address the next pixel byte
                CJNE R7,#48,Repeat    ;If end of pixel matrix is reached,
                MOV R7,#0             ;fetch it from the begin again.

Repeat:         DJNZ R6,Get_bytes     ;First 10 pixel bytes shifted?

                MOV R5,SHIFT          ;Copy SHIFT into R5
                CJNE R5,#0,Last_byte  ;11th pixel byte to be shifted?
                SJMP Wait             ;11th pixel byte need not to be
                                      ;shifted into the 4094.                 
Last_byte:      MOV A,R7              ;R7 addresses the 11th pixel byte
                MOV AUXR1,#0          ;89S52 needs DPTR to be defined
                MOVC A,@A+DPTR        ;Fetch the 11th pixel byte

Shift_loop2:    RLC A                 ;11.pixel byte is partially shifted
                MOV DATA_OUT,C        ;into the 4094. SHIFT represents
                SETB CLOCK            ;the number of bits to be shifted.
                CLR CLOCK              
                DJNZ R5,Shift_loop2    

Wait:           JNB TF0,Wait          ;Timer 0 overrun?
                MOV P0,#255           ;Turn-off the anode drivers
                CLR TR0               ;Stop Timer 0
                CLR TF0               ;Reset timer flag bit (TF0)
                MOV TMOD,#00000001B   ;Configure Timer 0 (Mode 1)
                MOV TH0,#252          ;Set 950µsec
                MOV TL0,#148   
                SETB TR0              ;Start Timer 0
                SETB STROBE           ;Latch the new column data in 
                CLR STROBE            ;the 4094s.
                MOV A,ANODE_DRIV      ;Copy ANODE_DRIV into A
                MOV P0,A              ;Turn-on selected anode driver
                RL A                  ;Prepare ANODE_DRIV for next row
                MOV ANODE_DRIV,A
                INC ROW               ;Prepare next row
                MOV A,ROW_OFS_L       ;Fabricate next ROW_OFS_L/H address
                ADD A,#48
                MOV ROW_OFS_L,A
                MOV A,ROW_OFS_H
                ADDC A,#0
                MOV ROW_OFS_H,A
                MOV A,ROW
                CJNE A,#8,Go_back     ;All 8 rows shifted?
                CLR A                 ;8 rows shifted, so reset ROW
                MOV ROW,A             ;and ROW_OFS_L/H
                MOV ROW_OFS_L,A
                MOV ROW_OFS_H,A
                INC REFRESH           ;and increment REFRESH.
                MOV A,REFRESH
                CJNE A,SCRL_RATE,Go_back    ;Time to scroll?
                SJMP Prepare_scroll

Go_back:        LJMP Main_loop        ;Jump back and shift the next row

Prepare_scroll: MOV REFRESH,#0        ;Reset REFRESH
                MOV A,INDEX_L         ;Increment INDEX_L/H
                ADD A,#1
                MOV INDEX_L,A
                MOV A,INDEX_H
                ADDC A,#0
                MOV INDEX_H,A
                INC SHIFT             ;Increment SHIFT
                MOV A,SHIFT
                CJNE A,#8,Go_back     ;SHIFT to be reseted?
                MOV SHIFT,#0          ;Reset SHIFT and
                INC STRT_BYTE         ;increment STRT_BYTE.
                MOV A,INDEX_L         ;INDEX_L/H = 384?
                CJNE A,#128,Go_back   ;No,so go back and shift next row
                MOV A,INDEX_H
                CJNE A,#1,Go_back
                LJMP Initialize       ;INDEX_L/H = 384,so initialize and
                                      ;start all over again.


                org 7168

                DB 0,0,0,0,0,0,0,0,0,0   ;Uppermost row of pixel matrix
                DB 255,255,255,255,255   ;"0" represents the blank pixels,
                DB 255,255,255,255,255   ;"255" the character pixels.
                DB 255,255,255,255,255
                DB 255,255,255,255,255   ;Each row contains 48 bytes
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255
                DB 0,0,0,0,0,0,0,0,0,0   ;2.row of pixel matrix
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255
                DB 0,0,0,0,0,0,0,0,0,0   ;3.row of pixel matrix
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255
                DB 0,0,0,0,0,0,0,0,0,0   ;4.row of pixel matrix
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255
                DB 0,0,0,0,0,0,0,0,0,0   ;5.row of pixel matrix
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255
                DB 0,0,0,0,0,0,0,0,0,0   ;6.row of pixel matrix
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255
                DB 0,0,0,0,0,0,0,0,0,0   ;7.row of pixel matrix
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255
                DB 0,0,0,0,0,0,0,0,0,0   ;8.row of pixel matrix
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255,255,255
                DB 255,255,255


                end

