kfest2017

An Apple II Build Chain for Inform

During Kansasfest 2017, I gave a presentation on how to use Inform 6.15 to build and run non-Infocom story files on an Apple II using Infocom Z-machine interpreters. The paper below contains the narrative and examples used that presentation.

apple_ii_inform

apple_ii_inform2.pdf  – PDF document

inform_a2.zip – Demo files used during my presentation. This is a companion to the PDF.

Here is a video of that presentation.

Update 2017-09-24: Revised summary at the top of this page, modified the link to the .zip file to no longer point to Dropbox, and added a link to the video of the presentation.

Advertisement
Retrochallenge, Retrochallenge 2016/10

Retrochallenge 2016/10 – Final Post

This is my last entry for my Retrochallenge 2016/10 journal, where I worked towards loading ROM images to an Intellivision from an Atari 800. To jump to the very beginning, click here.

Wrap-Up Video

Success!

I completed everything I originally set out to do.

  • Learned how to use OSS’s Action! programming environment
  • Learned more about OSS’s DOS OS/A+ and DOS XL (originally I was going to use BeWeDOS but decided early on it would be more fitting to use an OSS DOS).
  • Learned how to configure the Atari 850 Interface Module at runtime
  • Wanted to put @InverseATASCII’s Window Gadget Libraries to use
  • Extended the usefulness of my Intellicart! (it no longer was viable with my everyday laptops).

During the month, I also imagined displaying text versions of Intellivision game manuals and controller overlays on the Atari 800. I also envisioned doing a craft project to construct a floppy disk label and sleeve as if floppy-based games had been produced by Mattel Electronics. But Retrochallenges rarely accommodate feature-creep.

Some Surprises

The version of my copy of DOS XL is meant for HAPPY 1050 floppy drives and was not previously available on the Internet as far as I can find. I’ve uploaded it to AtariAge and Archive.org.

It takes much longer to transfer a ROM image to the Intellicart! than I would’ve originally guessed. ROM images also take up much more room on a single density floppy disk than I planned. There’s only room for about 2 ROM files per side. Both the speed and size problems may be due to the fact that the Intellivision uses 10-bit words, so the ROM image format uses 2 bytes to store each word.

I didn’t document this in my journal but along the way,  I upgraded my Atari 1050 floppy drive to be a HAPPY 1050. This will nicely pair it with my version of OSS DOS XL.

It took more work than I would’ve guessed to implement the GUI. This is no fault of the library code I borrowed from Wade, just the nature things.

Thanks!

A big thanks goes to John Linville & Michael Mulhern who volunteered to keep Retrochallenge a thing. Both are already busy with podcasts and normal life. Thanks to Wade Ripkowski (@InverseATASCII) for sharing his work. I learned a lot about programming in Action! by using/viewing his code. And thanks to Mark and crew who originally started it all.

It was fun.

Retrochallenge, Retrochallenge 2016/10

Retrochallenge 2016/10 – Post 6

This is part six of my Retrochallenge 2016/10 journal, where I’m working towards loading ROM images to an Intellivision from an Atari 800. To jump to the very beginning, click here.

This slideshow requires JavaScript.

Adding a User Interface

This week I’ve been working on adding a user interface based in @InverseATASCII’s Action! Window Gadgets found at https://unfinishedbitness.info/tag/action/. This slideshow from my emulator session should show everything except for the transfer because that has to be done on real hardware.

The Code

As we should expect by now, GUI’s require a *lot* of code. The Window Gadgets libraries were published in separate blogs. While it was straight-forward enough to copy the code from the blog entries, I did find there were a small number of DEFINES and supporting functions that were not included in the code snippets. For these I was able to either find in earlier entries, or I created them myself, or found similar functions on atariwiki.org.

Here’s my code, warts and all. (Libraries not included)

INCLUDE "H:DEFINES.ACT"
INCLUDE "H:DEFWIN.ACT"
INCLUDE "H:LIBMISC.ACT"
INCLUDE "H:LIBSTR.ACT"
INCLUDE "H:LIBWIN.ACT"
INCLUDE "H:LIBGADG.ACT"
INCLUDE "H:IOFUN3.ACT"

MODULE

;--------
PROC TITLEBAR()
  BYTE bW1
  bW1=WOpen(2,0,36,3,WINVOFF)
  WPrint(bW1,WPCENT,1,"Intellicart! Downloader")
RETURN

;--------
; OS/A+ 2.0 & DOS XL DRVBYT
; Rtn mnu lst of actve drvs
BYTE FUNC GetDRVBYT(CHAR ARRAY S)
  BYTE DRVBYT=$070A
  BYTE I,J,N,X
  CHAR ARRAY sDn(1)

  I=1;TEST BIT
  J=1;CUR DRV
  N=0;DRV COUNT

  ; Chk Drvs 1-4
  WHILE J<5
  DO
    ; If bit set then Dn active
    ; Inject Drive number into S
    IF DRVBYT&I THEN
      N==+1
      StrB(J,sDn)
      X=4*N-1
      SAssign(S,sDn,X,X)
    FI
    J==+1
    I==*2; Shift left
  OD

  ; Set len(S)
  S(0)=N*4
RETURN(N)

