Friday, September 19, 2014

RR-NET emulation dramas

I have been working for the past couple of weeks on getting RR-NET ethernet emulation working so that existing ethernet-enabled programs for the C64 can use it.

This has been a fascinating process.

First, the 8-bit mode of the CS8900a chip that the RR-NET uses is a bit weird, as it still uses 16-bit registers, and so you have to write to the two halves of the registers in turn, among various oddities.

Once I figured out the semantics I managed to get packet receiving working relatively quickly.  Packet transmission proved a little more frustrating, until I eventually removed the buggy code and wrote it again from scratch.    This is often the case with software that it is faster to re-write something than it is to fully understand and fix it.

I wrote a little BASIC test program that just uses POKE to send an ethernet frame, and it works quite nicely.

However, I haven't had a fully positive response from any of the C64 network-enabled programs I could fine.

The Breadbox64 twitter client requires a supertweet account, and Twitter have disconnected supertweet, so no joy there.

udpslave runs, sees packets, and tries to send replies, but seems to mess up the checksum fields. I don't know whether this represents a bug in my RR-NET emulation, the C65GS more generally, or something else.

The Contiki webserver runs, but fails to actually service any request, even though it does respond to ARP, reply to PING (sometimes at least), and can see and parse HTTP requests given to it.  It looks like there is something fishy going on with packet reception.  I might need to improve buffer handling in my ethernet controller to stop packets getting stomped on while you are still reading them out.  You can see what it does here:

The Contiki webserver and IRC client don't want to accept keyboard input on the C65GS for reasons I don't understand.

Most of the other ethernet-enabled software for the C64 requires either GEOS or a Final Replay or similar cartridge, neither of which are an option right now.

So I am at the frustrating point where it mostly works, and I can see very tantalising signs, but can't actually do anything useful with it.

The one program I have yet to test, but intend to, is the RR-NET version of 64NET/2.  64NET/2 is software that I wrote almost 20 years ago to interface C64s to PCs, and which was extended by some volunteers to support the RR-NET in place of a user port cable.  The RR-NET version consists of a patched kernel, which will be easy enough to load on the C65GS, I just need to make a little program that can load a custom kernel and then restart the machine.

Friday, September 12, 2014

Remote keyboard access now works

It is now possible to connect to the C65GS via VNC, and type in the VNC window and havee it communicate to the C65GS automatically.

Let me explain that another way: with a VNC client you can now log into a C65 on the internet and play with it.  It also happens to be the fastest C65 or C64 in existence.

See updated details in the previous post of how to connect, and play around with various things:

Already a few people have been trying it out, as the following screen shots show:

As I write this, someone is busily drawing some art, which began like:


And then:

And finally:

Part of the fun is that more than one person can connect at the same time, and all can type if they wish.  Otherwise, you can just sit and watch other people use it.

Wednesday, September 10, 2014

Remotely view and interact (awkwardly) with the C65GS!

[UPDATE: Fixed IP address]
[UPDATE: Keyboard input through VNC now works!  Keyboard layout is mostly positional for a MacBookPro.  F1=F1/F2, F2=F3/F4 etc, F6-F8 get some displaced keys and F9 gets RESTORE.  Hold RESTORE for about 3 seconds to reset the machine.]

A while back I mentioned that I wanted to make it possible to log in remotely and play with the C65GS.  My reasons are many, including fun your you, but also so that people can get involved in writing and testing software for the C65GS.

We are now at the first mile-stone for this. It is all a bit rough still, but if you are keen, you can now interact with my C65GS when it is plugged into the internet, typically night time my time.

I have pulled together all the pieces so that you can minimally interact with the C65GS.  VNC is used to view the screen, and there is a serial monitor interface that lets you poke around in memory, write to the screen, dump memory etc.  Real keyboard input through VNC is on my TODO list, but isn't there yet -- but keep trying it when you log in incase I have implemented it since your last visit. Keyboard input now works as well.

I have managed to fix a number of problems with the remote head, such that the display is fairly stable, and mostly updates accurately, albeit taking a few frames to update all rasters if there is a lot on the screen.  It is still prone to getting out of sync when there are busy lines, especially in 80 column mode or horizontal resolutions above 320 pixels.

You can see what it looks like now here, or if the C65GS happens to be plugged in and running, then you can point a VNC client to, and see it running live.  (RealVNC is an easy option for Mac and Windows, and Linux, if you don't already have a VNC client installed.  Mac's Screen Sharing VNC client does not work, however.)

The VNC display doesn't accept keyboard input, so you just get to stare at whatever I have running on it, although I intend to fix this in the near future so you can interact with the machine.

Some handy hints:
Hold F9 down for about 3 seconds to reset the machine.  It will boot to C65 mode unless you hold down the C= key (Command key if you are on a mac).
GO64 will get you from C65 mode into C64 mode.
SYS49152 in C64 mode will give you a crude menu to select a D81 disk image to mount from the SD card storage.  Saving to disk doesn't work (yet).
SYS58552 in C64 mode will take you back to C65 mode, without un-mounting the last disk image.

The serial monitor interface is also available by telnetting to port 4510.  This gives you an interactive serial console to the C65GS.

Note that multiple people can connect at the same time, and potentially type at the same time, so be careful.  Also, please keep all content G-rated, since it will be visible to anyone else connecting.  Similarly if you write stuff that becomes visible on the C65GS display via VNC, keep it G-rated there too, please.

You can then hit enter to see the current registers etc.

Type h and hit enter to get some (slightly misleading and out of date) help.

m displays 16 bytes of memory, and M displays 512 bytes of memory.  You can provide an optional 28-bit address to these commands, as they work on the entire address space.

d and D work like m and M, except that they take 16-bit addresses and show what the CPU can see at the specified addresses.

For commands that take an address, the address must IMMEDIATELY follow the letter, e.g., "d1000", not "d 1000", or else you will get a syntax error.

s sets bytes in memory using a 28-bit address, while S sets bytes in the current address space of the CPU using a 16-bit address.

f fills memory.

There are also commands to put the CPU into single step mode (t1), let the CPU run free again (t0), or display the registers after every instruction until you hit enter again (tc).  In single-step mode, hitting enter will run the next instruction, which in all likelihood will be the IRQ entry point, unless you have IRQs disabled.  I will improve this behaviour in time.

Monday, September 8, 2014

More work on remote display

We had a thunderstorm pass right overhead during the night, with one lightning strike close enough that I was woken by the shockwave.  So awake in the middle of the night, I have done a little work on the real-time streaming of video frames from the C65GS.

The previous post showed the initial progress, lacking horitzontal and vertical sync, and having all sorts of artifacts.  Things are now better as the following image shows:

With the work overnight, some artifacts clearly remain, but horizontal sync is now solved.

Vertical-sync is also still a work in progress, and it took a few goes to capture a frame that was more or less centred in the capture, although imperfectly, as the top and bottom borders should be equal size.

The colours aren't right, as the video capture process doesn't include the palette (yet), and I am using the C64 palette, so the colours are less saturated than on the real thing.  Red on a real C65 is just about bright enough to burn your socks off, for example.

Soon I will use the horizontal sync marks to also include a 72KHz audio stream.

I also still have a bit of work to do on the packet encapsulation.  Right now I have to use libpcap to sniff the packets, because my IPv6 encapsulation of them has something messed up.  Once I fix that,  it should be possible to just create a raw IP socket bound to the right IPv6 multicast address, and read the packets as they arrive.

Sunday, September 7, 2014

Working towards remote head

I have been doing a bit of work to support full-resolution remote display of the C65GS via the ethernet port.  My idea is that I can provide internet access for interacting with a C65GS in real-time and at full 60Hz so that people can get a feel for the machine, and also contribute to and test software on it.  In other words, I intend that in a few weeks time it will be possible to use a C65GS remotely via a web browser.

The first step is taking the video output from the VIC-IV and compressing it enough to go out on the 100mbit ethernet port.  This requires compressing the video to 10% of its original size. I have implemented a simple run-length encoder as a first step, which should be fine for 40 and 80 column text displays.  I will make this more sophisticated in time.

I want the remote display to be completely independent of the CPU, so that it can keep displaying even if the CPU is paused for debugging. To achieve this I have implemented a direct communications channel from the VIC-IV to the ethernet adapter that bundled and transmits the data as it arrives. There is a register that enables and disables remote display.

