;       BANER.SBR
;       VER 1.0         8510.20
;
;       ALLOWS USER TO MAKE A SCROLLING BANNER ON SCREEN
;
;       PROPRIETARY PROGRAM MATERIAL
;
;       THIS MATERIAL IS THE PROPERTY OF JEFF STUYVESANT,
;       12307 PACIFIC AVE, APT 2,MAR VISTA, CALIF. ,90066
;       PERMISSION TO COPY AND USE IS GRANTED FOR
;       NON-PROFIT USES ONLY.
;
;       Copyright (c) 1985 JEFF STUYVESANT


       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM

       OBJNAM .SBR

       RADIX 8.


VMAJOR  =       1.
VMINOR  =       0.
VSUB    =       0.
VEDIT   =       0.
VWHO    =       0.

;EQUATES
       ADRWIN  =4
       ADRLOP  =16
       ADRDLY  =30
       ADRSTR  =42
       OFFLEN  =4

       PHDR    -1,0,PH$REE!PH$REU

; BASIC PARAMETER MEMORY LAYOUT

;BASE:  WORD    4.              ; 0(A3)         PARAMETERS IN LIST (TOTAL)

       ; WINDOW SIZE
;       WORD    6.              ; 2(A3)         FIRST PARAMETER                 ; TYPE
;       LWORD   0               ; 4(A3)                                         ; ABS ADDR IN MEMORY
;       LWORD   2.              ;10(A3)                                         ; LENGTH IN BYTES

       ; NUMBER OF LOOPS
;       WORD    6.              ;14(A3)         SECOND
;       LWORD   0               ;16(A3)
;       LWORD   2.              ;22(A3)

       ; RELITIVE DELAY
;       WORD    6.              ;26(A3)         THIRD
;       LWORD   0               ;30(A3)
;       LWORD   2.              ;34(A3)

       ; STRING
;       WORD    2.              ;40(A3)         FORTH
;       LWORD   0               ;42(A3)
;       LWORD   LENGTH          ;46(A3)


START:  CMPW    @A3,#4                          ; VERIFY 4 PARAMETERS
       BEQ     BEGIN
       TYPE    <Insuficient parameters >
       JMP     ERR$

BEGIN:
       MOV     ADRSTR(A3),A1                   ; GET ADR TO STRING ->A1
       MOV     ADRSTR+OFFLEN(A3),D3            ; GET MAX LENGTH ->D3
       BNE     10$                             ; IF EQ=0 ERROR
05$:    MOVB    #4,D1                           ; PARAMETER # IN ERROR
       JMP     ERROR$                          ; ERROR PROCESS RTN

10$:    SUBW    #1,D3                           ; SUB ONE FOR ZEROED CASE

20$:    CMPB    0(A1)[~D3],#0                   ; CMP BYTES @ STRING BASE +D3 (DECREASING #)
       DBNE    D3,20$                          ; IF EQ 0 THEN LOOP
       TSTW    D3                              ; IS TRUE STRING LENGTH=0
       BEQ     05$                             ; IF NOT 0 CONTINUE

       MOV     A1,A4                           ; MOV BASE TO A4
       ADD     D3,A4                           ; CALC STRING END ADDR ->A4

; SET UP REGISTRERS

SETUP:
       MOV     ADRWIN(A3),A2                   ; GET ADDR OF WINDOW LENGTH

       CMPW    D3,@A2                          ; CMP STRING LENGTH TO WINDOW LENGTH
       BGE     10$                             ; IF STRING LARGER(D3) -- OK
05$:    MOVB    #1,D1                           ; WIN LENGTH LARGER NO GOOD / MOV PARAMETER # ->D1
       JMP     ERROR$

10$:    CLR     D5                              ; PRE-CLEAR
       MOVW    @A2,D5                          ; GET WINDOW LENGTH ->D5
       BEQ     05$                             ; IF WIN SIZE=0 NO GOOD
       CMPW    D5,#78.                         ; MAX SIZE=78
       BGT     05$                             ; IF WIN SIZE>78 -->05$

       MOV     ADRLOP(A3),A2                   ; GET ADDR OF LOOP COUNT
       CLR     D3                              ; PRE-CLEAR
       MOVW    @A2,D3                          ; MOV ->D3
       BNE     20$                             ; IF #0 -->20$
       MOVB    #2,D1                           ; =0 NO GOOD / MOV PARAMETER # ->D1
       JMP     ERROR$

20$:    MOV     ADRDLY(A3),A2                   ; GET ADDR OF RELATIVE DELAY AMOUNT
       CLR     D0                              ; PRE-CLEAR
       MOVW    @A2,D0                          ; MOV ->D0
       BNE     30$                             ; IF #0 -->30$
25$:    MOVB    #3,D1                           ; =0 NO GOOD / MOV PARAMETER #->D1
       JMP     ERROR$

; THE BELOW CALCS A DELAY FACTER RESLITVE TO THE NUMBER OF CHARACTERS
; IN THE ACTUAL STRING