;--------
PROC MsgBox(CHAR ARRAY S)
  BYTE bW,X,Y
  CHAR ARRAY sBtn="[OK]"

  X=19-S(0)/2
  Y=10
  bW=WOpen(X,Y,S(0)+2,3,WINVOFF)
  WPrint(bW,1,1,S)
  ;WPrint(bW,S(0)/2-1,2,sBtn)
  WaitKC()
  WClose(bW)
RETURN

;--------
; Populates S with ROMs found on Dn:
BYTE FUNC GetRomLst(CHAR ARRAY sDn,S)
  DEFINE BUFSIZ="18"
  BYTE INP,COUNT,N,X
  CHAR ARRAY BUF(BUFSIZ)
  CHAR ARRAY MASK(9)
  N=0
  INP=1
  SCopy(MASK,"Dn:*.ROM")
  SAssign(MASK,sDn,1,3)
  Close(INP)
  IF FOpen(INP,6,0,MASK)<=127
  THEN
    DO
      COUNT=FREAD(INP,BUF,BUFSIZ)
      IF COUNT>0
      THEN
         IF BUF(2)<'A THEN
           EXIT
         FI
         N==+1
         X=N*16-15
         SAssign(S,BUF,X,X+16)
      FI
    UNTIL COUNT<>BUFSIZ OR N > 10 OD
  FI
  Close(INP)
  S(0)=N*16
RETURN(N)

;--------
PROC PickROM(CHAR ARRAY sDirEntry,sDn,sM1 BYTE bDrvCnt)
  BYTE bW3,bW2,bCh1,bCh2,X
  CHAR ARRAY sM2(161)
  SCopy(sDn,"Dn:")

  bW3=WOpen(11,5,8,bDrvCnt+2,WINVOFF)
  WTitle(bW3," Dn ")
  DO
    bCh1=GMenuV(bW3,1,1,4,sM1)
    IF bCH1=0 THEN
      EXIT
    FI

    X=4*bCH1-2
    SCopyS(sDn,sM1,X,X+2)

    X=GetRomLst(sDn,sM2)
    IF X=0 THEN
      MsgBox("No ROMs found")
    ELSE
      bW2=WOpen(17,6,18,X+2,sM2)
      WTitle(bW2," ROMs ")
      bCh2=GMenuV(bW2,1,1,16,sM2)
      WClose(bW2)
      IF bCH2>0 THEN
        X=bCH2*16-15+1
        SCopyS(sDirEntry,sM2,X,X+15)
        sDirEntry(0)=15
        EXIT
      FI
    FI
  OD
  WClose(bW3)
RETURN

;--------
PROC GetRomFile(CHAR ARRAY sRomFile,sDn,sDirEntry)
  BYTE L
  CHAR ARRAY S(13)

  ; Extract Basename
  SCopyS(S,sDirEntry,1,8)
  S(0)=8
  RTrim(S)
  L=S(0)

  IF L>0 THEN
    ; Inject "sDn:"
    SCopy(sRomFile,sDn)
    SAssign(sRomFile,":",3,3)
    sRomFile(0)=3
    
    ; Inject basename
    SAssign(sRomFile,S,4,L+4)
    
    ; Inject ext
    SAssign(sRomFile,".ROM",L+4,L+8)
  FI
  sRomFile(0)=L+7
RETURN

;--------
CARD FUNC GetRomSz(CHAR ARRAY sRomFile)
  CARD cRomSz
  CHAR ARRAY S(5)
  SCopyS(S,sRomFile,12,15)
  cRomSz=ValC(S)
RETURN(cRomSz)

;--------
PROC ConfigRS232(BYTE IOCB,bBaud)
  BYTE AUX1
  BYTE AUX2

  ; AUX1: bBaud,8 Bit words,1 stop bit
  ; AUX2: No READY checks
  AUX1=bBaud
  AUX2=0
  XIO(IOCB,0,36,AUX1,AUX2,"R1:")

  ; AUX1: No translation. No parity
  ; AUX2: Unused
  AUX1=32+0+0
  AUX2=0
  XIO(IOCB,0,38,AUX1,AUX2,"R1:")

  ; AUX1: DTR off,RTS off
  ; AUX2: Unused
  AUX1=128+32
  AUX2=0
  XIO(IOCB,0,34,AUX1,AUX2,"R1:")
RETURN

;--------
PROC Send(CHAR ARRAY sRomFile CARD cRomSz BYTE bBaud)
  DEFINE BUFSIZ="128"
  BYTE INP,OUT,bW1,OK
  BYTE ARRAY BUF(BUFSIZ)
  INT  iC,iP1,iP2
  
  OK=1
  iP1=0
  INP=2 ; IOCB #1
  OUT=5 ; IOCB #5

  ; OPEN INPUT FILE
  CLOSE(INP)
  IF FOPEN(INP,4,0,sRomFile)>127
  THEN
    MsgBox("ROM not found")
    OK=0
  FI

  IF OK THEN
    ; OPEN OUTPUT ON ATARI 850
    IF FOpen(OUT,8,0,"R1:")>127
    THEN
      MsgBox("Can't open R1:")
      CLOSE(INP)
      OK=0
    FI
  FI

  IF OK THEN
    bW1=WOpen(7,10,24,4,WINVOFF)
    WPrint(bW1,1,1,"Sending")
    GProg(bW1,2,2,0)

    ConfigRS232(OUT,bBaud)
    DO
      ; XFER BLOCKS FROM INP TO OUT
      iC=FRead(INP,BUF,BUFSIZ)
      IF iC>0
      THEN
        FWrite(OUT,BUF,iC)
      FI
      ; Update Progress
      iP1==+100
      iP2=iP1/cRomSz
      GProg(bW1,2,2,iP2)

      ; Break out on ESC
      IF PEEK(764)=28 THEN
        POKE(764,255)
        iC=0
      FI
    UNTIL iC<>BUFSIZ OD
    WClose(bW1)
  FI

  CLOSE(OUT)
  CLOSE(INP)
