The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Saturday, November 11, 2000

Topiary Hell

Spring wrote more about topiaries, and sent the following links:

Potpourri Easter Egg Topiary
Valentine's Day Topiary Centerpiece
Sweet Treats Topiaries
Classic Duet

Oh the horror! The horror! Mommy! Make it stop!


Architectureal Heaven

I mentioned to Spring the other day about this Greek Orthodox church I drive by everyday to and from work.

I'm interested in architecture. And this church is one of the most beautiful (if not the most beautiful) churches in the area; I think it has a neoclassical design—you have your gold domes, the cross at the apex, a bell tower, but out front it has this stand of free-standing columns that give it a unique look. Simply gorgeous.

So when I discribed it to Spring she was very intrigued and wished she could see it. So I brought my digital camera to work so that on the way home in the morning, I could photograph it. [will add photos when I get a chance to]


Urban Decay

Also on the way home from work I pass what used to be Solar Testing Service Inc. Used to be because either it moved locations or went out of business. I remember there being hundreds of solar panels mounted about two feet off the ground in the field next to the building but now there is nothing left but an abandonded building and a field of posts.

Nothing like the beauty of urban decay.


Birthday Party

Today was Mark's birthday party and John, the paper millionaire of a dotcom, was hosting it for us. Unlike the last party John threw, there were no strippers.

It was just Mark's very close friends and family (his father). We sat around, eating freshly grilled burgers, warmed macaroni salad and cold baked beans (their maid is from another country and doesn't quite have our cuisine down pat), soda and beer. All of it good. And one delicious chocolate cake that was to die for.

Later on, we marveled at John's 800 gallon salt water aquarium, home to a few dozen fish, a dozen snails, live coral, some shrimp and two suicidal fish that kept wanting to be sucked into the filtration system. Mark and John spent some time keeping the fish from suicide runs (or who knows, meybe they get a rush from doing that) until they seemed to stop it.L

Afterwards, we ended up watching a forgettable film (Milk Money) and American Beauty on a digital HBO broadcast on John's 72" HDTV. Wow. HDTV, if you've never seen it, is simply incredible—it's like being in a movie theater.


Work Agony

What I didn't mention last week was that it was the Week From Hell. After getting home from work (remember, I work the midnight shift), I got a call from my friend Jeff Cuscutis (I know entirely too many Jeffs) called me up around noon to remind me we were getting together.

This only after two hours of sleep.

So I ended up spending the entire day over at his house and leaving in time to drive to work and spend eight hours there.

I must have been up for 28 of the previous 30 hours. It was horrible (and is one reason why there isn't an entry from last Sunday).

Anyway, this week was similar, except that I got twice as much sleep (four hours) and I spent it at someone else's house (John the paper millionaire of a dotcom).

Sigh.

On the plus side, like last week, I was able to (electronically) chat with a friend.

Sunday, November 11, 2001

Return to Post Apocalyptic Boca Raton

We finally returned to Post Apocalyptic Boca Raton or, as Spring calls it, Poca Boca. The day was beautiful, and we had the time. So like Douglas MacAuthor, we returned. Only it wasn't to the Philipines and it wasn't during a World War but I digress.

Poca Boca isn't all that big an area, being nestled just south of Spanish River Blvd and just east of FAU. We drove and parked the car along the abandoned road and strolled through the area for several hours.

The vegetation has gone wild and in one section (around 39th St. and an abandonded section of 5th Ave) the growth has almost overgrown the entire street. Along 39th are the foundations for the model homes that were built in the late 60s and we were amused to find a couch still there in what may have been the living room.

As we were walking around Spring and I talked about various locations that a person could potentially squat and remain unseen from homes and streets along the edge of Poca Boca.


Florida Swampland

After visiting Poca Boca Spring and I headed off to the ends of South Florida—Loxahatchee. The Loxahatchee National Wildlife Refuge on the western fringe of South Florida. We drove out there the day before but just after the sun had set and therefore we only stayed a few minutes before we were eaten alive by mosquitos.

Going in the day, we avoided all that and were able to stroll around the area a bit. Quite a few people were out, getting airboat tours (those things are loud) and fishing. We walked along the hiking path (that goes on and on and on and on) for a bit, then headed home where we both took a nap.

Thursday, November 11, 2004

Of course the bank is closed!

Whoa! Who made today a holiday? It's bad enough with banks and their bankers' hours …


I ain't got no password. You ain't got no password. They ain't got no password? Where the heck's the password?

Yesterday I was given the previous sysadmin's computer, running Windows XP Professional. Well, I'm given to understand that there are some support issues that require the use of Windows (cough frontpage cough) and it's not like this is new to me; so instead of using X-Windows to prop open a dozen xterms I use Windows to prop open a dozen putty.exes.

So when I sat down to use M's (the previous sysadmin) former computer she was already logged in. I did briefly think about changing her password just prior to leaving yesterday, but not knowing how to actually go about changing the password, I figured I could leave it until today. I'll just leave myself logged in and everything should be okay. Right?

Right?

You do see where this is going, right?

Today, I sat down in front of the computer, and right there was the Windows XP login window, asking me for M's password.

Sigh.

And none of the adminstrative passwords I've been given over the past few days worked. C couldn't even log in.

As I left the office tonight (the cubicle isn't nearly as depressive looking now that I've cleaned it up—now it has this Zen emptiness going for it) the XP installation CD was reformatting the harddrive (a different one—M's machine had important files on it and an XP reinstall is always destructive it seems—also, note to self: check to see if the cover is already off a computer before blindly removing screws out the back).

I've also learned the depths of my loathing of web-based adminstration. Of course you [the web-based administration program] couldn't create a sub-site—this computer doesn't have DNS on it you XXXXXXX piece of XXXX! Now create the sub-site! Aaaaaaaaarrrrrrgggggllll!

Fortunely, I didn't have to deal with the phone all that much today.


Reason #2.71828182845904523536 I hate PHP

So for my other job, I was requested to upgrade PHP from 4.3.8 to 4.3.9 because of a non-functioning script on one of the websites (in and of itself, never a good sign). So I pull it down, configure, make, make install and other stuff to get it into Apache, get an executable built, move it into place, start it up, and everything looks good so far … request http://www.example.net/server_info to make sure PHP is in there and … nothing.

Web server is running.

No page.

Any, and all requests are dying.

This is not good.

Check the log file and find:

[Sun Oct 10 02:09:49 2004] [notice] child pid 22113 exit signal Segmentation fault (11)

Put the old executable into place and start tracking down the problem.

Well, long story short, the “solution” to this “problem” involved deleting the existing PHP configuration (and associated files—the one installed for PHP 4.3.8) and installing the PHP configuration for PHP 4.3.9.

Okay, PHP 3x to PHP 4x, I could understand.

I might even forgive breakage from 4.x to 4.y.

But breakage from 4.3.8 to 4.3.9?

Truely, PHP is the scripting language du jour.

Saturday, November 11, 2006

“Office Space” Recut

Last year, Robert Ryang recut a trailer for “The Shining” to make it appear as a romantic comedy, which lead to a rash of recut trailers for various films placing them in different genres—Robert Ryang's work was the best of the lot.

Now comes this (and Mark should appreciate this)—“Office Space” Recut (link via Jason Kottke).

Wednesday, November 11, 2009

“You are in a fractal of twisty little chambers …

Years ago in college, generating fractals with fractint was a popular pastime among my group of friends. But it was mostly (if not entirely) two-dimentional fractals being generated.

But this three-dimentional Mandelbrot set?

Wow!

Wednesday, November 11, 2015

The Psychotherapy of Racter

One idea I have for this year's NaNoGenMo is Oz As She Is Spoke, an homage to English As She Is Spoke. The process is simple. Take the text from The Wonderful Wizard of Oz:

She was awakened by a shock, so sudden and severe that if Dorothy had not been lying on the soft bed she might have been hurt. As it was, the jar made her catch her breath and wonder what had happened; and Toto put his cold little nose into her face and whined dismally. Dorothy sat up and noticed that the house was not moving; nor was it dark, for the bright sunshine came in at the window, flooding the little room. She sprang from her bed and with Toto at her heels ran and opened the door.

The Wonderful Wizard of Oz, Chapter 2

and translate it to language A, then from A to B, and finally back to English:

Dorothy was he suddenly so bad, was awake by pushing The injury may have been lying on a soft bed, no. This was, This jar to catch his spirit, and he was made the surprise; And Toto put his cold little nose and his face and dismally whined. Dorothy sat up and noticed that the house is not growing; Nor was it Dark, bright sunlight entering through the window, the fill A small room. He sprang with his heel into his bed and ran to and Toto And has opened the door.

(I'll leave it to you, dear reader, to figure out the two intermediate langauges I used) Amusing, but I think I'll save that idea in case my current idea, a conversation between Racter and Eliza (the idea that Bunny would like to see) proves to be too difficult to pull off.

So, before tackling the difficult problem of “scripting Racter” I'd thought I'd try to get a version of Eliza up and running. I found this version, and with this commentary, it's pretty easy to see how Eliza works.

We can map the key sequences to possible responses:

local keyword_reply =
{
  ["can you"] =
  {
    "Don't you believe that i can*",
    "Perhaps you would like me to be able to*",
    "You want me to be able to*",
  },

  ["can i"] =
  {
    "Perhaps you don't want to*",
    "Do you want to be able to*",
  },

  ["you are"] =
  {
    "What makes you think i am*",
    "Does it please you believe i am *",
    "Perhaps you would like to be*", 
    "Do you sometimes wish you were*",
  },

  -- ...
}

And by using LPeg, we can easily build a parsing pattern that can match these key sequences:

local nonalpha = R(" @","[`","{~")

local keywords = P(false)
for kw in pairs(keyword_reply) do
  if kw ~= "" then
    keywords = keywords + P(kw)
  end
end

local parse = (P(1) - (keywords * nonalpha))^0 * C(keywords) * C(P(1)^0)

key,rest = parse:match "please, can i turn you off now?"

key will contain “can i” and rest will contain “turn you off now?” And given “can i”, we can pick one of the two possible responses. In this version, a response that ends with “*” just parrots the rest of the input, but at this point, Eliza would print: “Do you want to be able to turn you off now?” which isn't correct. We need to correct the pronouns. Again, some LPeg code to do just that:

conjugate = Cs((
                   P" are"  / " am "
                 + P" were" / " was "
                 + P" you"  / " me "
                 + P" your" / " my "
                 + P" I've" / " you've "
                 + P" I'm"  / " you're "
                 + P" me"   / " you "
                 + C(1)
                )^1)

rest = conjugate:match(rest)

and now we get: “Do you want to be able to turn me off now?” which is correct.

LPeg makes Eliza much easier to write and modify. Even if you can't understand the code itself, it's easy to see what needs to be added to do the conversion. Compare that with the original version I'm using as a reference:

380 REM ******************************************
390 REM **TAKE PART OF STRING AND CONJUGATE IT****
400 REM **USING THE LIST OF STRINGS TO BE SWAPPED*
410 REM ******************************************
430 C$=" "+RIGHT$(I$,LEN(I$)-LEN(F$)-L+1)+" "
440 FOR X=1 TO N2/2
460 FOR L=1 TO LEN(C$)
470 IF L+LEN(WORDIN$(X))>LEN(C$) THEN 510
480 IF MID$(C$,L,LEN(WORDIN$(X)))<>WORDIN$(X) THEN 510
490 C$=LEFT$(C$,L-1)+WORDOUT$(X)+RIGHT$(C$,LEN(C$)-L-LEN(WORDIN$(X))+1)
495 L = L+LEN(WORDOUT$(X))
500 GOTO 540
510 IF L+LEN(WORDOUT$(X))>LEN(C$)THEN 540
520 IF MID$(C$,L,LEN(WORDOUT$(X)))<>WORDOUT$(X) THEN 540
530 C$=LEFT$(C$,L-1)+WORDIN$(X)+RIGHT$(C$,LEN(C$)-L-LEN(WORDOUT$(X))+1)
535 L=L+LEN(WORDIN$(X))
540 NEXT L
550 NEXT X
555 IF MID$(C$,2,1)=" "THEN C$=RIGHT$(C$,LEN(C$)-1):REM ONLY 1 SPACE
556 FOR L=1 TO LEN(C$)
557 IF MID$(C$,L,1)="!" THEN C$=LEFT$(C$,L-1)+RIGHT$(C$,LEN(C$)-L):GOTO 557
558 NEXT L

Just a bit more work to get some corner cases worked out and then comes the hard part of getting Eliza to talk to Racter.

Thursday, November 11, 2021

Extreme spices, Brevard edition

Today was a cold, miserable, rainy day here in Brevard, so we didn't get out much. But a few days ago, we did stop by the local Food Lion, the other grocery chain in Brevard. Whereas Ingles is the more upscale type grocery store, Food Lion is your … um … less expensive grocery store. So my expectations were pretty low.

What I was not expecting was to find actual turmeric!

[A picture of fresh turmeric] A mutant carrot or a mutant worm … you decide.

I've never seen fresh turmeric! Much less expect to find it in a … um … less expensive grocery store!

Tuesday, November 11, 2025

Extending the syntax when calling assembly language subroutines for Color BASIC

A few days ago on the Color Computer mailing list, Allen Huffman asked:

The BASIC ROM has the USR function:

DEF USR0=&H3F00

A=USR0(42)

It accepts one parameter.

Since it jumps from BASIC into the USR assembly, couldn’t that code just parse a “,” and more numbers, allowing it to accept whatever needed to be passed in?

A=USR0(1,2,3,4)

[Coco] USRx() and adding more parameters?

Since we're talking about a 45 year old computer and with zero chance of a newer version of BASIC coming out any time sooner, the answer is “yes,” if you don't mind digging through the Unravelled Series (a series of books giving a disassembly of the Color Computer BASIC ROMs) and calling a bunch of nearly undocumented routines.

We'll start with the following code that implements a 16-bit version of PEEK, using some include files I wrote:

	include	"basic.i"
	.opt	basic defusr0 peekw
	org	$7F00

peekw	jsr	INTCVT	; convert parameter to integer
	tfr	x,d	; transfer into an index register
	ldd	,x	; read 16 bits from memory
	jmp	GIVABF	; return value to BASIC
	end

Now, a 16-bit version of PEEK is nice, but it would also be nice to have a 16-bit version of POKE. But USRn only takes one parameter; if we want an aditional value, we're going to have to extend the BASIC parser. Fortunately, due to the way Color BASIC works, this is easy and there are quite a few routines we can call. The first call is to a routine I'm calling CB.evalcomma (as in the Unravelled Series it goes by the name of LB26D). We need the comma, otherwise BASIC will return a syntax error without it. The next call we need is to a routine I'm calling CB.eval, which just evaluates an expression. And that's pretty much all that is needed to parse the additional syntax needed for this. The code looks like:

	include	"basic.i"
	include	"basic-internal.i"
	.opt	basic defusr1 pokew
	org	$7F00

pokew	jsr	INTCVT		; convert parameter to integer
	pshs	d		; save the address
	jsr	CB.evalcomma	; parse past comma
	jsr	CB.eval		; parse expression
	jsr	INTCVT		; convert expression to integer
	puls	x		; get address
	std	,x		; write data into address
	rts			; return to BASIC

And to use this:

DUMMY=USR1(&H76),1234

As it was pointed out, the code that handles USRn parses an expression in parentheses, so a modified USRn that parses would have to look something like A=USR0(1),2,3,4.

It's unfortunate that we can't just call USR1() without using the result, but that's a limitation of ColorBASIC which requires the results of USRn to be used. Other than that, we have successfully extended BASIC to modify how USRn works. This can also work with EXEC, the other way assembly code is called in BASIC (I'll leave that as an exercise for the reader).

But there are issues:

DUMMY=USR0(&H76),&HA000
?FC ERROR
OK

The issue—INTCVT checks if the value being converted is between -32,768 and 32,767 (a signed 16-bit value). The value of &HA000 is 40,960 (which still fits in 16-bits, but is unsigned) and thus, we get the ?FC ERROR from BASIC. This issue also affects the PEEKW function as we can't easily peek ROM addresses. If we wanted to peek the 16-bits at address 40,960, we would need to pass in the value of -24,576. That will work, but the value returned would be -24,117, which is $A1CB, the address that is stored at address 40,960 (or $A000 in hexadecimal).

It would be nice if we could correct these issues.

In looking through the Unravelled Series, I did find two routines that help. The first is CB.uintcvt. Like INTCVT this returns a 16-bit value in the D register, but doesn't signal an error if the value is outside -32,768 and 32,767. The other routine is CB.addrcvt, which returns the 16-bit value in the X register. We can thus rewrite our POKEW function as:

	include	"basic.i"
	include	"basic-internal.i"
	.opt	basic defusr1 pokew
	org	$7F00

pokew	jsr	CB.addrcvt	; convert parameter to an address
	pshs	x		; save the address
	jsr	CB.evalcomma	; parse past comma
	jsr	CB.eval		; parse expression
	jsr	CB.uintcvt	; convert expression to integer
	puls	x		; get address
	std	,x		; write data into address
	rts			; return to BASIC

And it all works as expected.

But that still leaves the PEEKW function returning negative values. Again, it would be nice if we could return an unsigned result to BASIC. I scanned the Unravelled Series but I could not find a routine to call. Perhaps I didn't look hard enough, but I did come up with a workaround. It's not pretty, but it works.

	include	"basic.i"
	.opt	basic defusr0 peekw
	org	$7F00

peekw	jsr	INTCVT	; convert parameter to integer
	tfr	x,d	; transfer into an index register
	ldd	,x	; read 16 bits from memory
	bmi	.neg
	jmp	GIVABF	; return value to BASIC
.neg	std	FP0	; return negative value as unsigned
	lda	#$90	; to BASIC
	sta	FP0EXP
	clr	FP0+2
	clr	FP0+3
	clr	FP0+4
	rts
	end

For positive values, I still use GIVABF. For negative values, I construct the floating point value “by hand” since all integer values from 32,768 to 65535 use the same floating point exponent. All I can say is “it works.” And given how seldom I've wanted to return an unsigned value, I can't say that it's a bad solution for this one case.

Then I got to thinking—could I combine the two routines into one? One function that can either peek or poke a 16-bit value? Where X=USR0(&H76) would read a 16-bit value, and X=USR0(&H76),&HA000 would write a 16-bit value while returning the original 16-bit value? I mean, why not make the return value for poking memory do something? But this means peeking ahead for a comma and deciding what to do.

Fortunately, there are enough examples of this in ColorBASIC that's it's relatively straight forward—the next character in the input can be found by the pointer stored at address CB.charad, and wouldn't you know it, the MC6809 can read through a pointer at an address to get it:

	ldb	[CB.charad] ; CB.charad contains an address
	cmpb	#','	; is it a comma?

So now we can combine the two routines:

		include	"dp.i"
		include	"basic.i"
		include	"basic-internal.i"

		.opt	basic defusr0 peekpokew
		org	$7FD0

peekpokew	jsr	CB.addrcvt	; return parameter in X
		ldd	,x		; read 16-bit at address
		pshs	x,d		; save address and data
		ldb	#','		; check for comma
		cmpb	[CB.charad]
		bne	.return		; if none, just a peek
		jsr	CB.evalcomma	; else parse the comma
		jsr	CB.eval		; evaluate the expression
		jsr	CB.uintcvt	; convert to 16-bit unsigned
		std	[2,s]		; store expr in address
.return		puls	x,d		; restore data (and stack)
		tsta			; test data < 0
		bmi	.neg		; if so, handle
		jmp	GIVABF		; return pos via BASIC
.neg		std	FP0		; return negative as unsigned
		lda	#$90
		sta	FP0EXP
		clr	FP0+2
		clr	FP0+3
		clr	FP0+4
		rts

		.pcle	$8000
		end

The PCLE directive stands for “PC register Less Than or Equal to” and is there to ensure our code doesn't run into ROM. If it does, it generates an error:

pw.asm:30: error: E0106: PC 8030 exceeds given limit 8000

and one can adjust the origin appropriately.

There are also some other functions I found, CB.evalopar which parses an open parenthesis, and CB.evalcpar which parses a close parenthesis. Then there's ECB.evalpoint which parses two expressions in parentheses: (x,y) and places the results in the variables ECB.horbeg (horizontal beginning) and the second into ECB.verbeg (verical beginning)—nice for parsing X,Y coordinates for graphics, and ECB.evalrect which parses a pair of points: (x1,y1)-(x2,y2) and places the second set of values into ECB.horend and ECB.verend. This can lead to some weird looking BASIC code:

X=USR3(4),(X1,Y1)-(X2,Y2)

but it works.

Obligatory Picture

[Self-portrait with my new glasses]

Obligatory Contact Info

Obligatory Feeds

Obligatory Links

Obligatory Miscellaneous

Obligatory AI Disclaimer

No AI was used in the making of this site, unless otherwise noted.

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: https://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

https://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2025 by Sean Conner. All Rights Reserved.