\ not a module, needs 'load' to define undefined symbols \ -*- forth -*- \ neeed to be provided by users \ declare console-on \ declare console-off \ declare receive \ declare transmit \ declare hello \ --- INTERPRETER --- \ control xts : jsr push receive2 TOSH ! TOSL ! ; : ack 0 transmit ; \ zero length message \ NOTE: console-on/off is disabled. fix this somewhere else. : ferase flash erase ack ; : fprog flash program ack ; \ token 0 is nop, so a stream of zeros can be used as soft interrupt \ Except for nop and reset, all tokens return at least one byte result \ to synchronize on. The protocol has Remote Procedure Call (RPC) \ semantics, but implements it without the need for simultaneous \ buffering and handling. \ token -- : interpret-cmd #x0F and route ack . receive/ack . ack1 . jsr/ack . lda . ldf . ack . reset n@a+ . n@f+ . n!a+ . n!f+ . chkblk . stacksize . ferase . fprog ; : receive2 receive receive ; : ack1 1 transmit transmit ; : receive/ack receive ack ; : jsr/ack jsr ack ; \ Bytecode interpreter main loop. The zero length message is ignored, \ all other messages are interpreted and assumed to be of correct \ length. ( This is debug: target doesn't need to second-guess the host. ) macro : 0= #xFF + drop nc? ; forth : interpret-msg receive 0= not if receive interpret-cmd then ; : interpreter interpret-msg interpreter ; \ Block transfer. These take the size from the command input to make \ the host -> target protocol context-free, and send out message \ length to do the same for target -> host protocol. : receive-dup-transmit receive dup transmit ; : n@f+ receive-dup-transmit for @f+ transmit next ; : n@a+ receive-dup-transmit for @a+ transmit next ; : n!f+ receive for receive !f+ next ack ; : n!a+ receive for receive !a+ next ack ; \ pointer initialization : lda receive2 a!! ack ; : ldf receive2 f!! ack ; \ program block memory check : chkblk 255 64 for @f+ and next ack1 ; \ Dump data stack size. Since the data stack is a real stack to the \ host, the target needs to provide information about the bottom. The \ easiest way to do this is to just return the size, and let the host \ pull out the data. : stacksize FSR0L @ stack-data - ack1 ;