; DISASSEMBLY OF TORCH CCCP 0.94 BDOS/BIOS ; CODE COPYRIGHT (C) TORCH COMPUTERS ; DISASSEMBLY COMMENTARY COPYRIGHT (C) J.G.HARSTON ; On startup, page &00 is initialised to the following: .RST00 ; RESET 0000 C3 CF FF ÃÏ. JP &FFCF ; RESET jumps to BIOS WBoot 0003 00 . DEFB &00 ; IOBYTE set to &00 0004 xx . DEFB &xx ; USER+DRIVE byte ; .BDOS ; CP/M BDOS Entry ; If no TORCHNET present, initialised as: 0005 C3 00 FA Ã.ú JP &FA00 ; Jump to Core BDOS entry point ; If TORCHNET is present, initialised as: 0005 C3 00 F8 Ã.ø JP &F800 ; Jump to Torchnet BDOS entry point ; .RomCopy: ; Copy data from rom to ram ; BC=Count, DE=Dest, HL=Source 0008 DB 02 Û. IN A,(&02) ; Page Rom in 000A ED B0 í° LDIR ; Copy from Rom to Ram 000C DB 06 Û. IN A,(&06) ; Page Rom out 000E C9 É RET ; ; Locations &000F to &002F uninitialised ; ; If no TORCHNET present, initialised as: 0030 C3 07 FA Ã.ú JP &FA07 ; Jump to Core BDOS RST entry ; If TORCHNET is present, initialised as: 0030 C3 07 F8 Ã.ø JP &F807 ; Jump to Torchnet BDOS RST entry ; 0033 xx ; unused 0034 xx ; unused .ADDR 0035 00 00 .. DEFW &0000 ; Address holder .COUNT 0037 xx ; Character output count .RST38 ; Debug entry point 0038 C9 É RET ; Just returns 0039 xx xx .. DEFW &xxxx ; Reserved for jump dest of RST &38 .DMA_ADDR 003B xx xx .. DEFW &xxxx ; DMA Address .SAVESP 003D xx xx .. DEFW &xxxx ; Save SP here within BDOS ; ; 003F ; ; Locations &003F to &005B unused, reserved ; ; DISASSEMBLY OF CCP v0.94 BIOS/BDOS ; COPIED INTO HIGH MEMORY FROM ROM ON COLD BOOT ; TorchNet BDOS Section of CP/N BDOS/BIOS Code ; ============================================ ; ; When TorchNet is present an extended BDOS is present at &F800 ; ; CALL &0005 BDOS Entry Point: ; C=function, DE=parameters F800 26 00 &. LD H,&0 ; Clear H F802 CD 38 F8 Í8ø CALL &F838 ; Call BDOS function handler F805 6F o LD L,A ; Put result in L F806 C9 É RET ; RST &30 BDOS Entry Point: ; inline byte=function, DE=parameters F807 E3 ã EX (SP),HL ; Get pointer to inline byte F808 7E ~ LD A,(HL) ; Get BDOS function byte F809 23 # INC HL ; Inc return address F80A E3 ã EX (SP),HL ; and put back on stack F80B C5 Å PUSH BC ; Preserved BC F80C 4F O LD C,A ; Put function byte into C F80D CD 38 F8 Í8ø CALL &F838 ; Call BDOS function handler F810 C1 Á POP BC ; Restore BC F811 C9 É RET ; and exit ; Torchnet BDOS Function Table ; F812 2F F9 /ù DEFW &F92F ; &6D F814 23 F9 #. DEFW &F923 ; &6E F816 1C F9 .. DEFW &F91C ; &6F F818 13 F9 .. DEFW &F913 ; &70 F81A 08 F9 .. DEFW &F908 ; &71 F81C 0E F9 .ù DEFW &F90E ; &72 F81E 34 F9 4. DEFW &F934 ; &73 F820 34 F9 4. DEFW &F934 ; &74 F822 E0 F8 à. DEFW &F8E0 ; &75 F824 D8 F8 Ø. DEFW &F8D8 ; &76 F826 B4 F8 ´. DEFW &F8B4 ; &77 F828 BA FF º. DEFW &FFBA ; &78 - CInstall F82A 9D F8 .. DEFW &F89D ; &79 F82C 86 F8 .. DEFW &F886 ; &7A F82E 34 F9 4. DEFW &F934 ; &7B F830 75 F8 u. DEFW &F875 ; &7C F832 6D F8 m. DEFW &F86D ; &7D F834 6D F8 m. DEFW &F86D ; &7E F836 5F F8 _. DEFW &F85F ; &7F ; BDOS Function Handler ; C=function DE=parameters ; F838 CD 65 FA Íeú CALL &FA65 ; Call Core BDOS call handler F83B D0 Ð RET NC ; Exit if handled (&00-&28) F83C 79 y LD A,C F83D CB 27 Ë' SLA A ; A=function*2 F83F DA 68 FA Úhú JP C,&FA68 ; if code=&80..&FF, exit with A=&00 F842 D6 DA ÖÚ SUB A,&DA ; adjust so 2*&6D -> 2*&00, etc. F844 DA 68 FA Úhú JP C,&FA68 ; if code<&6D, exit with A=&00 F847 ED 73 3D 00 ís=. LD (&003D),SP ; Save SP F84B 31 B4 FF 1´. LD SP,&FFB4 ; Point to internal temp'y stack F84E DD E5 Ýå PUSH IX ; Save registers F850 D5 Õ PUSH DE F851 C5 Å PUSH BC F852 E5 å PUSH HL F853 D5 Õ PUSH DE F854 DD E1 Ýá POP IX ; Get DE into IX F856 21 12 F8 !.ø LD HL,&F812 ; Point to address table F859 06 00 .. LD B,&00 F85B 4F O LD C,A ; BC=Function F85C C3 80 FA Ã.ú JP &FA80 ; Call the routine via core BDOS ; ; On entry to a BDOS routine, A=B=1st param, C=2nd param ; A =byte parameter (E on entry) ; BC=word parameter (DE on entry) ; DE=IX=address of any data block (DE on entry) ; HL=routine address ; BDOS &7F - F85F CD 3C F9 Í<ù CALL &F93C ; Send my Torchnet command (&00) F862 CD CD FE ÍÍþ CALL &FECD ; Wait for byte from Port B F865 6F o LD L,A ; Transfer to L F866 CD CD FE ÍÍþ CALL &FECD ; Wait for byte from Port B F869 67 g LD H,A ; Transfer to H F86A C3 97 FA Ã.ú JP &FA97 ; Return with HL=xxxx ; BDOS &7E - ; BDOS &7D - F86D CD 3C F9 Í<ù CALL &F93C ; Send my Torchnet command (&01/2) F870 06 06 .. LD B,&06 ; Send 6 bytes F872 C3 4E F9 ÃNù JP &F94E ; to Port B from addr in DE ; BDOS &7C - Send cmd, 6 bytes at DE; read 6 bytes to DE F875 CD 3C F9 Í<ù CALL &F93C ; Send my Torchnet command (&03) F878 06 06 .. LD B,&06 ; Send 6 bytes F87A CD 4E F9 ÍNù CALL &F94E ; to Port B from addr in DE F87D F5 õ PUSH AF ; Save AF F87E 06 06 .. LD B,&06 ; We want 6 bytes F880 EB ë EX DE,HL ; Put address in HL F881 CD 42 FE ÍBþ CALL &FE42 ; Read 6 bytes to address F884 F1 ñ POP AF ; Restore AF F885 C9 É RET ; BDOS &7A - Send cmd, 6 bytes; read data5, data0, data1 F886 CD 3C F9 Í<ù CALL &F93C ; Send my Torchnet command (&05) F889 06 06 .. LD B,&06 ; Send 6 bytes F88B CD 4E F9 ÍNù CALL &F94E ; to Port B from DE F88E F5 õ PUSH AF ; Save AF F88F CD CD FE ÍÍþ CALL &FECD ; Wait for ack from Port B F892 3C < INC A F893 28 01 (. JR Z,&F896 ; If A was &FF, make it &00 F895 3D = DEC A F896 DD 77 05 Ýw. LD (IX+&05),A ; Store it in byte 5 of data block F899 06 02 .. LD B,&02 ; Read 2 bytes to data block F89B 18 E3 .ã JR &F880 ; jump to read them ; BDOS &79 - Sends cmd, 66 bytes F89D CD 3C F9 Í<ù CALL &F93C ; Send my Torchnet command (&06) F8A0 06 42 .B LD B,&42 ; Send &42 bytes from addr F8A2 C3 4E F9 ÃNù JP &F94E ; at DE to port B ; BDOS &78, vectored via CInstall - Install SUB file ; Sends cmd; reads ack, if ack=0, reads &42 bytes to address ; On exit, A=0 - data block read (SUB FCB?), A<>0 - no data read F8A5 06 42 .B LD B,&42 ; ? F8A7 CD 3C F9 Í<ù CALL &F93C ; Send my TorchNet command (&07) F8AA CD CD FE ÍÍþ CALL &FECD ; Wait for byte from Tube port B F8AD C0 À RET NZ ; Return if <>0 F8AE EB ë EX DE,HL ; Transfer address to HL F8AF CD 42 FE ÍBþ CALL &FE42 ; Read &42 bytes to addr at HL F8B2 AF ¯ XOR A ; Clear A F8B3 C9 É RET ; BDOS &77 F8B4 CD 3C F9 Í<ù CALL &F93C ; Send my Torchnet command (&08) F8B7 06 1A .. LD B,&1A ; Send &1A bytes from address F8B9 CD 4E F9 ÍNù CALL &F94E ; at DE to Port B F8BC C0 À RET NZ ; Return if ack<>0 F8BD 23 # INC HL ; Point to 2nd byte after data F8BE 5E ^ LD E,(HL) F8BF 23 # INC HL ; Get 2nd/3rd byte after F8C0 56 V LD D,(HL) ; data into DE F8C1 DD 46 04 ÝF. LD B,(IX+&04) ; Get 4th data byte to B F8C4 DD 6E 05 Ýn. LD L,(IX+&05) ; Get 5th data byte to L F8C7 EB ë EX DE,HL ; Get ^^that address into HL F8C8 AF ¯ XOR A F8C9 B0 ° OR B ; Check number from data+4 F8CA C4 1F FE Ä.þ CALL NZ,&FE1F ; If some, send bytes to Port B F8CD 1C . INC E F8CE 1D . DEC E ; Is E zero? F8CF CA CD FE ÊÍþ JP Z,&FECD ; If so, wait for ack from Port B F8D2 23 # INC HL F8D3 CD 1F FE Í.þ CALL &FE1F ; send some more... F8D6 18 F6 .ö JR &F8CE ; BDOS &76 F8D8 CD 3C F9 Í<ù CALL &F93C ; Send my Torchnet command (&09) F8DB 06 0A .. LD B,&0A ; Send 10 bytes F8DD C3 4E F9 ÃNù JP &F94E ; from data to Port B ; BDOS &75 F8E0 CD 3C F9 Í<ù CALL &F93C F8E3 EB ë EX DE,HL F8E4 23 # INC HL F8E5 4E N LD C,(HL) F8E6 CD 4C FC ÍLü CALL &FC4C F8E9 C0 À RET NZ F8EA 06 18 .. LD B,&18 F8EC 23 # INC HL F8ED CD CD FE ÍÍþ CALL &FECD F8F0 77 w LD (HL),A F8F1 10 F9 .ù DJNZ &F8EC F8F3 DD 4E 04 ÝN. LD C,(IX+&04) F8F6 DD 46 05 ÝF. LD B,(IX+&05) F8F9 23 # INC HL F8FA 5E ^ LD E,(HL) F8FB 23 # INC HL F8FC 56 V LD D,(HL) F8FD CD CD FE ÍÍþ CALL &FECD F900 12 . LD (DE),A F901 13 . INC DE F902 AF ¯ XOR A F903 ED A1 í¡ CPI F905 E0 à RET PO F906 18 F5 .õ JR &F8FD ; BDOS &71 F908 21 00 00 !.. LD HL,&0000 F90B C3 97 FA Ã.ú JP &FA97 ; BDOS &72 F90E 21 00 FF !.. LD HL,&FF00 F911 18 F8 .ø JR &F90B ; BDOS &70 F913 CD 3C F9 Í<ù CALL &F93C F916 CD 12 FE Í.þ CALL &FE12 F919 C3 65 F8 Ãeø JP &F865 ; BDOS &6F F91C CD 3C F9 Í<ù CALL &F93C ; Send a command F91F 06 08 .. LD B,&08 F921 18 2B .+ JR &F94E ; BDOS &6E F923 CD 3C F9 Í<ù CALL &F93C ; F926 06 02 .. LD B,&02 F928 EB ë EX DE,HL F929 CD 1F FE Í.þ CALL &FE1F F92C C3 62 F8 Ãbø JP &F862 ; BDOS &6D F92F 06 0A .. LD B,&0A F931 C3 A7 F8 çø JP &F8A7 ; BDOS &73, BDOS &74, BDOS &7B - NULL F934 F1 ñ POP AF ; Restore registers F935 E1 á POP HL F936 C1 Á POP BC F937 AF ¯ XOR A ; Make A=&00 - no action F938 37 7 SCF ; Set Carry - no action F939 C3 8E FA Ã.ú JP &FA8E ; Jump to restore regs and exit ; Send 'Execute Torchnet Operation' to Tube F93C CD A2 FE Í¢þ CALL &FEA2 ; Send &1E to Tube port A F93F 1E . DEFB &1E ; Execute TorchNet Operation F940 21 06 00 !.. LD HL,&0006 ; HL=SP+6, =>4th stack entry. When F943 39 9 ADD HL,SP ; called from inside BDOS function F944 3E 7F >. LD A,&7F ; this is stacked BC, lo byte is C, F946 96 . SUB A,(HL) ; function number; A=&7F-function F947 C5 Å PUSH BC ; Save BC F948 4F O LD C,A ; Send &7F-function number F949 CD AC FE ͬþ CALL &FEAC ; ..to Tube port A F94C C1 Á POP BC ; Restore BC F94D C9 É RET ; Send B bytes to Port B from DE F94E 62 b LD H,D F94F 6B k LD L,E ; Copy address to HL F950 CD 1F FE Í.þ CALL &FE1F ; Send B bytes from HL to Port B F953 C3 CD FE ÃÍþ JP &FECD ; Wait for ack from Port B ; Core BDOS Section of CP/N BDOS/BIOS Code ; ======================================== ; ; When TorchNet not present an only core BDOS present at &FA00 ; ; ; BDOS Entry, C=function FA00 26 00 &. LD H,&00 ; Clear H FA02 CD 65 FA Íeú CALL &FA65 ; Call BDOS Function handler FA05 6F o LD L,A ; Transfer result to L FA06 C9 É RET ; and exit ; RST &30 inline BDOS call: FA07 E3 ã EX (SP),HL ; Get pointer to code FA08 7E ~ LD A,(HL) ; Get in-line byte FA09 23 # INC HL ; Increment return address FA0A E3 ã EX (SP),HL ; and restore it to stack FA0B C5 Å PUSH BC ; Save BC FA0C 4F O LD C,A ; Transfer function to C FA0D CD 65 FA Íeú CALL &FA65 ; Call BDOS function handler FA10 C1 Á POP BC ; Restore BC ; NULL jump point: FA11 C9 É RET ; and exit ; Core BDOS Function Table ; ------------------------ ; FA12 CF FF Ï. DEFW &FFCF ; &00 - SYSTEM BDOS / FA14 C7 FA Çú DEFW &FAC7 ; &01 - CONIN / FA16 CA FA Êú DEFW &FACA ; &02 - CONOUT / FA18 D5 FF Õ. DEFW &FFD5 ; &03 - AUXIN / FA1A D8 FF Ø. DEFW &FFD8 ; &04 - AUXOUT / FA1C DB FF Û. DEFW &FFDB ; &05 - LSTOUT / FA1E 3E FB >û DEFW &FB3E ; &06 - CONIO / FA20 4A FB Jû DEFW &FB4A ; &07 - AUXIST - GetIOBYTE / FA22 4E FB Nû DEFW &FB4E ; &08 - AUXOST - SetIOBYTE / FA24 52 FB Rû DEFW &FB52 ; &09 - PRNSTR / FA26 5C FB \û DEFW &FB5C ; &0A - RDCON / FA28 D2 FF Ò. DEFW &FFD2 ; &0B - GETCON / ?? FA2A 51 FC Qü DEFW &FC51 ; &0C - RDVERS / FA2C 57 FC Wü DEFW &FC57 ; &0D - DSKRESET / FA2E 68 FC hü DEFW &FC68 ; &0E - SELDSK / FA30 6F FC oü DEFW &FC6F ; &0F - OPEN / FA32 93 FC .ü DEFW &FC93 ; &10 - CLOSE / FA34 A1 FC ¡ü DEFW &FCA1 ; &11 - SRCHFST / FA36 B3 FC ³ü DEFW &FCB3 ; &12 - SRCHNXT / FA38 E0 FC àü DEFW &FCE0 ; &13 - DELETE / FA3A F1 FC ñü DEFW &FCF1 ; &14 - RDSEQ FA3C 04 FD .ý DEFW &FD04 ; &15 - WRSEQ FA3E 1A FD .ý DEFW &FD1A ; &16 - MAKE FA40 39 FD 9ý DEFW &FD39 ; &17 - RENAME FA42 4E FD Ný DEFW &FD4E ; &18 - LOGINV / FA44 5F FD _ý DEFW &FD5F ; &19 - RDDISK FA46 63 FD cý DEFW &FD63 ; &1A - SETDMA FA48 68 FD hý DEFW &FD68 ; &1B - GETALLOC FA4A 7F FD .ý DEFW &FD7F ; &1C - WRPROT FA4C 9C FD .ý DEFW &FD9C ; &1D - GETRO FA4E A1 FD ¡ý DEFW &FDA1 ; &1E - SETATTR FA50 A6 FD ¦ý DEFW &FDA6 ; &1F - GETPARM FA52 AC FD ¬ý DEFW &FDAC ; &20 - USER FA54 B9 FD ¹ý DEFW &FDB9 ; &21 - RDRANDOM FA56 C5 FD Åý DEFW &FDC5 ; &22 - WRRANDOM FA58 E7 FD çý DEFW &FDE7 ; &23 - FILESIZE FA5A 00 FE .þ DEFW &FE00 ; &24 - SETRANDOM FA5C 0E FE .þ DEFW &FE0E ; &25 - RESETDRV FA5E 11 FA .þ DEFW &FA11 ; &26 - FA60 11 FA .ú DEFW &FA11 ; &27 - FA62 C5 FD Åý DEFW &FDC5 ; &28 - WRZERO FA64 00 . DEFW &00 ; BDOS Function Handler ; C=in-line byte FA65 3E 28 >( LD A,&28 FA67 B9 ¹ CP C ; Is it one of our functions? FA68 3E 00 >. LD A,&00 FA6A D8 Ø RET C ; RET with A=&00 if C>&28 FA6B ED 73 3D 00 ís=. LD (&003D),SP ; Save SP FA6F 31 B4 FF 1´. LD SP,&FFB4 ; Point to internal temp'y stack FA72 DD E5 Ýå PUSH IX ; Save registers FA74 D5 Õ PUSH DE FA75 C5 Å PUSH BC FA76 E5 å PUSH HL FA77 D5 Õ PUSH DE FA78 DD E1 Ýá POP IX ; Get DE into IX FA7A 21 12 FA !.ú LD HL,&FA12 ; Point to entry table FA7D 06 00 .. LD B,&00 FA7F 09 . ADD HL,BC ; Index into table ; Enter here from Extended BDOS to call TorchNet function FA80 09 . ADD HL,BC ; HL=>table+2*code FA81 7E ~ LD A,(HL) ; Get low byte FA82 23 # INC HL FA83 66 f LD H,(HL) ; Get high byte FA84 6F o LD L,A ; HL=address FA85 42 B LD B,D ; B=1st param FA86 4B K LD C,E FA87 7B { LD A,E ; A=C=2nd param FA88 CD 96 FA Í.ú CALL &FA96 ; CALL (HL) FA8B E1 á POP HL ; Restore registers FA8C C1 Á POP BC ; FA8D B7 · OR A ; Set flags from A FA8E D1 Ñ POP DE FA8F DD E1 Ýá POP IX FA91 ED 7B 3D 00 í{=. LD SP,(&003D) ; Restore SP FA95 C9 É RET ; and return ; On entry to BDOS functions, registers contain: ; A =single parameter (E on entry) ... ; HL=routine address, B=1st param, C=A=2nd param, IX=DE=address parameter FA96 E9 é JP (HL) ; Jump to address in HL ; Routines jump to here to loose stacked retaddr, HL and BC and return FA97 F1 ñ POP AF ; Loose 3 stack entries FA98 F1 ñ POP AF FA99 F1 ñ POP AF FA9A 7D } LD A,L ; Copy HL to BA FA9B 44 D LD B,H FA9C 18 EF .ï JR &FA8D ; Restore regs and return ; WBoot returns here from .COM when WBoot dest has been altered: FA9E 2A 06 00 *.. LD HL,(&0006) ; Get TopOfTPA FAA1 25 % DEC H ; TopOfTPA-256 FAA2 E5 å PUSH HL ; Save for later FAA3 11 00 47 ..G LD DE,&4700 FAA6 B7 · OR A FAA7 ED 52 íR SBC HL,DE ; HL=TopOfTPA-&4800 FAA9 44 D LD B,H FAAA 4D M LD C,L ; BC=HL FAAB 05 . DEC B ; BC=TopOfTPA-&4900 FAAC 03 . INC BC ; BC=TopOfTPA-&48FF FAAD D1 Ñ POP DE ; DE=TopOfTPA-256 FAAE ED B8 í¸ LDDR ; Copy &0100->TopOfTPA-&4801 FAB0 21 B6 FA !¶ú LD HL,&FAB6 ; to &4800->TopOfTPA-257 FAB3 22 D0 FF "Ð. LD (&FFD0),HL ; Restore BIOS WBoot jump dest. ; and continue into WBoot ; BIOS WBoot: FAB6 AF ¯ XOR A FAB7 3D = DEC A ; Set flag for 'SoftRESET' FAB8 08 . EX AF,AF' FAB9 21 DB 02 !Û. LD HL,&02DB ; Put IN A,(&02) at &0000 to FABC 22 00 00 ".. LD (&0000),HL ; page Rom in, then continue FABF C3 00 00 Ã.. JP &0000 ; at Rom address &0002 ; BIOS CBoot: FAC2 CD A2 FE Í¢þ CALL &FEA2 ; Send &00 to Tube port A FAC5 00 . DEFB &00 FAC6 76 v HALT ; Wait to be reset ; BDOS &01 - CONIN - Wait for char, echo & return in A FAC7 CD D5 FF ÍÕ. CALL &FFD5 ; CALL JPBLK AUXIN ; ; BDOS &02 - CONOUT - Output char in A FACA E5 å PUSH HL FACB F5 õ PUSH AF ; Save character FACC E6 7F æ. AND &7F ; Loose b7 FACE CD D4 FA ÍÔú CALL &FAD4 ; Echo char and modify char count FAD1 F1 ñ POP AF ; Restore character FAD2 E1 á POP HL FAD3 C9 É RET ; Return with A=char FAD4 21 37 00 !7. LD HL,&0037 ; Point to line index FAD7 B7 · OR A FAD8 28 4B (K JR Z,&FB25 ; If 0, send to AUXOUT FADA FE 7F þ. CP &7F FADC 28 13 (. JR Z,&FAF1 ; If DEL, jump to dec count FADE FE 20 þ CP &20 FAE0 38 03 8. JR C,&FAE5 ; Jump with CTRL chars FAE2 34 4 INC (HL) ; Inc char count FAE3 18 40 .@ JR &FB25 ; Echo character and return FAE5 FE 07 þ. CP &07 FAE7 28 3C (< JR Z,&FB25 ; BEL - echo & ret FAE9 38 2B 8+ JR C,&FB16 ; LD A,&20 FAF9 CD 25 FB Í%û CALL &FB25 FAFC 34 4 INC (HL) FAFD 7E ~ LD A,(HL) FAFE E6 07 æ. AND &07 FB00 20 F5 õ JR NZ,&FAF7 FB02 F1 ñ POP AF FB03 C9 É RET FB04 FE 0A þ. CP &0A FB06 28 1D (. JR Z,&FB25 FB08 FE 1B þ. CP &1B FB0A 28 19 (. JR Z,&FB25 FB0C FE 0D þ. CP &0D FB0E 20 06 . JR NZ,&FB16 FB10 36 00 6. LD (HL),&00 FB12 CD 25 FB Í%û CALL &FB25 FB15 C9 É RET FB16 F5 õ PUSH AF FB17 3E 5E >^ LD A,&5E FB19 CD CA FA ÍÊú CALL &FACA FB1C F1 ñ POP AF FB1D F5 õ PUSH AF FB1E F6 40 ö@ OR &40 FB20 CD CA FA ÍÊú CALL &FACA FB23 F1 ñ POP AF FB24 C9 É RET FB25 F5 õ PUSH AF FB26 C5 Å PUSH BC FB27 E6 7F æ. AND &7F ; loose b7 FB29 4F O LD C,A FB2A CD D8 FF ÍØ. CALL &FFD8 ; Write character to AUXOUT FB2D C1 Á POP BC FB2E F1 ñ POP AF FB2F C9 É RET ; JPBLK AUXOUT: FB30 CD A2 FE Í¢þ CALL &FEA2 ; Send &15 to Tube port A FB33 15 . DEFB &15 FB34 C3 AC FE ìþ JP &FEAC ; Send C to Tube port A ; JPBLK LSTOUT: FB37 CD A2 FE Í¢þ CALL &FEA2 ; Send &01 to Tube port A FB3A 01 . DEFB &01 FB3B C3 AC FE ìþ JP &FEAC ; Send C to Tube port A ; BDOS &06 - CONIO FB3E 1C . INC E FB3F C2 D8 FF ÂØ. JP NZ,&FFD8 ; If E on entry <>1, jump to FB42 CD D2 FF ÍÒ. CALL &FFD2 ; ConStat - key pending? FB45 B7 · OR A FB46 C8 È RET Z ; Return if 0 FB47 C3 D5 FF ÃÕ. JP &FFD5 ; Jump to GetKey to fetch it ; BDOS &07 - AUXIST - GetIOBYTE FB4A 3A 03 00 :.. LD A,(&0003) FB4D C9 É RET ; BDOS &08 - AUXOST - SetIOBYTE FB4E 32 03 00 2.. LD (&0003),A FB51 C9 É RET ; BDOS &09 - PRNTSTRG FB52 1A . LD A,(DE) ; Get character FB53 FE 24 þ$ CP &24 ; Terminator? FB55 C8 È RET Z ; Exit if so FB56 CD CA FA ÍÊú CALL &FACA ; Send to CONOUT FB59 13 . INC DE ; Point to next char FB5A 18 F6 .ö JR &FB52 ; Loop to do it ; BDOS &0A - RDCON FB5C 62 b LD H,D FB5D 6B k LD L,E ; Pass pointer to HL FB5E 23 # INC HL FB5F 06 FF .. LD B,&FF FB61 3A 37 00 :7. LD A,(&0037) ; Get COUNT FB64 4F O LD C,A FB65 23 # INC HL FB66 04 . INC B FB67 1A . LD A,(DE) FB68 90 . SUB A,B FB69 28 43 (C JR Z,&FBAE FB6B CD D5 FF ÍÕ. CALL &FFD5 ; AUXIN - Get a char FB6E E6 7F æ. AND &7F ; Lose b7 FB70 28 F9 (ù JR Z,&FB6B ; Loop until not &00 FB72 77 w LD (HL),A ; Put into buffer FB73 FE 7F þ. CP &7F FB75 28 04 (. JR Z,&FB7B ; Deal with DEL FB77 FE 08 þ. CP &08 FB79 20 31 1 JR NZ,&FBAC ; Not BS FB7B 78 x LD A,B ; DEL & BS: FB7C B7 · OR A FB7D 28 E8 (è JR Z,&FB67 FB7F 05 . DEC B FB80 C5 Å PUSH BC FB81 62 b LD H,D FB82 6B k LD L,E FB83 23 # INC HL FB84 04 . INC B FB85 05 . DEC B FB86 28 14 (. JR Z,&FB9C FB88 23 # INC HL FB89 7E ~ LD A,(HL) FB8A 0C . INC C FB8B FE 20 þ CP &20 FB8D 30 F6 0ö JR NC,&FB85 FB8F 0C . INC C FB90 FE 09 þ. CP &09 FB92 20 F1 ñ JR NZ,&FB85 FB94 79 y LD A,C FB95 C6 06 Æ. ADD A,&06 FB97 E6 F8 æø AND &F8 FB99 4F O LD C,A FB9A 18 E9 .é JR &FB85 FB9C 3A 37 00 :7. LD A,(&0037) FB9F 91 . SUB A,C FBA0 47 G LD B,A FBA1 3E 7F >. LD A,&7F FBA3 CD CA FA ÍÊú CALL &FACA FBA6 10 FB .û DJNZ &FBA3 FBA8 C1 Á POP BC FBA9 23 # INC HL FBAA 18 BB .» JR &FB67 FBAC FE 0D þ. CP &0D FBAE 28 71 (q JR Z,&FC21 FBB0 FE 0A þ. CP &0A FBB2 28 6D (m JR Z,&FC21 FBB4 FE 10 þ. CP &10 FBB6 20 06 . JR NZ,&FBBE FBB8 CD 9E FE Í.þ CALL &FE9E FBBB 10 18 .. DJNZ &FBD5 FBBD A9 © XOR C FBBE FE 12 þ. CP &12 FBC0 20 16 . JR NZ,&FBD8 FBC2 CD 2A FC Í*ü CALL &FC2A FBC5 78 x LD A,B FBC6 B7 · OR A FBC7 28 9E (. JR Z,&FB67 FBC9 C5 Å PUSH BC FBCA 62 b LD H,D FBCB 6B k LD L,E FBCC 23 # INC HL FBCD 23 # INC HL FBCE 7E ~ LD A,(HL) FBCF CD CA FA ÍÊú CALL &FACA FBD2 10 F9 .ù DJNZ &FBCD FBD4 C1 Á POP BC FBD5 23 # INC HL FBD6 18 8F .. JR &FB67 FBD8 FE 15 þ. CP &15 FBDA 20 06 . JR NZ,&FBE2 FBDC CD 2A FC Í*ü CALL &FC2A FBDF C3 5C FB Ã\û JP &FB5C FBE2 FE 18 þ. CP &18 FBE4 20 10 . JR NZ,&FBF6 FBE6 3A 37 00 :7. LD A,(&0037) FBE9 91 . SUB A,C FBEA 28 EA (ê JR Z,&FBD6 FBEC 47 G LD B,A FBED 3E 7F >. LD A,&7F FBEF CD CA FA ÍÊú CALL &FACA FBF2 10 FB .û DJNZ &FBEF FBF4 18 E9 .é JR &FBDF FBF6 FE 05 þ. CP &05 FBF8 20 05 . JR NZ,&FBFF FBFA CD 40 FC Í@ü CALL &FC40 FBFD 18 D7 .× JR &FBD6 FBFF FE 03 þ. CP &03 FC01 20 0B . JR NZ,&FC0E FC03 CD CA FA ÍÊú CALL &FACA FC06 04 . INC B FC07 05 . DEC B FC08 CA C2 FA ÊÂú JP Z,&FAC2 FC0B C3 65 FB Ãeû JP &FB65 FC0E FE 07 þ. CP &07 FC10 28 09 (. JR Z,&FC1B FC12 FE 1B þ. CP &1B FC14 28 05 (. JR Z,&FC1B FC16 CD CA FA ÍÊú CALL &FACA FC19 18 F0 .ð JR &FC0B FC1B CD 16 FB Í.û CALL &FB16 FC1E C3 65 FB Ãeû JP &FB65 FC21 3E 0D >. LD A,&0D FC23 CD CA FA ÍÊú CALL &FACA FC26 78 x LD A,B FC27 13 . INC DE FC28 12 . LD (DE),A FC29 C9 É RET FC2A 3E 23 ># LD A,&23 FC2C CD CA FA ÍÊú CALL &FACA FC2F CD 40 FC Í@ü CALL &FC40 FC32 79 y LD A,C FC33 B7 · OR A FC34 C8 È RET Z FC35 C5 Å PUSH BC FC36 3E 20 > LD A,&20 FC38 CD CA FA ÍÊú CALL &FACA FC3B 0D . DEC C FC3C 20 FA ú JR NZ,&FC38 FC3E C1 Á POP BC FC3F C9 É RET FC40 3E 0D >. LD A,&0D FC42 CD CA FA ÍÊú CALL &FACA FC45 3E 0A >. LD A,&0A FC47 C3 CA FA ÃÊú JP &FACA ; CCCPCS - 'Reserved' - Gets keyboard status... FC4A 0E 16 .. LD C,&16 ; Get keyboard status. ; Send command in C to Port A, get response from Tube Port B FC4C CD AC FE ͬþ CALL &FEAC ; Send command, then wait FC4F 18 4D .M JR &FC9E ; for response from Tube port B ; BDOS &0C - RDVERS FC51 21 22 00 !". LD HL,&0022 ; Return version as 'CPM 2.2' FC54 C3 97 FA Ã.ú JP &FA97 ; BDOS &0D - RESET DISK SYSTEM FC57 AF ¯ XOR A FC58 21 80 00 !.. LD HL,&0080 FC5B 22 3B 00 ";. LD (&003B),HL ; Set DMA to &0080 FC5E 6F o LD L,A ; Clear L FC5F 22 35 00 "5. LD (&0035),HL ; Set Address to &0000 FC62 CD 9E FE Í.þ CALL &FE9E ; Send &0F, &00 to Tube FC65 09 . ADD HL,BC FC66 AF ¯ XOR A FC67 C9 É RET ; BDOS &0E - SETDRV - Set DRIVE from C, sets USER to 0 FC68 3E 0F >. LD A,&0F ; Mask off top nybble FC6A A1 ¡ AND C FC6B 32 04 00 2.. LD (&0004),A ; Store in DRIVE FC6E C9 É RET ; BDOS &0F - OPEN FC6F CD A2 FE Í¢þ CALL &FEA2 ; Send &1A to Tube port A FC72 1A . DEFB &1A FC73 CD 81 FE Í.þ CALL &FE81 FC76 CD 1A FE Í.þ CALL &FE1A FC79 DD 4E 0C ÝN. LD C,(IX+&0C) FC7C CD 4C FC ÍLü CALL &FC4C ; Send C to Port B, wait for reply FC7F C0 À RET NZ FC80 CD CD FE ÍÍþ CALL &FECD FC83 DD 77 0D Ýw. LD (IX+&0D),A FC86 EB ë EX DE,HL FC87 23 # INC HL FC88 06 0B .. LD B,&0B FC8A CD CA FC ÍÊü CALL &FCCA FC8D DD 77 0E Ýw. LD (IX+&0E),A FC90 C3 D2 FD ÃÒý JP &FDD2 ; BDOS &10 - CLOSE FC93 0E 03 .. LD C,&03 FC95 CD AC FE ͬþ CALL &FEAC ; Send &03 to Tube port A FC98 CD 81 FE Í.þ CALL &FE81 FC9B CD 1A FE Í.þ CALL &FE1A FC9E C3 CD FE ÃÍþ JP &FECD ; Wait for ack from Tube port B ; BDOS &11 - SCANFST FCA1 CD A2 FE Í¢þ CALL &FEA2 ; Send &18 to Tube port A FCA4 18 . DEFB &18 FCA5 CD 81 FE ..þ CALL &FE81 FCA8 CD 1A FE ..þ CALL &FE1A FCAC DD 4E 0C .N. LD C,(IX+&0C) FCAE CD AC FE ͬþ CALL &FEAC FCB1 18 04 .. JR &FCB7 ; BDOS &12 - SCANNXT FCB3 CD A2 FE Í¢þ CALL &FEA2 ; Send &19 to Tube port A FCB6 19 . DEFB &19 FCB7 06 20 . LD B,&20 FCB9 2A 3B 00 *;. LD HL,(&003B) FCBC AF ¯ XOR A FCBD 77 w LD (HL),A FCBE 23 # INC HL FCBF 10 FC .ü DJNZ &FCBD FCC1 CD CD FE ÍÍþ CALL &FECD FCC4 C0 À RET NZ FCC5 2A 3B 00 *;. LD HL,(&003B) FCC8 06 0C .. LD B,&0C FCCA CD CD FE ÍÍþ CALL &FECD FCCD 77 w LD (HL),A FCCE 23 # INC HL FCCF 10 F9 .ù DJNZ &FCCA FCD1 CD CD FE ÍÍþ CALL &FECD FCD4 77 w LD (HL),A FCD5 23 # INC HL FCD6 23 # INC HL FCD7 23 # INC HL FCD8 CD CD FE ÍÍþ CALL &FECD FCDB 77 w LD (HL),A FCDC 23 # INC HL FCDD 77 w LD (HL),A FCDE AF ¯ XOR A FCDF C9 É RET ; BDOS &13 - DELETE FCE0 CD 86 FE Í.þ CALL &FE86 FCE3 30 03 0. JR NC,&FCE8 FCE5 AF ¯ XOR A FCE6 3D = DEC A FCE7 C9 É RET FCE8 CD A2 FE Í¢þ CALL &FEA2 FCEB 06 CD .Í LD B,&CD FCED AC ¬ XOR H FCEE FE 18 þ. CP &18 FCF0 AA ª XOR D FCF1 CD A2 FE Í¢þ CALL &FEA2 FCF4 07 . RLCA FCF5 CD 6C FE Ílþ CALL &FE6C FCF8 CD 3D FE Í=þ CALL &FE3D FCFB CD D7 FE Í×þ CALL &FED7 FCFE DD 34 20 Ý4 INC (IX+&20) FD01 C3 D2 FD ÃÒý JP &FDD2 FD04 CD 2B FE Í+þ CALL &FE2B FD07 CD A2 FE Í¢þ CALL &FEA2 FD0A 08 . EX AF,AF' FD0B CD 6C FE Ílþ CALL &FE6C FD0E CD 4F FE ÍOþ CALL &FE4F FD11 DD 34 20 Ý4 INC (IX+&20) FD14 CD D7 FE Í×þ CALL &FED7 FD17 C3 D2 FD ÃÒý JP &FDD2 FD1A CD 2B FE Í+þ CALL &FE2B FD1D CD A2 FE Í¢þ CALL &FEA2 FD20 1D . DEC E FD21 CD AC FE ͬþ CALL &FEAC FD24 CD 1A FE Í.þ CALL &FE1A FD27 DD 4E 0C ÝN. LD C,(IX+&0C) FD2A CD 4C FC ÍLü CALL &FC4C ; Send C to Port B, wait for reply FD2D F8 ø RET M FD2E CD CD FE ÍÍþ CALL &FECD FD31 DD 77 0D Ýw. LD (IX+&0D),A FD34 AF ¯ XOR A FD35 DD 77 0F Ýw. LD (IX+&0F),A FD38 C9 É RET FD39 CD A2 FE Í¢þ CALL &FEA2 FD3C 0A . LD A,(BC) FD3D CD 81 FE Í.þ CALL &FE81 FD40 CD 1A FE Í.þ CALL &FE1A FD43 CD A2 FE Í¢þ CALL &FEA2 FD46 00 . NOP FD47 11 05 00 ... LD DE,&0005 FD4A 19 . ADD HL,DE FD4B EB ë EX DE,HL FD4C 18 A1 .¡ JR &FCEF ; BDOS &18 - LOGINVECTOR FD4E CD A2 FE Í¢þ CALL &FEA2 ; Send &1B to Tube port A FD51 1B . DEFB &1B FD52 CD CD FE ÍÍþ CALL &FECD ; Get low byte from Tube port B FD55 6F o LD L,A FD56 CD CD FE ÍÍþ CALL &FECD ; Get high byte from Tube port B FD59 67 g LD H,A FD5A 22 33 00 "3. LD (&0033),HL ; Store in word store FD5D 18 4A .J JR &FDA9 FD5F 3A 04 00 :.. LD A,(&0004) ; Get DRIVE FD62 C9 É RET ; SetDMA - Set DMA Address at &003B from BC FD63 ED 43 3B 00 íC;. LD (&003B),BC ; Set DMA_ADDR FD67 C9 É RET ; Get fake allocation map to workspace area FD68 CD 9E FE Í.þ CALL &FE9E ; Send &0F, &14 to Tube port A FD6B 14 . DEFB &14 ; Get fake allocation map FD6C 3A 04 00 :.. LD A,(&0004) ; Get current DRIVE FD6F 4F O LD C,A FD70 CD AC FE ͬþ CALL &FEAC ; Send to Tube port A FD73 06 20 . LD B,&20 FD75 21 59 FF !Y. LD HL,&FF59 ; HL=>workspace area to hold map FD78 E5 å PUSH HL ; Read &20 bytes to workspace area FD79 CD 42 FE ÍBþ CALL &FE42 ; from Tube port B FD7C E1 á POP HL ; Get pointer to workspace area FD7D 18 2A .* JR &FDA9 ; JPs to &FA97 ; Sets the bit in HL corresponding to the current drive FD7F 3A 04 00 :.. LD A,(&0004) ; Get current drive FD82 47 G LD B,A ; Put into B FD83 04 . INC B ; B=number of bits into HL FD84 21 00 00 !.. LD HL,&0000 ; Clear HL FD87 37 7 SCF FD88 CB 15 Ë. RL L ; Move a set bit into HL FD8A CB 14 Ë. RL H FD8C 10 FA .ú DJNZ &FD88 ; Loop until bit is in place FD8E ED 4B 35 00 íK5. LD BC,(&0035) ; Get an address FD92 79 y LD A,C ; OR the bit into (&0035) FD93 B5 µ OR L FD94 6F o LD L,A FD95 78 x LD A,B FD96 B4 ´ OR H FD97 67 g LD H,A ; HL=HL OR (&0035) FD98 22 35 00 "5. LD (&0035),HL ; Store it (RO vector?) FD9B C9 É RET ; FD9C 2A 35 00 *5. LD HL,(&0035) ; Get RO vector? FD9F 18 08 .. JR &FDA9 ; FDA1 0E 0B .. LD C,&0B FDA3 C3 95 FC Ã.ü JP &FC95 ; Get pointer to Disk Parameter Buffer FDA6 21 4A FF !J. LD HL,&FF4A ; HL=>Fake DPB FDA9 C3 97 FA Ã.ú JP &FA97 ; Get/Set User Number FDAC 4B K LD C,E ; Put parameter in C for later FDAD CD A2 FE Í¢þ CALL &FEA2 ; Send &10 to Tube port A FDB0 10 . DEFB &10 ; Get/Set User Number FDB1 CD AC FE ... CALL &FEAC ; Send parameter to Tube port A FDB4 1C . INC E FDB5 C0 À RET NZ ; Return if E was not &FF, ie SET FDB6 C3 CD FE ÃÍþ JP &FECD ; Jump to get data from Tube port B ; FDB9 CD A2 FE Í¢þ CALL &FEA2 ; Send &07 to Tube port A FDBC 07 . DEFB &07 ; Read Record FDBD CD 56 FE ÍVþ CALL &FE56 FDC0 CD 3D FE Í=þ CALL &FE3D ; Read 1 record from port B to DMA FDC3 18 0D .. JR &FDD2 FDC5 CD 2B FE Í+þ CALL &FE2B FDC8 CD A2 FE Í¢þ CALL &FEA2 ; Send &08 to Tube port A FDCB 08 . DEFB &08 ; Write Record FDCC CD 56 FE ÍVþ CALL &FE56 FDCF CD 4F FE ÍOþ CALL &FE4F ; Write 1 record from DMA to port A ; FDD2 CD A2 FE Í¢þ CALL &FEA2 ; Send &17 to Tube port A FDD5 17 . DEFB &17 ; Get Extent Size FDD6 DD 4E 0D ÝN. LD C,(IX+&0D) ; Get h1 to C (exHi) FDD9 CD AC FE ͬþ CALL &FEAC ; Send to Tube port A FDDC DD 4E 0C ÝN. LD C,(IX+&0C) ; Get ex to C FDDF CD 4C FC ÍLü CALL &FC4C ; Send C to Port B, wait for reply FDE2 DD 77 0F Ýw. LD (IX+&0F),A ; Store in rc FDE5 AF ¯ XOR A ; A=0 -> Ok FDE6 C9 É RET ; FDE7 0E 0C .. LD C,&0C FDE9 CD 95 FC Í.ü CALL &FC95 FDEC DD 77 23 Ýw# LD (IX+&23),A ; Set r2 FDEF F8 ø RET M ; Exit if b7 set FDF0 CD CD FE ÍÍþ CALL &FECD ; Get data from Tube port B FDF3 6F o LD L,A ; Put into L - low byte FDF4 CD CD FE ÍÍþ CALL &FECD ; Get data from Tube port B FDF7 67 g LD H,A ; Put into H - high byte FDF8 DD 75 21 Ýu! LD (IX+&21),L ; Put HL into r0,r1 FDFB DD 74 22 Ýt" LD (IX+&22),H ; FCB record count FDFE AF ¯ XOR A ; A=0 -> Ok FDFF C9 É RET ; FE00 CD D7 FE Í×þ CALL &FED7 FE03 DD 75 21 Ýu! LD (IX+&21),L ; Put HL into FCB record count FE06 DD 74 22 Ýt" LD (IX+&22),H ; r0 and r1 FE09 AF ¯ XOR A FE0A DD 77 23 Ýw# LD (IX+&23),A ; Make r2=0, and A=0 ->Ok FE0D C9 É RET ; FE0E CD 9E FE Í.þ CALL &FE9E ; Send &0F, &13 to Tube port A FE11 13 . DEFB &13 ; ??? FE12 4B K LD C,E FE13 CD AC FE ͬþ CALL &FEAC ; Send to Tube port A FE16 4A J LD C,D FE17 C3 4C FC ÃLü JP &FC4C ; Send C to Port B, wait for reply ; Send 11 bytes from DE+1 to DE+12 to Tube port A FE1A 62 b LD H,D FE1B 6B k LD L,E ; Pass DE to HL FE1C 06 0B .. LD B,&0B ; 11 bytes to send FE1E 23 # INC HL ; Point to start at DE+1 ; Send B bytes from memory at (HL) to Tube port A FE1F 4E N LD C,(HL) ; Get byte from memory FE20 DB 06 Û. IN A,(&06) ; Read Tube status from port C FE22 17 . RLA ; Check b7 - OUTRDY FE23 30 FB 0û JR NC,&FE20 ; Loop until output ok FE25 79 y LD A,C FE26 D3 04 Ó. OUT (&04),A ; Send to Tube port A FE28 10 F4 .ô DJNZ &FE1E ; Loop back for total specified FE2A C9 É RET ; FE2B CD 86 FE Í.þ CALL &FE86 ; Get current or specified drive? FE2E 41 A LD B,C FE2F 04 . INC B FE30 2A 35 00 *5. LD HL,(&0035) ; Get RO vector? FE33 CB 1C Ë. RR H FE35 CB 1D Ë. RR L FE37 10 FA .ú DJNZ &FE33 ; Move HL down until drive bit in Cy FE39 D0 Ð RET NC ; Ret if not RO FE3A E3 ã EX (SP),HL ; Put HL onto stack, swapping with FE3B E1 á POP HL ; return address; loose ret address FE3C C9 É RET ; Return to caller's caller ; FE3D 2A 3B 00 *;. LD HL,(&003B) ; HL=DMA Address FE40 06 80 .. LD B,&80 ; B=128 bytes, 1 record ; Read B bytes to memory at HL from Tube port B FE42 DB 06 Û. IN A,(&06) ; Read Tube status from port C FE44 CB 4F ËO BIT 1,A ; Check INRDY FE46 28 FA (ú JR Z,&FE42 ; Loop until data present FE48 DB 05 Û. IN A,(&05) ; Get data from port B FE4A 77 w LD (HL),A ; Store in memory FE4B 23 # INC HL ; Update pointer FE4C 10 F4 .ô DJNZ &FE42 ; Loop for total specified FE4E C9 É RET FE4F 2A 3B 00 *;. LD HL,(&003B) ; HL=DMA Address FE52 06 80 .. LD B,&80 ; B=128 bytes, 1 record FE54 18 C9 .É JR &FE1F ; Jump to send to Tube port A ; FE56 DD 4E 0D ÝN. LD C,(IX+&0D) ; Get h1 FE59 CD AC FE ͬþ CALL &FEAC ; Send to Tube port A FE5C DD 4E 21 ÝN! LD C,(IX+&21) ; Get r0 FE5F 69 i LD L,C ; Put into L for later FE60 CD AC FE ͬþ CALL &FEAC ; Send to Tube port A FE63 DD 4E 22 ÝN" LD C,(IX+&22) ; Get r1 FE66 61 a LD H,C ; Put into H for later FE67 CD E7 FE Íçþ CALL &FEE7 ... FE6A 18 0E .. JR &FE7A ; Jump to ; FE6C DD 4E 0D ÝN. LD C,(IX+&0D) ; Get h1 FE6F CD AC FE ͬþ CALL &FEAC ; Send to Tube port A FE72 CD D7 FE Í×þ CALL &FED7 ; ... FE75 4D M LD C,L ; Get low byte of ... FE76 CD AC FE ͬþ CALL &FEAC ; Send to Tube port A FE79 4C L LD C,H ; Get high byte of ... ; FE7A CD 4C FC ÍLü CALL &FC4C ; Send C to Port B, wait for reply FE7D C8 È RET Z FE7E 33 3 INC SP ; Loose a return address FE7F 33 3 INC SP FE80 C9 É RET ; Return to caller's caller ; FE81 CD 86 FE Í.þ CALL &FE86 FE84 18 26 .& JR &FEAC FE86 1A . LD A,(DE) FE87 FE 3F þ? CP &3F FE89 20 08 . JR NZ,&FE93 FE8B 3A 04 00 :.. LD A,(&0004) FE8E C6 80 Æ. ADD A,&80 FE90 4F O LD C,A FE91 37 7 SCF FE92 C9 É RET FE93 A7 § AND A FE94 20 04 . JR NZ,&FE9A FE96 3A 04 00 :.. LD A,(&0004) FE99 3C < INC A FE9A 3D = DEC A FE9B A7 § AND A FE9C 4F O LD C,A FE9D C9 É RET ; Tube Communication Routines ; --------------------------- ; Send command &0F then inline byte to Tube port A FE9E CD A2 FE Í¢þ CALL &FEA2 ; Prefix in-line byte with &0F FEA1 0F . DEFB &0F ; ; Send inline byte to Tube port A FEA2 E3 ã EX (SP),HL ; Get in-line address FEA3 C5 Å PUSH BC ; Save BC FEA4 4E N LD C,(HL) ; Get in-line byte FEA5 CD AC FE ͬþ CALL &FEAC ; Send to Tube FEA8 C1 Á POP BC ; Restore BC FEA9 23 # INC HL ; Update return address FEAA E3 ã EX (SP),HL FEAB C9 É RET ; Return ; Send byte in C to Tube port A FEAC DB 06 Û. IN A,(&06) ; Read Tube status through port C FEAE 17 . RLA ; Check b7 - OUTRDY FEAF 30 FB 0û JR NC,&FEAC ; Loop until output ready FEB1 79 y LD A,C FEB2 D3 04 Ó. OUT (&04),A ; Send data to port A FEB4 C9 É RET ; JPBLK AUXIN: ; Sends &11, ignores replies until <>0, then gets a reply byte FEB5 C5 Å PUSH BC FEB6 0E 11 .. LD C,&11 ; Send &11 to port A and FEB8 CD 4C FC ÍLü CALL &FC4C ; get byte from port B FEBB 28 FB (û JR Z,&FEB8 ; Loop until returned byte<>0 FEBD C1 Á POP BC FEBE 18 0D .. JR &FECD ; Get another byte from port B ; Check Tube status - Returns Cy=OUTRDY, Z=INRDY FEC0 DB 06 Û. IN A,(&06) ; Read Tube status through port C FEC2 E6 82 æ. AND &82 ; Check b7 & b1 - OUTRDY & INRDY FEC4 CB 07 Ë. RLC A ; Move OUTRDY to Cy FEC6 CB 57 ËW BIT 2,A ; Check INRDY FEC8 C9 É RET ; Send command &0F, &11 and wait for reply FEC9 CD 9E FE Í.þ CALL &FE9E ; Send &0F, &11 to Tube port A FECC 11 . DEFB &11 ; and wait for reply ; Get data from Tube port B FECD DB 06 Û. IN A,(&06) ; Read Tube status through port C FECF CB 4F ËO BIT 1,A ; Check b1 - INRDY FED1 28 FA (ú JR Z,&FECD ; Loop until data present FED3 DB 05 Û. IN A,(&05) ; Read data from port B FED5 A7 § AND A ; Set flags from data FED6 C9 É RET ; Miscellaneous bits... ; --------------------- ; Get ex&rc to HL FED7 D5 Õ PUSH DE ; Save DE FED8 DD 66 0C Ýf. LD H,(IX+&0C) ; h=ex FEDB AF ¯ XOR A FEDC 6F o LD L,A ; hl=ex*256 FEDD CB 1C Ë. RR H FEDF CB 1D Ë. RR L ; hl=ex*128 FEE1 57 W LD D,A FEE2 DD 5E 20 Ý^ LD E,(IX+&20) ; de=cr FEE5 19 . ADD HL,DE ; hl=ex*128+cr FEE6 D1 Ñ POP DE ; Restore DE ; ; Set ex&rc from HL FEE7 E5 å PUSH HL ; Save HL FEE8 7D } LD A,L FEE9 E6 7F æ. AND &7F ; A=cr portion of HL FEEB DD 77 20 Ýw LD (IX+&20),A ; Set cr from A FEEE 29 ) ADD HL,HL ; Move ex up to H FEEF DD 74 0C Ýt. LD (IX+&0C),H ; Set ex from H FEF2 E1 á POP HL ; Restore HL FEF3 C9 É RET ; something... ; ------------ ; LdFile - Load & Execute COM file ; BC=>FCB of file to be run FEF4 C5 Å PUSH BC FEF5 E1 á POP HL ; Pass BC to HL FEF6 11 59 FF .Y. LD DE,&FF59 ; FEF9 D5 Õ PUSH DE ; Copy &10 bytes of FCB to &FF59 FEFA 01 10 00 ... LD BC,&0010 FEFD ED B0 í° LDIR FEFF D1 Ñ POP DE ; Point to FCB copy FF00 97 . SUB A,A ; Clear A FF01 32 79 FF 2y. LD (&FF79),A ; Clear CR FF04 32 65 FF 2e. LD (&FF65),A ; Clear EX FF07 F7 ÷ RST &30 ; BDOS Function &0F FF08 0F . DEFB &0F ; Open file FF09 F2 0D FF ò.. JP P,&FF0D ; If P, file found, copy high mem to TPA start FF0C C9 É RET ; Not found, exit with M ; file found - copy everything higher than CCP on top of CCP FF0D ED 7B 06 00 í{.. LD SP,(&0006) ; Put stack at top of TPA FF11 D5 Õ PUSH DE ; Save DE, pointer to FCB copy FF12 2A 06 00 *.. LD HL,(&0006) ; Get TopOfTPA FF15 11 00 48 ..H LD DE,&4800 FF18 B7 · OR A FF19 ED 52 íR SBC HL,DE ; HL=TopOfTPA-&4800 FF1B 44 D LD B,H FF1C 4D M LD C,L FF1D 21 00 48 !.H LD HL,&4800 FF20 11 00 01 ... LD DE,&0100 ; Copy &4800->TOP FF23 ED B0 í° LDIR ; to &0100->(TOP-&4700) FF25 D1 Ñ POP DE ; Restore DE, pointer to FCB copy FF26 21 80 00 !.. LD HL,&0080 ; Set up HL for loading loop ; loop for each record FF29 01 80 00 ... LD BC,&0080 FF2C 09 . ADD HL,BC ; HL=&0100 FF2D EB ë EX DE,HL ; Get address in DE FF2E F7 ÷ RST &30 ; BDOS Function &1A FF2F 1A . DEFB &1A ; Set DMA address to DE FF30 EB ë EX DE,HL ; Get =>FCB back in DE FF31 F7 ÷ RST &30 ; BDOS Function &14 FF32 14 . DEFB &14 ; Read next record to DMA FF33 28 F4 (ô JR Z,&FF29 ; Loop until EOF ; FF35 11 80 00 ... LD DE,&0080 ; FF38 F7 ÷ RST &30 ; BDOS Function &1A FF39 1A . DEFB &1A ; SetDMA address back to &0080 FF3A 31 7D FF 1}. LD SP,&FF7D ; Set up internal COM stack FF3D 21 9E FA !.ú LD HL,&FA9E ; Change BIOS WBoot destination FF40 22 D0 FF "Ð. LD (&FFD0),HL ; to &FA9E FF43 21 00 00 !.. LD HL,&0000 FF46 E5 å PUSH HL ; Push return address of &0000 FF47 C3 00 01 Ã.. JP &0100 ; Enter program at &0100 ; Fake DPB: FF4A 01 00 07 ... LD BC,&0700 FF4D 7F . LD A,A FF4E 0F . RRCA FF4F FF . RST &38 FF50 00 . NOP FF51 FF . RST &38 FF52 00 . NOP FF53 80 . ADD A,B FF54 00 . NOP FF55 40 @ LD B,B FF56 00 . NOP FF57 00 . NOP FF58 00 . NOP ; FCB for loading .COM programs ; File field FF59 xx . DEFS 1 ; dr FF5A xx xx xx xx xx xx xx xx DEFS 8 ; f1,f2,f3,f4,f5,f6,f7,f8 FF62 xx xx xx DEFS 3 ; t1,t2,t3 FF65 xx DEFS 1 ; ex FF66 xx xx DEFS 2 ; h1,h2 FF68 xx DEFS 1 ; rc ; Allocation table (CP/N uses these as User field u0 to uF) FF69 xx xx xx xx xx xx xx xx DEFS 8 ; a0,a1,a2,a3,a4,a5,a6,a7 FF71 xx xx xx xx xx xx xx xx DEFS 8 ; a8,a9,aA,aB,aC,aD,aE,aF ; FF79 xx DEFS 1 ; cr FF7A xx xx xx DEFS 3 ; r0,r1,r2 ; Top of internal COM stack at &FF7C over internal FCB down to &FF59 ; Can hold a maximum of 18 entries .COMSTACK FF7D DEFS &FFB4-P% ; Fill to next code ; Top of internal BDOS stack at &FFB3 down to &FF7D or &FF59 ; Can hold a maximum of 27.5 entries to &FF7D or 45.5 entries down to &FF59 .BDOSSTACK ; Tube Control Vector ; ------------------- FFB4 C3 4A FC ÃJü JP &FC4A ; CCCPCS - Checks keyboard status FFB7 C3 C0 FE ÃÀþ JP &FEC0 ; TubeStat - Get Tube status to Cy+Z FFBA C3 A5 F8 Ã¥ø JP &F8A5 ; CInstall - Called from BDOS &76 (?) FFBD C3 F4 FE Ãôþ JP &FEF4 ; LdFile - Loads & enters COM program FFC0 C3 9E FE Ã.þ JP &FE9E ; UsrImm - Send &0F then inline to Port A FFC3 C3 A2 FE âþ JP &FEA2 ; PutImm - Send inline to Port A FFC6 C3 CD FE ÃÍþ JP &FECD ; GetByte - Get byte from Port B FFC9 C3 AC FE ìþ JP &FEAC ; PutByte - Send C to Port A ; BIOS Section of CP/N BDOS/BIOS Code ; =================================== ; BIOS Vector: FFCC C3 C2 FA ÃÂú JP &FAC2 ; CBoot - Waits for RESET from host FFCF C3 B6 FA öú JP &FAB6 ; WBoot - Pages Rom RESET code in FFD2 C3 4A FC ÃJü JP &FC4A ; ConStat - CONSTAT FFD5 C3 B5 FE õþ JP &FEB5 ; GetKey - AUXIN FFD8 C3 30 FB Ã0û JP &FB30 ; PutCh - AUXOUT FFDB C3 37 FB Ã7û JP &FB37 ; ListCh - LSTOUT FFDE C3 D8 FF ÃØ. JP &FFD8 ; Punch - (AUXOUT) FFE1 C3 D5 FF ÃÕ. JP &FFD5 ; Reader - (AUXIN) FFE4 C3 11 FA Ã.ú JP &FA11 ; Home - NULL FFE7 C3 68 FC Ãhü JP &FC68 ; SelDsk - DRIVE=C, USER=0 FFEA C3 11 FA Ã.ú JP &FA11 ; SetTrk - NULL FFED C3 11 FA Ã.ú JP &FA11 ; SetSec - NULL FFF0 C3 63 FD Ãcý JP &FD63 ; SetDMA - (&3B)=BC FFF3 C3 11 FA Ã.ú JP &FA11 ; ReadDsk - NULL FFF6 C3 11 FA Ã.ú JP &FA11 ; WriteDsk - NULL FFF9 C3 C9 FE ÃÉþ JP &FEC9 ; ListStat - Send &0F, &11 to Port A; get reply from B FFFC C3 11 FA Ã.ú JP &FA11 ; SecTran - NULL FFFF 09 . EQUB &09 ; GetVersion I/O Map: &00 - Page Rom in, Port A Data I/O &01 - Page Rom in, Port B Data I/O &02 - Page Rom in, Port C Data I/O &03 - Page Rom in, READ(82c55): Control WRITE: Control 8255 Operates in mode 0 from startup: Basic I/O, All ports input IN &02 - Dummy read, pages Rom in OUT &04 - Write to Port A - Tube Data A IN &05 - Read from Port B - Tube Data B IN &06 - Read from Port C - Tube Status b7----b1- - OUTRDY---INRDY- also pages Rom out