0 Members and 3 Guests are viewing this topic.
drawtile:;DE points to the sprite data;BC = (y,x); draw an 8x8 tile where X is on [0,11] and Y is on [0,7] ld a,b add a,a add a,b add a,a add a,a add a,a ld h,0 ld b,h ld l,a add hl,hl add hl,hl add hl,bc ld bc,(DrawBufPtr) add hl,bc ld bc,12 ld a,8 ex de,hl ; 32 ldi ;128 ex de,hl ; 32 add hl,bc ; 88 inc c ; 32 dec a ; 32 jr nz,$-7 ; 91 ret
drawtile:;DE points to the sprite;BC = (y,x);X*64 or a ld a,c ld l,0 rra rr l rra rr l ld h,a;y*8 ld a,b add a,a add a,a add a,a add a,l ld l,a ld bc,(DrawBufPtr) add hl,bc ex de,hl ld bc,8 ldir ret
push hl \ pop ix;IX points to where it gets drawn;DE is the sprite layer ld a,(de) ; 7 inc de ; 6 ld (ix),a ;19 ld a,(de) ; 7 inc de ; 6 ld (ix+12),a ;19 ld a,(de) ; 7 inc de ; 6 ld (ix+24),a ;19 ld a,(de) ; 7 inc de ; 6 ld (ix+36),a ;19 ld a,(de) ; 7 inc de ; 6 ld (ix+48),a ;19 ld a,(de) ; 7 inc de ; 6 ld (ix+60),a ;19 ld a,(de) ; 7 inc de ; 6 ld (ix+72),a ;19 ld a,(de) ; 7 ld (ix+84),a ;19 ret
PutSprite8x8:;Note: No clipping.;Inputs:; BC = (x,y); IX points to the sprite; 1871 worst-case ld a,b and $F8 ld h,0 rla \ rl h rla \ rl h rla \ rl h ld l,a ld a,b ld b,0 add hl,bc ld bc,9340h add hl,bc;HL points to the first byte to draw at and 7 jr nz,crossedbound push ix \ pop de ld b,8 ld a,(de) xor (hl) ld (hl),a inc hl inc de djnz $-5 retcrossedbound: ld b,a dec a ld (smc_jump1),a ld (smc_jump2),a ld a,1 rrca djnz $-1 dec a ld e,a ld c,8;E is the mask;IX points to the sprite;HL points to where to drawdrawloop1: ld a,(ix) .db 18h ;start of jr *smc_jump1: .db 0 rlca rlca rlca rlca rlca rlca rlca and e xor (hl) ld (hl),a inc ix inc hl dec c jr nz,drawloop1 ld c,56 add hl,bc ld a,e cpl ld e,a ld c,8drawloop2: ld a,(ix-8) .db 18h ;start of jr *smc_jump2: .db 0 rlca rlca rlca rlca rlca rlca rlca and e xor (hl) ld (hl),a inc ix inc hl dec c jr nz,drawloop2 ret
#define lcddelay() in a,(16) \ rlca \ jr c,$-3 ld a,5 out (16),a lcddelay() ld a,80h out (16),a ld hl,9340h lcddelay() ld a,20hcol: out (16),a push af ld bc,4011hrow: lcddelay() outi jr nz,row lcddelay() pop af inc a cp 2Ch jr nz,col ret
.org 9D93h .db $BB,$6DStart: ld a,5 ;set the increment mode, only needs to be done once out (16),a lcddelay() ld a,80h ;set the row pointer, only needs to be done once, since the LCD update routine leaves it where it started. out (16),aMain:<code>UpdateLCD: ld hl,9340h ld a,20hcol: out (16),a push af ld bc,4011hrow: lcddelay() outi jr nz,row lcddelay() pop af inc a cp 2Ch jr nz,col ret
;GetPixelLoc;Inputs:; BC =(x,y); DE is the buffer on which to draw;Outputs:; Returns HL pointing to the byte where the pixel gets plotted; Returns A as a mask; NC returned if out of bounds, else C if in bounds ld a,c \ cp 64 \ ret nc ld a,b \ cp 96 \ ret nc and $F8 ld h,0 rla \ rl h rla \ rl h rla \ rl h ld l,a ld a,b ld b,0 add hl,bc add hl,de;HL points to the first byte to draw at and 7 ld b,a ld a,1 inc b rrca \ djnz $-1 scf ret
ld hl,9340h ;gbuf ld de,64 ld c,eloop: or a ld b,12 rr (hl) push af \ add hl,de \ pop af djnz $-5 dec h \ dec h \ dec h inc l dec c jr nz,loop ret
;RectangleErase can be optimised to be much faster if you make it its own routine using cpl \ and (hl) for logic. Currently, it uses RectangleOR \ RectangleXOR;Included Routines;======================;Inputs:; B = Height; C = Width; D = X (leftmost); E = Y (upper);RectangleBoxEraseFill; Draws a box with a black border, interior is erased.; Returns B-2, C-2, D+1, E+1;RectArrowXOR; Draws an arrow pointing right with XOR logic; Returns BC,DE unchanged;RectangleMenu; Draws a box with rounded edges; Returns D+1,C+2, B and E unchanged;RectangleOR; Draws a black rectangle; Returns BC,DE unchanged;RectangleXOR; Inverts the region of the screen; Returns BC,DE unchanged;RectangleErase; Draws a white rectangle; Returns BC,DE unchangedRectangleBoxEraseFill: call RectangleOR inc d inc e dec b dec b dec c dec c jp RectangleXORRectArrowXOR: push de push bc ld a,b cp c jr c,$+3 ld b,c ld c,1;B is now the smaller of the two;C is 1 call RectangleXOR inc d \ inc e djnz $+5 pop bc pop de ret djnz $-10 jr $-5RectangleMenu: call RectangleErase push bc \ push de inc e \ dec b \ dec b call RectangleXOR pop de \ pop bc inc d \ dec c \ dec c jr RectangleXORRectangleErase: call RectangleORRectangleXOR:;Inputs:; DE is (x,y); BC is (h,w);Outputs: push de push bc call RectMain jr nz,$+11 ld a,c xor (hl) ;logic ld (hl),a inc hl djnz $-4 jp EndRect ld d,a ;number of columns before last col ld e,b ld a,(rect_FirstByte) ld c,axorrectcol: ld b,e ;height push hlxorrectloop: ld a,(hl) xor c ;logic ld (hl),a inc hl djnz xorrectloop pop hl ld c,64 add hl,bc ld c,-1 dec d jp m,endrect jr nz,xorrectcol ld bc,(rect_LastByte) jp xorrectcolRectangleOR:;Inputs:; DE is (x,y); BC is (h,w);Outputs: push de push bc call RectMain jr nz,$+11 ld a,c or (hl) ;logic ld (hl),a inc hl djnz $-4 jp EndRect ld d,a ;number of columns before last col ld e,b ld a,(rect_FirstByte) ld c,aorrectcol: ld b,e ;height push hlorrectloop: ld a,(hl) or c ;logic ld (hl),a inc hl djnz orrectloop pop hl ld c,64 add hl,bc ld c,-1 dec d jp m,endrect jr nz,orrectcol ld bc,(rect_LastByte) jp orrectcolEndRect: pop bc pop de retRectMain:;Inputs:; DE is (x,y); BC is (h,w);Outputs:; returns z if it is all in one column, else it returns the number of columns; HL points to the start byte; (rect_FirstByte), (rect_LastByte); A is negative the number of columns; BC is (h,w);;If it is a single column wide, C is the mask, B is the height ld a,d and %11111000 ld h,0 rla \ rl h rla \ rl h rla \ rl h ld l,a ld a,d ld d,0 add hl,de;HL points to the byte it will start on push hl ld d,a push bc call ComputeByte ld (rect_FirstByte),a ex (sp),hl ld a,d cpl and 7 inc a ld b,a ld a,l sub b ex (sp),hl call ComputeByte cpl ld (rect_LastByte),a;last and first byte are computed ld a,d and %11111000 ld e,a ld a,d add a,c and %11111000 pop hl ex (sp),hl ld bc,(DrawBufPtr) add hl,bc pop bc sub e rrca rrca rrca and %00011111 ret nz ld de,(rect_FirstByte) ld a,d \ and e ld c,a xor a retComputeByte: and 7 ld b,a ld a,80h jr z,$+5 rrca djnz $-1 add a,a dec a ret
Yeah, in my app the shadow registers are free game (the interrupt routine preserves them). As for using IX, it depends on where it is used, because something like ld a,(ix+n) is 19 t-states, versus 7 for ld a,(hl).
ld ix,gBuf+128 ld b,64shiftrightloop: srl (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64) \ inc ixh ;100 rr (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64) \ inc ixh ;100 rr (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64) ;92 dec ixh \ dec ixh \ inc ix ; 26 djnz shiftrightloop ret
interrupt: ;19 ex af, af' ;4 exx ;4 out ($31), a ;11 a = 3 outi ;16 jr z, nextColumm ;7 exx ;4 ex af, af' ;4 ei ;4 ret ;10 ;83 total
;RAM required:;fmt_leftmost 1 byte , define the left edge of where text can be drawn;fmt_rightmost 1 byte , define the right edge of where text can be drawn;fmt_lower 1 byte , define the lower edge of where text can be drawn;fmt_upper 1 byte , define the upper edge of where text can be drawn;bit wordrawp,(iy+textflags) ;define your own location and whatnot;textcol 1 byte;textrow 1 byte;fontptr 2 bytes points to the nibble packed 4x6 fontset;DrawBufPtr 2 bytes, points to the buffer where text gets drawn;lFont_record is defined by the ti83plus.inc. 6 bytes are used;;Sample Fontset included;Inlcuded Routines, Input:; IGPutSFmt null-terminated string, directly following the call; GPutSFmt HL points to the null terminated string; GPutCFmt A is the character to display (all formatting applied); GPutC B is the character to display (some formatting applied);;All text is written to the buffer with OR logic.;These routines are modified for vertically aligned buffers, not the way the OS does it.IGPutSFmt:;Inputs:; The null-terminated string to display immediately follows the call.;Example:; call IGPutSFmt; .db "Hello World!",0 pop hl call GPutSFmt jp (hl)GPutSFmt:;Inputs:; HL points to the zero-terminated string to display;The following define a rectangular region for where text is allowed:; (fmt_leftmost); (fmt_rightmost); (fmt_lower); (fmt_upper); bit wordwrap,(iy+textflags) ld a,(hl) inc hl or a ret z push de push hl call GPutCFmt pop hl pop de jr GPutSFmtGPutCFmt:;Input:; A is the char to display ld b,a call GPutC;perform formatting based on indents, wordwrap bit wordwrap,(iy+textflags) ret z ld hl,(textcol) ld de,(fmt_rightmost) ld a,e sub l ret nc ld a,d sub h ret c ld a,(fmt_leftmost) ld l,a ld a,h add a,6 ld h,a ld (textcol),hl retGPutC:;Inputs:; (fontptr); (textcol); (textrow); B is the char to display ld a,$D6 cp b jr nz,charregnextline: ld a,(fmt_leftmost) ld (textcol),a ld a,(textrow) add a,6 ld (textrow),a retcharreg: ld hl,(fontptr) ld a,b ld c,b ld b,0 add hl,bc add hl,bc add hl,bc ld de,lFont_record ld b,3 ld a,(hl) and $F0 ld (de),a inc e ld a,(hl) rrca \ rrca rrca \ rrca and $F0 ld (de),a inc e inc hl djnz $-15 ld ix,lFont_record ld de,0406h ld bc,(textcol) ld hl,fmt_lower ld a,b cp (hl) \ ret nc;e is height add a,e sub (hl) jr c,$+6 neg add a,e ld e,a ld a,c dec l cp (hl) \ ret nc ld a,c add a,4 ld (textcol),a ld a,b ld b,c ld c,aORSprite8xY:;Note: No clipping.;Inputs:; BC = (x,y); IX points to the sprite; E is the height ld a,b and $F8 ld h,0 rla \ rl h rla \ rl h rla \ rl h ld l,a ld a,b ld b,0 add hl,bc ld bc,(DrawBufPtr) add hl,bc;HL points to the first byte to draw at and 7 jr nz,crossedbound ld b,e push ix \ pop de ld a,(de) xor (hl) ld (hl),a inc hl inc de djnz $-5 retcrossedbound: ld b,a ld d,a ld a,1 rrca djnz $-1 dec a ld c,e push bc ld e,a;E is the mask;IX points to the sprite;HL points to where to drawdrawloop1: ld a,(ix) ld b,d \ rrca \ djnz $-1 and e or (hl) ld (hl),a inc ix inc hl dec c jr nz,drawloop1 ld c,64 add hl,bc ld a,e cpl ld e,a pop bcdrawloop2: dec ix dec hl ld a,(ix) ld b,d \ rrca \ djnz $-1 and e or (hl) ld (hl),a dec c jr nz,drawloop2 ret;===============================================================FontSet:;===============================================================;00~7F.db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$8C,$EC,$80,$00,$00,$00,$00,$00,$00.db $24,$44,$20,$0A,$4A,$00,$00,$EA,$E0,$00,$4E,$40,$00,$04,$00,$00,$E4,$44,$E4,$2C,$00,$EC,$EC,$C0.db $74,$4C,$40,$62,$A2,$00,$C2,$4E,$00,$02,$48,$E0,$69,$96,$00,$AC,$88,$00,$E4,$40,$00,$68,$60,$E0.db $2E,$4E,$80,$C2,$C0,$E0,$06,$00,$00,$E8,$C8,$E0,$42,$F2,$40,$AD,$DD,$A0,$4E,$44,$40,$44,$4E,$40.db $00,$00,$00,$44,$40,$40,$AA,$A0,$00,$00,$00,$00,$00,$00,$00,$A2,$48,$A0,$4A,$4A,$50,$88,$80,$00.db $24,$44,$20,$84,$44,$80,$00,$40,$00,$04,$E4,$00,$00,$44,$80,$00,$E0,$00,$00,$00,$80,$22,$48,$80;FontNumbers.db $4A,$AA,$40,$4C,$44,$E0,$C2,$48,$E0,$C2,$42,$C0,$AA,$E2,$20,$E8,$C2,$C0,$68,$EA,$E0,$E2,$44,$40,$EA,$EA,$E0,$EA,$E2,$20;3Ah~3Fh.db $04,$04,$00,$04,$04,$80,$24,$84,$20,$0E,$0E,$00,$84,$24,$80,$C2,$40,$40.db $00,$00,$00,$4A,$EA,$A0,$CA,$CA,$C0,$68,$88,$60,$CA,$AA,$C0,$E8,$C8,$E0,$E8,$C8,$80,$68,$AA,$60.db $AA,$EA,$A0,$E4,$44,$E0,$62,$2A,$40,$AA,$CA,$A0,$88,$88,$E0,$AE,$AA,$A0,$CA,$AA,$A0,$EA,$AA,$E0.db $CA,$C8,$80,$EA,$AE,$60,$CA,$CA,$A0,$68,$42,$C0,$E4,$44,$40,$AA,$AA,$E0,$AA,$AA,$40,$AA,$AE,$A0.db $AA,$4A,$A0,$AA,$44,$40,$E2,$48,$E0,$4A,$EA,$40,$88,$42,$20,$C4,$44,$C0,$4A,$00,$00,$00,$00,$E0.db $84,$00,$00,$06,$AA,$60,$88,$CA,$C0,$06,$88,$60,$22,$6A,$60,$04,$AC,$60,$48,$C8,$80,$06,$A6,$2C.db $88,$CA,$A0,$40,$44,$40,$20,$22,$A4,$8A,$CA,$A0,$88,$88,$40,$0A,$EA,$A0,$0C,$AA,$A0,$04,$AA,$40.db $0C,$AC,$80,$06,$A6,$22,$0A,$C8,$80,$0C,$84,$C0,$4E,$44,$20,$0A,$AA,$E0,$0A,$AA,$40,$0A,$AE,$A0.db $0A,$44,$A0,$0A,$A6,$24,$0E,$24,$E0,$64,$84,$60,$44,$44,$40,$C4,$24,$C0,$05,$A0,$00,$E0,$E0,$E0;FontNumbers2.db $04,$AA,$A4,$04,$C4,$4E,$0C,$24,$8E,$0C,$24,$2C,$0A,$AE,$22,$0E,$8C,$2C,$06,$8E,$AE,$0E,$24,$44.db $0E,$AE,$AE,$0E,$AE,$22;Accented A.db $24,$AE,$A0,$84,$AE,$A0,$00,$00,$00,$A4,$AE,$A0;Accented a.db $24,$06,$A5,$42,$06,$A5,$4A,$06,$A5,$A0,$6A,$60;Accented E.db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00;Accented e.db $48,$4A,$C6,$42,$4A,$C6,$4A,$4A,$C6,$A0,$4A,$C6;Accented I.db $24,$0E,$4E,$84,$0E,$4E,$4A,$0E,$4E,$A0,$E4,$E0;Accented i.db $24,$04,$44,$84,$04,$44,$4A,$04,$44,$A0,$44,$40;Bombs... er, accented O.db $24,$69,$96,$84,$69,$96,$4A,$69,$96,$A0,$69,$96;Lowercase bombs.db $24,$06,$96,$84,$06,$96,$4A,$06,$96,$A0,$06,$96;Accented U.db $24,$AA,$A6,$84,$AA,$A6,$4A,$AA,$A6,$A0,$AA,$A6;Accented u.db $24,$0A,$A6,$84,$0A,$A6,$4A,$0A,$A6,$A0,$0A,$A6;Accented C,c,N,n.db $4A,$8A,$48,$06,$88,$6C,$5A,$0C,$AA,$5A,$0C,$AA;Other Puntuation.db $24,$00,$00,$84,$00,$00,$A0,$00,$00,$40,$48,$60;Upside-Down Exclamation Point Identical to lowercase i;Change to something else?.db $00,$00,$00;Greek.db $05,$AA,$50,$25,$65,$A0,$05,$A2,$20,$00,$4A,$E0,$34,$27,$96,$68,$E8,$60;[.db $64,$44,$60;Greek (continued).db $84,$25,$90,$0A,$AD,$80,$0F,$55,$90,$25,$56,$48,$F4,$24,$F0.db $07,$55,$40,$07,$A2,$10;Idunno howta do these.db $4E,$AE,$40,$69,$99,$69;CC~CF.db $E0,$A4,$A0,$E0,$A6,$24,$52,$50,$00,$00,$00,$A0,$26,$E6,$20;D0~D5.db $44,$40,$00,$22,$48,$80,$00,$60,$00,$C4,$8C,$00,$EA,$E0,$00,$E4,$2C,$00;D6.db $00,$00,$00;D7~DF.db $40,$44,$20,$04,$CA,$C8,$8A,$4A,$20,$E9,$AE,$A8,$69,$E8,$60,$00,$44,$60,$9D,$FB,$90,$A5,$55,$A0,$4E,$FE,$40;Overwrite Cursor.db $FF,$FF,$FF,$FB,$1B,$BF,$FB,$51,$5F,$FF,$95,$9F;Insert Cursor.db $00,$00,$0F,$4E,$EE,$0F,$4A,$EA,$0F,$06,$A6,$0F;E8~EF.db $00,$84,$20,$00,$C6,$20,$00,$E6,$20,$00,$8C,$E0,$25,$D5,$20,$4A,$AA,$40,$4E,$44,$40;F0~F4.db $44,$4E,$40,$5A,$5A,$5A,$27,$A6,$3E,$4E,$44,$00,$69,$A9,$A0;male/female.db $73,$5E,$AE,$EA,$E4,$E4;BlockEater Down $F7.db $6F,$96,$90;BlockEater Left $F8.db $6F,$16,$90;BlockEater Right $F9.db $6F,$86,$90;BlockEater Up $FA.db $69,$96,$90;FB~FE.db $09,$AC,$E0,$08,$53,$70,$EC,$A1,$00,$73,$58,$00;FF.db $A5,$A5,$A5
#define DWAIT in a, ($10) \ or a \ jp m, $-3copySetup: di ld hl, $9900 ld de, $9901 ld bc, $100 ld (hl), $98 ldir ld a, $C3 ld ($9898), a ld hl, interrupt ld ($9899), hl ld a, $99 ld i, a im 2 xor a out (03), a ;don't use halt ld a, $A0 ;64 t-state timer out ($30), a ret; hl is the buffer to useinterruptCopy: nop ld a, $C9 ld (interruptCopy), a ;safeguard against running twice ld e, $20 nextColumn: DWAIT ld a, e out ($10), a cp $2E jr nz, notDoneYet xor a ld (interruptCopy), a ex af, af' exx ret ;returns with interrupts disablednotDoneYet: inc e DWAIT ld a, $80 out ($10), a ld bc, 64*256+$11 ld a, 3 out ($31), a ;this is 3*64 = 192 t-states per write out ($32), a ; you can refine this, but 192 is probably good ex af, af' exx ei retinterrupt: ;19 + 10 ex af, af' ;4 exx ;4 out ($31), a ;11 a = 3 outi ;16 jr z, nextColumn ;7 exx ;4 ex af, af' ;4 ei ;4 ret ;10 ;93 total