<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lallafa's Blog</title>
	<atom:link href="http://lallafa.de/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://lallafa.de/blog</link>
	<description>Personal Musings about the Commodore64, Macs and my other Hobby Projects</description>
	<lastBuildDate>Fri, 06 Apr 2012 12:50:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>CF card partitioning with rdbtool</title>
		<link>http://lallafa.de/blog/2012/04/cf-card-rdbtool/</link>
		<comments>http://lallafa.de/blog/2012/04/cf-card-rdbtool/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 12:50:59 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[amitools]]></category>
		<category><![CDATA[Mac Stuff]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=461</guid>
		<description><![CDATA[<p>Here is my little easter present for you: I finished the first release of rdbtool. &#8220;What&#8217;s that?&#8221; you may ask. It&#8217;s a new member of amitools, a family of cross-platform Classic Amiga tools I am developing. rdbtool is a command line utility that allows you to inspect, change or create new disk images or even <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2012/04/cf-card-rdbtool/">CF card partitioning with rdbtool</a></span>]]></description>
			<content:encoded><![CDATA[<p>Here is my little easter present for you: I finished the first release of <a title="rdbtool" href="http://lallafa.de/blog/amitools/rdbtool/">rdbtool</a>. &#8220;What&#8217;s that?&#8221; you may ask. It&#8217;s a new member of <a title="amitools" href="http://lallafa.de/blog/amitools/">amitools</a>, a family of cross-platform Classic Amiga tools I am developing. rdbtool is a command line utility that allows you to inspect, change or create new disk images or even real disks with Amiga&#8217;s RDB partitioning format. Its a companion tool to <a title="xdftool" href="http://lallafa.de/blog/amitools/xdftool/">xdftool</a> that handles Amiga&#8217;s file system in disk images or on the RDB partitions.</p>
<p>I had the idea for this tool while changing the CF flash card of my A1200. I removed the old card, had look at the files found there and wanted to retrieve files from there and then set up a new shiny card and build up partitions there. The current way to accomplish this, is to dump the card&#8217;s raw data from the block device and use this image as a RDB hard disk image in UAE to retrieve the files from there. Same thing with partitioning the new card: mount the block device or an empty image in UAE, run HDToolBox there, format partitions and copy files around in the virtual Amige environment&#8230; This works, but its a roundabout way. I wanted to have a nifty tool the works directly on my Mac&#8217;s Terminal&#8230; <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Read on to see how this task (and lots more!) can be achieved with rdbtool&#8230;</p>
<h4><span id="more-461"></span>Inspecting an old CF Card</h4>
<p>Ok, here we go: I unmount the CF card from the A1200 and insert it into my CF card USB reader on my Mac. Mac OS X tells me that it can&#8217;t find a valid file system on it (and that&#8217;s true for osx <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) &#8211; we ignore this and cancel the request to initalize (= format) it. First thing is now to find out the block device for this disk. On OS X I call a:</p>
<pre>&gt; diskutil list</pre>
<p>and it gives me:</p>
<pre>/dev/disk2
 #:                       TYPE NAME                    SIZE       IDENTIFIER
 0:                                                   *4.0 GB     disk2</pre>
<p>The empty Type Name gives you the hint that the partioning format is not recognized by OS X! So, it&#8217;s <strong>/dev/disk2</strong>&#8230; On Linux or other Posix systems the naming of raw block devices is slighty different (e.g. /dev/sd?). Just have a look at your system manuals (or dmesg) for details&#8230;</p>
<p>Now I use rdbtool to list the partition setup directly on the card:</p>
<pre>&gt; rdbtool /dev/disk2 info
PhysicalDisk:               0     7817     7880544  3.8Gi  heads=16 sectors=63
LogicalDisk:                2     7817     7878528  3.8Gi  rdb_blks=[0:2015,#2016] used=[hi=60,#61] cyl_blks=1008
Partition: #0 'CDH0'        2      103      102816   50Mi    1.31%  DOS3 bootable pri=0
Partition: #1 'DH0'       104      205      102816   50Mi    1.31%  DOS3
Partition: #2 'DH1'       206     2035     1844640  900Mi   23.41%  DOS3
Partition: #3 'DH2'      2036     3763     1741824  850Mi   22.11%  DOS3
Partition: #4 'DH3'      3764     3909      147168   71Mi    1.87%  DOS3
Partition: #5 'CDH1'     3910     3971       62496   30Mi    0.79%  DOS3
Partition: #6 'DH4'      3972     4124      154224   75Mi    1.96%  DOS3
Partition: #7 'DH5'      4125     5953     1843632  900Mi   23.40%  DOS3
Partition: #8 'DH6'      5954     7817     1878912  917Mi   23.85%  DOS3
FileSystem #0 DOS1 version=40.1 size=24588 seg_list_blk=0xb global_vec=0xffffffff</pre>
<p>Wow! Got a lot of partitions there&#8230; With the drive names (DH0, &#8230;) at hand you use xdftool to access the file system on each partition (I use -r option here to enable read-only mode &#8211; just for safety reasons):</p>
<pre>&gt; xdftool -r /dev/disk2 open part=DH1 + list
Games 1                                          VOLUME  --------  29.03.1993 11:35:33 t46 
  Disk.info                                         364  ----rw-d  29.03.1993 11:35:33 t47
...</pre>
<p>With the unpack command of <a title="xdftool" href="http://lallafa.de/blog/amitools/xdftool/">xdftool</a> I was able to easily recover all files of a partition into a directory structure on my Mac.</p>
<p>The info output also showed that a file system driver was also embedded in the RDB structure. You can use the <strong>fsget</strong> command to retrieve the Amiga loadSeg()able binary:</p>
<pre>&gt; rdbtool /dev/disk2 fsget 0 ffs</pre>
<p>0 is the number of the first and only file system driver on this disk and &#8220;ffs&#8221; is the local Mac file name for the binary:</p>
<pre>&gt; ls -la ffs
-rw-r--r--  1 chris  staff  24588  6 Apr 13:48 ffs
</pre>
<p>You can also have a closer look of the internals of the RDB structure with the <em>map</em> and <em>show</em> commands. Map shows the contents of the RDB area and describes the contents of each block (see rdbtool page for details) while show dumps all blocks describing the RDB:</p>
<pre>&gt; rdbtool /dev/disk2 map
000000:  RD P0 P1 P2 P3 P4 P5 P6 P7 P8 F0 F0 F0 F0 F0 F0
000016:  F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0
000032:  F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0
000048:  F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 -- -- --
...</pre>
<pre>&gt; rdbtool /dev/disk2 show
RigidDiskBlock(0):
 types:     5244534b/0 (valid: 5244534b/0)
 chksum:    0x7471bb06 (got) 0x7471bb06 (calc)
 valid:     True
 size:           64
 host_id:        7
 block_size:     512
 flags:          0x00000017
 badblk_list:    none
 part_list:      1
 fs_list:        10
 init_code:      none
...</pre>
<p>While working on a real disk you do not want to alter, it is advisable to either use the -r switch to enable <strong>read-only mode</strong> in rdbtool or simply copy the whole disk into a <strong>disk image</strong> and work on the image (if you have the disk space available, of course!):</p>
<pre>&gt; dd if=/dev/disk2 of=disk.rdb bs=512
&gt; rdbtool disk.rdb list</pre>
<p>That&#8217;s it for inspecting an existing RDB disk. Now let&#8217;s create an own, new one&#8230;</p>
<h5>Partitioning a new Disk</h5>
<p>Insert a shiny new CF card into your card reader. Typically some FAT file system already resides on a partition of the card. First thing is to remove the existing partioning layout. On OSX I do (for /dev/disk1):</p>
<pre>&gt; diskutil partitionDisk disk1 free none 100%</pre>
<p>Now rdbtool can access the disk. The first command we will issue is an<strong> init</strong>, it will create an empty RDB block on the disk. The info will show an empty layout:</p>
<pre>&gt; rdbtool /dev/disk1 init + info
PhysicalDisk:               0    61999     1984000  968Mi  heads=1 sectors=32
LogicalDisk:                1    61999     1983968  968Mi  rdb_blks=[0:31,#32] used=[hi=0,#1] cyl_blks=32</pre>
<p>A logical RDB disk is created automatically but no partition exist yet. So let&#8217;s add some! The <strong>add</strong> command adds a partition and only requires a size given either in percent (20%), bytes (2Mb), KiBytes (2Mib), or cylinders (20). If no start is given then the next free region on the logical disk is chosen:</p>
<pre>&gt; rdbtool /dev/disk1 add size=50Mib + add size=100Mib + fill + info
PhysicalDisk:               0    61999     1984000  968Mi  heads=1 sectors=32
LogicalDisk:                1    61999     1983968  968Mi  rdb_blks=[0:31,#32] used=[hi=3,#4] cyl_blks=32
Partition: #0 'DH0'         1     3200      102400   50Mi    5.16%  DOS3
Partition: #1 'DH1'      3201     9600      204800  100Mi   10.32%  DOS3
Partition: #2 'DH2'      9601    61999     1676768  818Mi   84.52%  DOS3
</pre>
<p>Note the <strong>fill</strong> command: It will create a partition to fill the remaining space on the logical disk.</p>
<p>You can alter settings of a partition with the <strong>change</strong> command: I use it to make the first partition bootable and set its priority:</p>
<pre>&gt; rdbtool /dev/disk1 change DH0 bootable pri=10 + info
...
Partition: #0 'DH0'         1     3200      102400   50Mi    5.16%  DOS3 bootable pri=10
...</pre>
<p>(See <a title="rdbtool" href="http://lallafa.de/blog/amitools/rdbtool/">rdbtool manual page</a> for more options). You can also pass these options to the add command in the previous step for a more compact usage of the tool.</p>
<p>The partition layout is already finished, the only thing I&#8217;d like to add to my RDB is the FFS file system driver restored from the old card (see above):</p>
<pre>&gt; rdbtool /dev/disk1 fsadd ffs + info
ERROR adding filesystem! (no space in RDB left)</pre>
<p>Oops! There is not enough space left for the file system. I have to recreate the RDB with more space reserved for the filesystem (see rdb_cyls = reserve a number of cylinders for RDB usage):</p>
<pre>&gt; rdbtool /dev/disk1 init rdb_cyls=2 + add size=50Mib bootable pri=10 + add size=100Mib + fill + fsadd ffs + info
PhysicalDisk:               0    61999     1984000  968Mi  heads=1 sectors=32
LogicalDisk:                2    61999     1983936  968Mi  rdb_blks=[0:63,#64] used=[hi=54,#55] cyl_blks=32
Partition: #0 'DH0'         2     3201      102400   50Mi    5.16%  DOS3 bootable pri=10
Partition: #1 'DH1'      3202     9601      204800  100Mi   10.32%  DOS3
Partition: #2 'DH2'      9602    61999     1676736  818Mi   84.52%  DOS3
FileSystem #0 DOS1 version=40.1 size=24588</pre>
<p>Voila! Everything set up in a single command <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>RDB work is done now! (See <a title="rdbtool" href="http://lallafa.de/blog/amitools/rdbtool/">rdbtool page</a> for lots of more commands available in this tool). Now let&#8217;s head over to <a title="xdftool" href="http://lallafa.de/blog/amitools/xdftool/">xdftool</a> and format the partitions:</p>
<pre>&gt; xdftool /dev/disk1 open part=dh0 + format System
&gt; xdftool /dev/disk1 open part=dh1 + format Work
&gt; xdftool /dev/disk1 open part=dh2 + format Data</pre>
<p>Now everything is partitioned and formatted for AmigaDOS use. Typically, you want to boot from the first partition, so its advisable to fill it now. In my case I used the pack command of xdftool to restore the Workbench files I recovered with unpack from my old card&#8230;</p>
<p>With this approach, setting up an Amiga disk drive on your Mac is done in seconds with rdbtool and xdftool. No need to boot up an emulator, just plain native tools <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  I hope you enjoyed this little introduction and find the tools as useful as I do&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2012/04/cf-card-rdbtool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>xdftool updated</title>
		<link>http://lallafa.de/blog/2012/02/xdftool-updated/</link>
		<comments>http://lallafa.de/blog/2012/02/xdftool-updated/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 17:40:18 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[xdftool]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=447</guid>
		<description><![CDATA[<p>Since my last report on xdftool I have updated a few things:</p> added support for RBD/RDSK hdf images changed repack command to be more flexible added open/create commands for better control of disk image geometry <p>In the following I give you a short round up of all new features by giving you some examples&#8230;</p> 1. <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2012/02/xdftool-updated/">xdftool updated</a></span>]]></description>
			<content:encoded><![CDATA[<p>Since my last report on xdftool I have updated a few things:</p>
<ul>
<li>added support for RBD/RDSK hdf images</li>
<li>changed repack command to be more flexible</li>
<li>added open/create commands for better control of disk image geometry</li>
</ul>
<p>In the following I give you a short round up of all new features by giving you some examples&#8230;</p>
<h4><span id="more-447"></span>1. RDB Support</h4>
<p>One very nasty thing when working with HDF image files is the fact that the extension .hdf is actually used for two types of different disk images in the context of Amiga emulation.</p>
<p>The first type is a disk image like a big floppy disk dump, i.e. it only contains a number of blocks and on these blocks an Amiga file system (like OFS or FFS) is located. Thats the way a floppy handles data. But in comparison with a floppy disk, a HDF has no pre-defined or fixed size. You can use every size for a HDF if you like. Now the drawback with these images is that you do not know the disk geometry (given in cylinders, heads, and sectors) directly but only the total size in bytes or blocks. You have to apply some magic (here: algorithms) to deduce the correct geometry. So this type of disk image is only fully useable if you know the disk geometry as external information. I call this type a <strong>partition HDF image</strong> because this type of image can be created by extracting the contents of a disk partition into an image file.</p>
<p>The other type I call a <strong>whole disk HDF image</strong> because it stores the whole contents of the disk. This includes some blocks describing the paritions found on this disk. This information starts with a RDISK/RDB (Rigid Disk Block) and thus images containing paritioning informations on an Amiga called like this first block RDB. The RDB references information on all partitions and knowns how large they are, what disk geometry the use locally and what file systems reside on them. Additionally, each partition has a AmigaOS device name associated so you can address them on your Amiga (e.g. dh0, dh1, &#8230;). An RDB is typically set up on a blank disk with the HDToolBox program on AmigaOS (soon you can use amitools&#8217; rdbtool for that &#8211; but thats another story/blog post <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ).</p>
<p>I distuingish these two types by naming my images differently: partition HDFs with *.hdf and disk images with *.rdsk, but thats my personal approach and unfortonately not widely used.</p>
<p>I added support of these RDB images to xdftool fully transparently, i.e. you simply specify a *.hdf file of any of the two types and xdftool will do the right thing. If its a <strong>partition HDF</strong> then there is only one file system and you can work with this one immediately:</p>
<pre>&gt; xdftool wb31.hdf blkdev
cylinders:   1280
heads:       1
sectors:     32
block_bytes: 512
reserved:    2
bootblocks:  2
</pre>
<p>This command prints the disk geometry detected from the byte size of the disk image. If the detection went wrong you can specify the new <strong>open</strong> command and give the missing parameters:</p>
<pre>&gt; xdftool wb31.hdf open chs=640,2,32 + blkdev
cylinders:   640
heads:       2
sectors:     32
block_bytes: 512
reserved:    2
bootblocks:  2</pre>
<p>This forces a disk geometry of 10 cylinders, 2 heads and 32 sectors. Another approach is to still use auto-detection but guide it by giving the heads or/and sectors count:</p>
<pre>&gt; xdftool wb31.hdf open h=2 + blkdev
cylinders:   640
heads:       2
sectors:     32
block_bytes: 512
reserved:    2
bootblocks:  2</pre>
<p>With a <strong>RDB/RDSK whole disk image</strong> you do not need to specify any geometry as this information is stored in the RDB structure. The only thing you have to specify is what partition shall xdftool work on. As xdftool only works on file system level you have to choose the partition either by giving the device name of AmigaOS (e.g. dh0, dh1) or the index number (starting with 0 for the first partition):</p>
<pre>&gt; xdftool wb31.rdsk open part=dh1 + list</pre>
<p>This list the contents of the second partition on my wb31 whole disk image (being dh0 the first partition). If you do not specify a partition then xdftool automatically takes the first partition:</p>
<pre>&gt; xdftool wb31.rdsk list</pre>
<h4>2. New Create Command</h4>
<p>With the new open command in place I added a new <strong>create</strong> command to create empty disk images of a given size. For ADFs the size is pre-defined so you need no extra arguments:</p>
<pre>&gt; xdftool empty.adf create   # create empty (and unformatted) floppy disk image
</pre>
<p>but for a (partition) HDF you have to give the size. You can either give a size in bytes (with short cuts for M)ega G)iga&#8230; and &#8216;i&#8217; for KiBi units) and use the internal algorithm for disk geometry or directly specify &#8220;chs&#8221; (cylinder, heads, and sectors):</p>
<pre>&gt; xdftool empty.hdf create size=10Mi
&gt; xdftool empty.hdf create chs=10,1,32
&gt; xdftool empty.hdf create size=10Mi h=2</pre>
<p>In the last example you see that you can also hint the disk geometry algorithm and specify the heads count (similar to the open command above).</p>
<p>Note: you will need to format this image before usage</p>
<p>2nd Note: you cannot create a full RDB/RDSK image with xdftool. Use HDToolBox on your Amiga (or soon: rdbtool) for that!</p>
<p>Typically You use a create command followed by a format command to create a file system you can work with:</p>
<pre>&gt; xdftool new.adf create + format MyDisk
&gt; xdftool work.hdf create size=10Mi + format Work ffs</pre>
<p>As this is used very often the format can do an implicit create if you simply omit the create command. Then you have to specify the options for create with the format command:</p>
<pre>&gt; xdftool new.adf format MyDisk
&gt; xdftool work.hdf format Work size=10Mi ffs</pre>
<h4>3. Repack Command Changed</h4>
<p>With the rework done handling rdisk and hdf I had to change the existing repack command. In older xdftool version you specify a new image as argument and the given image on the xdftool command line was the source. This is now flipped:</p>
<pre>&gt; xdftool old.hdf repack new.hdf   # OLD syntax
&gt; xdftool new.hdf repack old.hdf  # NEW syntax</pre>
<p>I changed it to make its usage more versatile: You can give open like options (see above) in the repack command to specify the source image:</p>
<pre>&gt; xdftool new.hdf repack old.rdsk part=dh0  # repack first partition into new partition image
&gt; xdftool new.hdf repack old.hdf chs=10,2,32   # repack old image with given geometry</pre>
<p>(Note: if you get an error that the new image can&#8217;t created then either remove the existing file first or specify the -f force option). Now you can also create a new image with different size or layout and repack all data into it:</p>
<pre>&gt; xdftool new.hdf create size=10Mi + repack wb31.hdf  # move my wb disk into a larger image
&gt; xdftool disk.rdsk open part=dh0 + repack wb31.hdf # move my wb disk into a partition</pre>
<p>That&#8217;s it! Have Fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2012/02/xdftool-updated/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mastering ADF/HDF Images with xdftool</title>
		<link>http://lallafa.de/blog/2012/01/mastering-adfhdf-images-with-xdftool/</link>
		<comments>http://lallafa.de/blog/2012/01/mastering-adfhdf-images-with-xdftool/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 21:28:43 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Mac Stuff]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=438</guid>
		<description><![CDATA[<p>My Amiga cross development environment on my Mac is getting really useful now: with vamos running the SAS C compiler I can create Amiga binaries with ease. With the binaries in place I want to try them on the real machine, too. For my trusty old Amiga 500, I still use disks to transfer the <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2012/01/mastering-adfhdf-images-with-xdftool/">Mastering ADF/HDF Images with xdftool</a></span>]]></description>
			<content:encoded><![CDATA[<p>My Amiga cross development environment on my Mac is getting really useful now: with<a title="Building a “real” Project on vamos running SAS C" href="http://lallafa.de/blog/2011/12/building-a-real-project-on-vamos-running-sas-c/"> vamos running the SAS C compiler</a> I can create Amiga binaries with ease. With the binaries in place I want to try them on the real machine, too. For my trusty old Amiga 500, I still use disks to transfer the data. So I create an ADF image with my files on it and either use my <a href="http://www.kryoflux.com/">kryoflux</a> setup to write a real disk or write a virtual HFE disk image on an SD card to be used with the <a href="http://hxc2001.free.fr/floppy_drive_emulator/">HXC2001 floppy emulator</a>.</p>
<p>While building the code is done automatically in a Makefile, the disk image creation still involves manual steps including launching an UAE emulator to create the disk image. Hmm, I thought, an ADF file mastering tool (like mkisofs is used for CDs) would be a great tool!! Adding this to my Makefile would fully automates my build cycle&#8230; I was aware of <a href="http://lclevy.free.fr/adflib/">ADFlib</a> as being the portable library for ADF manipulation and I had a look there, but I did not found a mastering tool. Some more googling didn&#8217;t show me a similar tool &#8211; so again &#8211; I was left on my own and had to create the tool myself <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>As a result <a title="xdftool" href="http://lallafa.de/blog/amitools/xdftool/"><strong>xdftool</strong></a> was born and added to my <a title="amitools" href="http://lallafa.de/blog/amitools/">amitools</a> tool set! I started writing a small tool using the Python binding of ADFlib to create an ADF image and copy files there. This worked really quickly but soon I found the limitations of this library: the mastering part is only partially supported and essential things like setting all meta infos of a file were missing (or I didn&#8217;t find them <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . In the end I dropped the ADFlib approach and started to build a FS library for Amiga OFS/FFS from scratch&#8230; Thanks to the excellent <a href="http://lclevy.free.fr/adflib/adf_info.html">ADF Disk Format FAQ </a> I soon had all necessary information available and some hours later the first code files written.</p>
<p>The lib is done now and included in amitools as &#8220;fs&#8221; module. In its first incarnation it already has an impressive feature set:</p>
<ul>
<li>full object-oriented API in Python</li>
<li>supports ADF and HDF containers</li>
<li>supports all OFS/FFS modes including international and dircache</li>
<li>read/write files/dir trees from/to host file system</li>
<li>multi-layer support: work on block level or on FS level</li>
<li>query and modify all parameters found in the file system including comments, protection flags and all time stamps in tick resolution</li>
<li>supports unpacking/packing/repacking of full images into host file system with meta db files to store information not available on host file system</li>
</ul>
<p>xdftool now supports all features of the library and while it started as a mastering tool for ADFs it is now a full featured command line tool to work with all kinds of ADF and HDF images&#8230; The remainder of this post gives you a short tutorial what you can do with xdftool:</p>
<p><span id="more-438"></span>First of all install xdftool. It is a part of amitools so have a look at my <a title="amitools" href="http://lallafa.de/blog/amitools/">amitools</a> page for installation details. It is handy to pack the top-level dir of amitools into your PATH so you have all tools available in your shell at any place.</p>
<p>In the following I will use a Workbench 3.1 disk image called wb31.adf which was taken from Cloanto&#8217;s Amiga Forever Pack. You can use any other disk image as well. Simply adjust the paths if necessary. Host files are taken from the top level directory of amitools.</p>
<p>This tutorial only shows a sub set of functions available in xdftool. Have a look at the <a title="xdftool" href="http://lallafa.de/blog/amitools/xdftool/">xdftool Homepage</a> for a full reference of commands.</p>
<h4>Look at a Disk</h4>
<pre>&gt; xdftool wb31.adf list
Workbench3.1                                    VOLUME  --------  06.07.1986 14:32:19 t08 
 C                                                 DIR  ----rwed  22.06.1991 02:13:25 t18 
 AddBuffers                                        444  --p-rwed  06.07.1986 14:39:06 t31 
 AddDataTypes                                     5880  --p-rwed  06.07.1986 14:39:06 t37 
 Assign                                           3220  --p-rwed  06.07.1986 14:39:06 t43 
 Avail                                             736  --p-rwed  06.07.1986 14:39:06 t49 
 BindDrivers                                      1420  ----rwed  06.07.1986 14:39:07 t04 
 Break                                             432  --p-rwed  06.07.1986 14:39:07 t16 
 ChangeTaskPri                                     460  --p-rwed  06.07.1986 14:39:07 t21 
 ConClip                                          2432  --p-rwed  06.07.1986 14:39:07 t29 
...
T                                                  DIR  ----rwed  22.06.1991 02:06:08 t25 
 Utilities                                         DIR  ----rwed  06.07.1986 14:39:05 t07 
 Clock                                           13856  ----rwed  06.07.1986 14:39:04 t31 
 Clock.info                                        590  ----rw-d  06.07.1986 14:39:04 t37 
 More                                            12752  --p-rwed  06.07.1986 14:39:04 t43 
 MultiView                                       28836  --p-rwed  06.07.1986 14:39:05 t01 
 MultiView.info                                    861  ----rw-d  06.07.1986 14:39:05 t11 
 Utilities.info                                    632  ----rw-d  06.07.1986 14:39:06 t14 
 WBStartup                                         DIR  ----rwed  06.07.1986 14:39:05 t19 
 WBStartup.info                                    632  ----rw-d  06.07.1986 14:39:06 t21 
Blocks:    data:     1496, fs:      199, sum:     1695, ratio=88.26, disk total:     1760
Bytes:     data:   765952, fs:   101888, sum:   867840, ratio=88.26, disk total:   901120
File:      data:   726742, ratio=94.88</pre>
<p>Ok, first command shows you whats on a disk! Note the calling convention in xdftool: always pass the image file name first then the command with parameters. You see the complete directory tree of the volume inside the disk image. Each entry shows you the size, protection flags, modification time stamps (with ticks) and if available the file comment. At the end a summary on block usage is given.</p>
<h4>Create a disk and write to it</h4>
<pre>&gt; xdftool mydisk.adf format MyDisk + boot install + list
MyDisk                                         VOLUME  --------  14.01.2012 21:49:13 t00 
Blocks:    data:        0, fs:        1, sum:        1, ratio=0.00, disk total:     1760
Bytes:     data:        0, fs:      512, sum:      512, ratio=0.00, disk total:   901120
File:      data:        0, ratio=0.00</pre>
<p>With this command creating an empty formatted image is a no-brainer&#8230; Note that you can combine multiple commands in a single call to xdftool by separating them with a plus sign. Creating a hard disk image is also very easy:</p>
<pre>&gt; xdftool myhd.hdf format Work 10M</pre>
<p>Here a size (or a disk geometry) needs to be specified.</p>
<p>You can put some files from your host on it with the &#8216;write&#8217; command:</p>
<pre>&gt; xdftool mydisk.adf write README + list
test                                            VOLUME  --------  14.01.2012 21:51:42 t00 
 README                                           3728  ----rwed  14.01.2012 21:51:42 t00 
Blocks:    data:        8, fs:        2, sum:       10, ratio=80.00, disk total:     1760
Bytes:     data:     4096, fs:     1024, sum:     5120, ratio=80.00, disk total:   901120
File:      data:     3728, ratio=91.02</pre>
<p>This will write the file README from the host&#8217;s current directory to the volume directory of the image. You can also write a full directory tree to the image:</p>
<pre>&gt; xdftool mydisk.adf write doc + list
test                                            VOLUME  --------  14.01.2012 21:53:20 t00 
 doc                                               DIR  ----rwed  14.01.2012 21:53:20 t00 
   xdftool.txt                                   18798  ----rwed  14.01.2012 21:53:20 t00 
Blocks:    data:       39, fs:        3, sum:       42, ratio=92.86, disk total:     1760
Bytes:     data:    19968, fs:     1536, sum:    21504, ratio=92.86, disk total:   901120
File:      data:    18798, ratio=94.14</pre>
<p>Now you can alter the protect flags, the modification time or set a comment:</p>
<pre>&gt; xdftool mydisk.adf protect doc rwe + time doc "12.01.1991 12:00:00 t11" + comment doc "my doc comment" + list
test                                            VOLUME  --------  14.01.2012 21:53:20 t00 
 doc                                               DIR  ----rwe-  12.01.1991 12:00:00 t11  my doc comment
   xdftool.txt                                   18798  ----rwed  14.01.2012 21:53:20 t00 
Blocks:    data:       39, fs:        3, sum:       42, ratio=92.86, disk total:     1760
Bytes:     data:    19968, fs:     1536, sum:    21504, ratio=92.86, disk total:   901120
File:      data:    18798, ratio=94.14</pre>
<p>With these commands at hand you can now easily write a Makefile entry that creates an ADF image and places all your files on it.</p>
<p>But xdftool can more:</p>
<h4>Unpacking and Packing Images</h4>
<p>The unpack command extracts all files and directories from a disk image and creates a corresponding directory structure on your host&#8217;s file system. Additionally a MetaDB file will be created with all flags of the Amiga file system that cannot be represented in the host file system, namely protect flags, timestamps with ticks and comments:</p>
<pre>&gt; xdftool wb31.adf unpack .
&gt; ls Workbench3.1*
Workbench3.1.blkdev    Workbench3.1.bootcode  Workbench3.1.xdfmeta

Workbench3.1:
C/              Devs.info       Expansion.info  Prefs/          S/              T/              WBStartup/
Classes/        Disk.info       L/              Prefs.info      System/         Utilities/      WBStartup.info
Devs/           Expansion/      Libs/           Rexxc/          System.info     Utilities.info</pre>
<p>You see a directory named after the volume inside the image was created with all files and dirs of the image. Additionally the MetaDB file *.xdfmeta, the boot code in *.bootcode and the description of the disk&#8217;s block device geometry *.blkdev was written.</p>
<p>With these files in place you can always recreate a new disk image that is equivalent to the original image (from the FS perspective):</p>
<pre>&gt; xdftool newimg.adf pack Workbench3.1 + list
Workbench3.1                                    VOLUME  --------  06.07.1986 14:32:19 t08 
 C                                                 DIR  ----rwed  22.06.1991 02:13:25 t18 
 AddBuffers                                        444  --p-rwed  06.07.1986 14:39:06 t31 
 AddDataTypes                                     5880  --p-rwed  06.07.1986 14:39:06 t37 
 Assign                                           3220  --p-rwed  06.07.1986 14:39:06 t43 
...
   MultiView.info                                  861  ----rw-d  06.07.1986 14:39:05 t11 
 Utilities.info                                    632  ----rw-d  06.07.1986 14:39:06 t14 
 WBStartup                                         DIR  ----rwed  06.07.1986 14:39:05 t19 
 WBStartup.info                                    632  ----rw-d  06.07.1986 14:39:06 t21 
Blocks:    data:     1496, fs:      199, sum:     1695, ratio=88.26, disk total:     1760
Bytes:     data:   765952, fs:   101888, sum:   867840, ratio=88.26, disk total:   901120
File:      data:   726742, ratio=94.88</pre>
<p>Note the correct time stamps and protect flags after packing&#8230;</p>
<p>With this approach you can quickly unpack an image, modify some files on your host file system and pack the image again.</p>
<p>Also mastering full images is now easy: create a Volume directory from scratch, place all your files in it and if you need special flags then write a *.xdfmeta file. Call xdftool pack to create your image. Done!</p>
<h5>Repacking Images</h5>
<p>Another nice operation in xdftool is repack: This essentially combines a unpack command on an existing image with a pack command on a new image. So you can rebuild the contents of the whole volume of the old image and write a fresh new FS structure. This will recreate the FS and re-aligns all file data blocks to be in one place. Originally this command helps me to test the integrity of amitools fs library but it may be useful for you, too:</p>
<pre>&gt; xdftool wb31.adf repack new.adf</pre>
<p>In combination with a hard disk image repack also allows you to create a larger target disk, so this command essentially allows you to &#8220;grow&#8221; your Amiga hard disk by repacking its image to a larger one:</p>
<pre>&gt; xdftool old.hdf repack new.hdf 10M
</pre>
<p>You can even repack a disk image into a hard disk image:</p>
<pre>&gt; xdftool wb31.adf repack wb31.hdf 10M</pre>
<p>That&#8217;s it&#8230; If you want to play more with xdftool have a look at the <a title="xdftool" href="http://lallafa.de/blog/amitools/xdftool/">xdftool page</a>!</p>
<p>Have Fun! And if you find bugs in the rather fresh code then please don&#8217;t hesitate to report them&#8230; Thanks!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2012/01/mastering-adfhdf-images-with-xdftool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a &#8220;real&#8221; Project on vamos running SAS C</title>
		<link>http://lallafa.de/blog/2011/12/building-a-real-project-on-vamos-running-sas-c/</link>
		<comments>http://lallafa.de/blog/2011/12/building-a-real-project-on-vamos-running-sas-c/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 17:40:35 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Mac Stuff]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[vamos]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=418</guid>
		<description><![CDATA[<p>In the last post I showed you that vamos is already able to call the SAS C Compiler 6.58 and compile some example source files. In the last few days I added the missing parts to vamos to support smake, too. Namely, calling sub processes with SystemTagList() was added and lots of bugs fixed. With <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2011/12/building-a-real-project-on-vamos-running-sas-c/">Building a &#8220;real&#8221; Project on vamos running SAS C</a></span>]]></description>
			<content:encoded><![CDATA[<p>In the last post I showed you that <a title="amitools" href="http://lallafa.de/blog/amitools/">vamos</a> is already able to call the SAS C Compiler 6.58 and compile some example source files. In the last few days I added the missing parts to vamos to support smake, too. Namely, calling sub processes with SystemTagList() was added and lots of bugs fixed. With smake at hand I am able to compile some real SAS C projects with an smakefile describing the build.</p>
<p>In this post I will show you how you can build the <a href="http://aminet.net/comm/net/magPLIP38.1.lha">magPLIP</a> network driver I used in my <a title="plip2slip" href="http://lallafa.de/blog/plip2slip/">plip2slip</a> project directly on your Mac without using an Amiga machine emulator like P-UAE&#8230;</p>
<h3><span id="more-418"></span>1. Setup Build Environment</h3>
<ul>
<li>I assume that you have installed the SAS C compiler ready to use for vamos as described in my <a title="Running the Amiga SAS C 6.58 compiler with vamos" href="http://lallafa.de/blog/2011/12/running-the-amiga-sas-c-6-58-compiler-with-vamos/">last post</a></li>
<li>The netword driver we will compile needs the Amiga Network Driver Includes (i.e. SANA-II headers)
<ul>
<li>Download the <a href="http://aminet.net/comm/tcp/AmiTCP-SDK-4.3.lha">AmiTCP-SDK-4.3.lha</a> from aminet</li>
<li>You can unpack it on your Mac with the lha command available in <a href="http://www.macports.org/">MacPorts</a> (call: <strong>sudo port install lha</strong> if the tool is still missing on your machine):</li>
</ul>
</li>
<pre>&gt; cd ~/amiga/src
&gt; lha x ~/Downloads/AmiTCP-SDK-4.3.lha</pre>
</ul>
<ul>
<li>Now we need to setup assigns in vamos so the build can reach the new network includes. My <strong>~/.vamosrc</strong> config file looks like this:</li>
</ul>
<pre>[volumes]
wb310=~/amiga/wb310
sc=~/amiga/shared/sc
net=~/amiga/src/AmiTCP-SDK-4.3

[assigns]
include=sc:include
lib=sc:lib
t=root:tmp
c=wb310:c
netinclude=net:netinclude
netlib=net:netlib
includeasm=sc:include

[path]
path=sc:c,wb310:c

[vamos]
quiet=True
ram_size=2048</pre>
<p>What&#8217;s new here?</p>
<ul>
<li>First I added a new volume in vamos called <strong>net:</strong> where the SANA-II includes reside. It points to the native path we just unpacked.</li>
<li>Some new assigns were added: <strong>netinclude</strong> and <strong>netlib</strong> point inside our new net: volume</li>
<li>Another assign called <strong>includeasm:</strong> was necessary as the following build requires it. It simply points directly to the include directory in the SAS C installation.</li>
<li>Finally, a new section called <strong>vamos</strong> was introduced. This section holds defaults for common option that were currently only available via command line:
<ul>
<li>The <strong>quiet</strong> switch is similar to the -q command line option and suppresses information about un-implemented Amiga OS calls in vamos</li>
<li>The <strong>ram_size</strong> sets the RAM for the AmigaOS emulation of vamos to 2 MiB. Similar to the -m command line option. This ensures that we do not run out of memory during compilation.</li>
</ul>
</li>
</ul>
<h3>2. Grab the Source</h3>
<ul>
<li>Next we download the source for <a title="magPLIP38.1" href="http://aminet.net/comm/net/magPLIP38.1.lha">magPLIP</a> from aminet</li>
<li>I unpacked the source in a build directory:</li>
</ul>
<pre>&gt; mkdir ~/build
&gt; cd build
&gt; lha x ~/magPLIP38.1.lha
&gt; ls
magplip/      magplip.info</pre>
<ul>
<li>I also downloaded the <a href="http://www.lallafa.de/files/plip2slip/plip2slip-0.1.zip">plip2slip-0.1</a> source archive because it contains a patch for the driver we are going to build</li>
<li>Unpack this, too:</li>
</ul>
<pre>&gt; unzip ~/Downloads/plip2slip-0.1.zip
&gt; ls
magplip/       magplip.info   plip2slip-0.1/</pre>
<ul>
<li>Next, we patch the source:</li>
</ul>
<pre>&gt; patch -p0 &lt; plip2slip-0.1/contrib/magplip/magplip.patch
patching file magplip/source/magplip_rev.h
patching file magplip/source/magplip_rev.i
patching file magplip/source/magport.asm
patching file magplip/source/server.c
patching file magplip/source/smakefile</pre>
<ul>
<li>That&#8217;s it, now the source is ready to be compiled!</li>
</ul>
<h3>3. Perform the Build</h3>
<ul>
<li>The build itself is now rather unspectacular&#8230; It simply works <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<pre>&gt; cd magplip/source
&gt; vamos smake all_opt
SAS/C_SMAKE 6.58 (27.12.96)
Copyright (c) 1988-1995 SAS Institute, Inc.
 sc:c/sc INCDIR="INCLUDEASM:" INCDIR="include:" INCDIR="netinclude:" VERBOSE DEFINE MAGPLIP=1 OBJECTNAME MAGrt.o rt.asm
No default scoptions file found
SAS/C Amiga Compiler 6.58
Copyright (c) 1988-1995 SAS Institute Inc.

asm "-dMAGPLIP=1" -iINCLUDEASM: -iinclude: -inetinclude: -oMAGrt.o rt.asm
...

SLINK Complete - Maximum code size = 8824 ($00002278) bytes

Final output file size = 8940 ($000022ec) bytes
</pre>
<ul>
<li>If everything went fine then the resulting binary resides in the <strong>magplip/devs/networks</strong> folder:</li>
</ul>
<pre>&gt; ls ../devs/networks/magplip.device.000
-rwxr-xr-x  1 chris  staff  8940 18 Dez 18:16 ../devs/networks/magplip.device.000*</pre>
<ul>
<li>Ah! A fresh build of the driver&#8230; Now let&#8217;s create a 68020 version, too:</li>
</ul>
<pre>&gt; vamos smake CPUSUFFIX=020 all_opt
...
&gt; ls ../devs/networks/magplip.device.020
-rwxr-xr-x  1 chris  staff  8872 18 Dez 18:21 ../devs/networks/magplip.device.020*</pre>
<ul>
<li>Finally, you can compare your new builds with the reference compiles I did on P-UAE and that are available in the plip2slip release:</li>
</ul>
<pre>&gt; cmp ../devs/networks/magplip.device.000 ../../plip2slip-0.1/contrib/magplip/magplip.device.000
&gt; cmp ../devs/networks/magplip.device.020 ../../plip2slip-0.1/contrib/magplip/magplip.device.020</pre>
<ul>
<li>It really works! Same output generated on vamos!!</li>
<li>Now its time to read the plip2slip docs on how to actually use the driver on your real machine&#8230;</li>
</ul>
<h3>4. Some additional Notes</h3>
<ul>
<li>While vamos now supports the typical builds on SAS C even with smakefiles, there are still things missing. Most notably, the internal Shell commands like Echo are not emulated yet. So the default/help rule in our project&#8217;s smakefile does not work. But the internal Shell commands and a more complete support for the typical CLI commands will be the next on my TODO list&#8230;</li>
<li>Compared to last vamos versions I optimized the loading of native libraries (most notably sc1.library and sc2.library of sc) and that gave a real speed boost when calling the compiler.</li>
<li>To better judge where the bottlenecks in the vamos emulation are, I added <strong>profiling support</strong> for the library calls. You can use the new <strong>-P</strong> switch and give the libraries you want to get detailed information for:</li>
</ul>
<pre>&gt; vamos smake clean # first clean our build again
...
&gt; vamos -v -P exec,dos smake all_opt # now build with profiling on
...
18:34:09.103       prof:   INFO:  'dos.library' Function Call Profile
18:34:09.103       prof:   INFO:                   Close: #     251  total=    0.0115  per call=    0.0000
18:34:09.103       prof:   INFO:              CurrentDir: #      45  total=    0.0009  per call=    0.0000
18:34:09.103       prof:   INFO:               DateStamp: #       9  total=    0.0005  per call=    0.0001
18:34:09.103       prof:   INFO:              DeleteFile: #      12  total=    0.0033  per call=    0.0003
18:34:09.103       prof:   INFO:                 DupLock: #       3  total=    0.0003  per call=    0.0001
18:34:09.103       prof:   INFO:                 Examine: #      85  total=    0.0158  per call=    0.0002
18:34:09.104       prof:   INFO:                FilePart: #       3  total=    0.0002  per call=    0.0001
18:34:09.104       prof:   INFO:                FreeArgs: #       6  total=    0.0017  per call=    0.0003
18:34:09.104       prof:   INFO:          FreeDeviceProc: #       3  total=    0.0005  per call=    0.0002
18:34:09.104       prof:   INFO:           GetDeviceProc: #       3  total=    0.0008  per call=    0.0003
18:34:09.104       prof:   INFO:                   Input: #      20  total=    0.0001  per call=    0.0000
18:34:09.104       prof:   INFO:                   IoErr: #      94  total=    0.0006  per call=    0.0000
18:34:09.104       prof:   INFO:                    Lock: #      77  total=    0.0163  per call=    0.0002
18:34:09.104       prof:   INFO:                MatchEnd: #       6  total=    0.0019  per call=    0.0003
18:34:09.104       prof:   INFO:              MatchFirst: #       6  total=    0.0055  per call=    0.0009
18:34:09.104       prof:   INFO:               MatchNext: #       6  total=    0.0002  per call=    0.0000
18:34:09.104       prof:   INFO:                    Open: #     352  total=    0.0850  per call=    0.0002
18:34:09.104       prof:   INFO:                  Output: #      37  total=    0.0003  per call=    0.0000
18:34:09.104       prof:   INFO:               ParentDir: #      62  total=    0.0061  per call=    0.0001
18:34:09.104       prof:   INFO:            ParsePattern: #       3  total=    0.0006  per call=    0.0002
18:34:09.104       prof:   INFO:                  PutStr: #       9  total=    0.0005  per call=    0.0001
18:34:09.104       prof:   INFO:                    Read: #     617  total=    0.0273  per call=    0.0000
18:34:09.105       prof:   INFO:                ReadArgs: #       6  total=    0.0038  per call=    0.0006
18:34:09.105       prof:   INFO:                  Rename: #       3  total=    0.0013  per call=    0.0004
18:34:09.105       prof:   INFO:                    Seek: #     155  total=    0.0048  per call=    0.0000
18:34:09.105       prof:   INFO:                SetIoErr: #       3  total=    0.0000  per call=    0.0000
18:34:09.105       prof:   INFO:           SetProtection: #       4  total=    0.0009  per call=    0.0002
18:34:09.105       prof:   INFO:           SystemTagList: #      16  total=    0.0486  per call=    0.0030
18:34:09.105       prof:   INFO:                  UnLock: #     108  total=    0.0026  per call=    0.0000
18:34:09.105       prof:   INFO:                   Write: #     277  total=    0.0152  per call=    0.0001
18:34:09.105       prof:   INFO:  sum total=0.2570
18:34:09.105       main:   INFO:  done 3218549052 cycles in host time 14.9556s -&gt; 174.60 MHz m68k CPU
18:34:09.106       main:   INFO:  code time 14.9556s (81.13 %), trap time 3.4781s (18.87 %) -&gt; total time 18.4337s
18:34:09.106       main:   INFO:  exit code=0
18:34:09.107       prof:   INFO:  'exec.library' Function Call Profile
18:34:09.107       prof:   INFO:                AllocMem: #    1266  total=    0.1440  per call=    0.0001
18:34:09.107       prof:   INFO:                AllocVec: #      39  total=    0.0024  per call=    0.0001
18:34:09.107       prof:   INFO:            CloseLibrary: #      85  total=    0.0129  per call=    0.0002
18:34:09.107       prof:   INFO:                FindTask: #     137  total=    0.0024  per call=    0.0000
18:34:09.107       prof:   INFO:                  Forbid: #     137  total=    0.0004  per call=    0.0000
18:34:09.107       prof:   INFO:                 FreeMem: #    1318  total=    0.4038  per call=    0.0003
18:34:09.107       prof:   INFO:                 FreeVec: #      39  total=    0.0059  per call=    0.0002
18:34:09.107       prof:   INFO:                  GetMsg: #     650  total=    0.0082  per call=    0.0000
18:34:09.107       prof:   INFO:             OpenLibrary: #      85  total=    0.1304  per call=    0.0015
18:34:09.107       prof:   INFO:                  Permit: #     137  total=    0.0004  per call=    0.0000
18:34:09.107       prof:   INFO:                  PutMsg: #     650  total=    0.0794  per call=    0.0001
18:34:09.108       prof:   INFO:                RawDoFmt: #      11  total=    0.0006  per call=    0.0001
18:34:09.108       prof:   INFO:               SetSignal: #  103942  total=    0.9651  per call=    0.0000
18:34:09.108       prof:   INFO:               StackSwap: #      34  total=    0.0030  per call=    0.0001
18:34:09.108       prof:   INFO:  sum total=1.7587
</pre>
<ul>
<li>That&#8217;s it for today! Enjoy vamos and if you already use it for doing your own &#8220;cross&#8221;-compiles then I&#8217;d really like to hear from your projects&#8230;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2011/12/building-a-real-project-on-vamos-running-sas-c/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Running the Amiga SAS C 6.58 compiler with vamos</title>
		<link>http://lallafa.de/blog/2011/12/running-the-amiga-sas-c-6-58-compiler-with-vamos/</link>
		<comments>http://lallafa.de/blog/2011/12/running-the-amiga-sas-c-6-58-compiler-with-vamos/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 20:39:03 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Mac Stuff]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[vamos]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=409</guid>
		<description><![CDATA[<p>Well, the vamos project is progressing really, really well&#8230; And while I&#8217;m working at bringing more and more native Amiga tools to life on my Mac, I almost overlooked the first major milestone (and actually its primary initial goal) of the project: running the SAS C Compiler&#8230;</p> <p>This posts interrupts the rather technical series of <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2011/12/running-the-amiga-sas-c-6-58-compiler-with-vamos/">Running the Amiga SAS C 6.58 compiler with vamos</a></span>]]></description>
			<content:encoded><![CDATA[<p>Well, the vamos project is progressing really, really well&#8230; And while I&#8217;m working at bringing more and more native Amiga tools to life on my Mac, I almost overlooked the first major milestone (and actually its primary initial goal) of the project: running the SAS C Compiler&#8230;</p>
<p>This posts interrupts the rather technical series of articles describing the internals of vamos and simply shows you how to actually <strong>use</strong> vamos the way its intended to be <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Fasten your seatbelts, grab your old SAS C compiler disks and read on!</p>
<h3><span id="more-409"></span>1. Installing SAS C in P-UAE</h3>
<p>First thing we need to get the SAS C installation files including the Amiga binaries, the headers and libraries.</p>
<p>I actually own(!) the SAS C compiler 6.50 package (really impressive boxing and lots to read <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ) and the contained disks were captured to ADF disk images with my <a href="http://www.kryoflux.com/">kryoflux device</a>. (And no, don&#8217;t ask me for the disk images!)</p>
<p>Then I took my all-time-ready P-UAE (<a href="https://github.com/GnoStiC/PUAE">src</a> or <a href="http://www.binarydevotion.com/">precompiled</a>) emulation setup with a classic OS 3.9 and installed the disks there.</p>
<p>I use a host-based virtual directory for <strong>DH1:</strong> called <strong>Shared:</strong> and the SAS compiler was installed there.</p>
<p>BTW: Do not forget to install the <a href="http://www.warped.com/amiga/">latest update of the SAS C 6.5 series</a> found on the net&#8230;</p>
<p>After this step I already had the necessary files for vamos residing on my Mac hard drive. (The <strong>Shared: </strong>volume is pointing to <strong>~/amiga/shared</strong> on the Mac &#8211; keep this in mind to understand the following vamos setup)</p>
<p>If everything works out then your directory something like this:</p>
<pre>chris@thaum:~/amiga/shared$ ls -la sc
total 160
drwxr-xr-x  28 chris  staff    952 24 Okt 18:11 ./
drwxr-xr-x  34 chris  staff   1156 26 Nov 16:42 ../
-rwxr-xr-x   1 chris  staff   5045  1 Okt  1993 READ.ME*
-rw-r-xr-x   1 chris  staff    838 13 Jan  2011 READ.ME.info*
-rwxr-xr-x   1 chris  staff  21515 27 Feb  1995 Read.Me.6.55*
-rw-r-xr-x   1 chris  staff    838 13 Jan  2011 Read.Me.6.55.info*
drwxr-xr-x  53 chris  staff   1802 25 Jun 12:58 c/
-rw-r-xr-x   1 chris  staff    628 13 Jan  2011 c.info*
drwxr-xr-x  11 chris  staff    374 13 Jan  2011 cxxinclude/
drwxr-xr-x   4 chris  staff    136 13 Jan  2011 env/
drwxr-xr-x  48 chris  staff   1632 16 Nov 21:32 examples/
-rw-r-xr-x   1 chris  staff    628 13 Jan  2011 examples.info*
drwxr-xr-x  32 chris  staff   1088 13 Jan  2011 extras/
-rw-r-xr-x   1 chris  staff    628 13 Jan  2011 extras.info*
drwxr-xr-x  18 chris  staff    612 13 Jan  2011 help/
-rw-r-xr-x   1 chris  staff    628 13 Jan  2011 help.info*
drwxr-xr-x  18 chris  staff    612 13 Jan  2011 icons/
-rw-r-xr-x   1 chris  staff    628 13 Jan  2011 icons.info*
drwxr-xr-x  56 chris  staff   1904 13 Jan  2011 include/
drwxr-xr-x  34 chris  staff   1156 13 Jan  2011 lib/
drwxr-xr-x  13 chris  staff    442 13 Jan  2011 libs/
-rwxr-xr-x   1 chris  staff   5935 13 Jan  2011 read.me.6.58*
-rw-r-xr-x   1 chris  staff    838 13 Jan  2011 read.me.6.58.info*
drwxr-xr-x  31 chris  staff   1054 13 Jan  2011 rexx/
drwxr-xr-x  28 chris  staff    952 13 Jan  2011 source/
-rw-r-xr-x   1 chris  staff    628 13 Jan  2011 source.info*
drwxr-xr-x   8 chris  staff    272 13 Jan  2011 starter_project/
-rw-r-xr-x   1 chris  staff    628 13 Jan  2011 starter_project.info*</pre>
<h3>2. Setting up vamos</h3>
<p>I won&#8217;t go into detail on how to compile, install vamos on your machine &#8211; have a look at my <a title="amitools" href="http://lallafa.de/blog/amitools/">amitools</a> page for this.</p>
<p>Here we will write a config file for vamos that defines the mapping of the Mac paths to Amiga volumes and also adds the assigns SAS C will need to run.</p>
<p>I added a file called <strong>.vamosrc</strong> to my $HOME directory (this is the default location where vamos will look for this file. You can also store this file at any place and use the -c command line option to select the config file):</p>
<pre># .vamosrc - vamos config file for SAS C compiler
[volumes]
wb310=~/amiga/wb310
sc=~/amiga/shared/sc

[assigns]
include=sc:include
lib=sc:lib
t=root:tmp

[path]
path=sc:c,wb310:c
</pre>
<p>Let&#8217;s have a closer look of whats described here:</p>
<ul>
<li>The first section called <strong>volumes</strong> in the file describes the Mac Path to Amiga Volume mapping. Each entry gives a Amiga volume defined inside vamos (and visible to Amiga programs running inside vamos) and maps them to a native Mac Path. In my config the volumes <strong>wb310:</strong> and <strong>sc:</strong> are defined. (Use absolute paths here to make the config work from any location) The wb310: isn&#8217;t actually used in this example but having Workbench files handy is always a good idea (for later use of vamos)</li>
<li>The next section <strong>assigns </strong> defines assigns inside vamos, like AmigaDOS does itself. Assign mapping always references Amiga paths on the right side and never native (Mac) paths! Furthermore, an assign must map either to another assign (optional plus path) or to an absolute path with volume. Relative paths are not allowed here. SAS C needs assigns for the headers (<strong>include:</strong>) and the link libraries (<strong>lib:</strong>). The last assign maps the temp dir of AmigaDOS as SAS C stores some files there temporarly. <strong>t:</strong> is mapped via the <strong>root:</strong> volume that is always defined in vamos and points to the file system root (/). So this assign actually points to /tmp&#8230;</li>
<li>The last section <strong>path</strong> gives &#8212; similar to AmigaDOS &#8212; the search path for binaries. Again, only absolute Amiga paths are allowed. The path is searched in vamos whenever a binary is given on the command line&#8230; very handy we will see soon&#8230;</li>
</ul>
<h3>3. Run sc for the first time</h3>
<p>With the config in place and vamos in your path, you can already call the SAS C compiler called <strong>sc</strong> from any place on your mac (Remember: vamos will look in your Amiga path for the binaries):</p>
<pre>chris@thaum:~$ vamos sc
20:51:58.301       path:WARNING:  ami_to_sys_path: ami_path='env:sc/scoptions' -&gt; abs_path='env:sc/scoptions' -&gt; no resolved paths!
SAS/C Amiga Compiler 6.58
Copyright (c) 1988-1995 SAS Institute Inc.
20:51:58.322        lib:WARNING:  [    exec.library]  ? CALL:  324 Signal( task[a1]=108b4, signalSet[d0]=8000 ) from PC=020062 -&gt; d0=0 (default)
20:51:58.322        lib:WARNING:  [    exec.library]  ? CALL:  252 Remove( node[a1]=2014c ) from PC=01ff36 -&gt; d0=0 (default)
Error  : No files to compile
20:51:58.328        lib:WARNING:  [    exec.library]  ? CALL:  252 Remove( node[a1]=2014c ) from PC=01ff36 -&gt; d0=0 (default)</pre>
<p>The compiler is already running &#8212; only vamos mocks about some currently un-emulated (but harmless) library calls. You can make vamos quiet with the -q switch:</p>
<pre>chris@thaum:~$ vamos -q sc
SAS/C Amiga Compiler 6.58
Copyright (c) 1988-1995 SAS Institute Inc.
Error  : No files to compile</pre>
<p>Ah, that&#8217;s the SAS C I remember <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  (Note: vamos options are placed before the Amiga binary. All options following the binary are passed to the Amiga program!)</p>
<p>Now we need a little program to test compile. Open your favorite editor (<a href="http://macromates.com/">TextMate</a> here) and enter the world famous &#8220;hello, world!&#8221; snippet:</p>
<pre>/* hello.c - say no more <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> */
#include &lt;stdio.h&gt;

int main(int argc, char **argv)
{
   printf("hello, world!\n");
   return 0;
}</pre>
<p>Let&#8217;s compile it:</p>
<pre>chris@thaum:~/Projects/amitools.git/test_code$ vamos -q sc hello.c
SAS/C Amiga Compiler 6.58
Copyright (c) 1988-1995 SAS Institute Inc.</pre>
<p>Hmm, not much to say here&#8230; But look what happened:</p>
<pre>chris@thaum:~/Projects/amitools.git/test_code$ ls -la hello.o
-rw-r--r--  1 chris  staff  236  2 Dez 20:59 hello.o
chris@thaum:~/Projects/amitools.git/test_code$ file hello.o
hello.o: AmigaOS object/library data</pre>
<p>yay! Your first SAS C compiled binary &#8212; and it was compiled on a Mac!!</p>
<h3>4. Link and Run</h3>
<p>Now we need to link our object file to get a program suitable for your Amiga.</p>
<p>The linker in SAS C is called <strong>slink</strong> and also ready to run on vamos:</p>
<pre>chris@thaum:~/Projects/amitools.git/test_code$ vamos -q slink
Error 607: No FROM/ROOT files specified
</pre>
<p>Ok, it needs some options to perform its task&#8230; (The Error is not from vamos but from slink)</p>
<pre>chris@thaum:~/Projects/amitools.git/test_code$ vamos -q slink from lib:c.o hello.o to hello lib lib:sc.lib lib:amiga.lib
Slink - Version 6.58
Copyright (c) 1988-1995 SAS Institute, Inc.  All Rights Reserved.

SLINK Complete - Maximum code size = 5384 ($00001508) bytes

Final output file size = 5396 ($00001514) bytes
</pre>
<p>I love it (now that it works <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> )&#8230; slink just created an Amiga LoadSeg()able binary:</p>
<pre>chris@thaum:~/Projects/amitools.git/test_code$ ls -la hello
-rwxr-xr-x  1 chris  staff  5396  2 Dez 21:06 hello*
chris@thaum:~/Projects/amitools.git/test_code$ file hello
hello: AmigaOS loadseg()ble executable/binary
</pre>
<p>Now comes the funny part:</p>
<pre>chris@thaum:~/Projects/amitools.git/test_code$ vamos ./hello
hello, world!</pre>
<p>Of, course! vamos can also run the created binary&#8230; If you don&#8217;t believe it try yourself, take hello to P-UAE or even better to the real(tm) machine&#8230;</p>
<h3>5. Some more complex code</h3>
<p>You can of course compile larger (aka &#8220;real&#8221;) code as well.</p>
<p>Just try one of the examples SAS C ships:</p>
<pre>&gt; cd ~/amiga/shared/sc/examples/amiproc
&gt; vamos -q sc amiproc.c simple.c
&gt; vamos -q slink from lib:c.o simple.o amiproc.o lib lib:sc.lib lib:amiga.lib
&gt; ls -la simple
-rwxr-xr-x  1 chris  staff  6768  2 Dez 21:15 simple*
&gt; file simple
simple: AmigaOS loadseg()ble executable/binary</pre>
<p>Note: this binary does not run on vamos but needs UAE or a real machine&#8230;</p>
<p>BTW: If you want to know how well vamos performs running the compiler then call it with the -v switch and have a look at the last lines:</p>
<pre>chris@thaum:~/Projects/amitools.git/sc/examples/amiproc$ vamos -v sc amiproc.c simple.c
21:24:13.888       main:   INFO:  read config file: /Users/chris/.vamosrc
21:24:13.888       main:   INFO:  setting up main memory with 1024 KiB RAM: top=100000
21:24:13.905       main:   INFO:  setting up m68k
21:24:13.906       main:   INFO:  start cpu: 0016bc
...
21:24:21.504       main:   INFO:  done (410454570 cycles in cpu time 2.3453s -&gt; 54.02 MHz (30.87 %), trap time 5.2531s (69.13 %), total time 7.5984s)
21:24:21.505       main:   INFO:  exit code=0
</pre>
<p>Quite impressive compiling on a 54 MHz m68k&#8230; The trap time currently spent in the Python emulation has lots of potential for further optimization. But hey, first of all its running and then we think about getting it running real fast <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>With sc and slink running fairly well&#8230; Now what&#8217;s still missing to have a full featured cross compiler environment with a vamos-ed SAS C compiler?</p>
<h3>6. What&#8217;s still missing?</h3>
<p>Currently vamos has no ability to execute child processes. This is used in sc if you wan to link directly (sc bla.c to bla &#8230;). This is also the main reason why smake is a NOP right now&#8230;</p>
<p>I am currently working on this issue and I think with smake up and running the most important tools are available to start serious cross development with SAS C on the Mac&#8230;</p>
<p>Probably, lots of other things are still not working as well&#8230; So if you find something that currently breaks in sc and slink then I&#8217;d really be happy if you drop me a note&#8230; (Beta testers hoorray! <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Always enjoy vamos now with SAS C on your Mac <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2011/12/running-the-amiga-sas-c-6-58-compiler-with-vamos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inside vamos (Part 2)</title>
		<link>http://lallafa.de/blog/2011/11/inside-vamos-part-2/</link>
		<comments>http://lallafa.de/blog/2011/11/inside-vamos-part-2/#comments</comments>
		<pubDate>Sun, 06 Nov 2011 18:47:15 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=399</guid>
		<description><![CDATA[<p>Today we continue our little journey through my newest project and have a look at libraries and structures in the &#8220;virtual&#8221; Amiga RAM of vamos.</p> <p>Make sure to read Part 1 of the series first&#8230;</p> <p>Todays topics:</p> Amiga Libraries Amiga Structures 1. Amiga Libraries <p>We already know from our first expirments that an Amiga library <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2011/11/inside-vamos-part-2/">Inside vamos (Part 2)</a></span>]]></description>
			<content:encoded><![CDATA[<p>Today we continue our little journey through my newest project and have a look at libraries and structures in the &#8220;virtual&#8221; Amiga RAM of vamos.</p>
<p>Make sure to read <a title="vamos runs Amiga CLI programs on my Mac" href="http://lallafa.de/blog/2011/11/vamos-runs-amiga-cli-programs-on-my-mac/">Part 1 of the series</a> first&#8230;</p>
<p>Todays topics:</p>
<ul>
<li>Amiga Libraries</li>
<li>Amiga Structures</li>
</ul>
<h3><span id="more-399"></span>1. Amiga Libraries</h3>
<p>We already know from our first expirments that an Amiga library has a large jump table for all functions which we already use to trap the calls and redirect them to our Python vamos code.</p>
<p>The open question is now what functions does a library have and what registers are filled by the application before calling this function. Furthermore, we need to know what we have to return in the registers before returning to the caller. The last question is answered quickly: data registrer D0 is the return value of all lib calls (if the lib call isn&#8217;t void then no register contains a return value). So mapping the python trapped call return value to D0 was quickly done.</p>
<p>For the function description in a library Commodore invented a textual programming language neutral description called the <strong>FD files</strong> describing each function call and the arguments required along with the CPU registers where the argument will be found.</p>
<p>To simplify my work with vamos I first wrote a parser for the FD files (that can be found in the Amiga NDKs). This little tool is called <strong>fdtool</strong> and also available in my <a title="amitools" href="http://lallafa.de/blog/amitools/">amitools</a> source tree. You simply call it with a single FD file and it shows all functions and the relative jump offset in the table:</p>
<pre>&gt; ./fdtool NDK_3.1/Includes\&amp;Libs/fd/exec_lib.fd
NDK_3.1/Includes&amp;Libs/fd/exec_lib.fd
 base: _SysBase
 #0001     30  0x001e                Supervisor [userFunction,a5]
 #0002     72  0x0048                  InitCode [startClass,d0][version,d1]
 #0003     78  0x004e                InitStruct [initTable,a1][memory,a2][size,d0]
 #0004     84  0x0054               MakeLibrary [funcInit,a0][structInit,a1][libInit,a2][dataSize,d0][segList,d1]
 #0005     90  0x005a             MakeFunctions [target,a0][functionArray,a1][funcDispBase,a2]
 #0006     96  0x0060              FindResident [name,a1]
 #0007    102  0x0066              InitResident [resident,a1][segList,d1]
 #0008    108  0x006c                     Alert [alertNum,d7]
 #0009    114  0x0072                     Debug [flags,d0]
 #0010    120  0x0078                   Disable
 #0011    126  0x007e                    Enable
 #0012    132  0x0084                    Forbid
 #0013    138  0x008a                    Permit
 #0014    144  0x0090                     SetSR [newSR,d0][mask,d1]
 #0015    150  0x0096                SuperState
 #0016    156  0x009c                 UserState [sysStack,d0
..</pre>
<p>Its already very useful to decode jumps into the lib (Note: the jump uses a negative offset while the tools displays positive ones).</p>
<p>The next step was to create a code generator that writes stubs for Python that describe all functions:</p>
<pre>./fdtool -g NDK_3.1/Includes\&amp;Libs/fd/exec_lib.fd
 (30, 'Supervisor', (('userFunction', 'a5'),)),
 (36, 'execPrivate1', None),
 (42, 'execPrivate2', None),
 (48, 'execPrivate3', None),
 (54, 'execPrivate4', None),
 (60, 'execPrivate5', None),
 (66, 'execPrivate6', None),
 (72, 'InitCode', (('startClass', 'd0'), ('version', 'd1'))),
 (78, 'InitStruct', (('initTable', 'a1'), ('memory', 'a2'), ('size', 'd0'))),
 (84, 'MakeLibrary', (('funcInit', 'a0'), ('structInit', 'a1'), ('libInit', 'a2'), ('dataSize', 'd0'), ('segList', 'd1'))),
 (90, 'MakeFunctions', (('target', 'a0'), ('functionArray', 'a1'), ('funcDispBase', 'a2'))),
 (96, 'FindResident', (('name', 'a1'),)),
 (102, 'InitResident', (('resident', 'a1'), ('segList', 'd1'))),
 (108, 'Alert', (('alertNum', 'd7'),)),
 (114, 'Debug', (('flags', 'd0'),)),
 (120, 'Disable', None),
 (126, 'Enable', None),
 (132, 'Forbid', None),
 (138, 'Permit', None),
 (144, 'SetSR', (('newSR', 'd0'), ('mask', 'd1'))),
 (150, 'SuperState', None),
</pre>
<p>I simply copy &amp; paste this output in my ExecLibrary class and this table now describes all functions available and also their parameters. This information is not used for trapping in the first place but for logging: Now I can decode each jump into the Lib and display the named function call...</p>
<pre>19:39:29.159        lib:   INFO:  [    exec.library]  { CALL:  198 AllocMem( byteSize[d0]=def4, requirements[d1]=10001 ) from PC=00205a
19:39:29.159        lib:   INFO:  [    exec.library]  } END CALL: d0=000108ac
19:39:29.159        lib:   INFO:  [    exec.library]  { CALL:  732 StackSwap( newStack[a0]=113e8 ) from PC=0020e8
19:39:29.159        lib:   INFO:  [    exec.library]  } END CALL: d0=0000000</pre>
<p>With this information in place I could add trapped functions by adding a new table to my Library object: this one maps the function offset (again positive) to an actual Python method inside the class. I can do this for only the functions I need &#8211; all others have a default handler that returns D0=0 and issues a warning trace that this function is still unimplemented.</p>
<p>An excerpt of the Python <strong>ExecLibrary</strong> class looks like this:</p>
<pre>def __init__(self):
  exec_funcs = (
     (408, self.OldOpenLibrary),
     (414, self.CloseLibrary),
     ...
  )
  self.set_funcs(exec_funcs)

def OpenLibrary(self, lib, ctx):
  name_ptr = ctx.cpu.r_reg(REG_A1)
  ...
  return lib_addr
</pre>
<p>You see the mapping of Python functions in this example. Note that each Python call gets the same parameters and not the Amiga function calls directlly: It gets a context object and via this context the function can access the virtual CPU and read out the registers it needs&#8230;</p>
<p>The return value of the Python method will be directly written to D0 automatically. Returning None will not alter D0. This is useful for void function calls.</p>
<h3>2. Amiga Structures</h3>
<p>The library jump tables are not the only kind of data an Amiga application directly accesses outside its own memory segments: A lot of public data structures reside in memory and function calls often pass in pointers to them and also private ones. Some functions even require to create new structures and we then need to return their pointers. Furthermore, each library itself has (beside the jump table) a so called &#8220;pos size range&#8221; that contains data structures of &#8220;public&#8221; accessible information. E.g. exec.library has a large pos size with lots of system constants and also information like your own task structure&#8230;</p>
<p>Our task in vamos is now to correctly fill these structures as needed and provide a convinient mechanism in Python to access those data members. Unfortunately, those data structures are only defined in the language headers of Commodore&#8217;s NDKs and there is no generic description like there is the FDs for the calls <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>Without having a tool to decode some generic data structure definitions I started to convert the C Amiga headers manually into a Python structure definition. Those definition are not structures in Python itself but rather meta objects that describe a structure in the &#8220;virtual&#8221; Amiga Memory of vamos. This tedious process was only performed on demand, i.e. onyl the structures currently needed were transcribed to Pyhon.</p>
<p>Similar to fdtool I have written a <strong>typetool </strong>to provide a small command line utility that uses the structures defined in Python and displays them (This is again useful for disassembly reading as you can quickly look up and index and find the structure entry):</p>
<pre>./typetool Library
 @0000        Library {
 @0000          Node {
0000 @0000/0000 +0004      Node*      ln_Succ               (ptr=True, sub=False)
0001 @0004/0004 +0004      Node*      ln_Pred               (ptr=True, sub=False)
0002 @0008/0008 +0001      UBYTE      ln_Type               (ptr=False, sub=False)
0003 @0009/0009 +0001      BYTE       ln_Pri                (ptr=False, sub=False)
0004 @0010/000a +0004      char*      ln_Name               (ptr=True, sub=False)
 @0014 =0014    } lib_Node
0005 @0014/000e +0001    UBYTE      lib_Flags             (ptr=False, sub=False)
0006 @0015/000f +0001    UBYTE      lib_pad               (ptr=False, sub=False)
0007 @0016/0010 +0002    UWORD      lib_NegSize           (ptr=False, sub=False)
0008 @0018/0012 +0002    UWORD      lib_PosSize           (ptr=False, sub=False)
0009 @0020/0014 +0002    UWORD      lib_Version           (ptr=False, sub=False)
0010 @0022/0016 +0002    UWORD      lib_Revision          (ptr=False, sub=False)
0011 @0024/0018 +0004    APTR       lib_IdString          (ptr=False, sub=False)
0012 @0028/001c +0004    ULONG      lib_Sum               (ptr=False, sub=False)
0013 @0032/0020 +0002    UWORD      lib_OpenCnt           (ptr=False, sub=False)
 @0034 =0034  }
</pre>
<p>This query for the Library structure of Exec displays all entries including nested structures, their byte offset from the beginning, the C type and the name to access each entry.</p>
<p>This structure information is now used for two purposes in vamos: First it provides a convinient way to access structures inside memory for the Python lib calls when they have to access data that was provided by giving structure pointers. The second use of structures is to provide so called <strong>memory labels</strong> for logging. Every time vamos allocates a structure (e.g. ExecLib pos space) it also registers a struct memory label for the same address. A label manager keeps all registered labels and if memory tracing is enabled then you can look up an arbitrary address if it can be labelled. A structure label looks like this:</p>
<pre>19:22:23.891        mem:   INFO:  R(4): 0102a8: 00000000  Struct  [@010210 +000098 ThisTask] Process+152 = pr_CurrentDir(BPTR)+0
19:22:23.892        mem:   INFO:  R(4): 0102bc: 00004070  Struct  [@010210 +0000ac ThisTask] Process+172 = pr_CLI(BPTR)+0
19:22:23.892        mem:   INFO:  R(4): 0102bc: 00004070  Struct  [@010210 +0000ac ThisTask] Process+172 = pr_CLI(BPTR)+0
19:22:23.892        mem:   INFO:  R(4): 0101d0: 00004080  Struct  [@0101c0 +000010 CLI] CLI+16 = cli_CommandName(BSTR)+0
</pre>
<p>So a read access to memory address<strong> 0x0102a8</strong> is detected as structure access to <strong>ThisTask.pr_CurrentDir</strong>. That&#8217;s what I call comfortable debugging <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />   Note that the labelling look ups cost quite a lot of performance and that&#8217;s the reason why you have to enable memory tracing with a command line switch (-t/-T).</p>
<p>The most common use of Structures is to decode lib call arguments. In Python I provide a so called <strong>AccessStruct</strong> object that assist reading/writing structures:</p>
<pre>def StackSwap(self, lib, ctx):
 stsw_ptr = ctx.cpu.r_reg(REG_A0)
 stsw = AccessStruct(ctx.mem, StackSwapDef, struct_addr=stsw_ptr)
 # get new stack values
 new_lower = stsw.r_s('stk_Lower')
 new_upper = stsw.r_s('stk_Upper')
 new_pointer = stsw.r_s('stk_Pointer')</pre>
<p>This is an excerpt of the Python implemenation of the Exec StackSwap call: In A0 a pointer to a StackSwap structure is passed in. We have already declared the function in Python as a defintion (hence the trailing Def):</p>
<pre>class StackSwapStruct(AmigaStruct):
 _name = "StackSwap"
 _format = [
 ('APTR', 'stk_Lower'),
 ('ULONG', 'stk_Upper'),
 ('APTR', 'stk_Pointer')
 ]
StackSwapDef = StackSwapStruct()</pre>
<p>With a memory pointer and a structure definition we can create an access object. Now the reads and writes to the entries of the structure a simple calls can be performed with the entry name of the structure&#8230; Ok its slower than direct offset handling but far more confortable and less error prone&#8230;</p>
<p>Beside the structure access vamos also provides a more generic memory access object that allows to read and write blocks of data, reads c-type strings and bcpl strings with a single call:</p>
<pre>def OpenLibrary(self, lib, ctx):
 ver = ctx.cpu.r_reg(REG_D0)
 name_ptr = ctx.cpu.r_reg(REG_A1)
 name = ctx.mem.access.r_cstr(name_ptr)
 ..</pre>
<p>That&#8217;s it for today&#8230; I hope you got more insight on the Library and Struct handling and the confortable features available in vamos for working with them.</p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2011/11/inside-vamos-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vamos runs Amiga CLI programs on my Mac</title>
		<link>http://lallafa.de/blog/2011/11/vamos-runs-amiga-cli-programs-on-my-mac/</link>
		<comments>http://lallafa.de/blog/2011/11/vamos-runs-amiga-cli-programs-on-my-mac/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 19:28:08 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Mac Stuff]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=390</guid>
		<description><![CDATA[<p>I did some classic m68k Amiga code development that uses the SAS C compiler recently (see plip2slip). Everything was set up in a P-UAE-based AmigaOS 3.9 environment and worked fairly confortable. While switching between TextMate on my Mac I used for editing the code and the CLI window in P-UAE I had a thought: &#8220;It <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2011/11/vamos-runs-amiga-cli-programs-on-my-mac/">vamos runs Amiga CLI programs on my Mac</a></span>]]></description>
			<content:encoded><![CDATA[<p>I did some classic m68k Amiga code development that uses the SAS C compiler recently (see <a title="plip2slip" href="http://lallafa.de/blog/plip2slip/">plip2slip</a>). Everything was set up in a P-UAE-based AmigaOS 3.9 environment and worked fairly confortable. While switching between TextMate on my Mac I used for editing the code and the CLI window in P-UAE I had a thought: &#8220;It would be fairly cool to have something like Wine for AmigaOS&#8230; Then I&#8217;d simply run the SAS C compiler Amiga binary on my Mac directly&#8230;&#8221;</p>
<p>That was the beginning of my newes project: <strong>vamos</strong> &#8211; The Virtual AMiga OS emulator.</p>
<p>Read on to learn more about the birth of vamos and its first major milestone: run the SAS C compiler in my new &#8220;Developer&#8217;s Diary&#8221; series <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><span id="more-390"></span></p>
<h3>Mission Statement</h3>
<p>If you know Wine then the goal is fairly clear: write a native Mac OS X program that &#8220;executes&#8221; the Amiga binary, trap all native library calls (to Exec or DOS libary) and replace them with native versions, i.e. an Open() call to Amiga&#8217;s dos.library will directly open a file on my Mac.</p>
<p>I want to focus on Exec and Dos library as those provide the functions required for typical command line tools including compilers. I will start with all trapped Exec/Dos libs with empty functions and then step-by-step fill in the functions called by my first target tool: the SAS C compiler&#8230;</p>
<p>The thing in vamos that&#8217;s more difficult than in Wine is the machine architecture that differs: the Amiga binary is written in m68k code and my Mac runs an Intel x86 based CPU&#8230; So the first thing vamos will need is a m68k CPU emulation. I searched the web and found the <a href="http://caesar.logiqx.com/php/library.php?id=musashi">Musashi CPU emulator</a>.</p>
<h3>First Experiment</h3>
<p>I wanted to write (the first prototype of) vamos in Python 2.x as it allows to me to quickly get started and let&#8217;s me play around with different approaches fairly fast. If everything works out and some portions are slow due to Python scripting I can gradually move them to C later on&#8230;</p>
<p>So the first thing was to attach the native m68k CPU emulator to Python. With the help of <a href="http://docs.python.org/library/ctypes.html">Python&#8217;s ctype </a>module binding the native code was very easy. Now the only thing required to run this virtual CPU is memory. In a first attempt I routed all memory accesss from Musashi to Python and managed memory there, but that was too slow (a 0.2 MHz CPU <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  ) and so I moved to a C-based memory implementation. Now a single memory &#8220;RAM block&#8221; is allocated (e.g. 1 MiB) and accessed by the virtual CPU (200 MHz CPU <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>The native Python interface now allows to create the memory, read/write data to the block and control the CPU: read/write its registers and let it run&#8230;</p>
<p>Now I was ready for a first experiment: I used my Python HunkReader from my <a title="amitools" href="http://lallafa.de/blog/amitools/">amitools</a> library to load a Amiga LoadSeg()able binary and relocate it into my still empty memory location. Then point the virtual CPU to the first instruction of the first code segment and let the CPU run and boom! To see how far we got I early added extensive memory debugging to have a close look what is fetched from memory&#8230; I got as far as the first read to exec base at location 4&#8230; so we need some environment to run our binary in vamos!</p>
<h3>Setting up the Environment</h3>
<p>Ok. We need the exec lib structure in our virtual memory filled with the essential parts, i.e. mainly the jump vectors to the lib functions. And then I need a method to trap the calls so that I know that the virtual CPU will call a library function and can redirect it to my Python code.</p>
<p>In a new experiment I crafted a faked Exec Lib structure in memory and for the call trapping I tried the RESET opcode. Musashi provides a callback whenever this opcode occurrs and I wanted to use this for the lib traps. The idea is to use the RESET callback to enter my Python code then look at the CPU&#8217;s PC to find out which entry of the jump vector was selected. In my python code I will emulate the effect of the lib call (or do nothing) and then the next opecode will be executed. I placed an RTS there so the jsr libcall will return to the caller.</p>
<p>So my lib jump table with a trap looks like this (compared to a original Amiga jump):</p>
<pre>vamos lib entry: &lt;RESET opcode.w&gt; &lt;RTS opcode.w&gt; &lt;lib_id.w&gt;
amiga lib entry: &lt;JMP opcode.w&gt; &lt;func_addr.l&gt;</pre>
<p>Both entries have 6 bytes so they are binary compatible&#8230; Good. The lib_id word will be used later to identify which lib was trapped&#8230;</p>
<p>In my Python code I fetch the PC and then retrieve the library base (here of EXEC) to call the offset of the trapped function. Then I know the function to be called and can emulate it. First thing here was to setup the full exec structure and add traces for all trapped lib calls&#8230;</p>
<p>My experiment was done with the Type command of Workbench 3.1&#8230; And voila! The code ran until a first call to Exec&#8230; Its OpenLibrary!</p>
<h3>Stack and Terminate</h3>
<p>I almost forgot the stack.. Both PC and initial stack have to be paced at address 0 and 4 before powering up the virtual CPU. PC is the first instruction of my loaded binary. For the stack I simply reserved some static memory region in my RAM block and set the stack pointer&#8230;</p>
<p>I can now imagine how running the code would work. But leaving vamos was still an open question: The Amiga binary is called by jsr()ing into the code and it will end with an RTS. So at the end of the code the last value is fetched from the stack and jumped there. So a simple solution for the termination problem was to initialise the stack with a jump to address 0 and there I placed another RESET opcode to trigger my callback. The callback was then extended to watch out for a PC of 0. In this case no lib trap occurred but the program wants to exit. I quit vamos then and termination was solved&#8230;</p>
<p>A very simply program only consisting of a empty main() code block was now able to run in my Mac based vamos enviroment! A more complex Amiga program was already able to fetch exec base and to do jumps into exec. Those jumps are trapped but the python code only does logging for now. The exchange of parameters in the trapped calls is done by readingw/writing the &#8220;virtual&#8221; CPU registers&#8230;</p>
<p>All in all I was very happy with these first results and really looked forward to get more Amiga code running on vamos&#8230;</p>
<h3>To be continued&#8230;</h3>
<p>That&#8217;s it for today&#8230; Next time we will have a look on more features of vamos.</p>
<p>If you can&#8217;t wait then just head over to the <a title="amitools" href="http://lallafa.de/blog/amitools/">amitools</a> page and download the vamos code there and play around with it&#8230; enjoy!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2011/11/vamos-runs-amiga-cli-programs-on-my-mac/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SilverSurfer patched for Amiga 500</title>
		<link>http://lallafa.de/blog/2011/10/silversurfer-patched-for-amiga-500/</link>
		<comments>http://lallafa.de/blog/2011/10/silversurfer-patched-for-amiga-500/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 16:53:05 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Misc]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=364</guid>
		<description><![CDATA[<p>I just purchased a new HW goodie for my classic Amiga 500. A clockport adapter and a SilverSurfer serial card that allows high baudrates (e.g. 115200 baud) on this machine without generating too much CPU load.</p> <p>HW installation was fairly easy, but with the software the trouble began&#8230; The supplied drivers does not run on <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2011/10/silversurfer-patched-for-amiga-500/">SilverSurfer patched for Amiga 500</a></span>]]></description>
			<content:encoded><![CDATA[<p>I just purchased a new HW goodie for my classic Amiga 500. A <a href="http://www.vesalia.de/e_a500clockport.htm">clockport adapter</a> and a <a href="http://www.icomp.de/products/silversurfer.htm">SilverSurfer</a> serial card that allows high baudrates (e.g. 115200 baud) on this machine without generating too much CPU load.</p>
<p>HW installation was fairly easy, but with the software the trouble began&#8230; The supplied drivers does not run on an Amiga 500 but only on an A1200 <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Being a real retro hacker I had a look at the driver binary, disassembled it and found out that the code could be easily patched to run on an A500, too.</p>
<p>Now it works like a charm even on the 680000 machines. Here try yourself: <a href="http://www.lallafa.de/files/silversurfer104-a500.zip">silversurfer104-a500.zip</a></p>
<p>If you want to know how this was done&#8230; then read on&#8230; Be warned: technical details ahead <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3><span id="more-364"></span>1. Take a close look at the binary</h3>
<p>First of all I did a disassembly of the original driver binary. As the Amiga binaries are in the LoagSeg()able Hunk Format you need a tool that can cope with this type of files.</p>
<p>Fortunately, in my <a href="http://github.com/cnvogelg/amitools">amitools Project</a> I am developing a tool called <strong>hunktool</strong> that allows to inspect those files. With the help of the dissassemblers <a href="http://sun.hasenbraten.de/~frank/projects/">vda68k</a> or m68k-elf-objdump from the gnu toolchain (here created like described in the <a href="http://en.wikibooks.org/wiki/Aros/Platforms/68k_support/Developer/Compiler">68k AROS</a> project) it even can disassemble the code segments&#8230; Since my tools are written in Python 2.x they run almost everywhere&#8230;</p>
<p>On my Mac I did a:</p>
<pre>&gt; hunktool info -A silversurfer.device &gt; surfer.txt</pre>
<p>Voila! A full disassembly nicely annoted with relocations was generated. You get something like this:</p>
<pre>silversurfer.device TYPE_LOADSEG
 header (segments: first=0, last=0, table size=1)
 #000  CODE   size 000037f4  file header @00000018  data @00000020 
 reloc  absreloc32 #1
 To Segment #0:   23 entries

00000000        70ff                          moveq   #-0x1,d0        
00000002        4e75                          rts                     
00000004        7000                          moveq   #0,d0           
00000006        4e75                          rts                     
00000008        4afc                          illegal                 
0000000a        0000 0008                     ori.b   #0x8,d0          ; absreloc32: self: 00000008
0000000e        0000 37f2                     ori.b   #-0xe,d0        
00000012        8002                          or.b    d2,d0           
00000014        0305                          btst    d1,d5           
00000016        0000 0024                     ori.b   #0x24,d0         ; absreloc32: self: 00000024
0000001a        0000 0081                     ori.b   #-0x7f,d0        ; absreloc32: self: 00000081
0000001e        0000 00c8                     ori.b   #-0x38,d0        ; absreloc32: self: 000000c8
00000022        0000 7369                     ori.b   #0x69,d0        
00000026        6c76                          bge.b   0x9e            
00000028        6572                          bcs.b   0x9c            
0000002a        7375                          moveq   #0x75,d1        
0000002c        7266                          moveq   #0x66,d1        
0000002e        6572                          bcs.b   0xa2            
00000030        2e64                          movea.l -(a4),sp        
00000032        6576                          bcs.b   0xaa            
00000034        6963                          bvs.b   0x99            
00000036        6500 5369                     bcs.w   0x53a1          
0000003a        6c76                          bge.b   0xb2            
0000003c        6572                          bcs.b   0xb0            
0000003e        5375 7266                     subq.w  #0x1,(0x66,a5,d7.w*2)</pre>
<p>Now its time to analyse the code and to refresh your amiga knowledge. Decode resident structures, library calls and look out for memory accesses in the range of the clockport&#8230; Have a look at <a href="http://www.icomp.de/products/silversurfer/Inside_Surfer.txt">Inside Silver Surfer</a> and you&#8217;ll find out we have to look for addresses like $d80001 in the driver code&#8230;</p>
<p>For decoding library calls and data structures I wrote two additional tools in amitools: <strong>fdtool</strong> and <strong>typetool</strong>. The first on you run with a library FD file from your Commodore NDK and it gives you details about function calls in a library:</p>
<pre>&gt; ./fdtool NDK_3.1/Includes\&amp;Libs/fd/exec_lib.fd NDK_3.1/Includes&amp;Libs/fd/exec_lib.fd
 base: _SysBase
 #0001     30  0x001e                Supervisor [userFunction,a5]
 #0002     72  0x0048                  InitCode [startClass,d0][version,d1]
 #0003     78  0x004e                InitStruct [initTable,a1][memory,a2][size,d0]
 #0004     84  0x0054               MakeLibrary [funcInit,a0][structInit,a1][libInit,a2][dataSize,d0][segList,d1]
 #0005     90  0x005a             MakeFunctions [target,a0][functionArray,a1][funcDispBase,a2]
 #0006     96  0x0060              FindResident [name,a1]
 #0007    102  0x0066              InitResident [resident,a1][segList,d1]
 #0008    108  0x006c                     Alert [alertNum,d7]
 #0009    114  0x0072                     Debug [flags,d0]
...
</pre>
<p>Now its very easy to decode a jsr -off(a6) library call (see second column for offsets!). typetool gives you the offset of data structures (Unfortunately, not all NDK datatypes are available in this tool right now):</p>
<pre>&gt; ./typetool ExecLibrary
 @0000        ExecLibrary {
 @0000          Library {
 @0000            Node {
0000 @0000/0000 +0004        Node*      ln_Succ               (ptr=True, sub=False)
0001 @0004/0004 +0004        Node*      ln_Pred               (ptr=True, sub=False)
0002 @0008/0008 +0001        UBYTE      ln_Type               (ptr=False, sub=False)
0003 @0009/0009 +0001        BYTE       ln_Pri                (ptr=False, sub=False)
0004 @0010/000a +0004        char*      ln_Name               (ptr=True, sub=False)
 @0014 =0014      } lib_Node
0005 @0014/000e +0001      UBYTE      lib_Flags             (ptr=False, sub=False)
0006 @0015/000f +0001      UBYTE      lib_pad               (ptr=False, sub=False)
0007 @0016/0010 +0002      UWORD      lib_NegSize           (ptr=False, sub=False)
0008 @0018/0012 +0002      UWORD      lib_PosSize           (ptr=False, sub=False)
0009 @0020/0014 +0002      UWORD      lib_Version           (ptr=False, sub=False)
0010 @0022/0016 +0002      UWORD      lib_Revision          (ptr=False, sub=False)
0011 @0024/0018 +0004      APTR       lib_ldString          (ptr=False, sub=False)
0012 @0028/001c +0004      ULONG      lib_Sum               (ptr=False, sub=False)
0013 @0032/0020 +0002      UWORD      lib_OpenCnt           (ptr=False, sub=False)
 @0034 =0034    } LibNode
...</pre>
<p>Furthermore, you can use hunktool to have a look at a hexdump of the segments, too.</p>
<pre>&gt; ./hunktool info -x silversurfer.device
silversurfer-hack.device TYPE_LOADSEG
 header (segments: first=0, last=0, table size=1)
 #000  CODE   size 000037f4  file header @00000018  data @00000020 
 00000000: 70 ff 4e 75 70 00 4e 75 4a fc 00 00 00 08 00 00  p&lt;FF&gt;Nup.NuJ&lt;FC&gt;......
 00000010: 37 f2 80 02 03 05 00 00 00 24 00 00 00 81 00 00  7&lt;F2&gt;&lt;80&gt;......$...&lt;81&gt;..
 00000020: 00 c8 00 00 73 69 6c 76 65 72 73 75 72 66 65 72  .&lt;C8&gt;..silversurfer
 00000030: 2e 64 65 76 69 63 65 00 53 69 6c 76 65 72 53 75  .device.SilverSu
 00000040: 72 66 65 72 20 42 6f 61 72 64 2d 00 20 55 6e 69  rfer Board-. Uni
 00000050: 74 00 00 00 20 52 00 00 20 57 00 00 53 69 6c 76  t... R.. W..Silv
 00000060: 65 72 53 75 72 66 65 72 20 6c 69 67 68 74 73 70  erSurfer lightsp
 00000070: 65 65 64 20 53 65 72 76 65 72 00 00 24 56 45 52  eed Server..$VER
 00000080: 3a 53 69 6c 76 65 72 53 75 72 66 65 72 20 32 2e  :SilverSurfer 2.
 00000090: 31 30 34 20 28 31 33 2e 31 31 2e 30 30 29 0d 0a  104 (13.11.00)..
 000000a0: 28 63 29 20 31 39 39 31 2d 45 56 45 52 20 62 79  (c) 1991-EVER by
 000000b0: 20 56 4d 43 20 48 61 72 61 6c 64 20 46 72 61 6e   VMC Harald Fran
 000000c0: 6b 0d 0a 0d 0a 00 00 00 00 00 00 f4 00 00 00 d8  k..........&lt;F4&gt;...&lt;D8&gt;
...</pre>
<p>With the help of these tools and my trusty old Developer manuals I soon found out everything I need to know about the driver. See my partially annotated disassembly here: <a href="http://www.lallafa.de/files/silversurfer104-disasm.txt">silversurfer104-disasm.txt</a></p>
<h3>Code Analysis</h3>
<p>The interesting part looking for a silver surfer HW is here:</p>
<pre>; ----- detecte silver surfer -----
00002b9c        48e7 7ffe                     movem.l d1-d7/a0-a6,-(sp)
00002ba0        2f0e                          move.l  a6,-(sp)        
00002ba2        2c6e 003c                     movea.l 0x3c(a6),a6      ; a6 = ExecBase
00002ba6        43fa 0be8                     lea     0x3790(pc),a1    ; a1 = "card.resource"
00002baa        4eae fe0e                     jsr     -0x1f2(a6)       ; OpenResource [resName,a1]
00002bae        2c5f                          movea.l (sp)+,a6         ; libaddr
00002bb0        4a80                          tst.l   d0              
00002bb2        6648                          bne.b   0x2bfc           ; ok! -&gt; look for surfer</pre>
<p>Aha! It looks for card.resource and if this is found then try to detect one. This one works like a charm on an A1200 with a card slot but not on A500 where this resource is missing. So on my machine this driver will never try to even look for the HW&#8230;</p>
<p>Ok, we need to patch this in order to have the driver look for my surfer&#8230; One way of doing this might be to replace the bne.s branch with a bra.s. I chose another option: just replace the resource name and use <strong>ciaa.resource</strong> instead of card.resource <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  This resource is available on the A500, too <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  A simple string replace in the driver binary does the trick!</p>
<p>Now the driver allows to open unit 0 on my machine! Yehaw!!</p>
<p>Unfortunately, it still crashes when trying to actually transfer data with it&#8230; <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>While scanning the disassembly I soon found some long branches (bra.l, bne.l, &#8230;) that are only available on cpus starting with 68020. So my A500 with a 68000 only sees a bogus (odd destination address) byte branch and crashes&#8230;</p>
<p>Damn! Its 68020 code&#8230; But as the init already works I need to find out how many 68020 instructions are actually used.. Again I use hunktool to find this out: It allows to use m68k-elf-objdump to do the disassemlby and this allows me to select the cpu type. So I did a dissassembly for the 68000 and the 68020 and simply diff&#8217;ed the result to see the 68020 portions:</p>
<pre>&gt; ./hunktool info -A -o -c 68000 silversurfer.device &gt; ss000.txt
&gt; ./hunktool info -A -o -c 68020 silversurfer.device &gt; ss020.txt
&gt; diff ss000.txt ss020.txt
307,308c307
&lt; 0000040a    61ff                    bsrs 0x40b                    
&lt; 0000040c    0000 02a6               orib #-90,%d0                 
---
&gt; 0000040a    61ff 0000 02a6          bsrl 0x6b2                    
310,311c309
&lt; 00000414    61ff                    bsrs 0x415                    
&lt; 00000416    0000 029c               orib #-100,%d0                
..</pre>
<p>Aha! Its only the long branches&#8230;  And we are lucky ones: the binary is only 16k and so each long branch could be converted into a 68000 compatible word branch&#8230; The spare word in each instruction will then be filled with a NOP opcode&#8230; So I could patch the binary in place and do not need to relocate anything&#8230; Phew!</p>
<p>The branch conversion actually needs to clear the branch offset in the first word (0xff -&gt; 00), remove the next word and keep the lower branch offset. Then add a NOP opcode word. This could be done by hand, but we are hackers so I wrote a little Python script to perform the patch: <a href="https://github.com/cnvogelg/amitools/blob/master/hacks/fix_bsrl.py">fix_bsrl.py</a></p>
<p>Just call it with the offsets to patch and it will do the job&#8230; (If you wonder where the global offset 32 in the -a switch comes from: Its the begin of the code segment in the hunk file. You can find the value in the output of hunktool: look for CODE data @20)</p>
<pre>&gt; grep bsrl ss020.txt &gt; offsets
&gt; hacks/fix_bsrl.py -a 32 silversurfer.device offsets
OK: 0000042a  distance: 678
OK: 00000434  distance: 668
OK: 00000e80  distance: 6862
OK: 0000106a  distance: 236
OK: 000010a0  distance: 62
OK: 0000110a  distance: 26
OK: 0000111a  distance: 10
OK: 00002288  distance: 1930
OK: 000026e8  distance: 614
OK: 000028a2  distance: 172
writing 'silversurfer.device.patched'... done</pre>
<p>Ok! Patch complete&#8230;</p>
<p>The driver now works on my A500 without any problems and I can do SLIP via AmiTCP with 115200 Baud resulting in approx. 8 KiB/s FTP transfer rate&#8230;</p>
<p>That&#8217;s it&#8230; I hope you enjoyed my little archeological excursion in hacking classic Amiga driver code&#8230;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2011/10/silversurfer-patched-for-amiga-500/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>plip2slip 0.1 released</title>
		<link>http://lallafa.de/blog/2011/08/plip2slip-0-1-released/</link>
		<comments>http://lallafa.de/blog/2011/08/plip2slip-0-1-released/#comments</comments>
		<pubDate>Sun, 28 Aug 2011 16:13:09 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Mac Stuff]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=357</guid>
		<description><![CDATA[<p>While playing with my A500 recently, I had the idea to try out the TCP Stacks available for this platform. Since the little Amiga lacks a decent ethernet card I had to get along with the internal serial port and a SLIP connection. With 9600 Baud this is very slooow. So I kept on searching <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2011/08/plip2slip-0-1-released/">plip2slip 0.1 released</a></span>]]></description>
			<content:encoded><![CDATA[<p><a href="http://lallafa.de/blog/wp-content/uploads/2011/08/plip2slip01a.jpg"><img class="aligncenter size-full wp-image-314" title="plip2slip01a" src="http://lallafa.de/blog/wp-content/uploads/2011/08/plip2slip01a.jpg" alt="" width="480" height="303" /></a>While playing with my A500 recently, I had the idea to try out the TCP Stacks available for this platform. Since the little Amiga lacks a decent ethernet card I had to get along with the internal serial port and a <a href="http://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol">SLIP </a>connection. With 9600 Baud this is very slooow. So I kept on searching for a faster solution and found a <a href="http://en.wikipedia.org/wiki/PLIP">PLIP</a> implementation on <a href="http://m68k.aminet.net/">Aminet</a>. PLIP using the parallel port is much faster than SLIP, but you need a peer with a parallel port, too&#8230; and that&#8217;s the hard part today <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Following  the same approach as found in my <a title="dtv2ser" href="http://lallafa.de/blog/dtv2ser/">dtv2ser</a> project, I just attached an AVR ATmega microcontroller to the parallel lines of my Amiga and implemented the PLIP counterpart there. The ATmega on the popular <a href="http://www.arduino.cc/en/Main/ArduinoBoardDuemilanove">Arduino 2009</a> boards has a fast serial connection that maps to a USB port via a FTDI 232. This is the ideal data channel for transporting the PLIP packets to your host Mac or PC. With baudrates up to 500 kBaud (~50 KiB/s) and hardware handshaking with RTS/CTS you can easily transfer the data packets very fast to your PC and encapsulate them again in SLIP.</p>
<p>With this idea I started to implement the plip2slip firmware. Fortunately, the <a href="http://aminet.net/package/comm/net/magPLIP38.1">magPLIP</a> driver for the Amiga comes with source and so I could port the code to the AVR. With slight modifications on the Amiga part (patch included) I was able to receive the first packets from the Amiga on the Arduino. Then I implemented a simple Ping mode that receives ICMP Ping Requests transforms them to Replies and returns them to the Amiga: plip2slip soon was a ping machine <img src='http://lallafa.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  I repeated the same thing for the SLIP side and with a patched slattach tool on Ubuntu Linux I was soon able to ping the AVR from this side, too.</p>
<p>With the basic parts of plip2slip in place and working I finally added the transport/bridging mode that transfers all received PLIP packets to SLIP and vice versa. With this mode running I could ping the Ubuntu host from my Amiga! After some IP forward configuration on Ubuntu I was able to reach my home network and also the Internet with the A500.</p>
<p>And its real fast! An FTP download on my Amiga reaches <strong>25 KiB/s</strong> when transferring 10k from Linux! So compared to SLIP with 9600 Baud its a real break through and worth the little hardware effort needed to build the Arduino device&#8230;</p>
<p>There is still lots of potential for tuning and optimizing, but I wanted to share this little project as soon as possible with you. So I crammed up everything you need into a little <strong>0.1 release</strong> that is available on my shiny new <a title="plip2slip" href="http://lallafa.de/blog/plip2slip/">plip2slip homepage</a>. I hope you enjoy it and bring lots of your classic machines back to the net with decent speed&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2011/08/plip2slip-0-1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vbcc 0.9b: An Amiga Cross Compiler for Mac OS X</title>
		<link>http://lallafa.de/blog/2011/08/vbcc-0-9b-an-amiga-cross-compiler-for-mac-os-x/</link>
		<comments>http://lallafa.de/blog/2011/08/vbcc-0-9b-an-amiga-cross-compiler-for-mac-os-x/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 18:46:00 +0000</pubDate>
		<dc:creator>lallafa</dc:creator>
				<category><![CDATA[Amiga]]></category>
		<category><![CDATA[Mac Stuff]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://lallafa.de/blog/?p=345</guid>
		<description><![CDATA[<p>&#160;</p> <p>On my neverending quest to have a powerful cross compiler for m68k Classic Amiga (i.e. OS &#60;= 3.x) for my Mac I had a closer look on the fresh new release of Volker Barthelmann&#8217;s C Compiler.</p> <p>In this post I&#8217;ll describe how to install this nice piece of code on your machine in a <span style="color:#777"> . . . &#8594; Read More: <a href="http://lallafa.de/blog/2011/08/vbcc-0-9b-an-amiga-cross-compiler-for-mac-os-x/">vbcc 0.9b: An Amiga Cross Compiler for Mac OS X</a></span>]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>On my neverending quest to have a powerful cross compiler for m68k Classic Amiga (i.e. OS &lt;= 3.x) for my Mac I had a closer look on the fresh new release of Volker Barthelmann&#8217;s C Compiler.</p>
<p>In this post I&#8217;ll describe how to install this nice piece of code on your machine in a few easy steps!<br />
<span id="more-345"></span></p>
<h3>1. vasm 1.5b</h3>
<p>First we build the cross assembler to assemble the output of vbcc.</p>
<ul>
<li><a href="http://sun.hasenbraten.de/vasm/">http://sun.hasenbraten.de/vasm/</a></li>
<li><a href="http://sun.hasenbraten.de/vasm/release/vasm.tar.gz">http://sun.hasenbraten.de/vasm/release/vasm.tar.gz</a></li>
</ul>
<p>Download the source code from the above link. Now extract it:</p>
<pre>tar xvfz vasm.tar.gz
cd vasm
</pre>
<p>Build the binary with:</p>
<pre>make CPU=m68k SYNTAX=mot</pre>
<p>Finally install with (note we use <strong>/opt/vbcc</strong> as the location for all this):</p>
<pre>mkdir -p /opt/vbcc/bin
cp vasmm68k_std vasmm68k_mot vobjdump /opt/vbcc/bin
</pre>
<p>Ok, the assembler is ready!</p>
<h3>2. vlink  0.14</h3>
<p>vlink&#8217;s homepage and the source can also be found on Frank Wille&#8217;s site:</p>
<ul>
<li><a href="http://sun.hasenbraten.de/vlink/">http://sun.hasenbraten.de/vlink/</a></li>
<li><a href="http://sun.hasenbraten.de/vlink/release/vlink.tar.gz">http://sun.hasenbraten.de/vlink/release/vlink.tar.gz</a></li>
</ul>
<p>Same game here: download source and untarring:</p>
<pre>tar xvfz vlink.tar.gz
cd vlink</pre>
<p>Build:</p>
<pre>mkdir objects
make</pre>
<p>Install:</p>
<pre>mkdir -p /opt/vbcc/bin
cp vlink /opt/vbcc/bin</pre>
<p>Done!</p>
<h3>3. vbcc 0.9b</h3>
<p>Finally, the compiler itself:</p>
<ul>
<li><a href="http://www.compilers.de/vbcc.html">http://www.compilers.de/vbcc.html</a></li>
<li><a href="http://www.ibaug.de/vbcc/vbcc.tar.gz">http://www.ibaug.de/vbcc/vbcc.tar.gz</a></li>
</ul>
<p>Pepare:</p>
<pre>tar xvfz vbcc.tar.gz
cd vbcc</pre>
<p>I removed the -DHAVE_AOS4 in the Makefile just to be sure.</p>
<p>Build:</p>
<pre>mkdir bin
make TARGET=m68k
make TARGET=m68ks</pre>
<p>Install:</p>
<pre>cp bin/vbcc* bin/vc bin/vprof /opt/vbcc/bin</pre>
<p>The compiler is in place now&#8230;</p>
<h3>4. Target Environment</h3>
<p>A cross compiler needs a target environment. This includes the system headers and libraries here for the m68k Amiga platform. Also the implementation for the c standard library (think of printf&#8230;) are required for the target.</p>
<p>Here I only install the amiga m68k target but vbcc supports also other targets. See the following homepage for more details:</p>
<ul>
<li><a href="http://sun.hasenbraten.de/vbcc/">http://sun.hasenbraten.de/vbcc/</a></li>
<li><a href="http://mail.pb-owl.de/~frank/vbcc/2011-08-05/vbcc_unix_config.zip">http://mail.pb-owl.de/~frank/vbcc/2011-08-05/vbcc_target_m68k-amigaos.lha</a></li>
<li><a href="http://mail.pb-owl.de/~frank/vbcc/2011-08-05/vbcc_unix_config.zip">http://mail.pb-owl.de/~frank/vbcc/2011-08-05/vbcc_unix_config.zip</a></li>
</ul>
<p>Download the given archives, one for the m68k target the other for the vbcc descriptions how to run the compiler on a unix-like operating system.</p>
<p>Unzip the archives (If you don&#8217;t have lha on your machine. Have a look in <a href="https://trac.macports.org/browser/trunk/dports/archivers/lha/Portfile">MacPorts</a>!):</p>
<pre>lha x vbcc_target_m68k-amigaos.lha
unzip vbcc_unix_config.zip</pre>
<p>Now install the files into our destination directory:</p>
<pre>export VBCC=/opt/vbcc
mv config $VBCC/
mv vbcc_target_m68k-amigaos/targets $VBCC/</pre>
<p>Done! Now all components are in place and we are ready for our first compile&#8230;</p>
<h3>5. First Test</h3>
<p>Ok, for the first test, a simple hello world is fine (file hello.c):</p>
<pre>#include &lt;stdio.h&gt;
int main(int argc, char **argv)
{
  printf("hello, world!\n");
  return 0;
}</pre>
<p>To compile make sure you have the environment variable VBCC set to the install directory and tha PATH holds the bin directory there:</p>
<pre>export VBCC=/opt/vbcc
export PATH=$VBCC/bin:$PATH</pre>
<p>The compiler always needs the target platform specified with the + switch:</p>
<pre>cv +aos68k -o hello hello.c</pre>
<p>If all went well you have created a Amiga OS LoadSeg&#8217;able binary called hello:</p>
<pre>&gt; file hello
hello: AmigaOS loadseg()ble executable/binary</pre>
<p>Now launch your favorite amiga emulator (e.g. P-UAE) and give it a try!</p>
<p>More information on the compiler and its options can be found in the documentation on the official home page of Volker:</p>
<ul>
<li><a href="http://www.ibaug.de/vbcc/doc/vbcc.html">vbcc Manual</a></li>
</ul>
<h3>6. Amiga OS Development</h3>
<p>If you want to use the Amiga Libraries in your Programs you will need the OS headers and libraries from a NDK. For the last OS 3.9 you can download it here: <a href="http://www.haage-partner.de/download/AmigaOS/NDK39.lha">NDK 3.9</a>. Simply untar the contents somewhere and define the following environment variables:</p>
<pre>export NDK=/path/to/NDK_3.9
export NDK_INC=$NDK/include/include_h
export NDK_LIB=$NDK/linker_libs</pre>
<p>Now a typical compile line looks like:</p>
<pre>vc +aos68k -I$NDK_INC -L$NDK_LIB -o test test.c -lamiga</pre>
<p>Use this to compile a sample taken from the NDK:</p>
<pre>cd $NDK/Tutorials/ARexx/Host
vc +aos68k -I$NDK_INC -L$NDK_LIB RexxShell.c -lamiga</pre>
<p>You can compare your compile (a.out) with the official binary:</p>
<pre>&gt; ls -la RexxShell a.out
-rwxr-xr-x  1 chris  staff  6652  1 Nov  1999 RexxShell*
-rwxr-xr-x  1 chris  staff  5988 18 Aug 20:38 a.out*</pre>
<p>Quite nice small result! Now head on to some own code and enjoy your new compiler!</p>
]]></content:encoded>
			<wfw:commentRss>http://lallafa.de/blog/2011/08/vbcc-0-9b-an-amiga-cross-compiler-for-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

