ICT archeology: Z80 assembler code

Home


CV in english

CV in italian


Photoalbum

Favorite links

Download


64bit corner

Acer 7720G

Acer 6930G

Z80


True3D*Shell

3D hand study

3D Depth sort

Raddy project

MQ4CPP project

 

This is a my project of 15 years ago based on Z80 chipset. The project aimed to buid a system to receive and transmit packets throught a PCM-30 8bit timeslot using a SIO device. The Z80 CPU was connected to an host throught a dual port RAM.

You can find more informations about Zilog Z80 on this website




This is a include file to define common symbols for other modules
NLIST ; ;******************* ;** STARLET.INC ** ;******************* ; ;Define phisical devices I/O address indirizzi fisici periferiche ; PIODA: EQU 0 PIODB: EQU 1 PIOCA: EQU 2 PIOCB: EQU 3 SIODA: EQU 4 SIODB: EQU 5 SIOCA: EQU 6 SIOCB: EQU 7 CTC0: EQU 0CH CTC1: EQU 0DH CTC2: EQU 0EH CTC3: EQU 0FH DPRAM1: EQU 4000H ; SIOA$SIOD: EQU SIODA SIOA$SIOC: EQU SIOCA SIOB$SIOD: EQU SIODB SIOB$SIOC: EQU SIOCB SIOA$CTCB: EQU CTC0 SIOA$CTCI: EQU CTC2 SIOB$CTCB: EQU CTC1 SIOB$CTCI: EQU CTC3 ; ;Definizioni per baud rate ; BR19200: EQU 1 BR9600: EQU 2 BR4800: EQU 4 BR2400: EQU 8 BR1200: EQU 16 BR600: EQU 32 ; ;Definizioni per pacchetto del tipo I/O request ; IRP$DISPL: EQU 8 IRP$SOH: EQU 1 IRP$STX: EQU 2 IRP$ETX: EQU 3 IRP$EOT: EQU 04H IRP$ACK: EQU 06H IRP$BEL: EQU 07H IRP$NAK: EQU 15H IRP$CAN: EQU 18H ; ;Definizioni tipi di struttura ; IRP$SIO: EQU 20H ;pacchetto per sio IRP$TIMER: EQU 30H ;pacchetto per timer ; ;Definizioni pacchetti di I/O ; NUM_SRP:EQU 1 ;Number of small request packets SIZ_SRP:EQU 32 ;Size of small request packets NUM_MRP:EQU 1 ;Number of medium request packets SIZ_MRP:EQU 64 ;Size of medium request packets NUM_LRP:EQU 90 ;Number of large request packets SIZ_LRP:EQU 80 ;Size of large request packets ; LIST

This is the main module, where there are initialization of devices and the scheduling of processes.
; ;# Module : MAIN ;# Date : August 28, 1992 ;# Author : Pompeo Riccardo ; PUBLIC EXE$RAM,EXE$START,EXE$MAIN PUBLIC EXE$PROCESS,EXE$PROCESSI EXTRN EQM$INIT,MBX$INIT EXTRN CTC$CONNECT,CTC$INTA,CTC$INTB EXTRN SIOA$CONNECT,SIOA$INT ; INCLUDE STARLET.INC ; CSEG ; DI JP EXE$START ; ;# Interrupt dispatch table ; ORG 10H IDT$CTC: DW NOINT DW NOINT DW CTC$INTA DW CTC$INTB ; ORG 20H IDT$PIO: DW SIOA$INT ; NOINT: EI DEVRES: RETI RET ; EXE$START: LD SP,STACK ;Inizializza ram LD HL,EXE$RAM ; LD DE,EXE$RAM+1 ; LD BC,1FFEH ; LD (HL),0 ; LDIR ; ; ;# Queues initialization ; CALL EQM$INIT ;Inizializza code dei vuoti LD HL,PROCESS_QUEUE ;Inizializza coda dei processi LD (QUEPTR),HL ; LD (SCHPTR),HL ; ; ;# Drivers initialization ; LD A,IDT$CTC ;Inizializza driver CALL CTC$CONNECT ; LD A,IDT$PIO ;Attivazione seriale CALL SIOA$CONNECT ; ; ;# Other initialization ; LD B,5 ;Abbatte eventuali interrupt C10: CALL DEVRES ;sulle periferiche DJNZ C10 ; IM 2 ;Attiva interrupt LD A,0 ; LD I,A ; EI ; ; ;# Process activation ; CALL MBX$INIT ; ; ;# Process scheduling ; EXE$MAIN: OUT (8),A ;Strobe LD HL,(SCHPTR) ;Sconfinamento puntatore ? LD DE,(QUEPTR) ; OR A ; SBC HL,DE ; JR Z,EXE$MAIN ; LD HL,(SCHPTR) ; LD E,(HL) ; INC L ; LD D,(HL) ; INC L ; LD (SCHPTR),HL ; EX DE,HL ; LD DE,EXE$MAIN ;Setta indirizzo di ritorno PUSH DE ; JP (HL) ;Lancia processo ; ;# Enqueue a process (DE = process pointer) ; EXE$PROCESS: DI LD HL,(QUEPTR) LD (HL),E INC L LD (HL),D INC L LD (QUEPTR),HL EI RET ; ;# Entry point for interrupt (process whaking) ; EXE$PROCESSI: LD HL,(QUEPTR) LD (HL),E INC L LD (HL),D INC L LD (QUEPTR),HL RET ; DSEG ; EXE$RAM: DS 100H ;Stack STACK: ; PROCESS_QUEUE: DS 100H ;No relocable SCHPTR: DS 2 ;Scheduler pointer QUEPTR: DS 2 ;Queuer pointer ; END

This is a library that includes several basic functions
; ;# Program : Z80 library ;# Date : April 22, 1992 ;# Author : Pompeo Riccardo ; PUBLIC LIB$INSQH,LIB$INSQT,LIB$REMQH,LIB$REMQT PUBLIC LIB$INSQHI,LIB$INSQTI,LIB$REMQHI,LIB$REMQTI PUBLIC LIB$INIT_QUEUE,LIB$INIT_HEADER PUBLIC LIB$HVAL,LIB$HSTR,LIB$DVAL,LIB$DSTR,LIB$NIBBLE PUBLIC LIB$IDIV,LIB$IMUL,LIB$BCDBIN,LIB$BINBCD PUBLIC LIB$BIN$,LIB$BCD$,LIB$BCD$Z?,LIB$CPHLDE,LIB$ADHLA PUBLIC LIB$ONCALL,LIB$ONJUMP PUBLIC LIB$DPRINT,LIB$HPRINT,LIB$COPY,LIB$INDEX PUBLIC LIB$ASC_BIN,LIB$STR_HVAL,LIB$BIT_SUM,LIB$BIT_TEST PUBLIC LIB$BINBCD3,LIB$PCKPTR,LIB$ADDBCD,LIB$BINASC2 ; ;# Queue structure header ; ;00 - FORWARD POINTER (LOW BYTE) ;01 - FORWARD POINTER (HIGH BYTE) ;02 - BACKWARD POINTER (LOW BYTE) ;03 - BACKWARD POINTER (HIGH BYTE) ;04 - FLAGS (LOW BYTE) ;05 - FLAGS (HIGHT BYTE) ; ;# Packet structure header ; ;00 - FORWARD POINTER (LOW BYTE) ;01 - FORWARD POINTER (HIGH BYTE) ;02 - BACKWARD POINTER (LOW BYTE) ;03 - BACKWARD POINTER (HIGH BYTE) ;04 - FLAGS (LOW BYTE) ;05 - FLAGS (HIGHT BYTE) ;06 - PACKET SIZE ;07 - TYPE OF STRUCTURE ; ;# Target : Get the pointer after the header ;# Input : IY = packet pointer ;# Output : DE = pointer inside the pachet ;# Used : A ; LIB$PCKPTR: PUSH IY POP DE LD A,8 ADD A,E LD E,A LD A,0 ADC A,D LD D,A RET ; ;# Target : Insert an element in the head of queue ;# Input : IX = queue header pointer ;# IY = packet pointer to add in the queue ;# Output : none ;# Used : all ; LIB$INSQH: DI CALL LIB$INSQHI EI RET ; LIB$INSQHI: LD C,(IX+0) ;BC=H_F=L LD B,(IX+1) PUSH IX POP HL LD E,L ;IX=DE=H LD D,H XOR A ;SE H_F=H CODA VUOTA SBC HL,BC JR Z,INSQEMP LD (IY+0),C ;E_F=L=BC LD (IY+1),B LD (IY+2),E ;E_B=H=DE LD (IY+3),D PUSH IY POP HL LD (IX+0),L ;H_F=E=HL=IY LD (IX+1),H PUSH BC POP IX ;IX=L LD (IX+2),L ;L_B=E=HL LD (IX+3),H RET ; ;Coda vuota ; INSQEMP: LD (IY+0),E ;E_F=H=DE LD (IY+1),D LD (IY+2),E ;E_B=H=DE LD (IY+3),D ; PUSH IY POP HL LD (IX+0),L ;H_F=E=HL=IY LD (IX+1),H LD (IX+2),L ;H_B=E=HL=IY LD (IX+3),H RET ; ;# Target : Insert a packet in the tail of queue ;# Input : IX = queue header pointer ;# IY = packet pointer to add to the queue ;# Output : none ;# Used : all ; LIB$INSQT: DI CALL LIB$INSQTI EI RET ; LIB$INSQTI: LD C,(IX+2) ;BC=H_B=L LD B,(IX+3) PUSH IX POP HL LD E,L ;IX=DE=H LD D,H XOR A ;SE H_B=H CODA VUOTA SBC HL,BC JR Z,INSQEMP LD (IY+0),E ;E_F=H=DE LD (IY+1),D LD (IY+2),C ;E_B=L=BC LD (IY+3),B PUSH IY POP HL LD (IX+2),L ;H_B=E=HL=IY LD (IX+3),H PUSH BC POP IX ;IX=L LD (IX+0),L ;L_F=E=HL LD (IX+1),H RET ; ;# Target : Remove an element from head of queue ;# Input : IX = header queue pointer ;# Output : IY = removed packet pointer ;# CY = if 1 queue empty ;# Used : all ; LIB$REMQH: DI CALL LIB$REMQHI EI RET ; LIB$REMQHI: LD C,(IX+0) ;BC=H_F=R LD B,(IX+1) PUSH IX POP HL LD E,L ;IX=DE=H LD D,H XOR A ;SE H_F=H CODA VUOTA SBC HL,BC JR Z,REMQEMPTY PUSH BC POP IY ;IY=BC=R LD L,(IY+0) ;H_F=R_F=L=HL LD H,(IY+1) LD (IX+0),L LD (IX+1),H PUSH HL POP IX ;IX=HL=L LD (IX+2),E ;L_B=H=DE LD (IX+3),D XOR A ;CY=0 RET ; ;Coda vuota ; REMQEMPTY: SCF ;CY=1 RET ; ;# Target : Remove an element fomr the end of queue ;# Input : IX = queue header pointer ;# Output : IY = removed packet pointer ;# CY = if 1 queue empty ;# Used : all ; LIB$REMQT: DI CALL LIB$REMQTI EI RET ; LIB$REMQTI: LD C,(IX+2) ;BC=H_B=R LD B,(IX+3) PUSH IX POP HL LD E,L ;IX=DE=H LD D,H XOR A ;SE H_B=H CODA VUOTA SBC HL,BC JR Z,REMQEMPTY PUSH BC POP IY ;IY=BC=R LD L,(IY+2) ;H_B=R_B=L=HL LD H,(IY+3) LD (IX+2),L LD (IX+3),H PUSH HL POP IX ;IX=HL=L LD (IX+0),E ;L_F=H=DE LD (IX+1),D XOR A ;CY=0 RET ; ;# Target : Initialize a queue ;# Input : IX = queue header pointer ;# IY = buffer pointer (first element of queue of empty packets) ;# HL = state flag ;# A = type fo structure ;# B = packets count ;# C = lenght of packets ;# Output : none ;# Used : all ; LIB$INIT_QUEUE: PUSH IX PUSH IY PUSH HL PUSH BC PUSH AF CALL LIB$INSQTI POP AF POP BC POP HL POP IY POP IX LD (IY+4),L LD (IY+5),H LD (IY+6),C LD (IY+7),A LD E,C LD D,0 ADD IY,DE DJNZ LIB$INIT_QUEUE RET ; ;# Target : Initialize an header ;# Input : IX = queue header pointer ;# HL = state flags ;# Output : none ;# Used : DE ; LIB$INIT_HEADER: PUSH IX POP DE LD (IX+0),E ;INIT HEADER FORWARD POINTER LD (IX+1),D LD (IX+2),E ;INIT HEADER BACKWARD POINTER LD (IX+3),D LD (IX+4),L ;INIT FLAGS LD (IX+5),H RET ; ;# Target : Displace over an array of words (16bit) ;# Input : HL = array pointer ;# A = index ;# Output : HL = word ;# Used : DE ; LIB$INDEX: RLCA LD E,A LD D,0 ADD HL,DE LD E,(HL) INC HL LD D,(HL) EX DE,HL RET ; ;# Target : Copy a string ;# Input : HL = string pointer ;# DE = destination buffer pointer ;# B = stop character (included) ;# Output : none ;# Used : none ; LIB$COPY: LD A,(HL) LD (DE),A CP B RET Z INC HL INC DE JR LIB$COPY ; ;# Target : Indexed jump ;# Input : IX = pointer to index to test ;# DE = values table ;# HL = jump table pointer ;# Output : none ;# Used : A ; LIB$ONJUMP: LD A,(DE) OR A RET Z CP (IX) JR Z,RUNJMP INC DE INC HL INC HL JR LIB$ONJUMP RUNJMP: LD E,(HL) INC HL LD D,(HL) EX DE,HL POP DE ;PULISCE DALL'ULTIMA CALL JP (HL) ; ;# Target : Indexed call ;# Input : IX = pointer to index to test ;# DE = values table ;# HL = jump table pointer ;# Output : none ;# Used : A ; LIB$ONCALL: LD A,(DE) OR A RET Z CP (IX) JR Z,RUNCALL INC DE INC HL INC HL JR LIB$ONCALL RUNCALL:LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) ; ;# Target : Add HL with A ;# Input : HL A ;# Output : HL = HL+A ;# Used : none ; LIB$ADHLA: ADD A,L LD L,A LD A,0 ADC A,H LD H,A RET ; ;# Target : Compare HL with DE ;# Input : HL DE ;# Output : CY Z ;# Used : none ; LIB$CPHLDE: PUSH HL OR A SBC HL,DE POP HL RET ; ;# Target : Convert binary to ascii ;# Input : A = binary nibble ;# Output : A = ascii ;# Used : none ; LIB$BIN$: AND 0FH OR 30H CP 3AH RET C ADD A,7 RET ; ;# Target : Convert bcd to ascii ;# Input : A = bcd nibble ;# Output : A = ascii ;# Used : none ; LIB$BCD$: AND 0FH OR 30H CP 3AH JR NC,CBLK RET ; ;# Target : Convert bcd to ascii ;# if 0 return a space character ;# Input : A = bcd nibble ;# Output : A = ascii ;# Used : none ; LIB$BCD$Z?: AND 0FH OR 30H CP 30H JR Z,CBLK CP 3AH JR NC,CBLK RET CBLK: LD A,' ' RET ; ;# Target : Convert binary to ascii 2 bytes ;# Input : A = bunary byte ;# Output : E = ascii low nibble ; D = ascii high nibble ;# Used : none ; LIB$BINASC2: CALL LIB$NIBBLE LD A,D CALL LIB$BIN$ LD D,A LD A,E CALL LIB$BIN$ LD E,A RET ; ;# Target : Convert 4 binary nibbles in compacted binary ;# Input : IX = nibbles pointer ;# Output : HL = output buffer pointer ;# Used : A ; LIB$HVAL: LD A,(IX+0) AND 0FH RLCA RLCA RLCA RLCA LD H,A LD A,(IX+1) AND 0FH OR H LD H,A LD A,(IX+2) AND 0FH RLCA RLCA RLCA RLCA LD L,A LD A,(IX+3) AND 0FH OR L LD L,A RET ; ;# Target : Convert compacted binary to 4 binary nibbles ;# Input : HL = compacted binary ;# IX = nibbles pointer ;# Output : none ;# Used : A ; LIB$HSTR: LD A,H RRCA RRCA RRCA RRCA AND 0FH LD (IX+0),A LD A,H AND 0FH LD (IX+1),A LD A,L RRCA RRCA RRCA RRCA AND 0FH LD (IX+2),A LD A,L AND 0FH LD (IX+3),A RET ; ;# Target : Convert 5 nibbles to binary bcd ;# Input : IX = nibbles pointer ;# Output : HL = compacted binary ;# Used : all ; LIB$DVAL: LD DE,10000D LD C,(IX+0) CALL LIB$IMUL PUSH HL LD DE,1000D LD C,(IX+1) CALL LIB$IMUL EX DE,HL POP HL ADD HL,DE PUSH HL LD DE,100D LD C,(IX+2) CALL LIB$IMUL EX DE,HL POP HL ADD HL,DE PUSH HL LD DE,10D LD C,(IX+3) CALL LIB$IMUL EX DE,HL POP HL ADD HL,DE LD E,(IX+4) LD D,0 ADD HL,DE RET ; ;# Target : Convert a binary to 5 bcd nibbles ;# Input : HL = compacted binary ;# IX = nibbles binary pointer ;# Output : none ;# Used : all ; LIB$DSTR: PUSH HL LD DE,10000D CALL LIB$IDIV LD (IX+0),C LD DE,10000D CALL LIB$IMUL EX DE,HL POP HL OR A SBC HL,DE PUSH HL LD DE,1000D CALL LIB$IDIV LD (IX+1),C LD DE,1000D CALL LIB$IMUL EX DE,HL POP HL OR A SBC HL,DE PUSH HL LD DE,100D CALL LIB$IDIV LD (IX+2),C LD DE,100D CALL LIB$IMUL EX DE,HL POP HL OR A SBC HL,DE PUSH HL LD DE,10D CALL LIB$IDIV LD (IX+3),C LD DE,10D CALL LIB$IMUL EX DE,HL POP HL OR A SBC HL,DE LD (IX+4),L RET ; ;# Target : Convert bcd to binary ;# Input : D = decimal ;# E = units ;# Output : A = binary ;# Used : none ; LIB$BCDBIN: LD A,D ADD A,A LD D,A ADD A,A ADD A,A ADD A,D ADD A,E RET ; ;# Target : Convert binary to bcd ;# Input : A = binary ;# Output : D = decimal ;# E = unit ;# Used : none ; LIB$BINBCD: LD DE,0 BLOOP: SUB 10D JR C,BCONT INC D JR BLOOP BCONT: ADD A,10D LD E,A RET ; ;# Target : Divide a byte in two nibble ;# Input : A = binary ;# Output : D = high nibble of A ;# E = low nibble of A ;# Used : none ; LIB$NIBBLE: LD D,A AND 0FH LD E,A LD A,D AND 0F0H RRCA RRCA RRCA RRCA LD D,A RET ; ;# Target : Unsigned multiplication ;# Input : DE = multiplicand ;# C = multiplier ;# Output : HL = result ;# CY = if 1 overflow ;# Used : B ; LIB$IMUL: LD HL,0 LD B,8 MLOOP: RR C JR NC,MCONT ADD HL,DE RET C MCONT: SLA E RL D DJNZ MLOOP OR A ;CY=0 RET ; ;# Target : Unsigned division ;# Input : HL = dividend ;# DE = divisor ;# Output : HL = result ;# CY = if 1 division by 0 ;# Used : BC AF ; LIB$IDIV: LD A,E OR D SCF RET Z LD A,0 LD C,L LD B,H ADJ: OR A SBC HL,DE JR C,ENDADJ SLA E RL D LD L,C LD H,B INC A JR ADJ ENDADJ: LD L,C LD H,B LD BC,0 OR A RET Z SRL D RR E DLOOP: OR A SBC HL,DE JR NC,DVSBL ADD HL,DE SCF DVSBL: CCF RL C RL B SRL D RR E DEC A JR NZ,DLOOP OR A RET ; ;# Target : Convert a binary to an ascii string ;# Input : HL = binary ;# IX = destination buffer pointer ;# Output : none ;# Used : DE BC AF ; LIB$DPRINT: CALL LIB$DSTR LD A,(IX+0) CALL LIB$BCD$Z? LD (IX+0),A LD B,(IX+1) CALL CONV LD (IX+1),A LD B,(IX+2) CALL CONV LD (IX+2),A LD B,(IX+3) CALL CONV LD (IX+3),A LD A,(IX+4) CALL LIB$BCD$ LD (IX+4),A RET ; CONV: CP ' ' JR Z,CN00 LD A,B CALL LIB$BCD$ RET CN00: LD A,B CALL LIB$BCD$Z? RET ; ;# Target : Convert binary to exadecimal ascii string ;# Input : HL = binary ;# IX = destination buffer pointer ;# Output : none ;# Used : DE BC AF ; LIB$HPRINT: CALL LIB$HSTR LD A,(IX+0) CALL LIB$BIN$ LD (IX+0),A LD A,(IX+1) CALL LIB$BIN$ LD (IX+1),A LD A,(IX+2) CALL LIB$BIN$ LD (IX+2),A LD A,(IX+3) CALL LIB$BIN$ LD (IX+3),A RET ; ;# Target : Convert ascii to binary ;# Input : A = ascii exadecimal ;# Output : A = binary nibble ;# Used : none ; LIB$ASC_BIN: CP 40H JR C,CONT SUB 7 CONT: AND 0FH RET ; ;# Target : Convert an ascii exadecimal string to binary ;# Input : IX = source buffer pointer ;# Output : HL = binary ;# Used : DE BC AF ; LIB$STR_HVAL: LD A,(IX+0) CALL LIB$ASC_BIN LD (IX+0),A LD A,(IX+1) CALL LIB$ASC_BIN LD (IX+1),A LD A,(IX+2) CALL LIB$ASC_BIN LD (IX+2),A LD A,(IX+3) CALL LIB$ASC_BIN LD (IX+3),A CALL LIB$HVAL RET ; ;# Target : Count how many bits are 1 ;# Input : A = binary ;# Output : A = bit count ;# Used : HL ; LIB$BIT_SUM: LD HL,SUMTAV ADD A,L LD L,A LD A,0 ADC A,H LD H,A LD A,(HL) RET ; ;# Target : Test a bit ;# Input : A = binary ;# E = bit index ;# Output : Z ;# Used : HL DE ; LIB$BIT_TEST: LD D,0 LD HL,BITTAV ADD HL,DE AND (HL) RET ; ;# Target : Convert binary to compacted bcd (3 nibble) ;# Input : A = binary ;# Output : HL = result ;# Used : DE BC ; LIB$BINBCD3: CALL LIB$NIBBLE LD A,E CP 10 JR C,C70 ADD A,6 LD E,A C70: LD C,D LD B,0 SLA C LD HL,TBCD ADD HL,BC LD C,(HL) INC HL LD B,(HL) LD A,E ADD A,C DAA LD L,A LD A,0 ADC A,B DAA LD H,A RET ; ;# Target : Sum a BCD counter with accumulator ;# Input : IX = counter pointer ;# HL = accumulator BCD ;# Output : HL = HL+(IX) ;# IX = IX+2 ;# Used : A ; LIB$ADDBCD: LD A,L ;somma i nibble meno significativi ADD A,(IX+0) DAA LD L,A LD A,H ADC A,(IX+1) ;somma con riporto i nibble piu' significativi DAA LD H,A INC IX ;IX=IX+2 INC IX RET ; ;# Data ; SUMTAV: DB 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 DB 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5 DB 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5 DB 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 DB 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5 DB 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 DB 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 DB 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7 DB 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5 DB 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 DB 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 DB 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7 DB 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6 DB 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7 DB 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7 DB 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 ; BITTAV: DB 00000001B DB 00000010B DB 00000100B DB 00001000B DB 00010000B DB 00100000B DB 01000000B DB 10000000B ; TBCD: DW 0H,16H,32H,48H,64H,80H,96H,112H DW 128H,144H,160H,176H,192H,208H,224H,240H ; END



