From fa4d831959cc65cb351b2aca7c38fb2cc2292f9e Mon Sep 17 00:00:00 2001 From: Jeremy Herbert Date: Mon, 10 Jan 2011 23:16:44 +1000 Subject: [PATCH] Added random number generator via a modified LFSR --- map | 72 ++++++++++++++++++++++++++++-------------------------- snake.asm | 61 ++++++++++++++++++++++++++++++++++++++++++--- snake.gb | Bin 32768 -> 32768 bytes 3 files changed, 95 insertions(+), 38 deletions(-) diff --git a/map b/map index 3404088..5d6a6d1 100644 --- a/map +++ b/map @@ -4,53 +4,55 @@ Bank #0 (HOME): SECTION: $0050-$0052 ($0003 bytes) SECTION: $0058-$0058 ($0001 bytes) SECTION: $0060-$0060 ($0001 bytes) - SECTION: $0100-$0D36 ($0C37 bytes) - $0A89 = timer_interrupt + SECTION: $0100-$0D66 ($0C67 bytes) + $0AB9 = timer_interrupt $0952 = init - $0D1E = setup_dma - $0CFD = stoplcd + $0D4E = setup_dma + $0D2D = stoplcd $0150 = TileData - $0C61 = clear_bg - $0C73 = splash_text - $0CF3 = splash_text_end - $0C0E = draw_snake - $0AA4 = read_joypad - $0B23 = move_snake - $0A16 = main - $0B10 = draw_gameover - $0A80 = subtract_16bit - $0AA2 = timer_interrupt_end - $0ACB = read_joypad_up_return - $0ABD = read_joypad_right_return - $0AD2 = read_joypad_down_return - $0AC4 = read_joypad_left_return - $0CF3 = gameover_text - $0CFD = gameover_text_end - $0C07 = move_snake_die - $0B73 = move_snake_write - $0B86 = move_snake_continue - $0A3B = tail_collision_scan - $0C0C = move_snake_end - $0BD6 = move_snake_cut_tail_continue - $0C51 = convert_xy_to_screen_addr - $0C32 = draw_snake_continue - $0D0E = multiply_to_hl - $0D2B = dma_copy - $0D37 = dma_copy_end + $0C91 = clear_bg + $0CA3 = splash_text + $0D23 = splash_text_end + $0C3E = draw_snake + $0A47 = lfsr_generate + $0AD4 = read_joypad + $0B53 = move_snake + $0A1F = main + $0B40 = draw_gameover + $0AB0 = subtract_16bit + $0AD2 = timer_interrupt_end + $0AFB = read_joypad_up_return + $0AED = read_joypad_right_return + $0B02 = read_joypad_down_return + $0AF4 = read_joypad_left_return + $0D23 = gameover_text + $0D2D = gameover_text_end + $0C37 = move_snake_die + $0BA3 = move_snake_write + $0BB6 = move_snake_continue + $0A6B = tail_collision_scan + $0C3C = move_snake_end + $0C06 = move_snake_cut_tail_continue + $0C81 = convert_xy_to_screen_addr + $0C62 = draw_snake_continue + $0D3E = multiply_to_hl + $0D5B = dma_copy + $0D67 = dma_copy_end SECTION: $0061-$00B6 ($0056 bytes) $007B = mem_CopyMono $0061 = mem_Set $00A1 = mem_CopyVRAM $008B = mem_SetVRAM $006D = mem_Copy - SLACK: $336A bytes + SLACK: $333A bytes BSS: - SECTION: $C000-$C179 ($017A bytes) + SECTION: $C000-$C17A ($017B bytes) $C000 = variables_start - $C17A = variables_end + $C17B = variables_end $C0A3 = SnakePieces $C16B = SnakePiecesEnd + $C175 = LFSRSeed $C0A0 = GameState $C16D = SnakeTail $C16B = SnakeHead @@ -60,7 +62,7 @@ BSS: $C174 = TimerTicks $C16F = SnakeDirection $C170 = SnakeNextDirection - SLACK: $1E86 bytes + SLACK: $1E85 bytes VRAM: EMPTY diff --git a/snake.asm b/snake.asm index 2c3ceb5..b67a0e7 100644 --- a/snake.asm +++ b/snake.asm @@ -47,6 +47,8 @@ NumberOfFoods: ds 1 ; number of food objects that exist (as sprites) TimerTicks: ds 1 ; count the number of ticks in the timer (to slow down the movement speed) +LFSRSeed: ds 1 ; seed value for our lfsr + DEBUG_BLANK_DONT_TOUCH: ds 5 ; this gets allocated to zeroes, makes it easier to see our ram block in the debugger variables_end: @@ -146,6 +148,11 @@ init_variables: ; this code displays the splash screen splash: + + ; turn on the timer, we need to use its value for our LFSR seed + ld a, TACF_START | TACF_262KHZ ; make it super fast to stop people gaming it + ld [rTAC], a + ; we are going to copy across the background tiles from the splash_text label ; using: mem_copyVRAM (hl->pSource, de->pDest, bc->byte count) ld hl, splash_text @@ -169,6 +176,10 @@ splash_wait_for_press: cp 1 jr z, splash_wait_for_press ; if the a key has not been pressed, the instruction above will set the zero flag and we will jump back + ; save our LFSR seed + ld a, [rTIMA] ; counter value into a + ld [LFSRSeed], a ; save it! + ;------------------------------------------------------------------------ ; ok, time to play the game! @@ -218,15 +229,16 @@ init_snake: ld a, 8 ; piece 2, y ld [hl+], a + ; draw our initial snake + call draw_snake + ; now we start the timer interrupts (ll. 828-852) + ; start the timer, we need this for our LIFR ld a, TACF_START | TACF_4KHZ ; turn on, set to 4khz (timer will interrupt every [255 * 1/4000] = 63.75ms) ld [rTAC], a ld a, IEF_VBLANK | IEF_TIMER | IEF_HILO ; enable vblank, timer, joypad interrupts ld [rIE], a ; save the register - - ; draw our initial snake - call draw_snake ;;;;;;;;;;;;;;;;;; DEBUG (make the snake grow by default) ld a, 10 @@ -239,6 +251,8 @@ main: ; nop ; a bug in the cpu means that the instruction after a halt might get skipped ei + call lfsr_generate ; so we get nice random numbers + ld a, [GameState] cp 2 ; does GameState == 2? (the gameover state) jr z, gameover ; show a nice message @@ -265,6 +279,47 @@ gameover: ; jr main ;------------------------------------------------------------------------ +;--------------- +; lfsr_generate +; generate a random number and put it in LFSRSeed +; see http://en.wikipedia.org/wiki/Linear_feedback_shift_register for info on how this works +; uses taps at 8, 6, 5, 4 +;--------------- +lfsr_generate: + ld a, [LFSRSeed] ; load up the seed + ld e, a ; e will store our seed value + +lfsr_generate_loop: + ld d, a + + rr d ; roll four times + rr d + rr d + rr d + xor d ; xor it + + rr d ; five rolls in total + xor d + + rr d ; up to 6 rolls + xor d ; xor it in + + rr d + rr d ; 8 rolls, this is our fourth and last tap + xor d + + ; not really sure if secure crypto allows me to do this, but frankly if you would like to game my system then go for it + ld b, a + ld a, [rDIV] ; source of some more random + xor b ; add it in + + cp e + jr z, lfsr_generate_loop ; make sure it is different + + ; save it + ld [LFSRSeed], a + + ret ;--------------- ; tail_collision_scan diff --git a/snake.gb b/snake.gb index e7238c6bdc1d61766754827314c5a76dea224f77..1ab6200136ac499e351186c2c95e413087f8c7b2 100644 GIT binary patch delta 451 zcmZo@U}|V!VxOWW&Y-{`KJlRCLFh{wpp%z<7cI#AJQIuDE#eLQYxs53H|B z51ySk`2eR|%vn1gJC+CRcA^jd+i|@rJox*pJJ+uT2mUc>h@ZW}^{eRMc8xc746lj~ zo(<*(sy!^vb=H9!Nd7847$1IG3IbQ1mVzK4?f!vf#cqu!KpRd@w&s##+%P$m%aQTY z>(i@>%Dj`s zxUCG$c@8h;7ODCtath3nss1MfVTo4#`ww9~y(*Y}@azVziv}zY4{w{?$ZZ;s&2`v@ z=j*TBgZaPm4yJ#63Q+)(XXAMY44JxcyZ=gc@j&A1)u*u`in#}?m8z5;Ui^4A8yX10 zXB&C!6c`y9&UP~#wwcVvqad<@3uHhN*Z{3?t@x)$&o)lB;*n;wn;gb-k}-O-0`G<* E03%SvdjJ3c delta 430 zcmZo@U}|V!VxOX>zyO334_Z!i5M=C}81#p!`{m{UMph0nIbOs6|LvYUaDU+Oz|)T5 zf%5~WvwwLeXLHI}Ci2)ZC^8&itYSQy$YA$haq$7h6AVD6Vlj{4ffCb_v(7 zqJ!Ht-rF&}Dmr*pnH#9!uo%}_0d62UIh#w8v0-v6mm}k%$;Y|8Oiy$D%0KvzS>v)D zr7>m_Xc1U@oJ^9y?|b_XyY5r&kp}^GtT*wlZYrIb6&wQuR;d6qqGb z{Z9zO60Q38AHsTiRWSSD*#@qQ1}qN`w@u#2Z5m+Bb(n|e>#y8{`M>fGrhj}2Q2>&^ z#{Cc&0(Ieb|CQ?EfyCFVPh&$Aa}QQ4RVh8Z`0=bY7sP|YX9Icc6c`y9&UP~#=9z59 sqaf121v0>h2V{U&xK{krqh|vrXYoig@=b2zImxKKIe>RV(ZmY|0Kdezb^rhX