Program MyProgram;var a,b,c : byte = 0; Procedure Myprocedure(mp_i:byte);var somProcedureVariable : byte;begin // Do sometingend; // This is the main block.begin // Call user-defined procedures etc MyProcedure(2);end.
program SpaceSplat;// Vic 20 unexpanded gamevar Title : cstring = ("Space Splat"); Author : cstring = ("by Tony Brice, 2021"); Start : cstring = ("Space to Start"); Play : cstring = ("Game in progress"); gameState: byte = 1; // 1 = title // 2 = game // 3 = game over // -------------------------------------------------------------------------------// **** Procedures ****// -------------------------------------------------------------------------------procedure RenderTitleScreen();begin moveto(5,2,hi(screen_char_loc)); PrintString( #Title, 0, 11 ); moveto(0,5,hi(screen_char_loc)); PrintString( #Author, 0, 19 ); moveto(3,10,hi(screen_char_loc)); PrintString( #Start, 0, 14 );end;procedure RenderPlayScreen();begin moveto(3,16,hi(screen_char_loc)); PrintString( #Play, 0, 16 );end;procedure ScreenClear();begin ClearScreen( 32, #SCREEN_CHAR_LOC); // ^$1e00 - unexpanded screen location ClearScreen( BLUE, #SCREEN_COL_LOC); // ^$9600 - unexpanded colour location //AUX_COLOR_AND_VOLUME := %00000010; SCREEN_BG_COLOR := BLACK + SCREEN_BG_WHITE; screenmemory := #SCREEN_CHAR_LOC;end;// -------------------------------------------------------------------------------// **** Main Loop ****// -------------------------------------------------------------------------------begin ScreenClear(); while (true) do begin readjoy1(); if ( joy1 & JOY_FIRE ) then begin gameState := gameState+1; ScreenClear(); end; if (gameState > 2) then gameState := 1; if (gameState=1) then RenderTitleScreen(); if (gameState=2) then RenderPlayScreen(); end;end.
processor 6502 org $1000 ; Starting new memory block at $1000StartBlock1000 .byte $0, $0E, $08, $0A, $00, $9E, $20, $28 .byte $34,$31,$31,$32 .byte $29, $00, $00, $00 ; Ending memory blockEndBlock1000 org $1010 ; Starting new memory block at $1010StartBlock1010SpaceSplat jmp block1Title dc.b $13, $10, $01, $03, $05, $20, $13, $10, $0c dc.b $01, $14, 0Author dc.b $02, $19, $20, $14, $0f, $0e, $19, $20, $02 dc.b $12, $09, $03, $05, $2c, $20, $32, $30, $32 dc.b $31, 0Start dc.b $13, $10, $01, $03, $05, $20, $14, $0f, $20 dc.b $13, $14, $01, $12, $14, 0Play dc.b $07, $01, $0d, $05, $20, $09, $0e, $20, $10 dc.b $12, $0f, $07, $12, $05, $13, $13, 0gameState dc.b $01 ; NodeProcedureDecl -1 ; *********** Defining procedure : initjoy1 ; Procedure type : Built-in function ; Requires initialization : no ; ---------- ; ReadJoy1 and ReadJoy2 (on supported platforms) ; populates joy1 and joy1pressed which can be tested by AND-ing with the following constants:;JOY_DOWN = %00000100;JOY_UP = %00000010;JOY_LEFT = %00001000;JOY_RIGHT = %00000001;JOY_FIRE = %00010000VIC20_PORTACASS = $911FVIC20_PORTBVIA2 = $9120 ; Port B 6522 2 value (joystick)VIC20_PORTBVIA2d = $9122 ; Port B 6522 2 direction (joystick)joy1 = $5ejoy1last = $5fjoy1pressed = $60callReadJoy1 LDA VIC20_PORTACASS EOR #$FF AND #$3C LDX #$7F SEI STX VIC20_PORTBVIA2d LDY VIC20_PORTBVIA2 BMI initjoy1_JoySkip2 ORA #$02initjoy1_JoySkip2 LDX #$FF STX VIC20_PORTBVIA2d CLI LSR STA joy1 eor joy1last and joy1 sta joy1pressed lda joy1 sta joy1last rts ; NodeProcedureDecl -1 ; *********** Defining procedure : initmoveto ; Procedure type : Built-in function ; Requires initialization : no jmp initmoveto_moveto3screenmemory = $fecolormemory = $fcscreen_x = $80screen_y = $82SetScreenPosition sta screenmemory+1 lda #0 sta screenmemory ldy screen_y beq sydonesyloop clc adc #22 bcc sskip inc screenmemory+1sskip dey bne syloopsydone ldx screen_x beq sxdone clc adc screen_x bcc sxdone inc screenmemory+1sxdone sta screenmemory rtsinitmoveto_moveto3 rts ; NodeProcedureDecl -1 ; *********** Defining procedure : initprintstring ; Procedure type : User-defined procedureprint_text = $80print_number_text .dc " ",0printstring ldy #0printstringloop lda (print_text),y cmp #0 ;keep beq printstring_done cmp #64 bcc printstring_skip sec sbc #64printstring_skip sta (screenmemory),y iny dex cpx #0 beq printstring_done jmp printstringloopprintstring_done rts ; // Vic 20 unexpanded game; // 1 = title; // 2 = game; // 3 = game over; // -------------------------------------------------------------------------------; // **** Procedures ****; // ------------------------------------------------------------------------------- ; NodeProcedureDecl -1 ; *********** Defining procedure : RenderTitleScreen ; Procedure type : User-defined procedureRenderTitleScreen ; MoveTo optimization lda #$31 sta screenmemory lda #>$1e00 clc adc #$00 sta screenmemory+1 clc lda #<Title adc #$0 ldy #>Title sta print_text+0 sty print_text+1 ldx #$b ; optimized, look out for bugs jsr printstring ; MoveTo optimization lda #$6e sta screenmemory lda #>$1e00 clc adc #$00 sta screenmemory+1 clc lda #<Author adc #$0 ldy #>Author sta print_text+0 sty print_text+1 ldx #$13 ; optimized, look out for bugs jsr printstring ; MoveTo optimization lda #$df sta screenmemory lda #>$1e00 clc adc #$00 sta screenmemory+1 clc lda #<Start adc #$0 ldy #>Start sta print_text+0 sty print_text+1 ldx #$e ; optimized, look out for bugs jsr printstring rts ; NodeProcedureDecl -1 ; *********** Defining procedure : RenderPlayScreen ; Procedure type : User-defined procedureRenderPlayScreen ; MoveTo optimization lda #$63 sta screenmemory lda #>$1e00 clc adc #$01 sta screenmemory+1 clc lda #<Play adc #$0 ldy #>Play sta print_text+0 sty print_text+1 ldx #$10 ; optimized, look out for bugs jsr printstring rts ; NodeProcedureDecl -1 ; *********** Defining procedure : ScreenClear ; Procedure type : User-defined procedureScreenClear ; Clear screen with offset lda #$20 ldx #$feScreenClear_clearloop15 dex sta $0000+$1e00,x sta $00fd+$1e00,x bne ScreenClear_clearloop15 ; // ^$1e00 - unexpanded screen location ; Clear screen with offset lda #$6 ldx #$feScreenClear_clearloop16 dex sta $0000+$9600,x sta $00fd+$9600,x bne ScreenClear_clearloop16 ; // ^$9600 - unexpanded colour location; //AUX_COLOR_AND_VOLUME := %00000010; ; Assigning memory location ; Assigning single variable : $900f lda #$18 ; Calling storevariable sta $900f ; Assigning single variable : screenmemory lda #$00 ldx #$1e sta screenmemory stx screenmemory+1 rtsblock1 ; // -------------------------------------------------------------------------------; // **** Main Loop ****; // ------------------------------------------------------------------------------- jsr ScreenClearMainProgram_while17 ; Binary clause Simplified: NOTEQUALS lda #$1 ; Compare with pure num / var optimization cmp #$0;keep beq MainProgram_elsedoneblock20MainProgram_ConditionalTrueBlock18: ;Main true block ;keep jsr callReadJoy1 ; Binary clause Simplified: NOTEQUALS ; 8 bit binop ; Add/sub where right value is constant number lda joy1 and #$10 ; end add / sub var with constant ; Compare with pure num / var optimization cmp #$0;keep beq MainProgram_elsedoneblock50MainProgram_ConditionalTrueBlock48: ;Main true block ;keep ; Assigning single variable : gameState inc gameState jsr ScreenClearMainProgram_elsedoneblock50 ; Binary clause Simplified: GREATEREQUAL lda gameState ; Compare with pure num / var optimization cmp #$3;keep bcc MainProgram_elsedoneblock56MainProgram_ConditionalTrueBlock54: ;Main true block ;keep ; Assigning single variable : gameState lda #$1 ; Calling storevariable sta gameStateMainProgram_elsedoneblock56 ; Binary clause Simplified: EQUALS lda gameState ; Compare with pure num / var optimization cmp #$1;keep bne MainProgram_elsedoneblock62MainProgram_ConditionalTrueBlock60: ;Main true block ;keep jsr RenderTitleScreenMainProgram_elsedoneblock62 ; Binary clause Simplified: EQUALS lda gameState ; Compare with pure num / var optimization cmp #$2;keep bne MainProgram_elsedoneblock68MainProgram_ConditionalTrueBlock66: ;Main true block ;keep jsr RenderPlayScreenMainProgram_elsedoneblock68 jmp MainProgram_while17MainProgram_elsedoneblock20 ; End of program ; Ending memory blockEndBlock1010
I've been tinkering with this a fair bit this week, trying to get my head around Pascal, because this is definitely the way forward to creating proper 100% machine code games on the Vic 20 for me.
program SpaceSplat;// *** Vic 20 unexpanded game ***var // Strings Title : cstring = ("Space Splat"); Author : cstring = ("by Tony Brice,2021"); Player : cstring = ("(-O-)"); // Integers Score : integer = 0; // Player score // Bytes Lives : byte = 3; // Player lives Level : byte = 1; // Difficulty level Timer : byte = 100; // Used with level to adjust game speed playerX : byte = 10; // Players X position on fixed Y line gameState: byte = 1; // 1 = title, 2 = game, 3 = game over playerFired : byte = 0; // Has player fired // -------------------------------------------------------------------------------// **** Procedures ****// -------------------------------------------------------------------------------procedure RenderTitleScreen();begin // Display Title Screen moveto(5,4,hi(screen_char_loc)); PrintString( #Title, 0, 12 ); moveto(2,7,hi(screen_char_loc)); PrintString( #Author, 0, 18 ); moveto(0,12,hi(screen_char_loc)); PrintString( "FIRE TO START THE GAME", 0, 22 );end;procedure HUD();begin // Display Hud Information moveto(0,0,hi(screen_char_loc)); printString( "SCORE-", 0, 6 ); moveto(6,0,hi(screen_char_loc)); printdecimal(Score,4); moveto(15,0,hi(screen_char_loc)); printString( "LIVES-", 0, 6 ); moveto(21,0,hi(screen_char_loc)); printdecimal(Lives,0); moveto(0,1,hi(screen_char_loc)); printString( "PRESS UP TO QUIT GAME!", 0, 22);end;procedure BeginGame();begin // Set up a new game Score:= 0; Lives:= 3;end;procedure Delay();var i:byte = 0;begin // Pause to slow game down (if it worked...) for i:=0 to Timer do wait(50);end;procedure PlayScreen();begin // Gameplay stuff HUD(); // Show player ship moveto(playerX,3,hi(screen_char_loc)); PrintString(#Player, 0, 5); // Controls readjoy1(); if (joy1 & JOY_LEFT) then begin if (playerX > 0) then begin playerX := playerX - 1; moveto(playerX+5,3,hi(screen_char_loc)); printString(" ",0,1); end; end; if (joy1 & JOY_RIGHT) then begin if (playerX < 17) then begin playerX := playerX + 1; moveto(playerX-1,3,hi(screen_char_loc)); printString(" ",0,1); end; end; Delay();end;procedure RenderGameOverScreen();begin // Display Game Over moveto(2,11,hi(screen_char_loc)); printString( "G A M E -- O V E R",0,18);end;procedure ScreenClear();begin // Clear screen ClearScreen( 32, #SCREEN_CHAR_LOC); // ^$1e00 - unexpanded screen location ClearScreen( BLUE, #SCREEN_COL_LOC); // ^$9600 - unexpanded colour location //AUX_COLOR_AND_VOLUME := %00000010; SCREEN_BG_COLOR := BLACK + SCREEN_BG_WHITE; screenmemory := #SCREEN_CHAR_LOC;end;// -------------------------------------------------------------------------------// **** Main Loop ****// -------------------------------------------------------------------------------begin ScreenClear(); while (true) do begin readjoy1(); if (joy1pressed & JOY_UP) then begin if (gameState = 2) then begin ScreenClear(); gameState := 3; end; end; if ( joy1pressed & JOY_FIRE ) then begin if (gameState = 1) then begin ScreenClear(); gameState := 2; // Reset the score and lives on a new game BeginGame(); end; if ( gameState=2) then begin if (joy1pressed & JOY_FIRE) then begin // fire weapon end; end; if (gameState=3) then begin ScreenClear(); gameState := 1; end; end; if (gameState=1) then RenderTitleScreen(); if (gameState=2) then PlayScreen(); if (gameState=3) then RenderGameOverScreen(); end;end.
Imho Pascal is the superior language to C++
I threw the author £30 in Norwegian Krone so he could buy some beer for his efforts and it turns out that will just about buy 6 cans in his local supermarket.