Author Archives: Allen Huffman

About Allen Huffman

Co-founder of Sub-Etha Software.

Interfacing assembly with BASIC via DEFUSR, part 3

See also: part 1, part 2, part 3, part 4, part 5, part 6, part 7 and part 8.

A quick update on some code listed in the previous installment. I mentioned that the user was passing in an integer that represented which character (a byte) the screen would be cleared to. It would be passed in as a 16-bit value (register D). Since the screen characters were one byte, a check was added in case the value passed in was larger than 255 (cmpd #255).

In the comments, Justin chimed in:

You could also just do a clra to force the issue and avoid the compare and branch. – Justin

Justin’s suggestion would make the code smaller and ignore the first byte of register D. Thus, if the user did pass in anything higher, it would just chop off the excess. In binary, if the user passed in a value from 0-255, only bits would be set in register B. When the value was larger than 255, it would start setting bits in register A:

     Reg A     |     Reg B
0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0 = Reg D is 0
0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 1 = Reg D is 1
0 0 0 0 0 0 0 0|1 1 1 1 1 1 1 1 = Reg D is 255
0 0 0 0 0 0 0 1|0 0 0 0 0 0 0 0 = Reg D is 256

If we just “clra”, we ensure the routine will never get a value greater than 8-bits. However, the user will get unexpected results. If they tried to pass in 256 (see above), register A would be cleared, and the value the routine would use would be 0. “Garbage in, garbage out!”

However, if error checking is desired, we still need to do a compare. L. Curtis Boyle suggested:

You could use TSTA. instead of CMPA #$00 to save a byte. – L. Curtis B.

I looked up the TST instruction, and it seems to test a byte in memory location or the A or B register and set some condition code register (CC) bits. If the high bit 7 is set, the CC register’s N bit will be set (testing for a negative value). If any bits are set, the CC register’z Z (zero) bit will be set (not zero). Hopefully I have that correct. The key point here is you can use TST to check for zero, and TSTA is a smaller instruction than CMPD. Here is the code:

* CLEARX.ASM v1.01
* by Allen C. Huffman of Sub-Etha Software
* www.subethasoftware.com / alsplace@pobox.com
*
* 1.01 use TSTA instead of CMPD per L. Curtis Boyle
*
* DEFUSRx() clear screen to character routine
*
* INPUT: ASCII character to clear screen to
* RETURNS: 0 is successful
* -1 if error
*
* EXAMPLE:
* CLEAR 200,&H3F00
* DEFUSR0=&H3F00
* A=USR0(42)
* PRINT A
*
ORGADDR EQU $3f00

GIVABF EQU  $B4F4  * 46324
INTCNV EQU  $B3ED  * 46061

       org  ORGADDR
start  jsr  INTCNV * get passed in value in D
       cmpd #255   * compare passed in value to 255
       bgt  error  * if greater, error
                   * D is made up of A and B, so if
                   * A has anything in it, it must be
                   * greater than 255.
       tsta        * test for zero
       bne  error  * branch if it is not zero
       ldx  #$400  * load X with start of screen
loop   stb  ,x+    * store B register at X and increment X
       cmpx #$600  * compare X to end of screen
       bne  loop   * if not there, keep looping
       bra  return * done
error  ldd  #-1    * load D with -1 for error code
return jmp  GIVABF * return to caller

* lwasm --decb -o clearx2.bin clearx2.asm
* decb copy -2 -r clearx2.bin ../Xroar/dsk/DRIVE0.DSK,CLEARX2.BIN

When I build this in to a .BIN file, the original showed 37 bytes, and this version shows 34 bytes. Here are the hex bytes that were generated:

clearx.hex:
:103F0000BDB3ED108300FF2E0C8E0400E7808C06FD
:0B3F10000026F92003CCFFFF7EB4F474

clearx2.hex:
:103F0000BDB3ED4D260C8E0400E7808C060026F92B
:083F10002003CCFFFF7EB4F496

It appears to save three bytes. Curtis mentioned saving one byte which I think is the case between a “CMPA #0” and “TSTA”.

Best of all, with this change, it still works and rejects larger values:

CLEARX2: Electric Boogaloo

Thanks, Justin and Curtis, for those suggestions.

By the way, I know programmers often don’t bother with error checking. I mean, our code is perfect, right? And, clearing a screen is hardly anything that requires error checking. And while I agree, I noticed that even COLOR BASIC has error checking for it’s CLS command:

CLS with a value greater than 255 returns a Function Call error.

And, since the CoCo’s VDG chip supported nine colors, you only get colors for CLS 0 through CLS 8. If you try to clear to any value between 9 and 255, you get an easter egg:

CLS 9 through 255 present a Microsoft easter egg.

Bonus Question: There is also an additional CLS easter egg in the CoCo 3’s BASIC, Do you know what it is?

But I digress…

String Theory

You can really speed up a BASIC program by using assembly routines. For instance, while BASIC has great string manipulation routines, doing something simple like converting a string to uppercase can be painfully slow.

Suppose you were trying to write a text-based program and you wanted it to work on all Color Computer models. The original Color Computer 1 and early Color Computer 2 models could not display true lowercase – they displayed inverse characters instead. Later Tandy-branded CoCo 2s and the CoCo 3 could support lowercase.

To work on all systems, you might simply choose to put all your menu text in UPPERCASE. Or, you might store every string twice with an uppercase and mixed case version, and use a variable to know which one to print:

IF UC=1 PRINT "ENTER YOUR NAME:" ELSE PRINT "Enter your name:"

That would be one brute-force way to do it, but if your program used many strings, it would needlessly increase the size of your program. Instead, it might make sense to store all the strings in mixed case, and convert them to uppercase on output if needed.

Here is a very simple brute-force subroutine that does just this:

BASIC uppsercase subroutine.

And it works just fine…

Output of BASIC uppercase subroutine.

…but it’s slow. If no conversion is needed, the mixed case text instantly appears, but when conversion is needed, it crawls through the line character-by-character at speeds we haven’t seen text display at since the days of dial-up BBSes.

In an earlier series of articles, we discussed word-wrap routines in BASIC. Several folks contributed their versions, and we ranked them based on code size, RAM size and speed. There were many different approaches to the same thing, and the same applies to uppercasing a string, so please don’t take my brute-force example as the best way it can be done. It certainly isn’t, and can surely be improved.

But even the fastest BASIC routine won’t compare to doing the same thing in assembly.

Unfortunately, the USRx() command only allows you to pass in a numeric value, and not a string, so we can’t simply do something like:

A$=USR0("Convert this to all uppercase.") 'THIS WILL NOT WORK!

Pity. But, I was able to find the solution, and it involves another BASIC command known as VARPTR. This command gets the address of a variable in memory. You may recall that Darren Atkinson (creator of the CoCoSDC interface) used VARPTR in his version of the word-wrap routine:

This is our solution to passing in a string to USRx(). We can pass in the address of the string, and then the assembly code can figure it out from there. Here is how it works:

A$="This is a string in memory"
X = VARPTR(A$)
PRINT "A$ IS LOCATED AT ";X

If you run that code, you will see the address of that string in memory. We just need to understand how a string is stored.

The address does not point to the actual string data. Instead, it points to a few bytes of information that describe the string and where it is.

The first byte where the string is stored will be the size of that string:

A$="THIS IS A STRING IN MEMORY"
X = VARPTR(A$)
PRINT "A$ IS LOCATED AT";X
PRINT "A$ IS";PEEK(X);"LONG"

I forget what the second byte is used for, but bytes three and four are the actual address of the string character data:

PRINT "STRING DATA IS AT";PEEK(X+2)*256+PEEK(X+3)

On my system, it looks like this:

VARPTR of a string.

Once you know the actual starting place for the string data, you can see what that is in memory. In my case, the string length was 26 bytes, and the data started at 32709. I could use a FOR/NEXT loop and display the contents of that memory:

VARPTR string data example.

You will notice that the string information (length of string, location of string characters) is nowhere near the actual string data is. This is because the string characters could actually be in your program code, rather than in string memory. For example:

10 A$="THIS STRING IS IN THE PROGRAM"

Somewhere in RAM will be a string identification block with the length of the string and an address that points inside the program space. This makes it sort of an “embedded string” that lives inside your program. However, if you manipulate this string, BASIC will then make a copy of it in other memory and make the pointer go there. Thus, if you have a 10 character string like this:

10 A$="1234567890"

…and inside your code you do something like this:

20 A$=A$+"!"

…at that point, BASIC will no longer be pointing A$ to inside your code. It will be copied (pluy the “!”) to a new memory location inside of string space:

10 A$="1234567890"
20 GOSUB 1000
30 A$=A$+1
40 GOSUB 1000
50 END
1000 X=VARPTR(A$)
1010 PRINT"VARP:";X
1020 PRINT"SIZE:";PEEK(X)
1030 PRINT"LOC :";PEEK(X+2)*256+PEEK(X+3)
1040 PRINT
1050 RETURN

Here you can see that the location of the string (initially inside the program code space) moves to higher string memory RAM:

VARPTR shows you where the string moves to.

You won’t see memory decrease when this happens, because print MEM is showing you available program space. Strings live in a special section at the end of program memory. You may have seen the CLEAR command uses to reserve space for strings like this:

CLEAR 200

I believe 200 is the default if you don’t specify. In this case, the string started out inside the program’s code space and was not using any of that 200 bytes, and then after altering the string, it was copied in to the 200 bytes of string space.

Thus, if you want to see the impact, try running with “CLEAR 0” so there is NO ROOM for strings!

5 CLEAR 0 ' NO STRING SPACE

Now when we run that program, we see that the initial string works, because it is stored inside the program space, but the moment we try to add one character to it, there is no string memory available to copy the string to and it fails with an ?OS ERROR (out of string space).

?OS ERROR showing strings move from code space to string space.

This is something to be aware of if you are ever writing large programs with many strings. Rather than do something like this:

10 A$="[DELTA BBS]"
20 B$="MAIN MENU"
30 C$=" >"
40 PR$=A$+B$+C$:PRINT PR$

…which would then allocate string space to hold the length of A$, B$ and C$, you could keep those strings in program code space by just printing them out each time:

40 PRINT A$;B$;C$

The trick is to avoid BASIC having to allocate string memory and copy things over. If you need to do this, you can re-use a temporary string:

40 TS$=A$+B$+C$:GOSUB 1000:TS$=""

I think something like that would create a temporary string (TS) and copy all those code space strings over, then you could use it, and then setting it back to “” at the end would release that memory. If string memory is limited, tricks like this can really help out.

But I digress.

Now that we know how strings are stored, we can create an assembly routine that will serve as a UPPERCASE PRINT command.

Our assembly routine will be passed the address of the string, and then use byte 1 to get the length, and bytes 3 and 4 to get the location of the actual string characters. We can then walk through that memory and use the CHROUT ROM routine to output each character one-by-one, the same way BASIC does for PRINT.

Here is the routine:

* UCASE.ASM v1.00
* by Allen C. Huffman of Sub-Etha Software
* www.subethasoftware.com / alsplace@pobox.com
*
* DEFUSRx() uppercase output function
*
* INPUT: VARPTR of a string
* RETURNS: # chars processed
*
* EXAMPLE:
* CLEAR 200,&H3F00
* DEFUSR0=&H3F00
* A$="Print this in uppercase."
* PRINT A$
* A=USR0(VARPTR(A$))
*
ORGADDR EQU $3f00
dir
GIVABF EQU   $B4F4    * 46324
INTCNV EQU   $B3ED    * 46061
CHROUT EQU   $A002

       org   ORGADDR
start  jsr   INTCNV   * get passed in value in D
       tfr   d,x      * move value (varptr) to X
foo    ldb   ,x       * load string len to B
       ldy   2,x      * load string addr to Y
       beq   null     * exit if strlen is 0
       ldx   #0       * clear X (count of chars conv)
loop   lda   ,y       * load char in A
       cmpa  #'a      * compare to lowercase A
       blt   nextch   * if less, no conv needed
       cmpa  #'z      * compare to lowercase Z
       bgt   nextch   * if greater, no conv needed
lcase  suba  #32      * subtract 32 to make uppercase
       leax  1,x      * inc count of chars converted
nextch jsr   [CHROUT] * call ROM output character routine
       leay  1,y      * increment Y pointer
cont   decb           * decrement counter
       beq   exit     * if 0, go to exit
       bra   loop     * go to loop
exit   tfr   x,d      * move chars conv count to D
       bra   return   * return D to caller
null   ldd   #-1      * load -2 as error
return jmp   GIVABF   * return to caller

* lwasm --decb -o ucase.bin ucase.asm
* decb copy -2 -r ucase.bin ../Xroar/dsk/DRIVE0.DSK,UCASE.BIN

W will call our assembly routine like this:

A$="Convert this to uppercase."
A=USR0(VARPTR(A$))

And it should work on upper and lowercase strings automatically:

Uppercase output routine in assembly.

Now our uppercasing output routine is lightning fast.

To be continued…

Interfacing assembly with BASIC via DEFUSR, part 2

See also: part 1, part 2, part 3, part 4, part 5, part 6, part 7 and part 8.

Previously, we took a look at using the EXTENDED COLOR BASIC DEFUSR command to interface a bit of assembly language with a BASIC program. The example I gave simply added one to a value passed in:

Using DEFUSR to call assembly from BASIC.

That’s not very useful, so let’s do something a bit more visual.

One of my favorite bits of CoCo 6809 assembly code is this:

      org  $3f00
start ldx  #$400 * load X with start of 32-column screen
loop  inc  ,x+   * increment whatever is at X, then increment X
      cmpx #$600 * compare X with end of screen
      bne  loop  * if not end, go back to loop
      bra  start * go back to start

This endless loop will start incrementing every byte on the screen over and over making a fun display. I ran this code in the Mocha emulator (which has EDTASM available):

http://www.haplessgenius.com/mocha

Then I compiled it (“A/IM/WE/AO” – assemble, in memory, wait for errors, absolute origin – how can I still remember this???), and ran it in the debugger (“Z” for debugger, then “G START” to start it):

Mocha emulator running silly screen code.

This inspired me to make a small assembly routine to do something similar from BASIC. The CLS command can take an optional value (0-8) to specify what color to clear the screen to. Let’s make an assembly routine that will allow specifying ANY character to clear the screen to:

ORGADDR EQU $3f00

GIVABF EQU  $B4F4  * 46324
INTCNV EQU  $B3ED  * 46061

       org  ORGADDR
start  jsr  INTCNV * get passed in value in D
       cmpd #255   * compare passed in value to 255
       bgt  error  * if greater, error
       ldx  #$400  * load X with start of screen
loop   stb  ,x+    * store B register at X and increment X
       cmpx #$600  * compare X to end of screen
       bne  loop   * if not there, keep looping
       bra  return * done
error  ldd  #-1    * load D with -1 for error code
return jmp  GIVABF * return to caller

First, I added a bit of error checking so if the user passed in anything greater than 255, it will return -1 as an error code. Otherwise, it returns back the value passed in (that the screen was cleared to.)

Side Note: Hmmm. Since I know register D is register A and B combined, all I really need to do is make sure A is 0. i.e, “D=00xx”. If anything is in A, it is greater than the one byte value in B. I suppose I could also have done “cmpa #0 / bne error”. Doing something like that might be smaller and/or faster than comparing a 16-bit register. Anyone want to provide me a better way?

Since the 16-bit register D is made up of the two 8-bit registers A and B, I can just use B as the value passed in (0-255).

Here is what it would do with a bad value:

Clear X routine, bad value error.

And here is it with a valid value of 42:

Clear X with a value of 42.

So far so good.

In the next part, we’ll look at how to pass in a string instead of an integer.

Interfacing assembly with BASIC via DEFUSR, part 1

See also: part 1, part 2, part 3, part 4, part 5, part 6, part 7 and part 8.

This article series will demonstrate how to interface some 6809 assembly code with Microsoft BASIC on a Tandy/Radio Shack TRS-80 Color Computer.

BASIC on the Color Computer is easy, but not fast. 6809 assembly language is fast, but not easy. Fortunately, it’s easy (and fast?) to combine them, allowing you to write a BASIC program that makes use of some assembly language to speed things up.

Assembly code can be loaded (or POKEd) in to memory at a specific address and then invoked by the EXEC command. This is fine for a “go do this” type of routine. But, if you want the assembly code to interact with BASIC by returning values or modifying a variable or string, you can use a special BASIC command designed for this purpose.

The Color Computer’s original 1980 COLOR BASIC had a USR command which could be used to call an assembly language routine via a BASIC interface. From the Wikipedia entry:

USR(num) calls a machine language subroutine whose address is stored in memory locations 275 and 276. num is passed to the routine, and a return value is assigned when the routine is done

This allowed passing a numeric parameter in to the assembly routine, and getting back a status value.

When EXTENDED COLOR BASIC came out, USR was enhanced to allow defining multiple routines. It looks like this:

DEFUSR0=&H3F00
A=USR0(42)

That code would define USR0 to call an assembly routine starting at memory location &H3F00 and pass it the value of 42. That routine could then return a value back to the caller which would end up in the variable A.

There are two ROM routines that enable receiving a value from BASIC, and returning one back:

  1. INTCNV will convert the integer passed in the USRx() call and store it in register D.
  2. GIVABF will take whatever is in register D and return it to the USR0() call.

Here is a very simple assembly routine that would receive a value, add one to it, and return it.

ORGADDR EQU $3f00

GIVABF EQU $B4F4   * 46324
INTCNV EQU $B3ED   * 46061

       org  ORGADDR
start  jsr  INTCNV * get passed in value in D
       tfr  d,x    * transfer D to X so we can manipulate it
       leax 1,x    * add 1 to X
       tfr  x,d    * transfer X back to D
return jmp  GIVABF * return to caller

Using the lwtools 6809 cross compiler, I can compile it in to a .BIN file that is loadable in DISK BASIC:

lwasm --decb -o addone.bin addone.asm

I could then use the toolshed decb command to copy the binary to a .DSK image to run in an amulator such as Xroar. In my case, I have an image called DRIVE0.DSK I want to copy it to:

decb copy -2 -r addone.bin ../Xroar/dsk/DRIVE0.DSK,ADDONE.BIN

Now I can run the Xroar emulator and mount this disk image and test it:

Using DEFUSR to call assembly from BASIC.

It works! Of course, I could have just done…

A=A+1

…so maybe this isn’t the best use of assembly language. ;-)

Up next … a look at doing something actually useful.

Easy websites with the w3.css style sheet, part 4

See also: Part 1Part 2 and Part 3.

This article will assume you know at least something about HTML, and a bit about CSS – even if it is just the basic stuff like the simple code shown in the example in part 3:

<html>
  <head>
    <title>My First Home Page</title>
  </head>
  <body>
    <p>Welcome to my home page!</p>     
    <p>Check out my other pages:</p>
    <ul>
      <li><a href="about.html">About Me</a></li>
      <li><a href="mydog.html">My Dog</a></li>
      <li><a href="poetry.html">My Poems</a></li>
    </ul>
  </body>
</html>

That makes this:

My First Home Page

But, with a bit of additional CSS styles, we can colorize and do other effects.

<html>
  <head>
     <title>My First Home Page</title>
   </head>
   <body>
     <p style="color: red">Welcome to my home page!</p> 
     <p style="color: green">Check out my other pages:</p>
     <ul style="background: black">
       <li><a href="about.html">About Me</a></li>
       <li><a href="mydog.html">My Dog</a></li>
       <li><a href="poetry.html">My Poems</a></li>
     </ul>
   </body>
</html>

That might look like this:

My First Home Page … in COLOR!

Here is an excellent tutorial on CSS:

http://www.w3schools.com/css/

