2015 Retrochallenge Winter Warmup, Retrochallenge

Retrochallenge 2015/01 – Post 03

Status Update

(This is part three of the chronicle of my Retrochallenge 2015/01 submission, which is to port the modern-day Apple II game, Structris, to the Atari 8-bit home computer using an obscure language called PL65. The mediocrity starts here.)

Nice weather persuaded me to go for a mountain bike ride rather than code so I didn’t make much progress this weekend. But a few nights ago, I was able to get a scrolling routine working. It is currently written in straight PL65 and isn’t animating as quickly as I would’ve hoped. I plan to ignore this problem for now. I’d rather have something that resembles the original Apple II version of Structris at the end of the month even if that means it’s running poorly.

INT A1, A2
  A1 = BL ! Address of bottom left of the Tetris well
  A2 = A1 - 32
  P1 = A1 P2 = A2 
  ! loop until we hit the gray wall on the right
  WHILE V1 <> $88 DO
    ! loop until we hit the top of the screen
    WHILE H > 0 DO
      IF FILL = 0 AND V1 = $00 THEN FILL = 1 ENDIF
      IF FILL = 1 THEN 
        V1 = V2  ! Copy pixel from above
      P1 = A2       ! Point to prev pixel
      A2 = A2 - 32  ! Address of next pixel (the one above)
      P2 = A2       ! Point to the next pixel 
      DEC H         ! Decrement 
    A1 = A1 + 2 A2 = A1 - 32
    P1 = A1 P2 = A2  
    FILL = 0 H = HEIGHT

 Slightly De-Mystifying the Ill-Behaved STR$()

In my last post, I expressed disbelief that calling the STR$() function to convert integers to strings could cause my custom graphics mode to freak out. After a little bit of RTFM, I see now that PL65’s pointer data type relies on zero page memory locations.

pl65_pointers_noteSo it does make more sense that the function has the possibility of interfering with system-related zero-page shadow registers. I’ll need to look at that compiler option to see if anything is suspicious. And if I’m willing to really get to the bottom of it, I can force the function to compile to a specific memory location and attempt tracing through the generated code. For now I have a work-around in place.

Here is the definition of Noahsoft’s STR$() function.

POINTER strptr
BYTE strval BASED strptr

    DEC A
    IF B>=58 THEN

Apple LoRes Graphics on the Atari

The original version of Structris on the Apple II uses the LoRes graphics mode. This is a very blocky but also very colorful 40×80 mode that uses very little RAM (1 nybble per pixel). This means that each Tetris shape can have its own color and the player and walls can have distinct colors, too. Because not much RAM is required, this means that moving shapes around doesn’t take as many cycles as a higher resolution graphics mode.

Mode Pixel Width Pixel Hgt Bytes per Line Screen Resolution Total RAM
Apple LoRes 4 color clocks 4 scan lines 40 bytes 40×80 800

On the Atari computer, only with the GTIA chip, which replaced the CTIA chip found on the earliest model 400s and 800s, does the Atari begin to approach the level of freedom for number of colors found in Apple’s LoRes mode. Atari’s graphics modes 9, 10, and 11 allow going beyond the 4 or 5 color modes possible with the CTIA, but each with its own tradeoffs.

I decided to go with mode 10 (ANTIC mode F), which allows me to pick any 8 color/luminance combinations along with the background which will be black. Unfortunately this still isn’t quite enough to faithfully reproduce Structris. I have enough colors for the Tetris pieces and walls but not enough for a blinking white pixel for the player.

The bad news is, out of the box, Atari mode 10 requires 8K of RAM. This would make moving pixels around very expensive. My solution was to take advantage of Atari’s ability to create custom graphics modes using the display list.

To save processor and RAM resources, my display list is set up to point to the same memory location for each set of 4 scan lines. This brings down the RAM required from 8K to 2K. But I noticed that the original Apple II Structris never exceeds using 32 of the 40 available pixels on any line. This allowed me to set the presumably rarely used Narrow Playfield bit in the DMACTL register. So instead of 80 bytes per line, it will be 64 bytes per line. This means the ANTIC chip requires less time to scan memory and gives that time back to the 6502.

More cycles means I can be a lazier programmer.

Mode Pixel Width Pixel Hgt Bytes per Line Screen Resolution Total Bytes
Standard Mode 10 2 Color Clocks 1 scan line 40 bytes 80×192 7680
My Custom Mode 10 2 Color Clocks 4 scan line 32 bytes 64×40 1280

