1K Hires : Car race

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
Baggers
Posts: 65
Joined: Wed Dec 19, 2012 8:49 pm

Re: 1K Hires : Car race

Post by Baggers »

Great game, and plays well too, fantastic for less than 1K :D job well done!
dr beep
Posts: 2092
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: 1K Hires : Car race

Post by dr beep »

Source with a lot of comment about how the programs works.

Code: Select all

; Car Race                                                      
; a hires racing game for the ZX81 in 1K                        
; based on RACE for the Videopac                                
                                                                
? * TORNADO *                                                   
                                                                
           ORG  #4009                                           
           DUMP 49161                                           
                                                                
; untested, but v marked sysvar might be used in code           
           JP   begin             ; used for jump to program    
d_file     DEFW dfile             ; x                           
dfcc       DEFW dfile+1           ; x                           
var        DEFW vars              ; x                           
dest       DEFW 0                 ; x                           
eline      DEFW last                                            
chadd      DEFW last-1                                          
xptr       DEFW 0                                               
stkbot     DEFW last              ; x                           
stkend     DEFW last              ; x                           
berg       DEFB 0                 ; x                           
mem        DEFW 0                 ; v                           
           DEFB 0                 ; v, not used                 
dfsz       DEFB 2                 ; x                           
stop       DEFW 1                 ; v                           
lastk      DEFB 255,255,255       ; x                           
margin     DEFB 55                ; x                           
nxtlin     DEFW basic             ; v                           
oldppc     DEFW 0                 ; v                           
flagx      DEFB 0                 ; x                           
strlen     DEFW 0                 ; v                           
taddr      DEFW 3213              ; v                           
seed       DEFW 0                 ; x                           
frames     DEFW 65535             ; x                           
coords     DEFB 0,0               ; v                           
prcc       DEFB 188               ; v                           
sposn      DEFB 33,24                                           
cdflag     DEFB 64                                              
                                                                
           DEFB 0                 ; the mask of the racecar     
onoff      DEFB 0,255,255,0,0                                   
           DEFB 0                                               
                                                                
c1         DEFB 096,1             ; computercars x and y pos    
c2         DEFB 048,0                                           
                                                                
carudg     DEFB 7,224             ; UDG of computercars         
           DEFB 111,246                                         
           DEFB 127,254                                         
           DEFB 111,246                                         
           DEFB 9,144                                           
           DEFB 107,214                                         
           DEFB 120,30                                          
           DEFB 103,230           ; 230 used as end marker      
                                                                
begin      LD   IX,hr                                           
                                                                
eog        LD   BC,5              ; end of game                 
           LD   HL,score-1        ; check on hiscore            
           LD   DE,high-1                                       
fhigh      INC  DE                                              
           INC  HL                                              
           LD   A,(DE)                                          
           CP   (HL)                                            
           JR   C,sethi                                         
           JR   NZ,nohigh                                       
           DEC  C                                               
           JR   NZ,fhigh                                        
nohigh     DEFB 33                ; hide LDIR in LD HL,nnnn                                              
sethi      LDIR                   ; copy score to hiscore                                                                          
                                                                
wstart     XOR  A                 ; wait for startkey           
           IN   A,(254)                                         
           CPL                                                  
           AND  28                                              
           JR   Z,wstart          ; wait for startkey           
                                                                
           LD   HL,c1                                           
           SET  7,(HL)            ; cars out of screen          
           INC  HL                                              
           INC  HL                                              
           SET  7,(HL)                                          
                                                                
           LD   HL,score          ; reset score                 
           LD   BC,#51C                                         
clsc       LD   (HL),C                                          
           INC  HL                                              
           DJNZ clsc                                            
                                                                
           INC  HL                                              
           LD   (HL),C            ; reset time                  
                                                                
makescr    LD   HL,hiresdata      ; clear positions around      
           LD   BC,#807           ; playercar                   
clcar      LD   DE,onoff          ; the car mask                
           INC  L                 ; skip pointer                
           INC  L                 ; skip border                 
