Prev: 32770 Up: Map Next: 33043
32774: 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 32774 CALL 124 Call the RET instruction at 0124, at the end of CH_ADD+1, which returns straight away.
DrawPicture_ReturnAddress 32777 DEC SP Move the stack pointer back down to the return address.
32778 DEC SP
32779 EX (SP),HL Swap it into HL, so HL=DrawPicture_ReturnAddress.
32780 INC SP Move the stack pointer back up again.
32781 INC SP
32782 AND A Clear the carry flag ready for the subtraction.
32783 LD DE,7 HL=DrawPicture_Number (DrawPicture_ReturnAddress less 0007).
32786 SBC HL,DE
32788 PUSH HL Stash the address of the parameters on the stack.
32789 POP IY Restore the address of the parameters from the stack into IY.
32791 LD DE,298 HL=Graphics_Crosshair (DrawPicture_Number plus 0298), the first picture record.
32794 ADD HL,DE
32795 LD A,(IY+0) A=the picture number from *DrawPicture_Number.
Skip over the records before the requested picture.
DrawPicture_FindPicture 32798 DEC A Decrease the picture number by one.
32799 JR Z,DrawPicture_Found Jump to DrawPicture_Found if HL points to the requested picture.
32801 LD E,(HL) DE=the length of this record, less one.
32802 INC HL
32803 LD D,(HL)
32804 ADD HL,DE Add it to HL, so HL points to the next record.
32805 JR DrawPicture_FindPicture Jump to DrawPicture_FindPicture.
DrawPicture_Found 32807 LD DE,16384 DE=16384. This value is never used, as D and E are both set again before they are needed.
32810 INC HL Move HL past the length, to the record's screen third.
32811 INC HL
32812 LD A,(IY+1) A=*DrawPicture_Third.
32815 INC A Increment A by one, so that 255 becomes zero.
32816 JR NZ,DrawPicture_Unpack_0 Jump to DrawPicture_Unpack_0 if *DrawPicture_Third is not 255.
32818 LD A,(HL) Else write the record's screen third to *DrawPicture_Third.
32819 LD (IY+1),A
DrawPicture_Unpack_0 32822 INC HL Move on to the record's number of thirds.
32823 LD A,(IY+2) A=*DrawPicture_Thirds.
32826 INC A Increment A by one, so that 255 becomes zero.
32827 JR NZ,DrawPicture_Unpack_1 Jump to DrawPicture_Unpack_1 if *DrawPicture_Thirds is not 255.
32829 LD A,(HL) Else write the record's number of thirds to *DrawPicture_Thirds.
32830 LD (IY+2),A
DrawPicture_Unpack_1 32833 INC HL Move on to the record's flags.
32834 LD A,(HL) Copy the record's flags to *DrawPicture_Flags.
32835 LD (IY+3),A
Make sure the picture fits on the screen.
32838 LD A,(IY+1) A=*DrawPicture_Third.
32841 CP 3 Jump to DrawPicture_Unpack_2 if the screen third is less than 3.
32843 JR C,DrawPicture_Unpack_2
32845 LD (IY+1),0 Else start at the top third (write 0 to *DrawPicture_Third).
DrawPicture_Unpack_2 32849 LD A,(IY+2) A=*DrawPicture_Thirds.
32852 CP 4 Jump to DrawPicture_Unpack_3 if the number of thirds is less than 4.
32854 JR C,DrawPicture_Unpack_3
32856 LD (IY+2),1 Else draw one third (write 1 to *DrawPicture_Thirds).
DrawPicture_Unpack_3 32860 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.
32863 CP 4 Jump to DrawPicture_Unpack_4 if the picture ends on the screen (the total is less than 4).
32865 JR C,DrawPicture_Unpack_4
32867 LD (IY+2),1 Else draw one third (write 1 to *DrawPicture_Thirds).
DrawPicture_Unpack_4 32871 LD A,(IY+2) A=*DrawPicture_Thirds.
32874 AND A Jump to DrawPicture_Pixels if the number of thirds is not zero.
32875 JR NZ,DrawPicture_Pixels
32877 LD (IY+2),1 Else draw one third (write 1 to *DrawPicture_Thirds).
Draw the pixels.
DrawPicture_Pixels 32881 INC HL Move HL on to the start of the picture data.
32882 LD E,0 E=0 (the left-hand column).
32884 LD A,(IY+1) A=*DrawPicture_Third.
32887 ADD A,A Multiply it by 8 as each third of the screen is 8 pages long.
32888 ADD A,A
32889 ADD A,A
DrawPicture_PixelsHighByte 32890 ADD A,64 Add the high byte of the start of the screen (64). BASIC POKEs this byte to draw into a buffer instead.
32892 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.
32893 LD C,A
32894 LD B,1 B=1 (one pass, for row order).
32896 BIT 0,(IY+3) Jump to DrawPicture_PassLoop if bit 0 of *DrawPicture_Flags is set (row order).
32900 JR NZ,DrawPicture_PassLoop
32902 LD B,32 Else B=32 (one pass for each column).
DrawPicture_PassLoop 32904 PUSH BC Stash the pass counter on the stack.
32905 LD B,(IY+2) B=the number of thirds from *DrawPicture_Thirds.
DrawPicture_ThirdLoop 32908 PUSH BC Stash the thirds counter on the stack.
32909 LD B,8 B=8 (character rows in a third).
DrawPicture_RowLoop 32911 PUSH BC Stash the character row counter on the stack.
32912 LD B,8 B=8 (pixel lines in a character row).
DrawPicture_LineLoop 32914 PUSH BC Stash the pixel line counter on the stack.
32915 LD B,1 B=1 (one byte, for column order).
32917 BIT 0,(IY+3) Jump to DrawPicture_Unpack_5 if bit 0 of *DrawPicture_Flags is clear (column order).
32921 JR Z,DrawPicture_Unpack_5
32923 LD B,32 Else B=32 (a whole pixel line, for row order).
DrawPicture_Unpack_5 32925 PUSH DE Stash the screen address of this pixel line on the stack.
DrawPicture_ByteLoop 32926 PUSH BC Stash the byte counter on the stack.
32927 JR DrawPicture_FetchByte Jump to DrawPicture_FetchByte to write the next byte; it comes back to DrawPicture_NextByte.
DrawPicture_NextByte 32929 POP BC Restore the byte counter from the stack.
32930 INC DE Move right to the next screen byte.
32931 DJNZ DrawPicture_ByteLoop Decrease the byte counter by one and loop back to DrawPicture_ByteLoop until it is zero.
32933 POP DE Restore the screen address of this pixel line from the stack.
32934 POP BC Restore the pixel line counter from the stack.
32935 INC D Move down to the next pixel line.
32936 DJNZ DrawPicture_LineLoop Decrease the pixel line counter by one and loop back to DrawPicture_LineLoop until all 8 pixel lines are done.
32938 LD A,D Move D back up to the top pixel line of this character row (subtract 8).
32939 SUB 8
32941 LD D,A
32942 LD A,E Move down to the next character row (add 32 to E).
32943 ADD A,32
32945 LD E,A
32946 POP BC Restore the character row counter from the stack.
32947 DJNZ DrawPicture_RowLoop Decrease the character row counter by one and loop back to DrawPicture_RowLoop until all 8 character rows are done.
32949 LD A,D Move down to the next third (add 8 to D). E has gone back round to the same column.
32950 ADD A,8
32952 LD D,A
32953 POP BC Restore the thirds counter from the stack.
32954 DJNZ DrawPicture_ThirdLoop Decrease the thirds counter by one and loop back to DrawPicture_ThirdLoop until all the thirds are done.
32956 LD D,C Move D back up to the top of the picture (D=C).
32957 INC E Move right to the next column.
32958 POP BC Restore the pass counter from the stack.
32959 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 32961 LD E,0 E=0.
DrawPicture_AttributesHighByte 32963 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.
32965 ADD A,(IY+1) Add the screen third.
32968 LD D,A D=A, so DE holds the address of the first attribute of the picture.
32969 LD B,(IY+2) BC=the number of attributes to draw: 256 for each third (B=*DrawPicture_Thirds and C=0).
32972 LD C,E
32973 SET 3,(IY+3) Set bit 3 of *DrawPicture_Flags, so that DrawPicture_FetchByte comes back to DrawPicture_NextAttribute.
DrawPicture_AttributesLoop 32977 PUSH BC Stash the attribute counter on the stack.
32978 JR DrawPicture_FetchByte Jump to DrawPicture_FetchByte to write the next attribute; it comes back to DrawPicture_NextAttribute.
DrawPicture_NextAttribute 32980 POP BC Restore the attribute counter from the stack.
32981 DEC BC Decrease the attribute counter by one.
32982 INC DE Move on to the next attribute.
32983 LD A,B Jump back to DrawPicture_AttributesLoop until the attribute counter is zero.
32984 OR C
32985 JR NZ,DrawPicture_AttributesLoop
32987 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.
32991 LD (IY+2),255
32995 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 32996 BIT 2,(IY+3) Jump to DrawPicture_ReadByte if no run is in progress.
33000 JR Z,DrawPicture_ReadByte
33002 EXX Switch to the shadow registers.
33003 DEC B Decrease the run count in B' by one.
33004 LD A,C A=the run value from C'.
33005 EXX Switch back to the normal registers.
33006 JR Z,DrawPicture_EndRun Jump to DrawPicture_EndRun if the run has finished.
33008 LD (DE),A Write the run value to *DE.
33009 JR DrawPicture_Continue Jump to DrawPicture_Continue.
DrawPicture_EndRun 33011 RES 2,(IY+3) Clear bit 2 of *DrawPicture_Flags, as the run has finished.
DrawPicture_ReadByte 33015 LD A,(HL) A=the next byte of picture data, and move HL on.
33016 INC HL
33017 AND A Jump to DrawPicture_WriteByte if it is not zero, to write it as it is.
33018 JR NZ,DrawPicture_WriteByte
33020 LD A,(HL) A zero byte starts a run. B'=the count.
33021 EXX
33022 LD B,A
33023 EXX
33024 INC HL Move HL on to the value.
33025 LD A,(HL) C'=the value (A holds it too).
33026 EXX
33027 LD C,A
33028 EXX
33029 INC HL Move HL on to the next byte of picture data.
33030 SET 2,(IY+3) Set bit 2 of *DrawPicture_Flags, as a run is in progress.
DrawPicture_WriteByte 33034 LD (DE),A Write the byte to *DE.
DrawPicture_Continue 33035 BIT 3,(IY+3) Jump back to DrawPicture_NextAttribute if the attributes are being drawn.
33039 JR NZ,DrawPicture_NextAttribute
33041 JR DrawPicture_NextByte Else jump back to DrawPicture_NextByte.
View the equivalent code in;
Prev: 32770 Up: Map Next: 33043