Disassembly of BBC B/B+ Tube Host 2.20 Code in DFS 2.2x ======================================================= | marks Tube 2.10 code different from Tube Host 1.xx in DNFS 3.xx (DFS 1.2x/NFS 3.6x) || marks Tube 2.20 code different from Tube Host 2.10 in DFS 2.1x TUBE HOST SERVICE HANDLER ========================= .LAE8A AE8A C9 09 I. : CMP #&09 | Is it *HELP? AE8C D0 24 P$ : BNE LAEB2 | No, skip ahead AE8E 98 . : TYA | AE8F 48 H : PHA | Save string offset AE90 A9 E9 )i : LDA #&E9 | OSBYTE &E9,&00,&FF AE92 20 80 A0 . : JSR LA080 | Get Tube presence to Y AE95 A6 F4 &t : LDX &F4 | Restore X AE97 98 . : TYA | Check Tube presence flag AE98 F0 14 p. : BEQ LAEAE | No Tube hardware, skip to exit AE9A 20 77 80 w. : JSR L8077 | Print inline text AE9D 0D . : EQUB &0D || cr,"TUBE HOST 2.20",cr AE9E 54 55 42 45 TUBE : EQUS "TUBE HOST 2.20" AEA2 20 48 4F 53 HOS || AEA6 54 20 32 2E T 2. || AEAA 32 30 20 || AEAC 0D . : EQUB &0D AEAD EA j : NOP .LAEAE AEAE 68 h : PLA | Get string offset back AEAF A8 ( : TAY | AEB0 A9 09 ). : LDA #&09 | Restore A .LAEB2 AEB2 C9 FE I~ : CMP #&FE Service call &FE/&FF? AEB4 90 5C .\ : BCC LAF12 No, jump to exit AEB6 D0 1B P. : BNE LAED3 Jump with service call &FF ServFE - Tube Postinit ---------------------- AEB8 C0 00 @. : CPY #&00 Y=0 if no Tube system present AEBA F0 56 pV : BEQ LAF12 Exit with no Tube system AEBC A2 06 ". : LDX #&06 AEBE A9 14 ). : LDA #&14 AEC0 20 F4 FF t. : JSR OSBYTE Explode character set .LAEC3 AEC3 2C E0 FE ,`~ : BIT LFEE0 Check Tube Register 0 status AEC6 10 FB .{ : BPL LAEC3 Loop until data present AEC8 AD E1 FE -a~ : LDA LFEE1 Fetch data from Tube Register 0 AECB F0 43 pC : BEQ LAF10 Data=0, jump to claim call AECD 20 EE FF n. : JSR OSWRCH Print the character AED0 4C C3 AE LC. : JMP LAEC3 Loop back to wait for another ServFF - Tube Preinit --------------------- .LAED3 AED3 A9 AD )- : LDA #&AD AED5 8D 20 02 . . : STA &0220 AED8 A9 06 ). : LDA #&06 AEDA 8D 21 02 .!. : STA &0221 Point EVNTV to L06AD AEDD A9 16 ). : LDA #&16 AEDF 8D 02 02 ... : STA &0202 AEE2 A9 00 ). : LDA #&00 AEE4 8D 03 02 ... : STA &0203 Point BRKV to &0016 AEE7 A9 8E ). : LDA #&8E AEE9 8D E0 FE .`~ : STA LFEE0 Enable NMI on R1, IRQ on R4, IRQ on R1 AEEC A0 00 . : LDY #&00 Initialise code at &0400-&05FF .LAEEE AEEE B9 54 AF 9T/ : LDA LAF54,Y by copying from &AF54-&B053 AEF1 99 00 04 ... : STA &0400,Y AEF4 B9 BC AC 9<, : LDA LACBC,Y and from &ACBC-&AEBB AEF7 99 00 05 ... : STA &0500,Y AEFA B9 BC AD 9<- : LDA LADBC,Y AEFD 99 00 06 ... : STA &0600,Y AF00 88 . : DEY AF01 D0 EB Pk : BNE LAEEE Loop to copy code AF03 20 21 04 !. : JSR L0421 Set Tube 'free' and no owner AF06 A2 41 "A : LDX #&41 | Initialise code at &0000-&005F .LAF08 AF08 BD 13 AF =./ : LDA LAF13,X by copying from &AF13-&AF53 AF0B 95 16 .. : STA &16,X AF0D CA J : DEX AF0E 10 F8 .x : BPL LAF08 Loop to copy code .LAF10 AF10 A9 00 ). : LDA #&00 Claim call .LAF12 AF12 60 ` : RTS | Return from service handler Code at &AE3F-&AE7F copied to &0016-&0056 ========================================= 0000 : EQUS 18 Control block for MOS calls 0012 00 00 .. : EQUW &0000 Pointer to Tube transfer block 0014 00 . : EQUB &00 Tube status 0015 00 . : EQUB &00 Tube owner BRK handler ----------- .L0016 0016 A9 FF ). : LDA #&FF 0018 20 9E 06 .. : JSR L069E Send &FF to R4 to interupt CoPro 001B AD E3 FE -c~ : LDA LFEE3 Get ACK byte from CoPro via R2 001E A9 00 ). : LDA #&00 0020 20 95 06 .. : JSR L0695 Send &00 to R2 to specify ERROR 0023 A8 ( : TAY Point Y to start of error block 0024 B1 FD 1} : LDA (&FD),Y Get error number 0026 20 95 06 .. : JSR L0695 Send via R2 .L0029 0029 C8 H : INY Point to next character 002A B1 FD 1} : LDA (&FD),Y Get error string character 002C 20 95 06 .. : JSR L0695 Send via R2 002F AA * : TAX 0030 D0 F7 Pw : BNE L0029 Loop until terminating &00 sent Idle startup ------------ .L0032 0032 A2 FF ". : LDX #&FF 0034 9A . : TXS Clear stack 0035 58 X : CLI Enable IRQs Tube idle loop -------------- .L0036 0036 2C E0 FE ,`~ : BIT LFEE0 Is there character in R1? 0039 10 06 .. : BPL L0041 No, check for command in R2 .L003B 003B AD E1 FE -a~ : LDA LFEE1 Get character from R1 003E 20 EE FF n. : JSR OSWRCH Send to VDU drivers .L0041 0041 2C E2 FE ,b~ : BIT LFEE2 Is there command in R2? 0044 10 F0 .p : BPL L0036 No, loop back 0046 2C E0 FE ,`~ : BIT LFEE0 Check again for character in R1 0049 30 F0 0p : BMI L003B Jump to catch this character 004B AE E3 FE .c~ : LDX LFEE3 Get command from R2 004E 86 51 .Q : STX &51 Use as index into &0500 0050 6C 00 05 l.. : JMP (L0500) Jump to command routine .L0053 0053 00 80 00 00 .... : EQUD &00008000 Code at AF54-B053 copied to &0400-&04FF ======================================= Copy language across the Tube ----------------------------- .L0400 0400 4C 84 04 L.. : JMP L0484 Copy Escape state across the Tube --------------------------------- .L0403 0403 4C A7 06 L'. : JMP L06A7 Tube Transfer/Claim/Release --------------------------- .L0406 0406 C9 80 I. : CMP #&80 Claim/Release/Action via Tube 0408 90 2B .+ : BCC L0435 If <&80, data transfer action 040A C9 C0 I@ : CMP #&C0 Is it claim or release? 040C B0 1A 0. : BCS L0428 &C0-&FF - jump to claim Tube 040E 09 40 .@ : ORA #&40 Ensure release ID same as claim ID 0410 C5 15 E. : CMP &15 Is the the same as the claim ID? 0412 D0 20 P : BNE L0434 No, exit. 0414 08 . : PHP Save IRQ state 0415 78 x : SEI Disable IRQs 0416 A9 05 ). : LDA #&05 Send &05 to R4 to interupt CoPro 0418 20 9E 06 .. : JSR L069E 041B A5 15 %. : LDA &15 Send Tube ID to notify a Tube release 041D 20 9E 06 .. : JSR L069E 0420 28 ( : PLP Get IRQ state back Clear Tube status and owner --------------------------- .L0421 0421 A9 80 ). : LDA #&80 0423 85 15 .. : STA &15 Set Tube ID to 'unclaimed' 0425 85 14 .. : STA &14 Set Tube status to 'free' 0427 60 ` : RTS Claim Tube ---------- .L0428 0428 06 14 .. : ASL &14 Is Tube free? 042A B0 06 0. : BCS L0432 Yes, jump to claim it 042C C5 15 E. : CMP &15 Is Tube ID same as claimer? 042E F0 04 p. : BEQ L0434 Yes, exit as we already own it 0430 18 . : CLC Signal 'can't claim Tube' 0431 60 ` : RTS And exit .L0432 0432 85 15 .. : STA &15 Store Tube ID 0434 60 ` : RTS Tube data transfer ------------------ .L0435 0435 08 . : PHP Save IRQ status 0436 78 x : SEI Disable IRQs 0437 84 13 .. : STY &13 Store pointer to control block 0439 86 12 .. : STX &12 Send action code to R4 to 043B 20 9E 06 .. : JSR L069E interrupt CoPro 043E AA * : TAX Save action code in X 043F A0 03 . : LDY #&03 Prepare to send 4 byte control block 0441 A5 15 %. : LDA &15 Send Tube ID via R4, interupting 0443 20 9E 06 .. : JSR L069E CoPro .L0446 0446 B1 12 1. : LDA (&12),Y Get byte from Tube control block 0448 20 9E 06 .. : JSR L069E Send via R4 044B 88 . : DEY 044C 10 F8 .x : BPL L0446 Loop for whole block 044E A0 18 . : LDY #&18 0450 8C E0 FE .`~ : STY LFEE0 Disable FIFO on R3, and NMI on R3 by default 0453 BD 18 05 =.. : LDA L0518,X Get Tube I/O setting according to 0456 8D E0 FE .`~ : STA LFEE0 action code and set Tube 0459 4A J : LSR A 045A 4A J : LSR A Move b1 to Carry (b1 set = Copro->I/O) 045B 90 06 .. : BCC L0463 If no pre-delay needed, jump past 045D 2C E5 FE ,e~ : BIT LFEE5 Read R3 twice to delay & empty FIFO 0460 2C E5 FE ,e~ : BIT LFEE5 0463 20 9E 06 .. : JSR L069E Send flag via R4 to synchronise .L0466 0466 2C E6 FE ,f~ : BIT LFEE6 Check R4 status 0469 50 FB P{ : BVC L0466 Loop until data has left R4 046B B0 0D 0. : BCS L047A Carry still indicates direction 046D E0 04 `. : CPX #&04 Is action 'execute code'? 046F D0 11 P. : BNE L0482 No, jump to finish 0471 20 14 04 .. : JSR L0414 Release Tube 0474 20 95 06 .. : JSR L0695 Send &80 via R2 0477 4C 32 00 L2. : JMP L0032 Jump to Tube idle loop 047A 4A J : LSR A Move Tube I/O b2 into Carry (b2 set = NMI required) 047B 90 05 .. : BCC L0482 It was clear, jump to exit 047D A0 88 . : LDY #&88 Set Tube I/O to NMI on R3 047F 8C E0 FE .`~ : STY LFEE0 0482 28 ( : PLP Restore IRQ status 0483 60 ` : RTS And exit Copy language across Tube ------------------------- On entry, A=1 - enter language, CLC=Break, SEC=OSBYTE 142 A=0 - no language found at Break .L0484 0484 58 X : CLI Enable IRQs 0485 B0 11 0. : BCS L0498 Branch if selected with *fx142 0487 D0 03 P. : BNE L048C A<>0, jump to enter language 0489 4C 9C 05 L.. : JMP L059C A=0, jump to enter Tube idle loop Language entered at BREAK ------------------------- .L048C 048C A2 00 ". : LDX #&00 048E A0 FF . : LDY #&FF 0490 A9 FD )} : LDA #&FD 0492 20 F4 FF t. : JSR OSBYTE Get last Break type 0495 8A . : TXA If soft Break, release Tube, 0496 F0 D9 pY : BEQ L0471 send &80 via R2 and enter idle loop The current language is not copied across the Tube on soft Break, only on Power-On Break and Hard Break, or when entered explicitly with OSBYTE 142. Language entered with OSBYTE 142, or on Hard Break -------------------------------------------------- 0498 A9 FF ). : LDA #&FF 049A 20 06 04 .. : JSR L0406 Claim Tube with ID=&3F 049D 90 F9 .y : BCC L0498 Loop until Tube available 049F 20 D2 04 R. : JSR L04D2 Find address to copy language to Send language ROM via Tube 256 bytes at a time ---------------------------------------------- 04A2 A9 07 ). : LDA #&07 Start I/O->CoPro transfer 256 bytes 04A4 20 CB 04 K. : JSR L04CB Use Tube address at &53-&56 04A7 A0 00 . : LDY #&00 04A9 84 00 .. : STY &00 Start copying from &8000 04AB B1 00 1. : LDA (&00),Y Get byte from ROM 04AD 8D E5 FE .e~ : STA LFEE5 Send to CoPro via R3 04B0 EA j : NOP Delay for a while 04B1 EA j : NOP 04B2 EA j : NOP 04B3 C8 H : INY 04B4 D0 F5 Pu : BNE L04AB Loop for 256 bytes 04B6 E6 54 fT : INC &54 Update Tube address 04B8 D0 06 P. : BNE L04C0 04BA E6 55 fU : INC &55 04BC D0 02 P. : BNE L04C0 04BE E6 56 fV : INC &56 04C0 E6 01 f. : INC &01 Update source address 04C2 24 01 $. : BIT &01 Check b6 of source high byte 04C4 50 DC P\ : BVC L04A2 Loop until source=&C000 04C6 20 D2 04 R. : JSR L04D2 Find start address language copied to 04C9 A9 04 ). : LDA #&04 Execute code in CoPro, finished by sending &80 to Copro in R2 Start a Tube transfer with address block at &0053 ------------------------------------------------- 04CB A0 00 . : LDY #&00 04CD A2 53 "S : LDX #&53 Point to Tube control block 04CF 4C 06 04 L.. : JMP L0406 Jump to do a data transfer Set Tube address to destination to copy language to --------------------------------------------------- Also sets source address at &00/&01 to &80xx .L04D2 04D2 A9 80 ). : LDA #&80 04D4 85 54 .T : STA &54 Set Tube address to &xxxx80xx 04D6 85 01 .. : STA &01 Set source address to &80xx 04D8 A9 20 ) : LDA #&20 04DA 2D 06 80 -.. : AND &8006 Check relocation bit in ROM type 04DD A8 ( : TAY If no relocation address, A=0, Y=0 04DE 84 53 .S : STY &53 Set Tube address to &xxxx8000 04E0 F0 19 p. : BEQ L04FB Jump forward with no relocation 04E2 AE 07 80 ... : LDX &8007 Get offset to ROM copyright 04E5 E8 h : INX 04E6 BD 00 80 =.. : LDA &8000,X Skip past copyright message 04E9 D0 FA Pz : BNE L04E5 Loop until terminating zero byte 04EB BD 01 80 =.. : LDA &8001,X Get relocation address from after 04EE 85 53 .S : STA &53 copyright message 04F0 BD 02 80 =.. : LDA &8002,X 04F3 85 54 .T : STA &54 04F5 BC 03 80 <.. : LDY &8003,X Get two high bytes to Y and A 04F8 BD 04 80 =.. : LDA &8004,X Set Tube address high bytes --------------------------- 04FB 85 56 .V : STA &56 Set Tube address high bytes 04FD 84 55 .U : STY &55 04FF 60 ` : RTS Code at &ACBC-&AEBB copied to &0500-&06FF ========================================= Tube R2 command entry block --------------------------- .L0500 0500 37 05 7. : EQUW L0537 RDCH 0502 96 05 .. : EQUW L0596 CLI 0504 F2 05 .r : EQUW L05F2 BYTELO 0506 07 06 .. : EQUW L0607 BYTEHI 0508 27 06 .' : EQUW L0627 WORD 050A 68 06 .h : EQUW L0668 WORD0 050C 5E 05 .^ : EQUW L055E ARGS 050E 2D 05 .- : EQUW L052D BGET 0500 20 05 . : EQUW L0520 BPUT 0512 42 05 .B : EQUW L0542 FIND 0514 A9 05 .) : EQUW L05A9 FILE 0516 D1 05 .Q : EQUW L05D1 GBPB Tube data transfer flags ------------------------ .L0518 0518 86 . : EQUB &86 CoPro->I/O bytes 0519 88 . : EQUB &88 I/O->CoPro bytes 051A 96 . : EQUB &96 CoPro->I/O words 051B 98 : EQUB &98 I/O->CoPro words 051C 18 . : EQUB &18 Execute in CoPro 051D 18 . : EQUB &18 Reserved 051E 82 . : EQUB &82 CoPro->I/O 256 bytes 051F 18 . : EQUB &18 I/O->CoPro 256 bytes BPUT ---- .L0520 0520 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 0523 A8 ( : TAY Pass to Y as file handle 0524 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 0527 20 D4 FF T. : JSR OSBPUT Write byte to file 052A 4C 9C 05 L.. : JMP L059C Send &7F ack byte via R2 and return to idle loop BGET ---- .L052D 052D 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 0530 A8 ( : TAY Pass to Y as file handle 0531 20 D7 FF W. : JSR OSBGET Fetch a byte from file 0534 4C 3A 05 L:. : JMP L053A Jump to send Carry and A RDCH ---- .L0537 0537 20 E0 FF `. : JSR OSRDCH Wait for a character .L053A 053A 6A j : ROR A Move carry to b7 053B 20 95 06 .. : JSR L0695 Send via R2 053E 2A * : ROL A Move A back 053F 4C 9E 05 L.. : JMP L059E Send via R2 and return to idle loop FIND ---- .L0542 0542 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 0545 F0 0B p. : BEQ L0552 Zero - jump to do CLOSE 0547 48 H : PHA Save OPEN action 0548 20 82 05 .. : JSR L0582 Get a string via R2 054B 68 h : PLA Get OPEN function back 054C 20 CE FF N. : JSR OSFIND Do the OPEN 054F 4C 9E 05 L.. : JMP L059E Send handle via R2 and go to idle loop CLOSE ----- .L0552 0552 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 0555 A8 ( : TAY Pass to Y as handle 0556 A9 00 ). : LDA #&00 Set A=0 for CLOSE 0558 20 CE FF N. : JSR OSFIND Do the CLOSE 055B 4C 9C 05 L.. : JMP L059C Send &7F ack and jump to idle loop ARGS ---- .L055E 055E 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 0561 A8 ( : TAY Pass to Y as handle 0562 A2 04 ". : LDX #&04 Fetch four bytes for control block .L0564 0564 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 0567 95 FF .. : STA &FF,X Store in &03,&02,&01,&00 0569 CA J : DEX 056A D0 F8 Px : BNE L0564 Loop for four bytes, X now &00 056C 20 C5 06 E. : JSR L06C5 Wait for ARGS function via R2 056F 20 DA FF Z. : JSR OSARGS Do the OSARGS action 0572 20 95 06 .. : JSR L0695 Send A back via R2 0575 A2 03 ". : LDX #&03 Send four bytes from control block .L0577 0577 B5 00 5. : LDA &00,X Fetch from &03,&02,&01,&00 0579 20 95 06 .. : JSR L0695 Send via R2 057C CA J : DEX 057D 10 F8 .x : BPL L0577 Loop for four bytes 057F 4C 36 00 L6. : JMP L0036 Jump to Tube idle loop Read a string via R2 into string buffer at &0700 ------------------------------------------------ .L0582 0582 A2 00 ". : LDX #&00 Set X to point to &xx00 0584 A0 00 . : LDY #&00 0586 20 C5 06 E. : JSR L06C5 Wait for a byte via R2 .L0586 0589 99 00 07 ... : STA &0700,Y Store in string buffer 058C C8 H : INY Move to next byte 058D F0 04 p. : BEQ L0593 Buffer full, end loop 058F C9 0D I. : CMP #&0D Was last char ? 0591 D0 F3 Ps : BNE L0586 Loop until received .L0593 0593 A0 07 . : LDY #&07 Return XY pointing to &0700 0595 60 ` : RTS CLI --- .L0596 0596 20 82 05 .. : JSR L0582 Read string to &0700 0599 20 F7 FF w. : JSR OS_CLI Execute the command If the command returns here, the CoPro will get &7F as an acknowledgement. The CoPro also gets sent a &7F byte if there is no language available on Break. If calling OSCLI results in code being run in the CoPro or a language being copied over and entered, the CoPro will get an &80 acknowledgement elsewhere. Send &7F acknowledgement byte via R2 and return to idle loop ------------------------------------------------------------ 059C A9 7F ). : LDA #&7F Send &7F to CoPro Send byte in A via R2 and return to Tube idle loop -------------------------------------------------- .L059E 059E 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 05A1 50 FB P{ : BVC L059E Loop until port free 05A3 8D E3 FE .c~ : STA LFEE3 Send byte in A .L05A6 05A6 4C 36 00 L6. : JMP L0036 Jump to Tube idle loop FILE ---- .L05A9 05A9 A2 10 ". : LDX #&10 Loop for 16-byte control block .L05AB 05AB 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 05AE 95 01 .. : STA &01,X Store in control block 05B0 CA J : DEX 05B1 D0 F8 Px : BNE L05AB Loop to store high->low 05B3 20 82 05 .. : JSR L0582 Read string to &0700 05B6 86 00 .. : STX &00 Point control block to string 05B8 84 01 .. : STY &01 05BA A0 00 . : LDY #&00 Point XY to &0000 05BC 20 C5 06 E. : JSR L06C5 Wait for action byte via R2 05BF 20 DD FF ]. : JSR OSFILE Do the OSFILE call During the OSFILE call the Tube system may be called to do a data transfer 05C2 20 95 06 .. : JSR L0695 Send result back via R2 05C5 A2 10 ". : LDX #&10 Send 16-byte control block back .L05C7 05C7 B5 01 5. : LDA &01,X Get byte from control block 05C9 20 95 06 .. : JSR L0695 Send via R2 05CC CA J : DEX 05CD D0 F8 Px : BNE L05C7 Loop to send high->low 05CF F0 D5 pU : BEQ L05A6 Jump to Tube idle loop GBPB ---- .L05D1 05D1 A2 0D ". : LDX #&0D Loop for 13-byte control block .L05D3 05D3 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 05D6 95 FF .. : STA &FF,X Store in control block 05D8 CA J : DEX 05D9 D0 F8 Px : BNE L05D3 Loop to store high->low, X now &00 05DB 20 C5 06 E. : JSR L06C5 Wait for action byte via R2 05DE A0 00 . : LDY #&00 Set XY to point to &0000 05E0 20 D1 FF Q. : JSR OSGBPB Do the OSGBPB call During the OSGBPB call the Tube system may be called to do a data transfer 05E3 48 H : PHA Save the result 05E4 A2 0C ". : LDX #&0C Loop for 13-byte control block .L05E6 05E6 B5 00 5. : LDA &00,X Get byte from control block 05E8 20 95 06 .. : JSR L0695 Send via R2 05EB CA J : DEX 05EC 10 F8 .x : BPL L05E6 Loop to send high->low 05EE 68 h : PLA Get result byte byte 05EF 4C 3A 05 L:. : JMP L053A Jump to send Carry and A, then return to Tube idle loop BYTELO - OSBYTEs &00-&7F ------------------------ .L05F2 05F2 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 05F5 AA * : TAX Pass this to X 05F6 20 C5 06 E. : JSR L06C5 Wait for byte in R2 to use a A 05F9 20 F4 FF t. : JSR OSBYTE Do the OSBYTE call Send byte in X via R2 and jump to Tube idle loop ------------------------------------------------ .L05FC 05FC 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 05FF 50 FB P{ : BVC L05FC Loop until port free 0601 8E E3 FE .c~ : STX LFEE3 Send X via R2 .L0604 0604 4C 36 00 L6. : JMP L0036 Return to Tube idle loop BYTEHI - OSBYTE &80-&FF ----------------------- .L0607 0607 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 060A AA * : TAX Pass this to X 060B 20 C5 06 E. : JSR L06C5 Wait for a byte in R2 060E A8 ( : TAY Pass this to Y 060F 20 C5 06 E. : JSR L06C5 Wait for byte in R2 to use as A 0612 20 F4 FF t. : JSR OSBYTE Do the OSBYTE call If the OSBYTE results in code being executed - ie, OSBYTE 142, then the call will not be returned here, and the CoPro will be sent an &80 ack byte. 0615 49 9D I. : EOR #&9D Was if OSBYTE &9D - Fast BPUT? 0617 F0 EB pk : BEQ L0604 If so, jump stright back to idle loop 0619 6A j : ROR A Move Carry into b7 of A 061A 20 95 06 .. : JSR L0695 Send via R2 Send bytes in Y, X via R2, then jump to Tube idle loop ------------------------------------------------------ .L061D 061D 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 0620 50 FB P{ : BVC L061D Loop until port free 0622 8C E3 FE .c~ : STY LFEE3 Send byte in Y 0625 70 D5 pU : BVS L05FC Jump to send X and jump to idle loop WORD ---- .L0627 0627 20 C5 06 E. : JSR L06C5 Wait for action byte in R2 062A A8 ( : TAY Save in Y .L062B 062B 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 062E 10 FB .{ : BPL L062B Loop until data present 0630 AE E3 FE .c~ : LDX LFEE3 Get X from R2 - number of bytes inward 0633 CA J : DEX See if no bytes to read. Note: this 0634 30 0F 0. : BMI L0645 treats &81-&FF as zero as well .L0636 0636 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 0639 10 FB .{ : BPL L0636 Loop until data present 063B AD E3 FE -c~ : LDA LFEE3 Get byte from R2 063E 9D 28 01 .(. : STA &0128,X Store in control block 0641 CA J : DEX 0642 10 F2 .r : BPL L0636 Loop to read high->low 0644 98 . : TYA Get function byte to A This builds the OSWORD control block in &0128 up towards &01FF, allowing a maximum control block of almost 216 bytes before it crashes into the stack. However, the protocol treats a control block length of &81-&FF as zero, so the maximum size control block will be &0128-&01A7. .L0645 0645 A2 28 "( : LDX #&28 Point XY to control block at &0128 0647 A0 01 . : LDY #&01 0649 20 F1 FF q. : JSR OSWORD Do the OSWORD call .L064C 064C 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 064F 10 FB .{ : BPL L064C Loop until data present 0651 AE E3 FE .c~ : LDX LFEE3 Get output control block size to X 0654 CA J : DEX See if no bytes to return - again, 0655 30 0E 0. : BMI L0665 treating &81-&FF as zero. .L0657 0657 BC 28 01 <(. : LDY &0128,X Get byte from control block .L065A 065A 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 065D 50 FB P{ : BVC L065A Loop until port free 065F 8C E3 FE .c~ : STY LFEE3 Send byte to R2 0662 CA J : DEX 0663 10 F2 .r : BPL L0657 Loop to send bytes high->low .L0665 0665 4C 36 00 L6. : JMP L0036 Return to Tube idle loop WORD0 - Read a line ------------------- .L0668 0668 A2 04 ". : LDX #&04 Fetch five bytes into control block .L066A 066A 20 C5 06 E. : JSR L06C5 Wait for a byte via R2 066D 95 00 .. : STA &00,X Store in control block 066F CA J : DEX 0670 10 F8 .x : BPL L066A Loop to get five bytes high->low 0672 E8 h : INX Increment X back to &00 0673 A0 00 . : LDY #&00 Point XY to control block at &0000 0675 8A . : TXA Set A=0 to read a line 0676 20 F1 FF q. : JSR OSWORD Call OSWORD to read the line This call assumes that the CoPro client code has sent the bottom two bytes as &00,&07 so that the OSWORD call will read the text line to &0700. There is enough space to make the code do LDA #7:STA &01:TXA:TAY:STY &00:JSR OSWORD. 0679 90 05 .. : BCC L0680 Jump if no Escape 067B A9 FF ). : LDA #&FF Send &FF via R2 to indicate Escape 067D 4C 9E 05 L.. : JMP L059E and return to Tube idle loop .L0680 0680 A2 00 ". : LDX #&00 Point to start of string buffer 0682 A9 7F ). : LDA #&7F 0684 20 95 06 .. : JSR L0695 Send &7F via R2 to indicate no Escape .L0687 0687 BD 00 07 =.. : LDA &0700,X Get byte from string buffer 068A 20 95 06 .. : JSR L0695 Send byte via R2 068D E8 h : INX Move to next byte 068E C9 0D I. : CMP #&0D 0690 D0 F5 Pu : BNE L0687 Loop until sent 0692 4C 36 00 L6. : JMP L0036 Jump to Tube idle loop Send byte in A via R2 --------------------- .L0695 0695 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 0698 50 FB P{ : BVC L0695 Loop until port free 069A 8D E3 FE .c~ : STA LFEE3 Send byte 069D 60 ` : RTS Send byte in A via R4 --------------------- .L069E 069E 2C E6 FE ,f~ : BIT LFEE6 Check R4 status 06A1 50 FB P{ : BVC L069E Loop until port free 06A3 8D E7 FE .g~ : STA LFEE7 Send byte 06A6 60 ` : RTS Copy Escape state across Tube ----------------------------- .L06A7 06A7 A5 FF %. : LDA &FF Get Escape state 06A9 38 8 : SEC 06AA 6A j : ROR A Rotate escape to b6 and set b7 06AB 30 0F 0. : BMI L06BC Interupt client with byte send via R1 Send event across Tube ---------------------- .L06AD 06AD 48 H : PHA Save A 06AE A9 00 ). : LDA #&00 06B0 20 BC 06 <. : JSR L06BC Send &00 via R1, generating client IRQ After being interupted with the first byte, above, the client usually disables IRQs and reads the following bytes directly from the Tube registers. 06B3 98 . : TYA 06B4 20 BC 06 <. : JSR L06BC Send Y via R1 06B7 8A . : TXA 06B8 20 BC 06 <. : JSR L06BC Send X via R1 06BB 68 h : PLA Get A back and send via R1 Send byte in A via R1 --------------------- .L06BC 06BC 2C E0 FE ,`~ : BIT LFEE0 Check R1 status 06BF 50 FB P{ : BVC L06BC Loop until port free 06C1 8D E1 FE .a~ : STA LFEE1 Send byte 06C4 60 ` : RTS Wait for data via R2 -------------------- .L06C5 06C5 2C E2 FE ,b~ : BIT LFEE2 Check R2 status 06C8 10 FB .{ : BPL L06C5 Loop until data present 06CA AD E3 FE -c~ : LDA LFEE3 Get byte 06CD 60 ` : RTS Unused space ------------ 06CE-06FF String buffer ------------- .L0700 0700 EQUS 256 String buffer Changes ------- The TUBE HOST version number appears to mirror the DFS version the code shares a ROM with. v2.10 - *Help displays TUBE HOST 2.10 if Tube enabled v2.20 - *Help version changed to 2.20 History ------- 07-Oct-1998 Initial disassembly and commentary by JGH