¡Hola a todos!, hay problemas con la web que espero poder arreglar lo antes posible, ¡mil perdones!

Ver índice de webs/blogs

ZX Spectrum Assembly, Space Battle – 0x03 Play area [Espamatica] [Leer]


In this chapter of ZX Spectrum Assembly, we will paint the play area.

Play area

Create the folder Step03 and copy the files const.asm, graph.asm, main.asm and var.asm from the folder Step02.

Before starting to draw the game area, it is necessary to know that the ZX Spectrum screen is divided into two zones, the upper one with twenty-two lines (from zero to twenty-one) and the lower one (the line where the commands are entered).

If you load the program resulting from the previous chapter, when it is executed, pressing the ENTER key will display the basic list of the loader. Executing line 40 should paint the graphics, but this does not seem to be the case. They do draw, but they do so on the command line; look and you will see them draw and then disappear.

After running our program, the active part of the screen is the command line, so we need a mechanism to activate the part of the screen where we want to paint.

Changing the active display

The upper part of the screen is two, the lower part one. There is a routine in the ROM that activates one or the other channel depending on the value in register A.

Open the file const.asm and add the following lines:

; ------------------------------------------------------------------- ; ROM routine that opens the display channel. ; ; Input: A -> 1 = command line ; 2 = top screen ; ------------------------------------------------------------------- OPENCHAN: EQU $1601

Next, we open the main.asm file and just below the Main tag we add the following lines:

ld a, $02 call OPENCHAN

We load the channel we want to activate into A, LD A, $02, and then call the ROM routine to activate it, CALL OPENCHAN.

We compile, load into the emulator, press any key, execute line 40 and now our graphics are painted in the right place again.

We paint text strings

When working with UDG, we could say that we are painting characters, and as such we will be painting the game screen.

We implement a routine that paints strings, giving the address where the string is and the length of the string.

We create the file print.asm and implement PrintString, which takes the address of the string in HL and the length in B. This routine changes the value of the AF, B and HL registers.

PrintString: ld a, (hl) rst $10 inc hl djnz PrintString ret

Loads the character to be drawn into A, LD A, (HL), draws it, RST $10, points HL to the next character, INC HL, and repeats the operation until B is 0, DJNZ PrintString. Finally, it exits, RET.

The final aspect of the routine, once commented, is as follows:

; ------------------------------------------------------------------- ; Paints chains. ; ; Input: HL = first memory location of the string. ; B = length of the chain. ; Alters the value of the AF, B and HL registers. ; ------------------------------------------------------------------- PrintString: ld a, (hl) ; A = character to be painted rst $10 ; Paint the character inc hl ; HL = next character djnz PrintString ; Until B has a value of 0 ret

The next step is testing, so let’s edit the main.asm file. The first thing to do, so we don’t forget, is to include the print.asm file before END Main:

include "print.asm"

Just before the includes, we are going to define a string with two tags, the string itself and a second tag to mark the end of the string.

String: db 'Hello World' String_End: db $

Just before the RET that takes us out of Basic, we add the call to the new routine.

ld hl, String ld b, String_End - String call PrintString

We compile, load in the emulator and see the results.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

As you can see, the string Hello World has been painted after the graphics.

We add codes before the string and leave it as it is:

db $16, $0a, $0a, 'Hello World'

We compile, load in the emulator and see the result.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

As we can see, the Hello World string now appears more centred, which we have achieved by adding characters in front of the string, specifically $16, which is the control character of the Basic AT command, and the Y and X coordinates.

Below is a list of the control characters we can use when painting strings in this way, and the parameters to send.

CharacterCodeParametersValues
DELETE$0c  
ENTER$0d  
INK$10ColourFrom $00 to $07
PAPER$11ColourFrom $00 to $07
FLASH$12No/YesFrom $00 to $01
BRIGHT$13No/YesFrom $00 to $01
INVERSE$14No/YesFrom $00 to $01
OVER$15No/YesFrom $00 to $01
AT$16Y and X coordinatesY = from $00 to $15
X = from $00 to $1f
TAB$17Number of tabulations 
ZX Spectrum Assembly, Space Battle

Control codes must be accompanied by their parameters to avoid unwanted results. If a string is printed after TAB, a space must be added as the first character of the string.

As an exercise, try different combinations of control codes, try colour, blinking, etc.

We paint the game screen

The game screen is surrounded by a frame, but before we paint anything, let’s clean up main.asm, removing everything that’s left over; we delete from the two lines before the Loop tag to the line before the RET statement, we also delete the definition of String and String_End.

main.asm should now look like this:

org $5dad Main: ld a, $02 call OPENCHAN ld hl, udgsCommon ld (UDG), hl ret include "const.asm" include "graph.asm" include "print.asm" include "var.asm" end Main

Now we define the strings to paint the frame in var.asm and include them before udgsCommon.

; ------------------------------------------------------------------- ; Display frame ; ------------------------------------------------------------------- frameTopGraph: db $16, $00, $00, $10, $01 db $96, $97, $97, $97, $97, $97, $97, $97, $97, $97, $97, $97, $97 db $97, $97, $97, $97, $97, $97, $97, $97, $97, $97, $97, $97, $97 db $97, $97, $97, $97, $97, $98 frameBottomGraph: db $16, $15, $00 db $9b, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c db $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c, $9c db $9c, $9c, $9c, $9c, $9c, $9d frameEnd:

In the first DB line we define the position of the top, $16, $00, $00 and the colour, $10, $01.

On the next line we define the top of the frame, first the top left corner, $96, then thirty top horizontal positions, $97, and finally the top right corner, $98; all these numbers are in the comments of the chart definition.

On the next line we define the position of the bottom, $16, $15, $00.

On the next line we define the bottom, first the lower left corner, $9b, then thirty lower horizontal positions, $9c, and finally the lower right corner, $9d.

Let’s see how it all looks. We go back to main.asm and add the following lines just above the RET:

ld hl, frameTopGraph ld b, frameEnd - frameTopGraph call PrintString

We compile, load in the emulator and see the results.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

We have painted the top and bottom of the frame, although the frame is not complete as the sides are missing.

We will implement a routine that prints the frame and we will do this in print.asm.

PrintFrame: ld hl, frameTopGraph ld b, frameEnd - frameTopGraph call PrintString

We load into HL the memory address of the top of the frame, LD HL, frameTopGraph, load into B the length by subtracting the start address of the top from the end address of the frame, LD B, frameEnd – frameTopGraph, and call the routine that prints the strings, CALL PrintString.

All that remains is to implement a loop to paint the sides.

ld b, $01 printFrame_loop: ld a, $16 rst $10 ld a, b rst $10 ld a, $00 rst $10 ld a, $99 rst $10

We load into B the start line of the pages, LD B, $01, we load into A the AT control character, LD A, $16, and draw it, RST $10, we load the Y coordinate, LD A, B, and draw it, RST $10, we load the zero column, LD A, $00, and draw it, RST $10, and finally we load into A the left page character, LD A, $99, and draw it, RST $10.

We do the same with the right side, since the code is practically the same, we just mark the two lines that change.

ld a, $16 rst $10 ld a, b rst $10 ld a, $1f rst $10 ld a, $9a rst $10

And so we come to the last part of the routine.

inc b ld a, b cp $15 jr nz, printFrame_loop ret

We point B to the next line, INC B, load it into A, LD A, B, and check if B points to line twenty-one (the line where the bottom of the frame is), CP $15, and if not, repeat the loop until it reaches line twenty-one, JR NZ, printFrame_loop. As soon as B points to line twenty-one, we quit, RET.

The final aspect of the routine is as follows:

; ------------------------------------------------------------------- ; Paint the frame of the screen. ; ; Alters the value of the HL, B and AF registers. ; ------------------------------------------------------------------- PrintFrame: ld hl, frameTopGraph ; HL = top address ld b, frameEnd – frameTopGraph ; B = length call PrintString ; Paints the string ld b, $01 ; B = line 1 printFrame_loop: ld a, $16 ; A = control character AT rst $10 ; Paints it ld a, b ; A = line rst $10 ; Paints it ld a, $00 ; A = column rst $10 ; Paints it ld a, $99 ; A = left lateral character rst $10 ; Paints it ld a, $16 ; A = control character AT rst $10 ; Paints it ld a, b ; A = line rst $10 ; Paints it ld a, $1f ; A = column rst $10 ; Paints it ld a, $9a ; A = right-hand side character rst $10 ; Paints it inc b ; B = next line ld a, b ; A = B cp $15 ; B = 21? jr nz, printFrame_loop ; B != 21, continue loop ret

We will test if it paints the whole frame. Go back to main.asm and replace these lines:

ld hl, frameTopGraph ld b, frameEnd - frameTopGraph call PrintString

For this one:

call PrintFrame

We compile, load in the emulator and see the result.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

As you can see, we have already painted the frame of the screen, but there is still work to be done; we have not erased the screen and you can see things that should not be there.

We clean and colour the screen

Many of the Basic listings you see have a line similar to this:

BORDER 0: INK 7: PAPER 0: CLS

This line sets the screen border to black, the ink to white and the background to black. Finally, the screen is cleaned by applying the ink and background attributes.

We will use the ZX Spectrum ROM to set the ink and background, clean the screen and implement the border colour change.

We start with the part where we clean the screen by opening the const.asm file and adding the following lines:

; System variable where the permanent colour attributes are located. ATTR_P: EQU $5c8d ; ------------------------------------------------------------------- ; ROM routine that clears the screen using the value of ATTR_P ; ------------------------------------------------------------------- CLS: EQU $0daf

ATTR_P contains the permanent colour attributes in the format FBPPPIII, where F = FLASH (0/1), B = BRIGHT (0/1), PPP = PAPER (from 0 to 7) and III = INK (from 0 to 7). On the other hand, CLS clears the screen using the attributes in ATTR_P.

We go back to main.asm and add the following lines just before the PrintFrame call:

ld hl, ATTR_P ld (hl), $07 call CLS

We load the memory address of the permanent attributes in HL, LD HL, ATTR_P; we set FLASH 0, BRIGHT 0, PAPER 0, INK 7, LD (HL), $07. Finally, we clear the screen, CALL CLS.

We compile, load into the emulator and see the results.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

Now we want to change the colour of the border. We have already seen in ZX-Pong that the BEEPER routine of the ROM changes the colour of the border, so it is necessary to store the attributes in a system variable; the attributes have the same format as seen for ATTR_P.

We go back to the const.asm file and add the constant for the system variable where the border attributes are stored.

; System variable where to store the border. Also used by BEEPER. ; The command line attributes are also stored here. BORDCR: EQU $5c48

We go back to main.asm and set the border to black after CALL CLS.

xor a out ($fe), a ld a, (BORDCR) and $c7 or $07 ld (BORDCR), a

We set A to zero, XOR A, and the border to black, OUT ($FE), A. We then load the value of BORDCR into A, LD A, (BORDCR), discard the border colour and so set it to black, AND $C7. We set the colour to white, OR $07, and load the value into BORDCR, LD (BORDCR), A.

The OR $07 command is only necessary while we are in Basic, remember that in BORDCR are the colour attributes of the command line, and if we don’t change the ink to white, it will stay as it was originally, in black, the same colour we gave to the background (border).

We compile, load into the emulator and see the results.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

The only thing left to do is to paint the game information area, which we will do from the command line.

We paint the information of the game

The first thing to do is to define the title line of the game information area, at the beginning of var.asm.

; ------------------------------------------------------------------- ; Title of the item information ; ------------------------------------------------------------------- infoGame: db $10, $03, $16, $00, $00 db 'Lives Points Level Enemies' infoGame_end:

In the first line we set the colour to magenta and position the cursor at the coordinates 0,0. Next we define the titles of the information.

In print.asm we implement the routine that paints the titles of the information.

PrintInfoGame: ld a, $01 call OPENCHAN

When painting the titles of the information on the command line, the first thing to do is to activate channel one. We load one in A, LD A, $01, and call the channel change, CALL OPENCHAN.

ld hl, infoGame ld b, infoGame_end - infoGame call PrintString

We load in HL the address of the title of the information, LD HL, infoGame, in B the length, LD B, infoGame_end – infoGame, and then we call to print the string, CALL PrintString.

ld a, $02 call OPENCHAN ret

Finally, we reactivate channel two (the top screen) and exit.

The final aspect of the routine is as follows:

; ------------------------------------------------------------------- ; Paint the game information headings. ; Alters the value of the A, C and HL registers. ; ------------------------------------------------------------------- PrintInfoGame: ld a, $01 ; A = 1 call OPENCHAN ; Activates channel 1 ld hl, infoGame ; HL = address string titles ld b, infoGame_end - infoGame ; B = length call PrintString ; Paints titles ld a, $02 ; A = 2 call OPENCHAN ; Activates channel 2 ret

We go back to main.asm and after CALL PrintFrame we add the call to paint the start information titles.

call PrintInfoGame

If we compile now, try it if you want, it seems that the last thing we implemented does not work, it does not paint the title information. Actually it does, but when we go back to Basic, the message 0 OK, 40:1 deletes it.

To avoid this, we’ll stay in an infinite loop; we’ll go to the RET statement that brings us back to Basic and change it to:

Main_loop: jr Main_loop

The final main.asm code is as follows:

org $5dad Main: ld a, $02 call OPENCHAN ld hl, udgsCommon ld (UDG), hl ld hl, ATTR_P ld (hl), $07 call CLS xor a out ($fe), a ld a, (BORDCR) and $c7 or $07 ld (BORDCR), a call PrintFrame call PrintInfoGame Main_loop: jr Main_loop include "const.asm" include "graph.asm" include "print.asm" include "var.asm" end Main

We compile, load the emulator and see the result.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

I don’t know about you, but I don’t like the fact that the titles are so close to the frame. Since we only have two lines in the command line without scrolling, and we need to draw the data below the title line, we have only one option left to remove a line from the play area.

In var.asm we find the frameBottomGraph tag, and one line down we see the DB that positions the cursor; we are going to change this line so that the Y coordinate is twenty instead of twenty-one.

db $16, $14, $00

In print.asm we now find the printFrame_loop tag. This loop runs until B is twenty-one; we need to change this condition so that it runs until it is twenty. Two lines above the RET of this routine we have CP $15, this is the line we need to modify, leaving it as follows:

cp $14 ; B = 20?

We compile, load into the emulator and see the results. Now we have our play area.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle ZX Spectrum Assembly, Space Battle

In the next chapter of ZX Spectrum Assembly, we will implement the ship, its movement and therefore the controls.

Download the source code from here.

ZX Spectrum Assembly, Space Battle by Juan Antonio Rubio García.
Translation by Felipe Monge Corbalán.
This work is licensed to Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0).
Any comments are always welcome.

Ortografía 1: Vocabulario (Mind Games España, 1986) [Recuerdos de 8 Bits] [Leer]


Ya hacía tiempo que no comentaba uno de estos maravillosos y útiles juegos educativos… y aquí me encuentro otra vez, con esta pequeña rareza de Mind Games España donde se pondrán a prueba nuestros conocimientos de vocabulario. Además, nos da la opción de competir contra otros tres jugadores y un número bastante elevado de opciones. Eso si, no le pidamos peras al olmo, que al ser un juego programado en BASIC, a veces las palabras se repiten con demasiada frecuencia. El mayor problema es que en cada partida, nos dan un tiempo de 20 minutos para responder y claro, la capacidad es demasiado limitada como para meter más.

Primero nos preguntará por el número de jugadores, después el nombre y ya pasamos a las opciones que nos dan para aprender y practicar. Podemos elegir miscelania, sinónimos, antónimos, numerales, gentilicios, singulares, plurales, masculinos, femeninos y abreviaturas.

Una vez seleccionado lo que queremos, el programa nos lanza la pregunta y nosotros tenemos que escribir la respuesta. Si acertamos, nos dará dos puntos. En cambio si fallamos, nos dará una segunda oportunidad enseñándonos 3 opciones. Si acertamos nos dará 1 solo punto y si una vez más erramos en la respuesta, nos dará la posibilidad de elegir otra de las 3 opciones. Eso si, en este punto si acertamos, ya no nos dará puntuación.

Clásico juego educativo digno de las épocas de EGB. Venga, a probarlo y a practicar ¿o tenéis miedo a tener oxidados vuestros conocimientos?

Descargas:

Ficha:

Juego: Ortografía 1
Genero: Educativo
Año: 1986
Programación: Pere Marqués / Sara Ranea
Distribución: Mind Games España
Dificultad: …
Mi Retropuntuación: 6

Shyre, nuevo juego de Platty Soft. Mecánicas clásicas para un juego fresco y divertido [MSXBlog de Konamito] [Leer]


Raúl Portales acaba de publicar un nuevo juego bajo su sello Platty Soft, una mezcla de géneros con un aspecto muy bonito y bastante divertido.

Hablamos de Shyre, un videojuego que se inspira principalmente en los clásicos Eggerland Mystery y Sokoban con sus mecánicas de resolución de puzles a las que se les une la exploración de pantallas para conseguir objetos que nos serán de vital importancia en nuestra misión de salir con vida del planeta Shyre que da nombre al juego.

A mí me gustan los juegos de puzles, y si además tienen un acabado gráfico tan chulo como este Shyre, todavía más. Al jugarlo no puedo evitar recordar los videojuegos japoneses de los años ochenta, capaces de engancharme durante horas frente al televisor. Jugando con Shyre he vuelto a sentir lo mismo de antaño.

Me quito el sombrero ante el trabajo de Raúl en el aspecto gráfico y sobre todo por haber conseguido hacer que una idea clásica, sea tan fresca y divertida en pleno siglo XXI.

Según su autor, Shyre comenzó como un ejemplo de programación de un juego tipo dungeon crawler para su libro Modern MSX Basic Game Development. Y mirad en qué se ha convertido finalmente.

El juego está disponible para descargar, junto con su manual de instrucciones desde su página oficial. Además, se está preparando una tirada del juego en formato físico para los que estén interesados a un precio de 25 euros. En la propia página encontraréis el enlace para poder hacer una reserva.

Las copias estarán disponibles para final de año, coincidiendo con la celebración del evento MSX GOTO40 en Países Bajos.

Enlace relacionado: Shyre

Joystick "Quick Joy" (elite Micro-Plus) [Retro Ordenadores Orty] [Leer]


Alta en la colección: Joystick "Quick Joy"  (elite Micro-Plus). Controlador de juegos con conector DB9 (protocolo Atari) utilizado en la mayoría de ordenadores y consolas de la época. Se distribuyó en Alemania con el nombre de "Quick Joy" (no confundir con los joysctick Quickjoy de la empresa alemana Jöllenbeck). También se vendieron a través de la cadena de grandes almacenes alemana Kaufhof AG Köln, con el nombre de "elite Micro-Plus". El Joystick "Quick Joy" estaba diseñado con componentes internos de larga duración (micro interruptores). Tenía dos pulsadores (de funcionamiento único), uno en la palanca y otro centrado en la parte posterior de la carcasa superior (con los pulsadores en esa posición, el controlador se podía utilizar tanto con la mano derecha como con la izquierda). En el bisel frontal tenía un selector de disparo automático.


De la parte posterior salía el cable con el conector DB9. En el bisel posterior tenía una serigrafía con el nombre (Quick Joy).


La disposición de los pulsadores en la parte superior de la palanca y centrado en la parte posterior de la carcasa superior permitía usarlos tanto por jugadores diestros como zurdos.


A diferencia de la mayor parte de los joystick, el "Quick Joy" solo tenía tres puntos de apoyo (en lugar de cuatro). Para acceder al interior se extraían cuatro tornillos y se separaban las carcasas, quedando a la vista el mecanismo interno de la palanca (micro interruptores) y una pequeña placa que daba servicio al selector de disparo automático.



ZX Spectrum Assembly, Space Battle – 0x02 Painting UDG [Espamatica] [Leer]


In this chapter of ZX Spectrum Assembly, we will start drawing with UDG.

Painting UDG

The ZX Spectrum character map consists of two hundred and fifty-six values, of which we can redefine twenty-one, namely those between $90 (144) and $A4 (164) inclusive.

Create a folder called Step02 and copy var.asm from Step01.

Where are the UDG?

The value of memory address $5C7B contains the memory address where the user-defined graphics are located, so all we need to do is load the address where our graphics are defined into that memory address. Once this is done, drawing any character between $90 and $A4 with RST $10 will draw the graphics we have defined.

We create the file called const.asm and add the following:

; Memory address where user-defined graphics are loaded. UDG: EQU $5c7b

In this constant we will have the address where we store the address where our graphics are located.

We paint our UDGs

It’s time for our first test, we’re going to paint the UDGs. Create main.asm and add the following lines:

org $5dad Main: ld a, $90 ld b, $15 Loop: push af rst $10 pop af inc a djnz Loop ret end Main

The first thing to do is to specify the address where we want to load the program, ORG $5DAD. We load the program at position $5DAD (23981) as it will be compatible with 16K models.

The next line is a label, Main, the entry point of the program.

Next we load one hundred and forty-four into A, LD A, $90, and twenty-one into B, LD B, $15, so we paint from character one hundred and forty-four to one hundred and sixty-four, for a total of twenty-one characters.

We make a loop of twenty-one iterations, starting with the loop label, Loop. We then keep the value of A, PUSH AF; the next instruction, RST $10, prints the character to which the code loaded into A belongs and modifies the register. We recover the value of A, POP AF.

We then increment A, INC A, so that it points to the next character, decrement B and jump to the loop if it has not reached zero, DJNZ Loop. Finally, we return to Basic, RET.

The last line tells PASMO to include the call to the address of the Main tag in the Basic loader.

Now it’s time to compile and see the results in the emulator.

pasmo --name Martian --tapbas main.asm martian.tap martian.log

But have we painted our graphics?

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

We have painted the capital letters A to U because we have not indicated where our graphics are.

Next, we go to the main.asm file, and under the Main tag we add the following lines:

ld hl, udgsCommon ld (UDG), hl

We load into HL the address where the graphics are, LD HL, udgsCommon, and load that value into the address where the location of our graphics is, LD (UDG), HL.

As both udgsCommon and UDG are not defined in the main.asm file, we need to add the includes for the const.asm and var.asm files after the RET statement.

include "const.asm" include "var.asm"

Now we can recompile the program, load it into the emulator and see our graphics on the screen.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle

Much better, right? But we painted twenty-one graphics: the ship, the shot, the explosion, the frame, the blank character, the graphics of enemy one and part of the graphics of enemy two. How are we going to paint the other two graphics of enemy two and the rest?

We load the enemies’ UDGs

Looking at the graphics definition, the first tag is called udgsCommon, and this should give us a clue as to how we’re going to do this. We have defined fifteen common UDGs (ship, shot, explosion, frame and target), so we are going to define thirty-two bytes to be able to dump the enemy graphics into them; we do this because the enemies are one per level, and the dump is only done once, just at the level change.

In the var.asm file, above udgsEnemiesLeve1, let’s add the following lines:

udgsExtension: db $00, $00, $00, $00, $00, $00, $00, $00 ; $9f Left/Up db $00, $00, $00, $00, $00, $00, $00, $00 ; $a0 Right/Up db $00, $00, $00, $00, $00, $00, $00, $00 ; $a1 Left/Down db $00, $00, $00, $00, $00, $00, $00, $00 ; $a2 Right/Down

In this block of memory we are going to dump the graphics of the enemies, depending on the level we are in.

Try compiling now and see how it looks. The enemy graphics are gone, aren’t they? It’s the udgsExtension painting.

We create the file graph.asm and implement in it the routine that loads into udgsExtension the graphics of the enemies of each of the levels, data that it receives in A.

To calculate the address where the graphics are, we multiply the level by thirty-two (bytes occupied by the graphics) and add the result to the address where the graphics of the first enemy are.

LoadUdgsEnemies: dec a ld h, $00 ld l, a

Since the levels range from one to thirty, we decrement A, DEC A, so that it does not add one level too many (level one adds zero to udgsEnemies, level two adds one, etc.).

The next step is to load the level into HL, for which we load zero into H, LD H, $00, and the level into L, LD L, A.

add hl, hl add hl, hl add hl, hl add hl, hl add hl, hl

We multiply the level by thirty-two by adding HL to itself five times, ADD HL, HL. The first addition is like multiplying by two, the second by four, by eight, by sixteen and by thirty-two.

ld de, udgsEnemiesLevel1 add hl, de ld de, udgsExtension ld bc, $20 ldir ret

We load the address of the first enemy graphic into DE, LD DE, udgsEnemiesLevel1, and add it to HL, ADD HL, DE. We load the extension address DE, LD DE, udgsExtension, load the number of bytes we are going to load into udgsExtension, LD BC, $20, and load the thirty-two bytes of the level’s enemy graphics into udgsExtension, LDIR. Finally we exit, RET.

The final aspect of the routine is as follows:

; ------------------------------------------------------------------- ; Load user-defined graphics relating to enemies ; ; Entry: A -> Level from 1 to 30 ; ; Alters the value of the A, BC, DE and HL registers. ; ------------------------------------------------------------------- LoadUdgsEnemies: dec a ; A = A - 1 which does not add one level more ld h, $00 ld l, a ; HL = level add hl, hl ; HL = HL * 2 add hl, hl ; * 4 add hl, hl ; * 8 add hl, hl ; * 16 add hl, hl ; * 32 ld de, udgsEnemiesLevel1 ; DE = address enemy graphics 1 add hl, de ; HL = HL + DE ld de, udgsExtension ; DE = extension address ld bc, $20 ; BC = bytes to copy, 32 ldir ; Copies enemy bytes to extension ret

Let’s test the new routine by editing the main.asm file, starting by changing the LD B, $15 instruction, above the Loop label, and leaving it as follows; it prints the first fifteen UDGs, the common ones:

ld b, $0f

The rest is implemented between the DJNZ Loop instruction and the RET instruction.

ld a, $01 ld b, $1e

We load in A the first level, LD A, $01, in B the total number of levels (thirty), LD B, $1E, and implement a loop that draws the enemies of the thirty levels.

Loop2: push af push bc call LoadUdgsEnemies

We keep AF, PUSH AF, and BC, PUSH BC, as we use A and B to control the enemies we paint and the loop iterations. Next, we call the routine that loads the level’s enemy graphics into udgsExtension, CALL LoadUdgsEnemies.

ld a, $9f rst $10 ld a, $a0 rst $10 ld a, $a1 rst $10 ld a, $a2 rst $10

The characters corresponding to the enemy graphics are $9F, $A0, $A1 and $A2; we load them into A, LD A, $9F, and paint, RST $10. We repeat the process with $A0, $A1 and $A2.

pop bc pop af inc a djnz Loop2

Recover BC, POP BC, AF, POP AF, increment A to go to the next level, INC A, and repeat until B is zero, DJNZ Loop2.

Finally, at the end of the file and before END Main, we insert the file graph.asm.

include "graph.asm"

The final main.asm code is as follows:

org $5dad Main: ld hl, udgsCommon ld (UDG), hl ld a, $90 ld b, $0f Loop: push af rst $10 pop af inc a djnz Loop ld a, $01 ld b, $1e Loop2: push af push bc call LoadUdgsEnemies ld a, $9f rst $10 ld a, $a0 rst $10 ld a, $a1 rst $10 ld a, $a2 rst $10 pop bc pop af inc a djnz Loop2 ret include "const.asm" include "graph.asm" include "var.asm" end Main

We compile, load into the emulator and see that we have painted all our graphics.

ZX Spectrum Assembly, Space BattleZX Spectrum Assembly, Space Battle ZX Spectrum Assembly, Space Battle

At this point we have defined all the graphics and learned how to paint them.

In the next chapter of ZX Spectrum Assembly, we will paint the play area.

Download the source code from here.

ZX Spectrum Assembly, Space Battle by Juan Antonio Rubio García.
Translation by Felipe Monge Corbalán.
This work is licensed to Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0).
Any comments are always welcome.