fend       LD   A,(DE)            ; fetch mask                  
           AND  (HL)              ; keep car                    
           LD   (HL),A            ; set car                     
           INC  E                 ; next mask                   
           INC  L                 ; next pos in line            
           LD   A,L                                             
           INC  A                                               
           AND  C                 ; AND C for speed only        
           JR   NZ,fend           ; handle full line            
           INC  HL                ; skip border right           
           DJNZ clcar             ; handle all lines            
                                                                
           LD   BC,#1081          ; 16 lines and border         
           LD   (maxval+1),A      ; always ZERO from AND C      
er1        LD   (HL),A            ; no line nr                  
           INC  L                                               
           LD   (HL),C            ; set border (needed once)    
           INC  L                                               
           LD   (HL),A            ; erase full line             
           INC  L                                               
           LD   (HL),A                                          
           INC  L                                               
           LD   (HL),A                                          
           INC  L                                               
           LD   (HL),A                                          
           INC  L                                               
           LD   (HL),A                                          
           INC  L                                               
           LD   (HL),C            ; set border                  
           INC  HL                                              
           DJNZ er1               ; now only playercar on screen
                                                                
           LD   DE,c2             ; now set new computercars    
           LD   HL,c1                                           
           LD   A,(hiresdata)                                   
           INC  A                                               
           CP   (HL)              ; car1 below car player       
           EX   DE,HL                                           
           JR   NC,okcall         ; if not do display 1         
           CP   (HL)              ; car2 also below car player  
           EX   DE,HL                                           
           JR   NC,okcall         ; if not do display 2         
           EX   DE,HL                                           
           PUSH HL                                              
           LD   HL,hiresdata+64                                 
           CALL place+6           ; special display for car1    
           DEFB 254               ; cp 225 = C, hide PUSH HL    
okcall     PUSH HL                                              
           CALL NC,place          ; NC to skip entry above      
           POP  DE                                              
                                                                
           CALL place+6           ; second car after first car  
                                                                
           LD   A,%11101111       ; read keys 6 to 0            
           IN   A,(254)                                         
           CPL                                                  
           AND  3                                               
           JR   Z,delay           ; no key pressed              
           DEC  A                                               
           JR   Z,right           ; right pressed               
left       CALL sleft             ; move mask                   
           JR   C,uleft           ; C = undo false move         
           CALL coltest           ; shift ok, now test car      
           JR   C,uleft-1         ; C = undo false move         
           LD   DE,onoff+5                                      
           LD   B,5                                             
flst       DEC  DE                                              
           DEC  B                                               
           LD   A,(DE)                                          
           OR   A                                               
           JR   Z,flst            ; find left start             
           LD   HL,hiresdata+2                                  
           LD   A,L                                             
           ADD  A,B                                             
           LD   L,A               ; point to UDG                
           LD   B,8               ; 8 lines                     
slloop     PUSH DE                ; save start of mask          
           PUSH HL                ; save start of line          
sllp2      RL   (HL)              ; move left                   
           DEC  L                                               
           DEC  E                                               
           LD   A,(DE)                                          
           INC  A                 ; no OR A, carry status needed
           DEC  A                                               
           JR   NZ,sllp2          ; all needed fields done?     
sldone     POP  HL                ; start of left back          
           LD   DE,8                                            
           ADD  HL,DE             ; calc new line               
           POP  DE                ; mask back                   
           DJNZ slloop            ; handle all lines            
           JR   delay             ; car is moved left           
                                                                
right      CALL sright            ; move mask                   
           JR   C,uright          ; C = undo false move         
           CALL coltest           ; test collisin with car      
           JR   C,uright-1        ; C = uno false move          
           LD   B,255                                           
           LD   DE,onoff-1                                      
frst       INC  DE                                              
           INC  B                                               
           LD   A,(DE)                                          
           OR   A                                               
           JR   Z,frst            ; find start right            
           LD   HL,hiresdata+2                                  
           LD   A,L                                             
           ADD  A,B                                             
           LD   L,A               ; point to UDG                
           LD   B,8               ; AS LEFT, but with move right