I was visiting this site a few weeks ago looking up some CSS things and I ran across a style sheet they had created which let you easily create navigation bars, menus, and responsive (scales to phone or desktop screens) websites. It was called w3.css:

http://www.w3schools.com/w3css/

By linking in that style sheet, and tagging items in your web page, you can turn a boring, bland HTML page in to something more modern. By just including the “w3.css” style sheet in your page, and adding a “class” parameter to an unordered list, you suddenly have a modern navigation menubar:

<html>
  <head>
    <title>My First Home Page</title>
    <link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
  </head>
  <body>
    <ul class="w3-navbar w3-blue">
      <li><a href="about.html">About Me</a></li>
      <li><a href="mydog.html">My Dog</a></li>
      <li><a href="poetry.html">My Poems</a></li>
    </ul>
    <p>Welcome to my home page!</p> 
    <p>Check out my other pages by using the top menu.</p>
  </body>
</html>

Since I wanted the menu bar to be at the top, I moved that line to the top. It looks like this:

My First Home Page … using w3.css!

And by adding a few more “class” tags, you can create horizontal side menus and a bunch more. For example, you can easily create a page layout, such as a navigation bar, left box, and main content area:

<html>
  <head>
    <title>My First Home Page</title>
  <link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
  </head>
  <body>
    <ul class="w3-navbar w3-blue">
      <li><a href="about.html">About Me</a></li>
      <li><a href="mydog.html">My Dog</a></li>
      <li><a href="poetry.html">My Poems</a></li>
    </ul>
    <div class="w3-row">
      <div class="w3-third w3-container w3-green">
        <h2>Thought for the Day</h2> 
      </div>
      <div class="w3-twothird w3-container">
        <h2>Welcome to my home page!</h2> 
        <p>Check out my other pages by using the top menu.</p>
      </div>
    </div>
  </body>
</html>

…and suddenly you have this:

My First Home Page … now with CSS!

And, this design automatically becomes responsive, and resizes for phone screens:

My First Home Page … now responsive!

How cool is that?

I just had to share.

Explore the w3.css tutorial site for many examples. There are a ton of fun things you can do with very little work these days.

Have fun!

Easy websites with the w3.css style sheet, part 3

See also: Part 1 and Part 2.

Let’s set the wayback machine to 1995, when I first learned HTML.

The company where I worked had an internal web server. Many of the other engineers had their own small work-related web pages, so I wanted one too. I decided to learn HTML.

Consider this very, very simple HTML page:

<html>
    <head>
        <title>My First Home Page</title>
    </head>
    <body>
        <p>Welcome to my home page!</p>     
    </body>
</html>

This very simple page would present an empty screen with one short paragraph.

Perhaps we want to add a list of links to some other pages:

<html>
    <head>
        <title>My First Home Page</title>
    </head>
    <body>
        <p>Welcome to my home page!</p>     
        <p>Check out my other pages:</p>
        <ul>
            <li><a href="about.html">About Me</a></li>
            <li><a href="mydog.html">My Dog</a></li>
            <li><a href="poetry.html">My Poems</a></li>
        </ul>
    </body>
</html>

…and thus, the world wide web as we know it began, with endless, simple home pages.

HTML gave us many things, like bold text and italics, and even ways to make simple tables. As web browsers evolved, so did web pages, and soon designers were creating amazing sites by abusing the very simple HTML language.

And boy was it messy.

Netscape might show a web page differently than Internet Explorer, so designers had to use all kinds of tricks to try to make their sites viewable on different browsers and operating systems.

And boy was it messy.

Over the years, web developers came up with all kinds of hacks and tricks to make pages look “pretty” like they wanted, and look similar on different systems and browsers. They were using HTML in ways the language was never intended to be used.

Web browsers came and went, and the HTML standard evolved with browsers slowly becoming more standardized and able to render the same webpages similarly without (as many) hacks.

Somewhere along the line, cascading style sheets (CSS) started getting used, giving developers a proper way to instruct a browser on how to render HTML. The wikipedia page says CSS came out in 1996:

https://en.wikipedia.org/wiki/Cascading_Style_Sheets

…but it was many years before software supported it enough to make it widespread. I remember going through three or four expensive versions of the Dreamweaver web authoring program before finally getting one that sorta-kinda supported CSS.

I believe CSS finally came in to its own thanks to the introduction of the iPhone in 2007. This moved the world wide web from large desktop screens to tiny screens into our pockets. Since viewing full sized websites on a tiny screen wasn’t that fun, web standards continued to evolve with new approaches to make websites look less crappy on tiny screens while still looking nice on large computer screens.

And boy was it complicated…

Up next: How to make a modern looking website without having to learn (almost anything about) CSS.

Building KenTon/LR-Tech SCSI drivers for NitrOS-9

While the NitrOS-9 project does contain drivers for the KenTon and LR-Tech hard drive interfaces, they are not built or included by default. I wanted to document the steps I took to build and use the KenTon interface under the current NitrOS-9.

Basically, you will be modifying a few makefiles to enable the building of the low level booter, device drivers and device descriptors. If I recall, the changes are the same for each of these makefiles, but you only need to make them for the one you are using. If you are only using the KenTon drivers under NitrOS-9 Level 2 on a CoCo 3, just do that makefile.

  • nitros9/level1/coco1/modules/makefile
  • nitros9/level2/coco3/modules/makefile
  • nitros9/level3/coco3/modules/makefile

Step 1 – Add “KTLRFLAGS”.

These generate the define used inside the generic SCSI source code so it knows which code to build.

TC3FLAGS = $(AFLAGS) -DTC3=1 $(FLAGS)
KTLRFLAGS = $(AFLAGS) -DKTLR=1 $(FLAGS)
IDEFLAGS = $(AFLAGS) -DIDE=1 $(FLAGS)

Step 2 – Add “boot_ktlr” to the BOOTER list.

This makes it a dependency so make will look for it and try to build it. I added it in the middle of the list so when you get updates, it will be easier for the “diff” tool to see what has changed.

BOOTERS = boot_1773_6ms boot_1773_30ms \
 boot_burke boot_rampak boot_wd1002 boot_dw \
 boot_tc3 boot_ide boot_rom boot_dw_becker \
 boot_ktlr \
 boot_dw_arduino boot_dw_38400 boot_sdc

Step 3 – Add the modules to the RBF list.

RBF = rbf.mn \
 rbdw.dr dwio.sb dwio_38400.sb dwio_becker.sb dwio_arduino.sb \
 rb1773.dr rb1773_scii_ff74.dr rb1773_scii_ff58.dr \
 ddd0_35s.dd d0_35s.dd d1_35s.dd d2_35s.dd d3_35s.dd \
 ddd0_40d.dd d0_40d.dd d1_40d.dd d2_40d.dd \
 ddd0_80d.dd d0_80d.dd d1_80d.dd d2_80d.dd \
 ddx0.dd x0.dd x1.dd x2.dd x3.dd \
 rbsuper.dr lltc3.dr llide.dr llcocosdc.dr \
 llktlr.dr \
 dds0_ktlr.dd s0_ktlr.dd s1_ktlr.dd s2_ktlr.dd s3_ktlr.dd s4_ktlr.dd \
     s5_ktlr.dd s6_ktlr.dd sh_ktlr.dd \
 ddi0_ide.dd i0_ide.dd i1_ide.dd ih_ide.dd \
 dds0_tc3.dd s0_tc3.dd s1_tc3.dd s2_tc3.dd s3_tc3.dd s4_tc3.dd \
     s5_tc3.dd s6_tc3.dd sh_tc3.dd \
 ddsd0_cocosdc.dd sd0_cocosdc.dd sd1_cocosdc.dd

Step 4 – Add the dependency to build the driver:

# TC^3 SCSI Booter
boot_tc3: boot_scsi.asm
 $(AS) $(ASOUT)$@ $< $(TC3FLAGS)

# KenTon/LR-Tech SCSI Booter
boot_ktlr: boot_scsi.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS)
 
# SuperIDE/Glenside IDE Booter
boot_ide: boot_ide.asm
 $(AS) $(ASOUT)$@ $< $(IDEFLAGS)

Step 5 – Add the dependencies for building each descriptor. I put mine after the existing TC3 SCSI driver stuff:

sh_tc3.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(TC3FLAGS) $(HDBDOS)

# KenTon/LR-Tech SCSI Descriptors
dds0_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(ID0) -DDD=1

s0_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(ID0) $(SCSI_HD)

s1_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(ID1) $(SCSI_HD)

s2_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(ID2) $(SCSI_HD)

s3_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(ID3) $(SCSI_HD)

s4_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(ID4) $(SCSI_HD)

s5_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(ID5) $(SCSI_HD)

s6_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(ID6) $(SCSI_HD)

sh_ktlr.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(KTLRFLAGS) $(HDBDOS)

# IDE Descriptors
ddi0_ide.dd: superdesc.asm
 $(AS) $(ASOUT)$@ $< $(IDEFLAGS) $(MASTER) -DDD=1

Now those modules should be built and made available for including in your bootfile. You could do this by editing the bootlist you are using:

  • nitros9/level1/coco1/bootlists/standard.bl
  • nitros9/level2/coco3/bootlists/standard.bl
  • nitros9/level3/coco3/bootlists/standardL3.bl

Or you could use a bootfile editor like ezgen to add them to your current bootfile. Or, if you were just doing something temporary (like I was, to pull data from hard drives), you could just merge the needed modules together and dynamically load them when you need to use the SCSI drive.

Hopefully this will be helpful to someone else.

CoCoSDC SDC-DOS version 1.14 release

In case you missed it, in December 2016, a software update to CoCoSDC and SDC-DOS was released. You can find it under “Latest Firmware” on this page:

http://cocosdc.blogspot.com/

SDC-DOS is now up to version 1.14 and includes the following changes:

  1. AUTOEXEC. If “AUTOEXEC.BAS” if found on a mounted disk image, it will automatically run on startup. Holding down SPACE on startup will bypass this. (I think Kenton’s RGB-DOS did this?)
  2. EXP. A new “EXP” command has been added. It will mount an image called “SDCEXP.DSK” and, if present, run “AUTOEXEC.BAS” from that image.
  3. DEF DW. You can now specify DriveWire baud rates.
  4. WRITE/COPY MEM. These commands can now write to flash pages $FExx on a CoCo 3.
  5. RUN @bank. Code to select and execute one of the virtual ROM banks has been rewritten to make it more compatible with various ROMs.
  6. DSKINI. Fixes a bug where drive motor could remain on when using a CoCoSDC and a real floppy controller at the same time.

The update comes with a .DSK image that you mount and then run a utility which will take care of the upgrade.

Nice! I just started setting my CoCo system back up, and will be trying this out soon.

Easy websites with the w3.css style sheet, part 2

Previously, I began this article by discussing my first experience making a website back in 1995, along with mentioning a custom program I wrote to help speed up the process.

Over the years, the web has grown considerably, and the HTML “language” has evolved and added more features. (Does anyone remember the “blink” HTML tag?) It’s taken two decades, but we are finally getting to the point where web browsers are finally standardized enough that website designers don’t have to rely on all kinds of hacks and tricks just to make their sites appear similar on different systems.

In the early days, a browser called Netscape dominated. Microsoft introduced their first Internet Explorer (bringing the World Wide Web to PC users) and Apple had whatever the heck it had. Other operating systems, like IBM’s OS/2 Warp, had browsers of their own … and all rendered HTML a bit differently.

It was a mess.

Pages wouldn’t look the same when using Netscape on a PC versus  Mac. Internet Explorer was even made for Macs at one point, and initially it added features that the PC version didn’t have.

It was a mess.

I know I just said that, but I feel it is worth repeating.

It was a mess.

Today, it seems pretty rare to find folks editing HTML by hand. There are endless options for HTML editors (like Dreamweaver) that aid in building websites using templates and libraries of HTML code. There are also tons of content management systems like WordPress (which this site currently uses) that let folks easily set up a site based on a pre-existing theme and customize it a bit without ever touching a line of code.

And this is why so much of the internet looks bland, boring, and similar. Folks like me pick out some very common WordPress theme and look like thousands of other sites using the same theme.

Because writing a modern-looking website is hard.

However, last week I stumbled upon something that appears to let my ancient 1995 HTML skills quickly and easily create a modern-looking website with very simple HTML code.

In the next installment, I will introduce you to the w3.css. If you have ever built HTML by hand, and are unaware of w3.css, hopefully you will be as impressed as I am by what it is capable of.

Until then…

Easy websites with the w3.css style sheet, part 1

This article will discuss an amazingly easy way to create modern websites using a cool thing I just found out about.

But, like most of my articles, we begin with a long, rambling story about my history with the web…

I built my first HTML web page in 1995, I think. It was the early and crude days of the World Wide Web. I remember having my first public website (which we all called “home pages” back then) on a free service called GeoPages. This server was later renamed to GeoCities and was eventually acquired by Yahoo!

Here is the Wikipedia entry with some of the history. It’s quite interesting seeing where things began:

https://en.wikipedia.org/wiki/Yahoo!_GeoCities

According to a news article referenced by Wikipedia, the name change happened in December 1995. I wish I still had copies of my first home page, but space was limited back then so few of us kept earlier versions of the things we did.

At some point, I moved my home page from GeoCities to Delphi, and it stayed there for awhile before I finally archived it to my own domain. It looks like I last updated it in 2000, so here is an archive of my old site that begin in 1995:

http://alsplace.os9al.com/alsplace.html
My original home page, as it was in 1999-ish.

Those were the days! HTML 1.0!

In those days, HTML was edited by hand in a text editor. I used the umacs editor on a SunOS workstation, and later, umacs for MS-DOS on a Toshiba laptop. I wrote several programs in C to help me built more complex sites by using template files and includes. I basically created a C-style “#ifdef”, “#include” and “#define” preprocessor for HTML, and also added variables.

If I wanted a consistent header and/or footer at the top of every page, I could create a file like “TOP.TEM” (top template) with that code, and then in my page files (INDEX.TEM, ABOUT.TEM, LINKS.TEM) I would do a “#include TOP.TEM”. When I ran my preprocessor, it would parse the files and generate the actual .HTM files. (Ah, those lousy days in the PC world where file names were limited to eight letters and a three letter extension!)

For variables, I could create a “#define EMAIL alsplace@pobox.com” in a template, and then anywhere the text “%EMAIL%” appeared in the file would get replaced with “alsplace@pobox.com”. It let me make global changes to my site and rebuild in seconds.

Years later, I would purchase the expensive Macromedia Dreamweaver, which is today known as Adobe Dreamweaver. (Hmmm, why is everything I use acquired by someone else?) This industrial strength web editor finally allowed me to edit in a more visual mode rather than raw HTML coding.

But, even though it added the concept of Library items and Templates, it was (and still is!) so far slower when generating a site than my ancient 1995 preprocessor.

But it looks much nicer and is easier to use.

Up next: From home page to hosting…