mirror of https://github.com/wwarthen/RomWBW.git
committed by
GitHub
34 changed files with 2599 additions and 833 deletions
@ -0,0 +1,15 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set TOOLS=../../../Tools |
|||
set PATH=%TOOLS%\tasm32;%PATH% |
|||
set TASMTABS=%TOOLS%\tasm32 |
|||
|
|||
tasm -t180 -g3 -fFF i2cscan.asm i2cscan.com i2cscan.lst |
|||
tasm -t180 -g3 -fFF rtcds7.asm rtcds7.com rtcds7.lst |
|||
tasm -t180 -g3 -fFF i2clcd.asm i2clcd.com i2clcd.lst |
|||
|
|||
if errorlevel 1 goto :eof |
|||
|
|||
copy /Y i2c*.com ..\..\..\Binary\Apps\ |
|||
copy /Y rtcds7*.com ..\..\..\Binary\Apps\ |
|||
@ -0,0 +1,5 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
if exist *.com del *.com |
|||
if exist *.lst del *.lst |
|||
@ -0,0 +1,21 @@ |
|||
OBJECTS = i2cscan.com, rtcds7.com, i2clcd.com |
|||
DEST = ../../../Binary/Apps |
|||
TOOLS = ../../../Tools |
|||
|
|||
include $(TOOLS)/Makefile.inc |
|||
|
|||
DEPS1 := i2cscan.asm $(shell find . -name '*.inc') |
|||
DEPS2 := rtcds7.asm $(shell find . -name '*.inc') |
|||
DEPS3 := i2clcd.asm $(shell find . -name '*.inc') |
|||
|
|||
|
|||
i2cscan.com: $(DEPS1) |
|||
$(TASM) -dWBW i2cscan.asm i2cscan.com i2cscan.lst |
|||
|
|||
rtcds7.com: $(DEPS2) |
|||
$(TASM) -dWBW rtcds7.asm rtcds7.com rtcds7.lst |
|||
|
|||
i2clcd.com: $(DEPS3) |
|||
$(TASM) -dWBW i2clcd.asm i2clcd.com i2clcd.lst |
|||
|
|||
|
|||
@ -0,0 +1,132 @@ |
|||
;================================================================================================== |
|||
; GENERIC CP/M ROUTINES |
|||
;================================================================================================== |
|||
; |
|||
BDOS .EQU 5 ;ENTRY BDOS |
|||
BS .EQU 8 ;BACKSPACE |
|||
TAB .EQU 9 ;TABULATOR |
|||
LF .EQU 0AH ;LINE-FEED |
|||
CR .EQU 0DH ;CARRIAGE-RETURN |
|||
; |
|||
CLIARGS .EQU $81 |
|||
RESTART .EQU $0000 ; CP/M restart vector |
|||
FCB .EQU $5C ; Location of default FCB |
|||
; |
|||
; OUTPUT TEXT AT HL |
|||
; |
|||
PRTSTR: LD A,(HL) |
|||
CP '$' |
|||
RET Z |
|||
CALL COUT |
|||
INC HL |
|||
JR PRTSTR |
|||
; |
|||
;Output WORD |
|||
;*********** |
|||
; |
|||
;PARAMETER: Entry WORD IN HL |
|||
;********* |
|||
; |
|||
OUTW: LD A,H |
|||
CALL OUTB |
|||
LD A,L |
|||
CALL OUTB |
|||
RET |
|||
; |
|||
;Output BYTE |
|||
;*********** |
|||
; |
|||
;PARAMETER: Entry BYTE IN A |
|||
;********* |
|||
; |
|||
OUTB: PUSH AF |
|||
RRCA |
|||
RRCA |
|||
RRCA |
|||
RRCA |
|||
AND 0FH |
|||
CALL HBTHE ;Change Half-BYTE |
|||
POP AF |
|||
AND 0FH |
|||
CALL HBTHE |
|||
RET |
|||
; |
|||
;Output HALF-BYTE |
|||
;**************** |
|||
; |
|||
;PARAMETER: Entry Half-BYTE IN A (BIT 0 - 3) |
|||
;********* |
|||
; |
|||
HBTHE: CP 0AH |
|||
JR C,HBTHE1 |
|||
ADD A,7 ;Character to Letter |
|||
HBTHE1: ADD A,30H |
|||
LD E,A |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
; |
|||
;Output on Screen |
|||
;**************** |
|||
; |
|||
PRBS: LD E,BS |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
;Output CR+LF on Screen |
|||
;********************** |
|||
; |
|||
NEWLINE: |
|||
LD E,CR |
|||
CALL PCHAR |
|||
LD E,LF |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
;Output ASCII-Character |
|||
;********************** |
|||
; |
|||
COUT: PUSH AF |
|||
LD E,A |
|||
CALL PCHAR |
|||
POP AF |
|||
RET |
|||
; |
|||
;CALL BDOS with Register Save |
|||
;**************************** |
|||
; |
|||
INCHA: LD C,1 ;INPUT CHARACTER TO A |
|||
JR BDO |
|||
PCHAR: LD C,2 ;PRINT CHARACTER IN E |
|||
JR BDO |
|||
PSTRIN: LD C,9 ;PRINT STRING |
|||
JR BDO |
|||
INBUFF: LD C,10 ;READ CONSOLE-BUFFER |
|||
JR BDO |
|||
CSTS: LD C,11 ;CONSOLE-STATUS |
|||
JR BDO |
|||
OPEN: LD C,15 ;OPEN FILE |
|||
JR BDO |
|||
CLOSE: LD C,16 ;CLOSE FILE |
|||
JR BDO |
|||
DELETE: LD C,19 ;DELETE FILE |
|||
JR BDO |
|||
READS: LD C,20 ;READ SEEK |
|||
JR BDO |
|||
WRITES: LD C,21 ;WRITE SEEK |
|||
JR BDO |
|||
MAKE: LD C,22 ;MAKE FILE |
|||
JR BDO |
|||
SETDMA: LD C,26 ;SET DMA-ADDRESS |
|||
BDO: PUSH HL |
|||
PUSH DE |
|||
PUSH BC |
|||
PUSH IX |
|||
PUSH IY |
|||
CALL BDOS |
|||
POP IY |
|||
POP IX |
|||
POP BC |
|||
POP DE |
|||
POP HL |
|||
RET |
|||
@ -0,0 +1,517 @@ |
|||
;================================================================================================== |
|||
; PCF8584 HD44780 I2C LCD UTILITY |
|||
; |
|||
; SOME GENERAL INFORMATION ON LCDS CAN BE SEEN HERE : FOCUSLCDS.COM/PRODUCT-CATEGORY/CHARACTER-LCD/ |
|||
; |
|||
;================================================================================================== |
|||
; |
|||
.ECHO "i2clcd\n" |
|||
; |
|||
#INCLUDE "pcfi2c.inc" |
|||
; |
|||
; LCD COMMANDS |
|||
; |
|||
LCDFSET .EQU 00100000B ; 20H |
|||
LCD4BIT .EQU 00000000B ; 00H |
|||
LCD2LIN .EQU 00001000B ; 08H |
|||
LCDDON .EQU 00000100B ; 04H |
|||
LCDDMOV .EQU 00001000B ; 07H |
|||
LCDSGRA .EQU 01000000B ; 04H |
|||
LCDSDRA .EQU 10000000B ; 80H |
|||
LCDEMS .EQU 00000100B ; 04H |
|||
LCDELFT .EQU 00000010B ; 03H |
|||
; |
|||
LCDPINE .EQU 00000100B ; PIN 2 |
|||
LCDPIND .EQU 00000001B ; PIN O |
|||
; |
|||
; |
|||
; STANDARD FORMATS - 8X1, 8X2, 16X1, 16X2, 16X4, 20X1, 20X2, 20X4, 24X2, 40X1, 40X2, 40X4 |
|||
; |
|||
TIMEOUT .EQU 255 |
|||
|
|||
.ORG 100H |
|||
|
|||
;INIT: CALL PCF_INIT |
|||
; |
|||
LD A,0 |
|||
LD (DEBUGF),A |
|||
; |
|||
CALL LCDINIT ; SETUP THE LCD THROUGH THE PCF8574 |
|||
|
|||
LD HL,LCDDATA ; DISPLAY TEXT AT HL |
|||
PUSH HL |
|||
CALL LCDSTR |
|||
POP HL |
|||
|
|||
CALL STOP ; CLOSE I2C CONNECTION |
|||
; |
|||
RET |
|||
|
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
LCDLITE .DB 00001000B |
|||
; |
|||
LCDINIT: |
|||
; CALL DEBUG |
|||
; |
|||
LD A,I2CLCDW ; SET SLAVE ADDRESS |
|||
OUT (REGS0),A |
|||
; |
|||
LD A,0C5H ; GENERATE START CONDITION |
|||
OUT (REGS1),A ; AND ISSUE THE SLAVE ADDRESS |
|||
CALL CHKPIN |
|||
; |
|||
; CALL DEBUG |
|||
; |
|||
LD HL,LCDINIT1 |
|||
LD B,2 |
|||
CALL WLN |
|||
; |
|||
CALL DELAY |
|||
; |
|||
LD HL,LCDINIT2 |
|||
LD B,2 |
|||
CALL WLN |
|||
; |
|||
CALL DELAY |
|||
; |
|||
; NOW WE ARE IN 4 BIT MODE |
|||
; |
|||
LD A,+(LCDFSET | LCD4BIT | LCD2LIN) |
|||
CALL LCDCMD |
|||
LD A,+(LCDDON | LCDDMOV) |
|||
CALL LCDCMD |
|||
LD A,+(LCDEMS | LCDELFT) |
|||
CALL LCDCMD |
|||
LD A,LCDSDRA |
|||
CALL LCDCMD |
|||
; |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
WLN: LD A,(HL) |
|||
OUT (REGS0),A ; PUT DATA ON BUS |
|||
CALL CHKPIN |
|||
INC HL |
|||
DJNZ WLN |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; DISPLAY STRING AT HL, TERMINATED BY 0 |
|||
; |
|||
LCDSTR: POP BC ; GET THE POINTER OF |
|||
POP HL ; THE TEXT TO DISPLAY |
|||
PUSH HL ; OFF THE STACK AND |
|||
PUSH BC ; PUT IT IN HL. |
|||
; |
|||
LCDST0: LD A,(HL) ; GET NEXT CHARACTER TO |
|||
OR A ; DISPLAY BUT RETURN |
|||
RET Z ; WHEN TERMINATOR REACHED |
|||
PUSH HL |
|||
; |
|||
CALL LCDATA ; OUTPUT TO LCD |
|||
POP HL |
|||
; RET C ; POINT TO NEXT |
|||
INC HL ; AND REPEAT |
|||
JR LCDST0 |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; SEND BYTE IN A TO LCD IN 4-BIT MODE |
|||
; |
|||
LCDATA: PUSH DE |
|||
LD D,A |
|||
LD A,(LCDLITE) |
|||
OR +(LCDPINE | LCDPIND) |
|||
JP LCDSND |
|||
LCDCMD: PUSH DE |
|||
LD D,A |
|||
LD A,(LCDLITE) |
|||
OR LCDPINE |
|||
LCDSND: LD E,A |
|||
LD A,D |
|||
PUSH BC |
|||
LD C,11110000B |
|||
AND C |
|||
OR E |
|||
LD (LCDBUF),A |
|||
AND ~LCDPINE |
|||
LD (LCDBUF+1),A |
|||
LD A,D |
|||
RLC A |
|||
RLC A |
|||
RLC A |
|||
RLC A |
|||
AND C |
|||
OR E |
|||
LD (LCDBUF+2),A |
|||
AND ~LCDPINE |
|||
LD (LCDBUF+3),A |
|||
; |
|||
LD HL,LCDBUF ; OUTPUT 1 BYTE WHICH |
|||
LD B,4 ; REQUIRES A FOUR |
|||
CALL WLN ; BYTE SEQUENCE |
|||
; |
|||
POP BC |
|||
POP DE |
|||
RET |
|||
; |
|||
LCDDATA: |
|||
.DB "TEST HOW BIG IS THIS LINE DOES IT WRAP",0 |
|||
; |
|||
LCDINIT1: |
|||
.DB 00110100B |
|||
.DB 00011000B |
|||
; |
|||
LCDINIT2: |
|||
.DB 00100100B |
|||
.DB 00100000B |
|||
; |
|||
LCDBUF: |
|||
.DB 0, 0, 0, 0 ; BUFFER TO HOLD 4 BYTE SEQUENCE |
|||
|
|||
; FLASH DEVICE READ |
|||
; |
|||
|
|||
DEVMADR .EQU 0 |
|||
|
|||
READR: LD B,255 |
|||
DLY1: DJNZ DLY1 |
|||
; |
|||
LD A,D ; SET SLAVE ADDRESS |
|||
OUT (REGS0),A |
|||
; |
|||
LD A,0C5H ; GENERATE START CONDITION |
|||
OUT (REGS1),A ; AND ISSUE THE SLAVE ADDRESS |
|||
CALL CHKPIN |
|||
; |
|||
LD A,+(DEVMADR/256) |
|||
OUT (REGS0),A ; PUT ADDRESS MSB ON BUS |
|||
CALL CHKPIN |
|||
; |
|||
LD A,+(DEVMADR&$00FF) |
|||
OUT (REGS0),A ; PUT ADDRESS LSB ON BUS |
|||
CALL CHKPIN |
|||
; |
|||
LD A,045H ; START |
|||
OUT (REGS1),A |
|||
; |
|||
LD A,E ; ISSUE CONTROL BYTE + READ |
|||
OUT (REGS0),A |
|||
; |
|||
CALL READI2C ; DUMMY READ |
|||
JR NZ,ERREXT |
|||
; |
|||
READLP1:CALL READI2C |
|||
; JR Z,ERREXT |
|||
CP 1AH |
|||
PUSH AF |
|||
CALL COUT |
|||
POP AF |
|||
JR NZ,READLP1 |
|||
; |
|||
LD A,PCF_ES0 |
|||
OUT (REGS1),A |
|||
CALL CHKPIN |
|||
IN A,(REGS0) |
|||
CALL READI2C |
|||
CALL STOP |
|||
; |
|||
CALL NEWLINE |
|||
; |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
;----------------------------------------------------------------------------- |
|||
RESET: LD A,0C2H ; STOP |
|||
OUT (REGS1),A |
|||
LD B,255 |
|||
DLY2: DJNZ DLY2 |
|||
LD A,0C1H |
|||
OUT (REGS1),A |
|||
RET |
|||
|
|||
|
|||
RDSTAT: LD BC,-1 |
|||
STATLP: IN A,(REGS1) |
|||
AND 1 |
|||
RET Z |
|||
LD A,B |
|||
OR C |
|||
DEC BC |
|||
JR NZ,STATLP |
|||
LD A,'T' |
|||
JP ERREXTT |
|||
; |
|||
ERREXT: LD A,'Q' |
|||
JR ERR |
|||
|
|||
ERREXTT: POP HL |
|||
ERR: CALL COUT |
|||
CALL STOP |
|||
CALL RESET |
|||
RET |
|||
; |
|||
STOP: LD A,0C3H |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
DELAY: PUSH HL |
|||
LD HL,-1 |
|||
DLOOP: LD A,H |
|||
OR L |
|||
DEC HL |
|||
JR NZ,DLOOP |
|||
POP HL |
|||
RET |
|||
; |
|||
CHKPIN: IN A,(REGS1) ; POLL FOR |
|||
BIT 7,A ; TRANSMISSION |
|||
JP NZ,CHKPIN ; TO FINISH |
|||
|
|||
; IN A,(REGS1) ; CHECK FOR |
|||
BIT 3,A ; SLAVE |
|||
RET Z ; ACKNOWLEDGMENT |
|||
LD A,'A' |
|||
JP ERREXTT |
|||
; |
|||
; READ ONE BYTE FROM I2C |
|||
; RETURNS DATA IN A |
|||
; Z flag set is acknowledge received (correct operation) |
|||
; |
|||
READI2C: |
|||
IN A,(REGS1) ; READ S1 REGISTER |
|||
BIT 7,A ; CHECK PIN STATUS |
|||
JP NZ,READI2C |
|||
BIT 3,A ; CHECK LRB=0 |
|||
RET NZ |
|||
IN A,(REGS0) ; GET DATA |
|||
RET |
|||
; |
|||
DEBUG: PUSH AF |
|||
PUSH DE |
|||
LD A,'[' |
|||
CALL COUT |
|||
LD HL,DEBUGF |
|||
LD A,(HL) |
|||
INC (HL) |
|||
CALL HBTHE |
|||
LD A,']' |
|||
CALL COUT |
|||
POP DE |
|||
POP AF |
|||
RET |
|||
DEBUGF: .DB 00H |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; LINUX DRIVER BASED CODE |
|||
; |
|||
; I2C_INB = IN A,(REGS0) |
|||
; I2C_OUTB = LD A,* | OUT (REGS0),A |
|||
; SET_PCF = LD A,* | OUT (REGS1),A |
|||
; GET_PCF = IN A,(REGS1) |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
I2C_START: |
|||
LD A,PCF_START_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
I2C_REPSTART: |
|||
LD A,PCF_START_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
I2C_STOP: |
|||
LD A,PCF_STOP_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
HANDLE_LAB: |
|||
|
|||
LABDLY .EQU 0F000H |
|||
|
|||
LD A,PCF_PIN |
|||
OUT (REGS1),A |
|||
LD A,PCF_ES0 |
|||
OUT (REGS1),A |
|||
; |
|||
LD HL,LABDLY |
|||
LABLP LD A,H |
|||
OR L |
|||
DEC HL |
|||
JR NZ,LABLP |
|||
; |
|||
IN A,(REGS1) |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
WAIT_FOR_BB: |
|||
; |
|||
BBTIMO .EQU 255 |
|||
; |
|||
LD HL,BBTIMO |
|||
BBNOTO IN A,(REGS1) |
|||
AND PCF_BB |
|||
RET Z |
|||
DEC HL |
|||
LD A,H |
|||
OR A |
|||
JR NZ,BBNOTO |
|||
CPL ; RET NZ IF TIMEOUT |
|||
BBNOTB RET ; RET Z IF BUS IS BUSY |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
WAIT_FOR_PIN: |
|||
; |
|||
; RETURN A=00/Z IF SUCCESSFULL |
|||
; RETURN A=FF/NZ IF TIMEOUT |
|||
; RETURN A=01/NZ IF LOST ARBITRATION |
|||
; |
|||
PINTIMO .EQU 16000 |
|||
; |
|||
LD HL,PINTIMO |
|||
PINNOTO IN A,(REGS1) |
|||
LD (STATUS),A |
|||
LD B,A |
|||
AND PCF_PIN |
|||
RET Z |
|||
DEC HL |
|||
LD A,H |
|||
OR A |
|||
JR NZ,PINNOTO |
|||
CPL ; RET NZ IF TIMEOUT |
|||
PINNOTB RET ; RET Z IF BUS IS BUSY |
|||
; |
|||
LD B,A |
|||
AND PCF_LAB |
|||
CALL HANDLE_LAB |
|||
LD (STATUS),A |
|||
XOR A |
|||
INC A |
|||
RET |
|||
; |
|||
STATUS .DB 00H |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
PCF_INIT: |
|||
LD A,PCF_PIN ; S1=80H: S0 SELECTED, SERIAL |
|||
OUT (REGS1),A ; INTERFACE OFF |
|||
NOP |
|||
IN A,(REGS1) ; CHECK TO SEE S1 NOW USED AS R/W |
|||
AND 07FH ; CTRL. PCF8584 DOES THAT WHEN ESO |
|||
JR NZ,INIERR ; IS ZERO |
|||
; |
|||
LD A,PCF_OWN ; LOAD OWN ADDRESS IN S0, |
|||
OUT (REGS0),A ; EFFECTIVE ADDRESS IS (OWN <<1) |
|||
NOP |
|||
IN A,(REGS0) ; CHECK IT IS REALLY WRITTEN |
|||
CP PCF_OWN |
|||
JR NZ,SETERR |
|||
; |
|||
LD A,+(PCF_PIN | PCF_ES1) ; S1=0A0H |
|||
OUT (REGS1),A ; NEXT BYTE IN S2 |
|||
NOP |
|||
IN A,(REGS1) |
|||
AND 07FH |
|||
CP PCF_ES1 |
|||
JR NZ,REGERR |
|||
; |
|||
LD A,PCF_CLK ; LOAD CLOCK REGISTER S2 |
|||
OUT (REGS0),A |
|||
NOP |
|||
IN A,(REGS0) ; CHECK IT'S REALLY WRITTEN, ONLY |
|||
AND 1FH ; THE LOWER 5 BITS MATTER |
|||
CP PCF_CLK |
|||
JR NZ,CLKERR |
|||
; |
|||
LD A,PCF_IDLE_ |
|||
OUT (REGS1),A |
|||
NOP |
|||
IN A,(REGS1) |
|||
CP +(PCF_PIN | PCF_BB) |
|||
JR NZ,IDLERR |
|||
|
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
PCF_SENDBYTES: ; HL POINTS TO DATA, BC = COUNT, A = 0 LAST A=1 NOT LAST |
|||
; |
|||
LD (LASTB),A |
|||
; |
|||
SB0: LD A,(HL) |
|||
OUT (REGS0),A |
|||
CALL WAIT_FOR_PIN |
|||
JR Z,SB1 |
|||
|
|||
CP 01H ; EXIT IF ARBITRATION ERROR |
|||
RET Z |
|||
|
|||
CALL I2C_STOP ; MUST BE TIMEOUT |
|||
LD A,055H ; ERROR |
|||
RET |
|||
|
|||
SB1: LD A,(STATUS) |
|||
AND PCF_LRB |
|||
JR NZ,SB2 |
|||
LD A,055H |
|||
; |
|||
SB2: LD A,B |
|||
OR C |
|||
INC HL |
|||
JR NZ,SB0 ; CHECK IF FINISHED |
|||
; |
|||
SBGOOD: LD A,(LASTB) |
|||
OR A |
|||
JR NZ,DB3 |
|||
CALL I2C_STOP |
|||
RET |
|||
DB3: CALL I2C_REPSTART |
|||
RET |
|||
; |
|||
LASTB .DB 00H |
|||
; |
|||
|
|||
; I2C_INB = IN A,(REGS0) |
|||
; I2C_OUTB = LD A,* | OUT (REGS0),A |
|||
; SET_PCF = LD A,* | OUT (REGS1),A |
|||
; GET_PCF = IN A,(REGS1) |
|||
|
|||
|
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
|
|||
INIERR LD HL,NOPCF |
|||
CALL PRTSTR |
|||
RET |
|||
; |
|||
SETERR LD HL,WRTFAIL |
|||
CALL PRTSTR |
|||
RET |
|||
REGERR LD HL,REGFAIL |
|||
CALL PRTSTR |
|||
RET |
|||
; |
|||
CLKERR LD HL,CLKFAIL |
|||
CALL PRTSTR |
|||
RET |
|||
; |
|||
IDLERR LD HL,IDLFAIL |
|||
CALL PRTSTR |
|||
RET |
|||
; |
|||
NOPCF .DB "NO DEVICE FOUND",CR,LF,"$" |
|||
WRTFAIL .DB "SETTING DEVICE ID FAILED",CR,LF,"$" |
|||
REGFAIL .DB "CLOCK REGISTER SELECT ERROR",CR,LF,"$" |
|||
CLKFAIL .DB "CLOCK SET FAIL",CR,LF,"$" |
|||
IDLFAIL .DB "BUS IDLE FAILED",CR,LF,"$" |
|||
; |
|||
#INCLUDE "i2ccpm.inc" |
|||
; |
|||
BUFFER: .DS 256 |
|||
; |
|||
.END |
|||
@ -0,0 +1,500 @@ |
|||
; |
|||
.ECHO "i2cscan\n" |
|||
; |
|||
; I2C BUS SCANNER |
|||
; MARCO MACCAFERRI, HTTPS://WWW.MACCASOFT.COM |
|||
; HBIOS VERSION BY PHIL SUMMERS (B1ACKMAILER) DIFFICULTLEVELHIGH@GMAIL.COM |
|||
; |
|||
PCF .EQU 1 |
|||
P8X180 .EQU 0 |
|||
SC126 .EQU 0 |
|||
SC137 .EQU 0 |
|||
; |
|||
#IF (PCF) |
|||
I2C_BASE .EQU 0F0H |
|||
PCF_ID .EQU 0AAH |
|||
CPU_CLK .EQU 12 |
|||
; |
|||
PCF_RS0 .EQU I2C_BASE |
|||
PCF_RS1 .EQU PCF_RS0+1 |
|||
PCF_OWN .EQU (PCF_ID >> 1) ; PCF'S ADDRESS IN SLAVE MODE |
|||
#ENDIF |
|||
; |
|||
#IF (P8X180) |
|||
I2C_BASE .EQU 0A0h |
|||
_sda .EQU 0 |
|||
_scl .EQU 1 |
|||
_idle .EQU 00000011B |
|||
#ENDIF |
|||
; |
|||
#IF (SC126) |
|||
I2C_BASE .EQU 0Ch |
|||
_sda .EQU 7 |
|||
_scl .EQU 0 |
|||
_idle .EQU 10001101B |
|||
#ENDIF |
|||
; |
|||
#IF (SC137) |
|||
I2C_BASE .EQU 20h |
|||
_sda .EQU 7 |
|||
_scl .EQU 0 |
|||
_idle .EQU 10000001B |
|||
#ENDIF |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
.org 100h |
|||
|
|||
ld sp,stack |
|||
|
|||
ld hl,signon |
|||
call _strout |
|||
|
|||
ld c,' ' |
|||
call _cout |
|||
call _cout |
|||
call _cout |
|||
|
|||
; display x axis header 00-0F |
|||
|
|||
xor a |
|||
ld (x),a |
|||
ld b, 16 |
|||
lp1: ld c,' ' |
|||
call _cout |
|||
ld a,(x) |
|||
ld c,a |
|||
inc a |
|||
ld (x),a |
|||
call _hexout |
|||
djnz lp1 |
|||
call _eolout |
|||
|
|||
; start of line loop 00-07 |
|||
|
|||
xor a ; display |
|||
ld (y),a ; y-axis |
|||
ld (addr),a ; prefix |
|||
ld d,8 |
|||
lp3b: ld a,(y) |
|||
ld c,a |
|||
add a,10h |
|||
ld (y),a |
|||
call _hexout |
|||
ld c,':' |
|||
call _cout |
|||
|
|||
; set up x axis loop |
|||
|
|||
xor a |
|||
ld (x),a |
|||
ld e,16 |
|||
lp2b: push de |
|||
|
|||
ld c,' ' |
|||
call _cout |
|||
|
|||
; i2c challenge |
|||
; . issue device start command |
|||
; . write address to device |
|||
; . issue device stop command. |
|||
; . delay |
|||
; . display response |
|||
|
|||
; call _i2c_start |
|||
; ld a,(addr) |
|||
; ld c,a |
|||
; call _i2c_write |
|||
; ld (rc),a |
|||
; call _i2c_stop |
|||
|
|||
CALL PCF_WAIT_FOR_BB |
|||
JP NZ,PCF_BBERR |
|||
; |
|||
LD A,(addr) |
|||
OUT (PCF_RS0),A |
|||
CALL PCF_START ; GENERATE START CONDITION |
|||
; |
|||
ld bc,100 ; delay |
|||
lp6: nop |
|||
dec bc |
|||
ld a,c |
|||
or b |
|||
jr nz,lp6 |
|||
|
|||
CALL PCF_WAIT_FOR_ACK; AND ISSUE THE SLAVE ADDRESS |
|||
or a |
|||
jp nz,lp4f |
|||
|
|||
ld c,'-' ; display no |
|||
call _cout ; response |
|||
call _cout |
|||
jp lp5f |
|||
|
|||
lp4f: ld a,(addr) ; adjust address |
|||
ld c,a ; and display it |
|||
srl c |
|||
call _hexout |
|||
|
|||
lp5f: ld a,(addr) ; next address |
|||
add a,2 ; adjust for |
|||
ld (addr),a ; 7-bit |
|||
|
|||
CALL PCF_STOP |
|||
|
|||
pop de ; check if |
|||
dec e ; reached end |
|||
jp nz,lp2b ; of line |
|||
call _eolout |
|||
|
|||
dec d ; loop until |
|||
jp nz,lp3b ; all done |
|||
|
|||
jp 0 |
|||
|
|||
signon: .db "I2C Bus Scanner" |
|||
#IF (PCF) |
|||
.DB " - PCF8584" |
|||
#ENDIF |
|||
#IF (SC126) |
|||
.DB " - SC126" |
|||
#ENDIF |
|||
#IF (SC137) |
|||
.DB " - SC137" |
|||
#ENDIF |
|||
.db 13, 10, 13, 10, 0, "$"8 |
|||
|
|||
_strout: |
|||
st1: ld a,(hl) ; display |
|||
CP '$' ; zero |
|||
ret z ; terminated |
|||
ld c,a ; string |
|||
call _cout |
|||
inc hl |
|||
jp st1 |
|||
|
|||
_hexout: ; display |
|||
ld a,c ; A in hex |
|||
srl a |
|||
srl a |
|||
srl a |
|||
srl a |
|||
add a,30h |
|||
cp 3Ah |
|||
jp c,h1 |
|||
add a,7 |
|||
h1: ld h,a |
|||
ld a,c |
|||
and 0Fh |
|||
add a,30h |
|||
cp 3Ah |
|||
jp c,h2 |
|||
add a,7 |
|||
h2: ld l,a |
|||
ld c,h |
|||
call _cout |
|||
ld c,l |
|||
call _cout |
|||
ret |
|||
|
|||
_eolout: ; newline |
|||
ld c,13 |
|||
call _cout |
|||
ld c,10 |
|||
call _cout |
|||
ret |
|||
|
|||
_cout: ; character |
|||
push af ; output |
|||
push bc |
|||
push de |
|||
push hl |
|||
ld e,c |
|||
ld c,02h |
|||
call 5 |
|||
pop hl |
|||
pop de |
|||
pop bc |
|||
pop af |
|||
ret |
|||
|
|||
;----------------------------------------------------------------------------- |
|||
#IF (PCF) |
|||
_i2c_start: |
|||
PCF_START: |
|||
LD A,PCF_START_ |
|||
OUT (PCF_RS1),A |
|||
RET |
|||
#ELSE |
|||
;_i2c_start: |
|||
ld a,_idle ; issue |
|||
out (I2C_BASE),a ; start |
|||
; command |
|||
res _sda,a |
|||
out (I2C_BASE),a |
|||
nop |
|||
nop |
|||
res _scl,a |
|||
out (I2C_BASE),a |
|||
|
|||
ld (oprval),a |
|||
ret |
|||
#ENDIF |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; CONTROL REGISTER BITS |
|||
; |
|||
PCF_PIN .EQU 10000000B |
|||
PCF_ES0 .EQU 01000000B |
|||
PCF_ES1 .EQU 00100000B |
|||
PCF_ES2 .EQU 00010000B |
|||
PCF_EN1 .EQU 00001000B |
|||
PCF_STA .EQU 00000100B |
|||
PCF_STO .EQU 00000010B |
|||
PCF_ACK .EQU 00000001B |
|||
; |
|||
; STATUS REGISTER BITS |
|||
; |
|||
;PCF_PIN .EQU 10000000B |
|||
PCF_INI .EQU 01000000B ; 1 if not initialized |
|||
PCF_STS .EQU 00100000B |
|||
PCF_BER .EQU 00010000B |
|||
PCF_AD0 .EQU 00001000B |
|||
PCF_LRB .EQU 00001000B |
|||
PCF_AAS .EQU 00000100B |
|||
PCF_LAB .EQU 00000010B |
|||
PCF_BB .EQU 00000001B |
|||
; |
|||
PCF_START_ .EQU (PCF_PIN | PCF_ES0 | PCF_STA | PCF_ACK) |
|||
PCF_STOP_ .EQU (PCF_PIN | PCF_ES0 | PCF_STO | PCF_ACK) |
|||
; |
|||
; TIMEOUT AND DELAY VALUES (ARBITRARY) |
|||
; |
|||
PCF_PINTO .EQU 65000 |
|||
PCF_ACKTO .EQU 65000 |
|||
PCF_BBTO .EQU 65000 |
|||
PCF_LABDLY .EQU 65000 |
|||
; |
|||
PCF_STATUS .DB 00H |
|||
; |
|||
;-------------------------------------------------------------------------------- |
|||
; |
|||
; RETURN NZ/FF IF TIMEOUT ERROR |
|||
; RETURN NZ/01 IF FAILED TO RECEIVE ACKNOWLEDGE |
|||
; RETURN Z/00 IF RECEIVED ACKNOWLEDGE |
|||
; |
|||
PCF_WAIT_FOR_ACK: |
|||
PUSH HL |
|||
LD HL,PCF_ACKTO |
|||
; |
|||
PCF_WFA0: |
|||
IN A,(PCF_RS1) ; READ PIN |
|||
LD (PCF_STATUS),A ; STATUS |
|||
LD B,A |
|||
; |
|||
DEC HL ; SEE IF WE HAVE TIMED |
|||
LD A,H ; OUT WAITING FOR PIN |
|||
OR L ; EXIT IF |
|||
JR Z,PCF_WFA1 ; WE HAVE |
|||
; |
|||
LD A,B ; OTHERWISE KEEP LOOPING |
|||
AND PCF_PIN ; UNTIL WE GET PIN |
|||
JR NZ,PCF_WFA0 ; OR TIMEOUT |
|||
; |
|||
LD A,B ; WE GOT PIN SO NOW |
|||
AND PCF_LRB ; CHECK WE HAVE |
|||
LD A,1 |
|||
JR Z,PCF_WFA2 ; RECEIVED ACKNOWLEDGE |
|||
XOR A |
|||
JR PCF_WFA2 |
|||
PCF_WFA1: |
|||
CPL ; TIMOUT ERROR |
|||
PCF_WFA2: |
|||
POP HL ; EXIT WITH NZ = FF |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; POLL THE BUS BUSY BIT TO DETERMINE IF BUS IS FREE. |
|||
; RETURN WITH A=00H/Z STATUS IF BUS IS FREE |
|||
; RETURN WITH A=FFH/NZ STATUS IF BUS |
|||
; |
|||
; AFTER RESET THE BUS BUSY BIT WILL BE SET TO 1 I.E. NOT BUSY |
|||
; |
|||
PCF_WAIT_FOR_BB: |
|||
LD HL,PCF_BBTO |
|||
PCF_WFBB0: |
|||
IN A,(PCF_RS1) |
|||
AND PCF_BB |
|||
RET Z ; BUS IS FREE RETURN ZERO |
|||
DEC HL |
|||
LD A,H |
|||
OR L |
|||
JR NZ,PCF_WFBB0 ; REPEAT IF NOT TIMED OUT |
|||
CPL ; RET NZ IF TIMEOUT |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; DISPLAY ERROR MESSAGES |
|||
; |
|||
PCF_RDERR: |
|||
PUSH HL |
|||
LD HL,PCF_RDFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_INIERR: |
|||
PUSH HL |
|||
LD HL,PCF_NOPCF |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_SETERR: |
|||
PUSH HL |
|||
LD HL,PCF_WRTFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_REGERR: |
|||
PUSH HL |
|||
LD HL,PCF_REGFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_CLKERR: |
|||
PUSH HL |
|||
LD HL,PCF_CLKFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_IDLERR: |
|||
PUSH HL |
|||
LD HL,PCF_IDLFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_ACKERR: |
|||
PUSH HL |
|||
LD HL,PCF_ACKFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_RDBERR: |
|||
PUSH HL |
|||
LD HL,PCF_RDBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_TOERR: |
|||
PUSH HL |
|||
LD HL,PCF_TOFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_ARBERR: |
|||
PUSH HL |
|||
LD HL,PCF_ARBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_PINERR: |
|||
PUSH HL |
|||
LD HL,PCF_PINFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_BBERR: |
|||
PUSH HL |
|||
LD HL,PCF_BBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_PRTERR: |
|||
CALL _strout |
|||
CALL _eolout |
|||
POP HL |
|||
RET |
|||
; |
|||
PCF_NOPCF .DB "NO DEVICE FOUND$" |
|||
PCF_WRTFAIL .DB "SETTING DEVICE ID FAILED$" |
|||
PCF_REGFAIL .DB "CLOCK REGISTER SELECT ERROR$" |
|||
PCF_CLKFAIL .DB "CLOCK SET FAIL$" |
|||
PCF_IDLFAIL .DB "BUS IDLE FAILED$" |
|||
PCF_ACKFAIL .DB "FAILED TO RECEIVE ACKNOWLEDGE$" |
|||
PCF_RDFAIL .DB "READ FAILED$" |
|||
PCF_RDBFAIL .DB "READBYTES FAILED$" |
|||
PCF_TOFAIL .DB "TIMEOUT ERROR$" |
|||
PCF_ARBFAIL .DB "LOST ARBITRATION$" |
|||
PCF_PINFAIL .DB "PIN FAIL$" |
|||
PCF_BBFAIL .DB "BUS BUSY$" |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
#IF (PCF) |
|||
_i2c_stop: |
|||
PCF_STOP: |
|||
LD A,PCF_STOP_ ; issue |
|||
OUT (PCF_RS1),A ; stop |
|||
RET ; command |
|||
#ELSE |
|||
;_i2c_stop: |
|||
ld a,(oprval) |
|||
res _scl,a |
|||
res _sda,a |
|||
out (I2C_BASE),a |
|||
|
|||
set _scl,a |
|||
out (I2C_BASE),a |
|||
nop |
|||
nop |
|||
set _sda,a |
|||
out (I2C_BASE),a |
|||
|
|||
ld (oprval),a |
|||
ret |
|||
; |
|||
_i2c_write: ; write |
|||
ld a,(oprval) ; to i2c |
|||
; bus |
|||
ld b,8 |
|||
i2c1: res _sda,a |
|||
rl c |
|||
jr nc,i2c2 |
|||
set _sda,a |
|||
i2c2: out (I2C_BASE),a |
|||
set _scl,a |
|||
out (I2C_BASE),a |
|||
|
|||
#IF (SC126=0) |
|||
ld d,a |
|||
i2c3: in a,(I2C_BASE) |
|||
bit _scl,a |
|||
jr z,i2c3 |
|||
ld a,d |
|||
#ENDIF |
|||
res _scl,a |
|||
out (I2C_BASE),a |
|||
djnz i2c1 |
|||
|
|||
set _sda,a |
|||
out (I2C_BASE),a |
|||
set _scl,a |
|||
out (I2C_BASE),a |
|||
|
|||
ld d,a |
|||
i2c4: in a,(I2C_BASE) |
|||
#IF (SC126=0) |
|||
bit _scl,a |
|||
jr z,4b |
|||
#ENDIF |
|||
ld c,a |
|||
ld a,d |
|||
|
|||
res _scl,a |
|||
out (I2C_BASE),a |
|||
ld (oprval),a |
|||
|
|||
xor a |
|||
bit _sda,c |
|||
ret z |
|||
inc a |
|||
|
|||
ret |
|||
#ENDIF |
|||
oprval: .db 0 |
|||
x: .db 0 |
|||
y: .db 0 |
|||
addr: .db 0 |
|||
rc: .db 0 |
|||
|
|||
.fill 128 |
|||
stack: |
|||
.end |
|||
@ -0,0 +1,116 @@ |
|||
;================================================================================================== |
|||
; PCF8584 Generic |
|||
;================================================================================================== |
|||
; |
|||
PCF_BASE .EQU 0F0H |
|||
PCF_ID .EQU 0AAH |
|||
CPU_CLK .EQU 12 |
|||
|
|||
PCF_RS0 .EQU PCF_BASE |
|||
PCF_RS1 .EQU PCF_RS0+1 |
|||
PCF_OWN .EQU (PCF_ID >> 1) ; PCF'S ADDRESS IN SLAVE MODE |
|||
|
|||
REGS0 .EQU PCF_BASE |
|||
REGS1 .EQU REGS0+1 |
|||
; |
|||
;T4LC512D .EQU 10100000B ; DEVICE IDENTIFIER |
|||
;T4LC512A1 .EQU 00000000B ; DEVICE ADDRESS |
|||
;T4LC512A2 .EQU 00001110B ; DEVICE ADDRESS |
|||
;T4LC512A3 .EQU 00000010B ; DEVICE ADDRESS |
|||
;T4LC512W .EQU 00000000B ; DEVICE WRITE |
|||
;T4LC512R .EQU 00000001B ; DEVICE READ |
|||
; |
|||
;I2CDEV1W .EQU (T4LC512D+T4LC512A1+T4LC512W) |
|||
;I2CDEV1R .EQU (T4LC512D+T4LC512A1+T4LC512R) |
|||
; |
|||
;I2CDEV2W .EQU (T4LC512D+T4LC512A2+T4LC512W) |
|||
;I2CDEV2R .EQU (T4LC512D+T4LC512A2+T4LC512R) |
|||
; |
|||
;I2CDEV3W .EQU (T4LC512D+T4LC512A3+T4LC512W) |
|||
;I2CDEV3R .EQU (T4LC512D+T4LC512A3+T4LC512R) |
|||
; |
|||
; CONTROL REGISTER BITS |
|||
; |
|||
PCF_PIN .EQU 10000000B |
|||
PCF_ES0 .EQU 01000000B |
|||
PCF_ES1 .EQU 00100000B |
|||
PCF_ES2 .EQU 00010000B |
|||
PCF_EN1 .EQU 00001000B |
|||
PCF_STA .EQU 00000100B |
|||
PCF_STO .EQU 00000010B |
|||
PCF_ACK .EQU 00000001B |
|||
; |
|||
PCF_START_ .EQU (PCF_PIN | PCF_ES0 | PCF_STA | PCF_ACK) |
|||
PCF_STOP_ .EQU (PCF_PIN | PCF_ES0 | PCF_STO | PCF_ACK) |
|||
PCF_REPSTART_ .EQU ( PCF_ES0 | PCF_STA | PCF_ACK) |
|||
PCF_IDLE_ .EQU (PCF_PIN | PCF_ES0 | PCF_ACK) |
|||
; |
|||
; STATUS REGISTER BITS |
|||
; |
|||
;PCF_PIN .EQU 10000000B |
|||
PCF_INI .EQU 01000000B ; 1 if not initialized |
|||
PCF_STS .EQU 00100000B |
|||
PCF_BER .EQU 00010000B |
|||
PCF_AD0 .EQU 00001000B |
|||
PCF_LRB .EQU 00001000B |
|||
PCF_AAS .EQU 00000100B |
|||
PCF_LAB .EQU 00000010B |
|||
PCF_BB .EQU 00000001B |
|||
; |
|||
; CLOCK CHIP FREQUENCIES |
|||
; |
|||
PCF_CLK3 .EQU 000H |
|||
PCF_CLK443 .EQU 010H |
|||
PCF_CLK6 .EQU 014H |
|||
PCF_CLK8 .EQU 018H |
|||
PCF_CLK12 .EQU 01cH |
|||
; |
|||
; TRANSMISSION FREQUENCIES |
|||
; |
|||
PCF_TRNS90 .EQU 000H ; 90 kHz */ |
|||
PCF_TRNS45 .EQU 001H ; 45 kHz */ |
|||
PCF_TRNS11 .EQU 002H ; 11 kHz */ |
|||
PCF_TRNS15 .EQU 003H ; 1.5 kHz */ |
|||
; |
|||
; TIMEOUT AND DELAY VALUES (ARBITRARY) |
|||
; |
|||
PCF_PINTO .EQU 65000 |
|||
PCF_ACKTO .EQU 65000 |
|||
PCF_BBTO .EQU 65000 |
|||
PCF_LABDLY .EQU 65000 |
|||
; |
|||
; DATA PORT REGISTERS |
|||
; |
|||
#IF (CPU_CLK = 443) |
|||
PCF_CLK .EQU PCF_CLK443 |
|||
#ELSE |
|||
#IF (CPU_CLK = 8) |
|||
PCF_CLK .EQU PCF_CLK8 |
|||
#ELSE |
|||
#IF (CPU_CLK = 12) |
|||
PCF_CLK .EQU PCF_CLK12 |
|||
#ELSE ***ERROR |
|||
#ENDIF |
|||
#ENDIF |
|||
#ENDIF |
|||
; |
|||
DS7_OUT .EQU 10000000B ; SELECT SQUARE WAVE FUNCTION |
|||
DS7_SQWE .EQU 00010000B ; ENABLE SQUARE WAVE OUTPUT |
|||
DS7_RATE .EQU 00000000B ; SET 1HZ OUPUT |
|||
; |
|||
DS7_DS1307 .EQU 11010000B ; DEVICE IDENTIFIER |
|||
DS7_W .EQU 00000000B ; DEVICE WRITE |
|||
DS7_R .EQU 00000001B ; DEVICE READ |
|||
; |
|||
DS7_READ .EQU (DS7_DS1307 | DS7_R) ; READ |
|||
DS7_WRITE .EQU (DS7_DS1307 | DS7_W) ; WRITE |
|||
; |
|||
DS7_CTL .EQU (DS7_OUT | DS7_SQWE | DS7_RATE) |
|||
; |
|||
PCF8574 .EQU 01000000B ; DEVICE IDENTIFIER |
|||
PCF8574A .EQU 00001110B ; DEVICE ADDRESS |
|||
PCF8574W .EQU 00000000B ; DEVICE WRITE |
|||
PCF8574R .EQU 00000001B ; DEVICE READ |
|||
; |
|||
I2CLCDR .EQU (PCF8574+PCF8574A+PCF8574R) |
|||
I2CLCDW .EQU (PCF8574+PCF8574A+PCF8574W) |
|||
@ -0,0 +1,540 @@ |
|||
;================================================================================================== |
|||
; PCF8584/DS1307 I2C DATE AND TIME UTILITY |
|||
;================================================================================================== |
|||
; |
|||
.ECHO "rtcds7\n" |
|||
; |
|||
#INCLUDE "pcfi2c.inc" |
|||
; |
|||
.ORG 100H |
|||
; |
|||
DS7_START: |
|||
LD (DS7_STK),SP ; SETUP A |
|||
LD SP,DS7_LOC ; LOCAL STACK |
|||
; |
|||
CALL DS7_INIT ; INITIALIZE AND |
|||
JR NZ,DS7_ERR ; RETURN WITH STATUS |
|||
; |
|||
LD A,(FCB+1) ; GET FIRST COMMAND LINE CHAR |
|||
CP ' ' ; COMPARE TO BLANK. IF SO NO |
|||
JR Z,DS7_ST0 ; ARGUMENTS SO DISLAY TIME AND DATE |
|||
; |
|||
LD A,(FCB+1) ; GET FIRST CHAR |
|||
CP '/' ; IS IT INDICATING AN ARGUMENT |
|||
JR NZ,DS7_ST0 ; |
|||
; |
|||
LD A,(FCB+2) ; GET NEXT CHARACTER |
|||
CP 'D' ; |
|||
JR NZ,DS7_ST1 ; |
|||
; |
|||
; /D SET DATE |
|||
; |
|||
JR DS7_EXIT |
|||
; |
|||
DS7_ST1: |
|||
LD A,(FCB+2) ; GET NEXT CHARACTER |
|||
CP 'T' ; |
|||
JR NZ,DS7_ST2 ; |
|||
; |
|||
; /T SET TIME |
|||
; |
|||
JR DS7_EXIT |
|||
; |
|||
DS7_ST2: |
|||
LD A,(FCB+2) ; GET NEXT CHARACTER |
|||
CP 'S' ; |
|||
JR NZ,DS7_ST3 ; |
|||
; |
|||
; /S SET TIME AND DATE |
|||
; |
|||
JR DS7_EXIT |
|||
; |
|||
DS7_ST3: |
|||
; |
|||
; UNREGOGNIZED ARGUMENT |
|||
; |
|||
JR DS7_EXIT |
|||
; |
|||
DS7_ST0: |
|||
CALL DS7_RDC ; READ CLOCK DATA INTO BUFFER |
|||
CALL DS7_DISP ; DISPLAY TIME AND DATE FROM BUFFER |
|||
; |
|||
DS7_EXIT: |
|||
LD SP,(DS7_STK) ; RESTORE STACK |
|||
RET ; AND EXIT |
|||
; |
|||
DS7_ERR: |
|||
CALL PCF_INIERR ; DISPLAY ERROR |
|||
JR DS7_EXIT ; END EXIT |
|||
; |
|||
DS7_STK .DW 2 ; SAVE STACK |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; RTC READ |
|||
; |
|||
; 1. ISSUE SLAVE ADDRESS WITH START CONDITION AND WRITE STATUS |
|||
; 2. OUTPUT THE ADDRESS TO ACCESS. (00H = START OF DS1307 REGISTERS) |
|||
; 3. OUTPUT REPEAT START TO TRANSITION TO READ PROCESS |
|||
; 4. ISSUE SLAVE ADDRESS WITH READ STATUS |
|||
; 5. DO A DUMMY READ |
|||
; 6. READ 8 BYTES STARTING AT ADDRESS PREVIOUSLY SET |
|||
; 7. END READ WITH NON-ACKNOWLEDGE |
|||
; 8. ISSUE STOP AND RELEASE BUS |
|||
; |
|||
DS7_RDC: |
|||
LD A,DS7_WRITE ; SET SLAVE ADDRESS |
|||
OUT (REGS0),A |
|||
; |
|||
CALL PCF_WAIT_FOR_BB |
|||
JP NZ,PCF_BBERR |
|||
; |
|||
CALL PCF_START ; GENERATE START CONDITION |
|||
CALL PCF_WAIT_FOR_PIN; AND ISSUE THE SLAVE ADDRESS |
|||
CALL NZ,PCF_PINERR |
|||
; |
|||
LD A,0 |
|||
OUT (REGS0),A ; PUT ADDRESS MSB ON BUS |
|||
CALL PCF_WAIT_FOR_PIN |
|||
CALL NZ,PCF_PINERR |
|||
; |
|||
CALL PCF_REPSTART ; REPEAT START |
|||
; |
|||
LD A,DS7_READ ; ISSUE CONTROL BYTE + READ |
|||
OUT (REGS0),A |
|||
; |
|||
CALL PCF_READI2C ; DUMMY READ |
|||
; |
|||
LD HL,DS7_BUF ; READ 8 BYTES INTO BUFFER |
|||
LD B,8 |
|||
DS7_RL1:CALL PCF_READI2C |
|||
LD (HL),A |
|||
INC HL |
|||
DJNZ DS7_RL1 |
|||
; |
|||
#IF (0) |
|||
LD A,8 |
|||
LD DE,DS7_BUF ; DISLAY DATA READ |
|||
CALL PRTHEXBUF ; |
|||
CALL NEWLINE |
|||
#ENDIF |
|||
; |
|||
LD A,PCF_ES0 ; END WITH NOT-ACKNOWLEDGE |
|||
OUT (REGS1),A ; AND RELEASE BUS |
|||
NOP |
|||
IN A,(REGS0) |
|||
NOP |
|||
DS7_WTPIN: |
|||
IN A,(REGS1) ; READ S1 REGISTER |
|||
BIT 7,A ; CHECK PIN STATUS |
|||
JP NZ,DS7_WTPIN |
|||
CALL PCF_STOP |
|||
; |
|||
IN A,(REGS0) |
|||
RET |
|||
|
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; DISPLAY CLOCK INFORMATION FROM DATA STORED IN BUFFER |
|||
; |
|||
DS7_DISP: |
|||
LD HL,DS7_CLKTBL |
|||
DS7_CLP:LD C,(HL) |
|||
INC HL |
|||
LD D,(HL) |
|||
CALL DS7_BCD |
|||
INC HL |
|||
LD A,(HL) |
|||
OR A |
|||
RET Z |
|||
CALL COUT |
|||
INC HL |
|||
JR DS7_CLP |
|||
RET |
|||
; |
|||
DS7_CLKTBL: |
|||
.DB 04H, 00111111B, '/' |
|||
.DB 05H, 00011111B, '/' |
|||
.DB 06H, 11111111B, ' ' |
|||
.DB 02H, 00011111B, ':' |
|||
.DB 01H, 01111111B, ':' |
|||
.DB 00H, 01111111B, 00H |
|||
; |
|||
DS7_BCD:PUSH HL |
|||
LD HL,DS7_BUF ; READ VALUE FROM |
|||
LD B,0 ; BUFFER, INDEXED BY A |
|||
ADD HL,BC |
|||
LD A,(HL) |
|||
AND D ; MASK OFF UNNEEDED |
|||
SRL A |
|||
SRL A |
|||
SRL A |
|||
SRL A |
|||
ADD A,30H |
|||
CALL COUT |
|||
LD A,(HL) |
|||
AND 00001111B |
|||
ADD A,30H |
|||
CALL COUT |
|||
POP HL |
|||
RET |
|||
; |
|||
DS7_BUF: .FILL 8,0 ; BUFFER FOR TIME, DATE AND CONTROL |
|||
|
|||
;----------------------------------------------------------------------------- |
|||
PCF_START: |
|||
LD A,PCF_START_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
PCF_REPSTART: |
|||
LD A,PCF_REPSTART_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
PCF_STOP: |
|||
LD A,PCF_STOP_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
DS7_INIT: |
|||
LD A,PCF_PIN ; S1=80H: S0 SELECTED, SERIAL |
|||
OUT (REGS1),A ; INTERFACE OFF |
|||
NOP |
|||
IN A,(REGS1) ; CHECK TO SEE S1 NOW USED AS R/W CTRL. |
|||
AND 07FH ; PCF8584 DOES THAT WHEN ESO IS ZERO |
|||
RET NZ ; PCF_INIERR |
|||
; |
|||
LD A,PCF_OWN ; LOAD OWN ADDRESS IN S0, |
|||
OUT (REGS0),A ; EFFECTIVE ADDRESS IS (OWN <<1) |
|||
NOP |
|||
IN A,(REGS0) ; CHECK IT IS REALLY WRITTEN |
|||
CP PCF_OWN |
|||
RET NZ ; PCF_SETERR |
|||
; |
|||
LD A,+(PCF_PIN | PCF_ES1) ; S1=0A0H |
|||
OUT (REGS1),A ; NEXT BYTE IN S2 |
|||
NOP |
|||
IN A,(REGS1) |
|||
AND 07FH |
|||
CP PCF_ES1 |
|||
RET NZ ; PCF_REGERR |
|||
; |
|||
LD A,PCF_CLK ; LOAD CLOCK REGISTER S2 |
|||
OUT (REGS0),A |
|||
NOP |
|||
IN A,(REGS0) ; CHECK IT'S REALLY WRITTEN, ONLY |
|||
AND 1FH ; THE LOWER 5 BITS MATTER |
|||
CP PCF_CLK |
|||
RET NZ ; PCF_CLKERR |
|||
; |
|||
LD A,PCF_IDLE_ |
|||
OUT (REGS1),A |
|||
NOP |
|||
IN A,(REGS1) |
|||
CP +(PCF_PIN | PCF_BB) |
|||
RET NZ ; PCF_IDLERR |
|||
; |
|||
XOR A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
PCF_HANDLE_LAB: |
|||
; |
|||
LD A,PCF_PIN |
|||
OUT (REGS1),A |
|||
LD A,PCF_ES0 |
|||
OUT (REGS1),A |
|||
; |
|||
LD HL,PCF_LABDLY |
|||
PCF_LABLP: |
|||
LD A,H |
|||
OR L |
|||
DEC HL |
|||
JR NZ,PCF_LABLP |
|||
; |
|||
IN A,(REGS1) |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; RETURN A=00/Z IF SUCCESSFULL |
|||
; RETURN A=FF/NZ IF TIMEOUT |
|||
; RETURN A=01/NZ IF LOST ARBITRATION |
|||
; PCF_STATUS HOLDS LAST PCF STATUS |
|||
; |
|||
PCF_WAIT_FOR_PIN: |
|||
PUSH HL |
|||
LD HL,PCF_PINTO ; SET TIMEOUT VALUE |
|||
|
|||
PCF_WFP0: |
|||
IN A,(REGS1) ; GET BUS |
|||
LD (PCF_STATUS),A ; STATUS |
|||
LD B,A |
|||
|
|||
DEC HL ; HAVE WE |
|||
LD A,H ; TIMED OUT |
|||
OR L |
|||
JR Z,PCF_WFP1 ; YES WE HAVE, GO ACTION IT |
|||
|
|||
LD A,B ; |
|||
AND PCF_PIN ; IS TRANSMISSION COMPLETE? |
|||
JR NZ,PCF_WFP0 ; KEEP ASKING IF NOT OR |
|||
POP HL ; YES COMPLETE (PIN=0) RETURN WITH ZERO |
|||
RET |
|||
PCF_WFP1: |
|||
LD A,B ; DID WE LOSE ARBITRATION? |
|||
AND PCF_LAB ; IF A=0 THEN NO |
|||
CPL |
|||
JR NZ,PCF_WFP2 ; NO |
|||
CALL PCF_HANDLE_LAB ; YES GO HANDLE IT |
|||
LD (PCF_STATUS),A |
|||
XOR A ; RETURN NZ, A=01H |
|||
INC A |
|||
PCF_WFP2: |
|||
POP HL ; RET NZ, A=FF IF TIMEOUT |
|||
RET |
|||
; |
|||
PCF_STATUS .DB 00H |
|||
|
|||
;-------------------------------------------------------------------------------- |
|||
; |
|||
; RETURN NZ/FF IF TIMEOUT ERROR |
|||
; RETURN NZ/01 IF FAILED TO RECEIVE ACKNOWLEDGE |
|||
; RETURN Z/00 IF RECEIVED ACKNOWLEDGE |
|||
; |
|||
PCF_WAIT_FOR_ACK: |
|||
PUSH HL |
|||
LD HL,PCF_ACKTO |
|||
; |
|||
PCF_WFA0: |
|||
IN A,(REGS1) ; READ PIN |
|||
LD (PCF_STATUS),A ; STATUS |
|||
LD B,A |
|||
; |
|||
DEC HL ; SEE IF WE HAVE TIMED |
|||
LD A,H ; OUT WAITING FOR PIN |
|||
OR L ; EXIT IF |
|||
JR Z,PCF_WFA1 ; WE HAVE |
|||
; |
|||
LD A,B ; OTHERWISE KEEP LOOPING |
|||
AND PCF_PIN ; UNTIL WE GET PIN |
|||
JR NZ,PCF_WFA0 ; OR TIMEOUT |
|||
; |
|||
LD A,B ; WE GOT PIN SO NOW |
|||
AND PCF_LRB ; CHECK WE HAVE |
|||
LD A,1 |
|||
JR Z,PCF_WFA2 ; RECEIVED ACKNOWLEDGE |
|||
XOR A |
|||
JR PCF_WFA2 |
|||
PCF_WFA1: |
|||
CPL ; TIMOUT ERROR |
|||
PCF_WFA2: |
|||
POP HL ; EXIT WITH NZ = FF |
|||
RET |
|||
; |
|||
;-------------------------------------------------------------------------------- |
|||
; |
|||
; HL POINTS TO DATA |
|||
; DE = COUNT |
|||
; A = 0 LAST A=1 NOT LAST |
|||
; |
|||
; |
|||
;PCF_READBYTES: ; NOT FUNCTIONAL YET |
|||
|
|||
LD (PCF_LBF),A ; SAVE LAST BYTE FLAG |
|||
; |
|||
INC DE ; INCREMENT NUMBER OF BYTES TO READ BY ONE -- DUMMY READ BYTE |
|||
LD BC,0 ; SET BYTE COUNTER |
|||
; |
|||
PCF_RBL:PUSH BC |
|||
CALL PCF_WAIT_FOR_PIN ; DO WE HAVE THE BUS? |
|||
POP BC |
|||
JR Z,PCF_RB1 ; YES |
|||
CP 01H |
|||
JR Z,PCF_RB3 ; NO - LOST ARBITRATION |
|||
JR PCF_RB2 ; NO - TIMEOUT |
|||
; |
|||
PCF_RB1: |
|||
LD A,(PCF_STATUS) |
|||
AND PCF_LRB |
|||
|
|||
|
|||
; IS THIS THE SECOND TO LAST BYTE TO GO? |
|||
|
|||
PUSH DE ; SAVE COUNT |
|||
DEC DE ; COUNT (DE) = NUMBER OF BYTES TO READ LESS 1 |
|||
EX DE,HL ; SAVE POINTER, PUT COUNT IN DE |
|||
XOR A ; CLEAR CARRY FLAG |
|||
SBC HL,BC ; DOES BYTE COUNTER = HL (NUMBER OF BYTES TO READ LESS 1) |
|||
EX DE,HL ; RESTORE POINTER |
|||
POP DE ; RESTORE COUNT |
|||
|
|||
; Z = YES IT IS |
|||
; NZ = NO IT ISN'T |
|||
JR NZ,PCF_RB4 |
|||
; |
|||
PCF_RB4:LD A,B ; IF FIRST READ DO A DUMMY |
|||
OR C ; READ OTHERWISE READ AND SAVE |
|||
JR NZ,PCF_RB5 |
|||
|
|||
IN A,(REGS0) ; DUMMY READ |
|||
JR PCF_RB6 |
|||
|
|||
PCF_RB5:IN A,(REGS0) ; READ AND SAVE |
|||
LD (HL),A |
|||
; |
|||
PCF_RB6: ; HAVE WE DONE ALL? |
|||
|
|||
PUSH DE ; SAVE COUNT |
|||
EX DE,HL ; SAVE POINTER, PUT COUNT IN DE |
|||
XOR A ; CLEAR CARRY FLAG |
|||
SBC HL,BC ; DOES BYTE COUNTER = HL (NUMBER OF BYTES TO READ) |
|||
EX DE,HL ; RESTORE POINTER |
|||
POP DE ; RESTORE COUNT |
|||
; |
|||
INC HL ; BUFFER POINTER |
|||
INC BC ; COUNT |
|||
; |
|||
JR NZ,PCF_RBL ; REPEAT UNTIL COUNTS MATCH |
|||
RET |
|||
; |
|||
PCF_RB2: ; TIMEOUT |
|||
CALL PCF_STOP |
|||
CALL PCF_TOERR |
|||
RET |
|||
; |
|||
PCF_RB3: ; LOST ARBITRATION |
|||
CALL PCF_ARBERR |
|||
RET |
|||
; |
|||
PCF_LBF: |
|||
.DB 0 ; LAST BYTE FLAG |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; READ ONE BYTE FROM I2C |
|||
; RETURNS DATA IN A |
|||
; Z FLAG SET IS ACKNOWLEDGE RECEIVED (CORRECT OPERATION) |
|||
; |
|||
PCF_READI2C: |
|||
IN A,(REGS1) ; READ S1 REGISTER |
|||
BIT 7,A ; CHECK PIN STATUS |
|||
JP NZ,PCF_READI2C |
|||
BIT 3,A ; CHECK LRB=0 |
|||
JP NZ,PCF_RDERR |
|||
IN A,(REGS0) ; GET DATA |
|||
RET |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; POLL THE BUS BUSY BIT TO DETERMINE IF BUS IS FREE. |
|||
; RETURN WITH A=00H/Z STATUS IF BUS IS FREE |
|||
; RETURN WITH A=FFH/NZ STATUS IF BUS |
|||
; |
|||
; AFTER RESET THE BUS BUSY BIT WILL BE SET TO 1 I.E. NOT BUSY |
|||
; |
|||
PCF_WAIT_FOR_BB: |
|||
LD HL,PCF_BBTO |
|||
PCF_WFBB0: |
|||
IN A,(REGS1) |
|||
AND PCF_BB |
|||
RET Z ; BUS IS FREE RETURN ZERO |
|||
DEC HL |
|||
LD A,H |
|||
OR L |
|||
JR NZ,PCF_WFBB0 ; REPEAT IF NOT TIMED OUT |
|||
CPL ; RET NZ IF TIMEOUT |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; DISPLAY ERROR MESSAGES |
|||
; |
|||
PCF_RDERR: |
|||
PUSH HL |
|||
LD HL,PCF_RDFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_INIERR: |
|||
PUSH HL |
|||
LD HL,PCF_NOPCF |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_SETERR: |
|||
PUSH HL |
|||
LD HL,PCF_WRTFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_REGERR: |
|||
PUSH HL |
|||
LD HL,PCF_REGFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_CLKERR: |
|||
PUSH HL |
|||
LD HL,PCF_CLKFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_IDLERR: |
|||
PUSH HL |
|||
LD HL,PCF_IDLFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_ACKERR: |
|||
PUSH HL |
|||
LD HL,PCF_ACKFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_RDBERR: |
|||
PUSH HL |
|||
LD HL,PCF_RDBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_TOERR: |
|||
PUSH HL |
|||
LD HL,PCF_TOFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_ARBERR: |
|||
PUSH HL |
|||
LD HL,PCF_ARBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_PINERR: |
|||
PUSH HL |
|||
LD HL,PCF_PINFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_BBERR: |
|||
PUSH HL |
|||
LD HL,PCF_BBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_PRTERR: |
|||
CALL PRTSTR |
|||
CALL NEWLINE |
|||
POP HL |
|||
RET |
|||
; |
|||
PCF_NOPCF .DB "NO DEVICE FOUND$" |
|||
PCF_WRTFAIL .DB "SETTING DEVICE ID FAILED$" |
|||
PCF_REGFAIL .DB "CLOCK REGISTER SELECT ERROR$" |
|||
PCF_CLKFAIL .DB "CLOCK SET FAIL$" |
|||
PCF_IDLFAIL .DB "BUS IDLE FAILED$" |
|||
PCF_ACKFAIL .DB "FAILED TO RECEIVE ACKNOWLEDGE$" |
|||
PCF_RDFAIL .DB "READ FAILED$" |
|||
PCF_RDBFAIL .DB "READBYTES FAILED$" |
|||
PCF_TOFAIL .DB "TIMEOUT ERROR$" |
|||
PCF_ARBFAIL .DB "LOST ARBITRATION$" |
|||
PCF_PINFAIL .DB "PIN FAIL$" |
|||
PCF_BBFAIL .DB "BUS BUSY$" |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
#INCLUDE "i2ccpm.inc" |
|||
; |
|||
.FILL 128 |
|||
DS7_LOC: |
|||
; |
|||
.END |
|||
@ -1,703 +0,0 @@ |
|||
;================================================================================================== |
|||
; PCF8584 I2C Clock Driver |
|||
;================================================================================================== |
|||
; |
|||
PCF_BASE .EQU 0F0H |
|||
PCF_ID .EQU 0AAH |
|||
CPU_CLK .EQU 12 |
|||
|
|||
REGS0 .EQU PCF_BASE |
|||
REGS1 .EQU REGS0+1 |
|||
PCF_OWN .EQU (PCF_ID >> 1) ; PCF'S ADDRESS IN SLAVE MODE |
|||
; |
|||
;T4LC512D .EQU 10100000B ; DEVICE IDENTIFIER |
|||
;T4LC512A1 .EQU 00000000B ; DEVICE ADDRESS |
|||
;T4LC512A2 .EQU 00001110B ; DEVICE ADDRESS |
|||
;T4LC512A3 .EQU 00000010B ; DEVICE ADDRESS |
|||
;T4LC512W .EQU 00000000B ; DEVICE WRITE |
|||
;T4LC512R .EQU 00000001B ; DEVICE READ |
|||
; |
|||
;I2CDEV1W .EQU (T4LC512D+T4LC512A1+T4LC512W) |
|||
;I2CDEV1R .EQU (T4LC512D+T4LC512A1+T4LC512R) |
|||
; |
|||
;I2CDEV2W .EQU (T4LC512D+T4LC512A2+T4LC512W) |
|||
;I2CDEV2R .EQU (T4LC512D+T4LC512A2+T4LC512R) |
|||
; |
|||
;I2CDEV3W .EQU (T4LC512D+T4LC512A3+T4LC512W) |
|||
;I2CDEV3R .EQU (T4LC512D+T4LC512A3+T4LC512R) |
|||
; |
|||
; CONTROL REGISTER BITS |
|||
; |
|||
PCF_PIN .EQU 10000000B |
|||
PCF_ES0 .EQU 01000000B |
|||
PCF_ES1 .EQU 00100000B |
|||
PCF_ES2 .EQU 00010000B |
|||
PCF_EN1 .EQU 00001000B |
|||
PCF_STA .EQU 00000100B |
|||
PCF_STO .EQU 00000010B |
|||
PCF_ACK .EQU 00000001B |
|||
; |
|||
PCF_START_ .EQU (PCF_PIN | PCF_ES0 | PCF_STA | PCF_ACK) |
|||
PCF_STOP_ .EQU (PCF_PIN | PCF_ES0 | PCF_STO | PCF_ACK) |
|||
PCF_REPSTART_ .EQU ( PCF_ES0 | PCF_STA | PCF_ACK) |
|||
PCF_IDLE_ .EQU (PCF_PIN | PCF_ES0 | PCF_ACK) |
|||
; |
|||
; STATUS REGISTER BITS |
|||
; |
|||
;PCF_PIN .EQU 10000000B |
|||
PCF_INI .EQU 01000000B ; 1 if not initialized |
|||
PCF_STS .EQU 00100000B |
|||
PCF_BER .EQU 00010000B |
|||
PCF_AD0 .EQU 00001000B |
|||
PCF_LRB .EQU 00001000B |
|||
PCF_AAS .EQU 00000100B |
|||
PCF_LAB .EQU 00000010B |
|||
PCF_BB .EQU 00000001B |
|||
; |
|||
; CLOCK CHIP FREQUENCIES |
|||
; |
|||
PCF_CLK3 .EQU 000H |
|||
PCF_CLK443 .EQU 010H |
|||
PCF_CLK6 .EQU 014H |
|||
PCF_CLK8 .EQU 018H |
|||
PCF_CLK12 .EQU 01cH |
|||
; |
|||
; TRANSMISSION FREQUENCIES |
|||
; |
|||
PCF_TRNS90 .EQU 000H ; 90 kHz */ |
|||
PCF_TRNS45 .EQU 001H ; 45 kHz */ |
|||
PCF_TRNS11 .EQU 002H ; 11 kHz */ |
|||
PCF_TRNS15 .EQU 003H ; 1.5 kHz */ |
|||
; |
|||
; TIMEOUT AND DELAY VALUES (ARBITRARY) |
|||
; |
|||
PCF_PINTO .EQU 65000 |
|||
PCF_ACKTO .EQU 65000 |
|||
PCF_BBTO .EQU 65000 |
|||
PCF_LABDLY .EQU 65000 |
|||
; |
|||
; DATA PORT REGISTERS |
|||
; |
|||
#IF (CPU_CLK = 443) |
|||
PCF_CLK .EQU PCF_CLK443 |
|||
#ELSE |
|||
#IF (CPU_CLK = 8) |
|||
PCF_CLK .EQU PCF_CLK8 |
|||
#ELSE |
|||
#IF (CPU_CLK = 12) |
|||
PCF_CLK .EQU PCF_CLK12 |
|||
#ELSE ***ERROR |
|||
#ENDIF |
|||
#ENDIF |
|||
#ENDIF |
|||
; |
|||
DS7_OUT .EQU 10000000B ; SELECT SQUARE WAVE FUNCTION |
|||
DS7_SQWE .EQU 00010000B ; ENABLE SQUARE WAVE OUTPUT |
|||
DS7_RATE .EQU 00000000B ; SET 1HZ OUPUT |
|||
; |
|||
DS7_DS1307 .EQU 11010000B ; DEVICE IDENTIFIER |
|||
DS7_W .EQU 00000000B ; DEVICE WRITE |
|||
DS7_R .EQU 00000001B ; DEVICE READ |
|||
; |
|||
DS7_READ .EQU (DS7_DS1307 | DS7_R) ; READ |
|||
DS7_WRITE .EQU (DS7_DS1307 | DS7_W) ; WRITE |
|||
; |
|||
DS7_CTL .EQU (DS7_OUT | DS7_SQWE | DS7_RATE) |
|||
; |
|||
.ORG 100H |
|||
; |
|||
; |
|||
CALL DS7_RDC ; READ CLOCK DATA INTO BUFFER |
|||
CALL DS7_DISP ; DISPLAY TIME AND DATE FROM BUFFER |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; RTC READ |
|||
; |
|||
; 1. ISSUE SLAVE ADDRESS WITH START CONDITION AND WRITE STATUS |
|||
; 2. OUTPUT THE ADDRESS TO ACCESS. (00H = START OF DS1307 REGISTERS) |
|||
; 3. OUTPUT REPEAT START TO TRANSITION TO READ PROCESS |
|||
; 4. ISSUE SLAVE ADDRESS WITH READ STATUS |
|||
; 5. DO A DUMMY READ |
|||
; 6. READ 8 BYTES STARTING AT ADDRESS PREVIOUSLY SET |
|||
; 7. END READ WITH NON-ACKNOWLEDGE |
|||
; 8. ISSUE STOP AND RELEASE BUS |
|||
; |
|||
DS7_RDC:LD A,DS7_WRITE ; SET SLAVE ADDRESS |
|||
OUT (REGS0),A |
|||
; |
|||
CALL PCF_WAIT_FOR_BB |
|||
JP NZ,PCF_BBERR |
|||
; |
|||
CALL PCF_START ; GENERATE START CONDITION |
|||
CALL PCF_WAIT_FOR_PIN; AND ISSUE THE SLAVE ADDRESS |
|||
CALL NZ,PCF_PINERR |
|||
; |
|||
LD A,0 |
|||
OUT (REGS0),A ; PUT ADDRESS MSB ON BUS |
|||
CALL PCF_WAIT_FOR_PIN |
|||
CALL NZ,PCF_PINERR |
|||
; |
|||
CALL PCF_REPSTART ; REPEAT START |
|||
; |
|||
LD A,DS7_READ ; ISSUE CONTROL BYTE + READ |
|||
OUT (REGS0),A |
|||
; |
|||
CALL PCF_READI2C ; DUMMY READ |
|||
; |
|||
LD HL,DS7_BUF ; READ 8 BYTES INTO BUFFER |
|||
LD B,8 |
|||
DS7_RL1:CALL PCF_READI2C |
|||
LD (HL),A |
|||
INC HL |
|||
DJNZ DS7_RL1 |
|||
; |
|||
#IF (0) |
|||
LD A,8 |
|||
LD DE,DS7_BUF ; DISLAY DATA READ |
|||
CALL PRTHEXBUF ; |
|||
CALL NEWLINE |
|||
#ENDIF |
|||
; |
|||
LD A,PCF_ES0 ; END WITH NOT-ACKNOWLEDGE |
|||
OUT (REGS1),A ; AND RELEASE BUS |
|||
NOP |
|||
IN A,(REGS0) |
|||
NOP |
|||
DS7_WTPIN: |
|||
IN A,(REGS1) ; READ S1 REGISTER |
|||
BIT 7,A ; CHECK PIN STATUS |
|||
JP NZ,DS7_WTPIN |
|||
CALL PCF_STOP |
|||
; |
|||
IN A,(REGS0) |
|||
RET |
|||
|
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; DISPLAY CLOCK INFORMATION FROM DATA STORED IN BUFFER |
|||
; |
|||
DS7_DISP: |
|||
LD HL,DS7_CLKTBL |
|||
DS7_CLP:LD C,(HL) |
|||
INC HL |
|||
LD D,(HL) |
|||
CALL DS7_BCD |
|||
INC HL |
|||
LD A,(HL) |
|||
OR A |
|||
RET Z |
|||
CALL COUT |
|||
INC HL |
|||
JR DS7_CLP |
|||
RET |
|||
; |
|||
DS7_CLKTBL: |
|||
.DB 04H, 00111111B, '/' |
|||
.DB 05H, 00011111B, '/' |
|||
.DB 06H, 11111111B, ' ' |
|||
.DB 02H, 00011111B, ':' |
|||
.DB 01H, 01111111B, ':' |
|||
.DB 00H, 01111111B, 00H |
|||
; |
|||
DS7_BCD:PUSH HL |
|||
LD HL,DS7_BUF ; READ VALUE FROM |
|||
LD B,0 ; BUFFER, INDEXED BY A |
|||
ADD HL,BC |
|||
LD A,(HL) |
|||
AND D ; MASK OFF UNNEEDED |
|||
SRL A |
|||
SRL A |
|||
SRL A |
|||
SRL A |
|||
ADD A,30H |
|||
CALL COUT |
|||
LD A,(HL) |
|||
AND 00001111B |
|||
ADD A,30H |
|||
CALL COUT |
|||
POP HL |
|||
RET |
|||
; |
|||
DS7_BUF: .FILL 8,0 ; BUFFER FOR TIME, DATE AND CONTROL |
|||
|
|||
;----------------------------------------------------------------------------- |
|||
PCF_START: |
|||
LD A,PCF_START_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
PCF_REPSTART: |
|||
LD A,PCF_REPSTART_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
PCF_STOP: |
|||
LD A,PCF_STOP_ |
|||
OUT (REGS1),A |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
;; |
|||
PCF_INIT: |
|||
LD A,PCF_PIN ; S1=80H: S0 SELECTED, SERIAL |
|||
OUT (REGS1),A ; INTERFACE OFF |
|||
NOP |
|||
IN A,(REGS1) ; CHECK TO SEE S1 NOW USED AS R/W |
|||
AND 07FH ; CTRL. PCF8584 DOES THAT WHEN ESO |
|||
JP NZ,PCF_INIERR ; IS ZERO |
|||
; |
|||
LD A,PCF_OWN ; LOAD OWN ADDRESS IN S0, |
|||
OUT (REGS0),A ; EFFECTIVE ADDRESS IS (OWN <<1) |
|||
NOP |
|||
IN A,(REGS0) ; CHECK IT IS REALLY WRITTEN |
|||
CP PCF_OWN |
|||
JP NZ,PCF_SETERR |
|||
; |
|||
LD A,+(PCF_PIN | PCF_ES1) ; S1=0A0H |
|||
OUT (REGS1),A ; NEXT BYTE IN S2 |
|||
NOP |
|||
IN A,(REGS1) |
|||
AND 07FH |
|||
CP PCF_ES1 |
|||
JP NZ,PCF_REGERR |
|||
; |
|||
LD A,PCF_CLK ; LOAD CLOCK REGISTER S2 |
|||
OUT (REGS0),A |
|||
NOP |
|||
IN A,(REGS0) ; CHECK IT'S REALLY WRITTEN, ONLY |
|||
AND 1FH ; THE LOWER 5 BITS MATTER |
|||
CP PCF_CLK |
|||
JP NZ,PCF_CLKERR |
|||
; |
|||
LD A,PCF_IDLE_ |
|||
OUT (REGS1),A |
|||
NOP |
|||
IN A,(REGS1) |
|||
CP +(PCF_PIN | PCF_BB) |
|||
JP NZ,PCF_IDLERR |
|||
; |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
PCF_HANDLE_LAB: |
|||
; |
|||
LD A,PCF_PIN |
|||
OUT (REGS1),A |
|||
LD A,PCF_ES0 |
|||
OUT (REGS1),A |
|||
; |
|||
LD HL,PCF_LABDLY |
|||
PCF_LABLP: |
|||
LD A,H |
|||
OR L |
|||
DEC HL |
|||
JR NZ,PCF_LABLP |
|||
; |
|||
IN A,(REGS1) |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; RETURN A=00/Z IF SUCCESSFULL |
|||
; RETURN A=FF/NZ IF TIMEOUT |
|||
; RETURN A=01/NZ IF LOST ARBITRATION |
|||
; PCF_STATUS HOLDS LAST PCF STATUS |
|||
; |
|||
PCF_WAIT_FOR_PIN: |
|||
PUSH HL |
|||
LD HL,PCF_PINTO ; SET TIMEOUT VALUE |
|||
|
|||
PCF_WFP0: |
|||
IN A,(REGS1) ; GET BUS |
|||
LD (PCF_STATUS),A ; STATUS |
|||
LD B,A |
|||
|
|||
DEC HL ; HAVE WE |
|||
LD A,H ; TIMED OUT |
|||
OR L |
|||
JR Z,PCF_WFP1 ; YES WE HAVE, GO ACTION IT |
|||
|
|||
LD A,B ; |
|||
AND PCF_PIN ; IS TRANSMISSION COMPLETE? |
|||
JR NZ,PCF_WFP0 ; KEEP ASKING IF NOT OR |
|||
POP HL ; YES COMPLETE (PIN=0) RETURN WITH ZERO |
|||
RET |
|||
PCF_WFP1: |
|||
LD A,B ; DID WE LOSE ARBITRATION? |
|||
AND PCF_LAB ; IF A=0 THEN NO |
|||
CPL |
|||
JR NZ,PCF_WFP2 ; NO |
|||
CALL PCF_HANDLE_LAB ; YES GO HANDLE IT |
|||
LD (PCF_STATUS),A |
|||
XOR A ; RETURN NZ, A=01H |
|||
INC A |
|||
PCF_WFP2: |
|||
POP HL ; RET NZ, A=FF IF TIMEOUT |
|||
RET |
|||
; |
|||
PCF_STATUS .DB 00H |
|||
|
|||
;-------------------------------------------------------------------------------- |
|||
; |
|||
; RETURN NZ/FF IF TIMEOUT ERROR |
|||
; RETURN NZ/01 IF FAILED TO RECEIVE ACKNOWLEDGE |
|||
; RETURN Z/00 IF RECEIVED ACKNOWLEDGE |
|||
; |
|||
PCF_WAIT_FOR_ACK: |
|||
PUSH HL |
|||
LD HL,PCF_ACKTO |
|||
; |
|||
PCF_WFA0: |
|||
IN A,(REGS1) ; READ PIN |
|||
LD (PCF_STATUS),A ; STATUS |
|||
LD B,A |
|||
; |
|||
DEC HL ; SEE IF WE HAVE TIMED |
|||
LD A,H ; OUT WAITING FOR PIN |
|||
OR L ; EXIT IF |
|||
JR Z,PCF_WFA1 ; WE HAVE |
|||
; |
|||
LD A,B ; OTHERWISE KEEP LOOPING |
|||
AND PCF_PIN ; UNTIL WE GET PIN |
|||
JR NZ,PCF_WFA0 ; OR TIMEOUT |
|||
; |
|||
LD A,B ; WE GOT PIN SO NOW |
|||
AND PCF_LRB ; CHECK WE HAVE |
|||
LD A,1 |
|||
JR Z,PCF_WFA2 ; RECEIVED ACKNOWLEDGE |
|||
XOR A |
|||
JR PCF_WFA2 |
|||
PCF_WFA1: |
|||
CPL ; TIMOUT ERROR |
|||
PCF_WFA2: |
|||
POP HL ; EXIT WITH NZ = FF |
|||
RET |
|||
; |
|||
;-------------------------------------------------------------------------------- |
|||
; |
|||
; HL POINTS TO DATA |
|||
; DE = COUNT |
|||
; A = 0 LAST A=1 NOT LAST |
|||
; |
|||
; |
|||
;PCF_READBYTES: ; NOT FUNCTIONAL YET |
|||
|
|||
LD (PCF_LBF),A ; SAVE LAST BYTE FLAG |
|||
; |
|||
INC DE ; INCREMENT NUMBER OF BYTES TO READ BY ONE -- DUMMY READ BYTE |
|||
LD BC,0 ; SET BYTE COUNTER |
|||
; |
|||
PCF_RBL:PUSH BC |
|||
CALL PCF_WAIT_FOR_PIN ; DO WE HAVE THE BUS? |
|||
POP BC |
|||
JR Z,PCF_RB1 ; YES |
|||
CP 01H |
|||
JR Z,PCF_RB3 ; NO - LOST ARBITRATION |
|||
JR PCF_RB2 ; NO - TIMEOUT |
|||
; |
|||
PCF_RB1: |
|||
LD A,(PCF_STATUS) |
|||
AND PCF_LRB |
|||
|
|||
|
|||
; IS THIS THE SECOND TO LAST BYTE TO GO? |
|||
|
|||
PUSH DE ; SAVE COUNT |
|||
DEC DE ; COUNT (DE) = NUMBER OF BYTES TO READ LESS 1 |
|||
EX DE,HL ; SAVE POINTER, PUT COUNT IN DE |
|||
XOR A ; CLEAR CARRY FLAG |
|||
SBC HL,BC ; DOES BYTE COUNTER = HL (NUMBER OF BYTES TO READ LESS 1) |
|||
EX DE,HL ; RESTORE POINTER |
|||
POP DE ; RESTORE COUNT |
|||
|
|||
; Z = YES IT IS |
|||
; NZ = NO IT ISN'T |
|||
JR NZ,PCF_RB4 |
|||
; |
|||
PCF_RB4:LD A,B ; IF FIRST READ DO A DUMMY |
|||
OR C ; READ OTHERWISE READ AND SAVE |
|||
JR NZ,PCF_RB5 |
|||
|
|||
IN A,(REGS0) ; DUMMY READ |
|||
JR PCF_RB6 |
|||
|
|||
PCF_RB5:IN A,(REGS0) ; READ AND SAVE |
|||
LD (HL),A |
|||
; |
|||
PCF_RB6: ; HAVE WE DONE ALL? |
|||
|
|||
PUSH DE ; SAVE COUNT |
|||
EX DE,HL ; SAVE POINTER, PUT COUNT IN DE |
|||
XOR A ; CLEAR CARRY FLAG |
|||
SBC HL,BC ; DOES BYTE COUNTER = HL (NUMBER OF BYTES TO READ) |
|||
EX DE,HL ; RESTORE POINTER |
|||
POP DE ; RESTORE COUNT |
|||
; |
|||
INC HL ; BUFFER POINTER |
|||
INC BC ; COUNT |
|||
; |
|||
JR NZ,PCF_RBL ; REPEAT UNTIL COUNTS MATCH |
|||
RET |
|||
; |
|||
PCF_RB2: ; TIMEOUT |
|||
CALL PCF_STOP |
|||
CALL PCF_TOERR |
|||
RET |
|||
; |
|||
PCF_RB3: ; LOST ARBITRATION |
|||
CALL PCF_ARBERR |
|||
RET |
|||
; |
|||
PCF_LBF: |
|||
.DB 0 ; LAST BYTE FLAG |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; READ ONE BYTE FROM I2C |
|||
; RETURNS DATA IN A |
|||
; Z FLAG SET IS ACKNOWLEDGE RECEIVED (CORRECT OPERATION) |
|||
; |
|||
PCF_READI2C: |
|||
IN A,(REGS1) ; READ S1 REGISTER |
|||
BIT 7,A ; CHECK PIN STATUS |
|||
JP NZ,PCF_READI2C |
|||
BIT 3,A ; CHECK LRB=0 |
|||
JP NZ,PCF_RDERR |
|||
IN A,(REGS0) ; GET DATA |
|||
RET |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
; POLL THE BUS BUSY BIT TO DETERMINE IF BUS IS FREE. |
|||
; RETURN WITH A=00H/Z STATUS IF BUS IS FREE |
|||
; RETURN WITH A=FFH/NZ STATUS IF BUS |
|||
; |
|||
; AFTER RESET THE BUS BUSY BIT WILL BE SET TO 1 I.E. NOT BUSY |
|||
; |
|||
PCF_WAIT_FOR_BB: |
|||
LD HL,PCF_BBTO |
|||
PCF_WFBB0: |
|||
IN A,(REGS1) |
|||
AND PCF_BB |
|||
RET Z ; BUS IS FREE RETURN ZERO |
|||
DEC HL |
|||
LD A,H |
|||
OR L |
|||
JR NZ,PCF_WFBB0 ; REPEAT IF NOT TIMED OUT |
|||
CPL ; RET NZ IF TIMEOUT |
|||
RET |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; DISPLAY ERROR MESSAGES |
|||
; |
|||
PCF_RDERR: |
|||
PUSH HL |
|||
LD HL,PCF_RDFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_INIERR: |
|||
PUSH HL |
|||
LD HL,PCF_NOPCF |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_SETERR: |
|||
PUSH HL |
|||
LD HL,PCF_WRTFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_REGERR: |
|||
PUSH HL |
|||
LD HL,PCF_REGFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_CLKERR: |
|||
PUSH HL |
|||
LD HL,PCF_CLKFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_IDLERR: |
|||
PUSH HL |
|||
LD HL,PCF_IDLFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_ACKERR: |
|||
PUSH HL |
|||
LD HL,PCF_ACKFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_RDBERR: |
|||
PUSH HL |
|||
LD HL,PCF_RDBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_TOERR: |
|||
PUSH HL |
|||
LD HL,PCF_TOFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_ARBERR: |
|||
PUSH HL |
|||
LD HL,PCF_ARBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_PINERR: |
|||
PUSH HL |
|||
LD HL,PCF_PINFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_BBERR: |
|||
PUSH HL |
|||
LD HL,PCF_BBFAIL |
|||
JR PCF_PRTERR |
|||
; |
|||
PCF_PRTERR: |
|||
CALL PRTSTR |
|||
CALL NEWLINE |
|||
POP HL |
|||
RET |
|||
; |
|||
PCF_NOPCF .DB "NO DEVICE FOUND$" |
|||
PCF_WRTFAIL .DB "SETTING DEVICE ID FAILED$" |
|||
PCF_REGFAIL .DB "CLOCK REGISTER SELECT ERROR$" |
|||
PCF_CLKFAIL .DB "CLOCK SET FAIL$" |
|||
PCF_IDLFAIL .DB "BUS IDLE FAILED$" |
|||
PCF_ACKFAIL .DB "FAILED TO RECEIVE ACKNOWLEDGE$" |
|||
PCF_RDFAIL .DB "READ FAILED$" |
|||
PCF_RDBFAIL .DB "READBYTES FAILED$" |
|||
PCF_TOFAIL .DB "TIMEOUT ERROR$" |
|||
PCF_ARBFAIL .DB "LOST ARBITRATION$" |
|||
PCF_PINFAIL .DB "PIN FAIL$" |
|||
PCF_BBFAIL .DB "BUS BUSY$" |
|||
; |
|||
;----------------------------------------------------------------------------- |
|||
; |
|||
BDOS .EQU 5 ;ENTRY BDOS |
|||
BS .EQU 8 ;BACKSPACE |
|||
TAB .EQU 9 ;TABULATOR |
|||
LF .EQU 0AH ;LINE-FEED |
|||
CR .EQU 0DH ;CARRIAGE-RETURN |
|||
; |
|||
; OUTPUT TEXT AT HL |
|||
; |
|||
PRTSTR: LD A,(HL) |
|||
OR A |
|||
RET Z |
|||
CALL PRINP |
|||
INC HL |
|||
JR PRTSTR |
|||
; |
|||
;Output WORD |
|||
;*********** |
|||
; |
|||
;PARAMETER: Entry WORD IN HL |
|||
;********* |
|||
; |
|||
OUTW: LD A,H |
|||
CALL OUTB |
|||
LD A,L |
|||
CALL OUTB |
|||
RET |
|||
; |
|||
;Output BYTE |
|||
;*********** |
|||
; |
|||
;PARAMETER: Entry BYTE IN A |
|||
;********* |
|||
; |
|||
OUTB: PUSH AF |
|||
RRCA |
|||
RRCA |
|||
RRCA |
|||
RRCA |
|||
AND 0FH |
|||
CALL HBTHE ;Change Half-BYTE |
|||
POP AF |
|||
AND 0FH |
|||
CALL HBTHE |
|||
RET |
|||
; |
|||
;Output HALF-BYTE |
|||
;**************** |
|||
; |
|||
;PARAMETER: Entry Half-BYTE IN A (BIT 0 - 3) |
|||
;********* |
|||
; |
|||
HBTHE: CP 0AH |
|||
JR C,HBTHE1 |
|||
ADD A,7 ;Character to Letter |
|||
HBTHE1: ADD A,30H |
|||
LD E,A |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
; |
|||
;Output on Screen |
|||
;**************** |
|||
; |
|||
PRBS: LD E,BS |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
;Output CR+LF on Screen |
|||
;********************** |
|||
; |
|||
NEWLINE: |
|||
CRLF: LD E,CR |
|||
CALL PCHAR |
|||
LD E,LF |
|||
CALL PCHAR |
|||
RET |
|||
; |
|||
;Output ASCII-Character |
|||
;********************** |
|||
; |
|||
COUT: |
|||
PRINP: PUSH AF |
|||
PUSH DE |
|||
LD E,A |
|||
CALL PCHAR |
|||
POP DE |
|||
POP AF |
|||
RET |
|||
; |
|||
;CALL BDOS with Register Save |
|||
;**************************** |
|||
; |
|||
INCHA: LD C,1 ;INPUT CHARACTER TO A |
|||
JR BDO |
|||
PCHAR: LD C,2 ;PRINT CHARACTER IN E |
|||
JR BDO |
|||
PSTRIN: LD C,9 ;PRINT STRING |
|||
JR BDO |
|||
INBUFF: LD C,10 ;READ CONSOLE-BUFFER |
|||
JR BDO |
|||
CSTS: LD C,11 ;CONSOLE-STATUS |
|||
JR BDO |
|||
OPEN: LD C,15 ;OPEN FILE |
|||
JR BDO |
|||
CLOSE: LD C,16 ;CLOSE FILE |
|||
JR BDO |
|||
DELETE: LD C,19 ;DELETE FILE |
|||
JR BDO |
|||
READS: LD C,20 ;READ SEEK |
|||
JR BDO |
|||
WRITES: LD C,21 ;WRITE SEEK |
|||
JR BDO |
|||
MAKE: LD C,22 ;MAKE FILE |
|||
JR BDO |
|||
SETDMA: LD C,26 ;SET DMA-ADDRESS |
|||
BDO: PUSH HL |
|||
PUSH DE |
|||
PUSH BC |
|||
PUSH IX |
|||
PUSH IY |
|||
CALL BDOS |
|||
POP IY |
|||
POP IX |
|||
POP BC |
|||
POP DE |
|||
POP HL |
|||
RET |
|||
; |
|||
.END |
|||
@ -0,0 +1,324 @@ |
|||
;================================================================================================== |
|||
; Z80 DMA DRIVER FOR ECB-DMA |
|||
;================================================================================================== |
|||
; |
|||
; DUE TO LOW CLOCK SPEED CONTRAINTS OF Z80 DMA CHIP, THE HALF CLOCK FACILITY |
|||
; IS USED DURING DMA PROGRAMMING AND CONTINUOUS BLOCK TRANSFERS. |
|||
; TESTING CONDUCTED ON A SBC-V2-005 @ 10Mhz |
|||
; |
|||
DMA_CONTINUOUS .equ %10111101 ; + Pulse |
|||
DMA_BYTE .equ %10011101 ; + Pulse |
|||
DMA_BURST .equ %11011101 ; + Pulse |
|||
DMA_LOAD .equ $cf ; %11001111 |
|||
DMA_ENABLE .equ $87 ; %10000111 |
|||
DMA_FORCE_READY .equ $b3 |
|||
DMA_DISABLE .equ $83 |
|||
DMA_START_READ_SEQUENCE .equ $a7 |
|||
DMA_READ_STATUS_BYTE .equ $bf |
|||
DMA_READ_MASK_FOLLOWS .equ $bb |
|||
DMA_RESET .equ $c3 |
|||
;DMA_RESET_PORT_A_TIMING .equ $c7 |
|||
;DMA_RESET_PORT_B_TIMING .equ $cb |
|||
;DMA_CONTINUE .equ $d3 |
|||
;DMA_DISABLE_INTERUPTS .equ $af |
|||
;DMA_ENABLE_INTERUPTS .equ $ab |
|||
;DMA_RESET_DISABLE_INTERUPTS .equ $a3 |
|||
;DMA_ENABLE_AFTER_RETI .equ $b7 |
|||
;DMA_REINIT_STATUS_BYTE .equ $8b |
|||
; |
|||
;================================================================================================== |
|||
; DMA INITIALIZATION CODE |
|||
;================================================================================================== |
|||
; |
|||
DMA_INIT: |
|||
CALL NEWLINE |
|||
PRTS("DMA: IO=0x$") ; announce |
|||
LD A, DMABASE |
|||
CALL PRTHEXBYTE |
|||
; |
|||
xor a |
|||
out (DMABASE+1),a ; force ready off |
|||
; |
|||
ld a,(RTCVAL) |
|||
or %00001000 ; half |
|||
out (RTCIO),a ; clock |
|||
; |
|||
call DMAProbe ; do we have a dma? |
|||
jr nz,DMA_NOTFOUND |
|||
; |
|||
ld hl,DMACode ; program the |
|||
ld b,DMACode_Len ; dma command |
|||
ld c,DMABASE ; block |
|||
; |
|||
di |
|||
otir ; load dma |
|||
ei |
|||
xor a ; set status |
|||
; |
|||
DMA_EXIT: |
|||
push af |
|||
ld a,(RTCVAL) |
|||
and %11110111 ; full |
|||
out (RTCIO),a ; clock |
|||
pop af |
|||
ret |
|||
; |
|||
DMA_NOTFOUND: |
|||
push af |
|||
call PRTSTRD |
|||
.db " NOT PRESENT$" |
|||
pop af |
|||
jr DMA_EXIT |
|||
|
|||
; |
|||
;================================================================================================== |
|||
; DMA PROBE - WRITE TO ADDRESS REGISTER AND READ BACK |
|||
;================================================================================================== |
|||
; |
|||
DMAProbe: |
|||
ld a,DMA_RESET |
|||
out (DMABASE),a |
|||
ld a,%01111101 ; R0-Transfer mode, A -> B, start address follows |
|||
out (DMABASE),a |
|||
ld a,$cc |
|||
out (DMABASE),a |
|||
ld a,$dd |
|||
out (DMABASE),a |
|||
ld a,$e5 |
|||
out (DMABASE),a |
|||
ld a,$1a |
|||
out (DMABASE),a |
|||
ld a,DMA_LOAD |
|||
out (DMABASE),a |
|||
; |
|||
ld a,DMA_READ_MASK_FOLLOWS ; set up |
|||
out (DMABASE),a ; for |
|||
ld a,%00011000 ; register |
|||
out (DMABASE),a ; read |
|||
ld a,DMA_START_READ_SEQUENCE |
|||
out (DMABASE),a |
|||
; |
|||
in a,(DMABASE) ; read in |
|||
ld c,a ; address |
|||
in a,(DMABASE) |
|||
ld b,a |
|||
; |
|||
xor a ; is it |
|||
ld hl,$ddcc ; a match |
|||
sbc hl,bc ; return with |
|||
ret z ; status |
|||
cpl |
|||
ret |
|||
; |
|||
DMACode ;.db DMA_DISABLE ; R6-Command Disable DMA |
|||
.db %01111101 ; R0-Transfer mode, A -> B, start address, block length follow |
|||
.dw 0 ; R0-Port A, Start address |
|||
.dw 0 ; R0-Block length |
|||
.db %00010100 ; R1-No timing bytes follow, address increments, is memory |
|||
.db %00010000 ; R2-No timing bytes follow, address increments, is memory |
|||
.db %10000000 ; R3-DMA, interrupt, stop on match disabled |
|||
.db DMA_CONTINUOUS ; R4-Continuous mode, destination address, interrupt and control byte follow |
|||
.dw 0 ; R4-Port B, Destination address |
|||
.db %00001100 ; R4-Pulse byte follows, Pulse generated |
|||
.db 0 ; R4-Pulse offset |
|||
.db %10011010 ; R5-Stop on end of block, ce/wait multiplexed, READY active HIGH |
|||
.db DMA_LOAD ; R6-Command Load |
|||
; .db DMA_FORCE_READY ; R6-Command Force ready |
|||
; .db DMA_ENABLE ; R6-Command Enable DMA |
|||
DMACode_Len .equ $-DMACode |
|||
; |
|||
;================================================================================================== |
|||
; DMA COPY BLOCK CODE - ASSUMES DMA PREINITIALIZED |
|||
;================================================================================================== |
|||
; |
|||
DMALDIR: |
|||
ld (DMASource),hl ; populate the dma |
|||
ld (DMADest),de ; register template |
|||
ld (DMALength),bc |
|||
; |
|||
ld hl,DMACopy ; program the |
|||
ld b,DMACopy_Len ; dma command |
|||
ld c,DMABASE ; block |
|||
; |
|||
ld a,(RTCVAL) |
|||
or %00001000 ; half |
|||
out (RTCIO),a ; clock |
|||
di |
|||
otir ; load and execute dma |
|||
ei |
|||
; |
|||
ld a,DMA_READ_STATUS_BYTE ; check status |
|||
out (DMABASE),a ; of transfer |
|||
in a,(DMABASE) ; set non-zero |
|||
and %00111011 ; if failed |
|||
sub %00011011 |
|||
|
|||
push af |
|||
ld a,(RTCVAL) |
|||
and %11110111 ; full |
|||
out (RTCIO),a ; clock |
|||
pop af |
|||
ret |
|||
; |
|||
DMACopy ;.db DMA_DISABLE ; R6-Command Disable DMA |
|||
.db %01111101 ; R0-Transfer mode, A -> B, start address, block length follow |
|||
DMASource .dw 0 ; R0-Port A, Start address |
|||
DMALength .dw 0 ; R0-Block length |
|||
.db %00010100 ; R1-No timing bytes follow, address increments, is memory |
|||
.db %00010000 ; R2-No timing bytes follow, address increments, is memory |
|||
.db %10000000 ; R3-DMA, interrupt, stop on match disabled |
|||
.db DMA_CONTINUOUS ; R4-Continuous mode, destination address, interrupt and control byte follow |
|||
DMADest .dw 0 ; R4-Port B, Destination address |
|||
.db %00001100 ; R4-Pulse byte follows, Pulse generated |
|||
.db 0 ; R4-Pulse offset |
|||
; .db %10011010 ; R5-Stop on end of block, ce/wait multiplexed, READY active HIGH |
|||
.db DMA_LOAD ; R6-Command Load |
|||
.db DMA_FORCE_READY ; R6-Command Force ready |
|||
.db DMA_ENABLE ; R6-Command Enable DMA |
|||
DMACopy_Len .equ $-DMACopy |
|||
; |
|||
;================================================================================================== |
|||
; DMA I/O OUT BLOCK CODE - ADDRESS TO I/O PORT |
|||
;================================================================================================== |
|||
; |
|||
DMAOTIR: |
|||
ld (DMAOutSource),hl ; populate the dma |
|||
ld (DMAOutDest),a ; register template |
|||
ld (DMAOutLength),bc |
|||
; |
|||
ld hl,DMAOutCode ; program the |
|||
ld b,DMAOut_Len ; dma command |
|||
ld c,DMABASE ; block |
|||
; |
|||
ld a,(RTCVAL) |
|||
or %00001000 ; half |
|||
out (RTCIO),a ; clock |
|||
di |
|||
otir ; load and execute dma |
|||
ei |
|||
; |
|||
ld a,DMA_READ_STATUS_BYTE ; check status |
|||
out (DMABASE),a ; of transfer |
|||
in a,(DMABASE) ; set non-zero |
|||
and %00111011 ; if failed |
|||
sub %00011011 |
|||
; |
|||
push af |
|||
ld a,(RTCVAL) |
|||
and %11110111 ; full |
|||
out (RTCIO),a ; clock |
|||
pop af |
|||
ret |
|||
; |
|||
DMAOutCode ;.db DMA_DISABLE ; R6-Command Disable DMA |
|||
.db %01111001 ; R0-Transfer mode, B -> A (temp), start address, block length follow |
|||
DMAOutSource .dw 0 ; R0-Port A, Start address |
|||
DMAOutLength .dw 0 ; R0-Block length |
|||
|
|||
.db %00010100 ; R1-No timing bytes follow, fixed incrementing address, is memory |
|||
.db %00101000 ; R2-No timing bytes follow, address static, is i/o |
|||
.db %10000000 ; R3-DMA, interrupt, stop on match disabled |
|||
|
|||
.db %10100101 ; R4-Continuous mode, destination port, interrupt and control byte follow |
|||
DMAOutDest .db 0 ; R4-Port B, Destination port |
|||
; .db %00001100 ; R4-Pulse byte follows, Pulse generated |
|||
; .db 0 ; R4-Pulse offset |
|||
|
|||
.db %10011010 ; R5-Stop on end of block, ce/wait multiplexed, READY active HIGH |
|||
.db DMA_LOAD ; R6-Command Load |
|||
.db %00000101 ; R0-Port A is Source |
|||
.db DMA_LOAD ; R6-Command Load |
|||
.db DMA_FORCE_READY ; R6-Command Force ready |
|||
.db DMA_ENABLE ; R6-Command Enable DMA |
|||
DMAOut_Len .equ $-DMAOutCode |
|||
; |
|||
;================================================================================================== |
|||
; DMA I/O INPUT BLOCK CODE - I/O PORT TO ADDRESS |
|||
;================================================================================================== |
|||
; |
|||
DMAINIR: |
|||
ld (DMAInDest),hl ; populate the dma |
|||
ld (DMAInSource),a ; register template |
|||
ld (DMAInLength),bc |
|||
; |
|||
ld hl,DMAInCode ; program the |
|||
ld b,DMAIn_Len ; dma command |
|||
ld c,DMABASE ; block |
|||
; |
|||
ld a,(RTCVAL) |
|||
or %00001000 ; half |
|||
out (RTCIO),a ; clock |
|||
di |
|||
otir ; load and execute dma |
|||
ei |
|||
; |
|||
ld a,DMA_READ_STATUS_BYTE ; check status |
|||
out (DMABASE),a ; of transfer |
|||
in a,(DMABASE) ; set non-zero |
|||
and %00111011 ; if failed |
|||
sub %00011011 |
|||
; |
|||
push af |
|||
ld a,(RTCVAL) |
|||
and %11110111 ; full |
|||
out (RTCIO),a ; clock |
|||
pop af |
|||
ret |
|||
; |
|||
DMAInCode ;.db DMA_DISABLE ; R6-Command Disable DMA |
|||
.db %01111001 ; R0-Transfer mode, B -> A, start address, block length follow |
|||
DMAInDest .dw 0 ; R0-Port A, Start address |
|||
DMAInLength .dw 0 ; R0-Block length |
|||
.db %00010100 ; R1-No timing bytes follow, address increments, is memory |
|||
.db %00111000 ; R2-No timing bytes follow, address static, is i/o |
|||
.db %10000000 ; R3-DMA, interrupt, stop on match disabled |
|||
.db %10100101 ; R4-Continuous mode, destination port, no interrupt, control byte. |
|||
DMAInSource .db 0 ; R4-Port B, Destination port |
|||
; .db %00001100 ; R4-Pulse byte follows, Pulse generated |
|||
; .db 0 ; R4-Pulse offset |
|||
.db %10011010 ; R5-Stop on end of block, ce/wait multiplexed, READY active HIGH |
|||
.db DMA_LOAD ; R6-Command Load |
|||
.db DMA_FORCE_READY ; R6-Command Force ready |
|||
.db DMA_ENABLE ; R6-Command Enable DMA |
|||
|
|||
DMAIn_Len .equ $-DMAInCode |
|||
; |
|||
;================================================================================================== |
|||
; DEBUG - READ START, DESTINATION AN COUNT REGISTERS |
|||
;================================================================================================== |
|||
; |
|||
#IF (0) |
|||
; |
|||
DMARegDump: |
|||
ld a,DMA_READ_MASK_FOLLOWS |
|||
out (DMABASE),a |
|||
ld a,%01111110 |
|||
out (DMABASE),a |
|||
ld a,DMA_START_READ_SEQUENCE |
|||
out (DMABASE),a |
|||
; |
|||
in a,(DMABASE) |
|||
ld c,a |
|||
in a,(DMABASE) |
|||
ld b,a |
|||
call PRTHEXWORD |
|||
ld a,':' |
|||
call COUT |
|||
; |
|||
in a,(DMABASE) |
|||
ld c,a |
|||
in a,(DMABASE) |
|||
ld b,a |
|||
call PRTHEXWORD |
|||
ld a,':' |
|||
call COUT |
|||
; |
|||
in a,(DMABASE) |
|||
ld c,a |
|||
in a,(DMABASE) |
|||
ld b,a |
|||
call PRTHEXWORD |
|||
; |
|||
call NEWLINE |
|||
ret |
|||
#ENDIF |
|||
Loading…
Reference in new issue