This module implements a driver for packet oriented Rx/Tx
; ;# Module : SIOA driver - Sync protocol - ;# Date : August 28, 1992 ;# Author : Pompeo Riccardo ; PUBLIC SIOA$RAM,SIOA$CONNECT,SIOA$QIOR,SIOA$QIOW,SIOA$INT PUBLIC SIOA$IOCR,SIOA$IOCW,SIOA$FLUSHR,SIOA$FLUSHW EXTRN LIB$INSQT,LIB$REMQH,LIB$INSQTI,LIB$REMQHI,LIB$INIT_HEADER EXTRN EQM$REQUEST,EQM$RELEASE,EQM$REQUESTI,EQM$RELEASEI ; INCLUDE STARLET.INC ; SIOD: EQU SIOA$SIOD ENDTX: EQU 0 ; CSEG ; ;# Target : Driver inizialization ;# Input : A = interrupt vector ;# Output : none ;# Used : all ; SIOA$CONNECT: RES 0,A ;Init. PIO channel B OUT (PIOCB),A ; LD A,11001111B ;select control mode OUT (PIOCB),A ; LD A,11111111B ;i/o bit mask OUT (PIOCB),A ; LD A,10010111B ;int.en.,mask follow,active low,or func. OUT (PIOCB),A ; LD A,11111110B ;load mask OUT (PIOCB),A ; LD HL,0 ;Init. pointers LD (TXPTR),HL ; LD (RXPTR),HL ; LD HL,0 ;TX queue flags LD IX,SIOA$TX_QUEUE CALL LIB$INIT_HEADER LD HL,0 ;RX queue flags LD IX,SIOA$RX_QUEUE CALL LIB$INIT_HEADER RETI ; ;# Target : Enqueue a packet for transmition ;# Input : IY = packet pointer ;# Output : none ;# Used : all ; SIOA$QIOW: LD A,IRP$SIO ;Pacchetto di tipo elaborabile ? CP (IY+7) ; JR Z,C20 ; CALL EQM$RELEASE ;Riaccoda il pacchetto nei vuoti RET C20:LD IX,SIOA$TX_QUEUE CALL LIB$INSQT ;Accoda il pacchetto corrente RET ; ;# Target : Dequeue a packet from Rx buffer ;# Input : none ;# Output : IY = packet pointer ;# CY = if 1 the queue is empty ;# Used : all ; SIOA$QIOR: LD IX,SIOA$RX_QUEUE CALL LIB$REMQH RET ; ;# Target : Read flags code ;# Input : none ;# Output : +--7--+--6--+--5--+--4--+--3--+--2--+--1--+--0--+ ; H = | X | X | X | X | X | X | X | X | ; +-----+-----+-----+-----+-----+-----+-----+-----+ ; L = | X | X | X | X | X | X | X | X | ; +-----+-----+-----+-----+-----+-----+-----+-----+ ;# Used : all ; SIOA$IOCR: LD IX,SIOA$TX_QUEUE LD H,(IX+4) LD IX,SIOA$RX_QUEUE LD L,(IX+4) RET ; ;# Target : Write flags code ;# Input : +--7--+--6--+--5--+--4--+--3--+--2--+--1--+--0--+ ; H = | X | X | X | X | X | X | X | X | ; +-----+-----+-----+-----+-----+-----+-----+-----+ ; L = | X | X | X | X | X | X | X | X | ; +-----+-----+-----+-----+-----+-----+-----+-----+ ;# Output : none ;# Used : all ; SIOA$IOCW: LD IX,SIOA$TX_QUEUE LD (IX+5),H LD IX,SIOA$RX_QUEUE LD (IX+5),L RET ; ;# Target : Free Rx queue ;# Input : none ;# Output : none ;# Used : all ; SIOA$FLUSHR: LD IX,SIOA$RX_QUEUE CALL LIB$REMQH RET C CALL EQM$RELEASE JR SIOA$FLUSHR ; ;# Target : Free Tx queue ;# Input : none ;# Output : none ;# Used : all ; SIOA$FLUSHW: LD IX,SIOA$TX_QUEUE CALL LIB$REMQH RET C CALL EQM$RELEASE JR SIOA$FLUSHW ; ;# Interrupt entry point ; SIOA$INT: EX AF,AF' EXX PUSH IX PUSH IY CALL SIOA$TX CALL SIOA$RX POP IY POP IX EXX EX AF,AF' EI RETI ; PAGE ; ;# Rx ; SIOA$RX: LD HL,(RXPTR) ;Gia' in ricezione ? LD A,H OR L JR NZ,SIOA$RX_SELECT LD A,75 ;Richiede un pacchetto CALL EQM$REQUESTI JR C,SIOA$RX_CLEAR ;Pacchetto non disponibile ? SIOA$RX_NEWPCK: LD (IY+7),IRP$SIO ;Tipo struttura LD (RXPCK),IY ;Salva puntatore al pacchetto CALL SIOA$RX_INIT SIOA$RX_SELECT: LD IX,SIOA$RX_QUEUE LD (IX+4),0 ; LD IY,(RXPCK) ; LD HL,(RXSTEP) ;Avvia il passo di ricezione corrente JP (HL) ; SIOA$RX_CLEAR: ;Nell'impossibilita' di allocare un IN A,(SIOD) ;pacchetto il carattere viene RET ;ricevuto ma non gestito SIOA$RX_INIT: PUSH IY ;Inizializza puntatori per ricezione POP HL LD DE,IRP$DISPL ADD HL,DE LD (RXPTR),HL LD HL,SIOA$RX00 LD (RXSTEP),HL LD A,0 LD (RXNUM),A LD (RXBCC),A RET ; ;Riceve header of trasmission ; SIOA$RX00: IN A,(SIOD) CP IRP$SOH RET NZ LD HL,SIOA$RX01 LD (RXSTEP),HL RET ; ;Rx Address ; SIOA$RX01: IN A,(SIOD) LD HL,(RXPTR) LD (HL),A INC HL LD (RXPTR),HL LD (RXBCC),A LD HL,RXNUM INC (HL) LD HL,SIOA$RX02 LD (RXSTEP),HL RET ; ;Rx until ETX or overflow ; SIOA$RX02: IN A,(SIOD) LD HL,(RXPTR) LD (HL),A INC HL LD (RXPTR),HL CP IRP$ETX JR NZ,C01 LD HL,SIOA$RX03 LD (RXSTEP),HL C01: LD HL,RXBCC ADD A,(HL) LD (HL),A LD A,66 LD HL,RXNUM INC (HL) CP (HL) RET NC CALL SIOA$RX_INIT RET ; ;Rx BCC ; SIOA$RX03: IN A,(SIOD) LD HL,RXBCC CP (HL) JR NZ,C03 LD HL,0 LD (RXPTR),HL CALL LIB$INSQTI RET C03:CALL SIOA$RX_INIT RET ; PAGE ; ;# Tx ; SIOA$TX: LD HL,(TXPTR) ;Pacchetto gia' disponibile ? LD A,H OR L JR NZ,SIOA$TX_SELECT LD IX,SIOA$TX_QUEUE CALL LIB$REMQHI ;Scoda un pacchetto JR NC,SIOA$TX_NEWPCK ;Pacchetto presente ? LD A,16H OUT (SIOD),A ;Trasmette SYNC RET SIOA$TX_NEWPCK: ; LD (TXPCK),IY ;Inizializza puntatori CALL SIOA$TX_INIT SIOA$TX_SELECT: LD IX,SIOA$TX_QUEUE LD IY,(TXPCK) LD HL,(TXSTEP) ;Avvia il passo di trasmissione corrente JP (HL) SIOA$TX_INIT: PUSH IY ;Inizializza puntatori per trasmissione POP HL LD DE,IRP$DISPL ADD HL,DE LD (TXPTR),HL LD HL,SIOA$TX00 LD (TXSTEP),HL LD A,0 LD (TXBCC),A LD (TXNUM),A RET ; ;Tx header of trasmission ; SIOA$TX00: LD A,IRP$SOH OUT (SIOD),A LD HL,SIOA$TX01 LD (TXSTEP),HL RET ; ;Tx Address ; SIOA$TX01: LD HL,(TXPTR) LD A,(HL) OUT (SIOD),A INC HL LD (TXPTR),HL LD (TXBCC),A LD HL,TXNUM INC (HL) LD HL,SIOA$TX02 LD (TXSTEP),HL RET ; ;Tx until ETX ; SIOA$TX02: LD HL,(TXPTR) LD A,(HL) OUT (SIOD),A INC HL LD (TXPTR),HL CP IRP$ETX JR NZ,C15 LD HL,SIOA$TX03 LD (TXSTEP),HL C15:LD HL,TXBCC ADD A,(HL) LD (HL),A LD A,66 LD HL,TXNUM INC (HL) CP (HL) RET NC LD HL,SIOA$TX04 LD (TXSTEP),HL RET ; ;Tx BCC ; SIOA$TX03: LD A,(TXBCC) OUT (SIOD),A LD HL,0 LD (TXPTR),HL CALL EQM$RELEASEI ;RIACCODA IL PACCHETTO NEI VUOTI RET ; ;Tx ETX ; SIOA$TX04: LD A,IRP$ETX OUT (SIOD),A LD HL,TXBCC ADD A,(HL) LD (HL),A LD HL,SIOA$TX03 LD (TXSTEP),HL RET ; DSEG ; SIOA$RAM: ; SIOA$TX_QUEUE: DS 6 SIOA$RX_QUEUE: DS 6 ; TXPTR: DS 2 TXPCK: DS 2 TXBCC: DS 1 TXSTEP: DS 2 TXNUM: DS 1 ; RXPTR: DS 2 RXPCK: DS 2 RXBCC: DS 1 RXSTEP: DS 2 RXNUM: DS 1 ; END



