April 7th, 2014

Sweet16 3.0.3 released

Eric “Sheppy” Shepherd has released Sweet16 3.0.3. The key changes in this release are a new About box—the first portion of Sweet16 to be rewritten as Cocoa code—and the following two key bug fixes:

  • Fixed a memory leak in full-screen mode that would fairly quickly eat up a lot of free memory the longer you stayed in full-screen mode.
  • The internal tools used to implement the ability to drag files in and out of the emulator were not built correctly to support Intel Core Duo processors. These are the earliest processors supported by Sweet16, and were not working with this feature. Now they are.

There are a few other changes as well, so be sure to review the release notes.

Sweet16 about box

Sheppy says he’s especially excited about the new About box, because it’s the first step on the road to gradually converting Sweet16 into a modern Cocoa application, which will make it easier to develop and maintain in the future. He hopes to tackle the Disks window next.

August 15th, 2013

Sweet16 3.0.1 Apple IIgs emulator for Mac OS X released

Eric Shepherd has announced the release of version 3.0.1 of Sweet16, the Apple IIgs emulator for Mac OS X. This release fixes a few bugs in the KansasFest-launched version 3.0, and adds one new feature to the debugger. Some highlights of the changes include:

  • Full-screen mode now works on Macs with Retina Display.
  • Arrow keys no longer “stick” when using certain software that accessed the keyboard at a low level; this includes Wolfenstein 3D, for example.
  • Clicking on a Sweet16 window to bring it to the foreground now also ensures that the clicked window is focused.
  • Apple IIgs alerts displayed at shut down time no longer have buttons that cause the emulator to quit.
  • The debugger now offers a “Break” button, which immediately halts the computer and starts single-stepping mode.
  • The Sweet16 application is now code-signed with Shepherd’s Apple Developer ID, for your computing protection.

Shepherd notes that it’s necessary to install updated versions of the “SweetDupe” and “SweetPrinter” extensions included with the software in order to make all of these fixes work. The user guide accessible through the application’s Help menu explains how to do this.

August 25th, 2011

Sheppy Releases “Trasher” Extension for Apple IIgs

Trasher is a new extension for the Apple IIgs that adds support for using Command-Delete on your keyboard to delete the selected icons in the Finder. In addition, if you have Sheppy’s SideClick contextual menu manager installed, you get “Move to Trash” and “Empty Trash” contextual menu items as appropriate based on what icon or icons you’ve right-clicked (or control-clicked) on.

This is Eric Shepherd (a.k.a. “Sheppy”‘s) first all-new Apple II project in several years. He notes, “The funny story behind Trasher is that I actually started working on this project back in 1994, but was unable at that time to figure out a way to make it work. I finally had the grand epiphany this summer during KansasFest and spend the last few weeks working out the kinks and making it work.”

May 17th, 2011

Syndicomm Changes Management, Maintains Catalog and Commitment to Apple II

Syndicomm, the distributor of the largest catalog of Apple II products in the world, has been operated by Eric Shepherd since the fall of 2000. Recently, growing family commitments and expanding full time employment responsibilities have sharply limited the amount of time he has available for developing new software. For that reason, he set out to find someone new to take over operating Syndicomm so that he can dedicate those resources toward other Apple II and Macintosh projects.

As a result, after months of discussion and planning, on Friday, April 29, 2011, Shepherd transferred ownership of Syndicomm to Tony Diaz. Currently outstanding orders are being processed as expected alongside the transition and should ship very soon.