RETURN

;--------
BYTE FUNC GetBaud(BYTE X)
  BYTE B,bW,bCh
  CHAR ARRAY sM(26)
  SCopy(sM,"  2400  4800  9600 19200")

  bW=WOpen(7,7,10,6,WINVOFF)
  WTitle(bW," Baud ")

  bCh=GMenuV(bW,1,1,6,sM)
  IF bCh=1 THEN
    B=12 ; 2400
  ELSEIF bCh=2 THEN
    B=13 ; 4800
  ELSEIF bCh=3 THEN
    B=14 ; 9600
  ELSEIF bCh=4 THEN
    B=15 ; 19200(?)
  ELSE
    B=X ; No change
  FI
  WClose(bW)

RETURN(B)

;--------
PROC DisplaySettings(BYTE bW,bB CHAR ARRAY sR)
  CHAR ARRAY sB(7)
  WClr(bW)
  WPrint(bW,1,1,"ROM                   ")   
  WPrint(bW,1,2,"Baud        ")   
  IF sR(0) THEN
    WPrint(bW,6,1,sR)
  ELSE
    WPrint(bW,6,1,"None")
  FI

  IF bB=12 THEN
    SCopy(sB,"2400 ")
  ELSEIF bB=13 THEN
    SCopy(sB,"4800 ")
  ELSEIF bB=14 THEN
    SCopy(sB,"9600 ")
  ELSEIF bB=15 THEN
    SCopy(sB,"19200")
  FI
 WPrint(bW,6,2,sB)

RETURN

;--------
PROC DisplayAbout()
  BYTE bW
  CHAR ARRAY S(26)

  bW=WOpen(6,5,28,14,WINVOFF)

  SCopy(S," Retrochallenge 2016/10 ")
  STRINV(S+1,S(0))
  WPrint(bW,WPCENT,1,S)

  SCopy(S,"Intellicart! Downloader ")
  STRINV(S+1,S(0))
  WPrint(bW,WPCENT,2,S)

  WPrint(bW,WPCENT,3,"[Version 0.1]")
  WPrint(bW,WPCENT,5,"Michael Sternberg")
  WPrint(bW,WPCENT,6,"[16kRAM.com]")
  WPrint(bW,WPCENT,8,"UI Libraries by")
  WPrint(bW,WPCENT,9,"Wade Ripkowski")
  WPrint(bW,WPCENT,10,"[unfinishedbitness.info]")
  WPrint(bW,WPCENT,12,"CC BY-ND 4.0")
  WaitKC()
  WClose(bW)

RETURN

;--------
PROC MAIN()
  BYTE bW1,bW2
  BYTE bDrvCnt,bCh,N,bBaud
  CARD cRomSz
  CHAR ARRAY sM1(56),sM2(17)
  CHAR ARRAY sDn(3),sDirEntry(17),sRomFile(16)

  SCopy(sDn,"Dn:")
  SCopy(sM1," Pick ROM > Send       Set Baud   About      Exit      ")
  SCopy(sM2," Dn: Dn: Dn: Dn:")
  sRomFile(0)=0
  bBaud=14 ; Default to 9600
  bDrvCnt=GetDRVBYT(sM2)

  Winit()
  TitleBar()

  ; Current Rom
  bW2=WOpen(2,19,24,4,WINVOFF)
  ;WTitle(bW2," Settings ")
  DisplaySettings(bW2,bBaud,sRomFile)

  ; Main menu
  bW1=WOpen(2,4,13,7,WINVOFF)
  WTitle(bW1," Main ")
  DO
    bCh=GMenuV(bW1,1,1,11,sM1)
    ; Pick ROM
    IF bCh=1 THEN
      PickROM(sDirEntry,sDn,sM2,bDrvCnt)
      cRomSz=GetRomSz(sDirEntry)
      GetRomFile(sRomFile,sDn,sDirEntry)
      DisplaySettings(bW2,bBaud,sRomFile)
    ; Send ROM to Intellicart!
    ELSEIF bCh=2 THEN
      IF sRomFile(0)=0 THEN
        MsgBox("No ROM Selected")
      ELSE
        Send(sRomFile,cRomSz,bBaud)
      FI
    ; Change Baud setting
    ELSEIF bCh=3 THEN
      bBaud=GetBaud(bBaud)
      DisplaySettings(bW2,bBaud,sRomFile)
    ; Display "About" dialog
    ELSEIF bCh=4 THEN
      DisplayAbout()
    ; Exit to DOS
    ELSEIF bCh=5 THEN
      PUT(125) ; Clear screen
      PRINTE("Bye")
      EXIT
    FI
  OD
RETURN

Too Many Global Variables

