; dv2.src -- program for dvorak box rev. 1 hardware ; keyboard routines ; ; copyright (c) 1999 Andrew Huang ; I make no warranties or guarantees on the functionality of ; this code for your application. Use at your own risk. ; ; /*** includes make it work ***/ maclib 'p84.inc' ; /*** device specific declarations ***/ device pic16c84,xt_osc,wdt_off,pwrt_on,protect_off ; /*** defines ***/ ; note tht 1 is an input, 0 is an output for ports dir_a = 01fh ;all in dir_b = 00h ;all out HCLKRX = 004h HCLKRXN = 0FBh HCLKTX = 004h HCLKTXN = 0FBh HDATRX = 008h HDATRXN = 0F7h HDATTX = 008h HDATTXN = 0F7h KCLKRX = 002h KCLKRXN = 0FDh KCLKTX = 020h KCLKTXN = 0DFh KDATRX = 001h KDATRXN = 0FEh KDATTX = 010h KDATTXN = 0EFh MODESW = 010h ; RA4/T0CKI (make sure this is mapped right) ; /*** global variables ***/ org 0ch ;start of ram space keycode ds 1 del1us_cnt ds 1 ;delay counter rb_tmp ds 1 ra_tmp ds 1 hbits ds 1 hbitr ds 1 kbits ds 1 kbitr ds 1 tmp ds 1 ret_val ds 1 hdata ds 1 hctl ds 1 kdata ds 1 kctl ds 1 ghd_tmp ds 1 binary ds 1 e0flag ds 1 ; used as a global variable!!!! parity ds 1 paritytmp ds 1 ploop ds 1 ; /*** reset vector code ***/ org 0 ;reset vector jmp start ;go to beginning of program on reset ; /*** this declares where code starts ***/ ; org 5 ;start of code space ; ; ; retw 'dv1 -- Andrew Huang (bunnie@mit.edu) 12/24/96' table addwf pcl ; w = offset, pc = pc + w + 1 retlw 000h ; keycode 0x00 no opcode 0 retlw 001h ; keycode 0x01 retlw 002h ; keycode 0x02 retlw 003h ; keycode 0x03 retlw 004h ; keycode 0x04 retlw 005h ; keycode 0x05 retlw 006h ; keycode 0x06 retlw 007h ; keycode 0x07 retlw 008h ; keycode 0x08 retlw 009h ; keycode 0x09 retlw 00ah ; keycode 0x0A retlw 00bh ; keycode 0x0B retlw 00ch ; keycode 0x0C retlw 00dh ; keycode 0x0D retlw 00eh ; keycode 0x0E retlw 00fh ; keycode 0x0F retlw 010h ; keycode 0x10 retlw 011h ; keycode 0x11 retlw 012h ; keycode 0x12 retlw 013h ; keycode 0x13 retlw 014h ; keycode 0x14 retlw 052h ; keycode 0x15 = Q to ' retlw 016h ; keycode 0x16 retlw 017h ; keycode 0x17 retlw 018h ; keycode 0x18 retlw 019h ; keycode 0x19 retlw 04ch ; keycode 0x1A = Z to ; retlw 044h ; keycode 0x1B = S to O retlw 01ch ; keycode 0x1C = A to A retlw 041h ; keycode 0x1D = W to , retlw 01eh ; keycode 0x1E retlw 01fh ; keycode 0x1F retlw 020h ; keycode 0x20 retlw 03Bh ; keycode 0x21 = C to J retlw 015h ; keycode 0x22 = X to Q retlw 024h ; keycode 0x23 = D to E retlw 049h ; keycode 0x24 = E to . retlw 025h ; keycode 0x25 retlw 026h ; keycode 0x26 retlw 027h ; keycode 0x27 retlw 028h ; keycode 0x28 retlw 029h ; keycode 0x29 retlw 042h ; keycode 0x2A = V to K retlw 03Ch ; keycode 0x2B = E to U retlw 035h ; keycode 0x2C = T to Y retlw 04Dh ; keycode 0x2D = R to P retlw 02eh ; keycode 0x2E retlw 02fh ; keycode 0x2F retlw 030h ; keycode 0x30 retlw 032h ; keycode 0x31 = N to B retlw 022h ; keycode 0x32 = B to X retlw 023h ; keycode 0x33 = H to D retlw 043h ; keycode 0x34 = G to I retlw 02Bh ; keycode 0x35 = Y to F retlw 036h ; keycode 0x36 retlw 037h ; keycode 0x37 retlw 038h ; keycode 0x38 retlw 039h ; keycode 0x39 retlw 03ah ; keycode 0x3A = M to M retlw 033h ; keycode 0x3B = J to H retlw 034h ; keycode 0x3C = U to G retlw 03dh ; keycode 0x3D retlw 03eh ; keycode 0x3E retlw 03fh ; keycode 0x3F retlw 040h ; keycode 0x40 retlw 01Dh ; keycode 0x41 = , to W retlw 02Ch ; keycode 0x42 = K to T retlw 021h ; keycode 0x43 = I to C retlw 02Dh ; keycode 0x44 = O to R retlw 045h ; keycode 0x45 retlw 046h ; keycode 0x46 retlw 047h ; keycode 0x47 retlw 048h ; keycode 0x48 retlw 02ah ; keycode 0x49 = . to V retlw 01Ah ; keycode 0x4A = / to Z retlw 031h ; keycode 0x4B = L to N retlw 01Bh ; keycode 0x4C = ; to S retlw 04Bh ; keycode 0x4D = P to L retlw 054h ; keycode 0x4E = - to [ retlw 04fh ; keycode 0x4F retlw 050h ; keycode 0x50 retlw 051h ; keycode 0x51 retlw 04eh ; keycode 0x52 = ' to - retlw 053h ; keycode 0x53 retlw 04Ah ; keycode 0x54 = [ to / retlw 05Bh ; keycode 0x55 = = to ] retlw 056h ; keycode 0x56 retlw 057h ; keycode 0x57 retlw 058h ; keycode 0x58 retlw 059h ; keycode 0x59 retlw 05ah ; keycode 0x5A retlw 055h ; keycode 0x5B = ] to = retlw 05ch ; keycode 0x5C retlw 05dh ; keycode 0x5D retlw 05eh ; keycode 0x5E retlw 05fh ; keycode 0x5F retlw 060h ; keycode 0x60 retlw 061h ; keycode 0x61 retlw 062h ; keycode 0x62 retlw 063h ; keycode 0x63 retlw 064h ; keycode 0x64 retlw 065h ; keycode 0x65 retlw 066h ; keycode 0x66 retlw 067h ; keycode 0x67 retlw 068h ; keycode 0x68 retlw 069h ; keycode 0x69 retlw 06ah ; keycode 0x6A retlw 06bh ; keycode 0x6B retlw 06ch ; keycode 0x6C retlw 06dh ; keycode 0x6D retlw 06eh ; keycode 0x6E retlw 06fh ; keycode 0x6F retlw 070h ; keycode 0x70 retlw 071h ; keycode 0x71 retlw 072h ; keycode 0x72 retlw 073h ; keycode 0x73 retlw 074h ; keycode 0x74 retlw 075h ; keycode 0x75 retlw 076h ; keycode 0x76 retlw 077h ; keycode 0x77 retlw 078h ; keycode 0x78 retlw 079h ; keycode 0x79 retlw 07ah ; keycode 0x7A retlw 07bh ; keycode 0x7B retlw 07ch ; keycode 0x7C retlw 07dh ; keycode 0x7D retlw 07eh ; keycode 0x7E retlw 07fh ; keycode 0x7F retlw 080h ; keycode 0x80 retlw 081h ; keycode 0x81 retlw 082h ; keycode 0x82 retlw 083h ; keycode 0x83 retlw 084h ; keycode 0x84 retlw 085h ; keycode 0x85 retlw 086h ; keycode 0x86 retlw 087h ; keycode 0x87 retlw 088h ; keycode 0x88 retlw 089h ; keycode 0x89 retlw 08ah ; keycode 0x8A retlw 08bh ; keycode 0x8B retlw 08ch ; keycode 0x8C retlw 08dh ; keycode 0x8D retlw 08eh ; keycode 0x8E retlw 08fh ; keycode 0x8F retlw 090h ; keycode 0x90 retlw 091h ; keycode 0x91 retlw 092h ; keycode 0x92 retlw 093h ; keycode 0x93 retlw 094h ; keycode 0x94 retlw 095h ; keycode 0x95 retlw 096h ; keycode 0x96 retlw 097h ; keycode 0x97 retlw 098h ; keycode 0x98 retlw 099h ; keycode 0x99 retlw 09ah ; keycode 0x9A retlw 09bh ; keycode 0x9B retlw 09ch ; keycode 0x9C retlw 09dh ; keycode 0x9D retlw 09eh ; keycode 0x9E retlw 09fh ; keycode 0x9F retlw 0a0h ; keycode 0xA0 retlw 0a1h ; keycode 0xA1 retlw 0a2h ; keycode 0xA2 retlw 0a3h ; keycode 0xA3 retlw 0a4h ; keycode 0xA4 retlw 0a5h ; keycode 0xA5 retlw 0a6h ; keycode 0xA6 retlw 0a7h ; keycode 0xA7 retlw 0a8h ; keycode 0xA8 retlw 0a9h ; keycode 0xA9 retlw 0aah ; keycode 0xAA retlw 0abh ; keycode 0xAB retlw 0ach ; keycode 0xAC retlw 0adh ; keycode 0xAD retlw 0aeh ; keycode 0xAE retlw 0afh ; keycode 0xAF retlw 0b0h ; keycode 0xB0 retlw 0b1h ; keycode 0xB1 retlw 0b2h ; keycode 0xB2 retlw 0b3h ; keycode 0xB3 retlw 0b4h ; keycode 0xB4 retlw 0b5h ; keycode 0xB5 retlw 0b6h ; keycode 0xB6 retlw 0b7h ; keycode 0xB7 retlw 0b8h ; keycode 0xB8 retlw 0b9h ; keycode 0xB9 retlw 0bah ; keycode 0xBA retlw 0bbh ; keycode 0xBB retlw 0bch ; keycode 0xBC retlw 0bdh ; keycode 0xBD retlw 0beh ; keycode 0xBE retlw 0bfh ; keycode 0xBF retlw 0c0h ; keycode 0xC0 retlw 0c1h ; keycode 0xC1 retlw 0c2h ; keycode 0xC2 retlw 0c3h ; keycode 0xC3 retlw 0c4h ; keycode 0xC4 retlw 0c5h ; keycode 0xC5 retlw 0c6h ; keycode 0xC6 retlw 0c7h ; keycode 0xC7 retlw 0c8h ; keycode 0xC8 retlw 0c9h ; keycode 0xC9 retlw 0cah ; keycode 0xCA retlw 0cbh ; keycode 0xCB retlw 0cch ; keycode 0xCC retlw 0cdh ; keycode 0xCD retlw 0ceh ; keycode 0xCE retlw 0cfh ; keycode 0xCF retlw 0d0h ; keycode 0xD0 retlw 0d1h ; keycode 0xD1 retlw 0d2h ; keycode 0xD2 retlw 0d3h ; keycode 0xD3 retlw 0d4h ; keycode 0xD4 retlw 0d5h ; keycode 0xD5 retlw 0d6h ; keycode 0xD6 retlw 0d7h ; keycode 0xD7 retlw 0d8h ; keycode 0xD8 retlw 0d9h ; keycode 0xD9 retlw 0dah ; keycode 0xDA retlw 0dbh ; keycode 0xDB retlw 0dch ; keycode 0xDC retlw 0ddh ; keycode 0xDD retlw 0deh ; keycode 0xDE retlw 0dfh ; keycode 0xDF retlw 0e0h ; keycode 0xE0 retlw 0e1h ; keycode 0xE1 retlw 0e2h ; keycode 0xE2 retlw 0e3h ; keycode 0xE3 retlw 0e4h ; keycode 0xE4 retlw 0e5h ; keycode 0xE5 retlw 0e6h ; keycode 0xE6 retlw 0e7h ; keycode 0xE7 retlw 0e8h ; keycode 0xE8 retlw 0e9h ; keycode 0xE9 retlw 0eah ; keycode 0xEA retlw 0ebh ; keycode 0xEB retlw 0ech ; keycode 0xEC retlw 0edh ; keycode 0xED retlw 0eeh ; keycode 0xEE retlw 0efh ; keycode 0xEF retlw 0f0h ; keycode 0xF0 retlw 0f1h ; keycode 0xF1 retlw 0f2h ; keycode 0xF2 retlw 0f3h ; keycode 0xF3 retlw 0f4h ; keycode 0xF4 retlw 0f5h ; keycode 0xF5 retlw 0f6h ; keycode 0xF6 retlw 0f7h ; keycode 0xF7 retlw 0f8h ; keycode 0xF8 retlw 0f9h ; keycode 0xF9 retlw 0fah ; keycode 0xFA retlw 0fbh ; keycode 0xFB retlw 0fch ; keycode 0xFC retlw 0fdh ; keycode 0xFD retlw 0feh ; keycode 0xFE retlw 0ffh ; keycode 0xFF ; /* ; * ; * delay for about 1 us based on 4mhz clock cycle ; * ; */ ; 4 clocks overhead: 2 cycles each for mov and ret ; core loop: nop is 1 cycle, djnz is 3 cycles = 4 total cycles ; at 4 MHz cycle time is 1 us; desired delay is 50 us, so we need ; 50 cycles of instructions to do this. ; 50 - 4 = 46 clocks in loop ; 46 / 4 = 11 and 2 cycles. Rather go under than over. So 11 is the ; magic delay number (note that constants are radix 10 by default) del50us mov del1us_cnt,#4 del1us1 nop djnz del1us_cnt,del1us1 ret ; /* ; * hsendbit -- send a bit to the host, acting like a keyboard ; * return 1 on success, 0 on fail ; */ hsendbit mov rb_tmp, rb ; get rb value and rb_tmp, #HCLKTXN ; host clock high mov rb, rb_tmp btfss hbits, 3 ; check data to send HDATTX goto hsb1 ; is clear? then go to hsb1 and rb_tmp, #HDATTXN ; do this if bit is set goto hsb2 hsb1 not hbits ; do this if bit is to be cleared or rb_tmp, #HDATTX ; HDATTX hsb2 mov rb, rb_tmp call del50us ; wait while clock high mov ra_tmp, ra ; test to see if clock is not pulled low or ra_tmp, #HCLKRXN ; jz hsbfail mov rb_tmp, rb or rb_tmp, #HCLKTX ; now send clock low (HCLKTXN) mov rb, rb_tmp call del50us ; wait while clock is low mov ret_val,#1 ; return 1 for success ret ; return hsbfail mov ret_val,#0 ret ; return 0 for fail ; /* ; * ksendbit -- send a bit to the keyboard, acting like the host ; * return 1 on success, 0 on fail ; * assume clock line is high, on the falling edge ; */ ksendbit ; > wait for KCLK to go low < mov ra_tmp, ra ; get incoming (ra) value btfsc ra_tmp, 1 ; see if KCLKRX has fallen goto ksendbit ; this line skipped if KCLKRX is 0 mov rb_tmp, rb ; setup rb_tmp ; > set the bit to be xmit to keyboard < btfss kbits, 4 ; check data to send (KDATTX) goto ksb1 ; is clear? then go to hsb1 and rb_tmp, #KDATTXN ; do this if bit is set goto ksb2 ksb1 not kbits ; do this if bit is to be cleared or rb_tmp, #KDATTX ksb2 mov rb, rb_tmp ret ; return -- always successful ; /* ; * hgetbit -- get a bit from host acting as keyboard ; * return 0xFF if bit is 1, 0x00 if bit is 0 ; * assume: clock is high, just at end of rising edge ; */ hgetbit mov rb_tmp, rb or rb_tmp, #HCLKTX ; >set HCLKTX to 0< mov rb, rb_tmp call del50us mov ra_tmp, ra ; get input stuff and rb_tmp, #HCLKTXN ; >set HCLKTX to 1< mov rb, rb_tmp call del50us btfsc ra_tmp, 3 ; bit 3 is HDATRX location goto hgbset ; skips this line if HDATRX is 1 mov ret_val,#0 ; so HDATRX is 0, return 0 ret hgbset mov ret_val,#0FFh ; so HDATRX is 1, return 0xFF ret ; /* ; * kgetbit -- get a bit from keyboard acting as host ; * return 0xFF is bit is 1, 0x00 if bit is 0 ; */ kgetbit mov ra_tmp, ra ; wait until KCLKRX is 0 btfsc ra_tmp, 1 ; bit 1 is KCLKRX location goto kgetbit ; skips this line if KCLKRX is 0 ; mov ra_tmp, rb ; get new value (makes for hold time) btfsc ra_tmp, 0 ; bit 0 is KDATRX location goto kgbset ; skips this line if KDATRX is 0 mov ret_val,#0 ; so KDATRX is 0, return 0 ret kgbset mov ret_val,#0FFh ; so KDATRX is 1, return 1 ret ; /* ; * gethdat -- get a byte from the host as if keyboard ; */ gethdat mov hdata, #00 ; clear hdata value mov hctl, #00 ; clear hctl value mov rb_tmp, rb and rb_tmp, #07Fh ; set rb7 0 for debug info mov rb, rb_tmp ghdloop mov ra_tmp, ra ; get ra value btfss ra_tmp, 2 ; bit 2 is HCLKRX goto ghdloop ; loop until HCLKRX is 1 mov ghd_tmp, #8 ; setup the loop counter for 8 bits ghdloop2 cje ghd_tmp, #0, ghdend ; see if loop has exhausted call hgetbit btfss ret_val, 0 ; >see if returned value is 0< goto ghdclr ; skip this line if returned value was 1 stc ; set carry flag (return is 1) rrf hdata,1 ; rotate hdata right & store back in f dec ghd_tmp ; decrement loop counter goto ghdloop2 ; go back until you have 8 bits ghdclr clc ; clear carry flag (return was 0) rrf hdata,1 ; rotate hdata right & store back in f dec ghd_tmp ; decrement loop counter goto ghdloop2 ; go back until you have 8 bits ghdend call hgetbit ; >get and store parity bit< btfss ret_val, 0 ; see if returned value is 0 goto ghd1 ; skip this line if returned value was 1 mov hctl,#1 ; note that hctl is init to 0 at beginning ghd1 call hgetbit ; get the stop bit, don't store ; we're now at trailing edge of clock for ; stop bit (clock is still high) mov rb_tmp, rb or rb_tmp, #HCLKTX ; >set HCLKTX to 0< mov rb, rb_tmp or rb_tmp, #HDATTX ; >set KDATTX low for one rising edge< mov rb, rb_tmp call del50us and rb_tmp, #HCLKTXN ; >set HCLKTX to 1< mov rb, rb_tmp call del50us and rb_tmp, #HDATTXN ; >set HDATTX to 1< mov rb, rb_tmp call sendkdat ; now echo data to keyboard! ret ; /* ; * sendkdat -- send data to keyboard as if host ; */ sendkdat mov rb_tmp, rb ; >set KCLK,KDAT low for 100us< or rb_tmp, #KCLKTX ; KCLXTX or rb_tmp, #KDATTX ; KDATTX mov rb, rb_tmp call del50us call del50us and rb_tmp, #KCLKTXN ; >set KCLK high again< mov rb, rb_tmp nop ; >give a nop for line to settle< mov ghd_tmp, #8 skdloop cje ghd_tmp, #0, skdend dec ghd_tmp rrf hdata,1 ; >determine what bit type to send< jc skdset ; jump if we are sending a 1 mov kbits, #0 ; set kbits to 0 to send 0 call ksendbit jmp skdloop skdset mov kbits, #KDATTX ; set kbits to KDATTX to send data call ksendbit jmp skdloop skdend rrf hctl, 1 ; >send the parity bit< jc skd1 ; jump if we are sending a 1 mov kbits, #0 call ksendbit jmp skd2 skd1 mov kbits, #KDATTX call ksendbit skd2 mov kbits, #0 ; >send stop bit of 0< call ksendbit ; now we would check to see that the keyboard has reciprocated ; low value but I don't care at this point. mov rb_tmp, rb ; >set lines idle< and rb_tmp, #KDATTXN and rb_tmp, #KCLKTXN mov rb, rb_tmp mov rb_tmp, rb and rb_tmp, #0BFh ; set rb6 low for debug info mov rb, rb_tmp ;debug goto debug ; and stop! ret ; /* ; * getkdat -- get keyboard data as if host ; */ getkdat mov kdata, #0 mov kctl, #0 mov ghd_tmp, #8 ; setup the loop counter for 8 bits gkdloop2 cje ghd_tmp, #0, gkdend ; see if loop has exhausted gkd2 mov ra_tmp, ra ; > wait till clock high < btfss ra_tmp, 1 goto gkd2 call kgetbit btfss ret_val, 0 ; >see if returned value is 0< goto gkdclr ; skip this line if returned value was 1 stc ; set carry flag (return is 1) rrf kdata,1 ; rotate kdata right & store back in f dec ghd_tmp ; decrement loop counter goto gkdloop2 ; go back until you have 8 bits gkdclr clc ; clear carry flag (return was 0) rrf kdata,1 ; rotate kdata right & store back in f dec ghd_tmp ; decrement loop counter goto gkdloop2 ; go back until you have 8 bits gkdend mov ra_tmp, ra ; > wait till clock high < btfss ra_tmp, 1 goto gkdend call kgetbit ; > get parity bit < ; working marker btfss ret_val, 0 goto gkd1 ; this line skipped if 1 mov kctl, #1 ; set parity to 1 gkd1 ; note that kctl has been init'd to 0 ;working marker mov rb_tmp, rb ; > set stop bit of 0< or rb_tmp, #KDATTX mov rb, rb_tmp ; broken marker gkd3 mov ra_tmp, ra ; > wait till clock high < btfss ra_tmp, 1 goto gkd3 call kgetbit ; dummy cycle; value discarded ; broken marker mov rb_tmp, rb and rb_tmp, #KDATTXN ; reset stop bit to 1 mov rb, rb_tmp ; now I would wait for keyboard's ack cycle of 1 bit but ; I don't care ; broken marker mov ra_tmp, ra ; >check to see state of mode switch!< btfss ra_tmp, 4 ; bit 4 is ra4 => mode switch goto gkd4 ; this line skipped if mode switch = 1 cjne kdata, #0e0h, gkd5 ; if not e0 then skip setting e0flag mov e0flag, #01h ; set e0 flag goto e0skip ; skip the next line, of course gkd5 cje e0flag, #01h, gkd6 ; if e0 flag set skip translation, clear flag e0skip mov keycode, kdata ; this line executed if mode sw = 1 call remap ; remap the keycode! mov kdata, keycode ; only if not an E0 code sequence mov paritytmp, kdata ; > recalculate parity! < mov ploop, #8 ; parity is odd, eg, 0 when # of 1's is odd mov parity, #1 ; setup parity output; if all 0, then 1 out plabel cje ploop, #0, gkd7 ; exit loop after 8 bits have been processed rrf paritytmp, 1 ; rotate paritytmp jc ptoggle ; if bit was 1, toggle parity bit dec ploop ; else, decrement loop counter and go back! jmp plabel ptoggle btfss parity, 0 goto ptog2 ; this line skipped if parity is 1 mov parity, #0 ; this line executed if parity is 1 dec ploop jmp plabel ptog2 mov parity, #1 ; this line executed if parity is 0 dec ploop jmp plabel gkd7 mov kctl, parity ; set the parity arg for sendhdat goto gkd4 gkd6 mov e0flag, #00h ; clear e0 flag > skip translation < ; this skips translation gkd4 call sendhdat ; echo data to host mov rb_tmp, rb ; reset TX lines and rb_tmp, #KDATTXN and rb_tmp, #KCLKTXN mov rb_tmp, #000h ; wholesale reset mov rb, rb_tmp call del50us ; wait for lines to settle call del50us ; wait for lines to settle ret ; /* ; * sendhdat -- send data to host acting as keyboard ; */ sendhdat mov rb_tmp, rb ; > set HDAT, HCLK low < or rb_tmp, #HDATTX ; HDATTXN or rb_tmp, #HCLKTX ; HCLKTXN mov rb, rb_tmp call del50us call del50us mov ghd_tmp, #8 shdloop cje ghd_tmp, #0, shdend dec ghd_tmp rrf kdata,1 ; >determine what bit type to send< jc shdset ; jump if we are sending a 1 mov hbits, #0 ; set kbits to 0 to send 0 call hsendbit jmp shdloop shdset mov hbits, #HDATTX ; set hbits to HDATTX to send data call hsendbit jmp shdloop shdend rrf kctl, 1 ; >send the parity bit< jc shd1 ; jump if we are sending a 1 mov hbits, #0 call hsendbit jmp shd2 shd1 mov hbits, #HDATTX call hsendbit shd2 mov hbits, #HDATTX ; >do a null cycle for stop bit< call hsendbit mov hbits, #HDATTX ; >now send a 1 to reciprocate< call hsendbit mov rb_tmp, rb ; >reset lines to high state< and rb_tmp, #HDATTXN and rb_tmp, #HCLKTXN mov rb, rb_tmp ; call del50us ; give the lines some settling time ret ; /* ; * ; * program execution begins here ; * ; */ start mov !ra, #dir_a ; setup port A mov !rb, #dir_b ; setup port B mov !ra, #dir_a ; redundant to try to get startup reliable mov !rb, #dir_b mov rb, #000h ; set all lines idle (high) call del50us call del50us mov e0flag, #00h ; clear e0 flag (this is global!!!) mloop nop nop nop nop mov ra_tmp, ra ; listen for incoming data btfss ra_tmp, 1 ; is KCLKRX 0? call getkdat ; if so, go to getkdat (skipped if 1) btfss ra_tmp, 2 ; is HCLKRX 0? call gethdat ; if so, go to gethdat (skipped if 1) goto mloop ; keep on listening! ; /* ; * remap -- take in a qwerty keycode and turn it into dvorak ; * keycode is the I/O argument. ; */ remap mov W, keycode ; destination is W register andlw 0ffh ; make sure W has only 8 bits call table ; w contains table offset value ; on return, table value is in W mov keycode, W ; keycode now has table value ret ; exit routine org 0200h