Login

Subversion Repositories NedoOS

Rev

Rev 447 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

reservepage
;new page, set page in textpages, npages++, set page in #c000
;nz=error
        OS_NEWPAGE
        or a
        ret nz
npages=$+1
        ld hl,textpages
        ld (hl),e
        inc l
        ld (npages),hl
        ld a,e
        SETPG32KHIGH
        xor a
        ret ;z

unreservepages
         ld a,-1
         ld (npages_old),a
unreservepages0
        call unreservepage
        jr z,unreservepages0
        ret
       
unreservepage
;del page, npages--
;nz=error
        ld hl,(npages)
        ld a,l
        or a
        jr z,unreservepage_fail
        dec l
        ld (npages),hl
        ld e,(hl)
        OS_DELPAGE
        xor a
        ret ;z
unreservepage_fail
        xor a
        dec a
        ret ;nz
       
reserve_bmp_pages
        ld hl,(freemem_hl)
        ld a,(freemem_a)
        ld (putchar_hl),hl
        ld (putchar_a),a

        ld de,(curpichgt_visible)
         ;inc de
         ;srl d
         ;rr e
        ld bc,(curpicwidx3)
        CALL MULWORD
        ld d,b
        ld e,c
        ;hlde=bmp size
       
reserve_mem
;hlde=size
;out: ahl=freemem pointer
;меняет страницу в 0xc000
;ставит pgtemp в 0x8000
;ставит pgcode в 0x4000
freemem_hl=$+1
        ld bc,0
freemem_a=$+1
        ld a,0

;freemem может указывать на начало пока не заказанной страницы
;1.если (freememaddr&0x3fff) == 0, то заказать страницу
;2.если остаток страницы >= hlde, то сдвигаем freememaddr и выходим
;3.уменьшить hlde на длину остатка страницы
;4.сдвинуть freememaddr на начало следующей страницы
;5.goto 1
;TODO уметь откатывать заказанные страницы, если не хватает памяти
reserve_mem0
;если (freememaddr&0x3fff) == 0, то заказать страницу:
         ;inc b
         ;djnz reserve_mem_noreservepage
         ;push bc
         ;sla b
         ;sla b
         ;pop bc
         ;jr nz,reserve_mem_noreservepage
        push af
        ld a,b
        and 0x3f
        or c
        jr nz,reserve_mem_noreservepage
        push bc
        push de
        push hl
        push iy
reserve_mem_pages_fail
        call reservepage
        or a
        jr nz,reserve_mem_pages_fail ;repeat until success
        pop iy
        pop hl
        pop de
        pop bc
reserve_mem_noreservepage
        pop af
;если остаток страницы >= hlde (при прибавлении freememaddr+hlde-1 не меняется номер страницы), то сдвигаем freememaddr и выходим:
        inc h
        dec h
        jr nz,reserve_mem_nolast
        inc l
        dec l
        jr nz,reserve_mem_nolast
   ;hldeHSW=0
        push bc
        push hl
   ;bc=freememaddr&0xffff
        res 7,b
        res 6,b
   ;bc=0..0x3fff
        ld hl,0x4000
        or a
        sbc hl,bc ;NC
   ;hl = остаток страницы = 0x4000..1
        ;or a
        sbc hl,de ;остаток страницы-hlde
        pop hl
        pop bc
        jr c,reserve_mem_nolast
 ;сдвигаем freememaddr и выходим:        
        ex de,hl
        add hl,bc
        adc a,0 ;т.к. могли попасть ровно на конец страницы
        ld (freemem_hl),hl
        ld (freemem_a),a
         push af
         push hl
         call showmem ;ставит pgcode в 0x4000
         call setpgtemp8000
         pop hl
         pop af
        ret
reserve_mem_nolast
;уменьшить hlde на длину остатка страницы:
        push bc
        push hl
   ;bc=freememaddr&0xffff
        res 7,b
        res 6,b
   ;bc=0..0x3fff
        ld hl,0x4000
        or a
        sbc hl,bc
        ld b,h
        ld c,l
   ;bc = остаток страницы = 0x4000..1
        pop hl
        ex de,hl
        or a
        sbc hl,bc
        ex de,hl
        jr nc,$+3
        dec hl ;hlde = hlde - остаток страницы
        pop bc
;сдвинуть freememaddr на начало следующей страницы:
        sla c
        rl b
        rla
        sla c
        rl b
        rla
        ;dec abc:
        dec c
        jr nz,reserve_mem_nolast_decabcq
        dec b
        djnz reserve_mem_nolast_decabcq
        dec a
reserve_mem_nolast_decabcq
        inc a   ;next pg
        ld bc,0 ;
        srl a
        rr b
        rr c
        srl a
        rr b
        rr c
        jp reserve_mem0
       
writebyte
;c=byte
        push af
        push hl
        call ahl_to_pgaddrc000
        ld (hl),c
        pop hl
        pop af
        jp skipbyte
       
writeword
;bc=word
        push af
        push hl
        call ahl_to_pgaddrc000
        ld (hl),c
        pop hl
        pop af
        call skipbyte
        push af
        push hl
        call ahl_to_pgaddrc000
        ld (hl),b
        pop hl
        pop af
        jp skipbyte
       
readbyte
;out: c
        push af
        push hl
        call ahl_to_pgaddrc000
        ld c,(hl)
        pop hl
        pop af
