;
; Union presents a small production for Speccy.pl classic demo competition 2015
;
; Programmed and designed by Dr Piotr - back on Amstrad after 25 years!
; Music by Ben Daglish - ripped from Masters Of Universe game (c) 1987 Gremlin Graphics
;
; Code & Graphics - copyright 2015 Union, free for noncommercial use
; Music - copyright 1987 Gremlin Graphics
; This intro features:
; - Unlimited bobs effect, using triple screen buffering, fixed point math
; - Split screen mode, with mode 0 (16 colors) in 256x148 in the upper part of the screen
; and with mode 1 (4 colors) in 400x50
; - Overscan with 400 pixels for the scroll at the bottom of the screen
; - Raster effect on the scroll text
; - Shake screen effect, synced with music
; - No firmware calls used, pure hardware banging
; Maxam or WinAPE compatible assembler required.
org &800
run &800
nolist
; screen dimensions
ScreenWidth equ 128
ScreenHeight equ 148
; screen mode 0 - 160x200
ScreenMode equ 0
; screen bytes per pixels - calculation based on Screenmode
ScreenBytesPerPixel equ ScreenMode*ScreenMode+ScreenMode+2
; max count of chars i aa font
MaxCharsInFont equ 52
; define sprite x & y dimensions i pixels
SpriteXsize equ 16
SpriteYSize equ 16
; scroll width in bytes
ScrollWidth equ 50
; scroll height
ScrollHeight equ 25
; scroll screen mode
ScrollScreenMode equ 1
; scroll char width in pixels
ScrollCharWidth equ 16
; scroll char height in pixels
ScrollCharHeight equ 25
; deleay between changes of parameters for bobs drawing
BobsDelay equ 1800
; macro - calculate next screen lined address input and result in hl
macro scr_next_line_hl bytes_per_line
ld a,h ; 1
add a,8 ; 2
ld h,a ; 1
and &38 ; 2
jr nz,@scr_next_line_end ; 2
ld a,l ; 1
add a, bytes_per_line ; 2
ld l,a ; 1
ld a,h ; 1
adc a,&c0 ; 2
ld h,a ; 1
@scr_next_line_end:
mend
; macro - calculate next screen lined address input and result in hl
macro scr_next_line_de bytes_per_line
ld a,d ; 1
add a,8 ; 2
ld d,a ; 1
and &38 ; 2
jr nz,@scr_next_line_end ; 2
ld a,e ; 1
add a, bytes_per_line ; 2
ld e,a ; 1
ld a,d ; 1
adc a,&c0 ; 2
ld d,a ; 1
@scr_next_line_end:
mend
; macro - wait for vertcal refresh
macro WaitVBL
ld bc,&f500
@WaitVBLLoop:
in a,(c)
rra
jr nc,@WaitVBLLoop
mend
; macro - multiply 16 bit value by 8 bit value
; DE - 16 bit number to multiply by
; A - 8 bit number (multiplier)
; HL - 16 bit result
macro Mul_DExA
ld b,8
ld hl,0
@loop: add hl,hl
rlca
jr nc,@skip
add hl,de
@skip: djnz @loop
mend
; macro - multiply 8 bit value by 8 bit value
; H,E - 8 bit numbers to multiply
; HL - 16 bit result
macro Mul_HxE
ld d,0
ld l,d
ld b,8
@loop: add hl,hl
jr nc,@skip
add hl,de
@skip: djnz @loop
mend
; macro - get sin value from the table
macro cos
ld l,a
ld h,0
ld de, cosTable
add hl,de
ld a,(hl)
mend
; macro - get sin value from the table
macro sin
sub 64
cos
mend
; macro - draw a character on screen
; b - char height, c - char width, hl- ptr to char data to draw, de - destination screen address
macro DrawChar bytes_per_line
@charloop:
push hl
push bc
@lineloop:
ld a,(de)
inc de
ld (hl),a
inc hl
dec c
jr nz, @lineloop
pop bc
pop hl
scr_next_line_hl bytes_per_line
djnz @charloop
mend
; ---- start of the program ----
; setup interrupt handler
di
im 1
ld hl,InterruptHandler
ld (#0039),hl
ld a,#c3
ld (#0038),a
; change stack to free area - the original location is taken by the 2nd sceen buffer
ld sp,#3fff
; initialize screen address lookup table
call BuildLookupTable
; initialize font character table
ld hl, ScrollFont
ld a,50
call InitFontCharOffsetTable
;initialize music
call music_init
; set crtc vertival height (disp characters) to 26
ld bc,&bc06
out (c),c
ld bc,&bd1a
out (c),c
ld bc,&bc07
out (c),c
ld bc,&bd1f
out (c),c
call ClearVideoMemory
ld hl,Colors
ld e, 8
call SetColors
WaitVBL
; enable interrupts
ei
; main loop starts here
Loop:
; wait for vertical blanking sync
WaitVBL
ld a,(UnlimitedBobsEffectEnabled)
or a
jr nz, init_bobs
call Scroll
jr loop
init_bobs:
ld hl,(CurrSpritePosPtr)
ld a,l
or h
jr nz, do_bobs
ld hl,SpritePos
jp set_pos
do_bobs
WaitVBL
; get current screen buffer offset and calculate next
ld a, (current_scr_offset+1)
add #10
cp #40
jr nz, update_screen_offset
ld a,#10
update_screen_offset:
ld (current_scr_offset+1),a
; set a new hardware screen buffer offset
ld bc,&bc0c
out (c),c
inc b
out (c),a
; update sprite position
call SpriteUpdatePos
ld hl, (CallCnt)
ld a,l
or h
jr nz, next
ld hl,BobsDelay
ld (CallCnt),hl
ld hl,(CurrSpritePosPtr)
inc hl
inc hl
inc hl
inc hl
inc hl
ld a,(hl)
or a
jr nz,set_pos
ld hl,SpritePos
set_pos:
ld (CurrSpritePosPtr),hl
ld de,CurrSpritePos
ld a,(hl)
ld (de),a
inc hl
inc de
ld a,(hl)
ld (de),a
inc hl
inc de
ld a,(hl)
ld (CurrSpriteAngle+1),a
inc hl
ld a,(hl)
ld (de),a
inc hl
inc de
ld a,(hl)
ld (de),a
inc hl
inc de
; clear 3 buffers with upper part of the screen
ld a, (current_scr_offset+1)
push af
ld a,#10
ld (current_scr_offset+1),a
ld h,ScreenHeight
ld l,ScreenWidth/2
ld de,0
ld bc,0
xor a
call ClearScreen
ld a,#20
ld (current_scr_offset+1),a
ld h,ScreenHeight
ld l,ScreenWidth/2
ld de,0
ld bc,0
xor a
call ClearScreen
ld a,#30
ld (current_scr_offset+1),a
ld h,ScreenHeight
ld l,ScreenWidth/2
ld de,0
ld bc,0
xor a
call ClearScreen
pop af
ld (current_scr_offset+1),a
next:
; wait a bit
ld hl,#6e0
@waitloop:
dec hl
ld a,l
or h
jr nz, @waitloop
; back to main loop
jp loop
; clear screen
ClearScreen:
; h,l -ysize,xsize
; bc - xstart
; de - ystart
; a - a value to fill in
push af
push hl
call CalcScreenAddress
pop de
pop af
ld b,d
ld d,a
@ClearHeightLoop:
push hl
ld c,e
@ClearWidthLoop:
ld (hl),d
inc hl
dec c
jr nz, @ClearWidthLoop
pop hl
scr_next_line_hl &40
djnz @ClearHeightLoop
ret
; clear screen buffers memory
ClearVideoMemory:
ld hl, &4000
ld de, &bfff
@fill:
xor a
ld (hl),a
inc hl
dec de
ld a,e
or d
jr nz, @fill
ret
; set hardware screen address offset
SetScreenAddress:
ld a, (current_scr_offset+1)
ld bc,&bc0c
out (c),c
out (c),a
xor a
ld bc,&bc0d
out (c),c
out (c),a
ret
CalcScreenAddress:
; de - ypos
; bc - x pos
; out- hl - current screen address
sla e
rl d
ld hl,screen_lines_table
add hl,de
; get memory offset for y coord
ld e, (hl)
inc hl
ld d, (hl)
; account for current video screen address
ex de,hl
ld de,(current_scr_offset)
sla d
sla d
add hl,de
; calc x offset - for mode 0 divide by 2
ld a,c
srl b
rr c
; calc final screen memory address
add hl,bc
ret
; sprite related variables
CurrSpriteAngle:
db 0, 6
CurrSpritePos:
db 96,96, 2, 2
CurrSpritePosPtr:
dw 0
SpritePos:
db 20,30, 6, 6, 4
db 10,10,-3, 2, 1
db 78,66, 4,-1, 4
db 44,35, 3, 2, 6
db 88,30, 4, 1, 5
db 96,96, 6, 2, 2
db 50,50, 4, 3, 3
db 0
; update sprite position
SpriteUpdatePos:
; update sprite angle
ld ix,CurrSpriteAngle
ld a,(ix)
add (ix+1)
ld (ix),a
jr nc, @skip_update
; update sprite x position
ld ix,CurrSpritePos
ld a,(ix)
add (ix+2)
cp ScreenWidth-SpriteXSize
jr c, @updatenext
ld a,ScreenHeight-SpriteYSize
@updatenext:
ld (ix),a
; update sprite y position
ld a,(ix+1)
add (ix+3)
cp ScreenHeight-SpriteYSize
jr c, @updatenext2
ld a, ScreenHeight-SpriteYSize
@updatenext2:
ld (ix+1),a
ld a,(CurrSpriteAngle)
@skip_update:
; get sinus for a given angle, returns value in fp 8.8 format
call sinFP
ex de,hl
ld a,(CurrSpritePos)
; calculate curent x position
Mul_DExA
push hl
; get cosinus for a given angle, returns value in fp 8.8 format
ld a,(CurrSpriteAngle)
call cosFP
ex de,hl
ld a,(CurrSpritePos+1)
; calculate curent y position
Mul_DExA
ex de,hl
pop bc
; draw a sprite
;draw a sprite on a screen
; bc - xpos in fp 8.8
; de - ypox in fp 8.8
DrawSpriteFP:
xor a
ld c,b
ld e,d
ld b,a
ld d,a
;draw a sprite on a screen
; bc - xpos
; de - ypox
DrawSprite:
; x clipping
ld a,c
cp 0
jp p, @ClipXNext
ld c,0
jr @ClipXnext2
@ClipXnext:
cp ScreenWidth-SpriteXsize
jp c, @ClipXnext2
ld c,ScreenWidth-SpriteXsize
@ClipXnext2:
; y clipping
ld a,e
cp 1
jp nc, @ClipYNext
ld e,0
jr @ClipYnext2
@ClipYnext:
cp ScreenHeight-SpriteYsize
jp c, @ClipYnext2
ld e,ScreenHeight-SpriteYsize
@ClipYnext2:
; calc target memory address for a given screen position
call CalcScreenAddress
ex de,hl
; de now contains destination screen memory pointer
ld hl, SpriteData
ld b, SpriteYSize
; draw a sprite
@DrawHeightLoop:
ld c, SpriteXSize/ScreenBytesPerPixel
push de
@DrawWidthLoop:
; get sprite data
ld a,(de)
; apply sprite mask
and (hl)
inc hl
; copy in image data
or (hl)
inc hl
; write to screen
ld (de),a
inc de
dec c
jr nz, @DrawWidthLoop
pop de
; calculate address of next screen line
scr_next_line_de &40
djnz @DrawHeightLoop
ret
; clear sprite on screen
; bc - xpos
; de - ypox
; a - a value to fill in
SpriteClear:
call CalcScreenAddress
ld b, SpriteYSize-1
@SpriteClearHeightLoop:
ld c, SpriteXSize/ScreenBytesPerPixel
push hl
@SpriteClearWidthLoop:
ld (hl),a
inc hl
dec c
jr nz, @SpriteClearWidthLoop
pop hl
scr_next_line_hl &40
djnz @SpriteClearHeightLoop
ret
; scroll routines
; scroll text
Scroll:
ld a,(scroll_delay)
or a
jr z, @skip_delay
dec a
ld (scroll_delay),a
jr @skip_write_char
@skip_delay:
ld hl,(current_scr_offset)
call ScrollText
ld a,(scroll_cnt)
dec a
ld (scroll_cnt),a
or a
jr nz,@skip_write_char
call WriteChar
ld a,ScrollCharWidth/4+1
ld (scroll_cnt),a
@skip_write_char:
ret
ScrollText:
; hl - hardware screen address
; calculate final screen memory offset
ld bc, #1e0e
sla h
sla h
add hl, bc
ex de, hl
ld b, ScrollHeight
@scroll_loop:
ld a,b
push de
ld h,d
ld l,e
inc hl
ld bc, ScrollWidth*2
ldir
ld b,a
pop de
scr_next_line_de ScrollWidth*2
djnz @scroll_loop
ret
; restart scroll text
RestartScrollText:
ld hl, scroll_text
ld (scrolltext_ptr), hl
WriteChar:
; get a char from text scroll, check if reached end
ld hl, (scrolltext_ptr)
ld a, (hl)
or a
jr z, RestartScrollText
inc hl
ld (scrolltext_ptr), hl
cp 1
jr nz, @write_skip_delay
ld a, (hl)
inc hl
ld (scrolltext_ptr), hl
ld (scroll_delay), a
ld a,64
@write_skip_delay:
cp 2
jr nz, @write_skip_trigger_bobs
; copy scroll area to remaining 2 screen buffers
ld hl,#c000
ld de,#4000
ld bc,#3fff
ldir
ld hl,#c000
ld de,#8000
ld bc,#3fff
ldir
ld hl,BobsDelay
ld (CallCnt),hl
ld (UnlimitedBobsEffectEnabled),a
ret
@write_skip_trigger_bobs:
cp 32
jr nz, @write_skip_space
add 32
jr @skip
@write_skip_space:
cp 63
jr nc, @skip
add 16+26
@skip:
; calculate offset to the char in the font
sub 64
sla a
ld de,0
ld e,a
ld hl, charoffset_table
add hl,de
ld e,(hl)
inc hl
ld d,(hl)
; calculate final screen memory offset
ld hl,(current_scr_offset)
sla h
sla h
ld bc,#1e0e+96
add hl,bc
ld b, ScrollCharHeight
ld c, 4
; draw a char
; DrawChar ScrollWidth*2
;DrawChar:
; b - char height, hl-char data to draw, de - destination address
charloop:
push hl
ld a,(de)
inc de
ld (hl),a
inc hl
ld a,(de)
inc de
ld (hl),a
inc hl
ld a,(de)
inc de
ld (hl),a
inc hl
ld a,(de)
inc de
ld (hl),a
pop hl
scr_next_line_hl ScrollWidth*2
djnz charloop
ret
; initialize table, containing font offsets for each character
; hl - new font data
; a - number of chars
InitFontCharOffsetTable:
push af
ld e, (hl)
inc hl
ld a, (hl)
inc hl
push hl
ld h,a
Mul_HxE
push hl
pop bc
pop hl
pop af
ld de,charoffset_table
@fonttableloop:
ex de,hl
ld (hl), e
inc hl
ld (hl), d
inc hl
ex de,hl
add hl,bc
dec a
or a
jr nz, @fonttableloop
ret
; screen related variables
; current screen offset in crtc values
current_scr_offset:
dw &3000
scroll_delay:
db 0
scroll_cnt
db 4
scrolltext_ptr;
dw scroll_text
scroll_text:
db ' FIRST ',1,120
db ' THERE WAS GFORCE ',1,100
db ' NOW ',1,100
db ' AFTER 25 YEARS ',1,120
db ' WE ARE BACK ',1,140
db ' UNION PRESENTS ',1,240
db ' A PRODUCTION FOR SPECCY PL 2O15 CLASSIC DEMO COMPETITION '
db ' PROGRAM GRAPHICS AND DESIGN BY DR PIOTR '
db ' UNLIMITED BOBS ',2,0
db 'MUSIC BY BEN DAGLISH RIPPED FROM MASTERS OF UNIVERSE GAME BY GREMLIN GRAPHICS',2,0
; interupt im 1 handler routine, called every 300th of second
InterruptHandler:
di
; store used registers on the stack
push af
push bc
push de
push hl
push ix
; find if an interrupt was triggered in vertical blanking
ld b,&f5
in a,(c)
rra
jr nc,@UpdateIntCnt
; if so, reset interrupt counter
xor a
jr @SkipCnt
@UpdateIntCnt:
ld a,(IntCnt)
inc a
@skipcnt:
; handle various operations depending on screen vertical position
ld (IntCnt),a
or a
jr nz, @next1
; change video mode to 0
ld bc,&7f8c
out (c),c
; set screen size to 256 pixels (32 crtc chars)
ld bc,&bc01
out (c),c
ld bc,&bd20
out (c),c
ld bc,&bc02
out (c),c
ld bc,&bd2a
out (c),c
; on every 50th of second call music player
call music_play
ld hl,(CallCnt)
ld a,l
or h
jr z,IntExit
dec hl
ld (CallCnt),hl
jp ShakeEffect
@next1:
cp #3
jr nz,@next2
jr IntExit
@next2: cp #4
jr nz,IntExit
ld bc,#bc02
out (c),c
ld bc,#bd2a
out (c),c
; in lower part of the screenm change the screen mode to 1
ld bc,&7f8d
out (c),c
; set overscan width = 400 pixels (50 crtc chars)
ld bc,&bc01
out (c),c
ld bc,&bd32
out (c),c
ld bc,&bc02
out (c),c
ld bc,&bd33
out (c),c
ld bc,&7f00
ld a,#54
out (c),c
out (c),a
; call raster effect
jr RasterEffect
IntExit:
; reset colors to default after raster effect
ld hl,Colors
ld e, 8
call SetColors
; restore registers from stack
pop ix
pop hl
pop de
pop bc
pop af
; return from interrupt
ei
reti
; this keeps track of the section of the screen we are currenty in
IntCnt:
db 0
CallCnt:
dw 0
ShakeEffectEnabled:
db 0
RasterEffectEnabled:
db 1
UnlimitedBobsEffectEnabled:
db 0
; various effects called from interrupt routine
; Raster effect - make stripes on the scroll font
RasterEffect:
; check if raster effect is enabled
ld a, (RasterEffectEnabled)
or a
jr z, IntExit
defs 19,0
ld b,12
@raster_effect_loop:
push bc
; set colors to a color from the table
ld hl,RasterColorsTable
ld bc,&7f01
out (c),c
ld a,4
@raster_effect_loop2:
outi
; nops to exactly sync to the next raster line
defs 54,0
inc b
dec a
jr nz,@raster_effect_loop2
; move colors in the table to get the moving raster effect
ld hl,RasterColorsTable+1
ld de,RasterColorsTable
ld a,(de)
ld bc,12
ldir
ld (RasterColorsTable+12),a
defs 20,0
pop bc
djnz @raster_effect_loop
jp IntExit
RasterColorsTable:
db #5c,#4c,#4e,#4a,#4b,#4a,#4e,#4c,#54,#54,#54,#54,#54
; shake effect - shakes the screen by changing position of horizontal sync. pulse
ShakeEffect:
; check if the effect is enabled
ld a,(ShakeEffectEnabled)
or a
jp z, IntExit
; wait a bit
ld b,20
@wait_loop:
djnz @wait_loop
ld hl,(WavePtr)
ld b,5
@shake_loop:
push bc
; change the position of horizontal sync. pulse crtc register
ld bc,#bc02
out (c),c
inc b
ld a,(hl)
inc hl
sub #3
out (c),a
pop bc
djnz @shake_loop
; change the offset to the table to get the moving shake effect
ld hl,(WavePtr)
inc hl
ld a, (ShakeCnt)
dec a
jr nz,@shake_skip
; reset table offsets and counters
xor a
ld (ShakeEffectEnabled),a
ld a,28
ld hl, waves
@shake_skip:
ld (ShakeCnt),a
ld (WavePtr),hl
shake_reset:
jp IntExit
ShakeCnt:
db 28
WavePtr:
dw waves
waves:
db 42,43,44,45,46,47,48,49,48,47,46,45,44,43,42,43,44,45,46,47,48,49
db 45,44,43,42,43,44
db 45,46,47,48,49,49,49,48,47,46,45,44,43,42,43,44,45,45
; get sinus value from the table - also available as a macro
sin:
sub 64
; get cosinus value from the table - also available as a macro
cos:
ld l,a
ld h,0
ld de, CosTable
add hl,de
ld a,(hl)
ret
; get sin value from the table in fixed point 8.8
sinFP:
sub 64
; get cossin value from the table in fixed point 8.8
cosFP:
ld l,a
ld h,0
ld de, CosTable
add hl,de
ld a,(hl)
add 64
ld l,a
rla
; sbc a,a
; ld h,a
ld h,0
; add hl, hl
add hl, hl
ret
; 256 values of cosinus, kept between -64,64 range - calculated as cos(2*PI*a/256)/64
CosTable:
defb 64, 64, 64, 64, 64, 64, 63, 63
defb 63, 62, 62, 62, 61, 61, 60, 60
defb 59, 59, 58, 57, 56, 56, 55, 54
defb 53, 52, 51, 50, 49, 48, 47, 46
defb 45, 44, 43, 42, 41, 39, 38, 37
defb 36, 34, 33, 32, 30, 29, 27, 26
defb 24, 23, 22, 20, 19, 17, 16, 14
defb 12, 11, 9, 8, 6, 5, 3, 2
defb 0, -2, -3, -5, -6, -8, -9,-11
defb -12,-14,-16,-17,-19,-20,-22,-23
defb -24,-26,-27,-29,-30,-32,-33,-34
defb -36,-37,-38,-39,-41,-42,-43,-44
defb -45,-46,-47,-48,-49,-50,-51,-52
defb -53,-54,-55,-56,-56,-57,-58,-59
defb -59,-60,-60,-61,-61,-62,-62,-62
defb -63,-63,-63,-64,-64,-64,-64,-64
defb -64,-64,-64,-64,-64,-64,-63,-63
defb -63,-62,-62,-62,-61,-61,-60,-60
defb -59,-59,-58,-57,-56,-56,-55,-54
defb -53,-52,-51,-50,-49,-48,-47,-46
defb -45,-44,-43,-42,-41,-39,-38,-37
defb -36,-34,-33,-32,-30,-29,-27,-26
defb -24,-23,-22,-20,-19,-17,-16,-14
defb -12,-11, -9, -8, -6, -5, -3, -2
defb 0, 2, 3, 5, 6, 8, 9, 11
defb 12, 14, 16, 17, 19, 20, 22, 23
defb 24, 26, 27, 29, 30, 32, 33, 34
defb 36, 37, 38, 39, 41, 42, 43, 44
defb 45, 46, 47, 48, 49, 50, 51, 52
defb 53, 54, 55, 56, 56, 57, 58, 59
defb 59, 60, 60, 61, 61, 62, 62, 62
defb 63, 63, 63, 64, 64, 64, 64, 64
;16x16
SpriteData:
defb &FF,&00,&FF,&00,&FF,&00,&00,&0C,&00,&0C,&FF,&00,&FF,&00,&FF,&00; line 0
defb &FF,&00,&FF,&00,&00,&0C,&00,&00,&00,&00,&00,&0C,&FF,&00,&FF,&00; line 1
defb &FF,&00,&AA,&04,&00,&78,&00,&E4,&00,&C0,&00,&C0,&55,&08,&FF,&00; line 2
defb &FF,&00,&00,&1C,&00,&F0,&00,&A0,&00,&30,&00,&30,&00,&84,&FF,&00; line 3
defb &AA,&04,&00,&D8,&00,&F0,&00,&40,&00,&30,&00,&30,&00,&60,&55,&08; line 4
defb &AA,&04,&00,&78,&00,&E4,&00,&90,&00,&30,&00,&30,&00,&60,&55,&08; line 5
defb &00,&4C,&00,&78,&00,&A0,&00,&30,&00,&30,&00,&30,&00,&C0,&00,&04; line 6
defb &00,&08,&00,&78,&00,&A0,&00,&30,&00,&30,&00,&60,&00,&00,&00,&8C; line 7
defb &00,&08,&00,&44,&00,&C8,&00,&30,&00,&30,&00,&80,&00,&00,&00,&8C; line 8
defb &00,&08,&00,&C0,&00,&90,&00,&60,&00,&C0,&00,&00,&00,&44,&00,&8C; line 9
defb &AA,&04,&00,&C0,&00,&30,&00,&C0,&00,&80,&00,&44,&00,&6C,&55,&08; line 10
defb &AA,&04,&00,&40,&00,&90,&00,&C0,&00,&00,&00,&9C,&00,&B4,&55,&08; line 11
defb &FF,&00,&00,&08,&00,&C0,&00,&80,&00,&00,&00,&78,&00,&A4,&FF,&00; line 12
defb &FF,&00,&AA,&04,&00,&40,&00,&80,&00,&00,&00,&3C,&55,&08,&FF,&00; line 13
defb &FF,&00,&FF,&00,&00,&0C,&00,&00,&00,&00,&00,&0C,&FF,&00,&FF,&00; line 14
defb &FF,&00,&FF,&00,&FF,&00,&00,&0C,&00,&0C,&FF,&00,&FF,&00,&FF,&00; line 15
; a table of pointers to screen memory lines
screen_lines_table:
ds 200*2,0
SetColors:
; hl - color table of hardware values
; e - number of colors to set
ld bc,&7f00
@loop: ld a,(hl)
inc hl
out (c),c
out (c),a
inc c
dec e
jr nz, @loop
ld bc,&7f10
ld a,(hl)
out (c),c
out (c),a
ret
Colors:
db #57,#55,#54,#5f,#44,#4b,#5b,#54,#57
; include music player and data
read "MastersOfUniverseMusic.asm"
; build screen lines lookup tables
BuildLookupTable:
ld de,&0000
ld b,200
ld hl, screen_lines_table
build_table_loop:
ld (hl),e
inc hl
ld (hl),d
inc hl
scr_next_line_de &40
dec b
jr nz,build_table_loop
ret
; table of character offsets in a font
charoffset_table:
ds MaxCharsInFont*2,0
; include compiled fonts
ScrollFont:
incbin "ScrollFont.bin"