PART 1
6809 Assembly Language Programming on the TRS-80 Color Computer
(Using M.E.S.S. as the Vehicle)


By: Robert ([email protected])


Okay, since you have apparently decided to take this journey with me, I will try to make it as painless as possible (and hopefully, I won't be quite so annoying).

To begin with, I needed a project. Something simple to practice coding the 6809. I thought about it and decided that I would do something with the 32x16 text screen. After some thought, I decided I would like to have the screen cleared to black. Then, I would like to have a border around the screen, comprised of all eight solid color blocks that the CoCo is capable of generating. Just to make it interesting, I thought I would like to have this border rotating counter-clockwise. That should be enough of a project to get started, but I thought perhaps, I would add another border under the other, but have it rotating clock-wise, and finally, I would like to put a text window in the center of the screen, with scrolling text (something like 6 lines or so), and finally, have the routine continually checking the keyboard for a keypress at which point, the routine will return control to BASIC.



So, here we are, ready to create our little routine, which could possibly be used as an intro screen for BASIC programs. I would like to hear suggestions of other possible uses for the routine. This is, of course, assuming my efforts will be successful (they will <grin>). Okay, so to begin, I need the character codes for the block graphics characters that I intend to use to create the border. Not having the CoCo manual readily accessible, I fired up the emulator and entered in the following BASIC program:
10 FOR F=0 TO 255
20 PRINT CHR$(F);HEX$(F);" ";
30 NEXT F
Upon typing RUN and pressing [ENTER], the entire CoCo character set scrolled happily by, doing me absolutely no good. So, RUNning the program again and being quick enough to use the CoCo's [SHIFT][@] key sequence to pause program execution, I was able to acquire the needed information, as follows:
 
COLOR OF SOLID BLOCK CHARACTER HEXADECIMAL CODE FOR THAT CHARACTER
BLACK (ABSENCE OF COLOR) $80, $90, $A0, $B0, $C0, $D0, $E0, $F0
GREEN $8F
YELLOW $9F
BLUE $AF
RED $BF
BUFF $CF
CYAN $DF
MAGENTA $EF
ORANGE $FF

Mind you, had I not remembered the CoCo's color designations, I would have listed BUFF as WHITE, CYAN as LIGHT BLUE and MAGENTA as PURPLE. The fact that I did remember this might mean that there is hope of me remembering all that I used to know about 6809 Assembly Programming. You may note above that there are EIGHT hexadecimal codes that produce black. However, $80 is the official code for black. The other codes are for the other colors listed in the chart above, but represent absence of color, thus we get black.

Note that each solid block of color is exactly $20 (I will be speaking hexadecimal for the entirety of this - my appologies) higher than the color block that precedes it. This may make things easier down the line (instead of sticking the character data in a table, we can start at $8F, display that character, increment by $20, display the next character and so on). Of course, I might still use a table - I haven't got that far yet, so we'll see.

Also, creating and maintaining this document will be on an ''As I Have Time'' Basis, so if it goes days without an update, please don't FLAME me. I have to work on it when I am not at work, not sleeping, etc.



Now, let's have a look at how we intend to clear the 32x16 screen to black (this is an easy one):
Here is the Assembly Language Listing (In Disk EDTASM+ Lingo):

00100          ORG         $4000
00110 *PRESERVE REGISTERS
00120 START    PSHS        A,B,X,Y,U,CC
00130 *POINT TO START OF SCREEN
00140          LDX         #$0400
00150 *BLACK BLOCK = $80
00160          LDA         #$80
00170 *PUT BLOCK ON SCREEN & INCREMENT POINTER
00180 LOOP     STA         ,X+
00190 *CHECK FOR END OF SCREEN
00200          CMPX        #$0600
00210 *NOT END OF SCREEN, SO DO AGAIN
00220          BNE         LOOP
00230 *RESTORE REGISTERS AND RETURN (PULS PC PERFORMS LIKE RTS)
00240          PULS        CC,U,Y,X,B,A,PC
00250          END

Note that the above listing is not spaced exactly as it will appear on your CoCo's screen. You would enter it as:
00120 (the editor automatically displays the line number), followed by START, then [LEFT ARROW], PSHS, [LEFT ARROW], A,B,X,Y,U,CC followed by [ENTER], but hopefully you will already be familiar with EDTASM, or the Editor/Assembler that you happen to be using. Throughout this document, I will be referring to the commands and procedures of Disk EDTASM+, so you will have to be familiar with your Assembler in order to use this with something other than Disk EDTASM+.



Line 00100 tells the assembler the starting address in memory of this routine.


Line 00110 is a comment (think REM statement)


Line 00120 Preserves the contents of all of the CPU's registers upon entering this routine by pushing them onto the stack (as pointed to by the S register). Although this may not be necessary, it doesn't hurt either. If the routine used to call this routine needs the contents of the registers to be as they were prior to this routine, then this would be a necessary step. However, since this routine only modifies the X, A and CC registers, we could have just used: PSHS A,X,CC.


Line 00130 is a comment.


Line 00140 loads the value $0400 into the index register X (this is the IMMEDIATE addressing mode). $0400 is the normal starting address in memory of the 32x16 VDG text screen, the end of which is $05FF.


Line 00150 is a comment.


Line 00160 loads the value $80 into the Accumulator A (also IMMEDIATE ADDRESSING MODE). This is the character code for the solid black block.


Line 00170 is a comment.


Line 00180 places the contents of ACCA (Accumulator A) into the address contained in the Index Register X, and automatically increments the X register by 1.


Line 00190 is a comment.


Line 00200 compares the contents of the Index Register X with the number $0600. Recall that $05FF is the end of the screen, therefore if X has incremented to $0600, then we have finished filling the screen with black blocks ($80).


Line 00210 is a comment.


Line 00220 branches back to Line 00180 if we have not reached the end of the screen, otherwise, we fall through to the next instruction.


Line 00230 is a comment.


Line 00240 retrieves the register values from the stack that we pushed there at the beginning of this routine. Notice I have added the PC register to the PULS. This pulls the Program Counter from the stack and functions just like RTS, thereby saving the need of including the RTS instruction to return from this routine.


Line 00250 Tells the assembler that this is the end of the Assembly Language Listing.

In the future, I will try not to be so long winded - for example, you will no longer see Line xxxxx is a comment. Only the actually Instructions will be broken down for you. Okay, so enter the above program into Disk EDTASM+ and save it to disk via: WD SCREEN
Then, assemble it by entering AD SCREEN /AO
This will assemble the program to disk using the Absolute Origin Switch of Edtasm.
Exit Edtasm and return to BASIC.
Type: CLEAR 300,&H3FFF
      LOADM "SCREEN"
      EXEC &H4000

You should get a nice black screen, with the OK prompt of BASIC returning and ruining the effect, but at least you can see that it works.
This is all that I have time for this wonderful Easter Day, but I promise to continue soon and we'll work on creating the rotating borders. Hopefully this will be fun to you folks that are wanting to learn assembly. The already Assembly Guru's will no doubt be bored! Until Next Time..... Robert

 

UPDATE
(COURTESY OF ROBERT GAULT)


Subject:  Re: journal for 6809 assembly
 From: Robert Gault <e-mail address removed to foil spam-bots>
Date: Sun, Apr 08, 2007 4:10 pm
To: [email protected]

Hi Robert,

Here is some information that should help you. On the 32 character text screen there are 16 patterns and 8 colors. The formula is code =128+16(c-1)+pattern where c is color.

Basic automatically pushes all the registers when you execute an ml program so it is not necessary to start your program with  pshs    d,x,y,u,cc   and end it with
   puls   d,x,y,u,cc,pcr

You can easily make your program twice as fast as follows:

        org        $4000
start   ldx        #$400
        ldd        #$8080
loop    std        ,x++
        cmpx        #$600
        bne        loop
        rts
        end        start

The final    end   start   will cause EDTASM to place the correct start  address in the header for the file so that you just need to LOADM"SCREEN":EXEC 
without the &Haddress.


MORE FROM ROBERT GAULT:

Subject:   More on the clear screen routine <overkill :) >
From: Robert Gault <email address removed to foil spam-bots>
Date: Mon, Apr 09, 2007 5:30 am
To: Robert <[email protected]>
     
