Now that I’ve completed the Assembly version of this little game, I want to contrast the required Assembly source with the equivalent BASIC source.
For those that don’t know, BASIC is a simplified computer language that uses an English like syntax. The word BASIC stands for Beginners All-purpose Symbolic Instruction Code. On the Atari 8 bit it is an interpreted language, meaning your program source does not compile down into machine opcode instructions. Rather the BASIC program itself executes each line of a programs source code on the fly when its run (interpreted).
BASIC often was, and perhaps still is in some cases, the first language a new programmer learns. It was designed to be easy to use, and it was included with many (now) vintage computers. Often these computers booted straight into BASIC if no other programs were present – as was the case with the Atari 8 bits. Today there is debate surrounding BASIC’s relevance.
From my point of view, BASIC and Assembly may as well be complete opposites.
Assembly Source
First the Assembly source code (in Mac/65 Assembly) for Number Guess, as presented in the last post.
01 ; ------------------------------ 02 ; App.: GUESSNUM.M65 03 ; Desc: Guess My Number 04 ; ------------------------------ 10 .TITLE "Guess Number, Version 1.0" 15 .OPT OBJ,NO EJECT 20 *= $3600 25 .INCLUDE #D2:A8DEFS.LIB 30 .INCLUDE #D2:A8STRMAC.LIB 0300 ; ------------------------------ 0301 ; Setup Game 0302 ; ------------------------------ 0304 GAMEST 0306 CLD 0310 ; Set Margin 0312 LDA #0 0314 STA LMARG 0320 ; Position 0,0 0322 LDX #0 0324 LDY #0 0326 JSR CURXY 0330 ; Print Title 0332 LDA #STITLE/256 0334 LDY #STITLE&255 0336 JSR PRTLN 0340 ; Position 0,2 0342 LDX #0 0344 LDY #2 0346 JSR CURXY 0350 ; Print statement 0352 LDA #SMYNUM/256 0354 LDY #SMYNUM&255 0356 JSR PRTLN 0359 ; Print What question 0360 LDA #SQWHAT/256 0362 LDY #SQWHAT&255 0364 JSR PRTLN 0370 ; Init Vars 0372 LDX #1 0374 STX VGCNT 0376 LDX #0 0378 STX VGCNT+1 0400 ; Get Random Number 0402 LDA RANDM 0404 AND #100 ; Ensure < 100 0406 STA VMYNUM ; Store it 0408 LDA #0 0410 STA VMYNUM+1 0500 ; ------------------------------ 0501 ; Guess Loop 0502 ; ------------------------------ 0510 GSLOOP 0519 ; Print Guess # 0520 LDA #SGUESS/256 0522 LDX #SGUESS&255 0524 JSR PRTCH 0529 ; Convert Int to String 0530 INT2STR VGCNT,SVGCNT 0534 ; Print it and ? 0535 LDA #SVGCNT/256 0540 LDX #SVGCNT&255 0550 JSR PRTCH 0600 LDA #SQMARK/256 0602 LDX #SQMARK&255 0604 JSR PRTCH 0700 ; Get Users Guess 0710 LDA #VUSNUM/256 0712 LDX #VUSNUM&255 0714 LDY #EOL 0716 JSR INPSTR 0720 ; Convert Str to Int 0725 STR2INT VUSNUM,IUSNUM 0730 LDA IUSNUM 0800 ; Compare guess to num 0802 ; Equal ? 0810 CMP VMYNUM 0812 BCC RTOLOW ; HB < 0814 BNE RTOHI ; HB > 0820 LDA IUSNUM+1 0822 CMP VMYNUM+1 0824 BCC RTOLOW ; LB < 0826 BNE RTOHI ; LB > 0828 BEQ RGOTIT ; LB = 0830 GSFINI ; Guess finish 0840 ; Inc guess # 0845 INC VGCNT 0850 ; Guess max reached? 0860 ; Loop for next guess 0865 JMP GSLOOP 1000 ; ------------------------------ 1001 ; Guess too low 1002 ; ------------------------------ 1010 RTOLOW 1020 LDA #STOLOW/256 1022 LDY #STOLOW&255 1024 JSR PRTLN 1030 JMP GSFINI 1100 ; ------------------------------ 1101 ; Guess too high 1102 ; ------------------------------ 1110 RTOHI 1120 LDA #STOHI/256 1122 LDY #STOHI&255 1124 JSR PRTLN 1130 JMP GSFINI 1200 ; ------------------------------ 1201 ; Guessed it! 1202 ; ------------------------------ 1210 RGOTIT 1220 LDA #SGOTIT/256 1222 LDY #SGOTIT&255 1224 JSR PRTLN 1900 ; ------------------------------ 1901 ; End of program 1902 ; ------------------------------ 1910 GMOVER 1915 LDA #STHX/256 1920 LDY #STHX&255 1925 JSR PRTLN 1995 RTS 30000 ; ----- String Data ----- 30002 STITLE .BYTE CLS,"-[Number Guess]------------------------",EOL 30005 SMYNUM .BYTE "My number is between 1 and 100.",EOL 30010 SQWHAT .BYTE "What is it?",EOL 30015 SGUESS .BYTE "Guess #",EOS 30020 SQMARK .BYTE "? ",EOS 30025 STOHI .BYTE "Sorry, too high!",EOL 30030 STOLOW .BYTE "Sorry, too low!",EOL 30035 SGOTIT .BYTE "You guessed it!",EOL 30040 STHX .BYTE "Thanks for playing.",EOL 30050 SSORRY .BYTE "Sorry, my number was ",EOS 31000 ; ----- Game Vars ----- 31005 VGCNT .BYTE 0,0 31006 SVGCNT .BYTE "00000",EOL 31010 VMYNUM .BYTE 0,0 31020 VUSNUM .BYTE " ",EOL 31025 IUSNUM .BYTE 0,0 50000 ; ----- Function Includes ----- 50010 .INCLUDE #D2:A8FUNCS.LIB 50020 .INCLUDE #D2:A8STRFNC.LIB 64000 ; ---------- E N D ---------- 64001 .END
BASIC Source
I crated two versions. The first version follows the same flow format and line numbering for an easy comparison. The second is shorter version without the same flow restrictions imposed. Both BASIC versions of Number Guess are in Atari BASIC.
Version 1
This is version that emulates the assembly program flow and line numbers to make an easy comparison. Any line number here can be matched up to the same line in the Assembly source above. The Assembly version will generally require more steps (lines) to do the same thing.
10 DIM SINPT$(10),SZERO$(5),SGSNUM$(5),STEMP$(5),SGUESS$(5) 15 IGUESS=0 25 SZERO$="00000" 304 REM Game Start 310 POKE 82,0 320 POSITION 0,0 330 ? CHR$(125);"-[Number Guess, BASIC, V1]--------------" 340 POSITION 0,2 350 ? "My number is between 1 and 100." 360 ? "What is it?" 370 GSNUM=1 400 MYNUM=INT(RND(100)*100) 510 REM Guess Loop 520 ? "GUESS #"; 529 REM CREATE 0 PAD VER OF GUESS # 530 STEMP$=STR$(GSNUM) 531 SGSNUM$=SZERO$(1,5-LEN(STEMP$)) 532 SGSNUM$(5-LEN(STEMP$)+1)=STEMP$ 535 ? SGSNUM$; 710 INPUT SINPT$ 725 IGUESS=VAL(SINPT$) 812 IF IGUESSMYNUM THEN GOTO 1110 828 IF IGUESS=MYNUM THEN GOTO 1210 830 REM End Guess Loop 845 GSNUM=GSNUM+1 865 GOTO 510 1010 REM Too Low 1020 ? "Sorry, too low!" 1030 GOTO 830 1110 REM Too High 1120 ? "Sorry, too high!" 1130 GOTO 830 1210 REM Got It 1220 ? "You guessed it!" 1910 REM Game Over 1915 ? "Thanks for playing." 1995 END
Version 2
This one is shorter and more streamlined. It could also be improved on a lot further, but it gives you an idea.
9 REM DECLARE AND INIT VARS 10 DIM SINPT$(10),SZERO$(5),SGSNUM$(5),STEMP$(5),SGUESS$(5) 15 GSNUM=1:IGUESS=0 20 SZERO$="00000" 29 REM GENERATE RANDOM NUMBER 30 MYNUM=INT(RND(100)*100) 99 REM SETUP SCREEN 100 POKE 82,0 105 ? CHR$(125);"-[Number Guess, BASIC, V2]--------------" 110 ? "My number is between 1 and 100." 115 ? "What is it?" 199 REM CREATE 0 PAD VER OF GUESS # 200 STEMP$=STR$(GSNUM) 210 SGSNUM$=SZERO$(1,5-LEN(STEMP$)) 220 SGSNUM$(5-LEN(STEMP$)+1)=STEMP$ 229 REM DISPLAY GUESS AND GET INPUT 230 ? "Guess #";SGSNUM$; 240 INPUT SINPT$ 249 REM CONVERT INPUT STR TO VALUE 250 IGUESS=VAL(SINPT$) 299 REM CHECK VALUE 300 IF IGUESSMYNUM THEN ? "Sorry, too high!" 320 IF IGUESS=MYNUM THEN ? "You guessed it!":GOTO 400 349 REM INC GUESS COUNT AND REPEAT LP 350 GSNUM=GSNUM+1 360 GOTO 200 399 REM EXIT 400 ? "Thanks for playing."
Comparison
See, BASIC does a lot of work for you! But at the cost of speed and the fact that BASIC must be loaded in some form before your program can be executed. With Assembly programs they can be run without any other programs (or interpreters) loaded first, which makes more memory available to your program.
Results
First a screen shot of the Assembly version being run:
Now a screen shot from the game being played with the first BASIC version:
And lastly, a screen shot from the game being played with the second BASIC version:
As you can see they are basic-ally the same. 😉 The only real difference with the BASIC versions is there is not a space after the “?” when the user inputs the guess.