Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker.mit.edu!ai-lab!rice-chex!bson From: bson@rice-chex.ai.mit.edu (Jan Brittenson) Newsgroups: comp.sys.handhelds Subject: Re: Message-ID: <11887@life.ai.mit.edu> Date: 15 Nov 90 17:41:53 GMT References: <0471181703FF001A65@gacvx2.gac.edu> Sender: news@ai.mit.edu Organization: nil Lines: 890 In article <0471181703FF001A65@gacvx2.gac.edu> CW%APG.PH.UCL.AC.UK@pucc.PRINCETON.EDU writes: > my chip assembler and disassembler (which were very primitive!!!) were > very very slow and not too useful, and I gave up. Oh, c'mon, don't give up! Included here are two routines I wrote for the very same purpose. The first, GETINT, gets a 16-bit integer from a string object, byte addressed, with an offset of #200h. GETINT 2: chip-program.string 1: address.short --> 1: chip-opcode.short The second, CHID, takes a 16-bit integer and a 12-bit address, and returns a string object containing the CHIP instruction. CHID 2: chip-opcode.short 1: address.short --> 1: mnemonic.string If the address is nonzero, it will be precede the mnemonic. Now for the caveat. CHID suffers from the same problem as CHIP-48: it cannot (always) be called from a program. I haven't found out why, but my guess is that allocating a string shifts local variables/loop variables/return addresses, or something. I haven't had time to figure out exactly what goes wrong and when, but would be quite happy if someone did. Both programs are ASAP style. O / \/ /\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ O \ ;;+ ;; GETINT - Get 16-bit integer from CHIP program string ;; ;; s.str byteaddr.short --> int.short ;; ;; bson@ai.mit.edu, Nov 4, 1990 ;; ;;- getshort=#6641 shortpush_a_rplret=#18d07 save_regs=#679b restore_regs=#67d2 error_bad_arg_value=#18ca7 data.b 'H' data.b 'P' data.b 'H' data.b 'P' data.b '4' data.b '8' data.b '-' data.b 'D' data.a #2dcc begin: data.a end-begin getint: call.a getshort ; A=short arg swap.a c,d1 push.a c swap.a c,d1 move.p5 #200,c sub.a c,a ; Address less than #200 brcs error move.a @d1,c ; C=string move.a c,d1 add.a 5,d1 move.a @d1,c ; Get length sub.a 5,c srb.a c ; C=#chars dec.a c brle.a c,a,error ; Signal error if string too short add.a 5,d1 ; D1 = string base swap.a c,d1 add.a a,a add.a a,c swap.a c,d1 ; D1 = data address clr.a a move.b @d1,a ; Get high byte sln.a a sln.a a add.a 2,d1 move.b @d1,a ; Get low byte pop.a c move.a c,d1 ; Restore TOS add.a 5,d1 inc.a d call.a save_regs jump.a shortpush_a_rplret ; Signal error error: pop.a c move.a c,d1 ; Restore TOS add.a 5,d1 inc.a d jump.a error_bad_arg_value end: O / \/ /\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ O \ ;;+ ;; CHID -- Disassemble CHIP-48 instruction ;; ;; ;; bson@ai.mit.edu, Nov 4, 1990 ;; ;;- error_inv_def=#1104b save_regs=#679b restore_regs=#67d2 stralloc=#5b79 pushobj_a_rplret=#6ec9 getshort=#6641 data.b 'H' data.b 'P' data.b 'H' data.b 'P' data.b '4' data.b '8' data.b '-' data.b 'D' data.a #2dcc begin: data.a end-begin chdi: call.3 ref ref: call.a getshort move.w a,r3 ; R3 = address call.a getshort move.w a,r2 ; R2 = opcode call.a save_regs move.p5 opcode_table,a pop.a c add.a c,a move.a a,d0 ; Look through table. move.w r2,a try_next: clr.a b move.b @d0,c move.b c,b ; B=length brz.b b,no_match ; End of table add.a 2,d0 move.a @d0,c ; C=mask and.a a,c move.a c,d ; D=opcode & mask add.a 5,d0 move.a @d0,c ; C=value breq.a d,c,match ; Go decode if match swap.a a,d0 add.a b,a ; Skip remainder swap.a a,d0 brcc try_next ; Go for next ; We should never end up here. Signal suitable error. no_match: clr.w a move.w a,r0 move.w a,r1 move.w a,r2 move.w a,r3 call.a restore_regs jump.a error_inv_def ; "Invalid definition" ; A match has been made. Set things up for expansion. match: add.a 5,d0 clr.a c move.b @d0,c ; C.a=alloc size, chars add.a 2,d0 swap.a d0,a move.w a,r1 ; R1=def start swap.w a,r3 move.w a,r3 brz.a a,noaddr ; No adjustment for addr field add.a 5,c ; Add 5 chars for addr field noaddr: clrb #a,st call.a stralloc ; Allocate string swap.a a,d0 move.a a,d1 ; D1=string data addr swap.w a,r1 ; R1=string data addr, A=def addr move.a a,d0 ; D0=def addr ; Expand string from @d0 to @d1, count bytes in B. ; R2 contains the opcode. clr.a b ; No bytes accumulated yet ; If addr is nonzero, prefix with space-addr-space swap.w a,r3 brz.a a,expchar ; No addr - just opcode clr.a c call.3 exp_space ; Space move.1 2,p ; Nibbles 0-2 call.3 exp_hex_a clr.a c call.3 exp_space ; Expand def expchar: clr.a c move.b @d0,c add.a 2,d0 move.a c,d ; D=def char brz.b d,expdone ; Terminate at NUL move.1 0,p move.p2 1,c breq.b d,c,exp_nib_dec ; ^A=nib 0 inc.b c inc.1 p breq.b d,c,exp_nib_dec ; ^B=nib 1 inc.b c inc.1 p breq.b d,c,exp_nib_dec ; ^C=nib 2 inc.b c breq.b d,c,exp_nib0_p ; ^D=nib 0-2 inc.b c dec.1 p breq.b d,c,exp_nib0_p ; ^E=nib 0-1 inc.b c inc.1 p inc.1 p breq.b d,c,exp_nib0_p ; ^F=nib 0-3 ; Default - simply add D.b selfins: move.b d,c call.3 exp_c ; Add C.b to buffer brnz.a b,expchar ; Next char ; Expand R2.p, in decimal exp_nib_dec: move.w r2,c ; C=opcode call.3 exp_nib_c ; Add C.p to output buffer brnz.a b,expchar ; Expand R2.wp, in hex exp_nib0_p: move.w r2,a call.3 exp_hex_a ; Expand a.wp brnz.a b,expchar ; Expand next char of def ; Expansion done expdone: swap.w a,r1 move.a a,d0 ; D0 = string addr sub.a 5,d0 move.a b,c add.a c,c ; Chars to nibbles add.a 5,c ; Add 5 for length word move.a c,@d0 ; Set length sub.a 5,d0 swap.a a,d0 move.w a,r0 move.1 0,p call.a restore_regs swap.w r0,a clrb #a,st clr.w c move.w c,r0 move.w c,r1 move.w c,r2 move.w c,r3 jump.a pushobj_a_rplret ; Add space to output buffer exp_space: move.p2 ' ',c ; Add C.b to output buffer exp_c: move.b c,@d1 add.a 2,d1 inc.a b ret ; Add C.p to output buffer, in decimal exp_nib_c: breq.1 p,0,exp_nib_shfx exp_nib_shf: ; Shift so we have the nibble in A.1 srn.a c dec.1 p brne.1 p,0,exp_nib_shf exp_nib_shfx: clr.a a move.p1 #f,a and.a a,c ; Mask low nibble move.p1 10,a brlt.a c,a,exp_digit ; < 10 push.a c move.p2 '1',c ; Prefix with '1' call.3 exp_c pop.a c sub.a a,c ; Reduce digit by 10 exp_digit: move.p2 '0',a add.b a,c brnz.a c,exp_c ; Add C.b and return ; Expand A.wp, in hex exp_hex_a: clr.a c add.a p+1,c move.a c,d ; D=#nibbles add.a c,b ; Update char counter expshf: rrn.w a ; Rot A right P+1 nibbles dec.a d brnz.a d,expshf expshfx: move.a c,d ; D=#nibbles move.1 0,p exp_next_hex: clr.a a rln.w a ; Move highest nibble into C.1 clr.a c move.p1 #a,c brgt.a c,a,exp_hexdig move.p1 7,c add.b c,a exp_hexdig: move.p2 '0',c add.b c,a move.b a,@d1 ; Add to string add.a 2,d1 dec.a d brnz.b d,exp_next_hex ret ; Opcode definitions dummy: opcode_table=dummy-ref data.b 19 data.a #ffff data.a #e0 data.b 6 data.b #43 data.b #4c data.b #4c data.b #43 data.b #44 data.b 0 data.b 21 data.a #ffff data.a #ee data.b 7 data.b #52 data.b #45 data.b #54 data.b #55 data.b #52 data.b #4e data.b 0 data.b 23 data.a #f000 data.a #0 data.b 11 data.b #4d data.b #43 data.b #41 data.b #4c data.b #4c data.b #20 data.b #4 data.b 0 data.b 21 data.a #f000 data.a #1000 data.b 10 data.b #4a data.b #55 data.b #4d data.b #50 data.b #20 data.b #4 data.b 0 data.b 21 data.a #f000 data.a #2000 data.b 10 data.b #43 data.b #41 data.b #4c data.b #4c data.b #20 data.b #4 data.b 0 data.b 33 data.a #f000 data.a #3000 data.b 16 data.b #53 data.b #4b data.b #49 data.b #50 data.b #20 data.b #49 data.b #46 data.b #20 data.b #56 data.b #3 data.b #3d data.b #5 data.b 0 data.b 33 data.a #f000 data.a #4000 data.b 16 data.b #53 data.b #4b data.b #49 data.b #50 data.b #20 data.b #49 data.b #46 data.b #20 data.b #56 data.b #3 data.b #8b data.b #5 data.b 0 data.b 35 data.a #f00f data.a #5000 data.b 17 data.b #53 data.b #4b data.b #49 data.b #50 data.b #20 data.b #49 data.b #46 data.b #20 data.b #56 data.b #3 data.b #3d data.b #56 data.b #2 data.b 0 data.b 17 data.a #f000 data.a #6000 data.b 8 data.b #56 data.b #3 data.b #8e data.b #5 data.b 0 data.b 19 data.a #f000 data.a #7000 data.b 9 data.b #56 data.b #3 data.b #2b data.b #8e data.b #5 data.b 0 data.b 19 data.a #f00f data.a #8000 data.b 9 data.b #56 data.b #3 data.b #8e data.b #56 data.b #2 data.b 0 data.b 21 data.a #f00f data.a #8001 data.b 10 data.b #56 data.b #3 data.b #7c data.b #8e data.b #56 data.b #2 data.b 0 data.b 21 data.a #f00f data.a #8002 data.b 10 data.b #56 data.b #3 data.b #26 data.b #8e data.b #56 data.b #2 data.b 0 data.b 21 data.a #f00f data.a #8003 data.b 10 data.b #56 data.b #3 data.b #5e data.b #8e data.b #56 data.b #2 data.b 0 data.b 21 data.a #f00f data.a #8004 data.b 10 data.b #56 data.b #3 data.b #2b data.b #8e data.b #56 data.b #2 data.b 0 data.b 21 data.a #f00f data.a #8005 data.b 10 data.b #56 data.b #3 data.b #2d data.b #8e data.b #56 data.b #2 data.b 0 data.b 19 data.a #f00f data.a #8006 data.b 8 data.b #56 data.b #3 data.b #bb data.b #8e data.b #31 data.b 0 data.b 23 data.a #f00f data.a #8007 data.b 11 data.b #56 data.b #3 data.b #2d data.b #8e data.b #2d data.b #56 data.b #2 data.b 0 data.b 19 data.a #f00f data.a #800e data.b 8 data.b #56 data.b #3 data.b #ab data.b #8e data.b #31 data.b 0 data.b 35 data.a #f00f data.a #9000 data.b 17 data.b #53 data.b #4b data.b #49 data.b #50 data.b #20 data.b #49 data.b #46 data.b #20 data.b #56 data.b #3 data.b #8b data.b #56 data.b #2 data.b 0 data.b 15 data.a #f000 data.a #a000 data.b 7 data.b #49 data.b #8e data.b #4 data.b 0 data.b 27 data.a #f000 data.a #b000 data.b 13 data.b #4a data.b #55 data.b #4d data.b #50 data.b #20 data.b #4 data.b #2b data.b #56 data.b #30 data.b 0 data.b 27 data.a #f000 data.a #c000 data.b 14 data.b #56 data.b #3 data.b #8e data.b #52 data.b #41 data.b #4e data.b #44 data.b #26 data.b #5 data.b 0 data.b 35 data.a #f000 data.a #d000 data.b 18 data.b #53 data.b #48 data.b #4f data.b #57 data.b #20 data.b #1 data.b #28 data.b #56 data.b #3 data.b #2c data.b #56 data.b #2 data.b #29 data.b 0 data.b 37 data.a #f0ff data.a #e09e data.b 17 data.b #53 data.b #4b data.b #49 data.b #50 data.b #20 data.b #49 data.b #46 data.b #20 data.b #4b data.b #45 data.b #59 data.b #20 data.b #56 data.b #3 data.b 0 data.b 39 data.a #f0ff data.a #e0a1 data.b 18 data.b #53 data.b #4b data.b #49 data.b #50 data.b #20 data.b #49 data.b #46 data.b #20 data.b #21 data.b #4b data.b #45 data.b #59 data.b #20 data.b #56 data.b #3 data.b 0 data.b 25 data.a #f0ff data.a #f007 data.b 11 data.b #56 data.b #3 data.b #8e data.b #44 data.b #45 data.b #4c data.b #41 data.b #59 data.b 0 data.b 23 data.a #f0ff data.a #f00a data.b 10 data.b #57 data.b #41 data.b #49 data.b #54 data.b #20 data.b #56 data.b #3 data.b 0 data.b 25 data.a #f0ff data.a #f015 data.b 11 data.b #44 data.b #45 data.b #4c data.b #41 data.b #59 data.b #8e data.b #56 data.b #3 data.b 0 data.b 25 data.a #f0ff data.a #f018 data.b 11 data.b #53 data.b #4f data.b #55 data.b #4e data.b #44 data.b #8e data.b #56 data.b #3 data.b 0 data.b 19 data.a #f0ff data.a #f01e data.b 8 data.b #49 data.b #2b data.b #8e data.b #56 data.b #3 data.b 0 data.b 33 data.a #f0ff data.a #f029 data.b 15 data.b #49 data.b #8e data.b #53 data.b #50 data.b #52 data.b #49 data.b #54 data.b #45 data.b #28 data.b #56 data.b #3 data.b #29 data.b 0 data.b 33 data.a #f0ff data.a #f033 data.b 15 data.b #4d data.b #28 data.b #49 data.b #29 data.b #8e data.b #42 data.b #43 data.b #44 data.b #28 data.b #56 data.b #3 data.b #29 data.b 0 data.b 29 data.a #f0ff data.a #f055 data.b 13 data.b #4d data.b #28 data.b #49 data.b #29 data.b #8e data.b #56 data.b #30 data.b #1f data.b #56 data.b #3 data.b 0 data.b 29 data.a #f0ff data.a #f065 data.b 13 data.b #56 data.b #30 data.b #1f data.b #56 data.b #3 data.b #8e data.b #4d data.b #28 data.b #49 data.b #29 data.b 0 data.b 21 data.a #0 data.a #0 data.b 11 data.b #44 data.b #41 data.b #54 data.b #41 data.b #20 data.b #6 data.b 0 data.b 0 end: