Cover

The Adam Technical Journal

Description of the Video Display Processor 	1
Controlling the screen directly 	2
Now to customize the character set 	4
Controlling screen and character colors 	6
First installment of Basic Utility Library 1.0 	9
Example programs to demonstrate the utilities 	10
Helpful Tid-Bits of information about the ADAM	13

Copyright 1985, serendipity Productions

Page - 1

BI MONTHLY NEWSLETTER

VOL 1 -NO. 1 2/85

CREATED FOR COLECO ADAM OWNERS

A TECHNICAL NEWSLETTER ON HOW TO OUT SMART "SMART BASIC"

SERENDIPITY PRODUCTIONS
P.O. BOX 07592
MILWAUKEE, WI 53207

INTRODUCTION

This  is the first of a series of newsletters that discusses  the 
capabilities of ADAM Smart Basic.  The first few newsletters will 
concentrate on the Video Display Processor. We will then continue 
into the Smart Basic interpreter and Operating system.

The Video Display Processor (VDP) is one of three microprocessors 
in the ADA.M. The main processor is the Z80 CPU (Central Process
ing  Unit).  The Operating System and Smart Basic are written  in 
the  Z80's  assembly  language.  The Z80 control the  Inputs  and 
Outputs  (1/0) that control the TI SN76489AN sound processor  and 
the  TI  TMS9918A video Display Processor.  For this  reason  the 
programs  that we will discuss will be partially written  in  the 
Z80 assembly language.


The  Video  Display  Processor controls all of the  video  screen 
displays. This includes:

1)	How the characters to be displayed are defined

2) 	The color of the foreground and background of  different 
        sets of characters

3)	The display or retrieval of a character an the screen

4)	The definition and display of sprites

5)	The ability to go into high resolution graphics.

In this newsletter, we will concentrate an displaying and retrie-
ving characters from the screen. We will also discuss how you can 
define your own character sets and change the screen and character
colors.

VDP MEMORY

The  ADAM computer has 80K (81920 bytes) of Random  Access 
Memory (RAM).	Only 64K of this memory is directly accessible by 
the  main Z80 CPU.   The remaining 16K is an indirect memory  and 
can only be accessed through the VDP.  This 16K of memory,  which 
we will call VDP memory,  contains a collection of tables used by 	
the  hardware which operates the display  screen.   For  example, 
there are two segments of 768 bytes of memory used for the Screen 
Image  Table.   The  Screen Image table holds the ASCII codes  of 
text presently being displayed on the screen.  Another example is 
the  Character Definition table.   This table uses 2048 bytes  of 
memory which describes what each displayable text character looks 
like.  When you want to display the letter "A" on the screen, the 
ASCII  code for "A" is placed in the first  table.  The  hardware 
sees that code,  looks it up in the character definition table to 
see what it looks like, then paints it on the screen.

Page -2

The VDP is accessed through two I/O PORTS.   (PORT 191,190).  The 
first  port  (191)  is used to tell the VDP what to do  with  the 
data.  Port 190 is used to send or receive the actual data. There 
are 4 basic operations that the VDP can perform.

1)	Write to VDP memory
2)	Reid from VDP memory
3)	Write to VDP write-only 	registers
4)	read the VDP status register

The first two operations are your only means of access to the 16K 
VDP memory. The third operation allows you to change the 8 inter-
nal  registers of the VDP processor.  The appropriate  values  in 
these  registers  will  allow you to define where  the  different 
tables will reside. They also give the capability of changing the 
mode of the display. These modes are:

1)	Hi-res (each point, or pixel, an the screen is definable)

2)	TEXT (gives you 40 columns of text displayed)

3)	Graphics (gives you 32 columns,  and is the mode the ADAM 
        is normally in)

4 )	Multi-Color ( each character appears as four color defin-
        able squares)

We  will  discuss these modes and how to obtain  them  in  future 
newsletters. 

As  mentioned earlier the main topics of this issue are Character 
definition, Color code definitions., screen color and reading and 
writing  to  the screen.  These issues will be discussed  in  the 
context of the 32 column by 24 row Graphics mode.

POKING AND PEEKING VDP MEMORY

in  order  to  tap the exceptional power of  this  Video  display 
Processor,  we must be able to modify VDP memory. Since the BASIC 
PEEK and POKE commands cannot reach VDP memory,  we will have  to 
use  two small assembly language programs.  Assembly listings (#2 
and  #3)  for  these  programs  are given  at  the  end  of  this 
newsletter.  They are for your information only since the  actual 
routine  is  built for you by the BASIC Utility program  (listing 
#1).  Both programs listed at the end of this newsletter use port 
#191 to set up the address to poke into and port #190 to send the 
value you want poked into VDP memory.

The POKEVM program first save the accumulator,  status flags  and 
register  pair BC on the stack.  The low address byte is sent to 
PORT  191 first.  The high byte must be offset by a value  of  64 
before  it is sent to PORT 191.  The offset indicates to the  VDP 
which of the 4 operations described above are to be performed.  A 
write to VDP memory requires an offset of 64, writing to a register
requires a 128 and a read from memory requires no offset. Reading 
the  status register is a slightly different operation and is not 
very useful until we get into some rather sophisticated graphics.  
The offset is added on by line 52000 of the BASIC  program.   The 
series  of  six "EX (SP),HL" instructions are used as a delay  to 	
give the processor time to set the address.   This in instruction 
was chosen because it is one of the most time consuming, which is 
the effect	we're after.   The value you wish to transfer  to 
VDP memory is then sent through Port 190.   	After each write 
to VDP memory the VDP's internal address buffer increments itself 
automatically.
Therefore,  if  the count-down register (BC) has not reached zero 
the program will loop through without having to tell the VDP what 
address  to write to every time.   After the count down loop  has 
completed,  the accumulator,  status and BC registers are  POPed 
back and the program returns to the calling BASIC program.

The BASIC subroutine at line 52000 does nothing more than take the

Page - 3

destination  address  and character count,  then decomposes  them 
into  2-byte values.  It then adds 64 onto the high byte  of  the 
address  and  pokes  the  four bytes  into  the  POKEVM  assembly 
language routine.  lastly,  the assembly subroutine is CALLed and 
the BASIC subroutine RETURNS to the main program.

The  PEEK  subroutine is similar to the POKE with  the  following 
exceptions.  The count-down loop is no longer needed since we are 
only going to read one memory location.  The high byte of the VDP 
address no longer needs the offset (actually,  the offset is zero 
as discussed above).  The OUT 191 is replaced by an IN 191. After 
the  IN  instruction,  the accumulator is transferred into a  CPU 
address. Since only one address is to be read the PUSH BC and POP 
BC instructions are also not present in the-PEEKV program.

The  PEEK BASIC subroutine decomposes the address into two  bytes 
the same way as the POKE subroutine.  These two bytes are  passed 
down  into  the PEEK VDP assembly routine.  After the routine  is 
executed,  the contents of the VDP memory location will have been 
copied into the CPU memory 10 bytes beyond the PEEK VDP  assembly 
routine.  This CPU address is then peeked by the BASIC subroutine 
and stored in a variable.

WHERE TO PUT THE ASSEMBLY LANGUAGE

The  assembly  language  is loaded into memory  using  subroutine 
starting at line #51000.   This routine PEEKs at locations  16102 
and 16101.  These locations contain the high and low bytes of the 
address  where  the  largest line number is stored  in  the  line 
number  table.  Two locations below this address is the high  and 
low  bytes  of the address where the tokenized code of  the  last 
line  is stored.  This address with the offset of 10 is where  we 
are  going to store the assembly language.  Therefore to create a 
buffer in your basic program to store your assembly language  you 
need a non-executable instruction, Such an instruction is the REM 
with as many characters in it as needed for the buffer.  This REM 
statement  must  be located with the largest line number in  your 
program- Storing the assembly routine inside a REM statement of a 
basic  program gains several advantages.  one advantage  is  that 
assembly  language becomes an integral part of your  program.  it 
can  be  saved and loaded onto a data pack right along with  your 
BASIC  program.  Other  reasons will become  apparent  in  future 
issues.  one of these topics will include a fast loader and saver 
that  will  decrease the time of saving and loading to  about  an 
eighth  of the normal time.  This topic will be in the issue that 
covers the topic of how the BASIC interpreter tokenizes code.

SCREEN DEFINITION TABLES

This  contains the ASCII codes of what is presently appearing  on 
the screen.  Therefore,  if you put,  for example, a 65 into this 
table you see the letter "All appear on the screen.

There are actually two screen Image Tables,  The operating system 
alternates these tables in order to cause a cursor  to blink.  If 
the  ASCII  65 was only Put into one of these tables  the  screen 
display would alternate between what was originally there and the 
"A".  To  make  the screen appear stable you must poke  the  same 
ASCII value into both tables.

Smart  Basic has defined these tables in the VDP memory to  start 
at locations 2048 and 6144.  Each table contains 768 bytes.  This 
corresponds  to 24 rows times 32 columns.  The  memory  locations 
that correspond to each row are as follows.

Page - 4

	ROW	TABLE(l)	TABLE(2)
	1	2048-2079	6144-61715
	2	2080-2111	6176-6207
	3	2112-2143	6208-6239
	4	2144-2175	6240-6271
	5	2176-2207	6272-6303
	6	2208-2239	6204-6335
	7	2240-2271	6336-6367
	a	2272-2303	6368-6399
	9	2304-2335	6400-6431
	10	2336-2367	6432-6463
	11	2368-2399	6464-6495
	12	2400-2431	6496-6527
	13	2432-2463	6528-6559
	14	2464-2495	6560-6591
	15	2496-2527	6592-6623
	16	2528-2559	6624-6655
	17	2560-2591	6656-6687
	18	2592-2623	6688-6719
	19	2624-2655	6720-6751
	20	2656-2687	6752-6783
	21	2688-2719	6784-6815
	22	2720-2751	6816-6847
	23	2752-2783	6848-6879
	24	2784-2815	6880-6911

The  basic  "WRITE-TO SCREEN" subroutine starting at  line  53000 
calculates the addresses for you,  given the row and column,  and 
then executes the POKEMV routine.

The  "READ-FROM-SCREEN" subroutine starting at line 56000  calcu-
lates  an  address  only for Table (2) given the row  and  column 
locations.   	The  reason for PEEKing from only one  table  is 
what we had mentioned earlier.   The two tables are duplicates of 
each other except for what is under the cursor.

CHARACTER DEFINITION TABLE

As  we mentioned above in the VDP MEMORY section,  the  character 
definition  table  describes the appearance of  each  displayable 
character.   This  table  consists of an 8 byte binary  "picture" 
corresponding  to each of the ASCII  codes.  The format  of  that 
picture  will be described below and we will actually change  the 
appearance of the character of your choice.

The character definition table starts in VDP memory at location 0 
and  goes  to location 2048 allowing a maximum of  256  character 
definitions. To calculate which 8 bytes control the definition of 
a  particular ASCII code you would multiply the ASCII code by  8. 
This  will  give  you  the beginning memory locations  of  the  8 
consecutive memory locations that define the character.

A  character is made up of an eight by eight grid.  Each  row  of 
this grid,  starting from the top,  must be converted into a byte 
value  to be poked into the a consecutive memory locations of the 
character you are redefining.

we  will first explain how to convert the row into a  byte  value 
which ranges from a value of 0 to 255.  Eight of these bytes that 
represent  each  raw could then be transferred directly into  the 
table.  Secondly, we will look at a shorthand way of representing 
the  8  bytes.   This  shorthand  method is  used  in  the  BASIC 
subroutine which will be discussed later.

If  you  look  at Fig.  1,  you will see a grid of 8  rows  by  8 
columns.  Each raw must be converted into a single byte. You will 
notice the columns are numbered left to right 128, 64, 32, 16, 8, 
4, 2, 1. To obtain the byte value of the row, first check off the 
squares  in  the 8x8 grid that will make the grid appear  as  the 
object you wish.  For each row,  add up the values that appear at 
the top of the columns for the squares that are checked off. When 
you  have  completed  all  the rows,  you  will  have  the  bytes 
necessary to poke into the table to redefine the character.

As  an example,  we will calculate the memory locations  for  the 
character "A" and determine the bytes to be poked into 
these locations to make it look like a jet.

Page - 5

To  calculate  the  memory location simply multiply 8  times  the 
ASCII code "A".   this is:  8x65=520.  Therefore,  locations  520 
through 527 hold the definition for the letter "A".

The  values  to he POKED into these locations are calculated  and 
appear at the bottom of the grid in fig 2.

(GRAPHIC NOT INCLUDED)

ROW 1: 8 = 8
ROW 2: 16+8+1 = 25
ROW 3: 32+16+8+2+1 = 59
ROW 4: 128+64+32+16+8+4+2+1 = 255
ROW 5: 32+16+8+2+1 = 59
ROW 6: 16+8+1 = 25
ROW 7: 8 = 8
ROW 8: 0 = 0

Fig. 2

If you were to use the POKEVM subroutine that we discussed  earl-
ier to poke the calculated values into locations 520 through 527, 
all A's from that point on would appear on the screen as jets.

THE SHORTHAND METHOD

The  shorthand  method is used by the BASIC subroutine  discussed 
later  to pass a new character definition to the VDP by use of  a 
single string variable. This is desirable for two reasons. First, 
it  allows  you  to use one variable to  describe  the  character 
rather than 8, a considerable savings in a large program. Second, 
it  breaks up the character into twice as many pieces  making  it 
easier to modify later on.

The  method involves decomposing the 8x8 grid into a 16 character 
string.  This  is done by separating each row into two  4  column 
rows (see Fig.  3). The 4 columns for each raw are converted into 
a hexadecimal value.  Hexadecimal is a number system that is base 
16 and the digits in the set are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, 
B,  C,  D,  E and F. Figure 4 lists the hexadecimal value for its 
particular 4 column pattern.

(GRAPHIC NOT INCLUDED)

Page - 6

To illustrate how a 16 character string can represent a character 
Pattern,  we obtain the definition of the jet of Fig.  2.  If you 
look  at Fig.5 you will see that the 8x8 grid has been  separated 
into two grids of 4 columns by 16 rows. Each 4 column row is then 
compared  to Fig.  4 to obtain the corresponding pattern  number. 
The  pattern numbers are then combined into a single 16 character 
string.

(GRAPHIC NOT INCLUDED)

COLOR DEFINITION

The Color Definition Table contains the code which defines the 
foreground  and background colors of the 2 character  sets.  The 
table  starts at VDP memory location 8192 and contains 32  memory 
locations.   Each byte defines one subset of a  characters.  For 
example,  character  set #10 would contain the ASCII codes  72-79 
which are (H,I,J,K,L,M,N,O)  The following table gives the char-
acter  set # and VDP memory location that controls the colors  of 
the characters in that set.

TABLE 2

SET	VDP	ASCII
	LOCATION	CODES
1	8192	0- 7
	2	8193	8-15
	3	8194	16- 23
4	8195	24- 31
5	8196	32- 39
6	8197	40- 47
7	8198	48- 55
8	8199	56-63
 	9	8200	64- 71
	10	8101	72- 79
	11	8202	80- 87
	12	8203	88- 95
	13	8204	96-103
	14	8205	104-111
	15	8206	112-119
	16	8207	120-127
	17	8208	128-135
	is	8209	136-143
	19	8210	144-151
	20	8211	152-159
	21	8212	160-167
	22	8213	168-175
	23	8214	176-183
	24	8215	184-191
	25	8216	192-199
	26	8217	200-207
	27	8218	208-215
	28	8219	216-223
	29	8220	224-231
	30	8221	232-239
	31	8222	240-247
	32	8223	248-255

The  character  set number will be used in the  Basic  subroutine 
starting  at  line 55000 to identify which set you would like  to 
chance.  The  value you POKE into the Color Definition  Table  is 
listed in Table 3.

The  chosen foreground and background color must be combined into 
a  single  byte to be poked into the  appropriate  character  set 
memory  location.  This is accomplished by multiplying the  fore-
ground  color by 16 and adding the background color code onto it. 
The BASIC subroutine at line 55000 does this for you.  The back-
ground is normally  transparent.

Page - 7

for  all the character sets.  This allows the screen color to  be 
seen behind the characters.

	TABLE 3

				CODE
		COLOR	NUMBER
	Transparent	0
	Black		1
	Medium Green	2
	Light Green	3
	Dark Blue	4
	Light Blue	5
	Dark Red	6
	Cyan		7
	Medium Red	8
	Light Red	9
	Dark Yellow	10
	Light Yellow	11
	Dark Green	12
	Magenta	13
	Gray		14
	White		15

SCREEN 	COLOR

The screen color is the background color you would see behind the 
characters  that have been defined with a transparent  foreground 
or background color.   The color code number used is the same  as 
defined in Table 3.

Changing  the  screen  color involves changing the value  in  VDP 
register  #7.   We will discuss how to calculate the  value  that 
must be poked to change VDP registers in a future issue. However, 
we  have  included a BASIC subroutine starting at line  57000  to 
alter the Screen colors.

THE BASIC UTILITIES

As you can see, the utilities are a set of basic subroutines.  By 
simply  setting  some  reserved variables to the  parameters  you 
desire and doing a GOSUB to the particular subroutine,  you  will 
perform a graphics function.

The  idea  is  to include the utilities in a  BASIC  program  you 
create.  This can be done in one of two ways. you can either LOAD 
the utility file from tape and key in the program above it or you 
can  use  SMARTWRITER to append the utility file to  an  existing 
program.

Your  program  should not use any variables that start  with  the 
letter  "u"  other  than for  passing  utility  parameters.  Your 
program must reside above the utilities, that is, have lower line 
numbers  than the utilities.  The following section describes how 
to use each utility.

SET UP UTILITY (GOSUB 51000)

This subroutine sets up the assembly language needed for all  the 
other subroutines.  Therefore GOSUB 51000 only has to be executed 
once at the beginning of your program.  If you intend to list the 
entire program on the printer or transmit it aver a modem,  it is 
advisable  to  re-enter  the REM statement at line 65535  with  a 
string  of  at least 60 characters.  Since the  remark  statement 
contains  a  machine language program after  performing  a  GOSUB 
51000  and  not printable characters,  it may cause  problems  on 
certain  rare occasions.  If a data value poked into the  routine 
corresponds  to  a  screen or printer control byte,  it  will  be 
executed.  For  example a value of 16 corresponds to a  control-P 
which  causes  the  contents  of the screen to  be  sent  to  the 
printer.

Also, 	if  you  are repeatedly saving a program to  tape  (i.e. 
developing a new or large program) it is a good

Page - 8

idea to re-enter the line anyway since SMARTBASIC always  inserts 
an  extra  character  into  the beginning of  all  REM  and  DATA 
statements  when  writing it to tape.  Because of this  you  must 
GOSUB 51000 after every LOAD.

FORMAT:
10 GOSUB 51000

POKE VDP UTILITY (GOSUB 52000)

This  utility  will  let you poke a value  into  consecutive  VDP 
memory locations. The variables (ua,ub, and uc) are set by you to 
the starting address in VDP memory, the value to be poked and the 
number  of copies to be poked.  By doing a GOSUB 52000 the poking 
will be performed.

FORMAT:

10 ua=2048: ub=65: uc=5: GOSUB 52000

WRITING TO THE SCREEN (GOSUB 53000)

Placing  a  character or a series of the same  character  on  the 
screen is performed by this subroutine. The variable (ur) is used 
to  set  the  desired row.  Variable (ul) contains  the  starting 
column location on the screen.  Variable (ub) is used to hold the 
ASCII code to be displayed on the screen.  The last variable  you 
must  define  is  (uc) which contains the number  of  consecutive 
copies you will have displayed on the screen. Finally, performing 
a GOSUB 53000 will put the character on the screen.

FORMAT:

10 ur=1: ul=1: ub=66: uc=5: GOSUB 53000

CHARACTER DEFINITION UTILITY (GOSUB 54000)

This  subroutine will allow you	to change the appearance of  any 
character.  All that must be done is to set the variables 
(us)  to the 	ASCII code of the character you wish  to  change 
and (us$) to the 16 character string that defines the pattern, as 
discussed  in the shorthand method.   Lastly,  performing a GOSUB 
54000 will change the appearances of the character.

FORMAT:

10 us=65: us$="08l93BFF3Bl90800": GOSUB 54000

CHARACTER SET COLOR UTILITY (GOSUB 55000)