************************** Check window limits ************************* ; D10D LDX #&24 ;X=&24 D10F LDY #&00 ;Y=0 D111 STY &DA ;&DA=0 D113 LDY #&02 ;Y=2 D115 JSR &D128 ;check vertical graphics position 326/7 ;bottom and top margins 302/3, 306/7 D118 ASL &DA ;DATA is set in &DA bits 0 and 1 then shift left D11A ASL &DA ;twice to make room for next pass D11C DEX ;X=&22 D11D DEX ; D11E LDY #&00 ;Y=0 D120 JSR &D128 ;left and right margins 300/1, 304/5 ;cursor horizontal position 324/5 D123 INX ;X=X+2 D124 INX ; D125 LDA &DA ;A=&DA D127 RTS ;exit *** cursor and margins check ****************************************** ; D128 LDA &0302,X ;check for window violation D12B CMP &0300,Y ;300/1 +Y > 302/3+X D12E LDA &0303,X ;then window fault D131 SBC &0301,Y ; D134 BMI &D146 ;so D146 D136 LDA &0304,Y ;check other windows D139 CMP &0302,X ; D13C LDA &0305,Y ; D13F SBC &0303,X ; D142 BPL &D148 ;if no violation exit D144 INC &DA ;else DA=DA+1 D146 INC &DA ;DA=DA+1 D148 RTS ;and exit DA=0 no problems DA=1 first check 2, 2nd ***********set up and adjust positional data **************************** D149 LDA #&FF ;A=&FF D14B BNE &D150 ;then &D150 D14D LDA &031F ;get first parameter in plot D150 STA &DA ;store in &DA D152 LDY #&02 ;Y=2 D154 JSR &D176 ;set up vertical coordinates/2 D157 JSR &D1AD ;/2 again to convert 1023 to 0-255 for internal use ;this is why minimum vertical plot separation is 4 D15A LDY #&00 ;Y=0 D15C DEX ;X=x-2 D15D DEX ; D15E JSR &D176 ;set up horiz. coordinates/2 this is OK for mode0,4 D161 LDY &0361 ;get number of pixels/byte (-1) D164 CPY #&03 ;if Y=3 (modes 1 and 5) D166 BEQ &D16D ;D16D D168 BCS &D170 ;for modes 0 & 4 this is 7 so D170 D16A JSR &D1AD ;for other modes divide by 2 twice D16D JSR &D1AD ;divide by 2 D170 LDA &0356 ;get screen display type D173 BNE &D1AD ;if not 0 (modes 3-7) divide by 2 again D175 RTS ;and exit ;for mode 0, 1 division 1280 becomes 640 = horizontal resolution ;for mode 1, 2 divisions 1280 becomes 320 = horizontal resolution ;for mode 2, 3 divisions 1280 becomes 160 = horizontal resolution ;for mode 4, 2 divisions 1280 becomes 320 = horizontal resolution ;for mode 5, 3 divisions 1280 becomes 160 = horizontal resolution ********** calculate external coordinates in internal format *********** ;on entry X is usually &1E or &20 D176 CLC ;clear carry D177 LDA &DA ;get &DA D179 AND #&04 ;if bit 2=0 D17B BEQ &D186 ;then D186 to calculate relative coordinates D17D LDA &0302,X ;else get coordinate D180 PHA ; D181 LDA &0303,X ; D184 BCC &D194 ;and goto D194 D186 LDA &0302,X ;get coordinate D189 ADC &0310,Y ;add cursor position D18C PHA ;save it D18D LDA &0303,X ; D190 ADC &0311,Y ;add cursor D193 CLC ;clear carry D194 STA &0311,Y ;save new cursor D197 ADC &030D,Y ;add graphics origin D19A STA &0303,X ;store it D19D PLA ;get back lo byte D19E STA &0310,Y ;save it in new cursor lo D1A1 CLC ;clear carry D1A2 ADC &030C,Y ;add to graphics orgin D1A5 STA &0302,X ;store it D1A8 BCC &D1AD ;if carry set D1AA INC &0303,X ;increment hi byte as you would expect! D1AD LDA &0303,X ;get hi byte D1B0 ASL ; D1B1 ROR &0303,X ;divide by 2 D1B4 ROR &0302,X ; D1B7 RTS ;and exit ***** calculate external coordinates from internal coordinates************ D1B8 LDY #&10 ;Y=10 D1BA JSR &D488 ;copy 324/7 to 310/3 i.e.current graphics cursor ;position to position in external values D1BD LDX #&02 ;X=2 D1BF LDY #&02 ;Y=2 D1C1 JSR &D1D5 ;multiply 312/3 by 4 and subtract graphics origin D1C4 LDX #&00 ;X=0 D1C6 LDY #&04 ;Y=4 D1C8 LDA &0361 ;get number of pixels/byte D1CB DEY ;Y=Y-1 D1CC LSR ;divide by 2 D1CD BNE &D1CB ;if result not 0 D1CB D1CF LDA &0356 ;else get screen display type D1D2 BEQ &D1D5 ;and if 0 D1D5 D1D4 INY ; D1D5 ASL &0310,X ;multiply coordinate by 2 D1D8 ROL &0311,X ; D1DB DEY ;Y-Y-1 D1DC BNE &D1D5 ;and if Y<>0 do it again D1DE SEC ;set carry D1DF JSR &D1E3 ; D1E2 INX ;increment X D1E3 LDA &0310,X ;get current graphics position in external coordinates D1E6 SBC &030C,X ;subtract origin D1E9 STA &0310,X ;store in graphics position D1EC RTS ;and exit ************* compare X and Y PLOT spans ******************************** D1ED JSR &D40D ;Set X and Y spans in workspace 328/9 32A/B D1F0 LDA &032B ;compare spans D1F3 EOR &0329 ;if result -ve spans are different in sign so D1F6 BMI &D207 ;goto D207 D1F8 LDA &032A ;else A=hi byte of difference in spans D1FB CMP &0328 ; D1FE LDA &032B ; D201 SBC &0329 ; D204 JMP &D214 ;and goto D214 D207 LDA &0328 ;A = hi byte of SUM of spans D20A CLC ; D20B ADC &032A ; D20E LDA &0329 ; D211 ADC &032B ; D214 ROR ;A=A/2 D215 LDX #&00 ;X=0 D217 EOR &032B ; D21A BPL &D21E ;if positive result D21E D21C LDX #&02 ;else X=2 D21E STX &DE ;store it D220 LDA &C4AA,X ;set up vector address D223 STA &035D ;in 35D D226 LDA &C4AB,X ; D229 STA &035E ;and 35E D22C LDA &0329,X ;get hi byte of span D22F BPL &D235 ;if +ve D235 D231 LDX #&24 ;X=&24 D233 BNE &D237 ;jump to D237 D235 LDX #&20 ;X=&20 D237 STX &DF ;store it D239 LDY #&2C ;Y=&2C D23B JSR &D48A ;get X coordinate data or horizontal coord of ;curent graphics cursor D23E LDA &DF ;get back original X D240 EOR #&04 ;covert &20 to &24 and vice versa D242 STA &DD ; D244 ORA &DE ; D246 TAX ; D247 JSR &D480 ;copy 330/1 to 300/1+X D24A LDA &031F ;get plot type D24D AND #&10 ;check bit 4 D24F ASL ; D250 ASL ; D251 ASL ;move to bit 7 D252 STA &DB ;store it D254 LDX #&2C ;X=&2C D256 JSR &D10F ;check for window violations D259 STA &DC ; D25B BEQ &D263 ;if none then D263 D25D LDA #&40 ;else set bit 6 of &DB D25F ORA &DB ; D261 STA &DB ; D263 LDX &DD ; D265 JSR &D10F ;check window violations again D268 BIT &DC ;if bit 7 of &DC NOT set D26A BEQ &D26D ;D26D D26C RTS ;else exit ; D26D LDX &DE ;X=&DE D26F BEQ &D273 ;if X=0 D273 D271 LSR ;A=A/2 D272 LSR ;A=A/2 D273 AND #&02 ;clear all but bit 2 D275 BEQ &D27E ;if bit 2 set D27E D277 TXA ;else A=X D278 ORA #&04 ;A=A or 4 setting bit 3 D27A TAX ;X=A D27B JSR &D480 ;set 300/1+x to 330/1 D27E JSR &D42C ;more calcualtions D281 LDA &DE ;A=&DE EOR 2 D283 EOR #&02 ; D285 TAX ;X=A D286 TAY ;Y=A D287 LDA &0329 ;compare upper byte of spans D28A EOR &032B ; D28D BPL &D290 ;if signs are the same D290 D28F INX ;else X=X+1 D290 LDA &C4AE,X ;get vector addresses and store 332/3 D293 STA &0332 ; D296 LDA &C4B2,X ; D299 STA &0333 ; D29C LDA #&7F ;A=&7F D29E STA &0334 ;store it D2A1 BIT &DB ;if bit 6 set D2A3 BVS &D2CE ;the D2CE D2A5 LDA &C447,X ;get VDU section number D2A8 TAX ;X=A D2A9 SEC ;set carry D2AA LDA &0300,X ;subtract coordinates D2AD SBC &032C,Y ; D2B0 STA &DA ; D2B2 LDA &0301,X ; D2B5 SBC &032D,Y ; D2B8 LDY &DA ;Y=hi D2BA TAX ;X=lo=A D2BB BPL &D2C0 ;and if A+Ve D2C0 D2BD JSR &D49B ;negate Y/A D2C0 TAX ;X=A increment Y/A D2C1 INY ;Y=Y+1 D2C2 BNE &D2C5 ; D2C4 INX ;X=X+1 D2C5 TXA ;A=X D2C6 BEQ &D2CA ;if A=0 D2CA D2C8 LDY #&00 ;else Y=0 D2CA STY &DF ;&DF=Y D2CC BEQ &D2D7 ;if 0 then D2D7 D2CE TXA ;A=X D2CF LSR ;A=A/4 D2D0 ROR ; D2D1 ORA #&02 ;bit 1 set D2D3 EOR &DE ; D2D5 STA &DE ;and store D2D7 LDX #&2C ;X=&2C D2D9 JSR &D864 ; D2DC LDX &DC ; D2DE BNE &D2E2 ; D2E0 DEC &DD ; D2E2 DEX ;X=X-1 D2E3 LDA &DB ;A=&3B D2E5 BEQ &D306 ;if 0 D306 D2E7 BPL &D2F9 ;else if +ve D2F9 D2E9 BIT &0334 ; D2EC BPL &D2F3 ;if bit 7=0 D2F3 D2EE DEC &0334 ;else decrement D2F1 BNE &D316 ;and if not 0 D316 D2F3 INC &0334 ; D2F6 ASL ;A=A*2 D2F7 BPL &D306 ;if +ve D306 D2F9 STX &DC ; D2FB LDX #&2C ; D2FD JSR &D85F ;calculate screen position D300 LDX &DC ;get back original X D302 ORA #&00 ; D304 BNE &D316 ; D306 LDA &D1 ;byte mask for current graphics point D308 AND &D4 ;and with graphics colour byte D30A ORA (&D6),Y ;or with curent graphics cell line D30C STA &DA ;store result D30E LDA &D5 ;same again with next byte (hi??) D310 AND &D1 ; D312 EOR &DA ; D314 STA (&D6),Y ;then store it in current graphics line D316 SEC ;set carry D317 LDA &0335 ;A=&335/6-&337/8 D31A SBC &0337 ; D31D STA &0335 ; D320 LDA &0336 ; D323 SBC &0338 ; D326 BCS &D339 ;if carry set D339 D328 STA &DA ; D32A LDA &0335 ; D32D ADC &0339 ; D330 STA &0335 ; D333 LDA &DA ; D335 ADC &033A ; D338 CLC ; D339 STA &0336 ; D33C PHP ; D33D BCS &D348 ;if carry clear jump to VDU routine else D348 D33F JMP (&0332) ; ****** vertical scan module 1****************************************** D342 DEY ;Y=Y-1 D343 BPL &D348 ;if + D348 D345 JSR &D3D3 ;else d3d3 to advance pointers D348 JMP (&035D) ;and JUMP (&35D) ****** vertical scan module 2****************************************** D34B INY ;Y=Y+1 D34C CPY #&08 ;if Y<>8 D34E BNE &D348 ;then D348 D350 CLC ;else clear carry D351 LDA &D6 ;get address of top line of cuirrent graphics cell D353 ADC &0352 ;add number of bytes/character row D356 STA &D6 ;store it D358 LDA &D7 ;do same for hibyte D35A ADC &0353 ; D35D BPL &D363 ;if result -ve then we are above screen RAM D35F SEC ;so D360 SBC &0354 ;subtract screen memory size hi D363 STA &D7 ;store it this wraps around point to screen RAM D365 LDY #&00 ;Y=0 D367 JMP (&035D) ; ****** horizontal scan module 1****************************************** D36A LSR &D1 ;shift byte mask D36C BCC &D348 ;if carry clear (&D1 was +ve) goto D348 D36E JSR &D3ED ;else reset pointers D371 JMP (&035D) ;and off to do more ****** horizontal scan module 2****************************************** D374 ASL &D1 ;shift byte mask D376 BCC &D348 ;if carry clear (&D1 was +ve) goto D348 D378 JSR &D3FD ;else reset pointers D37B JMP (&035D) ;and off to do more D37E DEY ;Y=Y-1 D37F BPL &D38D ;if +ve D38D D381 JSR &D3D3 ;advance pointers D384 BNE &D38D ;goto D38D normally D386 LSR &D1 ;shift byte mask D388 BCC &D38D ;if carry clear (&D1 was +ve) goto D348 D38A JSR &D3ED ;else reset pointers D38D PLP ;pull flags D38E INX ;X=X+1 D38F BNE &D395 ;if X>0 D395 D391 INC &DD ;else increment &DD D393 BEQ &D39F ;and if not 0 D39F D395 BIT &DB ;else if BIT 6 = 1 D397 BVS &D3A0 ;goto D3A0 D399 BCS &D3D0 ;if BIT 7=1 D3D0 D39B DEC &DF ;else Decrement &DF D39D BNE &D3D0 ;and if not Zero D3D0 D39F RTS ;else return ; D3A0 LDA &DE ;A=&DE D3A2 STX &DC ;&DC=X D3A4 AND #&02 ;clear all but bit 1 D3A6 TAX ;X=A D3A7 BCS &D3C2 ;and if carry set goto D3C2 D3A9 BIT &DE ;if Bit 7 of &DE =1 D3AB BMI &D3B7 ;then D3B7 D3AD INC &032C,X ;else increment D3B0 BNE &D3C2 ;and if not 0 D3C2 D3B2 INC &032D,X ;else increment hi byte D3B5 BCC &D3C2 ;and if carry clear D3C2 D3B7 LDA &032C,X ;esle A=32C,X D3BA BNE &D3BF ;and if not 0 D3BF D3BC DEC &032D,X ;decrement hi byte D3BF DEC &032C,X ;decrement lo byte D3C2 TXA ;A=X D3C3 EOR #&02 ;invert bit 2 D3C5 TAX ;X=A D3C6 INC &032C,X ;Increment 32C/D D3C9 BNE &D3CE ; D3CB INC &032D,X ; D3CE LDX &DC ;X=&DC D3D0 JMP &D2E3 ;jump to D2E3 **********move display point up a line ********************************** D3D3 SEC ;SET CARRY D3D4 LDA &D6 ;subtract number of bytes/line from address of D3D6 SBC &0352 ;top line of current graphics cell D3D9 STA &D6 ; D3DB LDA &D7 ; D3DD SBC &0353 ; D3E0 CMP &034E ;compare with bottom of screen memory D3E3 BCS &D3E8 ;if outside screen RAM D3E5 ADC &0354 ;add screen memory size to wrap it around D3E8 STA &D7 ;store in current address of graphics cell top line D3EA LDY #&07 ;Y=7 D3EC RTS ;and RETURN D3ED LDA &0362 ;get current left colour mask D3F0 STA &D1 ;store it D3F2 LDA &D6 ;get current top line of graphics cell D3F4 ADC #&07 ;ADD 7 D3F6 STA &D6 ; D3F8 BCC &D3FC ; D3FA INC &D7 ; D3FC RTS ;and return D3FD LDA &0363 ;get right colour mask D400 STA &D1 ;store it D402 LDA &D6 ;A=top line graphics cell low D404 BNE &D408 ;if not 0 D408 D406 DEC &D7 ;else decrement hi byte D408 SBC #&08 ;subtract 9 (8 + carry) D40A STA &D6 ;and store in low byte D40C RTS ;return ********:: coordinate subtraction *************************************** D40D LDY #&28 ;X=&28 D40F LDX #&20 ;Y=&20 D411 JSR &D418 ; D414 INX ;X=X+2 D415 INX ; D416 INY ;Y=Y+2 D417 INY ; D418 SEC ;set carry D419 LDA &0304,X ;subtract coordinates D41C SBC &0300,X ; D41F STA &0300,Y ; D422 LDA &0305,X ; D425 SBC &0301,X ; D428 STA &0301,Y ; D42B RTS ;and return D42C LDA &DE ;A=&DE D42E BNE &D437 ;if A=0 D437 D430 LDX #&28 ;X=&28 D432 LDY #&2A ;Y=&2A D434 JSR &CDDE ;exchange 300/1+Y with 300/1+X ;IN THIS CASE THE X AND Y SPANS! D437 LDX #&28 ;X=&28 D439 LDY #&37 ;Y=&37 D43B JSR &D48A ;copy &300/4+Y to &300/4+X ;transferring X and Y spans in this case D43E SEC ;set carry D43F LDX &DE ;X=&DE D441 LDA &0330 ;subtract 32C/D,X from 330/1 D444 SBC &032C,X ; D447 TAY ;partial answer in Y D448 LDA &0331 ; D44B SBC &032D,X ; D44E BMI &D453 ;if -ve D453 D450 JSR &D49B ;else negate Y/A D453 STA &DD ;store A D455 STY &DC ;and Y D457 LDX #&35 ;X=&35 D459 JSR &D467 ;get coordinates D45C LSR ; D45D STA &0301,X ; D460 TYA ; D461 ROR ; D462 STA &0300,X ; D465 DEX ; D466 DEX ; D467 LDY &0304,X ; D46A LDA &0305,X ; D46D BPL &D47B ;if A is +ve RETURN D46F JSR &D49B ;else negate Y/A D472 STA &0305,X ;store back again D475 PHA ; D476 TYA ; D477 STA &0304,X ; D47A PLA ;get back A D47B RTS ;and exit ; D47C LDA #&08 ;A=8 D47E BNE &D48C ;copy 8 bytes D480 LDY #&30 ;Y=&30 D482 LDA #&02 ;A=2 D484 BNE &D48C ;copy 2 bytes D486 LDY #&28 ;copy 4 bytes from 324/7 to 328/B D488 LDX #&24 ; D48A LDA #&04 ; ***********copy A bytes from 300,X to 300,Y *************************** D48C STA &DA ; D48E LDA &0300,X ; D491 STA &0300,Y ; D494 INX ; D495 INY ; D496 DEC &DA ; D498 BNE &D48E ; D49A RTS ;and return ************* negation routine ****************************************** D49B PHA ;save A D49C TYA ;A=Y D49D EOR #&FF ;invert D49F TAY ;Y=A D4A0 PLA ;get back A D4A1 EOR #&FF ;invert D4A3 INY ;Y=Y+1 D4A4 BNE &D4A9 ;if not 0 exit D4A6 CLC ;else D4A7 ADC #&01 ;add 1 to A D4A9 RTS ;return ; D4AA JSR &D85D ;check window boundaries and set up screen pointer D4AD BNE &D4B7 ;if A<>0 D4B7 D4AF LDA (&D6),Y ;else get byte from current graphics cell D4B1 EOR &035A ;compare with current background colour D4B4 STA &DA ;store it D4B6 RTS ;and RETURN D4B7 PLA ;get back return link D4B8 PLA ; D4B9 INC &0326 ;increment current graphics cursor vertical lo D4BC JMP &D545 ;