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
Edited by Norman Sword, 17 July 2019 - 05:16 PM.