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

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search
(Screen Dump (Epson))
(Unerase)
Line 502: Line 502:
  
 
=Unerase=
 
=Unerase=
The Z80 assembler code for David Link's Unerase program.
+
The Z80 assembler code for David Link's Unerase program.<br/>
 +
See Amstrad Computer User, March 1985 for more details.
 
<pre>
 
<pre>
 
; Unerase a file in CP/M - 04/11/84
 
; Unerase a file in CP/M - 04/11/84

Revision as of 01:42, 27 April 2009

Return to ACU Type-Ins

Downloads

Disk Image

Cover Image

Acu march 1985 cover.png

Boolean operations demonstration

To run Boolean operations demonstration, type:
RUN"BOOLEAN"

Electric Eddy

To run Electric Eddy, type:
RUN"EDDY"

Electric Fencing

To run Electric Fencing, type:
RUN"FENCING"

Flashman

To run Flashman, type:
RUN"FLASHMAN"

Jeremy Vine's music routine

To run Jeremy Vine's music routine, type:
RUN"MUSIC"

Machine code fill routine and demonstration

To run Machine code fill routine and demonstration, type:
RUN"MCFILL"

Number Sort routine

To run Number Sort routine, type:
RUN"SORT"

Prime Numbers (1)

To run Prime Numbers (1), type:
RUN"PASCAL3"

Prime Numbers (2)

To run Prime Numbers (2), type:
RUN"PASCAL4"

Screen Dump (DMP1)

The Z80 assembler code for the DMP1 Screen Dump program.
The machine code can be loaded in BASIC using DMPLIST2.BAS and DMPLIST4.BAS.
See Amstrad Computer User, March 1985 for more details.

			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
							; DMP1DUMP
.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

.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,&02
			CALL	MC_PRINT_CHAR
			LD	A,&40
			CALL	MC_PRINT_CHAR		; &240

.LINE			EQU	$
			LD	(IX+0),0		; byte out = 0
			LD	(IX+6),0		; 7-bit count = 0

.BYTE			SRA	(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	6,(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

Screen Dump (Epson)

The Z80 assembler code for the Epson Screen Dump program.
The machine code can be loaded in BASIC using DMPLIST2.BAS and DMPLIST4.BAS.
See Amstrad Computer User, March 1985 for more details.

			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

Sum Numbers

To run Sum Numbers, type:
RUN"PASCAL5"

Trench

To run Trench, type:
RUN"TRENCH"

Unerase

The Z80 assembler code for David Link's Unerase program.
See Amstrad Computer User, March 1985 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	$