Learning Assembly Language on the TRS-80/Tandy Color Computer - Makefile, Programs #6 & #7

 

 Introduction

Today I'll try Programs 6 and 7 from the Inman book, which draw an orange rectangle in different graphics modes.  6...7?  Sorry, I just had to put those two together. ; )

Assembly Language Graphics for the TRS-80 Color Computer - by Don Inman and Kurt Inman with Dymax

I'll also explore makefiles in macOS and how they can help to automate working with virtual disk files, assembling your code and opening MAME to test it.

Makefiles or Batch Files

I'm fairly new to macOS, but have worked in Linux enough to have used makefiles a bit, but I hadn't really understood what they did before Glen Hewlett suggested I start to use them to help automate some of the manual tasks involved with testing my assembly code on my iMac.

I had an assembly environment setup on my Windows PC a few years ago, following Paul Fiscarelli's advice from this video Long Branch Never YouTube Channel - Setting up Your Development Environment.  He uses batch files, which I'm extremely familiar with, having been a DOS and Windows poweruser and software developer since the early 1990s.

Glen suggested I use makefiles in macOS in a similar way to how Paul was using batch files in Windows.

I did some research to become more familiar with the structure and uses of makefiles.  This article provides a good introduction.  Glen also sent me an example of the makefile that he uses for his CoCo assembly work.  I took his example and modified it some to do a bit more of what I wanted.  I wanted to be able to use MAME in either debug or normal mode, depending on if I wanted to just run my program or step through it.  So, I created a makefile with two targets in it: run and test.  I then saved this makefile in the same folder where I'm working on my assembly language listings from the Inman book.

Here's what is inside my makefile:

# Name your program here (in uppercase, no extension)

FILENOEXT := TEST

SPEED := -nothrottle

run:

# Copy blank .DSK image to DISK1.dsk

    cp ./BLANK.DSK ./DISK1.DSK

# Use LWASM to assemble $(FILENOEXT).asm into a CoCo LOADMable program called $(FILENOEXT).bin

    lwasm -9bl -o$(FILENOEXT).bin $(FILENOEXT).asm > ./NEW_Assembly_Listing.txt

# copy binary to disk image

    decb copy -2 -b -r ./$(FILENOEXT).BIN ./DISK1.DSK,$(FILENOEXT).BIN

# Start mame

    mame coco3 -window -flop1 DISK1.DSK

test:

# Copy blank .DSK image to DISK1.dsk

    cp ./BLANK.DSK ./DISK1.DSK

# Use LWASM to assemble $(FILENOEXT).asm into a CoCo LOADMable program called $(FILENOEXT).bin

    lwasm -9bl -o$(FILENOEXT).bin $(FILENOEXT).asm > ./NEW_Assembly_Listing.txt

# copy binary to disk image

    decb copy -2 -b -r ./$(FILENOEXT).BIN ./DISK1.DSK,$(FILENOEXT).BIN

# Start mame

    mame coco3 -window -debug -flop1 DISK1.DSK

The two targets, run and test are very similar.  The only difference is I add the -debug parameter when calling mame in the test target to open mame in debug mode.  Since the run target is first, it is the default target and so when I just call make without specifying a target, mame is opened without the debugging features turned on.

VS Code has a built-in TERMINAL pane where you can type in your make commands.  This video shows the use of makefiles in VS Code.

Makefile VSCode Tutorial

I use my makefile in a very similar way shown in that video.  I save the assembly listing I'm currently working on in TEST.asm, as my makefile always looks for the source in that file.  After I'm happy with it, I'll save it to a new file: Save As to Program6.asm, for example.  But, I'll use TEST.asm during my development and testing phases so I don't need to create multiple makefiles or edit my makefile all the time.

I make sure the TERMINAL pane is shown below my assembly listing and then I can type any of these commands:

  • make
  • make run
  • make test
The first two commands do the same thing, since run is the default target.

I have a blank CoCo RSDOS virtual disk file sitting in my development folder: BLANK.DSK

Otherwise, the green comments in the makefile listing above should explain what each command does well enough.  Leave a comment down below if you have questions.

Once you have this setup, you'll see that using VS Code and a makefile is very convenient!

Batch files in Windows?

You should be able to do pretty much the same thing on a Window PC with VS Code's TERMINAL pane and a batch file instead of a makefile.

Let's get on with Program #6!

Program 6 - Drawing an Orange Rectangle (6C)

Program 6 draws an orange rectangle on a mode 6C graphics screen.  I didn't need to make any changes to the listing this time.

;********************************************
;* Assembly Language Graphics for the TRS-80 Color Computer *
;* by Don and Kurt Inman, 1983 *
;* Program 6 - Drawing an Orange Rectangle *
;* 6809 assembly language for Tandy CoCo *
;* David Kroeker, 07-Dec-2025 *
;* Draw an orange rectangle in mode 6C, *
;* Using colour set 1. *
;********************************************