Shepherd’s own products currently available through the Syndicomm store will will have their ownership shifted away from Syndicomm and will be available under the SheppyWare banner. These include OK-Writer, DiskMaker, and ImageMaker. Information on these titles, among others, is available on the SheppyWare site (http://www.sheppyware.net).

Tony Diaz will combine his years of Apple II involvement, product creation and manufacturing experience to the Syndicomm product line to carry the products and distribution forward.

Syndicomm carries a broad assortment of software and other products from companies including EGO Systems®, Parkhurst Micro Products, and The Byte Works. In addition, Syndicomm is the only licensed distributor of the entire line of APDA software, tools, and manuals from Apple®, Inc.

October 6th, 2010

Some Assembly Required: Let’s Do It Again

Last time, we looked at how to increment and decrement the values in registers. The code sample wasn’t very interesting, but learning how to use INC and DEC is a key step in learning how to build code that repeats tasks.

A loop is a code sequence that executes over and over again until some condition is met. A very common use case is to repeat some specific number of times. If you’re familiar with BASIC, this is equivalent to the notion of the FOR...NEXT loop.

Our Code This Time

In this installment, we’re going to create our first subroutine, which will use a loop to output a string of characters to the screen. This is actually very similar code to the string printing code in the example in the first Some Assembly Required article a few weeks ago. We’ll likely be using this exact routine a lot in the future — a simple “print a string” routine. Let’s have a look at the code.

[Download not found]
*
* print
*
* Prints the null-terminated string
* pointed to by the X and Y registers.
*
print    start
string   equ   $00                      ;String pointer address

         sty   string                   ;Save the string
         stx   string+1

         ldy   #$00                     ;Start at the beginning
loop     lda   (string),y               ;Get a character
         beq   done                     ;->If it's zero, done
         jsr   COUT                     ;Print it
         iny                            ;Next character
         jmp   loop                     ;And keep going
done     rts                            ;Return to caller
         end

Our print routine starts by using the EQU (EQUate) directive to give a name to the memory location at the address $00 in memory. This location is in the zero page, the very first page of memory. This page has special properties that make it particularly useful, since locations in the zero page can be referenced using a single byte (since the first 256 addresses in memory range from $00 to $FF). There are even special addressing modes just for working with the zero page, and instructions using these addressing modes are faster than when addressing other parts of memory. We’ll talk about that in more detail next time, though.

The first thing this routine does is take the value in the Y register and store it in the memory location pointed to by string, and then the X register into the next location in memory (string+1 equals $00+1 equals $01).

What we’ve done, then, is take the two-byte memory address pointed to by the bytes in the X and Y registers, and store them as a two-byte value in the memory locations at $00 and $01.

Numbers on the 6502

Let’s step back for a moment and look at how numbers are represented on the Apple II. A single byte can have the value $00 to $FF (that is, 0 to 255). To represent higher numbers, you need to use more bytes. By adding a second byte, you can represent values from $00 to $FFFF (0 to 65,535). For the foreseeable future, that will suffice for our needs.

It’s extremely important to keep in mind that the 6502 (like Intel’s processors, by the way) is a little-endian architecture. This means it uses low-byte first byte ordering. That means that if you need to represent a 16-bit (two byte) value, you put the lowest-order byte first, then the highest-order byte.

So, for example, the number $1234 would be represented in memory by $34 then $12.

This takes a little getting used to, but has key advantages on an 8-bit platform, since typically we need to manipulate the bytes in order from lowest to highest anyway when performing calculations. We’ll be looking at how to do math in the near(ish) future.

Back to Our Code

That said, now we can see that we’ve taken the address of the string we want to print and stored its low byte at the address $00 and its high byte at byte $01 in memory. This is the correct order for storing a 16-bit value (such as an address) on the 6502.

The next thing we do is initialize the Y register to have the numeric value 0, using the LDY (LoaD Y register) instruction. We’ll be using the Y register as a counter to keep track of how far into the string we’ve progressed while printing it out.

The next line is the first line of our printing loop. As I mentioned earlier, a loop is a set of instructions that runs over and over again until a condition is met. Let’s see how it works.

The first line of the loop starts with the text “loop”. Text that starts at the left-hand edge of the source code is called a label. Labels represent a location in memory. The actual value of the label is computed by the assembler when you assemble your program. This lets you refer to memory locations without having to know where they are.

The first thing the loop does is use a new addressing mode we haven’t looked at before. This is the indirect indexed addressing mode. When you see an address in parentheses in 6502 assembly language, we’re performing an indirect access to memory. That is, we take the address specified by the operand (in this case, the address referenced by string, which is $00), and then look at the address that’s stored in that memory. In this case, that’s the address that was specified by the X and Y registers when the print routine was run — which we previously stored in the two bytes at $00 and $01.

The indexed part of this addressing mode means we then take the retrieved address and add the value of the Y register to it to get the actual address to use for our operation.

For Example

Let’s say that when this routine was called, the value in string was $1234, meaning that the string we’re going to print is in memory starting at the address $1234.

That means we would store the number $34 in address $00 and $12 at $01.

Then, Y is set to zero.

The next thing we do is get the first character of the string to print. We look at the two bytes located at string and string+1 to determine the address of the string, so LDA knows to start looking at $1234. Then it adds the value of the Y register to that, getting $1234 for the address of the first character. It then loads the byte from that location into A.

Finishing the Loop

Once the character is in the accumulator, we need to see if we need to actually print it, or if the string is done being printed. We’re using null terminated strings; these are strings that end with a null character (that is, a character with the ASCII value 0). So we need to look to see if the character we just loaded is zero.

This is easy to do using the BEQ (Branch if EQual) instruction.

Whenever the value of a register changes, special status flags in the processor are changed. We’ll be looking at each of them over time as we proceed through this series of articles, but for now, let’s consider the zero flag. This flag’s value is 1 if the result of the last operation was zero, or if the result of a comparison operation indicated that two values were equal.

So BEQ branches (that is, starts executing code at a different location in memory) if the zero flag is 1. Which it is, if the LDA instruction loaded a zero into the accumulator.

So simply using BEQ to exit our loop if the end of the string was reached works nicely for us here; we simply branch if equal to the line of code with the label done. If the accumulator isn’t zero, the code continues to run on the next line.

The next line calls the ROM routine COUT, located at $FDED, which prints the character whose ASCII value is in the accumulator.

Now comes the fun part. We increment the value in the Y register so that the next time we run through our loop, we get the next character. This is done using the INY instruction; this implied mode instruction takes no operands at all. It simply adds one to the value of the Y register. We looked at this last time.

Finally, we use the JMP instruction to jump back to the start of the loop to continue printing the string.

Next Time

Next time, we’re going to learn more about the magic of the zero page, and the layout of the Apple II’s memory in general, which we only briefly touched on this time.

September 16th, 2010

Sweet16 Apple IIgs emulator for Mac OS X updated to version 2.2.1

Eric Shepherd has released Sweet16 2.2.1, a minor update that corrects an issue with how the disk controller is emulated, which lets certain disk activities work correctly; for example, you can now start up in ProDOS 8 then switch to GS/OS by running the GS/OS bootstrap “PRODOS” file.

September 3rd, 2010

Partial Draft of Toolbox Programming in GSoft BASIC Released

When GSoft BASIC was first released by The Byte Works, Mike Westerfield (of The Byte Works) contracted Eric Shepherd to adapt his book “Toolbox Programming in C” for GSoft BASIC. Work proceeded apace for a while, but stalled when issues were run into getting the code samples for chapter 7 (on printing) adapted. When it became clear that the problems would not be resolved easily, work on the book halted completely.

Permission has been received from The Byte Works to release the six chapters that were completed, along with the corresponding code samples, as freeware. They’re now available from the Syndicomm web site.

August 17th, 2010

Some Assembly Required: Incremental Progress

In this installment, we’re going to continue to learn more about the three primary registers in the 6502 processor (accumulator, X, and Y). We’ll also create our first simple subroutine.

You can [Download not found] for this program.

Comments

Before we do anything else, let’s take a moment to talk about comments. Comments are text in your source code that are human-readable, intended to help you remember what your code is doing (and so others can read your code more easily).

There are two formats for comments. Comments starting with a semicolon (“;”) can be placed stand-alone on a line of code, or can be at the end of any line of code. Comments starting with an asterisk (“*”) can only be placed on a line by themselves. In both cases, the comment extends from the character that starts the comment to the end of the line.

We’ve been using these already, but it just occurred to me that I haven’t actually talked about them yet, so there you go.

Our First Subroutine

Let’s start by creating our first subroutine. This simple routine just takes the value in the X register and prints it to the screen, followed by a carriage return. We’ve used the PRBYTE and CROUT firmware routines in the past, so we won’t dwell on them.

Let’s look at the code:

*
* xcr
*
* Prints the byte in X then a carriage return.
*
xcr      start
         txa                            ;Copy X to A
         jsr   PRBYTE                   ;Print the byte in A
         jsr   CROUT                    ;Print CR
         rts                            ;Return to caller
         end

The first thing this code does is use the implied mode instruction TXA (Transfer X register to Accumulator) to copy the value in the X register into (believe it or not) the accumulator. We do this because the PRBYTE firmware routine prints the value in the accumulator, but we want to use the X register in this case.

Then we call CROUT to output a carriage return, and use RTS to return to the caller.

Incrementing and Decrementing

A very common operation is the need to add or subtract one from a number. For this reason, the 6502 has special instructions just for that purpose. This time, we’re going to look specifically at incrementing and decrementing the index registers.

The INX (INcrement X register) and INY (INcrement Y register) instructions add one to the value of the respective registers. Similarly, DEX (DEcrement X register) and DEY (DEcrement Y register) subtract one from these registers.

Let’s take a look at a code sample:

* Demo increment and decrement

         ldx   #$00                     ;Start with zero
         jsr   xcr                      ;Print it
         inx                            ;Increment X
         jsr   xcr                      ;Print it
         dex                            ;Decrement X
         jsr   xcr                      ;Print it
         dex                            ;Oooh, now what?
         jsr   xcr                      ;Print that

We start by setting the X register to zero and calling our xcr routine to print that value to the screen.

Then we increment X and print the resulting value (in this case, $01).

Then we decrement X and print the result again (this time, $00).

Now, let’s see what happens when you decrement the X register again. The result is $FF (255). That’s right, they wrap around. if you then incremented X again, the result would wrap back to $00.

This is called carry, and it’s similar to what you do when you’re doing addition and subtraction by hand. You have to carry the result from one column to the next when adding or subtracting by hand; similarly, when doing math byte by byte, you have to carry the result from one byte to the next.

We’ll be looking in more detail as to how the carry bit works and how to perform multi-byte mathematics later.

Next Time

Next time, we’re going to apply this knowledge about incrementing and decrementing values to build our first loop to repeat an operation several times until the desired result is achieved.

July 18th, 2010

Sweet16 Apple IIgs emulator version 2.2 released

Sweet16 2.2 for Mac OS X has been released; this is the latest version of Eric Shepherd and F.E. Systems’ Apple IIgs emulator for Mac OS X.

One of the key changes is that by default, Sweet16 now limits the emulated IIgs speed to 40 MHz. Previously, the default was to go as fast as possible. This resulted in using 100% of at least one CPU core, which would cause battery drain and temperature issues, especially on laptops. Although users always had the option to turn on speed control and throttle the speed, this wasn’t obvious, so to help out new users, the default was changed.

If you’re already using Sweet16, your current setting won’t change when you update to version 2.2. If you’re a current user and are having this problem, you can enable speed control by opening the preferences, going to the CPU tab, and turning on the “Speed control” option. Then select a speed to throttle your emulated IIgs to.

Since modern Macs can typically blaze along at over 100 MHz emulated IIgs speed if unthrottled, even setting it to 40 MHz should improve the situation dramatically.

The full change list:

1. Sweet16 now defaults to having speed control enabled, with the GS set to a 40 MHz emulated speed. This prevents laptops from getting hot while running Sweet16. You can easily turn off speed control to let your GS fly, using the preferences’ CPU options panel.

2. You can now mount ProDOS-order (.po) disk images that are not floppy disk sizes.

3. When paused, Sweet16 no longer continues to use lots of your Mac’s processor capacity.

4. Creating 1.4 MB disks using the Create Disk Image feature now creates disk images that are actually 1.4 MB, rather than 1.6 MB.

July 1st, 2010

Some Assembly Required: Introducing the Registers

Unlike most modern processors, the 6502 series of processors has only three primary registers that you can use for manipulating data. A register is, basically, a slot within the processor that can contain a numeric value. On the 6502 and 65C02, these are each able to hold an 8-bit value. On the 65816, they can hold either 8-bit or 16-bit values, depending on whether or not the processor is switched to use 16-bit values for the register in question.

The accumulator — also known as the “A” register — is used for performing computations. Addition, subtraction, binary operations, and so forth are all performed on the accumulator.

The other two registers, X and Y, are called index registers. These registers are primarily used to index into a block of data while performing operations.

Addressing Modes: An Introduction

When you think about it, there are several ways to reference information. You can load or store a value directly into a specific memory address. You can set a register’s value to a specific number. You can use the address stored in a memory location as the address from which to load a value. These, among others, are called addressing modes. We’ll be introducing these gradually as we proceed through this series of articles.

Immediate Addressing

The first, and simplest, addressing mode is immediate mode. Immediate addressing is when you load a specific numeric value into a register. For example, here’s how you can set the value of the accumulator to zero:

            lda      #0

This is pretty straightforward. The LDA instruction (“LoaD Accumulator”) is used to load a value into the accumulator. When you want to represent an immediate numeric constant value in assembly language, you put a pound sign (“#”) in front of it.

Similarly, you can load immediate values into the X and Y registers like this:

            ldx      #$55
            ldy      #32

The LDX (“LoaD X register”) and LDY (“LoaD Y register”) instructions work exactly like LDA. Note, however, the presence of the dollar sign (“$”) in the LDX instruction above. That indicates that the value is hexadecimal.

Absolute Addressing

Absolute addressing is the mode by which you load and store values to a specific address in memory. For example:

            lda      #$ED
            sta      $0300

This code snippet loads the hexadecimal number $ED into the accumulator, then stores it in memory at the address $0300 using the STA instruction (“STore Accumulator”). You can similarly use STX (“STore X register”) and STY (“STore Y register”) to save the values of the X and Y registers into specific memory locations.

You’ll note that these instruction names get recycled. This is the first key lesson of assembly language programming. The 6502 has only about 50 different instructions, but most of them are available in multiple addressing modes. This lets each instruction take on a variety of uses; we’ll learn more about these over time.

Calling Subroutines

Before we get to our sample program for the week, let’s quickly look at how you call subroutines in assembly language. A subroutine is a (usually short) subprogram that handles specific tasks.

To call a subroutine, you use the JSR (Jump to SubRoutine) instruction. For now, we’ll only look at how to use its absolute addressing mode version.

Subroutines return to the calling code using the RTS (ReTurn from Subroutine) instruction. This instruction accepts no arguments. This is, for future reference, the implied addressing mode.

Let’s put together a little sample that uses what we’ve learned this week (note that this is using ORCA/M 8-bit syntax):

         keep  Registers                ;Name to compile to

PRBYTE   gequ  $FDDA                    ;Prints a hex byte
CROUT    gequ  $FD8E                    ;Prints a CR

         org   $2000

main     start
         lda   #$AB                     ;Set A to the number $AB
         jsr   PRBYTE                   ;Print A
         jsr   CROUT                    ;And a carriage return
         rts                            ;Exit program
         end

This is actually a simpler program than last week’s, but we’re going to look at it in more detail.

The KEEP directive on the first line is a bit of ORCA detail; it tells the assembler to save the assembled binary code in a file named “Registers”. This is not a 6502 operation, but a directive — or special instruction — for the assembler itself.

The next two lines use the GEQU (Global EQUate) directive define the constants PRBYTE and CROUT to point to two memory locations; these constants let us refer to these locations by name instead of number, which makes our code easier to read. These locations, in the Apple II ROM, represent a routine that prints the value of the accumulator as a hexadecimal number and a routine that simply prints out a carriage return character, respectively.

The ORG (ORiGin) directive tells the assembler the address in memory at which the program should load. In this case, we’re specifying $2000 (which happens to be the location in memory at which the high resolution graphics screen starts, but since our program doesn’t use that memory, it’s a nice place to run our code).

Next comes the body of our program. In ORCA, blocks of code are surrounded by the START and END directives. These allow us some capabilities we’ll explore later; for now, it suffices to know that you need to include them in ORCA but not in Merlin.

The main program uses the LDA instruction to set the accumulator’s value to the immediate value $AB, then calls the PRBYTE routine to print it to the screen. The CROUT routine is called next, to send a carriage return to the screen — this moves the printing cursor to the beginning of the next line.

Finally, our program ends with an RTS instruction. Simple 8-bit programs are called using a JSR instruction, so we return to the calling program (such as the ORCA shell or the BASIC interpreter) with an RTS.

Note for Merlin users: The GEQU directive in ORCA doesn’t work in Merlin; instead, you should use simply EQU. Likewise, you don’t need the KEEP, START, and END directives in Merlin. Instead, to specify the filename with which to save the assembled file, add “SAV REGISTERS” to the end of the source code file.

Save this code and assemble it, following the same instructions as last time. In ORCA, once you’ve saved the file, you can assemble and run it using the command “RUN REGISTERS.ASM” (assuming you saved the source code with the name “REGISTERS.ASM”).

Final Notes

You’ll notice we’ve skipped over any details on how the JSR and RTS instructions actually function together. This is a whole interesting set of information that we’re going to ignore for now, but we’ll get to it in a couple of installments.

Next time, we’ll expand on what we learned in this installment by doing some basic manipulation of the contents of registers.

« Previous Entries | Next Page »