srloop     PUSH DE                                              
           PUSH HL                                              
srlp2      RR   (HL)                                            
           INC  L                                               
           INC  E                                               
           LD   A,(DE)                                          
           INC  A                 ; no OR A, carry status needed
           DEC  A                                               
           JR   NZ,srlp2                                        
           POP  HL                                              
           LD   DE,8                                            
           ADD  HL,DE                                           
           POP  DE                                              
           DJNZ srloop                                          
           JR   delay                                           
                                                                
           AND  A                 ; reset carry from colltest   
uleft      CALL sright+1          ; undo maskmove               
           JR   delay                                           
           AND  A                 ; reset carry                 
uright     CALL sleft+1           ; undo maskmove               
                                                                
                                                                
delay      LD   HL,frames         ; 1 frame delay to make       
           LD   A,(HL)            ; a stable screen             
wait       CP   (HL)                                            
           JR   Z,wait                                          
           ADD  A,50                                            
           JR   NC,notime         ; test if a second has passed 
           LD   (HL),A            ; reset sec counter           
           LD   HL,time+2                                       
           LD   B,1                                             
           CALL points            ; increase screencounter      
           LD   D,B               ; always 0                    
           LD   B,8                                             
           LD   E,B               ; DE=8, B=8                   
           LD   HL,hiresdata      ; after a second increase     
           LD   A,(HL)            ; screenposition of player    
upcar      INC  (HL)                                            
           ADD  HL,DE                                           
           DJNZ upcar             ; all lines of player done?   
                                                                
           LD   B,A               ; fetch linepositon           
           SUB  E                 ; not counting size of UDG    
           LD   HL,score+4                                      
           CALL NZ,points         ; add position as score       
                                                                
notime     LD   A,(time)          ; test end of game (300 sec)  
           CP   31                ; "3"                         
           JP   Z,eog                                           
                                                                
                                                                
           LD   HL,c1             ; when here, no collission so 
           DEC  (HL)              ; both cars are allowed to go 
           INC  L                 ; down by 1 position          
           INC  L                                               
           DEC  (HL)                                            
           JR   NZ,make1          ; second car not out of screen
                                                                
           LD   HL,c1             ; car1 becomes car2           
           LD   DE,c2                                           
           LDI                                                  
           LD   A,(HL)                                          
           LD   (DE),A                                          
                                                                
           EX   DE,HL                                           
                                                                
rnd        LD   HL,0              ; calculate new RND as x-pos  
           INC  HL                                              
           LD   A,H                                             
           AND  #1F                                             
           LD   H,A                                             
           LD   (rnd+1),HL                                      
           LD   A,(HL)                                          
           AND  3                                               
           LD   (DE),A            ; new car1 x-pos              
           DEC  DE                                              
           LD   A,103                                           
           LD   (DE),A            ; linepos is just out screen  
make1      JP   makescr           ; back to loop                
                                                                
coltest    LD   HL,c1-1                                         
           CALL ctest             ; test car 1                  
           RET  C                 ; same place, not ok          
ctest      LD   A,(hiresdata)     ; car1 and car2 tested        
           INC  HL                                              
           SUB  (HL)                                            
           INC  HL                                              
           LD   C,A                ; differenc to C                                             
           SBC  A,A                ; 255 or 0
           XOR  C                  ; A = ABS (C), absolute value
           CP   8                                               
           RET  NC                ; >8 lines from player=no col 
           EX   DE,HL             ; c1/c2 x-pos to DE           
           LD   HL,onoff                                        
           LD   A,(DE)            ; fetch X                     
           ADD  A,L                                             
           LD   L,A               ; point to mask player        
           LD   A,(HL)            ; fetch mask                  
           INC  HL                                              
           OR   (HL)              ; and test next also          
           EX   DE,HL                                           
           RET  Z                 ; not same place, NoCol       
           SCF                    ; we have collission          
           RET                                                  
                                                                
change     LD   (HL),28           ; the score and timeroutine   
           DEC  HL                                              
           DEFB 62                ; save a byte, no JR needed   
