Annotation of cci/d/dmp4/run_code.s, revision 1.1.1.1

1.1       root        1: 
                      2: # ************************************************************************
                      3: # *            "RUN THE CODE" ROUTINE
                      4: # *
                      5: # *  This routine will test the current instruction. The instruction will
                      6: # *  be moved to a page boundary and executed and the results will be
                      7: # *  verified. The code will be tested twice, once with an instruction 
                      8: # *  cache miss and once with a cache hit. To insure instruction cache 
                      9: # *  hits, the code will be executed twice -once with all pages validated
                     10: # *  in the memory map and the 2nd time with them invalidated. The results
                     11: # *  will be checked after the 2nd execution. 
                     12: # *  Successive calls to this routine will set the page boundary on 
                     13: # *  different bytes in the code to check page faults at each byte.
                     14: # *  The general template of the 16 byte test code will be:
                     15: # *
                     16: # *      <op-code> [<addr-mode>] [<offset#1>] [<addr-mode>] [<offset#2>]
                     17: # *
                     18: # *  any unused bytes will be padded with NOPs. At the end of the test
                     19: # *  code is a jump back to the instruction execution routine (below).
                     20: # *
                     21: # *  25-Jun-85 : added MULL2 / MULL3 changes
                     22: # *   1-Jul-85 : restore operand 2 between executions for MULL2.
                     23: # *  17-Jul-85 : look for FPM traps as instruction completion
                     24: # ************************************************************************
                     25:        .text
                     26:        .align 1
                     27:        .globl _run_code
                     28: _run_code:
                     29:        .word   0
                     30:        movpsl  _run_code_psl           /* save the current PSL            */
                     31:        callf   $4,_fill_code_buff      /* stuff the code buffer           */
                     32:        callf   $4,_set_psl             /* set up the initial PSL to use   */
                     33: # Save operand 2 for MULL2
                     34:        movl    *$_dmp_byte_op_2,_rc_bop2 /* save byte operand #2          */
                     35:        movl    *$_dmp_op_2,_rc_op2     /* save operand #2                 */
                     36: # Set the return from an FPP emulation trap
                     37:        clrl    _event_return
                     38:        tstl    _emulated_inst          /* should we get an FPM trap?      */
                     39:        beql    1f
                     40:        moval   _run_code_mtpr,_event_return    /* set the return address  */
                     41: 1:
                     42: # Run with an instruction cache miss
                     43:        clrl    _i_cache_hit            /* 1st pass gets a cache miss      */
                     44:        callf   $4,_run_test            /* run the test code w/ cache miss */
                     45: # Run with an instruction cache hit
                     46:        movl    $1,_i_cache_hit         /* 2nd pass gets a cache hit       */
                     47:        movl    _rc_bop2,*$_dmp_byte_op_2 /* restore byte operand #2       */
                     48:        movl    _rc_op2,*$_dmp_op_2     /* restore operand #2              */
                     49:        callf   $4,_run_test            /* run the test code again         */
                     50:        ret                             /* return                          */
                     51: 
                     52: 
                     53: 
                     54: 
                     55: 
                     56: # ************************************************************************
                     57: # *
                     58: # *            "RUN THE TEST" ROUTINE
                     59: # *
                     60: # *  This routine will set up the Instruction Code Cache Key and the
                     61: # *  memory map. It will call the routine that actually executes the
                     62: # *  test code ('_execute_code').
                     63: # *  looping on error is done in this routine.
                     64: # *
                     65: # ************************************************************************
                     66:        .text
                     67:        .align 1
                     68:        .globl _run_test
                     69: _run_test:
                     70:        .word   0
                     71:        clrl    _trans_acc_error        /* clear bad-acc-after-pg-flt flag */
                     72:        clrl    _fpm_trap_occurred      /* clear got-an-fpm-trap flag */
                     73:   
                     74: #########################################################################
                     75: # The error loop starts here:
                     76: # Get a new Code Cache Key to invalidate the instruction cache,
                     77: # Invalidate the instruction and data pages in the page table,
                     78: # and execute the test instrcution.
                     79: #########################################################################
                     80: _shift_loop:
                     81:        incl    _Codek                  /* Bump code cache key         */
                     82:        cmpl    _Codek,$255             /* Last key yet ?              */
                     83:        jlss    1f
                     84:        movl    $1,_Codek               /* Reset Code key to 1         */
                     85:        mtpr    $1,$PACC                /* Purge all code cache        */
                     86:        nop
                     87: 1:
                     88:        mtpr    _Codek,$CCK             /* Set new key                 */
                     89:  
                     90: #########################################################################
                     91: # If we're running in user mode, set up the stack pointer
                     92: # Invalidate the instruction and data pages in the page table,
                     93: # and execute the test instrcution.
                     94: #########################################################################
                     95:        tstl    _user_mode              /* are we in User mode?        */
                     96:        beql    1f
                     97:        callf   $4,_set_user_stack      /* set up the user stack data  */
                     98: 1:     callf   $4,_invalidate_pages    /* invalidate page tbl entries */
                     99:        callf   $4,_execute_code        /* execute code with pg faults */
                    100:   
                    101: #########################################################################
                    102: # If the Force Loop flag is set then loop on the error
                    103: #########################################################################
                    104:        tstl    _force_loop             /* Is "force_loop" set?   */
                    105:        beql    1f
                    106:        brw     _shift_loop             /* then loop on the error */
                    107: 1:
                    108: #########################################################################
                    109: #  Now verify the results of the instruction. 'test_ptr' points to the 
                    110: #  test routine to use. Check the Force Loop flag again to see if we
                    111: #  just had an error. If we don't start looping then exit.
                    112: #  If we're testing an emulated instruction then call the FPM checking
                    113: #  routine rather than the instruction's normal test routine.
                    114: #########################################################################
                    115:        callf   $4,_get_stored_value    /* get results of any store */
                    116:        tstl    _emulated_inst          /* emulated instruction?    */
                    117:        beql    1f
                    118:        callf   $4,_chk_fpm_trap        /* check the FPM interface  */
                    119:        brb     2f
                    120: 1:     calls   $4,*_test_ptr           /* verify the final results */
                    121: 2:     tstl    _force_loop             /* Is "force_loop" set?     */
                    122:        beql    1f
                    123:        jmp     _shift_loop             /* then loop on the error   */
                    124: 1:
                    125:        ret                             /* return */
                    126: 
                    127: 
                    128: 
                    129: 
                    130: 
                    131: # **************************************************************************
                    132: # *
                    133: # *    "ENABLE MEMORY MANAGEMENT AND EXECUTE THE CODE" Routine
                    134: # *
                    135: # *   Enable Memory Management, Load the ACC. and Execute the Test Code 
                    136: # *
                    137: # **************************************************************************
                    138:        .text
                    139:        .align  1
                    140:        .globl  _execute_code
                    141: _execute_code:
                    142:        .word   0
                    143:        moval   (r13),_ex_code_fp       /* save the frame pointer     */
                    144:        moval   (r14),_ex_code_sp       /* save the stack pointer     */
                    145:        clrl    _no_page_faults         /* clear the page fault count   */
                    146:        mtpr    $1,$TBIA                /* purge all Trans Buff entries */
                    147:        mtpr    $1,$MME                 /* enable memory management     */
                    148:        jmp     1f                      /* start the memory management  */
                    149: 1:
                    150:        cmpl    _acc_ld_size,$DBL
                    151:        beql    1f
                    152:        ldf     _dbl_ld_acc             /* load the sgl accumulator    */
                    153:        brb     2f                      /* or */
                    154: 1:     ldd     _dbl_ld_acc             /* load the dbl accumulator    */
                    155: 2:
                    156:        loadr   $0x3fff,_load_regs      /* load regs 0 - 13 (FP)       */
                    157:        movl    _init_psl,-(sp)         /* push the PSL to use         */
                    158:        movl    _code_addr,-(sp)        /* push the test code's PC     */
                    159:        clrl    _clock_event            /* clear diagnostic clock flag */
                    160:        tstl    _emulated_inst          /* check if inst is emulated   */
                    161:        beql    1f
                    162:        movl    $FPM_CODE,_exp_event    /* expect an FPM event         */
                    163: 1:
                    164:        rei                             /* switch modes & execute code */
                    165:        halt                            /* we shouldn't ever get here  */
                    166:  
                    167: ##########################################################################
                    168: # The only way here (knock on wood) is after the Translation faults.
                    169: # - Save the PSL, the registers, and the accumulator
                    170: ##########################################################################
                    171:        .globl _ex_code_return
                    172: _ex_code_return:
                    173:        movpsl  _psl_val                /* save the final PSL        */
                    174:        clrl    _exp_event              /* clear event-expected flag */
                    175:        storer  $0x3fff,_store_regs     /* store regs 0 - 13         */
                    176:        cmpl    _acc_st_size,$DBL
                    177:        beql    1f
                    178:        stf     _dbl_st_acc             /* store the sgl accumulator */
                    179:        brb     2f
                    180: 1:     std     _dbl_st_acc             /* store the dbl accumulator */
                    181: 2:
                    182: ##########################################################################
                    183: #  Disable Memory Management and Return
                    184: #     If we are in User mode the priveleged instruction fault handler will 
                    185: #     put us back into the Kernal Mode.
                    186: #    ( Return here after a floating point emulation (FPM) trap )
                    187: ##########################################################################
                    188:        .globl _run_code_mtpr
                    189: _run_code_mtpr:
                    190:        mtpr    $2,$MME                 /* disable memory management */
                    191:        nop
                    192:        mtpr    $_pcb0,$PCBB            /* set the current PCB addr  */
                    193:        movl    _ex_code_fp,fp          /* reload the frame pointer  */
                    194:        movl    _ex_code_sp,sp          /* reload the stack pointer  */
                    195:        ret                             /* return */
                    196: 
                    197: 
                    198: 
                    199: 
                    200: # *************************************************************************
                    201: # *
                    202: # *                    FILL IN THE CODE BUFFER ROUTINE
                    203: # *
                    204: # *  Set up the instruction code sequence  -shifted by 'shift_count'.
                    205: # *  After the instruction code, put a jump back to "run_code" and
                    206: # *  fill the rest of the code buffer with NOPs.
                    207: # *
                    208: # *************************************************************************
                    209:        .set    NOP_JMP,0x1010719f      /* jump to an absolute address */
                    210:        .text
                    211:        .align  1
                    212:        .globl  _fill_code_buff
                    213: _fill_code_buff:
                    214:        .word   0
                    215:        movl    $START_OF_CODE,r0
                    216:        addl2   _shift_count,r0         /* get the 1st addr for the code */
                    217:        movl    r0,_code_addr           /* save the starting address     */
                    218:        movab   _inst_buf,r1            /* get the address of the code   */
                    219: 1:     movb    (r1),(r0)               /* move the code to the code buf */
                    220:        incl    r0
                    221:        aoblss  $_end_of_inst_buf,r1,1b
                    222:  
                    223: ########################################################################
                    224: # Fill the rest of the buffer with NOPs
                    225: ########################################################################
                    226:        movl    $0x10,r1                /* 0x10 = NOP op-code         */
                    227: 1:     movb    r1,(r0)                 /* put NOPs in the code space */
                    228:        aobleq  $END_OF_CODE,r0,1b
                    229:   
                    230: ########################################################################
                    231: # After the instruction code, put a jump back to "_ex_code_return"
                    232: ########################################################################
                    233:        movl    $NOP_JMP,_sgl_dummy1    /* "<nop><nop><jmp><abs addr>" */
                    234:        clrl    r1
                    235: 1:     movb    _sgl_dummy1(r1),(r0)    /* move 'jmp' to the code buf */
                    236:        incl    r0
                    237:        aoblss  $4,r1,1b
                    238:   
                    239:        moval   _ex_code_return,_sgl_dummy1 /* jmp to 'ex_code_return' */
                    240:        clrl    r1
                    241: 1:     movb    _sgl_dummy1(r1),(r0)    /* move the code to the code buf */
                    242:        incl    r0
                    243:        aoblss  $4,r1,1b
                    244:        ret                             /* return */
                    245: 
                    246: 
                    247: 
                    248: 
                    249: 
                    250: # ***********************************************************************
                    251: # *
                    252: # *    SET UP THE INITIAL PSL TO BE USED WITH THE TEST 
                    253: # *
                    254: # ***********************************************************************
                    255:        .text
                    256:        .align  1
                    257:        .globl  _set_psl
                    258: _set_psl:
                    259:        .word   0
                    260:        tstl    _dbl_ld_acc             /* set the PSL flag bits */
                    261:        movpsl  _init_psl               /* current PSL = base PSL      */
                    262:        andl2   $0xffffff7f,_init_psl   /* clear the DBL acc bit       */
                    263:        cmpl    _acc_ld_size,$DBL       /* are we loading a DBL acc?   */
                    264:        bneq    1f                      /*    -NO, jump                */
                    265:        orl2    $PSL_DBL,_init_psl      /*    -Yes, set the DBL bit    */
                    266: 1:
                    267:        mfpr    $PCBB,r0                /* get the current PCB pointer */
                    268:        tstl    _user_mode              /* Run process in USER mode?   */
                    269:        bneq    1f                      /*   - yes                     */
                    270:        andl2   $0xfeffffff,_init_psl   /* clear the User Mode bit     */
                    271:        brb     2f
                    272: 1:
                    273:        andl2   $0xfbe0ffff,_init_psl   /* clear Int. Stack bit & IPL  */
                    274:        orl2    $0x01000000,_init_psl   /* set the PSL's User Mode bit */
                    275: 2:
                    276:        ret                             /* return */ 
                    277: 
                    278: 
                    279: 
                    280: 
                    281: 
                    282: # *************************************************************************
                    283: # *
                    284: # *    SET UP THE STACK POINTER AND THE STACK DATA FOR TESTS IN USER MODE
                    285: # *
                    286: # *  Set up the user stack pointer and set up the stack data for POP's
                    287: # *************************************************************************
                    288:        .text
                    289:        .align  1
                    290:        .globl  _set_user_stack
                    291: _set_user_stack:
                    292:        .word   0
                    293:        mfpr    $PCBB,r0                /* get the current PCB pointer */
                    294:        cmpl    $0x7e,_addr_code        /* PUSH addressing mode ?      */
                    295:        bneq    1f
                    296:        movl    $_sp_page,PCB_USP(r0)   /* set init PCB_USP for PUSH   */
                    297:        brb     2f
                    298: 1:     cmpl    $0x67,_op_code          /* PUSHD instruction?          */
                    299:        bneq    3f
                    300:        movl    $_sp_plus,PCB_USP(r0)   /* set init PCB_USP for PUSHD  */
                    301:        brb     2f
                    302: 3:     movl    $_sp_minus,PCB_USP(r0)  /* set init PCB_USP for other  */
                    303:  
                    304: #########################################################################
                    305: #      Now set up the data for POP addressing modes
                    306: #
                    307: #  This bit of code assumes that if op #1 is a popped that op #2 is too.
                    308: #  It also assumes that op #3 is never poppped -just it's address.
                    309: #########################################################################
                    310: 2:
                    311:        cmpl    $0x8e,_addr_code        /* POP SP addressing?          */
                    312:        beql    1f
                    313:        cmpl    $0x9e,_addr_code        /* POP SP deferred addr.?      */
                    314:        bneq    2f                      /* not POP -skip the rest      */
                    315:        cmpl    $3,_no_ops              /* check for 3 operands.       */
                    316:        bneq    1f
                    317:        movl    _sgl_value_10,_sp_plus  /* set up 3rd POP operand      */
                    318: 1:     cmpl    $1,_no_ops              /* check for 1 operand.        */
                    319:        beql    1f
                    320:        movl    _sgl_value_9,_sp_page   /* set up 2nd POP operand      */
                    321: 1:     movl    _sgl_value_8,_sp_minus  /* set up 1st POP operand      */
                    322: 2:
                    323:        ret                             /* return */ 
                    324: 
                    325: 
                    326: 
                    327: 
                    328: # ************************************************************************
                    329: # *
                    330: # *    INVALIDATE THE TEST PAGES IN THE PAGE TABLE ROUTINE
                    331: # *
                    332: # ************************************************************************
                    333:        .text
                    334:        .align  1
                    335:        .globl  _invalidate_pages
                    336: _invalidate_pages:
                    337:        .word   0
                    338:        movl    $START_OF_CODE,r0       /* get 1st code buffer address  */
                    339:        shar    $PGSHIFT,r0,r0          /* get 1st page # to invalidate */
                    340:        addl3   $15,r0,r1               /* invalidate 15 pages          */
                    341: 1:
                    342:        andl2   $0x7fffffff,_Sysmap[r0] /* mask out the Valid bit       */
                    343:        aoblss  r1,r0,1b                /*  ... for all test code pages */
                    344:        ret                             /* return */
                    345: 
                    346: 
                    347: 
                    348: 
                    349: # *************************************************************************
                    350: # *
                    351: # *    GET THE STORED VALUE FOR STORE OPERATIONS
                    352: # *
                    353: # *  The stored data will be put into 'dbl_value_3'.
                    354: # *  If the instruction is MULL2 or MULL3 call the appropriate routine.
                    355: # *  Otherwise, the store would have been onto the stack, to register(s) 0/1,
                    356: # *  or to memory -either in operand #1 or in byte-operand #1.
                    357: # *  If the instruction being tested isn't either MULL2, MULL3, or a 
                    358: # *  floating point store instruction then this routine will just exit.
                    359: # *
                    360: # *************************************************************************
                    361:        .text
                    362:        .align  1
                    363:        .globl  _get_stored_value
                    364: _get_stored_value:
                    365:        .word   0
                    366:        cmpl    _op_code,$MULL2_OP_CODE /* Are we testing MULL2?      */
                    367:        bneq    1f
                    368:        callf   $4,_get_mull2_store     /* then get MULL2's result    */
                    369:        ret                             /* return */
                    370: 1:
                    371:        cmpl    _op_code,$MULL3_OP_CODE /* Are we testing MULL2?      */
                    372:        bneq    1f
                    373:        callf   $4,_get_mull3_store     /* then get MULL3's result    */
                    374:        ret                             /* return */
                    375: 1:
                    376:        cmpl    $STORE,_op_type         /* was it a store operation?  */
                    377:        beql    1f
                    378:        ret                             /* return if not a store inst */
                    379: 1:
                    380:        cmpl    $0x7e,_addr_code        /* PUSH addressing mode ?     */
                    381:        beql    1f
                    382:        cmpl    $0x67,_op_code          /* PUSHD instruction?         */
                    383:        bneq    2f
                    384:        movl    _sp_page,_dbl_value_3+4 /* get the LS value pushed    */
                    385: 1:
                    386:        movl    _sp_minus,_dbl_value_3  /* get the operand pushed     */
                    387:        brw     3f
                    388: 2:
                    389: #########################################################################
                    390: #    - Next check to see if the store would be to register 0/1
                    391: #########################################################################
                    392:        cmpl    $ADR_REG,_addr_mode     /* register addressing mode?  */
                    393:        bneq    1f                      /*   -no                      */
                    394:        clrl    r0                      /*   -yes, get the MSW stored */
                    395:        movl    _store_regs[r0],_dbl_value_3    /* from the final r0. */
                    396:        incl    r0                      /* get the LSW value stored   */
                    397:        movl    _store_regs[r0],_dbl_value_3+4  /* from the final r1. */
                    398:        brw     3f
                    399: 1:
                    400: #########################################################################
                    401: #    - If not Stack or Register addressing, then the store went to memory
                    402: #########################################################################
                    403:        cmpl    $ADR_B_DSP,_addr_mode   /* byte displacement addressing? */
                    404:        bneq    1f                      /* branch if not byte addr.    */
                    405:        movl    $_dmp_byte_op_1,r0      /* get the addr of the operand */
                    406:        movl    (r0),_dbl_value_3       /* get the MS longwored stored */
                    407:        addl2   $4,r0
                    408:        movl    (r0),_dbl_value_3+4     /* get the LS longwored stored */
                    409:        brw     3f
                    410: 1:                                     /* byte disp. rel. addr. mode  */
                    411:        movl    $_dmp_op_1,r0           /* get the addr of the operand */
                    412:        movl    (r0),_dbl_value_3       /* get the MS longwored stored */
                    413:        addl2   $4,r0
                    414:        movl    (r0),_dbl_value_3+4     /* get the LS longwored stored */
                    415: 3:
                    416:        ret                             /* return */
                    417: 
                    418: 
                    419: 
                    420: 
                    421: # *************************************************************************
                    422: # *
                    423: # *    GET THE STORED VALUE FOR THE MULL2 INSTRUCTION
                    424: # *
                    425: # *  The stored data will be put into 'dbl_value_2'.
                    426: # *  The store would have been into register 4, or to memory -either in 
                    427: # *  operand #2 or in byte-operand #2.
                    428: # *
                    429: # *************************************************************************
                    430:        .text
                    431:        .align  1
                    432:        .globl  _get_mull2_store
                    433: _get_mull2_store:
                    434:        .word   0
                    435: #########################################################################
                    436: #    - Check to see if the store would be to register 6
                    437: #########################################################################
                    438:        cmpl    $ADR_REG,_addr_mode     /* register addressing mode?  */
                    439:        bneq    1f                      /*   -no                      */
                    440:        movl    $4,r0                   /*   -yes, get the data       */
                    441:        movl    _store_regs[r0],_dbl_value_3    /* from the final R4. */
                    442:        brw     3f
                    443: 1:
                    444: #########################################################################
                    445: #    - If not Register addressing, then the store went to memory
                    446: #########################################################################
                    447:        cmpl    $ADR_B_DSP,_addr_mode   /* byte displacement addressing? */
                    448:        bneq    1f                      /* branch if not byte addr.    */
                    449:        movl    $_dmp_byte_op_2,r0      /* get the addr of the operand */
                    450:        movl    (r0),_dbl_value_3       /* get the data stored         */
                    451:        brw     3f
                    452: 1:
                    453:        movl    $_dmp_op_2,r0           /* get the addr of the operand */
                    454:        movl    (r0),_dbl_value_3       /* get the data stored         */
                    455: 3:
                    456:        ret                             /* return */
                    457: 
                    458: 
                    459: 
                    460: 
                    461: # *************************************************************************
                    462: # *
                    463: # *    GET THE STORED VALUE FOR THE MULL3 INSTRUCTION
                    464: # *
                    465: # *  The stored data will be put into 'dbl_value_3'.
                    466: # *  The store would have been onto the stack, to a register ( R6 or R8 ),
                    467: # *  or to memory -either in operand #3 or in byte-operand #3.
                    468: # *
                    469: # *************************************************************************
                    470:        .text
                    471:        .align  1
                    472:        .globl  _get_mull3_store
                    473: _get_mull3_store:
                    474:        .word   0
                    475:        cmpl    $0x7e,_addr_code3       /* PUSH addressing mode ?  */
                    476:        bneq    1f
                    477:        movl    _sp_page,_dbl_value_3   /* get the pushed result   */
                    478:        brw     3f
                    479: 1:
                    480: #########################################################################
                    481: #    - Next check to see if the store would be to a register 
                    482: #########################################################################
                    483:        cmpl    $ADR_REG,_addr_mode     /* register addressing mode?  */
                    484:        bneq    4f                      /*   -no                      */
                    485:        cmpl    $0x56,_addr_code3       /* store to register 6?       */
                    486:        bneq    1f                      /*   -no                      */
                    487:        movl    $6,r0                   /*   -yes, check register 6.  */
                    488:        brb     2f
                    489: 1:     movl    $8,r0                   /*  get data from register 8. */
                    490: 2:     movl    _store_regs[r0],_dbl_value_3  /* get result from reg  */
                    491:        brw     3f
                    492: 4:
                    493: #########################################################################
                    494: #    - If not Stack or Register addressing, then the store went to memory
                    495: #########################################################################
                    496:        cmpl    $ADR_B_DSP,_addr_mode   /* byte displacement addressing? */
                    497:        bneq    1f                      /* branch if not byte addr.    */
                    498:        movl    $_dmp_byte_op_3,r0      /* get the addr of the operand */
                    499:        movl    (r0),_dbl_value_3       /* get the data stored         */
                    500:        brw     3f
                    501: 1:
                    502:        movl    $_dmp_op_3,r0           /* get the addr of the operand */
                    503:        movl    (r0),_dbl_value_3       /* get the data stored         */
                    504: 3:
                    505:        ret                             /* return */
                    506: 
                    507: 
                    508: 
                    509: ###########################################################################
                    510: #                      DATA STORAGE
                    511: ###########################################################################
                    512:        .align 2
                    513: _ex_code_sp:                           /* save stack pointer value here */
                    514:        .long   0
                    515: _ex_code_fp:                           /* save frame pointer value here */
                    516:        .long   0
                    517: _rc_bop2:                              /* save byte operand #2 here     */
                    518:        .long   0
                    519: _rc_op2:                               /* save operand #2 here          */
                    520:        .long   0
                    521: 
                    522: 

unix.superglobalmegacorp.com

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