1: TOYCSR  = 177526
   2: 
   3: / April 6, 2000 - sms@moe.2bsd.com
   4: / Remove the cpu type (93 or 94) restriction and probe for the TOY register.
   5: / Some systems have clock boards added _and_ P11 (Begemot Computer Associates'
   6: / PDP-11 emulator) have support for the TOY clock.
   7: /
   8: / April 10, 1997 - sms@moe.2bsd.com
   9: / The day of week calculation was incorrect and would return -1 for Saturday
  10: / rather than 6.  Alan Sieving spotted this one too (toyset.s must be favorite
  11: / reading material ;-))
  12: /
  13: / February 6, 1997 - sms@moe.2bsd.com
  14: / Forgot that May has 31 days.  Thanks to Alan Sieving (ars@quickware.com) for
  15: / spotting this.
  16: /
  17: / August 21, 1993 - Steven M. Schultz (sms@wlv.iipo.gtegsc.com)
  18: / This is a standalone program which is used to set the TOY (Time Of Year)
  19: / clock on a PDP-11/93 or 11/94.  If this program is run on other than a
  20: / 93 or 94 an error is printed and the program 'exits' back to the boot
  21: / runtime.
  22: /
  23: / The current date is printed (in the same format used to enter the new date)
  24: / and the prompt "Toyset> " is displayed.  At that time a string of the form:
  25: / YYMMDDHHMM[.SS]\n is entered.  The seconds "SS" are optional, if not entered
  26: / the seconds will be set to 0.  Any invalid input string simply loops back
  27: / to the top of the program.
  28: /
  29: / To not change the date and time simply hit a return and the program will
  30: / exit, returning control to 'boot'.
  31: 
  32:         .globl  _main, csv, cret, _printf, _gets, _exit, _module
  33:         .globl  nofault
  34: 
  35: _main:
  36: main:
  37:         jsr     r5,csv                  / srt0.o sets up a C frame...
  38: 
  39:         jsr     pc,init                 / probe for clock, display current TOY
  40: 
  41:         clrb    line                    / init buffer
  42:         mov     $line,-(sp)
  43:         jsr     pc,_gets                / get input from user
  44:         tst     r0
  45:         bgt     1f
  46: leave:
  47:         jsr     pc,_exit                / exit on error
  48: 1:
  49:         tstb    line                    / did we get anything?
  50:         beq     leave                   / nope - go exit
  51: 
  52:         clr     r3                      / clear '.' seen flag
  53:         mov     $line,r4                / point to input data
  54: 2:
  55:         movb    (r4)+,r0
  56:         beq     1f                      / end of string - go validate it
  57:         cmpb    r0,$'.                  / are there seconds present?
  58:         bne     2b                      / not yet - go try another byte
  59:         clrb    -1(r4)                  / zap '.' - separating two parts of date
  60:         mov     r4,r3                   / set seconds present flag
  61:         tstb    (r3)+                   / must have two...
  62:         beq     main                    / and only two...
  63:         tstb    (r3)+                   / characters after...
  64:         beq     main                    / the '.'...
  65:         tstb    (r3)                    / followed by a ...
  66:         bne     main                    / null character.
  67: 1:
  68:         clrb    seconds                 / assume no seconds (start of minute)
  69:         tst     r3                      / do we have seconds?
  70:         beq     nosec                   / no - br
  71:         cmpb    -(r3),-(r3)             / back up to beginning of seconds string
  72:         mov     r3,-(sp)
  73:         jsr     pc,atoi2                / convert two digits to binary
  74:         tst     (sp)+
  75:         cmp     r0,$59.                 / range check
  76:         bhi     main                    / error - go back to top
  77:         movb    r0,seconds              / save for later
  78: nosec:
  79:         sub     $line+1,r4              / number of characters in date string
  80:         cmp     r4,$10.                 / _must_ have *exactly* "YYMMDDhhmm"
  81:         bne     main                    / back to the top on error
  82:         mov     $line,r4                / point to start of date string
  83:         mov     r4,-(sp)
  84:         jsr     pc,atoi2                / convert 2 digits to binary (year)
  85:         tst     (sp)+
  86:         cmp     r4,$-1                  / error?
  87:         beq     main                    / yes - go back to top
  88:         cmp     r0,$69.                 / before [19]69?
  89:         bgt     1f                      / no - it's a 1970-1999 year - br
  90:         add     $100.,r0                / 21st century and 11s are still around!
  91: 1:
  92:         movb    r0,year                 / save year for later
  93:         cmpb    (r4)+,(r4)+             / skip two digits, move to month
  94:         mov     r4,-(sp)
  95:         jsr     pc,atoi2                / convert month to binary
  96:         tst     (sp)+
  97:         cmp     r0,$12.                 / range check
  98:         bhi     main                    / back to top on too high
  99:         cmpb    (r4)+,(r4)+             / move on to day of month
 100:         movb    r0,month                / save month for later
 101:         beq     main                    / can't have a month 0
 102:         mov     r4,-(sp)
 103:         jsr     pc,atoi2                / convert day of month to binary
 104:         tst     (sp)+
 105:         movb    month,r1
 106:         cmpb    r0,Mtab-1(r1)           / crude check (no leap year case)
 107:         bhi     main                    / on day of month
 108:         movb    r0,day                  / save the day for later
 109:         cmpb    (r4)+,(r4)+             / move along to hours of day
 110:         mov     r4,-(sp)
 111:         jsr     pc,atoi2                / convert hours of day to binary
 112:         tst     (sp)+
 113:         cmp     r0,$23.                 / can't have more than 23 hours
 114:         bhi     main                    / but 00 is ok (midnight)
 115:         movb    r0,hours                / save hours for later
 116:         cmpb    (r4)+,(r4)+             / move over to minutes
 117:         mov     r4,-(sp)
 118:         jsr     pc,atoi2                / convert minutes to binary
 119:         tst     (sp)+
 120:         cmp     r0,$59.                 / can't have more than 59 minutes
 121:         bhi     main                    / back to top on out of range error
 122:         movb    r0,minutes              / save for later
 123: 
 124: / need to compute the "day of week".  why the TOY clock couldn't figure
 125: / this out (or do without) itself i don't know.
 126: 
 127:         jsr     pc,t2dow                / find out "day of week"
 128:         movb    r0,dow                  / save for later
 129: 
 130: / now we have to convert the binary data to BCD.  We needed (or preferred)
 131: / the binary form for ease of range checking but the TOY wants BCD.  Besides
 132: / i like to improve my typing skills ;-)
 133: 
 134:          movb   seconds,r1
 135:          jsr    pc,tobcd
 136:          movb   r0,bcd+1                / seconds
 137: 
 138:          movb   minutes,r1
 139:          jsr    pc,tobcd
 140:          movb   r0,bcd+2                / minutes
 141: 
 142:          movb   hours,r1
 143:          jsr    pc,tobcd
 144:          movb   r0,bcd+3                / hours
 145: 
 146:          movb   dow,r1
 147:          jsr    pc,tobcd
 148:          movb   r0,bcd+4                / day of week
 149: 
 150:          movb   day,r1
 151:          jsr    pc,tobcd
 152:          movb   r0,bcd+5                / day of month
 153: 
 154:          movb   month,r1
 155:          jsr    pc,tobcd
 156:          movb   r0,bcd+6                / month of year
 157: 
 158:          movb   year,r1
 159:          jsr    pc,tobcd
 160:          movb   r0,bcd+7
 161: 
 162: / Now initialize the TOY by sending the 'recognition' sequence.  We have
 163: / to inline this because immediately after the recognition sequence must
 164: / come the 'write' of data - a 'read' to save the contents of the CSR
 165: / would tell the TOY we're reading data.  *sigh*
 166: 
 167:         tst     *$TOYCSR                / strobe the clock register
 168:         clr     -(sp)                   / save previous high byte of register
 169:         movb    *$TOYCSR+1,(sp)         / only bit 8 belongs to TOY!
 170:         bic     $1,(sp)                 / make sure bit 8 (TOY bit) is clear
 171:         mov     $2,r2                   / number of double words to send clock
 172: 1:
 173:         mov     $35305,r0               / first word of recognition code
 174:         jsr     pc,toyload              / send it to clock
 175:         mov     $56243,r0               / second word
 176:         jsr     pc,toyload              / send it
 177:         sob     r2,1b                   / do the whole thing twice
 178: 
 179: / Now write the data to the TOY without an intervening 'tst' or 'movb'
 180: / to the CSR.
 181: 
 182:         mov     bcd,r0                  / first two bytes
 183:         jsr     pc,toyload
 184:         mov     bcd+2,r0                / bytes 3 and 4
 185:         jsr     pc,toyload
 186:         mov     bcd+4,r0
 187:         jsr     pc,toyload              / bytes 5 and 6
 188:         mov     bcd+6,r0
 189:         jsr     pc,toyload              / bytes 7 and 8
 190: 
 191:         tst     (sp)+                   / clean stack now, we're done
 192:         clr     r0                      / "exit" status.  ha! ;-)
 193:         jsr     pc,_exit
 194: 
 195: / Probe for the TOY register.  If present initialize the TOY and read the
 196: / current date otherwise print an error message and exit.  Convert the date
 197: / into printable form and print it out along with the prompt.
 198: 
 199: init:
 200:         mov     $1f, nofault            / catch fault if no TOY clock
 201:         tst     *$TOYCSR
 202:         br      2f                      / we have a clock
 203: 1:
 204:         mov     $errmsg1,-(sp)
 205:         jsr     pc,_printf
 206:         mov     $1,r0
 207:         jsr     pc,_exit
 208: 2:
 209:         clr     nofault                 / faults are serious again
 210:         jsr     pc,initoy               / init the TOY clock
 211:         mov     $bcd,-(sp)              / buffer for the date
 212:         jsr     pc,_gettoy              / read the TOY
 213:         tst     (sp)+
 214:         mov     $timbuf,r3              / where to put printable form of date
 215:         clr     r1
 216:         bisb    bcd+7,r1                / year in bcd
 217:         jsr     pc,bcd2msg
 218:         movb    bcd+6,r1                / month in bcd
 219:         jsr     pc,bcd2msg
 220:         movb    bcd+5,r1                / day of month in bcd
 221:         jsr     pc,bcd2msg
 222:         movb    bcd+3,r1                / hour of day in bcd
 223:         jsr     pc,bcd2msg
 224:         movb    bcd+2,r1                / minute of hour in bcd
 225:         jsr     pc,bcd2msg
 226:         movb    $'.,(r3)+
 227:         movb    bcd+1,r1                / seconds of minute in bcd
 228:         jsr     pc,bcd2msg
 229:         mov     $timmsg,-(sp)
 230:         jsr     pc,_printf
 231:         tst     (sp)+
 232:         rts     pc
 233: 
 234: / convert two bytes of ascii pointed to by 2(sp) into a binary number.
 235: / the return value is in r0.
 236: 
 237: atoi2:
 238:         movb    *2(sp),r1
 239:         inc     2(sp)
 240:         movb    *2(sp),r0
 241:         sub     $'0,r1
 242:         sub     $'0,r0
 243:         mul     $10.,r1
 244:         add     r1,r0
 245:         rts     pc
 246: 
 247: / convert a byte of BCD (in r1) two to ascii digits and place those
 248: / at (r3)+ and (r3)+ respectively.
 249: 
 250: bcd2msg:
 251:         clr     r0
 252:         div     $16.,r0
 253:         add     $'0,r0
 254:         add     $'0,r1
 255:         movb    r0,(r3)+
 256:         movb    r1,(r3)+
 257:         rts     pc
 258: 
 259: / convert a binary number (in r1) to a byte containing two bcd digits.
 260: / return result in r0.
 261: 
 262: tobcd:
 263:         clr     r0
 264:         div     $100.,r0                / truncate to max of 99
 265:         clr     r0
 266:         div     $10.,r0
 267:         ash     $4,r0
 268:         bis     r1,r0
 269:         rts     pc
 270: 
 271: / To calculate the day of the week (Sunday = 1) an algorithm found in
 272: / "The Ready Reference (r) Weekly Planner 1986 ((c) 1986 Ready Reference)"
 273: / is used.
 274: 
 275: t2dow:
 276:         jsr     r5,csv                  / save registers
 277:         movb    year,r4                 / low two digits (93) of year
 278:         mov     r4,r0
 279:         asr     r0                      / divide by 4
 280:         asr     r0                      /  ignoring any remainder
 281:         add     r0,r4                   / add to year
 282:         movb    day,r0
 283:         add     r0,r4                   / add day of month
 284:         movb    month,r0
 285:         movb    m_magic-1(r0),r3
 286:         cmp     r0,$2                   / February Or January?
 287:         bgt     1f                      / no - br
 288:         movb    year,r0
 289:         add     $1900.,r0
 290:         mov     r0,-(sp)
 291:         jsr     pc,isleap               / are we in a leap year?
 292:         mov     r0,(sp)+
 293:         beq     1f                      / no - br
 294:         dec     r3                      / adjust number from magic month table
 295: 1:
 296:         add     r3,r4                   / add magic number to total
 297:         cmpb    year,$69.               / before 1969?
 298:         bgt     2f                      / no - br, we're in the 20th century
 299:         add     $6,r4                   / adjustment for 21st century
 300: 2:
 301:         mov     r4,r1
 302:         clr     r0
 303:         div     $7,r0                   / divide total by 7
 304:         dec     r1                      / Saturday or Sunday?
 305:         bgt     3f                      / no - br
 306:         add     $7,r1                   / yes - set Saturday to 6, Sunday to 7
 307: 3:
 308:         mov     r1,r0                   / put return value in right place
 309:         jmp     cret                    / 1 = Monday ... 7 = Sunday
 310: 
 311: / (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
 312: 
 313: isleap:
 314:         clr     r0
 315:         mov     2(sp),r1                / get year
 316:         bit     $3,r1                   / easy check for "mod 4"
 317:         bne     1f                      / can't be a leap - br
 318:         div     $100.,r0                / % 100
 319:         tst     r1                      / check remainder
 320:         bne     2f
 321:         bit     $3,r0                   / % 400
 322:         beq     2f
 323: 1:
 324:         clr     r0
 325:         rts     pc
 326: 2:
 327:         mov     $1,r0
 328:         rts     pc
 329: 
 330: initoy:
 331:         tst     *$TOYCSR                / strobe the clock register
 332:         clr     -(sp)                   / save previous high byte of register
 333:         movb    *$TOYCSR+1,(sp)         / only bit 8 belongs to TOY!
 334:         bic     $1,(sp)                 / make sure bit 8 (TOY bit) is clear
 335:         mov     $2,r2                   / number of double words to send clock
 336: 1:
 337:         mov     $35305,r0               / first word of recognition code
 338:         jsr     pc,toyload              / send it to clock
 339:         mov     $56243,r0               / second word
 340:         jsr     pc,toyload              / send it
 341:         sob     r2,1b                   / do the whole thing twice
 342:         tst     (sp)+                   / clean stack
 343:         rts     pc
 344: 
 345: / send contents of r0 to the TOY.  2(sp) has the old bits 9-15, bit 8
 346: / has been cleared.
 347: 
 348: toyload:
 349:         mov     $16.,r1                 / number of bits to send
 350: 1:
 351:         mov     r0,r3                   / scratch copy
 352:         bic     $177776,r3              / clear all but bit being sent
 353:         bis     2(sp),r3                / merge in old_csr_bits
 354:         movb    r3,*$TOYCSR+1           / send bit to clock
 355:         asr     r0                      / shift pattern down
 356:         sob     r1,1b                   / do all 16 bits in the word
 357:         rts     pc
 358: 
 359:         .globl  _gettoy
 360: _gettoy:                                / (void)gettoy(&char[8]);
 361:         jsr     r5,csv                  / C callable
 362:         mov     4(r5),r2                / buffer address
 363:         mov     $4,r3                   / number of words in buffer
 364: 1:
 365:         mov     $16.,r4                 / number of bits in word
 366: 2:
 367:         movb    *$TOYCSR+1,r0           / low bit of top byte is a clock bit
 368:         asr     r0                      / put it in carry
 369:         ror     r1                      / ripple in at top end of r1
 370:         sob     r4,2b                   / do all 16 bits
 371:         mov     r1,(r2)+                / store the word in the buffer
 372:         sob     r3,1b                   / do all 4 words
 373:         jmp     cret                    / and return
 374: 
 375:         .data
 376: Mtab:
 377:         .byte   31.,29.,31.,30.,31.,30.
 378:         .byte   31.,31.,30.,31.,30.,31.
 379: m_magic:
 380:         .byte   1,4,4,0,2,5,0,3,6,1,4,6
 381: errmsg1:
 382:         <No TOY clock present\n\0>
 383: timmsg:
 384:         <Current TOY: >
 385: timbuf:
 386:         .=.+13.                         / room for YYMMDDhhmm.ss
 387:         <\n>
 388:         <Toyset\> \0>
 389: _module:
 390:         <Toyset\0>
 391:         .even
 392:         .bss
 393: seconds:
 394:         .=.+1
 395: minutes:
 396:         .=.+1
 397: hours:
 398:         .=.+1
 399: day:
 400:         .=.+1
 401: month:
 402:         .=.+1
 403: year:
 404:         .=.+1
 405: dow:
 406:         .=.+1
 407:         .even
 408: bcd:
 409:         .=.+8.
 410: line:
 411:         .=.+64.

Defined functions

TOYCSR defined in line 1; used 7 times
_gettoy declared in line 359; defined in line 360; used 2 times
_main declared in line 32; defined in line 35; used 1 times
  • in line 32
atoi2 defined in line 237; used 6 times
bcd2msg defined in line 250; used 6 times
init defined in line 199; used 1 times
  • in line 39
initoy defined in line 330; used 1 times
isleap defined in line 313; used 1 times
leave defined in line 46; used 1 times
  • in line 50
main defined in line 36; used 11 times
nosec defined in line 78; used 1 times
  • in line 70
t2dow defined in line 275; used 1 times
tobcd defined in line 262; used 7 times
toyload defined in line 348; used 8 times

Defined variables

Mtab defined in line 376; used 1 times
_module declared in line 32; defined in line 389; used 1 times
  • in line 32
bcd defined in line 408; used 18 times
day defined in line 399; used 3 times
dow defined in line 405; used 2 times
errmsg1 defined in line 381; used 1 times
hours defined in line 397; used 2 times
line defined in line 410; used 6 times
m_magic defined in line 379; used 1 times
minutes defined in line 395; used 2 times
month defined in line 401; used 4 times
seconds defined in line 393; used 3 times
timbuf defined in line 385; used 1 times
timmsg defined in line 383; used 1 times
year defined in line 403; used 5 times
Last modified: 2000-04-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3018
Valid CSS Valid XHTML 1.0 Strict