org &8000:limit &a400:nolist

ld a,2
call &bc0e
ld bc,0
call &bc38

xor a
.blackout
push af
ld bc,0
call &bc32
pop af
inc a
cp 16
jr nz,blackout

ld hl,&5600
ld de,&4000
ld bc,&29ff
ldir

call expand

ld hl,&c000
ld de,&4000
ld b,192
.makedata
push bc
push hl
ld bc,80
ldir
pop hl
call &bc26
pop bc
djnz makedata

call &bb6c

ld a,1
ld bc,&1a1a
call &bc32

xor a
ld (blockno),a

.block_loop

call calc_scradd
ld (start_scr),hl

;---------------
ld a,8
.loop1
ld (loopvar),a
call drawsub1

ld a,(loopvar)
dec a
jp p,loop1

xor a
.loop2
ld (loopvar),a
call drawsub1
ld a,(loopvar)
inc a
cp 9
jp nz,loop2

ld a,8
.loop3
ld (loopvar),a
call drawsub2
ld a,(loopvar)
dec a
jp p,loop3

xor a
.loop4
ld (loopvar),a
call drawsub2
ld a,(loopvar)
inc a
cp 9
jp nz,loop4

ld a,8
.loop5
ld (loopvar),a
call drawsub1
ld a,(loopvar)
dec a
jp p,loop5

;---------------

ld a,(blockno)
add 2
ld (blockno),a
cp 24
jp c,block_loop

ret

;---------

.drawsub1
;Routine for drawing blocks right way up

call setup_drawsub

call draw_blanks

ld a,(loopvar)            ;Skip if no picture data to be put on screen
cp 8
jp z,all_blanks

ld a,(blockno)            ;Calculate start of data to draw (=&4000+640*blockno)
call get_data_start

ld a,(sub8_loopvar)       ;A=number of lines to draw (=8-loop)
call draw_normal

;Move data address on to start for lower half of this block
ld a,(blockno)
inc a
call get_data_start

push hl
call loop_x_80
add hl,de
ex hl,de
pop hl

ld a,(sub8_loopvar)       ;A=number of lines to draw (=8-loop)
call draw_normal

.all_blanks
call draw_blanks

call pause

ret

;---------

.drawsub2
;Routine to draw blocks when they're upside down

call setup_drawsub

call draw_blanks

ld a,(loopvar)            ;Skip if no picture data to be put on screen
cp 8
jp z,all_blanks_2

push hl
ld a,(blockno)            ;Calculate start of data to draw
add 2                     ;=&4000+640*(blockno+2)-80
call get_data_start
ld hl,-80
add hl,de
ex hl,de
pop hl

ld a,(sub8_loopvar)       ;A=number of lines to draw (=8-loop)
call draw_inverted

push hl                   ;Get data address for lower half
ld a,(blockno)            ;=blockno*640+&4000+80*(8-loop)
call get_data_start
ld a,(sub8_loopvar)
call a_x_80
add hl,de
ex hl,de
pop hl

ld a,(sub8_loopvar)       ;A=number of lines to draw (=8-loop)
call draw_inverted

.all_blanks_2
call draw_blanks

.pause
ld b,255
.p2
djnz p2

ret

;---------

.copy_80
;Copies 80 bytes to screen
;Entry - HL=screen address to copy bytes to
;        DE=address of data to copy

ex hl,de
ld bc,80
ldir            ;*** replace with LDI ***
ex hl,de
ret

;---------

.draw_inverted
;Enter with A=number of lines to draw
;          DE=address of data, HL=screen address to draw at
;Exits with HL=scradd of line below end of this block

ld b,a
.di2
push bc
push hl

call copy_80

ld hl,-160
add hl,de
ex hl,de

pop hl
call &bc26

pop bc
djnz di2
ret

;---------

.draw_normal
;Enter with  A=number of lines to draw
;           DE=address of data, HL=screen address to draw at
;Exits with HL=scradd of line below end of this block

ld b,a
.dn2
push bc
push hl

call copy_80
pop hl
call &bc26

pop bc
djnz dn2
ret

;---------

.draw_blanks
;Draw blank lines at start/end of blocks (HL holds start scradd)

ld a,(loopvar)
or a
ret z

ld b,a
.dblnk_loop
push bc

push hl
ld d,h
ld e,l
ld (hl),0
inc de
ld bc,79
ldir
pop hl
call &bc26

pop bc
djnz dblnk_loop

ret

;---------

.loop_x_80
;Multiply value in loopvar by 80, store result in HL
ld a,(loopvar)

.a_x_80
ld l,a
ld h,0
add hl,hl
add hl,hl
add hl,hl
add hl,hl
ld b,h
ld c,l
add hl,hl
add hl,hl
add hl,bc
ret

;---------

.calc_scradd
;Get start scradd of block in (blockno)

ld a,(blockno)
call a_x_80
ld bc,&c000
add hl,bc
ret

;---------

.get_data_start
;Gets start address of data for block (held in A) into DE

push hl
add a
add a
add a
call a_x_80
ld bc,&4000
add hl,bc
ex hl,de
pop hl
ret

;---------

.setup_drawsub
ld a,(loopvar)
neg
add 8
ld (sub8_loopvar),a
ld hl,(start_scr)
ret

;---------

.expand
ld hl,&4000
           ld de,0

.ex2       ld a,(hl)
           inc hl
           or a
           ret z
           ld c,a
           ld b,a
           res 7,b

.ex3       push de
           push hl
           ld a,e
           and 7
           add a,a
           add a,a
           add a,a
           add &c0
           ld h,a
           ld l,d
           push hl
           ld d,0
           srl e
           srl e
           srl e
           ld h,d
           ld l,e
           add hl,hl
           add hl,hl
           add hl,de
           add hl,hl
           add hl,hl
           add hl,hl
           add hl,hl
           pop de 
           add hl,de
           ex de,hl 
           pop hl
           ld a,(hl)
           ld (de),a

           pop de
           inc d
           ld a,d
           cp 80
           jr nz,ex4
           ld d,0
           inc e

.ex4       bit 7,c
           jr nz,ex5
           inc hl

.ex5       djnz ex3
           bit 7,c
           jr z,ex2
           inc hl
           jr ex2

;---------

.blockno        defb 0
.loopvar        defb 0
.sub8_loopvar   defb 0
list
.start_scr      defw 0
