;; this program will test the I/O decoding for the RAM configuration ;; selection. ;; ;; This program assumes a Dk'Tronics/Amstrad/Dobbertin compatible RAM expansion. ;; ;; This program assumes that the expansion is connected/active, and the recommeded ;; I/O port is used to select the configurations. (&7fxx) ;; ;; the program does the following: ;; 1. using recommended I/O port address write byte to ram (using configuration 0) ;; 2. using recommended I/O port address set configuration 4, so 16k of extra ram is ;; paged into &4000-&7fff ;; 3. using current I/O port address attempt to set configuration 0 (16k of extra ram is paged out) ;; 4. write a byte ;; 5. using recommended I/O port address set configuration 0. ;; 5. test byte ;; ;; if I/O port address is valid, then the previous ram configuration will be restored and the byte ;; will be modified with the new value. ;; ;; if I/O port address is invalid, then the previous ram configuration will not be restored and the byte ;; will not be modified. ;; ;; the ram block will be swapped into &4000-&8000 org &8000 nolist ;; clear result table ld hl,result_table ld e,l ld d,h inc de ld (hl),0 ld bc,8191 ldir ;; test all 65536 I/O addressess ld bc,0 ;; this is the initial I/O port address ld de,0 ld ix,result_table .next_config push bc ;; ram address to write ld hl,&4000 ;; set ram configuration 0 ;; using recommended I/O port address ld bc,&7fc0 out (c),c ;; write byte ld (hl),&00 ;; set ram configuration 4 ;; using recommended I/O port address ld bc,&7fc4 out (c),c ;; set ram configuration using a different I/O port address ;; compared to recommended port address ld b,d ld c,e ld a,&c0 out (c),a ;; write byte ld (hl),&ff ;; if this I/O port can be used, then the byte at &4000 ;; will be different to the original value after ram configuration 0 has been selected ;; set ram configuration 0 ;; using recommended I/O port address ld bc,&7fc0 out (c),c ;; get byte ld a,(hl) ;; has it changed? ;; if yes, then the I/O port address can be used to change the ram configuration ;; if no, then the I/O port address can't be used to change the ram configuration cp 0 jr z,failure ;; get OR bit ld a,(or_value) ;; combine with existing byte or (ix+0) ;; store back ld (ix+0),a .failure pop bc ;; shift OR value ld a,(or_value) rlca ld (or_value),a ;; update bit count and increment position in table ;; if bit count gets to 8. ld a,(bit_count) inc a cp 8 jr c,nbit inc ix xor a .nbit ld (bit_count),a inc de ;; next I/O port address dec bc ;; loop ld a,b or c jr nz,next_config ;; operation stages: ;; 1. use XOR => (a XOR b) => where bits are 0, then they are the same. where bits are 1, then they are not the same ;; 2. use NOT => NOT (a XOR b) => generates a mask for bits (1 where a bit is the same in a and b, 0 for a bit that is different) ;; 3. use a AND (NOT (a XOR b)) => keeps values of bits that are the same ;; ;; the mask and value is updated for each value where the I/O address is valid and produces a result ld a,0 ld (first),a ld hl,result_table ld de,0 ld bc,8192 ld ix,io_info ld (ix+0),0 ld (ix+1),0 .generate_result push bc ld c,(hl) inc hl ;; go through the result byte ;; if a bit is "1" then this I/O port can be used. ;; if a bit is "0" then this I/O port can't be used ld b,8 .gr2 ;; is this bit significant? ld a,c and 128 jr z,not_useable ;; yes! ld a,(first) or a jr nz,gr4 ld a,&ff ld (first),a ld (ix+0),a ld (ix+1),a jr gr5 .gr4 ;; calc "important bits mask" ;; bit is 1 in mask if the bit in this position is important ;; bit is 0 in mask if the bit in this position is not important ;; low byte of bits ld a,(ix+2) ;; current bits xor e ;; NOT cpl ;; low byte of mask and (ix+0) ;; store low byte of mask ld (ix+0),a ;; high byte of bits ld a,(ix+3) ;; current bits xor d ;; NOT cpl ;; high byte of mask and (ix+1) ;; store high byte of mask ld (ix+1),a .gr5 ;; store new value masked with "important bits mask" ld a,e and (ix+0) ld (ix+2),a ld a,d and (ix+1) ld (ix+3),a .not_useable inc de rlc c djnz gr2 pop bc dec bc ld a,b or c jp nz,generate_result ;;---------------------------------------------------------------------------- ;; display the result ;; "1" indicates that this bit must be 1, ;; "0" indicates that this bit must be 0 ;; "-" indicates that this bit is ignored. ;; show result ;; force horizontal to valid number ld bc,&bc00 out (c),c ld bc,&bd3f out (c),c ;; 16-bits ld b,2 .sr push bc ld b,8 ld e,(ix+1) ;; mask for high byte ld d,(ix+3) ;; bits for high byte .sr2 ld a,e and 128 ld a,"-" ;; character for bit is ignored jr z,sr3 ;; setup character for bit that is used ld a,d and 128 ;; isolate state of bit 7 add a,a ;; bit 7 into carry (A will be 0 after this operation) adc a,"0" ;; if bit is 0 -> "0" character, if bit is 1 -> "1" character .sr3 call &bb5a ;; display character rl e ;; shift mask rl d ;; shift data djnz sr2 dec ix ;; now fetch mask for low byte and mask for high byte pop bc djnz sr ret .OR_value defb 1 .BIT_count defb 0 .first defb 0 .IO_info defw 0 ;; mask defw 0 ;; bits ;; a bit will be 0 if failure, 1 if successs .result_table defs 8192