Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Output to the screen can be achieved by treating the screen as a device and using the file I/O system calls. However, there are four six calls which can be used to send output to what is called standard output, which although it may be redefined by the CLI, see 'Standard I/O and the CLI', is usually the screen device. The four calls are:

...

...

  • ,   write

...

  • character

...

  • to

...

  • standard

...

  • output
  • OS_Nln,   write newline to standard output (<CR><LF>), replace GN_Nln
  • OS_Sout,  write a string in local memory to standard output, replace GN_Sop
  • OS_Bout,  as OS_Sout, but from an extended address, replace GN_Soe
  • OS_Pout,  write an embedded string at (PC)
  • OS_Hout,  write a hexadecimal byte to standard output 

These calls are fully compatible with GN_Sop, GN_Soe, GN_Nln. They are deprecated and maintained for compatibility. They perform a significantly slower rendering.

These calls are fairly friendly as far as register corruption is concerned. OS_Out writes the character held in register A and forces Fc = 0 before returning with no other register or flag changes. GN_Nln changes no registers and returns Fc = 0 unless there is an error. GN_Sop and GN_Soe expect HL (or BHL) to point to a null-terminated string, and on exit HL (or BHL) will point to the null, with other registers remaining the same, unless there is an error. Errors can occur if the standard output device has been redirected to somewhere other than the screen. In the case of errors Fc = 1 and register A will contain an error code. If you are not doing any redirection yourself then these kind of error situations can be largely ignored, since if the user is doing bizarre stream rebindings it is not your responsibility what happens. Examples of these routines in use can be seen in the "Input and the keyboard decoder" section.

In using the Z88 you may well have come across a "Page Wait" message which appears on the left hand side of the screen in place of the application name and list of topics. This message can be generated by an application (it is not done automatically) when scrolling output is being sent to the screen. The actual system call involved is OS_Sr with register A = SR_PWT. This call produces the "Page Wait" message, waits for a key, restores the application name and topic list and then returns to the application. Because at the core of this routine there is a keyread, application writers must be careful to check for pre-emption codes, especially RC_QUIT. Although the writer may think about "Page Wait" as primarily an output function, it has all the characteristics of an input function. However, it only returns <BACKSPACE> (ASCII 8) and all relevant error codes like RC_QUIT and RC_DRAW. 
 

...

  • Set fonts and select bold or flash effects for characters
  • Switch the cursor on and off
  • Simulate the effects of special keys (Caps lock, index etc.)
  • Define, select and scroll windows
  • Select the horisontal horizontal and vertical print positions
  • Set justification or alignment
  • Set up user defined characters
  • Make various strings of beeps

in In fact, any graphic effects used by the built-in software with the single exception of the map. This is accessed more directly through the system calls, in particular OS_Map described in "Miscellaneous useful routines". The Standard library have also supplied utilities to plot, draw lines and sprites in the map area, which easily can be linked with application code using the Z80 Module Assembler Mpm.

...

The following screen driver codes generate special printable characters when preceeded by SOH:

Code
Value
Description
Width
Boldable
' '
$20
Exact symbol
1
 
'!'
$21
Bell symbol
3
 
