title The Game of Pong name ('PONG') include solvdm.lib ; ; PONG ; ; 08/17/76 20:12 ; BY ROBERT A. VAN VALZAH ; EXTENSIVELY MODIFIED ; BY WARD CHRISTENSEN ; ; ######################################################## ; # Angepasst an den JOYCE, Werner Cirsovius, Maerz 2002 # ; ######################################################## ; ; REPLY TO 'ENTER OPTION': ; S TO PLAY SOLO (WALLS REFLECT ; NO COMPUTER PADDLE) ; W TO PLAY WARM UP; WALLS STILL ; REFLECT, BUT YOU PLAY AGAINST ; THE COMPUTER PADDLE ; P PLAY AGAINST THE COMPUTER ; SERVE CHANGES EVERY 5, MUST ; WIN BY 2. ; ; HIT RUBOUT AT ANY TIME TO GO BACK ; TO ENTER OPTION ; ; HIT CONTROL-C TO RETURN TO CP/M ; extrn SOLon,VDMclr,gotoxy extrn CONsta,CONdat,CONout ;;SOL equ true ; Originaltasten SOL equ false ; Angepasste Tasten IF SOL ; ; Originalzeichen ; margin equ 'I' paddle equ 'I' _UL equ 'U' _UP equ 'I' _UR equ 'O' _LT equ 'J' _RG equ 'L' _DL equ 'M' _DW equ ',' _DR equ '.' ; ELSE ; ; Zeichen fuer Steuerung kompatibel zu CHASE ; margin equ '|' paddle equ '|' _UL equ 'T' _UP equ 'Z' _UR equ 'U' _LT equ 'G' _RG equ 'J' _DL equ 'B' _DW equ 'N' _DR equ 'M' ; ENDIF DELVAL equ 801h ; Verzoegerung lscor equ SOLvid+8 ; Platz fuer linke Punktzahl rscor equ SOLvid+54 ; Platz fuer rechte Punktzahl rcorn1 equ 18*256+22 rcorn2 equ 19*256+24 rcorn3 equ 20*256+22 rcorn4 equ 21*256+24 rcorn5 equ 22*256+22 rcorn6 equ 23*256+22 ld sp,stack ; Stack laden call SOLon ; SOL einschalten pong: ld sp,stack ; Stack neu laden ld hl,SOLvid ld (curs),hl ; Cursoradresse setzen ld hl,recvr ld (hl),-4 ; Links setzen call VDMclr ; Bildschirm loeschen ld hl,opmsg call string ; Frage nach Option pongag: call CONdat ; .. Taste lesen push af ld (optn),a ; Option retten cp 'S' ; Test 'S'olo jr nz,tryp ld a,'I' ld (left),a ld (right),a jr ok tryp: cp 'P' ; Test S'P'iel gegen Computer jr nz,tryw usep: ld a,']' ld (left),a ld a,'[' ld (right),a jr ok tryw: cp 'W' ; Test auf'W'aermen jr z,usep cp 'A' ; Test 'A'uto jr z,ok pop af ; Ignorieren jr pongag ; .. und Neustart ; ok: pop af call CONout ; .. echo ld hl,SOLvid ld (curs),hl ; Cursoradresse setzen ; ; Bildschirm loeschen ; call VDMclr ; Bildschirm loeschen ld hl,(curs) ; Cursor laden ld de,maxcol add hl,de ; Auf naechste Zeile zeigen ; ; +++++++++++++++++++++ Spielfeld aufbauen +++++++++++++++++++++ ; ; Oberste Zeile setzen ; topb: ld_hl_8 '-' ; .. Zeile setzen inc hl ld a,l and maxcol-1 ; Test, ob Zeile fertig jr nz,topb ; ; Linke und rechte Seite des Feldes setzen ; ld b,high VidTop sids: ld_hl_8 margin ; Links setzen left equ $-1 ld a,l or maxcol-1 ; Rechts berechnen ld l,a ld_hl_8 margin ; Rechts setzen right equ $-1 inc hl ld a,h cp b jr nz,sids ; ld de,-maxcol add hl,de ; Letzte Zeile berechnen botb: ld_hl_8 '-' ; Zeile setzen inc hl ld a,l and maxcol-1 jr nz,botb ; ; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; call rose ; Hilfe aufbauen ; ld hl,SOLvid+7*maxcol+2 ld (padl),hl call pdon ; Schlaeger einschalten ld a,(optn) ; Option laden cp 'S' ; Test Option jr z,rest ; .. 'S'olo cp 'W' call nz,sinit ; .. 'W'aermen rest: ld hl,(padl) call poff ; Schlaeger ausschalten ld hl,SOLvid+7*maxcol+2 ld (padl),hl call pdon ; Schlaeger einschalten ld hl,xpos ld (hl),2*maxcol inc hl ld (hl),maxcol-4 inc hl ld (hl),-4 recvr equ $-1 inc hl ld (hl),0 more: call CONsta ; Tastaturstatus holen call nz,mvpa ; .. Zeichen behandeln call auto call off ; Cursor ausschalten advl: ; Geschwindigkeit erhoehen ld hl,xpos ld de,xvel ld a,(de) add a,(hl) ld (hl),a inc de inc hl ld a,(de) add a,(hl) ld (hl),a ; ; Den Ball plazieren ; ld hl,SOLvid ld a,(xpos) rra rra and maxcol-1 add a,l ld l,a ld a,(ypos) rra rra rra and 2*maxrow-1 ld e,a ld d,0 ex de,hl add hl,hl ; * 2 add hl,hl ; * 4 add hl,hl ; * 8 add hl,hl ; *16 add hl,hl ; *32 add hl,hl ; *64 add hl,de ld_a_hl ; Spielstein holen cp '-' jr z,hhit ; Treffer testen cp margin jr z,vhit cp '/' jr z,hiht cp '\' jr z,loht cp ']' jr z,scorr cp '[' jr z,scorl cp ' ' jr nz,rest ld (curs),hl ; ; Im Originalspiel wirdi schlicht der Ball als Leerzeichen ; mit gesetztem Videoattribut dargestellt. ; Ich finde einen 'echten' Ball besser :-) ; IF SOL ld_a_hl or MSB ; Videoattribut setzen ld_hl_a ELSE ld_hl_8 _bal ; Ball setzen ENDIF dely: ld bc,DELVAL wait: dec bc ld a,b or c jr nz,wait jr more ; ; Treffer oben oder unten ; hhit: ld a,(yvel) cpl inc a ld (yvel),a jr advl ; ; Seitlicher Treffer ; vhit: ld a,(xvel) cpl inc a ld (xvel),a jr advl ; ; Treffer am Schlaeger ; hiht: ld a,(yvel) cpl inc a inc a hiht1: ld (yvel),a jr vhit ; Aufprall ; loht: ld a,(yvel) cpl jr hiht1 ; ; Spielergebnisse ; scorr: ld a,(optn) ; Option holen cp 'W' ; Test 'W'aermen jr z,vhit ld hl,score+1 inc (hl) ld de,rscor+2 call inrsc ld d,(hl) dec hl ld b,(hl) jp test ; scorl: ld a,(optn) ; Option holen cp 'W' ; Test 'W'aermen jr z,vhit ld hl,score inc (hl) ld de,lscor+2 call inrsc ld b,(hl) inc hl ld c,(hl) ; ; Routine bestimmt Gewinner ; EIN Reg B haelt linken Spielstand ; Reg C haelt rechten Spielstand ; test: ld hl,0 ; Werte fuer Verzoegerung ld d,3 hold: dec hl ; .. Verzoegerung ld a,h or l jr nz,hold dec d jr nz,hold ; ; Server bestimmen ; ld a,b add a,c ; Spielstand addieren sub10: sub 10 ; Division durch 10 jp p,sub10 add a,10 ld de,256*'<'+ LOW (-3) cp 5 jr c,setsv ld de,256*'>'+ LOW (+3) setsv: ld hl,recvr ld (hl),e ld a,d ld_@_a SOLvid+32 ; ; Punktedifferenz > 1 ? ; ld a,b sub c ; Differenz bilde jp z,rest ; .. Gleichstand cp 1 jp z,rest ; 1 Punk Unterschied cp -1 jp z,rest ; ; Differenz > 1; Gibt es einen Gewinner? ; ld a,b ; Linken Spielstand cp 20+1 jr nc,test2 ; .. gewonnen ld a,c ; Rechten Spielstand cp 20+1 jp c,rest ; .. noch nicht fertig ; ; Gewinner ermittelt ; test2: ld a,b sub c ; Test, wer gewonnen hat ld hl,lscor jr nc,lwin ; RIGHT WIN ld hl,rscor lwin: ld b,6 son: ld_a_hl or MSB ld_hl_a inc hl ld_a_hl or MSB ld_hl_a call swait ld_a_hl and NoMSB ld_hl_a dec hl ld_a_hl and NoMSB ld_hl_a call swait djnz son jp pong ; ; ASCII Zaehler in ^DE erhoehen ; inrsc: dec de ld_a_de inc a ld_de_a cp '9'+1 ret c ld a,'0' ld_de_a jr inrsc ; ; Schlaeger bewegen ; mvpa: call CONdat ; Eingabe holen ld de,-(maxcol+3) ; Bewegung initiieren cp _UL ; .. Testen jr z,pdlmv inc de inc de inc de cp _UP jr z,pdlmv inc de inc de inc de cp _UR jr z,pdlmv ld de,-3 cp _LT jr z,pdlmv ld de,3 cp _RG jr z,pdlmv ld de,maxcol-3 cp _DL jr z,pdlmv inc de inc de inc de cp _DW jr z,pdlmv inc de inc de inc de cp _DR jr z,pdlmv cp esc ; Abbruch? jr nz,try09 ; .. nein, eventuell Delay pop hl jp pong ; .. Neustart try09: sub '0' ; Zahlenwert ermitteln ret c ; .. keine Zahl cp '9'-'0'+1 ret nc rla ld (dely+2),a ; Verzoegerung setzen ret ; ; Bewegung des Schlaegers durchfuehren ; pdlmv: push de ld hl,(padl) call poff ; Schlaeger ausschalten pop de add hl,de ; ; Ball muss im Feld bleiben ; ld_a_hl cp ' ' jr nz,lpadl ld de,-maxcol add hl,de ld_a_hl cp ' ' jr nz,lpadl ld de,2*maxcol add hl,de ld_a_hl cp ' ' jr nz,lpadl ld de,-maxcol add hl,de ld (padl),hl lpadl: ld hl,(padl) pdon: ld a,'/' ld b,paddle ld c,'\' jr pdtg ; ; Schlaeger ausschalten ; poff: ld a,' ' ld b,a ld c,a pdtg: push hl ld_hl_b ld de,-maxcol add hl,de ld_hl_a ld de,2*maxcol add hl,de ld_hl_c pop hl ret ; ; Cursor ausschalten ; -> Gemeint ist der Ball ; off: ld hl,(curs) IF SOL ld_a_hl and NoMSB ld_hl_a ELSE ld_hl_8 ' ' ENDIF ret ; ; Automatische Schlaegerbewegung ; auto: ld a,(optn) ; Option holen cp 'S' ; Test 'S'olo ret z ld a,(xpos) cp 3*maxcol ; <-- Computer testet Entfernung ret c ld a,(xvel) or a ret m ld a,(xpos) and 00000100b ret z ; <-- Computer bewegt 1/2 Ballgeschwindigkeit ld hl,(apadl) call poff ; Schlaeger ausschalten ; ; Vertikale Ballposition ermitteln ; add hl,hl add hl,hl ld a,h and maxrow-1 ; Nur Zeile lassen ld h,a ld a,(ypos) rra rra rra and maxrow-1 ; Nur Zeile lassen ld de,0 sub h ld hl,(apadl) jr z,amove cp 1 jp z,amove cp -1 jr z,amove ld de,-maxcol or a jp m,amove ld de,maxcol amove: add hl,de ld (apadl),hl ld a,'\' ld b,paddle ld c,'/' call pdtg ret ; ; Verzoegerung ca. 0,5 Sekunden (4 MHz) ; swait: push hl ld hl,0 sloop: dec hl ld a,h or l jr nz,sloop pop hl ret ; ; Initialisierung ; sinit: ld hl,lscor ld_hl_8 '0' inc hl ld_hl_8 '0' ld hl,rscor ld_hl_8 '0' inc hl ld_hl_8 '0' ld hl,0 ld (score),hl ret ; ; Hilfe aufbauen ; rose: ld iy,$HLP ; Adresse laden ld b,Hlplen/Hlpitm ; .. Laenge rosloop: ld e,(iy+0) ; Koordinaten laden ld d,(iy+1) ld l,(iy+2) ; .. und Meldung ld h,(iy+3) call msgo ; Meldung ausgeben ld de,Hlpitm add iy,de djnz rosloop ret ; $HLP: dw rcorn1,help1 Hlpitm equ $-$HLP dw rcorn2,help2 dw rcorn3,help3 dw rcorn4,help4 dw rcorn5,help5 dw rcorn6,help6 Hlplen equ $-$HLP ; ; Meldung fuer Hilfe ausgeben ; ; DIE ROUTINE ZEIGT HILFE AUSSERHALB DES VDM-BEREICHES ; ; EIN Reg DE haelt Koordinaten, Reg HL zeigt auf Meldung ; msgo: call gotoxy ; Cursor setzen string: ld a,(hl) cp eot ret z call CONout ; .. Zeichen ausgeben inc hl jr string ; curs: ds 2 ; ; ; Konstanten ; apadl: dw SOLvid+7*maxcol+61 padl: dw 0 xpos: ; \ db 0 ; | ypos: ; | db 0 ; | xvel: ; | db 0 ; | yvel: ; | db 0 ; / score: dw 0 ; Linker, rechter Spielstand optn: db 'W' opmsg: db 'Option (' db 'S'+MSB,'olo, ' db 'W'+MSB,_ae,'rmen, ' db 's','P'+MSB,'ielen)?' db eot help1: db _UL,' ',_UP,' ',_UR db eot help2: db '\ ',_aru,' /' db eot help3: db _LT,' ',_arl,' ',_arr,' ',_RG db eot help4: db '/ ',_ard,' \' db eot help5: db _DL,' ',_DW,' ',_DR db eot help6: db '0..9: Verz.' db eot ; ds 2*25 stack equ $ end