Sense Insensibility

There's some serious hacking going on here. This code runs right at the start of BASIC, and it's job is to modify the IO code at 1100-1300 which reads input chars and prints output chars. The modifications make the code specific to whatever device the user has configured via the front panel. Actual modifications are :

1. Port numbers to use for read/write.
2. Bits to test for read/write readiness.
3. Conditional instructions to use after testing bits for read/write readiness.

ReadSense:4D66IN A,(FF)Read sense switches.
4D68AND F0Only interested in A15-A12.
4D6ARRCA
4D6BRRCA
4D6CCP 3CNo switches set, then return.
4D6ERET Z
4D6FCP 38Only A12 set?
4D71SCFCarry = 1.
4D72JP NZ,4D7FIf A15, A14, or A13 set then jump ahead.
4D75LD HL,5FFFSpong! What on earth can be here??
4D78LD C,(HL)
4D79DEC HL
4D7ALD A,(HL)
4D7BAND F0
4D7DRRCA
4D7ERRCA
Use A15-A12 configuration in A as index into some table. The lowest possible index is 0 and the highest is 34, in multiples of 4.
4D7FPUSH AFPreserve A15 - A12.
4D80LD L,A
4D81LD H,00
4D83LD DE,4DE4
4D86ADD HL,DEHL=offset into IO table.
4D87LD A,(HL)A=port #.
4D88INC HL
4D89LD D,(HL)D=conditional jump opcode.
4D8AINC HL
4D8BLD B,(HL)B=IO read test bit.
4D8CINC HL
4D8DLD E,(HL)E=IO write test bit.
4D8ELD H,AH=port #.
4D8FPOP AF
4D90PUSH AF
4D91LD A,HA=port #.
4D92JP C,4D96Spong! Where is carry set?
4D95LD A,C
4D96LD (4DE2),AWrite port # to code below.
4D99POP AFA=port #.
4D9ALD HL,4E00
4D9DPUSH HLPush ??? address onto stack
4D9ELD C,FF
4DA0CP 10If A15, A13, A12 all set
4DA2LD HL,0000
4DA5LD (116E),HLWrites two NOPs into IO code. Why??
4DA8JP Z,4DBA
4DABCP 08
4DADRET NC'Return' to 4E00.
4DAEADD A,11
4DB0PUSH AF
4DB1LD A,03
4DB3CALL 4DE1
4DB6POP AF
4DB7JP 4DE1
4DBAXOR A
4DBBCALL 4DE1
4DBECALL 4DDD
4DC1CALL 4DDD
4DC4CPL
4DC5LD C,01
4DC7CALL 4DDD
4DCAPUSH HL
4DCBLD HL,(4DE1)
4DCELD L,DB
4DD0LD (116E),HL
4DD3POP HL
4DD4LD A,2C
4DD6DEC (HL)
4DD7CALL 4DE1
4DDADEC (HL)
4DDBDEC (HL)
4DDCDEC (HL)
4DDDLD HL,4DE2
4DE0INC (HL)
4DE1OUT (10),A
4DE3RET


I/O configuration table

First byte = port #.
Second byte = conditional instruction: 0xCA = JP Z, 0xC2 = JP NZ.
Third byte = bit to test for IO read readiness.
Fourth byte = bit to test for IO write readiness.

4DE410 CA 01 02A15, A14, A13, A12
4DE810 CA 01 02A15, A14, A13
4DEC00 C2 01 80A15, A14, A12
4DF006 C2 01 80A15, A14
4DF420 CA 80 80A15, A13, A12
4DF804 CA 02 01A15, A13
4DFC24 CA 40 40A15, A12


I/O Code Modification

Using values from the above table and code, this modifies the IO code in the 1100-1300 area to use selected ports, test bits, and conditional flow opcodes.
4E00LD H,DH=conditional jump opcode.
4E01LD L,BL=test bit.
4E02LD (11A1),HLIO_Read_ready code.
4E05LD A,H
4E06AND C8
4E08LD H,AH=0xC8 (RET Z) or 0xC0 (RET NZ).
4E09LD (134F),HLWrite to elsewhere in IO code.
4E0CXOR 0C
4E0ELD H,AH=0xC4 (CALL NZ) or 0xCC (CALL Z).
4E0FLD (123E),HLWrite to elsewhere in IO code.
4E12EX DE,HL
4E13LD (1166),HLIO_Write_ready code.
4E16LD A,(4DE2)
4E19LD (119F),A
4E1CLD (134D),A
4E1FLD (123C),A
4E22INC A
4E23LD (11A6),A
4E26ADD A,C
4E27LD (1164),A
4E2AINC A
4E2BLD (116C),A
4E2ERET
4E2FNOP
4E30NOP