A.N.A.L.O.G. ISSUE 13 / SEPTEMBER 1983 / PAGE 76
Roundup is a public-domain assembly-language game for one player. There are no aliens, laser beams or noisy “ZAP” sounds, just a lot of fun.
Before typing anything into your computer, let’s look at the listings included with this article and see what they do.
Listing 1 is the main data and data checking routine. This listing is used to create both cassette and disk versions of Roundup. As with previous A.N.A.L.O.G. assembly-language programs, the data statements are listed in hexadecimal (base 16) so that the program will run in 16K cassette systems.
Listing 2 must be added to Listing 1 you are using a 410 cassette recorder.
Listing 3 must be added to Listing 1 if you are using a disk drive.
Listing 4 is the assembly-language source code for Roundup, created with the ATARI Macro Assembler. You DO NOT have to type in this listing to play the game! It is provided for those readers interested in seeing how the program works.
Follow the instructions below to make either a cassette or disk version of Roundup.
The game of Roundup requires you to herd and lasso cattle. Plug your joystick into port 1 and press START to begin or restart the game. When the game begins, you will be seen riding a horse on the left side of the screen, between two fences. You can move up and down by pushing the stick. You cannot go above or below the fences.
You will see that you are pursuing cattle to the right of you. The cattle must not be allowed to get behind you off the screen. If three cattle get behind you, the game is over. To prevent this you must move your horse into them and, with renewed vigor, the cattle will then sprint ahead. The cattle get tired, however, and repeated herding will not move the cattle as far. Nevertheless, a skillful trail hand should be able to drive them all day.
While you are doing all this herding you may notice that you aren’t receiving points. Points can only be scored by lassoing the cattle. Push the joystick button to throw your lasso. You must devote all of your attention to lassoing, so you will not be able to move up or down at this time. If your lassoing is successful, the longhorn will disappear and points will be scored.
There are four kinds of cattle. They vary in color, speed and point value. One steer is particularly stubborn and cannot be herded. He must be lassoed or you will lose other cattle. As an added penalty, when the game ends, any unscored points will be lost. Between games your score and the high score are displayed on the bottom of the screen.
This program listing was done with the ATARI Macro Assembler, but can be assembled on other assemblers. For those of you with ATARI’S Editor Assembler cartridge or the OSS EASMD, here are some translation hints.
MACRO EDITOR ASSEMBLER DB .BYTE DW .WORD DS $100 *=*+$100 ORG *= #HIGH ANG #ANG/256 #LOW ANG #ANG&$FF
Extensive use of local labels (:L) has been used to reduce the number of referenced labels. If your assembler does not support local labels, you will have to invent your own unique labels to resolve branches. My equate file is rather long, and not all of the labels are used. You may leave out unused equates to save text buffer RAM.
Roundup should run on any ATARI with a minimum of 16K but will require at least 32K to assemble with the Macro Assembler.
1 REM *** ROUNDUP *** 10 DATA 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15 20 DIM DAT$(91),HEX(22):FOR X=0 TO 22: READ N:HEX(X)=N:NEXT X:LINE=990:RESTOR E 1000:TRAP 60:? "CHECKING DATA" 25 LINE=LINE+10:? "LINE:";LINE:READ DA T$:IF LEN(DAT$)<>90 THEN 110 28 DATLIN=PEEK(183)+PEEK(184)*256:IF D ATLIN<>LINE THEN ? "LINE ";LINE;" MISS ING!":END 30 FOR X=1 TO 89 STEP 2:D1=ASC(DAT$(X, X))-48:D2=ASC(DAT$(X+1,X+1))-48:BYTE=H EX(D1)*16+HEX(D2) 35 IF PASS=2 THEN PUT #1,BYTE:NEXT X:R EAD CHKSUM:GOTO 25 40 TOTAL=TOTAL+BYTE:NEXT X:READ CHKSUM :IF TOTAL=CHKSUM THEN 25 50 GOTO 110 60 IF PEEK(195)<>6 THEN 110 100 ? "WRITING FILE":PASS=2:LINE=990:R ESTORE 1000:TRAP 60:GOTO 25 110 ? "BAD DATA: LINE ";LINE:END 1000 DATA 488A489848AE9E24BDA124BCAA24 8D0AD48D04D48C16D0AD07D0F007A9019D5D20 D01CBD5428C939F015AD04D0,5284 1010 DATA 0D06D0F00DBDBC24F008A9009DBC 24FE53208D1ED0E8E009D002A2008E9E2468A8 68AA68400300000000000000,9613 1020 DATA 000000000000000000000000A200 BD00E09D0008BD00E19DFF08BD00E29DFF09BD 00E39DFF0AE8D0E5A9088DF4,14092 1030 DATA 02A200BDE9239D0808E8E010D0F5 A200BDF9239D1808E8E010D0F5A200BD29249D 2808E8E010D0F5A2008A9D00,19575 1040 DATA 039D00049D00059D00069D00079D 00369D00379D00389D0039E8D0E2A9038D1A36 8D1D368D20368D1D378D2037,23041 1050 DATA 8D2038A9048D1B368D1E368D2136 8D1E378D21378D2138A9058D1A39A9068D1B39 20D925A9008D0002A9208D01,26542 1060 DATA 02A9C08D0ED4A93F8D2F02A9038D 1DD0A90A8D3002A9228D3102A9118D6F02A9C6 8DC802A9D08DC1028DC202A9,31378 1070 DATA 0A8DC0028DC3028DC702A9A88DC4 02A9E48DC502A9168DC602A9008D08D0A9018D 09D08D0AD0A9018D0BD0A9FF,36715 1080 DATA 8D09D28D0CD0A9308D02D3A9F08D 00D3A9348D02D3A9008D07D4A93C8D00D0A930 8D01D0A9408D02D0A9448D07,41986 1090 DATA D0A94C8D06D0A9548D05D0A95C8D 04D0A9648D03D0A9648D7F24A9008D08D2A903 8D0FD2A9648D00D2A91E8D02,47237 1100 DATA D2A9C88D06D220C12220312920A6 25A9008D7726AD0BD4C919D0F9A9CF8D2202A9 248D2302A9018DA225ADA225,52153 1110 DATA D0FBAD7726F0034C3E29AD2F28D0 03208F2220762720C1224CE72170708060575D 248050570036805057003680,56322 1120 DATA 5057003680505700368050570036 80505700368050575D248050463924410A22A2 00BD4124DD8122F0049014B0,59914 1130 DATA 05E8E006D0EFA200BD41249D8122 E8E006D0F5A200BD41249D7922E8E006D0F5A9 748D3722A9228D3822600000,65239 1140 DATA 0000001010101010100000101010 1010100000000000000000AD00D3C90FF01CA9 00854DAD00D3C90EF012C90D,67749 1150 DATA D00DAD7F24C998F006EE7F24EE7F 2460AD7F24C932F0F8CE7F24CE7F2460CEE823 30034CF622A9048DE823AEDB,73566 1160 DATA 23BDDC238D1123E8BDDC238D1223 E8BDDC238D1723E8BDDC238D1823E8E00CD002 A2008EDB23AC7F24A200BD23,78816 1170 DATA 23990004C8E8E023D0F4AD7F2418 6911A8A200BDFFFF990005BDFFFF990006C8E8 E01AD0EE600000263632327A,84216 1180 DATA 323222267C787070707070707070 70383E1F030303060C0402000000000000000F 1F3F5F5F5F5F5F1F10303030,86597 1190 DATA 50A020400000000000081C1CFEFE F6F2F0E0E0E0E030380C040408080000000000 000000000F1F3F5F5F5F9F9F,89981 1200 DATA 1F18181828282848505000000000 081C1CFEFEF6F2F2E0E0E0E020202020505050 5040000000000000000F1F3F,93255 1210 DATA 5F5F5F5F5F1F1808080808080505 0400000000081C1CFEFEF6F2F0E0E0E0E06060 60A0A0A02040000000004523,97003 1220 DATA 5E2377239023A923C2230000FF03 06FF18306000FF0000FF00000000000F1F2FCC 0A0A0004FEF0F03048080080,100406 1230 DATA 4F3F1F1C6406000CFEF0F0302828 00000F7F8F0C1414000CFEF0F018141020701F 1F0F0B08080000E0F0E8A820,103874 1240 DATA 20000033232F3225001010101010 1000232F373300130000000000000000000000 000000000102010201020102,104441 1250 DATA 0102010201020102010201020102 01020102010201020102010200AE9B24E030D0 02A200A000BDF923991808E8,106539 1260 DATA C8C010D0F48E9B24600000000000 0000000000000000000000000000000000000C 000602040401020000000101,107861 1270 DATA 0001000100010000000000000000 0000A9008DA225EE9825EE9925EEA325AD7726 F0034C5FE4ADA425F006CEA4,111628 1280 DATA 254CF924208024ADA5258DA425A9 008DA225A200E000F073BDBD24F031100620DD 284C6025BD9A25F006DE9A25,116455 1290 DATA 4C6025BDA124E90130069DA1244C 5A25A9079DA124FEC724BDB3249D9A254C6025 AD98252901F01FBDA1246901,121042 1300 DATA C908F00890069DA1244C6025A900 9DA124DEC724BDB3249D9A25E8E007D09F2033 2820EE2520BE2520F8282079,125936 1310 DATA 294C5FE4BDA124E902300F9DA124 9DA824BDB3249D9A254C6025A90F9DA1249DA1 244C60250000000000000000,129837 1320 DATA 000000000006A200A9D89DAA249D B124A90A9DB224E8208628E006D0F860A900AA A8BDC724990F22BD55289910,134509 1330 DATA 22C8C8C8C8C8E8E008D0EA60A900 AAA8B90F229DC724C8C8C8C8C8E8E008D0F060 A201207826BDC724300AC924,140758 1340 DATA F013E8E007D0EF60A9019DBD24A9 009DC7244CFC25A91E8DFD29A9A88D07D2BD55 28C938F00FC937F019C936F0,146672 1350 DATA 2BC939F0034CFC25CE4D24CE5220 F0382086284CFC25CE5220CE4D24CE4D24CE52 203024F0222086284CFC25CE,151500 1360 DATA 5220CE4D24CE4D24CE4D24CE5220 CE5220F00830062086284CFC25A9018D77264C FC2500BDBD24F00160BD5420,155973 1370 DATA DDC724D005A9019DBD2460000080 00000000000000000000000000000000000000 000000000000804040000000,157674 1380 DATA 0000000000000000000000000000 00000000000080404020200000000000000000 000000000000000000000000,157994 1390 DATA 0080404020201010000000000000 00000000000000000000000000804040202010 100808000000000000000000,158714 1400 DATA 0000000000000000804040202010 10080804040000000000000000000000000000 008040402020101008080404,159466 1410 DATA 0202000000000000000000000000 00804040202010100808040402020101000000 000000000000000000000000,159852 1420 DATA 00000000000000001C2222C18141 4141413C0000A9012C2F28305A7077D010AD84 02F00160A9018D2F28A2008E,162830 1430 DATA 3028AD98252901F0EEA91A8D3128 AC7F24AE3028BD8C26990003E8C8CE3128D0F3 38E0CEB0048E302860A91AAC,167882 1440 DATA 7F24A200BD5C27990007C8E8E01A D0F4A9F58D9925A9808D2F2860AD9925F00160 A9408D2F28AC7F24A21BA900,173041 1450 DATA 990007C8CAD0F9A9018D302860AD 98252901F00160AE3028A9FF0ACAD0FC8D3228 AC7F24A21BB900032D322899,177885 1460 DATA 0003C8CAD0F3AD30286901C90AF0 048D302860A9008D2F2860000000FFA201BD5E 20D006E8E008D0F660A9009D,182668 1470 DATA 5E202066286002050A640AD87600 02030400243636363636362400000000000000 0000A9008D9925BD5D286D65,184962 1480 DATA 288D6528FE5528BD5528C939F008 C93AF0049D552860BDE828A8B94D289DAA24B9 49289D5D28B951289DB324C0,190116 1490 DATA 03F024A9369D5528A9009DC724A9 019DBD24A9009D5420FEE828BDE828C904D005 A9009DE82860A9399D5528A9,195231 1500 DATA 009DC724A9FF9DBD24AD0AD28DDC 284CAF2800CEDC28D005A9019DBD2460000101 000200010000010100020001,198851 1510 DATA 00AD6528D00160AD98252903F001 60CE6528A005B94124C919F006690199412460 A9109941248810EB60A9008D,203171 1520 DATA 6528A005A91099412488D0F860A9 088D1FD0AD1FD0C906D0F960203C22203129A9 008D2F288D30288D31282021,207502 1530 DATA 29A9398D3722A9248D3822A9038D 5220A9138D4D24A200BDF0289DE828E8E008D0 F56868684C6620AD7726F00F,212388 1540 DATA A9008D01D28D03D28D05D28D07D2 60ADFB29F012AD6528F01EA9008DFB29A9A88D 01D24CB529AD98252902D00A,217592 1550 DATA A9008D01D2A9018DFB29EEFC29AD FC29C915D005A9008DFC29C900F017C903F01B C90AF00FC90CF013C90FF007,223087 1560 DATA C911F00B4CEC29A9848D03D24CEC 29A9008D03D2ADFD29F006CEFD294CFA298D07 D26001000000000000000000,227475
1 DATA 794,955,686,427,745,192,617,894,445,496,549,150,147,897,114,8108 1030 DATA 309,165,126,431,436,356,459, 211,970,661,214,683,723,551,419,6720 1180 DATA 758,19,739,979,686,974,842,2 92,43,811,98,76,942,26,109,7394 1330 DATA 427,553,233,59,114,688,771,8 18,764,551,224,176,312,60,471,6221 1480 DATA 256,222,949,841,944,235,287, 395,38,4167
2 REM *** CASSETTE VERSION *** 65 IF PASS=2 THEN CLOSE #1:END 70 ? "READY CASSETTE AND PRESS RETURN";:OPEN #1,8,128,"C:":RESTORE 200:FOR X =1 TO 35:READ N:PUT #1,N:NEXT X 200 DATA 0,21,221,31,255,31,169,60,141 ,2,211,169,0,141,231,2,133,14,169,56,1 41,232,2,133,15,169,102 210 DATA 133,10,169,32,133,11,24,96 1570 DATA 0000000000000000000000000000 00000000000000000000000000000000000000 000000000000000000000000,227475 1580 DATA 0000000000000000000000000000 00000000000000000000000000000000000000 000000000000000000000000,227475
2 REM *** DISK VERSION *** 65 IF PASS=2 THEN PUT #1,224:PUT #1,2:PUT #1,225:PUT #1,2:PUT #1,102:PUT #1, 32:CLOSE #1:END 70 ? "INSERT DISK WITH DOS, PRESS RETU RN";:DIM IN$(1):INPUT IN$:OPEN #1,8,0, "D:AUTORUN.SYS" 90 PUT #1,255:PUT #1,255:PUT #1,0:PUT #1,32:PUT #1,4:PUT #1,42
;------------------------ ;ROUNDUP by RICHARD LOKEN ;------------------------ ; EQUATES FOR "ROUNDUP" DMACTL = $22F CHBASE = $2F4 POKMSK = 16 RTCLOC = 18 ATRACT = 77 VDSLST = 512 CDTMV2 = 538 CDTMA1 = 552 VVBLKI = 546 SDMCTL = 559 SDLSTL = 560 GPRIOR = 623 STRIG = $284 STRIG0 = 644 PCOLR0 = 704 PCOLR1 = 705 PCOLR2 = 706 PCOLR3 = 707 COLOR0 = 708 COLOR1 = 709 COLOR2 = 710 COLOR3 = 711 COLOR4 = 712 CHBAS = 756 HPOSP0 = $D000 M0PF = $D000 HPOSP1 = $D001 M1PF = $D001 HPOSP2 = $D002 M2PF = $D002 HPOSP3 = $D003 M3PF = $D003 HPOSM0 = $D004 P0PF = $D004 HPOSM1 = $D005 P1PF = $D005 HPOSM2 = $D006 P2PF = $D006 HPOSM3 = $D007 P3PF = $D007 M0PL = $D008 SIZEP0 = $D008 M1PL = $D009 SIZEP1 = $D009 M2PL = $D00A SIZEP2 = $D00A M3PL = $D00B SIZEP3 = $D00B P0PL = $D00C SIZEM = $D00C P1PL = $D00D P2PL = $D00E P3PL = $D00F TRIG0 = $D010 PRIOR = $D01B GRACTL = $D01D HITCLR = $D01E CONSOL = $D01F AUDF1 = $D200 AUDC1 = $D201 AUDF2 = $D202 AUDC2 = $D203 AUDF3 = $D204 AUDC3 = $D205 AUDF4 = $D206 AUDC4 = $D207 AUDCTL = $D208 STIMER = $D209 RANDOM = $D20A PORTA = $D300 PACTL = $D302 HSCROL = $D404 PMBASE = $D407 WSYNC = $D40A VCOUNT = $D40B NMIEN = $D40E SETVBV = $E45C SYSVBV = $E45F XITVBV = $E462 CGREY = $00 CGOLD = $10 CORANG = $20 CREDOR = $30 CPINK = $40 CPURPL = $50 CPURBL = $60 CBLUE1 = $70 CBLUE2 = $80 CLBLUE = $90 CTURQO = $A0 CGRNBL = $B0 CGREEN = $C0 CYEGRN = $D0 CORGRN = $E0 CLORNG = $F0 COLBK = $2C8 MYPMB = $0000 MISSIL = $0300 PL0 = $0400 PL1 = $0500 PL2 = $0600 PL3 = $0700 CHSET = $0800 ;These memory areas are reserved for ;the scrolling cow lines. They are ;aligned on 256-byte boundaries for ;ease of use. COW = $3600 ;3 COWS COW.A = $3700 ;2 COWS COW.B = $3800 ;1 COW ANG = $3900 ;LONE ANGUS ORG $2000 ;the display list interupt stuffs ;the cow color and fine scrolling ;data into the hardware ;also checks herding and lasso ;collisions - sets flags for ;other routines to process DLI PROC PHA ; save all registers TXA PHA TYA PHA LDX LINECT ; get DLI counter LDA LNSC1,X ; get fscrol for line LDY LNCOL1,X ; get line color STA WSYNC STA HSCROL ; and stuff them into STY $D016 ; the hardware ; check for hits on cows LDA P3PF BEQ :L3 LDA #1 STA HIT-1,X BNE :L2 ; check for herding :L3 LDA LMSHI-1,X CMP #HIGH ANG BEQ :L2 LDA P0PF ; get the coll. reg. ORA P2PF BEQ :L2 ; if zero then no coll. LDA LFRT-1,X BEQ :L2 LDA #0 ; yes, a coll. ; change STA LFRT-1,X ; dir. of prev. ln INC NUMHRD-1,X :L2 STA HITCLR ; and clear hit ; finish DLI INX CPX #9 ; 8 is too many BNE :L LDX #0 :L STX LINECT PLA TAY PLA TAX PLA RTI COWLFT DB 3 DB 0 NUMHRD DB 0,0,0,0,0,0,0,0 DB 0,0 HIT DB 0,0,0,0,0,0,0,0 ;program begins and restarts here START PROC LDX #0 ; TRANSFER CHARACTER SET :L LDA $E000,X STA CHSET,X LDA $E100,X STA CHSET+$FF,X LDA $E200,X STA CHSET+$1FF,X LDA $E300,X STA CHSET+$2FF,X INX BNE :L LDA #HIGH CHSET ;INSTALL CHAR SET STA CHBAS LDX #0 ; ALTER CHARACTER SET :L1 LDA FNCE,X STA CHSET+8,X INX CPX #$10 BNE :L1 LDX #0 :L2 LDA COW1,X STA CHSET+$18,X INX CPX #$10 BNE :L2 LDX #0 :L5 LDA ANGUS,X STA CHSET+$28,X INX CPX #$10 BNE :L5 LDX #0 ; CLEAR P/M AND COW LINES TXA :L3 STA MISSIL,X STA PL0,X STA PL1,X STA PL2,X STA PL3,X STA COW,X STA COW.A,X STA COW.B,X STA ANG,X INX BNE :L3 ;now set up the character bytes in the ;cow lines that represent the cows. LDA #3 STA COW+26 STA COW+29 STA COW+32 STA COW.A+29 STA COW.A+32 STA COW.B+32 LDA #4 STA COW+27 STA COW+30 STA COW+33 STA COW.A+30 STA COW.A+33 STA COW.B+33 LDA #5 STA ANG+26 LDA #6 STA ANG+27 JSR INILMS LDA #LOW DLI ; install DLI STA VDSLST LDA #HIGH DLI STA VDSLST+1 LDA #$C0 ;ENABLE DLI STA NMIEN LDA #$3F ; EN.SIN RES + WIDE PF STA SDMCTL LDA #3 ; ENABLE P/M STA GRACTL LDA #LOW DISPL ; install DISPLIST STA SDLSTL LDA #HIGH DISPL STA SDLSTL+1 LDA #$11 ; $11 for 5th player STA GPRIOR LDA #$C6 STA COLOR4 LDA #$D0 ; horse is STA PCOLR1 STA PCOLR2 LDA #$A ; rider and lasso STA PCOLR0 STA PCOLR3 STA COLOR3 LDA #$A8 STA COLOR0 LDA #$E4 STA COLOR1 LDA #$16 STA COLOR2 LDA #0 ; rider is narrow STA SIZEP0 LDA #1 ; horse is medium STA SIZEP1 STA SIZEP2 LDA #1 ; lasso is MEDIUM STA SIZEP3 LDA #$FF STA STIMER STA SIZEM LDA #$30 ; enable joystick STA PACTL LDA #$F0 STA PORTA LDA #$34 STA PACTL LDA #HIGH MYPMB STA PMBASE LDA #60 STA HPOSP0 LDA #48 STA HPOSP1 LDA #64 STA HPOSP2 LDA #68 STA HPOSM3 ; lasso hpos LDA #76 STA HPOSM2 LDA #84 STA HPOSM1 LDA #92 STA HPOSM0 LDA #100 STA HPOSP3 LDA #100 STA VPOSP0 LDA #0 STA $D208 LDA #3 STA $D20F LDA #100 STA AUDF1 LDA #30 STA AUDF2 LDA #200 STA AUDF4 JSR CWPKLD JSR CHEKST JSR INICOL LDA #0 STA GAMEND :L10 LDA VCOUNT CMP #$19 BNE :L10 LDA #LOW VBLANK STA VVBLKI LDA #HIGH VBLANK STA VVBLKI+1 ;most processor time is spent waiting ;for the next VBLANK. mnloop handles ;the stick,lasso, and player image ;lasso in progress will mask the ;stick handler MNLOOP PROC LDA #1 STA VBDONE :L LDA VBDONE BNE :L LDA GAMEND BEQ :L3 JMP NEWGAM :L3 LDA LASTAT BNE :L2 JSR UPDOWN :L2 JSR ROPEM JSR CWPKLD JMP MNLOOP ;simple display list with lms and ;hscrol enable and dli on each line DISPL DB $70,$70,$80,$60,$57 LMS1 DW FENCE DB $80,$50,$57 CW1 DW COW DB $80,$50,$57 CW2 DW COW DB $80,$50,$57 CW3 DW COW DB $80,$50,$57 CW4 DW COW DB $80,$50,$57 CW5 DW COW DB $80,$50,$57 CW6 DW COW DB $80,$50,$57 FN1 DW FENCE DB $80,$50,$46 SCRLN DW SCORLN DB $41 DW DISPL ;checks for hi score and sets score ;for end of game score line CHKHSC PROC LDX #0 :L LDA SCORE,X CMP HSCR,X BEQ :L1 BCC :L2 BCS :L3 :L1 INX CPX #6 BNE :L :L3 LDX #0 :L4 LDA SCORE,X STA HSCR,X INX CPX #6 BNE :L4 :L2 LDX #0 :L5 LDA SCORE,X STA SCR1,X INX CPX #6 BNE :L5 LDA #LOW HSCRL STA SCRLN LDA #HIGH HSCRL STA SCRLN+1 RTS HSCRL DB 0,0,0,0,0 SCR1 DB $10,$10,$10,$10,$10,$10 DB 0,0 HSCR DB $10,$10,$10,$10,$10,$10 DB 0,0,0,0,0,0,0,0 ;reads stick for up/down and sets ;vposp0 for CWPKLD UPDOWN PROC LDA PORTA CMP #$F BEQ :L LDA #0 STA ATRACT LDA PORTA CMP #14 ; GO UP ? BEQ UP CMP #13 ; GO DOWN ? BNE :L DOWN LDA VPOSP0 CMP #152 BEQ :L INC VPOSP0 INC VPOSP0 :L RTS UP LDA VPOSP0 CMP #50 BEQ :L DEC VPOSP0 DEC VPOSP0 RTS ;updates horse + cowboy whether it ;needs it or not and animates horse CWPKLD PROC DEC HRSCTR BMI :L JMP :L1 :L LDA #4 STA HRSCTR LDX HRSAV LDA HS,X STA :L5+1 INX LDA HS,X STA :L5+2 INX LDA HS,X STA :L6+1 INX LDA HS,X STA :L6+2 INX CPX #12 BNE :L2 LDX #0 :L2 STX HRSAV :L1 LDY VPOSP0 LDX #0 :L3 LDA COWBOY,X STA PL0,Y INY INX CPX #35 BNE :L3 LDA VPOSP0 CLC ADC #17 TAY LDX #0 :L5 LDA $FFFF,X STA PL1,Y :L6 LDA $FFFF,X STA PL2,Y INY INX CPX #26 BNE :L5 RTS EPROC ;image data for cowboy and horse COWBOY DB 0,0,$26,$36,$32,$32 DB $7A,$32,$32,$22,$26,$7C DB $78,$70,$70,$70,$70,$70 DB $70,$70,$70,$70,$38,$3E DB $1F,3,3,3,6,$C,4,2,0,0 H1A DB 0,0,0,0,0,$F,$1F,$3F DB $5F,$5F,$5F,$5F,$5F,$1F DB $10,$30,$30,$30,$50,$A0 DB $20,$40,0,0,0 H1B DB 0,0,8,$1C,$1C,$FE,$FE DB $F6,$F2,$F0,$E0,$E0,$E0 DB $E0,$30,$38,$C,4,4,8,8 DB 0,0,0,0 H2A DB 0,0,0,0,0,$F,$1F,$3F DB $5F,$5F,$5F,$9F,$9F,$1F DB $18,$18,$18,$28,$28,$28 DB $48,$50,$50,0,0 H2B DB 0,0,8,$1C,$1C,$FE,$FE DB $F6,$F2,$F2,$E0,$E0,$E0 DB $E0,$20,$20,$20,$20,$50 DB $50,$50,$50,$40,0,0 H3A DB 0,0,0,0,0,$F,$1F,$3F,$5F DB $5F,$5F,$5F,$5F,$1F,$18,8 DB 8,8,8,8,5,5,4,0,0 H3B DB 0,0,8,$1C,$1C,$FE,$FE DB $F6,$F2,$F0,$E0,$E0,$E0 DB $E0,$60,$60,$60,$A0,$A0 DB $A0,$20,$40,0,0,0 HRSAV DB 0 HS DW H1A DW H1B DW H2A DW H2B DW H3A DW H3B HRSCTR DB 0 FNCE DB 0,$FF,3,6,$FF,$18,$30,$60 DB 0,$FF,0,0,$FF,0,0,0 COW1 DB 0,0,$F,$1F,$2F,$CC,$A,$A DB 0,4,$FE,$F0,$F0,$30,$48,8 COW2 DB 0,$80,$4F,$3F,$1F,$1C,$64,6 DB 0,$C,$FE,$F0,$F0,$30,$28,$28 COW3 DB 0,0,$F,$7F,$8F,$C,$14,$14 DB 0,$C,$FE,$F0,$F0,$18,$14,$10 ANGUS DB $20,$70,$1F,$1F,$F,$B,8,8 DB 0,0,$E0,$F0,$E8,$A8,$20,$20 SCORLN DB 0,0,51,35,47,50,37,0 SCORE DB 16,16,16,16,16,16,0 DB 35,47,55,51,0 CWLEFT DB 19,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0 FENCE DB 1,2,1,2,1,2,1,2,1,2 DB 1,2,1,2,1,2,1,2,1,2,1,2 DB 1,2,1,2,1,2,1,2,1,2,1,2 VPOSP0 DB 0 ;animates cows in character set ANIMATE PROC LDX CHINDX CPX #$30 BNE :L LDX #0 :L LDY #0 :L1 LDA COW1,X STA CHSET+$18,Y INX INY CPY #$10 BNE :L1 STX CHINDX RTS CHINDX DB 0,0,0 LINECT DB 0,0,0 LNSC1 DB 0,0,0,0,0,0,0,0,0 LNCOL1 DB 0,0,0,0,0,0,0,0,$C LN1SP DB 0,6,2,4,4,1,2,0,0,0 LFRT DB 1,1,0,1,0,1,0,1,0,0 SLMS1 DB 0,0,0,0,0,0,0,0 ;controls speed of character anima- ;tion and processes fine and coarse ;scrolling ;updates three clocks which are used ;by other routines VBLANK PROC LDA #0 STA VBDONE INC VBCTR INC VBCTR1 INC VBCTR2 LDA GAMEND BEQ :L14 JMP SYSVBV :L14 LDA SSPEED ; time to animate? BEQ :L ; yes DEC SSPEED ; no just count JMP :L1 :L JSR ANIMATE LDA SPEED ; reset counter STA SSPEED :L1 LDA #0 ; handshake with main STA VBDONE LDX #0 ; start scrolling sequence :L7 CPX #0 BEQ MVFENC :L11 LDA LFRT,X BEQ GOLEFT BPL GORIT JSR COUNTD JMP NXLN GORIT LDA SLN1SP,X BEQ :L2 DEC SLN1SP,X JMP NXLN :L2 LDA LNSC1,X SBC #1 BMI :L4 STA LNSC1,X JMP :L8 :L4 LDA #7 STA LNSC1,X INC SLMS1,X LDA LN1SP,X STA SLN1SP,X JMP NXLN GOLEFT LDA VBCTR AND #1 BEQ NXLN LDA LNSC1,X ADC #1 CMP #8 BEQ :L6 BCC :L6 STA LNSC1,X JMP NXLN :L6 LDA #0 STA LNSC1,X DEC SLMS1,X :L8 LDA LN1SP,X STA SLN1SP,X NXLN INX CPX #7 BNE :L11 ;resolve hardware collisions, check ;scrolling for events and effect ;the lms's so the fence and cows ;move JSR CHKHIT JSR LMSCK ; check for excess JSR LMSLD JSR SETSCO JSR SOUND JMP SYSVBV ;the fence never coarse scrolls ;16 fine scrolls = two characters MVFENC PROC :L LDA LNSC1,X SBC #2 BMI :L1 STA LNSC1,X STA LNSC1+7,X LDA LN1SP,X STA SLN1SP,X JMP NXLN :L1 LDA #15 STA LNSC1,X STA LNSC1,X JMP NXLN VBCTR DB 0 VBCTR1 DB 0 SLN1SP DB 0,0,0,0,0,0,0,0 VBDONE DB 0 VBCTR2 DB 0 SSPEED DB 0 SPEED DB 6 ; speed of animation ;initializes color shadows and ;loads six groups of cows INICOL PROC LDX #0 LDA #$D8 STA LNCOL1,X STA LNCOL1+7,X LDA #$A STA LNCOL1+8,X :L INX JSR NEWCOW CPX #6 BNE :L RTS ;writes lms work area into the ;display list LMSLD PROC LDA #0 TAX TAY :L LDA SLMS1,X STA LMS1,Y LDA LMSHI,X STA LMS1+1,Y INY INY INY INY INY INX CPX #8 BNE :L RTS ;takes display list lms from ori- ;ginal load and shadows them in ;the SLMS1 array INILMS PROC LDA #0 TAX TAY :L LDA LMS1,Y STA SLMS1,X INY INY INY INY INY INX CPX #8 BNE :L RTS ;critical routine which prevents ;scrolling from going beyond limits ;calculates missed cows,brings ;herded cows back and checks for ;end of game LMSCK PROC ; check lms for excess LDX #1 :L JSR HERD LDA SLMS1,X BMI :L1 CMP #LOW COW+36 BEQ :L2 :L3 INX CPX #7 BNE :L RTS :L1 LDA #1 STA LFRT,X LDA #0 STA SLMS1,X JMP :L3 :L2 LDA #30 STA MISCOW LDA #$A8 STA AUDC4 LDA LMSHI,X CMP #HIGH COW+2 BEQ :L4 CMP #HIGH COW+1 BEQ :L5 CMP #HIGH COW BEQ :L6 CMP #HIGH ANG BEQ :L4 JMP :L3 :L4 DEC CWLEFT DEC COWLFT BEQ :L7 JSR NEWCOW JMP :L3 :L5 DEC COWLFT DEC CWLEFT DEC CWLEFT DEC COWLFT BMI :L7 BEQ :L7 JSR NEWCOW JMP :L3 :L6 DEC COWLFT DEC CWLEFT DEC CWLEFT DEC CWLEFT DEC COWLFT DEC COWLFT BEQ :L7 BMI :L7 JSR NEWCOW JMP :L3 :L7 LDA #1 STA GAMEND JMP :L3 GAMEND DB 0 ;calculates time to return cows ;after being herded. The number ;of times the line has been ;herded shortens the return time HERD PROC LDA LFRT,X BEQ :L1 RTS :L1 LDA NUMHRD,X CMP SLMS1,X BNE :L2 LDA #1 STA LFRT,X :L2 RTS LASSO1 DB 0,0,$80,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0 ; second image DB 0,0,$80,$40,$40,0,0,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0 ; third image DB 0,0,$80,$40,$40,$20,$20,0,0,0 DB 0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0 ; fourth image DB 0,0,$80,$40,$40,$20,$20,$10,$10 DB 0,0,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0 ; fifth image DB 0,0,$80,$40,$40,$20,$20,$10,$10 DB 8,8,0,0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0 ; sixth image DB 0,0,$80,$40,$40,$20,$20,$10,$10 DB 8,8,4,4,0,0,0,0,0,0,0 DB 0,0,0,0,0,0 ; seventh image DB 0,0,$80,$40,$40,$20,$20,$10,$10 DB 8,8,4,4,2,2,0,0,0,0,0 DB 0,0,0,0,0,0 ; eigthth image DB 0,0,$80,$40,$40,$20,$20,$10,$10 DB 8,8,4,4,2,2,1,1,0,0,0 DB 0,0,0,0,0,0 LASSO2 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,$1C,$22,$22,$C1,$81 DB $41,$41,$41,$41,$3C,0,0 ;throws the lasso,sets flag which ;disables the stick while lasso is ;on screen ROPEM PROC LDA #1 ; test for appropriate BIT LASTAT ; sequence BMI :L ; initial recall BVS :L1 ; continue recall BNE :L2 ; continue shoot LDA STRIG0 ; none of above so BEQ :L3 ; check for trigger :L4 RTS ; not puched so return :L3 LDA #1 ; he wants to fire so STA LASTAT ; set status for cont.sht LDX #0 ; initial index for image STX LSCTR :L2 LDA VBCTR ; don't execute every AND #1 ; time BEQ :L4 ; not yet so return LDA #26 ; initialize counter for STA LSCTR1 ; 26 bytes LDY VPOSP0 ; initialize index to ms LDX LSCTR ; 0,26,52,78,104,130,156 :L5 LDA LASSO1,X ; or 182 - do block STA MISSIL,Y ; move into missile INX ; next image byte INY ; next missile image DEC LSCTR1 ; 26 bytes been moved? BNE :L5 ; not yet so loop back SEC ; have we done the eigtht image? CPX #206 ;a=208 - 206 leaves carry BCS :L6 ; yes,eigtht image done so STX LSCTR ; no so store image cnt RTS ; for next time and return :L6 LDA #26 ; set up fill for pl3 LDY VPOSP0 ; and same vertical pos LDX #0 ; initialize ctr for image :L7 LDA LASSO2,X ; get image byte STA PL3,Y ; and put in pl3 INY ; next vertical position INX ; next image byte CPX #26 ; 26 bytes moved ? BNE :L7 ; no go do more LDA #245 ; yes - set delay for recal STA VBCTR1 LDA #$80 ; and set status for recall STA LASTAT RTS :L LDA VBCTR1 ; check to see if time BEQ :L8 ; if = 0 then init recall RTS ; not time yet :L8 LDA #$40 ; set status for recall STA LASTAT ; in progress LDY VPOSP0 ; get vertical index LDX #27 ; # of bytes to erase from LDA #0 ; player 3 :L9 STA PL3,Y ; erase player 3 INY DEX BNE :L9 ; not done yet LDA #1 STA LSCTR RTS :L1 LDA VBCTR AND #1 BEQ :L14 RTS :L14 LDX LSCTR LDA #$FF :L11 ASL A DEX BNE :L11 STA MSMASK LDY VPOSP0 LDX #27 :L12 LDA MISSIL,Y AND MSMASK STA MISSIL,Y INY DEX BNE :L12 LDA LSCTR ADC #1 CMP #10 BEQ :L13 STA LSCTR RTS :L13 LDA #0 STA LASTAT RTS LASTAT DB 0 LSCTR DB 0 LSCTR1 DB 0 MSMASK DB $FF ;checks HIT array (set by DLI) for ;lasso hits and jumps to a routine ;which removes the cow so to speak CHKHIT PROC LDX #1 :L LDA HIT,X BNE :L3 INX CPX #8 BNE :L RTS :L3 LDA #0 STA HIT,X JSR CLCOW RTS COWRTH DB 2,5,10,100 COWCOL DB CGREY+10 DB CYEGRN+8 DB CBLUE1+6 DB 0 COWSP DB 2,3,4,0 LMSHI DB HIGH FENCE DB HIGH COW DB HIGH COW DB HIGH COW DB HIGH COW DB HIGH COW DB HIGH COW DB HIGH FENCE COWVAL DB 0,0,0,0,0,0,0,0 NEWSCO DB 0 ;sets points to be scored by VBLANK ;and advances cow sequence CLCOW PROC LDA #0 STA VBCTR1 LDA COWVAL,X ADC NEWSCO STA NEWSCO INC LMSHI,X LDA LMSHI,X CMP #HIGH ANG BEQ NEWCOW CMP #HIGH ANG+1 BEQ NEWCOW STA LMSHI,X RTS ;initializes various cow tables and ;advances sequence of cows NEWCOW PROC LDA WHICHC,X TAY LDA COWCOL,Y STA LNCOL1,X LDA COWRTH,Y STA COWVAL,X LDA COWSP,Y STA LN1SP,X CPY #3 BEQ :L1 LDA #HIGH COW STA LMSHI,X LDA #0 STA SLMS1,X LDA #1 STA LFRT,X :L2 LDA #0 STA NUMHRD,X INC WHICHC,X LDA WHICHC,X CMP #4 BNE :L LDA #0 STA WHICHC,X :L RTS :L1 LDA #HIGH ANG STA LMSHI,X LDA #0 STA SLMS1,X LDA #255 STA LFRT,X LDA RANDOM STA ANGCNT JMP :L2 ANGCNT DB 0 ;kills time waiting to put angus on ;the screen - angcnt set by random ;number for a delay of 0 to 3 sec. COUNTD PROC DEC ANGCNT BNE :L LDA #1 STA LFRT,X :L RTS WHICHC DB 0,1,1,0,2,0,1,0 TWHICH DB 0,1,1,0,2,0,1,0 ;called from VBLANK. scores the ;points accumulated in NEWSCO SETSCO PROC LDA NEWSCO BNE :L RTS :L LDA VBCTR AND #3 BEQ :L3 RTS :L3 DEC NEWSCO LDY #5 :L2 LDA SCORE,Y CMP #$19 BEQ :L1 ADC #1 STA SCORE,Y RTS :L1 LDA #$10 STA SCORE,Y DEY BPL :L2 RTS ;zeroes the score at game start CLSCOR PROC LDA #0 STA NEWSCO LDY #5 :L LDA #$10 STA SCORE,Y DEY BNE :L RTS ;freezes execution until START ;key is pressed CHEKST PROC LDA #8 STA CONSOL :L LDA CONSOL CMP #6 BNE :L RTS ;the game is over so look for a new ;high score and show the score - high ;score line ;upon START key reset some arrays NEWGAM PROC JSR CHKHSC JSR CHEKST LDA #0 STA LASTAT STA LSCTR STA LSCTR1 JSR CLSCOR LDA #LOW SCORLN STA SCRLN LDA #HIGH SCORLN STA SCRLN+1 LDA #3 STA COWLFT LDA #19 STA CWLEFT LDX #0 :L LDA TWHICH,X STA WHICHC,X INX CPX #8 BNE :L PLA PLA PLA JMP START ;AUDF1 is point sound ;AUDF2 is clippity clop ;AUDF4 is missed cow sound ;clippity clop is shaped by a ;counter which toggles AUDC2 SOUND PROC LDA GAMEND BEQ :L LDA #0 STA AUDC1 STA AUDC2 STA AUDC3 STA AUDC4 RTS :L LDA PTFLAG BEQ :L1 LDA NEWSCO BEQ :L4 LDA #0 STA PTFLAG LDA #$A8 STA AUDC1 JMP :L4 :L1 LDA VBCTR AND #2 BNE :L4 LDA #0 STA AUDC1 LDA #1 STA PTFLAG :L4 INC CLIPCT LDA CLIPCT CMP #21 BNE :L5 LDA #0 STA CLIPCT :L5 CMP #0 BEQ :L6 CMP #3 BEQ :L7 CMP #10 BEQ :L6 CMP #12 BEQ :L7 CMP #15 BEQ :L6 CMP #17 BEQ :L7 JMP :L8 :L6 LDA #$84 STA AUDC2 JMP :L8 :L7 LDA #0 STA AUDC2 :L8 LDA MISCOW BEQ :L9 DEC MISCOW JMP :L10 :L9 STA AUDC4 :L10 RTS PTFLAG DB 1 CLIPCT DB 0 MISCOW DB 0 END START