points     PUSH HL                ; B at least 1 on entry!      
           INC  (HL)              ; start is saved for B>1      
           LD   A,(HL)                                          
           CP   38                ; overflow?                   
           JR   Z,change          ; go to next pos if so        
           POP  HL                ; fetch start                 
           DJNZ points            ; handle all points           
           RET                                                  
                                                                
sleft      AND  A                 ; reset carry                 
           LD   HL,onoff+4                                      
           LD   B,5                                             
sl         RL   (HL)              ; move mask left              
           DEC  HL                                              
           DJNZ sl                ; but only 5 positions        
           RET                                                  
                                                                
sright     AND  A                 ; reset carry                 
           LD   HL,onoff                                        
           LD   B,5                                             
sr         RR   (HL)              ; move mask right             
           INC  HL                                              
           DJNZ sr                ; but only 5 positions        
           RET                                                  
                                                                                                                                                                                         
place      LD   HL,hiresdata-8    ; linedown corrects to start  
fpos       CALL linedown          ; 1 line down (or up!)        
           LD   A,(DE)            ; y-pos of c1/c2              
           DEC  A                 ; 1 pos down                  
           CP   (HL)              ; find start of car           
           JR   C,fpos                                          
           INC  E                 ; point to x                  
           LD   B,A               ; y pos                       
           LD   A,(DE)                                          
           LD   C,A               ; x pos                       
           EXX                                                  
           LD   HL,onoff                                        
           ADD  A,L                                             
           LD   L,A               ; point to x on line for col  
           EXX                    ; some extra reg needed       
           LD   DE,carudg-1                                     
nextset    INC  E                 ; carudg pos1 in line         
           LD   (HL),B            ; linenr to screen            
           LD   A,B                                             
           CP   96                                              
           JR   NC,nochange       ; out of screen               
maxval     CP   0                                               
           JR   C,nochange                                      
           LD   (maxval+1),A      ; find start for display      
           LD   (stscreen+1),HL                                 
nochange   LD   A,L                                             
           ADD  A,2                                             
           ADD  A,C                                             
           LD   L,A               ; no carry possible           
           LD   A,(hiresdata)                                   
           CP   B                                               
           JR   NZ,nocol          ; collision only on y player  
           EXX                    ; and back to first set       
           LD   A,(HL)            ; fetch old screen            
           INC  L                                               
           OR   (HL)              ; test clear                  
           DEC  HL                ; back to start for next      
           EXX                                                  
           JR   NZ,bump           ; collision with player       
nocol      LD   A,(DE)            ; copy computer UDG to screem 
           LD   (HL),A                                          
           INC  L                                               
           INC  E                                               
           LD   A,(DE)                                          
           LD   (HL),A                                          
           LD   A,5                                             
           SUB  C                                               
           CALL l2in              ; test for screenwraparound   
           LD   A,(DE)                                          
           SUB  230               ; end of carudg and A=0!      
           JR   NZ,nextset                                      
           RET                    ; car is set                  
bump       POP  HL                ; drop return                 
           LD   HL,c1                                           
           INC  (HL)              ; undo down                   
           INC  L                                               
           INC  L                                               
           INC  (HL)              ; undo down                   
           LD   HL,hiresdata      ; fetch player car            
           LD   DE,8                                            
           LD   B,E                                             
           LD   A,(HL)                                          
           CP   B                                               
           JR   Z,downcret        ; at bottom, no down possible 
downcoll   DEC  (HL)              ; car pushed down             
           ADD  HL,DE                                           
           DJNZ downcoll                                        
downcret   JP   makescr                                         
                                                                
linedown   LD   A,8               ; the screen has player UDG on
           LD   B,(HL)            ; top in memory, but this is  
l2in       DEC  B                 ; not always top of screen.   
           ADD  A,L               ; this calculates the move    
           LD   L,A               ; back to top when needed.    
adddone    LD   A,(hiresdata)                                   
           CP   B                 ; B =next line                
           RET  NZ                ; if not playerudg then end   
           LD   HL,hiresdata      ; otherwise back to top.      
                                                                