skipbyte
        inc l
        ret nz
        inc h
        ret nz
        inc a
        ret
       
ahl_to_pgaddrc000
;keeps bc,de
;counts physical hl
        rl h
        rla
        rl h
        rla
        scf
        rr h
        sra h
        push bc
        ld c,a
        ld b,textpages/256
        ld a,(bc)
        SETPG32KHIGH
        pop bc
        ret

ahl_to_pgaddr_setpg32k
;keeps bc,de
;counts physical hl
        rl h
        rla
        rl h
        rla
        srl h
        scf
        rr h
        push bc
        call setpg32k
        pop bc
        ret

setpg32k
;a=page number in table (0..)
        push hl
        ld l,a
        ld h,textpages/256
        ld a,(hl)
        SETPG32KLOW
        inc l
        ld a,(hl)
        SETPG32KHIGH
        pop hl
        ret

reservemem_puttomem
;hl=from
;bc=size
;out: ahl=addr
        push hl
        ld hl,(freemem_hl)
        ld a,(freemem_a)
        push af
        push hl
        push bc ;size
        ld d,b
        ld e,c
        ld hl,0
;hlde=size
        call reserve_mem
        pop bc ;size
        pop hl
        pop af
        pop de
;de=from
;ahl=to
;bc=size
        push af
        push hl
        call puttomem
        pop hl
        pop af
        ret
       
puttomem
;de=from
;ahl=to
;bc=size
        ld (putchar_ldir_hl),de
        push bc
        rl h
        rla
        rl h
        rla
        scf
        rr h
        scf
        rr h
;a=page number in table (0..)
        ld c,a
        ld b,textpages/256
        ld a,(bc)
        inc c
         ld (purchar_nextpgtabaddr),bc
        SETPG32KHIGH
        ex de,hl
        pop bc ;сколько байт копируем
       
;если строка не помещается в страничке, то копируем сколько помещается, включаем следующую страницу и копируем остаток
        ld hl,0
        or a
        sbc hl,de ;hl=сколько места осталось в страничке
        or a
        sbc hl,bc ;hl>=0: места хватает
        jr nc,putchar_ldir
;места не хватает -hl байт
         push hl ;-остаток ширины
        add hl,bc ;hl=сколько места осталось в страничке
        ld b,h
        ld c,l
        ld hl,(putchar_ldir_hl) ;локальное начало строки
        ldir
purchar_nextpgtabaddr=$+1
        ld a,(0) ;ok
        SETPG32KHIGH
        ld de,0xc000
;hl=остаток строки
         pop bc ;-остаток ширины
        xor a
        sub c
        ld c,a
        sbc a,b
        sub c
        ld b,a ;bc=остаток ширины
        ldir
        ret
putchar_ldir
putchar_ldir_hl=$+1
        ld hl,0 ;локальное начало строки
        ldir
        ret
       
       
getfrommem
;de=to
;ahl=from
;bc=size
        ld (getfrommem_ldir_hl),de
        push bc
        rl h
        rla
        rl h
        rla
        scf
        rr h
        scf
        rr h
;a=page number in table (0..)
        ld c,a
        ld b,textpages/256
        ld a,(bc)
        inc c
         ld (getfrommem_nextpgtabaddr),bc
        SETPG32KHIGH
        ex de,hl
        pop bc ;сколько байт копируем
       
;если строка не помещается в страничке, то копируем сколько помещается, включаем следующую страницу и копируем остаток
        ld hl,0
        or a
        sbc hl,de ;hl=сколько места осталось в страничке
        or a
        sbc hl,bc ;hl>=0: места хватает
        jr nc,getfrommem_ldir
;места не хватает -hl байт
         push hl ;-остаток ширины
        add hl,bc ;hl=сколько места осталось в страничке
        ld b,h
        ld c,l
        ld hl,(getfrommem_ldir_hl) ;локальное начало строки
        ex de,hl
        ldir
        ex de,hl
getfrommem_nextpgtabaddr=$+1
        ld a,(0) ;ok
        SETPG32KHIGH
        ld de,0xc000
;hl=остаток строки
         pop bc ;-остаток ширины
        xor a
        sub c
        ld c,a
        sbc a,b
        sub c
        ld b,a ;bc=остаток ширины
        ex de,hl
        ldir
        ex de,hl
        ret
getfrommem_ldir
getfrommem_ldir_hl=$+1
        ld hl,0 ;локальное начало строки
        ex de,hl
        ldir
        ex de,hl
        ret

;;;;;;;;;;;;;;;;;;;;;;;

;структура списков:
;+0 3 следующий элемент или -1
;+3 3 предыдущий элемент или -1
;+6 данные
       
getprevelement
;ahl=pointer
        call skipbyte
        call skipbyte
        call skipbyte
getnextelement
;ahl=pointer
        call readbyte ;c
        ld e,c
        call readbyte ;c
        ld d,c
        call readbyte ;c
        ld a,c
        ex de,hl
        ret
       
readword
;ahl=pointer
;out: de=word
        call readbyte ;c
        ld e,c
        call readbyte ;c
        ld d,c
        ret
       
isnull
;ahl=pointer
;out: z=null (pointer == -1)
        push bc
        ld c,a
        and h
        and l
        inc a
        ld a,c
        pop bc
        ret