This module controls CTC
; ;# Module : CTC driver ;# Date : August 28, 1992 ;# Author : Pompeo Riccardo ; PUBLIC CTC$CONNECT,CTC$INTA,CTC$INTB EXTRN SIOA$INT_TX,SIOA$INT_RX EXTRN SIOB$INT_TX,SIOB$INT_RX ; INCLUDE STARLET.INC ; BRATE1: EQU BR1200 BRATE2: EQU BR9600 TIMER1: EQU 19 ;1 ms TIMER2: EQU 192 ;10 ms ; CSEG ; ;# CTC initilization (A = interrupt vector) ; CTC$CONNECT: RES 0,A ;set interrupt vector OUT (CTC0),A ; LD A,00000101B ;int disab.,timer mode,*16,time cost. OUT (CTC0),A ; LD A,BRATE1 ; OUT (CTC0),A ; LD A,00100101B ;int disab.,timer mode,*256,time cost. OUT (CTC2),A ; LD A,TIMER1 ; OUT (CTC2),A ; LD A,00000101B ;int disab.,timer mode,*16,time cost. OUT (CTC1),A ; LD A,BRATE2 ; OUT (CTC1),A ; LD A,00100101B ;int disab.,timer mode,*256,time cost. OUT (CTC3),A ; LD A,TIMER2 ;N.B. OUT (CTC3),A ;interrupt -> bit 7 0 = dis , 1 = enab RETI ;prescaler -> bit 5 0 = *16 , 1 = *256 ; ;# Channel A interrupt entry point ; CTC$INTA: EX AF,AF' EXX ; EXX EX AF,AF' EI RETI ; ;# Channel B interrupt entry point ; CTC$INTB: EX AF,AF' EXX ; EXX EX AF,AF' EI RETI ; END

