[{"data":1,"prerenderedAt":256},["ShallowReactive",2],{"learn:invaders:01-blank-loop":3},{"item":4,"marksAgainst":255},{"slug":5,"number":6,"title":7,"idea":8,"models":9,"body":11,"tryIt":225,"game":244,"cites":245,"program":254},"01-blank-loop",1,"A blank screen and a game loop that does nothing yet","a cleared screen and a game loop, a turn with a counted wait, round for ever",[10,6],3,[12,18,22,26,42,45,62,65,85,89,92,96,98,102,105,116,119,141,143,176,188,215,218],{"kind":13,"inlines":14},"p",[15],{"kind":16,"text":17},"text","Over these chapters you build a game in the spirit of Space Invaders, from a blank page to rows of invaders that march, descend and drop bombs on a base that moves and fires back. Each chapter's program is the last one with a few lines added or changed, and each one runs.",{"kind":13,"inlines":19},[20],{"kind":16,"text":21},"This first one has nothing to see. It clears the screen and starts the game loop, the frame everything else hangs on, and the loop does nothing yet but wait and go round again.",{"kind":23,"id":24,"text":25},"h2","what-changed","What changed",{"kind":13,"inlines":27},[28,30,33,35,36,38,40],{"kind":16,"text":29},"Everything: chapter 1 starts from a blank page, so every line of its program is new, and the editor marks each one with a ",{"kind":31,"text":32},"strong","+",{"kind":16,"text":34}," in the margin and a green band. From chapter 2 on, the marks show only what that chapter changes: ",{"kind":31,"text":32},{"kind":16,"text":37}," for a new line, ",{"kind":31,"text":39},"~",{"kind":16,"text":41}," for a changed one, and a line taken out is listed under the editor, struck through, with the line it stood before. Edit the program and the marks step aside, since they describe the chapter's own text; Reset to the lesson brings them back.",{"kind":23,"id":43,"text":44},"a-blank-screen","A blank screen",{"kind":13,"inlines":46},[47,49,52,54,56,58,60],{"kind":16,"text":48},"The screen is memory: the 1,024 bytes from ",{"kind":50,"text":51},"code","3C00H",{"kind":16,"text":53}," to ",{"kind":50,"text":55},"3FFFH",{"kind":16,"text":57}," are its 16 rows of 64 cells, one byte a cell, top left first. A game owns the whole screen, so it starts by clearing it, storing a space, ",{"kind":50,"text":59},"20H",{"kind":16,"text":61},", in every cell:",{"kind":50,"lang":63,"text":64},"z80","START:  LD      HL,3C00H        ; HL points at the top-left cell\n        LD      BC,400H         ; BC counts the cells: 400H is 1024\nCLEAR:  LD      (HL),20H        ; a space: the cell is blank\n        INC     HL              ; on to the next cell\n        DEC     BC              ; one cell fewer to go\n        LD      A,B             ; copy B into A\n        OR      C               ; and OR in C: zero only when B and C both are\n        JR      NZ,CLEAR        ; not zero yet: clear the next cell",{"kind":13,"inlines":66},[67,69,71,73,75,77,79,81,83],{"kind":16,"text":68},"If you did the lessons, this is lesson 1's fill with a space in place of the white block. ",{"kind":50,"text":70},"DEC BC",{"kind":16,"text":72}," changes no flags, so ",{"kind":50,"text":74},"LD A,B",{"kind":16,"text":76}," and ",{"kind":50,"text":78},"OR C",{"kind":16,"text":80}," make the zero flag that ",{"kind":50,"text":82},"JR NZ",{"kind":16,"text":84}," reads: zero only when both halves of BC are.",{"kind":13,"inlines":86},[87],{"kind":16,"text":88},"On Fugløy you will see no change when it runs, because Fugløy's stand-in ROM fills the screen with spaces before it starts a program. The game clears it anyway, so that it never depends on what was there before.",{"kind":23,"id":90,"text":91},"the-game-loop","The game loop",{"kind":13,"inlines":93},[94],{"kind":16,"text":95},"A game is a loop. Each turn it reads the keys, moves what moves, draws it, and waits a moment, so that the game runs at the same speed whatever the turn did; then it goes round again, until the game is over. This chapter's turn is only the wait:",{"kind":50,"lang":63,"text":97},"LOOP:   CALL    WAIT            ; the turn's pause, so the game runs at a steady speed\n        JR      LOOP            ; and round again, for ever",{"kind":13,"inlines":99},[100],{"kind":16,"text":101},"In JavaScript, a game loop is the same shape:",{"kind":50,"lang":103,"text":104},"js","while (true) {\n  \u002F\u002F read the keys, move things, draw them: nothing yet\n  wait();\n}",{"kind":13,"inlines":106},[107,109,111,112,114],{"kind":16,"text":108},"The game grows inside this loop. The next chapter draws the base on the bottom row before the loop starts; after that, each chapter gives the turn a little more to do between ",{"kind":50,"text":110},"LOOP",{"kind":16,"text":76},{"kind":50,"text":113},"JR LOOP",{"kind":16,"text":115},": moving the base, firing a shot, and then the invaders.",{"kind":23,"id":117,"text":118},"wait-a-delay-you-can-count","WAIT, a delay you can count",{"kind":13,"inlines":120},[121,123,125,126,128,129,131,132,134,135,137,139],{"kind":50,"text":122},"WAIT",{"kind":16,"text":124}," is lesson 5's delay, a counted loop with nothing in it. Each instruction takes a known number of T-states, clock cycles: ",{"kind":50,"text":70},{"kind":16,"text":127}," 6, ",{"kind":50,"text":74},{"kind":16,"text":130}," 4, ",{"kind":50,"text":78},{"kind":16,"text":133}," 4, and ",{"kind":50,"text":82},{"kind":16,"text":136}," 12 when it jumps, 7 when it falls through. That is 26 a pass, and BC counts 5,120 passes, ",{"kind":50,"text":138},"1400H",{"kind":16,"text":140},":",{"kind":50,"lang":63,"text":142},"WAIT:   PUSH    BC              ; save BC, which the loop uses\n        LD      BC,1400H        ; 1400H is 5,120 passes of 26 T-states\nDELAY:  DEC     BC\n        LD      A,B\n        OR      C\n        JR      NZ,DELAY\n        POP     BC              ; BC as the caller left it\n        RET",{"kind":13,"inlines":144},[145,147,148,150,152,154,156,158,160,162,164,165,167,169,170,172,174],{"kind":16,"text":146},"The passes take 133,115 T-states, 5 fewer than 5,120 times 26 because the last ",{"kind":50,"text":82},{"kind":16,"text":149}," falls through. With ",{"kind":50,"text":151},"CALL WAIT",{"kind":16,"text":153}," (17), ",{"kind":50,"text":155},"PUSH BC",{"kind":16,"text":157}," (11), ",{"kind":50,"text":159},"LD BC,1400H",{"kind":16,"text":161}," (10), ",{"kind":50,"text":163},"POP BC",{"kind":16,"text":161},{"kind":50,"text":166},"RET",{"kind":16,"text":168}," (10) and ",{"kind":50,"text":113},{"kind":16,"text":171}," (12), a whole turn is 133,185 T-states. Fugløy runs the Model III's Z80 at 2.03 MHz (2,027,520 a second), so a turn lasts about 66 ms, and the loop goes round about 15 times a second. The T-states come from Fugløy's own decoding table, ",{"kind":50,"text":173},"packages\u002Fz80\u002Fsrc\u002Ftables.ts",{"kind":16,"text":175},".",{"kind":13,"inlines":177},[178,179,181,183,184,186],{"kind":50,"text":122},{"kind":16,"text":180}," keeps BC with ",{"kind":50,"text":182},"PUSH",{"kind":16,"text":76},{"kind":50,"text":185},"POP",{"kind":16,"text":187},", so that whatever later chapters keep in B and C survives the wait. Nothing does yet.",{"kind":13,"inlines":189},[190,192,193,195,197,199,201,203,204,206,207,209,210,212,213],{"kind":16,"text":191},"In the program, ",{"kind":50,"text":122},{"kind":16,"text":194}," comes first, above ",{"kind":50,"text":196},"START",{"kind":16,"text":198},". A routine can sit anywhere the processor never falls into it from the line before: ",{"kind":50,"text":200},"END START",{"kind":16,"text":202}," makes ",{"kind":50,"text":196},{"kind":16,"text":205}," the program's entry, the address its .CMD file tells the TRS-80 to start at, so the processor begins below ",{"kind":50,"text":122},{"kind":16,"text":208}," and reaches it only by ",{"kind":50,"text":151},{"kind":16,"text":211},". This program keeps its routines above ",{"kind":50,"text":196},{"kind":16,"text":214}," and the game itself below it.",{"kind":23,"id":216,"text":217},"on-the-model-i","On the Model I",{"kind":13,"inlines":219},[220,222,223],{"kind":16,"text":221},"The Model I's screen is the same memory at ",{"kind":50,"text":51},{"kind":16,"text":224},", the same 16 rows of 64, so the program runs on it unchanged. Fugløy runs its Z80 at 1.77 MHz, so a turn lasts about 75 ms there and the loop goes round about 13 times a second.",[226,237],{"kind":13,"inlines":227},[228,230,232,233,235],{"kind":16,"text":229},"Change ",{"kind":50,"text":231},"LD (HL),20H",{"kind":16,"text":53},{"kind":50,"text":234},"LD (HL),2EH",{"kind":16,"text":236}," and press Run ▶. 2EH is the full stop, and the screen fills with them: now you can see the clear happen.",{"kind":13,"inlines":238},[239,241,242],{"kind":16,"text":240},"Then put it back, click the left edge of the ",{"kind":50,"text":113},{"kind":16,"text":243}," line for a breakpoint, and press Run ▶ again. The program pauses there at the end of every turn; press Continue and it goes round once more, about 66 ms of waiting each time, and pauses again.",null,[246,250],{"source":247,"page":248,"about":249},"m3-trm","14","the Model III's screen is video memory at 3C00H, 1,024 bytes",{"source":251,"page":252,"about":253},"m1-trh","12","the Model I's screen is video memory at 3C00H, 16 lines of 64 characters","; Build Space Invaders, chapter 1: a blank screen and a game loop that does\n; nothing yet. The program clears the screen, all 1,024 cells of video memory\n; at 3C00H-3FFFH, to spaces, then goes round its game loop for ever: each turn\n; waits a counted 66 ms and goes round again. The chapters that follow give\n; the loop its work, one piece at a time, until it is a game.\n\n        ORG     7000H           ; the program lives at 7000H, in free memory\n\n; WAIT: a counted delay, 5,120 passes of 26 T-states, about 66 ms a turn at\n; 2.03 MHz. The routines come first, and the game itself after them, from\n; START, where END START says the program begins.\nWAIT:   PUSH    BC              ; save BC, which the loop uses\n        LD      BC,1400H        ; 1400H is 5,120 passes of 26 T-states\nDELAY:  DEC     BC\n        LD      A,B\n        OR      C\n        JR      NZ,DELAY\n        POP     BC              ; BC as the caller left it\n        RET\n\nSTART:  LD      HL,3C00H        ; HL points at the top-left cell\n        LD      BC,400H         ; BC counts the cells: 400H is 1024\nCLEAR:  LD      (HL),20H        ; a space: the cell is blank\n        INC     HL              ; on to the next cell\n        DEC     BC              ; one cell fewer to go (DEC BC sets no flags ...)\n        LD      A,B             ; ... so test BC by hand: copy B into A\n        OR      C               ; and OR in C: zero only when B and C both are\n        JR      NZ,CLEAR        ; not zero yet: clear the next cell\n\n; The game loop: one turn of the game, then round again. A game's turn\n; reads the keys, moves things and draws them; this one only waits.\nLOOP:   CALL    WAIT            ; the turn's pause, so the game runs at a steady speed\n        JR      LOOP            ; and round again, for ever\n\n        END     START           ; the program starts at START\n","",1792464470931]