Working with screens and printing texts
In my first article, I did a little introduction about the reasons behind my decision to learn assembly for the MSX, but the most important was the first program I analyzed from MSXPen’s Hello World. It doesn’t seem much but there are a few concepts presented that are very important to notice so I’d like to return on that, such as:
- Defining constants for BIOS routines, like
- The org statements which defines the memory position where the program will be allocated
- The Z80
HLregisters, being capable to respectively address 8 and 16 bits data
- Commands such as
DB(Define Byte) statement
- And a simple loop example
I’m going to avoid being too technical about the commands, statements, and parameters but at the same time, I will always add comments on each line of the code even for the most common actions because I believe that reading the code and understanding the actions through the explanations presented at the comments can be more engaging than listing all commands and trying to explain what each one does.
The Hello World program, extended.
After learning how to read the Hello World program I decide to change it and print the message on both Screen 0 and Screen 1, which the MSX Red Book describes as 40×24 and 32×24 text modes due to the number of columns and rows reach mode can present.
There is a very interesting detail there about the TMS9918 video display processor used by the first MSX generation: the resolution used by the processor is 256 pixels per line and 192 lines of pixels in any screen mode, but since Screen0/40×24 mode uses 6 pixels wide for 8 pixels tall characters it can only use 240 pixels per line (40 x 6 = 240 pixels). On the other hand, Screen1/32×34 text mode characters are 8×8 in size, therefore it uses the full 256 pixels line resolution to show 32 characters 8 pixels wide. Screen 2 / Graphics Mode is the most used one and allows to address each of the 256×192 pixels in blocks of 8×8 patterns, but can only apply two colors per block line, and finally Screen 3 / Multi-Color mode allows to color each “pixel”, but this pixel size is actually a block correspondent of 4×4 regular pixels.
But let’s not extend too long on these technicalities and go back to the new Hello World program:
; bios call to print a character on screen CHPUT: equ 0x00a2 ; BIOS routine that sends to the screen the contents pointed by the A register CHGMOD: equ 0x005f ; BIOS routine that changes the screen mode to the value defined by A CHGET: equ 0x009F ; BIOS routine that waits for a key to be pressed ERAFNK: equ 0x00CC ; BIOS routine that sets the function keys as hidden DSPFNK: equ 0x00CF ; BIOS routine that sets the function keys as shown FNKSB: equ 0x00C9 ; BIOS routine that changes the function keys between hidden and shown org 0xD000 ; origin memore address start: call ERAFNK ; calls the routine that hides the function keys call FNKSB ; calls the routine that switches the function key mode ld a,0 ; loads the value 0 into A to be used by the CHGMOD call call CHGMOD ; calls the routine to change the screen mode ld hl, message1 ; Loads into HL the initial position of the message1 variable call mainLoop ; calls mainLoop to print the message stored at message1 call CHGET ; waits for a key to be pressed ld a,1 ; loads the value 1 into A to be used by the CHMOD call call CHGMOD ; calls the routine to change the screen mode ld hl,message2 ; Loads into HL the initial position of the message2 variable call mainLoop ; calls mainLoop to print the message stored at message1 call CHGET ; waits for a key to be pressed call DSPFNK ; calls the routine that shows the function keys call FNKSB ; calls the routine that switches the function key mode mainLoop: ld a, (hl) ; loads into A the content pointed by HL cp 0 ; compares A with 0, raising the Z flag if true ret z ; if Z flag was set by cp, returns to the position where the routine was called call CHPUT ; prints the content from A on the screen inc hl ; advances one position of HL (next character) jr mainLoop ; repeates the loop message1: db "Hello world in screen 0!",0 ; message to be printed in screen 0 message2: db "Hello world in screen 1!",0 ; message to be printed in screen 1 end start
We have now some new BIOS routines like
CHGET to wait for a key to be pressed so we can pause the program to see the first message printed, the trio
FNKSB which hides or shows the function keys at the bottom of the screen, and the
CHMOD which is called to change the screen mode defined by the value loaded at the
A register. All routines values and details can be found at the grauw.nl site with this format:
CHGMOD Address : #005F Function : Switches to given screen mode Input : A - Screen mode Registers: All
We can notice that when the
CHGMOD routine is called all registers are have their data changed, so it’s important to avoid loading values at other registers before calling this routine or remember to
PUSH the register to the stack then
POP it again after the call. I’m going to talk about this in the next articles.
Apart from the screen mode changes, there aren’t many differences from the original Hello World program, and I just duplicated the lines to execute the same actions in both screen modes. You can copy and paste the program at the MSXPen site, or just open this link to see the results.
Boring boring, let’s do something different?
In the next article, we will do something more interesting like changing the characters’ design and printing it on the screen at different positions. See you there!
In my first article, I did a little introduction about the reasons behind my decision to learn assembly for the MSX, but the most important was the first program I analyzed from MSXPen’s Hello World. It doesn’t seem much but there are a few concepts presented that are very important to notice so I’d like…