Here is my display list at the moment. Note that each set of 4 scan lines point to the same memory location and each row requires 32 bytes ($20). (Output generated from the sweet “atari800” emulator’s debug console).

> dlist
8DA0: 2x 8 BLANK
8DA3: 4x LMS A000 MODE F
8DAF: 4x LMS A020 MODE F
8DBB: 4x LMS A040 MODE F
8DC7: 4x LMS A060 MODE F
8DD3: 4x LMS A080 MODE F
8DF7: 4x LMS A0E0 MODE F
8E03: 4x LMS A100 MODE F
8E0F: 4x LMS A120 MODE F
8E1B: 4x LMS A140 MODE F
8E27: 4x LMS A160 MODE F
8E33: 4x LMS A180 MODE F
8E3F: 4x LMS A1A0 MODE F
8E4B: 4x LMS A1C0 MODE F
8E57: 4x LMS A1E0 MODE F
8E63: 4x LMS A200 MODE F
8E6F: 4x LMS A220 MODE F
8E7B: 4x LMS A240 MODE F
8E87: 4x LMS A260 MODE F
8E93: 4x LMS A280 MODE F
8E9F: 4x LMS A2A0 MODE F
8EB7: 4x LMS A2E0 MODE F
8EC3: 4x LMS A300 MODE F
8ECF: 4x LMS A320 MODE F
8EDB: 4x LMS A340 MODE F
8EE7: 4x LMS A360 MODE F
8EF3: 4x LMS A380 MODE F
8F0B: 4x LMS A3C0 MODE F
8F17: 4x LMS A3E0 MODE F
8F23: 4x LMS A400 MODE F
8F2F: 4x LMS A420 MODE F
8F3B: 4x LMS A440 MODE F
8F47: 4x LMS A460 MODE F
8F53: 4x LMS A480 MODE F
8F5F: 4x LMS A4A0 MODE F
8F6B: 4x LMS A4C0 MODE F
8F77: 3x LMS A4E0 MODE F
8F83: LMS 9F86 MODE 2
8F86: 3x MODE 2
8F89: JVB 8DA0

Finally, a custom LPLOT function maps screen into a 32×40 matrix so that two adjacent pixels are assigned the same color. This is effectively the 4 color color x 4 scan line pixel found on the Apple II LoRes mode.

  P1 = .FRAME_GR + $20 * Y + X 
  V1 = C 

FOR I = 0 TO Y2 + 1 DO
  LPLOT(X1, I, $88)
  LPLOT(X2, I, $88)

In the code snippet here, the instruction LPLOT(X1, I, $88) sets 4 color clocks  to whatever color/luminance is defined in color register 8.

Up Next…

Dunno. Hopefully some progress.

2015 Retrochallenge Winter Warmup, Retrochallenge

Retrochallenge 2015/01 – Post 02

(This is part two of the chronicle of my Retrochallenge 2015/01 submission, which is to port the modern-day Apple II game, Structris, to the Atari 8-bit home computer using an obscure language called PL65. The mediocrity starts here.)


This week I’ve been wading into the cold water of PL65 programming for the Atari 8-bit. There are moments when I’m lulled into thinking I’m really using a modern language to cross-develop for the Atari. And then there are moments when I want to throw my laptop through the wall. I’ve lost a lot of time fighting what I perceive as bugs in PL65. Though I wouldn’t be surprised to find one day that the bugs were in my code and not in PL65.

I’ve been having fun, but I’m a little disappointed that my efforts don’t correspond to progress. Granted, I have been able to explore a lot of  territory new to me, like creating a custom display list (graphics mode) and implementing display list interrupts (to change graphics mode and color registers on-the-fly as the electron gun is traveling down the screen), but for sure I thought I’d to this point after the first weekend.

The only time computers irritate me is when they don’t appear to be acting logical.

A couple of examples:

  • Calling the string function STR$(val) to convert a numeric value to a string is inexplicably affecting my custom display mode, switching from GTIA mode 10 (9 Hues/9 Intensities) to GTIA mode 11 (16 Hues/1 Intensity). I was able to prove that by itself, the inclusion of the most trivial call to STR$() would cause my program to go awry. The PL65 source code for the STR$() function is on public display in the STRING.LIB library.
  • My original idea was to implement 3 display list interrupts:
  1. At the top of the screen to set the PRIOR register to render GTIA mode 10
  2. At the start of the base of the Tetris well to alter the color registers used in the tiles.
  3. At the bottom of the Tetris well base to turn off the GTIA settings so the 4-line text window displays properly.

