0 Members and 4 Guests are viewing this topic.
GetPixel: ; Inputs: ; A = x-coordinate, L = y-coordinate ; Outputs: ; A = a bitmask for the pixel, HL = the address of the byte containing the pixel ld h, 0 ld d, h ld e, l add hl, hl ; the graph screen is arranged as an array of 12 x 64 bytes (12 bytes per row, 64 rows) add hl, de ; so in order to find the correct byte we first multiply the y coordinate by 12... add hl, hl add hl, hl ld e, a ; ...then add the x-coordinate/8 (because there are 8 pixels per byte) srl e srl e srl e add hl, de ld de, PlotSScreen add hl, de ; now hl contains the address of the byte and 7 ; this is the tricky part: finding the bit. Because there are 8 bits in each byte, we can do x-coordinate modulo 8 ld b, a ; and that will return a number (0-7). That number tells us which bit to use (where "7" represents bit 0, and "0" represents bit 7) ld a, $80 ; here we load the initial bitmask into A ret z ; if the "and 7" command returned 0, then the mask doesn't need to be rotated, so we can just return now._loop: rrca ; otherwise, rotate the bitmask B times (remember we loaded the result of "and 7" into B earlier) djnz _loop ret
call GetPixel or (hl) ; HL holds the byte, and A holds the mask, so we simply use or to turn on the masked pixel... ld (hl), a ;...then load it into the buffer
call GetPixel xor (hl) ; Same idea as before only using xor to invert ld (hl), a
call GetPixel cpl ; because AND clears any pixels that are already set, you have to invert the mask first and (hl) ld (hl), a
; Inputs: ; D is the x-coordinate, L is the starting y-coordinate and E is the ending y-coordinate ; make sure L is less than E, otherwise it'll go KABLOOIE!! or something... ld a, e sub l ; get the length of the line by subtracting L from E ret z ; if the length is zero, we don't need to draw it, so just return push af ; save the length of the line into the stack so we don't lose it ld a, d ; put the x-coordinate in A call GetPixel ; now A is the mask that we'll just use for all the rows and HL is the address of the starting byte for the line pop BC ; we pushed AF before, so now we pop to BC, so now B is the line length ld de, 12 ld c, a ; save the bitmask to C so we don't lose it_vloop: ld a, c ; restore the mask or (hl) ; turn the pixel on ld (hl), a add hl, de ; each row is 12 bytes, so to go to the next row we can just add 12 (which we stored in DE) to HL djnz _vloop ret
; Inputs: ; L =is the y-coordinate, D is the starting x-coordinate and E is the ending x-coordinate ; again, make sure D is less than E ld a, e ; get length, return if 0 sub d ret z srl a ; divide line length by 8 to find the number of bytes this line will span across (minus 1) srl a srl a push af ; save it for later ld h, 0 ; get the address of the byte containing the first pixel of the line ld b, h ; same code as in GetPixel, just using BC instead of DE because DE is currently occupied by our precious x-coordinates ld c, l add hl, hl add hl, bc add hl, hl add hl, hl ld c, d srl c srl c srl c add hl, bc ld bc, PlotSScreen add hl, bc ; now hl is the starting byte of the line call GetMask ;get the mask for the left end of the line pop bc ; length of the line goes into b ld c, a ; save the mask to c ld a, b or a ; if b is 0, mask the end of the line as well jr z, _lastbyte ld a, c_hloop: or (hl) ; apply the mask ld (hl), a inc hl ld a, $FF ; after the first byte, the other bytes (except the last) will be masked with $FF so all pixels are turned on djnz _hloop_lastbyte: ld d, e dec d call GetMask ; get the mask for the right end of the line srl a ; because GetMask gives us the mask for the left end, we shift it one to the left and invert it to get the mask for the right end cpl and c ; get the similar bits between the previous mask and the current one (remember that if the length is less than 8, the masks for both the left and right ends have to be applied to the same byte) or (hl) ; now we apply the mask ld (hl), a ret ; and we're done! GetMask: ; this is also the same idea as getting the mask in GetPixel, only instead of rotating $80 we do a logical shift right on $FF to retrieve the mask for the ends of the line ld a, d and 7 ld b, a ld a, $FF ret z_maskloop: sra a djnz _maskloop: ret
;============================================DrawHoriz:;============================================;Input:; l is the row to draw to; a is the type of line to draw; 0 is a white line; 1 is a black line; 2 is an inverted line;============================================ ld h,0 ;2600 7 ld b,h ;44 4 ld c,l ;4D 4 add hl,bc ;09 11 add hl,bc ;09 11 add hl,hl ;29 11 add hl,hl ;29 11 ld bc,9340h ;014093 10 add hl,bc ;09 11 ld b,12 ;060C 7 or a ;B7 4 Total: 91 jr z,DrawHoriz ;2804 White: 12+318+91 dec a ;3C 4 jr nz,DrawInvH ;2006 Black: 4+4+7+7+318+91 dec a ;3C 4DrawHoriz: Total: 5 bytes, 318 cycles ld (hl),a ;77 7 84 inc hl ;23 6 72 djnz DrawHoriz ;10FC 13*11+8 152 ret ;C9 10 10DrawInv: Total: 7 bytes, 450 cycles Invert: 4+7+12+450+91 ld a,(hl) ;7E 7 84 cpl ;2F 4 48 ld (hl),a ;77 7 84 inc hl ;23 6 72 djnz DrawInv ;10FA 13*11+8 152 ret ;C9 10 10;============================================;Stats:;============================================;Size: 33 bytes;Speed:; White: 12+318+91 421 cycles; Black: 4+4+7+7+318+91 431 cycles; Inv: 4+7+12+450+91 564 cycles;============================================
;============================================DrawVert:;============================================;Inputs:; a is the column; c is the method; 0 draws a white line; 1 draws a black line; 2 draws an inverted line;============================================ ld b,a ;47 rrca \ rrca \ rrca ;0F0F0F and 1Fh ;E60F add 40h ;C640 ld l,a ;6F ld h,93h ;2693 ld a,b ;78 and 7 ;E607 inc a ;3C ld b,a ;47 ld a,1 ;3E01GetPixelMask: rrca ;0F djnz GetPixelMask ;10FD dec c ;0D jr nz,DrawVertW ;200F ld e,a ;5F ld bc,400Ch ;010C40DrawVertBLoop: ld a,e ;7B or (hl) ;B6 ld (hl),a ;77 ld a,b ;78 ld b,0 ;0600 add hl,bc ;09 ld b,a ;47 djnz DrawVertBLoop ;10F6 ret ;C9DrawVertW: dec c ;0D jr z,DrawVertI ;2001 cpl a ;2FDrawVertI: ld e,a ;5F ld bc,400Ch ;010C40DrawVertILoop: ld a,e ;7B xor (hl) ;AE ld (hl),a ;77 ld a,b ;78 ld b,0 ;0600 add hl,bc ;09 ld b,a ;47 djnz DrawVertBLoop ;10F6 ret ;C9;============================================;Stats:;============================================;Size: 58 bytes;Speed: ... too lazy to calculate at the moment; White: ; Black: ; Inv: ;============================================
;============================================PlotPixel: ;45 bytes;============================================;Inputs:; b is the x coordinate; c is the y coordinate; e is the method; 0 draws a white line; 1 draws a black line; 2 draws an inverted line;============================================ ld a,b ;78 ld b,0 ;0600 ld h,b ;60 ld l,c ;69 add hl,hl ;29 add hl,bc ;09 add hl,hl ;29 add hl,hl ;29 ld bc,9340h ;014093 add hl,bc ;09 ld b,a ;47 rrca ;0F rrca ;0F rrca ;0F and 1Fh ;E60F ld c,a ;4F ld a,b ;78 ld b,0 ;0600 add hl,bc ;09 and 7 ;E607 ld b,a ;47 inc b ;04 ld a,1 ;3E01GetMask: rrca ;0F djnz GetMask ;10FD dec e ;1D jr nz,DrawWPix ;2003 or (hl) ;B6 ld (hl),a ;77 ret ;C9DrawWPix: dec e ;1D jr z,DrawIPix ;2801 cpl ;2FDrawIPix: xor (hl) ;AE ld (hl),a ;77 ret ;C9
;###############################;input: de = xy; hl = xyline: push hl push de ld b, 2fastLinePreLoop: ld a, d call xClipCheck ld d, a ld a, e call yClipCheck ld e, a ex de, hl djnz fastLinePreLoop or a sbc hl, de add hl, de jr nc, noSwitch ex de, hlnoSwitch: ld a, h sub d ld b, a ld a, l sub e ld c, 0 jp p, positivoz neg ld c, 1positivoz: cp b jr nc, yMajorxMajor: inc b ld h, a ld a, b call setUpForLoop bit 0, c jr z, notNeggaz inc hnotNeggaz: ld c, d xMajorLoop: push bc ld de, (increment) add hl, de push hl ld d, c ld e, h call getPixel ld a, c call middlePartOfLoop pop hl pop bc inc c djnz xMajorLoop pop de pop hl retyMajor: bit 0, c jr z, alreadySetUp ex de, hlalreadySetUp: inc a ld h, b ld b, a call setUpForLoop bit 0, c jr z, notNegga inc dnotNegga: ld c, h ld h, dyMajorLoop: push bc ld de, (increment) add hl, de push hl ld e, c ld d, h ld b, h call getPixel ld a, b call middlePartOfLoop pop hl pop bc inc c djnz yMajorLoop pop de pop hl ret middlePartOfLoop: ld c, 128 and %00000111 jr z, alreadyDone ld b, abyteLoop: srl c djnz byteLoopalreadyDone: ld a, c or (hl) ld (hl), a retsetUpForLoop: ld l, $FF push de push bc call divHLbyA pop bc bit 0, c call nz, negHL ld (increment), hl pop hl ld d, h ld h, l ld l, 0 retyClipCheck: ;super efficient, no rets call isANeg cp 64 ret c ld a, 63xClipCheck: call isANeg cp 96 ret c ld a, 95isANeg: or a ret p xor a ret