Yours Sincerely,
Mr. Emmanuel Roche, France
A>mallard /m:&HAFFF
Mallard-86 BASIC with Jetsam Version 1.50
(c) Copyright 1984 Locomotive Software Ltd
All rights reserved
42025 free bytes
load"rtc
Ok
list
10 REM Real-Time Clock (RTC)
20 REM by Simon Payne
30 REM "Amstrad Action", October 1988
40 REM Seconds are stored at 9C40H
50 REM Minutes are stored at 9C41H
60 REM Hours are stored at 9C42H
70 mode 1
80 ln = 180
90 FOR adr = &H8000 TO &H809F STEP 13
100 READ byte$ : chk = 0
110 FOR i = 0 TO 12
120 v = VAL ("&H" + MID$ (byte$, i * 2 + 1, 2))
130 POKE adr + i, v : chk = chk + v
140 NEXT i
150 locate 10, 10 : PRINT "Checking line " ; ln
160 IF chk <> VAL ("&H" + RIGHT$ (byte$, 3)) THEN PRINT
"Error in line:" ; ln : STOP
170 ln = ln + 10 : NEXT
180 DATA 21A2800681111D80C3EFBC219C5A3
190 DATA 80113200013200C3E9BC219C8049B
200 DATA C3ECBC3A409C3CFE3CCC2D80326A2
210 DATA 409CCD5680C93A419C3CFE3CCC6A1
220 DATA 3F8032419C3E0032409CC93A4245F
230 DATA 9C3CFE18CC000032429C3E003243A
240 DATA 419C3E07CD5ABBC93E06CD1EBB5B7
250 DATA C83A429CCD83803E3ACD5ABB3A644
260 DATA 419CCD83803E3ACD5ABB3A409C61D
270 DATA CD83803E07CD5ABB3E0DCD5ABB624
280 DATA C9160ACD8A8016010E009238033B2
290 DATA 0C18FA82F579C630CD5ABBF1C97A0
300 DATA 00000000000000000000000000000
310 CALL &H8000 : CALL &H800B
320 mode 1 : INPUT "Enter Hour:" ; h : POKE 40002!, h
330 INPUT "Enter Min:" ; h : POKE 40001!, h
340 INPUT "Enter sec:" ; h : POKE 4000, h
350 mode 1 : PRINT "Time set. Press the small ENTER key to see the
time."
Ok
run
Checking line 180
Checking line 190
Checking line 200
Checking line 210
Checking line 220
Checking line 230
Checking line 240
Checking line 250
Checking line 260
Checking line 270
Checking line 280
Checking line 290
Checking line 300
Enter Hour:?
Break in 320
Ok
135 PRINT HEX$ (v, 2) " " ;
Ok
run
21 A2 80 06 81 11 1D 80 C3 EF BC 21 9C Checking line 180
80 11 32 00 01 32 00 C3 E9 BC 21 9C 80 Checking line 190
C3 EC BC 3A 40 9C 3C FE 3C CC 2D 80 32 Checking line 200
40 9C CD 56 80 C9 3A 41 9C 3C FE 3C CC Checking line 210
3F 80 32 41 9C 3E 00 32 40 9C C9 3A 42 Checking line 220
9C 3C FE 18 CC 00 00 32 42 9C 3E 00 32 Checking line 230
41 9C 3E 07 CD 5A BB C9 3E 06 CD 1E BB Checking line 240
C8 3A 42 9C CD 83 80 3E 3A CD 5A BB 3A Checking line 250
41 9C CD 83 80 3E 3A CD 5A BB 3A 40 9C Checking line 260
CD 83 80 3E 07 CD 5A BB 3E 0D CD 5A BB Checking line 270
C9 16 0A CD 8A 80 16 01 0E 00 92 38 03 Checking line 280
0C 18 FA 82 F5 79 C6 30 CD 5A BB F1 C9 Checking line 290
00 00 00 00 00 00 00 00 00 00 00 00 00 Checking line 300
Enter Hour:?
Break in 320
Ok
run"savehex
SAVEHEX> Enter Intel HEX File Name: ? rtc
Start address (HEX without H): ? B000
End address (HEX without H): ? B0A8
RTC.HEX
-------
Documentation ? RTC for Amstrad CPC-6128
Documentation ?
:10B0000021A2800681111D80C3EFBC219C801132DA !..........!...2
:10B0100000013200C3E9BC219C80C3ECBC3A409CD7 ..2....!.....:@.
:10B020003CFE3CCC2D8032409CCD5680C93A419CA0 <.<.-.2@..V..:A.
:10B030003CFE3CCC3F8032419C3E0032409CC93AB1 <.<.?.2A.>.2@..:
:10B04000429C3CFE18CC000032429C3E0032419CA7 B.<.....2B.>.2A.
:10B050003E07CD5ABBC93E06CD1EBBC83A429CCD69 >..Z..>.....:B..
:10B0600083803E3ACD5ABB3A419CCD83803E3ACD57 ..>:.Z.:A....>:.
:10B070005ABB3A409CCD83803E07CD5ABB3E0DCD96 Z.:@....>..Z.>..
:10B080005ABBC9160ACD8A8016010E009238030CED Z............8..
:10B0900018FA82F579C630CD5ABBF1C9000000001C ....y.0.Z.......
:09B0A000000000000000000000A7 .........
:0000000000
First address: B000
Last address: B0A8
Bytes read: 00A9
Records read: 01
Ok
system
A>
(Reload HEX file with SID, save it in binary, then disassemble with
Good Old CP/M disassembler.)
; RTC6128.MAC
; -----------
;
; Amstrad CPC-6128 -- RTC6128
;
; Disassembled by:
;
; Mr. Emmanuel ROCHE
; Chemin de Boisrond
; 17430 Tonnay-Charente
; FRANCE
;
;--------------------------------
.Z80
ORG 8000H
;--------------------------------
C$0000 EQU 0000H ; -C---
D.9C40 EQU 9C40H ; --SL-
D.9C41 EQU 9C41H ; --SL-
D.9C42 EQU 9C42H ; --SL-
C$BB1E EQU 0BB1EH ; -C---
C.BB5A EQU 0BB5AH ; -C---
J$BCE9 EQU 0BCE9H ; J----
J$BCEC EQU 0BCECH ; J----
J$BCEF EQU 0BCEFH ; J----
;--------------------------------
C8000:
LD HL,I$80A2
LD B,81H
LD DE,I$801D
JP J$BCEF
;--------------------------------
C800B:
LD HL,I.809C
LD DE,0032H
LD BC,0032H
JP J$BCE9
;--------------------------------
C8117:
LD HL,I.809C
JP J$BCEC
;--------------------------------
I$801D:
LD A,(D.9C40)
INC A
CP 3CH ; "<"
CALL Z,C$802D
;
LD (D.9C40),A
CALL C$8056
;
RET
;--------------------------------
C$802D:
LD A,(D.9C41)
INC A
CP 3CH ; "<"
CALL Z,C$803F
;
LD (D.9C41),A
LD A,00H
LD (D.9C40),A
RET
;--------------------------------
C$803F:
LD A,(D.9C42)
INC A
CP 18H
CALL Z,C$0000
;
LD (D.9C42),A
LD A,00H
LD (D.9C41),A
LD A,07H ; 7
CALL C.BB5A
;
RET
;--------------------------------
C$8056:
LD A,06H ; 6
CALL C$BB1E
;
RET Z
;
LD A,(D.9C42)
CALL C.8083
;
LD A,3AH ; ":"
CALL C.BB5A
;
LD A,(D.9C41)
CALL C.8083
;
LD A,3AH ; ":"
CALL C.BB5A
;
LD A,(D.9C40)
CALL C.8083
;
LD A,07H ; 7
CALL C.BB5A
;
LD A,0DH ; 13
CALL C.BB5A
;
RET
;--------------------------------
C.8083:
LD D,0AH ; 10
CALL C$808A
;
LD D,01H ; 1
C$808A:
LD C,00H
J$018C:
SUB D
JR C,J$0192
;
INC C
JR J$018C
;
J$0192:
ADD A,D
PUSH AF
LD A,C
ADD A,30H ; "0"
CALL C.BB5A
;
POP AF
RET
;--------------------------------
I.809C:
db 0
db 0
db 0
db 0
db 0
db 0
I$80A2:
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
;--------------------------------
END
> This week, while searching for something else, I saw a mention of one
> "RTC" (Real-Time Clock) for the Amstrad CPC-6128 in an old "Amstrad
> Action" magazine, dated October 1988. I am missing an RTC for the
> Amstrad PCW-8256 so, since the listing was so small, photocopied the
> page. This morning, I retyped it and disassembled it... but the
> problem is that it contains (probably) calls to ROM subroutines of the
> CPC, so I have no idea what it does. Is anybody out there who could
> explain what those ROM subroutines are doing?
Without stopping to analyse the code, I can tell you that certainly all the
calls to addresses in the &BXXX range are to firmware routines in the CPC.
There is nothing to correspond to them in the PCW.
Since the CPC did not have a RTC chip as standard, there is no standard
interface to it. Possibly a de-facto standard would be the interface to the
DK-Tronics RTC module which used a Z80-PIO chip to address the RTC itself
as Port A of the PIO, with a 9-pin user i/o port as Port B.
Access to the unit then required special software to be written to access
the PIO at its correct I/O addresses and perform appropriate actions, e.g.
show a running time display using a synchronous event polled from Basic.
--
ξ:) Proud to be curly
Interchange the alphabetic letter groups to reply
> ... but the
> problem is that it contains (probably) calls to ROM subroutines of the
> CPC, so I have no idea what it does. Is anybody out there who could
> explain what those ROM subroutines are doing?
There is a CPC firmware manual on my website at
http://www.cantrell.org.uk/david/tech/cpc/
--
David Cantrell | http://www.cantrell.org.uk/david
If I could read only one thing it would be the future, in the
entrails of the bastard denying me access to anything else.
> There is a CPC firmware manual on my website
>
> http://www.cantrell.org.uk/david/tech/cpc/
Many thanks. So,
BB1E = Km Test Key
BB5A = TXT Output
BCE9 = KL Add Ticker
BCEC = KL Del Ticker
BCEF = KL Init Ticker
I tried to save the explanations of those subroutines, but the "Copy
to Clipboard" menu is grey, not black. I am afraid that I will be
obliged to retype them by hand.
(According to Google, you posted 119,084 messages dealing with Perl!
Incredible! This must be a record. And only 94 on the comp.sys.amstrad.
8bit Newsgroup. So, I was lucky that you happened to read my message.)
> I tried to save the explanations of those subroutines, but the "Copy
> to Clipboard" menu is grey, not black. I am afraid that I will be
> obliged to retype them by hand.
I saw that the text was available online. I cut and pasted all the
explanations of the subroutines used. Will work on it tomorrow.
Please find below the disassembly of RTC6128.
As you can see, I re-used everything that I found on your Web site.
Since this is the first time that I disassemble a CPC-6128 program,
some things remain mysterious for me.
1) Is 9C40H the top of the TPA?
2) What is the structure of this mysterious "event block"?
3) I guessed how worked the Display$BCD routine. Me, when displaying
the time in the SCB of CP/M Plus, I simply use HEX$. I trust the value
to be legal.
So, this program polls the ENTER key. If pressed, it displays the time
on screen. Since I have no Amstrad CPC-6128, this is all I can say.
Yours Sincerely,
Mr. Emmanuel Roche, France
; RTC6128.MAC
; -----------
;
; Amstrad CPC-6128 -- RTC6128
;
; - "Real Time Clock"
; "Amstrad Action" Magazine
; Simon Payne
; October 1988, pp.54-55
;
; Disassembled by:
;
; Mr. Emmanuel ROCHE
; Chemin de Boisrond
; 17430 Tonnay-Charente
; FRANCE
;
;--------------------------------
.Z80
ORG 8000H
;--------------------------------
; ASCII characters used.
BEL EQU 07H
CR EQU 0DH
Sep EQU 3AH ; ":"
;--------------------------------
; Fields used in RAM.
Seconds EQU 9C40H
Minutes EQU 9C41H
Hours EQU 9C42H
;--------------------------------
; Firmware subroutine used.
System$Reset EQU 0000H
KM$Test$Key EQU 0BB1EH
TXT$Output EQU 0BB5AH
KL$Add$Ticker EQU 0BCE9H
KL$Del$Ticker EQU 0BCECH
KL$Init$Event EQU 0BCEFH
;--------------------------------
Init$Event:
; Action
; Initialises an event block.
;
; Entry
; HL contains the address of the event block (in the central
; 32K of RAM), B contains the class of event, and C contains
; the ROM select address, and DE holds the address of the event
; routine.
;
; Exit
; HL holds the address of the event block+7, and all other
; registers are preserved.
;
; Notes
; The event class is derived as follows:
;
; bit 0 - indicates a near address
; bits 1 to 4 - hold the synchronous event priority
; bit 5 - always zero
; bit 6 - if bit 6 is set, then it is an express event
; bit 7 - if bit 7 is set, then it is an asynchronous event.
;
; Asynchronous events do not have priorities; if it is an
; express asynchronous event, then its event routine is called
; from the interrupt path; if it is a normal asynchronous event,
; then its event routine is called just before returning from
; the interrupt; if it is an express synchronous event, then
; it has a higher priority than normal synchronous events, and
; it may not be disabled through use of KL EVENT DISABLE;
; if the 'near address bit' is set, then the routine is located
; in the central 32K of RAM and is called directly, so saving
; time; no event may have a priority of zero.
LD HL,Event$Block+7 ; Event block
LD B,10000001B
; ||||||||
; |||||||+--> Bit 0: Near address
; ||||||+---> Bit 1:
; |||||+----> Bit 2:
; ||||+-----> Bit 3:
; |||+------> Bit 4:
; ||+-------> Bit 5:
; |+--------> Bit 6:
; +---------> Bit 7: Asynchronous event
LD DE,Update$Seconds ; Event routine
JP KL$Init$Event
;--------------------------------
Add$Ticker:
; Action
; Sets up a ticker event block which will be run whenever a
; 1/50th second ticker interrupt occurs.
;
; Entry
; HL contains the address of the event block (in the central
; 32K of RAM), DE contains the initial value for the counter,
; and BC holds the value that the counter will be given
; whenever it reaches zero.
;
; Exit
; AF, BC, DE and HL are corrupt, and all the other registers are
preserved.
LD HL,Event$Block
LD DE,50 ; Initial value of counter
LD BC,50 ; Rollover value
JP KL$Add$Ticker
;--------------------------------
Del$Ticker:
; Action
; Removes a ticker event block from the list of routines that
; are run when a l/50th second ticker interrupt occurs.
;
; Entry
; HL contains the address of the event block.
;
; Exit
; If the event block was found, then Carry is true,
; and DE holds the value remaining of the counter;
; if the event block was not found, then Carry is false,
; and DE is corrupt. In both cases, A, HL and the other
; flags are corrupt, and all other registers are preserved.
LD HL,Event$Block
JP KL$Del$Ticker
;--------------------------------
Update$Seconds:
LD A,(Seconds)
INC A
CP 60
CALL Z,Update$Minutes
LD (Seconds),A
CALL Poll$ENTER$Key ; Check if user wants to see time
RET
;--------------------------------
Update$Minutes:
LD A,(Minutes)
INC A
CP 60
CALL Z,Update$Hours
LD (Minutes),A
LD A,00H
LD (Seconds),A
RET
;--------------------------------
Update$Hours:
LD A,(Hours)
INC A
CP 24
CALL Z,System$Reset
LD (Hours),A
LD A,00H
LD (Minutes),A
LD A,BEL ; Beeps every hour
CALL TXT$Output
RET
;--------------------------------
Poll$ENTER$Key:
; Action
; Tests if a particular key (or joystick direction,
; or button) is pressed.
;
; Entry
; A contains the key/joystick number.
;
; Exit
; If the requested key is pressed, then Zero is False;
; otherwise, Zero is True for both, Carry is false,
; A and HL are corrupt. C holds the Shift and Control
; status. Others registers are preserved.
;
; Notes
; After calling this, C will hold the state of shift
; and control -- if bit 7 is set then Control was pressed;
; if bit 5 is set then Shift was pressed.
LD A,6 ; ENTER key?
CALL KM$Test$Key
RET Z ; No: Loop
LD A,(Hours) ; Yes: Display time
CALL Display$2$BCD
LD A,Sep
CALL TXT$Output
LD A,(Minutes)
CALL Display$2$BCD
LD A,Sep
CALL TXT$Output
LD A,(Seconds)
CALL Display$2$BCD
LD A,BEL ; Beeps
CALL TXT$Output
LD A,CR ; Ends 12:34:56
CALL TXT$Output
RET
;--------------------------------
Display$2$BCD:
LD D,10
CALL Display$1$BCD
LD D,1
Display$1$BCD:
LD C,0
Display$BCD:
SUB D
JR C,Display$Number
INC C
JR Display$BCD
Display$Number:
ADD A,D
PUSH AF
LD A,C
ADD A,'0' ; Convert to ASCII number
CALL TXT$Output
POP AF
RET
;--------------------------------
Event$Block:
> Hello, David!
> Please find below the disassembly of RTC6128.
>
> As you can see, I re-used everything that I found on your Web site.
> Since this is the first time that I disassemble a CPC-6128 program,
> some things remain mysterious for me.
> 1) Is 9C40H the top of the TPA?
> 2) What is the structure of this mysterious "event block"?
Perhaps you should try reading the rest of the firmware manual. IIRC it
includes a memory map.
--
David Cantrell | A machine for turning tea into grumpiness
EINE KIRCHE! EIN KREDO! EIN PAPST!