With 3 display list interrupts (DLIs), the graphics mode became unstable. The DLIs were running in the wrong region. For many hours, I thought this was on me, but like the STR$() problem, it looked to me like calling unrelated PL65 functions was altering the graphics registers. In the end, I had to concede and use only two DLIs.

Paranoia, The Destroya

So now I don’t completely trust the system. I feel compelled to run a tedious compile/run/test cycle for each new line of code so I know which pieces of code might result in new odd behavior.

I know that dealing with display lists and DLIs are extremely sensitive to timing, so it’s possible a logical explanation exists. I just hope nothing else freaks-out. Otherwise I’ll need to come up with a different challenge – or try doing this in Action!.

“Cross-Compiling” using vim, make, and the Atari800 Emulator

Despite the very nice KED full-screen editor, doing the development on a real Atari 800 would be too painful. By now I’ve run a thousand edit/compile/run/debug cycles so I’m glad I spent some time up front to have a Linux-based toolchain. To compile my PL65 code, I run “make”. The basic idea is:

  1. Edit the PL65 source file using vim
  2. Run “make” to convert/move the source file to a Unix directory that is mapped as a hard-drive device within the “atari800” emulator and launch the emulator.
  3. Use the -record, -playback, and max-speed features of the “atari800” emulator to automate the keyboard entry needed to compile the source.
  4. When testing on the Atari, use BeweDOS’s STARTUP.BAT to launch the executable.

Here my toolchain is in action:

vim Syntax file

Here is my vim syntax file. Mostly just syntax-highlighting, however there is a feature with binary numbers which will change color only after 8 bits have been typed.

  1. Copy/paste this text to the file ~/.vim/syntax/pl65.vim
" Vim syntax file
" Language: PL65 for Atari 8-bit computers
" Maintainer: Michael Sternberg
" Latest Revision: 02 January 2015

if version < 600
    syntax clear
elseif exists("b:current_syntax")

" Todo.
syn keyword pl65Todo TODO FIXME XXX DEBUG NOTE

" pl65CommentGroup allows adding matches for special things in comments.
syn cluster pl65CommentGroup  contains=pl65Todo

" Keywords


syn keyword pl65Conditional IF THEN ELSE ENDIF 

syn keyword pl65State FOR TO STEP NEXT DOWNTO

syn keyword pl65Mneumonic BNE BEQ BMI BPL BCC BCS BVS BVC JMP JSR
syn keyword pl65Mneumonic INX DEX INY DEY PHA PLA PHP PLP ASLA LSA 
syn keyword pl65Mneumonic RORA ROLA TSX TXA TAX TYA TAY NOP BRK RTS 
syn keyword pl65Mneumonic RTI SED CLD SEC CLC SEI CLI CLV LDA STA LDX 
syn keyword pl65Mneumonic STX LDY STY CMP CPX CPY AND ORA EOR BIT ASL 
syn keyword pl65Mneumonic LSR ROL ROR INC DEC ADC SBC 

syn region pl65String start='"' end='"'

syn match pl65Comment "!.*$"
syn match pl65Comment "!.*!$"

syn match   pl65Label          display "[:]<w+>"
syn match   cexprNumber        display "<d+>"
syn match   cexprNumberHex     display "[$]<[0123456789ABCDEFabcdef]+>"
syn match   cexprNumberBin     display "[%]<[01][01][01][01][01][01][01][01]>"

syn region  pl65CommentL start="!" skip="\$" end="$" keepend contains=@pl65CommentGroup,@Spell

" Define the default highlighting.
" For version 5.x and earlier, only when not done already.
" For version 5.8 and later, only when and item doesn't have highlighting
" yet.
if version >= 508 || !exists("did_pl1_syn_inits")
    if version < 508
        let did_pl1_syn_inits = 1
        command -nargs=+ HiLink hi link <args>
        command -nargs=+ HiLink hi def link <args>

    hi def link pl65Command         PreProc
    hi def link pl65Type            Type
    hi def link cexprNumber         Number
    hi def link pl65State           Statement
    hi def link pl65Mneumonic       Statement
    hi def link pl65Conditional     Statement
    hi def link pl65Todo            Todo
    hi def link pl65Label           Label
    hi def link cexprNumberHex      Special
    hi def link cexprNumberBin      Special
    hi def link pl65String          String
    hi def link pl65CommentL        pl65Comment
    hi def link pl65Comment         Comment

    delcommand HiLink