;          RET   ; exit through lbuf saves 1 byte               
                                                                
lbuf       LD   R,A                                             
emptyline  DEFB 129,0,0,0,0,0,129 ; 129 = ADD A,C no effect on code!          
           RET                                                  
                                                                
                                                                
hr1del     JR   $+2               ; some timingdelay            
           SBC  HL,DE                                           
           JR   hr11                                            
                                                                
hr         LD   B,14              ; sync first                  
hr00       DJNZ hr00                                            
                                                                
                                                                
           LD   BC,#301           ; 3 lines on top in lowres    
           LD   HL,dfile+#8000                                  
           LD   A,#1E                                           
           LD   I,A                                             
           LD   A,#F5                                           
           CALL #2B5              ; lowres display              
                                                                
stscreen   LD   HL,hiresdata      ; changes per screen!         
                                                                
           LD   B,96              ; 96 lines double shown       
           JR   hr1                                             
settop     LD   HL,hiresdata      ; needed on wraparound        
           DEC  B                 ; 1 to much, but              
           RET  Z                 ; never ZERO! (timing)        
                                                                
hr1        LD   C,2               ; line double displayed       
hr11       LD   A,(HL)                                          
           CP   B                                               
           JP   Z,linedisp        ; show line or empytline      
empty      LD   A,emptyline/256                                 
           LD   I,A                                             
           LD   A,emptyline*256/256                             
           CALL lbuf+#8000                                      
           LD   DE,0              ; no change in pointer        
           JP   dline                                           
linedisp   INC  HL                ; skip pointer                
           LD   A,H                                             
           LD   I,A                                             
           LD   A,L                                             
           CALL lbuf+#8000        ; show line                   
           DEC  HL                ; timing                      
           NOP                    ; timing                      
           LD   DE,8              ; adjust pointer              
dline      ADD  HL,DE                                           
cxlinenr   LD   A,(hiresdata)     ; fetch player y-pos          
           DEC  C                                               
           JR   NZ,hr1del         ; some delay and show twice   
                                                                
           INC  A                                               
           CP   B                 ; next in line player?        
           JP   Z,settop          ; if so change to top         
           INC  BC                ; timing                      
           DJNZ hr1               ; normal loop                 
                                                                
           PUSH HL                ; end of screen, 2 bytes      
           POP  HL                ; still needed?               
           CALL #292                                            
           CALL #220                                            
           LD   IX,hr                                           
           JP   #2A4                                            
                                                                
           DEFB 0,0               ; filler                      
                                                                
                                                                
basic      DEFB 0,1               ; filler and basic call       
           DEFW lenbas-$                                        
           DEFB 249,212,28                                      
           DEFB 126                                             
           DEFB 143,0,18,0,0                                    
lenbas     DEFB 118,0                                           
           DEFB 118                                             
                                                                
dfile      EQU  lenbas            ; the screen                  
score      DEFB 28,28,28,29,37,0                                
time       DEFB 28,28,28,0                                      
high       DEFB 28,28,28,36,29                                  
           DEFB 118                                             
                                                                
           DEFB 0                                               
                                                                
                                                                
; at #4308 never to next highbyte with 192 bytes of screen      
                                                                
hiresdata  DEFB 8,129,0,7,224,0,0,129                           
           DEFB 7,129,0,110,118,0,0,129                         
           DEFB 6,129,0,120,30,0,0,129                          
           DEFB 5,129,0,111,246,0,0,129                         
           DEFB 4,129,0,9,144,0,0,129                           
           DEFB 3,129,0,107,214,0,0,129                         
           DEFB 2,129,0,120,30,0,0,129                          
           DEFB 1,129,0,103,230,0,0,129                         
                                                                
                                                                
endcarpl   DEFB 5,129,7,224,0,0,0,129                           
           DEFB 4,129,110,118,0,0,0,129                         
           DEFB 3,129,124,62,0,0,0,129                          
           DEFB 2,129,104,22,0,0,0,129                          
           DEFB 1,129,14,112,0,0,0,129                          
                                                                
; rest of hiresdata is set by the program.                      
; therefore this part can be used by the ROM-loader as stack.   
                                                                
vars       DEFB 128                                             
                                                                
last       EQU  $                                               
Baggers
Posts: 65
Joined: Wed Dec 19, 2012 8:49 pm

Re: 1K Hires : Car race

Post by Baggers »

16534 :)
dr beep
Posts: 2092
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: 1K Hires : Car race

Post by dr beep »

Baggers wrote:16534 :)
Good score, I just got over it.
car.jpg
car.jpg (24.05 KiB) Viewed 4811 times
dr beep
Posts: 2092
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: 1K Hires : Car race

Post by dr beep »

Found a restartbug, the playercar isn't set back on the bottom.
dr beep
Posts: 2092
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: 1K Hires : Car race

Post by dr beep »

Bugfixed version...
Attachments
car.p
(848 Bytes) Downloaded 305 times
User avatar
zsolt
Posts: 214
Joined: Wed Apr 20, 2011 11:43 am
Location: Fót, Hungary

Re: 1K Hires : Car race

Post by zsolt »

Dear Dr,

First of all: I really like to drive (and not only virtually) so this program is really close to me - nice work (as always), but ...
Yesterday I tested the latest version of my tape loader solution with your games in my real hardware environment and found some mistake. (see the attachment) For example the Car race: parts of the computer cars are hidden when they are near by player's car (in front) - i created some screenshot about this, too.

Regards,
Zsolt
Attachments
1KHR_drBeep.zip
(632.18 KiB) Downloaded 339 times
ZX81 (8K), ENTERPRISE 128, [ZX SPECTRUM (48K,+,+128K,+2,+2A), TS1000, TS1500, TS2068, Cambridge Z88, PRIMO A64 (red)]
dr beep
Posts: 2092
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: 1K Hires : Car race

Post by dr beep »

zsolt wrote:Dear Dr,

First of all: I really like to drive (and not only virtually) so this program is really close to me - nice work (as always), but ...
Yesterday I tested the latest version of my tape loader solution with your games in my real hardware environment and found some mistake. (see the attachment) For example the Car race: parts of the computer cars are hidden when they are near by player's car (in front) - i created some screenshot about this, too.

Regards,
Zsolt
Some of them can be explained.
The screenintrupt is a fact before the entire car is drawn on my 'dummy' screen which is used for the actual draw. When the next intrupt appears after the drawing the screen will be correct. The player car is constantly on screen, the computercars are erased and redrawn each time. This is needed for the right screenorder of the cars and the limited space of the computer, the screenmemory must be defined in the right order of the cars which may vary.

The ball in PONG is the final ball which goes out of screen, the first line is redrawn and the test says out of screen. Then the code ends. This will NOT happen when their is no vertical move on the last ball. I found this minor to the gameplay and left it in.

The upper lowresdisplay might be from an older version, the latest version of PONG has a smaller hiresscreen to give the lowres some room to get in sync.
Also the 3d RANDOM MAZE has a later version with improved lowres display.

As for Ghost Hunt, I never got italic cross.
dr beep
Posts: 2092
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: 1K Hires : Car race

Post by dr beep »

Zsolt pointed to the incorrect display in some cases.

I managed to speed the drawingroutine so the flicker is (almost) gone.
Attachments
car.p
(856 Bytes) Downloaded 755 times
dr beep
Posts: 2092
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: 1K Hires : Car race

Post by dr beep »

zsolt wrote:Dear Dr,

First of all: I really like to drive (and not only virtually) so this program is really close to me - nice work (as always), but ...
Yesterday I tested the latest version of my tape loader solution with your games in my real hardware environment and found some mistake. (see the attachment) For example the Car race: parts of the computer cars are hidden when they are near by player's car (in front) - i created some screenshot about this, too.

Regards,
Zsolt

The screen of ghosthunt is kept as it is, the small reverse italic is kept since the score can be read
The same for 3d rnd maze.

Car Race is altered, other games are in end of game state (car race can have a similar effect)

So now again back to Outlaw!
Post Reply