From 1575d4f53805f177474b5bb96daebede9b2dfb73 Mon Sep 17 00:00:00 2001
From: root <root@ka-ata-killa.ourano.james.local>
Date: Wed, 24 Feb 2021 23:45:58 +0000
Subject: base

---
 docs/Acorn_BBCSMOct85_Sec1.pdf                     |  Bin 0 -> 6708693 bytes
 docs/README                                        |    6 +
 docs/SN76489.pdf                                   |  Bin 0 -> 249096 bytes
 docs/keyboard.odg                                  |  Bin 0 -> 16836 bytes
 docs/keyboard.png                                  |  Bin 0 -> 60246 bytes
 docs/keyboard.txt                                  |   81 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C000       |  876 ++++++++++
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C300       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C4C0       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C735       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CA39       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CDED       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D10D       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D4BF       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D940       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DF0C       |  512 ++++++
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E20E       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E435       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E6B0       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E887       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EAD9       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EEDA       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F135       |  549 +++++++
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F3CA       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F68B       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F9B4       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/FC00       |    1 +
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/Microbase  | 1682 ++++++++++++++++++++
 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/index.html |   80 +
 docs/texas_instruments_sn76489an.pdf               |  Bin 0 -> 344223 bytes
 31 files changed, 3805 insertions(+)
 create mode 100644 docs/Acorn_BBCSMOct85_Sec1.pdf
 create mode 100644 docs/README
 create mode 100644 docs/SN76489.pdf
 create mode 100644 docs/keyboard.odg
 create mode 100644 docs/keyboard.png
 create mode 100644 docs/keyboard.txt
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C000
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C300
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C4C0
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C735
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CA39
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CDED
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D10D
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D4BF
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D940
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DF0C
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E20E
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E435
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E6B0
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E887
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EAD9
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EEDA
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F135
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F3CA
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F68B
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F9B4
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/FC00
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/Microbase
 create mode 100644 docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/index.html
 create mode 100644 docs/texas_instruments_sn76489an.pdf

(limited to 'docs')

diff --git a/docs/Acorn_BBCSMOct85_Sec1.pdf b/docs/Acorn_BBCSMOct85_Sec1.pdf
new file mode 100644
index 0000000..c0a47b5
Binary files /dev/null and b/docs/Acorn_BBCSMOct85_Sec1.pdf differ
diff --git a/docs/README b/docs/README
new file mode 100644
index 0000000..47daf92
--- /dev/null
+++ b/docs/README
@@ -0,0 +1,6 @@
+T65 implementation from http://www.fpgaarcade.com/resources/T65_v302.zip (bug fixes from PACE dev)
+M6522 implementation from FPGA arcade VIC20 design.  Various bug fixes added locally.
+SN76489 implementation by Arnim Laeuger and obtained from FPGA arcade
+
+
+
diff --git a/docs/SN76489.pdf b/docs/SN76489.pdf
new file mode 100644
index 0000000..b103f37
Binary files /dev/null and b/docs/SN76489.pdf differ
diff --git a/docs/keyboard.odg b/docs/keyboard.odg
new file mode 100644
index 0000000..403b1e7
Binary files /dev/null and b/docs/keyboard.odg differ
diff --git a/docs/keyboard.png b/docs/keyboard.png
new file mode 100644
index 0000000..12735bd
Binary files /dev/null and b/docs/keyboard.png differ
diff --git a/docs/keyboard.txt b/docs/keyboard.txt
new file mode 100644
index 0000000..d63fa03
--- /dev/null
+++ b/docs/keyboard.txt
@@ -0,0 +1,81 @@
+Column	Row	Key	PC key	Scancode
+0	0	SHIFT	LEFT SHIFT, RIGHT SHIFT	12 + 59
+0	1	Q	Q	15
+0	2	F0	F10	09
+0	3	1 (!)	1	16
+0	4	CAPS LOCK	CAPS LOCK	58
+0	5	SHIFT LOCK	LEFT ALT	11
+0	6	TAB	TAB	0D
+0	7	ESCAPE	ESCAPE	76
+1	0	CTRL	LEFT CTRL, RIGHT CTRL	14 + E0,14
+1	1	3 (#)	3	26
+1	2	W	W	1D
+1	3	2 (")	2	1E
+1	4	A	A	1C
+1	5	S	S	1B
+1	6	Z	Z	1A
+1	7	F1	F1	05
+2	0	DIP 7
+2	1	4 ($)	4	25
+2	2	E	E	24
+2	3	D	D	23
+2	4	X	X	22
+2	5	C	C	21
+2	6	SPACE	SPACE	29
+2	7	F2	F2	06
+3	0	DIP 6
+3	1	5 (%)	5	2E
+3	2	T	T	2C
+3	3	R	R	2D
+3	4	F	F	2B
+3	5	G	G	34
+3	6	V	V	2A
+3	7	F3	F3	04
+4	0	DIP 5
+4	1	F4	F4	0C
+4	2	7 (')	7	3D
+4	3	6 (&)	6	36
+4	4	Y	Y	35
+4	5	H	H	33
+4	6	B	B	32
+4	7	F5	F5	03
+5	0	DIP 4
+5	1	8 (()	8	3E
+5	2	I	I	43
+5	3	U	U	3C
+5	4	J	J	3B
+5	5	N	N	31
+5	6	M	M	3A
+5	7	F6	F6	0B
+6	0	DIP 3
+6	1	F7	F7	83
+6	2	9 ())	9	46
+6	3	O	O	44
+6	4	K	K	42
+6	5	L	L	4B
+6	6	, (<)	,	41
+6	7	F8	F8	0A
+7	0	DIP 2
+7	1	- (=)	-	4E
+7	2	0	0	45
+7	3	P	P	4D
+7	4	@	`	0E
+7	5	; (+)	;	4C
+7	6	. (>)	.	49
+7	7	F9	F9	01
+8	0	DIP 1
+8	1	^ (~)	=	55
+8	2	_ (£)	#	5D
+8	3	[ ({)	[	54
+8	4	: (*)	'	52
+8	5	] (})	]	5B
+8	6	/ (?)	/	4A
+8	7	\ (|)	\	61
+9	0	DIP 0
+9	1	LEFT	LEFT	E0,6B
+9	2	DOWN	DOWN	E0,72
+9	3	UP	UP	E0,75
+9	4	RETURN	RETURN	5A
+9	5	DELETE	BACKSPACE	66
+9	6	COPY	END	E0,69
+9	7	RIGHT	RIGHT	E0,74
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C000 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C000
new file mode 100644
index 0000000..ccfc412
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C000
@@ -0,0 +1,876 @@
+BBC Operating System OS 1.20
+============================
+Commented disassembly by Geoff Cox, originally published on Micronet.
+Additional comments by J.G.Harston.
+
+***************** VDU CHARACTER FONT LOOK UP TABLE ****************************
+
+These are the default definitions for characters 32-127. The are accessed with
+OSWORD 10 (read character definition) and reprogrammed with VDU 23 (define
+character). If the character set is not exploded, then a block of 32 characters
+is copied to the soft character buffer at &0C00 when a character is defined.
+
+C000  DB  00  ;00000000   ........   &20  32 - ' '
+C001  DB  00  ;00000000   ........
+C002  DB  00  ;00000000   ........
+C003  DB  00  ;00000000   ........
+C004  DB  00  ;00000000   ........
+C005  DB  00  ;00000000   ........
+C006  DB  00  ;00000000   ........
+C007  DB  00  ;00000000   ........
+
+C008  DB  18  ;00011000   ...**...   &21  33 - '!'
+C009  DB  18  ;00011000   ...**...
+C00A  DB  18  ;00011000   ...**...
+C00B  DB  18  ;00011000   ...**...
+C00C  DB  18  ;00011000   ...**...
+C00D  DB  00  ;00000000   ........
+C00E  DB  18  ;00011000   ...**...
+C00F  DB  00  ;00000000   ........
+
+C010  DB  6C  ;01101100   .**.**..   &22  34 - '"'
+C011  DB  6C  ;01101100   .**.**..
+C012  DB  6C  ;01101100   .**.**..
+C013  DB  00  ;00000000   ........
+C014  DB  00  ;00000000   ........
+C015  DB  00  ;00000000   ........
+C016  DB  00  ;00000000   ........
+C017  DB  00  ;00000000   ........
+
+C018  DB  36  ;00110110   ..**.**.   &23  35 - '#'
+C019  DB  36  ;00110110   ..**.**.
+C01A  DB  7F  ;01111111   .*******
+C01B  DB  36  ;00110110   ..**.**.
+C01C  DB  7F  ;01111111   .*******
+C01D  DB  36  ;00110110   ..**.**.
+C01E  DB  36  ;00110110   ..**.**.
+C01F  DB  00  ;00000000   ........
+
+C020  DB  0C  ;00001100   ....**..   &24  36 - '$'
+C021  DB  3F  ;00111111   ..******
+C022  DB  68  ;01101000   .**.*...
+C023  DB  3E  ;00111110   ..*****.
+C024  DB  0B  ;00001011   ....*.**
+C025  DB  7E  ;01111110   .******.
+C026  DB  18  ;00011000   ...**...
+C027  DB  00  ;00000000   ........
+
+C028  DB  60  ;01100000   .**.....   &25  37 - '%'
+C029  DB  66  ;01100110   .**..**.
+C02A  DB  0C  ;00001100   ....**..
+C02B  DB  18  ;00011000   ...**...
+C02C  DB  30  ;00110000   ..**....
+C02D  DB  66  ;01100110   .**..**.
+C02E  DB  06  ;00000110   .....**.
+C02F  DB  00  ;00000000   ........
+
+C030  DB  38  ;00111000   ..***...   &26  38 - '&'
+C031  DB  6C  ;01101100   .**.**..
+C032  DB  6C  ;01101100   .**.**..
+C033  DB  38  ;00111000   ..***...
+C034  DB  6D  ;01101101   .**.**.*
+C035  DB  66  ;01100110   .**..**.
+C036  DB  3B  ;00111011   ..***.**
+C037  DB  00  ;00000000   ........
+
+C038  DB  0C  ;00001100   ....**..   &27  39 - '''
+C039  DB  18  ;00011000   ...**...
+C03A  DB  30  ;00110000   ..**....
+C03B  DB  00  ;00000000   ........
+C03C  DB  00  ;00000000   ........
+C03D  DB  00  ;00000000   ........
+C03E  DB  00  ;00000000   ........
+C03F  DB  00  ;00000000   ........
+
+C040  DB  0C  ;00001100   ....**..   &28  40 - '('
+C041  DB  18  ;00011000   ...**...
+C042  DB  30  ;00110000   ..**....
+C043  DB  30  ;00110000   ..**....
+C044  DB  30  ;00110000   ..**....
+C045  DB  18  ;00011000   ...**...
+C046  DB  0C  ;00001100   ....**..
+C047  DB  00  ;00000000   ........
+
+C048  DB  30  ;00110000   ..**....   &29  41 - ')'
+C049  DB  18  ;00011000   ...**...
+C04A  DB  0C  ;00001100   ....**..
+C04B  DB  0C  ;00001100   ....**..
+C04C  DB  0C  ;00001100   ....**..
+C04D  DB  18  ;00011000   ...**...
+C04E  DB  30  ;00110000   ..**....
+C04F  DB  00  ;00000000   ........
+
+C050  DB  00  ;00000000   ........   &2A  42 - '*'
+C051  DB  18  ;00011000   ...**...
+C052  DB  7E  ;01111110   .******.
+C053  DB  3C  ;00111100   ..****..
+C054  DB  7E  ;01111110   .******.
+C055  DB  18  ;00011000   ...**...
+C056  DB  00  ;00000000   ........
+C057  DB  00  ;00000000   ........
+
+C058  DB  00  ;00000000   ........   &2B  43 - '+'
+C059  DB  18  ;00011000   ...**...
+C05A  DB  18  ;00011000   ...**...
+C05B  DB  7E  ;01111110   .******.
+C05C  DB  18  ;00011000   ...**...
+C05D  DB  18  ;00011000   ...**...
+C05E  DB  00  ;00000000   ........
+C05F  DB  00  ;00000000   ........
+
+C060  DB  00  ;00000000   ........   &2C  44 - ','
+C061  DB  00  ;00000000   ........
+C062  DB  00  ;00000000   ........
+C063  DB  00  ;00000000   ........
+C064  DB  00  ;00000000   ........
+C065  DB  18  ;00011000   ...**...
+C066  DB  18  ;00011000   ...**...
+C067  DB  30  ;00110000   ..**....
+
+C068  DB  00  ;00000000   ........   &2D  45 - '-'
+C069  DB  00  ;00000000   ........
+C06A  DB  00  ;00000000   ........
+C06B  DB  7E  ;01111110   .******.
+C06C  DB  00  ;00000000   ........
+C06D  DB  00  ;00000000   ........
+C06E  DB  00  ;00000000   ........
+C06F  DB  00  ;00000000   ........
+
+C070  DB  00  ;00000000   ........   &2E  46 - '.'
+C071  DB  00  ;00000000   ........
+C072  DB  00  ;00000000   ........
+C073  DB  00  ;00000000   ........
+C074  DB  00  ;00000000   ........
+C075  DB  18  ;00011000   ...**...
+C076  DB  18  ;00011000   ...**...
+C077  DB  00  ;00000000   ........
+
+C078  DB  00  ;00000000   ........   &2F  47 - '/'
+C079  DB  06  ;00000110   .....**.
+C07A  DB  0C  ;00001100   ....**..
+C07B  DB  18  ;00011000   ...**...
+C07C  DB  30  ;00110000   ..**....
+C07D  DB  60  ;01100000   .**.....
+C07E  DB  00  ;00000000   ........
+C07F  DB  00  ;00000000   ........
+
+C080  DB  3C  ;00111100   ..****..   &30  48 - '0'
+C081  DB  66  ;01100110   .**..**.
+C082  DB  6E  ;01101110   .**.***.
+C083  DB  7E  ;01111110   .******.
+C084  DB  76  ;01110110   .***.**.
+C085  DB  66  ;01100110   .**..**.
+C086  DB  3C  ;00111100   ..****..
+C087  DB  00  ;00000000   ........
+
+C088  DB  18  ;00011000   ...**...   &31  49 - '1'
+C089  DB  38  ;00111000   ..***...
+C08A  DB  18  ;00011000   ...**...
+C08B  DB  18  ;00011000   ...**...
+C08C  DB  18  ;00011000   ...**...
+C08D  DB  18  ;00011000   ...**...
+C08E  DB  7E  ;01111110   .******.
+C08F  DB  00  ;00000000   ........
+
+C090  DB  3C  ;00111100   ..****..   &32  50 - '2'
+C091  DB  66  ;01100110   .**..**.
+C092  DB  06  ;00000110   .....**.
+C093  DB  0C  ;00001100   ....**..
+C094  DB  18  ;00011000   ...**...
+C095  DB  30  ;00110000   ..**....
+C096  DB  7E  ;01111110   .******.
+C097  DB  00  ;00000000   ........
+
+C098  DB  3C  ;00111100   ..****..   &33  51 - '3'
+C099  DB  66  ;01100110   .**..**.
+C09A  DB  06  ;00000110   .....**.
+C09B  DB  1C  ;00011100   ...***..
+C09C  DB  06  ;00000110   .....**.
+C09D  DB  66  ;01100110   .**..**.
+C09E  DB  3C  ;00111100   ..****..
+C09F  DB  00  ;00000000   ........
+
+C0A0  DB  0C  ;00001100   ....**..   &34  52 - '4'
+C0A1  DB  1C  ;00011100   ...***..
+C0A2  DB  3C  ;00111100   ..****..
+C0A3  DB  6C  ;01101100   .**.**..
+C0A4  DB  7E  ;01111110   .******.
+C0A5  DB  0C  ;00001100   ....**..
+C0A6  DB  0C  ;00001100   ....**..
+C0A7  DB  00  ;00000000   ........
+
+C0A8  DB  7E  ;01111110   .******.   &35  53 - '5'
+C0A9  DB  60  ;01100000   .**.....
+C0AA  DB  7C  ;01111100   .*****..
+C0AB  DB  06  ;00000110   .....**.
+C0AC  DB  06  ;00000110   .....**.
+C0AD  DB  66  ;01100110   .**..**.
+C0AE  DB  3C  ;00111100   ..****..
+C0AF  DB  00  ;00000000   ........
+
+C0B0  DB  1C  ;00011100   ...***..   &36  54 - '6'
+C0B1  DB  30  ;00110000   ..**....
+C0B2  DB  60  ;01100000   .**.....
+C0B3  DB  7C  ;01111100   .*****..
+C0B4  DB  66  ;01100110   .**..**.
+C0B5  DB  66  ;01100110   .**..**.
+C0B6  DB  3C  ;00111100   ..****..
+C0B7  DB  00  ;00000000   ........
+
+C0B8  DB  7E  ;01111110   .******.   &37  55 - '7'
+C0B9  DB  06  ;00000110   .....**.
+C0BA  DB  0C  ;00001100   ....**..
+C0BB  DB  18  ;00011000   ...**...
+C0BC  DB  30  ;00110000   ..**....
+C0BD  DB  30  ;00110000   ..**....
+C0BE  DB  30  ;00110000   ..**....
+C0BF  DB  00  ;00000000   ........
+
+C0C0  DB  3C  ;00111100   ..****..   &38  56 - '8'
+C0C1  DB  66  ;01100110   .**..**.
+C0C2  DB  66  ;01100110   .**..**.
+C0C3  DB  3C  ;00111100   ..****..
+C0C4  DB  66  ;01100110   .**..**.
+C0C5  DB  66  ;01100110   .**..**.
+C0C6  DB  3C  ;00111100   ..****..
+C0C7  DB  00  ;00000000   ........
+
+C0C8  DB  3C  ;00111100   ..****..   &39  57 - '9'
+C0C9  DB  66  ;01100110   .**..**.
+C0CA  DB  66  ;01100110   .**..**.
+C0CB  DB  3E  ;00111110   ..*****.
+C0CC  DB  06  ;00000110   .....**.
+C0CD  DB  0C  ;00001100   ....**..
+C0CE  DB  38  ;00111000   ..***...
+C0CF  DB  00  ;00000000   ........
+
+C0D0  DB  00  ;00000000   ........   &3A  58 - ':'
+C0D1  DB  00  ;00000000   ........
+C0D2  DB  18  ;00011000   ...**...
+C0D3  DB  18  ;00011000   ...**...
+C0D4  DB  00  ;00000000   ........
+C0D5  DB  18  ;00011000   ...**...
+C0D6  DB  18  ;00011000   ...**...
+C0D7  DB  00  ;00000000   ........
+
+C0D8  DB  00  ;00000000   ........   &3B  59 - ';'
+C0D9  DB  00  ;00000000   ........
+C0DA  DB  18  ;00011000   ...**...
+C0DB  DB  18  ;00011000   ...**...
+C0DC  DB  00  ;00000000   ........
+C0DD  DB  18  ;00011000   ...**...
+C0DE  DB  18  ;00011000   ...**...
+C0DF  DB  30  ;00110000   ..**....
+
+C0E0  DB  0C  ;00001100   ....**..   &3C  60 - '<'
+C0E1  DB  18  ;00011000   ...**...
+C0E2  DB  30  ;00110000   ..**....
+C0E3  DB  60  ;01100000   .**.....
+C0E4  DB  30  ;00110000   ..**....
+C0E5  DB  18  ;00011000   ...**...
+C0E6  DB  0C  ;00001100   ....**..
+C0E7  DB  00  ;00000000   ........
+
+C0E8  DB  00  ;00000000   ........   &3D  61 - '='
+C0E9  DB  00  ;00000000   ........
+C0EA  DB  7E  ;01111110   .******.
+C0EB  DB  00  ;00000000   ........
+C0EC  DB  7E  ;01111110   .******.
+C0ED  DB  00  ;00000000   ........
+C0EE  DB  00  ;00000000   ........
+C0EF  DB  00  ;00000000   ........
+
+C0F0  DB  30  ;00110000   ..**....   &3E  62 - '>'
+C0F1  DB  18  ;00011000   ...**...
+C0F2  DB  0C  ;00001100   ....**..
+C0F3  DB  06  ;00000110   .....**.
+C0F4  DB  0C  ;00001100   ....**..
+C0F5  DB  18  ;00011000   ...**...
+C0F6  DB  30  ;00110000   ..**....
+C0F7  DB  00  ;00000000   ........
+
+C0F8  DB  3C  ;00111100   ..****..   &3F  63 - '?'
+C0F9  DB  66  ;01100110   .**..**.
+C0FA  DB  0C  ;00001100   ....**..
+C0FB  DB  18  ;00011000   ...**...
+C0FC  DB  18  ;00011000   ...**...
+C0FD  DB  00  ;00000000   ........
+C0FE  DB  18  ;00011000   ...**...
+C0FF  DB  00  ;00000000   ........
+
+C100  DB  3C  ;00111100   ..****..   &40  64 - '@'
+C101  DB  66  ;01100110   .**..**.
+C102  DB  6E  ;01101110   .**.***.
+C103  DB  6A  ;01101010   .**.*.*.
+C104  DB  6E  ;01101110   .**.***.
+C105  DB  60  ;01100000   .**.....
+C106  DB  3C  ;00111100   ..****..
+C107  DB  00  ;00000000   ........
+
+C108  DB  3C  ;00111100   ..****..   &41  65 - 'A'
+C109  DB  66  ;01100110   .**..**.
+C10A  DB  66  ;01100110   .**..**.
+C10B  DB  7E  ;01111110   .******.
+C10C  DB  66  ;01100110   .**..**.
+C10D  DB  66  ;01100110   .**..**.
+C10E  DB  66  ;01100110   .**..**.
+C10F  DB  00  ;00000000   ........
+
+C110  DB  7C  ;01111100   .*****..   &42  66 - 'B'
+C111  DB  66  ;01100110   .**..**.
+C112  DB  66  ;01100110   .**..**.
+C113  DB  7C  ;01111100   .*****..
+C114  DB  66  ;01100110   .**..**.
+C115  DB  66  ;01100110   .**..**.
+C116  DB  7C  ;01111100   .*****..
+C117  DB  00  ;00000000   ........
+
+C118  DB  3C  ;00111100   ..****..   &43  67 - 'C'
+C119  DB  66  ;01100110   .**..**.
+C11A  DB  60  ;01100000   .**.....
+C11B  DB  60  ;01100000   .**.....
+C11C  DB  60  ;01100000   .**.....
+C11D  DB  66  ;01100110   .**..**.
+C11E  DB  3C  ;00111100   ..****..
+C11F  DB  00  ;00000000   ........
+
+C120  DB  78  ;01111000   .****...   &44  68 - 'D'
+C121  DB  6C  ;01101100   .**.**..
+C122  DB  66  ;01100110   .**..**.
+C123  DB  66  ;01100110   .**..**.
+C124  DB  66  ;01100110   .**..**.
+C125  DB  6C  ;01101100   .**.**..
+C126  DB  78  ;01111000   .****...
+C127  DB  00  ;00000000   ........
+
+C128  DB  7E  ;01111110   .******.   &45  69 - 'E'
+C129  DB  60  ;01100000   .**.....
+C12A  DB  60  ;01100000   .**.....
+C12B  DB  7C  ;01111100   .*****..
+C12C  DB  60  ;01100000   .**.....
+C12D  DB  60  ;01100000   .**.....
+C12E  DB  7E  ;01111110   .******.
+C12F  DB  00  ;00000000   ........
+
+C130  DB  7E  ;01111110   .******.   &46  70 - 'F'
+C131  DB  60  ;01100000   .**.....
+C132  DB  60  ;01100000   .**.....
+C133  DB  7C  ;01111100   .*****..
+C134  DB  60  ;01100000   .**.....
+C135  DB  60  ;01100000   .**.....
+C136  DB  60  ;01100000   .**.....
+C137  DB  00  ;00000000   ........
+
+C138  DB  3C  ;00111100   ..****..   &47  71 - 'G'
+C139  DB  66  ;01100110   .**..**.
+C13A  DB  60  ;01100000   .**.....
+C13B  DB  6E  ;01101110   .**.***.
+C13C  DB  66  ;01100110   .**..**.
+C13D  DB  66  ;01100110   .**..**.
+C13E  DB  3C  ;00111100   ..****..
+C13F  DB  00  ;00000000   ........
+
+C140  DB  66  ;01100110   .**..**.   &48  72 - 'H'
+C141  DB  66  ;01100110   .**..**.
+C142  DB  66  ;01100110   .**..**.
+C143  DB  7E  ;01111110   .******.
+C144  DB  66  ;01100110   .**..**.
+C145  DB  66  ;01100110   .**..**.
+C146  DB  66  ;01100110   .**..**.
+C147  DB  00  ;00000000   ........
+
+C148  DB  7E  ;01111110   .******.   &49  73 - 'I'
+C149  DB  18  ;00011000   ...**...
+C14A  DB  18  ;00011000   ...**...
+C14B  DB  18  ;00011000   ...**...
+C14C  DB  18  ;00011000   ...**...
+C14D  DB  18  ;00011000   ...**...
+C14E  DB  7E  ;01111110   .******.
+C14F  DB  00  ;00000000   ........
+
+C150  DB  3E  ;00111110   ..*****.   &4A  74 - 'J'
+C151  DB  0C  ;00001100   ....**..
+C152  DB  0C  ;00001100   ....**..
+C153  DB  0C  ;00001100   ....**..
+C154  DB  0C  ;00001100   ....**..
+C155  DB  6C  ;01101100   .**.**..
+C156  DB  38  ;00111000   ..***...
+C157  DB  00  ;00000000   ........
+
+C158  DB  66  ;01100110   .**..**.   &4B  75 - 'K'
+C159  DB  6C  ;01101100   .**.**..
+C15A  DB  78  ;01111000   .****...
+C15B  DB  70  ;01110000   .***....
+C15C  DB  78  ;01111000   .****...
+C15D  DB  6C  ;01101100   .**.**..
+C15E  DB  66  ;01100110   .**..**.
+C15F  DB  00  ;00000000   ........
+
+C160  DB  60  ;01100000   .**.....   &4C  76 - 'L'
+C161  DB  60  ;01100000   .**.....
+C162  DB  60  ;01100000   .**.....
+C163  DB  60  ;01100000   .**.....
+C164  DB  60  ;01100000   .**.....
+C165  DB  60  ;01100000   .**.....
+C166  DB  7E  ;01111110   .******.
+C167  DB  00  ;00000000   ........
+
+C168  DB  63  ;01100011   .**...**   &4D  77 - 'M'
+C169  DB  77  ;01110111   .***.***
+C16A  DB  7F  ;01111111   .*******
+C16B  DB  6B  ;01101011   .**.*.**
+C16C  DB  6B  ;01101011   .**.*.**
+C16D  DB  63  ;01100011   .**...**
+C16E  DB  63  ;01100011   .**...**
+C16F  DB  00  ;00000000   ........
+
+C170  DB  66  ;01100110   .**..**.   &4E  78 - 'N'
+C171  DB  66  ;01100110   .**..**.
+C172  DB  76  ;01110110   .***.**.
+C173  DB  7E  ;01111110   .******.
+C174  DB  6E  ;01101110   .**.***.
+C175  DB  66  ;01100110   .**..**.
+C176  DB  66  ;01100110   .**..**.
+C177  DB  00  ;00000000   ........
+
+C178  DB  3C  ;00111100   ..****..   &4F  79 - 'O'
+C179  DB  66  ;01100110   .**..**.
+C17A  DB  66  ;01100110   .**..**.
+C17B  DB  66  ;01100110   .**..**.
+C17C  DB  66  ;01100110   .**..**.
+C17D  DB  66  ;01100110   .**..**.
+C17E  DB  3C  ;00111100   ..****..
+C17F  DB  00  ;00000000   ........
+
+C180  DB  7C  ;01111100   .*****..   &50  80 - 'P'
+C181  DB  66  ;01100110   .**..**.
+C182  DB  66  ;01100110   .**..**.
+C183  DB  7C  ;01111100   .*****..
+C184  DB  60  ;01100000   .**.....
+C185  DB  60  ;01100000   .**.....
+C186  DB  60  ;01100000   .**.....
+C187  DB  00  ;00000000   ........
+
+C188  DB  3C  ;00111100   ..****..   &51  81 - 'Q'
+C189  DB  66  ;01100110   .**..**.
+C18A  DB  66  ;01100110   .**..**.
+C18B  DB  66  ;01100110   .**..**.
+C18C  DB  6A  ;01101010   .**.*.*.
+C18D  DB  6C  ;01101100   .**.**..
+C18E  DB  36  ;00110110   ..**.**.
+C18F  DB  00  ;00000000   ........
+
+C190  DB  7C  ;01111100   .*****..   &52  82 - 'R'
+C191  DB  66  ;01100110   .**..**.
+C192  DB  66  ;01100110   .**..**.
+C193  DB  7C  ;01111100   .*****..
+C194  DB  6C  ;01101100   .**.**..
+C195  DB  66  ;01100110   .**..**.
+C196  DB  66  ;01100110   .**..**.
+C197  DB  00  ;00000000   ........
+
+C198  DB  3C  ;00111100   ..****..   &53  83 - 'S'
+C199  DB  66  ;01100110   .**..**.
+C19A  DB  60  ;01100000   .**.....
+C19B  DB  3C  ;00111100   ..****..
+C19C  DB  06  ;00000110   .....**.
+C19D  DB  66  ;01100110   .**..**.
+C19E  DB  3C  ;00111100   ..****..
+C19F  DB  00  ;00000000   ........
+
+C1A0  DB  7E  ;01111110   .******.   &54  84 - 'T'
+C1A1  DB  18  ;00011000   ...**...
+C1A2  DB  18  ;00011000   ...**...
+C1A3  DB  18  ;00011000   ...**...
+C1A4  DB  18  ;00011000   ...**...
+C1A5  DB  18  ;00011000   ...**...
+C1A6  DB  18  ;00011000   ...**...
+C1A7  DB  00  ;00000000   ........
+
+C1A8  DB  66  ;01100110   .**..**.   &55  85 - 'U'
+C1A9  DB  66  ;01100110   .**..**.
+C1AA  DB  66  ;01100110   .**..**.
+C1AB  DB  66  ;01100110   .**..**.
+C1AC  DB  66  ;01100110   .**..**.
+C1AD  DB  66  ;01100110   .**..**.
+C1AE  DB  3C  ;00111100   ..****..
+C1AF  DB  00  ;00000000   ........
+
+C1B0  DB  66  ;01100110   .**..**.   &56  86 - 'V'
+C1B1  DB  66  ;01100110   .**..**.
+C1B2  DB  66  ;01100110   .**..**.
+C1B3  DB  66  ;01100110   .**..**.
+C1B4  DB  66  ;01100110   .**..**.
+C1B5  DB  3C  ;00111100   ..****..
+C1B6  DB  18  ;00011000   ...**...
+C1B7  DB  00  ;00000000   ........
+
+C1B8  DB  63  ;01100011   .**...**   &57  87 - 'W'
+C1B9  DB  63  ;01100011   .**...**
+C1BA  DB  6B  ;01101011   .**.*.**
+C1BB  DB  6B  ;01101011   .**.*.**
+C1BC  DB  7F  ;01111111   .*******
+C1BD  DB  77  ;01110111   .***.***
+C1BE  DB  63  ;01100011   .**...**
+C1BF  DB  00  ;00000000   ........
+
+C1C0  DB  66  ;01100110   .**..**.   &58  88 - 'X'
+C1C1  DB  66  ;01100110   .**..**.
+C1C2  DB  3C  ;00111100   ..****..
+C1C3  DB  18  ;00011000   ...**...
+C1C4  DB  3C  ;00111100   ..****..
+C1C5  DB  66  ;01100110   .**..**.
+C1C6  DB  66  ;01100110   .**..**.
+C1C7  DB  00  ;00000000   ........
+
+C1C8  DB  66  ;01100110   .**..**.   &59  89 - 'Y'
+C1C9  DB  66  ;01100110   .**..**.
+C1CA  DB  66  ;01100110   .**..**.
+C1CB  DB  3C  ;00111100   ..****..
+C1CC  DB  18  ;00011000   ...**...
+C1CD  DB  18  ;00011000   ...**...
+C1CE  DB  18  ;00011000   ...**...
+C1CF  DB  00  ;00000000   ........
+
+C1D0  DB  7E  ;01111110   .******.   &5A  90 - 'Z'
+C1D1  DB  06  ;00000110   .....**.
+C1D2  DB  0C  ;00001100   ....**..
+C1D3  DB  18  ;00011000   ...**...
+C1D4  DB  30  ;00110000   ..**....
+C1D5  DB  60  ;01100000   .**.....
+C1D6  DB  7E  ;01111110   .******.
+C1D7  DB  00  ;00000000   ........
+
+C1D8  DB  7C  ;01111100   .*****..   &5B  91 - '['
+C1D9  DB  60  ;01100000   .**.....
+C1DA  DB  60  ;01100000   .**.....
+C1DB  DB  60  ;01100000   .**.....
+C1DC  DB  60  ;01100000   .**.....
+C1DD  DB  60  ;01100000   .**.....
+C1DE  DB  7C  ;01111100   .*****..
+C1DF  DB  00  ;00000000   ........
+
+C1E0  DB  00  ;00000000   ........   &5C  92 - '\'
+C1E1  DB  60  ;01100000   .**.....
+C1E2  DB  30  ;00110000   ..**....
+C1E3  DB  18  ;00011000   ...**...
+C1E4  DB  0C  ;00001100   ....**..
+C1E5  DB  06  ;00000110   .....**.
+C1E6  DB  00  ;00000000   ........
+C1E7  DB  00  ;00000000   ........
+
+C1E8  DB  3E  ;00111110   ..*****.   &5D  93 - ']'
+C1E9  DB  06  ;00000110   .....**.
+C1EA  DB  06  ;00000110   .....**.
+C1EB  DB  06  ;00000110   .....**.
+C1EC  DB  06  ;00000110   .....**.
+C1ED  DB  06  ;00000110   .....**.
+C1EE  DB  3E  ;00111110   ..*****.
+C1EF  DB  00  ;00000000   ........
+
+C1F0  DB  18  ;00011000   ...**...   &5E  94 - '^'
+C1F1  DB  3C  ;00111100   ..****..
+C1F2  DB  66  ;01100110   .**..**.
+C1F3  DB  42  ;01000010   .*....*.
+C1F4  DB  00  ;00000000   ........
+C1F5  DB  00  ;00000000   ........
+C1F6  DB  00  ;00000000   ........
+C1F7  DB  00  ;00000000   ........
+
+C1F8  DB  00  ;00000000   ........   &5F  95 - '_'
+C1F9  DB  00  ;00000000   ........
+C1FA  DB  00  ;00000000   ........
+C1FB  DB  00  ;00000000   ........
+C1FC  DB  00  ;00000000   ........
+C1FD  DB  00  ;00000000   ........
+C1FE  DB  00  ;00000000   ........
+C1FF  DB  FF  ;11111111   ********
+
+C200  DB  1C  ;00011100   ...***..   &60  96 - '`'
+C201  DB  36  ;00110110   ..**.**.
+C202  DB  30  ;00110000   ..**....
+C203  DB  7C  ;01111100   .*****..
+C204  DB  30  ;00110000   ..**....
+C205  DB  30  ;00110000   ..**....
+C206  DB  7E  ;01111110   .******.
+C207  DB  00  ;00000000   ........
+
+C208  DB  00  ;00000000   ........   &61  97 - 'a'
+C209  DB  00  ;00000000   ........
+C20A  DB  3C  ;00111100   ..****..
+C20B  DB  06  ;00000110   .....**.
+C20C  DB  3E  ;00111110   ..*****.
+C20D  DB  66  ;01100110   .**..**.
+C20E  DB  3E  ;00111110   ..*****.
+C20F  DB  00  ;00000000   ........
+
+C210  DB  60  ;01100000   .**.....   &62  98 - 'b'
+C211  DB  60  ;01100000   .**.....
+C212  DB  7C  ;01111100   .*****..
+C213  DB  66  ;01100110   .**..**.
+C214  DB  66  ;01100110   .**..**.
+C215  DB  66  ;01100110   .**..**.
+C216  DB  7C  ;01111100   .*****..
+C217  DB  00  ;00000000   ........
+
+C218  DB  00  ;00000000   ........   &63  99 - 'c'
+C219  DB  00  ;00000000   ........
+C21A  DB  3C  ;00111100   ..****..
+C21B  DB  66  ;01100110   .**..**.
+C21C  DB  60  ;01100000   .**.....
+C21D  DB  66  ;01100110   .**..**.
+C21E  DB  3C  ;00111100   ..****..
+C21F  DB  00  ;00000000   ........
+
+C220  DB  06  ;00000110   .....**.   &64  100 - 'd'
+C221  DB  06  ;00000110   .....**.
+C222  DB  3E  ;00111110   ..*****.
+C223  DB  66  ;01100110   .**..**.
+C224  DB  66  ;01100110   .**..**.
+C225  DB  66  ;01100110   .**..**.
+C226  DB  3E  ;00111110   ..*****.
+C227  DB  00  ;00000000   ........
+
+C228  DB  00  ;00000000   ........   &65  101 - 'e'
+C229  DB  00  ;00000000   ........
+C22A  DB  3C  ;00111100   ..****..
+C22B  DB  66  ;01100110   .**..**.
+C22C  DB  7E  ;01111110   .******.
+C22D  DB  60  ;01100000   .**.....
+C22E  DB  3C  ;00111100   ..****..
+C22F  DB  00  ;00000000   ........
+
+C230  DB  1C  ;00011100   ...***..   &66  102 - 'f'
+C231  DB  30  ;00110000   ..**....
+C232  DB  30  ;00110000   ..**....
+C233  DB  7C  ;01111100   .*****..
+C234  DB  30  ;00110000   ..**....
+C235  DB  30  ;00110000   ..**....
+C236  DB  30  ;00110000   ..**....
+C237  DB  00  ;00000000   ........
+
+C238  DB  00  ;00000000   ........   &67  103 - 'g'
+C239  DB  00  ;00000000   ........
+C23A  DB  3E  ;00111110   ..*****.
+C23B  DB  66  ;01100110   .**..**.
+C23C  DB  66  ;01100110   .**..**.
+C23D  DB  3E  ;00111110   ..*****.
+C23E  DB  06  ;00000110   .....**.
+C23F  DB  3C  ;00111100   ..****..
+
+C240  DB  60  ;01100000   .**.....   &68  104 - 'h'
+C241  DB  60  ;01100000   .**.....
+C242  DB  7C  ;01111100   .*****..
+C243  DB  66  ;01100110   .**..**.
+C244  DB  66  ;01100110   .**..**.
+C245  DB  66  ;01100110   .**..**.
+C246  DB  66  ;01100110   .**..**.
+C247  DB  00  ;00000000   ........
+
+C248  DB  18  ;00011000   ...**...   &69  105 - 'i'
+C249  DB  00  ;00000000   ........
+C24A  DB  38  ;00111000   ..***...
+C24B  DB  18  ;00011000   ...**...
+C24C  DB  18  ;00011000   ...**...
+C24D  DB  18  ;00011000   ...**...
+C24E  DB  3C  ;00111100   ..****..
+C24F  DB  00  ;00000000   ........
+
+C250  DB  18  ;00011000   ...**...   &6A  106 - 'j'
+C251  DB  00  ;00000000   ........
+C252  DB  38  ;00111000   ..***...
+C253  DB  18  ;00011000   ...**...
+C254  DB  18  ;00011000   ...**...
+C255  DB  18  ;00011000   ...**...
+C256  DB  18  ;00011000   ...**...
+C257  DB  70  ;01110000   .***....
+
+C258  DB  60  ;01100000   .**.....   &6B  107 - 'k'
+C259  DB  60  ;01100000   .**.....
+C25A  DB  66  ;01100110   .**..**.
+C25B  DB  6C  ;01101100   .**.**..
+C25C  DB  78  ;01111000   .****...
+C25D  DB  6C  ;01101100   .**.**..
+C25E  DB  66  ;01100110   .**..**.
+C25F  DB  00  ;00000000   ........
+
+C260  DB  38  ;00111000   ..***...   &6C  108 - 'l'
+C261  DB  18  ;00011000   ...**...
+C262  DB  18  ;00011000   ...**...
+C263  DB  18  ;00011000   ...**...
+C264  DB  18  ;00011000   ...**...
+C265  DB  18  ;00011000   ...**...
+C266  DB  3C  ;00111100   ..****..
+C267  DB  00  ;00000000   ........
+
+C268  DB  00  ;00000000   ........   &6D  109 - 'm'
+C269  DB  00  ;00000000   ........
+C26A  DB  36  ;00110110   ..**.**.
+C26B  DB  7F  ;01111111   .*******
+C26C  DB  6B  ;01101011   .**.*.**
+C26D  DB  6B  ;01101011   .**.*.**
+C26E  DB  63  ;01100011   .**...**
+C26F  DB  00  ;00000000   ........
+
+C270  DB  00  ;00000000   ........   &6E  110 - 'n'
+C271  DB  00  ;00000000   ........
+C272  DB  7C  ;01111100   .*****..
+C273  DB  66  ;01100110   .**..**.
+C274  DB  66  ;01100110   .**..**.
+C275  DB  66  ;01100110   .**..**.
+C276  DB  66  ;01100110   .**..**.
+C277  DB  00  ;00000000   ........
+
+C278  DB  00  ;00000000   ........   &6F  111 - 'o'
+C279  DB  00  ;00000000   ........
+C27A  DB  3C  ;00111100   ..****..
+C27B  DB  66  ;01100110   .**..**.
+C27C  DB  66  ;01100110   .**..**.
+C27D  DB  66  ;01100110   .**..**.
+C27E  DB  3C  ;00111100   ..****..
+C27F  DB  00  ;00000000   ........
+
+C280  DB  00  ;00000000   ........   &70  112 - 'p'
+C281  DB  00  ;00000000   ........
+C282  DB  7C  ;01111100   .*****..
+C283  DB  66  ;01100110   .**..**.
+C284  DB  66  ;01100110   .**..**.
+C285  DB  7C  ;01111100   .*****..
+C286  DB  60  ;01100000   .**.....
+C287  DB  60  ;01100000   .**.....
+
+C288  DB  00  ;00000000   ........   &71  113 - 'q'
+C289  DB  00  ;00000000   ........
+C28A  DB  3E  ;00111110   ..*****.
+C28B  DB  66  ;01100110   .**..**.
+C28C  DB  66  ;01100110   .**..**.
+C28D  DB  3E  ;00111110   ..*****.
+C28E  DB  06  ;00000110   .....**.
+C28F  DB  07  ;00000111   .....***
+
+C290  DB  00  ;00000000   ........   &72  114 - 'r'
+C291  DB  00  ;00000000   ........
+C292  DB  6C  ;01101100   .**.**..
+C293  DB  76  ;01110110   .***.**.
+C294  DB  60  ;01100000   .**.....
+C295  DB  60  ;01100000   .**.....
+C296  DB  60  ;01100000   .**.....
+C297  DB  00  ;00000000   ........
+
+C298  DB  00  ;00000000   ........   &73  115 - 's'
+C299  DB  00  ;00000000   ........
+C29A  DB  3E  ;00111110   ..*****.
+C29B  DB  60  ;01100000   .**.....
+C29C  DB  3C  ;00111100   ..****..
+C29D  DB  06  ;00000110   .....**.
+C29E  DB  7C  ;01111100   .*****..
+C29F  DB  00  ;00000000   ........
+
+C2A0  DB  30  ;00110000   ..**....   &74  116 - 't'
+C2A1  DB  30  ;00110000   ..**....
+C2A2  DB  7C  ;01111100   .*****..
+C2A3  DB  30  ;00110000   ..**....
+C2A4  DB  30  ;00110000   ..**....
+C2A5  DB  30  ;00110000   ..**....
+C2A6  DB  1C  ;00011100   ...***..
+C2A7  DB  00  ;00000000   ........
+
+C2A8  DB  00  ;00000000   ........   &75  117 - 'u'
+C2A9  DB  00  ;00000000   ........
+C2AA  DB  66  ;01100110   .**..**.
+C2AB  DB  66  ;01100110   .**..**.
+C2AC  DB  66  ;01100110   .**..**.
+C2AD  DB  66  ;01100110   .**..**.
+C2AE  DB  3E  ;00111110   ..*****.
+C2AF  DB  00  ;00000000   ........
+
+C2B0  DB  00  ;00000000   ........   &76  118 - 'v'
+C2B1  DB  00  ;00000000   ........
+C2B2  DB  66  ;01100110   .**..**.
+C2B3  DB  66  ;01100110   .**..**.
+C2B4  DB  66  ;01100110   .**..**.
+C2B5  DB  3C  ;00111100   ..****..
+C2B6  DB  18  ;00011000   ...**...
+C2B7  DB  00  ;00000000   ........
+
+C2B8  DB  00  ;00000000   ........   &77  119 - 'w'
+C2B9  DB  00  ;00000000   ........
+C2BA  DB  63  ;01100011   .**...**
+C2BB  DB  6B  ;01101011   .**.*.**
+C2BC  DB  6B  ;01101011   .**.*.**
+C2BD  DB  7F  ;01111111   .*******
+C2BE  DB  36  ;00110110   ..**.**.
+C2BF  DB  00  ;00000000   ........
+
+C2C0  DB  00  ;00000000   ........   &78  120 - 'x'
+C2C1  DB  00  ;00000000   ........
+C2C2  DB  66  ;01100110   .**..**.
+C2C3  DB  3C  ;00111100   ..****..
+C2C4  DB  18  ;00011000   ...**...
+C2C5  DB  3C  ;00111100   ..****..
+C2C6  DB  66  ;01100110   .**..**.
+C2C7  DB  00  ;00000000   ........
+
+C2C8  DB  00  ;00000000   ........   &79  121 - 'y'
+C2C9  DB  00  ;00000000   ........
+C2CA  DB  66  ;01100110   .**..**.
+C2CB  DB  66  ;01100110   .**..**.
+C2CC  DB  66  ;01100110   .**..**.
+C2CD  DB  3E  ;00111110   ..*****.
+C2CE  DB  06  ;00000110   .....**.
+C2CF  DB  3C  ;00111100   ..****..
+
+C2D0  DB  00  ;00000000   ........   &7A  122 - 'z'
+C2D1  DB  00  ;00000000   ........
+C2D2  DB  7E  ;01111110   .******.
+C2D3  DB  0C  ;00001100   ....**..
+C2D4  DB  18  ;00011000   ...**...
+C2D5  DB  30  ;00110000   ..**....
+C2D6  DB  7E  ;01111110   .******.
+C2D7  DB  00  ;00000000   ........
+
+C2D8  DB  0C  ;00001100   ....**..   &7B  123 - '{'
+C2D9  DB  18  ;00011000   ...**...
+C2DA  DB  18  ;00011000   ...**...
+C2DB  DB  70  ;01110000   .***....
+C2DC  DB  18  ;00011000   ...**...
+C2DD  DB  18  ;00011000   ...**...
+C2DE  DB  0C  ;00001100   ....**..
+C2DF  DB  00  ;00000000   ........
+
+C2E0  DB  18  ;00011000   ...**...   &7C  124 - '|'
+C2E1  DB  18  ;00011000   ...**...
+C2E2  DB  18  ;00011000   ...**...
+C2E3  DB  00  ;00000000   ........
+C2E4  DB  18  ;00011000   ...**...
+C2E5  DB  18  ;00011000   ...**...
+C2E6  DB  18  ;00011000   ...**...
+C2E7  DB  00  ;00000000   ........
+
+C2E8  DB  30  ;00110000   ..**....   &7D  125 - '}'
+C2E9  DB  18  ;00011000   ...**...
+C2EA  DB  18  ;00011000   ...**...
+C2EB  DB  0E  ;00001110   ....***.
+C2EC  DB  18  ;00011000   ...**...
+C2ED  DB  18  ;00011000   ...**...
+C2EE  DB  30  ;00110000   ..**....
+C2EF  DB  00  ;00000000   ........
+
+C2F0  DB  31  ;00110001   ..**...*   &7E  126 - '~'
+C2F1  DB  6B  ;01101011   .**.*.**
+C2F2  DB  46  ;01000110   .*...**.
+C2F3  DB  00  ;00000000   ........
+C2F4  DB  00  ;00000000   ........
+C2F5  DB  00  ;00000000   ........
+C2F6  DB  00  ;00000000   ........
+C2F7  DB  00  ;00000000   ........
+
+C2F8  DB  FF  ;11111111   ********   &7F  127 - DEL
+C2F9  DB  FF  ;11111111   ********
+C2FA  DB  FF  ;11111111   ********
+C2FB  DB  FF  ;11111111   ********
+C2FC  DB  FF  ;11111111   ********
+C2FD  DB  FF  ;11111111   ********
+C2FE  DB  FF  ;11111111   ********
+C2FF  DB  FF  ;11111111   ********
+
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C300 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C300
new file mode 100644
index 0000000..83abcfd
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C300
@@ -0,0 +1 @@
+BBC Operation System OS 1.20		Startup Strings and Tables

C300 JMP  &CB1D  ;Initialise screen with mode in A.

C303 DB  13,'BBC Computer ',0

C312 DB '16K',7,0

C317 DB '32K',7,0

C31C DB 08,0D,0D ;Termination byte in next table


****** 16 COLOUR MODE BYTE MASK LOOK UP TABLE******

C31F  DB  00  ;00000000
C320  DB  11  ;00010001
C321  DB  22  ;00100010
C322  DB  33  ;00110011
C323  DB  44  ;01000100
C324  DB  55  ;01010101
C325  DB  66  ;01100110
C326  DB  77  ;01110111
C327  DB  88  ;10001000
C328  DB  99  ;10011001
C329  DB  AA  ;10101010
C32A  DB  BB  ;10111011
C32B  DB  CC  ;11001100
C32C  DB  DD  ;11011101
C32D  DB  EE  ;11101110
C32E  DB  FF  ;11111111


****** 4 COLOUR MODE BYTE MASK LOOK UP TABLE******

C32F  DB  00  ;00000000
C330  DB  55  ;01010101
C331  DB  AA  ;10101010
C332  DB  FF  ;11111111


****** VDU ENTRY POINT LO       LOOK UP TABLE******

C333  DB  11  ;00010001
C334  DB  3B  ;00111011
C335  DB  96  ;10010110
C336  DB  A1  ;10100001
C337  DB  AD  ;10101101
C338  DB  B9  ;10111001
C339  DB  11  ;00010001
C33A  DB  6F  ;01101111
C33B  DB  C5  ;11000101
C33C  DB  64  ;01100100
C33D  DB  F0  ;11110000
C33E  DB  5B  ;01011011
C33F  DB  59  ;01011001
C340  DB  AF  ;10101111
C341  DB  8D  ;10001101
C342  DB  A6  ;10100110
C343  DB  C0  ;11000000
C344  DB  F9  ;11111001
C345  DB  FD  ;11111101
C346  DB  92  ;10010010
C347  DB  39  ;00111001
C348  DB  9B  ;10011011
C349  DB  EB  ;11101011
C34A  DB  F1  ;11110001
C34B  DB  39  ;00111001
C34C  DB  8C  ;10001100
C34D  DB  BD  ;10111101
C34E  DB  11  ;00010001
C34F  DB  FA  ;11111010
C350  DB  A2  ;10100010
C351  DB  79  ;01111001
C352  DB  87  ;10000111
C353  DB  AC  ;10101100


****** VDU ENTRY POINT HI PARAMETER LOOK UP TABLE******

; 1xxxxxxx - no parameters, address high byte
; 0aaapppp - parameter count 16-p, address high byte &C3+a

C354  DB  C5  ;11000101  VDU 0   - &C511, no parameters
C355  DB  2F  ;00101111  VDU 1   - &C53B, 1 parameter
C356  DB  C5  ;11000101  VDU 2   - &C596, no parameters
C357  DB  C5  ;11000101  VDU 3   - &C5A1, no parameters
C358  DB  C5  ;11000101  VDU 4   - &C5AD, no parameters
C359  DB  C5  ;11000101  VDU 5   - &C5B9, no parameters
C35A  DB  C5  ;11000101  VDU 6   - &C511, no parameters
C35B  DB  E8  ;11101000  VDU 7   - &E86F, no parameters
C35C  DB  C5  ;11000101  VDU 8   - &C5C5, no parameters
C35D  DB  C6  ;11000110  VDU 9   - &C664, no parameters
C35E  DB  C6  ;11000110  VDU 10  - &C6F0, no parameters
C35F  DB  C6  ;11000110  VDU 11  - &C65B, no parameters
C360  DB  C7  ;11000111  VDU 12  - &C759, no parameters
C361  DB  C7  ;11000111  VDU 13  - &C7AF, no parameters
C362  DB  C5  ;11000101  VDU 14  - &C58D, no parameters
C363  DB  C5  ;11000101  VDU 15  - &C5A6, no parameters
C364  DB  C7  ;11000111  VDU 16  - &C7C0, no parameters
C365  DB  4F  ;01001111  VDU 17  - &C7F9, 1 parameter
C366  DB  4E  ;01001110  VDU 18  - &C7FD, 2 parameters
C367  DB  5B  ;01011011  VDU 19  - &C892, 5 parameters
C368  DB  C8  ;11001000  VDU 20  - &C839, no parameters
C369  DB  C5  ;11000101  VDU 21  - &C59B, no parameters
C36A  DB  5F  ;01011111  VDU 22  - &C8EB, 1 parameter
C36B  DB  57  ;01010111  VDU 23  - &C8F1, 9 parameters
C36C  DB  78  ;01111000  VDU 24  - &CA39, 8 parameters
C36D  DB  6B  ;01101011  VDU 25  - &C9AC, 5 parameters
C36E  DB  C9  ;11001001  VDU 26  - &C9BD, no parameters
C36F  DB  C5  ;11000101  VDU 27  - &C511, no parameters
C370  DB  3C  ;00111100  VDU 28  - &C6FA, 4 parameters
C371  DB  7C  ;01111100  VDU 29  - &CAA2, 4 parameters
C372  DB  C7  ;11000111  VDU 30  - &C779, no parameters
C373  DB  4E  ;01001110  VDU 31  - &C787, 2 parameters
C374  DB  CA  ;11001010  VDU 127 - &CAAC, no parameters


****** 640 MULTIPLICATION TABLE  40COL, 80COL MODES  HIBYTE, LOBYTE ******

C375  DW  0000  ;  0*640 = &0000
C377  DW  8002  ;  1*640 = &0280
C379  DW  0005  ;  2*640 = &0500
C37B  DW  8007  ;  3*640 = &0780
C37D  DW  000A  ;  4*
C37F  DW  800C  ;  5*
C381  DW  000F  ;  6*
C383  DW  8011  ;  7*
C385  DW  0014  ;  8*
C387  DW  8016  ;  9*
C389  DW  0019  ; 10*
C38B  DW  801B  ; 11*
C38D  DW  001E  ; 12*
C38F  DW  8020  ; 13*
C391  DW  0023  ; 14*
C393  DW  8025  ; 15*
C395  DW  0028  ; 16*
C397  DW  802A  ; 17*
C399  DW  002D  ; 18*
C39B  DW  802F  ; 19*
C39D  DW  0032  ; 20*
C39F  DW  8034  ; 21*
C3A1  DW  0037  ; 22*
C3A3  DW  8039  ; 23*
C3A5  DW  003C  ; 24*
C3A7  DW  803E  ; 25*
C3A9  DW  0041  ; 26*
C3AB  DW  8043  ; 27*
C3AD  DW  0046  ; 28*
C3AF  DW  8048  ; 29*
C3B1  DW  004B  ; 30*
C3B3  DW  804D  ; 31*640 = &4D80


****** *40 MULTIPLICATION TABLE  TELETEXT  MODE   HIBYTE, LOBYTE  ******

C3B5  DW  0000  ;  0*40 = &0000
C3B7  DW  2800  ;  1*40 = &0028
C3B9  DW  5000  ;  2
C3BB  DW  7800  ;  3
C3BD  DW  A000  ;  4
C3BF  DW  C800  ;  5
C3C1  DW  F000  ;  6
C3C3  DW  1801  ;  7
C3C5  DW  4001  ;  8
C3C7  DW  6801  ;  9
C3C9  DW  9001  ; 10
C3CB  DW  B801  ; 11
C3CD  DW  E001  ; 12
C3CF  DW  0802  ; 13
C3D1  DW  3002  ; 14
C3D3  DW  5802  ; 15
C3D5  DW  8002  ; 16
C3D7  DW  A802  ; 17
C3D9  DW  D002  ; 18
C3DB  DW  F802  ; 19
C3DD  DW  2003  ; 20
C3DF  DW  4803  ; 21
C3E1  DW  7003  ; 22
C3E3  DW  9803  ; 23*40 = &0398
C3E5  DW  C003  ; 24*40 = &03C0


****** TEXT WINDOW -BOTTOM ROW LOOK UP TABLE ******

C3E7  DB  1F  ; MODE 0 - 32 ROWS
C3E8  DB  1F  ; MODE 1 - 32 ROWS
C3E9  DB  1F  ; MODE 2 - 32 ROWS
C3EA  DB  18  ; MODE 3 - 25 ROWS
C3EB  DB  1F  ; MODE 4 - 32 ROWS
C3EC  DB  1F  ; MODE 5 - 32 ROWS
C3ED  DB  18  ; MODE 6 - 25 ROWS
C3EE  DB  18  ; MODE 7 - 25 ROWS





****** TEXT WINDOW -RIGHT HAND COLUMN LOOK UP TABLE ******

C3EF  DB  4F  ; MODE 0 - 80 COLUMNS
C3F0  DB  27  ; MODE 1 - 40 COLUMNS
C3F1  DB  13  ; MODE 2 - 20 COLUMNS
C3F2  DB  4F  ; MODE 3 - 80 COLUMNS
C3F3  DB  27  ; MODE 4 - 40 COLUMNS
C3F4  DB  13  ; MODE 5 - 20 COLUMNS
C3F5  DB  27  ; MODE 6 - 40 COLUMNS
C3F6  DB  27  ; MODE 7 - 40 COLUMNS


*************************************************************************
*                                                                       *
*       SEVERAL OF THE FOLLOWING TABLES OVERLAP EACH OTHER              *
*       SOME ARE DUAL PURPOSE                                           *
*                                                                       *
*************************************************************************

************** VIDEO ULA CONTROL REGISTER SETTINGS ***********************

C3F7  DB  9C  ;10011100
C3F8  DB  D8  ;11011000
C3F9  DB  F4  ;11110100
C3FA  DB  9C  ;10011100
C3FB  DB  88  ;10001000
C3FC  DB  C4  ;11000100
C3FD  DB  88  ;10001000
C3FE  DB  4B  ;01001011


******** NUMBER OF BYTES PER CHARACTER FOR EACH DISPLAY MODE ************

C3FF  DB  08  ;00001000
C400  DB  10  ;00010000
C401  DB  20  ;00100000
C402  DB  08  ;00001000
C403  DB  08  ;00001000
C404  DB  10  ;00010000
C405  DB  08  ;00001000
C406  DB  01  ;00000001


******************* MASK TABLE FOR  2 COLOUR MODES **********************

C407  DB  AA  ;10101010
C408  DB  55  ;01010101


****************** MASK TABLE FOR  4 COLOUR MODES ***********************

C409  DB  88  ;10001000
C40A  DB  44  ;01000100
C40B  DB  22  ;00100010
C40C  DB  11  ;00010001


********** MASK TABLE FOR  4 COLOUR MODES FONT FLAG MASK TABLE **********

C40D  DB  80  ;10000000
C40E  DB  40  ;01000000
C40F  DB  20  ;00100000
C410  DB  10  ;00010000
C411  DB  08  ;00001000
C412  DB  04  ;00000100
C413  DB  02  ;00000010  -  NEXT BYTE IN FOLLOWING TABLE


********* NUMBER OF TEXT COLOURS -1 FOR EACH MODE ************************

C414  DB  01  ; MODE 0 - 2 COLOURS
C415  DB  03  ; MODE 1 - 4 COLOURS
C416  DB  0F  ; MODE 2 - 16 COLOURS
C417  DB  01  ; MODE 3 - 2 COLOURS
C418  DB  01  ; MODE 4 - 2 COLOURS
C419  DB  03  ; MODE 5 - 4 COLOURS
C41A  DB  01  ; MODE 6 - 2 COLOURS
C41B  DB  00  ; MODE 7 - 1 'COLOUR'


************** GCOL PLOT OPTIONS PROCESSING LOOK UP TABLE ***************

C41C  DB  FF  ;11111111
C41D  DB  00  ;00000000
C41E  DB  00  ;00000000
C41F  DB  FF  ;11111111
C420  DB  FF  ;11111111
C421  DB  FF  ;11111111
C422  DB  FF  ;11111111
C423  DB  00  ;00000000

********** 2 COLOUR MODES PARAMETER LOOK UP TABLE WITHIN TABLE **********

C424  DB  00  ;00000000
C425  DB  FF  ;11111111


*************** 4 COLOUR MODES PARAMETER LOOK UP TABLE ******************

C426  DB  00  ;00000000
C427  DB  0F  ;00001111
C428  DB  F0  ;11110000
C429  DB  FF  ;11111111


***************16 COLOUR MODES PARAMETER LOOK UP TABLE ******************

C42A  DB  00  ;00000000
C42B  DB  03  ;00000011
C42C  DB  0C  ;00001100
C42D  DB  0F  ;00001111
C42E  DB  30  ;00110000
C42F  DB  33  ;00110011
C430  DB  3C  ;00111100
C431  DB  3F  ;00111111
C432  DB  C0  ;11000000
C433  DB  C3  ;11000011
C434  DB  CC  ;11001100
C435  DB  CF  ;11001111
C436  DB  F0  ;11110000
C437  DB  F3  ;11110011
C438  DB  FC  ;11111100
C439  DB  FF  ;11111111









********** DISPLAY MODE PIXELS/BYTE-1 LOOK UP TABLE *********************

C43A  DB  07  ; MODE 0 - 8 PIXELS/BYTE
C43B  DB  03  ; MODE 1 - 4 PIXELS/BYTE
C43C  DB  01  ; MODE 2 - 2 PIXELS/BYTE
C43D  DB  00  ; MODE 3 - 1 PIXEL/BYTE (NON-GRAPHICS)
C43E  DB  07  ; MODE 4 - 8 PIXELS/BYTE
C43F  DB  03  ; MODE 5 - 4 PIXELS/BYTE

********* SCREEN DISPLAY MEMORY INDEX LOOK UP TABLE OVERLAPS ************

C440  DB  00  ; MODE 6 - 1 PIXEL/BYTE  //  MODE 0 - TYPE 0

***** SOUND PITCH OFFSET BY CHANNEL LOOK UP TABLE WITHIN TABLE **********

C441  DB  00  ; MODE 7 - 1 PIXEL/BYTE  //  MODE 1 - TYPE 0  //  CHANNEL 0 
C442  DB  00  ; MODE 2 - TYPE 0  //  CHANNEL 1
C443  DB  01  ; MODE 3 - TYPE 1  //  CHANNEL 2
C444  DB  02  ; MODE 4 - TYPE 2  //  CHANNEL 3

**** REST OF DISPLAY TABLE ****

C445  DB  02  ; MODE 5 - TYPE 2
C446  DB  03  ; MODE 6 - TYPE 3
C447  DB  04  ; MODE 7 - TYPE 4

***************** VDU SECTION CONTROL NUMBERS ***************************

C447  DB  04  ; MODE 7 - TYPE 4
C448  DB  00  ;00000000
C449  DB  06  ;00000110
C44A  DB  02  ;00000010

*********** CRTC SET UP PARAMETERS TABLE 1 WITHIN TABLE ******************

C44B  DB  0D  ;00001101
C44C  DB  05  ;00000101
C44D  DB  0D  ;00001101
C44E  DB  05  ;00000101

*********** CRTC SET UP PARAMETERS TABLE 2  WITHIN TABLE *****************

C44F  DB  04  ;00000100
C450  DB  04  ;00000100
C451  DB  0C  ;00001100
C452  DB  0C  ;00001100
C453  DB  04  ;00000100

**** REST OF VDU SECTION CONTROL NUMBERS ****

C454  DB  02  ;00000010
C455  DB  32  ;00110010
C456  DB  7A  ;01111010
C457  DB  92  ;10010010
C458  DB  E6  ;11100110


************** MSB OF MEMORY OCCUPIED BY SCREEN BUFFER  *****************

C459  DB  50  ;  Type 0: &5000 - 20k
C45A  DB  40  ;  Type 1: &4000 - 16k
C45B  DB  28  ;  Type 2: &2800 - 10k
C45C  DB  20  ;  Type 3: &2000 - 8k
C45D  DB  04  ;  Type 4: &0400 - 1k


************ MSB OF FIRST LOCATION OCCUPIED BY SCREEN BUFFER ************

C45E  DB  30  ;  Type 0: &3000
C45F  DB  40  ;  Type 1: &4000
C460  DB  58  ;  Type 2: &5800
C461  DB  60  ;  Type 3: &6000
C462  DB  7C  ;  Type 4: &7C00


***************** NUMBER OF BYTES PER ROW *******************************

C463  DB  28  ;00101000
C464  DB  40  ;01000000
C465  DB  80  ;10000000


******** ROW MULTIPLIACTION TABLE POINTER TO LOOK UP TABLE **************

C466  DB  B5  ;10110101
C467  DB  75  ;01110101
C468  DB  75  ;01110101


********** CRTC CURSOR END REGISTER SETTING LOOK UP TABLE ***************

C469  DB  0B  ;00001011
C46A  DB  17  ;00010111
C46B  DB  23  ;00100011
C46C  DB  2F  ;00101111
C46D  DB  3B  ;00111011


************* 6845 REGISTERS 0-11 FOR MODES 0-2 *************************

C46E  DB  7F  ;01111111
C46F  DB  50  ;01010000
C470  DB  62  ;01100010
C471  DB  28  ;00101000
C472  DB  26  ;00100110
C473  DB  00  ;00000000
C474  DB  20  ;00100000
C475  DB  22  ;00100010
C476  DB  01  ;00000001
C477  DB  07  ;00000111
C478  DB  67  ;01100111
C479  DB  08  ;00001000


************* 6845 REGISTERS 0-11 FOR MODE 3 ****************************

C47A  DB  7F  ;01111111
C47B  DB  50  ;01010000
C47C  DB  62  ;01100010
C47D  DB  28  ;00101000
C47E  DB  1E  ;00011110
C47F  DB  02  ;00000010
C480  DB  19  ;00011001
C481  DB  1B  ;00011011
C482  DB  01  ;00000001
C483  DB  09  ;00001001
C484  DB  67  ;01100111
C485  DB  09  ;00001001




************ 6845 REGISTERS 0-11 FOR MODES 4-5 **************************

C486  DB  3F  ;00111111
C487  DB  28  ;00101000
C488  DB  31  ;00110001
C489  DB  24  ;00100100
C48A  DB  26  ;00100110
C48B  DB  00  ;00000000
C48C  DB  20  ;00100000
C48D  DB  22  ;00100010
C48E  DB  01  ;00000001
C48F  DB  07  ;00000111
C490  DB  67  ;01100111
C491  DB  08  ;00001000


********** 6845 REGISTERS 0-11 FOR MODE 6 *******************************

C492  DB  3F  ;00111111
C493  DB  28  ;00101000
C494  DB  31  ;00110001
C495  DB  24  ;00100100
C496  DB  1E  ;00011110
C497  DB  02  ;00000010
C498  DB  19  ;00011001
C499  DB  1B  ;00011011
C49A  DB  01  ;00000001
C49B  DB  09  ;00001001
C49C  DB  67  ;01100111
C49D  DB  09  ;00001001


********* 6845 REGISTERS 0-11 FOR MODE 7    *****************************

C49E  DB  3F  ;00111111
C49F  DB  28  ;00101000
C4A0  DB  33  ;00110011
C4A1  DB  24  ;00100100
C4A2  DB  1E  ;00011110
C4A3  DB  02  ;00000010
C4A4  DB  19  ;00011001
C4A5  DB  1B  ;00011011
C4A6  DB  93  ;10010011
C4A7  DB  12  ;00010010
C4A8  DB  72  ;01110010
C4A9  DB  13  ;00010011


************* VDU ROUTINE VECTOR ADDRESSES   ******************************

C4AA  DB  86  ;10000110
C4AB  DB  D3  ;11010011
C4AC  DB  7E  ;01111110
C4AD  DB  D3  ;11010011


************ VDU ROUTINE BRANCH VECTOR ADDRESS LO ***********************

C4AE  DB  6A  ;01101010
C4AF  DB  74  ;01110100
C4B0  DB  42  ;01000010
C4B1  DB  4B  ;01001011




************ VDU ROUTINE BRANCH VECTOR ADDRESS HI ***********************

C4B2  DB  D3  ;11010011
C4B3  DB  D3  ;11010011
C4B4  DB  D3  ;11010011
C4B5  DB  D3  ;11010011


*********** TELETEXT CHARACTER CONVERSION TABLE  ************************

C4B6  DB  23  ; '#' -> '_'
C4B7  DB  5F  ; '_' -> '`'
C4B8  DB  60  ; '`' -> '#'
C4B9  DB  23  ; '#'


*********** SOFT CHARACTER RAM ALLOCATION   *****************************

C4BA  DB  04  ; &20-&3F - OSHWM+&0400
C4BB  DB  05  ; &40-&5F - OSHWM+&0500
C4BC  DB  06  ; &60-&7F - OSHWM+&0600
C4BD  DB  00  ; &80-&9F - OSHWM+&0000
C4BE  DB  01  ; &A0-&BF - OSHWM+&0100
C4BF  DB  02  ; &C0-&DF - OSHWM+&0200

*************************************************************************
*                                                                       *
*       VDU FUNCTIONS ADDRESSES                                         *
*                                                                       *
*************************************************************************

    	; VDU   Address      Parameters         function

    	;  0    &C511           0       does nothing
    	;  1    &C53B           1       next character to printer only
    	;  2    &C596           0       enable printer
    	;  3    &C5A1           0       disable printer
    	;  4    &C5AD           0       select text cursor
    	;  5    &C5B9           0       select graphics cursor
    	;  6    &C511           0       enable display
    	;  7    &E86F           0       bell
    	;  8    &C5C5           0       cursor left
    	;  9    &C664           0       cursor right
    	; 10    &C6F0           0       cursor down
    	; 11    &C65B           0       cursor up
    	; 12    &C759           0       clear text window
    	; 13    &C7AF           0       newline
    	; 14    &C58D           0       select paged mode
    	; 15    &C5A6           0       cancel paged mode
    	; 16    &C7C0           0       clear graphics screen
    	; 17    &C7F9           1       define text colour
    	; 18    &C7FD           2       define graphics colour
    	; 19    &C892           5       define logical colour
    	; 20    &C839           0       restore default colours
    	; 21    &C59B           0       disable display
    	; 22    &C8EB           1       select screen MODE
    	; 23    &C8F1           9       define character
    	; 24    &CA39           8       define graphics window
    	; 25    &C98C           5       PLOT
    	; 26    &C9BD           0       set default windows
    	; 27    &C511           0       ESCAPE (does nothing)
    	; 28    &C6FA           4       define text window
    	; 29    &CAA2           4       define graphics origin
    	; 30    &C779           0       home cursor
    	; 31    &C787           2       position text cursor (TAB)
    	;127    &CAAC           0       delete
    	
*************************************************************************
*                                                                       *
*      VDU Variables                                                    *
*                                                                       *
*************************************************************************

    	;D0 VDU status
    	;Bit    0       printer output enabled
    	;   1       scrolling disabled
    	;   2       paged scrolling enabled
    	;   3       software scrolling selected
    	;   4       not used
    	;   5       printing at graphics cursor enabled
    	;   6       cursor editing mode enabled
    	;   7       screen disabled

    	;D1 byte mask for current graphics point
    	;D2/3   text colour bytes to be ORed and EORed into memory
    	;D4/5   graphics colour bytes to be ORed and EORed into memory
    	;D6/7   address of top line of current graphics cell
    	;D8/9   address of top scan line of current text character
    	;DA/F   temporary workspace
    	;E0/1   CRTC row multiplication table pointer


    	;246    Character definition explosion switch

    	;248    current video ULA control regiter setting
    	;249    current pallette setting

    	;251    flash counter
    	;252    mark-space count
    	;253    space period count

    	;256    EXEC file handle
    	;257    SPOOL file handle

    	;260    Econet OSWRCH interception flag
    	;267    bit 7 set ignore start up message
    	;268    length of key string
    	;269    print line counter
    	;26A    number of items in VDU queque
    	;26B    TAB key value
    	;26C    ESCAPE character

    	;27D    cursor editing status

    	;28F    start up options (Keyboard links)
    	    bits    0-2     default screen Mode
    	              3     reverse SHIFT/BREAK
    	            4-5     disc timing parameters
    	;290    screen display vertical adjustment
    	;291    interlace toggle flag
    	
    	;300/1  graphics window left
    	;302/3  graphics window bottom
    	;304/5  graphics window right
    	;306/7  graphics window top
    	;308    text window left
    	;309    text window bottom
    	;30A    text window right
    	;30B    text window top
    	;30C/D  graphics origin, horizontal (external values)
    	;30E/F  graphics origin, vertical   (external values)

    	;310/1  current graphics cursor, horizontal (external values)
    	;312/3  current graphics cursor, vertical   (external values)
    	;314/5  last graphics cursor, horizontal    (external values)
    	;316/7  last graphics cursor, vertical      (external values)
    	;318    text column
    	;319    text line
    	;31A    graphics scan line expressed as line of character
    	;31B-323 VDU parameters, last parameter in &323
    	;324/5  current graphics cursor, horizontal (internal values)
    	;316/7  current graphics cursor, vertical   (internal values)
    	;328-349 general workspace
    	;34A/B  text cursor address to CRT controller
    	;34C/D  width of text window in bytes
    	;34E    hi byte of address of screen RAM start
    	;34F    bytes per character
    	;350/1  address of window area start
    	;352/3  bytes per character row
    	;354    high byte of screen RAM size
    	;355    Mode
    	;356    memory map type
    	;357/35A current colours
    	;35B/C  graphics plot mode
    	;35D/E  jump vector
    	;35F    last setting of CRT controller Cursor start register
    	;360    number of logical colours less 1
    	;361    pixels per byte (0  in text only modes)
    	;362/3  colour masks
    	;364/5  X/Y for text input cursor
    	;366    output cursor character for MODE 7
    	;367    Font flag
    	;368/E  font location bytes
    	;36F-37E Colour palette
\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C4C0 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C4C0
new file mode 100644
index 0000000..308e246
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C4C0
@@ -0,0 +1 @@
+BBC Operation System OS 1.20		VDU Main Routines

**************************************************************************
**************************************************************************
**                                                                      **
**      OSWRCH  MAIN ROUTINE  entry from E0C5                           **
**                                                                      **
**      output a byte via the VDU stream                                **
**                                                                      **
**************************************************************************
**************************************************************************
;This routine takes up over 40% of the operating system ROM
;entry points are variable, as are the results achieved.
;tracing any particular path is relatively easy but generalising for
;commenting is not.  For clarity comments will not be as detailed as
;for later parts of the Operating system.

C4C0	LDX &026A   ;get number of items in VDU queue
C4C3	BNE &C512   ;if parameters needed then C512
C4C5	BIT &D0     ;else check status byte
C4C7	BVC &C4D8   ;if cursor editing enabled two cursors exist
C4C9	JSR &C568   ;swap values
C4CC	JSR &CD6A   ;then set up write cursor
C4CF	BMI &C4D8   ;if display disabled C4D8
C4D1	CMP #&0D    ;else if character in A=RETURN teminate edit
C4D3	BNE &C4D8   ;else C4D8

C4D5	JSR &D918   ;terminate edit

C4D8	CMP #&7F    ;is character DELETE ?
C4DA	BEQ &C4ED   ;if so C4ED

C4DC	CMP #&20    ;is it less than space? (i.e. VDU control code)
C4DE	BCC &C4EF   ;if so C4EF
C4E0	BIT &D0     ;else check VDU byte ahain
C4E2	BMI &C4EA   ;if screen disabled C4EA
C4E4	JSR &CFB7   ;else display a character
C4E7	JSR &C664   ;and cursor right
C4EA	JMP &C55E   ;

********* read link addresses and number of parameters *****************

C4ED	LDA #&20    ;to replace delete character

********* read link addresses and number of parameters *****************

C4EF	TAY         ;Y=A
C4F0	LDA &C333,Y ;get lo byte of link address
C4F3	STA &035D   ;store it in jump vector
C4F6	LDA &C354,Y ;get hi byte
C4F9	BMI &C545   ;if negative (as it will be if a direct address)
    	            ;there are no parameters needed
    	            ;so C545
C4FB	TAX         ;else X=A
C4FC	ORA #&F0    ;set up negated parameter count
C4FE	STA &026A   ;store it as number of items in VDU queue
C501	TXA         ;get back A
C502	LSR         ;A=A/16
C503	LSR         ;
C504	LSR         ;
C505	LSR         ;
C506	CLC         ;clear carry
C507	ADC #&C3    ;add &C3 to get hi byte of link address
C509	STA &035E   ;
C50C	BIT &D0     ;check if cursor editing enabled
C50E	BVS &C52F   ;if so re-exchange pointers
C510	CLC         ;clear carry
C511	RTS         ;and exit

;return with carry clear indicates that printer action not required.
;
********** parameters are outstanding ***********************************
X=&26A = 2 complement of number of parameters X=&FF for 1, FE for 2 etc.

C512	STA &0224,X ;store parameter in queue
C515	INX         ;increment X
C516	STX &026A   ;store it as VDU queue
C519	BNE &C532   ;if not 0 C532 as more parameters are needed
C51B	BIT &D0     ;get VDU status byte
C51D	BMI &C534   ;if screen disabled C534
C51F	BVS &C526   ;else if cursor editing C526
C521	JSR &CCF5   ;execute required function
C524	CLC         ;clear carry
C525	RTS         ;and exit
;
C526	JSR &C568   ;swap values of cursors
C529	JSR &CD6A   ;set up write cursor
C52C	JSR &CCF5   ;execute required function
C52F	JSR &C565   ;re-exchange pointers

C532	CLC         ;carry clear
C533	RTS         ;exit

*************************************************************************
*                                                                       *
*       VDU 1 - SEND NEXT CHARACTER TO PRINTER                          *
*                                                                       *
*       1 parameter required                                            *
*                                                                       *
*************************************************************************
;
C534	LDY &035E   ;if upper byte of link address not &C5
C537	CPY #&C5    ;printer is not interested
C539	BNE &C532   ;so C532
C53B	TAX         ;else X=A
C53C	LDA &D0     ;A=VDU status byte
C53E	LSR         ;get bit 0 into carry
C53F	BCC &C511   ;if printer not enabled exit
C541	TXA         ;restore A
C542	JMP &E11E   ;else send byte in A (next byte) to printer

*********** if explicit link address found, no parameters ***************

C545	STA &035E   ;upper byte of link address
C548	TYA         ;restore A
C549	CMP #&08    ;is it 7 or less?
C54B	BCC &C553   ;if so C553
C54D	EOR #&FF    ;invert it
C54F	CMP #&F2    ;c is set if A >&0D
C551	EOR #&FF    ;re invert

C553	BIT &D0     ;VDU status byte
C555	BMI &C580   ;if display disabled C580
C557	PHP         ;push processor flags
C558	JSR &CCF5   ;execute required function
C55B	PLP         ;get back flags
C55C	BCC &C561   ;if carry clear (from C54B/F)

**************** main exit routine **************************************

C55E	LDA &D0     ;VDU status byte
C560	LSR         ;Carry is set if printer is enabled
C561	BIT &D0     ;VDU status byte
C563	BVC &C511   ;if no cursor editing  C511 to exit

***************** cursor editing routines *******************************

C565	JSR &CD7A   ;restore normal write cursor

C568	PHP         ;save flags and
C569	PHA         ;A
C56A	LDX #&18    ;X=&18
C56C	LDY #&64    ;Y=&64
C56E	JSR &CDDE   ;exchange &300/1+X with &300/1+Y
C571	JSR &CF06   ;set up display address
C574	JSR &CA02   ;set cursor position
C577	LDA &D0     ;VDU status byte
C579	EOR #&02    ;invert bit 1 to allow or bar scrolling
C57B	STA &D0     ;VDU status byte
C57D	PLA         ;restore flags and A
C57E	PLP         ;
C57F	RTS         ;and exit
;
C580	EOR #&06    ;if A<>6
C582	BNE &C58C   ;return via C58C
C584	LDA #&7F    ;A=&7F
C586	BCC &C5A8   ;and goto C5A8 ALWAYS!!

******************* check text cursor in use ***************************

C588	LDA &D0     ;VDU status byte
C58A	AND #&20    ;set A from bit 5 of status byte
C58C	RTS         ;and exit

A=0 if text cursor, &20 if graphics

*************************************************************************
*                                                                       *
*       VDU 14 - SET PAGED MODE                                         *
*                                                                       *
*************************************************************************
;
C58D	LDY #&00    ;Y=0
C58F	STY &0269   ;paged mode counter
C592	LDA #&04    ;A=04
C594	BNE &C59D   ;jump to C59D

*************************************************************************
*                                                                       *
*       VDU 2  - PRINTER ON (START PRINT JOB)                           *
*                                                                       *
*************************************************************************

C596	JSR &E1A2   ;select printer buffer and output character
C599	LDA #&94    ;A=&94
    	            ;when inverted at C59B this becomes =&01

*************************************************************************
*                                                                       *
*       VDU 21 - DISABLE DISPLAY                                        *
*                                                                       *
*************************************************************************

C59B	EOR #&95    ;if A=&15 A now =&80: if A=&94 A now =1

C59D	ORA &D0     ;VDU status byte set bit 0 or bit 7
C59F	BNE &C5AA   ;branch forward to store



*************************************************************************
*                                                                       *
*       VDU 3  - PRINTER OFF (END PRINT JOB)                            *
*                                                                       *
*************************************************************************

C5A1	JSR &E1A2   ;select printer buffer and output character
C5A4	LDA #&0A    ;A=10 to clear status bits below...

*************************************************************************
*                                                                       *
*       VDU 15 - PAGED MODE OFF                                         *
*                                                                       *
*************************************************************************
; A=&F or &A

C5A6	EOR #&F4    ;convert to &FB or &FE
C5A8	AND &D0     ;VDU status byte clear bit 0 or bit 2 of status
C5AA	STA &D0     ;VDU status byte
C5AC	RTS         ;exit

*************************************************************************
*                                                                       *
*       VDU 4  - OUTPUT AT TEXT CURSOR                                  *
*                                                                       *
*************************************************************************
;
C5AD	LDA &0361   ;pixels per byte
C5B0	BEQ &C5AC   ;if no graphics in current mode C5AC
C5B2	JSR &C951   ;set CRT controller for text cursor
C5B5	LDA #&DF    ;this to clear bit 5 of status byte
C5B7	BNE &C5A8   ;via C5A8 exit

*************************************************************************
*                                                                       *
*       VDU 5  - OUTPUT AT GRAPHICS CURSOR                              *
*                                                                       *
*************************************************************************

C5B9	LDA &0361   ;pixels per byte
C5BC	BEQ &C5AC   ;if none this is text mode so exit
C5BE	LDA #&20    ;set up graphics cursor
C5C0	JSR &C954   ;via C954
C5C3	BNE &C59D   ;set bit 5 via exit C59D

*************************************************************************
*                                                                       *
*       VDU 8  - CURSOR LEFT                                            *
*                                                                       *
*************************************************************************

C5C5	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C5C8	BNE &C61F   ;move cursor left 8 pixels if graphics
C5CA	DEC &0318   ;else decrement text column
C5CD	LDX &0318   ;store new text column
C5D0	CPX &0308   ;if it is less than text window left
C5D3	BMI &C5EE   ;do wraparound  cursor to rt of screen 1 line up
C5D5	LDA &034A   ;text cursor 6845 address
C5D8	SEC         ;subtract
C5D9	SBC &034F   ;bytes per character
C5DC	TAX         ;put in X
C5DD	LDA &034B   ;get text cursor 6845 address
C5E0	SBC #&00    ;subtract 0
C5E2	CMP &034E   ;compare with hi byte of screen RAM address
C5E5	BCS &C5EA   ;if = or greater
C5E7	ADC &0354   ;add screen RAM size hi byte to wrap around
C5EA	TAY         ;Y=A
C5EB	JMP &C9F6   ;Y hi and X lo byte of cursor position

***************** execute wraparound left-up*****************************

C5EE	LDA &030A   ;text window right
C5F1	STA &0318   ;text column

*************** cursor up ***********************************************

C5F4	DEC &0269   ;paged mode counter
C5F7	BPL &C5FC   ;if still greater than 0 skip next instruction
C5F9	INC &0269   ;paged mode counter to restore X=0
C5FC	LDX &0319   ;current text line
C5FF	CPX &030B   ;top of text window
C602	BEQ &C60A   ;if its at top of window C60A
C604	DEC &0319   ;else decrement current text line
C607	JMP &C6AF   ;and carry on moving cursor

******** cursor at top of window ****************************************

C60A	CLC         ;clear carry
C60B	JSR &CD3F   ;check for window violatations
C60E	LDA #&08    ;A=8 to check for software scrolling
C610	BIT &D0     ;compare against VDU status byte
C612	BNE &C619   ;if not enabled C619
C614	JSR &C994   ;set screen start register and adjust RAM
C617	BNE &C61C   ;jump C61C

C619	JSR &CDA4   ;soft scroll 1 line
C61C	JMP &C6AC   ;and exit

**********cursor left and down with graphics cursor in use **************

C61F	LDX #&00    ;X=0 to select horizontal parameters

********** cursor down with graphics in use *****************************
;X=2 for vertical or 0 for horizontal

C621	STX &DB     ;store X
C623	JSR &D10D   ;check for window violations
C626	LDX &DB     ;restore X
C628	SEC         ;set carry
C629	LDA &0324,X ;current graphics cursor X>1=vertical
C62C	SBC #&08    ;subtract 8 to move back 1 character
C62E	STA &0324,X ;store in current graphics cursor X>1=verticaal
C631	BCS &C636   ;if carry set skip next
C633	DEC &0325,X ;current graphics cursor hi -1
C636	LDA &DA     ;&DA=0 if no violation else 1 if vert violation
    	            ;2 if horizontal violation
C638	BNE &C658   ;if violation C658
C63A	JSR &D10D   ;check for window violations
C63D	BEQ &C658   ;if none C658

C63F	LDX &DB     ;else get back X
C641	LDA &0304,X ;graphics window rt X=0 top X=2
C644	CPX #&01    ;is X=0
C646	BCS &C64A   ;if not C64A
C648	SBC #&06    ;else subtract 7

C64A	STA &0324,X ;current graphics cursor X>1=vertical
C64D	LDA &0305,X ;graphics window hi rt X=0 top X=2
C650	SBC #&00    ;subtract carry
C652	STA &0325,X ;current graphics cursor X<2=horizontal else vertical
C655	TXA         ;A=X
C656	BEQ &C660   ;cursor up
C658	JMP &D1B8   ;set up external coordinates for graphics

*************************************************************************
*                                                                       *
*       VDU 11 - CURSOR UP                                              *
*                                                                       *
*************************************************************************

C65B	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C65E	BEQ &C5F4   ;if text cursor then C5F4
C660	LDX #&02    ;else X=2
C662	BNE &C6B6   ;goto C6B6

*************************************************************************
*                                                                       *
*       VDU 9  - CURSOR RIGHT                                           *
*                                                                       *
*************************************************************************

C664	LDA &D0     ;VDU status byte
C666	AND #&20    ;check bit 5
C668	BNE &C6B4   ;if set then graphics cursor in use so C6B4
C66A	LDX &0318   ;text column
C66D	CPX &030A   ;text window right
C670	BCS &C684   ;if X exceeds window right then C684
C672	INC &0318   ;text column
C675	LDA &034A   ;text cursor 6845 address
C678	ADC &034F   ;add bytes per character
C67B	TAX         ;X=A
C67C	LDA &034B   ;text cursor 6845 address
C67F	ADC #&00    ;add carry if set
C681	JMP &C9F6   ;use X and Y to set new cursor address

********: text cursor down and right *************************************

C684	LDA &0308   ;text window left
C687	STA &0318   ;text column

********: text cursor down *************************************

C68A	CLC         ;clear carry
C68B	JSR &CAE3   ;check bottom margin, X=line count
C68E	LDX &0319   ;current text line
C691	CPX &0309   ;bottom margin
C694	BCS &C69B   ;if X=>current bottom margin C69B
C696	INC &0319   ;else increment current text line
C699	BCC &C6AF   ;
C69B	JSR &CD3F   ;check for window violations
C69E	LDA #&08    ;check bit 3
C6A0	BIT &D0     ;VDU status byte
C6A2	BNE &C6A9   ;if software scrolling enabled C6A9
C6A4	JSR &C9A4   ;perform hardware scroll
C6A7	BNE &C6AC   ;
C6A9	JSR &CDFF   ;execute upward scroll
C6AC	JSR &CEAC   ;clear a line

C6AF	JSR &CF06   ;set up display address
C6B2	BCC &C732   ;






*********** graphic cursor right ****************************************

C6B4	LDX #&00    ;

************** graphic cursor up  (X=2) **********************************

C6B6	STX &DB     ;store X
C6B8	JSR &D10D   ;check for window violations
C6BB	LDX &DB     ;get back X
C6BD	CLC         ;clear carry
C6BE	LDA &0324,X ;current graphics cursor X>1=vertical
C6C1	ADC #&08    ;Add 8 pixels
C6C3	STA &0324,X ;current graphics cursor X>1=vertical
C6C6	BCC &C6CB   ;
C6C8	INC &0325,X ;current graphics cursor X<2=horizontal else vertical
C6CB	LDA &DA     ;A=0 no window violations 1 or 2 indicates violation
C6CD	BNE &C658   ;if outside window C658
C6CF	JSR &D10D   ;check for window violations
C6D2	BEQ &C658   ;if no violations C658

C6D4	LDX &DB     ;get back X
C6D6	LDA &0300,X ;graphics window X<2 =left else bottom
C6D9	CPX #&01    ;If X=0
C6DB	BCC &C6DF   ;C6DF
C6DD	ADC #&06    ;else add 7
C6DF	STA &0324,X ;current graphics cursor X>1=vertical
C6E2	LDA &0301,X ;graphics window hi X<2 =left else bottom
C6E5	ADC #&00    ;add anny carry
C6E7	STA &0325,X ;current graphics cursor X<2=horizontal else vertical
C6EA	TXA         ;A=X
C6EB	BEQ &C6F5   ;if X=0 C6F5 cursor down
C6ED	JMP &D1B8   ;set up external coordinates for graphics

*************************************************************************
*                                                                       *
*       VDU 10  - CURSOR DOWN                                           *
*                                                                       *
*************************************************************************

C6F0	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C6F3	BEQ &C68A   ;if text cursor back to C68A
C6F5	LDX #&02    ;else X=2 to indicate vertical movement
C6F7	JMP &C621   ;move graphics cursor down

*************************************************************************
*                                                                       *
*       VDU 28 - DEFINE TEXT WINDOW                                     *
*                                                                       *
*       4 parameters                                                    *
*                                                                       *
*************************************************************************
;parameters are set up thus
;0320  P1 left margin
;0321  P2 bottom margin
;0322  P3 right margin
;0323  P4 top margin
;Note that last parameter is always in 0323

C6FA	LDX &0355   ;screen mode
C6FD	LDA &0321   ;get bottom margin
C700	CMP &0323   ;compare with top margin
C703	BCC &C758   ;if bottom margin exceeds top return
C705	CMP &C3E7,X ;text window bottom margin maximum
C708	BEQ &C70C   ;if equal then its OK
C70A	BCS &C758   ;else exit



C70C	LDA &0322   ;get right margin
C70F	TAY         ;put it in Y
C710	CMP C3EF,X  ;text window right hand margin maximum
C713	BEQ &C717   ;if equal then OK
C715	BCS &C758   ;if greater than maximum exit

C717	SEC         ;set carry to subtract
C718	SBC &0320   ;left margin
C71B	BMI &C758   ;if left greater than right exit
C71D	TAY         ;else A=Y (window width)
C71E	JSR &CA88   ;calculate number of bytes in a line
C721	LDA #&08    ;A=8 to set bit  of &D0
C723	JSR &C59D   ;indicating that text window is defined
C726	LDX #&20    ;point to parameters
C728	LDY #&08    ;point to text window margins
C72A	JSR &D48A   ;(&300/3+Y)=(&300/3+X)
C72D	JSR &CEE8   ;set up screen address
C730	BCS &C779   ;home cursor within window
C732	JMP &CA02   ;set cursor position

\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C735 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C735
new file mode 100644
index 0000000..badc60f
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/C735
@@ -0,0 +1 @@
+*************************************************************************
*                                                                       *
*       OSWORD 9  - READ A PIXEL                                        *
*       =POINT(X,Y)                                                     *
*                                                                       *
*************************************************************************
;on entry &EF=A=9
;   	   &F0=X=low byte of parameter block address
;   	   &F1=Y=high byte of parameter block address
;   	PARAMETER BLOCK
;       0,1=X coordinate
;       2,3=Y coordinate
;on exit, result in BLOCK+4
;     =&FF if point was of screen or logical colour of point if on screen
;
C735	LDY #&03    ;Y=3 to point to hi byte of Y coordinate
C737	LDA (&F0),Y ;get it
C739	STA &0328,Y ;store it
C73C	DEY         ;point to next byte
C73D	BPL &C737   ;transfer till Y=&FF lo byte of X coordinate in &328
C73F	LDA #&28    ;
C741	JSR &D839   ;check window boundaries
C744	LDY #&04    ;Y=4
C746	BNE &C750   ;jump to C750


*************************************************************************
*                                                                       *
*       OSWORD 11 - READ PALLETTE                                       *
*                                                                       *
*************************************************************************
;on entry &EF=A=11
;   	   &F0=X=low byte of parameter block address
;   	   &F1=Y=high byte of parameter block address
;   	PARAMETER BLOCK
;       0=logical colour to read
;on exit, result in BLOCK
;       0=logical colour
;       1=physical colour
;       2=red colour component  \
;       3=green colour component } when set using analogue colours
;       4=blue colour component /

C748	AND &0360   ;number of logical colours less 1
C74B	TAX         ;put it in X
C74C	LDA &036F,X ;colour pallette
C74F	INY         ;increment Y to point to byte 1

C750	STA (&F0),Y ;store data
C752	LDA #&00    ;issue 0s
C754	CPY #&04    ;to next bytes until Y=4
C756	BNE &C74F   ;

C758	RTS         ;and exit


*************************************************************************
*                                                                       *
*       VDU 12 - CLEAR TEXT SCREEN                                      *
*       CLS                                                             *
*                                                                       *
*************************************************************************
;
C759	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C75C	BNE &C7BD   ;if graphics cursor &C7BD
C75E	LDA &D0     ;VDU status byte
C760	AND #&08    ;check if software scrolling (text window set)
C762	BNE &C767   ;if so C767
C764	JMP &CBC1   ;initialise screen display and home cursor

C767	LDX &030B   ;top of text window
C76A	STX &0319   ;current text line
C76D	JSR &CEAC   ;clear a line

C770	LDX &0319   ;current text line
C773	CPX &0309   ;bottom margin
C776	INX         ;X=X+1
C777	BCC &C76A   ;if X at compare is less than bottom margin clear next


*************************************************************************
*                                                                       *
*       VDU 30 - HOME CURSOR                                            *
*                                                                       *
*************************************************************************

C779	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C77C	BEQ &C781   ;if text cursor C781
C77E	JMP &CFA6   ;home graphic cursor if graphic
C781	STA &0323   ;store 0 in last two parameters
C784	STA &0322   ;


*************************************************************************
*                                                                       *
*       VDU 31 - POSITION TEXT CURSOR                                   *
*       TAB(X,Y)                                                        *
*                                                                       *
*       2 parameters                                                    *
*                                                                       *
*************************************************************************
;0322 = supplied X coordinate
;0323 = supplied Y coordinate

C787	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C78A	BNE &C758   ;exit
C78C	JSR &C7A8   ;exchange text column/line with workspace 0328/9
C78F	CLC         ;clear carry
C790	LDA &0322   ;get X coordinate
C793	ADC &0308   ;add to text window left
C796	STA &0318   ;store as text column
C799	LDA &0323   ;get Y coordinate
C79C	CLC         ;
C79D	ADC &030B   ;add top of text window
C7A0	STA &0319   ;current text line
C7A3	JSR &CEE8   ;set up screen address
C7A6	BCC &C732   ;set cursor position if C=0 (point on screen)
C7A8	LDX #&18    ;else point to workspace
C7AA	LDY #&28    ;and line/column to restore old values
C7AC	JMP &CDDE   ;exchange &300/1+X with &300/1+Y


*************************************************************************
*                                                                       *
*       VDU 13 - CARRIAGE RETURN                                        *
*                                                                       *
*************************************************************************

C7AF	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
C7B2	BEQ &C7B7   ;if text C7B7
C7B4	JMP &CFAD   ;else set graphics cursor to left hand columm

C7B7	JSR &CE6E   ;set text column to left hand column
C7BA	JMP &C6AF   ;set up cursor and display address

C7BD	JSR &CFA6   ;home graphic cursor






*************************************************************************
*                                                                       *
*       VDU 16 - CLEAR GRAPHICS SCREEN                                  *
*       CLG                                                             *
*                                                                       *
*************************************************************************

C7C0	LDA &0361   ;pixels per byte
C7C3	BEQ &C7F8   ;if 0 current mode has no graphics so exit
C7C5	LDX &035A   ;Background graphics colour
C7C8	LDY &035C   ;background graphics plot mode (GCOL n)
C7CB	JSR &D0B3   ;set graphics byte mask in &D4/5
C7CE	LDX #&00    ;graphics window
C7D0	LDY #&28    ;workspace
C7D2	JSR &D47C   ;set(300/7+Y) from (300/7+X)
C7D5	SEC         ;set carry
C7D6	LDA &0306   ;graphics window top lo.
C7D9	SBC &0302   ;graphics window bottom lo
C7DC	TAY         ;Y=difference
C7DD	INY         ;increment
C7DE	STY &0330   ;and store in workspace (this is line count)
C7E1	LDX #&2C    ;
C7E3	LDY #&28    ;
C7E5	JSR &D6A6   ;clear line
C7E8	LDA &032E   ;decrement window height in pixels
C7EB	BNE &C7F0   ;
C7ED	DEC &032F   ;
C7F0	DEC &032E   ;
C7F3	DEC &0330   ;decrement line count
C7F6	BNE &C7E1   ;if <>0 then do it again
C7F8	RTS         ;exit


*************************************************************************
*                                                                       *
*       VDU 17 - DEFINE TEXT COLOUR                                     *
*       COLOUR n                                                        *
*                                                                       *
*       1 parameter                                                     *
*                                                                       *
*************************************************************************
;parameter in &0323

C7F9	LDY #&00    ;Y=0
C7FB	BEQ &C7FF   ;jump to C7FF


*************************************************************************
*                                                                       *
*       VDU 18 - DEFINE GRAPHICS COLOUR                                 *
*       GCOL k,c                                                        *
*                                                                       *
*       2 parameters                                                    *
*                                                                       *
*************************************************************************
;parameters in 323,322

C7FD	LDY #&02    ;Y=2

C7FF	LDA &0323   ;get last parameter
C802	BPL &C805   ;if +ve it's foreground colour so C805
C804	INY         ;else Y=Y+1
C805	AND &0360   ;number of logical colours less 1
C808	STA &DA     ;store it
C80A	LDA &0360   ;number of logical colours less 1
C80D	BEQ &C82B   ;if none exit
C80F	AND #&07    ;else limit to an available colour and clear M
C811	CLC         ;clear carry
C812	ADC &DA     ;Add last parameter to get pointer to table
C814	TAX         ;pointer into X

C815	LDA &C423,X ;get plot options from table
C818	STA &0357,Y ; colour Y=0=text fgnd 1= text bkgnd 2=graphics fg etc
C81B	CPY #&02    ;If Y>1
C81D	BCS &C82C   ;then its graphics so C82C else
C81F	LDA &0357   ;foreground text colour
C822	EOR #&FF    ;invert
C824	STA &D3     ;text colour byte to be orred or EORed into memory
C826	EOR &0358   ;background text colour
C829	STA &D2     ;text colour byte to be orred or EORed into memory
C82B	RTS         ;and exit
;
C82C	LDA &0322   ;get first parameter
C82F	STA &0359,Y ;text colour Y=0=foreground 1=background etc.
C832	RTS         ;exit
;
C833	LDA #&20    ;
C835	STA &0358   ;background text colour
C838	RTS         ;


*************************************************************************
*                                                                       *
*       VDU 20 - RESTORE DEFAULT COLOURS                                *
*                                                                       *
*************************************************************************
;
C839	LDX #&05    ;X=5

C83B	LDA #&00    ;A=0
C83D	STA &0357,X ;zero all colours
C840	DEX         ;
C841	BPL &C83D   ;until X=&FF
C843	LDX &0360   ;number of logical colours less 1
C846	BEQ &C833   ;if none its MODE 7 so C833
C848	LDA #&FF    ;A=&FF
C84A	CPX #&0F    ;if not mode 2 (16 colours)
C84C	BNE &C850   ;goto C850

C84E	LDA #&3F    ;else A=&3F
C850	STA &0357   ;foreground text colour
C853	STA &0359   ;foreground graphics colour
C856	EOR #&FF    ;invert A
C858	STA &D2     ;text colour byte to be orred or EORed into memory
C85A	STA &D3     ;text colour byte to be orred or EORed into memory
C85C	STX &031F   ;set first parameter of 5
C85F	CPX #&03    ;if there are 4 colours
C861	BEQ &C874   ;goto C874
C863	BCC &C885   ;if less there are 2 colours goto C885
    	            ;else there are 16 colours
C865	STX &0320   ;set second parameter
C868	JSR &C892   ;do VDU 19 etc
C86B	DEC &0320   ;decrement first parameter
C86E	DEC &031F   ;and last parameter
C871	BPL &C868   ;
C873	RTS         ;
;
********* 4 colour mode *************************************************

C874	LDX #&07    ;X=7
C876	STX &0320   ;set first parameter
C879	JSR &C892   ;and do VDU 19
C87C	LSR &0320   ;
C87F	DEC &031F   ;
C882	BPL &C879   ;
C884	RTS         ;exit

;********* 2 colour mode ************************************************

C885	LDX #&07    ;X=7
C887	JSR &C88F   ;execute VDU 19
C88A	LDX #&00    ;X=0
C88C	STX &031F   ;store it as
C88F	STX &0320   ;both parameters


*************************************************************************
*                                                                       *
*       VDU 19 - DEFINE COLOURS                                         *
*      [COLOUR l,p]                                                     *
*      [COLOUR l,r,g,b]                                                 *
*                                                                       *
*       5 parameters                                                    *
*                                                                       *
*************************************************************************
;&31F=first parameter logical colour
;&320=second physical colour

C892	PHP         ;push processor flags
C893	SEI         ;disable interrupts
C894	LDA &031F   ;get first parameter and
C897	AND &0360   ;number of logical colours less 1
C89A	TAX         ;toi make legal  X=A
C89B	LDA &0320   ;A=second parameter
C89E	AND #&0F    ;make legal
C8A0	STA &036F,X ;colour pallette
C8A3	TAY         ;Y=A
C8A4	LDA &0360   ;number of logical colours less 1
C8A7	STA &FA     ;store it
C8A9	CMP #&03    ;is it 4 colour mode??
C8AB	PHP         ;save flags
C8AC	TXA         ;A=X
C8AD	ROR         ;rotate A into &FA
C8AE	ROR &FA     ;
C8B0	BCS &C8AD   ;
C8B2	ASL &FA     ;
C8B4	TYA         ;A=Y
C8B5	ORA &FA     ;
C8B7	TAX         ;
C8B8	LDY #&00    ;Y=0
C8BA	PLP         ;check flags
C8BB	PHP         ;
C8BC	BNE &C8CC   ;if A<>3 earlier C8CC
C8BE	AND #&60    ;else A=&60 to test bits 5 and 6
C8C0	BEQ &C8CB   ;if not set C8CB
C8C2	CMP #&60    ;else if both set
C8C4	BEQ &C8CB   ;C8CB
C8C6	TXA         ;A=X
C8C7	EOR #&60    ;invert
C8C9	BNE &C8CC   ;and if not 0 C8CC

C8CB	TXA         ;X=A
C8CC	JSR &EA11   ;call Osbyte 155 pass data to pallette register
C8CF	TYA         ;
C8D0	SEC         ;
C8D1	ADC &0360   ;number of logical colours less 1
C8D4	TAY         ;
C8D5	TXA         ;
C8D6	ADC #&10    ;
C8D8	TAX         ;
C8D9	CPY #&10    ;if Y<16 do it again
C8DB	BCC &C8BA   ;
C8DD	PLP         ;pull flags twice
C8DE	PLP         ;
C8DF	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSWORD 12 - WRITE PALLETTE                                      *
*                                                                       *
*************************************************************************
;on entry X=&F0:Y=&F1:YX points to parameter block
;byte 0 = logical colour;  byte 1 physical colour; bytes 2-4=0

C8E0	PHP         ;push flags
C8E1	AND &0360   ;and with number of logical colours less 1
C8E4	TAX         ;X=A
C8E5	INY         ;Y=Y+1
C8E6	LDA (&F0),Y ;get phsical colour
C8E8	JMP &C89E   ;do VDU19 with parameters in X and A


*************************************************************************
*                                                                       *
*       VDU 22 - SELECT MODE                                            *
*       MODE n                                                          *
*                                                                       *
*       1 parameter                                                     *
*                                                                       *
*************************************************************************
;parameter in &323

C8EB	LDA &0323   ;get parameter
C8EE	JMP &CB33   ;goto CB33


*************************************************************************
*                                                                       *
*       VDU 23 - DEFINE CHARACTERS                                      *
*                                                                       *
*       9 parameters                                                    *
*                                                                       *
*************************************************************************
;parameters are:-
;31B character to define
;31C to 323 definition

C8F1	LDA &031B   ;get character to define
C8F4	CMP #&20    ;is it ' '
C8F6	BCC &C93F   ;if less then it is a control instruction, goto C93F
C8F8	PHA         ;else save parameter
C8F9	LSR         ;A=A/32
C8FA	LSR         ;
C8FB	LSR         ;
C8FC	LSR         ;
C8FD	LSR         ;
C8FE	TAX         ;X=A
C8FF	LDA &C40D,X ;get font flag mask from table (A=&80/2^X)
C902	BIT &0367   ;font flag
C905	BNE &C927   ;and if A<>0 C927 storage area is established already
C907	ORA &0367   ;or with font flag to set bit found to be 0
C90A	STA &0367   ;font flag
C90D	TXA         ;get back A
C90E	AND #&03    ;And 3 to clear all but bits 0 and 1
C910	CLC         ;clear carry
C911	ADC #&BF    ;add &BF (A=&C0,&C1,&C2) to select a character page
C913	STA &DF     ;store it
C915	LDA &0367,X ;get font location byte (normally &0C)
C918	STA &DD     ;store it
C91A	LDY #&00    ;Y=0 so (&DE) holds (&C000 -&C2FF)
C91C	STY &DC     ;
C91E	STY &DE     ;
C920	LDA (&DE),Y ;transfer page to storage area
C922	STA (&DC),Y ;
C924	DEY         ;
C925	BNE &C920   ;

C927	PLA         ;get back A
C928	JSR &D03E   ;set up character definition pointers

C92B	LDY #&07    ;Y=7
C92D	LDA &031C,Y ;transfer definition parameters
C930	STA (&DE),Y ;to RAM definition
C932	DEY         ;
C933	BPL &C92D   ;
C935	RTS         ;and exit
;
C936	PLA         ;Pull A
C937	RTS         ;and exit
;


************ VDU EXTENSION **********************************************

C938	LDA &031F   ;A=fifth VDU parameter
C93B	CLC         ;clear carry
C93C	JMP (&0226) ;jump via VDUV vector

********** VDU control commands *****************************************

C93F	CMP #&01    ;is A=1
C941	BCC &C958   ;if less (0) then set CRT register directly

C943	BNE &C93C   ;if not 1 jump to VDUV for VDU extension

********** turn cursor on/off *******************************************

C945	JSR &C588   ;A=0 if text cursor, A=&20 if graphics cursor
C948	BNE &C937   ;if graphics exit
C94A	LDA #&20    ;A=&20 - preload to turn cursor off
C94C	LDY &031C   ;Y=second VDU parameter
C94F	BEQ &C954   ;if 0, jump to C954 to turn cursor off
C951	LDA &035F   ;get last setting of CRT controller register
                   ;for cursor on
C954	LDY #&0A    ;Y=10 - cursor control register number
C956	BNE &C985   ;jump to C985, Y=register, Y=value

********** set CRT controller *******************************************

C958	LDA &031D   ;get third
C95B	LDY &031C   ;and second parameter
C95E	CPY #&07    ;is Y=7
C960	BCC &C985   ;if less C985
C962	BNE &C967   ;else if >7 C967
C964	ADC &0290   ;else ADD screen vertical display adjustment

C967	CPY #&08    ;If Y<>8
C969	BNE &C972   ;C972
C96B	ORA #&00    ;if bit 7 set
C96D	BMI &C972   ;C972
C96F	EOR &0291   ;else EOR with interlace toggle

C972	CPY #&0A    ;Y=10??
C974	BNE &C985   ;if not C985
C976	STA &035F   ;last setting of CRT controller register
C979	TAY         ;Y=A
C97A	LDA &D0     ;VDU status byte
C97C	AND #&20    ;check bit 5 printing at graphics cursor??
C97E	PHP         ;push flags
C97F	TYA         ;Y=A
C980	LDY #&0A    ;Y=10
C982	PLP         ;pull flags
C983	BNE &C98B   ;if graphics in use then C98B


C985	STY &FE00   ;else set CRTC address register
C988	STA &FE01   ;and poke new value to register Y
C98B	RTS         ;exit


*************************************************************************
*                                                                       *
*       VDU 25 - PLOT                                                   *
*       PLOT k,x,y                                                      *
*                                                                       *
*       5 parameters                                                    *
*                                                                       *
*************************************************************************
;
C98C	LDX &0361   ;pixels per byte
C98F	BEQ &C938   ;if no graphics available go to VDU Extension
C991	JMP &D060   ;else enter Plot routine at D060


********** adjust screen RAM addresses **********************************

C994	LDX &0350   ;window area start address lo
C997	LDA &0351   ;window area start address hi
C99A	JSR &CCF8   ;subtract bytes per character row from this
C99D	BCS &C9B3   ;if no wraparound needed C9B3

C99F	ADC &0354   ;screen RAM size hi byte to wrap around
C9A2	BCC &C9B3   ;

C9A4	LDX &0350   ;window area start address lo
C9A7	LDA &0351   ;window area start address hi
C9AA	JSR &CAD4   ;add bytes per char. row
C9AD	BPL &C9B3   ;

C9AF	SEC         ;wrap around i other direction
C9B0	SBC &0354   ;screen RAM size hi byte
C9B3	STA &0351   ;window area start address hi
C9B6	STX &0350   ;window area start address lo
C9B9	LDY #&0C    ;Y=12
C9BB	BNE &CA0E   ;jump to CA0E


*************************************************************************
*                                                                       *
*       VDU 26 - SET DEFAULT WINDOWS                                    *
*                                                                       *
*************************************************************************

C9BD	LDA #&00    ;A=0
C9BF	LDX #&2C    ;X=&2C

C9C1	STA &0300,X ;clear all windows
C9C4	DEX         ;
C9C5	BPL &C9C1   ;until X=&FF

C9C7	LDX &0355   ;screen mode
C9CA	LDY C3EF,X  ;text window right hand margin maximum
C9CD	STY &030A   ;text window right
C9D0	JSR &CA88   ;calculate number of bytes in a line
C9D3	LDY &C3E7,X ;text window bottom margin maximum
C9D6	STY &0309   ;bottom margin
C9D9	LDY #&03    ;Y=3
C9DB	STY &0323   ;set as last parameter
C9DE	INY         ;increment Y
C9DF	STY &0321   ;set parameters
C9E2	DEC &0322   ;
C9E5	DEC &0320   ;
C9E8	JSR &CA39   ;and do VDU 24
C9EB	LDA #&F7    ;
C9ED	JSR &C5A8   ;clear bit 3 of &D0
C9F0	LDX &0350   ;window area start address lo
C9F3	LDA &0351   ;window area start address hi
C9F6	STX &034A   ;text cursor 6845 address
C9F9	STA &034B   ;text cursor 6845 address
C9FC	BPL &CA02   ;set cursor position
C9FE	SEC         ;
C9FF	SBC &0354   ;screen RAM size hi byte


**************** set cursor position ************************************

CA02	STX &D8     ;set &D8/9 from X/A
CA04	STA &D9     ;
CA06	LDX &034A   ;text cursor 6845 address
CA09	LDA &034B   ;text cursor 6845 address
CA0C	LDY #&0E    ;Y=15
CA0E	PHA         ;Push A
CA0F	LDA &0355   ;screen mode
CA12	CMP #&07    ;is it mode 7?
CA14	PLA         ;get back A
CA15	BCS &CA27   ;if mode 7 selected CA27
CA17	STX &DA     ;else store X
CA19	LSR         ;divide X/A by 8
CA1A	ROR &DA     ;
CA1C	LSR         ;
CA1D	ROR &DA     ;
CA1F	LSR         ;
CA20	ROR &DA     ;
CA22	LDX &DA     ;
CA24	JMP &CA2B   ;goto CA2B

CA27	SBC #&74    ;mode 7 subtract &74
CA29	EOR #&20    ;EOR with &20
CA2B	STY &FE00   ;write to CRTC address file register
CA2E	STA &FE01   ;and to relevant address (register 14)
CA31	INY         ;Increment Y
CA32	STY &FE00   ;write to CRTC address file register
CA35	STX &FE01   ;and to relevant address (register 15)
CA38	RTS         ;and RETURN
\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CA39 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CA39
new file mode 100644
index 0000000..576492f
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CA39
@@ -0,0 +1 @@
+*************************************************************************
*                                                                       *
*       VDU 24 - DEFINE GRAPHICS WINDOW                                 *
*                                                                       *
*       8 parameters                                                    *
*                                                                       *
*************************************************************************
;&31C/D Left margin
;&31E/F Bottom margin
;&320/1 Right margin
;&322/3 Top margin

CA39	JSR &CA81   ;exchange 310/3 with 328/3
CA3C	LDX #&1C    ;
CA3E	LDY #&2C    ;
CA40	JSR &D411   ;calculate width=right - left
    	            ;          height = top-bottom
CA43	ORA &032D   ;
CA46	BMI &CA81   ;exchange 310/3 with 328/3 and exit
CA48	LDX #&20    ;X=&20
CA4A	JSR &D149   ;scale pointers to mode
CA4D	LDX #&1C    ;X=&1C
CA4F	JSR &D149   ;scale pointers to mode
CA52	LDA &031F   ;check for negative margins
CA55	ORA &031D   ;
CA58	BMI &CA81   ;if found exchange 310/3 with 328/3 and exit
CA5A	LDA &0323   ;
CA5D	BNE &CA81   ;exchange 310/3 with 328/3 and exit
CA5F	LDX &0355   ;screen mode
CA62	LDA &0321   ;right margin hi
CA65	STA &DA     ;store it
CA67	LDA &0320   ;right margin lo
CA6A	LSR &DA     ;/2
CA6C	ROR         ;A=A/2
CA6D	LSR &DA     ;/2
CA6F	BNE &CA81   ;exchange 310/3 with 328/3
CA71	ROR         ;A=A/2
CA72	LSR         ;A=A/2
CA73	CMP C3EF,X  ;text window right hand margin maximum
CA76	BEQ &CA7A   ;if equal CA7A
CA78	BPL &CA81   ;exchange 310/3 with 328/3

CA7A	LDY #&00    ;Y=0
CA7C	LDX #&1C    ;X=&1C
CA7E	JSR &D47C   ;set(300/7+Y) from (300/7+X)


***************** exchange 310/3 with 328/3 *****************************

CA81	LDX #&10    ;X=10
CA83	LDY #&28    ;Y=&28
CA85	JMP &CDE6   ;exchange 300/3+Y and 300/3+X

CA88	INY         ;Y=Y+1
CA89	TYA         ;A=Y
CA8A	LDY #&00    ;Y=0
CA8C	STY &034D   ;text window width hi (bytes)
CA8F	STA &034C   ;text window width lo (bytes)
CA92	LDA &034F   ;bytes per character
CA95	LSR         ;/2
CA96	BEQ &CAA1   ;if 0 exit
CA98	ASL &034C   ;text window width lo (bytes)
CA9B	ROL &034D   ;text window width hi (bytes)
CA9E	LSR         ;/2
CA9F	BCC &CA98   ;
CAA1	RTS         ;


*************************************************************************
*                                                                       *
*       VDU 29 - SET GRAPHICS ORIGIN                                    *
*                                                                       *
*       4 parameters                                                    *
*                                                                       *
*************************************************************************
;
CAA2	LDX #&20    ;
CAA4	LDY #&0C    ;
CAA6	JSR &D48A   ;(&300/3+Y)=(&300/3+X)
CAA9	JMP &D1B8   ;set up external coordinates for graphics


*************************************************************************
*                                                                       *
*       VDU 127 (&7F) - DELETE (entry 32)                               *
*                                                                       *
*************************************************************************

CAAC	JSR &C5C5   ;cursor left
CAAF	JSR &C588   ;A=0 if text cursor A=&20 if graphics cursor
CAB2	BNE &CAC7   ;if graphics then CAC7
CAB4	LDX &0360   ;number of logical colours less 1
CAB7	BEQ &CAC2   ;if mode 7 CAC2
CAB9	STA &DE     ;else store A (always 0)
CABB	LDA #&C0    ;A=&C0
CABD	STA &DF     ;store in &DF (&DE) now points to C300 SPACE pattern
CABF	JMP &CFBF   ;display a space

CAC2	LDA #&20    ;A=&20
CAC4	JMP &CFDC   ;and return to display a space

CAC7	LDA #&7F    ;for graphics cursor
CAC9	JSR &D03E   ;set up character definition pointers
CACC	LDX &035A   ;Background graphics colour
CACF	LDY #&00    ;Y=0
CAD1	JMP &CF63   ;invert pattern data (to background colour)


***** Add number of bytes in a line to X/A ******************************

CAD4	PHA         ;store A
CAD5	TXA         ;A=X
CAD6	CLC         ;clear carry
CAD7	ADC &0352   ;bytes per character row
CADA	TAX         ;X=A
CADB	PLA         ;get back A
CADC	ADC &0353   ;bytes per character row
CADF	RTS         ;and return
;
********* control scrolling in paged mode *******************************

CAE0	JSR &CB14   ;zero paged mode line counter
CAE3	JSR &E9D9   ;osbyte 118 check keyboard status; set LEDs
CAE6	BCC &CAEA   ;if carry clear CAEA
CAE8	BMI &CAE0   ;if M set CAE0 do it again

CAEA	LDA &D0     ;VDU status byte
CAEC	EOR #&04    ;invert bit 2 paged scrolling
CAEE	AND #&46    ;and if 2 cursors, paged mode off, or scrolling
CAF0	BNE &CB1C   ;barred then CB1C to exit

CAF2	LDA &0269   ;paged mode counter
CAF5	BMI &CB19   ;if negative then exit via CB19



CAF7	LDA &0319   ;current text line
CAFA	CMP &0309   ;bottom margin
CAFD	BCC &CB19   ;increment line counter and exit

CAFF	LSR         ;A=A/4
CB00	LSR         ;
CB01	SEC         ;set carry
CB02	ADC &0269   ;paged mode counter
CB05	ADC &030B   ;top of text window
CB08	CMP &0309   ;bottom margin
CB0B	BCC &CB19   ;increment line counter and exit

CB0D	CLC         ;clear carry
CB0E	JSR &E9D9   ;osbyte 118 check keyboard status; set LEDs
CB11	SEC         ;set carry
CB12	BPL &CB0E   ;if +ve result then loop till shift pressed


**************** zero paged mode  counter *******************************

CB14	LDA #&FF    ;
CB16	STA &0269   ;paged mode counter
CB19	INC &0269   ;paged mode counter
CB1C	RTS         ;
;

*********part of intitialisation routines ******************************

CB1D	PHA         ;save A
CB1E	LDX #&7F    ;X=&7F
CB20	LDA #&00    ;A=0
CB22	STA &D0     ;VDU status byte to set default conditions

CB24	STA &02FF,X ;zero 300,37E
CB27	DEX         ;with this loop
CB28	BNE &CB24   ;

CB2A	JSR &CD07   ;implode character definitions
CB2D	PLA         ;get back A
CB2E	LDX #&7F    ;X=&7F
CB30	STX &0366   ;mode 7 write cursor character
CB33	BIT &028E   ;available RAM pages
CB36	BMI &CB3A   ;if 32k CB3A

CB38	ORA #&04    ;ensure only modes 4-7 are available

CB3A	AND #&07    ;X=A and 7 ensure legal mode
CB3C	TAX         ;X=mode
CB3D	STX &0355   ;set screen mode flag
CB40	LDA &C414,X ;no. of colours -1 in mode table
CB43	STA &0360   ;number of logical colours less 1
CB46	LDA &C3FF,X ;number of bytes /character for each mode
CB49	STA &034F   ;bytes per character
CB4C	LDA &C43A,X ;display mode pixels/byte table
CB4F	STA &0361   ;pixels per byte
CB52	BNE &CB56   ;if <> 0 CB56
CB54	LDA #&07    ;else A=7

CB56	ASL         ;A=A*2
CB57	TAY         ;Y=A






CB58	LDA &C406,Y ;mask table
CB5B	STA &0363   ;colour mask left
CB5E	ASL         ;A=A*2
CB5F	BPL &CB5E   ;If still +ve CB5E
CB61	STA &0362   ;colour mask right
CB64	LDY &C440,X ;screen display memory index table
CB67	STY &0356   ;memory map type
CB6A	LDA &C44F,Y ;VDU section control
CB6D	JSR &E9F8   ;set hardware scrolling to VIA
CB70	LDA &C44B,Y ;VDU section control
CB73	JSR &E9F8   ;set hardware scrolling to VIA
CB76	LDA &C459,Y ;Screen RAM size hi byte table
CB79	STA &0354   ;screen RAM size hi byte
CB7C	LDA &C45E,Y ;screen ram address hi byte
CB7F	STA &034E   ;hi byte of screen RAM address
CB82	TYA         ;Y=A
CB83	ADC #&02    ;Add 2
CB85	EOR #&07    ;
CB87	LSR         ;/2
CB88	TAX         ;X=A
CB89	LDA &C466,X ;row multiplication table pointer
CB8C	STA &E0     ;store it
CB8E	LDA #&C3    ;A=&C3
CB90	STA &E1     ;store it (&E0) now points to C3B5 or C375
CB92	LDA &C463,X ;get nuber of bytes per row from table
CB95	STA &0352   ;store as bytes per character row
CB98	STX &0353   ;bytes per character row
CB9B	LDA #&43    ;A=&43
CB9D	JSR &C5A8   ;A=A and &D0:&D0=A
CBA0	LDX &0355   ;screen mode
CBA3	LDA &C3F7,X ;get video ULA control setting
CBA6	JSR &EA00   ;set video ULA using osbyte 154
CBA9	PHP         ;push flags
CBAA	SEI         ;set interrupts
CBAB	LDX &C469,Y ;get cursor end register data from table
CBAE	LDY #&0B    ;Y=11

CBB0	LDA &C46E,X ;get end of 6845 registers 0-11 table
CBB3	JSR &C95E   ;set register Y
CBB6	DEX         ;reduce pointers
CBB7	DEY         ;
CBB8	BPL &CBB0   ;and if still >0 do it again

CBBA	PLP         ;pull flags
CBBB	JSR &C839   ;set default colours
CBBE	JSR &C9BD   ;set default windows

CBC1	LDX #&00    ;X=0
CBC3	LDA &034E   ;hi byte of screen RAM address
CBC6	STX &0350   ;window area start address lo
CBC9	STA &0351   ;window area start address hi
CBCC	JSR &C9F6   ;use X and Y to set new cursor address
CBCF	LDY #&0C    ;Y=12
CBD1	JSR &CA2B   ;set registers 12 and 13 in CRTC
CBD4	LDA &0358   ;background text colour
CBD7	LDX &0356   ;memory map type
CBDA	LDY &C454,X ;get section control number
CBDD	STY &035D   ;set it in jump vector lo
CBE0	LDY #&CC    ;Y=&CC
CBE2	STY &035E   ;upper byte of link address
CBE5	LDX #&00    ;X=0
CBE7	STX &0269   ;paged mode counter
CBEA	STX &0318   ;text column
CBED	STX &0319   ;current text line
CBF0	JMP (&035D) ;jump vector set up previously


*************************************************************************
*                                                                       *
*       OSWORD 10 - READ CHARACTER DEFINITION                           *
*                                                                       *
*************************************************************************
;&EF=A:&F0=X:&F1=Y, on entry YX contains number of byte to be read
;(&DE) points to address
;on exit byte YX+1 to YX+8 contain definition

CBF3	JSR &D03E   ;set up character definition pointers
CBF6	LDY #&00    ;Y=0
CBF8	LDA (&DE),Y ;get first byte
CBFA	INY         ;Y=Y+1
CBFB	STA (&F0),Y ;store it in YX
CBFD	CPY #&08    ;until Y=8
CBFF	BNE &CBF8   ;
CC01	RTS         ;then exit
;

*************************************************************************
*                                                                       *
*       MAIN SCREEN CLEARANCE ROUTINE                                   *
*                                                                       *
*************************************************************************
;on entry A contains background colour which is set in every byte
;of the screen

************************ Mode 0,1,2 entry point *************************

CC02	STA &3000,X ;
CC05	STA &3100,X ;
CC08	STA &3200,X ;
CC0B	STA &3300,X ;
CC0E	STA &3400,X ;
CC11	STA &3500,X ;
CC14	STA &3600,X ;
CC17	STA &3700,X ;
CC1A	STA &3800,X ;
CC1D	STA &3900,X ;
CC20	STA &3A00,X ;
CC23	STA &3B00,X ;
CC26	STA &3C00,X ;
CC29	STA &3D00,X ;
CC2C	STA &3E00,X ;
CC2F	STA &3F00,X ;

************************ Mode 3 entry point *****************************

CC32	STA &4000,X ;
CC35	STA &4100,X ;
CC38	STA &4200,X ;
CC3B	STA &4300,X ;
CC3E	STA &4400,X ;
CC41	STA &4500,X ;
CC44	STA &4600,X ;
CC47	STA &4700,X ;
CC4A	STA &4800,X ;
CC4D	STA &4900,X ;
CC50	STA &4A00,X ;
CC53	STA &4B00,X ;
CC56	STA &4C00,X ;
CC59	STA &4D00,X ;
CC5C	STA &4E00,X ;
CC5F	STA &4F00,X ;
CC62	STA &5000,X ;
CC65	STA &5100,X ;
CC68	STA &5200,X ;
CC6B	STA &5300,X ;
CC6E	STA &5400,X ;
CC71	STA &5500,X ;
CC74	STA &5600,X ;
CC77	STA &5700,X ;

************************ Mode 4,5 entry point ***************************

CC7A	STA &5800,X ;
CC7D	STA &5900,X ;
CC80	STA &5A00,X ;
CC83	STA &5B00,X ;
CC86	STA &5C00,X ;
CC89	STA &5D00,X ;
CC8C	STA &5E00,X ;
CC8F	STA &5F00,X ;

************************ Mode 6 entry point *****************************

CC92	STA &6000,X ;
CC95	STA &6100,X ;
CC98	STA &6200,X ;
CC9B	STA &6300,X ;
CC9E	STA &6400,X ;
CCA1	STA &6500,X ;
CCA4	STA &6600,X ;
CCA7	STA &6700,X ;
CCAA	STA &6800,X ;
CCAD	STA &6900,X ;
CCB0	STA &6A00,X ;
CCB3	STA &6B00,X ;
CCB6	STA &6C00,X ;
CCB9	STA &6D00,X ;
CCBC	STA &6E00,X ;
CCBF	STA &6F00,X ;
CCC2	STA &7000,X ;
CCC5	STA &7100,X ;
CCC8	STA &7200,X ;
CCCB	STA &7300,X ;
CCCE	STA &7400,X ;
CCD1	STA &7500,X ;
CCD4	STA &7600,X ;
CCD7	STA &7700,X ;
CCDA	STA &7800,X ;
CCDD	STA &7900,X ;
CCE0	STA &7A00,X ;
CCE3	STA &7B00,X ;

************************ Mode 7 entry point *****************************

CCE6	STA &7C00,X ;
CCE9	STA &7D00,X ;
CCEC	STA &7E00,X ;
CCEF	STA &7F00,X ;
CCF2	INX         ;
CCF3	BEQ &CD65   ;exit

****************** execute required function ****************************

CCF5	JMP (&035D) ;jump vector set up previously




********* subtract bytes per line from X/A ******************************

CCF8	PHA         ;Push A
CCF9	TXA         ;A=X
CCFA	SEC         ;set carry for subtraction
CCFB	SBC &0352   ;bytes per character row
CCFE	TAX         ;restore X
CCFF	PLA         ;and A
CD00	SBC &0353   ;bytes per character row
CD03	CMP &034E   ;hi byte of screen RAM address
CD06	RTS         ;return


*************************************************************************
*                                                                       *
*       OSBYTE 20 - EXPLODE CHARACTERS                                  *
*                                                                       *
*************************************************************************
;
CD07	LDA #&0F    ;A=15
CD09	STA &0367   ;font flag indicating that page &0C,&C0-&C2 are
    	            ;used for user defined characters
CD0C	LDA #&0C    ;A=&0C
CD0E	LDY #&06    ;set loop counter

CD10	STA &0368,Y ;set all font location bytes
CD13	DEY         ;to page &0C to indicate only page available
CD14	BPL &CD10   ;for user character definitions

CD16	CPX #&07    ;is X= 7 or greater
CD18	BCC &CD1C   ;if not CD1C
CD1A	LDX #&06    ;else X=6
CD1C	STX &0246   ;character definition explosion switch
CD1F	LDA &0243   ;A=primary OSHWM
CD22	LDX #&00    ;X=0

CD24	CPX &0246   ;character definition explosion switch
CD27	BCS &CD34   ;
CD29	LDY &C4BA,X ;get soft character  RAM allocation
CD2C	STA &0368,Y ;font location bytes
CD2F	ADC #&01    ;Add 1
CD31	INX         ;X=X+1
CD32	BNE &CD24   ;if X<>0 then CD24

CD34	STA &0244   ;current value of page (OSHWM)
CD37	TAY         ;Y=A
CD38	BEQ &CD06   ;return via CD06 (ERROR?)

CD3A	LDX #&11    ;X=&11
CD3C	JMP &F168   ;issue paged ROM service call &11
    	            ;font implosion/explosion warning

******** move text cursor to next line **********************************

CD3F	LDA #&02    ;A=2 to check if scrolling disabled
CD41	BIT &D0     ;VDU status byte
CD43	BNE &CD47   ;if scrolling is barred CD47
CD45	BVC &CD79   ;if cursor editing mode disabled RETURN

CD47	LDA &0309   ;bottom margin
CD4A	BCC &CD4F   ;if carry clear on entry CD4F
CD4C	LDA &030B   ;else if carry set get top of text window
CD4F	BVS &CD59   ;and if cursor editing enabled CD59
CD51	STA &0319   ;get current text line
CD54	PLA         ;pull return link from stack
CD55	PLA         ;
CD56	JMP &C6AF   ;set up cursor and display address

CD59	PHP         ;push flags
CD5A	CMP &0365   ;Y coordinate of text input cursor
CD5D	BEQ &CD78   ;if A=line count of text input cursor CD78 to exit
CD5F	PLP         ;get back flags
CD60	BCC &CD66   ;
CD62	DEC &0365   ;Y coordinate of text input cursor

CD65	RTS         ;exit
;
CD66	INC &0365   ;Y coordinate of text input cursor
CD69	RTS         ;exit


*********************** set up write cursor ********************************

CD6A	PHP         ;save flags
CD6B	PHA         ;save A
CD6C	LDY &034F   ;bytes per character
CD6F	DEY         ;Y=Y-1
CD70	BNE &CD8F   ;if Y=0 Mode 7 is in use

CD72	LDA &0338   ;so get mode 7 write character cursor character &7F
CD75	STA (&D8),Y ;store it at top scan line of current character
CD77	PLA         ;pull A
CD78	PLP         ;pull flags
CD79	RTS         ;and exit
;
CD7A	PHP         ;push flags
CD7B	PHA         ;push A
CD7C	LDY &034F   ;bytes per character
CD7F	DEY         ;
CD80	BNE &CD8F   ;if not mode 7
CD82	LDA (&D8),Y ;get cursor from top scan line
CD84	STA &0338   ;store it
CD87	LDA &0366   ;mode 7 write cursor character
CD8A	STA (&D8),Y ;store it at scan line
CD8C	JMP &CD77   ;and exit

CD8F	LDA #&FF    ;A=&FF =cursor
CD91	CPY #&1F    ;except in mode 2 (Y=&1F)
CD93	BNE &CD97   ;if not CD97
CD95	LDA #&3F    ;load cursor byte mask


********** produce white block write cursor *****************************

CD97	STA &DA     ;store it
CD99	LDA (&D8),Y ;get scan line byte
CD9B	EOR &DA     ;invert it
CD9D	STA (&D8),Y ;store it on scan line
CD9F	DEY         ;decrement scan line counter
CDA0	BPL &CD99   ;do it again
CDA2	BMI &CD77   ;then jump to &CD77

CDA4	JSR &CE5B   ;exchange line and column cursors with workspace copies
CDA7	LDA &0309   ;bottom margin
CDAA	STA &0319   ;current text line
CDAD	JSR &CF06   ;set up display address
CDB0	JSR &CCF8   ;subtract bytes per character row from this
CDB3	BCS &CDB8   ;wraparound if necessary
CDB5	ADC &0354   ;screen RAM size hi byte
CDB8	STA &DB     ;store A
CDBA	STX &DA     ;X
CDBC	STA &DC     ;A again
CDBE	BCS &CDC6   ;if C set there was no wraparound so CDC6
CDC0	JSR &CE73   ;copy line to new position
    	            ;using (&DA) for read
    	            ;and (&D8) for write
CDC3	JMP &CDCE   ;

CDC6	JSR &CCF8   ;subtract bytes per character row from X/A
CDC9	BCC &CDC0   ;if a result is outside screen RAM CDC0
CDCB	JSR &CE38   ;perform a copy

CDCE	LDA &DC     ;set write pointer from read pointer
CDD0	LDX &DA     ;
CDD2	STA &D9     ;
CDD4	STX &D8     ;
CDD6	DEC &DE     ;decrement window height
CDD8	BNE &CDB0   ;and if not zero CDB0
CDDA	LDX #&28    ;point to workspace
CDDC	LDY #&18    ;point to text column/line
CDDE	LDA #&02    ;number of bytes to swap
CDE0	BNE &CDE8   ;exchange (328/9)+Y with (318/9)+X
CDE2	LDX #&24    ;point to graphics cursor
CDE4	LDY #&14    ;point to last graphics cursor
    	            ;A=4 to swap X and Y coordinates


*************** exchange 300/3+Y with 300/3+X ***************************

CDE6	LDA #&04    ;A =4


************** exchange (300/300+A)+Y with (300/300+A)+X *****************

CDE8	STA &DA     ;store it as loop counter

CDEA	LDA &0300,X ;get byte
\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CDED b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CDED
new file mode 100644
index 0000000..ef1ac9b
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/CDED
@@ -0,0 +1 @@
+CDED	PHA         ;store it
CDEE	LDA &0300,Y ;get byte pointed to by Y
CDF1	STA &0300,X ;put it in 300+X
CDF4	PLA         ;get back A
CDF5	STA &0300,Y ;put it in 300+Y
CDF8	INX         ;increment pointers
CDF9	INY         ;
CDFA	DEC &DA     ;decrement loop counter
CDFC	BNE &CDEA   ;and if not 0 do it again
CDFE	RTS         ;and exit

******** execute upward scroll ******************************************
;
CDFF	JSR &CE5B   ;exchange line and column cursors with workspace copies
CE02	LDY &030B   ;top of text window
CE05	STY &0319   ;current text line
CE08	JSR &CF06   ;set up display address
CE0B	JSR &CAD4   ;add bytes per char. row
CE0E	BPL &CE14   ;
CE10	SEC         ;
CE11	SBC &0354   ;screen RAM size hi byte

CE14	STA &DB     ;(&DA)=X/A
CE16	STX &DA     ;
CE18	STA &DC     ;&DC=A
CE1A	BCC &CE22   ;
CE1C	JSR &CE73   ;copy line to new position
    	            ;using (&DA) for read
    	            ;and (&D8) for write
CE1F	JMP &CE2A   ;exit


CE22	JSR &CAD4   ;add bytes per char. row
CE25	BMI &CE1C   ;if outside screen RAM CE1C
CE27	JSR &CE38   ;perform a copy
CE2A	LDA &DC     ;
CE2C	LDX &DA     ;
CE2E	STA &D9     ;
CE30	STX &D8     ;
CE32	DEC &DE     ;decrement window height
CE34	BNE &CE0B   ;CE0B if not 0
CE36	BEQ &CDDA   ;exchange text column/linelse CDDA


*********** copy routines ***********************************************

CE38	LDX &034D   ;text window width hi (bytes)
CE3B	BEQ &CE4D   ;if no more than 256 bytes to copy X=0 so CE4D

CE3D	LDY #&00    ;Y=0 to set loop counter

CE3F	LDA (&DA),Y ;copy 256 bytes
CE41	STA (&D8),Y ;
CE43	INY         ;
CE44	BNE &CE3F   ;Till Y=0 again
CE46	INC &D9     ;increment hi bytes
CE48	INC &DB     ;
CE4A	DEX         ;decrement window width
CE4B	BNE &CE3F   ;if not 0 go back and do loop again

CE4D	LDY &034C   ;text window width lo (bytes)
CE50	BEQ &CE5A   ;if Y=0 CE5A

CE52	DEY         ;else Y=Y-1
CE53	LDA (&DA),Y ;copy Y bytes
CE55	STA (&D8),Y ;
CE57	TYA         ;A=Y
CE58	BNE &CE52   ;if not 0 CE52
CE5A	RTS         ;and exit
;

CE5B	JSR &CDDA   ;exchange text column/line with workspace
CE5E	SEC         ;set carry
CE5F	LDA &0309   ;bottom margin
CE62	SBC &030B   ;top of text window
CE65	STA &DE     ;store it
CE67	BNE &CE6E   ;set text column to left hand column
CE69	PLA         ;get back return address
CE6A	PLA         ;
CE6B	JMP &CDDA   ;exchange text column/line with workspace

CE6E	LDA &0308   ;text window left
CE71	BPL &CEE3   ;Jump CEE3 always!

CE73	LDA &DA     ;get back A
CE75	PHA         ;push A
CE76	SEC         ;set carry
CE77	LDA &030A   ;text window right
CE7A	SBC &0308   ;text window left
CE7D	STA &DF     ;
CE7F	LDY &034F   ;bytes per character to set loop counter

CE82	DEY         ;copy loop
CE83	LDA (&DA),Y ;
CE85	STA (&D8),Y ;
CE87	DEY         ;
CE88	BPL &CE83   ;

CE8A	LDX #&02    ;X=2
CE8C	CLC         ;clear carry
CE8D	LDA &D8,X   ;
CE8F	ADC &034F   ;bytes per character
CE92	STA &D8,X   ;
CE94	LDA &D9,X   ;
CE96	ADC #&00    ;
CE98	BPL &CE9E   ;if this remains in screen RAM OK

CE9A	SEC         ;else wrap around screen
CE9B	SBC &0354   ;screen RAM size hi byte
CE9E	STA &D9,X   ;
CEA0	DEX         ;X=X-2
CEA1	DEX         ;
CEA2	BEQ &CE8C   ;if X=0 adjust second set of pointers
CEA4	DEC &DF     ;decrement window width
CEA6	BPL &CE7F   ;and if still +ve do it all again
CEA8	PLA         ;get back A
CEA9	STA &DA     ;and store it
CEAB	RTS         ;then exit
;
*********** clear a line ************************************************

CEAC	LDA &0318   ;text column
CEAF	PHA         ;save it
CEB0	JSR &CE6E   ;set text column to left hand column
CEB3	JSR &CF06   ;set up display address
CEB6	SEC         ;set carry
CEB7	LDA &030A   ;text window right
CEBA	SBC &0308   ;text window left
CEBD	STA &DC     ;as window width
CEBF	LDA &0358   ;background text colour
CEC2	LDY &034F   ;bytes per character

CEC5	DEY         ;Y=Y-1 decrementing loop counter
CEC6	STA (&D8),Y ;store background colour at this point on screen
CEC8	BNE &CEC5   ;if Y<>0 do it again
CECA	TXA         ;else A=X
CECB	CLC         ;clear carry to add
CECC	ADC &034F   ;bytes per character
CECF	TAX         ;X=A restoring it
CED0	LDA &D9     ;get hi byte
CED2	ADC #&00    ;Add carry if any
CED4	BPL &CEDA   ;if +ve CeDA
CED6	SEC         ;else wrap around
CED7	SBC &0354   ;screen RAM size hi byte






CEDA	STX &D8     ;restore D8/9
CEDC	STA &D9     ;
CEDE	DEC &DC     ;decrement window width
CEE0	BPL &CEBF   ;ind if not 0 do it all again
CEE2	PLA         ;get back A
CEE3	STA &0318   ;restore text column
CEE6	SEC         ;set carry
CEE7	RTS         ;and exit
;

CEE8	LDX &0318   ;text column
CEEB	CPX &0308   ;text window left
CEEE	BMI &CEE6   ;if less than left margin return with carry set
CEF0	CPX &030A   ;text window right
CEF3	BEQ &CEF7   ;if equal to right margin thats OK
CEF5	BPL &CEE6   ;if greater than right margin return with carry set

CEF7	LDX &0319   ;current text line
CEFA	CPX &030B   ;top of text window
CEFD	BMI &CEE6   ;if less than top margin
CEFF	CPX &0309   ;bottom margin
CF02	BEQ &CF06   ;set up display address
CF04	BPL &CEE6   ;or greater than bottom margin return with carry set



************:set up display address *************************************

;Mode 0: (0319)*640+(0318)* 8
;Mode 1: (0319)*640+(0318)*16
;Mode 2: (0319)*640+(0318)*32
;Mode 3: (0319)*640+(0318)* 8
;Mode 4: (0319)*320+(0318)* 8
;Mode 5: (0319)*320+(0318)*16
;Mode 6: (0319)*320+(0318)* 8
;Mode 7: (0319)* 40+(0318)
;this gives a displacement relative to the screen RAM start address
;which is added to the calculated number and stored in in 34A/B
;if the result is less than &8000, the top of screen RAM it is copied into X/A
;and D8/9.
;if the result is greater than &7FFF the hi byte of screen RAM size is
;subtracted to wraparound the screen. X/A, D8/9 are then set from this

CF06	LDA &0319   ;current text line
CF09	ASL         ;A=A*2
CF0A	TAY         ;Y=A
CF0B	LDA (&E0),Y ;get CRTC multiplication table pointer
CF0D	STA &D9     ;&D9=A
CF0F	INY         ;Y=Y+1
CF10	LDA #&02    ;A=2
CF12	AND &0356   ;memory map type
CF15	PHP         ;save flags
CF16	LDA (&E0),Y ;get CRTC multiplication table pointer
CF18	PLP         ;pull flags
CF19	BEQ &CF1E   ;
CF1B	LSR &D9     ;&D9=&D9/2
CF1D	ROR         ;A=A/2 +(128*carry)
CF1E	ADC &0350   ;window area start address lo
CF21	STA &D8     ;store it
CF23	LDA &D9     ;
CF25	ADC &0351   ;window area start address hi
CF28	TAY         ;
CF29	LDA &0318   ;text column
CF2C	LDX &034F   ;bytes per character
CF2F	DEX         ;X=X-1
CF30	BEQ &CF44   ;if X=0 mode 7 CF44
CF32	CPX #&0F    ;is it mode 1 or mode 5?
CF34	BEQ &CF39   ;yes CF39 with carry set
CF36	BCC &CF3A   ;if its less (mode 0,3,4,6) CF3A
CF38	ASL         ;A=A*16 if entered here (mode 2)

CF39	ASL         ;A=A*8 if entered here

CF3A	ASL         ;A=A*4 if entered here
CF3B	ASL         ;
CF3C	BCC &CF40   ;if carry clear
CF3E	INY         ;Y=Y+2
CF3F	INY         ;
CF40	ASL         ;A=A*2
CF41	BCC &CF45   ;if carry clear add to &D8
CF43	INY         ;if not Y=Y+1

CF44	CLC         ;clear carry
CF45	ADC &D8     ;add to &D8
CF47	STA &D8     ;and store it
CF49	STA &034A   ;text cursor 6845 address
CF4C	TAX         ;X=A
CF4D	TYA         ;A=Y
CF4E	ADC #&00    ;Add carry if set
CF50	STA &034B   ;text cursor 6845 address
CF53	BPL &CF59   ;if less than &800 goto &CF59
CF55	SEC         ;else wrap around
CF56	SBC &0354   ;screen RAM size hi byte

CF59	STA &D9     ;store in high byte
CF5B	CLC         ;clear carry
CF5C	RTS         ;and exit


******** Graphics cursor display routine ********************************

CF5D	LDX &0359   ;foreground graphics colour
CF60	LDY &035B   ;foreground graphics plot mode (GCOL n)
CF63	JSR &D0B3   ;set graphics byte mask in &D4/5
CF66	JSR &D486   ;copy (324/7) graphics cursor to workspace (328/B)
CF69	LDY #&00    ;Y=0
CF6B	STY &DC     ;&DC=Y
CF6D	LDY &DC     ;Y=&DC
CF6F	LDA (&DE),Y ;get pattern byte
CF71	BEQ &CF86   ;if A=0 CF86
CF73	STA &DD     ;else &DD=A
CF75	BPL &CF7A   ;and if >0 CF7A
CF77	JSR &D0E3   ;else display a pixel
CF7A	INC &0324   ;current horizontal graphics cursor
CF7D	BNE &CF82   ;
CF7F	INC &0325   ;current horizontal graphics cursor

CF82	ASL &DD     ;&DD=&DD*2
CF84	BNE &CF75   ;and if<>0 CF75
CF86	LDX #&28    ;point to workspace
CF88	LDY #&24    ;point to horizontal graphics cursor
CF8A	JSR &D482   ;0300/1+Y=0300/1+X
CF8D	LDY &0326   ;current vertical graphics cursor
CF90	BNE &CF95   ;
CF92	DEC &0327   ;current vertical graphics cursor
CF95	DEC &0326   ;current vertical graphics cursor
CF98	LDY &DC     ;
CF9A	INY         ;
CF9B	CPY #&08    ;if Y<8 then do loop again
CF9D	BNE &CF6B   ;else
CF9F	LDX #&28    ;point to workspace
CFA1	LDY #&24    ;point to graphics cursor
CFA3	JMP &D48A   ;(&300/3+Y)=(&300/3+X)


*********** home graphics cursor ***************************************

CFA6	LDX #&06    ;point to graphics window TOP
CFA8	LDY #&26    ;point to workspace
CFAA	JSR &D482   ;0300/1+Y=0300/1+X


************* set graphics cursor to left hand column *******************

CFAD	LDX #&00    ;X=0 point to graphics window left
CFAF	LDY #&24    ;Y=&24
CFB1	JSR &D482   ;0300/1+Y=0300/1+X
CFB4	JMP &D1B8   ;set up external coordinates for graphics
CFB7	LDX &0360   ;number of logical colours less 1
CFBA	BEQ &CFDC   ;if MODE 7 CFDC

CFBC	JSR &D03E   ;set up character definition pointers
CFBF	LDX &0360   ;number of logical colours less 1
CFC2	LDA &D0     ;VDU status byte
CFC4	AND #&20    ;and out bit 5 printing at graphics cursor
CFC6	BNE &CF5D   ;if set CF5D
CFC8	LDY #&07    ;else Y=7
CFCA	CPX #&03    ;if X=3
CFCC	BEQ &CFEE   ;goto CFEE to handle 4 colour modes
CFCE	BCS &D01E   ;else if X>3 D01E to deal with 16 colours

CFD0	LDA (&DE),Y ;get pattern byte
CFD2	ORA &D2     ;text colour byte to be orred or EORed into memory
CFD4	EOR &D3     ;text colour byte to be orred or EORed into memory
CFD6	STA (&D8),Y ; write to screen
CFD8	DEY         ;Y=Y-1
CFD9	BPL &CFD0   ;if still +ve do loop again
CFDB	RTS         ;and exit

******* convert teletext characters *************************************
;mode 7
CFDC	LDY #&02    ;Y=2
CFDE	CMP &C4B6,Y ;compare with teletext conversion table
CFE1	BEQ &CFE9   ;if equal then CFE9
CFE3	DEY         ;else Y=Y-1
CFE4	BPL &CFDE   ;and if +ve CFDE

CFE6	STA (&D8,X) ;if not write byte to screen
CFE8	RTS         ;and exit



CFE9	LDA &C4B7,Y ;convert with teletext conversion table
CFEC	BNE &CFE6   ;and write it


***********four colour modes ********************************************

CFEE	LDA (&DE),Y ;get pattern byte
CFF0	PHA         ;save it
CFF1	LSR         ;move hi nybble to lo
CFF2	LSR         ;
CFF3	LSR         ;
CFF4	LSR         ;
CFF5	TAX         ;X=A
CFF6	LDA &C31F,X ;4 colour mode byte mask look up table
CFF9	ORA &D2     ;text colour byte to be orred or EORed into memory
CFFB	EOR &D3     ;text colour byte to be orred or EORed into memory
CFFD	STA (&D8),Y ; write to screen
CFFF	TYA         ;A=Y

D000	CLC         ;clear carry
D001	ADC #&08    ;add 8 to move screen RAM pointer 8 bytes
D003	TAY         ;Y=A
D004	PLA         ;get back A
D005	AND #&0F    ;clear high nybble
D007	TAX         ;X=A
D008	LDA &C31F,X ;4 colour mode byte mask look up table
D00B	ORA &D2     ;text colour byte to be orred or EORed into memory
D00D	EOR &D3     ;text colour byte to be orred or EORed into memory
D00F	STA (&D8),Y ; write to screen
D011	TYA         ;A=Y
D012	SBC #&08    ;A=A-9
D014	TAY         ;Y=A
D015	BPL &CFEE   ;if +ve do loop again
D017	RTS         ;exit

    	

D018	TYA         ;Y=Y-&21
D019	SBC #&21    ;
D01B	BMI &D017   ;IF Y IS negative then RETURN
D01D	TAY         ;else A=Y

******* 16 COLOUR MODES *************************************************

D01E	LDA (&DE),Y ;get pattern byte
D020	STA &DC     ;store it
D022	SEC         ;set carry
D023	LDA #&00    ;A=0
D025	ROL &DC     ;carry now occupies bit 0 of DC
D027	BEQ &D018   ;when DC=0 again D018 to deal with next pattern byte
D029	ROL         ;get bit 7 from &DC into A bit 0
D02A	ASL &DC     ;rotate again to get second
D02C	ROL         ;bit into A
D02D	TAX         ;and store result in X
D02E	LDA &C32F,X ;multiply by &55 using look up table
D031	ORA &D2     ;and set colour factors
D033	EOR &D3     ;
D035	STA (&D8),Y ;and store result
D037	CLC         ;clear carry
D038	TYA         ;Y=Y+8 moving screen RAM pointer on 8 bytes
D039	ADC #&08    ;
D03B	TAY         ;
D03C	BCC &D023   ;iloop to D023 to deal with next bit pair


************* calculate pattern address for given code ******************
;A contains code on entry = 12345678

D03E	ASL         ;23456780  C holds 1
D03F	ROL         ;34567801  C holds 2
D040	ROL         ;45678012  C holds 3
D041	STA &DE     ;save this pattern
D043	AND #&03    ;00000012
D045	ROL         ;00000123 C=0
D046	TAX         ;X=A=0 - 7
D047	AND #&03    ;A=00000023
D049	ADC #&BF    ;A=&BF,C0 or C1
D04B	TAY         ;this is used as a pointer
D04C	LDA &C40D,X ;A=&80/2^X i.e.1,2,4,8,&10,&20,&40, or &80
D04F	BIT &0367   ;with font flag
D052	BEQ &D057   ;if 0 D057
D054	LDY &0367,X ;else get hi byte from table
D057	STY &DF     ;store Y
D059	LDA &DE     ;get back pattern
D05B	AND #&F8    ;convert to 45678000
D05D	STA &DE     ;and re store it
D05F	RTS         ;exit
    	            ;
*************************************************************************
*************************************************************************
**                                                                      **
**                                                                      **
**      PLOT ROUTINES ENTER HERE                                        **
**                                                                      **
**                                                                      **
*************************************************************************
*************************************************************************
;on entry    ADDRESS    PARAMETER        DESCRIPTION
;   	    031F    1               plot type
;   	    0320/1  2,3             X coordinate
;   	    0322/3  4,5             Y coordinate

D060	LDX #&20    ;X=&20
D062	JSR &D14D   ;translate coordinates

D065	LDA &031F   ;get plot type
D068	CMP #&04    ;if its 4
D06A	BEQ &D0D9   ;D0D9 move absolute
D06C	LDY #&05    ;Y=5
D06E	AND #&03    ;mask only bits 0 and 1
D070	BEQ &D080   ;if result is 0 then its a move (multiple of 8)
D072	LSR         ;else move bit 0 int C
D073	BCS &D078   ;if set then D078 graphics colour required
D075	DEY         ;Y=4
D076	BNE &D080   ;logic inverse colour must be wanted

******** graphics colour wanted *****************************************

D078	TAX         ;X=A if A=0 its a foreground colour 1 its background
D079	LDY &035B,X ;get fore or background graphics PLOT mode
D07C	LDA &0359,X ;get fore or background graphics colour
D07F	TAX         ;X=A

D080	JSR &D0B3   ;set up colour masks in D4/5

D083	LDA &031F   ;get plot type
D086	BMI &D0AB   ;if &80-&FF then D0AB type not implemented
D088	ASL         ;bit 7=bit 6
D089	BPL &D0C6   ;if bit 6 is 0 then plot type is 0-63 so D0C6
D08B	AND #&F0    ;else mask out lower nybble
D08D	ASL         ;shift old bit 6 into C bit old 5 into bit 7
D08E	BEQ &D0D6   ;if 0 then type 64-71 was called single point plot
    	            ;goto D0D6
D090	EOR #&40    ;if bit 6 NOT set type &80-&87 fill triangle
D092	BEQ &D0A8   ;so D0A8
D094	PHA         ;else push A
D095	JSR &D0DC   ;copy 0320/3 to 0324/7 setting XY in current graphics
    	            ;coordinates
D098	PLA         ;get back A
D099	EOR #&60    ;if BITS 6 and 5 NOT SET type 72-79 lateral fill
D09B	BEQ &D0AE   ;so D0AE
D09D	CMP #&40    ;if type 88-95 horizontal line blanking
D09F	BNE &D0AB   ;so D0AB

D0A1	LDA #&02    ;else A=2
D0A3	STA &DC     ;store it
D0A5	JMP &D506   ;and jump to D506 type not implemented

D0A8	JMP &D5EA   ;to fill triangle routine

D0AB	JMP &C938   ;VDU extension access entry

D0AE	STA &DC     ;store A
D0B0	JMP &D4BF   ;

*********:set colour masks **********************************************
;graphics mode in Y
;colour in X

D0B3	TXA         ;A=X
D0B4	ORA &C41C,Y ;or with GCOL plot options table byte
D0B7	EOR &C41D,Y ;EOR with following byte
D0BA	STA &D4     ;and store it
D0BC	TXA         ;A=X
D0BD	ORA &C41B,Y ;
D0C0	EOR &C420,Y ;
D0C3	STA &D5     ;
D0C5	RTS         ;exit with masks in &D4/5


************** analyse first parameter in 0-63 range ********************
    	            ;
D0C6	ASL         ;shift left again
D0C7	BMI &D0AB   ;if -ve options are in range 32-63 not implemented
D0C9	ASL         ;shift left twice more
D0CA	ASL         ;
D0CB	BPL &D0D0   ;if still +ve type is 0-7 or 16-23 so D0D0
D0CD	JSR &D0EB   ;else display a point

D0D0	JSR &D1ED   ;perform calculations
D0D3	JMP &D0D9   ;


*************************************************************************
*                                                                       *
*       PLOT A SINGLE POINT                                             *
*                                                                       *
*************************************************************************

D0D6	JSR &D0EB   ;display a point
D0D9	JSR &CDE2   ;swap current and last graphics position
D0DC	LDY #&24    ;Y=&24
D0DE	LDX #&20    ;X=&20
D0E0	JMP &D48A   ;copy parameters to 324/7 (300/3 +Y)


D0E3	LDX #&24    ;
D0E5	JSR &D85F   ;calculate position
D0E8	BEQ &D0F0   ;if result =0 then D0F0
D0EA	RTS         ;else exit
    	            ;
D0EB	JSR &D85D   ;calculate position
D0EE	BNE &D103   ;if A<>0 D103 and return
D0F0	LDY &031A   ;else get current graphics scan line
D0F3	LDA &D1     ;pick up and modify screen byte
D0F5	AND &D4     ;
D0F7	ORA (&D6),Y ;
D0F9	STA &DA     ;
D0FB	LDA &D5     ;
D0FD	AND &D1     ;
D0FF	EOR &DA     ;
D101	STA (&D6),Y ;put it back again
D103	RTS         ;and exit
    	            ;

D104	LDA (&D6),Y ;this is a more simplistic version of the above
D106	ORA &D4     ;
D108	EOR &D5     ;
D10A	STA (&D6),Y ;
D10C	RTS         ;and exit


\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D10D b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D10D
new file mode 100644
index 0000000..7978697
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D10D
@@ -0,0 +1 @@
+************************** Check window limits *************************
    	            ;
D10D	LDX #&24    ;X=&24
D10F	LDY #&00    ;Y=0
D111	STY &DA     ;&DA=0
D113	LDY #&02    ;Y=2
D115	JSR &D128   ;check vertical graphics position 326/7
    	            ;bottom and top margins 302/3, 306/7
D118	ASL &DA     ;DATA is set in &DA bits 0 and 1 then shift left
D11A	ASL &DA     ;twice to make room for next pass
D11C	DEX         ;X=&22
D11D	DEX         ;
D11E	LDY #&00    ;Y=0
D120	JSR &D128   ;left and right margins 300/1, 304/5
    	            ;cursor horizontal position 324/5
D123	INX         ;X=X+2
D124	INX         ;
D125	LDA &DA     ;A=&DA
D127	RTS         ;exit


*** cursor and margins check ******************************************
    	            ;
D128	LDA &0302,X ;check for window violation
D12B	CMP &0300,Y ;300/1 +Y > 302/3+X
D12E	LDA &0303,X ;then window fault
D131	SBC &0301,Y ;
D134	BMI &D146   ;so D146

D136	LDA &0304,Y ;check other windows
D139	CMP &0302,X ;
D13C	LDA &0305,Y ;
D13F	SBC &0303,X ;
D142	BPL &D148   ;if no violation exit
D144	INC &DA     ;else DA=DA+1

D146	INC &DA     ;DA=DA+1
D148	RTS         ;and exit  DA=0 no problems DA=1 first check 2, 2nd
    	            ;


***********set up and adjust positional data ****************************

D149	LDA #&FF    ;A=&FF
D14B	BNE &D150   ;then &D150

D14D	LDA &031F   ;get first parameter in plot

D150	STA &DA     ;store in &DA
D152	LDY #&02    ;Y=2
D154	JSR &D176   ;set up vertical coordinates/2
D157	JSR &D1AD   ;/2 again to convert 1023 to 0-255 for internal use
    	            ;this is why minimum vertical plot separation is 4
D15A	LDY #&00    ;Y=0
D15C	DEX         ;X=x-2
D15D	DEX         ;
D15E	JSR &D176   ;set up horiz. coordinates/2 this is OK for mode0,4
D161	LDY &0361   ;get number of pixels/byte (-1)
D164	CPY #&03    ;if Y=3 (modes 1 and 5)
D166	BEQ &D16D   ;D16D
D168	BCS &D170   ;for modes 0 & 4 this is 7 so D170
D16A	JSR &D1AD   ;for other modes divide by 2 twice

D16D	JSR &D1AD   ;divide by 2
D170	LDA &0356   ;get screen display type
D173	BNE &D1AD   ;if not 0 (modes 3-7) divide by 2 again
D175	RTS         ;and exit

;for mode 0 1 division  1280 becomes 640 = horizontal resolution
;for mode 1 2 divisions 1280 becomes 320 = horizontal resolution
;for mode 2 3 divisions 1280 becomes 160 = horizontal resolution
;for mode 4 2 divisions 1280 becomes 320 = horizontal resolution
;for mode 5 3 divisions 1280 becomes 160 = horizontal resolution


********** calculate external coordinates in internal format ***********
;on entry X is usually &1E or &20

    	            ;
D176	CLC         ;clear carry
D177	LDA &DA     ;get &DA
D179	AND #&04    ;if bit 2=0
D17B	BEQ &D186   ;then D186 to calculate relative coordinates
D17D	LDA &0302,X ;else get coordinate
D180	PHA         ;
D181	LDA &0303,X ;
D184	BCC &D194   ;and goto D194

D186	LDA &0302,X ;get coordinate
D189	ADC &0310,Y ;add cursor position
D18C	PHA         ;save it
D18D	LDA &0303,X ;
D190	ADC &0311,Y ;add cursor
D193	CLC         ;clear carry

D194	STA &0311,Y ;save new cursor
D197	ADC &030D,Y ;add graphics origin
D19A	STA &0303,X ;store it
D19D	PLA         ;get back lo byte
D19E	STA &0310,Y ;save it in new cursor lo
D1A1	CLC         ;clear carry
D1A2	ADC &030C,Y ;add to graphics orgin
D1A5	STA &0302,X ;store it
D1A8	BCC &D1AD   ;if carry set
D1AA	INC &0303,X ;increment hi byte as you would expect!

D1AD	LDA &0303,X ;get hi byte
D1B0	ASL         ;
D1B1	ROR &0303,X ;divide by 2
D1B4	ROR &0302,X ;
D1B7	RTS         ;and exit
    	            ;

***** calculate external coordinates from internal coordinates************
D1B8	LDY #&10    ;Y=10
D1BA	JSR &D488   ;copy 324/7 to 310/3 i.e.current graphics cursor
    	            ;position to position in external values
D1BD	LDX #&02    ;X=2
D1BF	LDY #&02    ;Y=2
D1C1	JSR &D1D5   ;multiply 312/3 by 4 and subtract graphics origin
D1C4	LDX #&00    ;X=0
D1C6	LDY #&04    ;Y=4
D1C8	LDA &0361   ;get  number of pixels/byte
D1CB	DEY         ;Y=Y-1
D1CC	LSR         ;divide by 2
D1CD	BNE &D1CB   ;if result not 0 D1CB
D1CF	LDA &0356   ;else get screen display type
D1D2	BEQ &D1D5   ;and if 0 D1D5
D1D4	INY         ;

D1D5	ASL &0310,X ;multiply coordinate by 2
D1D8	ROL &0311,X ;
D1DB	DEY         ;Y-Y-1
D1DC	BNE &D1D5   ;and if Y<>0 do it again
D1DE	SEC         ;set carry
D1DF	JSR &D1E3   ;
D1E2	INX         ;increment X

D1E3	LDA &0310,X ;get current graphics position in external coordinates
D1E6	SBC &030C,X ;subtract origin
D1E9	STA &0310,X ;store in graphics position
D1EC	RTS         ;and exit
    	            ;


************* compare X and Y PLOT spans ********************************

D1ED	JSR &D40D   ;Set X and Y spans in workspace 328/9 32A/B
D1F0	LDA &032B   ;compare spans
D1F3	EOR &0329   ;if result -ve spans are different in sign so
D1F6	BMI &D207   ;goto D207
D1F8	LDA &032A   ;else A=hi byte of difference in spans
D1FB	CMP &0328   ;
D1FE	LDA &032B   ;
D201	SBC &0329   ;
D204	JMP &D214   ;and goto D214

D207	LDA &0328   ;A = hi byte of SUM of spans
D20A	CLC         ;
D20B	ADC &032A   ;
D20E	LDA &0329   ;
D211	ADC &032B   ;


D214	ROR         ;A=A/2
D215	LDX #&00    ;X=0
D217	EOR &032B   ;
D21A	BPL &D21E   ;if positive result D21E

D21C	LDX #&02    ;else X=2

D21E	STX &DE     ;store it
D220	LDA &C4AA,X ;set up vector address
D223	STA &035D   ;in 35D
D226	LDA &C4AB,X ;
D229	STA &035E   ;and 35E
D22C	LDA &0329,X ;get hi byte of span
D22F	BPL &D235   ;if +ve D235
D231	LDX #&24    ;X=&24
D233	BNE &D237   ;jump to D237

D235	LDX #&20    ;X=&20
D237	STX &DF     ;store it
D239	LDY #&2C    ;Y=&2C
D23B	JSR &D48A   ;get X coordinate data or horizontal coord of
    	            ;curent graphics cursor
D23E	LDA &DF     ;get back original X
D240	EOR #&04    ;covert &20 to &24 and vice versa
D242	STA &DD     ;
D244	ORA &DE     ;
D246	TAX         ;
D247	JSR &D480   ;copy 330/1 to 300/1+X
D24A	LDA &031F   ;get plot type
D24D	AND #&10    ;check bit 4
D24F	ASL         ;
D250	ASL         ;
D251	ASL         ;move to bit 7
D252	STA &DB     ;store it
D254	LDX #&2C    ;X=&2C
D256	JSR &D10F   ;check for window violations
D259	STA &DC     ;
D25B	BEQ &D263   ;if none then D263
D25D	LDA #&40    ;else set bit 6 of &DB
D25F	ORA &DB     ;
D261	STA &DB     ;

D263	LDX &DD     ;
D265	JSR &D10F   ;check window violations again
D268	BIT &DC     ;if bit 7 of &DC NOT set
D26A	BEQ &D26D   ;D26D
D26C	RTS         ;else exit
    	            ;
D26D	LDX &DE     ;X=&DE
D26F	BEQ &D273   ;if X=0 D273
D271	LSR         ;A=A/2
D272	LSR         ;A=A/2

D273	AND #&02    ;clear all but bit 2
D275	BEQ &D27E   ;if bit 2 set D27E
D277	TXA         ;else A=X
D278	ORA #&04    ;A=A or 4 setting bit 3
D27A	TAX         ;X=A
D27B	JSR &D480   ;set 300/1+x to 330/1
D27E	JSR &D42C   ;more calcualtions
D281	LDA &DE     ;A=&DE EOR 2
D283	EOR #&02    ;
D285	TAX         ;X=A
D286	TAY         ;Y=A
D287	LDA &0329   ;compare upper byte of spans
D28A	EOR &032B   ;
D28D	BPL &D290   ;if signs are the same D290
D28F	INX         ;else X=X+1
D290	LDA &C4AE,X ;get vector addresses and store 332/3
D293	STA &0332   ;
D296	LDA &C4B2,X ;
D299	STA &0333   ;

D29C	LDA #&7F    ;A=&7F
D29E	STA &0334   ;store it
D2A1	BIT &DB     ;if bit 6 set
D2A3	BVS &D2CE   ;the D2CE
D2A5	LDA &C447,X ;get VDU section number
D2A8	TAX         ;X=A
D2A9	SEC         ;set carry
D2AA	LDA &0300,X ;subtract coordinates
D2AD	SBC &032C,Y ;
D2B0	STA &DA     ;
D2B2	LDA &0301,X ;
D2B5	SBC &032D,Y ;
D2B8	LDY &DA     ;Y=hi
D2BA	TAX         ;X=lo=A
D2BB	BPL &D2C0   ;and if A+Ve D2C0
D2BD	JSR &D49B   ;negate Y/A

D2C0	TAX         ;X=A increment Y/A
D2C1	INY         ;Y=Y+1
D2C2	BNE &D2C5   ;
D2C4	INX         ;X=X+1
D2C5	TXA         ;A=X
D2C6	BEQ &D2CA   ;if A=0 D2CA
D2C8	LDY #&00    ;else Y=0

D2CA	STY &DF     ;&DF=Y
D2CC	BEQ &D2D7   ;if 0 then D2D7
D2CE	TXA         ;A=X
D2CF	LSR         ;A=A/4
D2D0	ROR         ;
D2D1	ORA #&02    ;bit 1 set
D2D3	EOR &DE     ;
D2D5	STA &DE     ;and store
D2D7	LDX #&2C    ;X=&2C
D2D9	JSR &D864   ;
D2DC	LDX &DC     ;
D2DE	BNE &D2E2   ;
D2E0	DEC &DD     ;
D2E2	DEX         ;X=X-1
D2E3	LDA &DB     ;A=&3B
D2E5	BEQ &D306   ;if 0 D306
D2E7	BPL &D2F9   ;else if +ve D2F9
D2E9	BIT &0334   ;
D2EC	BPL &D2F3   ;if bit 7=0 D2F3
D2EE	DEC &0334   ;else decrement
D2F1	BNE &D316   ;and if not 0 D316

D2F3	INC &0334   ;
D2F6	ASL         ;A=A*2
D2F7	BPL &D306   ;if +ve D306
D2F9	STX &DC     ;
D2FB	LDX #&2C    ;
D2FD	JSR &D85F   ;calcualte screen position
D300	LDX &DC     ;get back original X
D302	ORA #&00    ;
D304	BNE &D316   ;
D306	LDA &D1     ;byte mask for current graphics point
D308	AND &D4     ;and with graphics colour byte
D30A	ORA (&D6),Y ;or  with curent graphics cell line
D30C	STA &DA     ;store result
D30E	LDA &D5     ;same again with next byte (hi??)
D310	AND &D1     ;
D312	EOR &DA     ;
D314	STA (&D6),Y ;then store it inm current graphics line
D316	SEC         ;set carry
D317	LDA &0335   ;A=&335/6-&337/8
D31A	SBC &0337   ;
D31D	STA &0335   ;
D320	LDA &0336   ;
D323	SBC &0338   ;
D326	BCS &D339   ;if carry set D339
D328	STA &DA     ;
D32A	LDA &0335   ;
D32D	ADC &0339   ;
D330	STA &0335   ;
D333	LDA &DA     ;
D335	ADC &033A   ;
D338	CLC         ;
D339	STA &0336   ;
D33C	PHP         ;
D33D	BCS &D348   ;if carry clear jump to VDU routine else D348
D33F	JMP (&0332) ;


****** vertical scan module 1******************************************

D342	DEY         ;Y=Y-1
D343	BPL &D348   ;if + D348
D345	JSR &D3D3   ;else d3d3 to advance pointers
D348	JMP (&035D) ;and JUMP (&35D)


****** vertical scan module 2******************************************

D34B	INY         ;Y=Y+1
D34C	CPY #&08    ;if Y<>8
D34E	BNE &D348   ;then D348
D350	CLC         ;else clear carry
D351	LDA &D6     ;get address of top line of cuirrent graphics cell
D353	ADC &0352   ;add number of bytes/character row
D356	STA &D6     ;store it
D358	LDA &D7     ;do same for hibyte
D35A	ADC &0353   ;
D35D	BPL &D363   ;if result -ve then we are above screen RAM
D35F	SEC         ;so
D360	SBC &0354   ;subtract screen memory size hi
D363	STA &D7     ;store it this wraps around point to screen RAM
D365	LDY #&00    ;Y=0
D367	JMP (&035D) ;

****** horizontal scan module 1******************************************

D36A	LSR &D1     ;shift byte mask
D36C	BCC &D348   ;if carry clear (&D1 was +ve) goto D348
D36E	JSR &D3ED   ;else reset pointers
D371	JMP (&035D) ;and off to do more

****** horizontal scan module 2******************************************

D374	ASL &D1     ;shift byte mask
D376	BCC &D348   ;if carry clear (&D1 was +ve) goto D348
D378	JSR &D3FD   ;else reset pointers
D37B	JMP (&035D) ;and off to do more
    	
D37E	DEY         ;Y=Y-1
D37F	BPL &D38D   ;if +ve D38D
D381	JSR &D3D3   ;advance pointers
D384	BNE &D38D   ;goto D38D normally
D386	LSR &D1     ;shift byte mask
D388	BCC &D38D   ;if carry clear (&D1 was +ve) goto D348
D38A	JSR &D3ED   ;else reset pointers
D38D	PLP         ;pull flags
D38E	INX         ;X=X+1
D38F	BNE &D395   ;if X>0 D395
D391	INC &DD     ;else increment &DD
D393	BEQ &D39F   ;and if not 0 D39F
D395	BIT &DB     ;else if BIT 6 = 1
D397	BVS &D3A0   ;goto D3A0
D399	BCS &D3D0   ;if BIT 7=1 D3D0
D39B	DEC &DF     ;else Decrement &DF
D39D	BNE &D3D0   ;and if not Zero D3D0
D39F	RTS         ;else return
    	            ;
D3A0	LDA &DE     ;A=&DE
D3A2	STX &DC     ;&DC=X
D3A4	AND #&02    ;clear all but bit 1
D3A6	TAX         ;X=A
D3A7	BCS &D3C2   ;and if carry set goto D3C2
D3A9	BIT &DE     ;if Bit 7 of &DE =1
D3AB	BMI &D3B7   ;then D3B7
D3AD	INC &032C,X ;else increment
D3B0	BNE &D3C2   ;and if not 0 D3C2
D3B2	INC &032D,X ;else increment hi byte
D3B5	BCC &D3C2   ;and if carry clear D3C2
D3B7	LDA &032C,X ;esle A=32C,X
D3BA	BNE &D3BF   ;and if not 0 D3BF
D3BC	DEC &032D,X ;decrement hi byte
D3BF	DEC &032C,X ;decrement lo byte

D3C2	TXA         ;A=X
D3C3	EOR #&02    ;invert bit 2
D3C5	TAX         ;X=A
D3C6	INC &032C,X ;Increment 32C/D
D3C9	BNE &D3CE   ;
D3CB	INC &032D,X ;
D3CE	LDX &DC     ;X=&DC
D3D0	JMP &D2E3   ;jump to D2E3


**********move display point up a line **********************************
D3D3	SEC         ;SET CARRY
D3D4	LDA &D6     ;subtract number of bytes/line from address of
D3D6	SBC &0352   ;top line of current graphics cell
D3D9	STA &D6     ;
D3DB	LDA &D7     ;
D3DD	SBC &0353   ;
D3E0	CMP &034E   ;compare with bottom of screen memory
D3E3	BCS &D3E8   ;if outside screen RAM
D3E5	ADC &0354   ;add screen memory size to wrap it around
D3E8	STA &D7     ;store in current address of graphics cell top line
D3EA	LDY #&07    ;Y=7
D3EC	RTS         ;and RETURN

    	            ;
D3ED	LDA &0362   ;get current left colour mask
D3F0	STA &D1     ;store it
D3F2	LDA &D6     ;get current top line of graphics cell
D3F4	ADC #&07    ;ADD 7
D3F6	STA &D6     ;
D3F8	BCC &D3FC   ;
D3FA	INC &D7     ;
D3FC	RTS         ;and return
    	            ;

D3FD	LDA &0363   ;get right colour mask
D400	STA &D1     ;store it
D402	LDA &D6     ;A=top line graphics cell low
D404	BNE &D408   ;if not 0 D408
D406	DEC &D7     ;else decrement hi byte

D408	SBC #&08    ;subtract 9 (8 + carry)
D40A	STA &D6     ;and store in low byte
D40C	RTS         ;return
    	            ;

********:: coordinate subtraction ***************************************

D40D	LDY #&28    ;X=&28
D40F	LDX #&20    ;Y=&20
D411	JSR &D418   ;
D414	INX         ;X=X+2
D415	INX         ;
D416	INY         ;Y=Y+2
D417	INY         ;

D418	SEC         ;set carry
D419	LDA &0304,X ;subtract coordinates
D41C	SBC &0300,X ;
D41F	STA &0300,Y ;
D422	LDA &0305,X ;
D425	SBC &0301,X ;
D428	STA &0301,Y ;
D42B	RTS         ;and return
    	            ;


D42C	LDA &DE     ;A=&DE
D42E	BNE &D437   ;if A=0 D437
D430	LDX #&28    ;X=&28
D432	LDY #&2A    ;Y=&2A
D434	JSR &CDDE   ;exchange 300/1+Y with 300/1+X
    	            ;IN THIS CASE THE X AND Y SPANS!

D437	LDX #&28    ;X=&28
D439	LDY #&37    ;Y=&37
D43B	JSR &D48A   ;copy &300/4+Y to &300/4+X
    	            ;transferring X and Y spans in this case
D43E	SEC         ;set carry
D43F	LDX &DE     ;X=&DE
D441	LDA &0330   ;subtract 32C/D,X from 330/1
D444	SBC &032C,X ;
D447	TAY         ;partial answer in Y
D448	LDA &0331   ;
D44B	SBC &032D,X ;
D44E	BMI &D453   ;if -ve D453
D450	JSR &D49B   ;else negate Y/A

D453	STA &DD     ;store A
D455	STY &DC     ;and Y
D457	LDX #&35    ;X=&35
D459	JSR &D467   ;get coordinates
D45C	LSR         ;
D45D	STA &0301,X ;
D460	TYA         ;
D461	ROR         ;
D462	STA &0300,X ;
D465	DEX         ;
D466	DEX         ;


D467	LDY &0304,X ;
D46A	LDA &0305,X ;
D46D	BPL &D47B   ;if A is +ve RETURN
D46F	JSR &D49B   ;else negate Y/A
D472	STA &0305,X ;store back again
D475	PHA         ;
D476	TYA         ;
D477	STA &0304,X ;
D47A	PLA         ;get back A
D47B	RTS         ;and exit
    	            ;
D47C	LDA #&08    ;A=8
D47E	BNE &D48C   ;copy 8 bytes
D480	LDY #&30    ;Y=&30
D482	LDA #&02    ;A=2
D484	BNE &D48C   ;copy 2 bytes
D486	LDY #&28    ;copy 4 bytes from 324/7 to 328/B
D488	LDX #&24    ;
D48A	LDA #&04    ;



***********copy A bytes from 300,X to 300,Y ***************************

D48C	STA &DA     ;
D48E	LDA &0300,X ;
D491	STA &0300,Y ;
D494	INX         ;
D495	INY         ;
D496	DEC &DA     ;
D498	BNE &D48E   ;
D49A	RTS         ;and return
    	            ;


************* negation routine ******************************************

D49B	PHA         ;save A
D49C	TYA         ;A=Y
D49D	EOR #&FF    ;invert
D49F	TAY         ;Y=A
D4A0	PLA         ;get back A
D4A1	EOR #&FF    ;invert
D4A3	INY         ;Y=Y+1
D4A4	BNE &D4A9   ;if not 0 exit
D4A6	CLC         ;else
D4A7	ADC #&01    ;add 1 to A
D4A9	RTS         ;return
    	            ;
D4AA	JSR &D85D   ;check window boundaries and set up screen pointer
D4AD	BNE &D4B7   ;if A<>0 D4B7
D4AF	LDA (&D6),Y ;else get byte from current graphics cell
D4B1	EOR &035A   ;compare with current background colour
D4B4	STA &DA     ;store it
D4B6	RTS         ;and RETURN
    	            ;

D4B7	PLA         ;get back return link
D4B8	PLA         ;
D4B9	INC &0326   ;increment current graphics cursor vertical lo
D4BC	JMP &D545   ;
\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D4BF b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D4BF
new file mode 100644
index 0000000..2d10030
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D4BF
@@ -0,0 +1 @@
+OS SERIES IV
GEOFF COX

*************************************************************************
*                                                                       *
*  LATERAL FILL ROUTINE                                                 *
*                                                                       *
*************************************************************************

D4BF	JSR &D4AA   ;check current screen state
D4C2	AND &D1     ;if A and &D1 <> 0 a plotted point has been found
D4C4	BNE &D4B9   ;so D4B9
D4C6	LDX #&00    ;X=0
D4C8	JSR &D592   ;update pointers
D4CB	BEQ &D4FA   ;if 0 then D4FA
D4CD	LDY &031A   ;else Y=graphics scan line
D4D0	ASL &D1     ;
D4D2	BCS &D4D9   ;if carry set D4D9
D4D4	JSR &D574   ;else D574
D4D7	BCC &D4FA   ;if carry clear D4FA
D4D9	JSR &D3FD   ;else D3FD to pick up colour multiplier
D4DC	LDA (&D6),Y ;get graphics cell line
D4DE	EOR &035A   ;EOR with background colour
D4E1	STA &DA     ;and store
D4E3	BNE &D4F7   ;if not 0 D4F7
D4E5	SEC         ;else set carry
D4E6	TXA         ;A=X
D4E7	ADC &0361   ;add pixels/byte
D4EA	BCC &D4F0   ;and if carry clear D4F0
D4EC	INC &DB     ;else increment &DB
D4EE	BPL &D4F7   ;and if +ve D4F7

D4F0	TAX         ;else X=A
D4F1	JSR &D104   ;display a pixel
D4F4	SEC         ;set carry
D4F5	BCS &D4D9   ;goto D4D9


D4F7	JSR &D574   ;
D4FA	LDY #&00    ;Y=0
D4FC	JSR &D5AC   ;
D4FF	LDY #&20    ;
D501	LDX #&24    ;
D503	JSR &CDE6   ;exchange 300/3 +Y with 300/3+X
D506	JSR &D4AA   ;check screen pixel
D509	LDX #&04    ;Y=5
D50B	JSR &D592   ;
D50E	TXA         ;A=x
D50F	BNE &D513   ;if A<>0 d513
D511	DEC &DB     ;else  &DB=&dB-1

D513	DEX         ;X=X-1
D514	JSR &D54B   ;
D517	BCC &D540   ;
D519	JSR &D3ED   ;update pointers
D51C	LDA (&D6),Y ;get byte from graphics line
D51E	EOR &035A   ;EOR with background colour
D521	STA &DA     ;and store it
D523	LDA &DC     ;
D525	BNE &D514   ;If A-0 back to D514
D527	LDA &DA     ;else A=&DA
D529	BNE &D53D   ;if A<>d53D
D52B	SEC         ;else set carry
D52C	TXA         ;A=x
D52D	ADC &0361   ;Add number of pixels/byte
D530	BCC &D536   ;and if carry clear D536
D532	INC &DB     ;else inc DB
D534	BPL &D53D   ;and if +ve D53D
D536	TAX         ;get back X
D537	JSR &D104   ;display a point
D53A	SEC         ;set carry
D53B	BCS &D519   ;goto D519

D53D	JSR &D54B   ;
D540	LDY #&04    ;
D542	JSR &D5AC   ;


D545	JSR &D0D9   ;
D548	JMP &D1B8   ;scale pointers

D54B	LDA &D1     ;get byte mask
D54D	PHA         ;save it
D54E	CLC         ;clear carry
D54F	BCC &D560   ;

D551	PLA         ;get back A
D552	INX         ;X=X+1
D553	BNE &D559   ;if not 0 D559
D555	INC &DB     ;else inc &DB
D557	BPL &D56F   ;if +ve D56F
D559	LSR &D1     ;
D55B	BCS &D56F   ;if Bit 7 D1 set D56F
D55D	ORA &D1     ;else or withA
D55F	PHA         ;save result
D560	LDA &D1     ;A=&D1
D562	BIT &DA     ;test bits 6 and 7 of &DA
D564	PHP         ;save flags
D565	PLA         ;get into A
D566	EOR &DC     ;EOR and DC
D568	PHA         ;save A
D569	PLP         ;
D56A	BEQ &D551   ;

D56C	PLA         ;A=A EOR &D1 (byte mask)
D56D	EOR &D1     ;
D56F	STA &D1     ;store it
D571	JMP &D0F0   ;and display a pixel

D574	LDA #&00    ;A=0
D576	CLC         ;Clear carry

D577	BCC &D583   ;goto D583 if carry clear

D579	INX         ;X=X+1
D57A	BNE &D580   ;If <>0 D580
D57C	INC &DB     ;else inc &DB
D57E	BPL &D56F   ;and if +ve d56F

D580	ASL         ;A=A*2
D581	BCS &D58E   ;if C set D58E
D583	ORA &D1     ;else A=A OR (&D1)
D585	BIT &DA     ;set V and M from &DA b6 b7
D587	BEQ &D579   ;
D589	EOR &D1     ;A=AEOR &D1
D58B	LSR         ;/2
D58C	BCC &D56F   ;if carry clear D56F
D58E	ROR         ;*2
D58F	SEC         ;set carry
D590	BCS &D56F   ;to D56F


D592	LDA &0300,X ;Y/A=(&300/1 +X)-(&320/1)
D595	SEC         ;
D596	SBC &0320   ;
D599	TAY         ;
D59A	LDA &0301,X ;
D59D	SBC &0321   ;
D5A0	BMI &D5A5   ;if result -ve D5A5
D5A2	JSR &D49B   ;or negate Y/A
D5A5	STA &DB     ;store A
D5A7	TYA         ;A=Y
D5A8	TAX         ;X=A
D5A9	ORA &DB     ;
D5AB	RTS         ;exit


    	            ;
D5AC	STY &DA     ;Y=&DA
D5AE	TXA         ;A=X
D5AF	TAY         ;Y=A
D5B0	LDA &DB     ;A=&DB
D5B2	BMI &D5B6   ;if -ve D5B6
D5B4	LDA #&00    ;A=0
D5B6	LDX &DA     ;X=&DA
D5B8	BNE &D5BD   ;if <>0 D5BD
D5BA	JSR &D49B   ;negate
D5BD	PHA         ;
D5BE	CLC         ;
D5BF	TYA         ;
D5C0	ADC &0300,X ;Y/A+(&300/1 +X)=(&320/1)
D5C3	STA &0320   ;
D5C6	PLA         ;
D5C7	ADC &0301,X ;
D5CA	STA &0321   ;
D5CD	RTS         ;return


*************************************************************************
*                                                                       *
*       OSWORD 13 - READ LAST TWO GRAPHIC CURSOR POSITIONS              *
*                                                                       *
*************************************************************************
    	            ;
D5CE	LDA #&03    ;A=3
D5D0	JSR &D5D5   ;
D5D3	LDA #&07    ;A=7
D5D5	PHA         ;Save A
D5D6	JSR &CDE2   ;exchange last 2 graphics cursor coordinates with
    	            ;current coordinates
D5D9	JSR &D1B8   ;convert to external coordinates
D5DC	LDX #&03    ;X=3
D5DE	PLA         ;save A
D5DF	TAY         ;Y=A
D5E0	LDA &0310,X ;get graphics coordinate
D5E3	STA (&F0),Y ;store it in OS buffer
D5E5	DEY         ;decrement Y and X
D5E6	DEX         ;
D5E7	BPL &D5E0   ;if +ve do it again
D5E9	RTS         ;then Exit
    	            ;


*************************************************************************
*                                                                       *
*       PLOT Fill triangle routine                                      *
*                                                                       *
*************************************************************************


D5EA	LDX #&20    ;X=&20
D5EC	LDY #&3E    ;Y=&3E
D5EE	JSR &D47C   ;copy 300/7+X to 300/7+Y
    	            ;this gets XY data parameters and current graphics
    	            ;cursor position
D5F1	JSR &D632   ;exchange 320/3 with 324/7 if 316/7=<322/3
D5F4	LDX #&14    ;X=&14
D5F6	LDY #&24    ;Y=&24
D5F8	JSR &D636   ;
D5FB	JSR &D632   ;

D5FE	LDX #&20    ;
D600	LDY #&2A    ;
D602	JSR &D411   ;calculate 032A/B-(324/5-320/1)
D605	LDA &032B   ;and store
D608	STA &0332   ;result

D60B	LDX #&28    ;set pointers
D60D	JSR &D459   ;
D610	LDY #&2E    ;

D612	JSR &D0DE   ;copy 320/3 32/31
D615	JSR &CDE2   ;exchange 314/7 with 324/7
D618	CLC         ;
D619	JSR &D658   ;execute fill routine

D61C	JSR &CDE2   ;
D61F	LDX #&20    ;
D621	JSR &CDE4   ;
D624	SEC         ;
D625	JSR &D658   ;

D628	LDX #&3E    ;;X=&3E
D62A	LDY #&20    ;;Y=&20
D62C	JSR &D47C   ;;copy 300/7+X to 300/7+Y
D62F	JMP &D0D9   ;;this gets XY data parameters and current graphics
    	             ;cursor position

    	
D632	LDX #&20    ;X=&20
D634	LDY #&14    ;Y=&14
D636	LDA &0302,X ;
D639	CMP &0302,Y ;
D63C	LDA &0303,X ;
D63F	SBC &0303,Y ;
D642	BMI &D657   ;if 302/3+Y>302/3+X return
D644	JMP &CDE6   ;else swap 302/3+X with 302/3+Y

    	            ;


*************************************************************************
*                                                                       *
*       OSBYTE 134 - READ CURSOR POSITION                               *
*                                                                       *
*************************************************************************


D647	LDA &0318   ;read current text cursor (X)
D64A	SEC         ;set carry
D64B	SBC &0308   ;subtract left hand column of current text window
D64E	TAX         ;X=A
D64F	LDA &0319   ;get current text cursor (Y)
D652	SEC         ;
D653	SBC &030B   ;suptract top row of current window
D656	TAY         ;Y=A
D657	RTS         ;and exit


    	            ;PLOT routines continue
    	            ;many of the following routines are just manipulations
    	            ;only points of interest will be explained
D658	PHP         ;store flags
D659	LDX #&20    ;X=&20
D65B	LDY #&35    ;Y=&35
D65D	JSR &D411   ;335/6=(324/5+X-320/1)
D660	LDA &0336   ;
D663	STA &033D   ;
D666	LDX #&33    ;
D668	JSR &D459   ;set pointers

D66B	LDY #&39    ;set 339/C=320/3
D66D	JSR &D0DE   ;
D670	SEC         ;
D671	LDA &0322   ;
D674	SBC &0326   ;
D677	STA &031B   ;
D67A	LDA &0323   ;
D67D	SBC &0327   ;
D680	STA &031C   ;
D683	ORA &031B   ;check VDU queque
D686	BEQ &D69F   ;

D688	JSR &D6A2   ;display a line
D68B	LDX #&33    ;
D68D	JSR &D774   ;update pointers
D690	LDX #&28    ;
D692	JSR &D774   ;and again!
D695	INC &031B   ;update VDU queque
D698	BNE &D688   ;and if not empty do it again
D69A	INC &031C   ;else increment next byte
D69D	BNE &D688   ;and do it again

D69F	PLP         ;pull flags
D6A0	BCC &D657   ;if carry clear exit
D6A2	LDX #&39    ;
D6A4	LDY #&2E    ;
D6A6	STX &DE     ;
D6A8	LDA &0300,X ;is 300/1+x<300/1+Y
D6AB	CMP &0300,Y ;
D6AE	LDA &0301,X ;
D6B1	SBC &0301,Y ;
D6B4	BMI &D6BC   ;if so D6BC
D6B6	TYA         ;else A=Y
D6B7	LDY &DE     ;Y=&DE
D6B9	TAX         ;X=A
D6BA	STX &DE     ;&DE=X
D6BC	STY &DF     ;&DF=Y
D6BE	LDA &0300,Y ;
D6C1	PHA         ;
D6C2	LDA &0301,Y ;
D6C5	PHA         ;
D6C6	LDX &DF     ;
D6C8	JSR &D10F   ;check for window violations
D6CB	BEQ &D6DA   ;
D6CD	CMP #&02    ;
D6CF	BNE &D70E   ;
D6D1	LDX #&04    ;
D6D3	LDY &DF     ;
D6D5	JSR &D482   ;
D6D8	LDX &DF     ;
D6DA	JSR &D864   ;set a screen address
D6DD	LDX &DE     ;X=&DE
D6DF	JSR &D10F   ;check for window violations
D6E2	LSR         ;A=A/2
D6E3	BNE &D70E   ;if A<>0 then exit
D6E5	BCC &D6E9   ;else if C clear D6E9
D6E7	LDX #&00    ;
D6E9	LDY &DF     ;
D6EB	SEC         ;
D6EC	LDA &0300,Y ;
D6EF	SBC &0300,X ;
D6F2	STA &DC     ;
D6F4	LDA &0301,Y ;
D6F7	SBC &0301,X ;
D6FA	STA &DD     ;
D6FC	LDA #&00    ;
D6FE	ASL         ;
D6FF	ORA &D1     ;
D701	LDY &DC     ;
D703	BNE &D719   ;
D705	DEC &DD     ;
D707	BPL &D719   ;
D709	STA &D1     ;
D70B	JSR &D0F0   ;display a point
D70E	LDX &DF     ;restore X
D710	PLA         ;and A
D711	STA &0301,X ;store it
D714	PLA         ;get back A
D715	STA &0300,X ;and store it
D718	RTS         ;exit
    	            ;
D719	DEC &DC     ;
D71B	TAX         ;
D71C	BPL &D6FE   ;
D71E	STA &D1     ;
D720	JSR &D0F0   ;display a point
D723	LDX &DC     ;
D725	INX         ;
D726	BNE &D72A   ;
D728	INC &DD     ;
D72A	TXA         ;
D72B	PHA         ;
D72C	LSR &DD     ;
D72E	ROR         ;
D72F	LDY &0361   ;number of pixels/byte
D732	CPY #&03    ;if 3 mode = goto D73B
D734	BEQ &D73B   ;
D736	BCC &D73E   ;else if <3 mode 2 goto D73E
D738	LSR &DD     ;else rotate bottom bit of &DD
D73A	ROR         ;into Accumulator

D73B	LSR &DD     ;rotate bottom bit of &DD
D73D	LSR         ;into Accumulator
D73E	LDY &031A   ;Y=line in current graphics cell containing current
    	            ;point
D741	TAX         ;X=A
D742	BEQ &D753   ;
D744	TYA         ;Y=Y-8
D745	SEC         ;
D746	SBC #&08    ;
D748	TAY         ;

D749	BCS &D74D   ;
D74B	DEC &D7     ;decrement byte of top line off current graphics cell
D74D	JSR &D104   ;display a point
D750	DEX         ;
D751	BNE &D744   ;
D753	PLA         ;
D754	AND &0361   ;pixels/byte
D757	BEQ &D70E   ;
D759	TAX         ;
D75A	LDA #&00    ;A=0
D75C	ASL         ;
D75D	ORA &0363   ;or with right colour mask
D760	DEX         ;
D761	BNE &D75C   ;
D763	STA &D1     ;store as byte mask
D765	TYA         ;Y=Y-8
D766	SEC         ;
D767	SBC #&08    ;
D769	TAY         ;
D76A	BCS &D76E   ;if carry clear
D76C	DEC &D7     ;decrement byte of top line off current graphics cell
D76E	JSR &D0F3   ;display a point
D771	JMP &D70E   ;and exit via D70E

D774	INC &0308,X ;
D777	BNE &D77C   ;
D779	INC &0309,X ;
D77C	SEC         ;
D77D	LDA &0300,X ;
D780	SBC &0302,X ;
D783	STA &0300,X ;
D786	LDA &0301,X ;
D789	SBC &0303,X ;
D78C	STA &0301,X ;
D78F	BPL &D7C1   ;
D791	LDA &030A,X ;
D794	BMI &D7A1   ;
D796	INC &0306,X ;
D799	BNE &D7AC   ;
D79B	INC &0307,X ;
D79E	JMP &D7AC   ;
D7A1	LDA &0306,X ;
D7A4	BNE &D7A9   ;
D7A6	DEC &0307,X ;
D7A9	DEC &0306,X ;
D7AC	CLC         ;
D7AD	LDA &0300,X ;
D7B0	ADC &0304,X ;
D7B3	STA &0300,X ;
D7B6	LDA &0301,X ;
D7B9	ADC &0305,X ;
D7BC	STA &0301,X ;
D7BF	BMI &D791   ;
D7C1	RTS         ;
    	            ;
    	            ;


*************************************************************************
*                                                                       *
*       OSBYTE 135 - READ CHARACTER AT TEXT CURSOR POSITION             *
*                                                                       *
*************************************************************************

D7C2	LDY &0360   ;get number of logical colours
D7C5	BNE &D7DC   ;if Y<>0 mode <>7 so D7DC
D7C7	LDA (&D8),Y ;get address of top scan line of current text chr
D7C9	LDY #&02    ;Y=2
D7CB	CMP &C4B7,Y ;compare with conversion table
D7CE	BNE &D7D4   ;if not equal D7d4
D7D0	LDA &C4B6,Y ;else get next lower byte from table
D7D3	DEY         ;Y=Y-1
D7D4	DEY         ;Y=Y-1
D7D5	BPL &D7CB   ;and if +ve do it again
D7D7	LDY &0355   ;Y=current screen mode
D7DA	TAX         ;return with character in X
D7DB	RTS         ;
    	            ;
D7DC	JSR &D808   ;set up copy of the pattern bytes at text cursor
D7DF	LDX #&20    ;X=&20
D7E1	TXA         ;A=&20
D7E2	PHA         ;Save it
D7E3	JSR &D03E   ;get pattern address for code in A
D7E6	PLA         ;get back A
D7E7	TAX         ;and X
D7E8	LDY #&07    ;Y=7
D7EA	LDA &0328,Y ;get byte in pattern copy
D7ED	CMP (&DE),Y ;check against pattern source
D7EF	BNE &D7F9   ;if not the same D7F9
D7F1	DEY         ;else Y=Y-1
D7F2	BPL &D7EA   ;and if +ve D7EA
D7F4	TXA         ;A=X
D7F5	CPX #&7F    ;is X=&7F (delete)
D7F7	BNE &D7D7   ;if not D7D7
D7F9	INX         ;else X=X+1
D7FA	LDA &DE     ;get byte lo address
D7FC	CLC         ;clear carry
D7FD	ADC #&08    ;add 8
D7FF	STA &DE     ;store it
D801	BNE &D7E8   ;and go back to check next character if <>0

D803	TXA         ;A=X
D804	BNE &D7E1   ;if <>0 D7E1
D806	BEQ &D7D7   ;else D7D7


***************** set up pattern copy ***********************************

D808	LDY #&07    ;Y=7

D80A	STY &DA     ;&DA=Y
D80C	LDA #&01    ;A=1
D80E	STA &DB     ;&DB=A
D810	LDA &0362   ;A=left colour mask
D813	STA &DC     ;store an &DC
D815	LDA (&D8),Y ;get a byte from current text character
D817	EOR &0358   ;EOR with text background colour
D81A	CLC         ;clear carry
D81B	BIT &DC     ;and check bits of colour mask
D81D	BEQ &D820   ;if result =0 then D820
D81F	SEC         ;else set carry
D820	ROL &DB     ;&DB=&DB+Carry
D822	BCS &D82E   ;if carry now set (bit 7 DB originally set) D82E
D824	LSR &DC     ;else  &DC=&DC/2
D826	BCC &D81B   ;if carry clear D81B
D828	TYA         ;A=Y
D829	ADC #&07    ;ADD ( (7+carry)
D82B	TAY         ;Y=A
D82C	BCC &D810   ;
D82E	LDY &DA     ;read modified values into Y and A
D830	LDA &DB     ;
D832	STA &0328,Y ;store copy
D835	DEY         ;and do it again
D836	BPL &D80A   ;until 8 bytes copied
D838	RTS         ;exit
    	            ;
********* pixel reading *************************************************

D839	PHA         ;store A
D83A	TAX         ;X=A
D83B	JSR &D149   ;set up positional data
D83E	PLA         ;get back A
D83F	TAX         ;X=A
D840	JSR &D85F   ;set a screen address after checking for window
    	            ;violations
D843	BNE &D85A   ;if A<>0 D85A to exit with A=&FF
D845	LDA (&D6),Y ;else get top line of current graphics cell
D847	ASL         ;A=A*2 C=bit 7
D848	ROL &DA     ;&DA=&DA+2 +C  C=bit 7 &DA
D84A	ASL &D1     ;byte mask=bM*2 +carry from &DA
D84C	PHP         ;save flags
D84D	BCS &D851   ;if carry set D851
D84F	LSR &DA     ;else restore &DA with bit '=0
D851	PLP         ;pull flags
D852	BNE &D847   ;if Z set D847
D854	LDA &DA     ;else A=&DA AND number of colours in current mode -1
D856	AND &0360   ;
D859	RTS         ;then exit
    	            ;
D85A	LDA #&FF    ;A=&FF
D85C	RTS         ;exit
    	            ;


********** check for window violations and set up screen address **********

D85D	LDX #&20    ;X=&20
D85F	JSR &D10F   ;
D862	BNE &D85C   ;if A<>0 there is a window violation so D85C
D864	LDA &0302,X ;else set up graphics scan line variable
D867	EOR #&FF    ;
D869	TAY         ;
D86A	AND #&07    ;
D86C	STA &031A   ;in 31A
D86F	TYA         ;A=Y
D870	LSR         ;A=A/2
D871	LSR         ;A=A/2
D872	LSR         ;A=A/2
D873	ASL         ;A=A*2 this gives integer value bit 0 =0
D874	TAY         ;Y=A
D875	LDA (&E0),Y ;get high byte of offset from screen RAM start
D877	STA &DA     ;store it
D879	INY         ;Y=Y+1
D87A	LDA (&E0),Y ;get lo byte
D87C	LDY &0356   ;get screen map type
D87F	BEQ &D884   ;if 0 (modes 0,1,2) goto D884
D881	LSR &DA     ;else &DA=&DA/2
D883	ROR         ;and A=A/2 +C if set
    	            ;so 2 byte offset =offset/2

D884	ADC &0350   ;add screen top left hand corner lo
D887	STA &D6     ;store it
D889	LDA &DA     ;get high  byte
D88B	ADC &0351   ;add top left hi
D88E	STA &D7     ;store it
D890	LDA &0301,X ;
D893	STA &DA     ;
D895	LDA &0300,X ;
D898	PHA         ;
D899	AND &0361   ;and then Add pixels per byte-1
D89C	ADC &0361   ;
D89F	TAY         ;Y=A
D8A0	LDA &C406,Y ;A=&80 /2^Y using look up table
D8A3	STA &D1     ;store it
D8A5	PLA         ;get back A
D8A6	LDY &0361   ;Y=&number of pixels/byte
D8A9	CPY #&03    ;is Y=3 (modes 1,6)
D8AB	BEQ &D8B2   ;goto D8B2
D8AD	BCS &D8B5   ;if mode =1 or 4 D8B5
D8AF	ASL         ;A/&DA =A/&DA *2
D8B0	ROL &DA     ;

D8B2	ASL         ;
D8B3	ROL &DA     ;

D8B5	AND #&F8    ;clear bits 0-2
D8B7	CLC         ;clear carry

D8B8	ADC &D6     ;add A/&DA to &D6/7
D8BA	STA &D6     ;
D8BC	LDA &DA     ;
D8BE	ADC &D7     ;
D8C0	BPL &D8C6   ;if result +ve D8C6
D8C2	SEC         ;else set carry
D8C3	SBC &0354   ;and subtract screen memory size making it wrap round

D8C6	STA &D7     ;store it in &D7
D8C8	LDY &031A   ;get line in graphics cell containing current graphics
D8CB	LDA #&00    ;point  A=0
D8CD	RTS         ;And exit
   		    ;
D8CE	PHA         ;Push A
D8CF	LDA #&A0    ;A=&A0
D8D1	LDX &026A   ;X=number of items in VDU queque
D8D4	BNE &D916   ;if not 0 D916
D8D6	BIT &D0     ;else check VDU status byte
D8D8	BNE &D916   ;if either VDU is disabled or plot to graphics
   		    ;cursor enabled then D916
D8DA	BVS &D8F5   ;if cursor editing enabled D8F5
D8DC	LDA &035F   ;else get 6845 register start setting
D8DF	AND #&9F    ;clear bits 5 and 6
D8E1	ORA #&40    ;set bit 6 to modify last cursor size setting
D8E3	JSR &C954   ;change write cursor format
D8E6	LDX #&18    ;X=&18
D8E8	LDY #&64    ;Y=&64
D8EA	JSR &D482   ;set text input cursor from text output cursor
D8ED	JSR &CD7A   ;modify character at cursor poistion
D8F0	LDA #&02    ;A=2
D8F2	JSR &C59D   ;bit 1 of VDU status is set to bar scrolling


D8F5	LDA #&BF    ;A=&BF
D8F7	JSR &C5A8   ;bit 6 of VDU status =0
D8FA	PLA         ;Pull A
D8FB	AND #&7F    ;clear hi bit (7)
D8FD	JSR &C4C0   ;entire VDU routine !!
D900	LDA #&40    ;A=&40
D902	JMP &C59D   ;exit


D905	LDA #&20    ;A=&20
D907	BIT &D0     ;if bit 6 cursor editing is set
D909	BVC &D8CB   ;
D90B	BNE &D8CB   ;or bit 5 is set exit &D8CB
D90D	JSR &D7C2   ;read a character from the screen
D910	BEQ &D917   ;if A=0 on return exit via D917
D912	PHA         ;else store A
D913	JSR &C664   ;perform cursor right

D916	PLA         ;restore A
D917	RTS         ;and exit
   		    ;
D918	LDA #&BD    ;zero bits 2 and 6 of VDU status
D91A	JSR &C5A8   ;
D91D	JSR &C951   ;set normal cursor
D920	LDA #&0D    ;A=&0D
D922	RTS         ;and return
   		    ;this is response of CR as end of edit line


*************************************************************************
*                                                                       *
*       OSBYTE 132 - READ BOTTOM OF DISPLAY RAM                         *
*                                                                       *
*************************************************************************
   		    ;
D923	LDX &0355   ; Get current screen mode


*************************************************************************
*                                                                       *
*       OSBYTE 133 - READ LOWEST ADDRESS FOR GIVEN MODE                 *
*                                                                       *
*************************************************************************

D926	TXA         ; A=X
D927	AND #&07    ; Ensure mode 0-7
D929	TAY         ; Pass to Y into index into screen size table
D92A	LDX &C440,Y ; X=screen size type, 0-4
D92D	LDA &C45E,X ; A=high byte of start address for screen type
D930	LDX #&00    ; Returned address is &xx00
D932	BIT &028E   ; Check available RAM
D935	BMI &D93E   ; If bit 7 set then 32K RAM, so return address
D937	AND #&3F    ; 16K RAM, so drop address to bottom 16K
D939	CPY #&04    ; Check screen mode
D93B	BCS &D93E   ; If mode 4-7, return the address
D93D	TXA         ; If mode 0-3, return &0000 as not enough memory
; exit
D93E	TAY         ; Pass high byte of address to Y
D93F	RTS         ; and return address in YX

\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D940 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D940
new file mode 100644
index 0000000..1c5c51c
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/D940
@@ -0,0 +1 @@
+*************************************************************************
*************************************************************************
**                                                                     **
**      SYSTEM STARTUP                                                 **
**                                                                     **
*************************************************************************
*************************************************************************

* DEFAULT PAGE &02 SETTINGS (VECTORS, OSBYTE VARIABLES)
* RESET CODE

*************************************************************************
*                                                                       *
*       DEFAULT SYSTEM SETTINGS FOR PAGE &02                            *
*                                                                       *
*************************************************************************

-------------------------------------------------------------------------
|                                                                       |
|       DEFAULT VECTOR TABLE                                            |
|                                                                       |
-------------------------------------------------------------------------

D940	DW  &E310	; USERV				&200
D942	DW  &DC54	; BRKV 				&202
D944	DW  &DC93	; IRQ1V				&204
D946	DW  &DE89	; IRQ2V				&206
D948	DW  &DF89	; CLIV 				&208
D94A	DW  &E772	; BYTEV				&20A
D94C	DW  &E7EB	; WORDV				&20C
D94E	DW  &E0A4	; WRCHV				&20E
D950	DW  &DEC5	; RDCHV				&210
D952	DW  &F27D	; FILEV				&212
D954	DW  &F18E	; ARGSV				&214
D956	DW  &F4C9	; BGETV				&216
D958	DW  &F529	; BPUTV				&218
D95A	DW  &FFA6	; GBPBV				&21A
D95C	DW  &F3CA	; FINDV				&21C
D95E	DW  &F1B1	; FSCV 				&21E
D960	DW  &FFA6	; EVNTV				&220
D962	DW  &FFA6	; UPTV 				&222
D964	DW  &FFA6	; NETV 				&224
D966	DW  &FFA6	; VDUV 				&226
D968	DW  &EF02	; KEYV 				&228
D96A	DW  &E4B3	; INSBV				&22A
D96C	DW  &E464	; REMVB				&22C
D96E	DW  &E1D1	; CNPV 				&22E
D970	DW  &FFA6	; IND1V				&230
D972	DW  &FFA6	; IND2V				&232
D974	DW  &FFA6	; IND3V				&234

-------------------------------------------------------------------------
|                                                                       |
|       DEFAULT MOS VARIABLES SETTINGS                                  |
|                                                                       |
-------------------------------------------------------------------------

* Read/Written by OSBYTE &A6 to &FC

D976	DW  &0190   ; OSBYTE variables base address          &236   *FX166/7
		    ; (address to add to osbyte number)
D978	DB  &0D9F   ; Address of extended vectors            &238   *FX168/9
D97A	DB  &02A1   ; Address of ROM information table       &23A   *FX170/1
D97C	DB  &F02B   ; Address of key translation table       &23C   *FX172/3
D97E	DB  &0300   ; Address of VDU variables               &23E   *FX174/5

D980	DB  &00     ; CFS/Vertical sync Timeout counter      &240   *FX176
D981	DB  &00     ; Current input buffer number            &241   *FX177
D982	DB  &FF     ; Keyboard interrupt processing flag     &242   *FX178
D983	DB  &00     ; Primary OSHWM (default PAGE)           &243   *FX179
D984	DB  &00     ; Current OSHWM (PAGE)                   &244   *FX180
D985	DB  &01     ; RS423 input mode                       &245   *FX181
D986	DB  &00     ; Character explosion state              &246   *FX182
D987	DB  &00     ; CFS/RFS selection, CFS=0 ROM=2         &247   *FX183
D988	DB  &00     ; Video ULA control register copy        &248   *FX184
D989	DB  &00     ; Pallette setting copy                  &249   *FX185
D98A	DB  &00     ; ROM number selected at last BRK        &24A   *FX186
D98B	DB  &FF     ; BASIC ROM number                       &24B   *FX187
D98C	DB  &04     ; Current ADC channel number             &24C   *FX188
D98D	DB  &04     ; Maximum ADC channel number             &24D   *FX189
D98E	DB  &00     ; ADC conversion 0/8bit/12bit            &24E   *FX190
D98F	DB  &FF     ; RS423 busy flag (bit 7=0, busy)        &24F   *FX191

D990	DB  &56     ; ACIA control register copy             &250   *FX192
D991	DB  &19     ; Flash counter                          &251   *FX193
D992	DB  &19     ; Flash mark period count                &252   *FX194
D993	DB  &19     ; Flash space period count               &253   *FX195
D994	DB  &32     ; Keyboard auto-repeat delay             &254   *FX196
D995	DB  &08     ; Keyboard auto-repeat rate              &255   *FX197
D996	DB  &00     ; *EXEC file handle                      &256   *FX198
D997	DB  &00     ; *SPOOL file handle                     &257   *FX199
D998	DB  &00     ; Break/Escape handing                   &258   *FX200
D999	DB  &00     ; Econet keyboard disable flag           &259   *FX201
D99A	DB  &20     ; Keyboard status                        &25A   *FX202
		    ;  bit 3=1 shift pressed
		    ;  bit 4=0 caps  lock
		    ;  bit 5=0 shift lock
		    ;  bit 6=1 control bit
		    ;  bit 7=1 shift enabled
D99B	DB  &09     ; Serial input buffer full threshold     &25B   *FX203
D99C	DB  &00     ; Serial input suppression flag          &25C   *FX204
D99D	DB  &00     ; Cassette/RS423 flag (0=CFS, &40=RS423) &25D   *FX205
D99E	DB  &00     ; Econet OSBYTE/OSWORD interception flag &25E   *FX206
D99F	DB  &00     ; Econet OSRDCH interception flag        &25F   *FX207

D9A0	DB  &00     ; Econet OSWRCH interception flag        &260   *FX208
D9A1	DB  &50     ; Speech enable/disable flag (&20/&50)   &261   *FX209
D9A2	DB  &00     ; Sound output disable flag              &262   *FX210
D9A3	DB  &03     ; BELL channel number                    &263   *FX211
D9A4	DB  &90     ; BELL amplitude/Envelope number         &264   *FX212
D9A5	DB  &64     ; BELL frequency                         &265   *FX213
D9A6	DB  &06     ; BELL duration                          &266   *FX214
D9A7	DB  &81     ; Startup message/!BOOT error status     &267   *FX215
D9A8	DB  &00     ; Length of current soft key string      &268   *FX216
D9A9	DB  &00     ; Lines printed since last paged halt    &269   *FX217
D9AA	DB  &00     ; 0-(Number of items in VDU queue)       &26A   *FX218
D9AB	DB  &09     ; TAB key value                          &26B   *FX219
D9AC	DB  &1B     ; ESCAPE character                       &26C   *FX220

	; The following are input buffer code interpretation variables for
	; bytes entered into the input buffer with b7 set (is 128-255).
	; The standard keyboard only enters characters &80-&BF with the
	; function keys, but other characters can be entered, for instance
	; via serial input of via other keyboard input systems.
	; 0=ignore key
	; 1=expand as soft key
	; 2-FF add to base for ASCII code
D9AD	DB  &01     ; C0-&CF                                 &26D   *FX221
D9AE	DB  &D0     ; D0-&DF                                 &26E   *FX222
D9AF	DB  &E0     ; E0-&EF                                 &26F   *FX223
D9B0	DB  &F0     ; F0-&FF                                 &270   *FX224
D9B1	DB  &01     ; 80-&8F function key                    &271   *FX225
D9B2	DB  &80     ; 90-&9F Shift+function key              &272   *FX226
D9B3	DB  &90     ; A0-&AF Ctrl+function key               &273   *FX227
D9B4	DB  &00     ; B0-&BF Shift+Ctrl+function key         &274   *FX228

D9B5	DB  &00     ; ESCAPE key status (0=ESC, 1=ASCII)     &275   *FX229
D9B6	DB  &00     ; ESCAPE action                          &276   *FX230
D9B7	DB  &FF     ; USER 6522 Bit IRQ mask                 &277   *FX231
D9B8	DB  &FF     ; 6850 ACIA Bit IRQ bit mask             &278   *FX232
D9B9	DB  &FF     ; System 6522 IRQ bit mask               &279   *FX233
D9BA	DB  &00     ; Tube prescence flag                    &27A   *FX234
D9BB	DB  &00     ; Speech processor prescence flag        &27B   *FX235
D9BC	DB  &00     ; Character destination status           &27C   *FX236
D9BD	DB  &00     ; Cursor editing status                  &27D   *FX237

****************** Soft Reset high water mark ***************************

D9BE	DB  &00     ; unused                                 &27E   *FX238
D9BF	DB  &00     ; unused                                 &27F   *FX239
D9C0	DB  &00     ; Country code                           &280   *FX240
D9C1	DB  &00     ; User flag                              &281   *FX241
D9C2	DB  &64     ; Serial ULA control register copy       &282   *FX242
D9C3	DB  &05     ; Current system clock state             &283   *FX243
D9C4	DB  &FF     ; Soft key consitancy flag               &284   *FX244
D9C5	DB  &01     ; Printer destination                    &285   *FX245
D9C6	DB  &0A     ; Printer ignore character               &286   *FX246
   	
****************** Hard Reset High water mark ***************************
   	
D9C7	DB  &00     ; Break Intercept Vector JMP opcode      &288   *FX247
D9C8	DB  &00     ; Break Intercept Vector address low     &288   *FX248
D9C9	DB  &00     ; Break Intercept Vector address high    &289   *FX249
D9CA	DB  &00     ; unused (memory used for VDU)           &28A   *FX250
D9CB	DB  &00     ; unused (memory used for display)       &28B   *FX251
D9CC	DB  &FF     ; Current language ROM number            &28C   *FX252
   	
****************** Power-On Reset High Water mark ***********************


**************************************************************************
**************************************************************************
**                                                                      **
**      RESET (BREAK) ENTRY POINT                                       **
**                                                                      **
**      Power up Enter with nothing set, 6522 System VIA IER bits       **
**      0 to 6 will be clear                                            **
**                                                                      **
**      BREAK IER bits 0 to 6 one or more will be set 6522 IER          **
**      not reset by BREAK                                              **
**                                                                      **
**************************************************************************
**************************************************************************

D9CD	LDA #&40    ;set NMI first instruction to RTI
D9CF	STA &0D00   ;NMI ram start

D9D2	SEI         ;disable interrupts just in case
D9D3	CLD         ;clear decimal flag
D9D4	LDX #&FF    ;reset stack to where it should be
D9D6	TXS         ;(&1FF)
D9D7	LDA &FE4E   ;read interupt enable register of the system VIA
D9DA	ASL         ;shift bit 7 into carry
D9DB	PHA         ;save what's left
D9DC	BEQ &D9E7   ;if Power up A=0 so D9E7
D9DE	LDA &0258   ;else if BREAK pressed read BREAK Action flags (set by
		    ;*FX200,n)
D9E1	LSR         ;divide by 2
D9E2	CMP #&01    ;if (bit 1 not set by *FX200)
D9E4	BNE &DA03   ;then &DA03
D9E6	LSR         ;divide A by 2 again (A=0 if *FX200,2/3 else A=n/4

********** clear memory routine ******************************************

D9E7	LDX #&04    ;get page to start clearance from (4)
D9E9	STX &01     ;store it in ZP 01
D9EB	STA &00     ;store A at 00

D9ED	TAY         ;and in Y to set loop counter
   	
D9EE	STA (&00),Y ;clear store
D9F0	CMP &01     ;until address &01 =0
D9F2	BEQ &D9FD   ;
D9F4	INY         ;increment pointer
D9F5	BNE &D9EE   ;if not zero loop round again
D9F7	INY         ;else increment again (Y=1) this avoids overwriting
   		    ;RTI instruction at &D00
D9F8	INX         ;increment X
D9F9	INC &01     ;increment &01
D9FB	BPL &D9EE   ;loop until A=&80 then exit
   		    ;note that RAM addressing for 16k loops around so
   		    ;&4000=&00 hence checking &01 for 00.  This avoids
   		    ;overwriting zero page on BREAK


D9FD	STX &028E   ;writes marker for available RAM 40 =16k,80=32
DA00	STX &0284   ;write soft key consistency flag

**+********** set up system VIA *****************************************

DA03	LDX #&0F    ;set PORT B to output on bits 0-3 Input 4-7
DA05	STX &FE42   ;



*************************************************************************
*                                                                       *
*        set addressable latch IC 32 for peripherals via PORT B         *
*                                                                       *
*       ;bit 3 set sets addressed latch high adds 8 to VIA address      *
*       ;bit 3 reset sets addressed latch low                           *
*                                                                       *
*       Peripheral              VIA bit 3=0             VIA bit 3=1     *
*                                                                       *
*       Sound chip              Enabled                 Disabled        *
*       speech chip (RS)        Low                     High            *
*       speech chip (WS)        Low                     High            *
*       Keyboard Auto Scan      Disabled                Enabled         *
*       C0 address modifier     Low                     High            *
*       C1 address modifier     Low                     High            *
*       Caps lock  LED          ON                      OFF             *
*       Shift lock LED          ON                      OFF             *
*                                                                       *
*       C0 & C1 are involved with hardware scroll screen address        *
*************************************************************************

   	;X=&F on entry

DA08	DEX         ;loop start
DA09	STX &FE40   ;write latch IC32
DA0C	CPX #&09    ;is it 9
DA0E	BCS &DA08   ;if so go back and do it again
   		    ;X=8 at this point
   		    ;Caps lock On, SHIFT lock undetermined
   		    ;Keyboard Autoscan on
   		    ;sound disabled (may still sound)
DA10	INX         ;X=9
DA11	TXA         ;A=X
DA12	JSR &F02A   ;interrogate keyboard
DA15	CPX #&80    ;for keyboard links 9-2 and CTRL key (1)
DA17	ROR &FC     ;rotate MSB into bit 7 of &FC






DA19	TAX         ;get back value of X for loop
DA1A	DEX         ;decrement it
DA1B	BNE &DA11   ;and if >0 do loop again
   		    ; on exit if Carry set link 3 made
   		    ;link 2 = bit 0 of &FC and so on
   		    ;if CTRL pressed bit 7 of &FC=1
   		    ;X=0
DA1D	STX &028D   ;clear last BREAK flag
DA20	ROL &FC     ;CTRL is now in carry &FC is keyboard links
DA22	JSR &EEEB   ;set LEDs carry on entry  bit 7 of A on exit
DA25	ROR         ;get carry back into carry flag

****** set up page 2 ****************************************************

DA26	LDX #&9C    ;
DA28	LDY #&8D    ;
DA2A	PLA         ;get back A from &D9DB
DA2B	BEQ &DA36   ;if A=0 power up reset so DA36 with X=&9C Y=&8D
DA2D	LDY #&7E    ;else Y=&7E
DA2F	BCC &DA42   ;and if not CTRL-BREAK DA42 WARM RESET
DA31	LDY #&87    ;else Y=&87 COLD RESET
DA33	INC &028D   ;&28D=1

DA36	INC &028D   ;&28D=&28D+1
DA39	LDA &FC     ;get keyboard links set
DA3B	EOR #&FF    ;invert
DA3D	STA &028F   ;and store at &28F
DA40	LDX #&90    ;X=&90



**********: set up page 2 *************************************************

   	;on entry    &28D=0 Warm reset, X=&9C, Y=&7E
   		    ;&28D=1 Power up  , X=&90, Y=&8D
   		    ;&28D=2 Cold reset, X=&9C, Y=&87

DA42	LDA #&00    ;A=0
DA44	CPX #&CE    ;zero &200+X to &2CD
DA46	BCC &DA4A   ;
DA48	LDA #&FF    ;then set &2CE to &2FF to &FF
DA4A	STA &0200,X ;
DA4D	INX         ;
DA4E	BNE &DA44   ;
   		    ;A=&FF X=0
DA50	STA &FE63   ;set port A of user via to all outputs (printer out)

DA53	TXA         ;A=0
DA54	LDX #&E2    ;X=&E2
DA56	STA &00,X   ;zero zeropage &E2 to &FF
DA58	INX         ;
DA59	BNE &DA56   ;X=0

DA5B	LDA &D93F,Y ;copy data from &D93F+Y
DA5E	STA &01FF,Y ;to &1FF+Y
DA61	DEY         ;until
DA62	BNE &DA5B   ;1FF+Y=&200

DA64	LDA #&62    ;A=&62
DA66	STA &ED     ;store in &ED
DA68	JSR &FB0A   ;set up ACIA
   		    ;X=0
************** clear interrupt and enable registers of Both VIAs ********

DA6B	LDA #&7F    ;
DA6D	INX         ;
DA6E	STA &FE4D,X ;
DA71	STA &FE6D,X ;
DA74	DEX         ;
DA75	BPL &DA6E   ;

DA77	CLI         ;briefly allow interrupts to clear anything pending
DA78	SEI         ;disallow again N.B. All VIA IRQs are disabled
DA79	BIT &FC     ;if bit 6=1 then JSR &F055 (normally 0)
DA7B	BVC &DA80   ;else DA80
DA7D	JSR &F055   ;F055 JMP (&FDFE) probably causes a BRK unless
   		    ;hardware there redirects it.
   		    ;
DA80	LDX #&F2    ;enable interrupts 1,4,5,6 of system VIA
DA82	STX &FE4E   ;
   		    ;0      Keyboard enabled as needed
   		    ;1      Frame sync pulse
   		    ;4      End of A/D conversion
   		    ;5      T2 counter (for speech)
   		    ;6      T1 counter (10 mSec intervals)
   		    ;
DA85	LDX #&04    ;set system VIA PCR
DA87	STX &FE4C   ;
   		    ;CA1 to interrupt on negative edge (Frame sync)
   		    ;CA2 Handshake output for Keyboard
   		    ;CB1 interrupt on negative edge (end of conversion)
   		    ;CB2 Negative edge (Light pen strobe)
   		    ;
DA8A	LDA #&60    ;set system VIA ACR
DA8C	STA &FE4B   ;
   		    ;disable latching
   		    ;disable shift register
   		    ;T1 counter continuous interrupts
   		    ;T2 counter timed interrupt

DA8F	LDA #&0E    ;set system VIA T1 counter (Low)
DA91	STA &FE46   ;
   		    ;this becomes effective when T1 hi set

DA94	STA &FE6C   ;set user VIA PCR
   		    ;CA1 interrupt on -ve edge (Printer Acknowledge)
   		    ;CA2 High output (printer strobe)
   		    ;CB1 Interrupt on -ve edge (user port)
   		    ;CB2 Negative edge (user port)

DA97	STA &FEC0   ;set up A/D converter
   		    ;Bits 0 & 1 determine channel selected
   		    ;Bit 3=0 8 bit conversion bit 3=1 12 bit

DA9A	CMP &FE6C   ;read user VIA IER if = &0E then DAA2 chip present
DA9D	BEQ &DAA2   ;so goto DAA2
DA9F	INC &0277   ;else increment user VIA mask to 0 to bar all
   		    ;user VIA interrupts

DAA2	LDA #&27    ;set T1 (hi) to &27 this sets T1 to &270E (9998 uS)
DAA4	STA &FE47   ;or 10msec, interrupts occur every 10msec therefore
DAA7	STA &FE45   ;

DAAA	JSR &EC60   ;clear the sound channels

DAAD	LDA &0282   ;read serial ULA control register
DAB0	AND #&7F    ;zero bit 7
DAB2	JSR &E6A7   ;and set up serial ULA

DAB5	LDX &0284   ;get soft key status flag
DAB8	BEQ &DABD   ;if 0 (keys OK) then DABD
DABA	JSR &E9C8   ;else reset function keys



*************************************************************************
*                                                                       *
*       Check sideways ROMS and make rom list                           *
*                                                                       *
*************************************************************************
   	
   		    ;X=0
DABD	JSR &DC16   ;set up ROM latch and RAM copy to X
DAC0	LDX #&03    ;set X to point to offset in table
DAC2	LDY &8007   ;get copyright offset from ROM

   		    ; DF0C = ")C(",0
DAC5	LDA &8000,Y ;get first byte
DAC8	CMP &DF0C,X ;compare it with table byte
DACB	BNE &DAFB   ;if not the same then goto DAFB
DACD	INY         ;point to next byte
DACE	DEX         ;(s)
DACF	BPL &DAC5   ;and if still +ve go back to check next byte

   		    ;this point is reached if 5 bytes indicate valid
   		    ;ROM (offset +4 in (C) string)


*************************************************************************
* Check first 1k of each ROM against higher priority Roms to ensure that*
* there are no matches, if a match found ignore lower priority ROM      *
*************************************************************************

DAD1	LDX &F4     ;get RAM copy of ROM No. in X
DAD3	LDY &F4     ;and Y

DAD5	INY         ;increment Y to check
DAD6	CPY #&10    ;if ROM 15 is current ROM
DAD8	BCS &DAFF   ;if equal or more than 16 goto &DAFF
   		    ;to store catalogue byte
DADA	TYA         ;else put Y in A
DADB	EOR #&FF    ;invert it
DADD	STA &FA     ;and store at &FA
DADF	LDA #&7F    ;store &7F at
DAE1	STA &FB     ;&FB to get address &7FFF-Y

DAE3	STY &FE30   ;set new ROM
DAE6	LDA (&FA),Y ;Get byte
DAE8	STX &FE30   ;switch back to previous ROM
DAEB	CMP (&FA),Y ;and compare with previous byte called
DAED	BNE &DAD5   ;if not the same then go back and do it again
   		    ;with next rom up
DAEF	INC &FA     ;else increment &FA to point to new location
DAF1	BNE &DAE3   ;if &FA<>0 then check next byte
DAF3	INC &FB     ;else inc &FB
DAF5	LDA &FB     ;and check that it doesn't exceed
DAF7	CMP #&84    ;&84 (1k checked)
DAF9	BCC &DAE3   ;then check next byte(s)

DAFB	LDX &F4     ;X=(&F4)
DAFD	BPL &DB0C   ;if +ve then &DB0C

DAFF	LDA &8006   ;get rom type
DB02	STA &02A1,X ;store it in catalogue
DB05	AND #&8F    ;check for BASIC (bit 7 not set)
DB07	BNE &DB0C   ;if not BASIC the DB0C
DB09	STX &024B   ;else store X at BASIC pointer


DB0C	INX         ;increment X to point to next ROM
DB0D	CPX #&10    ;is it 15 or less
DB0F	BCC &DABD   ;if so goto &DABD for next ROM

OS SERIES V
GEOFF COX
*************************************************************************
*                                                                       *
*       Check SPEECH System                                             *
*                                                                       *
*************************************************************************

    	            ;X=&10
DB11	BIT &FE40   ;if bit 7 low then we have speech system fitted
DB14	BMI &DB27   ;else goto DB27

DB16	DEC &027B   ;(027B)=&FF to indicate speech present

DB19	LDY #&FF    ;Y=&FF
DB1B	JSR &EE7F   ;initialise speech generator
DB1E	DEX         ;via this
DB1F	BNE &DB19   ;loop
    	            ;X=0
DB21	STX &FE48   ;set T2 timer for speech
DB24	STX &FE49   ;


*********** SCREEN SET UP **********************************************
    	            ;X=0
DB27	LDA &028F   ;get back start up options (mode)
DB2A	JSR &C300   ;then jump to screen initialisation

DB2D	LDY #&CA    ;Y=&CA
DB2F	JSR &E4F1   ;to enter this in keyboard buffer
    	            ;this enables the *KEY 10 facility

********* enter BREAK intercept with Carry Clear ************************

DB32	JSR &EAD9   ;check to see if BOOT address is set up, if so
    	            ;JMP to it

DB35	JSR &F140   ;set up cassette options
DB38	LDA #&81    ;test for tube to FIFO buffer 1
DB3A	STA &FEE0   ;
DB3D	LDA &FEE0   ;
DB40	ROR         ;put bit 0 into carry
DB41	BCC &DB4D   ;if no tube then DB4D
DB43	LDX #&FF    ;else
DB45	JSR &F168   ;issue ROM service call &FF
    	            ;to initialise TUBE system
DB48	BNE &DB4D   ;if not 0 on exit (Tube not initialised) DB4D
DB4A	DEC &027A   ;else set tube flag to show it's active


DB4D	LDY #&0E    ;set current value of PAGE
DB4F	LDX #&01    ;issue claim absolute workspace call
DB51	JSR &F168   ;via F168
DB54	LDX #&02    ;send private workspace claim call
DB56	JSR &F168   ;via F168
DB59	STY &0243   ;set primary OSHWM
DB5C	STY &0244   ;set current OSHWM
DB5F	LDX #&FE    ;issue call for Tube to explode character set etc.
DB61	LDY &027A   ;Y=FF if tube present else Y=0
DB64	JSR &F168   ;and make call via F168

DB67	AND &0267   ;if A=&FE and bit 7 of 0267 is set then continue
DB6A	BPL &DB87   ;else ignore start up message
DB6C	LDY #&02    ;output to screen
DB6E	JSR &DEA9   ;'BBC Computer ' message
DB71	LDA &028D   ;0=warm reset, anything else continue
DB74	BEQ &DB82   ;
DB76	LDY #&16    ;by checking length of RAM
DB78	BIT &028E   ;
DB7B	BMI &DB7F   ;and either
DB7D	LDY #&11    ;
DB7F	JSR &DEA9   ;finishing message with '16k' or '32k'
DB82	LDY #&1B    ;and two newlines
DB84	JSR &DEA9   ;

*********: enter BREAK INTERCEPT ROUTINE WITH CARRY SET (call 1)
DB87	SEC         ;
DB88	JSR &EAD9   ;look for break intercept jump do *TV etc
DB8B	JSR &E9D9   ;set up LEDs in accordance with keyboard status
DB8E	PHP         ;save flags
DB8F	PLA         ;and get back in A
DB90	LSR         ;zero bits 4-7 and bits 0-2 bit 4 which was bit 7
DB91	LSR         ;may be set
DB92	LSR         ;
DB93	LSR         ;
DB94	EOR &028F   ;eor with start-up options which may or may not
DB97	AND #&08    ;invert bit 4
DB99	TAY         ;Y=A
DB9A	LDX #&03    ;make fs initialisation call, passing boot option in Y
DB9C	JSR &F168   ;Eg, RUN, EXEC or LOAD !BOOT file
DB9F	BEQ &DBBE   ;if a ROM accepts this call then DBBE
DBA1	TYA         ;else put Y in A
DBA2	BNE &DBB8   ;if Y<>0 DBB8
DBA4	LDA #&8D    ;else set up standard cassete baud rates
DBA6	JSR &F135   ;via &F135

DBA9	LDX #&D2    ;
DBAB	LDY #&EA    ;
DBAD	DEC &0267   ;decrement ignore start up message flag
DBB0	JSR OSCLI   ;and execute */!BOOT
DBB3	INC &0267   ;restore start up message flag
DBB6	BNE &DBBE   ;if not zero then DBBE

DBB8	LDA #&00    ;else A=0
DBBA	TAX         ;X=0
DBBB	JSR &F137   ;set tape speed

******** Preserve current language on soft RESET ************************

DBBE	LDA &028D   ;get last RESET Type
DBC1	BNE &DBC8   ;if not soft reset DBC8

DBC3	LDX &028C   ;else get current language ROM address
DBC6	BPL &DBE6   ;if +ve (language available) then skip search routine



*************************************************************************
*                                                                       *
*       SEARCH FOR LANGUAGE TO ENTER (Highest priority)                 *
*                                                                       *
*************************************************************************

DBC8	LDX #&0F    ;set pointer to highest available rom

DBCA	LDA &02A1,X ;get rom type from map
DBCD	ROL         ;put hi-bit into carry, bit 6 into bit 7
DBCE	BMI &DBE6   ;if bit 7 set then ROM has a language entry so DBE6

DBD0	DEX         ;else search for language until X=&ff
DBD1	BPL &DBCA   ;


*************** check if tube present ***********************************

DBD3	LDA #&00    ;if bit 7 of tube flag is set BMI succeeds
DBD5	BIT &027A   ;and TUBE is connected else
DBD8	BMI &DC08   ;make error

********* no language error ***********************************************

DBDA	BRK         ;
DBDB	DB  &F9     ;error number
DBDC	DB  'Language?'     ;message
DBE5	BRK         ;


DBE6	CLC         ;


*************************************************************************
*                                                                       *
*       OSBYTE 142 - ENTER LANGUAGE ROM AT &8000                        *
*                                                                       *
*       X=rom number C set if OSBYTE call clear if initialisation       *
*                                                                       *
*************************************************************************

DBE7	PHP         ;save flags
DBE8	STX &028C   ;put X in current ROM page
DBEB	JSR &DC16   ;select that ROM
DBEE	LDA #&80    ;A=128
DBF0	LDY #&08    ;Y=8
DBF2	JSR &DEAB   ;display text string held in ROM at &8008,Y
DBF5	STY &FD     ;save Y on exit (end of language string)
DBF7	JSR OSNEWL  ;two line feeds
DBFA	JSR OSNEWL  ;are output
DBFD	PLP         ;then get back flags
DBFE	LDA #&01    ;A=1 required for language entry
DC00	BIT &027A   ;check if tube exists
DC03	BMI &DC08   ;and goto DC08 if it does
DC05	JMP &8000   ;else enter language at &8000


*************************************************************************
*                                                                       *
*       TUBE FOUND, ENTER TUBE SOFTWARE                                 *
*                                                                       *
*************************************************************************

DC08	JMP &0400   ;enter tube environment


*************************************************************************
*                                                                       *
*       OSRDRM entry point                                              *
*                                                                       *
*       get byte from PHROM or page ROM                                 *
*       Y= rom number, address is in &F6/7                              *
*************************************************************************

DC0B	LDX &F4     ;get current ROM number into X
DC0D	STY &F4     ;store new number in &F4
DC0F	STY &FE30   ;switch in ROM
DC12	LDY #&00    ;get current PHROM address
DC14	LDA (&F6),Y ;and get byte

******** Set up Sideways Rom latch and RAM copy *************************
    	    ;on entry X=ROM number

DC16	STX &F4     ;RAM copy of rom latch
DC18	STX &FE30   ;write to rom latch
DC1B	RTS         ;and return



\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C
new file mode 100644
index 0000000..b319f77
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DC1C
@@ -0,0 +1 @@
+**************************************************************************
**************************************************************************
**                                                                      **
**      MAIN IRQ Entry point                                            **
**                                                                      **
**                                                                      **
**************************************************************************
**************************************************************************
;ON ENTRY STACK contains        STATUS REGISTER,PCH,PCL                 ;

DC1C	STA &FC     ;save A
DC1E	PLA         ;get back status (flags)
DC1F	PHA         ;and save again
DC20	AND #&10    ;check if BRK flag set
DC22	BNE &DC27   ;if so goto DC27
DC24	JMP (&0204) ;else JMP (IRQ1V)


*************************************************************************
*                                                                       *
*               BRK handling routine                                    *
*                                                                       *
*************************************************************************

DC27	TXA         ;save X on stack
DC28	PHA         ;
DC29	TSX         ;get status pointer
DC2A	LDA &0103,X ;get Program Counter lo
DC2D	CLD         ;
DC2E	SEC         ;set carry
DC2F	SBC #&01    ;subtract 2 (1+carry)
DC31	STA &FD     ;and store it in &FD
DC33	LDA &0104,X ;get hi byte
DC36	SBC #&00    ;subtract 1 if necessary
DC38	STA &FE     ;and store in &FE
DC3A	LDA &F4     ;get currently active ROM
DC3C	STA &024A   ;and store it in &24A
DC3F	STX &F0     ;store stack pointer in &F0
DC41	LDX #&06    ;and issue ROM service call 6
DC43	JSR &F168   ;(User BRK) to roms
    	            ;at this point &FD/E point to byte after BRK
    	            ;ROMS may use BRK for their own purposes

DC46	LDX &028C   ;get current language
DC49	JSR &DC16   ;and activate it
DC4C	PLA         ;get back original value of X
DC4D	TAX         ;
DC4E	LDA &FC     ;get back original value of A
DC50	CLI         ;allow interrupts
DC51	JMP (&0202) ;and JUMP via BRKV (normally into current language)



*************************************************************************
*                                                                       *
*       DEFAULT BRK HANDLER                                             *
*                                                                       *
*************************************************************************

DC54	LDY #&00    ;Y=0 to point to byte after BRK
DC56	JSR &DEB1   ;print message

DC59	LDA &0267   ;if BIT 0 set and DISC EXEC error
DC5C	ROR         ;occurs
DC5D	BCS &DC5D   ;hang up machine!!!!

DC5F	JSR OSNEWL  ;else print two newlines
DC62	JSR OSNEWL  ;
DC65	JMP &DBB8   ;and set tape speed before entering current
    	            ;language

; ACIA IRQ, RxRDY but both Serial and Printer buffers empty
; ---------------------------------------------------------
DC68	SEC
DC69	ROR &024F   ; Set b7 of RS423 busy flag
DC6C	BIT &0250   ;check bit 7 of current ACIA control register
DC6F	BPL &DC78   ;if interrupts NOT enabled DC78
DC71	JSR &E741   ;else E741 to check if serial buffer full
DC74	LDX #&00    ; X=&00 to set RTS low
DC76	BCS &DC7A   ;if carry set goto DC7A to transfer data

DC78	LDX #&40    ; X=&40 to set RTS high
DC7A	JMP &E17A   ; Jump to set ACIA control register

; Serial IRQ and RxRDY - Get byte and store in serial buffer
; ----------------------------------------------------------
DC7D	LDY &FE09   ; Read data from ACIA
DC80	AND #&3A    ; Check PE:RO:FE:DCD
DC82	BNE &DCB8   ; If any set, jump to generate Serial Error Event

; Serial IRQ and RxRDY, no errors
; -------------------------------
DC84	LDX &025C   ; Read RS423 input suppression flag
DC87	BNE &DC92   ; If not 0, jump to ignore
DC89	INX         ; X=1, serial input buffer
DC8A	JSR &E4F3   ; Put byte in buffer
DC8D	JSR &E741   ; Check if serial buffer almost full
DC90	BCC &DC78   ; If almost full, jump to set RTS high
DC92	RTS         ; Return


*************************************************************************
*                                                                       *
*       Main IRQ Handling routines, default IRQ1V destination           *
*                                                                       *
*************************************************************************

DC93	CLD         ; Clear decimal flag
DC94	LDA &FC     ; Get original value of A
DC96	PHA         ; Save it
DC97	TXA         ; Save X
DC98	PHA         ;
DC99	TYA         ; and Y
DC9A	PHA         ;
DC9B	LDA #&DE    ; Stack return address to &DE82
DC9D	PHA
DC9E	LDA #&81
DCA0	PHA
DCA1	CLV         ; Clear V flag
DCA2	LDA &FE08   ; Read ACIA status register
DCA5	BVS &DCA9   ; b6 set, jump with serial parity error
DCA7	BPL &DD06   ; b7=0, no ACIA interrupt, jump to check VIAs

; ACIA Interrupt or ACIA Parity Error
; -----------------------------------
DCA9	LDX &EA     ; Get RS423 timeout counter
DCAB	DEX         ; Decrement it
DCAC	BMI &DCDE   ; If 0 or <0, RS423 owns 6850, jump to DCDE
DCAE	BVS &DCDD   ; If &41..&80, nobody owns 6850, jump to exit
DCB0	JMP &F588   ; CFS owns 6850, jump to read ACIA in CFS routines

; ACIA Data Carrier Detect
; ------------------------
DCB3	LDY &FE09   ; Read ACIA data
DCB6	ROL A       ;
DCB7	ASL A       ; Rotate ACIA Status back
DCB8	TAX         ; X=ACIA Status
DCB9	TYA         ; A=ACIA Data
DCBA	LDY #&07    ; Y=07 for RS423 Error Event
DCBC	JMP &E494   ; Jump to issue event

; ACIA IRQ, TxRDY - Send a byte
; -----------------------------
DCBF	LDX #&02
DCC1	JSR &E460   ; Read from Serial output buffer
DCC4	BCC &DCD6   ; Buffer is not empty, jump to send byte
DCC6	LDA &0285   ; Read printer destination
DCC9	CMP #&02    ; Is it serial printer??
DCCB	BNE &DC68   ; Serial buffer empty, not Serial printer, jump to ... DC68
DCCD	INX         ; X=3 for Printer buffer
DCCE	JSR &E460   ; Read from Printer buffer
DCD1	ROR &02D2   ; Copy Byte Fetched/Not fetched into Printer Buffer full flag
DCD4	BMI &DC68   ; Printer buffer was empty, so jump to ... DC68

DCD6	STA &FE09   ; Send byte to ACIA
DCD9	LDA #&E7    ; Set timeout counter to &E7
DCDB	STA &EA     ; Serial owns 6850 for 103 more calls
DCDD	RTS         ; Exit IRQ

; RS423 owns 6850, PE or RxRDY interupt occured
; ---------------------------------------------
; On entry, A contains ACIA status
;
DCDE	AND &0278   ; AND with ACIA IRQ mask (normally &FF)
DCE1	LSR A       ; Move RxRDY into Carry
DCE2	BCC &DCEB   ; If no RxData, jump to check DCD and TxRDY
;
; Data in RxData, check for errors
;
DCE4	BVS &DCEB   ; If IRQ=1 (now in b6) RxIRQ must have occured, so jump to DCEB
;
; RxData but no RxIRQ, check that IRQs are actually disabled
;
DCE6	LDY &0250   ; Get ACIA control setting
DCE9	BMI &DC7D   ; If bit 7=1, IRQs enabled so jump to read byte and insert into buffer
;
; DCE9 -> RxData, no RxIRQ, IRQs disabled
; DCE4 -> RxData and RxIRQ
; DCE2 -> No RxData
;
; Check TxRDY and DCD, if neither set, send a Serial Error Event
; --------------------------------------------------------------
DCEB	LSR A       ; Move TxRDY into Carry
DCEC	ROR A       ; Rotate TxRDY into b7 and DCD into Carry
DCED	BCS &DCB3   ; If Data Carrier Detected, jump to DCB3
DCEF	BMI &DCBF   ; If TxRDY (now in b7) jump to to DCBF to send a byte
DCF1	BVS &DCDD   ; b6 should always be zero by now, but if set, then jump to exit

; Issue Unknown Interupt service call
; ===================================
DCF3	LDX #&05
DCF5	JSR &F168   ; Issue service call 5, 'Unknown Interrupt'
DCF8	BEQ &DCDD   ; If claimed, then jump to exit
DCFA	PLA         ; Otherwise drop return address from stack
DCFB	PLA         ;
DCFC	PLA         ; And restore registers
DCFD	TAY         ;
DCFE	PLA         ;
DCFF	TAX         ;
DD00	PLA         ;
DD01	STA &FC     ; Store A in IRQA
DD03	JMP (&0206) ; And pass the IRQ in to IRQ2V



*************************************************************************
*                                                                       *
* VIA INTERUPTS ROUTINES                                                *
*                                                                       *
*************************************************************************

DD06	LDA &FE4D   ; Read System VIA interrupt flag register
DD09	BPL &DD47   ; No System VIA interrupt, jump to check User VIA

; System VIA interupt
;
DD0B	AND &0279   ; Mask with System VIA bit mask
DD0E	AND &FE4E   ; and interrupt enable register
DD11	ROR         ; Rotate to check for CA1 interupt (frame sync)
DD12	ROR         ;
DD13	BCC &DD69   ; No CA1 (frame sync), jump to check speech

; System VIA CA1 interupt (Frame Sync)
;
DD15	DEC &0240   ;decrement vertical sync counter
DD18	LDA &EA     ;A=RS423 Timeout counter
DD1A	BPL &DD1E   ;if +ve then DD1E
DD1C	INC &EA     ;else increment it
DD1E	LDA &0251   ;load flash counter
DD21	BEQ &DD3D   ;if 0 then system is not in use, ignore it
DD23	DEC &0251   ;else decrement counter
DD26	BNE &DD3D   ;and if not 0 go on past reset routine

DD28	LDX &0252   ;else get mark period count in X
DD2B	LDA &0248   ;current VIDEO ULA control setting in A
DD2E	LSR         ;shift bit 0 into C to check if first colour
DD2F	BCC &DD34   ;is effective if so C=0 jump to DD34

DD31	LDX &0253   ;else get space period count in X
DD34	ROL         ;restore bit
DD35	EOR #&01    ;and invert it
DD37	JSR &EA00   ;then change colour

DD3A	STX &0251   ;&0251=X resetting the counter

DD3D	LDY #&04    ;Y=4 and call E494 to check and implement vertical
DD3F	JSR &E494   ;sync event (4) if necessary
DD42	LDA #&02    ;A=2
DD44	JMP &DE6E   ;clear interrupt 1 and exit


*************************************************************************
*                                                                       *
*       PRINTER INTERRUPT USER VIA 1                                    *
*                                                                       *
*************************************************************************

DD47	LDA &FE6D   ; Read User VIA interrupt flag register
DD4A	BPL &DCF3   ; No User VIA interrupt, jump to pass to ROMs

; User VIA interupt
;
DD4C	AND &0277   ;else check for USER IRQ 1
DD4F	AND &FE6E   ;
DD52	ROR         ;
DD53	ROR         ;
DD54	BCC &DCF3   ;if bit 1=0 the no interrupt 1 so DCF3
DD56	LDY &0285   ;else get printer type
DD59	DEY         ;decrement
DD5A	BNE &DCF3   ;if not parallel then DCF3
DD5C	LDA #&02    ;reset interrupt 1 flag
DD5E	STA &FE6D   ;
DD61	STA &FE6E   ;disable interrupt 1
DD64	LDX #&03    ;and output data to parallel printer
DD66	JMP &E13A   ;


*************************************************************************
*                                                                       *
*       SYSTEM INTERRUPT 5   Speech                                     *
*                                                                       *
*************************************************************************

DD69	ROL         ; Rotate bit 5 into bit 7
DD6A	ROL         ;
DD6B	ROL         ;
DD6C	ROL         ;
DD6D	BPL &DDCA   ; Not a Timer 2 interrupt, jump to check timers

; System VIA Timer 2 interupt - Speech interupt
;
DD6F	LDA #&20    ; Prepare to clear VIA interupt
DD71	LDX #&00
DD73	STA &FE4D   ; Clear VIA interupt
DD76	STX &FE49   ; Zero high byte of T2 Timer
DD79	LDX #&08    ; X=8 for Speech buffer
DD7B	STX &FB     ; Prepare to loop up to four times for Speak from RAM

;
DD7D	JSR &E45B   ; Examine Speech buffer
DD80	ROR &02D7   ; Shift carry into bit 7
DD83	BMI &DDC9   ; Buffer empty, so exit
DD85	TAY         ; Buffer not empty, A=first byte waiting
DD86	BEQ &DD8D   ; Waiting byte=&00 (Speak, no reset), skip past
DD88	JSR &EE6D   ;control speech chip
DD8B	BMI &DDC9   ;if negative exit

DD8D	JSR &E460   ; Fetch Speech command byte from buffer
DD90	STA &F5     ; Store it
DD92	JSR &E460   ; Fetch Speech word high byte from buffer
DD95	STA &F7     ; Store it
DD97	JSR &E460   ; Fetch Speech word low byte from buffer
DD9A	STA &F6     ; Store it, giving &F6/7=address to be accessed
DD9C	LDY &F5     ; Y=Speech command byte
DD9E	BEQ &DDBB   ; SOUND &FF00 - Speak from RAM, no reset
DDA0	BPL &DDB8   ; SOUND &FF01-&FF7F - Speak from RAM, with reset
DDA2	BIT &F5     ; Check bit 6 of Speech command
DDA4	BVS &DDAB   ; SOUND &FFC0-&FFFF - Speak word number

; SOUND &FF80-&FFBF - Speak from absolute address
; &F5=command &80-&BF (b0-b3=PHROM number), &F6/7=address
;
DDA6	JSR &EEBB   ; Write address to speech processor
DDA9	BVC &DDB2   ; Skip forward to speak from selected address

; SOUND &FFC0-&FFFF - Speak word number
; &F5=command &C0-&FF (b0-b3=PHROM number), &F6/7=word number
;
DDAB	ASL &F6     ; Multiply address by 2 to index into word table
DDAD	ROL &F7     ;
DDAF	JSR &EE3B   ; Read address from specified PHROM

; Speak from PHROM address
; By now, the address in the PHROM specified in Command b0-b3 has been set
; to the start of the speech data to be voiced.
;
DDB2	LDY &0261   ; Fetch command code, usually &50=Speak or &00=Nop
DDB5	JMP &EE7F   ; Jump to send command to speak from current address

; SOUND &FF01-&FF7F - Speak from RAM with reset
; Y=Speech command byte, &F6/7=Speech data
; Use SOUND &FF60 to send Speak External command
;
DDB8	JSR &EE7F   ; Send command byte to Speech processor

; SOUND &FF00 - Speak from RAM without reset
; &6/7=Speech data
;
DDBB	LDY &F6
DDBD	JSR &EE7F   ; Send Speech data low byte
DDC0	LDY &F7
DDC2	JSR &EE7F   ; Send Speech data high byte
DDC5	LSR &FB     ; Shift loop counter
DDC7	BNE &DD7D   ; Loop to send up to four byte-pairs
DDC9	RTS

***********************************************************************
*                                                                       *
*       SYSTEM INTERRUPT 6 10mS Clock                                   *
*                                                                       *
*************************************************************************

DDCA	BCC &DE47   ;bit 6 is in carry so if clear there is no 6 int
    	            ;so go on to DE47
DDCC	LDA #&40    ;Clear interrupt 6
DDCE	STA &FE4D   ;

;UPDATE timers routine, There are 2 timer stores &292-6 and &297-B
;these are updated by adding 1 to the current timer and storing the
;result in the other, the direction of transfer being changed each
;time of update.  This ensures that at least 1 timer is valid at any call
;as the current timer is only read.  Other methods would cause inaccuracies
;if a timer was read whilst being updated.

DDD1	LDA &0283   ;get current system clock store pointer (5,or 10)
DDD4	TAX         ;put A in X
DDD5	EOR #&0F    ;and invert lo nybble (5 becomes 10 and vv)
DDD7	PHA         ;store A
DDD8	TAY         ;put A in Y

    	            ;Carry is always set at this point
DDD9	LDA &0291,X ;get timer value
DDDC	ADC #&00    ;update it
DDDE	STA &0291,Y ;store result in alternate
DDE1	DEX         ;decrement X
DDE2	BEQ &DDE7   ;if 0 exit
DDE4	DEY         ;else decrement Y
DDE5	BNE &DDD9   ;and go back and do next byte

DDE7	PLA         ;get back A
DDE8	STA &0283   ;and store back in clock pointer (i.e. inverse previous
    	            ;contents)
DDEB	LDX #&05    ;set loop pointer for countdown timer
DDED	INC &029B,X ;increment byte and if
DDF0	BNE &DDFA   ;not 0 then DDFA
DDF2	DEX         ;else decrement pointer
DDF3	BNE &DDED   ;and if not 0 do it again
DDF5	LDY #&05    ;process EVENT 5 interval timer
DDF7	JSR &E494   ;

DDFA	LDA &02B1   ;get byte of inkey countdown timer
DDFD	BNE &DE07   ;if not 0 then DE07
DDFF	LDA &02B2   ;else get next byte
DE02	BEQ &DE0A   ;if 0 DE0A
DE04	DEC &02B2   ;decrement 2B2
DE07	DEC &02B1   ;and 2B1

DE0A	BIT &02CE   ;read bit 7 of envelope processing byte
DE0D	BPL &DE1A   ;if 0 then DE1A
DE0F	INC &02CE   ;else increment to 0
DE12	CLI         ;allow interrupts
DE13	JSR &EB47   ;and do routine sound processes
DE16	SEI         ;bar interrupts
DE17	DEC &02CE   ;DEC envelope processing byte back to 0

DE1A	BIT &02D7   ;read speech buffer busy flag
DE1D	BMI &DE2B   ;if set speech buffer is empty, skip routine
DE1F	JSR &EE6D   ;update speech system variables
DE22	EOR #&A0    ;
DE24	CMP #&60    ;
DE26	BCC &DE2B   ;if result >=&60 DE2B
DE28	JSR &DD79   ;else more speech work

DE2B	BIT &D9B7   ;set V and C
DE2E	JSR &DCA2   ;check if ACIA needs attention
DE31	LDA &EC     ;check if key has been pressed
DE33	ORA &ED     ;
DE35	AND &0242   ;(this is 0 if keyboard is to be ignored, else &FF)
DE38	BEQ &DE3E   ;if 0 ignore keyboard
DE3A	SEC         ;else set carry
DE3B	JSR &F065   ;and call keyboard
DE3E	JSR &E19B   ;check for data in user defined printer channel
DE41	BIT &FEC0   ;if ADC bit 6 is set ADC is not busy
DE44	BVS &DE4A   ;so DE4A
DE46	RTS         ;else return
    	            ;


*************************************************************************
*                                                                       *
*       SYSTEM INTERRUPT 4 ADC end of conversion                        *
*                                                                       *
*************************************************************************


DE47	ROL         ;put original bit 4 from FE4D into bit 7 of A
DE48	BPL &DE72   ;if not set DE72

DE4A	LDX &024C   ;else get current ADC channel
DE4D	BEQ &DE6C   ;if 0 DE6C
DE4F	LDA &FEC2   ;read low data byte
DE52	STA &02B5,X ;store it in &2B6,7,8 or 9
DE55	LDA &FEC1   ;get high data byte
DE58	STA &02B9,X ;and store it in hi byte
DE5B	STX &02BE   ;store in Analogue system flag marking last channel
DE5E	LDY #&03    ;handle event 3 conversion complete
DE60	JSR &E494   ;

DE63	DEX         ;decrement X
DE64	BNE &DE69   ;if X=0
DE66	LDX &024D   ;get highest ADC channel preseny
DE69	JSR &DE8F   ;and start new conversion
DE6C	LDA #&10    ;reset interrupt 4
DE6E	STA &FE4D   ;
DE71	RTS         ;and return


*************************************************************************
*                                                                       *
*       SYSTEM INTERRUPT 0 Keyboard                                     *
*                                                                       *
*************************************************************************

    	            ;
DE72	ROL         ;get original bit 0 in bit 7 position
DE73	ROL         ;
DE74	ROL         ;
DE75	ROL         ;
DE76	BPL &DE7F   ;if bit 7 clear not a keyboard interrupt
DE78	JSR &F065   ;else scan keyboard
DE7B	LDA #&01    ;A=1
DE7D	BNE &DE6E   ;and off to reset interrupt and exit

DE7F	JMP &DCF3   ;


************** exit routine *********************************************

DE82	PLA         ;restore registers
DE83	TAY         ;
DE84	PLA         ;
DE85	TAX         ;
DE86	PLA         ;
DE87	STA &FC     ;store A


*************************************************************************
*                                                                       *
*       IRQ2V default entry                                             *
*************************************************************************

DE89	LDA &FC     ;get back original value of A
DE8B	RTI         ;and return to calling routine



*************************************************************************
*                                                                       *
*       OSBYTE 17 Start conversion                                      *
*                                                                       *
*************************************************************************

    	            ;
DE8C	STY &02BE   ;set last channel to finish conversion
DE8F	CPX #&05    ;if X<4 then
DE91	BCC &DE95   ;DE95
DE93	LDX #&04    ;else X=4

DE95	STX &024C   ;store it as current ADC channel
DE98	LDY &024E   ;get conversion type
DE9B	DEY         ;decrement
DE9C	TYA         ;A=Y
DE9D	AND #&08    ;and it with 08
DE9F	CLC         ;clear carry
DEA0	ADC &024C   ;add to current ADC
DEA3	SBC #&00    ;-1
DEA5	STA &FEC0   ;store to the A/D control panel
DEA8	RTS         ;and return
    	            ;

DEA9	LDA #&C3    ;point to start of string @&C300
DEAB	STA &FE     ;store it
DEAD	LDA #&00    ;point to lo byte
DEAF	STA &FD     ;store it and start loop@

DEB1	INY         ;print character in string
DEB2	LDA (&FD),Y ;pointed to by &FD/E
DEB4	JSR OSASCI  ;print it expanding Carriage returns
DEB7	TAX         ;store A in X
DEB8	BNE &DEB1   ;and loop again if not =0
DEBA	RTS         ;else exit


*********** OSBYTE 129 TIMED ROUTINE ******************************
;ON ENTRY TIME IS IN X,Y

DEBB	STX &02B1   ;store time in INKEY countdown timer
DEBE	STY &02B2   ;which is decremented every 10ms
DEC1	LDA #&FF    ;A=&FF to flag timed wait
DEC3	BNE &DEC7   ;goto DEC7



**************************************************************************
**************************************************************************
**                                                                      **
**      OSRDCH Default entry point                                      **
**                                                                      **
**      RDCHV entry point       read a character                        **
**                                                                      **
**************************************************************************
**************************************************************************

DEC5	LDA #&00    ;A=0 to flag wait forever

DEC7	STA &E6     ;store entry value of A
DEC9	TXA         ;save X and Y
DECA	PHA         ;
DECB	TYA         ;
DECC	PHA         ;
DECD	LDY &0256   ;get *EXEC file handle
DED0	BEQ &DEE6   ;if 0 (not open) then DEE6
DED2	SEC         ;set carry
DED3	ROR &EB     ;set bit 7 of CFS active flag to prevent clashes
DED5	JSR OSBGET  ;get a byte from the file
DED8	PHP         ;push processor flags to preserve carry
DED9	LSR &EB     ;restore &EB
DEDB	PLP         ;get back flags
DEDC	BCC &DF03   ;and if carry clear, character found so exit via DF03
DEDE	LDA #&00    ;else A=00 as EXEC file empty
DEE0	STA &0256   ;store it in exec file handle
DEE3	JSR OSFIND  ;and close file via OSFIND

DEE6	BIT &FF     ;check ESCAPE flag, if bit 7 set Escape pressed
DEE8	BMI &DF00   ;so off to DF00
DEEA	LDX &0241   ;else get current input buffer number
DEED	JSR &E577   ;get a byte from input buffer
DEF0	BCC &DF03   ;and exit if character returned

DEF2	BIT &E6     ;(E6=0 or FF)
DEF4	BVC &DEE6   ;if entry was OSRDCH not timed keypress, so go back and
    	            ;do it again i.e. perform GET function
DEF6	LDA &02B1   ;else check timers
DEF9	ORA &02B2   ;
DEFC	BNE &DEE6   ;and if not zero go round again
DEFE	BCS &DF05   ;else exit

DEF0             ..   BCC &DF03
DEF2             $�   BIT &E6
DEF4             P�   BVC &DEE6
DEF6             ��.  LDA &02B1
DEF9             .�.  ORA &02B2
DEFC             ��   BNE &DEE6
DEFE             �.   BCS &DF05
DF00             8    SEC
DF01             �.   LDA #&1B
DF03             .�   STA &E6
DF05             h    PLA
DF06             �    TAY
DF07             h    PLA
DF08             �    TAX
DF09             ��   LDA &E6
DF0B             `    RTS

\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DF0C b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DF0C
new file mode 100644
index 0000000..b273fa3
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/DF0C
@@ -0,0 +1,512 @@
+**** STRINGS ****
+
+DF0C	DB ')C)',0      ; Copyright string match
+
+**** COMMMANDS ****
+;				  Command   Address       Call goes to
+DF10	DB '.',E0,31,05		; *.       &E031, A=5     FSCV, XY=>String
+DF14	DB 'FX',E3,42,FF	; *FX      &E342, A=&FF   Number paramters
+DF19	DB 'BASIC',E0,18,00	; *BASIC   &E018, A=0     XY=>String
+DF21	DB 'CAT',E0,31,05	; *CAT     &E031, A=5     FSCV, XY=>String
+DF27	DB 'CODE',E3,48,88	; *CODE    &E348, A=&88   OSBYTE &88
+DF2E	DB 'EXEC',F6,8D,00	; *EXEC    &F68D, A=0     XY=>String
+DF35	DB 'HELP',F0,B9,FF	; *HELP    &F0B9, A=&FF   F2/3=>String
+DF3C	DB 'KEY',E3,27,FF	; *KEY     &E327, A=&FF   F2/3=>String
+DF42	DB 'LOAD',E2,3C,00	; *LOAD    &E23C, A=0     XY=>String
+DF49	DB 'LINE',E6,59,01	; *LINE    &E659, A=1     USERV, XY=>String
+DF50	DB 'MOTOR',E3,48,89	; *MOTOR   &E348, A=&89   OSBYTE
+DF58	DB 'OPT',E3,48,8B	; *OPT     &E348, A=&8B   OSBYTE
+DF5E	DB 'RUN',E0,31,04	; *RUN     &E031, A=4     FSCV, XY=>String
+DF64	DB 'ROM',E3,48,8D	; *ROM     &E348, A=&8D   OSBYTE
+DF6A	DB 'SAVE',E2,3E,00	; *SAVE    &E23E, A=0     XY=>String
+DF70	DB 'SPOOL',E2,81,00	; *SPOOL   &E281, A=0     XY=>String
+DF79	DB 'TAPE',E3,48,8C	; *TAPE    &E348, A=&8C   OSBYTE
+DF80	DB 'TV',E3,48,90	; *TV      &E348, A=&90   OSBYTE
+DF85	DB E0			; Table end marker
+
+; Command routines are entered with XY=>command tail, A=table parameter,
+; &F2/3,&E6=>start of command string
+; If table parameter if <&80, F2/3,Y converted to XY before entering
+
+
+DF86 31 03       1.   AND (&03),Y
+DF88 00          .    BRK
+
+*************************************************************************
+*                                                                       *
+*   CLI - COMMAND LINE INTERPRETER                                      *
+*                                                                       *
+*   ENTRY: XY=>Command line                                             *
+*   EXIT:  All registers corrupted                                      *
+*   [ A=13 - unterminated string ]
+*************************************************************************
+;
+DF89	STX &F2		; Store XY in &F2/3
+DF8B	STY &F3
+DF8D	LDA #&08
+DF8F	JSR &E031	; Inform filing system CLI being processed
+DF92	LDY #&00	; Check the line is correctly terminated
+DF94	LDA (&F2),Y
+DF96	CMP #&0D	; Loop until CR is found
+DF98	BEQ &DF9E
+DF9A	INY		; Move to next character
+DF9B	BNE &DF94	; Loop back if less than 256 bytes long
+DF9D	RTS		; Exit if string > 255 characters
+
+; String is terminated - skip prepended spaces and '*'s
+DF9E	LDY #&FF
+DFA0	JSR &E039	; Skip any spaces
+DFA3	BEQ &E017	; Exit if at CR
+DFA5	CMP #&2A	; Is this character '*'?
+DFA7	BEQ &DFA0	; Loop back to skip it, and check for spaces again
+
+DFA9	JSR &E03A	; Skip any more spaces
+DFAC	BEQ &E017	; Exit if at CR
+DFAE	CMP #&7C	; Is it '|' - a comment?
+DFB0	BEQ &E017	; Exit if so
+DFB2	CMP #&2F	; Is it '/' - pass straight to filing system?
+DFB4	BNE &DFBE	; Jump forward if not
+DFB6	INY		; Move past the '/'
+DFB7	JSR &E009	; Convert &F2/3,Y->XY, ignore returned A
+DFBA	LDA #&02	; 2=RunSlashCommand
+DFBC	BNE &E031	; Jump to pass to FSCV
+;
+; Look command up in command table
+DFBE 84 E6       .�   STY &E6	; Store offset to start of command
+DFC0 A2 00       �.   LDX #&00
+DFC2 F0 13       �.   BEQ &DFD7
+;
+DFC4 5D 10 DF    ].�  EOR &DF10,X
+DFC7 29 DF       )�   AND #&DF
+DFC9 D0 17       �.   BNE &DFE2
+DFCB C8          �    INY
+DFCC 18          .    CLC
+;
+DFCD B0 25       �%   BCS &DFF4
+DFCF E8          �    INX
+DFD0 B1 F2       ��   LDA (&F2),Y
+DFD2 20 E3 E4     ��  JSR &E4E3
+DFD5 90 ED       .�   BCC &DFC4
+;
+DFD7 BD 10 DF    �.�  LDA &DF10,X
+DFDA 30 16       0.   BMI &DFF2
+DFDC B1 F2       ��   LDA (&F2),Y
+DFDE C9 2E       �.   CMP #&2E
+DFE0 F0 04       �.   BEQ &DFE6
+DFE2 18          .    CLC
+DFE3 A4 E6       ��   LDY &E6
+DFE5 88          .    DEY
+DFE6 C8          �    INY
+DFE7 E8          �    INX
+DFE8 E8          �    INX
+DFE9 BD 0E DF    �.�  LDA &DF0E,X
+DFEC F0 33       �3   BEQ &E021
+DFEE 10 F8       .�   BPL &DFE8
+DFF0 30 DB       0�   BMI &DFCD
+;
+DFF2 E8          �    INX
+DFF3 E8          �    INX
+;
+DFF4 CA          �    DEX
+DFF5 CA          �    DEX
+DFF6 48          H    PHA
+DFF7 BD 11 DF    �.�  LDA &DF11,X
+DFFA 48          H    PHA
+DFFB 20 3A E0     :�  JSR &E03A
+DFFE 18          .    CLC
+DFFF 08          .    PHP
+E000 20 04 E0     .�  JSR &E004
+E003 40          @    RTI	; Jump to routine
+
+E004	LDA &DF12,X	; Get table parameter
+E007	BMI &E017	; If >=&80, number follow
+;                      ; else string follows
+
+E009	TYA		; Pass Y line offset to A for later
+E00A	LDY &DF12,X	; Get looked-up parameter from table
+
+; Convert &F2/3,A to XY, put Y in A
+E00D 18          .    CLC
+E00E 65 F2       e�   ADC &F2
+E010 AA          �    TAX
+E011 98          .    TYA	; Pass supplied Y into A
+E012 A4 F3       ��   LDY &F3
+E014 90 01       ..   BCC &E017
+E016 C8          �    INY
+;
+E017 60          `    RTS
+
+
+; *BASIC
+E018	LDX &024B	; Get Basic rom number
+E01B	BMI &E021       ; If none set, jump to pass command on
+E01D	SEC             ; Set Carry = not entering from RESET
+E01E	JMP &DBE7	; Enter language rom in X
+
+; Pass command on to other roms and to filing system
+E021	LDY &E6		; Restore pointer to start of command
+E023	LDX #&04	; 4=UnknownCommand
+E025	JSR &F168	; Pass to sideways roms
+E028	BEQ &E017	; If claimed, exit
+E02A	LDA &E6		; Restore pointer to start of command
+E02C	JSR &E00D	; Convert &F2/3,A to XY, ignore returned A
+E02F	LDA #&03	; 3=PassCommandToFilingSystem
+
+; Pass to current filing system
+E031	JMP (&021E)
+
+E034 0A          .    ASL A
+E035 29 01       ).   AND #&01
+E037 10 F8       .�   BPL &E031
+
+; Skip spaces
+E039 C8          �    INY
+E03A B1 F2       ��   LDA (&F2),Y
+E03C C9 20       �    CMP #&20
+E03E F0 F9       ��   BEQ &E039
+E040 C9 0D       �.   CMP #&0D
+E042 60          `    RTS
+
+;
+E043 90 F5       .�   BCC &E03A
+E045 20 3A E0     :�  JSR &E03A
+E048 C9 2C       �,   CMP #&2C
+E04A D0 F4       ��   BNE &E040
+E04C C8          �    INY
+E04D 60          `    RTS
+
+;
+E04E 20 3A E0     :�  JSR &E03A
+E051 20 7D E0     }�  JSR &E07D
+E054 90 37       .7   BCC &E08D
+E056 85 E6       .�   STA &E6
+E058 20 7C E0     |�  JSR &E07C
+E05B 90 19       ..   BCC &E076
+E05D AA          �    TAX
+E05E A5 E6       ��   LDA &E6
+E060 0A          .    ASL A
+E061 B0 2A       �*   BCS &E08D
+E063 0A          .    ASL A
+E064 B0 27       �'   BCS &E08D
+E066 65 E6       e�   ADC &E6
+E068 B0 23       �#   BCS &E08D
+E06A 0A          .    ASL A
+E06B B0 20       �    BCS &E08D
+E06D 85 E6       .�   STA &E6
+E06F 8A          .    TXA
+E070 65 E6       e�   ADC &E6
+E072 B0 19       �.   BCS &E08D
+E074 90 E0       .�   BCC &E056
+E076 A6 E6       ��   LDX &E6
+E078 C9 0D       �.   CMP #&0D
+E07A 38          8    SEC
+E07B 60          `    RTS
+
+E07C C8          �    INY
+E07D B1 F2       ��   LDA (&F2),Y
+E07F C9 3A       �:   CMP #&3A
+E081 B0 0A       �.   BCS &E08D
+E083 C9 30       �0   CMP #&30
+E085 90 06       ..   BCC &E08D
+E087 29 0F       ).   AND #&0F
+E089 60          `    RTS
+
+E08A 20 45 E0     E�  JSR &E045
+E08D 18          .    CLC
+E08E 60          `    RTS
+
+E08F 20 7D E0     }�  JSR &E07D
+E092 B0 0E       �.   BCS &E0A2
+E094 29 DF       )�   AND #&DF
+E096 C9 47       �G   CMP #&47
+E098 B0 F0       ��   BCS &E08A
+E09A C9 41       �A   CMP #&41
+E09C 90 EC       .�   BCC &E08A
+E09E 08          .    PHP
+E09F E9 37       �7   SBC #&37
+E0A1 28          (    PLP
+E0A2 C8          �    INY
+E0A3 60          `    RTS
+
+; WRCH control routine
+; ====================
+E0A4 48          H    PHA          ; Save all registers
+E0A5 8A          .    TXA
+E0A6 48          H    PHA
+E0A7 98          .    TYA
+E0A8 48          H    PHA
+E0A9 BA          �    TSX
+E0AA BD 03 01    �..  LDA &0103,X  ; Get A back from stack
+E0AD 48          H    PHA          ; Save A
+E0AE 2C 60 02    ,`.  BIT &0260    ; Check OSWRCH interception flag
+E0B1 10 08       ..   BPL &E0BB    ; Not set, skip interception call
+E0B3 A8          �    TAY          ; Pass character to Y
+E0B4 A9 04       �.   LDA #&04     ; A=4 for OSWRCH call
+E0B6 20 7E E5     ~�  JSR &E57E    ; Call interception code
+E0B9 B0 52       �R   BCS &E10D    ; If claimed, jump past to exit
+
+E0BB 18          .    CLC          ; Prepare to not send this to printer
+E0BC A9 02       �.   LDA #&02     ; Check output destination
+E0BE 2C 7C 02    ,|.  BIT &027C    ; Is VDU driver disabled?
+E0C1 D0 05       �.   BNE &E0C8    ; Yes, skip past VDU driver
+E0C3 68          h    PLA          ; Get character back
+E0C4 48          H    PHA          ; Resave character
+E0C5 20 C0 C4     ��  JSR &C4C0    ; Call VDU driver
+                                   ; On exit, C=1 if character to be sent to printer
+
+E0C8 A9 08       �.   LDA #&08     ; Check output destination
+E0CA 2C 7C 02    ,|.  BIT &027C    ; Is printer seperately enabled?
+E0CD D0 02       �.   BNE &E0D1    ; Yes, jump to call printer driver
+E0CF 90 05       ..   BCC &E0D6    ; Carry clear, don't sent to printer
+E0D1 68          h    PLA          ; Get character back
+E0D2 48          H    PHA          ; Resave character
+E0D3 20 14 E1     .�  JSR &E114    ; Call printer driver
+
+E0D6 AD 7C 02    �|.  LDA &027C    ; Check output destination
+E0D9 6A          j    ROR A        ; Is serial output enabled?
+E0DA 90 1B       ..   BCC &E0F7    ; No, skip past serial output
+E0DC A4 EA       ��   LDY &EA      ; Get serial timout counter
+E0DE 88          .    DEY          ; Decrease counter
+E0DF 10 16       ..   BPL &E0F7    ; Timed out, skip past serial code
+E0E1 68          h    PLA          ; Get character back
+E0E2 48          H    PHA          ; Resace character
+E0E3 08          .    PHP          ; Save IRQs
+E0E4 78          x    SEI          ; Disable IRQs
+E0E5 A2 02       �.   LDX #&02     ; X=2 for serial output buffer
+E0E7 48          H    PHA          ; Save character
+E0E8 20 5B E4     [�  JSR &E45B    ; Examine serial output buffer
+E0EB 90 03       ..   BCC &E0F0    ; Buffer not full, jump to send character
+E0ED 20 70 E1     p�  JSR &E170    ; Wait for buffer to empty a bit
+E0F0 68          h    PLA          ; Get character back
+E0F1 A2 02       �.   LDX #&02     ; X=2 for serial output buffer
+E0F3 20 F8 E1     ��  JSR &E1F8    ; Send character to serial output buffer
+E0F6 28          (    PLP          ; Restore IRQs
+
+E0F7 A9 10       �.   LDA #&10     ; Check output destination
+E0F9 2C 7C 02    ,|.  BIT &027C    ; Is SPOOL output disabled?
+E0FC D0 0F       �.   BNE &E10D    ; Yes, skip past SPOOL output
+E0FE AC 57 02    �W.  LDY &0257    ; Get SPOOL handle
+E101 F0 0A       �.   BEQ &E10D    ; If not open, skip past SPOOL output
+E103 68          h    PLA          ; Get character back
+E104 48          H    PHA          ; Resave character
+E105 38          8    SEC
+E106 66 EB       f�   ROR &EB      ; Set RFS/CFS's 'spooling' flag
+E108 20 D4 FF     �.  JSR &FFD4    ; Write character to SPOOL channel
+E10B 46 EB       F�   LSR &EB      ; Reset RFS/CFS's 'spooling' flag
+
+E10D 68          h    PLA          ; Restore all registers
+E10E 68          h    PLA
+E10F A8          �    TAY
+E110 68          h    PLA
+E111 AA          �    TAX
+E112 68          h    PLA
+E113 60          `    RTS          ; Exit
+
+
+*************************************************************************
+*                                                                       *
+*       PRINTER DRIVER                                                  *
+*                                                                       *
+*************************************************************************
+
+;A=character to print
+
+E114	BIT &027C   ;if bit 6 of VDU byte =1 printer is disabled
+E117	BVS &E139   ;so E139
+
+E119	CMP &0286   ;compare with printer ignore character
+E11C	BEQ &E139   ;if the same E139
+
+E11E	PHP         ;else save flags
+E11F	SEI         ;bar interrupts
+E120	TAX         ;X=A
+E121	LDA #&04    ;A=4
+E123	BIT &027C   ;read bit 2 'disable printer driver'
+E126	BNE &E138   ;if set printer is disabled so exit E138
+E128	TXA         ;else A=X
+E129	LDX #&03    ;X=3
+E12B	JSR &E1F8   ;and put character in printer buffer
+E12E	BCS &E138   ;if carry set on return exit, buffer not full (empty?)
+
+E130	BIT &02D2   ;else check buffer busy flag if 0
+E133	BPL &E138   ;then E138 to exit
+E135	JSR &E13A   ;else E13A to open printer cahnnel
+
+E138	PLP         ;get back flags
+E139	RTS         ;and exit
+
+E13A	LDA &0285   ;check printer destination
+E13D	BEQ &E1AD   ;if 0 then E1AD clear printer buffer and exit
+E13F	CMP #&01    ;if parallel printer not selected
+E141	BNE &E164   ;E164
+E143	JSR &E460   ;else read a byte from the printer buffer
+E146	ROR &02D2   ;if carry is set then 2d2 is -ve
+E149	BMI &E190   ;so return via E190
+E14B	LDY #&82    ;else enable interrupt 1 of the external VIA
+E14D	STY &FE6E   ;
+E150	STA &FE61   ;pass code to centronics port
+E153	LDA &FE6C   ;pulse CA2 line to generate STROBE signal
+E156	AND #&F1    ;to advise printer that
+E158	ORA #&0C    ;valid data is
+E15A	STA &FE6C   ;waiting
+E15D	ORA #&0E    ;
+E15F	STA &FE6C   ;
+E162	BNE &E190   ;then exit
+
+*********:serial printer *********************************************
+
+E164	CMP #&02    ;is it Serial printer??
+E166	BNE &E191   ;if not E191
+E168	LDY &EA     ;else is RS423 in use by cassette??
+E16A	DEY         ;
+E16B	BPL &E1AD   ;if so E1AD to flush buffer
+
+E16D	LSR &02D2   ;else clear buffer busy flag
+E170	LSR &024F   ;and RS423 busy flag
+E173	JSR &E741   ;count buffer if C is clear on return
+E176	BCC &E190   ;no room in buffer so exit
+E178	LDX #&20    ;else
+E17A	LDY #&9F    ;
+
+
+
+
+*************************************************************************
+*                                                                       *
+*       OSBYTE 156 update ACIA setting and RAM copy                     *
+*                                                                       *
+*************************************************************************
+;on entry
+
+E17C	PHP         ;push flags
+E17D	SEI         ;bar interrupts
+E17E	TYA         ;A=Y
+E17F	STX &FA     ;&FA=X
+E181	AND &0250   ;A=old value AND Y EOR X
+E184	EOR &FA     ;
+E186	LDX &0250   ;get old value in X
+E189	STA &0250   ;put new value in
+E18C	STA &FE08   ;and store to ACIA control register
+E18F	PLP         ;get back flags
+E190	RTS         ;and exit
+
+
+
+************ printer is neither serial or parallel so its user type *****
+
+E191	CLC         ;clear carry
+E192	LDA #&01    ;A=1
+E194	JSR &E1A2   ;
+
+
+*************************************************************************
+*                                                                       *
+*       OSBYTE 123 Warn printer driver going dormant                    *
+*                                                                       *
+*************************************************************************
+
+E197	ROR &02D2   ;mark printer buffer empty for osbyte
+E19A	RTS         ;and exit
+
+E19B	BIT &02D2   ;if bit 7 is set buffer is empty
+E19E	BMI &E19A   ;so exit
+
+E1A0	LDA #&00    ;else A=0
+
+E1A2	LDX #&03    ;X=3
+E1A4	LDY &0285   ;Y=printer destination
+E1A7	JSR &E57E   ;to JMP (NETV)
+E1AA	JMP (&0222) ;jump to PRINT VECTOR for special routines
+
+
+*************** Buffer handling *****************************************
+    	            ;X=buffer number
+    	;Buffer number  Address         Flag    Out pointer     In pointer
+    	;0=Keyboard     3E0-3FF         2CF     2D8             2E1
+    	;1=RS423 Input  A00-AFF         2D0     2D9             2E2
+    	;2=RS423 output 900-9BF         2D1     2DA             2E3
+    	;3=printer      880-8BF         2D2     2DB             2E4
+    	;4=sound0       840-84F         2D3     2DC             2E5
+    	;5=sound1       850-85F         2D4     2DD             2E6
+    	;6=sound2       860-86F         2D5     2DE             2E7
+    	;7=sound3       870-87F         2D6     2DF             2E8
+    	;8=speech       8C0-8FF         2D7     2E0             2E9
+
+
+E1AD	CLC         ;clear carry
+E1AE	PHA         ;save A
+E1AF	PHP         ;save flags
+E1B0	SEI         ;set interrupts
+E1B1	BCS &E1BB   ;if carry set on entry then E1BB
+E1B3	LDA &E9AD,X ;else get byte from baud rate/sound data table
+E1B6	BPL &E1BB   ;if +ve the E1BB
+E1B8	JSR &ECA2   ;else clear sound data
+
+E1BB	SEC         ;set carry
+E1BC	ROR &02CF,X ;rotate buffer flag to show buffer empty
+E1BF	CPX #&02    ;if X>1 then its not an input buffer
+E1C1	BCS &E1CB   ;so E1CB
+
+E1C3	LDA #&00    ;else Input buffer so A=0
+E1C5	STA &0268   ;store as length of key string
+E1C8	STA &026A   ;and length of VDU queque
+E1CB	JSR &E73B   ;then enter via count purge vector any user routines
+E1CE	PLP         ;restore flags
+E1CF	PLA         ;restore A
+E1D0	RTS         ;and exit
+
+
+
+*************************************************************************
+*                                                                       *
+*       COUNT PURGE VECTOR      DEFAULT ENTRY                           *
+*                                                                       *
+*                                                                       *
+*************************************************************************
+;on entry if V set clear buffer
+;   	  if C set get space left
+;   	  else get bytes used
+
+E1D1	BVC &E1DA   ;if bit 6 is set then E1DA
+E1D3	LDA &02D8,X ;else start of buffer=end of buffer
+E1D6	STA &02E1,X ;
+E1D9	RTS         ;and exit
+
+E1DA	PHP         ;push flags
+E1DB	SEI         ;bar interrupts
+E1DC	PHP         ;push flags
+E1DD	SEC         ;set carry
+E1DE	LDA &02E1,X ;get end of buffer
+E1E1	SBC &02D8,X ;subtract start of buffer
+E1E4	BCS &E1EA   ;if carry caused E1EA
+E1E6	SEC         ;set carry
+E1E7	SBC &E447,X ;subtract buffer start offset (i.e. add buffer length)
+E1EA	PLP         ;pull flags
+E1EB	BCC &E1F3   ;if carry clear E1F3 to exit
+E1ED	CLC         ;clear carry
+E1EE	ADC &E447,X ;adc to get bytes used
+E1F1	EOR #&FF    ;and invert to get space left
+E1F3	LDY #&00    ;Y=0
+E1F5	TAX         ;X=A
+E1F6	PLP         ;get back flags
+E1F7	RTS         ;and exit
+
+
+
+********** enter byte in buffer, wait and flash lights if full **********
+
+E1F8	SEI         ;prevent interrupts
+E1F9	JSR &E4B0   ;entera byte in buffer X
+E1FC	BCC &E20D   ;if successful exit
+E1FE	JSR &E9EA   ;else switch on both keyboard lights
+E201	PHP         ;push p
+E202	PHA         ;push A
+E203	JSR &EEEB   ;switch off unselected LEDs
+E206	PLA         ;get back A
+E207	PLP         ;and flags
+E208	BMI &E20D   ;if return is -ve Escape pressed so exit
+E20A	CLI         ;else allow interrupts
+E20B	BCS &E1F8   ;if byte didn't enter buffer go and try it again
+E20D	RTS         ;then return
+
+
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E20E b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E20E
new file mode 100644
index 0000000..4f0b4b6
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E20E
@@ -0,0 +1 @@
+OS SERIES VI
GEOFF COX


*************************************************************************
*                                                                       *
*       SAVE/LOAD ENTRY                                                 *
*                                                                       *
*                                                                       *
*************************************************************************


**************: clear osfile control block workspace ********************

E20E	PHA         ;push A
E20F	LDA #&00    ;A=0
E211	STA &02EE,X ;clear osfile control block workspace
E214	STA &02EF,X ;
E217	STA &02F0,X ;
E21A	STA &02F1,X ;
E21D	PLA         ;get back A
E21E	RTS         ;and exit



*********** shift through osfile control block **************************

E21F	STY &E6     ;&E6=Y
E221	ROL         ;A=A*2
E222	ROL         ;*4
E223	ROL         ;*8
E224	ROL         ;*16
E225	LDY #&04    ;Y=4
E227	ROL         ;A=A*32
E228	ROL &02EE,X ;shift bit 7 of A into shift register
E22B	ROL &02EF,X ;and
E22E	ROL &02F0,X ;shift
E231	ROL &02F1,X ;along
E234	BCS &E267   ;if carry set on exit then register has overflowed
    	            ;so bad address error
E236	DEY         ;decrement Y
E237	BNE &E227   ;and if Y>0 then do another shift
E239	LDY &E6     ;get back original Y
E23B	RTS         ;and exit



*************************************************************************
*                                                                       *
*       *LOAD ENTRY                                                     *
*                                                                       *
*                                                                       *
*************************************************************************

E23C	LDA #&FF    ;signal that load is being performed




*************************************************************************
*                                                                       *
*       *SAVE ENTRY                                                     *
*                                                                       *
*                                                                       *
*************************************************************************
;on entry A=0 for save &ff for load

E23E	STX &F2     ;store address of rest of command line
E240	STY &F3     ;
E242	STX &02EE   ;x and Y are stored in OSfile control block
E245	STY &02EF   ;
E248	PHA         ;Push A
E249	LDX #&02    ;X=2
E24B	JSR &E20E   ;clear the shift register
E24E	LDY #&FF    ;Y=255
E250	STY &02F4   ;store im 2F4
E253	INY         ;increment Y
E254	JSR &EA1D   ;and call GSINIT to prepare for reading text line
E257	JSR &EA2F   ;read a code from text line if OK read next
E25A	BCC &E257   ;until end of line reached
E25C	PLA         ;get back A without stack changes
E25D	PHA         ;
E25E	BEQ &E2C2   ;IF A=0 (SAVE)  E2C2
E260	JSR &E2AD   ;set up file block
E263	BCS &E2A0   ;if carry set do OSFILE
E265	BEQ &E2A5   ;else if A=0 goto OSFILE


E267	BRK         ;
E268	DB  &FC     ;
E269	DB  'Bad Address'   ;error
E274	BRK         ;



*************************************************************************
*                                                                       *
*       OSBYTE 119             ENTRY                                    *
*       CLOSE SPOOL/ EXEC FILES                                         *
*                                                                       *
*************************************************************************


E275	LDX #&10    ;X=10 issue *SPOOL/EXEC files warning
E277	JSR &F168   ;and issue call
E27A	BEQ &E29F   ;if a rom accepts and issues a 0 then E29F to return
E27C	JSR &F68B   ;else close the current exec file
E27F	LDA #&00    ;A=0



**************************************************************************
**************************************************************************
**                                                                      **
**                                                                      **
**      *SPOOL                                                          **
**                                                                      **
**************************************************************************
**************************************************************************

E281	PHP         ;if A=0 file is closed so
E282	STY &E6     ;Store Y
E284	LDY &0257   ;get file handle
E287	STA &0257   ;store A as file handle
E28A	BEQ &E28F   ;if Y<>0 then E28F
E28C	JSR OSFIND  ;else close file via osfind
E28F	LDY &E6     ;get back original Y
E291	PLP         ;pull flags
E292	BEQ &E29F   ;if A=0 on entry then exit
E294	LDA #&80    ;else A=&80
E296	JSR OSFIND  ;to open file Y for output
E299	TAY         ;Y=A
E29A	BEQ &E310   ;and if this is =0 then E310 BAD COMMAND ERROR
E29C	STA &0257   ;store file handle
E29F	RTS         ;and exit

E2A0	BNE &E310   ;if NE then BAD COMMAND error
E2A2	INC &02F4   ;increment 2F4 to 00
E2A5	LDX #&EE    ;X=&EE
E2A7	LDY #&02    ;Y=&02
E2A9	PLA         ;get back A
E2AA	JMP OSFILE  ;and JUMP to OSFILE

**** check for hex digit ************************************************

E2AD	JSR &E03A   ;look for NEWline
E2B0	JSR &E08F   ;carry is set if it finds hex digit
E2B3	BCC &E2C1   ;so E2C1 exit
E2B5	JSR &E20E   ;clear shift register


************** shift byte into control block ***************************

E2B8	JSR &E21F   ;shift lower nybble of A into shift register
E2BB	JSR &E08F   ;then check for Hex digit
E2BE	BCS &E2B8   ;if found then do it again
E2C0	SEC         ;else set carry
E2C1	RTS         ;and exit



**************; set up OSfile control block ****************************

E2C2	LDX #&0A    ;X=0A
E2C4	JSR &E2AD   ;
E2C7	BCC &E310   ;if no hex digit found EXIT via BAD Command error
E2C9	CLV         ;clear bit 6


******************READ file length from text line************************

E2CA	LDA (&F2),Y ;read next byte from text line
E2CC	CMP #&2B    ;is it '+'
E2CE	BNE &E2D4   ;if not assume its a last byte address so e2d4
E2D0	BIT &D9B7   ;else set V and M flags
E2D3	INY         ;increment Y to point to hex group

E2D4	LDX #&0E    ;X=E
E2D6	JSR &E2AD   ;
E2D9	BCC &E310   ;if carry clear no hex digit so exit via error
E2DB	PHP         ;save flags
E2DC	BVC &E2ED   ;if V set them E2ED explicit end address found
E2DE	LDX #&FC    ;else X=&FC
E2E0	CLC         ;clear carry
E2E1	LDA &01FC,X ;and add length data to start address
E2E4	ADC &0200,X ;
E2E7	STA &0200,X ;
E2EA	INX         ;
E2EB	BNE &E2E1   ;repeat until X=0

E2ED	LDX #&03    ;X=3
E2EF	LDA &02F8,X ;copy start adddress to load and execution addresses
E2F2	STA &02F4,X ;
E2F5	STA &02F0,X ;
E2F8	DEX ;
E2F9	BPL &E2EF   ;
E2FB	PLP         ;get back flag
E2FC	BEQ &E2A5   ;if end of command line reached then E2A5
    	            ; to do osfile
E2FE	LDX #&06    ;else set up execution address
E300	JSR &E2AD   ;
E303	BCC &E310   ;if error BAD COMMAND
E305	BEQ &E2A5   ;and if end of line reached do OSFILE

E307	LDX #&02    ;else set up load address
E309	JSR &E2AD   ;
E30C	BCC &E310   ;if error BAD command
E30E	BEQ &E2A5   ;else on end of line do OSFILE
    	            ;anything else is an error!!!!

******** Bad command error ************************************

E310	BRK         ;
E311	DB  &FE             ;error number
E312	DB  'Bad Command'   ;
E31D	BRK
E31E	DB  &FB             ;
E31F	DB  'Bad Key'       ;
E326	BRK


*************************************************************************
*                                                                       *
*       *KEY ENTRY                                                      *
*                                                                       *
*************************************************************************

E327	JSR &E04E   ;set up key number in A
E32A	BCC &E31D   ;if not valid number give error
E32C	CPX #&10    ;if key number greater than 15
E32E	BCS &E31D   ;if greater then give error
E330	JSR &E045   ;otherwise skip commas, and check for CR
E333	PHP         ;save flags for later
E334	LDX &0B10   ;get pointer to top of existing key strings
E337	TYA         ;save Y
E338	PHA         ;to preserve text pointer
E339	JSR &E3D1   ;set up soft key definition
E33C	PLA         ;get back Y
E33D	TAY         ;
E33E	PLP         ;and flags
E33F	BNE &E377   ;if CR found return else E377 to set up new string
E341	RTS         ;else return to set null string


*************************************************************************
*                                                                       *
*       *FX   OSBYTE                                                    *
*                                                                       *
*************************************************************************
    	A=number

E342	JSR &E04E   ;convert the number to binary
E345	BCC &E310   ;if bad number call bad command
E347	TXA         ;save X


*************************************************************************
*                                                                       *
*       *CODE   *MOTOR  *OPT    *ROM    *TAPE   *TV                     *
*                                                                       *
*************************************************************************
    	;enter codes    *CODE   &88
    	            *MOTOR  &89
    	            *OPT    &8B
    	            *TAPE   &8C
    	            *ROM    &8D
    	            *TV     &90

E348	PHA         ;save A
E349	LDA #&00    ;clear &E4/E5
E34B	STA &E5     ;
E34D	STA &E4     ;
E34F	JSR &E043   ;skip commas and check for newline (CR)
E352	BEQ &E36C   ;if CR found E36C
E354	JSR &E04E   ;convert character to binary
E357	BCC &E310   ;if bad character bad command error
E359	STX &E5     ;else save it
E35B	JSR &E045   ;skip comma and check CR
E35E	BEQ &E36C   ;if CR then E36C
E360	JSR &E04E   ;get another parameter
E363	BCC &E310   ;if bad error
E365	STX &E4     ;else store in E4
E367	JSR &E03A   ;now we must have a newline
E36A	BNE &E310   ;if none then output an error

E36C	LDY &E4     ;Y=third osbyte parameter
E36E	LDX &E5     ;X=2nd
E370	PLA         ;A=first
E371	JSR OSBYTE  ;call osbyte
E374	BVS &E310   ;if V set on return then error
E376	RTS         ;else RETURN

********* *KEY CONTINUED ************************************************
    	    ;X points to last byte of current key definitions
E377	SEC         ;
E378	JSR &EA1E   ;look for '"' on return bit 6 E4=1 bit 7=1 if '"'found
    	            ;this is a GSINIT call without initial CLC
E37B	JSR &EA2F   ;call GSREAD carry is set if end of line found
E37E	BCS &E388   ;E388 to deal with end of line
E380	INX         ;point to first byte of new key definition
E381	BEQ &E31D   ;if X=0 buffer WILL overflow so exit with BAD KEY error
E383	STA &0B00,X ;store character
E386	BCC &E37B   ;and loop to get next byte if end of line not found
E388	BNE &E31D   ;if Z clear then no matching '"' found or for some
    	            ;other reason line doesn't terminate properly
E38A	PHP         ;else if all OK save flags
E38B	SEI         ;bar interrupts
E38C	JSR &E3D1   ;and move string

E38F	LDX #&10    ;set loop counter

E391	CPX &E6     ;if key being defined is found
E393	BEQ &E3A3   ;then skip rest of loop
E395	LDA &0B00,X ;else get start of string X
E398	CMP &0B00,Y ;compare with start of string Y
E39B	BNE &E3A3   ;if not the same then skip rest of loop
E39D	LDA &0B10   ;else store top of string definition
E3A0	STA &0B00,X ;in designated key pointer
E3A3	DEX         ;decrement loop pointer X
E3A4	BPL &E391   ;and do it all again
E3A6	PLP         ;get back flags
E3A7	RTS         ;and exit


***********: set string lengths *****************************************

E3A8	PHP         ;push flags
E3A9	SEI         ;bar interrupts
E3AA	LDA &0B10   ;get top of currently defined strings
E3AD	SEC         ;
E3AE	SBC &0B00,Y ;subtract to get the number of bytes in strings
    	            ;above end of string Y
E3B1	STA &FB     ;store this
E3B3	TXA         ;save X
E3B4	PHA         ;
E3B5	LDX #&10    ;and X=16

E3B7	LDA &0B00,X ;get start offset (from B00) of key string X
E3BA	SEC         ;
E3BB	SBC &0B00,Y ;subtract offset of string we are working on
E3BE	BCC &E3C8   ;if carry clear (B00+Y>B00+X) or
E3C0	BEQ &E3C8   ;result (in A)=0
E3C2	CMP &FB     ;or greater or equal to number of bytes above
    	            ;string we are working on
E3C4	BCS &E3C8   ;then E3C8
E3C6	STA &FB     ;else store A in &FB

E3C8	DEX         ;point to next lower key offset
E3C9	BPL &E3B7   ;and if 0 or +ve go back and do it again
E3CB	PLA         ;else get back value of X
E3CC	TAX         ;
E3CD	LDA &FB     ;get back latest value of A
E3CF	PLP         ;pull flags
E3D0	RTS         ;and return


***********: set up soft key definition *********************************

E3D1	PHP         ;push P
E3D2	SEI         ;bar interrupts
E3D3	TXA         ;save X
E3D4	PHA         ;push A
E3D5	LDY &E6     ;get key number

E3D7	JSR &E3A8   ;and set up &FB
E3DA	LDA &0B00,Y ;get start of string
E3DD	TAY         ;put it in Y
E3DE	CLC         ;clear carry
E3DF	ADC &FB     ;add number of bytes above string
E3E1	TAX         ;put this in X
E3E2	STA &FA     ;and store it
E3E4	LDA &0268   ;check number of bytes left to remove from key buffer
    	            ;if not 0 key is being used (definition expanded so
    	            ;error.  This stops *KEY 1 "*key1 FRED" etc.
E3E7	BEQ &E3F6   ;if not in use continue

E3E9	BRK         ;
E3EA	DB  &FA     ;error number
E3EB	DB  'Key in use'            ;
E3F5	BRK         ;
    	
E3F6	DEC &0284   ;decrement consistence flag to &FF to warn that key
    	            ;definitions are being changed
E3F9	PLA         ;pull A
E3FA	SEC         ;
E3FB	SBC &FA     ;subtract &FA
E3FD	STA &FA     ;and re store it
E3FF	BEQ &E40D   ;if 0 then E40D

E401	LDA &0B01,X ;else move string
E404	STA &0B01,Y ;from X to Y
E407	INY         ;
E408	INX         ;
E409	DEC &FA     ;for length of string
E40B	BNE &E401   ;

E40D	TYA         ;store end of moved string(s)
E40E	PHA         ;
E40F	LDY &E6     ;get back key number
E411	LDX #&10    ;point at top of last string

E413	LDA &0B00,X ;get this value
E416	CMP &0B00,Y ;compare it with start of new or re defined key
E419	BCC &E422   ;if less then E422
E41B	BEQ &E422   ;if = then E422
E41D	SBC &FB     ;shift key definitions accordingly
E41F	STA &0B00,X ;
E422	DEX         ;point to next lowest string def
E423	BPL &E413   ;and if =>0 then loop and do it again
E425	LDA &0B10   ;else make top of key definitions
E428	STA &0B00,Y ;the start of our key def
E42B	PLA         ;get new end of strings
E42C	STA &0B10   ;and store it
E42F	TAX         ;put A in X
E430	INC &0284   ;reset consistency flag
E433	PLP         ;restore flags
E434	RTS         ;and exit


\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E435 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E435
new file mode 100644
index 0000000..636b244
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E435
@@ -0,0 +1 @@
+**************** BUFFER ADDRESS HI LOOK UP TABLE ************************
E435    DB      &03   ;keyboard
E436    DB      &0A   ;rs423 input
E437    DB      &08   ;rs423 output
E438    DB      &07   ;printer
E439    DB      &07   ;sound 0
E43A    DB      &07   ;sound 1
E43B    DB      &07   ;sound 2
E43C    DB      &07   ;sound 3
E43D    DB      &09   ;speech
 
**************** BUFFER ADDRESS LO LOOK UP TABLE ************************
E43E    DB      &00
E43F    DB      &00
E440    DB      &C0
E441    DB      &C0
E442    DB      &50
E443    DB      &60
E444    DB      &70
E445    DB      &80
E446    DB      &00
 
**************** BUFFER START ADDRESS OFFSET ****************************
E447    DB      &E0
E448    DB      &00
E449    DB      &40
E44A    DB      &C0
E44B    DB      &F0
E44C    DB      &F0
E44D    DB      &F0
E44E    DB      &F0
E44F    DB      &C0

*******: get nominal buffer addresses in &FA/B **************************

    	; ON ENTRY X=buffer number
    	;Buffer number  Address         Flag    Out pointer     In pointer
    	;0=Keyboard     3E0-3FF         2CF     2D8             2E1
    	;1=RS423 Input  A00-AFF         2D0     2D9             2E2
    	;2=RS423 output 900-9BF         2D1     2DA             2E3
    	;3=printer      880-8BF         2D2     2DB             2E4
    	;4=sound0       840-84F         2D3     2DC             2E5
    	;5=sound1       850-85F         2D4     2DD             2E6
    	;6=sound2       860-86F         2D5     2DE             2E7
    	;7=sound3       870-87F         2D6     2DF             2E8
    	;8=speech       8C0-8FF         2D7     2E0             2E9

E450	LDA &E43E,X ;get buffer base address lo
E453	STA &FA     ;store it
E455	LDA &E435,X ;get buffer base address hi
E458	STA &FB     ;store it
E45A	RTS         ;exit


*************************************************************************
*                                                                       *
*       OSBYTE 152 Examine Buffer status                                *
*                                                                       *
*************************************************************************
;on entry X = buffer number
;on exit FA/B points to buffer start  Y is offset to next character
;if buffer is empty C=1, Y is preserved else C=0

E45B	BIT &D9B7   ;set V and
E45E	BVS &E461   ;jump to E461


*************************************************************************
*                                                                       *
*       OSBYTE 145 Get byte from Buffer                                 *
*                                                                       *
*************************************************************************
;on entry X = buffer number
; ON EXIT Y is character extracted
;if buffer is empty C=1, else C=0

E460	CLV         ;clear V

E461	JMP (&022C) ;Jump via REMV


*************************************************************************
*                                                                       *
*       REMV buffer remove vector default entry point                   *
*                                                                       *
*************************************************************************
;on entry X = buffer number
;on exit if buffer is empty C=1, Y is preserved else C=0

E464	PHP         ;push flags
E465	SEI         ;bar interrupts
E466	LDA &02D8,X ;get output pointer for buffer X
E469	CMP &02E1,X ;compare to input pointer
E46C	BEQ &E4E0   ;if equal buffer is empty so E4E0 to exit
E46E	TAY         ;else A=Y
E46F	JSR &E450   ;and get buffer pointer into FA/B
E472	LDA (&FA),Y ;read byte from buffer
E474	BVS &E491   ;if V is set (on input) exit with CARRY clear
    	            ;Osbyte 152 has been done
E476	PHA         ;else must be osbyte 145 so save byte
E477	INY         ;increment Y
E478	TYA         ;A=Y
E479	BNE &E47E   ;if end of buffer not reached <>0 E47E

E47B	LDA &E447,X ;get pointer start from offset table

E47E	STA &02D8,X ;set buffer output pointer
E481	CPX #&02    ;if buffer is input (0 or 1)
E483	BCC &E48F   ;then E48F

E485	CMP &02E1,X ;else for output buffers compare with buffer start
E488	BNE &E48F   ;if not the same buffer is not empty so E48F

E48A	LDY #&00    ;buffer is empty so Y=0
E48C	JSR &E494   ;and enter EVENT routine to signal EVENT 0 buffer
    	            ;becoming empty

E48F	PLA         ;get back byte from buffer
E490	TAY         ;put it in Y
E491	PLP         ;get back flags
E492	CLC         ;clear carry to indicate success
E493	RTS         ;and exit




**************************************************************************
**************************************************************************
**                                                                      **
**      CAUSE AN EVENT                                                  **
**                                                                      **
**************************************************************************
**************************************************************************
;on entry Y=event number
;A and X may be significant Y=A, A=event no. when event generated @E4A1
;on exit carry clear indicates action has been taken else carry set

E494	PHP         ;push flags
E495	SEI         ;bar interrupts
E496	PHA         ;push A
E497	STA &FA     ;&FA=A
E499	LDA &02BF,Y ;get enable event flag
E49C	BEQ &E4DF   ;if 0 event is not enabled so exit
E49E	TYA         ;else A=Y
E49F	LDY &FA     ;Y=A
E4A1	JSR &F0A5   ;vector through &220
E4A4	PLA         ;get back A
E4A5	PLP         ;get back flags
E4A6	CLC         ;clear carry for success
E4A7	RTS         ;and exit


********* check event 2 character entering buffer ***********************

E4A8	TYA         ;A=Y
E4A9	LDY #&02    ;Y=2
E4AB	JSR &E494   ;check event
E4AE	TAY         ;Y=A


*************************************************************************
*                                                                       *
*       OSBYTE 138 Put byte into Buffer                                 *
*                                                                       *
*************************************************************************
;on entry X is buffer number, Y is character to be written


E4AF	TYA         ;A=Y

E4B0	JMP (&022A) ;jump to INSBV


*************************************************************************
*                                                                       *
*       INSBV insert character in buffer vector default entry point     *
*                                                                       *
*************************************************************************
;on entry X is buffer number, A is character to be written

E4B3	PHP         ;save flags
E4B4	SEI         ;bar interrupts
E4B5	PHA         ;save A
E4B6	LDY &02E1,X ;get buffer input pointer
E4B9	INY         ;increment Y
E4BA	BNE &E4BF   ;if Y=0 then buffer is full else E4BF
E4BC	LDY &E447,X ;get default buffer start

E4BF	TYA         ;put it in A
E4C0	CMP &02D8,X ;compare it with input pointer
E4C3	BEQ &E4D4   ;if equal buffer is full so E4D4
E4C5	LDY &02E1,X ;else get buffer end in Y
E4C8	STA &02E1,X ;and set it from A
E4CB	JSR &E450   ;and point &FA/B at it
E4CE	PLA         ;get back byte
E4CF	STA (&FA),Y ;store it in buffer
E4D1	PLP         ;pull flags
E4D2	CLC         ;clear carry for success
E4D3	RTS         ;and exit


E4D4	PLA         ;get back byte
E4D5	CPX #&02    ;if we are working on input buffer
E4D7	BCS &E4E0   ;then E4E0

E4D9	LDY #&01    ;else Y=1
E4DB	JSR &E494   ;to service input buffer full event
E4DE	PHA         ;push A


***** return with carry set *********************************************

E4DF	PLA         ;restore A

E4E0	PLP         ;restore flags
E4E1	SEC         ;set carry
E4E2	RTS         ;and exit



***************** CODE MODIFIER ROUTINE *********************************
*                 CHECK FOR ALPHA CHARACTER                             *
*************************************************************************
    	            ;ENTRY  character in A
    	            ;exit with carry set if non-Alpha character
E4E3	PHA         ;Save A
E4E4	AND #&DF    ;convert lower to upper case
E4E6	CMP #&41    ;is it 'A' or greater ??
E4E8	BCC &E4EE   ;if not exit routine with carry set
E4EA	CMP #&5B    ;is it less than 'Z'
E4EC	BCC &E4EF   ;if so exit with carry clear
E4EE	SEC         ;else clear carry
E4EF	PLA         ;get back original value of A
E4F0	RTS         ;and Return
    	            ;
    	            ;

*******: INSERT byte in Keyboard buffer *********************************

E4F1	LDX #&00    ;X=0 to indicate keyboard buffer

*************************************************************************
*                                                                       *
*       OSBYTE 153 Put byte in input Buffer checking for ESCAPE         *
*                                                                       *
*************************************************************************
;on entry X = buffer number (either 0 or 1)
;X=1 is RS423 input
;X=0 is Keyboard
;Y is character to be written

E4F3	TXA         ;A=buffer number
E4F4	AND &0245   ;and with RS423 mode (0 treat as keyboard
    	            ;1 ignore Escapes no events no soft keys)
E4F7	BNE &E4AF   ;so if RS423 buffer AND RS423 in normal mode (1) E4AF

E4F9	TYA         ;else Y=A character to write
E4FA	EOR &026C   ;compare with current escape ASCII code (0=match)
E4FD	ORA &0275   ;or with current ESCAPE status (0=ESC, 1=ASCII)
E500	BNE &E4A8   ;if ASCII or no match E4A8 to enter byte in buffer
E502	LDA &0258   ;else get ESCAPE/BREAK action byte
E505	ROR         ;Rotate to get ESCAPE bit into carry
E506	TYA         ;get character back in A
E507	BCS &E513   ;and if escape disabled exit with carry clear
E509	LDY #&06    ;else signal EVENT 6 Escape pressed
E50B	JSR &E494   ;
E50E	BCC &E513   ;if event handles ESCAPE then exit with carry clear
E510	JSR &E674   ;else set ESCAPE flag
E513	CLC         ;clear carry
E514	RTS         ;and exit


******** get a byte from keyboard buffer and interpret as necessary *****
;on entry A=cursor editing status 1=return &87-&8B,
;2= use cursor keys as soft keys 11-15
;this area not reached if cursor editing is normal

E515	ROR         ;get bit 1 into carry
E516	PLA         ;get back A
E517	BCS &E592   ;if carry is set return
    	            ;else cursor keys are 'soft'
E519	TYA         ;A=Y get back original key code (&80-&FF)
E51A	PHA         ;PUSH A
E51B	LSR         ;get high nybble into lo
E51C	LSR         ;
E51D	LSR         ;
E51E	LSR         ;A=8-&F
E51F	EOR #&04    ;and invert bit 2
    	            ;&8 becomes &C
    	            ;&9 becomes &D
    	            ;&A becomes &E
    	            ;&B becomes &F
    	            ;&C becomes &8
    	            ;&D becomes &9
    	            ;&E becomes &A
    	            ;&F becomes &B
    	
E521	TAY         ;Y=A = 8-F
E522	LDA &0265,Y ;read 026D to 0274 code interpretation status
    	            ;0=ignore key, 1=expand as 'soft' key
    	            ;2-&FF add this to base for ASCII code
    	            ;note that provision is made for keypad operation
    	            ;as codes &C0-&FF cannot be generated from keyboard
    	            ;but are recognised by OS
    	            ;
E525	CMP #&01    ;is it 01
E527	BEQ &E594   ;if so expand as 'soft' key via E594
E529	PLA         ;else get back original byte
E52A	BCC &E539   ;if above CMP generated Carry then code 0 must have
    	            ;been returned so E539 to ignore
E52C	AND #&0F    ;else add ASCII to BASE key number so clear hi nybble
E52E	CLC         ;clear carry
E52F	ADC &0265,Y ;add ASCII base
E532	CLC         ;clear carry
E533	RTS         ;and exit
    	            ;
*********** ERROR MADE IN USING EDIT FACILITY ***************************

E534	JSR &E86F   ;produce bell
E537	PLA         ;get back A, buffer number
E538	TAX         ;X=buffer number

********get byte from buffer ********************************************

E539	JSR &E460   ;get byte from buffer X
E53C	BCS &E593   ;if buffer empty E593 to exit
E53E	PHA         ;else Push byte
E53F	CPX #&01    ;and if RS423 input buffer is not the one
E541	BNE &E549   ;then E549

E543	JSR &E173   ;else oswrch
E546	LDX #&01    ;X=1 (RS423 input buffer)
E548	SEC         ;set carry

E549	PLA         ;get back original byte
E54A	BCC &E551   ;if carry clear (I.E not RS423 input) E551
E54C	LDY &0245   ;else Y=RS423 mode (0 treat as keyboard )
E54F	BNE &E592   ;if not 0 ignore escapes etc. goto E592

E551	TAY         ;Y=A
E552	BPL &E592   ;if code is less that &80 its simple so E592
E554	AND #&0F    ;else clear high nybble
E556	CMP #&0B    ;if less than 11 then treat as special code
E558	BCC &E519   ;or function key and goto E519
E55A	ADC #&7B    ;else add &7C (&7B +C) to convert codes B-F to 7-B
E55C	PHA         ;Push A
E55D	LDA &027D   ;get cursor editing status
E560	BNE &E515   ;if not 0 (normal) E515
E562	LDA &027C   ;else get character destination status

;Bit 0 enables  RS423 driver
;BIT 1 disables VDU driver
;Bit 2 disables printer driver
;BIT 3 enables  printer independent of CTRL B or CTRL C
;Bit 4 disables spooled output
;BIT 5 not used
;Bit 6 disables printer driver unless VDU 1 precedes character
;BIT 7 not used

E565	ROR         ;get bit 1 into carry
E566	ROR         ;
E567	PLA         ;
E568	BCS &E539   ;if carry is set E539 screen disabled
E56A	CMP #&87    ;else is it COPY key
E56C	BEQ &E5A6   ;if so E5A6

E56E	TAY         ;else Y=A
E56F	TXA         ;A=X
E570	PHA         ;Push X
E571	TYA         ;get back Y
E572	JSR &D8CE   ;execute edit action

E575	PLA         ;restore X
E576	TAX         ;
E577	BIT &025F   ;check econet RDCH flag
E57A	BPL &E581   ;if not set goto E581
E57C	LDA #&06    ;else Econet function 6
E57E	JMP (&0224) ;to the Econet vector


********* get byte from key string **************************************
;on entry 0268 contains key length
;and 02C9 key string pointer to next byte

E581	LDA &0268   ;get length of keystring
E584	BEQ &E539   ;if 0 E539 get a character from the buffer
E586	LDY &02C9   ;get soft key expansion pointer
E589	LDA &0B01,Y ;get character from string
E58C	INC &02C9   ;increment pointer
E58F	DEC &0268   ;decrement length


************** exit with carry clear ************************************

E592	CLC         ;
E593	RTS         ;exit
    	            ;
*** expand soft key strings *********************************************
Y=pointer to sring number

E594	PLA         ;restore original code
E595	AND #&0F    ;blank hi nybble to get key string number
E597	TAY         ;Y=A
E598	JSR &E3A8   ;get string length in A
E59B	STA &0268   ;and store it
E59E	LDA &0B00,Y ;get start point
E5A1	STA &02C9   ;and store it
E5A4	BNE &E577   ;if not 0 then get byte via E577 and exit


*********** deal with COPY key ******************************************

E5A6	TXA         ;A=X
E5A7	PHA         ;Push A
E5A8	JSR &D905   ;read a character from the screen
E5AB	TAY         ;Y=A
E5AC	BEQ &E534   ;if not valid A=0 so BEEP
E5AE	PLA         ;else restore X
E5AF	TAX         ;
E5B0	TYA         ;and Y
E5B1	CLC         ;clear carry
E5B2	RTS         ;and exit


\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E6B0 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E6B0
new file mode 100644
index 0000000..5f1e45f
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E6B0
@@ -0,0 +1 @@
+*************************************************************************
*                                                                       *
*        OSBYTE LOOK UP TABLE
*                                                                       *
*************************************************************************


E5B3	DB  &21,&E8         ;OSBYTE   0  (&E821)
E5B5	DB  &88,&E9         ;OSBYTE   1  (&E988)
E5B7	DB  &D3,&E6         ;OSBYTE   2  (&E6D3)
E5B9	DB  &97,&E9         ;OSBYTE   3  (&E997)
E5BB	DB  &97,&E9         ;OSBYTE   4  (&E997)
E5BD	DB  &76,&E9         ;OSBYTE   5  (&E976)
E5BF	DB  &88,&E9         ;OSBYTE   6  (&E988)
E5C1	DB  &8B,&E6         ;OSBYTE   7  (&E68B)
E5C3	DB  &89,&E6         ;OSBYTE   8  (&E689)
E5C5	DB  &B0,&E6         ;OSBYTE   9  (&E6B0)
E5C7	DB  &B2,&E6         ;OSBYTE  10  (&E6B2)
E5C9	DB  &95,&E9         ;OSBYTE  11  (&E995)
E5CB	DB  &8C,&E9         ;OSBYTE  12  (&E98C)
E5CD	DB  &F9,&E6         ;OSBYTE  13  (&E6F9)
E5CF	DB  &FA,&E6         ;OSBYTE  14  (&E6FA)
E5D1	DB  &A8,&F0         ;OSBYTE  15  (&F0A8)
E5D3	DB  &06,&E7         ;OSBYTE  16  (&E706)
E5D5	DB  &8C,&DE         ;OSBYTE  17  (&DE8C)
E5D7	DB  &C8,&E9         ;OSBYTE  18  (&E9C8)
E5D9	DB  &B6,&E9         ;OSBYTE  19  (&E9B6)
E5DB	DB  &07,&CD         ;OSBYTE  20  (&CD07)
E5DD	DB  &B4,&F0         ;OSBYTE  21  (&F0B4)
E5DF	DB  &6C,&E8         ;OSBYTE 117  (&E86C)
E5E1	DB  &D9,&E9         ;OSBYTE 118  (&E9D9)
E5E3	DB  &75,&E2         ;OSBYTE 119  (&E275)
E5E5	DB  &45,&F0         ;OSBYTE 120  (&F045)
E5E7	DB  &CF,&F0         ;OSBYTE 121  (&F0CF)
E5E9	DB  &CD,&F0         ;OSBYTE 122  (&F0CD)
E5EB	DB  &97,&E1         ;OSBYTE 123  (&E197)
E5ED	DB  &73,&E6         ;OSBYTE 124  (&E673)
E5EF	DB  &74,&E6         ;OSBYTE 125  (&E674)
E5F1	DB  &5C,&E6         ;OSBYTE 126  (&E65C)
E5F3	DB  &35,&E0         ;OSBYTE 127  (&E035)
E5F5	DB  &4F,&E7         ;OSBYTE 128  (&E74F)
E5F7	DB  &13,&E7         ;OSBYTE 129  (&E713)
E5F9	DB  &29,&E7         ;OSBYTE 130  (&E729)
E5FB	DB  &85,&F0         ;OSBYTE 131  (&F085)
E5FD	DB  &23,&D9         ;OSBYTE 132  (&D923)
E5FF	DB  &26,&D9         ;OSBYTE 133  (&D926)
E601	DB  &47,&D6         ;OSBYTE 134  (&D647)
E603	DB  &C2,&D7         ;OSBYTE 135  (&D7C2)
E605	DB  &57,&E6         ;OSBYTE 136  (&E657)
E607	DB  &7F,&E6         ;OSBYTE 137  (&E67F)
E609	DB  &AF,&E4         ;OSBYTE 138  (&E4AF)
E60B	DB  &34,&E0         ;OSBYTE 139  (&E034)
E60D	DB  &35,&F1         ;OSBYTE 140  (&F135)
E60F	DB  &35,&F1         ;OSBYTE 141  (&F135)
E611	DB  &E7,&DB         ;OSBYTE 142  (&DBE7)
E613	DB  &68,&F1         ;OSBYTE 143  (&F168)
E615	DB  &E3,&EA         ;OSBYTE 144  (&EAE3)
E617	DB  &60,&E4         ;OSBYTE 145  (&E460)
E619	DB  &AA,&FF         ;OSBYTE 146  (&FFAA)
E61B	DB  &F4,&EA         ;OSBYTE 147  (&EAF4)
E61D	DB  &AE,&FF         ;OSBYTE 148  (&FFAE)
E61F	DB  &F9,&EA         ;OSBYTE 149  (&EAF9)
E621	DB  &B2,&FF         ;OSBYTE 150  (&FFB2)
E623	DB  &FE,&EA         ;OSBYTE 151  (&EAFE)
E625	DB  &5B,&E4         ;OSBYTE 152  (&E45B)
E627	DB  &F3,&E4         ;OSBYTE 153  (&E4F3)
E629	DB  &FF,&E9         ;OSBYTE 154  (&E9FF)
E62B	DB  &10,&EA         ;OSBYTE 155  (&EA10)
E62D	DB  &7C,&E1         ;OSBYTE 156  (&E17C)
E62F	DB  &A7,&FF         ;OSBYTE 157  (&FFA7)
E631	DB  &6D,&EE         ;OSBYTE 158  (&EE6D)
E633	DB  &7F,&EE         ;OSBYTE 159  (&EE7F)
E635	DB  &C0,&E9         ;OSBYTE 160  (&E9C0)
E637	DB  &9C,&E9         ;
E639	DB  &59,&E6         ;


*************************************************************************
*                                                                       *
*        OSWORD LOOK UP TABLE                                           *
*                                                                       *
*************************************************************************


E63B	DB  &02,&E9         ;OSWORD   0  (&E902)
E63D	DB  &D5,&E8         ;OSWORD   1  (&E8D5)
E63F	DB  &E8,&E8         ;OSWORD   2  (&E8E8)
E641	DB  &D1,&E8         ;OSWORD   3  (&E8D1)
E643	DB  &E4,&E8         ;OSWORD   4  (&E8E4)
E645	DB  &03,&E8         ;OSWORD   5  (&E803)
E647	DB  &0B,&E8         ;OSWORD   6  (&E80B)
E649	DB  &2D,&E8         ;OSWORD   7  (&E82D)
E64B	DB  &AE,&E8         ;OSWORD   8  (&E8AE)
E64D	DB  &35,&C7         ;OSWORD   9  (&C735)
E64F	DB  &F3,&CB         ;OSWORD  10  (&CBF3)
E651	DB  &48,&C7         ;OSWORD  11  (&C748)
E653	DB  &E0,&C8         ;OSWORD  12  (&C8E0)
E655	DB  &CE,&D5         ;OSWORD  13  (&D5CE)


*************************************************************************
*                                                                       *
*       OSBYTE 136   Execute Code via User Vector                       *
*                                                                       *
*       *CODE effectively                                               *
*                                                                       *
*************************************************************************

E658	LDA #00     ;A=0


*************************************************************************
*                                                                       *
*       *LINE   entry                                                   *
*                                                                       *
*************************************************************************

E659	JMP (&0200) ;Jump via USERV


*************************************************************************
*                                                                       *
*       OSBYTE  126  Acknowledge detection of ESCAPE condition          *
*                                                                       *
*************************************************************************


E65C	LDX #&00    ;X=0
E65E	BIT &FF     ;if bit 7 not set there is no ESCAPE condition
E660	BPL &E673   ;so E673
E662	LDA &0276   ;else get ESCAPE Action, if this is 0
    	            ;Clear ESCAPE
    	            ;close EXEC files
    	            ;purge all buffers
    	            ;reset VDU paging counter
E665	BNE &E671   ;else do none of the above
E667	CLI         ;allow interrupts
E668	STA &0269   ;number of lines printed since last halt in paged
    	            ;mode = 0
E66B	JSR &F68D   ;close any open EXEC files
E66E	JSR &F0AA   ;clear all buffers
E671	LDX #&FF    ;X=&FF to indicate ESCAPE acknowledged



*************************************************************************
*                                                                       *
*       OSBYTE  124  Clear ESCAPE condition                             *
*                                                                       *
*************************************************************************


E673	CLC         ;clear carry



*************************************************************************
*                                                                       *
*       OSBYTE  125  Set ESCAPE flag                                    *
*                                                                       *
*************************************************************************


E674	ROR &FF     ;clear  bit 7 of ESCAPE flag
E676	BIT &027A   ;read bit 7 of Tube flag
E679	BMI &E67C   ;if set TUBE exists so E67C
E67B	RTS         ;else RETURN
    	            ;
E67C	JMP &0403   ;Jump to Tube entry point



*************************************************************************
*                                                                       *
*       OSBYTE  137  Turn on Tape motor                                 *
*                                                                       *
*************************************************************************


E67F	LDA &0282   ;get serial ULA control setting
E682	TAY         ;Y=A
E683	ROL         ;rotate left to get bit 7 into carry
E684	CPX #&01    ;if X=1 then user wants motor on so CARRY set else
    	            ;carry is cleared
E686	ROR         ;put carry back in control RAM copy
E687	BVC &E6A7   ;if bit 6 is clear then cassette is selected
    	            ;so write to control register and RAM copy

E689	LDA #&38    ;A=ASCII 8


*************************************************************************
*                                                                       *
*       OSBYTE 08/07 set serial baud rates                              *
*                                                                       *
*************************************************************************
    	on entry X=baud rate
    	     A=8 transmit
    	     A=7 receive

E68B	EOR #&3F    ;converts ASCII 8 to 7 binary and ASCII 7 to 8 binary
E68D	STA &FA     ;store result
E68F	LDY &0282   ;get serial ULA control register setting
E692	CPX #&09    ;is it 9 or more?
E694	BCS &E6AD   ;if so exit
E696	AND &E9AD,X ;and with byte from look up table
E699	STA &FB     ;store it
E69B	TYA         ;put Y in A
E69C	ORA &FA     ;and or with Accumulator
E69E	EOR &FA     ;zero the three bits set true
E6A0	ORA &FB     ;set up data read from look up table + bit 6
E6A2	ORA #&40    ;
E6A4	EOR &025D   ;write cassette/RS423 flag

E6A7	STA &0282   ;store serial ULA flag
E6AA	STA &FE10   ;and write to control register
E6AD	TYA         ;put Y in A to save old contents
E6AE	TAX         ;write new setting to X
E6AF	RTS         ;and return

OS SERIES VII
GEOFF COX

*************************************************************************
*                                                                       *
*       OSBYTE  9   Duration of first colour                            *
*                                                                       *
*************************************************************************
;on entry Y=0, X=new value

E6B0	INY         ;Y is incremented to 1
E6B1	CLC         ;clear carry


*************************************************************************
*                                                                       *
*       OSBYTE  10   Duration of second colour                          *
*                                                                       *
*************************************************************************

;on entry Y=0 or 1 if from FX 9 call, X=new value

E6B2	LDA &0252,Y ;get mark period count
E6B5	PHA         ;push it
E6B6	TXA         ;get new count
E6B7	STA &0252,Y ;store it
E6BA	PLA         ;get back original value
E6BB	TAY         ;put it in Y
E6BC	LDA &0251   ;get value of flash counter
E6BF	BNE &E6D1   ;if not zero E6D1

E6C1	STX &0251   ;else restore old value
E6C4	LDA &0248   ;get current video ULA control register setting
E6C7	PHP         ;push flags
E6C8	ROR         ;rotate bit 0 into carry, carry into bit 7
E6C9	PLP         ;get back flags
E6CA	ROL         ;rotate back carry into bit 0
E6CB	STA &0248   ;store it in RAM copy
E6CE	STA &FE20   ;and ULA control register

E6D1	BVC &E6AD   ;then exit via OSBYTE 7/8


*************************************************************************
*                                                                       *
*       OSBYTE  2   select input stream                                 *
*                                                                       *
*************************************************************************

;on input X contains stream number

E6D3	TXA         ;A=X
E6D4	AND #&01    ;blank out bits 1 - 7
E6D6	PHA         ;push A
E6D7	LDA &0250   ;and get current ACIA control setting
E6DA	ROL         ;Bit 7 into carry
E6DB	CPX #&01    ;if X>=1 then
E6DD	ROR         ;bit 7 of A=1
E6DE	CMP &0250   ;compare this with ACIA control setting
E6E1	PHP         ;push processor
E6E2	STA &0250   ;put A into ACIA control setting
E6E5	STA &FE08   ;and write to control register
E6E8	JSR &E173   ;set up RS423 buffer
E6EB	PLP         ;get back P
E6EC	BEQ &E6F1   ;if new setting different from old E6F1 else
E6EE	BIT &FE09   ;set bit 6 and 7

E6F1	LDX &0241   ;get current input buffer number
E6F4	PLA         ;get back A
E6F5	STA &0241   ;store it
E6F8	RTS         ;and return
    	


*************************************************************************
*                                                                       *
*       OSBYTE  13   disable events                                     *
*                                                                       *
*************************************************************************

    	;X contains event number 0-9

E6F9	TYA         ;Y=0 A=0



*************************************************************************
*                                                                       *
*       OSBYTE  14   enable events                                      *
*                                                                       *
*************************************************************************

    	;X contains event number 0-9


E6FA	CPX #&0A    ;if X>9
E6FC	BCS &E6AE   ;goto E6AE for exit
E6FE	LDY &02BF,X ;else get event enable flag
E701	STA &02BF,X ;store new value in flag
E704	BVC &E6AD   ;and exit via E6AD



*************************************************************************
*                                                                       *
*       OSBYTE  16   Select A/D channel                                 *
*                                                                       *
*************************************************************************
 ;X contains channel number or 0 if disable conversion

E706	BEQ &E70B   ;if X=0 then E70B
E708	JSR &DE8C   ;start conversion

E70B	LDA &024D   ;get  current maximum ADC channel number
E70E	STX &024D   ;store new value
E711	TAX         ;put old value in X
E712	RTS         ;and exit
    	            ;


*************************************************************************
*                                                                       *
*       OSBYTE 129   Read key within time limit                         *
*                                                                       *
*************************************************************************
 ;X and Y contains either time limit in centi seconds Y=&7F max
 ; or Y=&FF and X=-ve INKEY value

E713	TYA         ;A=Y
E714	BMI &E721   ;if Y=&FF the E721
E716	CLI         ;else allow interrupts
E717	JSR &DEBB   ;and go to timed routine
E71A	BCS &E71F   ;if carry set then E71F
E71C	TAX         ;then X=A
E71D	LDA #&00    ;A=0

E71F	TAY         ;Y=A
E720	RTS         ;and return
    	            ;
    	            ;scan keyboard
E721	TXA         ;A=X
E722	EOR #&7F    ;convert to keyboard input
E724	TAX         ;X=A
E725	JSR &F068   ;then scan keyboard
E728	ROL         ;put bit 7 into carry
E729	LDX #&FF    ;X=&FF
E72B	LDY #&FF    ;Y=&FF
E72D	BCS &E731   ;if bit 7 of A was set goto E731 (RTS)
E72F	INX         ;else X=0
E730	INY         ;and Y=0
E731	RTS         ;and exit


********** check occupancy of input or free space of output buffer *******
    	            ;X=buffer number
    	;Buffer number  Address         Flag    Out pointer     In pointer
    	;0=Keyboard     3E0-3FF         2CF     2D8             2E1
    	;1=RS423 Input  A00-AFF         2D0     2D9             2E2
    	;2=RS423 output 900-9BF         2D1     2DA             2E3
    	;3=printer      880-8BF         2D2     2DB             2E4
    	;4=sound0       840-84F         2D3     2DC             2E5
    	;5=sound1       850-85F         2D4     2DD             2E6
    	;6=sound2       860-86F         2D5     2DE             2E7
    	;7=sound3       870-87F         2D6     2DF             2E8
    	;8=speech       8C0-8FF         2D7     2E0             2E9

E732	TXA         ;buffer number in A
E733	EOR #&FF    ;invert it
E735	TAX         ;X=A
E736	CPX #&02    ;is X>1
E738	CLV         ;clear V flag
E739	BVC &E73E   ;and goto E73E count buffer

E73B	BIT &D9B7   ;set V
E73E	JMP (&022E) ;CNPV defaults to E1D1


************* check RS423 input buffer ************************************

E741	SEC
E742	LDX #&01    ;X=1 to point to buffer
E744	JSR &E738   ;and count it
E747	CPY #&01    ;if the hi byte of the answer is 1 or more
E749	BCS &E74E   ;then Return
E74B	CPX &025B   ;else compare with minimum buffer space
E74E	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSBYTE 128  READ ADC CHANNEL                                    *
*                                                                       *
*************************************************************************

;ON Entry: X=0             Exit Y contains number of last channel converted
;   	   X=channel number       X,Y contain 16 bit value read from channe
;   	   X<0 Y=&FF              X returns information about various buffers
;   	   X=&FF (keyboard )      X=number of characters in buffer
;   	   X=&FE (RS423 Input)    X=number of characters in buffer
;   	   X=&FD (RS423 output)   X=number of empty spaces in buffer
;   	   X=&FC (Printer)        X=number of empty spaces in buffer
;   	   X=&FB (sound 0)        X=number of empty spaces in buffer
;   	   X=&FA (sound 1)        X=number of empty spaces in buffer
;   	   X=&F9 (sound 2)        X=number of empty spaces in buffer
;   	   X=&F8 (sound 3)        X=number of empty spaces in buffer
;   	   X=&F7 (Speech )        X=number of empty spaces in buffer



E74F	BMI &E732   ;if X is -ve then E732 count spaces
E751	BEQ &E75F   ;if X=0 then E75F
E753	CPX #&05    ;else check for Valid channel
E755	BCS &E729   ;if not E729 set X & Y to 0 and exit
E757	LDY &02B9,X ;get conversion values for channel of interest Hi &
E75A	LDA &02B5,X ;lo byte
E75D	TAX         ;X=lo byte
E75E	RTS         ;and exit


E75F	LDA &FE40   ;read system VIA port B
E762	ROR         ;move high nybble to low
E763	ROR         ;
E764	ROR         ;
E765	ROR         ;
E766	EOR #&FF    ;and invert it
E768	AND #&03    ;isolate the FIRE buttons
E76A	LDY &02BE   ;get analogue system flag byte
E76D	STX &02BE   ;store X here
E770	TAX         ;A=X bits 0 and 1 indicate fire buttons
E771	RTS         ;and return


**************************************************************************
**************************************************************************
**                                                                      **
**      OSBYTE  DEFAULT ENTRY POINT                                     **
**                                                                      **
**      pointed to by default BYTEV                                     **
**                                                                      **
**************************************************************************
**************************************************************************


E772	PHA         ;save A
E773	PHP         ;save Processor flags
E774	SEI         ;disable interrupts
E775	STA &EF     ;store A,X,Y in zero page
E777	STX &F0     ;
E779	STY &F1     ;
E77B	LDX #&07    ;X=7 to signal osbyte is being attempted
E77D	CMP #&75    ;if A=0-116
E77F	BCC &E7C2   ;then E7C2
E781	CMP #&A1    ;if A<161
E783	BCC &E78E   ;then E78E
E785	CMP #&A6    ;if A=161-165
E787	BCC &E7C8   ;then EC78
E789	CLC         ;clear carry

E78A	LDA #&A1    ;A=&A1
E78C	ADC #&00    ;

********* process osbyte calls 117 - 160 *****************************

E78E	SEC         ;set carry
E78F	SBC #&5F    ;convert to &16 to &41 (22-65)

E791	ASL         ;double it (44-130)
E792	SEC         ;set carry


E793	STY &F1     ;store Y
E795	TAY         ;Y=A
E796	BIT &025E   ;read econet intercept flag
E799	BPL &E7A2   ;if no econet intercept required E7A2

E79B	TXA         ;else A=X
E79C	CLV         ;V=0
E79D	JSR &E57E   ; to JMP via ECONET vector
E7A0	BVS &E7BC   ;if return with V set E7BC


E7A2	LDA &E5B4,Y ;get address from table
E7A5	STA &FB     ;store it as hi byte
E7A7	LDA &E5B3,Y ;repeat for lo byte
E7AA	STA &FA     ;
E7AC	LDA &EF     ;restore A
E7AE	LDY &F1     ;Y
E7B0	BCS &E7B6   ;if carry is set E7B6

E7B2	LDY #&00    ;else
E7B4	LDA (&F0),Y ;get value from address pointed to by &F0/1 (Y,X)

E7B6	SEC         ;set carry
E7B7	LDX &F0     ;restore X
E7B9	JSR &F058   ;call &FA/B

E7BC	ROR         ;C=bit 0
E7BD	PLP         ;get back flags
E7BE	ROL         ;bit 0=Carry
E7BF	PLA         ;get back A
E7C0	CLV         ;clear V
E7C1	RTS         ;and exit


*************** Process OSBYTE CALLS BELOW &75 **************************

E7C2	LDY #&00    ;Y=0
E7C4	CMP #&16    ;if A<&16
E7C6	BCC &E791   ;goto E791

E7C8	PHP         ;push flags
E7C9	PHP         ;push flags

E7CA	PLA         ;pull flags
E7CB	PLA         ;pull flags
E7CC	JSR &F168   ;offer paged ROMS service 7/8 unrecognised osbyte/word
E7CF	BNE &E7D6   ;if roms don't recognise it then E7D6
E7D1	LDX &F0     ;else restore X
E7D3	JMP &E7BC   ;and exit


E7D6	PLP         ;else pull flags
E7D7	PLA         ;and A
E7D8	BIT &D9B7   ;set V and C
E7DB	RTS         ;and return

E7DC	LDA &EB     ;read cassette critical flag bit 7 = busy
E7DE	BMI &E812   ;if busy then EB12


E7E0	LDA #&08    ;else A=8 to check current Catalogue status
E7E2	AND &E2     ;by anding with CFS status flag
E7E4	BNE &E7EA   ;if not set (not in use) then E7EA RTS
E7E6	LDA #&88    ;A=%10001000
E7E8	AND &BB     ;AND with FS options (short msg bits)
E7EA	RTS         ;RETURN


**************************************************************************
**************************************************************************
**                                                                      **
**      OSWORD  DEFAULT ENTRY POINT                                     **
**                                                                      **
**      pointed to by default WORDV                                     **
**                                                                      **
**************************************************************************
**************************************************************************


E7EB	PHA         ;Push A
E7EC	PHP         ;Push flags
E7ED	SEI         ;disable interrupts
E7EE	STA &EF     ;store A,X,Y
E7F0	STX &F0     ;
E7F2	STY &F1     ;
E7F4	LDX #&08    ;X=8
E7F6	CMP #&E0    ;if A=>224
E7F8	BCS &E78A   ;then E78A with carry set

E7FA	CMP #&0E    ;else if A=>14
E7FC	BCS &E7C8   ;else E7C8 with carry set pass to ROMS & exit

E7FE	ADC #&44    ;add to form pointer to table
E800	ASL         ;double it
E801	BCC &E793   ;goto E793 ALWAYS!! (carry clear E7F8)
    	            ;this reads bytes from table and enters routine


*************************************************************************
*                                                                       *
*       OSWORD  05   ENTRY POINT                                        *
*                                                                       *
*       read a byte from I/O memory                                     *
*                                                                       *
*************************************************************************
;block of 4 bytes set at address pointed to by 00F0/1 (Y,X)
;XY +0  ADDRESS of byte
;   +4  on exit byte read


E803	JSR &E815   ;set up address of data block
E806	LDA (&F9,X) ;get byte
E808	STA (&F0),Y ;store it
E80A	RTS         ;exit


*************************************************************************
*                                                                       *
*       OSWORD  06   ENTRY POINT                                        *
*                                                                       *
*       write a byte to I/O memory                                      *
*                                                                       *
*************************************************************************
;block of 5 bytes set at address pointed to by 00F0/1 (Y,X)
;XY +0  ADDRESS of byte
;   +4  byte to be written


E80B	JSR &E815   ;set up address
E80E	LDA (&F0),Y ;get byte
E810	STA (&F9,X) ;store it
E812	LDA #&00    ;a=0
E814	RTS         ;exit


********************: set up data block *********************************

E815	STA &FA     ;&FA=A
E817	INY         ;Y=1
E818	LDA (&F0),Y ;get byte from block
E81A	STA &FB     ;store it
E81C	LDY #&04    ;Y=4
E81E	LDX #&01    ;X=1
E820	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSBYTE  00   ENTRY POINT                                        *
*                                                                       *
*       read OS version number                                          *
*                                                                       *
*************************************************************************

E821	BNE &E81E   ;if A <> 0 then exit else print error
E823	BRK         ;
E824	DB  &F7             ;error number
E825	DB  'OS 1.20'       ;error message
E82C	BRK

\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E887 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E887
new file mode 100644
index 0000000..cfdd00d
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/E887
@@ -0,0 +1 @@
+*************************************************************************
*************************************************************************
**                                                                     **
**      SOUND SYSTEM                                                   **
**                                                                     **
*************************************************************************
*************************************************************************

-------------------------------------------------------------------------
|                                                                       |
|       OSWORD  07 - Make a sound                                       |
|                                                                       |
-------------------------------------------------------------------------
; On entry, control block pointed to by &F0/1
;           Y=0 on entry
; XY +0  Channel - &hsfc for Hold, Sync, Flush, Channel
;     2  Amplitude/Envelope
;     4  Pitch
;     6  Duration

E82D	INY
E82E	LDA (&F0),Y ; Get channel high byte byte
E830	CMP #&FF
E832	BEQ &E88D   ; Channel &FFxx, speech command
E834	CMP #&20    ; Is channel>=&20 ?
E836	LDX #&08    ; Prepare X=8 for unrecognised OSWORD call
E838	BCS &E7CA   ; Pass to sideways ROMs for channel &2000+
E83A	DEY         ; Point back to channel low byte
E83B	JSR &E8C9   ; Get Channel 0-3, and Cy if >=&10 for Flush
E83E	ORA #&04    ; Convert to buffer number 4-7
E840	TAX
E841	BCC &E848   ; If no Flush, skip past
E843	JSR &E1AE   ; Flush buffer
E846	LDY #&01    ; Point back to channel high byte

E848	JSR &E8C9   ; Get Sync 0-3, and Cy if >=&10 for Hold
E84B	STA &FA     ; Save Sync in &FA
E84D	PHP         ; Stack flags
E84E	LDY #&06
E850	LDA (&F0),Y ; Get Duration byte
E852	PHA         ;  and stack it
E853	LDY #&04
E855	LDA (&F0),Y ; Get pitch byte
E857	PHA         ;  and stack it
E858	LDY #&02    ;
E85A	LDA (&F0),Y ; Get amplitude/envelope byte
E85C	ROL         ; Move Hold into bit 0
E85D	SEC         ;set carry
E85E	SBC #&02    ;subract 2
E860	ASL         ;multiply by 4
E861	ASL         ;
E862	ORA &FA     ;add S byte (0-3)

    	            ; At this point,
		    ; b7,   0=envelope, 1=volume
		    ; b6-3, envelope-1 or volume+15
		    ; b2,   Hold
		    ; b1-0, Sync

E864	JSR &E1F8   ; Insert into buffer
E867	BCC &E887   ; Buffer not full, jump to insert the rest
E869	PLA         ; Drop stacked pitch
E86A	PLA         ; Drop stacked duration
E86B	PLP         ; Restore flags
		    ; And exit

-------------------------------------------------------------------------
|                                                                       |
|       OSBYTE  117 - Read VDU status                                   |
|                                                                       |
-------------------------------------------------------------------------

E86C	LDX &D0     ;get VDU status byte in X
E86E	RTS         ;and return


************* set up sound data for Bell ********************************


E86F	PHP         ;push P
E870	SEI         ;bar interrupts
E871	LDA &0263   ;get bell channel number in A
E874	AND #&07    ; (bits 0-3 only set)
E876	ORA #&04    ;set bit 2
E878	TAX         ;X=A = bell channel number +4=buffer number
E879	LDA &0264   ;get bell amplitude/envelope number
E87C	JSR &E4B0   ;store it in buffer pointed to by X
E87F	LDA &0266   ;get bell duration
E882	PHA         ;save it
E883	LDA &0265   ;get bell frequency
E886	PHA         ;save it

; Insert sound pitch and duration into sound buffer
;
E887	SEC         ; Set carry
E888	ROR &0800,X ; Set bit 7 of channel flags to indicate it's active
E88B	BMI &E8A4   ; Jump forward to insert pitch and duration


-------------------------------------------------------------------------
|                                                                       |
|       SOUND &FFxx - Speech System                                     |
|                                                                       |
-------------------------------------------------------------------------
; On entry, control block pointed to by &F0/1
;           Y=1 on entry
; XY +0  Channel - &FFxx - xx=Speech command
;     2  Word number/Address
;     4  Ignored
;     6  Ignored

E88D	PHP         ; Save flags
E88E	INY         ; Y=2
E88F	LDA (&F0),Y ; Get word number low byte
E891	PHA         ;  and stack it
E892	INY         ; Y=3
E893	LDA (&F0),Y ; Get word number high byte
E895	PHA         ;  and stack it
E896	LDY #&00    ; Y=0
E898	LDA (&F0),Y ; Get speech command
E89A	LDX #&08    ; X=8 for Speech buffer
E89C	JSR &E1F8   ; Insert speech command into speech buffer
E89F	BCS &E869   ; Buffer full, drop stack and abandon
E8A1	ROR &02D7   ; Clear bit 7 of speech buffer busy flag

; Insert two bytes into buffer
;
E8A4	PLA         ; Get word number high byte or pitch back
E8A5	JSR &E4B0   ; Insert into speech buffer
E8A8	PLA         ; Get word number low byte or duration back
E8A9	JSR &E4B0   ; Insert into speech buffer
E8AC	PLP         ; Restore flags
E8AD	RTS         ;  and return


*************************************************************************
*                                                                       *
*       OSWORD  08 - Define Envelope                                    *
*                                                                       *
*************************************************************************
; On entry, control block pointed to by &F0/1
;           Y=0 on entry
;           A=envelope number from (&F0),0
;XY +0  Envelope number, also in A
;    1  bits 0-6 length of each step in centi-secsonds bit 7=0 auto repeat
;    2  change of Pitch per step (-128-+127) in section 1
;    3  change of Pitch per step (-128-+127) in section 2
;    4  change of Pitch per step (-128-+127) in section 3
;    5  number of steps in section 1 (0-255)
;    6  number of steps in section 2 (0-255)
;    7  number of steps in section 3 (0-255)
;    8  change of amplitude per step during attack  phase (-127 to +127)
;    9  change of amplitude per step during decay   phase (-127 to +127)
;   10  change of amplitude per step during sustain phase (-127 to +127)
;   11  change of amplitude per step during release phase (-127 to +127)
;   12  target level at end of attack phase   (0-126)
;   13  target level at end of decay  phase   (0-126)

E8AE	SBC #&01    ;set up appropriate displacement to storage area
E8B0	ASL         ;A=(A-1)*16 or 15
E8B1	ASL         ;
E8B2	ASL         ;
E8B3	ASL         ;
E8B4	ORA #&0F    ;
E8B6	TAX         ;X=A
E8B7	LDA #&00    ;A=0

E8B9	LDY #&10    ;Y=&10

E8BB	CPY #&0E    ;is Y>=14??
E8BD	BCS &E8C1   ;yes then E8C1
E8BF	LDA (&F0),Y ;else get byte from parameter block
E8C1	STA &08C0,X ;and store it in appropriate area
E8C4	DEX         ;decrement X
E8C5	DEY         ;Decrement Y
E8C6	BNE &E8BB   ;if not 0 then do it again
E8C8	RTS         ;else exit
    	            ;note that envelope number is NOT transferred
;
E8C9	LDA (&F0),Y ;get byte
E8CB	CMP #&10    ;is it greater than 15, if so set carry
E8CD	AND #&03    ;and 3 to clear bits 2-7
E8CF	INY         ;increment Y
E8D0	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSWORD  03   ENTRY POINT                                        *
*                                                                       *
*       read interval timer                                             *
*                                                                       *
*************************************************************************
F0/1 points to block to store data

E8D1	LDX #&0F    ;X=&F displacement from clock to timer
E8D3	BNE &E8D8   ;jump to E8D8


*************************************************************************
*                                                                       *
*       OSWORD  01   ENTRY POINT                                        *
*                                                                       *
*       read system clock                                               *
*                                                                       *
*************************************************************************
F0/1 points to block to store data


E8D5	LDX &0283   ;X=current system clock store pointer

E8D8	LDY #&04    ;Y=4
E8DA	LDA &028D,X ;read byte
E8DD	STA (&F0),Y ;store it in parameter block
E8DF	INX         ;X=x+1
E8E0	DEY         ;Y=Y-1
E8E1	BPL &E8DA   ;if Y>0 then do it again
E8E3	RTS         ;else exit




*************************************************************************
*                                                                       *
*       OSWORD  04   ENTRY POINT                                        *
*                                                                       *
*       write interval timer                                            *
*                                                                       *
*************************************************************************
F0/1 points to block to store data


E8E4	LDA #&0F    ;offset between clock and timer
E8E6	BNE &E8EE   ;jump to E8EE ALWAYS!!


*************************************************************************
*                                                                       *
*       OSWORD  02   ENTRY POINT                                        *
*                                                                       *
*       write system clock                                              *
*                                                                       *
*************************************************************************
F0/1 points to block to store data

E8E8	LDA &0283   ;get current clock store pointer
E8EB	EOR #&0F    ;and invert to get inactive timer
E8ED	CLC         ;clear carry

E8EE	PHA         ;store A
E8EF	TAX         ;X=A
E8F0	LDY #&04    ;Y=4
E8F2	LDA (&F0),Y ;and transfer all 5 bytes
E8F4	STA &028D,X ;to the clock or timer
E8F7	INX         ;
E8F8	DEY         ;
E8F9	BPL &E8F2   ;if Y>0 then E8F2
E8FB	PLA         ;get back stack
E8FC	BCS &E8E3   ;if set (write to timer) E8E3 exit
E8FE	STA &0283   ;write back current clock store
E901	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSWORD  00   ENTRY POINT                                        *
*                                                                       *
*       read line from current input to memory                          *
*                                                                       *
*************************************************************************
;F0/1 points to parameter block
;   	+0/1    buffer address for input
;   	+2  Maximum line length
;   	+3  minimum acceptable ASCII value
;   	+4  maximum acceptable ASCII value

E902	LDY #&04    ;Y=4

E904	LDA (&F0),Y ;transfer bytes 4,3,2 to 2B3-2B5
E906	STA &02B1,Y ;
E909	DEY         ;decrement Y
E90A	CPY #&02    ;until Y=1
E90C	BCS &E904   ;

E90E	LDA (&F0),Y ;get address of input buffer
E910	STA &E9     ;store it in &E9 as temporary buffer
E912	DEY         ;decrement Y
E913	STY &0269   ;Y=0 store in print line counter for paged mode
E916	LDA (&F0),Y ;get lo byte of address
E918	STA &E8     ;and store in &E8
E91A	CLI         ;allow interrupts
E91B	BCC &E924   ;Jump to E924

E91D	LDA #&07    ;A=7
E91F	DEY         ;decrement Y
E920	INY         ;increment Y
E921	JSR OSWRCH  ;and call OSWRCH

E924	JSR OSRDCH  ;else read character  from input stream
E927	BCS &E972   ;if carry set then illegal character or other error
    	            ;exit via E972
E929	TAX         ;X=A
E92A	LDA &027C   ;A=&27C get character destination status
E92D	ROR         ;put VDU driver bit in carry
E92E	ROR         ;if this is 1 VDU driver is disabled
E92F	TXA         ;X=A
E930	BCS &E937   ;if Carry set E937
E932	LDX &026A   ;get number of items in VDU queque
E935	BNE &E921   ;if not 0 output character and loop round again

E937	CMP #&7F    ;if character is not delete
E939	BNE &E942   ;goto E942
E93B	CPY #&00    ;else is Y=0
E93D	BEQ &E924   ;and goto E924
E93F	DEY         ;decrement Y
E940	BCS &E921   ;and if carry set E921 to output it
E942	CMP #&15    ;is it delete line &21
E944	BNE &E953   ;if not E953
E946	TYA         ;else Y=A, if its 0 we are still reading first
    	            ;character
E947	BEQ &E924   ;so E924
E949	LDA #&7F    ;else output DELETES

E94B	JSR OSWRCH  ;until Y=0
E94E	DEY         ;
E94F	BNE &E94B   ;

E951	BEQ &E924   ;then read character again

E953	STA (&E8),Y ;store character in designated buffer
E955	CMP #&0D    ;is it CR?
E957	BEQ &E96C   ;if so E96C
E959	CPY &02B3   ;else check the line length
E95C	BCS &E91D   ;if = or greater loop to ring bell
E95E	CMP &02B4   ;check minimum character
E961	BCC &E91F   ;if less than minimum backspace
E963	CMP &02B5   ;check maximum character
E966	BEQ &E920   ;if equal E920
E968	BCC &E920   ;or less E920
E96A	BCS &E91F   ;then JUMP E91F

E96C	JSR OSNEWL  ;output CR/LF
E96F	JSR &E57E   ;call Econet vector

E972	LDA &FF     ;A=ESCAPE FLAG
E974	ROL         ;put bit 7 into carry
E975	RTS         ;and exit routine


*************************************************************************
*                                                                       *
*       OSBYTE  05   ENTRY POINT                                        *
*                                                                       *
*       SELECT PRINTER TYPE                                             *
*                                                                       *
*************************************************************************

E976	CLI         ;allow interrupts briefly
E977	SEI         ;bar interrupts
E978	BIT &FF     ;check if ESCAPE is pending
E97A	BMI &E9AC   ;if it is E9AC
E97C	BIT &02D2   ;else check bit 7 buffer 3 (printer)
E97F	BPL &E976   ;if not empty bit 7=0 E976

E981	JSR &E1A4   ;check for user defined routine
E984	LDY #&00    ;Y=0
E986	STY &F1     ;F1=0


*************************************************************************
*                                                                       *
*       OSBYTE  01   ENTRY POINT                                        *
*                                                                       *
*       READ/WRITE USER FLAG (&281)                                     *
*                                                                       *
*          AND                                                          *
*                                                                       *
*       OSBYTE  06   ENTRY POINT                                        *
*                                                                       *
*       SET PRINTER IGNORE CHARACTER                                    *
*                                                                       *
*************************************************************************
; A contains osbyte number


E988	ORA #&F0    ;A=osbyte +&F0
E98A	BNE &E99A   ;JUMP to E99A


*************************************************************************
*                                                                       *
*       OSBYTE  0C   ENTRY POINT                                        *
*                                                                       *
*       SET  KEYBOARD AUTOREPEAT RATE                                   *
*                                                                       *
*************************************************************************

E98C	BNE &E995   ;if &F0<>0 goto E995
E98E	LDX #&32    ;if X=0 in original call then X=32
E990	STX &0254   ;to set keyboard autorepeat delay ram copy
E993	LDX #&08    ;X=8


*************************************************************************
*                                                                       *
*       OSBYTE  0B   ENTRY POINT                                        *
*                                                                       *
*       SET  KEYBOARD AUTOREPEAT DELAY                                  *
*                                                                       *
*************************************************************************

E995	ADC #&CF    ;A=A+&D0 (carry set)


*************************************************************************
*                                                                       *
*       OSBYTE  03   ENTRY POINT                                        *
*                                                                       *
*       SELECT OUTPUT STREAM                                            *
*                                                                       *
*               AND                                                     *
*                                                                       *
*                                                                       *
*       OSBYTE  04   ENTRY POINT                                        *
*                                                                       *
*       ENABLE/DISABLE CURSOR EDITING                                   *
*                                                                       *
*************************************************************************

E997	CLC         ;c,ear carry
E998	ADC #&E9    ;A=A+&E9

E99A	STX &F0     ;store X


*************************************************************************
*                                                                       *
*       OSBYTE  A6-FF   ENTRY POINT                                     *
*                                                                       *
*       READ/ WRITE SYSTEM VARIABLE OSBYTE NO. +&190                    *
*                                                                       *
*************************************************************************


E99C	TAY         ;Y=A
E99D	LDA &0190,Y ;i.e. A=&190 +osbyte call!
E9A0	TAX         ;preserve this
E9A1	AND &F1     ;new value = OLD value AND Y EOR X!
E9A3	EOR &F0     ;
E9A5	STA &0190,Y ;store it
E9A8	LDA &0191,Y ;get value of next byte into A
E9AB	TAY         ;Y=A
E9AC	RTS         ;and exit


******* SERIAL BAUD RATE LOOK UP TABLE ************************************

E9AD	DB  &64     ; % 01100100      75
E9AE	DB  &7F     ; % 01111111     150
E9AF	DB  &5B     ; % 01011011     300
E9B0	DB  &6D     ; % 01101101    1200
E9B1	DB  &C9     ; % 11001001    2400
E9B2	DB  &F6     ; % 11110110    4800
E9B3	DB  &D2     ; % 11010010    9600
E9B4	DB  &E4     ; % 11100100   19200
E9B5	DB  &40     ; % 01000000



*************************************************************************
*                                                                       *
*       OSBYTE  &13   ENTRY POINT                                       *
*                                                                       *
*       Wait for VSync                                                  *
*                                                                       *
*************************************************************************

E9B6	LDA &0240   ;read vertical sync counter
E9B9	CLI         ;allow interrupts briefly
E9BA	SEI         ;bar interrupts
E9BB	CMP &0240   ;has it changed?
E9BE	BEQ &E9B9   ;no then E9B9
; falls through and reads VDU variable X

*************************************************************************
*                                                                       *
*       OSBYTE  160   ENTRY POINT                                       *
*                                                                       *
*       READ VDU VARIABLE                                               *
*                                                                       *
*************************************************************************
;X contains the variable number
;0 =lefthand column in pixels current graphics window
;2 =Bottom row in pixels current graphics window
;4 =Right hand column in pixels current graphics window
;6 =Top row in pixels current graphics window
;8 =lefthand column in absolute characters current text window
;9 =Bottom row in absolute characters current text window
;10 =Right hand column in absolute characters current text window
;11 =Top row in absolute characters current text window
;12-15 current graphics origin in external coordinates
;16-19 current graphics cursor in external coordina4es
;20-23 old graphics cursor in internal coordinates
;24 current text cursor in X and Y

E9C0	LDY &0301,X ;get VDU variable hi
E9C3	LDA &0300,X ;low
E9C6	TAX         ;X=low byte
E9C7	RTS         ;and exit


*************************************************************************
*                                                                       *
*       OSBYTE  18   ENTRY POINT                                        *
*                                                                       *
*       RESET SOFT KEYS                                                 *
*                                                                       *
*************************************************************************

E9C8	LDA #&10    ;set consistency flag
E9CA	STA &0284   ;

E9CD	LDX #&00    ;X=0

E9CF	STA &0B00,X ;and wipe clean
E9D2	INX         ;soft key buffer
E9D3	BNE &E9CF   ;until X=0 again

E9D5	STX &0284   ;zero consistency flag
E9D8	RTS         ;and exit


*************************************************************************
*                                                                       *
*        OSBYTE &76 (118) SET LEDs to Keyboard Status                   *
*                                                                       *
*************************************************************************

    	            ;osbyte entry with carry set
    	            ;called from &CB0E, &CAE3, &DB8B
    	
E9D9	PHP         ;PUSH P
E9DA	SEI         ;DISABLE INTERUPTS
E9DB	LDA #&40    ;switch on CAPS and SHIFT lock lights
E9DD	JSR &E9EA   ;via subroutine
E9E0	BMI &E9E7   ;if ESCAPE exists (M set) E9E7
E9E2	CLC         ;else clear V and C
E9E3	CLV         ;before calling main keyboard routine to
E9E4	JSR &F068   ;switch on lights as required
E9E7	PLP         ;get back flags
E9E8	ROL         ;and rotate carry into bit 0
E9E9	RTS         ;Return to calling routine
    	            ;
***************** Turn on keyboard lights and Test Escape flag ************
    	            ;called from &E1FE, &E9DD
    	            ;
E9EA	BCC &E9F5   ;if carry clear
E9EC	LDY #&07    ;switch on shift lock light
E9EE	STY &FE40   ;
E9F1	DEY         ;Y=6
E9F2	STY &FE40   ;switch on Caps lock light
E9F5	BIT &FF     ;set minus flag if bit 7 of &00FF is set indicating
E9F7	RTS         ;that ESCAPE condition exists, then return
    	            ;
****************** Write A to SYSTEM VIA register B *************************
    	            ;called from &CB6D, &CB73
E9F8	PHP         ;push flags
E9F9	SEI         ;disable interupts
E9FA	STA &FE40   ;write register B from Accumulator
E9FD	PLP         ;get back flags
E9FE	RTS         ;and exit
    	            ;


*************************************************************************
*                                                                       *
*       OSBYTE 154 (&9A) SET VIDEO ULA                                  *
*                                                                       *
*************************************************************************

E9FF	TXA         ;osbyte entry! X transferred to A thence to

*******Set Video ULA control register **entry from VDU routines **************
    	            ;called from &CBA6, &DD37

EA00	PHP         ;save flags
EA01	SEI         ;disable interupts
EA02	STA &0248   ;save RAM copy of new parameter
EA05	STA &FE20   ;write to control register
EA08	LDA &0253   ;read  space count
EA0B	STA &0251   ;set flash counter to this value
EA0E	PLP         ;get back status
EA0F	RTS         ;and return


*************************************************************************
*                                                                       *
*        OSBYTE &9B (155) write to palette register                     *
*                                                                       *
*************************************************************************

    	    ;entry X contains value to write
EA10	TXA         ;A=X
EA11	EOR #&07    ;convert to palette format
EA13	PHP         ;
EA14	SEI         ;prevent interrupts
EA15	STA &0249   ;store as current palette setting
EA18	STA &FE21   ;store actual colour in register
EA1B	PLP         ;get back flags
EA1C	RTS         ;and exit
    	            ;


*************************************************************************
*       GSINIT  string initialisation                                   *
*       F2/3 points to string offset by Y                               *
*                                                                       *
*       ON EXIT                                                         *
*       Z flag set indicates null string,                               *
*       Y points to first non blank character                           *
*       A contains first non blank character                            *
*************************************************************************

EA1D	CLC         ;clear carry

EA1E	ROR &E4     ;Rotate moves carry to &E4
EA20	JSR &E03A   ;get character from text
EA23	INY         ;increment Y to point at next character
EA24	CMP #&22    ;check to see if its '"'
EA26	BEQ &EA2A   ;if so EA2A (carry set)
EA28	DEY         ;decrement Y
EA29	CLC         ;clear carry
EA2A	ROR &E4     ;move bit 7 to bit 6 and put carry in bit 7
EA2C	CMP #&0D    ;check to see if its CR to set Z
EA2E	RTS         ;and return


*************************************************************************
*       GSREAD  string read routine                                     *
*       F2/3 points to string offset by Y                               *
*                                                                       *
*************************************************************************
    	            ;
EA2F	LDA #&00    ;A=0
EA31	STA &E5     ;store A
EA33	LDA (&F2),Y ;read first character
EA35	CMP #&0D    ;is it CR
EA37	BNE &EA3F   ;if not goto EA3F
EA39	BIT &E4     ;if bit 7=1 no 2nd '"' found
EA3B	BMI &EA8F   ;goto EA8F
EA3D	BPL &EA5A   ;if not EA5A

EA3F	CMP #&20    ;is less than a space?
EA41	BCC &EA8F   ;goto EA8F
EA43	BNE &EA4B   ;if its not a space EA4B
EA45	BIT &E4     ;is bit 7 of &E4 =1
EA47	BMI &EA89   ;if so goto EA89
EA49	BVC &EA5A   ;if bit 6 = 0 EA5A
EA4B	CMP #&22    ;is it '"'
EA4D	BNE &EA5F   ;if not EA5F
EA4F	BIT &E4     ;if so and Bit 7 of &E4 =0 (no previous ")
EA51	BPL &EA89   ;then EA89
EA53	INY         ;else point at next character
EA54	LDA (&F2),Y ;get it
EA56	CMP #&22    ;is it '"'
EA58	BEQ &EA89   ;if so then EA89

EA5A	JSR &E03A   ;read a byte from text
EA5D	SEC         ;and return with
EA5E	RTS         ;carry set
    	            ;
EA5F	CMP #&7C    ;is it '|'
EA61	BNE &EA89   ;if not EA89
EA63	INY         ;if so increase Y to point to next character
EA64	LDA (&F2),Y ;get it
EA66	CMP #&7C    ;and compare it with '|' again
EA68	BEQ &EA89   ;if its '|' then EA89
EA6A	CMP #&22    ;else is it '"'
EA6C	BEQ &EA89   ;if so then EA89
EA6E	CMP #&21    ;is it !
EA70	BNE &EA77   ;if not then EA77
EA72	INY         ;increment Y again
EA73	LDA #&80    ;set bit 7
EA75	BNE &EA31   ;loop back to EA31 to set bit 7 in next CHR
EA77	CMP #&20    ;is it a space
EA79	BCC &EA8F   ;if less than EA8F Bad String Error
EA7B	CMP #&3F    ;is it '?'
EA7D	BEQ &EA87   ;if so EA87
EA7F	JSR &EABF   ;else modify code as if CTRL had been pressed
EA82	BIT &D9B7   ;if bit 6 set
EA85	BVS &EA8A   ;then EA8A
EA87	LDA #&7F    ;else set bits 0 to 6 in A

EA89	CLV         ;clear V
EA8A	INY         ;increment Y
EA8B	ORA &E5     ;
EA8D	CLC         ;clear carry
EA8E	RTS         ;Return
    	            ;
EA8F	BRK         ;
EA90	DB  &FD     ;error number
EA93	DB 'Bad String' ; message
EA9B	BRK         ;


************ Modify code as if SHIFT pressed *****************************

EA9C	CMP #&30    ;if A='0' skip routine
EA9E	BEQ &EABE   ;
EAA0	CMP #&40    ;if A='@' skip routine
EAA2	BEQ &EABE   ;
EAA4	BCC &EAB8   ;if A<'@' then EAB8
EAA6	CMP #&7F    ;else is it DELETE

EAA8	BEQ &EABE   ;if so skip routine
EAAA	BCS &EABC   ;if greater than &7F then toggle bit 4
EAAC	EOR #&30    ;reverse bits 4 and 5
EAAE	CMP #&6F    ;is it &6F (previously ' _' (&5F))
EAB0	BEQ &EAB6   ;goto EAB6
EAB2	CMP #&50    ;is it &50 (previously '`' (&60))
EAB4	BNE &EAB8   ;if not EAB8
EAB6	EOR #&1F    ;else continue to convert ` _
EAB8	CMP #&21    ;compare &21 '!'
EABA	BCC &EABE   ;if less than return
EABC	EOR #&10    ;else finish conversion by toggling bit 4
EABE	RTS         ;exit
    	            ;
    	            ;ASCII codes &00 &20 no change
    	            ;21-3F have bit 4 reverses (31-3F)
    	            ;41-5E A-Z have bit 5 reversed a-z
    	            ;5F & 60 are reversed
    	            ;61-7E bit 5 reversed a-z becomes A-Z
    	            ;DELETE unchanged
    	            ;&80+ has bit 4 changed


************** Implement CTRL codes *************************************


EABF	CMP #&7F    ;is it DEL
EAC1	BEQ &EAD1   ;if so ignore routine
EAC3	BCS &EAAC   ;if greater than &7F go to EAAC
EAC5	CMP #&60    ;if A<>'`'
EAC7	BNE &EACB   ;goto EACB
EAC9	LDA #&5F    ;if A=&60, A=&5F

EACB	CMP #&40    ;if A<&40
EACD	BCC &EAD1   ;goto EAD1  and return unchanged
EACF	AND #&1F    ;else zero bits 5 to 7
EAD1	RTS         ;return
    	            ;
EAD2	DB  '/!BOOT',&0D

\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EAD9 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EAD9
new file mode 100644
index 0000000..6682621
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EAD9
@@ -0,0 +1 @@
+OS SERIES 8
GEOFF COX

*************************************************************************
*                                                                       *
*        OSBYTE &F7 (247) INTERCEPT BREAK                               *
*                                                                       *
*************************************************************************

EAD9	LDA &0287   ;get BREAK vector code
EADC	EOR #&4C    ;produces 0 if JMP not in &287
EADE	BNE &EAF3   ;if not goto EAF3
EAE0	JMP &0287   ;else jump to user BREAK code


*************************************************************************
*                                                                       *
*        OSBYTE &90 (144)   *TV                                         *
*                                                                       *
*************************************************************************

    	    ;X=display delay
    	    ;Y=interlace flag

EAE3	LDA &0290   ;VDU vertical adjustment
EAE6	STX &0290   ;store new value
EAE9	TAX         ;put old value in X
EAEA	TYA         ;put interlace flag in A
EAEB	AND #&01    ;maximum value =1
EAED	LDY &0291   ;get old value into Y
EAF0	STA &0291   ;put new value into A
EAF3	RTS         ;and Exit


*************************************************************************
*                                                                       *
*        OSBYTE &93 (147)  WRITE TO FRED                                *
*                                                                       *
*************************************************************************

    	            ;X is offset within page
    	            ;Y is byte to write
EAF4	TYA         ;
EAF5	STA &FC00,X ;
EAF8	RTS         ;


*************************************************************************
*                                                                       *
*        OSBYTE &95 (149)  WRITE TO JIM                                 *
*                                                                       *
*************************************************************************

    	            ;X is offset within page
    	            ;Y is byte to write
    	            ;
EAF9	TYA         ;
EAFA	STA &FD00,X ;
EAFD	RTS         ;


*************************************************************************
*                                                                       *
*        OSBYTE &97 (151)  WRITE TO SHEILA                              *
*                                                                       *
*************************************************************************

    	            ;X is offset within page
    	            ;Y is byte to write

EAFE	TYA         ;
EAFF	STA &FE00,X ;
EB02	RTS         ;


****************** Silence a sound channel *******************************
    	            ;X=channel number

EB03	LDA #&04    ;mark end of release phase
EB05	STA &0808,X ;to channel X
EB08	LDA #&C0    ;load code for zero volume

****** if sound not disabled set sound generator volume ******************

EB0A	STA &0804,X ;store A to give basic sound level of Zero
EB0D	LDY &0262   ;get sound output/enable flag
EB10	BEQ &EB14   ;if sound enabled goto EB14
EB12	LDA #&C0    ;else load zero sound code
EB14	SEC         ;set carry
EB15	SBC #&40    ;subtract &40
EB17	LSR         ;divide by 8
EB18	LSR         ;to get into bits 0 - 3
EB19	LSR         ;
EB1A	EOR #&0F    ;invert bits 0-3
EB1C	ORA &EB3C,X ;get channel number into top nybble
EB1F	ORA #&10    ;

EB21	PHP         ;

EB22	SEI         ;disable interrupts
EB23	LDY #&FF    ;System VIA port A all outputs
EB25	STY &FE43   ;set
EB28	STA &FE4F   ;output A on port A
EB2B	INY         ;Y=0
EB2C	STY &FE40   ;enable sound chip
EB2F	LDY #&02    ;set and
EB31	DEY         ;execute short delay
EB32	BNE &EB31   ;
EB34	LDY #&08    ;then disable sound chip again
EB36	STY &FE40   ;
EB39	LDY #&04    ;set delay
EB3B	DEY         ;and loop delay
EB3C	BNE &EB3B   ;
EB3E	PLP         ;get back flags
EB3F	RTS         ;and exit

*******: Sound parameters look up table **********************************

EB40	DB  &E0,&C0,&A0,&80


EB44	JMP &EC59   ;just to allow relative branches in early part
    	            ;of sound interrupt routine


*************************************************************************
*                                                                       *
*       PROCESS SOUND INTERRUPT                                         *
*                                                                       *
*************************************************************************

EB47	LDA #&00    ;
EB49	STA &083B   ;zero number of channels on hold for sync
EB4C	LDA &0838   ;get number of channels required for sync
EB4F	BNE &EB57   ;if this <>0 then EB57
EB51	INC &083B   ;else number of chanels on hold for sync =1
EB54	DEC &0838   ;number of channels required for sync =255

EB57	LDX #&08    ;set loop counter
EB59	DEX         ;loop
EB5A	LDA &0800,X ;get value of &800 +offset (sound queue occupancy)
EB5D	BEQ &EB44   ;if 0 goto EC59 no sound this channel
EB5F	LDA &02CF,X ;else get buffer busy flag
EB62	BMI &EB69   ;if negative (buffer empty) goto EB69
EB64	LDA &0818,X ;else if duration count not zer0
EB67	BNE &EB6C   ;goto EB6C
EB69	JSR &EC6B   ;check and pick up new sound if required
EB6C	LDA &0818,X ;if duration count 0
EB6F	BEQ &EB84   ;goto EB84
EB71	CMP #&FF    ;else if it is &FF (infinite duration)
EB73	BEQ &EB87   ;go onto EB87
EB75	DEC &081C,X ;decrement 10 mS count
EB78	BNE &EB87   ;and if 0
EB7A	LDA #&05    ;reset to 5
EB7C	STA &081C,X ;to give 50 mSec delay
EB7F	DEC &0818,X ;and decrement main counter
EB82	BNE &EB87   ;if not zero then EB87
EB84	JSR &EC6B   ;else check and get nw sound
EB87	LDA &0824,X ;if step progress counter is 0 no envelope involved
EB8A	BEQ &EB91   ;so jump to EB91
EB8C	DEC &0824,X ;else decrement it
EB8F	BNE &EB44   ;and if not zero go on to EC59
EB91	LDY &0820,X ;get  envelope data offset from (8C0)
EB94	CPY #&FF    ;if 255 no envelope set so
EB96	BEQ &EB44   ;goto EC59
EB98	LDA &08C0,Y ;else get get step length
EB9B	AND #&7F    ;zero repeat bit
EB9D	STA &0824,X ;and store it
EBA0	LDA &0808,X ;get phase counter
EBA3	CMP #&04    ;if release phase completed
EBA5	BEQ &EC07   ;goto EC07
EBA7	LDA &0808,X ;else start new step by getting phase
EBAA	CLC         ;
EBAB	ADC &0820,X ;add it to interval multiplier
EBAE	TAY         ;transfer to Y
EBAF	LDA &08CB,Y ;and get target value base for envelope
EBB2	SEC         ;
EBB3	SBC #&3F    ;
EBB5	STA &083A   ;store modified number as current target amplitude
EBB8	LDA &08C7,Y ;get byte from envelope store
EBBB	STA &0839   ;store as current amplitude step
EBBE	LDA &0804,X ;get base volumelevel
EBC1	PHA         ;save it
EBC2	CLC         ;clear carry
EBC3	ADC &0839   ;add to current amplitude step
EBC6	BVC &EBCF   ;if no overflow
EBC8	ROL         ;double it Carry = bit 7
EBC9	LDA #&3F    ;if bit =1 A=&3F
EBCB	BCS &EBCF   ;into &EBCF
EBCD	EOR #&FF    ;else toggle bits (A=&C0)

    	            ;at this point the BASIC volume commands are converted
    	            ; &C0 (0) to &38 (-15) 3 times, In fact last 3 bits
    	            ;are ignored so &3F represents -15

EBCF	STA &0804,X ;store in current volume
EBD2	ROL         ;multiply by 2
EBD3	EOR &0804,X ;if bits 6 and 7 are equal
EBD6	BPL &EBE1   ;goto &EBE1
EBD8	LDA #&3F    ;if carry clear A=&3F (maximum)
EBDA	BCC &EBDE   ;or
EBDC	EOR #&FF    ;&C0 minimum

EBDE	STA &0804,X ;and this is stored in current volume

EBE1	DEC &0839   ;decrement amplitude change per step
EBE4	LDA &0804,X ;get volume again
EBE7	SEC         ;set carry
EBE8	SBC &083A   ;subtract target value
EBEB	EOR &0839   ;negative value undicates correct trend
EBEE	BMI &EBF9   ;so jump to next part
EBF0	LDA &083A   ;else enter new phase
EBF3	STA &0804,X ;
EBF6	INC &0808,X ;

EBF9	PLA         ;get the old volume level
EBFA	EOR &0804,X ;and compare with the old
EBFD	AND #&F8    ;
EBFF	BEQ &EC07   ;if they are the same goto EC07
EC01	LDA &0804,X ;else set new level
EC04	JSR &EB0A   ;via EB0A
EC07	LDA &0810,X ;get absolute pitch value
EC0A	CMP #&03    ;if it =3
EC0C	BEQ &EC59   ;skip rest of loop as all sections are finished
EC0E	LDA &0814,X ;else if 814,X is not 0 current section is not
    	            ;complete
EC11	BNE &EC3D   ;so EC3D
EC13	INC &0810,X ;else implement a section change
EC16	LDA &0810,X ;check if its complete
EC19	CMP #&03    ;if not
EC1B	BNE &EC2D   ;goto EC2D
EC1D	LDY &0820,X ;else set A from
EC20	LDA &08C0,Y ;&820 and &8C0 (first envelope byte)
EC23	BMI &EC59   ;if negative there is no repeat
EC25	LDA #&00    ;else restart section sequence
EC27	STA &0830,X ;
EC2A	STA &0810,X ;

EC2D	LDA &0810,X ;get number of steps in new section
EC30	CLC         ;
EC31	ADC &0820,X ;
EC34	TAY         ;
EC35	LDA &08C4,Y ;
EC38	STA &0814,X ;set in 814+X
EC3B	BEQ &EC59   ;and if 0 then EC59

EC3D	DEC &0814,X ;decrement
EC40	LDA &0820,X ;and pick up rate of pitch change
EC43	CLC         ;
EC44	ADC &0810,X ;
EC47	TAY         ;
EC48	LDA &08C1,Y ;
EC4B	CLC         ;
EC4C	ADC &0830,X ;add to rate of differential pitch change
EC4F	STA &0830,X ;and save it
EC52	CLC         ;
EC53	ADC &080C,X ;ad to base pitch
EC56	JSR &ED01   ;and set new pitch

EC59	CPX #&04    ;if X=4 (last channel)
EC5B	BEQ &EC6A   ;goto EC6A (RTS)
EC5D	JMP &EB59   ;else do loop again

EC60	LDX #&08    ;X=7 again
EC62	DEX         ;loop
EC63	JSR &ECA2   ;clear channel
EC66	CPX #&04    ;if not 4
EC68	BNE &EC62   ;do it again
EC6A	RTS         ;and return
    	            ;
EC6B	LDA &0808,X ;check for last channel
EC6E	CMP #&04    ;is it 4 (release complete)
EC70	BEQ &EC77   ;if so EC77
EC72	LDA #&03    ;else mark release in progress
EC74	STA &0808,X ;and store it
EC77	LDA &02CF,X ;is buffer not empty
EC7A	BEQ &EC90   ;if so EC90
EC7C	LDA #&00    ;else mark buffer not empty
EC7E	STA &02CF,X ;an store it

EC81	LDY #&04    ;loop counter
EC83	STA &082B,Y ;zero sync bytes
EC86	DEY         ;
EC87	BNE &EC83   ;until Y=0

EC89	STA &0818,X ;zero duration count
EC8C	DEY         ;and set sync count to
EC8D	STY &0838   ;&FF
EC90	LDA &0828,X ;get synchronising flag
EC93	BEQ &ECDB   ;if its 0 then ECDB
EC95	LDA &083B   ;else get number of channels on hold
EC98	BEQ &ECD0   ;if 0 then ECD0
EC9A	LDA #&00    ;else
EC9C	STA &0828,X ;zero note length interval
EC9F	JMP &ED98   ;and goto ED98

ECA2	JSR &EB03   ;silence the channel
ECA5	TYA         ;Y=0 A=Y
ECA6	STA &0818,X ;zero main count
ECA9	STA &02CF,X ;mark buffer not empty
ECAC	STA &0800,X ;mark channel dormant
ECAF	LDY #&03    ;loop counter
ECB1	STA &082C,Y ;zero sync flags
ECB4	DEY         ;
ECB5	BPL &ECB1   ;

ECB7	STY &0838   ;number of channels to &FF
ECBA	BMI &ED06   ;jump to ED06 ALWAYS

ECBC	PHP         ;save flags
ECBD	SEI         ;and disable interrupts
ECBE	LDA &0808,X ;check for end of release
ECC1	CMP #&04    ;
ECC3	BNE &ECCF   ;and if not found ECCF
ECC5	JSR &E45B   ;elseexamine buffer
ECC8	BCC &ECCF   ;if not empty ECCF
ECCA	LDA #&00    ;else mark channel dormant
ECCC	STA &0800,X ;
ECCF	PLP         ;get back flags

ECD0	LDY &0820,X ;if no envelope 820=&FF
ECD3	CPY #&FF    ;
ECD5	BNE &ECDA   ;then terminate sound
ECD7	JSR &EB03   ;via EB03
ECDA	RTS         ;else return
    	            ;


************ Synchronise sound routines **********************************

ECDB	JSR &E45B   ;examine buffer if empty carry set
ECDE	BCS &ECBC   ;
ECE0	AND #&03    ;else examine next word if>3 or 0
ECE2	BEQ &EC9F   ;goto ED98 (via EC9F)
ECE4	LDA &0838   ;else get synchronising count
ECE7	BEQ &ECFE   ;in 0 (complete) goto ECFE
ECE9	INC &0828,X ;else set sync flag
ECEC	BIT &0838   ;if 0838 is +ve S has already been set so
ECEF	BPL &ECFB   ;jump to ECFB
ECF1	JSR &E45B   ;else get first byte
ECF4	AND #&03    ;mask bits 0,1
ECF6	STA &0838   ;and store result
ECF9	BPL &ECFE   ;Jump to ECFE (ALWAYS!!)

ECFB	DEC &0838   ;decrement 0838
ECFE	JMP &ECD0   ;and silence the channel if envelope not in use


************ Pitch setting ***********************************************

ED01	CMP &082C,X ;If A=&82C,X then pitch is unchanged
ED04	BEQ &ECDA   ;then exit via ECDA
ED06	STA &082C,X ;store new pitch
ED09	CPX #&04    ;if X<>4 then not noise so
ED0B	BNE &ED16   ;jump to ED16


*********** Noise setting ************************************************

ED0D	AND #&0F    ;convert to chip format
ED0F	ORA &EB3C,X ;
ED12	PHP         ;save flags
ED13	JMP &ED95   ;and pass to chip control routine at EB22 via ED95


ED16	PHA         ;
ED17	AND #&03    ;
ED19	STA &083C   ;lose eigth tone surplus
ED1C	LDA #&00    ;
ED1E	STA &083D   ;
ED21	PLA         ;get back A
ED22	LSR         ;divide by 12
ED23	LSR         ;
ED24	CMP #&0C    ;
ED26	BCC &ED2F   ;
ED28	INC &083D   ;store result
ED2B	SBC #&0C    ;with remainder in A
ED2D	BNE &ED24   ;

    	            ;at this point 83D defines the Octave
    	            ;A the semitone within the octave
ED2F	TAY         ;Y=A
ED30	LDA &083D   ;get octave number into A
ED33	PHA         ;push it
ED34	LDA &EDFB,Y ;get byte from look up table
ED37	STA &083D   ;store it
ED3A	LDA &EE07,Y ;get byte from second table
ED3D	PHA         ;push it
ED3E	AND #&03    ;keep two LS bits only
ED40	STA &083E   ;save them
ED43	PLA         ;pull second table byte
ED44	LSR         ;push hi nybble into lo nybble
ED45	LSR         ;
ED46	LSR         ;
ED47	LSR         ;
ED48	STA &083F   ;store it
ED4B	LDA &083D   ;get back octave number
ED4E	LDY &083C   ;adjust for surplus eighth tones
ED51	BEQ &ED5F   ;
ED53	SEC         ;
ED54	SBC &083F   ;
ED57	BCS &ED5C   ;
ED59	DEC &083E   ;
ED5C	DEY         ;
ED5D	BNE &ED53   ;
ED5F	STA &083D   ;
ED62	PLA         ;
ED63	TAY         ;
ED64	BEQ &ED6F   ;
ED66	LSR &083E   ;
ED69	ROR &083D   ;
ED6C	DEY         ;
ED6D	BNE &ED66   ;
ED6F	LDA &083D   ;
ED72	CLC         ;
ED73	ADC &C43D,X ;
ED76	STA &083D   ;
ED79	BCC &ED7E   ;
ED7B	INC &083E   ;
ED7E	AND #&0F    ;
ED80	ORA &EB3C,X ;
ED83	PHP         ;push P
ED84	SEI         ;bar interrupts
ED85	JSR &EB21   ;set up chip access 1
ED88	LDA &083D   ;
ED8B	LSR &083E   ;
ED8E	ROR         ;
ED8F	LSR &083E   ;
ED92	ROR         ;
ED93	LSR         ;
ED94	LSR         ;
ED95	JMP &EB22   ;set up chip access 2 and return



**************** Pick up and interpret sound buffer data *****************

ED98	PHP         ;push flags
ED99	SEI         ;disable interrupts
ED9A	JSR &E460   ;read a byte from buffer
ED9D	PHA         ;push A
ED9E	AND #&04    ;isolate H bit
EDA0	BEQ &EDB7   ;if 0 then EDB7
EDA2	PLA         ;get back A
EDA3	LDY &0820,X ;if &820,X=&FF
EDA6	CPY #&FF    ;envelope is not in use
EDA8	BNE &EDAD   ;
EDAA	JSR &EB03   ;so call EB03 to silence channel

EDAD	JSR &E460   ;clear buffer of redundant data
EDB0	JSR &E460   ;and again
EDB3	PLP         ;get back flags
EDB4	JMP &EDF7   ;set main duration count using last byte from buffer

EDB7	PLA         ;get back A
EDB8	AND #&F8    ;zero bits 0-2
EDBA	ASL         ;put bit 7 into carry
EDBB	BCC &EDC8   ;if zero (envelope) jump to EDC8
EDBD	EOR #&FF    ;invert A
EDBF	LSR         ;shift right
EDC0	SEC         ;
EDC1	SBC #&40    ;subtract &40
EDC3	JSR &EB0A   ;and set volume
EDC6	LDA #&FF    ;A=&FF

EDC8	STA &0820,X ;get envelope no.-1 *16 into A
EDCB	LDA #&05    ;set duration sub-counter
EDCD	STA &081C,X ;
EDD0	LDA #&01    ;set phase counter
EDD2	STA &0824,X ;
EDD5	LDA #&00    ;set step counter
EDD7	STA &0814,X ;
EDDA	STA &0808,X ;and envelope phase
EDDD	STA &0830,X ;and pitch differential
EDE0	LDA #&FF    ;
EDE2	STA &0810,X ;set step count
EDE5	JSR &E460   ;read pitch
EDE8	STA &080C,X ;set it
EDEB	JSR &E460   ;read buffer
EDEE	PLP         ;
EDEF	PHA         ;save duration
EDF0	LDA &080C,X ;get back pitch value
EDF3	JSR &ED01   ;and set it
EDF6	PLA         ;get back duration
EDF7	STA &0818,X ;set it
EDFA	RTS         ;and return


********************* Pitch look up table 1*****************************
EDFB	    DB         &F0
EDFC	    DB         &B7
EDFD	    DB         &82
EDFE	    DB         &4F
EDFF	    DB         &20
EE00	    DB         &F3
EE01	    DB         &C8
EE02	    DB         &A0
EE03	    DB         &7B
EE04	    DB         &57
EE05	    DB         &35
EE06	    DB         &16


********************* Pitch look up table 2 *****************************

EE07	    DB         &E7
EE08	    DB         &D7
EE09	    DB         &CB
EE0A	    DB         &C3
EE0B	    DB         &B7
EE0C	    DB         &AA
EE0D	    DB         &A2
EE0E	    DB         &9A
EE0F	    DB         &92
EE10	    DB         &8A
EE11	    DB         &82
EE12	    DB         &7A

*********: set current filing system ROM/PHROM **************************
EE13	LDA #&EF    ;get ROM
EE15	STA &F5     ;store it
EE17	RTS         ;return



********** Get byte from data ROM ***************************************

EE18	LDX #&0D    ;X=13
EE1A	INC &F5     ;
EE1C	LDY &F5     ;get Rom
EE1E	BPL &EE59   ;if +ve it's a sideways ROM else it's a PHROM
EE20	LDX #&00    ;PHROM
EE22	STX &F7     ;set address pointer in PHROM
EE24	INX         ;
EE25	STX &F6     ;to 0001
EE27	JSR &EEBB   ;pass info to speech processor
EE2A	LDX #&03    ;X=3

EE2C	JSR &EE62   ;check for speech processor and output until
    	            ;it reports, read byte from ROM
EE2F	CMP &DF0C,X ;if A<> DF0C+X then EE18 (DF0C = (C))
EE32	BNE &EE18   ;
EE34	DEX         ;else decrement X
EE35	BPL &EE2C   ;and do it again
EE37	LDA #&3E    ;
EE39	STA &F6     ;get noe lo byte address
EE3B	JSR &EEBB   ;pass info to speech processor
EE3E	LDX #&FF    ;
EE40	JSR &EE62   ;check for speech proc. etc.
EE43	LDY #&08    ;
EE45	ASL         ;
EE46	ROR &F7,X   ;
EE48	DEY         ;
EE49	BNE &EE45   ;
EE4B	INX         ;
EE4C	BEQ &EE40   ;
EE4E	CLC         ;
EE4F	BCC &EEBB   ;


************ ROM SERVICE ************************************************

EE51	LDX #&0E    ;
EE53	LDY &F5     ;if Y is negative (PHROM)
EE55	BMI &EE62   ;GOTO EE62
EE57	LDY #&FF    ;else Y=255
EE59	PHP         ;push flags
EE5A	JSR &F168   ;offer paged rom service
EE5D	PLP         ;pull processor flags
EE5E    CMP #&01    ;if A>0  set carry
EE60	TYA         ;A=Y
EE61	RTS         ;return

********* PHROM SERVICE *************************************************
			 ;
EE62	PHP         ;push processor flags
EE63	SEI         ;disable interrupts
EE64	LDY #&10    ;Y=16
EE66	JSR &EE7F   ;call EE7F (osbyte 159 write to speech processor
EE69	LDY #&00    ;Y=0
EE6B	BEQ &EE84   ;Jump to EE84 (ALWAYS!!)



*************************************************************************
*                                                                       *
*       OSBYTE 158 read from speech processor                           *
*                                                                       *
*************************************************************************


EE6D	LDY #&00    ;Y=0 to set speech proc to read
EE6F	BEQ &EE82   ;jump to EE82 always

			 ;write A to speech processor as two nybbles

EE71	PHA         ;push A
EE72	JSR &EE7A   ;to write to speech processor
EE75	PLA         ;get back A
EE76	ROR         ;bring upper nybble to lower nybble
EE77	ROR         ;by rotate right
EE78	ROR         ;4 times
EE79	ROR         ;

EE7A	AND #&0F    ;Y=lo nybble A +&40
EE7C	ORA #&40    ;
EE7E	TAY         ;forming command for speech processor



*************************************************************************
*                                                                       *
*       OSBYTE 159 Write to speech processor                            *
*                                                                       *
*************************************************************************


;       on entry data or command in Y

EE7F	TYA         ;transfer command to A
EE80	LDY #&01    ;to set speech proc to write

			 ;if Y=0 read speech processor
			 ;if Y=1 write speech processor

EE82	PHP         ;push flags
EE83	SEI         ;disable interrupts
EE84	BIT &027B   ;test for prescence of speech processor
EE87	BPL &EEAA   ;if not there goto EEAA
EE89	PHA         ;else push A
EE8A	LDA &F075,Y ;
EE8D	STA &FE43   ;set DDRA of system VIA to give 8 bit input (Y=0)
			 ;or 8 bit output (Y=1)
EE90	PLA         ;get back A
EE91	STA &FE4F   ;and send to speech chip
EE94	LDA &F077,Y ;output Prt B of system VIA
EE97	STA &FE40   ;to select read or write (dependent on Y)
EE9A	BIT &FE40   ;loop until
EE9D	BMI &EE9A   ;speech proceessor reports ready (bit 7 Prt B=0)
EE9F	LDA &FE4F   ;read speech processor data if  input selected
EEA2	PHA         ;push A
EEA3	LDA &F079,Y ;reset speech
EEA6	STA &FE40   ;processor
EEA9	PLA         ;get back A

EEAA	PLP         ;get back flags
EEAB	TAY         ;transfer A to Y
EEAC	RTS         ;and exit routine
			 ;
EEAD	LDA &03CB   ;set rom displacement pointer
EEB0	STA &F6     ;in &F6
EEB2	LDA &03CC   ;
EEB5	STA &F7     ;And &F7
EEB7	LDA &F5     ;if F5 is +ve ROM is selected so
EEB9	BPL &EED9   ;goto EED9

EEBB	PHP         ;else push processor
EEBC	SEI         ;disable interrupts
EEBD	LDA &F6     ;get lo displacement
EEBF	JSR &EE71   ;pass two nyblles to speech proc.
EEC2	LDA &F5     ;&FA=&F5
EEC4	STA &FA     ;
EEC6	LDA &F7     ;get hi displacement value
EEC8	ROL         ;replace two most significant bits of A
EEC9	ROL         ;by 2 LSBs of &FA
EECA	LSR &FA     ;
EECC	ROR         ;
EECD	LSR &FA     ;
EECF	ROR         ;
EED0	JSR &EE71   ;pass two nybbles to speech processor
EED3	LDA &FA     ;FA has now been divided by 4 so pass
EED5	JSR &EE7A   ;lower nybble to speech proc.
EED8	PLP         ;get back flags
EED9	RTS         ;and Return
			 ;


\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EEDA b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EEDA
new file mode 100644
index 0000000..14e3c49
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/EEDA
@@ -0,0 +1 @@
+
************ Keyboard Input and housekeeping ************************
	 ;entered from &F00C

EEDA	LDX #&FF    ;
EEDC	LDA &EC     ;get value of most recently pressed key
EEDE	ORA &ED     ;Or it with previous key to check for presses
EEE0	BNE &EEE8   ;if A=0 no keys pressed so off you go
EEE2	LDA #&81    ;else enable keybd interupt only by writing bit 7
EEE4	STA &FE4E   ;and bit 0 of system VIA interupt register
EEE7	INX         ;set X=0
EEE8	STX &0242   ;reset keyboard semaphore


**********: Turn on Keyboard indicators *******************************
EEEB	PHP         ;save flags
EEEC	LDA &025A   ;read keyboard status;
			 ;Bit 7  =1 shift enabled
			 ;Bit 6  =1 control pressed
			 ;bit 5  =0 shift lock
			 ;Bit 4  =0 Caps lock
			 ;Bit 3  =1 shift pressed
EEEF	LSR         ;shift Caps bit into bit 3
EEF0	AND #&18    ;mask out all but 4 and 3
EEF2	ORA #&06    ;returns 6 if caps lock OFF &E if on
EEF4	STA &FE40   ;turn on or off caps light if required
EEF7	LSR         ;bring shift bit into bit 3
EEF8	ORA #&07    ;
EEFA	STA &FE40   ;turn on or off shift  lock light
EEFD	JSR &F12E   ;set keyboard counter
EF00	PLA         ;get back flags
EF01	RTS         ;return
			 ;


*************************************************************************
*                                                                       *
* MAIN KEYBOARD HANDLING ROUTINE   ENTRY FROM KEYV                      *
* ==========================================================            *
*                                                                       *
*                       ENTRY CONDITIONS                                *
*                       ================                                *
* C=0, V=0 Test Shift and CTRL keys.. exit with N set if CTRL pressed   *
*                                 ........with V set if Shift pressed   *
*                                                                       *
* C=1, V=0 Scan Keyboard as OSBYTE &79                                  *
*                                                                       *
* C=0, V=1 Key pressed interrupt entry                                  *
*                                                                       *
* C=1, V=1 Timer interrupt entry                                        *
*                                                                       *
*************************************************************************

EF02	BVC &EF0E   ;if V is clear then leave interrupt routine
EF04	LDA #&01    ;disable keyboard interrupts
EF06	STA &FE4E   ;by writing to VIA interrupt vector
EF09	BCS &EF13   ;if timer interrupt then EF13
EF0B	JMP &F00F   ;else to F00F

EF0E	BCC &EF16   ;if test SHFT & CTRL goto EF16
EF10	JMP &F0D1   ;else to F0D1
			 ;to scan keyboard
*************************************************************************
*       Timer interrupt entry                                           *
*************************************************************************

EF13	INC &0242   ;increment keyboard semaphore (to 0)


*************************************************************************
*       Test Shift and Control Keys entry                               *
*************************************************************************

EF16	LDA &025A   ;read keyboard status;
			 ;Bit 7  =1 shift enabled
			 ;Bit 6  =1 control pressed
			 ;bit 5  =0 shift lock
			 ;Bit 4  =0 Caps lock
			 ;Bit 3  =1 shift pressed
EF19	AND #&B7    ;zero bits 3 and 6
EF1B	LDX #&00    ;zero X to test for shift key press
EF1D	JSR &F02A   ;interrogate keyboard X=&80 if key determined by
			 ;X on entry is pressed
EF20	STX &FA     ;save X
EF22	CLV         ;clear V
EF23	BPL &EF2A   ;if no key press (X=0) then EF2A else
EF25	BIT &D9B7   ;set M and V
EF28	ORA #&08    ;set bit 3 to indicate Shift was pressed
EF2A	INX         ;check the control key
EF2B	JSR &F02A   ;via keyboard interrogate
EF2E	BCC &EEEB   ;if carry clear (entry via EF16) then off to EEEB
			 ;to turn on keyboard lights as required
EF30	BPL &EF34   ;if key not pressed goto EF30
EF32	ORA #&40    ;or set CTRL pressed bit in keyboard status byte in A
EF34	STA &025A   ;save status byte
EF37	LDX &EC     ;if no key previously pressed
EF39	BEQ &EF4D   ;then EF4D
EF3B	JSR &F02A   ;else check to see if key still pressed
EF3E	BMI &EF50   ;if so enter repeat routine at EF50
EF40	CPX &EC     ;else compare X with last key pressed (set flags)
EF42	STX &EC     ;store X in last key pressed
EF44	BNE &EF4D   ;if different from previous (Z clear) then EF4D
EF46	LDX #&00    ;else zero
EF48	STX &EC     ;last key pressed
EF4A	JSR &F01F   ;and reset repeat system
EF4D	JMP &EFE9   ;


********** REPEAT ACTION *************************************************
EF50	CPX &EC     ;if X<>than last key pressed
EF52	BNE &EF42   ;then back to EF42
EF54	LDA &E7     ;else get value of AUTO REPEAT COUNTDOWN TIMER
EF56	BEQ &EF7B   ;if 0 goto EF7B
EF58	DEC &E7     ;else decrement
EF5A	BNE &EF7B   ;and if not 0 goto EF7B
			 ;this means that either the repeat system is dormant
			 ;or it is not at the end of its count
EF5C	LDA &02CA   ;next value for countdown timer
EF5F	STA &E7     ;store it
EF61	LDA &0255   ;get auto repeat rate from 0255
EF64	STA &02CA   ;store it as next value for Countdown timer
EF67	LDA &025A   ;get keyboard status
EF6A	LDX &EC     ;get last key pressed
EF6C	CPX #&D0    ;if not SHIFT LOCK key (&D0) goto
EF6E	BNE &EF7E   ;EF7E
EF70	ORA #&90    ;sets shift enabled, & no caps lock all else preserved
EF72	EOR #&A0    ;reverses shift lock disables Caps lock and Shift enab
EF74	STA &025A   ;reset keyboard status
EF77	LDA #&00    ;and set timer
EF79	STA &E7     ;to 0
EF7B	JMP &EFE9   ;

EF7E	CPX #&C0    ;if not CAPS LOCK
EF80	BNE &EF91   ;goto EF91
EF82	ORA #&A0    ;sets shift enabled and disables SHIFT LOCK
EF84	BIT &FA     ;if bit 7 not set by (EF20) shift NOT pressed
EF86	BPL &EF8C   ;goto EF8C
EF88	ORA #&10    ;else set CAPS LOCK not enabled
EF8A	EOR #&80    ;reverse SHIFT enabled

EF8C	EOR #&90    ;reverse both SHIFT enabled and CAPs Lock
EF8E	JMP &EF74   ;reset keyboard status and set timer


*********** get ASCII code *********************************************
	 ;on entry X=key pressed internal number

EF91	LDA &EFAB,X ;get code from look up table
EF94	BNE &EF99   ;if not zero goto EF99 else TAB pressed
EF96	LDA &026B   ;get TAB character

EF99	LDX &025A   ;get keyboard status
EF9C	STX &FA     ;store it in &FA
EF9E	ROL &FA     ;rotate to get CTRL pressed into bit 7
EFA0	BPL &EFA9   ;if CTRL NOT pressed EFA9

EFA2	LDX &ED     ;get no. of previously pressed key
EFA4	BNE &EF4A   ;if not 0 goto EF4A to reset repeat system etc.
EFA6	JSR &EABF   ;else perform code changes for CTRL

EFA9	ROL &FA     ;move shift lock into bit 7
EFAB	BMI &EFB5   ;if not effective goto EFB5 else
EFAD	JSR &EA9C   ;make code changes for SHIFT

EFB0	ROL &FA     ;move CAPS LOCK into bit 7
EFB2	JMP &EFC1   ;and Jump to EFC1

EFB5	ROL &FA     ;move CAPS LOCK into bit 7
EFB7	BMI &EFC6   ;if not effective goto EFC6
EFB9	JSR &E4E3   ;else make changes for CAPS LOCK on, return with
			 ;C clear for Alphabetic codes
EFBC	BCS &EFC6   ;if carry set goto EFC6 else make changes for
EFBE	JSR &EA9C   ;SHIFT as above

EFC1	LDX &025A   ;if shift enabled bit is clear
EFC4	BPL &EFD1   ;goto EFD1
EFC6	ROL &FA     ;else get shift bit into 7
EFC8	BPL &EFD1   ;if not set goto EFD1
EFC8	BPL &EFD1   ;if not set goto EFD1
EFCA	LDX &ED     ;get previous key press
EFCC	BNE &EFA4   ;if not 0 reset repeat system etc. via EFA4
EFCE	JSR &EA9C   ;else make code changes for SHIFT
EFD1	CMP &026C   ;if A<> ESCAPE code
EFD4	BNE &EFDD   ;goto EFDD
EFD6	LDX &0275   ;get Escape key status
EFD9	BNE &EFDD   ;if ESCAPE returns ASCII code goto EFDD
EFDB	STX &E7     ;store in Auto repeat countdown timer

EFDD	TAY         ;
EFDE	JSR &F129   ;disable keyboard
EFE1	LDA &0259   ;read Keyboard disable flag used by Econet
EFE4	BNE &EFE9   ;if keyboard locked goto EFE9
EFE6	JSR &E4F1   ;put character in input buffer
EFE9	LDX &ED     ;get previous keypress
EFEB	BEQ &EFF8   ;if none  EFF8
EFED	JSR &F02A   ;examine to see if key still pressed
EFF0	STX &ED     ;store result
EFF2	BMI &EFF8   ;if pressed goto EFF8
EFF4	LDX #&00    ;else zero X
EFF6	STX &ED     ;and &ED

EFF8	LDX &ED     ;get &ED
EFFA	BNE &F012   ;if not 0 goto F012
EFFC	LDY #&EC    ;get first keypress into Y
EFFE	JSR &F0CC   ;scan keyboard from &10 (osbyte 122)

F001	BMI &F00C   ;if exit is negative goto F00C
F003	LDA &EC     ;else make last key the
F005	STA &ED     ;first key pressed i.e. rollover

F007	STX &EC     ;save X into &EC
F009	JSR &F01F   ;set keyboard repeat delay
F00C	JMP &EEDA   ;go back to EEDA


*************************************************************************
*   Key pressed interrupt entry point                                   *
*************************************************************************
			 ;enters with X=key
F00F	JSR &F02A   ;check if key pressed

F012	LDA &EC     ;get previous key press
F014	BNE &F00C   ;if none back to housekeeping routine
F016	LDY #&ED    ;get last keypress into Y
F018	JSR &F0CC   ;and scan keyboard
F01B	BMI &F00C   ;if negative on exit back to housekeeping
F01D	BPL &F007   ;else back to store X and reset keyboard delay etc.


**************** Set Autorepeat countdown timer **************************

F01F	LDX #&01    ;set timer to 1
F021	STX &E7     ;
F023	LDX &0254   ;get next timer value
F026	STX &02CA   ;and store it
F029	RTS         ;


*************** Interrogate Keyboard routine ***********************
			 ;
F02A	LDY #&03    ;stop Auto scan
F02C	STY &FE40   ;by writing to system VIA
F02F	LDY #&7F    ;set bits 0 to 6 of port A to input on bit 7
			 ;output on bits 0 to 6
F031	STY &FE43   ;
F034	STX &FE4F   ;write X to Port A system VIA
F037	LDX &FE4F   ;read back &80 if key pressed (M set)
F03A	RTS         ;and return


*************************************************************************
*                                                                       *
*       KEY TRANSLATION TABLES                                          *
*                                                                       *
*       7 BLOCKS interspersed with unrelated code                       *
*************************************************************************

*key data block 1

F03B	DB  71,33,34,35,84,38,87,2D,5E,8C
	 ;       q ,3 ,4 ,5 ,f4,8 ,f7,- ,^ ,rt



*************************************************************************
*                                                                       *
*       OSBYTE 120  Write KEY pressed Data                              *
*                                                                       *
*************************************************************************


F045	STY &EC     ;store Y as latest key pressed
F047	STX &ED     ;store X as previous key pressed
F049	RTS         ;and exit

*key data block 2

F04A	DB  80,77,65,74,37,69,39,30,5F,8E
	 ;       f0,w ,e ,t ,7 ,i ,9 ,0 ,_ ,lft

F055	JMP (&FDFE) ;Jim paged entry vector
F058	JMP (&FA)   ;

*key data block 3

F05A	DB  31,32,64,72,36,75,6F,70,5B,8F
	 ;       1 ,2 ,d ,r ,6 ,u ,o ,p ,[ ,dn


*************************************************************************
*                                                                       *
* Main entry to keyboard routines                                       *
*                                                                       *
*************************************************************************

F065	BIT &D9B7   ;set V and M
F068	JMP (&0228) ;i.e. KEYV

*key data block 4

F06B	DB  01,61,78,66,79,6A,6B,40,3A,0D
	 ;       CL,a ,x ,f ,y ,j ,k ,@ ,: ,RETN  N.B CL=CAPS LOCK

*speech routine data
F075	DB  00,FF,01,02,09,0A

*key data block 5

F07B	DB  02,73,63,67,68,6E,6C,3B,5D,7F
	 ;       SL,s ,c ,g ,h ,n ,l ,; ,] ,DEL N.B. SL=SHIFT LOCK



*************************************************************************
*                                                                       *
*       OSBYTE 131  READ OSHWM  (PAGE in BASIC)                         *
*                                                                       *
*************************************************************************


F085	LDY &0244 ;read current OSHWM
F088	LDX #&00    ;
F08A	RTS         ;

*key data block 6

F08B	DB          00 ,7A,20   ,76,62,6D,2C,2E,2F,8B
	 ;               TAB,Z ,SPACE,V ,b ,m ,, ,. ,/ ,copy

***** set input buffer number and flush it *****************************

F095	LDX &0241   ;get current input buffer
F098	JMP &E1AD   ;flush it

*key data block 7

F09B	DB  1B,81,82,83,85,86,88,89,5C,8D
	 ;      ESC,f1,f2,f3,f5,f6,f8,f9,\ ,


F0A5	JMP (&0220) ;goto eventV handling routine




*************************************************************************
*                                                                       *
*       OSBYTE 15  FLUSH SELECTED BUFFER CLASS                          *
*                                                                       *
*************************************************************************

			 ;flush selected buffer
			 ;X=0 flush all buffers
			 ;X>1 flush input buffer

F0A8	BNE &F095   ;if X<>1 flush input buffer only
F0AA	LDX #&08    ;else load highest buffer number (8)
F0AC	CLI         ;allow interrupts
F0AD	SEI         ;briefly!
F0AE	JSR &F0B4   ;flush buffer
F0B1	DEX         ;decrement X to point at next buffer
F0B2	BPL &F0AC   ;if X>=0 flush next buffer
			 ;at this point X=255


*************************************************************************
*                                                                       *
*       OSBYTE 21  FLUSH SPECIFIC BUFFER                                *
*                                                                       *
*************************************************************************
;on entry X=buffer number

F0B4	CPX #&09    ;is X<9?
F0B6	BCC &F098   ;if so flush buffer or else
F0B8	RTS         ;exit
			 ;
*************************************************************************
*                                                                       *
*               Issue *HELP to ROMS                                     *
*                                                                       *
*************************************************************************
F0B9	LDX #&09    ;
F0BB	JSR &F168   ;
F0BE	JSR &FA4A   ;print following message routine return after BRK
F0C1	DB  &0D     ;carriage return
F0C2	DS  'OS 1.20' ;help message
F0C9	DB  &0D     ;carriage return
F0CA	BRK         ;
F0CB	RTS         ;


*************************************************************************
*                                                                       *
*       OSBYTE 122  KEYBOARD SCAN FROM &10 (16)                         *
*                                                                       *
*************************************************************************

    	            ;
F0CC	CLC         ;clear carry
F0CD	LDX #&10    ;set X to 10
    	            ;


*************************************************************************
*                                                                       *
*       OSBYTE 121  KEYBOARD SCAN FROM VALUE IN X                       *
*                                                                       *
*************************************************************************

F0CF	BCS &F068   ;if carry set (by osbyte 121) F068
    	            ;Jmps via KEYV and hence back to;


*************************************************************************
*        Scan Keyboard C=1, V=0 entry via KEYV                          *
*************************************************************************

F0D1	TXA         ;if X is +ve goto F0D9
F0D2	BPL &F0D9   ;
F0D4	JSR &F02A   ;else interrogate keyboard
F0D7	BCS &F12E   ;if carry set F12E to set Auto scan else
F0D9	PHP         ;push flags
F0DA	BCC &F0DE   ;if carry clear goto FODE else
F0DC	LDY #&EE    ;set Y so next operation saves to 2cd
F0DE	STA &01DF,Y ;can be 2cb,2cc or 2cd
F0E1	LDX #&09    ;set X to 9
F0E3	JSR &F129   ;select auto scan
F0E6	LDA #&7F    ;set port A for input on bit 7 others outputs
F0E8	STA &FE43   ;
F0EB	LDA #&03    ;stop auto scan
F0ED	STA &FE40   ;
F0F0	LDA #&0F    ;select non-existent keyboard column F (0-9 only!)
F0F2	STA &FE4F   ;
F0F5	LDA #&01    ;cancel keyboard interrupt
F0F7	STA &FE4D   ;
F0FA	STX &FE4F   ;select column X (9 max)
F0FD	BIT &FE4D   ;if bit 1 =0 there is no keyboard interrupt so
F100	BEQ &F123   ;goto F123
F102	TXA         ;else put column address in A

F103	CMP &01DF,Y ;compare with 1DF+Y
F106	BCC &F11E   ;if less then F11E
F108	STA &FE4F   ;else select column again
F10B	BIT &FE4F   ;and if bit 7 is 0
F10E	BPL &F11E   ;then F11E
F110	PLP         ;else push and pull flags
F111	PHP         ;
F112	BCS &F127   ;and if carry set goto F127
F114	PHA         ;else Push A
F115	EOR &0000,Y ;EOR with EC,ED, or EE depending on Y value
F118	ASL         ;shift left  
F119	CMP #&01    ;set carry if = or greater than number holds EC,ED,EE
F11B	PLA         ;get back A
F11C	BCS &F127   ;if carry set F127
F11E	CLC         ;else clear carry
F11F	ADC #&10    ;add 16
F121	BPL &F103   ;and do it again if 0=<result<128
F123	DEX         ;decrement X
F124	BPL &F0E3   ;scan again if greater than 0
F126	TXA         ;
F127	TAX         ;
F128	PLP         ;pull flags

F129	JSR &F12E   ;call autoscan
F12C	CLI         ;allow interrupts 
F12D	SEI         ;disable interrupts



*************Enable counter scan of keyboard columns *******************
    	            ;called from &EEFD, &F129

F12E	LDA #&0B    ;select auto scan of keyboard
F130	STA &FE40   ;tell VIA
F133	TXA         ;Get A into X
F134	RTS         ;and return


\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F135 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F135
new file mode 100644
index 0000000..11211c6
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F135
@@ -0,0 +1,549 @@
+OS SERIES 9
+GEOFF COX
+*************************************************************************
+*                                                                       *
+*       OSBYTE 140  *TAPE                                               *
+*       selects TAPE filing system                                      *
+*                                                                       *
+*       OSBYTE 141  *ROM                                                *
+*       selects ROM filing system                                       *
+*                                                                       *
+*************************************************************************
+
+F135	EOR #&8C    ;if it's *TAPE A=0 *ROM A=1
+F137	ASL         ;double it
+F138	STA &0247   ;store it in filing system flag store
+F13B	CPX #&03    ;if X>=3 C set X=3 Z set
+F13D	JMP &F14B   ;
+
+******** set cassette options *******************************************
+    	;called after BREAK etc
+    	;lower nybble sets sequential access
+    	;upper sets load and save options
+    	
+    	;0000   Ignore errors,          no messages
+    	;0001   Abort if error,         no messages
+    	;0010   Retry after error,      no messages
+    	;1000   Ignore error            short messages
+    	;1001   Abort if error          short messages
+    	;1010   Retry after error       short messages
+    	;1100   Ignore error            long messages
+    	;1101   Abort if error          long messages
+    	;1110   Retry after error       long messages
+
+
+F140	PHP         ;save flags
+F141	LDA #&A1    ;set sequential access abort if error, no messages
+F143	STA &E3     ;set load/save retry if error, short messages
+F145	LDA #&19    ;set interblock gap
+F147	STA &03D1   ;and store it
+F14A	PLP         ;get back flags
+
+F14B	PHP         ;push flags
+F14C	LDA #&06    ;get close files command to FSCV
+F14E	JSR &E031   ;and gosub OSFSC
+F151	LDX #&06    ;
+F153	PLP         ;get back flags
+F154	BEQ &F157   ;if Z set earlier
+F156	DEX         ;do not decrement X
+F157	STX &C6     ;set current baud rate X=5 300 baud X=6 1200 baud
+
+********* reset FILEV,ARGSV,BGETV,BPUTV,GBPBV,FINDV,FSCV ******************
+**********   to F27D, F18E, F4C9, F529, FFA6, F3CA, F1B1 ******************
+
+F159	LDX #&0E    ;RESET VECTORS FOR FILE RELATED OPERATIONS
+F15B	LDA &D951,X ;
+F15E	STA &0211,X ;
+F161	DEX         ;
+F162	BNE &F15B   ;
+
+F164	STX &C2     ;&C2=0 PROGRESS FLAG
+F166	LDX #&0F    ;set X to make Rom service call &F claim vectors!
+
+
+
+*************************************************************************
+*                                                                       *
+*       OSBYTE 143                                                      *
+*       Pass service commands to sideways ROMs                          *
+*                                                                       *
+*************************************************************************
+    	    ; On entry X=service call number
+    	    ;          Y=any additional parameter
+    	    ; On entry X=0 if claimed, or preserved if unclaimed
+    	    ;          Y=any returned parameter
+    	    ;          When called internally, EQ set if call claimed
+
+F168	LDA &F4     ; Get current ROM number
+F16A	PHA         ; Save it
+F16B	TXA         ; Pass service call number to  A
+F16C	LDX #&0F    ; Start at ROM 15
+
+    	            ; Issue service call loop
+F16E	INC &02A1,X ; Read bit 7 on ROM type table (no ROM has type 254 &FE)
+F171	DEC &02A1,X ;
+F174	BPL &F183   ; If not set (+ve result), step to next ROM down
+F176	STX &F4     ; Otherwise, select this ROM, &F4 RAM copy
+F178	STX &FE30   ; Page in selected ROM
+F17B	JSR &8003   ; Call the ROM's service entry
+    	            ; X and P do not need to be preserved by the ROM
+F17E	TAX         ; On exit pass A to X to chech if claimed
+F17F	BEQ &F186   ; If 0, service call claimed, reselect ROM and exit
+F181	LDX &F4     ; Otherwise, get current ROM back
+F183	DEX         ; Step to next ROM down
+F184	BPL &F16E   ; Loop until done ROM 0
+
+F186	PLA         ; Get back original ROM number
+F187	STA &F4     ; Set ROM number RAM copy
+F189	STA &FE30   ; Page in the original ROM
+F18C	TXA         ; Pass X back to A to set zero flag
+F18D	RTS         ; And return
+
+
+
+*************************************************************************
+*                                                                       *
+*       CFS OSARGS entry point                                          *
+*
+*************************************************************************
+
+F18E	ORA #&00    ;is A=00
+F190	BNE &F1A2   ;if not return
+F192	CPY #&00    ;is Y=0
+F194	BNE &F1A2   ;if not return
+F196	LDA &C6     ;else get current baud rate and zero bit 2
+F198	AND #&FB    ;C6=5 becomes 1, 6 becomes 2
+F19A	ORA &0247   ;if cassette selected A=0 else A=2
+F19D	ASL         ;multiply by 2
+F19E	ORA &0247   ;Or it again
+F1A1	LSR         ;divide by 2
+F1A2	RTS         ;return cassette =0
+    	
+*************************************************************************
+*                                                                       *
+*       FSC     VECTOR  TABLE                                           *
+*                                                                       *
+*************************************************************************
+
+F1A3	DB  4C,F5   ; *OPT            (F54C)
+F1A5	DB  1D,F6   ; check EOF       (F61D)
+F1A7	DB  04,F3   ; */              (F304)
+F1A9	DB  0F,E3   ; unknown command (E30F)
+F1AB	DB  04,F3   ; *RUN            (F304)
+F1AD	DB  2A,F3   ; *CAT            (F32A)
+F1AF	DB  74,E2   ; osbyte 77       (E274)
+
+
+*************************************************************************
+*       Filing System control entry     OSFSC                           *
+*       Entry via 021E FSCV                                             *
+*       A= index 0 to 7                                                 *
+*************************************************************************
+    	;on entry A is reason code
+    	;A=0    A *OPT command has been used X & Y are the 2 parameters
+    	;A=1    EOF is being checked, on entry  X=File handle
+    	                          on Exit X=FF = EOF exists else 00
+    	;A=2    A */ command has been used *RUN the file
+    	;A=3    An unrecognised OS command has ben used X,Y point at command
+    	;A=4    A *RUN command has been used X,Y point at filename
+    	;A=5    A *CAT cammand has been issued X,Y point to rest of command
+    	;A=6    New filing system about to take over, close SPOOL & EXEC files
+    	;A=7    Return in X and Y lowest and highest file handle used
+    	;A=8    OS about to process *command
+
+F1B1	CMP #&07    ;if A>6
+F1B3	BCS &F1A2   ;goto F1A2 (RTS)
+F1B5	STX &BC     ;else save X
+F1B7	ASL         ;A=A*2
+F1B8	TAX         ;X=A to get offset
+F1B9	LDA &F1A4,X ;get hi byte of address
+F1BC	PHA         ;push it
+F1BD	LDA &F1A3,X ;get lo byte of address
+F1C0	PHA         ;push it
+F1C1	LDX &BC     ;get back X
+F1C3	RTS         ;this now jumps to the address got from the table +1
+    	            ;the next RTS takes us back to CLI
+
+
+
+*************************************************************************
+*                                                                       *
+*       LOAD FILE                                                       *
+*                                                                       *
+*************************************************************************
+    	
+F1C4	PHP         ;save flags on stack
+F1C5	PHA         ;save A on stack
+F1C6	JSR &FB27   ;Set cassette optionsinto (BB),set C7=6
+    	            ;claim serial system for cassette
+F1C9	LDA &03C2   ;execution address LO
+F1CC	PHA         ;save A on stack
+F1CD	JSR &F631   ;search for file
+F1D0	PLA         ;get back A
+F1D1	BEQ &F1ED   ;if A=0 F1ED
+F1D3	LDX #&03    ;else X=3
+F1D5	LDA #&FF    ;A=&FF
+F1D7	PHA         ;save A on stack
+F1D8	LDA &03BE,X ;get load address
+F1DB	STA &B0,X   ;store it as current load address
+F1DD	PLA         ;get back A
+F1DE	AND &B0,X   ;
+F1E0	DEX         ;X=X-1
+F1E1	BPL &F1D7   ;until all 4 bytes copied
+
+F1E3	CMP #&FF    ;if all bytes contain don't contain &FF
+F1E5	BNE &F1ED   ;continue
+F1E7	JSR &FAE8   ;else sound bell, reset ACIA & motor off
+F1EA	JMP &E267   ;'Bad Address' error
+
+F1ED	LDA &03CA   ;block flag
+F1F0	LSR         ;set carry from bit 0
+F1F1	PLA         ;get back A
+F1F2	BEQ &F202   ;if A=0 F202
+F1F4	BCC &F209   ;if carry clear F209
+
+
+*************** LOCKED FILE ROUTINE *************************************
+
+F1F6	JSR &FAF2   ;enable second processor and reset serial system
+
+F1F9	BRK         ;
+F1FA	DB  &E5     ;error number
+F1FC	'Locked'        ;
+F201	BRK         ;
+
+
+F202	BCC &F209   ;if carry clear F209
+F204	LDA #&03    ;else A=3
+F206	STA &0258   ;store to cause ESCAPE disable and memory
+    	            ;clear on break
+
+F209	LDA #&30    ;
+F20B	AND &BB     ;current OPTions
+F20D	BEQ &F213   ;if options and #&30 =0 ignore error condition is set
+F20F	LDA &C1     ;else get checksum result
+F211	BNE &F21D   ;and if not 0 F21D
+
+F213	TYA         ;A=Y
+F214	PHA         ;save A on stack
+F215	JSR &FBBB   ;read from second processor if present
+F218	PLA         ;get back A
+F219	TAY         ;Y=A
+F21A	JSR &F7D5   ;reset flags and check block length
+F21D	JSR &F9B4   ;load file from tape
+F220	BNE &F255   ;if not found return to search
+F222	JSR &FB69   ;increment current block number
+F225	BIT &03CA   ;block flag
+F228	BMI &F232   ;if bit 7=1 then this is last block so F232
+F22A	JSR &F96A   ;else increment current load address
+F22D	JSR &F77B   ;read block header
+F230	BNE &F209   ;and goto F209
+
+******** store data in OSFILE parameter block ***************************
+
+F232	LDY #&0A    ;Y=&0A
+F234	LDA &CC     ;file length counter lo
+F236	STA (&C8),Y ;OSFILE parameter  block
+F238	INY         ;Y=Y+1
+F239	LDA &CD     ;file length counter hi
+F23B	STA (&C8),Y ;OSFILE parameter  block
+F23D	LDA #&00    ;A=0
+F23F	INY         ;Y=Y+1
+F240	STA (&C8),Y ;OSFILE parameter  block
+F242	INY         ;Y=Y+1
+F243	STA (&C8),Y ;OSFILE parameter  block
+F245	PLP         ;get back flags
+F246	JSR &FAE8   ;bell, reset ACIA & motor
+F249	BIT &BA     ;current block flag
+F24B	BMI &F254   ;return
+F24D	PHP         ;save flags on stack
+F24E	JSR &FA46   ; print message following call (in this case NEWLINE!)
+F251	DB  &0D,&00 ;message
+F254	RTS         ;return
+    	;
+************RETRY AFTER A FAILURE ROUTINE *******************************
+
+F255	JSR &F637   ;search for a specified block
+F258	BNE &F209   ;goto F209
+
+
+
+*********** Read Filename using Command Line Interpreter ****************
+
+;filename pointed to by X and Y
+
+F25A	STX &F2     ;OS filename/command line pointer lo
+F25C	STY &F3     ;OS filename/command line pointer
+F25E	LDY #&00    ;Y=0
+F260	JSR &EA1D   ;initialise string
+F263	LDX #&00    ;X=0
+F265	JSR &EA2F   ;GSREAD call
+F268	BCS &F277   ;if end of character string F277
+F26A	BEQ &F274   ;if 0 found F274
+F26C	STA &03D2,X ;else store character in CFS filename area
+F26F	INX         ;X=X+1
+F270	CPX #&0B    ;if X<>11
+F272	BNE &F265   ;then read next
+F274	JMP &EA8F   ;else Bad String error
+
+
+
+************* terminate Filename ****************************************
+
+F277	LDA #&00    ;terminate filename with 0
+F279	STA &03D2,X ;
+F27C	RTS         ;return
+
+
+
+
+*************************************************************************
+*                                                                       *
+*       OSFILE ENTRY                                                    *
+*                                                                       *
+*       on entry A determines action                                    *
+*       A=0     save block of memory as a file                          *
+*       A=1     write catalogue info for existing file                  *
+*       A=2     write load address only for existing file               *
+*       A=3     write execution address only for existing file          *
+*       A=4     write attributes only for existing file                 *
+*       A=5     Read catalogue info, return file type in A              *
+*       A=6     Delete named file                                       *
+*       A=&FF   load the named file if lo byte of Exec address=0 use    *
+*               address in parameter block else files own load address  *
+*       X,Y     point to parameter block                                *
+*       bytes   0,1 filename address, 2-5 load,6-9 exec,A-D length or   *
+*               start of data for save, 0E End address /attributes      *
+*************************************************************************
+
+;parameter block located by XY
+;0/1	Address of Filename terminated by &0D
+;2/4	Load Address of File
+;6/9	Execution Address of File
+;A/D	Start address of data for write operations or length of file
+;   	for read operations
+;E/11   End address of Data; i.e. byte AFTER last byte to be written
+;   	or file attributes
+;
+;On Entry action is determined by value in A
+;
+;A=0	Save section of memory as named file, write catalogue information
+;A=1	Write catalogue information for named file
+;A=2	Write the LOAD       address (only) for the named File
+;A=3	Write the EXECUTION  address (only) for the named File
+;A=4	Write the ATTRIBUTES for the named File
+;A=5	Read the named files catalogue information Place file type in A
+;A=6	Delete the named file
+;A=&FF  Load the named file and read its catalogue information
+
+F27D	PHA         ;save A on stack
+F27E	STX &C8     ;osfile block pointer lo
+F280	STY &C9     ;osfile block pointer hi
+F282	LDY #&00    ;Y=0
+F284	LDA (&C8),Y ;OSFILE parameter  block
+F286	TAX         ;X=A
+F287	INY         ;Y=Y+1
+F288	LDA (&C8),Y ;OSFILE parameter  block
+F28A	TAY         ;Y=A
+F28B	JSR &F25A   ;get filename from BUFFER
+F28E	LDY #&02    ;Y=2
+
+F290	LDA (&C8),Y ;copy parameters to Cassette block at 3BE/C5
+F292	STA &03BC,Y ;from LOAD and EXEC address
+F295	STA &00AE,Y ;make second copy at B0-B8
+F298	INY         ;Y=Y+1
+F299	CPY #&0A    ;until Y=10
+F29B	BNE &F290   ;
+
+F29D	PLA         ;get back A
+F29E	BEQ &F2A7   ;if A=0 F2A7
+F2A0	CMP #&FF    ;else if A<>&FF
+F2A2	BNE &F254   ;RETURN as cassette has no other options
+F2A4	JMP &F1C4   ;load file
+
+
+************** Save a file **********************************************
+
+F2A7	STA &03C6   ;zero block number
+F2AA	STA &03C7   ;zero block number hi
+
+F2AD	LDA (&C8),Y ;OSFILE parameter  block
+F2AF	STA &00A6,Y ;store to Zero page copy (&B0 to &B7)
+F2B2	INY         ;data start and data end address
+F2B3	CPY #&12    ;until Y=18
+F2B5	BNE &F2AD   ;
+F2B7	TXA         ;A=X
+F2B8	BEQ &F274   ;if X=0 no filename found so B274 else BAD STRING error
+
+F2BA	JSR &FB27   ;Set cassette option sinto (BB),set C7=6
+    	            ;claim serial system for cassette
+F2BD	JSR &F934   ;prompt to start recording
+
+F2C0	LDA #&00    ;A=0
+F2C2	JSR &FBBD   ;enable 2nd proc. if present and set up osfile block
+F2C5	JSR &FBE2   ;set up CFS for write operation
+F2C8	SEC         ;set carry flag
+F2C9	LDX #&FD    ;X=&FD
+
+F2CB	LDA &FFB7,X ;set 03C8/A block length and block flag
+F2CE	SBC &FFB3,X ;to B4/6-B0/2 the number of pages (blocks) to be
+    	            ;saved
+F2D1	STA &02CB,X ;
+F2D4	INX         ;X=X+1
+F2D5	BNE &F2CB   ;
+
+F2D7	TAY         ;Y=A
+F2D8	BNE &F2E8   ;if last byte is non zero F2E8 else
+F2DA	CPX &03C8   ;compare X with block length
+F2DD	LDA #&01    ;A=1
+F2DF	SBC &03C9   ;subtract block length hi
+F2E2	BCC &F2E8   ;if carry clear F2E8
+
+F2E4	LDX #&80    ;X=&80
+F2E6	BNE &F2F0   ;jump F2F0
+
+F2E8	LDA #&01    ;A=1
+F2EA	STA &03C9   ;block length hi
+F2ED	STX &03C8   ;block length
+F2F0	STX &03CA   ;block flag
+F2F3	JSR &F7EC   ;write block to Tape
+F2F6	BMI &F341   ;return if negative
+F2F8	JSR &F96A   ;increment current load address
+F2FB	INC &03C6   ;block number
+F2FE	BNE &F2C8   ;if not 0 loop back again else
+F300	INC &03C7   ;block number hi
+F303	BNE &F2C8   ;and loop back again
+
+
+
+*************************************************************************
+*                                                                       *
+*       *RUN    ENTRY                                                   *
+*                                                                       *
+*************************************************************************
+
+F305	JSR &F25A   ;get filename from BUFFER
+F308	LDX #&FF    ;X=&FF
+F30A	STX &03C2   ;execution address
+F30D	JSR &F1C4   ;load file
+F310	BIT &027A   ;&FF if tube present
+F313	BPL &F31F   ;so if not present F31F else
+F315	LDA &03C4   ;execution address extend
+F318	AND &03C5   ;execution address extend
+F31B	CMP #&FF    ;if they are NOT both &FF i.e.for base processor
+F31D	BNE &F322   ;F322 else
+F31F	JMP (&03C2) ; RUN file
+
+F322	LDX #&C2    ;point to execution address
+F324	LDY #&03    ;(&03C2)
+F326	LDA #&04    ;Tube call 4
+F328	JMP &FBC7   ;and issue to Tube to run file
+
+
+*************************************************************************
+*                                                                       *
+*       *CAT    ENTRY                                                   *
+*                                                                       *
+*************************************************************************
+
+    	;CASSETTE OPTIONS in &E2
+
+    	;bit 0  input file open
+    	;bit 1  output file open
+    	;bit 2,4,5  not used
+    	;bit 3  current CATalogue status
+    	;bit 6  EOF reached
+    	;bit 7  EOF warning given
+
+F32B	LDA #&08    ;A=8
+F32D	JSR &F344   ;set status bits from A
+F330	JSR &FB27   ;Set cassette options into (BB),set C7=6
+    	            ;claim serial system for cassette
+F333	LDA #&00    ;A=0
+F335	JSR &F348   ;read data from CFS/RFS
+F338	JSR &FAFC   ;perform read
+F33B	LDA #&F7    ;A=&F7
+F33D	AND &E2     ;clear bit 3 of CFS status bit
+F33F	STA &E2     ;
+F341	RTS         ;return
+    	;
+
+F342	LDA #&40    ;set bit 6 of E2 cassette options
+F344	ORA &E2     ;
+F346	BNE &F33F   ;and Jump F33F
+
+
+
+********** search routine ***********************************************
+
+F348	PHA         ;save A on stack
+F349	LDA &0247   ;filing system flag 0=CFS 2=RFS
+F34C	BEQ &F359   ;if CFS F359 else
+F34E	JSR &EE13   ;set current Filing System ROM/PHROM
+F351	JSR &EE18   ;get byte from data Romcheck type
+F354	BCC &F359   ;if carry clear F359 else
+F356	CLV         ;clear overflow flag
+F357	BVC &F39A   ;JUMP F39A
+
+
+*********** cassette routine********************************************
+
+F359	JSR &F77B   ;read block header
+F35C	LDA &03C6   ;block number
+F35F	STA &B4     ;current block no. lo
+F361	LDA &03C7   ;block number hi
+F364	STA &B5     ;current block no. hi
+F366	LDX #&FF    ;X=&FF
+F368	STX &03DF   ;copy of last read block flag
+F36B	INX         ;X=X+1
+F36C	STX &BA     ;current block flag
+F36E	BEQ &F376   ;if  0 F376
+
+F370	JSR &FB69   ;inc. current block no.
+F373	JSR &F77B   ;read block header
+F376	LDA &0247   ;get filing system flag 0=CFS 2=RFS
+F379	BEQ &F37D   ;if CFS F37D
+F37B	BVC &F39A   ;if V clear F39A
+F37D	PLA         ;get back A
+F37E	PHA         ;save A on stack
+F37F	BEQ &F3AE   ;if A=0 F3AE
+F381	JSR &FA72   ;else check filename header block matches searched Fn
+F384	BNE &F39C   ;if so F39C
+F386	LDA #&30    ;else A=30 to clear all but bits 4/5 of current OPTions
+
+F388	AND &BB     ;current OPTions
+F38A	BEQ &F39A   ;if 0 F39A else
+
+F38C	LDA &03C6   ;block number
+F38F	CMP &B6     ;next block no. lo
+F391	BNE &F39C   ;
+F393	LDA &03C7   ;block number hi
+F396	CMP &B7     ;next block no. hi
+F398	BNE &F39C   ;
+F39A	PLA         ;get back A
+F39B	RTS         ;return
+    	;
+F39C	LDA &0247   ;filing system flag 0=CFS 2=RFS
+F39F	BEQ &F3AE   ;if tape F3AE
+F3A1	JSR &EEAD   ;else set ROM displacement address
+
+F3A4	LDA #&FF    ;A=&FF
+F3A6	STA &03C6   ;block number
+F3A9	STA &03C7   ;block number hi
+F3AC	BNE &F370   ;jump F370
+
+F3AE	BVC &F3B5   ;if carry clear F3B5
+F3B0	LDA #&FF    ;A=&FF
+F3B2	JSR &F7D7   ;set flags
+F3B5	LDX #&00    ;X=0
+F3B7	JSR &F9D9   ;report 'DATA?'
+F3BA	LDA &0247   ;filing system flag 0=CFS 2=RFS
+F3BD	BEQ &F3C3   ;
+F3BF	BIT &BB     ;current OPTions
+F3C1	BVC &F3A1   ;long messages not required if BIT 6 =0
+F3C3	BIT &03CA   ;block flag
+F3C6	BMI &F3A4   ;if -ve F3A4
+F3C8	BPL &F370   ;else loop back and do it again
+
+
+
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F3CA b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F3CA
new file mode 100644
index 0000000..7ddf502
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F3CA
@@ -0,0 +1 @@
+*************************************************************************
*                                                                       *
*       OSFIND  ENTRY                                                   *
*       file handling                                                   *
*                                                                       *
*************************************************************************
;on entry A determines Action Y may contain file handle or
;X/Y point to filename terminated by &0D in memory
;A=0	closes file in channel Y if Y=0 closes all files
;A=&40  open a file for input  (reading) X/Y points to filename
;A=&80  open a file for output (writing) X/Y points to filename
;A=&C0  open a file for input and output (random access)
;ON EXIT Y=0 if no file found else Y=channel number in use for file

    	            ;save A X and Y
F3CA	STA &BC     ;file status or temporary store
F3CC	TXA         ;A=X
F3CD	PHA         ;save X on stack
F3CE	TYA         ;A=Y
F3CF	PHA         ;save Y on stack
F3D0	LDA &BC     ;file status or temporary store
F3D2	BNE &F3F2   ;if A is non zero open a file via F3F2


************ close a file ***********************************************

F3D4	TYA         ;A=Y
F3D5	BNE &F3E3   ;if A<> 0 close specified file else close them all
F3D7	JSR &E275   ;close spool/exec files via OSBYTE 77
F3DA	JSR &F478   ;tidy up
F3DD	LSR &E2     ;CFS status byte is shifted left and right to zero
F3DF	ASL &E2     ;bit 0
F3E1	BCC &F3EF   ;and if carry clear no input file was open so F3EF

F3E3	LSR         ;A contains file handle so shift bit 0 into carry
F3E4	BCS &F3DD   ;if carry set close input file
F3E6	LSR         ;else shift bit 1 into carry
F3E7	BCS &F3EC   ;if carry set close output file
F3E9	JMP &FBB1   ;else report 'Channel Error' as CFS can only support
    	            ;1 input and 1 output file

F3EC	JSR &F478   ;tidy up
F3EF	JMP &F471   ;and exit


************ OPEN A FILE ************************************************

F3F2	JSR &F25A   ;get filename from BUFFER
F3F5	BIT &BC     ;file status or temporary store
F3F7	BVC &F436   ;check A at input if bit 6 not set its an output file

********* Input files +**************************************************

F3F9	LDA #&00    ;else its an input file
F3FB	STA &039E   ;BGET buffer offset for next byte
F3FE	STA &03DD   ;Expected BGET file block number lo
F401	STA &03DE   ;expected BGET file block number hi
F404	LDA #&3E    ;A=&3E
F406	JSR &F33D   ;CFS status =CFS status AND A
F409	JSR &FB1A   ;claim serial system and set OPTions
F40C	PHP         ;save flags on stack
F40D	JSR &F631   ;search for file
F410	JSR &F6B4   ;check protection bit of block status and respond
F413	PLP         ;get back flags
F414	LDX #&FF    ;X=&FF increment to 0 on next instruction

F416	INX         ;X=X+1
F417	LDA &03B2,X ;get file name and
F41A	STA &03A7,X ;store as BGET filename
F41D	BNE &F416   ;until end of filename

F41F	LDA #&01    ;A=1 to show file open
F421	JSR &F344   ;set status bits from A
F424	LDA &02EA   ;CFS currently resident file block length lo
F427	ORA &02EB   ;CFS currently resident file block length hi
F42A	BNE &F42F   ;if block length is 0
F42C	JSR &F342   ;set CFS status bit 3 (EOF reached)
    	            ;else
F42F	LDA #&01    ;A=1
F431	ORA &0247   ;filing system flag 0=CFS 2=RFS
F434	BNE &F46F   ;and exit after restoring registers


******************* open an output file***********************************

F436	TXA         ;A=X

F437	BNE &F43C   ;if X=0 then zero length filename so
F439	JMP &EA8F   ;Bad String error

F43C	LDX #&FF    ;X=&FF
F43E	INX         ;X=X+1
    	            ;copy sought filename to header block
F43F	LDA &03D2,X ;sought filename
F442	STA &0380,X ;BPUT file header block
F445	BNE &F43E   ;until A=0 end of filename
F447	LDA #&FF    ;A=&FF
F449	LDX #&08    ;X=8

F44B	STA &038B,X ;set 38C/93 to &FF
F44E	DEX         ;X=X-1
F44F	BNE &F44B   ;

F451	TXA         ;A=X=0
F452	LDX #&14    ;X=14
F454	STA &0380,X ;BPUT file header block
F457	INX         ;X=X+1
F458	CPX #&1E    ;this zeros 394/D
F45A	BNE &F454   ;

F45C	ROL &0397   ;
F45F	JSR &FB27   ;Set cassette optionsinto (BB),set C7=6
    	            ;claim serial system for cassette
F462	JSR &F934   ;prompt to start recording
F465	JSR &FAF2   ;enable second processor and reset serial system
F468	LDA #&02    ;A=2
F46A	JSR &F344   ;set status bits from A
F46D	LDA #&02    ;A=2
F46F	STA &BC     ;file status or temporary store
F471	PLA         ;get back A
F472	TAY         ;Y=A
F473	PLA         ;get back A
F474	TAX         ;X=A
F475	LDA &BC     ;file status or temporary store
F477	RTS         ;return
    	;

F478	LDA #&02    ;A=2 clearing all but bit 1 of status byte
F47A	AND &E2     ;CFS status byte, with output file open
F47C	BEQ &F477   ;if file not open then exit
F47E	LDA #&00    ;else A=0
F480	STA &0397   ;setting block length to current value of BPUT offset
F483	LDA #&80    ;A=&80
F485	LDX &039D   ;get BPUT buffer ofset
F488	STX &0396   ;setting block length to current value of BPUT offset
F48B	STA &0398   ;mark current block as last
F48E	JSR &F496   ;save block to tape
F491	LDA #&FD    ;A=&FD
F493	JMP &F33D   ;CFS status =CFS status AND A


*********** SAVE BLOCK TO TAPE ********************************************

F496	JSR &FB1A   ;claim serial system and set OPTions

F499	LDX #&11    ;X=11
F49B	LDA &038C,X ;copy header block from 38C-39D
F49E	STA &03BE,X ;to 3BE/DF
F4A1	DEX         ;X=X-1
F4A2	BPL &F49B   ;
    	            ;X=&FF
F4A4	STX &B2     ;current load address high word
F4A6	STX &B3     ;current load address high word
F4A8	INX         ;X=X+1, (X=0)
F4A9	STX &B0     ;current load address lo byte set to &00
F4AB	LDA #&09    ;A=9 to set current load address at &900
F4AD	STA &B1     ;current load address
F4AF	LDX #&7F    ;X=&7F
F4B1	JSR &FB81   ;copy from 301/C+X to 3D2/C sought filename
F4B4	STA &03DF   ;copy of last read block flag
F4B7	JSR &FB8E   ;switch Motor On
F4BA	JSR &FBE2   ;set up CFS for write operation
F4BD	JSR &F7EC   ;write block to Tape
F4C0	INC &0394   ;block number lo
F4C3	BNE &F4C8   ;
F4C5	INC &0395   ;block number hi
F4C8	RTS         ;return


*************************************************************************
*                                                                       *
*                                                                       *
*       OSBGET  get a byte from a file                                  *
*                                                                       *
*                                                                       *
*************************************************************************
    	;on ENTRY       Y contains channel number
    	;on EXIT        X and Y are preserved C=0 indicates valid character
    	;           A contains character (or error) A=&FE End Of File

    	            ;push X and Y
F4C9	TXA         ;A=X
F4CA	PHA         ;save A on stack
F4CB	TYA         ;A=Y
F4CC	PHA         ;save A on stack
F4CD	LDA #&01    ;A=1
F4CF	JSR &FB9C   ;check conditions for OSBGET are OK
F4D2	LDA &E2     ;CFS status byte
F4D4	ASL         ;shift bit 7 into carry (EOF warning given)
F4D5	BCS &F523   ;if carry set F523
F4D7	ASL         ;shift bit 6 into carry
F4D8	BCC &F4E3   ;if clear EOF not reached F4E3
F4DA	LDA #&80    ;else A=&80 setting bit 7 of status byte EOF warning
F4DC	JSR &F344   ;set status bits from A
F4DF	LDA #&FE    ;A=&FE
F4E1	BCS &F51B   ;if carry set F51B

F4E3	LDX &039E   ;BGET buffer offset for next byte
F4E6	INX         ;X=X+1
F4E7	CPX &02EA   ;CFS currently resident file block length lo
F4EA	BNE &F516   ;read a byte
    	            ;else
F4EC	BIT &02EC   ;block flag of currently resident block
F4EF	BMI &F513   ;if bit 7=1 this is the last block so F513 else
F4F1	LDA &02ED   ;last character of currently resident block
F4F4	PHA         ;save A on stack
F4F5	JSR &FB1A   ;claim serial system and set OPTions
F4F8	PHP         ;save flags on stack
F4F9	JSR &F6AC   ;read in a new block
F4FC	PLP         ;get back flags
F4FD	PLA         ;get back A
F4FE	STA &BC     ;file status or temporary store
F500	CLC         ;clear carry flag
F501	BIT &02EC   ;block flag of currently resident block
F504	BPL &F51D   ;if not last block (bit 7=0)
F506	LDA &02EA   ;CFS currently resident file block length lo
F509	ORA &02EB   ;CFS currently resident file block length hi
F50C	BNE &F51D   ;if block size not 0 F51D else
F50E	JSR &F342   ;set CFS status bit 6 (EOF reached)
F511	BNE &F51D   ;goto F51D

F513	JSR &F342   ;set CFS status bit 6 (EOF reached)
F516	DEX         ;X=X-1
F517	CLC         ;clear carry flag
F518	LDA &0A00,X ;read byte from cassette buffer

F51B	STA &BC     ;file status or temporary store
F51D	INC &039E   ;BGET buffer offset for next byte
F520	JMP &F471   ;exit via F471


F523	BRK         ;
F524	DB  &DF     ;error number
F525	DB  'EOF'   ;
F528	BRK         ;


*************************************************************************
*                                                                       *
*                                                                       *
*       OSBPUT  WRITE A BYTE TO FILE                                    *
*                                                                       *
*                                                                       *
*************************************************************************
;ON ENTRY  Y contains channel number A contains byte to be written

F529	STA &C4     ;store A in temorary store
F52B	TXA         ;and stack X and Y
F52C	PHA         ;save  on stack
F52D	TYA         ;A=Y
F52E	PHA         ;save on stack

F52F	LDA #&02    ;A=2
F531	JSR &FB9C   ;check conditions necessary for OSBPUT are OK
F534	LDX &039D   ;BPUT buffer offset for next byte
F537	LDA &C4     ;get back original value of A
F539	STA &0900,X ;Cassette buffer
F53C	INX         ;X=X+1
F53D	BNE &F545   ;if not 0 F545, otherwise buffer is full so
F53F	JSR &F496   ;save block to tape
F542	JSR &FAF2   ;enable second processor and reset serial system
F545	INC &039D   ;BPUT buffer offset for next byte
F548	LDA &C4     ;get back A
F54A	JMP &F46F   ;and exit



*************************************************************************
*                                                                       *
*                                                                       *
*       OSBYTE 139      Select file options                             *
*                                                                       *
*                                                                       *
*************************************************************************
;ON ENTRY  Y contains option value  X contains option No. see *OPT X,Y
;this applies largely to CFS LOAD SAVE CAT and RUN
;X=1	is message switch
;   	Y=0 no messages
;   	Y=1 short messages
;   	Y=2 gives detailed information on load and execution addresses

;X=2	is error handling
;   	Y=0 ignore errors
;   	Y=1 prompt for a retry
;   	Y=2 abort operation

;X=3	is interblock gap for BPUT# and PRINT#
;   	Y=0-127 set gap in 1/10ths Second
;   	Y > 127 use default values


F54D	TXA         ;A=X
F54E	BEQ &F57E   ;if A=0 F57E
F550	CPX #&03    ;if X=3
F552	BEQ &F573   ;F573 to set interblock gap
F554	CPY #&03    ;else if Y>2 then BAD COMMAND error
F556	BCS &F55E   ;
F558	DEX         ;X=X-1
F559	BEQ &F561   ;i.e. if X=1 F561 message control
F55B	DEX         ;X=X-1
F55C	BEQ &F568   ;i.e. if X=2 F568 error response
F55E	JMP &E310   ;else E310 to issue Bad Command error



*********** message control *********************************************

F561	LDA #&33    ;to set lower two bits of each nybble as mask
F563	INY         ;Y=Y+1
F564	INY         ;Y=Y+1
F565	INY         ;Y=Y+1
F566	BNE &F56A   ;goto F56A




*********** error response *********************************************

F568	LDA #&CC    ;setting top two bits of each nybble as mask
F56A	INY         ;Y=Y+1
F56B	AND &E3     ;clear lower two bits of each nybble
F56D	ORA &F581,Y ;or with table value
F570	STA &E3     ;store it in &E3
F572	RTS         ;return

    	;setting of &E3
    	;
    	;lower nybble sets LOAD options
    	;upper sets SAVE options
    	
    	;0000   Ignore errors,          no messages
    	;0001   Abort if error,         no messages
    	;0010   Retry after error,      no messages
    	;1000   Ignore error            short messages
    	;1001   Abort if error          short messages
    	;1010   Retry after error       short messages
    	;1100   Ignore error            long messages
    	;1101   Abort if error          long messages
    	;1110   Retry after error       long messages



***********set interblock gap *******************************************

F573	TYA         ;A=Y
F574	BMI &F578   ;if Y>127 use default values
F576	BNE &F57A   ;if Y<>0 skip next instruction
F578	LDA #&19    ;else A=&19

F57A	STA &03D1   ;sequential block gap
F57D	RTS         ;return
    	;
F57E	TAY         ;Y=A
F57F	BEQ &F56D   ;jump to F56D



*********** DEFAULT OPT VALUES TABLE ************************************

F581	DB  &A1     ;%1010 0001
F582	DB  &00     ;%0000 0000
F583	DB  &22     ;%0010 0010
F584	DB  &11     ;%0001 0001
F585	DB  &00     ;%0000 0000
F586	DB  &88     ;%1000 1000
F587	DB  &CC     ;%1100 1100

F588	DEC &C0     ;filing system buffer flag
F58A	LDA &0247   ;filing system flag 0=CFS 2=RFS
F58D	BEQ &F596   ;if CFS F596

F58F	JSR &EE51   ;read RFS data rom or Phrom
F592	TAY         ;Y=A
F593	CLC         ;clear carry flag
F594	BCC &F5B0   ;jump to F5B0

F596	LDA &FE08   ;ACIA status register
F599	PHA         ;save A on stack
F59A	AND #&02    ;clear all but bits 0,1 A=(0-3)
F59C	BEQ &F5A9   ;if 0 F5A9 transmit data register full or RDR empty
F59E	LDY &CA     ;
F5A0	BEQ &F5A9   ;
F5A2	PLA         ;get back A
F5A3	LDA &BD     ;character temporary storage
F5A5	STA &FE09   ;ACIA transmit data register
F5A8	RTS         ;return
    	;
F5A9	LDY &FE09   ;read ACIA recieve data register
F5AC	PLA         ;get back A
F5AD	LSR         ;bit 2 to carry (data carrier detect)
F5AE	LSR         ;
F5AF	LSR         ;

F5B0	LDX &C2     ;progress flag
F5B2	BEQ &F61D   ;if &C2=0 exit
F5B4	DEX         ;X=X-1
F5B5	BNE &F5BD   ;if &C2>1 then F5BD
F5B7	BCC &F61D   ;else if carrier tone from cassette detected exit

F5B9	LDY #&02    ;Y=2

F5BB	BNE &F61B   ;
F5BD	DEX         ;X=X-1
F5BE	BNE &F5D3   ;if &C2>2
F5C0	BCS &F61D   ;if carrier tone from cassette not detected  exit
F5C2	TYA         ;A=Y
F5C3	JSR &FB78   ;set (BE/C0) to 0
F5C6	LDY #&03    ;Y=3
F5C8	CMP #&2A    ;is A= to synchronising byte &2A?
F5CA	BEQ &F61B   ;if so F61B
F5CC	JSR &FB50   ;control cassette system
F5CF	LDY #&01    ;Y=1
F5D1	BNE &F61B   ;goto F61B
F5D3	DEX         ;X=X-1
F5D4	BNE &F5E2   ;if &C2>3
F5D6	BCS &F5DC   ;
F5D8	STY &BD     ;get character read into Y
F5DA	BEQ &F61D   ;if 0 exit via F61D
F5DC	LDA #&80    ;else A=&80
F5DE	STA &C0     ;filing system buffer flag
F5E0	BNE &F61D   ;and exit

F5E2	DEX         ;X=X-1
F5E3	BNE &F60E   ;if &C2>4 F60E
F5E5	BCS &F616   ;if carry set F616
F5E7	TYA         ;A=Y
F5E8	JSR &F7B0   ;perform CRC
F5EB	LDY &BC     ;file status or temporary store
F5ED	INC &BC     ;file status or temporary store
F5EF	BIT &BD     ;if bit 7 set this is the last byte read
F5F1	BMI &F600   ;so F600
F5F3	JSR &FBD3   ;check if second processor file test tube prescence
F5F6	BEQ &F5FD   ;if return with A=0 F5FD
F5F8	STX &FEE5   ;Tube FIFO3
F5FB	BNE &F600   ;

F5FD	TXA         ;A=X restore value
F5FE	STA (&B0),Y ;store to current load address
F600	INY         ;Y=Y+1
F601	CPY &03C8   ;block length
F604	BNE &F61D   ;exit
F606	LDA #&01    ;A=1
F608	STA &BC     ;file status or temporary store
F60A	LDY #&05    ;Y=5
F60C	BNE &F61B   ;exit

F60E	TYA         ;A=Y
F60F	JSR &F7B0   ;perform CRC
F612	DEC &BC     ;file status or temporary store
F614	BPL &F61D   ;exit

F616	JSR &FB46   ;reset ACIA
F619	LDY #&00    ;Y=0
F61B	STY &C2     ;progress flag
F61D	RTS         ;return


*************************************************************************
*                                                                       *
*       FSCV xx - check for end of file                                 *
*                                                                       *
*************************************************************************
    	;
F61E	PHA         ;save A on stack
F61F	TYA         ;A=Y
F620	PHA         ;save Y on stack
F621	TXA         ;A=X to put X into Y
F622	TAY         ;Y=A
F623	LDA #&03    ;A=3
F625	JSR &FB9C   ;confirm file is open
F628	LDA &E2     ;CFS status byte
F62A	AND #&40    ;
F62C	TAX         ;X=A
F62D	PLA         ;get back A
F62E	TAY         ;Y=A
F62F	PLA         ;get back A
F630	RTS         ;return
    	;
F631	LDA #&00    ;A=0
F633	STA &B4     ;current block no. lo
F635	STA &B5     ;current block no. hi
F637	LDA &B4     ;current block no. lo
F639	PHA         ;save A on stack
F63A	STA &B6     ;next block no. lo
F63C	LDA &B5     ;current block no. hi
F63E	PHA         ;save A on stack
F63F	STA &B7     ;next block no. hi
F641	JSR &FA46   ;print message following call

F644	DB  'Searching';
F64C	DB  &0D     ;newline
F64E	BRK         ;

F64F	LDA #&FF    ;A=&FF
F651	JSR &F348   ;read data from CFS/RFS
F654	PLA         ;get back A
F655	STA &B5     ;current block no. hi
F657	PLA         ;get back A
F658	STA &B4     ;current block no. lo
F65A	LDA &B6     ;next block no. lo
F65C	ORA &B7     ;next block no. hi
F65E	BNE &F66D   ;
F660	STA &B4     ;current block no. lo
F662	STA &B5     ;current block no. hi
F664	LDA &C1     ;checksum result
F666	BNE &F66D   ;
F668	LDX #&B1    ;current load address
F66A	JSR &FB81   ;copy from 301/C+X to 3D2/C sought filename
F66D	LDA &0247   ;filing system flag 0=CFS 2=RFS
F670	BEQ &F685   ;if cassette F685
F672	BVS &F685   ;

F674	BRK         ;
F675	DB  &D6             ;Error number
F676	DB  'File Not found'
F684	BRK         ;

F685	LDY #&FF    ;Y=&FF
F687	STY &03DF   ;copy of last read block flag
F68A	RTS         ;return
    	;

\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F68B b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F68B
new file mode 100644
index 0000000..1f8ba97
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F68B
@@ -0,0 +1 @@
+********  CLOSE EXEC FILE  **********************************************

F68B	LDA #&00    ;A=0

*************************************************************************
*                                                                       *
*       *EXEC                                                           *
*                                                                       *
*************************************************************************

F68D	PHP         ;save flags on stack
F68E	STY &E6     ;&E6=Y
F690	LDY &0256   ;EXEC file handle
F693	STA &0256   ;EXEC file handle
F696	BEQ &F69B   ;if not 0 close file via OSFIND
F698	JSR OSFIND  ;
F69B	LDY &E6     ;else Y= original Y
F69D	PLP         ;get back flags
F69E	BEQ &F6AB   ;if A=0 on entry exit else
F6A0	LDA #&40    ;A=&40
F6A2	JSR OSFIND  ;to open an input file
F6A5	TAY         ;Y=A
F6A6	BEQ &F674   ;If Y=0 'File not found' else store
F6A8	STA &0256   ;EXEC file handle
F6AB	RTS         ;return
    	
******* read a block    *************************************************

F6AC	LDX #&A6    ;X=&A6
F6AE	JSR &FB81   ;copy from 301/C+X to 3D2/C sought filename
F6B1	JSR &F77B   ;read block header
F6B4	LDA &03CA   ;block flag
F6B7	LSR         ;A=A/2 bit 0 into carry to check for locked file
F6B8	BCC &F6BD   ;if not set then skip next instruction
F6BA	JMP &F1F6   ;'locked' file routine

F6BD	LDA &03DD   ;Expected BGET file block number lo
F6C0	STA &B4     ; current block no. lo
F6C2	LDA &03DE   ;expected BGET file block number hi
F6C5	STA &B5     ;current block no. hi
F6C7	LDA #&00    ;A=0
F6C9	STA &B0     ;current load address
F6CB	LDA #&0A    ;A=&A setting current load address to the CFS/RFS
F6CD	STA &B1     ;current load address buffer at &A00
F6CF	LDA #&FF    ;A=&FF to set other 2 bytes
F6D1	STA &B2     ;current load address high word
F6D3	STA &B3     ;current load address high word
F6D5	JSR &F7D5   ;reset flags
F6D8	JSR &F9B4   ;load file from tape
F6DB	BNE &F702   ;if return non zero F702 else
F6DD	LDA &0AFF   ;get last character from input buffer
F6E0	STA &02ED   ;last character currently resident block
F6E3	JSR &FB69   ;inc. current block no.
F6E6	STX &03DD   ;expected BGET file block number lo
F6E9	STY &03DE   ;expected BGET file block number hi
F6EC	LDX #&02    ;X=2
F6EE	LDA &03C8,X ;read bytes from block flag/block length
F6F1	STA &02EA,X ;store into current values of above
F6F4	DEX         ;X=X-1
F6F5	BPL &F6EE   ;until X=-1 (&FF)

F6F7	BIT &02EC   ;block flag of currently resident block
F6FA	BPL &F6FF   ;
F6FC	JSR &F249   ;print newline if needed
F6FF	JMP &FAF2   ;enable second processor and reset serial system
F702	JSR &F637   ;search for a specified block
F705	BNE &F6B4   ;if NE check for locked condition else
F707	CMP #&2A    ;is it Synchronising byte &2A?
F709	BEQ &F742   ;if so F742
F70B	CMP #&23    ;else is it &23 (header substitute in ROM files)
F70D	BNE &F71E   ;if not BAD ROM error

F70F	INC &03C6   ;block number
F712	BNE &F717   ;
F714	INC &03C7   ;block number hi
F717	LDX #&FF    ;X=&FF
F719	BIT &D9B7   ;to set V & M
F71C	BNE &F773   ;and jump (ALWAYS!!) to F773

F71E	LDA #&F7    ;clear bit 3 of RFS status (current CAT status)
F720	JSR &F33D   ;RFS status =RFS status AND A

F723	BRK         ;and cause error
F724	DB  &D7     ;error number
F725	DB  'Bad Rom'
F72C	BRK         ;


**********: pick up a header ********************************************

F72D	LDY &FF     ;get ESCAPE flag
F72F	JSR &FB90   ;switch Motor on
F732	LDA #&01    ;A=1
F734	STA &C2     ;progress flag
F736	JSR &FB50   ;control serial system
F739	JSR &F995   ;confirm ESC not set and CFS not executing
F73C	LDA #&03    ;A=3
F73E	CMP &C2     ;progress flag
F740	BNE &F739   ;back until &C2=3

F742	LDY #&00    ;Y=0
F744	JSR &FB7C   ;zero checksum bytes
F747	JSR &F797   ;get character from file and do CRC
F74A	BVC &F766   ;if V clear on exit F766
F74C	STA &03B2,Y ;else store
F74F	BEQ &F757   ;or if A=0 F757
F751	INY         ;Y=Y+1
F752	CPY #&0B    ;if Y<>&B
F754	BNE &F747   ;go back for next character
F756	DEY         ;Y=Y-1

F757	LDX #&0C    ;X=12
F759	JSR &F797   ;get character from file and do CRC
F75C	BVC &F766   ;if V clear on exit F766
F75E	STA &03B2,X ;else store byte
F761	INX         ;X=X+1
F762	CPX #&1F    ;if X<>31
F764	BNE &F759   ;goto F759

F766	TYA         ;A=Y
F767	TAX         ;X=A
F768	LDA #&00    ;A=0
F76A	STA &03B2,Y ;store it
F76D	LDA &BE     ;CRC workspace
F76F	ORA &BF     ;CRC workspace
F771	STA &C1     ;Checksum result
F773	JSR &FB78   ;set (BE/C0) to 0
F776	STY &C2     ;progress flag
F778	TXA         ;A=X
F779	BNE &F7D4   ;
F77B	LDA &0247   ;filing system flag 0=CFS 2=RFS
F77E	BEQ &F72D   ;if cassette F72D
F780	JSR &EE51   ;read RFS data rom or Phrom
F783	CMP #&2B    ;is it ROM file terminator?
F785	BNE &F707   ;if not F707

********* terminator found **********************************************

F787	LDA #&08    ;A=8 isolating bit 3 CAT status
F789	AND &E2     ;CFS status byte
F78B	BEQ &F790   ;if clera skip next instruction
F78D	JSR &F24D   ;print CR if CFS not operational
F790	JSR &EE18   ;get byte from data Rom
F793	BCC &F780   ;if carry set F780
F795	CLV         ;clear overflow flag
F796	RTS         ;return



****************  get character from file and do CRC  *******************
    	;
F797	LDA &0247   ;filing system flag 0=CFS 2=RFS
F79A	BEQ &F7AD   ;if cassette F7AD
F79C	TXA         ;A=X to save X and Y
F79D	PHA         ;save X on stack
F79E	TYA         ;A=Y
F79F	PHA         ;save Y on stack
F7A0	JSR &EE51   ;read RFS data rom or Phrom
F7A3	STA &BD     ;put it in temporary storage
F7A5	LDA #&FF    ;A=&FF
F7A7	STA &C0     ;filing system buffer flag
F7A9	PLA         ;get back Y
F7AA	TAY         ;Y=A
F7AB	PLA         ;get back X
F7AC	TAX         ;X=A
F7AD	JSR &F884   ;check for Escape and loop till bit 7 of FS buffer
    	            ;flag=1


************************** perform CRC **********************************

F7B0	PHP         ;save flags on stack
F7B1	PHA         ;save A on stack
F7B2	SEC         ;set carry flag
F7B3	ROR &CB     ;CRC Bit counter
F7B5	EOR &BF     ;CRC workspace
F7B7	STA &BF     ;CRC workspace
F7B9	LDA &BF     ;CRC workspace
F7BB	ROL         ;A=A*2 C=bit 7
F7BC	BCC &F7CA   ;
F7BE	ROR         ;A=A/2
F7BF	EOR #&08    ;
F7C1	STA &BF     ;CRC workspace
F7C3	LDA &BE     ;CRC workspace
F7C5	EOR #&10    ;
F7C7	STA &BE     ;CRC workspace
F7C9	SEC         ;set carry flag

F7CA	ROL &BE     ;CRC workspace
F7CC	ROL &BF     ;CRC workspace
F7CE	LSR &CB     ;CRC Bit counter
F7D0	BNE &F7B9   ;
F7D2	PLA         ;get back A
F7D3	PLP         ;get back flags
F7D4	RTS         ;return
    	;


F7D5	LDA #&00    ;A=0
F7D7	STA &BD     ;&BD=character temporary storage buffer=0
F7D9	LDX #&00    ;X=0
F7DB	STX &BC     ;file status or temporary store
F7DD	BVC &F7E9   ;
F7DF	LDA &03C8   ;block length
F7E2	ORA &03C9   ;block length hi
F7E5	BEQ &F7E9   ;if 0 F7E9

F7E7	LDX #&04    ;else X=4
F7E9	STX &C2     ;filename length/progress flag
F7EB	RTS         ;return



*************** SAVE A BLOCK ********************************************

F7EC	PHP         ;save flags on stack
F7ED	LDX #&03    ;X=3
F7EF	LDA #&00    ;A=0
F7F1	STA &03CB,X ;clear 03CB/E (RFS EOF+1?)
F7F4	DEX         ;X=X-1
F7F5	BPL &F7F1   ;

F7F7	LDA &03C6   ;block number
F7FA	ORA &03C7   ;block number hi
F7FD	BNE &F804   ;if block =0 F804 else
F7FF	JSR &F892   ;generate a 5 second delay
F802	BEQ &F807   ;goto F807


F804	JSR &F896   ;generate delay set by interblock gap
F807	LDA #&2A    ;A=&2A
F809	STA &BD     ;store it in temporary file
F80B	JSR &FB78   ;set (BE/C0) to 0
F80E	JSR &FB4A   ;set ACIA control register
F811	JSR &F884   ;check for Escape and loop till bit 7 of FS buffer
    	            ;flag=1
F814	DEY         ;Y=Y-1
F815	INY         ;Y=Y+1
F816	LDA &03D2,Y ;move sought filename
F819	STA &03B2,Y ;into filename block
F81C	JSR &F875   ;transfer byte to CFS and do CRC
F81F	BNE &F815   ;if filename not complet then do it again


******: deal with rest of header ****************************************

F821	LDX #&0C    ;X=12
F823	LDA &03B2,X ;get filename byte
F826	JSR &F875   ;transfer byte to CFS and do CRC
F829	INX         ;X=X+1
F82A	CPX #&1D    ;until X=29
F82C	BNE &F823   ;

F82E	JSR &F87B   ;save checksum to TAPE reset buffer flag
F831	LDA &03C8   ;block length
F834	ORA &03C9   ;block length hi
F837	BEQ &F855   ;if 0 F855

F839	LDY #&00    ;else Y=0
F83B	JSR &FB7C   ;zero checksum bytes
F83E	LDA (&B0),Y ;get a data byte
F840	JSR &FBD3   ;check if second processor file test tube prescence
F843	BEQ &F848   ;if not F848 else

F845	LDX &FEE5   ;Tube FIFO3

F848	TXA         ;A=X
F849	JSR &F875   ;transfer byte to CFS and do CRC
F84C	INY         ;Y=Y+1
F84D	CPY &03C8   ;block length
F850	BNE &F83E   ;
F852	JSR &F87B   ;save checksum to TAPE reset buffer flag
F855	JSR &F884   ;check for Escape and loop till bit 7 of FS buffer
    	            ;flag=1
F858	JSR &F884   ;check for Escape and loop till bit 7 of FS buffer
    	            ;flag=1
F85B	JSR &FB46   ;reset ACIA

F85E	LDA #&01    ;A=1
F860	JSR &F898   ;generate 0.1 * A second delay
F863	PLP         ;get back flags
F864	JSR &F8B9   ;update block flag, PRINT filename (& address if reqd)
F867	BIT &03CA   ;block flag
F86A	BPL &F874   ;is this last block (bit 7 set)?
F86C	PHP         ;save flags on stack
F86D	JSR &F892   ;generate a 5 second delay
F870	JSR &F246   ;sound bell and abort
F873	PLP         ;get back flags
F874	RTS         ;return


****************** transfer byte to CFS and do CRC **********************
    	;
F875	JSR &F882   ;save byte to buffer, transfer to CFS & reset flag
F878	JMP &F7B0   ;perform CRC


***************** save checksum to TAPE reset buffer flag ****************

F87B	LDA &BF     ;CRC workspace
F87D	JSR &F882   ;save byte to buffer, transfer to CFS & reset flag
F880	LDA &BE     ;CRC workspace


************** save byte to buffer, transfer to CFS & reset flag ********

F882	STA &BD     ;store A in temporary buffer


***** check for Escape and loop untill bit 7 of FS buffer flag=1 ***********

F884	JSR &F995   ;confirm ESC not set and CFS not executing
F887	BIT &C0     ;filing system buffer flag
F889	BPL &F884   ;loop until bit 7 of &C0 is set

F88B	LDA #&00    ;A=0
F88D	STA &C0     ;filing system buffer flag
F88F	LDA &BD     ;get temporary store byte
F891	RTS         ;return
    	;


****************** generate a 5 second delay  ***************************

F892	LDA #&32    ;A=50
F894	BNE &F898   ;generate delay 100ms *A (5 seconds)



*************** generate delay set by interblock gap ********************

F896	LDA &C7     ;get current interblock flag


*************** generate delay ******************************************

F898	LDX #&05    ;X=5
F89A	STA &0240   ;CFS timeout counter
F89D	JSR &F995   ;confirm ESC not set and CFS not executing
F8A0	BIT &0240   ;CFS timeout counter (decremented each 20ms)
F8A3	BPL &F89D   ;if +ve F89D
F8A5	DEX         ;X=X-1
F8A6	BNE &F89A   ;
F8A8	RTS         ;return
    	;


************: generate screen reports ***********************************

F8A9	LDA &03C6   ;block number
F8AC	ORA &03C7   ;block number hi
F8AF	BEQ &F8B6   ;if 0 F8B6
F8B1	BIT &03DF   ;copy of last read block flag
F8B4	BPL &F8B9   ;update block flag, PRINT filename (& address if reqd)
F8B6	JSR &F249   ;print newline if needed


************** update block flag, PRINT filename (& address if reqd) ****

F8B9	LDY #&00    ;Y=0
F8BB	STY &BA     ;current block flag
F8BD	LDA &03CA   ;block flag
F8C0	STA &03DF   ;copy of last read block flag
F8C3	JSR &E7DC   ;check if free to print message
F8C6	BEQ &F933   ;if A=0 on return Cassette system is busy
F8C8	LDA #&0D    ;else A=&0D :carriage return
F8CA	JSR OSWRCH  ;print it (note no linefeed as it's via OSWRCH)
F8CD	LDA &03B2,Y ;get byte from filename
F8D0	BEQ &F8E2   ;if 0 filename is ended
F8D2	CMP #&20    ;if <SPACE
F8D4	BCC &F8DA   ;F8DA
F8D6	CMP #&7F    ;if less than DELETE
F8D8	BCC &F8DC   ;its a printable character for F8DC else


*******************Control characters in RFS/CFS filename ******************

F8DA	LDA #&3F    ;else A='?'
F8DC	JSR OSWRCH  ;and print it

F8DF	INY         ;Y=Y+1
F8E0	BNE &F8CD   ;back to get rest of filename


***************** end of filename ***************************************

F8E2	LDA &0247   ;filing system flag 0=CFS 2=RFS
F8E5	BEQ &F8EB   ;if cassette F8EB
F8E7	BIT &BB     ;test current OPTions
F8E9	BVC &F933   ;if bit 6 clear no,long messages needed F933
F8EB	JSR &F991   ;print a space
F8EE	INY         ;Y=Y+1
F8EF	CPY #&0B    ;if Y<11 then
F8F1	BCC &F8E2   ;loop again to fill out filename with spaces

F8F3	LDA &03C6   ;block number
F8F6	TAX         ;X=A
F8F7	JSR &F97A   ;print ASCII equivalent of hex byte
F8FA	BIT &03CA   ;block flag
F8FD	BPL &F933   ;if not end of file return
F8FF	TXA         ;A=X
F900	CLC         ;clear carry flag
F901	ADC &03C9   ;block length hi
F904	STA &CD     ;file length counter hi
F906	JSR &F975   ;print space + ASCII equivalent of hex byte
F909	LDA &03C8   ;block length
F90C	STA &CC     ;file length counter lo
F90E	JSR &F97A   ;print ASCII equivalent of hex byte
F911	BIT &BB     ;current OPTions
F913	BVC &F933   ;if bit 6 clear no long messages required so F933

F915	LDX #&04    ;X=4
F917	JSR &F991   ;print a space
F91A	DEX         ;X=X-1
F91B	BNE &F917   ;loop to print 4 spaces

F91D	LDX #&0F    ;X=&0F to point to load address
F91F	JSR &F927   ;print 4 bytes from CFS block header
F922	JSR &F991   ;print a space
F925	LDX #&13    ;X=&13 point to Execution address


************** print 4 bytes from CFS block header **********************

F927	LDY #&04    ;loop pointer
F929	LDA &03B2,X ;block header
F92C	JSR &F97A   ;print ASCII equivalent of hex byte
F92F	DEX         ;X=X-1
F930	DEY         ;Y=Y-1
F931	BNE &F929   ;

F933	RTS         ;return

    	;
*********** print prompt for SAVE on TAPE *******************************

F934	LDA &0247   ;filing system flag 0=CFS 2=RFS
F937	BEQ &F93C   ;if cassette F93C
F939	JMP &E310   ;else 'Bad Command error message'
F93C	JSR &FB8E   ;switch Motor On
F93F	JSR &FBE2   ;set up CFS for write operation
F942	JSR &E7DC   ;check if free to print message
F945	BEQ &F933   ;if not exit else
F947	JSR &FA46   ; print message following call

F94A	DB  'RECORD then RETURN';
F95C	BRK         ;

F95D	JSR &F995   ;confirm CFS not operating, nor ESCAPE flag set



************ wait for RETURN key to be pressed **************************

F960	JSR OSRDCH  ;wait for keypress
F963	CMP #&0D    ;is it &0D (RETURN)
F965	BNE &F95D   ;no then do it again

F967	JMP OSNEWL  ;output Carriage RETURN and LINE FEED



************* increment current load address ****************************

F96A	INC &B1     ;current load address
F96C	BNE &F974   ;
F96E	INC &B2     ;current load address high word
F970	BNE &F974   ;
F972	INC &B3     ;current load address high word
F974	RTS         ;return
    	;
************* print a space + ASCII equivalent of hex byte **************

F975	PHA         ;save A on stack
F976	JSR &F991   ;print a space
F979	PLA         ;get back A


************** print ASCII equivalent of hex byte  **********************

F97A	PHA         ;save A on stack
F97B	LSR         ;/16 to put high nybble in lo
F97C	LSR         ;
F97D	LSR         ;
F97E	LSR         ;
F97F	JSR &F983   ;print its ASCII equivalent
F982	PLA         ;get back A

F983	CLC         ;clear carry flag
F984	AND #&0F    ;clear high nybble
F986	ADC #&30    ;Add &30 to convert 0-9 to ASCII A-F to : ; < = > ?
F988	CMP #&3A    ;if A< ASC(':')
F98A	BCC &F98E   ;goto F98E
F98C	ADC #&06    ;else add 7 to convert : ; < = > ? to A B C D E F

F98E	JMP OSWRCH  ;print character and return



******************** print a space  *************************************

F991	LDA #&20    ;A=' '
F993	BNE &F98E   ;goto F98E to print it



******************** confirm CFS not operating, nor ESCAPE flag set *****

F995	PHP         ;save flags on stack
F996	BIT &EB     ;CFS Active flag
F998	BMI &F99E   ;
F99A	BIT &FF     ;if ESCAPE condition
F99C	BMI &F9A0   ;goto F9A0
F99E	PLP         ;get back flags
F99F	RTS         ;return
    	;


F9A0	JSR &F33B   ;close input file
F9A3	JSR &FAF2   ;enable second processor and reset serial system
F9A6	LDA #&7E    ;A=&7E (126) Acknowledge ESCAPE
F9A8	JSR OSBYTE  ;OSBYTE Call

F9AB	BRK         ;
F9AC	DB  &11     ;error 17
F9AD	DB  'Escape' ;
F9B3	BRK         ;


\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F9B4 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F9B4
new file mode 100644
index 0000000..77fe206
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/F9B4
@@ -0,0 +1 @@
+OS SERIES 10
LAST PART
GEOFF COX
****************************** LOAD *************************************

F9B4	TYA         ;A=Y
F9B5	BEQ &F9C4   ;
F9B7	JSR &FA46   ; print message following call

F9BA	DB  &0D     ;
F9BB	DB  'Loading';
F9C2	DB  &0D     ;
F9C3	BRK         ;

F9C5	STA &BA     ;current block flag
F9C6	LDX #&FF    ;X=&FF
F9C8	LDA &C1     ;Checksum result
F9CA	BNE &F9D9   ;if not 0 F9D9
F9CC	JSR &FA72   ;else check filename header block matches searched
    	            ;filename if this returns NE then no match
F9CF	PHP         ;save flags on stack
F9D0	LDX #&FF    ;X=&FF
F9D2	LDY #&99    ;Y=&99
F9D4	LDA #&FA    ;A=&FA this set Y/A to point to 'File?' FA99
F9D6	PLP         ;get back flags
F9D7	BNE &F9F5   ;report a query unexpected file name

F9D9	LDY #&8E    ;making Y/A point to 'Data' FA8E for CRC error
F9DB	LDA &C1     ;Checksum result
F9DD	BEQ &F9E3   ;if 0 F9E3
F9DF	LDA #&FA    ;A=&FA
F9E1	BNE &F9F5   ;jump to F9F5

F9E3	LDA &03C6   ;block number
F9E6	CMP &B4     ;current block no. lo
F9E8	BNE &F9F1   ;if not eual F9F1
F9EA	LDA &03C7   ;block number hi
F9ED	CMP &B5     ;current block no. hi
F9EF	BEQ &FA04   ;if equal FA04

F9F1	LDY #&A4    ;Y=&A4
F9F3	LDA #&FA    ;A=&FA  point to 'Block?' error unexpected block no.

    	            ;at this point an error HAS occurred

F9F5	PHA         ;save A on stack
F9F6	TYA         ;A=Y
F9F7	PHA         ;save Y on stack
F9F8	TXA         ;A=X
F9F9	PHA         ;save X on stack
F9FA	JSR &F8B6   ;print CR if indicated by current block flag
F9FD	PLA         ;get back A
F9FE	TAX         ;X=A
F9FF	PLA         ;get back A
FA00	TAY         ;Y=A
FA01	PLA         ;get back A
FA02	BNE &FA18   ;jump to FA18

FA04	TXA         ;A=X
FA05	PHA         ;save A on stack
FA06	JSR &F8A9   ;report
FA09	JSR &FAD6   ;check loading progress, read another byte
FA0C	PLA         ;get back A
FA0D	TAX         ;X=A
FA0E	LDA &BE     ;CRC workspace
FA10	ORA &BF     ;CRC workspace
FA12	BEQ &FA8D   ;
FA14	LDY #&8E    ;Y=&8E
FA16	LDA #&FA    ;A=&FA  FA8E points to 'Data?'
FA18	DEC &BA     ;current block flag
FA1A	PHA         ;save A on stack
FA1B	BIT &EB     ;CFS Active flag
FA1D	BMI &FA2C   ;if active FA2C
FA1F	TXA         ;A=X
FA20	AND &0247   ;filing system flag 0=CFS 2=RFS
FA23	BNE &FA2C   ;
FA25	TXA         ;A=X
FA26	AND #&11    ;
FA28	AND &BB     ;current OPTions
FA2A	BEQ &FA3C   ;ignore errors
FA2C	PLA         ;get back A
FA2D	STA &B9     ;store A on &B9
FA2F	STY &B8     ;store Y on &B8
FA31	JSR &F68B   ;do *EXEC 0 to tidy up
FA34	LSR &EB     ;halve CFS Active flag to clear bit 7

FA36	JSR &FAE8   ;bell, reset ACIA & motor
FA39	JMP (&00B8) ;display selected error report

FA3C	PLA         ;get back A
FA3D	INY         ;Y=Y+1
FA3E	BNE &FA43   ;
FA40	CLC         ;clear carry flag
FA41	ADC #&01    ;Add 1
FA43	PHA         ;save A on stack
FA44	TYA         ;A=Y
FA45	PHA         ;save Y on stack
FA46	JSR &E7DC   ;check if free to print message
FA49	TAY         ;Y=A
FA4A	PLA         ;get back A
FA4B	STA &B8     ;&B8=8
FA4D	PLA         ;get back A
FA4E	STA &B9     ;&B9=A
FA50	TYA         ;A=Y
FA51	PHP         ;save flags on stack
FA52	INC &B8     ;
FA54	BNE &FA58   ;
FA56	INC &B9     ;
FA58	LDY #&00    ;Y=0
FA5A	LDA (&B8),Y ;get byte
FA5C	BEQ &FA68   ;if 0 Fa68
FA5E	PLP         ;get back flags
FA5F	PHP         ;save flags on stack
FA60	BEQ &FA52   ;if 0 FA52 to get next character
FA62	JSR OSASCI  ;else print
FA65	JMP &FA52   ;and do it again

FA68	PLP         ;get back flags
FA69	INC &B8     ;increment pointers
FA6B	BNE &FA6F   ;
FA6D	INC &B9     ;
FA6F	JMP (&00B8) ;and print error message so no error condition
    	            ;occcurs



************ compare filenames ******************************************

FA72	LDX #&FF    ;X=&FF inx will mean X=0

FA74	INX         ;X=X+1
FA75	LDA &03D2,X ;sought filename byte
FA78	BNE &FA81   ;if not 0 FA81
FA7A	TXA         ;else A=X
FA7B	BEQ &FA80   ;if X=0 A=0 exit
FA7D	LDA &03B2,X ;else A=filename byte
FA80	RTS         ;return
    	;
FA81	JSR &E4E3   ;set carry if byte in A is not upper case Alpha
FA84	EOR &03B2,X ;compare with filename
FA87	BCS &FA8B   ;if carry set FA8B
FA89	AND #&DF    ;else convert to upper case
FA8B	BEQ &FA74   ;and if A=0 filename characters match so do it again
FA8D	RTS         ;return
    	;
FA8E	BRK         ;
FA8F	DB  &D8     ;error number
FA90	DB  'Data'  ;
FA96	BRK         ;

FA97	BNE &FAAE   ;

FA99	BRK         ;
FA9A	DB  &DB     ;error number
FA9B	DB  'File?' ;
FAA1	BRK         ;

FAA2	BNE &FAAE   ;

FAA4	BRK         ;
FAA5	DB  &DA     ;error number
FAA6	DB  'Block?'
FAAD	BRK         ;

FAAE	LDA &BA     ;current block flag
FAB0	BEQ &FAD3   ;if 0 FAD3 else
FAB2	TXA         ;A=X
FAB3	BEQ &FAD3   ;If X=0 FAD3
FAB5	LDA #&22    ;A=&22
FAB7	BIT &BB     ;current OPTions checking bits 1 and 5
FAB9	BEQ &FAD3   ;if neither set no  retry so FAD3 else
FABB	JSR &FB46   ;reset ACIA
FABE	TAY         ;Y=A
FABF	JSR &FA4A   ;print following message

FAC2	DB  &0D     ;Carriage RETURN
FAC3	DB  &07     ;BEEP
FAC4	DB  'Rewind Tape'   ;
FACF	DW  &0D0D   ;two more newlines
FAD1	BRK         ;

FAD2	RTS         ;return
    	;

FAD3	JSR &F24D   ;print CR if CFS not operational
FAD6	LDA &C2     ;filename length/progress flag
FAD8	BEQ &FAD2   ;if 0 return else
FADA	JSR &F995   ;confirm ESC not set and CFS not executing
FADD	LDA &0247   ;filing system flag 0=CFS 2=RFS
FAE0	BEQ &FAD6   ;if CFS FAD6
FAE2	JSR &F588   ;else set up ACIA etc
FAE5	JMP &FAD6   ;and loop back again


********** sound bell, reset ACIA, motor off ****************************

FAE8	JSR &E7DC   ;check if free to print message
FAEB	BEQ &FAF2   ;enable second processor and reset serial system
FAED	LDA #&07    ;beep
FAEF	JSR OSWRCH  ;
FAF2	LDA #&80    ;
FAF4	JSR &FBBD   ;enable 2nd proc. if present and set up osfile block
FAF7	LDX #&00    ;
FAF9	JSR &FB95   ;switch on motor
FAFC	PHP         ;save flags on stack
FAFD	SEI         ;prevent IRQ interrupts
FAFE	LDA &0282   ;get serial ULA control register setting
FB01	STA &FE10   ;write to serial ULA control register setting
FB04	LDA #&00    ;A=0
FB06	STA &EA     ;store A RS423 timeout counter
FB08	BEQ &FB0B   ;jump FB0B


FB0A	PHP         ;save flags on stacksave flags
FB0B	JSR &FB46   ;release ACIA (by &FE08=3)
FB0E	LDA &0250   ;get last setting of ACIA
FB11	JMP &E189   ;set ACIA and &250 from A before exit

FB14	PLP         ;get back flags
FB15	BIT &FF     ;if bit 7of ESCAPE flag not set
FB17	BPL &FB31   ;then FB31
FB19	RTS         ;else return as unserviced ESCAPE is pending
    	



*************************************************************************
*                                                                       *
*       Claim serial system for sequential Access                       *
*                                                                       *
*************************************************************************


FB1A	LDA &E3     ;get cassette filing system options byte
    	            ;high nybble used for LOAD & SAVE operations
    	            ;low nybble used for sequential access

    	            ;0000   Ignore errors,          no messages
    	            ;0001   Abort if error,         no messages
    	            ;0010   Retry after error,      no messages
    	            ;1000   Ignore error            short messages
    	            ;1001   Abort if error          short messages
    	            ;1010   Retry after error       short messages
    	            ;1100   Ignore error            long messages
    	            ;1101   Abort if error          long messages
    	            ;1110   Retry after error       long messages

FB1C	ASL         ;move low nybble into high nybble
FB1D	ASL         ;
FB1E	ASL         ;
FB1F	ASL         ;
FB20	STA &BB     ;current OPTions save into &BB
FB22	LDA &03D1   ;get sequential block gap
FB25	BNE &FB2F   ;goto to &FB2F


*************************************************************************
*                                                                       *
*       claim serial system for cassette etc.                           *
*                                                                       *
*************************************************************************

FB27	LDA &E3     ;get cassette filing system options byte
    	            ;high nybble used for LOAD & SAVE operations
    	            ;low nybble used for sequential access

    	            ;0000   Ignore errors,          no messages
    	            ;0001   Abort if error,         no messages
    	            ;0010   Retry after error,      no messages
    	            ;1000   Ignore error            short messages
    	            ;1001   Abort if error          short messages
    	            ;1010   Retry after error       short messages
    	            ;1100   Ignore error            long messages
    	            ;1101   Abort if error          long messages
    	            ;1110   Retry after error       long messages

FB29	AND #&F0    ;clear low nybble
FB2B	STA &BB     ;as current OPTions
FB2D	LDA #&06    ;set current interblock gap
FB2F	STA &C7     ;to 6


FB31	CLI         ;allow interrupts
FB32	PHP         ;save flags on stack
FB33	SEI         ;prevent interrupts
FB34	BIT &024F   ;check if RS423 is busy
FB37	BPL &FB14   ;if not FB14
FB39	LDA &EA     ;see if RS423 has timed out
FB3B	BMI &FB14   ;if not FB14

FB3D	LDA #&01    ;else load RS423 timeout counter with
FB3F	STA &EA     ;1 to indicate that cassette has 6850
FB41	JSR &FB46   ;reset ACIA with &FE80=3
FB44	PLP         ;get back flags
FB45	RTS         ;return
    	;

FB46	LDA #&03    ;A=3
FB48	BNE &FB65   ;and exit after resetting ACIA



**********************  set ACIA control register  **********************

FB4A	LDA #&30    ;set current ACIA control register
FB4C	STA &CA     ;to &30
FB4E	BNE &FB63   ;and goto FB63

    	            ;if bit 7=0 motor off 1=motor on


***************** control cassette system *******************************

FB50	LDA #&05    ;set &FE10 to 5
FB52	STA &FE10   ;setting a transmit baud rate of 300,motor off

FB55	LDX #&FF    ;
FB57	DEX         ;delay loop
FB58	BNE &FB57   ;

FB5A	STX &CA     ;&CA=0
FB5C	LDA #&85    ;Turn motor on and keep baud rate at 300 recieve
FB5E	STA &FE10   ;19200 transmit
FB61	LDA #&D0    ;A=&D0

FB63	ORA &C6     ;
FB65	STA &FE08   ;set up ACIA control register
FB68	RTS         ;returnand return

    	;
FB69	LDX &03C6   ;block number
FB6C	LDY &03C7   ;block number hi
FB6F	INX         ;X=X+1
FB70	STX &B4     ;current block no. lo
FB72	BNE &FB75   ;
FB74	INY         ;Y=Y+1
FB75	STY &B5     ;current block no. hi
FB77	RTS         ;return
    	;
FB78	LDY #&00    ;
FB7A	STY &C0     ;filing system buffer flag


*****************set (zero) checksum bytes ******************************

FB7C	STY &BE     ;CRC workspace
FB7E	STY &BF     ;CRC workspace
FB80	RTS         ;return
    	;


*********** copy sought filename routine ********************************

FB81	LDY #&FF    ;Y=&FF
FB83	INY         ;Y=Y+1
FB84	INX         ;X=X+1
FB85	LDA &0300,X ;
FB88	STA &03D2,Y ;sought filename
FB8B	BNE &FB83   ;until end of filename (0)
FB8D	RTS         ;return
    	;
FB8E	LDY #&00    ;Y=0


********************** switch Motor on **********************************

FB90	CLI         ;allow   IRQ interrupts
FB91	LDX #&01    ;X=1
FB93	STY &C3     ;store Y as current file handle


********************: control motor ************************************

FB95	LDA #&89    ;do osbyte 137
FB97	LDY &C3     ;get back file handle (preserved thru osbyte)
FB99	JMP OSBYTE  ;turn on motor



****************** confirm file is open  ********************************

FB9C	STA &BC     ;file status or temporary store
FB9E	TYA         ;A=Y
FB9F	EOR &0247   ;filing system flag 0=CFS 2=RFS
FBA2	TAY         ;Y=A
FBA3	LDA &E2     ;CFS status byte
FBA5	AND &BC     ;file status or temporary store
FBA7	LSR         ;A=A/2
FBA8	DEY         ;Y=Y-1
FBA9	BEQ &FBAF   ;
FBAB	LSR         ;A=A/2
FBAC	DEY         ;Y=Y-1
FBAD	BNE &FBB1   ;
FBAF	BCS &FBFE   ;


FBB1	BRK         ;
FBB2	DB  &DE     ;error number
FBB3	DB  'Channel' ;
FBBA	BRK         ;


************* read from second processor ********************************

FBBB	LDA #&01    ;A=1
FBBD	JSR &FBD3   ;check if second processor file test tube prescence
FBC0	BEQ &FBFE   ;if not exit
FBC2	TXA         ;A=X
FBC3	LDX #&B0    ;current load address
FBC5	LDY #&00    ;Y=00
FBC7	PHA         ;save A on stack
FBC8	LDA #&C0    ;filing system buffer flag
FBCA	JSR &0406   ;and out to TUBE
FBCD	BCC &FBCA   ;
FBCF	PLA         ;get back A
FBD0	JMP &0406   ;


*************** check if second processor file test tube prescence ******

FBD3	TAX         ;X=A
FBD4	LDA &B2     ;current load address high word
FBD6	AND &B3     ;current load address high word
FBD8	CMP #&FF    ;
FBDA	BEQ &FBE1   ;if &FF then its for base processor
FBDC	LDA &027A   ;&FF if tube present
FBDF	AND #&80    ;to set bit 7 alone
FBE1	RTS         ;return
    	;

******** control ACIA and Motor *****************************************

FBE2	LDA #&85    ;A=&85
FBE4	STA &FE10   ;write to serial ULA control register setting
FBE7	JSR &FB46   ;reset ACIA
FBEA	LDA #&10    ;A=16
FBEC	JSR &FB63   ;set ACIA to CFS baud rate
FBEF	JSR &F995   ;confirm ESC not set and CFS not executing
FBF2	LDA &FE08   ;read ACIA status register
FBF5	AND #&02    ;clear all but bit 1
FBF7	BEQ &FBEF   ;if clear FBEF
FBF9	LDA #&AA    ;else A=&AA
FBFB	STA &FE09   ;transmit data register
FBFE	RTS         ;return
    	;
FBFF	BRK         ;
\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/FC00 b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/FC00
new file mode 100644
index 0000000..177d500
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/FC00
@@ -0,0 +1 @@
+************** FRED 1MHz Bus memory-mapped I/O **************************

FC00	 ;test hardware
FC10-13 ;teletext
FC14-1F ;Prestel
FC20-27 ;IEEE interface
FC30	 ;
FC40-47 ;winchester disc interface
FC50	;
FC60	;
FC70	;
FC80	;
FC90	;
FCA0	;
FCB0	;
FCC0	;
FCD0	;
FCE0	;
FCF0	;
FCFF	;paging register for JIM expansion memory


************** JIM 1MHz Bus memory-expansion page ***********************

FD00-FF ;


FDFE	;Ecosoak Vector


************** SHEILA MOS memory-mapped I/O ***************************


    	;DEVICE         WRITE                   READ
FE00	;6845 CRTC      address register
FE01	;6845 CRTC      register file
FE02	;Border colour	border colour
FE03	;
FE04	;
FE05	;
FE06	;
FE07	;
FE08	;6850 ACIA      control register        status register
FE09	;6850 ACIA      transmit data           recieve data
FE0A	;
FE0B	;
FE0C	;
FE0D	;
FE0E	;
FE0F	;
FE10	;SERIAL ULA     control register
FE11	;
FE12	;
FE13	;
FE14	;
FE15	;
FE16	;
FE17	;
FE18	;68B54 ADLC     Disable interrupts      Econet station ID
FE19	;
FE1A	;
FE1B	;
FE1C	;
FE1D	;
FE1E	;
FE1F	;
FE20	;Video ULA      control register
FE21	;Video ULA      palette register        palette register
FE22	;
FE23	;
FE24	;
FE25	;
FE26	;
FE27	;
FE28	;
FE29	;
FE2A	;
FE2B	;
FE2C	;
FE2D	;
FE2E	;
FE2F	;
FE30	;ROM latch      paged ROM ID            write only
FE31	;ALTAIR         RAM protect
FE32	;
FE33	;
FE34	;Shadow RAM     B+ only         note different OS
FE35	;
FE36	;
FE37	;
FE38	;
FE39	;
FE3A	;
FE3B	;
FE3C	;
FE3D	;
FE3E	;
FE3F	;
FE40	;MOS 6522 VIA Output Register B                 Input Register B
FE41	;MOS 6522 VIA Output Register A                 Input Register A
FE42	;MOS 6522 VIA data direction register B
FE43	;MOS 6522 VIA data direction register A
FE44	;MOS 6522 VIA T1C-L  latches                    T1 low Order counter
FE45	;MOS 6522 VIA T1C-H  counter
FE46	;MOS 6522 VIA T1L-L low order latches
FE47	;MOS 6522 VIA T1L-H high order latches
FE48	;MOS 6522 VIA T2C-L latches                     T2C-L lo order counter
FE49	;MOS 6522 VIA T2C-H T2 high order counter
FE4A	;MOS 6522 VIA shift register
FE4B	;MOS 6522 VIA auxilliary control register ACR
FE4C	;MOS 6522 VIA Peripheral control register PCR
FE4D	;MOS 6522 VIA Interrupt  flag    register IFR
FE4E	;MOS 6522 VIA Interrupt enable   register IER
FE4F	;MOS 6522 VIA ORB/IRB but no handshake
FE50	;
FE51	;
FE52	;
FE53	;
FE54	;
FE55	;
FE56	;
FE57	;
FE58	;
FE59	;
FE5A	;
FE5B	;
FE5C	;
FE5D	;
FE5E	;
FE5F	;
FE60	;USER 6522 VIA Output Register B                Input Register B
FE61	;USER 6522 VIA Output Register A                Input Register A
FE62	;USER 6522 VIA data direction register B
FE63	;USER 6522 VIA data direction register A
FE64	;USER 6522 VIA T1C-L  latches                   T1 low Order counter
FE65	;USER 6522 VIA T1C-H  counter
FE66	;USER 6522 VIA T1L-L low order latches
FE67	;USER 6522 VIA T1L-H high order latches
FE68	;USER 6522 VIA T2C-L latches                    T2C-L lo order counter
FE69	;USER 6522 VIA T2C-H T2 high order counter
FE6A	;USER 6522 VIA shift register
FE6B	;USER 6522 VIA auxilliary control register ACR
FE6C	;USER 6522 VIA Peripheral control register PCR
FE6D	;USER 6522 VIA Interrupt  flag    register IFR
FE6E	;USER 6522 VIA Interrupt enable   register IER
FE6F	;USER 6522 VIA ORB/IRB but no handshake
FE70	;
FE71	;
FE72	;
FE73	;
FE74	;
FE75	;
FE76	;
FE77	;
FE78	;
FE79	;
FE7A	;
FE7B	;
FE7C	;
FE7D	;
FE7E	;
FE7F	;
FE80	;8271 FDC       command register                status register
FE81	;8271 FDC       parameter register              result register
FE82	;8271 FDC       reset register
FE83	;8271 FDC       illegal                         illegal
FE84	;8271 FDC       data                            data
FE85	;
FE86	;
FE87	;
FE88	;
FE89	;
FE8A	;
FE8B	;
FE8C	;
FE8D	;
FE8E	;
FE8F	;
FE90	;
FE91	;
FE92	;
FE93	;
FE94	;
FE95	;
FE96	;
FE97	;
FE98	;
FE99	;
FE9A	;
FE9B	;
FE9C	;
FE9D	;
FE9E	;
FE9F	;
FEA0	;68B54 ADLC     control register 1              status register 1
FEA1	;68B54 ADLC     control register 2/3            status register 2/3
FEA2	;68B54 ADLC     Tx FIFO (frame continue)        Rx      FIFO
FEA3	;68B54 ADLC     Tx FIFO (frame terminate)       Rx      FIFO
FEA4	;
FEA5	;
FEA6	;
FEA7	;
FEA8	;
FEA9	;
FEAA	;
FEAB	;
FEAC	;
FEAD	;
FEAE	;
FEAF	;
FEB0	;
FEB1	;
FEB2	;
FEB3	;
FEB4	;
FEB5	;
FEB6	;
FEB7	;

FEB8	;
FEB9	;
FEBA	;
FEBB	;
FEBC	;
FEBD	;
FEBE	;
FEBF	;
FEC0	;7002 ADC       data latch A/D start            status
FEC1	;7002 ADC       hi data byte
FEC2	;7002 ADC       lo data byte
FEC3	;
FEC4	;
FEC5	;
FEC6	;
FEC7	;
FEC8	;
FEC9	;
FECA	;
FECB	;
FECC	;
FECD	;
FECE	;
FECF	;
FED0	;
FED1	;
FED2	;
FED3	;
FED4	;
FED5	;
FED6	;
FED7	;
FED8	;
FED9	;
FEDA	;
FEDB	;
FEDC	;
FEDD	;
FEDE	;
FEDF	;
FEE0	;TUBE FIFO1     status register
FEE1	;TUBE FIFO1
FEE2	;TUBE FIFO2     status register
FEE3	;TUBE FIFO2
FEE4	;TUBE FIFO3     status register
FEE5	;TUBE FIFO3
FEE6	;TUBE FIFO4     status register
FEE7	;TUBE FIFO4
FEE8	;
FEE9	;
FEEA	;
FEEB	;
FEEC	;
FEED	;
FEEE	;
FEEF	;
FEF0	;
FEF1	;
FEF2	;
FEF3	;
FEF4	;
FEF5	;
FEF6	;
FEF7	;
FEF8	;
FEF9	;
FEFA	;
FEFB	;
FEFC	;
FEFD	;
FEFE	;
FEFF	;


********** EXTENDED VECTOR ENTRY POINTS**********************************
;vectors are pointed to &F000 +vector No. vectors may then be directed thru
;a three byte vector table whose XY address is given by osbyte A8, X=0, Y=&FF
;this is set up as lo-hi byte in ROM and ROM number

FF00	JSR &FF51   ;E USERV
FF03	JSR &FF51   ;E BRKV
FF06	JSR &FF51   ;E IRQ1V
FF09	JSR &FF51   ;E IRQ2V
FF0C	JSR &FF51   ;E CLIV
FF0F	JSR &FF51   ;E BYTEV
FF12	JSR &FF51   ;E WORDV
FF15	JSR &FF51   ;E WRCHV
FF18	JSR &FF51   ;E RDCHV
FF1B	JSR &FF51   ;E FILEV
FF1E	JSR &FF51   ;E ARGSV
FF21	JSR &FF51   ;E BGETV
FF24	JSR &FF51   ;E BPUTV
FF27	JSR &FF51   ;E GBPBV
FF2A	JSR &FF51   ;E FINDV
FF2D	JSR &FF51   ;E FSCV
FF30	JSR &FF51   ;E EVENTV
FF33	JSR &FF51   ;E UPTV
FF36	JSR &FF51   ;E NETV
FF39	JSR &FF51   ;E VDUV
FF3C	JSR &FF51   ;E KEYV
FF3F	JSR &FF51   ;E INSV
FF42	JSR &FF51   ;E REMV
FF45	JSR &FF51   ;E CNPV
FF48	JSR &FF51   ;E IND1V
FF4B	JSR &FF51   ;E IND2V
FF4E	JSR &FF51   ;E IND3V

;at this point the stack will hold 4 bytes (at least)
;S 0,1 extended vector address
;S 2,3 address of calling routine
;A,X,Y,P will be as at entry

FF51	PHA         ;save A on stack
FF52	PHA         ;save A on stack
FF53	PHA         ;save A on stack
FF54	PHA         ;save A on stack
FF55	PHA         ;save A on stack
FF56	PHP         ;save flags on stack
FF57	PHA         ;save A on stack
FF58	TXA         ;A=X
FF59	PHA         ;save X on stack
FF5A	TYA         ;A=Y
FF5B	PHA         ;save Y on stack
FF5C	TSX         ;get stack pointer into X (&F2 or less)
FF5D	LDA #&FF    ;A=&FF
FF5F	STA &0108,X ;A
FF62	LDA #&88    ;
FF64	STA &0107,X ;
FF67	LDY &010A,X ;this is VECTOR number*3+2!!
FF6A	LDA &0D9D,Y ;lo byte of action address
FF6D	STA &0105,X ;store it on stack
FF70	LDA &0D9E,Y ;get hi byte
FF73	STA &0106,X ;store it on stack
    	            ;at this point stack has YXAP and action address
    	            ;followed by return address and 5 more bytes
FF76	LDA &F4     ;
FF78	STA &0109,X ;store original ROM number below this
FF7B	LDA &0D9F,Y ;get new rom number
FF7E	STA &F4     ;store it as ram copy
FF80	STA &FE30   ;and switch ti that ROM
FF83	PLA         ;get back A
FF84	TAY         ;Y=A
FF85	PLA         ;get back A
FF86	TAX         ;X=A
FF87	PLA         ;get back A
FF88	RTI         ;get back flags and jump to ROM vectored entry
    	            ;leaving return address and 5 more bytes on stack


************ return address from ROM indirection ************************

;at this point stack comprises original ROM number,return from JSR &FF51,
;return from original call the return from FF51 is garbage so;

FF89	PHP         ;save flags on stack
FF8A	PHA         ;save A on stack
FF8B	TXA         ;A=X
FF8C	PHA         ;save X on stack
FF8D	TSX         ; (&F7 or less)
FF8E	LDA &0102,X ;STORE A AND P OVER
FF91	STA &0105,X ;return address from (JSR &FF51)
FF94	LDA &0103,X ;hiding garbage by duplicating A and X just saved
FF97	STA &0106,X ;
    	            ;now we have
    	            ;flags,
    	            ;A,
    	            ;X,
    	            ;Rom no.,
    	            ;A,
    	            ;flags,
    	            ;and original return address on stack
    	            ;so
FF9A	PLA         ;get back X
FF9B	TAX         ;X=A
FF9C	PLA         ;get back A lose next two bytes
FF9D	PLA         ;get back A lose
FF9E	PLA         ;get back A rom number
FF9F	STA &F4     ;store it
FFA1	STA &FE30   ;and set it
FFA4	PLA         ;get back A
FFA5	PLP         ;get back flags
FFA6	RTS         ;return and exit pulling original return address
    	            ;from stack
;FFA6 is also default input for CFS OSBPGB, VDUV, IND1V,IND2V,IND3V
;as these functions are not implemented by the OS but may be used
;by software or other filing systems or ROMs


*************************************************************************
*                                                                       *
*       OSBYTE &9D    FAST BPUT                                         *
*                                                                       *
*************************************************************************
FFA7	TXA         ;A=X
FFA8	BCS &FFD4   ;carry always set, jump to BPUT


*************************************************************************
*                                                                       *
*       OSBYTE &92      READ A BYTE FROM FRED                           *
*                                                                       *
*************************************************************************       ;

FFAA	LDY &FC00,X ;read a byte from FRED area
FFAD	RTS         ;return


*************************************************************************
*                                                                       *
*       OSBYTE &94      READ A BYTE FROM JIM                            *
*                                                                       *
*************************************************************************       ;
    	;
FFAE	LDY &FD00,X ;read a byte from JIM area
FFB1	RTS         ;return



*************************************************************************
*                                                                       *
*       OSBYTE &96      READ A BYTE FROM SHEILA                         *
*                                                                       *
*************************************************************************       ;
    	;
FFB2	LDY &FE00,X ;read a byte from SHEILA memory mapped I/O area
FFB5	RTS         ;return


*********** DEFAULT VECTOR TABLE ****************************************
    	
FFB6	DB  36      ;length of look up table in bytes
FFB7	DB  40      ;low byte of address of this table
FFB8	DB  D9      ;high byte of address of this table


**************************************************************************
**************************************************************************
**                                                                      **
**      OPERATING SYSTEM FUNCTION CALLS                                 **
**                                                                      **
**************************************************************************
**************************************************************************

FFB9	JMP &DC0B   ;OSRDRM get a byte from sideways ROM
FFBC	JMP &C4C0   ;VDUCHR VDU character output
FFBF	JMP &E494   ;OSEVEN generate an EVENT
FFC2	JMP &EA1E   ;GSINIT initialise OS string
FFC5	JMP &EA2F   ;GSREAD read character from input stream
FFC8	JMP &DEC5   ;NVRDCH non vectored OSRDCH
FFCB	JMP &E0A4   ;NVWRCH non vectored OSWRCH
FFCE	JMP (&021C) ;OSFIND open or close a file
FFD1	JMP (&021A) ;OSGBPB transfer block to or from a file
FFD4	JMP (&0218) ;OSBPUT save a byte to file
FFD7	JMP (&0216) ;OSBGET get a byte from file
FFDA	JMP (&0214) ;OSARGS read or write file arguments
FFDD	JMP (&0212) ;OSFILE read or write a file
FFE0	JMP (&0210) ;OSRDCH get a byte from current input stream
FFE3	CMP #&0D    ;OSASCI output a byte to VDU stream expanding
FFE5	BNE &FFEE   ; carriage returns (&0D) to LF/CR (&0A,&0D)
FFE7	LDA #&0A    ;OSNEWL output a CR/LF to VDU stream
FFE9	JSR OSWRCH  ;Outputs A followed by CR to VDU stream
FFEC	LDA #&0D    ;OSWRCR output a CR to VDU stream
FFEE	JMP (&020E) ;OSWRCH output a character to the VDU stream
FFF1	JMP (&020C) ;OSWORD perform operation using parameter table
FFF4	JMP (&020A) ;OSBYTE perform operation with single bytes
FFF7	JMP (&0208) ;OSCLI  pass string to command line interpreter


*************************************************************************
*                                                                       *
*       6502 Vectors                                                    *
*                                                                       *
*************************************************************************

FFFA	DW  &0D00   ;NMI   address
FFFC	DW  &D9CD   ;RESET address
FFFE	DW  &DC1C   ;IRQ   address

That's it the end of the series and the end of Micronet.

See you on the new system or in the paper mags.

Geoff


\ No newline at end of file
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/Microbase b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/Microbase
new file mode 100644
index 0000000..3251a42
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/Microbase
@@ -0,0 +1,1682 @@
+BBC MICROBASE SERIES
+BBC 6502 Machine Code by Geoff Cox
+----------------------------------
+This series was first published on Micronet
+between April and October 1991
+
+The BBC Micro Operating System
+Part One: The moving electron writes
+------------------------------------
+In the last series we reviewed the basics of machine code programming
+using the 6502. You will have noticed that not too many examples of
+programming were given. This is because there are two levels of
+programming on any machine, machine level and operating system level.
+
+Operating Systems
+-----------------
+An operating system is basically a group of routines that sit between
+the user and the electronics of the computer. To illustrate what an
+operating system does we have to turn briefly from the path of the
+series.
+
+We'll imagine that you want to write the letter A on the screen of
+your monitor. First we have to work out the shape of the character and
+slice it horizontally into eight sections, one for each of eight
+screen scanning lines on the monitor.
+
+Now we need to detect when the frame synchronising pulse for the
+monitor is sent by the computer. Next we need to count the line
+synchronising pulses to find the one corresponding to the start of the
+first line of the character.
+
+Then we must time from this pulse to the start of the first line of
+the character, turn on the appropriate electron guns in the monitor
+and turn them off at the correct time for the end of the of the
+character. Finally we have a few microseconds to do it all again for
+the next line. That's more or less what happens fifty times a second
+on your monitor screen.
+
+Mapped Screens
+--------------
+This makes even the easiest task very complex. We can make life easier
+by storing a picture or map of the screen in memory and writing the
+character shape to the appropriate map locations.
+
+The map can then be scanned in synchronisation with the electron beam
+on the monitor. This can either be via a clever piece of electronics
+or a software routine.
+
+To illustrate the BBC map, type the following program on any 6502-
+based BBC without screen RAM shadowing.
+
+10 MODE 0
+20 ?&7D00=65
+
+You should see two little white dots towards the bottom right of the
+screen. Now two dots are not the letter A so if we want to write A we
+have to designthe character and write it to the map. This program does
+just that.
+
+10 MODE 0
+20 FOR A=&7D00 TO &7D07
+30 READ B
+40 ?A=B
+50 NEXT
+60 DATA &3C, &66, &66, &7E
+70 DATA &66, &66, &66, &00
+
+The sharp-eyed among you will have spotted something a little odd
+here. The screen seems to be arranged in blocks of eight bytes in this
+mode. Don't worry about this - it simply makes character table design
+simpler.
+
+Character Tables
+----------------
+We can make life even easier by designing a set of characters and
+putting them in an area of memory where they can be looked up. In the
+BBC B this area is in ROM starting at &C000.
+
+A quick diversion here. If we have to have a series of character
+designs in memory it helps to have a standard method of accessing
+them.
+
+The standard character ordering is called ASCII. A space has ASCII
+number 32 and this is the first "printable" character in the set. The
+last is 127 (Delete). There are eight bytes in each character matrix
+so the design for any character is at &C000+(8*(ASCII - 32)).
+
+This program examines the ROM character table and shows how characters
+are arranged.
+
+10 MODE 0
+20 PRINT "CHARACTER ?"
+30 A$=GET$
+40 PRINT A$
+50 START=(8(ASC(A$)-32))+&C000
+60 FIN=START+7
+70 FOR BYTE=START TO FIN
+80 PEEK=?BYTE
+90 PROC_BIN
+100 PRINT~BYTE;TAB(15);~?BYTE;TAB(20);
+110 NEXT
+120 END
+130 DEFPROC_BIN
+140 A$=""
+150 FOR BIT=7 TO 0 STEP-1
+160 X=(PEEK AND 2^BIT)
+170 IF X>1 THEN A$=A$+"" ELSE A$=A$+"."
+180 NEXT
+190 ENDPROC
+
+As you will often want to write characters on the screen it makes a
+lot of sense to have a little routine to take a character from a
+register and print it on the screen.
+
+The routine will look up a character in the table and print it to the
+appropriate position on the screen. There will also need to be a
+record of the cursor position on the screen.
+
+Routines for printing and moving a cursor on the screen will also be
+useful. You could, of course, write all of these routines yourself as
+part of every program but as the computer manufacturer has to provide
+them in order to tell you the machine is working he usually leaves an
+access point for you to use the routines yourself.
+
+Incidentally if you rewrite the first program but change line 10 to
+read MODE 7 you will see a letter A on the screen.
+
+This is an example of clever electronics. A chip on the BBC board
+contains a character generator. Instead of the character design being
+stored in the screen map the character's ASCII value is stored. This
+is read by the electronics and used to generate characters directly on
+the screen. This allows a 40 x 80 text and block graphics screen to be
+generated in just 1K of RAM.
+
+Using the Operating System
+--------------------------
+The screen handling routines and several others make up an operating
+system. In the BBC micro the series of routines that write a character
+on the screen can be accessed though a point called OSWRCH at &FFFE.
+
+So instead of having to design characters, time lines and do all of
+the other things, you can output a letter A to the screen simply
+using:
+
+LDA #65
+JSR &FFEE ;OSWRCH
+
+and leave the operating system to do the rest.
+
+
+BBC 6502 Machine Code
+Part Two: In the beginning
+--------------------------
+Last week we looked at the reasons for an operating system and how it
+can simplify the programmer's task. Unfortunately you will not always
+be able to use the operating system. There may not be a suitable
+routine or it may be too slow. In these cases you have to write to the
+device itself. So to continue our look at machine code we need to
+examine programming with device handling and the operating system.
+
+This series will attempt to kill two birds with one stone by taking
+avery close look at Acorn's OS 1.20 used on Model Bs.
+
+This changed little for the B+ and Master so while the routines may be
+in a slightly different place the basic system will be the same. The
+Master uses 65C02 code which has a few extra instructions so there may
+be some differences in the length of the code.
+
+What you will need
+------------------
+A disassembler or machine code monitor that can handle 6502 or 65C02
+codes. If If you don't have either you can use:
+
+PRINT ~?address
+
+to get the hexadecimal codes which you can then look up in the back of
+the BBC User Guide to get the relevant command.
+
+Suitable Monitors are EXMON, BBC Monitor or the SYSTEM monitor. (I use
+"Maxim" - Ed.) If you have a single- stepping monitor like one of
+these, you will be able to trace some of the routines for yourself.
+
+For this series we will use standard 6502 mnemonics except that DB and
+DW will be used to show byte assignments rather than EQUS, EQUW and
+EQUB. This is because the disassembler I am using produces these codes
+and it's a lot easier to follow than convoluted BBC-type statements.
+
+First things first
+------------------
+Remember that an operating system is not a program in the usual sense.
+Normal programs have a defined entry and exit routines. An operating
+system can have a large number of entry and exit points as well as
+interlocking routines. So to examine the operating system we need a
+starting point.
+
+The 6502 regards memory as a series of 256-byte pages 0 to &FF (255).
+Any address can be considered to be a page number plus an offset
+within the page.  Both figures can be represented by a single byte. So
+address &FF01 is on Page &FF offset 01. The concept of offsets is very
+useful if you ever get involved in 80n86 programming.
+
+The BBC Manual gives a series of system entry points on page FF. Most
+of these are indirected through Page 2 and as we cannot guarantee what
+the contents of Page 2 should be (the vectors can be and are changed)
+these are useless as starting points. This leaves three sensible entry
+points.
+
+6502 Vectors
+FFFA DW &0D00      ;NMI address
+FFFC DW &D9CD      ;RESET address
+FFFE DW &DC1C      ;IRQ address
+
+The NMI address is in RAM so no joy there, but the other two look
+fine. The best is RESET as this is where the machine starts when it is
+turned on or BREAK is pressed. In the case of Model B and OS 1.20 that
+address is &D9CD, so what happens?
+
+In the beginning
+----------------
+Reset can be effected by turning on the computer or pressing BREAK. If
+it is a power-up then the system VIA and processor are reset
+electronically.
+
+If this is a power on situation then nothing has been set up. The
+first thing that happens when power is turned on is that the 6522
+VIAs, the processor and the floppy disc controller are reset. This is
+done by means of one of three printed circuit tracks. The tracks are
+RSTA, RST and NOTRESET.
+
+RSTA is only connected to the system 6522 Versatile Interface adaptor
+(VIA). This operates through a little resistor/capacitor circuit that
+only works when the power is turned on. The effect of this is that the
+6522 System VIA Interrupt Enable Register (IER) bits 0 to 6 will be
+clear (0) only if the reset is caused by a power on condition.
+
+If the Reset is caused by BREAK being pressed then the machine must
+have been on and therefore one or more of the System VIA IER bits will
+be set (to 1). If one or more bits are set then bit 7 of the VIA will
+also be set. This is used to determine the type of Reset. So let's
+look at the operating system more closely.
+
+D9CD LDA #&40  ;set NMI first instruction to RTI
+D9CF STA &0D00 ;NMI RAM start
+
+RESET is the ultimate Act of God as far as the machine is concerned.
+Anything could be happening so the operating system has to clean up
+the system as its first act.
+
+These first instructions just make sure that if a disc is running no
+more information will be read or written from or to the disc. This
+illustrates why you shouldn't press BREAK when a disc is being
+accessed!
+
+The next section sets up the stack:
+
++
+D9D2 SEI      ;disable interrupts just in case
+D9D3 CLD      ;clear decimal flag
+D9D4 LDX #&FF ;reset stack to where it should be
+D9D6 TXS      ;(&1FF)
+
+Next find out if a power-up reset or a BREAK press by examining the
+System VIA IER register.
+
+D9D7 LDA &FE4E ;read interrupt enable register of the system VIA
+D9DA ASL       ;shift bit 7 into carry
+D9DB PHA       ;save what's left
+D9DC BEQ &D9E7 ;if Power up A=0 so go to D9E7 to clear memory
+
+That's probably enough for this time. Don't worry! I don't intend to
+do a complete disassembly of the operating system in this series but
+we will follow through the power-on sequence to the end because a lot
+of interesting things happen at this time.
+
+We'll take a look at D9E7 and the next routine in this sequence (D9DE)
+in the next part.
+
+
+BBC 6502 Machine Code
+Part Three: Cleaning up the mess
+--------------------------------
+In the last part we looked at what happens when you press BREAK or
+switch on the machine. We'll now continue with a look at an
+undocumented (at least officially) routine.
+
+The byte at &258 can be used to contain information about what the
+machine should do if BREAK is pressed. FX200,n is used to set this
+byte. If n=2 or n=3 then the memory must be cleared. This is often
+used in program protection.
+
+D9DE LDA &0258 ;else if BREAK pressed read BREAK Action flags (set by FX200,n)
+D9E1 LSR       ;divide by 2
+D9E2 CMP #&01  ;if &0258 <> 2 or 3
+D9E4 BNE &DA03 ;then Goto &DA03
+D9E6 LSR       ;divide A by 2 again (A=0 if FX200,2/3 else A=n/4
+
+Pages 4-&7F are cleared by a simple loop if &258=2 or 3 or it is a
+power on reset. Look out for the clever way of avoiding problems on
+16K machines.
+
+D9E7 LDX #&04    ;get page to start clearance from (4)
+D9E9 STX &01     ;store it in ZP 01
+D9EB STA &00     ;store A at 00
+D9ED TAY         ;and in Y to set loop counter
+                 ;LOOP STARTS
+D9EE STA (&00),Y ;clear RAM
+D9F0 CMP &01     ;until page address (in &01) =0
+D9F2 BEQ &D9FD   ;
+D9F4 INY         ;increment pointer
+D9F5 BNE &D9EE   ;if not zero loop round again
+D9F7 INY         ;else increment again (Y=1) this avoids overwriting the RTI
+                 ;instruction at &D00
+D9F8 INX         ;increment X
+D9F9 INC &01     ;increment &01
+D9FB BPL &D9EE   ;loop until Page (in 01)=&80 then exit
+
+Note that RAM addressing for 16K loops around to &4000=&00 hence the
+checking of &01 for 00. This avoids overwriting zero page on BREAK
+which would cause the machine to crash!
+
+D9FD STX &028E   ;writes marker for available RAM 40 =16K,80=32
+DA00 STX &0284   ;write soft key consistency flag
+
+This routine shows the basic structure of a loop. Those of you who
+program in BASIC will recognise it as a very simple structure:
+
+10 A=A+1
+20 IF A<20 GOTO 10
+
+The loop uses zero page addressing with the target address in 00 and
+01 (Page) and the index in Y.
+
+The loop is exited when the value in 01 becomes negative. Remember
+that all values between 0 and &7F are considered to be positive, so
+the BPL instruction can be used to exit the loop at page &80, the
+first negative number. This is the first of the useful loop techniques
+we'll see in this series.
+
+Notice that the first byte of each page is left unchanged. This is
+useful if you want information to survive a BREAK of this type. This
+clearing of memory is not normally carried out.
+
+Next week we'll have a look at the normal RESET path.
+
+BBC 6502 Machine Code
+Part Four: Cleaning up even more mess
+-------------------------------------
+As we saw last week, a normal warm reset avoids the memory clearance
+and proceeds to set up the System VIA.
+
+DA03 LDX #&0F  ;set PORT B data direction register to output on bits
+               ;0-3 and input bits 4-7
+DA05 STX &FE42 ;
+
+The next bit is a little more complicated and is intimately bound up
+with hardware. The function is to set up the addressable latch IC 32
+for peripherals via PORT B.
+
+The latch value is written by writing the value to &FE40 bits 0 to 2
+and either a 1 or 0 to bit 3.
+
+Writing the value + 8 therefore writes a 1 to the latched address,
+otherwise a 0 is written.
+
+Value    Peripheral   Effect
++                     0        8
+
+0        Sound chip   Enabled  Disabled
+         Speech Chip
+1        (RS)         Low      High
+2        (WS)         Low      High
+2        (WS)         Low      High
+3        Keyboard
+         Write        Disabled Enabled
+4        C0 address
+         modifier     Low      High
+5        C1 address
+         modifier     Low      High
+6        Caps LED     On       Off
+7        Shift LED    On       Off
+
+C0 and C1 are involved with hardware scroll screen address.
+
+                     ;X=&F on entry
+DA08   DEX           ;loop start
+DA09   STX   &FE40   ;Write latch IC32
+DA0C   CPX   #&09    ;Is it 9?
+DA0E   BCS   &DA08   ;If not go back and do it again
+                     ;X=8 at this point
+                     ;Caps Lock On, SHIFT Lock undetermined
+                     ;Keyboard Autoscan on
+                     ;Sound disabled (may still sound)
+
+Next the keyboard is scanned to determine the values of the keyboard
+links and whether a Ctrl-Break has been performed.
+
+Remember that although we have spent a lot of time reading this, we
+are probably less than 200 microseconds after BREAK was pressed.
+
+The check for Ctrl-Break is effectively looking for simultaneous
+keypresses.
+
+DA10   INX           ;X=9
+DA11   TXA           ;A=X
+DA12   JSR   &F02A   ;Interrogate keyboard
+DA15   CPX   #&80    ;for keyboard links 9-2 and CTRL key (1)
+DA17   ROR   &FC     ;rotate MSB into bit 7 of &FC
+
+DA19   TAX           ;Get back value of X for loop
+DA1A   DEX           ;Decrement it
+DA1B   BNE   &DA11   ;and if >0 do loop again
+                     ;On exit if Carry set link 3 is made
+                     ;link 2 = bit 0 of &FC and so on
+                     ;If CTRL pressed bit 7 of &FC=1 X=0
+DA1D   STX   &028D   ;Clear last BREAK flag
+DA20   ROL   &FC     ;CTRL is now in carry &FC is keyboard links
+DA22   JSR   &EEEB   ;Set LEDs
+                     ;Carry set on entry is in bit 7 of A on exit
+DA25   ROR           ;Get carry back into carry flag
+
+To review what the operating system has done so far, about 400
+microseconds after a BREAK press or about 2 milliseconds from a power
+on. Memory may have been cleared, NMIs have been short circuited, IRQs
+disabled. The keyboard has been scanned for made links and for Ctrl
+being pressed.
+
+We have also located two important and undocumented subroutines: &F02A
+to scan the keyboard and &EEEB to set the keyboard LEDs.
+
+The F02A routine scans for the key whose code is in X being pressed:
+
+F02A   LDY   #&03  ;Stop Auto scan
+F02C   STY   &FE40 ;by writing to system VIA
+F02F   LDY   #&7F  ;Set bits 0 to 6 of port A to input on bit 7.
+                   ;Output on bits 0 to 6
+F031   STY   &FE43 ;
+F034   STX   &FE4F ;Write X to Port A system VIA (key to check)
+F037   LDX   &FE4F ;Read back &80 if key pressed (M set)
+F03A   RTS         ;And return
+
+The routine at &EEEB switches on the selected keyboard lights.
+
+EEEB   PHP          ;Save flags
+EEEC   LDA   &025A  ;Read keyboard status
+                    ;Bit 7=1 shift enabled
+                    ;Bit 6=1 control pressed
+                    ;Bit 5 =0 shift lock
+                    ;Bit 4 =0 Caps lock
+                    ;Bit 3 =1 shift pressed
+EEEF   LSR          ;Shift Caps bit into bit 3
+EEF0   AND   #&18   ;Mask out all but 4 and 3
+EEF2   ORA   #&06   ;Returns 6 if caps lock OFF &E if on.
+                    ;Remember add 8 to the value for the addressable
+                    ;latch to send a 1.
+EEF4   STA   &FE40  ;Turn on or off caps light if required
+EEF7   LSR          ;Bring shift bit into bit 3
+EEF8   ORA   #&07   ;
+EEFA   STA   &FE40  ;Turn on or off shift lock light
+EEFD   JSR   &F12E  ;Set keyboard counter
+EF00   PLA          ;Get back flags into A
+EF01   RTS          ;Return
+
+In this part we've had a look at subroutines using JSR and RTS, the
+machine code equivalent of GOSUB, PROC or FN. Subroutines are often
+used in machine code to perform such frequently needed functions as
+scanning a keyboard or turning on and off lights.
+
+We've also discovered that the byte at &25A contains the keyboard
+status. Try changing it for yourself. You can therefore use OR and AND
+to set the shift and Caps lock status of the machine for a particular
+program.
+
+Next week we'll examine setting up the default vector table in memory.
+
+BBC 6502 Machine Code
+Part Five: Vectors Victor
+-------------------------
+The next stage is to set up the vectors on page 2.
+
+DA26   LDX   #&9C  ;
+DA28   LDY   #&8D  ;
+DA2A   PLA         ;Get back A from &D9DB
+DA2B   BEQ   &DA36 ;If A=0 power up reset so go to DA36 with X=&9C
+                   ;Y=&8D
+DA2D   LDY   #&7E  ;else let Y=&7E
+DA2F   BCC   &DA42 ;and if not CTRL- BREAK go to DA42 for a WARM RESET
+DA31   LDY   #&87  ;else Y=&87 COLD RESET
+DA33   INC   &028D ;&28D=1
+DA36   INC   &028D ;&28D=&28D+1
+DA39   LDA   &FC   ;Get keyboard links set
+DA3B   EOR   #&FF  ;Invert
+DA3D   STA   &028F ;and store at &28F
+DA40   LDX   #&90  ;X=&90
+
+What we have done is to set up the high water marks for the reset of
+vectors.
+
+&28D=0 Warm reset, X=&9C, Y=&7E
+&28D=1 Power up  , X=&90, Y=&8D
+&28D=2 Cold reset, X=&9C, Y=&87
+
+DA42   LDA   #&00    ;A=0
+DA44   CPX   #&CE    ;zero &200+X to &2CD
+DA46   BCC   &DA4A   ;
+DA48   LDA   #&FF    ;then set &2CE to &2FF to &FF
+DA4A   STA   &0200,X ;
+DA4D   INX           ;
+DA4E   BNE   &DA44   ;
+                     ;A=&FF X=0
+
+This is another IF-GOTO loop, but in this case it is a double function
+loop. The test at DA44 to DA46 means that A is 0 only for values of X
+between the high water mark and &CD. Above this value A is set to &FF
+by the instruction at &DA48. This saves a few bytes of space,
+essential when writing a tightly-filled ROM.
+
+The next instructions set up the printer port. The only reason for
+doing this now is to save two bytes. A must be &FF at this point so it
+is used to set up the User VIA for outputs as the printer port.
+
+DA50   STA   &FE63   ;Set port A of user VIA to all outputs (printer out)
+DA53   TXA           ;A=0
+DA54   LDX   #&E2    ;X=&E2
+
+START OF LOOP
+DA56   STA   &00,X   ;set zero page addresses &E2 to &FF to zero
+DA58   INX           ;
+DA59   BNE   &DA56   ;X=0
+
+Now set up the vectors in page 2 from the table at &D940:
+
+DA5B   LDA   &D93F,Y ;copy data from &D93F+Y
+DA5E   STA   &01FF,Y ;to &1FF+Y
+DA61   DEY           ;until
+DA62   BNE   &DA5B   ;1FF+Y=&200
+
+Note that this is a decrementing loop which, for loops ending when an
+index register reaches zero, is faster and shorter because no compare
+is needed. More space saved!
+
+Now the RS423 port is set up via a subroutine affecting the ACIA.
+(Asynchronous Communications Interface Adaptor)
+
+DA64   LDA   #&62    ;A=&62
+DA66   STA   &ED     ;store in &ED
+DA68   JSR   &FB0A   ;set up ACIA ;X=0
+
+Now Acorn clears the interrupt and enable registers of both VIAs.
+
+DA6B   LDA   #&7F    ;bit 7 is 0!
+DA6D   INX           ;
+DA6E   STA   &FE4D,X ;
+DA71   STA   &FE6D,X ;
+DA74   DEX           ;
+DA75   BPL   &DA6E   ;
+                     ;This loop only has two passes as X=0 on entry.
+DA77   CLI           ;Briefly allow interrupts to clear anything
+                     ;pending
+DA78   SEI           ;Disallow again NB: all VIA IRQs are disabled
+DA79   BIT   &FC     ;If bit 6=1 then JSR &F055 as there must be a
+                     ;hardware interrupt!
+DA7B   BVC   &DA80   ;else DA80
+DA7D   JSR   &F055   ;
+
+What have we here? Another undocumented routine. If bit 6 of &FC is
+set there must have been a hardware interrupt when the SEI occurred.
+
+From the circuit diagram the only place that this IRQ could have come
+from is the 1MHz bus - let's have a look at the routine at &F055.
+
+F055   JMP   (&FDFE) ;Jim paged entry vector
+
+So we jump to some piece of hardware on the 1MHz bus. This would
+probably be a ROM which would take over the system at power on and
+Break. This has some very interesting applications. It was designed by
+Acorn to provide a crude Econet facility to allow a batch of machines
+to be functionally tested without the need to install a full Econet
+kit.
+
+Next week we shall examine the VIA bus.
+
+BBC 6502 Machine Code
+Part Six: The VIA bus
+---------------------
+The next interesting routine we find in the BBC operating system is
+the one that sets up the system VIA interrupts. It is located at
+&DA80. Refer to the manual for the meanings of Sheila addresses.
+
+DA80   LDX   #&F2  ;Enable interrupts 1,4,5,6 of system VIA
+DA82   STX   &FE4E ;
+                   ;0 Keyboard enabled as needed
+                   ;1 Frame sync pulse
+                   ;4 End of A/D conversion
+                   ;5 T2 counter (for speech)
+                   ;6 T1 counter (10 mSec intervals)
+
+DA85   LDX   #&04  ;set system VIA PCR
+DA87   STX   &FE4C ;
+                   ;CA1 Interrupt on negative edge (Frame sync)
+                   ;CA2 Handshake output for keyboard
+                   ;CB1 Interrupt on negative edge (end of conversion)
+                   ;CB2 Negative edge (Light pen strobe)
+DA8A   LDA   #&60  ;Set system VIA ACR
+DA8C   STA   &FE4B ;
+                   ;Disable latching
+                   ;Disable shift register
+                   ;T1 counter continuous interrupts
+                   ;T2 counter timed interrupt
+
+DA8F   LDA   #&0E  ;Set system VIA T1 counter (low)
+DA91   STA   &FE46 ;
+                   ;This becomes effective when T1 hi set
+DA94   STA   &FE6C ;Set user VIA PCR
+                   ;CA1 interrupt on -ve edge (Printer Acknowledge)
+DA80   LDX   #&F2  ;enable interrupts
+                   ;CA2 High output (printer strobe)
+                   ;CB1 Interrupt on -ve edge (user port)
+                   ;CB2 Negative edge (user port)
+DA97   STA   &FEC0 ;Set up A/D converter Bits 0 and 1 determine
+                   ;channel selected
+                   ;If Bit 3=0 it is set for an 8-bit conversion.
+                   ;If bit 3=1 12-bit conversion.
+
+Now although the machine now knows how much RAM it has it still
+doesn't know if it's a Model A or Model B, so it does not know if a
+user VIA is present at &FE60-FE6F.
+
+The next routine tests for the presence of a user VIA. The system
+timers are then set up to interrupt every 10mSec. Sound channels are
+cleared and the serial ULA is set up. Then the function keys are
+reset.
+
+Now we need a catalogue of sideways ROMS. This is not a catalogue in
+the conventional sense as the ROM title is always at the same place in
+the ROM itself and can be read from there. It is a catalogue of the
+ROM types and positions.
+
+There is a ROM latch at &FE30. Writing a number between 0 and 15 to
+this switches the corresponding ROM into the area between &8000 and
+&BFFF. A short subroutine does this and maintains a copy of the
+current ROM in zero page at location &F4.
+
+                   ;on entry X=required ROM number
+DC16   STX   &F4   ;RAM copy of ROM latch
+DC18   STX   &FE30 ;Write to ROM latch
+DC1B   RTS         ;and return
+
+You should use this subroutine if you want to switch ROMs. Now we can
+look at the ROM cataloguing routines;
+
+A ROM is considered to be valid if it contains a string identical to
+astring at location &DF0C in the Operating System ROM.
+
+DF0C   DB    ')C('   ;
+DF0F   DB    0       ;
+
+The location of this string is pointed to by an offset byte located at
+&8007.
+
+;X=0 on entry
+DABD   JSR   &DC16   ;Set up ROM latch and RAM copy to X
+DAC0   LDX   #&03    ;Set X to point to offset in table
+DA80   LDX   #&F2    ;Enable interrupts
+DAC2   LDY   &8007   ;Get copyright offset from ROM
+DAC5   LDA   &8000,Y ;Get first byte
+DAC8   CMP   &DF0C,X ;Compare it with table byte
+DACB   BNE   &DAFB   ;If not the same then goto DAFB
+DACD   INY           ;Point to next byte
+DACE   DEX ;(s)
+DACF   BPL   &DAC5   ;and if still +ve go back to check next byte.
+                     ;This point is reached if 4 bytes indicate
+                     ;valid ROM
+
+Next the first 1K of each ROM is checked against higher priority ROMs
+to ensure that there are no matches. If a match is found, the lower
+priority ROM is ignored.
+
+A ROM type byte is located at &8006. A catalogue of these bytes is
+held at &2A1-&2B0. If bit 7 of this byte is 0 then the ROM is BASIC.
+The position of this ROM is stored at  &24B.
+
+Now the ROMs are catalogued it is time to set up the speech system and
+screen. More about that next week.
+
+BBC 6502 Machine Code
+Part Seven: Talk to me
+----------------------
+The operating system start-up routines next checks the SPEECH system.
+At this point the X register is set to 16 (&10) by previous routines.
+
+This is one of the reasons why this routine is inserted here. Setting
+X to the required value would use two more bytes. This is not much
+space but it can make the difference between all of the OS fitting
+into a single ROM and a complete hardware or software redesign.
+
+DB11  BIT  &FE40  ;If bit 7 low then we have speech system fitted
+DB14  BMI  &DB27  ;else goto DB27 for screen set up routine.
+DB16  DEC  &027B  ;(027B)=&FF a RAM flag that indicates that a speech
+                  ;chip is present.
+DB19  LDY  #&FF   ;Y=&FF
+DB1B  JSR  &EE7F  ;Initialise speech generator
+DB1E  DEX         ;via this
+DB1F  BNE  &DB19  ;loop
+
+Now X = 0 so:
+
+DB21  STX  &FE48  ;Set T2 timer for speech
+DB24  STX  &FE49  ;
+
+Screen set-up
+-------------
+X=0 on entry to this routine which gets the default screen mode and
+then goes off to the screen setup routine.
+
+DB27  LDA  &028F  ;Get back start up options (mode)
+DB2A  JSR  &C300  ;then jump to initialise screen.
+
+One of the things that I wondered when I got a BBC was how the RESET
+key could possibly act as a soft key. As we all know BREAK acts as
+soft key 10. But the keyboard buffer is cleared by the Reset. Tucked
+away is the five-byte routine that makes the BREAK key act as soft
+key 10.
+
+Soft keys work by inserting a byte greater than 127 into the keyboard
+buffer. &CA is the code for key 10.
+
+DB2D  LDY  #&CA   ;Y=&CA
+DB2F  JSR  &E4F1  ;to enter this value in the keyboard buffer
+
+Simple isn't it? You can use the routine yourself although further
+investigation will show that E4F1 is part of an OSbyte call. Remember
+that the keyboard buffer is buffer 0.
+
+E4F1  LDX  #&00  ;X=0 keyboard buffer
+
+**************************************
+*                                    *
+*   OSBYTE 153 Put byte in input     *
+*    Buffer checking for ESCAPE      *
+*                                    *
+**************************************
+
+On entry X = buffer number which is either 0 or 1. If it's 0 then the
+keyboard buffer is selected. If it's 1 then it is the RS423 buffer.
+
+Notice that the JSR to EF41 ensures that ONLY the keyboard buffer can
+be selected. Once again we are looking at coding economy, in this case
+with a specific keyboard buffer entry routine. Y contains the
+character to be written.
+
+E4F3  TXA         ;A=buffer number
+E4F4  AND  &0245  ;and with RS423 mode (0 treat as keyboard 1 ignore
+                  ;Escapes no events no soft keys)
+E4F7 BNE &E4AF    ;so if RS423 buffer AND RS423 in normal mode (1) E4AF
+                  ;
+E4F9 TYA          ;else Y=A character to write
+E4FA  EOR  &026C  ;compare with current escape ASCII code (0=match)
+E4FD  ORA  &0275  ;or with current ESCAPE status (0=ESC, 1=ASCII)
+E500  BNE  &E4A8  ;if ASCII or no match E4A8 to enter byte in buffer
+E502  LDA  &0258  ;else get ESCAPE / BREAK action byte
+E505  ROR         ;Rotate to get ESCAPE bit into carry
+E506  TYA         ;get character back in A
+E507  BCS  &E513  ;and if escape disabled exit with carry clear
+E509  LDY  #&06   ;else signal EVENT 6 Escape pressed
+E50B  JSR  &E494  ;
+E50E  BCC  &E513  ;if event handles ESCAPE then exit with carry clear
+E510  JSR  &E674  ;else set ESCAPE flag
+E513  CLC         ;clear carry
+E514  RTS         ;and exit
+
+This routine will normally be accessed by assembly language
+programmers by OSbyte 138 which calls EF43.
+
+BBC 6502 Machine Code
+Part Eight: Breaker Break
+-------------------------
+One of the 'secret' features of the BBC Micro OS 1.20 when it was
+arrived was the BREAK intercept. This is a useful method of taking
+over the machine and is sometimes used by ROM software.
+
+There are two entry points, entered with the carry flag reset to 0 and
+set to 1 respectively. The first call comes before sideways ROM calls.
+
+Enter BREAK intercept with Carry Clear
+
+DB32  JSR  &EAD9  ;check to see if BOOT address is set up if so
+                  ;JMP to it
+
+The address &287 is written by OSbyte 247 and the jump addresses in
+&288 and &289 by OSbytes 248 and 249. The machine code for JMP is &4C.
+
+EAD9  LDA  &0287  ;get BREAK vector code
+EADC  EOR  #&4C   ;produces 0 if JP (4C) not in &287
+EADE  BNE  &EAF3  ;if not goto EAF3
+EAE0  JMP  &0287  ;else jump to use BREAK code
+EAF3  RTS         ;Return
+
+The RTS at the end of another routine is used because it saves code.
+
+Frequently you will find machine code routines where a lot of branches
+go to a single RTS for just this reason. If you are writing your own
+code remember that the RTS must be within range of the branch. One of
+the most common assembler errors is a branch out of range that in turn
+causes more errors when you add an extra RTS.
+
+Obviously at this point the machine could be totally in your control.
+You can return control to the OS with an RTS or just continue on your
+merry way.
+
+Remember that the sideways ROMs don't have any workspace yet and you
+can't really run BASIC or any other language as the workspace will not
+exist. But, assuming that you don't want to do any of this, let's go
+back to the OS routines after testing for BREAK intercept.
+
+DB35  JSR  &F140  ;set up cassette options
+DB38  LDA  #&81   ;test for tube to FIFO buffer 1
+DB3A  STA  &FEE0  ;
+DB3D  LDA  &FEE0  ;
+DB40  ROR         ;put bit 0 into carry
+DB41  BCC  &DB4D  ;if no tube then DB4D
+DB43  LDX  #&FF   ;else
+DB45  JSR  &F168  ;issue ROM service call &FF to initialise TUBE system
+DB48  BNE  &DB4D  ;if not 0 on exit (tube not initialised) DB4D
+DB4A  DEC  &027A  ;else set tube flag to show its active
+
+Now the Tube is flagged as active, or not as the case may be. We
+continue next week, with the setup routines for the sideways ROMs.
+
+BBC 6502 Machine Code
+Part Nine:  A ROM with a view
+-----------------------------
+Now we nearly have a working system, we are, perhaps, 400 milliseconds
+into the Power up routine. Now is the time to set up all of those nice
+sideways ROMs we catalogued earlier.
+
+First we set up workspace and hence the value of BASIC's PAGE
+variable. The call to ROMs is made via F168. This is available to the
+programmer as OSBYTE 143.
+
+A ROM can have a number between 0 and 15 and will have two entry
+points - a Service entry at &8003 and a Language entry at &8000. If
+the ROM does not contain language code it will not have a language
+entry.
+
+ROMs are paged into main memory by writing the ROM number to a latch
+at &FE30. Hardware could be arranged to allow 256 ROMs although the
+operating system does not support this.
+
+The Break Intercept code could be used to make drastic hardware
+modifications like this.
+
+**************************************
+*                                    *
+* OSBYTE 143                         *
+* Pass service commands              *
+* to sideways ROMs                   *
+*                                    *
+**************************************
+                   ;on entry X=command number
+F168  LDA  &F4     ;get current ROM number
+F16A  PHA          ;store it
+F16B  TXA          ;command in A
+F16C  LDX  #&0F    ;set X=15
+
+The next bit of code is a countdown loop to send the command code to
+each enabled ROM in turn. The Map at &2A1 is used to decide which ROMs
+are active. Note the use of a countdown loop. This gives code economy
+and explains why the highest ROM number has priority.
+
+F16E  INC  &02A1,X ;read bit 7 on ROM map (no ROM has type 254 &FE)
+F171  DEC  &02A1,X ;
+F174  BPL  &F183   ;if not set (+ve result)
+F176  STX  &F4     ;else store ROM number in &F4
+F178  STX  &FE30   ;switch in paged ROM
+F17B  JSR  &8003   ;and jump to service entry
+F17E  TAX          ;on exit put A in X
+F17F  BEQ  &F186   ;if 0 (command recognised by ROM) reset ROMs & exit
+F181  LDX  &F4     ;else point to next lower ROM
+F183  DEX          ;
+F184  BPL  &F16E   ;and go round loop again
+F186  PLA          ;get back original ROM number
+F187  STA  &F4     ;store it in RAM copy
+F189  STA  &FE30   ;select original page
+F18C  TXA          ;put X back in A
+F18D  RTS          ;and return
+
+Couldn't be easier! So we can now return to the main body of the
+routine.
+
+DB4D  LDY  #&0E    ;set current value of PAGE
+DB4F  LDX  #&01    ;issue call to claim absolute workspace
+DB51  JSR  &F168   ;via F168
+DB54  LDX  #&02    ;send private workspace claim call
+DB56  JSR  &F168   ;via F168
+
+OSHWM is OS High Water Mark. The highest address used by the operating
+system.
+
+DB59  STY  &0243   ;set primary OSHWM
+DB5C  STY  &0244   ;set current OSHWM
+DB5F  LDX  #&FE    ;issue call for Tube to explode character set etc.
+DB61  LDY  &027A   ;Y=FF if tube present else Y=0
+DB64  JSR  &F168   ;and make call via F168
+
+We now have the machine set up to enter a language, all the filing
+systems have been set up and the sideways ROMs activated.
+
+Next week we finally start the screen messages.
+
+BBC 6502 Machine Code
+Part Ten:  Stringing it along
+-----------------------------
+The next routine shows why the Machine start up message is not always
+seen on third-party kit.
+
+DB67  AND  &0267  ;if A=&FE and bit 7 of 0267 is set then continue
+DB6A  BPL &DB87   ;else ignore start up message
+DB6C  LDY  #&02   ;output to screen
+DB6E  JSR  &DEA9  ;'BBC Computer ' message
+
+Looking at the routine in DEA9 we find a very useful string printing
+routine. Remember that Y = 2 on entry.
+
+DEA9  LDA  #&C3   ;point to start &C300
+DEAB  STA  &FE    ;store it
+DEAD  LDA #&00   ;point to lo byte
+DEAF  STA  &FD    ;store it and start loop with Y=2
+DEB1  INY         ;print character in string
+DEB2  LDA (&FD),Y ;pointed to by &FD/E +Y
+DEB4  JSR  OSASCI ;print it expanding Carriage returns
+DEB7  TAX         ;store A in X
+DEB8  BNE  &DEB1  ;and loop again if not =0
+DEBA  RTS         ;else exit
+
+Here is the string delimited by BRK. The code for BRK is 00. Y is 3
+when the first character is read so its address is &C303.
+
+C303  DB  13      ;Carriage Return
+C304  DB 'BBC Computer '
+C311  BRK
+
+Notice that the routine uses TAX to set the zero flag which marks the
+end of the string. This is a useful tip.
+
+The next part of the Operating system deals with printing correct
+messages on the screen.
+
+DB71  LDA  &028D  ;0=warm reset, If a cold reset continue
+DB74  BEQ  &DB82  ;
+DB76  LDY  #&16   ;by checking length of RAM
+DB78  BIT  &028E  ;
+DB7B  BMI  &DB7F  ;and either
+DB7D  LDY  #&11   ;
+DB7F  JSR  &DEA9  ;finishing message with '16K' or '32K'
+DB82  LDY  #&1B   ;and two new lines
+DB84  JSR  &DEA9  ;
+
+Notice that Y is used to pick the appropriate message.
+
+C312  DB  '16K'
+C315  DB  7       ;Bell
+C316  BRK
+C317  DB  '32K'
+C31A  DB  7       ;Bell
+C31B  BRK
+C31C  DB  08,0D,0D
+
+Notice the BBC Beep at this point indicates that nearly all set up
+procedures have been finished.
+
+The hum is generated by the Sound channel which is reset as part of
+the start routine. Hence the HUM-BEEP start up. If the machine does
+not start properly the sound signals give a strong clue to the nature
+of the problem. Having got this far the OS gives us another chance to
+take control.
+
+Enter BREAK INTERCEPT ROUTINE WITH CARRY SET (call 1)
+
+DB87  SEC         ;
+DB88  JSR  &EAD9  ;look for break intercept jump
+                  ;SEE EARLIER PART
+
+Next we set up the keyboard lights
+
+DB8B  JSR  &E9D9  ;set up LEDs in accordance with keyboard status
+
+This is another 'undocumented' OSBYTE call.
+
+**************************************
+*                                    *
+* OSBYTE &76 (118)                   *
+* SET LEDs to Keyboard Status        *
+*                                    *
+**************************************
+;osbyte entry with carry set
+E9D9  PHP ;PUSH P
+E9DA  SEI         ;DISABLE INTERRUPTS
+E9DB  LDA  #&40   ;switch on CAPS and SHIFT lock lights
+E9DD  JSR  &E9EA  ;via subroutine
+E9E0  BMI  &E9E7  ;if ESCAPE exists (M set) E9E7
+E9E2  CLC         ;else clear V and C
+E9E3  CLV         ;before calling main keyboard routine to
+E9E4  JSR  &F068  ;switch on lights as required
+E9E7  PLP ;get back flags
+E9E8  ROL         ;and rotate carry into bit 0
+E9E9  RTS ;Return to calling routine
+                  ;
+* Turn on keyboard lights and
+* Test Escape flag
+                  ;
+E9EA  BCC  &E9F5  ;if carry clear
+E9EC  LDY  #&07   ;switch on shift lock light
+E9EE  STY  &FE40  ;
+E9F1  DEY         ;Y=6
+E9F2  STY  &FE40  ;switch on Caps lock light
+E9F5  BIT  &FF    ;set minus flag if bit 7 of &00FF is set indicating
+E9F7  RTS         ;that ESCAPE condition exists, then return
+
+The Keyboard routine continues via the KEYV. This is a little long to
+include here so we'll leave it until a later part. So back to the
+Start up routine next week with the cassette system.
+
+BBC 6502 Machine Code
+Part Eleven: Language!
+----------------------
+Having got the keyboard nicely set up the machine proceeds to
+initialise a filing system and run a !BOOT file if one exists. The
+start up options are already read from the keyboard links.
+
+DB8E  PHP         ;save flags
+DB8F  PLA         ;and get back in A
+DB90  LSR         ;zero bits 4-7 and bits 0-2 bit 4 which was bit 7
+DB91  LSR         ;may be set
+DB92  LSR         ;
+DB93  LSR         ;
+DB94  EOR  &028F  ;EOR with start up options which may or may not
+DB97  AND  #&08   ;invert bit 4
+DB99  TAY         ;Y=A
+DB9A  LDX  #&03   ;make initialisation call, if Y=0 on entry
+DB9C  JSR  &F168  ;RUN, EXEC or LOAD !BOOT file from a filing system.
+DB9F  BEQ  &DBBE  ;if a ROM accepts this call then DBBE
+DBA1  TYA         ;else put Y in A
+DBA2  BNE  &DBB8  ;if Y<>0 DBB8
+DBA4  LDA  #&8D   ;else set up standard cassette baud rates
+DBA6  JSR  &F135  ;via &F135 which is OSBYTE 140.
+DBA9  LDX  #&D2   ;
+DBAB  LDY  #&EA   ;
+DBAD  DEC  &0267  ;decrement ignore start up message flag
+DBB0  JSR  OSCLI  ;and execute /!BOOT
+DBB3  INC  &0267  ;restore start up message flag
+DBB6  BNE  &DBBE  ;if not zero then DBBE
+DBB8  LDA  #&00   ;else A=0
+DBBA  TAX  ;X=0
+DBBB  JSR  &F137  ;set tape speed via OSBYTE 140.
+
+We now have an active filing system. The next job is to preserve the
+current language on soft RESET.
+
+DBBE  LDA  &028D  ;get last RESET Type
+DBC1  BNE  &DBC8  ;if not soft reset DBC8
+DBC3  LDX  &028C  ;else get current language ROM address
+DBC6  BPL  &DBE6  ;if +ve (language available) then skip search
+                  ;routine
+For a cold break we search for the language with the highest priority.
+
+DBC8  LDX  #&0F   ;set pointer to highest available ROM
+DBCA  LDA &02A1,X ;get ROM type from map
+DBCD  ROL         ;put hi-bit into carry, bit 6 into bit 7
+DBCE  BMI  &DBE6  ;if bit 7 set then ROM has a language entry so DBE6
+DBD0  DEX         ;else search for language until X=&ff
+
+Check for Tube if no language found.
+
+DBD1  BPL  &DBCA  ;check if tube present
+DBD3  LDA  #&00   ;if bit 7 of tube flag is set BMI succeeds
+DBD5  BIT  &027A  ;and TUBE is connected else
+DBD8  BMI  &DC08  ;make error
+
+No language error
+
+DBDA  BRK            ;
+DBDB  DB   &F9       ;error number
+DBDC  DB 'Language?' ;message
+DBE5  BRK            ;
+
+This might seem odd as BRK is handled by the current language BRK
+handler, but we don't have a language! We need to investigate further
+in another part.
+
+DBE6  CLC         ;
+
+OSBYTE 142 enter Language ROM at &8000 X=ROM number. Carry is set if
+this is an OSBYTE call and clear if this is an initialisation routine.
+
+DBE7  PHP         ;save flags
+DBE8  STX  &028C  ;put X in current ROM page
+DBEB  JSR  &DC16  ;select that ROM
+DBEE  LDA  #&80   ;A=128
+DBF0  LDY  #&08   ;Y=8
+DBF2  JSR  &DEAB  ;display text string held in ROM at &8008,Y
+DBF5  STY  &FD    ;save Y on exit (end of language string)
+DBF7  JSR  OSNEWL ;two line feeds
+DBFA  JSR  OSNEWL ;are output
+DBFD  PLP         ;then get back flags
+DBFE  LDA  #&01   ;A=1 required for language entry
+DC00  BIT  &027A  ;check if tube exists
+DC03  BMI  &DC08  ;and goto DC08 if it does
+DC05  JMP  &8000  ;else enter language at &8000
+
+TUBE FOUND enter tube software
+
+DC08  JMP  &0400  ;enter tube environment
+
+The Tube initialisation would have read the language across to the
+TUBE usually but it could be loaded by a !BOOT file from the filing
+system initialisation.
+
+The operating system now stops general control of the system and hands
+this to the language which looks after command lines etc. The OS
+however still handles the screen, keyboard and much else.
+
+Notice how every possible eventuality was taken into account during
+the initialisation routine. This is one of the things that made the
+Beeb a very powerful machine.
+
+Next week we'll have a look at the Interrupt code.
+
+BBC 6502 Machine Code
+Part Twelve: Pardon me!
+-----------------------
+We finished the last part at the point where the operating systems
+power up routine handed over control to the language. We'll write our
+own language later in the series but for now let's dive into another
+entry point.
+
+When the processor's IRQ pin (4) goes low (0V) the processor finishes
+off the current instruction and then goes off to run some microcode of
+its own. This checks that the RDY (2) pin is high and that the
+interrupt flag in the status register is 0 (not set). If it is set the
+interrupt is ignored and the processor goes to the next instruction.
+This continues when the IRQ pin is low.
+
+If the flag is clear then the processor stores the program counter and
+status register on the stack and sets the interrupt flag. The 6502
+then gets the address stored in &FFFE and &FFFF and executes this
+instruction next.
+
+If a BRK instruction is found in executing code then the processor
+performs exactly the same actions except that it does not check the
+status register for the interrupt flag, it does set a flag in the
+status register, the BRK flag.
+
+The main entry point for IRQ (and BRK) for OS 1.20 is &DC51.
+
+MAIN IRQ Entry point
+
+;ON ENTRY STACK contains STATUS REGISTER,PCH,PCL
+DC1C  STA  &FC    ;save A
+DC1E  PLA         ;get back status (flags)
+DC1F  PHA         ;and save again
+DC20  AND  #&10   ;check if BRK flag set
+DC22  BNE  &DC27  ;if so goto DC27
+DC24  JMP (&0204) ;else JUMP through IRQ1V
+
+That's pretty straightforward so far. As you can see IRQ1V allows you
+to put your own hardware at a higher priority than anything else in
+the machine.
+
+You can also write your own hardware interrupt handler if you wish.
+This is the flexibility that made the BBC machine so remarkably
+successful among knowledgeable users.
+
+Let's look at the BRK handler now.
+
+* BRK handling routine *
+DC27  TXA         ;save X on stack
+DC28  PHA         ;
+DC29  TSX         ;get status pointer
+DC2A  LDA &0103,X ;get Program Counter low byte
+DC2D  CLD         ;
+DC2E  SEC         ;set carry
+DC2F  SBC  #&01  ;subtract 2 (1+carry)
+DC31  STA  &FD    ;and store it in &FD
+DC33  LDA &0104,X ;get hi byte
+DC36  SBC  #&00   ;subtract 1 if necessary
+DC38  STA  &FE    ;and store in &FE
+DC3A  LDA  &F4    ;get currently active ROM
+DC3C  STA  &024A  ;and store it in &24A
+DC3F  STX  &F0    ;store stack pointer in &F0
+DC41  LDX  #&06   ;and issue ROM service call 6
+DC43  JSR  &F168  ;(User BRK) to ROMs
+                  ;now &FD/E points to byte after BRK
+                  ;ROMS may use BRK for their own purposes
+                  ;and many do!
+
+It's interesting to see what happens with the ROM handler. This is
+also an entry point for OSBYTE 143 so you can use this in your own
+code.
+
+* OSBYTE 143 *
+*Pass service commands to sideways ROMs *
+                  ;on entry X=command number
+F168  LDA &F4     ;get current ROM number
+F16A  PHA         ;store it
+F16B  TXA         ;command in A
+F16C  LDX  #&0F   ;set X=15
+                  ;send commands loop
+F16E  INC &02A1,X ;read bit 7 on ROM map (no ROM has
+                  ;type 254 &FE)
+F171  DEC &02A1,X ;
+F174  BPL &F183   ;if not set (+ve result)
+F176  STX  &F4    ;else store ROM number in &F4
+F178  STX  &FE30  ;switch in paged ROM
+F17B  JSR  &8003  ;and jump to service entry
+F17E  TAX         ;on exit put A in X
+F17F  BEQ  &F186  ;if 0 (command recognised by ROM)
+                  ;reset ROMs & exit
+F181  LDX  &F4    ;else point to next lower ROM
+F183  DEX         ;
+F184  BPL  &F16E  ;and go round loop again
+F186  PLA         ;get back original ROM number
+F187  STA  &F4    ;store it in RAM copy
+F189  STA  &FE30  ;select original page
+F18C  TXA         ;put X back in A
+F18D  RTS         ;and return
+
+Useful little routine that. So back to the BRK handler.
+
+DC46  LDX  &028C  ;get current language
+DC49  JSR  &DC16  ;and activate it
+DC4C  PLA         ;get back original value of X
+DC4D  TAX         ;
+DC4E  LDA  &FC    ;get back original value of A
+DC50  CLI         ;allow interrupts
+DC51  JMP (&0202) ;and JUMP via BRKV (normally into current language)
+
+Next week we'll carry on by taking a look at the BRK handler.
+
+BBC 6502 Machine Code
+Part Thirteen: Give us a BRK
+----------------------------
+BRK is usually handled by the default language (or by a Sideways ROM).
+However, it may be that you are running a machine code program before
+a current language is set up or perhaps your language doesn't handle
+BRK (it should but you never know).
+
+That's when a default BRK handler takes over.
+
+* DEFAULT BRK HANDLER *
+
+DC54 LDY #&00  ;Y=0 to point to byte after BRK
+DC56 JSR &DEB1 ;print message
+
+Let's have a look at the print routine. Remember that the error-
+handling layout is:
+
+BRK
+Error Number (1 byte)
+Message
+BRK
+
+Y plus the address in &FD &FE points to the error message on entry.
+
+DEB1 INY          ;point to first ;character in string
+DEB2 LDA (&FD),Y
+DEB4 JSR OSASCI   ;print it
+                  ;expanding
+                  ;Carriage
+                  ;returns
+DEB7 TAX          ;store A in X to change flags
+DEB8 BNE &DEB1    ;and loop again if not =0
+DEBA RTS          ;else exit
+
+A standard print routine, nothing out of the ordinary but nice and
+compact.
+
+You can use this in your own print routines by changing the zero page
+values. Back to the default BRK handler and an interesting bit of
+code.
+
+DC59 LDA &0267 ;if BIT 0 set and DISK EXEC error
+DC5C ROR       ;occurs
+DC5D BCS &DC5D ;hang up machine!
+
+Nasty! But the machine has to be in a pretty unusual configuration for
+this to happen. Mind you, setting 0267 then doing a JSR to DC59 would
+confuse the average user.
+
+DC5F JSR OSNEWL ;else print two newlines
+DC62 JSR OSNEWL ;
+DC65 JMP &DBB8  ;and set tape speed before entering the current
+                ;language
+DBB8 LDA #&00   ;else A=0
+DBBA TAX        ;X=0
+DBBB JSR &F137  ;set tape speed via OSBYTE 141.
+
+There's the end of the BRK handling code. As I said before this is
+generally handled by the default language but you can arrange for your
+own code or a Sideways ROM to handle it.
+
+Next week we'll return to the interrupt system with a look at the
+default entry point for IRQ1.
+
+BBC 6502 Machine Code
+Part Fourteen: The story so far...
+----------------------------------
+We left the interrupt-handling routine just after it had gone off to
+the IRQ1V vector. If you don't change the vector the code continues
+from DC93.
+
+One very important thing to remember about an interrupt-driven machine
+like the BBC is that the interrupt flag is not set for too long. If it
+is the machine could crash. This means that interrupt routines are
+short and snappy.
+
+* Main IRQ Handling routines, default IRQIV destination *
+
+DC93 CLD      ;clear decimal flag
+DC94 LDA &FC  ;get original value of A
+DC96 PHA      ;save it
+DC97 TXA      ;save X
+DC98 PHA      ;
+DC99 TYA      ;and Y
+DC9A PHA      ;on the stack
+              ;note the pre-CMOS code!
+DC9B LDA #&DE ;A=&DE
+DC9D PHA      ;store it
+DC9E LDA #&81 ;save &81
+DCA0 PHA      ;store it (a RTS will now jump to DE82)
+
+This is quite a useful technique as we will see later. If we now use
+JMP to go to an OS routine we can ensure that the routine, which ends
+with an RTS, causes execution to go to a specified point.
+
+This saves a lot of code as it can be arranged that the first device
+found that called the interrupt will be the only one handled. This, in
+turn, saves time!
+
+We now poll the hardware looking for who caused it. The first routine
+deals with the serial/tape system.
+
+DCA1 CLV       ;clear V flag
+DCA2 LDA &FE08 ;get value of status register of ACIA
+DCA5 BVS &DCA9 ;if this was source then DCA9 to process
+DCA7 BPL &DD06 ;else if no interrupt requested DD06
+DCA9 LDX &EA   ;read RS423 timeout counter
+DCAB DEX       ;decrement it
+DCAC BMI &DCDE ;and if <0 DCDE
+DCAE BVS &DCDD ;else if >&40 DCDD (RTS to DE82)
+DCB0 JMP &F588 ;else read ACIA via F588
+               ;RTS ends routine!!
+DCB3 LDY &FE09 ;read ACIA data
+DCB6 ROL       ;
+DCB7 ASL       ;
+DCB8 TAX       ;X=A
+DCB9 TYA       ;A=Y
+DCBA LDY #&07  ;Y=07
+DCBC JMP &E494 ;check and service EVENT 7 RS423 error
+DCBF LDX #&02  ;read RS423 output buffer
+DCC1 JSR &E460 ;
+DCC4 BCC &DCD6 ;if C=0 buffer is not empty goto DCD6
+DCC6 LDA &0285 ;else read printer destination
+DCC9 CMP #&02  ;is it serial printer??
+DCCB BNE &DC68 ;if not DC68
+DCCD INX       ;else X=3
+DCCE JSR &E460 ;read printer buffer
+DCD1 ROR &02D2 ;rotate to pass carry into bit 7
+DCD4 BMI &DC68 ;if set then DC68
+DCD6 STA &FE09 ;pass either printer or RS423 data to ACIA
+DCD9 LDA #&E7  ;set timeout counter to stored value
+DCDB STA &EA   ;
+DCDD RTS       ;and exit (to DE82)
+
+               ;A contains ACIA status
+DCDE AND &0278 ;AND with ACIA bit mask (normally FF)
+DCE1 LSR       ;rotate right to put bit 0 in carry
+DCE2 BCC &DCEB ;if carry clear receive register not full so DCEB
+DCE4 BVS &DCEB ;if V is set then DCEB
+DCE6 LDY &0250 ;else Y=ACIA control setting
+DCE9 BMI &DC7D ;if bit 7 set receive interrupt is enabled so DC7D
+
+DCEB LSR       ;put BIT 2 of ACIA status into
+DCEC ROR       ;carry if set then Data Carrier Detected applies
+DCED BCS &DCB3 ;jump to DCB3
+
+DCEF BMI &DCBF ;if original bit 1 is set TDR is empty so DCBF
+DCF1 BVS &DCDD ;if V is set then exit to DE82
+
+DCF3 LDX #&05  ;X=5
+DCF5 JSR &F168 ;issue ROM call 5 'unrecognised ;interrupt'
+
+We've seen this ROM service routine call before.
+
+DCF8 BEQ &DCDD   ;if a ROM recognises it then exit to DE82
+DCFA PLA         ;otherwise get back DE82 address from stack
+DCFB PLA         ;
+DCFC PLA         ;and get back X, Y and A
+DCFD TAY         ;
+DCFE PLA         ;
+DCFF TAX         ;
+DD00 PLA         ;
+DD01 STA &FC     ;&FC=A
+DD03 JMP (&0206) ;and offer to the user via IRQ2V
+
+That was a little convoluted, to say the least. Next week we look at how the
+VIAs are dealt with.
+
+BBC 6502 Machine Code
+Part Fifteen: Hardware VIA interrupts
+-------------------------------------
+After deciding that it wasn't the ACIA that caused the interrupt, the
+VIAs are the next port of inquisition.
+
+* VIA INTERRUPTS ROUTINES *
+
+DD06 LDA &FE4D ;read system VIA interrupt flag register
+DD09 BPL &DD47 ;if bit 7=0 the VIA has not caused interrupt goto DD47
+
+DD0B AND &0279 ;mask with VIA bit mask
+DD0E AND &FE4E ;and interrupt enable register
+DD11 ROR       ;rotate right twice to ;check for IRQ 1 (frame sync)
+
+DD12 ROR       ;
+DD13 BCC &DD69 ;if carry clear then no IRQ 1, else IRQ 1 means
+               ;interrupt request 1. This is different from the
+               ;vector IRQ1.
+
+DD15 DEC &0240 ;decrement vertical sync counter
+DD18 LDA &EA   ;A=RS423 Timeout counter
+DD1A BPL &DD1E ;if +ve then DD1E
+DD1C INC &EA   ;else increment it
+DD1E LDA &0251 ;load flash character counter
+DD21 BEQ &DD3D ;if 0 then flash system is not in use, ignore it
+DD23 DEC &0251 ;else decrement counter
+DD26 BNE &DD3D ;and if not 0 go on past reset routine
+
+This routine resets the flashing character system.
+
+DD28 LDX &0252 ;get mark period count in X
+DD2B LDA &0248 ;current VIDEO ULA control setting in A
+DD2E LSR       ;shift bit 0 into C to ;check if first colour
+DD2F BCC &DD34 ;is effective if so C=0. Jump to DD34
+DD31 LDX &0253 ;else get space period count in X
+DD34 ROL       ;restore bit
+DD35 EOR #&01  ;and invert it
+DD37 JSR &EA00 ;then change colour
+
+DD3A STX &0251 ;&0251=X resetting the counter
+
+DD3D LDY #&04  ;Y=4 and call E494 to check and implement vertical
+DD3F JSR &E494 ;sync event (4) if necessary
+DD42 LDA #&02  ;A=2
+DD44 JMP &DE6E ;clear interrupt 1 and exit
+
+Remember the RTS routine last time?
+
+* PRINTER INTERRUPT USER VIA 1 *
+
+DD47 LDA &FE6D ;Check USER VIA interrupt flags register
+DD4A BPL &DCF3 ;if +ve USER VIA did not call interrupt
+DD4C AND &0277 ;else check for USER IRQ 1 printer interrupt.
+DD4F AND &FE6E ;
+DD52 ROR       ;
+DD53 ROR       ;
+DD54 BCC &DCF3 ;if bit 1=0 then no ;interrupt 1 so DCF3
+DD56 LDY &0285 ;else get printer type
+DD59 DEY       ;decrement
+DD5A BNE &DCF3 ;if not parallel then :CF3
+DD5C LDA #&02  ;reset interrupt 1 flag
+DD5E STA &FE6D ;
+DD61 STA &FE6E ;disable interrupt 1
+DD64 LDX #&03  ;and output data to parallel printer
+DD66 JMP &E13A ;and exit via RTS
+
+* SYSTEM INTERRUPT 5 Speech *
+
+DD69 ROL       ;get bit 5 into bit 7
+DD6A ROL       ;
+DD6B ROL       ;
+DD6C ROL       ;
+DD6D BPL &DDCA ;if not set this is not ;a speech interrupt so DDCA
+DD6F LDA #&20  ;
+DD71 LDX #&00  ;
+DD73 STA &FE4D ;
+DD76 STX &FE49 ;and zero high byte of Timer t2
+DD79 LDX #&08  ;&FB=8
+DD7B STX &FB   ;
+DD7D JSR &E45B ;and examine buffer 8
+DD80 ROR &02D7 ;shift carry into bit 7
+DD83 BMI &DDC9 ;and if set buffer is empty so exit
+DD85 TAY       ;else Y=A
+DD86 BEQ &DD8D ;
+DD88 JSR &EE6D ;control speech chip
+DD8B BMI &DDC9 ;if negative exit
+DD8D JSR &E460 ;else get a byte from buffer
+DD90 STA &F5   ;store it to indicate speech or file ROM
+DD92 JSR &E460 ;get another byte
+DD95 STA &F7   ;store it
+DD97 JSR &E460 ;and another
+DD9A STA &F6   ;giving address to be accessed in paged ROM
+DD9C LDY &F5   ;Y=&F5
+DD9E BEQ &DDBB ;and if =0 then DDBB
+DDA0 BPL &DDB8 ;else if +ve DDB8
+DDA2 BIT &F5   ;if bit 6 of F5 =1 (&F5)>&40
+DDA4 BVS &DDAB ;then DDAB
+DDA6 JSR &EEBB ;else continue for more speech processing
+DDA9 BVC &DDB2 ;if bit 6 clear then DDB2
+DDAB ASL &F6   ;else double address in &F6/7
+DDAD ROL &F7   ;
+DDAF JSR &EE3B ;and call EE3B
+DDB2 LDY &0261 ;get speech enable/disable flag into Y
+DDB5 JMP &EE7F ;and JMP to EE7F
+
+DDB8 JSR &EE7F ;Call EE7F
+DDBB LDY &F6   ;get address pointer in Y
+DDBD JSR &EE7F ;
+DDC0 LDY &F7   ;get address pointer high in Y
+DDC2 JSR &EE7F ;
+DDC5 LSR &FB   ;
+DDC7 BNE &DD7D ;
+DDC9 RTS       ;and exit
+
+Next week we continue with a look at the remaining System Interrupts.
+
+BBC 6502 Machine Code
+Part Sixteen: Timers and Keyboard Interrupts
+--------------------------------------------
+The last part showed how the BBC Micro handles some of the system
+interrupt calls. Most of these are pretty routine so we won't continue
+with an interminable list.
+
+The next interesting routines concern how the timers and keyboard
+interrupts are handled.
+
+* SYSTEM INTERRUPT 6 10mS Clock *
+
+DDCA  BCC  &DE47  ;bit 6 is in carry so if clear there is no 6 so go
+                  ;on to DE47
+DDCC  LDA  #&40   ;Clear interrupt 6
+DDCE  STA  &FE4D  ;
+
+This is the start of the update timers routine, This is interesting
+because of the way that the timer information is stored. It's very
+clever. There are two timer stores, &292-6 and &297-B. These are
+updated by adding 1 to the current timer and storing the result in the
+other, the direction of transfer being changed each time of update.
+
+This ensures that at least one timer is valid at any call as the
+current timer only is read. Other methods would cause inaccuracies if
+a timer was read while being updated.
+
+DDD1  LDA  &0283   ;get current system clock store pointer (5,or 10)
+DDD4  TAX          ;put A in X
+DDD5  EOR  #&0F    ;and invert lo nybble (5becomes 10 and vv)
+DDD7  PHA          ;store A
+DDD8  TAY          ;put A in Y. Carry is always set at this point
+DDD9  LDA  &0291,X ;get timer value
+DDDC  ADC   #&00   ;update it
+DDDE  STA  &0291,Y ;store result in alternate
+DDE1  DEX          ;decrement X
+DDE2  BEQ  &DDE7   ;if 0 exit
+DDE4  DEY          ;else decrement Y
+DDE5  BNE  &DDD9   ;and go back and do next byte
+DDE7  PLA          ;get back A
+DDE8  STA  &0283   ;and store back in clock pointer (ie. inverse
+                   ;previous contents)
+DDEB  LDX  #&05    ;set loop pointer for countdown timer
+DDED  INC  &029B,X ;increment byte and
+DDF0  BNE  &DDFA   ;if not 0 then DDFA
+DDF2  DEX          ;else decrement pointer
+DDF3  BNE  &DDED   ;and if not 0 do it again
+DDF5  LDY  #&05    ;process EVENT 5 interrupt timer
+DDF7  JSR  &E494   ;
+DDFA  LDA  &02B1   ;get byte of inkey countdown timer
+DDFD  BNE  &DE07   ;if not 0 then DE07
+DDFF  LDA  &02B2   ;else get next byte
+DE02  BEQ  &DE0A   ;if 0 DE0A
+DE04  DEC  &02B2   ;decrement 2B2
+DE07  DEC  &02B1   ;and 2B1
+DE0A  BIT  &02CE   ;read bit 7 of envelope processing byte
+DE0D  BPL  &DE1A   ;if 0 then DE1A
+DE0F  INC  &02CE   ;else increment to 0
+DE12  CLI          ;allow interrupts
+DE13  JSR  &EB47   ;and do routine sound processes
+DE16  SEI          ;bar interrupts
+DE17  DEC  &02CE   ;DEC envelope processing byte back to 0
+DE1A  BIT  &02D7   ;read speech buffer busy flag
+DE1D  BMI  &DE2B   ;if set speech buffer is empty, skip routine
+DE1F  JSR  &EE6D   ;update speech system variables
+DE22  EOR  #&A0    ;
+DE24  CMP  #&60    ;
+DE26  BCC  &DE2B   ;if result >=&60 DE2B
+DE28  JSR  &DD79   ;else more speech work
+DE2B  BIT  &D9B7   ;set V and C
+DE2E  JSR  &DCA2   ;check if ACIA needs attention
+DE31  LDA  &EC     ;check if key has been pressed
+DE33  ORA  &ED     ;
+DE35  AND  &0242   ;(this is 0 if keyboard is to be ignored, else
+                   ;&FF)
+DE38  BEQ  &DE3E   ;if 0 ignore keyboard
+DE3A  SEC          ;else set carry
+DE3B  JSR  &F065   ;and call keyboard
+DE3E  JSR  &E19B   ;check for data in use defined printer channel
+DE41  BIT  &FEC0   ;if ADC bit 6 is set ADC is not busy
+DE44  BVS  &DE4A   ;so DE4A
+DE46  RTS          ;else return
+
+* SYSTEM INTERRUPT 4 ADC end of conversion *
+
+DE47  ROL          ;put original bit 4 from FE4D into bit 7 of A
+DE48  BPL  &DE72   ;if not set DE72
+DE4A  LDX  &024C   ;else get current ADC channel
+DE4D  BEQ  &DE6C   ;if 0 DE6C
+DE4F  LDA  &FEC2   ;read low data byte
+DE52  STA  &02B5,X ;store it in &2B6,7,8 or 9
+DE55  LDA  &FEC1   ;get high data byte
+DE58  STA  &02B9,X ;and store it in hi byte
+DE5B  STX  &02BE   ;store in Analogue system flag marking last channel
+DE5E  LDY  #&03    ;handle event 3 conversion complete
+DE60  JSR  &E494   ;
+DE63  DEX          ;decrement X
+DE64  BNE  &DE69   ;if X=0
+DE66  LDX  &024D   ;get highest ADC channel present
+DE69  JSR  &DE8F   ;and start new conversion
+DE6C  LDA  #&10    ;reset interrupt 4
+DE6E  STA  &FE4D   ;
+DE71  RTS          ;and return
+
+* SYSTEM INTERRUPT 0 Keyboard *
+
+DE72  ROL         ;get original bit 0 in bit 7 position
+DE73  ROL         ;
+DE74  ROL         ;
+DE75  ROL         ;
+DE76  BPL  &DE7F  ;if bit 7 clear not a keyboard interrupt
+DE78  JSR  &F065  ;else scan keyboard
+DE7B  LDA  #&01   ;A=1
+DE7D  BNE  &DE6E  ;and off to reset interrupt and exit
+DE7F  JMP  &DCF3  ;and again a subroutine to exit.
+
+Now we come to the point you've all been waiting for. This mystery
+RTSreturns all subroutines to &DE82.
+
+************** exit routine
+DE82  PLA         ;restore registers
+DE83  TAY         ;
+DE84  PLA         ;
+DE85  TAX         ;
+DE86  PLA         ;
+DE87  STA   &FC   ;store A
+
+* IRQ2V default entry *
+
+DE89  LDA   &FC   ;get back original value of A
+DE8B  RTI         ;and return to calling routine.
+
+NEXT WEEK: OSBYTE entry.
+
+BBC 6502 Machine Code
+Part Seventeen: The BBC Operating System
+----------------------------------------
+We've been examining the BBC operating system in some detail over the
+last few weeks. Unfortunately the demise of Micronet means that we
+cannot finish completely, as we hoped. So we've put together the next
+twenty weeks' articles in the form of a completely commented
+disassembly of OS 1.20.
+
+This is an excellent example of BBC programming and is full of tips.
+
+Just to remind you of the main points of the software. Entry points
+are pointed to by a jump table in the last six bytes of the ROM.
+
+The font characters are located from &C000 to &C2FF.
+
+OK, so here it is all commented and ready for you to peruse.
+
+Ed says: I have uploaded the series of disassembly articles as ten
+         short TSW files. Look on Micronet on 700100239 (before it's
+         too late!)
+
+               *********** THE END **********
+
diff --git a/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/index.html b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/index.html
new file mode 100644
index 0000000..fe01700
--- /dev/null
+++ b/docs/os12/mdfs.net/Docs/Comp/BBC/OS1-20/index.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML><HEAD>
+<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<META name="MSSmartTagsPreventParsing" content="True">
+<META name="Author" content="Jonathan Graham Harston">
+<TITLE>BBC OS 1.20 - BBC FAQ</TITLE>
+</HEAD>
+
+<BODY>
+<TABLE width="100%">
+<TR bgcolor="#eeeeaa"><th colspan="2"><font size="+3">BBC OS 1.20 DISASSEMBLY</font></th>
+<TR bgcolor="#ffff66"><TD><SMALL><A href="../"
+target="_top">BBC</A>-&gt;<B>OS1-20</B>
+</SMALL><TD align="right">
+<SMALL><A href="http://google.co.uk/custom?domains=mdfs.net&amp;sitesearch=mdfs.net">Search</A>
+</SMALL></TABLE><P>
+
+These files were originally abritarily chopped up into approximately
+18K chunks just for ease of editing. I have rearranged them up into
+more logical function chunks. I am going through them and updating,
+correcting and clarifying the comments.
+
+<P><TT>
+<A href="C000" TYPE="text/plain">C000</A>&nbsp;&nbsp;
+Default character set.<BR>
+<A href="C300" TYPE="text/plain">C300</A>&nbsp;&nbsp;
+VDU startup entry and tables.<BR>
+<A href="C4C0" TYPE="text/plain">C4C0</A>&nbsp;&nbsp;
+VDU Part 1: Main Routine. Control character dispatch,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VDU 1,14,2,21,3,15,4,5,8, scroll text window, VDU 11,9,10,28.<BR>
+<A href="C735" TYPE="text/plain">C735</A>&nbsp;&nbsp;
+VDU Part 2: Read pixel, read pallette,
+VDU 12,30,31,13,16,17,18,20,19<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write pallette, VDU 22,23,cursor control, CRTC control, VDU 25,26.<BR>
+<A href="CA39" TYPE="text/plain">CA39</A>&nbsp;&nbsp;
+VDU Part 3: VDU 24,29,127,paged mode,initialisation,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;read character, clear screen, *FX20, block cursor.<BR>
+<A href="CDED" TYPE="text/plain">CDED</A>&nbsp;&nbsp;
+VDU Part 4: Scroll, clear, move graphics cursor, plot routines,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plot a point.<BR>
+<A href="D10D" TYPE="text/plain">D10D</A>&nbsp;&nbsp; VDU Part 5<BR>
+<A href="D4BF" TYPE="text/plain">D4BF</A>&nbsp;&nbsp; VDU Part 6<BR>
+<A href="D940" TYPE="text/plain">D940</A>&nbsp;&nbsp;
+System Startup. Default vectors, RESET code, find ROMs and BASIC,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;initialise ROMs, enter a language.<BR>
+<A href="DC1C" TYPE="text/plain">DC1C</A>&nbsp;&nbsp; Main IRQ Routines.<BR>
+<A href="DF0C" TYPE="text/plain">DF0C</A>&nbsp;&nbsp; OSCLI and OSWRCH dispatch.<BR>
+<A href="E20E" TYPE="text/plain">E20E</A>&nbsp;&nbsp;
+*SAVE, *LOAD, *SPOOL, *KEY, *FX.<BR>
+<A href="E435" TYPE="text/plain">E435</A>&nbsp;&nbsp;
+Buffer handling, Event handling.<BR>
+<A href="E6B0" TYPE="text/plain">E6B0</A>&nbsp;&nbsp;
+OSBYTE/OSWORD dispatch table, FX9/10, FX2, FX13/14, FX16, INKEY,<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADVAL, OSBYTE handler, OSWORD handler, OSWORD 5/6, FX0.<BR>
+<A href="E887" TYPE="text/plain">E887</A>&nbsp;&nbsp;
+Sound system, SOUND, Speech, BELL, ENVELOPE,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OSWORD 3,1,2,0,5 FX1,6,12,11,3,4,166+ FX19,160,18,118, GSTrans.<BR>
+<A href="EAD9" TYPE="text/plain">EAD9</A>&nbsp;&nbsp;
+BIV, *TV, Sound IRQs, Speech.<BR>
+<A href="EEDA" TYPE="text/plain">EEDA</A>&nbsp;&nbsp;
+Keyboard.<BR>
+<A href="F135" TYPE="text/plain">F135</A>&nbsp;&nbsp;
+ROM/Cassette filing system. ARGS, FSC, FILE, RUN, CAT. Pass service calls around ROMs<BR>
+<A href="F3CA" TYPE="text/plain">F3CA</A>&nbsp;&nbsp;
+ROM/Cassette filing system. Save data, FIND, BGET, BPUT, OPT, EOF.<BR>
+<A href="F68B" TYPE="text/plain">F68B</A>&nbsp;&nbsp;
+ROM/Cassette filing system. Read/write blocks, CRC checks.<BR>
+<A href="F9B4" TYPE="text/plain">F9B4</A>&nbsp;&nbsp;
+ROM/Cassette filing system. Load data, housekeeping.<BR>
+<A href="FC00" TYPE="text/plain">FC00</A>&nbsp;&nbsp;
+I/O locations, extended vector handler, MOS entry points.<BR>
+<A href="Microbase" TYPE="text/plain">Microbase</A>&nbsp;&nbsp;
+Introduction to the BBC Operating System.<BR>
+</TT>
+
+<BR>
+<table width="100%" bgcolor="#f0f0b0"><tr><th>This page last updated 11-Aug-2010</th></table>
+
+</BODY>
+</HTML>
diff --git a/docs/texas_instruments_sn76489an.pdf b/docs/texas_instruments_sn76489an.pdf
new file mode 100644
index 0000000..2356bef
Binary files /dev/null and b/docs/texas_instruments_sn76489an.pdf differ
-- 
cgit v1.2.3