Changes
Created page with 'Here is the original Amstrad CPC source code of the [[PDS development system]] download functions. Below DLn files (and other versions for C64, BBC, Spectrum) are also found in […'
Here is the original Amstrad CPC source code of the [[PDS development system]] download functions. Below DLn files (and other versions for C64, BBC, Spectrum) are also found in [[Media:PDS source code.zip]].
== AMSTRAD.DL0 (short version, 114 bytes) ==
<pre>
; Amstrad short download software
;
;
;Only to be used for assembling and downloading, most monitor functions
;will not opperate with this download software. It has been kept as short
;as possible. Note that the interupts are disabled. This is to prevent
;your own interupt routines crashing if they are overwritten.
;The code is 114 bytes long. It may be ORG'ed anywhere.
;
;
ORG 8000H
;
START LD A,255
LD BC,0FBEEH
OUT (C),A
OUT (C),A
INC C
OUT (C),A ;Initial port setup
LD C,0EDH
OUT (C),A
LD C,0EFH
LD A,63
OUT (C),A
LD D,64 ;Protocol flags to input from main computer
DI
;
; Main loop
;
MAINLOOP CALL GETBYTE ;Get 'command byte'
LD A,E
CP 180 ;Download code into aabb, len=ccdd
JZ DLOAD
CP 183
JZ BANK
CP 181
JNZ MAINLOOP ;If unknown, keep looping
;
; Function 181, Execute code from aabb
;
CALL GETBYTE
LD H,E ;Get address
CALL GETBYTE
LD L,E
LD BC,MAINLOOP ;CALL it.
PUSH BC
JP (HL)
;
; Function 183, Select bank aa
;
BANK CALL GETBYTE
LD B,7FH ;You may write your own routine here.
LD C,E ;You may corrupt everything except E
OUT (C),C ;This allows you to page in rom and ram
JR MAINLOOP
;
; Function 180, Download code into aabb, length=ccdd
;
DLOAD CALL GETBYTE
LD H,E
CALL GETBYTE ;Get start address of code
LD L,E
CALL GETBYTE
LD B,E
CALL GETBYTE ;Get length of code
LD C,E
DLOAD1 CALL GETBYTE
LD (HL),E ;Get and store bytes
INC HL
DEC BC
LD A,B
OR C
JNZ DLOAD1
JR MAINLOOP ;Go back into main download loop
;
; Get a byte from the main computer into E
;
GETBYTE PUSH BC
LD BC,0FBEDH
$1 IN A,(C)
XOR D ;Wait for 'sent the byte'
RRCA
JC $1
DEC C
IN E,(C) ;Get the byte
INC C
LD A,D
OUT (C),A ;Say 'byte received'
XOR 129
LD D,A ;Flip flags ready for next byte
POP BC
RET
;
;
; The end of the PDS download software.
;
; Now is a short routine to return to basic from the ASMSTRAD download
; software supplied with the system. Note that to run the download software
; you must use the following :
;
; LOAD "D" : CALL 40000
;
; When you assemble and download this program you will return to basic, to
; save to disk or tape use the following:
;
; SAVE "DLOAD",B,start address,114,start address
;
; Now it will be saved so it will auto run when RUN "DLOAD is typed.
;
;
ORG START-3
POP HL ;Get rid of return to PDS software
EI
RET ;Start interupts and return
;
;
;
SEND COMPUTER1
END
</pre>
== AMSTRAD.DL1 (long version, 374 bytes) ==
<pre>
; Amstrad long download software
;
;
;This download software can be used for assembling and download, and will
;work with all the monitor functions, such as trace, upload etc...It will
;not work with the Analyze command, which requires the DL2 software.
;Interupts are disabled. Jump to START the first time, this will setup all
;the ports. If you wish to enter the download software again, jump to
;MONITOR. The length of the code is 374 bytes.
;
;
ORG 8000H
;
;
; Initial setup code
;
START PUSH AF
LD A,255
LD BC,0FBEEH
OUT (C),A
OUT (C),A
INC C
OUT (C),A ;Initial port setup
LD C,0EDH
OUT (C),A
LD C,0EFH
LD A,63
OUT (C),A
INC A
LD (FLAGIO),A ;Initial flags 0 - Input
POP AF
;
; Now main part of download software
;
MONITOR DI ;Interupts would corrupt the stack
LD (ZHL),HL ;Save HL
LD (ZSP),SP ;Save SP
POP HL ;Get 'return' address
LD (ZPC),HL ;Where I was called from
LD SP,ZHL ;Top of register block
PUSH DE
PUSH BC
EXX
PUSH HL
PUSH DE
PUSH BC ;All registers are saved for PDS
PUSH IX
PUSH IY
PUSH AF
LD A,I
LD H,A
LD A,R
LD L,A
PUSH HL
EX AF,AF'
PUSH AF
LD D,0 ;D is the download flag
FLAGIO EQU $-1
;
; Mainloop
;
MAINLOOP CALL GETBYTE
LD A,E
CP 180 ;Download code into aabb, len=ccdd
JZ DLOAD
CP 186 ;Run code aa,bb,cc,dd
JP Z,EXECUTE
CP 184 ;Send register block to Apricot
JP Z,SENDREG
CP 185 ;Get register block from Apricot
JP Z,GETREG
CP 183 ;Select bank aa
JZ SBANK
CP 182 ;Upload code from aabb len=ccdd
JZ UPLOAD
CP 181 ;Execute code from aabb?
JNZ MAINLOOP ;Not recognised - keep looping.
;
; Function 181, Execute code from aabb
;
CALL GETBYTE
LD H,E
CALL GETBYTE ;Notice that the address is downloaded H then L
LD L,E
LD (EXEC+2),HL ;Put NOP, CALL <xxxx> into execution buffer
LD HL,0CD00H
LD (EXEC),HL
JP RUNIT
;
; Function 180, Download code into aabb, length=ccdd
;
DLOAD CALL GETBYTE
LD H,E
CALL GETBYTE ;Get start address of code
LD L,E
CALL GETBYTE
LD B,E
CALL GETBYTE ;Get length of code
LD C,E
DLOAD1 CALL GETBYTE
LD (HL),E ;Get and store bytes
INC HL
DEC BC
LD A,B
OR C
JNZ DLOAD1
JR MAINLOOP ;Go back into main download loop
;
; Function 183, select bank aa
;
SBANK CALL GETBYTE
LD B,7FH ;You may write your own routine here.
LD C,E ;You may corrupt everything except E
OUT (C),C ;This allows you to page in rom and ram
JR MAINLOOP
;
; Function 184, upload register block to the main computer.
;
SENDREG LD HL,REGISTERS
LD BC,26
JR UPLOAD1 ;Upload the register block
;
; Function 185, download register block from the main computer.
;
GETREG LD HL,REGISTERS
LD BC,26
JR DLOAD1 ;Download the register block
;
; Upload code, from aabb, length ccdd
;
UPLOAD CALL GETBYTE
LD H,E
CALL GETBYTE ;Get start address of code
LD L,E
CALL GETBYTE
LD B,E
CALL GETBYTE ;Get length of code
LD C,E
;
UPLOAD1 PUSH BC
LD BC,0FBEDH
$0 IN A,(C)
XOR D
RRCA
JC $0
INC C
LD A,255
OUT (C),A ;This swaps the PDS interface direction around
INC A
OUT (C),A ;The Amstrad now transmitts to the Apricot
LD A,D
XOR 65
LD D,A
POP BC
;
$1 LD A,(HL)
CALL SENDBYTE
INC HL ;Send the area of memory
DEC BC
LD A,B
OR C
JNZ $1
;
DEC A
LD BC,0FBEEH
OUT (C),A
OUT (C),A
DEC C
LD A,D
XOR 64 ;Swap the ports back to normal
OUT (C),A
XOR 128
LD D,A
;
JP MAINLOOP
;
; Function 186, execute the next 4 bytes, and reenter monitor
;
EXECUTE CALL GETBYTE
LD L,E
CALL GETBYTE
LD H,E
LD (EXEC),HL
CALL GETBYTE ;Get the 4 bytes to be run
LD L,E
CALL GETBYTE ;Store in execution buffer
LD H,E
LD (EXEC+2),HL
RUNIT LD A,D
LD (FLAGIO),A
POP AF
EX AF,AF'
POP HL
LD A,H
LD I,A
LD A,L
LD R,A
POP AF
POP IY
POP IX ;Get all registers off stack
POP BC
POP DE
POP HL
EXX
POP BC
POP DE
POP HL
LD SP,(ZSP)
EXEC DS 4 ;All code to be run is placed here
JP MONITOR
;
; Get a byte from the main computer into E
;
GETBYTE PUSH BC
LD BC,0FBEDH
$1 IN A,(C)
XOR D ;Wait for 'sent byte'
RRCA
JC $1
DEC C
IN E,(C) ;Get the byte
INC C
LD A,D
OUT (C),A ;Set 'byte received'
XOR 129
LD D,A ;Flip flags for next byte
POP BC
RET
;
; Send A to the main computer
;
SENDBYTE PUSH BC
LD BC,0FBECH
OUT (C),A ;Send the byte
INC C
LD A,D
OUT (C),A ;Set 'sent the byte'
XOR 129
LD D,A
$1 IN A,(C)
XOR D ;Wait for 'byte received'
RRCA
JNC $1
POP BC
RET
;
DW 0,0 ;Uses two levels of stack
REGISTERS DS 20 ;Other registers stored here
ZHL DW 0 ;HL stored here
ZPC DW 0 ;PC stored here
ZSP DW 0 ;SP stored here
;
;
;
; The end of the PDS download software.
;
; Now is a short routine to return to basic from the ASMSTRAD download
; software supplied with the system. Note that to run the download software
; you must use the following :
;
; LOAD "D" : CALL 40000
;
; When you assemble and download this program you will return to basic, to
; save to disk or tape use the following:
;
; SAVE "DLOAD",B,start address,374,start address
;
; Now it will be saved so it will auto run when RUN "DLOAD is typed.
;
;
ORG START-3
EXEC $
EI
POP HL
RET
;
;
;
SEND COMPUTER1
END
</pre>
== AMSTRAD.DL2 (interrupt driven) ==
<pre>
; This is the interupt driven download software for the Amstrad
;
; To use this software, insert a CALL to the routine PDSSETUP in the
; 'cold start' or 'once only' part of your program. Also insert a CALL
; to the routine MONITOR in your interupt routine. PDS corrupts HL,DE,BC
; and AF. The call to monitor must have HL containing the address where
; the interupt occured.
; You will now be able to use most of the monitor functions while your
; program is running and interupts enabled. Note that you cannot alter
; the registers or trace as this would not make sense under the interupts.
; The analyze command will also opperate now.
;
; Note that if you try and download programs, containing the PDS download
; software, chances are that you will crash the system as the download
; software contains self modifiying code that would get overwritten.
; To download programs just make sure you never download over the
; download software currently running.
;
; Below is the PDS download software and a short program that sets up the
; amstrad and returns you to basic, so you may modify memory while you
; are running basic programs.
; To run this, use the download software disk supplied and type :
;
; LOAD "D
; CALL 40000
;
; If you had used RUN"D you would not have been able to return to basic
; Now you can download the program
;
;
;
ORG 39000
EXEC $
;
; Setup interupts and return to basic
;
CALL PDSSETUP ;Initialize PDS software
DI
LD HL,(39H)
LD (INTEND+1),HL ;Redirect interupt vector
LD HL,INTR
LD (39H),HL
EI
POP HL ;Remove PDS return to download software address
RET
;
; End of example program
;
;
;
;
; Now the main PDS download software routines
;
;
; Initial setup code - only called once.
;
PDSSETUP LD A,255
LD BC,0FBEEH
OUT (C),A
OUT (C),A
INC C
OUT (C),A ;Initial port setup
LD C,0EDH
OUT (C),A
LD C,0EFH
LD A,63
OUT (C),A
INC A
LD (FLAGIO),A ;Initial protocol flags, input
RET
;
; An example interupt routine
;
INTR LD (STKSTO+1),SP
PUSH HL
PUSH DE
STKSTO LD HL,1
LD E,(HL)
INC HL ;Get HL=old PC address
LD D,(HL)
EX DE,HL
CALL MONITOR ;Do download software
POP DE
POP HL ;Now go back into AMSTRAD routines
INTEND JP 1
;
;
; Call this address from your interupt routine
;
MONITOR PUSH AF
PUSH BC ;Save all regs from your program
PUSH DE
PUSH HL
LD D,0 ;D is the download flag
FLAGIO EQU $-1
;
LD BC,0FBEDH
IN A,(C)
XOR D ;WAIT UNTIL GOT=I
RRCA
JC EXIT
DEC C
IN E,(C) ;GET BYTE
INC C
LD A,D
OUT (C),A ;SET SEND=I
XOR 129
LD D,A ;I=1-I (ready for next byte)
;
LD A,E
SUB 180
JZ DLOAD
DEC A
JZ EXECUTE
DEC A
JZ UPLOAD
DEC A
JZ SBANK
CP 4
JZ ANALYZE
;
EXIT LD A,D
LD (FLAGIO),A
POP HL
POP DE ;Return to your program
POP BC
POP AF
RET
;
; Send PC address back to main computer
;
ANALYZE CALL PORTOUT
LD A,L
CALL SENDA
LD A,H
CALL SENDA
CALL PORTIN
JR EXIT
;
; Execute code from aaaa - does a jump note! (call would be silly from ints)
;
EXECUTE CALL GETA
LD H,E
CALL GETA ;Notice that the address is downloaded H then L
LD L,E
JP (HL)
;
; Download code into aaaa, length=bbbb
;
DLOAD CALL GETA
LD H,E
CALL GETA ;Get start address
LD L,E
CALL GETA
LD B,E
CALL GETA ;Get length of code
LD C,E
DLOAD1 CALL GETA
LD (HL),E ;Get and store code
INC HL
DEC BC
LD A,B
OR C
JNZ DLOAD1
JR EXIT
;
; Upload code, from aaaa, length bbbb
;
UPLOAD CALL GETA
LD H,E
CALL GETA ;Get start address
LD L,E
CALL GETA
LD B,E
CALL GETA ;Get length of code
LD C,E
CALL PORTOUT
$1 LD A,(HL)
CALL SENDA
INC HL ;Send the area of memory
DEC BC
LD A,B
OR C
JNZ $1
CALL PORTIN
JP EXIT
;
; Function 183, select bank xx (This is different for each computer)
;
SBANK CALL GETA
;
; HL, BC and A may be corrupted here
; Please write your own bank changing routine, for example it could just
; be LD BC,nnnn then OUT (C),A. Note that A contains the number of the
; bank, sent from the PDS BANK n command in the assembler
;
JP EXIT
;
; Turn port direction TO main computer
;
PORTOUT PUSH BC
LD BC,0FBEDH
$R IN A,(C)
XOR D
RRCA
JC $R
INC C
LD A,255
OUT (C),A ;This swaps the PDS interface direction around
INC A
OUT (C),A ;The Spectrum now transmitts to the Apricot
LD A,D
XOR 65
LD D,A
POP BC
RET
;
; Turn port direction FROM main computer
;
PORTIN LD A,255
LD BC,0FBEEH
OUT (C),A
OUT (C),A
DEC C
LD A,D
XOR 64 ;Swap the ports round again
OUT (C),A
XOR 128
LD D,A
RET
;
; Get a byte from the APRICOT in E
;
GETA PUSH BC
LD BC,0FBEDH
$1 IN A,(C)
XOR D ;WAIT UNTIL GOT=I
RRCA
JC $1
DEC C
IN E,(C) ;GET BYTE
INC C
LD A,D
OUT (C),A ;SET SEND=I
XOR 129
LD D,A ;I=1-I (ready for next byte)
POP BC
RET
;
; Send A to the APRICOT
;
SENDA PUSH BC
LD BC,0FBECH
OUT (C),A
INC C
LD A,D
OUT (C),A
XOR 129
LD D,A
$1 IN A,(C)
XOR D
RRCA
JNC $1
POP BC
RET
;
;
;
SEND COMPUTER1
END
</pre>
== AMSTRAD.DL0 (short version, 114 bytes) ==
<pre>
; Amstrad short download software
;
;
;Only to be used for assembling and downloading, most monitor functions
;will not opperate with this download software. It has been kept as short
;as possible. Note that the interupts are disabled. This is to prevent
;your own interupt routines crashing if they are overwritten.
;The code is 114 bytes long. It may be ORG'ed anywhere.
;
;
ORG 8000H
;
START LD A,255
LD BC,0FBEEH
OUT (C),A
OUT (C),A
INC C
OUT (C),A ;Initial port setup
LD C,0EDH
OUT (C),A
LD C,0EFH
LD A,63
OUT (C),A
LD D,64 ;Protocol flags to input from main computer
DI
;
; Main loop
;
MAINLOOP CALL GETBYTE ;Get 'command byte'
LD A,E
CP 180 ;Download code into aabb, len=ccdd
JZ DLOAD
CP 183
JZ BANK
CP 181
JNZ MAINLOOP ;If unknown, keep looping
;
; Function 181, Execute code from aabb
;
CALL GETBYTE
LD H,E ;Get address
CALL GETBYTE
LD L,E
LD BC,MAINLOOP ;CALL it.
PUSH BC
JP (HL)
;
; Function 183, Select bank aa
;
BANK CALL GETBYTE
LD B,7FH ;You may write your own routine here.
LD C,E ;You may corrupt everything except E
OUT (C),C ;This allows you to page in rom and ram
JR MAINLOOP
;
; Function 180, Download code into aabb, length=ccdd
;
DLOAD CALL GETBYTE
LD H,E
CALL GETBYTE ;Get start address of code
LD L,E
CALL GETBYTE
LD B,E
CALL GETBYTE ;Get length of code
LD C,E
DLOAD1 CALL GETBYTE
LD (HL),E ;Get and store bytes
INC HL
DEC BC
LD A,B
OR C
JNZ DLOAD1
JR MAINLOOP ;Go back into main download loop
;
; Get a byte from the main computer into E
;
GETBYTE PUSH BC
LD BC,0FBEDH
$1 IN A,(C)
XOR D ;Wait for 'sent the byte'
RRCA
JC $1
DEC C
IN E,(C) ;Get the byte
INC C
LD A,D
OUT (C),A ;Say 'byte received'
XOR 129
LD D,A ;Flip flags ready for next byte
POP BC
RET
;
;
; The end of the PDS download software.
;
; Now is a short routine to return to basic from the ASMSTRAD download
; software supplied with the system. Note that to run the download software
; you must use the following :
;
; LOAD "D" : CALL 40000
;
; When you assemble and download this program you will return to basic, to
; save to disk or tape use the following:
;
; SAVE "DLOAD",B,start address,114,start address
;
; Now it will be saved so it will auto run when RUN "DLOAD is typed.
;
;
ORG START-3
POP HL ;Get rid of return to PDS software
EI
RET ;Start interupts and return
;
;
;
SEND COMPUTER1
END
</pre>
== AMSTRAD.DL1 (long version, 374 bytes) ==
<pre>
; Amstrad long download software
;
;
;This download software can be used for assembling and download, and will
;work with all the monitor functions, such as trace, upload etc...It will
;not work with the Analyze command, which requires the DL2 software.
;Interupts are disabled. Jump to START the first time, this will setup all
;the ports. If you wish to enter the download software again, jump to
;MONITOR. The length of the code is 374 bytes.
;
;
ORG 8000H
;
;
; Initial setup code
;
START PUSH AF
LD A,255
LD BC,0FBEEH
OUT (C),A
OUT (C),A
INC C
OUT (C),A ;Initial port setup
LD C,0EDH
OUT (C),A
LD C,0EFH
LD A,63
OUT (C),A
INC A
LD (FLAGIO),A ;Initial flags 0 - Input
POP AF
;
; Now main part of download software
;
MONITOR DI ;Interupts would corrupt the stack
LD (ZHL),HL ;Save HL
LD (ZSP),SP ;Save SP
POP HL ;Get 'return' address
LD (ZPC),HL ;Where I was called from
LD SP,ZHL ;Top of register block
PUSH DE
PUSH BC
EXX
PUSH HL
PUSH DE
PUSH BC ;All registers are saved for PDS
PUSH IX
PUSH IY
PUSH AF
LD A,I
LD H,A
LD A,R
LD L,A
PUSH HL
EX AF,AF'
PUSH AF
LD D,0 ;D is the download flag
FLAGIO EQU $-1
;
; Mainloop
;
MAINLOOP CALL GETBYTE
LD A,E
CP 180 ;Download code into aabb, len=ccdd
JZ DLOAD
CP 186 ;Run code aa,bb,cc,dd
JP Z,EXECUTE
CP 184 ;Send register block to Apricot
JP Z,SENDREG
CP 185 ;Get register block from Apricot
JP Z,GETREG
CP 183 ;Select bank aa
JZ SBANK
CP 182 ;Upload code from aabb len=ccdd
JZ UPLOAD
CP 181 ;Execute code from aabb?
JNZ MAINLOOP ;Not recognised - keep looping.
;
; Function 181, Execute code from aabb
;
CALL GETBYTE
LD H,E
CALL GETBYTE ;Notice that the address is downloaded H then L
LD L,E
LD (EXEC+2),HL ;Put NOP, CALL <xxxx> into execution buffer
LD HL,0CD00H
LD (EXEC),HL
JP RUNIT
;
; Function 180, Download code into aabb, length=ccdd
;
DLOAD CALL GETBYTE
LD H,E
CALL GETBYTE ;Get start address of code
LD L,E
CALL GETBYTE
LD B,E
CALL GETBYTE ;Get length of code
LD C,E
DLOAD1 CALL GETBYTE
LD (HL),E ;Get and store bytes
INC HL
DEC BC
LD A,B
OR C
JNZ DLOAD1
JR MAINLOOP ;Go back into main download loop
;
; Function 183, select bank aa
;
SBANK CALL GETBYTE
LD B,7FH ;You may write your own routine here.
LD C,E ;You may corrupt everything except E
OUT (C),C ;This allows you to page in rom and ram
JR MAINLOOP
;
; Function 184, upload register block to the main computer.
;
SENDREG LD HL,REGISTERS
LD BC,26
JR UPLOAD1 ;Upload the register block
;
; Function 185, download register block from the main computer.
;
GETREG LD HL,REGISTERS
LD BC,26
JR DLOAD1 ;Download the register block
;
; Upload code, from aabb, length ccdd
;
UPLOAD CALL GETBYTE
LD H,E
CALL GETBYTE ;Get start address of code
LD L,E
CALL GETBYTE
LD B,E
CALL GETBYTE ;Get length of code
LD C,E
;
UPLOAD1 PUSH BC
LD BC,0FBEDH
$0 IN A,(C)
XOR D
RRCA
JC $0
INC C
LD A,255
OUT (C),A ;This swaps the PDS interface direction around
INC A
OUT (C),A ;The Amstrad now transmitts to the Apricot
LD A,D
XOR 65
LD D,A
POP BC
;
$1 LD A,(HL)
CALL SENDBYTE
INC HL ;Send the area of memory
DEC BC
LD A,B
OR C
JNZ $1
;
DEC A
LD BC,0FBEEH
OUT (C),A
OUT (C),A
DEC C
LD A,D
XOR 64 ;Swap the ports back to normal
OUT (C),A
XOR 128
LD D,A
;
JP MAINLOOP
;
; Function 186, execute the next 4 bytes, and reenter monitor
;
EXECUTE CALL GETBYTE
LD L,E
CALL GETBYTE
LD H,E
LD (EXEC),HL
CALL GETBYTE ;Get the 4 bytes to be run
LD L,E
CALL GETBYTE ;Store in execution buffer
LD H,E
LD (EXEC+2),HL
RUNIT LD A,D
LD (FLAGIO),A
POP AF
EX AF,AF'
POP HL
LD A,H
LD I,A
LD A,L
LD R,A
POP AF
POP IY
POP IX ;Get all registers off stack
POP BC
POP DE
POP HL
EXX
POP BC
POP DE
POP HL
LD SP,(ZSP)
EXEC DS 4 ;All code to be run is placed here
JP MONITOR
;
; Get a byte from the main computer into E
;
GETBYTE PUSH BC
LD BC,0FBEDH
$1 IN A,(C)
XOR D ;Wait for 'sent byte'
RRCA
JC $1
DEC C
IN E,(C) ;Get the byte
INC C
LD A,D
OUT (C),A ;Set 'byte received'
XOR 129
LD D,A ;Flip flags for next byte
POP BC
RET
;
; Send A to the main computer
;
SENDBYTE PUSH BC
LD BC,0FBECH
OUT (C),A ;Send the byte
INC C
LD A,D
OUT (C),A ;Set 'sent the byte'
XOR 129
LD D,A
$1 IN A,(C)
XOR D ;Wait for 'byte received'
RRCA
JNC $1
POP BC
RET
;
DW 0,0 ;Uses two levels of stack
REGISTERS DS 20 ;Other registers stored here
ZHL DW 0 ;HL stored here
ZPC DW 0 ;PC stored here
ZSP DW 0 ;SP stored here
;
;
;
; The end of the PDS download software.
;
; Now is a short routine to return to basic from the ASMSTRAD download
; software supplied with the system. Note that to run the download software
; you must use the following :
;
; LOAD "D" : CALL 40000
;
; When you assemble and download this program you will return to basic, to
; save to disk or tape use the following:
;
; SAVE "DLOAD",B,start address,374,start address
;
; Now it will be saved so it will auto run when RUN "DLOAD is typed.
;
;
ORG START-3
EXEC $
EI
POP HL
RET
;
;
;
SEND COMPUTER1
END
</pre>
== AMSTRAD.DL2 (interrupt driven) ==
<pre>
; This is the interupt driven download software for the Amstrad
;
; To use this software, insert a CALL to the routine PDSSETUP in the
; 'cold start' or 'once only' part of your program. Also insert a CALL
; to the routine MONITOR in your interupt routine. PDS corrupts HL,DE,BC
; and AF. The call to monitor must have HL containing the address where
; the interupt occured.
; You will now be able to use most of the monitor functions while your
; program is running and interupts enabled. Note that you cannot alter
; the registers or trace as this would not make sense under the interupts.
; The analyze command will also opperate now.
;
; Note that if you try and download programs, containing the PDS download
; software, chances are that you will crash the system as the download
; software contains self modifiying code that would get overwritten.
; To download programs just make sure you never download over the
; download software currently running.
;
; Below is the PDS download software and a short program that sets up the
; amstrad and returns you to basic, so you may modify memory while you
; are running basic programs.
; To run this, use the download software disk supplied and type :
;
; LOAD "D
; CALL 40000
;
; If you had used RUN"D you would not have been able to return to basic
; Now you can download the program
;
;
;
ORG 39000
EXEC $
;
; Setup interupts and return to basic
;
CALL PDSSETUP ;Initialize PDS software
DI
LD HL,(39H)
LD (INTEND+1),HL ;Redirect interupt vector
LD HL,INTR
LD (39H),HL
EI
POP HL ;Remove PDS return to download software address
RET
;
; End of example program
;
;
;
;
; Now the main PDS download software routines
;
;
; Initial setup code - only called once.
;
PDSSETUP LD A,255
LD BC,0FBEEH
OUT (C),A
OUT (C),A
INC C
OUT (C),A ;Initial port setup
LD C,0EDH
OUT (C),A
LD C,0EFH
LD A,63
OUT (C),A
INC A
LD (FLAGIO),A ;Initial protocol flags, input
RET
;
; An example interupt routine
;
INTR LD (STKSTO+1),SP
PUSH HL
PUSH DE
STKSTO LD HL,1
LD E,(HL)
INC HL ;Get HL=old PC address
LD D,(HL)
EX DE,HL
CALL MONITOR ;Do download software
POP DE
POP HL ;Now go back into AMSTRAD routines
INTEND JP 1
;
;
; Call this address from your interupt routine
;
MONITOR PUSH AF
PUSH BC ;Save all regs from your program
PUSH DE
PUSH HL
LD D,0 ;D is the download flag
FLAGIO EQU $-1
;
LD BC,0FBEDH
IN A,(C)
XOR D ;WAIT UNTIL GOT=I
RRCA
JC EXIT
DEC C
IN E,(C) ;GET BYTE
INC C
LD A,D
OUT (C),A ;SET SEND=I
XOR 129
LD D,A ;I=1-I (ready for next byte)
;
LD A,E
SUB 180
JZ DLOAD
DEC A
JZ EXECUTE
DEC A
JZ UPLOAD
DEC A
JZ SBANK
CP 4
JZ ANALYZE
;
EXIT LD A,D
LD (FLAGIO),A
POP HL
POP DE ;Return to your program
POP BC
POP AF
RET
;
; Send PC address back to main computer
;
ANALYZE CALL PORTOUT
LD A,L
CALL SENDA
LD A,H
CALL SENDA
CALL PORTIN
JR EXIT
;
; Execute code from aaaa - does a jump note! (call would be silly from ints)
;
EXECUTE CALL GETA
LD H,E
CALL GETA ;Notice that the address is downloaded H then L
LD L,E
JP (HL)
;
; Download code into aaaa, length=bbbb
;
DLOAD CALL GETA
LD H,E
CALL GETA ;Get start address
LD L,E
CALL GETA
LD B,E
CALL GETA ;Get length of code
LD C,E
DLOAD1 CALL GETA
LD (HL),E ;Get and store code
INC HL
DEC BC
LD A,B
OR C
JNZ DLOAD1
JR EXIT
;
; Upload code, from aaaa, length bbbb
;
UPLOAD CALL GETA
LD H,E
CALL GETA ;Get start address
LD L,E
CALL GETA
LD B,E
CALL GETA ;Get length of code
LD C,E
CALL PORTOUT
$1 LD A,(HL)
CALL SENDA
INC HL ;Send the area of memory
DEC BC
LD A,B
OR C
JNZ $1
CALL PORTIN
JP EXIT
;
; Function 183, select bank xx (This is different for each computer)
;
SBANK CALL GETA
;
; HL, BC and A may be corrupted here
; Please write your own bank changing routine, for example it could just
; be LD BC,nnnn then OUT (C),A. Note that A contains the number of the
; bank, sent from the PDS BANK n command in the assembler
;
JP EXIT
;
; Turn port direction TO main computer
;
PORTOUT PUSH BC
LD BC,0FBEDH
$R IN A,(C)
XOR D
RRCA
JC $R
INC C
LD A,255
OUT (C),A ;This swaps the PDS interface direction around
INC A
OUT (C),A ;The Spectrum now transmitts to the Apricot
LD A,D
XOR 65
LD D,A
POP BC
RET
;
; Turn port direction FROM main computer
;
PORTIN LD A,255
LD BC,0FBEEH
OUT (C),A
OUT (C),A
DEC C
LD A,D
XOR 64 ;Swap the ports round again
OUT (C),A
XOR 128
LD D,A
RET
;
; Get a byte from the APRICOT in E
;
GETA PUSH BC
LD BC,0FBEDH
$1 IN A,(C)
XOR D ;WAIT UNTIL GOT=I
RRCA
JC $1
DEC C
IN E,(C) ;GET BYTE
INC C
LD A,D
OUT (C),A ;SET SEND=I
XOR 129
LD D,A ;I=1-I (ready for next byte)
POP BC
RET
;
; Send A to the APRICOT
;
SENDA PUSH BC
LD BC,0FBECH
OUT (C),A
INC C
LD A,D
OUT (C),A
XOR 129
LD D,A
$1 IN A,(C)
XOR D
RRCA
JNC $1
POP BC
RET
;
;
;
SEND COMPUTER1
END
</pre>