TOY - A program initially written by Oleg Saffuilin


A small program

Oleg Saffiulin has written a small RSX-11M programm, TOY, that can read the TOY and display the result read from the DS1215. I have added the ability to set the DS1215 with the current time of system.

In theory the TIM command from RSX-11M is able to do that itself. But it disables all access to the Additional Status Register and the functions of the RTC if it does not recognise the CPU as a KDJ1E. Initially my CPU board identifies itself as a KDJ1A to the operating system. Unfortunately my CPU card from my PDP-11/Hack required some hardware modifications before it would announce itself as a KDJ11E. Therefore I decided to add the missing code for the /SETTOY switch to Oleg’s program and test if at least I could read and set the RTC with my own tools.

For the beginning I used my version of Oleg’s TOY to make use of the RTC. I modified the STARTUP.CMD so it calls my version of TOY and proposes the time returned by TOY as the default, when asking for the current date and time. Here is the modified section of the original STARTUP.CMD created during SYSGEN.

.; See if the system has a known TOY clock

.;      .SETF $TOY
.;      .PARSE <FMASK> "," FMX FMX FMX FMX HFMSK FMX
.;      .SETN TEMPN 'HFMSK'
.;      .SETN TEMPN TEMPN&1400
.;      .SETS TEMPS "(HH:MM DD-MMM-YYYY)"
.;      .IF TEMPN EQ 0 .GOTO ASKTIM
        .ENABLE QUIET
.;      TIM /SYNC
        RUN TOY/CMD="TOY /SYNCHRONIZE"
        .DISABLE QUIET
        .IF <EXSTAT> NE 1 .GOTO ASKTIM
        .PARSE <TIME> ":" HH MM SS
        .SETS TEMPS "(Default:'<DATE4>' 'HH':'MM')"
        .SETT $TOY

.ASKTIM:
        .ASKS $TIME Please enter time and date 'TEMPS'
        .IFT $TOY .IF <STRLEN> EQ 0 .GOTO SETIME
        .IF <STRLEN> < 12 .GOTO ASKTIM
        TIME '$TIME'
        .IF <EXSTAT> <> <SUCCES> .GOTO ASKTIM
.SETIME:

You can use my version of TOY to set the RTC to the current system time using the command TOY /SETTOY. What is missing is that I write a version for other operating systems, like RT-11, to take advantage of the RTC. Here you can see the startup dialog of my PDP-11/Hack and you can see that the STARTUP.CMD proposes the time returned by TOY (not visible of course)

@173000g
$DL2


RSX-11M-PLUS V4.6  BL87   512.KW  System:"HACK11"
>RED DL2:=SY:
>RED DL2:=LB:
>RED DL2:=SP:
>MOU DL2:"HACK11"
@DL2:[1,2]STARTUP
>
>;                      PLEASE NOTE
>;
>;      If you have not yet read the system release notes, please do so
>;      now before attempting to perform a SYSGEN or to utilize the new
>;      features of this system.
>;
>;
SET -- Inquire cannot determine terminal type 
>;
>; Please ignore any random characters that may have printed on your
>; terminal just now.  They came from a SET /INQUIRE=TI: command.
>; Evidently your terminal does not recognize escape sequences.
>; This will not affect the running of this command file.
>;
>* Please enter time and date (Default:10-AUG-2019 18:48) [S]: 
>ACS SY:/BLKS=1024.
>CON ONLINE ALL
>ELI /LOG/LIM
>CLI /INIT=DCL/CTRLC/DPR="<15><12>/$ /"
>INS LB:[1,1]RMSRESAB.TSK/RON=YES/PAR=GEN
>INS LB:[1,1]RMSLBL.TSK/RON=YES/PAR=GEN
>INS LB:[1,1]RMSLBM.TSK/RON=YES/PAR=GEN
>INS $QMGCLI
>INS $QMGCLI/TASK=...PRI
>INS $QMGCLI/TASK=...SUB
>QUE /START:QMG
>INS $QMGPRT/TASK=PRT.../SLV=NO
>QUE LP0:/CR/NM
>START/ACCOUNTING
>CON ESTAT LP0:
>QUE BAP0:/BATCH
>QUE BAP0:/AS:BATCH
>@ <EOF>
>

