Räumliche Grafik auf dem C 64
Gerade auf dem Gebiet von Film- und Fernsehproduktionen werden Computergrafiken immer öfter eingesetzt, da es hiermit möglich ist, Dinge zu zeigen, die mit herkömmlichen Methoden nicht gefilmt werden konnten.

Ob nun Raumschiffe gezeigt werden, die eigentlich unmögliche Bewegungen durchführen oder der »Anflug« eines Logos (wie zum Beispiel die »1«bei der ARD), die Realisierung vereinfacht sich durch den Einsatz von Grafik-Computern enorm. Diese müssen jedoch — bedingt durch die anfallenden Datenmengen — enorm schnell sein, so daß zur Zeit nur »Supercomputer« Echtzeitsimulation erlauben.
Wenn man sich allerdings etwas mehr Zeit läßt, dann reicht auch ein Homecomputer wie der C 64 aus, um solche Grafiken (mit bestimmten Einschränkungen) zu erzeugen.
Das hier vorgestellte Grafikpaket geht über das übliche Punkte setzen und Linien ziehen weit hinaus. Es erlaubt die Erzeugung von plastischen Bildern ohne größeren Aufwand, wie zum Beispiel in Bild 1 und 2 dargestellt.


Das eigentliche Grafikpaket nimmt nur 3 KByte (I) des Speichers in Anspruch und steht im Bereich ab $C000. Damit bleibt der Basic-Speicher für die eigentlichen Programme frei. Auch das DOS 5.1 von Commodore kann parallel zu den Grafikroutinen verwendet werden. Aufgrund der Kompaktheit dieses Grafikpakets mußten allerdings bestimmte Dinge, wie zum Beispiel die Abfrage auf legale Koordinaten, in den Hintergrund treten; die Software fängt also solche Fehler nicht ab. Das macht das Schreiben eines eigenen Programms zwar etwas komplizierter, hat man aber erst einmal alle Fehler beseitigt, so würde eine Fehlerabfrage den Ablauf nur verlangsamen.
Beginnen wir mit den Grundlagen zur Erzeugung der Grafik. Da stellt sich zunächt einmal die Frage, wie man die verschiedenen Helligkeitswerte und Schattierungen eines darzustellenden Objektes berechnet. Danach müssen diese verschiedenen Grauwerte in einzelne Punkte umgesetzt werden, denn auf dem HiRes-Bildschirm können diese ja nur gesetzt und gelöscht werden. Dazu muß die gesamte Software selbst geschrieben werden, da der C 64 diese Art der Grafik vom Betriebssystem her nicht unterstützt.
Schnelle Rechenroutinen
Das Maschinenprogramm, das für den Aufbau der Grafik zuständig ist, besteht aus mehreren Unterprogrammen. Beginnen wollen wir mit einem Unterprogrammpaket, das für schnelles Rechnen notwendig ist.
Integer Arithmetik (Listing 1)
Diese Unterroutinen stellen schnelle Algorithmen für Multiplikation, Division, Wurzelziehen und Zufallszahlen zur Verfügung. Diese sind zwar schon im normalen Basic-Interpreter vorhanden, für unsere Anwendung sind sie jedoch aus Geschwindigkeitsgründen ungeeignet. Die Basic-Routinen sind nämlich nicht auf Geschwindigkeit, sondern auf Kürze optimiert worden, wie zum Beispiel die Funktion SQR. Die Wurzelberechnung in Basic teilt den Logarithmus durch 2 und potenziert das Ergebnis anschließend wieder. Das hat den Vorteil, daß der Interpreter auf bereits vorhandene Unterprogramme zugreifen kann, aber den Nachteil, daß diese Berechnungsweise relativ langsam ist. Wenn man für alle 64000 Bildschirmpunkte die Quadratwurzel mit den vorhandenen Routinen berechnen würde, ergäbe sich eine Zeichenzeit von mehr als einer Stunde (und dies trotz Maschinenspracheprogramm)! Man benötigt diese Berechnung zwar nicht für jeden Punkt, aber gerade bei der Berechnung der Schattierungswerte spielt die Quadratwurzel eine große Rolle. Eine Möglichkeit, die Wurzelberechnung zu beschleunigen bietet die Newton-Methode, mit der man Fließkommawurzeln in einem Bruchteil der sonst benötigten Zeit berechnen kann. Da wir, um die einzelnen Grafikpunkte zu adressieren, nur ganze Zahlen benötigen, beschleunigt sich die Abarbeitungszeit nochmals. Auch die Routine für die Erzeugung von Zufallszahlen, die später bei der »Random«-Schattierung erforderlich ist, wurde neu geschrieben.
Grafik Utilities (Listing 2)
Die nächste Unterprogrammsammlung beinhaltet Basisroutinen für die Verwaltung der Bitmap wie zum Beispiel löschen, Farbe setzen und Punkte plotten. Diese Unterroutinen sind als einzige Commodore 64-spezifisch, so daß man — möchte man das Programm auf andere 6502-Computer übertragen — nur diese an das jeweilige Gerät anpassen muß.
Ferner wurden noch zwei Schattierungsroutinen »SHADE« und »RSHADE« implementiert. »SHADE« arbeitet im Prinzip ganz einfach: Man definiert eine 8 x 8 Graustufenmatrix, in der Werte von 0 bis 63 enthalten sind (Tabelle 1). Mit Hilfe dieser Daten wird nun ein — ebenfalls 8 x 8 Pixel großes — Feld erstellt, daß dann an einer bestimmten Stelle in den HiRes-Bildschirm kopiert wird. Um eine gleichmäßige Grauschattierung zu erreichen, müssen die Pixels auch möglichst einen gleichmäßigen Abstand voneinander haben. Wenn das Programm nun einen Grauwert in die Grafik setzen will, so übergibt es einfach einen Wert zwischen 0 und 63 an diese Unterroutine. Nun werden innerhalb dieser Matrix die einzelnen Punkte der Reihe nach gesetzt, also zuerst der Punkt mit der Nummer 0 (oben links), dann 1 (4. von links und 4. von oben) und so weiter. Also, je größer die Zahl ist, desto mehr Punkte werden gesetzt (und um so dunkler wird das Ganze). Durch diese festgelegte Reihenfolge wird sichergestellt, daß die Schattierung gleichmäßig ist. Die RSHADE-Unterroutine hat genau die gleiche Aufgabe, sorgt aber für etwas ungleichmäßigere — durch den Zufallsgenerator gesteuerte — Grauwerte.
0 | 8 | 53 | 61 | 2 | 10 | 55 | 63 |
16 | 24 | 37 | 45 | 18 | 26 | 39 | 47 |
49 | 57 | 4 | 12 | 51 | 59 | 6 | 14 |
33 | 41 | 20 | 28 | 35 | 43 | 22 | 30 |
3 | 11 | 54 | 62 | 1 | 9 | 52 | 60 |
19 | 27 | 38 | 46 | 17 | 25 | 36 | 44 |
50 | 58 | 7 | 15 | 48 | 56 | 5 | 13 |
34 | 42 | 23 | 31 | 32 | 40 | 21 | 29 |
Ein weiteres zu lösendes Problem ist das etwas merkwürdige rechteckige Bildschirmformat des C 64. Die Auflösung von 320 x 200 Punkten entspricht einem Teilungsverhältnis von 8:5, wodurch es bei einem normalen Bildschirm — mit einem Verhältnis von 4:3 — zu einer horizontalen Verzerrung kommen kann (eine Kugel würde dann etwa wie ein plattgedrückter Ball aussehen). Die Unterroutine »SCALE« (in Listing 2) sorgt für diese darstellungs- und maßstabsgerechte Aufbereitung der Koordinaten.
Linien und Facettenzeichnen
Die Routinen in Listing 3 komplettieren die elementaren Grafik-Funktionen für das Ziehen von Linien und das Zeichnen von schattierten Polygonnetzen. Ein solches räumliches Polygonnetz ist in Bild 3 zu sehen; es besteht nur aus aneinander gesetzten und entsprechend schattierten Dreiecken. Diese Figuren können einfacher und schneller gezeichnet werden, da die Schattierung auf ebenen Flächen einfacher darzustellen ist als auf gekrümmten. Neben der üblichen Darstellungsweise (in der geschlossenen, schattierten Form) ist auch die Zeichnung von Grafiken ohne verdeckte Linien möglich.

Mit diesen Routinen gerüstet, können wir uns nun auf das eigentliche Shape-Unterprogramm konzentrieren, mit dem es möglich ist, gekrümmte, schattierte Figuren in kurzer Zeit zu erstellen.
Hier geht es wiederum als erstes um die Berechnung der verschiedenen Oberflächenreflexe, Brechungen, Streuungen und Absorptionen des Lichtes auf einer Oberfläche. Um diese, teilweise sehr komplizierten Berechnungenn, zu vereinfachen, geht man einen anderen Weg: Man beschränkt sich auf einige einfache symmetrische Figuren (Bild 4), aus denen alle zu zeichnenden Objekte zusammengesetzt werden. Weiterhin werden die Figuren nur in der Frontsicht, also von vorn, dargestellt; Drehungen sind nicht möglich. Durch diese Einschränkungen braucht man bei der Programmierung nicht auf komplizierte Vektorberechnungen zurückzugreifen.

