;z80 ;zx-spectrum ;assembler ; haiku (c) Gasman 2005 ; haiku.asm: the actual intro code ; macro to align on an 'n' byte boundary align macro n org ($ + n - 1) / n * n endm org 0x8000 call 3435 ; clear screen call mus_init ; interrupt setup ld a,0xc3 ; put JP instruction ld (0xfdfd),a ld hl,interrupt ld (0xfdfe),hl ld hl,0xfe00 ld a,h ld de,0xfe01 ld bc,0x0100 ld (hl),0xfd ldir ld i,a im 2 ; build table of y addresses ld hl,0xc000 mkylo ld a,l add a,a add a,a and 0xe0 ld (hl),a inc l jr nz,mkylo inc h mkyhi ld a,l and 0x07 or 0x40 ld c,a ld a,l and h srl a srl a srl a or c ld (hl),a inc l jr nz,mkyhi ; generate sine table include sine.asm ; generate sphere table call mksphere ; generate ribbon bitmap include ribbon.asm ; draw dragon curve call sidragon ld hl,haiku_kanji call bezlist xor a ld (0x5C3C),a ; set tvflag for main screen output ld b,titletext_end - titletext ld hl,titletext titleprint ld a,(hl) inc hl push bc push hl rst 0x0010 pop hl pop bc djnz titleprint ld hl,23185 ; attribute position of "h a i k u" text ld b,9 fade_title fade_title_letter dec (hl) halt halt halt ld a,(hl) cp 0x38 jr nz, fade_title_letter inc l djnz fade_title ld b,140 hold_title halt djnz hold_title ; clear title ld a,1 clsframe ld hl,ylo ld b,24 cp 24 jr nc,cls_over24 ld b,a cls_over24 clsgroup push bc ld b,7 cls8 ; copy character line up one pixel push bc push hl ld e,(hl) inc h ld d,(hl) ld h,d ld l,e inc h ld bc,32 ldir pop hl inc l pop bc djnz cls8 push hl ld e,(hl) ; blank bottom line of character inc h ld d,(hl) ld h,d ld l,e inc e ld bc,31 ld (hl),b ldir pop hl inc l ; now hl points to ytable entry for next char line pop bc djnz clsgroup inc a halt cp 32 jr c, clsframe ; make ribbon column blue ld hl,0x5800 ld (hl),0x39 inc l ld (hl),0x39 inc l ld (hl),0x39 inc l ld (hl),0x39 ld hl,0x5800 ld de,0x5820 ld bc,0x02e0 ldir sphere_scene_length equ 340 ld b,4 spherescene push bc spheredata_ptr ld hl,spheredata ld a,(hl) ld (ringstep1 + 1),a inc hl ld a,(hl) ld (dotcount1 + 1),a inc hl ld a,(hl) ld (animstep1 + 1),a inc hl ld a,(hl) ld (ringstep2 + 1),a inc hl ld a,(hl) ld (dotcount2 + 1),a inc hl ld a,(hl) ld (animstep2 + 1),a inc hl ld a,(hl) ld (ringstep3 + 1),a inc hl ld a,(hl) ld (dotcount3 + 1),a inc hl ld a,(hl) ld (animstep3 + 1),a inc hl ld a,(hl) ld (animstep3 + 2),a inc hl ld (spheredata_ptr + 1),hl ld bc,sphere_scene_length sphereframe push bc halt call clearplots ld ix,clearaddrs animring1 dotcount1 ld b,0 sphrpos1 ld hl,sphere_table ringstep1 ld de,0 call plotring ld hl,(sphrpos1+1) animstep1 ld de,0 add hl,de res 2,h ld (sphrpos1+1),hl animring2 dotcount2 ld b,0 dec b jr z, animring3 sphrpos2 ld hl,sphere_table ringstep2 ld de,0 call plotring ld hl,(sphrpos2+1) animstep2 ld de,0 add hl,de res 2,h ld (sphrpos2+1),hl animring3 dotcount3 ld b,0 dec b jr z, animring3_done sphrpos3 ld hl,sphere_table + 512 ringstep3 ld de,0 call plotring ld hl,(sphrpos3+1) animstep3 ld de,0 add hl,de res 2,h ld (sphrpos3+1),hl animring3_done inc ix ld (ix),0 ribplot_on ld bc,ribplot pop bc dec bc ld a,b or c jr nz,sphereframe pop bc ld a,b cp 3 jr nz,no_ribplot_on ld a,0xcd ; opcode for CALL ld (ribplot_on),a no_ribplot_on dec b jp nz,spherescene call 3435 ; clear screen ; sunset xor a out (254),a ld hl,0x5800 ld b,0x60 sunset1 ld (hl),0x10 ; dark red inc hl djnz sunset1 ld b,0x60 sunset2 ld (hl),0x50 ; bright red inc hl djnz sunset2 ld b,0xa0 sunset3 ld (hl),0x30 ; dark yellow inc hl djnz sunset3 ld b,0xa0 sunset4 ld (hl),0x70 ; bright yellow inc hl djnz sunset4 ld b,0 sunset5 ld (hl),0 ; black! black! inc hl djnz sunset5 include fizzle.asm ; create halftone pattern ld hl,0x5000 ld de,0x5001 ld bc,0x00ff ld (hl),0x55 ldir ld hl,0x5000 ld de,0x5200 ld bc,0x0600 ldir ld a,0xcd ; opcode for CALL ld (ripple_frame_on),a ld bc,600 ripplewait halt dec bc ld a,b or c jr nz,ripplewait ld hl,boat call bezlist ld b,180 boatwait halt djnz boatwait ld a,0x01 ; opcode for LD BC,nn - NOPify the call to ripple_frame ld (ripple_frame_on),a ld a,7 out (254),a call 3435 ; cls call tile ; fountain frame ld hl,0x47e3 set 0,(hl) inc l ld b,16 topframe ld (hl),0xff inc l djnz topframe set 7,(hl) ld hl,0x5083 set 0,(hl) inc l ld b,16 botframe ld (hl),0xff inc l djnz botframe set 7,(hl) ld hl,ylo + 64 ld b,96 sideframe ld a,(hl) inc h ld d,(hl) dec h inc l add a,3 ld e,a ex de,hl set 0,(hl) add a,17 ld l,a set 7,(hl) ex de,hl djnz sideframe call fountain ; restart fountain, spinning this time ld a,0x3c ; opcode for inc a ld (fountain_spin1),a ld (fountain_spin2),a call fountain ld bc,545 pregasuman push bc call tile pop bc dec bc ld a,b or c jr nz,pregasuman call 3435 ; cls ; fill with white-on-white ld hl,0x5900 ld de,0x5901 ld (hl),0x3f ld bc,255 ldir ld c,255 ldir ; disable bezier slowdown xor a ld (bez_halt_on),a ld hl,gasuman call bezlist xor a ld (0x5C3C),a ; set tvflag for main screen output ld b,gasmantext_end - gasmantext ld hl,gasmantext gasmanprint ld a,(hl) inc hl push bc push hl rst 0x0010 pop hl pop bc djnz gasmanprint ld b,7 reveal1 halt ld hl,0x5965 ld a,7 call revealsqr djnz reveal1 ld b,29 revwait1 halt djnz revwait1 ld b,7 reveal2 halt ld hl,0x596c ld a,6 call revealsqr djnz reveal2 ld b,29 revwait2 halt djnz revwait2 ld b,7 reveal3 halt ld hl,0x5972 ld a,5 call revealsqr djnz reveal3 ld b,29 revwait3 halt djnz revwait3 ld b,7 reveal4 halt ld hl,0x5977 ld a,5 call revealsqr djnz reveal4 ld b,100 revwait4 halt djnz revwait4 ; make fully black-on-white in readiness for geisha picture ld hl,0x5800 ld de,0x5801 ld (hl),0x38 ld bc,767 ldir ; doctor yhi table to draw to 0x6000 ld hl,yhi doctor_yhi set 5,(hl) inc l jr nz,doctor_yhi ; clear 0x6000 ld hl,0x6000 ld de,0x6001 ld (hl),l ld bc,0x17ff ldir ; obliterate brush to make geisha even more ghostly ld b,8 ld hl,brush oblit1 ld a,0x55 and (hl) ld (hl),a inc l djnz oblit1 ld b,8 ld hl,brush + 0x100 oblit2 ld a,0x55 and (hl) ld (hl),a inc l djnz oblit2 ld hl,geisha call bezlist ; display random horizontal lines of geisha ld hl,0 ld bc,0x2030 ghoston push bc ld a,(hl) cp 0xc0 jr nc, noghoston push hl ld l,a ld h,2 add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ld d,h ld e,l set 5,h rept 32 ldi endm pop hl noghoston pop bc inc hl dec c jr nz,ghoston halt ld c,0x30 dec b jr nz,ghoston ; remove same random horizontal lines ld hl,0 ld bc,0x2030 ghostoff push bc ld a,(hl) cp 0xc0 jr nc, noghostoff push hl ld l,a ld h,2 add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ld d,h ld e,l ld hl,0x4000 ; should always be blank rept 32 ldi endm pop hl noghostoff pop bc inc hl dec c jr nz,ghostoff halt ld c,0x30 dec b jr nz,ghostoff call 3435 di stop jr stop revealsqr push bc ld b,10 revealrow push bc push hl ld b,a revealcell dec (hl) inc l djnz revealcell pop hl ld de,0x0020 add hl,de pop bc djnz revealrow pop bc ret plotring: sphrlp push de push hl ld e,(hl) ld (ix),e inc ix inc h inc h inc h inc h ld d,(hl) ld (ix),d inc ix inc h inc h inc h inc h ld a,(de) or (hl) ld (de),a pop hl pop de add hl,de res 2,h djnz sphrlp ret ; ribbon plotter ribplot ld a,(ribstart + 1) add a,2 ld (ribstart + 1),a ld a,(riby + 1) add a,1 ; inc a ld (riby + 1),a riblinecount ld b,1 ld hl,ylo ribline push bc push hl ld e,(hl) inc h ld d,(hl) riby ld a,0 add a,l ld l,a ld h,sine / 0x100 ld l,(hl) sla l ribstart ld a,0 add a,l ld l,a ld l,(hl) ld h,ribbon / 0x100 ld a,(hl) ld (de),a inc e inc h ld a,(hl) ld (de),a inc e inc h ld a,(hl) ld (de),a inc e inc h ld a,(hl) ld (de),a pop hl inc l pop bc djnz ribline ld a,(riblinecount + 1) inc a cp 192 jr z, no_inc_ribline ld (riblinecount + 1),a no_inc_ribline wait_colfade ld hl, 0 + (sphere_scene_length * 2) - 30 dec hl ld a,h or l jr z,colfade ld (wait_colfade + 1),hl ret colfade ld hl,0x5800 colfade_col ld a,0xe0 ; black-on-white shifted left twice inc a ld (colfade_col + 1),a srl a srl a ld b,0 colfade_fill ld (hl),a inc hl ld (hl),a inc hl ld (hl),a inc hl djnz colfade_fill ret sidragon: ; hl = display address, c = pre-rotated bit ; d = 'x' / 'y' values (assumed to be the same) ; e = 'a' counter from original code L10 ld hl,dragon+2048+768+192+22 ; 180,60 ld c,8 ; bit for x=180 ld (hl),c ; plot start position ld de,$020c L20 ld a,e and a jr z,drawx L30 dec e call L20 jr L65 L40 ld a,e and a jr z,drawy L50 dec e xor a sub d ld d,a call L20 L60 xor a sub d ld d,a L65 call L40 inc e ret drawx ld ix,rpixel ld b,d bit 7,b jr z,draw ld ix,lpixel jr drawneg drawy ld ix,uline ld b,d bit 7,b jr z,draw ld ix,dline drawneg xor a sub b ld b,a draw call jpix ld a,(hl) xor c ; change to or c for over 0 ld (hl),a djnz draw ret jpix jp (ix) lpixel rlc c ret nc dec l ret rpixel rrc c ret nc inc l ret uline push de ld de,65536-32 add hl,de pop de ret dline push de ld de,32 add hl,de pop de ret clearplots ld (clearplots_sp + 1),sp ld sp,clearaddrs xor a clearplots_lp pop hl ld (hl),a cp h jr nz, clearplots_lp clearplots_sp ld sp,0 ret ; interrupt service routine interrupt push af push bc push de push hl call mus_play ripple_frame_on ld bc,ripple_frame pop hl pop de pop bc pop af ei ret titletext db 22, 20, 17, 16, 7, "h a i k u" ; AT 20, 17; INK 7 titletext_end equ $ gasmantext db 22, 20, 6, 16, 7, "g a s m a n" gasmantext_end equ $ spheredata db 48, 32, 33, 3, 17, 8, 3, 17, 8, 0 db 31, 32, 1, 0, 1, 1, 33, 33, 1023 MOD 0x100, 1023 / 0x100 db 63, 32, 1, 9, 33, 17, 0, 1, 1, 0 db 97, 24, 1, 9, 25, 17, 2, 25, 993 MOD 0x100, 993 / 0x100 include ripple.asm include fountain.asm include tile.asm include bezier.asm include sphere.asm include music.asm align 0x100 screenbits db 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03 align 0x100 screenbits2 db 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 align 0x100 rip_colours db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41 db 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08 db 0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48 db 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09 db 0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09 db 0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49 db 0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d db 0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d db 0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29,0x29 db 0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69 db 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d db 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d db 0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f db 0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d db 0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f,0x6f ; 00 = black black ; 01 = black blue ; 41 = bright black blue ; 08 = blue black ; 48 = bright blue black ; 09 = blue ; 49 = bright blue ; 0d = blue cyan ; 4d = bright blue cyan ; 29 = cyan blue ; 69 = bright cyan blue clearaddrs equ 0xc300 ; buffer of screen addresses to clear ribbon equ 0xc600 ; draw dragon curve here dragon equ 0xd000 ; table of y addresses ylo equ 0xc000 yhi equ 0xc100 ; sine table sine equ 0xc200 bob_buffer equ 0xc300 sphere_table equ 0xf000 ; must be a multiple of 2k = 0x0800