{"id":2943,"date":"2021-04-01T15:01:17","date_gmt":"2021-04-01T15:01:17","guid":{"rendered":"https:\/\/blog.rastersoft.com\/?p=2943"},"modified":"2023-12-25T19:47:25","modified_gmt":"2023-12-25T19:47:25","slug":"pintando-en-el-spectrum-15","status":"publish","type":"post","link":"https:\/\/blog.rastersoft.com\/?p=2943","title":{"rendered":"Pintando en el Spectrum (15)"},"content":{"rendered":"\n<p>En la \u00faltima entrada habl\u00e9 del gestor de tareas. Sin embargo, desde entonces la cosa ha evolucionado mucho y el c\u00f3digo actualmente es algo diferente. En concreto, es este:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted mycode\">old_stack:\n    DEFW 0\ntask_pointer:\n    DEFW 0\n\ntask_run:\n    ld (old_stack), SP\n    ld iy, task_list\ntask_loop:\n    ld a, (iy+0)\n    and a\n    jr z, task_end\n    ld l, (iy+1)\n    ld h, (iy+2)\n    ld sp, hl\n    ld (task_pointer), iy\n    ret\ntask_end:\n    ld sp, (old_stack)\n    ret\ntask_yield:\n    ld iy, (task_pointer)\n    ld hl, 0\n    add hl, sp ; get the current stack\n    ld (iy+1), l\n    ld (iy+2), h\n    ld e, (iy+0)\n    ld d, 0\n    add iy, de ; jump to next entry\n    jp task_loop\n\ntask_list:\n    TASK_ENTRY 36, task1\n    TASK_ENTRY 10, task2\n    TASK_ENTRY 14, task3\n    DEFB 0 ; fin de la lista de tareas<\/pre>\n\n\n\n<p>El primer cambio es que ahora guardo el valor de IY, de manera que puede modificarse dentro de la tarea sin problemas. El segundo es que ahora, cada tarea puede tener un tama\u00f1o de pila diferente, lo que permite ahorrar mucha memoria, pues hay tareas que casi no hacen llamadas anidadas, mientras que otras s\u00ed.<\/p>\n\n\n\n<p>El segundo cambio fue crear una macro que simplifica crear la tabla de tareas. Al final, en la etiqueta <em>task_list<\/em>, tengo una lista de tareas de ejemplo con un total de tres <em>tasks<\/em>, donde el c\u00f3digo de la primera empieza en <em>task1<\/em>, el de la segunda en <em>task2<\/em>, y el de la tercera en <em>task3<\/em>, y sus <em>stacks<\/em> respectivos tienen un tama\u00f1o de 36, 10 y 14 bytes. <em>TASK_ENTRY<\/em> es una macro con el siguiente formato:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted mycode\">MACRO TASK_ENTRY, STACK_SIZE, TASK_FUNCTION\n    DEFB STACK_SIZE+3\n    DEFW $+STACK_SIZE\n    DEFS STACK_SIZE-2\n    DEFW TASK_FUNCTION\nENDM<\/pre>\n\n\n\n<p>El primer byte indica el tama\u00f1o completo de la entrada, que ser\u00e1 de tres bytes m\u00e1s que el tama\u00f1o de pila que queremos asignar a esta <em>task<\/em>. Los dos siguientes bytes contienen el valor del registro SP de esta tarea, o sea, el actual puntero de pila. Se inicializa de manera que apunte al final del bloque reservado para la pila. Luego vienen tantos bytes como tama\u00f1o de pila queramos menos 2, de manera que reservamos los dos \u00faltimos bytes para poner la direcci\u00f3n de inicio de la tarea. De esta manera, cuando se crea la entrada para una tarea, la pila s\u00f3lo contiene la direcci\u00f3n de inicio de dicha tarea, y el puntero de pila apunta justo a ella.<\/p>\n\n\n\n<p>Por \u00faltimo, a\u00f1ad\u00ed una funci\u00f3n optativa para depurar las tareas. Es \u00e9sta:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted mycode\">    ld hl, (task_pointer)\n    inc hl\n    inc hl\n    inc hl ; jump over the size and the stored SP pointer\n    ld d, 0\ntask_check_size:\n    ld a, (hl)\n    and a\n    jr nz, task_end_check_size\n    inc d\n    inc hl\n    jr task_check_size\ntask_end_check_size:\n    ld a, d\n    ld SP, (old_stack)\n    call do_debug<\/pre>\n\n\n\n<p>Este bloque se puede ejecutar justo despu\u00e9s de que una tarea haya vuelto (llamando a <em>task_yield<\/em>), y lo que hace es comprobar cuanto espacio se ha llegado a ocupar en la pila. Para ello se basa en que el bloque de la pila se inicializ\u00f3 a cero, y que cuando se saca un valor de la pila s\u00f3lo se incrementa SP, pero el valor sigue estando ah\u00ed. De esta manera, si vemos cuantos bytes seguidos cuyo valor sea cero hay desde el principio, sabremos hasta donde ha llegado a crecer la pila. Si este tama\u00f1o es cero significa que esa pila se ha llenado del todo en alg\u00fan momento (y hasta es posible que haya sobreescrito alguna posici\u00f3n extra), por lo que en ese caso hay que aumentar el tama\u00f1o.<\/p>\n\n\n\n<p>La llamada a <em>CALL do_debug<\/em> se supone que muestra, de alguna manera, el contenido del registro A.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Qu\u00e9 pinta tiene<\/h2>\n\n\n\n<p>Pues el juego ya lo he terminado y ahora mismo estoy puliendo los textos y la traducci\u00f3n al ingl\u00e9s, y los <em>petatesters<\/em> est\u00e1n buscando los <em>bugs<\/em> y pifias varias. Pero tiene esta pinta:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"576\" style=\"aspect-ratio: 1024 \/ 576;\" width=\"1024\" controls src=\"https:\/\/blog.rastersoft.com\/wp-content\/uploads\/2021\/04\/demo_juego.mp4\"><\/video><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>En la \u00faltima entrada habl\u00e9 del gestor de tareas. Sin embargo, desde entonces la cosa ha evolucionado mucho y el c\u00f3digo actualmente es algo diferente. En concreto, es este: old_stack: DEFW 0 task_pointer: DEFW 0 task_run: ld (old_stack), SP ld iy, task_list task_loop: ld a, (iy+0) and a jr z, task_end ld l, (iy+1) ld &hellip; <a href=\"https:\/\/blog.rastersoft.com\/?p=2943\" class=\"more-link\">Seguir leyendo <span class=\"screen-reader-text\">Pintando en el Spectrum (15)<\/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,6],"tags":[20],"class_list":["post-2943","post","type-post","status-publish","format-standard","hentry","category-programacion","category-retrocomputacion","category-trucos","tag-pintando-en-el-spectrum"],"_links":{"self":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2943","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=2943"}],"version-history":[{"count":11,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2943\/revisions"}],"predecessor-version":[{"id":2956,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2943\/revisions\/2956"}],"wp:attachment":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2943"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2943"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}