Replace invalid characters with HTML entities

— with —
’ with ’
+ with +
× with x
ç with ç
“ with “
” with ”
‘ with ‘
• with •
– with -
µ with µ
† with †
Fix C++
θ with θ
Yen symbol instead of times
Fix broken apos
Bullet again
E-circumflex
This commit is contained in:
James Gregory 2013-12-30 12:50:32 +11:00
commit 500e7f5654
353 changed files with 5091 additions and 5091 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -70,10 +70,10 @@
; ;
; Note: These routines can introduce slight inaccuracies into the ; Note: These routines can introduce slight inaccuracies into the
; system clock count for each code section timed even if ; system clock count for each code section timed even if
; timer 0 doesn’t overflow. If timer 0 does overflow, the ; timer 0 doesn’t overflow. If timer 0 does overflow, the
; system clock can become slow by virtually any amount of ; system clock can become slow by virtually any amount of
; time, since the system clock can’t advance while the ; time, since the system clock can’t advance while the
; precison timer is timing. Consequently, it’s a good idea ; precison timer is timing. Consequently, it’s a good idea
; to reboot at the end of each timing session. (The ; to reboot at the end of each timing session. (The
; battery-backed clock, if any, is not affected by the Zen ; battery-backed clock, if any, is not affected by the Zen
; timer.) ; timer.)
@ -84,7 +84,7 @@
; in when ZTimerOn was called. ; in when ZTimerOn was called.
; ;
Code segment word public ‘CODE’ Code segment word public ‘CODE’
assumecs: Code, ds:nothing assumecs: Code, ds:nothing
public ZTimerOn, ZTimerOff, ZTimerReport public ZTimerOn, ZTimerOff, ZTimerReport
@ -95,11 +95,11 @@ BASE_8253equ40h
; ;
; The address of the timer 0 count registers in the 8253. ; The address of the timer 0 count registers in the 8253.
; ;
TIMER_0_8253 equBASE_8253 + 0 TIMER_0_8253 equBASE_8253 + 0
; ;
; The address of the mode register in the 8253. ; The address of the mode register in the 8253.
; ;
MODE_8253 equBASE_8253 + 3 MODE_8253 equBASE_8253 + 3
; ;
; The address of Operation Command Word 3 in the 8259 Programmable ; The address of Operation Command Word 3 in the 8259 Programmable
; Interrupt Controller (PIC) (write only, and writable only when ; Interrupt Controller (PIC) (write only, and writable only when
@ -131,9 +131,9 @@ p2: push cs ; construct far return address to
; can respond to both accesses even on a very fast PC. ; can respond to both accesses even on a very fast PC.
; ;
DELAY macro DELAY macro
jmp $+2 jmp $+2
jmp $+2 jmp $+2
jmp $+2 jmp $+2
endm endm
OriginalFlags db ? ; storage for upper byte of OriginalFlags db ? ; storage for upper byte of
@ -150,28 +150,28 @@ OverflowFlag db ? ; used to indicate whether the
; String printed to report results. ; String printed to report results.
; ;
OutputStr label byte OutputStr label byte
db 0dh, 0ah, ‘Timed count: ‘, 5 dup (?) db 0dh, 0ah, ‘Timed count: ‘, 5 dup (?)
ASCIICountEnd labelbyte ASCIICountEnd labelbyte
db ‘ microseconds’, 0dh, 0ah db ‘ microseconds’, 0dh, 0ah
db ‘$’ db ‘$’
; ;
; String printed to report timer overflow. ; String printed to report timer overflow.
; ;
OverflowStr label byte OverflowStr label byte
db 0dh, 0ah db 0dh, 0ah
db ‘****************************************************’ db ‘****************************************************’
db 0dh, 0ah db 0dh, 0ah
db ‘* The timer overflowed, so the interval timed was *’ db ‘* The timer overflowed, so the interval timed was *’
db 0dh, 0ah db 0dh, 0ah
db ‘* too long for the precision timer to measure. *’ db ‘* too long for the precision timer to measure. *’
db 0dh, 0ah db 0dh, 0ah
db ‘* Please perform the timing test again with the *’ db ‘* Please perform the timing test again with the *’
db0dh, 0ah db0dh, 0ah
db ‘* long-period timer. *’ db ‘* long-period timer. *’
db 0dh, 0ah db 0dh, 0ah
db ‘****************************************************’ db ‘****************************************************’
db 0dh, 0ah db 0dh, 0ah
db ‘$’ db ‘$’
; ******************************************************************** ; ********************************************************************
; * Routine called to start timing. * ; * Routine called to start timing. *
@ -193,7 +193,7 @@ ZTimerOn proc near
; to 0 ; to 0
push ax push ax
; ;
; Turn on interrupts, so the timer interrupt can occur if it’s ; Turn on interrupts, so the timer interrupt can occur if it’s
; pending. ; pending.
; ;
sti sti
@ -206,7 +206,7 @@ ZTimerOn proc near
mov al,00110100b ;mode 2 mov al,00110100b ;mode 2
out MODE_8253,al out MODE_8253,al
; ;
; Set the timer count to 0, so we know we won’t get another ; Set the timer count to 0, so we know we won’t get another
; timer interrupt right away. ; timer interrupt right away.
; Note: this introduces an inaccuracy of up to 54 ms in the system ; Note: this introduces an inaccuracy of up to 54 ms in the system
; clock count each time it is executed. ; clock count each time it is executed.
@ -224,7 +224,7 @@ ZTimerOn proc near
; delay time will be more than long enough even on a very fast PC. ; delay time will be more than long enough even on a very fast PC.
; ;
rept 10 rept 10
jmp $+2 jmp $+2
endm endm
; ;
; Disable interrupts to get an accurate count. ; Disable interrupts to get an accurate count.
@ -308,9 +308,9 @@ ZTimerOff proc near
call ReferenceZTimerOff call ReferenceZTimerOff
loop RefLoop loop RefLoop
sti sti
add cs:[ReferenceCount],8; total + (0.5 * 16) add cs:[ReferenceCount],8; total + (0.5 * 16)
mov cl,4 mov cl,4
shr cs:[ReferenceCount],cl; (total) / 16 + 0.5 shr cs:[ReferenceCount],cl; (total) / 16 + 0.5
; ;
; Restore original interrupt state. ; Restore original interrupt state.
; ;
@ -453,7 +453,7 @@ PrintGoodCount:
CTSLoop: CTSLoop:
sub dx, dx sub dx, dx
div bx div bx
add dl,’0’ add dl,’0’
mov [si],dl mov [si],dl
dec si dec si
loop CTSLoop loop CTSLoop

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -50,7 +50,7 @@
#include &ltalloc.h&gt /* alloc.h for Borland compilers, #include &ltalloc.h&gt /* alloc.h for Borland compilers,
malloc.h for Microsoft compilers */ malloc.h for Microsoft compilers */
#define BLOCK_SIZE 0x4000 /* we’ll process the file in 16K blocks */ #define BLOCK_SIZE 0x4000 /* we’ll process the file in 16K blocks */
/* Searches the specified number of sequences in the specified /* Searches the specified number of sequences in the specified
buffer for matches to SearchString of SearchStringLength. Note buffer for matches to SearchString of SearchStringLength. Note
@ -77,19 +77,19 @@ int SearchForString(unsigned char *Buffer, int SearchLength,
also matches */ also matches */
if ( SearchStringLength == 1 ) { if ( SearchStringLength == 1 ) {
return(1); /* That one matching character was the whole return(1); /* That one matching character was the whole
search string, so we’ve got a match */ search string, so we’ve got a match */
} }
else { else {
/* Check whether the remaining characters match */ /* Check whether the remaining characters match */
if ( !memcmp(PotentialMatch + 1, SearchString + 1, if ( !memcmp(PotentialMatch + 1, SearchString + 1,
SearchStringLength - 1) ) { SearchStringLength - 1) ) {
return(1); /* We’ve got a match */ return(1); /* We’ve got a match */
} }
} }
/* The string doesn’t match; keep going by pointing past the /* The string doesn’t match; keep going by pointing past the
potential match location we just rejected */ potential match location we just rejected */
SearchLength -= PotentialMatch - Buffer + 1; SearchLength -= PotentialMatch - Buffer + 1;
Buffer = PotentialMatch + 1; Buffer = PotentialMatch + 1;
} }
return(0); /* No match found */ return(0); /* No match found */
@ -114,13 +114,13 @@ main(int argc, char *argv[]) {
/* Check for the proper number of arguments */ /* Check for the proper number of arguments */
if ( argc != 3 ) { if ( argc != 3 ) {
printf(“usage: search filename search-string\n”); printf(“usage: search filename search-string\n”);
exit(1); exit(1);
} }
/* Try to open the file to be searched */ /* Try to open the file to be searched */
if ( (Handle = open(argv[1], O_RDONLY | O_BINARY)) == -1 ) { if ( (Handle = open(argv[1], O_RDONLY | O_BINARY)) == -1 ) {
printf(“Can’t open file: %s\n”, argv[1]); printf(“Can’t open file: %s\n”, argv[1]);
exit(1); exit(1);
} }
/* Calculate the length of text to search for */ /* Calculate the length of text to search for */
@ -128,7 +128,7 @@ main(int argc, char *argv[]) {
SearchStringLength = strlen(SearchString); SearchStringLength = strlen(SearchString);
/* Try to get memory in which to buffer the data */ /* Try to get memory in which to buffer the data */
if ( (WorkingBlock = malloc(BLOCK_SIZE)) == NULL ) { if ( (WorkingBlock = malloc(BLOCK_SIZE)) == NULL ) {
printf(“Can’t get enough memory\n”); printf(“Can’t get enough memory\n”);
exit(1); exit(1);
} }
@ -137,7 +137,7 @@ main(int argc, char *argv[]) {
NextLoadPtr = WorkingBlock; NextLoadPtr = WorkingBlock;
NextLoadCount = BLOCK_SIZE; NextLoadCount = BLOCK_SIZE;
Done = 0; /* Not done with search yet */ Done = 0; /* Not done with search yet */
Found = 0; /* Assume we won’t find a match */ Found = 0; /* Assume we won’t find a match */
/* Search the file in BLOCK_SIZE chunks */ /* Search the file in BLOCK_SIZE chunks */
do { do {
/* Read in however many bytes are needed to fill out the block /* Read in however many bytes are needed to fill out the block
@ -145,10 +145,10 @@ main(int argc, char *argv[]) {
the rest of the bytes in the file, whichever is less */ the rest of the bytes in the file, whichever is less */
if ( (WorkingLength = read(Handle, NextLoadPtr, if ( (WorkingLength = read(Handle, NextLoadPtr,
NextLoadCount)) == -1 ) { NextLoadCount)) == -1 ) {
printf(“Error reading file %s\n”, argv[1]); printf(“Error reading file %s\n”, argv[1]);
exit(1); exit(1);
} }
/* If we didn’t read all the bytes we requested, we’re done /* If we didn’t read all the bytes we requested, we’re done
after this block, whether we find a match or not */ after this block, whether we find a match or not */
if ( WorkingLength != NextLoadCount ) { if ( WorkingLength != NextLoadCount ) {
Done = 1; Done = 1;
@ -156,7 +156,7 @@ main(int argc, char *argv[]) {
/* Account for any bytes we copied from the end of the last /* Account for any bytes we copied from the end of the last
block in the total length of this block */ block in the total length of this block */
WorkingLength += NextLoadPtr - WorkingBlock; WorkingLength += NextLoadPtr - WorkingBlock;
/* Calculate the number of bytes in this block that could /* Calculate the number of bytes in this block that could
possibly be the start of a matching sequence that lies possibly be the start of a matching sequence that lies
entirely in this block (sequences that run off the end of entirely in this block (sequences that run off the end of
@ -164,10 +164,10 @@ main(int argc, char *argv[]) {
when that block is searched) when that block is searched)
*/ */
if ( (BlockSearchLength = if ( (BlockSearchLength =
WorkingLength - SearchStringLength + 1) &lt= 0 ) { WorkingLength - SearchStringLength + 1) &lt= 0 ) {
Done = 1; /* Too few characters in this block for Done = 1; /* Too few characters in this block for
there to be any possible matches, so this there to be any possible matches, so this
is the final block and we’re done without is the final block and we’re done without
finding a match finding a match
*/ */
} }
@ -175,7 +175,7 @@ main(int argc, char *argv[]) {
/* Search this block */ /* Search this block */
if ( SearchForString(WorkingBlock, BlockSearchLength, if ( SearchForString(WorkingBlock, BlockSearchLength,
SearchString, SearchStringLength) ) { SearchString, SearchStringLength) ) {
Found = 1; /* We’ve found a match */ Found = 1; /* We’ve found a match */
Done = 1; Done = 1;
} }
else { else {
@ -184,22 +184,22 @@ main(int argc, char *argv[]) {
the end of the block over to the next block */ the end of the block over to the next block */
if ( SearchStringLength &gt 1 ) { if ( SearchStringLength &gt 1 ) {
memcpy(WorkingBlock, memcpy(WorkingBlock,
WorkingBlock+BLOCK_SIZE - SearchStringLength + 1, WorkingBlock+BLOCK_SIZE - SearchStringLength + 1,
SearchStringLength - 1); SearchStringLength - 1);
} }
/* Set up to load the next bytes from the file after the /* Set up to load the next bytes from the file after the
bytes copied from the end of the current block */ bytes copied from the end of the current block */
NextLoadPtr = WorkingBlock + SearchStringLength - 1; NextLoadPtr = WorkingBlock + SearchStringLength - 1;
NextLoadCount = BLOCK_SIZE - SearchStringLength + 1; NextLoadCount = BLOCK_SIZE - SearchStringLength + 1;
} }
} }
} while ( !Done ); } while ( !Done );
/* Report the results */ /* Report the results */
if ( Found ) { if ( Found ) {
printf(“String found\n”); printf(“String found\n”);
} else { } else {
printf(“String not found\n”); printf(“String not found\n”);
} }
exit(Found); /* Return the found/not found status as the exit(Found); /* Return the found/not found status as the
DOS errorlevel */ DOS errorlevel */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -67,15 +67,15 @@ Parmsends
.code .code
public _FindString public _FindString
_FindStringprocnear _FindStringprocnear
push bp ;preserve caller’s stack frame push bp ;preserve caller’s stack frame
mov bp,sp ;point to our stack frame mov bp,sp ;point to our stack frame
push si ;preserve caller’s register variables push si ;preserve caller’s register variables
push di push di
cld ;make string instructions increment pointers cld ;make string instructions increment pointers
mov si,[bp+SearchString] ;pointer to string to search for mov si,[bp+SearchString] ;pointer to string to search for
mov cx,[bp+SearchStringLength] ;length of string mov cx,[bp+SearchStringLength] ;length of string
jcxz FindStringNotFound ;no match if string is 0 length jcxz FindStringNotFound ;no match if string is 0 length
mov dx,[bp+BufferLength] ;length of buffer mov dx,[bp+BufferLength] ;length of buffer
sub dx,cx ;difference between buffer and search sub dx,cx ;difference between buffer and search
; lengths ; lengths
jc FindStringNotFound ;no match if search string is jc FindStringNotFound ;no match if search string is
@ -85,11 +85,11 @@ _FindStringprocnear
; locations to check in the buffer) ; locations to check in the buffer)
mov di,ds mov di,ds
mov es,di mov es,di
mov di,[bp+Buffer] ;point ES:DI to buffer to search thru mov di,[bp+Buffer] ;point ES:DI to buffer to search thru
mov bx,[bp+ScanCharOffset] ;offset in string of character mov bx,[bp+ScanCharOffset] ;offset in string of character
; on which to scan ; on which to scan
add di,bx ;point ES:DI to first buffer byte to scan add di,bx ;point ES:DI to first buffer byte to scan
mov al,[si+bx] ;put the scan character in AL mov al,[si+bx] ;put the scan character in AL
inc bx ;set BX to the offset back to the start of the inc bx ;set BX to the offset back to the start of the
; potential full match after a scan match, ; potential full match after a scan match,
; accounting for the 1-byte overrun of ; accounting for the 1-byte overrun of
@ -97,7 +97,7 @@ _FindStringprocnear
FindStringLoop: FindStringLoop:
mov cx,dx ;put remaining buffer search length in CX mov cx,dx ;put remaining buffer search length in CX
repnz scasb ;scan for the scan byte repnz scasb ;scan for the scan byte
jnz FindStringNotFound ;not found, so there’s no match jnz FindStringNotFound ;not found, so there’s no match
;found, so we have a potential match-check the ;found, so we have a potential match-check the
; rest of this candidate location ; rest of this candidate location
push di ;remember the address of the next byte to scan push di ;remember the address of the next byte to scan
@ -105,18 +105,18 @@ FindStringLoop:
; the buffer ; the buffer
sub di,bx ;point back to the potential start of the sub di,bx ;point back to the potential start of the
; match in the buffer ; match in the buffer
mov si,[bp+SearchString] ;point to the start of the string mov si,[bp+SearchString] ;point to the start of the string
mov cx,[bp+SearchStringLength] ;string length mov cx,[bp+SearchStringLength] ;string length
shr cx,1 ;convert to word for faster search shr cx,1 ;convert to word for faster search
jnc FindStringWord ;do word search if no odd byte jnc FindStringWord ;do word search if no odd byte
cmpsb ;compare the odd byte cmpsb ;compare the odd byte
jnz FindStringNoMatch ;odd byte doesn’t match, so we jnz FindStringNoMatch ;odd byte doesn’t match, so we
; haven’t found the search string here ; haven’t found the search string here
FindStringWord: FindStringWord:
jcxz FindStringFound ;if the string is only 1 byte long, jcxz FindStringFound ;if the string is only 1 byte long,
; we’ve found a match ; we’ve found a match
repz cmpsw ;check the rest of the string a word at a time repz cmpsw ;check the rest of the string a word at a time
jz FindStringFound ;it’s a match jz FindStringFound ;it’s a match
FindStringNoMatch: FindStringNoMatch:
pop di ;get back pointer to the next byte to scan pop di ;get back pointer to the next byte to scan
and dx,dx ;is there anything left to check? and dx,dx ;is there anything left to check?
@ -129,9 +129,9 @@ FindStringFound:
sub ax,bx ; string was found (earlier we pushed the sub ax,bx ; string was found (earlier we pushed the
; address of the byte after the scan match) ; address of the byte after the scan match)
FindStringDone: FindStringDone:
pop di ;restore caller’s register variables pop di ;restore caller’s register variables
pop si pop si
pop bp ;restore caller’s stack frame pop bp ;restore caller’s stack frame
ret ret
_FindStringendp _FindStringendp
end end
@ -148,26 +148,26 @@ _FindStringendp
extern unsigned char * FindString(unsigned char *, unsigned int, extern unsigned char * FindString(unsigned char *, unsigned int,
unsigned char *, unsigned int, unsigned int); unsigned char *, unsigned int, unsigned int);
void main(void); void main(void);
static unsigned char TestBuffer[] = “When, in the course of human \ static unsigned char TestBuffer[] = “When, in the course of human \
events, it becomes necessary for one people to dissolve the \ events, it becomes necessary for one people to dissolve the \
political bands which have connected them with another, and to \ political bands which have connected them with another, and to \
assume among the powers of the earth the separate and equal station \ assume among the powers of the earth the separate and equal station \
to which the laws of nature and of nature’s God entitle them...”; to which the laws of nature and of nature’s God entitle them...”;
void main() { void main() {
static unsigned char TestString[] = “equal”; static unsigned char TestString[] = “equal”;
unsigned char TempBuffer[DISPLAY_LENGTH+1]; unsigned char TempBuffer[DISPLAY_LENGTH+1];
unsigned char *MatchPtr; unsigned char *MatchPtr;
/* Search for TestString and report the results */ /* Search for TestString and report the results */
if ((MatchPtr = FindString(TestBuffer, if ((MatchPtr = FindString(TestBuffer,
(unsigned int) strlen(TestBuffer), TestString, (unsigned int) strlen(TestBuffer), TestString,
(unsigned int) strlen(TestString), 1)) == NULL) { (unsigned int) strlen(TestString), 1)) == NULL) {
/* TestString wasn’t found */ /* TestString wasn’t found */
printf(“\”%s\“ not found\n”, TestString); printf(“\”%s\“ not found\n”, TestString);
} else { } else {
/* TestString was found. Zero-terminate TempBuffer; strncpy /* TestString was found. Zero-terminate TempBuffer; strncpy
won’t do it if DISPLAY_LENGTH characters are copied */ won’t do it if DISPLAY_LENGTH characters are copied */
TempBuffer[DISPLAY_LENGTH] = 0; TempBuffer[DISPLAY_LENGTH] = 0;
printf(“\”%s\“ found. Next %d characters at match:\n\”%s\“\n”, printf(“\”%s\“ found. Next %d characters at match:\n\”%s\“\n”,
TestString, DISPLAY_LENGTH, TestString, DISPLAY_LENGTH,
strncpy(TempBuffer, MatchPtr, DISPLAY_LENGTH)); strncpy(TempBuffer, MatchPtr, DISPLAY_LENGTH));
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -63,16 +63,16 @@ parms ends
public _FindString public _FindString
_FindString proc near _FindString proc near
cld cld
push bp ;preserve caller’s stack frame push bp ;preserve caller’s stack frame
mov bp,sp ;point to our stack frame mov bp,sp ;point to our stack frame
push si ;preserve caller’s register variables push si ;preserve caller’s register variables
push di push di
sub sp,256*2 ;allocate space for SkipTable sub sp,256*2 ;allocate space for SkipTable
; Create the table of distances by which to skip ahead on mismatches ; Create the table of distances by which to skip ahead on mismatches
; for every possible byte value. First, initialize all skips to the ; for every possible byte value. First, initialize all skips to the
; pattern length; this is the skip distance for bytes that don’t ; pattern length; this is the skip distance for bytes that don’t
; appear in the pattern. ; appear in the pattern.
mov ax,[bp+PatternLength] mov ax,[bp+PatternLength]
and ax,ax ;return an instant match if the pattern is and ax,ax ;return an instant match if the pattern is
jz InstantMatch ;0-length jz InstantMatch ;0-length
mov di,ds mov di,ds
@ -81,23 +81,23 @@ _FindString proc near
mov cx,256 mov cx,256
rep stosw rep stosw
dec ax ;from now on, we only need dec ax ;from now on, we only need
mov [bp+PatternLength],ax ; PatternLength - 1 mov [bp+PatternLength],ax ; PatternLength - 1
; Point to last (rightmost) byte of first potential pattern match ; Point to last (rightmost) byte of first potential pattern match
; location in buffer. ; location in buffer.
add [bp+BufferPtr],ax add [bp+BufferPtr],ax
; Reject if buffer is too small, and set the count of the number of ; Reject if buffer is too small, and set the count of the number of
; potential pattern match locations in the buffer. ; potential pattern match locations in the buffer.
sub [bp+BufferLength],ax sub [bp+BufferLength],ax
jbe NoMatch jbe NoMatch
; Set the skip values for the bytes that do appear in the pattern to ; Set the skip values for the bytes that do appear in the pattern to
; the distance from the byte location to the end of the pattern. ; the distance from the byte location to the end of the pattern.
; When there are multiple instances of the same byte, the rightmost ; When there are multiple instances of the same byte, the rightmost
; instance’s skip value is used. Note that the rightmost byte of the ; instance’s skip value is used. Note that the rightmost byte of the
; pattern isn’t entered in the skip table; if we get that value for ; pattern isn’t entered in the skip table; if we get that value for
; a mismatch, we know for sure that the right end of the pattern has ; a mismatch, we know for sure that the right end of the pattern has
; already passed the mismatch location, so this is not a relevant byte ; already passed the mismatch location, so this is not a relevant byte
; for skipping purposes. ; for skipping purposes.
mov si,[bp+PatternPtr] ;point to start of pattern mov si,[bp+PatternPtr] ;point to start of pattern
and ax,ax ;are there any skips to set? and ax,ax ;are there any skips to set?
jz SetSkipDone ;no jz SetSkipDone ;no
mov di,sp ;point to SkipBuffer mov di,sp ;point to SkipBuffer
@ -106,57 +106,57 @@ SetSkipLoop:
mov bl,[si] ;get the next pattern byte mov bl,[si] ;get the next pattern byte
inc si ;advance the pattern pointer inc si ;advance the pattern pointer
shl bx,1 ;prepare for word lookup shl bx,1 ;prepare for word lookup
mov [di+bx],ax ;set the skip value when this byte value is mov [di+bx],ax ;set the skip value when this byte value is
; the mismatch value in the buffer ; the mismatch value in the buffer
dec ax dec ax
jnz SetSkipLoop jnz SetSkipLoop
SetSkipDone: SetSkipDone:
mov dl,[si] ;DL=rightmost pattern byte from now on mov dl,[si] ;DL=rightmost pattern byte from now on
dec si ;point to next-to-rightmost byte of pattern dec si ;point to next-to-rightmost byte of pattern
mov [bp+PatternPtr],si ; from now on mov [bp+PatternPtr],si ; from now on
; Search the buffer. ; Search the buffer.
std ;for backward REPZ CMPSB std ;for backward REPZ CMPSB
mov di,[bp+BufferPtr] ;point to first search location mov di,[bp+BufferPtr] ;point to first search location
mov cx,[bp+BufferLength] ;# of match locations to check mov cx,[bp+BufferLength] ;# of match locations to check
SearchLoop: SearchLoop:
mov si,sp ;point SI to SkipTable mov si,sp ;point SI to SkipTable
; Skip through until there’s a match for the rightmost pattern byte. ; Skip through until there’s a match for the rightmost pattern byte.
QuickSearchLoop: QuickSearchLoop:
mov bl,[di] ;rightmost buffer byte at this location mov bl,[di] ;rightmost buffer byte at this location
cmp dl,bl ;does it match the rightmost pattern byte? cmp dl,bl ;does it match the rightmost pattern byte?
jz FullCompare ;yes, so keep going jz FullCompare ;yes, so keep going
sub bh,bh ;convert to a word sub bh,bh ;convert to a word
add bx,bx ;prepare for look-up in SkipTable add bx,bx ;prepare for look-up in SkipTable
mov ax,[si+bx] ;get skip value from skip table for this mov ax,[si+bx] ;get skip value from skip table for this
; mismatch value ; mismatch value
add di,ax ;BufferPtr += Skip; add di,ax ;BufferPtr += Skip;
sub cx,ax ;BufferLength -= Skip; sub cx,ax ;BufferLength -= Skip;
ja QuickSearchLoop ;continue if any buffer left ja QuickSearchLoop ;continue if any buffer left
jmp short NoMatch jmp short NoMatch
; Return a pointer to the start of the buffer (for 0-length pattern). ; Return a pointer to the start of the buffer (for 0-length pattern).
align 2 align 2
InstantMatch: InstantMatch:
mov ax,[bp+BufferPtr] mov ax,[bp+BufferPtr]
jmp short Done jmp short Done
; Compare the pattern and the buffer location, searching from high ; Compare the pattern and the buffer location, searching from high
; memory toward low (right to left). ; memory toward low (right to left).
align 2 align 2
FullCompare: FullCompare:
mov [bp+BufferPtr],di ;save the current state of mov [bp+BufferPtr],di ;save the current state of
mov [bp+BufferLength],cx ; the search mov [bp+BufferLength],cx ; the search
mov cx,[bp+PatternLength] ;# of bytes yet to compare mov cx,[bp+PatternLength] ;# of bytes yet to compare
jcxz Match ;done if only one character jcxz Match ;done if only one character
mov si,[bp+PatternPtr] ;point to next-to-rightmost bytes mov si,[bp+PatternPtr] ;point to next-to-rightmost bytes
dec di ; of buffer location and pattern dec di ; of buffer location and pattern
repz cmpsb ;compare the rest of the pattern repz cmpsb ;compare the rest of the pattern
jz Match ;that’s it; we’ve found a match jz Match ;that’s it; we’ve found a match
; It’s a mismatch; let’s see what we can learn from it. ; It’s a mismatch; let’s see what we can learn from it.
inc di ;compensate for 1-byte overrun of REPZ CMPSB; inc di ;compensate for 1-byte overrun of REPZ CMPSB;
; point to mismatch location in buffer ; point to mismatch location in buffer
; # of bytes that did match. ; # of bytes that did match.
mov si,[bp+BufferPtr] mov si,[bp+BufferPtr]
sub si,di sub si,di
; If, based on the mismatch character, we can’t even skip ahead as far ; If, based on the mismatch character, we can’t even skip ahead as far
; as where we started this particular comparison, then just advance by ; as where we started this particular comparison, then just advance by
; 1 to the next potential match; otherwise, skip ahead from this ; 1 to the next potential match; otherwise, skip ahead from this
; comparison location by the skip distance for the mismatch character, ; comparison location by the skip distance for the mismatch character,
@ -166,18 +166,18 @@ FullCompare:
add bx,bx ;prepare for word look-up add bx,bx ;prepare for word look-up
add bx,sp ;SP points to SkipTable add bx,sp ;SP points to SkipTable
mov cx,[bx] ;get the skip value for this mismatch mov cx,[bx] ;get the skip value for this mismatch
mov ax,1 ;assume we’ll just advance to the next mov ax,1 ;assume we’ll just advance to the next
; potential match location ; potential match location
sub cx,si ;is the skip far enough to be worth taking? sub cx,si ;is the skip far enough to be worth taking?
jna MoveAhead ;no, go with the default advance of 1 jna MoveAhead ;no, go with the default advance of 1
mov ax,cx ;yes; this is the distance to skip ahead from mov ax,cx ;yes; this is the distance to skip ahead from
; the last potential match location checked ; the last potential match location checked
MoveAhead: MoveAhead:
; Skip ahead and perform the next comparison, if there’s any buffer ; Skip ahead and perform the next comparison, if there’s any buffer
; left to check. ; left to check.
mov di,[bp+BufferPtr] mov di,[bp+BufferPtr]
add di,ax ;BufferPtr += Skip; add di,ax ;BufferPtr += Skip;
mov cx,[bp+BufferLength] mov cx,[bp+BufferLength]
sub cx,ax ;BufferLength -= Skip; sub cx,ax ;BufferLength -= Skip;
ja SearchLoop ;continue if any buffer left ja SearchLoop ;continue if any buffer left
; Return a NULL pointer for no match. ; Return a NULL pointer for no match.
@ -188,14 +188,14 @@ NoMatch:
; Return start of match in buffer (BufferPtr - (PatternLength - 1)). ; Return start of match in buffer (BufferPtr - (PatternLength - 1)).
align 2 align 2
Match: Match:
mov ax,[bp+BufferPtr] mov ax,[bp+BufferPtr]
sub ax,[bp+PatternLength] sub ax,[bp+PatternLength]
Done: Done:
cld ;restore default direction flag cld ;restore default direction flag
add sp,256*2 ;deallocate space for SkipTable add sp,256*2 ;deallocate space for SkipTable
pop di ;restore caller’s register variables pop di ;restore caller’s register variables
pop si pop si
pop bp ;restore caller’s stack frame pop bp ;restore caller’s stack frame
ret ret
_FindString endp _FindString endp
end end

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -106,7 +106,7 @@
COMMENT $ COMMENT $
How it works How it works
—————— ——————
The idea is to go through the buffer fetching each letter-pair (words The idea is to go through the buffer fetching each letter-pair (words
rather than bytes). The carry flag indicates whether we are rather than bytes). The carry flag indicates whether we are
currently in a (text) word or not. The letter-pair fetched from the currently in a (text) word or not. The letter-pair fetched from the
@ -127,7 +127,7 @@ repeated. Finally, the carry flag is saved to indicate the final
in-a-word/not-in-a-word status. The count register is masked to in-a-word/not-in-a-word status. The count register is masked to
remove the high bit and the count of words remains in the count remove the high bit and the count of words remains in the count
register. register.
Sound complicated? You’re right! But it’s fast! Sound complicated? You’re right! But it’s fast!
The beauty of this method is that no jumps are required, the The beauty of this method is that no jumps are required, the
operations are fast, it requires only one table and the process can operations are fast, it requires only one table and the process can
@ -139,14 +139,14 @@ jumping.
.code .code
Test1 macro x,y ;9 or 10 bytes Test1 macro x,y ;9 or 10 bytes
Addr&ampx: mov di,[bp+y] ;3 or 4 bytes Addr&ampx: mov di,[bp+y] ;3 or 4 bytes
adc di,di adc di,di
or ax,si or ax,si
add al,[di] add al,[di]
endm endm
Test2 macro x,y ;7 or 8 bytes Test2 macro x,y ;7 or 8 bytes
Addr&ampx: mov di,[bp+y] ;3 or 4 bytes Addr&ampx: mov di,[bp+y] ;3 or 4 bytes
adc di,di adc di,di
add ah,[di] add ah,[di]
endm endm
@ -165,18 +165,18 @@ jumping.
push di push di
xor cx,cx xor cx,cx
mov si,[bp+Buffer] ;si = text buffer mov si,[bp+Buffer] ;si = text buffer
mov ax,[bp+BufferLength] ;dx = length in bytes mov ax,[bp+BufferLength] ;dx = length in bytes
shr ax,1 ;dx = length in words shr ax,1 ;dx = length in words
jnz NormalBuf jnz NormalBuf
OneByteBuf: OneByteBuf:
mov ax,seg WordTable mov ax,seg WordTable
mov es,ax mov es,ax
mov di,[bp+CharFlag] mov di,[bp+CharFlag]
mov bh,[di] ;bh = old CharFlag mov bh,[di] ;bh = old CharFlag
mov bl,[si] ;bl = character mov bl,[si] ;bl = character
add bh,‘A’-1 ;make bh into character add bh,‘A’-1 ;make bh into character
add bx,bx ;prepare to index add bx,bx ;prepare to index
mov al,es:[bx] mov al,es:[bx]
cbw ;get hi bit in ah (then bh) cbw ;get hi bit in ah (then bh)
@ -203,7 +203,7 @@ jumping.
mov di,LoopEntry[bx] ;...address in di mov di,LoopEntry[bx] ;...address in di
xchg dx,ax ;dx is the loop counter xchg dx,ax ;dx is the loop counter
xor cx,cx ;total word count xor cx,cx ;total word count
mov bx,[bp+CharFlag] mov bx,[bp+CharFlag]
mov bl,[bx] ;bl = old CharFlag mov bl,[bx] ;bl = old CharFlag
mov bp,seg WordTable mov bp,seg WordTable
mov ds,bp mov ds,bp
@ -218,12 +218,12 @@ jumping.
n = 0 n = 0
rept Scan/2 rept Scan/2
Test1 %n,%n*2 Test1 %n,%n*2
Test2 %n+1,%n*2+2 Test2 %n+1,%n*2+2
n = n+2 n = n+2
endm endm
EndCount: EndCount:
sbb bx,bx ;save carry sbb bx,bx ;save carry
if Scan ge 128 ;because al+ah may equal 128! if Scan ge 128 ;because al+ah may equal 128!
or ax,si or ax,si
add al,ah add al,ah
mov ah,0 mov ah,0
@ -250,11 +250,11 @@ jumping.
pop ds pop ds
pop bp ;(1) pop bp ;(1)
CleanUp: CleanUp:
mov si,[bp+WordCount] mov si,[bp+WordCount]
add [si],cx add [si],cx
adc word ptr [si+2],0 adc word ptr [si+2],0
and bh,1 ;save only the carry flag and bh,1 ;save only the carry flag
mov si,[bp+CharFlag] mov si,[bp+CharFlag]
mov [si],bh mov [si],bh
pop di pop di
pop si pop si

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -39,9 +39,9 @@
<P><B>LISTING 17.1 L17-1.CPP</B></P> <P><B>LISTING 17.1 L17-1.CPP</B></P>
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
/* C&#43;&#43; Game of Life implementation for any mode for which mode set /* C++ Game of Life implementation for any mode for which mode set
and draw pixel functions can be provided. and draw pixel functions can be provided.
Tested with Borland C&#43;&#43; in the small model. */ Tested with Borland C++ in the small model. */
#include &ltstdlib.h&gt #include &ltstdlib.h&gt
#include &ltstdio.h&gt #include &ltstdio.h&gt
#include &ltiostream.h&gt #include &ltiostream.h&gt
@ -100,30 +100,30 @@ void main()
cellmap next_map(cellmap_height, cellmap_width); cellmap next_map(cellmap_height, cellmap_width);
// Get the seed; seed randomly if 0 entered // Get the seed; seed randomly if 0 entered
cout &lt&lt &#147;Seed (0 for random seed): &#148;; cout &lt&lt &ldquo;Seed (0 for random seed): &rdquo;;
cin &gt&gt seed; cin &gt&gt seed;
if (seed == 0) seed = (unsigned) time(NULL); if (seed == 0) seed = (unsigned) time(NULL);
// Randomly initialize the initial cell map // Randomly initialize the initial cell map
cout &lt&lt &#147;Initializing...&#148;; cout &lt&lt &ldquo;Initializing...&rdquo;;
srand(seed); srand(seed);
init_length = (cellmap_height * cellmap_width) / 2; init_length = (cellmap_height * cellmap_width) / 2;
do { do {
x = random(cellmap_width); x = random(cellmap_width);
y = random(cellmap_height); y = random(cellmap_height);
next_map.set_cell(x, y); next_map.set_cell(x, y);
} while (&#151;init_length); } while (&mdash;init_length);
current_map.copy_cells(next_map); // put init map in current_map current_map.copy_cells(next_map); // put init map in current_map
enter_display_mode(); enter_display_mode();
// Keep recalculating and redisplaying generations until a key // Keep recalculating and redisplaying generations until a key
// is pressed // is pressed
show_text(0, MSG_LINE, &#147;Generation: &#148;); show_text(0, MSG_LINE, &ldquo;Generation: &rdquo;);
start_bios_time = _bios_timeofday(_TIME_GETCLOCK, &ampbios_time); start_bios_time = _bios_timeofday(_TIME_GETCLOCK, &ampbios_time);
do { do {
generation&#43;&#43;; generation++;
sprintf(gen_text, &#147;%10lu&#148;, generation); sprintf(gen_text, &ldquo;%10lu&rdquo;, generation);
show_text(1, GENERATION_LINE, gen_text); show_text(1, GENERATION_LINE, gen_text);
// Recalculate and draw the next generation // Recalculate and draw the next generation
current_map.next_generation(next_map); current_map.next_generation(next_map);
@ -139,15 +139,15 @@ void main()
} while (!kbhit()); } while (!kbhit());
getch(); // clear keypress getch(); // clear keypress
exit_display_mode(); exit_display_mode();
cout &lt&lt &#147;Total generations: &#148; &lt&lt generation &lt&lt &#147;\nSeed: &#148; &lt&lt cout &lt&lt &ldquo;Total generations: &rdquo; &lt&lt generation &lt&lt &ldquo;\nSeed: &rdquo; &lt&lt
seed &lt&lt &#147;\n&#148;; seed &lt&lt &ldquo;\n&rdquo;;
} }
/* cellmap constructor. */ /* cellmap constructor. */
cellmap::cellmap(unsigned int h, unsigned int w) cellmap::cellmap(unsigned int h, unsigned int w)
{ {
width = w; width = w;
width_in_bytes = (w &#43; 7) / 8; width_in_bytes = (w + 7) / 8;
height = h; height = h;
length_in_bytes = width_in_bytes * h; length_in_bytes = width_in_bytes * h;
cells = new unsigned char[length_in_bytes]; // cell storage cells = new unsigned char[length_in_bytes]; // cell storage
@ -160,7 +160,7 @@ cellmap::~cellmap(void)
delete[] cells; delete[] cells;
} }
/* Copies one cellmap&#146;s cells to another cellmap. Both cellmaps are /* Copies one cellmap&rsquo;s cells to another cellmap. Both cellmaps are
assumed to be the same size. */ assumed to be the same size. */
void cellmap::copy_cells(cellmap &ampsourcemap) void cellmap::copy_cells(cellmap &ampsourcemap)
{ {
@ -171,7 +171,7 @@ void cellmap::copy_cells(cellmap &ampsourcemap)
void cellmap::set_cell(unsigned int x, unsigned int y) void cellmap::set_cell(unsigned int x, unsigned int y)
{ {
unsigned char *cell_ptr = unsigned char *cell_ptr =
cells &#43; (y * width_in_bytes) &#43; (x / 8); cells + (y * width_in_bytes) + (x / 8);
*(cell_ptr) |= 0x80 &gt&gt (x &amp 0x07); *(cell_ptr) |= 0x80 &gt&gt (x &amp 0x07);
} }
@ -180,7 +180,7 @@ void cellmap::set_cell(unsigned int x, unsigned int y)
void cellmap::clear_cell(unsigned int x, unsigned int y) void cellmap::clear_cell(unsigned int x, unsigned int y)
{ {
unsigned char *cell_ptr = unsigned char *cell_ptr =
cells &#43; (y * width_in_bytes) &#43; (x / 8); cells + (y * width_in_bytes) + (x / 8);
*(cell_ptr) &amp= ~(0x80 &gt&gt (x &amp 0x07)); *(cell_ptr) &amp= ~(0x80 &gt&gt (x &amp 0x07));
} }
@ -192,15 +192,15 @@ int cellmap::cell_state(int x, int y)
unsigned char *cell_ptr; unsigned char *cell_ptr;
#if WRAP_EDGES #if WRAP_EDGES
while (x &lt 0) x &#43;= width; // wrap, if necessary while (x &lt 0) x += width; // wrap, if necessary
while (x &gt= width) x -= width; while (x &gt= width) x -= width;
while (y &lt 0) y &#43;= height; while (y &lt 0) y += height;
while (y &gt= height) y -= height; while (y &gt= height) y -= height;
#else #else
if ((x &lt 0) || (x &gt= width) || (y &lt 0) || (y &gt= height)) if ((x &lt 0) || (x &gt= width) || (y &lt 0) || (y &gt= height))
return 0; // return 0 for off edges if no wrapping return 0; // return 0 for off edges if no wrapping
#endif #endif
cell_ptr = cells &#43; (y * width_in_bytes) &#43; (x / 8); cell_ptr = cells + (y * width_in_bytes) + (x / 8);
return (*cell_ptr &amp (0x80 &gt&gt (x &amp 0x07))) ? 1 : 0; return (*cell_ptr &amp (0x80 &gt&gt (x &amp 0x07))) ? 1 : 0;
} }
@ -210,13 +210,13 @@ void cellmap::next_generation(cellmap&amp next_map)
{ {
unsigned int x, y, neighbor_count; unsigned int x, y, neighbor_count;
for (y=0; y&ltheight; y&#43;&#43;) { for (y=0; y&ltheight; y++) {
for (x=0; x&ltwidth; x&#43;&#43;) { for (x=0; x&ltwidth; x++) {
// Figure out how many neighbors this cell has // Figure out how many neighbors this cell has
neighbor_count = cell_state(x-1, y-1) &#43; cell_state(x, y-1) &#43; neighbor_count = cell_state(x-1, y-1) + cell_state(x, y-1) +
cell_state(x&#43;1, y-1) &#43; cell_state(x-1, y) &#43; cell_state(x+1, y-1) + cell_state(x-1, y) +
cell_state(x&#43;1, y) &#43; cell_state(x-1, y&#43;1) &#43; cell_state(x+1, y) + cell_state(x-1, y+1) +
cell_state(x, y&#43;1) &#43; cell_state(x&#43;1, y&#43;1); cell_state(x, y+1) + cell_state(x+1, y+1);
if (cell_state(x, y) == 1) { if (cell_state(x, y) == 1) {
// The cell is on; does it stay on? // The cell is on; does it stay on?
if ((neighbor_count != 2) &amp&amp (neighbor_count != 3)) { if ((neighbor_count != 2) &amp&amp (neighbor_count != 3)) {
@ -239,7 +239,7 @@ void cellmap::next_generation(cellmap&amp next_map)
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
/* VGA mode 13h functions for Game of Life. /* VGA mode 13h functions for Game of Life.
Tested with Borland C&#43;&#43;. */ Tested with Borland C++. */
#include &ltstdio.h&gt #include &ltstdio.h&gt
#include &ltconio.h&gt #include &ltconio.h&gt
#include &ltdos.h&gt #include &ltdos.h&gt
@ -260,12 +260,12 @@ void draw_pixel(unsigned int x, unsigned int y, unsigned int color)
FP_SEG(screen_ptr) = SCREEN_SEGMENT; FP_SEG(screen_ptr) = SCREEN_SEGMENT;
FP_OFF(screen_ptr) = FP_OFF(screen_ptr) =
y * magnifier * SCREEN_WIDTH_IN_BYTES &#43; x * magnifier; y * magnifier * SCREEN_WIDTH_IN_BYTES + x * magnifier;
for (i=0; i&ltmagnifier; i&#43;&#43;) { for (i=0; i&ltmagnifier; i++) {
for (j=0; j&ltmagnifier; j&#43;&#43;) { for (j=0; j&ltmagnifier; j++) {
*(screen_ptr&#43;j) = color; *(screen_ptr+j) = color;
} }
screen_ptr &#43;= SCREEN_WIDTH_IN_BYTES; screen_ptr += SCREEN_WIDTH_IN_BYTES;
} }
} }
@ -291,7 +291,7 @@ void exit_display_mode()
screen. */ screen. */
void show_text(int x, int y, char *text) void show_text(int x, int y, char *text)
{ {
gotoxy(TEXT_X_OFFSET &#43; x, y); gotoxy(TEXT_X_OFFSET + x, y);
puts(text); puts(text);
} }
</PRE> </PRE>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -39,12 +39,12 @@
<P><B>LISTING 17.5 L17-5.CPP</B></P> <P><B>LISTING 17.5 L17-5.CPP</B></P>
<!-- CODE //--> <!-- CODE //-->
<PRE> <PRE>
/* C&#43;&#43; Game of Life implementation for any mode for which mode set /* C++ Game of Life implementation for any mode for which mode set
and draw pixel functions can be provided. The cellmap stores the and draw pixel functions can be provided. The cellmap stores the
neighbor count for each cell as well as the state of each cell; neighbor count for each cell as well as the state of each cell;
this allows very fast next-state determination. Edges always wrap this allows very fast next-state determination. Edges always wrap
in this implementation. in this implementation.
Tested with Borland C&#43;&#43;. To run, link with Listing 17.2 Tested with Borland C++. To run, link with Listing 17.2
in the large model. */ in the large model. */
#include &ltstdlib.h&gt #include &ltstdlib.h&gt
#include &ltstdio.h&gt #include &ltstdio.h&gt
@ -111,11 +111,11 @@ void main()
// Keep recalculating and redisplaying generations until any key // Keep recalculating and redisplaying generations until any key
// is pressed // is pressed
show_text(0, MSG_LINE, &#147;Generation: &#148;); show_text(0, MSG_LINE, &ldquo;Generation: &rdquo;);
start_bios_time = _bios_timeofday(_TIME_GETCLOCK, &ampbios_time); start_bios_time = _bios_timeofday(_TIME_GETCLOCK, &ampbios_time);
do { do {
generation&#43;&#43;; generation++;
sprintf(gen_text, &#147;%10lu&#148;, generation); sprintf(gen_text, &ldquo;%10lu&rdquo;, generation);
show_text(1, GENERATION_LINE, gen_text); show_text(1, GENERATION_LINE, gen_text);
// Recalculate and draw the next generation // Recalculate and draw the next generation
current_map.next_generation(); current_map.next_generation();
@ -130,8 +130,8 @@ void main()
getch(); // clear keypress getch(); // clear keypress
exit_display_mode(); exit_display_mode();
cout &lt&lt &#147;Total generations: &#148; &lt&lt generation &lt&lt &#147;\nSeed: &#148; &lt&lt cout &lt&lt &ldquo;Total generations: &rdquo; &lt&lt generation &lt&lt &ldquo;\nSeed: &rdquo; &lt&lt
seed &lt&lt &#147;\n&#148;; seed &lt&lt &ldquo;\n&rdquo;;
} }
/* cellmap constructor. */ /* cellmap constructor. */
@ -143,7 +143,7 @@ cellmap::cellmap(unsigned int h, unsigned int w)
cells = new unsigned char[length_in_bytes]; // cell storage cells = new unsigned char[length_in_bytes]; // cell storage
temp_cells = new unsigned char[length_in_bytes]; // temp cell storage temp_cells = new unsigned char[length_in_bytes]; // temp cell storage
if ( (cells == NULL) || (temp_cells == NULL) ) { if ( (cells == NULL) || (temp_cells == NULL) ) {
printf(&#147;Out of memory\n&#148;); printf(&ldquo;Out of memory\n&rdquo;);
exit(1); exit(1);
} }
memset(cells, 0, length_in_bytes); // clear all cells, to start memset(cells, 0, length_in_bytes); // clear all cells, to start
@ -162,7 +162,7 @@ void cellmap::set_cell(unsigned int x, unsigned int y)
{ {
unsigned int w = width, h = height; unsigned int w = width, h = height;
int xoleft, xoright, yoabove, yobelow; int xoleft, xoright, yoabove, yobelow;
unsigned char *cell_ptr = cells &#43; (y * w) &#43; x; unsigned char *cell_ptr = cells + (y * w) + x;
// Calculate the offsets to the eight neighboring cells, // Calculate the offsets to the eight neighboring cells,
// accounting for wrapping around at the edges of the cell map // accounting for wrapping around at the edges of the cell map
@ -184,14 +184,14 @@ void cellmap::set_cell(unsigned int x, unsigned int y)
yobelow = w; yobelow = w;
*(cell_ptr) |= 0x01; *(cell_ptr) |= 0x01;
*(cell_ptr &#43; yoabove &#43; xoleft) &#43;= 2; *(cell_ptr + yoabove + xoleft) += 2;
*(cell_ptr &#43; yoabove) &#43;= 2; *(cell_ptr + yoabove) += 2;
*(cell_ptr &#43; yoabove &#43; xoright) &#43;= 2; *(cell_ptr + yoabove + xoright) += 2;
*(cell_ptr &#43; xoleft) &#43;= 2; *(cell_ptr + xoleft) += 2;
*(cell_ptr &#43; xoright) &#43;= 2; *(cell_ptr + xoright) += 2;
*(cell_ptr &#43; yobelow &#43; xoleft) &#43;= 2; *(cell_ptr + yobelow + xoleft) += 2;
*(cell_ptr &#43; yobelow) &#43;= 2; *(cell_ptr + yobelow) += 2;
*(cell_ptr &#43; yobelow &#43; xoright) &#43;= 2; *(cell_ptr + yobelow + xoright) += 2;
} }
/* Turns an on-cell off, decrementing the on-neighbor count for the /* Turns an on-cell off, decrementing the on-neighbor count for the
@ -200,7 +200,7 @@ void cellmap::clear_cell(unsigned int x, unsigned int y)
{ {
unsigned int w = width, h = height; unsigned int w = width, h = height;
int xoleft, xoright, yoabove, yobelow; int xoleft, xoright, yoabove, yobelow;
unsigned char *cell_ptr = cells &#43; (y * w) &#43; x; unsigned char *cell_ptr = cells + (y * w) + x;
// Calculate the offsets to the eight neighboring cells, // Calculate the offsets to the eight neighboring cells,
// accounting for wrapping around at the edges of the cell map // accounting for wrapping around at the edges of the cell map
@ -222,14 +222,14 @@ void cellmap::clear_cell(unsigned int x, unsigned int y)
yobelow = w; yobelow = w;
*(cell_ptr) &amp= ~0x01; *(cell_ptr) &amp= ~0x01;
*(cell_ptr &#43; yoabove &#43; xoleft) -= 2; *(cell_ptr + yoabove + xoleft) -= 2;
*(cell_ptr &#43; yoabove ) -= 2; *(cell_ptr + yoabove ) -= 2;
*(cell_ptr &#43; yoabove &#43; xoright) -= 2; *(cell_ptr + yoabove + xoright) -= 2;
*(cell_ptr &#43; xoleft) -= 2; *(cell_ptr + xoleft) -= 2;
*(cell_ptr &#43; xoright) -= 2; *(cell_ptr + xoright) -= 2;
*(cell_ptr &#43; yobelow &#43; xoleft) -= 2; *(cell_ptr + yobelow + xoleft) -= 2;
*(cell_ptr &#43; yobelow) -= 2; *(cell_ptr + yobelow) -= 2;
*(cell_ptr &#43; yobelow &#43; xoright) -= 2; *(cell_ptr + yobelow + xoright) -= 2;
} }
/* Returns cell state (1=on or 0=off). */ /* Returns cell state (1=on or 0=off). */
@ -237,7 +237,7 @@ int cellmap::cell_state(int x, int y)
{ {
unsigned char *cell_ptr; unsigned char *cell_ptr;
cell_ptr = cells &#43; (y * width) &#43; x; cell_ptr = cells + (y * width) + x;
return *cell_ptr &amp 0x01; return *cell_ptr &amp 0x01;
} }
@ -254,21 +254,21 @@ void cellmap::next_generation()
// Process all cells in the current cell map // Process all cells in the current cell map
cell_ptr = temp_cells; // first cell in cell map cell_ptr = temp_cells; // first cell in cell map
for (y=0; y&lth; y&#43;&#43;) { // repeat for each row of cells for (y=0; y&lth; y++) { // repeat for each row of cells
// Process all cells in the current row of the cell map // Process all cells in the current row of the cell map
x = 0; x = 0;
do { // repeat for each cell in row do { // repeat for each cell in row
// Zip quickly through as many off-cells with no // Zip quickly through as many off-cells with no
// neighbors as possible // neighbors as possible
while (*cell_ptr == 0) { while (*cell_ptr == 0) {
cell_ptr&#43;&#43;; // advance to the next cell cell_ptr++; // advance to the next cell
if (&#43;&#43;x &gt= w) goto RowDone; if (++x &gt= w) goto RowDone;
} }
// Found a cell that&#146;s either on or has on-neighbors, // Found a cell that&rsquo;s either on or has on-neighbors,
// so see if its state needs to be changed // so see if its state needs to be changed
count = *cell_ptr &gt&gt 1; // # of neighboring on-cells count = *cell_ptr &gt&gt 1; // # of neighboring on-cells
if (*cell_ptr &amp 0x01) { if (*cell_ptr &amp 0x01) {
// Cell is on; turn it off if it doesn&#146;t have // Cell is on; turn it off if it doesn&rsquo;t have
// 2 or 3 neighbors // 2 or 3 neighbors
if ((count != 2) &amp&amp (count != 3)) { if ((count != 2) &amp&amp (count != 3)) {
clear_cell(x, y); clear_cell(x, y);
@ -282,8 +282,8 @@ void cellmap::next_generation()
} }
} }
// Advance to the next cell // Advance to the next cell
cell_ptr&#43;&#43;; // advance to the next cell byte cell_ptr++; // advance to the next cell byte
} while (&#43;&#43;x &lt w); } while (++x &lt w);
RowDone: RowDone:
} }
} }
@ -294,14 +294,14 @@ void cellmap::init()
unsigned int x, y, init_length; unsigned int x, y, init_length;
// Get the seed; seed randomly if 0 entered // Get the seed; seed randomly if 0 entered
cout &lt&lt &#147;Seed (0 for random seed): &#148;; cout &lt&lt &ldquo;Seed (0 for random seed): &rdquo;;
cin &gt&gt seed; cin &gt&gt seed;
if (seed == 0) seed = (unsigned) time(NULL); if (seed == 0) seed = (unsigned) time(NULL);
// Randomly initialize the initial cell map to 50% on-pixels // Randomly initialize the initial cell map to 50% on-pixels
// (actually generally fewer, because some coordinates will be // (actually generally fewer, because some coordinates will be
// randomly selected more than once) // randomly selected more than once)
cout &lt&lt &#147;Initializing...&#148;; cout &lt&lt &ldquo;Initializing...&rdquo;;
srand(seed); srand(seed);
init_length = (height * width) / 2; init_length = (height * width) / 2;
do { do {
@ -310,7 +310,7 @@ void cellmap::init()
if (cell_state(x, y) == 0) { if (cell_state(x, y) == 0) {
set_cell(x, y); set_cell(x, y);
} }
} while (&#151;init_length); } while (&mdash;init_length);
} }
</PRE> </PRE>
<!-- END CODE //--> <!-- END CODE //-->

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show more