<?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>DevBlog</title>
	<atom:link href="http://simonowen.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://simonowen.com/blog</link>
	<description>stuff and nonsense</description>
	<lastBuildDate>Mon, 07 May 2012 02:27:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>SimCoupe for Raspberry Pi</title>
		<link>http://simonowen.com/blog/2012/05/07/simcoupe-raspberry-pi/</link>
		<comments>http://simonowen.com/blog/2012/05/07/simcoupe-raspberry-pi/#comments</comments>
		<pubDate>Mon, 07 May 2012 02:23:53 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[SAM Coupe]]></category>
		<category><![CDATA[SimCoupe]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/?p=198</guid>
		<description><![CDATA[Raspberry Pi boards are starting to reach more end users, so it seems like a good time to cover what&#8217;s needed to get SimCoupe running on it. The instructions below will lead you through downloading and building SimCoupe on the Pi itself. If you&#8217;d prefer to download a ready-to-run binary, skip to the end. System [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Raspberry_Pi">Raspberry Pi</a> boards are starting to reach more end users, so it seems like a good time to cover what&#8217;s needed to get <a href="http://simcoupe.org">SimCoupe </a>running on it.</p>
<p>The instructions below will lead you through downloading and building SimCoupe on the Pi itself.  If you&#8217;d prefer to download a ready-to-run binary, skip to the <a href="#simcoupi_binary">end</a>.</p>
<h4>System Requirements</h4>
<p>&nbsp;&nbsp;• Raspberry Pi board (or QEMU ARM setup)<br />
&nbsp;&nbsp;• Debian &#8220;squeeze&#8221; (<a href="http://www.raspberrypi.org/downloads">debian6-19-04-2012</a>) image written to SD card<br />
&nbsp;&nbsp;• Ethernet connection for software downloads</p>
<h4>Building From Source</h4>
<p>As a first step we add the <em>pi</em> user to the video group, so it has permission to use the framebuffer device (/dev/fb0). This is needed to run SimCoupe from the console:</p>
<pre><code>$ sudo usermod -a -G video pi</code></pre>
<p>For this to take effect you&#8217;ll need to log out and back in again:</p>
<pre><code>$ exit</code></pre>
<p>The Debian image includes most of the development tools, but we need some additional libraries, and SubVersion:</p>
<pre><code>$ sudo apt-get install libsdl-dev libz-dev subversion</code></pre>
<p>Press Enter when prompted to confirm the downloads (around 22MB). It&#8217;ll take a couple of minutes to install them once the downloads complete.</p>
<p>Next we fetch the SimCoupe source code:</p>
<pre><code>$ svn co https://simcoupe.svn.sourceforge.net/svnroot/simcoupe/SimCoupe@1413</code></pre>
<p>This will appear to do nothing for around 20 seconds as it determines the list of files to download, so please be patient. The @1413 suffix selects a specific code revision known to work on the Pi. You can remove it to download latest revision, but there may be additional building requirements.</p>
<p>We&#8217;re now ready to compile the code using:</p>
<pre><code>$ cd SimCoupe/SDL
$ make</code></pre>
<p>This will take about 8 minutes, so go make yourself a cup of tea.</p>
<p>Once that completes you should have a binary ready to be launched using:</p>
<pre><code>$ ./simcoupe</code></pre>
<p>Before you do that, let&#8217;s download a SAM game demo to play:</p>
<pre><code>$ wget http://tinyurl.com/manicmdemo</code></pre>
<p>As a final step we&#8217;ll load the ALSA sound driver for Pi audio support, which isn&#8217;t enabled by default.  You&#8217;ll need to run this on every boot, unless you add it to the system startup scripts:</p>
<pre><code>$ sudo modprobe snd_bcm2835</code></pre>
<p>The sound driver is still under active development and considered alpha quality. It&#8217;s more stable than the previous release but CPU usage is still a bit high side, which may interfere with SimCoupe. Future Debian releases should include an updated driver.</p>
<p>To launch SimCoupe and boot the <em>Manic Miner</em> demo use:</p>
<pre><code>./simcoupe ManicMinerDemo.zip</code></pre>
<p><a name="simcoupi_binary"></a></p>
<h4>Binary Download</h4>
<p>Here&#8217;s one I made earlier:</p>
<pre><code>$ wget <a href="http://simcoupe.org/files/simcoupi-1413.zip">http://simcoupe.org/files/simcoupi-r1413.zip</a>
$ unzip simcoupe-raspi-r1413.zip
$ ./simcoupe</code></pre>
<h4>Known Issues</h4>
<p>It currently takes 10 seconds to close the ALSA audio device.  This delay will be experienced when quitting the emulator (Ctrl-F12), or after changing sound settings in the SimCoupe options (F10).  Hopefully a future driver update will fix this issue.</p>
<h4>ToDo</h4>
<p>SimCoupe does not yet take full advantage of the Pi hardware.  A future release will use OpenGL ES for hardware accelerated stretching and alpha blending.  Using a 50Hz/PAL display mode and vsync should also allow perfectly smooth scrolling, with audio scaled slightly to match.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2012/05/07/simcoupe-raspberry-pi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spectrum Pac-Man</title>
		<link>http://simonowen.com/blog/2012/01/19/spectrum-pac-man/</link>
		<comments>http://simonowen.com/blog/2012/01/19/spectrum-pac-man/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 17:59:26 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[SAM Coupe]]></category>
		<category><![CDATA[Spectrum]]></category>
		<category><![CDATA[emulator]]></category>
		<category><![CDATA[pacemu]]></category>
		<category><![CDATA[pacemuzx]]></category>
		<category><![CDATA[pacman]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/?p=184</guid>
		<description><![CDATA[I think I&#8217;ve got Pac-Man back out of my system for now, with the new(ish) Spectrum port and updated SAM version. The Spectrum version turned out to be much bigger than expected, in terms of both conversion effort and community reception. I&#8217;d only planned to do a quick conversion of the graphics to monochrome, and [...]]]></description>
			<content:encoded><![CDATA[<p>I think I&#8217;ve got Pac-Man back out of my system for now, with the new(ish) <a href="http://simonowen.com/spectrum/pacemuzx/" title="Spectrum port" target="_blank">Spectrum port</a> and updated <a href="http://simonowen.com/sam/pacemu/" title="SAM version" target="_blank">SAM version</a>.</p>
<p>The Spectrum version turned out to be much bigger than expected, in terms of both conversion effort and community reception.  I&#8217;d only planned to do a quick conversion of the graphics to monochrome, and spend an evening or two rewriting the graphics routines for the display change.  It did start that way, but snowballed from there.</p>
<p>The early work was done using <a href="http://www.intensity.org.uk/samcoupe/pyz80.html" title="pyz80" target="_blank">pyz80</a>+<a href="http://www.simcoupe.org/" title="SimCoupe" target="_blank">SimCoupe</a>, with a mode 1 screen matching what the Spectrum would use.  Once I got the basic tile drawing working (still only to 8-pixel boundaries), I switched to <a href="http://pasmo.speccy.org/" title="Pasmo" target="_blank">Pasmo</a>+<a href="http://fuse-emulator.sourceforge.net/" title="Fuse" target="_blank">Fuse</a> to check the AY sound mapping, and ensure the rest of the game was running correctly.  I kept a <a href="http://www.youtube.com/watch?v=HvqBFs1HDtE" title="video" target="_blank">video</a> of this first playable version, which still lacked sprites.</p>
<p>The tile support includes the flashing power pills, which the arcade version animates by changing the cell attribute colour.  The SAM version flashes a spare palette entry, used only for the power pill graphics.  Unfortunately, the Spectrum couldn&#8217;t use attribute blocks without affecting the sprites passing over them, so the only option was to flash the display data directly.</p>
<p>Adding the sprites was more trouble than expected due to lack of free memory.  The SAM version has 102 sprites, but at least 24 of the coloured ghost sprites weren&#8217;t needed, since they all looked the same in the Spectrum version.  The remaining 78 sprites still required a whopping 21K to be stored fully pre-shifted.  On top of that the 256 background tiles in 4 possible shift positions required an additional 10K.  Ouch.</p>
<p>To save space I halved the resolution of the frequency-to-AY sound look-up table, and stored only the even sprite shift positions; the odd positions could be made up from those at draw time.  Even that extra drawing work was too much at times, causing dropped frames if too many sprites were at odd positions, as they often were in one of the main vertical tunnels.</p>
<p>I really needed the full set of pre-shifted graphics, so I looked for savings in the graphics themselves.  The tile set included a number of gaps, which could be filled by relocating other tiles.  As with the sprites, the duplicate coloured ghosts (used for the attract screen) could also be removed.  The fruit tiles weren&#8217;t needed either, since I used the sprite versions to simplify drawing of the relocated fruit to the right of the maze.  On the sprites side, I eliminated duplicate segments from the large Pac-Man character, as used for the first intermission sequence.  The savings worked, with a little space to spare.</p>
<p>Having all the ghosts look the same was a problem, as each has its own behaviour, and telling them apart is an important part of gameplay.  I considered having a symbol stamped on each, but felt that would spoil the appearance.  I chose to single out just the red ghost (the most dangerous) with a small mouth, so you could tell him apart from the others.  It might even make it look a bit more menacing too!</p>
<p>At that point it was good enough for the first release.  I got plenty of feedback and feature requests, one of which was colour support.  However, the maze isn&#8217;t aligned to Spectrum attribute blocks, as that would require extensive changes to the graphics tile set and/or the ROM (thanks to Andrew Owen for looking into this).  I still thought it was worth trying colour, if only to prove how bad it would look.  Except it didn&#8217;t.</p>
<p>Colour support was added to the sprite save/restore/draw code, with a look-up table mapping sprite number to a single Spectrum attribute value.  As a bonus, the lives and fruit indicators to the side of the maze were also in colour, as they were drawn using the sprite code.  Unfortunately, the extra work to add colour pushed us back into the danger zone, causing frames to be dropped in some cases (mostly when the fruit sprite was visible).  I released a <a href="http://www.youtube.com/watch?v=69J3D-XGdlg" title="video" target="_blank">video</a> showing colour support in action, but took care to mask the speed problem by my choice of route through the maze.  The video was a hit, so I needed to fix the running speed, fast!</p>
<p>The biggest time saving was a relatively simple one; rather than save and restore the previous attribute blocks for each sprite, I just needed to paint the old location with the current screen attribute.  This, combined with other tweaks to the save/restore code was enough, and the colour version was ready for all. At this point it was still an assemble-time option to pick between mono and colour, but the next release added run-time switching, using a sprinkling of self-modifying code.</p>
<p>More recently, some of the Spectrum enhancements have found their way back to the SAM version, just in time for its 8th anniversary update.  The save/restore/draw/clip code is more efficient, reducing the risk of frame overrun in later levels when the game speeds up.  Adding the ROMs to the disk image is much easier, and the game startup is faster due to skipped memory check.  It also adds joystick support, and our old favourite the Q/A/O/P key mappings.</p>
<p>Barring bugs, I&#8217;ll probably not return to this project for a while.  That might even give time to look into the feasibility of <a href="http://en.wikipedia.org/wiki/Mr._Do!" title="Mr. Do!" target="_blank">Mr. Do!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2012/01/19/spectrum-pac-man/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZXodus Engine</title>
		<link>http://simonowen.com/blog/2011/09/29/zxodus-engine/</link>
		<comments>http://simonowen.com/blog/2011/09/29/zxodus-engine/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 11:50:25 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Spectrum]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/?p=148</guid>
		<description><![CDATA[Andrew Owen recently released his ZXodus Engine for the Spectrum, which provides a 9&#215;9 tile grid (144&#215;144 pixels), with independent attribute control for each 8-pixel display byte. He seemed particularly chuffed it achieved a rainbow processing effect across 18 blocks, when most people stopped at 16. While it was great he made it freely available, [...]]]></description>
			<content:encoded><![CDATA[<p>Andrew Owen recently released his <a href="http://www.worldofspectrum.org/infoseekid.cgi?id=0026639" title="ZXodus Engine"><em>ZXodus Engine</em></a> for the Spectrum, which provides a 9&#215;9 tile grid (144&#215;144 pixels), with independent attribute control for each 8-pixel display byte.  He seemed particularly chuffed it achieved a rainbow processing effect across 18 blocks, when most people stopped at 16.</p>
<p>While it was great he made it freely available, I have to admit I didn&#8217;t think the technical side was all that special.  The <strong>LD</strong>/<strong>PUSH</strong> technique for inlining data had been used elsewhere, and there had been plenty of rainbow processors too.  Was I missing something?  The best way to find out was to attempt to write my own version.  I ran the official <em>ZXodus</em> demo to see what it looked like, but avoided looking at the code so I wasn&#8217;t influenced in any way.</p>
<p>As with all raster-level effects on the Spectrum, it requires an interrupt mode 2 handler to give a consistent starting point at the beginning of the frame.  To that you add a large (~15KT) delay loop to wait until the TV raster is at the required position to begin racing the beam.  I used trial and error (and the debugger in <a href="http://fuse-for-macosx.sourceforge.net/Site/Fuse_for_Mac_OS_X/Fuse_for_Mac_OS_X.html" title="MacFuse">MacFuse</a>) to get me close enough to start work on the real code.</p>
<p>The simplest and fastest way to writing a block of 18 attribute bytes is:</p>
<pre><code>     ld   sp,xxxx   ; 10
     ld   hl,xxxx   ; 10
     ld   de,xxxx   ; 10
     ld   bc,xxxx   ; 10
     push bc        ; 11
     push de        ; 11
     push hl        ; 11
     ld   hl,xxxx   ; 10
     ld   de,xxxx   ; 10
     ld   bc,xxxx   ; 10
     push bc        ; 11
     push de        ; 11
     push hl        ; 11
     ld   hl,xxxx   ; 10
     ld   de,xxxx   ; 10
     ld   bc,xxxx   ; 10
     push bc        ; 11
     push de        ; 11
     push hl        ; 11
                    ; = 199T</code></pre>
<p>That is comfortably below the 224T per scanline on a 48K Spectrum.  However, that doesn&#8217;t include memory contention delays due by the ULA reading lower RAM when drawing the main display.  Contention affects 128T of each scanline, leaving a 96T region (right border, retrace, left border) free of delays.  The <strong>LD</strong> instructions and their immediate operands are in upper RAM, so they&#8217;re unaffected by contention.  That just leaves the <strong>PUSH</strong> instructions to worry about, which take an additional ~5T in contended areas.  If we position the code so the final 9 instructions are within the 96T region, only the first 3 <strong>PUSH</strong>es will be contended.  That gives us a new total of ~214T, which is still below the scanline limit.</p>
<p>Another requirement for rainbow processors is that the raster must not catch us mid-draw, or you&#8217;ll see a mix of old and new data, spoiling the effect.  This is made even more challenging by our use of the stack, which writes top-down; rather than trying to outrun the raster we&#8217;re running directly towards it!  Our wider 18-block effect further reduces the time available for the drawing code, requiring us to complete it in just (224-18*4)=152T.  Using our best-case contended timings from the code above the drawing code takes ~169T, which is too slow.</p>
<p>To fix this we need to cut the time between the first and last write, which means pre-loading more values into registers.  <strong>AF</strong> is no use, and <strong>IX</strong>/<strong>IY</strong> are too slow, but the alternate set of main registers are perfect.  It does require an extra 8T for two <strong>EXX</strong> instructions, but still have enough time to spare.</p>
<p>Here&#8217;s the updated code:</p>
<pre><code>     ld   sp,xxxx   ; 10
     ld   hl,xxxx   ; 10
     ld   de,xxxx   ; 10
     ld   bc,xxxx   ; 10
     exx            ;  4
     ld   hl,xxxx   ; 10
     ld   de,xxxx   ; 10
     ld   bc,xxxx   ; 10
     push bc        ; 11 (~16)
     push de        ; 11 (16)
     push hl        ; 11 (16)
     ld   hl,xxxx   ; 10
     ld   de,xxxx   ; 10
     ld   bc,xxxx   ; 10
     push bc        ; 11
     push de        ; 11
     push hl        ; 11
     exx            ;  4
     push bc        ; 11
     push de        ; 11
     push hl        ; 11
                    ; = 214T (~222T)</code></pre>
<p>This new code is <em>just</em> within the scanline limit, and the drawing time of ~143T is within the required 152T window.  This confirms we can achieve the required width of 18 blocks, but there&#8217;s still the issue of the effect position.  Keeping six of the <strong>PUSH</strong> instructions within the uncontended border region gives no control over the location of the first write, which ultimately determines the position of the right edge of the effect.  If we slide the code any earlier or later we&#8217;re bitten by extra contention, which pushes (tee-hee) us over the scanline time limit.  If we aim to have the final instruction finish just before the main screen on the next scanline, the first write is at scanline offset (224-143)=81T.  That&#8217;s 20 columns into the contended area, and since the ULA reads ahead of drawing the each display block, that puts the start of the effect at column 1 on the display.</p>
<p>With any raster effect there&#8217;s also the issue with timing stability.  Before servicing an interrupt the Z80 will finish the current instruction, which could be a modest 4T or a monster 23T.  To keep the effect stable you need to build some padding into the effect timing, or ensure the last instruction before every interrupt has the same timing.  Traditional rainbow effects have enough time to start early and finish late to mask the issue, but with 18 columns there&#8217;s literally no time to spare.  Our only option for stability is to rely on a <strong>HALT</strong> before every interrupt; that&#8217;s relatively easy in a machine code program, but it&#8217;s difficult to avoid flicker in BASIC when you&#8217;re doing other things.</p>
<p>So, I now see 18-column rainbow effect <em>is indeed</em> something special (sorry Andrew!)  It&#8217;s right at the very edge of what&#8217;s possible on a 48K Spectrum, with no time to spare.  For the full effect you just need 144 repeated copies of the code above, starting from T=15900, and with the appropriate values inserted.  No extra padding needed between lines as there&#8217;s no time to spare.  The only change needed for a 128K version is to the start offset, with the extra 4T scanline time seemingly absorbed by contention alignment.</p>
<p>I&#8217;m told that <a href="http://matt.west.co.tt/" title="Matt Westcott">Matt Westcott</a> was first to discover that 18 columns was possible, but don&#8217;t know if it was ever used in a demo.</p>
<p><del datetime="2012-03-17T15:14:03+00:00">I won&#8217;t link my own code here as it&#8217;s very much a work in progress, but I&#8217;m happy to supply it on request.  It may even become part of the official ZXodus code at some point, as it contains a number of enhancements.</del></p>
<p>Edit: Since it did become part of ZXodus II, here&#8217;s my original test program <a href='http://simonowen.com/blog/wp-content/uploads/2012/03/tile.asm'>source code</a>, as detailed above.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2011/09/29/zxodus-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Space Invaders emulator</title>
		<link>http://simonowen.com/blog/2009/12/10/space-invaders-emulator/</link>
		<comments>http://simonowen.com/blog/2009/12/10/space-invaders-emulator/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 20:56:18 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Emulator]]></category>
		<category><![CDATA[Release]]></category>
		<category><![CDATA[SAM Coupe]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/?p=122</guid>
		<description><![CDATA[I thought it was about time I added the Space Invaders &#8220;emulator&#8221; (binary port?) to my website, as I&#8217;d not touched it in over 3 years. Most of the work to get it running was done, with just sound and display rotation left to add. While mulling over the tricky display code I moved on [...]]]></description>
			<content:encoded><![CDATA[<p>I thought it was about time I added the Space Invaders &#8220;emulator&#8221; (binary port?) to my website, as I&#8217;d not touched it in over 3 years.  Most of the work to get it running was done, with just sound and display rotation left to add.  While mulling over the tricky display code I moved on to other projects and it was pretty much forgotten about.</p>
<p>It&#8217;s still unfinished but I&#8217;ve cleaned up the code, prepared a bootable disk, and refreshed myself on the technical details.  It was an interesting contrast to the Pac-Man project I&#8217;d worked on previously.  As before, the challenge was to modify as little of the original ROM as possible, with a virgin copy of the ROM patched at runtime.</p>
<p><strong>CPU</strong></p>
<p>The <em>Space Invaders</em> arcade machine uses an <a href="http://en.wikipedia.org/wiki/Intel_8080">Intel 8080</a> CPU running at just under 2MHz.  The Z80 was released 2 years after the 8080 and was designed to be object-code compatible, so the Invaders code runs on SAM (almost) unmodified.  The Z80 also added many new features, including: IX/IY index registers, alternate registers sets, multiple interrupt modes, CB/ED extended instruction sets, and the relative jump instructions <strong>JR [cc]</strong> and <strong>DJNZ</strong>.</p>
<p>The 8080 has a single interrupt mode equivalent to the Z80&#8242;s IM0, where an instruction is supplied on the bus at interrupt time.  The Invaders hardware supplies both <strong>RST 08</strong> and <strong>RST 10</strong> instructions at a frequency of 60Hz, which drive the overall game logic, including the attract screen.  SAM lacks the extra hardware, but they can both be simulated using IM2 and a line interrupt, without modifying the ROM.</p>
<p>I/O ports 1 to 6 are used for coin and button inputs, as well a hardware bit-shifter circuit.  The shifter takes a 16-bit value (written to port 4 in low/high order), and a left-shift count (written to port 2).  Reading from port 3 returns just the high byte of the result &#8212; more on this later.</p>
<p>As we&#8217;re running the ROM code natively, trapping the I/O requires patching the instructions that make the requests.  The only I/O instructions supported by the 8080 are <strong>IN A,(n)</strong> and <strong>OUT (n),A</strong>, which include the port number as an immediate operand.  This allows us to use a simple loop to find and patch instructions that access ports 1 to 6 (later checked manually to ensure no false-positive matches).  Each occurrence is replaced by a <strong>RST 08</strong> instruction, with the original operand modified to include a flag indicating whether the original instruction was IN or OUT.  We could have used separate RST calls for each, but that requires duplicating the RST handler and modifying more of the original ROM.</p>
<p>Since we&#8217;re simulating the interrupt calls, we have control over how the original <strong>RST 08</strong> and <strong>RST 10</strong> handlers are invoked.  The ROM code for both start with 4 register push instructions, which can be moved to our own interrupt handler, freeing the space for our I/O hook.</p>
<p><strong>DISPLAY</strong></p>
<p>Space Invaders uses a monochrome bitmapped display with a linear layout, similar to SAM&#8217;s mode 2.  The display resolution is 224&#215;256, but like most portrait arcade games the display hardware works in landscape mode.  Fitting the 256&#215;224 (rotated) area on SAM&#8217;s 256&#215;192 screen means we lose 4 character columns from the width of the play area.</p>
<p>As with SAM&#8217;s mode 2 (and the Spectrum), drawing to a non-character aligned position requires bit shifting of data.  Invaders uses this for more control over the vertical position of the invaders, as well as the smooth scrolling of player and invader bullets.  The hardware shifting circuit makes easy work of this, which is a good thing considering the slow CPU speed!  That said, the invader pack does only move one invader at a time, keeping the per-frame drawing to a minimum.</p>
<p>The Invaders display is stored at &#038;2400-3fff, which isn&#8217;t compatible with the 16K boundary requirement for SAM&#8217;s mode 2.  That means redirecting ALL display writes to a suitable upper memory location; something difficult to do from a centralised point in the code.  About the only option is to identify ROM routines accessing the display and provide alternative implementations.</p>
<p>Copying the first 6K of Invaders display to a SAM mode 2 screen in upper memory confirmed the game was running, but revealed another issue &#8212; the bit order within display bytes was reversed compared to SAM, requiring each byte be flipped before writing.  The byte rotation could be avoided by rotating the display in the opposite direction, but that would leave scanline rows in reverse order, requiring a much larger display mapping table to correct.</p>
<p>To map the display accesses to a SAM-compatible location we offset the high byte of the address.  Subtracting an additional 2 from this value also pulls the display up (well, left!) by two columns, centralising the game area on the SAM display.  This clips a character from each side of the title area, and half an invader at the left and right edges, but it&#8217;s only a small difference.  The movement range for the player turret is more limited so it&#8217;s unaffected.</p>
<p>The game now looked great, but play-testing revealed some issues.  When the invader pack reaches the edge of the display it&#8217;s supposed to lower and turn back, but that wasn&#8217;t happening.  Also, player bullets were passing through the invaders without hitting them.  It turned out that collision detection was done by checking the display contents, but it was still reading from the original display location.  Hooking an extra couple of routines to look at the new display area soon fixed that.</p>
<p>A final change was to add a splash of colour to match the original machine.  As the video hardware didn&#8217;t support colour, cellophane strips were added to areas of the monitor: green for lives, bases and player turret, red for the flying saucer at the top.  An equivalent effect can be achieved in the SAM version using blocks of mode 2 attributes, which are unaffected by the display data writes.</p>
<p>Rotating the display to the normal SAM orientation remains a challenge.  My original approach was to apply rotation and scaling to each display write, preserving the original layout.  That meant scaling/masking/combining each byte, so the iconic graphics would suffer some scaling distortion.  A better approach might be to relocate some areas of the display, as I did with the score and fruit areas in my Pac-Man emulator.  It still requires rotation, but only within simple 8 pixel blocks.  Writes from some hook reimplementations could also be optimised for full block writes.</p>
<p><strong>SOUND</strong></p>
<p>The sound effects in the original game are generated using analogue circuits rather than a sound chip, which makes them difficult to emulate in a traditional sense.  Most Space Invaders emulators use sound samples taken from the original machine instead.  I haven&#8217;t implemented the sound yet, but will attempt to create approximate effects with the SAM sound chip.</p>
<p>The source code and bootable disk image are <a href="http://simonowen.com/sam/invaders/">now available</a> on my website, but you&#8217;ll need to provide your own Space Invaders ROM image.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2009/12/10/space-invaders-emulator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Further EDSK extensions</title>
		<link>http://simonowen.com/blog/2009/03/21/further-edsk-extensions/</link>
		<comments>http://simonowen.com/blog/2009/03/21/further-edsk-extensions/#comments</comments>
		<pubDate>Sat, 21 Mar 2009 11:25:18 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[SamDisk]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/?p=86</guid>
		<description><![CDATA[I&#8217;ve been involved with various disk preservation groups over the last few years. A large part of that has been for Spectrum +3 and Amstrad CPC disks, with SAMdisk extended to support copy-protected disks. The +3/CPC disks are usually stored in the Extended DSK (EDSK) image file format, designed to hold (almost) any format compatible [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been involved with various disk preservation groups over the last few years. A large part of that has been for Spectrum +3 and Amstrad CPC disks, with <a href="http://simonowen.com/samdisk/">SAMdisk</a> extended to support copy-protected disks. The +3/CPC disks are usually stored in the <a href="http://www.cpctech.org.uk/docs/extdsk.html">Extended DSK</a> (EDSK) image file format, designed to hold (almost) any format compatible with the uPD765 floppy controller.</p>
<p>Many problem disks have been reverse-engineered to discover why they didn&#8217;t work. A few required emulator enhancements to improve hardware accuracy, but most were missing details from the original disks, due to some creative floppy controller use by the copy protection checks. Not all of these could be supported by the original EDSK specification.</p>
<p>Back in October 2005, I suggested a few <a href="http://groups.google.com/group/comp.sys.amstrad.8bit/browse_frm/thread/829c69bae5501fb8/dc42ab9a6b863327?tvc=1">EDSK enhancements</a>, designed to address some known limitations of the format. The extensions didn&#8217;t involve anything too radical, to maintain as much backwards compatibility as possible.</p>
<p>It&#8217;s now three years later, and a number of new gap-related CPC protections have been identified, which are beyond the scope of even the extended Extended DSK format! I&#8217;ve made further changes to address the new requirements, as well as a correction to a previous one.</p>
<p>My development version of SAMdisk includes support for all the new features, and will be released if the extensions are approved. Other programs will need similar enhancements to take advantage of them, particularly emulators wanting to run some of the difficult disks.</p>
<p>See the <a href="http://simonowen.com/misc/extextdsk.txt">updated extensions</a> document for further details. There are also <a href="http://simonowen.com/misc/extextdsk_samples.zip">sample disk images</a> showing each extension.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2009/03/21/further-edsk-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FdInstall false-positive, again</title>
		<link>http://simonowen.com/blog/2008/12/23/fdinstall-false-positive-again/</link>
		<comments>http://simonowen.com/blog/2008/12/23/fdinstall-false-positive-again/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 00:39:47 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[fdrawcmd.sys]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/?p=74</guid>
		<description><![CDATA[Avira Antivir strikes again, with another false-positive in the fdrawcmd.sys installer. The current virus definitions report the FdInstall.dll installer plugin as infected with TR/Dropper.Gen (a &#8220;generic trojan detection routine&#8221;). As before, avoiding UPX compression on the module is a magic fix. It&#8217;s particularly frustrating because the compression isn&#8217;t hiding anything, since the original module can [...]]]></description>
			<content:encoded><![CDATA[<p>Avira Antivir strikes again, with another false-positive in the <em>fdrawcmd.sys</em> installer.  The current virus definitions report the FdInstall.dll installer plugin as infected with <em>TR/Dropper.Gen</em> (a &#8220;generic trojan detection routine&#8221;).</p>
<p>As before, avoiding <a href="http://upx.sourceforge.net/">UPX</a> compression on the module is a magic fix.  It&#8217;s particularly frustrating because the compression isn&#8217;t hiding anything, since the original module can be extracted using freely available code that they&#8217;re already using!  Why should using a reversible executable packer be an instant black mark?  Shouldn&#8217;t they be more worried about unknown or non-reversible packers?  Grrr.</p>
<p>I&#8217;ve updated the <a href="http://simonowen.com/fdrawcmd/#download">driver installer</a> with a UPX-less version.  Hopefully the complete removal will mean an end to these virus scanner hassles.</p>
<p>Avira have since confirmed the issue as a false-positive, and will be fixing it in a future virus definition update.  Thanks to zogzog for taking the time to report the original problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2008/12/23/fdinstall-false-positive-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SAM/IP</title>
		<link>http://simonowen.com/blog/2007/12/11/samip/</link>
		<comments>http://simonowen.com/blog/2007/12/11/samip/#comments</comments>
		<pubDate>Tue, 11 Dec 2007 23:27:35 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[SAM Coupe]]></category>
		<category><![CDATA[Trinity]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/2007/12/11/samip/</guid>
		<description><![CDATA[The SAM port of uIP seems to be on hold at the moment, so I&#8217;ve been looking at other IP stacks to use until it&#8217;s ready. The most appealing is Mark Rison&#8217;s CPC/IP, not least because it&#8217;s written in Z80 and should work without extensive changes. It also comes with a number of built-in client [...]]]></description>
			<content:encoded><![CDATA[<p>The SAM port of <a href="http://www.sics.se/~adam/uip/index.php/Main_Page">uIP</a> seems to be on hold at the moment, so I&#8217;ve been looking at other IP stacks to use until it&#8217;s ready.  The most appealing is Mark Rison&#8217;s <a href="http://www.cepece.info/cpcip/">CPC/IP</a>, not least because it&#8217;s written in Z80 and should work without extensive changes.  It also comes with a number of built-in client (telnet, finger, host, ping) and server (web, tftp, dns) modules.</p>
<p>So far I&#8217;ve modified the source so it assembles with <a href="http://www.intensity.org.uk/samcoupe/pyz80.html">pyz80</a>.  A global search and replace made quick work of changing the label format from &#8220;.label&#8221; to &#8220;label:&#8221;, but I had to change many data statements manually.  Strings were often combined with other single bytes in defb statements, but the Comet format used by pyz80 doesn&#8217;t allow that, requiring defm be used instead.</p>
<p>The existing code is nice and modular, but there are CPC-specific ROM calls sprinkled throughout them.  All those need to be changed before a test run on SAM, to avoid us unexpectedly jumping into the middle of nowhere!  I changed the stdio.z module to use SAM&#8217;s ROM calls for character output, leaving the cursor control and keyboard input doing nothing for now.  I also replaced the serial module with a dummy ethernet module, with no-op versions of the required interface functions.  They will be fleshed out with calls to the Trinity driver when the rest of the code is ready.</p>
<p>Those changes are enough for a basic run on SAM, without being connected to a real network.  Here&#8217;s what you see when it&#8217;s launched:<br />
<a href='http://174.120.254.194/~simon/blog/wp-content/uploads/2007/12/cpcip.png' title='CPC/IP on SAM'><img src='http://174.120.254.194/~simon/blog/wp-content/uploads/2007/12/cpcip_small.png' alt='CPC/IP on SAM' /></a></p>
<p>The program continues polling for serial and keyboard input in a main loop.  The CPC version uses a 300Hz timer to poll for new data from the serial link, which is buffered for later reading from the main loop.  Each received byte is passed into either the SLIP or PPP module (whichever was configured during the build), which builds up complete datagrams.  These are then passed into the &#8216;ip_handle&#8217; function inside ip.z for the processing.</p>
<p>The SAM implementation will read complete datagrams from the Trinity driver, so they can be passed straight into &#8216;ip_handle&#8217;.  This vastly simplifies the setup above, but introduces a new requirement: ARP.  SLIP and PPP push datagrams back into the link and let the remote end deal with routing.  With ethernet we need to determine the hardware addresses for delivery, for both local and routed traffic.</p>
<p>I&#8217;ll need to write a new arp.z module to sit between the Trinity driver and the IP module.  Outgoing traffic for hosts already in the ARP cache can be sent immediately.  Anything for as-yet-unknown targets must be buffered, and a who-has ARP request made for the address owner to reply.  Once a reply is received, an entry for it is added to the local ARP cache and data buffered for that host is sent.  If no reply is received (ideally after multiple attempts), data for the target will be discarded.  We must also reply to incoming ARP requests for our own address so other hosts can to talk to us.</p>
<p>I&#8217;m still torn between using the SAM ROM routines for I/O and something based on the terminal code I wrote for the <a href="http://simonowen.com/blog/2007/03/19/apple-1-emulator/">Apple 1 emulator</a>.  The ROM code would give the same output flexibility as in BASIC, but the general ROM code is a bit on the slow side.  My own code could be tailored for a specific mode, either mode 2 for speed or mode 3 for hi-res.  It might be easier to stick with the ROM code for now, and change it if it&#8217;s too slow.</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2007/12/11/samip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trinity Ethernet</title>
		<link>http://simonowen.com/blog/2007/11/30/trinity-ethernet/</link>
		<comments>http://simonowen.com/blog/2007/11/30/trinity-ethernet/#comments</comments>
		<pubDate>Fri, 30 Nov 2007 00:09:54 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[SAM Coupe]]></category>
		<category><![CDATA[Trinity]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/2007/11/30/trinity-ethernet/</guid>
		<description><![CDATA[After a break of a few of months, I&#8217;m almost back on the development wagon. I did the odd project tweak during that time but haven&#8217;t spent any quality time working on new features. Last month I picked up one of the first Quazar Trinty boards. Since then I&#8217;ve been working on the ethernet side, [...]]]></description>
			<content:encoded><![CDATA[<p>After a break of a few of months, I&#8217;m almost back on the development wagon.  I did the odd project tweak during that time but haven&#8217;t spent any quality time working on new features.</p>
<p>Last month I picked up one of the first Quazar Trinty boards.  Since then I&#8217;ve been working on the ethernet side, which is based around a MicroChip ENC28J60 chip.  The Trinity board also includes EEPROM and MMC/SD board features, but I&#8217;m leaving those for another time.  My first task was to write a simple network driver, to allow sending and receiving raw packets from BASIC.</p>
<p>Trinity uses the SAM port range &#038;DC to &#038;DF.  The first of these is the microcontroller, which acts as a central hub for all the board&#8217;s features.  The other ports are used for the EEPROM, Ethernet and MMC/SD card, and each needs to be enabled through the microcontroller before it can be used.  Port &#038;DE is used for ENC ethernet chip, and once enabled we can read and write to the chip directly.  Well, almost directly as the link uses the SPI bus.</p>
<p>If you&#8217;re as clueless about electronics as I am you probably won&#8217;t have come across the SPI (Serial Peripheral Interface) bus.  It&#8217;s a full duplex link where each byte written is paired with a read back from the device.  Since reads can&#8217;t be performed without a write, Trinity stores the value read for later.  Reading from SAM reads only the stored value, without accessing the ENC.</p>
<p>SPI introduces a lag between writing a value and reading any result generated by the write, since the stored value is what was read <em>before</em> the write completed.  An additional dummy (zero) write is needed for the actual result to be available for reading.  The lag also means block reads require a dummy write before reading each byte.  Fortunately, the latest Trinity firmware provides an auto-null-writing feature to simplify and optimise this.</p>
<p>The ENC itself has a banked register setup, arranged as 4 banks of 32 registers.  The final 5 registers in each bank are common across all banks, and are used for status registers and bank selection.  All ENC features are accessed through these registers, including reading and writing from the internal 8K data buffer.  The buffer is used for both transmitting and receiving, with a user-defined portion of it configured as a circular receive buffer.  The remaining space is unmanaged and available for transmission storage.</p>
<p>In its power-on state the ENC will see but not receive anything.  It has no hardware address set, no space allocated for the receive buffer, and the packet filter is set to ignore everything.  The driver initialisation is responsible for setting up all of those, and any other register where the defaults are not suitable.  Before we do that it&#8217;s wise to ask the Trinity microcontroller to reset the ENC chip back to a known state.</p>
<p>I started my experimentation from BASIC as it was quicker to tweak the ENC registers and see results than launching the assembler for each change.  Colin supplied a sample disk with macros to access the board, with most containing a couple of OUTs and maybe an IN.  I added to them for higher level functions, such as setting the MAC address and writing blocks of data to the ENC buffer.  Once I was happy this was working I was ready to port it to Z80.</p>
<p>I chose to use 6.5K of the 8K buffer for receiving, with 1.5K left for sending.  That&#8217;s just enough space to send a single full-size ethernet frame.  The packet filter was set to receive packets addressed to our MAC address, as well as anything broadcast to the whole subnet.  Writing a zero to the packet filter register disables it, so all local network traffic is seen.  Couple that with packet decoding and you have an easy network sniffer.</p>
<p>My driver development wasn&#8217;t all smooth sailing, with a few bumps along the way.  The first was my early attempts to write and read the MAC address values, to ensure my new Z80 code was working.  It turns out the subset of ENC registers starting with &#8216;M&#8217; (which includes the MAC registers) have an extra lag on top of SPI, and require double-reading before they return the correct result.  I was also stung by a documented ENC issue with the transmit logic getting stuck under certain conditions.  A bug in my work-around meant I would still occasionally hang during transmits.</p>
<p>Even with the driver initialised and reception enabled, we&#8217;re still not quite ready to handle a test ping from another machine on the network.  Responding to requests requires CRC calculations in the return packets, which involved more work than I wanted to do for a test setup.  That will be the job of of a full IP stack.  It&#8217;s marginally easier to send a ping request <em>from</em> SAM, since the request can be pre-calculated and it&#8217;s only the remote host that needs to worry about dynamic responses.</p>
<p>Even pinging an IP address from SAM is surprisingly involved:</p>
<ol>
<li>Use local IP and netmask to determine whether target IP is on our subnet (if not, send to gateway machine for further routing)</li>
<li>Check local ARP cache for the target IP (if found, goto 5)</li>
<li>Broadcast who-has ARP request to find the MAC of the IP</li>
<li>Wait for ARP reply, then add MAC to local ARP cache</li>
<li>Construct ECHO REQUEST ICMP packet</li>
<li>Send unicast packet to target MAC</li>
</ol>
<p>Fortunately, we can strip this down for the sake of a simple test.  We&#8217;re using a local target so step 1 is unnecessary.  We can also hard-code the MAC of the target machine, to also skip steps 2 to 4.  An ICMP ECHO request packet can then be constructed with fixed details and pre-calculated CRCs.  I used Ethereal on my PC to sniff a request sent with a zero CRC, which was expected to fail, then completed the correct CRC with what it reported.</p>
<p>To send a reply, the target machine will perform the same steps as above, with an ICMP ECHO REPLY packet.  As SAM is currently unable to reply to ARP requests we must use the &#8220;arp&#8221; command on the target machine to add a static entry linking SAM&#8217;s IP with its MAC address.  In my case that meant running the following command in Windows XP:</p>
<p><code>arp -s 10.0.0.88 02:A4:92:E4:D3:20</code></p>
<p>The test MAC address I used was formed from bits of the string &#8220;TRINITY&#8221;, with a few unused zero bits at the end.  Bits 0 and 1 of the first byte are flags, but the rest can be pretty much anything.  I&#8217;ve set flag bit 1 to mark the address as &#8220;locally administered&#8221;, to avoid the (rather unlikely!) clash with existing network devices.  To avoid clashes with other Trinity boards, Colin will be assigning unique addresses to each one sold.  For convenience, the MAC and other network settings will ultimately stored on the EEPROM.</p>
<p>The rigid setup above was enough to show that I could ping my PC from SAM, and have the echo reply read from the receive buffer.  What we needed now was a proper IP stack to plug my driver into&#8230;</p>
<p>While I was working on the driver, Adrian Brown was busy porting Adam Dunkels&#8217; <a href="http://www.sics.se/~adam/uip/index.php/Main_Page">uIP</a> stack from C to Z80.  He&#8217;s made quick work of it too, with ARP and ICMP already working well enough to ping from PC to SAM without the need for any of my cheating (ping times are typically 7-8ms).  Once TCP is ready we&#8217;ll have enough for some real applications!  Web server anyone?</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2007/11/30/trinity-ethernet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ATTRibute port</title>
		<link>http://simonowen.com/blog/2007/08/04/attribute-port/</link>
		<comments>http://simonowen.com/blog/2007/08/04/attribute-port/#comments</comments>
		<pubDate>Sat, 04 Aug 2007 02:29:23 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[SimCoupe]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/2007/08/04/attribute-port/</guid>
		<description><![CDATA[The attribute port (255) is part of SAM&#8217;s Spectrum compatibility, and implements a quirk of the original hardware. On the Spectrum it returns the last value on the ULA side of the bus &#8212; an attribute byte over the main screen or 255 during the border. A handful of Spectrum titles use it to synchronise [...]]]></description>
			<content:encoded><![CDATA[<p>The attribute port (255) is part of SAM&#8217;s Spectrum compatibility, and implements a quirk of the original hardware.  On the Spectrum it returns the last value on the ULA side of the bus &#8212; an attribute byte over the main screen or 255 during the border.  A handful of Spectrum titles use it to synchronise with the top of the main screen, giving the maximum the amount of time to draw sprites without raster shearing.</p>
<p>To my knowledge no SAM software uses it, so it&#8217;s remained near to the bottom of my SimCoupe ToDo list for many years.  I made do with a dummy implementation, returning zero over the main screen and 255 during the border.  Though a bug in the border test meant even that functionality was broken, so port reads have always returned zero!</p>
<p><a href="http://velesoft.speccy.cz">Velesoft</a> recently released a SAM-mouse enhanced version of the Spectrum title <i><a href="http://www.worldofspectrum.org/infoseekid.cgi?id=0001928">Galactic Gunners</a></i>.  It uses the ATTR port to synchronise drawing with the top of the main screen, and the broken SimCoupe implementation caused sprites in the upper 2/3 of the screen to flicker.  In this case fixing the border test bug cured the flicker, but full ATTR support was needed to ensure other titles behaved correctly.</p>
<p>The <i>SAM Technical Manual</i> contains some details of SAM&#8217;s ATTR port behaviour:</p>
<blockquote><p>This register enables the programmer to read the attributes of the currently displayed character cell in modes 1 and 2, and the third byte in every four displayed in modes 3 and 4.</p></blockquote>
<p>There&#8217;s no mention of what happens in the border, thought a quick test was enough to show it didn&#8217;t match the Spectrum&#8217;s behaviour.  In fact it seemed to only return attribute bytes from the main screen.  Time for a test program!  My usual approach with these tests is to make whatever I&#8217;m probing as visible as possible, so the emulation will only match the real thing once everything is perfect.  In this case I used a tight loop reading from the ATTR port and writing the result to CLUT entry 0:</p>
<pre><code>      ld  hl,loop
      ld  bc,&#038;00f8
loop: in  a,(255)
      out (c),a
      jp  (hl)
&nbsp;
</code></pre>
<p>This code must be run with interrupts disabled, and started from a fixed position in the frame to ensure it&#8217;s the same on each run.  Both are most easily achieved by placing the code at the IM 1 handler address of &#038;0038 and using a HALT to guarantee the current instruction is a fixed 4 tstates when the interrupt handler is invoked.  The 4-cycle rounding from the HALT opcode fetch ensures the test begins on the same frame cycle each time.</p>
<p>To make the most of the test output I created a test pattern containing a range of colours, and interleaved with columns of palette colour 0 where the test colour would show through.  Here&#8217;s what I came up with:</p>
<p><a href='http://174.120.254.194/~simon/blog/wp-content/uploads/2007/07/attrtest1.png' title='ATTR Pattern'><img src='http://174.120.254.194/~simon/blog/wp-content/uploads/2007/07/attrtest1_small.png' alt='ATTR Pattern' /></a></p>
<p>And here&#8217;s what it looks like on SAM running in screen mode 1:</p>
<p><a href='http://174.120.254.194/~simon/blog/wp-content/uploads/2007/07/attrtest2.png' title='ATTR Test'><img src='http://174.120.254.194/~simon/blog/wp-content/uploads/2007/07/attrtest2_small.png' alt='ATTR Test' /></a></p>
<p>The time between the port read and the palette write causes the output to be shifted a few screen blocks to the right of the main screen position, reaching into the right border area.  The screens above were taken with the SimCoupe border area set to <i>Complete</i>, to show what would be seen if the ASIC generated the display over the full frame.  This doesn&#8217;t happen on a real machine but is useful to see video changes outside the visible TV area.</p>
<p>The stripes on the main screen and the jagged edges in the lower border are caused by the loop timing not being an exact multiple of the 384 tstates per display line.  The actual timing is complicated by the display memory fetches, mode 1 contention delays, and ASIC port I/O delays, but if you look closely you can see three repeating line end positions.</p>
<p>If SAM&#8217;s border behaviour matched the Spectrum, the border colour should be bright white (colour 127, since the top bit is not used) everywhere except to the right of the main screen where the colour bleeds from the main screen.  To the left of the main screen the colour is actually off-white (colour 120), which matches the right-most attribute on the scanline &#8212; bright white paper with black ink  is 01111000 binary, 120 decimal.</p>
<p>To test the right-most attribute observation with the lower border I added a bright white paper with white ink (01111000 binary, 127 decimal) block to the bottom right of the screen.  As expected this caused the lower and upper border to be coloured bright white.  So during the border areas SAM was returning the last attribute value fetched to draw the main screen area.</p>
<p>As a further test I coloured the screen attributes red, set the screen-off bit to disable the display, coloured the screen attributes green, then read from the ATTR port.  As expected the port returned the red colour, since that was the last screen byte the ASIC read when drawing the display.  Here&#8217;s the BASIC code for the test:<br />
<code><br />
10 PAPER 2 : BORDER 2 : MODE 4<br />
20 BORDER 4 : OUT 254,132 : PAPER 4 : CLS<br />
30 PAUSE 5 : PRINT IN 255 : REM should be 34 for red<br />
40 BORDER 0<br />
&nbsp;<br />
</code></p>
<p>Once the port behaviour was understood the SimCoupe implementation could be enhanced.  When the port is read it uses the current raster position to determine the last on-screen location that the ASIC would have read, and the memory address of the screen data (which depends on the current screen mode).  The existing mode-change ASIC artefact implementation did a lot of this already so the same code could be re-used.</p>
<p>An additional complication is the value returned when the display is disabled, which may no longer be part of the current display.  It requires the ATTR value to be determined when the screen goes from enabled to disabled, giving a value to return for as long as the screen remains disabled.</p>
<p>The test program and source code are available for <a href='http://174.120.254.194/~simon/blog/wp-content/uploads/2007/08/attrtest.zip' title='ATTR Test disk image'>download</a> (9K).  Pressing the NMI button returns you to basic, allowing the screen mode/contents to be changed to see different patterns.  It won&#8217;t work in SimCoupe 1.0, so you&#8217;ll need to wait until the next release!</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2007/08/04/attribute-port/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Atom Lite CF support</title>
		<link>http://simonowen.com/blog/2007/06/25/atom-lite-cf-support/</link>
		<comments>http://simonowen.com/blog/2007/06/25/atom-lite-cf-support/#comments</comments>
		<pubDate>Mon, 25 Jun 2007 23:44:11 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[SamDisk]]></category>
		<category><![CDATA[SimCoupe]]></category>

		<guid isPermaLink="false">http://simonowen.com/blog/2007/06/25/atom-lite-cf-support/</guid>
		<description><![CDATA[With Edwin&#8217;s help, I&#8217;ve just finished adding Atom Lite 1.x support to both SimCoupe and SamDisk. The new interface is a simplified version of the original Atom HDD interface, and is now primarily for Compact Flash use. The Atom Lite uses an ATA feature for 8-bit data accesses, rather than normal 16-bit IDE mode, avoiding [...]]]></description>
			<content:encoded><![CDATA[<p>With Edwin&#8217;s help, I&#8217;ve just finished adding Atom Lite 1.x support to both SimCoupe and SamDisk.</p>
<p>The new interface is a simplified version of the original Atom HDD interface, and is now primarily for Compact Flash use.  The Atom Lite uses an ATA feature for 8-bit data accesses, rather than normal 16-bit IDE mode, avoiding the need for half the data to be latched inside the interface.  The change simplifies the design and allows faster data transfers &#8211; the next data byte is now fetched with a single IN, rather than having to select the high or (latched) low address first.  Streamed media playback anyone?</p>
<p>The new interface requires updated B-DOS and HD-BOOT ROM versions to select 8-bit mode, but once set it&#8217;s software compatible with the original interface.  Data can be read from both &#038;F6 and &#038;F7 ports as before, despite no latching being involved this time.  However, the change does means the byte order of the Atom Lite media is reversed (or perhaps un-reversed!) compared to the Atom, which returned the high byte first.  Fear not, existing Atom media can be converted to use Atom Lite byte-order using SamDisk!</p>
<p>The changes to SimCoupe were mainly to the ATA emulation, with enhancements to support 8-bit data mode and 28-bit LBA sector addressing.  The latter allows support for devices beyond the 8GB CHS limit (16383 cylinders, 16 heads, 63 sectors), extending the maximum size to a whopping 137GB.  Even an 8GB card would contain almost 10,000 B-DOS records, which could easily contain every SAM software title ever written!  The Atom Lite implementation is just a cut-down version of the existing Atom C++ class, which has been further simplified as part of the same changes.</p>
<p>The SamDisk changes were also fairly trivial, especially as there&#8217;s no ATA emulation to worry about.  The byte order of the media is determined by examining the <i>BDOS</i> signature at offset 0xe8 in the first record (which follows the boot sector and record list).  With the original Atom (seen as &#8220;DBSO&#8221;) data accesses must be byte-swapped after reads and before writes.  This allows all record-level commands to work transparently on both media.  A new command-line option (/bs) forces byte-swapping of entire images, used for the Atom <-> Atom Lite conversion mentioned above.  Simply read the device to an HDF image using the byte-swap option, then write the converted image back to the original device.</p>
<p>The Atom Lite 2.x boards are expected to include a Dallas clock chip, with registers access through the same floppy 2 ports.  SimCoupe support will be added once the details have been confirmed&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://simonowen.com/blog/2007/06/25/atom-lite-cf-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: simonowen.com @ 2012-05-18 00:47:21 -->
