OS SERIES 9GEOFF COX**************************************************************************                                                                       **       OSBYTE 140  *TAPE                                               **       selects TAPE filing system                                      **                                                                       **       OSBYTE 141  *ROM                                                **       selects ROM filing system                                       **                                                                       **************************************************************************F135	EOR #&8C    ;if it's *TAPE A=0 *ROM A=1F137	ASL         ;double itF138	STA &0247   ;store it in filing system flag storeF13B	CPX #&03    ;if X>=3 C set X=3 Z setF13D	JMP &F14B   ;******** set cassette options *******************************************    	;called after BREAK etc    	;lower nybble sets sequential access    	;upper sets load and save options    	    	;0000   Ignore errors,          no messages    	;0001   Abort if error,         no messages    	;0010   Retry after error,      no messages    	;1000   Ignore error            short messages    	;1001   Abort if error          short messages    	;1010   Retry after error       short messages    	;1100   Ignore error            long messages    	;1101   Abort if error          long messages    	;1110   Retry after error       long messagesF140	PHP         ;save flagsF141	LDA #&A1    ;set sequential access abort if error, no messagesF143	STA &E3     ;set load/save retry if error, short messagesF145	LDA #&19    ;set interblock gapF147	STA &03D1   ;and store itF14A	PLP         ;get back flagsF14B	PHP         ;push flagsF14C	LDA #&06    ;get close files command to FSCVF14E	JSR &E031   ;and gosub OSFSCF151	LDX #&06    ;F153	PLP         ;get back flagsF154	BEQ &F157   ;if Z set earlierF156	DEX         ;do not decrement XF157	STX &C6     ;set current baud rate X=5 300 baud X=6 1200 baud********* reset FILEV,ARGSV,BGETV,BPUTV,GBPBV,FINDV,FSCV ****************************   to F27D, F18E, F4C9, F529, FFA6, F3CA, F1B1 ******************F159	LDX #&0E    ;RESET VECTORS FOR FILE RELATED OPERATIONSF15B	LDA &D951,X ;F15E	STA &0211,X ;F161	DEX         ;F162	BNE &F15B   ;F164	STX &C2     ;&C2=0 PROGRESS FLAGF166	LDX #&0F    ;set X to make Rom service call &F claim vectors!**************************************************************************                                                                       **       OSBYTE 143                                                      **       Pass service commands to sideways Roms                          **                                                                       **************************************************************************    	    ;on entry X=command numberF168	LDA &F4     ;get current Rom numberF16A	PHA         ;store itF16B	TXA         ;command in AF16C	LDX #&0F    ;set X=15    	            ;send commands loopF16E	INC &02A1,X ;read bit 7 on rom map (no rom has type 254 &FE)F171	DEC &02A1,X ;F174	BPL &F183   ;if not set (+ve result)F176	STX &F4     ;else store rom number in &F4F178	STX &FE30   ;switch in paged ROMF17B	JSR &8003   ;and jump tp service entryF17E	TAX         ;on exit put A in XF17F	BEQ &F186   ;if 0 (command recognised by ROM) reset roms & exitF181	LDX &F4     ;else point to next lower romF183	DEX         ;F184	BPL &F16E   ;and go round loop againF186	PLA         ;get back original Rom numberF187	STA &F4     ;store it in Ram copyF189	STA &FE30   ;select original pageF18C	TXA         ;put X back in AF18D	RTS         ;and return**************************************************************************                                                                       **       CFS OSARGS entry point                                          ***************************************************************************F18E	ORA #&00    ;is A=00F190	BNE &F1A2   ;if not returnF192	CPY #&00    ;is Y=0F194	BNE &F1A2   ;if not returnF196	LDA &C6     ;else get current baud rate and zero bit 2F198	AND #&FB    ;C6=5 becomes 1, 6 becomes 2F19A	ORA &0247   ;if cassette selected A=0 else A=2F19D	ASL         ;multiply by 2F19E	ORA &0247   ;Or it againF1A1	LSR         ;divide by 2F1A2	RTS         ;return cassette =0    	**************************************************************************                                                                       **       FSC     VECTOR  TABLE                                           **                                                                       **************************************************************************F1A3	DB  4C,F5   ; *OPT            (F54C)F1A5	DB  1D,F6   ; check EOF       (F61D)F1A7	DB  04,F3   ; */              (F304)F1A9	DB  0F,E3   ; unknown command (E30F)F1AB	DB  04,F3   ; *RUN            (F304)F1AD	DB  2A,F3   ; *CAT            (F32A)F1AF	DB  74,E2   ; osbyte 77       (E274)**************************************************************************       Filing System control entry     OSFSC                           **       Entry via 021E FSCV                                             **       A= index 0 to 7                                                 **************************************************************************    	;on entry A is reason code    	;A=0    A *OPT command has been used X & Y are the 2 parameters    	;A=1    EOF is being checked, on entry  X=File handle    	                          on Exit X=FF = EOF exists else 00    	;A=2    A */ command has been used *RUN the file    	;A=3    An unrecognised OS command has ben used X,Y point at command    	;A=4    A *RUN command has been used X,Y point at filename    	;A=5    A *CAT cammand has been issued X,Y point to rest of command    	;A=6    New filing system about to take over, close SPOOL & EXEC files    	;A=7    Return in X and Y lowest and highest file handle used    	;A=8    OS about to process *commandF1B1	CMP #&07    ;if A>6F1B3	BCS &F1A2   ;goto F1A2 (RTS)F1B5	STX &BC     ;else save XF1B7	ASL         ;A=A*2F1B8	TAX         ;X=A to get offsetF1B9	LDA &F1A4,X ;get hi byte of addressF1BC	PHA         ;push itF1BD	LDA &F1A3,X ;get lo byte of addressF1C0	PHA         ;push itF1C1	LDX &BC     ;get back XF1C3	RTS         ;this now jumps to the address got from the table +1    	            ;the next RTS takes us back to CLI**************************************************************************                                                                       **       LOAD FILE                                                       **                                                                       **************************************************************************    	F1C4	PHP         ;save flags on stackF1C5	PHA         ;save A on stackF1C6	JSR &FB27   ;Set cassette optionsinto (BB),set C7=6    	            ;claim serial system for cassetteF1C9	LDA &03C2   ;execution address LOF1CC	PHA         ;save A on stackF1CD	JSR &F631   ;search for fileF1D0	PLA         ;get back AF1D1	BEQ &F1ED   ;if A=0 F1EDF1D3	LDX #&03    ;else X=3F1D5	LDA #&FF    ;A=&FFF1D7	PHA         ;save A on stackF1D8	LDA &03BE,X ;get load addressF1DB	STA &B0,X   ;store it as current load addressF1DD	PLA         ;get back AF1DE	AND &B0,X   ;F1E0	DEX         ;X=X-1F1E1	BPL &F1D7   ;until all 4 bytes copiedF1E3	CMP #&FF    ;if all bytes contain don't contain &FFF1E5	BNE &F1ED   ;continueF1E7	JSR &FAE8   ;else sound bell, reset ACIA & motor offF1EA	JMP &E267   ;'Bad Address' errorF1ED	LDA &03CA   ;block flagF1F0	LSR         ;set carry from bit 0F1F1	PLA         ;get back AF1F2	BEQ &F202   ;if A=0 F202F1F4	BCC &F209   ;if carry clear F209*************** LOCKED FILE ROUTINE *************************************F1F6	JSR &FAF2   ;enable second processor and reset serial systemF1F9	BRK         ;F1FA	DB  &E5     ;error numberF1FC	'Locked'        ;F201	BRK         ;F202	BCC &F209   ;if carry clear F209F204	LDA #&03    ;else A=3F206	STA &0258   ;store to cause ESCAPE disable and memory    	            ;clear on breakF209	LDA #&30    ;F20B	AND &BB     ;current OPTionsF20D	BEQ &F213   ;if options and #&30 =0 ignore error condition is setF20F	LDA &C1     ;else get checksum resultF211	BNE &F21D   ;and if not 0 F21DF213	TYA         ;A=YF214	PHA         ;save A on stackF215	JSR &FBBB   ;read from second processor if presentF218	PLA         ;get back AF219	TAY         ;Y=AF21A	JSR &F7D5   ;reset flags and check block lengthF21D	JSR &F9B4   ;load file from tapeF220	BNE &F255   ;if not found return to searchF222	JSR &FB69   ;increment current block numberF225	BIT &03CA   ;block flagF228	BMI &F232   ;if bit 7=1 then this is last block so F232F22A	JSR &F96A   ;else increment current load addressF22D	JSR &F77B   ;read block headerF230	BNE &F209   ;and goto F209******** store data in OSFILE parameter block ***************************F232	LDY #&0A    ;Y=&0AF234	LDA &CC     ;file length counter loF236	STA (&C8),Y ;OSFILE parameter  blockF238	INY         ;Y=Y+1F239	LDA &CD     ;file length counter hiF23B	STA (&C8),Y ;OSFILE parameter  blockF23D	LDA #&00    ;A=0F23F	INY         ;Y=Y+1F240	STA (&C8),Y ;OSFILE parameter  blockF242	INY         ;Y=Y+1F243	STA (&C8),Y ;OSFILE parameter  blockF245	PLP         ;get back flagsF246	JSR &FAE8   ;bell, reset ACIA & motorF249	BIT &BA     ;current block flagF24B	BMI &F254   ;returnF24D	PHP         ;save flags on stackF24E	JSR &FA46   ; print message following call (in this case NEWLINE!)F251	DB  &0D,&00 ;messageF254	RTS         ;return    	;************RETRY AFTER A FAILURE ROUTINE *******************************F255	JSR &F637   ;search for a specified blockF258	BNE &F209   ;goto F209*********** Read Filename using Command Line Interpreter ****************;filename pointed to by X and YF25A	STX &F2     ;OS filename/command line pointer loF25C	STY &F3     ;OS filename/command line pointerF25E	LDY #&00    ;Y=0F260	JSR &EA1D   ;initialise stringF263	LDX #&00    ;X=0F265	JSR &EA2F   ;GSREAD callF268	BCS &F277   ;if end of character string F277F26A	BEQ &F274   ;if 0 found F274F26C	STA &03D2,X ;else store character in CFS filename areaF26F	INX         ;X=X+1F270	CPX #&0B    ;if X<>11F272	BNE &F265   ;then read nextF274	JMP &EA8F   ;else Bad String error************* terminate Filename ****************************************F277	LDA #&00    ;terminate filename with 0F279	STA &03D2,X ;F27C	RTS         ;return**************************************************************************                                                                       **       OSFILE ENTRY                                                    **                                                                       **       on entry A determines action                                    **       A=0     save block of memory as a file                          **       A=1     write catalogue info for existing file                  **       A=2     write load address only for existing file               **       A=3     write execution address only for existing file          **       A=4     write attributes only for existing file                 **       A=5     Read catalogue info, return file type in A              **       A=6     Delete named file                                       **       A=&FF   load the named file if lo byte of Exec address=0 use    **               address in parameter block else files own load address  **       X,Y     point to parameter block                                **       bytes   0,1 filename address, 2-5 load,6-9 exec,A-D length or   **               start of data for save, 0E End address /attributes      **************************************************************************;parameter block located by XY;0/1	Address of Filename terminated by &0D;2/4	Load Address of File;6/9	Execution Address of File;A/D	Start address of data for write operations or length of file;   	for read operations;E/11   End address of Data; i.e. byte AFTER last byte to be written;   	or file attributes;;On Entry action is determined by value in A;;A=0	Save section of memory as named file, write catalogue information;A=1	Write catalogue information for named file;A=2	Write the LOAD       address (only) for the named File;A=3	Write the EXECUTION  address (only) for the named File;A=4	Write the ATTRIBUTES for the named File;A=5	Read the named files catalogue information Place file type in A;A=6	Delete the named file;A=&FF  Load the named file and read its catalogue informationF27D	PHA         ;save A on stackF27E	STX &C8     ;osfile block pointer loF280	STY &C9     ;osfile block pointer hiF282	LDY #&00    ;Y=0F284	LDA (&C8),Y ;OSFILE parameter  blockF286	TAX         ;X=AF287	INY         ;Y=Y+1F288	LDA (&C8),Y ;OSFILE parameter  blockF28A	TAY         ;Y=AF28B	JSR &F25A   ;get filename from BUFFERF28E	LDY #&02    ;Y=2F290	LDA (&C8),Y ;copy parameters to Cassette block at 3BE/C5F292	STA &03BC,Y ;from LOAD and EXEC addressF295	STA &00AE,Y ;make second copy at B0-B8F298	INY         ;Y=Y+1F299	CPY #&0A    ;until Y=10F29B	BNE &F290   ;F29D	PLA         ;get back AF29E	BEQ &F2A7   ;if A=0 F2A7F2A0	CMP #&FF    ;else if A<>&FFF2A2	BNE &F254   ;RETURN as cassette has no other optionsF2A4	JMP &F1C4   ;load file************** Save a file **********************************************F2A7	STA &03C6   ;zero block numberF2AA	STA &03C7   ;zero block number hiF2AD	LDA (&C8),Y ;OSFILE parameter  blockF2AF	STA &00A6,Y ;store to Zero page copy (&B0 to &B7)F2B2	INY         ;data start and data end addressF2B3	CPY #&12    ;until Y=18F2B5	BNE &F2AD   ;F2B7	TXA         ;A=XF2B8	BEQ &F274   ;if X=0 no filename found so B274 else BAD STRING errorF2BA	JSR &FB27   ;Set cassette option sinto (BB),set C7=6    	            ;claim serial system for cassetteF2BD	JSR &F934   ;prompt to start recordingF2C0	LDA #&00    ;A=0F2C2	JSR &FBBD   ;enable 2nd proc. if present and set up osfile blockF2C5	JSR &FBE2   ;set up CFS for write operationF2C8	SEC         ;set carry flagF2C9	LDX #&FD    ;X=&FDF2CB	LDA &FFB7,X ;set 03C8/A block length and block flagF2CE	SBC &FFB3,X ;to B4/6-B0/2 the number of pages (blocks) to be    	            ;savedF2D1	STA &02CB,X ;F2D4	INX         ;X=X+1F2D5	BNE &F2CB   ;F2D7	TAY         ;Y=AF2D8	BNE &F2E8   ;if last byte is non zero F2E8 elseF2DA	CPX &03C8   ;compare X with block lengthF2DD	LDA #&01    ;A=1F2DF	SBC &03C9   ;subtract block length hiF2E2	BCC &F2E8   ;if carry clear F2E8F2E4	LDX #&80    ;X=&80F2E6	BNE &F2F0   ;jump F2F0F2E8	LDA #&01    ;A=1F2EA	STA &03C9   ;block length hiF2ED	STX &03C8   ;block lengthF2F0	STX &03CA   ;block flagF2F3	JSR &F7EC   ;write block to TapeF2F6	BMI &F341   ;return if negativeF2F8	JSR &F96A   ;increment current load addressF2FB	INC &03C6   ;block numberF2FE	BNE &F2C8   ;if not 0 loop back again elseF300	INC &03C7   ;block number hiF303	BNE &F2C8   ;and loop back again**************************************************************************                                                                       **       *RUN    ENTRY                                                   **                                                                       **************************************************************************F305	JSR &F25A   ;get filename from BUFFERF308	LDX #&FF    ;X=&FFF30A	STX &03C2   ;execution addressF30D	JSR &F1C4   ;load fileF310	BIT &027A   ;&FF if tube presentF313	BPL &F31F   ;so if not present F31F elseF315	LDA &03C4   ;execution address extendF318	AND &03C5   ;execution address extendF31B	CMP #&FF    ;if they are NOT both &FF i.e.for base processorF31D	BNE &F322   ;F322 elseF31F	JMP (&03C2) ; RUN fileF322	LDX #&C2    ;point to execution addressF324	LDY #&03    ;(&03C2)F326	LDA #&04    ;Tube call 4F328	JMP &FBC7   ;and issue to Tube to run file**************************************************************************                                                                       **       *CAT    ENTRY                                                   **                                                                       **************************************************************************    	;CASSETTE OPTIONS in &E2    	;bit 0  input file open    	;bit 1  output file open    	;bit 2,4,5  not used    	;bit 3  current CATalogue status    	;bit 6  EOF reached    	;bit 7  EOF warning givenF32B	LDA #&08    ;A=8F32D	JSR &F344   ;set status bits from AF330	JSR &FB27   ;Set cassette options into (BB),set C7=6    	            ;claim serial system for cassetteF333	LDA #&00    ;A=0F335	JSR &F348   ;read data from CFS/RFSF338	JSR &FAFC   ;perform readF33B	LDA #&F7    ;A=&F7F33D	AND &E2     ;clear bit 3 of CFS status bitF33F	STA &E2     ;F341	RTS         ;return    	;F342	LDA #&40    ;set bit 6 of E2 cassette optionsF344	ORA &E2     ;F346	BNE &F33F   ;and Jump F33F********** search routine ***********************************************F348	PHA         ;save A on stackF349	LDA &0247   ;filing system flag 0=CFS 2=RFSF34C	BEQ &F359   ;if CFS F359 elseF34E	JSR &EE13   ;set current Filing System ROM/PHROMF351	JSR &EE18   ;get byte from data Romcheck typeF354	BCC &F359   ;if carry clear F359 elseF356	CLV         ;clear overflow flagF357	BVC &F39A   ;JUMP F39A*********** cassette routine********************************************F359	JSR &F77B   ;read block headerF35C	LDA &03C6   ;block numberF35F	STA &B4     ;current block no. loF361	LDA &03C7   ;block number hiF364	STA &B5     ;current block no. hiF366	LDX #&FF    ;X=&FFF368	STX &03DF   ;copy of last read block flagF36B	INX         ;X=X+1F36C	STX &BA     ;current block flagF36E	BEQ &F376   ;if  0 F376F370	JSR &FB69   ;inc. current block no.F373	JSR &F77B   ;read block headerF376	LDA &0247   ;get filing system flag 0=CFS 2=RFSF379	BEQ &F37D   ;if CFS F37DF37B	BVC &F39A   ;if V clear F39AF37D	PLA         ;get back AF37E	PHA         ;save A on stackF37F	BEQ &F3AE   ;if A=0 F3AEF381	JSR &FA72   ;else check filename header block matches searched FnF384	BNE &F39C   ;if so F39CF386	LDA #&30    ;else A=30 to clear all but bits 4/5 of current OPTions