title Sinus Cosinus fuer PCW name ('SINPLOT') YMAX equ 256 ; CPC: 400 OS equ 0000h BDOS equ 0005h TPAtop equ BDOS+1 .condir equ 6 esc equ 1bh ld sp,(TPAtop) ; Stack laden ld hl,SCRcode ld de,COMMEM ld bc,CODlen ldir ; Bildschirmroutine in COMMON call ClrScr ; Bildschirm loeschen call drawsn ; SINUS und COSINUS plotten call Konsole ; Auf Konsole warten call ClrScr ; Bildschirm loeschen jp OS ; Ende ; ; Bildschirm loeschen ; ClrScr: ld e,esc ; Zwei ESCape Sequenzen call co ld e,'E' call co ld e,esc call co ld e,'H' call co ret ; ; Zeichen von Konsole holen - ohne Echo ; Konsole: ld e,0fdh ; ; Zeichen auf Konsole ausgeben ; co: ld c,.condir call BDOS ; Zeichen verarbeiten ret ; roller equ 0b600h COMMEM equ 0c000h xbios equ 0fc5ah run_scr equ 000e9h ; SCRcode equ $ .phase COMMEM ; plot: ld bc,_plot call xbios dw run_scr ret ; _plot: ld a,00000011b and d ; Spalte maskieren ld d,a ld h,0 add hl,hl ; Zeile*2 ld bc,roller add hl,bc ; Zeiger in das Roller RAM ld c,(hl) ; Adresse holen inc hl ld b,(hl) ld a,c and 11111000b ; Einstellungen vornehmen ld l,a ld h,b ; Echte Adresse berechnen add hl,hl add hl,de ld a,l and 11111000b ld l,a ld a,c and 00000111b or l ld l,a ld a,e ; Bitstatus holen and 00000111b inc a ld b,a xor a scf loop: rra ; Bit positionieren djnz loop or (hl) ; Bit setzen ld (hl),a ret .dephase CODlen equ $-SCRcode ;******************************* ;Testroutine: Sinus- und ;Cosinuskurve zeichnen drawsn: ld hl,0 ;Startwinkel=0 ld bc,320 ;Zaehler ploop: push bc ;Zaehler retten push hl ;Winkel retten push hl push hl push hl ld de,3*YMAX/8 ;Faktor call sinmul ;HL=DE*SIN(HL) ld de,YMAX/2 add hl,de ;Y = Ergebn. + 200 pop de ;X = Winkel call plot ;GRA PLOT ABSOLUTE pop hl ;Winkel holen ld de,3*YMAX/8 ;Faktor call cosmul ;HL=DE*COS(HL) ld de,YMAX/2 add hl,de ;Y = Ergebn. + 200 pop de ;X = Winkel call plot ;GRA PLOT ABSOLUTE pop hl ;Winkel inc hl inc hl ;Winkel + 2 pop bc ;Zaehler dec bc ;Zaehler - 1 ld a,b ;schon = 0? or c jr nz,ploop ;-> nein ret ;******************************** ;Sinus-Berechnung in Integer- ;Arithmetik ;******************************** ;******************************** ;Sinustabelle fuer Winkel 0..90 ;(Werte * 32767) sintab: dw 0,572,1144,1715,2286 dw 2856,3425,3993,4560,5126 dw 5690,6252,6813,7371,7927 dw 8481,9032,9580,10126,10668 dw 11207,11743,12275,12803,13328 dw 13848,14364,14876,15383,15886 dw 16384,16876,17364,17846,18323 dw 18794,19260,19720,20173,20621 dw 21062,21497,21925,22347,22762 dw 23170,23571,23964,24351,24730 dw 25101,25465,25821,26169,26509 dw 26841,27165,27481,27788,28087 dw 28377,28659,28932,29196,29451 dw 29697,29934,30162,30381,30591 dw 30791,30982,31163,31335,31498 dw 31650,31794,31927,32051,32165 dw 32269,32364,32448,32523,32587 dw 32642,32687,32722,32747,32762 dw 32767 ;******************************** ;IN: HL = Winkel in Grad ;OUT: HL = SIN(HL) * 32767 ; A = Vorzeichenflag ; 0 wenn positiv ; &FF wenn negativ intsin: ld bc,360 loop1: bit 7,h ;Winkel positiv? jr z,loop2 ;-> ja, okay add hl,bc ;ansonsten + 360 jr loop1 ;-> weiter testen loop2: or a ;Carry loeschen sbc hl,bc ;Winkel - 360 jr nc,loop2 ;->weiter,wenn >=0 add hl,bc ;sonst korrigieren ld e,l ;Winkel nach DE ld d,h ld bc,90 xor a ;Vorz.flag = 0 sbc hl,bc ;Winkel < 90? jr nc,test2 ;-> nein ex de,hl ;sonst HL = Winkel jr gettab ;Tab.wert holen test2: sbc hl,bc ;Winkel < 180? jr nc,test3 ;-> nein ld hl,180 ;sonst HL = or a ;180 - Winkel sbc hl,de jr gettab ;Tab.wert holen test3: dec a ;Vorz.flag = &FF sbc hl,bc ;Winkel < 270? jr nc,test4 ;- > nein ex de,hl ;sonst HL = or a ;Carry loeschen sbc hl,bc ;Winkel - 180 sbc hl,bc jr gettab ;Tab.wert holen test4: ld hl,360 ;Wenn Winkel>=270 sbc hl,de ;HL = 360 - Winkel gettab: add hl,hl ;Winkel * 2 ld de,sintab ;+ Start Tabelle add hl,de ;= Tabellenadr. ld e,(hl) ;Lowbyte nach E inc hl ld d,(hl) ;Highbyte nach D ex de,hl ;Ergebnis nach HL ret ;******************************** ;Multiplikation mit 32-Bit-Ergeb. ;IN: HL = 1. Faktor ; DE = 2. Faktor ;OUT: DE = Lowword Ergebnis ; HL = Highword Ergebnis mul32: ld b,16 ;16 Bit abgrasen ld ix,0 ;Lowword loeschen mloop: add ix,ix ;Teilergebnis * 2 adc hl,hl ;u. 1. Faktor * 2 jr nc,noadd ;-> nicht addieren add ix,de ;2. Faktor add. jr nc,noadd ;-> kein Uebertrag inc hl ;Highword + 1 noadd: djnz mloop ;-> naechstes Bit push ix ;Lowword nach DE pop de ret ;******************************** ;32-Bit-Vorzeichenwechsel ;IN: DE = Lowword ; HL = Highword ;OUT: DE = -Lowword ; HL = -Highword vzw32: xor a ;Akku loeschen sub e ;32-Bit-Wert ld e,a ;byteweise ld a,0 ;negieren sbc a,d ld d,a ld a,0 sbc a,l ld l,a ld a,0 sbc a,h ld h,a ret ;******************************** ;Berechnet DE * COS(HL) gerundet ;IN: DE = Faktor ; HL = Winkel in Grad ;OUT: HL = DE * COS(HL) cosmul: ld bc,90 add hl,bc ;Winkel + 90 Grad ;******************************** ;Berechnet DE * SIN(HL) gerundet ;IN: DE = Faktor ; HL = Winkel in Grad ;OUT: HL = DE * SIN(HL) sinmul: push de ;Faktor retten call intsin ;HL=Sin(HL)*32767 pop de ;Faktor holen call mul32 ;HL,DE = HL * DE or a ;Vorz. testen call m,vzw32 ;ev. umdrehen ld bc,16384 ;32768/2 ex de,hl ;Low <-> Highword add hl,bc ;Add. fuer Rundung ex de,hl ld bc,0 ;Uebertrag zum adc hl,bc ;Highword addieren sla d ;Ergebnis * 2 und adc hl,hl ;mit dem Highword ret ;weiterrechnen end