Wednesday, 28 May 2025

MSBASIC : Control LCD

 Intro

We have implemented MSBASIC on BEN2, which is a 6502 system closely following Ben Eater's design.  MSBASIC was originally developed by Microsoft for the 6502 in 1976 and was implemented on many early and famous computers, including Apple and Commodore.  The software source was released some years ago and is available on Github.  It can be compiled for a variety of different machines.  Ben Eater has forked his own version which runs on his 6502 and mine!

Ben (me too) has an LCD display display on his 6502 and the generic MSBASIC doesn't include commands to use an LCD display.  Ben and has provided a video tutorial describing how to control the LCD using POKE/PEEK commands and he adds new MSBASIC commands allowing the user to "print" to an LCD.

As usual it is an interesting, educational tutorial allowing me to add LCD display into my MSBASIC.

POKE/PEEK

MSBASIC includes the commands PEEK and POKE to view (read) and update (write) specific actual memory locations.  We control LCD hardware by writing values to VIA (Versatile Interface Adapter) ports which are wired up to the LCD.  PORTB pins PB4-PB7 are used for data.  PORTA pins PA5-PA7 are used for control signals.

Ben uses different connections from VIA to LCD so I needed to work out how it should work BEN2.

So far we have done this in assembly programs by writing to the VIA ports we use at addresses $6000-$6003 (hexadecimal).
Similarly we can use POKE in BASIC programs to  write directly to VIA ports.  BASIC uses decimal address so $6000 equates to 24576.  By putting the data in 24576 = $6000 (PORTB) and changing control bits in 24577 = $6001 (PORTA) the character CHAR$ is displayed on the LCD.


We implement three principle BASIC subroutines using POKE commands: LCDINIT (set  up display) LCDPRINT (char display), LCDCMD (control command, clear screen, set cursor etc)
This subroutine shows that we can easily print a string on the LCD.


Add MSBASIC Commands

It is encouraging to know that we can control the LCD from MSBASIC.  It would be preferable to add some commands to the MSBASIC language so that we can easily initialise / control / display LCD output.  In his video Ben describes his detective work to add three such commands LCDINIT, LCDCMD and LCDPRINT to MSBASIC.  It turns out to be quite simple to add new commands and cause them to execute assembly subroutines.  Our own assembly code is stored in LCD.s and added in to the MSBASIC build.

For example, the LCDINIT command executes the code at label LCDINIT: in lcd.s.  This sets up the ports we need to use and calls LCD4_init which is my existing assembly code to initialise LCD.

Part of the detective work was to determine how MSBASIC passes arguments to assembly subroutine.  Ben looked at the PRINT command code and found that a subroutine GETBYT takes a value from the command line and stores it in the X-register.
So we can have a BASIC command "LCDPRINT 65" and the value 65 is passed to our LCDPRINT assembly subroutine in X-reg.  We then tell the subroutine to print what is in X-reg and prints the corresponding character "A".

I was very pleased that I could mainly cut and paste my assembly routines into lcd.s, rebuild MSBASIC and then see the code working.

Printing Strings

The MSBASIC PRINT command allows you to print characters strings of numeric expressions and Ben uses a follow-up video tutorial to show how he decoded the way in which the code (written by Bill Gates et al) works.  


One really cool idea is to display some of the MSBASIC internal variables addresses on the terminal then drop out of Basic to WOZMON..  You can then list out those addresses in WOZMON to find what values they are set as.  Ben uses this to understand how zero page memory is used to store characters, variables, strings, numbers and expressions for 

Armed with this knowledge the LCDPRINT subroutine can now print expressions and strings.  Ben provides a copy of his source on github and to make it work I simply had to swap in my own LCD subroutines, developed previously.
It worked without any quirky complications.


Outro

In the two MSBASIC tutorial implementing LCDs Ben has done a grand job discovering how the original code works, with some clever detective work along the way.  The tutorials are rather different from his usual approach of carefully reviewing data sheets and devising assembly code but interesting all the same.
It is rewarding to get the LCD working in BASIC as you can actually see the computer producing something rather than looking at a terminal emulator as usual.  The knowledge gained from this approach could be applied to add other hardware related functions if I feel like it.









































No comments:

Post a Comment