OS SERIES IV GEOFF COX ************************************************************************* * * * LATERAL FILL ROUTINE * * * ************************************************************************* D4BF JSR &D4AA ;check current screen state D4C2 AND &D1 ;if A and &D1 <> 0 a plotted point has been found D4C4 BNE &D4B9 ;so D4B9 D4C6 LDX #&00 ;X=0 D4C8 JSR &D592 ;update pointers D4CB BEQ &D4FA ;if 0 then D4FA D4CD LDY &031A ;else Y=graphics scan line D4D0 ASL &D1 ; D4D2 BCS &D4D9 ;if carry set D4D9 D4D4 JSR &D574 ;else D574 D4D7 BCC &D4FA ;if carry clear D4FA D4D9 JSR &D3FD ;else D3FD to pick up colour multiplier D4DC LDA (&D6),Y ;get graphics cell line D4DE EOR &035A ;EOR with background colour D4E1 STA &DA ;and store D4E3 BNE &D4F7 ;if not 0 D4F7 D4E5 SEC ;else set carry D4E6 TXA ;A=X D4E7 ADC &0361 ;add pixels/byte D4EA BCC &D4F0 ;and if carry clear D4F0 D4EC INC &DB ;else increment &DB D4EE BPL &D4F7 ;and if +ve D4F7 D4F0 TAX ;else X=A D4F1 JSR &D104 ;display a pixel D4F4 SEC ;set carry D4F5 BCS &D4D9 ;goto D4D9 D4F7 JSR &D574 ; D4FA LDY #&00 ;Y=0 D4FC JSR &D5AC ; D4FF LDY #&20 ; D501 LDX #&24 ; D503 JSR &CDE6 ;exchange 300/3 +Y with 300/3+X D506 JSR &D4AA ;check screen pixel D509 LDX #&04 ;Y=5 D50B JSR &D592 ; D50E TXA ;A=x D50F BNE &D513 ;if A<>0 d513 D511 DEC &DB ;else &DB=&dB-1 D513 DEX ;X=X-1 D514 JSR &D54B ; D517 BCC &D540 ; D519 JSR &D3ED ;update pointers D51C LDA (&D6),Y ;get byte from graphics line D51E EOR &035A ;EOR with background colour D521 STA &DA ;and store it D523 LDA &DC ; D525 BNE &D514 ;If A-0 back to D514 D527 LDA &DA ;else A=&DA D529 BNE &D53D ;if A<>d53D D52B SEC ;else set carry D52C TXA ;A=x D52D ADC &0361 ;Add number of pixels/byte D530 BCC &D536 ;and if carry clear D536 D532 INC &DB ;else inc DB D534 BPL &D53D ;and if +ve D53D D536 TAX ;get back X D537 JSR &D104 ;display a point D53A SEC ;set carry D53B BCS &D519 ;goto D519 D53D JSR &D54B ; D540 LDY #&04 ; D542 JSR &D5AC ; D545 JSR &D0D9 ; D548 JMP &D1B8 ;scale pointers D54B LDA &D1 ;get byte mask D54D PHA ;save it D54E CLC ;clear carry D54F BCC &D560 ; D551 PLA ;get back A D552 INX ;X=X+1 D553 BNE &D559 ;if not 0 D559 D555 INC &DB ;else inc &DB D557 BPL &D56F ;if +ve D56F D559 LSR &D1 ; D55B BCS &D56F ;if Bit 7 D1 set D56F D55D ORA &D1 ;else or withA D55F PHA ;save result D560 LDA &D1 ;A=&D1 D562 BIT &DA ;test bits 6 and 7 of &DA D564 PHP ;save flags D565 PLA ;get into A D566 EOR &DC ;EOR and DC D568 PHA ;save A D569 PLP ; D56A BEQ &D551 ; D56C PLA ;A=A EOR &D1 (byte mask) D56D EOR &D1 ; D56F STA &D1 ;store it D571 JMP &D0F0 ;and display a pixel D574 LDA #&00 ;A=0 D576 CLC ;Clear carry D577 BCC &D583 ;goto D583 if carry clear D579 INX ;X=X+1 D57A BNE &D580 ;If <>0 D580 D57C INC &DB ;else inc &DB D57E BPL &D56F ;and if +ve d56F D580 ASL ;A=A*2 D581 BCS &D58E ;if C set D58E D583 ORA &D1 ;else A=A OR (&D1) D585 BIT &DA ;set V and M from &DA b6 b7 D587 BEQ &D579 ; D589 EOR &D1 ;A=A EOR &D1 D58B LSR ;/2 D58C BCC &D56F ;if carry clear D56F D58E ROR ;*2 D58F SEC ;set carry D590 BCS &D56F ;to D56F D592 LDA &0300,X ;Y/A=(&300/1 +X)-(&320/1) D595 SEC ; D596 SBC &0320 ; D599 TAY ; D59A LDA &0301,X ; D59D SBC &0321 ; D5A0 BMI &D5A5 ;if result -ve D5A5 D5A2 JSR &D49B ;or negate Y/A D5A5 STA &DB ;store A D5A7 TYA ;A=Y D5A8 TAX ;X=A D5A9 ORA &DB ; D5AB RTS ;exit D5AC STY &DA ;Y=&DA D5AE TXA ;A=X D5AF TAY ;Y=A D5B0 LDA &DB ;A=&DB D5B2 BMI &D5B6 ;if -ve D5B6 D5B4 LDA #&00 ;A=0 D5B6 LDX &DA ;X=&DA D5B8 BNE &D5BD ;if <>0 D5BD D5BA JSR &D49B ;negate D5BD PHA ; D5BE CLC ; D5BF TYA ; D5C0 ADC &0300,X ;Y/A+(&300/1 +X)=(&320/1) D5C3 STA &0320 ; D5C6 PLA ; D5C7 ADC &0301,X ; D5CA STA &0321 ; D5CD RTS ;return ************************************************************************* * * * OSWORD 13 - READ LAST TWO GRAPHIC CURSOR POSITIONS * * * ************************************************************************* ; D5CE LDA #&03 ;A=3 D5D0 JSR &D5D5 ; D5D3 LDA #&07 ;A=7 D5D5 PHA ;Save A D5D6 JSR &CDE2 ;exchange last 2 graphics cursor coordinates with ;current coordinates D5D9 JSR &D1B8 ;convert to external coordinates D5DC LDX #&03 ;X=3 D5DE PLA ;save A D5DF TAY ;Y=A D5E0 LDA &0310,X ;get graphics coordinate D5E3 STA (&F0),Y ;store it in OS buffer D5E5 DEY ;decrement Y and X D5E6 DEX ; D5E7 BPL &D5E0 ;if +ve do it again D5E9 RTS ;then Exit ************************************************************************* * * * PLOT Fill triangle routine * * * ************************************************************************* D5EA LDX #&20 ;X=&20 D5EC LDY #&3E ;Y=&3E D5EE JSR &D47C ;copy 300/7+X to 300/7+Y ;this gets XY data parameters and current graphics ;cursor position D5F1 JSR &D632 ;exchange 320/3 with 324/7 if 316/7=<322/3 D5F4 LDX #&14 ;X=&14 D5F6 LDY #&24 ;Y=&24 D5F8 JSR &D636 ; D5FB JSR &D632 ; D5FE LDX #&20 ; D600 LDY #&2A ; D602 JSR &D411 ;calculate 032A/B-(324/5-320/1) D605 LDA &032B ;and store D608 STA &0332 ;result D60B LDX #&28 ;set pointers D60D JSR &D459 ; D610 LDY #&2E ; D612 JSR &D0DE ;copy 320/3 32/31 D615 JSR &CDE2 ;exchange 314/7 with 324/7 D618 CLC ; D619 JSR &D658 ;execute fill routine D61C JSR &CDE2 ; D61F LDX #&20 ; D621 JSR &CDE4 ; D624 SEC ; D625 JSR &D658 ; D628 LDX #&3E ;;X=&3E D62A LDY #&20 ;;Y=&20 D62C JSR &D47C ;;copy 300/7+X to 300/7+Y D62F JMP &D0D9 ;;this gets XY data parameters and current graphics ;cursor position D632 LDX #&20 ;X=&20 D634 LDY #&14 ;Y=&14 D636 LDA &0302,X ; D639 CMP &0302,Y ; D63C LDA &0303,X ; D63F SBC &0303,Y ; D642 BMI &D657 ;if 302/3+Y>302/3+X return D644 JMP &CDE6 ;else swap 302/3+X with 302/3+Y ************************************************************************* * * * OSBYTE 134 - READ CURSOR POSITION * * * ************************************************************************* D647 LDA &0318 ;read current text cursor (X) D64A SEC ;set carry D64B SBC &0308 ;subtract left hand column of current text window D64E TAX ;X=A D64F LDA &0319 ;get current text cursor (Y) D652 SEC ; D653 SBC &030B ;suptract top row of current window D656 TAY ;Y=A D657 RTS ;and exit ;PLOT routines continue ;many of the following routines are just manipulations ;only points of interest will be explained D658 PHP ;store flags D659 LDX #&20 ;X=&20 D65B LDY #&35 ;Y=&35 D65D JSR &D411 ;335/6=(324/5+X-320/1) D660 LDA &0336 ; D663 STA &033D ; D666 LDX #&33 ; D668 JSR &D459 ;set pointers D66B LDY #&39 ;set 339/C=320/3 D66D JSR &D0DE ; D670 SEC ; D671 LDA &0322 ; D674 SBC &0326 ; D677 STA &031B ; D67A LDA &0323 ; D67D SBC &0327 ; D680 STA &031C ; D683 ORA &031B ;check VDU queque D686 BEQ &D69F ; D688 JSR &D6A2 ;display a line D68B LDX #&33 ; D68D JSR &D774 ;update pointers D690 LDX #&28 ; D692 JSR &D774 ;and again! D695 INC &031B ;update VDU queque D698 BNE &D688 ;and if not empty do it again D69A INC &031C ;else increment next byte D69D BNE &D688 ;and do it again D69F PLP ;pull flags D6A0 BCC &D657 ;if carry clear exit D6A2 LDX #&39 ; D6A4 LDY #&2E ; D6A6 STX &DE ; D6A8 LDA &0300,X ;is 300/1+x<300/1+Y D6AB CMP &0300,Y ; D6AE LDA &0301,X ; D6B1 SBC &0301,Y ; D6B4 BMI &D6BC ;if so D6BC D6B6 TYA ;else A=Y D6B7 LDY &DE ;Y=&DE D6B9 TAX ;X=A D6BA STX &DE ;&DE=X D6BC STY &DF ;&DF=Y D6BE LDA &0300,Y ; D6C1 PHA ; D6C2 LDA &0301,Y ; D6C5 PHA ; D6C6 LDX &DF ; D6C8 JSR &D10F ;check for window violations D6CB BEQ &D6DA ; D6CD CMP #&02 ; D6CF BNE &D70E ; D6D1 LDX #&04 ; D6D3 LDY &DF ; D6D5 JSR &D482 ; D6D8 LDX &DF ; D6DA JSR &D864 ;set a screen address D6DD LDX &DE ;X=&DE D6DF JSR &D10F ;check for window violations D6E2 LSR ;A=A/2 D6E3 BNE &D70E ;if A<>0 then exit D6E5 BCC &D6E9 ;else if C clear D6E9 D6E7 LDX #&00 ; D6E9 LDY &DF ; D6EB SEC ; D6EC LDA &0300,Y ; D6EF SBC &0300,X ; D6F2 STA &DC ; D6F4 LDA &0301,Y ; D6F7 SBC &0301,X ; D6FA STA &DD ; D6FC LDA #&00 ; D6FE ASL ; D6FF ORA &D1 ; D701 LDY &DC ; D703 BNE &D719 ; D705 DEC &DD ; D707 BPL &D719 ; D709 STA &D1 ; D70B JSR &D0F0 ;display a point D70E LDX &DF ;restore X D710 PLA ;and A D711 STA &0301,X ;store it D714 PLA ;get back A D715 STA &0300,X ;and store it D718 RTS ;exit ; D719 DEC &DC ; D71B TAX ; D71C BPL &D6FE ; D71E STA &D1 ; D720 JSR &D0F0 ;display a point D723 LDX &DC ; D725 INX ; D726 BNE &D72A ; D728 INC &DD ; D72A TXA ; D72B PHA ; D72C LSR &DD ; D72E ROR ; D72F LDY &0361 ;number of pixels/byte D732 CPY #&03 ;if 3 mode = goto D73B D734 BEQ &D73B ; D736 BCC &D73E ;else if <3 mode 2 goto D73E D738 LSR &DD ;else rotate bottom bit of &DD D73A ROR ;into Accumulator D73B LSR &DD ;rotate bottom bit of &DD D73D LSR ;into Accumulator D73E LDY &031A ;Y=line in current graphics cell containing current ;point D741 TAX ;X=A D742 BEQ &D753 ; D744 TYA ;Y=Y-8 D745 SEC ; D746 SBC #&08 ; D748 TAY ; D749 BCS &D74D ; D74B DEC &D7 ;decrement byte of top line off current graphics cell D74D JSR &D104 ;display a point D750 DEX ; D751 BNE &D744 ; D753 PLA ; D754 AND &0361 ;pixels/byte D757 BEQ &D70E ; D759 TAX ; D75A LDA #&00 ;A=0 D75C ASL ; D75D ORA &0363 ;or with right colour mask D760 DEX ; D761 BNE &D75C ; D763 STA &D1 ;store as byte mask D765 TYA ;Y=Y-8 D766 SEC ; D767 SBC #&08 ; D769 TAY ; D76A BCS &D76E ;if carry clear D76C DEC &D7 ;decrement byte of top line off current graphics cell D76E JSR &D0F3 ;display a point D771 JMP &D70E ;and exit via D70E D774 INC &0308,X ; D777 BNE &D77C ; D779 INC &0309,X ; D77C SEC ; D77D LDA &0300,X ; D780 SBC &0302,X ; D783 STA &0300,X ; D786 LDA &0301,X ; D789 SBC &0303,X ; D78C STA &0301,X ; D78F BPL &D7C1 ; D791 LDA &030A,X ; D794 BMI &D7A1 ; D796 INC &0306,X ; D799 BNE &D7AC ; D79B INC &0307,X ; D79E JMP &D7AC ; D7A1 LDA &0306,X ; D7A4 BNE &D7A9 ; D7A6 DEC &0307,X ; D7A9 DEC &0306,X ; D7AC CLC ; D7AD LDA &0300,X ; D7B0 ADC &0304,X ; D7B3 STA &0300,X ; D7B6 LDA &0301,X ; D7B9 ADC &0305,X ; D7BC STA &0301,X ; D7BF BMI &D791 ; D7C1 RTS ; ************************************************************************* * * * OSBYTE 135 - READ CHARACTER AT TEXT CURSOR POSITION * * * ************************************************************************* D7C2 LDY &0360 ;get number of logical colours D7C5 BNE &D7DC ;if Y<>0 mode <>7 so D7DC D7C7 LDA (&D8),Y ;get character in current character cell D7C9 LDY #&02 ;Y=2 D7CB CMP &C4B7,Y ;compare with conversion table D7CE BNE &D7D4 ;if not equal D7D4 D7D0 LDA &C4B6,Y ;else get next lower byte from table D7D3 DEY ;Y=Y-1 D7D4 DEY ;Y=Y-1 D7D5 BPL &D7CB ;and if +ve do it again D7D7 LDY &0355 ;Y=current screen mode D7DA TAX ;return with character in X, setting EQ/NE D7DB RTS ; ; D7DC JSR &D808 ;set up copy of the pattern bytes at text cursor D7DF LDX #&20 ;X=&20 D7E1 TXA ;A=&20 D7E2 PHA ;Save it D7E3 JSR &D03E ;get pattern address for code in A D7E6 PLA ;get back A D7E7 TAX ;and X D7E8 LDY #&07 ;Y=7 D7EA LDA &0328,Y ;get byte in pattern copy D7ED CMP (&DE),Y ;check against pattern source D7EF BNE &D7F9 ;if not the same D7F9 D7F1 DEY ;else Y=Y-1 D7F2 BPL &D7EA ;and if +ve D7EA D7F4 TXA ;A=X D7F5 CPX #&7F ;is X=&7F (delete) D7F7 BNE &D7D7 ;if not D7D7 D7F9 INX ;else X=X+1 D7FA LDA &DE ;get byte lo address D7FC CLC ;clear carry D7FD ADC #&08 ;add 8 D7FF STA &DE ;store it D801 BNE &D7E8 ;and go back to check next character if <>0 D803 TXA ;A=X D804 BNE &D7E1 ;if <>0 D7E1 D806 BEQ &D7D7 ;else D7D7 ***************** set up pattern copy *********************************** D808 LDY #&07 ;Y=7 D80A STY &DA ;&DA=Y D80C LDA #&01 ;A=1 D80E STA &DB ;&DB=A D810 LDA &0362 ;A=left colour mask D813 STA &DC ;store an &DC D815 LDA (&D8),Y ;get a byte from current text character D817 EOR &0358 ;EOR with text background colour D81A CLC ;clear carry D81B BIT &DC ;and check bits of colour mask D81D BEQ &D820 ;if result =0 then D820 D81F SEC ;else set carry D820 ROL &DB ;&DB=&DB+Carry D822 BCS &D82E ;if carry now set (bit 7 DB originally set) D82E D824 LSR &DC ;else &DC=&DC/2 D826 BCC &D81B ;if carry clear D81B D828 TYA ;A=Y D829 ADC #&07 ;ADD ( (7+carry) D82B TAY ;Y=A D82C BCC &D810 ; D82E LDY &DA ;read modified values into Y and A D830 LDA &DB ; D832 STA &0328,Y ;store copy D835 DEY ;and do it again D836 BPL &D80A ;until 8 bytes copied D838 RTS ;exit ********* pixel reading ************************************************* D839 PHA ;store A D83A TAX ;X=A D83B JSR &D149 ;set up positional data D83E PLA ;get back A D83F TAX ;X=A D840 JSR &D85F ;set a screen address after checking for window ;violations D843 BNE &D85A ;if A<>0 D85A to exit with A=&FF D845 LDA (&D6),Y ;else get top line of current graphics cell D847 ASL ;A=A*2 C=bit 7 D848 ROL &DA ;&DA=&DA+2 +C C=bit 7 &DA D84A ASL &D1 ;byte mask=bM*2 +carry from &DA D84C PHP ;save flags D84D BCS &D851 ;if carry set D851 D84F LSR &DA ;else restore &DA with bit '=0 D851 PLP ;pull flags D852 BNE &D847 ;if Z set D847 D854 LDA &DA ;else A=&DA AND number of colours in current mode -1 D856 AND &0360 ; D859 RTS ;then exit ; D85A LDA #&FF ;A=&FF D85C RTS ;exit ********** check for window violations and set up screen address ********** D85D LDX #&20 ;X=&20 D85F JSR &D10F ; D862 BNE &D85C ;if A<>0 there is a window violation so D85C D864 LDA &0302,X ;else set up graphics scan line variable D867 EOR #&FF ; D869 TAY ; D86A AND #&07 ; D86C STA &031A ;in 31A D86F TYA ;A=Y D870 LSR ;A=A/2 D871 LSR ;A=A/2 D872 LSR ;A=A/2 D873 ASL ;A=A*2 this gives integer value bit 0 =0 D874 TAY ;Y=A D875 LDA (&E0),Y ;get high byte of offset from screen RAM start D877 STA &DA ;store it D879 INY ;Y=Y+1 D87A LDA (&E0),Y ;get lo byte D87C LDY &0356 ;get screen map type D87F BEQ &D884 ;if 0 (modes 0,1,2) goto D884 D881 LSR &DA ;else &DA=&DA/2 D883 ROR ;and A=A/2 +C if set ;so 2 byte offset =offset/2 D884 ADC &0350 ;add screen top left hand corner lo D887 STA &D6 ;store it D889 LDA &DA ;get high byte D88B ADC &0351 ;add top left hi D88E STA &D7 ;store it D890 LDA &0301,X ; D893 STA &DA ; D895 LDA &0300,X ; D898 PHA ; D899 AND &0361 ;and then Add pixels per byte-1 D89C ADC &0361 ; D89F TAY ;Y=A D8A0 LDA &C406,Y ;A=&80 /2^Y using look up table D8A3 STA &D1 ;store it D8A5 PLA ;get back A D8A6 LDY &0361 ;Y=&number of pixels/byte D8A9 CPY #&03 ;is Y=3 (modes 1,6) D8AB BEQ &D8B2 ;goto D8B2 D8AD BCS &D8B5 ;if mode =1 or 4 D8B5 D8AF ASL ;A/&DA =A/&DA *2 D8B0 ROL &DA ; D8B2 ASL ; D8B3 ROL &DA ; D8B5 AND #&F8 ;clear bits 0-2 D8B7 CLC ;clear carry D8B8 ADC &D6 ;add A/&DA to &D6/7 D8BA STA &D6 ; D8BC LDA &DA ; D8BE ADC &D7 ; D8C0 BPL &D8C6 ;if result +ve D8C6 D8C2 SEC ;else set carry D8C3 SBC &0354 ;and subtract screen memory size making it wrap round D8C6 STA &D7 ;store it in &D7 D8C8 LDY &031A ;get line in graphics cell containing current graphics D8CB LDA #&00 ;point A=0 D8CD RTS ;And exit ; D8CE PHA ;Push A D8CF LDA #&A0 ;A=&A0 D8D1 LDX &026A ;X=number of items in VDU queue D8D4 BNE &D916 ;if not 0, D916 D8D6 BIT &D0 ;else check VDU status byte D8D8 BNE &D916 ;if either VDU is disabled or plot to graphics ;cursor enabled then D916 D8DA BVS &D8F5 ;if cursor editing enabled D8F5 D8DC LDA &035F ;else get 6845 register start setting D8DF AND #&9F ;clear bits 5 and 6 D8E1 ORA #&40 ;set bit 6 to modify last cursor size setting D8E3 JSR &C954 ;change write cursor format D8E6 LDX #&18 ;X=&18 D8E8 LDY #&64 ;Y=&64 D8EA JSR &D482 ;set text input cursor from text output cursor D8ED JSR &CD7A ;modify character at cursor poistion D8F0 LDA #&02 ;A=2 D8F2 JSR &C59D ;bit 1 of VDU status is set to bar scrolling D8F5 LDA #&BF ;A=&BF D8F7 JSR &C5A8 ;bit 6 of VDU status =0 D8FA PLA ;Pull A D8FB AND #&7F ;clear hi bit (7) D8FD JSR &C4C0 ;entire VDU routine !! D900 LDA #&40 ;A=&40 D902 JMP &C59D ;exit D905 LDA #&20 ;A=&20 D907 BIT &D0 ;if bit 6 cursor editing is set D909 BVC &D8CB ; D90B BNE &D8CB ;or bit 5 is set exit &D8CB D90D JSR &D7C2 ;read a character from the screen D910 BEQ &D917 ;if A=0 on return exit via D917 D912 PHA ;else store A D913 JSR &C664 ;perform cursor right D916 PLA ;restore A D917 RTS ;and exit ; D918 LDA #&BD ;zero bits 2 and 6 of VDU status D91A JSR &C5A8 ; D91D JSR &C951 ;set normal cursor D920 LDA #&0D ;A=&0D D922 RTS ;and return ;this is response of CR as end of edit line ************************************************************************* * * * OSBYTE 132 - READ BOTTOM OF DISPLAY RAM * * * ************************************************************************* D923 LDX &0355 ; Get current screen mode ************************************************************************* * * * OSBYTE 133 - READ LOWEST ADDRESS FOR GIVEN MODE * * * ************************************************************************* D926 TXA ; A=X D927 AND #&07 ; Ensure mode 0-7 D929 TAY ; Pass to Y into index into screen size table D92A LDX &C440,Y ; X=screen size type, 0-4 D92D LDA &C45E,X ; A=high byte of start address for screen type D930 LDX #&00 ; Returned address is &xx00 D932 BIT &028E ; Check available RAM D935 BMI &D93E ; If bit 7 set then 32K RAM, so return address D937 AND #&3F ; 16K RAM, so drop address to bottom 16K D939 CPY #&04 ; Check screen mode D93B BCS &D93E ; If mode 4-7, return the address D93D TXA ; If mode 0-3, return &0000 as not enough memory ; exit D93E TAY ; Pass high byte of address to Y D93F RTS ; and return address in YX