{"id":2718,"date":"2021-01-02T12:49:55","date_gmt":"2021-01-02T12:49:55","guid":{"rendered":"http:\/\/blog.rastersoft.com\/?p=2718"},"modified":"2023-12-25T19:48:34","modified_gmt":"2023-12-25T19:48:34","slug":"pintando-en-el-spectrum-2","status":"publish","type":"post","link":"https:\/\/blog.rastersoft.com\/?p=2718","title":{"rendered":"Pintando en el Spectrum (2)"},"content":{"rendered":"\n<p>Esta ma\u00f1ana estaba revisando mi c\u00f3digo y se me ocurri\u00f3 una peque\u00f1a optimizaci\u00f3n. JP cc, nn (salto condicional) necesita 10 Tstados, mientras que DJNZ necesita 13 cuando no se cumple la condici\u00f3n, y 8 cuando s\u00ed se cumple. Dado que siete veces no se cumple pero una s\u00ed se cumple, si podemos sustituir el DJNZ por un JP pe, nn, ahorraremos 19 Tstados en cada fila. S\u00f3lo tenemos que cargar BC con 256, que es el n\u00famero de transferencias que tenemos que hacer entre grupos de atributos. Pero adem\u00e1s, dado que cada vez que terminamos una fila de caracteres BC valdr\u00e1 cero, podemos simplemente incrementar B en uno, que es una operaci\u00f3n m\u00e1s r\u00e1pida que cargar un n\u00famero, con lo que ahorraremos 3 Tstados m\u00e1s. As\u00ed quedar\u00eda el c\u00f3digo:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted mycode\">    <code>LD SP, tabla_direcciones<\/code>\n    <code>LD HL, buffer<\/code>\n    LD BC, 0 ; mismo valor que si hubi\u00e9semos hecho una fila entera\n    <code>EXX ; cambiamos al juego de registros alternativo<\/code>\n    <code>LD HL, buffer + 6144 ; apunta a los atributos de color del buffer<\/code>\n    <code>LD DE, 22528 ;  zona de atributos de la pantalla<\/code>\n    <code>LD BC, 768 ; tama\u00f1o de los atributos<\/code>\n loop1:\n     EXX ; volvemos al juego original con los datos de p\u00edxeles\n     INC B ; como BC aqu\u00ed vale cero, esto es igual que LD BC, 256\n           ; pero m\u00e1s r\u00e1pido\n loop2:\n     POP DE\n     LDI\n     \u2026 ; 32 LDIs en total\n     LDI\n     JP PE, loop2\n     EXX\n     LDI\n     \u2026 ; 32 LDIs en total\n     LDI\n     JP PE, loop1 ; no podemos usar DJNZ porque el salto es\n                   ; de m\u00e1s de 128 bytes\n     \u2026\n tabla_direcciones:\n     DEFW 0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700\n     DEFW 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520, 0x4620, 0x4720\n     ; completar hasta las 192 l\u00edneas<\/pre>\n\n\n\n<p>Ahora el bucle interno dura 11 + 512 + 10 = 533 Tstados, aunque en las zonas con contienda ser\u00e1n 536, por lo que necesitaremos entre 4 264 y 4 288 Tstados por cada fila de caracteres. Sumando la parte de los atributos tenemos que ser\u00e1n 4 + 4 + 4 + 512 + 10 = 534 Tstados extra, que cuando haya contienda subir\u00e1 a 536 Tstados. Y esto para cada una de las 24 filas de la pantalla, lo que nos da entre 115 152 y 115 776 Tstados, lo que significa que en el peor de los casos estamos igual, pero en el mejor ahorramos algo.<\/p>\n\n\n\n<p>\u00bfPero realmente existe ese \u00abmejor de los casos\u00bb si, al escribir en pantalla, siempre tenemos contienda? En realidad esto s\u00f3lo es verdad a medias: s\u00f3lo tenemos contienda cuando la ULA est\u00e1 leyendo de la memoria para pintar el <em>paper<\/em>, pero no cuando est\u00e1 pintando el borde. Teniendo en cuenta que de las 312 l\u00edneas de la pantalla, s\u00f3lo 192 tienen contienda, y las 192 las recorremos dos veces (pues primero el haz va por delante nuestra, pero al llegar al final de la pantalla y volver al principio va por detr\u00e1s hasta que nos alcanza) tenemos un total de 504 l\u00edneas, de las cuales 120 no tienen contienda. Eso significa que el tiempo real ser\u00e1, aproximadamente, 0,762 * tiempo_peor + 0,238 * tiempo mejor. Por tanto, en este caso, tenemos que tardaremos 115 627 Tstados, frente a los 115 764 Tstados del caso anterior. No es mucha diferencia, pero cualquier Tstado que ahorremos es tiempo que podemos emplear luego en generar el siguiente frame. Y teniendo en cuenta que antes de pintarlo tenemos que sincronizarnos con la pantalla, el pasarnos tan solo un Tstado puede hacer que tengamos que esperar al siguiente frame de la pantalla.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Esta ma\u00f1ana estaba revisando mi c\u00f3digo y se me ocurri\u00f3 una peque\u00f1a optimizaci\u00f3n. JP cc, nn (salto condicional) necesita 10 Tstados, mientras que DJNZ necesita 13 cuando no se cumple la condici\u00f3n, y 8 cuando s\u00ed se cumple. Dado que siete veces no se cumple pero una s\u00ed se cumple, si podemos sustituir el DJNZ &hellip; <a href=\"https:\/\/blog.rastersoft.com\/?p=2718\" class=\"more-link\">Seguir leyendo <span class=\"screen-reader-text\">Pintando en el Spectrum (2)<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,17,7],"tags":[20],"class_list":["post-2718","post","type-post","status-publish","format-standard","hentry","category-programacion","category-retrocomputacion","category-tutoriales","tag-pintando-en-el-spectrum"],"_links":{"self":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2718","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2718"}],"version-history":[{"count":1,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2718\/revisions"}],"predecessor-version":[{"id":2719,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2718\/revisions\/2719"}],"wp:attachment":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2718"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2718"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2718"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}