E: Tube Host Code

Tube Host Code

No listings or specifications were available for any of the code examples shown here, therefore they were saved from a live 512 system and disassembled. This has two implications. Firstly, they should be accurate, and secondly there is unfortunately no way to determine the precise purpose of some areas of data storage or some parts of the code in detail for all circumstances.

In the original disassembly there were short sections of code in page 6, now omitted, which were not called from any of the tube roufines here or elsewhere. Direct calls to ROM addresses within the code tend to suggest that they were incidental to tube operation. If they have any relevant function it is possible that these portions of code are used only during initial machine power-up and are subsequently overwritten. More probable however, is that they are downloaded simply because they just happen to occupy the last few bytes of that page, the bulk of which is relevant and remains.

The code shown below, which in essence and function is common to all BBC micro second processor support, consists of two parts. The first resides in page zero and is called at &16 on execution of a BRK instraction and is used to inform the co-processor of host software errors. During tube initialisation, when a hard break has been issued, if the tube is found to be active the break vector at &202 is therefore re-directed to point to &16 in zero page.

The second portion of the code is located in pages 4,5 and 6, normally reserved for the host's current language, which of course is irrelevant when running a co-processor. Page 7, normally the input strearn buffer, is used as a 256 byte data buffer for various transfers and calls. This code calls the zero page code at both location &32 and &36. In turn it is itself called by the zero page code. The entry addresses for this depend on the function called for by the co-processor. This is indicated by a single hex digit, detected within the idle loop at &36.

This is where the 6502 'waits' in the host code for co-processor dialogue when there is no current activity. The code entry points for the various function calls are located in a table of twelve addresses at &500 in both examples.

The two sections of the code are downloaded from the filing system ROM, provided that it includes support for the tube. The original DFS 0.9 did not, but all Acorn disc filing systens since DNFS 1.2, including the 1770 DFS and all versions of ADFS have, as have the alternatives from Solidisk and more recent versions from Watford Electronics. No Watford code has been checked, but like the STL version which has, it is likely to be identical byte for byte with the Acorn code, and the entry points, functions and returned values must be.

Note that the ADFS in the Master's 'Mega-ROM' is different to that in the stand-alone ADFS ROMs used by model B or B+ machines. The Master version of this code is therefore shown in the second example of the host code. The major differences are a slight 'shuffling' of the order of several of the routines and the saving of a few bytes of memory by using a 2 byte 65C02 relative branch instruction (BRA) instead of a three byte absolute JMP.

These differences are not in the interests of efficiency, as in places this technique is clearly less efficient. It is rather a by-product of the fact that Acorn's ADFS code is produced by a macro assembler rather than being hand-coded, with the result that some of the generated code is highly stylised. As the entry points in the code must remain fixed (i.e. 6502.SYS does not configure itself to suit the host type or its MOS) any bytes saved are wasted, as shown at &47h. Also, for example at &65F, there are no less than 2 relative branches followed by an absolute jump where only an absolute IMP would normally be used.

For both examples of this code shown here the functions are substantially similar, therefore to aid comparison the same labels have been used where direct equivalents of operations exist. The latest incarnation of the Master's 'Mega-ROM', released in November 1989 (since these disassemblies were produced and too late for inclusion) is largely similar to the Master version shown and 'hackers' should have little trouble in dis-assembling and understanding the new code. For all versions of the code the entry points, the functions, temporary workspace and zero page code are the same.

For a 512, regardless of host type, additional functions are required over and above those of a 6502 co-processor. rfl the case of the 512 therefore, extra code is loaded from the DOS boot disc. Initially this is transferred across the tube to the 512 from the DOS file called 6502.SYS, contained in the boot disc. Before system initialisation this file is transferred back across the tube and located at &2800, after shadow RAM has been turned off by an OSBYTE 114. The 6502.SYS code is then initialised, which results in the redirection of three more of the host's vectors. The user-vector at &200 is re-directed to &2803, the interrupt request 1 vector at &204 is redirected to &2834 and the event vector at &220 is re-directed to &2831.

