OS SERIES VII GEOFF COX ************************************************************************* * * * OSBYTE 9 Duration of first colour * * * ************************************************************************* ;on entry Y=0, X=new value E6B0 INY ;Y is incremented to 1 E6B1 CLC ;clear carry ************************************************************************* * * * OSBYTE 10 Duration of second colour * * * ************************************************************************* ;on entry Y=0 or 1 if from FX 9 call, X=new value E6B2 LDA &0252,Y ;get mark period count E6B5 PHA ;push it E6B6 TXA ;get new count E6B7 STA &0252,Y ;store it E6BA PLA ;get back original value E6BB TAY ;put it in Y E6BC LDA &0251 ;get value of flash counter E6BF BNE &E6D1 ;if not zero E6D1 E6C1 STX &0251 ;else restore old value E6C4 LDA &0248 ;get current video ULA control register setting E6C7 PHP ;push flags E6C8 ROR ;rotate bit 0 into carry, carry into bit 7 E6C9 PLP ;get back flags E6CA ROL ;rotate back carry into bit 0 E6CB STA &0248 ;store it in RAM copy E6CE STA &FE20 ;and ULA control register E6D1 BVC &E6AD ;then exit via OSBYTE 7/8 ************************************************************************* * * * OSBYTE 2 select input stream * * * ************************************************************************* ;on input X contains stream number E6D3 TXA ;A=X E6D4 AND #&01 ;blank out bits 1 - 7 E6D6 PHA ;push A E6D7 LDA &0250 ;and get current ACIA control setting E6DA ROL ;Bit 7 into carry E6DB CPX #&01 ;if X>=1 then E6DD ROR ;bit 7 of A=1 E6DE CMP &0250 ;compare this with ACIA control setting E6E1 PHP ;push processor E6E2 STA &0250 ;put A into ACIA control setting E6E5 STA &FE08 ;and write to control register E6E8 JSR &E173 ;set up RS423 buffer E6EB PLP ;get back P E6EC BEQ &E6F1 ;if new setting different from old E6F1 else E6EE BIT &FE09 ;set bit 6 and 7 E6F1 LDX &0241 ;get current input buffer number E6F4 PLA ;get back A E6F5 STA &0241 ;store it E6F8 RTS ;and return ************************************************************************* * * * OSBYTE 13 disable events * * * ************************************************************************* ;X contains event number 0-9 E6F9 TYA ;Y=0 A=0 ************************************************************************* * * * OSBYTE 14 enable events * * * ************************************************************************* ;X contains event number 0-9 E6FA CPX #&0A ;if X>9 E6FC BCS &E6AE ;goto E6AE for exit E6FE LDY &02BF,X ;else get event enable flag E701 STA &02BF,X ;store new value in flag E704 BVC &E6AD ;and exit via E6AD ************************************************************************* * * * OSBYTE 16 Select A/D channel * * * ************************************************************************* ;X contains channel number or 0 if disable conversion E706 BEQ &E70B ;if X=0 then E70B E708 JSR &DE8C ;start conversion E70B LDA &024D ;get current maximum ADC channel number E70E STX &024D ;store new value E711 TAX ;put old value in X E712 RTS ;and exit ; ************************************************************************* * * * OSBYTE 129 Read key within time limit * * * ************************************************************************* ;X and Y contains either time limit in centi seconds Y=&7F max ; or Y=&FF and X=-ve INKEY value E713 TYA ;A=Y E714 BMI &E721 ;if Y=&FF the E721 E716 CLI ;else allow interrupts E717 JSR &DEBB ;and go to timed routine E71A BCS &E71F ;if carry set then E71F E71C TAX ;then X=A E71D LDA #&00 ;A=0 E71F TAY ;Y=A E720 RTS ;and return ; ;scan keyboard E721 TXA ;A=X E722 EOR #&7F ;convert to keyboard input E724 TAX ;X=A E725 JSR &F068 ;then scan keyboard E728 ROL ;put bit 7 into carry E729 LDX #&FF ;X=&FF E72B LDY #&FF ;Y=&FF E72D BCS &E731 ;if bit 7 of A was set goto E731 (RTS) E72F INX ;else X=0 E730 INY ;and Y=0 E731 RTS ;and exit ********** check occupancy of input or free space of output buffer ******* ;X=buffer number ;Buffer number Address Flag Out pointer In pointer ;0=Keyboard 3E0-3FF 2CF 2D8 2E1 ;1=RS423 Input A00-AFF 2D0 2D9 2E2 ;2=RS423 output 900-9BF 2D1 2DA 2E3 ;3=printer 880-8BF 2D2 2DB 2E4 ;4=sound0 840-84F 2D3 2DC 2E5 ;5=sound1 850-85F 2D4 2DD 2E6 ;6=sound2 860-86F 2D5 2DE 2E7 ;7=sound3 870-87F 2D6 2DF 2E8 ;8=speech 8C0-8FF 2D7 2E0 2E9 E732 TXA ;buffer number in A E733 EOR #&FF ;invert it E735 TAX ;X=A E736 CPX #&02 ;is X>1 E738 CLV ;clear V flag E739 BVC &E73E ;and goto E73E count buffer E73B BIT &D9B7 ;set V E73E JMP (&022E) ;CNPV defaults to E1D1 ************* check RS423 input buffer ************************************ E741 SEC E742 LDX #&01 ;X=1 to point to buffer E744 JSR &E738 ;and count it E747 CPY #&01 ;if the hi byte of the answer is 1 or more E749 BCS &E74E ;then Return E74B CPX &025B ;else compare with minimum buffer space E74E RTS ;and exit ************************************************************************* * * * OSBYTE 128 READ ADC CHANNEL * * * ************************************************************************* ;ON Entry: X=0 Exit Y contains number of last channel converted ; X=channel number X,Y contain 16 bit value read from channe ; X<0 Y=&FF X returns information about various buffers ; X=&FF (keyboard ) X=number of characters in buffer ; X=&FE (RS423 Input) X=number of characters in buffer ; X=&FD (RS423 output) X=number of empty spaces in buffer ; X=&FC (Printer) X=number of empty spaces in buffer ; X=&FB (sound 0) X=number of empty spaces in buffer ; X=&FA (sound 1) X=number of empty spaces in buffer ; X=&F9 (sound 2) X=number of empty spaces in buffer ; X=&F8 (sound 3) X=number of empty spaces in buffer ; X=&F7 (Speech ) X=number of empty spaces in buffer E74F BMI &E732 ;if X is -ve then E732 count spaces E751 BEQ &E75F ;if X=0 then E75F E753 CPX #&05 ;else check for Valid channel E755 BCS &E729 ;if not E729 set X & Y to 0 and exit E757 LDY &02B9,X ;get conversion values for channel of interest Hi & E75A LDA &02B5,X ;lo byte E75D TAX ;X=lo byte E75E RTS ;and exit E75F LDA &FE40 ;read system VIA port B E762 ROR ;move high nybble to low E763 ROR ; E764 ROR ; E765 ROR ; E766 EOR #&FF ;and invert it E768 AND #&03 ;isolate the FIRE buttons E76A LDY &02BE ;get analogue system flag byte E76D STX &02BE ;store X here E770 TAX ;A=X bits 0 and 1 indicate fire buttons E771 RTS ;and return ************************************************************************** ************************************************************************** ** ** ** OSBYTE DEFAULT ENTRY POINT ** ** ** ** pointed to by default BYTEV ** ** ** ************************************************************************** ************************************************************************** E772 PHA ;save A E773 PHP ;save Processor flags E774 SEI ;disable interrupts E775 STA &EF ;store A,X,Y in zero page E777 STX &F0 ; E779 STY &F1 ; E77B LDX #&07 ;X=7 to signal osbyte is being attempted E77D CMP #&75 ;if A=0-116 E77F BCC &E7C2 ;then E7C2 E781 CMP #&A1 ;if A<161 E783 BCC &E78E ;then E78E E785 CMP #&A6 ;if A=161-165 E787 BCC &E7C8 ;then EC78 E789 CLC ;clear carry E78A LDA #&A1 ;A=&A1 E78C ADC #&00 ; ********* process osbyte calls 117 - 160 ***************************** E78E SEC ;set carry E78F SBC #&5F ;convert to &16 to &41 (22-65) E791 ASL ;double it (44-130) E792 SEC ;set carry E793 STY &F1 ;store Y E795 TAY ;Y=A E796 BIT &025E ;read econet intercept flag E799 BPL &E7A2 ;if no econet intercept required E7A2 E79B TXA ;else A=X E79C CLV ;V=0 E79D JSR &E57E ; to JMP via ECONET vector E7A0 BVS &E7BC ;if return with V set E7BC E7A2 LDA &E5B4,Y ;get address from table E7A5 STA &FB ;store it as hi byte E7A7 LDA &E5B3,Y ;repeat for lo byte E7AA STA &FA ; E7AC LDA &EF ;restore A E7AE LDY &F1 ;Y E7B0 BCS &E7B6 ;if carry is set E7B6 E7B2 LDY #&00 ;else E7B4 LDA (&F0),Y ;get value from address pointed to by &F0/1 (Y,X) E7B6 SEC ;set carry E7B7 LDX &F0 ;restore X E7B9 JSR &F058 ;call &FA/B E7BC ROR ;C=bit 0 E7BD PLP ;get back flags E7BE ROL ;bit 0=Carry E7BF PLA ;get back A E7C0 CLV ;clear V E7C1 RTS ;and exit *************** Process OSBYTE CALLS BELOW &75 ************************** E7C2 LDY #&00 ;Y=0 E7C4 CMP #&16 ;if A<&16 E7C6 BCC &E791 ;goto E791 E7C8 PHP ;push flags E7C9 PHP ;push flags E7CA PLA ;pull flags E7CB PLA ;pull flags E7CC JSR &F168 ;offer paged ROMS service 7/8 unrecognised osbyte/word E7CF BNE &E7D6 ;if roms don't recognise it then E7D6 E7D1 LDX &F0 ;else restore X E7D3 JMP &E7BC ;and exit E7D6 PLP ;else pull flags E7D7 PLA ;and A E7D8 BIT &D9B7 ;set V and C E7DB RTS ;and return E7DC LDA &EB ;read cassette critical flag bit 7 = busy E7DE BMI &E812 ;if busy then EB12 E7E0 LDA #&08 ;else A=8 to check current Catalogue status E7E2 AND &E2 ;by anding with CFS status flag E7E4 BNE &E7EA ;if not set (not in use) then E7EA RTS E7E6 LDA #&88 ;A=%10001000 E7E8 AND &BB ;AND with FS options (short msg bits) E7EA RTS ;RETURN ************************************************************************** ************************************************************************** ** ** ** OSWORD DEFAULT ENTRY POINT ** ** ** ** pointed to by default WORDV ** ** ** ************************************************************************** ************************************************************************** E7EB PHA ;Push A E7EC PHP ;Push flags E7ED SEI ;disable interrupts E7EE STA &EF ;store A,X,Y E7F0 STX &F0 ; E7F2 STY &F1 ; E7F4 LDX #&08 ;X=8 E7F6 CMP #&E0 ;if A=>224 E7F8 BCS &E78A ;then E78A with carry set E7FA CMP #&0E ;else if A=>14 E7FC BCS &E7C8 ;else E7C8 with carry set pass to ROMS & exit E7FE ADC #&44 ;add to form pointer to table E800 ASL ;double it E801 BCC &E793 ;goto E793 ALWAYS!! (carry clear E7F8) ;this reads bytes from table and enters routine ************************************************************************* * * * OSWORD 05 ENTRY POINT * * * * read a byte from I/O memory * * * ************************************************************************* ;block of 4 bytes set at address pointed to by 00F0/1 (Y,X) ;XY +0 ADDRESS of byte ; +4 on exit byte read E803 JSR &E815 ;set up address of data block E806 LDA (&F9,X) ;get byte E808 STA (&F0),Y ;store it E80A RTS ;exit ************************************************************************* * * * OSWORD 06 ENTRY POINT * * * * write a byte to I/O memory * * * ************************************************************************* ;block of 5 bytes set at address pointed to by 00F0/1 (Y,X) ;XY +0 ADDRESS of byte ; +4 byte to be written E80B JSR &E815 ;set up address E80E LDA (&F0),Y ;get byte E810 STA (&F9,X) ;store it E812 LDA #&00 ;a=0 E814 RTS ;exit ********************: set up data block ********************************* E815 STA &FA ;&FA=A E817 INY ;Y=1 E818 LDA (&F0),Y ;get byte from block E81A STA &FB ;store it E81C LDY #&04 ;Y=4 E81E LDX #&01 ;X=1 E820 RTS ;and exit ************************************************************************* * * * OSBYTE 00 ENTRY POINT * * * * read OS version number * * * ************************************************************************* E821 BNE &E81E ;if A <> 0 then exit else print error E823 BRK ; E824 DB &F7 ;error number E825 DB 'OS 1.20' ;error message E82C BRK ************************************************************************* * * * OSWORD 07 ENTRY POINT * * * * make a sound * * * ************************************************************************* ;block of 8 bytes set at address pointed to by 00F0/1 ;XY +0 Channel or +0=Flush, Channel:+1=Hold,Sync ; 2 Amplitude ; 4 Pitch ; 6 Duration ;Y=0 on entry E82D INY ;increment Y E82E LDA (&F0),Y ;get channel byte from table E830 CMP #&FF ;if its &FF goto speech E832 BEQ &E88D ;at E8DD E834 CMP #&20 ;else if>=&20 set carry E836 LDX #&08 ;X=8 for unrecognised OSWORD call E838 BCS &E7CA ;and if carry set off to E7CA to offer to ROMS E83A DEY ;Y=0 E83B JSR &E8C9 ;return with Carry set if Flush=1:A=C E83E ORA #&04 ;convert to buffer number E840 TAX ;A=X E841 BCC &E848 ;and if carry clear (ex E8C9) then E848 E843 JSR &E1AE ;else flush buffer E846 LDY #&01 ;Y=1 E848 JSR &E8C9 ;returns with carry set if H=1;A=S E84B STA &FA ;Sync number =&FA E84D PHP ;ave flags E84E LDY #&06 ;Y=6 E850 LDA (&F0),Y ;Get Duration byte E852 PHA ;push it E853 LDY #&04 ;Y=4 E855 LDA (&F0),Y ;get pitch byte E857 PHA ;push it E858 LDY #&02 ;get amplitude byte E85A LDA (&F0),Y ; E85C ROL ;H now =bit 0 (carry shifted) E85D SEC ;set carry E85E SBC #&02 ;subract 2 E860 ASL ;multiply by 4 E861 ASL ; E862 ORA &FA ;add S byte (0-3) ;at this point bit 7=0 for an envelope ;bits 3-6 give envelope -1, or volume +15 ;(i.e.complemented) ;bit 2 gives H ;bits 0-1 =Sync E864 JSR &E1F8 ;transfer to buffer E867 BCC &E887 ;if C set on exit succesful transfer so E887 E869 PLA ;else get back E86A PLA ;stored values E86B PLP ; ************************************************************************* * * * OSBYTE 117 ENTRY POINT * * * * read VDU status * * * ************************************************************************* E86C LDX &D0 ;get VDU status byte in X E86E RTS ;and return ************* set up sound data for Bell ******************************** E86F PHP ;push P E870 SEI ;bar interrupts E871 LDA &0263 ;get bell channel number in A E874 AND #&07 ; (bits 0-3 only set) E876 ORA #&04 ;set bit 2 E878 TAX ;X=A = bell channel number +4=buffer number E879 LDA &0264 ;get bell amplitude/envelope number E87C JSR &E4B0 ;store it in buffer pointed to by X E87F LDA &0266 ;get bell duration E882 PHA ;save it E883 LDA &0265 ;get bell frequency E886 PHA ;save it