30$:    CMPW    D0,#100.                        ; MAX 100 RELATIVE SCROLL SPEED
       BGT     25$

       MOVW    #324.,D1                        ; SET BASE NUMBER
       MOVW    D5,D2                           ; SAVE # OF CHARACTERS
       MUL     D2,#4.                          ; MUL #23
       SUBW    D2,D1                           ; CALC RELATIVE VALUE
       MUL     D0,#15.                         ; CALC DELAY RELATIVE FACTOR
       ADDW    D1,D0                           ; CALC ACTUAL DELAY AS CLOCK TICKS
       MOV     A1,A2                           ; SET SHIFTING STRING BASE= CONSTANT STRING BASE

; THIS SECTION DOSE THE WORK
; TO START
;       A0= TEMP WORK REGISTER                  D0= DELAY (CLOCK TICKS)
;       A1= STRING BASE ADDR (CONSTANT)         D1= CHARACTER TO BE OUTPUT
;       A2=   "     "    "   (SHIFTING)         D2= CHARACTERS TO OUTPUT (QTY)
;       A3= PARAMETER BASE ADDR                 D3= LOOP COUNT
;       A4= STRING END ADDR                     D4= TEMP WORK REGISTER
;       A5=                                     D5= WINDOW LENGTH


PARTA:  MOV     A4,D2                           ; COPY STR END
       ADD     #1,D2                           ; ADD 1 FOR ZERO RELATIVE
       SUB     A2,D2                           ; CALC CHARACTERS LEFT IN STRING
       CMP     D5,D2                           ; CMP W/WINDOW SIZE
       BGE     10$                             ; IF WIN SIZE>CHAR LEFT
       MOV     D5,D2                           ; FORCE (WINDOW LENGTH) CHARACTERS OUTPUT ->D2

10$:    MOV     A2,A0                           ; SET A0=ADDR OF FIRST CHAR TO BE OUTPUT FOR SBR CALL
       MOV     D2,D4                           ; SET D4=CHAR COUNT FOR SBR CALL
       CALL    TYPWIN                          ; CALL SBR TO OUTPUT STRING
       CMP     D2,D5                           ; TEST FOR PARTIAL WINDOW PRINTED (IE CHAR OUTPUT< WINDOW SIZE)
       JGE     LOPEND                          ; IF GT OR EQ DO NEXT

; ONLY A PARTIAL WINDOW WAS OUTPUT NOW OUTPUT THE REST (WHICH IS AT THE BEGINING OF THE STRING)

       MOV     D5,D4                           ; GET COPY OF TRUE WINDOW LENGTH ->D4
       SUB     D2,D4                           ; SUBTRACT QTY OF CHAR ALREADY OUTPUT
                                               ; ->D4 =QTY OF CHAR REMAINING TO BE OUTPUT
       MOV     A1,A0                           ; SET A0=ADDR OF FIRST CHAR TO BE OUTPUT FOR SBR CALL
       CALL    TYPWIN                          ; CALL SBR TO OUTPUT STRING

LOPEND: CTRLC   ALLOVR                          ; TEST FOR ^C
       SLEEP   D0                              ; SLEEP FOR CLOCK TICKS IN D0
       CALL    BACKUP                          ; SBR TO POSITION CURSOR AT BEGINING OF WINDOW
       INC     A2                              ; INC SHIFTING STR BASE ADDR
       CMP     A2,A4                           ; CMP NEW TEMP BASE ADDR W/ STR END ADDR
       BLE     PARTA                           ; IF NEW STR BASE<=STR END DO IT AGAIN

RESET:  DEC     D3                              ; DEC LOOP COUNT
       BLE     ALLOVR                          ; IF LOOP COUNT=0 WE'RE FINISHED
       MOV     A1,A2                           ; RESET SHIFTING BASE=TRUE STRING BASE
       BR      PARTA                           ; DO ANOTHER LOOP

ALLOVR: RTN                                     ; WE ARE FINISHED GO BACK TO BASIC

; SBR TO OUTPUT A STRING INDEXED

WINLOP: MOVB    (A0)+,D1                        ; MOV CHAR TO BE OUTPUT TO D1
       TOUT                                    ; SPIT IT OUT
TYPWIN: DBF     D4,WINLOP                       ; DEC BRANCH COUNT / FINISH IF =0
       RTN                                     ; GO BACK

; SBR TO BACKUP TO BEGINING OF STRING

BACKUP: MOV     D5,D2                           ; SET BACKUP COUNT ->D2
       SUB     #1.,D2                          ; PRE-DEC FOR DBF

10$:    TTYI                                    ; OUTPUT #8 DECIMAL (BACKSPACE)
       BYTE    8.,0
       EVEN
       DBF     D2,10$                          ; DEC BRANCH COUNT / FIN IF =0
       RTN

       ASCII   / Copyright (c) 1985 JEFF STUYVESANT/
       EVEN

; ERROR PRINTING RTN

ERROR$: TYPE    <Parameter #>
       DCVT    0,OT$TRM!OT$LSP!OT$TSP          ; OUTPUT PARAMETER # AS DECIMAL W/LEAD SP & TRAIL SP
       TYPE    <is in ERROR>
ERR$:   SLEEP   #10000.                         ; INSURE THEY WILL SEE THIS MESSAGE
       RTN

       END