Robert,

Here are more examples (maybe overkill) to show how you can evaluate 
whether an "enhancement" is worth the trouble. The factors to consider 
are size and speed of code.

The code will work with either EDTASM+ or Roger's Rainbow-IDE. You will 
need another name for S_HOLDER with EDTASM+.
===============================================================

* This routine is the baseline algorithm.

* Clear low resolution text screen

         ORG        $4000
START    LDX        #$400
         LDA        #$80
         ORCC       #$50      turns off interrupts so counts are accurate
LOOP     STA        ,X+        6 cycles
         CMPX       #$600     4 cycles
         BNE        LOOP       3 cycles
         ANDCC      #$AF     turn on interrupts
         RTS
         END        START

* 13 Cycles per loop; 1 loop clears 1 byte; $200 bytes per screen
* Screen = 13 * $200 = 6656 cycles at 0.89 MHz = 0.0075 seconds

* This routine is an obvious improvement on the basic algorithm.

* Clear low resolution text screen

         ORG        $4000
START    LDX        #$400
         LDD        #$8080
         ORCC       #$50        turns off interrupts so counts are accurate
LOOP     STD        ,X++        8 cycles
         CMPX       #$600        4 cycles
         BNE        LOOP        3 cycles
         ANDCC      #$AF        turn on interrupts
         RTS
         END        START