I encountered a problem tonight when doing my final compile. I can successfully create a binary file that requires the Action! cartridge to be inserted in the Atari computer at runtime. However I wanted to also create a stand-alone binary that does not need the Action! cartridge at runtime. This involves adding a special runtime library file (SYS.LIB) to the list at the top of my code. However, I was getting an error code related to too many global variables when trying to compile everything with SYS.LIB.

This is a known problem and is discussed in the Action! Run-Time Library manual (pp 11). Here’s the important part:

global_variables

Alas, this will have to wait for another day if ever.

Up Next

A video to show everything working and farewell to this Retrochallenge.

Retrochallenge, Retrochallenge 2016/10

Retrochallenge 2016/10 – Post 5

This is part five of my Retrochallenge 2016/10 journal, where I’m working towards loading ROM images to an Intellivision from an Atari 800. To jump to the very beginning, click here.

Tranferring ROMs from the Atari 800 to the Intellicart!

Here I’ll combine what I learned in Post 3 about transferring non-Intellivision data from the Atari 800 to my laptop and what I learned in Post 4 about creating and transferring Intellivision ROMs from my laptop to the Intellicart!. The result should be transferring Intellivision ROMs from the Atari 800 to the Intellicart!. Yippee!

850_intellivision_setup

Something Afoul in the Library

The Action! code I created in Post 3 reads characters from a small text file using the statement CH=GETD(INP). In that experiment, the GETD() procedure found in Action!’s default library returned zeroes once the program started reading past the end-of-file. That’s somewhat okay for reading text files but will not work when reading binary ROM files which will certainly contain many, many zeroes as valid data.

I looked through the Action! documentation and couldn’t find any procedures or functions that would provide a clue when the end-of-file is encountered. One kludgey solution would be to set up a loop counter break out of it after a per-determined number of iterations. Then I’d have to maintain a table of byte counts for each ROM file. Adding new ROM files would require updating the table. That’s no good.

IOFUN3

Looking through the list of Action! articles at atariwiki.org, I found a library file called iofun3.act. It contains file I/O functions akin to those found in Unix’s low-level system library. That is, the file read function includes a requested number of bytes to be retrieved and then returns the actual number of bytes retrieved. So if the function requests to read, say, 128 bytes, but receives something less than 128 bytes, then it can be assumed the end-of-file has been reached.

action_iofun3

Let’s get cracking.

Action! Code to Upload a ROM to the Intellicart!

INCLUDE "D3:IOFUN3.ACT"

;------------------------------------
PROC CONFIG_RS232(BYTE IOCB)    
  BYTE AUX1
  BYTE AUX2

  ; AUX1: 19200,8 Bit words,1 stop bit
  ; AUX2: No READY checks
  AUX1=15
  AUX2=0
  XIO(IOCB,0,36,AUX1,AUX2,"R1:")

  ; AUX1: No translation. No parity
  ; AUX2: Unused
  AUX1=32+0+0
  AUX2=0
  XIO(IOCB,0,38,AUX1,AUX2,"R1:")

  ; AUX1: DTR off,RTS off
  ; AUX2: Unused
  AUX1=128+32
  AUX2=0
  XIO(IOCB,0,34,AUX1,AUX2,"R1:")
RETURN

;------------------------------------
PROC MAIN()
  DEFINE BUFSIZ="256"
  BYTE CH, INP,OUT, GO
  BYTE ARRAY ROMFILE(30)
  BYTE ARRAY BUF(BUFSIZ)
  CARD COUNT  
  CARD TOTAL

  INP=2 ; IOCB #1
  OUT=5 ; IOCB #5
  TOTAL=0

  ; GET INPUT FILE
  PRINT("Enter ROM: ")
  INPUTS(ROMFILE)

  ; OPEN INPUT FILE
  CLOSE(INP)  
  IF FOPEN(INP,4,0,ROMFILE)>127
  THEN
    PRINTE("Error> ROM not found.")
  ELSE
    ; OPEN OUTPUT ON ATARI 850
    FOPEN(OUT,8,0,"R1:")
    CONFIG_RS232(OUT)
    DO
      ; XFER BLOCKS FROM INP TO OUT
      COUNT=FREAD(INP,BUF,BUFSIZ)
      IF COUNT>0
      THEN
        FWRITE(OUT,BUF,COUNT)
      FI
      TOTAL==+COUNT
      PRINT("So far...")
      PRINTCE(TOTAL)
    UNTIL COUNT<>BUFSIZ OD
  FI

  ; HOUSEKEEPING
  CLOSE(OUT)   
  CLOSE(INP)
RETURN

 A Trivial Test

  1. Created a custom Intellivision ROM image called RC201610.ROM using TESTROM.BIN found on the Intellicart! Download Software diskette as a basis.
  2. Transferred the ROM file to a physical floppy disk via a NUXX SDrive SD card/floppy drive emulator.
  3. Booted DOS XL and ran the compiled version of the Action! code found above.
  4. Entered “RC201610.ROM” at the program’s input prompt.

A Non Trivial Test

Here I transferred a ROM image for the 2011 homebrew game DK Arcade which was 49,221 bytes. There’d only be room for two ROMs that size on a typical Atari-formatted diskette. (If you’re wondering why the ROM files are so large, the Intellivision uses 10-bit words called decles. The ROM format spreads that information across two bytes).

Up Next