Für die Berechnung des Lichteinfalls stelle man sich einfach eine Lampe vor, die an der rechten Schulter des Beobachters angebracht ist und das Objekt von dieser Position anleuchtet. Dementsprechend errechnet das Programm die Helligkeitswerte für jeden Punkt des Objektes. Ein Flag (Adresse 898) dient dazu, den Standort der »Lampe« (0= Frontbeleuchtung, 1 = Beleuchtung von hinten) festzulegen.
Zeichenroutinen für Shapes
Listing 4 beinhaltet eine Sammlung von Routinen, die die acht Grundshapes (siehe Bild 4) zeichnen. Da dieses Unterprogramm auf die — an den C 64 angepaßten — Lower-Level-Routinen der Grafik-Utilities (Listing 2) zugreift, ist es selbst nicht vom jeweiligen Computer abhängig. Zusammen mit dem, in Listing 5 abgebildeten Programm, wird der Kontakt zum Basic hergestellt. Die Übergabe der Parameter geschieht mittels »SYS«-Befehl:
SYS <KOMMANDO>, <PARAM. 1,>, <PARAM. 2>, …, wobei <KOMMANDO> die Adresse des jeweiligen Grafikbefehls ist (Tabelle 2 zeigt die komplette Befehlsübersicht dieses Grafikprogramms). Über <PARAMETER 1> und <PARAMETER 2> müssen die Koordinaten des Shapes angegeben werden, wobei zu beachten ist, daß der Ursprung (dort wo die X- und Y-Koordinate null ist) in der linken unteren Bildschirmecke liegt. Die einzusetzenden Werte gehen in der Horizontalen von 0 bis 255, in der Vertikalen von 0 bis 239.
Grafikspeicher: | 40960-48959 |
Farbspeicher. | 33792-34791 |
Shape-Fenster | |
893: | Linker Rand |
894: | Rechter Rand |
895; | Unterer Rand |
896: | Oberer Rand |
Style Flags | |
838: | Schattierungsart (0 = zufällig, 1 = Halbton) |
839: | Skalierungsflag (0 = normal 1:1, 1 = skaliert 4:3) |
868: | Eck Flag bei Polygonen (0 = Normal, 1 = zeichnet Linien an den Ecken) |
871: | Eckenmodus (0 = zeichnet Linie, 1 = löscht Rand) |
898: | Beleuchtungsflag (0 = von vorne, 1 = von hinten) |
Funktionsadressen | |
49378: | Auf den Grafikmodus umschalten |
49411: | Zurück zum Textbildschirm |
51979: | Bitmap löschen |
52001: | Bitmap färben |
52023: | PLOT (Parameter X,Y) setzt einen Punkt |
52026: | UNPLOT löscht einen Punkt mit den Koordinaten X und Y |
52049: | LINE (Parameter X1,Y1,X2,X2) zieht Linie von / bis |
52052: | FACET X1,Y1,X2,Y2,X3,Y3,SA zeichnet dreieckige Facetten mit den Koordinaten X1,Y1, X2,... und schattiert sie (SA: 0 = schwarz, 64 = weiß) |
Shapes | |
52119: | Kugel |
52141: | Ring |
52150: | vertikaler Zylinder |
52153: | horizontaler Zylinder |
52186: | vertikaler Ring |
52189: | horizontaler Ring |
52203: | vertikale Rolle |
52206: | horizontale Rolle |
Alle Shapes, mit Ausnahme der Kugel, können durch die Eingabe von insgesamt vier Parametern in ihrer Position und Form beeinflußt werden. Die ersten zwei bestimmen, wie oben erläutert, die Koordinaten des Figurmittelpunktes. Mit dem dritten und vierten Paramter kann man die Verzerrung in X- und Y-Richtung einstellen. Doch hier ist Vorsicht geboten, denn der X-Wert sollte hierbei immer größer als der Y-Wert sein, sonst zeichnet das Programm unerwünschte Figuren.
Eine weitere Besonderheit sind die Shape-Fenster. Damit ist es möglich, auch einzelne Teile eines Shapes auf dem Bildschirm zu bringen. Diese Funktion wurde zum Beispiel bei der Erstellung der Grafik in Bild 1 verwendet. Der Henkel dieser Kafffeetasse ist aus drei verschiedenen Shapes zusammengesetzt, die mit Hilfe des Fensters in ihrer Ausdehnung eingeschränkt wurden. Diesen Begrenzungsfenstern sind die Adressen 893 bis 896 zugeordnet, wobei sich die POKE-Werte auf den Mittelpunkt der Figur beziehen.
Die Kommandos, um die Bitmap zu löschen oder mit Punkten zu füllen, benötigen auch alle nur einen Parameter. So sieht zum Beispiel das Kommando zum Initialisieren des Farbspeichers so aus:
POKE 52001,16*DC + BC
wobei DC die Farbe der zu setzenden Punkte und BC die Hintergrundfarbe ist. Auch Texte können nach Wunsch auf dem Grafikbildschirm ausgegeben werden. Die dafür zuständigen Routinen sind in Listing 2 enthalten.
Die in Listing 10 und 11 abgedruckten Demonstrationsprogramme sollen helfen, die Arbeitsweise und die Kombinationsmöglichkeiten der einzelnen Shapes aufzuzeigen. Auch alle hier gezeigten Bilder stammen von diesem Programm. Die Bilder stehen im Speicher übrigens »unter« dem Basic-ROM im Bereich zwischen $A000 und $BFFF.
Um den Platz für das DOS 5.1 freizuhalten, wurde das Grafikpaket in zwei Teile aufgespalten. Der eine Teil mit dem Namen GRAPHICS (Listing 8) befindet sich im Bereich zwischen $C000 und $CBFC. Der zweite Teil, auf den im folgenden noch kurz eingegangen werden soll, muß nach Adresse $CF59 geladen werden. Dieser Programmteil enthält eine schnelle Sortierroutine (Listing 6) und ermöglicht die Darstellung von Text auf dem Grafikbildschirm (Listing 7). Die beiden Unterprogramme sind in dem MSE-Listing 9 zusammengefaßt worden und müssen gemeinsam mit »GRAPHICS« in den Speicher geladen werden.
Hinweise zum Abtippen
Sie müssen als erstes die MSE-Listings 8 und 9 eingeben und anschließend natürlich auch abspeichern. Die Listings 1 bis 7 dienen nur zur Dokumentation und brauchen nicht eingegeben werden. Nachdem Sie auch die Demos abgetippt und auf Diskette oder Band gespeichert haben, müssen die einzelnen Programmteile nacheinander in den Speicher geladen werden. Begonnen wird mit GRAPHICS, das mit LOAD-"GRAPHICS",8,1 in den Speicher gelesen werden muß. Nachdem man anschließend NEW eingegeben hat, muß das zweite Maschinenprogramm, wie oben, geladen werden (auch hier das NEW nicht vergessen). Anschließend kann wahlweise eines der beiden Demonstrationsprogramme (Listing 10 oder11) geladen und ganz normal gestartet werden.
(Richard Rylander/Christoph Sauer/ev)
; INTEGER ARITHMETIC ROUTINES ; ; RICHARD L. RYLANDER 8/12/84 ; ; REVISED 10/29/84 TO ADD FULL DOUBLE ; PRECISION ARGUMENTS IN DIVIDE ROUTINE ; ;***************************************** ; ; USE PAGE ZERO LOCATIONS WHERE POSSIBLE FOR ; ITERATIVE PROCEDURE WORK SPACE ; MLPCND =$AC ; MULTIPLICAND MLPLER =$AD ; MULTIPLIER PROD =$AE ; PRODUCT ; DVDND =$FD ; DIVIDEND/QUOTIENT DVSOR =$FB ; DIVISOR RMNDR =$B4 ; REMAINDER ; RADCND =$AC ; RADICAND ROOT =$033C ; SQUARE ROOT ; TEMP =$FB ; ; SET UP SEED VALUES FOR PSEUDO-RANDOM NUMBERS *=$C000 RNDM .BYTE $FF,$55 RTEMP .BYTE $00,$00 ; ; ;***************************************** ; ; MULTIPLY SINGLE PRECISION MULTIPLICAND ; BY SINGLE PRECISION MULTIPLIER GIVING ; DOUBLE PRECISION PRODUCT (ENTER AT "MULT") ; ; SPECIAL CASE: ENTER AT "SQUARE" TO FIND ; SQUARE OF SIGNED 8-BIT NUMBER ; SQUARE LDA MLPCND ; ENTRY TO SQUARE BPL POSITV ; USE ABSOLUTE VALUE SEC ; NEGATE IF NEEDED LDA #$00 SBC MLPCND STA MLPCND POSITV STA MLPLER MULT LDA #$00 ; ENTRY TO MULTIPLY LDX #$08 MLOOP LSR MLPLER BCC NOADD CLC ADC MLPCND NOADD ROR A ROR PROD DEX BNE MLOOP STA PROD+1 RTS ; ;***************************************** ; ; DIVIDE DOUBLE PRECISION DIVIDEND ; BY DOUBLE PRECISION DIVISOR GIVING ; DOUBLE PRECISION QUOTIENT ; ; DIVIDEND IS REPLACED BY QUOTIENT ; IN THE PROCESS ; ; QUOTIENT IS ROUNDED TO NEAREST INTEGER ; DIVIDE LDA #$00 STA RMNDR STA RMNDR+1 LDX #$10 DLOOP ROL DVDND ROL DVDND+1 ROL RMNDR ROL RMNDR+1 SEC LDA RMNDR SBC DVSOR TAY LDA RMNDR+1 SBC DVSOR+1 BCC DECCNT STY RMNDR STA RMNDR+1 DECCNT DEX BNE DLOOP ROL DVDND ; CHECK IF REMAINDER ROL DVDND+1 ; IS >= 1/2 OF DIVIDEND ASL RMNDR ; FOR ROUNDING ROL RMNDR+1 BCS ROUND SEC LDA DVSOR SBC RMNDR LDA DVSOR+1 SBC RMNDR+1 BCS NOCHNG ROUND INC DVDND BNE NOCHNG INC DVDND+1 NOCHNG RTS ; ;***************************************** ; ; TAKE INTEGER SQUARE ROOT OF A ; DOUBLE PRECISION RADICAND GIVING ; SINGLE PRECISION ROOT ( <= REAL ROOT ) ; SQRT LDX #$08 LDA #$00 STA ROOT STA ROOT+1 STA TEMP STA TEMP+1 SQRT1 ASL ROOT ROL ROOT+1 INC ROOT ; ASSUME CURRENT LSB OF BNE NEXT1 ; ROOT WILL BE 1 INC ROOT+1 NEXT1 ASL RADCND ; SHIFT RADICAND LEFT ROL RADCND+1 ; TWICE INTO TEMP ROL TEMP ROL TEMP+1 ASL RADCND ROL RADCND+1 ROL TEMP ROL TEMP+1 SEC ; SUBTRACT ROOT ESTIMATE LDA TEMP ; FROM TEMP SBC ROOT TAY LDA TEMP+1 SBC ROOT+1 BCC RESTOR STA TEMP+1 ; SUBTRACTION OK STY TEMP INC ROOT BNE NEXT2 INC ROOT+1 NEXT2 DEX BNE SQRT1 JMP FINI RESTOR SEC ; IGNORE SUBTRACTION LDA ROOT ; AND RESET LSB OF ROOT SBC #$01 STA ROOT BCS NEXT3 DEC ROOT+1 NEXT3 DEX BNE SQRT1 FINI ROR ROOT+1 ; FINAL /2 TO NORMALIZE ROR ROOT RTS ; ;***************************************** ; ; GENERATE PSEUDO-RANDOM BYTES ; EXIT WITH P-R BYTE IN ACCUM. ; RANDOM LDA RNDM STA RTEMP EOR RNDM+1 ROL RTEMP+1 ; RTEMP+1 PRESERVES ROR A ; CARRY BIT FOR CYCLING ROR RTEMP+1 ; RANDOM NUMBERS STA RNDM LDA RTEMP STA RNDM+1 RTS .END
; GRAPHICS UTILITIES ; ; RICHARD L. RYLANDER 11/4/84 ; ; LOAD ARITHMETIC UTILITIES FIRST ; RAM=$033E ORIGIN=$C0E2 ; MLPCND=$AC ; MULTIPLICAND (S) MLPLER=$AD ; MULTIPLIER (S) PROD=$AE ; PRODUCT (D) MULT=$C011 ; CALL FOR MULTIPLY ; RNDM=$C000 ; RANDOM NUMBER RANDOM=$C0C8 ; CALL FOR RANDOM ; NOTE - A CALL TO 'RANDOM' LEAVES A RANDOM BYTE ; IN THE ACCUMULATOR ; *=RAM PLTFLG *=*+1 ; PLOT/UNPLOT FLAG XPLT *=*+2 ; ABSOLUTE PLOT COORD YPLT *=*+1 ; ABSOLUTE PLOT COORD VIC1 *=*+1 ; REGISTER STORAGE VIC2 *=*+1 ; REGISTER STORAGE VALUE *=*+2 ; FINAL NORMALIZED SHADE VALUE HTORRN *=*+1 ; SHADE FLAG, 1=HALFTONE NOSCAL *=*+1 ; SCALE FLAG, 1=NO SCALE TEMP *=*+2 ; TEMPORARY STORAGE ; *=ORIGIN ; ;***************************************** ; ; TURN ON BIT MAP GRAPHICS MODE, ; SAVING REGISTER VALUES FOR ; RETURN TO TEXT MODE LATER. ; GRFON LDA $D011 ORA #$20 STA $D011 LDA $DD00 STA VIC1 AND #$FC ORA #$01 STA $DD00 LDA $D018 STA VIC2 LDA #$19 STA $D018 RTS ; ;***************************************** ; ; RETURN TO TEXT SCREEN ; GRFOFF LDA $D011 AND #$DF STA $D011 LDA VIC1 STA $DD00 LDA VIC2 STA $D018 RTS ; ;***************************************** ; ; FILL COLOR MAP FOR BLACK DOTS ON WHITE ; COLOR LDA #$01 ; POKE NEW COLORS HERE LDX #0 COL1 STA $8400,X STA $8500,X STA $8600,X STA $8700,X DEX BNE COL1 RTS ; ;***************************************** ; ; CLEAR HI-RES GRAPHICS SCREEN ; CLEAR LDA #$A0 STA $FC LDY #0 STY $FB LDA #0 ; CLEAR BYTE LDX #$20 CLRLP STA ($FB),Y INY BNE CLRLP INC $FC DEX BNE CLRLP RTS ; ;***************************************** ; ; PLOT AND UNPLOT POINTS ON HI-RES GRAPHICS ; SCREEN. ABSOLUTE X AND Y SCREEN COORDINATES ; ARE POKED INTO XPLT, XPLT+1, AND YPLT ; PLOT LDA #0 .BYTE $2C UNPLOT LDA #$80 STA PLTFLG LDA $01 ; BASIC ROM OUT AND #$FE STA $01 SEC ; INVERT Y COORDINATE TO LDA #$C7 ; PUT ORIGIN IN LOWER LEFT SBC YPLT ; CORNER OF SCREEN TAX ; (199.-YPLT) LSR A LSR A LSR A TAY LDA TABLE1,Y STA $FB LDA TABLE2,Y STA $FC TXA AND #$07 CLC ADC $FB STA $FB LDA XPLT AND #$F8 ADC $FB STA $FB LDA XPLT+1 ADC $FC STA $FC LDA #$A0 ADC $FC STA $FC LDA XPLT AND #$07 EOR #$07 TAX LDA #$01 PLOTLP DEX BMI PLOT2 ASL A BNE PLOTLP PLOT2 LDY #0 BIT PLTFLG BPL NOPLOT EOR #$FF AND ($FB),Y .BYTE $2C NOPLOT ORA ($FB),Y STA ($FB),Y LDA $01 ; BASIC ROM RESTORED ORA #$01 STA $01 RTS ; TABLE1 .BYTE $00,$40,$80,$C0 .BYTE $00,$40,$80,$C0 .BYTE $00,$40,$80,$C0 .BYTE $00,$40,$80,$C0 .BYTE $00,$40,$80,$C0 .BYTE $00,$40,$80,$C0,$00 ; TABLE2 .BYTE $00,$01,$02,$03 .BYTE $05,$06,$07,$08 .BYTE $0A,$0B,$0C,$0D .BYTE $0F,$10,$11,$12 .BYTE $14,$15,$16,$17 .BYTE $19,$1A,$1B,$1C,$1E ; ;***************************************** ; ; SHADING BY HYBRID DITHER/DOT-GROWTH ; SHADE LDA XPLT ; USE BITS -----*** AND #$07 ; OF 'X' SCREEN COORD STA TEMP LDA YPLT ; AND BITS -----*** AND #$07 ; OF 'Y' SCREEN COORD ASL A ; SHIFTED INTO --***--- ASL A ; POSITION TO DETERMINE ASL A ; 6-BIT OFFSET IN ORA TEMP ; THRESHOLD TABLE TAX LDA THRESH,X ; SCREEN-POSITION-WEIGHTED CMP VALUE ; THRESHOLD VALUE BPL GREATR JMP UNPLOT GREATR JMP PLOT ; ;***************************************** ; ; SHADING BY RANDOM HALFTONE ; RSHADE JSR RANDOM LSR A ; REDUCE RANDOM BYTE LSR A ; TO 6 BITS FOR SHADE CMP VALUE ; VALUE COMPARISON BPL MORE JMP UNPLOT MORE JMP PLOT ; ;***************************************** ; ; PLOT A POINT WEIGHTED BY SHADING SCHEME ; AND SHADE VALUE ; CHECK 'NOSCAL' FLAG FOR SCALING OF Y COORD ; CHECK 'HTORRN' FLAG FOR TYPE OF SHADING ; PLTSHD LDA NOSCAL BEQ NORM ; ; SCALE Y FROM 0-239 PSEUDO-COORDINATES ; TO 0-199 TRUE SCREEN COORDINATES BY ; Y = (Y+1)*213/256 ; SCALE LDY YPLT INY STY MLPLER LDA #$D5 ; 213. STA MLPCND JSR MULT ; RETURN WITH HIGH BYTE STA YPLT ; IN ACCUMULATOR NORM LDA HTORRN BEQ RPLT JMP SHADE RPLT JMP RSHADE ; ; ; THRESH .BYTE $00,$08,$35,$3D .BYTE $02,$0A,$37,$3F .BYTE $10,$18,$25,$2D .BYTE $12,$1A,$27,$2F .BYTE $31,$39,$04,$0C .BYTE $33,$3B,$06,$0E .BYTE $21,$29,$14,$1C .BYTE $23,$2B,$16,$1E .BYTE $03,$0B,$36,$3E .BYTE $01,$09,$34,$3C .BYTE $13,$1B,$26,$2E .BYTE $11,$19,$24,$2C .BYTE $32,$3A,$07,$0F .BYTE $30,$38,$05,$0D .BYTE $22,$2A,$17,$1F .BYTE $20,$28,$15,$1D .END
; FACET - DRAW SHADED TRIANGULAR FACETS ; AND STRAIGHT LINES. ; ; RICHARD L. RYLANDER 11/4/84 ; ; LOAD "ARITH.HEX" AND "GRAPH.HEX" ; BEFORE USING ; ORIGIN = $C26F RAM = $034A ; XPLT = $033F YPLT = $0341 NORM = $C224 NOSCAL = $0347 PLOT = $C143 UNPLOT = $C146 ; MLPCND = $AC MLPLER = $AD PROD = $AE MULT = $C011 ; DVDND = $FD DVSOR = $FB QUOT = $FD DIVIDE = $C025 ; *=RAM ; XMIN *=*+2 YMIN *=*+1 XMID *=*+2 YMID *=*+1 XMAX *=*+2 YMAX *=*+1 YTOP *=*+1 YBOT *=*+1 YBASE *=*+1 DLTAX1 *=*+2 DLTAX2 *=*+1 DLTAX3 *=*+1 DELTAX *=*+1 DLTAY1 *=*+1 DLTAY2 *=*+1 DLTAY3 *=*+1 DELTAY *=*+1 XDIFF *=*+1 FLAG1 *=*+1 FLAG2 *=*+1 FLAG3 *=*+1 FLAG *=*+1 EDGES *=*+1 ERROR *=*+2 MODE *=*+1 COUNT *=*+2 ; ; *=ORIGIN ; ;***************************************** ; ; SCALE ALL Y COORDINATES FROM 0..239 ; PSUEDO-COORDINATE RANGE TO 0..199 ; TRUE SCREEN COORDINATE RANGE ; SCALE LDY #6 LDA #$D5 STA MLPCND SCLP LDA YMIN,Y STA MLPLER JSR MULT STA YMIN,Y DEY DEY DEY BPL SCLP RTS ; ; ;***************************************** ; ; EXCHANGE 'MIN' AND 'MID' COORDINATES ; SWAP12 LDY #2 LOOP1 LDA XMIN,Y PHA LDA XMID,Y STA XMIN,Y PLA STA XMID,Y DEY BPL LOOP1 RTS ; ;***************************************** ; ; EXCHANGE 'MID' AND 'MAX' COORDINATES ; SWAP23 LDY #2 LOOP2 LDA XMID,Y PHA LDA XMAX,Y STA XMID,Y PLA STA XMAX,Y DEY BPL LOOP2 RTS ; ;***************************************** ; ; SORT COORDINATES ACCORDING TO X COMPONENTS ; SORTX LDX #2 SORTLP SEC LDA XMID SBC XMIN LDA XMID+1 SBC XMIN+1 BCS NOSWP1 JSR SWAP12 NOSWP1 DEX BEQ SORTED SEC LDA XMAX SBC XMID LDA XMAX+1 SBC XMID+1 BCS SORTLP JSR SWAP23 JMP SORTLP SORTED RTS ; ;***************************************** ; ; DRAW A LINE BETWEEN XMIN,YMIN AND XMID,YMID ; USING FAST DDA (DIGITAL DIFFERENTIAL ANALYZER) ; TECHNIQUE ; LINE LDA #2 ; ENSURE XMAX IS STA XMAX+1 ; LARGEST BEFORE JSR SORTX ; ORDERING 'MIN' AND 'MID' LDA NOSCAL BEQ OUTLN JSR SCALE OUTLN JSR FINDXY ; ENTRY POINT TO LDA XMIN ; OUTLINE FACETS STA XPLT LDA XMIN+1 STA XPLT+1 LDA YMIN STA YPLT LDA DLTAX1+1 ; CHECK FOR DX>DY BNE STEPX SEC LDA DLTAX1 SBC DLTAY1 BCS STEPX STEPY LDA DLTAY1 STA ERROR STA COUNT LSR ERROR SEC LDA DLTAX1 SBC ERROR STA ERROR LDA DLTAX1+1 SBC #0 STA ERROR+1 INC COUNT LNLP1 LDA MODE ; 0 = DRAW, 1 = ERASE BNE ERASE1 JSR PLOT JMP SK1 ERASE1 JSR UNPLOT SK1 LDA FLAG1 ; 0 = POSITIVE SLOPE BNE NSLOPE INC YPLT BNE SK2 ; ALWAYS BRANCH NSLOPE DEC YPLT SK2 BIT ERROR+1 BMI SK3 INC XPLT BNE NOINC1 INC XPLT+1 NOINC1 SEC LDA ERROR SBC DLTAY1 STA ERROR LDA ERROR+1 SBC #0 STA ERROR+1 SK3 CLC LDA ERROR ADC DLTAX1 STA ERROR LDA ERROR+1 ADC DLTAX1+1 STA ERROR+1 DEC COUNT BNE LNLP1 RTS ; STEPX LDA DLTAX1 STA ERROR STA COUNT LDA DLTAX1+1 STA ERROR+1 STA COUNT+1 LSR ERROR+1 ROR ERROR SEC LDA DLTAY1 SBC ERROR STA ERROR LDA #0 SBC ERROR+1 STA ERROR+1 LNLP2 LDA MODE BNE ERASE2 JSR PLOT JMP SKP1 ERASE2 JSR UNPLOT SKP1 INC XPLT BNE NOINC2 INC XPLT+1 NOINC2 BIT ERROR+1 BMI SKP3 LDA FLAG1 BNE NGSLP INC YPLT BNE SKP2 ; ALWAYS BRANCH NGSLP DEC YPLT SKP2 SEC LDA ERROR SBC DLTAX1 STA ERROR LDA ERROR+1 SBC DLTAX1+1 STA ERROR+1 SKP3 CLC LDA ERROR ADC DLTAY1 STA ERROR LDA ERROR+1 ADC #0 STA ERROR+1 SEC LDA COUNT SBC #1 STA COUNT BCS TEST DEC COUNT+1 TEST BIT COUNT+1 BPL LNLP2 RTS ; ;***************************************** ; DRAW A SHADED VERTICAL LINE AT ; XPLT FROM YTOP TO YBOT ; VLINE SEC ; MAKE SURE YTOP>YBOT LDA YTOP SBC YBOT BCS DRAW LDA YTOP PHA LDA YBOT STA YTOP PLA STA YBOT DRAW LDA YTOP STA YPLT JSR NORM ; PLOT A SHADE-WEIGHTED LDA YTOP ; PIXEL CHECKING ONLY CMP YBOT ; FOR SHADE STYLE BEQ DONE DEC YTOP JMP DRAW DONE RTS ; ;***************************************** ; ; FIND ENDPOINTS FOR VERTICAL LINES ; BETWEEN FACET EDGES ; ENDPTS LDA XDIFF STA MLPCND LDA DELTAY STA MLPLER JSR MULT STA DVDND+1 LDA PROD STA DVDND LDA #0 STA DVSOR+1 LDA DELTAX STA DVSOR JSR DIVIDE LDA FLAG BNE NEGSLP CLC LDA YBASE ADC QUOT BCC SKIP2 NEGSLP SEC LDA YBASE SBC QUOT SKIP2 RTS ; ;***************************************** ; ; FIND COORDINATE DIFFERENCES ; ; ALL "DELTA X" VALUES POSITIVE, ; SINGLE PRECISION (JUST LOWER BYTE) ; FINDXY SEC LDA XMID SBC XMIN STA DLTAX1 LDA XMID+1 SBC XMIN+1 STA DLTAX1+1 SEC LDA XMAX SBC XMID STA DLTAX2 SEC LDA XMAX SBC XMIN STA DLTAX3 ; ; USE ABS(DELTA Y) VALUES, ; FLAGS INDICATE SLOPE OF LIMIT LINES ; LDA #$00 STA FLAG1 STA FLAG2 STA FLAG3 SEC LDA YMID SBC YMIN BCS STORE1 INC FLAG1 LDA YMIN SBC YMID STORE1 STA DLTAY1 SEC LDA YMAX SBC YMID BCS STORE2 INC FLAG2 LDA YMID SBC YMAX STORE2 STA DLTAY2 SEC LDA YMAX SBC YMIN BCS STORE3 INC FLAG3 LDA YMIN SBC YMAX STORE3 STA DLTAY3 RTS ; ;***************************************** ; ; DRAW A SHADED TRIANGULAR FACET ; FACET JSR SORTX LDA NOSCAL BEQ YSOK JSR SCALE YSOK JSR FINDXY LDA XMIN STA XPLT LDA XMIN+1 STA XPLT+1 FCETLP SEC LDA XPLT SBC XMIN STA XDIFF LDA DLTAX1 BEQ CONT STA DELTAX LDA DLTAY1 STA DELTAY LDA FLAG1 STA FLAG LDA YMIN STA YBASE JSR ENDPTS STA YTOP LDA DLTAX3 BEQ CONT STA DELTAX LDA DLTAY3 STA DELTAY LDA FLAG3 STA FLAG JSR ENDPTS STA YBOT JSR VLINE LDA XPLT+1 CMP XMID+1 BNE NEXTX1 LDA XPLT CMP XMID BEQ CONT NEXTX1 INC XPLT BNE SKIP3 INC XPLT+1 SKIP3 JMP FCETLP CONT SEC LDA XPLT SBC XMIN STA XDIFF LDA DLTAX3 BEQ FINI STA DELTAX LDA DLTAY3 STA DELTAY LDA FLAG3 STA FLAG LDA YMIN STA YBASE JSR ENDPTS STA YBOT SEC LDA XPLT SBC XMID STA XDIFF LDA DLTAX2 BEQ FINI STA DELTAX LDA DLTAY2 STA DELTAY LDA FLAG2 STA FLAG LDA YMID STA YBASE JSR ENDPTS STA YTOP JSR VLINE LDA XPLT+1 CMP XMAX+1 BNE NEXTX2 LDA XPLT CMP XMAX BEQ FINI NEXTX2 INC XPLT BNE SKIP4 INC XPLT+1 SKIP4 JMP CONT FINI LDA EDGES BEQ FINISH JSR OUTLN JSR SWAP23 JSR OUTLN JSR SWAP12 JSR SWAP23 JSR SWAP12 JSR OUTLN FINISH RTS .END
; PRIMITIVE SOLID SHAPE DRAWING ; ; RICHARD L. RYLANDER 11/7/84 ; ; LOAD ARITHMETIC AND GRAPHIC UTILITIES FIRST ; ;***************************************** RAM=$036A ORIGIN=$C5EA ; MLPCND=$AC ; MULTIPLICAND (S) MLPLER=$AD ; MULTIPLIER (S) PROD=$AE ; PRODUCT (D) MULT=$C011 ; CALL FOR MULTIPLY ; DVDND=$FD ; DIVIDEND (D) DVSOR=$FB ; DIVISOR (D) QUOT=$FD ; QUOTIENT (D) DIVIDE=$C025 ; CALL FOR DIVIDE ; ARG=$AC ; ARGUMENT (S) SQR=$AE ; SQUARE OF ARG (D) SQUARE=$C004 ; CALL FOR SQUARE ; RADCND=$AC ; RADICAND (D) ROOT=$033C ; SQUARE ROOT (S) SQRT=$C064 ; CALL FOR SQRT ; RNDM=$C000 ; RANDOM NUMBER RANDOM=$C0C8 ; CALL FOR RANDOM ; NOTE - A CALL TO 'RANDOM' LEAVES A RANDOM BYTE ; IN THE ACCUMULATOR ; XPLT=$033F YPLT=$0341 NORM=$C224 PLTSHD=$C20F VALUE=$0344 ; FINAL NORMALIZED SHADE VALUE HTORRN=$0346 ; SHADE FLAG, 1=HALFTONE NOSCAL=$0347 ; SCALE FLAG, 1=NO SCALE ; *=RAM XCENT *=*+2 ; CENTER COORD XREL *=*+1 ; RELATIVE (TO CENTER) XSHD *=*+2 ; USED IN SHADE CALC YCENT *=*+1 ; CENTER COORD YREL *=*+1 ; RELATIVE (TO CENTER) YSHD *=*+2 ; USED IN SHADE CALC ZREL *=*+2 ; RELATIVE (TO CENTER) ZWX *=*+2 ; Z WITH X (+ OR -) ; RADIUS *=*+2 ; LOCAL RADIUS OF SURFACE TONE *=*+2 ; USED IN SHADE CALC TNTMP *=*+2 ; USED IN SHADE CALC ; CLIPL *=*+1 ; LEFT CLIPPING BOUND CLIPR *=*+1 ; RIGHT CLIPPING BOUND CLIPU *=*+1 ; UP CLIPPING BOUND CLIPD *=*+1 ; DOWN CLIPPING BOUND ; HEMI *=*+1 ; PLOTTING HEMISPHERE ; BAKLIT *=*+1 ; BACKLIT FLAG HVFLAG *=*+1 ; HORIZONTAL/VERTICAL FLAG TEMP *=*+2 ; TEMPORARY STORAGE CNTX *=*+1 ; LOOP COUNTER CNTY *=*+1 ; LOOP COUNTER MAX *=*+1 ; LOOP LIMIT ; HLEN *=*+1 ; HALF-LENGTH OF CYLINDERS RS *=*+2 ; SQUARE OF TOROID RADIUS RT *=*+1 ; TOROID (RING) RADIUS RC *=*+1 ; CENTER RADIUS OF TOROID RO *=*+1 ; OUTER RADIUS OF TOROID RI *=*+1 ; INNER RADIUS OF TOROID XSQR *=*+2 XMAX *=*+1 ; R0=HLEN ; *=ORIGIN ;***************************************** ; ; DIVIDE WITH SINGLE PRECISION DIVISOR ; (USED OFTEN IN SHAPE ROUTINES) ; SDIV LDA #0 STA DVSOR+1 JMP DIVIDE ; ;***************************************** ; ; CALCULATE SHADE VALUE (0-63) BY ; MULTIPLYING 'TONE' BY 26 THEN ; DIVIDE RESULT BY RADIUS OF SURFACE ; GETVAL BIT TONE+1 BPL CNTNU ; IF 'TONE'<0, THEN LDA BAKLIT ; MAKE VALUE 0 OR ABS(TONE) BNE NEGATE ; DEPENDING ON BAKLIT FLAG STA VALUE RTS NEGATE SEC LDA #$00 SBC TONE STA TONE CNTNU LDA TONE STA MLPCND LDA #$1A STA MLPLER JSR MULT STA DVDND+1 LDA PROD STA DVDND LDA RADIUS STA DVSOR JSR SDIV LDA QUOT STA VALUE RTS ; ;***************************************** ; ; POINT PLOTTING BY QUADRANTS USING ; THE FOUR-FOLD SYMMETRY OF SIMPLE OBJECTS ; ; DEPENDING ON STATUS OF 'HVFLAG', EXCHANGE ; X AND Y COORDINATES TO ROTATE OBJECTS 90 DEG ; SINGLE SHAPE ROUTINE CAN THEN BE USED TO ; DRAW 'HORIZONTAL' OR 'VERTICAL' VERSIONS ; OF AN OBJECT ; ; THE FOLOWING IS A 'BASIC SUBROUTINE' ; EQUIVALENT TO EXPLAIN ITS OPERATION ; ; NOTE THAT LABELS ARE USED IN PLACE OF ; LINE NUMBERS ; ; 'PTPLOT' IF HVFLAG<0 THEN GOTO 'NOROT' ; (STACK)=XREL:XREL=YREL:YREL=(STACK) ; (STACK)=XSHD:XSHD=YSHD:YSHD=(STACK) ; 'NOROT' GOSUB 'GETZ' ; REM CALCULATE 2*Z FROM X,Y AND RADIUS ; HEMI = 1 ; IF XREL>CLIPL THEN GOTO 'RHEMI' ; ZWX=2*Z-XSHD ; XPLT=XCENT-XREL:REM LEFT HEMISPHERE ; 'CHCLUP' IF YREL>CLIPU THEN GOTO 'DHEMI' ; TONE=ZWX+YSHD ; GOSUB 'GETVAL':REM NORMALIZE SHADE VAL ; YPLT=YCENT+YREL ; GOSUB 'PLTSHD':REM PLOT OR UNPLOT ; REM POINTS WEIGHTED BY SHADE VALUE ; 'DHEMI' IF YREL>CLIPD THEN GOTO 'RHEMI' ; TONE=ZWX-YSHD ; GOSUB 'GETVAL' ; YPLT=YCENT-YREL ; GOSUB 'PLTSHD' ; 'RHEMI' IF HEMI=0 THEN RETURN ; HEMI=0 ; IF XREL>CLIPR THEN RETURN ; ZWX=2*Z+XSHD ; XPLT=XCENT+XREL ; GOSUB 'CHCLUP' ; RETURN ; PTPLOT BIT HVFLAG BPL NOROT LDA XREL PHA PHA LDA YREL STA XREL PLA STA YREL LDA XSHD PHA PHA LDA YSHD STA XSHD PLA STA YSHD LDA XSHD+1 PHA PHA LDA YSHD+1 STA XSHD+1 PLA STA YSHD+1 NOROT JSR GETZ PTPLT2 LDA #$01 STA HEMI SEC LDA CLIPL ; CHECK LEFT HEMISPHERE CMP XREL BCC RHEMI SEC LDA ROOT SBC XSHD STA ZWX LDA ROOT+1 SBC XSHD+1 STA ZWX+1 SEC LDA XCENT SBC XREL STA XPLT LDA XCENT+1 SBC #$00 STA XPLT+1 ; CHCLUP SEC LDA CLIPU ; CHECK FOR UP CLIPPING CMP YREL BCC DHEMI CLC LDA ZWX ADC YSHD STA TONE LDA ZWX+1 ADC YSHD+1 STA TONE+1 JSR GETVAL CLC LDA YCENT ADC YREL STA YPLT JSR PLTSHD ; DHEMI SEC LDA CLIPD ; CHECK FOR DOWN CLIPPING CMP YREL BCC RHEMI SEC LDA ZWX SBC YSHD STA TONE LDA ZWX+1 SBC YSHD+1 STA TONE+1 JSR GETVAL SEC LDA YCENT SBC YREL STA YPLT JSR PLTSHD ; RHEMI LDA HEMI BEQ PLDONE DEC HEMI SEC LDA CLIPR ; CHECK FOR RIGHT CLIPPING CMP XREL BCC PLDONE CLC LDA ROOT ADC XSHD STA ZWX LDA ROOT+1 ADC XSHD+1 STA ZWX+1 CLC LDA XCENT ADC XREL STA XPLT LDA XCENT+1 ADC #$00 STA XPLT+1 JMP CHCLUP PLDONE BIT HVFLAG BPL NORSTR LDA XSHD+1 ; RESTORE COORDS STA YSHD+1 PLA STA XSHD+1 LDA XSHD STA YSHD PLA STA XSHD LDA XREL STA YREL PLA STA XREL NORSTR RTS ; ;***************************************** ; ; CALCULATE Z FROM LOCAL X,Y BY ; PYTHAGOREAN SUM ; GETZ LDA RADIUS STA ARG JSR SQUARE STA TNTMP+1 LDA SQR STA TNTMP LDA XSHD STA ARG JSR SQUARE SEC LDA TNTMP SBC SQR STA TNTMP LDA TNTMP+1 SBC SQR+1 STA TNTMP+1 LDA YSHD STA ARG JSR SQUARE SEC LDA TNTMP SBC SQR STA RADCND LDA TNTMP+1 SBC SQR+1 STA RADCND+1 BMI ZEROOT JSR SQRT ASL ROOT ROL ROOT+1 RTS ZEROOT LDA #$00 STA ROOT STA ROOT+1 RTS ; ;***************************************** ; ; SET UP PARAMETERS FOR TOROIDS ; ; RT=(RO-RI)/2 RS=RT*RT RC=RT+RI ; TPARM LDA RO SEC SBC RI LSR A STA RT STA RADIUS CLC ADC RI STA RC LDA RT STA ARG JSR SQUARE LDA SQR STA RS LDA SQR+1 STA RS+1 LDA #0 STA CNTX RTS ; ;***************************************** ; ; DRAW A SHADED SPHERE ; ; 'BASIC SUBROUTINE' EQUIVALENT ; ; 'SPHERE' FOR CNTX=0 TO RADIUS/SQR(2) ; XREL=CNTX:XSHD=CNTX ; FOR CNTY=CNTX TO SQR(RAD*RAD-CNTX*CNTX) ; YREL=CNTY:YSHD=CNTY ; HVFLAG=0 ; GOSUB 'PTPLOT' ; REM EXCHANGE X & Y TO USE 8-FOLD SYM ; HVFLAG=-128 ; ; GOSUB 'PTPLOT' ; NEXT CNTY ; NEXT CNTX ; RETURN ; ; SPHERE LDA RADIUS STA ARG JSR SQUARE ASL SQR ROL SQR+1 LDA SQR STA RADCND LDA SQR+1 STA RADCND+1 JSR SQRT LSR ROOT+1 ROR ROOT LDA ROOT STA XMAX LDA #$00 STA CNTX STA XSHD+1 STA YSHD+1 LDA RADIUS STA ARG JSR SQUARE STA TEMP+1 LDA SQR STA TEMP LOOPX LDA CNTX STA CNTY STA ARG STA XREL STA XSHD JSR SQUARE SEC LDA TEMP SBC SQR STA RADCND LDA TEMP+1 SBC SQR+1 STA RADCND+1 JSR SQRT LDA ROOT STA MAX LOOPY LDA CNTY STA YREL STA YSHD LDA #0 STA HVFLAG JSR PTPLOT LDA #$80 STA HVFLAG JSR PTPLOT LDA CNTY CMP MAX BEQ DONEY INC CNTY JMP LOOPY DONEY LDA CNTX CMP XMAX BEQ DONE INC CNTX JMP LOOPX DONE RTS ; ;***************************************** ; ; DRAW SHADED CYLINDERS ; ; 'BASIC SUBROUTINE' EQUIVALENT ; ; 'CYLNDR' XSHD=0 ; FOR YREL=RADIUS TO 0 ; YSHD=YREL ; FOR XREL=HLEN TO 0 ; GOSUB 'PTPLOT' ; NEXT XREL ; NEXT YREL ; RETURN ; CYLNDR LDA #0 STA XSHD STA XSHD+1 STA YSHD+1 LDA RADIUS STA YREL CYLOOP LDA HLEN STA XREL LDA YREL STA YSHD CXLOOP JSR PTPLOT DEC XREL BPL CXLOOP DEC YREL BPL CYLOOP RTS ; ;***************************************** ; ; DRAW EDGE-VIEW TOROIDS ; ; 'BASIC SUBROUTINE' EQUIVALENT ; ; 'EDGTOR' GOSUB 'TPARM':REM SET UP RADII ; FOR CNTX=0 TO RT ; XREL=CNTX:XSHD=CNTX ; R0=SQR(RT*RT-CNTX*CNTX) ; FOR CNTY=0 TO R0+RC ; YREL=CNTY ; YSHD=(R0*CNTY)/(R0+RC) ; GOSUB 'PTPLOT' ; NEXT CNTY ; NEXT CNTX ; RETURN ; EDGTOR JSR TPARM LDA #$00 STA XSHD+1 STA YSHD+1 LOOPX4 LDA CNTX STA XREL STA XSHD STA ARG JSR SQUARE SEC LDA RS SBC SQR STA RADCND LDA RS+1 SBC SQR+1 STA RADCND+1 JSR SQRT LDA ROOT STA R0 CLC ADC RC STA MAX LDA #$00 STA CNTY LOOPY4 LDA CNTY STA YREL STA MLPLER LDA R0 STA MLPCND JSR MULT STA DVDND+1 LDA PROD STA DVDND LDA MAX STA DVSOR JSR SDIV LDA QUOT STA YSHD JSR PTPLOT LDA CNTY CMP MAX BEQ DONE4 INC CNTY JMP LOOPY4 DONE4 LDA CNTX CMP RT BEQ DONEHT INC CNTX JMP LOOPX4 DONEHT RTS ; ;***************************************** ; ; DRAW A SHADED, TOP-VIEW TOROID ; ; 'BASIC SUBROUTINE' EQUIVALENT ; ; 'TOROID' GOSUB 'TPARM' ; FOR CNTX=0 TO RO/SQR(2) ; REM 8-FOLD SYMMETRY USED ; XREL=CNTX ; MAX=SQR(RO*RO-CNTX*CNTX) ; IF CNTX>RI THEN GOTO 'GRTR' ; CNTY=SQR(RI*RI-CNTY*CNTY) ; GOTO 'LLPY1' ; 'GRTR' CNTY=CNTX ; 'LLPY1' YREL=CNTY ; R0=SQR(CNTY*CNTY+CNTX*CNTX) ; XSHD=CNTX-(CNTX*RC)/R0 ; YSHD=CNTY-(CNTY*RC)/R0 ; HVFLAG=0:GOSUB 'PTPLOT' ; HVFLAG=-128:GOSUB 'PTPLOT' ; IF CNTY=MAX THEN GOTO 'DDNY1' ; CNTY=CNTY+1 ; GOTO 'LLPY1' ; 'DDNY1' NEXT CNTX ; RETURN ; TOROID JSR TPARM LDA RO STA ARG JSR SQUARE ASL SQR ROL SQR+1 LDA SQR STA RADCND LDA SQR+1 STA RADCND+1 JSR SQRT LSR ROOT+1 ROR ROOT LDA ROOT STA XMAX LLPX1 LDA CNTX STA XREL STA ARG JSR SQUARE STA XSQR+1 LDA SQR STA XSQR LDA RO STA ARG JSR SQUARE SEC LDA SQR SBC XSQR STA RADCND LDA SQR+1 SBC XSQR+1 STA RADCND+1 JSR SQRT LDA ROOT STA MAX SEC LDA RI SBC CNTX BCC GRTR LDA RI STA ARG JSR SQUARE SEC LDA SQR SBC XSQR STA RADCND LDA SQR+1 SBC XSQR+1 STA RADCND+1 JSR SQRT LDA ROOT STA CNTY JMP LLPY1 GRTR LDA CNTX STA CNTY LLPY1 LDA CNTY STA YREL STA ARG JSR SQUARE CLC LDA SQR ADC XSQR STA RADCND LDA SQR+1 ADC XSQR+1 STA RADCND+1 JSR SQRT LDA ROOT STA R0 STA DVSOR LDA CNTX STA MLPLER LDA RC STA MLPCND JSR MULT STA DVDND+1 LDA PROD STA DVDND JSR SDIV SEC LDA CNTX SBC QUOT STA XSHD LDA #$00 SBC QUOT+1 STA XSHD+1 LDA CNTY STA MLPLER LDA RC STA MLPCND JSR MULT STA DVDND+1 LDA PROD STA DVDND LDA R0 STA DVSOR JSR SDIV SEC LDA CNTY SBC QUOT STA YSHD LDA #$00 STA HVFLAG SBC QUOT+1 STA YSHD+1 JSR PTPLOT LDA #$80 STA HVFLAG JSR PTPLOT LDA CNTY CMP MAX BEQ DDNY1 INC CNTY JMP LLPY1 DDNY1 LDA CNTX CMP XMAX BEQ DUNTOR INC CNTX JMP LLPX1 DUNTOR RTS ; ;***************************************** ; ; DRAW "INSIDE VIEW" TOROIDS ; ; 'BASIC SUBROUTINE' EQUIVALENT ; ; 'SPOOL' GOSUB 'TPARM' ; FOR CNTX=0 TO RT ; XREL=CNTX:XSHD=CNTX ; MAX=RC-SQR(RS-CNTX*CNTX) ; FOR CNTY=0 TO MAX ; YREL=CNTY ; YSHD=(RC*CNTY/MAX)-CNTY ; GOSUB 'PTPLOT' ; NEXT CNTY ; NEXT CNTX ; RETURN ; SPOOL JSR TPARM LLPX2 LDA CNTX STA XREL STA ARG SEC LDA #$00 SBC CNTX STA XSHD LDA #$00 SBC #$00 STA XSHD+1 JSR SQUARE SEC LDA RS SBC SQR STA RADCND LDA RS+1 SBC SQR+1 STA RADCND+1 JSR SQRT SEC LDA RC SBC ROOT STA MAX LDA #$00 STA CNTY LLPY2 LDA CNTY STA YREL STA MLPLER LDA RC STA MLPCND JSR MULT STA DVDND+1 LDA PROD STA DVDND LDA MAX STA DVSOR JSR SDIV LDA QUOT SEC SBC CNTY STA YSHD LDA QUOT+1 SBC #$00 STA YSHD+1 JSR PTPLOT LDA CNTY CMP MAX BEQ DDNY2 INC CNTY JMP LLPY2 DDNY2 LDA CNTX CMP RT BEQ DUNHSP INC CNTX JMP LLPX2 DUNHSP RTS .END
; INTERFACE - EASY PARAMETER SETTING FOR SHAPE ; DRAWING ROUTINES FROM BASIC. ; ; RICHARD L. RYLANDER 11/23/84 ; ;**************************************** ORIGIN=$CAC8 RAM =$0393 ; ; PARAMETER LOCATIONS FOR VARIOUS SHAPES ; XCENT =$036A YCENT =$036F XPLOT =$033F YPLOT =$0341 XMIN =$034A YMIN =$034C XMID =$034D YMID =$034F XMAX =$0350 YMAX =$0352 RADIUS =$0377 HLEN =$0389 RI =$038F RO =$038E ; HVFLAG =$0383 VALUE =$0344 PLTFLG =$033E ; DEFLAG =$FB ; ;**************************************** ; ; FUNCTION LOCATIONS ; GRFON =$C0E2 ; SWITCH TO GRAPHICS MODE GRFOFF =$C103 ; RETURN TO TEXT DISPLAY ; CLEARR=$C12C ; CLEAR BITMAP CLRBYT=$C135 ; CLEAR (FILL) BYTE COLORR=$C118 ; LOAD COLOR MAP COLBYT=$C119 ; COLOR BYTE ; PLOTR =$C14B ; POINT PLOT ROUTINE LINER =$C2DB ; DRAW A LINE FACETR =$C4E1 ; DRAW A SHADED FACET ; ;**************************************** ; ; SHADED SHAPE DRAWING ROUTINES ; SPHERR=$C7C7 ; SPHERE CYLNDR=$C864 ; CYLINDER TORUSR=$C90F ; TOP-VIEW TOROID EDGTOR=$C88F ; EDGE-VIEW TOROID SPOOLR=$CA3B ; INSIDE-VIEW TOROID ; ;**************************************** ; ; BASIC ROM ROUTINES ; CHKCOM=$AEFD ; CHECK FOR COMMA EVAEXP=$AD9E ; EVALUATE EXPRESSION FLTFIX=$B1AA ; CONVERT TO FIXED ; *=RAM LINFAC *=*+1 ; LINE OR FACET FLAG ; *=ORIGIN ; ;**************************************** ; ; GET PARAMETERS FROM BASIC CALLING STATEMENT ; OF THE FORM: ; SYS(FNCTN),PARAM1,PARAM2,PARAM3[OPT] ; WHERE THE THIRD PARAMETER (FOR EXAMPLE) ; MAY BE OPTIONAL (A DEFAULT VALUE IS USED ; IF THE PARAMETER IS NOT SPECIFIED) ; GETNUM JSR CHKCOM ; LOOK FOR COMMA JSR EVAEXP ; EVALUATE EXPRESSION JSR FLTFIX ; CHANGE TO INTEGER WITH ; HIGH BYTE IN "A" AND LOW BYTE IN "Y" RTS ; ; CHECK FOR ADDITIONAL (OPTIONAL) PARAMETERS ; PCHECK LDA #$2C ; "," COMMA LDY #0 STY DEFLAG CMP ($7A),Y BNE NOMORE ; NO COMMA - USE DEFAULT JMP $0073 NOMORE LDY #$80 STY DEFLAG RTS ; ; GET TWO ADDITIONAL PARAMETERS FOR TOROIDS ; GETTWO JSR PCHECK BIT DEFLAG BMI DFAULT JSR EVAEXP JSR FLTFIX STY RI JSR GETNUM STY RO DFAULT RTS ; ;**************************************** ; ; SET CENTER COORDINATES ; CENTER JSR GETNUM STY XCENT STA XCENT+1 JSR GETNUM STY YCENT RTS ; ;**************************************** ; ; CLEAR THE BITMAP, FILLING WITH (OPTIONAL) ; FILL VALUE SPECIFIED OR WITH (DEFAULT) "0" ; CLEAR2 JSR PCHECK BIT DEFLAG BMI DEFCLR JSR EVAEXP JSR FLTFIX .BYTE $2C DEFCLR LDY #0 STY CLRBYT JMP CLEARR ; ;**************************************** ; ; FILL COLOR MAP WITH (OPTIONAL) COLOR BYTE ; SPECIFIED OR WITH (DEFAULT) "$01" ; (BLACK DOTS ON WHITE BACKGROUND) ; COLOR2 JSR PCHECK BIT DEFLAG BMI DEFCOL JSR EVAEXP JSR FLTFIX .BYTE $2C DEFCOL LDY #$01 STY COLBYT JMP COLORR ; ;**************************************** ; ; PLOT OR UNPLOT POINTS ; PLOT2 LDA #0 .BYTE $2C UNPLT2 LDA #$80 STA PLTFLG JSR GETNUM STY XPLOT STA XPLOT+1 JSR GETNUM STY YPLOT JMP PLOTR ; ;**************************************** ; ; DRAW LINES BETWEEN (X1,Y1) AND (X2,Y2) ; OR SHADED FACETS BETWEEN THREE POINTS ; (X1,Y1), (X2,Y2) AND (X3,Y3) ; LINE2 LDA #0 .BYTE $2C FACET2 LDA #$80 STA LINFAC JSR GETNUM STY XMIN STA XMIN+1 JSR GETNUM STY YMIN JSR GETNUM STY XMID STA XMID+1 JSR GETNUM STY YMID BIT LINFAC BPL LDRAW JSR GETNUM STY XMAX STA XMAX+1 JSR GETNUM STY YMAX JSR GETNUM STY VALUE JMP FACETR LDRAW JMP LINER ; ;**************************************** ; ; DRAW A SPHERE CENTERED AT (XCENT,YCENT) ; DEFAULT RADIUS IS LAST VALUE USED ; SPHER2 JSR CENTER JSR PCHECK BIT DEFLAG BMI SKIP1 JSR EVAEXP JSR FLTFIX STY RADIUS SKIP1 JMP SPHERR ; ;**************************************** ; ; DRAW A TOP-VIEW TOROID AT (XCENT,YCENT) ; DEFAULT INNER AND OUTER RADII ARE LAST USED ; TORUS2 JSR CENTER JSR GETTWO JMP TORUSR ; ;**************************************** ; ; DRAW CYLINDERS WITH AXES HORIZONTAL OR ; VERTICAL. DEFAULT RADIUS AND "HALF-LENGTH" ; ARE LAST VALUES USED. ; VCYL2 LDA #$80 .BYTE $2C HCYL2 LDA #0 STA HVFLAG JSR CENTER JSR PCHECK BIT DEFLAG BMI SKIP2 JSR EVAEXP JSR FLTFIX STY RADIUS JSR GETNUM STY HLEN SKIP2 JMP CYLNDR ; ;**************************************** ; ; DRAW EDGE-VIEW TOROIDS WITH AXES HORIZONTAL ; OR VERTICAL ; INNNER AND OUTER RADII ARE OPTIONAL ; VTOR2 LDA #$80 .BYTE $2C HTOR2 LDA #0 STA HVFLAG JSR CENTER JSR GETTWO JMP EDGTOR ; ;**************************************** ; ; DRAW INSIDE-VIEW TOROIDS, "SPOOLS", ; WITH AXES HORIZONTAL OR VERTICAL ; INNER AND OUTER RADII ARE OPTIONAL ; VSPL2 LDA #$80 .BYTE $2C HSPL2 LDA #0 STA HVFLAG JSR CENTER JSR GETTWO JMP SPOOLR .END
; KEYSORT - RELOCATABLE BUBBLE SORT USING KEY ARRAY ; POINTING TO INTEGER ARRAY ; ; RICHARD L. RYLANDER 1/12/85 ; ORIGIN=$CF59 ; 53081. (FOLLOWING DOS 5.1) ; KB = $FB ; 251. POINTER TO KEY ARRAY ZB = $FD ; 253. POINTER TO DATA ARRAY MAX = $8C ; 140. POKE WITH MAX ARRAY INDEX TOP = $AC TOPDIS = $AD FLAG = $AE NXTFLG = $61 CRRNT = $62 REPEAT = $64 ; *=ORIGIN ; INIT LDY #$FF ; INITIALIZE KEY ARRAY INLOOP INY TYA STA (KB),Y CMP MAX BNE INLOOP ; SORT STA TOPDIS ; 'A' HOLDS 'MAX' LOOP1 LDA TOPDIS STA TOP LDX #0 STX NXTFLG STX FLAG LOOP2 STX REPEAT ; ; GET BOTH BYTES OF INTEGER POINTED TO BY ; 'KEY' ELEMENT. RETURN WITH MSB ON STACK ; AND LSB IN THE ACCUMULATOR ; GETINT TXA TAY LDA (KB),Y ASL A BCC LOAD DEC NXTFLG INC ZB+1 LOAD TAY LDA (ZB),Y PHA INY LDA (ZB),Y BIT NXTFLG BPL NODEC INC NXTFLG DEC ZB+1 NODEC CPX REPEAT BNE ORDER STA CRRNT PLA STA CRRNT+1 INX BNE GETINT ; ; COMPARE INTEGERS OBTAINED THROUGH KEY ARRAY ; IF 'CURRENT' <= 'NEXT' THEN SWAP KEY ; ELEMENTS, ELSE CONTINUE ; ORDER CMP CRRNT PLA SBC CRRNT+1 BVC TEST EOR #$80 TEST BPL NOSWAP SWAP TXA TAY STX TOPDIS LDA (KB),Y PHA DEY LDA (KB),Y INY STA (KB),Y PLA DEY STA (KB),Y INC FLAG NOSWAP CPX TOP BNE LOOP2 LDA FLAG BNE LOOP1 ; ; UNPACK THE BYTE ELEMENTS OF THE 'KEY' ARRAY ; INTO BASIC'S NORMAL 2-BYTE INTEGER FORMAT ; UNPACK LDX MAX INX PKLOOP DEX TXA TAY LDA (KB),Y PHA TXA ASL A ; MOVE TO 2*I+1 ORA #1 BCC STORE INC NXTFLG INC KB+1 STORE TAY PLA STA (KB),Y LDA #0 DEY STA (KB),Y LDA NXTFLG BEQ OK DEC NXTFLG DEC KB+1 OK TXA BNE PKLOOP DONE RTS .END
; "WRITE" RICHARD L. RYLANDER ; 12/30/84 ; REVISED 1/19/85 - ORIGIN MOVED TO $CFE5 (53221.) ; ; PUT TEXT CHARACTERS ON GRAPHIC SCREEN ; (UNDER BASIC ROM) IN VARIOUS STYLES ; *=$CFE5 ; PUT CODE AFTER DOS 5.1 WRITE LDA $01 ; SWITCH OUT BASIC ROM AND #$FE STA $01 LDY #7 LOOP LDA ($FD),Y ; READ CHARACTER BYTE AND ($FB),Y ; MODIFY W/SCREEN BYTE STA ($FB),Y ; STORE IN SCREEN ; ; POKE NEW LOGICAL OPERATOR TO REPLACE ; 'AND' (53231.) FOR DIFFERENT STYLES ; ORA=17. BIT (NOP)=36. AND=49. EOR=81. ; DEY BPL LOOP LDA $01 ; RESTORE BASIC ROM ORA #1 STA $01 RTS .END
PROGRAMM : GRAPHICS C000 CBFC ----------------------------------- C000 : FF 55 00 00 A5 AC 10 07 B8 C008 : 38 A9 00 E5 AC 85 AC 85 86 C010 : AD A9 00 A2 08 46 AD 90 71 C018 : 03 18 65 AC 6A 66 AE CA 40 C020 : D0 F3 85 AF 60 A9 00 85 9F C028 : B4 85 B5 A2 10 26 FD 26 D7 C030 : FE 26 B4 26 B5 38 A5 B4 50 C038 : E5 FB A8 A5 B5 E5 FC 90 99 C040 : 04 84 B4 85 B5 CA D0 E5 25 C048 : 26 FD 26 FE 06 B4 26 B5 E0 C050 : B0 0B 38 A5 FB E5 B4 A5 56 C058 : FC E5 B5 B0 06 E6 FD D0 FB C060 : 02 E6 FE 60 A2 08 A9 00 B2 C068 : 8D 3C 03 8D 3D 03 85 FB 80 C070 : 85 FC 0E 3C 03 2E 3D 03 1B C078 : EE 3C 03 D0 03 EE 3D 03 02 C080 : 06 AC 26 AD 26 FB 26 FC F0 C088 : 06 AC 26 AD 26 FB 26 FC F8 C090 : 38 A5 FB ED 3C 03 A8 A5 21 C098 : FC ED 3D 03 90 12 85 FC E4 C0A0 : 84 FB EE 3C 03 D0 03 EE 06 C0A8 : 3D 03 CA D0 C5 4C C1 C0 7B C0B0 : 38 AD 3C 03 E9 01 8D 3C 84 C0B8 : 03 B0 03 CE 3D 03 CA D0 67 C0C0 : B1 6E 3D 03 6E 3C 03 60 EE C0C8 : AD 00 C0 8D 02 C0 4D 01 B4 C0D0 : C0 2E 03 C0 6A 6E 03 C0 28 C0D8 : 8D 00 C0 AD 02 C0 8D 01 A9 C0E0 : C0 60 AD 11 D0 09 20 8D 4F C0E8 : 11 D0 AD 00 DD 8D 42 03 26 C0F0 : 29 FC 09 01 8D 00 DD AD A5 C0F8 : 18 D0 8D 43 03 A9 19 8D 41 C100 : 18 D0 60 AD 11 D0 29 DF 4A C108 : 8D 11 D0 AD 42 03 8D 00 7A C110 : DD AD 43 03 8D 18 D0 60 93 C118 : A9 01 A2 00 9D 00 84 9D 12 C120 : 00 85 9D 00 86 9D 00 87 AF C128 : CA D0 F1 60 A9 A0 85 FC 92 C130 : A0 00 84 FB A9 00 A2 20 D6 C138 : 91 FB C8 D0 FB E6 FC CA 93 C140 : D0 F6 60 A9 00 2C A9 80 E2 C148 : 8D 3E 03 A5 01 29 FE 85 CA C150 : 01 38 A9 C7 ED 41 03 AA 1B C158 : 4A 4A 4A A8 B9 AB C1 85 7A C160 : FB B9 C4 C1 85 FC 8A 29 5E C168 : 07 18 65 FB 85 FB AD 3F C1 C170 : 03 29 F8 65 FB 85 FB AD 2A C178 : 40 03 65 FC 85 FC A9 A0 5B C180 : 65 FC 85 FC AD 3F 03 29 97 C188 : 07 49 07 AA A9 01 CA 30 79 C190 : 03 0A D0 FA A0 00 2C 3E 63 C198 : 03 10 05 49 FF 31 FB 2C E0 C1A0 : 11 FB 91 FB A5 01 09 01 1B C1A8 : 85 01 60 00 40 80 C0 00 D1 C1B0 : 40 80 C0 00 40 80 C0 00 6C C1B8 : 40 80 C0 00 40 80 C0 00 74 C1C0 : 40 80 C0 00 00 01 02 03 87 C1C8 : 05 06 07 08 0A 0B 0C 0D D7 C1D0 : 0F 10 11 12 14 15 16 17 DE C1D8 : 19 1A 1B 1C 1E AD 3F 03 9B C1E0 : 29 07 8D 48 03 AD 41 03 A2 C1E8 : 29 07 0A 0A 0A 0D 48 03 89 C1F0 : AA BD 2F C2 CD 44 03 10 C8 C1F8 : 03 4C 46 C1 4C 43 C1 20 11 C200 : C8 C0 4A 4A CD 44 03 10 2F C208 : 03 4C 46 C1 4C 43 C1 AD 3C C210 : 47 03 F0 10 AC 41 03 C8 89 C218 : 84 AD A9 D5 85 AC 20 11 F8 C220 : C0 8D 41 03 AD 46 03 F0 53 C228 : 03 4C DD C1 4C FF C1 00 CD C230 : 08 35 3D 02 0A 37 3F 10 DA C238 : 18 25 2D 12 1A 27 2F 31 6A C240 : 39 04 0C 33 3B 06 0E 21 43 C248 : 29 14 1C 23 2B 16 1E 03 C9 C250 : 0B 36 3E 01 09 34 3C 13 6F C258 : 1B 26 2E 11 19 24 2C 32 FC C260 : 3A 07 0F 30 38 05 0D 22 0C C268 : 2A 17 1F 20 28 15 1D A0 CB C270 : 06 A9 D5 85 AC B9 4C 03 41 C278 : 85 AD 20 11 C0 99 4C 03 0E C280 : 88 88 88 10 F0 60 A0 02 09 C288 : B9 4A 03 48 B9 4D 03 99 75 C290 : 4A 03 68 99 4D 03 88 10 D8 C298 : EF 60 A0 02 B9 4D 03 48 C2 C2A0 : B9 50 03 99 4D 03 68 99 37 C2A8 : 50 03 88 10 EF 60 A2 02 2E C2B0 : 38 AD 4D 03 ED 4A 03 AD 0B C2B8 : 4E 03 ED 4B 03 B0 03 20 6F C2C0 : 86 C2 CA F0 15 38 AD 50 E2 C2C8 : 03 ED 4D 03 AD 51 03 ED C3 C2D0 : 4E 03 B0 DC 20 9A C2 4C E2 C2D8 : B0 C2 60 A9 02 8D 51 03 0E C2E0 : 20 AE C2 AD 47 03 F0 03 14 C2E8 : 20 6F C2 20 6F C4 AD 4A DD C2F0 : 03 8D 3F 03 AD 4B 03 8D 46 C2F8 : 40 03 AD 4C 03 8D 41 03 56 C300 : AD 57 03 D0 7D 38 AD 56 31 C308 : 03 ED 5B 03 B0 74 AD 5B 55 C310 : 03 8D 65 03 8D 68 03 4E 58 C318 : 65 03 38 AD 56 03 ED 65 C3 C320 : 03 8D 65 03 AD 57 03 E9 19 C328 : 00 8D 66 03 EE 68 03 AD 82 C330 : 67 03 D0 06 20 43 C1 4C C9 C338 : 3D C3 20 46 C1 AD 60 03 39 C340 : D0 05 EE 41 03 D0 03 CE D7 C348 : 41 03 2C 66 03 30 1A EE DB C350 : 3F 03 D0 03 EE 40 03 38 13 C358 : AD 65 03 ED 5B 03 8D 65 05 C360 : 03 AD 66 03 E9 00 8D 66 D5 C368 : 03 18 AD 65 03 6D 56 03 8A C370 : 8D 65 03 AD 66 03 6D 57 09 C378 : 03 8D 66 03 CE 68 03 D0 1A C380 : AE 60 AD 56 03 8D 65 03 CD C388 : 8D 68 03 AD 57 03 8D 66 50 C390 : 03 8D 69 03 4E 66 03 6E 16 C398 : 65 03 38 AD 5B 03 ED 65 93 C3A0 : 03 8D 65 03 A9 00 ED 66 43 C3A8 : 03 8D 66 03 AD 67 03 D0 30 C3B0 : 06 20 43 C1 4C BA C3 20 B9 C3B8 : 46 C1 EE 3F 03 D0 03 EE 23 C3C0 : 40 03 2C 66 03 30 20 AD E7 C3C8 : 60 03 D0 05 EE 41 03 D0 25 C3D0 : 03 CE 41 03 38 AD 65 03 78 C3D8 : ED 56 03 8D 65 03 AD 66 55 C3E0 : 03 ED 57 03 8D 66 03 18 58 C3E8 : AD 65 03 6D 5B 03 8D 65 85 C3F0 : 03 AD 66 03 69 00 8D 66 5D C3F8 : 03 38 AD 68 03 E9 01 8D 2E C400 : 68 03 B0 03 CE 69 03 2C 13 C408 : 69 03 10 A0 60 38 AD 53 30 C410 : 03 ED 54 03 B0 0E AD 53 58 C418 : 03 48 AD 54 03 8D 53 03 25 C420 : 68 8D 54 03 AD 53 03 8D 61 C428 : 41 03 20 24 C2 AD 53 03 64 C430 : CD 54 03 F0 06 CE 53 03 30 C438 : 4C 24 C4 60 AD 5F 03 85 C0 C440 : AC AD 5E 03 85 AD 20 11 23 C448 : C0 85 FE A5 AE 85 FD A9 A1 C450 : 00 85 FC AD 5A 03 85 FB D3 C458 : 20 25 C0 AD 63 03 D0 08 92 C460 : 18 AD 55 03 65 FD 90 06 99 C468 : 38 AD 55 03 E5 FD 60 38 6D C470 : AD 4D 03 ED 4A 03 8D 56 E2 C478 : 03 AD 4E 03 ED 4B 03 8D A6 C480 : 57 03 38 AD 50 03 ED 4D 8C C488 : 03 8D 58 03 38 AD 50 03 01 C490 : ED 4A 03 8D 59 03 A9 00 69 C498 : 8D 60 03 8D 61 03 8D 62 F1 C4A0 : 03 38 AD 4F 03 ED 4C 03 EB C4A8 : B0 09 EE 60 03 AD 4C 03 79 C4B0 : ED 4F 03 8D 5B 03 38 AD C1 C4B8 : 52 03 ED 4F 03 B0 09 EE A9 C4C0 : 61 03 AD 4F 03 ED 52 03 E7 C4C8 : 8D 5C 03 38 AD 52 03 ED A1 C4D0 : 4C 03 B0 09 EE 62 03 AD 54 C4D8 : 4C 03 ED 52 03 8D 5D 03 84 C4E0 : 60 20 AE C2 AD 47 03 F0 57 C4E8 : 03 20 6F C2 20 6F C4 AD 1B C4F0 : 4A 03 8D 3F 03 AD 4B 03 D8 C4F8 : 8D 40 03 38 AD 3F 03 ED 2A C500 : 4A 03 8D 5F 03 AD 56 03 18 C508 : F0 53 8D 5A 03 AD 5B 03 62 C510 : 8D 5E 03 AD 60 03 8D 63 5E C518 : 03 AD 4C 03 8D 55 03 20 35 C520 : 3C C4 8D 53 03 AD 59 03 95 C528 : F0 33 8D 5A 03 AD 5D 03 7A C530 : 8D 5E 03 AD 62 03 8D 63 9E C538 : 03 20 3C C4 8D 54 03 20 BB C540 : 0D C4 AD 40 03 CD 4E 03 01 C548 : D0 08 AD 3F 03 CD 4D 03 49 C550 : F0 0B EE 3F 03 D0 03 EE 0A C558 : 40 03 4C FB C4 38 AD 3F F0 C560 : 03 ED 4A 03 8D 5F 03 AD 88 C568 : 59 03 F0 63 8D 5A 03 AD FE C570 : 5D 03 8D 5E 03 AD 62 03 AB C578 : 8D 63 03 AD 4C 03 8D 55 EB C580 : 03 20 3C C4 8D 54 03 38 33 C588 : AD 3F 03 ED 4D 03 8D 5F 35 C590 : 03 AD 58 03 F0 39 8D 5A A4 C598 : 03 AD 5C 03 8D 5E 03 AD 1D C5A0 : 61 03 8D 63 03 AD 4F 03 33 C5A8 : 8D 55 03 20 3C C4 8D 53 6B C5B0 : 03 20 0D C4 AD 40 03 CD 24 C5B8 : 51 03 D0 08 AD 3F 03 CD 3C C5C0 : 50 03 F0 0B EE 3F 03 D0 C6 C5C8 : 03 EE 40 03 4C 5D C5 AD D5 C5D0 : 64 03 F0 15 20 EB C2 20 41 C5D8 : 9A C2 20 EB C2 20 86 C2 26 C5E0 : 20 9A C2 20 86 C2 20 EB D9 C5E8 : C2 60 A9 00 85 FC 4C 25 00 C5F0 : C0 2C 7A 03 10 12 AD 82 13 C5F8 : 03 D0 04 8D 44 03 60 38 64 C600 : A9 00 ED 79 03 8D 79 03 DC C608 : AD 79 03 85 AC A9 1A 85 6F C610 : AD 20 11 C0 85 FE A5 AE 6E C618 : 85 FD AD 77 03 85 FB 20 83 C620 : EA C5 A5 FD 8D 44 03 60 DE C628 : 2C 83 03 10 2D AD 6C 03 D1 C630 : 48 48 AD 70 03 8D 6C 03 6A C638 : 68 8D 70 03 AD 6D 03 48 C6 C640 : 48 AD 71 03 8D 6D 03 68 3D C648 : 8D 71 03 AD 6E 03 48 48 B5 C650 : AD 72 03 8D 6E 03 68 8D 65 C658 : 72 03 20 45 C7 A9 01 8D E5 C660 : 81 03 38 AD 7D 03 CD 6C 27 C668 : 03 90 7D 38 AD 3C 03 ED BE C670 : 6D 03 8D 75 03 AD 3D 03 09 C678 : ED 6E 03 8D 76 03 38 AD CB C680 : 6A 03 ED 6C 03 8D 3F 03 14 C688 : AD 6B 03 E9 00 8D 40 03 5C C690 : 38 AD 7F 03 CD 70 03 90 6D C698 : 23 18 AD 75 03 6D 71 03 49 C6A0 : 8D 79 03 AD 76 03 6D 72 7A C6A8 : 03 8D 7A 03 20 F1 C5 18 4A C6B0 : AD 6F 03 6D 70 03 8D 41 5B C6B8 : 03 20 0F C2 38 AD 80 03 E0 C6C0 : CD 70 03 90 23 38 AD 75 2E C6C8 : 03 ED 71 03 8D 79 03 AD 8B C6D0 : 76 03 ED 72 03 8D 7A 03 1E C6D8 : 20 F1 C5 38 AD 6F 03 ED A7 C6E0 : 70 03 8D 41 03 20 0F C2 50 C6E8 : AD 81 03 F0 34 CE 81 03 FA C6F0 : 38 AD 7E 03 CD 6C 03 90 6C C6F8 : 28 18 AD 3C 03 6D 6D 03 77 C700 : 8D 75 03 AD 3D 03 6D 6E 3D C708 : 03 8D 76 03 18 AD 6A 03 6E C710 : 6D 6C 03 8D 3F 03 AD 6B BF C718 : 03 69 00 8D 40 03 4C 90 F0 C720 : C6 2C 83 03 10 1E AD 6E C3 C728 : 03 8D 72 03 68 8D 6E 03 A2 C730 : AD 6D 03 8D 71 03 68 8D F2 C738 : 6D 03 AD 6C 03 8D 70 03 84 C740 : 68 8D 6C 03 60 AD 77 03 42 C748 : 85 AC 20 04 C0 8D 7C 03 1C C750 : A5 AE 8D 7B 03 AD 6D 03 78 C758 : 85 AC 20 04 C0 38 AD 7B 37 C760 : 03 E5 AE 8D 7B 03 AD 7C 33 C768 : 03 E5 AF 8D 7C 03 AD 71 75 C770 : 03 85 AC 20 04 C0 38 AD E7 C778 : 7B 03 E5 AE 85 AC AD 7C 31 C780 : 03 E5 AF 85 AD 30 0A 20 D7 C788 : 64 C0 0E 3C 03 2E 3D 03 F4 C790 : 60 A9 00 8D 3C 03 8D 3D 03 C798 : 03 60 AD 8E 03 38 ED 8F D1 C7A0 : 03 4A 8D 8C 03 8D 77 03 3E C7A8 : 18 6D 8F 03 8D 8D 03 AD 68 C7B0 : 8C 03 85 AC 20 04 C0 A5 25 C7B8 : AE 8D 8A 03 A5 AF 8D 8B 55 C7C0 : 03 A9 00 8D 86 03 60 AD A7 C7C8 : 77 03 85 AC 20 04 C0 06 E9 C7D0 : AE 26 AF A5 AE 85 AC A5 47 C7D8 : AF 85 AD 20 64 C0 4E 3D B9 C7E0 : 03 6E 3C 03 AD 3C 03 8D 6E C7E8 : 92 03 A9 00 8D 86 03 8D 9A C7F0 : 6E 03 8D 72 03 AD 77 03 13 C7F8 : 85 AC 20 04 C0 8D 85 03 F1 C800 : A5 AE 8D 84 03 AD 86 03 AE C808 : 8D 87 03 85 AC 8D 6C 03 B9 C810 : 8D 6D 03 20 04 C0 38 AD 9B C818 : 84 03 E5 AE 85 AC AD 85 EC C820 : 03 E5 AF 85 AD 20 64 C0 A1 C828 : AD 3C 03 8D 88 03 AD 87 CC C830 : 03 8D 70 03 8D 71 03 A9 3A C838 : 00 8D 83 03 20 28 C6 A9 F2 C840 : 80 8D 83 03 20 28 C6 AD 82 C848 : 87 03 CD 88 03 F0 06 EE 83 C850 : 87 03 4C 2E C8 AD 86 03 4C C858 : CD 92 03 F0 06 EE 86 03 45 C860 : 4C 05 C8 60 A9 00 8D 6D 19 C868 : 03 8D 6E 03 8D 72 03 AD 02 C870 : 77 03 8D 70 03 AD 89 03 A4 C878 : 8D 6C 03 AD 70 03 8D 71 EA C880 : 03 20 28 C6 CE 6C 03 10 F3 C888 : F8 CE 70 03 10 E7 60 20 66 C890 : 9A C7 A9 00 8D 6E 03 8D EC C898 : 72 03 AD 86 03 8D 6C 03 1C C8A0 : 8D 6D 03 85 AC 20 04 C0 B3 C8A8 : 38 AD 8A 03 E5 AE 85 AC FD C8B0 : AD 8B 03 E5 AF 85 AD 20 BE C8B8 : 64 C0 AD 3C 03 8D 89 03 38 C8C0 : 18 6D 8D 03 8D 88 03 A9 CF C8C8 : 00 8D 87 03 AD 87 03 8D 0F C8D0 : 70 03 85 AD AD 89 03 85 17 C8D8 : AC 20 11 C0 85 FE A5 AE 35 C8E0 : 85 FD AD 88 03 85 FB 20 6D C8E8 : EA C5 A5 FD 8D 71 03 20 8F C8F0 : 28 C6 AD 87 03 CD 88 03 9E C8F8 : F0 06 EE 87 03 4C CC C8 EF C900 : AD 86 03 CD 8C 03 F0 06 1C C908 : EE 86 03 4C 9A C8 60 20 35 C910 : 9A C7 AD 8E 03 85 AC 20 1A C918 : 04 C0 06 AE 26 AF A5 AE A8 C920 : 85 AC A5 AF 85 AD 20 64 6A C928 : C0 4E 3D 03 6E 3C 03 AD EF C930 : 3C 03 8D 92 03 AD 86 03 61 C938 : 8D 6C 03 85 AC 20 04 C0 CA C940 : 8D 91 03 A5 AE 8D 90 03 AB C948 : AD 8E 03 85 AC 20 04 C0 0B C950 : 38 A5 AE ED 90 03 85 AC 55 C958 : A5 AF ED 91 03 85 AD 20 D6 C960 : 64 C0 AD 3C 03 8D 88 03 DC C968 : 38 AD 8F 03 ED 86 03 90 FB C970 : 23 AD 8F 03 85 AC 20 04 F4 C978 : C0 38 A5 AE ED 90 03 85 0E C980 : AC A5 AF ED 91 03 85 AD 4B C988 : 20 64 C0 AD 3C 03 8D 87 E1 C990 : 03 4C 9A C9 AD 86 03 8D CF C998 : 87 03 AD 87 03 8D 70 03 61 C9A0 : 85 AC 20 04 C0 18 A5 AE C5 C9A8 : 6D 90 03 85 AC A5 AF 6D 60 C9B0 : 91 03 85 AD 20 64 C0 AD 5D C9B8 : 3C 03 8D 89 03 85 FB AD B2 C9C0 : 86 03 85 AD AD 8D 03 85 3D C9C8 : AC 20 11 C0 85 FE A5 AE 25 C9D0 : 85 FD 20 EA C5 38 AD 86 9B C9D8 : 03 E5 FD 8D 6D 03 A9 00 94 C9E0 : E5 FE 8D 6E 03 AD 87 03 37 C9E8 : 85 AD AD 8D 03 85 AC 20 B0 C9F0 : 11 C0 85 FE A5 AE 85 FD 84 C9F8 : AD 89 03 85 FB 20 EA C5 D3 CA00 : 38 AD 87 03 E5 FD 8D 71 B8 CA08 : 03 A9 00 8D 83 03 E5 FE 77 CA10 : 8D 72 03 20 28 C6 A9 80 FC CA18 : 8D 83 03 20 28 C6 AD 87 AA CA20 : 03 CD 88 03 F0 06 EE 87 96 CA28 : 03 4C 9A C9 AD 86 03 CD E8 CA30 : 92 03 F0 06 EE 86 03 4C 08 CA38 : 35 C9 60 20 9A C7 AD 86 1A CA40 : 03 8D 6C 03 85 AC 38 A9 77 CA48 : 00 ED 86 03 8D 6D 03 A9 E4 CA50 : 00 E9 00 8D 6E 03 20 04 7E CA58 : C0 38 AD 8A 03 E5 AE 85 16 CA60 : AC AD 8B 03 E5 AF 85 AD 73 CA68 : 20 64 C0 38 AD 8D 03 ED 21 CA70 : 3C 03 8D 88 03 A9 00 8D 3B CA78 : 87 03 AD 87 03 8D 70 03 41 CA80 : 85 AD AD 8D 03 85 AC 20 48 CA88 : 11 C0 85 FE A5 AE 85 FD 1C CA90 : AD 88 03 85 FB 20 EA C5 EB CA98 : A5 FD 38 ED 87 03 8D 71 B1 CAA0 : 03 A5 FE E9 00 8D 72 03 AF CAA8 : 20 28 C6 AD 87 03 CD 88 1C CAB0 : 03 F0 06 EE 87 03 4C 7A 41 CAB8 : CA AD 86 03 CD 8C 03 F0 8A CAC0 : 06 EE 86 03 4C 3E CA 60 E2 CAC8 : 20 FD AE 20 9E AD 20 AA C4 CAD0 : B1 60 A9 2C A0 00 84 FB B5 CAD8 : D1 7A D0 03 4C 73 00 A0 1C CAE0 : 80 84 FB 60 20 D2 CA 24 B9 CAE8 : FB 30 0F 20 9E AD 20 AA F0 CAF0 : B1 8C 8F 03 20 C8 CA 8C B8 CAF8 : 8E 03 60 20 C8 CA 8C 6A 0E CB00 : 03 8D 6B 03 20 C8 CA 8C 92 CB08 : 6F 03 60 20 D2 CA 24 FB 21 CB10 : 30 07 20 9E AD 20 AA B1 8A CB18 : 2C A0 00 8C 35 C1 4C 2C 11 CB20 : C1 20 D2 CA 24 FB 30 07 F0 CB28 : 20 9E AD 20 AA B1 2C A0 31 CB30 : 01 8C 19 C1 4C 18 C1 A9 D6 CB38 : 00 2C A9 80 8D 3E 03 20 E0 CB40 : C8 CA 8C 3F 03 8D 40 03 1C CB48 : 20 C8 CA 8C 41 03 4C 4B 04 CB50 : C1 A9 00 2C A9 80 8D 93 67 CB58 : 03 20 C8 CA 8C 4A 03 8D 39 CB60 : 4B 03 20 C8 CA 8C 4C 03 96 CB68 : 20 C8 CA 8C 4D 03 8D 4E F0 CB70 : 03 20 C8 CA 8C 4F 03 2C B6 CB78 : 93 03 10 18 20 C8 CA 8C 21 CB80 : 50 03 8D 51 03 20 C8 CA C9 CB88 : 8C 52 03 20 C8 CA 8C 44 A0 CB90 : 03 4C E1 C4 4C DB C2 20 B9 CB98 : FB CA 20 D2 CA 24 FB 30 79 CBA0 : 09 20 9E AD 20 AA B1 8C 4E CBA8 : 77 03 4C C7 C7 20 FB CA B0 CBB0 : 20 E4 CA 4C 0F C9 A9 80 65 CBB8 : 2C A9 00 8D 83 03 20 FB 33 CBC0 : CA 20 D2 CA 24 FB 30 0F A9 CBC8 : 20 9E AD 20 AA B1 8C 77 00 CBD0 : 03 20 C8 CA 8C 89 03 4C 28 CBD8 : 64 C8 A9 80 2C A9 00 8D 46 CBE0 : 83 03 20 FB CA 20 E4 CA 43 CBE8 : 4C 8F C8 A9 80 2C A9 00 73 CBF0 : 8D 83 03 20 FB CA 20 E4 64 CBF8 : CA 4C 3B CA 22
PROGRAMM : SORT_WRITE CF59 CFFF ----------------------------------- CF59 : A0 FF C8 98 91 FB C5 8C 67 CF61 : D0 F8 85 AD A5 AD 85 AC FC CF69 : A2 00 86 61 86 AE 86 64 9A CF71 : 8A A8 B1 FB 0A 90 04 C6 FE CF79 : 61 E6 FE A8 B1 FD 48 C8 E0 CF81 : B1 FD 24 61 10 04 E6 61 E6 CF89 : C6 FE E4 64 D0 08 85 62 BC CF91 : 68 85 63 E8 D0 DA C5 62 71 CF99 : 68 E5 63 50 02 49 80 10 63 CFA1 : 13 8A A8 86 AD B1 FB 48 DD CFA9 : 88 B1 FB C8 91 FB 68 88 CD CFB1 : 91 FB E6 AE E4 AC D0 B6 34 CFB9 : A5 AE D0 A8 A6 8C E8 CA 06 CFC1 : 8A A8 B1 FB 48 8A 0A 09 9E CFC9 : 01 90 04 E6 61 E6 FC A8 83 CFD1 : 68 91 FB A9 00 88 91 FB B8 CFD9 : A5 61 F0 04 C6 61 C6 FC 78 CFE1 : 8A D0 DC 60 A5 01 29 FE 1B CFE9 : 85 01 A0 07 B1 FD 31 FB C0 CFF1 : 91 FB 88 10 F7 A5 01 09 67 CFF9 : 01 85 01 60 01 08 97
10 rem shapes demo 20 : 30 rem richard l. rylander 11/23/84 (revised 1/20/85 to add labeling) 40 : 50 gr=49378 :rem graphik modus 60 tx=49411 :rem text modus 70 : 80 lb=893 :rem linke grenze 90 rb=894 :rem rechte grenze 100 ub=895 :rem obere grenze 110 db=896 :rem untere grenze 120 : 130 rem flags fuer verschiedene grafikmodi 140 : 150 sh=838 :rem schattierung: 0=random, 1=halbton 160 sc=839 :rem skalierung:0=normal (1:1), 1=skal. (4:3) fuer darstellung 170 lt=898 :rem lichteinfall: 0=normal, 1=von hinten beleuchtet 180 : 190 bo=53280 :rem rahmenfarbe 200 : 210 rem funktionsadressen 220 : 230 cl=51979 :rem bitmap bereich loeschen 240 co=52001 :rem colorbereich fuellen 250 : 260 sp=52119 :rem sphere 270 tr=52141 :rem ring von oben 280 vc=52150 :rem zylinder (vertikale achse) 290 hc=52153 :rem zylinder (horizontale achse) 300 vt=52186 :rem ringschnitt (vertikale achse) 310 ht=52189 :rem ringschnitt (axis horizontale achse) 320 vs=52203 :rem spule (vertikale achse) 330 hs=52206 :rem spule (horizontale achse) 340 : 350 rem einzelne shapes zeichnen 360 : 370 poke sh,1 :rem halbtonschattierung 380 poke sc,1 :rem skalierung 390 poke lt,0 :rem normalbeleuchtung 400 sys(cl) :rem bildschirm loeschen 410 sys(co),17*11+1 :rem farbkombination - dunkelgrau (11) weisse punkte (1) 414 rem auf den meisten farbmonitoren 420 poke bo,1 :rem weisser rahmen 430 sys(gr) :rem grafik einschalten 432 rw=12:cm=14:md=1:a$="shapes demo":gosub 1900:rem titel 434 x1=110:y1=120:x2=210:y2=120:bc=1:dc=7:gosub 1700:rem color titel 440 poke lb,38:poke rb,38:poke ub,38:poke db,38 :rem shape fenster 450 sys(sp),40,199,38 455 rw=9:cm=2:md=1:a$="kugel":gosub1900 460 sys(hc),120,199,38,38 465 cm=11:a$="h-zylnd.":gosub1900 470 sys(vc),200,199 :rem voreingestellte parameter werden benutzt 475 cm=21:a$="v-zylind.":gosub1900 480 sys(tr),280,199,15,38 485 cm=32:a$=" ring":gosub1900 490 sys(vt),40,64 495 rw=23:cm=1:a$="h-ring":gosub1900 500 sys(ht),120,64 505 cm=11:a$="v-ring":gosub1900 510 sys(hs),200,64,5,100 515 cm=22:a$="h-spule":gosub1900 520 sys(vs),280,64 525 cm=32:a$="v-spule":gosub1900 530 poke 198,0:wait 198,1:poke 198,0 540 rem auf taste warten 550 : 560 rem zwei "pokale", einer mit halbton-, der andere mit "random"-schattierung 570 : 580 sys(cl):sys(co),16*11+1 582 rw=14:cm=14:a$="vergleich":gosub 1900:rw=15:cm=16:a$="zweier":gosub 1900 584 rw=16:cm=12:a$="schattierungen":gosub 1900:rw=18:cm=14:a$="<-- halbton" 586 gosub 1900:rw=20:cm=15:a$="random -->":gosub 1900 590 poke lb,255:poke rb,255:poke ub,49:poke db,255: rem an den oberen rand 600 sys(sp),80,190,80 610 poke ub,51:poke db,51: rem weitern sprite-teil anhaengen 620 sys(vs),80,69,10,130 630 poke db,9:poke ub,8 640 sys(vt),80,9,25,45 650 poke sh,0 :rem auf random schattierung umschalten 660 poke lb,255:poke rb,255:poke ub,49:poke db,255 670 sys(sp),240,190,80 680 poke ub,51:poke db,51 690 sys(vs),240,69,10,130 700 poke db,9:poke ub,8 710 sys(vt),240,9,25,45 720 poke 198,0:wait 198,1:poke 198,0 740 : 750 rem zeichne "wein" szene 760 poke lt,1 :rem hintergrungbeleuchtung 770 poke sh,1 :rem halbtonschattierung fuer flaschenetikett 780 sys(co):sys(cl),255: rem bitmap fuellen 790 poke bo,0 : rem schwarzer hintergrund 792 rw=0:cm=0:md=2:a$="zeichenen mit":gosub 1900:rw=1:cm=0:a$="rueckbeleuchtung" 794 gosub 1900:rw=2:cm=0:a$="gegen gesetzten":gosub 1900 796 rw=3:cm=0:a$="hintergrund":gosub 1900 798 rw=1:cm=26:a$="farben werden":gosub 1900 800 rw=2:cm=26:a$="nachgezeichnet":gosub1900 810 rem zeichne flasche 820 poke ub,0:poke db,255:poke lb,255:pokerb,255 830 sys(vt),150,10,30,50 840 poke ub,255:sys(vc),150,70,50,60 850 poke db,0:sys(vt),150,130,6,50 860 poke db,55:poke ub,0:sys(vs),150,204,15,181 870 poke ub,255:sys(vc),150,221,16,17 880 : 890 rem zeichene weinglas 900 poke ub,20:sys(sp),80,120,60 910 poke ub,35:poke db,34:sys(vs),80,34,10,110 920 : 930 rem zeichent ein paar trauben 940 sys(sp),8,8,8: 950 sys(sp),20,8:sys(sp),40,8:sys(sp),12,20:sys(sp),30,20:sys(sp),25,16 960 : 970 rem zeichnet apfel bestehend aus 2 ringen und einem kugelfragment 980 poke ub,255:poke db,255:poke lb,255:poke rb,59 990 sys(vt),260,29,0,50:sys(vt),260,79 1000 poke ub,43:poke db,43:sys(sp),260,54,60 1010 rem apfelstiel zeichnen 1020 poke rb,0:poke db,0:sys(tr),272,104,10,15 1030 rem blatt zeichnen 1040 poke db,255:poke rb,0:sys(sp),256,119,15 1050 rem "random"-schattiertes ettikett hinzufuegen ! 1060 poke ub,255:poke rb,255:poke lb,6 1070 poke sh,0:sys(vc),150,72,50,48 1080 : 1090 rem bild nachcolorieren 1100 sys(co),12 1110 x1=200:y1=1:x2=315:y2=100:dc=0:bc=2:gosub 1700 1120 x1=240:y1=110:x2=255:y2=150:bc=5:gosub 1700 1130 x1=260:y1=110:x2=270:y2=135:bc=9:gosub 1700 1140 x1=1:y1=1:x2=48:y2=30:bc=4:gosub 1700 1150 x1=140:y1=205:x2=180:y2=235:bc=7:gosub 1700 1160 x1=145:y1=25:x2=195:y2=115:bc=6:gosub 1700 1170 poke 198,0:wait 198,1:poke 198,0 1190 : 1200 rem "kaffee und plaetzchen" 1210 poke sh,0 :rem random-schattierung fuer plaetzchen 1220 sys(co),16*11+1:sys(cl):poke bo,1 1230 poke lb,255:poke rb,255:poke ub,255:poke db,255 :rem kein shape-fenster 1240 sys(vt),60,20,20,60 1250 poke rb,29:sys(vt),99,60:poke rb,255 1260 sys(tr),188,180 1270 rem halbtonschattierte kaffeetasse hinzufuegen. 1280 poke sh,1:poke ub,0:sys(vt),188,20:poke ub,255 1290 poke db,0:sys(tr),278,110,20,40 1300 poke db,255:poke ub,0:poke lb,0 1310 sys(tr),248,90,50,70:poke lb,255:sys(sp),248,110,10:poke ub,255 1320 sys(vc),308,100,10,10 1330 sys(vc),188,77,60,57 1340 poke db,0:sys(vt),188,134,40,60 1360 sys(co),1+16*9 :rem 1=weisser hintergrund, 9=braune punkte 1370 x1=130:y1=1:x2=319:y2=136:bc=1:dc=5:gosub 1700 1380 x1=250:y1=144:x2=319:y2=144:gosub 1700 1390 poke 198,0:wait 198,1:poke 198,0 1410 : 1420 rem zeichne "verbundene" ringe durch ueberlappung der fenster 1430 poke lt,0 :rem blaue punkte auf weiss, keine hintergrundbeleutung 1440 sys(cl):sys(co),1+16*6: rem 1=weisser intergrund, 6=blaue punkte 1450 poke ub,255:poke db,255:poke lb,255:poke rb,255: rem keine fenster 1460 poke sh,0 :rem zufaellige schattierung 1470 sys(tr),244,84,48,70 1480 sys(tr),160,84:sys(tr),76,84 1490 sys(tr),118,156:sys(tr),202,156 1500 rem ueberlappende zonen hinzufuegen 1510 poke rb,0:poke db,0:sys(tr),160,84:poke rb,255:poke lb,0 1520 sys(tr),76,84:poke db,255:poke ub,0:sys(tr),118,156 1530 poke lb,255:poke rb,0:sys(tr),202,156:poke lb,27 1540 poke db,0:poke ub,255:sys(tr),160,84 1550 poke db,0:poke ub,255:sys(tr),160,84 1560 poke lb,255:poke ub,27:sys(tr),244,84 1570 poke lb,0:poke rb,27:poke ub,255:sys(tr),244,84 1580 poke 198,0 1590 get a$:if a$= "" then 1590 1600 sys(tx):poke bo,14:rem rueckkehr zum textmodus 1610 end 1620 : 1630 rem unterprogramm zu nachcolorieren verschiedener zonen 1640 rem achtung: es kann jeweils nur eine rechteckige flaeche 1650 rem von 8x8 punkten eingefaerbt werden !! 1660 rem (x1,y1)=unterer linker punkt, (x2,y2)=oberer rechter punkt 1690 rem die y-koordinaten muessen "unskalliert" sein. falls scale-flag gesetzt: 1700 if peek(sc)then y1=(y1+1)*213/256:y2=(y2+1)*213/256 1710 rem uebergabevariable ist cc. 1720 rem cc=16*dc + bc [dc=punkt farbe, bc= hintergrundfarbe] 1730 cc=16*dc+bc 1740 for ix=int(x1/8) to int(x2/8) 1750 for iy=int(y1/8) to int(y2/8) 1760 poke 34752+ix-40*iy,cc 1770 next:next:return 1780 : 1790 rem "text"-unterroutine ermoeglicht einfuegen von text in die bilder. 1800 rem "rw" und "cm" sind die zeilen(0-24) und spalten(0-39) koordinaten des 1810 rem ersten buchstaben des zu druckenden textstrings. 1820 rem uebergabevariable fuer text ist a$ 1830 rem "md" zeigt den druckmodus an: 1840 rem 1 - normal ("schwarze" buchstaben auf "weissem" hintergrund) 1850 rem 2 - inverse ("weisse" buchstaben auf "schwarzem" hintergrund) 1860 rem 3 - buchstaben werden mit logischem oder mit hintergrund verknuepft. 1870 rem 4 - buchstaben werden mit logischem und mit hintergrund verknuepft. 1880 rem 5 - buchstaben werden mit logischem exor mit hintergrund verknuepft. 1890 : 1900 sb=40952:tb=54272:if(md and 1)then tb=53248:rem basisadressen 1910 os=320*rw+8*cm:rem adresse des zeichengenerators 1920 poke 56334,peek(56334)and 254:rem disable irq timer 1930 poke 1,peek(1)and 251:rem character rom einschalten 1940 l=len(a$):for n=1 to l:n8=n*8+os+sb 1950 x=asc(mid$(a$,n,1)):if x>63 then x=x-64 1960 tc=tb+8*x 1970 on md goto 1980,1980,1990,2000,2010 1980 poke 53231,36:goto 2020 1990 poke 53231,17:goto 2020 2000 poke 53231,49:goto 2020 2010 poke 53231,81 2020 poke252,n8/256:poke251,n8-256*int(n8/256) 2030 poke254,tc/256:poke253,tc-256*int(tc/256) 2040 sys(53221):next 2050 poke 1,peek(1)or 4:poke 56334,peek(56334)or 1:rem normal schalten 2060 return
10 rem "stellation" 20 rem by richard l. rylander 12/5/84 30 : 40 gr=49378 :rem graphik modus 50 tx=49411 :rem text modus 60 bo=53280 :rem rahmenfarbe 70 : 80 rem style parameters 90 poke 839,1 :rem skalierung (3:4) 100 poke 871,0 :rem facettenraender (0=nachzeichnen, 1=loeschen) 110 sh=838 :rem schattierung (0=random, 1=halbton) 120 eg=868 :rem randflag (0=normal, 1=linien am rand hinzufuegen) 130 : 140 rem funktions adressen 150 cl=51979 :rem bitmap loeschen 160 co=52001 :rem color map fuellen 170 fc=52052 :rem schattierte facetten zeichnen 180 ks=53081 :rem sortierroutine 190 : 200 xc=160:yc=120 :rem zentrierungskoordinaten 210 : 220 print"{clr}***************************************" 230 print"* kleiner sternfoermiger dodekahedron *" 240 print"***************************************" 250 print"{down}{down} schattierung:" 260 print" r=random, h=halbton" 270 input"{down} ihre wahl h{left}{left}{left}";a$ 280 poke sh,0:if a$="h" then poke sh,1 290 print"{down}{down} rand-stil :" 300 print"{down} n - normal":print"{down} e - eckenbetonung" 310 print"{down} w - drahtgitter" 320 input"{down} ihre wahl n{left}{left}{left}";a$ 330 poke eg,0:wi=0:if a$="n" then 360 340 poke eg,1:if a$="w" then wi=-1 350 : 360 print"{down} lese scheitel daten" 370 vn=32:dim p%(vn-1,2) 380 for n=0 to vn-1:read p%(n,0),p%(n,1),p%(n,2):next 390 : 400 print"{down} geben sie x, y, und z winkel ein" 410 print" (winkel in grad)" 420 input x,y,z 430 j=3.14159265/180:x=x*j:y=y*j:z=z*j 440 x0=cos(y)*cos(z)-sin(x)*sin(y)*sin(z):x1=cos(y)*sin(z)+sin(x)*sin(y)*cos(z) 450 x2=-cos(x)*sin(y):y0=-cos(x)*sin(z):y1=cos(x)*cos(a):y2=sin(x) 460 z0=sin(y)*cos(z)+sin(x)*cos(y)*sin(z) 470 z1=sin(y)*sin(z)-sin(x)*cos(y)*cos(z):z2=cos(x)*cos(y) 480 print"{down} rotationsberechnung" 490 for n=0 to vn-1 500 x=p%(n,0):y=p%(n,1):z=p%(n,2) 510 p%(n,0)=x0*x+x1*y+x2*z:p%(n,1)=y0*x+y1*y+y2*z:p%(n,2)=z0*x+z1*y+z2*z:next 520 : 530 fa=60: rem anzahl der facetten 540 dim f%(fa/2,2),sh(fa/2),z%(fa/2),k%(fa/2) 550 print" lese verbindungsdaten " 560 vf=-1: rem vf = anzahl der sichtbaren facetten 570 for n=1 to fa 580 vf=vf+1 590 for i=0 to 2 :read f%(vf,i):next 600 rem berechnung der normalenvektoren 610 z=(p%(f%(vf,2),0)-p%(f%(vf,1),0))*(p%(f%(vf,0),1)-p%(f%(vf,1),1)) 620 z=z-(p%(f%(vf,0),0)-p%(f%(vf,1),0))*(p%(f%(vf,2),1)-p%(f%(vf,1),1)) 630 if z=<0 then 720:rem facette nicht sichtbar 640 x=(p%(f%(vf,2),1)-p%(f%(vf,1),1))*(p%(f%(vf,0),2)-p%(f%(vf,1),2)) 650 x=x-(p%(f%(vf,0),1)-p%(f%(vf,1),1))*(p%(f%(vf,2),2)-p%(f%(vf,1),2)) 660 y=(p%(f%(vf,2),2)-p%(f%(vf,1),2))*(p%(f%(vf,0),0)-p%(f%(vf,1),0)) 670 y=y-(p%(f%(vf,0),2)-p%(f%(vf,1),2))*(p%(f%(vf,2),0)-p%(f%(vf,1),0)) 680 nc=sqr(x*x+y*y+z*z):rem laenge des normalenvektors 690 sh(vf)=26*(2*z+x+y)/nc 700 sh(vf)=(sh(vf)+64)*(sh(vf)+64)/256:rem schattierung 710 goto 730 720 vf=vf-1 730 next 740 : 750 print" berechnung der darstellungsgroesse" 760 y=0:for n=0 to vn-1:if abs(p%(n,1))>y then y=abs(p%(n,1)) 770 next:s=119/y 780 for n=0 to vn-1:p%(n,1)=s*p%(n,1)+yc:p%(n,0)=s*p%(n,0)+xc:next 790 : 800 : 810 for n=0 to vf 820 z%(n)=(p%(f%(n,0),2)+p%(f%(n,1),2)+p%(f%(n,2),2))/3:next 830 : 840 print" sortierung der facetten" 850 poke 140,vf 860 k%(0)=k%(0):poke 251,peek(71):poke 252,peek(72) 870 z%(0)=z%(0):poke 253,peek(71):poke 254,peek(72) 880 sys(ks) 890 : 900 rem zeichne facetten 910 sys(gr):sys(co):sys(cl):poke bo,1 920 for n=0 to vf:fa=k%(n) 930 if wi then sh(fa)=64 940 x0=p%(f%(fa,0),0):y0=p%(f%(fa,0),1):x1=p%(f%(fa,1),0):y1=p%(f%(fa,1),1) 950 x2=p%(f%(fa,2),0):y2=p%(f%(fa,2),1) 960 sys(fc),x0,y0,x1,y1,x2,y2,sh(fa) 970 next 980 poke198,0 990 get a$:if a$="" then 990 1000 sys(tx):poke bo,14:end 1010 : 1020 rem scheiteldaten 1030 data 1000,618,0, 1000,-618,0, -1000,618,0, -1000,-618,0 1040 data 0,1000,618, 0,1000,-618, 0,-1000,618, 0,-1000,-618 1050 data 618,0,1000, -618,0,1000, 618,0,-1000, -618,0,-1000 1060 data 618,0,236, 618,0,-236, -618,0,236, -618,0,-236 1070 data 236,618,0, -236,618,0, 236,-618,0, -236,-618,0 1080 data 0,236,618, 0,-236,618, 0,236,-618, 0,-236,-618 1090 data 382,382,382, 382,382,-382, 382,-382,382, 382,-382,-382 1100 data -382,382,382, -382,382,-382, -382,-382,382, -382,-382,-382 1110 : 1120 rem verbindungsdaten 1130 data 0,12,13, 0,13,25, 0,25,16, 0,16,24, 0,24,12 1140 data 1,12,26, 1,26,18, 1,18,27, 1,27,13, 1,13,12 1150 data 2,15,14, 2,14,28, 2,28,17, 2,17,29, 2,29,15 1160 data 3,14,15, 3,15,31, 3,31,19, 3,19,30, 3,30,14 1170 data 4,16,17, 4,17,28, 4,28,20, 4,20,24, 4,24,16 1180 data 5,17,16, 5,16,25, 5,25,22, 5,22,29, 5,29,17 1190 data 6,19,18, 6,18,26, 6,26,21, 6,21,30, 6,30,19 1200 data 7,18,19, 7,19,31, 7,31,23, 7,23,27, 7,27,18 1210 data 8,20,21, 8,21,26, 8,26,12, 8,12,24, 8,24,20 1220 data 9,21,20, 9,20,28, 9,28,14, 9,14,30, 9,30,21 1230 data 10,23,22, 10,22,25, 10,25,13, 10,13,27, 10,27,23 1240 data 11,22,23, 11,23,31, 11,31,15, 11,15,29, 11,29,22
