home *** CD-ROM | disk | FTP | other *** search
- INCLUDE "exec/types.i"
- INCLUDE "exec/tasks.i"
- INCLUDE "exec/memory.i"
- INCLUDE "exec/funcdef.i"
- INCLUDE "exec/exec_lib.i"
- INCLUDE "libraries/dos_lib.i"
- INCLUDE "libraries/dos.i"
- INCLUDE "intuition/intuition.i"
-
- csect wreq.o,0,0,1,2
-
- xdef _autorequest
- xdef __main
-
- NULL EQU 0 ; Pointing to nowhere
- absexecbase EQU 4 ; Adress to get the ExecBase
- CR EQU 13 ; Carriage return
- LF EQU 10 ; Line feed
- TRUE EQU 1 ; Boolean TRUE-value
- FALSE EQU 0 ; Boolean FALSE-value
- autoreqoffset EQU $FEA4 ; Library offset
- ONE EQU '1' ; Primary option
- TWO EQU '2' ; Secondary option
- HIT_RET_LEN EQU 27 ; Prompt lenght
- UP_CASE EQU $DF ; Bit 5 masked
- FIRST_LEGAL EQU 'A' ; First alphabet
- LAST_LEGAL EQU 'Z' ; End of range
- OPT_LEN EQU 4 ; Lenght per option query
- WRITING EQU 10000 ; Not just measuring
- ONE_LINE EQU 20000 ; No linefeeds
- MAX_COL EQU 76 ; Max line lenght
- MAX_OPT EQU 72 ; Including the option
- OPT_ONE_LINE EQU 13 ; For both in same line
- LIST_LEN EQU 64 ; Lenght of the index list
-
- __main MOVEM.L A2/D2,-(A7) ; save registers
- MOVEA.L absexecbase,A6 ; Exec-librarys base to use
- LEA intuitionname(PC),A1 ; A1 = Name of the library
- MOVEQ #0,D0 ; D0 = Version
- JSR _LVOOpenLibrary(A6) ;Open the intuition-library
- CMPI.L #NULL,D0 ; If the library pointer is NULL
- BEQ s_exit ; Then exit immediately
- MOVEA.L D0,A2 ; Save the pointer to library
- LEA _autorequest(PC),A0 ; Start of function
- LEA intuitionname(PC),A1 ; End of function and data
- SUBA.L A0,A1 ; Calculate the size
- MOVE.L A1,D2 ; Save the size
- MOVE.L A1,D0 ; D0 = Size in bytes
- MOVE.L #MEMF_PUBLIC,D1 ; D1 = Requirements
- JSR _LVOAllocMem(A6) ; Allocate memory
- CMPI.L #NULL,D0 ; If there was no memory
- BEQ close ; Then close and exit
- MOVEA.L D0,A1 ; D0 = Pointer to memory
- SUBQ.W #1,D2 ; Adjust the counter
- LEA _autorequest(PC),A0 ; Pointer to function
- copyfunc MOVE.B (A0)+,(A1)+ ; Copy bytes
- DBRA D2,copyfunc ; Decrement and branch
- MOVEA.L #autoreqoffset,A0 ; A0 = library offset
- MOVEA.L A2,A1 ; A1 = pointer to library
- JSR _LVOSetFunction(A6) ; Replace function
- close MOVEA.L A2,A1 ; Restore the pointer to library
- JSR _LVOCloseLibrary(A6) ; Close intuition-library
- s_exit MOVEQ #FALSE,D0 ; Return FALSE
- MOVEM.L (A7)+,A2/D2 ; Restore registers
- RTS ; Return to caller
-
- _autorequest MOVEM.L D2-D7/A2-A6,-(A7) ; Save registers
- MOVEQ #FALSE,D6 ; Return FALSE
- MOVE.L A1,A4 ; A1 -> Bodytext (IntuiText)
- MOVEA.L absexecbase,A6 ; Exec-librarys base to use
- MOVEA.L #0,A1 ; A1 = NULL (my task)
- JSR _LVOFindTask(A6) ; Find the task structure
- MOVEA.L D0,A1 ; Structure base to A1
- CMPI.B #NT_PROCESS,LN_TYPE(A1) ;If my task is not a process
- BNE a_exit ; Then exit immediately
- LEA doslibname(PC),A1 ; A1 = Name of the dos-library
- MOVEQ #0,D0 ; D0 = Version
- JSR _LVOOpenLibrary(A6) ;Open dos-library
- CMPI.L #NULL,D0 ; If the library pointer is NULL
- BEQ a_exit ; Then exit immediately
- MOVEA.L D0,A6 ; Dos-librarys base to use
- JSR _LVOInput(A6) ; Get standard input file
- CMPI.L #NULL,D0 ; If the file pointer is NULL
- BEQ done ; Then do not write
- LEA input(PC),A0 ; Get storing address
- MOVE.L D0,(A0) ; Save the file pointer
- MOVE.L D0,D1 ; D1 = file pointer
- JSR _LVOIsInteractive(A6) ;Check the input file type
- TST.L D0 ; If not interactive
- BEQ done ; Then do not write
- JSR _LVOOutput(A6) ; Get standard output file
- CMPI.L #NULL,D0 ; If the file pointer is NULL
- BEQ done ; Then do not write
- MOVE.L D0,D4 ; Save file pointer in D4
- CMPA.L #NULL,A2 ; If the positive text not NULL
- BNE may_query ; Query is still possible
- CMPA.L #NULL,A3 ; If the negative text not NULL
- BNE no_options ; No need to query
- CMPA.L #NULL,A4 ; If the body text is also NULL
- BEQ done ; Then no text to display
- no_options LEA posit(PC),A0 ; Pointer to good option
- MOVE.B #0,(A0)+ ; Mark it meaningless
- BRA options_set ; Go to display text
- may_query CMPA.L #NULL,A3 ; If the negative text not NULL
- BNE query ; Then read line
- MOVEQ #TRUE,D6 ; Return TRUE
- BRA no_options ; No other option
- query MOVEQ #0,D7 ; Zero the counters
- MOVEA.L A3,A5 ; A5 = negative text
- JSR writetext(PC) ; Sort the text
- MOVEA.L first(PC),A0 ; Pointer to negative string
- MOVE.L A0,-(A7) ; Save the negative pointer
- MOVEA.L A2,A5 ; A5 = positive text
- JSR writetext(PC) ; Sort the text
- MOVEA.L first(PC),A0 ; Pointer to positive string
- MOVEA.L (A7)+,A1 ; Restore the negative pointer
- MOVE.B (A0),D0 ; First character
- JSR check_char ; Check if legal
- TST.B D0 ; Was it illegal?
- BEQ one_two ; Then ask with numbers
- LEA posit(PC),A0 ; Positive option = first char
- MOVE.B D0,(A0)+ ; A0 -> negat
- MOVE.B (A1),D0 ; First character
- JSR check_char ; Check if legal
- TST.B D0 ; Was it illegal?
- BEQ one_two ; Then ask with numbers
- MOVE.B D0,(A0)+ ; Negative option = first char
- CMP.B posit(PC),D0 ; Aren't the options identical?
- BNE options_set ; Then they are ok.
- one_two LEA posit(PC),A0 ; A0 -> positive option
- MOVE.B #ONE,(A0)+ ; Positive option = '1'
- MOVE.B #TWO,(A0)+ ; Negative option = '2'
- options_set JSR linefeed(PC) ; D4 = file pointer
- MOVEQ #0,D7 ; Zero the counter
- MOVEA.L A4,A5 ; A5 = body text
- JSR writetext(PC) ; Measure text
- MOVEA.L A4,A5 ; A5 = body text
- CMP.W #MAX_COL,D7 ; Is it too long for one line
- BHI high_body ; Then use many lines
- MOVE.W #ONE_LINE,D7 ; Use one line
- BRA write_body ; Go to write it
- high_body MOVE.W #WRITING,D7 ; Set write mode
- write_body JSR writetext(PC) ; Write body text
- CMPI.W #WRITING,D7 ; Is there LF already
- BEQ ask_option ; Then don't write an other one
- JSR linefeed(PC) ; D4 = file pointer
- ask_option SWAP D6 ; Save return value
- MOVE.W #OPT_ONE_LINE,D6 ; Set counter starting value
- MOVEQ #0,D7 ; Zero the counters
- MOVEA.L A3,A5 ; A5 = negative text
- JSR writetext(PC) ; Measure text
- ADD.W D7,D6 ; Add lenght to counter
- CMP.W #MAX_OPT,D7 ; Is it too long for one line
- BHI high_negat ; Then use many lines
- MOVE.W #ONE_LINE,D7 ; Use one line
- BRA normal_negat ; Go to write it
- high_negat MOVE.W #WRITING,D7 ; Set write mode
- normal_negat SWAP D7 ; Save value
- MOVEA.L A2,A5 ; A5 = positive text
- JSR writetext(PC) ; Measure text
- ADD.W D7,D6 ; Add lenght to counter
- CMP.W #MAX_OPT,D7 ; Is it too long for one line
- BHI high_posit ; Then use many lines
- MOVE.W #ONE_LINE,D7 ; Use one line
- BRA normal_posit ; Go to write it
- high_posit MOVE.W #WRITING,D7 ; Set write mode
- normal_posit MOVEQ #0,D0 ; Get zero
- CMP.B posit(PC),D0 ; Is option meaningless
- BEQ reply ; Then just wait for RETURN
- CMP.W #MAX_COL,D6 ; Are the options too long
- BHI too_long ; Then use separate lines
- MOVE.W #0,D6 ; Use one line for options
- BRA show_options ; Go to show the options
- too_long JSR linefeed(PC) ; D4 = file pointer
- show_options LEA option(PC),A0 ; Pointer to option
- MOVE.B posit(PC),0(A0) ; Option is positive
- MOVEQ #OPT_LEN,D3 ; D3 = lenght of write
- JSR write_out(PC) ; Write to output
- MOVEA.L A2,A5 ; A5 = positive text
- JSR writetext(PC) ; Write it out
- TST.W D6 ; Aren't we using separate lines?
- BEQ write_mid ; Then separate options
- CMPI.W #WRITING,D7 ; Is there LF already
- BEQ show_negat ; Then don't write an other one
- JSR linefeed(PC) ; D4 = file pointer
- BRA show_negat ; Go to show the negative option
- write_mid LEA mid_part(PC),A0 ; Pointer to option separator
- JSR write_two(PC) ; Write it out
- show_negat LEA option(PC),A0 ; Pointer option
- MOVE.B negat(PC),0(A0) ; Option is negative
- MOVEQ #OPT_LEN,D3 ; D3 = lenght of write
- JSR write_out(PC) ; Write to output
- SWAP D7 ; Restore value
- MOVEA.L A3,A5 ; A5 = negative text
- JSR writetext(PC) ; Write it out
- TST.W D6 ; Aren't we using separate lines?
- BEQ right_after ; Then put it right after
- CMPI.W #WRITING,D7 ; Is there LF already
- BEQ right_after ; Then don't write an other one
- JSR linefeed(PC) ; D4 = file pointer
- right_after LEA prompt(PC),A0 ; Pointer to prompt
- JSR write_two(PC) ; Write lenght of two
- BRA wait ; Go to wait answer
- reply MOVEA.L A2,A5 ; A5 = positive text
- JSR writetext(PC) ; Write it out
- SWAP D7 ; Restore value
- MOVEA.L A3,A5 ; A5 = negative text
- JSR writetext(PC) ; Write it out
- LEA hit_ret(PC),A0 ; Pointer to Press RETURN text
- MOVE.L #HIT_RET_LEN,D3 ; D3 = lenght of write
- jsr write_out(PC) ; Write it out
- wait MOVE.L input(PC),D5 ; Restore input file pointer
- SWAP D6 ; Restore return value
- LEA answer(PC),A0 ; Pointer to answer
- MOVE.L D5,D1 ; D1 = pointer to file (input)
- MOVE.L A0,D2 ; D2 = pointer to buffer
- MOVEQ #1,D3 ; D3 = lenght of read
- JSR _LVORead(A6) ; Read a character
- MOVEA.L D2,A0 ; Reastore pointer
- CMPI.B #LF,(A0) ; Was it end of the line
- BEQ empty ; Then stop reading
- LEA bucket(PC),A0 ; Pointer to bucket
- MOVE.L A0,D2 ; D2 = pointer to buffer
- read_next MOVE.L D5,D1 ; D1 = pointer to file (input)
- JSR _LVORead(A6) ; Read a character
- MOVEA.L D2,A0 ; Reastore pointer
- CMPI.B #LF,(A0) ; Wasn't it end of the line
- BNE read_next ; Then read next character
- empty MOVEQ #0,D0 ; Get zero
- CMP.B posit(PC),D0 ; Is the option meaningless
- BEQ done ; Then the job is done
- MOVE.B answer(PC),D0 ; Pointer to answer
- CMPI.B #FIRST_LEGAL,D0 ; Can it be digit
- BLT digit ; Then don't modify
- ANDI.B #UP_CASE,D0 ; Convert to upper case
- digit CMP.B negat(PC),D0 ; Is it negative
- BEQ done ; Then go return FALSE
- CMP.B posit(PC),D0 ; Isn't it positive
- BNE ask_option ; Then go to ask again
- MOVEQ #TRUE,D6 ; Return TRUE
- done MOVEA.L A6,A1 ; A1 = pointer to library (dos)
- MOVEA.L absexecbase,A6 ; Exec-librarys base to use
- JSR _LVOCloseLibrary(A6) ; Close dos-library
- a_exit MOVEQ #0,D0 ; Zero the long register
- MOVE.B D6,D0 ; Boolean return value
- MOVEM.L (A7)+,D2-D7/A2-A6 ; Restore registers
- RTS ; Return to caller
-
- writetext LEA list(PC),A0 ; Pointer to index list
- MOVEA.L A5,A1 ; Pointer to first structure
- MOVEQ #0,D5 ; Zero the index counter
- count_next CMPA.L #NULL,A1 ; If the IntuiText pointer is NULL
- BEQ last ; Then this was the last one
- MOVE.B D5,(A0)+ ; Put index to list
- ADDQ.B #1,D5 ; Increment the index
- CMPI.W #LIST_LEN,D5 ; If the index is too big
- BEQ last ; Then this was the last one
- MOVEA.L it_NextText(A1),A1 ; Pointer to next IntuiText
- BRA count_next ; Next structure
- last TST.B D5 ; Was there NULL-pointer
- BEQ return ; Then return to caller
- MOVE.L D5,D3 ; Initialize outer counter
- SUBQ.B #2,D3 ; Adjust the counter
- BMI sorted ; Nothing to sort?
- outer_loop MOVEQ #0,D2 ; Initialize inner counter
- inner_loop LEA list(PC,D2.W),A1 ; Pointer to current index
- ADDQ.B #1,D2 ; Increment inner counter
- CMP.B D5,D2 ; If counter reached max value
- BEQ loop_end ; Then the loop has exhausted
- MOVEQ #0,D0 ; Zero the register
- MOVE.B (A1)+,D0 ; Get index value
- JSR getstruct(PC) ; Get current structure
- MOVEQ #0,D0 ; Zero the register
- MOVE.B (A1),D0 ; Get next index value
- MOVEA.L A0,A1 ; Current structure to A1
- JSR getstruct(PC) ; Get next structure
- MOVE.W it_TopEdge(A0),D0 ; Get the next top edge
- CMP.W it_TopEdge(A1),D0 ; If current < next top edge
- BLT inner_loop ; Then don't swap them
- BNE swap ; Swap only if not equal
- MOVE.W it_LeftEdge(A0),D0 ; Get the next left edge
- CMP.W it_LeftEdge(A1),D0 ; If current < next left edge
- BLT inner_loop ; Then don't swap them
- swap LEA list(PC,D2.W),A0 ; Pointer to next index
- MOVE.B (A0),D0 ; Get next index value
- SWAP D0 ; Save next index value
- MOVE.B -(A0),D0 ; Get current index value
- SWAP D0 ; Swap index values
- MOVE.B D0,(A0)+ ; Set current index value
- SWAP D0 ; Restore next index value
- MOVE.B D0,(A0)+ ; Set next index value
- BRA inner_loop ; Continue looping
- loop_end DBRA D3,outer_loop ; Check if outer loop done
- sorted MOVE.L D5,D0 ; Get counter value
- SUBQ.B #1,D0 ; Point to last index
- MOVE.B list(PC,D0.W),D0 ; Get last index value
- JSR getstruct(PC) ; Get last IntuiText structure
- LEA first(PC),A1 ; Pointer to saving address
- MOVE.L it_IText(A0),(A1)+ ; Save string pointer
- BRA check_counter ; Go to write loop
-
- list DS.B LIST_LEN ; Sorttable index list
-
- continue MOVEQ #0,D0 ; Zero the register
- MOVE.B list(PC,D5.W),D0 ; Get current index value
- JSR getstruct(PC) ; Get current structure
- MOVEA.L it_IText(A0),A0 ; Pointer to string
- MOVE.L A0,D2 ; D2 = NULL-terminated string
- MOVEQ #-1,D3 ; D3 = lenght to be written
- strlen ADDQ.L #1,D3 ; Increment lenght
- TST.B (A0)+ ; While terminator not found
- BNE strlen ; If lenght = 0 then D3 = -1 + 1
- CMPI.W #WRITING,D7 ; Are we actually writing this
- BGE writing ; Then go to write it
- ADD.W D3,D7 ; Add lenght to counter
- ADDQ.W #1,D7 ; Add one for space character
- BRA check_counter ; Continue measuring
- writing JSR write_file(PC) ; Write to output
- CMPI.W #ONE_LINE,D7 ; Are we using only one line
- BEQ put_space ; Then don't write linefeed
- writenext JSR linefeed(PC) ; D4 = file pointer
- check_counter DBRA D5,continue ; If counter exhausted
- return RTS ; Then return to caller
-
- put_space TST.B D5 ; If counter exhausting
- BEQ return ; Then the write is done
- LEA space(PC),A0 ; Pointer to space string
- MOVEQ #1,D3 ; D3 = lenght of write
- JSR write_out(PC) ; Write the space character
- BRA sorted ; Continue the line
-
- getstruct MOVEA.L A5,A0 ; Pointer to first structure
- BRA dec_counter ; Go to counting loop
- next_struct MOVEA.L it_NextText(A0),A0 ; Pointer to next IntuiText
- dec_counter DBRA D0,next_struct ; If counter exhausted
- RTS ; Then return to caller
-
- linefeed LEA crlf(PC),A0 ; Pointer to line-end string
- write_two MOVEQ #2,D3 ; D3 = lenght to be written
- write_out MOVE.L A0,D2 ; D2 = string (not terminated)
- write_file MOVE.L D4,D1 ; D1 = file pointer
- JMP _LVOWrite(A6) ; Write to output
-
- check_char CMPI.B #FIRST_LEGAL,D0 ; Is it less than 'A'
- BLT not_a_z ; Then it's not legal
- ANDI.B #UP_CASE,D0 ; Convert to upper case
- CMPI.B #LAST_LEGAL,D0 ; Is it less or equal to 'Z'
- BLE legal ; Then it's legal
- not_a_z MOVEQ #0,D0 ; Zero means illegal
- legal RTS ; Return to caller
-
- input DC.L 0 ; Pointer to input file
- first DC.L 0 ; First IntuiText string
- doslibname DOSNAME ; Name of the dos-library
- crlf DC.B CR,LF ; End of line characters
- prompt DC.B '?' ; Prompt for query
- space DC.B ' ' ; Space for separator
- mid_part DC.B ', ' ; Option separator
- option DC.B 'X = ' ; Option expression
- answer DC.B ' ' ; Store for the answer
- bucket DC.B ' ' ; Store for the rest ones
- posit DC.B 0 ; Positive option
- negat DC.B 0 ; Negative option
- hit_ret DC.B LF,'Press RETURN to continue! ' ;Dummy query
- intuitionname DC.B 'intuition.library',0 ; Name of the intuition-library
-
- END
-