********* Welcome to International Project 64! The goal of International Project 64 is to preserve non-English Commodore 64 related documents in electronic text format that might otherwise cease to exist with the rapid advancement of computer technology and declining interest in 8-bit computers on the part of the general population. If you would like to help by converting C64 related hardcopy documents to electronic texts please contact the manager of International Project 64, Peter Karlsson, at m9944@abc.se. Extensive efforts were made to preserve the contents of the original document. However, certain portions, such as diagrams, program listings, and indexes may have been either altered or sacrificed due to the limitations of plain vanilla text. Diagrams may have been eliminated where ASCII-art was not feasible. Program listings may be missing display codes where substitutions were not possible. Tables of contents and indexes may have been changed from page number references to section number references. Please accept our apologies for these limitations, alterations, and possible omissions. Document names are limited to the 8.3 file convention of DOS. The first characters of the file name are an abbreviation of the original document name and the language of the etext. The version number of the etext follows next. After that a letter may appear to indicate the particular source of the document. Finally, the document is given a .TXT extension. The author(s) of the original document and members of International Project 64 make no representations about the accuracy or suitability of this material for any purpose. This etext is provided "as-is". Please refer to the warantee of the original document, if any, that may included in this etext. No other warantees, express or implied, are made to you as to the etext or any medium it may be on. Neither the author(s) nor the members of International Project 64 will assume liability for damages either from the direct or indirect use of this etext or from the distribution of or modification to this etext. Therefore if you read this document or use the information herein you do so at your own risk. ********* The International Project 64 PRE-RELEASE etext of the Swedish Comal-80 0.12/0.14 manual, converted to text by Peter Karlsson COMALSE0.TXT, May 1997, etext #7. Note from the etexter (in Swedish): Ofta förekommande stavfel (som **sekvensiella (sekventiella) och **formattera (formatera)) har rättats, men inte feluttryck som initialisera (initiera), och saker som det numera finns andra ord för (printer - skrivare, mod - läge). Ej heller har onödiga bindestreck tagits bort (kommando-rad, sprite-grafik). Danska namn har skrivits om med danska bokstäver, och vissa saknade tecken har lagts till. I övrigt har ingen ändring gjorts, mer än layoutmässig, för att det ska vara enklare att läsa som text. Rubriker är markerade med en asterisk (*) i vänstermarginalen, och uppslagsord i kommandolistninger är markerade med plustecken, för att underlätta sökning. Om du vill söka efter kommandot "PRINT" söker du på "+ PRINT". Förhandsversion - programlistningar saknas. Eftersom texten är inläst via bildläsare och OCR-program kan vissa ord vara helt uppåt väggarna fel. Om du hittar sådana, rapportera de gärna, så det kan rättas. ********* HANDBOK för VIC 64 ***** COMAL-80 av BØRGE R. CHRISTENSEN ################################ (Diskettversion: rev. 00.12 för VIC-64 med VIC 1541) © 1984, författaren och Förlagsgruppen för teknisk utbildning i Norrköping AB Upplaga 1:1 1000 ex Översättning: Å Fredriksson Sättning: DELTA Tryck: GRAFAX ISBN 91-86398-32-6 Distribution: Handic Electronic AB Box 1063 436 00 ASKIM/GÖTEBORG Tel: 031-28 97 90 Litteratur och föreningstjänst Box 1338 17126 SOLNA Tel: 08-730 02 75 Förlagsgruppen Nygatan 85 602 34 NORRKÖPING Tel: 011-13 40 80 * Förord Programspråket COMAL (COMmon Algorithmic Language) definierades 1973 av Benedict Løfstedt och undertecknad med utgångspunkt i en önskan att göra tillvaron lättare för de människor, som vill programmera datorer utan att nödvändigtvis vara professionella programmerare. Vi startade med språket BASIC och det på den tiden helt nya Pascal. Om man ser lite närmare på BASIC finner man; att huvudanledningen till att det är så lätt att använda, kan sökas i dess s k operativa miljö mer än i språket som sådant. En nybörjare som använder BASIC, kan knappa in en eller några programsatser och få dessa utfärda med hjälp av ett enkelt kommando. Radnumren används för att radera eller sätta in nya satser och ange deras ordningsföljd, dvs när de skall utföras. Man behöver ingen krävande editor eller ett invecklat kommandospråk till ett operativsystem. Indata och utdata förmedlas enkelt över terminalen/datorns tangentbord/bildskärm eller över en printer. Å andra sidan råder det inget tvivel om, att BASIC som programspråk betraktat är hopplöst föråldrat. Det har aldrig varit något speciellt bra språk och ur modern synvinkel är det en ren katastrof. Om man börjar att programmera i BASIC kommer man lätt på avvägar och får efter kort tid problem att slåss med, som kan lösas mycket lättare med ett programspråk som i högre grad är anpassat till det sätt som människan tänker på. COMAL har samma enkla operativa miljö som kännetecknar BASIC. Det har även detta språks enkla kommandon som t ex INPUT, PRINT, READ osv. Därtill har det också några kommandon som hämtas från Pascal. Med COMAL är det lätt - ja nästan oundvikligt - att skriva välstrukturerade program. I stället för att leda användaren bort från de moderna, effektiva strukturerade metoderna i programmeringen ger COMAL en nära nog perfekt inlärning av denna metod. Med COMAL-80 till VIC-64 är det nu för var och en möjligt att lära känna och kunna öva sig i att använda moderna programmeringsprinciper. Som den Farsta COMAL-80 någonsin, omfattar VIC-64 COMAL-80 enkla men effektiva styrinstruktioner för högupplösningsgrafiken, som är inbyggd i VIC-64. Detta ger helt nya mödligheter- inte minst för undervisningen i skolorna. VIC-64 COMAL-80 ger en hittills osedd kombination av slagkraftig programmering och ett material med många inbyggda mödligheter. Tønder, oktober, 1983 Børge R. Christensen * Inläsning och start av COMAL-80 Din COMAL-80-tolk levereras på två disketter. De är identiskt lika. Du kan inte kopiera disketterna och du bör alltså använda den ena disketten i ditt dagliga programmeringsarbete med COMAL-80 och förvara den andra på en skyddad plats. Använd bara denna andra diskett, om du på grund av någon olyckshändelse får din arbetsdiskett förstörd. Skulle olyckan vara framme och arbetsdisketten bli förstörd, då kan du mot en mindre expeditionsavgift få en ny arbetsdiskett. Du bör dock lägga märke till att ett sådant ombyte är förbundet med två villkor: 1. Att den förstörda eller defekta disketten lämnas till säljaren. 2. Att ditt registerkort, som finns längst bak i denna bok, har fyllts i och finns hos Förlagsgruppen vid bytestillfället. Du bör därför, innan du överhuvudtaget börjar arbeta med din COMAL-80-tolk, fylla i och sända in detta registreringskort till Förlagsgruppen Nygatan 85, 602 34 Norrköping. Märk kuvertet "Comal-garantikort". På disketten finns olika slags programfiler. Av dessa skall speciellt nämnas: BOOT COMAL AUTOBOOT COMAL.1 COMAL.2 GENERROR.E.L De två första är programfiler i BASIC, som kan användas för att starta upp din nyförvärvade COMAL-80. Du kan använda följande metoder: [1] Skriv: LOAD "BOOT COMAL",8 och tryck på -tangenten När texten READY kommer fram, slår du in: RUN och trycker på -tangenten. Nu sätter inlåsningen av COMAL-80-tolken igång och efter ca 1,5 minuter är COMAL-80 inläst och klar att använda. I stället för ovanstående startprocedur kan du göra så här: [2] Skriv: LOAD"AUTOBOOT",8,1 och tryck på . Nu startar inläsningen av COMAL-80 automatiskt och efter ca 1,5 minuter är den inläst och klar att använda. Programmen COMAL.1 och COMAL.2 används under uppstartningen efter denna procedur och kan inte läsas in av dia. Programmet GENERROR.E.L är en listfil, som kan läsas in i COMAL-80, (se ENTER). Efter inläsning av filen kan programmet köras, och det kan användas för att förse varje diskett med alla COMAL-80:s feltexter. Detta program är speciellt värdefullt, om du vill nyformatera oanvända disketter för att spara COMAL-80-program. Utan GENERROR.E.L, kommer COMAL-80-tolken endast att skriva ut ett felnummer, om du t ex skulle ha ett syntaxfel. Om Du däremot har kört in programmet GENERROR.E.L på den nyformaterade disketten, kan COMAL-80 istället skriva ut felmeddelandena i klartext (se även SETMSG). Utöver de här nämnda programmen, innehåller disketten en mängd program, som fungerar som förklarande exempel till denna användarhandbok. Dessa program finns också listade längst bak i boken. Programmen kan kopieras fritt från diskett till diskett (använd LOAD och SAVE eller LIST och ENTER). Men var snäll och kom ihåg att programmen omfattas av normal upphovsrätt och därför inte får användas i kommersiellt bruk! Denna handbok är inte någon lärobok utan snarare en uppslagsbok, där alla kommandon och funktioner har listats i alfabetisk ordning tillsammans med en översikt över deras individuella syntax. Vi gör inget försök att lära ut COMAL-80 till användaren, som därför hänvisas till litteraturhänvisningen som finns längst bak i boken. Du kan köpa extra exemplar av handboken från din VIC-handlare eller direkt från Förlagsgruppen. Såväl programdiskett och dess innehåll som denna handbok omfattas av copyright, upphovsmannarätt, som innehas av författaren och det förlag som angivits. De må därför icke i någon form kopieras, rättas, ändras eller försäljas. Försäljning kan endast ske genom auktoriserade VIC-representanter. Lycka till! + ABS Se under STANDARDFUNKTIONER + AND Se under UTTRYCK + APPEND Se under OPEN + ATN Se under STANDARDFUNKTIONER + AUTO AUTO är ett kommando, som får COMAL-systemet att sätta radnummer automatiskt under programskrivningen. Efter AUTO har knappats in, och man tryckt på skriver systemet: 0010 och väntar på att man skriver in en rad. När raden avslutas med tryck på , svarar systemet: 0020 och väntar på ytterligare en rad. Man stänger av AUTO genom att avsluta en rad med två nedslag på tangenten. Om ordet AUTO följs av ett tillåtet radnummer, börjar listan av framtagna nummer med detta. T ex får kommandot: AUTO 110 systemet att ta fram följande radnummer: 0110, 0120, 0130, ... Lägger man till ett komma, följt av ytterligare ett heltal, använder systemet detta som tillväxtfaktor för radnumren. Alltså får kommandot: AUTO ,2 systemet att ta fram denna följd av radnummer 0010, 0012, 0014, ... och AUTO 110,2 får systemet att numrera inslagna rader med: 0110, 0112, 0114, ... + BASIC BASIC är ett kommando, som får systemet att skifta över till den inbyggda BASIC-tolken. COMAL-tolken kan endast återstartas genom att man företar en förnyad inläsning av den från disketten (se Inläsning och uppstartning av COMAL i inledningen till handboken). + CASE WHEN + OTHERWISE + ENDCASE CASE-satsen används som inledning till en CASE-struktur som anger en flerfaldig förgrening. Syntaxen för en CASE-sats är: CASE [OF] är ett numeriskt uttryck, ett textuttryck eller ett logiskt uttryck. Nyckelordet OF står inom hakparentes för att ange, att det automatiskt sätts dit av systemet, om användaren inte själv skriver det. En CASE-sats kan bara användas, om det sker tillsammans med WHEN- och ENDCASE-satserna. Syntaxen för en WHEN-sats är: WHEN Uttrycken i listan skall vara av samma typ som uttrycket i den tillhörande CASE-satsen. Uttrycken i listan skall vara skilda med kommatecken (,). ENDCASE-satsen består endast av ett ord: ENDCASE Man kan också ha en OTHERWISE-sats i CASE-strukturen. Syntaxen är: OTHERWISE CASE-strukturen är uppbyggd som visas i följande diagram: CASE OF WHEN ,', ,' ', +---------. programavsnitt A-1 ---+---| lista 1 > A-1 ', ,' | +---------' · WHEN ',' _____|_________________| ,' | +---------. programavsnitt A-2 | |---| lista 2 > A-2 | | +---------' · |______|_________________| ... | | : : WHEN : : | | +---------. programavsnitt A-n | |---| lista n > A-3 | | +---------' · OTHERWISE |______|_________________| | | Programavsnitt B | `--------------> B | · ENDCASE |________________________| | v Efter det att uttrycket efter CASE har utvärderats, undersöks listan efter det första WHEN. Om ett av uttrycken ger samma värde som CASE-uttrycket, utförs programavsnittet A-t, och därefter fortsätts med de satser som står efter ENDCASE. Om värdet av CASE-uttrycket inte återfinns bland uttrycken i den första WHEN-satsen, undersöks nästa lista och om likhet hittas där, utförs satserna A-2 och därefter fortsätts efter ENDCASE. Har värdet ännu inte återfunnits, fortsätts med den tredje WHEN-listan osv. Ett alternativt programavsnitt, B, kan sättas in och blir utfört, om uttryckets värde (i CASE-satsen) inte återfinns i någon WHEN-lista. Detta avsnitt skall inledas med en OTHERWISE-sats. OTHERWISE-delen kan utelämnas, men i så fall stoppar COMAL-tolken programutförandet med ett felmeddelande, om uttrycket efter CASE-satsen inte återfinns i någon av WHEN-satserna. Lägg märke till, att högst ett av programavsnitten blir utfört. Skulle det vara så, att uttryckets värde kan finnas i mer än en av listorna (efter WHEN), blir bara programavsnittet för den första listan som har "rätt" värde utförd. Programtexten i A-1, A-2, ... A-n och B kommer att visas med "indrag" under utlistning av programmet. Detta ser COMAL-tolken till automatiskt. Exempel: se angivna rader i programmen "småtexter": 540-690,1610-1700; "kartotek": 400-530 OBS! kolla efter pgmövers.! + CAT CAT är ett kommando, som används för att skriva ut diskens innehållsförteckning (katalogen) som visar de filer som finns på disketten. + CHAIN Satsen: CHAIN "" gör, att programmet blir inläst i datorns minne från diskett i 1541-stationen. Ett program med tillhörande variabler, som kanske finns i arbetsminnet innan CHAIN-satsen utförs, kommer att raderas. Det inlästa programmet körs omedelbart efter inläsningen. CHAIN kan också användas som kommando: Exempel: CHAIN "inläsning", CHAIN "huvudprogram". + CHR$ Se under STANDARDFUNKTIONER + CLOSE Satsen: CLOSE gör, att alla filer stängs. Fogar man till ett numeriskt uttryck, får man: CLOSE Denna utgåva av CLOSE stänger endast den fil, som har samma nummer som svarar mot värdet av . CLOSE kan också utföras som direktkommando. Exempel: se angivna rader i "kartotek": 2590, 2710. + CLOSED Om ett procedurhuvud avslutas med nyckelordet CLOSED blir de variabler, som förekommer i proceduren, antagna att vara lokala, dvs samma variabler kan användas i "ytterprogrammet" utan risk för påverkan. Normalt sker detta endast för parametrarna (se även PROCsatserna). Exempel: PROC FÖNSTER(FRÅN,TILL) CLOSED SCREEN(FRÅN,1) FOR I := FRÅN TO TILL DO EXEC RADERA'RAD(I) SCREEN(FRÅN,1) ENDPROC FÖNSTER PROC SCREEN(L,C) CLOSED PRINT CHR$(19) // HOME FOR I := 1 TO L-1 DO PRINT CHR$(17), // NED FOR I := 1 TO C-1 DO PRINT CHR$(29), // FRAM ENDPROC SCREEN PROC RADERA'RAD(L) CLOSED SCREEN(L,1) FOR I := 1 TO 40 DO PRINT " ", ENDPROC RADERA'RAD // + CON Kommandot: CON återupptar utförandet av ett program, som stoppats med nedtryckning av STOP-tangenten eller med en STOP-sats. På grund av hur den interna lagringen av variabler etc. sker, kan inte detta kommando utföras sedan man har lagt till eller tagit bort programrader eller tillfogat nya variabelnamn. + COS Se under STANDARDFUNKTIONER + DATA DATA-satsen används för att ange konstanter, som skall läsas med READ-satser (se även READ). Konstanterna skiljs åt med kommatecken. DATA-satserna kan placeras var som helst i programmet, de läggs vid programmets start i en datakö, vars element läses i den ordning de förekommer i programmet. Talkonstanter kan skrivas med förtecken. Textkonstanter skall omges med citationstecken ("). Exempel: DATA "Hans Andersson", 5678, "Peter Jansson", 1245 DATA "Lina Hansson", 4567, "Lisa Jakobsson", 2578 + DEL DEL-kommandot används för att ta bort en eller flera rader från programmet i maskinens minne. T ex tar kommandot: DEL 100 bort rad 100. Kommandot: DEL 100-200 tar bort alla rader mellan och inklusive 100 till 200. Kommandot: DEL -300 tar bort alla rader till och med rad 300 och kommandot: DEL 300 tar bort alla rader från och med rad 300 OBS! man kan inte ta bort en rad bara genom att skriva radnumret följt av tryck på . Det går bara i BASIC! + DELETE DELETE-kommandot används för att radera filer på disk. Exempel: Kommandot DELETE "0:gammaltext" raderar filen "gammaltext" på disketten (se även PASS) + DIM DIM-satsen används som i BASIC till att deklarera tabeller och textvariabler. I COMAL-80 kan man deklarera tabeller med hur många dimensioner som helst och indexnumreringen behöver inte börja med 0 eller 1. Låt oss se på några exempel: DIM TABELL(100) deklarerar en tabell med reella tal med index gående från 1 till 100. Vill man att undre gränsen skall vara 0, skall man skriva: DIM TABELL(0:100) Man kan använda vilket heltal som helst till nedre eller övre gräns, om bara det första är mindre än eller lika med det andra heltalet. DIM FÄLT (-7:7) deklarerar en tabell med index från och med -7 till och med 7. Satsen: DIM ELEV(30:100,8:10) deklarerar en tvådimensionell siffertabell med index från 30 till 100 och från 8 till 10. Satsen: DIM NAMN$(30:100,8:10) OF 30 deklarerar en tvådimensionell texttabell med index från 30 till 100 och från 8 till 10. Varje komponent har plats för 30 tecken. DIM NAMN$ OF 30 deklarerar en enkel textvariabel med plats för 30 tecken. Enkla textvariabler måste alltid deklareras i COMAL-80. Exempel: se angivna radnummer i "småtext": 50-170; "kartotek": 80-160. + DIV DIV är en operator som används vid heltalsdivision. Den definieras av: A DIV B = INT(A/B) (heltalsdelen av div.) där A och B kan vara reella tal eller hela tal. Se även under MOD och under UTTRYCK. + DO DO är ett nyckelord, som används för att avsluta en FOR eller en WHILE-sats. Se under FOR och WHILE. + EDIT EDIT-kommandot används för att skriva ut programraderna i maskinens minne, men utan den indragning, som vanligen skapas av LIST-kommandot. EDIT används for att skriva ut rader från ett program, som skall rättas med hjälp av skärmeditorn, i de fall några av dessa rader skulle bli överskrivna om kommandot LIST används. + ELIF ELIF-satsen ("elseif") kan endast användas i samband med en IF-sats. Se under IF. + ELSE ELSE-satsen kan endast användas i samband med en IF-sats. Se IF. + END END-satsen gör, att utförandet av programmet stoppas. + ENDCASE ENDCASE används för att avsluta det sista programblocket i en CASE-konstruktion. Se under CASE. + ENDFOR ENDFOR används för att avsluta en FORslinga och ersätter automatiskt kommandot NEXT. Se under FOR. + ENDIF ENDIF används för att avsluta det sista blocket med satser i en IF-konstruktion. Se IF. + ENDFUNC ENDFUNC-satsen används för att avsluta en användardefinierad funktion. Se under FUNC. + ENDPROC ENDPROC-satsen används för att avsluta en procedur. Se under PROC. + ENDWHILE ENDWHILE-satsen används för att avsluta det satsblock som styrs av en tillhörande WHILE-sats. Se under WHILE. + ENTER Kommandot: ENTER "", gör att programmet läses in från enheten som har numret . Om inget enhetsnummer är angivet, använder systemet disken (nr 8). Om en hetsnumret är angivet till 1, använder systemet bandspelaren. Man kan endast hämta fram program, som sparats med LIST-kommandot (se LIST), på detta sätt. De rader, som läses in med ENTER, flätas samman med de rader, som redan finns i minnet på samma sätt som om raderna knappats in via tangentbordet (till skillnad från vid LOAD). + EOD EOD (End-Of-Data) är en logisk funktion, som antar värdet TRUE (sant), så snart det sista värdet i datalistan har lästs (eller listan är tom). Exempel: REPEAT READ NAMN$(I), TELENR(I) I:+1 (vilket betyder "I:=I+1") UNTIL EOD MAX:=I-1 DATA "David Bengtsson", 554564, "Martin Eriksson", 234567 DATA "Jens Erik Jenssen", 200330, "Olle Holmgren", 611100 + EOF EOF (End-Of-File) är en logisk funktion. EOF(X), där X är ordningsnumret på en sekventiell fil, antar värdet TRUE (sant), när sista posten i filen har hämtats. Exempel: OPEN FILE 2, "NYCKLAR", READ REPEAT READ FILE 2: NAMN$, ADRESS$, STAD$ PRINT NAMN$ PRINT ADRESS$ PRINT STAD$ UNTIL EOF(2) CLOSE + ESC Ordet ESC används dels i TRAP-satsen (se denna), dels som en STANDARDFUNKTION (se dessa). + ETIKETTER (Labels) En etikett kan användas som en hoppadress för en GOTO-sats. Syntaxen för etikett är: : Exempel: WHILE TRUE DO // OÄNDLIG SLINGA INPUT NAMN$ IF NAMN$="" THEN GOTO HALT ... ... ENDWHILE HALT: OBSERVERA! GOTO kan INTE användas i COMAL-80/VIC-64. + EXEC EXEC är ett ord, som kan sättas framför ett procedurnamn i ett anrop på proceduren. Om ordet används, får proceduranropet denna syntax: EXEC () Normalt används ordet EXEC icke i CBM COMAL-80, men med hänsyn till jämförbarheten med äldre versioner av COMAL, accepteras ordet av förtolken, och kan under listningen återges av systemet, när kommandot SETEXEC (se detta ord) används. En närmare beskrivning av procedurer och parametrar finns under PROC. + EXP Se under STANDARDFUNKTIONER + FALSE Två konstanter, TRUE (sant) och FALSE (falskt) är fördefinierade, för att förbättra programmens läsbarhet. TRUE svarar mot 1 och FALSE är lika med 0 I COMAL-80 betraktas ett numeriskt uttryck i relevant sammanhang som FALSKT, om det har värdet 0, i övrigt anses det vara SANT. Exempel: Efter tilldelningen: SLUT := FALSE har det logiska uttrycket: TAL>MAX AND SLUT värdet FALSE. I verkligheten är SLUT inget annat än en numerisk variabel med värdet noll, och den kan också i övrigt användas som sådan, om man vill. + FILE FILE är ett nyckelord, som används i READ/WRITE och INPUT/PRINT-satser när de används i förbindelse med filhantering. Se READ FILE, WRITE FILE, INPUT FILE och PRINT FILE. + FOR FOR-satsen och FOR-slingor fungerar på samma sätt som i BASIC. Dock är COMAL-80 utvidgad med: FOR <"som i BASIC"> DO Nyckelordet DO används endast för att skilja FOR-delen från den följande programsatsen (ungefär som THEN i den "långa" IF-satsen). Den "långa" FOR-satsen kan också användas som kommando. OBSERVERA! En flerradig FOR-slinga avslutas med en ENDFOR-sats. Förtolken accepterar dock även ordet NEXT som i BASIC, men ändrar automatiskt detta till ENDFOR. Man behöver inte knappa in index-variabeln efter ENDFOR. Om den icke slås in, sätter förtolken in den automatiskt vid första körningen av programmet. Exempel: "småtext", raderna 2120-2330, "kartotek", raderna 2860, 2910, 2920, 2960 etc. + FUNC + ENDFUNC + RETURN FUNC-satsen används för att inleda en användardefinierad funktion. ENDFUNC används för att avsluta en sådan funktion, och med RETURN-satsen sänder man tillbaka funktionens värde till programmet. FUNC-satsen har denna syntax: FUNC () ENDFUNC-satsen har denna syntax: ENDFUNC RETURN-satsens syntax är: RETURN En funktion är uppbyggd efter följande schema: FUNC () ... ... RETURN ... ENDFUNC Som visas ovan kan listan med formella parametrar vara tom. Man kan ha flera RETURN-satser i funktionens "kropp", men man måste ha minst en, som kan ange funktionsvärdet till huvudprogrammet. Funktioner i denna COMAL-version (00.12), kan endast ge tillbaka talvärden (hela eller decimala). Funktioner kan vara slutna, liksom procedurer (se under CLOSED). Exempel: FUNC SFD(X,Y) IF X MOD Y=0 THEN // OM X KAN DELAS MED Y RETURN Y // Y ÄR STÖRSTA GEMENSAMMA DIVISOR ELSE RETURN SFD(Y,X MOD Y) // ANVÄND EUKLIDES ALGORITM ENDIF ENDFUNC SFD Denna funktion kan t ex anropas med satsen: IF SFD(A,B)=1 THEN PRINT "TALEN ÄR EJ DELBARA MED VARANDRA" Andra exempel: "småtext", raderna 2770-2830, 2850-2910. + GOTO GOTO-satsen åstadkommer att programutföringen fortsätter på ett bestämt ställe i programmet. Syntaxen är: GOTO Se under ETIKETT för närmare definition av och exempel på hur en GOTO-sats används. MÄRK VÄL!! Resultatet av ett uthopp från en procedur är oförutsägbart!! + INT Se under STANDARDFUNKTIONER + IN IN är en operator, som används i förbindelse med textsträngar. Uttrycket: IN har värdet 0 om ej finns som en sammanhängande deltext i . Om däremot finns som en sammanhängande deltext i så blir värdet av uttrycket positionen på (=läget av) första förekomsten av i , dvs numret på det tecken i som bildar början på . Om är den "tomma textmängden", "", ger uttryckets värde längden på plus ett, dvs detsamma som BASICs LEN()+1. Exempel: "småtext", rad 2010. + INPUT INPUT-satsen har följande syntax: INPUT ; eller: INPUT : ; där är ett textuttryck. Anmärkning: Om det finns mer än en textvariabel i variabellistan, skall varje text avslutas med ett tryck på RETURN-tangenten under inknappningen. Orsaken till detta är, att i COMAL-80 uppfångas ALLA tecken som knappas in av en textvariabel, alltså även citationstecken och kommatecken, som alltså inte kan användas som skiljetecken mellan texter. Ingår ett funktionsanrop i variabellistan (t ex som index till ett tabell-element) så får dessa icke innehålla INPUT-satser, då dessa i så fall kommer att radera innehållet i indata-bufferten. Avslutas INPUT-satsen med ett semikolon (;) fungerar det så, att markören stannar på raden efter inläsningen. Exempel: "kartotek", raderna 390, 910,1520. + INPUT FILE INPUT FILE-satsen används för att hämta data från sekventiella eller direkta filer, när dessa data lagrats undan med en PRINT FILE-sats. T ex gör satsen: INPUT FILE 2: NAMN$, ADRESS$, STAD$ att värden tilldelas variablerna i listan efter kolonet (:) genom att värdena hämtas sekventiellt i den fil, som öppnats med ordningsnumret 2 (se även OPEN). Satsen: INPUT FILE 2,I: NAMN$, TELEFON hämtar värden till variablerna på listan i post nr I i den direkta fil, som öppnats med ordningsnumret 2. MÄRK VÄL! När man hämtar data från en diskett, använder man normalt READ FILE-satsen (se detta ord), eftersom den är snabbare än INPUT FILE-satsen. Om man hämtar data från kassettbandspelaren (Datasetten) är man hänvisad till enbart INPUT FILE-satsen. När man hanterar data på diskett använder man normalt satserna WRITE FILE/READ FILE. Då man hanterar data på kassett skall man använda PRINT FILE/INPUT FILE. Var också uppmärksam på att man inte kan använda direkta filer tillsammans med kassettbandspelaren. Se även OPEN FILE. Exempel: "kartotek", raderna 2530, 2560. + IF + ELSE + ELIF + ENDIF Syntaxen för en IF-sats är: IF THEN eller: IF THEN Den första formen kan endast användas tillsammans med en ENDIF-sats. I detta fall kan THEN uteslutas och i så fall lägger förtolken till det själv. ELIF-satsen har syntaxen: ELIF THEN En ELSE-sats består endast av ordet ELSE, och en ENDIF-sats är också bara ett ord. De fyra satserna ingår i följande strukturer: a. IF .. ENDIF SANT ------> IF THEN +---------. Programavsnitt A | | uttryck > A FALSKT | +---------' · ENDIF | |-----------' V v Om har ett värde som motsvarar SANT (TRUE), utförs programavsnittet A. Ar värdet av FALSKT (FALSE), ignoreras blocket A och förtolken fortsätter utförandet med programavsnitten efter ENDIF-satsen. Programtexten mellan IF och ENDIF rycks in under utlistningen av programmet. b. IF .. ELSE .. ENDIF IF THEN +---------. Programavsnitt A | uttryck > A +---------' · ELSE .-----|-----------' | | Programavsnitt B | `---------> B | · ENDIF |-----------------' v Om värdet av uttrycket är TRUE, utförs programavsnitt A. Motsvarar värdet FALSE, utförs programavsnitt B. Programtexten mellan styrsatserna kommer att dras in under utlistningen. c. IF .. ELIF .. ELSE .. ENDIF IF THEN +---------. Programavsnitt A | uttryck > A +---------' · ELIF THEN .-----|------------' | +-----------. Programavsnitt A-1 | | uttryck-1 > A-1 | +-----------' · ELIF THEN |-----|-------------' | +-----------. Programavsnitt A-2 | | uttryck-2 > A-2 | +-----------' · ... |-----|-------------' | : ... | : | : ELSE | | | | Programavsnitt B | `---------> B | · ENDIF |------------------' v Nyckelordet ELIF är en sammandragning av ELSE IF. Som visats i blockdiagrammet vid sidan av figuren kommer endast ett av programblocken i strukturen att bli utfört. Lägg märke till att om mer än ett av uttrycken är sant, så blir bara det programblock, som har det första sanna uttrycket utfört. Det sista alternativet har ELSE utelämnat och vi får: d. IF .. ELIF .. ELIF .... ENDIF Lägg märke till att då vi får alla programblock mellan styrsatserna indragna under utlistningen, är det mycket lätt att upptäcka om det avslutande ENDIF är bortglömt. Det är också lätt att överblicka hela det område som en IF-sats styr, och att se, om en given sats finns med i ett av blocken eller inte. IF THEN +---------. Programavsnitt A | uttryck > A +---------' · ELIF THEN .-----|------------' | +-----------. Programavsnitt A-1 | | uttryck-1 > A-1 | +-----------' · ELIF THEN |-----|-------------' | +-----------. Programavsnitt A-2 | | uttryck-2 > A-2 | +-----------' · ... |-----|-------------' | : ... | : | : ELIF THEN | | | +-----------. Programavsnitt A-n | | uttryck-n > A-n | +-----------' · ENDIF |-----'-------------' v Exempel: "småtext", raderna 1080-1120, 1600-1720, 1650, 1670, 1710; "kartotek", raderna 2160-2260. I båda programmen finns flera exempel. + KEY$ Se under STANDARDFUNKTIONER. sid 36 + LEN Se under STANDARDFUNKTIONER. sid 36 + LET I COMAL uttrycks en tilldelning med hjälp av tecknet := För att underlätta programmeringen är det dock möjligt att använda ett vanligt likhetstecken under programinskrivningen. Detta ändras av förtolken automatiskt till ":=". Nyckelordet LET ignoreras av förtolken, om det slås in. Man kan ha så många tilldelningar på en rad som radlängden tillåter, tilldelningarna skall då skiljas med ett semikolon (;). Utom vanliga tilldelningar med hjälp av ":=" finns också möjlighet att direkt addera till eller subtrahera från en variabel. Detta anges med tecknen ":+" eller ":-". + LINEFEED +/- LINEFEED + genererar radskifte efter vagnretur vid utlistning och liknande. LINEFEED - genererar inget radskifte efter vagnretur (default-värde, dvs det värde, som sätts in om inget värde anges av användaren). + LIST LIST är ett kommando, som används när man vill skriva ut hela eller delar av det program, som för tillfället finns i arbetsminnet. Kommandot: LIST får systemet att skriva en lista över hela programmet. Kommandot: LIST 100 får systemet att skriva ut rad 100. Kommandot: LIST 100-200 ger en utskrift av raderna från och med 100 till och med 200 och kommandot: LIST -300 gör, att alla rader till och med rad 300 skrivs ut. Kommandot: LIST 300- ger en listning av alla rader från och med rad 300. Normalt kommer en programlista att löpa över skärmen tills programlistningen är utskriven till slut, eller man trycker på RUN/STOP-tangenten. Man kan även stoppa listningen genom att trycka på mellanslagstangenten. När man åter trycker på mellanslaget så fortsätter listningen. Om man har stoppat listningen med ett tryck på mellanslaget kan man inte använda de vanliga editeringsmöjligheterna. Dessa träder först i funktion när man stoppat listningen med RUN/STOP-tangenten. LIST-kommandot kan också användas för att spara program som ASCII-filer på diskett eller kassettband. Kommandot: LIST "MITTPROGRAM" lagrar det program, som för tillfället ligger i arbetsminnet som en programfil med namnet "MITTPROGRAM". Programmet sparas som källkod, och kan därför flätas samman med ett annat i maskinens minne (se ENTER). Eftersom LIST-kommandot arbetar direkt på källkoden, är denna form också tillåten: LIST 100-200 "MITTPROGRAM" I detta fall sparas raderna 100-200 i programfilen "MITTPROGRAM". Vill man använda kassettbandspelaren i stället för disk-stationen (enhet 8), måste man använda följande version av LIST-kommandot: LIST "", 1 Ett program, som sparats med hjälp av LIST"" kan läsas som en vanlig ASCII-fil genom att man Öppnar filen med: OPEN FILE 2, "", READ De enskilda programraderna kan också läsas in i en textvariabel med: INPUT FILE 2: A$ OBS! Se även under EDIT-kommandot. + LOAD LOAD är ett kommando som läser in program från disketten till arbetsminnet. T ex: LOAD "OLSONMONITOR" kommer att läsa in programmet "OLSONMONITOR" till arbetsminnet. LOAD-kommandot kan endast användas i förbindelse med program, som sparats på diskett med kommandot SAVE (se SAVE). Kommandot kan ej användas i förbindelse med program, som lagrats på kassettband. + LOG Se under STANDARDFUNKTIONER. sid 36 + MOD MOD är en tvåställig operator och definieras med: A MOD B = A - INT(A/B) * B dvs resten efter division av A med B. Se även DIV och UTTRYCK + NAMN Namn i COMAL-80 får bestå av upp till 78 tecken, som alla är signifikanta, dvs tas med vid jämförelser. Första tecknet måste vara en bokstav, resten kan vara bokstäver, siffror eller ett av tecknen "'" och "_". Var uppmärksam på, att det senaste tecknet, (understrykningstecken) kommer att på bildskärmen visas som vänsterpil "<-". Exempel: ANTAL'ELEVER, MAXTAL, ADRESS$, FÖRNAMN$ + NEW Detta kommando gör, att innehållet i maskinens arbetsminne raderas (både program och data). + NEXT Se under ENDFOR. + NOT Se under UTTRYCK. + NULL NULL-satsen utför den "tomma processen", dvs absolut ingenting. Liksom den tomma mängden i matematiken, kan den dock vara mycket nyttig av syntaktiska skäl. Exempel: "kartotek", rad 2960. + OF Nyckelordet OF används i COMAL-80 för att avsluta en CASE-sats och under en deklaration av en textvariabel eller en texttabell. Se även CASE och DIM. + OPEN OPEN-satsen används for att öppna datafiler på en yttre enhet. T ex: OPEN FILE 2, "TECKEN", WRITE öppnar filen "TECKEN". Ordningsnumret 2 används i resten av programmet för att hänvisa till denna fil och nyckelordet WRITE betyder, att filen öppnas for att man vill spara data på den. Ordningsnumret kan vara ett heltal från 1 till och med 254, och utom for WRITE kan en fil öppnas med READ, APPEND eller RANDOM. READ betyder att man vill hämta data sekventiellt, APPEND betyder att man vill spara på filen som en förlängning av filens nuvarande innehåll och RANDOM används for att öppna en direkt fil for hämtning eller lagring. Ordet RANDOM måste följas av ett uttryck, som anger postlängden. T ex: OPEN FILE 34, "KUNDER", RANDOM 100 Konstanten 100 efter ordet RANDOM anger, att varje post får vara på upp till 100 bytes. Se även READ FILE och WRITE FILE. Önskar man öppna filer på kassettenheten, kan man göra det genom att foga till en UNIT-del i kommandot: OPEN FILE 2, "DATAFIL", UNIT 1, READ öppnar filen "DATAFIL" på enhet nr 1 (kassetten): OPEN FILE 3, "", UNIT 1, READ kommer att öppna den första filen som finns på kassettstationen för hämtning in till arbetsminnet. Exempel: se "kartotek" raderna 2560, 2640. "kartotek/d", raderna 2520, 2640. + OR Se under UTTRYCK. + ORD ORD(X$) är en standardfunktion som har effekt på textsträngar. Den sänder tillbaka ASCII-värdet av det första tecknet i X$. + OTHERWISE En OTHERWISE-sats används i förbindelse med ett alternativval i en CASE-konstruktion. Se under CASE. + OUTPUT Se under SELECT. + PASS PASS-satsen används för att sända kommandon vidare till diskettstationens inbyggda operativsystem. Satsen har följande syntax: PASS "" Exempel: PASS "n0:bokprogram,bc" formateras en ny diskett. Disketten får namnet "bokprogram" och identifikationen blir "bc". PASS "c0:nytext=0:småtext" lagrar undan en kopia av "småtext" under namnet "nytext". PASS "r0:småtext/d=0:småtext" döper om filen "småtext" till "småtext/d". PASS "s0:gammaltext" raderar filen "gammaltext" (se även DELETE) PASS "i" initialiserar en diskett som nyss satts in i diskettstationen. PASS "v" "rensar upp" på disketten (stänger ev. öppna filer etc). + PEEK PEEK(I) är en standardfunktion, som hämtar värdet av byte nr I från arbetsminnet. + POKE POKE I, J är en sats, som sätter byte nr I i arbetsminnet till J. PRINT En PRINT-sats har generellt samma syntax som i BASIC. I COMAL-80 kan man dock bestämma skrivzonens bredd med hjälp av systemvariabeln ZONE. T ex: ZONE 10 PRINT 1, 2, 3 ger följande utskrift: 1 2 3 123456789012345678901234567890 <--kolumn-nummer varemot dessa två rader: ZONE 5 PRINT 1, 2, 3 ger följande utskrift: 1 2 3 12345678901234567890 <--kolumnnummer Omedelbart efter strömtillslag är värdet på ZONE lika med noll, vilket betyder, att om inga andra värden på ZONE specificeras, så ger PRINT-satsen från de två ovanstående exemplen utskriften: 123 dvs inga mellanrum alls mellan tecknen. Semikolon (;) ger alltid ett extra mellanrum. T ex: PRINT 1;2;3 skriver ut följande: 1 2 3 TAB används for att tabulera in till en bestämd kolumn på raden. Således ger t ex satsen: PRINT "Jens E. Jensen", TAB(20), 11 följande utskrift: Jens E. Jensen 11 123456789012345678901234567890 <--kolumn-nummer Om värdet av uttrycket i parentesen efter TAB är mindre än nuvarande kolumnläge, görs först ett radbyte. Om värdet är mindre än 1 får man ett felmeddelande. Exempel: I såväl "småtext" som "kartotek" finns talrika exempel på PRINT-satser. + PRINT FILE PRINT FILE-satsen används för att lagra data i sekventiella eller direkta filer. Så lagrar t ex satsen: PRINT FILE 2: NAMN$, TELENR värdena av de två variablerna i listan (alltså NAMN$ och TELENR) sekventiellt i filen med ordningsnumret 2 (se även OPEN). Satsen: PRINT FILE 4,I: NAMN$, TELENR lagrar värdena av variablerna i post nr I i den direkta fil som har öppnats med ordningsnumret 4. Data, som har lagrats med PRINT FILE måste hämtas med INPUT FILE. Se i övrigt närmare om lagring och hämtning av data genom användning av kommandona PRINT FILE/INPUT FILE under INPUT FILE. + PROC + ENDPROC Om ett block med satser inleds med satsen: PROC där är ett giltigt namn, och avslutas med satsen: ENDPROC kan detta block anropas som ett underprogram med hjälp av satsen: . Namnet efter ENDPROC står inom spetsiga parenteser för att ange, att man inte behöver ange det under inslagningen. Förtolken fogar själv till det saknade namnet vid första körningen. När underprogrammet är utfört, fortsätter programkörningen med programraden som följer på den sats som anropade underprogrammet (proceduren). Programtexten mellan PROC och ENDPROC kommer att visas med indrag när programmet LISTas. Diagrammet nedan visar sammanhanget mellan verkningen av PROC och ENDPROC-satserna och den sats som anropar proceduren: ... .--> PROC | procedurkropp ---. | ENDPROC | | ... | `--- | ... <------------' + PROCEDURER MED PARAMETRAR I VIC-64-COMAL-80 kan PROC-satsen utvidgas till: PROC () och nu talar vi om ett riktigt procedurhuvud. En procedur med parametrar skall anropas så här: () Då procedurer med parameteröverföring är ett stort framsteg i förhållande till BASIC, och samtidigt också därför ganska okänt för många läsare, skall detta begrepp beskrivas mer i detalj i det följande avsnittet. ** Exempel nr 1 En procedur inleds med satsen: PROC PROV (I, J) och anropas med satsen: PROV (FÖRST, SIST) I detta fall är I och J i procedurhuvudet de formella parametrarna och de skall tilldelas ett värde, när proceduren anropas. Namnen FÖRST och SIST i anropet är de aktuella parametrarna och måste ha tilldelats värden innan denna sats kan utföras. Under proceduranropet får I sig tilldelat värdet av FÖRST och J värdet på SIST. Man kan säga att I övertar FÖRSTs värde och J övertar SISTs värde. Därför kallar man också I och J för värdeparametrar (called-by-value). Men det ligger ännu mer häri: I och J blir behandlade som lokala variabler av proceduren PROV och de kommer inte att vara kända för den programvärld, som ligger utanför proceduren. De kan därför inte heller förväxlas med eventuella andra variabler I och J någon annanstans i programmet. De aktuella parametrarna till en värdeparameter kan vara konstanter, variabler eller uttryck. Proceduren PROV kan t ex anropas på följande tillåtna sätt: PROV (1,8) eller PROV (I+1, J-1) Ett anrop till en procedur kan även företas inifrån proceduren själv, den kallar alltså sig själv "rekursivt". I detta fall sätter förtolken upp nya utrymmen för I och J, som om den aldrig hade sett dem tidigare, och den kommer icke att förväxla värdena från ett anrop med ett annat. Eftersom rekursion och lokala variabler i flera nivåer är en ganska komplicerad historia, är denna korta översikt inte rätt plats for att göra någon större utredning av detta ämne. ** Exempel nr 2 En procedur inleds med: PROC SKRIVPOST (R, N$, REF M()) och anropas med: SKRIVPOST (ELEVNR, NAMN$, TECKEN) I detta fall är R och N$ formella värdeparametrar och under anropet blir de tilldelade värdet på respektive ELEVER och NAMN$. Teckensträngen REF M() betyder en formell parameter M, som är en referensparameter (called-by-reference). Tecknen () efter M betyder, att M hänvisar till en endimensionell tabell. Om anropet skall vara tillåtet, måste TECKEN vara en endimensionell tabell. För referensparametrar sker ingen tilldelning under anropet, den formella parametern blir endast använd som ett slags "öknamn" på den aktuella parametern. TECKEN kommer således att få utstå allt det, som SKRIVPOST utsätter M för. SKRIVPOST kunde också vara inlett med: PROC SKRIVPOST(R, REF N$, REF M()) Den enda skillnaden i förhållande till föregående procedurhuvud är, att N$ nu är en referensparameter. N$ hänvisar endast till NAMN$, och det sker ingen tilldelning. Det ökar naturligtvis hastigheten och spar minnesutrymme. ** Exempel nr 3 En procedur inleds med: PROC SKRIV'UT (REF TABELL(,)) Tecknen (,) efter parameternamnet TABELL anger, att TABELL endast kan hänvisa till en tvådimensionell tabell. Tecknen (,,) visar, att man hänvisar till en tredimensionell tabell, osv. Ytterligare exempel kan återfinnas i programmen "småtext" och "kartotek". En procedur kan också vara sluten. Detta anges genom att man avslutar procedurhuvudet med ordet CLOSED. I detta fall kommer alla variabler, som förekommer i procedurens kropp, att behandlas som lokala variabler på samma sätt som värdeparametrarna tidigare. Arbetsminnet för de lokala variablerna frigörs, när proceduranropet är avslutat. + RANDOM Se under OPEN. sid 26 + READ READ-satsen är definierad på samma sätt som i BASIC. Se även under EOD. + READ FILE READ FILE-satsen används för att läsa från sekventiella och direkta filer, som sparats på diskett. T ex kommer: READ FILE 2: NAMN$, ADRESS$, STAD$ att tilldela värden till variablerna på listan genom att läsa sekventiellt i den fil, som har ordningsnumret 2 (se även OPEN). Satsen: READ FILE 4, I: NAMN$, ELEVER, KLASSNR tilldelar värden till variablerna på listan genom att läsa post nr I i den direkta fil, som har öppnats med ordningsnumret 4. Exempel finns i "kartotek", raderna 2530 och 2560. + REF Se under PROC. + REM REM-satser kan användas i VIC-64 COMAL-80, men förtolken ändrar nyckelordet REM till symbolen "//". I COMAL-80 kan en kommentar placeras på sin egen rad (som en REM-sats) eller användas för att avsluta en programrad vilken som helst. Bara kommentaren inleds med "//". Många exempel kan återfinnas i "småtext" och "kartotek". + RENUM RENUM ändrar följden av radnummer i ett program till följande sekvens: 0010, 0020, 0030, ... Kommandot: RENUM 1000 ändrar radnumren till: 1000, 1010, 1020, ... Kommandot: RENUM 1000, 2 ändrar radnumren till: 1000, 1002, 1004, ... Kommandot: RENUM, 2 ändrar radnumren till: 0010, 0012, 0014, ... + REPEAT + UNTIL REPEAT- och UNTIL-satserna ingår i följande slingstruktur: REPEAT -----------------> A ^ .---------+ Programavsnitt A .----|------< uttryck | | | `---------+ UNTIL | +------------' v Blocket med satser A, blir upprepat tills uttrycket vid UNTIL antar värdet SANT (TRUE). När detta sker, fortsätter programkörningen med satsen som folier efter UNTIL-satsen. Programtexten mellan REPEAT och UNTIL kommer att dras in vid LISTning av programmet. Exempel finns i "småtext", raderna 480-710 samt "kartotek", raderna 950-1010. + RESTORE Satsen: RESTORE medför, att DATA-pekaren sätts till att peka på den första DATA-satsen i programmet, dvs det första elementet i datakön. + RETURN RETURN-satsen används, när man vill lämna en procedur, innan man har kommit fram till ENDPROC-satsen. Dessutom används satsen för att returnera värdet från en användardefinierad funktion (se FUNC). Exempel: "småtext", raderna 1380, 2790, 2810, 2870, 2890 och "kartotek", rad 1740. + RND RND-funktionen använd för att ta fram följder av slumptal precis som i BASIC. I COMAL-80 finns följande utvidgning RND (X,Y) där X och Y är två heltal och X är mindre än eller lika med Y. Denna funktion tar fram slumpade heltal i intervallet från och med X till och med Y. + RUN RUN-kommandot gör att alla variabler nollställs, ett s k "prepass" blir utfört, dvs alla strukturer undersöks om de har något fel. Maskinen börjar därefter köra programmet som finns i arbetsminnet med dess första programsats. + SAVE SAVE-kommandot används för att spara program från maskinens arbetsminne på diskett. SAVE "RÄKNEBOK" Ett program, som sparats på diskett med hjälp av SAVE-kommandot, kan hämtas genom att man använder LOAD-kommandot (se LOAD). Kommandot kan ej användas för att spara program på kassettband. + SELECT OUTPUT SELECT OUTPUT kan användas både i program och som kommando. Kommandot: SELECT OUTPUT "LP" dirigerar de följande utskrifterna från systemet till printern (LP står för LINE PRINTER). Kommandot: SELECT OUTPUT "DS" återför systemet till att ge utskrifter på bildskärmen (DS står för DATASCREEN). Om satsen: SELECT OUTPUT "LP" förekommer i ett program, kommer alla utskrifter etter denna sats på printern ända tills följande sats förekommer i programmet: SELECT OUTPUT "DS" Då återkommer utskrifterna på bildskärmen. OBSERVERA! De texter, som skrivs ut som instruktionstext i en INPUT-sats, kommer alltid att skrivas ut på bildskärmen. Exempel, se "småtext", raderna 2110,2360 och i "kartotek" rad 1530. + SETEXEC Kommandot: SETEXEC- gör, att nyckelordet EXEC inte blir utskrivet vid utlistning av programmet. Kommandot: SETEXEC+ gör, att nyckelordet EXEC skrivs ut. I förbindelse med systemstart utförs SETEXEC-, dvs nyckelordet EXEC blir alltså inte utskrivet med mindre än kommandot SETEXEC+ utförs (se också EXEC). + SETMSG Kommandot: SETMSG- åstadkommer, att feltexterna som ligger på systemdisketten, inte mer hämtas in från denna. I stället ger systemet endast ett felnummer, men markerar fortförande felet på den nyss inslagna raden. Kommandot: SETMSG+ gör, att feltexterna hämtas in från systemdisketten. Vid uppstart av systemet utförs SETMSG+. + SGN Se under STANDARDFUNKTIONER. + SIN Se under STANDARDFUNKTIONER. + SQR Se under STANDARDFUNKTIONER. + STATUS Kommandot: STATUS får systemet att visa ett eventuellt felmeddelande från diskettstationen 1541 och släcker fellampan. + SIZE SIZE-kommandot får systemet att visa antalet lediga bytes i minnet. + STANDARDFUNKTIONER VIC-64 COMAL-80 innehåller följande standardfunktioner: ++ ABS(X) ger absoluta beloppet på X ++ ATN(X) ger i radianer arcustangens av X ++ CHR$(X) ger det tecken som svarar mot talvärdet X (där X kan vara ett tal från 0 till 255) i VIC-64ans teckenuppsättning (Se Appendix A bak i boken [not från e-textaren: Appendix A ingår inte i denna e-text]). ++ COS(X) ger cosinus av X, X i radianer. ++ EOD ger värdet TRUE (sant), om sista elementet i datakön är läst eller kön är tom (dvs om det inte finns några DATA-satser kvar att läsa i programmet). I motsatt fall ger det värdet FALSE (falskt). ++ EOF(X) ger värdet TRUE, om filslut-markeringen i filen med ordningsnumret X har uppnåtts, annars värdet FALSE. ++ ESC ger värdet TRUE, om RUN/STOP-tangenten har varit nedtryckt, annars värdet FALSE. Funktionen verkar endast om den vanliga effekten av RUN/STOP-tangenten är satt ur funktion med en TRAP ESC-sats eller ett kommando (se TRAP) ++ EXP(X) ger grundexponentialfunktionens värde i punkten X (e upphöjt med X). ++ INT(X) ger heltalsdelen av X, dvs det största heltal, som är mindre än eller lika med X. ++ KEY$ ger det första tecknet i inslagningsbufferten. Om ingen tangent varit nedtryckt, ger det CHR$(0) som värde. Exempel på användningen av KEY$: PROC HÄMTA'TECKEN(REF T$) T$=CHR$(0) WHILE T$=CHR$(0) DO T$:=KEY$ ENDPROC HÄMTA'TECKEN ++ LEN(X$) ger längden på texten X$. ++ LOG(X) ger den naturliga logaritmen för X, X större än 0. ++ ORD(X$) ger det talvärde, som internt i VIC-64 representerar det första tecknet i texten X$ (Se Appendix A bak i boken [not från e-textaren: Appendix A ingår inte i denna e-text]). ++ RND (X) ger en följd slumptal i intervallet från 0 till 1. Om X är positivt eller 0, startar följden slumpartat. Om X är negativt, startar följden med samma tal varje körning. Starttalet beror på det numeriska värdet på X. RND (X,Y) där X och Y är heltal, ger ett slumpmässigt heltal inom det slutna intervallet från X till Y. Om Y anges med en negativ talkonstant, skall det omges med parenteser (t ex: RND(5,(-1))). Om X är större än eller lika med Y, ger funktionen konstant talet X. ++ SGN(X) ger tecknet för X: -1 om X är negativt, 0 om X är lika med noll och 1 om X är ett positivt tal. ++ SQR(X) ger kvadratroten ur X, X får ej vara negativt. ++ TAN(X) ger tangens för X, X i radianer. + STEP Se under FOR. sid 15 + STOP STOP-satsen gör att programkörningen stoppas. Utförandet kan fortsätta igen med hjälp av CON-kommandot (se CON). + SYS Satsen: SYS I gör att förtolken ger ett subrutinanrop till byte nr I i arbetsminnet. + TAB Se under PRINT. + TAN Se under STANDARDFUNKTIONER. + TEXTBEHANDLING, DELTEXTER En textvariabel skall alltid deklareras. T ex deklarerar: DIM NAMN$ OF 30 en textvariabel (strängvariabel) NAMN$, med plats för 30 tecken. När man deklarerar en strängtabell, skall det maximala antalet element också anges. T ex deklarerar: DIM ADRESS$ (100,3) OF 20 en tvådimensionell strängtabell, där varje element kan bestå av 20 tecken. Deltexter anges genom att man skriver positionen på första och sista tecknet i strängen. Om t ex NAMN$ innehåller följande text: "RICKARD PAWSON", kommer NAMN$ (9:11) att vara detsamma som "PAW". OBSERVERA! Om variabeln TOMMA$ är deklarerad med längden 60 tecken, kommer tilldelningen: TOMMA$(1:60):="" att fylla upp TOMMA$ med mellanrum. För variabeln NAMN$ är uttrycket NAMN$ (5) ekvivalent (lika med) NAMN$ (5:5). Exempel: I programmet "småtext" finns talrika exempel på användningen av textvariabler och deltexter (strängvariabler och delsträngar). + THEN THEN är ett nyckelord, som används for att avsluta en IF-sats. Se IF. + TRUE TRUE är en fördefinierad konstant med värdet 1. Se FALSE för ytterligare detaljer. + TO Se under FOR. + TRAP TRAP-satsen/kommandot använd for att sätta den normala funktionen av RUN/STOP-tangenten ur spel. Normalt avbryter en nedtryckning av RUN/STOP-tangenten programutförandet. Om systemet möter följande sats/kommando: TRAP ESC- kommer ett tryck på RUN/STOP-tangenten endast att registreras i systemvariabeln ESC medan programutförandet fortsätter utan hinder. Man kan återskapa den normala funktionen av RUN/STOP-tangenten genom att använda satsen/kommandot: TRAP ESC+ Vid systemstart sätts TRAP ESC+. Se även under ESC. + UTTRYCK I COMAL-80 finns det numeriska uttryck och stränguttryck. Ett numeriskt uttryck kan innehålla konstanter, variabler och numeriska funktioner, och man kan använda parenteser och nedanstående operaturer, enligt vanliga matematiska regler: + enställigt + +A - enställigt - -A ^ potenshöjning A^B * multiplikation A*B / division A/B DIV heltalsdivision A DIV B MOD rest efter division A MOD B + addition A+B - subtraktion A-B Om A och B är heltal är A MOD B den så kallade principiella resten från divisionen av A med B. Dvs det minsta icke-negativa heltalet R, så att: A = B*Q + R och A DIV B är kvoten Q. Numeriska värden kan jämföras med hjälp av följande jämförelse-operatorer: Mindre än < Mindre än eller lika med <= Lika med = Större än > Större än eller lika med >= Skild från eller Inte lika med <> Numeriska uttryck kan användas som Booleska uttryck. Ett numeriskt värde av noll tolkas som FALSE dvs falskt medan däremot varje värde som är skilt från noll tolkas som TRUE dvs sant. En logisk operation ger en numerisk 1:a för TRUE och en 0:a för FALSE. Vi kan använda följande Booleska uttryck: NOT logisk negation. NOT A ger värdet FALSE, om A har värdet TRUE, eller TRUE, om A har värdet AND logisk förbindning. A AND B ger värdet TRUE om både A och B är TRUE. I alla andra fall ger uttrycket värdet FALSE. OR logisk förbindning. A OR B ger värdet FALSE om både A och B är FALSE, i alla andra fall ger uttrycket värdet TRUE. Ett stränguttryck kan bestå av strängkonstanter, textvariabler (strängvariabler) eller strängfunktioner som har kedjats samman med +tecknet. Textuttryck kan jämföras med hjälp av operatorerna: < <= = >= > <> som i detta fall betyder "kommer före", "kommer före eller är lika med", "är lika med", "kommer efter eller är lika med", "kommer efter" och "är icke lika med" i bokstavsordning. OBSERVERA att texter med villkorsoperatorer är uttryck som ger numeriska värden; 1 för TRUE och 0 för FALSE. IN används för jämförelser mellan strängar. Uttrycket A$ IN B$ ger värdet 0 (dvs FALSE) om A$ icke finns som en delsträng i B$. Om A$ finns som delsträng av B$ så ger uttrycket läget för det första tecken som är lika. Exempel: Om NAMN$ har värdet "JOHN COLLINS" så kommer uttrycket: EFTERNAMN$ IN NAMN$ att ge värdet 6 (TRUE) om EFTERNAMN$ är "COLLINS", men värdet 0 (FALSE), om EFTERNAMN$ är "COLIN". Prioriteterna för de operatorer som nämns ovan är: ^ (exponentiering) * DIV MOD < <= = >= > <> IN NOT AND OR + UNTIL UNTIL-satsen används för att avsluta satsblocket i en REPEAT...UNTIL-slinga. Se REPEAT, UNTIL. + USING Satsen: PRINT USING : , ... . används för att skriva ut värdena i listan över , styrt av textuttrycket . Detta program: 0010 SELECT OUTPUT "LI" 0020 // 0030 REPEAT 0040 INPUT X 0050 PRINT "OFORMATERAT: ", X, TAB (30), 0060 PRINT USING "FORMATERAT: -#####.##": X 0070 UNTIL X = 0 ger följande utskrift OFORMATERAT: 3 FORMATERAT: 3.00 OFORMATERAT: - 3 FORMATERAT: -3.00 OFORMATERAT: - .3 FORMATERAT: -0.30 OFORMATERAT: .3 FORMATERAT: 0.30 OFORMATERAT: 234.4567 FORMATERAT: 234.46 OFORMATERAT: -234.5678 FORMATERAT: -234.57 OFORMATERAT: 123444567 FORMATERAT: ******* OFORMATERAT: -.123456 FORMATERAT: -0.12 OFORMATERAT: 3.4E-04 FORMATERAT: 0.00 OFORMATERAT: 0 FORMATERAT: 0.00 Följande program ger samma utskrift: 0010 DIM FORMAT$ OF 20 0020 FORMAT$:="#####.##" 0030 SELECT OUTPUT "LI" 0040 // 0050 REPEAT 0060 INPUT X 0070 PRINT "OFORMATERAT: ", X, TAB (30), 0080 PRINT USING "FORMATERAT: "+FORMAT$: X 0090 UNTIL X = 0 + WHEN WHEN används för att inleda ett programblock i en CASE-konstruktion. Se under CASE. + WHILE + ENDWHILE WHILE och ENDWHILE-satserna används för att skapa följande struktur: WHILE DO +---------. | uttryck > -------> A Programsatser A +---------' · | ^-------------' ENDWHILE v Blocket med programsatser, A, utförs så länge som värdet på uttrycket efter WHILE är sant. När uttrycket blir falskt, fortsätter utförandet med satsen efter ENDWHILE. Programtexten mellan WHILE och ENDWHILE kommer att ryckas in under LISTning av programmet. Om bara en sats skall styras av uttrycket efter WHILE, kan hela slingan skrivas på en rad. T ex: WHILE X: NAMN$, ADRESS$, AVDNR skriver värdet av listans variabler i den post som anges av , i den direkta fil, som har öppnats med logiskt filnummer 4. En variabel på listan efter WRITE FILE kan vara namnet på en tabell. I så fall blir alla tabellens komponenter skrivna i den fil eller post man hänvisar till. Man kan adressera enskilda bytes i en post. När t ex följande utförs: READ FILE 4, , : X WRITE FILE 4, , : X läser och skriver X i byte nr i posten . OBS! SKRIVNING KAN ENDAST SKE FRAMIFRÅN I EN POST EFTERSOM RESTEN AV POSTEN NOLLSTÄLLS VID DENNA OPERATION!!!!! Exempel i "kartotek": rad 2650, 2680; "småtext": rad 2630. + ZONE ZONE används för att bestämma bredden av skrivzonerna. Se under PRINT * VIC-64 COMAL-80 GRAFIK Här används ett nytt begrepp, "musen". På amerikanska kallas den också för "The Turtle", (sköldpaddan). Vi behåller det rara danska namnet "musen" ända tills någon funnit på en bra svensk beteckning för denna fördefinierade figur eller form. + BACK Syntax: BACK Flyttar "musen" enheter bakåt. Om pennan är nere (se PENDOWN), ritas en linje i nuvarande färg. BACKGROUND Syntax: BACKGROUND där är ett heltal från 0 till 15 (se Appendix B, bak i boken). Satsen/kommandot sätter bakgrunden till den färg, som anges med . När man använder högupplösningsgrafiken, fungerar ej instruktionen, innan förtolken har stött på en CLEAR-sats/kommando (se CLEAR). Exempel: kommandot/satsen: BACKGROUND 6 sätter bakgrunden till färgen blå. + BORDER Syntax: BORDER Sätter kanten runt "arbetsytan" på bildskärmen till den färg som anges med (se även BACKGROUND). + CLEAR Syntax: CLEAR Rensar grafikbildskärmen. + DRAWTO Syntax: DRAWTO , Ritar en linje från pennans nuvarande läge till punkten (,). + FILL Syntax: FILL , Fyller ut det slutna område som innehåller punkten (,) med pennans nuvarande färg (se PENCOLOR). Kanten på ett slutet område definieras så här: En kantpunkt är en punkt, som har en annan färg än bakgrunden, eller en punkt på kanten av nuvarande ram (se FRAME). + FORWARD Syntax: FORWARD Musen flyttas enheter framåt. Om pennan är nere tecknas en linje i nuvarande färg. + FRAME Syntax: FRAME ,,, Definierar den ram, innanför vilken man kan rita. Man ritar icke i punkter vars koordinater ligger utanför detta område, om nedre vänstra hörnet är angivet med (,), och om övre högra hörnet är (,). Musen (eller "The Turtle") visas dock även utanför ramen. Vid uppstartning av systemet täcker ramen hela skärmen, dvs man har ::=0 ::=319 ::=0 ::=199 + GETCOLOR Syntax: GETCOLOR (,) Denna funktion ger färgen på punkten (,). Om den angivna punkten ligger utanför den för tillfället gällande ramen, ger funktionen värdet -1. + HEADING HEADING är en funktion, som ger riktningen för musen. Riktningen anges i grader moturs med vågrätt till höger som utgångspunkt. + LEFT Syntax: LEFT Musen vrider huvudet grader åt vänster (motsols). + MOVETO Syntax: MOVETO , Flyttar pennan utan att rita från nuvarande läge till det läge som anges av (,). PENCOLOR Syntax: PENCOLOR Sätter den färg, som man ritar med, dvs pennans färg. Detta är samtidigt den färg som markören får och den färg i vilken texten skrivs på bildskärmen. Dessutom är det musens färg. Normalt skall man for använda ett talvärde mellan 0 och 15 (se BACKGROUND), men om man använder ett negativt tal. ritas det i samma färg som bakgrunden. + PENDOWN Syntax: PENDOWN Pennan sänks, dvs de rörelser pennan därefter gör lämnar ett skrivspår, ett streck, så länge som rörelsen pågår innanför ramen och pennans färg är olika bakgrundens. + PENUP Syntax: PENUP Pennan lyfts, dvs dess rörelser lämnar icke längre något streck på skärmen. + PLOT Syntax: PLOT , Märker ut punkten (,) i pennans nuvarande färg. + PLOTTEXT Syntax: PLOTTEXT ,, Den text, som anges av textuttrycket , visas på grafikskärmen så, att nedre vänstra hörnet av första tecknet i placeras i den punkt som anges av (,). Lägg märke till att de använda koordinaterna blir satta lika med de största hela multiplarna av 8, som är mindre än eller lika med de angivna värdena. Texter kan endast framställas i förbindelse med högupplösningsgrafik. + POSITION Syntax: POSITION , Pennan flyttas till positionen (,). En linje ritas endast om pennan är nere och har en färg, som är skild från bakgrundsfärgen. + RIGHT Syntax: RIGHT Musen vrider huvudet grader åt höger (medsols). + SCREENECCO Syntax: SCREENECCO Om har värdet TRUE, blir den linje som markören står på, visad överst på grafikskärmen. Detta fungerar dock endast i högupplösningsgrafik. Man kan flytta markören upp och ned som vanligt och på detta sätt få se en bild av var och en av de linjer som står på textskärmen. Texterna står alltid i ljusblå färg på mörkblå bakgrund. Kommandot: SCREENECCO TRUE utförs alltid tillsammans med SETGRAPHIC 0 (initialisering av högupplösningsgrafiken). + SETGRAPHIC Syntax: SETGRAPHIC Kommando/sats, som initialiserar grafiksystemen och gör den grafiska skärmen synlig. På VIC-64 finns två olika grafikmoder: Högupplösningsgrafik: = 0 Flerfärgsgrafik: = 1 I högupplösningsgrafik har man 320*200 punkter att förfoga över. Hela den grafiska skärmen delas upp i 40*25 block om vardera 8*8 punkter. Inom varje block kan man endast ha två färger, av vilka den ena är bakgrundsfärgen. Den andra färgen definieras, så snart en punkt inom blocket används. Om en punkt inom samma block åter används med en annan färg så skiftar hela blocket till denna sista färg. I Flerfärgsgrafik har man endast halva upplösningen mot högupplösningen i vågrätt riktning dvs man kan förfoga över 160*200 punkter. Skärmen blir även i detta fall uppdelad i 40*25 block, som nu är på 8*4 punkter vardera. Nu kan varje block innehålla fyra olika färger, av vilka en är bakgrundsfärg. SETGRAPHIC-kommandot/satsen med angiven typ initialiserar grafiksystemet, rensar bildskärmen, ställer musen i nedre vänstra hörnet pekande vågrätt åt höger och tar fram grafikskärmen. SETGRAPHIC utan typangivning gör endast att grafikskärmen tas fram. Resultatet av eventuella operationer, som kan ha utförts bakom textskärmen, blir synliga. + SETHEADING Syntax: SETHEADING Musen vrider sitt huvud i riktning grader motsols med utgångspunkt från riktningen vågrätt åt höger. + SETTEXT Syntax: SETTEXT Gömmer grafikskärmen och visar textskärmen. Grafikkommandon fungerar likväl fortförande på den gömda grafikskärmen. Resultatet av sådana kommandon kan lätt avslöjas genom att man använder en SETGRAPHIC-sats/ kommando. En STOP-sats eller ett felmeddelande utfor automatiskt SETTEXT-kommandot. + TURTLESIZE Syntax: TURTLESIZE Definierar storleken på musen. Storleken skall vara ett heltal i det slutna intervallet mellan 1 och 10. Vid systemstart är lika med 10. + TURTLESTATE Syntax: TURTLESTATE Om har värdet TRUE, visas musen, men om har värdet FALSE visas ej musen. * VIC-64 COMAL-80 SPRITE-GRAFIK Ordet "sprite" betyder "alf", "fe" eller "nisse". På VIC-64 betecknar "sprite" en fördefinierad figur, som kan röra sig runt på skärmen oberoende av eller i samspel med övrig grafik. Man kan ha upp till 8 sådana figurer på skärmen samtidigt. I "Grafik och ljud på VIC-64", kan man läsa en utförlig redogörelse för sprite-figurer.. I det följande kommer vi att syssla med hur man ritar en sprite och hur man kan styra den. I den tidigare nämnda boken kan man se, hur en sprite byggs upp. Den beskrivna metoden är emellertid mycket tekniskt präglad och därför finns på COMAL-disketten ett program, som heter "SPRITEDESIGN". I det följande kommer vi att utgå från, att detta program används för uppritning och redigering av sprites. ** SPRITEEDITOR När 64:an kör COMAL och systemdisketten sitter i 1541-stationen, startas spriteeditorn med följande kommando: CHAIN "SPRITEDESIGN" Editorn startar med att märka ut en kvadrat på vänster sida av bildskärmen och ställer därefter en rad frågor i övre högra hörnet. Det första lyder så här: MULTICOLOR? Man skall nu slå in 0 eller 1. Om man slår in 0, blir sprite-figuren ritad i högupplösningsgrafik; om man slår 1 får man en flerfärgs sprite-figur. Låt oss först se, vad som sker därefter, om man startar med att slå in 0, alltså anger högupplösningsgrafik. Programmet skriver då COLOR: och väntar på, att ett färgnummer slås in (se Appendix B bak i boken). Vi kan t ex slå in , som betyder gul. Därefter frågar programmet: EXPANDX? Här kan man återigen välja att slå in 0 eller 1. Om man slår in 0 så tecknas sprite-figuren i normal (liten) storlek i vågrätt riktning. Om man slår in 1 så ritas figuren i dubbel storlek utefter vågräta axeln (X-riktningen). Låt oss tänka oss att vi slår in 1. Det ger en mycket tydlig figur på skärmen. Nu skriver programmet: BACKCOL: och ber därmed om uppgift på bakgrundsfärg. Som svar skall man använda ett av de tidigare nämnda CTRL eller C= tangenterna. Slår man t ex C= och 4 får man en grå bakgrund. Som tecken på att editorn nu fått de nödvändigaste frågorna besvarade, ritas en mindre kvadrat under "frågeschemat" och markören sätts i övre vänstra hörnet av den stora kvadraten. Man kan nu börja att rita sin sprite-figur. Det sker på följande sätt: Man kan föreställa sig att kvadraten består av 24*21 fält (ett fält=markören). Markören kan flyttas fritt runt i kvadraten med hjälp av de vanliga styrtangenterna. I samtliga 24*21 fälten skall man nu markera, om man vill att fältet skall visa bakgrundsfärgen eller förgrundsfärgen. Det gör man genom att slå in 0 eller 1. Om man slår 0, får det fält som markören står på, bakgrundsfärgen. Om man slår in 1, får fältet förgrundsfärgen. När man så markerat samtliga 24*21 fält, kan man ändra på sin ritning om man så vill genom att flytta markören till ett bestämt fält och ändra markeringen (0 eller 1) för just detta fält. Samtidigt med att man ritar sin sprite-figur så visas figuren i sin rätta storlek i den mindre kvadraten, som kom fram nederst till höger på skärmen. När man är klar med uppritningen av sin sprite-figur, skall den sparas på disketten, så att man senare kan hämta fram den för användning i ett program. Det gör man genom att trycka på tangenten med bokstaven "s" (for SAVE). Spriteeditorn svarar med att skriva: FILENAME: under den stora kvadraten. Användaren skall nu bara slå in ett tillåtet filnamn och trycka på RETURN-tangenten. Så sparas de 64 tecken, som definierar sprite-figuren i en sekventiell fil med det av användaren angivna namnet. Den kan senare läsas med hjälp av OPEN FILE och READ FILE. Den sista bytens (byte nr 64) värde anger, om det är fråga om en högupplösnings- eller flerfärgs sprite. 0 = högupplösning, 1 =flerfärgs. Låt oss sedan se vad som sker om man slår in 1, när editorn skriver: MULTICOLOR? Man får därefter samma frågor som tidigare men editorn ställer ytterligare två frågor: MULTICOLOR-1: MULTICOLOR-2: och för vart och ett av dessa skall en av färgkoderna slås in. Dessa två färger kommer vi att kalla sidofärger. Man har alltså angivit totalt fyra färger: en bakgrundsfärg (BACKCOL), en förgrundsfärg (COLOR) och två sidofärger (MULTICOL-1) och MULTICOL-2). Man fortsätter nu som ovan beskrivits, blott med den skillnaden att man nu kan använda tangenterna 0, 1, 2 och 3 för markering av resp bakgrundsfärg förgrundsfärg och de två sidofärgerna. Dessutom skall man lägga märke till att varje markering nu definierar färgen på två fält i vågrätt riktning och ej som i högupplösningsgrafik, där varje fält kan ha sin färg. Men så har man ju i stället fyra färger att arbeta med, och inte bara två, som vid högupplösningsgrafik. Om man senare önskar ändra sin sprite-figur, kan man även här använda spriteeditorn. Man skall då starta upp rutinen som beskrivits här ovan och när markören ställer sig i ritkvadratens övre vänstra hörn, skall man trycka på tangenten med bokstaven "l" (for LOAD). Nu skriver editorn: FILENAME? och man skall slå in namnet på den sekventiella fil, som innehåller den sprite-figur, som man vill ändra. Därpå ritar editorn den önskade figuren och man kan ändra den genom att flytta runt med markören och ändra markeringarna for de fält, som man vill ändra. När redigeringen är avslutad, sparas den nya ritningen genom att man trycker på "s" och anger ett nytt filnamn. Den gamla ritningen kan ev. raderas genom att man använder DELETE-kommandot (se DELETE eller PASS). Editorn stoppas genom att man trycker på tangenten med bokstaven "q" (för QUIT, lämna). Vi skall nu övergå till att titta litet på de olika sprite-ord, som kan användas i förbindelse med COMAL-80/64. Till de enskilda orden är inga exempel visade. Läsaren hänvisas till de två programmen "uppmottak" och "kollision", vilka i detalj genomgås i tillägget till detta avsnitt. + DATACOLLISION Syntax: DATACOLLISION(,) Detta är en funktion, som används för att undersöka, om sprite-figur nr har stött ihop med annan grafisk information på skärmen (dvs en icke-bakgrundspunkt på sprite-figuren sammanfaller med en icke-bakgrundspunkt för en annan grafisk figur). Om har värdet TRUE, registreras en sammanstötning, så snart den sker. Om har värdet FALSE, registreras det, om en sammanstötning har skett tidigare. Funktionen ger alltså värdet TRUE, om spritefigur nr tidigare har stött samman med annan grafisk information. + DEFINE Syntax: DEFINE , där är ett heltal från 0-47 och är ett stränguttryck som innehåller de 64 tecken, som definierar en sprite-figur (se under SPRITEEDITOR). Man kan ha ett förråd på totalt 48 figurer, och med hjälp av var och en av dessa figurer, kan man definiera en av de 8 sprite-figurer, som kan finnas i skärmen samtidigt. Man kan ev använda samma teckning för definition av fler än en av de sprite-figurer som uppträder på skärmen. + HIDESPRITE Syntax: HIDESPRITE Sprite-figur nr visas icke längre på skärmen. + IDENTIFY Syntax: IDENTIFY , Sprite-figur nr visar teckning nr . Man kan föreställa sig, att man har ett skåp fullt med teckningar av olika sprites (0-47). Varje gång, man använder IDENTIFY-satsen, tar man en teckning från skåpet och låter en figur efter den nuvarande teckningen uppträda på skärmen med det nummer anger. Numret skall vara ett heltal mellan 0 och 7. Om musen är framme, uppträder denna som sprite-figur nr 7. + PRIORITY Syntax: PRIORITY ,

Om

har värdet TRUE så blir sprite-figur nr visad bakom ev existerande grafik. Om

har värdet FALSE, kommer figuren att visas framfor ev. annan grafik. De enskilda sprite-figurernas inbördes prioritet är fastlagd på förhand. Av två sprite-figurer har den med lägst nummer högst prioritet. + SPRITEBACK Syntax: SPRITEBACK , där och är heltal från 0-15. Satsen används för att omdefiniera de två sidofärgerna i en flerfärgs-sprite (se under SPRITEEDITOR). + SPRITECOLLISION Syntax: SPRITECOLLISION(,) En funktion som ger värdet TRUE, om och endast om sprite-figur nr stöter ihop med eller tidigare har stött samman med en annan sprite-figur. Om se under DATACOLLISION. + SPRITECOLOR Syntax: SPRITECOLOR , Sätter förgrundsfärgen för sprite-figur nr till den färg som anges med , där är ett heltal från 0 till 15 (Se under SPRITEEDITOR). + SPRITEPOS Syntax: SPRITEPOS ,, Sätter sprite-figur nr så, att figurens övre vänstra hörn befinner sig i punkten (,). + SPRITESIZE Syntax: SPRITESIZE ,, Om har värdet TRUE (ett talvärde skilt från noll), blir sprite figur nr expanderad till dubbla storleken i horisontell riktning. Om har värdet TRUE (ett talvärde skilt från noll), blir sprite-figur nr expanderad i dubbel storlek i vertikal riktning. ** TVÅ EXEMPEL Exempel nr 1: programmet "UPPMOTTAK" I proceduren "hämtasprite" öppnas filen "ballong" med filnr 2 och variabeln "figur$" får sig tilldelad värdet på den sträng om 64 tecken, som har sparats i filen. I proceduren "ritasprite" sker följande: 200: De 64 tecken, som är värdet av "figur$" används för att definiera teckning nr 45. 210: Sprite-figur nr 2 får dubbel storlek i båda riktningarna. 220: Bakgrundsfärgen sätts till färg nr 8 (orange). 230: Ramfärgen sätts till färg nr 2 (röd). 240: Förgrundsfärgen till sprite nr 2 sätts till 11 (grå). 250: Man byter om till grafik. 260: För sprite-figur nr 2 används teckning nr 45 (som tidigare definierats på rad nr 170). I proceduren "användsprite" styrs "ballongen" snett upp över skärmen och när den stöter mot "taket" så rör den sig snett nedåt över skärmen: 330: Läget på sprite-figur nr 2 sätts till (x,y) dvs övre vänstra hörnet av figuren. 350: Om figur nr 2 stöter mot annan grafik ("taket"), får variabeln "uppmot'taket" värdet TRUE. 360: Om "uppmot'taket" har värdet TRUE, sänds figuren i "ballongen" nedåt igen. I proceduren "rita'tak" ritas en vågrät linje ("taket") på en höjd av 180 enheter. I proceduren "ned'igen" dirigeras figuren ned efter att ha stött ihop med "taket". 590: Figuren styrs, så dess övre vänstra hörn är i punkten (x,y). 610: Programmet stannar, om man tryckt på ESC-tangenten. Exempel nr 2: programmet "KOLLISION" Programmet har många gemensamma drag med föregående program. Följande rader bör observeras: 230: sprite-figur nr 2 ritas efter teckning nr 45. 240: sprite-figur nr 3 ritas efter teckning nr 45. De två sprite-figurerna alltså framställda efter samma teckning. 360: Variabeln "möte" får värdet TRUE, så snart sprite-figur nr 2 stöter ihop med en annan sprite-figur, i detta fall nr 3. 370: Om de två sprite-figurerna stöter ihop, rör de sig tillbaka igen. Läsaren uppmanas att göra experiment med dessa två program genom att ändra parametrarna for färger, storlekar mm. Filen "ballong" ligger på COMAL-programdisketten. Se även programlistningarna längst bak i boken. * APPENDIX A Teckenvärdena för PRINT, CHR$ och ASC [Etextarens not: Denna lista är borttagen, eftersom C64:ans teckenuppsättning är svår att efterlikna i ISO-text. Jag hänvisar till C64-manualen] * APPENDIX B De 16 färgerna du kan använda är 0 SVART 1 VIT 2 RÖD 3 CYAN 4 PURPUR 5 GRÖN 6 BLÅ 7 GUL 8 ORANGE 9 BRUN 10 LJUSRÖD 11 GRÅ 1 12 GRÅ 2 13 LJUSGRÖN 14 LJUSBLÅ 15 GRÅ 3 ** LITTERATURHÄNVISNING (Engelsk, dansk och svensk litteratur) [1. DANSKA BÖCKER] COMAL, Problemløsning og programmering I+II, Børge R. Christensen, förlag BOGIKA, Ikast, Danmark Diskett med böckernas program för VIC-64 kan köpas efter skriftlig beställning hos författaren. Priset för båda disketterna är kr 200:-. Skriv till Børge R. Christensen, Viben 34, 6270 Tønder, Danmark. Programmering i COMAL-80 Poul Østergaard, Teknisk Forlag, Köpenhamn, Danmark Svensk översättning från Förlagshuset under våren 1984. 4 * COMAL Leif Pehrsson m fl. Forlaget SYSTIME, Herning, Danmark. Svensk översättning från Förlagshuset under våren 1984. [ENGELSKA BÖCKER] COMAL HANDBOOK Len Lindsay, Reston Publishing Company, USA Beginning COMAL Børge Christensen, Ellis Horwood Ltd, England Structured Programming with COMAL Roy Atherton, Ellis Horwood Ltd, England Foundations in Computer Studies with COMAL John Kelly, Education Company of Ireland, Irland Starting with COMAL Erik Gratte, Prentice Hall International, England [SVENSKA BÖCKER] COMAL SNABBGUIDE Åke Fredriksson, COMAL-klubben i Sverige, Mölndal COMAL-80 på VIC-64 Børge R. Christensen i övers. av Å Fredriksson, Förlagsgruppen, Norrköping Planerade svenska utgåvor: COMAL Handbok, Len Lindsay, t svenska av Å Fredriksson *) Strukturerad programmering i Comal, Roy Atherton, övers. Å F-n. *) Programmering i COMAL-80, Poul Østergaard, övers. Å F-n. *) 4 * COMAL - 4 * VIC, Leif Pehrsson m fl. Förlagsgruppen, Norrköping. *) samtliga utkommer på svenska från Förlagsgruppen, Norrköping. Dessutom beräknar COMAL-Klubben i Sverige ge ut sitt nyhetsblad med början 1984 som kvartalsblad. Distribueras endast till medlemmar i COMAL-Klubben i Sverige. Medlemsavgift 100:-/år. Kansli: c/o Åke Fredriksson, Gustavsbergsgatan 8, 431 37 MÖLNDAL. Telefon 031-87 70 84. Postgiro 42 17 64-2. * Om programmen "KARTOTEK" "SMÅTEXT" 1. Programmet "kartotek" Programmet hämtas in med kommandot: CHAIN "KARTOTEK" och börjar med att skriva 1 = Inskrivning 2 = Utskrift 3 = Rättelser 4 = Tag bort 5 = Sluta Välj funktion: Genom att slå in ett av de fem angivna talvärdena, får man den funktion aktiverad som anges mitt för talvärdet. Under körningen ger programmet själv instruktioner om, vad man skall göra. Programmet är skrivet med hänsyn till att man använder diskdrive 1541 for Iagring av sina data. Versionen "kartotek/k" använder kassettbandspelare Programmet "småtext" Programmet startas genom att man skriver in: CHAIN "SMÅTEXT" Överst i bildskärmen framkommer en kommando-rad: Ange arbete: n j u s 1 a De olika bokstäverna står för följande n(y text), j(ustera), u(tskrift), s(para), l(adda) och alvbryt). Följande exempel går igenom användningen av kommandona: Tryck först på tangenten 'n'. Lägg märke till att n:et då skrivs i negativ (omvänt) utfirande och att ett smalt, blinkande streck blir synligt på rad 4. Knappa in följande text: Anton har en häst, som heter Sörenson. Och tryck därefter på tangenten med snabel-a (@). Programmet skriver då återigen kommandoraden: Ange arbete: n j u s 1 a Tryck nu på 'j'. Bokstaven 'j' lyser upp negativt och programmet skriver: Sök: med ett blinkande streck därunder. Knappa in ordet 'häst' och tryck på snabel-a igen. Bokstaven 'h' i 'häst' börjar att blinka med ett streck under. Knappa in orden 'mycket liten' och lägg märke till hur de sätts in i texten. Tryck till slut på snabel-a igen för att komma tillbaka till kommandoraden. Då systemet ligger i j(usterings)-tillstånd kan man alltid också använda alla vanliga redigeringstangenter, utom Markör-upp och Markör-ned, i det att "småtext" är radorienterat. Pröva t ex följande: tryck på 'j' och svara Liten' när programmet ber om ett sök-ord. Tryck på snabel-a. Textmarkören, det blinkande strecket ställer sig under 'l' i 'liten'. Tryck på knappen sex gånger och lägg märke till att ordet 'mycket' stryks ut. Tryck på snabel-a för att komma tillbaka till kommando-raden. Ett tryck på 'u' ger möjlighet att få en utskrift med korrekt uppdelning av texten i hela ord. Genom att använda 's' och 'l' kan man respektive spara på och ladda in texter på/från disketten/kassetten. På COMAL-80-disketten ligger datafilen "text". Denna kan t ex hämtas in genom att starta "småtext" och trycka på 'l'. Med "småtext" kan man spara och hämta texter på diskett. Med "småtext/k" kan man spara och hämta texter på kassett. * OM GRAFIKPROGRAMMEN Grafikprogrammen "graf.01" - "graf.09" demonstrerar samtliga satser som kan användas i förbindelse med x-y-grafik och s k turtle-grafik. Programmen "kollision" och "uppmottak", som omtalades mer i detalj i det föregående avsnittet demonstrerar en stor del av sprite-grafiken.. Författaren har ansträngt sig att använda sådana namn på variabler och procedurer, att pro- grammen skall vara självförklarande. Programmen startas med kommandon som t ex: CHAIN "GRAF.03" och stoppas genom att man trycker på mellanslagstangenten (den långa längst ned). De flesta programmen använder en följd gemensamma standardprocedurer. Dessa procedurer visas ej i alla programlistningar. Läsaren hänvisas i varje givet fall till att titta på en listning på bildskärmen eller ev. själv framställa listor på sin egen printer med kommandona: SELECT "LP" LIST På följande sidor visas COMAL-80-programmen på disketten i listat format. [Programlistningarna följs av en UU-kodad T64-fil i vilken listningarna finns i PETSCII-format. Dessa kan laddas in i COMAL-tolken med kommandot ENTER]. 0010 // uppmottak 0020 // --------- 0030 // 0040 dim figur$ of 64 0050 trap esc- 0060 hamta'sprite 0070 while true do 0080 rita'sprite 0090 rita'tak 0100 anvand'sprite 0110 endwhile 0120 // 0130 proc hamta'sprite 0140 open file 2,"ballong",read 0150 read file 2: figur$ 0160 close 0170 endproc hamta'sprite 0180 // 0190 proc rita'sprite 0200 define 45,figur$ 0210 spritesize 2,1,1 0220 background 8 0230 border 2 0240 spritecolor 2,11 0250 setgraphic 0 0260 identify 2,45 0270 endproc rita'sprite 0280 // 0290 proc anvand'sprite 0300 uppmot'tak:=false 0310 for x:=0 to 319 do 0320 y:=2/3*x 0330 spritepos 2,x,y 0340 x1:=x 0350 uppmot'tak:=datacollision(2,true) 0360 if uppmot'tak then ned'igen 0370 endfor x 0380 endproc anvand'sprite 0390 // 0400 proc stoppa'sprite 0410 pencolor 8 0420 border 8 0430 background 11 0440 settext 0450 trap esc+ 0460 print chr$(14),chr$(147) 0470 stop 0480 endproc stoppa'sprite 0490 // 0500 proc rita'tak 0510 pencolor 11 0520 moveto 0,180 0530 drawto 319,180 0540 endproc rita'tak 0550 // 0560 proc ned'igen 0570 for x:=x1 to 0 step -1 do 0580 y:=2/3*x 0590 spritepos 2,x,y 0600 endfor x 0610 if esc then stoppa'sprite 0620 endproc ned'igen 0630 // 0010 // kollision 0020 // --------- 0030 // 0040 dim figur$ of 64 0050 trap esc- 0060 // 0070 hamta'sprite 0080 definera'sprite 0090 while true do spriteshow 0100 // 0110 proc hamta'sprite 0120 open file 2,"ballong",read 0130 read file 2: figur$ 0140 close 0150 endproc hamta'sprite 0160 // 0170 proc definera'sprite 0180 background 8 0190 border 2 0200 pencolor 7 0210 setgraphic 0 0220 define 45,figur$ 0230 identify 2,45 0240 identify 3,45 0250 spritesize 2,1,1 0260 spritesize 3,1,1 0270 spritecolor 2,11 0280 spritecolor 3,11 0290 endproc definera'sprite 0300 // 0310 proc spriteshow 0320 for x:=-20 to 200 do 0330 x0:=x 0340 spritepos 2,x,100 0350 spritepos 3,270-x,100 0360 mote:=spritecollision(2,true) 0370 for t:=1 to 5 do null 0380 if mote then tillbaka 0390 endfor x 0400 endproc spriteshow 0410 // 0420 proc tillbaka 0430 for x:=x0 to -20 step -1 do 0440 spritepos 2,x,100 0450 spritepos 3,270-x,100 0460 for t:=1 to 5 do null 0470 endfor x 0480 if esc then stopshow 0490 endproc tillbaka 0500 // 0510 proc stopshow 0520 border 10 0530 background 11 0540 pencolor 8 0550 settext 0560 print chr$(147),chr$(14) 0570 trap esc+ 0580 stop 0590 endproc stopshow 0600 // 0010 // paddle.l 0020 // -------- 0030 // 0040 proc paddle(pair,ref x,ref y) closed 0050 cia:=13*4096+12*256 0060 sid:=13*4096+4*256 0070 poke cia+13,1 //stäng av timer a avbrott 0080 ddra:=peek(cia+2) 0090 poke cia+2,12*16 0100 poke cia,4*16*pair 0110 x:=peek(sid+25); y:=peek(sid+26) 0120 poke cia+2,ddra 0130 poke cia+13,128+1 // sätt på timer 0140 endproc paddle 0150 // 0160 repeat 0170 paddle(1,x,y) 0180 print x;y 0190 until false 0010 // joystick.l 0020 // ---------- 0030 // 0040 proc joystick(no,ref direction$) 0050 j:=peek(no+56319) 0060 i:=15-j mod 16 0070 case i of 0080 when 1 0090 direction$:="upp" 0100 when 2 0110 direction$:="ner" 0120 when 4 0130 direction$:="vänster" 0140 when 5 0150 direction$:="upp vänster" 0160 when 6 0170 direction$:="ner vänster" 0180 when 8 0190 direction$:="höger" 0200 when 9 0210 direction$:="upp höger" 0220 when 10 0230 direction$:="ner höger" 0240 otherwise 0250 direction$:="ingen" 0260 endcase 0270 if j div 16 mod 2=0 then direction$:=direction$+" eld!" 0280 endproc joystick 0290 dim a$ of 100 0300 print chr$(147) // rensa skärmen 0310 repeat 0320 joystick(2,a$) 0330 print "{home}",a$," " 0340 until false 0005 // kartotek2 0006 // 0007 // 0010 //Litet adresskartotek 0020 //skrivet av chris jorge 0030 //version 02: 28. maj 1983 0040 //cbm comal-80 0050 // 0060 maxant:=40; maxfält:=5 0070 // 0080 dim efternamn$ of 20 0090 dim förnamn$ of 20 0100 dim gatuadr$ of 20, stad$ of 20 0110 dim annat$ of 20 0120 dim enhet$ of 1, svar$ of 1 0130 dim job$ of 1 0140 dim text$(1:maxfält) of 15 0150 dim f$(1:maxant,maxfält) of 20 0160 dim namn$ of 40, f12$ of 40 0170 // 0180 max:=0; post:=0 0190 text$(1):="1. Efternamn" 0200 text$(2):="2. Förnamn" 0210 text$(3):="3. Gata husnr." 0220 text$(4):="4. Postnr. stad" 0230 text$(5):="5. Andre uppl." 0240 // 0250 hämta'adresser 0260 meny 0270 spara'adresser 0280 // 0290 proc meny 0300 while true do //forever 0310 rensa'skärmen 0320 skriv'från(5,1) 0330 print "1 = Inskrivning" 0340 print "2 = Utskrivning" 0350 print "3 = Rättelser" 0360 print "4 = Ta bort post" 0370 print "5 = Avsluta" 0380 print 0390 input "Välj job: ": job$ 0400 case job$ of 0410 when "1" 0420 inskrivning 0430 when "2" 0440 utskrivning 0450 when "3" 0460 rättelser 0470 when "4" 0480 ta'bort 0490 when "5" 0500 return 0510 otherwise 0520 null //inget 0530 endcase 0540 endwhile 0550 endproc meny 0560 // 0570 proc inskrivning 0580 repeat 0590 rensa'skärmen 0600 for fält:=1 to maxfält do hämta(fält) 0610 hämta'svar("Rättelser (j/)?",svar$) 0620 if svar$<>"" then rätta'post 0630 hämta'svar("Insätt (n/)? ",svar$) 0640 if svar$="" then sätt'upp 0650 hämta'svar("Flera (n/)? ",svar$) 0660 until svar$="n" 0670 endproc inskrivning 0680 // 0690 proc hämta(fält) 0700 case fält of 0710 when 1 0720 slå'in(text$(1),efternamn$) 0730 when 2 0740 slå'in(text$(2),förnamn$) 0750 when 3 0760 slå'in(text$(3),gatuadr$) 0770 when 4 0780 slå'in(text$(4),stad$) 0790 when 5 0800 slå'in(text$(5),annat$) 0810 otherwise 0820 null //anullera processen 0830 endcase 0840 endproc hämta 0850 // 0860 proc slå'in(ledtext$,ref buf$) 0870 skriv'från(2*fält+3,1) 0880 print ledtext$,":" 0890 rensa'infält(fält) 0900 skriv'från(2*fält+3,20) 0910 input "": buf$ 0920 endproc slå'in 0930 // 0940 proc rätta'post 0950 repeat 0960 rensa'rad(20) 0970 input "Ange fält nummer: ": fält 0980 hämta(fält) 0990 rensa'rad(20) 1000 hämta'svar("Flera rättelser (j/)? ",svar$) 1010 until svar$="" 1020 endproc rätta'post 1030 // 1040 proc sätt'upp 1050 namn$:=efternamn$+förnamn$ 1060 binsök(namn$) 1070 // 1080 for j:=max to post step -1 do 1090 for fält:=1 to maxfält do 1100 f$(j+1,fält):=f$(j,fält) 1110 endfor fält 1120 endfor j 1130 sätt'in(post) 1140 max:=max+1 1150 endproc sätt'upp 1160 // 1170 proc sätt'in(post) 1180 f$(post,1):=efternamn$ 1190 f$(post,2):=förnamn$ 1200 f$(post,3):=gatuadr$ 1210 f$(post,4):=stad$ 1220 f$(post,5):=annat$ 1230 endproc sätt'in 1240 // 1250 proc binsök(n$) 1260 v:=1; h:=max 1270 while v<=h do 1280 m:=(v+h) div 2 1290 f12$:=f$(m,1)+f$(m,2) 1300 if n$"2" then 1980 rensa'skärmen 1990 skriv'från(10,1) 2000 endif 2010 print f$(n,2);f$(n,1),"," 2020 print f$(n,3),"," 2030 print f$(n,4) 2035 print f$(n,5) 2040 if enhet$<>"2" then 2050 hämta'svar("Tryck på : ",svar$) 2060 else 2070 ryck'fram 2080 endif 2090 endproc skriv'ut 2100 // 2110 proc rättelser 2120 rensa'skärmen 2130 skriv'från(10,1) 2140 for fält:=1 to 2 do hämta(fält) 2150 finn(efternamn$,förnamn$) 2160 if funnet then 2170 rensa'skärmen 2180 for fält:=1 to maxfält do 2190 skriv'från(2*fält+3,1) 2200 print text$(fält) 2210 skriv'från(2*fält+3,20) 2220 print f$(post,fält) 2230 endfor fält 2240 rätta'post 2250 sätt'in(post) 2260 endif 2270 endproc rättelser 2280 // 2290 proc ta'bort 2300 rensa'skärmen 2310 for fält:=1 to 2 do hämta(fält) 2320 finn(efternamn$,förnamn$) 2330 if funnet then 2340 skriv'ut(post) 2350 skriv'från(20,1) 2360 hämta'svar("Skall denna post raderas (j/)? ",svar$) 2370 if svar$="j" then stryk'post 2380 endif 2390 endproc ta'bort 2400 // 2410 proc stryk'post 2420 for i':=post to max do 2430 for fält:=1 to maxfält do 2440 f$(i',fält):=f$(i'+1,fält) 2450 endfor fält 2460 endfor i' 2470 max:=max-1 2480 endproc stryk'post 2490 // 2500 proc hämta'adresser 2510 klargör 2520 open file 5,"adrlista",read 2530 read file 5: max 2540 for n:=1 to max do 2550 for fält:=1 to maxfält do 2560 read file 5: f$(n,fält) 2570 endfor fält 2580 endfor n 2590 close file 5 2600 endproc hämta'adresser 2610 // 2620 proc spara'adresser 2630 klargör 2635 pass "s0:adrlista" // ta bort gammal adresslista ( mogf 12/83 ) 2640 open file 5,"adrlista",write 2650 write file 5: max 2660 for n:=1 to max do 2670 for fält:=1 to maxfält do 2680 write file 5: f$(n,fält) 2690 endfor fält 2700 endfor n 2710 close file 5 2720 endproc spara'adresser 2730 // 2740 proc hämta'svar(ledtext$,ref svar$) 2750 rensa'rad(20) 2760 print chr$(18),ledtext$, 2770 input "": svar$ 2780 endproc hämta'svar 2790 // 2800 proc rensa'skärmen 2810 print chr$(147), 2820 endproc rensa'skärmen 2830 // 2840 proc rensa'infält(fält) 2850 skriv'från(2*fält+3,20) 2860 for p:=1 to 19 do print " ", 2870 endproc rensa'infält 2880 // 2890 proc skriv'från(x,y) 2900 print chr$(19), 2910 for p:=1 to x-1 do print 2920 for p:=1 to y-1 do print chr$(29), 2930 endproc skriv'från 2940 // 2950 proc vänta(t) 2960 for p:=1 to t*750 do null 2970 endproc vänta 2980 // 2990 proc rensa'rad(ln) 3000 skriv'från(ln,1) 3010 for p:=1 to 39 do print " ", 3020 skriv'från(ln,1) 3030 endproc rensa'rad 3040 // 3050 proc klargör 3060 rensa'skärmen 3070 hämta'svar("Klargör diskett och tryck ",svar$) 3080 endproc klargör 3090 // 0005 // småtext 0006 // ------- 0007 // 0010 initialisering 0020 småtext'monitor 0030 // 0040 proc initialisering 0050 dim text$ of 1000, tecken$ of 1 0060 dim t$ of 1, avb$ of 10 0070 dim clr$ of 1, stryk$ of 1 0080 dim bak$ of 1, fram$ of 1 0090 dim bort$ of 1, ned$ of 1 0100 dim streck$ of 1, noll$ of 1 0110 dim enh$ of 1, inskjut$ of 1 0120 dim mark$ of 1, upp$ of 1 0130 dim hem$ of 1, retur$ of 1 0140 dim revon$ of 1, revoff$ of 1 0150 dim job$ of 1, spcs$ of 20 0160 dim rad$ of 40, sök$ of 40 0170 dim nedåt$ of 24, bortåt$ of 40 0180 dim filnamn$ of 15 0190 // 0200 bak$:=chr$(157) //crsr back 0210 fram$:=chr$(29) //crsr right 0220 stryk$:=chr$(20) //delete 0230 streck$:=chr$(164) //markering 0240 noll$:=chr$(0) //ASCII null 0250 clr$:=chr$(147) //clear screen 0260 ned$:=chr$(17) //crsr down 0270 upp$:=chr$(145) //crsr up 0280 inskjut$:=chr$(148) //insert 0290 hem$:=chr$(19) //crsr home 0300 retur$:=chr$(13) //return 0310 revon$:=chr$(18) //reverse on 0320 revoff$:=chr$(146) //reverse off 0330 // 0340 for i:=1 to 40 do 0350 bortåt$(i:i):=fram$ 0360 endfor i 0370 // 0380 for i:=1 to 24 do 0390 nedåt$(i:i):=ned$ 0400 endfor i 0410 // 0420 spcs$(1:20):="" //mellanrum 0430 bredd:=39; max:=0 0440 köerna'skall'in:=false 0450 endproc initialisering 0460 // 0470 proc småtext'monitor 0480 repeat 0490 repeat 0500 rensa'skärmen 0510 visa'text 0520 ok:=true; pil:=0 0530 ange'jobb 0540 case job$ of 0550 when "n" 0560 skriv'ny'text 0570 when "j" 0580 förändra'text 0590 when "u" 0600 skriv'ut'texten 0610 when "s" 0620 spara'texten 0630 when "l" 0640 hämta'texten 0650 when "a" 0660 köerna'skall'in:=true 0670 otherwise 0680 ok:=false 0690 endcase 0700 until ok 0710 until köerna'skall'in 0720 endproc småtext'monitor 0730 // 0740 proc ange'jobb 0750 skriv'från(1,1) 0760 print "Ange jobb: n j u s l a" 0770 hämta(job$,1,12) 0780 endproc ange'jobb 0790 // 0800 proc skriv'ny'text 0810 avb$:=upp$+ned$+bak$+fram$ 0820 avb$:=avb$+inskjut$+clr$+hem$ 0830 rensa'skärmen 0840 visa'jobb("n") 0850 max:=1; pil:=1; text$:=" " 0860 sätt'av:=3 0870 hämta'text(text$,max,pil) 0880 max:=max-1 0890 text$:=text$(1:max) 0900 endproc skriv'ny'text 0910 // 0920 proc visa'jobb(job$) 0930 skriv'från(1,1) 0940 print " n j u s l a" 0950 p:=job$ in "n j u s l a" 0960 skriv'från(1,p+15) 0970 rev'on 0980 print job$, 0990 rev'off 1000 endproc visa'jobb 1010 // 1020 proc hämta(ref tecken$,x,y) 1030 tecken$:=""; t$:=noll$ 1040 tid:=0 1050 while t$=noll$ do 1060 t$:=key$ 1070 tid:=tid+1 1080 if job$="j" then 1090 markera(5,20) 1100 else 1110 markera(x,y) 1120 endif 1130 endwhile 1140 kolla'tecken:=(t$ in avb$) 1150 if kolla'tecken then return 1160 if t$=retur$ then t$:="^" 1170 print t$, 1180 tecken$:=t$ 1190 endproc hämta 1200 // 1210 proc markera(x,y) 1220 hämta'märke 1230 skriv'från(x,y) 1240 if tid mod 8<4 then 1250 print mark$, 1260 else 1270 print streck$, 1280 endif 1290 print bak$, 1300 endproc markera 1310 // 1320 proc förändra'text 1330 avb$:=upp$+ned$+inskjut$+clr$+hem$ 1340 visa'text 1350 visa'jobb("j") 1360 hämta'söktext 1370 finn(pil) 1380 if not funnet then return 1390 rensa'skärmen 1400 visa'jobb("j") 1410 fönster 1420 sätt'av:=3 1430 hämta'text(text$,max,pil) 1440 endproc förändra'text 1450 // 1460 proc hämta'söktext 1470 skriv'från(1,1) 1480 print "söker:" 1490 sätt'av:=1 1500 job$:="a" 1510 m:=1; p:=1; sök$:=" " 1520 hämta'text(sök$,m,p) 1530 job$:="j" 1540 sök$:=sök$(1:m-1) 1550 endproc hämta'söktext 1560 // 1570 proc hämta'text(ref text$,ref max,ref pil) 1580 hämta(tecken$,x(pil),y(pil)) 1590 while not tecken$="@" do 1600 if not kolla'tecken then 1610 case tecken$ of 1620 when stryk$ 1630 stryk'tecken 1640 when bak$ 1650 if pil>1 then pil:=pil-1 1660 when fram$ 1670 if pil270 then x1:=270; delta1:=0 0360 if x2>270 then x2:=270; delta2:=0 0370 if delta1>=0 then 0380 spritepos 0,x1,y1 0390 spritepos 1,x1,y1 0400 else 0410 spritepos 1,x1,y1 0420 spritepos 0,x1,y1 0430 endif 0440 if delta2>=0 then 0450 spritepos 2,x2,y2 0460 spritepos 3,x2,y2 0470 else 0480 spritepos 3,x2,y2 0490 spritepos 2,x2,y2 0500 endif 0510 ch$:=key$ 0520 if ch$<>chr$(0) then 0530 if ch$="a" then delta1:=-d 0540 if ch$="d" then delta1:=d 0550 if ch$="s" then delta1:=0 0560 if ch$="j" then delta2:=-d 0570 if ch$="l" then delta2:=d 0580 if ch$="k" then delta2:=0 0590 if ch$=" " then i:=y1; y1:=y2; y2:=i 0600 endif 0610 if spritecollision(1,true) or spritecollision(3,false) then collision 0620 flytta'nöt 0630 until ch$="q" 0640 settext 0650 proc init'nöt 0660 nnöt:=2 0670 dim nötter(nnöt,2) 0680 ny'nöt 0690 for i:=4 to nnöt+3 do 0700 spritecolor i,8 0710 identify i,2 0720 spritesize i,0,0 0730 endfor i 0740 spritecolor 5,7 0750 pencolor 8 0760 rita'nöt 0770 moveto 0,20 0780 drawto 0,199 0790 drawto 319,199 0800 drawto 319,20 0810 drawto 0,20 0820 svart:=0; vit:=0 0830 point 0840 i:=spritecollision(1,true) 0850 endproc init'nöt 0860 // 0870 proc flytta'nöt 0880 flytta 0890 rita'nöt 0900 endproc flytta'nöt 0910 // 0920 proc rita'nöt 0930 for i:=1 to nnöt do spritepos i+3,nötter(i,1),nötter(i,2) 0940 endproc rita'nöt 0950 // 0960 proc flytta 0970 for i:=1 to nnöt do 0980 nötter(i,2):-i*4 0990 if nötter(i,2)<40 then nötter(i,2):=200; nötter(i,1):=rnd(1,270) 1000 endfor i 1010 endproc flytta 1020 // 1030 proc collision 1040 vit:+spritecollision(1,false) 1050 svart:+spritecollision(3,false) 1060 byt'om 1070 for i:=1 to nnöt do 1080 if spritecollision(i+3,false) then 1090 nötter(i,1):=rnd(1,270) 1100 nötter(i,2):=200 1110 endif 1120 endfor i 1130 point 1140 rita'nöt 1150 i:=spritecollision(1,true) 1160 endproc collision 1170 // 1180 proc point 1190 pencolor 1 1200 str(vit,tal$) 1210 plottext 40,8,"white: "+tal$ 1220 pencolor 0 1230 str(svart,tal$) 1240 plottext 200,8,"black: "+tal$ 1250 endproc point 1260 // 1270 proc str(i,ref tal$) closed 1280 tal$:=" "; j:=1000 1290 for k:=1 to 4 do 1300 tal$(k):=chr$(48+i div j) 1310 i:=i mod j; j:=j/10 1320 endfor k 1330 endproc str 1340 proc ny'nöt 1350 for i:=1 to nnöt do 1360 nötter(i,1):=rnd(8,280) 1370 nötter(i,2):=rnd(10,80) 1380 endfor i 1390 endproc ny'nöt 1400 // 1410 proc byt'om 1420 if vit<=svart then 1430 y1:=upp; y2:=ned 1440 else 1450 y1:=ned; y2:=upp 1460 endif 1470 endproc byt'om 1480 // 1500 proc instruktion 1510 print "{clear}" 1520 print "figurerna flyttas som anges här :" 1530 print 1540 print 1550 print " den vita spelaren:" 1560 print 1570 print "a flytta åt vänster" 1580 print "s sluta flytta" 1590 print "d flytta åt höger" 1600 print 1610 print " den svarta spelaren:" 1620 print 1630 print "j flytta åt vänster" 1640 print "k sluta flytta" 1650 print "l flytta åt höger" 1660 print 1670 print " starta med någon tangent:" 1680 repeat 1690 until key$<>chr$(0) 1700 endproc instruktion 0001 // 0010 proc soundinit(volume) 0020 sid:=13.25*4096 0030 dim thisnote$ of 3 0040 poke sid+24,volume 0050 for i:=2 to 16 step 7 do poke sid+i,0 0060 for i:=3 to 17 step 7 do poke sid+i,8 0070 for i:=5 to 19 step 7 do poke sid+i,6*16+12 0080 for i:=6 to 20 step 7 do poke sid+i,0 0090 for i:=4 to 18 step 7 do poke sid+i,0 0100 dim notes$ of 3*96, values(0:95,2) 0110 for i:=0 to 95 do 0120 read notes$(i*3+1:i*3+3),values(i,1),values(i,2) 0130 endfor i 0140 data "c0 ",1,18 0150 data "c0#",1,35 0160 data "d0 ",1,52 0170 data "d0#",1,70 0180 data "e0 ",1,90 0190 data "f0 ",1,110 0200 data "f0#",1,132 0210 data "g0 ",1,155 0220 data "g0#",1,179 0230 data "a0 ",1,205 0240 data "b0 ",1,233 0250 data "h0 ",2,6 0260 data "c1 ",2,37 0270 data "c1#",2,69 0280 data "d1 ",2,104 0290 data "d1#",2,140 0300 data "e1 ",2,179 0310 data "f1 ",2,220 0320 data "f1#",3,8 0330 data "g1 ",3,54 0340 data "g1#",3,103 0350 data "a1 ",3,155 0360 data "b1 ",3,210 0370 data "h1 ",4,12 0380 data "c2 ",4,73 0390 data "c2#",4,139 0400 data "d2 ",4,208 0410 data "d2#",5,25 0420 data "e2 ",5,103 0430 data "f2 ",5,185 0440 data "f2#",6,16 0450 data "g2 ",6,108 0460 data "g2#",6,206 0470 data "a2 ",7,53 0480 data "b2 ",7,163 0490 data "h2 ",8,23 0500 data "c3 ",8,147 0510 data "c3#",9,21 0520 data "d3 ",9,159 0530 data "d3#",10,50 0540 data "e3 ",10,205 0550 data "f3 ",11,114 0560 data "f3#",12,32 0570 data "g3 ",12,216 0580 data "g3#",13,156 0590 data "a3 ",14,107 0600 data "b3 ",15,70 0610 data "h3 ",16,47 0620 data "c4 ",17,37 0630 data "c4#",18,42 0640 data "d4 ",19,63 0650 data "d4#",20,100 0660 data "e4 ",21,154 0670 data "f4 ",22,227 0680 data "f4#",24,63 0690 data "g4 ",25,177 0700 data "g4#",27,56 0710 data "a4 ",28,214 0720 data "b4 ",30,141 0730 data "h4 ",32,94 0740 data "c5 ",34,75 0750 data "c5#",36,85 0760 data "d5 ",38,126 0770 data "d5#",40,200 0780 data "e5 ",43,52 0790 data "f5 ",45,198 0800 data "f5#",48,127 0810 data "g5 ",51,97 0820 data "g5#",54,111 0830 data "a5 ",57,172 0840 data "b5 ",61,26 0850 data "h5 ",64,188 0860 data "c6 ",68,149 0870 data "c6#",72,169 0880 data "d6 ",76,252 0890 data "d6#",81,143 0900 data "e6 ",86,105 0910 data "f6 ",91,140 0920 data "f6#",96,254 0930 data "g6 ",102,194 0940 data "g6#",108,223 0950 data "a6 ",115,88 0960 data "b6 ",122,52 0970 data "h6 ",129,120 0980 data "c7 ",137,43 0990 data "c7#",145,83 1000 data "d7 ",153,247 1010 data "d7#",163,31 1020 data "e7 ",172,210 1030 data "f7 ",183,25 1040 data "f7#",193,252 1050 data "g7 ",205,133 1060 data "g7#",217,189 1070 data "a7 ",230,176 1080 data "b7 ",244,103 1090 data "z ",0,0 1100 endproc soundinit 1110 proc adsr(voice,attack,decay,sustain,release) 1120 j:=sid+(voice-1)*7 1130 poke j+5,attack*16+decay 1140 poke j+6,sustain*16+release 1150 endproc adsr 1160 data "a1",2,"z",2,"c2",2,"a1",2,"e1",2,"z",2,"a1",2,"e1",2 1170 data "c1",2,"z",2,"e1",2,"c1",2,"a0",6,"z",2,"e0",2,"a0",2 1180 data "c1",2,"a0",2,"h0",2,"a0",2,"h0",2,"a0",2,"g0#",2,"h0",2,"d1",2 1190 data "h0",2,"c1",2,"z",2,"a0",2,"z",2,"a1",2,"z",2,"c2",2,"a1",2,"e1",2 1200 data "z",2,"a1",2,"e1",2,"c1",2,"z",2,"e1",2,"c1",2,"a0",6 1210 data "z",2,"c1",2,"z",2,"c1",2,"z",2,"c1",2,"z",2,"c1",2 1220 data "z",2,"a1",2,"z",2,"c1",2,"z",2,"c1",4,"h0",2,"z",2 1230 data "e1",2,"z",2,"e1",2,"z",2,"e1",2,"z",2,"e1",2,"z",2 1240 data "c2",2,"z",2,"e1",2,"z",2,"e1",4,"d1#",2,"z",2,"h0",2 1250 data "e1",2,"g1",2,"e1",2,"f1#",2,"e1",2,"f1#",2,"e1",2,"d1#",2 1260 data "f1#",2,"a1",2,"f1#",2,"g1",2,"f1#",2,"g1",2,"f1#",2,"e1",2 1270 data "g1",2,"e1",2,"d1#",2,"e1",2,"a1",2,"e1",2,"d1#",2,"e1",2 1280 data "h1",2,"e1",2,"d1#",2,"e1",2,"c2",2,"e1",2,"d1#",2,"e1",2 1290 data "c2",2,"h1",2,"a1",2,"h1",2,"g1",2,"f1#",2,"e1",2,"g1",2 1300 data "z",2,"g1",.7,"f1#",.7,"g1",.7,"f1#",2,"e1",6,"z",2,"e1",2 1310 data "z",2,"g1",2,"e1",2,"h0",2,"z",2,"e1",2,"h0",2,"g0",2 1320 data "z",2,"h0",2,"g0",2,"e0",6,"z",2,"b0",4,"a0",2,"z",2 1330 data "d1",4,"c1#",2,"d1",2,"g1",4,"f1",2,"e1",2,"f1",2,"z",2 1340 data "d1",2,"z",2,"f1",2,"z",2,"a1",2,"e1",2,"d1",2,"z",2 1350 data "f1",2,"d1",2,"h0",2,"z",2,"d1",2,"h0",2,"g0",6,"z",2 1360 data "g0",2,"c1",2,"e1",2,"c1",2,"d1",2,"c1",2,"d1",2,"c1",2 1370 data "h0",2,"d1",2,"f1",2,"d1",2,"e1",2,"d1",2,"e1",2,"d1",2 1380 data "c1",2,"e1",2,"c1",2,"h0",2,"c1",2,"f1",2,"c1",2,"h0",2 1390 data "c1",2,"g1",2,"c1",2,"h0",2,"c1",2,"a1",2,"c1",2,"h0",2 1400 data "c1",2,"a1",2,"g1",2,"f1",2,"g1",2,"e1",2,"d1",2,"c1",2 1410 data "e1",2,"z",2,"d1",.7,"e1",.7,"d1",.7,"e1",.7,"d1",.7,"c1",6 1420 data "z",2,"e1",2,"z",2,"e1",2,"z",2,"e1",2,"z",2,"e1",2 1430 data "z",2,"c2",2,"z",2,"e1",2,"z",2,"e1",4,"d1",2,"z",2 1440 data "d1",2,"z",2,"d1",2,"z",2,"d1",2,"z",2,"d1",2,"z",2 1450 data "h1",2,"z",2,"d1",2,"z",2,"d1",4,"c1",2,"z",2,"a1",4 1460 data "c2",2,"a1",2,"g1",4,"f1",8,"a1",.7,"g1",.7,"f1",.7,"e1",.7 1470 data "d1",12,"f1",.7,"e1",.7,"d1",.7,"c1",.7,"b0",2,"d1",2,"f1",2 1480 data "d1",2,"b0",2,"a0",2,"b0",2,"a0",2,"g0#",2,"z",2,"e0",2 1490 data "z",2,"f0",4,"e0",2,"z",2,"a0",4,"g0#",2,"h0",2,"d1",4 1500 data "c1",2,"h0",2,"c1",4,"a0",.7,"h0",.7,"c1",.7,"d1",.7,"e1",4 1510 data "c1",2,"e1",2,"a1",2.5,"z",3,"e1",3,"z",2,"d1",3,"c1",3.5 1520 data "h0",3.7,"c1",4,"h0",9,"a0",14,"z",30,"xx",0 1530 soundinit(15) 1540 dim n$ of 3, n1$ of 1, n3$ of 1 1550 s:=sid 1560 for ii:=1 to 3 do 1570 adsr(ii,0,4,12,10) 1580 endfor ii 1590 control:=32 1600 repeat 1610 n$:=" " 1620 read n$(1:3),lng 1630 if n$<>"xx " then 1640 if n$<>"z " then 1650 n$(2):=chr$(ord(n$(2))+4) 1660 i:=((n$ in notes$)-1)/3 1670 poke s,values(i,2) 1680 poke s+1,values(i,1) 1690 poke s+4,control+1 1700 else 1710 poke s+4,control 1720 for ii:=1 to 20 do 1730 endfor ii 1740 endif 1750 for ii:=1 to lng*30 do 1760 endfor ii 1770 poke s+4,control 1780 s:+7 1790 if s=sid+3*7 then s:=sid 1800 endif 1810 until eod 1820 poke sid+24,0 1830 proc k 1840 poke sid+24,0 1850 endproc k 0005 // grafik.01 0010 pencolor 0 0020 background 10 0030 border 11 0040 setgraphic 0 0050 turtlestate false 0055 axlar 0060 // 0070 flytta'till(0,-5) 0080 rita'till(5,0) 0090 rita'till(-5,5) 0100 rita'till(0,-5) 0110 // 0120 // 0130 fyll'i(1,1) 0140 while key$=chr$(0) do null 0150 settext 0160 print chr$(14), 0170 pencolor 8 0180 background 11 0190 border 10 0200 // 0210 proc flytta'till(x,y) 0220 x:=160+x*16 0230 y:=100+y*10 0240 moveto x,y 0250 endproc flytta'till 0260 // 0270 proc rita'till(x,y) 0280 x:=160+x*16 0290 y:=100+y*10 0300 drawto x,y 0310 endproc rita'till 0320 // 0330 proc fyll'i(x,y) 0340 x:=160+x*16 0350 y:=100+y*10 0360 fill x,y 0370 endproc fyll'i 0380 // 5000 proc axlar 5010 dx:=2; dy:=2 5020 moveto 0,100 5030 drawto 320,100 5040 moveto 160,0 5050 drawto 160,200 5060 rita'skala 5070 moveto 160,100 5080 endproc axlar 5090 // 5100 proc rita'skala 5110 moveto 0,100 5120 for m:=0 to 319 step 16 do 5130 lodrätt'markering(m,100) 5140 endfor m 5150 for m:=0 to 199 step 10 do 5160 vågrätt'markering(160,m) 5170 endfor m 5180 endproc rita'skala 5190 // 5200 proc lodrätt'markering(x,y) 5210 moveto m,y+dy 5220 drawto m,y-dy 5230 endproc lodrätt'markering 5240 // 5250 proc vågrätt'markering(x,y) 5260 moveto x+dx,y 5270 drawto x-dx,y 5280 endproc vågrätt'markering 5290 // 0010 grafik'start 0020 trekant 0030 grafik'stopp 0040 // 0050 proc grafik'start 0060 pencolor 0 0070 background 10 0080 border 11 0090 setgraphic 0 0100 turtlestate false 0110 axlar 0120 endproc grafik'start 0130 // 0140 proc trekant 0150 flytta'till(0,0) 0160 rita'till(7,7) 0170 rita'till(5,-3) 0180 rita'till(0,0) 0190 endproc trekant 0200 // 0210 proc grafik'stopp 0220 while key$=chr$(0) do null 0230 settext 0240 print chr$(14), 0250 pencolor 8 0260 background 11 0270 border 10 0280 endproc grafik'stopp 0290 // 0300 proc flytta'till(x,y) 0310 x:=160+x*16 0320 y:=100+y*10 0330 moveto x,y 0340 endproc flytta'till 0350 // 0360 proc rita'till(x,y) 0370 x:=160+x*16 0380 y:=100+y*10 0390 drawto x,y 0400 endproc rita'till 0410 // 0420 proc fyll'i(x,y) 0430 x:=160+x*16 0440 y:=100+y*10 0450 fill x,y 0460 endproc fyll'i 0470 // 0480 proc axlar 0490 dx:=2; dy:=2 0500 moveto 0,100 0510 drawto 320,100 0520 moveto 160,0 0530 drawto 160,200 0540 rita'skala 0550 moveto 160,100 0560 endproc axlar 0570 // 0580 proc rita'skala 0590 moveto 0,100 0600 for m:=0 to 319 step 16 do 0610 lodrätt'markering(m,100) 0620 endfor m 0630 for m:=0 to 199 step 10 do 0640 vågrätt'markering(160,m) 0650 endfor m 0660 endproc rita'skala 0670 // 0680 proc lodrätt'markering(x,y) 0690 moveto m,y+dy 0700 drawto m,y-dy 0710 endproc lodrätt'markering 0720 // 0730 proc vågrätt'markering(x,y) 0740 moveto x+dx,y 0750 drawto x-dx,y 0760 endproc vågrätt'markering 0770 // 0005 // grafik.03 0010 grafik'start 0020 triangel'med'skugga 0030 grafik'stopp 0040 // 0050 proc triangel'med'skugga 0060 flytta'till(0,0) 0070 rita'till(7,7) 0080 rita'till(5,-3) 0090 rita'till(0,0) 0100 fyll'i(2,1) 0110 endproc triangel'med'skugga 0120 // 5000 proc grafik'start 5010 pencolor 0 5020 background 10 5030 border 11 5040 setgraphic 0 5050 turtlestate false 5060 axlar 5070 endproc grafik'start 5080 // 5090 proc grafik'stopp 5100 while key$=chr$(0) do null 5110 settext 5120 print chr$(14), 5130 pencolor 8 5140 background 11 5150 border 10 5160 endproc grafik'stopp 5170 // 5180 proc flytta'till(x,y) 5190 x:=160+x*16 5200 y:=100+y*10 5210 moveto x,y 5220 endproc flytta'till 5230 // 5240 proc rita'till(x,y) 5250 x:=160+x*16 5260 y:=100+y*10 5270 drawto x,y 5280 endproc rita'till 5290 // 5300 proc fyll'i(x,y) 5310 x:=160+x*16 5320 y:=100+y*10 5330 fill x,y 5340 endproc fyll'i 5350 // 5360 proc axlar 5370 dx:=2; dy:=2 5380 moveto 0,100 5390 drawto 320,100 5400 moveto 160,0 5410 drawto 160,200 5420 rita'skala 5430 moveto 160,100 5440 endproc axlar 5450 // 5460 proc rita'skala 5470 moveto 0,100 5480 for m:=0 to 319 step 16 do 5490 lodrätt'markering(m,100) 5500 endfor m 5510 for m:=0 to 199 step 10 do 5520 vågrätt'markering(160,m) 5530 endfor m 5540 endproc rita'skala 5550 // 5560 proc lodrätt'markering(x,y) 5570 moveto m,y+dy 5580 drawto m,y-dy 5590 endproc lodrätt'markering 5600 // 5610 proc vågrätt'markering(x,y) 5620 moveto x+dx,y 5630 drawto x-dx,y 5640 endproc vågrätt'markering 5650 // 0010 graf'start 0020 segla'i'solen 0025 fyll'upp 0030 graf'stop 0040 // 0050 proc segla'i'solen 0070 for a:=0 to 360 step 60 do 0080 t:=a/180*3.14159 0090 x:=2*sin(t)-4; y:=2*cos(t) 0100 trekant(x,y) 0110 endfor a 0120 endproc segla'i'solen 0130 // 0140 proc trekant(x,y) 0150 flytta'till(x,y) 0160 x:=x+7; y:=y+7 0170 rita'till(x,y) 0180 x:=x-2; y:=y-10 0190 rita'till(x,y) 0200 x:=x-5; y:=y+3 0210 rita'till(x,y) 0220 endproc trekant 0230 // 0240 proc fyll'upp 0250 for r:=2 to 3 do 0260 for a:=0 to 360 step 30 do 0270 t:=a/180*3.14159 0280 x:=r*cos(t); y:=r*sin(t) 0290 fyll(x,y) 0300 endfor a 0310 endfor r 0320 endproc fyll'upp 0330 // 5000 proc graf'start 5010 pencolor 0 5020 background 10 5030 border 11 5040 setgraphic 0 5050 turtlestate false 5060 axlar 5070 endproc graf'start 5080 // 5090 proc graf'stop 5100 while key$=chr$(0) do null 5110 settext 5120 print chr$(14), 5130 pencolor 8 5140 background 11 5150 border 10 5160 endproc graf'stop 5170 // 5180 proc flytta'till(x,y) 5190 x:=160+x*16 5200 y:=100+y*10 5210 moveto x,y 5220 endproc flytta'till 5230 // 5240 proc rita'till(x,y) 5250 x:=160+x*16 5260 y:=100+y*10 5270 drawto x,y 5280 endproc rita'till 5290 // 5300 proc fyll(x,y) 5310 x:=160+x*16 5320 y:=100+y*10 5330 fill x,y 5340 endproc fyll 5350 // 5360 proc axlar 5370 dx:=2; dy:=2 5380 moveto 0,100 5390 drawto 320,100 5400 moveto 160,0 5410 drawto 160,200 5420 rita'skala 5430 moveto 160,100 5440 endproc axlar 5450 // 5460 proc rita'skala 5470 moveto 0,100 5480 for m:=0 to 319 step 16 do 5490 lodrätt'markering(m,100) 5500 endfor m 5510 for m:=0 to 199 step 10 do 5520 vågrätt'markering(160,m) 5530 endfor m 5540 endproc rita'skala 5550 // 5560 proc lodrätt'markering(x,y) 5570 moveto m,y+dy 5580 drawto m,y-dy 5590 endproc lodrätt'markering 5600 // 5610 proc vågrätt'markering(x,y) 5620 moveto x+dx,y 5630 drawto x-dx,y 5640 endproc vågrätt'markering 5650 // 0010 graf'start 0020 cirkel 0030 graf'stop 0040 // 0050 proc cirkel 0060 markering(1,-2) 0070 flytta'till(5,-2) 0080 for a:=0 to 360 step 10 do 0090 t:=a/180*3.14159 0100 x:=4*cos(t)+1 0110 y:=4*sin(t)-2 0120 rita'till(x,y) 0130 endfor a 0140 endproc cirkel 0150 // 0160 proc markering(x,y) 0170 flytta'till(x-2/16,y) 0180 rita'till(x+2/16,y) 0190 flytta'till(x,y-2/15) 0200 rita'till(x,y+2/15) 0210 endproc markering 0220 // 0230 proc graf'start 0240 pencolor 0 0250 background 10 0260 border 11 0270 setgraphic 0 0280 turtlestate false 0290 axlar 0300 endproc graf'start 0310 // 0320 proc graf'stop 0330 while key$=chr$(0) do null 0340 settext 0350 print chr$(14), 0360 pencolor 8 0370 background 11 0380 border 10 0390 endproc graf'stop 0400 // 0410 proc flytta'till(x,y) 0420 x:=160+x*16 0430 y:=100+y*15 0440 moveto x,y 0450 endproc flytta'till 0460 // 0470 proc rita'till(x,y) 0480 x:=160+x*16 0490 y:=100+y*15 0500 drawto x,y 0510 endproc rita'till 0520 // 0530 proc fyll(x,y) 0540 x:=160+x*16 0550 y:=100+y*15 0560 fill x,y 0570 endproc fyll 0580 // 0590 proc axlar 0600 dx:=2; dy:=2 0610 moveto 0,100 0620 drawto 320,100 0630 moveto 160,0 0640 drawto 160,200 0650 rita'skala 0660 moveto 160,100 0670 endproc axlar 0680 // 0690 proc rita'skala 0700 moveto 0,100 0710 for m:=0 to 319 step 16 do 0720 lodrätt'markering(m,100) 0730 endfor m 0740 for m:=10 to 209 step 15 do 0750 vågrätt'markering(160,m) 0760 endfor m 0770 endproc rita'skala 0780 // 0790 proc lodrätt'markering(x,y) 0800 moveto m,y+dy 0810 drawto m,y-dy 0820 endproc lodrätt'markering 0830 // 0840 proc vågrätt'markering(x,y) 0850 moveto x+dx,y 0860 drawto x-dx,y 0870 endproc vågrätt'markering 0880 // 0010 graf'start 0020 rita'graf 0030 graf'stop 0040 // 0050 proc rita'graf 0060 flytta'till(-10,f(-10)) 0070 for x:=-10 to 10 step .2 do 0090 rita'till(x,f(x)) 0100 endfor x 0110 endproc rita'graf 0120 // 0130 func f(x) 0140 return 2*exp(x/10)*sin(x) 0150 endfunc f 0160 // 5000 proc markering(x,y) 5010 flytta'till(x-2/16,y) 5020 rita'till(x+2/16,y) 5030 flytta'till(x,y-2/15) 5040 rita'till(x,y+2/15) 5050 endproc markering 5060 // 5070 proc graf'start 5080 pencolor 0 5090 background 10 5100 border 11 5110 setgraphic 0 5120 turtlestate false 5130 axlar 5140 endproc graf'start 5150 // 5160 proc graf'stop 5170 while key$=chr$(0) do null 5180 settext 5190 print chr$(14), 5200 pencolor 8 5210 background 11 5220 border 10 5230 endproc graf'stop 5240 // 5250 proc flytta'till(x,y) 5260 x:=160+x*16 5270 y:=100+y*15 5280 moveto x,y 5290 endproc flytta'till 5300 // 5310 proc rita'till(x,y) 5320 x:=160+x*16 5330 y:=100+y*15 5340 drawto x,y 5350 endproc rita'till 5360 // 5370 proc fyll(x,y) 5380 x:=160+x*16 5390 y:=100+y*15 5400 fill x,y 5410 endproc fyll 5420 // 5430 proc axlar 5440 dx:=2; dy:=2 5450 moveto 0,100 5460 drawto 320,100 5470 moveto 160,0 5480 drawto 160,200 5490 rita'skala 5500 moveto 160,100 5510 endproc axlar 5520 // 5530 proc rita'skala 5540 moveto 0,100 5550 for m:=0 to 319 step 16 do 5560 lodrätt'markering(m,100) 5570 endfor m 5580 for m:=10 to 209 step 15 do 5590 vågrätt'markering(160,m) 5600 endfor m 5610 endproc rita'skala 5620 // 5630 proc lodrätt'markering(x,y) 5640 moveto m,y+dy 5650 drawto m,y-dy 5660 endproc lodrätt'markering 5670 // 5680 proc vågrätt'markering(x,y) 5690 moveto x+dx,y 5700 drawto x-dx,y 5710 endproc vågrätt'markering 5720 // 0010 start'robert 0020 flytta'till(0,-3) 0030 riktning(0) 0040 framåt(7) 0050 vänster(90) 0060 framåt(7) 0070 vänster(90) 0080 framåt(7) 0090 vänster(90) 0100 framåt(7) 0110 vänster(90) 0120 stop'robert 0130 // 0140 proc start'robert 0150 pencolor 0 0160 background 10 0170 border 11 0180 setgraphic 0 0190 turtlestate true 0200 endproc start'robert 0210 // 0220 proc stop'robert 0230 while key$=chr$(0) do null 0240 settext 0250 print chr$(14), 0260 pencolor 8 0270 background 11 0280 border 10 0290 endproc stop'robert 0300 // 0310 proc framåt(x) 0320 forward x*10 0330 endproc framåt 0340 // 0350 proc vänster(v) 0360 nu:=(nu+v) mod 180 0370 left v 0380 endproc vänster 0390 // 0400 proc riktning(v) 0410 nu:=v 0420 setheading v 0430 endproc riktning 0440 // 0450 proc flytta'till(x,y) 0460 moveto x*16+160,y*10+100 0470 endproc flytta'till 0480 // 0490 proc robert'hem 0500 flytta'till(0,0) 0510 riktning(0) 0520 endproc robert'hem 0530 // 0010 start'robert 0020 cirkel'kvadrater 0030 stop'robert 0040 // 0050 proc cirkel'kvadrater 0060 flytta'till(0,0) 0070 for vinkel:=0 to 360 step 10 do 0080 kvadrat(0,0,vinkel,5) 0090 endfor vinkel 0100 endproc cirkel'kvadrater 0110 // 0120 proc kvadrat(x,y,v,s) 0130 flytta'till(x,y) 0140 riktning(v) 0150 for k:=1 to 4 do 0160 framåt(s) 0170 vänster(90) 0180 endfor k 0190 endproc kvadrat 0200 // 5000 proc start'robert 5010 pencolor 0 5020 background 10 5030 border 11 5040 setgraphic 0 5050 turtlestate true 5060 endproc start'robert 5070 // 5080 proc stop'robert 5090 while key$=chr$(0) do null 5100 settext 5110 print chr$(14), 5120 pencolor 8 5130 background 11 5140 border 10 5150 endproc stop'robert 5160 // 5170 proc framåt(x) 5180 forward x*10 5190 endproc framåt 5200 // 5210 proc vänster(v) 5220 nu:=(nu+v) mod 180 5230 left v 5240 endproc vänster 5250 // 5260 proc riktning(v) 5270 nu:=v 5280 setheading v 5290 endproc riktning 5300 // 5310 proc flytta'till(x,y) 5320 moveto x*16+160,y*10+100 5330 endproc flytta'till 5340 // 5350 proc robert'hem 5360 flytta'till(0,0) 5370 riktning(0) 5380 endproc robert'hem 5390 // 0010 start'robert 0020 stor'konst 0025 plottext 200,10,"poul papkasse" 0030 stop'robert 0040 // 0050 proc stor'konst 0060 for b:=1 to 40 do 0070 x:=rnd(-8,3); y:=rnd(-8,3) 0080 sida:=rnd(1,5) 0090 kvadrat(x,y,0,sida) 0100 fyll(x+sida/2,y+sida/2) 0110 endfor b 0120 endproc stor'konst 0130 // 0140 proc kvadrat(x,y,v,s) 0150 flytta'till(x,y) 0160 riktning(v) 0170 for k:=1 to 4 do 0180 framåt(s) 0190 vänster(90) 0200 endfor k 0210 endproc kvadrat 0220 // 0230 proc start'robert 0240 pencolor 0 0250 background 10 0260 border 11 0270 setgraphic 0 0280 turtlestate true 0290 endproc start'robert 0300 // 0310 proc stop'robert 0320 while key$=chr$(0) do null 0330 settext 0340 print chr$(14), 0350 pencolor 8 0360 background 11 0370 border 10 0380 endproc stop'robert 0390 // 0400 proc framåt(x) 0410 forward x*10 0420 endproc framåt 0430 // 0440 proc vänster(v) 0450 nu:=(nu+v) mod 180 0460 left v 0470 endproc vänster 0480 // 0490 proc riktning(v) 0500 nu:=v 0510 setheading v 0520 endproc riktning 0530 // 0540 proc flytta'till(x,y) 0550 moveto x*16+160,y*10+100 0560 endproc flytta'till 0570 // 0580 proc robert'hem 0590 flytta'till(0,0) 0600 riktning(0) 0610 endproc robert'hem 0620 // 0630 proc fyll(x,y) 0640 x:=16*x+160; y:=10*y+100 0650 fill x,y 0660 endproc fyll 0670 // begin 644 comal.t64 M0S8T('1A<&4@:6UA9V4@9FEL90```````````````````1,`$P```%9)0RTV M-"!#3TU!3"TX,"U04D]'4D%-(`&!,##6-```H`(```````!54%!-3U1404L@ M("`@("`@`8$P,,XT``!&!P```````$M/3$Q)4TE/3B`@("`@("`!@3`PY3$` M`.0+````````4$%$1$Q%+DP@("`@("`@(`&!,#`+,P``F0T```````!*3UE3 M5$E#2RY,("`@("`@`8(P,!A+``!T$````````$M!4E1/5$5+("`@("`@("`! M@3`PTTT``%PK````````4TU=5$585"`@("`@("`@(`&!,#`\/P``_T@````` M``!43TU415-014P@("`@("`@`8$P,"-'```+6````````$U54TE+("`@("`@ M("`@("`!@3`P2C4``/YN````````1U)!1DE++C`Q("`@("`@(`&!,##B-0`` M&'0```````!'4D%&24LN,#(@("`@("`@`8$P,"DV``#*>0```````$=2049) M2RXP,R`@("`@("`!@3`PG3<``,-_````````1U)!1DE++C`T("`@("`@(`&! M,##%-@``,(<```````!'4D%&24LN,#4@("`@("`@`8$P,,TV``#%C0`````` M`$=2049)2RXP-B`@("`@("`!@3`PYC,``&*4````````1U)!1DE++C`W("`@ M("`@(`&!,#"C-```&)@```````!'4D%&24LN,#@@("`@("`@`8$P,#