The following is the complete source code of TOY.MAC, a single file.

        .TITLE  TOY -- TOY CLOCK UTILITY

        .IDENT  /V02.10/

;
; COPYRIGHT (C) 2005 BY OLEG SAFIULLIN <form@pdp-11.org.ru>
; ALL RIGHTS RESERVED
;
; REDISTRIBUTION AND USE IN SOURCE AND BINARY FORMS, WITH OR WITHOUT
; MODIFICATIONS, ARE PERMITTED PROVIDEDTHAT THE FOLLOWING CONDITIONS
; ARE MET:
;   1. REDISTRIBUTION OF SOURCE CODE MUST RETAIN THE ABOVE COPYRIGHT
;      NOTICE,  THIS LIST OF CONDITIONS AND THE FOLLOWING DISCLAIMER
;      UNMODIFIED.
;   2. REDISTRIBUTIONS IN  BINARY  FORM  MUST  REPRODUCE  THE  ABOVE
;      COPYRIGHT NOTICE, THIS LIST OF CONDITIONS AND  THE  FOLLOWIN
;      DISCLAIMER  IN  THE  DOCUMENTATION  AND/OR  OTHER  MATERIALS,
;      PROVIDED WITH THE DISTRIBUTION.
;
; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS-IS" AND ANY EXPRESS O
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
; ANY   DIRECT,   INDIRECT,   INCIDENTAL,   SPECIAL,  EXEMPLARY,  OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  PROCUREMENT
; OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
; BUSINESS  INTERRUPTION)  HOWEVER  CAUSED  AND  ON  ANY  THEORY  OF
; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  IN
; ANY WAY OUT OF THE USE THIS  SOFTWARE,  EVEN  IF  ADVISED  OF  THE
; POSSIBILITY OF SUCH DAMAGE.
;
;
; 2018-04-13    Peter Schranz add code to support /SETTOY
; 2018-04-22    Add Day Calculation for /SETTOY
;

;
; The command line syntax can be one of the following:
;
; >TOY [/SYNCHRONIZE][/PRINT][/QUIET]
; >TOY [/SETTOY][/PRINT][/QUIET]
;
; Switches may be abbreviated.
;       /PRINT
;               - print TOY clock time and date
;       /QUIET
;               - do not display 'device not available' message
;       /SETTOY (P)
;               - set TOY clock from the system time and date
;       /SYNCHRONIZE (P)
;               - set system date and time from TOY clock
;-

TOYASR  ==      177526

LUN.TI  ==      1
EFN.TI  ==      1

S.PRN   =       1
S.QET   =       2
S.SET   =       4
S.SYN   =       10

        .MCALL  DIR$,EXIT$S,EXST$S,GMCR$,GTIM$S
        .MCALL  QIOW$,STIM$S,TCBDF$,UCBDF$

        TCBDF$
        UCBDF$  ,,TTDEF

        .IF     DF,R$$MPL
        .MCALL  GIN$S
        .IFF
        .MCALL  GTSK$S,SVTK$S
        .ENDC

QIOW:   QIOW$   IO.WVB,LUN.TI,EFN.TI,,,,<BUFF,,40>
GMCR:   GMCR$
BUFF    =       GMCR+G.MCRB

PRIV:   .WORD   0
NDEV:   .WORD   0

SWFLG:  .WORD   0
TOYBUF: .WORD   35305,56243,35305,56243
TOYWRT: .WORD   0,0,0,0
TIMBUF: .BLKW   8.

        .IF     DF,R$$MPL
EXEVEC: .WORD   0
TKTCB:  .WORD   $TKTCB
SGFIN:  .WORD   $SGFIN
EXEVCL  =       <.-EXEVEC>/2
        .ENDC

TOYEP::
        .IF     DF,R$$MPL
        GIN$S   #GI.VEC,#EXEVEC,#EXEVCL
        BCC     5$
        MOV     #ETRAN,R2
        JMP     ERROR
5$:     MOV     @TKTCB,R0
        .IFF
        SVTK$S  #1$,#2
Ox      BR      2$
1$:     .WORD   5$,5$
2$:     MOV     $TKTCB,R0

        .IF     DF,M$$MGE
        CMP     #120000,R0
        BLOS    5$
        .ENDC

        GTSK$S  #BUFF
        CMP     T.NAM(R0),BUFF
        BNE     5$
        CMP     T.NAM+2(R0),BUFF+2
        BNE     5$
        SVTK$S
        BR      10$

5$:     MOV     #EWSTB,R2
        JMP     ERROR
        .ENDC

10$:    CALL    $SWSTK,GTCMD

        .IF     DF,M$$MUP
        MOV     T.UCB(R0),R0
20$:    CMP     U.RED(R0),R0
        BEQ     25$
        MOV     U.RED(R0),R0
        BR      20$
25$:    BIT     #U2.PRV,U.CW2(R0)
        BEQ     30$
        .ENDC

        INC     PRIV

        .IF     DF,R$$MPL
30$:    CALL    @SGFIN
        .IFF
30$:    CALL    $SGFIN
        .ENDC

        TST     @#TOYASR
        ROL     NDEV
        RETURN

GTCMD:  DIR$    #GMCR
        BCS     DOTOY
        MOV     #GMCR+G.MCRB,R5
        MOV     R5,R0
        ADD     $DSW,R0
        CLRB    @R0
10$:    TSTB    @R5
        BEQ     DOTOY
        CMPB    #'/,@R5
        BEQ     CMPSW
        CMPB    #' ,(R5)+
        BNE     10$
20$:    TSTB    @R5
        BEQ     DOTOY
        CMPB    #' ,(R5)+
        BEQ     20$
        DEC     R5

CMPSW:  CMPB    #'/,(R5)+
        BEQ     20$
10$:    MOV     #ESYNT,R2
        BR      ERROR
20$:    MOV     #SWLST,R0
30$:    MOV     R5,R4
        CLR     R2
        MOV     (R0)+,R1
        BNE     40$
        MOV     #EINVL,R2
        BR      ERROR
40$:    MOVB    (R1)+,R3
50$:    TSTB    @R4
        BEQ     60$
        CMPB    #'/,@R4
        BEQ     60$
        CMPB    #' ,@R4
        BHIS    10$
        CMPB    (R4)+,(R1)+
        BNE     30$
        INC     R2
        BR      50$
60$:    TST     R2
        BEQ     10$
        CMPB    R3,R2
        BLE     70$
        MOV     #EAMBG,R2
        BR      ERROR
70$:    BIS     @R0,SWFLG
        MOV     R4,R5
        TSTB    @R5
        BNE     CMPSW

DOTOY:  MOV     SWFLG,R3
        BIT     #<S.SET!S.SYN>,R3
        BEQ     20$
        TST     PRIV
        BNE     10$
        MOV     #EPRIV,R2
        BR      ERROR
10$:    MOV     R3,R0
        BIC     #^C<S.SET!S.SYN>,R0
        CMP     #<S.SET!S.SYN>,R0
        BNE     20$
        MOV     #ECNFL,R2
        BR      ERROR
20$:    TST     NDEV
        BEQ     30$
        BIT     #S.QET,R3
        BNE     EXERR
        MOV     #ENDEV,R2
        BR      ERROR
30$:    BIT     #S.SET,R3
        BNE     DOSET
        CALL    RDTOY
        BIT     #S.SYN,R3
        BNE     DOSYN
        BIT     #S.PRN,R3
        BNE     DOPRN
        BIT     #S.QET,R3
        BNE     EXSUC
        BR      DOPRN

DOSYN:  STIM$S  #TIMBUF
        BCC     10$
        MOV     #ESTIM,R2
        BR      ERROR
10$:    BIT     #S.PRN,R3
        BEQ     EXSUC

DOPRN:  MOV     #BUFF,R0
        MOV     #TIMBUF+S.TIHR,R1
        MOV     #3,R2
        CALL    $TIM
        MOVB    #' ,(R0)+
        MOV     #TIMBUF,R1
        CALL    $DAT
        SUB     #2,R0
        MOV     TIMBUF,R1
        ADD     #1900.,R1
        CLR     R2
        CALL    $CBDMG
        CALL    INSDAY
        CALL    PRNT3
        BR      EXSUC

