| Usagyuuun Kniffel | Title: | Usagyuuun Kniffel | Category: | Game/Dices | Release Date: | 2023-02-23 | Language: | English/German/Spanish | Size: | 64K | Device Req.: | Disk only (1 side) | Machine: | PAL & NTSC | Code Type: | Basic + Machine code | Distribution: | Freeware | | | Created by: | Sirhadisen | Notes: | AKA Usagikniffel. A multiplayer dice game for everyone who likes BASIC, machine code, and rabbits! |
User Rating: 7.3/10 (3 votes) User comments: Read comments
|
|
|
| |
| Description | --------------------------------- *** USAGIKNIFFEL *** FAN-GAME BY SIRHADISEN 23.02.2023 (YEAR OF THE BUNNY) SEINEM KOMISCHEN TIER GEWIDMET INSPIRED BY QUAN INC. USING TEDZAKKER 1.1 BY HERMIT ASSEMBLERCODE RANGES: $0333-03F2 IRQ EXT. ACCESS STUBS $A4FF-B431 ANIMATIONS & MUSIC ---------------------------------
How to run the game ------------------- 1. Get a commodore emulator 2. Mount the disk image 3. Load the loader by typing DLOAD "LOADER" + Enter 4. Type RUN + Enter (this takes a while because it keeps the interactive mode intact) 5. Choose language, number of players, and player names of at least 2 characters each 6. Pick the dices you want to re-roll by pressing their numbers (1-5) and confirm with enter 7. After last roll, pick an unused combination from the scoreboard with arrow up/down and confirm with enter.
The top10 sequence file can be deleted to start over with an empty hall of fame. Good luck and have fun!
Here for the coders ------------------- Beware of the run/stop button that ends the program and enters the interactive BASIC 3.5 mode. So do not press it accidentally or it will break your lucky streak ;) It was left enabled intentionally, because interrupting the game allows you to play around with the effect assembler routines, or check out and customize the commented BASIC code. Since the player variables are currently not persisted in memory, however, you won't be able to continue the game where you left it. This would be an extension worth considering.
Some commented-out GOSUB 10000 statements were left in the code. Removing the REM in front of them makes it possible to start the program in that line, which can be used to test the post-game subroutines with fake player scores.
Note that the code is self-changing at some locations, such as the STA statements during music initialization at $A96F and $A9B1 that toggle $ABF7 between RTS and JMP. This seems to cause issues if the music routine is saved in a state after having executed the initialization, probably because of misplaced RTS returns inside the IRQ-extension.
Happy retro-coding my fellow Gyuuuns!
Planned for the next release ---------------------------- - Music for the award ceremony (I tend to "Es gibt Reis" by Helge Schneider) - Balancing of speed control between animations and music - Let user pick color themes on the start screen that affect the entire game - More easter eggs
Credits ------- - Programmed in the emulator plus4emu 1.2.9.1 by Istvan Varga - Theme inspired by Quan Inc.'s cuddlesome Usagyuuun - Music is an 8-bit cover of Oh!YOU's splendid song - To generate and play the song I use the TEDzakker 1.1 by Hermit (SIDRIP) - To keep track of the code I used a Notepad in Windows (yes, I cheated)
It all began with an 8bit carrot. --------------------------------- o o oooo ooo oooo oooo ooo ooo o --------------------------------- |
| |
| Program Analysis | Name_of_Variable;Definition A$;Temporary key AA;Temporary key number/rank number AR$;Active assembly routine AS;Decimal-coded occurrence of faces in a dice roll AUGE;Face integer cache AUGE$;Face character cache AVA;Avatar index per player BF$;Pattern flag cache BW;Language index or pattern index - 1 BS;Counter of distinguishable faces in a dice roll C$;Temporary string with character-coded colors C0;Score board first column number - 1 C1;Rain start column index for 1st place C2;Rain start column index for 2nd place CC;Continuation character number CC$;Character-string for faces 1-6 CO$;Reference character (temporary) CS;Carrot speed increment CT;Color theme index CV;Temporary color cache FLAGS$;Flags locked patterns per player JA$;Language-specific character for choice "yes" HI;Temporary High-Byte L;Temporary lenth of a string LO:Temporary Low-Byte MC;Direction of cursor in menue MN;Size of largest face multiplet NV$;Temporary array for vertical names (awards ceremony) OSET;Offset of rows for printing of dice result P;Page index of the custom character set PALL;Accumulators for total score per player PBM;Score per pattern & player PT;Temporary cache for score Q$;Quotation marks R;Round index R0;Index of 1st row for printing avatars R1;Scoretafel 1.Zeile RANKS;For sorting of player scores RC$;String cache RK$;String cache RS$;Speech bubble graphic S;Player index S1;Temporary total score 1 S2;Temporary total score 2 SA;Number of players SC;Temporary score of current round SF$;Array with character colors of player names SNAME$;Array of player names SO;Sum for 1s to 6s SP;Usagyuuun response index TS;Array cache of top 10 scores TN$;Array cache of top 10 names US$;Usagyuuun responses UU$;Usagyuuun PETSCII graphic V;Counter of current roll WCN;Counter per face in current roll WDH;Numeric flags for dices chosen to be rerolled WE;Index of a dice that was chosen to be rerolled WI;Like WE WURF$;Character cache of current roll X;Temporary variable for various things
23.02.2023
Organisation of the Assembly Routines ------------------------------------- For parallel utilization of interruptable BASIC 3.5 and assembly codes in the bank-switching-RAM region of the Commodore Plus/4, the game is stored in three separate memory regions: 1) Toggle and access-stubs within the tape buffer (pure RAM from $0333-$03F2) enable flexible activation/deactivation of IRQ-extension from the interactive BASIC mode (using SYS statements); note that this code is wiped by a soft reset. 2) Interruptable BASIC 3.5 program (starting at $1000); note that this code is wiped by a soft reset. 3) Initialization routines, animations, and musik (incl. player) are saved in the bank-switching-RAM region from $A4FF-$B431; note that in order to view&edit the assembly code in this region from the MONITOR, one has to switch $07F8 "MSB for monitor fetches from ROM=0;RAM=1", e.g. with the statement POKE 2040, 128. This code remains in memory after a soft reset.
*** 1) Routines in the tape buffer *** $0333-$0355 General bank-switching-independent initialization and toggle of the IRQ RAM vector between $CE0E and $0357 $0357-$037D Universal RAM-access stub, which IRQ detour address (JSR $#### statement) must have been set in advance $037F-$039F Start screen-specific initialization (music, color circle addresses, IRQ-detour address & -toggle) $03A1-$03BE Player name query-specific initialization (color box addresses, IRQ-detour address & -toggle) $03C0-$03CF Award ceremony-specific initialization (IRQ-detour address & -toggle) $03D1-$03D6 Unspecific initialization (just toggling the IRQ-detour, which address must have been set in advance)
*** 2) Routines in the bank-switching-RAM *** $A4FF-$A518 Start screen: IRQ main $A519-$A563 Rain routine: Create new drops $A564-$A5DA Rain routine: Move & eliminate drops $A5DB-$A619 Color circle: Change colors within periodic region boundaries $A61A-$A69F Color circle: Persistent storage of circle addresses as (Low-Byte, High-Byte)-pairs $A6A0-$A6AE Player name query: IRQ main $A6B0-$A6E4 Award ceremony: IRQ main $A6E8-$A6F2 Rain routine: Memorize symbol and color attribute of drop X $A6F4-$A6FE Rain routine: Retrieve symbol and color attribute of drop X and cache in $DF and $E4 $A700-$A70D Simple pseudo-random number generator $A70F-$A737 Start screen: Oscillating brightness of Usagyuuun lettering $A73C-$A755 Set all TED color attributes to grey $A757-$A765 Kniffel interlude: IRQ main $A767-$A78F Kniffel interlude: Color flickering of Kniffel lettering $A794-$A79A Hall of fame: IRQ main $A79C-$A7DC Hall of fame: Color flickering of top 10 score board $A7DE-$A7EB Start screen: Initialize addresses that define the color circle $A7ED-$A7FA Player name query: Initialize addresses that define the box frame
Reserved memory and required initialization of values before IRQ-toggles ------------------------------------------------------------------------ Some parameters of the animations are initialized/modified from BASIC with POKE statements, some are initialized by other assembly routines. Usagyuuun deserves some chaos after all.
1) Start screen General: $D3 reserved for slowing counter of animation routines $D6-$D7 reserved for indirectly indexed addressing by the music routine $DD reserved for slowing counter of the music routine
Rain routine (sorry, no sprites for the Plus4!): $D8-$D9 reserved for indirectly indexed addressing of TED attributes $DA-$DB reserved for indirectly indexed addressing of TED characters $DC max. number of drops >0 and <16 (z.B. 6) - do not change while routine is running! $DE reset value of the slowing counter; must be >0 (uneven numbers like 7 seem to produce better RNG results) $DF symbol for new rain drops (e.g. the carrot uses #$66, the $ character can be set with poke 223, 36) $E0 random seed (z.B. 123) $E4 color attribute of rain drops (e.g. the carrot uses #$43, the $ character uses gold = #$48), also used as a switch which value #$00 indicates that the RAM-access stub is to be executed only once $E6 Byte-frame for "double width - 1" of the region in which rain drops fall (e.g. #$1F for start screen, #$0F for avatars in the award ceremony) $E7-$E8 Low byte, high byte of the origin position of the region in which rain drops fall (e.g. #$73, #$0D) $0662-$0671 cache for low-bytes of positions of rain drops = TED-address ("Charpointer") $0672-$0681 cache for high-bytes of positions of rain drops = TED-address ("Charpointer") $0682-$0691 cache for chars to be restored behind rain drops as they move $0692-$06A1 cache for attriutes of chars to be restored behind rain drops as they move $06A2-$06B1 cache for symbol per rain drop (they differ between 1st and 2nd place) $06B2-$06C1 cache for basis color per rain drop (drops change brightness as they fall)
Color circle / box frame: Y-register starts at #$00 $E1-$E2 reserved for holding addresses of color attributes accessed by indirectly indexed addressing ? Clarify: Should E1 E2 be used instead of D6 D7 for the music routine? $E3 has been set to default color (e.g. #$67 for start screen) $E4 has been set to basis color (lowest brightness) of the rotating stream in the color circle (e.g. #$50 for the start screen) $E5 reserved for double number of addresses that define the color circle $A61C-$A64F reserved for cache of rotating address bytes of the color circle
2) Player name query $DD reserved for slowing counter of the music routine $DE reset value of the slowing counter; must be >0 (uneven numbers like 7 seem to produce better RNG results) $E5 reserved for double number of addresses that define the color box
3) Kniffel interlude $DD reserved for slowing counter of the music routine $DE reset value of the slowing counter; must be >0 (uneven numbers like 7 seem to produce better RNG results) $036F-$0370 the jump address in the RAM-access stub needs to be set to $A757 from BASIC using POKE statements The attribute column ($0991, $09B9, $09E1, $0A09, $0A31) must hold colors greater 0 as a seed for the flickering
4) Award ceremony $DC max. number of drops >0 and <16 (e.g. 6) $DD reserved for slowing counter of the music routine $DE reset value of the slowing counter; must be >0 (uneven numbers like 7 seem to produce better RNG results) $E6 Byte-frame for "double width - 1" of the region in which rain drops fall (e.g. #$1F for start screen, #$0F for avatars in the award ceremony) $E7 low-bytes of the origin positions for 1st and 2nd place avatars have been POKEd directly into the IRQ main of the award ceremony: $A6C1 = 1st place $A6D2 = 2nd place $E8 high-byte of all origin positions is #$0C
5) Greying out the score board $D8-$D9 reserved for indirectly indexed addressing of TED attributes $E4 in this context used as a switch which value #$00 indicates that the RAM-access stub is to be executed only once
This is how to use the RAM-access stub for initiation of a single execution of an assembly routine from BASIC: 1. Let rain drops settle and do not create new ones: POKE 220, 0 - set number of drops to be falling to 0 FOR I=1 TO 400:NEXT - wait until remaining drops have fallen 2. Disable rain IRQ-main and prepare the RAM-access stub to be used for a single execution SYS 995 - disable IRQ-extension for rain POKE 228, 0 - set $E4 to #$00 to indicate that the stub won't be used for an IRQ-extension POKE 879, 60 - set low-byte of the start address of the one time routine to #$3C POKE 880, 167 - set high-byte of the start address of the one time routine to #$A7 SYS 870 - start routine that greys out all TED chars via RAM-access stub
6) Hall of Fame $D8-$D9 reserved for indirectly indexed addressing of TED attributes $DA-$DB reserved for indirectly indexed addressing of TED characters $036F-$0370 the jump address in the RAM-access stub needs to be set to $A794 from BASIC using POKE statements The attribute column ($094C, $0974, $099C, $09C4, $09EC) must hold colors greater 0 as a seed for the flickering
Assembler Code Listing ---------------------- *** 1) Routines in the tape buffer ***
--- $0333-$0355 General bank-switching-independent initialization and toggle of the IRQ RAM vector between $CE0E and $0357 .0333 LDA #$0E EOR #$57 EOR $0314 STA $0314 LDA #$CE EOR #$03 EOR $0315 STA $0315 -- Reset slowing counter LDA $DE STA $DD -- Set all high-bytes of the rain drop buffer between $0673-$0681 to #$00 to mark the corresponding drops as inactive (=not containing drop info) LDX #$0F LDA #$00 .034F STA $0672,X DEX BNE $034F RTS
--- $0357-$037D Universal RAM-access stub, which IRQ detour address (JSR $#### statement) must have been set in advance -- Decrement slowing counter and skip IRQ-extension if >0 .0357 DEC $DD BNE $037B LDA $02 - slow musik with constant countdowns from #$02 ?? This speed also applies to effects on screens other than the start screen. It would have to be derived from $DE to be dynamic, but there is not enough room at the moment... STA $DD -- Raster line synchronization for music (must happen outside the SEI CLI block!) .035F LDA #$10 - line #$10 seems to be a good balance for musik speed; should probably be derived from $DE with LSR .0361 CMP $FF1D BNE $0361 -- .0366 is the entry point for single execution of a code in the bank-switching-RAM .0366 SEI -- Bank-Switching: Memorize the "ROM select"-status by putting it on the stack before entering the IRQ-extension LDA $FF3E PHA STA $FF3F - set RAM_ON JSR $0000 - the detour address is set from other routines or POKE-Statements ($A4FF / $A6A0 / $A6B0 / ...) -- Bank-Switching: Restore the "ROM select"-status from the stack PLA STA $FF3E - set ROM_ON (as expected by BASIC) CLI -- If $E4 = #$00, do an RTS, as the stub only serves a single execution, otherwise resume with system-IRQ tasks at $CE0E LDA $E4 BNE $037B RTS .037B JMP $CE0E
--- $037F-$039F Start screen-specific initialization (music, color circle addresses, IRQ-detour address & -toggle) .037F SEI -- General initialization and toggle execution of the universal RAM-access stub as a general IRQ-extension JSR $0333 -- Bank-Switching: Memorize the "ROM select"-status by putting it on the stack before entering the IRQ-extension LDA $FF3E PHA STA $FF3F - set RAM_ON -- Music initialization ?? To be clarified with Hermit: Do we need another LDA #$00 here to avoid issues with saves of initialized code? JSR $A96A -- Copy circle addresses of the start screen from $A61A- to $A61C- JSR $A7DE -- Bank-Switching: Restore the "ROM select"-status from the stack PLA STA $FF3E - set ROM_ON - Set the detour address in the RAM-access stub to $A4FF LDA #$FF STA $036F LDA #$A4 STA $0370 CLI .039F RTS
--- $03A1-$03BE Player name query-specific initialization (color box addresses, IRQ-detour address & -toggle) .03A1 SEI -- General initialization and toggle execution of the universal RAM-access stub as a general IRQ-extension JSR $0333 -- Bank-Switching: Memorize the "ROM select"-status by putting it on the stack before entering the IRQ-extension LDA $FF3E PHA STA $FF3F - set RAM_ON - Copy box addresses of the frame around the player name query from $A670- to $A61C- JSR $A7ED -- Bank-Switching: Restore the "ROM select"-status from the stack PLA STA $FF3E - set ROM_ON - Set the detour address in the RAM-access stub to $A6A0 LDA #$A0 STA $036F LDA #$A6 STA $0370 CLI .03BE RTS
--- $03C0-$03CF Award ceremony-specific initialization (IRQ-detour address & -toggle) .03C0 SEI -- General initialization and toggle execution of the universal RAM-access stub as a general IRQ-extension JSR $0333 - Set the detour address in the RAM-access stub to $A6B0 LDA #$B0 STA $036F LDA #$A6 STA $0370 CLI .03CF RTS
--- $03D1-$03D6 Unspecific initialization (just toggling the IRQ-detour, which address must have been set in advance) .03D1 SEI -- General initialization and toggle execution of the universal RAM-access stub as a general IRQ-extension JSR $0333 CLI .03D6 RTS
*** 2) Routines in the bank-switching-RAM ***
--- $A4FF-$A518 Start screen: IRQ main -- Play one music frame each call .A4FF JSR $A9BF -- Apply slowing counter only to the animation routines DEC $D0 BNE $A563 LDA $DE STA $D0 LDY #$00 JSR $A519 JSR $A564 JSR $A5DB JSR $A710 .A518 RTS
--- $A519-$A563 Rain routine: Create new drops -- Loop over all drop indices (irrespective of whether they are active or not) .A519 LDX $DC CPX #$00 BEQ $A563 .A51F LDA $0672, X -- If drop X is already active, as indicated by a position high-byte <> #$00, skip drop creation for this index CMP #$00 BNE $A560 -- Otherwise generate pseudo-random number for a drop creation attempt and convert it to a column-offset between 0 and the double width of the rain region, whereby the 0-bit is used to decide, whether the drop shall be created JSR $A700 -- "Double width - 1" of the rain region is read from $E6 AND $E6 -- 0-bit is used to decide whether the creation is skipped LSR BCC $A560 -- Add the random 1-byte column-offset to the 2-byte origin (in $E7-E8) of the rain region and store the result as the starting position (=TED address) of the new rain drop CLC ADC $E7 STA $DA STA $0662, X STA $D8 LDA #$00 ADC $E8 STA $DB STA $0672, X SEC SBC #$04 STA $D9 -- Memorize the symbol that is overwritten at the starting position, as long as it is not that of a drop (from a previous iteration): -- Otherwise the drop must be eliminated again, as we cannot allow multidrops that would cause stripes by restoring prev-iteration-drops instead of the overwritten background LDA ($DA),Y CMP $DF BNE $A553 LDA #$00 STA $0672, X BEQ $A560 .A553 STA $0682, X -- Memorize attribute of the overwritten symbol LDA ($D8),Y STA $0692,X -- Memorize symbol and color attribute of drop X JSR $A6E8 NOP NOP .A560 DEX BNE $A51F RTS
--- $A564-$A5DA Rain routine: Move & eliminate drops -- Loop over all drop indices (not only the $DC existing drops, because then the code would crash when we set it to #$00 while it rains!) .A564 LDX #$10 .A566 LDA $0672, X -- Skip drops that are not active CMP #$00 BEQ $A5D7 -- Copy address bytes for indirectly indexed addressing of the TED char pointer in $DA-$DB and of the TED attribute pointer in $D8-$D9 (which has the same low-byte and the high-byte - #$04) LDA $0662, X STA $DA STA $D8 LDA $0672, X STA $DB SEC SBC #$04 STA $D9 -- Cache symbol of drop X in $DF and its color attribute in $E4 .A57E JSR $A6F4 ?? ToDo: This should only happen during the award ceremony, as it hinders changes of $E4 on the start screen ?? As a workaround, JSR is modified to LDA with POKE 42366,173 in order to skip the call of the routine at $A6F4, and then LDA is modified to JSR again with POKE 42366,32 NOP NOP -- Restore overwritten background symbol at the current drop position from the buffer, IF it is not a drop symbol (this prevents stripes in the case of adjacent drops) LDA $0682, X CMP $DF - compare to the symbol of the drop with index X BEQ $A5AF STA ($DA), Y -- Restore attribute of the background symbol from the buffer LDA $0692, X STA ($D8), Y -- Let drop fall one row by 2-byte addition of #$28 to the position address LDA $DA CLC ADC #$28 STA $DA STA $0662, X STA $D8 LDA $DB ADC #$00 STA $DB STA $0672, X SEC SBC #$04 STA $D9 -- Eliminate drop once it "hits the ground", meaning its high-byte reaches #$0C, or when it hits a drop symbol (= was one iteration faster than an adjacent drop in the same column) CMP #$0C BNE $A5B6 .A5AF LDA #$00 STA $0672, X BEQ $A5D7 -- Memorize symbol and color attribute of background at the new position of the drop.. .A5B6 LDA ($DA), Y STA $0682, X LDA ($D8),Y STA $0692,X -- ..and overwrite it with the drop symbol from $DF LDA $DF STA ($DA), Y -- Calculate dynamic color attribute of the drop (changing brightness) from its row/128 CLC LDA $DB SBC #$0E LSR ROR $DA LDA $DA LSR LSR AND #$F0 -- To change brightness add a multiple of #$10 to the symbol-specific (golden $ and silver *) basis color = n*$10+$E4 CLC ADC $E4 STA ($D8), Y .A5D7 DEX BNE $A566 RTS
--- $A5DB-$A619 Color circle: Change colors within periodic region boundaries -- "1" to "30" represent addresses of TED attributes in the region $0800-0BFF, which values change in a rotating manner: -- "1" = address of the low-byte of the attribute of the 1st point of the shape (circle or box) -- "2" = address of the high-byte of the attribute of the 1st point of the shape (circle or box) etc. -- The initial values for the definition of the circle and direction of the rotation have been initialized by $A7DE-$A7EB or $A7ED-$A7FA -- Initialize pointer to flexible number of addresses (=index of last address) that define the object .A5DB LDY $E5 -- Copy address of the last circle (or box) position directly in front of the list of addresses, and to $E1-$E2 for indirect addressing LDA $"1",Y STA $"1" STA $E1 LDA $"2",Y STA $"2" STA $E2 -- Restore default color at the address of the last point of the shape LDA $E3 LDY #$00 STA ($E1), Y LDY $E5 -- Move all addresses one position (=2 bytes) up in the shape .A5F5 LDA $"0", Y STA $"2", Y LDA $"-1", Y STA $"1", Y DEY DEY BNE $A5F5 -- For the 5th point of the shape apply an oscillating brigthness on the basis color LDA $"21" STA $E1 LDA $"22" STA $E2 -- Trail with an oscillating brightness: n*$10+$E4 LDA $00A5 AND #$30 CLC ADC $E4 STA ($E1), Y RTS
--- $A61A-$A69F Color circle: Persistent storage of circle addresses as (Low-Byte, High-Byte)-pairs -- Active circle addresses .A61A 00 - cache1 .A61B 00 - cache2 .A61C-A64F -- Definition of the TED-addresses of the color circle on the start screen .A650 CF 09 F9 09 4A 0A C3 0A 3A 0B 89 0B AF 0B A6 0B 7C 0B 2B 0B B2 0A 3B 0A EC 09 C6 09 -- Definition of the TED-addresses of the frame around the player name query .A670 7A 08 7E 08 82 08 86 08 8A 08 8E 08 92 08 96 08 9A 08 42 0B 3E 0B 3A 0B 36 0B 32 0B 2E 0B 2A 0B 26 0B 22 0B
--- $A6A0-$A6AE Player name query: IRQ main .A6A0 JSR $A5DB ?? Here I left some room for creativity: Calling another music routine, context-specific slowing counters and other fancy stuff 11* NOP .A6AE RTS
--- $A6B0-$A6E4 Award ceremony: IRQ main --- Let it rain golden dollar symbols for 1st place and silver stars for the 2nd place -- The high-bytes of all needed reference positions are #$0C .A6B0 LDA #$0C STA $E8 ?? 8 bytes are what one would need for a context-specific slowing counter 8* NOP - Initialize the low-byte of the reference position at $E7, the symbol at $DF, and the basis color at $E4 before each call to the rain drop generating routine LDA #$24 STA $DF LDA #$00 - to be initialized from BASIC: Byte for the Position of the avatar of the 1st place STA $E7 LDA #$48 STA $E4 LDY #$00 JSR $A519 LDA #$2A STA $DF LDA #$00 - to be initialized from BASIC: Byte for the Position of the avatar of the 2nd place STA $E7 LDA #$31 STA $E4 LDY #$00 JSR $A519 JSR $A564 ?? 3 bytes are what one would need for a JSR statement to anther music routine 3* NOP .A6E4 RTS
--- $A6E8-$A6F2 Rain routine: Memorize symbol and color attribute of drop X .A6E8 LDA $DF STA $06A2, X LDA $E4 STA $06B2, X .A6F2 RTS
--- $A6F4-$A6FE Rain routine: Retrieve symbol and color attribute of drop X and cache in $DF and $E4 .A6F4 LDA $06A2, X STA $DF LDA $06B2, X STA $E4 RTS
--- $A700-$A70D Simple pseudo-random number generator from https://codebase64.org/doku.php?id=base:small_fast_8-bit_prng .A700 LDA $E0 BEQ $A709 ASL BEQ $A70B BCC $A70B .A709 EOR #$1D .A70B STA $E0 RTS
--- $A70F-$A737 Start screen: Oscillating brightness of Usagyuuun lettering -- Fun fact: Change .A70F to F1 and #$E0 to #$E1 for a rainbow effect -- Loop over all TED char addresses in region $0C00-$0CC7 .A70F 10 - this address stores the increment for the color attribute change: #$10 to increase brightness or by #$E0 to decrease brightness .A710 LDX #$C8 - #$C8 = 5 rows * 40 columns .A712 LDA $0BFF,X -- Compare to whitespace code #$20 that indicates empty cells (also the cells right of the lettering must be #$20 to avoid unintentional flickering) CMP #$20 BEQ $A734 -- If there is a character at that position add value from $A70F to color attribute LDA $07FF,X CLC ADC $A70F BPL $A731 -- Toggle increment at $A70F LDA $A70F EOR #$E0 STA $A70F -- Add increment to color attribute LDA $07FF,X CLC ADC $A70F .A731 STA $07FF,X .A734 DEX BNE $A712 RTS
--- $A73C-$A755 Set all TED color attributes to grey .A73C LDA #$00 STA $D8 LDA #$08 STA $D9 -- Outer loop over high-bytes of attribute addresses .A744 LDA #$61 LDY #$00 -- Inner loop over low-bytes of attribute addresses .A749 STA ($D8),Y DEY BNE $A748 INC $D9 LDA $D9 CMP #$0C BNE $A744 .A755 RTS
--- $A757-$A765 Kniffelinterlude: IRQ main .A757 JSR $A768 ?? 11 bytes would be enough for a context-specific slowing counter and a JSR statement that calls another music routine 11* NOP .A765 RTS
--- $A767-$A78F Kniffelinterlude: Color flickering of Kniffel lettering .A767 10 - increment for color (brightness) change .A768 LDX #$C8 - #$C8 = 5 rows * 40 columns .A76A LDA $0D8F,X - Lettering starts in 10th row -> the address of the first cell is $0D90 CMP #$20 BEQ $A78C LDA $098F,X CLC ADC $A767 BPL $A789 -- Toggle increment at $A767 LDA $A767 EOR #$E1 STA $A767 -- Add increment to color attribute LDA $098F,X CLC ADC $A767 .A789 STA $0990,X .A78C DEX BNE $A76A .A78F RTS
--- $A794-$A79A Hall of fame: IRQ main .A794 JSR $A79D NOP NOP NOP RTS
--- $A79C-$A7DC Hall of fame: Color flickering of top 10 score board .A79C F1 - increment for chaotic color change -- Initialize low- and high-bytes of addresses of first TED character in $DA-$DB and TED attribute in $D8-$D9; The top 10 table starts in row 9 -> the address of the first cell is $0D4B .A79D LDA #$4B STA $DA STA $D8 LDA #$0D STA $DB LDA #$09 - high-byte of attribute = high-byte of character - #$04 STA $D9 -- Loop over 10 rows * 40 columns = 400, but 512 work as well, so we run Y from #$00 to #$FF and use two STA statements .A7AB LDY #$00 -- Alternative 1: Change color at characters <> #$20 (whitespace) --.A7AD LDA ($DA),Y --CMP #$20 -- Alternative 2: Change color at attributes <> #$10 (white) .A7AD LDA ($D8), Y CMP #$10 BEQ $A7CF LDA ($D8),Y CLC ADC $A79C BPL $A7C9 -- Toggle increment at $A70F LDA $A79C EOR #$E1 STA $A79C -- Add increment to color attribute (using indirectly indexed addressing, because region >#$FF) LDA ($D8),Y CLC ADC $A79C -- To achieve flowing color effect, we want to save the attribute one behind (!) the source cell; So we increment the low-byte for indirectly indexed addressing stored at $D8 by 1.. INC $D8 .A7CB STA ($D8),Y DEC $D8 .A7CF DEY BNE $A7AD -- ..and restore its original value afterwards for the loop ?? There might well be a more clever way of achieving this, so go ahead and try! INC $DB INC $D9 LDA $DB CMP #$0F BNE $A7AB .A7DC RTS
--- $A7DE-$A7EB Start screen: Initialize addresses that define the color circle .A7DE LDX #$1C STX $E5 .A7E2 LDA $A64F, X STA $A61B,X DEX BNE $A7E2 .A7EB RTS
--- $A7ED-$A7FA Player name query: Initialize addresses that define the box frame .A7ED LDX #$24 STX $E5 .$A7F1 LDA $A66F, X STA $A61B,X DEX BNE $A7F1 .A7FA RTS
|
| |
Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon |