May 2nd, 2015

Merlin 16 assembler macros for System 6.0.1 updated

Eric “Sheppy” Shepherd has released an updated version of his Merlin macros for System 6.0/6.0.1 (fixing a broken Toolbox macro) and a new version of his Merlin GS/OS macros (there’s no functional improvement to the new version of the GS/OS macros; just updated contact information in the comments).

The macro files included with Merlin 16 predate the creation of System 6.0; way back when System 6 shipped, Shepherd decided to create these macros to make it easier for Apple IIgs programmers to use the new features of the operating system.

See Sheppy’s Web site for details and to download these.

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.

« Previous Entries | Next Page »