DOSET:  CALL    WRTOY
        BR      EXSUC

ERROR:: MOV     #BUFF,R0
        MOV     #EPREF,R1
        CALL    MOVEZ
        MOV     R2,R1
        CALL    PRNT2
EXERR:: EXST$S  #EX$ERR
EXSUC:: EXIT$S
;
;
;
PRX2:   MOVB    #',, (R0)+
        MOVB    #' , (R0)+
PRX1:   MOVB    (R4)+, R1
        MOV     R1, R2
        ASR     R2
        ASR     R2
        ASR     R2
        ASR     R2
        BIC     #177760, R1
        BIC     #177760, R2
        BIS     #'0, R1
        BIS     #'0, R2
        MOVB    R2, (R0)+
        MOVB    R1, (R0)+
        RETURN



PRX:    MOV     #BUFF, R0
        MOV     #TOYWRT, R4
        CALL    PRX1

        CALL    PRX2
        CALL    PRX2
        CALL    PRX2
        CALL    PRX2
        CALL    PRX2
        CALL    PRX2
        CALL    PRX2

        JMP     PRNT3
;
;
;
INSDAY: MOVB    TOYBUF+2, R2
        BIC     #177770, R2
        ASL     R2
        MOV     DAYPTR(R2), R2
10$:    MOVB    (R2)+, (R0)+
        BNE     10$
        RETURN
;
; Write the current time to the phantom clock chip
;
WRTOY:  GTIM$S  #TIMBUF
        CLRB    TOYWRT                  ; 10ths and 100ths of second = 0
        MOV     TIMBUF+10., R0
        CALL    B2BCD
        MOVB    R0, TOYWRT+1            ; Seconds in BCD
        MOV     TIMBUF+8., R0
        CALL    B2BCD
        MOVB    R0, TOYWRT+2            ; Minutes in BCD
        MOV     TIMBUF+6, R0
        CALL    B2BCD
        MOVB    R0, TOYWRT+3            ; Hours in BCD
;
;
;
        MOV     TIMBUF+G.TIYR, R0       ; Get Year
        MOV     TIMBUF+G.TIMO, R1       ; Get Month
        SUB     #3, R1                  ; March=0
        BPL     110$                    ; If PL leap day of this year
        DEC     R0                      ; is over, else don't consider 
110$:   MOV     R0, R2
        ASR     R0                      ; this year. Divide by 4
        ASR     R0
        ADD     R2, R0
        MOVB    DAYMON(R1), R1
        ADD     R1, R0
        ADD     TIMBUF+G.TIDA, R0       ; Add date
        ADD     #4, R0                  ; 01.03.1900 was thursday
        DEC     R0                      ; Compensate 1 
120$:   SUB     #7, R0
        BPL     120$
        ADD     #8., R0                 ; subtracted 7 once to much and
        MOVB    R0, TOYWRT+4            ; DS1215 starts with 1=sunday
;       CLRB    TOYWRT+4                ; Day of week should be calculated
        MOV     TIMBUF+4, R0
        CALL    B2BCD
        MOVB    R0, TOYWRT+5            ; Day of Month
        MOVB    TIMBUF+2, R0
        CALL    B2BCD
        MOVB    R0, TOYWRT+6            ; Month
        MOV     TIMBUF, R0
        CALL    B2BCD
        MOVB    R0, TOYWRT+7            ; Year

;       CALL    PRX

        CALL    $SWSTK, 99$
        MOV     #TOYASR+1, R5
        MOV     #TOYBUF, R4

        MOV     #1, R3
        MOV     #4, R2
        MOVB    (R5), R0
10$:    ASR     R0                      ;
        ASR     (R4)                    ; Get Bit from pattern
        ROL     R0                      ; Into bit 0 of R0
        MOVB    R0, (R5)                ; Write to DS1215
        ASL     R3                      ; Word done
        BCC     10$                     ; no
        ROL     R3                      ; Make r3 = 1 again
        TST     (R4)+                   ; Advance pointer
        SOB     R2, 10$

        MOV     #TOYWRT, R4
        MOV     #8., R2                 ; Byte Counter
20$:    MOV     #8., R3                 ; Bit Counter
        MOVB    (R4)+, R0