* 15 Cycles per loop; 1 loop clears 2 bytes; $200 bytes per screen
* Screen = 15 * $200 / 2 = 3840 cycles at 0.89 MHz = 0.0043 seconds

* This routine takes the technique a few steps further.

         ORG        $4000
START    LDX        #$400
         LDD        #$8080
         ORCC       #$50        turns off interrupts so counts are accurate
LOOP     STD        ,X++        8 cycles
         STD        ,X++        8 cycles
         STD        ,X++        8 cycles
         STD        ,X++        8 cycles
         CMPX       #$600       4 cycles
         BNE        LOOP        3 cycles
         ANDCC      #$AF        turn on interrupts
         RTS
         END        START        
        
* Here we take advantage of $200 being an even multiple of 8 bytes.
* 39 Cycles per loop; 1 loop clears 8 bytes; $200 bytes per screen
* Screen = 39 * $200 / 8 = 2496 cycles at 0.89 MHz = 0.0028 seconds

* This routine changes the algorithm for a significant boost in speed.

         ORG        $4000
START    STS        S_HOLDER
         LDS        #$600        the 6809 pushes down
         LDD        #$8080
         LDX        #$8080
         LDY        #$8080
         LDU        #$8080
         ORCC       #$50        turns off interrupts so counts are accurate
LOOP     PSHS       D,X,Y,U        13 cycles
         CMPS       #$400        5 cycles
         BNE        LOOP        3 cycles
         LDS        S_HOLDER
         ANDCC      #$AF        turn on interrupts
         RTS
S_HOLDER RMB        2
         END        START        
        
* Here again we take advantage of $200 being an even multiple of 8 bytes.
* 21 Cycles per loop; 1 loop clears 8 bytes; $200 bytes per screen
* Screen = 21 * $200 / 8 = 1344 cycles at 0.89 MHz = 0.0015 seconds
 

* It is clear that the push routine is faster 1344 cycles vs 2496, 3840, 
or 6656
* but as even the slowest routine takes much less than a second, speed 
is a moot
* point for this purpose.
*
* However if the Coco3 high res graphic screen is being cleared which 
might be
* $1E000 bytes, then the times would be 0.36 seconds vs 1.8 seconds.



I appreciate Robert Gaults input. I was hoping other's would get involved, point out my mistakes and such. I have acually admired his work for some time. In 1993 or 1994, right before CoCoPRO! went out of business, I purchased a product called EDTASM6309 from them. This is without a doubt the BEST assembler that I ever owned. Sadly, it went missing with the rest of my original CoCo stuff years ago. However, Robert still sells this product from his website for $35, and it is worth it! The Rainbow IDE has similar functionality, I am told, but if you are working with a REAL CoCo 3 instead of emulating, then I highly recommend this product. Note that you do have to own a copy of Disk EDTASM+ in order to generate the functioning version of EDTASM6309. YOU CAN PURCHASE IT HERE.

STUDY ROBERT GAULTS EXAMPLES ABOVE - THERE IS A LOT TO BE LEARNED FROM THEM.



 

page1.html


 
 
 
 
 
 
 
 
 
 
 
 

Direct Buy Video - Direct Buy Video specializes in liquidating inventory from Retail Store Closings, Manufacturers Direct Sales, Overstocks, Discontinues, Buy Backs, Overruns etc... Here you will find DVDs from all categories at prices as low as $.57 per unit. All of their DVDs are Brand New, Factory Sealed, & Shrink wrapped. You will not receive any Used, Illegal Copies, Bootlegs, or Imports.

CLICK HERE TO VISIT DIRECT BUY VIDEO'S STOREFRONT PAGE

CLICK HERE TO VISIT DIRECT BUY VIDEO'S CATALOG SEARCH PAGE