ORG $1E00
; 1) SET GRAPHICS MODE to 6C, COLOUR SET 1
Start LDA #$E8 ; Select mode 6C (4 colour graphics mode), colour set 1
STA $FF22 ; Set graphics mode
STA $FFC3 ; Set V1
STA $FFC5 ; Set V2
; 2) CLEAR GRAPHICS SCREEN
CLRA ; Prepare to clear screen by clearing registers A & B
CLRB
LDX #$400 ; Start of screen memory in mode 6C
Loop1 STD ,X++ ; Clear screen memory
CMPX #$1C00 ; Have we cleared the entire screen?
BLO Loop1 ; If not, keep clearing
; 3) DRAW ORANGE RECTANGLE
; a) TOP ROW OF RECTANGLE
LDX #$1008 ; Starting address for rectangle (top left corner)
LDY #Table ; Load Y with address of rectangle colour data table
First LDA ,Y+ ; Load A with next byte of rectangle data
CMPA #$FF ; Check for end of rectangle top row (entire top row is FF - orange)
BNE Down ; If not orange, we are at the end of the top row, go to middle rows
STA ,X+ ; Next byte of screen memory
BRA First ; Repeat for next byte
; b) MIDDLE ROWS OF RECTANGLE
Down LDX #$1028 ; Colour byte for middle rows of rectangle
Next STA ,X+ ; Store colour byte in screen memory
LDA ,Y+ ; Load A with next byte of rectangle data
CMPA #$C0 ; Check for end of this rectangle row
BLO Next ; If not end of row, continue storing colour bytes
LEAX $1C,X ; Move to start of next row of rectangle
CMPX #$11E8 ; Have we done all middle rows of rectangle?
BNE Next ; If not, repeat for next row
; c) BOTTOM ROW OF RECTANGLE
Last STA ,X+ ; Store colour byte in screen memory
LDA ,Y+ ; Load A with next byte of rectangle data
CMPA #$FF ; Check for end of rectangle bottom row
BEQ Last ; If end of bottom row, we are done
; 4) Look for X keypress to end program
Xkey JSR $A1B1 ; ROM routine to read keystroke
CMPA #$58 ; Did user press X key?
BNE Xkey ; If not, keep checking for X key
; 5) Set back to text screen and clear
LDA #$60 ; Select text mode
LDX #$400 ; Start of screen memory
Loop2 STA ,X+ ; Clear screen memory
CMPX #$600 ; Have we cleared the entire screen?
BLO Loop2 ; If not, keep clearing
LDA #0 ; Set mode to text
STA $FF22
STA $FFC2
STA $FFC4
RTS ; Return from subroutine
; 6) Rectangle colour data table
Table FCB $FF,$FF,$FF,$FF
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $C0,$00,$00,$03
FCB $FF,$FF,$FF,$FF
FCB $00,$00,$00,$00 ; End of table marker
; END OF PROGRAM
END Start

Program 7 - Drawing an Orange Rectangle (1C)

Program 7 also draws an orange rectangle, but this time on a mode 1C graphics screen.  I didn't need to make any changes to this listing either.

;********************************************
;* Assembly Language Graphics for the TRS-80 Color Computer *
;* by Don and Kurt Inman, 1983 *
;* Program 7 - Drawing an Orange Rectangle *
;* 6809 assembly language for Tandy CoCo *
;* David Kroeker, 07-Dec-2025 *
;* Draw an orange rectangle in mode 1C, *
;* Using colour set 1. *
;********************************************


ORG $1E00
; SET GRAPHICS MODE to 1C, COLOUR SET 1
Start LDA #$88 ; Select mode 1C (low res 4 colour graphics mode), colour set 1
STA $FF22 ; Set graphics mode
STA $FFC1 ; Set V0
; CLEAR GRAPHICS SCREEN
CLRA ; Prepare to clear screen by clearing registers A & B
CLRB
LDX #$400 ; Start of screen memory in mode 6C
Loop1 STD ,X++ ; Clear screen memory
CMPX #$800 ; Have we cleared the entire screen?
BLO Loop1 ; If not, keep clearing
; DRAW ORANGE RECTANGLE
; TOP ROW OF RECTANGLE
LDX #$588 ; Starting address for rectangle (top left corner)
LDY #Table ; Load Y with address of rectangle colour data table
LDB #2 ; Counter to store 2 bytes per screen line
First LDA ,Y+ ; Load A with next byte of rectangle data
STA ,X+ ; Store colour byte in screen memory
DECB ; Decrement byte counterB
BNE First ; Repeat for next byte
;MIDDLE ROWS OF RECTANGLE
LDX #$598 ; Starting address for middle rows of rectangle
Down LDB #2 ; Counter to store 2 bytes per screen line
Next LDA ,Y+ ; Load A with next byte of rectangle data
STA ,X+ ; Store colour byte in screen memory
DECB ; Decrement byte counterB
BNE Next ; If not zero, repeat for next byte
LEAX $E,X ; Move X down to next row (2 bytes per row in mode 1C)
CMPX #$5D8 ; Have we drawn all middle rows of rectangle?
BNE Down ; If not, repeat for next row
; BOTTOM ROW OF RECTANGLE
LDB #2 ; Counter to store 2 bytes per screen line
Last LDA ,Y+ ; Load A with next byte of rectangle data
STA ,X+ ; Store colour byte in screen memory
DECB ; Decrement byte counterB
BNE Last ; If end of bottom row, we are done
; Look for X keypress to end program
Xkey JSR $A1B1 ; ROM routine to read keystroke
CMPA #$58 ; Did user press X key?
BNE Xkey ; If not, keep checking for X key
; Set back to text screen and clear
LDA #$60 ; Select text mode
LDX #$400 ; Start of screen memory
Loop2 STA ,X+ ; Clear screen memory
CMPX #$600 ; Have we cleared the entire screen?
BLO Loop2 ; If not, keep clearing
LDA #0 ; Set mode to text
STA $FF22
STA $FFC2
STA $FFC4
RTS ; Return from subroutine
; Rectangle colour data table
Table FCB $FF,$FF
FCB $C0,$03
FCB $C0,$03
FCB $C0,$03
FCB $C0,$03
FCB $FF,$FF
FCB $00,$00 ; End of table marker
; END OF PROGRAM
END Start

Enjoy!
David
17-Dec-2025

Comments