Disassembly of Master Tube Host Code in Utils ROM with MOS 3.20 =============================================================== | marks code different from Tube Host 1.xx in DNFS 3.xx (DFS 1.2x/NFS 3.6x) || marks code different from Tube Host 2.xx in DFS 2.xx UTILS ROM HEADER ================ 8003 4C 72 9D Lr. JMP &9D72 SERVICE HANDLER =============== 9D72 C9 FE Éþ CMP #&FE 9D74 90 56 .V BCC &9DCC Jump if not Tube call 9D76 D0 14 Ð. BNE &9D8C Jump with &FF ServFE - Tube Postinit ---------------------- 9D78 C0 00 À. CPY #&00 Y=0 if no Tube 9D7A F0 50 ðP BEQ &9DCC Exit with no Tube || Character set already exploded 9D7C 2C E0 FE ,àþ BIT &FEE0 Check Tube Register 0 status 9D7F 10 FB .û BPL &9D7C Loop until data present 9D81 AD E1 FE ­áþ LDA &FEE1 Fetch data from Tube Register 0 9D84 F0 44 ðD BEQ &9DCA Data=0, jump to claim call 9D86 20 EE FF î. JSR OSWRCH Print the character 9D89 4C 7C 9D L|. JMP &9D7C Loop back for another ServFF - Tube Preinit --------------------- 9D8C A9 7B ©{ LDA #&7B 9D8E 8D 20 02 . . STA &0220 9D91 A9 06 ©. LDA #&06 9D93 8D 21 02 .!. STA &0221 || Point EVNTV to &067B 9D96 A9 16 ©. LDA #&16 9D98 8D 02 02 ... STA &0202 9D9B A9 00 ©. LDA #&00 9D9D 8D 03 02 ... STA &0203 Point BRKV to &0016 9DA0 A9 8E ©. LDA #&8E 9DA2 8D E0 FE .àþ STA &FEE0 Enable NMI on R1, IRQ on R4, IRQ on R1 9DA5 A0 00  . LDY #&00 Initialise code at &0400-&05FF 9DA7 B9 6E AB ¹n« LDA &AB6E,Y by copying from &AB6E-&AC6D 9DAA 99 00 04 ... STA &0400,Y 9DAD B9 65 AC ¹e¬ LDA &AC65,Y and &AC65-&AE65 9DB0 99 00 05 ... STA &0500,Y 9DB3 B9 65 AD ¹e­ LDA &AD65,Y 9DB6 99 00 06 ... STA &0600,Y 9DB9 88 . DEY 9DBA D0 EB Ðë BNE &9DA7 Loop to copy code 9DBC 20 1F 04 .. JSR &041F Set Tube 'free' and no owner 9DBF A2 41 ¢A LDX #&41 Initialise code at &0016-&0057 9DC1 BD 2D AB ½-« LDA &AB2D,X by copying from &AB2D-&6E 9DC4 9D 16 00 ... STA &0016,X 9DC7 CA Ê DEX 9DC8 10 F7 .÷ BPL &9DC1 Loop to copy code 9DCA A9 00 ©. LDA #&00 Claim service call Continue service handler ------------------------ 9DCC C9 12 É. CMP #&12 Code at &AB2D copied to &0016 ============================= 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 ----------- 0016 A9 FF ©. LDA #&FF 0018 20 6C 06 l. JSR &066C Send &FF to R4 to interupt CoPro 001B AD E3 FE ­ãþ LDA &FEE3 Get ACK byte from CoPro 001E A9 00 ©. LDA #&00 0020 20 61 06 a. JSR &0661 Send &00 to R2 to specify ERROR 0023 A8 ¨ TAY Point Y to start of error block 0024 B1 FD ±ý LDA (&FD),Y Get error number 0026 20 61 06 a. JSR &0661 Send via R2 0029 C8 È INY Point to next character 002A B1 FD ±ý LDA (&FD),Y Get error string character 002C 20 61 06 l. JSR &0661 Send via R2 002F AA ª TAX 0030 D0 F7 Ð÷ BNE &0029 Loop until terminating &00 sent Idle startup ------------ 0032 A2 FF ¢. LDX #&FF 0034 9A . TXS Clear stack 0035 58 X CLI Enable IRQs Tube idle loop -------------- 0036 2C E0 FE ,àþ BIT &FEE0 Is there character in R1? 0039 10 06 .. BPL &0041 No, check for command in R2 003B AD E1 FE ­áþ LDA &FEE1 Get character from R1 003E 20 EE FF î. JSR OSWRCH Send to VDU drivers 0041 2C E2 FE ,âþ BIT &FEE2 Is there command in R2? 0044 10 F0 .ð BPL &0036 No, loop back 0046 2C E0 FE ,àþ BIT &FEE0 Check again for character in R1 0049 30 F0 0ð BMI &003B Jump to catch this character 004B AE E3 FE ®ãþ LDX &FEE3 Get command from R2 004E 86 51 .Q STX &51 Use as index into &0500 0050 6C 00 05 l.. JMP (&0500) Jump to command routine 0053 00 80 00 00 .... EQUD &00800000 Code at &AB6E-&AC6D and &AC65-&AE64 copied to &0400-&06FF ========================================================= Copy language across the Tube ----------------------------- 0400 4C C2 04 LÂ. JMP &04C2 Copy Escape state across the Tube --------------------------------- 0403 4C 75 06 Lu. JMP &0675 Tube Transfer/Claim/Release --------------------------- 0406 C9 80 É. CMP #&80 Claim/Release/Action via Tube 0408 90 29 .) BCC &0433 If <&80, data transfer action 040A C9 C0 ÉÀ CMP #&C0 Is it claim or release? 040C B0 18 °. BCS &0426 &C0-&FF - jump to claim Tube 040E 09 40 .@ ORA #&40 Ensure release ID same as claim ID 0410 C5 15 Å. CMP &15 Is the the same as the claim ID? 0412 D0 1E Ð. BNE &0432 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 6C 06 l. JSR &066C 041B 20 6A 06 j. JSR &066A || Send Tube ID to notify a Tube release 041E 28 ( PLP Get IRQ state back Clear Tube status and owner --------------------------- 041F A9 80 ©. LDA #&80 0421 85 15 .. STA &15 Set Tube ID to 'unclaimed' 0423 85 14 .. STA &14 Set Tube status to 'free' 0425 60 ` RTS Claim Tube ---------- 0426 06 14 .. ASL &14 Is Tube free? 0428 B0 06 °. BCS &0430 Yes, jump to claim it 042A C5 15 Å. CMP &15 Is Tube ID same as claimer? 042C F0 04 ð. BEQ &0432 Yes, exit as we already own it 042E 18 . CLC Signal 'can't claim Tube' 042F 60 ` RTS And exit 0430 85 15 .. STA &15 Store Tube ID 0432 60 ` RTS Tube data transfer ------------------ 0433 08 . PHP Save IRQ status 0434 78 x SEI Disable IRQs 0435 84 13 .. STY &13 Store pointer to control block 0437 86 12 .. STX &12 Send action code to R4 to 0439 20 6C 06 l. JSR &066C interrupt CoPro 043C AA ª TAX Save action code in X 043D A0 03  . LDY #&03 Prepare to send 4 byte control block 043F 20 6A 06 j. JSR &066A || Send Tube ID via R4, interupting CoPro 0442 B1 12 ±. LDA (&12),Y Get byte from Tube control block 0444 20 6C 06 l. JSR &066C Send via R4 0447 88 . DEY 0448 10 F8 .ø BPL &0442 Loop for whole block 044A A0 18  . LDY #&18 044C 8C E0 FE .àþ STY &FEE0 Disable FIFO on R3, and NMI on R3 by default 044F BD 18 05 ½.. LDA &0518,X Get Tube I/O setting according to 0452 8D E0 FE .àþ STA &FEE0 action code and set Tube 0455 4A J LSR A 0456 4A J LSR A Move b1 to Carry (b1 set = Copro->I/O) 0457 90 06 .. BCC &045F If no pre-delay needed, jump past 0459 2C E5 FE ,åþ BIT &FEE5 Read R3 twice to delay & empty FIFO 045C 2C E5 FE ,åþ BIT &FEE5 045F 20 6C 06 l. JSR &066C Send flag via R4 to synchronise 0462 2C E6 FE ,æþ BIT &FEE6 Check R4 status 0465 50 FB Pû BVC &0462 Loop until data has left R4 0467 B0 0D °. BCS &0476 Carry still indicates direction 0469 E0 04 à. CPX #&04 Is action 'execute code'? 046B D0 11 Ð. BNE &047E No, jump to finish 046D 20 14 04 .. JSR &0414 Release Tube 0470 20 61 06 a. JSR &0661 Send &80 via R2 0473 4C 32 00 L2. JMP &0032 Jump to Tube Idle loop 0476 4A J LSR A Move Tube I/O setting b2 into Carry (b2 set = NMI required) 0477 90 05 .. BCC &047E It was clear, jump to exit 0479 A0 88  . LDY #&88 Set Tube I/O to NMI on R3 047B 8C E0 FE .àþ STY &FEE0 047E 28 ( PLP Restore IRQ status 047F 60 ` RTS And exit Language entered at BREAK ------------------------- 0480 AE 8D 02 ®.. LDX &028D | Get last break type 0483 F0 E8 ðè BEQ &046D If Soft Break, release Tube, 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 -------------------------------------------------- 0485 A9 FF ©. LDA #&FF 0487 20 06 04 .. JSR &0406 Claim Tube with ID=&3F 048A 90 F9 .ù BCC &0485 Loop until Tube available 048C 20 C9 04 É. JSR &04C9 Find address to copy language to Send language ROM via Tube 256 bytes at a time ---------------------------------------------- 048F 08 . PHP | Save IRQ status 0490 78 x SEI | Disable IRQs 0491 A9 07 ©. LDA #&07 Start I/O->CoPro transfer 256 bytes 0493 20 BB 04 ». JSR &04BB Use Tube address at &53-&56 0496 A0 00  . LDY #&00 0498 64 00 d. STZ &00 || Start copying from &8000 049A B1 00 ±. LDA (&00),Y Get byte from ROM 049C 8D E5 FE .åþ STA &FEE5 Send to CoPro via R3 049F EA ê NOP Delay for a while 04A0 EA ê NOP 04A1 EA ê NOP 04A2 C8 È INY 04A3 D0 F5 Ðõ BNE &049A Loop for 256 bytes 04A5 28 ( PLP | Restore IRQs 04A6 E6 54 æT INC &54 Update Tube address 04A8 D0 06 Ð. BNE &04B0 04AA E6 55 æU INC &55 04AC D0 02 Ð. BNE &04B0 04AE E6 56 æV INC &56 04B0 E6 01 æ. INC &01 Update source address 04B2 24 01 $. BIT &01 Check b6 of source high byte 04B4 50 D9 PÙ BVC &048F Loop until source=&C000 04B6 20 C9 04 É. JSR &04C9 Find start address language copied to 04B9 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 ------------------------------------------------- 04BB A0 00  . LDY #&00 04BD A2 53 ¢S LDX #&53 Point to Tube control block 04BF 4C 06 04 L.. JMP &0406 Jump to do a data transfer Copy language across Tube ------------------------- On entry, A=1 - enter language, CLC=Break, SEC=OSBYTE 142 A=0 - no language found at Break || Code moved 04C2 58 X CLI Enable IRQs 04C3 B0 C0 °À BCS &0485 Branch if selected with *fx142 04C5 D0 B9 й BNE &0480 A<>0, jump to enter language 04C7 80 61 .a BRA &052A A=0, jump to enter Tube Idle loop Set Tube address to destination to copy language to --------------------------------------------------- Also sets source address at &00/&01 to &80xx 04C9 A9 80 ©. LDA #&80 04CB 85 54 .T STA &54 Set Tube address to &xxxx80xx 04CD 85 01 .. STA &01 Set source address to &80xx 04CF A9 20 © LDA #&20 04D1 2D 06 80 -.. AND &8006 Check relocation bit in ROM type 04D4 A8 ¨ TAY If no relocation address, A=0, Y=0 04D5 84 53 .S STY &53 Set Tube address to &xxxx8000 04D7 F0 19 ð. BEQ &04F2 Jump forward with no relocation 04D9 AE 07 80 ®.. LDX &8007 Get offset to ROM copyright 04DC E8 è INX 04DD BD 00 80 ½.. LDA &8000,X Skip past copyright message 04E0 D0 FA Ðú BNE &04DC Loop until terminating zero byte 04E2 BD 01 80 ½.. LDA &8001,X Get relocation address from after 04E5 85 53 .S STA &53 copyright message 04E7 BD 02 80 ½.. LDA &8002,X 04EA 85 54 .T STA &54 04EC BC 03 80 ¼.. LDY &8003,X Get two high bytes to Y and A 04EF BD 04 80 ½.. LDA &8004,X Set Tube address high bytes --------------------------- 04F2 85 56 .V STA &56 Set Tube address high bytes 04F4 84 55 .U STY &55 04F6 60 ` RTS Spare bytes ----------- 04F7 35 05 5. AND &05,X | 04F9 88 . DEY | 04FA 05 DA .Ú ORA &DA | 04FC 05 EB .ë ORA &EB | 04FE 05 07 .. ORA &07 | Tube R2 command entry block --------------------------- 0500 35 05 5. EQUW &0535 RDCH 0502 88 05 .. EQUW &0588 CLI 0504 DA 05 Ú. EQUW &05DA BYTELO 0506 EB 05 ë. EQUW &05EB BYTEHI 0508 07 06 .. EQUW &0607 WORD 050A 36 06 6. EQUW &0636 WORD0 050C 59 05 Y. EQUW &0559 ARGS 050E 2C 05 ,. EQUW &052C BGET 0510 20 05 . EQUW &0520 BPUT 0512 3F 05 ?. EQUW &053F FIND 0514 B2 05 ². EQUW &05B2 FILE 0516 9A 05 .. EQUW &059A GBPB Tube data transfer flags ------------------------ 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 ---- 0520 20 A1 06 ¡. JSR &06A1 Wait for a byte in R2 0523 A8 ¨ TAY Pass to Y as file handle 0524 20 A1 06 ¡. JSR &06A1 Wait for a byte in R2 0527 20 D4 FF Ô. JSR OSBPUT Write byte to file 052A 80 62 .b BRA &058E Send &7F ack byte via R2 and return to idle loop BGET ---- 052C 20 A1 06 ¡. JSR &06A1 Wait for a byte in R2 052F A8 ¨ TAY Pass to Y as file handle 0530 20 D7 FF ×. JSR OSBGET Fetch a byte from file 0533 80 03 .. BRA &0538 || Jump to send Carry and A RDCH ---- 0535 20 E0 FF à. JSR OSRDCH Wait for a character 0538 6A j ROR A Move carry to b7 0539 20 61 06 a. JSR &0661 Send via R2 053C 2A * ROL A Move A back 053D 80 51 .Q BRA &0590 Send via R2 and return to idle loop FIND ---- 053F 20 A1 06 ¡. JSR &06A1 Wait for a byte in R2 0542 F0 0A ð. BEQ &054E Zero - jump to do CLOSE 0544 48 H PHA Save OPEN action 0545 20 74 05 t. JSR &0574 Get a string via R2 0548 68 h PLA Get OPEN function back 0549 20 CE FF Î. JSR OSFIND Do the OPEN 054C 80 42 .B BRA &0590 Send handle via R2 and go to idle loop CLOSE ----- 054E 20 A1 06 ¡. JSR &06A1 Wait for a byte in R2 0551 A8 ¨ TAY Pass to Y as handle 0552 A9 00 ©. LDA #&00 Set A=0 for CLOSE 0554 20 CE FF Î. JSR OSFIND Do the CLOSE 0557 80 35 .5 BRA &058E Send &7F ack and jump to idle loop ARGS ---- 0559 20 A1 06 ¡. JSR &06A1 Wait for a byte in R2 055C A8 ¨ TAY Pass to Y as handle 055D A2 04 ¢. LDX #&04 Fetch four bytes for control block 055F 20 93 06 .. JSR &0693 || Wait for bytes in R2 and store in &00-&03 || Returns A=action 0562 20 DA FF Ú. JSR OSARGS Do the OSARGS action 0565 20 61 06 a. JSR &0661 Send A back via R2 0568 A2 03 ¢. LDX #&03 Send four bytes from control block 056A B5 00 µ. LDA &00,X Fetch from &03,&02,&01,&00 056C 20 61 06 a. JSR &0661 Send via R2 056F CA Ê DEX 0570 10 F8 .ø BPL &056A Loop for four bytes 0572 80 24 .$ BRA &0598 || Jump to Tube idle loop Read a string via R2 into string buffer at &0700 ------------------------------------------------ 0574 A2 00 ¢. LDX #&00 Set X to point to &xx00 0576 A0 00  . LDY #&00 0578 20 A1 06 ¡. JSR &06A1 Wait for a byte via R2 057B 99 00 07 ... STA &0700,Y Store in string buffer 057E C8 È INY Move to next byte 057F F0 04 ð. BEQ &0585 Buffer full, end loop 0581 C9 0D É. CMP #&0D Was last char ? 0583 D0 F3 Ðó BNE &0578 Loop until received 0585 A0 07  . LDY #&07 Return XY pointing to &0700 0587 60 ` RTS CLI --- 0588 20 74 05 t. JSR &0574 Read string to &0700 058B 20 F7 FF ÷. JSR OSCLI 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 ------------------------------------------------------------ 058E A9 7F ©. LDA #&7F Send &7F to CoPro Send byte in A via R2 and return to Tube idle loop -------------------------------------------------- 0590 2C E2 FE ,âþ BIT &FEE2 Check R2 status 0593 50 FB Pû BVC &0590 Loop until port free 0595 8D E3 FE .ãþ STA &FEE3 Send byte in A 0598 80 4E .N BRA &05E8 Jump to Tube idle loop GBPB ---- || Code moved 059A A2 0D ¢. LDX #&0D Loop for 13-byte control block 059C 20 93 06 .. JSR &0693 || Wait for bytes in R2 and store in &00-&0C || Returns A=action 059F A0 00  . LDY #&00 Set XY to point to &0000 05A1 20 D1 FF Ñ. JSR OSGBPB Do the OSGBPB call During the OSGBPB call the Tube system may be called to do a data transfer 05A4 48 H PHA Save the result 05A5 A2 0C ¢. LDX #&0C Loop for 13-byte control block 05A7 B5 00 µ. LDA &00,X Get byte from control block 05A9 20 61 06 a. JSR &0661 Send via R2 05AC CA Ê DEX 05AD 10 F8 .ø BPL &05A7 Loop to send high->low 05AF 68 h PLA Get result byte byte 05B0 80 86 .. BRA &0538 Jump to send Carry and A, then return to Tube idle loop FILE ---- 05B2 A2 10 ¢. LDX #&10 Loop for 16-byte control block 05B4 20 A1 06 ¡. JSR &06A1 Wait for a byte in R2 05B7 95 01 .. STA &01,X Store in control block 05B9 CA Ê DEX 05BA D0 F8 Ðø BNE &05B4 Loop to store high->low 05BC 20 74 05 t. JSR &0574 Read string to &0700 05BF 86 00 .. STX &00 Point control block to string 05C1 84 01 .. STY &01 05C3 A0 00  . LDY #&00 Point XY to &0000 05C5 20 A1 06 ¡. JSR &06A1 Wait for action byte via R2 05C8 20 DD FF Ý. JSR OSFILE Do the OSFILE call During the OSFILE call the Tube system may be called to do a data transfer 05CB 20 61 06 a. JSR &0661 Send result back via R2 05CE A2 10 ¢. LDX #&10 Send 16-byte control block back 05D0 B5 01 µ. LDA &01,X Get byte from control block 05D2 20 61 06 a. JSR &0661 Send via R2 05D5 CA Ê DEX 05D6 D0 F8 Ðø BNE &05D0 Loop to send high->low 05D8 80 0E .. BRA &05E8 | Jump to Tube idle loop BYTELO - OSBYTEs &00-&7F ------------------------ 05DA 20 9D 06 .. JSR &069D || Wait for a bytes in R2, read to X,A 05DD 20 F4 FF ô. JSR OSBYTE Do the OSBYTE call Send byte in X via R2 and jump to Tube idle loop ------------------------------------------------ 05E0 2C E2 FE ,âþ BIT &FEE2 Check R2 status 05E3 50 FB Pû BVC &05E0 Loop until port free 05E5 8E E3 FE .ãþ STX &FEE3 Send X via R2 05E8 4C 36 00 L6. JMP &0036 Return to Tube idle loop BYTEHI - OSBYTE &80-&FF ----------------------- 05EB 20 9D 06 .. JSR &069D || Wait for a bytes in R2, read to X,A 05EE A8 ¨ TAY Pass this to Y 05EF 20 A1 06 ¡. JSR &06A1 Wait for byte in R2 to use as A 05F2 20 F4 FF ô. 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. 05F5 49 9D I. EOR #&9D Was if OSBYTE &9D - Fast BPUT? 05F7 F0 EF ðï BEQ &05E8 If so, jump stright back to idle loop 05F9 6A j ROR A Move Carry into b7 of A 05FA 20 61 06 a. JSR &0661 Send via R2 Send bytes in Y, X via R2, then jump to Tube idle loop ------------------------------------------------------ 05FD 2C E2 FE ,âþ BIT &FEE2 Check R2 status 0600 50 FB Pû BVC &05FD Loop until port free 0602 8C E3 FE .ãþ STY &FEE3 Send byte in Y 0605 80 D9 .Ù BRA &05E0 Jump to send X and jump to idle loop WORD ---- 0607 20 A1 06 ¡. JSR &06A1 Wait for action byte in R2 060A A8 ¨ TAY Save in Y 060B 20 AA 06 ª. JSR &06AA || Get control block length to X from R2 060E 30 0A 0. BMI &061A || Skip if no bytes to read. Note: this || treats &81-&FF as zero as well 0610 20 A1 06 ¡. JSR &06A1 Wait for byte in R2 0613 9D 28 01 .(. STA &0128,X Store in control block 0616 CA Ê DEX 0617 10 F7 .÷ BPL &0610 Loop to read high->low 0619 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 call treats a control block length of &81-&FF as zero. The check at &0633 should really be something like TXA:BEQ zero_in:DEX 061A A2 28 ¢( LDX #&28 Point XY to control block at &0128 061C A0 01  . LDY #&01 061E 20 F1 FF ñ. JSR OSWORD Do the OSWORD call 0621 20 AA 06 ª. JSR &06AA || Get control block length to X from R2 0624 30 C2 0 BMI &05E8 || Skip if no bytes to return - again, || treating &81-&FF as zero as well 0626 BC 28 01 ¼(. LDY &0128,X Get byte from control block 0629 2C E2 FE ,âþ BIT &FEE2 Check R2 status 062C 50 FB Pû BVC &0629 Loop until port free 062E 8C E3 FE .ãþ STY &FEE3 Send byte to R2 0631 CA Ê DEX 0632 10 F2 .ò BPL &0626 Loop to send bytes high->low 0634 80 B2 .² BRA &05E8 Return to Tube idle loop WORD0 - Read a line ------------------- 0636 A2 04 ¢. LDX #&04 Fetch five bytes into control block 0638 20 A1 06 ¡. JSR &06A1 Wait for a byte via R2 063B 95 00 .. STA &00,X Store in control block 063D CA Ê DEX 063E 10 F8 .ø BPL &0638 Loop to get five bytes high->low 0640 E8 è INX Increment X back to &00 0641 8A . TXA || Set A=0 to read a line 0642 A8 ¨ TAY || Point XY to control block at &0000 0643 20 F1 FF ñ. 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. 0646 90 05 .. BCC &064D Jump if no Escape 0648 A9 FF ©. LDA #&FF Send &FF via R2 to indicate Escape 064A 4C 90 05 L.. JMP &0590 and return to Tube idle loop 064D A2 00 ¢. LDX #&00 Point to start of string buffer 064F A9 7F ©. LDA #&7F 0651 20 61 06 a. JSR &0661 Send &7F via R2 to indicate no Escape 0654 BD 00 07 ½.. LDA &0700,X Get byte from string buffer 0657 20 61 06 a. JSR &0661 Send byte via R2 065A E8 è INX Move to next byte 065B C9 0D É. CMP #&0D 065D D0 F5 Ðõ BNE &0654 Loop until sent 065F 80 D3 .Ó BRA &0634 Jump to Tube idle loop Send byte in A via R2 --------------------- 0661 2C E2 FE ,âþ BIT &FEE2 Check R2 status 0664 50 FB Pû BVC &0661 Loop until port free 0666 8D E3 FE .ãþ STA &FEE3 Send byte 0669 60 ` RTS Send Tube ID via R4 ------------------- 066A A5 15 ¥. LDA &15 || Get Tube ID Send byte in A via R4 --------------------- 066C 2C E6 FE ,æþ BIT &FEE6 Check R4 status 066F 50 FB Pû BVC &066C Loop until port free 0671 8D E7 FE .çþ STA &FEE7 Send byte 0674 60 ` RTS Copy Escape state across Tube ----------------------------- 0675 A5 FF ¥. LDA &FF Get Escape state 0677 38 8 SEC 0678 6A j ROR A Rotate escape to b6 and set b7 0679 80 0F .. BRA &068A Interupt client with byte send via R1 Send event across Tube ---------------------- 067B 48 H PHA Save A 067C A9 00 ©. LDA #&00 067E 20 8A 06 .. JSR &068A 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. 0681 98 . TYA 0682 20 8A 06 .. JSR &068A Send Y via R1 0685 8A . TXA 0686 20 8A 06 .. JSR &068A Send X via R1 0689 68 h PLA Get A back and send via R1 Send byte in A via R1 --------------------- 068A 2C E0 FE ,àþ BIT &FEE0 Check R1 status 068D 50 FB Pû BVC &068A Loop until port free 068F 8D E1 FE .áþ STA &FEE1 Send byte 0692 60 ` RTS 0693 20 A1 06 ¡. JSR &06A1 0696 95 FF .. STA &FF,X 0698 CA Ê DEX 0699 D0 F8 Ðø BNE &0693 069B 80 04 .. BRA &06A1 069D 20 A1 06 ¡. JSR &06A1 06A0 AA ª TAX Wait for data via R2 -------------------- 06A1 2C E2 FE ,âþ BIT &FEE2 Check R2 status 06A4 10 FB .û BPL &06A1 Loop until data present 06A6 AD E3 FE ­ãþ LDA &FEE3 Get byte 06A9 60 ` RTS Wait for control block length X via R2 -------------------------------------- 06AA 2C E2 FE ,âþ BIT &FEE2 || Check R2 status 06AD 10 FB .û BPL &06AA || Loop until data present 06AF AE E3 FE ®ãþ LDX &FEE3 || Get byte 06B2 CA Ê DEX || Decrement 06B3 60 ` RTS || Unused space ------------ 06B4-06FF String buffer ------------- 0700 EQUS 256 String buffer