Difference between revisions of "ACU March 1985 - Type-ins"

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search
(Screen Dump (DMP1))
(Screen Dump (Epson))
Line 290: Line 290:
  
 
=Screen Dump (Epson)=
 
=Screen Dump (Epson)=
The Z80 assembler code for the Epson Screen Dump program.<br/>
+
DMPEPSON.ASM contains the Z80 assembler code for the "Events & Screen Dumps" article.<br/>
The machine code can be loaded in BASIC using DMPLIST2.BAS and DMPLIST4.BAS.<br/>
+
DMPLIST2.BAS and DMPLIST4.BAS contain the related BASIC code.<br/>
 
See Amstrad Computer User, March 1985, page 90 for more details.
 
See Amstrad Computer User, March 1985, page 90 for more details.
<pre>
 
ORG &8000
 
 
.entry EQU $
 
LD HL,&E9E1 ; Start RELOCATOR
 
LD (&30),HL
 
RST &30
 
 
.this EX DE,HL
 
LD HL,rel_table-this
 
ADD HL,DE ; HL has absolute address of rel_table
 
 
.loop LD C,(HL)
 
INC HL
 
LD B,(HL) ; BC has first entry in table
 
LD A,C
 
OR B
 
JR Z,done ; entry was 0000 so exit loop
 
PUSH HL ; stack current table pointer
 
LD H,B
 
LD L,C
 
ADD HL,DE ; make table entry absolute
 
PUSH HL ; and stack this value
 
LD C,(HL)
 
INC HL
 
LD B,(HL) ; get contents pointed to by entry
 
LD H,B
 
LD L,C
 
ADD HL,DE ; make this absolute
 
LD B,H
 
LD C,L
 
POP HL ; retrieve absolute entry value
 
LD (HL),C
 
INC HL
 
LD (HL),B ; store absolute value at this address
 
POP HL ; get address of previous table entry
 
INC HL ; make HL point at next
 
JR loop
 
 
.done EQU $ ; end of RELOCATOR
 
 
KL_NEW_FRAME_FLY EQU &BCD7
 
KM_TEST_KEY EQU &BB1E
 
COPY_key EQU 9
 
CTRL_key EQU 23
 
SHIFT_key EQU 21
 
 
.r01 LD HL,tick_block-this ; set-up EVENT
 
LD B,%10000001
 
LD C,0
 
 
.r02 LD DE,int_routine-this
 
CALL KL_NEW_FRAME_FLY
 
RET
 
 
.int_routine EQU $ ; this is the interrupt routine
 
PUSH BC
 
PUSH DE
 
PUSH HL
 
PUSH AF
 
LD A,COPY_key
 
CALL KM_TEST_KEY
 
JR Z,return
 
LD A,CTRL_key
 
CALL KM_TEST_KEY
 
JR Z,return
 
 
.r03 CALL scrndump-this
 
 
.return POP AF
 
POP HL
 
POP DE
 
POP BC
 
RET
 
 
.tick_block DEFS 9
 
 
.FRED DEFS 7
 
 
.scrndump EQU $
 
 
GRA_TEST_ABSOLUTE EQU &BBF0
 
MC_PRINT_CHAR EQU &BD2B
 
MC_BUSY_PRINTER EQU &BD2E
 
; EPSONDUMP
 
.r04 LD IX,FRED-this
 
LD (IX+1),0 ; x coord = 0
 
LD (IX+2),0
 
LD (IX+3),&90 ; y coord = 400
 
LD (IX+4),&01
 
LD (IX+5),0 ; line count = 0
 
LD (IX+0),0 ; byte out = 0
 
 
LD A,&1B
 
CALL MC_PRINT_CHAR
 
LD A,&41
 
CALL MC_PRINT_CHAR
 
LD A,&06
 
CALL MC_PRINT_CHAR
 
 
.MAIN CALL MC_BUSY_PRINTER
 
JR C,MAIN
 
LD A,&1B
 
CALL MC_PRINT_CHAR ; ESC
 
LD A,&4B
 
CALL MC_PRINT_CHAR ; "K"
 
LD A,&40
 
CALL MC_PRINT_CHAR
 
LD A,&02
 
CALL MC_PRINT_CHAR ; &240
 
 
.LINE EQU $
 
