I wrote these subroutines while learning how to program on the MiniMax8085 board -- a simple 8085-based single board computer (SBC). My board's RAM starts at 0x8000, so that's where the subroutines are. You should update the addresses and jump instructions based on your RAM size (E.G. if it has 8K of RAM, start at 0xE000). To load the subroutines on MON85, use i ADDR (ADDR is the address of the start) and then paste in the Intel hex (listed after the assembly).
Input:
C - Character to print
Output:
Character printed to the USART
8200 DB 09 IN 09
8202 E6 01 ANI 01
8204 CA 00 82 JZ 8200
8207 79 MOV A,C
8208 D3 08 OUT 08
820A C9 RET
:0C820000DB09E601CA008279D308C9003E
:00000001FF
Input:
HL - Address of the text string to print
Output:
String printed to the USART
8100 3E 00 MVI A 00
8102 4E MOV C,M
8103 B9 CMP C
8104 CA 0E 81 JZ 810E
8107 23 INX H
8108 CD 00 82 CALL 8200
810B C3 00 81 JMP 8100
810E C9 RET
:108100003E004EB9CA0E8123CD0082C30081C90052
:00000001FF
Input:
none
Output:
A - Character from the USART
8180 D8 09 IN 09
8182 E6 02 ANI 02
8184 CA 80 81 JS 8180
8187 D8 08 IN 08
8189 C9 RET
:108100003E004EB9CA0E8123CD0082C30081C90052
:00000001FF
Input:
C - Byte to print
Output:
Byte printed to the USART
8280 F5 PUSH PSW ; Push acc. and flags
8281 79 MOV A,C ; Copy input into acc.
8282 E6 0F ANI 0F ; Get lower half of acc.
8284 C6 30 ADI 30 ; Add 0x30 (ascii '0') to acc.
8286 FE 39 CPI 3A ; See if acc. is greater than 9 (characters after digits are ":;<=>?")
8288 DA 8D 82 JC 828E ; Acc. is not a hex number, so skip adding
828B C6 07 ADI 07 ; Add 0x07 to get to capital letters (use 0x27 if you want lower case)
828D 47 MOV B,A ; Move character into B to be later moved into C for printing
828E 79 MOV A,C ; See 8281
828F E6 F0 ANI F0 ; See 8282
8291 07 RLC ; Shift
8292 07 RLC ; Acc.
8293 07 RLC ; Four
8294 07 RLC ; Bits
8295 C6 30 ADI 30 ; See 8284
8297 FE 39 CPI 3A ; See 8286
8299 DA 9E 82 JC 829F ; See 8288
829C C6 07 ADI 07 ; See 828B
829E 4F MOV C,A ; Move character into C to be printed first
829F F1 POP PSW ; Pop acc. and flags
82A0 C9 RET ; Exit
Lets use an example: 0x7F (01111111)
Get the lower 4-bits (nibble) of the input: 0x0F
Add 0x30 - the ASCII code of "0": 0x3F
If the result value is greater than 0x39:
Add 0x07, so that the values from 0xA to 0xF are translated to the ASCII codes of "A" to "F": 0x46
Store the result value (ASCII code) into B
Get the higher 4-bits (nibble) of the input: 0x70
Shift the value left 4 times: 0x07
Add 0x30 - the ASCI code of "0": 0x37
If the result is value greater than 0x39:
No
Store the result value (ASCII code) into C
Return
:10828000F579E60FC630FE3ADA8D82C6074779E601
:10829000F007070707C630FE3ADA9E82C6074FF19D
:0182A000C914
:00000001FF
Input:
B,C - Factors
Output:
HL - product
8300 F5 PUSH PSW
8301 C5 PUSH B
8302 D5 PUSH D
8303 26 00 MVI H,$00
8305 6C MOV L,H
8306 54 MOV D,H
8307 59 MOV E,C
8308 78 MOV A,B
8309 37 STC
830A 3F CMC
830B 1F RAR
830C 47 MOV B,A
830D D2 11 83 JNC $8311
8310 19 DAD D
8311 37 STC
8312 3F CMC
8313 7B MOV A,E
8314 17 RAL
8315 5F MOV E,A
8316 7A MOV A,D
8317 17 RAL
8318 57 MOV D,A
8319 3E 00 MVI A,$00
831B B8 CMP B
831C C2 08 83 JNZ $8308
831F D1 POP D
8320 C1 POP B
8321 F1 POP PSW
8322 C9 RET
Lets use the example of B: 0x06 (00000110) times C: 0x0B (00001011)
Start with a standard multiplication layout but in binary:
00001011
x 00000110
----------
Expand the top value (stored in register C) to a 16 bit value (stored in register pair DE), and zero the output value (register pair HL):
0000000000001011
x 00000110
------------------
0000000000000000
In a loop:
Shift the bottom value (register B) to the right through carry:
0000000000001011
x 00000011 Carry = 0
------------------
0000000000000000
If the carry flag is set, add the top value (register pair DE) to the output (register pair HL) and reset the carry flag
Shift the top value (register pair DE) to the left;
0000000000010110
x 00000011 Carry = 0
------------------
0000000000000000
If the bottom value is not zero, repeat the loop:
0000000000010110
x 00000001 Carry = 1
------------------
0000000000010110
0000000000101100
x 00000001 Carry = 0
------------------
0000000000010110
0000000000101100
x 00000000 Carry = 1
------------------
0000000000010110
0000000001011000
x 00000000 Carry = 0
------------------
1111
0000000000101100
+ 0000000000010110
------------------
0000000001000010
Now that the bottom value is zero, the loop stops and subroutine returns the value of 0x42 (0000000001000010) in register pair HL
Now lets see how the subroutine works with the factors C = 0x1B (00011011) x B = 0x97 (10010111)
0000000000011011
x 10010111
------------------
0000000000000000
0000000000011011
x 01001011 Carry = 1
------------------
0000000000000000
0000000000110110
x 01001011 Carry = 0
------------------
0000000000011011
0000000000110110
x 00100101 Carry = 1
------------------
0000000000011011
0000000001101100
x 00100101 Carry = 0
------------------
11111
0000000000110110
+ 0000000000011011
------------------
0000000001010001
0000000001101100
x 00010010 Carry = 1
------------------
0000000001010001
0000000011011000
x 00010010 Carry = 0
------------------
1
0000000001101100
+ 0000000001010001
------------------
0000000010111101
0000000011011000
x 0001001 Carry = 0
------------------
0000000010111101
0000000110110000
x 0001001 Carry = 0
------------------
0000000010111101
0000000110110000
x 0000100 Carry = 1
------------------
0000000010111101
0000001101100000
x 00000100 Carry = 0
------------------
11 11
0000000110110000
+ 0000000010111101
------------------
0000001001101101
0000001101100000
x 00000010 Carry = 0
------------------
0000001001101101
0000011011000000
x 00000010 Carry = 0
------------------
0000001001101101
0000011011000000
x 00000001 Carry = 0
------------------
0000001001101101
0000110110000000
x 00000001 Carry = 0
------------------
0000001001101101
0000110110000000
x 00000000 Carry = 1
------------------
0000001001101101
0001101100000000
x 00000000 Carry = 0
------------------
0000110110000000
+ 0000001001101101
------------------
0000111111101101
The subroutine exits with an answer of 0x0FED (0000111111101101) in register pair HL
:10830000F5C5D526006C545978373F1F47D2118329
:1083100019373F7B175F7A17573E00B8C20883D125
:03832000C1F1C981
:00000001FF