Код:
/*********************/
/* LASER BASIC 2 */
/* by Oleg N. Cher */
/* zx.oberon2.ru */
/*********************/
extern unsigned int Laser2_SPRT_ADR; // Sprite file start address
/* Спрайты хранятся в памяти в следующем формате:
Байт 1 - номер спрайта.
Байт 2 - младший байт размера спрайта (9*HGT*LEN+3).
Байт 3 - старший байт размера спрайта.
Байт 4 - длина спрайта.
Байт 5 - высота спрайта.
8*HGT*LEN - данные о состоянии
пикселей.
HGT*LEN - атрибуты.
ИТОГО: 9*HGT*LEN+5 байтов.
*/
/*--------------------------------- Cut here ---------------------------------*/
void Laser2_ATOF (void)
{
__asm
LD A, #0xC9 ; "RET"
LD (Laser2_ATOF_IN), A
__endasm;
} //Laser2_ATOF
/*--------------------------------- Cut here ---------------------------------*/
void Laser2_ATON (void)
{
__asm
LD A, #0xED ; "LD DE,(ADDR) ED5BXXXX"
LD (Laser2_ATOF_IN), A
__endasm;
} //Laser2_ATON
/*--------------------------------- Cut here ---------------------------------*/
void Laser2_PTBL (signed char col, signed char row, unsigned char spn) __naked {
__asm
POP HL
POP BC ; C = col; B = row
POP DE ; E = spn
PUSH DE
PUSH BC
PUSH HL
XOR A ; NOP
JP _Laser2_PUT_SPRITE
__endasm;
} //Laser2_PTBL
/*--------------------------------- Cut here ---------------------------------*/
void Laser2_PTOR (signed char col, signed char row, unsigned char spn) __naked {
__asm
POP HL
POP BC ; C = col; B = row
POP DE ; E = spn
PUSH DE
PUSH BC
PUSH HL
LD A, #0xB6 ; OR (HL)
JP _Laser2_PUT_SPRITE
__endasm;
} //Laser2_PTOR
/*--------------------------------- Cut here ---------------------------------*/
void Laser2_PTXR (signed char col, signed char row, unsigned char spn) __naked {
__asm
POP HL
POP BC ; C = col; B = row
POP DE ; E = spn
PUSH DE
PUSH BC
PUSH HL
LD A, #0xAE ; XOR (HL)
JP _Laser2_PUT_SPRITE
__endasm;
} //Laser2_PTXR
/*--------------------------------- Cut here ---------------------------------*/
void Laser2_PTND (signed char col, signed char row, unsigned char spn) __naked {
__asm
POP HL
POP BC ; C = col; B = row
POP DE ; E = spn
PUSH DE
PUSH BC
PUSH HL
LD A, #0xA6 ; AND (HL)
JP _Laser2_PUT_SPRITE
__endasm;
} //Laser2_PTND
/*--------------------------------- Cut here ---------------------------------*/
void Laser2_PUT_SPRITE (void) __naked {
// A: mode; C: col; B: row; E: spn
__asm
.globl Laser2_ATOF_IN
LD (SPRT_MODE_IN$), A ; Set draw mode
; Процедура расчёта адреса экрана из координат
; Вход: C=x, B=y
; Выход: HL = адрес видеопамяти
LD A, B
AND #7
RRCA
RRCA
RRCA
OR C
LD L, A
LD A, B
AND #24
OR #0x40
LD H, A ; 14 байт, 53 такта
LD (SCR_ADR_IN$+1), HL
LD HL, (_Laser2_SPRT_ADR)
FIND_BY_N_IN$: LD A, (HL) ; N of a sprite
OR A
RET Z
INC HL
CP E ; spn
JR Z, SPRT_FOUND_IN$
LD C, (HL)
INC HL
LD B, (HL)
ADD HL, BC ; + offset to next sprite
JR FIND_BY_N_IN$
SPRT_FOUND_IN$: INC HL
INC HL
LD C, (HL) ; length of sprite
INC HL
LD B, (HL) ; height of sprite
LD (SPRT_HGT_LEN_IN$+1), BC
INC HL
SCR_ADR_IN$: LD DE, #0 ; adr of sprite (up left corner)
SPRT_HLINE_IN$: LD A, E ; Begin of loop on charlines
LD (SCR_LOBYTE_IN$+1), A
PUSH BC
LD B, #8
SPRT_CHAR_IN$: LD A, (HL)
SPRT_MODE_IN$: NOP ; NOP | AND (HL) | OR (HL) | XOR (HL)
LD (DE), A
INC HL
INC D
DJNZ SPRT_CHAR_IN$
LD B, #8 ; Draw 8 bytes (one charline)
LD A, D
SUB A, B
LD D, A
INC E ; Next screen line
DEC C
JR NZ, SPRT_CHAR_IN$
SCR_LOBYTE_IN$: LD A, #0
ADD #0x20 ; Next charline
LD E, A ; If carry then jump to next third of screen
JR NC, CONTIN_1_3_IN$
LD A, D ; Next third of screen
ADD B
LD D, A ; DE := DE + 0x0800
CONTIN_1_3_IN$: POP BC
DJNZ SPRT_HLINE_IN$ ; End of loop on charlines (the same third)
Laser2_ATOF_IN: ; RET
LD DE, (SCR_ADR_IN$+1)
LD A, D ; Calculate attribute address
RRCA
RRCA
RRCA
AND #3
OR #0x58
LD D, A
SPRT_HGT_LEN_IN$: LD BC, #0
LD A, #32
SUB A, C ; 32 - len
LD (SPRT_HGT_DIS_IN$+1), A
DRAW_ATRLINE_IN$: PUSH BC ; Begin of loop on charlines
LD B, #0
LDIR
LD A, E
SPRT_HGT_DIS_IN$: ADD #0
LD E, A
LD A, C
ADC D
LD D, A
POP BC
DJNZ DRAW_ATRLINE_IN$
RET
__endasm;
} //Laser2_PUT_SPRITE