LD (IX+0),0 ; byte out = 0
 
LD (IX+6),0 ; 7-bit count = 0
 
 
.BYTE SLA (IX+0)
 
LD E,(IX+1) ; FRED + 1 - 2 = x coord
 
LD D,(IX+2)
 
LD L,(IX+3) ; FRED + 3 - 4 = y coord
 
LD H,(IX+4)
 
CALL GRA_TEST_ABSOLUTE
 
OR A
 
JR Z,NOSET
 
SET 0,(IX+0) ; +0 is byte being built
 
 
.NOSET INC (IX+6) ; increase bit count
 
LD A,(IX+6) ; and get it
 
CP 7
 
JR Z,PRINT ; if got 7 bits the print
 
LD L,(IX+3) ; get y coord
 
LD H,(IX+4)
 
DEC HL ; use HL for simple 16 bit maths
 
DEC HL ; move down by 2 (1 pixel)
 
LD (IX+3),L ; then put it back
 
LD (IX+4),H
 
JR BYTE
 
 
.MID_JMP JR MAIN ; to relative jump more than 128
 
 
.PRINT CALL MC_BUSY_PRINTER
 
JR C,PRINT ; wait until it's free
 
LD A,(IX+0) ; get byte output
 
CALL MC_PRINT_CHAR ; and print it
 
INC (IX+1)
 
INC (IX+1) ; move x coord on by 2
 
JR NZ,NOHIGH
 
INC (IX+2) ; handle high byte if necessary
 
 
.NOHIGH LD A,(IX+1)
 
SUB &82
 
JR NZ,RESETY
 
LD A,(IX+2)
 
CP 2
 
JR Z,ENDLIN ; x coord = &282
 
 
.RESETY LD L,(IX+3)
 
LD H,(IX+4)
 
LD DE,&000C
 
ADD HL,DE
 
LD (IX+3),L ; increase y coord by 12
 
LD (IX+4),H
 
JR LINE
 
 
.ENDLIN INC (IX+5) ; increment line count
 
LD A,&0A ; Line Feed
 
CALL MC_PRINT_CHAR
 
LD A,&0D ; Carriage Return
 
CALL MC_PRINT_CHAR
 
LD A,SHIFT_key
 
CALL KM_TEST_KEY ; check id SHIFT is pressed
 
JR NZ,BYE
 
LD (IX+1),0 ; set x coord to zero
 
LD (IX+2),0
 
LD A,(IX+5) ; get line count
 
CP &22
 
JR NZ,MID_JMP ; have we got 34 lines (7 high)
 
 
.BYE EQU $
 
LD A,15
 
CALL MC_PRINT_CHAR
 
LD A,13
 
CALL MC_PRINT_CHAR
 
RET
 
 
.rel_table EQU $
 
DEFW r01-this+1
 
DEFW r02-this+1
 
DEFW r03-this+1
 
DEFW r04-this+2 ; address in IX operator is 3 and 4
 
DEFW 0
 
</pre>
 
  
 
=Sum Numbers=
 
=Sum Numbers=

Revision as of 09:43, 31 July 2009

Return to ACU Type-Ins

Downloads

Disk Image

Cover Image

Acu march 1985 cover.png

Boolean operations demonstration

RUN"BOOLEAN"
Acu Boolean1.png Acu Boolean2.png

Electric Eddy

RUN"EDDY"
Acu Eddy1.png Acu Eddy2.png Acu Eddy3.png Acu Eddy4.png Acu Eddy5.png Acu Eddy6.png Acu Eddy7.png Acu Eddy8.png

Electric Fencing

RUN"FENCING"
Acu Fencing1.png Acu Fencing2.png Acu Fencing3.png Acu Fencing4.png

Flashman

RUN"FLASHMAN"
Acu Flash1.png Acu Flash2.png Acu Flash3.png Acu Flash4.png Acu Flash5.png Acu Flash6.png

Jeremy Vine's music routine

RUN"MUSIC"
Acu Music1.png

Machine code fill routine and demonstration

RUN"MCFILL"
Acu Mcfill1.png Acu Mcfill2.png Acu Mcfill3.png Acu Mcfill4.png

Manipulating the Amstrad CPC464 Screen Display

The Z80 assembler code for the "Manipulating the Amstrad CPC464 Screen Display" article.
See Amstrad Computer User, March 1985, page 103 for more details.

Routine 1
		ORG	&8000

.start		LD	HL,XXXX		; address of top left corner of area
		LD	DE,XXXX		; address of store area
		LD	B,8

.loop1		PUSH	BC
		PUSH	HL
		LD	B,8		; number of horizontal lines

.loop2		LD	A,(HL)
		LD	(DE),A
		INC	DE
		INC	HL
		DJNZ	loop2
		POP	HL
		LD	BC,&0000	; add &0800 to screen address
		ADD	HL,BC
		JR	NC,loopend	; jump if total not more than &FFFF
		LD	BC,&3FB0
		AND	A		; else subtract &3FB0
		SBC	HL,BC

.loopend	POP	BC
		DJNZ	loop1
		RET

Routine 2

	ORG	&4000

.pixstr	DEFB	0

.start	LD	HL,&C000	; Address of top-left corner of screen
	LD	E,&88		; mask for left-most pixel in byte
	LD	B,200		; number of pixel lies in screen

.loop1	PUSH	BC
	PUSH	HL		; save address of first byte on stack
	LD	A,(HL)		; get first screen byte
	AND	E		; mask off all pixels except left-most
	LD	(pixstr),A	; store pixel for later
	CPL
	AND	(HL)		; blank out pixel
	LD	(HL),A		; update screen
	RLC	(HL)		; rotate screen byte left
	LD	B,79		; number of bytes in line minus one

.loop2	INC	HL		; next byte
	LD	A,(HL)
	AND	E		; mask off all pixels except left-most
	LD	D,A		; save pixel for later
	CPL
	AND	(HL)		; blank out pixel
	LD	(HL),A		; update screen
	RLC	(HL)		; rotate screen byte left
	LD	A,D		; recover pixel

.loop3	RRC	E		; rotate mask right one bit
	JR	C,out1		; jump out when mask bit rotates out
	SRL	A		; else shift pixel right
	JR	loop3		; and repeat

.out1	DEC	HL		; back to previous byte
	OR	(HL)
	LD	(HL),A		; insert pixel into screen byte
	INC	HL		; restore screen address
	DJNZ	loop2		; jump back unless finished with line
	LD	A,(pixstr)	; recall stored pixel

.loop4	RRC	E		; rotate mask right one bit
	JR	C,out2		; jump out when mask bit rotates out
	SRL	A		; else shift pixel right
	JR	loop4		; and repeat

.out2	OR	(HL)
	LD	(HL),A		; insert pixel into screen byte
	POP 	HL
	LD	BC,&0800
	ADD	HL,BC		; next line down
	JR	NC,end		; jump if total not greater than &FFFF
	AND	A
	LD	BC,&3FB0
	SBC	HL,BC		; else subtract &3FB0

.end	POP	BC
	DJNZ	loop1		; jump back unless finished
	RET

Routine 3

	ORG	&4000

.pixstr	DEFB	0

.start	LD	HL,&C04F	; Address of top-left corner of screen
	LD	E,&11		; mask for left-most pixel in byte
	LD	B,200		; number of pixel lies in screen

.loop1	PUSH	BC
	PUSH	HL		; save address of first byte on stack
	LD	A,(HL)		; get first screen byte
	AND	E		; mask off all pixels except left-most
	LD	(pixstr),A	; store pixel for later
	CPL
	AND	(HL)		; blank out pixel
	LD	(HL),A		; update screen
	RRC	(HL)		; rotate screen byte left
	LD	B,79		; number of bytes in line minus one

.loop2	DEC	HL		; next byte
	LD	A,(HL)
	AND	E		; mask off all pixels except left-most
	LD	D,A		; save pixel for later
	CPL
	AND	(HL)		; blank out pixel
	LD	(HL),A		; update screen
	RRC	(HL)		; rotate screen byte left
	LD	A,D		; recover pixel

.loop3	RLC	E		; rotate mask right one bit
	JR	C,out1		; jump out when mask bit rotates out
	SLA	A		; else shift pixel right
	JR	loop3		; and repeat

