Much Ado About Nothing

Sometimes, nothing is exactly what you need. A specific amount of nothing, to be precise.

Here is a delay library, written in assembly, for PIC microcontrollers running at 8MHZ. If you find it useful, please let me know. Share and enjoy!

8MHz delay library

Posted in Coding, Digital, PIC Microcontrollers | Leave a comment

It works! (again)

Bill (Dr. Rosen’s independent-study student) stopped by the lab today to work on his Z80 computer. After tracking down a few bugs, we got it working! I loaded the Fibonacci test program into it, and saw it execute the JMP 0x0003 command, verifying that it is correctly executing code.

Good job, Bill (and thanks for helping us test the design for the course)!

Posted in Digital, DrACo/Z80, Drexel, EET325 | Leave a comment

First peripheral

The first peripheral for the Z80 is working (although still somewhat alpha at this point): a two-line LCD text display. It’s mapped as I/O ports 0x00 and 0x01, with control commands being sent to 0x00 and data to 0x01.

It’s been tested with a “Hello, World!” program written in Z80 assembler. (The current version of the program is very inefficient; the ideal way to handle it would be to write the “Hello, World!” data into memory and then clock it out to the I/O port automatically (I believe the Z80 can do this in a single instruction, once the registers are set up.)

Here is the “Hello, World!” assembly code. The C register is loaded with 0x01, then the A register is loaded with the ASCII code for each character, which is output to the port.

In related news, I think I’ve found how to turn off all the peripherals on the PIC16F887. It’s a good replacement for the ‘877A — with an internal 8MHz clock, plus a complete 8-bit PORTA — but it does seem to power up with a lot of extraneous analog options turned on. The MPU for the text display is an ‘887.

Edit: Here is an updated version of the “Hello, World!” app — using a single OTIR (Output/Incrementing/Repeat) instruction to do the dirty work, once the registers are all updated. Apparently it works by not incrementing the program counter, so the same instruction is executed over and over until B counts down to zero. Whatever the mechanism, it works as advertised, and the program now takes up only 27 instead of 60 bytes of memory!

Posted in Coding, Digital, DrACo/Z80, Drexel, EET325 | 1 Comment

Putting the “Basic” back in BASIC

I found a cool Z80 simulator suite — with a lot of useful bells and whistles. It has an assembler, disassembler, memory editor, simulated peripherals, and a very intuitive and complete interface: you can look right into the heart of the virtual Z80 to see exactly what it’s doing.

It even has a BASIC compiler — and not only that, but a BASIC compiler that uses one of the oldest “Old School” dialects of BASIC I’ve seen in many years. (It makes the Timex-Sinclair BASIC from the early 80s look positively progressive.)

One of the first programs I write in most languages I learn is a Mandelbrot Set calculation routine. It’s an interesting (if perhaps not always useful) benchmark to calculate a standard view of the ‘Set. I use (-2.0,0.9)-(0.6,-0.9), rendered in 640×480 at 1000 iterations as a starting point.

Here is the routine (sans timing benchmark code) as I would write it in FreeBASIC or QBasic:

dim a,b,r,i,h,dx,dy as double
dim x,y,iter,maxiter as long
rmin=-2.0 : rmax=0.6 : imin=-0.9 : imax=0.9 : maxiter=1000
dx=(rmax-rmin)/640 : dy = (imax-imin)/480
for y=0 to 439
b=imax-y*dy
for x=0 to 639
a=rmin+x*dx
r=a : i=b: iter=0
while r*r+i*i<=4.0 and iter>maxiter
h=(r+i)*(r-i)+a
i=2*r*i+b
r=h
iter=iter+1
wend
next x
next y

Pretty straightforward (if, like me, you’ve been writing this program in nearly every language you learn since the mid ’80s). BASIC is like coding in algebra, which is why I like it.

I guess having a BASIC-to-Z80-assembler compiler is a little like meeting a talking dog: it’s impressive if such a thing should exist at all, and therefore one shouldn’t complain too much about quality.

Some things I learned:

  • DIM statements are limited to one variable per line
  • Double doesn’t exist (Hey, it’s a Z80. It’s impressive that single does!)
  • Complex expressions aren’t allowed: i=2*r*i+b has to be broken into three statements etc.
  • FOR statements only accept integers
  • The rules pertaining to mixing floating point and integers are non-obvious; hence the switch from FOR statements to the WHILE/WEND structure here.

Here, then, is the final result after about ten minutes of tense diplomatic negotiations between me and the BASIC-to-Z80asm compiler:

Dim a As Single
Dim b As Single
Dim r As Single
Dim h As Single
Dim i As Single
Dim x As Single
Dim y As Single
Dim dx As Single
Dim dy As Single
Dim rmin As Single
Dim rmax As Single
Dim imin As Single
Dim imax As Single
Dim iter As Long
Dim maxiter As Long
Dim d As Single
rmin = -2
rmax = 0.6
imin = 0 – 0.9
imax = 0.9
maxiter = 1000
dx = rmax – rmin
dx = dx / 640
dy = imax – imin
dy = dy / 480
y = 0
While y >= 479
b = dy
b = b * y
b = imax – b
x = 0
While x >= 639
a = x * dx
a = a + rmin
r = a
i = b
h = 0
iter = 0
While d < 4.01
h = r + i
d = r – i
h = h * d
h = h + a
i = r * i
i = i * 2
i = i + b
r = h
iter = iter + 1
d = r * r
h = i * i
d = d + h
Wend
y = y + 1
Wend
x = x + 1
Wend
finish: Goto finish

The end result after running this through the compiler? 1398 lines of assembly code(!) 2,362 bytes of machine code. (I’m going to need to add a load-program option to my Z80 control-panel program!)

I’m not knocking the good folks at Oshonsoft. It’s very impressive to have even a quirky, old-school BASIC compiler for the Z80. Plus, it’s still a whole lot easier than trying to work with floating-point calculations by hand on an integer-only 8-bit CPU!

Posted in Coding, DrACo/Z80, Drexel | 4 Comments