Avram Posted May 21, 2010 Share Posted May 21, 2010 I keep trying to teach myself assembly language but have been struggling due to time and difficulty with the concepts. If I wanted to do the following could someone please help? 1) Perform the equivalent of a BASIC "GRAPHICS 12" command so that I could set up a screen of antic mode #4 2) Plot text characters onto the screen. And if I wanted to move them, I guess I would have to redraw them during the vertical blank so that there wouldn't be any flickering? Thanks! Avram Quote Link to comment Share on other sites More sharing options...
gauntman Posted May 21, 2010 Share Posted May 21, 2010 Hi Avram, The concept to wrap your head around when moving to assembly language, is that you are now in control - not the OS routines. So, while it is possible to call the OS graphics routines to set GR.12, it is more typical to set up the display list and screen memory yourself. Here is a small example... this actually is doing a lot more than necessary, including setting up look-up tables for plotting that is definitely overkill for this example, but might be useful for a larger project. *=$4000 begin lda #<scr ; start by calculating look-up tables sta $d0 ; at the same time, we will clear the lda #>scr ; screen sta $d1 ldx #0 c0 lda #0 ldy #39 ; clear a single line c1 sta ($d0),y dey bpl c1 lda $d1 ; store address into look-up table sta schi,x lda $d0 sta sclo,x clc ; update zero page to next line adc #40 ; 40 bytes per line sta $d0 bcc c2 inc $d1 c2 inx ; for all 24 lines... cpx #24 bne c0 lda #4 ; set some colors sta 708 ; make ANTIC4 slightly more readable lda #6 sta 709 lda #8 sta 710 lda #<DLIST ; finally, point ANTIC to new display sta 560 lda #>DLIST sta 561 ; Plot a character ldx #20 ; vertical position ldy #20 ; horizontal position lda sclo,x ; set up zero-page address sta $d0 lda schi,x sta $d1 lda #33 ; plot the character sta ($d0),y ; Plot a block ldx #8 ; upper corner ldy #8 lda sclo,x ; set up zero-page addresses sta $d0 lda schi,x sta $d1 inx lda sclo,x sta $d2 lda schi,x sta $d3 lda #34 ; plot the character block... sta ($d0),y ; warning - no boundary testing sta ($d2),y iny sta ($d0),y sta ($d2),y j1 jmp j1 ; wait DLIST .byte 112,112,112 ; blank lines .byte 68,<scr,>scr ; 24 lines of ANTIC 4 .byte 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 .byte 4,4,4,4,4,4,4 .byte 65,<DLIST,>DLIST ; Jump to top *=$5000 scr .ds 40*24 ; 960 bytes for screen sclo .ds 24 schi .ds 24 So, in this case, I created a display list for an Gr.12 screen, with screen data starting at the address scr ($5000). The book Atari Arcade Graphics and Design explains this pretty well in the early chapters, if you want more information. Quote Link to comment Share on other sites More sharing options...
Avram Posted May 21, 2010 Author Share Posted May 21, 2010 Fantastic. Thank-you! I'll play with it and see how it goes but thanks for making it so readable. Avram Quote Link to comment Share on other sites More sharing options...
Avram Posted May 21, 2010 Author Share Posted May 21, 2010 Gauntman, I've been slowly making a mess out of your neat code as I try to get it to perform what I want. What's the purpose of the look-up table you create at the beginning? If I wanted to move a character around the screen using the joystick, could I replace this... ; Plot a character ldx #20 ; vertical position ldy #20 ; horizontal position with this(and I'm using 1536-1537 as temporary locations at the moment) and read the joystick register to increase and decrease the x and y positions? ; Plot a character ldx 1536 ; vertical position ldy 1537 ; horizontal position Quote Link to comment Share on other sites More sharing options...
danwinslow Posted May 21, 2010 Share Posted May 21, 2010 (edited) Its to provide a quick way to look up the starting address of a line on the screen. Normally, to address a character block you'd need to multiply the Y co-ordinate by the number of bytes in a line, in order to index into the screen RAM by the correct amount. The table gives you the starting address of each line, though, so all you have to do is fetch the address at that index and then add the X position. Essentially, you do all the multiplies once and save it in a table, so that you don't have to do a multiply every time you want to plot a character. I think the answer to your second question is 'yes'. Edited May 21, 2010 by danwinslow Quote Link to comment Share on other sites More sharing options...
Bryan Posted May 21, 2010 Share Posted May 21, 2010 These kinds of concepts kept me from understanding Assembly back in the '80s. I always expected all languages to work like BASIC with different syntax. When you work in assembly, you need to learn the hardware. You need to know how the chips and their registers work so you can take control of them. The OS can still be used for some things (especially if you don't need all the speed you can get), but to become proficient you should know how to do things both ways. Start by reading up on Antic and GTIA. Make a custom screen and write data to it. Once you're comfortable you can move on to Pokey, etc... It's rough at first but it gets much easier as you go. Quote Link to comment Share on other sites More sharing options...
Avram Posted May 21, 2010 Author Share Posted May 21, 2010 Here's my take on the original code. Right now I'm attempting to move a character when the joystick is moved to the right. Instead it seems to jump several characters. Any ideas? And thanks so far for the further help! *=$4000 begin lda #<scr ; start by calculating look-up tables sta $d0 ; at the same time, we will clear the lda #>scr ; screen sta $d1 ldx #0 c0 lda #0 ldy #39 ; clear a single line c1 sta ($d0),y dey bpl c1 lda $d1 ; store address into look-up table sta schi,x lda $d0 sta sclo,x clc ; update zero page to next line adc #40 ; 40 bytes per line sta $d0 bcc c2 inc $d1 c2 inx ; for all 24 lines... cpx #24 bne c0 lda #4 ; set some colors sta 708 ; make ANTIC4 slightly more readable lda #6 sta 709 lda #8 sta 710 lda #<DLIST ; finally, point ANTIC to new display sta 560 lda #>DLIST sta 561 j1 ; Plot a block ldx #8 ; upper corner ldy #8 lda sclo,x ; set up zero-page addresses sta $d0 lda schi,x sta $d1 inx lda sclo,x sta $d2 lda schi,x sta $d3 lda #0 ; plot the character block... sta ($d0),y ; warning - no boundary testing sta ($d2),y iny sta ($d0),y sta ($d2),y ; joystick lda 632 cmp #7 beq right jmp j1 right inc 1537 ldx 1536 ; vertical position ldy 1537 ; horizontal position lda sclo,x ; set up zero-page address sta $d0 lda schi,x sta $d1 lda 53770 ; plot the character sta ($d0),y dey ; erase behind the character lda sclo,x ; set up zero-page address sta $d0 lda schi,x sta $d1 lda #0 ; plot the character sta ($d0),y jmp j1 ; wait DLIST .byte 112,112,112 ; blank lines .byte 68,<scr,>scr ; 24 lines of ANTIC 4 .byte 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 .byte 4,4,4,4,4,4,4 .byte 65,<DLIST,>DLIST ; Jump to top *=$5000 scr .ds 40*24 ; 960 bytes for screen sclo .ds 24 schi .ds 24 Quote Link to comment Share on other sites More sharing options...
gauntman Posted May 24, 2010 Share Posted May 24, 2010 Here's my take on the original code. Right now I'm attempting to move a character when the joystick is moved to the right. Instead it seems to jump several characters. Any ideas? And thanks so far for the further help! The code looks okay - my guess is that it is jumping because the code is executing several times before the screen refreshes. Moving by character steps is much faster in assembly than in Basic, so it is zipping 2-3 times before the screen can catch up. You will probably want to place the movement code (or at least the drawing) into the VBI - and most likely only execute every other frame or so. Alternatively, you could hook up to a timer or for now busy wait. i.e. for testing at the moment, just before the "jmp j1" j0 lda 20 and #7 bne j0 ; delay for 8 jiffies You may wish to change the 7 to a 3 for a faster response. Quote Link to comment Share on other sites More sharing options...
Avram Posted May 24, 2010 Author Share Posted May 24, 2010 That's improved it immensely. Thanks for taking the time to fix that for me. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.