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

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

unix.superglobalmegacorp.com

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