Annotation of 42BSD/sys/mdec/tuboot.s, revision 1.1

1.1     ! root        1: /*     tuboot.s        6.1     83/08/01        */
        !             2: 
        !             3: /*
        !             4:  * VAX tu58 console cassette boot block
        !             5:  *
        !             6:  * Helge Skrivervik CSRG/UCB 18jun83
        !             7:  *
        !             8:  * Reads a program from a rt-11 directory on tape
        !             9:  * and executes it.  Programs must be stripped of
        !            10:  * the header and is loaded ``bits as is''.
        !            11:  * You can return to this loader via ``ret'' as
        !            12:  * you are called ``calls $0,ent''.
        !            13:  * Error checking and recovery is almost nonexistant
        !            14:  * due to the severe space constraints.
        !            15:  *
        !            16:  * NOTE: Any changes to this program are likely to
        !            17:  *      bring the size over 512 bytes ....
        !            18:  *
        !            19:  * Based on tp format bootstrap originally written by Thomas Ferrin.
        !            20:  *
        !            21:  */
        !            22:        .set    CTABLE,0x400    /* where to load the rad50 cnv table */
        !            23:        .set    RELOC,0x70000
        !            24: /* rt-11 directory definitions */
        !            25:        .set    DIRBLK,6        /* rt-11 directory starts at block 6 */
        !            26:        .set    FILSIZ,8        /* rt-11 direc entry offset for file size */
        !            27:        .set    ENTSIZ,14       /* size of 1 rt-11 dir entry, bytes */
        !            28:        .set    BLKSIZ,512      /* tape block size, bytes */
        !            29:        .set    NUMDIR,2        /* no. of dir blocks on tape */
        !            30:        .set    FNSIZ,8         /* size of rad50 filename + 2 */
        !            31:        .set    NAME,2          /* direc entry offset for filename */
        !            32:        .set    STATUS,1        /* direc entry offset for entry status */
        !            33: /* rt-11 directory entry status */
        !            34:        .set    RT_ESEG,8       /* end of directory segment */
        !            35:        .set    RT_NULL,2       /* empty entry */
        !            36:        .set    RT_FILE,4       /* valid file entry */
        !            37: /* processor registers and bits */
        !            38:        .set    RXCS,32
        !            39:        .set    RXDB,33
        !            40:        .set    TXCS,34
        !            41:        .set    TXDB,35
        !            42:        .set    RXCS_DONE,0x80
        !            43:        .set    TXCS_RDY,0x80
        !            44:        .set    TXCS_pr,7       /* bit position of TXCS ready bit */
        !            45:        .set    RXCS_pd,7       /* bit position of RXCS done bit */
        !            46: /* console storage registers and bits */
        !            47:        .set    CSRS,0x1c
        !            48:        .set    CSRD,0x1d
        !            49:        .set    CSTS,0x1e
        !            50:        .set    CSTD,0x1f
        !            51: /* TU commands and bits */
        !            52:        .set    TU_BREAK,1
        !            53:        .set    TU_INIT,4
        !            54:        .set    TU_CONTINUE,16
        !            55:        .set    TU_READY,7      /* bit position of CSRS ready bit */
        !            56:        .set    TU_PACKETLEN,8  /* length of readcom block */
        !            57: /* local stack variables */
        !            58:        .set    ext,-4                  /* file ext. */
        !            59:        .set    name,-20                /* 12 bytes for full name */
        !            60:        .set    rt_name,-20-FNSIZ       /* rad50 file name */
        !            61: /* reboot flags for boot */
        !            62:        .set    RB_ASK,3                /* ask name and come up single user */
        !            63: 
        !            64: /* 
        !            65:  * Initialization.
        !            66:  */
        !            67: init:
        !            68:        .word   0               /* entry mask for dec monitor */
        !            69:        nop;nop;nop;nop;nop     /* some no-ops for 750 boot rom to skip */
        !            70:        nop;nop;nop;nop;nop 
        !            71:        movl    $RELOC,fp       /* core loc to which to move this program */
        !            72:        addl3   $rt_name,fp,sp  /* set stack pointer; leave room for locals */
        !            73:        clrl    r0
        !            74: 1:
        !            75:        movc3   $end,(r0),(fp)  /* move boot up to relocated position */
        !            76:        jmp     start+RELOC
        !            77: 
        !            78: start:
        !            79:        mtpr    $TU_BREAK,$CSTS         /* set break condition */
        !            80:        clrl    r2                      /* nulls */
        !            81:        bsbw    xmit2                   /* wait 2 character times */
        !            82:        mfpr    $CSRD,r2                /* clear receive buffer */
        !            83:        movzwl  $TU_INIT|(TU_INIT<<8),r2        /* load 2 INIT opcodes */
        !            84:        bsbw    xmit2                   /* xmit 'em */
        !            85: 1:
        !            86:        mfpr    $CSRD,r7                /* get recv data */
        !            87:        cmpb    r7,$TU_CONTINUE         /* is it a continue flag? */
        !            88:        bneq    1b                      /* nope, look more */
        !            89: 
        !            90:        movab   name(fp),r4             /* start of filename storage */
        !            91:        clrq    (r4)                    /* init name field */
        !            92:        clrq    name+8(fp)
        !            93:        clrq    rt_name(fp)             /* init rad50 filename */
        !            94:        movzbl  $'=,r0                  /* prompt character */
        !            95:        bsbw    putc                    /* output char to main console */
        !            96: 
        !            97: /* 
        !            98:  * Read in a file name from console. 
        !            99:  */
        !           100:        movl    r4,r1                   /* loc at which to store file name */
        !           101: nxtc:
        !           102:        bsbw    getc                    /* get input char's in file name */
        !           103:        cmpb    r0,$012                 /* terminator ? */
        !           104:        beql    nullc
        !           105:        movb    r0,(r1)+
        !           106:        brb     nxtc
        !           107: nullc:
        !           108:        cmpl    r4,r1
        !           109:        beql    start                   /* restart if empty string */
        !           110:        clrb    (r1)                    /* add null byte at end */
        !           111: 
        !           112: /*
        !           113:  * User-specified filename has been stored at name(fp),
        !           114:  * read the entire directory contents into low core.
        !           115:  */
        !           116: dirred:
        !           117:        movl    $DIRBLK,r10             /* directory starts at block DIRBLK */
        !           118:        movl    $(NUMDIR*BLKSIZ),r6     /* no. bytes in total dir */
        !           119:        clrl    r11                     /* start address */
        !           120:        bsbw    taper                   /* read no. bytes indicated */
        !           121: /*
        !           122:  * Read in the character conversion table which reside in block 1
        !           123:  * (the second block) on the cassette. Place it after the directory
        !           124:  * on low core (from 0x400).
        !           125:  */
        !           126:        movl    $1,r10                  /* block number */
        !           127:        movl    $BLKSIZ,r6              /* read one block */
        !           128:        bsbw    taper
        !           129: 
        !           130: /*
        !           131:  * Convert the ascii filename to rad50.
        !           132:  * R4 still points to name(fp)
        !           133:  */
        !           134:        movl    $6,r3                   /* max length of filename */
        !           135: 1:
        !           136:        cmpb    $'.,(r4)+               /* look for '.' */
        !           137:        beql    1f
        !           138:        sobgtr  r3,1b
        !           139:        incl    r4                      /* point past '.' if ext is present */
        !           140: 1:
        !           141:        clrb    -1(r4)                  /* end name with null */
        !           142:        movl    $3,r3                   /* max length of extension */
        !           143:        movab   ext(fp),r5              /* place extension here */
        !           144: 1:
        !           145:        movb    (r4)+,(r5)+
        !           146:        beql    1f                      /* the string is null terminated */
        !           147:        sobgtr  r3,1b
        !           148: 1:
        !           149:        movab   name(fp),r4
        !           150:        movab   rt_name(fp),r5          /* ptr to rad50 name */
        !           151:        bsbw    rad50                   /* convert filename */
        !           152:        movab   ext(fp),r4
        !           153:        movab   rt_name+4(fp),r5
        !           154:        bsbw    rad50                   /* convert extension */
        !           155: 
        !           156: /*
        !           157:  * Search entire directory for user-specified file name.
        !           158:  */
        !           159: 
        !           160:        movab   rt_name(fp),r4          /* search for this file */
        !           161:        movl    $10,r5                  /* point to first file entry */
        !           162:        movzwl  -2(r5),r10              /* r10 = block # where files begin */
        !           163: 2:
        !           164:        cmpc3   $6,NAME(r5),(r4)        /* see if dir entry matches filename */
        !           165:        beql    fndfil                  /* found match */
        !           166: 1:
        !           167:        addw2   FILSIZ(r5),r10          /* add file length to block pointer */
        !           168:        addl2   $ENTSIZ,r5              /* move to next entry */
        !           169: #      cpmb    STATUS(r5),$RT_NULL     /* check if deleted file */
        !           170: #      beql    1b /* not really necessary since deleted entries will fail */
        !           171:                   /* to compare anyway */
        !           172:        cmpb    STATUS(r5),$RT_ESEG     /* check if end of segment */
        !           173:        bneq    2b
        !           174:        brw     start                   /* entry not in directory; start over */
        !           175: 
        !           176: /* 
        !           177:  * Found desired directory entry 
        !           178:  */
        !           179: fndfil:
        !           180:                                        /* start block no., 2 bytes in r10 */
        !           181:        movzwl  FILSIZ(r5),r6           /* file size (blocks) */
        !           182:        mull2   $BLKSIZ,r6              /* file size (bytes) */
        !           183:        cmpl    r6,$RELOC-512           /* check if file fits below stack */
        !           184:        blss    filok
        !           185:        brw     start                   /* file too large */
        !           186: 
        !           187: /* 
        !           188:  * Read in desired file from tape.
        !           189:  */
        !           190: filok:
        !           191:        movl    r6,r5                   /* start of bss space */
        !           192:        clrl    r11                     /* start address */
        !           193:        bsbb    taper
        !           194: 
        !           195: /* 
        !           196:  * Clear core.
        !           197:  */
        !           198:        subl3   r5,$RELOC-4,r0          /* no. bytes to clear */
        !           199: 1:
        !           200:        clrb    (r5)+
        !           201:        sobgtr  r0,1b
        !           202: 
        !           203: /* 
        !           204:  * Jump to start of file & execute.
        !           205:  */
        !           206:        addl3   $20,fp,ap               /* ?? */
        !           207:        clrl    r5
        !           208:        movl    $RB_ASK,r11
        !           209:        calls   $0,(r5)
        !           210: bad:
        !           211:        brw     start
        !           212: 
        !           213: /* 
        !           214:  * Read (r6) bytes from block (r10) 
        !           215:  * into loc (r11).
        !           216:  */
        !           217: taper:
        !           218:        clrl    r8                      /* initialize checksum */
        !           219:        movab   readcom,r0              /* read command packet addr */
        !           220:        movzbl  $TU_PACKETLEN/2,r1      /* size of readcom block */
        !           221: 1:
        !           222:        movzwl  (r0)+,r2                /* get 2 chars from block */
        !           223:        bsbb    xmit                    /* xmit and update ckecksum */
        !           224:        sobgtr  r1,1b                   /* loop if more */
        !           225: 
        !           226: /* 
        !           227:  * Now do variable part of packet. 
        !           228:  */
        !           229:        movl    r6,r2                   /* byte count */
        !           230:        bsbb    xmit
        !           231:        movl    r10,r2                  /* starting block number */
        !           232:        bsbb    xmit
        !           233:        movzwl  r8,r2                   /* accumulated ckecksum */
        !           234:        bsbb    xmit
        !           235: 
        !           236: /* 
        !           237:  * Collect read packet from device. 
        !           238:  */
        !           239: 1:
        !           240:        bsbb    recv2                   /* get 2 packet characters */
        !           241:        decb    r2                      /* data packet? */
        !           242:        bneq    1f                      /* branch on end of data */
        !           243:        movzbl  r1,r8                   /* get byte count of packet */
        !           244: 
        !           245: /* 
        !           246:  * Read data into memory.
        !           247:  */
        !           248: 2:
        !           249:        bsbb    recv1                   /* get a char */
        !           250:        movb    r1,(r11)+               /* stuff into memory */
        !           251:        sobgtr  r8,2b                   /* loop if more */
        !           252:        bsbb    recv2                   /* skip checksum */
        !           253:        brb     1b                      /* read next packet */
        !           254: 
        !           255: /* 
        !           256:  * End of data xfer; check for errors.
        !           257:  */
        !           258: 1:
        !           259:        bsbb    recv2                   /* get success code */
        !           260:        tstl    r1                      /* error in read? */
        !           261:        blss    9f                      /* branch if status error */
        !           262:        movl    $5,r0
        !           263: 1:
        !           264:        bsbb    recv2                   /* discard 10 bytes */
        !           265:        sobgtr  r0,1b
        !           266:        rsb
        !           267: 
        !           268: /* Fatal error */
        !           269: 9:
        !           270:        movab   ermsg,r1
        !           271: 1:
        !           272:        movb    (r1)+,r0
        !           273:        beql    bad
        !           274:        bsbb    putc
        !           275:        brb     1b
        !           276: 
        !           277: /* 
        !           278:  * Update checksum in r8 and xmit 2 characters.
        !           279:  */
        !           280: xmit:
        !           281:        addw2   r2,r8                   /* update checksum */
        !           282:        adwc    $0,r8                   /* add  in carry */
        !           283: 
        !           284: /* send the 2 characters contained in r2 */
        !           285: xmit2:
        !           286:        bsbb    1f                      /* xmit one of 'em */
        !           287:        ashl    $-8,r2,r2               /* get next char */
        !           288:                                        /* fall into... */
        !           289: 1:
        !           290:        mfpr    $CSTS,r7                /* get xmit status */
        !           291:        bbc     $TU_READY,r7,1b         /* loop until ready */
        !           292:        mtpr    r2,$CSTD                /* send char */
        !           293:        rsb
        !           294: 
        !           295: /* 
        !           296:  * Receive 2 characters, return in r2 and r1.
        !           297:  */
        !           298: recv2:
        !           299:        bsbb    recv1                   /* recv one of 'em */
        !           300:                                        /* fall into... */
        !           301: 
        !           302: /* 
        !           303:  * Receive 1 character.
        !           304:  */
        !           305: recv1:
        !           306:        movzbl  r1,r2                   /* save previous byte */
        !           307: 1:
        !           308:        mfpr    $CSRS,r7                /* get recv status */
        !           309:        bbc     $TU_READY,r7,1b         /* loop until ready */
        !           310:        mfpr    $CSRD,r1                /* get char */
        !           311:        blss    9b                      /* branch on recv error */
        !           312:        rsb
        !           313: 
        !           314: getc:
        !           315:        mfpr    $RXCS,r0
        !           316:        bbc     $RXCS_pd,r0,getc        /* receiver ready ? */
        !           317:        mfpr    $RXDB,r0
        !           318:        extzv   $0,$7,r0,r0
        !           319:        cmpb    r0,$015
        !           320:        bneq    putc                    /* echo and return */
        !           321:        bsbb    putc                    /* carriage return */
        !           322: #      movb    $0,r0
        !           323: #      bsbb    putc                    /* delay */
        !           324:        movb    $012,r0                 /* send line feed and return */
        !           325: putc:
        !           326:        mfpr    $TXCS,r2
        !           327:        bbc     $TXCS_pr,r2,putc        /* transmitter ready ? */
        !           328:        mtpr    r0,$TXDB
        !           329:        rsb
        !           330: 
        !           331: /*
        !           332:  * Convert the filename given from the console
        !           333:  * to radix 50 (rt-11) format.
        !           334:  */
        !           335: rad50:
        !           336:        clrw    r1
        !           337:        bsbb    getb50                  /* get next ascii byte, exit if null */
        !           338:        mull3   $03100,r0,r1
        !           339:        bsbb    getb50
        !           340:        mull3   $050,r0,r2
        !           341:        addl2   r2,r1
        !           342:        bsbb    getb50
        !           343:        addl2   r0,r1                   /* last byte, just add it in */
        !           344:        movw    r1,(r5)+                /* save result */
        !           345:        brb     rad50
        !           346: 
        !           347: getb50:
        !           348:        movzbl  (r4)+,r0                /* get next ascii byte */
        !           349:        beql    1f                      /* if zero: end of string */
        !           350:        movzbl  CTABLE(r0),r0           /* and get the r50 byte from the table*/
        !           351:        rsb
        !           352: 1:
        !           353:        tstl    (sp)+                   /* we're through, get back to where */
        !           354:                                        /* rad50 was called */
        !           355:        movw    r1,(r5)                 /* but first save the result */
        !           356:        rsb
        !           357: 
        !           358:        .align  2
        !           359: readcom:
        !           360:        .byte   2                       /* command packet flag */
        !           361:        .byte   10                      /* number of bytes in message */
        !           362:        .byte   2                       /* tu read opcode */
        !           363:        .byte   0                       /* modifier */
        !           364:        .byte   0                       /* unit number */
        !           365:        .byte   0                       /* switches */
        !           366:        .word   0                       /* sequence number */
        !           367:                                        /* byte count and block number follow */
        !           368: 
        !           369: ermsg:
        !           370:        .asciz  "tuerr\r\n"
        !           371: end:
        !           372: 
        !           373: /*
        !           374:  * Ascii to rad 50 conversion table,
        !           375:  * stored on the second block on the cassette
        !           376:  *
        !           377:  * NOTE: Always make sure this table ends up
        !           378:  * starting at byte 512!!!!
        !           379:  */
        !           380:        .align  2
        !           381:        .data   2
        !           382:        .long   0x1d1d1d1d
        !           383:        .long   0x1d1d1d1d
        !           384:        .long   0x1d1d1d1d
        !           385:        .long   0x1d1d1d1d
        !           386:        .long   0x1d1d1d1d
        !           387:        .long   0x1d1d1d1d
        !           388:        .long   0x1d1d1d1d
        !           389:        .long   0x1d1d1d1d
        !           390:        .long   0x1d1d1d00
        !           391:        .long   0x1d1d1d1b
        !           392:        .long   0x1d1d1d1d
        !           393:        .long   0x1d1c1d1d
        !           394:        .long   0x21201f1e
        !           395:        .long   0x25242322
        !           396:        .long   0x1d1d2726
        !           397:        .long   0x1d1d1d1d
        !           398:        .long   0x302011d
        !           399:        .long   0x7060504
        !           400:        .long   0xb0a0908
        !           401:        .long   0xf0e0d0c
        !           402:        .long   0x13121110
        !           403:        .long   0x17161514
        !           404:        .long   0x1d1a1918
        !           405:        .long   0x1d1d1d1d
        !           406:        .long   0x302011d
        !           407:        .long   0x7060504
        !           408:        .long   0xb0a0908
        !           409:        .long   0xf0e0d0c
        !           410:        .long   0x13121110
        !           411:        .long   0x17161514
        !           412:        .long   0x1d1a1918
        !           413:        .long   0x1d1d1d1d
        !           414:        .long   0x1d1d1d1d
        !           415:        .long   0x1d1d1d1d
        !           416:        .long   0x1d1d1d1d
        !           417:        .long   0x1d1d1d1d
        !           418:        .long   0x1d1d1d1d
        !           419:        .long   0x1d1d1d1d
        !           420:        .long   0x1d1d1d1d
        !           421:        .long   0x1d1d1d1d
        !           422:        .long   0x1d1d1d00
        !           423:        .long   0x1d1d1d1b
        !           424:        .long   0x1d1d1d1d
        !           425:        .long   0x1d1c1d1d
        !           426:        .long   0x21201f1e
        !           427:        .long   0x25242322
        !           428:        .long   0x1d1d2726
        !           429:        .long   0x1d1d1d1d
        !           430:        .long   0x302011d
        !           431:        .long   0x7060504
        !           432:        .long   0xb0a0908
        !           433:        .long   0xf0e0d0c
        !           434:        .long   0x13121110
        !           435:        .long   0x17161514
        !           436:        .long   0x1d1a1918
        !           437:        .long   0x1d1d1d1d
        !           438:        .long   0x302011d
        !           439:        .long   0x7060504
        !           440:        .long   0xb0a0908
        !           441:        .long   0xf0e0d0c
        !           442:        .long   0x13121110
        !           443:        .long   0x17161514
        !           444:        .long   0x1d1a1918
        !           445:        .long   0x1d1d1d
        !           446:        .data

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.