Intel sponsors gamedev.net search:
Any Colour You LikeBy benryves      
I enjoy dabbling with low-level programming, but have never actually built a computer to run these programs. I think it's time to correct that, and as the BBC BASIC project has required me to develop an almost complete Z80 OS (the only thing that's left for the TI-OS to do is manage files) I thought a Z80 computer would be a good start.

The planned specs are (as a starting point):
  • 10 MHz Z80180 CPU;
  • 64KB RAM (2 32K×8 SRAM chips);
  • 128KB Flash ROM;
  • Graphical LCD;
  • Simple joypad input;
  • Keyboard input (AT using either software AT routines or dedicated microcontroller).
The first spanner in the works is the Z80180, as I didn't read the datasheet closely enough and it's in a DIP 64 package with 0.07" pin spacing instead of the standard 0.1" pin spacing. I'll need to find some way of constructing an adapter so I can use it with my breadboards and stripboard.

In the meantime, I've concentrated on the graphical LCD. I picked a 128×64 backlit graphical LCD for the princely sum of £16. It's very easy to control - you hook up it up to a 8-bit data bus to transfer image data and instructions and a handful of control pins to indicate what you're doing on that bus (reading or writing, whether you're sending an instruction or some image data, that sort of thing) and that's it - the only supporting circuitry it requires is a 10K potentiometer to act as a contrast control and power for the display and backlight.


To experiment with the LCD, I'm using a PICAXE-28X1 microcontroller, programmed in BASIC. There isn't much space to store graphics, so I'm using a 32 character font (at eight bytes per character, that takes up all 256 bytes of free EEPROM space!)

; LCD data bus should be connected to port C.

Symbol LcdRegisterSelection = 0 ; D/I  :  4
Symbol LcdReadWrite         = 1 ; R/W  :  5
Symbol LcdStartEnable       = 2 ; E    :  6
Symbol LcdChipSelect1       = 3 ; CS1  : 15
Symbol LcdChipSelect2       = 4 ; CS2  : 16
Symbol LcdReset             = 5 ; /RST : 17

; Storage for console state variables.

Symbol ConsoleX             = B10
Symbol ConsoleY             = B11
Symbol ConsoleChar          = B12


	GoSub LcdInit                              ; Initialise LCD.
	B0 = %00111111 : GoSub LcdWriteInstruction ; Switch LCD on.

	GoSub LcdClear ; Clear LCD
	
	; Write the obligatory message to the LCD.
	
	ConsoleX = 0 : ConsoleY = 0

	ConsoleChar = $08 : GoSub LcdPutChar ; H
	ConsoleChar = $05 : GoSub LcdPutChar ; E
	ConsoleChar = $0C : GoSub LcdPutChar ; L
	ConsoleChar = $0C : GoSub LcdPutChar ; L
	ConsoleChar = $0F : GoSub LcdPutChar ; O
	ConsoleChar = $1D : GoSub LcdPutChar ; ,
	ConsoleChar = $00 : GoSub LcdPutChar ;  
	ConsoleChar = $17 : GoSub LcdPutChar ; W
	ConsoleChar = $0F : GoSub LcdPutChar ; O
	ConsoleChar = $12 : GoSub LcdPutChar ; R
	ConsoleChar = $0C : GoSub LcdPutChar ; L
	ConsoleChar = $04 : GoSub LcdPutChar ; D
	ConsoleChar = $1B : GoSub LcdPutChar ; !
	
	Pause 2000
	
	B2 = 0	
MainLoop:
	B2 = B2 - 1
	B0 = B2
	GoSub LcdGotoZ
	Pause 30
	GoTo MainLoop

LcdInit:
	DirsC = $00               ; Set data bus to input.
	High LcdStartEnable       ; We're not writing anything.
	High LcdChipSelect1
	High LcdChipSelect2
	Low LcdReset
	Pause 500
	High LcdReset
	Pause 500
	Return

LcdWriteInstruction:
	Low LcdReadWrite
	DirsC = $FF               ; Data bus = output.
	PinsC = B0                ; Set data bus state.
	Low LcdRegisterSelection  ; Instruction, not data.
	Low LcdStartEnable
	High LcdStartEnable
	DirsC = $00               ; Leave data bus floating.
	Return

LcdWriteData:
	Low LcdReadWrite
	DirsC = $FF               ; Data bus = output.
	PinsC = B0                ; Set data bus state.
	High LcdRegisterSelection ; Data, not instruction.	
	Low LcdStartEnable
	High LcdStartEnable
	DirsC = $00               ; Leave data bus floating.
	Return

LcdGotoX:
	B0 = B0 And 7
	B0 = B0 + %10111000
	GoTo LcdWriteInstruction
	
LcdGotoY:
	B0 = B0 And 63
	B0 = B0 + %01000000
	GoTo LcdWriteInstruction

LcdGotoZ:
	B0 = B0 And 63
	B0 = B0 + %11000000
	GoTo LcdWriteInstruction

LcdClear:
	For B2 = 0 To 7
		B0 = B2
		GoSub LcdGotoX
		B0 = 0
		GoSub LcdGotoY
		B0 = 0
		For B3 = 0 To 63
			GoSub LcdWriteData
		Next
	Next B2
	Return

LcdPutMap:
	B1 = B0 * 8
	For B2 = 0 To 7
		Read B1, B0
		GoSub LcdWriteData
		B1 = B1 + 1
	Next B2
	Return

