Prev: 8002 Up: Map Next: 8113
8006: 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 8006 CALL $007C Call the RET instruction at 007C, at the end of CH_ADD+1, which returns straight away.
DrawPicture_ReturnAddress 8009 DEC SP Move the stack pointer back down to the return address.
800A DEC SP
800B EX (SP),HL Swap it into HL, so HL=DrawPicture_ReturnAddress.
800C INC SP Move the stack pointer back up again.
800D INC SP
800E AND A Clear the carry flag ready for the subtraction.
800F LD DE,$0007 HL=DrawPicture_Number (DrawPicture_ReturnAddress less 0007).
8012 SBC HL,DE
8014 PUSH HL Stash the address of the parameters on the stack.
8015 POP IY Restore the address of the parameters from the stack into IY.
8017 LD DE,$012A HL=Graphics_Crosshair (DrawPicture_Number plus 012A), the first picture record.
801A ADD HL,DE
801B LD A,(IY+$00) A=the picture number from *DrawPicture_Number.
Skip over the records before the requested picture.
DrawPicture_FindPicture 801E DEC A Decrease the picture number by one.
801F JR Z,DrawPicture_Found Jump to DrawPicture_Found if HL points to the requested picture.
8021 LD E,(HL) DE=the length of this record, less one.
8022 INC HL
8023 LD D,(HL)
8024 ADD HL,DE Add it to HL, so HL points to the next record.
8025 JR DrawPicture_FindPicture Jump to DrawPicture_FindPicture.
DrawPicture_Found 8027 LD DE,$4000 DE=4000. This value is never used, as D and E are both set again before they are needed.
802A INC HL Move HL past the length, to the record's screen third.
802B INC HL
802C LD A,(IY+$01) A=*DrawPicture_Third.
802F INC A Increment A by one, so that FF becomes zero.
8030 JR NZ,DrawPicture_Unpack_0 Jump to DrawPicture_Unpack_0 if *DrawPicture_Third is not FF.
8032 LD A,(HL) Else write the record's screen third to *DrawPicture_Third.
8033 LD (IY+$01),A
DrawPicture_Unpack_0 8036 INC HL Move on to the record's number of thirds.
8037 LD A,(IY+$02) A=*DrawPicture_Thirds.
803A INC A Increment A by one, so that FF becomes zero.
803B JR NZ,DrawPicture_Unpack_1 Jump to DrawPicture_Unpack_1 if *DrawPicture_Thirds is not FF.
803D LD A,(HL) Else write the record's number of thirds to *DrawPicture_Thirds.
803E LD (IY+$02),A
DrawPicture_Unpack_1 8041 INC HL Move on to the record's flags.
8042 LD A,(HL) Copy the record's flags to *DrawPicture_Flags.
8043 LD (IY+$03),A
Make sure the picture fits on the screen.
8046 LD A,(IY+$01) A=*DrawPicture_Third.
8049 CP $03 Jump to DrawPicture_Unpack_2 if the screen third is less than 03.
804B JR C,DrawPicture_Unpack_2
804D LD (IY+$01),$00 Else start at the top third (write 00 to *DrawPicture_Third).
DrawPicture_Unpack_2 8051 LD A,(IY+$02) A=*DrawPicture_Thirds.
8054 CP $04 Jump to DrawPicture_Unpack_3 if the number of thirds is less than 04.
8056 JR C,DrawPicture_Unpack_3
8058 LD (IY+$02),$01 Else draw one third (write 01 to *DrawPicture_Thirds).
DrawPicture_Unpack_3 805C ADD A,(IY+$01) 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.
805F CP $04 Jump to DrawPicture_Unpack_4 if the picture ends on the screen (the total is less than 04).
8061 JR C,DrawPicture_Unpack_4
8063 LD (IY+$02),$01 Else draw one third (write 01 to *DrawPicture_Thirds).
DrawPicture_Unpack_4 8067 LD A,(IY+$02) A=*DrawPicture_Thirds.
806A AND A Jump to DrawPicture_Pixels if the number of thirds is not zero.
806B JR NZ,DrawPicture_Pixels
806D LD (IY+$02),$01 Else draw one third (write 01 to *DrawPicture_Thirds).
Draw the pixels.
DrawPicture_Pixels 8071 INC HL Move HL on to the start of the picture data.
8072 LD E,$00 E=00 (the left-hand column).
8074 LD A,(IY+$01) A=*DrawPicture_Third.
8077 ADD A,A Multiply it by 08 as each third of the screen is 08 pages long.
8078 ADD A,A
8079 ADD A,A
DrawPicture_PixelsHighByte 807A ADD A,$40 Add the high byte of the start of the screen (40). BASIC POKEs this byte to draw into a buffer instead.
807C 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.
807D LD C,A
807E LD B,$01 B=01 (one pass, for row order).
8080 BIT 0,(IY+$03) Jump to DrawPicture_PassLoop if bit 0 of *DrawPicture_Flags is set (row order).
8084 JR NZ,DrawPicture_PassLoop
8086 LD B,$20 Else B=20 (one pass for each column).
DrawPicture_PassLoop 8088 PUSH BC Stash the pass counter on the stack.
8089 LD B,(IY+$02) B=the number of thirds from *DrawPicture_Thirds.
DrawPicture_ThirdLoop 808C PUSH BC Stash the thirds counter on the stack.
808D LD B,$08 B=08 (character rows in a third).
DrawPicture_RowLoop 808F PUSH BC Stash the character row counter on the stack.
8090 LD B,$08 B=08 (pixel lines in a character row).
DrawPicture_LineLoop 8092 PUSH BC Stash the pixel line counter on the stack.
8093 LD B,$01 B=01 (one byte, for column order).
8095 BIT 0,(IY+$03) Jump to DrawPicture_Unpack_5 if bit 0 of *DrawPicture_Flags is clear (column order).
8099 JR Z,DrawPicture_Unpack_5
809B LD B,$20 Else B=20 (a whole pixel line, for row order).
DrawPicture_Unpack_5 809D PUSH DE Stash the screen address of this pixel line on the stack.
DrawPicture_ByteLoop 809E PUSH BC Stash the byte counter on the stack.
809F JR DrawPicture_FetchByte Jump to DrawPicture_FetchByte to write the next byte; it comes back to DrawPicture_NextByte.
DrawPicture_NextByte 80A1 POP BC Restore the byte counter from the stack.
80A2 INC DE Move right to the next screen byte.
80A3 DJNZ DrawPicture_ByteLoop Decrease the byte counter by one and loop back to DrawPicture_ByteLoop until it is zero.
80A5 POP DE Restore the screen address of this pixel line from the stack.
80A6 POP BC Restore the pixel line counter from the stack.
80A7 INC D Move down to the next pixel line.
80A8 DJNZ DrawPicture_LineLoop Decrease the pixel line counter by one and loop back to DrawPicture_LineLoop until all 08 pixel lines are done.
80AA LD A,D Move D back up to the top pixel line of this character row (subtract 08).
80AB SUB $08
80AD LD D,A
80AE LD A,E Move down to the next character row (add 20 to E).
80AF ADD A,$20
80B1 LD E,A
80B2 POP BC Restore the character row counter from the stack.
80B3 DJNZ DrawPicture_RowLoop Decrease the character row counter by one and loop back to DrawPicture_RowLoop until all 08 character rows are done.
80B5 LD A,D Move down to the next third (add 08 to D). E has gone back round to the same column.
80B6 ADD A,$08
80B8 LD D,A
80B9 POP BC Restore the thirds counter from the stack.
80BA DJNZ DrawPicture_ThirdLoop Decrease the thirds counter by one and loop back to DrawPicture_ThirdLoop until all the thirds are done.
80BC LD D,C Move D back up to the top of the picture (D=C).
80BD INC E Move right to the next column.
80BE POP BC Restore the pass counter from the stack.
80BF 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 80C1 LD E,$00 E=00.
DrawPicture_AttributesHighByte 80C3 LD A,$58 A=58 the high byte of the start of the attribute file. BASIC POKEs this byte to draw into a buffer instead.
80C5 ADD A,(IY+$01) Add the screen third.
80C8 LD D,A D=A, so DE holds the address of the first attribute of the picture.
80C9 LD B,(IY+$02) BC=the number of attributes to draw: 256 for each third (B=*DrawPicture_Thirds and C=00).
80CC LD C,E
80CD SET 3,(IY+$03) Set bit 3 of *DrawPicture_Flags, so that DrawPicture_FetchByte comes back to DrawPicture_NextAttribute.
DrawPicture_AttributesLoop 80D1 PUSH BC Stash the attribute counter on the stack.
80D2 JR DrawPicture_FetchByte Jump to DrawPicture_FetchByte to write the next attribute; it comes back to DrawPicture_NextAttribute.
DrawPicture_NextAttribute 80D4 POP BC Restore the attribute counter from the stack.
80D5 DEC BC Decrease the attribute counter by one.
80D6 INC DE Move on to the next attribute.
80D7 LD A,B Jump back to DrawPicture_AttributesLoop until the attribute counter is zero.
80D8 OR C
80D9 JR NZ,DrawPicture_AttributesLoop
80DB LD (IY+$01),$FF Write FF 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.
80DF LD (IY+$02),$FF
80E3 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 80E4 BIT 2,(IY+$03) Jump to DrawPicture_ReadByte if no run is in progress.
80E8 JR Z,DrawPicture_ReadByte
80EA EXX Switch to the shadow registers.
80EB DEC B Decrease the run count in B' by one.
80EC LD A,C A=the run value from C'.
80ED EXX Switch back to the normal registers.
80EE JR Z,DrawPicture_EndRun Jump to DrawPicture_EndRun if the run has finished.
80F0 LD (DE),A Write the run value to *DE.
80F1 JR DrawPicture_Continue Jump to DrawPicture_Continue.
DrawPicture_EndRun 80F3 RES 2,(IY+$03) Clear bit 2 of *DrawPicture_Flags, as the run has finished.
DrawPicture_ReadByte 80F7 LD A,(HL) A=the next byte of picture data, and move HL on.
80F8 INC HL
80F9 AND A Jump to DrawPicture_WriteByte if it is not zero, to write it as it is.
80FA JR NZ,DrawPicture_WriteByte
80FC LD A,(HL) A zero byte starts a run. B'=the count.
80FD EXX
80FE LD B,A
80FF EXX
8100 INC HL Move HL on to the value.
8101 LD A,(HL) C'=the value (A holds it too).
8102 EXX
8103 LD C,A
8104 EXX
8105 INC HL Move HL on to the next byte of picture data.
8106 SET 2,(IY+$03) Set bit 2 of *DrawPicture_Flags, as a run is in progress.
DrawPicture_WriteByte 810A LD (DE),A Write the byte to *DE.
DrawPicture_Continue 810B BIT 3,(IY+$03) Jump back to DrawPicture_NextAttribute if the attributes are being drawn.
810F JR NZ,DrawPicture_NextAttribute
8111 JR DrawPicture_NextByte Else jump back to DrawPicture_NextByte.
View the equivalent code in;
Prev: 8002 Up: Map Next: 8113