/* * Testing inline assembler with HI-TECH C under CP/M * Make rotation effects on four Z80 PIO's */ #include #define LEDS 00H /* Digital I/O board */ #define PIO1_A_D 068H /* Z80 PIO #1 */ #define PIO1_A_C 06AH #define PIO1_B_D 069H #define PIO1_B_C 06BH #define PIO2_A_D 06CH /* Z80 PIO #2 */ #define PIO2_A_C 06EH #define PIO2_B_D 06DH #define PIO2_B_C 06FH #define PIO3_A_D 0F0H /* Z80 PIO #3 */ #define PIO3_A_C 0F2H #define PIO3_B_D 0F1H #define PIO3_B_C 0F3H #define PIO4_A_D 0F4H /* Z80 PIO #4 */ #define PIO4_A_C 0F6H #define PIO4_B_D 0F5H #define PIO4_B_C 0F7H /* Forward declarations */ void delay(long); void pio1(int); void pio2(int); void pio3(int); void pio4(int); /* Entry point to program */ int main() { printf("Hello RC2014, Z80 CPU + four Z80 PIO's !\n"); /* Set SC103 - Z80 PIO's to output mode */ #asm PUSH AF LD A, 0FH ; Control word for PIO, set output mode OUT (PIO1_A_C), A ; PIO #1 port A OUT (PIO1_B_C), A ; PIO #1 port B OUT (PIO2_A_C), A ; PIO #2 port A OUT (PIO2_B_C), A ; PIO #2 port B OUT (PIO3_A_C), A ; PIO #3 port A OUT (PIO3_B_C), A ; PIO #3 port B OUT (PIO4_A_C), A ; PIO #4 port A OUT (PIO4_B_C), A ; PIO #4 port B ; Turn all LED's OFF XOR A ; LD A, 0 -> XOR A OUT (LEDS), A OUT (PIO1_A_D), A OUT (PIO1_B_D), A OUT (PIO2_A_D), A OUT (PIO2_B_D), A OUT (PIO3_A_D), A OUT (PIO3_B_D), A OUT (PIO4_A_D), A OUT (PIO4_B_D), A POP AF #endasm pio1(5); pio2(5); pio3(5); pio4(5); printf("Finished\n"); return 0; } void pio1(int count) { int i; for (i = 0; i < count; i++) { #asm PUSH AF PUSH BC PUSH DE LD D, 10000000B LD E, 00000001B ; Display initial state LD A, E OUT (PIO1_A_D), A LD A, D OUT (PIO1_B_D), A LD A, 10000000B OUT (LEDS), A CALL ASMDELAY LD B, 07H ; 8 LED's = 7 rotation cycles REPEAT1: ; Read PIO #1 to DE IN A, (PIO1_A_D) LD E, A IN A, (PIO1_B_D) LD D, A ; ; 8-bit rotation in D and E ; SCF ; The Carry Flag in the flags register is set RL E ; Rotate E left, bit 7 goes to Carry Flag and CF to bit 0 SCF ; The Carry Flag in the flags register is set RR D ; Rotate D right, Carry Flag with E(b7) goes to bit 7, D(b0) goes to CF ; Write DE back to PIO #1 LD A, E OUT (PIO1_A_D), A LD A, D OUT (PIO1_B_D), A CALL ASMDELAY DJNZ REPEAT1 POP DE POP BC POP AF #endasm delay(500l); } } void pio2(int count) { int i; #asm LD A, 01000000B OUT (LEDS), A CALL ASMDELAY #endasm for (i = 0; i < count; i++) { #asm PUSH AF PUSH DE LD B, 08H ; 8 shift cycles LD DE, 0001H LD A, 10000000B REPEAT2a: RLC A ; ; 16-bit left shift in DE ; ; Write DE back to PIO #2 PUSH AF LD A, E OUT (PIO2_A_D), A LD A, D OUT (PIO2_B_D), A POP AF CALL ASMDELAY SLA E ; Shift E left, bit 7 goes to Carry Flag bit 0 is reset DJNZ REPEAT2a ; Loop through 8 cycles RL D ; Push Carry Flag to D bit 0 LD B, 08H CALL ASMDELAY REPEAT2b: RLC A ; Write DE back to PIO #2 PUSH AF LD A, E OUT (PIO2_A_D), A LD A, D OUT (PIO2_B_D), A POP AF CALL ASMDELAY SLA D ; Shift D left, bit 7 goes to Carry Flag bit 0 is reset DJNZ REPEAT2b ; Loop through 8 cycles POP DE POP AF #endasm delay(150l); } } void pio3(int count) { int i; #asm PUSH AF LD A, 00100000B OUT (LEDS), A POP AF CALL ASMDELAY #endasm for (i = 0; i < count; i++) { #asm PUSH AF PUSH DE PUSH BC REPEAT3a: LD B, 08H ; 8 shift cycles LD DE, 0001H REPEAT3b: ; ; 16-bit left shift in DE ; ; Write DE back to PIO #3 LD A, D OUT (PIO3_A_D), A LD A, E OUT (PIO3_B_D), A CALL ASMDELAY SLA E ; Shift E left, bit 7 goes to Carry Flag bit 0 is reset DJNZ REPEAT3b ; Loop through 8 cycles RL D ; Push Carry Flag to D bit 0 LD B, 08H ; 8 shift cycles REPEAT3c: ; Write DE back to PIO #3 LD A, D OUT (PIO3_A_D), A LD A, E OUT (PIO3_B_D), A CALL ASMDELAY SLA D ; Shift D left, bit 7 goes to Carry Flag bit 0 is reset DJNZ REPEAT3c ; Loop through 8 cycles POP BC POP DE POP AF #endasm } delay(120l); } void pio4(int count) { int i; #asm LD A, 00010000B OUT (LEDS), A CALL ASMDELAY #endasm for (i = 0; i < count; i++) { #asm PUSH AF PUSH BC LD B, 0FFH LD A, 0 OUT (PIO4_A_D), A PIO3R: CALL ASMDELAY ; Read PIO #4 A to A IN A, (PIO4_A_D) INC A ; Write DE back to PIO #4 OUT (PIO4_A_D), A DJNZ PIO3R POP BC POP AF #endasm } delay(200l); } #asm ; ; ASM Routine to add a delay ; ASMDELAY: PUSH BC LD C, 08FH DELAY1: LD B, 0FFH DELAY2: NOP DJNZ DELAY2 DEC C JR NZ, DELAY1 POP BC RET #endasm /* C function to add a delay */ void delay(long duration) { long i; for (i = 0; i < duration; i++) { ; #asm NOP #endasm } }