6502.SYS performs many functions not provided by the standard host code. These include very fast screen updates (by direct pokes, which is why the host's shadow is not active), direct programming of the 6845 CRTC chip for the various IBM screen formats, special actions for keyboard activity scanning and reading mouse or tracker ball movement via the user-port.

6502.SYS must also perform some direct floppy disc control as CP/M formats, PC formats, as well as the 512's 800K format are not supported by ADFS, although they are by the WD1770 or 1772 if it is programmed directly. It will be found by reference to the 6502.SYS disassembly that, unlike 6502 second processors, the host code is called by the 512 via 6502.SYS only when standard MOS or ADFS filing system calls are required, though for speed 6502.SYS also issues several MOS calls directly itself. The host code is therefore of secondary irnportance to the 512, for which the majority of functions are provided by its own specialised code.

; ******************
; 6502 TUBE-HOSTCODE
; ******************
; *******************************
; Tube register data declarations
; *******************************
r1-stat=&FEE0
r1-data=&FEEl
r2-stat=&FEE2
r2-data=&FEE3
r3-data=&FEE5
r4-stat=&FEE6
r4-data=&FEE7
; *************
; Host OS calls
; *************
; Filing system
; *************
osfind=&FFCE
osgbpb=&FFD1
osbput=&FFD4
osbget=&FFD7
osargs=&FFDA
osfile=&FFDD
; *******
; general
; *******
osrdch=&FFE0
oswrch=&FFEE
osword=&FFF1
osbyte=&FFF4
oscli=&FFF7
; *******************
; zero Page work area
; *******************
; The first two bytes are used for indirect loading 'from' 
; when relocating a language across the tube in 6502 co-processors. 
; In the 512 system the first 16 bytes are used as the parameter 
; block for various OSWORD or filing system operations
.romadd
00 EQUD 0000
04 EQUD 0000
08 EQUD 0000
0C EQUD 0000
10 EQUW 00
; Bytes &12 and &13 are used for the hi-lo-byte pair for 
; block transfers of memory across the tube
12 EQUW 00
14 EQUB 0				; Tube status - &8O = free / zero = busy
15 EQUB 0				; Current owner ID - 80 = nobody
; Status bits are as follows
; Bit 0 = &O1 is the Interlock for FDC and IRQ in use 
; Bit 1 = &02 is the Bad FSmap flag
; Bit 2 = &04 is the MON flaq
; Bit 3 = &05 is the *compact flag (i.e. 'Do not disturb') Not used by DOS 
; Bit 4 - &10 is set during an atomic series of operations for the MFM
; Bit 5 - &20 is set it there's a Winchester controller 
; Bit 6 - 40 is set when tube is in use
; Bit 7 - &80 is set if tube is present
; The following is the BRK handling code located at byte &16 in zero page.
				 \
.brk handler
016 LDA #&FF				 \Load A with 255
018 JSR write_R4_data			 \Write A to tube data register A
01B LDA r2-data				 \Load A from tube data register 2
01E LDA #0				 \Load A with zero
020 JSR write_R2_data			 \Write A to tube data register 2
023 TAY					 \Set Y to zero
024 LDA (&FD),Y				 \Load A with first error byte
026 JSR write_R2_data			 \Write to tube data register 2
029 INY					 \Increment Y
02A LDA (&FD),Y				 \Load second and subsequent error bytes
02C JSR write_R2_data			 \Write to tube data register 2
02F TAX					 \Transfer A to X
030 BNE &29				 \Was byte zero (termination)?- No repeat
.reset_stack
032 LDX &FF				 \Load X with 255
034 TXS					 \Transfer to stack pointer (reset stack)
035 CLI					 \Clear interrupt disable flag
; This is the tube-idle loop which keeps the 6502 amused 
; when there is no current I/O activity or tube transfer 
; in progress. It continually checks register 1 status 
; and if nothing is required checks register 2 - until 
; either requires attention this is repeated endlessly.
; Register 1 is reserved for the current output channel 
; (screen, printer, RS232) hence an immediate OSWRCH is 
; expected if R1 is pending - thus if an output delay is 
; caused by the host or peripherals the co-pro is also 
; forced to wait. It is the entry for all other activity 
; therefore, even if R2 is pending. R1 is serviced first.
; The R2 entry causes an indirect jump to various code 
; entry points in page 5 to give access to the required 
; facilities.
.tube_idle_poll
036 BIT ri-stat				 \test tube register 1 status
039 flPL &41 				 \Not ready - try reqister 2
03B LDA ri-data 			 \Read tube data register 1
03E Jsn anwrch 				 \write to current output stream
041 SIT r2-stat 			 \Test tube register 2 status
044 BPL '36 				 \not ready - try register 1 again
046 BIT ri-stat				 \Register 2 ready - recheck register 1
049 assI &33 				 \negimter 1 not, ready - do that first
045 rnx r2-data 			 \Read function cods tram data register a
OAE Sn' &51 ~store at j~var. modifyina it- address
050 JMP (~WnpVHX to modified address Cs500+x - dirty!)
iL-var
051 EOUE C 				 \variable 10-byte of j~ point in page 5
052 EQUn &05 				 \~ixed hi-byte of iL- point (page 5
This is the 4 byte address used for language re-location across the tube
.reloc_data 				 \used for 4 byte memory addressing.
063 FOUR 0 				 \LO-byte of low order of 4 byte address
054 ~ous 0 				 \Hi-byte of low order of 4 byte address
oss tat's 0 				 \These bytes contain 'rrFF for the host
056 EQUE C 				 \and &0000 upwards for the co-processor
Model BBC B+ source listing
Tube host code for model n. n+ machines using stand-alone Ants

This is the start of the code which occupies pages 0 through 6.
Page 7 is also used as a buffer for 256 byte transfers

400 JMP &404 				 \Entry to copy language across tube
403 JMp &0A7 				 \Entry to copy ESCAPE flag across tube
This is the only entry point from 6502Sys
tube_entry 				 \A-t29 for tube releace, 193 for claim
IC' CKP iSSO 				 \Entry for 6502sYs - Tube claim or release?
408 BCC &435 				 \&t's neither - must be data transfer
40A CKP faco ~Is it a tube claim?
40c ECS a428 				 \Yes - branch to claim_tube
40E ORA  ;&4O 				 \no it's a release - set bit 7 on
410 CMP &15 				 \Are ~e the tube owner?
412 ENE &434 				 \If not branch return - do nothing
414 PflP 				 \save processor status on stack
415 SE' ~set interrupt disable flag
416 LDA *5 				 \Lcad A with 5
416 JSR write_R4_data 			 \write A to tube R~
419 LDA i's 				 \Load A with tube owner
AiD asa write RI data 			\Write A to tube RA
420 FLP 				 \Restore processor status from stack
421 LDA t&60 				 \load A with 128
423 STA &15				 \store in tube owner (&15)
42S STA '14 				 \and in tilbe status (&14
427 RTS 				 \Return
-claim tube
428 ASt ~l4 				 \Shift left tube status
42A Bes $432 ~Tube wa3 tree - now it'S ours - store owner
42C ChP &15 				 \Tube busy. As it us in &15?
42E BEQ &4a4 				 \Yes it~s already ours - exit
430 CLc 				 \clear carry - claim failed
431 RTS									 \Return
.store owner
432 stA &15 				 \store A in zero paqe byte &15
'34 nTs 				 \Return
data transfer
435 PHP 				 \save processor statue on stack
43' SEx 				 \Disable Interrusts (time critical transfer)
437 STY &~S 				 \store y (lo-address byte in '13
439 5,,' &12 				 \Stort X (hi-address byte in &12
433 ask write_RI_data 			 \write A to tube data register 4
43! TAX ~and also store in 'C
43? LDY #3 				 \Load r for 4 byte transfer
441 tUn &15 				 \Load A froit zero page tube~owner
443 JSn write_~4_data 			 \write A to tube data register A
446 WA ('12 ,Y 				 \Load A fr~ indexed zero page address
44S Jsn write_RA_data 			 \write byte to tube data register A
44fl flEy 				 \Decrement count
44c BPL &446 				 \co~1ete? No - loop back and repeat
44E ~Y jale 				 \Load Y 24
450 S~Y ri_stat 				 \write to tube registeri status
453 WA ~51S.X 				 \Load from temporary_data
45' STA ri_stat 				 \write register 1 status
459 LS't A 				 \Divide value by 2
Ask tSR A 				 \and again (- Divide value by 4
45a ncc &463 				 \nranch if old bit 1 was C
4SD PIT r3_data 				 \waste a bit of time? These two
460 BIT r3_data 				 \instructinns Set p but do not affect A
463 JSR write R4 data 				 \which is written to tube data register 4
4C6 SIT r4_Stat 				 \Tnnt register 4 status
469 nvc &466 				 \Not ready - loo~ until it in
463 BeS &47A 				 \status ears terminate Operation
46D cpx ;4 				 \was original A - 4
46? linE &4e2 				 \no - branch to return
.soft_break
471 JsR &414 				 \Inform co-pro of tube release
474 Js~ write_Ra_data 			 \write A to tube data register S
477 JMP &32 				 \J~ to reset_stack
.terminate_operation
47A LSR A 				 \Clear top bit
475 BCC ~462 				 \Branch if bottom bit was also clear
47D WY f&aa 				 \confirm action terainated
4~T Sty ri_stat 			 \write y to tube register 1 status
462 pIr 				 \Rsstote processor status reg from stack
4SS KTS
copy_langtiage
464 cLr 				 \Enable interrupts
465 MOS '49$ 				 \rf catry branch to claim tubs
467 mm &48c 				 \rf not zero we~ve not finished branch
489 JMp &59C 				 \J~ to termination at send_c~1etion byte
48c Lnx 40 				 \Load X tero
4SE WY *&FF ~Load Y 255
490 WA flFD 				 \Load A 253
492 JSR osbyte 				 \Read~write last break
495 TXA 				 \Last break byte in X, transfer to A
~96 BEQ &471				 \soft break - branch to soft_break
49e LDA #~rr 				 \Load A 255 (all bits on)
49A JSR &406 				 \Exsc tube claim code (hard break - startup)
49D BCC &496 				 \If not successful repeat until it is
49F JSR ~4D~ 				 \check current ~on, set up reloc.rt lan4"age
432 LDA *7 				 \Load A with 7 for call to tube_entry
4A4 JSR &4C3 				 \Jup to tube entry (with return)
437 LDY *0 				 \set Y counter to zero
4A9 STY 0 				 \Store in romadd (10-byte of transfer addr
4An LDA (O~,Y 				 \toad byte to be transferred
4AD STA r3_data 				 \write A to tube data register 3
4B0 NOP 				 \These Mops are included s~ly to cause a
AB1 NOP 				 \de1a~, as the as transfet is 'slow
4B2 NOP 				 \cThia extra NO? needed for 6502 and ZOO)
4Ba INY 				 \rncrwnent Y - Finished current page?
4BA BNE &4AD 				 \No repeat until 256 bytes tranaterred
4B~ INC 654				 \Increment hi-byte, lot, order of co-~ro addr
439 ENS &4C0 				 \64K transferred? No-branch update-host-page
4SA INC &55 				 \Next 64K in co-pro. Inc. 10-byte high order
4fle stat &4c0 				 \16Mb co~1ete? no.branch npdate-host-~age
4BE INC &56 				 \:nc co-pro hi-byte hiah ordercnext 1~nb!

update_hostjage
'Co INC 1				 \Incr-ent RON address hi-byte
~C2 BIT 1 				 \Teat > ~ bit. In 'Ci (2~14 - "'C eadresaed)
.C. BVc ~4~ 			 \rt tEK co-let. branch for tub, data xfer
4C~ asa &4D2 				 \Check current no" and set up reloc.!! lsng
Ac' WA #4 				 \Load A .ith 4 for tube transfer type
403 WY 					 \Load Y (la-byte for tube data transfer
4cn rnx ~&53 				 \Load X (hi-byte rot tube data transfer
4cr JXP ~4O6 				 \J~ to tube_entry

check_roTa_type
4D2 LDA ~&SO 			 \ncad A 120
404 STA &54				 \set co-pro relocation addre5s to &0000e000
'De STA 1 				 \And set hosttXfer ircit' address to 'SOOC
ADS IDA t&20 				 \set bit ~ Ott all othnr5 off
ADA AND &SOO' 				 \Aflt current RON tyna byte - is it a lang
cnn TA? 				 \Put result in Y in case At's not
INTh s~Y &s3 				 \put result in 'sa in case it~s not
AED BEQ &4Th				 \means RON in NOT lang - branch no_reloc
4:2 lAX 58007 				 \Load X with ~I copyright pointer offset

read C
4E5 Iba 				 \Inc X to point to firat C of (C string
4s6 WA &8000.x 				 \Load A with copyright bytes until byte - 0
4E9 BNs~&4E5 				 \Until 0 it~s the c'right notice
AEn LDA &6001,X 				 \Load 1st byte of ca-flrocessot reloc address
4EE STA &53 				 \Store in zero page byte &5a
470 WA ~SOO2.x 				 \boad 2nd byte of relocation address
4r3 STA &54 				 \Stote in zero page byte &S4
4r5 'fly &6003,X 				 \Load Y with 3rd byte of relocation address
~rs LDA aa004,x				 \Load A with 4th byte of relocation address
reloc
4FB STA &5e				 \store accumlator in zero page byte 6~6
4FD STY &55 				 \store Y in zero page byte &55
4FF k~S				 \Return
; These are indirect jumps taken from the tube idle loop
; cede at &036 to &050 The a~ras5 In &O51 Is pnknd to
; index one of the following indirect jump addresses.
500 EOUW &3705 				 \was 0 - jump osrdch_call
502 sOUW &9605				 \ was 2 - ju'np oncli_call
504 ECUW ar205				 \ ~n2 was 4 - 5u~ shor~ _nabyte
soe EQUW &0706 				 \n2 was 6 - j~ long-osbyte
508 ~auw &2706 				 \n2 was S - jump OSWORD_call
50A EQUW &6806 				 \R2 was A jump cawordo-call
SOC EQUW &5305				 \ ~a3 C - ju~ osarga_call
SOE EQUW &2n05 				 \ft2 was E - ~ o,bget_call
510 sOUW &2005				 \ was 10 - zump osbput_call
512 KOOW &4205				 \ ~n2 was 12 - itimp osfind_call 1
514 EQuw &A~O5				 \ was 14 - ju~ osfilo call
516 tom' ~DlO5				 \ was 16 - j~ osgbpb_call

.te~rary-data
518 SOUw 00
51k RQWI OO
510 EQuw OG
51E RQUS OO
.onbput_call
520 JSn rend_'12 data 			 \Load A with fil. handle from register 2
523 TAY 				 \File handle must be in Y
524 Jsn read_fl_data 			 \Load A with tube data register 2
527 Jsn asbpnt				\Put a single byte to file
52A JMP 				 \Jmp to send completion byte
.osbget_call
520 JSR read_~_data 			 \Load A with file handle from r~i5ter 2
$30 TAY 				 \rile handle mu5t be in V
531 JSa osbget 				 \c;et one byte from file
5a4 SM? asak 				 \aun~ to transfer_one_byte
.osrdch call
53~ JSR
.transfer_one_byte
SSA flea A 				 \shift tight one bit
San JsR write ~ data 			 \write A to tube data reginter 2
sat 'tot a 				 \Shift left one bit
3)4? &5~t 				 \J-p to send unshifted byte
.osfind_call_1
542 Jsn read_RZ_data 			 \Load A with tube data re~ister 2
545 BEQ osfind_call_2 			 \zero byte means close a file
SA' PRA ~stnre A on ntack temporarily
541 JSa block transfer 			 \Transfer file-naras from co~ro
54fl Pu 				 \nestore A (Contents - access mode)
sac jsn osfind 				 \open the named file
54F JXP &s9E 				\Jmp to return file handle
.osfind_call_2
55~ JSR read_fl_data 			 \toad A with tube data register 2
555 TAY 				 \File handle must be in Y
556 LDA *0 				 \Lcad A with zero
5se Jsn ostind 				 \Clone file
SSn OMP &59c 				 \Jnrnp to send conpietion byte
.osarga_call
55E Osri read_R2_data ~Load A tram tube data register 2
sel TAY 				 \put file handle in Y
562 LDx ~4 			 \Set up loop count
564 3sn read_fl_data 				 \LOad A fro~ tube data register 2
567 S~A &r~,x 				 \store at bottom of zero page
569 flEX 				 \Decremnt count
SeA ENS &564 				 \coa~1ete? No - loop back and re~at
56c Jsa read_RI data 				 \Load A with osarg~ call type
SEF JsR onarga 				 \nead(write tile attrihutea
572 3srt write_R2_data 				 \write A to tube data register 2
575 rnx *3 				 \Set up loop count for 4 bytes
577 WA O,X 				 \Load A with returned attributes
579 Jsn write_'2_data 				 \write a to tube data re4ister 2
57C DEX ~D.crmnnt count
57fl BPL 6577 				 \c~1et,? No - loop back and repeat
$77 JwP '36 				 \Jnnp to tube idle polling loop
-block transfer
582 tux to ~2oro
sac INY IC 				 \and
Ses JSR read_fl_data 				 \Load A from tube data register 2
509 STA data,Y 				 \store in 256 byte buffer at &700
Sec '~ 				 \Incr~nt Y
SaD BEQ end_block 				 \Finished 2S~ bytes? - Yes
5SF am ~Nn 				 \ wa3 byte CR (end of transfer
5~1 SNE isee 				 \NO - Loop back for next byte
end-block
$93 ~Y ~? 				 \Finisbed! - Load Y with 7
595 't~s 				 \Rsturn
-ouch call
5~c Jsa block_ttansfer 				 \Get cli string
S9~ JSR ascii 				 \Call "0S co-and line interpreter
send_copletion_byte
5~C ~A *'7r 				 \Load A with 127 (co~1etion byte)
SSE flI' r2_stat 				 \Test tube register 2 status
Sal Evo ~59E 				 \not ready - repeat
5A3 STA rZ_data 				 \write A to tube data register 2
5A6 JNp '35 				 \3~ to tube idle polling loop
osfile call
5A9 IDX talc				 \Set up for is byte transfer in x
SAn asa read_fl_data 				 \toad A frOm tube data register 2
SAL STA &i,x				 \5tore at romadd+1,x
sao flEx 				 \Decreraent count
531 SNE &SAB				 \1eto7 - Na loop back and repeat
5B3 JSR block_transfer ~transfer bytes
Sne STX 0 				 \Raset filename hi-byte to zero
SBR STY 1 				 \Set filena~ pointer la-byte to Y
SnA rnY *0 				 \set x-Y to point to 16 byte parameter block
5Bc SSR read_R2_data				 \Lcad A trOta tube data register 2
SEF JSR osfile 				 \Ca1Y osfile - A defines required action
5c2 JSR write_RZ_data 				 \write result code to tube data register 2
5C5 LDX #610				 \set up for 16 byte transfer out
5C7 Ink 1,X 				 \Load from romadd+1.x
509 JSR write_R2_data 				 \write A to tube data register 2
SOC DEX 				 \Decro~nt count
5cn slit 'Sd 				 \c~lete? - '10 loop bac~ and repeat
SCF BEQ &SAE 				 \2 stage j~ back to tub._idle_loop
.osqb~_call
sni inx ~&n 				 \toad X counter with length of param- block
5n3 JSR read_fl_data 				 \Load A from tubs data register a
506 S~A &rr,x 				 \store at bottom of Page zero (1 to aD)
SflS DEX 				 \necremant count
Sflg BIlE &5D3 				 \cc~let.~ - No loon back and repeat
5DB JSK read_RI_data 				 \Load A frog~ tube data tegistet 2
SDE WY 40 ~sot Y to la-byte of parems
5t0 Jsn osgbpb 				 \call osgetbytelputbyte
5E3 PRA				 \preserw A on stack
5E4 W~ 				 \set loop count
5~6 ~A O,X 				 \boad returned file info~tion
SEa Jsa write_fl_data				 \write A to tube data register 2
5ES flEx 				 \Decrereflt count
5EC flPt &5E6 				 \Complctc? No - Loop back and re~at
SEE PLA 				 \flestore A from stack
5SF JMP $53A 				 \Ju=p to transfer_one_byte
.short_osbyte
5F2 JSR read_n2_data 				 \Load A tram tube data re~ister 2 SF5 TAX 				 \set X paramter
SF6 Jan read FIS data 				 \Load cabyte n~ber from tabe data reg SIrS JSR osbyte 				 \Call osbyte
SF0 BIT r2_stat 				 \'remt register 2 status
srr nvc aSFO 				 \Not ready - loop back until it is
601 STX rZ_data 				 \write returned X value to tube data reg 2
604 JKp &36				 \3wnp to tube idle polling 100p
.long_osbyte
607 JSR read RI data 				 \Load A frog~ tube data register 2
EGA TA)[ 				 \set osbyte 'C paramtar
Con Jsn read_R2_data 				 \Load A from tube data register 2
COE TAY 				 \set osbyte Y parameter
SOF Jsn read_R2_data 				 \load A from tube data register 2
612 JSR osbyte				 \call osbyte
615 EoR *&9D				 \was it osbyte 157 (fast tube flPUT~?
617 BEG &604				 \Yea - Branch to idle poll j~
619 KOR A 				 \Not 157 - shift right one bit
GiA JSft write_R2_data 				 \writo A to tube data register 2
Gin BIT r2 stat 				 \Test tube register 2 status
620 ave &61n 				 \NOt ready - loop back until it is
622 STY rZ_data 				 \write Y to tube data register 2
625 nvs aSFC ~nranch to write X value to register 2
.osword call
627 Jsn read R2_data 				 \Load A from tube data register 2
62A TAY 				 \Save read/write action in Y
enn nIT r2 _stat				 \Test tube register 2 s~atus
62E BPL &S2a 				 \Not ready - 1cc~ until it is
630 rnx r2_data				 \Load X with param. block offset
633 DEX 				 \Decrement X - If it~s zero no parameter.
634 ml' &645				 \ now ~t?? - Yes branch to csword_setup
636 BIT r2_stat 				 \lest tube register 2 status
639 nPL &~~6 				 \not ready - loop back until it is
63B Kak r2_data				 \ ~flead tube data register 2
63E STA &126,x 				 \Store in paramter block at offset
641 DEX 				 \necrement count
642 flPL &636 				 \c~lete? no - loop back and repeat
644 TYA 				 \nsstore read/write action from
.osword_setup
645 ~X ~&28 				 \Load X with patam. block address lot, byte
647 Wy ~1 				 \toad Y with param. block address high byte
644 asa onword 				 \Ezecute osgord using parm. block at &126
64c nIT z2_stat 				 \Test tube register 2 status
64r BPL &64c 				 \not ready - loop back until it is
551 LOx r2_data				 \Load A from tube data register 2
65~ flEx 				 \Decrement x
655 SM' &6e5 				 \cor~lete? Yea -
657 In? &12s,x 				 \Else read paranstet into
~SA nIT r2_stat 				 \.!est tube re~ister 2 statun
650 avc SeSA 				 \not ready - loo~ back until it is
65r STY r2 data 				 \write y to tube data register 2
'62 flEx 				 \DecremeQt count
663 BPL &657 				 \con~lete? no - loop back and tepeat
s'5 S"? &36 				 \Jtimp to tube idle polling loop
.oswordo_call
6's Lox #4				 \set loon count to 4 in x
SCA Jsn read_;12_data				 \Load A fro~ tube data register fl
6~fl STA O,X 				 \store at rmadd+x
66? flEx 				 \necrement count until 'C - 'Fr
670 apt SGGA				 \5 bytes Xferred? - No loop back and repeat
6~2 "ix 				 \Incr~nt X (back to zero)
673 WY *0 				 \Set Y to zero
675 TXA 				 \Set A to zero
676 JSR ozwcrd 				 \oet characters fro~ current in~ut stream
679 BCC a6eo 				 \RSturfl preaned? - Yes - branch to wtite
G79 WA ~&FF 				 \Escape pressed! - load A with 255 and
67D JMp &59E 				 \J~ to write tegister 2
.read_string
~ao wx ~o 				 \zeto loop counter
6S2 LOX *&7F 				 \Load A with start string byte
6S4 Jsn write_&12_data				 \write A to tnbe data registar 2
6S7 WA data.x 				 \toad from 256 byte block at &700
ERA asri write_R2_data 				 \write A to tube data register 2
Sen "ix 				 \Incr~nt count
'SE OMP l&D 				 \End of in~ut warked by cMa$13?
6~O fiNE ~6S7 				 \No - loop back for next byte
692 aMP &36 				 \rndirect it- to tube idle flolling loop
.write fl data
695 BIT r2_stat 				 \Test RZ status
696 BVc write_~_data 				 \wot ready - loop until it is
69A STA r2_data 				 \write A to tube data register 2
'SD RTS 				 \RSturfl
write R4 data
6~E nIT r4_5tat 				 \Temt n4 status
Gal BYC write_R4_data 				 \Not ready - loop until it is
'A3 STA r4_data 				 \Write A to tube data register 4
6A6 RTS 				 \Keturn
-copy_escape_tlao
6A7 WA &rr				 \Laad Accunnjlatcr with 255
6A9 SEC 				 \Set earrr flag
6AA "Ca A 				 \notate right Accnmnlator bits
EAB ml! write_Ri_data 				 \Branch on -ve flag (bit 7. prev carry
SAD PHA 				 \?teserve A on stack
SAE InA 40 				 \toad A with zero
630 Jsn write_RI_data 				 \write A to tube data register 1
6B3 7YA 				 \transfer content3 of Y to A
SEA JSn write_RA_data 				 \nrite A to tube data register 1
Sn7 Tm 				 \Transfer content5 of X to A
GnS asa write_Ri_data 				 \write A to tube data register 1
EBB PIA 				 \Restore A ftoa stack
-write Ri data
6nc BIT ri_5tat 				 \rest al status
ear nvc write_RY_data 				 \ae~at - Ri not ready (bit 6 clear) Gd STA ri_data 				 \write Ri data from A
'CC ~fS ~Return
-read R2 data
5c5 BIT r2_stat 				 \Test Ttfl status
'CS B~t read_'t2_data 				 \Repeat - ~ not ready (bit 7 clear
ECA WA r2_data ~nsad regiater 2 data into A
600 aTS 				 \neturn
700 .dat. 				 \flata buffer far (up to) 256 bytes
; Master 128 source listing
; Tube host code for Master 128 machine, using Mega-ROM ADFS
; This is the start of the code which occupies pages 4 through ~
; Page 7 is also used. as a butter for 256 byte transfers.
400 JMP &4C2 				 \Entry to cony language across tube
403 JIw ~675 				 \Entry to copy ESCAPZ flag across tube
.tube_entry 				 \On entry A~129 for tube rel, 193 for claim
406 cXP ~aeo 				 \Entry for 6502sYs-Is it tube claim or tel?
409 Thea ~433 				 \rt's neither - rust be data transfer
40A CMp ~&co 				 \!3 it a tub, claim?
40c ncs ~426 				 \Yes - branch to c1a~_tube
lot OAR ~s40 				 \NO it~s a release - set bit 7 on
'10 CKp als 				 \Are we the tub, owner?
~12 ENE ~4~2 				 \If not branch return - do nothin0
414 eMP 				 \save processor statun on atack
415 SEI 				 \set interrupt disable flag
416 ~A $5 				 \boad A with 5
41S JsR write_RA_data 				 \write A to tube a'
41n Jsa write n4_tube_owner 				 \Load A with tube otmer and writ. to Re
41K pLp ~Reator.				 \rooessot status tram stack
417 IflA ,&E0 ~load A with 128
421 STA &15 				 \Store An t~ owner (&15
423 STA &14				 \and in tube stattis (&14
~25 Ft's 				 \'etnrn
.claim_tube
426 ASL &14 				 \shift left tube status
428 Ecs &430				 \ uaa free - now it'a ours - store own~r
42A CPe '15 				 \Tube bnsy, is it us in &15?
42e etc &432 				 \yes it~s alreadr ours - exit
42& crc 				 \Clear carry - claim failed
42r R7S 				 \Return
.store owner
430 STA &15 				 \store A An z~ro page byte ~15
4~2 RTS 				 \Rsturn
.data_transfer
Ass pnp				 \save processor statue on stack
434 SEI 				 \Disable interrupt , (tine critical transfer)
4~5 STY '13 				 \store Y (10-address byte in &lj
41~ STX &12				 \starn X (hi-address byte) in &12
439 JSR write_R4_data 			 \write A to tube data register 4
43c TAX 				 \and also store in x
43D LDY .3 				 \Load Y for A byte transf.r
4SF Jsn write_R4_tube_ovaer				 \Load tube owner and write to Ra
442 InA c&12}.y 				 \Load A frm indexed zero page address
444 Jsn writ._rt4_data				 \write byte to tube data register A
447 flEX 				 \Decreent
448 aph ~4~2 				 \comp1~t,? No - loop bacir and repeat
44A WY isle 				 \Load Y 2~
440 STY ri_stat 				 \wtite to tube tegisteri status
''F WA '5i6,X 				 \Load frort te-rary_data
45~ STA ri_stat ~write regist,r 1 status
455 LSR A 				 \Divide value by 2
456 LSR A 				 \and again C- Divide value by 4)
457 ncc aAsr				 \ntanch if old bit 1 Was 0
ASS BIT r3_data 				 \waste a bit of tint? These two
45C sI'r ra_data 				 \insttuctions set F but do not attect A
4Sr JSR write_R4_data 				 \Wh*ch in written to tube data register 4
462 srT r4 stat 				 \¶est regi5ter 4 statun
465 Bvc ~4~2 				 \Not ready - loop until it is
467 acs &476 				 \statn5 says terminat, op.ration
469 cpx #4 				 \wa5 original A - I
'GB BRE a47E - branch to return
160 Jsn '414 				 \Inform co~ro of tube release
470 JSn '561 				 \wrAt. A to tube data register 2
473 JMp ~32 				 \J~ to reset_stack
.terminate_operation
47' 1&rt A 				 \Clear top bit
4~7 scc &47E 				 \Branch if bottom btt was also clear
47~ tar ~'ae				 \confirm action terminated
'75 sTY ri_stat 				 \write Y to tub, rgi,t.r 1 status
47t Pt, 				 \Rostore processor Status reg fr~ stack
47F RTS 				 \Returfl
460 Wx &29n -				 \s copy of last BREAK type byte
4e3 BEQ &46D 				 \O-soft - branch inform 512, reset stack
4S5 ~A ~&FF				 \Load A 255 (all bits on)
4$, Jsn &406 				 \Ex tube claim code (hard break - startup)
48A floe &4e5 				 \If not successful repeat until it is
4Sc JSR &4C9 				 \Ch.ck current RON, set u~ reloc.if lang
4er pHp 				 \Save processor status
490 S~X				 \Disab1e interrusts
491 IrA ~7 				 \~ad A with 1 for call to tube_entry
4,3 JSR SAaB 				 \J~ to tube entry (with return)
496 tnT 40 				 \Store in rgmadd (la-byte of xfer address)
49$ STZ a 				 \store in romadd (10-byte of kfer address)
49A rflA (O),Y 				 \Load byte to be transferred
49c STA r3_data				 \wtite A to tube data register 3
49r flop 				 \These flOps are included sin~ply to eanse a
4A0 NOP 				 \delay. as the Ra transfer is slow'
4Al NOP					 \(Extra NO? needed for the 6502 and zec)
4A2 INY 					 \Increment y - Finished current page?
4As BNE ~49A 				 \No - repeat until 256 bytes transferred
4A5 PLY 				 \aestore processor flags
4A6 Inc &s4 				 \~nc hi-byte. low order of co-pro address
AAS ENE &4B0 				 \64~ xferred? Nn - branch update-host-page
4AA INC ass 				 \Next 64K in co-pro- Inc- ic-byte high order
4AC BNs SABO				 \1&Wb c~lete? No-br. update-host-page
				 \increment fiflM address hi-byte

4AE INC &5E 				 \Inc co-pro hi-byte high ordcr(next 16Mb-)
.update~hcst~age
4n0 INC ~l 				 \:ncre~nt ROM address hi-byte
4n2 BIT al 				 \test > 6 bits in &O1 C2~14 - 16K adnressed
454 Bvc '4sf				 \If 16K c~1ete branch for tube data xter
dnA 3sn &4C9 				 \check cnrrent RON and set up reloc-if lang
4S9 LDA ~4 				 \Load A with 4 for tube transfer type
49S ~Y *0 ~Lcad Y (10-byte) for tube data transfer
4nn rnx ~&53 				 \Load X (hi-byte) for tube data transter
43? OMP &4C6 				 \Jti'ap to tube_entry
copy_language
4c2 CLI 				 \Enable interrupts
4c3 ncs a4as 				 \If carry branch to claim tube
4c5 flNr &480 				 \If not zero we've not finished - branch
AC? BRA &52A 				 \a tc termination at send_completion_byte
.check_ram_type
(Cs tAX saso				 \Load A ~2B
4CR STA &54				 \set co~pro relocation address to &0000s000
4Cn STA I 				 \And net host ~Xter frOTh address to
ICF ILA ~a20				 \sat bit 6 on, all others off
4n1 AND &BOOC 				 \Abtj cnrrent ROM type byte - is it a lang?
4D4 TAY '				 \Pnt result in y in casa it's not
Ans STY &53 				 \put result in &53 in case it's not
4D7 BEQ &4t2 - RON is NOT a language - branch no_reloc
4D9 LDx &e007 				 \Load X with $tO~ copyright flointer offaet
read C
Cflc INX				 \Inc X to first of '(C), atring
4DD LDA &a000,x 				 \Load A with copyright bytes until byte - 0
4s0 nnr &4nc 				 \untii it1s the Cc notice - branch read_C
4E2 LDA &E00!,x 				 \Lnad 1st byte of co-pro reloc address
4E5 STA &53 				 \store in zero page byte &5~
4E7 LDA ~8OO2,x 				 \Load 2nd byte of relocation address
4EA SIA &54 				 \store in zero page byte &54
4EC LDY &8003.x				 \LOad Y with 3rd byte of relocation address
4EF LDA &E004,x 				 \Load A with 4th byto of relocation address

no reloc
4F2 STA &56 				 \store accuinulator Yn zero page byte &56
4r4 STY &55 				 \Store Y in zero flage byte &55
4F6 RTS 				 \Return
4F7 				 \These addresses are undefined- They are 				 \unused because the code was re-written
AFA				 \for the master so as to use less 'reraory.
4F0 				 \but the addresses at &500 cannot be moved
ArE				 \therefote these bytes are redundant.
These are indirect j~s taken from the ttte idle loop code at 036 to &0S0- 
The address in '051 is poked to index' one of the following indirect jump addresses.
500 EQUW &3505 				 \n2 was a - i~ osrdch_call
502 EOns &6605 was 2 - ii- ouch call
504 FOUW sokos wan 4 - it- short_osbyte
SOS EQUW &EBOS 				 \R2 was 6 - j~ lon~-osbyts
508 EQUw ~O7O6 was S - it- OSWORD_call
50A ECUW &3606 was A - j~ OSWORDO-call
50C EQUW &5905 was C - ii- osarga_call
SOE EOtM &2005 was S - j~ osbget_call
510 EQUW &2005 was 10 - ii- csbput_call
512 EQWI &3r05 was 12 - jur~ osfind_call_1
514 EQUW &8205 was 14 - jump osfile_call
5h EQUW &9A05 was 16 - jump osgbpb_call
.t~otary_data
SIB EQLM OO
51A EQUW OO
Sic tQWI OO
SlE EQUW 00
.osbpnt_call
520 JSR read_n_data 				 \toad A with file handle tram rnginter 2
$23 TAY 				 \File handle ~ust be in r
524 asa read ~ data 				 \Load A with tube data tegister 2
527 asa osbput 				 \pnt a single byte to file
52A flRA aSSE 				 \Branch to send completion byte
.osbget_call
52c JSR read_~_data 				 \Load A with file handle from register 2
52F TAY 				 \rile handle mnst be in Y
530 JSa os~et 				 \Get one byte tram file
533 BRA &538 				 \atanch to transfer_one_byte
.osrdch call
535 JSR osr&h
.tranafar_one_byte
53B ROR A 				 \shift riQht one bit
539 JSa &661 				 \write A to tube data register 2
53C ROL A 				 \shift left one bit
53n BRA &590 				 \Branch to send unshifted byte
.osfind_call_1
5SF JsR read_~_data				 \Load A with tube data register 2
542 nEC &54~ 				 \zero byte means close a file
544 P'h 				 \store A on stack te~orari1y
545 JSR block transfer				 \transfer file-name from co-pro
546 pLA 				 \Reatora A (Contents - access made
549 JaR csfind 				 \open the named tile
54C BRA &590 				 \nranch to return tile handle
ostind call_2
54E JSfl read_RZ_data				 \Load A with tube data register 2
551 TAY 				 \rile handAc must be in Y
552 tak				 \Load A with zero
554 JSR onfind 				 \Clnse file
55, flRA '56& 				 \Jump to send con~1etion byte
.osargs_call
55* asa read_~_data				 \Load A fror tube data register 2
55C TAX 				 \put file handie in Y
55n ~x .4				 \set up loon count
55r Jsn reftasarams				 \Read parameters into zero page
562 JSR osargs 				 \Rsad~write file attributes
565 asa write ~_data 				 \write returned A value to data register 2
sea 'nx .3 				 \Set up loon cOunt fat 4 bytes
SEA boA O,X 				 \Load A with returned attributes
Sec asa write_fl_data 				 \write A to tube data register 2
5SF flEx 				 \Dectenent count
570 Ept &56A				 \co~1ete? No - loop back and repeat
572 BRA &59e				 \Indirect branch to tube idle polling loop
.block transfer
574 wx 40 				 \zeto x
57~ WY *0				 \and Y
57$ JsR read_fl_data 				 \Load A from tube data register 2
57B S~A data,Y 				 \Store in 256 byte buffer at &700
57E 'NY 				 \rncrement Y
S7F nEO end_block				 \Fininhad 256 bytes? - Yes
501 cMp ~&D 				 \No - was byte CR (end at transfer
593 EnE &57a 				 \no - Loop back for next byte
end block
5SS ~Y ~7 				 \rinished! - Load Y with 7
5S7 RTS 				 \flrturn
oseli call
sea asa block_transfer				 \Get cli stting
San 3sn ascii 				 \Call "Os car-and line intarpreter
send_cc~letion_byte
SeE InA ~&7F 				 \Load A with 127 (co~1etIon byte)
5~O BIT r2 stat 				 \Test tube register 2 status
593 Bvc ~59O 				 \Not ready - repeat
595 STA ri_data				 \writs A to tnt,. data regimt.r 2
596 WtA LSES 				 \Indirect branch to tube idle polling lo~
-osg~b_call
S9A WIC ~sn 				 \Load X counter with length of param- block
59c as,' read~ramn 				 \Raad zero ~age ~aram trO# tube register 2
Sgr w~ 40				 \set y to la-byte at parama
SAl JSK os~pb 				 \call osg,tbyte~putbyt.
5A4 PHIL 				 \Pr.serv. A on stack
5A5 Lox IaC				 \set loop count
SA7 LnA O,X 				 \Load returned tile information
5A9 JS't write_RQ_data 				 \write A tn tube data register 2
SAC flEx 				 \Decrement count
SAD Ert s5A7				 \conp1ete? No Loop hack and repeat
SAF PTA 				 \nestore A tr~ stack
5B0 BRA &53e 				 \etanch to transfer_one_byte
onfile_call
5B2 Lnx ,&1o 				 \set up for 16 byte transfer in
5n4 Jsn read_~_data 				 \Load A from tube data register 2
5S7 S~A 1,X 				 \Store at romadd+1,X
5B~ fltx 				 \flecrement count
SNz t5n4 				 \co~lete? - No loo~ back and repeat
SEC JSa block_transfer 				 \transfet bytes
5Br STX 0 				 \Raset tijename hi-byte to zero
Sal STY 1 				 \Set tiYename pointer b-byte to Y
sca 'fly ~o 				 \set x-Y to point to 16 byte parameter block
505 JSn read_pt2_data 				 \Lcad A tror tube data register 2
505 aSa osfile 				 \Call ostile - A defines re~uired action
ScB Jsa write_RZ_data				 \Nrite result code to tube data register 2
5CR Ifix '&10 				 \Set u~ for 16 byte transfer ont
Sno KnA 1,X				 \Load tram rmadd+1,X
5n2 JSR write_~_data 				 \write A to tube data register 2
5D5 DEX				 \flecremCnt count
5D6 SNE s500				 \cc~lete? - No loop back and repeat
5DB BRA &5E8				 \2 stage in- back to tube_idle_loop
short_osbyte
SDA Jsn read_x_and_A 				 \Read X an~ A params for short osbyte
5DD JSR osbyte				 \ca11 osbyte
5~O nIT r2_stat 				 \Teat register 2 status
SES nvc &SEO 				 \not ready - lccp back until it is
SES STX r2_data 				 \write teturned X value to tube data reg 2
5E8 JKp 636 to tube idle pol1in~ loop
long-osbyte
5E3 JSR read_x_and A 				 \ncad X and A params for osbyte
5EE TAY 				 \~ove A parameter to Y
SEF JsR read_R2_data				 \Load A from tube data register ~
SF2 JSR osbyte 				 \call osbyte
5F5 Eon *&9D 				 \was it osbyte 157 (fast tube flPUT}?
5F7 BEQ 'SEa 				 \yes - Sranch to idle poll j~
579 ROR A 				 \Not 157 shift right one bit
STA asa write_fl_data 				 \write A to tube data register 2
Sm BIT rZ_3tat 				 \Test tube re4ister 2 status
600 EVa SSFD				 \Not ready - 100P back until it is
602 STY r2_data 				 \write y to tube data re~ister 2
'05 Sak &5E0 				 \Branch to write X value to regAster 2
.OSWORD call
~C7 asa read_%2_data 				 \Load A from tube data register 2
60A Thy 				 \save read~write action in Y
603 JSR read_x_n_data				 \~ad X from tube data register 2
~OE SM!				 \61A now &FF? - Yes branch to OSWORD_setup
610 JSR read_n_data 				 \Rsad patanrbera from tube data register 2
613 SZA ~l2S,X				 \stnre in paranter block at offset x
'16 DEX 				 \necrersent connt
617 SPL &610 				 \c~lete? no - loop back and re~at
619 TYA 				 \aestore read/write action from y
.onward_setup
61A LDX ~$28 				 \toad 'C with patam. block address low byte
610 KnY 41 				 \r'oad Y with param- block address high byte
EYE JSR osijord 				 \SXecut, O5WO~ using param block at &12e
621 asa read_x_R2_data 				 \Read X from tube data register 2
624 3"' &5Ee 				 \coapl,te? Yea
626 WY &129,x 				 \E1S. read parameter into Y
62g SIT t2_stat 				 \Teat tubs registet 2 status
62c Bvc &62~ 				 \Not ready - 1oo~ back until it is
~2E sty rQ_data 				 \writ. Y to tubs data register 2
631 flEx 				 \D~erement count
632 EPt ~62~				 \co~1ete~ No - loop back and tepeat
634 BRA asEe				 \rndirect branch ~o tube idle polling loop
.cswordO-call
636 ~X 				 	\Set loop count to ~ in 'C
GSa JSR read_R2_data 			 \Load A tram tube data register 2
E3B sta o,x 				 \Store at rcu-dd+X
63n Dtx 				 \Decremsnt count until X - 'Fr
63t S?t &630 				 \5 bytes xterred? - No loop back and repeat
640 Ibix 				 \rncrtment X (hack to zero
641 Tm ~set A to zero
~42 TAY 				 \Set Y to zero
643 Jsn caword 'Get character. frorn current Snout stream
646 scc &GAD 				 \Return pressed? - Yen - branch to write
64S LDA i&FF 				 \Escape pressed - load A with 255 and
64A JMP &590 				 \J~ to write register 2
.read_string
SAC Inx *0				 \zero loop counter
64F InA 4&7t 				 \Load A with stact string byte
&51 3SR write_n_data				 \write A to tube data register 2
654 WA data.x 				 \Load from 256 byte block at 6700
657 JaR write ~ data 				 \write A to tube data register 2
'SA INX 				 \Incre=flt count
CM? ~&fl 				 \tnd of input tarked by CHR$13?
CSD ENE &654 				 \No - loop back for next byte
6SF BRA &634 				 \Indirect iL- to tube idle polling loop
.write_R2_data
661 BIT r2-stat 				 \test ~ statns
GSA Eva write_R2_data				 \Nat ready loop until it is
665 STA r2_data 				 \write A to tube data register 2
669 RTS 				 \Return
.write R4 tube owner
6~A Ink &15				 \Load current tube owner
write nA data
Sec BIT r4_stat 			 \Te.t Re status
Ser nvc write_RA_data			\Not ready - loop until it is
671 STA rC_data 			 \write A to tube data regAster C
674 RTS 				 \Retnrn
.copy_escape_flag
675 LDA #FF 				 \load Accumulator with 255
677 SCF 				 \set carry flag
676 ROR A 				 \Rotate right Acurulator bAts
679 BA write_Ri_data 				 \Braneh on negative flag (bit 7. prev carry)
67B PHA 				 \preserve A on stack
670 LDA #0 				 \load A with zero
67E JSR write_Ri_data 				 \write A to tube data regist,r 1
601 TYA 				 \transfer contents ot Y to A
602 JsR write_Ri_data 			 \write A to tube data regist.r 1
685 TKA 				 	\Trannter contenta of K to A
6as JSR writ._Ri_data 			 \write a to tube data register 1
604 PLA 				 \Ra5tcre A from stack
.write Ri data
65A arT ri_stat 			 \Test Ri status
65D nvc write_Ri_data 			 \n~ps.t - Ri not ready (bit ~ clear)
65F STA ri data 			 \Write Ri data frm A
662 RTS 				 \Return
.read~atams
693 asa read_32_data 			 \load A irm tube data register 2
6SE STA &FT,x 				 \store at bottom of zero page
6~8 flEx 				 \necrermant count
699 ENE rcad~rninn 			 \c~lete? no - loo~ bac~ and tepeat
69B SKA read_fl_data 			 \Branch read Accumulator from ~
read X and A
69D Jsn read_fl_data 			 \Read data register 2 into A and transfer
6A0 TAX 				 \the value to x, then ta~1 througb to..
.read_R1_data
SAl SIT rQ_stat 			 \Test ~ status
6A4 flPt read_~_data				 \Repeat - n not ready (bit 7 clear
EAE Efla r~_data				 \Read register 2 data Into A
EAS RTS 				 \neturn
.read_R2_data
EAA SIT r2_stat				 \Test R2 status
EAD EPL read_x_w_data 			 \Repeat - ~ not ready bit 7 clear) 
EAr U)Z r2_data				 \Read register 2 data into X 
6n2 DEX 				 \Decrenent the value
'Ba RTS 				 \Return
700 data 				 \Data buffer for up to 256 bytes