let b:current_syntax = "pl65"

Then copy this text to the file ~/.vim/ftdetect/pl65.vim
This allows files with a .pl65 extension to have syntax-highlighting automatically applied.

au BufRead,BufNewFile *.pl65 set filetype=pl65


The makefile supports the following targets.

Command Description
make Convert source file to Atari format and launch emulator with PL65 in D1: and target diskette in D2: using keyboard playback
make run Launch emulator with diskette containing target executable
make record Launch emulator with keyboard recording enabled
make edit Launch vim with project-specific preferences, such as 2-space indentation


all:	$(IMG)

$(IMG):	$(TAR)
	atari800 -atari -playback build.rec ../Disks/PL65_BW.atr $(IMG) 2> /dev/null

$(TAR): $(SRC) $(UTL)
	./pl65_to_prg $(SRC) > ../Work/$(TAR)

$(UTL): $(UTL).c
	gcc -o $(UTL) $(UTL).c

.PHONY: run
	atari800 -atari $(IMG)

.PHONY: record
	atari800 -atari -record build.rec ../Disks/PL65_BW.atr $(IMG)

.PHONY: edit
	vim -u ./.vimrc $(SRC)

.PHONY: norun
	atari800 -atari ../Disks/PL65_BW.atr $(IMG)

Utility for Converting PL65 source from Unix to Atari

This C program converts a Unix text file to have Atari end-of-line characters. It also strips out PL65 comments, but doesn’t support comments on the same line as PL65 code. Instead it makes a mess of things.

/* Convert EOL from Unix to Atari
   Also skip PL65 comments "! this is a comment"
   Note: Does not support comments on same line as code.
#include <stdio.h>

void display_usage(void);

#define A8_EOL 0x9b

int main (int argc, char* argv[])
    FILE* fp; 
    unsigned char ch;
    char state = 0;

    if (argc != 2)

    fp = fopen(argv[1], "r");

    if (fp == NULL)
        fprintf (stderr, "Unable to open [%s] for readn", argv[1]);

    /* while (!feof(fp)) */
    while (state >= 0)
        ch = fgetc(fp);
        if (feof(fp)) { state = -1; }
            /* Convert Unix EOL to Atari 8-bit EOL */
            if (ch == 'n') { ch = A8_EOL; }

            if (state == 0 && ch == '"') 
                state = 1;
            else if (state == 1 && (ch == '"' || ch == A8_EOL))
                state = 0;
            else if (state == 0 && ch == '!') 
                state = 2;
            else if (state == 2 && (ch == A8_EOL))
                state = 3;
            else if (state == 3 && (ch == '!'))
                state = 2;
            else if (state == 3 && (ch != '!'))
                state = 0;

            /* Skip comments (!) */
            if (state == 0 || state == 1) fputc(ch, stdout);



void display_usage(void)
    fprintf(stderr, "Usage: pl65_to_prg <filename>n");
    fprintf(stderr, "Output sent to stdoutn");

 Up Next…

Mimicking (well, closely enough) the Apple’s Lo-Res graphics mode on the Atari 8-bit. This time. I promise.


2015 Retrochallenge Winter Warmup, Retrochallenge

Retrochallenge 2015/01 – Post 01

(This is part one of the chronicle of my Retrochallenge 2015/01 submission, which is to port the modern-day Apple II game, Structris, to the Atari 8-bit home computer using an obscure language called PL65. The mediocrity starts here.)

Hello, PL65

To get things going, I wanted to talk a bit about Noahsoft’s PL65. It was published towards the end of the 8-bit era and, as far as I know, distributed but for a few months solely via mail order. Quarter-page ads for PL65 can be found in Atari User (UK) between late 1987 and early 1988. Given it’s timing and duration on the market, it’s often regarded as the rarest of programming software titles for the Atari home computer.

If you are reading this in early 2015, you can still examine a current eBay auction for a copy of Noahsoft’s PL65. The asking price is 295.95 GBP or $461.46 USD. Yikes.

Just so there is no confusion, another programming language called PL/65 pre-dated Noahsoft’s. As early as 1978, Rockwell International offered a language called PL/65 to support their second-sourced R6500 microprocessors, and later, their single-board computer, the AIM-65. However, after looking through a copy Rockwell’s user manual, I saw nothing to suggest Noahsoft’s PL65 was a derivative of the earlier work. The only commonality is the use of ALGOL-like code blocks.

