LBSOS KRNLI/O ERRORFILE 'SOS.KERNEL' NOT FOUNDINVALID KERNEL FILExةw,@  4  J  ȱ⩤i8#) ) 8Le Title: The Pull Down Menu Unit Created by Pair Software 11/12/1988 17:33:11 The Pull_Down_Menus Unit by John E. Cisar By now everyone but the most novice personal computer user has seen pull down menus in some form or another. Pull down menus hav? z0 &READ.ME.FIRST0})#RGB 600%SEG.T j0 Ÿ/ III.PAR.O2AIRu' -BIB.ASCII.PT2)NӴ 'CISAR.1ULL.DOWNsJ0̴ 'CISAR.2{#5B, 'CISAR.3%G-DISKNAME.DAT*MENU.MAKER m#im#iЛ#Lȱ  6L憦  Lsmm l y` @8(Je稽 ʈe quickly become the computer industry "standard" for user interface in both graphics environments (i.e. the macintosh) and non-graphics environments (i.e. turbo lightning on the ibm pc). A pull down menu consists of "menu headers" listed horizontall  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyrograms without the worry of writing (or cannibalizing) menu routines. Since the PDM unit is intrinsic you have the further advantages of no linking and no compiling when you use it (all you need is a "uses PDM;" statement after your program headin for the pull down menu (or pdm) unit. PDM is a PASCAL intrinsic library unit that emulates a bitmapped graphics pull down menu system without a mouse. Input is accomplished by means of the keystrokes described above. with PDM you can now write PASCAL ppull down menus. The Apple /// text mode allows limited bit-mapped graphics by means of down-loadable font characters. This translates into a graphics looking interface without the overhead of bit-mapped graphics! Figure 1 contains the source code and down arrow keys and can execute the option by pressing the key again. Additionally, if no option is wanted, the user can press the key to erase the option list. The Apple /// presents a unique environment in which to execute e same as the graphics environment. When using a keyboard to simulate a mouse, the user "points" to a menu header by means of the left and right arrow keys, then "clicks" by means of the key. The user can "select" an option by using the upa non-graphics mode and use a combination of keystrokes to simulate the mouse. By using the non-graphics environment (that is the "text" mode), the pull down menu may lose some cosmetic attributes (i.e. A box with shadows),but the content is exactly ths have been enhanced with pull down menus. However, pull down menus do not require bit-mapped graphics or a mouse to be used effectively. in fact, many programs available for the Apple and IBM family of personal computers work just fine in graphics environment. The Macintosh quickly followed with an even more enhanced pull down menu system. It also came standard with a mouse and operated exclusively in a bit-mapped graphics environment. Ever since then, most new and many old applicationg splash with the introduction of the Lisa Office Computer System by apple. The Lisa came standard with a mouse and operated the "Lisa office system" (a series of applications designed for word processing, database management, etc.) in a bit-mappeded option is executed when the mouse button is released. However, before actual execution begins, the highlighted menu header is reset, and the options box is erased so the pull down menu appears "available". The pull down menu concept made its first biin displayed as long as the mouse button is depressed. At this point the user then "selects" an option by moving the mouse down the options list highlighting them one at a time as the mouse's arrow symbol contacts an option. Finally, the highlighting the mouse's arrow symbol, and "clicks" (depresses the mouse button) on the menu header, thus highlighting (usually in inverse mode) the menu header and displaying the menu's options in a box underneath and connected to the header. The options remay across the top of the screen, and "menu options" which can be selectively listed in a box under the header. Pull down menus are normally used in conjunction with a mouse. The user "points" (moves the mouse around) to a menu header directg). Merely install the PDM unit in the system (or a program) library and you'll never have to compile or link it in your source programs (see PASCAL programmer's manual Volume 1 pages 231 to 252 for a complete discussion of library units). The PDM unit will read a standard PASCAL text file to build a pull down menu system (more on the format of this file later). The pull down menu system is actually a linked list of the menu headers with an attached linked list of the options for each header. WithoFigure 3 illustrates a sample menu data file, and figure 4 illustrates a program that uses that data file. The samples given illustrate how the standard system utilities might be implemented using pull down menus. The first line in the samp71, and 166 to 171. When you read in a PDM data file that contains the information used to build the pull down menus, you must ensure that the data follows a specific format. Each line of the text file will be a menu header, an option, or a command. gure 2 shows the ASCII value (0 thru 31) of the character being replaced, the grid layout of each character, and the 8 byte-values needed for down-loading. For more information on down loading characters see standard device drivers guide, pages or example, "nrmldelm = 128;" is actually ascii value 0 (128 - 128 = 0); "optndelm = 129;" is 1 (129 -128 = 1); etc. If you have a character or characters already defined for these values, you can change them as required. each character listed in fiby means of the procedure "load_PDM_font_chrs". The ascii value of the characters being replaced is controlled by the "const" values given in the "implementation" section of the PDM unit. The ASCII values listed are actually increased by 128. F Remember that the Apple /// character set consists of 128 characters with the first 31 normally never used or displayed. This allows the first 31 characters to be overlayed with characters of your own design. This is what the PDM unit does edure is executed again to pick up where the user left off. In order to implement the pull down menus emulating a bit-mapped graphics environment it is necessary to load some special characters. Figure 2 contains a layout of these characters.ny combination pressed. This is normally the fourth procedure called and is called many times. This procedure is exited each time an option is choosen so the program can perform that option. Upon completion of that option, this procdure menu_manager" -this procedure handles the user input that controls the pull down menus. You may optionally pass in a menu number and option number that can be displayed upon entry. The menu and option number selected are passed back as well as and is usually only called once. "Procedure display_menu" -this procedure clears the screen, displays the menu headers on line 1, and displays a delimiter line on line 2. This is normally the third procedure called and is usually only called once. "Proceerse fields, etc. This is normally the first procedure called and is usually only called once. "Procedure read_PDM_data" - this procedure reads a standard PASCAL text file and builds the pull down menus. This is normally the second procedure called aed to control the appearance and functionality of the pull down menus: "Procedure load_PDM_font_chrs" - this procedure loads the special characters needed to display the pull down menus. These characters consist of box corners, shadow lines, invn't waste memory. PDM numbers each menu header starting at 1. The options associated with each menu are also numbered starting at 1 (i.e. The numbers "2,3" indicate menu number 2, option number 3). As listed there are four procedures in the PDM unit usut getting too technical, linked lists are a means of utilizing only that amount of memory needed to hold the data you have (in this case, menu headers and options). This means you don't have to use large arrays or strings to hold your data, and you dole menu file will always be considered the first menu header, and will be numbered 1. Following the first (and every) menu header will be the options for that menu, which will be numbered starting at 1. In the example, the first menu header is the at-sign, "@" followed by the single option of "about system utilities...". Please note that "@" actually stands for the open-Apple character (ASCII 127) which can be generated in the PASCAL editor with the <|> key.by "MENU2_HEAD_PTR". ================================================================== FIGURE 4: THE SAMPLE PROGRAM THAT USES THE "SAMP.MENUS.TEXT" SHOWN IN FIGURE 3 TO BUILD A PULL DOWN MENU STRUCTURE. THIS CAN BE USED AS A SKELETON PROGRe set up "menu2_head_ptr" and read in a second menu file using "menu2_head_ptr" as your "master pointer". Then at an appropriate time in the program (say when a particular option is choosen), you could display the set of menus and options pointed to ning from execution of an option, so you can display exactly where you left off.you could also build several "menu lists". In the example, "menu_head_ptr" is used as the "master pointer" to the menus built from the sample menu file.you could havption displayed by setting "menu_nbr" and "opt_nbr" to the appropriate number. In the example, "menu_nbr" is set to 1, and "opt_nbr" is set to 0, indicating to display menu number 1, option number 0 (no option). This might be useful after return menus. As you can see, it's quite small but it does quite a bit. you no longer have the overhead of large (and sometimes complex) menu routines because PDM now handles all of this for you. Please note that you could easily have a default menu and oVER EDIT DRIVER PARAMETERS @E CHANGE SYSTEM PARAMETERS - GENERATE NEW SYSTEM @G ================================================================== The program shown in figure 4 can be used as a shell for developing applications that use pull dowR - MAKE A SUBDIRECTORY @M - SET WRITE PROTECTION @W SET PREFIX @P % DEVICE HANDLING COPY ONE VOLUME ONTO ANOTHER RENAME A VOLUME - FORMAT A VOLUME @F VERIFY A VOLUME @V - LIST DEVICES CONFIGURED SET TIME AND DATE @T % SCP READ A DRIVER FILE - DELETE A DRIA FILE FOR USE WITH THE PROGRAM SHOWN IN FIGURE 4. ------------------------------------------------------------------ @ ABOUT SYSTEM UTILITIES... % SYSTEM HELP... @H - QUIT @Q % FILE HANDLING LIST FILES @L - COPY FILES @C DELETE FILES @D RENAME FILES @e the best screen location to place the option box for each menu. ================================================================== FIGURE 3: THE FILE "SAMP.MENUS.TEXT", CREATED AS A STANDARD PASCAL TEXT FILE PROVIDES AN EXAMPLE OF A MENU DATnd side of the option box (similar to the MAC). Finally, the last line of the data file must not have an extra carriage return at the end or you'll get an extra blank line in your options for the last menu. Also, PDM will automatically determinline, "quit @q". Notice that since there are two open-Apple commands in this option list, PDM will automatically right justify the commands to the length of the longest option. This will enable the open-Apple commands to be listed down the right-hahis is a short-cut to selecting options). The next line consists of a single hyphen character ,'-'. This tells PDM that a delimiter line is wanted in the option box. This line will seperate option 1 from option 2, which in this case is the next The first option for "system" is "help... @h". notice the "@h" at the end of the option. This tells PDM that if the user presses (either upper or lower case), the option is to be selected (that is, menu number 2, option number 1; t following the option is a line containing the percent character, '%'. This tells PDM that the end of a menu and its options has been reached. The next line after a percent character is considered to be the next menu header, in this case, "system".AM FOR ANY APPLICATION THAT USES THE PDM UNIT. ------------------------------------------------------------------ PROGRAM PDM_SAMP; USES {$U PDM.CODE } PDM; { OR ANY LIBRARY FILE } VAR HEAD_MENU_PTR : MENU_PTR; { YOU COULD HAVE MORE THAN ONE } PDM_DATA_FILE : INTERACTIVE; { FILE THAT CONTAINS THE OPTIONS } EXIT_CODE : CHAR; { OPEN-APPLE KEY PRESSED, IF ANY } OPT_NBR, { OPTION NUMBER PICKED } MENU_NBR : INTEGER; { MGER; VAR EXIT_CODE : CHAR); PROCEDURE LOAD_PDM_FONT_CHRS; IMPLEMENTATION { THE FOLLOWING CONSTANT DECLARATIONS ARE USED FOR REDEFINING } { CERTAIN ASCII CHARACTERS FOR USE IN CONSTRUCTING THE PULL } { DOWN MENU INTERFACE. TH FILE_NAME : STRING; VAR HEAD_MENU_PTR : MENU_PTR); PROCEDURE DISPLAY_MENU (HEAD_MENU_PTR : MENU_PTR); PROCEDURE MENU_MANAGER (HEAD_MENU_PTR : MENU_PTR; VAR MENU_NBR,OPT_NBR : INTE { LINES PER MENU } OPT_START_COL, { WHERE OPTIONS START } MENU_START_COL : INTEGER; { WHERE MENU STARTS } END; PROCEDURE READ_PDM_DATA (VAR PDM_DATA_FILE : INTERACTIVE;OINTER TO NEXT MENU } HEAD_OPT_PTR : OPT_PTR; { POINTER TO OPTIONS } MAX_OPT_LEN, { BIGGEST OPTION LEN } NBR_OF_OPTS, { OPTIONS PER MENU } NBR_OF_LINES, OLINK : OPT_PTR; { POINTER TO NEXT OPTION } END; MENU_PTR = ^MENU_REC; { MENU POINTER } MENU_REC = PACKED RECORD MENU : STR50; { VALUE OF MENU } MLINK : MENU_PTR; { P52; { VERIFY THAT THIS ISN'T USED ALREADY } INTERFACE TYPE STR50 = STRING[50]; { MAXIMUM MENU AND OPTION LENGTH } OPT_PTR = ^OPT_REC; { OPTION POINTER } OPT_REC = PACKED RECORD OPTION : STR50; { VALUE OF OPTION } ew programs. Good luck and good computing! ================================================================== FIGURE 1: THE SOURCE CODE FOR THE PDM UNIT. ------------------------------------------------------------------ UNIT PDM; INTRINSIC CODE outines. The Apple /// PDM unit has the further advantages of emulating pull down menus in a bit-mapped graphics environment, thus giving the interface a truly "professional" look. I hope you find the PDM unit as useful as I have in development of nis interface in some form or another. The PDM unit addresses this aspect of program development by allowing you to have a standard method of creating and implemented pull down menus without the overhead of developing and debugging pull down menu r(NONE) } UNTIL (MENU_NBR = 2) AND (OPT_NBR = 2); END. ================================================================== With pull down menus now an industry standard, it is inevitable that new programs developed for personal computers will utilize thN NUMBER SELECTED IS:',OPT_NBR:3); WRITELN (CHR(31),'EXIT CODE IS: ',EXIT_CODE); { WAS THE QUIT OPTION CHOOSEN? } IF (MENU_NBR <> 2) OR (OPT_NBR <> 2) THEN OPT_NBR := 0; { NO, RESET OPTION TO 0 MENU_MANAGER { WAIT UNTIL USER SELECTS OPTION } (HEAD_MENU_PTR,MENU_NBR,OPT_NBR,EXIT_CODE); GOTOXY (0,10); { DISPLAY OPTION SELECTED } WRITELN ('MENU NUMBER SELECTED IS:',MENU_NBR:3); WRITELN ('OPTIO(HEAD_MENU_PTR); { DISPLAY THE MENUS } MENU_NBR := 1; { USE MENU 1 AS 1ST SELECTED } OPT_NBR := 0; { USE OPT 0 AS 1ST SELECT (NONE) } REPEAT { UNTIL QUIT OPTION SELECTED } ENU NUMBER PICKED } BEGIN { PDM_SAMP } LOAD_PDM_FONT_CHRS; { LOAD THE SPECIAL CHARACTER SET } READ_PDM_DATA_FILE { READ IN AND BUILD THE MENUS } (PDM_DATA_FILE,'SAMP.MENUS.TEXT',HEAD_MENU_PTR); DISPLAY_MENU ESE CHARACTERS ARE USED IN BUILDING } { BOXES WITH SHADOWS, LINES WITHIN BOXES, ETC. THERE ARE CUR- } { RENTLY 26 CHARACTERS DEFINED, OF WHICH 21 ARE USED. THE ONES } { NOT USED ARE "MOUSEARW", "RIGHTARW", "LEFTARRW", AND } { "DOWNARRW". THESE CONSTANTS DEFINE AN ASCII CHARACTER VALUE } { OF THE CHARACTER TO BE DEFINED, PLUS 128. THE ACTUAL ASCII } { VALUES ARE 0 THRU 24 AND 127. THEY ARE LISTED HERE (INSTEAD } { OF HARD CODED) SO YOU CAN CHANGE THEM IN CASE YOU HAVE AL- } { READY DERE CHR_PROMPT (DISPLAY : DISPLAY_TYPES; X,Y : INTEGER; C : CHAR); { THIS PROCEDURE WILL DISPLAY A CHAR "C" AT COLUMN "X" } { AND ROW "Y" WITH "DISPLAY" ATTRIBUTES ON THE SCREEN. } { "X" AND "Y" ARE ASSUMED TO BE 1 RE { HOW DISPLAYED? } INVERSE : WRITE (CHR(18),S,CHR(17)); { INVERSE CHARACTERS } OTHERWISE { ASSUME NORMAL CHRS } WRITE (S); { WRITE THE STRING } END; END; PROCEDUE SCREEN. } { "X" AND "Y" ARE ASSUMED TO BE 1 RELATIVE WITH THE UP- } { PER LEFT CORNER OF THE SCREEN BEING POSITION (1,1). } BEGIN GOTOXY (X-1,Y-1); { ASSUME 1 RELATIVE } CASE DISPLAY OF EF5,DEF6,DEF7,DEF8 : INTEGER); } PROCEDURE STR_PROMPT (DISPLAY : DISPLAY_TYPES; X,Y : INTEGER; S : STRING); { THIS PROCEDURE WILL DISPLAY A STRING "S" AT COLUMN "X" } { AND ROW "Y" WITH "DISPLAY" ATTRIBUTES ON TH } { PROCEDURE STRIP_BACKWARD (VAR S : BYTESTREAM); } { } { PROCEDURE LOAD_CHARACTER (ASCII_CHAR,DEF1,DEF2,DEF3, } { DEF4,D } { JUSTIFY : JUSTIFY_TYPES; STR_LENGTH : INTEGER); } { } { PROCEDURE CHR_CONCAT (C1 : CHAR; VAR S : STRING; C2 : CHAR); } { ROCEDURE MAKE_STRING (VAR S : BYTESTREAM; } { STR_LENGTH : INTEGER; C : CHAR); } { } { PROCEDURE JUSTIFY_STRING (VAR S : BYTESTREAM; } { PROCEDURE CHR_PROMPT (DISPLAY : DISPLAY_TYPES; X,Y : INTEGER; } { C : CHAR); } { } { PINSTUFF, ETC.) I MAY NEED. } { } { PROCEDURE STR_PROMPT (DISPLAY : DISPLAY_TYPES; X,Y : INTEGER; } { S : STRING); } { MPLEMENTATION SECTION. } { AS A POINT OF INTEREST, I GENERALLY KEEP THESE KIND OF GENERAL } { PURPOSE ROUTINES IN A SEPERATE UNIT CALLED GENUTIL AND THEN } { LIST IT IN MY HOST PROGRAM "USES" STATEMENT ALONG WITH PDM AND } { ANY OTHER UNITS (GIO, CHA YOU CANNOT } { CALL THEM FROM YOUR HOST PROGRAM. IF YOU WISH TO MAKE THEM } { ACCESIBLE TO YOUR HOST PROGRAM AS WELL AS THIS UNIT, MOVE THE } { PROCEDURE HEADER INTO THE INTERFACE SECTION AND COMMENT OUT } { THE PROCEDURE PARAMETER LIST IN THE I55_ARRAY = PACKED ARRAY [0..255] OF CHAR; { PSEUDO STRING } JUSTIFY_TYPES = (LEFT,RIGHT,CENTER); { HOW TO JUSTIFY STRINGS } DISPLAY_TYPES = (NORMAL,INVERSE,FLASHING); { DISPLAY STRINGS } { THE FOLLOWING PROCEDURES ARE LOCAL TO THIS UNIT. = 139; FILLBLCK = 140; FILLTHAF = 141; OURBOXSH = 142; OPTLFTDL = 143; OPTRGTDL = 144; FURBOXSH = 145; FILLWLFT = 146; FILLBHAF = 147; MOUSEARW = 148; RIGHTARW = 149; LEFTARRW = 150; DOWNARRW = 151; UPARROW = 152; OPNAPPLE = 255; TYPE STR2FINED CHARACTERS IN THIS RANGE. } CONST NRMLDELM = 128; OPTNDELM = 129; OPTLFTDM = 130; OPTRGTDM = 131; FLBOXSHD = 132; OPNUPRGT = 133; OPNUPLFT = 134; OPNLWLFT = 135; OPNLWRGT = 136; HFBOXSHD = 137; FILUPRGT = 138; FILUPLFT LATIVE WITH THE UP- } { PER LEFT CORNER OF THE SCREEN BEING POSITION (1,1). } BEGIN GOTOXY (X-1,Y-1); { ASSUME 1 RELATIVE } CASE DISPLAY OF { HOW DISPLAYED? } INVERSE : WRITE (CHR(18),C,CHR(17)); { INVERSE CHARACTERS } OTHERWISE { ASSUME NORMAL CHRS } WRITE (C); { WRITE THE STRING } END; END; PROCEDURE MAKE_STRING (VAR S : BYTESTREAM; } VAR I,I2 : INTEGER; BEGIN I := ORD(S[0]); { GET LENGTH OF STRING } IF I > 0 THEN { LENGTH > 0? } BEGIN { YES, PROCESS STRING } RETURN STRING } END; PROCEDURE STRIP_BACKWARD (VAR S : BYTESTREAM); { THIS PROCEDURE WILL STRIP A STRING "S" OF TRAILING } { SPACES. IF "S" CONSISTS OF NOTHING BUT SPACES, IT } { WILL BE SET TO NULLS AND NO LENGTH. 0) THEN { IF C2 HAS AN ASCII GREATER } BEGIN { THAN ZERO, THEN USE IT } S2[1] := C2; { TURN C2 INTO A STRING } S := CONCAT(S,S2); { ADD THE CONVERTED CHARACTER } END; { TO THE } BEGIN { THAN ZERO, THEN USE IT } S2[1] := C1; { TURN C1 INTO A STRING } S := CONCAT(S2,S); { ADD THE CONVERTED CHARACTER } END; { TO THE RETURN STRING } IF C2 > CHR( TO THE END OF THE STRING (IF THEY HAVE AN ASCII } { VALUE GREATER THAN ZERO). } VAR S2 : STRING; BEGIN S2 := ' '; { INITIALIZE THE WORK STRING } IF C1 > CHR(0) THEN { IF C1 HAS AN ASCII GREATERGTH,CHR(32)); { SPACE RET STRING } END; END; PROCEDURE CHR_CONCAT (C1 : CHAR; VAR S : STRING; C2 : CHAR); { THIS PROCEDURE WILL RETURN A STRING "S" THAT HAS CHAR- } { ACTER "C1" ADDED TO THE BEGINNING AND CHARACTER "C2" } { ADDED S[0] := CHR(STR_LENGTH); { SET STR LENGTH } MOVELEFT (WRK_STR[1],S[1],STR_LENGTH); { LOAD RET STRING } END ELSE BEGIN S[0] := CHR(STR_LENGTH); { SET STRING LENGTH } FILLCHAR (S[1],STR_LEN CENTER : JUSTIFY_OFFSET := (STR_LENGTH - OLD_STR_LENGTH) DIV 2 + 1; END; { MOVE ORIGINAL DATA INTO WORK STRING AT START COLUMN } MOVELEFT (S[1],WRK_STR[JUSTIFY_OFFSET],OLD_STR_LENGTH); N { SET STRING LENGTH } OLD_STR_LENGTH := STR_LENGTH; CASE JUSTIFY OF { COMPUTE START COL FOR REPOSITIONING } RIGHT : JUSTIFY_OFFSET := STR_LENGTH - OLD_STR_LENGTH+1; LEFT : JUSTIFY_OFFSET := 1; OLD_STR_LENGTH := ORD(S[0]); { GET ORIGINAL STRING LENGTH } IF OLD_STR_LENGTH > 0 THEN { WE'VE GOT DATA IN THE STRING } BEGIN FILLCHAR (WRK_STR[1],STR_LENGTH,CHR(32)); { SPACE WORK } IF OLD_STR_LENGTH > STR_LENGTH THE "STR_LENGTH" CAUSES TRUNCATION OF IT. } VAR WRK_STR : STR255_ARRAY; { PSEUDO WORK STRING } JUSTIFY_OFFSET, { START POS FOR JUSTIFY } OLD_STR_LENGTH : INTEGER; { ORIGINAL STRING LENGTH } BEGIN " LEFT, RIGHT, OR CENTER JUSTIFIED AS DETERMINED BY } { "JUSTIFY", IN A FIELD OF "STR_LENGTH" CHARACTERS. "S" } { DOES NOT HAVE TO BE DEFINED BEFORE CALLING. IF "S" } { HAS DATA, THAT DATA IS NOT ALTERED (ONLY JUSTIFIED), } { UNLESS (S[1],STR_LENGTH,C); { FILL IT WITH THE CHARACTER } END; PROCEDURE JUSTIFY_STRING (VAR S : BYTESTREAM; JUSTIFY : JUSTIFY_TYPES; STR_LENGTH : INTEGER); { THIS PROCEDURE WILL JUSTIFY AND RETURN A STRING VALUE, } { "S STR_LENGTH : INTEGER; C : CHAR); { THIS PROCEDURE WILL RETURN A STRING VALUE "S" CONSIST- } { ING OF "STR_LENGTH" CHARACTERS OF TYPE "C". } BEGIN S[0] := CHR(STR_LENGTH); { SET STRINGS LENGTH } FILLCHAR I2 := ABS(SCAN(-I,<>' ',S[I])); { SCAN FOR A NON-SPACE } IF I2 = I THEN { NON-SPACE FOUND? } FILLCHAR (S[0],I+1,CHR(0)) { NO, FILL WITH NULLS } ELSE { YES, SET STRING LEN } S[0] := CHR(I-I2); { TO LAST NON-SPACE } END; END; PROCEDURE LOAD_CHARACTER (ASCII_CHAR,DEF1,DEF2,DEF3, DEF4,DEF5,DEF6,DEF7,DEF8 : INTEGER); { THIS PROCEDURE WILL LOAD A CUSTOM CHARACTER LAST_MENU_PTR^.NBR_OF_LINES+1; { SET THE MAXIMUM OPTION LENGTH FOR THIS MENU } IF LENGTH(LINE)+2 > LAST_MENU_PTR^.MAX_OPT_LEN THEN LAST_MENU_PTR^.MAX_OPT_LEN := LENGTH(LINE) + 2; { CHECK FOR A DELIMITER LINE }OPT_PTR^ DO BEGIN OPTION := LINE; { SET OPTION } OLINK := NIL; { SET NEXT OPTION PTR } END; { INCREMENT NUMBER OF LINES READ IN FOR THIS MENU } LAST_MENU_PTR^.NBR_OF_LINES:= LAST_MENU_PTR^.MLINK := TEMP_MENU_PTR; LAST_MENU_PTR := TEMP_MENU_PTR; { ASSIGN TEMP PTR } END; PROCEDURE MAKE_OPTION (LINE : STR50); BEGIN NEW (TEMP_OPT_PTR); { ALLOCATE AN OPTION PTR } WITH TEMP_ { " " } END; IF HEAD_MENU_PTR = NIL THEN { FIRST TIME THRU ? } HEAD_MENU_PTR := TEMP_MENU_PTR { YES, ASSIGN PTRS } ELSE { NO, SET MENU PTRS } OPTIONS YET } NBR_OF_OPTS := 0; { " " } NBR_OF_LINES := 0; { " " } OPT_START_COL := 0; { " " } MENU_START_COL := 0; BEGIN MENU := CONCAT(' ',LINE,' '); { SET MENU HEADER } MLINK := NIL; { SET NEXT MENU PTR } HEAD_OPT_PTR := NIL; { SET HEAD OPT PTR } MAX_OPT_LEN := 0; { NO MENU POINTER } LINE : STR50; { LINE READ IN } PROCEDURE MAKE_HEADER (LINE : STR50); BEGIN NEW (TEMP_MENU_PTR); { ALLOCATE A MENU PTR } WITH TEMP_MENU_PTR^ DO CEDURE BUILD_OPTIONS_LIST; VAR TEMP_OPT_PTR, { TEMPORARY OPTION POINTER } LAST_OPT_PTR : OPT_PTR; { LAST OPTION POINTER } TEMP_MENU_PTR, { TEMPORARY MENU POINTER } LAST_MENU_PTR : MENU_PTR; { LAST"PDM_DATA_FILE", AND NAMED BY "FILE_NAME". THE MENU } { HEADERS AND OPTIONS ARE READ IN AND BUILT INTO A TWO- } { WAY LINKED LIST IN MEMORY. THE START OF THAT LIST IS } { POINTED TO BY "HEAD_MENU_PTR". } PRO PROCEDURE READ_PDM_DATA { (VAR PDM_DATA_FILE : INTERACTIVE; FILE_NAME : STRING; VAR HEAD_MENU_PTR : MENU_PTR) }; { THIS PROCEDURE WILL READ A DISK FILE REFERENCED BY } { ON BYTE 5 } CNTL_LST[8] := DEF6; { DEFINITION BYTE 6 } CNTL_LST[9] := DEF7; { DEFINITION BYTE 7 } CNTL_LST[10] := DEF8; { DEFINITION BYTE 9 } UNITSTATUS (1,CNTL_LST,70); { PERFORM D_CONTROL } END; { DEFINITION BYTE 1 } CNTL_LST[4] := DEF2; { DEFINITION BYTE 2 } CNTL_LST[5] := DEF3; { DEFINITION BYTE 3 } CNTL_LST[6] := DEF4; { DEFINITION BYTE 4 } CNTL_LST[7] := DEF5; { DEFINITIKED ARRAY [1..10] OF BYTE; VAR CNTL_LST : CNTL_LST_ARRAY; { USED FOR A DEVICE CONTROL CALL } BEGIN CNTL_LST[1] := 1; { NUMBER OF CHARS } CNTL_LST[2] := ASCII_CHAR - 128; { ASCII TO DEFINE } CNTL_LST[3] := DEF1; DEFINED BY } { THE DEFINITION BYTES "DEF1" THRU "DEF8". THE CHARAC- } { TER TO BE DEFINED IS PASSED IN AS "ASCII_CHAR". THIS } { WOULD NORMALLY BE ONE OF THE CONSTANTS DEFINED ABOVE. } TYPE BYTE = 0..255; CNTL_LST_ARRAY = PAC IF POS('-',LINE) <> 1 THEN LAST_MENU_PTR^.NBR_OF_OPTS:=LAST_MENU_PTR^.NBR_OF_OPTS+1; { SET THE APPROPRIATE OPTION POINTER, IF FIRST TIME THRU } IF LAST_MENU_PTR^.HEAD_OPT_PTR = NIL THEN LAST_MENU_PTR^.HEAD_OPT_PTR := TEMP_OPT_PTR ELSE LAST_OPT_PTR^.OLINK := TEMP_OPT_PTR; { ASSIGN TEMP POINTER } LAST_OPT_PTR := TEMP_OPT_PTR; END; BEGIN { BUILD_OPTIONS_LIST } HEAD_MENU_PTR := NIL; { INITIALIZE OPTION := S; { OPTION BUILT, ASSIGN IT } END; TEMP_OPT_PTR := OLINK; { ASSIGN NEXT OPT PTR } END; TEMP_MENU_PTR := MLINK; { ASSIGN NEXT MENU PTR } END; ENJUSTIFIED IN STRING } IF I < STR_LENGTH THEN BEGIN S[MAX_OPT_LEN-2] := CHR(255); S[MAX_OPT_LEN-1] := OPT_STR[I+2]; END; ENGTH THEN S := COPY(S,1,I); JUSTIFY_STRING (S,LEFT,MAX_OPT_LEN); S[MAX_OPT_LEN] := CHR(OPTRGTDM); { SET OPEN-APPLE RIGHT STR_LENGTH := LENGTH(S); OPT_STR := S; I := SCAN(STR_LENGTH,=CHR(255),OPT_STR[1]); { FOUND ONE, LEFT JUSTIFY TEXT OF STRING } IF I < STR_L NORMAL OPTION LINE } S := OPTION; {$V-} CHR_CONCAT(CHR(OPTLFTDM),S,CHR(0)); {$V+} { LOOK FOR AN OPEN-APPLE CHARACTER } )); {$V-} CHR_CONCAT(CHR(OPTLFTDL),S,CHR(OPTRGTDL)); {$V+} OPTION := S; END ELSE BEGIN { BUILD AILE TEMP_OPT_PTR <> NIL DO WITH TEMP_OPT_PTR^ DO BEGIN IF OPTION = '-' THEN BEGIN { BUILD A DELIMITER LINE } MAKE_STRING (S,MAX_OPT_LEN-2,CHR(NRMLDELM} TEMP_MENU_PTR^.MENU_START_COL := MENU_COLUMN; { INCREMENT TO NEXT COLUMN } MENU_COLUMN := MENU_COLUMN+LENGTH(TEMP_MENU_PTR^.MENU); TEMP_OPT_PTR := HEAD_OPT_PTR; { ASSIGN TEMP OPT PTR } WH_COLUMN+MAX_OPT_LEN+1 > 80 THEN OPT_START_COL := (MENU_COLUMN+LENGTH(MENU)-1) - MAX_OPT_LEN + 1 ELSE OPT_START_COL := MENU_COLUMN; { SET MENU HEADER START COLUMN OF MENU LIST } MENU_COLUMN := 2; { 1ST MENU STARTS IN COL 2 } WHILE TEMP_MENU_PTR <> NIL DO WITH TEMP_MENU_PTR^ DO BEGIN { SET OPT START COLUMN BASED ON LENGTH OF BIGGEST OPT } IF MENU; PROCEDURE ADJUST_OPTIONS; VAR TEMP_MENU_PTR : MENU_PTR; TEMP_OPT_PTR : OPT_PTR; S,OPT_STR : STR50; I, STR_LENGTH, MENU_COLUMN : INTEGER; BEGIN TEMP_MENU_PTR := HEAD_MENU_PTR; { START BEGIN READLN (PDM_DATA_FILE,LINE); { GET NEXT LINE } MAKE_HEADER (LINE); { MUST BE A HEADER } READLN (PDM_DATA_FILE,LINE); { GET NEXT LINE } END; UNTIL EOF(PDM_DATA_FILE); ENDPOS('%',LINE) = 0) AND (NOT EOF(PDM_DATA_FILE)) DO BEGIN MAKE_OPTION (LINE); { MUST BE AN OPTION } READLN (PDM_DATA_FILE,LINE); { GET NEXT LINE } END; IF NOT EOF(PDM_DATA_FILE) THEN HEAD MENU PTR } READLN (PDM_DATA_FILE,LINE); { READ A LINE FROM DATA FILE } MAKE_HEADER (LINE); { FIRST LINE READ IS A HEADER } READLN (PDM_DATA_FILE,LINE); { GET NEXT LINE FROM FILE } REPEAT WHILE (D; BEGIN { READ_PDM_DATA } {$I-} RESET (PDM_DATA_FILE,FILE_NAME); { OPEN THE DATA FILE } {$I+} IF IORESULT > 0 THEN { ERROR ON FILE OPEN } BEGIN { DISPLAY ERROR MESSAGE } GOTOXY (0,23); WRITE (CHR(7),CHR(30),CHR(18)); WRITE ('*** IOERROR #',IORESULT); WRITE (' OPENING "',FILE_NAME,'" ***'); WRITE (CHR(17)); EXIT (PROGRAM); END; BUILD_OPTIONS_LIST; { BUILD THE LINKE (NORMAL,MENU_START_COL,2,S); { SHOW IT } END; END; PROCEDURE RESET_MENU (TEMP_MENU_PTR : MENU_PTR); VAR S : STRING; BEGIN WITH TEMP_MENU_PTR^ DO BEGIN STR_PROMPT (NORMAL,MENU_START_COL,1,MENU); { (TEMP_MENU_PTR : MENU_PTR); VAR S : STRING; BEGIN WITH TEMP_MENU_PTR^ DO BEGIN STR_PROMPT (INVERSE,MENU_START_COL,1,MENU); { SHW MENU } MAKE_STRING (S,LENGTH(MENU),CHR(FILLTHAF)); { DELIM LN } STR_PROMPT_ARRAY); BEGIN UNITSTATUS(1,SCREEN,18*4); { D_STATUS TO SAVE SCREEN } END; PROCEDURE RESTORE_SCREEN (SCREEN : SCREEN_ARRAY); BEGIN UNITSTATUS(1,SCREEN,18*4+2); { D_STATUS TO RESTORE SCREEN } END; PROCEDURE SET_MENU KEY_STROKES := 0; { PERFORM A D_STATUS CALL } UNITSTATUS (1,KEY_STROKES,20); { TO THE .CONSOLE DRIVER } KEY_PRESSED := KEY_STROKES > 0; { TO CHECK FOR A KEYPRESS } END; PROCEDURE SAVE_SCREEN (VAR SCREEN : SCREENY SCREEN BUFFER } TOP_BORDER, { TOP OPTION BOX BORDER } BOT_BORDER : STR50; { BOTTOM OPTION BOX BORDER } FUNCTION KEY_PRESSED : BOOLEAN; VAR KEY_STROKES : INTEGER; { STATUS LIST FOR CALL } BEGIN TION ROW } OPT_PICKED, { HAS OPTION BEEN PICKED? } OPTS_DISPLAYED : BOOLEAN; { ARE OPTIONS DISPLAYED? } C : CHAR; { USER KEY PRESSED } SCREEN : SCREEN_ARRAY; { TEMPORARBOX } SCREEN_ARRAY = PACKED ARRAY [1..1923] OF CHAR; { SCR BUFFER } VAR TEMP_MENU_PTR : MENU_PTR; { CURRENT MENU DISPLAYED } TEMP_OPT_PTR : OPT_PTR; { CURRENT OPTION DISPLAYED } OPT_ROW : INTEGER; { TRACK OP { NBR" WILL CONTAIN THE MENU AND OPTION NUMBERS OF THE } { SELECTED OPTION. IF AN OPEN-APPLE KEY COMBAINATION } { WAS PRESSED, "EXIT_CODE" WILL CONTAIN THIS VALUE. } TYPE FILL_TYPES = (SOLID,HOLLOW); { OPTION { "MENU_NBR" AND "OPT_NBR" ARE GREATER THAN ZERO, THE } { APPROPRIATE MENU AND OPTION WILL BE DISPLAYED. OTHER- } { WISE, THE FIRST MENU WILL BE HIGHLIGHTED, BUT ITS OP- } { TIONS WILL NOT BE SHOWN. ON EXIT, "MENU_NBR" AND "OPT_ } HEAD_MENU_PTR : MENU_PTR; VAR MENU_NBR,OPT_NBR : INTEGER; VAR EXIT_CODE : CHAR) }; { THIS PROCEDURE WILL HANDLE THE OPERATION OF THE PULL } { DOWN MENUS SPECIFIED BY "HEAD_MENU_PTR". ON ENTRY, IF }LL MENUS } WITH TEMP_MENU_PTR^ DO { DISPLAY MENU HEADER } BEGIN STR_PROMPT (NORMAL,MENU_START_COL,1,MENU); TEMP_MENU_PTR := MLINK; { GET NEXT MENU } END; END; PROCEDURE MENU_MANAGER { ( THE SCREEN } MAKE_STRING (S,80,CHR(OPTNDELM)); { MAKE DELIMITER LINE } STR_PROMPT (NORMAL,1,2,S); { DISPLAY IT } TEMP_MENU_PTR := HEAD_MENU_PTR; { ASSIGN HEAD MENU PTR } WHILE TEMP_MENU_PTR <> NIL DO { PROCESS ARS POINTED } { TO BY "HEAD_MENU_PTR" ACROSS THE FIRST LINE OF THE } { SCREEN. } VAR S : STRING; TEMP_MENU_PTR : MENU_PTR; BEGIN WRITE (CHR(28)); { CLEARD LIST } ADJUST_OPTIONS; { ADJUST THE OPTIONS } CLOSE (PDM_DATA_FILE,NORMAL); { CLOSE THE DATA FILE } END; PROCEDURE DISPLAY_MENU { (HEAD_MENU_PTR : MENU_PTR) }; { THIS PROCEDURE WILL DISPLAY THE MENU HEADESHW MENU } MAKE_STRING (S,LENGTH(MENU),CHR(OPTNDELM)); { DELIM LN } STR_PROMPT (NORMAL,MENU_START_COL,2,S); { SHOW IT } END; END; PROCEDURE SET_TOP_BORDER (FILL : FILL_TYPES); VAR S : STRING; I : INTEGER; BEGIN S := TOP_BORDER; { GET TOP OPTION BORDER } WITH TEMP_MENU_PTR^ DO BEGIN IF FILL = SOLID THEN { REPLACE BORDER CHARS } FOR I := 1 TO LENGTH(S) DO { WITH SOLID CHARS } { MAKE THE OPTION BOX BOTTOM BORDER } MAKE_STRING (BOT_BORDER,MAX_OPT_LEN,CHR(OPTNDELM)); BOT_BORDER[1] := CHR(OPNLWLFT); { L CORNER } BOT_BORDER[MAX_OPT_LEN] := CHR(OPNLWRGT); { R CORNER } IF OPT_START_COL+MAX_OPT_LEN <= MENU_START_COL+LENGTH(MENU) THEN TOP_BORDER[MAX_OPT_LEN] := CHR(FILUPLFT) { R CORNER } ELSE TOP_BORDER[MAX_OPT_LEN] := CHR(OPNUPRGT); { R CORNER } T_START_COL = MENU_START_COL THEN TOP_BORDER[1] := CHR(FILUPRGT) { LEFT CORNER } ELSE TOP_BORDER[1] := CHR(OPNUPLFT); { LEFT CORNER } { OPTIONS ARE RIGHT ALIGNED WITH MENU HEADER } COL - OPT_START_COL + 1; FOR I := OFFSET TO OFFSET+LENGTH(MENU)-1 DO IF I <= MAX_OPT_LEN THEN TOP_BORDER[I] := CHR(FILLTHAF); { OPTIONS ARE LEFT ALIGNED WITH MENU HEADER } IF OP SAVE_SCREEN (SCREEN); { SAVE CURRENT SCREEN } { MAKE THE OPTION BOX TOP BORDER } MAKE_STRING (TOP_BORDER,MAX_OPT_LEN,CHR(OPTNDELM)); OFFSET := MENU_START_ BEGIN TEMP_OPT_PTR := TEMP_MENU_PTR^.HEAD_OPT_PTR; { SET OPT PTR } IF TEMP_OPT_PTR <> NIL THEN { THERE ARE OPTIONS } WITH TEMP_MENU_PTR^ DO BEGIN OPTS_DISPLAYED := TRUE; { OPTIONS DIAPLAYED }ON); IF OPT_ROW-2 = TEMP_MENU_PTR^.NBR_OF_LINES THEN SET_BOT_BORDER (HOLLOW); { SET BOT OPTION BORDER } END; END; PROCEDURE DISPLAY_OPTIONS_AREA (OPT_TO_DISPLAY : INTEGER); VAR I,OFFSET : INTEGER; TR^ DO BEGIN IF OPT_ROW = 3 THEN { SET TOP OPTION BORDER } SET_TOP_BORDER (HOLLOW); { TO CLEAR OPTION BOX } STR_PROMPT (NORMAL,TEMP_MENU_PTR^.OPT_START_COL, OPT_ROW,OPTI OPT_ROW,S); IF OPT_ROW-2 = TEMP_MENU_PTR^.NBR_OF_LINES THEN SET_BOT_BORDER (SOLID); { SET BOT OPTION BORDER } END; END; PROCEDURE RESET_OPTION (TEMP_OPT_PTR : OPT_PTR); BEGIN WITH TEMP_OPT_PID); { TO FILL IN OPTION BOX } S := OPTION; { SET OPTION UP FOR HIGHLIGHTING } S[1] := ' '; S[TEMP_MENU_PTR^.MAX_OPT_LEN] := ' '; STR_PROMPT (INVERSE,TEMP_MENU_PTR^.OPT_START_COL, PT_ROW+1,S); END; END; PROCEDURE SET_OPTION (TEMP_OPT_PTR : OPT_PTR); VAR S : STRING; BEGIN WITH TEMP_OPT_PTR^ DO BEGIN IF OPT_ROW = 3 THEN { SET TOP OPTION BORDER } SET_TOP_BORDER (SOLS } FOR I := 1 TO LENGTH(S) DO { WITH SOLID CHARS } IF ORD(S[I]) IN [OPNLWLFT] THEN S[I] := CHR(FILLWLFT) ELSE S[I] := CHR(FILLTHAF); STR_PROMPT (NORMAL,OPT_START_COL,O SET_BOT_BORDER (FILL : FILL_TYPES); VAR S : STRING; I : INTEGER; BEGIN S := BOT_BORDER; { GET BOT OPTION BORDER } WITH TEMP_MENU_PTR^ DO BEGIN IF FILL = SOLID THEN { REPLACE BORDER CHAR IF ORD(S[I]) IN [FILUPRGT,FILLTHAF,FILUPLFT] THEN S[I] := CHR(FILLBLCK) ELSE S[I] := CHR(FILLBHAF); STR_PROMPT (NORMAL,OPT_START_COL,OPT_ROW-1,S); END; END; PROCEDURE { SPECIAL DELIMITER LINE CORNERS FOR OPTION BOX } IF OPT_START_COL+MAX_OPT_LEN < MENU_START_COL+LENGTH(MENU) THEN CHR_PROMPT (NORMAL,OPT_START_COL+MAX_OPT_LEN,2, CHR(FURBOXSH)) ELSE CHR_PROMPT (NORMAL,OPT_START_COL+MAX_OPT_LEN,2, CHR(OURBOXSH)); OPT_NBR := 0; { SHOW EACH OPTION } OPT_ROW := 2; { BY { GET THE NEXT } BEGIN { MENU IN LIST } OLD_OPTS_DISPLAYED := OPTS_DISPLAYED; { SAVE STATUS } IF OPTS_DISPLAYED THEN { OPTS DISPLAYED } END; END; PROCEDURE GET_NEXT_MENU; VAR OLD_OPTS_DISPLAYED : BOOLEAN; BEGIN IF TEMP_MENU_PTR^.MLINK = NIL THEN { LAST MENU IN } WRITE (CHR(7)) { LIST, ERROR } ELSE NU (TEMP_MENU_PTR); { FOUND IT, HIGHLIGHT } MENU_NBR := MENU_NBR - 1; { SET THE NEW MENU NBR } IF OLD_OPTS_DISPLAYED THEN { IF OPTIONS WERE DIS- } DISPLAY_OPTIONS_AREA (1); { PLAYED, RE-DISPLAY } { SEARCH LIST FOR PREV } FOR I := 1 TO MENU_NBR-2 DO { MENU } BEGIN TEMP_MENU_PTR := TEMP_MENU_PTR^.MLINK; TEMP_OPT_PTR := TEMP_MENU_PTR^.HEAD_OPT_PTR; END; SET_MEE STATUS } IF OPTS_DISPLAYED THEN { OPTIONS DISPLAYED? } CLEAR_OPTIONS_AREA; { YES, CLEAR THEM } RESET_MENU (TEMP_MENU_PTR); { UN-HIGHLIGHT MENU } TEMP_MENU_PTR := HEAD_MENU_PTR;} WRITE (CHR(7)) { SOUND BELL } ELSE { GET THE PREVIOUS } BEGIN { MENU } OLD_OPTS_DISPLAYED := OPTS_DISPLAYED; { SAV } RESTORE_SCREEN (SCREEN); { SHOW THE SAVED SCREEN } END; PROCEDURE GET_PREV_MENU; VAR I : INTEGER; OLD_OPTS_DISPLAYED : BOOLEAN; BEGIN IF MENU_NBR = 1 THEN { NO PREVIOUS MENU OPTION } SET_OPTION (TEMP_OPT_PTR); END ELSE { NO OPTIONS FOR THIS MENU, SOUND BELL } WRITE (CHR(7)); END; PROCEDURE CLEAR_OPTIONS_AREA; BEGIN OPTS_DISPLAYED := FALSE; { OPTIONS ARE NOT DISPLAYED TEMP_OPT_PTR := TEMP_OPT_PTR^.OLINK; { NEXT OPT } END; IF OPT_NBR = 0 THEN { NO OPTION WAS SELECTED } TEMP_OPT_PTR := HEAD_OPT_PTR ELSE { HIGHLIGHT THE OPT_ROW := OPT_ROW + 1; { TOTAL LINE COUNT } IF TEMP_OPT_PTR^.OPTION[2] <> CHR(NRMLDELM) THEN OPT_NBR := OPT_NBR + 1; { TOTAL OPTION COUNT } IF OPT_NBR < OPT_TO_DISPLAY THEN E OPT } OPT_ROW := 2; { NBR PASSED TO PROC } TEMP_OPT_PTR := HEAD_OPT_PTR; { BY SEARCHING LIST } WHILE (OPT_NBR < OPT_TO_DISPLAY) AND (TEMP_OPT_PTR <> NIL) DO BEGIN _PTR^.OLINK; { NEXT OPT } END; CHR_PROMPT (NORMAL,OPT_START_COL+MAX_OPT_LEN, OPT_ROW+1,CHR(HFBOXSHD)); { BOX SHADOW } OPT_NBR := 0; { HIGHLIGHT TH TOTAL OPTION COUNT } RESET_OPTION (TEMP_OPT_PTR); { SHOW OPTION } CHR_PROMPT (NORMAL,OPT_START_COL+MAX_OPT_LEN, OPT_ROW,CHR(FLBOXSHD)); { BOX SHADOW } TEMP_OPT_PTR := TEMP_OPT SEARCHING LIST } WHILE TEMP_OPT_PTR <> NIL DO BEGIN OPT_ROW := OPT_ROW + 1; { TOTAL LINE COUNT } IF TEMP_OPT_PTR^.OPTION[2] <> CHR(NRMLDELM) THEN OPT_NBR := OPT_NBR + 1; {CLEAR_OPTIONS_AREA; { THEN CLEAR BOX } RESET_MENU (TEMP_MENU_PTR); { UN-HIGHLIGHT } TEMP_MENU_PTR := TEMP_MENU_PTR^.MLINK;{ GET NEXT MENU } SET_MENU (TEMP_MENU_PTR); { HIGHLIGHT IT } MENU_NBR := MENU_NBR + 1; { INC MENU NBR } IF OLD_OPTS_DISPLAYED THEN { OPTS DISPLAYED } DISPLAY_OPTIONS_AREA (1); { YES, REDISPLAY } END; END; PROCEDURE GET_PREV_OPT; LD_MENU_NBR,I : INTEGER; OLD_TEMP_MENU_PTR : MENU_PTR; OPTION_FOUND : BOOLEAN; BEGIN IF OPTS_DISPLAYED THEN { IF OPTIONS ARE } WRITE (CHR(7)) { DISPLAYED THEN } ELS_OPT_ROW; { FORE SEARCH CON- } END; { DITIONS } SET_OPTION (TEMP_OPT_PTR) { SHOW THE OPTION } END; END; PROCEDURE SCAN_FOR_SPECIAL_KEY; VAR O { THERE IS NO NEXT } BEGIN { OPTION, SOUND } WRITE (CHR(7)); { BELL, RESET PA- } TEMP_OPT_PTR := START_OPT_PTR; { RAMETERS TO BE- } OPT_ROW := OLDOW + 1; { TOTAL LINE COUNT } IF TEMP_OPT_PTR^.OPTION[2] <> CHR(NRMLDELM) THEN OPT_NBR := OPT_NBR + 1; { TOTAL OPT COUNT } END; END; IF TEMP_OPT_PTR = NIL THEN BEGIN { OR END REACHED } TEMP_OPT_PTR := TEMP_OPT_PTR^.OLINK; { NEXT OPTION } IF TEMP_OPT_PTR <> NIL THEN { NOT AT END LIST } BEGIN OPT_ROW := OPT_R:= TEMP_OPT_PTR; { SAVE CURRENT OPT PTR } RESET_OPTION (TEMP_OPT_PTR); { UN-HIGHLIGHT CUR OPT } WHILE (OPT_NBR < OLD_OPT_NBR+1) AND { LOOK FORWARD IN } (TEMP_OPT_PTR <> NIL) DO { LIST UNTIL NEXT } BR_OF_OPTS) THEN { PLAYED? } BEGIN { YES } OLD_OPT_NBR := OPT_NBR; { SAVE CURRENT OPT NBR } OLD_OPT_ROW := OPT_ROW; { SAVE CURRENT OPT ROW } START_OPT_PTR _OPT_NBR, OLD_OPT_ROW : INTEGER; START_OPT_PTR : OPT_PTR; BEGIN IF OPTS_DISPLAYED AND { ARE THERE } (OPT_NBR > 0) AND { OPTS DIS- } (OPT_NBR < TEMP_MENU_PTR^.NLD_OPT_NBR-1 THEN { GET NEXT OPT } TEMP_OPT_PTR := TEMP_OPT_PTR^.OLINK; END; SET_OPTION (TEMP_OPT_PTR); { HIGHLIGHT IT } END; END; PROCEDURE GET_NEXT_OPT; VAR OLD { PREV OPT FOUND } IF TEMP_OPT_PTR^.OPTION[2] <> CHR(NRMLDELM) THEN OPT_NBR := OPT_NBR + 1; { TOTAL OPT COUNT } OPT_ROW := OPT_ROW + 1; { TOTAL LNE COUNT } IF OPT_NBR < O { SET UP SEARCH } OPT_ROW := 2; { PARAMETERS } TEMP_OPT_PTR := TEMP_MENU_PTR^.HEAD_OPT_PTR; WHILE OPT_NBR < OLD_OPT_NBR-1 DO { CONTINUE UNTIL } BEGIN BEGIN { THAN ONE } OLD_OPT_NBR := OPT_NBR; { SAVE CUR OPT } RESET_OPTION (TEMP_OPT_PTR); { UN-HIGHLIGHT IT } OPT_NBR := 0; CLEAR_OPTIONS_AREA; { OPT BOX, SET } OPT_NBR := 0; { OPTION NUMBER } END { TO ZERO } ELSE { OPT IS GREATER } VAR I,OLD_OPT_NBR : INTEGER; BEGIN IF OPTS_DISPLAYED AND (OPT_NBR > 0) THEN { ARE THERE OPTS? } IF OPT_NBR = 1 THEN { YES, 1ST ONE? } BEGIN { YES, CLEAR THE } E { CAN'T SEARCH FOR } BEGIN { OPEN-APPLE KEY } OLD_MENU_NBR := MENU_NBR; { ELSE SAVE CUR- } OLD_TEMP_MENU_PTR := TEMP_MENU_PTR; { RENT MENU NUMBER } TEMP_MENU_PTR := HEAD_MENU_PTR; { AND POINTER, SET } MENU_NBR := 0; { UP TO SEARCH } OPTION_FOUND := FALSE; { FROM BEGINNING } WHILE TEMP_MENU_PTR <> NIL DO { SEARBR := TEMP_MENU_PTR^.NBR_OF_OPTS; DISPLAY_OPTIONS_AREA (OPT_NBR); { OF OPTIONS FOR THIS } END { MENU, THEN DISPLAY } ELSE { IT, IF NOT A VALID } BEGIN < 1 THEN { OPTION NUMBER: BE- } OPT_NBR := 1 { TWEEN THE LEAST } ELSE { & GREATEST NUMBER } IF OPT_NBR > TEMP_MENU_PTR^.NBR_OF_OPTS THEN OPT_N { HIGHLIGHT THE MENU } { NOW SCAN FOR THE OPTION NUMBER PASSED IN TO THE PROC } IF (OPT_NBR > 0) AND (TEMP_MENU_PTR^.NBR_OF_OPTS > 0) THEN BEGIN { CHECK FOR A VALID } IF OPT_NBR ACHED } TEMP_MENU_PTR := TEMP_MENU_PTR^.MLINK; { NEXT MENU } I := I + 1; { INCREMENT COUNTER } END; { WHEN FINISHED, } SET_MENU (TEMP_MENU_PTR); } IF TEMP_MENU_PTR^.MLINK = NIL THEN { SCAN UNTIL MENU NUM } MENU_NBR := I { IS REACHED, OR } ELSE { UNTIL END OF LIST } BEGIN { IS RE PROCEDURE SET_INIT_PARMS; VAR I : INTEGER; BEGIN TEMP_MENU_PTR := HEAD_MENU_PTR; { SET UP MENU AND OPT } I := 1; { TO THOSE VALUES } WHILE I < MENU_NBR DO { PASSED INTO PROC END; WRITE (CHR(7)); { IF WE'RE HERE, A } TEMP_MENU_PTR := OLD_TEMP_MENU_PTR; { MATCH WASN'T } MENU_NBR := OLD_MENU_NBR; { FOUND } END; END; EXIT (SCAN_FOR_SPECIAL_KEY); { LEAVE } END; TEMP_OPT_PTR := OLINK; { SET TO NEXT OPT } END; TEMP_MENU_PTR := MLINK; { SET TO NEXT MENU } RESET_MENU (OLD_TEMP_MENU_PTR); SET_MENU (TEMP_MENU_PTR); { SET } EXIT_CODE := C; { EXIT } OPT_PICKED := TRUE; { PARMS } IF (ORD(C)-128 = ORD(OPTION[I+2])) OR ((ORD(C)-128 IN [97..122]) AND (ORD(C)-160 = ORD(OPTION[I+2]))) THEN BEGIN { FOUND A MATCH } { SCAN LINE FOR AN OPEN-APPLE CHARACTER } I := SCAN(MAX_OPT_LEN,=CHR(255),OPTION[1]); { CHECK OPEN-APPLE KEY FOR KEY PRESSED } IF I < MAX_OPT_LEN THEN { LIST } { IF THIS ISN'T A DEL LINE INC OPT COUNTER } IF OPTION[2] <> CHR(NRMLDELM) THEN OPT_NBR := OPT_NBR + 1; _PTR; { SCAN ALL OPTIONS } OPT_NBR := 0; { FOR THIS MENU } WHILE TEMP_OPT_PTR <> NIL DO { SEARCH UNTIL NO } WITH TEMP_OPT_PTR^ DO { OPTIONS LEFT IN } BEGIN CH UNTIL NO } WITH TEMP_MENU_PTR^ DO { MENUS LEFT IN } BEGIN { LIST } MENU_NBR := MENU_NBR + 1; { INC MENU NUMBER } TEMP_OPT_PTR := HEAD_OPT { OPTION NUMBER, SET } OPT_NBR := 0; { TO ZERO, AND DO NOT } OPTS_DISPLAYED := FALSE; { DISPLAY OPTIONS FOR } END; { THE MENU } END; BEGIN { MENU_MANAGER } WRITE (CHR(6)); { TURN CURSOR OFF } EXIT_CODE := CHR(0); { NO EXIT HAS OCCURRED YET } OPT_PICKED := FALSE; { NO OPTIONS ARE PICKED YET } SET_INIT_PARMS; , 1, 1); LOAD_CHARACTER (FILUPLFT,127,127,127,127,127, 64, 64, 64); LOAD_CHARACTER (FILLBLCK,127,127,127,127,127,127,127,127); LOAD_CHARACTER (FILLTHAF,127,127,127,127,127, 0, 0, 0); LOAD_CHARACTER (OURBOXSH, 0, 0, 0,127,127, 0, 1, 1); LOAD_CHARACTER (OPNLWLFT, 1, 1, 1,127,112, 0, 0, 0); LOAD_CHARACTER (OPNLWRGT, 64, 64, 64,127,127, 0, 0, 0); LOAD_CHARACTER (HFBOXSHD, 7, 7, 7, 7, 7, 0, 0, 0); LOAD_CHARACTER (FILUPRGT,127,127,127,127,127, 1, 1, 1); LOAD_CHARACTER (OPTRGTDM, 64, 64, 64, 64, 64, 64, 64, 64); LOAD_CHARACTER (FLBOXSHD, 7, 7, 7, 7, 7, 7, 7, 7); LOAD_CHARACTER (OPNUPRGT, 0, 0, 0,127,127, 64, 64, 64); LOAD_CHARACTER (OPNUPLFT, 0, 0, 0,127,127, 1A } { PULL DOWN MENU INTERFACE (AND MUCH SMALLER UNIT ). } BEGIN LOAD_CHARACTER (NRMLDELM, 0, 0, 0,127, 0, 0, 0, 0); LOAD_CHARACTER (OPTNDELM, 0, 0, 0,127,127, 0, 0, 0); LOAD_CHARACTER (OPTLFTDM, 1, 1, 1, 1, 1, 1OWS } { WITH THE BOXES, DELIMITER LINES WITHIN OPTION BOXES, } { HIGHLIGHTED MENU HEADERS AND OPTION LINES, ETC. IF } { YOU PREFER, YOU MAY ELIMINATE ALL SPECIAL CHARACTERS } { AND REFERENCES TO THEM, THUS PRODUCING A PLAIN VANILL MENU HEADER } WRITE (CHR(5)); { TURN CURSOR BACK ON } END; PROCEDURE LOAD_PDM_FONT_CHRS; { THIS PROCEDURE WILL LOAD ALL THE SPECIAL CHARACTERS } { NEEDED BY THE PULL DOWN MENUS TO FORM BOXES, SHAD END; UNTIL OPT_PICKED; { REAPEAT ABOVE UNTIL VAL OPT } IF OPTS_DISPLAYED THEN { IF OPTIONS ARE DISPLAYED ON } CLEAR_OPTIONS_AREA; { EXIT, CLEAR THE SCREEN } RESET_MENU (TEMP_MENU_PTR); { UN-HIGHLIGHTVE, WAS THE } IF ORD(C) IN [128..255] THEN { OPEN-APPLE KEY DOWN? } SCAN_FOR_SPECIAL_KEY { YES, SCAN FOR COMMAND KEYS } ELSE { NO, SOUND AN ERROR BELL } WRITE (CHR(7)); } CLEAR_OPTIONS_AREA { CURRENTLY DISPLAYED, ER- } ELSE { ASE THEM, ELSE SOUND AN } WRITE (CHR(7)); { ERROR BELL } OTHERWISE { NONE OF THE ABO 21 : GET_NEXT_MENU; { RIGHT-ARROW, GET NEXT MENU } 10 : GET_NEXT_OPT; { DOWN-ARROW, GET NEXT OPTION } 11 : GET_PREV_OPT; { UP-ARROW, GET PREV OPTION } 27 : IF OPTS_DISPLAYED THEN { ESCAPE, IF OPTIONS ARE IONS_AREA (1) { THEN DISPLAY THEM FOR MENU } ELSE { IF NOT A RETURN KEY, THE } CASE ORD(C) OF { CHECK TO SEE WHAT KEY } 8 : GET_PREV_MENU; { BACK-ARROW, GET PREV MENU } { IS > 0, THEN OPT IS PICKED } ELSE { OTHERWISE NONE OF THE ABOVE } WRITE (CHR(7)) { IS TRUE, SO SOUND AN ERROR } ELSE { IF OPTS ARE NOT DISPLAYED, } DISPLAY_OPT KEY PRESSED } IF EOLN(KEYBOARD) THEN { IF A RETURN IS HIT } IF OPTS_DISPLAYED THEN { AND OPTIONS ARE DISPLAYED } IF OPT_NBR > 0 THEN { AND OPTION NUMBER SELECTED } OPT_PICKED := TRUE { PROCESS MENU AND OPT PASSED } REPEAT { UNTIL AN OPTION IS PICKED } REPEAT { UNTIL A KEY IS PRESSED } UNTIL KEY_PRESSED; READ (KEYBOARD,C); { READ THE, 7, 7); LOAD_CHARACTER (OPTLFTDL, 1, 1, 1,127, 1, 1, 1, 1); LOAD_CHARACTER (OPTRGTDL, 64, 64, 64,127, 64, 64, 64, 64); LOAD_CHARACTER (FURBOXSH,127,127,127,127,127, 0, 7, 7); LOAD_CHARACTER (FILLWLFT,127,127,127,127,112, 0, 0, 0); LOAD_CHARACTER (FILLBHAF, 0, 0, 0,127,127,127,127,127); LOAD_CHARACTER (MOUSEARW, 1, 6, 30,124, 60, 40, 64, 0); LOAD_CHARACTER (RIGHTARW, 8, 16, 32,127, 32, 16, 8, 0); LOAD_CHARACTER (LEFTARRW, 8, 4, 2,127, 2, 4pear normal. Therefore, in order to produce a flashing character, that characters 8 definition bytes will have to be retrieved from memory, all bits will have to be inverted (that is,a 1 becomes a 0, and a 0 becomes a 1; this has to be done so the charactper-byte=64bits). however, a character is defined as 7-columns by 8-rows equalling 56 bits.This leaves bit 8 of each byte as unused. As it turns out, if bit 8 is set to 1, the character will flash when it is displayed in inverse mode, otherwise it will appies $0c00 thru $0c07, ASCII 1 occupies $0c08 thru $0c0f, etc.). If you stack any characters 8 definition bytes one on top of the other, you would form a matrix of 8-columns by 8-rows equalling 64 bits (remember,a byte consists of 8 bits: 8 bytes * 8 bits- is the start of the system character set definition. The Apple ///'s system character set consists of 128 unique characters given ASCII values 0 thru 127. Each character is defined in 8 consecutive bytes starting at location $0c00 (that is, ASCII 0 occu keyboard.It naturally follows that when characters are displayed on the screen, the ".CONSOLE" driver must know the pattern of the characters to be displayed.".CONSOLE" determines this pattern from the information contained at memory location $0c00, which also in "SOS.DRIVER"), is loaded into specific memory locations.One device driver that is required and always loaded is the ".console" driver. the ".console" driver controls all keyboard and screen/IO that occurs and constantly monitors the status of theime consuming program code. As you may already know, when the Apple /// is booted the SOS operating system ("SOS.KERNEL"), the interpreter ("SOS.INTERP"), the device drivers ("SOS.DRIVER"),and other information (including the system character set which isz|}~ routines? How many times have you wanted to add a nice visual presentation to your programs, but didn't want to use graphics? Well thanks to Apple ///down-loadable characters you can make flashing characters and fancy pictures without having complex or t Title: How To Get Special Characters Created by Pair Software 11/12/1988 17:10:54 How To Get Flashing (and other) Characters by John E. Cisar Have you ever wondered how some programs display flashing characters or fancy pictures without calling graphicsEND. ================================================================== NO INITIALIZATION } END. ================================================================== ======================================= ========== , 8, 0); LOAD_CHARACTER (DOWNARRW, 8, 8, 8, 8, 73, 42, 28, 8); LOAD_CHARACTER (UPARROW, 8, 28, 42, 73, 8, 8, 8, 8); LOAD_CHARACTER (OPNAPPLE, 16, 8, 62, 17, 17, 33, 30, 0); END; BEGIN { PDM } { NO INITIALIZATION } er will appear normal when it's displayed in inverse),bit 8 of each byte will have to be set to a 1, and the character will have to be re-loaded and re-displayed in inverse mode. This can be accomplished via the assembly procedure "get_char_map" shown in figure 1, and the PASCAL procedure "load_char_map" in the PASCAL program "flash_a_char" both shown in figure 2. Note that "get_char_map" is an assembly language procedure that can be used in either PASCAL or BASIC programs to retrieve character definition b The first one is d_control call number 16:"download characterset". this will load a characterset into the Apple ///'s video generator, thus changing all subsequent characters displayed. It also changes any characters currently on the screen to the new cCONSOLE" driver are the d_status and d_control calls. Generally speaking, most drivers are designed to handle a variety of d_status and d_control calls, each having a unique number. There are two d_control calls used in conjunction with characters sets.vers. System (or SOS) calls are the normal method that assembly-language programs (including the BASIC and PASCAL language interpreters) use for communicating with files (including drivers) and devices on the Apple ///. Two SOS calls used to control the ".raphics screen) How To Get Drivers To Do What You Want -------------------------------------- The design of device drivers, and in particular the ".CONSOLE" DRIVER, allows programs to send commands known as system calls (or SOS calls) to control these driolution graphics screen). You could, in theory, use all 128 characters for building your picture, but that would leave you with no characters to display text with and you would not gain all that much:128 x 8 x 7 or 11,136 pixels (only about 1/9th of the ggrams; the only drawback is that you are limited to 32 characters to build your picture in. Since a normal high-resolution graphics screen is 560 x192 or 107,520 pixels, with 32 characters you only get 32 x 8 x 7 or 1,792 pixels (or 1/60th of the high-resnition bytes of these 7 characters since you'll be loading them with completely different definitions. Instead, all you need is the PASCAL procedure "load_char_map". This concept of making larger pictures out of smaller ones is common on many Apple/// pros, 2 for the sides, and 1 for the horizontal line. These 7 characters were actually taken from the 'non-displayable' ASCII characters 0 thru 31, re-defined and re-loaded (as discussed above). However, you obviously don't need to retrieve the character defi picture composed of several characters that have been loaded with special definitions. An example of this would be in Mail List Manager, where a 3"x 5" label is drawn on the screen. This label is actually composed of 7 special characters:4 for the cornero be a flashing "a", it will have to be displayed (in pascal) as"write(chr(30+128));"not"write (chr(30));". Some programs display fancy pictures that look like they're drawn using graphics routines. However, many times what you're looking at is actually aferent definition). Once the new flashing character has been loaded, the value 128 will have to be added to the ASCII value before displaying (even though ASCII 0 thru 31 are never displayed, 128 thru 159 are).For example, if ASCII value 30 is re-loaded tters 0 thru 31 are INTERPreted by ".CONSOLE" as screen control codes and are never displayed. But since they occupy character definition bytes in memory,they can temporarily (or permanently) hold the new flashing character definition (or an altogether difnd re-loading a character is that all occurences of that character on the screen change to reflect the new definition. In order to prevent this, the character will have to be re-loaded as a character that is not already displayed. Fortunately, ASCII characytes. When used in PASCAL programs (such as "flash_a_char"), it must be a(ssembled and l(inked with the program before use. Also note that"load_char_map"is a PASCAL procedure that can be used within any PASCAL program. The only problem when re-defining aharacter set. The second d_control call is number 17: "load partial character set". This will load up to 8 characters into the Apple ///'s video generator, again changing those 8 characters on the screen, as well as when they are subsequently displayed. This call is the method by which an individual character is re-loaded on the Apple ///. All SOS d_status and d_control calls to drivers and devices (including the ".CONSOLE" driver) can be made through PASCAL by means of the unitstatus procedure, but only ER PROCEDURE. ------------------------------------------------------------------ ;---------------- ; MACRO POP - POPS 1 WORD OFF STACK ;---------------- .MACRO POP PLA STA %1 PLA BELLS AND WHISTLES TO YOUR PROGRAMS IN THE FORM OF FLASHING CHARACTERS AND/OR FLASHY PICTURES. GOOD LUCK AND GOOD COMPUTING! ================================================================== FIGURE 1: THE SOURCE CODE FOR THE "GET_CHAR_MAP" ASSEMBL PRODUCE STRIKING AND BEAUTIFUL PROGRAMS NORMALLY CONSIDERED APPROPRIATE ONLY FOR GRAPHICS ENVIRONMENTS (WHICH HAVE A TEMENDOUS AMOUNT OF OVERHEAD ON ANY COMPUTER). I HOPE THIS INFORMATION HELPS THOSE OF YOU WHO HAVE BEEN THINKING ABOUT ADDING SOMEROL CALLS, REFER TO THE "STANDARD DEVICE DRIVERS HANDBOOK" PAGES 34 TO 46, 59 TO 71, APPENDIX G, AND APPENDIX H. THE APPLE /// AFFORDS PROGRAMMERS (AND END-USERS) THE POWER AND FLEXIBILITY OF DOWN-LOADABLE CHARACTERS. IF USED PROPERLY, THIS ABILITY CANEN SETTING UP A SPECIAL DATA STRUCTURE AND HAVING SEVERAL EQUATE STATEMENTS. THIS IS ALSO THE METHOD USED IN THE "LOAD_CHAR_MAP" PROCEDURE. FOR AN EVEN MORE IN-DEPTH DISCUSSION OF CHARACTER LAYOUTS, SCREEN CONTROL CODES, AND D_STATUS AND D_CONTQUIVALANT TO THE INTEGER VALUE 68 (REMEMBER, AN INTEGER IS ALSO 16 BITS), SO THE UNITSTATUS CALL WOULD BE: UNITSTATUS (UNIT_NUMBER,STATUS_LIST,68); THIS METHOD IS SOMETIMES EASIER (ESPECIALLY WHEN YOU ONLY HAVE ONE OR TWO UNITSTATUS CALLS) TH0 0 0 1 1 0 | | | | | | | | | | | +---CHANNEL | | | | +---STATUS OR CONTROL | | +-------------+---REQUEST NUMBER +---------+---RESERVED THIS IS El 16 bits filling in the appropriate bits, then computing the integer that the pattern produces and passing that number as the "request_code". For example, if you wanted to make d_control call 17, the bit pattern would be: 0 0 0 0 0 0 0 0 0 1 RESERVED : 0..63; { ALWAYS ZERO } END; VAR REQ_CODE : REQ_CODE_REC; You would then fill in the fields of the record as appropriate for the type of call you are making. The second method is to simply layout alformation: TYPE REQ_CODE_REC = PACKED RECORD CHANNEL : 0..1; { 0-INPUT 1-OUTPUT } STAT_OR_CTRL : 0..1; { 0-D_STATUS 1-D_CONTROL} REQUEST_NUM : 0..255; { SPECIFIC NUMBER } trol call being made; and what channel (input or output) of the "unit_number" is being affected. there are two methods of specifying the "request_code". The first method is to specify a pascal data structure with the appropriate d_status or d_control in you define depends upon the kind of d_status or d_control call you are making. The "request_code" parameter is a 16 bit value specifing three pieces of information: whether it's a d_status or d_control call; the number of the d_status or d_con For calls to the ".CONSOLE" driver, "unit_number" should be 1; for the ".GRAFIX" driver, "unit_number" should be 3; etc. The "status_list" parameter must be a declared variable; it cannot be a constant of any kind. the type of "status_list"some of them are useful in PASCAL programs. The form of a unitstatus request is: UNITSTATUS (UNIT_NUMBER,STATUS_LIST,REQUEST_CODE); The "unit_number" parameter is an integer variable or constant that specifies the logical unit to be controlled. STA %1+1 .ENDM ;---------------- ; MACRO PUSH - PUSHES 1 WORD ON STACK ;---------------- .MACRO PUSH LDA %1+1 PHA LDA %1 PHA .ENDM ;---------------- ; MACRO ADD - ADD TWO NUMBERS ;---------------- .MACRO ADD CLC LDA %1 ADC %2 STA %3 LDA %1+1 ADC } { DEFINITION BYTES USED TO DEFINE A CHARACTER AS 8 SEPARATE } { INTEGERS. THIS VERSION WOULD BE EASIER TO WORK WITH IF YOU } { WERE PLANNING ON DEFINING BRAND NEW CHARACTERS, AND/OR YOU } { DID NOT NEED THE "GET_CHAR_MAP" PROCEDURE. OL_LIST[I+1] := CHAR_MAP[I]; { LOAD EACH BYTE } UNITSTATUS (1,CONTROL_LIST,70); { MAKE THE LOAD CALL } END; { AN ALTERNATE "LOAD_CHAR_MAP" PROCEDURE IS SHOWN BELOW. THIS } { VERSION OF "LOAD_CHAR_MAP" HAS YOU PASS IN THE 8 CHARACTER ..10] OF BYTE; I : INTEGER; BEGIN CONTROL_LIST[1] := 1; { NUM. CHARS. TO LOAD } CONTROL_LIST[2] := ASCII; { ASCII TO LOAD } FOR I := 2 TO 9 DO { MAP IS BYTES 2 TO 9 } CONTR : CHAR; { PLACE TO HOLD KEY ENTERED } PROCEDURE GET_CHAR_MAP (ASCII : INTEGER; VAR S); EXTERNAL; PROCEDURE LOAD_CHAR_MAP (ASCII : INTEGER; CHAR_MAP : CHAR_MAP_ARRAY); VAR CONTROL_LIST : PACKED ARRAY [1----------------------- PROGRAM FLASH_A_CHAR; TYPE BYTE = 0..255; { STANDARD BYTE } CHAR_MAP_ARRAY = PACKED ARRAY [1..9] OF BYTE; { CHARACTER MAP } VAR CHAR_MAP : CHAR_MAP_ARRAY; { PLACE TO HOLD CHARACTER MAP } C ==================================== ================================================================== FIGURE 2: THE SOURCE CODE FOR THE "FLASH_A_CHAR" PASCAL PROGRAM AND THE "LOAD_A_CHAR" PASCAL PROCEDURE. -------------------------------------------" CPY #8 ; HAVE WE GOT 8 BYTES? BNE $01 ; NO - CONTINUE PROCESSING END_GCBM PUSH RETURN ; ALL DONE RTS .END ============================== ; SET ASCII IN BYTE 1 STA @S,Y ; " " $01 LDA @OFFSET,Y ; GET OFFSET CHARACTER INY ; STORE CHAR. IN VARIABLE STA @S,Y ; " BNE $01 ; COMPUTE_OFFSET ADD ASCII,CHARACTER_SET,OFFSET LOAD_DEFINITION LDY #0 ; INITIALIZE FOR INDIRECT STY OFFSET_XBYTE ; INITIALIZE X-BYTE TXA MPORARILY STORE ASCII LDY #3 ; $01 CLC ; ASL ASCII ; MULTIPLY ASCII BY 8 ROL ASCII+1 ; DEY ; ; ADDRESS OF CHARACTER SET START_GCM POP RETURN ; RETURN ADDRESS POP S ; VARIABLE ADDRESS POINTER POP ASCII ; SHOULE BE 0..127 LDX ASCII ; TE .EQU 00E0 ; ENHANCED ASCII .EQU 0002 ; NON-ENHANCED OFFSET .EQU 0004 ; NON-ENHANCED OFFSET_XBYTE .EQU 1605 ; XBYTE OF OFFSET CHARACTER_SET .WORD 0C00 RST BYTE ; BEING THE ASCII VALUE PASSED IN. ; ;---------------- .PROC GET_CHAR_MAP,2 ; 2 WORDS OF PARAMETERS JMP START_GCM ; JUMP OVER STORAGE, ETC. RETURN .EQU 0000 ; NON-ENHANCED S %2+1 STA %3+1 .ENDM ;---------------- ; PROCEDURE GET_CHAR_MAP (ASCII : INTEGER; VAR S); EXTERNAL; ; ; THIS PROCEDURE RETURNS THE 'ASCII' CHARACTER DEFINITION BYTES ; IN VARIABLE 'S' AS A STREAM OF 9 BYTES WITH THE FI } { } { PROCEDURE LOAD_CHAR_MAP (ASCII, } { D1,D2,D3,D4,D5,D6,D7,D8 : INTEGER; } { VAR CONTROL_LIST : PACKED ARRAY [1..10] OF BYTE; } { BEGIN } { CONTROL_LIST[ 1] := 1; (* NUM. CHARS. TO LOAD *) } { CONTROL_LIST[ 2] := ASCII; (* ASCII TO LOAD *) } { CONTROL_LIST[ 3] := D1tine that directly accesses the video screen's memory mapped display and retrieves a specified portion of it. Figure 1 contains a table showing the internally mapped screen layout locations. This table is reprinted from the "Prompt Procedure" arthow much simpler some of your program and routines (especialy I/O routines) would be if you had this capability? Well the "GET_SCREEN_STRING" procedure may be what you're looking for. The "GET_SCREEN_STRING" procedure is an assembly language rou TITLE: GET A SCREEN STRING IN BASIC OR PASCAL CREATED BY PAIR SOFTWARE 11/11/1988 10:02:15 THE GET_SCREEN_STRING PROCEDURE BY JOHN E. CISAR Wouldn't it be nice to quickly retrieve part of a screen display? How many times have you thought about ),CHR(159),CHR(17),'"'); END; UNTIL ORD(C) = 27; { ESCAPE PRESSED } END. ================================================================== SUBJECT (Q,R,I,?,/) -> ================================================================ ORD(C):4,' NORMAL "',C, '" INVERSE "',CHR(18),C,CHR(17),'"'); WRITELN; WRITELN ('NOW RELOADED AS ASCII 31 NORMAL "',CHR(159), '" INVERSE "',CHR(18 '" INVERSE "',CHR(18),C,CHR(17),'"'); WRITELN; WRITELN ('NOW RELOADED AS ASCII 31 NORMAL "',CHR(159), '" INVERSE "',CHR(18),CHR(159),CHR(17),'"'); END; UNTIL ORD(C) = 27; { ESCAPE PRESSED } END. =============C) MOD 128,CHAR_MAP); { GET CURRENT } SET_FLASH_BITS (CHAR_MAP); { SET NEW MAP } LOAD_CHAR_MAP (31,CHAR_MAP); { LOAD NEW MAP } WRITELN; WRITELN ('KEY PRESSED WAS ASCII',ORD(C):4,' NORMAL "',C, ; WRITELN; REPEAT GOTOXY (0,2); WRITE ('PRESS KEY OF CHARACTER TO FLASH ( TO EXIT) '); READ (KEYBOARD,C); { GET KEY TO CHANGE TO FLASHING } WRITELN; IF ORD(C) IN [32..127,160..255] THEN BEGIN GET_CHAR_MAP (ORD( { REPLACE ASCII 31 } FOR I := 2 TO 9 DO { MAP IS BYTES 2 TO 9 } CHAR_MAP[I] := 255 - CHAR_MAP[I]; { MASK BYTES TO FLASH } END; BEGIN { FLASH_A_CHAR } WRITE (CHR(28)); { CLEAR THE SCREEN } WRITELN ('FLASH A CHARACTER') UNITSTATUS (1,CONTROL_LIST,70); (* MAKE THE LOAD CALL *) } { END; } PROCEDURE SET_FLASH_BITS (VAR CHAR_MAP : CHAR_MAP_ARRAY); VAR I : INTEGER; BEGIN CHAR_MAP[1] := 31; ST[ 7] := D5; (* DEFINITION BYTE 5 *) } { CONTROL_LIST[ 8] := D6; (* DEFINITION BYTE 6 *) } { CONTROL_LIST[ 9] := D7; (* DEFINITION BYTE 7 *) } { CONTROL_LIST[10] := D8; (* DEFINITION BYTE 8 *) } { ; (* DEFINITION BYTE 1 *) } { CONTROL_LIST[ 4] := D2; (* DEFINITION BYTE 2 *) } { CONTROL_LIST[ 5] := D3; (* DEFINITION BYTE 3 *) } { CONTROL_LIST[ 6] := D4; (* DEFINITION BYTE 4 *) } { CONTROL_LIicle appearing in "The /// Magazine." The "GET_SCREEN_STRING" procedure incorporates some of the concepts covered in that article regarding the internally mapped screen layout. ==================================================================== FIGURE 1: THE INTERNALLY MAPPED SCREEN LAYOUT LOCATIONS. -------------------------------------------------------------------- ::::::::SCREEN MAP 1::::::::: ::::::::SCREEN MAP 2::::::::: LOCATIONS ROW COLUMNS LOCATIONS ROW TION IS THAT ALL CHECKING HAS BEEN DONE BEFORE THIS PRO- ; CEDURE IS CALLED. ; ;---------------- .PROC GET_SCREEN_STRING,4 ; 4 WORDS OF PARMS. JMP START_GSS ; JUMP OVER STORAGE, ETC. RETURN .EQU VAR S : BYTESTREAM); EXTERNAL; ; ; THIS PROCEDURE RETURNS A STRING 'S' CONSISTING OF 'LENGTH' ; CHARACTERS STARTING AT POSITIONS 'COLUMN' AND 'ROW' ON THE ; SCREEN. IT DOES NOT CHECK FOR BOUNDS ERRORS AS THE ASSUMP- ; ADC %2 STA %3 LDA %1+1 ADC %2+1 STA %3+1 .ENDM ;---------------- ; PROCEDURE GET_SCREEN_STRING (LENGTH,COLUMN,ROW : INTEGER; ; F LDA #%1^MASK AND %2 STA %2 .ENDM ;---------------- ; MACRO ADD - ADD TWO NUMBERS ;---------------- .MACRO ADD CLC LDA %1 RO PUSH LDA %1+1 PHA LDA %1 PHA .ENDM MASK .EQU 00FF ;---------------- ; MACRO BITSOFF - SETS BITS TO 0 ;---------------- .MACRO BITSOF-------------- .MACRO POP PLA STA %1 PLA STA %1+1 .ENDM ;---------------- ; MACRO PUSH - PUSHES 1 WORD ON STACK ;---------------- .MAC============================================================== FIGURE 2: THE SOURCE CODE FOR THE "GET_SCREEN_STRING" PROCEDURE. -------------------------------------------------------------------- ;---------------- ; MACRO POP - POPS 1 WORD OFF STACK ;-- $0BA8 - $0BCF 16 ODD $07D0 - $07F7 24 EVEN $0BD0 - $0BF7 24 ODD ==================================================================== FIGURE 2 CONTAINS THE SOURCE CODE FOR THE "GET_SCREEN_STRING" PROCEDURE. ====== $0B00 - $0B27 7 ODD $0728 - $074F 15 EVEN $0B28 - $0B4F 15 ODD $0750 - $0777 23 EVEN $0B50 - $0B77 23 ODD $0780 - $07A7 8 EVEN $0B80 - $0BA7 8 ODD $07A8 - $07CF 16 EVEN $0A50 - $0A77 21 ODD $0680 - $06A7 6 EVEN $0A80 - $0AA7 6 ODD $06A8 - $06CF 14 EVEN $0AA8 - $0ACF 14 ODD $06D0 - $06F7 22 EVEN $0AD0 - $0AF7 22 ODD $0700 - $0727 7 EVEN A8 - $09CF 12 ODD $05D0 - $05F7 20 EVEN $09D0 - $09F7 20 ODD $0600 - $0627 5 EVEN $0A00 - $0A27 5 ODD $0628 - $064F 13 EVEN $0A28 - $0A4F 13 ODD $0650 - $0677 21 EVEN $0927 3 ODD $0528 - $054F 11 EVEN $0928 - $094F 11 ODD $0550 - $0577 19 EVEN $0950 - $0977 19 ODD $0580 - $05A7 4 EVEN $0980 - $09A7 4 ODD $05A8 - $05CF 12 EVEN $0977 17 ODD $0480 - $04A7 2 EVEN $0880 - $08A7 2 ODD $04A8 - $04CF 10 EVEN $08A8 - $08CF 10 ODD $04D0 - $04F7 18 EVEN $08D0 - $08F7 18 ODD $0500 - $0527 3 EVEN $0900 - COLUMNS ------------- --- ------- ------------- --- ------- $0400 - $0427 1 EVEN $0800 - $0827 1 ODD $0428 - $044F 9 EVEN $0828 - $084F 9 ODD $0450 - $0477 17 EVEN $0850 - $08 0000 ; NON-ENHANCED S .EQU 00E8 ; ENHANCED ROW .EQU 0002 ; NON-ENHANCED COLUMN .EQU 0004 ; NON-ENHANCED LENGTH .EQU 0006 ; NON-ENHANCED OFFSET1 .EQU 0008 ; WORK OFFSET 1 OFFSET2 .EQU 000A ; WORK OFFSET 2 OFFSET1_XBYTE .EQU 1609 ; XBYTE OF OFFSET 1 OFFSET2_XBYTE .EQU 160B ; XBYTE OF OFFSET 2 COUNTER .BYTE #0 ; INITIALIZE FOR OFFSETS $01 TXA ; LOAD OFFSET COUNTER TAY ; " " LDA @OFFSET1,Y ; INC COUNTER ; STORE OFFSET 1 C STY OFFSET2_XBYTE ; USE X-BYTE FOR S-BANK STY COUNTER ; INITIALIZE COUNTER LDA LENGTH ; SET LENGTH OF STA @S,Y ; RETURN STRING LDX ADD ROW,COLUMN,OFFSET2 ; COMPUTE OFFSET 2 ADD OFFSET2,SCREEN1,OFFSET2 ; " " LOAD_CHARACTERS LDY #0 ; INITIALIZE FOR INDIRECT STY OFFSET1_XBYTE ; USE X-BYTE FOR S-BANK DEC COLUMN ; SUBTRACT 1 ADD ROW,COLUMN,OFFSET1 ; COMPUTE OFFSET 1 ADD OFFSET1,SCREEN2,OFFSET1 ; " " INC COLUMN ; ADD 1 TO COLUMN JMP LOAD_CHARACTERS ; LOAD STRING $02 STX COLUMN ; GET ORIG. VALUE OF COLUMN CLC ; CLEAR CARRY FOR DIVISION ROR COLUMN ; DIVIDE COLUMN IN HALF ; CLEAR CARRY FOR DIVISION ROR COLUMN ; DIVIDE COLUMN IN HALF ADD ROW,COLUMN,OFFSET1 ; ADD OFFSET1,SCREEN2,OFFSET2 ; COMPUTE OFFSETS ADD OFFSET1,SCREEN1,OFFSET1 ;LDA COLUMN CMP #0 ; IS COLUMN ODD OR EVEN? BEQ $02 ; GOTO LABEL 2 - EVEN COL. $01 STX COLUMN ; GET ORIG. VALUE OF COLUMN CLC TE_OFFSETS ; READY TO COMPUTE OFFSETS $03 ADD NUM80,ROW,ROW ; ROW IN 17..24 - ADD 80 COMPUTE_OFFSETS LDX COLUMN ; TEMPORARILY STORE COLUMN BITSOFF 00FE,COLUMN ; MASK OFF ALL BUT LAST BIT JMP COMPUTE_OFFSETS ; YES $02 CMP #11 ; CHECK IF ROW IN 9..16 BPL $03 ; NO - GOTO LABEL 3 ADD NUM40,ROW,ROW ; YES - ADD 40 TO ROW JMP COMPU ; BNE $01 ; TXA ; GET ORIGINAL VALUE OF ROW CMP #9 ; CHECK IF ROW IN 1..8 BPL $02 ; NO - GOTO LABEL 2 ; 3 BITS LDY #7 ; $01 CLC ; ASL ROW ; MULTIPLY ROW VALUE BY 128 ROL ROW+1 ; DEY POP LENGTH ; SHOULD BE 1..255 LDX ROW ; TEMPORARILY STORE ROW DEC ROW ; TO GET IN 0..23 BITSOFF 00F8,ROW ; MASK OFF ALL BUT LAST DECIMAL 80 START_GSS POP RETURN ; RETURN ADDRESS POP S ; ADDRESS POINTER FOR 'S' POP ROW ; SHOULD BE 1..24 POP COLUMN ; SHOULD BE 1..80 00 ; COUNTER SCREEN1 .WORD 0400 ; ADDRESS OF SCREEN PAGE 1 SCREEN2 .WORD 0800 ; ADDRESS OF SCREEN PAGE 2 NUM40 .WORD 0028 ; DECIMAL 40 NUM80 .WORD 0050 ; HR. IN 'S' LDY COUNTER ; STA @S,Y ; CPY LENGTH ; DOES COUNTER EQUAL LENGTH? BEQ END_GSS ; YES - ALL DONE TXA ; LOAD OFFSET COUNTER TAY ; " " LDA @OFFSET2,Y ; INC COUNTER ; STORE OFFSET 2 CHR. IN 'S' LDY COUNTER ; STA IS THE UNIT NUMBER OF THE .CONSOLE DRIVER. THE SECOND PARAMETER OF THE "UNITSTATUS" CALL IS THE "STATUS LIST" (THE VALUE OR VALUES RETURNED FROM THE STATUS CALL). IN THIS CASE IT IS THE CHARACTER "C". THE THIRD AND FINAL PARAMETER IS THE "RERFORMS .CONSOLE STATUS CALL 17. NOTE THE USE OF THE "UNITSTATUS" CALL IN THE PROGRAM. THE FIRST PARAMETER OF THE "UNITSTATUS" CALL IS THE "UNIT NUMBER" (A NUMBER DESIGNATED TO DRIVERS IN PASCAL). IN THIS CASE IT IS THE NUMBER "1", WHICH N PORTIONS), BOTH HAVING THEIR ADVANTAGES AND DIS-ADVANTAGES. BOTH OF THESE METHODS ARE TEXT SCREEN'. THIS CALL RETURNS THE ASCII VALUE OF THE CHARACTER AT THE CURRENT CURSOR POSITION. FIGURE 4 ILLUSTRATES A SMALL PASCAL PROGRAM THAT PHE LINE } WRITELN ('STRING RETURNED IS "',S,'"'); END; UNTIL (LENGTH = 0) AND (COLUMN = 0) AND (ROW=0); END. ==================================================================== THERE ARE TWO OTHER WAYS TO RETRIEVE SCREENS (AND/OR SCREEENGTH ? } (COLUMN IN [1..80]) AND { IN A VALID COLUMN ? } (ROW IN [1..24]) THEN { IN A VALID ROW ? } BEGIN GET_SCREEN_STRING (LENGTH,COLUMN,ROW,S); GOTOXY (0,3); { SHOW STRING } WRITE (CHR(30)); { CLEAR T REPEAT GOTOXY (0,2); { GET LENGTH, COLUMN, AND ROW VALUES } WRITE (CHR(30)); { CLEAR THE LINE } WRITE ('ENTER "LENGTH", "COLUMN", AND "ROW" (0,0,0 TO END) ? '); READLN (LENGTH,COLUMN,ROW); IF (LENGTH IN [1..80]) AND { IN A VALID LEAR SCREEN } GOTOXY (0,5); WRITELN ('THIS IS A FIELD THAT YOU CAN EXPERIMENT ON'); WRITELN ('RETRIEVING DATA WITH THE "GET_SCREEN_STRING"'); WRITELN ('PROCEDURE. IT STARTS IN COLUMN 1 ON ROW 6'); WRITELN ('(REMEMBER, 1 RELATIVE ADDRESSING).'); TEGER; S : STRING[255]; { CAN BE ANY STRING TYPE } PROCEDURE GET_SCREEN_STRING (LENGTH,COLUMN,ROW : INTEGER; VAR S : BYTESTREAM); EXTERNAL; BEGIN { USES_GET_SCREEN_STRING } WRITE (CHR(28)); { SET CURSOR TO 0,0 - CL============================================= FIGURE 3: A PASCAL PROGRAM THAT USES THE "GET_SCREEN_STRING" PROCEDURE. -------------------------------------------------------------------- PROGRAM USES_GET_SCREEN_STRING; VAR ROW, LENGTH, COLUMN : INQUENT PROGRAMS) TO SEPERATE EACH VALUE WITH A SPACE (NOT A COMMA) OR YOU'LL GET A RUN-TIME EXECUTION ERROR (PLEASE KEEP IN MIND THAT THESE PROGRAMS ARE FOR DEMONSTRATION PURPOSES ONLY, THEY ARE NOT MEANT TO BE "BULLET-PROOF"). ======================= CORNER OF THE SCREEN IS LOCATION 1,1 (NOT 0,0). THE STRING RETURNED ("S") CAN BE OF ANY STRING LENGTH, AS LONG AS YOU ENSURE IT IS LONG ENOUGH TO HOLD "LENGTH" BYTES. BE SURE WHEN ENTERING THE PARAMETERS FROM THE KEYBOARD (FOR THIS AND ALL SUBSEYOU PASS "LENGTH", "ROW", AND "COLUMN" (INTEGERS) TO THE PROCEDURE, AND IT RETURNS "S" (STRING), CONSISTING OF "LENGTH" BYTES STARTING AT POSITION "ROW" AND "COLUMN". ALSO, THE "GET_SCREEN_STRING" PROCEDURE ASSUMES THAT THE UPPER RIGHT-HAND ; ALL DONE RTS .END ==================================================================== FIGURE 3 CONTAINS A SMALL PASCAL PROGRAM ILLUSTRATING THE USE OF THE"GET_SCREEN_STRING" PROCEDURE. NOTE THAT @S,Y ; INX ; INCREMENT OFFSET COUNTER CPY LENGTH ; DOES COUNTER EQUAL LENGTH? BNE $01 ; NO - CONTINUE PROCESSING END_GSS PUSH RETURNEQUEST NUMBER" (THE STATUS CALL NUMBER). IN THIS CASE, IT IS "68", WHICH IS ACTUALLY "17" (THE STATUS CALL NUMBER) MULTIPLIED BY 4 (68 = 17 * 4). THIS METHOD WILL WORK FOR ALL .CONSOLE STATUS CALLS (SUBSTITUTING APPROPRIATE VALUES AS NECESSARY), HOWEVER, IT WILL NOT WORK FOR .CONSOLE CONTROL CALLS (SEE STANDARD DEVICE DRIVERS, APPENDIX H - SYSTEM CALLS IN PASCAL PAGES 169 TO 171 FOR MORE INFORMATION ON STATUS AND CONTROL CALLS). STATUS CALL 17 WORKS FINE WHEN YOU ONLY NEED TO GET AALUE } I : INTEGER; BEGIN { GET_ENTIRE_SCREEN } WRITE (CHR(28)); { SET CURSOR TO 0,0 - CLEAR SCREEN } { YOU COULD SET A NEW VIEWPORT HERE } GOTOXY (0,5); WRITELN ('THIS IS SOME SAMPLE TEXT THAT WILL BE'); WRITELN ('RETRIEVED USING .CONSENTS OF THE CUR- RENTLY DEFINED VIEWPORT. -------------------------------------------------------------------- PROGRAM GET_ENTIRE_SCREEN; TYPE SCREEN_ARRAY = PACKED ARRAY [1..1923] OF CHAR; { 80 * 24 + 3 } VAR SCREEN : SCREEN_ARRAY; { STATUS LIST V INVOLVE A RATHER COMPLEX PASCAL PROCEDURE, OR A SOMEWHAT LENGTHY ASSEMBLER ROUTINE. EITHER WAY, IT'S GOING TO BE INEFFICIENT. ==================================================================== FIGURE 5: A SMALL PASCAL PROGRAM THAT RETRIEVES THE CONT THEREFORE YOU CANNOT RETRIEVE ONLY ONE LINE. SECOND (AND MOST IMPORTANT), THE CONTENTS RETURNED ARE IDENTICAL TO THE MEMORY MAP. YOU WOULD HAVE TO INTERPRET (ACCORDING TO THE TABLE GIVEN IN FIGURE 1) ALL ACTUAL "X" AND "Y" LOCATIONS. THIS WOULD CAN BE COMPUTED BY TAKING THE NUMBER OF ROWS TIMES THE NUMBER OF COLUMNS AND ADDING THREE (I.E. 1923 = 24 * 80 + 3). WHILE THIS METHOD IS FAST AND EFFICIENT, IT HAS TWO DRAWBACKS: FIRST, YOU CANNOT DEFINE A VIEWPORT THAT CONSISTS OF ONLY ONE LINE, AD CHANGED THE VIEWPORT COORDINATES BEFORE MAKING THIS STATUS CALL, YOU WOULD ONLY RECEIVE THE CONTENTS WITHIN THAT VIEWPORT. THE "STATUS LIST" VALUE MUST BE LARGE ENOUGH TO HOLD ALL OF THE SCREEN DATA (TEXT AND COLOR INFORMATION). THISSCAL PROGRAM THAT RETURNS THE CONTENTS OF THE CURRENT VIEWPORT. AGAIN, NOTE THE "UNITSTATUS" METHOD OF MAKING THE CALL. YOU SHOULD ALSO BE AWARE THAT THIS CALL WILL RETURN THE CONTENTS OF THE VIEWPORT YOU CURRENTLY HAVE DEFINED. IF YOU H=========================================================== METHOD 2 IS .CONSOLE STATUS CALL 18: 'PRESERVE CONTENTS OF VIEWPORT'. THIS CALL WILL RETURN THE ENTIRE CONTENTS OF THE VIEWPORT TO THE "STATUS LIST" VALUE. FIGURE 5 LISTS A SMALL PA UNITSTATUS (1,C,68); { NOTE USE OF UNITSTATUS } GOTOXY (0,3); { SHOW CHARACTER } WRITE (CHR(30)); { CLEAR THE LINE } WRITELN ('CHARACTER RETURNED IS "',C,'"'); END; UNTIL (X = 80) AND (Y = 24); END. =========D Y COORDINATES } WRITE (CHR(30)); { CLEAR THE LINE } WRITE ('INPUT "X" AND "Y" COORDINATES (80,24 TO END) ? '); READLN (X,Y); IF (X IN [0..79]) AND (Y IN [0..23]) THEN BEGIN GOTOXY (X,Y); { GOTO POSITION ENTERED } CAN EXPERIMENT'); WRITELN ('RETRIEVING CHARACTERS FROM WITH THE USE OF'); WRITELN ('.CONSOLE STATUS CALL 17. IT STARTS IN'); WRITELN ('COLUMN 0 ON ROW 5 (REMEMBER, 0 RELATIVE'); WRITELN ('ADDRESSING).'); REPEAT GOTOXY (0,2); { GET X AN-------------------------------------------------------- PROGRAM GET_SCREEN_ASCII; VAR X,Y : INTEGER; C : CHAR; BEGIN { GET_SCREEN_ASCII } WRITE (CHR(28)); { SET CURSOR TO 0,0 - CLEAR SCREEN } GOTOXY (0,5); WRITELN ('THIS IS A FIELD THAT YOUR, EACH STATUS CALL 17 RETURNS ONLY ONE BYTE AT A TIME). ==================================================================== FIGURE 4: A SMALL PASCAL PROGRAM THAT RETRIEVES THE ASCII VALUE OF THE CHARACTER AT THE CURRENT CURSOR POSITION. ------------ FEW BYTES OFF THE SCREEN, HOWEVER, IF YOU NEED TO GET 10 CHARACTERS OR MORE THE INDIVIDUAL CALLS WILL SLOW DOWN PROGRAM EXECUTION AND THE PROGRAMMING BECOMES SOMEWHAT INEFFICIENT SINCE YOU'LL BE DEALING WITH PASCAL LOOPS WHICH ARE VERY SLOW (REMEMBEOLE STATUS CALL 18.'); WRITELN ('IT STARTS IN COLUMN 0 ON ROW 5 (REMEMBER,'); WRITELN ('0 RELATIVE ADDRESSING).'); UNITSTATUS (1,SCREEN,72); { NOTE USE OF UNITSTATUS } GOTOXY (0,0); { ALL DONE } WRITELN ('ENTIRE SCREEN RETRIEVED. PRESS TO CONTINUE'); READLN; WRITELN ('DUMP FOLLOWS:'); { SHOW A DUMP } FOR I := 1 TO 1923 DO IF ORD(SCREEN[I]) IN [33..127,161..255] THEN WRITE (SCREEN[I]) { WRITE ALL PRINTABLE CHARS. } ELSE IF ORD(SCREEN[I]) IN [32,160] THENSUE: 03 DAY: MONTH: Mar/Apr YEAR: 1986 PG(S): 37 File: PAIR.BIB Page 21 Report: SUBJECTS SUBJECT: Pascal DBMS TITLE: Swan's PDBM and the /// MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Cohen VOL: 2 TLE: PASCAL 1.2 Errata MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 09 DAY: 1 MONTH: March YEAR: 1985 PG(S): 1 SUBJECT: Pascal 1.2 TITLE: PASCAL 1.2 MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Cohen VOL: 2 IS: 25 DAY: 14 MONTH: June YEAR: 1985 PG(S): 2 SUBJECT: PASCAL TITLE: The General I/O Unit MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Cisar VOL: 2 ISSUE: 10 DAY: MONTH: Nov/Dec YEAR: 1986 PG(S): 18-26 SUBJECT: PASCAL 1.2 TIe MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 32 DAY: 2 MONTH: August YEAR: 1985 PG(S): 1-2 SUBJECT: PASCAL TITLE: Loading/Executing PASCAL Files MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE Page 20 Report: SUBJECTS SUBJECT: PASCAL TITLE: PASCAL Notes MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 33 DAY: 9 MONTH: August YEAR: 1985 PG(S): 2 SUBJECT: PASCAL TITLE: PASCAL 1.2 Not ISSUE: 01 DAY: MONTH: January YEAR: 1986 PG(S): 8 SUBJECT: Networks TITLE: Network Systems MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 31 DAY: 26 MONTH: July YEAR: 1985 PG(S): 2 File: PAIR.BIB rs MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 36 DAY: 30 MONTH: August YEAR: 1985 PG(S): 1 SUBJECT: Networking TITLE: Corvus Constellation II and Catalyst MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Betz VOL: 2 ge 19 Report: SUBJECTS SUBJECT: Menu Program TITLE: For the Hacker MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Rasmussen VOL: 1 ISSUE: 02 DAY: MONTH: October YEAR: 1985 PG(S): 13-14 SUBJECT: Metamorphosis TITLE: Last of the Newslette BIBLIOGRAPHY OF THE /// NEWSLETTER AND /// MAGAZINE PART 2 REPRINTS AVAILABLE FROM: /// CHEERS PRESS #300 11160 Viers Mill Road, L-15 Wheaton, MD. 20902 (301)-681-6136 Write or call for Details! File: PAIR.BIB Paputing! KNOW IT EXISTED OR COULD BE DONE. GOOD LUCK AND GOOD COMPUTING! scal or Basic and should help you in designing more effecient programs. I hope this procedure and information helps those of you out there that have wanted (or needed) this capability but did not know it existed or could be done. Good luck and good com WRITE ('.') { IF IT'S A SPACE SUBSTITUE A PERIOD } ELSE WRITE ('?'); { OTHERWISE UNRECOGNIZABLE } END. ==================================================================== The "GET_SCREEN_STRING" procedure will work in either Pa ISSUE: 03 DAY: MONTH: Mar/Apr YEAR: 1986 PG(S): 13-15 SUBJECT: PASCAL Tutorial 0A TITLE: On Learning PASCAL MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Hanson VOL: 2 ISSUE: 04 DAY: MONTH: May YEAR: 1986 PG(S): 7-8 SUBJECT: Power Keys TITLE: Latest in Power Keys MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 09 DAY: MONTH: October YEAR: 1986 PG(S): 7 SUBJECT: Pressure TITLE: Write to Apple Time MAGAZINE/NEWSLETTER: The /// Newslett85 PG(S): 9-10 SUBJECT: Review TITLE: The Art of Negotiating MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 1 ISSUE: 02 DAY: MONTH: October YEAR: 1985 PG(S): 7-8 SUBJECT: Review TITLE: Let's Talk MAGAZINE/NEWSLETTER: The /// M The /// Magazine AUTHOR: Moore VOL: 1 ISSUE: 02 DAY: MONTH: October YEAR: 1985 PG(S): 11-12 SUBJECT: Review TITLE: Post Master MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 1 ISSUE: 02 DAY: MONTH: October YEAR: 19EAR: 1985 PG(S): 7-9 SUBJECT: Review TITLE: Password /// MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Gooding VOL: 1 ISSUE: 04 DAY: MONTH: December YEAR: 1985 PG(S): 10-11 SUBJECT: Review TITLE: Hooked on Power Keys MAGAZINE/NEWSLETTER:ry YEAR: 1985 PG(S): 2 File: PAIR.BIB Page 24 Report: SUBJECTS SUBJECT: Review TITLE: Keystone Accounting MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Wade VOL: 1 ISSUE: 04 DAY: MONTH: December YTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 24 DAY: 8 MONTH: June YEAR: 1985 PG(S): 2 SUBJECT: Ramdisks TITLE: A Note on Ramdisks MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Anderson VOL: ISSUE: 08 DAY: 22 MONTH: FebruaSUBJECT: Quick File TITLE: Quick File Revisited MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Lomartire VOL: 2 ISSUE: 08 DAY: MONTH: Aug/Sep YEAR: 1986 PG(S): 11 SUBJECT: Ram Errors TITLE: The /// On Lamp and Ram Errors MAGAZINE/NEWSLETL: ISSUE: 07 DAY: 15 MONTH: February YEAR: 1985 PG(S): 2 SUBJECT: Public Domain TITLE: Public Domain Library List MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 05 DAY: 30 MONTH: January YEAR: 1985 PG(S): 1-2 15 MONTH: March YEAR: 1985 PG(S): 2 File: PAIR.BIB Page 23 Report: SUBJECTS SUBJECT: Public Domain TITLE: Additions to the Public Domain Library MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOhe /// Newsletter AUTHOR: Moore VOL: ISSUE: 23 DAY: 1 MONTH: June YEAR: 1985 PG(S): 1-2 SUBJECT: Public Domain TITLE: Additions to the Public Domain Library MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 11 DAY:1985 PG(S): 19 SUBJECT: Public Domain TITLE: New Packages MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 28 DAY: 5 MONTH: July YEAR: 1985 PG(S): 3-4 SUBJECT: Public Domain TITLE: New Packages MAGAZINE/NEWSLETTER: TMoore VOL: 2 ISSUE: 07 DAY: MONTH: July YEAR: 1986 PG(S): 16-17 SUBJECT: Public Domain TITLE: Public Domain Software Available MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 1 ISSUE: 03 DAY: MONTH: November YEAR: roducts TITLE: New Products MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 33 DAY: 9 MONTH: August YEAR: 1985 PG(S): 1-2 SUBJECT: Program TITLE: Mandelbrot 'ala Pascal MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: UBJECT: Products TITLE: New Products MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 34 DAY: 16 MONTH: August YEAR: 1985 PG(S): 1-2 File: PAIR.BIB Page 22 Report: SUBJECTS SUBJECT: Per AUTHOR: Moore VOL: ISSUE: 25 DAY: 14 MONTH: June YEAR: 1985 PG(S): 2 SUBJECT: Problems TITLE: Quick Notes MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 29 DAY: 12 MONTH: July YEAR: 1985 PG(S): 2 Sagazine AUTHOR: Moore VOL: 1 ISSUE: 01 DAY: MONTH: September YEAR: 1985 PG(S): 8 File: PAIR.BIB Page 25 Report: SUBJECTS SUBJECT: Review TITLE: Metapath's DDS-5 Switch MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 1 ISSUE: 01 DAY: MONTH: September YEAR: 1985 PG(S): 12-13 SUBJECT: Review TITLE: Power Keys MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Anderson VOL: ISSUE: 36 DAY: 30 MONTH: August YEAR: 1985 PG(S): 1- PAIR.BIB Page 29 Report: SUBJECTS SUBJECT: Review TITLE: Selector /// Notes and Thoughts MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Norris VOL: ISSUE: 13 DAY: 29 MONTH: March YEAR: 1985 PG(S): 2 Moore VOL: ISSUE: 15 DAY: 12 MONTH: April YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: Calendar Pak /// MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Baker VOL: ISSUE: 14 DAY: 5 MONTH: April YEAR: 1985 PG(S): 1-2 File: UBJECT: Review TITLE: Tool Times Three MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 16 DAY: 19 MONTH: April YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: Attach.Driver MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR:ter AUTHOR: Moore VOL: ISSUE: 18 DAY: 3 MONTH: May YEAR: 1985 PG(S): 2 SUBJECT: Review TITLE: Think Tank MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Baker VOL: ISSUE: 17 DAY: 25 MONTH: April YEAR: 1985 PG(S): 1-2 S 28 Report: SUBJECTS SUBJECT: Review TITLE: Aladin MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 18 DAY: 3 MONTH: May YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: Data Base /// MAGAZINE/NEWSLETTER: The /// Newslet YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: Back-It-Up /// MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Corbin VOL: ISSUE: 19 DAY: 10 MONTH: May YEAR: 1985 PG(S): 2 File: PAIR.BIB Page May YEAR: 1985 PG(S): 1 File: PAIR.BIB Page 27 Report: SUBJECTS SUBJECT: Review TITLE: The Legend 'S' Card MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Anderson VOL: ISSUE: 20 DAY: 17 MONTH: May ER: The /// Newsletter AUTHOR: Anderson VOL: ISSUE: 22 DAY: 31 MONTH: May YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: Corvus Constellation II Update MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 21 DAY: 24 MONTH:G(S): 1-2 SUBJECT: Review TITLE: Catalyst 2.1 MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 25 DAY: 14 MONTH: June YEAR: 1985 PG(S): 1 SUBJECT: Review TITLE: The Personal Computer Products Applicard MAGAZINE/NEWSLETTNewsletter AUTHOR: Moore VOL: ISSUE: 27 DAY: 28 MONTH: June YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: MS-DOS for the /// MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 26 DAY: 21 MONTH: June YEAR: 1985 PCTS SUBJECT: Review TITLE: Infax Disk System MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Anderson VOL: ISSUE: 28 DAY: 5 MONTH: July YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: The BPI Accounting System MAGAZINE/NEWSLETTER: The /// YEAR: 1985 PG(S): 2 SUBJECT: Review TITLE: /// Pack MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 30 DAY: 19 MONTH: July YEAR: 1985 PG(S): 1-2 File: PAIR.BIB Page 26 Report: SUBJENewsletter AUTHOR: Fortune VOL: ISSUE: 35 DAY: 23 MONTH: August YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: Essential Data Duplicator MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Anderson VOL: ISSUE: 34 DAY: 16 MONTH: August 2 SUBJECT: Review TITLE: Hallock Systems Company MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Anderson VOL: ISSUE: 35 DAY: 23 MONTH: August YEAR: 1985 PG(S): 2 SUBJECT: Review TITLE: Stock Portfolio System MAGAZINE/NEWSLETTER: The /// SUBJECT: Review TITLE: Basic Extension MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 12 DAY: 22 MONTH: March YEAR: 1985 PG(S): 2 SUBJECT: Review TITLE: Ink Well MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 12 DAY: 22 MONTH: March YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: Omni-Reader MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 11 DAY: 15 MONTH: March YEAR: 1985 PG(S): 1-2 SUBJECT: Review ne AUTHOR: Bloom VOL: 2 ISSUE: 08 DAY: MONTH: Aug/Sep YEAR: 1986 PG(S): 34-37 File: PAIR.BIB Page 33 Report: SUBJECTS SUBJECT: Review TITLE: RPS MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Betz VOReview TITLE: Desktop Manager vs. Power Keys MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Johnson VOL: 2 ISSUE: 08 DAY: MONTH: Aug/Sep YEAR: 1986 PG(S): 24-32 SUBJECT: Review TITLE: PC-Disk and PC-Copy MAGAZINE/NEWSLETTER: The /// Magazire VOL: 2 ISSUE: 07 DAY: MONTH: July YEAR: 1986 PG(S): 18-20 SUBJECT: Review TITLE: Reformatter /// MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Bloom VOL: 2 ISSUE: 08 DAY: MONTH: Aug/Sep YEAR: 1986 PG(S): 15-18 SUBJECT: BJECT: Review TITLE: Textgraphics MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 07 DAY: MONTH: July YEAR: 1986 PG(S): 8 SUBJECT: Review TITLE: The Graphics Manager MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: MooPG(S): 7 File: PAIR.BIB Page 32 Report: SUBJECTS SUBJECT: Review TITLE: Draw On /// MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 07 DAY: MONTH: July YEAR: 1986 PG(S): 9-10 SUhe /// Magazine AUTHOR: Johnson VOL: 2 ISSUE: 06 DAY: MONTH: June YEAR: 1986 PG(S): 11-18 SUBJECT: Review TITLE: Omnis 3 MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Reilly VOL: 2 ISSUE: 06 DAY: MONTH: June YEAR: 1986 1986 PG(S): 16 SUBJECT: Review TITLE: Power Keys 2.0 MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 04 DAY: MONTH: May YEAR: 1986 PG(S): 9-11 SUBJECT: Review TITLE: Catalyst Vs. Selector /// MAGAZINE/NEWSLETTER: Te /// Magazine AUTHOR: Wade VOL: 2 ISSUE: 03 DAY: MONTH: Mar/Apr YEAR: 1986 PG(S): 12 SUBJECT: Review TITLE: MacStuff for the /// MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 04 DAY: MONTH: May YEAR: Page 31 Report: SUBJECTS SUBJECT: Review TITLE: Titan ///+//e MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 02 DAY: MONTH: February YEAR: 1986 PG(S): 10-12 SUBJECT: Review TITLE: GL-Plus MAGAZINE/NEWSLETTER: Th 22 MONTH: January YEAR: 1985 PG(S): 1 SUBJECT: Review TITLE: ADC Modem MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Corbin VOL: 2 ISSUE: 02 DAY: MONTH: February YEAR: 1986 PG(S): 13 File: PAIR.BIB Cap'N Magneto MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 06 DAY: 6 MONTH: February YEAR: 1985 PG(S): 2 SUBJECT: Review TITLE: 3 EZ Pieces MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 04 DAY:1 MONTH: March YEAR: 1985 PG(S): 2 SUBJECT: Review TITLE: Titan Technologies ///+][ Card MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Anderson VOL: ISSUE: 08 DAY: 22 MONTH: February YEAR: 1985 PG(S): 1 SUBJECT: Review TITLE: : 8 MONTH: March YEAR: 1985 PG(S): 1 File: PAIR.BIB Page 30 Report: SUBJECTS SUBJECT: Review TITLE: Corvus Constellation II MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 09 DAY: TITLE: Basic GTO MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 10 DAY: 8 MONTH: March YEAR: 1985 PG(S): 1-2 SUBJECT: Review TITLE: SOSTran MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 10 DAYL: 2 ISSUE: 8 DAY: MONTH: Aug/Sep YEAR: 1986 PG(S): 49-51 SUBJECT: Review TITLE: Smarttax MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 10 DAY: MONTH: Nov/Dec YEAR: 1986 PG(S): 42-43 SUBJECT: Review TITLE: Access 3270 MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Baker VOL: 3 ISSUE: 2 DAY: MONTH: February YEAR: 1987 PG(S): 20-23 SUBJECT: Review TITLE: Basic GTO MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 3 ISSUE: 2 DAY: 1-2 SUBJECT: Titan /// + ][ TITLE: /// Hardware News MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: DAY: 10 MONTH: December YEAR: 1984 PG(S): 2 SUBJECT: Tutorial TITLE: Installing the Clock Chip MAGAZINE/NEWSLETTER: Th: ISSUE: 09 DAY: 1 MONTH: March YEAR: 1985 PG(S): 2 SUBJECT: The /// Newsletter TITLE: The End of the /// Newsletter MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 29 DAY: 12 MONTH: July YEAR: 1985 PG(S):smission via Modem MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 11 DAY: 15 MONTH: March YEAR: 1985 PG(S): 1 SUBJECT: The /// Magazine TITLE: The /// Magazine MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOLGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 13 DAY: 29 MONTH: March YEAR: 1985 PG(S): 1-2 File: PAIR.BIB Page 36 Report: SUBJECTS SUBJECT: Telecommunications TITLE: 9600 Baud Tran YEAR: 1985 PG(S): 2 SUBJECT: Telecommunications TITLE: More BBS'S MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 15 DAY: 12 MONTH: April YEAR: 1985 PG(S): 1 SUBJECT: Telecommunications TITLE: BBS Updates MANEWSLETTER: The /// Magazine AUTHOR: Rasmussen VOL: 2 ISSUE: 03 DAY: MONTH: Mar/Apr YEAR: 1986 PG(S): 40-44 SUBJECT: Sun Data TITLE: Sun Data MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 29 DAY: 12 MONTH: July986 PG(S): 20 SUBJECT: Software M05 TITLE: New Pair Software Additions MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 10 DAY: MONTH: Nov/Dec YEAR: 1986 PG(S): 36 SUBJECT: SOS TITLE: SOS Directory Structure MAGAZINE/: 45 File: PAIR.BIB Page 35 Report: SUBJECTS SUBJECT: Software M04 TITLE: New Pair Software Additions MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 09 DAY: MONTH: October YEAR: 1oore VOL: 2 ISSUE: 03 DAY: MONTH: Mar/Apr YEAR: 1986 PG(S): 45 SUBJECT: Software M03 TITLE: New Pair Software Additions MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 08 DAY: MONTH: Aug/Sep YEAR: 1986 PG(S)c Domain Additions MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 02 DAY: MONTH: February YEAR: 1986 PG(S): 21 SUBJECT: Software M02 TITLE: New Pair Software Additions MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: MONTH: January YEAR: 1985 PG(S): 2 SUBJECT: Slot Switcher TITLE: The SCRG Box MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Anderson VOL: 2 ISSUE: 03 DAY: MONTH: Mar/Apr YEAR: 1986 PG(S): 11 SUBJECT: Software M01 TITLE: New Publir Color T.V. MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 04 DAY: 22 MONTH: January YEAR: 1985 PG(S): 2 SUBJECT: Rumors TITLE: Rumors MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 01 DAY: 2 MZINE/NEWSLETTER: The /// Magazine AUTHOR: Short VOL: 3 ISSUE: 1 DAY: MONTH: January YEAR: 1987 PG(S): 20-24 File: PAIR.BIB Page 34 Report: SUBJECTS SUBJECT: RF Modulators TITLE: Hooking the /// to You MONTH: February YEAR: 1987 PG(S): 24-29 SUBJECT: Review TITLE: C.C.C. Cooling System MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Blythe VOL: 3 ISSUE: 2 DAY: MONTH: February YEAR: 1987 PG(S): 9 SUBJECT: Review TITLE: Go Forth MAGAe /// Magazine AUTHOR: Moore VOL: 3 ISSUE: 1 DAY: MONTH: January YEAR: 1987 PG(S): 19 SUBJECT: Unification TITLE: The Grand Unification Project MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 32 DAY: 2 MONTH: August YEAR: 1985 PG(S): 1 File: PAIR.BIB Page 37 Report: SUBJECTS SUBJECT: Upgrades TITLE: Microprocessor Upgrading in the /// MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VOL: ISSUE: 11 DAY: 1")2070H540R\A$="RUNNING "+B$(I),16,B)f"79C";A$;:=0pB$(I),16,B) z::SEG=1".D1/SEG.T"t=+B$(I),16,B) yCT=CT+1~240:=24:=0:"@ ..... "DATE.TIME.LINE" ....JM=Ҡ,4,2))BTM1630,1640,1650,166=+IBOTM/2-.5):I=IBOTM:I/2=I/2)I=I-1 œ2120B=B$(I),16)," ")-1 B$(I),"BASIC 0")850B$(I),"TEXT 0")890 B$(I),"CAT 0")1140*B$(I),"FONT 0")18504B$(I),"FOTO 0")1930>B$(I),"PASTXT 0I);v:520: 500THPOS=4:I/2=I/2)I=I-1I=IBOTM THPOS=44:I/2<>I/2)I=I+1I2=-1:I=I-2:IBOTM<30THPOS=44I=IBOTM/2)*2:=+IBOTM/2)-1:0"PRINT.ALL": OA+P 3HA=(81+UCA)A=(81+LCA):::: OA+Q Quits 3IA=(83+LCA)A=(83+UCA)"PRINT.SHOW": OA+S 2JA=(68+LCA)A=(68+UCA)/Screen.Savers/HELLON=THPOS:B$(I);XA<8A>11540bA-7640,660,690,720l:=THPOS:B$(00 =Q:WW=0A=:A=21A=9&oldprefix$=40A=31410: Control C "aborts" program to Basic(:A=13770: Return Selects a file *DA=27:50: Escape to change disks/FA=324000: back out one directory level 3GA=(80+UCA)A=(80+LCA)SIC 0":150A$="TEXT 0":150A$="CAT 0":150A$="FONT 0":150A$="FOTO 0":150A$(L),"BLOCKS")510*=27:=19:"FREE MEMORY AVAILABLE: ";=7:=20:"80C";A$(L);$:=5:THPOS=4:I=1:IBOTM=J-1:620Q=:=26:=21:16; +Q Quits."r12);::"80C";a$;:+w#9,"DISKNAME.DAT":#9;DISKNAME$:#9|d$=DISKNAME$$=23:=0::"80C";d$;::12)201M=3:=14:"This /// SIG Disk is \^ 19";Р,2)", Washington Apple `, Ltd."=4:B$(1)="":B$(2)=""A$="BA16,B) THEN 240 #1, d$="":=10:"80C";d$ ž#1300I=0"I=I+1:#1;A$(I):290,#1 6L=I-1@j=1:same=0 J:SEG=0 Tœ2030^CT<1CT=1:CT>13000Zha$="{,|,~,}; selects; to new disk; J/2)=4:=+1:ۙ=44B$(J);:J=J+1I:1,180,22:2,280,21:2,2380,23:8A$(1000),B$(1000),C%(511),C$(20),name$(20):=10:=0UCA=128:LCA=UCA+32CT=15 IF PREFIX$= PREFIX$+MID$(B$(I),VOLUME NAME (/DISKNAME) OR DEVICE NAME (.Dx)"P12);::"80C";a$;:Zb$="CHANGING DISKS"$d=23:=0::"80C";b$;::12).n=12:=20:"MAKE A NEW MENU FOR DISK: ";N$xN$)<2110=N$ :210 I=1L(A$(I),A$))200B$0 WAP /// SIG MENU.MAKER PROGRAM (v. 6.2) =".D1"210: Coldstart (320: Warmstart &*X=11000: TEXT SLOW-DOWN LOOP ,X.1 CHANGE DISK SUBROUTINE23œ202:2200<RFa$=" YOU MAY SELECT YOUR DISK BY 5 MONTH: March YEAR: 1985 PG(S): 1 SUBJECT: User Groups TITLE: Bits and Pieces MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 1 ISSUE: 04 DAY: MONTH: December YEAR: 1985 PG(S): 12-14 SUBJECT: Versaform TITLE: Versafo0,1670,1680,1690,1700,1710,1720,1730,1740^M$="JANUARY":1750hM$="FEBRUARY":1750rM$="MARCH":1750|M$="APRIL":1750M$="MAY":1750M$="JUNE":1750M$="JULY":1750M$="AUGUST":1750M$="SEPTEMBER":1750M$="OCTOBER":1750M$="NOVEMBER":1750M$="DECEMBER":1750826);"-";M$;" ";Ѡ,2));", ";"19";Р,2);" ";/П,2))=>13П,2))-12;џ,6);:1780$П,2))=0"12";џ,6);:ٟ;$П,2))=>12" PM-":" AM-" 1830WW=1530 =26:=21 oring assembly language and how to use it to do different things on the ///. A Bibliography of Pair's /// Newsletter and /// Magazine is included. On Side One: BIB.ASCI.PT1 :Bibliography of Pair publications (ASCII) CISARS.ARTICLES :Discusses John WAP /// SIG PD LIBRARY PDS NAME: Best Of Pair Software DISK ID#: 3INF-16 The Best of Pair Software includes programs downloaded from the company's BBS that operated for a time (we wish we'd downloaded more!). This disk includes a number of articles explS): 35-36 OL: ISSUE: 01 DAY: 2 MONTH: January YEAR: 1985 PG(S): 2 SUBJECT: Write Protection TITLE: A Write Protection On/Off Switch MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Moore VOL: 2 ISSUE: 03 DAY: MONTH: Mar/Apr YEAR: 1986 PG(rm and Power Keys MAGAZINE/NEWSLETTER: The /// Magazine AUTHOR: Bridges VOL: 2 ISSUE: 10 DAY: MONTH: Nov/Dec YEAR: 1986 PG(S): 16-17 SUBJECT: Word Juggler TITLE: /// Software News MAGAZINE/NEWSLETTER: The /// Newsletter AUTHOR: Moore VTHE BEST OF PAIR SOFTWARE BBS a$,1)="/"5060:s=s-1 5030=a$240 MENU.MAKER 6.2 * Thanks to C.M.Davidson for his help! G$:::320H: Error Routine 202:U=11:"79C";"BAD PATH ERROR (NO DISK IN DISK DRIVE OR DESIRED FILE NOT FOUND.)"X=11000:X:::210Z a$="{,|,~,}; selects; back 1 level;1600 &:WW=1:0 :SEG=1;".D1/S EG.F" SEG=1".D1/SEG.G"diskname$=3802  CATCH PASCAL TEXT FILES 202 :F*=08:"78C";"SORRY BUT MENU.MAKER CAN'T READ PASCAL TEXT FILES."04=10:"78CCisar's articles on Side Two. PAIR.BIB :3EZ Pieces bibliography of Pair publications. -: On Side Two: BIB.ASCII.PT2 : Part 2 of ASCII version of Pair bibliography. CISAR.1 :The Pull Down Menu Unit. CISAR.2 :How to get flashingequired transistors -- 2n3906 pnp's and 2n3904 npn's -- for the circuits were available at my nearby Radio Shack store for only $2.00 for 10!). Since my TV circuit required the synch to be hooked up separately from the xRGB ones I simply took the syncor, I connected various higher resistance values across the 2.2k ones until I got a reasonable match for most of the colors. Since I had to use values to those commonly available at any nearby Radio Shack store, some compromises were made (the r xRGB4, xRGB8 yellow xRGB1, xRGB4, xRGB8 aqua xRGB2, xRGB4, xRGB8 white all xRGB inputs Armed with this knowledge, I started to make a simple mixing network consisting of 2.2k ohm resistors. Then, by trial and errk blue xRGB2 lavender xRGB1, xRGB2 dark green xRGB4 gray #1 xRGB1, xRGB4 blue xRGB2, xRGB4 light blue xRGB1, xRGB2, xRGB4 brown xRGB8 orange xRGB1, xRGB8 gray #2 xRGB2, xRGB8 pink xRGB1, xRGB2, xRGB8 green hart consists of four horizontal stripes and four vertical stripes. By a superposition of these stripes the various colors come out. Here is a list of the standard colors and the xRGB inputs used to make them: black none magenta xRGB1 dar xRGB Apple /// outputs (after passing through the proper transistor matching circuits) one at a time to a single color input. Then, by looking at the standard 16 color chart, I was able to decode the meaning of the xRGB outputs. The standard color cwith my newly purchased RGB TV set, it did not produce the standard Apple color set. When I ran the Apple /// demo diskette, the one with the colored horses, the results were bizarre! So, I went back to square one and started hooking up the fourseparate monitor was spoken for. Besides, the Apple /// at our house is for business only and games are not allowed. They couldn't understand what I wanted color for anyway. Well, when I dutifully assembled the Apple conversion circuit and tried it em while the sensible solution, of course, would be a purchase of an xRGB compatiable monitor dedicated to the computer {ed.note- these are almost impossible to find now }, my wife and daughters wanted a video recorder, and so the money for a t my purchase would only be made if the set had RGB outputs in addition to the standard ntsc ones. Since the apple /// owner's manual had a neat coversion circuit printed in it (on page 135 - Appendix c), I figured that setup would be no probl NEW RGB CIRCUIT FOR THE /// CREATED BY PAIR SOFTWARE 0/31/1988 10:46:06 GETTING A HORSE OF A DIFFERENT COLOR by D.D. Meisel Recently faced with the prospect of having to buy a new color TV set for the family, I steadfastly insisted at the store tha characters and upload characters into your programs. CISAR.3 :The Cisar Prompt Procedure. RGB : A new RGB circuit for the Apple ///. h output from the two npn transistors shown in the circuit and hooked it up directly to the RGB synch input on my TV set. My final resistance network is shown in the diagram below. It is to be connected between the transistor xRGB outputs shown in the Apple /// owner's manual circuit and the transistor RGB inputs on the same diagram. While the color match is not absolutely exact, and you might have to jack up the RGB monitor's brightness a bit to see them all, it does give the 16 dis 79C";"PRESS ANY KEY TO HALT LISTING"::202 1020#2,B$(I),16,B)ž#242:::1160Z=1#2;A$:"78A";A$Z=Z+1:Z>1842:::Z=1980*:=23:=0::"79C";"CONTINUE...?":1C$:C$<>"Y"C$<>"y"C$<>"N"C$<>"n"10 MENU.MAKER TEXT MODULESEG=0"MENU.MAKER"890&*X=11000: TEXT SLOW-DOWN LOOP ,X.1,180,22:2,280,21:2,2380,23:z:A$="LISTING "+B$(I),16,B)$=01:=0::"80C";A$;::12)>=23:=0::"problem of compatibility with the newer systems. } ________| |___/\/\/\/\___| 4.7K SYNCH O____________________________________________________O SYNCH { ED. Note: For the modern RGB standards, this circuit seems to be superior to the Apple /// example. It also solves the 8 O______________________/\/\/\/\__________| | | |__/\/\/\/\___/\/\/\/\__| | | 4.7K 1K | | 2.2K | |___/\/\/\/\_________________________________________>___________O G |_/\/\/\/\___| | | 6.8K | | | | 2.2K | | XRGB___| | 15K | TRANSISTOR | 2.2K | INPUTS XRGB4 O___/\/\/\/\_________|__>____________________O R 4.7K 1K | | | | 2.2K | | XRGB2 O___/\/\/\/\____________________|________>___________O B |_/\/\/\/\ ___/\/\/\/\____ | V 1K 1K XRGB1 O____/\/\/\/\______/\/\/\/\_____ | | | 2.2K | |__/\/\/\/\________________ | |__/\/\/\/\______/\/\/\/\__ WIRES WIRES NOT EXAMPLES: __|__ CONNECTED | CONNECTED RESISTOR | ___>___ | TRANSISTOR OUTPUTS | re experimentation would have produced results closer to the Apple ones, but I have not taken the time to do this. Anyway, I prefer the colors I have. In any event, this network is a good starting point if you want to mix your own set. Have fun! tinct colors which are very close to the standard ones (I think they are better!). besides, my solution is cheap- about $20.00! In the final test of these colors I ran the infamous demo horse sequence and got back quite a show!! Now I am sure mo30C$="N"C$="n"1160;:=23:=0::"79C";"PRESS ANY KEY TO HALT LISTING": $1020.202 8::Z=1B::=23:=0::"79C";"WOULD YOU LIKE A PRINTED COPY?":1C$:C$<>"Y"C$<>"y"C$<>"N"C$<>"n"1170*C$="N"C$="n"EAD PASCAL TEXT FILES."04=10:"78C";"ANY KEY RETURNS TO THE MENU."!>G$:::".D1/MENU.MAKER",320R",220(204::"79A";""; 2D=1:F=1 <#4;a$ FD=D+1 P#5;a$ZD=60#5;12)dD=60D=1nF=F+1::d$;::Y=1100:Y x13402  CATCH PASCAL TEXT FILES 202 :F*=08:"78C";"SORRY BUT MENU.MAKER CAN'T R".D1/MENU.MAKER",220 d$="" A$="PRINTING "+B$(I),16,B)=01:=0::"80C";A$;:#3,B$(I),16,B)Z=1#3;b$:"78A";b$Z=Z+1:Z=18:1290 1260 #4,B$(I),16,B)#5,".PRINTER"+ž#4#5;12):::".D1/MENU.MAKE