30$:    MOVB    R0, (R5)
        ROR     R0
        SOB     R3, 30$
        SOB     R2, 20$
99$:    RETURN

        MOV     TOYWRT+2, R0
        MOV     TOYWRT+4, R1
        MOV     TOYWRT+6, R2
        MOV     #33333, R3
        MOV     #44444, R4
        MOV     TIMBUF, R5              ; Year Since 1900
        HALT

RDTOY:  GTIM$S  #TIMBUF
        CALL    $SWSTK,40$
        MOV     #TOYASR+1,R5
        MOV     #TOYBUF,R4
        MOV     R4,-(SP)
        MOV     #1,R3
        MOV     #4,R2
        MOV     R2,R1
        MOVB    @R5,R0
10$:    ASR     R0
        ASR     @R4
        ROL     R0
        MOVB    R0,@R5
        ASL     R3
        BCC     10$
        ROL     R3
        TST     (R4)+
        SOB     R2,10$
20$:    TST     -(R4)
30$:    MOVB    @R5,R0
        ASR     R0
        ROR     @R4
        ASL     R3
        BCC     30$
        ROL     R3
        SOB     R1,20$
        MOV     (SP)+,R4
        MOV     #TIMBUF,R2
        CALL    BCDTB
        MOV     R0,S.TIMO(R2)
        CALL    BCDTB
        MOV     #100.,R1
        CALL    $DIV
        ADD     #100.,R1
        MOV     R1,@R2
        INC     R4
        CALL    BCDTB
        MOV     R0,S.TIDA(R2)
        CALL    BCDTB
        MOV     R0,S.TIMI(R2)
        CALL    BCDTB
        MOV     R0,S.TIHR(R2)
        INC     R4
        CALL    BCDTB
        MOV     R0,S.TISC(R2)
40$:    RETURN

BCDTB:: MOVB    (R4)+,R0
        MOV     R0,R1
        BIC     #^C377,R1
        BIC     #^C17,R0
        BIC     R0,R1
        ASR     R1
        ADD     R1,R0
        ASR     R1
        ASR     R1
        ADD     R1,R0
        RETURN

B2BCD:  MOV     #8., R4
        MOV     R0, R1
        CLR     R0
10$:    MOV     R0, R2
        BIC     #177417, R2             ; Isolate Ten's
        CMPB    R2, #120                ; Compare Ten's with 5
        BLO     20$
        ADD     #60, R2
        BIC     #177417, R2
        BIC     #360, R0
        BIS     R2, R0
20$:    MOV     R0, R2
        BIC     #177760, R2             ; Isolate One's
        CMP     R2, #5
        BLO     30$
        ADD     #3, R2
        BIC     #177760, R2
        BIC     #17, R0
        BIS     R2, R0
30$:    ASLB    R1
        ROL     R0
        SOB     R4, 10$
        RETURN

MOVEZ:: MOVB    (R1)+,(R0)+
        BNE     MOVEZ
        DEC     R0
        RETURN

PRINT:: MOV     #BUFF,R0
PRNT2:: CALL    MOVEZ
PRNT3:: SUB     #BUFF,R0
        MOV     R0,QIOW+Q.IOPL+2
        DIR$    #QIOW
        RETURN

SWLST:  .WORD   SWPRN,S.PRN
        .WORD   SWQET,S.QET
        .WORD   SWSET,S.SET
        .WORD   SWSYN,S.SYN
        .WORD   0

        .BYTE   5,1                     ; January, February
DAYMON: .BYTE   0,3                     ; March, April
        .BYTE   5,1
        .BYTE   3,6
        .BYTE   2,4
        .BYTE   0,2

DAYPTR: .WORD   DAYZO
        .WORD   DAYSO
        .WORD   DAYMO
        .WORD   DAYTU
        .WORD   DAYWE
        .WORD   DAYTH
        .WORD   DAYFR
        .WORD   DAYSA

DAYZO:  .ASCIZ  / (Zeroday)/
DAYMO:  .ASCIZ  / (Monday)/
DAYTU:  .ASCIZ  / (Tuesday)/
DAYWE:  .ASCIZ  / (Wednesday)/
DAYTH:  .ASCIZ  / (Thursday)/
DAYFR:  .ASCIZ  / (Friday)/
DAYSA:  .ASCIZ  / (Saturday)/
DAYSO:  .ASCIZ  / (Sunday)/