Here’s my demonstration of editing, compiling, and running a minimal program using Noahsoft’s PL65 for the Atari 8-bit home computers.

PL65 Disk Image and User Manual

In case you want to play along, below are links to a PDF of the PL65 User Manual and my version of the PL65 disk image. The disk image is in the ATR file format used by Atari 800 emulators and SIO2PC programs.

PL65 Programming Manual Title
PL65 Diskette image

I modified the 2nd cracked image originally created by the heroic hackers on the AtariAge forums from being a SpartaDOS X-formatted disk to the more 48K-friendly BeweDOS version 1.30 (pronounced Bay-Vay or Bay-Way Dos).

I also re-created the “WELCOME TO PL65” program using screenshots included in the recent eBay auction mentioned earlier. It was missing in the original AtariAge-cracked disk images. The greeting program is found in the file AUTOEXEC.SYS.

Originally PL65 was distributed on an Atari DOS II version 2.5 diskette. Copy protection was enforced by having the compiler stomp over your object code using XOR if it discovered it was not running on the original diskette. For what it’s worth, my version of the “WELCOME TO PL65” program uses the BeweDOS CIO command 40 with AUX1 = 128 to perform the binary load/run needed to launch the compiler and editor. This CIO command is undefined in Atari DOS II, so my program won’t run properly there.

If you are new to BeweDOS, like I am, note that, unlike the menu-driven Atari DOS II operating systems, it uses a command-line interface. To save space on the diskette, I didn’t include all the BeweDOS utilities in the DOS directory. Here are some essential BeweDOS 1.30 commands:

DIR - List contents of the current working directory
CWD - Change current working directory. Path separator is ">".
      For example, to visit the DOS directory, type "CWD >DOS" 
      To return to the root directory, type "CWD >"
ERASE - Delete a file. 
        For example "ERASE MYFILE.PRG"
Dn:  - To switch to another device. For example to switch to
       drive 2, type "D2:". To return to drive 1, type "D1:".

To execute a binary file, usually named with the .COM extension,
simply type the name of the file. If named properly, you may skip the extension.
For example, to run the KED editor, type "KED.COM" or just "KED"

Hello World in Noahsoft’s PL65 for the Atari 400/800

As a brief diversion before diving into coding Structris in PL65, I wanted to share some of the flavor of PL65. First by sharing a minimal “Hello World” example. And later, by adding a few more lines of code that showcase some of the features of the language.

Example Program 1


To spare you the trouble of reading through the PL65 manual, here are some notes about the example program:

  • No line numbers. Oy! Up, Scumbag!
  • PL65 uses the ALGOL concept of organizing code blocks which are defined by the bounding keywords “BEGIN” and “END”.
  • Every program must have a “MAIN” procedure. It is the code block that will be executed first.
  • The “WRTLN” procedure prints text to the terminal display. It appends a carriage return.
  •  The WRTLN procedure is defined in an external library file, TERMINAL.LIB, that must be included at compile-time. PL65 is a single-pass compiler, therefore all procedures and functions must be defined before they can be called.

Example Program 2



  HOME()           ! CLEAR SCREEN
  •  HOME() is an example of a user-defined procedure. In this case, the magic ATASCII character #125 is used to clear the screen and move the cursor to the home position.
  • The GRAPHICS library is included so we can use the SETCOLOR procedure to change the playfield background color (register 2) to dark lavender (color 4, intensity 0). The GRAPHICS library itself includes TERMINAL and STRING libraries that would otherwise be needed for WRTSTR, WRTLN, and STR$.
  • The WHILE/ENDWHILE loop uses a 2-byte integer variable, “I”, which is defined just before the start of the code block. A pitfall looms in that someone may be tempted to declare and initialize the variable using “INT I = 0”. While this is legal, it actually tell the compiler to use addresses $00/$01 (LO/HI) to store integer “I”.
  • The REPEAT/FOREVER is an empty loop construct. It could have other statements between the keywords similar to the WHILE/ENDWHILE example.
  • The language allows numeric values to be represented in decimal, hexadecimal, and binary.

Next Up…

Mimicking (well, as close as possible) Apple’s Lo-Res graphics mode using the Atari display list.

2015 Retrochallenge Winter Warmup, Retrochallenge

2015 Retrochallenge Winter Warmup – Initial Post

The Challenge