'''
$27
Grave accent
1
yes
'*'
$2A
Square
1
yes
'+'
$2B
Diamond
1
yes
'-'
$2D
SHIFT symbol
3
 
'|'
$7D
Vertical unbroken bar
1
yes
SD_SPC
$E0
SPACE symbol
3
 
SD_ENT
$E1
ENTER symbol
3
 
SD_TAB
$E2
TAB symbol
3
 
SD_DEL
$E3
DEL symbol
3
 
SD_ESC
$E4
ESC symbol
3
 
SD_MNU
$E5
MENU symbol
3
 
SD_INX
$E6
INDEX symbol
3
 
SD_HLP
$E7
HELP symbol
3
 
SD_OLFT
$F0
Outline arrow Left
2
 
SD_ORGT
$F1
Outline arrow Right
2
 
SD_ODWN
$F2
Outline arrow Down
2
 
SD_OUP
$F3
Outline arrow Up
2
 
SD_BLFT
$F4
Bullet arrow Left
1
 
SD_BRGT
$F5
Bullet arrow Right
1
 
SD_BDWN
$F6
Bullet arrow Down
1
 
SD_BUP
$F7
Bullet arrow Up
1
 
SD_PLFT
$F8
Pointer arrow Left
1
yes
SD_PRGT
$F9
Pointer arrow Right
1
yes
SD_PDWN
$FA
Pointer arrow Down
1
yes
SD_PUP
$FB
Pointer arrow Up
1
yes

Box Characters

1, '2', '*', <char>

...

If one bit is set, a pointer arrow in the relevant direction is drawn. If two bits are set, two sides of a square or a line will be drawn. If three bits are set, a 'T' shape will be drawn. If all four bits are set, a cross will be drawn.

For example, the corner generated:

VDU 1, ASC"2", ASC"*", ASC"F"

makes a reasonable logical NOT sign. Here's the complete VDU's:

...

Code

...

Up  

...

Left

...

Down

...

Right

...

Symbol

...

1, '2', '*', 'A'

...

0

...

0

...

0

...

1

...

Pointer arrow Right

...

1, '2', '*', 'B'

...

0

...

0

...

1

...

0

...

Pointer arrow Down

...

1, '2', '*', 'C'

...

0

...

0

...

1

...

1

...

Corner Down Right

...

1, '2', '*', 'D'

...

0

...

1

...

0

...

0

...

corner generated:

VDU 1, ASC"2", ASC"*", ASC"F"

makes a reasonable logical NOT sign. Here's the complete VDU's:

Code
Up  
Left
Down
Right
Symbol
1, '2', '*', '
E
A'
0
1
0
0
1
Horizontal
Pointer arrow 
bar
Right
1, '2', '*', '
F
B'
0
1
0
1
0
Corner
Pointer 
Left
arrow Down
1, '2', '*', '
G
C'
0
1
0
1
1
T
Corner Down Right
1, '2', '*', '
H
D'
0
1
0
0
0
Pointer arrow 
Up
Left
1, '2', '*', '
I
E'
0
1
0
0
1
Corner
Horizontal 
Up Right
bar
1, '2', '*', '
J
F'
0
1
0
1
0
Vertical
Corner 
unbroken
Left 
bar
Down
1, '2', '*', '
K
G'
0
1
0
1
1
T 
Right
Down
1, '2', '*', '
L
H'
1
1
0
0
0
Corner
Pointer arrow Up
Left
1, '2', '*', '
M
I'
1
1
0
0
1
T
Corner Up Right
1, '2', '*', '
N
J'
1
1
0
1
0
T
Vertical unbroken 
Left
bar
1, '2', '*', '
O
K'
1
1
0
1
1
Cross

 

To draw a horizontally and vertically divided window:

 

...

T Right
1, '2', '*', 'L'
1
1
0
0
Corner Up Left
1, '2', '*', 'M'
1
1
0
1
T Up
1, '2', '*', 'N'
1
1
1
0
T Left
1, '2', '*', 'O'
1
1
1
1
Cross

 

To draw a horizontally and vertically divided window:

Gliffy
namewindow-vdu-char-overview
 

User Defined Characters

Finally, the screen driver may create user defined characters by the following combination which specifies the rows on a 6x8 matrix:

...

Application windows may be preserved by using the system call OS_Sr, A=SR_SUS. This is a lazy method and consumes 2K of continuous memory - don't use use it unless strictly necessary. Further, only the screen area starting from (10,0) to the right edge (before the OZ window) are preserved. Windows beyond that has to be redrawn explicitly. In any case, application windows must be redrawn when your application is re-entered (otherwise your are faced with a blank screen). If your application uses a window that overlaps the system's topic window you must also re-draw your window after an executed command, pressing <MENU> or the <HELP> key.

...

There are three calls which can be used to obtain information about the current state of the screen and they are all accessed via OS_Nq which takes a reason code in the BC register. A fuller description is given in "Miscellaneous useful routines", but the reason codes of interest are:

NQ_WBOX  return the size of a window
NQ_WCUR  return the cursor location in a window and indicate whether enabled
NQ_RDS   read characters from the screen starting at the cursor position1, '2', '*', 'J'