If nothing else gets accomplished, I’d be happy with having this command-line user interface. But my original plan was to have a “GUI” using @InverseATASCII’s Window Gadgets for Action!. I’ll have a little more than a week to get that working.

Retrochallenge, Retrochallenge 2016/10

Retrochallenge 2016/10 – Post 4

This is part four of my Retrochallenge 2016/10 journal, where I’m working towards loading ROM images to an Intellivision from an Atari 800. To jump to the very beginning, click here.

Transferring ROMs from Linux to the Intellicart!

Before trying to transfer ROMs from the Atari 800 to the Intellicart!, I thought it wiser to troubleshoot these details from a modern machine.

linux_intellicart_setupBinary ROM Images and The Intellicart!

ROMs for the library of classic Intellivision games are typically available as raw binary files containing solely the bits dumped from cartridge EPROMs. These raw data files are found on ROM archive websites with a “.bin” file extension. I’d like to transfer ROM images from the Atari 800 to the Intellicart!. However, the Intellicart! cartridge emulator expects more than just the raw binary data. It expects some transmission details and metadata before and after the raw binary data. This download protocol is explained in the Intellicart! manual pages 17-22.

intellicartmanual
Intellicart! Manual (Click on image to go to archive.org)

The Intellicart! Download Protocol

Here is a summary of the Intellicart! download protocol verbatim from the manual:

  1. Send Byte 0xA8, used for auto baud rate detection
  2. Send number of ROM segments
    This is the number of non-contiguous ROM segments that will follow. For example, a cart that occupied memory from 0x5000-0x6FFF and 0xD000-0xDFFF would send the number 0x02. (The actual binary value, not its ASCII equivalent.)
  3. Send the ones complement of the number of ROM segments.
  4. Send high byte of start address of first segment, 0x50 for above example.
  5. Send high byte of stop address of first segment, 0x6F for above example.
  6. Send the ROM segment itself.
  7. Send the high byte of the CRC-16 for the first ROM segment.
  8. Send the low byte of the CRC-16 for the first ROM segment.
  9. Repeat steps 4-8 for each additional ROM segment.
  10. Send the Enable Tables (see manual for details).
  11. Send high byte of CRC-16 for the tables.
  12. Send low byte of CRC-16 for the tables.
  13. Done

The Intellicart! Diskette

intellicart_diskette

At the beginning of this season’s Retrochallenge, my assumption was I’d have to write my own code to handle the details of the download protocol either at run-time on the Atari, or more likely, in a pre-calculated form on a modern machine.

So it was with great gratitude to the Intellicart! team that I found a C source file called BIN2ROM.C included on its installation diskette. The C source compiled without complaints on my Linux laptop. The program takes a .bin and corresponding .cfg file as input and outputs a .rom file that encapsulates the entire protocol. The only caveat is that for it to run successfully under Linux, the input files need to be lowercase. Many of the .BIN files included on the installation disk are old-fashioned MS-DOS upper case.

The diskette is available here.

Creating a Test ROM File

Included on the installation diskette for the Intellicart! is (among other .BIN files) a file called TESTROM.BIN. This is a minimal Intellivision program to test downloads. I’ll be using it for my tests.

1. Compile BINROM.C (included on Intellicart! diskette).

$ cc -o bin2rom BIN2ROM.C
$ ls -l bin2rom
-rwxr-xr-x 1 michael michael 15192 Oct 20 19:44 bin2rom

2. Create copies of TESTROM.BIN & TESTROM.CFG with lower-case names to appease the Linux version of the executable.

$ cp TESTROM.BIN testrom.bin
$ cp TESTROM.CFG testrom.cfg
$ ls -l testrom.*
-rw-r--r-- 1 michael michael 512 Oct 20 19:45 testrom.bin
-rw-r--r-- 1 michael michael  92 Oct 20 19:45 testrom.cfg

2. Convert testrom.bin to testrom.rom

$ ./bin2rom testrom
$ ls -l testrom.*
-rw-r--r-- 1 michael michael 512 Oct 20 19:45 testrom.bin
-rw-r--r-- 1 michael michael  92 Oct 20 19:45 testrom.cfg
-rw-r--r-- 1 michael michael 569 Oct 20 19:48 testrom.rom

Now I need to try uploading testrom.rom to the Intellicart!.

Minicom Is a Bad Friend

I’ve used minicom to get me this far in my Retrochallenge. I’ve used it to capture data being sent from the Intellicart software for Windows to the Intellicart! cartridge. However, I tried transferring testrom.rom from my Linux laptop to the Intellicart! cartridge using minicom’s “Paste File” functionality but I kept receiving a BAUD ERROR on the Intellicart! side.

minicom_paste
minicom “Paste File” didn’t work for me
image2
Baud News

STTY Is My New Friend

To the rescue comes the old Unix tool stty, which alters terminal line settings. I’ve used STTY to correct backspace keys and screen sizes in the past. But this functionality is new to me and now I’m grateful minicom was unsuccessful. Otherwise I may not have learned about it.

$ stty -F /dev/ttyUSB0 raw speed 9600
$ cat testrom.rom > /dev/ttyUSB0

The first command configures my laptop’s serial port to 9600 baud and the second command uploads the ROM file onto the serial connection.

Up Next

So now I know I’m able to generate a ROM data file that is acceptable to the Intellicart!. And I know what serial port configuration works. I just need to do the same on the Atari 800 and I should find success there, too.