This module controls a scratch area filled by empty packets
; ;# Module : Queue Manager ;# Date : December 5, 1991 ;# Author : Pompeo Riccardo ; PUBLIC EQM$RAM,EQM$INIT,EQM$STATUS PUBLIC EQM$REQUEST,EQM$RELEASE,EQM$REQUESTI,EQM$RELEASEI EXTRN LIB$INIT_QUEUE,LIB$INIT_HEADER EXTRN LIB$REMQH,LIB$INSQH,LIB$REMQHI,LIB$INSQHI ; INCLUDE STARLET.INC ; OVRFL: EQU 0 ; CSEG ; ;# Target : Initialization ;# Input : none ;# Output : none ;# Used : all ; EQM$INIT: LD HL,0 LD IX,EQM$SRP_QUEUE CALL LIB$INIT_HEADER LD IX,EQM$MRP_QUEUE CALL LIB$INIT_HEADER LD IX,EQM$LRP_QUEUE CALL LIB$INIT_HEADER ; LD A,0 LD B,NUM_SRP LD C,SIZ_SRP LD HL,0 LD IX,EQM$SRP_QUEUE LD IY,EQM$SRP CALL LIB$INIT_QUEUE ; LD A,0 LD B,NUM_MRP LD C,SIZ_MRP LD HL,0 LD IX,EQM$MRP_QUEUE LD IY,EQM$MRP CALL LIB$INIT_QUEUE ; LD A,0 LD B,NUM_LRP LD C,SIZ_LRP LD HL,0 LD IX,EQM$LRP_QUEUE LD IY,EQM$LRP CALL LIB$INIT_QUEUE ; RET ; ;# Target : Get a packet ;# Input : A = packet size ;# Output : IY = packet pointer ;# CY = if 1 packet not available ;# Used : all ; EQM$REQUEST: CP SIZ_SRP JR NC,C00 LD IX,EQM$SRP_QUEUE CALL LIB$REMQH RET NC LD IX,EQM$SRP_QUEUE SET OVRFL,(IX+4) RET C00: CP SIZ_MRP JR NC,C01 LD IX,EQM$MRP_QUEUE CALL LIB$REMQH RET NC LD IX,EQM$MRP_QUEUE SET OVRFL,(IX+4) RET C01: CP SIZ_LRP JR NC,C02 LD IX,EQM$LRP_QUEUE CALL LIB$REMQH RET NC LD IX,EQM$LRP_QUEUE SET OVRFL,(IX+4) RET C02: SCF RET ; ;# Entry point for interrupt ; EQM$REQUESTI: CP SIZ_SRP JR NC,C20 LD IX,EQM$SRP_QUEUE CALL LIB$REMQHI RET NC LD IX,EQM$SRP_QUEUE SET OVRFL,(IX+4) RET C20: CP SIZ_MRP JR NC,C21 LD IX,EQM$MRP_QUEUE CALL LIB$REMQHI RET NC LD IX,EQM$MRP_QUEUE SET OVRFL,(IX+4) RET C21: CP SIZ_LRP JR NC,C22 LD IX,EQM$LRP_QUEUE CALL LIB$REMQHI RET NC LD IX,EQM$LRP_QUEUE SET OVRFL,(IX+4) RET C22: SCF RET ; ;# Target : Release a packet ;# Input : none ;# Output : IY = packet pointer ;# Used : all ; EQM$RELEASE: LD A,(IY+6) CP SIZ_SRP JR NZ,C10 LD IX,EQM$SRP_QUEUE RES OVRFL,(IX+4) CALL LIB$INSQH RET C10: CP SIZ_MRP JR NZ,C11 LD IX,EQM$MRP_QUEUE RES OVRFL,(IX+4) CALL LIB$INSQH RET C11: LD IX,EQM$LRP_QUEUE RES OVRFL,(IX+4) CALL LIB$INSQH RET ; ;# Entry point for interrupt ; EQM$RELEASEI: LD A,(IY+6) CP SIZ_SRP JR NZ,C30 LD IX,EQM$SRP_QUEUE RES OVRFL,(IX+4) CALL LIB$INSQHI RET C30: CP SIZ_MRP JR NZ,C31 LD IX,EQM$MRP_QUEUE RES OVRFL,(IX+4) CALL LIB$INSQHI RET C31: LD IX,EQM$LRP_QUEUE RES OVRFL,(IX+4) CALL LIB$INSQHI RET ; ;# Target : Read status ;# Input : none ;# Output : +--7--+--6--+--5--+--4--+--3--+--2--+--1--+--0--+ ;# A = | X | X | X | X | X |LRPOV|MRPOV|SRPOV| ;# +-----+-----+-----+-----+-----+-----+-----+-----+ ;# Used : B ; EQM$STATUS: LD A,(EQM$SRP_QUEUE+4) AND 00000001B LD B,A LD A,(EQM$MRP_QUEUE+4) AND 00000001B RLCA OR B LD B,A LD A,(EQM$LRP_QUEUE+4) AND 00000001B RLCA RLCA OR B RET ; DSEG ; EQM$RAM: ; EQM$SRP_QUEUE: DS 6 EQM$MRP_QUEUE: DS 6 EQM$LRP_QUEUE: DS 6 ; EQM$SRP: DS NUM_SRP*SIZ_SRP EQM$MRP: DS NUM_MRP*SIZ_MRP EQM$LRP: DS NUM_LRP*SIZ_LRP ; END



This module controls the exchange of informations between Z80 and the host system
; ;# Module : Mailbox controller ;# Date : August 28, 1992 ;# Author : Pompeo Riccardo ; PUBLIC MBX$INIT,MBX$CONTROLLER EXTRN EXE$PROCESS EXTRN SIOA$QIOW,SIOA$QIOR,SIOA$IOCR,SIOA$IOCW,SIOA$FLUSHW,SIOA$FLUSHR EXTRN EQM$REQUEST,EQM$RELEASE ; INCLUDE STARLET.INC INCLUDE HSKCODE.INC ; STRSZ EQU 67 ;String size PCKSZ EQU STRSZ+IRP$DISPL ;Packet size PIOD EQU PIODA ;PIO data address PIOC EQU PIOCA ;PIO control address FLGADD EQU DPRAM1 ;Flag address LENADD EQU DPRAM1+1 ;Length address STRADD EQU DPRAM1+2 ;String address ; CSEG ; ;# Initialize mail box ; MBX$INIT: ; ;Programmazione PIO A ; LD A,11001111B ;select control mode OUT (PIOC),A ; LD A,11110000B ;i/o bit mask OUT (PIOC),A ; LD A,00000111B ;interrupt disabled OUT (PIOC),A ; LD A,MP$NULL ; OUT (PIOD),A ; ; ;# Inizializzazione dual port ram ; LD HL,DPRAM1 LD DE,DPRAM1+1 LD BC,3FCH LD (HL),0 LDIR ; ;# Attivazione processi ; LD DE,MBX$CONTROLLER CALL EXE$PROCESS RET ; ;# Mailbox controller ; MBX$CONTROLLER: IN A,(PIOD) AND HS$RWRQ JR Z,NORQ IN A,(PIOD) AND HS$MASK CP HS$READ JP Z,MBX$RDSIOA CP HS$WRIT JP Z,MBX$WRSIOA CP HS$FLSH JP Z,MBX$FLUSH NORQ: LD DE,MBX$CONTROLLER CALL EXE$PROCESS RET ; ;# Flush Rx/Tx buffers ; MBX$FLUSH: CALL SIOA$FLUSHR LD A,MP$RWOK CALL COMPLETION LD DE,MBX$CONTROLLER CALL EXE$PROCESS RET ; ;# Tx to RS422 ; MBX$WRSIOA: LD A,(LENADD) ;Controllo lunghezza stringa CP STRSZ ; JR NC,NOPCK ; LD A,PCKSZ ;Richiede un pacchetto CALL EQM$REQUEST JR C,NOPCK ;Pacchetto non disponibile ? LD (IY+7),IRP$SIO ;Tipo struttura LD A,(FLGADD) ;Traferisce indirizzo LD (IY+8),A ; LD (IY+9),IRP$STX PUSH IY ;Si spiazza sul pacchetto POP HL LD DE,IRP$DISPL+2 ADD HL,DE ; EX DE,HL ; LD HL,STRADD ;Trasferisce la stringa LD A,(LENADD) ; LD C,A LD B,0 LDIR ; LD A,IRP$ETX ; LD (DE),A ; CALL SIOA$QIOW ;Trasmissione LD A,MP$RWOK ; CALL COMPLETION LD DE,MBX$CONTROLLER CALL EXE$PROCESS RET NOPCK: LD A,MP$RWOK ;Buffer full OR MP$FULL CALL COMPLETION LD DE,MBX$CONTROLLER CALL EXE$PROCESS RET ; ;# Rx from RS422 ; MBX$RDSIOA: CALL SIOA$QIOR ;Pacchetto presente JR C,NODATA ; LD A,(IY+8) ;Trasferisce indirizzo LD (FLGADD),A ; PUSH IY ;Si spiazza sul pacchetto POP HL LD DE,IRP$DISPL+2 ADD HL,DE ;HL - source buffer address LD DE,STRADD ;DE - destin. " " LD B,0 ;B - length C20: ; LD A,(HL) ;Trasferisce la stringa CP IRP$ETX ;Fine stringa ? JR Z,C21 LD (DE),A INC HL INC DE INC B JR C20 C21: ; LD A,B ;Trasferisce lunghezza LD (LENADD),A CALL EQM$RELEASE ;Riaccoda il pacchetto nei vuoti LD A,MP$RWOK CALL COMPLETION LD DE,MBX$CONTROLLER CALL EXE$PROCESS RET NODATA: LD A,MP$RWOK ;Buffer empty OR MP$EMPT CALL COMPLETION LD DE,MBX$CONTROLLER CALL EXE$PROCESS RET ; ;# Target : Signaling I/O completion ;# Input : A = code (MP$xxxx) ;# Output : none ;# Used : A ; COMPLETION: OUT (PIOD),A C50: IN A,(PIOD) AND HS$RWRQ JR NZ,C50 LD A,MP$NULL OUT (PIOD),A RET ; END

Please report any problem or request of support sending an e-mail here.