LcdPutChar:
	B0 = ConsoleY
	GoSub LcdGotoX
	B0 = ConsoleX * 8
	If B0 < 64 Then
		Low LcdChipSelect2
	Else
		Low LcdChipSelect1
		B0 = B0 - 64
	EndIf
	GoSub LcdGotoY
	B0 = ConsoleChar
	GoSub LcdPutMap
	High LcdChipSelect1
	High LcdChipSelect2
	ConsoleX = ConsoleX + 1
	If ConsoleX = 16 Then
		ConsoleX = 0
		ConsoleY = ConsoleY + 1
		If ConsoleY = 8 Then
			ConsoleY = 0
		EndIf
	EndIf
	Return
	
; Font
EEPROM $00,($00,$00,$00,$00,$00,$00,$00,$00,$7E,$7F,$09,$09,$7F,$7E,$00,$00)
EEPROM $10,($7F,$7F,$49,$49,$7F,$36,$00,$00,$3E,$7F,$41,$41,$63,$22,$00,$00)
EEPROM $20,($7F,$7F,$41,$63,$3E,$1C,$00,$00,$7F,$7F,$49,$49,$49,$41,$00,$00)
EEPROM $30,($7F,$7F,$09,$09,$09,$01,$00,$00,$3E,$7F,$41,$49,$7B,$3A,$00,$00)
EEPROM $40,($7F,$7F,$08,$08,$7F,$7F,$00,$00,$41,$41,$7F,$7F,$41,$41,$00,$00)
EEPROM $50,($20,$61,$41,$7F,$3F,$01,$00,$00,$7F,$7F,$1C,$36,$63,$41,$00,$00)
EEPROM $60,($7F,$7F,$40,$40,$40,$40,$00,$00,$7F,$7F,$06,$1C,$06,$7F,$7F,$00)
EEPROM $70,($7F,$7F,$0C,$18,$7F,$7F,$00,$00,$3E,$7F,$41,$41,$7F,$3E,$00,$00)
EEPROM $80,($7F,$7F,$09,$09,$0F,$06,$00,$00,$3E,$7F,$41,$31,$6F,$5E,$00,$00)
EEPROM $90,($7F,$7F,$09,$19,$7F,$66,$00,$00,$26,$6F,$49,$49,$7B,$32,$00,$00)
EEPROM $A0,($01,$01,$7F,$7F,$01,$01,$00,$00,$3F,$7F,$40,$40,$7F,$3F,$00,$00)
EEPROM $B0,($1F,$3F,$60,$60,$3F,$1F,$00,$00,$7F,$7F,$30,$1C,$30,$7F,$7F,$00)
EEPROM $C0,($63,$77,$1C,$1C,$77,$63,$00,$00,$07,$0F,$78,$78,$0F,$07,$00,$00)
EEPROM $D0,($61,$71,$59,$4D,$47,$43,$00,$00,$00,$00,$5F,$5F,$00,$00,$00,$00)
EEPROM $E0,($02,$03,$59,$5D,$07,$02,$00,$00,$00,$80,$E0,$60,$00,$00,$00,$00)
EEPROM $F0,($00,$00,$60,$60,$00,$00,$00,$00,$07,$07,$00,$07,$07,$00,$00,$00)

The code isn't very robust - it doesn't check the state of the LCD's busy flag as I'm assuming that a 4MHz PIC running an interpreted BASIC is too slow to manage to write another byte to the LCD driver before it has finished processing the last one.

The font was generated from the following image (it's the BBC Micro font):


It's rotated through 90° as, unlike the LCD driver in the TI-83+, each byte written outputs 8 pixels vertically, with the least significant at the top. (On the TI-83+, each byte written outputs 8 pixels horizontally, with the most significant bit on the left). More interestingly, this graphical LCD is made up of two 64×64 regions next to eachother, and by controlling two chip select pins you can control whether each byte written updates the left side, the right side, neither or both. I'm entirely sure how I could use this, though, other than not-very-exciting tricks like clearing the LCD extra-fast.


924KB WMV

Finally, here's a video of the LCD test in action. It's not very speedy, but will hopefully pick up some speed once I figure out how I'm going to use that Z80180 CPU.

  User Rating: 1970   |  Rate This User     Send Private MessageView ProfileView JournalReport this Post to a Moderator 


Post Reply 

All times are ET (US)

 
S
M
T
W
T
F
S
1
2
3
4
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

OPTIONS
Track this Journal

 RSS 

ARCHIVES
September, 2010
August, 2010
July, 2010
June, 2010
April, 2010
March, 2010
February, 2010
January, 2010
December, 2009
November, 2009
October, 2009
August, 2009
June, 2009
May, 2009
March, 2009
February, 2009
January, 2009
December, 2008
November, 2008
October, 2008
September, 2008
August, 2008
July, 2008
June, 2008
May, 2008
April, 2008
March, 2008
February, 2008
November, 2007
October, 2007
September, 2007
August, 2007
July, 2007
May, 2007
April, 2007
February, 2007
January, 2007
December, 2006
November, 2006
October, 2006
September, 2006
August, 2006
July, 2006
June, 2006
May, 2006
April, 2006
March, 2006
February, 2006
January, 2006
December, 2005
November, 2005
October, 2005
September, 2005
August, 2005
April, 2005
February, 2005
January, 2005