.out1	INC	HL		; back to previous byte
	OR	(HL)
	LD	(HL),A		; insert pixel into screen byte
	DEC	HL		; restore screen address
	DJNZ	loop2		; jump back unless finished with line
	LD	A,(pixstr)	; recall stored pixel

.loop4	RLC	E		; rotate mask right one bit
	JR	C,out2		; jump out when mask bit rotates out
	SLA	A		; else shift pixel right
	JR	loop4		; and repeat

.out2	OR	(HL)
	LD	(HL),A		; insert pixel into screen byte
	POP 	HL
	LD	BC,&0800
	ADD	HL,BC		; next line down
	JR	NC,end		; jump if total not greater than &FFFF
	AND	A
	LD	BC,&3FB0
	SBC	HL,BC		; else subtract &3FB0

.end	POP	BC
	DJNZ	loop1		; jump back unless finished
	RET

Routine 4

	ORG	&4000

.start	LD	HL,&C000	; top left corner of screen address
	LD	B,200		; number of pixel lines

.loop1	PUSH	BC
	PUSH	HL		; save line start address on stack
	XOR	A		; zero accumulator and clear carry flag
	LD	B,80		; number of bytes in line

.loop2	RR	(HL)		; rotate right, carry to d7, d0 to array
	INC	HL		; next byte
	DJNZ	loop2		; loop until finished with line
	POP	HL		; recover address of first byte in line
	RRA			; rotate last bit from carry into A
	OR	(HL)
	LD	(HL),A		; insert pixel into first byte
	LD	BC,&0800
	ADD	HL,BC		; next pixel line
	JR	NC,end		; jump if total not greater than &FFFF
	AND	A
	LD	BC,&3FB0
	SBC	HL,BC		; else subtract &3FB0

.end	POP	BC
	DJNZ	loop1		; loop unless finished
	RET

Routine 5

	ORG	&4000

.start	LD	HL,&C04F	; top left corner of screen address
	LD	B,200		; number of pixel lines

.loop1	PUSH	BC
	PUSH	HL		; save line start address on stack
	XOR	A		; zero accumulator and clear carry flag
	LD	B,80		; number of bytes in line

.loop2	RL	(HL)		; rotate right, carry to d7, d0 to array
	DEC	HL		; next byte
	DJNZ	loop2		; loop until finished with line
	POP	HL		; recover address of first byte in line
	RLA			; rotate last bit from carry into A
	OR	(HL)
	LD	(HL),A		; insert pixel into first byte
	LD	BC,&0800
	ADD	HL,BC		; next pixel line
	JR	NC,end		; jump if total not greater than &FFFF
	AND	A
	LD	BC,&3FB0
	SBC	HL,BC		; else subtract &3FB0

.end	POP	BC
	DJNZ	loop1		; loop unless finished
	RET

Number Sort routine

RUN"SORT"
Acu Sort1.png Acu Sort2.png Acu Sort3.png Acu Sort4.png

Prime Numbers (1)

RUN"PASCAL3"
Acu Pascal3 1.png Acu Pascal3 2.png

Prime Numbers (2)

RUN"PASCAL4"
Acu Pascal4 1.png Acu Pascal4 2.png

Screen Dump (DMP1)

DMPDMP1.ASM contains the Z80 assembler code for the "Events & Screen Dumps" article.
DMPLIST2.BAS and DMPLIST4.BAS contain the related BASIC code.
See Amstrad Computer User, March 1985, page 90 for more details.

Screen Dump (Epson)

DMPEPSON.ASM contains the Z80 assembler code for the "Events & Screen Dumps" article.
DMPLIST2.BAS and DMPLIST4.BAS contain the related BASIC code.
See Amstrad Computer User, March 1985, page 90 for more details.

Sum Numbers

RUN"PASCAL5"
Acu Pascal5 1.png Acu Pascal5 2.png

Trench

RUN"TRENCH"
Acu Trench1.png Acu Trench2.png Acu Trench3.png Acu Trench4.png Acu Trench5.png Acu Trench6.png Acu Trench7.png

Unerase