SWPRN:  .ASCIZ  <1>/PRINT/
SWQET:  .ASCIZ  <1>/QUIET/
SWSET:  .ASCIZ  <2>/SETTOY/
SWSYN:  .ASCIZ  <2>/SYNCHRONIZE/

EPREF:  .ASCIZ  /TOY -- /
ENDEV:  .ASCIZ  /Device not available/
ESYNT:  .ASCIZ  /Syntax error/
EINVL:  .ASCIZ  /Invalid switch/
EAMBG:  .ASCIZ  /Ambiguous switches/
ECNFL:  .ASCIZ  /Conflicting switches/
EPRIV:  .ASCIZ  /Privileged command/
ESTIM:  .ASCIZ  /Unable to set system time/

        .IF     DF,R$$MPL
ETRAN:  .ASCIZ  /Unable to translate EXEC vector/
        .IFF
EWSTB:  .ASCIZ  /Task built with wrong STB file/
        .ENDC

        .END    TOYEP

>

And the following is a small indirect command file to assemble and link the above source

        .ENABLE SUBSTITUTION

        ;
        ; TOY V02.01
        ; Copyright (c) 2005, 2006 by Oleg Safiullin <form@pdp-11.org.ru>
        ;

        .IFNDF <SYTYP> .GOTO NOSYS
        .IF <SYTYP> = "RSX-11M" .GOTO SYSOK
        .IF <SYTYP> = "RSX-11M-PLUS" .GOTO SYSOK

.NOSYS:
        ; Unsupported operating system. Only RSX-11M V4.0,
        ; RSX-11M-PLUS V3.0 and newer systems are supported.


        .EXIT 1

.SYSOK:
        ; '<SYTYP>' '<VERSN>' BL'<SYSID>'
        ;

        .SETS DIR <UIC>
        .IFNDF <DIRECT> .GOTO NODIR
        .IF <DIRECT> <> "[]" .SETS DIR <DIRECT>

.NODIR:
        .SETF DCL
        .IFNDF <CLI> .GOTO NOCLI
        .IF <CLI> = "DCL" .SETT DCL
        .IF <CLI> = "DCL" .GOTO NOCLI
        .IF <CLI> = "MCR" .GOTO NOCLI

        ; Terminal set to unsupported CLI "'<CLI>'".
        ; Please set CLI to MCR or DCL to process this command file.
        ;

        .EXIT 1

.NOCLI:
        .IFT DCL SET TERMINAL/MCR
        .SETF LST
        .SETF MAP
        .SETT DEL

        .ASK [LST] LST Do you want listing file
        .ASK [MAP] MAP Do you want task map
        .ASK [DEL] DEL Delete work files after building

        .SETS LS ""
        .IFT LST .SETS LS ",TOY/-SP"
        .SETS MP ""
        .IFT MAP .SETS MP ",TOY/-SP"

        ;
        MAC TOY'LS'=LB:[1,1]EXEMC/ML,[11,10]RSXMC/PA:1,SY:'DIR'TOY
        .IF <EXSTAT> <> 1 .GOTO CLEAN

        .SETS STB "LB:'<SYSUIC>'RSX11M.STB"
        .IF <SYTYP> = "RSX-11M-PLUS" .SETS STB "LB:'<LIBUIC>'RSXVEC.STB"

        .ONERR CLEAN
        .OPEN TOYBLD.CMD
        .DATA TOY/PR:5'MP'=TOY
        .DATA 'STB'/SS
        .DATA / 
        .DATA TASK=...TOY
        .DATA PRI=100
        .DATA UNITS=1
        .DATA ASG=TI:1
        .DATA STACK=64
        .DATA //
        .CLOSE

        TKB @TOYBLD
        .IF <EXSTAT> <> 1 .EXIT <EXSTAT>

        .IFT DEL PIP TOY.OBJ;*,TOYBLD.CMD;*/DE/NM

.CLEAN:
        .IFT DCL SET /DCL=TI: