.TITLE MACRO_IO_MOD ;======================================================================== ;= = ;= Programmer: Hunter Goatley = ;= Program: IOMOD.MAR (I/O routines) = ;= Language: VAX-11 assembler => MACRO-32 = ;= Purpose: Provide easy I/O from MACRO-32 (used with = ;= IOMAC.MLB) = ;= Shop: WKU/ACRS = ;= System: VAX 11/785 VAX/VMS v4.2 = ;= Date: October 27, 1985 = ;= = ;======================================================================== ;= = ;= Revision history: = ;= = ;= January 9, 1986 Added comments, cleaned up routines = ;= = ;= = ;======================================================================== ;= = ;= System services used: = ;= = ;= $ASSIGN Assign an I/O channel = ;= = ;= $QIOW Queue an I/O request and wait = ;= = ;======================================================================== ; ESC=27 CLRVT100: .ASCII /0;0H//[2J/ TTCHAN: .LONG 0 TTNAME: .ASCID /SYS$COMMAND/ ; .PSECT IO_INIT ;======================================================================== ;= = ;= IO_INIT Routine = ;= = ;= Function: = ;= = ;= This routine is called once to initialize I/O to the = ;= terminal (SYS$COMMAND). = ;= = ;= Parameters: = ;= = ;= None. = ;= = ;= Implicit inputs: = ;= = ;= TTCHAN, TTNAME = ;= = ;= Output: = ;= = ;= None. = ;= = ;= Effects: = ;= = ;= An I/O channel is assigned to SYS$COMMAND. = ;= = ;= Sample call: = ;= = ;= CALLS #0,IO_INIT = ;= = ;======================================================================== ; IO_INIT:: .WORD 0 $ASSIGN_S - ; Assign the I/O channel CHAN=TTCHAN, - ; Longword to hold channel number DEVNAM=TTNAME ; Name of I/O device RET ; Return to caller ; .PSECT CLRSCR ;======================================================================== ;= = ;= CLRSCR Routine = ;= = ;= Function: = ;= = ;= This routine clears a VT100-compatible terminal. = ;= = ;= Parameters: = ;= = ;= None. = ;= = ;= Implicit inputs: = ;= = ;= CLRVT100; Calls PUT_OUT = ;= = ;= Output: = ;= = ;= ANSI ESCape sequences to clear the screen. = ;= = ;= Effects: = ;= = ;= R0 and R1 may be destroyed. = ;= = ;= Sample call: = ;= = ;= CALLS #0,CLRVT100 ; Clear VT100 screen = ;= = ;======================================================================== ; CLRSCR:: .WORD 0 PUSHAB CLRVT100 ; Push the ESCape seq address PUSHL #9 ; Push the length of buffer (bytes) CALLS #2,PUT_OUT ; Print it RET ; Return to the caller LEN=4 ADDR=8 .PSECT PUT_OUT ;======================================================================== ;= = ;= PUT_OUT Routine = ;= = ;= Function: = ;= = ;= This routine is called to print ASCII characters to = ;= SYS$COMMAND. = ;= = ;= Parameters: = ;= = ;= The address of a buffer containing ASCII code and the = ;= length (in bytes) of the string. = ;= = ;= Implicit inputs: = ;= = ;= TTCHAN = ;= = ;= Output: = ;= = ;= The codes stored at location passed to routine. = ;= = ;= Effects: = ;= = ;= R0 and R1 may be destroyed. = ;= = ;= Sample call: = ;= = ;= PUSHAB BUFFER ; Push the buffer address = ;= PUSHL #80 ; Push the buffer length = ;= CALLS #2,PUT_OUT ; Print it = ;= = ;======================================================================== ; PUT_OUT:: .WORD 0 $QIOW_S CHAN=TTCHAN, - ; Print to I/O channel in TTCHAN FUNC=#IO$_WRITEVBLK, - ; Write a virtual block P1=@ADDR(AP), - ; The address is in call frame P2=LEN(AP) ; The length is in call frame RET ; Return to caller ; .PSECT PRINT0 ;======================================================================== ;= = ;= PRINT0 Routine = ;= = ;= Function: = ;= = ;= This routine accepts as a parameter the starting = ;= address of a buffer containing ASCII codes. The = ;= data is printed to the terminal (80 chars at a = ;= time) until a byte containing 0 is encountered. = ;= = ;= Parameters: = ;= = ;= The beginning address = ;= = ;= Implicit inputs: = ;= = ;= Calls routines PUT_OUT and CRLF_OUT. = ;= = ;= Output: = ;= = ;= The bytes between the starting address and the 0 byte. = ;= = ;= Effects: = ;= = ;= R0 and R1 may be destroyed. = ;= = ;= Sample call: = ;= = ;= PUSHAB BUFFER ; Push the starting address = ;= CALLS #1,PRINT0 ; Start printing = ;= = ;======================================================================== ; .ENTRY PRINT0,^M MOVL 4(AP),R3 ; Move the starting address to R3 10$: LOCC #0,#80,(R3) ; Find 0 to stop processing MOVL R0,R2 ; Save R0 (if 0, byte not found) SUBL2 R3,R1 ; Get the length of the string to print PUSHAL (R3) ; Push the address of print buffer PUSHL R1 ; Push the length CALLS #2,PUT_OUT ; Print it ADDL2 #80,R3 ; Bump up pointer past string printed TSTL R2 ; Was the 0 byte found? BEQL 10$ ; No go print next set of chars CALLS #0,CRLF_OUT ; Print combo RET ; Yes -- return to calling procedure ; ; CRLF: .BYTE 13,10 .PSECT CRLF_OUT ;======================================================================== ;= = ;= CRLF_OUT Routine = ;= = ;= Function: = ;= = ;= This routine prints a combination to the = ;= terminal (SYS$COMMAND). = ;= = ;= Parameters: = ;= = ;= None. = ;= = ;= Implicit inputs: = ;= = ;= CRLF; Calls PUT_OUT routine = ;= = ;= Output: = ;= = ;= A combo. = ;= = ;= Effects: = ;= = ;= R0 and R1 may be destroyed. = ;= = ;= Sample call: = ;= = ;= CALLS #0,CRLF_OUT = ;= = ;======================================================================== ; CRLF_OUT:: .WORD 0 PUSHAB CRLF ; Push the address of the PUSHL #2 ; Push the length of the buffer (bytes) CALLS #2,PUT_OUT ; Print it RET ; Return to caller ; ;======================================================================== ;= = ;= GETLIN routine = ;= = ;= Function: = ;= = ;= This routine reads a string from SYS$COMMAND. The = ;= input string is placed at the address specified by = ;= the buffer name passed to it. = ;= = ;= Parameters: = ;= = ;= Buffer address and length to read. = ;= = ;= Implicit inputs: = ;= = ;= None. = ;= = ;= Output: = ;= = ;= None. = ;= = ;= Sample call: = ;= = ;= PUSHAB BUFFER ; Push the buffer address = ;= PUSHL #80 ; Push the number of bytes = ;= CALLS #2,G^GETLIN ; Get the input = ;= = ;======================================================================== ; ADDR=8 LEN=4 GETLIN:: .WORD 0 $QIOW_S CHAN=TTCHAN, - ; Read from I/O channel in TTCHAN FUNC=#IO$_READVBLK, - ; Read a virtual block P1=@ADDR(AP), - ; The address is in call frame P2=LEN(AP) ; The length is in call frame RET ; Return to caller ; .END