Jump to content
Jet Set Willy & Manic Miner Community

Norman Sword

Contributor
  • Posts

    603
  • Joined

  • Last visited

Everything posted by Norman Sword

  1. The purpose and scope of the routine was primarily a proof of concept. After asking myself how easy is it to edit the original Manic Miner and compress the data slightly to enable 40 rooms. I decided to take a new naked listing of Manic Miner and look at how the original stored its data. Matthew stored the room graphic layout as an attribute tile for each and every one of the 512 tiles. In JSW the tiles were stored as a bit stream of pairs of bits describing one of four types, resulting in a reduction from 512 bytes down to 128 bytes plus an eight byte overhead to describe one stair and one conveyor. Manic Miner has more tile types and two bits does not give enough scope to describe the room without more add ons. Manic Miners room layout can be described with a stream of three bits (giving enough scope for all the rooms) . But a three bit stream of data is not easy to visualise or edit, and we still need to tag on one extra bit to describe the direction of the conveyors. Easy enough to write in code- but as I said not easy to edit the bit stream when seen as data. It makes more sense and is easier to visualise if we expand to a four bit stream of data. Here each four bits corresponds to a nibble of data. Very easy to edit, easy to visualise and editable with just a hex editor Expanding to nibbles to describe a room, actually compresses the original 512 bytes of data describing each rooms layout in Manic Miner down to 256 bytes. *** NOTE *** this compression is designed to be primitive in its layout. I could compress down to a quarter of this size if I used a more aggressive method. Editing naked layout data then becomes very difficult. Once I decided on using nibbles to represent each of the tiles, it is obvious I can have more types of tiles described by each nibble. Reducing each basic room layout and definition from 4*256 bytes to 3*256 bytes still does not give enough scope to greatly expand the room count... It has released 20*256 bytes of data, which is nearly enough for seven rooms. So doing just this slight compression allows 27 rooms for Manic Miner. It would not take much effort to do this- an expansion to 27 rooms is very easy. It just needs the indexing of rooms and the drawing of the rooms to be changed. (ignoring the few data reference's that also need changing) 40 rooms needs a bit more effort.
  2. The reason the game has the cheat invoked at run time, was to facilitate the discovery of the other features.
  3. I will post the novelty tomorrow. It is something I have not written for Manic Miner before. The novelty was aimed at a group such as this - It was how ever not finished due to lack of space in 48k. I use an assembler and editing is just a text file to play with. Of interest - In conversation recently with Matthew I asked him about the way he edited Jet Set Willy. Due to the nature of the Tandy hex memory editor it seemed more than likely that the data was page aligned due to the Tandy's method of Paging memory displayed in the editor. This then makes each room a page on the Tandy and each piece of data is fixed in position on the Tandy screen. You can flip pages and the conveyor data for each room stays in the same place. as does all the other room data. Easy to flip through the rooms changing bits and pieces. He confirmed to me that he edited the data for each room directly in hex- no editors- no room editor- no sprite movement editor- each room was edited directly in hex. Think about editing the room shape in hex for every room- without an editor - just editing the hex. Which considering that each of the 60 playable rooms has 256 bytes editable- I find it amazing that he managed to get to the end with just one bit wrong for the arrow. The other errors are the result of not having quick and fast access to each room. The easiest and probably best method of finding errors is having the demo room flash past. The arrow problem (MIGHT) have been spotted. For manic Miner he wrote an editor - What format that took I have no idea.
  4. This starts by default with cheat switched on. If edited, the cheat can be switched off . To enable a normal start to the game.
  5. Changed the wording on the download file from "top 20 caverns" to "Last 20 Caverns". Questionable the depth of the caverns- because the very last cavern provides access to ground level. To jump caverns press the combination of "3" and "1" to move to a previous cavern- or press "3" and "2" to move to the next cavern. Pressing "3" resets the cavern. Each cavern has 16 tiles from which it can be drawn. Kong is movable. Multiple conveyors Switches are movable Any sprite in any room any combination of sprites in any room any event Kong-Skylab-Light beam in any room any combination of events in any room But the above is NOT what is different with this version.
  6. Manic 40 Miner After I stopped developing the JSW128 VK VL VM engine. I spent a week writing a version of Manic Miner called Manic 40 Miner. This does not contain any new rooms. They are the original and Ligans rooms. This is NOT meant to be a playable version. It was just a test routine. The rooms have a lot more scope to edit and have a lot more tiles to play with. NOTE this runs in 48k the same as the original. It does a lot more than is obvious from a quick glance. ---------------------------------------------------------------- addendum. The feature that I mentioned with the comment "It does a lot more than is obvious from a quick glance." was explained in more detail in Post #14. The file size become excessive to edit online. So that explanation in post #14 is only current up to V5. I have attached a file that explains the current version here on post #1 Surprised that the earlier versions are still being down loaded. (i will delete them - they now serve no purpose) V1 was down loaded 4 times V2 was down loaded 9 times V3 was down loaded 6 times V4 was down loaded 3 times V5 was down loaded 3 times V6 was downloaded twice V6a followed by V6b fixing- specific flaws caused by one line of code deleted and an assembler problem Plus too much haste. V6c downloaded 37 times - version was not completable without editing Only the last version V6 revisions has been left. Manic 40 Miner V6 Editor Text.txt Manic 40 Miner V6c6.tap The Final final version V6c6 - this is a data changed version from V6b The version v6c6 is playable through all the 40 caverns. (other versions are not)
  7. Logical progression from version to version. Main changes. Version K was a completable version introducing several aspects of game play, and 128 rooms in 48k Version L removed the superjump, which had no real purpose, and removed the live's bonus. The reason for those two changes was the introduction of a portal. This I felt was sufficiently different to justify a rename of the versions. Version L demo, updates the games structure completely. Which is the reason for the dramatic increase in speed Version L demo update. (this version has never been released) This was an update where I added a lot of (now unseen/deleted) routines that expanded the graphics. Used mainly on pause and demo. These graphic routines redrew the screen in double and quadruple size. Whilst it was interesting to write those routine. I decided I could use the memory taken up by those routines in a better way. ------------------------------------------------------------------------------------------------------------------------------------------------- The standard game and inclusive of version K has a death sequence where when Willy dies, if he has lives left. Then he is shown re-emerging into the same room. Version L changed the sequence to when Willy dies, if he has time left. Then he is shown standing in the last portal he visited. This might be a long way away from where he died and all the objects collected since visiting the portal are all reinstated into the game. This is a major change in logic, and necessitates a lot of routines to be changed ---------------------------------------------------------------------------------------------------------------------------------------------- Version M has the ability to switch between these two basic game formats. The standard "die and re-enter the room" (version K and standard format games) and the extended logic used in version L where the standard "die re-enter the room" is changed "to die emerge from portal" In order to switch between the two differing logics was to me a challenge. I needed to back track all the changes I had made and modify the code to swap logics. Version M is version "K" and Version "L" combined. So in essence it supersedes both of the earlier versions. In order to have the ability to switch the logics I needed the simple addition of a key to press and perhaps a graphic indicating what is being changed. Instead I decided to add a graphic page with options. The memory needed for the options page was taken from the double and quadruple draw routines. Which is why they no longer exist in the game. Version "M" can play in the same basic way as version "K", and also has the ability to switch to the game mode introduced in version "L". It also uses the extended logic written into version "L" demo. The options page adds the ability to start in most of the rooms. selectable for every game start. It permits the ability to switch the shooter on and off. It permits the ability to change the shooter graphics. It permits the ability to use one of sixteen predefined Willies to play the game. It permits the player to switch off the many flashing screen graphics. It adds a proper in game tune playing ability.. The options page and all the changes that necessitated in the game consumed quite a lot of memory. The memory was found by deleting the double and quadruple draw routines. It also cut short the extension of game logics. I had added quite a few and had started to add the features into the game. I think only one or two now remain and the others deleted. The Major problem I have describing changes is that familiarity to the changes blurs what is new to me. For example the cold room has twinkling stars in the room. When those stars started to twinkle and in what version would necessitate my going back through all the versions looking to find when it happened. I have better things to spend my time on, and those twinkling stars are just one of the hundreds and hundreds of changes I have done.
  8. JSW128vM View File The logical sequence from JSW128VK and JSW128VL. The game changes are very few. This final version written very soon after jsw128VK, and has been sitting on my hard drive, for six months - awaiting further changes. Since I have decided to do other things, it has become obvious to me that this will not be updated in any way. short Condensed notes on game. 128 rooms Runs in 48k Can play In long notes for game music and not clicks triple speed multiple game options Game options menu 16 game characters to use ability to use portals ability to change start rooms extensive inbuilt cheat Cheat is activated by typing "IWroteQuip" or as spoken ( I Wrote Quip ) - without the spaces Submitter Norman Sword Submitted 12/25/2019 Category Jet Set Willy [Remakes]  
  9. Version Version 1

    90 downloads

    The logical sequence from JSW128VK and JSW128VL. The game changes are very few. This final version written very soon after jsw128VK, and has been sitting on my hard drive, for six months - awaiting further changes. Since I have decided to do other things, it has become obvious to me that this will not be updated in any way. short Condensed notes on game. 128 rooms Runs in 48k Can play In long notes for game music and not clicks triple speed multiple game options Game options menu 16 game characters to use ability to use portals ability to change start rooms extensive inbuilt cheat Cheat is activated by typing "IWroteQuip" or as spoken ( I Wrote Quip ) - without the spaces
  10. 1) The topic is well known about and has been discussed by various forums. 2) The graphic layout of the piano keyboard although wrong has been copied onto various other machines. It is what Matthew drew, so even though it is wrong, it has been copied with the incorrect layout. 3) The locations of the notes being played and displayed on the graphic keyboard, have no relationship to the music playing. The offsets to each note that is played is based purely on its arithmetic value and this creates a linear offset to each note. The offsets should be logarithmic. 4) The note that is highlighted never encroaches onto the upper portion of the keyboard. The parts illuminated are all identical. 5) The music played is a simple Pulse wave (square wave). Which because Matthew decided to use two waves generates a pulse wave difference. The sound you hear is the characteristic sound produced by the shifts in the values of each pulse. Similar to hearing Doppler shifts and harmony beats. The values used by the music have no bearing on how the music notes are seemingly played on the keyboard. So the values chosen were not influenced by the graphic depiction, With the consequence that no attempt was being made to avoid any part of the keyboard. The light up routine could play play a piano slide and thus light up each note in sequence if it was needed.
  11. Halfway through typing this it posted, with an error message. Hence the retype on post #4
  12. The strike through fell off and is lying somewhere in cyberspace. The op codes in the listings which are unwanted have been rem'ed out and also struck through again. (just in case I paste and copy again) with that statement I am reminded that the original still has only the strike through. So I will edit that as well. Code with the unwanted parts will still work. But since it is not needed best rem'out in addition to the strike through. (or just deleted completely)
  13. Semantics:- Every version of the raster copy routine listed under "source code for JSW" does not use the "a" register. I subsequently added before and after the actual routine a part which modified the Block_Copy routine (which ever variant of the block copy routine as listed in each post). The raster copy routine still does not use the a register, but the modifying code before and after did use the "a" register. I have done the trivial change to each modifying addition to remove the usage of the "a" register throughout the whole raster copy.
  14. All the raster copy posts under the heading "source code for JSW" work as stated. None use the piece of code listed back in APRIL 2017 and quoted in post #62. Because you are reverting between differing pieces of code used over many years, I have expanded each reference to raster copy listed under "source code for JSW" to be self contained. Each and every version works and none use the "A" register.
  15. I have edited three posts to remove the conflict of BLOCK_MOVE32: being used with differing routines. The routine that uses a long line of ldi's and returns without decrementing the "A" register has had its labels changed That block move now uses the labels BLOCKX_MOVE32 and BLOCKX_MOVE31. the inclusion of the X mid label hopefully removing confusion between two very similar routines, which are mentioned sporadically over a few posts.
  16. since the source code for me is just a blank canvas to edit. I am not restricted to worrying about will a piece of code fit in here or there. If I delete a byte in the source code, I immediately have that byte and it can be used anywhere I want in the limits of the memory I am editing. The restrictions are removed. Block move ld hl,source ld de,destination ld bc,size ldir looking at this yet again, but from the no restrictions point of view. The best solution is slightly different Shift_block32: ; new label to distinguish from all the other code ldi Shift_block31 rept31 ldi endm jp pe,Shift_block32 ret we write the code out exactly as specified in JSW but we now use one more byte on each instance and rather than LDIR we use an extra byte and call Shift_block32 or Shift_block31 ; Depending on the value being divisible by 32 or one short This also does not use the "a" register- similar to LDIR on its own. This method also is as close to a replacement LDIR as we can generate in code, returning with the same parameters as would be set with LDIR. so LD HL,CHAR0 ;L869F ;$4000 LD DE,CHAR0+1 ; 86A2 ;$4001 LD BC,$1AFF ; 86A5 ; LD (HL),$00 ; 86A8 ; LDIR ; 86AA ; call shift_block31 This is faster again (marginally) but uses the same registers as the original I suppose you could modify this routine to use a similar raster copy routine as the one posted above. e.g. ----------------------------------------------------------------------------------------------------------------------------------------------------------- ;copy work and attribute screens ld hl, S_M_C_New_Mod ;place to modify ld (hl),$c9 ; modify in a "ret" ld hl,att_work ld de,ATT0 ;;;;ld b,0 ; this was set for usage in a different routine exx ld hl,ytable ld bc,128 ; must be a multiple of 32 ; this is 4*32 ;- that is 4 raster lines before the attributes are written in ;loop executed 128 times on each game loop raster: ld e,(hl) inc l push hl ld h,(hl) ld l,e ld d,h res 5,d call Shift_block32 ;executed 128 times on each game loop jp pe,n_raster exx ; this code is executed 16 times on each game loop ;;;;ld c,32 ; this was set for usage in a different routine call Shift_block32 exx inc b n_raster: pop hl inc l jr nz,raster ld hl,S_M_C_New_Mod ;place to midify Ld (hl),$ea ;opcode for Jp PE,xx rest of code ----------------------------------------------------------------------------------------- Shift_block32: ; new label to distinguish from all the other code ldi Shift_block31: rept31 ldi endm S_M_C_New_Mod Equ $ jp pe,Shift_block32 ;opcode toggled between ( "ret" ) and ( "jp pe,xx" ) ret
  17. Since the last posted raster copy is a lot faster without using the "a" register and we don't want to supply two lots of LDI routines..... Lets just chop up the old LDI routine and make that return without modifying the "a" register. Then we have only one LDI routine. The chopping up of the routine takes 5 bytes to modify and five bytes to put it back. Since these two modifications are executed only once, it is a lot faster than having to re-use the "a" register inside the loop. The Block move from post #58 BLOCK_MOVE32: ldi BLOCK_MOVE31 ldi rept 30 ldi endm S_M_C_fast: equ $ dec a ; change this opcode jr nz,BLOCK_MOVE32 ret ;----------------------------------------------- The raster copy is expanded to become ;modify ld hl,S_M_C_fast ;position to modify ld (hl),$C9 ;opcode value for ret >>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;copy work and attribute screens ld hl,att_work ld de,ATT0 ;;;;;; ld b,0 ; this was set for usage in a different routine exx ld hl,ytable ld bc,128 ; must be a multiple of 32 ; this is 4*32 ;- that is 4 raster lines before the attributes are written in ;loop executed 128 times on each game loop raster: ld e,(hl) inc l push hl ld h,(hl) ld l,e ld d,h res 5,d call BLOCK_MOVE32 ;executed 128 times on each game loop jp pe,n_raster exx ; this code is executed 16 times on each game loop ;;;;ld c,32 ; this was set for usage in a different routine call BLOCK_MOVE32 exx inc b n_raster: pop hl inc l jr nz,raster >>>>>>>>>>>>>>>>>>>>>>>>>>>> ;restore back to old ld hl,S_M_C_fast ld (hl),$3d ;opcode value for dec a ; rest of code which leaves only one ldi routine. That's today's version.....
  18. The original with the "a" register passing the amount of copy was in response to the limited space available in the source code. ld hl,source ld de,destin ld bc,count ldir being 11 bytes in size.. modified to be ld hl,source ld de,destin ld a,count/32 call BLOCK_MOVE32 ; which uses "a" as a counter which is also 11 bytes in size and can be easily fitted into the same size space. IGNORING the raster copy routine for now. Lets look at the format of the original BLOCK_MOVE32 which was BLOCK_MOVE32: ldi BLOCK_MOVE31 ldi rept 30 ldi endm dec a jr nz,BLOCK_MOVE32 ret This has two labels BLOCK_MOVE32 and BLOCK_MOVE31. It could be written out to have every label from BLOCK_MOVE32 down to BLOCK_MOVE01. It doesn't because the other labels would be used infrequently and I am lazy. I can not be bothered writing them all out. Problems using the above routine to move odd amounts........ The bulk of block moves in the game are multiples of 32 and a call to BLOCK_MOVE32 does the job. However we also have cases where we copy a block in a block copy sequence such as. : this code will clear the screen attributes to black on black ld hl,ATT0 ld de,ATT0+1 ld bc,$2ff ld (hl),0 ldir this might seem to not be of the same format. we are copying here $2ff of data which is not a multiple of 32. But look again at the amount. I can re write $2ff in a different way, such as $300-1. Clearly the same value and clearly this is very similar to the format being used in the standard block move. so lets adapt that code ld hl,ATT0 ld de,ATT0+1 ld (hl),0 ld a,$300/32 ; MOVE $300 bytes call BLOCK_MOVE31 ;MOVE $300 bytes -1 e.g. move $2ff bytes <<<<<<< NOTE BLOCK_MOVE31 this has moved $2ff bytes which is what we wanted.... In jsw the vast majority of block moves want to move either a multiple of 32 bytes or one short of a multiple of 32 bytes. Which is why I only expanded BLOCK_MOVE32 and BLOCK_MOVE31 out in the routine to move the data. Going into jsw we have ... And this is just a quick grab from the source code. For all the big block moves LD HL,CHAR0 ;L869F ;$4000 LD DE,CHAR0+1 ; 86A2 ;$4001 LD BC,$1AFF ; 86A5 ; ld a,$1b00/32 LD (HL),$00 ; 86A8 ; LDIR ; 86AA ; call BLOCK_MOVE31 LD HL,code_att ; 86E8 ;L9B80 LD DE,ATT8 ; 86EB ;$5900 LD BC,$0080 ; 86EE ; ld a,$80/32 LDIR ; 86F1 ; call BLOCK_MOVE32 LD HL,CHAR0 ;L8813 ;$4000 LD DE,CHAR0+1 ; 8816 ;$4001 LD BC,$17FF ; 8819 ; ld a,$1800/32 LD (HL),$00 ; 881C ; LDIR call BLOCK_MOVE31 LD HL,logo_att ; 8820 ;L9800 LD BC,$0300 ; 8823 ; ld a,$300/32 LDIR ; 8826 ; call BLOCK_MOVE32 ;recolour line 19 LD HL,ATT19 ; 8828 ;$5A60 LD DE,ATT19+1 ; 882B ;$5A61 LD BC,$001F ; 882E ; ld a,$20/32 LD (HL),$46 ; 8831 ; LDIR call BLOCK_MOVE31 LD HL,ATT19 ; 88B8 ;$5A60 LD DE,ATT19+1 ; 88BB ;$5A61 LD BC,$001F ; 88BE ; ld a,$20/32 LD (HL),$4F ; 88C1 ; LDIR ; 88C3 ; call BLOCK_MOVE31 LD HL,bottom_att ; 8907 ;L9A00 LD DE,ATT16 ; 890A ;$5A00 LD BC,$0100 ; 890D ; ld a,$100 LDIR call BLOCK_MOVE32 LD DE,room_layout ; 891A ;L8000 LD BC,$0100 ; 891D ; ld a,$100/32 LDIR call BLOCK_MOVE32 LD HL,CHAR16 ; 8958 ;$5000 LD DE,CHAR16+1 ; 895B ;$5001 LD BC,$07FF ; 895E ; ld a,$800 LD (HL),$00 ; 8961 ; LDIR call BLOCK_MOVE31 LD HL,att_master ; 89B0 ;$5E00 LD DE,att_work ; 89B3 ;$5C00 LD BC,$0200 ; 89B6 ; ld a,$200/32 LDIR call BLOCK_MOVE32 LD HL,char_master ; 89BB ;$7000 LD DE,char_work ; 89BE ;$6000 LD BC,$1000 ; 89C1 ; ld a,$1000/32 LDIR call BLOCK_MOVE32 LD HL,char_work ;L89F5 ;6000 LD DE,CHAR0 ; 89F8 ;$4000 LD BC,$1000 ; 89FB ; ld a,$1000/32 LDIR ; 89FE ; call BLOCK_MOVE32 LD HL,att_work ; 8A1A ;$5C00 LD DE,att_work+1 ; 8A1D ;$5C01 LD BC,$01FF ; 8A20 ; ld a,$200/32 LD (HL),A ; 8A23 ; <<<<<< a reg problem LDIR call BLOCK_MOVE31 LD HL,att_work ;L8A26 ;$5C00 LD DE,ATT0 ; 8A29 ;$5800 LD BC,$0200 ; 8A2C ; ld a,$200/32 LDIR ; 8A2F ; call BLOCK_MOVE32 LD HL,bottom_att ;L8B07 ;L9A00 LD DE,ATT16 ; 8B0A ;$5A00 LD BC,$0100 ; 8B0D ; ld a,$100/32 LDIR call BLOCK_MOVE32 LD HL,ATT0 ;L8C03 ;$5800 LD DE,ATT0+1 ; 8C06 ;$5801 LD BC,$01FF ; 8C09 ; ld a,$200/32 LD (HL),A ; 8C0C ; <<<<<< problems here with the a register LDIR call BLOCK_MOVE31 LD HL,CHAR0 ;L8C4A ;$4000 LD DE,CHAR0+1 ; 8C4D ;$4001 LD BC,$0FFF ; 8C50 ; ld a,$1000/32 LD (HL),$00 ; 8C53 ; LDIR call BLOCK_MOVE31 LD HL,att_master ; 96F4 ;$5E00 LD DE,ATT0 ; 96F7 ;$5800 LD BC,$0200 ; 96FA ; ld a,$200/32 LDIR ; 96FD ; call BLOCK_MOVE32 LD HL,CHAR0 ; 96FF ;$4000 LD DE,CHAR0+1 ; 9702 ;$4001 LD BC,$0FFF ; 9705 ; ld a,$1000/32 LD (HL),$18 ; 9708 ; LDIR call BLOCK_MOVE31 The above illustrates why we have BLOCK_MOVE32 and BLOCK_MOVE31 . In a game like JSW we are moving multiples of 32 in the vast majority of cases. Only two of the above cases causes a pause and a need to work out how to preserve the a register. (it might contain more instances where the "A" register needs to be preserved) very easy to change and very easy to work out. The problem then comes with , how we manage the raster copy. Which in the recent posting uses a differnt BLOCK_MOVE
  19. Each example I write is self contained unless otherwise stated. The last example I wrote uses no check on the block of 32 ldi's and just returns. The above code "as used in post 54" is an old example which does use "a" as a counter. Give me five minutes and I will test the example as I wrote it and get back to you. But I think it will work as written ;----------------------------------------------------------------------------------------------------------------------- Works exactly as I said it would.
  20. Standard assembler directives:- One of the biggest helps is the macro language that you can build into pieces of standard code that are often used. The standard macro is as such: silly: Macro param1,param2,param3 ld hl,param1 ld de,param2 ld bc,param3 ldir endm. The macro here is defined by the label silly. Every time the word silly is seen in the source code it will replace it with all the code between the MACRO and endm. The word endm is shorthand for "end macro" So How do I use silly in a piece of code ( don't forget this example is called silly, because it is a silly example) I simply write in to the assemble code silly ATT0,ATT1,32 when the code is assembled the above will be substituted with ld hl,ATT0 ld de,ATT1 ld bc,32 LDIR which is the macro expanded and each of the labels re placed with the parameter passed to the macro. e.g ld hl,ATT0 ; here param1 is replaced with ATT0 ld de,ATT1 ; here param2 is replaced with ATT1 ld bc,32 ; here param3 is replaced with 32 LDIR Macros are very helpful to expand code out that is repetitive. another form of macros. is the rept directive. (rept = repeat). so getting back to to the original querry rept 32 ;repeat 32 times ldi endm ; end macro means repeat the line of code between the rept directive and then endm directive 32 times we can create big blocks of code by repeating and nesting : (these examples are just examples not taken from any code) so lets look at move macro count rept count ld a,(hl) ld (de),a inc hl inc d endm endm we can in the assembler now write move 8 and this will generate the inline code ld a,(hl) ld (de),a inc hl inc d ld a,(hl) ld (de),a inc hl inc d ld a,(hl) ld (de),a inc hl inc d ld a,(hl) ld (de),a inc hl inc d ld a,(hl) ld (de),a inc hl inc d ld a,(hl) ld (de),a inc hl inc d ld a,(hl) ld (de),a inc hl inc d ld a,(hl) ld (de),a inc hl inc d ; which is the quickest way of doing this operation possible. we have no loop counter. The above probably seems to be pointless, but consider a piece of code I have mentioned several times and written out an example of once. which is the stack copy. To speed up a stack copy we set up a nest macro similar to the example above. When the macro is expanded we end up with a big block of inline code. (the expansion can end up with 500 or more lines of code) we can also pass counters that can be used and acted upon. Macro's are also literally expanded and can cause no end of problems when the expansion does not seem to do what is wanted. ;-------------------------- TOO MUCH INFORMATION ------------------------------------- short answer REPT is short for REPeaT ENDM is short for END Macro
  21. Yes the BLOCKX_MOVE32 will clear the Parity Even Flag (PE flag) if and only if the last LDI counts the register pair "BC" down to zero. Which is why the line that loads BC with 128 is specifically indicating that "BC" must be set to a multiple of 32. If this was changed to a value which is not divisible by 32. Then the attributes would never be drawn, because the ( "JP PE,n_raster" ) would always branch to ( "n_raster" )
  22. Using a call and a ret to 32 consecutive LDI's . A variation on my last version would probably do what you want.... And this assumption is based on a quick scan of all the changes listed in the above posts. ;copy work and attribute screens ld hl,att_work ld de,ATT0 ;;;; ld b,0 ; this was set for usage in a different routine exx ld hl,ytable ld bc,128 ; must be a multiple of 32 ; this is 4*32 ;- that is 4 raster lines before the attributes are written in ;loop executed 128 times on each game loop raster: ld e,(hl) inc l push hl ld h,(hl) ld l,e ld d,h res 5,d call BLOCKX_MOVE32 ;executed 128 times on each game loop jp pe,n_raster exx ; this code is executed 16 times on each game loop ;;;; ld c,32 ; this was set for usage in a different routine call BLOCKX_MOVE32 exx inc b n_raster: pop hl inc l jr nz,raster ;Note the a register is not used in either routine --------------------------------------------------------------------- BLOCKX_MOVE32: rept 32 ldi endm ret ADDENDUM:- multiple reference through out these posts to BLOCK_MOVE32 or BLOCK_MOVE31.........I will go through all the posts and change the conflicting labels......In this post labels now called BLOCKX_MOVE32
  23. Re branching/ jumping and calling. The program counter is loaded during one of the clock cycles with data. This is the same with call's, Jump's and JR's. The number of clock cycles needed to set the data up is different. Once the program counter is loaded the next clock cycle we move to the new address. What this means is that the speed is fixed no matter where the Program Counter is asked to move to. A relative jump of 0 bytes is executed at the same speed as a relative jump of 127 bytes. Calls and jump's and I will also include ret's are similar the Program counter is loaded and the next clock cycle we execute the operand pointed at by the (possibly) changed Program counter. Each is acted on with no consideration of the amount of relative displacement from the old value. ---------------------------------------------------------------------------- I will re read the posts above this one.... And perhaps comment further.
  24. I would imagine you would end up with a large rule book. example 1:- S_M_C_counter1: equ $+1 ld a,12 inc a and 7 or 8 ld (S_M_C_counter1),a here the value varies between 8 and 15:- your example has failed, we never have a value of zero in the variable example 2:- S_M_C_opcode: inc a direction_switch equ $3c xor $3d ; this is ("inc a") xor ("dec a") ld hl,S_M_C_opcode ld a,(hl) xor direction_switch ld (hl),a here the opcode varies between either "inc a" or "dec a". the code is switching direction. again never zero ----------------------------------------------------- The circumstances can change from once instance to another. The S_M_C_ is alerting you to code that is modifying. The $-$ is making the statement that the value will be changed before the opcode is executed. In a lot of instances we must have an opcode or an initial value. In those cases the value is inserted or the opcode written out. I suppose it is similar to saying a block move is always in this format:- ld hl,source ld de,destination ld bc, count LDIR when the reality says it is a lot of the time, but the variations are vast.
  25. The opcode decides the size of the data used. I can not load the "A" register with 16 bits. In a similar way if I was to specify ld hl,2. I am always loading 16 bits never 8 bits. The $-$ is specifying 0. It is indicating a null value. The opcode is specifying the size of the data. you can not specify ld d,$- the syntax is wrong. you could specify ld d,-$ LD D,$ or any variation on that will load "D" with the low value of the program counter at that point. The value would change on each and every edit of the code if the program counter at that point is changed by edits. The $-$ is a consistent and fixed value of zero If you write enough code you will end up having to use references to data that you do not have. E.g. call $-$ which is a call to somewhere, but you do not have the address. The address is supplied by some other piece of code and in any case can move. So an address needs to be supplied to the assembler $-$ is as good an address as going out of your way to fabricate an address just to assemble the code.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.