@nataliapc/mcp-openmsx 1.2.9 → 1.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -2
- package/bin/win-x64/mcp-openmsx-sspi-proxy.exe +0 -0
- package/dist/chunker.js +187 -0
- package/dist/embedder.js +250 -0
- package/dist/openmsx.js +113 -248
- package/dist/openmsx_windows.js +316 -0
- package/dist/server.js +6 -1
- package/dist/server_tools.js +6 -5
- package/dist/vectordb.js +94 -35
- package/package.json +16 -18
- package/resources/audio/chipsfmpacpr1_en.md +209 -0
- package/resources/audio/chipsfmpacpr2_en.md +170 -0
- package/resources/audio/toc.json +12 -0
- package/resources/book--msx-top-secret-3/MTS3-Appendix-English-Upd2.pdf +0 -0
- package/resources/book--msx-top-secret-3/MTS3-Complete-English.pdf +0 -0
- package/resources/book--msx2-technical-handbook/toc.json +1 -1
- package/resources/book--the-msx-red-book/Chapter1_Programmable_Peripheral_Interface.md +112 -0
- package/resources/book--the-msx-red-book/Chapter2_Video_Display_Processor.md +308 -0
- package/resources/book--the-msx-red-book/Chapter3_Programmable_Sound_Generator.md +168 -0
- package/resources/book--the-msx-red-book/Chapter4_ROM_BIOS.md +2528 -0
- package/resources/book--the-msx-red-book/Chapter5_ROM_BASIC_Interpreter.md +3975 -0
- package/resources/book--the-msx-red-book/Chapter6_Memory_Map.md +1963 -0
- package/resources/book--the-msx-red-book/Chapter7_Machine_Code_Programs.md +1238 -0
- package/resources/book--the-msx-red-book/Introduction.md +104 -0
- package/resources/book--the-msx-red-book/toc.json +38 -3
- package/resources/processors/toc.json +3 -3
- package/resources/processors/z80-undocumented.md +141 -0
- package/resources/sdcc/1_Introduction.md +199 -0
- package/resources/sdcc/2_Installing_SDCC.md +533 -0
- package/resources/sdcc/3_Using_SDCC.md +1758 -0
- package/resources/sdcc/4_Notes_on_supported_Processors.md +1638 -0
- package/resources/sdcc/5_Debugging.md +210 -0
- package/resources/sdcc/6_Tips_and_Support.md +258 -0
- package/resources/sdcc/7_SDCC_Technical_Data.md +489 -0
- package/resources/sdcc/8_Compiler_internals.md +477 -0
- package/resources/sdcc/toc.json +44 -2
- package/vector-db/msxdocs.lance/_indices/4d3bd360-e3c6-408d-b0ff-a4d6bd9580cb/metadata.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/4d3bd360-e3c6-408d-b0ff-a4d6bd9580cb/part_0_docs.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/4d3bd360-e3c6-408d-b0ff-a4d6bd9580cb/part_0_invert.lance +0 -0
- package/vector-db/msxdocs.lance/_indices/4d3bd360-e3c6-408d-b0ff-a4d6bd9580cb/part_0_tokens.lance +0 -0
- package/vector-db/msxdocs.lance/_transactions/0-6f47c9fc-3657-40f0-9dd4-c7226b2a4805.txn +0 -0
- package/vector-db/msxdocs.lance/_transactions/1-2bb7426e-a4b0-40ea-9a58-00c4985fc6a9.txn +0 -0
- package/vector-db/msxdocs.lance/_versions/18446744073709551613.manifest +0 -0
- package/vector-db/msxdocs.lance/_versions/18446744073709551614.manifest +0 -0
- package/vector-db/msxdocs.lance/_versions/latest_version_hint.json +1 -0
- package/vector-db/msxdocs.lance/data/110001110001011010001000876c134b8296fbc47762d1e1ab.lance +0 -0
- package/resources/book--the-msx-red-book/the_msx_red_book.md +0 -10349
- package/resources/processors/z80-undocumented.tex +0 -5617
- package/resources/sdcc/lyx2md.py +0 -745
- package/resources/sdcc/sdccman.lyx +0 -81574
- package/resources/sdcc/sdccman.md +0 -5557
- package/vector-db/index.json +0 -1
|
@@ -0,0 +1,2528 @@
|
|
|
1
|
+
# 4. ROM BIOS
|
|
2
|
+
|
|
3
|
+
The design of the MSX ROM is of importance if machine code programs are to be developed efficiently and Operate reliably. Almost every program, including the BASIC Interpreter itself, will require a certain set of primitive functions to operate. These include screen and printer drivers, a keyboard decoder and other hardware related functions. By separating these routines from the BASIC Interpreter they can be made available to any application program. The section of ROM from 0000H to 268BH is largely devoted to such routines and is called the ROM BIOS (Basic Input Output System).
|
|
4
|
+
|
|
5
|
+
This chapter gives a functional description of every recognizably separate routine in the ROM BIOS. Special attention is given to the "standard" routines. These are documented by Microsoft and guaranteed to remain consistent through possible hardware and software changes. The first few hundred bytes of the ROM consists of Z80 JP instructions which provide fixed position entry points to these routines. For maximum compatibility with future software an application program should restrict its dependence on the ROM to these locations only. The description of the ROM begins with this list of entry points to the standard routines. A brief comment is placed with each entry point, the full description is given with the routine itself.
|
|
6
|
+
|
|
7
|
+
<a name="data_areas"></a>
|
|
8
|
+
## Data Areas
|
|
9
|
+
|
|
10
|
+
It is expected that most users will wish to disassemble the ROM to some extent (the full listing runs to nearly four hundred pages). In order to ease this process the data areas, which do not contain executable Z80 code, are shown below:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
0004H-0007H 185DH-1863H 4B3AH-4B4CH 73E4H-73E4H
|
|
14
|
+
002BH-002FH 1B97H-1BAAH 4C2FH-4C3FH 752EH-7585H
|
|
15
|
+
0508H-050DH 1BBFH-23BEH 555AH-5569H 7754H-7757H
|
|
16
|
+
092FH-097FH 2439H-2459H 5D83H-5DB0H 7BA3H-7BCAH
|
|
17
|
+
0DA5H-0EC4H 2CF1H-2E70H 6F76H-6F8EH 7ED8H-7F26H
|
|
18
|
+
1033H-105AH 3030H-3039H 70FFH-710CH 7F41H-7FB6H
|
|
19
|
+
1061H-10C1H 3710H-3719H 7182H-7195H 7FBEH-7FFFH
|
|
20
|
+
1233H-1252H 392EH-3FE1H 71A2H-71B5H
|
|
21
|
+
13A9H-1448H 43B5H-43C3H 71C7H-71DAH
|
|
22
|
+
160BH-1612H 46E6H-46E7H 72A6H-72B9H
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Note that these data areas are for the UK ROM, there are slight differences in the Japanese ROM relating to the keyboard decoder and the video character set. Disparities between the ROMs are restricted to these regions with the bulk of the code being identical in both cases.
|
|
26
|
+
|
|
27
|
+
<a name="terminology"></a>
|
|
28
|
+
## Terminology
|
|
29
|
+
|
|
30
|
+
Reference is frequently made in this chapter to the standard routines and to Workspace Area variables. Whenever this is done the Microsoft-recommended name is used in upper case letters, for example "the [FILVRM](#filvrm) standard routine" and "[SCRMOD](#scrmod) is set". Subroutines which are not named are referred to by a parenthesized address, "the screen is cleared ([0777H](#0777h))" for example. When reference is made to the Z80 status flags assembly language conventions are used, for example "Flag C" would mean that the carry flag is set while "Flag NZ" means that the zero flag is reset. The terms "EI" and "DI" mean enabled interrupts and disabled interrupts respectively.
|
|
31
|
+
|
|
32
|
+
|ADDRESS |NAME |TO |FUNCTION
|
|
33
|
+
|:---------:|:-----------------:|:-----------------:|--------------------------------------
|
|
34
|
+
|0000H |[CHKRAM](#chkram) |[02D7H](#02d7h) |Power-up, check RAM
|
|
35
|
+
|0004H |...... |..... |Two bytes, address of ROM character set
|
|
36
|
+
|0006H |...... |..... |One byte, VDP [Data Port](#data_port) number
|
|
37
|
+
|0007H |...... |..... |One byte, VDP [Data Port](#data_port) number
|
|
38
|
+
|0008H |[SYNCHR](#synchr) |[2683H](#2683h) |Check BASIC program character
|
|
39
|
+
|000BH |...... |..... |NOP
|
|
40
|
+
|000CH |[RDSLT](#rdslt) |[01B6H](#01b6h) |Read RAM in any slot
|
|
41
|
+
|000FH |...... |..... |NOP
|
|
42
|
+
|0010H |[CHRGTR](#chrgtr) |[2686H](#2686h) |Get next BASIC program character
|
|
43
|
+
|0013H |...... |..... |NOP
|
|
44
|
+
|0014H |[WRSLT](#wrslt) |[01D1H](#01d1h) |Write to RAM in any slot
|
|
45
|
+
|0017H |...... |..... |NOP
|
|
46
|
+
|0018H |[OUTDO](#outdo) |[1B45H](#1b45h) |Output to current device
|
|
47
|
+
|001BH |...... |..... |NOP
|
|
48
|
+
|001CH |[CALSLT](#calslt) |[0217H](#0217h) |Call routine in any slot
|
|
49
|
+
|001FH |...... |..... |NOP
|
|
50
|
+
|0020H |[DCOMPR](#dcompr) |[146AH](#146ah) |Compare register pairs HL and DE
|
|
51
|
+
|0023H |...... |..... |NOP
|
|
52
|
+
|0024H |[ENASLT](#enaslt) |[025EH](#025eh) |Enable any slot permanently
|
|
53
|
+
|0027H |...... |..... |NOP
|
|
54
|
+
|0028H |[GETYPR](#getypr) |[2689H](#2689h) |Get BASIC operand type
|
|
55
|
+
|002BH |...... |..... |Five bytes Version Number
|
|
56
|
+
|0030H |[CALLF](#callf) |[0205H](#0205h) |Call routine in any slot
|
|
57
|
+
|0033H |...... |..... |Five NOPs
|
|
58
|
+
|0038H |[KEYINT](#keyint) |[0C3CH](#0c3ch) |Interrupt handler, keyboard scan
|
|
59
|
+
|003BH |[INITIO](#initio) |[049DH](#049dh) |Initialize I/O devices
|
|
60
|
+
|003EH |[INIFNK](#inifnk) |[139DH](#139dh) |Initialize function key strings
|
|
61
|
+
|0041H |[DISSCR](#disscr) |[0577H](#0577h) |Disable screen
|
|
62
|
+
|0044H |[ENASCR](#enascr) |[0570H](#0570h) |Enable screen
|
|
63
|
+
|0047H |[WRTVDP](#wrtvdp) |[057FH](#057fh) |Write to any VDP register
|
|
64
|
+
|004AH |[RDVRM](#rdvrm) |[07D7H](#07d7h) |Read byte from VRAM
|
|
65
|
+
|004DH |[WRTVRM](#wrtvrm) |[07CDH](#07cdh) |Write byte to VRAM
|
|
66
|
+
|0050H |[SETRD](#setrd) |[07ECH](#07ech) |Set up VDP for read
|
|
67
|
+
|0053H |[SETWRT](#setwrt) |[07DFH](#07dfh) |Set up VDP for write
|
|
68
|
+
|0056H |[FILVRM](#filvrm) |[0815H](#0815h) |Fill block of VRAM with data byte
|
|
69
|
+
|0059H |[LDIRMV](#ldirmv) |[070FH](#070fh) |Copy block to memory from VRAM
|
|
70
|
+
|005CH |[LDIRVM](#ldirvm) |[0744H](#0744h) |Copy block to VRAM, from memory
|
|
71
|
+
|005FH |[CHGMOD](#chgmod) |[084FH](#084fh) |Change VDP mode
|
|
72
|
+
|0062H |[CHGCLR](#chgclr) |[07F7H](#07f7h) |Change VDP colours
|
|
73
|
+
|0065H |...... |..... |NOP
|
|
74
|
+
|0066H |[NMI](#nmi) |[1398H](#1398h) |Non Maskable Interrupt handler
|
|
75
|
+
|0069H |[CLRSPR](#clrspr) |[06A8H](#06a8h) |Clear all sprites
|
|
76
|
+
|006CH |[INITXT](#initxt) |[050EH](#050eh) |Initialize VDP to [40x24 Text Mode](#40x24_text_mode)
|
|
77
|
+
|006FH |[INIT32](#init32) |[0538H](#0538h) |Initialize VDP to [32x24 Text Mode](#32x24_text_mode)
|
|
78
|
+
|0072H |[INIGRP](#inigrp) |[05D2H](#05d2h) |Initialize VDP to [Graphics Mode](#graphics_mode)
|
|
79
|
+
|0075H |[INIMLT](#inimlt) |[061FH](#061fh) |Initialize VDP to [Multicolour Mode](#multicolor_mode)
|
|
80
|
+
|0078H |[SETTXT](#settxt) |[0594H](#0594h) |Set VDP to [40x24 Text Mode](#40x24_text_mode)
|
|
81
|
+
|007BH |[SETT32](#sett32) |[05B4H](#05b4h) |Set VDP to [32x24 Text Mode](#32x24_text_mode)
|
|
82
|
+
|007EH |[SETGRP](#setgrp) |[0602H](#0602h) |Set VDP to [Graphics Mode](#graphics_mode)
|
|
83
|
+
|0081H |[SETMLT](#setmlt) |[0659H](#0659h) |Set VDP to [Multicolour Mode](#multicolour_mode)
|
|
84
|
+
|0084H |[CALPAT](#calpat) |[06E4H](#06e4h) |Calculate address of sprite pattern
|
|
85
|
+
|0087H |[CALATR](#calatr) |[06F9H](#06f9h) |Calculate address of sprite attribute
|
|
86
|
+
|008AH |[GSPSIZ](#gspsiz) |[0704H](#0704h) |Get sprite size
|
|
87
|
+
|008DH |[GRPPRT](#grpprt) |[1510H](#1510h) |Print character on graphic screen
|
|
88
|
+
|0090H |[GICINI](#gicini) |[04BDH](#04bdh) |Initialize PSG (GI Chip)
|
|
89
|
+
|0093H |[WRTPSG](#wrtpsg) |[1102H](#1102h) |Write to any PSG register
|
|
90
|
+
|0096H |[RDPSG](#rdpsg) |[110EH](#110eh) |Read from any PSG register
|
|
91
|
+
|0099H |[STRTMS](#strtms) |[11C4H](#11c4h) |Start music dequeueing
|
|
92
|
+
|009CH |[CHSNS](#chsns) |[0D6AH](#0d6ah) |Sense keyboard buffer for character
|
|
93
|
+
|009FH |[CHGET](#chget) |[10CBH](#10cbh) |Get character from keyboard buffer (wait)
|
|
94
|
+
|00A2H |[CHPUT](#chput) |[08BCH](#08bch) |Screen character output
|
|
95
|
+
|00A5H |[LPTOUT](#lptout) |[085DH](#085dh) |Line printer character output
|
|
96
|
+
|00A8H |[LPTSTT](#lptstt) |[0884H](#0884h) |Line printer status test
|
|
97
|
+
|00ABH |[CNVCHR](#cnvchr) |[089DH](#089dh) |Convert character with graphic header
|
|
98
|
+
|00AEH |[PINLIN](#pinlin) |[23BFH](#23bfh) |Get line from console (editor)
|
|
99
|
+
|00B1H |[INLIN](#inlin) |[23D5H](#23d5h) |Get line from console (editor)
|
|
100
|
+
|00B4H |[QINLIN](#qinlin) |[23CCH](#23cch) |Display "`?`", get line from console (editor)
|
|
101
|
+
|00B7H |[BREAKX](#breakx) |[046FH](#046fh) |Check CTRL-STOP key directly
|
|
102
|
+
|00BAH |[ISCNTC](#iscntc) |[03FBH](#03fbh) |Check CRTL-STOP key
|
|
103
|
+
|00BDH |[CKCNTC](#ckcntc) |[10F9H](#10f9h) |Check CTRL-STOP key
|
|
104
|
+
|00C0H |[BEEP](#beep) |[1113H](#1113h) |Go beep
|
|
105
|
+
|00C3H |[CLS](#cls) |[0848H](#0848h) |Clear screen
|
|
106
|
+
|00C6H |[POSIT](#posit) |[088EH](#088eh) |Set cursor position
|
|
107
|
+
|00C9H |[FNKSB](#fnksb) |[0B26H](#0b26h) |Check if function key display on
|
|
108
|
+
|00CCH |[ERAFNK](#erafnk) |[0B15H](#0b15h) |Erase function key display
|
|
109
|
+
|00CFH |[DSPFNK](#dspfnk) |[0B2BH](#0b2bh) |Display function keys
|
|
110
|
+
|00D2H |[TOTEXT](#totext) |[083BH](#083bh) |Return VDP to text mode
|
|
111
|
+
|00D5H |[GTSTCK](#gtstck) |[11EEH](#11eeh) |Get joystick status
|
|
112
|
+
|00D8H |[GTTRIG](#gttrig) |[1253H](#1253h) |Get trigger status
|
|
113
|
+
|00DBH |[GTPAD](#gtpad) |[12ACH](#12ach) |Get touch pad status
|
|
114
|
+
|00DEH |[GTPDL](#gtpdl) |[1273H](#1273h) |Get paddle status
|
|
115
|
+
|00E1H |[TAPION](#tapion) |[1A63H](#1a63h) |Tape input ON
|
|
116
|
+
|00E4H |[TAPIN](#tapin) |[1ABCH](#1abch) |Tape input
|
|
117
|
+
|00E7H |[TAPIOF](#tapiof) |[19E9H](#19e9h) |Tape input OFF
|
|
118
|
+
|00EAH |[TAPOON](#tapoon) |[19F1H](#19f1h) |Tape output ON
|
|
119
|
+
|00EDH |[TAPOUT](#tapout) |[1A19H](#1a19h) |Tape output
|
|
120
|
+
|00F0H |[TAPOOF](#tapoof) |[19DDH](#19ddh) |Tape output OFF
|
|
121
|
+
|00F3H |[STMOTR](#stmotr) |[1384H](#1384h) |Turn motor ON/OFF
|
|
122
|
+
|00F6H |[LFTQ](#lftq) |[14EBH](#14ebh) |Space left in music queue
|
|
123
|
+
|00F9H |[PUTQ](#putq) |[1492H](#1492h) |Put byte in music queue
|
|
124
|
+
|00FCH |[RIGHTC](#rightc) |[16C5H](#16c5h) |Move current pixel physical address right
|
|
125
|
+
|00FFH |[LEFTC](#leftc) |[16EEH](#16eeh) |Move current pixel physical address left
|
|
126
|
+
|0102H |[UPC](#upc) |[175DH](#175dh) |Move current pixel physical address up
|
|
127
|
+
|0105H |[TUPC](#tupc) |[173CH](#173ch) |Test then [UPC](#upc) if legal
|
|
128
|
+
|0108H |[DOWNC](#downc) |[172AH](#172ah) |Move current pixel physical address down
|
|
129
|
+
|010BH |[TDOWNC](#tdownc) |[170AH](#170ah) |Test then [DOWNC](#downc) if legal
|
|
130
|
+
|010EH |[SCALXY](#scalxy) |[1599H](#1599h) |Scale graphics coordinates
|
|
131
|
+
|0111H |[MAPXYC](#mapxyc) |[15DFH](#15dfh) |Map graphic coordinates to physical address
|
|
132
|
+
|0114H |[FETCHC](#fetchc) |[1639H](#1639h) |Fetch current pixel physical address
|
|
133
|
+
|0117H |[STOREC](#storec) |[1640H](#1640h) |Store current pixel physical address
|
|
134
|
+
|011AH |[SETATR](#setatr) |[1676H](#1676h) |Set attribute byte
|
|
135
|
+
|011DH |[READC](#readc) |[1647H](#1647h) |Read attribute of current pixel
|
|
136
|
+
|0120H |[SETC](#setc) |[167EH](#167eh) |Set attribute of current pixel
|
|
137
|
+
|0123H |[NSETCX](#nsetcx) |[1809H](#1809h) |Set attribute of number of pixels
|
|
138
|
+
|0126H |[GTASPC](#gtaspc) |[18C7H](#18c7h) |Get aspect ratio
|
|
139
|
+
|0129H |[PNTINI](#pntini) |[18CFH](#18cfh) |Paint initialize
|
|
140
|
+
|012CH |[SCANR](#scanr) |[18E4H](#18e4h) |Scan pixels to right
|
|
141
|
+
|012FH |[SCANL](#scanl) |[197AH](#197ah) |Scan pixels to left
|
|
142
|
+
|0132H |[CHGCAP](#chgcap) |[0F3DH](#0f3dh) |Change Caps Lock LED
|
|
143
|
+
|0135H |[CHGSND](#chgsnd) |[0F7AH](#0f7ah) |Change Key Click sound output
|
|
144
|
+
|0138H |[RSLREG](#rslreg) |[144CH](#144ch) |Read Primary Slot Register
|
|
145
|
+
|013BH |[WSLREG](#wslreg) |[144FH](#144fh) |Write to Primary Slot Register
|
|
146
|
+
|013EH |[RDVDP](#rdvdp) |[1449H](#1449h) |Read VDP Status Register
|
|
147
|
+
|0141H |[SNSMAT](#snsmat) |[1452H](#1452h) |Read row of keyboard matrix
|
|
148
|
+
|0144H |[PHYDIO](#phydio) |[148AH](#148ah) |Disk, no action
|
|
149
|
+
|0147H |[FORMAT](#format) |[148EH](#148eh) |Disk, no action
|
|
150
|
+
|014AH |[ISFLIO](#isflio) |[145FH](#145fh) |Check for file I/O
|
|
151
|
+
|014DH |[OUTDLP](#outdlp) |[1B63H](#1b63h) |Formatted output to line printer
|
|
152
|
+
|0150H |[GETVCP](#getvcp) |[1470H](#1470h) |Get music voice pointer
|
|
153
|
+
|0153H |[GETVC2](#getvc2) |[1474H](#1474h) |Get music voice pointer
|
|
154
|
+
|0156H |[KILBUF](#kilbuf) |[0468H](#0468h) |Clear keyboard buffer
|
|
155
|
+
|0159H |[CALBAS](#calbas) |[01FFH](#01ffh) |Call to BASIC from any slot
|
|
156
|
+
|015CH |...... |..... |NOPs to 01B5H for expansion
|
|
157
|
+
|
|
158
|
+
<a name="01b6h"></a><a name="rdslt"></a>
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
Address... 01B6H
|
|
162
|
+
Name...... RDSLT
|
|
163
|
+
Entry..... A=Slot ID, HL=Address
|
|
164
|
+
Exit...... A=Byte read
|
|
165
|
+
Modifies.. AF, BC, DE, DI
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Standard routine to read a single byte from memory in any slot. The Slot Identifier is composed of a Primary Slot number a Secondary Slot number and a flag:
|
|
169
|
+
|
|
170
|
+
<a name="figure34"></a>![][CH04F34]
|
|
171
|
+
|
|
172
|
+
**Figure 34:** Slot ID
|
|
173
|
+
|
|
174
|
+
The flag is normally 0 but must be 1 if a Secondary Slot number is included in the Slot ID. The memory address and Slot ID are first processed ([027EH](#027eh)) to yield a set of bit masks to apply to the relevant slot register. If a Secondary Slot number is specified then the Secondary Slot Register is first modified to select the relevant page from that Secondary Slot ([02A3H](#02a3h)). The Primary Slot is then switched in to the Z80 address space, the byte read and the Primary Slot restored to its original setting via the [RDPRIM](#rdprim) routine in the Workspace Area. Finally, if a Secondary Slot number is included in the Slot ID, the original Secondary Slot Register setting is restored (01ECH).
|
|
175
|
+
|
|
176
|
+
Note that, unless it is the slot containing the Workspace Area, any attempt to access page 3 (C000H to FFFFH) will cause the system to crash as [RDPRIM](#rdprim) will switch itself out. Note also that interrupts are left disabled by all the memory switching routines.
|
|
177
|
+
|
|
178
|
+
<a name="01d1h"></a><a name="wrslt"></a>
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
Address... 01D1H
|
|
182
|
+
Name...... WRSLT
|
|
183
|
+
Entry..... A=Slot ID, HL=Address, E=Byte to write
|
|
184
|
+
Exit...... None
|
|
185
|
+
Modifies.. AF, BC, D, DI
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Standard routine to write a single byte to memory in any slot. Its operation is fundamentally the same as that of the [RDSLT](#rdslt) standard routine except that the Workspace Area routine [WRPRIM](#wrprim) is used rather than [RDPRIM](#rdprim).
|
|
189
|
+
|
|
190
|
+
<a name="01ffh"></a><a name="calbas"></a>
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
Address... 01FFH
|
|
194
|
+
Name...... CALBAS
|
|
195
|
+
Entry..... IX=Address
|
|
196
|
+
Exit...... None
|
|
197
|
+
Modifies.. AF', BC', DE', HL', IY, DI
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Standard routine to call an address in the BASIC Interpreter from any slot. Usually this will be from a machine code program running in an extension ROM in page 1 (4000H to 7FFFH). The high byte of register pair IY is loaded with the MSX ROM Slot ID (00H) and control transfers to the [CALSLT](#calslt) standard routine.
|
|
201
|
+
|
|
202
|
+
<a name="0205h"></a><a name="callf"></a>
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
Address... 0205H
|
|
206
|
+
Name...... CALLF
|
|
207
|
+
Entry..... None
|
|
208
|
+
Exit...... None
|
|
209
|
+
Modifies.. AF', BC', DE', HL', IX, IY, DI
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Standard routine to call an address in any slot. The Slot ID and address are supplied as inline parameters rather than in registers to fit inside a hook ([Chapter 6](chapter_6)), for example:
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
RST 30H
|
|
216
|
+
DEFB Slot ID
|
|
217
|
+
DEFW Address
|
|
218
|
+
RET
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The Slot ID is first collected and placed in the high byte of register pair IY. The address is then placed in register pair IX and control drops into the [CALSLT](#calslt) standard routine.
|
|
222
|
+
|
|
223
|
+
<a name="0217h"></a><a name="calslt"></a>
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
Address... 0217H
|
|
227
|
+
Name...... CALSLT
|
|
228
|
+
Entry..... IY(High byte)=Slot ID, IX=Address
|
|
229
|
+
Exit...... None
|
|
230
|
+
Modifies.. AF', BC', DE', HL', DI
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Standard routine to call an address in any slot. Its operation is fundamentally the same as that of the [RDSLT](#rdslt) standard routine except that the Workspace Area routine [CLPRIM](#clprim) is used rather than [RDPRIM](#rdprim). Note that [CALBAS](#calbas) and [CALLF](#callf) are just specialized entry points to this standard routine which offer a reduction in the amount of code required.
|
|
234
|
+
|
|
235
|
+
<a name="025eh"></a><a name="enaslt"></a>
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
Address... 025EH
|
|
239
|
+
Name...... ENASLT
|
|
240
|
+
Entry..... A=Slot ID, HL=Address
|
|
241
|
+
Exit...... None
|
|
242
|
+
Modifies.. AF, BC, DE, DI
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Standard routine to switch in a page permanently from any slot. Unlike the [RDSLT](#rdslt), [WRSLT](#wrslt) and [CALSLT](#calslt) standard routines the Primary Slot switching is performed directly and not by a Workspace Area routine. Consequently addresses in page 0 (0000H to 3FFFH) will cause an immediate system crash.
|
|
246
|
+
|
|
247
|
+
<a name="027eh"></a>
|
|
248
|
+
|
|
249
|
+
Address... 027EH
|
|
250
|
+
|
|
251
|
+
This routine is used by the memory switching standard routines to turn an address, in register pair HL, and a Slot ID, in register A, into a set of bit masks. As an example a Slot ID of FxxxSSPP and an address in Page 1 (4000H to 7FFFH) would return the following:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
Register B=00 00 PP 00 (OR mask)
|
|
255
|
+
Register C=11 11 00 11 (AND mask)
|
|
256
|
+
Register D=PP PP PP PP (Replicated)
|
|
257
|
+
Register E=00 00 11 00 (Page mask)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Registers B and C are derived from the Primary Slot number and the page mask. They are later used to mix the new Primary Slot number into the existing contents of the Primary Slot Register. Register D contains the Primary Slot number replicated four times and register E the page mask. This is produced by examining the two most significant bits of the address, to determine the page number, and then shifting the mask along to the relevant position. These registers are later used during Secondary Slot switching.
|
|
261
|
+
|
|
262
|
+
As the routine terminates bit 7 of the Slot ID is tested, to determine whether a Secondary Slot has been specified, and Flag M returned if this is so.
|
|
263
|
+
|
|
264
|
+
<a name="02a3h"></a>
|
|
265
|
+
|
|
266
|
+
Address... 02A3H
|
|
267
|
+
|
|
268
|
+
This routine is used by the memory switching standard routines to modify a Secondary Slot Register. The Slot ID is supplied in register A while registers D and E contain the bit masks shown in the previous routine.
|
|
269
|
+
|
|
270
|
+
Bits 6 and 7 of register D are first copied into the Primary Slot register. This switches in page 3 from the Primary Slot specified by the Slot ID and makes the required Secondary Slot Register available. This is then read from memory location FFFFH and the page mask, inverted, used to clear the required two bits. The Secondary Slot number is shifted to the relevant position and mixed in. Finally the new setting is placed in the Secondary Slot Register and the Primary Slot Register restored to its original setting.
|
|
271
|
+
|
|
272
|
+
<a name="02d7h"></a><a name="chkram"></a>
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
Address... 02D7H
|
|
276
|
+
Name...... CHKRAM
|
|
277
|
+
Entry..... None
|
|
278
|
+
Exit...... None
|
|
279
|
+
Modifies.. AF, BC, DE, HL, SP
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Standard routine to perform memory initialization at power- up. It non-destructively tests for RAM in pages 2 and 3 in all sixteen possible slots then sets the Primary and Secondary Slot registers to switch in the largest area found. The entire Workspace Area (F380H to FFC9H) is zeroed and [EXPTBL](#exptbl) and [SLTTBL](#slttbl) filled in to map any expansion interfaces in existence Interrupt Mode 1 is set and control transfers to the remainder of the power-up initialization routine ([7C76H](#7c76h)).
|
|
283
|
+
|
|
284
|
+
<a name="03fbh"></a><a name="iscntc"></a>
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
Address... 03FBH
|
|
288
|
+
Name...... ISCNTC
|
|
289
|
+
Entry..... None
|
|
290
|
+
Exit...... None
|
|
291
|
+
Modifies.. AF, EI
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Standard routine to check whether the CTRL-STOP or STOP keys have been pressed. It is used by the BASIC Interpreter at the end of each statement to check for program termination. [BASROM](#basrom) is first examined to see if it contains a non-zero value, if so the routine terminates immediately. This is to prevent users breaking into any extension ROM containing a BASIC program.
|
|
295
|
+
|
|
296
|
+
[INTFLG](#intflg) is then checked to determine whether the interrupt handler has placed the CTRL-STOP or STOP key codes (03H or 04H) there. If STOP has been detected then the cursor is turned on ([09DAH](#09dah)) and [INTFLG](#intflg) continually checked until one of the two key codes reappears. The cursor is then turned off ([0A27H](#0a27h)) and, if the key is STOP, the routine terminates.
|
|
297
|
+
|
|
298
|
+
If CTRL-STOP has been detected then the keyboard buffer is first cleared via the [KILBUF](#kilbuf) standard routine and [TRPTBL](#trptbl) is checked to see whether an "`ON STOP GOSUB`" statement is active. If so the relevant entry in [TRPTBL](#trptbl) is updated ([0EF1H](#0ef1h)) and the routine terminates as the event will be handled by the Interpreter Runloop. Otherwise the [ENASLT](#enaslt) standard routine is used to switch in page 1 from the MSX ROM, in case an extension ROM is using the routine, and control transfers to the "`STOP`" statement handler (63E6H).
|
|
299
|
+
|
|
300
|
+
<a name="0468h"></a><a name="kilbuf"></a>
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
Address... 0468H
|
|
304
|
+
Name...... KILBUF
|
|
305
|
+
Entry..... None
|
|
306
|
+
Exit...... None
|
|
307
|
+
Modifies.. HL
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Standard Routine to clear the forty character type-ahead keyboard buffer [KEYBUF](#keybuf). There are two pointers into this buffer, [PUTPNT](#putpnt) where the interrupt handler places characters, and [GETPNT](#getpnt) where application programs fetch them from. As the number of characters in the buffer is indicated by the difference between these two pointers [KEYBUF](#keybuf) is emptied simply by making them both equal.
|
|
311
|
+
|
|
312
|
+
<a name="046fh"></a><a name="breakx"></a>
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
Address... 046FH
|
|
316
|
+
Name...... BREAKX
|
|
317
|
+
Entry..... None
|
|
318
|
+
Exit...... Flag C if CTRL-STOP key pressed
|
|
319
|
+
Modifies.. AF
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Standard routine which directly tests rows 6 and 7 of the keyboard to determine whether the CTRL and STOP keys are both pressed. If they are then [KEYBUF](#keybuf) is cleared and row 7 of [OLDKEY](#oldkey) modified to prevent the interrupt handler picking the keys up as well. This routine may often be more suitable for use by an application program, in preference to [ISCNTC](#iscntc), as it will work when interrupts are disabled, during cassette I/O for example, and does not exit to the Interpreter.
|
|
323
|
+
|
|
324
|
+
<a name="049dh"></a><a name="initio"></a>
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
Address... 049DH
|
|
328
|
+
Name...... INITIO
|
|
329
|
+
Entry..... None
|
|
330
|
+
Exit...... None
|
|
331
|
+
Modifies.. AF, E, EI
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Standard routine to initialize the PSG and the Centronics Status Port. [PSG Register 7](#register_7) is first set to 80H making PSG Port B=Output and PSG Port A=Input. [PSG Register 15](#register_15) is set to CFH to initialize the Joystick connector control hardware. [PSG Register 14](#register_14) is then read and the Keyboard Mode bit placed in [KANAMD](#kanamd), this has no relevance for UK machines.
|
|
335
|
+
|
|
336
|
+
Finally a value of FFH is output to the Centronics Status Port (I/O port 90H) to set the [STROBE](#strobe) signal high. Control then drops into the [GICINI](#gicini) standard routine to complete initialization.
|
|
337
|
+
|
|
338
|
+
<a name="04bdh"></a><a name="gicini"></a>
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
Address... 04BDH
|
|
342
|
+
Name...... GICINI
|
|
343
|
+
Entry..... None
|
|
344
|
+
Exit...... None
|
|
345
|
+
Modifies.. EI
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Standard routine to initialize the PSG and the Workspace Area variables associated with the "`PLAY`" statement. [QUETAB](#quetab), [VCBA](#vcba), [VCBB](#vcbb) and [VCBC](#vcbc) are first initialized with the values shown in Chapter 6. PSG Registers [8](#register_8), [9](#register_9) and [10](#register_10) are then set to zero amplitude and [PSG Register 7](#register_7) to B8H. This enables the Tone Generator and disables the Noise Generator on each channel.
|
|
349
|
+
|
|
350
|
+
<a name="0508h"></a>
|
|
351
|
+
|
|
352
|
+
Address... 0508H
|
|
353
|
+
|
|
354
|
+
This six byte table contains the "`PLAY`" statement parameters initially placed in [VCBA](#vcba), [VCBB](#vcbb) and [VCBC](#vcbc) by the [GICINI](#gicini) standard routine: Octave=4, Length=4, Tempo=120, Volume=88H, Envelope=00FFH.
|
|
355
|
+
|
|
356
|
+
<a name="050eh"></a><a name="initxt"></a>
|
|
357
|
+
|
|
358
|
+
```
|
|
359
|
+
Address... 050EH
|
|
360
|
+
Name...... INITXT
|
|
361
|
+
Entry..... None
|
|
362
|
+
Exit...... None
|
|
363
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Standard routine to initialize the VDP to [40x24 Text Mode](#40x24_text_mode). The screen is temporarily disabled via the [DISSCR](#disscr) standard routine and [SCRMOD](#scrmod) and [OLDSCR](#oldscr) set to 00H. The parameters required by the [CHPUT](#chput) standard routine are set up by copying [LINL40](#linl40) to [LINLEN](#linlen), [TXTNAM](#txtnam) to [NAMBAS](#nambas) and [TXTCGP](#txtcgp) to [CGPBAS](#cgpbas). The VDP colours are then set by the [CHGCLR](#chgclr) standard routine and the screen is cleared (077EH). The current character set is copied into the VRAM Character Pattern Table ([071EH](#071eh)). Finally the VDP mode and base addresses are set via the [SETTXT](#settxt) standard routine and the screen is enabled.
|
|
367
|
+
|
|
368
|
+
<a name="0538h"></a><a name="init32"></a>
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
Address... 0538H
|
|
372
|
+
Name...... INIT32
|
|
373
|
+
Entry..... None
|
|
374
|
+
Exit...... None
|
|
375
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Standard routine to initialize the VDP to [32x24 Text Mode](#32x24_text_mode). The screen is temporarily disabled via the [DISSCR](#disscr) standard routine and [SCRMOD](#scrmod) and [OLDSCR](#oldscr) set to 01H. The parameters required by the [CHPUT](#chput) standard routine are set up by copying [LINL32](#linl32) to [LINLEN](#linlen), [T32NAM](#t32nam) to [NAMBAS](#nambas), [T32CGP](#t32cgp) to [CGPBAS](#cgpbas), [T32PAT](#t32pat) to [PATBAS](#patbas) and [T32ATR](#t32atr) to [ATRBAS](#atrbas). The VDP colours are then set via the [CHGCLR](#chgclr) standard routine and the screen is cleared (077EH). The current character set is copied into the VRAM Character Pattern Table ([071EH](#071eh)) and all sprites cleared (06BBH). Finally the VDP mode and base addresses are set via the [SETT32](#sett32) standard routine and the screen is enabled.
|
|
379
|
+
|
|
380
|
+
<a name="0570h"></a><a name="enascr"></a>
|
|
381
|
+
|
|
382
|
+
```
|
|
383
|
+
Address... 0570H
|
|
384
|
+
Name...... ENASCR
|
|
385
|
+
Entry..... None
|
|
386
|
+
Exit...... None
|
|
387
|
+
Modifies.. AF, BC, EI
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Standard routine to enable the screen. This simply involves setting bit 6 of VDP [Mode Register 1](#mode_register_1).
|
|
391
|
+
|
|
392
|
+
<a name="0577h"></a><a name="disscr"></a>
|
|
393
|
+
|
|
394
|
+
```
|
|
395
|
+
Address... 0577H
|
|
396
|
+
Name...... DISSCR
|
|
397
|
+
Entry..... None
|
|
398
|
+
Exit...... None
|
|
399
|
+
Modifies.. AF, BC, EI
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Standard routine to disable the screen. This simply involves resetting bit 6 of VDP [Mode Register 1](#mode_register_1).
|
|
403
|
+
|
|
404
|
+
<a name="057fh"></a><a name="wrtvdp"></a>
|
|
405
|
+
|
|
406
|
+
```
|
|
407
|
+
Address... 057FH
|
|
408
|
+
Name...... WRTVDP
|
|
409
|
+
Entry..... B=Data byte, C=VDP Mode Register number
|
|
410
|
+
Exit...... None
|
|
411
|
+
Modifies.. AF, B, EI
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Standard routine to write a data byte to any VDP [Mode Register](#vdp_mode_registers). The register selection byte is first written to the VDP [Command Port](#commandpport), followed by the data byte. This is then copied to the relevant register image, [RG0SAV](#rg0sav) to [RG7SAV](#rg7sav), in the Workspace Area
|
|
415
|
+
|
|
416
|
+
<a name="0594h"></a><a name="settxt"></a>
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
Address... 0594H
|
|
420
|
+
Name...... SETTXT
|
|
421
|
+
Entry..... None
|
|
422
|
+
Exit...... None
|
|
423
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Standard routine to partially set the VDP to [40x24 Text Mode](#40x24_text_mode). The mode bits M1, M2 and M3 are first set in VDP Mode Registers [0](#mode_register_0) and [1](#mode_register_1). The five VRAM table base addresses, beginning with [TXTNAM](#txtnam), are then copied from the Workspace Area into VDP Mode Registers [2](#mode_register_2), [3](#mode_register_3), [4](#mode_register_4), [5](#mode_register_5) and [6](#mode_register_6) ([0677H](#0677h)).
|
|
427
|
+
|
|
428
|
+
<a name="05b4h"></a><a name="sett32"></a>
|
|
429
|
+
|
|
430
|
+
```
|
|
431
|
+
Address... 05B4H
|
|
432
|
+
Name...... SETT32
|
|
433
|
+
Entry..... None
|
|
434
|
+
Exit...... None
|
|
435
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Standard routine to partially set the VDP to [32x24 Text Mode](#32x24_text_mode). The mode bits M1, M2 and M3 are first set in VDP Mode Registers [0](#mode_register_0) and [1](#mode_register_1). The five VRAM table base addresses, beginning with [T32NAM](#t32nam), are then copied from the Workspace Area into VDP Mode Registers [2](#mode_register_2), [3](#mode_register_3), [4](#mode_register_4), [5](#mode_register_5) and [6](#mode_register_6) ([0677H](#0677h)).
|
|
439
|
+
|
|
440
|
+
<a name="05d2h"></a><a name="inigrp"></a>
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
Address... 05D2H
|
|
444
|
+
Name...... INIGRP
|
|
445
|
+
Entry..... None
|
|
446
|
+
Exit...... None
|
|
447
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Standard routine to initialize the VDP to [Graphics Mode](#graphics_mode). The screen is temporarily disabled via the [DISSCR](#disscr) standard routine and [SCRMOD](#scrmod) set to 02H. The parameters required by the [GRPPRT](#grpprt) standard routine are set up by copying [GRPPAT](#grppat) to [PATBAS](#patbas) and [GRPATR](#grpatr) to [ATRBAS](#atrbas). The character code driver pattern is then copied into the VDP Name Table, the screen cleared (07A1H) and all sprites cleared (06BBH). Finally the VDP mode and base addresses are set via the [SETGRP](#setgrp) standard routine and the screen is enabled.
|
|
451
|
+
|
|
452
|
+
<a name="0602h"></a><a name="setgrp"></a>
|
|
453
|
+
|
|
454
|
+
```
|
|
455
|
+
Address... 0602H
|
|
456
|
+
Name...... SETGRP
|
|
457
|
+
Entry..... None
|
|
458
|
+
Exit...... None
|
|
459
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Standard routine to partially set the VDP to [Graphics Mode](#graphics_mode). The mode bits M1, M2 and M3 are first set in VDP Mode Registers [0](#mode_register_0) and [1](#mode_register_1). The five VRAM table base addresses, beginning with [GRPNAM](#grpnam), are then copied from the Workspace Area into VDP Mode Registers [2](#mode_register_2), [3](#mode_register_3), [4](#mode_register_4), [5](#mode_register_5) and [6](#mode_register_6) ([0677H](#0677h)).
|
|
463
|
+
|
|
464
|
+
<a name="061fh"></a><a name="inimlt"></a>
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
Address... 061FH
|
|
468
|
+
Name...... INIMLT
|
|
469
|
+
Entry..... None
|
|
470
|
+
Exit...... None
|
|
471
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Standard routine to initialize the VDP to [Multicolour Mode](#multicolour_mode). The screen is temporarily disabled via the [DISSCR](#disscr) standard routine and [SCRMOD](#scrmod) set to 03H. The parameters required by the [GRPPRT](#grpprt) standard routine are set up by copying [MLTPAT](#mltpat) to [PATBAS](#patbas) and [MLTATR](#mltatr) to [ATRBAS](#atrbas). The character code driver pattern is then copied into the VDP Name Table, the screen cleared (07B9H) and all sprites cleared (06BBH). Finally the VDP mode and base addresses are set via the [SETMLT](#setmlt) standard routine and the screen is enabled.
|
|
475
|
+
|
|
476
|
+
<a name="0659h"></a><a name="setmlt"></a>
|
|
477
|
+
|
|
478
|
+
```
|
|
479
|
+
Address... 0659H
|
|
480
|
+
Name...... SETMLT
|
|
481
|
+
Entry..... None
|
|
482
|
+
Exit...... None
|
|
483
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
Standard routine to partially set the VDP to [Multicolour Mode](#multicolour_mode). The mode bits M1, M2 and M3 are first set in VDP Mode Registers [0](#mode_register_0) and [1](#mode_register_1). The five VRAM table base addresses, beginning with [MLTNAM](#mltnam), are then copied from the Workspace Area to VDP Mode Registers [2](#mode_register_2), [3](#mode_register_3), [4](#mode_register_4), [5](#mode_register_5) and [6](#mode_register_6).
|
|
487
|
+
|
|
488
|
+
<a name="0677h"></a>
|
|
489
|
+
|
|
490
|
+
Address... 0677H
|
|
491
|
+
|
|
492
|
+
This routine is used by the [SETTXT](#settxt), [SETT32](#sett32), [SETGRP](#setgrp) and [SETMLT](#setmlt) standard routines to copy a block of five table base addresses from the Workspace Area into VDP Mode Registers [2](#mode_register_2), [3](#mode_register_3), [4](#mode_register_4), [5](#mode_register_5) and [6](#mode_register_6). On entry register pair HL points to the relevant group of addresses. Each base address is collected in turn shifted the required number of places and then written to the relevant Mode Register via the [WRTVDP](#wrtvdp) standard routine.
|
|
493
|
+
|
|
494
|
+
<a name="06a8h"></a><a name="clrspr"></a>
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
Address... 06A8H
|
|
498
|
+
Name...... CLRSPR
|
|
499
|
+
Entry..... None
|
|
500
|
+
Exit...... None
|
|
501
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
Standard routine to clear all sprites. The entire 2 KB Sprite Pattern Table is first filled with zeros via the [FILVRM](#filvrm) standard routine. The vertical coordinate of each of the thirty-two sprite attribute blocks is then set to -47 (D1H) to place the sprite above the top of the screen, the horizontal coordinate is left unchanged.
|
|
505
|
+
|
|
506
|
+
The pattern numbers in the Sprite Attribute Table are initialized with the series 0, 1, 2, 3, 4,... 31 for 8x8 sprites or the series 0, 4, 8, 12, 16,... 124 for 16x16 sprites. The series to be generated is determined by the Size bit in VDP [Mode Register 1](#mode_register_1). Finally the colour byte of each sprite attribute block is filled in with the colour code contained in [FORCLR](#forclr), this is initially white.
|
|
507
|
+
|
|
508
|
+
Note that the Size and Mag bits in VDP [Mode Register 1](#mode_register_1) are not affected by this routine. Note also that the [INIT32](#init32), [INIGRP](#inigrp) and [INIMLT](#inimlt) standard routines use this routine with an entry point at 06BBH, leaving the Sprite Pattern Table undisturbed.
|
|
509
|
+
|
|
510
|
+
<a name="06e4h"></a><a name="calpat"></a>
|
|
511
|
+
|
|
512
|
+
```
|
|
513
|
+
Address... 06E4H
|
|
514
|
+
Name...... CALPAT
|
|
515
|
+
Entry..... A=Sprite pattern number
|
|
516
|
+
Exit...... HL=Sprite pattern address
|
|
517
|
+
Modifies.. AF, DE, HL
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Standard routine to calculate the address of a sprite pattern. The pattern number is first multiplied by eight then, if 16x16 sprites are selected, multiplied by a further factor of four. This is then added to the Sprite Pattern Table base address, taken from [PATBAS](#patbas), to produce the final address.
|
|
521
|
+
|
|
522
|
+
This numbering system is in line with the BASIC Interpreter's usage of pattern numbers rather than the VDP's when 16x16 sprites are selected. As an example while the Interpreter calls the second pattern number one, it is actually VDP pattern number four. This usage means that the maximum pattern number this routine should allow, when 16x16 sprites are selected, is sixty-three. There is no actual check on this limit so large pattern numbers will produce addresses greater than 3FFFH. Such addresses, when passed to the other VDP routines, will wrap around past zero and corrupt the Character Pattern Table in VRAM.
|
|
523
|
+
|
|
524
|
+
<a name="06f9h"></a><a name="calatr"></a>
|
|
525
|
+
|
|
526
|
+
```
|
|
527
|
+
Address... 06F9H
|
|
528
|
+
Name...... CALATR
|
|
529
|
+
Entry..... A=Sprite number
|
|
530
|
+
Exit...... HL=Sprite attribute address
|
|
531
|
+
Modifies.. AF, DE, HL
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Standard routine to calculate the address of a sprite attribute block. The sprite number, from zero to thirty-one, is multiplied by four and added to the Sprite Attribute Table base address taken from [ATRBAS](#atrbas).
|
|
535
|
+
|
|
536
|
+
<a name="0704h"></a><a name="gspsiz"></a>
|
|
537
|
+
|
|
538
|
+
```
|
|
539
|
+
Address... 0704H
|
|
540
|
+
Name...... GSPSIZ
|
|
541
|
+
Entry..... None
|
|
542
|
+
Exit...... A=Bytes in sprite pattern (8 or 32)
|
|
543
|
+
Modifies.. AF
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
Standard routine to return the number of bytes occupied by each sprite pattern in the Sprite Pattern Table. The result is determined simply by examining the Size bit in VDP [Mode Register 1](#mode_register_1).
|
|
547
|
+
|
|
548
|
+
<a name="070fh"></a><a name="ldirmv"></a>
|
|
549
|
+
|
|
550
|
+
```
|
|
551
|
+
Address... 070FH
|
|
552
|
+
Name...... LDIRMV
|
|
553
|
+
Entry..... BC=Length, DE=RAM address, HL=VRAM address
|
|
554
|
+
Exit...... None
|
|
555
|
+
Modifies.. AF, BC, DE, EI
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
Standard routine to copy a block into main memory from the VDP VRAM. The VRAM starting address is set via the [SETRD](#setrd) standard routine and then sequential bytes read from the VDP [Data Port](#data_port) and placed in main memory.
|
|
559
|
+
|
|
560
|
+
<a name="071eh"></a>
|
|
561
|
+
|
|
562
|
+
Address... 071EH
|
|
563
|
+
|
|
564
|
+
This routine is used to copy a 2 KB character set into the VDP Character Pattern Table in any mode. The base address of the Character Pattern Table in VRAM is taken from [CGPBAS](#cgpbas). The starting address of the character set is taken from [CGPNT](#cgpnt). The [RDSLT](#rdslt) standard routine is used to read the character data so this may be situated in an extension ROM.
|
|
565
|
+
|
|
566
|
+
At power-up [CGPNT](#cgpnt) is initialized with the address contained at ROM location 0004H, which is [1BBFH](#1bbfh). [CGPNT](#cgpnt) is easily altered to produce some interesting results, `POKE &HF920,&HC7:SCREEN 0` provides a thoroughly confusing example.
|
|
567
|
+
|
|
568
|
+
<a name="0744h"></a><a name="ldirvm"></a>
|
|
569
|
+
|
|
570
|
+
```
|
|
571
|
+
Address... 0744H
|
|
572
|
+
Name...... LDIRVM
|
|
573
|
+
Entry..... BC=Length, DE=VRAM address, HL=RAM address
|
|
574
|
+
Exit...... None
|
|
575
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Standard routine to copy a block to VRAM from main memory. The VRAM starting address is set via the [SETWRT](#setwrt) standard routine and then sequential bytes taken from main memory and written to the VDP [Data Port](#data_port).
|
|
579
|
+
|
|
580
|
+
<a name="0777h"></a>
|
|
581
|
+
|
|
582
|
+
Address... 0777H
|
|
583
|
+
|
|
584
|
+
This routine will clear the screen in any VDP mode. In [40x24 Text Mode](#40x24_text_mode) and [32x24 Text Mode](#32x24_text_mode) the Name Table, whose base address is taken from [NAMBAS](#nambas), is first filled with ASCII spaces. The cursor is then set to the home position ([0A7FH](#0a7fh)) and [LINTTB](#linttb), the line termination table, re-initialized. Finally the function key display is restored, if it is enabled, via the [FNKSB](#fnksb) standard routine.
|
|
585
|
+
|
|
586
|
+
In [Graphics Mode](#graphics_mode) the border colour is first set via VDP [Mode Register 7](#mode_register_7) (0832H). The Colour Table is then filled with the background colour code, taken from [BAKCLR](#bakclr), for both 0 and 1 pixels. Finally the Character Pattern Table is filled with zeroes.
|
|
587
|
+
|
|
588
|
+
In [Multicolour Mode](#multicolour_mode) the border colour is first set via VDP [Mode Register 7](#mode_register_7) (0832H). The Character Pattern Table is then filled with the background colour taken from [BAKCLR](#bakclr).
|
|
589
|
+
|
|
590
|
+
<a name="07cdh"></a><a name="wrtvrm"></a>
|
|
591
|
+
|
|
592
|
+
```
|
|
593
|
+
Address... 07CDH
|
|
594
|
+
Name...... WRTVRM
|
|
595
|
+
Entry..... A=Data byte, HL=VRAM address
|
|
596
|
+
Exit...... None
|
|
597
|
+
Modifies.. EI
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
Standard routine to write a single byte to the VDP VRAM. The VRAM address is first set up via the [SETWRT](#setwrt) standard routine and then the data byte written to the VDP [Data Port](#data_port). Note that the two seemingly spurious `EX(SP),HL` instructions in this routine, and several others, are required to meet the VDP's timing constraints.
|
|
601
|
+
|
|
602
|
+
<a name="07d7h"></a><a name="rdvrm"></a>
|
|
603
|
+
|
|
604
|
+
```
|
|
605
|
+
Address... 07D7H
|
|
606
|
+
Name...... RDVRM
|
|
607
|
+
Entry..... HL=VRAM address
|
|
608
|
+
Exit...... A=Byte read
|
|
609
|
+
Modifies.. AF, EI
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
Standard routine to read a single byte from the VDP VRAM. The VRAM address is first set up via the [SETRD](#setrd) standard routine and then the byte read from the VDP [Data Port](#data_port).
|
|
613
|
+
|
|
614
|
+
<a name="07dfh"></a><a name="setwrt"></a>
|
|
615
|
+
|
|
616
|
+
```
|
|
617
|
+
Address... 07DFH
|
|
618
|
+
Name...... SETWRT
|
|
619
|
+
Entry..... HL=VRAM address
|
|
620
|
+
Exit...... None
|
|
621
|
+
Modifies.. AF, EI
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
Standard routine to set up the VDP for subsequent writes to VRAM via the [Data Port](#data_port). The address contained in register pair HL is written to the VDP [Command Port](#command_port) LSB first, MSB second as shown in [Figure 7](#figure7). Addresses greater than 3FFFH will wrap around past zero as the two most significant bits of the address are ignored.
|
|
625
|
+
|
|
626
|
+
<a name="07ech"></a><a name="setrd"></a>
|
|
627
|
+
|
|
628
|
+
```
|
|
629
|
+
Address... 07ECH
|
|
630
|
+
Name...... SETRD
|
|
631
|
+
Entry..... HL=VRAM address
|
|
632
|
+
Exit...... None
|
|
633
|
+
Modifies.. AF, EI
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Standard routine to set up the VDP for subsequent reads from VRAM via the [Data Port](#data_port). The address contained in register pair HL is written to the VDP [Command Port](#command_port) LSB first, MSB second as shown in [Figure 7](#figure7). Addresses greater than 3FFFH will wrap around past zero as the two most significant bits of the address are ignored.
|
|
637
|
+
|
|
638
|
+
<a name="07f7h"></a><a name="chgclr"></a>
|
|
639
|
+
|
|
640
|
+
```
|
|
641
|
+
Address... 07F7H
|
|
642
|
+
Name...... CHGCLR
|
|
643
|
+
Entry..... None
|
|
644
|
+
Exit...... None
|
|
645
|
+
Modifies.. AF, BC, HL, EI
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Standard routine to set the VDP colours. [SCRMOD](#scrmod) is first examined to determine the appropriate course of action. In [40x24 Text Mode](#40x24_text_mode) the contents of [BAKCLR](#bakclr) and [FORCLR](#forclr) are written to VDP [Mode Register 7](#mode_register_7) to set the colour of the 0 and 1 pixels, these are initially blue and white. Note that in this mode there is no way of specifying the border colour, this will be the same as the 0 pixel colour. In [32x24 Text Mode](#32x24_text_mode), [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode) the contents of [BDRCLR](#bdrclr) are written to VDP [Mode Register 7](#mode_register_7) to set the colour of the border, this is initially blue. Also in [32x24 Text Mode](#32x24_text_mode) the contents of [BAKCLR](#bakclr) and [FORCLR](#forclr) are copied to the whole of the Colour Table to determine the 0 and 1 pixel colours.
|
|
649
|
+
|
|
650
|
+
<a name="0815h"></a><a name="filvrm"></a>
|
|
651
|
+
|
|
652
|
+
```
|
|
653
|
+
Address... 0815H
|
|
654
|
+
Name...... FILVRM
|
|
655
|
+
Entry..... A=Data byte, BC=Length, HL=VRAM address
|
|
656
|
+
Exit...... None
|
|
657
|
+
Modifies.. AF, BC, EI
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
Standard routine to fill a block of the VDP VRAM with a single data byte. The VRAM starting address, contained in register pair HL, is first set up via the [SETWRT](#setwrt) standard routine. The data byte is then repeatedly written to the VDP [Data Port](#data_port) to fill successive VRAM locations.
|
|
661
|
+
|
|
662
|
+
<a name="083bh"></a><a name="totext"></a>
|
|
663
|
+
|
|
664
|
+
```
|
|
665
|
+
Address... 083BH
|
|
666
|
+
Name...... TOTEXT
|
|
667
|
+
Entry..... None
|
|
668
|
+
Exit...... None
|
|
669
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
Standard routine to return the VDP to either [40x24 Text Mode](#40x24_text_mode) or [32x24 Text Mode](#32x24_text_mode) if it is currently in [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode). It is used by the BASIC Interpreter Mainloop and by the "[INPUT](#input)" statement handler. Whenever the [INITXT](#initxt) or [INIT32](#init32) standard routines are used the mode byte, 00H or 01H, is copied into [OLDSCR](#oldscr). If the mode is subsequently changed to [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode), and then has to be returned to one of the two text modes for keyboard input, this routine ensures that it returns to the same one.
|
|
673
|
+
|
|
674
|
+
[SCRMOD](#scrmod) is first examined and, if the screen is already in either text mode, the routine simply terminates with no action. Otherwise the previous text mode is taken from [OLDSCR](#oldscr) and passed to the [CHGMOD](#chgmod) standard routine.
|
|
675
|
+
|
|
676
|
+
<a name="0848h"></a><a name="cls"></a>
|
|
677
|
+
|
|
678
|
+
```
|
|
679
|
+
Address... 0848H
|
|
680
|
+
Name...... CLS
|
|
681
|
+
Entry..... Flag Z
|
|
682
|
+
Exit...... None
|
|
683
|
+
Modifies.. AF, BC, DE, EI
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
Standard routine to clear the screen in any mode, it does nothing but call the routine at 0777H. This is actually the "`CLS`" statement handler and, because this indicates that there is illegal text after the statement, it will simply return if entered with Flag NZ.
|
|
687
|
+
|
|
688
|
+
<a name="084fh"></a><a name="chgmod"></a>
|
|
689
|
+
|
|
690
|
+
```
|
|
691
|
+
Address... 084FH
|
|
692
|
+
Name...... CHGMOD
|
|
693
|
+
Entry..... A=Screen mode required (0, 1, 2, 3)
|
|
694
|
+
Exit...... None
|
|
695
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
Standard routine to set a new screen mode. Register A, containing the required screen mode, is tested and control transferred to [INITXT](#initxt), [INIT32](#init32), [INIGRP](#inigrp) or [INIMLT](#inimlt).
|
|
699
|
+
|
|
700
|
+
<a name="085dh"></a><a name="lptout"></a>
|
|
701
|
+
|
|
702
|
+
```
|
|
703
|
+
Address... 085DH
|
|
704
|
+
Name...... LPTOUT
|
|
705
|
+
Entry..... A=Character to print
|
|
706
|
+
Exit...... Flag C if CTRL-STOP termination
|
|
707
|
+
Modifies.. AF
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
Standard routine to output a character to the line printer via the Centronics Port. The printer status is continually tested, via the [LPTSTT](#lptstt) standard routine, until the printer becomes free. The character is then written to the Centronics Data Port (I/O port 91H) and the [STROBE](#strobe) signal of the Centronics Status Port (I/O port 90H) briefly pulsed low. Note that the [BREAKX](#breakx) standard routine is used to test for the CTRL-STOP key if the printer is busy. If CTRL-STOP is detected a CR code is written to the Centronics Data Port, to flush the printer's line buffer, and the routine terminates with Flag C.
|
|
711
|
+
|
|
712
|
+
<a name="0884h"></a><a name="lptstt"></a>
|
|
713
|
+
|
|
714
|
+
```
|
|
715
|
+
Address... 0884H
|
|
716
|
+
Name...... LPTSTT
|
|
717
|
+
Entry..... None
|
|
718
|
+
Exit...... A=0 and Flag Z if printer busy
|
|
719
|
+
Modifies.. AF
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
Standard routine to test the Centronics Status Port BUSY signal. This just involves reading I/O port 90H and examining the state of bit 1: 0=Ready, 1=Busy.
|
|
723
|
+
|
|
724
|
+
<a name="088eh"></a><a name="posit"></a>
|
|
725
|
+
|
|
726
|
+
```
|
|
727
|
+
Address... 088EH
|
|
728
|
+
Name...... POSIT
|
|
729
|
+
Entry..... H=Column, L=Row
|
|
730
|
+
Exit...... None
|
|
731
|
+
Modifies.. AF, EI
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
Standard routine to set the cursor coordinates. The row and column coordinates are sent to the [OUTDO](#outdo) standard routine as the parameters in an ESC,"Y",Row+1FH, Column+1FH sequence. Note that the BIOS home position has coordinates of 1,1 rather than the 0,0 used by the BASIC Interpreter.
|
|
735
|
+
|
|
736
|
+
<a name="089dh"></a><a name="cnvchr"></a>
|
|
737
|
+
|
|
738
|
+
```
|
|
739
|
+
Address... 089DH
|
|
740
|
+
Name...... CNVCHR
|
|
741
|
+
Entry..... A=Character
|
|
742
|
+
Exit...... Flag Z,NC=Header; Flag NZ,C=Graphic; Flag Z,C=Normal
|
|
743
|
+
Modifies.. AF
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
Standard routine to test for, and convert if necessary, characters with graphic headers. Characters less than 20H are normally interpreted by the output device drivers as control characters. A character code in this range can be treated as a displayable character by preceding it with a graphic header control code (01H) and adding 40H to its value. For example to directly display character code 0DH, rather than have it interpreted as a carriage return, it is necessary to output the two bytes 01H,4DH. This routine is used by the output device drivers, such as the [CHPUT](#chput) standard routine, to check for such sequences.
|
|
747
|
+
|
|
748
|
+
If the character is a graphic header [GRPHED](#grphed) is set to 01H and the routine terminates, otherwise [GRPHED](#grphed) is zeroed. If the character is outside the range 40H to 5FH it is left unchanged. If it is inside this range, and [GRPHED](#grphed) contains 01H indicating a previous graphic header, it is converted by subtracting 40H.
|
|
749
|
+
|
|
750
|
+
<a name="08bch"></a><a name="chput"></a>
|
|
751
|
+
|
|
752
|
+
```
|
|
753
|
+
Address... 08BCH
|
|
754
|
+
Name...... CHPUT
|
|
755
|
+
Entry..... A=Character
|
|
756
|
+
Exit...... None
|
|
757
|
+
Modifies.. EI
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
Standard routine to output a character to the screen in [40x24 Text Mode](#40x24_text_mode) or [32x24 Text Mode](#32x24_text_mode). [SCRMOD](#scrmod) is first checked and, if the VDP is in either [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode), the routine terminates with no action. Otherwise the cursor is removed ([0A2EH](#0a2eh)), the character decoded ([08DFH](#08dfh)) and then the cursor replaced ([09E1H](#09e1h)). Finally the cursor column position is placed in [TTYPOS](#ttypos), for use by the "`PRINT`" statement, and the routine terminates.
|
|
761
|
+
|
|
762
|
+
<a name="08dfh"></a>
|
|
763
|
+
|
|
764
|
+
Address... 08DFH
|
|
765
|
+
|
|
766
|
+
This routine is used by the [CHPUT](#chput) standard routine to decode a character and take the appropriate action. The [CNVCHR](#cnvchr) standard routine is first used to check for a graphic character, if the character is a header code (01H) then the routine terminates with no action. If the character is a converted graphic one then the control code decoding section is skipped. Otherwise [ESCCNT](#esccnt) is checked to see if a previous ESC character (1BH) has been received, if so control transfers to the ESC sequence processor ([098FH](#098fh)). Otherwise the character is checked to see if it is smaller than 20H, if so control transfers to the control code processor ([0914H](#0914h)). The character is then checked to see if it is DEL (7FH), if so control transfers to the delete routine (0AE3H).
|
|
767
|
+
|
|
768
|
+
Assuming the character is displayable the cursor coordinates are taken from [CSRY](#csry) and [CSRX](#csrx) and placed in register pair HL, H=Column, L=Row. These are then converted to a physical address in the VDP Name Table and the character placed there ([0BE6H](#0be6h)). The cursor column position is then incremented ([0A44H](#0a44h)) and, assuming the rightmost column has not been exceeded, the routine terminates. Otherwise the row's entry in [LINTTB](#linttb), the line termination table, is zeroed to indicate an extended logical line, the column number is set to 01H and a LF is performed.
|
|
769
|
+
|
|
770
|
+
<a name="0908h"></a>
|
|
771
|
+
|
|
772
|
+
Address... 0908H
|
|
773
|
+
|
|
774
|
+
This routine performs the LF operation for the [CHPUT](#chput) standard routine control code processor. The cursor row is incremented ([0A61H](#0a61h)) and, assuming the lowest row has not been exceeded, the routine terminates. Otherwise the screen is scrolled upwards and the lowest row erased (0A88H).
|
|
775
|
+
|
|
776
|
+
<a name="0914h"></a>
|
|
777
|
+
|
|
778
|
+
Address... 0914H
|
|
779
|
+
|
|
780
|
+
This is the control code processor for the [CHPUT](#chput) standard routine. The table at [092FH](#092fh) is searched for a match with the code and control transferred to the associated address.
|
|
781
|
+
|
|
782
|
+
<a name="092fh"></a>
|
|
783
|
+
|
|
784
|
+
Address... 092FH
|
|
785
|
+
|
|
786
|
+
This table contains the control codes, each with an associated address, recognized by the [CHPUT](#chput) standard routine:
|
|
787
|
+
|
|
788
|
+
|CODE |TO |FUNCTION
|
|
789
|
+
|:---:|:-----:|--------------------------------
|
|
790
|
+
|07H |1113H |BELL, go beep
|
|
791
|
+
|08H |0A4CH |BS, cursor left
|
|
792
|
+
|09H |0A71H |TAB, cursor to next tab position
|
|
793
|
+
|0AH |0908H |LF, cursor down a row
|
|
794
|
+
|0BH |0A7FH |HOME, cursor to home
|
|
795
|
+
|0CH |077EH |FORMFEED, clear screen and home
|
|
796
|
+
|0DH |0A81H |CR, cursor to leftmost column
|
|
797
|
+
|1BH |0989H |ESC, enter escape sequence
|
|
798
|
+
|1CH |0A5BH |RIGHT, cursor right
|
|
799
|
+
|1DH |0A4CH |LEFT, cursor left
|
|
800
|
+
|1EH |0A57H |UP, cursor up
|
|
801
|
+
|1FH |0A61H |DOWN, cursor down.
|
|
802
|
+
|
|
803
|
+
</a>
|
|
804
|
+
|
|
805
|
+
<a name="0953h"></a>
|
|
806
|
+
|
|
807
|
+
Address... 0953H
|
|
808
|
+
|
|
809
|
+
This table contains the ESC control codes, each with an associated address, recognized by the [CHPUT](#chput) standard routine:
|
|
810
|
+
|
|
811
|
+
|CODE |TO |FUNCTION
|
|
812
|
+
|:---:|:-----:|-------------------------------
|
|
813
|
+
|6AH |077EH |ESC,"j", clear screen and home
|
|
814
|
+
|45H |077EH |ESC,"E", clear screen and home
|
|
815
|
+
|4BH |0AEEH |ESC,"K", clear to end of line
|
|
816
|
+
|4AH |0B05H |ESC,"J", clear to end of screen
|
|
817
|
+
|6CH |0AECH |ESC,"l", clear line
|
|
818
|
+
|4CH |0AB4H |ESC,"L", insert line
|
|
819
|
+
|4DH |0A85H |ESC,"M", delete line
|
|
820
|
+
|59H |0986H |ESC,"Y", set cursor coordinates
|
|
821
|
+
|41H |0A57H |ESC,"A", cursor up
|
|
822
|
+
|42H |0A61H |ESC,"B", cursor down
|
|
823
|
+
|43H |0A44H |ESC,"C", cursor right
|
|
824
|
+
|44H |0A55H |ESC,"D", cursor left
|
|
825
|
+
|48H |0A7FH |ESC,"H", cursor home
|
|
826
|
+
|78H |0980H |ESC,"x", change cursor
|
|
827
|
+
|79H |0983H |ESC,"y", change cursor
|
|
828
|
+
|
|
829
|
+
</a>
|
|
830
|
+
|
|
831
|
+
<a name="0980h"></a>
|
|
832
|
+
|
|
833
|
+
Address... 0980H
|
|
834
|
+
|
|
835
|
+
This routine performs the ESC,"x" operation for the [CHPUT](#chput) standard routine control code processor. [ESCCNT](#esccnt) is set to 01H to indicate that the next character received is a parameter.
|
|
836
|
+
|
|
837
|
+
<a name="0983h"></a>
|
|
838
|
+
|
|
839
|
+
Address... 0983H
|
|
840
|
+
|
|
841
|
+
This routine performs the ESC,"y" operation for the [CHPUT](#chput) standard routine control code decoder. [ESCCNT](#esccnt) is set to 02H to indicate that the next character received is a parameter.
|
|
842
|
+
|
|
843
|
+
<a name="0986h"></a>
|
|
844
|
+
|
|
845
|
+
Address... 0986H
|
|
846
|
+
|
|
847
|
+
This routine performs the ESC",Y" operation for the [CHPUT](#chput) standard routine control code processor. [ESCCNT](#esccnt) is set to 04H to indicate that the next character received is a parameter.
|
|
848
|
+
|
|
849
|
+
<a name="0989h"></a>
|
|
850
|
+
|
|
851
|
+
Address... 0989H
|
|
852
|
+
|
|
853
|
+
This routine performs the ESC operation for the [CHPUT](#chput) standard routine control code processor. [ESCCNT](#esccnt) is set to FFH to indicate that the next character received is the second control character.
|
|
854
|
+
|
|
855
|
+
<a name="098fh"></a>
|
|
856
|
+
|
|
857
|
+
Address... 098FH
|
|
858
|
+
|
|
859
|
+
This is the [CHPUT](#chput) standard routine ESC sequence processor. If [ESCCNT](#esccnt) contains FFH then the character is the second control character and control transfers to the control code processor (0919H) to search the ESC code table at [0953H](#0953h).
|
|
860
|
+
|
|
861
|
+
If [ESCCNT](#esccnt) contains 01H then the character is the single parameter of the ESC,"x" sequence. If the parameter is "4" (34H) then [CSTYLE](#cstyle) is set to 00H resulting in a block cursor. If the parameter is "5" (35H) then [CSRSW](#csrsw) is set to 00H making the cursor normally disabled.
|
|
862
|
+
|
|
863
|
+
If [ESCCNT](#esccnt) contains 02H then the character is the single parameter in the ESC,"y" sequence. If the parameter is "4" (34H) then [CSTYLE](#cstyle) is set to 01H resulting in an underline cursor. If the parameter is "5" (35H) then [CSRSW](#csrsw) is set to 01H making the cursor normally enabled.
|
|
864
|
+
|
|
865
|
+
If [ESCCNT](#esccnt) contains 04H then the character is the first parameter of the ESC,"Y" sequence and is the row coordinate. The parameter has 1FH subtracted and is placed in [CSRY](#csry), [ESCCNT](#esccnt) is then decremented to 03H.
|
|
866
|
+
|
|
867
|
+
If [ESCCNT](#esccnt) contains 03H then the character is the second parameter of the ESC,"Y" sequence and is the column coordinate. The parameter has 1FH subtracted and is placed in [CSRX](#csrx).
|
|
868
|
+
|
|
869
|
+
<a name="09dah"></a>
|
|
870
|
+
|
|
871
|
+
Address... 09DAH
|
|
872
|
+
|
|
873
|
+
This routine is used, by the [CHGET](#chget) standard routine for example, to display the cursor character when it is normally disabled. If [CSRSW](#csrsw) is non-zero the routine simply terminates with no action, otherwise the cursor is displayed (09E6H).
|
|
874
|
+
|
|
875
|
+
<a name="09e1h"></a>
|
|
876
|
+
|
|
877
|
+
Address... 09E1H
|
|
878
|
+
|
|
879
|
+
This routine is used, by the [CHPUT](#chput) standard routine for example, to display the cursor character when it is normally enabled. If [CSRSW](#csrsw) is zero the routine simply terminates with no action. [SCRMOD](#scrmod) is checked and, if the screen is in [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode), the routine terminates with no action. Otherwise the cursor coordinates are converted to a physical address in the VDP Name Table and the character read from that location ([0BD8H](#0bd8h)) and saved in [CURSAV](#cursav).
|
|
880
|
+
|
|
881
|
+
The character's eight byte pixel pattern is read from the VDP Character Pattern Table into the [LINWRK](#linwrk) buffer ([0BA5H](#0ba5h)). The pixel pattern is then inverted, all eight bytes if [CSTYLE](#cstyle) indicates a block cursor, only the bottom three if [CSTYLE](#cstyle) indicates an underline cursor. The pixel pattern is copied back to the position for character code 255 in the VDP Character Pattern Table ([0BBEH](#0bbeh)). The character code 255 is then placed at the current cursor location in the VDP Name Table ([0BE6H](#0be6h)) and the routine terminates.
|
|
882
|
+
|
|
883
|
+
This method of generating the cursor character, by using character code 255, can produce curious effects under certain conditions. These can be demonstrated by executing the BASIC statement `FOR N=1 TO 100: PRINT CHR$(255);:NEXT` and then pressing the cursor up key.
|
|
884
|
+
|
|
885
|
+
<a name="0a27h"></a>
|
|
886
|
+
|
|
887
|
+
Address... 0A27H
|
|
888
|
+
|
|
889
|
+
This routine is used, by the [CHGET](#chget) standard routine for example, to remove the cursor character when it is normally disabled. If [CSRSW](#csrsw) is non-zero the routine simply terminates with no action, otherwise the cursor is removed (0A33H).
|
|
890
|
+
|
|
891
|
+
<a name="0a2eh"></a>
|
|
892
|
+
|
|
893
|
+
Address... 0A2EH
|
|
894
|
+
|
|
895
|
+
This routine is used, by the [CHPUT](#chput) standard routine for example, .to remove the cursor character when it is normally enabled. If [CSRSW](#csrsw) is zero the routine simply terminates with no action. [SCRMOD](#scrmod) is checked and, if the screen is in [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode), the routine terminates with no action. Otherwise the cursor coordinates are converted to a physical address in the VDP Name Table and the character held in [CURSAV](#cursav) written to that location ([0BE6H](#0be6h)).
|
|
896
|
+
|
|
897
|
+
<a name="0a44h"></a>
|
|
898
|
+
|
|
899
|
+
Address... 0A44H
|
|
900
|
+
|
|
901
|
+
This routine performs the ESC,"C" operation for the [CHPUT](#chput) standard routine control code processor. If the cursor column coordinate is already at the rightmost column, determined by [LINLEN](#linlen), then the routine terminates with no action. Otherwise the column coordinate is incremented and [CSRX](#csrx) updated.
|
|
902
|
+
|
|
903
|
+
<a name="0a4ch"></a>
|
|
904
|
+
|
|
905
|
+
Address... 0A4CH
|
|
906
|
+
|
|
907
|
+
This routine performs the BS/LEFT operation for the [CHPUT](#chput) standard routine control code processor. The cursor column coordinate is decremented and [CSRX](#csrx) updated. If the column coordinate has moved beyond the leftmost position it is set to the rightmost position, from [LINLEN](#linlen), and an UP operation performed.
|
|
908
|
+
|
|
909
|
+
<a name="0a55h"></a>
|
|
910
|
+
|
|
911
|
+
Address... 0A55H
|
|
912
|
+
|
|
913
|
+
This routine performs the ESC,"D" operation for the [CHPUT](#chput) standard routine control code processor. If the cursor column coordinate is already at the leftmost position then the routine terminates with no action. Otherwise the column coordinate is decremented and [CSRX](#csrx) updated.
|
|
914
|
+
|
|
915
|
+
<a name="0a57h"></a>
|
|
916
|
+
|
|
917
|
+
Address... 0A57H
|
|
918
|
+
|
|
919
|
+
This routine performs the ESC,"A" (UP) operation for the [CHPUT](#chput) standard routine control code processor. If the cursor row coordinate is already at the topmost position the routine terminates with no action. Otherwise the row coordinate is decremented and [CSRY](#csry) updated.
|
|
920
|
+
|
|
921
|
+
<a name="0a5bh"></a>
|
|
922
|
+
|
|
923
|
+
Address... 0A5BH
|
|
924
|
+
|
|
925
|
+
This routine performs the RIGHT operation for the [CHPUT](#chput) standard routine control code processor. The cursor column coordinate is incremented and [CSRX](#csrx) updated. If the column coordinate has moved beyond the rightmost position, determined by [LINLEN](#linlen), it is set to the leftmost position (01H) and a DOWN operation performed.
|
|
926
|
+
|
|
927
|
+
<a name="0a61h"></a>
|
|
928
|
+
|
|
929
|
+
Address... 0A61H
|
|
930
|
+
|
|
931
|
+
This routine performs the ESC,"B" (DOWN) operation for the [CHPUT](#chput) standard routine control code processor. If the cursor row coordinate is already at the lowest position, determined by [CRTCNT](#crtcnt) and [CNSDFG](#cnsdfg) ([0C32H](#0c32h)), then the routine terminates with no action. Otherwise the row coordinate is incremented and [CSRY](#csry) updated.
|
|
932
|
+
|
|
933
|
+
<a name="0a71h"></a>
|
|
934
|
+
|
|
935
|
+
Address... 0A71H
|
|
936
|
+
|
|
937
|
+
This routine performs the TAB operation for the [CHPUT](#chput) standard routine control code processor. ASCII spaces are output ([08DFH](#08dfh)) until [CSRX](#csrx) is a multiple of eight plus one (BIOS columns 1, 9, 17, 25, 33).
|
|
938
|
+
|
|
939
|
+
<a name="0a7fh"></a>
|
|
940
|
+
|
|
941
|
+
Address... 0A7FH
|
|
942
|
+
|
|
943
|
+
This routine performs the ESC,"H" (HOME) operation for the [CHPUT](#chput) standard routine control code processor, [CSRX](#csrx) and [CSRY](#csry) are simply set to 1,1. The ROM BIOS cursor coordinate system, while functionally identical to that used by the BASIC Interpreter, numbers the screen rows from 1 to 24 and the columns from 1 to 32/40.
|
|
944
|
+
|
|
945
|
+
<a name="0a81h"></a>
|
|
946
|
+
|
|
947
|
+
Address... 0A81H
|
|
948
|
+
|
|
949
|
+
This routine performs the CR operation for the [CHPUT](#chput) standard routine control code processor, [CSRX](#csrx) is simply set to 01H .
|
|
950
|
+
|
|
951
|
+
<a name="0a85h"></a>
|
|
952
|
+
|
|
953
|
+
Address... 0A85H
|
|
954
|
+
|
|
955
|
+
This routine performs the ESC,"M" function for the [CHPUT](#chput) standard routine control code processor. A CR operation is first performed to set the cursor column coordinate to the leftmost position. The number of rows from the current row to the bottom of the screen is then determined, if this is zero the current row is simply erased ([0AECH](#0aech)). The row count is first used to scroll up the relevant section of [LINTTB](#linttb), the line termination table, by one byte. It is then used to scroll up the relevant section of the screen a row at a time. Starting at the row below the current row, each line is copied from the VDP Name Table into the [LINWRK](#linwrk) buffer ([0BAAH](#0baah)) then copied back to the Name Table one row higher ([0BC3H](#0bc3h)). Finally the lowest row on the screen is erased ([0AECH](#0aech)).
|
|
956
|
+
|
|
957
|
+
<a name="0ab4h"></a>
|
|
958
|
+
|
|
959
|
+
Address... 0AB4H
|
|
960
|
+
|
|
961
|
+
This routine performs the ESC,"L" operation for the [CHPUT](#chput) standard routine control code processor. A CR operation is first performed to set the cursor column coordinate to the leftmost position. The number of rows from the current row to the bottom of the screen is then determined, if this is zero the current row is simply erased ([0AECH](#0aech)). The row count is first used to scroll down the relevant section of [LINTTB](#linttb), the line termination table, by one byte. It is then used to scroll down the relevant section of the screen a row at a time. Starting at the next to last row of the screen, each line is copied from the VDP Name Table into the [LINWRK](#linwrk) buffer ([0BAAH](#0baah)), then copied back to the Name Table one row lower ([0BC3H](#0bc3h)). Finally the current row is erased ([0AECH](#0aech)).
|
|
962
|
+
|
|
963
|
+
Address... 0AE3H
|
|
964
|
+
|
|
965
|
+
This routine is used to perform the DEL operation for the [CHPUT](#chput) standard routine control code processor. A LEFT operation is first performed. If this cannot be completed, because the cursor is already at the home position, then the routine terminates with no action. Otherwise a space is written to the VDP Name Table at the cursor's physical location ([0BE6H](#0be6h)).
|
|
966
|
+
|
|
967
|
+
<a name="0aech"></a>
|
|
968
|
+
|
|
969
|
+
Address... 0AECH
|
|
970
|
+
|
|
971
|
+
This routine performs the ESC,"l" operation for the [CHPUT](#chput) standard routine control code processor. The cursor column coordinate is set to 01H and control drops into the ESC,"K" routine.
|
|
972
|
+
|
|
973
|
+
<a name="0aeeh"></a>
|
|
974
|
+
|
|
975
|
+
Address... 0AEEH
|
|
976
|
+
|
|
977
|
+
This routine performs the ESC,"K" operation for the [CHPUT](#chput) standard routine control code processor. The row's entry in [LINTTB](#linttb), the line termination table, is first made non-zero to indicate that the logical line is not extended ([0C29H](#0c29h)). The cursor coordinates are converted to a physical address (0BF2H) in the VDP Name Table and the VDP set up for writes via the [SETWRT](#setwrt) standard routine. Spaces are then written directly to the VDP [Data Port](#data_port) until the rightmost column, determined by [LINLEN](#linlen), is reached.
|
|
978
|
+
|
|
979
|
+
Address... 0B05H
|
|
980
|
+
|
|
981
|
+
This routine performs the ESC,"J" operation for the [CHPUT](#chput) standard routine control code processor. An ESC,"K" operation is performed on successive rows, starting with the current one, until the bottom of the screen is reached.
|
|
982
|
+
|
|
983
|
+
<a name="0b15h"></a><a name="erafnk"></a>
|
|
984
|
+
|
|
985
|
+
```
|
|
986
|
+
Address... 0B15H
|
|
987
|
+
Name...... ERAFNK
|
|
988
|
+
Entry..... None
|
|
989
|
+
Exit...... None
|
|
990
|
+
Modifies.. AF, DE, EI
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
Standard routine to turn the function key display off. [CNSDFG](#cnsdfg) is first zeroed and, if the VDP is in [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode), the routine terminates with no further action. If the VDP is in [40x24 Text Mode](#40x24_text_mode) or [32x24 Text Mode](#32x24_text_mode) the last row on the screen is then erased ([0AECH](#0aech)).
|
|
994
|
+
|
|
995
|
+
<a name="0b26h"></a><a name="fnksb"></a>
|
|
996
|
+
|
|
997
|
+
```
|
|
998
|
+
Address... 0B26H
|
|
999
|
+
Name...... FNKSB
|
|
1000
|
+
Entry..... None
|
|
1001
|
+
Exit...... None
|
|
1002
|
+
Modifies.. AF, BC, DE, EI
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
Standard routine to show the function key display if it is enabled. If [CNSDFG](#cnsdfg) is zero the routine terminates with no action, otherwise control drops into the [DSPFNK](#dspfnk) standard routine..
|
|
1006
|
+
|
|
1007
|
+
<a name="0b2bh"></a><a name="dspfnk"></a>
|
|
1008
|
+
|
|
1009
|
+
```
|
|
1010
|
+
Address... 0B2BH
|
|
1011
|
+
Name...... DSPFNK
|
|
1012
|
+
Entry..... None
|
|
1013
|
+
Exit...... None
|
|
1014
|
+
Modifies.. AF, BC, DE, EI
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
Standard routine to turn the function key display on. [CNSDFG](#cnsdfg) is set to FFH and, if the VDP is in [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode), the routine terminates with no further action. Otherwise the cursor row coordinate is checked and, if the cursor is on the last row of the screen, a LF code (0AH) issued to the [OUTDO](#outdo) standard routine to scroll the screen up.
|
|
1018
|
+
|
|
1019
|
+
Register pair HL is then set to point to either the unshifted or shifted function strings in the Workspace Area depending upon whether the SHIFT key is pressed. [LINLEN](#linlen) has four subtracted, to allow a minimum of one space between fields, and is divided by five to determine the field size for each string. Successive characters are then taken from each function string, checked for graphic headers via the [CNVCHR](#cnvchr) standard routine and placed in the [LINWRK](#linwrk) buffer until the string is exhausted or the zone is filled. When all five strings are completed the [LINWRK](#linwrk) buffer is written to the last row in the VDP Name Table ([0BC3H](#0bc3h)).
|
|
1020
|
+
|
|
1021
|
+
<a name="0b9ch"></a>
|
|
1022
|
+
|
|
1023
|
+
Address... 0B9CH
|
|
1024
|
+
|
|
1025
|
+
This routine is used by the function key display related standard routines. The contents of register A are placed in [CNSDFG](#cnsdfg) then [SCRMOD](#scrmod) tested and Flag NC returned if the screen is in [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode).
|
|
1026
|
+
|
|
1027
|
+
<a name="0ba5h"></a>
|
|
1028
|
+
|
|
1029
|
+
Address... 0BA5H
|
|
1030
|
+
|
|
1031
|
+
This routine copies eight bytes from the VDP VRAM into the [LINWRK](#linwrk) buffer, the VRAM physical address is supplied in register pair HL.
|
|
1032
|
+
|
|
1033
|
+
<a name="0baah"></a>
|
|
1034
|
+
|
|
1035
|
+
Address... 0BAAH
|
|
1036
|
+
|
|
1037
|
+
This routine copies a complete row of characters, with the length determined by [LINLEN](#linlen), from the VDP VRAM into the [LINWRK](#linwrk) buffer. The cursor row coordinate is supplied in register L.
|
|
1038
|
+
|
|
1039
|
+
<a name="0bbeh"></a>
|
|
1040
|
+
|
|
1041
|
+
Address... 0BBEH
|
|
1042
|
+
|
|
1043
|
+
This routine copies eight bytes from the [LINWRK](#linwrk) buffer into the VDP VRAM, the VRAM physical address is supplied in register pair HL.
|
|
1044
|
+
|
|
1045
|
+
<a name="0bc3h"></a>
|
|
1046
|
+
|
|
1047
|
+
Address... 0BC3H
|
|
1048
|
+
|
|
1049
|
+
This routine copies a complete row of characters, with the length determined by [LINLEN](#linlen), from the [LINWRK](#linwrk) buffer into the VDP VRAM. The cursor row coordinate is supplied in register L.
|
|
1050
|
+
|
|
1051
|
+
<a name="0bd8h"></a>
|
|
1052
|
+
|
|
1053
|
+
Address... 0BD8H
|
|
1054
|
+
|
|
1055
|
+
This routine reads a single byte from the VDP VRAM into register C. The column coordinate is supplied in register H, the row coordinate in register L.
|
|
1056
|
+
|
|
1057
|
+
<a name="0be6h"></a>
|
|
1058
|
+
|
|
1059
|
+
Address... 0BE6H
|
|
1060
|
+
|
|
1061
|
+
This routine converts a pair of screen coordinates, the column in register H and the row in register L, into a physical address in the VDP Name Table. This address is returned in register pair HL.
|
|
1062
|
+
|
|
1063
|
+
The row coordinate is first multiplied by thirty-two or forty, depending upon the screen mode, and added to the column coordinate. This is then added to the Name Table base address, taken from [NAMBAS](#nambas), to produce an initial address.
|
|
1064
|
+
|
|
1065
|
+
Because of the variable screen width, as contained in [LINLEN](#linlen), an additional offset has to be added to the initial address to keep the active region roughly centered within the screen. The difference between the "true" number of characters per row, thirty-two or forty, and the current width is halved and then rounded up to produce the left hand offset. For a UK machine, with a thirty-seven character width in [40x24 Text Mode](#40x24_text_mode), this will result in two unused characters on the left hand side and one on the right. The statement `PRINT (41-WID)\2`, where `WID` is any screen width, will display the left hand column offset in [40x24 Text Mode](#40x24_text_mode).
|
|
1066
|
+
|
|
1067
|
+
A complete BASIC program which emulates this routine is given below:
|
|
1068
|
+
|
|
1069
|
+
```
|
|
1070
|
+
10 CPR=40:NAM=BASE(0):WID=PEEK(&HF3AE)
|
|
1071
|
+
20 SCRMD=PEEK(&HFCAF):IF SCRMD=0 THEN 40
|
|
1072
|
+
30 CPR=32:NAM=BASE(5):WID=PEEK(&HF3AF)
|
|
1073
|
+
40 LH=(CPR+1-WID)\2
|
|
1074
|
+
50 ADDR=NAM+(ROW-1)*CPR+(COL-1)+LH
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
This program is designed for the `ROW` and `COL` coordinate system used by the ROM BIOS where home is 1,1. Line 50 may be simplified, by removing the "-1" factors, if the BASIC Interpreter's coordinate system is to be used.
|
|
1078
|
+
|
|
1079
|
+
<a name="0c1dh"></a>
|
|
1080
|
+
|
|
1081
|
+
Address... 0C1DH
|
|
1082
|
+
|
|
1083
|
+
This routine calculates the address of a row's entry in [LINTTB](#linttb), the line termination table. The row coordinate is supplied in register L and the address returned in register pair DE.
|
|
1084
|
+
|
|
1085
|
+
<a name="0c29h"></a>
|
|
1086
|
+
|
|
1087
|
+
Address... 0C29H
|
|
1088
|
+
|
|
1089
|
+
This routine makes a row's entry in [LINTTB](#linttb) non-zero when entered at [0C29H](#0c29h) and zero when entered at 0C2AH. The row coordinate is supplied in register L.
|
|
1090
|
+
|
|
1091
|
+
<a name="0c32h"></a>
|
|
1092
|
+
|
|
1093
|
+
Address... 0C32H
|
|
1094
|
+
|
|
1095
|
+
This routine returns the number of rows on the screen in register A. It will normally return twenty-four if the function key display is disabled and twenty-three if it is enabled. Note that the screen size is determined by [CRTCNT](#crtcnt) and may be modified with a BASIC statement, `POKE &HF3B1H,14:SCREEN 0` for example.
|
|
1096
|
+
|
|
1097
|
+
<a name="0c3ch"></a><a name="keyint"></a>
|
|
1098
|
+
|
|
1099
|
+
```
|
|
1100
|
+
Address... 0C3CH
|
|
1101
|
+
Name...... KEYINT
|
|
1102
|
+
Entry..... None
|
|
1103
|
+
Exit...... None
|
|
1104
|
+
Modifies.. EI
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1107
|
+
Standard routine to process Z80 interrupts, these are generated by the VDP once every 20 ms on a UK machine. The [VDP Status Register](#vdp_status_register) is first read and bit 7 checked to ensure that this is a frame rate interrupt, if not the routine terminates with no action. The contents of the [Status Register](#vdp_status_register) are saved in [STATFL](#statfl) and bit 5 checked for sprite coincidence. If the Coincidence Flag is active then the relevant entry in [TRPTBL](#trptbl) is updated ([0EF1H](#0ef1h)).
|
|
1108
|
+
|
|
1109
|
+
[INTCNT](#intcnt), the "`INTERVAL`" counter, is then decremented. If this has reached zero the relevant entry in [TRPTBL](#trptbl) is updated ([0EF1H](#0ef1h)) and the counter reset with the contents of [INTVAL](#intval).
|
|
1110
|
+
|
|
1111
|
+
[JIFFY](#jiffy), the "`TIME`" counter, is then incremented. This counter just wraps around to zero when it overflows.
|
|
1112
|
+
|
|
1113
|
+
[MUSICF](#musicf) is examined to determine whether any of the three music queues generated by the "`PLAY`" statement are active. For each active queue the dequeueing routine ([113BH](#113bh)) is called to fetch the next music packet and write it to the PSG.
|
|
1114
|
+
|
|
1115
|
+
[SCNCNT](#scncnt) is then decremented to determine if a joystick and keyboard scan is required, if not the interrupt handler terminates with no further action. This counter is used to increase throughput and to minimize keybounce problems by ensuring that a scan is only carried out every three interrupts. Assuming a scan is required joystick connector 1 is selected and the two Trigger bits read ([120CH](#120ch)), followed by the two Trigger bits from joystick connector 2 ([120CH](#120ch)) and the SPACE key from row 8 of the keyboard ([1226H](#1226h)). These five inputs, which are all related to the "`STRIG`" statement, are combined into a single byte where 0=Pressed, 1=Not pressed:
|
|
1116
|
+
|
|
1117
|
+
<a name="figure35"></a>![][CH04F35]
|
|
1118
|
+
|
|
1119
|
+
**Figure 35:** "`STRIG`" Inputs
|
|
1120
|
+
|
|
1121
|
+
This reading is compared with the previous one, held in [TRGFLG](#trgflg), to produce an active transition byte and [TRGFLG](#trgflg) is updated with the new reading. The active transition byte is normally zero but contains a 1 in each position where a transition from unpressed to pressed has occurred. This active transition byte is shifted out bit by bit and the relevant entry in [TRPTBL](#trptbl) updated ([0EF1H](#0ef1h)) for each active device.
|
|
1122
|
+
|
|
1123
|
+
A complete scan of the keyboard matrix is then performed to identify new key depressions, any found are translated into key codes and placed in [KEYBUF](#keybuf) ([0D12H](#0d12h)). If [KEYBUF](#keybuf) is found to be empty at the end of this process [REPCNT](#repcnt) is decremented to see whether the auto-repeat delay has expired, if not the routine terminates. If the delay period has expired [REPCNT](#repcnt) is reset with the fast repeat value (60 ms), the [OLDKEY](#oldkey) keyboard map is reinitialized and the keyboard scanned again (0D4EH). Any keys which are continuously pressed will show up as new transitions during this scan. Note that keys will only auto-repeat while an application program keeps [KEYBUF](#keybuf) empty by reading characters. The interrupt handler then terminates.
|
|
1124
|
+
|
|
1125
|
+
<a name="0d12h"></a>
|
|
1126
|
+
|
|
1127
|
+
Address... 0D12H
|
|
1128
|
+
|
|
1129
|
+
This routine performs a complete scan of all eleven rows of the keyboard matrix for the interrupt handler. Each of the eleven rows is read in via the PPI and placed in ascending order in [NEWKEY](#newkey). [ENSTOP](#enstop) is then checked to see if warm starts are enabled. If its contents are non-zero and the keys CODE, GRAPH, CTRL and SHIFT are pressed control transfers to the BASIC Interpreter (409BH) via the [CALBAS](#calbas) standard routine. This facility is useful as even a machine code program can be terminated as long as the interrupt handler is running. The contents of [NEWKEY](#newkey) are compared with the previous scan contained in [OLDKEY](#oldkey). If any change at all has occurred [REPCNT](#repcnt) is loaded with the initial auto-repeat delay (780 ms). Each row 1, reading from [NEWKEY](#newkey) is then compared with the previous one, held in [OLDKEY](#oldkey), to produce an active transition byte and [OLDKEY](#oldkey) is updated with the new reading. The active transition byte is normally zero but contains a 1 in each position where a transition from unpressed to pressed has occurred. If the row contains any transitions these are decoded and placed in [KEYBUF](#keybuf) as key codes ([0D89H](#0d89h)). When all eleven rows have been completed the routine checks whether there are any characters in [KEYBUF](#keybuf), by subtracting [GETPNT](#getpnt) from [PUTPNT](#putpnt), and terminates.
|
|
1130
|
+
|
|
1131
|
+
<a name="0d6ah"></a><a name="chsns"></a>
|
|
1132
|
+
|
|
1133
|
+
```
|
|
1134
|
+
Address... 0D6AH
|
|
1135
|
+
Name...... CHSNS
|
|
1136
|
+
Entry..... None
|
|
1137
|
+
Exit...... Flag NZ if characters in KEYBUF
|
|
1138
|
+
Modifies.. AF, EI
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
Standard routine to check if any keyboard characters are ready. If the screen is in [Graphics Mode](#graphincsmode) or [Multicolour Mode](#multicolour_mode) then [GETPNT](#getpnt) is subtracted from [PUTPNT](#putpnt) (0D62H) and the routine terminates. If the screen is in [40x24 Text Mode](#40x24_text_mode) or [32x24 Text Mode](#32x24_text_mode) the state of the SHIFT key is also examined and the function key display updated, via the [DSPFNK](#dspfnk) standard routine, if it has changed.
|
|
1142
|
+
|
|
1143
|
+
<a name="0d89h"></a>
|
|
1144
|
+
|
|
1145
|
+
Address... 0D89H
|
|
1146
|
+
|
|
1147
|
+
This routine converts each active bit in a keyboard row transition byte into a key code. A bit is first converted into a key number determined by its position in the keyboard matrix:
|
|
1148
|
+
|
|
1149
|
+
<a name="figure36"></a>![][CH04F36]
|
|
1150
|
+
|
|
1151
|
+
**Figure 36:** Key Numbers
|
|
1152
|
+
|
|
1153
|
+
The key number is then converted into a key code and placed in [KEYBUF](#keybuf) ([1021H](#1021h)). When all eight possible bits have been processed the routine terminates.
|
|
1154
|
+
|
|
1155
|
+
<a name="0da5h"></a>
|
|
1156
|
+
|
|
1157
|
+
Address... 0DA5H
|
|
1158
|
+
|
|
1159
|
+
This table contains the key codes of key numbers 00H to 2FH for various combinations of the control keys. A zero entry in the table means that no key code will be produced when that key is pressed:
|
|
1160
|
+
|
|
1161
|
+
```
|
|
1162
|
+
37H 36H 35H 34H 33H 32H 31H 30H Row 0
|
|
1163
|
+
3BH 5DH 5BH 5CH 3DH 2DH 39H 38H Row 1
|
|
1164
|
+
NORMAL 62H 61H 9CH 2FH 2EH 2CH 60H 27H Row 2
|
|
1165
|
+
6AH 69H 68H 67H 66H 65H 64H 63H Row 3
|
|
1166
|
+
72H 71H 70H 6FH 6EH 6DH 6CH 6BH Row 4
|
|
1167
|
+
7AH 79H 78H 77H 76H 75H 74H 73H Row 5
|
|
1168
|
+
|
|
1169
|
+
26H 5EH 25H 24H 23H 40H 21H 29H Row 0
|
|
1170
|
+
3AH 7DH 7BH 7CH 2BH 5FH 28H 2AH Row 1
|
|
1171
|
+
SHIFT 42H 41H 9CH 3FH 3EH 3CH 7EH 22H Row 2
|
|
1172
|
+
4AH 49H 48H 47H 46H 45H 44H 43H Row 3
|
|
1173
|
+
52H 51H 50H 4FH 4EH 4DH 4CH 4BH Row 4
|
|
1174
|
+
5AH 59H 58H 57H 56H 55H 54H 53H Row 5
|
|
1175
|
+
|
|
1176
|
+
FBH F4H BDH EFH BAH ABH ACH 09H Row 0
|
|
1177
|
+
06H 0DH 01H 1EH F1H 17H 07H ECH Row 1
|
|
1178
|
+
GRAPH 11H C4H 9CH 1DH F2H F3H BBH 05H Row 2
|
|
1179
|
+
C6H DCH 13H 15H 14H CDH C7H BCH Row 3
|
|
1180
|
+
18H CCH DBH C2H 1BH 0BH C8H DDH Row 4
|
|
1181
|
+
0FH 19H 1CH CFH 1AH C0H 12H D2H Row 5
|
|
1182
|
+
|
|
1183
|
+
00H F5H 00H 00H FCH FDH 00H 0AH Row 0
|
|
1184
|
+
04H 0EH 02H 16H F0H 1FH 08H 00H Row 1
|
|
1185
|
+
SHIFT 00H FEH 9CH F6H AFH AEH F7H 03H Row 2
|
|
1186
|
+
GRAPH CAH DFH D6H 10H D4H CEH C1H FAH Row 3
|
|
1187
|
+
A9H CBH D7H C3H D3H 0CH C9H DEH Row 4
|
|
1188
|
+
F8H AAH F9H D0H D5H C5H 00H D1H Row 5
|
|
1189
|
+
|
|
1190
|
+
E1H E0H 98H 9BH BFH D9H 9FH EBH Row 0
|
|
1191
|
+
B7H DAH EDH 9CH E9H EEH 87H E7H Row 1
|
|
1192
|
+
CODE 97H 84H 9CH A7H A6H 86H E5H B9H Row 2
|
|
1193
|
+
91H A1H B1H 81H 94H 8CH 8BH 8DH Row 3
|
|
1194
|
+
93H 83H A3H A2H A4H E6H B5H B3H Row 4
|
|
1195
|
+
85H A0H 8AH 88H 95H 82H 96H 89H Row 5
|
|
1196
|
+
|
|
1197
|
+
00H 00H 9DH 9CH BEH 9EH ADH D8H Row 0
|
|
1198
|
+
B6H EAH E8H 00H 00H 00H 80H E2H Row 1
|
|
1199
|
+
SHIFT 00H 8EH 9CH A8H 00H 8FH E4H B8H Row 2
|
|
1200
|
+
CODE 92H 00H B0H 9AH 99H 00H 00H 00H Row 3
|
|
1201
|
+
00H 00H E3H 00H A5H 00H B4H B2H Row 4
|
|
1202
|
+
00H 00H 00H 00H 00H 90H 00H 00H Row 5
|
|
1203
|
+
|
|
1204
|
+
7 6 5 4 3 2 1 0 Column
|
|
1205
|
+
```
|
|
1206
|
+
|
|
1207
|
+
</a>
|
|
1208
|
+
|
|
1209
|
+
<a name="0ec5h"></a>
|
|
1210
|
+
|
|
1211
|
+
Address... 0EC5H
|
|
1212
|
+
|
|
1213
|
+
Control transfers to this routine, from [0FC3H](#0fc3h), to complete decoding of the five function keys. The relevant entry in [FNKFLG](#fnkflg) is first checked to determine whether the key is associated with an "`ON KEY GOSUB`" statement. If so, and provided that [CURLIN](#curlin) shows the BASIC Interpreter to be in program mode, the relevant entry in [TRPTBL](#trptbl) is updated ([0EF1H](#0ef1h)) and the routine terminates. If the key is not tied to an "`ON KEY GOSUB`" statement, or if the Interpreter is in direct mode, the string of characters associated with the function key is returned instead. The key number is multiplied by sixteen, as each string is sixteen characters long, and added to the starting address of the function key strings in the Workspace Area. Sequential characters are then taken from the string and placed in [KEYBUF](#keybuf) ([0F55H](#0f55h)) until the zero byte terminator is reached.
|
|
1214
|
+
|
|
1215
|
+
<a name="0ef1h"></a>
|
|
1216
|
+
|
|
1217
|
+
Address... 0EF1H
|
|
1218
|
+
|
|
1219
|
+
This routine is used to update a device's entry in [TRPTBL](#trptbl) when it has produced a BASIC program interrupt. On entry register pair HL points to the device's status byte in the table. Bit 0 of the status byte is checked first, if the device is not "`ON`" then the routine terminates with no action. Bit 2, the event flag, is then checked. If this is already set then the routine terminates, otherwise it is set to indicate that an event has occurred. Bit 1, the "`STOP`" flag, is then checked. If the device is stopped then the routine terminates with no further action. Otherwise [ONGSBF](#ongsbf) is incremented to signal to the Interpreter Runloop that the event should now be processed.
|
|
1220
|
+
|
|
1221
|
+
<a name="0f06h"></a>
|
|
1222
|
+
|
|
1223
|
+
Address... 0F06H
|
|
1224
|
+
|
|
1225
|
+
This section of the key decoder processes the HOME key only. The state of the SHIFT key is determined via row 6 of [NEWKEY](#newkey) and the key code for HOME (0BH) or CLS (0CH) placed in [KEYBUF](#keybuf) ([0F55H](#0f55h)) accordingly.
|
|
1226
|
+
|
|
1227
|
+
<a name="0f10h"></a>
|
|
1228
|
+
|
|
1229
|
+
Address... 0F10H
|
|
1230
|
+
|
|
1231
|
+
This section of the keyboard decoder processes key numbers 30H to 57H apart from the CAP, F1 to F5, STOP and HOME keys. The key number is simply used to look up the key code in the table at [1033H](#1033h) and this is then placed in [KEYBUF](#keybuf) ([0F55H](#0f55h)).
|
|
1232
|
+
|
|
1233
|
+
<a name="0f1fh"></a>
|
|
1234
|
+
|
|
1235
|
+
Address... 0F1FH
|
|
1236
|
+
|
|
1237
|
+
This section of the keyboard decoder processes the DEAD key found on European MSX machines. On UK machines the key in row 2, column 5 always generates the pound key code (9CH) shown in the table at 0DA5H. On European machines this table will have the key code FFH in the same locations. This key code only serves as a flag to indicate that the next key pressed, if it is a vowel, should be modified to produce an accented graphics character.
|
|
1238
|
+
|
|
1239
|
+
The state of the SHIFT and CODE keys is determined via row 6 of [NEWKEY](#newkey) and one of the following placed in [KANAST](#kanast): 01H=DEAD, 02H=DEAD+SHIFT, 03H=DEAD+CODE, 04H=DEAD+SHIFT+CODE.
|
|
1240
|
+
|
|
1241
|
+
<a name="0f36h"></a>
|
|
1242
|
+
|
|
1243
|
+
Address... 0F36H
|
|
1244
|
+
|
|
1245
|
+
This section of the keyboard decoder processes the CAP key. The current state of [CAPST](#capst) is inverted and control drops into the [CHGCAP](#chgcap) standard routine.
|
|
1246
|
+
|
|
1247
|
+
<a name="0f3dh"></a><a name="chgcap"></a>
|
|
1248
|
+
|
|
1249
|
+
```
|
|
1250
|
+
Address... 0F3DH
|
|
1251
|
+
Name...... CHGCAP
|
|
1252
|
+
Entry..... A=ON/OFF Switch
|
|
1253
|
+
Exit...... None
|
|
1254
|
+
Modifies.. AF
|
|
1255
|
+
```
|
|
1256
|
+
|
|
1257
|
+
Standard routine to turn the Caps Lock LED on or off as determined by the contents of register A: 00H=On, NZ=Off. The LED is modified using the bit set/reset facility of the PPI Mode Port. As [CAPST](#capst) is not changed this routine does not affect the characters produced by the keyboard.
|
|
1258
|
+
|
|
1259
|
+
<a name="0f46h"></a>
|
|
1260
|
+
|
|
1261
|
+
Address... 0F46H
|
|
1262
|
+
|
|
1263
|
+
This section of the keyboard decoder processes the STOP key. The state of the CTRL key is determined via row 6 of [NEWKEY](#newkey) and the key code for STOP (04H) or CTRL/STOP (03H) produced as appropriate. If the CTRL/STOP code is produced it is copied to [INTFLG](#intflg), for use by the [ISCNTC](#iscntc) standard routine, and then placed in [KEYBUF](#keybuf) ([0F55H](#0f55h)). If the STOP code is produced it is also copied to [INTFLG](#intflg) but is not placed in [KEYBUF](#keybuf), instead only a click is generated (0F64H). This means that an application program cannot read the STOP key code via the ROM BIOS standard routines.
|
|
1264
|
+
|
|
1265
|
+
<a name="0f55h"></a>
|
|
1266
|
+
|
|
1267
|
+
Address... 0F55H
|
|
1268
|
+
|
|
1269
|
+
This section of the keyboard decoder places a key code in [KEYBUF](#keybuf) and generates an audible click. The correct address in the keyboard buffer is first taken from [PUTPNT](#putpnt) and the code placed there. The address is then incremented ([105BH](#105bh)). If it has wrapped round and caught up with [GETPNT](#getpnt) then the routine terminates with no further action as the keyboard buffer is full. Otherwise [PUTPNT](#putpnt) is updated with the new address.
|
|
1270
|
+
|
|
1271
|
+
[CLIKSW](#cliksw) and [CLIKFL](#clikfl) are then both checked to determine whether a click is required. [CLIKSW](#cliksw) is a general enable/disable switch while [CLIKFL](#clikfl) is used to prevent multiple clicks when the function keys are pressed. Assuming a click is required the Key Click output is set via the [PPI Mode Port](#ppi_mode_port) and, after a delay of 50 µs, control drops into the [CHGSND](#chgsnd) standard routine.
|
|
1272
|
+
|
|
1273
|
+
<a name="0f7ah"></a><a name="chgsnd"></a>
|
|
1274
|
+
|
|
1275
|
+
```
|
|
1276
|
+
Address... 0F7AH
|
|
1277
|
+
Name...... CHGSND
|
|
1278
|
+
Entry..... A=ON/OFF Switch
|
|
1279
|
+
Exit...... None
|
|
1280
|
+
Modifies.. AF
|
|
1281
|
+
```
|
|
1282
|
+
|
|
1283
|
+
Standard routine to set or reset the Key Click output via the [PPI Mode Port](#ppi_mode_port): 00H=Reset, NZ=Set. This audio output is AC coupled so absolute polarities should not be taken too seriously.
|
|
1284
|
+
|
|
1285
|
+
<a name="0f83h"></a>
|
|
1286
|
+
|
|
1287
|
+
Address... 0F83H
|
|
1288
|
+
|
|
1289
|
+
This section of the keyboard decoder processes key numbers 00H to 2FH. The state of the SHIFT, GRAPH and CODE keys is determined via row 6 of [NEWKEY](#newkey) and combined with the key number to form a look-up address into the table at [0DA5H](#0da5h). The key code is then taken from the table. If it is zero the routine terminates with no further action, if it is FFH control transfers to the DEAD key processor ([0F1FH](#0f1fh)). If the code is in the range 40H to 5FH or 60H to 7FH and the CTRL key is pressed then the corresponding control code is placed in [KEYBUF](#keybuf) ([0F55H](#0f55h)). If the code is in the range 01H to 1FH then a graphic header code (01H) is first placed in [KEYBUF](#keybuf) ([0F55H](#0f55h)) followed by the code with 40H added. If the code is in the range 61H to 7BH and [CAPST](#capst) indicates that caps lock is on then it is converted to upper case by subtracting 20H. Assuming that [KANAST](#kanast) contains zero, as it always will on UK machines, then the key code is placed in [KEYBUF](#keybuf) ([0F55H](#0f55h)) and the routine terminates. On European MSX machines, with a DEAD key instead of a pound key, then the key codes corresponding to the vowels a, e, i, o, u may be further modified into graphics codes.
|
|
1290
|
+
|
|
1291
|
+
<a name="0fc3h"></a>
|
|
1292
|
+
|
|
1293
|
+
Address... 0FC3H
|
|
1294
|
+
|
|
1295
|
+
This section of the keyboard decoder processes the five function keys. The state of the SHIFT key is examined via row 6 of [NEWKEY](#newkey) and five added to the key number if it is pressed. Control then transfers to [0EC5H](#0ec5h) to complete processing.
|
|
1296
|
+
|
|
1297
|
+
<a name="1021h"></a>
|
|
1298
|
+
|
|
1299
|
+
Address... 1021H
|
|
1300
|
+
|
|
1301
|
+
This routine searches the table at [1B97H](#1b97h) to determine which group of keys the key number supplied in register C belongs to. The associated address is then taken from the table and control transferred to that section of the keyboard decoder. Note that the table itself is actually patched into the middle of the [OUTDO](#outdo) standard routine as a result of the modifications made to the Japanese ROM.
|
|
1302
|
+
|
|
1303
|
+
<a name="1033h"></a>
|
|
1304
|
+
|
|
1305
|
+
Address... 1033H
|
|
1306
|
+
|
|
1307
|
+
This table contains the key codes of key numbers 30H to 57H other than the special keys CAP, F1 to F5, STOP and HOME. A zero entry in the table means that no key code will be produced when that key is pressed:
|
|
1308
|
+
|
|
1309
|
+
```
|
|
1310
|
+
00H 00H 00H 00H 00H 00H 00H 00H Row 6
|
|
1311
|
+
0DH 18H 08H 00H 09H 1BH 00H 00H Row 7
|
|
1312
|
+
1CH 1FH 1EH 1DH 7FH 12H 0CH 20H Row 8
|
|
1313
|
+
34H 33H 32H 31H 30H 00H 00H 00H Row 9
|
|
1314
|
+
2EH 2CH 2DH 39H 38H 37H 36H 35H Row 10
|
|
1315
|
+
|
|
1316
|
+
7 6 5 4 3 2 1 0 Column
|
|
1317
|
+
```
|
|
1318
|
+
|
|
1319
|
+
</a>
|
|
1320
|
+
|
|
1321
|
+
<a name="105bh"></a>
|
|
1322
|
+
|
|
1323
|
+
Address... 105BH
|
|
1324
|
+
|
|
1325
|
+
This routine simply zeroes [KANAST](#kanast) and then transfers control to [10C2H](#10c2h).
|
|
1326
|
+
|
|
1327
|
+
<a name="1061h"></a>
|
|
1328
|
+
|
|
1329
|
+
Address... 1061H
|
|
1330
|
+
|
|
1331
|
+
This table contains the graphics characters which replace the vowels a, e, i, o, u on European machines.
|
|
1332
|
+
|
|
1333
|
+
<a name="10c2h"></a>
|
|
1334
|
+
|
|
1335
|
+
Address... 10C2H
|
|
1336
|
+
|
|
1337
|
+
This routine increments the keyboard buffer pointer, either [PUTPNT](#putpnt) or [GETPNT](#getpnt), supplied in register pair HL. If the pointer then exceeds the end of the keyboard buffer it is wrapped back to the beginning.
|
|
1338
|
+
|
|
1339
|
+
<a name="10cbh"></a><a name="chget"></a>
|
|
1340
|
+
|
|
1341
|
+
```
|
|
1342
|
+
Address... 10CBH
|
|
1343
|
+
Name...... CHGET
|
|
1344
|
+
Entry..... None
|
|
1345
|
+
Exit...... A=Character from keyboard
|
|
1346
|
+
Modifies.. AF, EI
|
|
1347
|
+
```
|
|
1348
|
+
|
|
1349
|
+
Standard routine to fetch a character from the keyboard buffer. The buffer is first checked to see if already contains a character ([0D6AH](#0d6ah)). If not the cursor is turned on ([09DAH](#09dah)), the buffer checked repeatedly until a character appears ([0D6AH](#0d6ah)) and then the cursor turned off ([0A27H](#0a27h)). The character is taken from the buffer using [GETPNT](#getpnt) which is then incremented ([10C2H](#10c2h)).
|
|
1350
|
+
|
|
1351
|
+
<a name="10f9h"></a><a name="ckcntc"></a>
|
|
1352
|
+
|
|
1353
|
+
```
|
|
1354
|
+
Address... 10F9H
|
|
1355
|
+
Name...... CKCNTC
|
|
1356
|
+
Entry..... None
|
|
1357
|
+
Exit...... None
|
|
1358
|
+
Modifies.. AF, EI
|
|
1359
|
+
```
|
|
1360
|
+
|
|
1361
|
+
Standard routine to check whether the CTRL-STOP or STOP keys have been pressed. It is used by the BASIC Interpreter inside processor-intensive statements, such as "`WAIT`" and "`CIRCLE`", to check for program termination. Register pair HL is first zeroed and then control transferred to the [ISCNTC](#iscntc) standard routine. When the Interpreter is running register pair HL normally contains the address of the current character in the BASIC program text. If [ISCNTC](#iscntc) is CTRL-STOP terminated this address will be placed in [OLDTXT](#oldtxt) by the "`STOP`" statement handler (63E6H) for use by a later "`CONT`" statement. Zeroing register pair HL beforehand signals to the "`CONT`" handler that termination occurred inside a statement and it will issue a "`Can't CONTINUE`" error if continuation is attempted.
|
|
1362
|
+
|
|
1363
|
+
<a name="1102h"></a><a name="wrtpsg"></a>
|
|
1364
|
+
|
|
1365
|
+
```
|
|
1366
|
+
Address... 1102H
|
|
1367
|
+
Name...... WRTPSG
|
|
1368
|
+
Entry..... A=Register number, E=Data byte
|
|
1369
|
+
Exit...... None
|
|
1370
|
+
Modifies.. EI
|
|
1371
|
+
```
|
|
1372
|
+
|
|
1373
|
+
Standard routine to write a data byte to any of the sixteen [PSG registers](#registers_0_and_1). The register selection number is written to the PSG [Address Port](#address_port) and the data byte written to the PSG [Data Write Port](#data_write_port).
|
|
1374
|
+
|
|
1375
|
+
<a name="110eh"></a><a name="rdpsg"></a>
|
|
1376
|
+
|
|
1377
|
+
```
|
|
1378
|
+
Address... 110EH
|
|
1379
|
+
Name...... RDPSG
|
|
1380
|
+
Entry..... A=Register number
|
|
1381
|
+
Exit...... A=Data byte read from PSG
|
|
1382
|
+
Modifies.. A
|
|
1383
|
+
```
|
|
1384
|
+
|
|
1385
|
+
Standard routine to read a data byte from any of the sixteen [PSG registers](#registers_0_and_1). The register selection number is written to the PSG [Address Port](#address_port) and the data byte read from the PSG [Data Read Port](#data_read_port).
|
|
1386
|
+
|
|
1387
|
+
<a name="1113h"></a><a name="beep"></a>
|
|
1388
|
+
|
|
1389
|
+
```
|
|
1390
|
+
Address... 1113H
|
|
1391
|
+
Name...... BEEP
|
|
1392
|
+
Entry..... None
|
|
1393
|
+
Exit...... None
|
|
1394
|
+
Modifies.. AF, BC, E, EI
|
|
1395
|
+
```
|
|
1396
|
+
|
|
1397
|
+
Standard routine to produce a beep via the PSG. Channel A is set to produce a tone of 1316Hz then enabled with an amplitude of seven. After a delay of 40 ms control transfers to the [GICINI](#gicini) standard routine to reinitialize the PSG.
|
|
1398
|
+
|
|
1399
|
+
<a name="113bh"></a>
|
|
1400
|
+
|
|
1401
|
+
Address... 113BH
|
|
1402
|
+
|
|
1403
|
+
This routine is used by the interrupt handler to service a music queue. As there are three of these, each feeding a PSG channel, the queue to be serviced is specified by supplying its number in register A: 0=[VOICAQ](#voicaq), 1=[VOICBQ](#voicbq) and 2=[VOICCQ](#voiccq).
|
|
1404
|
+
|
|
1405
|
+
Each string in a "`PLAY`" statement is translated into a series of data packets by the BASIC Interpreter. These are placed in the appropriate queue followed by an end of data byte (FFH). The task of dequeueing the packets, decoding them and setting the PSG is left to the interrupt handler. The Interpreter is thus free to proceed immediately to the next statement without having to wait for notes to finish.
|
|
1406
|
+
|
|
1407
|
+
The first two bytes of any packet specify its byte count and duration. The three most significant bits of the first byte specify the number of bytes following the header in the packet. The remainder of the header specifies the event duration in 20 ms units. This duration count determines how long it will be before the next packet is read from the queue.
|
|
1408
|
+
|
|
1409
|
+
<a name="figure37"></a>![][CH04F37]
|
|
1410
|
+
|
|
1411
|
+
**Figure 37:** Packet Header
|
|
1412
|
+
|
|
1413
|
+
The packet header may be followed by zero or more blocks, in any order, containing frequency or amplitude information:
|
|
1414
|
+
|
|
1415
|
+
<a name="figure38"></a>![][CH04F38]
|
|
1416
|
+
|
|
1417
|
+
**Figure 38:** Packet Block Types
|
|
1418
|
+
|
|
1419
|
+
The routine first locates the current duration counter in the relevant voice buffer ([VCBA](#vcba), [VCBB](#vcbb) or [VCBC](#vcbc)) via the [GETVCP](#getvcp) standard routine and decrements it. If the counter has reached zero then the next packet must be read from the queue, otherwise the routine terminates.
|
|
1420
|
+
|
|
1421
|
+
The queue number is placed in [QUEUEN](#queuen) and a byte read from the queue ([11E2H](#11e2h)). This is then checked to see if it is the end of data mark (FFH), if so the queue terminates ([11B0H](#11b0h)). Otherwise the byte count is placed in register C and the duration MSB in the relevant voice buffer. The second byte is read ([11E2H](#11e2h)) and the duration LSB placed in the relevant voice buffer. The byte count is then examined, if there are no bytes to follow the packet header the routine terminates. Otherwise successive bytes are read from the queue, and the appropriate action taken, until the byte count is exhausted.
|
|
1422
|
+
|
|
1423
|
+
If a frequency block is found then a second byte is read and both bytes written to PSG Registers [0](#registers_0_and_1) and [1](#registers_0_and_1), [2](#registers_2_and_3) and [3](#registers_2_and_3) or [4](#registers_4_and_5) and [5](#registers_4_and_5) depending on the queue number.
|
|
1424
|
+
|
|
1425
|
+
If an amplitude block is found the Amplitude and Mode bits are written to PSG Registers [8](#register_8), [9](#register_9) or [10](#register_10) depending on the queue number. If the Mode bit is 1, selecting modulated rather than fixed amplitude, then the byte is also written to PSG [Register 13](#register_13) to set the envelope shape.
|
|
1426
|
+
|
|
1427
|
+
If an envelope block is found, or if bit 6 of an amplitude block is set, then a further two bytes are read from the queue and written to PSG Registers [11](#registers_11_and_12) and [12](#registers_11_and_12).
|
|
1428
|
+
|
|
1429
|
+
<a name="11b0h"></a>
|
|
1430
|
+
|
|
1431
|
+
Address... 11B0H
|
|
1432
|
+
|
|
1433
|
+
This routine is used when an end of data mark (FFH) is found in one of the three music queues. An amplitude value of zero is written to PSG Register [8](#register_8) [9](#register_9) or [10](#register_10), depending on the queue number, to shut the channel down. The channel's bit in [MUSICF](#musicf) is then reset and control drops into the [STRTMS](#strtms) standard routine.
|
|
1434
|
+
|
|
1435
|
+
<a name="11c4h"></a><a name="strtms"></a>
|
|
1436
|
+
|
|
1437
|
+
```
|
|
1438
|
+
Address... 11C4H
|
|
1439
|
+
Name...... STRTMS
|
|
1440
|
+
Entry..... None
|
|
1441
|
+
Exit...... None
|
|
1442
|
+
Modifies.. AF, HL
|
|
1443
|
+
```
|
|
1444
|
+
|
|
1445
|
+
Standard routine used by the "`PLAY`" statement handler to initiate music dequeueing by the interrupt handler. [MUSICF](#musicf) is first examined, if any channels are already running the routine terminates with no action. [PLYCNT](#plycnt) is then decremented, if there are no more "`PLAY`" strings queued up the routine terminates. Otherwise the three duration counters, in [VCBA](#vcba), [VCBB](#vcbb) and [VCBC](#vcbc), are set to 0001H, so that the first packet of the new group will be dequeued at the next interrupt, and [MUSICF](#musicf) is set to 07H to enable all three channels.
|
|
1446
|
+
|
|
1447
|
+
<a name="11e2h"></a>
|
|
1448
|
+
|
|
1449
|
+
Address... 11E2H
|
|
1450
|
+
|
|
1451
|
+
This routine loads register A with the current queue number, from [QUEUEN](#queuen), and then reads a byte from that queue ([14ADH](#14adh)).
|
|
1452
|
+
|
|
1453
|
+
<a name="11eeh"></a><a name="gtstck"></a>
|
|
1454
|
+
|
|
1455
|
+
```
|
|
1456
|
+
Address... 11EEH
|
|
1457
|
+
Name...... GTSTCK
|
|
1458
|
+
Entry..... A=Joystick ID (0, 1 or 2)
|
|
1459
|
+
Exit...... A=Joystick position code
|
|
1460
|
+
Modifies.. AF, B, DE, HL, EI
|
|
1461
|
+
```
|
|
1462
|
+
|
|
1463
|
+
Standard routine to read the position of a joystick or the four cursor keys. If the supplied ID is zero the state of the cursor keys is read via [PPI Port B](ppi_port_b) ([1226H](#1226h)) and converted to a position code using the look-up table at 1243H. Otherwise joystick connector 1 or 2 is read ([120CH](#120ch)) and the four direction bits converted to a position code using the look-up table at 1233H. The returned position codes are:
|
|
1464
|
+
|
|
1465
|
+
<a name="figure39a"></a>![][CH04F39a]
|
|
1466
|
+
|
|
1467
|
+
<a name="120ch"></a>
|
|
1468
|
+
|
|
1469
|
+
Address... 120CH
|
|
1470
|
+
|
|
1471
|
+
This routine reads the joystick connector specified by the contents of register A: 0=Connector 1, 1=Connector 2. The current contents of PSG [Register 15](#register_15) are read in then written back with the Joystick Select bit appropriately set. PSG [Register 14](#register_14) is then read into register A (110CH) and the routine terminates.
|
|
1472
|
+
|
|
1473
|
+
<a name="1226h"></a>
|
|
1474
|
+
|
|
1475
|
+
Address... 1226H
|
|
1476
|
+
|
|
1477
|
+
This routine reads row 8 of the keyboard matrix. The current contents of [PPI Port C](ppi_port_c) are read in then written back with the four Keyboard Row Select bits set for row 8. The column inputs are then read into register A from [PPI Port B](ppi_port_b).
|
|
1478
|
+
|
|
1479
|
+
<a name="1253h"></a><a name="gttrig"></a>
|
|
1480
|
+
|
|
1481
|
+
```
|
|
1482
|
+
Address... 1253H
|
|
1483
|
+
Name...... GTTRIG
|
|
1484
|
+
Entry..... A=Trigger ID (0, 1, 2, 3 or 4)
|
|
1485
|
+
Exit...... A=Status code
|
|
1486
|
+
Modifies.. AF, BC, EI
|
|
1487
|
+
```
|
|
1488
|
+
|
|
1489
|
+
Standard routine to check the joystick trigger or space key status. If the supplied ID is zero row 8 of the keyboard matrix is read ([1226H](#1226h)) and converted to a status code. Otherwise joystick connector 1 or 2 is read ([120CH](#120ch)) and converted to a status code. The selection IDs are:
|
|
1490
|
+
|
|
1491
|
+
```
|
|
1492
|
+
0=SPACE KEY
|
|
1493
|
+
1=JOY 1, TRIGGER A
|
|
1494
|
+
2=JOY 2, TRIGGER A
|
|
1495
|
+
3=JOY 1, TRIGGER B
|
|
1496
|
+
4=JOY 2, TRIGGER B
|
|
1497
|
+
```
|
|
1498
|
+
|
|
1499
|
+
The value returned is FFH if the relevant trigger is pressed and zero otherwise.
|
|
1500
|
+
|
|
1501
|
+
<a name="1273h"></a><a name="gtpdl"></a>
|
|
1502
|
+
|
|
1503
|
+
```
|
|
1504
|
+
Address... 1273H
|
|
1505
|
+
Name...... GTPDL
|
|
1506
|
+
Entry..... A=Paddle ID (1 to 12)
|
|
1507
|
+
Exit...... A=Paddle value (0 to 255)
|
|
1508
|
+
Modifies.. AF, BC, DE, EI
|
|
1509
|
+
```
|
|
1510
|
+
|
|
1511
|
+
Standard routine to read the value of any paddle attached to a joystick connector. Each of the six input lines (four direction plus two triggers) per connector can support a paddle so twelve are possible altogether. The paddles attached to joystick connector 1 have entry identifiers 1, 3, 5, 7, 9 and 11. Those attached to joystick connector 2 have entry identifiers 2, 4, 6, 8, 10 and 12. Each paddle is basically a one-shot pulse generator, the length of the pulse being controlled by a variable resistor. A start pulse is issued to the specified joystick connector via PSG [Register 15](#register_15). A count is then kept of how many times PSG [Register 14](#register_14) has to be read until the relevant input times out. Each unit increment represents an approximate period of 12 µs on an MSX machine with one wait state.
|
|
1512
|
+
|
|
1513
|
+
<a name="12ach"></a><a name="gtpad"></a>
|
|
1514
|
+
|
|
1515
|
+
```
|
|
1516
|
+
Address... 12ACH
|
|
1517
|
+
Name...... GTPAD
|
|
1518
|
+
Entry..... A=Function code (0 to 7)
|
|
1519
|
+
Exit...... A=Status or value
|
|
1520
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
1521
|
+
```
|
|
1522
|
+
|
|
1523
|
+
Standard routine to access a touchpad attached to either of the joystick connectors. Available functions codes for joystick connector 1 are:
|
|
1524
|
+
|
|
1525
|
+
```
|
|
1526
|
+
0=Return Activity Status
|
|
1527
|
+
1=Return "X" coordinate
|
|
1528
|
+
2=Return "Y" coordinate
|
|
1529
|
+
3=Return Switch Status
|
|
1530
|
+
```
|
|
1531
|
+
|
|
1532
|
+
Function codes 4 to 7 have the same effect with respect to joystick connector 2. The Activity Status function returns FFH if the Touchpad is being touched and zero otherwise. The Switch Status function returns FFH if the switch is being pressed and zero otherwise. The two coordinate request functions return the coordinates of the last location touched. These coordinates are actually stored in the Workspace Area variables [PADX](#padx) and [PADY](#pady) when a call with function code 0 or 4 detects activity. Note that these variables are shared by both joystick connectors.
|
|
1533
|
+
|
|
1534
|
+
<a name="1384h"></a><a name="stmotr"></a>
|
|
1535
|
+
|
|
1536
|
+
```
|
|
1537
|
+
Address... 1384H
|
|
1538
|
+
Name...... STMOTR
|
|
1539
|
+
Entry..... A=Motor ON/OFF code
|
|
1540
|
+
Exit...... None
|
|
1541
|
+
Modifies.. AF
|
|
1542
|
+
```
|
|
1543
|
+
|
|
1544
|
+
Standard routine to turn the cassette motor relay on or off via [PPI Port C](ppi_port_c): 00H=Off, 01H=On, FFH=Reverse current state.
|
|
1545
|
+
|
|
1546
|
+
<a name="1398h"></a><a name="nmi"></a>
|
|
1547
|
+
|
|
1548
|
+
```
|
|
1549
|
+
Address... 1398H
|
|
1550
|
+
Name...... NMI
|
|
1551
|
+
Entry..... None
|
|
1552
|
+
Exit...... None
|
|
1553
|
+
Modifies.. None
|
|
1554
|
+
```
|
|
1555
|
+
|
|
1556
|
+
Standard routine to process a Z80 Non Maskable Interrupt, simply returns on a standard MSX machine.
|
|
1557
|
+
|
|
1558
|
+
<a name="139dh"></a><a name="inifnk"></a>
|
|
1559
|
+
|
|
1560
|
+
```
|
|
1561
|
+
Address... 139DH
|
|
1562
|
+
Name...... INIFNK
|
|
1563
|
+
Entry..... None
|
|
1564
|
+
Exit...... None
|
|
1565
|
+
Modifies.. BC, DE, HL
|
|
1566
|
+
```
|
|
1567
|
+
|
|
1568
|
+
Standard routine to initialize the ten function key strings to their power-up values. The one hundred and sixty bytes of data commencing at [13A9H](#13a9h) are copied to the [FNKSTR](#fnkstr) buffer in the Workspace Area.
|
|
1569
|
+
|
|
1570
|
+
<a name="13a9h"></a>
|
|
1571
|
+
|
|
1572
|
+
Address... 13A9H
|
|
1573
|
+
|
|
1574
|
+
This area contains the power-up strings for the ten function keys. Each string is sixteen characters long, unused positions contain zeroes:
|
|
1575
|
+
|
|
1576
|
+
```
|
|
1577
|
+
F1 to F5 F6 to F10
|
|
1578
|
+
color color 15,4,4 CR
|
|
1579
|
+
auto cload"
|
|
1580
|
+
goto cont CR
|
|
1581
|
+
list list. CR UP UP
|
|
1582
|
+
run CR run CLS CR
|
|
1583
|
+
```
|
|
1584
|
+
|
|
1585
|
+
<a name="1449h"></a><a name="rdvdp"></a>
|
|
1586
|
+
|
|
1587
|
+
```
|
|
1588
|
+
Address... 1449H
|
|
1589
|
+
Name...... RDVDP
|
|
1590
|
+
Entry..... None
|
|
1591
|
+
Exit...... A=VDP Status Register contents
|
|
1592
|
+
Modifies.. A
|
|
1593
|
+
```
|
|
1594
|
+
|
|
1595
|
+
Standard routine to input the contents of the [VDP Status Register](#vdp_status_register) by reading the [Command Port](#command_port). Note that reading the [VDP Status Register](#vdp_status_register) will clear the associated flags and may affect the interrupt handler.
|
|
1596
|
+
|
|
1597
|
+
<a name="144ch"></a><a name="rslreg"></a>
|
|
1598
|
+
|
|
1599
|
+
```
|
|
1600
|
+
Address... 144CH
|
|
1601
|
+
Name...... RSLREG
|
|
1602
|
+
Entry..... None
|
|
1603
|
+
Exit...... A=Primary Slot Register contents
|
|
1604
|
+
Modifies.. A
|
|
1605
|
+
```
|
|
1606
|
+
|
|
1607
|
+
Standard routine to input the contents of the Primary slot Register by reading [PPI Port A](ppi_port_a).
|
|
1608
|
+
|
|
1609
|
+
<a name="144fh"></a><a name="wslreg"></a>
|
|
1610
|
+
|
|
1611
|
+
```
|
|
1612
|
+
Address... 144FH
|
|
1613
|
+
Name...... WSLREG
|
|
1614
|
+
Entry..... A=Value to write
|
|
1615
|
+
Exit...... None
|
|
1616
|
+
Modifies.. None
|
|
1617
|
+
```
|
|
1618
|
+
|
|
1619
|
+
Standard routine to set the Primary Slot Register by writing to [PPI Port A](ppi_port_a).
|
|
1620
|
+
|
|
1621
|
+
<a name="1452h"></a><a name="snsmat"></a>
|
|
1622
|
+
|
|
1623
|
+
```
|
|
1624
|
+
Address... 1452H
|
|
1625
|
+
Name...... SNSMAT
|
|
1626
|
+
Entry..... A=Keyboard row number
|
|
1627
|
+
Exit...... A=Column data of keyboard row
|
|
1628
|
+
Modifies.. AF, C, EI
|
|
1629
|
+
```
|
|
1630
|
+
|
|
1631
|
+
Standard routine to read a complete row of the keyboard matrix. [PPI Port C](ppi_port_c) is read in then written back with the row number occupying the four Keyboard Row Select bits. [PPI Port B](ppi_port_b) is then read into register A to return the eight column inputs. The four miscellaneous control outputs of [PPI Port C](ppi_port_c) are unaffected by this routine.
|
|
1632
|
+
|
|
1633
|
+
<a name="145fh"></a><a name="isflio"></a>
|
|
1634
|
+
|
|
1635
|
+
```
|
|
1636
|
+
Address... 145FH
|
|
1637
|
+
Name...... ISFLIO
|
|
1638
|
+
Entry..... None
|
|
1639
|
+
Exit...... Flag NZ if file I/O active
|
|
1640
|
+
Modifies.. AF
|
|
1641
|
+
```
|
|
1642
|
+
|
|
1643
|
+
Standard routine to check whether the BASIC Interpreter is currently directing its input or output via an I/O buffer. This is determined by examining [PTRFIL](#ptrfil). It is normally zero but will contain a buffer FCB (File Control Block) address while statements such as "`PRINT#1`", "`INPUT#1`", etc. are being executed by the Interpreter.
|
|
1644
|
+
|
|
1645
|
+
<a name="146ah"></a><a name="dcompr"></a>
|
|
1646
|
+
|
|
1647
|
+
```
|
|
1648
|
+
Address... 146AH
|
|
1649
|
+
Name...... DCOMPR
|
|
1650
|
+
Entry..... HL, DE
|
|
1651
|
+
Exit...... Flag NC if HL>DE, Flag Z if HL=DE, Flag C if HL<DE
|
|
1652
|
+
Modifies.. AF
|
|
1653
|
+
```
|
|
1654
|
+
|
|
1655
|
+
Standard routine used by the BASIC Interpreter to check the relative values of register pairs HL and DE.
|
|
1656
|
+
|
|
1657
|
+
<a name="1470h"></a><a name="getvcp"></a>
|
|
1658
|
+
|
|
1659
|
+
```
|
|
1660
|
+
Address... 1470H
|
|
1661
|
+
Name...... GETVCP
|
|
1662
|
+
Entry..... A=Voice number (0, 1, 2)
|
|
1663
|
+
Exit...... HL=Address in voice buffer
|
|
1664
|
+
Modifies.. AF, HL
|
|
1665
|
+
```
|
|
1666
|
+
|
|
1667
|
+
Standard routine to return the address of byte 2 in the specified voice buffer ([VCBA](#vcba), [VCBB](#vcbb) or [VCBC](#vcbc)).
|
|
1668
|
+
|
|
1669
|
+
<a name="1474h"></a><a name="getvc2"></a>
|
|
1670
|
+
|
|
1671
|
+
```
|
|
1672
|
+
Address... 1474H
|
|
1673
|
+
Name...... GETVC2
|
|
1674
|
+
Entry..... L=Byte number (0 to 36)
|
|
1675
|
+
Exit...... HL=Address in voice buffer
|
|
1676
|
+
Modifies.. AF, HL
|
|
1677
|
+
```
|
|
1678
|
+
|
|
1679
|
+
Standard routine to return the address of any byte in the voice buffer ([VCBA](#vcba), [VCBB](#vcbb) or [VCBC](#vcbc)) specified by the voice number in [VOICEN](#voicen).
|
|
1680
|
+
|
|
1681
|
+
<a name="148ah"></a><a name="phydio"></a>
|
|
1682
|
+
|
|
1683
|
+
```
|
|
1684
|
+
Address... 148AH
|
|
1685
|
+
Name...... PHYDIO
|
|
1686
|
+
Entry..... None
|
|
1687
|
+
Exit...... None
|
|
1688
|
+
Modifies.. None
|
|
1689
|
+
```
|
|
1690
|
+
|
|
1691
|
+
Standard routine for use by Disk BASIC, simply returns on standard MSX machines.
|
|
1692
|
+
|
|
1693
|
+
<a name="148eh"></a><a name="format"></a>
|
|
1694
|
+
|
|
1695
|
+
```
|
|
1696
|
+
Address... 148EH
|
|
1697
|
+
Name...... FORMAT
|
|
1698
|
+
Entry..... None
|
|
1699
|
+
Exit...... None
|
|
1700
|
+
Modifies.. None
|
|
1701
|
+
```
|
|
1702
|
+
|
|
1703
|
+
Standard routine for use by Disk BASIC, simply returns on standard MSX machines.
|
|
1704
|
+
|
|
1705
|
+
<a name="1492h"></a><a name="putq"></a>
|
|
1706
|
+
|
|
1707
|
+
```
|
|
1708
|
+
Address... 1492H
|
|
1709
|
+
Name...... PUTQ
|
|
1710
|
+
Entry..... A=Queue number, E=Data byte
|
|
1711
|
+
Exit...... Flag Z if queue full
|
|
1712
|
+
Modifies.. AF, BC, HL
|
|
1713
|
+
```
|
|
1714
|
+
|
|
1715
|
+
Standard routine to place a data byte in one of the three music queues. The queue's get and put positions are first taken from [QUETAB](#quetab) ([14FAH](#14fah)). The put position is temporarily incremented and compared with the get position, if they are equal the routine terminates as the queue is full. Otherwise the queue's address is taken from [QUETAB](#quetab) and the put position added to it. The data byte is placed at this location in the queue, the put position is incremented and the routine terminates. Note that the music queues are circular, if the get or put pointers reach the last position in the queue they wrap around back to the start.
|
|
1716
|
+
|
|
1717
|
+
<a name="14adh"></a>
|
|
1718
|
+
|
|
1719
|
+
Address... 14ADH
|
|
1720
|
+
|
|
1721
|
+
This routine is used by the interrupt handler to read a byte from one of the three music queues. The queue number is supplied in register A, the data byte is returned in register A and the routine returns Flag Z if the queue is empty. The queue's get and put positions are first taken from [QUETAB](#quetab) ([14FAH](#14fah)). If the putback flag is active then the data byte is taken from [QUEBAK](#quebak) and the routine terminates (14D1H), this facility is unused in the current versions of the MSX ROM. The put position is then compared with the get position, if they are equal the routine terminates as the queue is empty. Otherwise the queue's address is taken from [QUETAB](#quetab) and the get position added to it. The data byte is read from this location in the queue, the get position is incremented and the routine terminates.
|
|
1722
|
+
|
|
1723
|
+
Address... 14DAH
|
|
1724
|
+
|
|
1725
|
+
This routine is used by the [GICINI](#gicini) standard routine to initialize a queue's control block in [QUETAB](#quetab). The control block is first located in [QUETAB](#quetab) ([1504H](#1504h)) and the put, get and putback bytes zeroed. The size byte is set from register B and the queue address from register pair DE.
|
|
1726
|
+
|
|
1727
|
+
<a name="14ebh"></a><a name="lftq"></a>
|
|
1728
|
+
|
|
1729
|
+
```
|
|
1730
|
+
Address... 14EBH
|
|
1731
|
+
Name...... LFTQ
|
|
1732
|
+
Entry..... A=Queue number
|
|
1733
|
+
Exit...... HL=Free space left in queue
|
|
1734
|
+
Modifies.. AF, BC, HL
|
|
1735
|
+
```
|
|
1736
|
+
|
|
1737
|
+
Standard routine to return the number of free bytes left in a music queue. The queue's get and put positions are taken from [QUETAB](#quetab) ([14FAH](#14fah)) and the free space determined by subtracting put from get.
|
|
1738
|
+
|
|
1739
|
+
<a name="14fah"></a>
|
|
1740
|
+
|
|
1741
|
+
Address... 14FAH
|
|
1742
|
+
|
|
1743
|
+
This routine returns a queue's control parameters from [QUETAB](#quetab), the queue number is supplied in register A. The control block is first located in [QUETAB](#quetab) ([1504H](#1504h)), the put position is then placed in register B, the get position in register C and the putback flag in register A.
|
|
1744
|
+
|
|
1745
|
+
<a name="1504h"></a>
|
|
1746
|
+
|
|
1747
|
+
Address... 1504H
|
|
1748
|
+
|
|
1749
|
+
This routine locates a queue's control block in [QUETAB](#quetab). The queue number is supplied in register A and the control block address returned in register pair HL. The queue number is simply multiplied by six, as there are six bytes per block, and added to the address of [QUETAB](#quetab) as held in [QUEUES](#queues).
|
|
1750
|
+
|
|
1751
|
+
<a name="1510h"></a><a name="grpprt"></a>
|
|
1752
|
+
|
|
1753
|
+
```
|
|
1754
|
+
Address... 1510H
|
|
1755
|
+
Name...... GRPPRT
|
|
1756
|
+
Entry..... A=Character
|
|
1757
|
+
Exit...... None
|
|
1758
|
+
Modifies.. EI
|
|
1759
|
+
```
|
|
1760
|
+
|
|
1761
|
+
Standard routine to display a character on the screen in either [Graphics Mode](#graphics_mode) or [Multicolour Mode](#multicolour_mode), it is functionally equivalent to the [CHPUT](#chput) standard routine.
|
|
1762
|
+
|
|
1763
|
+
The [CNVCHR](#cnvchr) standard routine is first used to check for a graphic character, if the character is a header code (01H) then the routine terminates with no action. If the character is a converted graphic one then the control code decoding section is skipped. Otherwise the character is checked to see if it is a control code. Only the CR code (0DH) is recognized ([157EH](#157eh)), all other characters smaller than 20H are ignored.
|
|
1764
|
+
|
|
1765
|
+
Assuming the character is displayable its eight byte pixel pattern is copied from the ROM character set into the [PATWRK](#patwrk) buffer (0752H) and [FORCLR](#forclr) copied to [ATRBYT](#atrbyt) to set its colour. The current graphics coordinates are then taken from [GRPACX](#grpacx) and [GRPACY](#grpacy) and used to set the current pixel physical address via the [SCALXY](#scalxy) and [MAPXYC](#mapxyc) standard routines.
|
|
1766
|
+
|
|
1767
|
+
The eight byte pattern in [PATWRK](#patwrk) is processed a byte at a time. At the start of each byte the current pixel physical address is obtained via the [FETCHC](#fetchc) standard routine and saved. The eight bits are then examined in turn. If the bit is a 1 the associated pixel is set by the [SETC](#setc) standard routine, if it is a 0 no action is taken. After each bit the current pixel physical address is moved right ([16ACH](#16ach)). When the byte is finished, or the right hand edge of the screen is reached, the initial current pixel physical address is restored and moved down one position by the [TDOWNC](#tdownc) standard routine.
|
|
1768
|
+
|
|
1769
|
+
When the pattern is complete, or the bottom of the screen has been reached, [GRPACX](#grpacx) is updated. In [Graphics Mode](#graphics_mode) its value is increased by eight, in [Multicolour Mode](#multicolour_mode) by thirty-two. If [GRPACX](#grpacx) then exceeds 255, the right hand edge of the screen, a CR operation is performed ([157EH](#157eh)).
|
|
1770
|
+
|
|
1771
|
+
<a name="157eh"></a>
|
|
1772
|
+
|
|
1773
|
+
Address... 157EH
|
|
1774
|
+
|
|
1775
|
+
This routine performs the CR operation for the [GRPPRT](#grpprt) standard routine, this code functions as a combined CR,LF. [GRPACX](#grpacx) is zeroed and eight or thirty-two, depending on the screen mode, added to [GRPACY](#grpacy). If [GRPACY](#grpacy) then exceeds 191, the bottom of the screen, it is set to zero.
|
|
1776
|
+
|
|
1777
|
+
[GRPACX](#grpacx) and [GRPACY](#grpacy) may be manipulated directly by an application program to compensate for the limited number of control functions available.
|
|
1778
|
+
|
|
1779
|
+
<a name="1599h"></a><a name="scalxy"></a>
|
|
1780
|
+
|
|
1781
|
+
```
|
|
1782
|
+
Address... 1599H
|
|
1783
|
+
Name...... SCALXY
|
|
1784
|
+
Entry..... BC=X coordinate, DE=Y coordinate
|
|
1785
|
+
Exit...... Flag NC if clipped
|
|
1786
|
+
Modifies.. AF
|
|
1787
|
+
```
|
|
1788
|
+
|
|
1789
|
+
Standard routine to clip a pair of graphics coordinates if necessary. The BASIC Interpreter can produce coordinates in the range -32768 to +32767 even though this far exceeds the actual screen size. This routine modifies excessive coordinate values to fit within the physically realizable range. If the X coordinate is greater than 255 it is set to 255, if the Y coordinate is greater than 191 it is set to 191. If either coordinate is negative (greater than 7FFFH) it is set to zero. Finally if the screen is in [Multicolour Mode](#multicolour_mode) both coordinates are divided by four as required by the [MAPXYC](#mapxyc) standard routine.
|
|
1790
|
+
|
|
1791
|
+
Address... 15D9H
|
|
1792
|
+
|
|
1793
|
+
This routine is used to check the current screen mode, it returns Flag Z if the screen is in [Graphics Mode](#graphics_mode).
|
|
1794
|
+
|
|
1795
|
+
<a name="15dfh"></a><a name="mapxyc"></a>
|
|
1796
|
+
|
|
1797
|
+
```
|
|
1798
|
+
Address... 15DFH
|
|
1799
|
+
Name...... MAPXYC
|
|
1800
|
+
Entry..... BC=X coordinate, DE=Y coordinate
|
|
1801
|
+
Exit...... None
|
|
1802
|
+
Modifies.. AF, D, HL
|
|
1803
|
+
```
|
|
1804
|
+
|
|
1805
|
+
Standard routine to convert a graphics coordinate pair into the current pixel physical address. The location in the Character Pattern Table of the byte containing the pixel is placed in [CLOC](#cloc). The bit mask identifying the pixel within that byte is placed in [CMASK](#cmask). Slightly different conversion methods are used for [Graphics Mode](#graphics_mode) and [Multicolour Mode](#multicolour_mode), equivalent programs in BASIC are:
|
|
1806
|
+
|
|
1807
|
+
```
|
|
1808
|
+
Graphics Mode
|
|
1809
|
+
|
|
1810
|
+
10 INPUT"X,Y Coordinates";X,Y
|
|
1811
|
+
20 A=(Y\8)*256+(Y AND 7)+(X AND &HF8)
|
|
1812
|
+
30 PRINT"ADDR=";HEX$(Base(12)+A);"H ";
|
|
1813
|
+
40 RESTORE 100
|
|
1814
|
+
50 FOR N=0 TO (X AND 7):READ M$: NEXT N
|
|
1815
|
+
60 PRINT"MASK=";M$
|
|
1816
|
+
70 GOTO 10
|
|
1817
|
+
100 DATA 10000000
|
|
1818
|
+
110 DATA 01000000
|
|
1819
|
+
120 DATA 00100000
|
|
1820
|
+
130 DATA 00010000
|
|
1821
|
+
140 DATA 00001000
|
|
1822
|
+
150 DATA 00000100
|
|
1823
|
+
160 DATA 00000010
|
|
1824
|
+
170 DATA 00000001
|
|
1825
|
+
```
|
|
1826
|
+
|
|
1827
|
+
</a>
|
|
1828
|
+
|
|
1829
|
+
```
|
|
1830
|
+
Multicolour Mode
|
|
1831
|
+
|
|
1832
|
+
10 INPUT"X,Y Coordinates";X,Y
|
|
1833
|
+
20 X=X\4:Y-Y\4
|
|
1834
|
+
30 A=(Y\8)*256+(Y AND 7)+(X*4 AND &HF8)
|
|
1835
|
+
40 PRINT"ADDR=";HEX$(BASE(17)+A);"H ";
|
|
1836
|
+
50 IF X MOD 2=0 THEN MS="11110000" ELSE MS="00001111"
|
|
1837
|
+
60 PRINT"MASK=";M$
|
|
1838
|
+
70 GOTO 10
|
|
1839
|
+
```
|
|
1840
|
+
|
|
1841
|
+
The allowable input range for both programs is X=0 to 255 and Y=0 to 191. The data statements in the [Graphics Mode](#graphics_mode) program correspond to the eight byte mask table commencing at 160BH in the MSX ROM. Line 20 in the [Multicolour Mode](#multicolour_mode) program actually corresponds to the division by four in the [SCALXY](#scalxy) standard routine. It is included to make the coordinate system consistent for both programs.
|
|
1842
|
+
|
|
1843
|
+
<a name="1639h"></a><a name="fetchc"></a>
|
|
1844
|
+
|
|
1845
|
+
```
|
|
1846
|
+
Address... 1639H
|
|
1847
|
+
Name...... FETCHC
|
|
1848
|
+
Entry..... None
|
|
1849
|
+
Exit...... A=CMASK, HL=CLOC
|
|
1850
|
+
Modifies.. A, HL
|
|
1851
|
+
```
|
|
1852
|
+
|
|
1853
|
+
Standard routine to return the current pixel physical address, register pair HL is loaded from [CLOC](#cloc) and register A from [CMASK](#cmask).
|
|
1854
|
+
|
|
1855
|
+
<a name="1640h"></a><a name="storec"></a>
|
|
1856
|
+
|
|
1857
|
+
```
|
|
1858
|
+
Address... 1640H
|
|
1859
|
+
Name...... STOREC
|
|
1860
|
+
Entry..... A=CMASK, HL=CLOC
|
|
1861
|
+
Exit...... None
|
|
1862
|
+
Modifies.. None
|
|
1863
|
+
```
|
|
1864
|
+
|
|
1865
|
+
Standard routine to set the current pixel physical address, register pair HL is copied to [CLOC](#cloc) and register A is copied to [CMASK](#cmask).
|
|
1866
|
+
|
|
1867
|
+
<a name="1647h"></a><a name="readc"></a>
|
|
1868
|
+
|
|
1869
|
+
```
|
|
1870
|
+
Address... 1647H
|
|
1871
|
+
Name...... READC
|
|
1872
|
+
Entry..... None
|
|
1873
|
+
Exit...... A=Colour code of current pixel
|
|
1874
|
+
Modifies.. AF, EI
|
|
1875
|
+
```
|
|
1876
|
+
|
|
1877
|
+
Standard routine to return the colour of the current pixel. The VRAM physical address is first obtained via the [FETCHC](#fetchc) standard routine. If the screen is in [Graphics Mode](#graphics_mode) the byte pointed to by [CLOC](#cloc) is read from the Character Pattern Table via the [RDVRM](#rdvrm) standard routine. The required bit is then isolated by [CMASK](#cmask) and used to select either the upper or lower four bits of the corresponding entry in the Colour Table.
|
|
1878
|
+
|
|
1879
|
+
If the screen is in [Multicolour Mode](#multicolour_mode) the byte pointed to by [CLOC](#cloc) is read from the Character Pattern Table via the [RDVRM](#rdvrm) standard routine. [CMASK](#cmask) is then used to select either the upper or lower four bits of this byte. The value returned in either case will be a normal VDP colour code from zero to fifteen.
|
|
1880
|
+
|
|
1881
|
+
<a name="1676h"></a><a name="setatr"></a>
|
|
1882
|
+
|
|
1883
|
+
```
|
|
1884
|
+
Address... 1676H
|
|
1885
|
+
Name...... SETATR
|
|
1886
|
+
Entry..... A=Colour code
|
|
1887
|
+
Exit...... Flag C if illegal code
|
|
1888
|
+
Modifies.. Flags
|
|
1889
|
+
```
|
|
1890
|
+
|
|
1891
|
+
Standard routine to set the graphics ink colour used by the [SETC](#setc) and [NSETCX](#nsetcx) standard routines. The colour code, from zero to fifteen, is simply placed in [ATRBYT](#atrbyt).
|
|
1892
|
+
|
|
1893
|
+
<a name="167eh"></a><a name="setc"></a>
|
|
1894
|
+
|
|
1895
|
+
```
|
|
1896
|
+
Address... 167EH
|
|
1897
|
+
Name...... SETC
|
|
1898
|
+
Entry..... None
|
|
1899
|
+
Exit...... None
|
|
1900
|
+
Modifies.. AF, EI
|
|
1901
|
+
```
|
|
1902
|
+
|
|
1903
|
+
Standard routine to set the current pixel to any colour, the colour code is taken from [ATRBYT](#atrbyt). The pixel's VRAM physical address is first obtained via the [FETCHC](#fetchc) standard routine. In [Graphics Mode](#graphics_mode) both the Character Pattern Table and Colour Table are then modified ([186CH](#186ch)).
|
|
1904
|
+
|
|
1905
|
+
In [Multicolour Mode](#multicolour_mode) the byte pointed to by [CLOC](#cloc) is read from the Character Pattern Table by the [RDVRM](#rdvrm) standard routine. The contents of [ATRBYT](#atrbyt) are then placed in the upper or lower four bits, as determined by [CMASK](#cmask), and the byte written back via the [WRTVRM](#wrtvrm) standard routine
|
|
1906
|
+
|
|
1907
|
+
<a name="16ach"></a>
|
|
1908
|
+
|
|
1909
|
+
Address... 16ACH
|
|
1910
|
+
|
|
1911
|
+
This routine moves the current pixel physical address one position right. If the right hand edge of the screen is exceeded it returns with Flag C and the physical address is unchanged. In [Graphics Mode](#graphics_mode) [CMASK](#cmask) is first shifted one bit right, if the pixel still remains within the byte the routine terminates. If [CLOC](#cloc) is at the rightmost character cell (LSB=F8H to FFH) then the routine terminates with Flag C (175AH). Otherwise [CMASK](#cmask) is set to 80H, the leftmost pixel, and 0008H added to [CLOC](#cloc).
|
|
1912
|
+
|
|
1913
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([1779H](#1779h)).
|
|
1914
|
+
|
|
1915
|
+
<a name="16c5h"></a><a name="rightc"></a>
|
|
1916
|
+
|
|
1917
|
+
```
|
|
1918
|
+
Address... 16C5H
|
|
1919
|
+
Name...... RIGHTC
|
|
1920
|
+
Entry..... None
|
|
1921
|
+
Exit...... None
|
|
1922
|
+
Modifies.. AF
|
|
1923
|
+
```
|
|
1924
|
+
|
|
1925
|
+
Standard routine to move the current pixel physical address one position right. In [Graphics Mode](#graphics_mode) [CMASK](#cmask) is first shifted one bit right, if the pixel still remains within the byte the routine terminates. Otherwise [CMASK](#cmask) is set to 80H, the leftmost pixel, and 0008H added to [CLOC](#cloc). Note that incorrect addresses will be produced if the right hand edge of the screen is exceeded.
|
|
1926
|
+
|
|
1927
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([178BH](#178bh)).
|
|
1928
|
+
|
|
1929
|
+
<a name="16d8h"></a>
|
|
1930
|
+
|
|
1931
|
+
Address... 16D8H
|
|
1932
|
+
|
|
1933
|
+
This routine moves the current pixel physical address one position left. If the left hand edge of the screen is exceeded it returns Flag C and the physical address is unchanged. In [Graphics Mode](#graphics_mode) [CMASK](#cmask) is first shifted one bit left, if the pixel still remains within the byte the routine terminates. If [CLOC](#cloc) is at the leftmost character cell (LSB=00H to 07H) then the routine terminates with Flag C (175AH). Otherwise [CMASK](#cmask) is set to 01H, the rightmost pixel, and 0008H subtracted from [CLOC](#cloc).
|
|
1934
|
+
|
|
1935
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([179CH](#179ch)).
|
|
1936
|
+
|
|
1937
|
+
<a name="16eeh"></a><a name="leftc"></a>
|
|
1938
|
+
|
|
1939
|
+
```
|
|
1940
|
+
Address... 16EEH
|
|
1941
|
+
Name...... LEFTC
|
|
1942
|
+
Entry..... None
|
|
1943
|
+
Exit...... None
|
|
1944
|
+
Modifies.. AF
|
|
1945
|
+
```
|
|
1946
|
+
|
|
1947
|
+
Standard routine to move the current pixel physical address one position left. In [Graphics Mode](#graphics_mode) [CMASK](#cmask) is first shifted one bit left, if the pixel still remains within the byte the routine terminates. Otherwise [CMASK](#cmask) is set to 01H, the leftmost pixel, and 0008H subtracted from [CLOC](#cloc). Note that incorrect addresses will be produced if the left hand edge of the screen is exceeded.
|
|
1948
|
+
|
|
1949
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([17ACH](#17ach)).
|
|
1950
|
+
|
|
1951
|
+
<a name="170ah"></a><a name="tdownc"></a>
|
|
1952
|
+
|
|
1953
|
+
```
|
|
1954
|
+
Address... 170AH
|
|
1955
|
+
Name...... TDOWNC
|
|
1956
|
+
Entry..... None
|
|
1957
|
+
Exit...... Flag C if off screen
|
|
1958
|
+
Modifies.. AF
|
|
1959
|
+
```
|
|
1960
|
+
|
|
1961
|
+
Standard routine to move the current pixel physical address one position down. If the bottom edge of the screen is exceeded it returns Flag C and the physical address is unchanged. In [Graphics Mode](#graphics_mode) [CLOC](#cloc) is first incremented, if it still remains within an eight byte boundary the routine terminates. If [CLOC](#cloc) was in the bottom character row ([CLOC](#cloc)>=1700H) then the routine terminates with Flag C (1759H). Otherwise 00F8H is added to [CLOC](#cloc).
|
|
1962
|
+
|
|
1963
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([17C6H](#17c6h)).
|
|
1964
|
+
|
|
1965
|
+
<a name="172ah"></a><a name="downc"></a>
|
|
1966
|
+
|
|
1967
|
+
```
|
|
1968
|
+
Address... 172AH
|
|
1969
|
+
Name...... DOWNC
|
|
1970
|
+
Entry..... None
|
|
1971
|
+
Exit...... None
|
|
1972
|
+
Modifies.. AF
|
|
1973
|
+
```
|
|
1974
|
+
|
|
1975
|
+
Standard routine to move the current pixel physical address one position down. In [Graphics Mode](#graphics_mode) [CLOC](#cloc) is first incremented, if it still remains within an eight byte boundary the routine terminates. Otherwise 00F8H is added to [CLOC](#cloc). Note that incorrect addresses will be produced if the bottom edge of the screen is exceeded.
|
|
1976
|
+
|
|
1977
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([17DCH](#17dch)).
|
|
1978
|
+
|
|
1979
|
+
<a name="173ch"></a><a name="tupc"></a>
|
|
1980
|
+
|
|
1981
|
+
```
|
|
1982
|
+
Address... 173CH
|
|
1983
|
+
Name...... TUPC
|
|
1984
|
+
Entry..... None
|
|
1985
|
+
Exit...... Flag C if off screen
|
|
1986
|
+
Modifies.. AF
|
|
1987
|
+
```
|
|
1988
|
+
|
|
1989
|
+
Standard routine to move the current pixel physical address one position up. If the top edge of the screen is exceeded it returns with Flag C and the physical address is unchanged. In [Graphics Mode](#graphics_mode) [CLOC](#cloc) is first decremented, if it still remains within an eight byte boundary the routine terminates. If [CLOC](#cloc) was in the top character row ([CLOC](#cloc)<0100H) then the routine terminates with Flag C. Otherwise 00F8H is subtracted from [CLOC](#cloc).
|
|
1990
|
+
|
|
1991
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([17E3H](#17e3h)).
|
|
1992
|
+
|
|
1993
|
+
<a name="175dh"></a><a name="upc"></a>
|
|
1994
|
+
|
|
1995
|
+
```
|
|
1996
|
+
Address... 175DH
|
|
1997
|
+
Name...... UPC
|
|
1998
|
+
Entry..... None
|
|
1999
|
+
Exit...... None
|
|
2000
|
+
Modifies.. AF
|
|
2001
|
+
```
|
|
2002
|
+
|
|
2003
|
+
Standard routine to move the current pixel physical address one position up. In [Graphics Mode](#graphics_mode) [CLOC](#cloc) is first decremented, if it still remains within an eight byte boundary the routine terminates. Otherwise 00F8H is subtracted from [CLOC](#cloc). Note that incorrect addresses will be produced if the top edge of the screen is exceeded.
|
|
2004
|
+
|
|
2005
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([17F8H](#17f8h)).
|
|
2006
|
+
|
|
2007
|
+
<a name="1779h"></a>
|
|
2008
|
+
|
|
2009
|
+
Address... 1779H
|
|
2010
|
+
|
|
2011
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the routine at [16ACH](#16ach). It is identical to the [Graphics Mode](#graphics_mode) version except that [CMASK](#cmask) is shifted four bit positions right and becomes F0H if a cell boundary is crossed.
|
|
2012
|
+
|
|
2013
|
+
<a name="178bh"></a>
|
|
2014
|
+
|
|
2015
|
+
Address... 178BH
|
|
2016
|
+
|
|
2017
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the [RIGHTC](#rightc) standard routine. It is identical to the [Graphics Mode](#graphics_mode) version except that [CMASK](#cmask) is shifted four bit positions right and becomes F0H if a cell boundary is crossed.
|
|
2018
|
+
|
|
2019
|
+
<a name="179ch"></a>
|
|
2020
|
+
|
|
2021
|
+
Address... 179CH
|
|
2022
|
+
|
|
2023
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the routine at [16D8H](#16d8h). It is identical to the [Graphics Mode](#graphics_mode) version except that [CMASK](#cmask) is shifted four bit positions left and becomes 0FH if a cell boundary is crossed.
|
|
2024
|
+
|
|
2025
|
+
<a name="17ach"></a>
|
|
2026
|
+
|
|
2027
|
+
Address... 17ACH
|
|
2028
|
+
|
|
2029
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the [LEFTC](#leftc) standard routine. It is identical to the [Graphics Mode](#graphics_mode) version except that [CMASK](#cmask) is shifted four bit positions left and becomes 0FH if a cell boundary is crossed.
|
|
2030
|
+
|
|
2031
|
+
<a name="17c6h"></a>
|
|
2032
|
+
|
|
2033
|
+
Address... 17C6H
|
|
2034
|
+
|
|
2035
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the [TDOWNC](#tdownc) standard routine. It is identical to the [Graphics Mode](#graphics_mode) version except that the bottom boundary address is 0500H instead of 1700H. There is a bug in this routine which will cause it to behave unpredictably if [MLTCGP](#mltcgp), the Character Pattern Table base address, is changed from its normal value of zero. There should be an `EX DE,HL` instruction inserted at address 17CEH.
|
|
2036
|
+
|
|
2037
|
+
If the Character Pattern Table base is increased the routine will think it has reached the bottom of the screen when it actually has not. This routine is used by the "`PAINT`" statement so the following demonstrates the fault:
|
|
2038
|
+
|
|
2039
|
+
```
|
|
2040
|
+
10 BASE(17)=&H1000
|
|
2041
|
+
20 SCREEN 3
|
|
2042
|
+
30 PSET(200,0)
|
|
2043
|
+
40 DRAW"D180L100U180R100"
|
|
2044
|
+
50 PAINT(150,90)
|
|
2045
|
+
60 GOTO 60
|
|
2046
|
+
```
|
|
2047
|
+
|
|
2048
|
+
</a>
|
|
2049
|
+
|
|
2050
|
+
<a name="17dch"></a>
|
|
2051
|
+
|
|
2052
|
+
Address... 17DCH
|
|
2053
|
+
|
|
2054
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the [DOWNC](#downc) standard routine, it is identical to the [Graphics Mode](#graphics_mode) version.
|
|
2055
|
+
|
|
2056
|
+
<a name="17e3h"></a>
|
|
2057
|
+
|
|
2058
|
+
Address... 17E3H
|
|
2059
|
+
|
|
2060
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the [TUPC](#tupc) standard routine. It is identical to the [Graphics Mode](#graphics_mode) version except that is has a bug as above, this time there should be an `EX DE,HL` instruction at address 17EBH.
|
|
2061
|
+
|
|
2062
|
+
If the Character Pattern Table base address is increased the routine will think it is within the table when it has actually exceeded the top edge of the screen. This may be demonstrated by removing the "`R100`" part of Line 40 in the previous program.
|
|
2063
|
+
|
|
2064
|
+
<a name="17f8h"></a>
|
|
2065
|
+
|
|
2066
|
+
Address... 17F8H
|
|
2067
|
+
|
|
2068
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the [UPC](#upc) standard routine, it is identical to the [Graphics Mode](#graphics_mode) version.
|
|
2069
|
+
|
|
2070
|
+
<a name="1809h"></a><a name="nsetcx"></a>
|
|
2071
|
+
|
|
2072
|
+
```
|
|
2073
|
+
Address... 1809H
|
|
2074
|
+
Name...... NSETCX
|
|
2075
|
+
Entry..... HL=Pixel fill count
|
|
2076
|
+
Exit...... None
|
|
2077
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
2078
|
+
```
|
|
2079
|
+
|
|
2080
|
+
Standard routine to set the colour of multiple pixels horizontally rightwards from the current pixel physical address. Although its function can be duplicated by the [SETC](#setc) and [RIGHTC](#rightc) standard routines this would result in significantly slower operation. The supplied pixel count should be chosen so that the right-hand edge of the screen is not passed as this will produce anomalous behaviour. The current pixel physical address is unchanged by this routine.
|
|
2081
|
+
|
|
2082
|
+
In [Graphics Mode](#graphics_mode) [CMASK](#cmask) is first examined to determine the number of pixels to the right within the current character cell. Assuming the fill count is large enough these are then set ([186CH](#186ch)). The remaining fill count is divided by eight to determine the number of whole character cells. Successive bytes in the Character Pattern Table are then zeroed and the corresponding bytes in the Colour Table set from [ATRBYT](#atrbyt) to fill these whole cells. The remaining fill count is then converted to a bit mask, using the seven byte table at 185DH, and these pixels are set ([186CH](#186ch)).
|
|
2083
|
+
|
|
2084
|
+
In [Multicolour Mode](#multicolour_mode) control transfers to a separate routine ([18BBH](#18bbh)).
|
|
2085
|
+
|
|
2086
|
+
<a name="186ch"></a>
|
|
2087
|
+
|
|
2088
|
+
Address... 186CH
|
|
2089
|
+
|
|
2090
|
+
This routine sets up to eight pixels within a cell to a specified colour in [Graphics Mode](#graphicsmod). [ATRBYT](#atrbyt) contains the colour code, register pair HL the address of the relevant byte in the Character Pattern Table and register A a bit mask, 11100000 for example, where every 1 specifies a bit to be set.
|
|
2091
|
+
|
|
2092
|
+
If [ATRBYT](#atrbyt) matches the existing 1 pixel colour in the corresponding Colour Table byte then each specified bit is set to 1 in the Character Pattern Table byte. If [ATRBYT](#atrbyt) matches the existing 0 pixel colour in the corresponding Colour Table byte then each specified bit is set to 0 in the Character Pattern Table byte.
|
|
2093
|
+
|
|
2094
|
+
If [ATRBYT](#atrbyt) does not match either of the existing colours in the Colour Table Byte then normally each specified bit is set to 1 in the Character Pattern Table byte and the 1 pixel colour changed in the Colour Table byte. However if this would result in all bits being set to 1 in the Character Pattern Table byte then each specified bit is set to 0 and the 0 pixel colour changed in the Colour Table byte.
|
|
2095
|
+
|
|
2096
|
+
<a name="18bbh"></a>
|
|
2097
|
+
|
|
2098
|
+
Address... 18BBH
|
|
2099
|
+
|
|
2100
|
+
This is the [Multicolour Mode](#multicolour_mode) version of the [NSETCX](#nsetcx) standard routine. The [SETC](#setc) and [RIGHTC](#rightc) standard routines are called until the fill count is exhausted. Speed of operation is not so important in [Multicolour Mode](#multicolour_mode) because of the lower screen resolution and the consequent reduction in the number of operations required.
|
|
2101
|
+
|
|
2102
|
+
<a name="18c7h"></a><a name="gtaspc"></a>
|
|
2103
|
+
|
|
2104
|
+
```
|
|
2105
|
+
Address... 18C7H
|
|
2106
|
+
Name...... GTASPC
|
|
2107
|
+
Entry..... None
|
|
2108
|
+
Exit...... DE=ASPCT1, HL=ASPCT2
|
|
2109
|
+
Modifies.. DE, HL
|
|
2110
|
+
```
|
|
2111
|
+
|
|
2112
|
+
Standard routine to return the "`CIRCLE`" statement default aspect ratios.
|
|
2113
|
+
|
|
2114
|
+
<a name="18cfh"></a><a name="pntini"></a>
|
|
2115
|
+
|
|
2116
|
+
```
|
|
2117
|
+
Address... 18CFH
|
|
2118
|
+
Name...... PNTINI
|
|
2119
|
+
Entry..... A=Boundary colour (0 to 15)
|
|
2120
|
+
Exit...... Flag C if illegal colour
|
|
2121
|
+
Modifies.. AF
|
|
2122
|
+
```
|
|
2123
|
+
|
|
2124
|
+
Standard routine to set the boundary colour for the "`PAINT`" statement. In [Multicolour Mode](#multicolour_mode) the supplied colour code is placed in [BDRATR](#bdratr). In [Graphics Mode](#graphics_mode) [BDRATR](#bdratr) is copied from [ATRBYT](#atrbyt) as it is not possible to have separate paint and boundary colours.
|
|
2125
|
+
|
|
2126
|
+
<a name="18e4h"></a><a name="scanr"></a>
|
|
2127
|
+
|
|
2128
|
+
```
|
|
2129
|
+
Address... 18E4H
|
|
2130
|
+
Name...... SCANR
|
|
2131
|
+
Entry..... B=Fill switch, DE=Skip count
|
|
2132
|
+
Exit...... DE=Skip remainder, HL=Pixel count
|
|
2133
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
2134
|
+
```
|
|
2135
|
+
|
|
2136
|
+
Standard routine used by the "`PAINT`" statement handler to search rightwards from the current pixel physical address until a colour code equal to [BDRATR](#bdratr) is found or the edge of the screen is reached. The terminating position becomes the current pixel physical address and the initial position is returned in [CSAVEA](#csavea) and [CSAVEM](#csavem). The size of the traversed region is returned in register pair HL and [FILNAM](#filnam)+1. The traversed region is normally filled in but this can be inhibited, in [Graphics Mode](#graphics_mode) only, by using an entry parameter of zero in register B. The skip count in register pair DE determines the maximum number of pixels of the required colour that may be ignored from the initial starting position. This facility is used by the "`PAINT`" statement handler to search for gaps in a horizontal boundary blocking its upward progress.
|
|
2137
|
+
|
|
2138
|
+
<a name="197ah"></a><a name="scanl"></a>
|
|
2139
|
+
|
|
2140
|
+
```
|
|
2141
|
+
Address... 197AH
|
|
2142
|
+
Name...... SCANL
|
|
2143
|
+
Entry..... None
|
|
2144
|
+
Exit...... HL=Pixel count
|
|
2145
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
2146
|
+
```
|
|
2147
|
+
|
|
2148
|
+
Standard routine to search leftwards from the current pixel physical address until a colour code equal to [BDRATR](#bdratr) is found or the edge of the screen is reached. The terminating position becomes the current pixel physical address and the size of the traversed region is returned in register pair HL. The traversed region is always filled in.
|
|
2149
|
+
|
|
2150
|
+
<a name="19c7h"></a>
|
|
2151
|
+
|
|
2152
|
+
Address... 19C7H
|
|
2153
|
+
|
|
2154
|
+
This routine is used by the [SCANL](#scanl) and [SCANR](#scanr) standard routines to check the current pixel's colour against the boundary colour in [BDRATR](#bdratr).
|
|
2155
|
+
|
|
2156
|
+
<a name="19ddh"></a><a name="tapoof"></a>
|
|
2157
|
+
|
|
2158
|
+
```
|
|
2159
|
+
Address... 19DDH
|
|
2160
|
+
Name...... TAPOOF
|
|
2161
|
+
Entry..... None
|
|
2162
|
+
Exit...... None
|
|
2163
|
+
Modifies.. EI
|
|
2164
|
+
```
|
|
2165
|
+
|
|
2166
|
+
Standard routine to stop the cassette motor after data has been written to the cassette. After a delay of 550 ms, on MSX machines with one wait state, control drops into the [TAPIOF](#tapiof) standard routine.
|
|
2167
|
+
|
|
2168
|
+
<a name="19e9h"></a><a name="tapiof"></a>
|
|
2169
|
+
|
|
2170
|
+
```
|
|
2171
|
+
Address... 19E9H
|
|
2172
|
+
Name...... TAPIOF
|
|
2173
|
+
Entry..... None
|
|
2174
|
+
Exit...... None
|
|
2175
|
+
Modifies.. EI
|
|
2176
|
+
```
|
|
2177
|
+
|
|
2178
|
+
Standard routine to stop the cassette motor after data has been read from the cassette. The motor relay is opened via the [PPI Mode Port](#ppi_mode_port). Note that interrupts, which must be disabled during cassette data transfers for timing reasons, are enabled as this routine terminates.
|
|
2179
|
+
|
|
2180
|
+
<a name="19f1h"></a><a name="tapoon"></a>
|
|
2181
|
+
|
|
2182
|
+
```
|
|
2183
|
+
Address... 19F1H
|
|
2184
|
+
Name...... TAPOON
|
|
2185
|
+
Entry..... A=Header length switch
|
|
2186
|
+
Exit...... Flag C if CTRL-STOP termination
|
|
2187
|
+
Modifies.. AF, BC, HL, DI
|
|
2188
|
+
```
|
|
2189
|
+
|
|
2190
|
+
Standard routine to turn the cassette motor on, wait 550 ms for the tape to come up to speed and then write a header to the cassette. A header is a burst of HI cycles written in front of every data block so the baud rate can be determined when the data is read back.
|
|
2191
|
+
|
|
2192
|
+
The length of the header is determined by the contents of register A: 00H=Short header, NZ=Long header. The BASIC cassette statements "`SAVE`", "`CSAVE`" and "`BSAVE`" all generate a long header at the start of the file, in front of the identification block, and thereafter use short headers between data blocks. The number of cycles in the header is also modified by the current baud rate so as to keep its duration constant:
|
|
2193
|
+
|
|
2194
|
+
```
|
|
2195
|
+
1200 Baud SHORT ... 3840 Cycles ... 1.5 Seconds
|
|
2196
|
+
1200 Baud LONG ... 15360 Cycles ... 6.1 Seconds
|
|
2197
|
+
2400 Baud SHORT ... 7936 Cycles ... 1.6 Seconds
|
|
2198
|
+
2400 Baud LONG ... 31744 Cycles ... 6.3 Seconds
|
|
2199
|
+
```
|
|
2200
|
+
|
|
2201
|
+
After the motor has been turned on and the delay has expired the contents of [HEADER](#header) are multiplied by two hundred and fifty-six and, if register A is non-zero, by a further factor of four to produce the cycle count. HI cycles are then generated ([1A4DH](#1a4dh)) until the count is exhausted whereupon control transfers to the [BREAKX](#breakx) standard routine. Because the CTRL-STOP key is only examined at termination it is impossible to break out part way through this routine.
|
|
2202
|
+
|
|
2203
|
+
<a name="1a19h"></a><a name="tapout"></a>
|
|
2204
|
+
|
|
2205
|
+
```
|
|
2206
|
+
Address... 1A19H
|
|
2207
|
+
Name...... TAPOUT
|
|
2208
|
+
Entry..... A=Data byte
|
|
2209
|
+
Exit...... Flag C if CTRL-STOP termination
|
|
2210
|
+
Modifies.. AF, B, HL
|
|
2211
|
+
```
|
|
2212
|
+
|
|
2213
|
+
Standard routine to write a single byte of data to the cassette. The MSX ROM uses a software driven FSK (Frequency Shift Keyed) method for storing information on the cassette. At the 1200 baud rate this is identical to the Kansas City Standard used by the BBC for the distribution of BASICODE programs.
|
|
2214
|
+
|
|
2215
|
+
At 1200 baud each 0 bit is written as one complete 1200 Hz LO cycle and each 1 bit as two complete 2400 Hz HI cycles. The data rate is thus constant as 0 and 1 bits have the same duration. When the 2400 baud rate is selected the two frequencies change to 2400 Hz and 4800 Hz but the format is otherwise unchanged.
|
|
2216
|
+
|
|
2217
|
+
A byte of data is written with a 0 start bit ([1A50H](#1a50h)), eight data bits with the least significant bit first, and two 1 stop bits ([1A40H](#1a40h)). At the 1200 baud rate a single byte will have a nominal duration of 11 x 833 µs = 9.2 ms. After the stop bits have been written control transfers to the [BREAKX](#breakx) standard routine to check the CTRL-STOP key. The byte 43H is shown below as it would be written to cassette:
|
|
2218
|
+
|
|
2219
|
+
<a name="figure39b"></a>![][CH04F39b]
|
|
2220
|
+
|
|
2221
|
+
**Figure 39:** Cassette Data Byte
|
|
2222
|
+
|
|
2223
|
+
It is important not to leave too long an interval between bytes when writing data as this will increase the error rate. An inter-byte gap of 80 µs, for example, produces a read failure rate of approximately twelve percent. If a substantial amount of processing is required between each byte then buffering should be used to lump data into headered blocks. The BASIC "`SAVE`" format is of this type.
|
|
2224
|
+
|
|
2225
|
+
<a name="1a39h"></a>
|
|
2226
|
+
|
|
2227
|
+
Address... 1A39H
|
|
2228
|
+
|
|
2229
|
+
This routine writes a single LO cycle with a length of approximately 816 µs to the cassette. The length of each half of the cycle is taken from [LOW](#low) and control transfers to the general cycle generator ([1A50H](#1a50h)).
|
|
2230
|
+
|
|
2231
|
+
<a name="1a40h"></a>
|
|
2232
|
+
|
|
2233
|
+
Address... 1A40H
|
|
2234
|
+
|
|
2235
|
+
This routine writes two HI cycles to the cassette. The first cycle is generated ([1A4DH](#1a4dh)) followed by a 17 µs delay and then the second cycle ([1A4DH](#1a4dh)).
|
|
2236
|
+
|
|
2237
|
+
<a name="1a4dh"></a>
|
|
2238
|
+
|
|
2239
|
+
Address... 1A4DH
|
|
2240
|
+
|
|
2241
|
+
This routine writes a single HI cycle with a length of approximately 396 µs to the cassette. The length of each half of the cycle is taken from [HIGH](#high) and control drops into the general cycle generator.
|
|
2242
|
+
|
|
2243
|
+
<a name="1a50h"></a>
|
|
2244
|
+
|
|
2245
|
+
Address... 1A50H
|
|
2246
|
+
|
|
2247
|
+
This routine writes a single cycle to the cassette. The length of the cycle's first half is supplied in register L and its second half in register H. The first length is counted down and then the Cas Out bit set via the [PPI Mode Port](#ppi_mode_port). The second length is counted down and the Cas Out bit reset.
|
|
2248
|
+
|
|
2249
|
+
On all MSX machines the Z80 runs at a clock frequency of 3.579545 MHz (280 ns) with one wait state during the M1 cycle. As this routine counts every 16T states each unit increment in the length count represents a period of 4.47 µs. There is also a fixed overhead of 20.7 µs associated with the routine whatever the length count.
|
|
2250
|
+
|
|
2251
|
+
<a name="1a63h"></a><a name="tapion"></a>
|
|
2252
|
+
|
|
2253
|
+
```
|
|
2254
|
+
Address... 1A63H
|
|
2255
|
+
Name...... TAPION
|
|
2256
|
+
Entry..... None
|
|
2257
|
+
Exit...... Flag C if CTRL-STOP termination
|
|
2258
|
+
Modifies.. AF, BC, DE, HL, DI
|
|
2259
|
+
```
|
|
2260
|
+
|
|
2261
|
+
Standard routine to turn the cassette motor on, read the cassette until a header is found and then determine the baud rate. Successive cycles are read from the cassette and the length of each one measured ([1B34H](#1b34h)). When 1,111 cycles have been found with less than 35 µs variation in their lengths a header has been located.
|
|
2262
|
+
|
|
2263
|
+
The next 256 cycles are then read ([1B34H](#1b34h)) and averaged to determine the cassette HI cycle length. This figure is multiplied by 1.5 and placed in [LOWLIM](#lowlim) where it defines the minimum acceptable length of a 0 start bit. The HI cycle length is placed in [WINWID](#winwid) and will be used to discriminate between LO and HI cycles.
|
|
2264
|
+
|
|
2265
|
+
<a name="1abch"></a><a name="tapin"></a>
|
|
2266
|
+
|
|
2267
|
+
```
|
|
2268
|
+
Address... 1ABCH
|
|
2269
|
+
Name...... TAPIN
|
|
2270
|
+
Entry..... None
|
|
2271
|
+
Exit...... A=Byte read, Flag C if CTRL-STOP or I/O error
|
|
2272
|
+
Modifies.. AF, BC, DE, L
|
|
2273
|
+
```
|
|
2274
|
+
|
|
2275
|
+
Standard routine to read a byte of data from the cassette. The cassette is first read continuously until a start bit is found. This is done by locating a negative transition, measuring the following cycle length ([1B1FH](#1b1fh)) and comparing this to see if it is greater than [LOWLIM](#lowlim).
|
|
2276
|
+
|
|
2277
|
+
Each of the eight data bits is then read by counting the number of transitions within a fixed period of time ([1B03H](#1b03h)). If zero or one transitions are found it is a 0 bit, if two or three are found it is a 1 bit. If more than three transitions are found the routine terminates with Flag C as this is presumed to be a hardware error of some sort. After the value of each bit has been determined a further one or two transitions are read (1B23H) to retain synchronization. With an odd transition count one more will be read, with an even transition count two more.
|
|
2278
|
+
|
|
2279
|
+
<a name="1b03h"></a>
|
|
2280
|
+
|
|
2281
|
+
Address... 1B03H
|
|
2282
|
+
|
|
2283
|
+
This routine is used by the [TAPIN](#tapin) standard routine to count the number of cassette transitions within a fixed period of time. The window duration is contained in [WINWID](#winwid) and is approximately 1.5 times the length of a HI cycle as shown below:
|
|
2284
|
+
|
|
2285
|
+
<a name="figure40"></a>![][CH04F40]
|
|
2286
|
+
|
|
2287
|
+
**Figure 40:** Cassette Window
|
|
2288
|
+
|
|
2289
|
+
The Cas Input bit is continuously sampled via PSG [Register 14](#register_14) and compared with the previous reading held in register E. Each time a change of state is found register C is incremented. The sampling rate is once every 17.3 µs so the value in [WINWID](#winwid), which was determined by the [TAPION](#tapion) standard routine with a count rate of 11.45 µs, is effectively multiplied one and a half times.
|
|
2290
|
+
|
|
2291
|
+
<a name="1b1fh"></a>
|
|
2292
|
+
|
|
2293
|
+
Address... 1B1FH
|
|
2294
|
+
|
|
2295
|
+
This routine measures the time to the next cassette input transition. The Cassette Input bit is continuously sampled via PSG [Register 14](#register_14) until it changes from the state supplied in register E. The state flag is then inverted and the duration count returned in register C, each unit increment represents a period of 11.45 µs.
|
|
2296
|
+
|
|
2297
|
+
<a name="1b34h"></a>
|
|
2298
|
+
|
|
2299
|
+
Address... 1B34H
|
|
2300
|
+
|
|
2301
|
+
This routine measures the length of a complete cassette cycle from negative transition to negative transition. The Cassette Input bit is sampled via PSG [Register 14](#register_14) until it goes to zero. The transition flag in register E is set to zero and the time to the positive transition measured (1B23H). The time to the negative transition is then measured (1B25H) and the total returned in register C.
|
|
2302
|
+
|
|
2303
|
+
<a name="1b45h"></a><a name="outdo"></a>
|
|
2304
|
+
|
|
2305
|
+
```
|
|
2306
|
+
Address... 1B45H
|
|
2307
|
+
Name...... OUTDO
|
|
2308
|
+
Entry..... A=Character to output
|
|
2309
|
+
Exit...... None
|
|
2310
|
+
Modifies.. EI
|
|
2311
|
+
```
|
|
2312
|
+
|
|
2313
|
+
Standard routine used by the BASIC Interpreter to output a character to the current device. The [ISFLIO](#isflio) standard routine is first used to check whether output is currently directed to an I/O buffer, if so control transfers to the sequential output driver ([6C48H](#6c48h)) via the [CALBAS](#calbas) standard routine. If [PRTFLG](#prtflg) is zero control transfers to the [CHPUT](#chput) standard routine to output the character to the screen. Assuming the printer is active [RAWPRT](#rawprt) is checked. If this is non-zero the character is passed directly to the printer ([1BABH](#1babh)), otherwise control drops into the [OUTDLP](#outdlp) standard routine.
|
|
2314
|
+
|
|
2315
|
+
<a name="1b63h"></a><a name="outdlp"></a>
|
|
2316
|
+
|
|
2317
|
+
```
|
|
2318
|
+
Address... 1B63H
|
|
2319
|
+
Name...... OUTDLP
|
|
2320
|
+
Entry..... A=Character to output
|
|
2321
|
+
Exit...... None
|
|
2322
|
+
Modifies.. EI
|
|
2323
|
+
```
|
|
2324
|
+
|
|
2325
|
+
Standard routine to output a character to the printer. If the character is a TAB code (09H) spaces are issued to the [OUTDLP](#outdlp) standard routine until [LPTPOS](#lptpos) is a multiple of eight (0, 8, 16 etc.). If the character is a CR code (0DH) [LPTPOS](#lptpos) is zeroed if it is any other control code [LPTPOS](#lptpos) is unaffected, if it is a displayable character [LPTPOS](#lptpos) is incremented.
|
|
2326
|
+
|
|
2327
|
+
If [NTMSXP](#ntmsxp) is zero, meaning an MSX-specific printer is connected, the character is passed directly to the printer ([1BABH](#1babh)). Assuming a normal printer is connected the [CNVCHR](#cnvchr) standard routine is used to check for graphic characters. If the character is a header code (01H) the routine terminates with no action. If it is a converted graphic character it is replaced by a space, all other characters are passed to the printer (1BACH).
|
|
2328
|
+
|
|
2329
|
+
<a name="1b97h"></a>
|
|
2330
|
+
|
|
2331
|
+
Address... 1B97H
|
|
2332
|
+
|
|
2333
|
+
This twenty byte table is used by the keyboard decoder to find the correct routine for a given key number:
|
|
2334
|
+
|
|
2335
|
+
|KEY NUMBER |TO |FUNCTION
|
|
2336
|
+
|------------|:-----:|------------------
|
|
2337
|
+
|00H to 2FH |0F83H |Rows 0 to 5
|
|
2338
|
+
|30H to 32H |0F10H |SHIFT, CTRL, GRAPH
|
|
2339
|
+
|33H |0F36H |CAP
|
|
2340
|
+
|34H |0F10H |CODE
|
|
2341
|
+
|35H to 39H |0FC3H |F1 to F5
|
|
2342
|
+
|3AH to 3BH |0F10H |ESC, TAB
|
|
2343
|
+
|3CH |0F46H |STOP
|
|
2344
|
+
|3DH to 40H |0F10H |BS, CR, SEL, SPACE
|
|
2345
|
+
|41H |0F06H |HOME
|
|
2346
|
+
|42H to 57H |0F10H |INS, DEL, CURSOR
|
|
2347
|
+
|
|
2348
|
+
</a>
|
|
2349
|
+
|
|
2350
|
+
<a name="1babh"></a>
|
|
2351
|
+
|
|
2352
|
+
Address... 1BABH
|
|
2353
|
+
|
|
2354
|
+
This routine is used by the [OUTDLP](#outdlp) standard routine to pass a character to the printer. It is sent via the [LPTOUT](#lptout) standard routine, if this returns Flag C control transfers to the "`Device I/O error`" generator ([73B2H](#73b2h)) via the [CALBAS](#calbas) standard routine.
|
|
2355
|
+
|
|
2356
|
+
<a name="1bbfh"></a>
|
|
2357
|
+
|
|
2358
|
+
Address... 1BBFH
|
|
2359
|
+
|
|
2360
|
+
The following 2 KB contains the power-up character set. The first eight bytes contain the pattern for character code 00H, the second eight bytes the pattern for character code 01H and so on to character code FFH.
|
|
2361
|
+
|
|
2362
|
+
<a name="23bfh"></a><a name="pinlin"></a>
|
|
2363
|
+
|
|
2364
|
+
```
|
|
2365
|
+
Address... 23BFH
|
|
2366
|
+
Name...... PINLIN
|
|
2367
|
+
Entry..... None
|
|
2368
|
+
Exit...... HL=Start of text, Flag C if CTRL-STOP termination
|
|
2369
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
2370
|
+
```
|
|
2371
|
+
|
|
2372
|
+
Standard routine used by the BASIC Interpreter Mainloop to collect a logical line of text from the console. Control transfers to the [INLIN](#inlin) standard routine just after the point where the previous line has been cut (23E0H).
|
|
2373
|
+
|
|
2374
|
+
<a name="23cch"></a><a name="qinlin"></a>
|
|
2375
|
+
|
|
2376
|
+
```
|
|
2377
|
+
Address... 23CCH
|
|
2378
|
+
Name...... QINLIN
|
|
2379
|
+
Entry..... None
|
|
2380
|
+
Exit...... HL=Start of text, Flag C if CTRL-STOP termination
|
|
2381
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
2382
|
+
```
|
|
2383
|
+
|
|
2384
|
+
Standard routine used by the "`INPUT`" statement handler to collect a logical line of text from the console. The characters "`? `" are displayed via the [OUTDO](#outdo) standard routine and control drops into the [INLIN](#inlin) standard routine.
|
|
2385
|
+
|
|
2386
|
+
<a name="23d5h"></a><a name="inlin"></a>
|
|
2387
|
+
|
|
2388
|
+
```
|
|
2389
|
+
Address... 23D5H
|
|
2390
|
+
Name...... INLIN
|
|
2391
|
+
Entry..... None
|
|
2392
|
+
Exit...... HL=Start of text, Flag C if CTRL-STOP termination
|
|
2393
|
+
Modifies.. AF, BC, DE, HL, EI
|
|
2394
|
+
```
|
|
2395
|
+
|
|
2396
|
+
Standard routine used by the "`LINE INPUT`" statement handler to collect a logical line of text from the console. Characters are read from the keyboard until either the CR or CTRL-STOP keys are pressed. The logical line is then read from the screen character by character and placed in the Workspace Area text buffer [BUF](#buf).
|
|
2397
|
+
|
|
2398
|
+
The current screen coordinates are first taken from [CSRX](#csrx) and [CSRY](#csry) and placed in [FSTPOS](#fstpos). The screen row immediately above the current one then has its entry in [LINTTB](#linttb) made non-zero ([0C29H](#0c29h)) to stop it extending logically into the current row.
|
|
2399
|
+
|
|
2400
|
+
Each keyboard character read via the [CHGET](#chget) standard routine is checked (0919H) against the editing key table at [2439H](#2439h). Control then transfers to one of the editing routines or to the default key handler ([23FFH](#23ffh)) as appropriate. This process continues until Flag C is returned by the CTRL-STOP or CR routines. Register pair HL is then set to point to the start of [BUF](#buf) and the routine terminates. Note that the carry, flag is cleared when Flag NZ is also returned to distinguish between a CR or protected CTRL-STOP termination and a normal CTRL-STOP termination.
|
|
2401
|
+
|
|
2402
|
+
<a name="23ffh"></a>
|
|
2403
|
+
|
|
2404
|
+
Address... 23FFH
|
|
2405
|
+
|
|
2406
|
+
This routine processes all characters for the [INLIN](#inlin) standard routine except the special editing keys. If the character is a TAB code (09H) spaces are issued ([23FFH](#23ffh)) until [CSRX](#csrx) is a multiple of eight plus one (columns 1, 9, 17, 25, 33). If the character is a graphic header code (01H) it is simply echoed to the [OUTDO](#outdo) standard routine. All other control codes smaller than 20H are echoed to the [OUTDO](#outdo) standard routine after which [INSFLG](#insflg) and [CSTYLE](#cstyle) are zeroed. For the displayable characters [INSFLG](#insflg) is first checked and a space inserted ([24F2H](#24f2h)) if applicable before the character is echoed to the [OUTDO](#outdo) standard routine.
|
|
2407
|
+
|
|
2408
|
+
<a name="2439h"></a>
|
|
2409
|
+
|
|
2410
|
+
Address... 2439H
|
|
2411
|
+
|
|
2412
|
+
This table contains the special editing keys recognized by the [INLIN](#inlin) standard routine together with the relevant addresses:
|
|
2413
|
+
|
|
2414
|
+
|CODE |TO |FUNCTION
|
|
2415
|
+
|:---:|:----:|----------------------------
|
|
2416
|
+
|08H |2561H |BS, backspace
|
|
2417
|
+
|12H |24E5H |INS, toggle insert mode
|
|
2418
|
+
|1BH |23FEH |ESC, no action
|
|
2419
|
+
|02H |260EH |CTRL-B, previous word
|
|
2420
|
+
|06H |25F8H |CTRL-F, next word
|
|
2421
|
+
|0EH |25D7H |CTRL-N, end of logical line
|
|
2422
|
+
|05H |25B9H |CTRL-E, clear to end of line
|
|
2423
|
+
|03H |24C5H |CTRL-STOP, terminate
|
|
2424
|
+
|0DH |245AH |CR, terminate
|
|
2425
|
+
|15H |25AEH |CTRL-U, clear line
|
|
2426
|
+
|7FH |2550H |DEL, delete character
|
|
2427
|
+
|
|
2428
|
+
</a>
|
|
2429
|
+
|
|
2430
|
+
<a name="245ah"></a>
|
|
2431
|
+
|
|
2432
|
+
Address... 245AH
|
|
2433
|
+
|
|
2434
|
+
This routine performs the CR operation for the [INLIN](#inlin) standard routine. The starting coordinates of the logical line are found ([266CH](#266ch)) and the cursor removed from the screen ([0A2EH](#0a2eh)). Up to 254 characters are then read from the VDP VRAM ([0BD8H](#0bd8h)) and placed in [BUF](#buf). Any null codes (00H) are ignored, any characters smaller than 20H are replaced by a graphic header code (01H) and the character itself with 40H added. As the end of each physical row is reached [LINTTB](#linttb) is checked ([0C1DH](#0c1dh)) to see whether the logical line extends to the next physical row. Trailing spaces are then stripped from [BUF](#buf) and a zero byte added as an end of text marker. The cursor is restored to the screen ([09E1H](#09e1h)) and its coordinates set to the last physical row of the logical line via the [POSIT](#posit) standard routine. A LF code is issued to the [OUTDO](#outdo) standard routine, [INSFLG](#insflg) is zeroed and the routine terminates with a CR code (0DH) in register A and Flag NZ,C. This CR code will be echoed to the screen by the [INLIN](#inlin) standard routine mainloop just before it terminates.
|
|
2435
|
+
|
|
2436
|
+
<a name="24c5h"></a>
|
|
2437
|
+
|
|
2438
|
+
Address... 24C5H
|
|
2439
|
+
|
|
2440
|
+
This routine performs the CTRL-STOP operation for the [INLIN](#inlin) standard routine. The last physical row of the logical line is found by examining [LINTTB](#linttb) ([0C1DH](#0c1dh)), [CSTYLE](#cstyle) is zeroed, a zero byte is placed at the start of [BUF](#buf) and all music variables are cleared via the [GICINI](#gicini) standard routine. [TRPTBL](#trptbl) is then examined (0454H) to see if an "`ON STOP`" statement is active, if so the cursor is reset (24AFH) and the routine terminates with Flag NZ,C. [BASROM](#basrom) is then checked to see whether a protected ROM is running, if so the cursor is reset (24AFH) and the routine terminates with Flag NZ,C. Otherwise the cursor is reset (24B2H) and the routine terminates with Flag Z,C.
|
|
2441
|
+
|
|
2442
|
+
<a name="24e5h"></a>
|
|
2443
|
+
|
|
2444
|
+
Address... 24E5H
|
|
2445
|
+
|
|
2446
|
+
This routine performs the INS operation for the [INLIN](#inlin) standard routine. The current state of [INSFLG](#insflg) is inverted and control terminates via the [CSTYLE](#cstyle) setting routine (242CH).
|
|
2447
|
+
|
|
2448
|
+
<a name="24f2h"></a>
|
|
2449
|
+
|
|
2450
|
+
Address... 24F2H
|
|
2451
|
+
|
|
2452
|
+
This routine inserts a space character for the default key section of the [INLIN](#inlin) standard routine. The cursor is removed ([0A2EH](#0a2eh)) and the current cursor coordinates taken from [CSRX](#csrx) and [CSRY](#csry). The character at this position is read from the VDP VRAM ([0BD8H](#0bd8h)) and replaced with a space ([0BE6H](#0be6h)). Successive characters are then copied one column position to the right until the end of the physical row is reached.
|
|
2453
|
+
|
|
2454
|
+
At this point [LINTTB](#linttb) is examined ([0C1DH](#0c1dh)) to determine whether the logical line is extended, if so the process continues on the next physical row. Otherwise the character taken from the last column position is examined, if this is a space the routine terminates by replacing the cursor ([09E1H](#09e1h)). Otherwise the physical row's entry in [LINTTB](#linttb) is zeroed to indicate an extended logical line. The number of the next physical row is compared with the number of rows on the screen ([0C32H](#0c32h)). If the next row is the last one the screen is scrolled up (0A88H), otherwise a blank row is inserted (0AB7H) and the copying process continues.
|
|
2455
|
+
|
|
2456
|
+
<a name="2550h"></a>
|
|
2457
|
+
|
|
2458
|
+
Address... 2550H
|
|
2459
|
+
|
|
2460
|
+
This routine performs the DEL operation for the [INLIN](#inlin) standard routine. If the current cursor position is at the rightmost column and the logical line is not extended no action is taken other than to write a space to the VDP VRAM (2595H). Otherwise a RIGHT code (1CH) is issued to the [OUTDO](#outdo) standard routine and control drops into the BS routine.
|
|
2461
|
+
|
|
2462
|
+
<a name="2561h"></a>
|
|
2463
|
+
|
|
2464
|
+
Address... 2561H
|
|
2465
|
+
|
|
2466
|
+
This routine performs the BS operation for the [INLIN](#inlin) standard routine. The cursor is first removed ([0A2EH](#0a2eh)) and the cursor column coordinate decremented unless it is at the leftmost position and the previous row is not extended. Characters are then read from the VDP VRAM ([0BD8H](#0bd8h)) and written back one position to the left ([0BE6H](#0be6h)) until the end of the logical line is reached. At this point a space is written to the VDP VRAM ([0BE6H](#0be6h)) and the cursor character is restored ([09E1H](#09e1h)).
|
|
2467
|
+
|
|
2468
|
+
<a name="25aeh"></a>
|
|
2469
|
+
|
|
2470
|
+
Address... 25AEH
|
|
2471
|
+
|
|
2472
|
+
This routine performs the CTRL-U operation for the [INLIN](#inlin) standard routine. The cursor is removed ([0A2EH](#0a2eh)) and the start of the logical line located ([266CH](#266ch)) and placed in [CSRX](#csrx) and [CSRY](#csry). The entire logical line is then cleared (25BEH).
|
|
2473
|
+
|
|
2474
|
+
<a name="25b9h"></a>
|
|
2475
|
+
|
|
2476
|
+
Address... 25B9H
|
|
2477
|
+
|
|
2478
|
+
This routine performs the CTRL-E operation for the [INLIN](#inlin) standard routine. The cursor is removed ([0A2EH](#0a2eh)) and the remainder of the physical row cleared ([0AEEH](#0aeeh)). This process is repeated for successive physical rows until the end of the logical line is found in [LINTBB](#lintbb) ([0C1DH](#0c1dh)). The cursor is then restored ([09E1H](#09e1h)), [INSFLG](#insflg) zeroed and [CSTLYE](#cstlye) reset to a block cursor (242DH).
|
|
2479
|
+
|
|
2480
|
+
<a name="25d7h"></a>
|
|
2481
|
+
|
|
2482
|
+
Address... 25D7H
|
|
2483
|
+
|
|
2484
|
+
This routine performs the CTRL-N operation for the [INLIN](#inlin) standard routine. The cursor is removed ([0A2EH](#0a2eh)) and the last physical row of the logical line found by examination of [LINTTB](#linttb) ([0C1DH](#0c1dh)). Starting at the rightmost column of this physical row characters are read from the VDP VRAM ([0BD8H](#0bd8h)) until a non-space character is found. The cursor coordinates are then set one column to the right of this position ([0A5BH](#0a5bh)) and the routine terminates by restoring the cursor (25CDH).
|
|
2485
|
+
|
|
2486
|
+
<a name="25f8h"></a>
|
|
2487
|
+
|
|
2488
|
+
Address... 25F8H
|
|
2489
|
+
|
|
2490
|
+
This routine performs the CTRL-F operation for the [INLIN](#inlin) standard routine. The cursor is removed ([0A2EH](#0a2eh)) and moved successively right ([2624H](#2624h)) until a non-alphanumeric character is found. The cursor is then moved successively right ([2624H](#2624h)) until an alphanumeric character is found. The routine terminates by restoring the cursor (25CDH).
|
|
2491
|
+
|
|
2492
|
+
<a name="260eh"></a>
|
|
2493
|
+
|
|
2494
|
+
Address... 260EH
|
|
2495
|
+
|
|
2496
|
+
This routine performs the CTRL-B operation for the [INLIN](#inlin) standard routine. The cursor is removed ([0A2EH](#0a2eh)) and moved successively left ([2634H](#2634h)) until an alphanumeric character is found. The cursor is then moved successively left ([2634H](#2634h)) until a non-alphanumeric character is found and then moved one position right ([0A5BH](#0a5bh)). The routine terminates by restoring the cursor (25CDH).
|
|
2497
|
+
|
|
2498
|
+
<a name="2624h"></a>
|
|
2499
|
+
|
|
2500
|
+
Address... 2624H
|
|
2501
|
+
|
|
2502
|
+
This routine moves the cursor one position right ([0A5BH](#0a5bh)), loads register D with the rightmost column number, register E with the bottom row number and then tests for an alphanumeric character at the cursor position (263DH).
|
|
2503
|
+
|
|
2504
|
+
<a name="2634h"></a>
|
|
2505
|
+
|
|
2506
|
+
Address... 2634H
|
|
2507
|
+
|
|
2508
|
+
This routine moves the cursor one position left ([0A4CH](#0a4ch)), loads register D with the leftmost column number and register E with the top row number. The current cursor coordinates are compared with these values and the routine terminates Flag Z if the cursor is at this position. Otherwise the character at this position is read from the VDP VRAM ([0BD8H](#0bd8h)) and checked to see if it is alphanumeric. If so the routine terminates Flag NZ,C otherwise it terminates Flag NZ,NC.
|
|
2509
|
+
|
|
2510
|
+
The alphanumeric characters are the digits "0" to "9" and the letters "A" to "Z" and "a" to "z". Also included are the graphics characters 86H to 9FH and A6H to FFH, these were originally Japanese letters and should have been excluded during the conversion to the UK ROM.
|
|
2511
|
+
|
|
2512
|
+
<a name="266ch"></a>
|
|
2513
|
+
|
|
2514
|
+
Address... 266CH
|
|
2515
|
+
|
|
2516
|
+
This routine finds the start of a logical line and returns its screen coordinates in register pair HL. Each physical row above the current one is checked via the [LINTTB](#linttb) table ([0C1DH](#0c1dh)) until a non-extended row is found. The row immediately below this on the screen is the start of the logical line and its row number is placed in register L. This is then compared with [FSTPOS](#fstpos), which contains the row number when the [INLIN](#inlin) standard routine was first entered, to see if the cursor is still on the same line. If so the column coordinate in register H is set to its initial position from [FSTPOS](#fstpos). Otherwise register H is set to the leftmost position to return the whole line.
|
|
2517
|
+
|
|
2518
|
+
<a name="2680h"></a>
|
|
2519
|
+
<a name="2683h"></a>
|
|
2520
|
+
<a name="2686h"></a>
|
|
2521
|
+
<a name="2689h"></a>
|
|
2522
|
+
|
|
2523
|
+
```
|
|
2524
|
+
Address...2680H, JP to power-up initialize routine (7C76H).
|
|
2525
|
+
Address...2683H, JP to the SYNCHR standard routine (558CH).
|
|
2526
|
+
Address...2686H, JP to the CHRGTR standard routine (4666H).
|
|
2527
|
+
Address...2689H, JP to the GETYPR standard routine (5597H).
|
|
2528
|
+
```
|