458 lines
22 KiB
HTML
458 lines
22 KiB
HTML
|
|
|
||
|
|
<!-- saved from url=(0052)https://www.atarimagazines.com/v1n2/forthfactory.php -->
|
||
|
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
|
|
<title>Forth Factory: Utilities</title>
|
||
|
|
<meta name="Author" content="Bob Gonsalves">
|
||
|
|
<meta name="description" content="Forth Factory: Utilities. From Antic Vol. 1, No. 2 / June 1982">
|
||
|
|
</head>
|
||
|
|
|
||
|
|
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#800080" alink="#FF0000"><pre><a href="https://www.atarimagazines.com/antic/"><img src="./Atari-Forth Factory-Utilities_files/antic.gif" height="46" width="152" alt="Classic Computer Magazine Archive" align="center" border="0"></a> ANTIC VOL. 1, NO. 2 / JUNE 1982</pre><hr>
|
||
|
|
|
||
|
|
|
||
|
|
<div name="topadholder" id="topadholder" style="display: block; min-width:800px; text-align:left;padding:25px 10px 10px 20px;line-height:9.5pt;clear:both;"></div>
|
||
|
|
<table style="zoom:1; min-width:800px; border-width: 1px; border-spacing: 2px; border-style: dotted; border-color: gray; border-collapse: separate;">
|
||
|
|
<tbody><tr><td style="vertical-align:top; zoom:1; min-width:400px;">
|
||
|
|
<div id="main_article" name="main_article" style="zoom: 1; min-width:400px;">
|
||
|
|
<div id="spacer" style="width:400px;"></div>
|
||
|
|
|
||
|
|
<h2>FORTH FACTORY</h2>
|
||
|
|
|
||
|
|
<h1>Utilities</h1>
|
||
|
|
|
||
|
|
<p><i>by Bob Gonsalves</i></p>
|
||
|
|
|
||
|
|
<p>In this installment we'll present some utility definitions that you may
|
||
|
|
easily add to your system. The first set of words can be used in many Forth
|
||
|
|
systems, the second set are designed to access the Atari disk file management
|
||
|
|
system. </p>
|
||
|
|
|
||
|
|
<p><b>SOME QUICKIES</b></p>
|
||
|
|
|
||
|
|
<p>Screen 30 shows some useful extensions to fig-Forth systems. Following
|
||
|
|
/, all characters on a line will be ignored; the text following the / is
|
||
|
|
used for commenting. NOT is used to reverse the logical state of the top
|
||
|
|
stack item and is often used before conditional testing words, such as IF,
|
||
|
|
UNTIL.</p>
|
||
|
|
|
||
|
|
<p>Another group of words facilitates operations on bytes in 16-bit word.
|
||
|
|
LSBYTE will leave the least significant byte of the top stack value, while
|
||
|
|
MSBYTE leaves the most significant byte. >< uses these two operations
|
||
|
|
to reverse the two halves of a 16-bit stack value.</p>
|
||
|
|
|
||
|
|
<p>Our final category introduces a new data type. The 'TO' type variable,
|
||
|
|
introduced by Paul Bartholdi in Forth Dimensions, improves readability and
|
||
|
|
reliability of Forth programs by reducing the number of @ (fetch) and !
|
||
|
|
(store) operations that must be included in the source text. If the VAR
|
||
|
|
defined variable is preceded by TO, a stack parameter will be stored in
|
||
|
|
the variable. Otherwise, the variable simply leaves its contents. The following
|
||
|
|
should illustrate:</p>
|
||
|
|
|
||
|
|
<p><tt>0 VAR temp.cell / our specific instance<br>
|
||
|
|
20 TO temp.cell / store 20 in the variable <br>
|
||
|
|
temp.cell . 20/ prints the contents of temp.cell</tt></p>
|
||
|
|
|
||
|
|
<p><b>FMS 'n' FIELDS</b></p>
|
||
|
|
|
||
|
|
<p>With extensions such as these, we're now ready to suggest some ways of
|
||
|
|
accessing FMS formatted files. As shown in figure 1, both the FMS directory
|
||
|
|
entries and the individual sectors of a FMS file share a similar structure.
|
||
|
|
They both feature range of disk space, with certain bytes or 16-bit words
|
||
|
|
having specific significance. In the case of a directory entry, locations
|
||
|
|
are used to store the state of the file (open, closed, etc), its length
|
||
|
|
and starting sector, plus the characters that make up its name. These locations
|
||
|
|
are offset from an address DIR.ADDR, which contains the address, within
|
||
|
|
the disk buffers, of the start of the directory entry. The defining word
|
||
|
|
FIELDER will create some words that allow us to access these fields. These
|
||
|
|
access words are structured like the TO variables mentioned above. Thus,
|
||
|
|
START.SECTOR for example, will normally leave the starting sector number
|
||
|
|
of a file on the stack. If it is preceded by TO, however, as in:</p>
|
||
|
|
|
||
|
|
<p><tt>3 TO START.SECTOR</tt></p>
|
||
|
|
|
||
|
|
<p>then a value is stored to the START.SECTOR field. (This doesn't work
|
||
|
|
as well for FLAG.BYTE, which is only a single byte location.)</p>
|
||
|
|
|
||
|
|
<p>Three additional words on screen 32 show ways to make use of the data
|
||
|
|
from these fields. ?NULLED examines the least significant byte of the FLAG.BYTE
|
||
|
|
of a directory entry, and leaves a true flag on the stack if the directory
|
||
|
|
entry is not an active one. PNAME will print the name of an entry. BUMPSEC
|
||
|
|
will print out the number of sectors used by an individual file, and increments
|
||
|
|
a counter containing the number of sectors used on the disk.</p>
|
||
|
|
|
||
|
|
<p>Our DIR example makes use of all of the above definitions to print out
|
||
|
|
the directory of a FMS disk. It does so by examining sectors 361 through
|
||
|
|
368 for valid directory entries. Each entry is 16 bytes long (8 per sector)
|
||
|
|
and is checked to see if it is null. If it isn't, its name is printed and
|
||
|
|
the file length is added to the running total (#SEC). At the end of the
|
||
|
|
directory listing, the total number of sectors used by the files is printed,
|
||
|
|
as well as the number of sectors available (according to the FMS Volume
|
||
|
|
Table of Contents), using .USED.</p>
|
||
|
|
|
||
|
|
<p>In the case of an actual data sector from a file, the words FILE, POINTER
|
||
|
|
and BCOUNT (all defined by DATA) return the values stored at the end of
|
||
|
|
a data sector. Because of various tricks that are performed (to save disk
|
||
|
|
space) additional words are required to convert the values into a useable
|
||
|
|
format. The word #FILE returns the position of the file in the directory.
|
||
|
|
The next sector number in the file is returned by #POINT, which equals 0
|
||
|
|
if this sector is the end of the file. #BYTES returns the number of data
|
||
|
|
bytes in the sector, which may range from 125 to 1.</p>
|
||
|
|
|
||
|
|
<p>Two other words are useful in this context. DATA.FIELD leaves the address,
|
||
|
|
in the disk buffers, of the start of the sector. ?LAST leaves a false flag,
|
||
|
|
plus the next sector number of the file, if the end of the file has not
|
||
|
|
been reached. Otherwise a true flag is left on the stack.</p>
|
||
|
|
|
||
|
|
<p>Our final example, on screen 36, illustrates what it might take to list
|
||
|
|
a file. Assuming that the value of DIR.ADDR has been set to point to the
|
||
|
|
directory entry in the disk buffers, PRINT.FILE starts at the first sector
|
||
|
|
of the file, and types #BYTES from the DATA.FIELD of the sector, until the
|
||
|
|
last sector is reached.</p>
|
||
|
|
|
||
|
|
<p><b>FOR MORE INFO</b></p>
|
||
|
|
|
||
|
|
<p>Because of space limitations, we'll skip over exactly how one locates
|
||
|
|
a specific directory entry. This could be done by simply DUMPing the contents
|
||
|
|
of a disk block, or by actually accepting text from a user and performing
|
||
|
|
a string match against the FMS directory. Other applications for this system,
|
||
|
|
such as loading character fonts into memory and repairing 'damaged' files,
|
||
|
|
can be obtained by writing to the author c/o Pink Noise Studios, P.0. Box
|
||
|
|
785 Crockett, CA 94525. Please include a self-addressed, stamped envelope.</p>
|
||
|
|
|
||
|
|
<pre>----------------------------------------
|
||
|
|
pink noise studios/fig-forth 1/82
|
||
|
|
\ 30 extensions for others rfg20apr82
|
||
|
|
: \ in @ c/l / 1+ c/l * in ! ;
|
||
|
|
immediate \ from Henry Laxen
|
||
|
|
: NOT 0= ;
|
||
|
|
hex
|
||
|
|
: MSBYTE 0 100 u/ swap drop ;
|
||
|
|
: LSBYTE ff and ;
|
||
|
|
: >< \ byteswap
|
||
|
|
dup lsbyte 100 * swap msbyte + ;
|
||
|
|
0 variable TOFLAG
|
||
|
|
: TO 1 toflag ! ;
|
||
|
|
: VAR <builds ,
|
||
|
|
does> toflag @
|
||
|
|
if ! else @ then 0 toflag ! ;
|
||
|
|
decimal ;s
|
||
|
|
----------------------------------------
|
||
|
|
\ 31 fields in directory rfg18apr82
|
||
|
|
0 variable DIR.ADDR
|
||
|
|
\ points to directory entry in buffers
|
||
|
|
: FIELDER <builds c, \ offset into field
|
||
|
|
does> c@ dir.addr @ + \ compute addr
|
||
|
|
toflag @ if ! else @ then 0 toflag ! ;
|
||
|
|
0 fielder FLAG.BYTE
|
||
|
|
1 fielder SECTOR.COUNT
|
||
|
|
3 fielder START.SECTOR
|
||
|
|
: NAME.FIELD dir.addr @ 5 + ;
|
||
|
|
;s
|
||
|
|
----------------------------------------
|
||
|
|
\ 32 utilities for DIR rfg18apr82
|
||
|
|
: ?NULLED \ return true if nulled out
|
||
|
|
flag.byte lsbyte dup 80 =
|
||
|
|
swap 0= or sector.count 0= or ;
|
||
|
|
hex
|
||
|
|
: PNAME
|
||
|
|
name.field dup 8 type 2e emit
|
||
|
|
8 + 3 type ;
|
||
|
|
0 variable #SEC
|
||
|
|
: BUMPSEC \ increment total and print
|
||
|
|
sector.count dup #sec +! 4 .r ;
|
||
|
|
decimal
|
||
|
|
: .USED \ according to VTOC
|
||
|
|
359 block 3 + @ 4 .r
|
||
|
|
," sectors available " cr ;
|
||
|
|
;s
|
||
|
|
----------------------------------------
|
||
|
|
pink noise studios/fig-forth 1/82
|
||
|
|
\ 33 directory of FMS disks rfg18apr82
|
||
|
|
decimal
|
||
|
|
: DIR 0 #sec ! cr
|
||
|
|
368 360 \ directory sectors
|
||
|
|
do i block dup b/buf + swap
|
||
|
|
do i dir.addr !
|
||
|
|
?nulled not
|
||
|
|
if pname bumpsec cr then
|
||
|
|
16 +loop
|
||
|
|
loop cr #sec @ 4 .r
|
||
|
|
." sectors used by files " cr .used ;
|
||
|
|
;s
|
||
|
|
----------------------------------------
|
||
|
|
\ 34 fields in sectors rfg18apr82
|
||
|
|
decimal
|
||
|
|
0 variable SECTOR
|
||
|
|
: DATA <builds c,
|
||
|
|
does> c@ sector @ 1- block +
|
||
|
|
toflag @
|
||
|
|
if ! else @ then 0 toflag ! ;
|
||
|
|
125 data FILE
|
||
|
|
125 data POINTER
|
||
|
|
127 data BCOUNT
|
||
|
|
hex
|
||
|
|
\ below return values
|
||
|
|
: #FILE file lsbyte 4 / ;
|
||
|
|
: #POINT pointer >< 3ff and ;
|
||
|
|
: #BYTES bcount 7f and 7d min ;
|
||
|
|
\above accounts for short sectors
|
||
|
|
;s
|
||
|
|
----------------------------------------
|
||
|
|
\ 35 dos access utilities rfg18apr82
|
||
|
|
: DATA.FIELD \ first storage location
|
||
|
|
sector @ 1- block ;
|
||
|
|
: ?LAST #point -dup 0= ;
|
||
|
|
\ leave true or false + link
|
||
|
|
\ to next sector
|
||
|
|
----------------------------------------
|
||
|
|
pink noise studios/fig-forth 1/82
|
||
|
|
\ 36 printing a file rfg18apr82
|
||
|
|
\ assumes dir.addr points to
|
||
|
|
\ directory entry in buffers
|
||
|
|
: PRINT.FILE
|
||
|
|
start.sector sector !
|
||
|
|
begin data.field #bytes type
|
||
|
|
?last not
|
||
|
|
while sector !
|
||
|
|
repeat ;
|
||
|
|
----------------------------------------</pre>
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</td><td style="width:330px; min-width:330px; vertical-align:top; zoom:1; ">
|
||
|
|
<div id="sideadplaceholder" style=" width:340px; min-width:340px;">
|
||
|
|
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</td></tr></tbody></table>
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
<div style="display: none">
|
||
|
|
|
||
|
|
<!--[if !IE]-->
|
||
|
|
<script type="text/javascript">
|
||
|
|
var adcountoffset=0;
|
||
|
|
var aheightoffset=0;
|
||
|
|
var aheightfactor=0;
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<!--[endif]-->
|
||
|
|
<!--[if IE]>
|
||
|
|
<script type="text/javascript">
|
||
|
|
var adcountoffset=0;
|
||
|
|
var aheightoffset=19;
|
||
|
|
var aheightfactor=0.023;
|
||
|
|
</script>
|
||
|
|
<![endif]-->
|
||
|
|
|
||
|
|
<script type="text/javascript">
|
||
|
|
|
||
|
|
|
||
|
|
var maxAds = 20;
|
||
|
|
google_max_num_ads = 6;
|
||
|
|
var elementId = "main_article";
|
||
|
|
var col = document.getElementById(elementId); // determining the height of column to adjust number of ads
|
||
|
|
var article_height=parseInt(col.offsetHeight-aheightoffset-((col.offsetHeight-aheightoffset)*aheightfactor)); //compensate for IE
|
||
|
|
|
||
|
|
if (col) // if defined, trying to calculate how many ads to show
|
||
|
|
{
|
||
|
|
var article_height=col.offsetHeight-aheightoffset;
|
||
|
|
|
||
|
|
var adHeight = 80;
|
||
|
|
numberOfAds = Math.floor(article_height / adHeight);
|
||
|
|
numberOfAds = parseInt(numberOfAds);
|
||
|
|
|
||
|
|
numberOfAds = ((numberOfAds+5+adcountoffset) >= maxAds) ? maxAds : (numberOfAds+5+adcountoffset); //limiting numberOfAds
|
||
|
|
|
||
|
|
google_max_num_ads=(numberOfAds > google_max_num_ads) ? numberOfAds : google_max_num_ads;
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
function google_ad_request_done(google_ads){
|
||
|
|
var s = '<div style="width:330px; text-align:left;padding:25px 10px 0px 10px; line-height:15pt;" >';
|
||
|
|
s += '<a href=\"' + google_info.feedback_url + '\" style="clear:both; margin-left:0px;margin-top:-15px;display:block;color:#666666;font-family:verdana,arial,sans-serif; text-decoration: none; font-weight:500; font-size:9pt;">Ads by Google</a><div>';
|
||
|
|
var i;
|
||
|
|
|
||
|
|
if (google_ads.length == 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (google_ads[0].type == "flash") {
|
||
|
|
s += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' +
|
||
|
|
' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" WIDTH="' +
|
||
|
|
google_ad.image_width +
|
||
|
|
'" HEIGHT="' +
|
||
|
|
google_ad.image_height +
|
||
|
|
'"> <PARAM NAME="movie" VALUE="' +
|
||
|
|
google_ad.image_url +
|
||
|
|
'">' +
|
||
|
|
'<PARAM NAME="quality" VALUE="high">' +
|
||
|
|
'<PARAM NAME="AllowScriptAccess" VALUE="never">' +
|
||
|
|
'<EMBED src="' +
|
||
|
|
google_ad.image_url +
|
||
|
|
'" WIDTH="' +
|
||
|
|
google_ad.image_width +
|
||
|
|
'" HEIGHT="' +
|
||
|
|
google_ad.image_height +
|
||
|
|
'" TYPE="application/x-shockwave-flash"' +
|
||
|
|
' AllowScriptAccess="never" ' +
|
||
|
|
' PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer"></EMBED></OBJECT>';
|
||
|
|
if(document.getElementById('topadholder')) {
|
||
|
|
document.getElementById('topadholder').innerHTML = s;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
else
|
||
|
|
if (google_ads[0].type == "image") {
|
||
|
|
|
||
|
|
s += '<a href="' +
|
||
|
|
google_ads[0].url +
|
||
|
|
'" target="_top" title="go to ' +
|
||
|
|
google_ads[0].visible_url +
|
||
|
|
'" onmouseout="window.status=\'\'" onmouseover="window.status=\'go to ' +
|
||
|
|
google_ads[0].visible_url +
|
||
|
|
'\';return true"><img border="0" src="' +
|
||
|
|
google_ads[0].image_url +
|
||
|
|
'"width="' +
|
||
|
|
google_ads[0].image_width +
|
||
|
|
'"height="' +
|
||
|
|
google_ads[0].image_height +
|
||
|
|
'"></a>';
|
||
|
|
if(document.getElementById('topadholder')) {
|
||
|
|
document.getElementById('topadholder').innerHTML = s;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
else
|
||
|
|
if (google_ads[0].type == "html") {
|
||
|
|
s += google_ads[0].snippet;
|
||
|
|
|
||
|
|
if(document.getElementById('topadholder')) {
|
||
|
|
document.getElementById('topadholder').innerHTML = s;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (google_ads.length == 1) {
|
||
|
|
s += '<a style="line-height:18pt; letter-spacing: 2px; color:blue;font-family:verdana,arial,sans-serif;" href="' +
|
||
|
|
google_ads[0].url +
|
||
|
|
'" onmouseout="window.status=\'\'" onmouseover="window.status=\'go to ' +
|
||
|
|
google_ads[0].visible_url +
|
||
|
|
'\';return true"> <span style="font-size:18pt;font-weight:bold;"> ' +
|
||
|
|
google_ads[0].line1 +
|
||
|
|
'</span></a> <span style="line-height:18pt; letter-spacing: 2px; text-decoration:none;color:#0e0e0e;font-family:verdana,arial,sans-serif;font-size:14pt;font-weight:400;"> - ' +
|
||
|
|
google_ads[0].line2 +
|
||
|
|
' ' +
|
||
|
|
google_ads[0].line3 +
|
||
|
|
'</span><br /><span><a style="color:blue;letter-spacing: 1.5px;font-size:13pt;font-weight:400;text-decoration:none;font-family:verdana,arial,sans-serif;" href="' +
|
||
|
|
google_ads[0].url +
|
||
|
|
'" onmouseout="window.status=\'\'" onmouseover="window.status=\'go to ' +
|
||
|
|
google_ads[0].visible_url +
|
||
|
|
'\';return true">' +
|
||
|
|
google_ads[0].visible_url +
|
||
|
|
'</span></a><br>';
|
||
|
|
if(document.getElementById('topadholder')) {
|
||
|
|
document.getElementById('topadholder').innerHTML = s;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (google_ads.length > 1) {
|
||
|
|
var s1 = '<div style="display: block; min-width:800px; text-align:left;padding:25px 10px 10px 20px;line-height:9.5pt;clear:both;" >';
|
||
|
|
s1 += '<a href=\"' + google_info.feedback_url + '\" style="clear:both;margin-left:0px;margin-top:-15px;position:absolute;display:block;color:#666666;font-family:verdana,arial,sans-serif; text-decoration: none; font-weight:500; font-size:9pt;">Ads by Google</a><div>';
|
||
|
|
|
||
|
|
for (i = 0; i < 5; ++i) {
|
||
|
|
s1 += '<div style="display: block; margin-right:2px;">';
|
||
|
|
s1 += '<a style="letter-spacing: 1.5px;color:blue;font-family:verdana,arial,sans-serif;font-size:10pt;font-weight:bold;" href="' +
|
||
|
|
google_ads[i].url +
|
||
|
|
'" onmouseout="window.status=\'\'" onmouseover="window.status=\'go to ' +
|
||
|
|
google_ads[i].visible_url +
|
||
|
|
'\';return true">' +
|
||
|
|
google_ads[i].line1 +
|
||
|
|
'</a> <span style="text-decoration:none;letter-spacing: 1.5px;color:#0e0e0e;font-family:verdana,arial,sans-serif;font-size:10pt;font-weight:400;">' +
|
||
|
|
google_ads[i].line2 +
|
||
|
|
' ' +
|
||
|
|
google_ads[i].line3 +
|
||
|
|
'</span> <span><a style="line-height:normal;color:blue;letter-spacing: 1.2px;font-size:9pt;font-weight:400;text-decoration:none;font-family:verdana,arial,sans-serif;" href="' +
|
||
|
|
google_ads[i].url +
|
||
|
|
'" onmouseout="window.status=\'\'" onmouseover="window.status=\'go to ' +
|
||
|
|
google_ads[i].visible_url +
|
||
|
|
'\';return true">' +
|
||
|
|
google_ads[i].visible_url +
|
||
|
|
'</span></a>';
|
||
|
|
s1 += "</div><br />"
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if(document.getElementById('topadholder')) {
|
||
|
|
document.getElementById('topadholder').innerHTML = s1;
|
||
|
|
}
|
||
|
|
if (google_ads.length>5)
|
||
|
|
{
|
||
|
|
s2=s;
|
||
|
|
|
||
|
|
for (i = 5; i < google_ads.length; ++i) {
|
||
|
|
|
||
|
|
s2 += '<div style="margin-right:2px;">';
|
||
|
|
s2 += '<a style="color:blue;font-family:courier new,verdana;font-size:12pt;font-weight:bold;" href="' +
|
||
|
|
google_ads[i].url +
|
||
|
|
'" onmouseout="window.status=\'\'" onmouseover="window.status=\'go to ' +
|
||
|
|
google_ads[i].visible_url +
|
||
|
|
'\';return true">' +
|
||
|
|
google_ads[i].line1 +
|
||
|
|
'</a><br /><span style="text-decoration:none;letter-spacing: 1.5px;color:#0e0e0e;font-family:verdana,arial,sans-serif;font-size:10pt;font-weight:400;">' +
|
||
|
|
google_ads[i].line2 +
|
||
|
|
' ' +
|
||
|
|
google_ads[i].line3 +
|
||
|
|
'</span> <span><a style="line-height:normal;color:blue;letter-spacing: 1.2px;font-size:9pt;font-weight:400;text-decoration:none;font-family:verdana,arial,sans-serif;" href="' +
|
||
|
|
google_ads[i].url +
|
||
|
|
'" onmouseout="window.status=\'\'" onmouseover="window.status=\'go to ' +
|
||
|
|
google_ads[i].visible_url +
|
||
|
|
'\';return true">' +
|
||
|
|
google_ads[i].visible_url +
|
||
|
|
'</span></a><br /><br />';
|
||
|
|
s2 += "</div>";
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if(document.getElementById('sideadplaceholder')) {
|
||
|
|
document.getElementById('sideadplaceholder').innerHTML = s2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
google_ad_output = 'js';
|
||
|
|
google_feedback = 'on';
|
||
|
|
google_ad_client = "pub-0754410284344153";
|
||
|
|
google_alternate_color = "FFFFFF";
|
||
|
|
google_ad_channel ="1234567886";
|
||
|
|
google_ad_type = "text";
|
||
|
|
google_color_border = "FFFFFF";
|
||
|
|
google_color_bg = "FFFFFF";
|
||
|
|
google_color_link = "0000EE";
|
||
|
|
google_color_url = "0000EE";
|
||
|
|
google_color_text = "000000";
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
</script>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<hr>
|
||
|
|
<ul>
|
||
|
|
<li><a href="javascript:history.back()">Back to previous page</a>
|
||
|
|
</li><li><a href="https://www.atarimagazines.com/index/?issue=v1n2">View this issue's table of contents</a>
|
||
|
|
</li></ul>
|
||
|
|
|
||
|
|
|
||
|
|
<protonpass-root-b2d3 data-protonpass-role="root" data-protonpass-theme="dark"><template shadowrootmode="closed"></template></protonpass-root-b2d3></body></html>
|