I'll assume you've already read the first bit about redefining Joyce characters.
So you already know what USERF and SCR RUN ROUTINE are.
In that same bank of memory as the character matrices is a small chunk of memory known as the roller RAM and a bigger chunk that holds the screen pixel information.
The roller RAM sits at #B600 and consists of 256 word addresses which are the encoded start addresses for each pixel line on the screen.
That is
As mentioned above, I have included a screen dump program here that shows an example of reading bytes from the screen memory.
To actually make use of this the following steps should be followed.
Now I know some of you will have two drives so I'm not going to attempt to explain which discs go where.
I assume if you've got this far then you can work it out anyway. :
;test
;
; Joyce screen dump using ESC L n1 n2 to give about 3/4 width dump
;
; program by Cliff Lawson, 1986 Amstrad Consumer Electronics plc.
;
; This is inplemented as a null .COM file with attached RSX that is set
; to renain in memory. It intercepts BOOS function 2 and if an escape
; character is printed then the dump springs into life. Two types of dump
; are supported. ESC O gives a heavy print while ESC P is more of a "draft"
; quality dump. The heavy one works by printing the info, once, performing
; a fractional line feed then overprinting followed by the rest of a conplete
; line feed.
; A new BDOS call 73 (as always) is implemented so that the RSX can be
; removed.
;
; Use RMAC B:JOYCEDMP $PZSZRM
; LINK M:JOYCEDMP[OP $SZRB]
; REN JOYCEDMP.RSX=JOYCEDMP.PRL
; GENCOM B:JOYCEDMP [NULL]
;
bdos equ 5
listout equ 5
cr equ 00dh
lf equ 00ah
esc equ 27
heavy equ 'O'
light equ 'P'
offsetuserf equ 87
scrrunroutine equ 00e9h
bytesperline equ 720
roller equ 0b600h
ldir macro
db 0edh,0b0h
endm
db 0,0,0,0,0,0 ;'ole faithful RSX prefix
jmp start
next: db 0c3h
dw 0 ;next chain entry filled by LOADER
prev: dw 0 ;previous entry " " "
remov: db 000h ;leave in memory
nbank: db 0 ;not non-banked
db 'SCRNDMP'
loader: db 0
db 0,0
start
mov a,c
cpi 2
jz begin
cpi 73
jz takeaway
jmp next
takeaway
mvi a,0ffh
sta remov
ret
begin
lda flagesc
cpi 0ffh
jz contest ;just had an escape
mov a,e
cpi esc ;escape O or P Starts dump
jz setflag
jmp next ;nothing to do with us
setflag
mvi a,0ffh
sta flagesc
ret
contest
mov a,e
cpi heavy ;heavy dump
jz goforit
cpi light ;light dump
jz goforit
xra a
sta flagesc ;forget that last ESC
push d
push b
mvi c,2
mvi e,esc
call next ;but esc wasn't ours so make amends
pop b
pop d
jmp next ;pass current char down the thain
goforit
sta dtype ;save 'O' or 'P' that deterwine dump type
xra a
sta flagesc ;esc has been used so reset
lxi h,0
dad sp
shld oldstak ;save CCP stack
lxi sp,mystak ;use my own 64 byte stack
lhld 1
lxi d,offsetuserf
dad d
shld userf+1 ;that famous ole routine
mvi a,esc
call prntbyte
mvi a,'3'
call prntbyte
mvi a,25 ;fiddle factor
call prntbyte
mvi a,0 ;start at line 0
dloop
push psw ;keep line count safe
dark
push psw ;save line count while sussin lf setting
lda dtype
cpi light
jz fred
mvi a,esc ;only set this fractional line feed lf
call prntbyte ;we're going to overtype for heavy dump
mvi a,'3'
call prntbyte
mvi a,2
call prntbyte ;set first line feed to 2/216"
fred
pop psw ;ok to retrieve line count for grabyte
lxi b,grabyte
call userf
dw scrrunroutine
call dumpaline
lda dtype
cpi light
jz justone ;If ESC P then dont do line again
mvi a,esc ;second pass, lf now to be set to 23/216"
call prntbyte
mvi a,'3'
call prntbyte
mvi a,23 ;previous 2/216 + 23/216 = 25/216
call prntbyte
pop psw
push psw ;what was that line count ?
lxi b,grabyte ;need to grab bytes cos dump is destructive
call userf
dw scrrunroutine
call dumpaline ;overtype what's just been printed
justone
mvi c,6
mvi e,0ffh
call next ;attempt to get keyboard char
cpi 0
jnz pleasereleaseme
pop psw ;let's have that line count back again
inr a
cpi 32 ;done line 31 yet ?
jnz dloop
eric
lda dtype
cpi light
jz dontreset ;cos it hasn't changed
mvi a,esc
call prntbyte
mvi a,'2' ;set line feed Back to 1/6"
call prntbyte
dontreset
lhld oldstak ;let Mr. CCP have his own stack back
sphl
ret ;an ave it away an our toes
pleasereleaseme
pop psw ;don't you just luv a bit of structure ?
jmp eric
;=======
grabyte
;=======
;
; Go get one lines worth of bytes fror screen memory
;
; entry : a contains the character line number
; exit : all corrupt
;
mov e,a
;
;The following is a routine whith already sits in common memory
; and is executed by scr_run_routine
;
; this routine courtesy Roland Perry
;
; entry conditions:
;
; e=line number
;
docommon:
lxi h,buffer
push h
mvi h,0
mov l,e ;hl=e
dad h ;hl=2*e
dad h ;hl=4*e
dad h ;hl=8*e
dad h ;hl=16*e
lxi d,roller ;that mysterious region of the universe
dad d ;hl=roller+16+e
;
mov e,m
inx h
mov d,m ;de=encoded address
;
mov a,e
ani 7 ;also clears carry
mov l,a ;l = 3 lsb
mov a,e
ral ;lp8 to carry
mov e,a ;lp7-4/lp2-lp0/carry
mov a,d
ral ;lsb=lp8
mov d,a
mov a,e
ani 0F0h ;lp7-lp4
ora l
mov e,a ;don't you just love meaningful comments
;
pop h
lxi b,bytesperline
xchg ;move from screen to buffer
ldir
ret
;
;=========
dumpaline:
;=========
;
; Dump one lines worth of byte to printer. There are 90 characters each
; composed of eight bytes so HL points at buffer containing 720 bytes.
;
; entry : no conditions
; exit : all registers corrupt
; (and Buffer contents destroyed)
;
lxi h,buffer
mvi a,esc ;let Mr. printer know whats happening
call prntbyte
mvi a,'L'
call prntbyte
mvi a,(bytesperline and 0ffh)
call prntbyte
mvi a,(bytesperline/256)
call prntbyte
mvi b,0 ;character count (0..89)
dstart
push b
mvi b,8 ;number of shifts count (8)
ateshft
xra a ;clear A and carry
mvi c,8 ;number of bytes in a group (8)
push h
atebit
db 0cbh,026h ;Z80 SLA (HL)
;drawback of this is that it can't be single
;stepped in SID. So put NOP after to hold a
;RST 6 if needed
; nop
ral ;so the 8080 does have rotates after all
inx h
dcr c
jnz atebit ;have we got all 8 top bits ?
call prntbyte ;yup, so print that character
pop h
dcr b
jnz ateshft ;have the current group been shifted 8 times
lxi d,8
dad d ;step hl onto next group of 8
pop b
inr b
mov a,b
cpi 90 ;hit the 90th group of 8 yet ?
jnz dstart
mvi a,cr ;Guess it uould be a guod idea to start
call prntbyte ;next line at l.h. margin
mvi a,lf
call prntbyte ;either 2/216,23/216 or just 25/216
ret
prntbyte
push h
push d
push b
mov e,a
mvi c,listout
call bdos
pop b
pop d
pop h
ret
userf: db 0c3h ;what do you mean you've never heard of it
dw 0
dseg
flagesc db 0
dtype db 0
oldstak dw 0
buffer ds 720
ds 64
mystak
end