Prev: 50002 Up: Map Next: 50275
50006: Draw Picture: Unpack
Used by the routine at DrawPicture.
Continues from DrawPicture.
Find out where this code is in memory. The call leaves its return address (DrawPicture_ReturnAddress) just below the stack pointer. An interrupt at this point would overwrite it, so BASIC calls DisableInterrupts first and EnableInterrupts afterwards.
DrawPicture_Unpack 50006 CALL 124 Call the RET instruction at 0124, at the end of CH_ADD+1, which returns straight away.
DrawPicture_ReturnAddress 50009 DEC SP Move the stack pointer back down to the return address.
50010 DEC SP
50011 EX (SP),HL Swap it into HL, so HL=DrawPicture_ReturnAddress.
50012 INC SP Move the stack pointer back up again.
50013 INC SP
50014 AND A Clear the carry flag ready for the subtraction.
50015 LD DE,7 HL=DrawPicture_Number (DrawPicture_ReturnAddress less 0007).
50018 SBC HL,DE
50020 PUSH HL Stash the address of the parameters on the stack.
50021 POP IY Restore the address of the parameters from the stack into IY.
50023 LD DE,298 HL=Graphics_DepartmentOfNationalPolice (DrawPicture_Number plus 0298), the first picture record.
50026 ADD HL,DE
50027 LD A,(IY+0) A=the picture number from *DrawPicture_Number.
Skip over the records before the requested picture.
DrawPicture_FindPicture 50030 DEC A Decrease the picture number by one.
50031 JR Z,DrawPicture_Found Jump to DrawPicture_Found if HL points to the requested picture.
50033 LD E,(HL) DE=the length of this record, less one.
50034 INC HL
50035 LD D,(HL)
50036 ADD HL,DE Add it to HL, so HL points to the next record.
50037 JR DrawPicture_FindPicture Jump to DrawPicture_FindPicture.
DrawPicture_Found 50039 LD DE,16384 DE=16384. This value is never used, as D and E are both set again before they are needed.
50042 INC HL Move HL past the length, to the record's screen third.
50043 INC HL
50044 LD A,(IY+1) A=*DrawPicture_Third.
50047 INC A Increment A by one, so that 255 becomes zero.
50048 JR NZ,DrawPicture_Unpack_0 Jump to DrawPicture_Unpack_0 if *DrawPicture_Third is not 255.
50050 LD A,(HL) Else write the record's screen third to *DrawPicture_Third.
50051 LD (IY+1),A
DrawPicture_Unpack_0 50054 INC HL Move on to the record's number of thirds.
50055 LD A,(IY+2) A=*DrawPicture_Thirds.
50058 INC A Increment A by one, so that 255 becomes zero.
50059 JR NZ,DrawPicture_Unpack_1 Jump to DrawPicture_Unpack_1 if *DrawPicture_Thirds is not 255.
50061 LD A,(HL) Else write the record's number of thirds to *DrawPicture_Thirds.
50062 LD (IY+2),A
DrawPicture_Unpack_1 50065 INC HL Move on to the record's flags.
50066 LD A,(HL) Copy the record's flags to *DrawPicture_Flags.
50067 LD (IY+3),A
Make sure the picture fits on the screen.
50070 LD A,(IY+1) A=*DrawPicture_Third.
50073 CP 3 Jump to DrawPicture_Unpack_2 if the screen third is less than 3.
50075 JR C,DrawPicture_Unpack_2
50077 LD (IY+1),0 Else start at the top third (write 0 to *DrawPicture_Third).
DrawPicture_Unpack_2 50081 LD A,(IY+2) A=*DrawPicture_Thirds.
50084 CP 4 Jump to DrawPicture_Unpack_3 if the number of thirds is less than 4.
50086 JR C,DrawPicture_Unpack_3
50088 LD (IY+2),1 Else draw one third (write 1 to *DrawPicture_Thirds).
DrawPicture_Unpack_3 50092 ADD A,(IY+1) Add the screen third to A. A still holds the number of thirds read at DrawPicture_Unpack_2, even when it has just been changed.
50095 CP 4 Jump to DrawPicture_Unpack_4 if the picture ends on the screen (the total is less than 4).
50097 JR C,DrawPicture_Unpack_4
50099 LD (IY+2),1 Else draw one third (write 1 to *DrawPicture_Thirds).
DrawPicture_Unpack_4 50103 LD A,(IY+2) A=*DrawPicture_Thirds.
50106 AND A Jump to DrawPicture_Pixels if the number of thirds is not zero.
50107 JR NZ,DrawPicture_Pixels
50109 LD (IY+2),1 Else draw one third (write 1 to *DrawPicture_Thirds).
Draw the pixels.
DrawPicture_Pixels 50113 INC HL Move HL on to the start of the picture data.
50114 LD E,0 E=0 (the left-hand column).
50116 LD A,(IY+1) A=*DrawPicture_Third.
50119 ADD A,A Multiply it by 8 as each third of the screen is 8 pages long.
50120 ADD A,A
50121 ADD A,A
DrawPicture_PixelsHighByte 50122 ADD A,64 Add the high byte of the start of the screen (64). BASIC POKEs this byte to draw into a buffer instead.
50124 LD D,A Set D and C to the high byte of the top pixel line of the picture, so DE holds its screen address.
50125 LD C,A
50126 LD B,1 B=1 (one pass, for row order).
50128 BIT 0,(IY+3) Jump to DrawPicture_PassLoop if bit 0 of *DrawPicture_Flags is set (row order).
50132 JR NZ,DrawPicture_PassLoop
50134 LD B,32 Else B=32 (one pass for each column).
DrawPicture_PassLoop 50136 PUSH BC Stash the pass counter on the stack.
50137 LD B,(IY+2) B=the number of thirds from *DrawPicture_Thirds.
DrawPicture_ThirdLoop 50140 PUSH BC Stash the thirds counter on the stack.
50141 LD B,8 B=8 (character rows in a third).
DrawPicture_RowLoop 50143 PUSH BC Stash the character row counter on the stack.
50144 LD B,8 B=8 (pixel lines in a character row).
DrawPicture_LineLoop 50146 PUSH BC Stash the pixel line counter on the stack.
50147 LD B,1 B=1 (one byte, for column order).
50149 BIT 0,(IY+3) Jump to DrawPicture_Unpack_5 if bit 0 of *DrawPicture_Flags is clear (column order).
50153 JR Z,DrawPicture_Unpack_5
50155 LD B,32 Else B=32 (a whole pixel line, for row order).
DrawPicture_Unpack_5 50157 PUSH DE Stash the screen address of this pixel line on the stack.
DrawPicture_ByteLoop 50158 PUSH BC Stash the byte counter on the stack.
50159 JR DrawPicture_FetchByte Jump to DrawPicture_FetchByte to write the next byte; it comes back to DrawPicture_NextByte.
DrawPicture_NextByte 50161 POP BC Restore the byte counter from the stack.
50162 INC DE Move right to the next screen byte.
50163 DJNZ DrawPicture_ByteLoop Decrease the byte counter by one and loop back to DrawPicture_ByteLoop until it is zero.
50165 POP DE Restore the screen address of this pixel line from the stack.
50166 POP BC Restore the pixel line counter from the stack.
50167 INC D Move down to the next pixel line.
50168 DJNZ DrawPicture_LineLoop Decrease the pixel line counter by one and loop back to DrawPicture_LineLoop until all 8 pixel lines are done.
50170 LD A,D Move D back up to the top pixel line of this character row (subtract 8).
50171 SUB 8
50173 LD D,A
50174 LD A,E Move down to the next character row (add 32 to E).
50175 ADD A,32
50177 LD E,A
50178 POP BC Restore the character row counter from the stack.
50179 DJNZ DrawPicture_RowLoop Decrease the character row counter by one and loop back to DrawPicture_RowLoop until all 8 character rows are done.
50181 LD A,D Move down to the next third (add 8 to D). E has gone back round to the same column.
50182 ADD A,8
50184 LD D,A
50185 POP BC Restore the thirds counter from the stack.
50186 DJNZ DrawPicture_ThirdLoop Decrease the thirds counter by one and loop back to DrawPicture_ThirdLoop until all the thirds are done.
50188 LD D,C Move D back up to the top of the picture (D=C).
50189 INC E Move right to the next column.
50190 POP BC Restore the pass counter from the stack.
50191 DJNZ DrawPicture_PassLoop Decrease the pass counter by one and loop back to DrawPicture_PassLoop until all the passes are done.
Draw the attributes.
DrawPicture_Attributes 50193 LD E,0 E=0.
DrawPicture_AttributesHighByte 50195 LD A,88 A=88 the high byte of the start of the attribute file. BASIC POKEs this byte to draw into a buffer instead.
50197 ADD A,(IY+1) Add the screen third.
50200 LD D,A D=A, so DE holds the address of the first attribute of the picture.
50201 LD B,(IY+2) BC=the number of attributes to draw: 256 for each third (B=*DrawPicture_Thirds and C=0).
50204 LD C,E
50205 SET 3,(IY+3) Set bit 3 of *DrawPicture_Flags, so that DrawPicture_FetchByte comes back to DrawPicture_NextAttribute.
DrawPicture_AttributesLoop 50209 PUSH BC Stash the attribute counter on the stack.
50210 JR DrawPicture_FetchByte Jump to DrawPicture_FetchByte to write the next attribute; it comes back to DrawPicture_NextAttribute.
DrawPicture_NextAttribute 50212 POP BC Restore the attribute counter from the stack.
50213 DEC BC Decrease the attribute counter by one.
50214 INC DE Move on to the next attribute.
50215 LD A,B Jump back to DrawPicture_AttributesLoop until the attribute counter is zero.
50216 OR C
50217 JR NZ,DrawPicture_AttributesLoop
50219 LD (IY+1),255 Write 255 to *DrawPicture_Third and *DrawPicture_Thirds. BASIC never POKEs these bytes, so the next picture again takes its screen third and number of thirds from its own record.
50223 LD (IY+2),255
50227 RET Return.
Write the next byte of picture data to *DE. While a run of repeated bytes is being written, bit 2 of *DrawPicture_Flags is set, B' holds the count and C' holds the value.
DrawPicture_FetchByte 50228 BIT 2,(IY+3) Jump to DrawPicture_ReadByte if no run is in progress.
50232 JR Z,DrawPicture_ReadByte
50234 EXX Switch to the shadow registers.
50235 DEC B Decrease the run count in B' by one.
50236 LD A,C A=the run value from C'.
50237 EXX Switch back to the normal registers.
50238 JR Z,DrawPicture_EndRun Jump to DrawPicture_EndRun if the run has finished.
50240 LD (DE),A Write the run value to *DE.
50241 JR DrawPicture_Continue Jump to DrawPicture_Continue.
DrawPicture_EndRun 50243 RES 2,(IY+3) Clear bit 2 of *DrawPicture_Flags, as the run has finished.
DrawPicture_ReadByte 50247 LD A,(HL) A=the next byte of picture data, and move HL on.
50248 INC HL
50249 AND A Jump to DrawPicture_WriteByte if it is not zero, to write it as it is.
50250 JR NZ,DrawPicture_WriteByte
50252 LD A,(HL) A zero byte starts a run. B'=the count.
50253 EXX
50254 LD B,A
50255 EXX
50256 INC HL Move HL on to the value.
50257 LD A,(HL) C'=the value (A holds it too).
50258 EXX
50259 LD C,A
50260 EXX
50261 INC HL Move HL on to the next byte of picture data.
50262 SET 2,(IY+3) Set bit 2 of *DrawPicture_Flags, as a run is in progress.
DrawPicture_WriteByte 50266 LD (DE),A Write the byte to *DE.
DrawPicture_Continue 50267 BIT 3,(IY+3) Jump back to DrawPicture_NextAttribute if the attributes are being drawn.
50271 JR NZ,DrawPicture_NextAttribute
50273 JR DrawPicture_NextByte Else jump back to DrawPicture_NextByte.
View the equivalent code in;
Prev: 50002 Up: Map Next: 50275