While there is obviously more work to do as the following images show, I was surprised at just how quickly I was able to get it to this point.  Next step will be to figure out what is causing the lost pixels in the stream so that it stays properly registered, and fix the horizontal and vertical synchronisation marks.  But I thought I would include these initial real-time frame captures as a taste of what is to come.

Wednesday, September 3, 2014

Boulder Mark at 48MHz, with working sound

Boulder Mark seems to work now, even though I can't think what I might have fixed that would have addressed the problem it was having.  It does still crash occasionally, but it usually runs to completion.  

So I thought I would post a video of boulder mark running on it to give an idea of how fast the C65GS is.  That turns out to be about 500 frames per second in this test, which is very nearly 100x the score of a stock C64.  The vacuum-like sound is boulder mark making a noise every frame.

As I have mentioned before, boulder mark is a non-linear benchmark, because the first few hundred frames are much more work to draw.

So it is probably a better comparison between the C65GS and Chameleon, since both are fast enough that the slow frames are only a small fraction of the score.

On that basis, the C65GS is about double the speed of the Chameleon, rather than the 4x that SynthMark would suggest.  This makes sense, since SynthMark places a fairly heavy weighting on operations that read from IO and colour RAM, even though they are relatively rare operations.  So, depending on the workload, the speed difference is likely to be somewhere between 2x and 4x, if using normal 6502 opcodes.

SID audio at last, plus CPU and VIC-IV redesign catching

I finally had some time over the last couple of days to get the redesigned CPU and VIC-IV to some reasonable degree of working, so that I can finally begin enjoying the benefit of the work, and making use of the about 2/3 of the FPGA that the redesign has freed up.

I have fixed bugs with the read-modify-write instructions, PLP, PHW, the $nn,Y addressing mode (it had a copy and paste error and was acting like $nn,X), the MAP instruction was no inhibiting interrupts and numerous others.

I also finally got around to making the dummy write in read-modify-write instructions only happen if the target address is $D019, i.e., to acknowledge VIC-II interrupts, thus avoiding an extra cycle in those instructions.

The CPU now passes the Lorenz 6502 tests for all the legal opcodes, and C64 and C65 mode BASIC both work, as does the DOS for the internal drive, making it easier to test a wider variety of software again.  The Lorenz test suite takes about half an hour on a real C64, but all the official 6502 opcodes can be tested on the C65GS in under a minute. This really is a fast 8-bit computer.

However, not everything is right, since Bouldermark crashes for a reason I have yet to discover.  Synthmark64 runs fine, however, and the speed is almost unchanged from the last test.  The slight slow-down is due to putting back a necessary wait-state when reading from colour RAM.

Obligatory screen shot of Synthmark64 running very fast indeed.

I also put some effort into tracking down some bugs in the newly added parts, including the emulated stereo SIDs (although they both come out the same mono audio jack right now).  Apart from some speed issues, which is just as likely due to the 60Hz screen refresh rate as anything, sound is now working, as tested in Bouldermark and Lemmings.

The VIC-IV reimplementation is not yet complete, with multi-colour and bitmap graphics modes still having a few bugs to shake out.  I did manage to get extended colour mode and bitmap modes working to some degree, although multi-colour mode and bitmap modes both have some problems to work out, which I have yet to fully explore.

Along the way I also added support for the DMAgic DMA controller to DMA memory from outside the 1MB C65 address range.  This is used to copy the disk chooser program from the Kickstart ROM to $C000 at start up.  Similarly, chained DMA lists are now supported, and one chained DMA list does the copy as well as clear the screen and colour RAM.  Clearing 4KB RAM and copying another 4KB RAM all takes about 13,000 cycles, about the equivalent of five rasters on a real C64.

The next steps will probably be to debug the multi-colour graphics problems to figure out what is going on there, so that graphics looks right.  Then I might finally get started on implementing writing to SD card and implementing sprites, at which point all core functionality will exist, however flawed and imperfect it may be.

My plan for sprites is to have the 8 normal C64 sprites, plus another 8 (or 16 if I can manage it) 64x64 256-colour sprites.  These will each require up to 4KB of data.  I am thinking about how I can make the sprite data fetching character based, so that the sprites can be made up from 8x8 pixel character tiles, making for much more efficient use of memory.  In principle I could re-use the character generator machinery