For the 2015 Retrochallenge Winter Warmup, my goal is to write a program in Noahsoft’s PL65, an exquisitely obscure programming language for the Atari 8-bit. The program will be a port of the modern-day Apple II game, Structris. The target platform will be an Atari 800 with 48k RAM.

Close-up of quarter-page advertisement in Atari User (UK) September 1987 pp 46


PL65 is a compiled high-level programming language published in 1987 by UK developer Noahsoft for the Atari 8-bit computers.  Its syntax is similar to ALGOL and therefore facilitates a structured design methodolgy. However, it also allows the inclusion of 6502 mnemonic instructions (LDA, STA, etc) as first-class statement types. The PL65 diskette included a full screen editor (KED), compiler (PL65), and libraries to provide functions for handling strings, the terminal, graphics, sound, player/missiles, and controllers. A programmer can extend the language by creating libraries of additional functions.

From what I have been able to find, Noahsoft distributed the software itself and publicized  its existence via quarter-page advertisements in Atari User Magazine (UK) between September 1987 and February 1988.

In May 2007, a half-way cracked version of the diskette appeared on an AtariAge forum. However, it turned out in this version the compiler will don its Godzilla shoes and XOR the object code if a checksum doesn’t match the expected value. In January 2009, a fully-cracked version and good-quality scan of the original documentation were created and also shared in the forum.


Structris is a Tetris-like game for the Apple II created in 2010 by Martin Haye ostensibly as an exercise in structured programming in BASIC and as a test implementation of Ivan X’s Slammer, a utility that enables embedding machine language within an AppleSoft BASIC program as plain-text in REM statements.

The game is a twist on Tetris whereby players control a small blip that exists in an otherwise normal-looking game of Tetris. However, it’s the computer program that is in control of the optimal placement of tetrominos. The computer’s goal is to crush the player’s blip with a tetromino. The player’s goal is to avoid being crushed.

Ken Gagne’s Let’s Play Structris


2014 Retrochallenge Winter Warmup, Retrochallenge

2014 Retrochallenge Winter Warmup – Post 05

(This is part five of the chronicle of my 2014 Retrochallenge Winter Warmup submission.  The mediocrity starts here.)


Source code and disk image available at A2MP3-Xfer Project at Bitbucket


Still have two other projects I’d like to complete before the end of the month:

  • Super Sunday XLVIII – Reverse engineer and alter the American football team/player data for the Apple II game program “Super Sunday” (currently contains teams from 1966-1981) to contain 2013 season teams, players, and statistics. Then simulate the upcoming Super Bowl XLVIII once the teams are decided.
  • Aquarius Tape Library – Create a personal cassette tape library of the games available for the tragic Mattel Aquarius home computer.
2014 Retrochallenge Winter Warmup, Retrochallenge

2014 Retrochallenge Winter Warmup – Post 04

(This is part four of the chronicle of my 2014 Retrochallenge Winter Warmup submission. The mediocrity starts here.)

And Back Again.

Last weekend I was successful in transferring a physical floppy diskette to a .DSK disk image file on the USB thumb drive mounted to the A2MP3 card in my Apple II. To complete the challenge, I also wanted to make the return trip work, too. That is, to transfer a .DSK disk image file found on the USB thumb drive to a physical floppy diskette.

If you would’ve asked me, I would’ve bet good wages that I’d have this working in a day or so. However, most of the week has been instead spent butting my head against the wall fighting silly mistakes.

The French and Endian War

When reading the disk image data and comparing it to what was being written to the floppy, I became convinced the VMusic2 MP3 encoder was sending the bytes as Big Endian 16-Bit words and I needed to swap the byte order to restore it to a stream of single bytes.

The evidence:

1) when peeking at the USB-sourced disk image data being read in the Apple II’s memory, it looked like this:

<START>$44 $01 $a5 $27 $c9 $09 $d0 $18 $a5 ...

2) when examining a disk image file under Linux, the first few bytes looked like this:

$ hexdump -x A2MP3XFR.DSK | head
0000000    a501    c927    d009    a518    ...

So besides the spurious ‘D’ ($44)  at the beginning of the stream in the Apple II’s memory, I concluded the Apple II program was receiving bytes from the VMusic2 controller in a sligthtly jumbled order. And I spent days fighting this.

Then yesterday, in an act as desperate as a trapped miner banging a pipe, I happened to run this command:

$ echo "ABCDE" | hexdump -xc
0000000    4241    4443    0a45

0000000   A   B   C   D   E  n

What the what? This shows the hexdump command was the one guilty of transposing bytes.

Hold on. I need to compose a letter….

Dear hexdump authors,
I hate you.

Spurious D and the Pick of Destiny

Now that the byte order problem had been un-solved, next was to get rid of that 0x44 appearing at the head of the data streamed from the VMusic2 controller. I won’t go through all the failed solutions, but I eventually found a way to skip the D. And I had my first successful USB to physical floppy transfer – and life was grand.

In my moment of elation, I went through all the functions that the program currently performs: A) this week’s Transferring from USB to floppy, Yea!, B) this week’s Formatting a blank floppy, Yea!, C) last week’s Transferring from floppy to USB, What? (From observing the blinking lights, activity was normal about 1/6th of the transfer and then the little flicker normally seen when a file is being closed. Then USB activity ceased).

In my focus on getting the USB to floppy feature working, I had not tested the floppy to USB function in many days. What had I done to break it? I had made so many changes for the red-herring byte transposing.

In the end, it was indeed the changes regarding the Spurious D that was causing the new problems. An option (SKIPREAD) was added so that, when needed, a command sent to the VMusic2 controller would not always jump immediately to the code that read the VMusic2’s response.

Stick a Fork in It

So, now that the program is able to successfully transfer disk images to and from physical floppies, I am happy with its current state and declare “Success!”.

A2MP3-Xfer Project at Bitbucket

A video to follow.

2014 Retrochallenge Winter Warmup, Retrochallenge

2014 Retrochallenge Winter Warmup – Post 02

(This is part two of the chronicle of my 2014 Retrochallenge Winter Warmup submission.  The mediocrity starts here.)

Talking to the 6551

Si. We make all kind of chips: Tortillas, Papas y Plátanos, Silicio.

In order to send or receive data from the Apple II to the VMusic2 USB controller attached to the A2MP3 card, I need to understand how to communicate with, in this case, the Rockwell International R6551 ACIA (Asynchronous Communication Interface Adapter). This handy integrated circuit was designed to enable serial communications for 6502-based systems.

Link to R6551 Datasheet

The R6551’s four internal registers on the A2MP3 card are exposed to the Apple II’s 6502 at four addresses. The exact four are dependent on which slot the A2MP3 card is inserted.

Assuming the A2MP3 card is inserted in Slot #3, the addresses and registers are:

Address R6551 Register Description
  • Contains the current byte being sent to/received from the VMusic2 controller
  • When sending a byte, indicates when the current one has been read from the DATA register by VMusic2 controller.
  • When receiving a byte, indicates when the next one is ready for grabbing from the DATA register
$C0B2 COMMAND Used in order to:

  • Set parity
$C0B3 CONTROL Used in order to:

  • Set BAUD rate
  • Set number of stop bits.

The registers provide several other functions, such as setting the clock source, detecting interrupts and errors but I’ve listed only those needed for this project. Regarding the addresses, if the card were in Slot #4, then the addresses would start at $C0C0, Slot #5: $C0D0, and so on.

Initializing the 6551

For the assembly language portion of my project, I started off with Vince Briel’s original code provided with the A2MP3 kit. Especially for the initialization since I’m making no hardware changes. Assuming the datasheet I found applies to the R6551P (and I’m interpreting it correctly), the predefined baud rates max out at 19.2k and Vince is using the external clock to get to 115k.

ACIA_DAT    equ $C0B0          ; 6551 DATA REGISTER
ACIA_SR     equ $C0B1          ; 6551 STATUS REGISTER
ACIA_CMD    equ $C0B2          ; 6551 COMMAND REGISTER
ACIA_CTRL   equ $C0B3          ; 6551 CONTROL REGISTER

INIT        LDA     #$10       ; $10 = 1/16x EXTNL CLOCK; 1 STOP BIT
            LDA     #$0B       ; PARITY DISABLED, NO IRQS, DTR READY

Sending Bytes

To send a byte from the Apple II to the VMusic2 controller via the 6551, the process is:

  1. Poke the payload byte into the 6551’s DATA register
  2. Peek at bit 4 of the STATUS register, if it’s set then send is complete. Otherwise check again.
            AND     #$10       ; IN STATUS REG 0=NOT_EMPTY 1=EMPTY
            BEQ     NOT_EMPTY  ; WAIT FOR "EMPTY"

Reading Bytes

To read a byte delivered from the VMusic2 card to the Apple II via the 6551, the process is:

  1. Peek at bit 3 of the STATUS register. If it’s set then the reception is complete. Otherwise check again. Give up it’s its been a while.
  2. Peek the payload byte from the DATA register.
