then i looked at my bank account, and realized that i can’t afford to be spending any money on hobbies right now. so since i don’t have all of the chips i need to implement the serial port hardware on hand, i’m instead going to focus on the firmware and filling out whatever functions i can without needing to change the hardware any…
i’ve been on vacation and busy with some other things, so i didn’t have a chance to work on the 8-bit project for a couple of weeks. but the last two weekends i’ve been working on the XMIT command, and finally finished it up. as usual, there were a couple of stupid little bugs in the assembler that i didn’t catch. one was properly loading up the X register with the number of full pages to transmit, and the other was not having copied the data location information into the alternate location for use as a counter.
coding XMIT actually wasn’t all that difficult – i just started by copying the code for RECV and switching the sense from receiving to transmitting. i also needed to update my PC-side utility to allow it to receive as well as transmit data.
the form of the command is
where ‘a$’ and ‘l$’ represent the starting address and length of the data to be sent, respectively. both arguments are required, and the order must be as shown – because i’m taking a shortcut and ignoring the letters and assuming that the arguments are in this order. i also skip the $s and assume that the value is in hex – decimal simply isn’t allowed. i justify this because a) it works and b) i do intend, if i ever manage to complete this project and get it running on my own hardware design, to at that point go back and flesh out the firmware to provide a better user experience.
the format of the transmitted data is identical to that for the RECV command.
with XMIT and RECV now both working, i think the next step is to go back to the hardware side and integrate the serial hardware onto my breadboard, bypassing the SSC.
today marked the successful testing of the RECV (serial receive) command for the 8-bit project. the format of the command is
with the square brackets indicating that the address argument is optional.
this isn’t the first command that’s been tested, but it is the first since i’ve started this blog, so it gains the distinction of the first success that i report here. i do intend to go back and cover the already-tested commands as well though. also, there will be an overview post going over the entire command set as currently planned.
the serial data is received in the following format:
- the 2-byte address at which the data should be stored (if the address argument is included, the received address is replaced by the argument), LSB first.
- the 2-byte length of the data to be received, LSB first.
- the data itself, in 256-byte blocks. before each block, an ACK (0xAA) is sent to inform the sender that the software is ready to receive. after receipt of the last block (which may be less than 256 bytes) a final ACK is sent to inform the sender that receipt is complete.
the address argument must be exactly four hex characters long. so e.g. if you wanted to receive the data at decimal address 768, you would need to enter the address argument as A$0300; A$300 would be rejected as an error. while not perfectly ideal, i’m concentrating at this point on getting everything to just work. assuming i ever get to the point of completing this project to the point where it’s fully working on native hardware, then i may go back and add ‘niceties’ such as allowing a 3-character hex address to be interpreted properly.
to keep the user updated on the progress of the transfer, the command outputs several pieces of information:
- the command starts by outputting an ‘I’ to indicate it has initialized and is ready to begin receiving data
- after receipt of the address and length arguments, an ‘R’ is output
- after receipt of each 256-byte block (and the last less-than-256 byte block if needed), an additional ‘R’ is output
- after data receipt is complete, a status message is output on a new line: “File received at $xxxx:yyyy bytes”, where xxxx is the address the data was stored at and yyyy is the length of the data received. both are in hex, and both are exactly 4 hex characters long.
testing was performed both with and without the address argument, as well as with an invalid address argument to ensure the testing of that code.
the next command to be worked on is SHOW, for displaying the contents of memory. in fact, after completing testing of RECV this morning, i wrote the code for SHOW and am ready to upload and test that. i may do that tomorrow…
before i could start hooking up any custom hardware, i needed to have a way to get code from my laptop (where i am writing and assembling it) to the apple. the obvious answer was through the super serial card (SSC), since i already had a USB-to-serial adapter.
while setting up the physical connection was simple enough (i’ve gathered enough of a collection of cables and adapters over the years that it was simply a matter of locating the correct ones), the software side proved to be more difficult. part of this was because i was simultaneously creating the software for both ends of the connection.
to back up a step, i verified that the connection was working properly simply by using Terminal on the laptop and IN#3 (SSC card in slot 3) on the apple. i selected 300 baud because, for typing, that seemed plenty fast. that allowed me to type on the laptop and have it appear on the apple. i didn’t worry about communication in the other direction because i didn’t need it yet. however, that only allowed for text communication, while i needed to be able to transfer binary programs.
so i wrote a serial receive utility for the apple (in assembler). i also wrote a simple utility to convert the 65C02 binary output from the assembler into a text file containing a series of apple ‘input lines’ – i.e. as if i were typing the program in byte-by-byte from the Monitor prompt. so the sequence of operations was
- write/edit the code for my serial receive utility
- assemble the code using Anton Treuenfels’ Hobby Cross Assembler
- use my conversion utility to convert the binary into ‘input lines’
- set up the Terminal-to-IN#3 connection
- send the text file via Terminal
- type in the command to save the file to disk on the apple
i hit an immediate problem with this in that 300 baud was way too fast for the apple to keep up. luckily in Terminal it is possible to add a delay after each character sent and a different delay after a CR/LF is sent. i believe i ended up needing 30ms per character and 500ms after a CR/LF to ensure proper communication.
once i was able to get an initial version of my receive utility across, i expanded my conversion utility to be able to send the binary file directly. then followed a long series of trying a wide variety of things in both the apple and laptop utilities (including hooking up my logic analyzer at one point to confirm what control lines were/were not being used) before i was eventually able to find success. i then increased the speed from 300 to 9600 baud without difficulty, and have kept it there ever since. i think my apple code is tight enough to handle 19.2k (the highest the SSC supports), but 9600 is fast enough for the size of files i’m transferring, so i’m not going to bother trying.