Retrochallenge, Retrochallenge 2016/10

Retrochallenge 2016/10 – Post 3

This is part three of my Retrochallenge 2016/10 journal, where I’m working towards loading ROM images to an Intellivision from an Atari 800. To jump to the very beginning, click here.

850_setup

My First Serial Transmission From Atari & Action!

Before attempting to send data to the Intellicart! cartridge emulator on the Intellivision, I wanted to be sure I can send data correctly from the Atari 800 and its 850 interface module.

For this, I wrote a quick and dirty Action! script on the Atari 800 to open a small text file as input and configure/open a serial connection for output. The Atari 800 reads bytes from a text file stored on a floppy and sends the bytes to the serial connection provided by the Atari 850 interface module. On the other end of the serial connection is a serial to USB adapter and my laptop running minicom, which is listening to /dev/ttyUSB0 and capturing any input. The serial cable I am using is a normal null-modem serial cable, not a normal null-modem cable. Correction: I am using a null-modem cable.

Using my laptop to receive the data provides a way for me to observe what exactly is arriving via the RS232 connection. The Intellicart! will provide little diagnostic feedback.

Lessons Learned:

  1. When working with a serial connection, ensure the serial cable is connected.
  2. When working with minicom,  modify its configuration–>screen & keyboard setting to display hex. This avoids any confusion caused by characters being interpreted as control codes such as vertical tabs, backspaces, etc.

Configuring the Atari 850 Interface Module

For setting the baud rate, parity, stop bits, and the other RS232 settings on the Atari 850 interface module, the Action! language provides the XIO command which is similar to the XIO command found in Atari BASIC. The XIO command is a way to talk to devices via its driver software.

The general format of the XIO command in Action! is:

XIO(IOCB, 0, cmd, AUX1, AUX2, "Rn:")
  • where IOCB is be a number between 0-7 (maybe just 1-5 in this case)

