This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Messages - chickendude
Pages: 1 ... 33 34 [35] 36 37 ... 55
511
« on: February 19, 2013, 11:58:58 am »
I'm probably also not quite hitting what you're getting at, but i've tried many many times to get into high-level languages but i just can't. I get bored, lost, don't understand concepts, or just find that the code looks super ugly (pretty silly excuse, i know ). With a new assembly language (z80, m68k, SH3/4, ARM) i can usually spend a couple days rummaging through the manual and things just click together. I really enjoy learning what the processor can actually do. Maybe it just seems easier when i know exactly what's going on? I generally prefer to write my own code as i dunno why but i don't like using libraries. I hate feeling dependent on libraries, i'd rather just write the routine myself or pull it from a routine i've already written(/can modify if i want to be more efficient in my program). I guess high-level languages just seem much bigger and much more complicated/confusing to me... And besides, i think the way assembly addresses memory is generally much simpler (and C code seems to super abuse the stack). I love finding my way around an assembly program, even in assembly languages i've never used before like old SNES (65816) and (especially) NES (6502) code, but i hate trying to read C code Assembly just makes more sense to me...
512
« on: February 19, 2013, 02:18:06 am »
Don't learn assembly first. At least learn Axe before that.
Most of us assembly programmers started with asm, personally i never learned any Axe. My vote is go for what you want any language can be hard if you dont work on understanding it. I started with asm and honestly I am a horrible coder of Ti-Basic and axe I suck at them frankly.
Learn what you think you will enjoy most. They all have there pluses and minuses ^^ I agree with this. I suck at TI-BASIC and switched to asm as soon as i found out about it. Really, as Hayleia mentions, learning assembly (or Axe) first will prevent you from trying to use/depending on high-level concepts too much in your assembly code and help you to think like the processor, a little more streamlined. I can't comment much on Axe, but there are a lot of very impressive games programmed in it. Besides, i think that learning assembly would help you tremendously in Axe, you'd have a better idea of what exactly each command does, it's speed, size, etc. Once you get a basic grasp of the language (which really doesn't take that long) you can just start talking to other programmers, asking questions, looking through source code, etc. and you'll be writing cool games and programs in no time If you want to learn BASIC then Axe then asm, go for it, just don't feel limited to that order or put off by the supposed difficulty of Axe and asm. I think it takes the same amount of time to learn TI-BASIC really well as it does to learn assembly/Axe, and maybe even longer to be good enough to do a lot of the cool things BASIC programmers do! Axe/asm folks are always excited to see new programmers come around and are anxious to help out.
513
« on: February 18, 2013, 10:17:47 am »
I love the pixelate animation, but it looks like the screen gets shifted down 8 pixels first...? Anyway, it's super cool.
EDIT: and what do you need the buffer for? If the graph buffer isn't enough i'm sure you can fit whatever you need into saferam (much easier than creating/deleting a variable).
514
« on: February 18, 2013, 03:55:12 am »
CoBB's tutorial is pretty good: http://sgate.emt.bme.hu/patai/publications/z80guide/Other than that, here's what i wrote at Cemetech: Some things that can be helpful to understand to be able to start writing fun games quickly: -indirection -what buffers are and why/how to use them -direct input -tilemapping -how the LCD is mapped: 1 byte = 8 pixels. This complicates drawing individual pixels a bit but means your sprites will be much smaller in size. -bit shifting commands, absolutely necessary once you want to start making games that scroll smoothly and also very useful for optimizing -storing and accessing data in tables Assembly uses an assembler, i use spasm. Essentially you just run the source file through spasm and it outputs a .8xp. The assembly mnemonics correspond directly with the z80s commands, the assembler just converts the mnemonics into assembly opcodes (hex) as well as making a lot of other things easier for you, for example calculating addresses so you don't need to count how many bytes there are to jump to the right address and lots more. If you have any questions, please ask! I don't think it's as difficult as people think (it was my first language, after English) it just takes a little while to get used to thinking differently.
515
« on: February 17, 2013, 12:08:27 pm »
But that doesn't support scrolling? I don't think you'll have any trouble adding in scrolling, but it might take a big speed hit. I don't think you have to worry so much about speed for this project, though. I also don't understand why you're using masked sprites, especially for 8x8 sprites, having more than one layer isn't going to give you that much more detail unless you want things like bridges and even then i like having larger sprites (16x16) to fit more detail in.
517
« on: February 17, 2013, 03:28:00 am »
Very cool, i just loaded it up and i have to say i really suck, but it is super fun! The only thing, and maybe the original is that way too, is that it seems to take a long time to get from one edge of the screen to the other. Still, an amazing program (even if i did more collecting bullets than dodging diamonds ). Incredible work, hoffa! All of your projects i've seen so far have been really cool
518
« on: February 11, 2013, 07:15:08 am »
I believe on the ez80 instructions all generally fit into one t-state, or rather due to the way the ez80 is set up it can pipeline/decode instructions in advance and execute them within one t-state. On the z80, each cycle takes 3-6 t-states and i assume it's basically the same on the ez80. For example: xor a takes one machine cycle of 4 t-states. add a,3 takes two machine cycles, the first is 4 t-states and the second is 3, altogether 7 t-states. add hl,de takes three machine cycles, the first two are 4 t-states and the third is 3, altogether 11 t-states. add ix,de takes four machine cycles, three cycles of 4 t-states and the last one is 3, altogether 15 t-states. ld (ix+4),a takes 5 M cycles, 4 t-states for the IX prefix, 4 more to read the opcode, 3 t-states to read the offset, 5 to add the offset and read a, 3 t-states to write a to the address. rl (ix) takes six M cycles, amounting to 23 t-states. I'm not sure what each each cycle amounts to, i think first you've got the IX prefix (4 t-states), then the opcode (4 t-states), then the offset (here, +0, 3 t-states), i don't know what the others might be.
So i think on the ez80, these M cycles will be prefetched/decoded while the previous instruction/cycle decodes/executes (each instruction must be fetched, decoded, then executed) so that they can be immediately executed when the previous instruction ends.
EDIT: Also, i was just thinking about how convenient add hl,imm16 would've been. It'd save you from having to destroy bc/de.
519
« on: February 04, 2013, 02:53:32 pm »
Bump. Today i was thinking once again how i wish there were an easy way to transfer registers to their shadow counterparts, like a version of exx that instead of swapping registers copied them. So you could do something like this: exx' ;copy hl, bc, and de to hl', bc', and de' ;mess up hl, bc, and de exx ;restore original register values (shadows contain the "messed up" values)
520
« on: February 04, 2013, 11:37:01 am »
The other routine is just a plain rectangle (non-filled) drawing routine. I don't bother SMC'ing the or (hl), just the ld (hl),a. What it does is draw the first and last pixels of the line/border outside of the main loop then either draws (ld (hl),a) all pixels in between or skips (nop's) them all. It's a bit larger so unless the speed is that important you might be better off drawing two filled rectangles with the other routine, one OR'd and a slightly smaller one XOR'd. Also, i just realized i don't need the "or a" after "ex af,af'" since the flags should still be preserved from the "and $7", so we can delete that. It's interesting to see how our syntax/style differs even on bits of code that do exactly the same thing And if you don't mind sacrificing just a few clocks (altogether maybe between 8-64), maybe you could try this and save 2 bytes: ComputeByte: and 7 ld b,a ld a,$FF ret z srl a ;or or a \ rra djnz $-2 ret
521
« on: February 03, 2013, 11:51:44 pm »
They should work with any rectangle with a width/height greater than 0 (there's no error checking for invalid dimensions and no clipping). I can see what i can do for a generic rectangle routine, what i've been doing is just calling the routine twice: start: ld de,$0204 ld bc,$2121 call draw_box2 call ionFastCopy bcall _getkey ret
draw_box2: call rectangle_filled_solid inc d inc e dec b dec b dec c dec c call rectangle_filled_xor ret EDIT: What i meant was that the first routine i wrote only handled multiples of 8, the other routines (the one in post #64 and at the bottom of #66) can handle any rectangle with valid (non-zero) dimensions. Well, as long as they don't go off-screen! EDIT2: Here's a simple normal rectangle routine. I just converted the other routine to not draw the inside of the rectangle, so it won't erase what's inside the rectangle. It's currently at 90 bytes and not terribly fast, slightly slower than drawing a filled rectangle. By default a rectangle needs to be at least 3x2 (that is X*Y), but if you don't mind adding 8 bytes (altogether 99 bytes) you can use it to draw horizontal and vertical lines and even plot pixels You can just uncomment those lines. ;b = # rows ;c = # columns ;d = starting x ;e = starting y rectangle: push de push bc ld a,d ;starting x and $7 ;what bit do we start on? ex af,af' ld a,d ;starting x ld l,e ;ld hl,e ld h,0 ; .. ld d,h ;set d = 0 add hl,de ;starting y * 12 add hl,de ;x3 add hl,hl ;x6 add hl,hl ;x12 rra ;a = x coord / 8 rra ; rra ; and %00011111 ;starting x/8 (starting byte in gbuf) add a,GBUF_LSB ld e,a ; ld d,GBUF_MSB ; add hl,de ;hl = offset in gbuf ex af,af' ;carry should be reset and z affected from and $7 ld e,a ld a,%10000000 jr z,$+6 rra dec e jr nz,$-2 dec b ;you could adjust your input to take care of this, ie b = width-2, c = height-1 and save 3 bytes here dec b ;we draw the ends separately dec c ;we'll draw the last line at the end ld d,a ;starting bit to draw ;d = starting bit rectangle_loop_y: push bc push hl call rectangle_loop_x pop hl ;hl = first column in gbuf row ld c,12 ;b = 0, bc = 12 add hl,b ;move down to next row pop bc ;restore b (# columns) xor a ; cp c ; # UNCOMMENT TO ALLOW LINES WITH A HEIGHT OF 1 PIXEL ; jr z,rectangle_end ; # ld (ld_hl),a ;change ld (hl),a to nop ld a,d ;restore a (starting bit to draw) dec c jr nz,rectangle_loop_y ld a,$77 ;ld (hl),a ld (ld_hl),a ;return nop to ld (hl),a ld a,d call rectangle_loop_x rectangle_end: pop bc pop de ret
rectangle_loop_x: or (hl) ;first bit ld (hl),a ; inc b ; # UNCOMMENT TO ALLOW LINES WITH A WIDTH OF 1 PIXEL ; ret z ; # ; dec b ; # ; jr z,rectangle_loop_x_end ; # ld a,d rectangle_loop_x_inner: rrca ;rotate a to draw the next bit jr nc,$+3 inc hl ld e,a ;save a (overwritten with or (hl)) or (hl) ;smc will modify this to or/xor ld_hl = $ ld (hl),a ld a,e ;recall a djnz rectangle_loop_x_inner rectangle_loop_x_end: rrca ;rotate a to draw the next bit jr nc,$+3 inc hl or (hl) ;last bit ld (hl),a ret If you don't care about the coordinates, you can just remove the push/pops and get another 4 bytes. And i've got another idea which should be faster (essentially working with bytes instead of pixels), though it might take up a bit more space. If you're interested let me know and i'll try to work on it some. As always, use and abuse without restrictions EDIT3: Small optimization
522
« on: February 03, 2013, 04:11:16 am »
That's a cool trick with the add a,a \ dec a. My first go at it only handled multiples of 8 and looked like this: ;b = # columns ;c = # rows ;d = starting x ;e = starting y rectangle_filled2: ld a,d ;a = starting x coord ld l,e ;ld hl,e ld h,0 ; .. ld d,h ;set d = 0 add hl,de ;starting y * 12 add hl,de ;x3 add hl,hl ;x6 add hl,hl ;x12 rra ;a = x coord / 8 rra ; rra ; and %00011111 ;starting x/8 ld e,a ; add hl,de ;add x ld de,gbuf add hl,de ;offset in gbuf ld a,b ;b = no columns rra rra rra and %00011111 ;no. columns / 8 ld b,a ld a,12 sub b ld e,a ld d,0 rectangle_loop_y: push bc rectangle_loop_x: ld (hl),$FF inc hl djnz rectangle_loop_x pop bc ;restore c (# columns) add hl,de ;move down to next row dec c jr nz,rectangle_loop_y rectangle_end: ret Much smaller and faster, but certain cases (for example, a rectangle less than 8 pixels wide, 2 byte rectangles, etc.) seemed like they were going to bump up the size quite a bit and what I wanted was to write it more for size than speed since it's not being used in any time-critical areas of the game (mostly in menus and the battle engine). How do you handle cases where, say, a rectangle doesn't fill an entire byte? The gbuf bit is also pretty creative (i guess you could also just add a,$40) but unfortunately wouldn't work out since it's being written for the 83 as well, though i guess a simple define would do. Yep: #ifdef TI83P GBUF_LSB = $40 GBUF_MSB = $93
.org progstart-2 .db $bb,$6d #else GBUF_LSB = $29 GBUF_MSB = $8E .org progstart #endif ;... rra ;a = x coord / 8 rra ; rra ; and %00011111 ;starting x/8 (starting byte in gbuf) add a,GBUF_LSB ld e,a ; ld d,GBUF_MSB ; add hl,de ;hl = offset in gbuf ...works just fine for the 83/+ I hope deeph doesn't mind, if you feel like checking their project out it's over at yAronet: http://www.yaronet.com/posts.php?s=153983EDIT: Here's a version that draws vertically (here b = height and c = width) which seems to be slightly faster (and's the same size): #ifdef TI83P GBUF_LSB = $40 GBUF_MSB = $93 #else GBUF_LSB = $29 GBUF_MSB = $8E #endif
;b = # rows ;c = # columns ;d = starting x ;e = starting y rectangle_filled_xor: ld a,$AE ;xor (hl) jr rectangle_filled2 rectangle_filled_solid: ld a,$B6 ;or (hl) rectangle_filled2: push de push bc ld (or_xor),a ;use smc for xor/solid fill ld a,d ;starting x and $7 ;what bit do we start on? ex af,af' ld a,d ;starting x ld l,e ;ld hl,e ld h,0 ; .. ld d,h ;set d = 0 add hl,de ;starting y * 12 add hl,de ;x3 add hl,hl ;x6 add hl,hl ;x12 rra ;a = x coord / 8 rra ; rra ; and %00011111 ;starting x/8 (starting byte in gbuf) add a,GBUF_LSB ld e,a ; ld d,GBUF_MSB ; add hl,de ;hl = offset in gbuf ex af,af' ;carry should be reset and z affected from and $7 ld d,a ld a,%10000000 jr z,$+6 rra dec d jr nz,$-2 ld e,12 rectangle_loop_x: push af push bc push hl ld c,a rectangle_loop_y: or_xor = $ or (hl) ;smc will modify this to or/xor ld (hl),a ld a,c add hl,de djnz rectangle_loop_y pop hl pop bc pop af rrca jr nc,$+3 inc hl dec c jr nz,rectangle_loop_x rectangle_end: pop bc pop de ret EDIT: Small optimization
523
« on: February 01, 2013, 06:17:14 am »
If you don't mind sacrificing a couple t-states (altogether maybe 30?) you can save around 30 bytes doing something like this:
;... ;... draw: ;******************* ld hl,drawReturn push hl ld hl,$9340 ;drawposition in hl drawReturn: ;******************* ld ix,$8528 ;sprite mask pointer ld de,(axv_R2) add hl, de ld b,16 ld de, 11 drawFront: ld a, (ix) and (hl) or (ix+32) ld (hl), a inc hl inc ix
ld a, (ix) and (hl) or (ix+32) ld (hl), a add hl,de inc ix djnz drawFront
ld hl,$9872 ;reset registers ;******************* ret ;******************* Also, you might be able to get rid of the ld de,(axv_R2) and the ld hl,9872 for the second iteration by adding ($9872-$9340)-(12*16) to hl (12*16 for how much you changed hl in the drawFront loop). I might have my numbers off a bit, but you could try:
draw: ld hl,drawReturn push hl ld hl,$9340 ;drawposition in hl ld de,(axv_R2) drawReturn: ld ix,$8528 ;sprite mask pointer add hl, de ld b,16 ld de, 11 drawFront: ld a, (ix) and (hl) or (ix+32) ld (hl), a inc hl inc ix
ld a, (ix) and (hl) or (ix+32) ld (hl), a add hl,de inc ix djnz drawFront
ld de,($9872-$9340)-(12*16) ;update hl with the add hl,de after drawReturn ret
524
« on: February 01, 2013, 06:05:19 am »
Wow, that's just incredible! The text feature is a really nice touch.
What do you have in mind for the menus?
525
« on: February 01, 2013, 05:08:48 am »
Here's a quick filled rectangle routine i wrote the other night. It probably doesn't belong here since i don't think it's that optimized, but it should be smaller and faster than Jason Kovacs' routine posted on the previous page. As always, do whatever you want with the code and please don't give me credit! It takes the starting x/y coordinates in de, and the width and height in pixels in bc. rectangle_filled_solid will make a solid black rectangle, rectangle_filled_xor will xor the pixels within the rectangle's area. EDIT: Added Xeda's optimisations. (see below for a slightly faster version)#ifdef TI83P GBUF_LSB = $40 GBUF_MSB = $93 #else GBUF_LSB = $29 GBUF_MSB = $8E #endif
;b = # columns ;c = # rows ;d = starting x ;e = starting y rectangle_filled_xor: ld a,$AE ;xor (hl) jr rectangle_filled2 rectangle_filled_solid: ld a,$B6 ;or (hl) rectangle_filled2: push de push bc ld (or_xor),a ;use smc for xor/solid fill ld a,d ;starting x and $7 ;what bit do we start on? ex af,af' ld a,d ;starting x ld l,e ;ld hl,e ld h,0 ; .. ld d,h ;set d = 0 add hl,de ;starting y * 12 add hl,de ;x3 add hl,hl ;x6 add hl,hl ;x12 rra ;a = x coord / 8 rra ; rra ; and %00011111 ;starting x/8 (starting byte in gbuf) add a,GBUF_LSB ld e,a ; ld d,GBUF_MSB ; add hl,de ;hl = offset in gbuf ex af,af' ;carry should be reset and z affected from and $7 ld e,a ld a,%10000000 jr z,$+6 rra dec e jr nz,$-2 ld d,a ;starting bit to draw rectangle_loop_y: push bc push hl rectangle_loop_x: ld e,a ;save a (overwritten with or (hl)) or_xor = $ or (hl) ;smc will modify this to or/xor ld (hl),a ld a,e ;recall a rrca ;rotate a to draw the next bit jr nc,$+3 inc hl djnz rectangle_loop_x pop hl ;hl = first column in gbuf row ld c,12 ;b = 0, bc = 12 add hl,bc ;move down to next row pop bc ;restore b (# columns) ld a,d ;restore a (starting bit to draw) dec c jr nz,rectangle_loop_y rectangle_end: pop bc pop de ret Here's a little example of how you could use the routine to make a text box:
start: ld de,$041B ld bc,$1103 call draw_box2 call ionFastCopy bcall _getkey ret draw_box2: call rectangle_filled_solid inc d inc e dec b dec b dec c dec c call rectangle_filled_xor ret EDIT: Small optimization
Pages: 1 ... 33 34 [35] 36 37 ... 55
|