;====================================================================== include common.inc udata_acs dsave_w res 1 dsave_fsr0 res 2 debugp res 1 debug_section udata 0x100 debug res 256 code ;====================================================================== ; GENERALLY USEFUL ROUTINES ;---------- read_pic_no @ ; read pic no from ID locations and return it ; W undefined pic number from ID loc 0 ; status Z undefined 1 iff master PIC ; TBLPTR* undefined points to 20001 mov_lw 0x20 mov_wf TBLPTRU clr_f TBLPTRH clr_f TBLPTRL tblrd_postinc_fixup mov_fw TABLAT return ;---------- idlocs_init @ ; read id locations and store in canonical place ; W undefined undefined ; picno undefined pic number (from 20000) ; idloc1 undefined idloc1 (from 20001) rcall read_pic_no mov_wf picno tblrd_postinc_fixup mov_fw TABLAT mov_wf idloc1 return ;---------- bitnum2bit_init @ ; populate bitnum2bit mov_lw 0x80 mov_lfsr bitnum2bit,0 init_bitnum2bit_loop rl_w mov_wf POSTINC0 bra_nn init_bitnum2bit_loop return ;---------- memory_erase @ ; picno preserved ; idloc1 preserved ; other GPRs overwritten with 0xbb mov_ff picno, FSR1L mov_ff idloc1, TABLAT mov_lfsr 0, 0 memory_erase_pageloop mov_lw 0xbb memory_erase_byteloop mov_wf POSTINC0 mov_wf POSTINC0 mov_wf POSTINC0 mov_wf POSTINC0 mov_wf POSTINC0 mov_wf POSTINC0 mov_wf POSTINC0 mov_wf POSTINC0 tst_f_ifnz FSR0L bra memory_erase_byteloop ; new page: mov_lw 0x06 xor_wfw FSR0H bra_nz memory_erase_pageloop ; done! mov_ff FSR1L, picno mov_ff TABLAT, idloc1 return ;---------- debugbyte @ ; Adds a byte to debug ; W message byte preserved ; STATUS any trashed ; all others any preserved ; Not for use in High ISR mov_ff FSR0L, dsave_fsr0 mov_ff FSR0H, dsave_fsr0+1 mov_lfsr debug, 0 mov_ff debugp, FSR0L mov_wf INDF0 inc_f debugp mov_ff dsave_fsr0, FSR0L mov_ff dsave_fsr0+1, FSR0H return ;------------------------------------------------------------ outpins_local_init_part1 @ ; Initialises a table of output pins ; TBLPTR picno2map (presence bitmap) ; FSR0 ix2latbit - 1 (start of output table) ; W maxs / 8 (table sizes) ; outpins_local_init_part2 @ ; TBLPTR bkix2portnumbitnum (phys pins) ; FSR0 ix2latbit - 1 (start of output table) ; W maxs (table sizes) ; Caller must use both, and set variables as above on each entry. ; ; Input table is as made by writeasm_outpin ; Result table is series of 2-byte entries, ; 0th byte is bottom byte of LAT* address ; 1st byte is single-bit mask for the relevant pin ; Internals: ; We do this in two stages. ; Firstly, we scan the bitmap for this pic, setting ; ix2latbit to 0xff,0x00 for used points and 0x00,0x00 ; to unused ones. ; Secondly, we scan the bkix2portnumbitnum, adjusting ; ix2latbit to have actually correct data. ; Doing it like this avoids having to constantly recompute ; individual TBLPTR*'s. ; On entry FSR0 -> this bit and LAT* ; points just at last thing we've filled in mov_wf t ; t = byte counter ;... outpins_init_byte_loop mov_lw 8 ; W = bit counter tblrd_postinc_fixup ; TABLAT = bitmap data being processed ;... outpins_init_bit_loop clr_f PREINC0 ; FSR0 -> LAT*[current] := 0 rrc_f TABLAT bt_f_if1 STATUS,C set_f INDF0 ; FSR0 -still-> LAT*[current] := 0xff clr_f PREINC0 ; FSR0 -> bit[current] := 0 dec_w_ifnz bra outpins_init_bit_loop dec_f_ifnz t bra outpins_init_byte_loop ;... end of loop: ; We've scanned for points used on this board; ; now find the actual pins. return ; caller will reset outpins_local_init_part2 @ ; TBLPTR, FSR0 and W (see above) bt_f_if1 idloc1,idloc1_boarddet add_wff TBLPTRL set_f FSR2H ; FSR2 -> some SFR, will point to LAT/TRIS mov_lfsr bitnum2bit+7, 1 ; FSR1 -> bitnum2bit+7 mov_wf t ; t = loop counter ;... outpins_init_portbit_loop tblrd_postinc_fixup ; TABLAT = portnum4 || bitnum4 bt_f_if0 PREINC0,7 ; zero?, FSR0 -> LAT*[this] bra outpins_init_portbit_endif_used ;... outpins_init_portbit_if_used mov_fw TABLAT bra_n outpins_initing_bad_object ior_lw 0xf8 ; W -> bit value for bit mov_wf FSR1L ; FSR1 -> bit value for bit swap_fw TABLAT ; W = bitnum4 || portnum4 and_lw 0x0f ; W = portnum4 add_lw LATA & 0xff ; W = LAT* mov_wf POSTINC0 ; LAT*[this] := LAT, FSR0 -> bit[this] mov_wf FSR2L ; FSR2 -> LAT* mov_fw INDF1 ; W = bit mov_wf POSTDEC0 ; bit[this] = bit, FSR0 -> LAT*[this] com_w ; W = ~bit and_wff INDF2 ; LAT* &= ~bit, ie pin set to L (still Z) pin_vh pall_pt0reverse ; but pt0 pin is backwards, set to H ; (still Z, unless we've done this already) ; (we don't care about doing this far too ; many times here.) mov_lw TRISA-LATA add_wff FSR2L ; FSR2 -> TRIS* com_fw INDF1 ; W = ~bit and_wff INDF2 ; TRIS* &= ~bit, ie pin set to not Z set_f FSR1L ; FSR1 -> bitnum2bit+7, again outpins_init_portbit_endif_used ; so now we move on to the next one mov_fw POSTINC0 ; FSR0 -> bit[this] dec_f_ifnz t bra outpins_init_portbit_loop return ;---------- outpins_initing_bad_object panic morse_OF include final.inc