Reading, storing and writing screen values oblo Member Posts: 97 Threads: 23 Joined: Jul 2011 Reputation: 0 03-05-2013, 05:33 PM Hi all I'm starting to learn how to manipulate screen directly at memory address level. Right now, I'm messing with this code Code:```rem screen values paper 0: border 0: ink 7: cls dim conta as byte dim x,y,n,adres,dirb as uinteger bucle: y=RND*10 x=RND*32 adres=0 POKE attrAddress(x,y),RND*256 Print at 10,0; "X="; x; " - "; "Y="; y; print at 11,0; "Attrib address is.......: "; attrAddress(x,y); print at 12,0; "Attrib value is.........: "; PEEK attrAddress(x,y); print at 13,0; "The 8 screen addresses..: " for conta=0 to 7         poke scrAddress(x,y)+adres,RND*256         print scrAddress(x,y)+adres;","; PEEK (scrAddress(x,y)+adres)         adres=adres+256 next conta pause 0 cls goto bucle rem funciones FUNCTION scrAddress(x AS UBYTE, y AS UBYTE) AS UINTEGER ASM ; This FUNCTION returns the address into HL of the screen address ; x,y in character grid notation. ; Original CODE was extracted by BloodBaz          ; x Arrives in A, y is in stack.          AND     31          ld      l,a          ld      a,(IX+7) ; Y value          ld      d,a          AND     24          add     a,64          ld      h,a          ld      a,d          AND     7          rrca          rrca          rrca          OR      l          ld      l,a                END ASM END FUNCTION FUNCTION attrAddress (x AS UBYTE, y AS UBYTE) AS UINTEGER 'This function returns the memory address of the Character Position 'x,y in the attribute screen memory. 'Adapted from code by Jonathan Cauldwell. 'Rebuilt for ZX BASIC by Britlion from NA_TH_AN's fourspriter, with permission. ASM          ld      a,(IX+7)  ;ypos          rrca          rrca          rrca              ; Multiply by 32          ld      l,a       ; Pass TO L          AND     3         ; Mask with 00000011          add     a,88      ; 88 * 256 = 22528 - start of attributes.          ld      h,a       ; Put it in the High BYTE          ld      a,l       ; We get y value *32          AND     224       ; Mask with 11100000          ld      l,a       ; Put it in L          ld      a,(IX+5)  ; xpos          add     a,l       ; Add it TO the Low BYTE          ld      l,a       ; Put it back in L, AND we're done. HL=Address. END ASM END FUNCTION``` Questions are: - Are there any better options to read and write given a X and Y coordinates? - What is the best way to storage screen memory addresses and their values? Integer (for addresses) and Ubyte (for values) arrays, right? Thanks and regards britlion Posting Freak Posts: 805 Threads: 135 Joined: Apr 2009 Reputation: 5 03-05-2013, 08:52 PM oblo Wrote:Hi all I'm starting to learn how to manipulate screen directly at memory address level. Right now, I'm messing with this code Questions are: - Are there any better options to read and write given a X and Y coordinates? - What is the best way to storage screen memory addresses and their values? Integer (for addresses) and Ubyte (for values) arrays, right? Thanks and regards I'm glad you found the routines in the library useful! Those are about as fast as you can get, short of using screen lookup tables, which I think I've discussed elsewhere (and used a lot!). Lookup tables are the fastest way to get screen addresses. When writing to a whole character square, you write to address, address+256, address+512 etc. This is a bit slow in basic. In raw machine code it's much easier - you point HL at the screen, write to address HL, and then increment H. One instruction, 4 T states, and you're at the next row of a character. This optimization is the reason the screen display appears so oddly laid out at first glance. (Sometimes it's easier to think of it as three long long long rows of 256 characters wide) In essence, then, poking the screen like this, because of the address overhead (+256 is probably not well optimized), it's likely to be slower than a dedicated drawing routine. Fortunately, there are quite a lot of those in the library in machine code as well - that write to full character squares as is. As for the other questions: Yes - if you need an address in memory, it's a uInteger. If you're storing the contents of an address, it's a ubyte. But if you're manipulating the screen, you probably want a specialised routine in assembler - as you have here for attr address and screen addresses. oblo Member Posts: 97 Threads: 23 Joined: Jul 2011 Reputation: 0 03-05-2013, 10:33 PM Thanks; I'm not good with ASM so I have to find some routines to reuse them. About look-up tables, I've found this: chuntey.wordpress.com/category/z80-assembly/ ...But the code doesn't work in zxbasic. Anyway, I'll continue to mess with this Cheers boriel Administrator Posts: 1,709 Threads: 54 Joined: Aug 2019 Reputation: 14 03-05-2013, 10:39 PM oblo Wrote:Thanks; I'm not good with ASM so I have to find some routines to reuse them. About look-up tables, I've found this: chuntey.wordpress.com/category/z80-assembly/ ...But the code doesn't work in zxbasic. Anyway, I'll continue to mess with this CheersHey, Interesting. Maybe we (you included) can port it! I'm currently really busy, but will help in any question regarding to syntax, toolkit capabilities, etc... britlion Posting Freak Posts: 805 Threads: 135 Joined: Apr 2009 Reputation: 5 03-09-2013, 09:04 PM (This post was last modified: 07-25-2022, 11:01 AM by britlion. Edit Reason: Fix url ) The screen and rotate tables I use are these ones: https://dl.dropbox.com/u/4903664/ScreenTables.7z (moved to: https://www.dropbox.com/s/wmf5oggc5f9izx...es.7z?dl=0 ) The High Res Print Fast routine uses screen tables: https://zxbasic.readthedocs.io/en/docs/l...ntfast.bas « Next Oldest | Next Newest »