Author Topic: pcw double buffer  (Read 907 times)

0 Members and 1 Guest are viewing this topic.

Offline arnoldemu

  • Supporter
  • 6128 Plus
  • *
  • Posts: 5.335
  • Country: gb
    • Unofficial Amstrad WWW Resource
  • Liked: 2261
  • Likes Given: 3478
pcw double buffer
« on: 20:14, 31 January 14 »
Back in 2010 I tried to implement double buffering on a pcw, I came up with this solution:

Code: [Select]
;; double buffer on pcw
org &8000
nolist


di
ld a,&c3
ld (&0038),a
ld hl,int1
ld (&0039),hl
ei

;; page 0,1 is screen 1 (9k free in page 1)
;; page 2,3 is screen 2 (9k free in page 3)
;; page 2 temporarily used to setup roller tables

ld a,roller_base1
ld (roller_base),a

ld a,screen_ram_base2
ld (screen_ram_base),a

call screen_set

;; table 1 at &0000 in block 4
;; table 2 at &0400 in block 4
;; 15872 bytes free here

;; 23040 bytes per screen with 256 lines
;; 46080 bytes for all screens

roller_table_page equ 1

;; 512 multiple within offset
roller_table_offs1 equ 30
roller_table_offs2 equ 31

;; roller table in page 4
roller_base1 equ (roller_table_page*32)+roller_table_offs1
roller_base2 equ (roller_table_page*32)+roller_table_offs2

roller_swap equ roller_base1 xor roller_base2

screen_ram_base1 equ 0
screen_ram_base2 equ 2

screen_ram_base_swap equ screen_ram_base1 xor screen_ram_base2

ld a,roller_table_page or &80
out (&f2),a

;; roller ram 1
;; page 0/1
ld ix,&8000+(roller_table_offs1*512)
ld hl,&0000+(screen_ram_base1*8192)
ld b,0
rr1:
ld (ix+0),l
ld (ix+1),h
inc ix
inc ix
call scr_next_line_normal_rr
djnz rr1

;; roller ram 2
;;
;; page 2/3
ld ix,&8000+(roller_table_offs2*512)
ld hl,&0000+(screen_ram_base2*8192)
ld b,0
rr2:
ld (ix+0),l
ld (ix+1),h
inc ix
inc ix
call scr_next_line_normal_rr
djnz rr2


int1:
push af
in a,(&f8)
bit 6,a
jr z,int1_nv

call screen_set

int1_nv
pop af
ei
reti

screen_set:

;; swap base
ld a,(roller_base)
xor roller_swap
ld (roller_base),a
out (&f5),a

;; toggle screen ram base
ld a,(screen_ram_base)
xor screen_ram_base_swap
ld (screen_ram_base),a
or &80
out (&f0),a
inc a
out (&f1),a
ret


roller_base:
defb 0

screen_ram_base
defb 0

line_length_bytes equ 720
line_length_bytes_minus_8 equ line_length_bytes-8

line_length_bytes_rr equ 720/16
line_length_bytes_minus_8_rr equ line_length_bytes_rr-8
;; this gets next line based on byte address
;; ok for sprites not ok for roller ram
;;

;; 0 8 16 24 32... 89
;; 1 9
;; 2
;; 7
;; 720

scr_next_line_normal:
inc l
ld a,l
and &7
ret nz
ld a,l
add a,line_length_bytes_minus_8 AND 255
ld l,a
ld a,h
adc a,line_length_bytes_minus_8/256
ld h,a
ret


scr_next_line_normal_rr:
inc l
ld a,l
and &7
ret nz
ld a,l
add a,line_length_bytes_minus_8_rr AND 255
ld l,a
ld a,h
adc a,line_length_bytes_minus_8_rr
ld h,a
ret



I'm not sure the code builds.

I setup 2 "roller ram display lists" which I switched.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource