1 Microsoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18
\r
2 c_utils.asm Page 1 - 1
\r
5 ;=======================================================
\r
6 ;=== C_UTILS.ASM - Asm Utilities for C/C++ ===
\r
7 ;=======================================================
\r
16 ; macros to PUSH and POP multiple registers
\r
18 PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8
\r
21 PUSHx R2, R3, R4, R5, R6, R7, R8
\r
25 POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8
\r
28 POPx R2, R3, R4, R5, R6, R7, R8
\r
32 ; Macro to Clear a Register to 0
\r
35 xor Register, Register ; Set Register = 0
\r
38 ; Macros to Decrement Counter & Jump on Condition
\r
40 LOOPx MACRO Register, Destination
\r
41 dec Register ; Counter--
\r
42 jnz Destination ; Jump if not 0
\r
45 LOOPjz MACRO Register, Destination
\r
46 dec Register ; Counter--
\r
47 jz Destination ; Jump if 0
\r
51 ; ==== General Constants ====
\r
57 = BYTE PTR b EQU BYTE PTR
\r
58 = WORD PTR w EQU WORD PTR
\r
59 = DWORD PTR d EQU DWORD PTR
\r
60 = OFFSET o EQU OFFSET
\r
61 = FAR PTR f EQU FAR PTR
\r
63 = ?,?,?,? ?x4 EQU <?,?,?,?>
\r
64 = ?,?,? ?x3 EQU <?,?,?>
\r
71 0000 1CE5 7307 0322 RND_Seed DW 7397, 29447, 802
\r
72 0006 00B3 00B7 00B6 RND_Mult DW 179, 183, 182
\r
73 000C 8003 800B 800F RND_ModV DW 32771, 32779, 32783
\r
75 0012 0D 0A CR_LF DB 13, 10 ; the CRLF data
\r
79 ;===========================================
\r
80 ;void far pascal dos_print (far char *Text)
\r
81 ;===========================================
\r
83 ; - Print Text Directly to DOS console w/ CR/LF
\r
89 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP
\r
91 0008 00000000 DD ? ; Caller
\r
92 000C 00000000 DP_Text DD ? ; Far Address of Text to print
\r
96 0000 DOS_PRINT PROC FAR
\r
98 PUSHx BP, DS, SI, DI ; Preserve Important Registers
\r
99 0000 55 1 push BP ; Save R1
\r
100 0001 1E 2 push DS ; Save R1
\r
101 0002 56 3 push SI ; Save R1
\r
102 0003 57 4 push DI ; Save R1
\r
103 0004 8B EC mov BP, SP ; Set up Stack Frame
\r
105 0006 C5 56 0C lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor
\r
107 ; Compute Length of string
\r
109 CLR CX ; Length = 0
\r
110 0009 33 C9 1 xor CX, CX ; Set Register = 0
\r
111 000B 8B F2 mov SI, DX ; DS:SI = String data
\r
115 000D 80 3C 00 cmp b [SI], 0 ; Null Byte found?
\r
116 0010 74 04 je @@DP_Got_Len ; exit loop if so
\r
118 0012 41 inc CX ; Len++
\r
119 0013 46 inc SI ; Point to next char
\r
120 0014 EB F7 jmp s @@DP_Scan_it ; check again...
\r
124 0016 E3 07 jcxz @No_Print ; Don't Print if empty
\r
126 0018 BB 0001 mov BX, 1 ; 1= DOS Handle for Display
\r
127 001B B4 40 mov AH, 40h ; Write Text Function
\r
128 001D CD 21 int 21h ; Call DOS to do it
\r
131 001F B8 ---- R mov AX, SEG DGROUP ; Restore DGroup
\r
132 0022 8E D8 mov DS, AX
\r
134 0024 BA 0012 R mov DX, o CR_LF ; Get Addr of CR/LF pair
\r
135 0027 B9 0002 mov CX, 2 ; 2 Characters to Write
\r
136 002A BB 0001 mov BX, 1 ; 1= DOS Handle for Display
\r
138 002D B4 40 mov AH, 40h ; Write Text Function
\r
139 002F CD 21 int 21h ; Call DOS to do it
\r
141 0031 FC cld ; Reset Direction Flag
\r
142 POPx DI, SI, DS, BP ; Restore Saved Registers
\r
143 0032 5F 1 pop DI ; Restore R1
\r
144 0033 5E 2 pop SI ; Restore R1
\r
145 0034 1F 3 pop DS ; Restore R1
\r
146 0035 5D 4 pop BP ; Restore R1
\r
147 0036 CA 0004 ret 4 ; Exit & Clean Up Stack
\r
149 0039 DOS_PRINT ENDP
\r
152 ;===========================================
\r
153 ;void far pascal dos_prints (char far *Text)
\r
154 ;===========================================
\r
156 ; Print Text Directly to DOS console
\r
157 ; without a trailing CR/LF
\r
162 0039 DOS_PRINTS PROC FAR
\r
164 PUSHx BP, DS, SI, DI ; Preserve Important Registers
\r
165 0039 55 1 push BP ; Save R1
\r
166 003A 1E 2 push DS ; Save R1
\r
167 003B 56 3 push SI ; Save R1
\r
168 003C 57 4 push DI ; Save R1
\r
169 003D 8B EC mov BP, SP ; Set up Stack Frame
\r
171 003F C5 56 0C lds DX, [BP].DP_Text ; Get Addr of Text$ descriptor
\r
173 ; Compute Length of string
\r
175 CLR CX ; Length = 0
\r
176 0042 33 C9 1 xor CX, CX ; Set Register = 0
\r
177 0044 8B F2 mov SI, DX ; DS:SI = String data
\r
179 0046 @@DPS_Scan_it:
\r
181 0046 80 3C 00 cmp b [SI], 0 ; Null Byte found?
\r
182 0049 74 04 je @@DPS_Got_Len ; exit loop if so
\r
184 004B 41 inc CX ; Len++
\r
185 004C 46 inc SI ; Point to next char
\r
186 004D EB F7 jmp s @@DPS_Scan_it ; check again...
\r
188 004F @@DPS_Got_len:
\r
190 004F E3 07 jcxz @DPS_Exit ; Don't Print if empty
\r
192 0051 BB 0001 mov BX, 1 ; 1= DOS Handle for Display
\r
193 0054 B4 40 mov AH, 40h ; Write Text Function
\r
194 0056 CD 21 int 21h ; Call DOS to do it
\r
197 0058 FC cld ; Reset Direction Flag
\r
198 POPx DI, SI, DS, BP ; Restore Saved Registers
\r
199 0059 5F 1 pop DI ; Restore R1
\r
200 005A 5E 2 pop SI ; Restore R1
\r
201 005B 1F 3 pop DS ; Restore R1
\r
202 005C 5D 4 pop BP ; Restore R1
\r
203 005D CA 0002 ret 2 ; Exit & Clean Up Stack
\r
205 0060 DOS_PRINTS ENDP
\r
208 ;=========================================
\r
209 ;void far pascal set_video_mode (int Mode)
\r
210 ;=========================================
\r
212 ; Sets the Video Mode through the BIOS
\r
215 PUBLIC SET_VIDEO_MODE
\r
217 000E SVM_Stack STRUC
\r
218 0000 0000 0000 0000 DW ?x4 ; DI, SI, DS, BP
\r
220 0008 00000000 DD ? ; Caller
\r
221 000C 00 00 SVM_Mode DB ?,? ; Desired Video Mode
\r
225 0060 SET_VIDEO_MODE PROC FAR
\r
227 PUSHx BP, DS, SI, DI ; Preserve Important Registers
\r
228 0060 55 1 push BP ; Save R1
\r
229 0061 1E 2 push DS ; Save R1
\r
230 0062 56 3 push SI ; Save R1
\r
231 0063 57 4 push DI ; Save R1
\r
232 0064 8B EC mov BP, SP ; Set up Stack Frame
\r
234 CLR AH ; Function 0
\r
235 0066 32 E4 1 xor AH, AH ; Set Register = 0
\r
236 0068 8A 46 0C mov AL, [BP].SVM_Mode ; Get Mode #
\r
238 006B CD 10 int 10H ; Change Video Modes
\r
241 POPx DI, SI, DS, BP ; Restore Saved Registers
\r
242 006D 5F 1 pop DI ; Restore R1
\r
243 006E 5E 2 pop SI ; Restore R1
\r
244 006F 1F 3 pop DS ; Restore R1
\r
245 0070 5D 4 pop BP ; Restore R1
\r
246 0071 CA 0002 ret 2 ; Exit & Clean Up Stack
\r
248 0074 SET_VIDEO_MODE ENDP
\r
251 ;===================================
\r
252 ;int far pascal scan_keyboard (void)
\r
253 ;===================================
\r
255 ; Function to scan keyboard for a pressed key
\r
258 PUBLIC SCAN_KEYBOARD
\r
260 0074 SCAN_KEYBOARD PROC FAR
\r
262 PUSHx BP, DS, SI, DI ; Preserve Important Registers
\r
263 0074 55 1 push BP ; Save R1
\r
264 \fMicrosoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18
\r
265 c_utils.asm Page 2 - 1
\r
268 0075 1E 2 push DS ; Save R1
\r
269 0076 56 3 push SI ; Save R1
\r
270 0077 57 4 push DI ; Save R1
\r
272 0078 B4 01 mov AH, 01H ; Function #1
\r
273 007A CD 16 INT 16H ; Call Keyboard Driver
\r
274 007C 74 0C JZ @SK_NO_KEY ; Exit if Zero flag set
\r
276 007E B4 00 mov AH, 00H ; Remove Key from Buffer
\r
277 0080 CD 16 INT 16H ; Get Keycode in AX
\r
279 0082 0A C0 OR AL, AL ; Low Byte Set (Ascii?)
\r
280 0084 74 06 JZ @SK_Exit ; if not, it's a F-Key
\r
282 CLR AH ; Clear ScanCode if Ascii
\r
283 0086 32 E4 1 xor AH, AH ; Set Register = 0
\r
284 0088 EB 02 JMP s @SK_Exit ; Return Key in AX
\r
287 CLR AX ; Return Nil (no Keypress)
\r
288 008A 33 C0 1 xor AX, AX ; Set Register = 0
\r
291 008C FC cld ; Reset Direction Flag
\r
292 POPx DI, SI, DS, BP ; Restore Saved Registers
\r
293 008D 5F 1 pop DI ; Restore R1
\r
294 008E 5E 2 pop SI ; Restore R1
\r
295 008F 1F 3 pop DS ; Restore R1
\r
296 0090 5D 4 pop BP ; Restore R1
\r
297 0091 CB ret ; Exit & Clean Up Stack
\r
299 0092 SCAN_KEYBOARD ENDP
\r
302 ;========================================
\r
303 ;int far pascal random_int (int MaxValue)
\r
304 ;========================================
\r
306 ; Returns a pseudo-random number in the range of (0.. MaxInt-1)
\r
312 0008 RI_Stack STRUC
\r
313 0000 0000 DW ? ; BP
\r
314 0002 00000000 DD ? ; Caller
\r
315 0006 0000 RI_MaxVal DW ? ; Maximum Value to Return + 1
\r
319 0092 RANDOM_INT PROC FAR
\r
321 0092 55 push BP ; Preserve Important Registers
\r
322 0093 8B EC mov BP, SP ; Set up Stack Frame
\r
324 CLR BX ; BX is the data index
\r
325 0095 33 DB 1 xor BX, BX ; Set Register = 0
\r
326 CLR CX ; CX is the accumulator
\r
327 0097 33 C9 1 xor CX, CX ; Set Register = 0
\r
330 mov AX, RND_Seed[BX] ; load the initial seed
\r
331 mul RND_Mult[BX] ; multiply it
\r
332 div RND_ModV[BX] ; and obtain the Mod value
\r
333 mov RND_Seed[BX], DX ; save that for the next time
\r
335 add CX, DX ; add it into the accumulator
\r
337 inc BX ; point to the next set of values
\r
339 0099 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed
\r
340 009D F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it
\r
341 00A1 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value
\r
342 00A5 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time
\r
343 00A9 03 CA 1 add CX, DX ; add it into the accumulator
\r
345 00AC 43 1 inc BX ; point to the next set of values
\r
346 00AD 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed
\r
347 00B1 F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it
\r
348 00B5 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value
\r
349 00B9 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time
\r
350 00BD 03 CA 1 add CX, DX ; add it into the accumulator
\r
352 00C0 43 1 inc BX ; point to the next set of values
\r
353 00C1 8B 87 0000 R 1 mov AX, RND_Seed[BX] ; load the initial seed
\r
354 00C5 F7 A7 0006 R 1 mul RND_Mult[BX] ; multiply it
\r
355 00C9 F7 B7 000C R 1 div RND_ModV[BX] ; and obtain the Mod value
\r
356 00CD 89 97 0000 R 1 mov RND_Seed[BX], DX ; save that for the next time
\r
357 00D1 03 CA 1 add CX, DX ; add it into the accumulator
\r
359 00D4 43 1 inc BX ; point to the next set of values
\r
361 00D5 8B C1 mov AX, CX ; AX = Random #
\r
363 00D7 33 D2 1 xor DX, DX ; Set Register = 0
\r
364 00D9 F7 76 06 div [BP].RI_MaxVal ; DX = DX:AX / MAxVal Remainder
\r
366 00DC 8B C2 mov AX, DX
\r
368 00DE 5D pop BP ; Restore BP
\r
369 00DF CA 0002 ret 2 ; back to BASIC with AX holding the result
\r
371 00E2 RANDOM_INT ENDP
\r
374 ;==================================
\r
375 ;void far pascal init_random (void)
\r
376 ;==================================
\r
378 ; Scrambles the psuedo-random number sequence
\r
379 ; (XOR's the seed value with the timer)
\r
384 00E2 INIT_RANDOM PROC FAR
\r
386 CLR AX ; Segment = 0000
\r
387 00E2 33 C0 1 xor AX, AX ; Set Register = 0
\r
388 00E4 8E C0 mov ES, AX
\r
389 00E6 26: A1 046C mov AX, ES:[046Ch] ; Get Timer Lo Word
\r
391 00EA 31 06 0000 R xor RND_Seed, AX ; Scramble 1st Seed
\r
393 00EE CB ret ; Exit & Clean Up Stack
\r
395 00EF INIT_RANDOM ENDP
\r
397 ;=========================================
\r
398 ;int far pascal int_sqr (int X, int Round)
\r
399 ;=========================================
\r
401 ; Returns the Integer Square Root of (X)
\r
402 ; Round allows the return value to be rounded to the
\r
403 ; nearest integer value by passing 0x80. Passing 0
\r
404 ; return the Integer Portion only. The rounding amound is
\r
405 ; a number from 0 to 1 multiplied by 256, thus
\r
406 ; 0.5 * 0x100 = 0x80!
\r
409 000C ISQ_Stack STRUC
\r
410 0000 0000 0000 DW ?,? ; BP, DI
\r
411 0004 00000000 DD ? ; Caller
\r
412 0008 0000 ISQ_Round DW ? ; Amount to Round Result * 256
\r
413 000A 0000 ISQ_X DW ? ; "X"
\r
418 00EF INT_SQR PROC FAR
\r
420 PUSHx BP, DI ; Save BP
\r
421 00EF 55 1 push BP ; Save R1
\r
422 00F0 57 2 push DI ; Save R1
\r
423 00F1 8B EC mov BP, SP ; Set up Stack Frame
\r
425 00F3 33 C0 xor AX, AX ; {xor eax,eax}
\r
426 00F5 33 D2 xor DX, DX ; {xor edx,edx}
\r
427 00F7 8B 7E 0A mov DI, [BP].ISQ_X ; {mov edi,x}
\r
429 00FA B9 0010 mov CX, 16 ; {mov cx, 32}
\r
433 00FD D1 E7 shl DI, 1 ; {shl edi,1}
\r
434 00FF D1 D2 rcl DX, 1 ; {rcl edx,1}
\r
435 0101 D1 E7 shl DI, 1 ; {shl edi,1}
\r
436 0103 D1 D2 rcl DX, 1 ; {rcl edx,1}
\r
437 0105 D1 E0 shl AX, 1 ; {shl eax,1}
\r
438 0107 8B D8 mov BX, AX ; {mov ebx,eax}
\r
439 0109 D1 E3 shl BX, 1 ; {shl ebx,1}
\r
440 010B 43 inc BX ; {inc ebx}
\r
441 010C 3B D3 cmp DX, BX ; {cmp edx,ebx}
\r
442 010E 7C 03 jl @ISQ_S
\r
444 0110 2B D3 sub DX, BX ; {sub edx,ebx}
\r
445 0112 40 inc AX ; {inc eax}
\r
448 0113 E2 E8 loop @ISQ_L
\r
450 0115 03 46 08 add ax, [BP].ISQ_Round ; {add eax,$00008000}
\r
451 ; {*round* result in hi word: ie. +0
\r
453 0118 C1 E8 08 shr ax, 8 ; {shr eax,16} {to ax (result)}
\r
455 POPx DI, BP ; Restore Registers
\r
456 011B 5F 1 pop DI ; Restore R1
\r
457 011C 5D 2 pop BP ; Restore R1
\r
458 011D CA 0004 ret 4 ; Exit
\r
462 ;=================================
\r
463 ;int far pascal timer_count (void)
\r
464 ;=================================
\r
466 ; Returns the current timer value as an integer/long integer
\r
471 0120 TIMER_COUNT PROC FAR
\r
473 CLR AX ; Segment = 0000
\r
474 0120 33 C0 1 xor AX, AX ; Set Register = 0
\r
475 0122 8E C0 mov ES, AX
\r
476 0124 26: A1 046C mov AX, ES:[046Ch] ; Get Timer Lo Word
\r
477 0128 26: 8B 16 046E mov DX, ES:[046Eh] ; Get Timer Hi Word
\r
478 012D CB ret ; Exit & Clean Up Stack
\r
480 012E TIMER_COUNT ENDP
\r
484 \fMicrosoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18
\r
485 c_utils.asm Symbols 3 - 1
\r
494 CLR . . . . . . . . . . . . . . Proc
\r
495 LOOPjz . . . . . . . . . . . . . Proc
\r
496 LOOPx . . . . . . . . . . . . . Proc
\r
497 POPx . . . . . . . . . . . . . . Proc
\r
498 PUSHx . . . . . . . . . . . . . Proc
\r
499 \fMicrosoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18
\r
500 c_utils.asm Symbols 4 - 1
\r
505 Structures and Unions:
\r
510 DP_Stack . . . . . . . . . . . . 0010
\r
511 DP_Text . . . . . . . . . . . 000C DWord
\r
512 ISQ_Stack . . . . . . . . . . . 000C
\r
513 ISQ_Round . . . . . . . . . . 0008 Word
\r
514 ISQ_X . . . . . . . . . . . . 000A Word
\r
515 RI_Stack . . . . . . . . . . . . 0008
\r
516 RI_MaxVal . . . . . . . . . . 0006 Word
\r
517 SVM_Stack . . . . . . . . . . . 000E
\r
518 SVM_Mode . . . . . . . . . . . 000C Byte
\r
519 \fMicrosoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18
\r
520 c_utils.asm Symbols 5 - 1
\r
525 Segments and Groups:
\r
527 N a m e Size Length Align Combine Class
\r
529 C_UTILS_TEXT . . . . . . . . . . 16 Bit 012E Word Public 'CODE'
\r
530 DGROUP . . . . . . . . . . . . . GROUP
\r
531 _DATA . . . . . . . . . . . . . 16 Bit 0014 Word Public 'DATA'
\r
532 \fMicrosoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18
\r
533 c_utils.asm Symbols 6 - 1
\r
538 Procedures, parameters and locals:
\r
540 N a m e Type Value Attr
\r
542 DOS_PRINTS . . . . . . . . . . . P Far 0039 C_UTILS_TEXT Length= 0027 Public
\r
543 DOS_PRINT . . . . . . . . . . . P Far 0000 C_UTILS_TEXT Length= 0039 Public
\r
544 INIT_RANDOM . . . . . . . . . . P Far 00E2 C_UTILS_TEXT Length= 000D Public
\r
545 INT_SQR . . . . . . . . . . . . P Far 00EF C_UTILS_TEXT Length= 0031 Public
\r
546 RANDOM_INT . . . . . . . . . . . P Far 0092 C_UTILS_TEXT Length= 0050 Public
\r
547 SCAN_KEYBOARD . . . . . . . . . P Far 0074 C_UTILS_TEXT Length= 001E Public
\r
548 SET_VIDEO_MODE . . . . . . . . . P Far 0060 C_UTILS_TEXT Length= 0014 Public
\r
549 TIMER_COUNT . . . . . . . . . . P Far 0120 C_UTILS_TEXT Length= 000E Public
\r
550 \fMicrosoft (R) Macro Assembler Version 6.11 07/03/14 12:38:18
\r
551 c_utils.asm Symbols 7 - 1
\r
558 N a m e Type Value Attr
\r
560 ?x3 . . . . . . . . . . . . . . Text ?,?,?
\r
561 ?x4 . . . . . . . . . . . . . . Text ?,?,?,?
\r
562 @@DPS_Got_len . . . . . . . . . L Near 004F C_UTILS_TEXT
\r
563 @@DPS_Scan_it . . . . . . . . . L Near 0046 C_UTILS_TEXT
\r
564 @@DP_Got_len . . . . . . . . . . L Near 0016 C_UTILS_TEXT
\r
565 @@DP_Scan_it . . . . . . . . . . L Near 000D C_UTILS_TEXT
\r
566 @CodeSize . . . . . . . . . . . Number 0001h
\r
567 @DPS_Exit . . . . . . . . . . . L Near 0058 C_UTILS_TEXT
\r
568 @DataSize . . . . . . . . . . . Number 0000h
\r
569 @ISQ_L . . . . . . . . . . . . . L Near 00FD C_UTILS_TEXT
\r
570 @ISQ_S . . . . . . . . . . . . . L Near 0113 C_UTILS_TEXT
\r
571 @Interface . . . . . . . . . . . Number 0000h
\r
572 @Model . . . . . . . . . . . . . Number 0004h
\r
573 @No_Print . . . . . . . . . . . L Near 001F C_UTILS_TEXT
\r
574 @SK_Exit . . . . . . . . . . . . L Near 008C C_UTILS_TEXT
\r
575 @SK_NO_KEY . . . . . . . . . . . L Near 008A C_UTILS_TEXT
\r
576 @SVM_Exit . . . . . . . . . . . L Near 006D C_UTILS_TEXT
\r
577 @code . . . . . . . . . . . . . Text C_UTILS_TEXT
\r
578 @data . . . . . . . . . . . . . Text DGROUP
\r
579 @fardata? . . . . . . . . . . . Text FAR_BSS
\r
580 @fardata . . . . . . . . . . . . Text FAR_DATA
\r
581 @stack . . . . . . . . . . . . . Text DGROUP
\r
582 CR_LF . . . . . . . . . . . . . Byte 0012 _DATA
\r
583 False . . . . . . . . . . . . . Number 0000h
\r
584 RND_ModV . . . . . . . . . . . . Word 000C _DATA
\r
585 RND_Mult . . . . . . . . . . . . Word 0006 _DATA
\r
586 RND_Seed . . . . . . . . . . . . Word 0000 _DATA
\r
587 True . . . . . . . . . . . . . . Number -0001h
\r
588 b . . . . . . . . . . . . . . . Text BYTE PTR
\r
589 d . . . . . . . . . . . . . . . Text DWORD PTR
\r
590 f . . . . . . . . . . . . . . . Text FAR PTR
\r
591 nil . . . . . . . . . . . . . . Number 0000h
\r
592 o . . . . . . . . . . . . . . . Text OFFSET
\r
593 s . . . . . . . . . . . . . . . Text SHORT
\r
594 w . . . . . . . . . . . . . . . Text WORD PTR
\r