123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- ; The entry point is im2value. The routine needs at least 4608 (0x1200) bytes.
- ; Well, maybe a bit less depending on where it is located.
- ; Base address - should be a multiple of 256.
- base equ 6D00h
- ; U is the base value for addresses contained in the De Bruijn sequence. The
- ; lowest address will be U*257 and the highest address will be (U+15)*257.
- ; These correspond to port values of 0 and 254, respectively.
- U equ (base>>8)+2 ; from 6F6Fh to 7E7Eh
- org base
- ; Sorted address to initial value lookup table - 256 entries.
- SortedTable: db 000h, 002h, 004h, 006h, 008h, 00Ah, 00Ch, 00Eh
- db 010h, 012h, 014h, 016h, 018h, 01Ah, 01Ch, 0FFh
- db 001h, 01Fh, 021h, 023h, 025h, 027h, 029h, 02Bh
- db 02Dh, 02Fh, 031h, 033h, 035h, 037h, 039h, 01Eh
- db 003h, 020h, 03Ch, 03Eh, 040h, 042h, 044h, 046h
- db 048h, 04Ah, 04Ch, 04Eh, 050h, 052h, 054h, 03Bh
- db 005h, 022h, 03Dh, 057h, 059h, 05Bh, 05Dh, 05Fh
- db 061h, 063h, 065h, 067h, 069h, 06Bh, 06Dh, 056h
- db 007h, 024h, 03Fh, 058h, 070h, 072h, 074h, 076h
- db 078h, 07Ah, 07Ch, 07Eh, 080h, 082h, 084h, 06Fh
- db 009h, 026h, 041h, 05Ah, 071h, 087h, 089h, 08Bh
- db 08Dh, 08Fh, 091h, 093h, 095h, 097h, 099h, 086h
- db 00Bh, 028h, 043h, 05Ch, 073h, 088h, 09Ch, 09Eh
- db 0A0h, 0A2h, 0A4h, 0A6h, 0A8h, 0AAh, 0ACh, 09Bh
- db 00Dh, 02Ah, 045h, 05Eh, 075h, 08Ah, 09Dh, 0AFh
- db 0B1h, 0B3h, 0B5h, 0B7h, 0B9h, 0BBh, 0BDh, 0AEh
- db 00Fh, 02Ch, 047h, 060h, 077h, 08Ch, 09Fh, 0B0h
- db 0C0h, 0C2h, 0C4h, 0C6h, 0C8h, 0CAh, 0CCh, 0BFh
- db 011h, 02Eh, 049h, 062h, 079h, 08Eh, 0A1h, 0B2h
- db 0C1h, 0CFh, 0D1h, 0D3h, 0D5h, 0D7h, 0D9h, 0CEh
- db 013h, 030h, 04Bh, 064h, 07Bh, 090h, 0A3h, 0B4h
- db 0C3h, 0D0h, 0DCh, 0DEh, 0E0h, 0E2h, 0E4h, 0DBh
- db 015h, 032h, 04Dh, 066h, 07Dh, 092h, 0A5h, 0B6h
- db 0C5h, 0D2h, 0DDh, 0E7h, 0E9h, 0EBh, 0EDh, 0E6h
- db 017h, 034h, 04Fh, 068h, 07Fh, 094h, 0A7h, 0B8h
- db 0C7h, 0D4h, 0DFh, 0E8h, 0F0h, 0F2h, 0F4h, 0EFh
- db 019h, 036h, 051h, 06Ah, 081h, 096h, 0A9h, 0BAh
- db 0C9h, 0D6h, 0E1h, 0EAh, 0F1h, 0F7h, 0F9h, 0F6h
- db 01Bh, 038h, 053h, 06Ch, 083h, 098h, 0ABh, 0BCh
- db 0CBh, 0D8h, 0E3h, 0ECh, 0F3h, 0F8h, 0FCh, 0FBh
- db 01Dh, 03Ah, 055h, 06Eh, 085h, 09Ah, 0ADh, 0BEh
- db 0CDh, 0DAh, 0E5h, 0EEh, 0F5h, 0FAh, 0FDh, 0FEh
- ; Interrupt vectors, organized as a De Bruijn sequence B(16,2)
- ; A B(16,2) De Bruijn sequence is a wrapping sequence of 256
- ; values, formed by 16 symbols, in which every consecutive
- ; pair appears exactly once in the sequence, which is what
- ; we need. We use the numbers U+0 through U+15 as symbols.
- IntVecs: db U+00h, U+00h, U+01h, U+00h, U+02h, U+00h, U+03h, U+00h
- db U+04h, U+00h, U+05h, U+00h, U+06h, U+00h, U+07h, U+00h
- db U+08h, U+00h, U+09h, U+00h, U+0Ah, U+00h, U+0Bh, U+00h
- db U+0Ch, U+00h, U+0Dh, U+00h, U+0Eh, U+00h, U+0Fh, U+01h
- db U+01h, U+02h, U+01h, U+03h, U+01h, U+04h, U+01h, U+05h
- db U+01h, U+06h, U+01h, U+07h, U+01h, U+08h, U+01h, U+09h
- db U+01h, U+0Ah, U+01h, U+0Bh, U+01h, U+0Ch, U+01h, U+0Dh
- db U+01h, U+0Eh, U+01h, U+0Fh, U+02h, U+02h, U+03h, U+02h
- db U+04h, U+02h, U+05h, U+02h, U+06h, U+02h, U+07h, U+02h
- db U+08h, U+02h, U+09h, U+02h, U+0Ah, U+02h, U+0Bh, U+02h
- db U+0Ch, U+02h, U+0Dh, U+02h, U+0Eh, U+02h, U+0Fh, U+03h
- db U+03h, U+04h, U+03h, U+05h, U+03h, U+06h, U+03h, U+07h
- db U+03h, U+08h, U+03h, U+09h, U+03h, U+0Ah, U+03h, U+0Bh
- db U+03h, U+0Ch, U+03h, U+0Dh, U+03h, U+0Eh, U+03h, U+0Fh
- db U+04h, U+04h, U+05h, U+04h, U+06h, U+04h, U+07h, U+04h
- db U+08h, U+04h, U+09h, U+04h, U+0Ah, U+04h, U+0Bh, U+04h
- db U+0Ch, U+04h, U+0Dh, U+04h, U+0Eh, U+04h, U+0Fh, U+05h
- db U+05h, U+06h, U+05h, U+07h, U+05h, U+08h, U+05h, U+09h
- db U+05h, U+0Ah, U+05h, U+0Bh, U+05h, U+0Ch, U+05h, U+0Dh
- db U+05h, U+0Eh, U+05h, U+0Fh, U+06h, U+06h, U+07h, U+06h
- db U+08h, U+06h, U+09h, U+06h, U+0Ah, U+06h, U+0Bh, U+06h
- db U+0Ch, U+06h, U+0Dh, U+06h, U+0Eh, U+06h, U+0Fh, U+07h
- db U+07h, U+08h, U+07h, U+09h, U+07h, U+0Ah, U+07h, U+0Bh
- db U+07h, U+0Ch, U+07h, U+0Dh, U+07h, U+0Eh, U+07h, U+0Fh
- db U+08h, U+08h, U+09h, U+08h, U+0Ah, U+08h, U+0Bh, U+08h
- db U+0Ch, U+08h, U+0Dh, U+08h, U+0Eh, U+08h, U+0Fh, U+09h
- db U+09h, U+0Ah, U+09h, U+0Bh, U+09h, U+0Ch, U+09h, U+0Dh
- db U+09h, U+0Eh, U+09h, U+0Fh, U+0Ah, U+0Ah, U+0Bh, U+0Ah
- db U+0Ch, U+0Ah, U+0Dh, U+0Ah, U+0Eh, U+0Ah, U+0Fh, U+0Bh
- db U+0Bh, U+0Ch, U+0Bh, U+0Dh, U+0Bh, U+0Eh, U+0Bh, U+0Fh
- db U+0Ch, U+0Ch, U+0Dh, U+0Ch, U+0Eh, U+0Ch, U+0Fh, U+0Dh
- db U+0Dh, U+0Eh, U+0Dh, U+0Fh, U+0Eh, U+0Eh, U+0Fh, U+0Fh
- db U+00h ; The De Bruijn sequence wraps around
- ; but the interrupt vectors don't, so we
- ; repeat the first byte here.
- ; At start, A = 255.
- ; At U*257+0000h, A should decrease by 255 before returning,
- ; resulting in 0.
- ; At U*257+0001h, A should decrease by 254, resulting in 1.
- ; At U*257+0002h, by 253, resulting in 2.
- ; ...
- ; At U*257+000Fh, by 240, resulting in 15.
- ; (Note there's a gap here)
- ; At U*257+0100h, by 239, resulting in 16.
- ; At U*257+0101h, by 238, resulting in 17.
- ; ...
- ; At U*257+0F0Eh, by 1, resulting in 254.
- ; At U*257+0F0Fh, it should be returned untouched (255).
- ;
- ; This way, the value of A will be unique for every possible
- ; target address, so all that is left is to find out which
- ; original bus value led to that value of A. That's what
- ; SortedTable is for.
- ;
- ; The comment at these addresses indicates what value of the
- ; bus led to that address.
- org U*257+0000h
- dec a ; 0
- dec a ; 2
- dec a ; 4
- dec a ; 6
- dec a ; 8
- dec a ; 10
- dec a ; 12
- dec a ; 14
- dec a ; 16
- dec a ; 18
- dec a ; 20
- dec a ; 22
- dec a ; 24
- dec a ; 26
- dec a ; 28
- ;dec a ; 255
- ;jp U*257+0100h ; Instead of this, we take a shortcut
- sub 240 ; by subtracting as many DEC A's as
- ret ; there are remaining, then return.
- ; Take advantage of the gap between address groups to insert this routine.
- ; The gap is at least 238 bytes long.
- ; Bus value finder, using IM2.
- ;
- ; Returns bus value in A. Clobbers HL.
- ; Upon return, interrupts are enabled and IM1 mode is set.
- im2value: ld a,HIGH IntVecs
- di
- ld i,a
- ld a,255 ; Prepare initial value
- im 2
- ei
- halt
- im 1
- ei
- ld l,a ; A is sorted index
- ld h,HIGH SortedTable
- ld a,(hl) ; Grab the value for that index
- ret
- org U*257+0100h
- dec a ; 1
- dec a ; 31
- dec a ; 33
- dec a ; 35
- dec a ; 37
- dec a ; 39
- dec a ; 41
- dec a ; 43
- dec a ; 45
- dec a ; 47
- dec a ; 49
- dec a ; 51
- dec a ; 53
- dec a ; 55
- dec a ; 57
- ;dec a ; 30
- ;jp U*257+0200h ; See comment above
- sub 224 ; 30
- ret
- org U*257+0200h
- dec a ; 3
- dec a ; 32
- dec a ; 60
- dec a ; 62
- dec a ; 64
- dec a ; 66
- dec a ; 68
- dec a ; 70
- dec a ; 72
- dec a ; 74
- dec a ; 76
- dec a ; 78
- dec a ; 80
- dec a ; 82
- dec a ; 84
- sub 208 ; 59
- ret
- org U*257+0300h
- dec a ; 5
- dec a ; 34
- dec a ; 61
- dec a ; 87
- dec a ; 89
- dec a ; 91
- dec a ; 93
- dec a ; 95
- dec a ; 97
- dec a ; 99
- dec a ; 101
- dec a ; 103
- dec a ; 105
- dec a ; 107
- dec a ; 109
- sub 192 ; 86
- ret
- org U*257+0400h
- dec a ; 7
- dec a ; 36
- dec a ; 63
- dec a ; 88
- dec a ; 112
- dec a ; 114
- dec a ; 116
- dec a ; 118
- dec a ; 120
- dec a ; 122
- dec a ; 124
- dec a ; 126
- dec a ; 128
- dec a ; 130
- dec a ; 132
- sub 176 ; 111
- ret
- org U*257+0500h
- dec a ; 9
- dec a ; 38
- dec a ; 65
- dec a ; 90
- dec a ; 113
- dec a ; 135
- dec a ; 137
- dec a ; 139
- dec a ; 141
- dec a ; 143
- dec a ; 145
- dec a ; 147
- dec a ; 149
- dec a ; 151
- dec a ; 153
- sub 160 ; 134
- ret
- org U*257+0600h
- dec a ; 11
- dec a ; 40
- dec a ; 67
- dec a ; 92
- dec a ; 115
- dec a ; 136
- dec a ; 156
- dec a ; 158
- dec a ; 160
- dec a ; 162
- dec a ; 164
- dec a ; 166
- dec a ; 168
- dec a ; 170
- dec a ; 172
- sub 144 ; 155
- ret
- org U*257+0700h
- dec a ; 13
- dec a ; 42
- dec a ; 69
- dec a ; 94
- dec a ; 117
- dec a ; 138
- dec a ; 157
- dec a ; 175
- dec a ; 177
- dec a ; 179
- dec a ; 181
- dec a ; 183
- dec a ; 185
- dec a ; 187
- dec a ; 189
- sub 128 ; 174
- ret
- org U*257+0800h
- dec a ; 15
- dec a ; 44
- dec a ; 71
- dec a ; 96
- dec a ; 119
- dec a ; 140
- dec a ; 159
- dec a ; 176
- dec a ; 192
- dec a ; 194
- dec a ; 196
- dec a ; 198
- dec a ; 200
- dec a ; 202
- dec a ; 204
- sub 112 ; 191
- ret
- org U*257+0900h
- dec a ; 17
- dec a ; 46
- dec a ; 73
- dec a ; 98
- dec a ; 121
- dec a ; 142
- dec a ; 161
- dec a ; 178
- dec a ; 193
- dec a ; 207
- dec a ; 209
- dec a ; 211
- dec a ; 213
- dec a ; 215
- dec a ; 217
- sub 96 ; 206
- ret
- org U*257+0A00h
- dec a ; 19
- dec a ; 48
- dec a ; 75
- dec a ; 100
- dec a ; 123
- dec a ; 144
- dec a ; 163
- dec a ; 180
- dec a ; 195
- dec a ; 208
- dec a ; 220
- dec a ; 222
- dec a ; 224
- dec a ; 226
- dec a ; 228
- sub 80 ; 219
- ret
- org U*257+0B00h
- dec a ; 21
- dec a ; 50
- dec a ; 77
- dec a ; 102
- dec a ; 125
- dec a ; 146
- dec a ; 165
- dec a ; 182
- dec a ; 197
- dec a ; 210
- dec a ; 221
- dec a ; 231
- dec a ; 233
- dec a ; 235
- dec a ; 237
- sub 64 ; 230
- ret
- org U*257+0C00h
- dec a ; 23
- dec a ; 52
- dec a ; 79
- dec a ; 104
- dec a ; 127
- dec a ; 148
- dec a ; 167
- dec a ; 184
- dec a ; 199
- dec a ; 212
- dec a ; 223
- dec a ; 232
- dec a ; 240
- dec a ; 242
- dec a ; 244
- sub 48 ; 239
- ret
- org U*257+0D00h
- dec a ; 25
- dec a ; 54
- dec a ; 81
- dec a ; 106
- dec a ; 129
- dec a ; 150
- dec a ; 169
- dec a ; 186
- dec a ; 201
- dec a ; 214
- dec a ; 225
- dec a ; 234
- dec a ; 241
- dec a ; 247
- dec a ; 249
- sub 32 ; 246
- ret
- org U*257+0E00h
- dec a ; 27
- dec a ; 56
- dec a ; 83
- dec a ; 108
- dec a ; 131
- dec a ; 152
- dec a ; 171
- dec a ; 188
- dec a ; 203
- dec a ; 216
- dec a ; 227
- dec a ; 236
- dec a ; 243
- dec a ; 248
- dec a ; 252
- sub 16 ; 251
- ret
- org U*257+0F00h
- dec a ; 29
- dec a ; 58
- dec a ; 85
- dec a ; 110
- dec a ; 133
- dec a ; 154
- dec a ; 173
- dec a ; 190
- dec a ; 205
- dec a ; 218
- dec a ; 229
- dec a ; 238
- dec a ; 245
- dec a ; 250
- dec a ; 253
- ret ; 254
|