1 ;;****************************************************************************
2 ;; Assembler MACROS for use with SELECT.
4 ;; Latest Change Date: July 28, 1987
6 ;; These macros define powerful assembler verbs neccessary for SELECT.
8 ;; Note: Many of the macros make use of an ASCII-N string for passing
9 ;; parameters. The string is defined below.
11 ;; DB "string_variable",?
13 ;; COUNT is the length of the string and is a word.
14 ;; It is necessary to follow the string with at least one byte for the
15 ;; purpose of changing the ASCII-N string to an ASCII-Z string.
17 ;;****************************************************************************
19 ;;************************************************************************;;
21 ;; GET_COUNTRY_DEFAULTS: Get country, keyboard and codepage for the
22 ;; specified entry from the CTY_TABLE.
24 ;; SYNTAX: GET_COUNTRY_DEFAULTS VAR_TABLE, VAR_INDEX
27 ;; VAR_TABLE = 1: Use CTY_TAB_A
29 ;; VAR_INDEX = index into country list table
32 ;; N_COUNTRY = Country code
33 ;; N_KYBD_VAL = 0: Keyboard code is not valid
34 ;; = 1: Keyboard code is valid
35 ;; S_KEYBOARD = Keyboard code (ASCII-N format)
36 ;; N_CP_PRI = Primary code page
37 ;; N_CP_SEC = Secondary code page
38 ;; N_DESIGNATES = Number of disignates
39 ;; N_CPSW = Cpsw status
40 ;; N_CTY_RES = Reserved
43 ;; OPERATION: The country code, keyboard, primary codepage and the
44 ;; seondary codepage from the CTY_TABLE for the specified index is
45 ;; returned as spedified above.
47 ;; Note: Index of the first item is the table is 1.
49 ;;****************************************************************************
50 GET_COUNTRY_DEFAULTS MACRO VAR_TABLE, VAR_INDEX ;;AN000;
52 MOV BX, VAR_TABLE ;;AN000; Get which table to search
53 MOV AX, VAR_INDEX ;;AN000; Get where to start in the table
54 CALL GET_CNTY_DEF_ROUTINE ;;AN000;
57 ;;************************************************************************;;
59 ;; GET_DOS_COUNTRY: Get current country information.
61 ;; SYNTAX: GET_DOS_COUNTRY buffer, var_country
64 ;; BUFFER = 38 byte data buffer area for country information.
67 ;; VAR_COUNTRY = Default country code
69 ;; OPERATION: DOS function call 65h (id=1) is performed to get the extended
70 ;; country information into the specified data buffer for the default
71 ;; and the active CON device. The country code value from the data buffer
72 ;; is returned in the memory variable specified.
74 ;;****************************************************************************
75 GET_DOS_COUNTRY MACRO BUFFER, VAR_COUNTRY ;;AN000;
82 MOV DI, OFFSET BUFFER ;;AN000; Get the address of the buffer
83 MOV AX, 6501H ;;AN000; Fn call 65h with ID value = 1
84 MOV BX, -1 ;;AN000; Code page of interest (current)
85 MOV DX, -1 ;;AN000; Get information for default country
86 MOV CX, 38 ;;AN000; Amount of data to return
89 MOV BX, [DI]+3 ;;AN000; Get the country ID
90 MOV VAR_COUNTRY, BX ;;AN000;
95 ;;****************************************************************************
97 ;; GET_COUNTRY_INDEX: Scan CTY_TABLE for the specified country code and
98 ;; return index of country code into the table.
100 ;; SYNTAX: GET_COUNTRY_INDEX var_country, var_tab, var_index
103 ;; var_country = The country code
106 ;; var_tab = 1: Country code is in table CTY_TAB_A
107 ;; = 2: Country code is in table CTY_TAB_B
108 ;; var_index = The index into the country list.
110 ;; OPERATION: The CTY_TABLE is scanned for the specified country code and
111 ;; the index into the table is returned.
113 ;; Note: The index of the first item in the table is 1.
115 ;;************************************************************************;;
116 GET_COUNTRY_INDEX MACRO VAR_COUNTRY, VAR_TAB, VAR_INDEX ;;AN000;
118 MOV CX, VAR_COUNTRY ;;AN000; Get the country index
119 CALL GET_CNTY_INDEX_ROUTINE ;;AN000; Search the table for this value
120 MOV VAR_TAB, DX ;;AN000; Which table it was found in
121 MOV VAR_INDEX, BX ;;AN000; Which location in that table
123 ;;****************************************************************************
125 ;; GET_KEYBOARD_INDEX: Scan KYBD_TABLE for the specified keyboard code and
126 ;; return index of keyboard code in the table and the
127 ;; alternate keyboard indicator.
129 ;; SYNTAX: GET_KEYBOARD_INDEX name_kybd, var_table, var_index, var_alt
132 ;; name_kybd = The keyboard code in ASCII-N format.
135 ;; var_table = 1: Keyboard is IN table KYBD_TAB_A
136 ;; = 2: Keyboard is in table KYBD_TAB_B
137 ;; var_index = The index into keyboard table.
138 ;; var_alt = 0: No alternate keyboard
139 ;; = 1: Alternate keyboard present
141 ;; OPERATION: The KYBD_TABLE is scanned for the specifies keyboard code and
142 ;; the index into the table is returned.
144 ;; Note: The index of the first item in the table is 1.
146 ;;************************************************************************
147 GET_KEYBOARD_INDEX MACRO NAME_KYBD, VAR_TABLE, VAR_INDEX, VAR_ALT ;;AN000;
149 MOV DI, OFFSET NAME_KYBD ;;AN000; The name of the keyboard to search for
150 CALL GET_KYBD_INDEX_ROUTINE ;;AN000; Search for this keyboard code
151 MOV VAR_TABLE, DX ;;AN000; Which table the code was found in
152 MOV VAR_INDEX, BX ;;AN000; Which index in the table
153 MOV VAR_ALT, AL ;;AN000; Returned alternate keyboard byte
155 ;;************************************************************************;;
157 ;; GET_KEYBOARD: Get the keyboard code and the alternate keyboard
158 ;; indicator from the KYBD_TABLE for the item specified by the index
159 ;; into the keyboard table.
161 ;; SYNTAX: GET_KEYBOARD var_table, var_index, name_kybd, var_alt
164 ;; var_table = 1: Keyboard code is in table KYBD_TAB_A
165 ;; = 2: Keyboard code is is table KYBD_TAB_B
166 ;; var_index = index into the keyboard table.
169 ;; name_kybd = keyboard code in ASCII-N format.
170 ;; var_alt = 0: No alternate keyboard
171 ;; = 1: Alternate keyboard present
173 ;; OPERATION: The keyboard code from the KYBD_TABLE for the specified
174 ;; index item is returned. Also, the alternate keyboard present
175 ;; variable is updated.
177 ;; Note: Index of the first item in the table is 1.
179 ;;****************************************************************************
180 GET_KEYBOARD MACRO VAR_TABLE, VAR_INDEX, NAME_KYBD, VAR_ALT ;;AN000;
182 MOV AX, VAR_INDEX ;;AN000; Where to start the search
183 MOV CX, VAR_TABLE ;;AN000; Which table to search
184 MOV DI, OFFSET NAME_KYBD ;;AN000; The name of the keyboard code returned
185 CALL GET_KYBD_ROUTINE ;;AN000;
186 MOV VAR_ALT, AL ;;AN000; Returned alternate code
188 ;;************************************************************************;;
190 ;; GET_ALT_KYBD_TABLE: Scan the ALT_KYB_TABLE for the specified keyboard,
191 ;; and return the pointer to the specified keyboards alternate keyboard
194 ;; SYNTAX: GET_ALT_KYBD_TABLE name_kybd, var_table, var_kyb
197 ;; name_kybd = Keyboard code in ASCII-N format.
200 ;; var_table = Pointer to alternat keyboards list.
201 ;; var_kyb = 1: French
205 ;; OPERATION: The ALT_KYB_TABLE is scanned for the specified keyboard
206 ;; code. Pointer to a table of alternate keyboards available for the
207 ;; specified keyboard code is returned as well as the keyboard identifier.
209 ;;****************************************************************************
210 GET_ALT_KYBD_TABLE MACRO NAME_KYBD, VAR_TABLE, VAR_KYB ;;AN000;
212 MOV SI, OFFSET ALT_KYB_TAB_1 ;;AN000; Offset of the data in the table
213 MOV AL, ALT_KYB_TABLE ;;AN000; Number of entries in the table
214 MOV BX, 1 ;;AN000; Index currently being scaned
216 MOV DX, NAME_KYBD+2 ;;AN000;
217 .WHILE <<WORD PTR [SI]> NE DX > AND ;;AN000;
218 .WHILE < BL LE AL > ;;AN000;
220 ADD SI, TYPE ALT_KYB_DEF ;;AN000;
223 .IF < BL GT AL > ;;AN000; Entry NOT found
224 MOV VAR_KYB, 0 ;;AN000;
225 MOV VAR_TABLE, 0 ;;AN000; Pointer is 0 since entry not found
227 COPY_WORD VAR_TABLE, [SI]+2 ;;AN000; Copy the table entries
228 COPY_BYTE VAR_KYB, [SI]+4 ;;AN000;
232 ;;************************************************************************;;
234 ;; GET_ALT_KEYBOARD: Get the alternate keyboard code from the specified
235 ;; alternate keyboard table for the item specified by the index.
237 ;; SYNTAX: GET_ALT_KEYBOARD var_table, var_kyb, var_index, name_kybd
240 ;; var_table = Pointer to alternate keyboard table
241 ;; var_kyb = 1: French
244 ;; var_index = Index into the keyboard table.
247 ;; name_kybd = The keyboard code in ASCII-N format.
249 ;; OPERATION: The keyboard code from the specified table for the
250 ;; specified index item is returned.
252 ;; NOTE: The index of the first item is the table is 1.
254 ;;****************************************************************************
255 GET_ALT_KEYBOARD MACRO VAR_TABLE, VAR_KYB, VAR_INDEX, NAME_KYBD ;;AN000;
257 MOV AX, VAR_INDEX ;;AN000; Get the table index
258 DEC AX ;;AN000; Make the index start at 0
259 MOV SI, VAR_TABLE ;;AN000; Pointer to the table
260 INC SI ;;AN000; Adjust pointer for table length byte
261 .IF < VAR_KYB EQ ALT_FRENCH> ;;AN000;
262 MOV CX, TYPE FR_STRUC ;;AN000;
263 .ELSEIF < VAR_KYB EQ ALT_ITALIAN > ;;AN000;
264 MOV CX, TYPE IT_STRUC ;;AN000;
266 MOV CX, TYPE UK_STRUC ;;AN000;
269 ADD SI, AX ;;AN000; Get the address of the required entry
274 MOV DI, OFFSET NAME_KYBD ;;AN000;
275 MOV CX, LEN_ALT_KYBD_ID ;;AN000; Number of bytes in the keyboard code
276 MOV [DI], CX ;;AN000;
282 ;;****************************************************************************
284 ;; EXEC_PROGRAM: Loads another program into memory and begins execution.
286 ;; SYNTAX: EXEC_PROGRAM child, name_com, parm_block, re_dir
288 ;; INPUT: child = Name of the program to execute (ASCII-N format)
289 ;; name_com = The command line to be passed to parm_block
290 ;; parm_block = Parameter block for child program.
291 ;; re_dir = 1: Redirect Stdout and Stderr to null
292 ;; = 0: Don't redirect output.
294 ;; OUTPUT: CY = 0: Successful
295 ;; CY = 1: Error - AX has the error code.
297 ;; OPERATION: The command line to be passed to the parameter block is
298 ;; copied to the command buffer specified for the parameter block and
299 ;; a carrage return is appended to the end of the buffer. (The
300 ;; command line length can be zero.
302 ;; The segment offsets in the parameter block are defined and DOS
303 ;; function call 29H is performed to set up the default FCB's.
305 ;; DOS function call 4Bh is performed to load and execute the
306 ;; specified child program. The contents of SS and SP are destroyed
307 ;; during the call, so they must be save and restored later. When the
308 ;; parent program (SELECT) gets control, all available memory is
309 ;; allocated to it. It is assumed that memory has been freed (Function
310 ;; call 4Ah - FREE_MEM) before invoking this function.
312 ;;************************************************************************;;
313 EXEC_PROGRAM MACRO CHILD, NAME_COM, PARM_BLOCK, RE_DIR ;;AN000;
315 MOV AX, OFFSET CHILD ;;AN000;
317 MOV AX, OFFSET NAME_COM ;;AN000;
319 MOV AX, OFFSET PARM_BLOCK ;;AN000;
321 MOV AX, RE_DIR ;;AN000;
323 CALL EXEC_PROGRAM_ROUTINE ;;AN000;
325 ;;*****************************************************************************
327 ;; FREE_MEM: Free memory by modifying the memory block
329 ;; SYNTAX: FREE_MEM address
332 ;; address - The address of the first free paragraph in memory.
334 ;; OUTPUT: CY = 0, AX=undefined, successful
335 ;; CY = 1, AX= error code
339 ;; FREEMEM MODIFIES ALLOCATED MEMORY BLOCKS TO
340 ;; CONTAIN THE NEW SPECIFIED BLOCK SIZE.
341 ;; IT MAKES USE OF DOS INT 21 (AH=4AH).
342 ;; IF AN ERROR OCCURS, THE CARRY FLAG IS SET, AND THE ERROR CODE
343 ;; IS RETURNED IN AX.
345 ;;****************************************************************************
346 FREE_MEM MACRO address ;;AN000;
349 DOSCALL ;;AN000; Get the current PSP segment
350 MOV ES,BX ;;AN000; Load current PSP segment
351 MOV BX, ADDRESS ;;AN000; size of program in paragraphs in bx reg
353 MOV AH,4AH ;;AN000; free memory function
357 ;;****************************************************************************
359 ;; CLEAR_SCREEN: clear the screen to white on blue
361 ;; SYNTAX: CLEAR_SCREEN
369 ;; OPERATION: Clears the screen using the BIOS function to scroll the
370 ;; screen completely.
372 ;;****************************************************************************
373 CLEAR_SCREEN MACRO ;;AN000;
375 MOV DX,184Fh ;;AN000; scroll screen from (0,0) tO (24,79)
376 MOV AX,0600h ;;AN000; AH = 6, Scroll Function
377 ;; AL = 0, Clear scroll area
378 MOV BH,01FH ;;AN000; video I/O interrupt
380 MOV DX,0 ;;AN000; RKJ-set cursor posn to top right hand corner
381 MOV BH,0 ;;AN000; RKJ
382 MOV AH,2 ;;AN000; RKJ
385 ;;****************************************************************************
387 ;; CLEAR_SCREEN2: clear the screen to white on black
389 ;; SYNTAX: CLEAR_SCREEN2
397 ;; OPERATION: Clears the screen using the BIOS function to scroll the
398 ;; screen completely.
400 ;;****************************************************************************
401 CLEAR_SCREEN2 MACRO ;;AN000;
403 MOV DX,184Fh ;;AN000; scroll screen from (0,0) tO (24,79)
404 MOV AX,0600h ;;AN000; AH = 6, Scroll Function
405 ;; AL = 0, Clear scroll area
406 MOV BH,7 ;;AN000; video I/O interrupt
408 MOV DX,0 ;;AN000; RKJ-set cursor posn to top right hand corner
409 MOV BH,0 ;;AN000; RKJ
410 MOV AH,2 ;;AN000; RKJ
413 ;;****************************************************************************
415 ;; POS_CURSOR: position the cursor to top left corner of screen
417 ;; SYNTAX: POS_CURSOR
425 ;; OPERATION: Homes the cursor using the BIOS function call.
427 ;;****************************************************************************
428 POS_CURSOR MACRO ;;AN085; SEH
436 MOV DX,0 ;;AN085; SEH-set cursor posn to top left hand corner
437 XOR BH,BH ;;AN085; SEH
438 MOV AH,2 ;;AN085; SEH
448 ;;****************************************************************************
450 ;; BEEP: Produce a tone on the PC speaker
452 ;; SYNTAX: BEEP frequency, duration
454 ;; INPUT: frequency = 37 to 32767
455 ;; duration = 1 to 65535
461 ;; BEEP CREATES A TONE USING THE PC SPEAKER
463 ;;****************************************************************************
464 BEEP MACRO FREQ,DUR ;;AN000;
467 MOV DI, FREQ ;;AN000; set the frequency
468 MOV BX, DUR ;;AN000; set the duration
469 CALL BEEP_ROUTINE ;;AN000;
472 ;;**************************************************************************
474 ;; GOTO : used instead of branching assembler intructions
476 ;; SYNTAX: GOTO label
478 ;; INPUT: label = an assembler label for a branching instruction
485 ;;**************************************************************************
486 GOTO MACRO LABEL ;;AN000;
487 JMP LABEL ;;AN000; jump to label
489 ;;************************************************************************;;
491 ;; BYTE_TO_CHAR: Convert a 8-bit binary number to ASCII format.
493 ;; SYNTAX: BYTE_TO_CHAR var_num, name_str
496 ;; var_num = binary number to convert. (8 bits)
499 ;; name_str = ASCII-N string for the specifed value.
501 ;; OPERATION: The specified 8 bit numeric variable contents are converted
502 ;; to ASCII and stored in ASCII-N format. Leading zeros will not be
505 ;;************************************************************************;;
506 BYTE_TO_CHAR MACRO VAR_NUM, NAME_STR ;;AN000;
509 MOV AL, VAR_NUM ;;AN000;
511 MOV DI, OFFSET NAME_STR ;;AN000;
512 CALL BIN_TO_CHAR_ROUTINE ;;AN000;
514 ;;************************************************************************;;
516 ;; WORD_TO_CHAR: Convert a binary number to ASCII format.
518 ;; SYNTAX: WORD_TO_CHAR var_num, name_str
521 ;; var_num = binary number to convert. (16 bits)
524 ;; name_str = ASCII-N string for the specifed value.
526 ;; OPERATION: The specified 16 bit numeric variable contents are converted
527 ;; to ASCII and stored in ASCII-N format. Leading zeros will not be
530 ;;************************************************************************;;
531 WORD_TO_CHAR MACRO VAR_NUM, NAME_STR ;;AN000;
533 MOV AX, VAR_NUM ;;AN000;
534 MOV DI, OFFSET NAME_STR ;;AN000;
535 CALL BIN_TO_CHAR_ROUTINE ;;AN000;
538 INCLUDE MACROS6.INC ;;AN000;