Sunday, August 2, 2020

33209: Straits -- Proceeding Forth

Chapter 13.5 Straits -- Exercises, Exercises

Chapter 13.6: Straits -- Proceeding Forth


Tanya looked up from her keyboard circuit. "How long do you think it will take them to get us those Micro Chromas?"

Julia and Bob were helping her debug her work. The rest of those with working keyboards were spread out helping those whose keyboards were not yet working.

Julia looked over at me and said, "Do you think they'll have them on Friday?"

I blinked and she winced. She mouthed a silent "Woops, sorry."

I gave her a wry smile and a wink.

"Denny hasn't said," I replied.

For a minute, work proceeded, then Suzanne looked up from where she was working with another group. "Friday?" She looked over at Dr. Brown. "Friday? Something happening Friday?"

He raised his eyebrows and shook his head. "I heard Joe may be going to Austin to talk with some people at Motorola. Other than that, who knows?"

"That's cool," said Wallace.

"Be fun to go check out that surplus shop this weekend," Bob commented. "I don't suppose you're going to have time for that, Joe?"

"No, actually, that's part of the plan. Rolling out on my nephews' floor Friday evening and hitting the surplus store on Saturday." I deliberately left the grammar incomplete, too.

"Hey," Winston spoke up. "We could caravan down. I'm sure Julia wants to go, too. Leaving in the morning? We could all skip classes."

That got a ripple of laughter and chatter.

"Leaving as soon as my last class of the morning is done. Eating on the road so I can get to Motorola in time without speeding -- erm, too much."

"They're not flying you out?" Bob asked.

"Denny pointed out the strategic benefit of me being able to visit the surplus store, so they gave me the option to drive."

Chuck asked, "So what time should we meet to caravan?"

I looked at Julia and she tilted her head and shrugged. I looked at Doctor Brown and he just shrugged, too.

"Julia's going with you, right?" Suzanne didn't ask, didn't really accuse, just said it like she was confirming a known fact.

"Uhm, ..."

The whole class was suddenly quiet.

"Look. I'll be under a really tight schedule. If I had a CB radio in the car, we probably could caravan, but I don't, and I really won't have time to wait for anyone. I'm not saying you guys can't caravan, and I'm not saying we won't see anyone on the road, either, just that I don't want to speed a lot, and I won't be able to slow down or stop. Well, except for emergencies and short rest stops, of course."

I stopped for breath and thought and glanced at Mike, who was shaking his head, his expression hard with doubt and distrust. Pat and George were beside him, whispering together.

"Julia is planning on going with me so she can look at disk drives and such, unless she changes her mind. My brother said it was okay for her to sleep on the couch in their living room. As I said, I'll be in with my nephews. And," I glared at everyone and no one in particular, "my brother and his wife will kick me out on the street if I try to move to the living room in the middle of the night."

That got laughs.

"They don't have any extra room beyond that," I added, somewhat apologetically. "So anyone else who goes Friday will have to find their own place to spend the night."

"It might be a better approach to leave early Saturday and meet up in Austin," Doctor Brown suggested, quietly.

We discussed logistics for several minutes, and I promised I'd bring the address and phone number of the surplus shop on Thursday. Mark and Jeff said they'd bring it, too, in case I forgot.

Shortly, we returned to working on keyboards, and the talk turned to expanding the computers and figuring out what kind of enclosures to put the electronics in.

More than half the students had their keyboards working by the time I needed to go deliver my newspapers, and, at Doctor Brown's suggestion, we broke the lab session up so I would have time to do things I needed to do to get ready for Friday. The rest of the group agreed, although some seemed reluctant.

As Julia and I loaded her car with our computers, Mike, Pat, and George approached us. That Mike was unhappy was clear from his expression.

"Julia, I need to talk to you."

Julia looked at me and I raised my eyebrows and tilted my head.

"Mike, Joe needs to get back," she replied.

Mike fixed me with an angry stare. "I'd like to talk with Julia alone."

"If you're not going to say it in front of Joe, don't even bother."

Pat pursed her lips. "Julia, I don't think you're being fair to Mike. At best."

Julia shut the back seat door and turned to me. "Let's go." She handed me her keys. "I'd like you to drive."

I took the keys, gave her a hug, and whispered close to her ear in a low voice only she could hear, "We're still a little early, maybe we should listen to what he has to say."

She gave me a moue, then turned to Mike. "Two minutes. Here, now."

Mike looked at me hesitantly, then took a deep breath. "What are you doing?"

Julia gave him a look I was glad I was not on the receiving end of. "What makes you think you have a right to ask such a question?"

"It seems to me like Joe gets a free pass I never got."

"So what if he does? I have a right to make my own choices. And, I think you should know, he never asks me for what I'm not willing to give."

I could tell that hurt going down.

"Just for the record, Mike, can I ask how far you tried to go with Julia?"

That earned me burning looks from both Mike and Julia.

"I think it's a relevant question," I added

"He couldn't keep his hands out from under my clothes."

"You said you liked it."

"I changed my mind."

"Why?"

"I thought you wouldn't like me if I said no. Then I prayed and I realized that, if being turned down was going to turn you off, I shouldn't have been saying it was okey in the first place."

"If God told you to turn me down, why wouldn't he tell me I shouldn't date you? And why doesn't he tell you to turn Joe down?"

"Joe has never once tried to put his hands on me where they don't belong. He respects me."

"Then what is this going to Austin alone with him?"

I broke in. "My brother and his wife will literally kick me out in the street if I try anything."

"What if she tries for it?"

"I'll still be the one to go out in the street, since guys are better able to defend themselves. But if I couldn't trust Julia, and If I couldn't trust them, I wouldn't be letting Julia go with me."

"What about on the road?"

"We've promised each other not to even kiss on the road."

"I don't believe that."

Julia sneered. I'd never seen her do that before, and it disturbed me.

"You never did believe me, or in me, or in my ability to make up my own mind."

"Okay, I was a stupid high-school kid. I guess I wasn't mature enough. But ...," Mike trailed off.

"Yeah, high school kids think love is all about hormones and emotions." I regretted the words the moment they came out of my mouth, but they were not words I could recall without consequences.

I prayed again, in my heart, for forgiveness and guidance, not just for myself, but for all five of us.

"Uhm, maybe I should ask Denny if we can squeeze two more guys in on the boys' floor in sleeping bags, and an air mattress on the living room floor for Pat."

Mike gave me a shocked look, but it did not compare to the look of surprise and confusion Julia gave me.

"Hey. We're just here to ...," George began, but he, too, trailed off. "Uhm, maybe that would be a good idea, even though I'm not sure I want to get to know you that well, Joe." He chuckled.

I gave him a wry half-smile.

Pat was looking very thoughtful. "That olive green compact station wagon of yours is gonna be a tight squeeze, but maybe I can put up with being squeezed between two of my best friends for two six-hour trips over one weekend". She gave Julia a meaningful look. "Especially since it's for another of my best friends."

The doubts in Julia's face began to resolve themselves, and Julia nodded slowly. "Maybe it's a good idea. If Mike promises to accept what he sees."

Mike took some visible effort to pick his jaw back up off the metaphorical floor.

"I, uhm, I'll think about it."

"I'm still too upset to drive, Joe."

I held the door for Julia.

"See you guys tomorrow." I nodded to the three of them as I slid into the drivers side.

Julia scooted over on the bench seat and nestled against me. "Pat, we'll call you when we find out what Denny says."

*****

While I folded newspapers and stuffed them in my carrier bags, Julia drew up some more sketches for enclosures.

"If my keyboard is separate from the computer box, I'll need a longer cable."

"Yeah."

"And a ribbon cable isn't going to work."

"True. Too stiff, too many conductors spaced too far apart to bend well. Too easily broken."

"Is this why a keyboard controller might have a serial port instead of a parallel port?"

"Yup." I took one of the newspapers and set it in front of me, sideways. "Keyboard." I pointed to the bags. "Computer." I drew a line in the air from the bags to the newspaper in front of me, twirling my finger as I did. "Maybe a coiled telephone handset cord. Two or four wires inside instead of nine or more, and flexible." I stretched a rubber band from the bag to the newspaper, and it snapped. "Ouch."

We both laughed.

"Maybe that's what I should do. I think I want the disk drives in the same box as the mainboard."

"We can do it, if you think it's a good idea."

After I got back from delivering the newspapers, she showed me her new sketches. Then we went into the kitchen and put something together for dinner. After dinner, we went to the piano in the den, and Julia played so I could practice for my recital.

It was late enough, when we were done with practicing, for evening rates to apply, so I called Denny and asked about the Micro Chroma 68 boards, and about the possibility of putting Mike, George, and Pat up for a night, as well. Denny and Denise sounded a bit skeptical, but they decided it could be done. But only because they were friends of Julia's, and that would be the absolute limit.

And Denny said he knew they had gathered some Micro Chroma 68 kits, but he didn't know how many, or whether they'd be turning them over to me on Friday.

We called Pat, and George and Mike were there, too, we let them know we could do it.

"What now?"Julia asked as we sat down on the sofa in the living room.

"I need to study the 8086 and the 9900 a bit more. But I also need to figure out that Forth stuff."

"What you were looking at when we both fell asleep night before last?"

"That."

"I think that's what you should work on now."

"You might be inspired." I got out the package and looked through it again. I had ordered a printed copy of the fig-FORTH FOR 6800 ASSEMBLY SOURCE LISTING and a copy of the source on tape, with a copy of the fig-FORTH Installation Manual, Glossary, and Model, and a copy of an introductory textbook, Leo Brodie's Starting Forth.  

I picked the baby blue cover Installation Manual up again, thought about it for a moment, and put it down.

"What?"

"I dunno. I seem to be more inclined to look at the source code than at the instructions."

"Well, you seem to be inspired today ..."

I opened up the pink cover Source Listing and scanned through it. "Me?"

"You got the same answer to prayer I got. I wasn't going to follow through, but you did."

"Oh. With Mike. I think he'll be okay."

"Oh, Joe, I'm scared."

I looked up from the listing.

"What if God says I can't marry you, that I have to get back together with Mike?"

The lyrics to a hymn came to mind. I sang:
Know this, that every soul is free
To choose her husband and whom she'll marry.
"Boop-boop!" Giselle called out from her room. My singing had been loud enough for her to hear.

Julia looked at me doubtfully. "Is that really a song?"

"Almost."

"It's in the hymnbook." Giselle came in and headed through the kitchen to the den.

"How does it really go?"

I grinned and stood, and took her hand. She stood, too, and we followed Giselle.

Giselle opened the hymnbook to number 240 and handed it to Julia.

Julia took it and set it in the music tray of the old upright, and then sat down on the piano bench. She checked the key and ran through the intro, and we started singing:
Know this, that ev’ry soul is free
To choose his life and what he’ll be;
For this eternal truth is giv’n:
That God will force no man to heav’n.

He’ll call, persuade, direct aright,
And bless with wisdom, love, and light,
In nameless ways be good and kind,
But never force the human mind.

Freedom and reason make us men;
Take these away, what are we then?
Mere animals, and just as well
The beasts may think of heav’n or hell.

May we no more our pow’rs abuse,
But ways of truth and goodness choose;
Our God is pleased when we improve
His grace and seek his perfect love.
Julia stood up with eyes bright and moist, and we shared a three-way hug.

"Now I should leave you two alone." Giselle returned to her room.

"Anonymous, from around 1805," Julia read from the notes.

"About the year Joseph Smith was born."

"Included in your first hymnal. You guys have some really cool hymns."

"That's one I wish we sang more often."