READCH      LDX     #$00
            BEQ     BAIL     
            AND     #$08       ; STATUS REG (BIT3) 0=NEXTCHAR 1=FULL
            BEQ     NEXTCHAR   ; WAIT UNTIL "FULL"
            LDA     ACIA_DAT   ; GET CHAR FROM 6551
BAIL        RTS

From Here

In the final project code, there’s a little more going on. I currently have subroutines to:

  • Send an arbirary null-terminated string of characters to the VMusic2 controller (for sending Vinculum commands)
  • Send exactly 256 bytes of memory to the VMusic2 controller (for sending one DOS 3.3 sector)

Both of these call the SENDCH routine described above.

I’ll also need subroutines to:

  • Read an arbitrary double-$0D-terminated string from the VMusic2 controller (for retrieving command responses or error messages).
  • Read exactly 256 bytes from the VMusic2 controller (for reading one DOS 3.3 sector)

Next, a work-in-progress demonstration video of me transferring a floppy image to the A2MP3 and a brief explanation of calling Apple’s RWTS (Read Write Track Sector)

2014 Retrochallenge Winter Warmup, Retrochallenge

2014 Retrochallenge Winter Warmup – Post 01

(This is part one of the chronicle of my 2014 Retrochallenge Winter Warmup submission.  The mediocrity starts here.)

A2MP3 Project: Synopsis

The A2MP3 is a creation of retro-engineer Vince Briel. It’s a peripheral card for the Apple II/II+/IIe/IIgs and allows the Apple II to programmatically control an embedded VMusic2 MP3 player created by Future Technology Devices International Ltd which itself is plugged onto the back of the A2MP3 card. (whew). Audio files are stored on a USB storage device such as a thumb drive. Audio output is sent to a phone jack on the VMusic2. The intermediary between the Apple II and the MP3 player is the workhorse 6551 chip – created to enable UART serial communications for 6502-based systems.

A2MP3The VMusic2 device is a member of F.T.D.I’s Vinculum family of the USB host controller devices. These devices listen for and respond to control commands delivered across its UART signal lines. For example, the command “V3A” will tell the VMusic2 to play all tracks; “VP” will pause playback.

A2MP3-backIncluded with Briel’s A2MP3 kit is a sample Applesoft program and an assembly-language program that work together to provide a menu-driven user interface and sends MP3-specific commands to the VMusic2 device.

However the 15 or so MP3-specific commands are a superset of the commands common to all devices in the Vinculum family. Most interesting to me are commands related to file operations on the USB storage device, such as “MKD” to create a directory or “OPW” to open a file for writing. Just look at all the other commands available in the firmware.

Vinculum Firmware User Manual

With this knowledge it seems possible to transfer a disk image from a physical floppy disk to the USB storage device on the VMusic2 using the following process:

  1. Open a file for writing on the VMusic2 USB storage device using its “OPW” command.
  2. Read a sector from the Apple II floppy disk into RAM using the Read Write Track Sector (RWTS) API included in Apple’s DOS 3.3
  3. Write the data from the Apple’s RAM to the VMusic2 USB storage device using its “WRF” command
  4. Repeat steps #3, #4 for all tracks/sectors on a floppy
  5. Close the file on the VMusic2 USB storage device
2014 Retrochallenge Winter Warmup, Retrochallenge

2014 Retrochallenge Winter Warmup – Initial Post

For the 2014 Retrochallenge Competition Winter Warmup, I have queued three projects with the goal of completing at least one of them. Each of the proposed tasks is meant to be easier than the previous so that if an impeneratrable barrier of possibility is encountered, I can don a parachute and jump to the next.

  • Have fun with Briel Computer’s A2MP3 card and Apple II RWTS – Not that the Apple world needs another way to transfer disk images to/from modern devices, but I would like to write a program for the Apple II that will transfer a disk image from a physical floppy to a USB thumb-drive mounted on an unmodified A2MP3 card. Then – there and back again.
  • Retro Super Bowl Sunday – Reverse engineer and alter the American football team/player data for the Apple II game program “Super Sunday” (currently contains teams from 1966-1981) to contain 2013 season teams, players, and statistics. Then simulate the upcoming Super Bowl XLVIII once the teams are decided.
  • Aquarius Tape Library – Create a personal cassette tape library of the games available for the tragic Mattel Aquarius home computer.