The Z80 assembler code for David Link's Unerase program.
See Amstrad Computer User, March 1985, page 40 for more details.

						; Unerase a file in CP/M - 04/11/84
						; Copyright David Link 1984

						; A program to unerase a file that has been accidentally
						; erased. Should be used immediately after erasing the
						; file since if user later, some blocks may have been re-used.

						; Format is - UNERA filename

DEFCB		EQU	&5C

fnamelen	EQU	8
extlen		EQU	3
extent		EQU	12
dirlen		EQU	32

						; CP/M BDOS call numbers

OPEN		EQU	15
CLOSE		EQU	16
SEARCH		EQU	17
SRCH_AGAIN	EQU	18
MAKE		EQU	22
SETDMA		EQU	26

						; Default workspace for file reads

tbuff		EQU	128

						; Macro to call CP/M setting DE and C

DOS		MAC
		LD	DE,=0
		LD	C,=1
		CALL	Dos
		ENDM

						; Macro to call CP/M setting C.

SDOS		MAC
		LD	C,=0
		CALL	Dos
		ENDM

						; COM files begin at &100

		ORG	&100

		LD	SP,(6)			; set stack to top of TPA
		DOS	DEFCB,SEARCH		; Does file exist?
		INC	A
		JP	NZ,0			; File exists, return to CCP
		LD	HL,FCBSPACE		; Initialise pointer to current FCB
		LD	(FCBPTR),HL
		DOS	tbuff,SETDMA		; set disc I/O to tbuff
		DOS	DUMFCB,SEARCH		; and search for the first entry in directory

More_Search	INC	A
		JR	Z,End_of_Directory	; No more entries

						; Compare found filename with the required filename

Continue	DEC	A			; adjust because we INCed it
		ADD	A,A			; multiply by dirlen to get postion
		ADD	A,A			; of entry in catalogue
		ADD	A,A
		ADD	A,A
		ADD	A,A
		LD	D,0
		LD	E,A
		LD	HL,tbuff		; point to found file
		ADD	HL,DE

Again		PUSH	HL			; and compare it with required filename
		INC	HL
		LD	B,fnamelen+extlen	; both name and type (8, name : 3, type)
		LD 	DE,DEFCB+1		; filename starts at FCB + 1

Match		LD	A,(DE)
		LD	C,(HL)
		RES	7,C			; some CP/Ms set bits on filename
		CP	C			; so make sure top bit is reset for comparison
		INC	HL
		INC	DE
		JR	NZ,NoMatch		; not this one
		DJNZ	Match			; good so far... keep going

						; Match found

		POP	HL			; filename match, but...
		PUSH	HL
		LD	A,(HL)			; ... is it erased?
		CP	&E5			; e% in first byte of directory = erased
		JR	NZ,NoMatch		; not erased... so search some more
		LD	(HL),0			; it was erased, so unerase it
		LD	DE,(FCBPTR)		; and store the FCB information in
		LD 	BC,dirlen		; our temporary table
		LDIR
		LD	(FCBPTR),DE		; updating our table pointer afterwards

						; Search for another entry

NoMatch		POP	HL
		DOS	DUMFCB,SRCH_AGAIN	; search for next entry in directory
		JR	More_Search

						; we have now exhausted the directory search and built
						; up our table of directory entries for the required file

End_of_Dir	LD	DE,FCBSPACE		; start processing table of matched
						; directory entries
MAIN_LOOP	LD	HL,(FCBPTR)		; have we reached end of table?
		OR	A
		SBC	HL,DE
		JP	Z,0			; finished, so return
		PUSH	DE			; save table pointer
		LD	HL,extent		; address extent byte
		ADD	HL,DE
		LD	A,(HL)			; make an extent of new,
		LD	(DEFCB+extent),a	; unerased file...
		DOS	DEFCB,MAKE
		POP	DE			; recover pointer to FCB...
		SDOS	CLOSE			; and close it
		LD	HL,dirlen
		ADD	HL,DE			; have we reached end of table?
		EX	DE,HL
		JR	MAIN_LOOP

Dos		PUSH	HL
		PUSH	DE
		PUSH	BC
		CALL	5
		POP	BC
		POP	DE
		POP	HL
		RET

FCBPTR		DEFS	2

DUMFCB		DEFM	"????????????"
		DEFW	0,0
		DEFS	16
		DEFW	0,0

FCBSPACE	EQU	$