She put the hymnal back and we shared a gentle kiss before returning to the living room.

Reluctantly, I released her hand and picked the listing back up, starting again with the first page.

"You might want to look at this license."

She gave me a look that said, maybe not.

"No, take a look." I showed her the first page of the listing."

* This listing is in the PUBLIC DOMAIN and
* may be freely copied or published with the
* restriction that a credit line is printed
* with the material, crediting the
* authors and the FORTH INTEREST GROUP.

"Public domain? But -- they claim copyright up here."

"Yeah."

"And, even though attribution shouldn't be all that big a problem, they do say it's required. I'm not sure that's actually public domain."

"You may be right. The Berne Convention tends to be interpreted to disallow alienation of copyright anyway, but they are clearly trying to retain some minimal claim."

(I was not particularly conversant in copyrights and the Berne Convention at the time, but I may have known enough about it to be able to say this much.)

"But it's probably legal enough that you can use it. Much more friendly than the other license, at least friendlier to poor students like us."

"I think so, too." We sat down, and I continued reading. "Wow. Right here, under the license, contact info, and attributions."

"What?" She looked over my shoulder again.

* ... All terminal 1/0
* is done in three subroutines:
*   PEMIT  ( word # 182 )
*   PKEY   (        183 )
*   PQTERM (        184 )

"Greek to me."

"Those routines will at least give me some clues."

I used the numbers for help searching through the code, and quickly found the routines.

"That's all?"

Looking over my shoulder again, Julia just laughed. "I'm sure none-the-wiser."

I did a little more searching, using the addresses of labels shown in the code listing, and shortly found the example code.

"Well, this is not exactly the place to customize the I/O routines."

"Oh?"

"More like replace. But I can use these to figure out what to replace the code with. Keyboard, display," I scanned a bit further. "Disk. No, that says virtual disk in RAM, so it'll take a bit more work. We aren't likely to be doing real disk just yet."

"What can you do without disks?"

"Not sure. Let's load the assembly language source in from tape, then save it to disk to work on."

That took a few minutes.

"Now I'll fix the I/O routines to match the Micro Chroma 68's hardware."

That took a bit longer.

"Save the resulting source and assemble it."

The assembler kicked out a few errors for me, so I fixed my mistakes and saved, and assembled it again. This time, it assembled cleanly.

Julia watched me patiently.

I saved the binary file to both disk and tape, and loaded and ran it. It came up nicely, first time.

FORTH-68                               
  OK                                            
                                                    

Julia went in to ask Giselle if she could borrow her TV, and Giselle came back out with her to watch as she loaded the binary from tape into her Micro Chroma 68+6801 and ran it. It came up nicely for her, too.


For a half hour or so, we played with the examples from Leo Brodie's book.

"No way to save our work?"

"Not without the disk I/O. Let's see if I can figure that out."

I let Giselle play on my computer while I went back to the manuals to try to understand enough about what Forth was all about to do something with the stub code for the disks.

The parameter stack, I understood. But the virtual machine was Greek to me for the evening. And the virtual disk was still quite opaque.

"No decimal point," Giselle muttered.

"I think Joe is going to have to program that himself."

"Probably so," I agreed, absently. "Also."

"Making your own words is fun." Giselle smiled. "Can we make this work with my word processor?"

I looked up from the program listing. "I think I'd have to rewrite the entire interpreter." I showed her the listing.

"That's like, a hundred pages? It'll take some time?"

"Seven thousand lines of code or so. It'd definitely take some time."

(fig Forth took the real me a full six months to get running, but that was because I did it the wrong way, hand assembling the source and entering the object in hexadecimal, also by hand, saving the object to the fast cassette. I learned a lot, but I also learned a lot of bad habits in the process. DIY-everything has limits.

No, the reason the me in this story progresses much more quickly is that he doesn't try to do everything himself. Even if you think that's what he's doing.

Forth, by the way, was a revelation to both the real me and the me in this story, but I'm not sure it wasn't a revelation of the dark arts.

The power you feel when you write your first BASIC program can be a little intoxicating.

The power you feel with Forth is more direct, stronger, more full of promise. But the details of implementation still bite you in the end, just like with any computer language, and they bite in ways that the majority of programmers and software engineers, unfamiliar with Forth, do not understand -- and never figure out how to deal with.

The me in this story was immune to the power effects, even though the real me was not. Giselle was not really immune, but lack of floating point math muted the effects. I think Julia wasn't immune either, but she instinctively hid behind the me of this story.

If you want to play with a more modern Forth interpreter than the one I used back then, look up Gforth. It has working disk I/O, floating point numbers, networking, and a number of other useful features. Or if you want a feel of what I was working with, the fig Forth interpreters can be found on-line, along with emulators to try them out on. The 6800 model fig Forth is in my sourceforge repositories. An emulator for the Micro Chroma 68 itself has even recently been added to the MAME/MESS project. I should write up a blog post of how to get those running, some day.

I do have a partially useful description up of how to get my BIF-6809 interpreter running on the XRoar Color Computer emulator, in my Open Source Developers Network Japan repositories.)

*****

In the lab the next day, we got the rest of the keyboards running, and those with Micro Chroma 68+6801s played with Forth a bit and let others give it a try. Several of us tried to work out the disk emulator stubs in the 6800 model, but the bug in the model and the narrow screen of the Micro Chroma 68 defeated us for the day.

More than BASIC and Flex, Forth got everyone excited to get their own mainboards running. Both the directness of the programming style and the accessibility of the source code for the fig FORTH interpreter gave it an immediacy that wasn't felt with BASIC.

The conversations again turned toward enclosures, and somebody pointed out that the surplus shop might have some, which raised the interest level in the trip to Austin.

Ultimately, two trips were planned, one leaving at the same time as Julia and me and another leaving at six Saturday morning. Several knew the Austin area, and they discussed campgrounds. Mark and Jeff said they'd lead the Saturday morning group.

For Institute that night, two sister missionaries stationed in Midland came to talk about how they prepared for their missions. Julia and Giselle both listened intently. I was also asked to give an impromptu testimony, and I spoke frankly about my experiences, as I felt inspired, including both my failures and successes.

Back at the house, raiding from the food storage shelves and the big freezer, as well as the fridge, Julia and I prepared food for the trip, with help and advice from Mom, Dad, and Giselle, and input over the phone from George, Pat, and Mike. Before heading for Julia's, we pre-packed our computers and got the old cooler box ready for the food. And I spent a half hour tuning the Colt's engine and giving the car a check-over.

We stopped at one of the grocery stores at 42nd and Dixie on the way back to her place, for a couple of two-liter bottles of soft drinks and a gallon jug of drinking water.

(I forget which store it was, or even whether it was the one on the north-east corner or the north-west. So much retail churn in Odessa -- the one on the north-west corner is gone now, and the one on the north-east is definitely part of a different chain now.) 

*****

"No, Mamá, it would not make more sense for me to spend the night tonight at Joe's house, not even in their spare room. We already have enough rumors going around at school as it is."

Mrs. Cisneros gave her own daughter a moue. "I suppose you're right. I don't know why Mike had to go and meddle in things."

"Mamá, paciencia. Todas las cosas buenas vendrán."

I reiterated what Julia said: "All good things will come, Mom."

Mrs. Cisneros turned to me with a shrewd, but pleased look and nodded. "Muy bien, hijo mio."

Julia looked at me with wide, surprised eyes. "Besas."

I complied.



[Backed up at https://joel-rees-economics.blogspot.com/2020/08/bk-33209-straits-proceeding-forth.html.]


Sunday, July 26, 2020

33209: Straits -- Exercises, Exercises

Chapter 13.4 Straits -- Keyboard Decoding

Chapter 13.5: Straits -- Exercises, Exercises


The doorbell rang as I was changing into gym shorts and a tee shirt for my morning exercises.

Giselle called out, "I think you should get it, Joe."

Puzzled, I pulled my tee on and carried my gym shoes into the living room.

Julia was waiting at the screen door in exercise gear when I rounded the hall doorway.

"Oh. So that's why you wanted to drive today." I gave her a cheesy grin and went to the door, lifting the screen door latch so she could come in. "You wanted to come early and see what I do for exercise."

"Well, more to join you than to watch." She loosened her shoelaces and left her shoes inside the door as she came in.

I set my shoes by hers. "I could have gone to your house early."

"And exercise with my parents watching? No way. Anyway, not the first time we exercise together. How do you usually start?"

"Warmups and stretches. The carpet in here is easy on the bones, but it's also easy to slip on. The floor in the den is hard, but you don't slide unless you're wearing socks."

"Barefoot it is, then."

We both left our socks with our shoes, saying good morning to my mom on our way through the kitchen to the den.

"You two focus on your exercises and I'll fix breakfast this morning."

Mom must have also been in on the plan.

We faced each other in the middle of the den. "And?" Julia looked at me expectantly.

"Uhm, I usually start with plié to warm up. Other than that, it's pretty random, and I'm open to suggestions."

"From ballet?"

"I learned a little from Louise and Giselle, but it's a hodge-podge mix. I wanted to take a class in modern dance this semester, but they told me I already had more than the usual limit of credit hours."

She laughed. "Like I say, you work too hard."

I had to chuckle.

I stood with my feet and arms in a rough approximation of first and second positions, respectively, and Julia mirrored me.

"One. Two." We did a couple of shallow knee bends. "Three, two, three, four." Once deeper, and back to standing, counting to slow it down. Four, two, three, four." Up to relevé and back. Plie, plié, grand plié, relevé. We repeated four more times.

Julia broke into jumping jacks. "One, two, three, four" I switched and mirrored her. "Two, two, three, four. Three, two, three, four. Four, two, three, four." She stopped. "That's base four, isn't it?"

I stopped and nodded.

"But it ends at four, not three." She wrinkled her forehead.

"Because it starts at one. Using different symbols doesn't really change the ring. It would be more recognizably the symbolic arithmetic base four if we started at zero, of course."

"But no one does that when exercising."

"Most people put math aside when they exercise."

She chuckled. "We've stalled. One-zero --" She started the jumping jacks again. "-- one-one, one-two, one-three."

"Trying to say all that breaks your concentration, doesn't it?" I joined in and we continued through three-three and on.

"One-one-zero, one, two, three. One-two-zero, one, two, three. One-three-zero, one, two three." She shook her head and stopped again. "Can't keep the rhythm going past three-three. Uhm, three-three's fifteen, so we're to 31, right?"

I stopped, too. "Right. And started at zero, so we've done thirty-two. Do it in hex?

"Zero, one, two, three, four, five, six, seven, eight, nine, aye, bee, cee, dee, ee, eff."

Somehow, we kept up the exercises and the counting in hexadecimal, in spite of the laughter, up to 100sixteen.

"Exercising with you gets my heart beating."

Julia rolled her eyes and slapped me gently over the head. "That was a lot of jumping jacks. Two fifty-six in base ten, right?"

"Yeah."

"What next?"

"Push-ups to relax?"

"Does not sound relaxing."

"Exercising different muscles."

Julia pursed her lips and got down into position for push-ups, and I followed, and we did seven together.

"My limit," she said.

"Mine, too."

"Don't be nice."

"Seriously. I can't even do more then seven at once from the knees." This was true. I didn't learn how to do push-ups until a modern dance teacher explained visualizing muscle use to the class once. "Sit-ups?"

We matched each other for twenty sit-ups, or 1Asixteen.

"Whew." She sat up. "We should take modern dance together."

I wonder if I'll have time for any summer classes, with the internships."
 
"We can take it together next fall."

"I thought you were moving on to Texas Christian. Up for a run?" 

"Maybe. Mom thinks I should postpone the associate's degree."

"You need to do what you need to do."

She gave me a perplexed look. "That's right. And I think I agree with my mom."

"Oh."

"Where do you usually run?"

"Lots of places. I learned how to pace myself and go for distance on my mission."

"Sounds scary."

"Sometimes I run past your house."

"And you don't stop in?"

"I think I will, next time."

"How long does it take?"

"About fifteen minutes, round trip."

"I think I can handle that. Better stretch first."

We both started doing stretches.

"I guess, if postponing your associate's is what you need to do, I'm not going to complain."

She turned and gave me an air kiss. I grinned and returned it.

"Can you study your Japanese at UTPB?"

"They don't have any courses to take, just like OC. I'd be the teacher."

"I've been thinking about finishing my bachelor's degree at UTPB."

"Me, too. I think I can do the Japanese by correspondence through BYU, if UT doesn't want to help me with it."

Our conversation lagged for a couple of minutes while we focused on the stretches. Then we stood, and she gave me a quick real kiss before we went in to the kitchen to tell my mom where we were going.

"Have fun. Be sure to get back in time to get cleaned up before classes."

We headed out, crossing 42nd at Dixie Boulevard, passing the shopping center on our right on our way to the park, heading east from there past her church, and stopping to surprise her mom at her house. From there we headed back south, crossing 42nd at the Lindale intersection where Lindale turns into 38th Street, then following 38th back home.

We stretched some more and cooled down in the den.

"I think you can borrow the shower on my parents' side of the house to wash off the swe-- uh, glow."

"South side bathroom's ready," my mom informed us from the kitchen.

I rolled my eyes. "Glad somebody here is good at planning."

Julia laughed and leaned over to give me another kiss. "Planning is something I'm good at."

"You're good at many things."

She gave me a smirk.

"Maybe we should agree before the trip to Austin, not to kiss during the trip."

Her smirk changed to a look of hurt, then a pout. Then she sighed. "You're probably right. Are you sure about your temples being hard to elope to?"

"Very hard. We both have to be members in good standing, and there's a year wait for new members."

"A what?"

"Temples are serious business. Promises to God. We want the members to be sure that they are willing to follow through on their promises."

"What are the promises?"

"Can't be specific, but basically to do our best to follow a godly walk and live a Christian life."

"That shouldn't be so hard." But she stopped and thought. "At least, it wouldn't be hard for me."

"The promises are easy to misunderstand without preparation, and the only ones who can really know if you're prepared are God and you, yourself. So I guess it seems better to just have everyone -- all new members -- wait at least a year."

"Hmm. And I'm not really a member of your church yet, anyway. Darn."

I chuckled, and she sighed, then joined me in chuckling.

"I need to ... wash off the glow."

I shook my head. "Anything I say about that, I'm dead in the water."

She laughed.

Mom made sure Julia had what she needed for her shower on the south side of the house, and I took a quick shower in the other bathroom, on Giselle's and my side, and we packed our stuff in her car and headed to school.


[Backed up at https://joel-rees-economics.blogspot.com/2020/07/bk-33209-straits-exercises-exercises.html.]


Sunday, July 12, 2020

33209: Straits -- Keyboard Decoding

Chapter 13.3: Straits -- Status Display

Chapter 13.4: Straits -- Keyboard Decoding


"Much improved last night." Julia's mom gave me an approving smile as she met me at their front door.

I grinned lopsidedly and bussed her cheek as I ducked in. "Somebody must have been peeking through the blinds?"

The smile she gave me in answer might have been a little smug.

Julia came into the living room carrying her backpack on a shoulder. "I threatened to do all our kissing somewhere else, and Mom didn't even bat an eyelash," she complained.

"You two belong together. You can kiss anywhere." Mrs. Cisneros gave her daughter a quick hug and a kiss and sent us off with a "Have a good time studying together today."

I held the passenger-side front door of the Colt open and Julia climbed in.

She leaned her seat back and put her backpack in the back seat as I walked around and climbed in the driver's seat.

"How about if I drive tomorrow?"

"Your folks won't need your car?"

The radio came on as I started the engine.

"I can usually, I just want to drive. tomorrow."

"Okay. I'll be waiting for you."

DJ talk and music played in the background as I drove and we talked about the day's schedule and other things.

"I don't particularly like this song," Julia said as the radio played the chorus of Mary MacGregor's hit rendition of "Torn between Two Lovers".

"Mmmyeah. It does kind of get stuck in the head, and the lyrics aren't all that great"

Julia was silent for a moment, then asked, "Do you think it would be breaking rules to love two people?"

I thought for a minute. "My automatic reaction is that's not the right kind of love if it's breaking any real rules."

"Platonic okay, Plutonic no." She gave me a shy-sly grin as she reached over to the radio to change stations.

"Heh."

The station she picked was playing Boston's "More Than a Feeling", and we listened to it in silence for a bit, holding hands on the gearshift lever.

"Hey. I'm going to make everyone rewire their keyboard controllers today. I hope they won't be too mad."

"Why's that?"

"Not enough port bits. Need to add a buffer and share one port between the keyboard and display, to free up a port to talk with the main CPU."

"I might be a little put out, too."

She tickled my palm, and I missed a downshift, letting the engine lug for a moment while I returned the tickle.

*****

In the lab after classes, I was going to ask first off if anyone in our group had ideas about how to shorten the interrupt handling routines for the displays, and ask after that if anyone had noticed that 32 pins of parallel I/O wasn't really enough. But, when Julia and I arrived, a group was gathered around Winston. He was testing his keyboard and seven-segment displays, and when he held a key down, it would interfere with the display, causing it to show stray segments.

He looked up at me. "I don't think we have enough output lines."

"Yeah, ...," I hedged.

Bob had a suggestion. "I'm thinking we could add two 'LS138s and control them both from one parallel port to do the scanning -- one for the display anodes and one for one side of the keyboard matrix."

"Oh. That could work." I nodded absently. "Can we get a look at the problem before we go looking for solutions?"

"Then it is a bug." Winston half-asserted, half-asked.

"Oh, yeah. I was planning on looking at it first or second thing today when everyone comes. Can you explain it to everyone, Winston?"

"Why me?" he complained, half-joking, half-resigned, as he picked up his schematics and went to the chalkboard. He started by putting up the working diagram from the day before while we waited for more of the group to come.

When he was done with that, and most of our group had arrived, he gave me a nod, and I nodded to Doctor Brown, and Doctor Brown said, "Any time you're ready."

Winston went back to his lab table and picked up his keyboard and controller, and announced, "Ground control, we have a problem."

Several of us chuckled as Winston proceeded to demonstrate how holding keys down would change a number shown on the display to some unintended shape.

"That's cool!" Carlos enthused.

"Solution one," Doctor Brown intoned with raised eyebrows. "It's not a bug, it's a feature."

Everyone laughed except Winston, who rolled his eyes before grinning lopsidedly. "That is one way of looking at it," he grudgingly admitted.

"Yeah," Doctor Brown grinned, "but I guess let's not use that solution this time."

"So, why does this happen?" I asked. "Show us what your circuit looks like."

Winston erased and redrew part of the circuit:


"So, we could ask Winston why he added another buffer," I pointed out, semi-rhetorically. "Or we could ask everyone if we all understand why. Suzanne, can you tell us why?"

She hesitated, than suggested, "If we don't have that, how does the computer know what key the controller decoded?"

"Exactly. Thanks. So, Winston, now what's the problem?"

"We don't have enough bits of I/O, and I have used one of the ports for the displays as one of the ports for the keyboard matrix." He erased and redrew another part of the diagram to show what he had.


"I was hoping that the scan could be done quickly enough to not interfere, but just holding the keys down messes things up."

"Yeah. So, Bob, you had a suggestion, right?"

"Jennifer thinks we should be able to do it without any additional LSI chips, but I think we need two 74LS138s."

"Can you diagram that?"

"Well, first, I think we need another bit for the main CPU interface."

"Why's that?"

Jennifer replied, "Main CPU has to be able to tell the controller what it's supposed to do, so it needs at least one bit of control."

Bob and Jennifer worked together to quickly put the following diagram up:


"Hmm. Let's keep that in mind. So, what about the 'LS138 one-of-eight demultiplexors?"

Bob modified parts of the diagram, to add the two demultiplexors:


"This would allow both the keyboard and the display to be addressed at the same time," Bob explained. "But if I shut down the displays for a hundred microseconds or so for the keyboard scan, I can share the select lines for the 'LS138s, and save a couple more port bits."

"Great. Thanks. Now I think Jennifer is right that, with a bit of really careful timing, and a bit of care in how we set up the ports for the matrix and displays, we could reduce the interference so that you could hardly tell that holding a key down is causing stray LEDs to light. But it would be kind of sensitive to pull-up or pull-down resistor values, and cheap parts might not work. And we might need to add diodes, as well."

Jennifer looked a little put-out at my conjecture.

"I'm not saying she shouldn't do it, just that that there are trade-offs, and I'm not prepared to dig into that right now. Back to the 'LS138s, how will they affect our code? Bob and Jennifer, let someone else answer."

Bob and Jennifer both nodded in agreement.

Javier finally spoke up. "Instead of shifting the matrix strobe bit and the display select bit on their ports, we count them?"

"Good. What does the counting look like?"

Everyone thought for a bit, and then Javier answered: "Counting for one of those can be just an INC instruction. He stood up and wrote in a blank space on the chalkboard,
COLSTB
    INC PORTC ; STROBE NEXT
But the other is going to be adding sixteen or something, depending on the bits used, right?" He wrote, to the side of the first,
COLSTB
    LDA PORTC ; GET STROBE
    ADD #$10 ; NEXT COLUMN
    STA PORTC ; NEW STROBE
I nodded. "Exactly. Or, if, as Bob mentioned, he shared select lines between the two 'LS138s, both could be increments. So we'll look at that, too, but anyone have another way to do this? Jeff? Mark?"

"We're kind of with Mike on this," Jeff replied.

I turned to Mike, and he responded, "I'm planning on sharing a port between the keyboard and the displays, but I'll use a single eight-bit buffer to disable the keyboard input lines most of the time. There are only seven digits, so only seven anode selects, and I can use the extra bit from the display select port to shut off the keyboard matrix except when I'm reading it."

"How about the control line for the main CPU to read the keyboard?"

"The Micro Chroma 68 keyboard interface only uses seven bits of data, so the high bit can be the key input strobe, like the Micro Chroma 68  documentation shows. I think that'll be enough." Mike stood up at a blank panel and sketched out his idea.


"Very good. Now we have at least a couple of different approaches that might work."

Larry asked, "Would it work to use two 6805s?"

"What do you think?"

"I guess we'd need a way for the main CPU to talk to the second controller."

"Sure. And that may have some advantages, as well."

Kyle laughed. "So we wouldn't need to bother with the timer and interrupts."

"We got 'em," Tim replied. "Might as well use 'em."

 Terry asked, "How about using a serial port for talking to the main CPU?"

"The Micro Chroma 68 design is looking for the keyboard on a parallel port," I pointed out. "But if we modify the design and the monitor ROM, we should be able to get a serial interface to work, as well."

Chuck objected, "The 6805 doesn't have a serial port."

"True."

After a moment of thought, he said, "But I guess a single bit of a parallel port could work, the way it's done on the Color Computer."

"Bit-banging. We could put the 6805's bit operators to good use there, I think."

Chuck nodded.

Carlos asked, "Which are you going to use?"

"I'll ask Julia later."

Several of the group chuckled.

"Because it's her keyboard and computer, not mine."

I turned and grinned at Julia, and she creased her brow and gave me a quizzical look.

Lupe raised a question -- "Does the Micro Chroma 68 use this status display we're adding?"

"Not with the current software, but, again, we can modify the software to use it, if we want to."

"Then maybe we don't really want the display on the keyboard controllers we're building now?"

"That is definitely a design option," I concurred. "Or, if you want the display but want to do it another way, you could add a 6821 to the mainboard and have the mainboard CPU control it directly."

Tanya complained, "So, basically, for the last three days, we've been on a wild goose chase."

"Make that, we've been exploring options," I reinterpreted. "And learning how to use a timer interrupt, so we can use timed samples instead of riding the port to debounce the keyboard matrix. And looking deeper into what we might want to build."

Larry said, "Okay, so can we get back to debouncing the keyboard now? I'm kind of interested in that. Can we use the same timer setup that we're using for the display to sample the keyboard matrix and debounce it?"

"Explain."

"The whole point of the debounce is to be sure we read one keypress as one keypress? We could remember which key we saw in a variable, and check it on the next timer interrupt?"

"How long do we wait to accept a keypress?"

Julia dug into her notes and recited, "300 words per minute is five words per second. At six letters per word, that's thirty keys pressed a second, or one thirtieth of a second."

I reached over and squeezed her hand, and she gave me a lopsided smile and a sigh.

Terry added, "That's about thirty-three milliseconds, so it's about thirty-three interrupts, the way we've set up the timer for the displays."

Freddie asked, "Can a key bounce take more than a millisecond to settle?"

Suzanne suggested, "We can count interrupts to time a keypress. Maybe sixteen interrupts is good to call it debounced."

I added, "Counting interrupts is good, and we can experiment with the duration, and we might even want to add keyboard repeat function based on counting timer interrupts."

"Don't make things too complicated," Doctor Brown warned me.

"Hmm. Maybe we should try to describe the steps the interrupt handler routine is going to go through before we talk about keyboard repeat and rollover."

"Flowchart?" Tanya asked.

"How about you draw it?"

"I don't know what to draw."

"We can figure that out as a class."

Pat suggested, "How about pseudo-code?"

"Okay, you write pseudo-code while Tanya draws the flow-chart."

George laughed. "If you keep making people who suggest things work, everybody'll quit suggesting things."

I tilted my head. "I think we're all here to work, and helping with the notes is an opportunity for work, like any other."

I don't know if that was a very good sales pitch, but Tanya and Pat both stood up and cleaned up panes of the chalkboard to work on.

"What's the first thing our interrupt response routine does?"

"Clear the interrupt mask?" Larry suggested.

"What happens if the next interrupt comes before we're done?"

Everyone thought for a bit.

"Should I try to answer that?" Bob asked.

"Sure, go ahead."

"We lose track of part of the start of what the first interrupt was trying to work on."

"That's the underlying problem. What does the user see happening?"

"Uhm, I think there would be missed keys. And the display might lose digits."

"I think you're on target."

"So when should we enable interrupts?" Suzanne asked. "If we keep them disabled too long, that will also cause missed interrupts and missed keys."

Mike responded, "Missed interrupts, but keys can still be caught and display digits are less likely to be dropped, I think. So, enabling should be just before we return, I guess."

I agreed.

"And," he continued, we need to keep the interrupt routine as short as possible."

"Exactly."

"If that's the case, I guess we probably don't want to be translating the display digits to segment images at interrupt time."

"Okay."

"What did Mike just say?" Julia asked.

"Thank you again, Julia," Tanya applauded.

Bob replied, "SEGTBL has the segment images. I think Mike is suggesting that, instead of keeping a buffer full of the numeric values to display, we should keep a buffer full of the corresponding element of SEGTBL."

"Yeah," Mike confirmed. Although, I think it's just one or two instructions saved."

I added, "I think it also makes the display more flexible, but we'll talk about that later. Right now, it's the principle of the thing. Do we want to take time in the interrupt response to decode the keyboard?"

Pat hesitantly raised her hand, and Mike said, "Just ask, Pat."

"No? But how do we remember what key we're trying to debounce?"

I looked at Doctor Brown, and he shrugged.

I hesitated. "Well,  maybe we don't exactly want to remember which key."

*~*~*~*~*

Again, just how prescient should I imply, or claim, that I might have been?

Sure, the real me was prescient. I understood far more than the limited exposure I had in high school and during my time at Radio Shack might explain. I'm sure I brought a lot of that knowledge with me from the pre-existence -- from the world before birth -- into this world. But would I really have been able to work this one out in this world's technology without more experience?

Experience wins over theory any time you want to make something that actually works, and what I had in the previous world would have been more theory and principle, not so much application and experience, and definitely not experience colored and transmorgrified by the real-world reductions into -- implementations of -- real technology that were invented in this world since the time I was born.

Even had I been one of the in-crowd there which prepped the individuals who would be leaders of the industry in our present world, things changed drastically when the tech was implemented here. If you've ever worked on a systems development team, you know things always change in implementation.

And I suspect I was a rebel there, too.

I always had trouble in school with the question of how much I wanted to sully my understanding of principle with the details of real-world implementations. I knew my hesitance was worrying too much about what I would ultimately find relevant, but without experience who knows what is irrelevant?

Our best theories in this world fall so far short, even of what we knew then, not to mention falling so completely short of what God knows, understands, and does. If theories fall short, so goes the implementation.

It doesn't matter. For the purposes of this novel, the me of this story must have been able to lead this discussion, or he could not have done what he had to do. But he has good company. There are other superhumans in this group.

*~*~*~*~*

Sheryl voiced the doubts most of the group had -- "How do we debounce a keypress we don't even know we've seen?"

"Good question." I turned it back to her. "What is that microprocessor going to see when it scans the keyboard matrix?"

Sheryl thought and then replied. "A whole bunch of zeroes and one one."

"One one? Sounds like a dog barking."

Everyone looked at me questioningly.

"Japanese joke. Woof-woof is wan-wan in Japanese. Sorry. Never mind."

Sheryl wasn't the only one shaking her head, but she replied. "Just one, I think."

I looked hopefully at Julia for support, but she just gave me a smirk and rolled her eyes.

"Does everyone agree?" I asked.

We had some nods and some blank looks.

"Okay, let's look at some possible code for this. We'll assume Mike's buffer for separation, with the keyboard matrix enabled. SHARED is the port shared for strobing the keyboard and setting the display segments, and KBDIN is the other edge of the matrix." I pointed to the buffers as I mentioned them. "Scanning will begin something like this," I erased a panel and wrote
    SEC
STBLUP
    ROL SHARED
    LDA KBDIN
"What happens next?"

"Mike?" Winston probed.

"I know what I'm doing. We all need to think about this."

Larry said, "Well, the natural response is to wait for a one, but we have to look on seven other rows, too. And Joe keeps harping about busy-waiting, so I don't think that's what he thinks we should do."

"You can busy-wait if you choose. I'm just trying to point out how to sample instead."

"Sample?" Terry piped up. "If we're going to sample, we need to record all the samples."

I held up the chalk, and she stood and took it, then went to the chalkboard and added to what I had written:
KBDST RMB 8
*
    LDX  KBDST ; STATE ARRAY
    CLR SHARED
    SEC ; READY TO STROBE
STBLUP
    ROL SHARED ; STROBE
    BCS KBDDUN ; DONE YET?
    LDA KBDIN ; COLUMN STATE
    STA ,X ; SAVE IT
    INX ; NEXT
    BRA STBLUP
KBDDUN
"That records the entire keyboard state. First I point X to the keyboard state array in page zero, I mean, direct page, RAM. Then I clear the shared port so we can shift the strobe across it. Then I set the carry flag to be shifted in.

"Rotate left shifts the carry flag in the SHARED port for the strobe. First time, it shifts the carry flag in. Branch on carry set will stop us when the carry flag is rotated out of the high bit."

"Note," I pointed out, "that branch on zero, BEQ, will also work and may be more resistant to hardware failures."

Julia raised her hand. "What? Is that supposed to go in the notes?"

"In case of short circuits or other bad things that could happen to the keyboard," I explained.

Wallace was writing the notes. "Got it."

Julia gave me a perplexed look. "I guess we can go on, but explain that tonight, please."

"Well, if the strobe bit is shifted out, the carry will be set, but so will the zero flag, because there will be no ones left in the port output register. It's a different way to test for the end of the loop, and we might want to take the time to consider which will be less likely to have problems when there are hardware failures."

"Does it matter on a keyboard?" asked Javier.

"Maybe, maybe not."

Doctor Brown cleared his throat. "Leave it in the notes, and add that we really don't have the tools for the analysis yet."

I exchanged glances with him.

"Got that, too," Wallace said.

"Right," I concurred. "Something to think about later."

"I can continue?" Terry asked.

"Please."

"Then we load the column state from the KBDIN port and store it where X points into the state table, and bump X before branching back. I don't think I need to clear the carry bit after incrementing X because there's nothing in the loop that would set it besides the rotate."

"Good, --"

Wallace interrupted. "But why check them all? Why not jump out of the loop on the first scan that's not all zeroes?"

Terry pointed out, "There may be other ones, as well. You don't always release one key before pressing another."

"I guess that's true." Winston tilted his head. "But can we handle that?"

"I think we can. Terry, can you walk us through how that would work?"

"What we want to see is which bits changed." She thought for a moment. "So we need to keep a record of the previous sample, too."

"I think so. It uses a lot of the MCU's little bit of RAM, but I think we need to keep three records."

"Do we have time to copy all of it?"

"Maybe. I think we can do it without copying three times, but let's look at copying first. I think it would be easier to understand."

Terry nodded, erased her code and started over.
KBDST0 RMB 8 ; NEWEST
KBDST1 RMB 8
KBDST2 RMB 8 ; OLDEST
*
    CLX ; FIRST COLUMN
    LDA #1
    STA SHARED ; STROBE
STBLUP
    LDA KBDST1,X ; COPY 2ND
    STA KBDST2,X ; TO OLDEST
    LDA KBDST0,X ; COPY PREVIOUS
    STA KBDST1,X ; TO 2ND
    LDA KBDIN ; GET STATE
    STA KBDST0,X ; SAVE CURRENT
    INX ; NEXT COLUMN
    ROL SHARED ; NEXT STROBE
    BCC STBLUP ; UNTIL CARRY
"That's pretty tight programming."

"Thank you."

"After finishing the copying, is there anything left to do before returning from the interrupt handler routine?"

"Wait," Julia said. "Pat and Tanya are stuck."

I laughed. "Sorry. I'm getting carried away. This little routine should be called 'Copy Keyboard State' or something." I paused until they were ready.

"Terry?"

"It starts with zeroing the index and preparing the strobe for the first column. Then it enters a loop without testing first." She paused.

"Copies the previous state over the oldest state for the column.

"Then copIes the most recent state over the previous state for the column.

"Reads the new current state and saves it."

"Bumps the index and shifts the strobe for the next column.

"Finally, if the strobe bit has shifted out, it's done."

Pat's pseudo code looked like this:
Copy Keyboard State:
    Zero column index;
    Prepare column strobe;
    Loop --
         Overwrite oldest state for this column with 2nd oldest;
         Overwrite 2nd oldest state with most recent;
         Overwrite most recent state with current;
         Bump column index;
         Shift strobe bit left;
    Until no columns left to strobe.
Tanya's flow chart looked like this:


"So, Terry, is there anything left to do?"

"If we've already done the display stuff when we get here, I don't think of anything else."

"Very nicely done. And that was no idle compliment. Let's count the cycles to see if that can all happen within a millisecond."

Everybody got involved in digging into the cycle counts from the dataheets and adding them up.

"CLX is four cycles."

"Three cycles for CMOS."

"These are CMOS chips aren't they?"

"Yeah."

"I'm counting HMOS cycles, just to be safe."

And so forth, some using the detailed timing charts and others using the summary in the op-code table.

"Fifty cycles through one loop."

"Roughly, worst case."

"Times eight is four hundred cycles worst case."

"That's not quite half the time between interrupts."

"Is that too much?"

"It'll only happen once every sixteen milliseconds, or so, right?"

"We'll have to test it."

"Joe said we could avoid all the copying."

"Well, we can avoid copying the previous and second previous. It's a little less straightforward, because we have to keep track of which one is the oldest and only overwrite that one. Then remember which is the new oldest. I think that should cut the time down under a hundred cycles. But I think four hundred cycles, plus the time for the interrupt counting, etc., isn't too much. Some of you might want to try both. Or you could also adjust the timer interrupt, to two or four milliseconds."

That gave everyone something to work with for a bit, each fitting the processes to their own circuits.

Then Carlos asked, "Okay, we've recorded all this state, now what? How do we check for someone hitting a key?"

"Good question." I checked the time before asking, "Any suggestions?"

Carlos frowned. "Looking for ones is not the answer, I guess."

"Almost."

"Look for changes."

"Right."

"Compare instruction, CMP?"

"That'll only tell us if there's a change. It won't tell us which changed. There's a way that can tell us which of eight bits changed with just one instruction," I prompted.

"The exclusive-or instruction?"

"Bingo."

"Does that mean we have to use eight more bytes to remember which bits went high?"

"Yes -- or to remember which changed and are no longer bouncing. We can check the most current state to figure out whether the change was a press or release."

"And this is not in the interrupt routine?"

"Right."

"How do we know when to look?"

"How about checking the interrupt count?"

Carlos shrugged. "Uhm, explain that?"

"After the interrupt routine counts sixteen interrupts or so and records the new samples, it can leave the count at sixteen, and the non-interrupt code can see that sixteen, check and record which changed, and subtract sixteen from the count to start over. Or clear the count if we are sure we don't get interrupted. But subtracting would be safer."

"Hmm. I guess I need to think about that."

I checked the clock again. "Well, I need to go deliver my newspapers. Who wants to lead the discussion of how to turn this into code, and how to work out the key codes from the bits that changed, and how to buffer key codes that the main CPU hasn't read yet? Mike?"

"I vote for letting Jennifer lead it."

"Why not? I'll let you guys work it out. I have to run."

*****

When I got back, they had worked out recording the changed bits, and were working out out to turn a changed bit into a bit number, to figure out which key was pressed. I suggested not loading the bit or count into the index or accumulator, to avoid having to save and restore them:
KBIT RMB 1 ; BIT TO COUNT
KBITCT RMB 1 ; BIT # COUNTER
*
    CLR KBITCT ; START AT BIT 0
KBITLP
    SHR KBIT ; SHIFT DOWN
    BEQ KBITDN ; DONE IF OUT
    INC KBITCT ; COUNT BIT
    BRA KBITLP ; DO IT AGAIN
KBITDN
* BIT NUMBER NOW KNOWN
There were several using math to convert the keyboard matrix to ASCII codes, but some had keyboard matrices that varied enough from ASCII to make that hard. So I showed them how to put the key codes in an array to match the keyboard matrix they had, using the bit number concatenated with the column number times eight to index the array.

* COLUMN INDEX IN X
    SHLX ; TIMES 8
    SHLX
    SHLX
    TXA ; COLUMN NUMBER TO A
    ORA KBIT ; KBIT <= 7

    TAX ; MATRIX ELEM #
* USE THIS TO INDEX
* ASCII CONVERSION TABLE
George complained, "I've heard that global variables are bad, but we're using globals all over the place."

Jennifer complained, as well. "Doctor Brown just laughs at us when we worry about it."

"I'm only here to make sure you don't destroy the lab." If anything, his grin was even broader. "And steal ideas for my lesson plans next year."

That provoked much laughter, and a release of stress.

"Seriously, though. I'm getting a lot of good ideas from watching you guys. And I want to see what Joe has to say before I weigh in."

"I'm not sure what I have to say, but it seems to me there are several problems in organizing our variables. One is where you declare them in the source program. We've been declaring them as we invent code snippets, then moving the actual declarations into the direct page variable list when we put the snippets into our code.

Jennifer tilted her head. "What about variables on the stack? Doesn't the 6805 have a way to put variables on the stack?"

"First question, which stack?"

"Now it gets interesting," Doctor Brown intoned.

"Which stack?" Winston echoed. "Is there more than one?"

"The 6805 doesn't have a parameter stack, perhaps because Motorola figures, if the code is complex enough for re-entrant parameters, it's complex enough to use something more powerful."

"Then why," asked Jennifer, "the jump subroutine instruction?"

"Cheap on transistor count and allows some simple code reuse? I guess. Anyway, that appears to be the approach we should take, graduating the project to a more powerful processor when we want to put parameters on a stack."

Julia shook her head. "I don't think I'm the only one who's lost."

"Can we talk about this tomorrow? I'm kind of hoping we can get some of the keyboards working today."

Doctor Brown laughed. "Classic avoidance maneuver, but I agree. Too early for a lot of you to talk about re-entrance and stacks."

Having only one computer to program 68705s on was a bottleneck, but we were able to get Winston's, Mark's, Jeff's, and Suzanne's keyboards working, and they plugged them into their Micro Chroma 68+6803s and started playing with the TV-BUG monitor. Some of the students who were waiting watched the fun.

Julia declined to use group time to program her keyboard. "I didn't bring the Micro Chroma today, anyway."

"Oh, is that why tomorrow?" I asked, and she just gave me a kind of thoughtful look.

"Sure. That's why." And she winked at me, but wouldn't explain further.

"Okay."

We got a few more keyboards running before time to shut down.

*****

"Intel 8086?" Julia looked at the book I was borrowing from the library. "What do you need that for?"

"Ammunition."

*****

From school, Julia and I went to her house for dinner, and from there we went to her Bible study group. Reverend Johansen was there, and while I don't remember what we discussed, I do remember we enjoyed the discussion. I carefully limited my contributions, to avoid raising issues that would lead to contention, and to focus on supporting the witnesses the members of the group held.

We studied together at her home afterwards, before taking fifteen minutes for me to practice for the recitation. Her mom and Dad joined in, singing in English.

Then we set up my Micro Chroma 68, and Julia programmed her keyboard controller and plugged the keyboard into my Micro Chroma 68 to test and play with it, while I studied the i8086/8088 manual and the TMS 9900 and 9940 manuals.

Her little brothers watched for a while, but got bored and left.

I recalled one of Julia's questions in class.

"Remember that BLWP instruction I was looking for last night?"

"Yeah."

"You can use it to allocate variables on a stack. When you leave a subroutine, you deallocate the variables."

"Allocate, I think I can understand. That's like reserving space for working on things?"

"Right. Reserving space to work on things."

"So deallocate would be giving the space up?"

"Right again."

"I guess that makes better use of RAM."

"It also means that, if you have more than one process running, the variables on the stack are local -- kind of private -- to the the process that owns the stack.

"I'll have to think about that. So what kind of ammunition are you getting from the 8086 book?"

"Registers that have limited uses. It's better than the 8080, but they are still pretty limited, compared to the even 6800's use of memory."

"Do you think they have a reason for that?"

"Simplifying their circuitry, mostly, I'm sure. And adding special purpose features in the transistors that are left available."

"Marketing?"

"Yeah."

I read in silence for a bit more. "Really weird address registers. It's like they deliberately put holes in addresses."

"Huh?"

I showed her a diagram of the 8086 segment registers and how addresses are assembled in the original 8086 segmentation.

"I can't even begin to understand what they are trying to do."

"The actual address registers are sixteen bit. So are the segment registers. But the segment registers are slid over four bits, before being added, so you can play address games and use two megabytes of RAM, if you do it right."

"So you can add more RAM. Do Motorola processors do that?"

"There is a memory management unit for the 6809, and, I think, the 6800, that allows a megabyte of memory to be addressed, and allows memory to be moved around in two kilobyte pieces to mix and match. The 8086 gives a cheaper, half-baked approach that doesn't really allow mixing and matching, except in sixty-four kilobyte sliding frames that slide with a sixteen address bump."

"Hmm."

"The address registers of the 68000 allows completely linear segmentation, if you want to use it. No shifting partial addresses around. No bumpy slide. The 6809 has a single direct page register that's similar to the segment registers, but is just appended whole to the direct page address, and doesn't extend overall space."

"I'll have to figure out what this is all about later."

"Yeah. Ah. The 8086 has instructions to support stack frames, kind of like the 9900. And it becomes clear to me why I don't like the idea of keeping return addresses in the stack frame."

"Return addresses?"

"The program counter from the routine that calls the subroutine, so you can get back to the calling code -- you save the program counter on the stack. With parameters and locals on the same stack, you're going to have return addresses and parameters and locals colliding. And bad things will happen, like returning to data instead of code, and then who knows what happens next."

"Who knows? I'm getting sleepy."

"Bad things like when my Micro Chroma's reset switch bounced and it would cause random text and flashing meaningless graphics to show on the screen."

"Oh." Her eyes closed and her head nodded, then she shook her head and blinked. "I think it's time for you to go home."

We shared a quick kiss or two as I prepared to leave, and her mother cleared her throat from the kitchen, where she was working through the monthly bills.

"Mom, not tonight. I've been studying stuff that is completely foreign to me. Joe calls it playing, but I'm tired."

Her mother smiled gently. "Some days are like that." She took us both in for a hug.

"I have to admit to being a bit tired myself," I added. "Julia's keyboard will now talk to her computer. Tomorrow's going to be another long day, I think."

"Speaking of her computer," Mr. Cisneros spoke up from the couch, "I think she needs a box to put it in."

"True."

I sat back down, and we discussed different kinds of enclosures for her computer for maybe a quarter of an hour, Julia and I holding hands in between making sketches and using our hands to talk about the shapes of things. We talked about a box like mine, and we also talked about putting her keyboard in a separate enclosure so she could move it around separately from the computer.

Mr. Cisneros asked about possible standard bus technology, and I promised to look more into Motorola's EXORbus.

Julia put the sketches with her notes, and we shared another quick kiss before I left.



[Backed up at https://joel-rees-economics.blogspot.com/2020/07/bk-33209-straits-keyboard-decoding.html.]


Wednesday, June 24, 2020

33209: Straits -- Status Display

Chapter 13.2: Straits -- Sabbath

Chapter 13.3: Straits -- Status Display


"Okay, guys, I have to focus on Julia's computer, so let's all work on our keyboard controllers on our own for a while."

"Focus on your girlfriend, huh?" Tanya was apparently feeling a little catty.

"So you're finally owning up to it!", Suzanne pouted. "What did it take?"

"Oh, shutup, Suzanne," Mike grumbled. "I, for one, don't want to hear about it."

Wallace also complained. "Leading us on, and then jumping ship for your girlfriend?"

Winston admonished, "We can handle this. Bob and Jennifer almost have it worked out, anyway."

Jennifer shook her head. "It's time for us all to work on our own for a bit. That's what we're here for."

"Should you just abandon everyone for me?" Julia asked.

"I'm not abandoning anybody, and Jennifer's right."

Doctor Brown just watched in amusement.

There was more grumbling, and some of the members of the group parked themselves where they could watch as I used scratch paper to show Julia how the display translation tables would be put together. But I ignored them and proceeded to recreate a diagram from Saturday.
                 

"Others have theirs wired up differently, but the way you ended up wiring yours is the same order as the diagram I drew. Bottom left is the high bit, and decimal is the low bit. Let's name those."

"Name them?"

"Give them names in the program."

"Okay."

"We'll call the bottom left segment BLS, and it will be binary 10000000."

"You and Dad both told me about converting to hexadecimal four bits at a time, so that's 1000 and 0000, which comes out as $80?"

I gave her a thumbs-up and scrawled
BLS EQU $80 ; 1000 0000
"Instead of BLS, BLT would not be a good name?"
Julia and I chuckled at her joke, and so did the students who were listening.

"No?"

"Well, I was thinking S for segment, but why not? T for the last letter of 'bit'. How about the rest?"

"Like this?" Julia wrote out code, intuiting the permutations from the line I'd written:
BLT  EQU $80 ; 1000 0000
BT   EQU $40 ; 0100 0000
BRT  EQU $20 ; 0010 0000
MT   EQU $10 ; 0001 0000
TLT  EQU $08 ; 0000 1000
TT   EQU $04 ; 0000 0100
TRT  EQU $02 ; 0000 0010
DT   EQU $01 ; 0000 0001
"Yep."

"Oh, maybe T is a little confusing."

"It's okay. We'll keep it. As long as we can read it and understand it."

"Then we'll need comment lines to help us remember?"

"Such as?"

She wrote,
* T FOR BIT:
* BOTTOM, TOP, MIDDLE
* LEFT, RIGHT, DECIMAL
"Looks good, and it keeps it short for the screen we're working on."

"Do the last four EQU lines need the dollar sign and the zero?"

"No, they're the same in decimal and hex, with or without the leading zero. But simplifying them would make the form less obvious, so let's keep them this way. So, now let's use those to make a table of segments, like we figured out on Saturday. The zero will be the first entry. Which bits does it use?"

"All but the middle and the decimal?"

"Okay. We can use '.OR.' to put bits together, so it can look like this:"
TABLE
    FCB BLT.OR.BT.OR.BRT.OR.TRT.OR.TT.OR.TLT
"That's not going to fit in the 32 column screen."

"True, but that's okay. Wrapping won't hurt. Oh, but it's also ugly -- hard to read, and that is not okay. Maybe I can think of something to help."

After a little thought, I wrote
CUP EQU BLT.OR.BT.OR.BRT
CAP EQU TRT.OR.TT.OR.TLT
*
TABLE
    FCB CUP.OR.CAP
"It sort of helps."

"Heh. Okay, there's zero. One is easy."

She scribbled her guess, "BRT.OR.TRT". "Is that it?"

"Right."

With a bit of scribbling, erasing, and rescribbling, we had this:
BCUP EQU BLT.OR.BT.OR.BRT
TCAP EQU TRT.OR.TT.OR.TLT
ONET EQU BRT.OR.TRT
TRCUP EQU TT.OR.TRT.OR.MT
BLCUP EQU MT.OR.BLT.OR.BT
BRCUP EQU MT.OR.BRT.OR.BT
TCUP EQU TLT.OR.MT.OR.TRT
TLCUP EQU TT.OR.TLT.OR.MT
BCAP EQU BLT.OR.BT.OR.BRT
VBAR EQU TLT.OR.BLT
*
SEGTBL
    FCB BCUP.OR.TCAP ; 0
    FCB ONET ; 1
    FCB TRCUP.OR.BLCUP ; 2
    FCB TRCUP.OR.BRCUP ; 3
    FCB TCUP.OR.BRT ; 4
    FCB TLCUP.OR.BRCUP ; 5
    FCB TLCUP.OR.BCUP ; 6
    FCB TT.OR.ONET ; 7
    FCB BCUP.OR.TCAP.OR.MT ; 8
    FCB TCAP.OR.BRCUP ; 9
    FCB TCAP.OR.BCAP ; A
    FCB VBAR.OR.BRCUP ; b
    FCB BLCUP ; c
    FCB BLCUP.OR.ONET ; d
    FCB TCAP.OR.BLCUP ; e
    FCB VBAR.OR.TLCUP ; F
"I can sort of see what the table is, but how does that get into the LEDs?" Julia asked me.

"I've been avoiding that question for a whole week. I want to use a parameter stack, but we're a little tight on both RAM and registers. I guess we're not going to be trying to run two displays at once, so global variables should work."

Julia looked at me with a blank expression.

I proceeded anyway. "We'll have a variable for the current number to display and a variable for the current column to display in, and --" I scribbled:
NUMDSP RMB 1
CLMDSP RMB 1
"We can squeeze those into a single byte if we need to, but let's do it simple first."
PUTDIG
    LDX NUMDSP ; HIGH BITS ZERO!
    LDA SEGTBL,X
    LDX CLMDSP ; HIGH BITS ZERO!
"I'm lost."

The lab erupted in applause, and I looked around and realized that everyone was gathered around listening, and Mark, Jeff, Mike, and even Bob and Jennifer had been taking turns transferring our scribblings and musings to the chalkboard so they could all take notes.

I looked over at Doctor Brown, and he gave just gave me a "Who, me?" look.

I chuckled in embarrassment.

"Okay. Maybe we should do this as a group after all, and then you can all adjust it for how you wired yours. But I guess we need to use teamwork on the notes and explanations. Who followed how we put the table together?"

Bob, Jennifer, Mark, Jeff, and Mike said they were good on it, some of the others raised their hands hesitantly. There was a lot of doubt.

"I don't seem to do hexadecimal math in my head," George apologized. "Can someone explain it?"

Mike started scribbling on some scratch paper. "It's like this, --"

Doctor Brown suggested, "Mike, could you do that at the board for those who need some review?"

After a moment of hesitation, Mike stood up to the chalkboard and quickly wrote out a conversion table:

decimal
hexadecimal
binary
0:$00=0000 0000
1:$01=0000 0001
2:$02=0000 0010
3:$03=0000 0011
4:$04=0000 0100
5:$05=0000 0101
6:$06=0000 0110
7:$07=0000 0111
8:$08=0000 1000
9:$09=0000 1001
10:$0A=0000 1010
11:$0B=0000 1011
12:$0C=0000 1100
13:$0D=0000 1101
14:$0E=0000 1110
15:$0F=0000 1111
16:$10=0001 0000
17:$11=0001 0001
21:$15=0001 0101
32:$20=0010 0000
37:$25=0010 0101
128:$80=1000 0000
133:$85=1000 0101

"We got groups of four binary digits on the right, and they match up with single digits of hexadecimal in the middle. It's not a coincidence. It's a rule."

After a bit of discussion, George just shrugged. "I guess I'm just not seeing something. Maybe we should keep going."

I concurred. "Mike can help you, and we'll be showing a lot of examples, I think. Let's see if moving ahead works."

"Joe."

"Julia?"

"Let me try." She stood up.

"I'm going to enjoy this."

She gave me a sharp look, but I just grinned.

"The LED's in our seven-segment displays are laid out to show the shapes of pieces of numbers when they're lit, okay?"

George nodded hesitantly.

"Let's ignore those shapes for now. Instead, we'll make each LED, each individual LED, a binary digit, or a bit. That's a place, or a column, or a position, in a binary number. If the LED lights, that's a binary one for that place in the number -- for that bit. If it doesn't light, that's a zero."

"I'm lo--"

Julia gave him an eyeroll.

"-- Lost, but I'll try to keep up anyway."

"There you go. So we take this seven-segment display and straighten out the LEDs in our minds, so they can form binary numbers that are not the same as the shapes when they make numbers. And we can use those numbers to figure out which bits of the port to set to one to make the display show the number."

"Maybe I'm seeing something."

"So the binary number that lights up the segments to make a '1' is zero-zero-one-zero, zero-zero-one-zero, which is hexadecimal two-two." She wrote "0010 0010" on the chalkboard, then turned and looked at me. "At least, as Joe keeps saying, in the circuit Joe and I have been making."

I nodded.

"In decimal," she continued, "that would be 34. But we aren't thinking in decimal. We don't care that 34 is smaller than 35 or bigger than 33. We use the hexadecimal numbers because they help us remember which LEDs are lit. It's easy ... well, sort-of easy to remember that two in binary is one-zero. Or, if you write it with four bits, zero-zero-one-zero."

George still looked doubtfully at Julia, but he said, "I think I'm seeing something now. Thanks. This might help me understand those examples Joe was talking about."

Julia gave me look that said, "I tried," and sat down.
"Thanks, Julia," I said. "I think that helps. Sometimes it takes a different approach."

After making new arrangements to make sure Julia would not be so busy taking notes that she couldn't think and ask questions, I started over, working through the elements of 6805 assembly language as I used them.

"'E-Q-U' is short for equate. It equates the label on the left to the expression on the right. Hopefully we don't need to know when the expression is evaluated, because I don't know and I don't want to waste time figuring that out."

Nobody complained about what I had said, so I continued

"When we write
BLT  EQU $80 ; 1000 0000
"that could mean bacon, lettuce, and tomato is flagged by bit seven, or it could mean the bottom left segment bit is bit seven."

That got some chuckles.

"'.OR.' is the logical-or operator. It performs a column-by-column logical or, keeping the column results in their columns. That means that'
ONET EQU BRT.OR.TRT
"equates the label ONET to the result of 00100000 or-ed with 00000010, which is 00100010, or hexadecimal 22."

I wrote on the chalkboard,
0010 0000
0000 0010
-------------
0010 0010

"And if we put $22 on the segments port and hold the anode of one of the displays down to 0, it should make the top and bottom right segments light up, showing us a '1'. If we want to see that, we could try something like"
START
    LDA #22
    STA CATHODES
    LDA #FE
    STA ANODES
WAITLP
    BRA WAITLP
"'LDA loads a small value into the accumulator, STA stores the value in the accumulator to memory or I/O space, BRA means branch always and forever, and it does so, looping to itself, letting us see the results. This is a CMOS 1468705, so I think we could use a WAIT instruction here, but this loop forever to itself will do what we need with most CPUs. So it's a good thing for everyone to see, at least once."

I decided to stop and demonstrate it. I added the reset vectors, then asked Julia to type it in, assemble it, and burn it into her 68705, and power it up to run the short program. When it produced a 1 on the rightmost seven segment display, George and some of the other students seemed to gain a bit more confidence of what they were looking at

"Hopefully everybody's working out your own equate definitions for your own circuits while we do this. I guess we should put the definitions Julia and I came up with on the chalkboard, but remember yours will be somewhat different." And as I copied to the chalkboard, I added more comments, showing the expected bit values:
* BOTTOM, TOP, MIDDLE
* LEFT, RIGHT, DECIMAL
* SEGMENT BIT T
BLT  EQU $80 ; 1000 0000
BT   EQU $40 ; 0100 0000
BRT  EQU $20 ; 0010 0000
MT   EQU $10 ; 0001 0000
TLT  EQU $08 ; 0000 1000
TT   EQU $04 ; 0000 0100
TRT  EQU $02 ; 0000 0010
DT   EQU $01 ; 0000 0001
*
BCUP EQU BLT.OR.BT.OR.BRT
* 1110 0000 $E0
TCAP EQU TRT.OR.TT.OR.TLT
* 0000 1110 $0E
ONET EQU BRT.OR.TRT
* 0010 0010 $22
TRCUP EQU TT.OR.TRT.OR.MT
* 0001 0110 $16
BLCUP EQU MT.OR.BLT.OR.BT
* 1101 0000 $D0
BRCUP EQU MT.OR.BRT.OR.BT
* 0111 0000 $70
TCUP EQU TLT.OR.MT.OR.TRT
* 0001 1010 $1A
TLCUP EQU TT.OR.TLT.OR.MT
* 0001 1100 $1C
BCAP EQU BLT.OR.BT.OR.BRT
* 1110 0000 $E0
VBAR EQU TLT.OR.BLT
* 1000 1000 $88
*
SEGTBL
    FCB BCUP.OR.TCAP ; 0
    FCB ONET ; 1
    FCB TRCUP.OR.BLCUP ; 2
    FCB TRCUP.OR.BRCUP ; 3
    FCB TCUP.OR.BRT ; 4
    FCB TLCUP.OR.BRCUP ; 5
    FCB TLCUP.OR.BCUP ; 6
    FCB TT.OR.ONET ; 7
    FCB BCUP.OR.TCAP.OR.MT ; 8
    FCB TCAP.OR.BRCUP ; 9
    FCB TCAP.OR.BCAP ; A
    FCB VBAR.OR.BRCUP ; b
    FCB BLCUP ; c
    FCB BLCUP.OR.ONET ; d
    FCB TLCUP.OR.BLCUP ; E
    FCB VBAR.OR.TLCUP ; F
"The FCB that we use to construct the table of constants stands for 'Form Constant Byte or some such, and it is used to store a constant value into the program object code. By putting them into a table in the object code, we make the patterns available for look-up.

"Now, if we shift the anode bit, we can light up one digit at a time, but it's going to happen so fast it will look like they're all lit up at once. The LSL instruction shifts the argument one bit to the left, so we'll use it to pick which which digit to light."

Eyes were glazing over, so I wrote another bit of demonstration code, directly using the constants I had defined earlier:
PAUSE
     DECX ; IDLE COUNT
     BNE PAUSE
     RTS
*
START
    CLRX
    LDA #FE
    STA ANODES
    LDA #ONET
    STA CATHODES
    BSR PAUSE ; LET PORT SETTLE
    LSL ANODES
    LDA #TCAP
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #VBAR
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #BLCUP
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #TRCUP
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #TCUP
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #BCAP
    STA CATHODES
    BSR PAUSE
    BRA START
"The PAUSE routine uses the X register as an idle counter. DEC counts X down one, and BNE loops back to count again until X is zero. 'B' for Branch. 'NE' for Not Equal, or in other words, not zero. I suppose I'll have to explain that more later. Anyway, we turn a digit on, then we pause for a bit so the human eye can register it."

"And get your minds out of the gutter, guys, BRA really is a BRanch Always. so when we have displayed all the patterns, one place at a time, we go back and do it again.

Suzanne complained, "I suppose some male engineer thought that mnemonic up."

"You suppose right. Apparently more than one. I do not defend them. In a little bit, I'll show you how to use a macro definition to give that instruction a better mnemonic name."

"I don't suppose anyone will forget the original mnemonic," Bob commented, and Jennifer slapped him over the head.

Doctor Brown watched this in amusement, taking no sides.

Again, Julia typed it in, assembled it, and burned it, this time into a 68705 she borrowed from Jeff while hers was in the eraser.


She was rather dissatisfied with the cryptic output, so she got back on the computer and added equates for each digit, using the equates in the table itself:
N0 EQU BCUP.OR.TCAP ; 0
N1 EQU ONET ; 1
N2 EQU TRCUP.OR.BLCUP ; 2
N3 EQU TRCUP.OR.BRCUP ; 3
N4 EQU TCUP.OR.BRT ; 4
N5 EQU TLCUP.OR.BRCUP ; 5
N6 EQU TLCUP.OR.BCUP ; 6
N7 EQU TT.OR.ONET ; 7
N8 EQU BCUP.OR.TCAP.OR.MT ; 8
N9 EQU TCAP.OR.BRCUP ; 9
NA EQU TCAP.OR.BCAP ; A
NB EQU VBAR.OR.BRCUP ; b
NC EQU BLCUP ; c
ND EQU BLCUP.OR.ONET ; d
NE EQU TLCUP.OR.BLCUP ; E
NF EQU VBAR.OR.TLCUP ; F
*
SEGTBL
    FCB N0 ; $EE 1110 1110
    FCB N1 ; $22 0010 0010
    FCB N2 ; $D6 1101 0110
    FCB N3 ; $76 0111 0110
    FCB N4 ; $3A 0011 1010
    FCB N5 ; $7C 0111 1100
    FCB N6 ; $FC 1111 1100
    FCB N7 ; $26 0010 0110
    FCB N8 ; $FE 1111 1110
    FCB N9 ; $7E 0111 1110
    FCB NA ; $EE 1110 1110
    FCB NB ; $F8 1111 1000
    FCB NC ; $D0 1101 0000
    FCB ND ; $F2 1111 0010
    FCB NE ; $DC 1101 1100
    FCB NF ; $9C 1001 1100
Then she modified the test code to use her new equates:
START
    CLRX
    LDA #FE
    STA ANODES
    LDA #N0
    STA CATHODES
    BSR PAUSE ; LET PORT SETTLE
    LSL ANODES
    LDA #N1
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #N2
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #N3
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #N4
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #N5
    STA CATHODES
    BSR PAUSE
    LSL ANODES
    LDA #N6
    STA CATHODES
    BSR PAUSE
    BRA START
And she tried it again, borrowing a 68705 from Mark this time.


I think everyone cheered.

"But I have a question," she said.

"Yeah?"

"I don't think my code is actually using the table in this test."

"True. And I could get a swelled head and imagine I taught you that, but I think you've done more figuring out than I've done teaching."

"Oh, give her a kiss," Winston said. "She deserves it."

"No es para ...," I began, but Julia shook her head just perceptively enough for me to see.

"Whether I reward him with a kiss or not is my business," she said.

Wolf whistles and other unnecessary noises of appreciation ensued, and Julia and I cleared our throats simultaneously, with lopsided grins.

Mike did not join in the circus. 

"Back to work," Julia said.

I continued. "So now we need to try actually using the table. We'll use the X register to pick the pattern to display:"
    ORG $40 ; VARIABLES
PAUSER RMB 1
    ORG ROM ; CODE
PAUSE
    CLR PAUSER
PAUSELP
    DEC PAUSER
    BNE PAUSELP
*
START
    LDA #$FE
    STA ANODES
    LDX #1
    SEC
DISPLP
    LSL ANODES
    LDA SEGTBL,X
    STA CATHODES
    BSR PAUSE
    INCX
    CPX #8
    BNE DISPLP
    BRA START
"ORG means origin, and it sets the address where the next part is assembled. RMB Reserves a Memory Byte in low memory, which we will use instead of X as the idle loop counter. We label that byte PAUSER. CLR clears the variable in memory here, and DEC decrements it by 1, so it's much the same as using X for the idle count, just slower.

"The indexed addressing mode used in 'LDA SEGTBL,X' adds the constant address of the base of the SEGTBL table to the value in X and uses the result as the address from which we load the accumulator.

"With a 0 in X, the argument 'SEGTBL,X' points to the bit pattern to display a zero. With a 1 in X, it points to the bit pattern to display a one. And so forth."

I stopped to diagram it on the chalkboard:

SEGTBL,X(@SEGTBL+X)
SEGTBL+0:11101110(N0=$EE)
(X=1)=>SEGTBL+1:00100010(N1=$22)
SEGTBL+2:11010110(N2=$D6)
SEGTBL+3:01110110(N3=$76)
SEGTBL+4:00111010(N4=$3A)
SEGTBL+5:01111100(N5=$7C)
SEGTBL+6:11111100(N6=$FC)
SEGTBL+7:00100110(N7=$26)
SEGTBL+8:11111110(N8=$FE)
SEGTBL+9:01111110(N9=$7E)
SEGTBL+A:11101110(NA=$EE)
SEGTBL+B:11111000(NB=$F8)
SEGTBL+C:11010000(NC=$D0)
SEGTBL+D:11110010(ND=$F2)
SEGTBL+E:11011100(NE=$DC)
SEGTBL+F:10011100(NF=$9C)

"So we start with X equal to 1, then count X up with INC each time through the loop, after we display the number in that digit for a fraction of a second.

"We're only displaying seven numbers, so we use CMP to CoMPare X to 8, and BNE Branches back to do another as long as X is Not Equal to 8 at that point in the loop."

I looked at Julia, and she nodded hesitantly.

"I think it sort of makes sense. Should we let someone else do the programming this time?"

Freddie volunteered, so Julia traded places with her to let her take a turn typing and burning, but we still used Julia's circuit so the wiring would be right. By this time, Julia's 68705 was erased and ready to use, so she used it, and this demonstration produced the numbers 1 through 7 on the displays.

When the test proved successful, Freddie returned to helping take notes.

Mark and Jeff were keeping track of how long each MCU was in the eraser.

(As I write this, I don't have hardware to make sure I'm not forgetting something, but the programs should look something like what I'm giving here.)

"Anybody who's not comfortable with all of that, try out some of your own variations later. For now we need to write the real display code. Bob, Jennifer, are you up to picking up from here, to give everyone a break from me?"

Bob looked questioningly at Jennifer, and they stood, hesitantly.

Jennifer asked, "I guess we need a variable to hold the number, and a routine to convert from binary to hexadecimal?"

I thought carefully how hard I wanted to push them, and actually stopped just long enough to pray for help, before responding with, "I wonder how much time we'll have to do conversions during the interrupt routines."

"Not much?" Bob asked.

Doctor Brown spoke up. "Before worrying about that, let's see what you would do."

I decided I agreed with Doctor Brown. "Go with what you have in mind and see how it works. I need to go deliver newspapers pretty soon."

They took over, and I sat down next to Julia.

She took my hand under the lab table and whispered, "This is hard!"

"You're not the only one who thinks so," I whispered back.

"Are we going to need to do decimal numbers?" Jennifer asked from the chalkboard.

"Somebody might, but, for now, let's just do hexadecimal," I suggested

Bob and Jennifer took separate panes of the chalkboard and both started writing:
    ORG $40
WAITCT RMB 1 ; IDLE COUNTER
CMDOUT RMB 1 ; CMD to DSP
BYTOUT RMB 1 ; BYTE to DISP
ADROUT RMB 2 ; ADR TO DISP
*
    ORG $80
* HI BIT DP
* CLOCKWISE FROM TOP
* LO BIT MIDDLE SEG
SEGTBL
    FCB $7E ; 0 0111 1110
    FCB $30 ; 1 0011 0000
    FCB $6D ; 2 0110 1101
    FCB $79 ; 3 0111 1001
    FCB $33 ; 4 0011 0011
    FCB $5B ; 5 0101 1011
    FCB $5F ; 6 0101 1111
    FCB $70 ; 7 0111 0000
    FCB $7F ; 8 0111 1111
    FCB $7B ; 9 0111 1011
    FCB $77 ; A 0111 0111
    FCB $1F ; b 0001 1111
    FCB $3D ; d 0011 1101
    FCB $0D ; c 0000 1101
    FCB $4F ; E 0100 1111
    FCB $47 ; F 0100 0111
*
*
BITTBL
    FCB 1
    FCB 2
    FCB 4
    FCB 8
    FCB $10
    FCB $20
    FCB $40
    FCB $80
*
DSPCMD
    LDA CMDOUT
GTXNIB
    ANDA  #$0F
    TAX
    LDA SEGTBL,X
    RTS
*
DSPBYT
* HI NIB
    LDA BYTOUT
    LSRA
    LSRA
    LSRA
    LSRA
    BSR GTXNIB
    STA CATHOD
    LDX #5
    LDA BITTBL,X
    STA ANODE
* LO NIB
    LDA BYTOUT
    BSR GTXNIB
    BSR WAIT
    STA CATHOD
    LDX #4
    LDA BITTBL,X
    STA ANODE
    BSR WAIT
    RTS
*
DSPADR
*WAIT
    CLR WAITCT
WAIT0
    INC WAITCT
    BNE WAIT0
    RTS
*
INIT
* INIT PORTS
START
    LDA #$0C
    STA CMDOUT
*    BSR DSPCMD
    LDA #$5A
    STA BYTOUT
    BSR DSPBYT
    LDA #$10
    STA ADROUT
    LDA #$00
    STA ADROUT+1
*     BSR DSPADR
    BRA START
*
    ORG $1FFE
    FDB INIT
    END
(Yes, I'm fudging a little, not showing the initialization code.)

When they got to this point, Bob and Jennifer both put their chalk down and turned around, and Bob said, "Filling in the two undefined display routines feels awkward, and it's going to be a lot of modifying code as we copy, which is an easy place to make mistakes."

Doctor Brown spoke up again. "Let's go ahead and walk us through that and test it, and see if we get any good ideas while we're typing and testing."

Jennifer pointed out, "Our segments are wired differently from Joe's and Julia's."

I commented, "I think your wiring makes it a bit easier to visualize the connection between bits and display segments than the wiring I came up with for Julia."

Julia snickered and poked me in the ribs.

"Theirs does follow a more common pattern," Mike pointed out. "Mine uses the same as theirs."

Tanya asked, "Is WAIT a legal label?"

"Labels and op-code mnemonics are in a different symbol space in the assembler, so it's okay," I explained. "Might confuse humans, though."

"Maybe we should use WAITLP like you do," Bob continued. "Other than the wiring differences, we're just following the same program flow pattern you've been following. All we've added is splitting up the byte into four-bit halves, and shifting things into place, and masking the high bits off so the array reference into the table stays in the table."

Jennifer added, "The LSR instruction does a logical shift right, meaning it's dividing by two but ignoring the sign. It fills the top bit with a zero. The AND instruction masks off the top byte, for when you do the lookup without shifting first."

"I'm doing something completely different than that," Mike asserted.

"When Bob and Jennifer have tested theirs, how about you taking a turn, Mike?" I suggested.

He seemed a little surprised that I suggested it, but agreed.

And I excused myself to go deliver newspapers. Before I left, I mumbled something to Julia about hoping Mike had jumped ahead to just storing the segments in a display buffer, but she just shrugged her shoulders.

"Sorry, you've lost me again. Tell me what you mean when you get back."

By the time I got back, Mike was describing his first step.

Julia gave me an update in a low voice. "Bob and Jennifer got theirs working, but we all helped. Torrence noticed that their bit table was inverted before they burned their first program in, and the fix's on the chalkboard."

The corrected bit table looked like this:
BITTBL
    FCB $FE
    FCB $FD
    FCB $FB
    FCB $F7
    FCB $EF
    FCB $DF
    FCB $BF
    FCB $7F
"They had a typing mistake bug, too, and Doctor Brown showed us how to play computer and do a group walk-through to find it."

"Valuable experience."

"Helped me a lot."

"Let's see what Mike's got."

Mike was describing how he planned to test his understanding of the built-in hardware timer by using it to interrupt the CPU so it could make the segments flash between 1 and E at a fairly precise one second rate. (Again, I'm fudging a little, not actually giving you his initialization code. Init code is easy to get wrong if you don't test, and I can't test. It's also fairly straightforward in cases such as this, if you can get the hardware and are inclined to try it yourself.)
    ORG $40
LONGP RMB 1
    ORG $100
INIT
* SET UP PORTS
* SET TIMER PRESCALE TO 64
* SET TIMER COUNT TO 125
    LDA #125
    STA LONGP
    LDA #$FE
    STA ANODE
    LDA #30 ; 1
    STA CATHOD
    WAIT
TIMINT
    BCLR TIMCR7 ; INT FLAG
    DEC LONGP
    BNE TIMDUN
    LDA #125
    STA LONGP
    LDA CATHOD
    XORA #$FF ; 1 INVERTS TO E
    STA CATHOD
TIMDUN
    RTI
*
    ORG $1FF6
    FDB TIMINT; CMOS MODE TIMER INT
    FDB TIMINT ; ORDINARY TIMER INT
    FDB INIT ; INTERRUPT
    FDB INIT ; SWI
    FDB INIT ; $1FFF RESET
    END
"Using the timer prescaler value of 64 and the timer count of 125, then counting a hundred twenty-five interrupts, we should get a count of 125 times 125 times 64, which is a million. So if the CPU clock is exactly one meghertz, this should be exactly a one second flash rate.

"WAIT clears the CPU's interrupt mask before it puts the CPU in a WAIT state, but lets the timer keep running.

"The exclusive-or with hex FF instruction toggles all the bits in the accumulator, which should show E and the decimal point. And we can see if the BCLR bit clear instruction works and clears the timer interrupt flag."

After Theresa, another of the more quiet students, typed the code in and burned it, Mike's test worked as advertised, and Mike proceeded with his next step.

"What I'm going to do is have a buffer for the digits to display. I'll just have the timer generate a one millisecond interval interrupt, and it will sequence through displaying each digit for a millisecond. I'm going to steal Bob and Jennifer's code for the bit table and the segment table, if they don't mind."

"No problemo."

And he proceeded to show his code:

    ORG $40
CURDIG RMB 1 ; 1-7
DIGBUF RMB 7 ; 7 DISPLAYS
*
ORG $100
* BIT AND SEGMENT TABLES
TIMINT
    BCLR TIMCR7
    LDA CURDIG
    ANDA #07 ; SAFE MASKING
    STA CURDIG
    TAX
    LDA BITTBL,X
    STA ANODE
    LDX CURDIG
    LDA DIGBUF,X
    ANDA #$0F ; SAFE MASKING
    TAX
    LDA SEGTBL,X
    STA CATHOD
    RTI
*
START
    LDA #5
    STA DIGBUF
    LDA #3
    STA DIGBUF+1
    LDA #7
    STA DIGBUF+2
    LDA #7
    STA DIGBUF+3
    LDA #3
    STA DIGBUF+4
    LDA #8
    STA DIGBUF+5
    LDA #0
    STA DIGBUF+6
    WAIT
Burning the code in produced close to the desired results, but not quite, and we proceeded, as a group, to debug it, and shortly had it working.

It was getting close to dinner time, so I asked everyone, "Should I offer some wrap-up comments about interrupt routines now, or should we go home in a euphoria?"

Mike looked at me in resignation. "Hit me with it."

I laughed and looked at Doctor Brown, and he said, "Just keep it short."

So I turned to the students. "We've done some really good work today, keeping the steps small and working together to fix bugs. Doctor Brown will tell us again why bugs are good tomorrow, I think. A couple or three things to think about tonight -- Is it better to clear the timer interrupt flag at the front of the interrupt routine or the end? What could we do with Mike's code to keep the digits available to look at, but make the interrupt routine itself shorter? And how do we fit the keyboard code into the framework Mike has given us?"

I paused, deliberately, and then added, "By the way, I couldn't have paid Mike, Bob, or Jennifer to give us better code to work with."

*****

Julia leaned against my shoulder across the transmission well, looking out the window at the twilit sky.

"Either you aren't the jealous kind or you have supreme confidence about my feelings for you."

"I trust you to figure out what you want." I lifted my hand from the gearshift and gave her a quick hug.

"Supremely confident."

I chuckled. "And if I disagree, I'm going to be in a world of hurt."

She turned and bit my shoulder. Gently.

*****

After dinner and home evening, we sang my recital song in duet, English first, then Julia following along with my pronunciation as I sang in Japanese for a verse. I wrote out the Romanization, and we sang the Japanese together. (I've mentioned Latinization before. In Japanese, it's called ローマ字 -- Rōmaji -- or Romanization.) Then we sat down and worked on homework. After homework, Julia looking over my shoulder while I worked through the TMS 9940 documentation.

"I'm not seeing it."

"What?

"The description of the instruction to call a subroutine. I found the return instruction, but not the call, and I want to get a look at it."

Julia gave me a blank look.

"It's actually a full context switch on this processor, generating a linked list of contexts instead of a straight stack."

 She raised her hands with a smile that said, "I have no idea what you are talking about."

I grinned back. "Just pretend like your listening to something that makes sense."

"Hah."

"I'm going to pretend I'm explaining it to you, but I'm explaining it to myself."

"Uh, huh." She snickered.

"The TMS 9900 has a really unusual register scheme. All the computational registers are actually in memory, pointed to by the working set register."

"Last week, I would have been lost when you said scheme and register."

"What's a register?"

"Registers are where the poor little thing does all those calculations, and RAM is where she stores her results after working so hard."

"Very good. The 9900 uses RAM for registers. And TI calls the RAM it uses for registers the context, or working set. And it can keep a link to the previous working set in a memory cell of the current context."

"I can pretend I might understand that someday."

We both laughed. "Thank you. Now you have to know where your registers are, so the 9900 has one real register that points to the working set. It's called WP."

"Working set pointer?"

"Careful. You might actually understand this."

"Hah."

"You also have to know where the instructions are, so the 9900 has a register for that. It's called IP."

"Instruction pointer."

"Nice. Anyway, when you call a new procedure or routine, you usually want to know how to get back to where you were. That's what the link to the previous context working set is."

"I could see that. Someday."

"So the 9900's call instruction holds onto the old IP and WP, loads a new WP to point to a new working set, and stores the old ones in the top of the new working set."

Julia frowned. "You know that almost makes sense."

"Almost. I don't think it's ideal. I haven't mentioned the status register. I think it's the status register. But it saves that, too."

"Now I'm lost again."

"That's okay. The status register is where it remembers such things as whether the last operation resulted in zero or a negative number. I want to see the instruction that sets up the new context frame, so I'm looking for the call instruction, and I can't find it. I can find the return, but not the call. It's called BLWP, for branch and link WP."

I thumbed through the datasheet pages again, with Julia looking over my shoulder again.

"These are jumps?" She said.

"Yeah. Conditional jumps. It's not there."

I thumbed back and forth a bit more.

"Single operand instructions. How many operands does this branch and link, uhm, WP  instruction have?"

"That's actually what I want to find out."

"B for branch."

"Yeah."

"BL."

"Branch and link, but without WP. It's a quick call."

"BLWP," we said in unison.

"Op code 17."

"Where? I don't see any seventeen anywhere near BLWP."

"Binary." I pointed to it. "One zero zero zero one."

"Ah. Yeah." She shook her head.

Shortly I was satisfied for the night with what I had learned about the 9940, so I dug out the Forth implementation package.

"You're finally going to look at that other package?" Julia yawned.

"Been putting it off too long." I opened it up and scanned through it.

Julia fell asleep on my shoulder while I tried to make sense of it, and then I drifted off, as well. Giselle woke us up about 10:30, and I drove Julia home.

"So, what if I decide to reward you with a kiss?"

We had stopped on her front porch to talk.

"Who am I to turn down a reward?"

It was a nice, sweet reward, giving and getting, but not too much.


[Second version backed up at https://joel-rees-economics.blogspot.com/2020/06/bk01-33209-straits-status-display.html.
First version backed up at https://joel-rees-economics.blogspot.com/2020/06/bk-33209-straits-status-display.html.]


3809/2801: Practice Makes Practice

2801 Practice Makes Practice 6502 Indexed Addressing,  Including Memory Indirect ...