The I/O Control Block number (IOCB#) specifies which channel a program is assigning to some interaction with a device. Normally, this can be a number between 0 and 7, however when using Action! channels 6 and 7 are already assigned to the editor (E:) and screen (S:) devices. Your program would allocate a channel to a device/file, perform some operation (read, write, get status, etc), then close the channel when finished.

  • and where the zero is required
  • and where cmd can be:
cmd Description
36 Set baud rate, word size, stop bits, and ready monitoring
38 Set translation mode and parity
34 Set outgoing lines DTR, RTS, and XMT
  • and where AUX1 and AUX2 are normally bit fields containing flags for different options.

For example, with XIO command 36, bits 0 through 3 define baud rate. The 850 technical manual contains tables with the available options (15 is supposed to be 19200).

850_baud_rates

Sample table from Atari 850 Technical Manual

  • and, finally, where “Rn:” specifies which of the four RS232C ports on the Atari 850 is being configured.

n can be a value between 1 and 4. “R:” is the same as “R1:”. One thing to keep in mind is that not all 4 serial ports on the 850 have exact same pin-outs. R1 is normal enough for our use.

Code

Here is the Action! code that runs on the Atari to send a small packet of bytes at 9600 8N1 to serial port 1 (R1:) on the Atari 850.

;------------------------------------
PROC HOME()
  PUT(125); Clear screen
RETURN
       
;------------------------------------
PROC INIT_R1(BYTE IOCB)    
  BYTE AUX1
  BYTE AUX2

  AUX1=14+0+0 ; 9600,8 bit word,1 stop bit
  AUX2=0  ; no ready checks
  XIO(IOCB,0,36,AUX1,AUX2,"R1:")

  AUX1=32+0+0;No translation nor parity
  AUX2=0
  XIO(IOCB,0,38,AUX1,AUX2,"R1:")

  AUX1=128+32 ;DTR off,RTS off
  AUX2=0
  XIO(IOCB,0,34,AUX1,AUX2,"R1:")
RETURN

;------------------------------------
PROC MAIN()
  BYTE CH
  BYTE INP,OUT
  HOME() 

  INP=1 ; IOCB #1
  OUT=5 ; IOCB #5
  OPEN(INP,"D2:TEST.TXT",4,0)
  OPEN(OUT,"R1:",8,0)          
  INIT_R1(OUT)

  CH=GETD(INP) ; READ CHAR FROM TXT FILE
  WHILE CH
  DO
    PUT(CH)      ;PRINT TO SCREEN
    PUTD(OUT,CH) ;WRITE TO R1:
    CH=GETD(INP)
  OD

  CLOSE(OUT)   
  CLOSE(INP)
RETURN

Some notes:

  1. INIT_R1 calls XIO to configure the RS232 port’s baud rate, etc.
  2. D2:TEST.TXT contains the text:
ABCDEFGH
01234567

Results

Here is minicom running on my laptop set to listen to /dev/ttyUSB0 at 9600 8N1. The minicom screen/keyboard setting has been configured to display data received in hex format. The bytes received match the bytes that were sent (“A” = 0x41, “B” = 0x42, …). 0x9B is Atari’s EOL character.

rs232_success_02

I’m thrilled!

Up Next

Learn a little more about the data transfer protocol expected by the Intellicart!

Retrochallenge, Retrochallenge 2016/10

Retrochallenge 2016/10 – Post 2

This is part two of my Retrochallenge 2016/10 journal, where I’m working towards loading ROM images to an Intellivision from an Atari 800. To jump to the very beginning, click here.

dos_xl_ver_2-42w

OSS DOS XL version 2.42w

After some searching, as far as I could tell, my copy of OSS DOS XL (version 2.42w) has not been archived / preserved yet on the Internet. It’s a variation the disk operating system, called Warp Speed DOS XL, to take advantage of HAPPY 810 & 1050 upgraded Atari floppy drives.

I’ve uploaded the information I have to AtariAge and archive.org.

happy_ad
A.N.A.L.O.G. magazine no. 47 pp. 7

https://archive.org/details/a8b_DOSXL_v2.42_1985_OSS

http://atariage.com/forums/topic/239044-happy-warp-speed-software-disk/?p=3611419

Retrochallenge, Retrochallenge 2016/10

Retrochallenge 2016/10 – Post 1

This is part one of my Retrochallenge 2016/10 journal, where I’m working towards loading ROM images to an Intellivision from an Atari 800. To jump to the very beginning, click here.

Getting Started

dosxl242w

Here we are 13 days into this Retrochallenge. Traveling out-of-state to visit family in the first weekend and doing minor home renovations on the second weekend has my project started flat-footed. And the usual “I need to work on my Retrochallenge” is losing its Force-like magic of persuasion. On top of that, everything I’ve done so far seems tangential to the real goal of transferring Intv binary files from an Atari 800 to an Intellicart! cartridge emulator connected to a Mattel Intellivision.

But here’s what I’ve been up to:

  1. Evaluating which DOS to use on the Atari 800
  2. Solve a DRIVE NUMBER ERROR message
  3. Deciding which emulator to use on my Linux laptop for initial development
  4. Creating the most convoluted cross-compiling development system possible
  5. Learning a little about the Action! programming language
  6. Pulling together the required code for the Action! Window Gadget library

I’ll cover those first two items in this journal entry.

Pick a DOS

There’s no shortage of Disk Operating Systems for the Atari home computers. Even though I used Atari DOS 2.5 and MyDOS4 throughout my Atari 8-bit days, after a lifetime of using Unix and MS-DOS, I find the old menu-based operating systems painful. I’d prefer a command-line DOS.

The serious Atari hackers use SpartaDOS X, but I don’t think it’s a good fit for this project. One variation of it requires a cartridge, but I’ll be using the cartridge port for the Action! language supercart. And with all its features, I’m doubtful it works as well on the 48K Atari 800 as it does on, say, a 128k Atari 130XE.

For a previous project, I used SpartaDOS’s more 48K-friendly distant cousin, BeweDOS v1.30. This is what I had planned on using at the beginning of the month. However, it uses a SpartaDOS-compatible disk structure that departs from the standard Atari DOS 2.0s format expected by some disk image tools I may use. In the end, I did find it can access Atari DOS 2.0s files via its menu interface, but not the command line. I admit I am enamored by seeing its time-stamps applied to files. While I don’t have a physical R-Time 8 clock cartridge, emulators emulate it.

But, really, since I’m using Action!, a programming system published by Optimized System Software, it seems fitting that I should use one of the disk operating systems released by the same small company of brilliant developers. Besides the original menu-driven Atari DOS which they created on Atari’s behalf, they later released their own command-line operating systems OS/A+ ver 2, OS/A+ ver 4, and DOS XL. My heart was set on using OS/A+ ver 4, for which I have a bona fide physical floppy and user manual. Unlike DOS XL, it hails more from the 48k Atari 800-era and represents a courageous attempt to start with a clean slate and push the Atari platform forward. For example, the authors envisioned being able to exchange data files between Atari and Apple II computers from the same floppy disk. But I’ve been unable to successfully modify its drive table to enable multiple disk drives. (It’s supposed to be updated by running “CONFIG” and then “@WRITESYS” but this hasn’t worked for me).

So, with a mild bit of reluctance, I’ve opted to go with OSS’s Warp DOS XL ver 2.42w, for which I also have a physical copy and manual. In fact, I don’t think this version exists in the normal software archival sites. My documentation’s title page states it’s version 2.30 which *is* archived. I think this “Warp” version takes advantage of Atari 1050 floppy drives with the “Happy” ROM enhancement. (Hm. I see the Atarimax store still sells “Happy” upgrades and my 1050 is now unhappy).

Fix a DOS

dosxl_drive_number_error
My first RTFM moment has arrived

The Atari home computer supports up to 8 floppy drives (D1 thru D8 – which would be an awesome sight to behold). So when using DOS XL, I was perplexed why I was receiving a “DRIVE NUMBER ERROR” when trying to access any devices after D2 (as shown in the image above). I was getting the same error when experimenting with OS/A+ version 2 and 4. My first RTFM moment had arrived.

Turns out DOS XL and OS/A+ ver 2 have a system variable called DRVBYT at address $070A that enables or disables D1 through D8. (OS/A+ ver 4 has a more complex data structure.) DRVBYT is a bitfield with the least significant bit representing D1 and on up through the most significant bit representing D8. If a bit is set, then the corresponding floppy drive is enabled. The default is $03 (D1 & D2 enabled) and is set when the file DOS.SYS is loaded into memory. To change the default requires modifying DRVBYT in RAM and dumping a region of RAM back to the file DOS.SYS. This task sounded a bit more onerous than it turned out to be. But it gave me a chance to do a little Action! and DOS XL work.

Tasks to set DRVBYT in DOS XL:

  1. Write a short Action! program to modify the memory location and run it.
  2. Un-protect DOS.SYS so we can overwrite it.
  3. Run the DOS XL “Init” tool and write a DOS.SYS file only
  4. Protect DOS.SYS

Action! Program to Modify DRVBYT

Action!’s variable declaration is counter-intuitive to what I’m used to. In Action! you define the variable name on the left side of the assignment operator (okay, I’m good with that). On the right side, you define it’s storage address, not its value (okay, that’s weird – but cool). The same task could’ve been accomplished using Action!’s immediate mode, but this is more fun.

Here’s the code.

action_drvbyt
Action! Code to Modify DRVBYT ($070A)

And the results. Nothing surprising.action_drvbyt_results

Update DOS.SYS

Remove the write protection from DOS.SYS and run the DOS XL INIT tool.dosxl_unprotect

Write out a new DOS.SYS file from memory.dosxl_init_menu

Re-Protect DOS.SYS

Don’t forget to re-apply protection to DOS.SYS. Write protection is signified by the leading asterisk in a directory listing.dosxl_protect_dossys

Fixed DOS

And now I can access D3 (and D4).dosxl_d3_working

D3 (and D4) now are enabled – yea!

Up Next

I need to capture the serial output of the Intellicart! data transfer.

Retrochallenge, Retrochallenge 2016/10

Retrochallenge 2016/10: Prologue

img_0176
Every ROM cartridge deserves an exclamation mark.

Goal: Atari 800 / Intellicart! Downloader

My Retrochallenge for 2016/10: use an Atari 800 to select & transfer Intv ROMs to an Intellivision via Chad Schell’s serial-based Intellicart! flash memory cart.

Background

Chad Schell’s Intellicart!, an Intellivision cartridge emulator, was released around 2000 and was the first multicart-like device for the Mattel Intellivision video game console. It connected the Intellivision to a Windows PC via a 9-pin serial connector. On the Intellivision, the Intellicart! initially boots to a communications program awaiting the arrival of data from the serial cable. On the PC, the user would select an Intellivision binary ROM file and upload it to the Intellicart!. Once there, the Intellivision rebooted to the just-delivered executable.

The Intellicart! made it possible for developers to test their homebrew programs on real hardware. For others it made it possible to play unreleased and rare games that had somehow found their way onto the Internet.

I acquired my Intellicart! (#171) sometime around 2001. It is my first retrocomputer device. Since then I moved onto the micro-SD based Cuttlecart and (soon) the just-released LTO Flash. I’ve also migrated away from Windows computers and found the original Windows-side Intellicart! application doesn’t behave well under WINE. So the Intellicart! has been dormant for about 10 years. Wakey wakey, eggs and bakey.

During the month, I want to learn how to program using OSS’s Action! programming system for the Atari home computers. This is a language I never owned or used in my Atari 800XL days. The closest I ever got to it was through the advertisements, reviews, and tutorials that appeared in Antic and A.N.A.L.O.G. magazines. I purchased a copy a year or two ago but so far it’s been sitting on the book shelf. Rise and shine.

Hardware

  • Mattel Intellivision Master Component
  • Chad Schell’s circa-2000 serial-based Intellicart! flash memory cartridge emulator
  • Atari 850 Interface Module
  • Atari 800 48k RAM
  • Rana 1000 double-density floppy disk drive
  • SDrive NUXX SD card Atari floppy drive emulator

 Software

  • The Action! System from Optimized System Software (OSS)
  • @InverseAtascii’s Window Gadget Library for Action!
  • Bewe DOS v1.30 for the Atari 800
  • Atari800 emulator for Linux
Retrochallenge, Retrochallenge 2016/01

Retrochallenge 2016/01: Final Post

(This is part six of the chronicle of my Retrochallenge 2016/01 submission, which is to port some classic Star Trek text games to the Mattel Aquarius. To jump to the beginning, go here.)

STTR2

For the final week of this year’s Retrochallenge, I worked on creating STTR2. This is an embellished port of STTR1 taking some advantage of the modest capabilities of the Mattel/Radofin Aquarius.

To get to this point, I took the code for my “straight” port of STTR1 and completely re-factored the BASIC code to make it more structured. Next was to change any code that PRINTED to use relocatable, colored text and use the Aquarius’ graphic text characters to make grids, etc.

Sadly the project is incomplete for the purposes of challenge. There is no sound. It exceeds my target 16K RAM, and is slower than an ASR-33 teletype terminal. (The video above is running in an emulator with max speed enabled). But it was very fun to get this far.

Retrochallenge 2016/01 Epilogue

Well, I fell a little short for my challenge. I did not port Super Star Trek like I had originally planned and therefore ported STTR1 to the Aquarius instead of Super Star Trek. In retrospect I’m fine with it. I find STTR1 to be simple and enjoyable. The Trek games that followed added perhaps needless complexity.

What I was successful with was learning a ton about a game that I initially knew very little about. I have heard revering stories of the game from programmers who got an earlier start in computers than I did. I was also successful in learning more about the Aquarius and the great efforts of its enthusiasts.

Thanks, Retrochallenge!