NRTS ver. 0.5 HP48sx dumb terminal program Bill Gribble I. Introduction This is the first release version of NRTS, a dumb terminal program. After fairly extensive betatesting I feel it's ready for general distribution. NRTS has about the functionality of other currently available terminal programs; that is, it doesn't process escape sequences and processes only a few control characters. Its fundamental advantage is speed. The bulk of the program is written in machine code, interspersed with RPL threads where I needed them, and is quite quick. Also, NRTS has at least one feature that's different and, I think, sort of neat: the function keys, which I'll talk about later. You may notice that the version number of this release is 0.5; I am still working on an ANSI code parser that will make NRTS a "real" terminal emulator, and hopefully allow anyone who feels the need to run an 8x22 EMACS session :-) That version will be 1.0, since I don't think the program's finished until it has escape code processing. NRTS is enclosed as an ASC'ed directory containing the program and the FKEYS function key list with some sample function keys. I don't have real documentation produced, but I will try to make this text thorough enough to make do. II. General information. As mentioned before, NRTS uses an 8x22 text display screen. It uses a subset of the HP48's medium font including only the characters from ASCII 32 thru 127. Control characters are all processed, meaning they aren't displayed as those irritating little squares. Escape sequences appear as text. Each key on the keyboard has up to four assignments: unshifted, blue-shifted, orange-shifted, and alpha-shifted. As a rule, unshifted = lowercase alpha, blue-shifted = uppercase alpha, orange-shifted = control, and alpha-shifted are program control and function keys. Complete keymaps follow in their own section. Unfortunately, in the interests of speed the key assignments are built in the program in a lookup table. They are easy to change in the source, but difficult once the program is compiled. This may change in a later version, but for now send me your key suggestions and I'll try to improve the keyboard as versions go by. The shift- alpha-keys work a little differently. Hitting alpha or orange-shift causes the appropriate annunciator to be displayed and the NEXT keystroke is shifted that way, unless the same (shift or alpha) key is hit again, in which case the annunciator goes off and the keyboard is returned to itsw unshifted state. Blue shift, if hit once, causes the blue-shifted keyboard to appear for one keystroke, but hitting it again causes the annunciator to stay on and shift to be locked until the next time blue-shift is hit. Make sense? Fool around with it and you'll see. Kermit file transfer is implemented in a limited way. Alpha-R starts kermit receive, but send is not well-implemented since I couldn't include an effective file selector. Alpha-S starts kermit send but is bound to cause an error unless you've used a function key or something else clever to put a file name on the stack. This will be improved in later versions. The function keys are the alpha-shifted "big keys" 789/456*123-0 .+. Pressing one of them evaluates the corresponding element in the list FKEYS, going upper-right to lower-left - '7' corresponds to list element 1, '8' to element 2 ... '-' to element 12, and so on down to '+' evaluating element 16. I think the example function keys give a crude idea of what is possible. Any sort of program that doesn't require arguments from the stack and doesn't leave any behind is o.k. to put in FKEYS. Since I use the stack/menu grobs for graphics, don't expect anything with PICT to perform as expected, although it might. Use DISP if you want to write to the screen. Future releases may include phonebooks, file browsers, etc. in fkeys. Alpha keys summary: B: sends serial break C: toggles between cr and cr/lf for received CR (just cr is default) Q: quit NRTS R: start Kermit receive S: start Kermit send (see note above) III. Keyboard layout Unshifted keyboard: (screen) | |_____________________________| | | a b c d e f | | g h i j k l | | m n o p q r | | s t u v w x | | < cr > y z del bs | | alf 7 8 9 / | | ctl 4 5 6 * | | shf 1 2 3 - | | on 0 . spc + | +---------------------------------+ Blue-shifted keyboard: (screen) | |____________________________| | | A B C D E F | | G H I J K L | | M N O P Q R | | S T U V W X | | < cr > Y Z del bs | | alf & * ( ~ | | ctl $ % ^ _ | | shf ! @ # " | | on ) , ? = | +---------------------------------+ Orange-shifted keyboard: (screen) | |_____________________________| | | ^a ^b ^c ^d ^e ^f | | ^g ^h ^i ^j ^k ^l | | ^m ^n ^o ^p ^q ^r | | ^s ^t ^u ^v ^w ^x | | < cr > ^y ^z del bs | | alf [ ] { } | | ctl < > ; : | | shf \ | ' ` | | on tab | +---------------------------------+ IV. Source code availability I'm pretty embarassed about the condition of the source code, but I'll post it to wuarchive soon. I guess I have to pay for sloppy code by having everybody see it. Hopefully it will be cleaned up by version 1.0. V. Random blathering I think the idea of 'shareware' for calculator software of this scope is ridiculous. If you like NRTS, please send me mail saying so. That will certainly boost my ego and probably speed the release of version 1.0 :-) I want to thank all of my betatesters, who kept me from making a total fool out of myself by releasing extremely buggy software to the world. If this documentation is unclear or appears to be in error, or (heaven forbid!) my code is not totally bug-free, please let me know by posting or through email. One small thing we do know about: if you hit the ON key while in the program, the next keystroke will exit the program and leave two system binaries <70h> on the stack. No big deal, but it is inconsistent and I'm sorry I can't figure out how to fix it, since the bug is rooted in the behaviour of the lastkey syseval which I don't fully understand. VI. Disclaimer and Copyright Notice NRTS is (C) Copyright 1990 Bill Gribble Noncommercial distribution allowed, provided that this copyright message is preserved, and any modified versions are clearly marked as such. NRTS makes use of undocumented low-level features of the HP48SX calculator, and may or may not cause loss of data, excessive battery drainage, and/or damage to the calculator hardware. The Author takes no responsibility whatsoever for any damage caused by the use of this program. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ***************************************************************************** ** Bill Gribble Harvey Mudd College, Claremont, CA ** ** bgribble@jarthur.claremont.edu Never heard of it? You're stupid. ** ***************************************************************************** ; NRTS 0.4: Under-construction machine/rpl terminal emulator. data.b 'H' ; download preamble data.b 'P' data.b 'H' data.b 'P' data.b '4' data.b '8' data.b '-' data.b 'D' ; ROM addresses: save_regs=#0679b restore_regs=#067d2 push_r0_shortint=#06537 alloc_str=#05b7d ; RAM addresses: loc_menugrob=#70551 loc_stackgrob=#70556 serbuf_len=#703fc annunc=#706c4 ; nibble for annunciator on/off ; Program execution starts here data.a #02d9d ; BEGIN rts data.a #64cca ; short_70 (mark for drop to mark code) data.a #2eb62 ; create iopar data.a #02dcc ; ml: init_shit ; store initial prog registers stinit: data.a eninit-stinit call.a save_regs call.4 clscr clr.w a ; scratch register move.w a,r1 ; now r1 is set clr.w a ; setting r2 move.p5 loc_stackgrob,c move.a c,d1 move.a @d1,a ; get address of stack grob add.a #a,a add.a #a,a move.w a,r2 clr.w a move.w a,r3 call.a restore_regs call.4 save_progregs move.a @d0,a ; return to system add.a 5,d0 jump.a @a eninit: ; End machine language (init_shit) data.a #071a2 ; do_begin data.a #02dcc ; ml: clear_to_mark cmstar: data.a cmend-cmstar cmref1: move.a @d1,a move.p5 #64cca,c ; looking for <70h> breq.a c,a,cmlpen add.a 5,d1 inc.a d jump.3 cmref1 cmlpen: move.a @d0,a add.a 5,d0 jump.a @a cmend: ; End machine code (clear_to_mark) data.a #04714 ; lastkey: check for keypress data.a #61ad8 ; if_then_else data.a #02d9d ; BEGIN out_char data.a #3fe44 ; KEY syseval stuff data.a #64bd0 data.a #03eb1 ; And_short_short data.a #03ff9 ; Short_1 data.a #41d92 data.a #2af60 ; ip - now stack1=real key# data.a #18cea ; real_to_short data.a #02dcc ; mcode (convert_key) ; convert short for key pressed to short for character. Return true for ; a sending character, false for an alpha-character, false and <1h> ; short for a shift, control, or alpha-key. ck_beg: data.a ck_end-ck_beg ; object size call.4 restore_progregs move.a @d1,a ; copy key number to reg a swap.a d1,a add.a 5,d1 move.a @d1,c ; c gets key number push.a c swap.a d1,a ; pop stack add.a 5,d1 inc.a d call.a save_regs pop.a c move.a c,b ; b gets key number move.w r1,c ; c gets registers move.p5 #51,a brne.a a,b,nsk ; not shift key jump.4 shfkey nsk: move.p5 #47,a brne.a a,b,nck ; not control key jump.4 cntkey nck: move.p5 #3d,a brne.a a,b,nak ; now we know it's not shf, cnt, or alf key jump.4 alfkey nak: brbc #2,c,akns ; alpha bit set jump.4 alfset akns: brbc #3,c,slns ; shift lock not set jump.4 sflset slns: brbc #0,c,sns ; shift not set jump.4 shfset sns: brbc #1,c,cns ; control not set jump.4 cntset cns: move.p1 #8,a jump.4 offset shfkey: brbc #3,c,nsoff ; toggle shift flags, push 0, false, and clrb #3,c ; exit. clrb #0,c move.p1 #8,a jump.3 kdone nsoff: brbc #0,c,son clrb #0,c setb #3,c move.p1 #a,a jump.3 kdone son: setb #0,c move.p1 #a,a kdone: move.w c,r1 move.p5 annunc,c ; set annunciators properly move.a c,d0 move.1 0,p move.p a,@d0 move.p5 #1,a move.a a,r0 call.a push_r0_shortint call.a restore_regs call.4 save_progregs jump.4 false_rplret cntkey: brbc #1,c,ncoff clrb #1,c move.p1 #8,a jump.3 kdone ncoff: setb #1,c move.p1 #9,a jump.3 kdone alfkey: brbc #2,c,naoff clrb #2,c move.p1 #8,a jump.3 kdone naoff: setb #2,c move.p1 #c,a jump.3 kdone sflset: move.p5 #64,a ; shift character but don't add.a a,b ; change flags move.p1 #a,a jump.3 offset shfset: move.p5 #64,a add.a a,b clrb #0,c move.w c,r1 move.p1 #8,a jump.3 offset cntset: move.p5 #c8,a add.a a,b clrb #1,c move.p1 #8,a move.w c,r1 jump.3 offset alfset: move.w r1,c clrb #2,c move.1 0,p move.p5 annunc,a move.a a,d0 move.p1 #8,a move.p a,@d0 move.w c,r1 clr.w c move.a b,c move.p2 #3d,a ; do func-key cases in machine code brgt.b c,a,afref1 jump.3 afref2 afref1: move.p2 #3e,a brne.b c,a,afref3 move.p5 #00101,c jump.3 afref2 afref3: move.p2 #3f,a brne.b c,a,afref4 move.p5 #00102,c jump.3 afref2 afref4: move.p2 #40,a brne.b c,a,afref5 move.p5 #00103,c jump.3 afref2 afref5: move.p2 #41,a brne.b c,a,afref6 move.p5 #00104,c jump.3 afref2 afref6: move.p2 #48,a brne.b c,a,afref7 move.p5 #00105,c jump.3 afref2 afref7: move.p2 #49,a brne.b c,a,afref8 move.p5 #00106,c jump.3 afref2 afref8: move.p2 #4a,a brne.b c,a,afref9 move.p5 #00107,c jump.3 afref2 afref9: move.p2 #4b,a brne.b c,a,afrefa move.p5 #00108,c jump.3 afref2 afrefa: move.p2 #52,a brne.b c,a,afrefb move.p5 #00109,c jump.3 afref2 afrefb: move.p2 #53,a brne.b c,a,afrefc move.p5 #0010a,c jump.3 afref2 afrefc: move.p2 #54,a brne.b c,a,afrefd move.p5 #0010b,c jump.3 afref2 afrefd: move.p2 #55,a brne.b c,a,afrefe move.p5 #0010c,c jump.3 afref2 afrefe: move.p2 #5c,a brne.b c,a,afreff move.p5 #0010d,c jump.3 afref2 afreff: move.p2 #5d,a brne.b c,a,afrefg move.p5 #0010e,c jump.3 afref2 afrefg: move.p2 #5e,a brne.b c,a,afrefh move.p5 #0010f,c jump.3 afref2 afrefh: move.p2 #5f,a brne.b c,a,afref2 move.p5 #00110,c jump.3 afref2 afref2: move.a c,r0 call.a push_r0_shortint call.4 save_progregs jump.4 false_rplret offset: clr.w c move.a b,c ; c gets key value move.a c,r0 move.1 0,p move.p5 annunc,c move.a c,d0 move.p a,@d0 call.a restore_regs ; restore pointers call.a push_r0_shortint call.4 save_progregs jump.4 true_rplret ck_end: ; End machine language (convert_key) data.a #61ad8 ; if_then_else data.a #02d9d ; BEGIN (sending character) data.a #02dcc ; ml: get_key_string ; Take short key value and return a string to send kstrst: data.a kstren-kstrst ; object size call.a save_regs move.a @d1,a ; get data from level 1(short) to a swap.a d1,a add.a 5,d1 move.a @d1,c push.a c move.p5 2,c ; size of string=1 byte call.a alloc_str ; r0=header, d0=data pop.a c move.a c,a move.p5 keytab-ref1,c ; offset from read point add.a a,a ; number of nibbles after keytab add.a a,c ; c has total offset from ref1 move.a pc,a ; load pc to a ref1: add.a c,a ; add offset value move.a a,d1 ; point at it move.b @d1,c ; c gets ascii value from keytab move.b c,@d0 ; put ascii in string call.a restore_regs ; get old d0,d1,b,d move.a r0,a ; load address of string move.a a,@d1 ; push string on stack & replace short move.a @d0,a ; return to system add.a 5,d0 jump.a @a kstren: ; End of machine code (get_key_string) data.a #2ee6f ; xmit data.a #03244 ; drop (the 1 or zero) data.a #0312b ; END (sending character) data.a #02d9d ; BEGIN (alpha character) data.a #2378d ; case data.a #02d9d ; begin data.a #03188 ; dup data.a #0414d ; short_23h (alpha-q) data.a #1e761 ; same data.a #237a8 ; then data.a #02d9d ; PRG data.a #03244 ; drop data.a #02dcc ; ml: set_quit ; Set quit bit of registers stquit: data.a enquit-stquit call.4 restore_progregs move.w r1,c setb #4,c move.w c,r1 call.4 save_progregs move.a @d0,a add.a 5,d0 jump.a @a enquit: ; End machine language (set_quit) data.a #21ed5 ; closeio data.a #0312b ; END (quit-key) ; function keys run until ENDFNK data.a #22fd5 ; end quit-case data.a #03188 ; dup data.a #04071 ; short_d (C) data.a #1e761 ; same data.a #237a8 ; then data.a #02d9d ; BEGIN (toggle cr/lf) data.a #03244 ; drop data.a #02dcc ; mcode toggle_cr/lf tgclbg: data.a tgclen-tgclbg call.4 restore_progregs move.w r1,a brbs #7,a,lfison setb #7,a jump.3 crlfdn lfison: clrb #7,a crlfdn: move.w a,r1 call.4 save_progregs move.a @d0,a add.a 5,d0 jump.a @a tgclen: ; End machine code (toggle cr/lf) data.a #0312b ; END (toggle cr/lf) data.a #22fd5 ; end toggle-case data.a #03188 ; dup data.a #04157 ; short_24 data.a #1e761 ; same data.a #237a8 ; then data.a #02d9d ; BEGIN (kermit receive) data.a #03244 ; drop data.a #21f96 ; cmd_recv data.a #0312b ; END (kermit receive) data.a #22fd5 ; end receive-case data.a #03188 ; dup data.a #04067 ; short_ch data.a #1e761 ; same data.a #237a8 ; then data.a #02d9d ; BEGIN (serial break) data.a #03244 ; drop data.a #220c2 ; cmd_SBRK data.a #0312b ; END (serial break) data.a #22fd5 ; end break-case data.a #03188 ; dup data.a #04189 ; short_29h data.a #1e761 ; same data.a #237a8 ; then data.a #02d9d ; BEGIN (kermit send) data.a #03244 ; drop data.a #21ef0 ; cmd_SEND data.a #0312b ; END (kermit send) data.a #22fd5 ; end send-case data.a #02d9d ; BEGIN (test clause) data.a #03188 ; dup data.a #64e32 ; short_100 data.a #03d83 ; greater_shortshort data.a #5380e ; T/F to real data.a #0312b ; END (test clause) data.a #237a8 ; then data.a #02d9d ; BEGIN (fn key #1) data.a #64e32 ; short_100h data.a #03de0 ; -_1short_2short data.a #23654 ; open single quote (?) data.a #02e48 ; global 'FKEYS' data.b #5 data.b 'F' data.b 'K' data.b 'E' data.b 'Y' data.b 'S' data.a #23679 data.a #03223 ; swap data.a #18dbf ; short_to_real data.a #1d7c6 ; cmd_get data.a #1a3be ; cmd_eval data.a #0312b ; END (func key case) data.a #22fd5 ; end function case data.a #0312b ; END cases data.a #22fd5 ; end case statement data.a #0312b ; END (alpha character) data.a #0312b ; END out_char data.a #02d9d ; BEGIN in_char data.a #3133b ; buflen data.a #02dcc ; ml: ser_buf_notempty ; check serial buffer status sbnest: data.a sbneen-sbnest ; size of object add.a 5,d1 inc.a d call.a save_regs move.a @d1,a add.a 5,a move.a a,d1 move.a @d1,c brz.b c,bufemp ; if something's there call.a restore_regs jump.4 true_rplret ; push true and exit bufemp: call.a restore_regs jump.4 false_rplret ; nothing's there, push false and exit sbneen: ; End machine language (ser_buf_notempty) data.a #61ad8 ; if_then_else data.a #02d9d ; BEGIN recv_char data.a #314e5 ; srecv data.a #02d9d ; BEGIN deal_with_string data.a #03244 ; drop (the true/false) data.a #02dcc ; ml: deal_with_rcvchar drcstr: data.a drcend-drcstr ; length of code object call.4 restore_progregs move.a @d1,a swap.a a,d1 add.a #5,d1 ; skip type move.a @d1,c ; get length sub.a #5,c ; subtract length of length srb.w c ; divide by 2 add.a #5,d1 ; d1 points to start of data swap.a d1,a ; now c.a has string length, move.a a,d0 ; a.a and d0 point to data sln.w a sln.w a move.b c,a move.w a,r3 ; now we're ready to start looping clr.w a loopst: move.b @d0,a clrb #7,a ; vt100 characters are 7-bit move.p2 #20,c brle.b c,a,iwchar clr.a c move.a a,c ; multiply a by 5 to get nibble offset add.a c,c add.a c,c ; c = 4 * a add.a c,a ; offset from ctltab move.p5 ctltab-drref4,c ; offset from jump point to ctltab add.a c,a move.a pc,c ; off. from top of mem to jump pt drref4: add.a c,a ; absolute address of data move.a a,d1 move.a @d1,a ; offset from drref4 to code add.a c,a ; absolute address of code jump.a a ; execute the code iwchar: call.4 write_a call.4 right_1 ; move right brcs drref1 ; if at end of line, newline jump.3 donewc drref1: call.4 carret call.4 down_1 brcs drref2 ; if on last line, scroll. jump.3 donewc drref2: call.4 scroll_up donewc: move.w r3,a move.b a,c ; get length to c srn.w a ; and pointer to a srn.w a dec.b c ; decrement length swap.w a,b ; stash pointer in b brz.b c,donews ; if length < 1, we're done swap.w a,b ; else put pointer back in a add.a #2,a ; skip to next character move.a a,d0 ; point at it sln.w a ; get ready to move to r3 sln.w a move.b c,a move.w a,r3 clr.w a jump.3 loopst donews: swap.w a,b call.a restore_regs call.4 save_progregs add.a 5,d1 inc.a d move.a @d0,a add.a 5,d0 jump.a @a ; graphics subroutines: write, move, scroll. write_a: move.p2 #20,c sub.b c,a ; get right char number to a sln.w a ; multiply by 16 for offset from fontab: move.p5 fontab-waref1,c ; off from jump point to fontab add.a c,a ; a has offset from jump to bitmap move.a pc,c waref1: add.a c,a ; a has absolute address of data move.a a,d1 move.w @d1,c ; c has character bitmap move.p16 #0c0c0c0c0c0c0c0c,a move.w a,b move.w r1,a brbc #6,a,waref4 move.p16 #3030303030303030,a move.w a,b call.4 flip_c srb.w c srb.w c call.4 flip_c waref4: move.w c,d ; get it out of the way. move.a r2,a ; get current bitmap pointer move.a a,d0 ; stick it in d0 move.1 #f,p ; p will be our loop counter waref2: move.p @d0,c ; get nibble of screen dec.1 p add.a 1,d0 move.p @d0,c ; get another nibble and.w b,c ; mask data where we're looking or.w d,c ; -or- with font bitmap move.p c,@d0 ; write nibble to screen inc.1 p sub.a 1,d0 move.p c,@d0 ; write second nibble to screen add.a #f,d0 ; move to next scan line add.a #f,d0 add.a #4,d0 breq.1 p,2,waref3 breq.1 p,1,waref3 ; if we're done with character breq.1 p,0,waref3 dec.1 p ; move to next byte of data dec.1 p jump.4 waref2 waref3: move.1 0,p ; character's written; now move pointer ret ctllf: call.4 carret call.4 down_1 brcs lfref1 ; if on last line, scroll. jump.3 donewc lfref1: call.4 scroll_up jump.4 donewc ctlcr: call.4 carret move.w r1,a brbc #7,a,ccrrf2 call.4 down_1 brcs ccrrf1 jump.3 donewc ccrrf1: call.4 scroll_up ccrrf2: jump.4 donewc ctlbs: call.4 left_1 jump.4 donewc nopctl: jump.4 donewc carret: call.4 left_1 brcc carret retclrc flip_c: move.1 0,p fcref1: clr.a a add.a 3,a fcref2: dec.a a brz.a a,fcref3 add.p c,c brcc fcref2 add.p 1,c jump.3 fcref2 fcref3: breq.1 p,#f,fcref4 inc.1 p jump.3 fcref1 fcref4: move.1 0,p ret right_1: move.w r2,c move.a c,b ; b has display pointer srn.w c srn.w c srn.w c srn.w c srn.w c move.p3 #15,a brlt.b c,a,mrref1 retsetc mrref1: inc.b c sln.w c sln.w c sln.w c sln.w c sln.w c move.a b,c move.w r1,a brbs #6,a,mrref2 inc.a c setb #6,a jump.3 mrref3 mrref2: add.a 2,c clrb #6,a mrref3: move.w a,r1 move.w c,r2 retclrc left_1: move.w r2,c move.a c,b ; b has display pointer srn.w c srn.w c srn.w c srn.w c srn.w c brnz.b c,mlref1 retsetc mlref1: dec.b c sln.w c sln.w c sln.w c sln.w c sln.w c move.a b,c move.w r1,a brbc #6,a,mlref2 dec.a c clrb #6,a jump.3 mlref3 mlref2: sub.a #2,c setb #6,a mlref3: move.w a,r1 move.w c,r2 retclrc down_1: move.1 0,p move.w r2,c move.a c,b ; b has display pointer, column srn.w c srn.w c srn.w c srn.w c srn.w c sln.w b sln.w b move.b c,b srn.w c srn.w c move.p1 #6,a brlt.p c,a,mdref1 breq.p c,a,mdref2 retsetc mdref1: inc.p c sln.w c sln.w c move.b b,c srn.w b srn.w b sln.w c sln.w c sln.w c sln.w c sln.w c move.a b,c move.p5 #110,a add.a a,c jump.3 mdref3 mdref2: inc.p c sln.w c sln.w c move.b b,c srn.w b srn.w b sln.w c sln.w c sln.w c sln.w c sln.w c move.a b,c move.p5 loc_stackgrob,a move.a a,d1 move.a @d1,a move.a a,b ; b points to stackgrob header move.p5 #674,a ; offset to line #6 (7th line) add.a a,b ; b points to start of line #6 subn.a c,b ; b has offset from start of #6 move.p5 loc_menugrob,a move.a a,d1 move.a @d1,a add.a #a,a add.a #a,a ; a points to menugrob data add.a b,a ; a points to 8th line move.a a,c ; c.a points to 8th line mdref3: move.w c,r2 retclrc scroll_up: supst: move.p5 loc_stackgrob,a move.a a,d1 move.a @d1,a move.a a,b move.p5 #124,c ; nibbles to start of second line add.a c,a move.a a,d1 move.a b,a move.a a,d0 add.a #a,d0 add.a #a,d0 move.p5 #6c,c ; words to copy suref1: move.w @d1,a move.w a,@d0 add.a #f,d1 add.a #f,d0 dec.a c brnz.a c,suref1 ; loop until done move.12 @d1,a ; finish off the last bit move.12 a,@d0 add.a #c,d0 move.p5 loc_menugrob,a move.a a,d1 move.a @d1,a move.a a,d1 add.a #a,d1 add.a #a,d1 ; d1 points to start of menugrob data move.p5 #12,c ; words to copy suref2: move.w @d1,a ; get old region move.w a,@d0 ; copy it add.a #f,d0 add.a #f,d1 dec.a c brnz.a c,suref2 move.p5 loc_menugrob,a ; clear last line of display (menu grob) move.a a,d1 move.a @d1,a move.a a,d1 ; d1 points to header of graph grob add.a #a,d1 add.a #a,d1 ; d1 points to data move.p5 #12,c ; number of data words clr.w a suref3: move.w a,@d1 ; clear 1 word dec.a c add.a #f,d1 brnz.a c,suref3 ret drcend: ; End of machine language (deal_with_rcvchar) data.a #0312b ; END deal_with_string data.a #0312b ; END recv_char data.a #02d9d ; BEGIN data.a #03244 ; drop data.a #0312b ; END data.a #0312b ; END in_char data.a #02dcc ; ml: quit_flag_set? ; Check if quit flag has been set in previous loop. If it has, push true. ; If not, push false. qfstar: data.a qfsend-qfstar ; object size call.4 restore_progregs call.4 save_progregs move.w r1,a brbs #4,a,qset jump.4 false_rplret qset: jump.4 true_rplret qfsend: ; End machine language (quit_flag_set?) data.a #071c8 ; end? data.a #02dcc ; ml: pseudo_code_data dtstar: data.a dtend-dtstar ; length of data dtref1: move.a @d1,a move.p5 #64cca,c add.a 5,d1 inc.a d breq.a c,a,dtlpen jump.3 dtref1 dtlpen: move.a @d0,a ; just jump back to rpl add.a 5,d0 ; jump.a @a ; ; start called subroutines. move graphics routines here later. clscr: move.p5 loc_stackgrob,a move.a a,d1 move.a @d1,a move.a a,d1 ; d1 points to header of graph grob add.a #a,d1 add.a #a,d1 ; d1 points to data move.p5 #7e,c ; number of data words clr.w a csref1: move.w a,@d1 ; clear 1 nibble dec.a c add.a #f,d1 brnz.a c,csref1 move.11 a,@d1 move.p5 loc_menugrob,a move.a a,d1 move.a @d1,a move.a a,d1 ; d1 points to header of graph grob add.a #a,d1 add.a #a,d1 ; d1 points to data move.p5 #12,c ; number of data words clr.w a csref2: move.w a,@d1 ; clear 1 word dec.a c add.a #f,d1 brnz.a c,csref2 ret save_progregs: call.a save_regs move.p5 regs-spref1,a move.a pc,c spref1: add.a c,a move.a a,d1 move.w r1,a move.w a,@d1 add.a #10,d1 move.w r2,a move.w a,@d1 add.a #10,d1 move.w r3,a move.w a,@d1 add.a #10,d1 move.w r4,a move.w a,@d1 call.a restore_regs ret restore_progregs: call.a save_regs move.p5 regs-rpref1,c move.a pc,a rpref1: add.a c,a move.a a,d1 move.w @d1,a move.w a,r1 add.a #10,d1 move.w @d1,a move.w a,r2 add.a #10,d1 move.w @d1,a move.w a,r3 add.a #10,d1 move.w @d1,a move.w a,r4 call.a restore_regs ret true_rplret: sub.a 5,d1 dec.a d move.p5 #3a81,a move.a a,@d1 move.a @d0,a add.a 5,d0 jump.a @a false_rplret: sub.a 5,d1 dec.a d move.p5 #3ac0,a move.a a,@d1 move.a @d0,a add.a 5,d0 jump.a @a regs: data.w 0 data.w 0 data.w 0 data.w 0 data.w 0 keytab: ; key-number to ascii conversion table. data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b 'a' data.b 'b' data.b 'c' data.b 'd' data.b 'e' data.b 'f' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b 'g' data.b 'h' data.b 'i' data.b 'j' data.b 'k' data.b 'l' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b 'm' data.b 'n' data.b 'o' data.b 'p' data.b 'q' data.b 'r' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b 's' data.b 't' data.b 'u' data.b 'v' data.b 'w' data.b 'x' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b #d ; return data.b 'y' data.b 'z' data.b #7f ; delete data.b #8 ; backspace data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' ; alpha - not used data.b '7' data.b '8' data.b '9' data.b '/' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' ; shift - not used data.b '4' data.b '5' data.b '6' data.b '*' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' ; blue-shift - not used data.b '1' data.b '2' data.b '3' data.b '-' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b '0' data.b '.' data.b ' ' data.b '+' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' ; start shifted characters data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b 'A' data.b 'B' data.b 'C' data.b 'D' data.b 'E' data.b 'F' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b 'G' data.b 'H' data.b 'I' data.b 'J' data.b 'K' data.b 'L' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b 'M' data.b 'N' data.b 'O' data.b 'P' data.b 'Q' data.b 'R' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b 'S' data.b 'T' data.b 'U' data.b 'V' data.b 'W' data.b 'X' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b #d ; return, even shifted data.b 'Y' data.b 'Z' data.b #7f ; del data.b #8 ; bs data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b '&' data.b '*' data.b '(' data.b '~' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b '$' data.b '%' data.b '^' data.b '_' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b '!' data.b '@' data.b '#' data.b '"' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ')' data.b #2c data.b '?' data.b '=' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' ; start of control characters data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b ' ' data.b #01 data.b #02 data.b #03 data.b #04 data.b #05 data.b #06 data.b #0 data.b #0 data.b #0 data.b #0 data.b #07 data.b #08 data.b #09 data.b #0a data.b #0b data.b #0c data.b #0 data.b #0 data.b #0 data.b #0 data.b #0d data.b #0e data.b #0f data.b #10 data.b #11 data.b #12 data.b #0 data.b #0 data.b #0 data.b #0 data.b #13 data.b #14 data.b #15 data.b #16 data.b #17 data.b #18 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0d data.b #19 data.b #1a data.b #7f data.b #8 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b '[' data.b ']' data.b '{' data.b '}' data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b '<' data.b '>' data.b #3b data.b #3a data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b '\' data.b '|' data.b #27 data.b #60 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b #0 data.b #9 data.b #0 fontab: data.w #0000000000000000 data.w #4040404040004000 data.w #A0A0A00000000000 data.w #A0A0F1A0F1A0A000 data.w #40E150E041F04000 data.w #3031804020918100 data.w #2050502051906100 data.w #4040400000000000 data.w #8040202020408000 data.w #2040808080402000 data.w #00A040F140A00000 data.w #004040F140400000 data.w #0000000060604020 data.w #000000F100000000 data.w #0000000000606000 data.w #0001804020100000 data.w #E01191513111E000 data.w #406040404040E000 data.w #E01101C02010F100 data.w #E01101E00111E000 data.w #80C0A090F1808000 data.w #F110F0010111E000 data.w #C02010F01111E000 data.w #F101804020202000 data.w #E01111E01111E000 data.w #E01111E101806000 data.w #0060600060600000 data.w #0060600060604020 data.w #8040201020408000 data.w #0000F100F1000000 data.w #1020408040201000 data.w #E011018040004000 data.w #E01151D15010E100 data.w #E01111F111111100 data.w #F01111F01111F000 data.w #E01110101011E000 data.w #7090111111907000 data.w #F11010F01010F100 data.w #F11010F010101000 data.w #E01110109111E100 data.w #111111F111111100 data.w #E04040404040E000 data.w #010101011111E000 data.w #1190503050901100 data.w #101010101010F100 data.w #11B1515111111100 data.w #1111315191111100 data.w #E01111111111E000 data.w #F01111F010101000 data.w #E011111151906100 data.w #F01111F050901100 data.w #E01110E00111E000 data.w #F140404040404000 data.w #111111111111E000 data.w #111111A0A0404000 data.w #1111115151B11100 data.w #1111A040A0111100 data.w #1111A04040404000 data.w #F10180402010F100 data.w #E02020202020E000 data.w #0010204080010000 data.w #E08080808080E000 data.w #40A0110000000000 data.w #000000000000F100 data.w #2020400000000000 data.w #0000E001E111E100 data.w #1010F0111111F000 data.w #0000E1101010E100 data.w #0101E1111111E100 data.w #0000E011F110E000 data.w #40A0207020202000 data.w #0000E01111E101E0 data.w #1010F01111111100 data.w #400060404040E000 data.w #8000C08080809060 data.w #1010905030509000 data.w #604040404040E000 data.w #0000B05151511100 data.w #0000F01111111100 data.w #0000E0111111E000 data.w #0000F01111F01010 data.w #0000E11111E10101 data.w #0000D13010101000 data.w #0000E110E001F000 data.w #2020702020A04000 data.w #000011111111E100 data.w #0000111111A04000 data.w #000011115151A000 data.w #000011A040A01100 data.w #0000111111E101E0 data.w #0000F1804020F100 data.w #C02020102020C000 data.w #4040404040404000 data.w #6080800180806000 data.w #0000205180000000 ctltab: data.a nopctl-drref4 ; null data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 ; enquiry (next version?) data.a nopctl-drref4 data.a nopctl-drref4 ; bell (next version?) data.a ctlbs-drref4 ; backspace data.a nopctl-drref4 ; tab data.a ctllf-drref4 ; linefeed data.a ctllf-drref4 ; linefeed data.a ctllf-drref4 ; linefeed data.a ctlcr-drref4 ; carriage return data.a nopctl-drref4 ; char set shit data.a nopctl-drref4 ; char set shit data.a nopctl-drref4 ; hex #f data.a nopctl-drref4 ; hex #10 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 data.a nopctl-drref4 dtend: ; End machine language (pseudo-code data) data.a #0312b ; END nrts %%HP: T(3)A(D)F(.); "D9D20ACC4626BE2CCD20450008FB97608E42C0AF0101AF03465507135143818F 09818F09102AF01038F2D7608E45C0142164808C2A170CCD207200014334ACC4 68A2B0174E76BEF142164808C417408DA16D9D2044EF30DB461BE309FF3029D1 406FA2AEC81CCD20FB3008EF1C014313317414706133174E78FB976007D51198 0824150008A4808CE60080824740008A4808C7D0080824D30008A4808C7E0080 8A2808C1510808A3808C2F00808A0808CBF00808A1808CC0108082088C0E2080 8A36180883808808082086920808A061808808089380820A6E008089080820A1 09344C607134201500808241000081AF008F735608F2D7608ECBA08C36B0808A 1118088180820860BF8089180820961AF808A211808828082086B8F808928082 0C6C7F8082446000C880820A61028082446000C88088010980820863E1808248 C000C88088180820810965C11198088220808244C6071308082081500109AF2D 980821D39E260637180821E3966D034101006C5180821F3966D0342010065418 082104966D034301006E218082114966D0344010067118082184966D03450100 60018082194966D0346010069E080821A4966D0347010062D080821B4966D034 801006BB08082125966D0349010064A08082135966D034A01006D80808214596 6D034B010066708082155966D034C01006F5080821C5966D034D010068408082 1D5966D034E0100613080821E5966D034F01006A1080821F5966D03401100630 081AF088F735608EE5808C5090AF2D981AF0820344C60713415008F2D7608F73 5608E92808C4B808DA16D9D20CCD20060008FB97601431331741470634200008 FD7B5007DA34EE800C4C281B4CA13114F14C8F2D76081AF10141142164808CF6 EE244230B2130D9D20D8732D9D2088130D4140167E18A732D9D2044230CCD206 20008E0B70119808941098E7570142164808C5DE12B21305DF22881301704016 7E18A732D9D2044230CCD20630008E857011180877B0808576800808471018EF E60142164808CB21305DF228813075140167E18A732D9D204423069F12B21305 DF228813076040167E18A732D9D20442302C022B21305DF228813098140167E1 8A732D9D20442300FE12B21305DF22D9D208813023E4638D30E0835B21308A73 2D9D2023E460ED304563284E205064B45495359763232230FBD816C7D1EB3A1B 21305DF22B21305DF22B2130B2130D9D20B3313CCD20F3000174E78FB9760143 818F0413114796AF08F2D7608C52608F2D7608C43608DA16D9D205E413D9D204 4230CCD20684008E6A50143133174147818FA481E174133130BF0BF0AEA103AF 014A8084731029EE72D2D6C6C6CA3406E00CA81B5CA131143CA81B28EB7008EC C104606C108E48108EF62046069008E4330113AE6BF4BF4A6EAFC96A12AFC818 F01130BF0BF0AEA103AF06B6FAFC8F2D7608E9840174E7142164808C3102B6AB F034AC700CA81B5CA13115778082FC0C0C0C0C0C0C0C0AF811180866C28082F0 303030303030303AF88E7C0081E81E8EBB00AF781AF121302F15600D16015600 E750E7F15400C180154016E16E1638926189111890C00D0D8C0CFF20018E4500 8EF31046069DE8E40208CECEF8E530011180867518E611046060BE8EBD108C5A EF8E6A008C99EF8C39EF8E490059F0320D0818F02CC8A821A0655F8180206CEF 89F800C69DF200111AD5BF6BF6BF6BF6BF6808225109E64002B66BF2BF2BF2BF 2BF2D911180876D0E6808566E00818F218084610110A0311AD5BF6BF6BF6BF6B F696E4002A6EBF2BF2BF2BF2BF2D911180866D0CE808466E00818FA180856101 10A032011AD5BF6BF6BF6BF6BF6BF1BF1AE5BF6BF6808206986909027302B06B F2BF2AE9BF5BF5BF2BF2BF2BF2BF2D98082401100C26660B06BF2BF2AE9BF5BF 5BF2BF2BF2BF2BF2D98082465507131143D88082447600C8ED80824155071311 43818F09818F09C0D610A038082465507131143D83442100CA131D4130169169 34C60001537150717E16ECE8AEDE15BB158B16B8082415507131143131179179 34210001537150716E17ECE8AEDE80824155071311431311791793421000AF01 517CE17E8AE4F01B2130B2130D9D2044230B2130B2130CCD20720008EDF008EF A0011180874808CC4108CA2108C170CCD204AA0014334ACC46174E78A2606BEF 142164808C808246550713114313117917934E7000AF01517CE17E8AE4F159A8 0824155071311431311791793421000AF01517CE17E8AE4F018FB9760808240B 00081B5CA131111151717F112151717F113151717F11415178F2D760018FB976 034B600081B4CA131153710117F153710217F153710317F15371048F2D760011 C4CF8082418A30141142164808C1C4CF808240CA30141142164808C010000000 0000000C7907000000000000000000000000000AA34AC634A051000000000000 0000000020202020202020202020216263646566602020202768696A6B6C6020 20202D6E6F60717270202020237475767778702020202D097A7F780020202020 202738393F2020202020202435363A2020202020202132333D20202020202020 3E202B202020202020202020202020202020214243444546402020202748494A 4B4C402020202D4E4F40515250202020235455565758502020202D095A5F7800 2020202020262A282E70202020202024252E5F50202020202021204322202020 202020292C2F3D30202020202020202020202020202021020304050600000000 0708090A0B0C000000000D0E0F00111210000000031415161718100000000D09 1A1F780000000000000B5D5B7D7000000000000C3E3B3A3000000000000C5C77 2060000000000000000009000000000000000000000040004040404040000000 0000A0A0A000A0A1F0A1F0A0A00040F140E051E0400181902040813030016091 50205050200000000000404040008040202020408000204080808040200000A0 41F040A00000004041F0404000204060600000000000000001F0000000006060 0000000000000010204081000000E11131519110E000E040404040604001F010 20C10110E000E11100E10110E0008081F090A0C08000E1110100F011F000E111 10F01020C000202020408101F000E11110E11110E000608101E11110E0000060 600060600020406060006060000080402010204080000001F001F00000001020 408040201000400040810110E001E01051D15110E001111111F11110E000F111 10F11110F000E11010101110E0007091111110907001F01010F01011F0001010 10F01011F001E11190101110E001111111F111111000E04040404040E000E111 1101010100011090503050911001F0101010101010011111115151B110011111 915131111000E11111111110E000101010F11110F001609151111110E0011090 50F11110F000E11100E01110E000404040404041F000E1111111111110004040 A0A11111100111B15151111110011110A040A111100040404040A1111001F010 20408101F000E02020202020E0000100804020100000E08080808080E0000000 000110A04001F0000000000000000000000040202001E111E100E0000000F111 1110F0101001E0101011E0000001E1111111E1010000E011F110E00000002020 207020A040E101E11110E000000111111110F0101000E0404040600040609080 8080C00080009050305090101000E04040404040600111515150B00000011111 1110F0000000E1111110E000001010F11110F000010101E11111E00000001010 1031D0000000F100E011E000000040A0202070202001E11111111000000040A1 111110000000A15151111000000110A040A1100000E101E1111110000001F020 4081F0000000C02020102020C000404040404040400060808100808060000000 8150200005A1005A1005A1005A1005A1005A1005A1005A100991005A10015100 1510015100071005A1005A1005A1005A1005A1005A1005A1005A1005A1005A10 05A1005A1005A1005A1005A1005A1005A1005A1005A1005A1005A1005A1005A1 005A100B2130DF33"