screenaddr = screenbase + (y AND 7)*&800 + int(y/8)*2*R1 + int(x/M)
Pasándo los parámetros reg16, base, X, Y podemos obtener instrucciones "pre-formateadas" para cualquier configuración de pantalla y cualquier registro de 16 bits:
ld de,nnnn
ld hl,(nnnn)
ld (nnnn),sp
dw nnnn
etc...
SCR_WIDTH tiene que estar definido como global (ancho de pantalla en bytes, #50,#40, etc), Al igual que la coordenada XPOS es en bytes.
La razón de que sea global es porque se usa frecuentemente en otras partes de código, ya sea para dibujar sprites, scrolls, etc.
Saludos
Código: Seleccionar todo
;;===================================================
;; LD/LDC/LDR/DW SCREEN ADDR from XYPOS
;; Based on Winape's macro example by Richard Wilson
;; macro params: BC|DE|HL|IX|IY|SP, scr_base_addr, xpos, ypos
;; Globals: SCR_WIDTH (R1*2*MODE)
;; 2-4 bytes
;; Examples:
;; M_LD_SCR_ADDR HL, #C000, 1,3 --> LD HL,#D801
;; M_LDC_SCR_ADDR BC, #8000, 1,3 --> LD BC,(#9801)
;; M_LDR_SCR_ADDR DE, #8000, 1,3 --> LD (#9801),DE
;; M_DW_SCR_ADDR #C000, 1,3 --> DEFW #D801
ifndef SCR_WIDTH:SCR_WIDTH equ #50:endif
macro M_SCR_ADDR base, X, Y
let @y7 = Y and 7 * #800
let addr = Y / 8 * SCR_WIDTH + base + @y7 + X
mend
macro M_LD_SCR_ADDR reg16, base, X, Y
M_SCR_ADDR base, X, Y
ld reg16,addr
mend
macro M_LDC_SCR_ADDR reg16, base, X, Y
M_SCR_ADDR base, X, Y
ld reg16,(addr)
mend
macro M_LDR_SCR_ADDR reg16, base, X, Y
M_SCR_ADDR base, X, Y
ld (addr),reg16
mend
macro M_DW_SCR_ADDR base, X, Y
M_SCR_ADDR base, X, Y
defw addr
mend
Programming:Calculating xpos,ypos to screen address in assembly - CPCWiki
https://www.cpcwiki.eu/index.php/Progra ... n_assembly
Assembler Macros - WinAPE
http://www.winape.net/help/macros.html