BOOTLEG GAMES REVIEW (PARTE-CXXVII): Hong Kong 97 (Unl) (SUPER FAMICOM) [Thue Ryoga's Gyroscope] [Leer]


{twitter}: @FpgaWarrior / {YouTube} Hong Kong 97 (Unl) (SUPER FAMICOM) (Pirate) Hong Kong 97​, estilizado como HONGKONG1997 en la portada del juego, es un videojuego de disparos multidireccional sin licencia de 1995 hecho para la Super Famicom en formato de unidad de disco por HappySoft Ltd., una compañía japonesa de juegos caseros o ‘Homebrew’. Fue diseñado por el … Sigue leyendo →

UFO Kamen Yakisoban: Kettler no Kuroi Inbo [Mundo Retrogaming] [Leer]


UFO Kamen Yakisoban: Kettler no Kuroi Inbo es un juego programado por KID y publicado y distribuido por Den'Z para Super Nintendo, saliendo a la venta únicamente en Japón el 14 de octubre de 1994. Se trata de un entretenido beat 'em up para un solo jugador protagonizado por UFO Kamen Yakisoban, protagonista de los anuncios de la marca de noodles yakisoba instantáneos UFO.



Leer más »
SC72MFZEDV43

RetroAlacant VII [El Blog de Manu] [Leer]


A pesar de que esta feria ha celebrado este año su séptima edición, esta es la primera vez que me acercaba a Alicante a visitarla. El viaje lo hice ayer sábado junto con mi amigo Adrián, y dio la casualidad que Bruno Sol cogió también ese mismo tren para acercarse a la capital alicantina, lo que hizo que el camino al Centro Cultural Las Cigarreras fuese de lo más animado.

Controlador "Joy Stick 125" con cuatro pulsadores de disparo y dos conectores DB9 (estándar y Spectrum +2) [Retro Ordenadores Orty] [Leer]


Alta en la colección: Controlador "·Joy Stick 125" con cuatro pulsadores de disparo y dos conectores DB9 (estándar y Spectrum +2). Controlador de juegos genérico diseñado con cuatro pulsadores de disparo y dos conectores DB9: un conector (de color negro) compatible con la mayoría de las consolas y ordenadores de la época (ZX Spectrum, C64, Atari, MSX, Amstrad y otros) y otro conector (de color gris) específico para el ZX Spectrum +2 y +3 (no eran compatibles con la norma Atari). Su funcionalidad y aspecto externo eran similares al Cheetah 125 + fabricado por la empresa Cheetah Marketing Ltd (UK) en 1986. Estaba diseñado con componentes internos (pletinas metálicas) susceptibles de rotura con un uso prolongado. Los pulsadores de disparo (dos en la palanca y dos en la carcasa superior) estaban duplicados (funcionaban como si solo fueran dos), lo que permitía utilizar el joystick tanto con la mano izquierda como con la derecha. En el bisel frontal tenía una etiqueta con el nombre (JOY STICK 125).

Enlace a accesorios comunes

De la parte posterior salía el cable con los dos conectores DB9. Entre la palanca y el bisel posterior tenía un selector de disparo automático (ON/OFF).


La disposición de los pulsadores en la parte superior de la palanca y a ambos lados de la carcasa superior permitía usarlos tanto por jugadores diestros como zurdos.


En la carcasa inferior tenía grabado en relieve el lugar de fabricación (MADE IN CHINA) y el numero de patente (16577). Para acceder al interior se extraían cuatro tornillos y se separaban las carcasas quedando a la vista el mecanismo de la palanca (pletinas metálicas) y una pequeña placa con los contactos de los pulsadores de la carcasa superior.


Joystick con cuatro pulsadores y conector DB9 [Retro Ordenadores Orty] [Leer]


Alta en la colección: Joystick con cuatro pulsadores y conector DB9. Controlador de juegos genérico diseñado con cuatro pulsadores de disparo y un conector DB9 compatible con la mayoría de las consolas y ordenadores de la época (ZX Spectrum, C64, Atari, MSX, Amstrad y otros). Su funcionalidad y aspecto externo eran similares al Cheetah 125 fabricado por la empresa Cheetah Marketing Ltd (UK). Estaba diseñado con componentes internos (pletinas metálicas) susceptibles de rotura con un uso prolongado. Los pulsadores de disparo (dos en la palanca y dos en la carcasa superior) estaban duplicados (funcionaban como si solo fueran dos), lo que permitía utilizar el joystick tanto con la mano izquierda como con la derecha. En el bisel frontal tenía una etiqueta con el nombre (falta).


De la parte posterior salía el cable con el conector DB9. Entre la palanca y el bisel posterior tenía un selector de disparo automático (ON/OFF).


La disposición de los pulsadores en la parte superior de la palanca y a ambos lados de la carcasa superior permitía usarlos tanto por jugadores diestros como zurdos.


En la carcasa inferior tenía grabado en relieve el lugar de fabricación (MADE IN TAIWAN). Para acceder al interior se extraían cuatro tornillos y se separaban las carcasas quedando a la vista el mecanismo de la palanca (pletinas metálicas) y una pequeña placa con los contactos de los pulsadores (sujeta a la carcasa superior).



Retro Alacant 2023 [AUA Amstrad] [Leer]


Durante el día de ayer sábado 16 y hoy domingo 17 se está celebrando una nueva edición de Retro Alacant 2023 en el Centro Cultural Las Cigarreras, de Alicante.

Esto es un festival de la cultura “retro”, un espacio de disfrute que gira en torno a los videojuegos, consolas, juegos de mesa, y todo aquel material que nos hace recordar mediante torneos solidarios, talleres, música, zona de expositores, batallas arcade, etc … la tecnología de los 80-90 y su evolución en el tiempo.

Una expedición de AUA se ha desplazado hasta el mismo para montar un stand con máquinas y hardware del Amstrad CPC.

Además, todo aquel que se acerque podrá disfrutar de diversos juegos, máquinas arcades, charlas, talleres, torneos, mercadillo, etc.

Quizás una de las principales atracciones en lo que se refiere al mundo del Amstrad, sea la presencia de Roland Perry, ya que fue el ingeniero encargado del diseño del Amstrad CPC, tenemos que dar las gracias la organización de Retro Alacant por hacer esto posible.

Retro Alacant 2023

Retro Alacant 2023 14 Retro Alacant 2023 15 Retro Alacant 2023 16 Retro Alacant 2023 17 retro alacant 2023 Retro Alacant 2023 18 Retro Alacant 2023 19 Retro Alacant 2023 20Hobbyretro Stand Retro Alacant 2023 21 Retro Alacant 2023 22 Retro Alacant 2023 23 Retro Alacant 2023 24 Retro Alacant 2023 25placa fallida del prototipo del cpc con el 6502 Retro Alacant 2023 26interface de comunicación RS232

Prototipo MOS del CPC

En una entrevista que se le ha hecho conoceremos de primera mano toda la historia de la creación de esta computadora y todas las curiosidades que llevo el proceso y las derivadas de su cargo de director de proyectos en Amstrad.

Gran afluencia de público como se puede observar en el video que os dejamos a continuación, junto con algunas fotografías del evento, esperemos que os guste.

Por favor, acepta las cookies de YouTube para poder ver este video. Aceptando, accederás al contenido de YouTube, un servicio externo y gestionado por terceros.

Leer la privacidad de Youtube.

Aceptando este aviso, tu selección será guardara y la página se refrescará.

Aceptar Cookiesaccept

ZX Spectrum Assembly, Space Battle – 0x01 Definition of graphics [Espamatica] [Leer]


In this chapter of ZX Spectrum Assembly, we will define all the graphics used in Space Battle.

Definition of graphics

We will learn how to do the hexadecimal/binary conversion on the fly by doing our first exercise.

You can use ZX Paintbrush, or you can use the templates I created for GIMP, which you can download from these addresses:

The templates I have prepared are as follows:

  • 8x8Template: for creating 8×8 pixel graphics.
  • 256x192Template: the size of the ZX Spectrum’s screen.

For Space Battle we will use 8×8 templates. I will show you the image of the graphics, the hexadecimal codes, and your job will be to convert the codes into pixels, head first, to draw the graphics on the templates.

Hexadecimal/binary conversion

Although at first it may seem complicated to convert a hexadecimal number to binary, and vice versa, it is very simple and practically straightforward. We need to know the value of each bit (pixel) in blocks of four, which gives us a value between 0 and F, a value that can be represented by each hexadecimal digit.

In a byte, each bit to one has the following values:

Bit76543210
Value1286432168421
ZX Spectrum Assembly, Space Battle

When we convert from hexadecimal to binary, we divide the byte into two blocks of four bits (nibbles), resulting in a range of values between 0 and F (8 + 4 + 2 + 1 = 15 = F). To convert from binary to hexadecimal, we add the value of the bits to one of each nibble, which gives us the value in hexadecimal.

Suppose we have the following binary value:

0101 1001

If we add up the values of the nibbles, the result would be:

0 + 4 + 0 + 1 = 5       8 + 0 + 0 + 1 = 9

The result is that 01011001 is 59 in hexadecimal.

In hexadecimal a byte is represented by two digits. What if the value of some of the nibbles is greater than nine?

11011011 = 8 + 4 + 0 + 1 = 13 y 8 + 0 + 2 + 1 = 11

How do we represent thirteen and eleven with only one digit each? In hexadecimal, values from ten to fifteen are represented by letters.

Decimal123456789101112131415
Hexadecimal123456789ABCDEF
ZX Spectrum Assembly, Space Battle

In the example above, the hexadecimal value of 11011011 is DB.

Practising hexadecimal/binary conversion

A good way to learn is by doing, and this is what I propose to do below. Let’s look at the definition of all the UDGs we are going to use (the hexadecimal values) and draw them by doing the conversion from hexadecimal to binary.

If we work with nibbles (4 bits), the conversion table for a byte would be as follows:

Byte76543210
Value84218421
ZX Spectrum Assembly, Space Battle

We will create a folder called Step01 and inside it a file called var.asm. Having this table at hand, we are going to draw the ship, whose definition in hexadecimal (which we are going to copy into the created file) is the following:

udgsCommon: db $24, $42, $99, $bd, $ff, $18, $24, $5a ; $90 Ship

We convert to binary.

Byte76543210
Value84218421
$24  X  X  
$42 X    X 
$99X  XX  X
$bdX XXXX X
$ffXXXXXXXX
$18   XX   
$24  X  X  
$5a X XX X 
ZX Spectrum Assembly, Space Battle

If you transfer this conversion to ZX Paintbrush, or to the templates, the result should look like this:

ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle

We are going to continue practising, doing the conversions for the shot and the animation of the explosion of the ship. It is important that you try to translate it from hexadecimal to binary and from there to the graphics.

db $00, $18, $24, $5a, $5a, $24, $18, $00 ; $91 Shot
Byte76543210
Value84218421
$00        
$18   XX   
$24  X  X  
$5a X XX X 
$5a X XX X 
$24  X  X  
$18   XX   
$00        
ZX-Spectrum Assembly, Space Battle ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
db $00, $00, $00, $00, $24, $5a, $24, $18 ; $92 Blast 1
Byte76543210
Value84218421
$00        
$00        
$00        
$00        
$24  X  X  
$5a X XX X 
$24  X  X  
$18   XX   
ZX-Spectrum Assembly, Space Battle
db $00, $00, $00, $14, $2a, $34, $24, $18 ; $93 Blast 2
Byte76543210
Value84218421
$00        
$00        
$00        
$14   X X  
$2a  X X X 
$34  XX X  
$24  X  X  
$18   XX   
ZX-Spectrum Assembly, Space Battle
db $00, $00, $0c, $12, $2a, $56, $64, $18 ; $94 Blast 3
Byte76543210
Value84218421
$00        
$00        
$0c    XX  
$12   X  X 
$2a  X X X 
$56 X X XX 
$64 XX  X  
$18   XX   
ZX-Spectrum Assembly, Space Battle
db $20, $51, $92, $d5, $a9, $72, $2c, $18 ; $95 Blast 4
Byte76543210
Value84218421
$20  X     
$51 X X   X
$92X  X  X 
$d5XX X X X
$a9X X X  X
$72 XXX  X 
$2c  X XX  
$18   XX   
ZX-Spectrum Assembly, Space Battle ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle

From here on, I will just give the hexadecimal definition and the image of the final appearance of each UDG.

If you are wondering what the number in the comments of each definition means, it is the code of the character we are redefining, i.e. the character code we are going to send to the printer to make the graphic. Don’t worry if you don’t understand it now, it will be much clearer later.

db $3f, $6a, $ff, $b8, $f3, $a7, $ef, $ae ; $96 Top/Left db $ff, $aa, $ff, $00, $ff, $ff, $00, $00 ; $97 Top db $fc, $ae, $fb, $1f, $cd, $e7, $f5, $77 ; $98 Top/Right db $ec, $ac, $ec, $ac, $ec, $ac, $ec, $ac ; $99 Left db $35, $37, $35, $37, $35, $37, $35, $37 ; $9a Right db $ee, $af, $e7, $b3, $f8, $df, $75, $3f ; $9b Bottom/Left db $00, $00, $ff, $ff, $00, $ff, $55, $ff ; $9c Bottom db $75, $f7, $e5, $cf, $1d, $ff, $56, $fc ; $9d Bottom/Right db $00, $00, $00, $00, $00, $00, $00, $00 ; $9e White
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel1: db $8c, $42, $2d, $1d, $b4, $be, $46, $30 ; $9f Left/Up db $31, $42, $b4, $b8, $2d, $7d, $62, $0c ; $a0 Right/Up db $30, $46, $be, $b4, $1d, $2d, $42, $8c ; $a1 Left/Down db $0c, $62, $7d, $2d, $b8, $b4, $42, $31 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel2: db $c0, $fb, $69, $5d, $7b, $14, $4a, $79 ; $9f Left/Up db $03, $df, $96, $ba, $de, $28, $52, $9e ; $a0 Right/Up db $79, $4a, $14, $7b, $5d, $69, $fb, $c0 ; $a1 Left/Down db $9e, $52, $28, $de, $ba, $96, $df, $03 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel3: db $fc, $84, $b4, $af, $99, $f7, $14, $1c ; $9f Left/Up db $3f, $21, $2d, $f5, $99, $ef, $28, $38 ; $a0 Right/Up db $1c, $14, $f7, $99, $af, $b4, $84, $fc ; $a1 Left/Down db $38, $28, $ef, $99, $f5, $2d, $21, $3f ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel4: db $f2, $95, $98, $fe, $39, $55, $92, $4d ; $9f Left/Up db $4f, $a9, $19, $7f, $9c, $aa, $49, $b2 ; $a0 Right/Up db $4d, $92, $55, $39, $fe, $98, $95, $f2 ; $a1 Left/Down db $b2, $49, $aa, $9c, $7f, $19, $a9, $4f ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel5: db $76, $99, $a4, $d4, $47, $bd, $8a, $4c ; $9f Left/Up db $6e, $99, $25, $2b, $e2, $bd, $51, $32 ; $a0 Right/Up db $4c, $8a, $bd, $47, $d4, $a4, $99, $76 ; $a1 Left/Down db $32, $51, $bd, $e2, $2b, $25, $99, $6e ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel6: db $98, $66, $59, $aa, $b6, $49, $5a, $24 ; $9f Left/Up db $19, $66, $9a, $55, $6d, $92, $5a, $24 ; $a0 Right/Up db $24, $5a, $49, $b6, $aa, $59, $66, $98 ; $a1 Left/Down db $24, $5a, $92, $6d, $55, $9a, $66, $19 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel7: db $04, $72, $5d, $74, $2e, $be, $4c, $20 ; $9f Left/Up db $20, $4e, $ba, $2e, $74, $7d, $32, $04 ; $a0 Right/Up db $20, $4c, $be, $2e, $74, $5d, $72, $04 ; $a1 Left/Down db $04, $32, $7d, $74, $2e, $ba, $4e, $20 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel8: db $00, $7c, $5a, $68, $7c, $4f, $26, $04 ; $9f Left/Up db $00, $3e, $5a, $16, $3e, $f2, $64, $20 ; $a0 Right/Up db $04, $26, $4f, $7c, $68, $5a, $7c, $00 ; $a1 Left/Down db $20, $64, $f2, $3e, $16, $5a, $3e, $00 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel9: db $e0, $d8, $b6, $6e, $5b, $36, $3c, $08 ; $9f Left/Up db $07, $1b, $6d, $76, $da, $6c, $3c, $10 ; $a0 Right/Up db $08, $3c, $36, $5b, $6e, $b6, $d8, $e0 ; $a1 Left/Down db $10, $3c, $6c, $da, $76, $6d, $1b, $07 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel10: db $e0, $ce, $bf, $3c, $73, $75, $6a, $2c ; $9f Left/Up db $07, $73, $fd, $3c, $ce, $ae, $56, $34 ; $a0 Right/Up db $2c, $6a, $75, $73, $3c, $bf, $ce, $e0 ; $a1 Left/Down db $34, $56, $ae, $ce, $3c, $fd, $73, $07 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel11: db $e0, $de, $bf, $7c, $7b, $75, $6a, $2c ; $9f Left/Up db $07, $7b, $fd, $3e, $de, $ae, $56, $34 ; $a0 Right/Up db $2c, $6a, $75, $7b, $7c, $bf, $de, $e0 ; $a1 Left/Down db $34, $56, $ae, $de, $3e, $fd, $7b, $07 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel12: db $e0, $fe, $f7, $6c, $5f, $7e, $6c, $28 ; $9f Left/Up db $07, $7f, $ef, $36, $fa, $7e, $36, $14 ; $a0 Right/Up db $28, $6c, $7e, $5f, $6c, $f7, $fe, $e0 ; $a1 Left/Down db $14, $36, $7e, $fa, $36, $ef, $7f, $07 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel13: db $07, $6c, $7e, $34, $6f, $fb, $ae, $8c ; $9f Left/Up db $e0, $36, $7e, $2c, $f6, $df, $75, $31 ; $a0 Right/Up db $8c, $ae, $fb, $6f, $34, $7e, $6c, $07 ; $a1 Left/Down db $31, $75, $df, $f6, $2c, $7e, $36, $e0 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel14: db $21, $1a, $96, $75, $4c, $3c, $62, $90 ; $9f Left/Up db $84, $58, $69, $ae, $32, $3c, $46, $09 ; $a0 Right/Up db $90, $62, $3c, $4c, $75, $96, $1a, $21 ; $a1 Left/Down db $09, $46, $3c, $32, $ae, $69, $58, $84 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel15: db $04, $02, $0d, $14, $28, $b0, $40, $20 ; $9f Left/Up db $20, $40, $b0, $28, $14, $0d, $02, $04 ; $a0 Right/Up db $20, $40, $b0, $28, $14, $0d, $02, $04 ; $a1 Left/Down db $04, $02, $0d, $14, $28, $b0, $40, $20 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel16: db $30, $48, $be, $b9, $7c, $2e, $27, $13 ; $9f Left/Up db $0c, $12, $7d, $9d, $3e, $74, $e4, $c8 ; $a0 Right/Up db $13, $27, $2e, $7c, $b9, $be, $48, $30 ; $a1 Left/Down db $c8, $e4, $74, $3e, $9d, $7d, $12, $0c ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel17: db $c0, $df, $36, $7c, $58, $77, $66, $44 ; $9f Left/Up db $03, $fb, $6c, $3e, $1a, $ee, $66, $22 ; $a0 Right/Up db $44, $66, $77, $58, $7c, $36, $df, $c0 ; $a1 Left/Down db $22, $66, $ee, $1a, $3e, $6c, $fb, $03 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel18: db $02, $71, $69, $57, $2f, $1e, $9e, $78 ; $9f Left/Up db $40, $8e, $96, $ea, $f4, $78, $79, $1e ; $a0 Right/Up db $78, $9e, $1e, $2f, $57, $69, $71, $02 ; $a1 Left/Down db $1e, $79, $78, $f4, $ea, $96, $8e, $40 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel19: db $20, $7f, $e6, $4e, $5e, $79, $78, $44 ; $9f Left/Up db $04, $fe, $67, $72, $7a, $9e, $1e, $22 ; $a0 Right/Up db $44, $78, $79, $5e, $4e, $e6, $7f, $20 ; $a1 Left/Down db $22, $1e, $9e, $7a, $72, $67, $fe, $02 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel20: db $36, $2f, $db, $be, $7c, $db, $f6, $64 ; $9f Left/Up db $6c, $f4, $db, $7d, $3e, $db, $6f, $26 ; $a0 Right/Up db $64, $f6, $db, $7c, $be, $db, $2f, $36 ; $a1 Left/Down db $26, $6f, $db, $3e, $7d, $db, $f4, $6c ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel21: db $00, $70, $6e, $54, $2b, $34, $28, $08 ; $9f Left/Up db $00, $0e, $76, $2a, $d4, $2c, $14, $10 ; $a0 Right/Up db $08, $28, $34, $2b, $54, $6e, $70, $00 ; $a1 Left/Down db $10, $14, $2c, $d4, $2a, $76, $0e, $00 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel22: db $00, $78, $6e, $56, $6d, $3b, $34, $0c ; $9f Left/Up db $00, $1e, $76, $6a, $b6, $dc, $2c, $30 ; $a0 Right/Up db $0c, $34, $3b, $6d, $56, $6e, $78, $00 ; $a1 Left/Down db $30, $2c, $dc, $b6, $6a, $76, $1e, $00 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel23: db $0c, $02, $3d, $35, $ac, $b8, $40, $30 ; $9f Left/Up db $30, $40, $bc, $ac, $35, $1d, $02, $0c ; $a0 Right/Up db $30, $40, $b8, $ac, $35, $3d, $02, $0c ; $a1 Left/Down db $0c, $02, $1d, $35, $ac, $bc, $40, $30 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel24: db $00, $77, $6e, $56, $2a, $74, $7b, $42 ; $9f Left/Up db $00, $ee, $76, $6a, $54, $2e, $de, $42 ; $a0 Right/Up db $42, $7b, $74, $2a, $56, $6e, $77, $00 ; $a1 Left/Down db $42, $de, $2e, $54, $6a, $76, $ee, $00 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel25: db $c0, $ff, $76, $6c, $5f, $7e, $6c, $48 ; $9f Left/Up db $03, $ff, $6e, $36, $fa, $7e, $36, $12 ; $a0 Right/Up db $48, $6c, $7e, $5f, $6c, $76, $ff, $c0 ; $a1 Left/Down db $12, $36, $7e, $fa, $36, $6e, $ff, $03 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel26: db $3c, $7e, $f7, $e8, $da, $e1, $68, $24 ; $9f Left/Up db $3c, $7e, $ef, $17, $5b, $87, $16, $24 ; $a0 Right/Up db $24, $68, $e1, $da, $e8, $f7, $7e, $3c ; $a1 Left/Down db $24, $16, $87, $5b, $17, $ef, $7e, $3c ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel27: db $04, $02, $39, $2d, $3f, $9e, $4c, $38 ; $9f Left/Up db $20, $40, $9c, $b4, $fc, $79, $32, $1c ; $a0 Right/Up db $38, $4c, $9e, $3f, $2d, $39, $02, $04 ; $a1 Left/Down db $1c, $32, $79, $fc, $b4, $9c, $40, $20 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel28: db $00, $37, $69, $5c, $34, $5f, $46, $64 ; $9f Left/Up db $00, $ec, $96, $3a, $2c, $fa, $62, $26 ; $a0 Right/Up db $64, $46, $5f, $34, $5c, $69, $37, $00 ; $a1 Left/Down db $26, $62, $fa, $2c, $3a, $96, $ec, $00 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel29: db $00, $37, $6d, $5e, $34, $7f, $56, $64 ; $9f Left/Up db $00, $ec, $b6, $7a, $2c, $fe, $6a, $26 ; $a0 Right/Up db $64, $56, $7f, $34, $5e, $6d, $37, $00 ; $a1 Left/Down db $26, $6a, $fe, $2c, $7a, $b6, $ec, $00 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle
udgsEnemiesLevel30: db $e0, $ff, $ed, $5b, $7e, $6e, $5f, $72 ; $9f Left/Up db $07, $ff, $b7, $da, $7e, $76, $fa, $4e ; $a0 Right/Up db $72, $5f, $6e, $7e, $5b, $ed, $ff, $e0 ; $a1 Left/Down db $4e, $fa, $76, $7e, $da, $b7, $ff, $07 ; $a2 Right/Down
ZX-Spectrum Assembly, Space BattleZX-Spectrum Assembly, Space Battle

With this we have already defined the graphics we are going to use: the ship, the shot, the explosion, the frame of the screen and the enemies.

You may notice that all the enemies have the same character code, this is because there is a limited number of characters that can be used as UDGs. Don’t worry, we’ll see a way around this later on.

ZX-Spectrum Assembly, Space Battle

It’s really very important to practice the hexadecimal to binary conversion, so don’t leave it for another day, it’s a very simple exercise.

In the next chapter of ZX Spectrum Assembly, we will start drawing with UDG.

Download the source code from here.

ZX Spectrum Assembly, Space Battle by Juan Antonio Rubio García.
Translation by Felipe Monge Corbalán.
This work is licensed to Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0).
Any comments are always welcome.