; ; Sum two numbers using ADD instruction and then make BCD correction using DAA instruction ; .ORG 100H ; CP/M programs start address JR START ; Go to program start ; ; Variable storage space ; Stack1 .DW 0 ; Place to save old stack Sbot .DS 64 ; Temp stack for us to use ; ; Constants ; STOP .EQU $-1 ; Top of our stack BDOS .EQU 5 ; Address of BDOS entry ; ; Peripheral I/O addresses ; LEDS .EQU 00H ; Digital I/O board PIO1_A_D .EQU 068H ; Z80 PIO #1 PIO1_A_C .EQU 06AH PIO1_B_D .EQU 069H PIO1_B_C .EQU 06BH PIO2_A_D .EQU 06CH ; Z80 PIO #2 PIO2_A_C .EQU 06EH PIO2_B_D .EQU 06DH PIO2_B_C .EQU 06FH PIO3_A_D .EQU 0F0H ; Z80 PIO #3 PIO3_A_C .EQU 0F2H PIO3_B_D .EQU 0F1H PIO3_B_C .EQU 0F3H PIO4_A_D .EQU 0F4H ; Z80 PIO #4 PIO4_A_C .EQU 0F6H PIO4_B_D .EQU 0F5H PIO4_B_C .EQU 0F7H ; ; Start of code segment ; START: LD HL, 0000H ; HL = 0 ADD HL, SP ; HL = SP LD (Stack1), HL ; Save original stack LD HL, STOP ; HL = address of new stack LD SP, HL ; Stack pointer = our stack ; ------------------------------------------------------------ ; Initialize Z80 PIO's 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 ; ; ADD: A = A + B ; LD A, 00010111B ; 17D (packed BCD) LD B, 01010100B ; 54D (packed BCD) OUT (PIO1_A_D), A ; Set LEDs in PIO #1 ch. A with 1st operand LD C, PIO1_B_D OUT (C), B ; Set LEDs in PIO #1 ch. B with 2nd operand LD C, A CALL PRINT_BCD LD E, '+' CALL BDOS2 LD C, B CALL PRINT_BCD LD E, '=' CALL BDOS2 ADD A, B ; A and B are added together, and the result is written back to A OUT (LEDS), A ; Send result (expect 0110 1011 = 6BH) of A + B to digital I/O board ; ; The A register is BCD corrected using the contents of the flags. ; See: http://z80-heaven.wikidot.com/instructions-set:daa ; PUSH AF ; We want send Flags te LEDs so PUSH AF POP DE ; Now we have Flags in E LD C, PIO2_A_D OUT (C), E ; Set LEDs in PIO #2 ch. A with content of Flags DAA ; A register is BCD corrected using the contents of the Flags OUT (PIO2_B_D), A ; Set LEDs in PIO #2 ch. B with content DAA result, expect 0111 0001 = 71D LD C, A CALL PRINT_BCD ; ------------------------------------------------------------ ; Finish and return to CP/M EXIT: LD HL, (Stack1) ; HL = entry stack address LD SP, HL ; SP = value on entry RET ; Return control back to CP/M ;-------------------------------------------------------------------------------------- PRINT_BCD: ; ; Print BCD number in C ; PUSH AF PUSH BC LD A, C RRA \ RRA \ RRA \ RRA AND 00001111B ADD A, '0' ; Convert to ASCII LD E, A CALL BDOS2 POP BC LD A, C AND 00001111B ADD A, '0' ; Convert to ASCII LD E, A CALL BDOS2 POP AF RET ;-------------------------------------------------------------------------------------- ; ; BDOS function 2 (C_WRITE) - Console output, char in E ; BDOS2: PUSH AF PUSH BC PUSH DE PUSH HL LD C, 2 ; We want BDOS func 2 CALL BDOS ; Entered with C = 2, E = ASCII character POP HL POP DE POP BC POP AF RET ;-------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------- .END