Norman Sword Posted November 21, 2018 Report Share Posted November 21, 2018 (edited) This is a re-use of the same algorithm. This time it translates a key press into a key value. Could be used for high score input which uses the keyboard to type in a name and not the easy scroll letters to get an input. The big wastage is the translate table. The purpose of typing this is only to show a quick re purposing of a routine. (Of note I have seen far worse than this)..key_input:LD HL,TABLE-1 LD BC,#FEFE keyloop1: IN A,( C ) LD E,5 keyloop2: INC HL RRCA JR NC,key_pressed DEC E JR NZ,keyloop2 RLC B JR NC,keyloop1JR C,keyloop1 << corrected JR key_input key_pressed: LD A,(HL) ;the key value from the keyboard . . TABLE db 0,"ZXCVASDFGQWERT1234509876POIUY",13,"IJKL ",1,MNB"TABLE db 0,"ZXCVASDFGQWERT1234509876POIUY",13,"LKJH ",1,"MNB" <<hopefully corrected shift translates as 0, symbol shift as 1, enter as 13 Edited to correct the errors from my quick transcribe. Edited November 21, 2018 by Norman Sword IRF 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted November 21, 2018 Report Share Posted November 21, 2018 "JR NC,keyloop1" should read "JR C,keyloop1"? This entry: "IJKL ", should be "LKJH ", (with the Space character at the end, before the symbol shift entry)? Quote Link to comment Share on other sites More sharing options...
Norman Sword Posted November 21, 2018 Report Share Posted November 21, 2018 Very surprised it did not contain far more errors. I will edit but leave the errors obvious. IRF 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted February 19, 2019 Report Share Posted February 19, 2019 (edited) I've found a six nine-byte saving in the 'Initialise the title screen' routine, by replacing the individual checks of various attribute values at #8844-#8870, inserting a couple of look-up tables and using two CPIR commands. I'll type up a disassembly when I find the time. :) Edited February 20, 2019 by IRF jetsetdanny and Spider 2 Quote Link to comment Share on other sites More sharing options...
IRF Posted February 24, 2019 Report Share Posted February 24, 2019 (edited) There follows a disassembly of my rewrite of the Impossible Triangle-drawing code, as mentioned in my previous post. The rewritten part of the routine now saves eight bytes, compared with the original. N.B. I believe that this is exactly the sort of thing that the CPIR command should be used for (unlike Matthew's dodgy application of CPIR in the room-drawing code, which gives rise to the Cell Graphics Bug). Title_screen_data EQU #885D ; A new data table, which contains all the attribute values which were individually checked ; via CP #nn commands in the original code (and the former operand of a LD A, #nn command) Triangle_graphic_data EQU #8431 ; The original table containing the pixel-graphics used to create the impossible triangle. ; There are two halves to this table (at #8431 and #8441), and each half contains a pair ; of two eight-byte graphics (e.g. graphics start at #8431 and #8439 for the first half of the table) ORG: #8841 LD DE, #5800 Impossible_triangle_loop: LD A, (DE) LD HL, Title_screen_data ; HL now points at the start of the data table, in preparation for the CPIR loops (and other commands) that follow LD BC, #0005 ; BC counts down the CPIR loop, but B is also used to indicate which half of the graphic data at #8431 is picked up CPIR ; Search through the first five entries in the data table JR Z, Nothing_to_draw ; If there is a match, then this particular screen cell contains no pixel-graphics LD C, #03 ; B still holds 00 at this point (and HL is pointing at the next part of the data table) CPIR ; Search through the next three entries in the data table JR Z, Draw_triangle_segment ; If there is a match, then draw a part of the triangle using the first half of the graphic data at #8431 CP (HL) ; Check A against the penultimate value in the data table... INC HL ; ...and move HL on to the final entry in the table (I tried a CPI command here, but that doesn't preserve B = #00) JR Z, switch_INK_and_PAPER ; If there is a match with the penultimate entry, then we are at the 'tricky corner' of the triangle LD B, #10 ; No match in the data table, so we need to select a graphic from the second half of the pixel data JR Draw_triangle_segment ' (i.e. the parts of the triangle which slope 'up-to-the-right') Title_screen_data: ; This table could be moved elsewhere in the code, but every path through this routine jumps past it, ; so it can safely be left here DEFB #00 #09 #24 #2D #D3 ; These entries correspond to parts of the screen with no pixel-graphics (i.e. the black background, flashing lettering, ; or solid parts of the triangle which have matching INK and PAPER colours) DEFB #05 #08 #29 ; All remaining entries in the table correspond to parts of the triangle which slope 'down-to-the-right' DEFB #2C #25 ; If the attribute in the cell under consideration is #2C (green INK/cyan PAPER), then replace it with #25 (cyan INK/green PAPER) ; N.B. I could have save an extra byte by retaining the original commands for the last two entries [CP #2C and LD A, #25 / LD (DE), A], ; and omitting the last two entries in the table, but I considered it more elegant to have all the data stored within a single data table DEFS #08 ; Eight unused bytes (NOPs) - the point of the exercise! (These can obviously be consolidated elsewhere) Switch_INK_and_PAPER: LD A, (HL) ; Pick up the final entry in the data table and update the attribute in this cell (this swaps the INK/PAPER colours around... LD (DE), A ; ... which allows the green/cyan corner of the triangle to be drawn using all four of the graphics at #8431) ; N.B. From hereon in, there are further byte-efficiencies to be achieved, which are documented earlier in this thread, ; but which I haven't (yet) incorporated below Draw_triangle_segment: LD A, E AND #01 ; Whether E has an even or odd value determines which half of the selected pair of graphics from #8431 is used RLCA RLCA RLCA OR B ; Determines which pair of graphics from #8431 is used (N.B. this has been changed from the OR C in the original code) LD C, A LD B, #00 LD HL, Triangle_graphic_data ADD HL, BC PUSH DE BIT 0, D LD D, #40 JR Z, correct_part_of_screen_identified LD D, #48 Correct_part_of_screen_identified: LD B, #08 CALL #969B POP DE Nothing_to_draw: INC DE LD A, D CP #5A JP NZ, Impossible_triangle_loop EDIT: I should also mention that the above rewrite still works if the erroneous attribute in the original title screen is corrected (i.e. the green/black cell inside the lower part of the letter 'S', which should properly be green and blue). This can be fixed by editing the data at source, within page #98 (i.e. POKE #98D2, #0C) - no change to the new table at #885D is required, because the corresponding triangle segment slopes down-to-the-left, and so it doesn't need a specific entry in the table (the correct graphic is selected 'by default'). Edited February 24, 2019 by IRF jetsetdanny and Spider 2 Quote Link to comment Share on other sites More sharing options...
Spider Posted February 24, 2019 Report Share Posted February 24, 2019 I did wonder a while back if there was a better way of doing this, not the actual code more the way the 'data' for it is present. I vaguely recall trying a fully compressed full screen to expand and LDIR into screen memory although from what I remember there were no byte savings from this, given it had to live 'somewhere' anyway in its original format. Impressive stuff. :thumbsup: IRF and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
jetsetdanny Posted March 2, 2019 Author Report Share Posted March 2, 2019 Yes, impressive stuff, Ian! - thanks for this :). IRF and Spider 2 Quote Link to comment Share on other sites More sharing options...
Norman Sword Posted March 4, 2019 Report Share Posted March 4, 2019 (edited) The way the logo is stored is poor design. It is possible (i have done so) to reduce the size of the title screen and its data by around 200+ bytes, it might be nearer 300 bytes. Edited March 6, 2019 by Norman Sword jetsetdanny, IRF and Spider 3 Quote Link to comment Share on other sites More sharing options...
IRF Posted March 4, 2019 Report Share Posted March 4, 2019 (edited) I'm aware that there are large areas of the title screen with many consecutive identical attribute values (e.g. the first two character rows all hold 00), where it is much more efficient to use a few simple loops to write the appropriate values to the 'uniform' parts of the screen, instead of storing whole chunks of repetitive data (e.g. 64 consecutive 00 bytes for the top two rows) and copying the whole screen using a single LDIR command (as was the case in the original code). EDIT: That is to say, the amount of bytes saved in optimising the storage of the Title Screen's attribute data, vastly outweighs the modest saving which I have just come up with for the routine that draws the Impossible Triangle's pixels based on the attribute data. Edited March 4, 2019 by IRF jetsetdanny and Spider 2 Quote Link to comment Share on other sites More sharing options...
IRF Posted June 11, 2019 Report Share Posted June 11, 2019 (edited) Small rewrite in the JSW game initialisation code which saves a byte: 87F5 LD HL,$857C 87F8 LD (HL),$30 87FA INC HL 87FB LD (HL),$30 87FD INC HL 87FE LD (HL),$30 LD HL, #857C LD BC, #0330 loop: LD (HL), C INC HL DJNZ loop Edited June 11, 2019 by IRF Spider 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.