.title six_stack -- routines to manipulate the record-number-test stack .library 'six' ;============================================================================= ; psect _SIX_STACK ; notes: ; The stack, SIX_STACK_STACK, is a list of quadword ranges which ; grows upwards in memory. The ranges are used to test records ; to see whether they have been selected to be printed. ; The variable SIX_STACK_PTR points to the end of the list. ; That is, to the first unoccupied quadword. ; Ranges are formed of two consecutive signed longword integers: ; the first integer is the first selected record number, and ; the second integer is the last selected record number. ; Positive numbers count from the first record in the file (record 1). ; Non-positive numbers count from the last record in the file (record 0). ; ;============================================================================= _lsect _six_stack six_stack_stack:: .long 0 [40] six_stack_ptr:: .address six_stack_stack six_stack_limits:: ; defaults for ranges .long 1, 0 ;============================================================================== _esect _six_code ;----------------------------------------------------------------------------- ; jsb routine SIX_STACK_PUSH_HEAD ; r0 = addr of desc. to string containing integer tail-length => (scratch) ;-------------------- six_stack_push_head:: moval -(sp), -(sp) ; convert string to integer movaq (r0), -(sp) calls #2, g^ots$cvt_ti_l _if_err <, - ; on error goto six_err_number <_fade #six__number>> movl six_stack_ptr, r1 ; push range (1:n) onto the stack movl #1, (r1)+ movl (sp)+, (r1)+ movl r1, six_stack_ptr movl #1, r0 rsb ; return ;----------------------------------------------------------------------------- ; jsb routine SIX_STACK_PUSH_TAIL ; r0 = addr of desc. to string containing integer tail-length => (scratch) ;-------------------- six_stack_push_tail:: moval -(sp), -(sp) ; convert string to integer movaq (r0), -(sp) calls #2, g^ots$cvt_ti_l _if_err <, - ; on error goto six_err_number <_fade #six__number>> movl six_stack_ptr, r1 ; push range (-n+1:0) onto the stack movl #1, (r1)+ subl3 #1, (sp)+, r0 mnegl r0, (r1)+ movl r1, six_stack_ptr movl #1, r0 rsb ; return ;----------------------------------------------------------------------------- ; jsb point six_stack_push_range ; parameters: ; r0 should contain the address of a string containing the text ; representation of one range. If multiple ranges were specified ; on the command line, this routine will be called once with each. ; registers: ; r0 = addr of string desc --> success status (0 or 1) ;--------------------------------- six_stack_push_range:: pushaq six_stack_limits ; call routine to translate pushaq @six_stack_ptr ; string into quadword range pushaq (r0) calls #3, trn$range_q _if_leq r0, <, - ; on error goto six_err_range <_fade #six__range>> addl2 #4, six_stack_ptr ; update stack ptr movl #1, r0 rsb ;----------------------------------------------------------------------------- ; jsb point SIX_STACK_TEST_REC ; notes: ; range quadword takes the form of (n:m), where n is the first record, ; and m is the last. Negative numbers are counting back from the last ; record in the file (record 0). When the look-ahead ptr encounters the ; end of the file, R7 is set to 0; only then can we test negative values. ; ; registers: ; r0 = (scratch) --> T/F success code ; r1 = (scratch) --> (scratch) ; r7 = lookahead pointer --> (unchanged) ; (zero if end-of-file has been found) ; r8 = current record number --> (unchanged) ; r9 = lookahead pointer record number --> (unchanged) ; (if r7=0, r9=end-of-file-record-number) ;------------------------------ six_stack_test_rec:: ; test current record number against tstl r8 ; all the quadword ranges in the stack. beql six_stack_no movaq six_stack_stack, r1 six_stack_tst_n: ; is N negative or positive? tstl (r1) bleq six_stack_neg_n six_stack_pos_n: ; test potitive N cmpl r8, (r1) blss six_stack_not_yet brb six_stack_tst_m six_stack_neg_n: ; test negative N tstl r7 bneq six_stack_not_yet addl3 (r1), r9, r0 ; r0 = eof_rec + N cmpl r8, r0 ; r8 = cur_rec blss six_stack_not_yet six_stack_tst_m: ; is M negative or positive? tstl 4(r1) beql six_stack_yes bleq six_stack_neg_m six_stack_pos_m: ; test positive M cmpl r8, 4(r1) bgtr six_stack_not_yet brb six_stack_yes six_stack_neg_m: ; test negative M tstl r7 bneq six_stack_yes addl3 4(r1), r9, r0 ; r0 = eof_rec + M cmpl r8, r0 ; r8 = cur_rec bgtr six_stack_not_yet six_stack_yes: ; this test succeeds...return success. movl #1, r0 rsb six_stack_not_yet: ; this test fails, try the next addl2 #8, r1 cmpl r1, six_stack_ptr blss six_stack_tst_n six_stack_no: ; no more tests...return failure. clrl r0 rsb ;============================================================================== .end