OS SERIES VGEOFF COX**************************************************************************                                                                       **       Check SPEECH System                                             **                                                                       **************************************************************************    	            ;X=&10DB11	BIT &FE40   ;if bit 7 low then we have speech system fittedDB14	BMI &DB27   ;else goto DB27DB16	DEC &027B   ;(027B)=&FF to indicate speech presentDB19	LDY #&FF    ;Y=&FFDB1B	JSR &EE7F   ;initialise speech generatorDB1E	DEX         ;via thisDB1F	BNE &DB19   ;loop    	            ;X=0DB21	STX &FE48   ;set T2 timer for speechDB24	STX &FE49   ;*********** SCREEN SET UP **********************************************    	            ;X=0DB27	LDA &028F   ;get back start up options (mode)DB2A	JSR &C300   ;then jump to screen initialisationDB2D	LDY #&CA    ;Y=&CADB2F	JSR &E4F1   ;to enter this in keyboard buffer    	            ;this enables the *KEY 10 facility********* enter BREAK intercept with Carry Clear ************************DB32	JSR &EAD9   ;check to see if BOOT address is set up, if so    	            ;JMP to itDB35	JSR &F140   ;set up cassette optionsDB38	LDA #&81    ;test for tube to FIFO buffer 1DB3A	STA &FEE0   ;DB3D	LDA &FEE0   ;DB40	ROR         ;put bit 0 into carryDB41	BCC &DB4D   ;if no tube then DB4DDB43	LDX #&FF    ;elseDB45	JSR &F168   ;issue ROM service call &FF    	            ;to initialise TUBE systemDB48	BNE &DB4D   ;if not 0 on exit (Tube not initialised) DB4DDB4A	DEC &027A   ;else set tube flag to show it's activeDB4D	LDY #&0E    ;set current value of PAGEDB4F	LDX #&01    ;issue claim absolute workspace callDB51	JSR &F168   ;via F168DB54	LDX #&02    ;send private workspace claim callDB56	JSR &F168   ;via F168DB59	STY &0243   ;set primary OSHWMDB5C	STY &0244   ;set current OSHWMDB5F	LDX #&FE    ;issue call for Tube to explode character set etc.DB61	LDY &027A   ;Y=FF if tube present else Y=0DB64	JSR &F168   ;and make call via F168DB67	AND &0267   ;if A=&FE and bit 7 of 0267 is set then continueDB6A	BPL &DB87   ;else ignore start up messageDB6C	LDY #&02    ;output to screenDB6E	JSR &DEA9   ;'BBC Computer ' messageDB71	LDA &028D   ;0=warm reset, anything else continueDB74	BEQ &DB82   ;DB76	LDY #&16    ;by checking length of RAMDB78	BIT &028E   ;DB7B	BMI &DB7F   ;and eitherDB7D	LDY #&11    ;DB7F	JSR &DEA9   ;finishing message with '16k' or '32k'DB82	LDY #&1B    ;and two newlinesDB84	JSR &DEA9   ;*********: enter BREAK INTERCEPT ROUTINE WITH CARRY SET (call 1)DB87	SEC         ;DB88	JSR &EAD9   ;look for break intercept jump do *TV etcDB8B	JSR &E9D9   ;set up LEDs in accordance with keyboard statusDB8E	PHP         ;save flagsDB8F	PLA         ;and get back in ADB90	LSR         ;zero bits 4-7 and bits 0-2 bit 4 which was bit 7DB91	LSR         ;may be setDB92	LSR         ;DB93	LSR         ;DB94	EOR &028F   ;eor with start-up options which may or may notDB97	AND #&08    ;invert bit 4DB99	TAY         ;Y=ADB9A	LDX #&03    ;make fs initialisation call, passing boot option in YDB9C	JSR &F168   ;Eg, RUN, EXEC or LOAD !BOOT fileDB9F	BEQ &DBBE   ;if a ROM accepts this call then DBBEDBA1	TYA         ;else put Y in ADBA2	BNE &DBB8   ;if Y<>0 DBB8DBA4	LDA #&8D    ;else set up standard cassete baud ratesDBA6	JSR &F135   ;via &F135DBA9	LDX #&D2    ;DBAB	LDY #&EA    ;DBAD	DEC &0267   ;decrement ignore start up message flagDBB0	JSR OSCLI   ;and execute */!BOOTDBB3	INC &0267   ;restore start up message flagDBB6	BNE &DBBE   ;if not zero then DBBEDBB8	LDA #&00    ;else A=0DBBA	TAX         ;X=0DBBB	JSR &F137   ;set tape speed******** Preserve current language on soft RESET ************************DBBE	LDA &028D   ;get last RESET TypeDBC1	BNE &DBC8   ;if not soft reset DBC8DBC3	LDX &028C   ;else get current language ROM addressDBC6	BPL &DBE6   ;if +ve (language available) then skip search routine**************************************************************************                                                                       **       SEARCH FOR LANGUAGE TO ENTER (Highest priority)                 **                                                                       **************************************************************************DBC8	LDX #&0F    ;set pointer to highest available romDBCA	LDA &02A1,X ;get rom type from mapDBCD	ROL         ;put hi-bit into carry, bit 6 into bit 7DBCE	BMI &DBE6   ;if bit 7 set then ROM has a language entry so DBE6DBD0	DEX         ;else search for language until X=&ffDBD1	BPL &DBCA   ;*************** check if tube present ***********************************DBD3	LDA #&00    ;if bit 7 of tube flag is set BMI succeedsDBD5	BIT &027A   ;and TUBE is connected elseDBD8	BMI &DC08   ;make error********* no language error ***********************************************DBDA	BRK         ;DBDB	DB  &F9     ;error numberDBDC	DB  'Language?'     ;messageDBE5	BRK         ;DBE6	CLC         ;**************************************************************************                                                                       **       OSBYTE 142 - ENTER LANGUAGE ROM AT &8000                        **                                                                       **       X=rom number C set if OSBYTE call clear if initialisation       **                                                                       **************************************************************************DBE7	PHP         ;save flagsDBE8	STX &028C   ;put X in current ROM pageDBEB	JSR &DC16   ;select that ROMDBEE	LDA #&80    ;A=128DBF0	LDY #&08    ;Y=8DBF2	JSR &DEAB   ;display text string held in ROM at &8008,YDBF5	STY &FD     ;save Y on exit (end of language string)DBF7	JSR OSNEWL  ;two line feedsDBFA	JSR OSNEWL  ;are outputDBFD	PLP         ;then get back flagsDBFE	LDA #&01    ;A=1 required for language entryDC00	BIT &027A   ;check if tube existsDC03	BMI &DC08   ;and goto DC08 if it doesDC05	JMP &8000   ;else enter language at &8000**************************************************************************                                                                       **       TUBE FOUND, ENTER TUBE SOFTWARE                                 **                                                                       **************************************************************************DC08	JMP &0400   ;enter tube environment**************************************************************************                                                                       **       OSRDRM entry point                                              **                                                                       **       get byte from PHROM or page ROM                                 **       Y= rom number, address is in &F6/7                              **************************************************************************DC0B	LDX &F4     ;get current ROM number into XDC0D	STY &F4     ;store new number in &F4DC0F	STY &FE30   ;switch in ROMDC12	LDY #&00    ;get current PHROM addressDC14	LDA (&F6),Y ;and get byte******** Set up Sideways Rom latch and RAM copy *************************    	    ;on entry X=ROM numberDC16	STX &F4     ;RAM copy of rom latchDC18	STX &FE30   ;write to rom latchDC1B	RTS         ;and return******************************************************************************************************************************************************                                                                      ****      MAIN IRQ Entry point                                            ****                                                                      ****                                                                      ******************************************************************************************************************************************************;ON ENTRY STACK contains        STATUS REGISTER,PCH,PCL                 ;DC1C	STA &FC     ;save ADC1E	PLA         ;get back status (flags)DC1F	PHA         ;and save againDC20	AND #&10    ;check if BRK flag setDC22	BNE &DC27   ;if so goto DC27DC24	JMP (&0204) ;else JMP (IRQ1V)**************************************************************************                                                                       **               BRK handling routine                                    **                                                                       **************************************************************************DC27	TXA         ;save X on stackDC28	PHA         ;DC29	TSX         ;get status pointerDC2A	LDA &0103,X ;get Program Counter loDC2D	CLD         ;DC2E	SEC         ;set carryDC2F	SBC #&01    ;subtract 2 (1+carry)DC31	STA &FD     ;and store it in &FDDC33	LDA &0104,X ;get hi byteDC36	SBC #&00    ;subtract 1 if necessaryDC38	STA &FE     ;and store in &FEDC3A	LDA &F4     ;get currently active ROMDC3C	STA &024A   ;and store it in &24ADC3F	STX &F0     ;store stack pointer in &F0DC41	LDX #&06    ;and issue ROM service call 6DC43	JSR &F168   ;(User BRK) to roms    	            ;at this point &FD/E point to byte after BRK    	            ;ROMS may use BRK for their own purposesDC46	LDX &028C   ;get current languageDC49	JSR &DC16   ;and activate itDC4C	PLA         ;get back original value of XDC4D	TAX         ;DC4E	LDA &FC     ;get back original value of ADC50	CLI         ;allow interruptsDC51	JMP (&0202) ;and JUMP via BRKV (normally into current language)**************************************************************************                                                                       **       DEFAULT BRK HANDLER                                             **                                                                       **************************************************************************DC54	LDY #&00    ;Y=0 to point to byte after BRKDC56	JSR &DEB1   ;print messageDC59	LDA &0267   ;if BIT 0 set and DISC EXEC errorDC5C	ROR         ;occursDC5D	BCS &DC5D   ;hang up machine!!!!DC5F	JSR OSNEWL  ;else print two newlinesDC62	JSR OSNEWL  ;DC65	JMP &DBB8   ;and set tape speed before entering current    	            ;languageDC68	SEC         ;set carryDC69	ROR &024F   ;and rotate right to set RS423 busy flagDC6C	BIT &0250   ;check bit 7 of current ACIA control registerDC6F	BPL &DC78   ;if interrupts NOT enabled DC78DC71	JSR &E741   ;else E741 to check if serial buffer fullDC74	LDX #&00    ;DC76	BCS &DC7A   ;if carry set goto DC7A to transfer dataDC78	LDX #&40    ;X=&40DC7A	JMP &E17A   ;and transfer dataDC7D	LDY &FE09   ;read serial data from ACIADC80	AND #&3A    ;and %0011 1010DC82	BNE &DCB8   ;if no 0 then DCB8DC84	LDX &025C   ;read RS423 input suppression flagDC87	BNE &DC92   ;if not 0 then DC92 ignore RS423 inputDC89	INX         ;else X=X+1DC8A	JSR &E4F3   ;put byte in bufferDC8D	JSR &E741   ;count bufferDC90	BCC &DC78   ;and if carry clear (buffer not full) back to DC78DC92	RTS         ;else return    	            ;**************************************************************************                                                                       **       Main IRQ Handling routines, default IRQIV destination           **                                                                       **************************************************************************DC93	CLD         ;clear decimal flagDC94	LDA &FC     ;get original value of ADC96	PHA         ;save itDC97	TXA         ;save XDC98	PHA         ;DC99	TYA         ;and YDC9A	PHA         ;DC9B	LDA #&DE    ;A=&DEDC9D	PHA         ;store itDC9E	LDA #&81    ;save &81DCA0	PHA         ;store it (an RTS will now jump to DE82)DCA1	CLV         ;clear V flagDCA2	LDA &FE08   ;get value of status register of ACIADCA5	BVS &DCA9   ;if parity error then DCA9DCA7	BPL &DD06   ;else if no interrupt requested DD06DCA9	LDX &EA     ;read RS423 timeout counterDCAB	DEX         ;decrement itDCAC	BMI &DCDE   ;and if <0 DCDEDCAE	BVS &DCDD   ;else if >&40 DCDD (RTS to DE82)DCB0	JMP &F588   ;else read ACIA via F588DCB3	LDY &FE09   ;read ACIA dataDCB6	ROL         ;DCB7	ASL         ;DCB8	TAX         ;X=ADCB9	TYA         ;A=YDCBA	LDY #&07    ;Y=07DCBC	JMP &E494   ;check and service EVENT 7 RS423 errorDCBF	LDX #&02    ;read RS423 output bufferDCC1	JSR &E460   ;DCC4	BCC &DCD6   ;if C=0 buffer is not empty goto DCD6DCC6	LDA &0285   ;else read printer destinationDCC9	CMP #&02    ;is it serial printer??DCCB	BNE &DC68   ;if not DC68DCCD	INX         ;else X=3DCCE	JSR &E460   ;read printer bufferDCD1	ROR &02D2   ;rotate to pass carry into bit 7DCD4	BMI &DC68   ;if set then DC68DCD6	STA &FE09   ;pass either printer or RS423 data to ACIADCD9	LDA #&E7    ;set timeout counter to stored valueDCDB	STA &EA     ;DCDD	RTS         ;and exit (to DE82)    	            ;A contains ACIA statusDCDE	AND &0278   ;AND with ACIA bit mask (normally FF)DCE1	LSR         ;rotate right to put bit 0 in carryDCE2	BCC &DCEB   ;if carry clear receive register not full so DCEBDCE4	BVS &DCEB   ;if V is set then DCEBDCE6	LDY &0250   ;else Y=ACIA control settingDCE9	BMI &DC7D   ;if bit 7 set receive interrupt is enabled so DC7DDCEB	LSR         ;put BIT 2 of ACIA status intoDCEC	ROR         ;carry if set then Data Carrier Detected appliesDCED	BCS &DCB3   ;jump to DCB3DCEF	BMI &DCBF   ;if original bit 1 is set TDR is empty so DCBFDCF1	BVS &DCDD   ;if V is set then exit to DE82DCF3	LDX #&05    ;X=5DCF5	JSR &F168   ;issue rom call 5 'unrecognised interrupt'DCF8	BEQ &DCDD   ;if a rom recognises it then exit to DE82DCFA	PLA         ;otherwise get back DE82 address from stackDCFB	PLA         ;DCFC	PLA         ;and get back X, Y, and ADCFD	TAY         ;DCFE	PLA         ;DCFF	TAX         ;DD00	PLA         ;DD01	STA &FC     ;&FC=ADD03	JMP (&0206) ;and offer to the user via IRQ2V**************************************************************************                                                                       ** VIA INTERUPTS ROUTINES                                                **                                                                       **************************************************************************DD06	LDA &FE4D   ;read system VIA interrupt flag registerDD09	BPL &DD47   ;if bit 7=0 the VIA has not caused interrupt    	            ;goto DD47DD0B	AND &0279   ;mask with VIA bit maskDD0E	AND &FE4E   ;and interrupt enable registerDD11	ROR         ;rotate right twice to check for IRQ 1 (frame sync)DD12	ROR         ;DD13	BCC &DD69   ;if carry clear then no IRQ 1, elseDD15	DEC &0240   ;decrement vertical sync counterDD18	LDA &EA     ;A=RS423 Timeout counterDD1A	BPL &DD1E   ;if +ve then DD1EDD1C	INC &EA     ;else increment itDD1E	LDA &0251   ;load flash counterDD21	BEQ &DD3D   ;if 0 then system is not in use, ignore itDD23	DEC &0251   ;else decrement counterDD26	BNE &DD3D   ;and if not 0 go on past reset routineDD28	LDX &0252   ;else get mark period count in XDD2B	LDA &0248   ;current VIDEO ULA control setting in ADD2E	LSR         ;shift bit 0 into C to check if first colourDD2F	BCC &DD34   ;is effective if so C=0 jump to DD34DD31	LDX &0253   ;else get space period count in XDD34	ROL         ;restore bitDD35	EOR #&01    ;and invert itDD37	JSR &EA00   ;then change colourDD3A	STX &0251   ;&0251=X resetting the counterDD3D	LDY #&04    ;Y=4 and call E494 to check and implement verticalDD3F	JSR &E494   ;sync event (4) if necessaryDD42	LDA #&02    ;A=2DD44	JMP &DE6E   ;clear interrupt 1 and exit**************************************************************************                                                                       **       PRINTER INTERRUPT USER VIA 1                                    **                                                                       **************************************************************************DD47	LDA &FE6D   ;Check USER VIA interrupt flags registerDD4A	BPL &DCF3   ;if +ve USER VIA did not call interruptDD4C	AND &0277   ;else check for USER IRQ 1DD4F	AND &FE6E   ;DD52	ROR         ;DD53	ROR         ;DD54	BCC &DCF3   ;if bit 1=0 the no interrupt 1 so DCF3DD56	LDY &0285   ;else get printer typeDD59	DEY         ;decrementDD5A	BNE &DCF3   ;if not parallel then DCF3DD5C	LDA #&02    ;reset interrupt 1 flagDD5E	STA &FE6D   ;DD61	STA &FE6E   ;disable interrupt 1DD64	LDX #&03    ;and output data to parallel printerDD66	JMP &E13A   ;************************************************************************                                                                       **       SYSTEM INTERRUPT 5   Speech                                     **                                                                       **************************************************************************DD69	ROL         ;get bit 5 into bit 7DD6A	ROL         ;DD6B	ROL         ;DD6C	ROL         ;DD6D	BPL &DDCA   ;if not set the not a speech interrupt so DDCADD6F	LDA #&20    ;clear interrupt flagDD71	LDX #&00    ;DD73	STA &FE4D   ;DD76	STX &FE49   ;and zer0 hi byte of T2 TimerDD79	LDX #&08    ;&FB=8DD7B	STX &FB     ;DD7D	JSR &E45B   ;and examine buffer 8DD80	ROR &02D7   ;shift carry into bit 7DD83	BMI &DDC9   ;and if set buffer is empty so exitDD85	TAY         ;else Y=ADD86	BEQ &DD8D   ;DD88	JSR &EE6D   ;control speech chipDD8B	BMI &DDC9   ;if negative exitDD8D	JSR &E460   ;else get a byte from bufferDD90	STA &F5     ;store it to indicate speech or file romDD92	JSR &E460   ;get another byteDD95	STA &F7     ;store itDD97	JSR &E460   ;and anotherDD9A	STA &F6     ;giving address  to be accessed in paged ROMDD9C	LDY &F5     ;Y=&F5DD9E	BEQ &DDBB   ;and if =0 then DDBBDDA0	BPL &DDB8   ;else if +ve DDB8DDA2	BIT &F5     ;if bit 6 of F5 =1 (&F5)>&40DDA4	BVS &DDAB   ;then DDABDDA6	JSR &EEBB   ;else continue for more speech processingDDA9	BVC &DDB2   ;if bit 6 clear then DDB2DDAB	ASL &F6     ;else double address in &F6/7DDAD	ROL &F7     ;DDAF	JSR &EE3B   ;and call EE3BDDB2	LDY &0261   ;get speech enable/disable flag into YDDB5	JMP &EE7F   ;and JMP to EE7FDDB8	JSR &EE7F   ;Call EE7FDDBB	LDY &F6     ;get address pointer in YDDBD	JSR &EE7F   ;DDC0	LDY &F7     ;get address pointer high in YDDC2	JSR &EE7F   ;DDC5	LSR &FB     ;DDC7	BNE &DD7D   ;DDC9	RTS         ;and exit    	