// file: main.asm // date: 2015-12-22 19:23:00 // +++ file: "main.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ============================================================================== Microcode for the K1-16/16 CPU 2013-03-07 2015-12-22 The microcode implements 3 different code models: microcode: located in the microcode rom and executed by the control unit hardware. microcodes are addressed with the microcode address counter. subroutines are called with 'jsr' (actually 5 microcodes in total!) and return with 'ret' which actually consists of 2 microcodes, jp and a nop, but one last microcode can sometimes be postponed into the 'nop'. ? labels are all_lowercase. ? arguments and return values are typically passed in registers. ? subroutines try to preserve registers. Millicode: located in the microcode rom and addressed with the ip register. millicodes are implemented in microcode. but may itself switch to millicode with the 'millicoded' microcode. millicodes are the implementation's address with condition 'bit15'. millicodes jump to the next millicode with the 'next_mc' microcode, or the 'Ret' millicode, if they are millicoded. note: 'millicoded' pushes the current ip and 'Ret' restores it. ? labels (millicodes!) are CamelCased. ? arguments are passed on the data stack with the top value in the alu register. ? most (simple) millicodes preserve all common registers. ? subroutines are implemented as new millicodes. (there is no 'Jsr') OPCODE: located in ram and addressed with the ip register. opcodes are implemented in microcode. opcodes are the implementation's address with - bit15 = code plane of the address and - bit14 = 1 to not clear the low byte or - bit14 = 0 to clear the low byte which may contain one byte of data (cmd_lo). opcodes jump to the next opcode with the 'next' microcode, which actually consists of 2 microcodes, the jp and a nop, but one last microcode can frequently be postponed into the 'nop'. ? labels (opcodes!) are ALL_UPPERCASE. ? arguments are passed on the data stack with the top value in the alu register. ? most (simple) opcodes preserve all common registers. ? subroutines (in ram) are implemented with opcodes. they are called with 'JSR' and return with 'RET' opcode. ? reading of the next opcode can be superseded with the interrupt vector. due to the hardware this results in a jump to the read opcode address & $F000. address $0000 is the reset entry, therefore opcodes must not start in range $0000-$0FFF. */ #include "options.h" // options for cc and asm // +++ file: "options.h" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Dieses File darf nur #defines enthalten. Es wird von c-Sourcen und vom Assembler eingebunden! */ // Welcher Quartz-Vorteiler soll maximal eingestellt werden? // 2 -> 32/2 = 16 MHz // 4 -> 32/4 = 8 MHz // 8 -> 32/8 = 4 MHz // 16 -> 32/16 = 2 MHz // Der mca Assembler kennt 'clock_predivider' und ersetzt ggf. set clock2 und set clock4. // #define clock_predivider 2 // does "tst,(areg) : z" work? // note: does not work, even with 74AC151 on SSW // note: eliminate. no known user for this option. // #define fast_ival_z_test 0 // sollen die Microcode Macros 'log', 'trace' und 'tron' in 'macros.h' aktiviert werden? // Auch: Einbinden der Bytecode-Namen im BytecodeCompiler. // #define enable_debug_macros 1 // Der i2c-Treiber "i2c.cc" kann Code enthalten, der einen Treiber aus einem Array // statt aus dem i2c eeprom liest. Damit kann ein K1-Bus-Treiber erstmalig // ins System eingebracht werden. // // wenn include_i2c_soft_eeprom != 0 wird dieser Code für dieses Device eingebaut, zB. Device 3. // wenn include_i2c_soft_eeprom == 0 wird kein derartiger Code eingebaut. // // Die Daten für den Array werden in "i2c.cc" aus der Datei "i2c-sio-eeprom.h" importiert. // Dieses kann mit dem Script "eeprom.vs" aus der Datei "eeprom.bin" erzeugt werden. // eeprom.bin = output file des VCC Compilers für Target K1-Bus-Bytecode. // eeprom.vs = Script sollte in diesem Ordner ("?/Microcode/mc/eeprom.vs") liegen. // #define include_i2c_soft_eeprom 0 #define i2c_sio_addr 2 // falls include_i2c_soft_eeprom enabled // Der Driver für die Sio-Karte kann in Millicode implementiert sein. // Dann muss dieser Treiber nicht aus dem Eeprom geladen werden // #define include_sio_driver_in_rom 0 // Soll das EEFS Filesystem eingebaut werden? // #define include_filesystem 0 // Sollen die FP-Funktionen eingebaut werden? // #define include_floating_point 0 // sollen test-module eingebaut werden? // globales flag für alle test module. // test-module müssen zusätzlich individuell enabled werden. // #define include_tests 0 #define test_millicode 0 #define test_long 0 #define test_float 0 #define test_misc 0 #define test_i2c 0 // soll der ram-test übersprungen werden? // vor allem sinnvoll in der Emulation wg. Laufzeit. B-) // #define include_ramtest 1 // soll Datentyp bool signed oder unsigned sein? // unsigned: 0, 1 // signed: 0, -1 // unsigned ist C-Standard, signed wäre aber eine Winzigkeit schneller & kürzer // #define signed_bool 0 // --- file: "options.h" --- #include "asm/defs.asm" // symbolic names for registers and so on // +++ file: "defs.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // K1-16/16 microcode // 2015-12-03 // ============================================================================== // Symbolic Names: // dis in out in out // ccc:E:oooooo:aaa:aaa:dddd:dddd // Data Bus: dreg cmd.clk = ___:0:______:___:___:0000:???? // cmd input (r/-) dreg ival.oe = ___:0:______:___:___:____:0000 // ival output (-/w) dreg mem.clk = ___:0:______:___:???:0001:???? // internal ram dreg mem.oe = ___:0:______:___:???:____:0001 // internal ram dreg io.clk = ___:0:____??:___:___:0010:???? // k1-bus i/o dreg io.oe = ___:0:____??:___:___:____:0010 // k1-bus i/o dreg dnop.clk = ___:0:______:___:___:0011:???? // dummy target (-/w) dreg axd.oe = ___:0:______:___:___:____:0011 // a-to-d port (r/-) dreg alu.clk = ___:0:__?_??:___:___:1000:???? // top of stack = tos = akku = alu dreg alu.oe = ___:0:______:___:___:____:1000 // top of stack = tos = akku = alu dreg sr.clk = ___:0:___?__:___:___:1100:???? // shift right // dreg sr_cy.clk = ___:0:___1__:___:___:1100:???? // shift right dreg sr.oe = ___:0:______:___:___:____:1100 // shift right dreg sl.clk = ___:0:___?__:___:___:1101:???? // shift left // dreg sl_cy.clk = ___:0:___1__:___:___:1101:???? // shift left dreg sl.oe = ___:0:______:___:___:____:1101 // shift left dreg d2ar.clk = ___:0:______:___:___:1111:???? // d-to-a register (-/w) dreg cmd_lo.oe = ___:0:______:___:___:____:1111 // cmd.lo register (r/-) dreg d0 = 4 // gp dreg register dreg d1 = 5 // "" dreg d2 = 6 // "" dreg d3 = 7 // scratch dreg dtmp = d3 // scratch dreg dxxx1 = 9 // unused dreg swap = 10 // swap hibyte <-> lobyte dreg dxxx2 = 11 // unused dreg msbit = 14 // 16-to-4 encoder // Address Bus: areg dxa.oe = ___:0:______:___:001:____:____ // d-to-a port areg anop.clk = ___:0:______:001:???:____:____ // dummy target areg d2ar.oe = ___:0:______:___:111:____:____ // d-to-a register (r/-) areg ioaddr.clk = ___:0:______:111:???:____:____ // k1-bus i/o address (w/-) areg ip = 0 // instruction pointer areg sp = 2 // stack pointer areg a0 = 3 // gp address register areg a1 = 4 // "" areg hp = 5 // heap pointer areg atmp = 6 // scratch // Option Lines: opt opt0 = ___:0:_____?:___:___:____:____ opt opt1 = ___:0:____?_:___:___:____:____ opt opt2 = ___:0:___?__:___:___:____:____ opt opt3 = ___:0:__?___:___:___:____:____ opt opt4 = ___:0:_?____:___:___:____:____ opt opt5 = ___:0:?_____:___:___:____:____ opt a_bits = ___:0:??____:___:___:____:____ opt d_bits = ___:0:__????:___:___:____:____ // for ALU: opt alu_fu = ___:0:____??:___:___:____:____ opt alu_cy = ___:0:___?__:___:___:____:____ // alu carry input opt alu_cpl = ___:0:__?___:___:___:____:____ // alu complement input opt cy = ___:0:___1__:___:___:____:____ opt nc = ___:0:___0__:___:___:____:____ opt add = ___:0:__0000:___:___:____:____ opt add_cy = ___:0:__0100:___:___:____:____ opt xor = ___:0:__0_01:___:___:____:____ opt and = ___:0:__0010:___:___:____:____ opt or = ___:0:__0110:___:___:____:____ opt load = ___:0:__0_11:___:___:____:____ opt sub = ___:0:__1100:___:___:____:____ opt sub_nc = ___:0:__1000:___:___:____:____ opt xor_cpl = ___:0:__1_01:___:___:____:____ opt and_cpl = ___:0:__1010:___:___:____:____ opt or_cpl = ___:0:__1110:___:___:____:____ opt load_cpl = ___:0:__1_11:___:___:____:____ // for Address Register: opt a_cpl = ___:0:_?____:___:___:____:____ opt a_dis = ___:0:?_____:___:___:____:____ opt add0 = ___:0:00____:___:001:____:____ // 001 = dxa.out opt sub2 = ___:0:01____:___:001:____:____ // 001 = dxa.out opt add1 = ___:0:00____:___:???:____:____ // ??? = !dxa.out opt sub1 = ___:0:01____:___:???:____:____ // ??? = !dxa.out opt adddis = ___:0:10____:___:???:____:____ // + cmd_lo opt subdis = ___:0:11____:___:???:____:____ // + cmd_lo - 256 // for I/O opt io_bits = ___:0:____??:___:___:____:____ opt i2c_clk = ___:0:___?01:___:___:____:0010 // 0010 = 2 = io.oe opt i2c_data = ___:0:__?_01:___:___:____:0010 // 0010 = 2 = io.oe // output: dreg io_data.clk = ___:0:____00:___:___:0010:???? // 0010 = 2 = io.clk dreg io_select.clk = ___:0:____01:___:___:0010:???? // 0010 = 2 = io.clk dreg io_ie_mask.clk = ___:0:____10:___:___:0010:???? // 0010 = 2 = io.clk dreg io_dummy.clk = ___:0:____11:___:___:0010:???? // 0010 = 2 = io.clk // input: dreg io_dummy.oe = ___:0:____00:___:___:____:0010 // 0010 = 2 = io.oe dreg io_i2c.oe = ___:0:__??01:___:___:____:0010 // 0010 = 2 = io.oe dreg io_irpt.oe = ___:0:____10:___:___:____:0010 // 0010 = 2 = io.oe dreg io_data.oe = ___:0:____11:___:___:____:0010 // 0010 = 2 = io.oe // Misc. Options: opt cmden = ___:0:______:___:___:____:____ opt cmddis = ___:1:___=_:________________ opt value = ___:1:___=_:???????????????? opt abort = ___:1:111=1:1111111111111111 // emulator only; reset on real machine // DIV_FF Names: "___:1:xxx=?:________________" opt clock2 = ___:1:000=?:________________ // 000 0 => XTAL/2 opt clock4 = ___:1:001=?:________________ // 001 0 => XTAL/4 opt halt = ___:1:010=?:________________ opt ei = ___:1:011=?:________________ opt led_grn = ___:1:100=?:________________ opt led_yel = ___:1:101=?:________________ opt led_red = ___:1:110=?:________________ opt reset = ___:1:111=?:________________ // Conditions: "000:_:______:___:___:____:____" cond 0 = 0 // (stay in) code plane 0 cond 1 = 1 // (stay in) code plane 1 cond cy = 2 // fork dep. on ALU carry flag cond z = 3 // fork dep. on ALU zero flag cond ovfl = 4 // fork dep. on ALU signed overflow flag cond rnd = 5 // fork dep. on RND cond bit0 = 6 // fork dep. on data bus bit 0 cond bit15 = 7 // fork dep. on data bus bit 15 // --- file: "defs.asm" --- #include "asm/globals.asm" // global data // +++ file: "globals.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // ======================================================================== // Global Data // start at $0000 // ======================================================================= // Interrupts: int_vector data 16 // interrupt vectors int_mask data 1 // enable mask for installed handlers // Memory Management: gdata_ptr data 1 // allocation pointer for zeropage global data gcode_ptr data 1 // start of space for new words hp_base data 1 // bottom of data heap sp_base data 1 // top of return stack mem_data_start data 1 // Start of dynamic data blocks mem_data_end data 1 // Start of free memory between data and pointers mem_ptr_start data 1 // Start of global data pointers mem_free_ptr data 1 // Pointer to linked list of free global pointers mem_end data 1 mem_ptr_end := mem_end // End of local data pointers // Misc: opcode_Ret data 1 // opcode Ret: return_to_millicode #if include_filesystem//skipping: trashname data 1 // ".trash" #endif #if include_sio_driver_in_rom//skipping: sio_getctl_proc data 1 sio_setctl_proc data 1 sio_getc_proc data 1 sio_gets_proc data 1 sio_putc_proc data 1 sio_puts_proc data 1 #endif mem_globs_nz_end data 0 // 0-inited values: null data 1 // const value 0 stdin data 1 // dev_data[] for standard input device stdout data 1 // "" output "" stderr data 1 // "" error "" bc_data data 1 // bytecode compiler data #if include_floating_point//skipping: ee_ptab data 1 // ec pos. exponents table ee_mtab data 1 // ec neg. exponents table #endif context0 data 1 context1 data 1 errno data 1 root data 1 // root node current_time data 2 // current time in UTC current_microsec data 2 // µsecond akku microsecs_per_int data 1 // µseconds per timer interrupt #if include_sio_driver_in_rom//skipping: sio_channel_A data 1 sio_channel_B data 1 sio_selectmask data 1 IMR_value data 1 OPCR_value data 1 #endif // End of Globals: mem_globs_end data 0 // --- file: "globals.asm" --- #include "asm/macros.asm" // instruction macros // +++ file: "macros.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // ================================================================ // exception.asm: // ================================================================ instr TODO ld atmp,$ jp TODO end instr OOMEM ld atmp,$ jp OOMEM end instr PANIC ld atmp,$ jp PANIC end instr TRAP(COND) if COND ld atmp,$ jp PANIC then end // ================================================================ // mem.asm: // ================================================================ // Get data address and size for handle // in: AREG = handle // out: AREG -> data.data // DREG = size // instr mem_get_address_and_size(AREG,DREG) ld DREG,(AREG) ld AREG,DREG // AREG -> data.size ld DREG,(AREG++) // AREG -> data.data; DREG = data.size end // ================================================================ // millicode.h: // ================================================================ // switch to millicode: // (switch back with 'Native') // (or return to caller with 'Next') // instr Millicode ld ip,$+4 ld cmd,ival //mc first_millicode :bit15 end // fetch next millicode instruction: // // instr next_mc // ld cmd,ip++ // ld cmd,ival :bit15 // end instr next_m // TODO: preliminary: vicci replaces 'return' only with 'next_m', because 'next_mc' is 1 char longer... next_mc // ld cmd,ip++ // ld cmd,ival :bit15 end // start millicoded millicode: // pushr ip and switch to millicode // (switch back and next_mc with 'Next') // instr Millicoded ld atmp,$+4 jp millicoded end #if enable_debug_macros instr logchar(N) ld io,N,d_bits=4 end instr lognum(N) ld io,N,d_bits=5 end instr loghex(N) ld io,N,d_bits=6 end instr logfloat(PTR) ld io,PTR,d_bits=7 end instr log_registers ld io,alu,d_bits=8 end instr log_cc ld io,alu,d_bits=9 end instr login ld io,alu,d_bits=10 end instr logout ld io,alu,d_bits=11 end instr logmem ld io,alu,d_bits=12 end instr trace(N) ld io,N,d_bits=15 end instr tron ld io,2,d_bits=15 end instr troff ld io,0,d_bits=15 end instr abort dw $ffff,abort end #else//skipping: instr abort end instr log_cc end instr logchar(N) end instr lognum(N) end instr login end instr logout end instr logmem end instr log_registers end instr loghex(N) end instr logfloat(PTR) end instr trace(N) end instr tron end instr troff end #endif // --- file: "macros.asm" --- #include "asm/microcodes.asm" // #defines for microcodes implemented in c // +++ file: "microcodes.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define AddPokeL op__ADDGL__5int32_5int32P_ #define SubPokeL op__SUBGL__5int32_5int32P_ #define SlPokeL op__SLGL__5int16_6uint32P_ #define SrPokeUL op__SRGL__5int16_6uint32P_ #if include_floating_point//skipping: #define AddPokeF op__ADDGL__7float48_7float48P_ #define SubPokeF op__SUBGL__7float48_7float48P_ #define MulPokeF op__MULGL__7float48_7float48P_ #define DivPokeF op__DIVGL__7float48_7float48P_ // not used #define ModPokeF op__MODGL__7float48_7float48P_ // NIMP #define SlPokeF op__SLGL__5int16_7float48P_ // not used #define SrPokeF op__SRGL__5int16_7float48P_ // not used #define Cast_iF new__5int16_7float48 // not used #define Cast_uF new__6uint16_7float48 #define Cast_LF new__5int32_7float48 // not used #define Cast_ULF new__6uint32_7float48 #define Cast_Fi new__7float48_5int16 #define Cast_FL new__7float48_5int32 #endif #define Cast_iL new__5int16_5int32 // not used #define Cast_uL new__6uint16_6uint32 #define Cast_Li Nip #define Cast_RangeStr cast_range_2_str // cast ( str[?] -- str ) #define Cast_RangeStrRt cast_range_2_str_Rt // cast ( str[?] -- str ) and retain items NIMP // arith mixed i16+u16: //#define Eq_iu op__EQ__5int16_6uint16_6uint16 // NIMP //#define Ne_iu op__NE__5int16_6uint16_6uint16 // NIMP //#define Ge_iu op__GE__5int16_6uint16_6uint16 // NIMP //#define Gt_iu op__GT__5int16_6uint16_6uint16 // NIMP //#define Lt_iu op__LT__5int16_6uint16_6uint16 // NIMP //#define Le_iu op__LE__5int16_6uint16_6uint16 // NIMP //#define Eq_ui op__EQ__6uint16_5int16_6uint16 // NIMP //#define Ne_ui op__NE__6uint16_5int16_6uint16 // NIMP //#define Ge_ui op__GE__6uint16_5int16_6uint16 // NIMP //#define Le_ui op__LE__6uint16_5int16_6uint16 // NIMP //#define Gt_ui op__GT__6uint16_5int16_6uint16 // NIMP //#define Lt_ui op__LT__6uint16_5int16_6uint16 // NIMP //#define Mul_iu Mul_i16u16 // NIMP //#define Mul_ui Mul_u16i16 // NIMP //#define Div_iu Div_i16u16 // NIMP //#define Div_ui Div_u16i16 // NIMP #define Mod_iu op__MOD__5int16_6uint16_5int16 //#define Mod_ui Mod_u16i16 // NIMP // arith i32: #define EqL op__EQ__5int32_5int32_5int16 #define NeL op__NE__5int32_5int32_5int16 // not used #define GeL op__GE__5int32_5int32_5int16 // not used #define LeL op__LE__5int32_5int32_5int16 // not used #define GtL op__GT__5int32_5int32_5int16 // not used #define LtL op__LT__5int32_5int32_5int16 // not used #define AddL op__ADD__5int32_5int32_5int32 #define SubL op__SUB__5int32_5int32_5int32 #define MulL op__MUL__5int32_5int32_5int32 // not used #define DivL op__DIV__5int32_5int32_5int32 // not used #define ModL op__MOD__5int32_5int32_5int32 // NIMP #define AndL op__AND__5int32_5int32_5int32 // not used #define OrL op__OR__5int32_5int32_5int32 // not used #define XorL op__XOR__5int32_5int32_5int32 // not used #define SrL op__SR__6uint32_5int16_6uint32 #define SlL op__SL__6uint32_5int16_6uint32 #define NotL op__NOT__4void_5int32_4bool // NIMP //#define BoolL // not used #define NegL op__SUB__4void_5int32_5int32 #define CplL op__CPL__4void_5int32_6uint32 //#define AbsL // NIMP //#define SignL // NIMP //#define PowL // NIMP //#define IncrL //#define DecrL // NIMP #define PeekppL peekpp__5int32P_5int32 // not used //#define PeekmmL // NIMP //#define ppPeekL // NIMP //#define mmPeekL // NIMP //#define MinL // NIMP //#define MaxL // NIMP // arith u32: #define GeUL op__GE__6uint32_6uint32_5int16 #define GtUL op__GT__6uint32_6uint32_5int16 #define LtUL op__LT__6uint32_6uint32_5int16 #define LeUL op__LE__6uint32_6uint32_5int16 #define MulUL op__MUL__6uint32_6uint32_6uint32 // not used #define DivUL op__DIV__6uint32_6uint32_6uint32 // not used #define ModUL op__MOD__6uint32_6uint32_6uint32 // NIMP #define SrUL op__SR__6uint32_5int16_6uint32 //#define PowUL //#define MinUL //#define MaxUL // arith mixed i32+u32: //#define Eq_iuL //#define Ne_iuL //#define Ge_iuL //#define Gt_iuL //#define Lt_iuL //#define Le_iuL // //#define Eq_uiL //#define Ne_uiL //#define Ge_uiL //#define Le_uiL //#define Gt_uiL //#define Lt_uiL // //#define Mul_iuL //#define Mul_uiL //#define Div_iuL //#define Div_uiL //#define Mod_iuL //#define Mod_uiL // arith f48: #define EqF op__EQ__7float48_7float48_5int16 #define NeF op__NE__7float48_7float48_5int16 // not used #define GeF op__GE__7float48_7float48_5int16 #define LtF op__LT__7float48_7float48_5int16 #define LeF op__LE__7float48_7float48_5int16 #define GtF op__GT__7float48_7float48_5int16 #define AddF op__ADD__7float48_7float48_7float48 #define SubF op__SUB__7float48_7float48_7float48 #define MulF op__MUL__7float48_7float48_7float48 #define DivF op__DIV__7float48_7float48_7float48 #define ModF op__MOD__7float48_7float48_7float48 // NIMP #define NotF op__NOT__7float48_4bool // not used #define BoolF op__NOTNOT__7float48_4bool #define NegF op__SUB__4void_7float48_7float48 //#define IncrF //#define DecrF //#define PeekppF //#define PeekmmF //#define ppPeekF //#define mmPeekF #define MantF mant__7float48_6uint32 // not used. float = mantisse(float); 0.5 ? mant < 1.0; link with -lm #define SlF op__SL__7float48_5int16_7float48 // a< a n << note: neg. floats behave different than ints! #define SrF op__SR__7float48_5int16_7float48 // a>>int:n -> a n >> note: neg. floats behave different than ints! // Strings & Arrays: //#define ShrinkStr // shrink ( T[]˘ uint -- ) //#define ShrinkStrL //#define ShrinkStrF #define ShrinkStrStr ShrinkStrArray__8ucs2charAEAEC_6uint16_ // not used. shrink ( str[]˘ uint -- ) also for: array of other allocated type with no dtor //#define GrowStr // grow ( T[]˘ uint -- ) //#define GrowStrL //#define GrowStrF #define Append AppendGl__8ucs2char_8ucs2charAEP_ // operator+= ( T T[]& -- ) //#define AppendL //#define AppendF #define AppendStr AppendGl__8ucs2charAE_8ucs2charAEP_ // operator+= ( T[] T[]& -- ) //#define AppendCstr // operator+= ( T[]˘ T[]& -- ) //#define AppendRange // operator+= ( T[?] T[]& -- ) #define AppendStrRt AppendGlStrRt // not used. operator+= ( T[] T[]& -- ) and retain items #define AppendCstrRt AppendGl__8ucs2charAEAEC_8ucs2charAEAEP_// not used. operator+= ( T[]˘ T[]& -- ) and retain items #define AppendRangeRt AppendGlRangeRt // not used. operator+= ( T[?] T[]& -- ) and retain items #define AppendRt AppendGl__8ucs2charAE_8ucs2charAEAEP_ // operator+= ( T T[]& -- ) and retain items #define SortRange sort__5int16AEC_6uint16_6uint16_4boolB5int165int16D_ // sort ( int[?] bool(int,int) -- ) #define SortRangeL sort__5int32AEC_6uint16_6uint16_4boolB5int325int32D_ // NIMP. sort ( int32[?] bool(int32,int32) -- ) #define SortRangeF sort__7float48AEC_6uint16_6uint16_4boolB7float487float48D_ // NIMP. sort( float[?] bool(float,float) -- ) #define RolRange Rol_AE__6uint16AEC_6uint16_6uint16_ //#define RolRangeL //#define RolRangeF #define RorRange Ror_AE__6uint16AEC_6uint16_6uint16_ //#define RorRangeL //#define RorRangeF #define Find find__8ucs2charAEC_8ucs2char_6uint16_6uint16 // findchar ( str˘ char int:startidx -- ) //#define FindL //#define FindF #define RFind rfind__8ucs2charAEC_8ucs2char_6uint16_6uint16 // rfindchar ( str˘ char int:startidx -- ) //#define RFindL //#define RFindF //#define FindCstr // findstr ( str˘:z str˘: int -- ) //#define RFindCstr // rfindstr ( str˘:z str˘: int -- ) //#define Alloc // alloc ( uint32 -- T[] ) //#define Retain // retain ( T[]˘ -- T[] ) //#define RefCnt // refcnt ( T˘ -- uint ) //#define IsShared // is_shared ( T˘ -- uint ) //#define DropStr // dispose ( T[] -- ) //#define Shrinktofit // shrinktofit ( T[]& -- ) //#define End // end ( int -- ) // does not return //#define Assert // assert ( bool str -- ) //#define IoHelper // iohelper ( -- ) // does not advance ip #define CatCstrCstr catstr__8ucs2charAEC_8ucs2charAEC_8ucs2charAE // operator + ( str˘ str˘ -- str ) #define CatStrCstr catstr__8ucs2charAE_8ucs2charAEC_8ucs2charAE // operator + ( str str˘ -- str ) #define CatCstrStr catstr__8ucs2charAEC_8ucs2charAE_8ucs2charAE // operator + ( str˘ str -- str ) #define CatStrStr catstr__8ucs2charAE_8ucs2charAE_8ucs2charAE // operator + ( str str -- str ) //#define CatRangeCstr // operator + ( str_r str˘ -- str ) //#define CatCstrRange // operator + ( str˘ str_r -- str ) #define CatRangeStr catstr__8ucs2charAEC_6uint16_6uint16_8ucs2charAE_8ucs2charAE // operator + ( str_r str -- str ) #define CatStrRange catstr__8ucs2charAE_8ucs2charAEC_6uint16_6uint16_8ucs2charAE // operator + ( str str_r -- str ) #define CatRangeRange catstr__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_8ucs2charAE // operator + ( str_r str_r -- str ) #define CatStrChar catchar__8ucs2charAE_8ucs2char_8ucs2charAE // operator + ( T[] T -- T[] ) //#define CatStrL // operator + ( L[] L -- L[] ) //#define CatStrF // operator + ( F[] F -- F[] ) #define CatRangeChar catchar__8ucs2charAEC_6uint16_6uint16_8ucs2char_8ucs2charAE // operator + ( T[?] T -- T[] ) //#define CatRangeL // operator + ( L[?] L -- L[] ) //#define CatRangeF // operator + ( F[?] F -- F[] ) //#define CatCstrCstrRt // operator + ( str˘ str˘ -- str ) and retain items //#define CatStrCstrRt // operator + ( str str˘ -- str ) and retain items //#define CatCstrStrRt // operator + ( str˘ str -- str ) and retain items //#define CatStrStrRt // operator + ( str str -- str ) and retain items //#define CatRangeCstrRt // operator + ( str_r str˘ -- str ) and retain items //#define CatRangeStrRt // operator + ( str_r str -- str ) and retain items //#define CatCstrStrRt // operator + ( str˘ str_r -- str ) and retain items //#define CatStrRangeRt // operator + ( str str_r -- str ) and retain items //#define CatRangeRangeRt // operator + ( str_r str_r -- str ) and retain items //#define CatStrIRt // operator + ( I[] I -- I[] ) and retain item //#define Eq_CstrCstr // operator == ( str˘ str˘ -- bool ) //#define Eq_StrCstr // operator == ( str str˘ -- bool ) //#define Eq_CstrStr // operator == ( str˘ str -- bool ) //#define Eq_StrStr // operator == ( str str -- bool ) #define Eq_RangeCstr eq__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_4bool // operator == ( str_r str˘ -- bool ) #define Eq_CstrRange eq__8ucs2charAEC_8ucs2charAEC_6uint16_6uint16_4bool // operator == ( str˘ str_r -- bool ) #define Eq_RangeRange eq__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool // operator == ( str_r str_r -- bool ) //#define Ne_CstrCstr // operator != ( str˘ str˘ -- bool ) //#define Ne_StrCstr // operator != ( str str˘ -- bool ) //#define Ne_CstrStr // operator != ( str˘ str -- bool ) //#define Ne_StrStr // operator != ( str str -- bool ) #define Ne_RangeCstr ne__8ucs2charATOE_8ucs2charAEC_4bool // operator != ( str_r str˘ -- bool ) #define Ne_CstrRange ne__8ucs2charAEC_8ucs2charATOE_4bool // operator != ( str˘ str_r -- bool ) #define Ne_RangeRange ne__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool // operator != ( str_r str_r -- bool ) //#define Gt_CstrCstr // operator > ( str˘ str˘ -- bool ) //#define Ge_CstrCstr // operator >= ( str˘ str˘ -- bool ) //#define Le_CstrCstr // operator <= ( str˘ str˘ -- bool ) //#define Lt_CstrCstr // operator < ( str˘ str˘ -- bool ) #define NumStr numstr__5int16_8ucs2charAE // numstr ( int16 -- str ) #define NumStrU numstr__5int16_8ucs2charAE // numstr ( uint64 -- str ) #define NumStrL numstr__5int32_8ucs2charAE // numstr ( int32 -- str ) #define NumStrUL numstr__6uint32_8ucs2charAE // numstr ( uint32 -- str ) #define NumStrF numstr__7float48_8ucs2charAE // numstr ( float -- str ) #define SubStr SubStrc_r // ( str˘ int int -- str[?] ) #define MidStr3 midstr__8ucs2charAEC_5int16_5int16_8ucs2charATOE // ( str˘ int int -- str[?] ) #define MidStr2 midstr__8ucs2charAEC_5int16_8ucs2charATOE // ( str˘ int -- str[?] ) #define LeftStr leftstr__8ucs2charAEC_5int16_8ucs2charATOE // ( str˘ int -- str[?] ) #define RightStr rightstr__8ucs2charAEC_5int16_8ucs2charATOE // ( str˘ int -- str[?] ) // --- file: "microcodes.asm" --- #include "asm/exception.asm" // +++ file: "exception.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* LED Codes: -/yel/grn booting, cpu self test -/yel/- booting, ram test -/-/grn booting, initializing -/-/- running: all Leds off red/-/- OOMEM red/yel/- TODO red/yel/grn PANIC red/-/grn Abort (with message) */ // ======================================================= // Error Exits: // ======================================================= // abort oomem: // out of memory // :OOMEM ( -- ) // red/-/- Oomem: ( -- ) oomem: clr led_grn clr led_yel jp STOP1 // abort todo: // not yet implemented // TODO: ( -- ) // red/yel/- Todo: ( -- ) todo: clr led_grn set led_yel jp STOP1 // abort panic: // unexpected situation // PANIC: ( -- ) Panic: ( -- ) panic: set led_grn set led_yel // red/yel/grn jp STOP1 // abort with message (hopefully) // ABORT: ( -- ) // red/-/grn Abort: ( -- ) set led_grn clr led_yel // jp STOP1 STOP1: set led_red STOP2: clr clock4 clr clock2 abort // for emulator dw $ffff,abort // * abort do nop, dtmp.oe, atmp.oe // atmp = µC address in macro PANIC, TRAP, OOMEM and TODO nop, alu.oe, ip.oe // alu = TOP nop, mem.oe, hp.oe // HP and 2nd value on vstack nop, mem.oe, sp.oe // SP and top value on rstack nop, d0.oe, a0.oe nop, d1.oe, a1.oe nop, d2.oe, d2ar.oe nop, ival.oe, atmp.oe nop, sl.oe nop, sr.oe nop, swap.oe nop, msbit.oe loop // --- file: "exception.asm" --- #include "asm/ramtest.asm" // +++ file: "ramtest.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2010 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* -------------------------------------------------- Test and Clear Ram Test and clear ram with $0000. PANICs if defective ram found. RamTest should detect defective bits, defective chips, total failure of ram, defective data lines and defective address lines. Note: we can test the data ram, but we cannot test the microcode ram! failure in first loop: defective word at a0: issue with data lines? Bit always 0, always 1, shortened? failure in second loop: defective address lines => folding of addresses RamTest itself does not use any ram. RamTest does not use hp and sp On return alu = 0 so that whole memory = $00 even if alu = TOP is written back Returns via "next_mc" --> jp (*ip++) --> next microcode */ // in: - // out: alu = 0 // mod: alu,dtmp, a0 :Ramtest ( void -- void ) #if !include_ramtest//skipping: // clear ram: xor alu ld sp,alu // sp = RAMTOP do tstn sp // test for $ffff ld (sp++),alu :z while 0 next_mc #else // Check whole ram word by word: // Store and read 16 x single bit 1 and 16 x single bit 0 ld a0,$0000 // a0 -> ram do ld alu,$8000 // alu = pattern = $8000 --> $0001 ld dtmp,alu do cpl // test single bit cleared: ld (a0),alu equ dtmp // toggle bits on bus equ (a0) // delay 16 MHz equ (a0) // compare ld dtmp,alu : z jp 0,ee // defective word at a0 cpl // test single bit set: ld (a0),alu equ dtmp // toggle bits on bus equ (a0) // delay 16 MHz equ (a0) // compare ld dtmp,alu : z jp 0,ee // defective word at a0 ld sr,alu,nc // note: data bit 0 on bus ld alu,sr : bit0 // note: test for bit0 until 1 // note: conditional branch // same byte, next bit inc a0 tst a0 until z // next byte // now: all RAM[?] = $01 // Check for folding (defective address lines) and clear ram to $0000: // ld a0,$0000 // a0 = pointer ist schon // ld dtmp,1 // const: 1 ist schon do ld alu,(a0) sub dtmp // -1 ld (a0++),alu : z // $01 -> $00 while 1 // Exit loop if ram cell did not contain $0001: // either due to folded addresses due to defective address line // or because entire 64k were cleared. // a0 points behind the mirrored cell or at $0001 if entire 64k are ok: xor alu // if stopped because 64k have been cleared: ld (--a0),alu // clear ram[$0000] tst a0 TRAP !z if !z // * TRAP ld atmp,$ // * TRAP jp PANIC // * TRAP then // * TRAP next_mc ee PANIC // PANIC exit from loop 1 ld atmp,$ // * PANIC jp PANIC // * PANIC #endif // --- file: "ramtest.asm" --- #include "asm/mem.asm" // +++ file: "mem.asm" +++ /* Copyright (c) Günter Woigk 2006 - 2012 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Memory Management -------------------------------------------------------- This module implements a dynamical memory management with 'handles'. External Calls: abort_oomem Blurb: Dynamically allocated data blocks are referenced by position-independent 'handles'. If a memory request cannot be served immediately, then the garbage collection 'mem_compact' is run. The time stamp grows linearly with the number of allocated blocks and the total allocated data size. For each block 3 words with management info are added: 1 word data size and 1 word pointer + 1 word ref count Pointers are allocated from a pool which grows downwards in direction of the data blocks for global pointers and upwards towards the machine stack for hierarchically nested local pointers. Handles are pointers to these pointers. More than one pointer can point to the same data block. Pointers can point to const data outside the managed data space. Local pointers are allocated on a heap. Releasing one local pointer releases all pointers above it too. Memory Layout: _______________________ mem_end / physical ram end !___________! <---- mem_ptr_end ! ! ! gpointer ! <---- mem_free_ptr !___ ! \_______! <---- mem_ptr_start ____ ! \________ <---- mem_data_end ! ! ! ! ! data ! ! ! ____!___________!______ mem_data_start ____!___________!______ sp_base !___retaddr ! \_______! <---- sp ____ ! \________ <---- hp ! locals ! !___________!______ hp_base !___________!______ ! ! ! globals ! ____!___________!______ $0000 / physical ram start Naming: data block : memory chunk allocated in the 'data' area layout: struct { size, data[size] } memptr : pointer to data.size of a data block memcnt : reference count handle : pointer to a memptr Functions: mem_compact ( -- ) mod: sr pres: d0-d2,a0-a1,alu mem_assert_free ( d0:size -- ) mod: alu,sr pres: d0-d2,a0-a1 new_data_with_size ( d0:size -- a1:memptr ) mod: alu,sr,a1 pres: d0-d2,a0 new_data_with_filler( d0:size d1:fill -- a1:memptr) mod: alu,sr,d0-d1,a1 pres: d2,a0 // new_data_with_data ( d0:size a0->data -- a1:memptr) mod: alu,sr,d0,a0-a1 pres: d1-d2 new_handle ( -- alu:a0:handle ) mod: alu,sr,a0 pres: d0-d2,a1 new_handle_for_ptr_quick(a1:ptr -- alu:a0:handle ) mod: alu,sr,a0 pres: d0-d2,a1 alloc ( d0:size -- alu:a0:handle a1:ptr ) mod: alu,sr,a0-a1 pres: d0-d2 filled_str ( d0:size d1:fill -- alu:a0:handle) mod: alu,sr,a0-a1,d0-d1 pres: d2 // alloc_with_data ( d0:size a1->data -- alu:a0:handle)mod: alu,sr,a0-a1,d0 pres: d1-d2 // del_handle ( a0:handle -- ) mod: -- pres: d0-d2,a0-a1,alu mem_resize_handle mem_shrink_handle ( a0=handle d0=size -- a0=handle ) mod: alu,sr pres:d0-d2,a0-a1 mem_grow_handle ( a0=handle d0=size -- a1->space ) mod: alu,sr,a0-a1 pres:d0-d2 mem_append_handle ( a0=handle1 a1=handle2 -- ) mod: alu,a0-a1,d0-d1 pres: d2 mem_find_handle ( alu=address--a0=handle d0=alu=idx)mod:alu,a0-a1,d0-d1 pres: d2 Opcodes: MEM_COMPACT ( -- ) MEM_GET_FREE_TOTAL ( -- u16:size ) MEM_GET_FREE ( -- u16:size ) MEM_ASSERT_FREE ( size -- ) // NEW_DATA_WITH_SIZE ( size -- memptr ) // alu = a1 -> data.size; data cleared ALLOC ( size -- str ) // a1 -> data.size; data cleared FILLEDSTR ( size filler -- str ) // alu = a1 -> data.size data cleared with filler DROPSTR ( str -- ) // release memory NIPSTR ( str top -- top ) // release memory Millicodes: MemCompact ( -- ) MemGetFreeTotal ( -- size ) MemGetFree ( -- size ) MemAssertFree ( size -- ) // NewDataWithSize ( size -- memptr ) // alu = a1 -> data.size; data cleared Alloc ( size -- str ) // a1 -> data.size; data cleared FilledStr ( size filler -- str ) // alu = a1 -> data.size data cleared with filler DropStr ( str -- ) // release memory NipStr ( str top -- top ) // release memory */ // -------------------------------------------------------- // Garbage Collection // // in: -- // out: -- // mod: sr // pres: alu,d0-d2,a0-a1 :mem0 if 1 MEM_COMPACT: ( -- ) pshr NEXT // return address else MemCompact: ( -- ) pshr next_mc // return address then // jp mem_compact mem_compact: login ld io,alu,d_bits=10 // * login psh alu,a0,a1,d0,d1 // *dtmp* // 1. Loop over Handles: // In the size field of all used data blocks a pointer to the data pointer is stored. // In the data pointer the size is stored. // // If multiple data pointers point to the same data block, then this creates a linked list // data.size -> data_ptr1 -> data_ptr2 -> data_ptr_n = block_size. ld a0,(mem_ptr_end) // a0 -> behind last ptr *dtmp* ld d0,(mem_data_start) // d0 -> first data: dyn. data is in range [d0 .. [d1 *atmp* ld d1,(mem_ptr_start) // d1 -> first ptr: also loop end *atmp* jp mem_p1 do dec a0 // step over memcnt ld alu,(a0) // alu = *ptr: must be in range [d0 .. [d1 cmp_nc d1 // first_ptr - *ptr -1 if !cy // !cy => cy => first_ptr - *ptr -1 ? 0 => first_ptr ? *ptr+1 // => first_ptr > *ptr => ptr in use! cmp d0 if cy // cy => !cy => *ptr-mem_data_start?0 => *ptr?mem_data_start ld a1,alu // a1 -> data.size ld alu,(a1) // alu = data.size ld (a1),a0 // data.size -> ptr *dtmp* ld (a0),alu // *ptr := data.size then then mem_p1 ld alu,d1 equ a0-- // compare with first_ptr & step until z // 2. Loop over Data Blocks: // Used blocks and freed blocks can be distinguished by their size field: // size fields of used blocks now contain a pointer to their (first) data_ptr ? mem_data_end // size fields of free blocks still contain their block size < mem_data_end // Unused blocks are skipped. // The data of used blocks is moved downwards to close any gap formed by free blocks. // The size is restored to the size field and the new block address is stored in the data_ptr. // If the data block was shared, then the data_ptr did not contain the block size < mem_data_end // but the address of the the next sharing data_ptr, which is ? mem_data_end. // All data_ptrs are updated to point to the new data location, // until a data_ptr, the last sharing data_ptr, actually contains the block size. // Improvements TODO: // a first loop can skip over data blocks which do not move // until the first released data block is encountered ld a0,d0//(mem_data_start) // a0 -> old data *dtmp* ld d1,(mem_data_end) // for loop end test and for discriminating between ptrs and sizes *atmp* ld a1,a0 // a1 -> new data do ld d0,(a0++) // a0 -> old_data.data; used: d0 -> data_ptr; free: d0 = size ld alu,d0 cmp d1 // mem_data_end if !cy // !cy => cy => d0 = size => freed block => skip it add a0 // size + old_data.data => alu -> next old_data.size ld a0,alu // a0 -> next old data else // block is in use: // d0 -> data_ptr // a0 -> old data.data // a1 -> new data.size // read size (or ptr to other data_ptr) from data_ptr // write new data address into data_ptr // if the read size is ? mem_data_end, then this is a link to another data_ptr. // Then do same with the other data_ptr. ld dtmp,a0 // dtmp -> old_data.data ld a0,d0 // a0 -> (1st) data_ptr ld d0,a1 // d0 -> new data.size do ld alu,(a0) // alu = data.size or ptr -> other data_ptr ld (a0),d0 // store ptr -> new data cmp d1 // mem_data_end ld a0,alu :cy // a0 -> other data_ptr (if alu ? mem_data_end) until 0 // !cy => cy => alu < mem_data_end => alu = data size ld (a1++),alu // store data.size; a1 -> new data.data ld a0,dtmp // a0 -> old_data.data jsr memcpy // a0 -> next old_data.size; a1 -> next new_data.size ld alu,a0 // alu -> next old data then equ d1 // compare with mem_data_end until z // update sysvar ld (mem_data_end),a1 // *dtmp* *atmp* // clear new space ld alu,a0 sub a1 jsr memclr // exit pop d1,d0,a1,a0,alu // *dtmp* logout ld io,alu,d_bits=11 // * logout ret // *post* // -------------------------------------------- // allocate handle and data: // // in: d0 = size // out: alu = a0 = handle // a1 = memptr // mod: alu,sr,a0,a1 // pres: d0-d2 // :mem2 if 1 ALLOC: ( size -- str ) // a1 -> data.size; data actually cleared pshr NEXT else Alloc: ( size -- str ) // a1 -> data.size; data actually cleared pshr next_mc then ld d0,alu // jp alloc alloc: pshr new_handle_for_ptr_quick // jp new_data_with_size // -------------------------------------------- // allocate data: // asserts 2 words free for a pointer+refcnt without mem_compact() // runs mem_compact() if needed // // in: d0 = size // out: a1 = memptr -> data.size // d0 = size (pres.) // mod: alu,sr,a1 // pres:d0-d2,a0 // new_data_with_size: ld atmp,mem_data_end // atmp->mem_data_end ld alu,(atmp++) // alu = mem_data_end atmp->mem_ptr_start ld dtmp,alu // dtmp = mem_data_end add_c d0 // alu = new mem_data_end jp cy,p1 // cy => new mem_data_end ? $10000 ld d2ar,(atmp--) // d2ar = mem_ptr_start atmp->mem_data_end ld a1,d2ar-1 // a1 = mem_ptr_start -1 cmp a1 // new mem_data_end - (mem_ptr_start-1) jp cy,p1 // cy => !cy => new mem_data_end ? (mem_ptr_start-1) // ((mem_ptr_start!=$0000!!)) p2 ld a1,dtmp ld (a1),d0 // data.size = size ld (atmp),alu // update mem_data_end ret // a1 -> data.size; d0 = size *post* // no space => compact & retry p1 jsr mem_compact ld atmp,mem_data_end // atmp->mem_data_end ld alu,(atmp++) // alu = mem_data_end atmp->mem_ptr_start ld dtmp,alu // dtmp = mem_data_end add_c d0 // alu = new mem_data_end jp cy,p1 // cy => new mem_data_end ? $10000 ld d2ar,(atmp--) // d2ar = mem_ptr_start atmp->mem_data_end ld a1,d2ar-1 // a1 = mem_ptr_start -1 cmp a1 // new mem_data_end - (mem_ptr_start-1) jp !cy,p2 jp oomem // cy => !cy => new mem_data_end ? (mem_ptr_start-1) // ((mem_ptr_start!=$0000!!)) // -------------------------------------------- // allocate data: // in: d0 = size // d1 = filler // out: a1 -> data.size // alu=a0=handle // mod: alu,sr,a0-a1,d0-d1 // pres:d2 // :mem3 if 1 FILLEDSTR: ( len filler -- str ) // alu = a1 -> data.size pshr NEXT else FilledStr: ( len filler -- str ) // alu = a1 -> data.size pshr next_mc then pop d0 // size ld d1,alu // filler jp filled_str :mem5 if 1 SPACESTR: ( len -- str ) pshr NEXT else SpaceStr: ( len -- str ) pshr next_mc then ld d0,alu ld d1,' ' // jp filled_str filled_str: pshr new_handle_for_ptr_quick // jp new_data_with_filler // -------------------------------------------- // allocate data: // asserts one word free for a pointer without mem_compact() // runs mem_compact() if needed // // in: d0 = size // d1 = filler // out: a1 = memptr // mod: alu,sr,a1,d0-d1 // pres:a0,d2 // new_data_with_filler: jsr new_data_with_size // ( d0=size -- a1->data.size ) mod:alu,sr,a1 pres:d0-d2,a0 ld d0,d1 // d0=filler ld d1,a1 // d1=memptr ld alu,(a1++) // alu=count, a1->dest jsr memset // ( a1->dest alu=count d0=filler ) mod: alu,sr,a1 pres:d0-d2,a0 ld a1,d1 // a1=memptr ret // ======================================================== // handles // ======================================================== // -------------------------------------------- // get a new handle for a memptr: // two words free must be asserted! e.g. by new_data_with_xxx() // does not run mem_compact(). // in: a1 = memptr // out: alu = a0 = handle // handle is retained // mod: alu,sr,a0 // pres: a1, d0-d2 // :new_handle_for_ptr_quick ld atmp,mem_free_ptr // get ptr from free_list ld alu,(atmp) // delay ld alu,(atmp) if !z // got one: ld a0,alu // a0 = alu = handle ld (atmp),(a0) // update mem_free_ptr *dtmp* ld (a0++),a1 // store data_ptr *dtmp* ld (a0--),1 ret // *post* else // free_list empty: ld atmp,mem_ptr_start // atmp -> mem_ptr_start ld dtmp,(atmp) // dtmp = mem_ptr_start ld dnop,dtmp,a0.clk,dxa.oe,sub2 // a0 = mem_ptr_start-2 = new mem_ptr_start ld alu,a0 // alu = a0 = new mem_ptr_start = new handle ld (atmp),alu // update mem_ptr_start ld (a0++),a1 // store data_ptr *dtmp* ld (a0--),1 ret // *post* then // -------------------------------------------- // get a new handle: // may run mem_compact() // the memptr is preset so that mem_compact() can be run safely // before a dataptr is stored in the memptr // in: -- // out: alu=a0=handle // mod: alu,a0,sr // pres: d0-d2,a1 // :new_handle ld atmp,mem_free_ptr // atmp -> linked list of free mem pointers ld alu,(atmp) // delay ld alu,(atmp) // get address of free memptr ld a0,alu :z // a0 = alu = handle if 0 // !z -> got one ld (atmp),(a0++) // update mem_free_ptr -> next in linked list *dtmp* ld (a0--),1 // refcnt := 1 // ld (a0),0 // note: free memptr is mem_compact()-safe: 0 or address_of_next_free_ptr > mem_ptr_start ret // else // free_list is empty => get ptr at start of pointers ld atmp,mem_ptr_start ld d2ar,(atmp--) // d2ar -> last used memptr; atmp -> mem_data_end ld a0,d2ar-1 // a0 -> new memcnt ld alu,a0 // alu = mem_ptr_start-1 sub_nc (atmp++) // alu = mem_ptr_start-1-mem_data_end-1 = gap_sz - 2 // atmp -> mem_ptr_start if cy // cy=!cy -> gap_sz - 2 ? 0 -> gap_sz ? 2 p1 ld (a0--),1 // memcnt = 1; a0 -> memptr // ld (a0),0 // make memptr mem_compact()-safe note: must be 0 ld alu,a0 // alu = a0 = handle ld (atmp),alu // update mem_ptr_start ret // *post* else jsr mem_compact // pres. alu,a0-a1,d0-d2 ld atmp,mem_ptr_start ld d2ar,(atmp--) // d2ar -> last used memptr ld a0,d2ar-1 // a0 -> new memcnt ld alu,a0 // alu = mem_ptr_start-1 sub_nc (atmp++) // alu = mem_ptr_start-1-mem_data_end-1 = gap_sz - 2 jp cy,p1 // cy=!cy -> gap_sz - 2 ? 0 -> gap_sz ? 2 jp oomem then then // -------------------------------------------- // find block which contains an address // the address must actually point inside an allocated block // or the returned handle/index are meaningless // in: alu = address // out: a0 = handle // d0 = alu = index // pres: d2 // :mem_find_handle login ld io,alu,d_bits=10 // * login TODO // anpassung wg. memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d1,alu // d1 = address ld a1,(mem_ptr_start) // a1 = pointer in memptrs dtmp ld alu,(mem_ptr_end) // atmp sub_nc a1 ld atmp,alu // atmp = loop counter ld d0,0 // d0 = 0 = 'best' memptr so far ld a0,d0 // a0 = 0 = 'best' handle so far do ld alu,(a1++) // alu = next memptr cmp d0 // new memptr - old memptr jp !cy,n // !cy => cy => new < old => worse than current 'best' cmp_nc d1 // new memptr - address -1 jp cy,n // cy => !cy => new memptr > address // new 'best' candidate: ld a0,a1-1 ld d0,alu n tst atmp-- while !z // now a0/d0 should be the memblock which contains the var: ld alu,d1 // address sub_nc d0 // alu = index = address - memptr -1 ld d0,alu ret // a0 = handle // -------------------------------------------- // resize handle: // in: a0=handle // d0=new size // out: a1->start of appended space (only if grown) // pres:d0-d2 // :mem_resize_handle // login // TODO ld d2ar,(a0) // d2ar = memptr ld alu,(d2ar) // alu = mem.size cmp d0 // oldsize-newsize jp !cy,mem_grow_handle // !cy => cy => oldsize-newsize<0 => oldsizemem.data ld alu,d0 // alu=new size add atmp // alu=memptr+1+size -> gap ld atmp,alu // atmp->gap.size ld alu,dtmp // alu=old size sub_nc d0 // alu=old size-new size -1 = gap.size ld (atmp),alu // gap.size := alu ret // post mem_shrink_handle_cond: // login // TODO ld d2ar,(a0) // d2ar = memptr ld alu,(d2ar) // alu = old len cmp_nc d0 // oldlen - newlen -1 jp cy,mem_shrink_handle// cy => !cy => oldlen -newlen -1 ? 0 => newlenstart of appended space // mod: alu,a0-a1 // pres:d0-d2 // :mem_grow_handle_cond // login // TODO ld d2ar,(a0) // d2ar = memptr ld alu,(d2ar) // alu = old len cmp d0 // oldlen - newlen ret cy // cy => !cy => newlen?oldlen mem_grow_handle: // login // TODO jsr new_data_with_size // out:a1=ptr mod: alu,sr,a1 pres: d0-d2,a0 ld alu,(a0) // alu = old memptr ld (a0),a1 // *handle = new memptr dtmp ld a0,alu // a0 = old memptr ld alu,(a0++) // alu = oldlen; a0->olddata.data inc a1 // a1->newdata.data jp memcpy // -------------------------------------------- // append data from handle a1 to data from handle a0 // handle a1: not modified and not released // // in: a0=handle1 // a1=handle2 // out: -- // mod: alu,a0-a1,d0-d1 // pres:d2 // :mem_append_handle ld d2ar,(a0) // memptr1 ld alu,(d2ar) // alu=size1 ld d2ar,(a1) // memptr2 add (d2ar) // alu=size1+size2 ld d0,alu :cy // d0=size1+size2 jp 1,oomem // size1+size2>$ffff ld d1,a1 // d1=handle2 jsr mem_grow_handle // a1->start of appended space pres: d0-d2,a0 ld a0,d1 // a0=handle2 ld a0,(a0) // a0=ptr2 dtmp ld alu,(a0++) // alu=len2 jp memcpy #if 0//skipping: // -------------------------------------------- // allocate data: // in: d0 = size // d1 = filler // out: a1 -> data.size // alu=a0=handle // mod: alu,sr,a0-a1,d0-d1 // pres:d2 // :NEW_DATA_WITH_SIZE ( size -- memptr ) // alu = a1 -> data.size; data cleared ld d0,alu jsr new_data_with_size ld alu,a1 next_op :NewDataWithSize ( size -- memptr ) // alu = a1 -> data.size; data cleared ld d0,alu jsr new_data_with_size ld alu,a1 next_mc #endif // -------------------------------------------------------- // Get amount of immediately available memory // which will not trigger the garbage collection. // note: Returns the raw available size -3 ? 0 // This asserts a request for the returned size. // Except if the returned size = 0; then even a dup_pointer may fail. // :mem4 if 1 MEM_GET_FREE: ( -- u16:size ) pshr NEXT else MemGetFree: ( -- size ) pshr next_mc then psh alu ld atmp,mem_ptr_start ld alu,-3 // alu = -3 add (atmp--) // alu = mem_ptr_start -3 sub (atmp) // mem_ptr_start -3 -mem_data_end if cy ret else xor alu ret // post then // -------------------------------------------------------- // Test whether d0+2 bytes are available. // note: d0=req.size +1=data.size +1=memptr // runs mem_compact() if needed. // // in: d0 = requested size // out: d0 = size (pres.) // mod: alu,sr // pres: d0-d2,a0-a1 // :mem1 if 1 MEM_ASSERT_FREE: ( size -- ) ld d0,alu pshr DROP // return address else MemAssertFree: ( size -- ) ld d0,alu pshr Drop // return address then // jp mem_assert_free mem_assert_free: login ld io,alu,d_bits=10 // * login TODO // assert d0+3 bytes ld atmp,$ // * TODO jp TODO // * TODO ld atmp,mem_ptr_start ld alu,(atmp--) // mem_ptr_start sub_nc (atmp) // -mem_data_end -1 jp !cy,p1 // !cy => cy => mem_ptr_start ? mem_data_end => mem_ptr_start == mem_data_end sub_nc d0 // -size -1 ret cy // cy => !cy => remaining space ? 0 p1 jsr mem_compact // compact & try again: ld atmp,mem_ptr_start ld alu,(atmp--) // mem_ptr_start sub_nc (atmp) // -mem_data_end -1 jp !cy,oomem sub_nc d0 // -size -1 ret cy jp oomem // -------------------------------------------- // peek & retain handle // retain handle // NULL-safe // :PeekStr ( str& -- str ) ld a1,alu // a1->strvar ld alu,(a1) // alu=handle Retain: ( str -- str ) ld atmp,alu jp z,next_mc xor alu inc atmp // *combine* add_c (atmp) ld (atmp--),alu ld alu,atmp next_mc :PEEKSTR ( str& -- str ) ld a1,alu // a1->strvar ld alu,(a1) // alu=handle RETAIN: ( str -- str ) ld atmp,alu jp z,NEXT xor alu inc atmp // *combine* add_c (atmp) ld (atmp--),alu ld alu,atmp next_op // *post* // -------------------------------------------- // Release memory // NULL-safe // :NipStr ( str top -- top ) // release memory ld dtmp,(hp) ld (hp),alu ld alu,dtmp // jp DropStr DropStr: ( str -- ) // release memory ld atmp,alu // atmp -> memptr inc atmp :z // atmp -> memcnt jp 1,Drop // null ld d2ar,(atmp) // d2ar = memcnt ld a0,d2ar-1 // a0 = memcnt-1 ld (atmp--),a0 // update memcnt atmp -> memptr *dtmp* jp !z,Drop // memcnt != 0 ld a0,mem_free_ptr ld (atmp),(a0) // *dtmp* ld (a0),alu pop alu next_mc :NIPSTR ( str top -- top ) // release memory ld dtmp,(hp) ld (hp),alu ld alu,dtmp // jp DROPSTR DROPSTR: ( str -- ) // release memory ld atmp,alu // atmp -> memptr inc atmp :z // atmp -> memcnt jp 1,DROP ld d2ar,(atmp) // d2ar = memcnt ld a0,d2ar-1 // a0 = memcnt-1 ld (atmp--),a0 // update memcnt atmp -> memptr *dtmp* jp z,DROP ld a0,mem_free_ptr ld (atmp),(a0) // *dtmp* ld (a0),alu pop alu next_op // *post* // -------------------------------------------- // Store Handle in Variable // and release old handle // NULL-safe // POKESTR: ( str str* -- ) ld a0,alu // a0 -> zstr ld alu,(a0) // alu = old zstr pop (a0) // *zstr := qstr *dtmp* jp DROPSTR PokeStr: ( str str* -- ) ld a0,alu // a0 -> zstr ld alu,(a0) // alu = old zstr pop (a0) // *zstr := qstr *dtmp* jp DropStr // -------------------------------------------- // allocate handle and data: // // in: d0 = size // d1 = tracked address // out: alu = a0 = handle // d1 = updated address // a1 = memptr // mod: alu,sr,a0,a1 // pres:d0,d2 // :alloc_wtv pshr new_handle_for_ptr_quick // jp new_data_with_size_wtv // -------------------------------------------- // allocate data and track an address: // asserts 2 words free for a pointer+refcnt without mem_compact() // runs mem_compact() if needed // if mem_compact() is run and address d1 lies inside the movable memory, // then address d1 is updated to the new address // // in: d0 = size // d1 = tracked address // out: a1 = memptr -> data.size // d0 = size (pres.) // d1 = updated address // mod: alu,sr,a1 // pres:d0,d2,a0 // new_data_with_size_wtv: ld atmp,mem_data_end // atmp->mem_data_end ld alu,(atmp++) // alu = mem_data_end atmp->mem_ptr_start ld dtmp,alu // dtmp = mem_data_end add_c d0 // alu = new mem_data_end jp cy,p1 // cy => new mem_data_end ? $10000 ld d2ar,(atmp--) // d2ar = mem_ptr_start atmp->mem_data_end ld a1,d2ar-1 // a1 = mem_ptr_start -1 cmp a1 // new mem_data_end - (mem_ptr_start-1) jp cy,p1 // cy => !cy => new mem_data_end ? (mem_ptr_start-1) // ((mem_ptr_start!=$0000!!)) p2 ld a1,dtmp ld (a1),d0 // data.size = size ld (atmp),alu // update mem_data_end ret // a1 -> data.size; d0 = size *post* // no space => compact & retry p1 ld alu,d1 // alu = tracked address ld atmp,mem_ptr_start // atmp=mem_ptr_start cmp (atmp) // address-mem_ptr_start if !cy // !cy => cy => address not in allocated ram jsr mem_compact else // d1 points into movable ram: psh a0,d0 // *dtmp* jsr mem_find_handle // ( alu:address -- a0:handle d0:alu:index ) pres: d2 jsr mem_compact // a0 = handle -> memptr ld dtmp,(a0) // dtmp = memptr -> data.size add_c dtmp // alu -> data.data + index ld d1,alu // update tracked address in d1 pop d1,a0 // *dtmp* then ld atmp,mem_data_end // atmp->mem_data_end ld alu,(atmp++) // alu = mem_data_end atmp->mem_ptr_start ld dtmp,alu // dtmp = mem_data_end add_c d0 // alu = new mem_data_end jp cy,p1 // cy => new mem_data_end ? $10000 ld d2ar,(atmp--) // d2ar = mem_ptr_start atmp->mem_data_end ld a1,d2ar-1 // a1 = mem_ptr_start -1 cmp a1 // new mem_data_end - (mem_ptr_start-1) jp !cy,p2 jp oomem // cy => !cy => new mem_data_end ? (mem_ptr_start-1) // ((mem_ptr_start!=$0000!!)) // --- file: "mem.asm" --- #include "asm/ldir.asm" // +++ file: "ldir.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* memcpy ( a0=Q a1=Z alu=n -- a0+=n a1+=n ) mod:alu,sr,a0,a1 pres:d0-d2 memclr ( a1=Z alu=n -- a1+=n ) mod:alu,sr,a1,d0 pres:d1-d2,a0 memset ( a1=Z alu=n d0=filler -- a1+=n ) mod:alu,sr,a1 pres:d0-d2,a0 */ :ldir1a if 1 TRADMEMCPY: ( a:dest a:src cnt -- ) pshr DROP else TradMemCpy: ( a:dest a:src cnt -- ) pshr Drop then pop a0,a1 // *dtmp* jp memcpy // --------------------------------------------- // move block of data in ram // in: a0 -> source // a1 -> dest // alu = count // out: a0 += count; a1 += count // mod: alu,sr,a0,a1 // pres:d0-d2 // :ldir1 if 1 NEWMEMCPY: ( a:src a:dest cnt -- ) pshr DROP else NewMemCpy: ( a:src a:dest cnt -- ) pshr Drop then pop a1,a0 // *dtmp* // jp memcpy memcpy: ldir: ld sr,alu,nc // sr = cnt/16 ld sr,sr,nc ld sr,sr,nc ld sr,sr,nc and $F // cnt&15: 0..15 cpl // -1 .. -16 add alu // -2 .. -32 nodelay // and memcpytable | 31 add mc0+2 // *dtmp* ld cmd,alu ld atmp,sr :bit15 // atmp = cnt/16 //:memcpytable % 32 do ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* ld (a1++),(a0++) // *dtmp* mc0 tst atmp-- while !z ret :lddr1 if 1 TRADRMEMCPY: ( a:dest a:src cnt -- ) pshr DROP else TradRMemCpy: ( a:dest a:src cnt -- ) pshr Drop then pop a0,a1 // *dtmp* jp rmemcpy // --------------------------------------------- // move block of data in ram // in: a0 -> source // a1 -> dest // alu = count // mod: alu,sr // pres:d0-d2, a0,a1 // :lddr2 if 1 NEWRMEMCPY: ( a:src a:dest cnt -- ) pshr DROP else NewRMemCpy: ( a:src a:dest cnt -- ) pshr Drop then pop a1,a0 // *dtmp* // jp memcpy rmemcpy: ld dtmp,alu add a0 ld a0,alu ld alu,dtmp add a1 ld a1,alu ld alu,dtmp // move block of data in ram // in: a0 -> source end (excl) // a1 -> dest end (excl) // alu = count // out: a0 -= count; a1 -= count // mod: alu,sr,a0,a1 // pres:d0-d2 // lddr: dec a0 dec a1 ld sr,alu,nc // sr = cnt/16 ld sr,sr,nc ld sr,sr,nc ld sr,sr,nc and $F // cnt&15: 0..15 cpl // -1 .. -16 add alu // -2 .. -32 nodelay // and memcpytable | 31 add mc0+2 // *dtmp* ld cmd,alu ld atmp,sr :bit15 // atmp = cnt/16 //:rmemcpytable % 16 do ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* ld (a1--),(a0--) // *dtmp* mc0 tst atmp-- while !z inc a0 inc a1 ret :lddrx1 if 1 TRADMEMMOVE: ( a:dest a:src cnt -- ) pshr DROP else TradMemMove: ( a:dest a:src cnt -- ) pshr Drop then pop a0,a1 // *dtmp* jp memmove :lddrx2 if 1 NEWMEMMOVE: ( a:src a:dest cnt -- ) pshr DROP else NewMemMove: ( a:src a:dest cnt -- ) pshr Drop then pop a1,a0 // *dtmp* // jp memmove // --------------------------------------------- // move block of data in ram // in: a0 -> source // a1 -> dest // alu = count // mod: alu,sr,a0,a1 // pres:d0-d2 // memmove: ld dtmp,alu ld alu,a0 cmp a1 // src_addr - dest_addr ld alu,dtmp :cy if 1 jp memcpy // cy=!cy => src_addr ? dest_addr => ldir else jp rmemcpy then // -------------------------------------------- // clear block of data to $0000 // in: a1 -> dest // alu = count // out: a1 += count // mod: alu,sr,a1,d0 // pres:d1-d2,a0 // :ldir3 if 1 MEMCLR: ( a:dest cnt -- ) pshr DROP else MemClr: ( a:dest cnt -- ) pshr Drop then pop a1 // *dtmp* // jp memclr memclr: ld d0,0 // jp memset // -------------------------------------------- // clear block of data with filler // in: a1 -> dest // alu = count // d0 = fill word // out: a1 += count // mod: alu,sr,a1 // pres:d0-d2,a0 // memset: ld sr,alu,nc ld sr,sr,nc ld sr,sr,nc ld sr,sr,nc and $F // 0..15 cpl // -1 .. -16 // and memsettable | 15 add ms0+1 // *dtmp* ld cmd,alu ld atmp,sr :bit15 //:memsettable % 16 do ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ld (a1++),d0 ms0 tst atmp-- while !z ret :ldir2 if 1 MEMSET: ( a:dest filler cnt -- ) pshr DROP else MemSet: ( a:dest filler cnt -- ) pshr Drop then pop d0,a1 // *dtmp* jp memset // --- file: "ldir.asm" --- #include "asm/interrupt.asm" // +++ file: "interrupt.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // ============================================================ // Interrupt Vectors: // ============================================================ // interrupts jump to $1000:0 .. $3000:0 and $0000:1 .. $3000:1 // depending on the replaced opcode. ($0000:0 is the reset vector) :IRPT2 = $2000:0 ( -- ) jp IRPT1 :IRPT3 = $3000:0 ( -- ) jp IRPT1 :IRPT4 = $0000:1 ( -- ) jp IRPT1 :IRPT6 = $2000:1 ( -- ) jp IRPT1 :IRPT7 = $3000:1 ( -- ) jp IRPT1 :IRPT5 = $1000:1 ( -- ) dec ip :0 // ... and join handler in other plane :IRPT1 = $1000:0 ( -- ) dec ip // restore suppressed opcode pshr ip // *dtmp* ld dtmp,alu // save alu ld d2ar,io_irpt ld alu,d2ar // int status of all devices di // *combine* ld atmp,int_mask or (atmp) ld msbit,alu // msbit = highest 0-bit position ld alu,dtmp // restore alu ld d2ar,msbit // d2ar = 0 .. 15 ld d2ar,(d2ar) // d2ar -> OPCODE 'SELECTI' ld ip,d2ar+1 // ip -> IVAL 'SELECTMASK' ld io_select,(ip++) set led_yel clr led_grn next_op // *post* :DROP8_RETI ( x x x x x x x x -- ) pop alu pop alu pop alu pop alu pop alu pop alu pop alu pop alu // jp RETI DROP0_RETI: RETI: ( -- ) // return from interrupt popr ip // *dtmp* ld io_select,$ffff // deselect device clr led_yel set led_grn ei // re-enable interrupts next_op // *post* // wait for interrupt // handle interrupt if interrupts are enabled // and resume millicode // :Halt ( -- ) set halt // wait for interrupt pshr ip // dtmp ld ip,opcode_Ret clr halt next_op // Template für Timer-Interrupt-Handler #if 0//skipping: void SYSTEMTIMER() { current_microsec += microsecs_per_int; if current_microsec ? 1000000 { current_time++; current_microsec -= 1000000; } } #endif #if 1 :SYSTEMTIMER ( -- ) Millicoded // Size: 23 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Gget+microsecs_per_int mc new__6uint16_6uint32 mc Gvar+current_microsec mc op__ADDGL__5int32_5int32P_ mc Gvar+current_microsec mc Peek2 mc Int8+15 mc Int8+64 mc Int16+66 mc op__GE__6uint32_6uint32_5int16 mc BraIf0+7 mc Gvar+current_time mc IncrL mc Int8+15 mc Int8+64 mc Int16+66 mc Gvar+current_microsec mc op__SUBGL__5int32_5int32P_ mc NextOpcode #endif #if 0//skipping: :SYSTEMTIMER ( -- ) ld a0,microsecs_per_int ld dtmp,(a0--) // dtmp = microsecs_per_int; a0 -> current_microsec.lo ld alu,(a0) // alu = current_microsec.lo (alt) add dtmp // alu = current_microsec.lo (neu) ld (a0--),alu : cy // update current_microsec.lo; a0 -> current_microsec.hi if 1 ld d1,alu // d1 = current_microsec.lo ld d2ar,(a0) // d2ar = current_microsec.hi ld atmp,d2ar+1 ld alu,atmp // alu = current_microsec.hi ld (a0--),alu // update current_microsec.hi; a0 -> current_time.lo else ld d1,alu // d1 = current_microsec.lo ld alu,(a0--) // alu = current_microsec.hi; a0 -> current_time.lo then ld dtmp,1e6.hi // dtmp = 1000000.hi ld d0,1e6.lo // d0 = 1000000.lo equ dtmp if z // 1000000.hi == current_microsec.hi ld alu,d1 // alu = current_microsec.lo ld dtmp,d0 // dtmp = 1000000.lo then cmp dtmp // current_microsec - 1000000 if cy // cy=!cy => current_microsec ? 1000000 ld d2ar,(a0) // d2ar = current_time.lo ld atmp,d2ar+1 ld alu,atmp // alu = current_time.lo ld (a0--),atmp // update current_time.lo; a0 -> current_time.hi if z ld d2ar,(a0) // d2ar = current_time.hi ld atmp,d2ar+1 ld alu,atmp // alu = current_time.hi ld (a0),atmp // update current_time.hi then then next_op #endif // --- file: "interrupt.asm" --- #include "asm/millicode.asm" // +++ file: "millicode.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // Microcode for the K1-16/16 CPU // // 2012-04-25 // ================================================================ // millicode: // ================================================================ // forth-style opcodes in microcode rom // // similar to opcodes in ram // // notes: // do not forget to save & restore ip! // millicodes with cmd_lo argument can use opcode range $100 .. $F00 // instruction macros are in instr.h // Millicode: clear errno // :clear_error ( -- ) // clear errno ld atmp,errno ld (atmp),0 //ok next_mc // ================================================================ // Code Model Change & Subroutines: // ================================================================ // switch from microcode to millicode: // push ip and start millicode processing at atmp // used in macro instruction 'Millicoded' // (( ld atmp,$+4 )) // (( jp millicoded )) // millicoded: pshr ip // dtmp ld cmd,atmp, ip.clk, add1 // & ip = atmp+1 ld cmd,ival :bit15 // Return to millicoded procedure: // either from millicoded or microcoded proc im microcode ROM // or from opcoded procedure in RAM. // note: the opcode Ret is always stored in the gvar opcode_Ret // :Ret ( -- ) Next: popr ip // dtmp Nop: ( -- ) next_mc: next_mc // switch from millicode to microcode: // :Native ( -- ) jp ip // Call Procedure in Ram from Millicode: // :CallOpcode ( a:proc -- ) pshr ip,opcode_Ret // dtmp ld ip,alu pop alu next_op // post // Call Millicode ProcPointer from Millicode: // :CallMillicode ( addr -- ) ld cmd,alu pop alu :bit15 // Call Millicoded Struct or Array Destructor 'kill()' from Millicode: // Call kill() if handle != null and retain count == 1 // the kill() proc Millicode follows after this opcode // :CallKill ( T -- T ) ld atmp,alu if !z inc atmp // --> ref_cnt ld d2ar,(atmp) ld atmp,d2ar-1 tst atmp if z next_mc then then inc ip // skip kill() millicode next_mc // ================================================================ // Code Flow: // ================================================================ // ------------------------------------------------------- // branch to $+1+dis // // note: // if Bra_M == Bra-$100 // then Bra can be used for dist = -256 .. +255 :Bra_M = $100:0 ( -- ) // branch to ip-256+dis ld ip,ip-dis next_mc :Bra = $200:0 ( -- ) // branch to ip+dis ld ip,ip+dis next_mc :BraIf1_M = $300:0 ( bool -- ) tst alu pop alu : z if 1 next_mc else ld ip,ip-dis // ld ip,ip-256+dis next_mc then :BraIf1 = $400:0 ( bool -- ) tst alu pop alu : z if 1 next_mc else ld ip,ip+dis next_mc then :BraIf0_M = $500:0 ( bool -- ) tst alu pop alu : z if 0 next_mc else ld ip,ip-dis next_mc then :BraIf0 = $600:0 ( bool -- ) tst alu pop alu : z if 0 next_mc else ld ip,ip+dis next_mc then // ------------------------------------------------------- // pruning boolean OR: // mc Or1 // mc Bra // :Or1 ( i1 -- ) tst alu if !z ld alu,1 // this allows i16 argument instead of proper i1 next_mc else pop alu // drop i1 inc ip // skip bra next_mc // execute 2nd branch for i1 then // pruning boolean AND: // mc And0 // mc Bra // :And0 ( i1 -- ) tst alu if z next_mc else pop alu // drop i1 inc ip // skip bra next_mc // execute 2nd branch for i1 then // -------------------------------------------------------- // jump to address // after 'Hi8' // //:Jp = $100:1 ( -- ) // ld ip,dxa+dis,swap.oe // ld ip,swap+dis // next_mc //:JpIf1 = $700:0 ( i1 -- ) // ((not used so far)) // tst alu // pop alu :z // if 0 // ld ip,dxa+dis,swap.oe // ld ip,swap+dis // next_mc // else // next_mc // then //:JpIf0 = $800:0 ( i1 -- ) // tst alu // pop alu :z // if 1 // ld ip,dxa+dis,swap.oe // ld ip,swap+dis // next_mc // else // next_mc // then // prepare 16 bit argument: // :Hi8 = $200:1 ( -- ) ld swap,cmd_lo next_mc :BraFar % $100 ( -- ) // after Hi8 ld dtmp,alu, ip.oe, ip.clk, adddis // ld dtmp,alu + ld ip,ip+dis ld alu,ip add swap ld ip,alu ld alu,dtmp next_mc // -------------------------------------------------------- // conditional millicode execution: // //If := BraIf0+1 ( i1 -- ) // execute next millicode if top != 0 //If2 := BraIf0+2 ( i1 -- ) // execute next 2 millicodes if top != 0 //If3 := BraIf0+3 ( i1 -- ) // execute next 3 millicodes if top != 0 // //Ifnot := BraIf1+1 ( i1 -- ) // execute next millicode if top == 0 //Ifnot2 := BraIf1+2 ( i1 -- ) // execute next 2 millicodes if top == 0 //Ifnot3 := BraIf1+3 ( i1 -- ) // execute next 3 millicodes if top == 0 // -------------------------------------------------------- // jump via table // cmd_lo = table size // // mc SwitchFar+n // mc Jp[0],Jp[1], .. Jp[n-1], Jp[default] // :SwitchFar = $A00:0 ( i8 -- ) cmp cmd_lo // idx - tbl_size add alu :cy // alu=i8*2 = offset in table *nodelay* if 1 // cy => !cy => idx ? tbl_size => out of table ld ip,ip+dis ld ip,ip+dis // ip += dis*2 => ip -> next millicode after tab pop alu next_mc else add ip // alu = ip+i8*2 ld ip,alu // ip = ip+i8*2 -> Jp pop alu next_mc then // -------------------------------------------------------- // branch via table // cmd_lo = table size // // mc Switch+n // mc Bra[0],Bra[1], .. Bra[n-1], Bra[default] :Switch = $900:0 ( i8 -- ) cmp cmd_lo // idx - tbl_size ld dtmp,ip+=dis :cy // ip -> next millicode after tab if 1 // cy => !cy => idx ? tbl_size => out of table pop alu next_mc else add dtmp ld ip,alu pop alu next_mc then // -------------------------------------------------------- // For all items... // // ForAllItems // Bra L_end // L_loop: ... // ... // L_end: mmNextItem // Bra L_loop // // :ForAllItems ( T[]˘ -- ) // rstack:( -- T[]˘ a_idx e_idx ) // opcode bra.dest follows ld d2ar,alu // d2ar = alu = handle -> memptr ld d2ar,(d2ar) : z // d2ar = memptr -> data.size if 0 ld d0,(d2ar) // d0 = data.size else ld d0,alu // d0 = data.size = 0 then pshr alu,0,d0 // pushr T[]˘, a_idx, e_idx dtmp pop alu next_mc :ForRange ( T[]˘ a_idx e_idx -- ) // rstack:( -- T[]˘ a_idx e_idx ) // opcode bra.dest follows pop d0,d1 pshr d1,d0,alu pop alu next_mc :mmNextItem ( -- ) // loop: vstack:( -- T* ) rstack:( T[]˘ a_idx e_idx -- T[]˘ a_idx e_idx ) // exit: vstack:( -- ) rstack:( T[]˘ a_idx e_idx -- ) // opcode bra.dest follows push alu popr alu,d0 // alu=e_idx, d0=a_idx cmp d0 // todo: nodelay if !z ld d2ar,(sp) // d2ar = T[]˘ = handle -> memptr dec alu // alu = --e_idx atmp pshr d0,alu add_c (d2ar) // alu -> data.data+e_idx next_mc // => bra else popr dtmp // rdrop T[]˘ pop alu // alu := top inc ip // skip bra next_mc // => exit loop then /* :mmNextItem48 ( -- ) // loop: vstack:( -- float* ) rstack:( float[]˘ a_idx e_idx -- float[]˘ a_idx e_idx ) // exit: vstack:( -- ) rstack:( float[]˘ a_idx e_idx -- ) // opcode bra.dest follows push alu popr alu,d0 // alu=e_idx, d0=a_idx cmp d0 // todo: nodelay if !z ld d2ar,(sp) // d2ar = T[]˘ = handle -> memptr sub 3 // alu = --e_idx dtmp pshr d0,alu add_c (d2ar) // alu -> data.data+e_idx next_mc // => bra else popr dtmp // rdrop T[]˘ pop alu // alu := top incr ip // skip bra next_mc // => exit loop then */ /* :NextItempp ( -- ) // loop: vstack:( -- T* ) rstack:( T[]˘ a_idx e_idx -- T[]˘ a_idx e_idx ) // exit: vstack:( -- ) rstack:( T[]˘ a_idx e_idx -- ) // opcode bra.dest follows push alu popr d0,alu // d0=e_idx, alu=a_idx cmp d0 if !z ld d2ar,(sp) // d2ar = T[]˘ = handle -> memptr ld atmp,alu inc atmp pshr atmp,d0 // dtmp add_c (d2ar) // alu -> data.data+a_idx next_mc // => bra else popr dtmp // rdrop T[]˘ pop alu // alu := top incr ip // skip bra next_mc // => exit loop then */ // ======================================== // Stack Basics // ======================================== :SwapWithVar ( int:Q int&:Z -- int:Z ) // swap data Q with contents of variable Z ld atmp,alu // atmp -> var Z ld alu,(atmp) // alu = Z pop (atmp) // var Z = Q dtmp next_mc :SwapWithVar2 ( long:Q long&:Z -- long:Z ) // swap data Q with contents of variable Z ld atmp,alu // atmp -> var Z.h ld d1,(atmp++) // d1 = Z.h ld alu,(atmp) // alu = Z.l pop dtmp // dtmp = Q.l ld (atmp--),dtmp // var Z.l = Q.l ld dtmp,(hp) // dtmp = Q.h ld (atmp),dtmp // var Z.h = Q.h ld (hp),d1 // RVAL.h = Z.h // ld alu,alu // RVAL.l = Z.l next_mc :SwapWithVar3 ( float:Q float&:Z -- float:Z ) // swap data Q with contents of variable Z ld atmp,alu // atmp -> var Z2 ld d2,(atmp++) // d2 = Z2 ld d1,(atmp++) // d1 = Z1 ld alu,(atmp) // alu = Z0 pop dtmp // dtmp = Q0 ld (atmp--),dtmp // var Z0 = Q0 pop dtmp // dtmp = Q1 ld (atmp--),dtmp // var Z1 = Q1 ld dtmp,(hp) // dtmp = Q2 ld (atmp),dtmp // var Z2 = Q2 ld (hp++),d2 // RVAL2 = Z2 ld (hp),d1 // RVAL1 = Z1 // ld alu,alu // RVAL0 = Z0 next_mc :Poke3 ( exp mant_h mant_l float* -- ) ld atmp,alu pop alu,d0,dtmp ld (atmp++),dtmp ld (atmp++),d0 ld (atmp),alu pop alu next_mc :Poke2 ( int int long* -- ) ld atmp,alu pop alu,dtmp // alu=lo, dtmp=hi ld (atmp++),dtmp ld (atmp),alu pop alu next_mc :Poke ( int int* -- ) ld atmp,alu pop dtmp ld (atmp),dtmp pop alu next_mc :Peek3 ( float* -- exp mant_h mant_l ) ld atmp,alu psh (atmp++) // dtmp psh (atmp++) // dtmp ld alu,(atmp) next_mc :Peek2 ( long* -- int_h int_l ) ld atmp,alu psh (atmp++) // dtmp ld alu,(atmp) next_mc :Peek ( int* -- int ) ld atmp,alu ld alu,(atmp) next_mc :Peek_Clear ( T& -- T ) // peek and clear var ld atmp,alu ld alu,(atmp) ld (atmp),0 next_mc // swap top and 2nd on top value: // :Swap ( a b -- b a ) ld dtmp,(hp) ld (hp),alu ld alu,dtmp next_mc //:Over( a b -- a b a ) // ld dtmp,(hp++) // ld (hp),alu // ld alu,dtmp // next_mc :Dup2( a b -- a b a b ) // *not* MDup2 !! ld dtmp,(hp++) // dtmp = a ld (hp++),alu ld (hp),dtmp next_mc // multi-Dup: // mc MDup0-i3 -> dup top word i3 times // if 0 MDup8: inc hp :1 inc hp :1 inc hp :1 inc hp :1 inc hp :1 inc hp :1 inc hp :1 inc hp :1 MDup0: nop else nop ld (hp++),alu ld (hp++),alu ld (hp++),alu ld (hp++),alu ld (hp++),alu ld (hp++),alu ld (hp++),alu ld (hp),alu then next_mc // multi-Drop: // mc MDrop0-i3 -> drop i3 words // :MDrop8 ( x x x x x x x x -- ) pop alu pop alu pop alu pop alu pop alu pop alu pop alu pop alu MDrop0: next_mc :Drop8_Next ( x x x x x x x x -- ) pop alu pop alu pop alu pop alu pop alu pop alu pop alu pop alu MDrop0_Next: popr ip // dtmp next_mc // multi-Drop: // mc MNip0-i3 -> nip i3 words over int16 // :MNip8 ( x x x x x x x x a -- a ) dec hp dec hp dec hp dec hp dec hp dec hp dec hp dec hp MNip0: next_mc :MNip8_Next ( x x x x x x x x a -- a ) dec hp dec hp dec hp dec hp dec hp dec hp dec hp dec hp MNip0_Next: popr ip // dtmp next_mc Nip := MNip0-1 ( a b -- b ) Dup := MDup0-1 ( int -- int int ) Drop := MDrop0-1 ( x -- ) Drop2 := MDrop0-2 ( x x -- ) Drop3 := MDrop0-3 ( x x x -- ) Drop_Next := MDrop0_Next-1 ( x -- ) Drop2_Next := MDrop0_Next-2 ( x x -- ) Drop3_Next := MDrop0_Next-3 ( x x x -- ) // ======================================== // R-Stack: // ======================================== :ToR3 ( int int int -- ) pshr alu pop alu ToR2: ( int int -- ) pshr alu pop alu ToR: ( int -- ) pshr alu pop alu next_mc :DupToR ( int -- int ) pshr alu next_mc :PeekR ( -- int ) psh alu ld alu,(sp) next_mc :DropR ( -- ) inc sp next_mc :FromR3 ( -- int int int ) psh alu popr alu FromR2: ( -- int int ) psh alu popr alu FromR: ( -- int ) psh alu popr alu next_mc // ======================================== // Data Access // ======================================== // get address of global variable at 0+dis: // Gvar := Int8 ( -- i16& ) // store value into global variable at 0+dis: // :Gset % $100 ( i16 -- ) ld atmp,cmd_lo ld (atmp),alu pop alu next_mc // read value from global variable at 0+dis: // :Gget % $100 ( -- i16 ) ld d2ar,cmd_lo // note: d2ar => merges with ++hp psh alu ld alu,(d2ar) next_mc // get address of local variable at HP-256+dis: // can't be used for HP[0] => use PshHP instead // :Lvar % $100 ( -- T& ) psh alu ld atmp,hp-dis ld alu,atmp next_mc // read value from local variable at HP-256+dis: // can't be used for HP[0] => use Dup instead // :Lget % $100 ( -- i16 ) psh alu ld atmp,hp-dis ld alu,(atmp) next_mc // store value into local variable at HP-256+dis: // can't be used for HP[0] => use Nip instead // :Lset % $100 ( i16 -- ) ld atmp,hp-dis ld (atmp),alu pop alu next_mc // get address of outer local variable context 0: // :XLvar % $100 ( -- i16* ) psh alu ld atmp,context0 ld d2ar,(atmp) ld atmp,d2ar+dis ld alu,atmp next_mc :PushContext0 ( -- ) ld atmp,context0 pshr (atmp) // dtmp ld dtmp,alu ld alu,-126 add hp ld (atmp),alu ld alu,dtmp next_mc :PopContext0 ( -- ) ld atmp,context0 popr (atmp) // dtmp next_mc // get address of outer local variable context 1: // :XXLvar % $100 ( -- i16* ) psh alu ld atmp,context1 ld d2ar,(atmp) ld atmp,d2ar+dis ld alu,atmp next_mc :PushContext1 ( -- ) ld atmp,context1 pshr (atmp) // dtmp ld dtmp,alu ld alu,-126 add hp ld (atmp),alu ld alu,dtmp next_mc :PopContext1 ( -- ) ld atmp,context1 popr (atmp) // dtmp next_mc // get address of struct item at offset dis // :Item % $100 ( T{}˘ -- T& ) ld atmp,alu // atmp = handle ld d2ar,(atmp) // d2ar = ptr -> data.len ld atmp,d2ar+dis // atmp -> item-1 inc atmp // atmp -> item ld alu,atmp next_mc // read value from struct item at offset dis // :ItemGet % $100 ( T{}˘ -- i16 ) ld atmp,alu // atmp = handle ld d2ar,(atmp) // d2ar = ptr -> data.len ld atmp,d2ar+dis // atmp -> item-1 inc atmp // atmp -> item ld alu,(atmp) next_mc // store value into struct item at offset dis // :ItemSet % $100 ( i16 T{}˘ -- ) ld atmp,alu // atmp = handle ld d2ar,(atmp) // d2ar = ptr -> data.len ld atmp,d2ar+dis // atmp -> item-1 inc atmp // atmp -> item pop (atmp),alu // dtmp next_mc :Last ( int[]˘ -- int& ) psh alu if !z ld d2ar,alu // d2ar=alu=handle ld d2ar,(d2ar) // d2ar=ptr tst (d2ar) ld dtmp,(d2ar) // dtmp=len if !z orn alu // alu = alu | !alu = 0xffff add (d2ar) jp AtIndex then then pop alu next_mc :AtIndex0 ( int[]˘ -- int& ) psh alu xor alu // jp AtIndex AtIndex: ( int[]˘ idx -- int& ) pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] next_mc :AtIndex2 ( long[]˘ idx -- long& ) add alu // offset = index*2 nodelay pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] next_mc :AtIndex3 ( float[]˘ idx -- float& ) ld dtmp,alu add alu // nodelay add dtmp // offset = index*3 pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] next_mc :AtIndexPeek ( int[]˘ idx -- int ) pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] ld d2ar,alu ld alu,(d2ar) // value next_mc :AtIndexPeek2 ( long[]˘ idx -- long ) add alu // offset = index*2 nodelay pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] ld atmp,alu push (atmp++) // dtmp ld alu,(atmp) next_mc :AtIndexPeek3 ( float[]˘ idx -- float ) ld dtmp,alu add alu // nodelay add dtmp // offset = index*3 pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] ld atmp,alu push (atmp++),(atmp++) // dtmp ld alu,(atmp) next_mc :AtIndexPoke ( int int[]˘ idx -- ) pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] ld d2ar,alu pop (d2ar),alu // store value *dtmp* next_mc :AtIndexPoke3 ( float float[]˘ idx -- ) ld dtmp,alu add alu // nodelay add dtmp // offset = index*3 pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] ld atmp,alu // atmp -> bu[idx] pop d2,d1,d0,alu ld (atmp++),d0 ld (atmp++),d1 ld (atmp++),d2 next_mc SwapVar3: ( float& float& -- ) ld atmp,alu pop a0 // dtmp sw3 ld alu,(a0) :1 if 1 ld (a0++),(atmp) // dtmp ld (atmp++),alu sw2 ld alu,(a0) ld (a0++),(atmp) // dtmp ld (atmp++),alu sw1 ld alu,(a0) ld (a0++),(atmp) // dtmp ld (atmp++),alu pop alu next_mc else SwapVar2: ( long& long& -- ) ld atmp,alu pop a0 :1 // dtmp nop SwapVar: ( int& int& -- ) ld atmp,alu pop a0 :1 // dtmp then // ======================================== // Registers: // ======================================== :PshHP ( -- a16 ) psh alu ld alu,hp next_mc :PopHP ( a16 -- ) ld hp,alu pop alu next_mc :PshSP ( -- a16 ) psh alu ld alu,sp next_mc :PopSP ( a16 -- ) ld sp,alu pop alu next_mc //:PshD0 ( -- i16 ) // psh alu // ld alu,d0 // next_mc //:PshD1 ( -- i16 ) // psh alu // ld alu,d1 // next_mc //:PshD2 ( -- i16 ) // psh alu // ld alu,d2 // next_mc //:PopD0 ( i16 -- ) // ld d0,alu // pop alu // next_mc //:PopD1 ( i16 -- ) // ld d1,alu // pop alu // next_mc //:PopD2 ( i16 -- ) // ld d2,alu // pop alu // next_mc //:PshA0 ( -- a16 ) // psh alu // ld alu,a0 // next_mc //:PshA1 ( -- a16 ) // psh alu // ld alu,a1 // next_mc //:PopA0 ( a16 -- ) // ld a0,alu // pop alu // next_mc //:PopA1 ( a16 -- ) // ld a1,alu // pop alu // next_mc //:PokeA0pp ( i16 -- ) // ld (a0++),alu // pop alu // next_mc //:PokeA1pp ( i16 -- ) // ld (a1++),alu // pop alu // next_mc //:PeekA0pp ( -- i16 ) // psh alu // ld alu,(a0++) // next_mc //:PeekA1pp ( -- i16 ) // psh alu // ld alu,(a1++) // next_mc //:PeekA0 ( -- i16 ) // psh alu // ld alu,(a0) // next_mc //:PeekA1 ( -- i16 ) // psh alu // ld alu,(a1) // next_mc //:IncA0 ( -- ) // inc a0 // next_mc //:DecA0 ( -- ) // dec a0 // next_mc //:IncA1 ( -- ) // inc a1 // next_mc //:DecA1 ( -- ) // dec a1 // next_mc // ======================================== // Misc. Functions // ======================================== // General Short Delay n+2 µs: // num_opcodes/µs = 1e-6 * 16e6 = 16 ( 1µs @ 16MHz ) // 0 ~ 2 µs // // Ival|delay // 6 // :BusyWait ( i16:µs -- ) ld atmp,alu // 1 do clr clock4 // 1..4 + n*4 1:4 tst atmp-- // 4 + n*4 until z // 8 + n*8 set clock4 // 4 1:1 pop alu // 1 next_mc // 3 :SetIntMask ( -- ) ld io_ie_mask,(int_mask) // atmp next_mc :Select ( i16:sel_mask -- ) // DI and select device ld io_select,alu pop alu Di: di next_mc :Deselect ( -- ) ld io_select,$FFFF Ei: ei next_mc // LEDs on SSW: // :SetLedRed() set led_red next_mc :ClrLedRed() clr led_red next_mc :SetLedYel() set led_yel next_mc :ClrLedYel() clr led_yel next_mc :SetLedGrn() set led_grn next_mc :ClrLedGrn() clr led_grn next_mc /* :SetLeds ( i3:ryg -- ) ld sr,alu,nc pop alu :bit0 if 0 ld sr,sr,nc clr led_red :bit0 else ld sr,sr,nc set led_red :bit0 then // cond if 0 ld sr,sr,nc clr led_yel :bit0 else ld sr,sr,nc set led_yel :bit0 then // cond if 0 clr led_grn else set led_grn then next_mc */ // ======================================================= // Logging // ======================================================= :LogChar ( char -- ) // put char (cpu emulator) logchar alu ld io,alu,d_bits=4 // * logchar pop alu next_mc :LogNum ( i16 -- ) // put number (cpu emulator) lognum alu ld io,alu,d_bits=5 // * lognum pop alu next_mc :LogCstr ( str˘ -- ) ld a0,alu ld a1,(a0) // dtmp ld atmp,(a1++) // dtmp jp psc do logchar (a1++) ld io,(a1++),d_bits=4 // * logchar psc tst atmp-- until z pop alu next_mc :LogStr ( str -- ) ld a0,alu ld a1,(a0) // dtmp ld atmp,(a1++) // dtmp jp psa do logchar (a1++) ld io,(a1++),d_bits=4 // * logchar psa tst atmp-- until z jp DropStr :LogCC ( -- ) log_cc ld io,alu,d_bits=9 // * log_cc next_mc :LogRegisters ( -- ) log_registers ld io,alu,d_bits=8 // * log_registers next_mc :LogMem ( -- ) logmem ld io,alu,d_bits=12 // * logmem next_mc :LogHP ( -- ) logchar '<' ld io,'<',d_bits=4 // * logchar logchar 'H' ld io,'H',d_bits=4 // * logchar logchar 'P' ld io,'P',d_bits=4 // * logchar logchar '=' ld io,'=',d_bits=4 // * logchar lognum hp ld io,hp,d_bits=5 // * lognum logchar '>' ld io,'>',d_bits=4 // * logchar next_mc :Trace ( -- ) trace 2 ld io,2,d_bits=15 // * trace next_mc :Tron ( -- ) trace 1 ld io,1,d_bits=15 // * trace next_mc :Troff ( -- ) trace 0 ld io,0,d_bits=15 // * trace next_mc // --- file: "millicode.asm" --- #include "asm/millicode_int.asm" // +++ file: "millicode_int.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // Microcode for the K1-16/16 CPU // // 2012-04-08 op__GT__5int16_5int16_5int16 := Gt ( i16:a i16:b -- i1 ) // für sort() op__LT__5int16_5int16_5int16 := Lt ( i16:a i16:b -- i1 ) // für sort() op__GT__6uint16_6uint16_5int16 := Ugt ( i16:a i16:b -- i1 ) // für sort() op__LT__6uint16_6uint16_5int16 := Ult ( i16:a i16:b -- i1 ) // für sort() // util: :DupToRPeekSwap ( int int* -- int int ) // UP pshr alu ld a0,alu ld alu,(hp) ld (hp),(a0) // dtmp next_mc :FromRPokeNext ( int -- ) // UP popr a0,ip // dtmp ld (a0),alu pop alu next_mc // ======================================================= // Immediate Values: // ======================================================= // add immediate value quick: // :Addq = $B00:0 ( i16 -- i16 ) add cmd_lo next_mc // subtract immediate value quick: // :Subq = $C00:0 ( i16 -- i16 ) sub cmd_lo next_mc // push immediate value 0..255 // :Int8 = $D00:0 ( -- i8 ) psh alu ld alu,cmd_lo next_mc // extend int8 to int16 // Ival nn = mc Int8+nn.lo, Int16+nn.hi // :Int16 = $E00:0 ( i8 -- i16 ) ld swap,cmd_lo or swap next_mc Inc := Addq+1 ( i16 -- i16 ) Dec := Subq+1 ( i16 -- i16 ) // ======================================================= // Arithmetics: // ======================================================= :Max ( i16:a i16:b -- i16 ) pop dtmp // dtmp=a sub dtmp // b-a if !ovfl // !ovfl: signed result b-a is valid tst alu // b-a if bit15 // b-a?0 => a?b ld alu,dtmp else add dtmp then next_mc else // ovfl: implies: sign(a) != sign(b) tst dtmp // a if bit15 // a<0 => b?0 => b?a add dtmp else ld alu,dtmp then next_mc then :Min ( i16:a i16:b -- i16 ) pop dtmp // dtmp=a sub dtmp // b-a if !ovfl // !ovfl: signed result b-a is valid tst alu // b-a if bit15 // b-a?0 => a?b add dtmp else ld alu,dtmp then next_mc else // ovfl: implies: sign(a) != sign(b) tst dtmp // a if bit15 // a<0 => b?0 => b?a ld alu,dtmp else add dtmp then next_mc then :Abs ( i16 -- u16 ) tst alu if bit15 neg // atmp next_mc else next_mc then :Sign ( i16 -- i16 ) tst alu if z next_mc else tst alu ld alu,ival : bit15 if 1 dw $ffff else dw $0001 then next_mc then :Cpl ( i16 -- i16 ) cpl next_mc :DropNeg ( i16:a i16:b -- i16:-a ) // -a = 0-a = 1-1-a = -1-(a-1) = ~(a-1) pop d2ar ld atmp,d2ar-1 ldn atmp next_mc :NipNeg ( i16:a i16:b -- i16:-b ) dec hp // nip // jp Neg Neg: ( i16 -- i16 ) neg // atmp next_mc :Not ( i16 -- i16 ) tst alu xor alu :z if 1 add_c alu // z => 1 nodelay then // nz => 0 next_mc :Bool ( i16 -- i16 ) tst alu xor alu :z if 0 add_c alu // nz => 1 nodelay then // z => 0 next_mc :Msbit0 ( i16 -- i4 ) ld msbit,alu ld alu,msbit next_mc :Msbit ( i16 -- i4 ) ldn alu ld msbit,alu ld alu,msbit next_mc :Bit0 ( i16 -- i1 ) and 1 next_mc :Add ( i16 i16 -- i16 ) add (hp--) next_mc :Sub( i16 i16 -- i16 ) sub_nc (hp--) cpl next_mc :And ( i16 i16 -- i16 ) and (hp--) next_mc :Or ( i16 i16 -- i16 ) or (hp--) next_mc :Xor ( i16 i16 -- i16 ) xor (hp--) next_mc :Eq( i16 i16 -- i1 ) equ (hp) // delay equ (hp--) xor alu :z if 1 add_c alu // z => 1 nodelay then next_mc :Ne( i16 i16 -- i1 ) equ (hp) // delay equ (hp--) xor alu :z if 0 add_c alu // z => 1 nodelay then next_mc :Peekpp( i16& -- i16 ) // peek and increment variable ld d2ar,alu ld alu,(d2ar) ld atmp,alu inc atmp ld (d2ar),atmp // dtmp next_mc :Peekmm( i16& -- i16 ) ld d2ar,alu ld alu,(d2ar) ld atmp,alu dec atmp ld (d2ar),atmp // dtmp next_mc :ppPeek( i16& -- i16 ) // increment and peek variable ld d2ar,alu ld alu,(d2ar) inc alu // atmp ld (d2ar),alu next_mc :mmPeek( i16& -- i16 ) ld d2ar,alu ld alu,(d2ar) dec alu // atmp ld (d2ar),alu next_mc :Incr ( i16& -- ) ld d2ar,alu ld alu,(d2ar) inc alu // atmp ld (d2ar),alu pop alu next_mc :Decr ( i16& -- ) ld d2ar,alu ld alu,(d2ar) dec alu // atmp ld (d2ar),alu pop alu next_mc :AddPoke ( int int& -- ) ld atmp,alu ld alu,(atmp) add (hp--) ld (atmp),alu pop alu next_mc :SubPoke ( int int& -- ) ld atmp,alu ld alu,(atmp) sub (hp--) ld (atmp),alu pop alu next_mc :AndPoke ( int int& -- ) ld atmp,alu ld alu,(atmp) and (hp--) ld (atmp),alu pop alu next_mc :OrPoke ( int int& -- ) ld atmp,alu ld alu,(atmp) or (hp--) ld (atmp),alu pop alu next_mc :XorPoke ( int int& -- ) ld atmp,alu ld alu,(atmp) xor (hp--) ld (atmp),alu pop alu next_mc //:Add_p3_n ( float* int -- float* ) // ld dtmp,alu // add alu // nodelay // add dtmp // add (hp--) // next_mc //:Add_p2_n ( long* int -- long* ) // add alu // nodelay // add (hp--) // next_mc // ======================================================= // Signed Arithmetics: // ======================================================= :SignedCompares if 1 Gt: ( i16:a i16:b -- i1 ) // signed greater than ld dtmp,(hp--) ogt: sub dtmp // b-a else Ge: ( i16:a i16:a -- i1 ) // signed greater or equal ld dtmp,(hp--) oge: sub_nc dtmp // b-a-1 then if !ovfl // !ovfl: signed result b-a is valid tst alu // b-a xor alu :bit15 if 1 // b-a<0 => b (a>b) = true add_c alu // => 1 nodelay then next_mc else // ovfl: implies: sign(a) != sign(b) tst dtmp // a xor alu :bit15 if 0 // a?0 => b<0 => (a>b) = true add_c alu // => 1 nodelay then next_mc then if 1 Lt: ( i16:a i16:b -- i1 ) // signed less than ld dtmp,(hp--) olt: sub_nc dtmp // b-a-1 else Le: ( i16:a i16:a -- i1 ) // signed less or equal ld dtmp,(hp--) ole: sub dtmp // b-a then if !ovfl // !ovfl: signed result b-a is valid tst alu // b-a xor alu :bit15 if 0 // b-a?0 => b?a => (a?b) = true add_c alu // => 1 nodelay then next_mc else // ovfl: implies: sign(a) != sign(b) tst dtmp // a xor alu :bit15 if 1 // a<0 => b?0 => (a?b) = true add_c alu // => 1 nodelay then next_mc then // signed multiplication // Mul: ( i16 i16 -- i16 ) // signed multiplication pop d0 // result pos or neg? xor d0 // alu.bit15 = result.sign tst alu xor d0 :bit15 // test result.sign if 1 ld a0,Neg // resut<0: return to neg else ld a0,next_mc // result?0: return to next millicode then mul_d0: // alu neg? ld atmp,alu dec atmp :bit15 if 1 // note: ~a = -1-a ldn atmp // alu = ~(atmp) = -1-(atmp) = -1-(alu-1) = -alu then // d0 neg? ld atmp,d0 dec atmp :bit15 jp 0,mulu_d0 // d0 pos. ld d0,alu ldn atmp jp mulu_d0 // signed division // :Div ( i16:Q i16:D -- i16 ) // signed division ld d0,(hp) // result pos or neg? xor d0 // alu.bit15 = result.sign tst alu xor d0 :bit15 // test result.sign if 1 ld a0,DropNeg // result<0: return to Drop + Neg else ld a0,Drop then div_d0: // alu neg? ld atmp,alu dec atmp :bit15 if 1 // note: -a = ~(a-1) ldn atmp // D = -D then // d0 neg? ld atmp,d0 dec atmp :bit15 jp 0,divu // d0 pos. ld dtmp,alu ldn atmp ld (hp),alu // Q = -Q ld alu,dtmp jp divu // Q = Q/D*D + Q%D // Q%D = Q - Q/D*D => sign(D) irrelevant, sign(Q%D) = sign(Q) ! // :Rem ( i16:Q i16:D -- i16:R ) // signed division remainder // D neg? ld atmp,alu dec atmp :bit15 if 1 // note: -a = ~(a-1) ldn atmp // D = -D then // Q neg? => result neg? ld d0,(hp) ld a0,ival :bit15 if 0 dw Nip // Q?0 => result?0 jp divu else dw NipNeg // Q<0 => result<0: return to neg ld dtmp,alu ld atmp,d0 dec atmp ldn atmp ld (hp),alu // Q = -Q ld alu,dtmp jp divu then :MulPoke ( int int& -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap,Mul,FromRPokeNext :DivPoke ( int int& -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap,Div,FromRPokeNext :RemPoke ( int int& -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap,Rem,FromRPokeNext // ======================================================= // Unsigned Arithmetics: // ======================================================= :UnsignedCompares if 1 Ugt: ( u16:a u16:b -- i1 ) cmp (hp--) // b-a xor alu :cy else Uge: ( u16:a u16:b -- i1 ) cmp_nc (hp--) // b-a-1 xor alu :cy then if 0 // !cy => cy => a>b | a?b add_c alu // => 1 nodelay then next_mc if 1 Ule: ( u16:a u16:b -- i1 ) // unsigned less or equal cmp (hp--) // b-a xor alu :cy else Ult: ( u16:a u16:b -- i1 ) // unsigned less than cmp_nc (hp--) // b-a-1 xor alu :cy then if 1 // cy => !cy => b?a | b>a add_c alu // => 1 nodelay then next_mc :Umax ( u16 u16 -- u16 ) cmp (hp) pop dtmp :cy if 1 // cy => !cy => alu?(hp) next_mc else ld alu,dtmp next_mc then :Umin ( u16 u16 -- u16 ) cmp (hp) pop dtmp :cy if 1 // cy => !cy => alu?(hp) ld alu,dtmp next_mc else next_mc then :Log10 ( uint -- uint ) // 0 .. 4 // return x<100 ? x<10?1:2 : x<10000 ? x<1000?3:4 : 5 cmp 100 // dtmp if !cy cmp 10 // dtmp ld alu,ival :cy if 0 dw 0 else dw 1 then next_mc else cmp 10000 // dtmp if cy ld alu,4 next_mc else cmp 1000 // dtmp ld alu,ival :cy if 0 dw 2 else dw 3 then next_mc then then //:Mul10 ( uint -- uint ) // ld sl,alu,nc // sl=alu*2 // ld sl,sl,nc // sl=alu*4 // add sl // alu=alu*5 // add alu // alu=alu*10 nodelay // next_mc //:Exp10 ( uint -- uint ) // 0 .. 4 // //// return x<2 ? x?10:1 : x<4 ? x<3?100:1000 : 10000 // // cmp 5 // dtmp // if !cy // !cy => cy => x<5 // add tab // dtmp // ld cmd,alu // ld alu,ival :bit15 //tab dm 1,10,100,1000,10000 // else // xor alu // then // next_mc // ======================================== // unsigned multiplication and division // ======================================== :Mulu0 ( int -- int:0 ) xor alu next_mc :Mulu5 ( int -- int ) ld sl,alu,nc ld sl,sl,nc add sl next_mc Mulu1 := Nop ( int -- int ) Mulu2 := Sli0-1 ( int -- int ) Mulu4 := Sli0-2 ( int -- int ) Mulu8 := Sli0-3 ( int -- int ) :Mulu6 ( int -- int ) add alu // nodelay Mulu3: ( int -- int ) ld sl,alu,nc add sl next_mc :Mulu7 ( int -- int ) ld sl,alu,nc add sl ld sl,sl,nc add sl next_mc // --------------------- :unsigned_multiplication if 1 MULU: ( u16 u16 -- u16 ) // unsigned multiplication ld a0,NEXT // a0 = return address else Mulu: ( u16 u16 -- u16 ) // unsigned multiplication ld a0,next_mc // a0 = return address then mulu: pop d0 mulu_d0:ld d1,alu cmp d0 if !cy // !cy => cy => d1-d0<0 => d1 swap ld d1,d0 ld d0,alu then // d0 ? d1 // d0?255 else overflow! ld sr,d0,nc // sr = d0>>1 = shift bits (should be max 8) ld sl,d1,nc :bit0 // sl = d1<<1 = add value if 1 ld alu,d1 // add value for bit0 else xor alu then ld sr,sr,nc nop :bit0 if 1 add sl // add value for bit1 then do ld sr,sr,nc ld sl,sl,nc : bit0 if 1 add sl // add value for bit2 (5) then ld sr,sr,nc ld sl,sl,nc : bit0 if 1 add sl // add value for bit3 (6) then ld sr,sr,nc ld sl,sl,nc : bit0 if 1 add sl // add value for bit4 (7) then tst sr while !z jp a0 // --------------- :unsigned_division if 1 DIVU: ( u16:x u16:y -- u16:r ) // r = x/y ld a0,DROP else Divu: ( u16:x u16:y -- u16:q ) // q = x/y ld a0,Drop then divu: ( u16:Q u16:D -- u16:q u16:r ) // q = Q/D r = Q%D return via a0 // test ob im Divisor bit15 gesetzt ist: // dann kann der remainder nämlich einen Überlauf in bit16 haben // (dieser Test ist bei signed Div nicht nötig) ld d0,alu // d0 = divisor D if bit15 ld alu,(hp) // alu=Q cmp d0 // Q?D ? if cy // cy => !cy => Q?D sub d0 ld (hp),1 jp a0 else ld (hp),0 jp a0 then then // ld d0,alu // d0 = divisor D xor alu // alu = remainder ld sr,(hp),nc // sl = divident Q / result q if bit0 ld sl,sr,cy else ld sl,sr,nc then ld atmp,16 // atmp = loop counter do ld dtmp,alu // for undo sub d0 // try subtraction if cy // cy => !cy => d0 fits in alu => keep it & result bit = 1 ld sl,sl,cy // quotient << 1 + 1 nop :bit15 add_c alu // remainder << 1 nodelay else // d0 did not fit in alu => restore alu & result bit = 0 ld sl,sl,nc // quotient << 1 + 0 ld alu,dtmp :bit15 // undo sub add alu // remainder << 1 nodelay then tst atmp-- while !z // now: d0=divisor, alu=remainder, sl=quotient ld sr,alu,nc ld alu,sr ld (hp),sl jp a0 // post ld d0,alu // d0 = divisor ld sl,(hp),nc // alu+sl = 32 bit divident, result is shifted into sl xor alu : bit15 if 0 // alu+sl <<= 1 add alu // nodelay else add_c alu // nodelay then ld a1,15 do ld dtmp,alu // for undo sub d0 // try subtraction nop : cy if 1 // cy => !cy => d0 fits in alu => keep it & result bit = 1 ld sl,sl,cy // shift left alu+sl and shift 1 into result nop : bit15 add alu // nodelay else // d0 did not fit in alu => restore alu & result bit = 0 ld sl,sl,nc // shift left alu+sl and shift 0 into result ld alu,dtmp : bit15 // undo sub add_c alu // nodelay then tst a1-- while !z // now: d0=divisor, alu=remainder, sl=quotient ld (hp),sl jp a0 // post // ------------------ // unsigned remainder // :Remu ( u16:x u16:y -- u16:r ) // r = x%y ld a0,Nip jp divu :MuluPoke ( int int& -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap mc Mulu mc FromRPokeNext :DivuPoke ( int int& -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap mc Divu mc FromRPokeNext :RemuPoke ( int int& -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap mc Remu mc FromRPokeNext // ======================================== // mixed signedness // ======================================== :Lt_iu ( i16 u16 -- bool ) tst alu pop dtmp : bit15 jp 0,olt ld alu,1 next_mc :Ge_iu ( i16 u16 -- bool ) tst alu pop dtmp : bit15 jp 0,oge xorn alu next_mc // ======================================== // shift left and shift right // ======================================== //:Srs1 ( i16 -- i16 ) // shift right signed once // tst alu // if bit15 // ld sr,alu,cy // else // ld sr,alu,nc // then // ld alu,sr // next_mc :Sl ( i16:a i4:n -- i16 ) // calculated shift: a = a<>n with 0<=n<=15 and $000F cpl // -1-n -1..-16 add srutab+1 // srtab+1-1-n = srtab-n dtmp ld cmd,alu // jp srtab-n pop alu :bit15 // a if 1 Sru15: ( u16 -- u16 ) // fixed shift right: a = a>>n with 0<=n<=15 ld sr,alu,nc :0 // a>>15 ld sr,alu,nc :0 // a>>14 ld sr,alu,nc :0 // a>>13 ld sr,alu,nc :0 // a>>12 ld sr,alu,nc :0 // a>>11 ld sr,alu,nc :0 // a>>10 ld sr,alu,nc :0 // a>>9 ld sr,alu,nc :0 // a>>8 ld sr,alu,nc :0 // a>>7 ld sr,alu,nc :0 // a>>6 ld sr,alu,nc :0 // a>>5 ld sr,alu,nc :0 // a>>4 ld sr,alu,nc :0 // a>>3 ld sr,alu,nc :0 // a>>2 ld sr,alu,nc :0 // a>>1 srutab next_mc // a>>0 else nop // a>>15 ld sr,sr , nc // a>>14 ld sr,sr , nc // a>>13 ld sr,sr , nc // a>>12 ld sr,sr , nc // a>>11 ld sr,sr , nc // a>>10 ld sr,sr , nc // a>>9 ld sr,sr , nc // a>>8 ld sr,sr , nc // a>>7 ld sr,sr , nc // a>>6 ld sr,sr , nc // a>>5 ld sr,sr , nc // a>>4 ld sr,sr , nc // a>>3 ld sr,sr , nc // a>>2 ld sr,sr , nc // a>>1 ld alu,sr // a>>0 next_mc then Sru0: = srutab ( int -- int ) // fixed shift right Sru1: = srutab-1 ( int -- int ) // single shift right :SrsPoke ( u4 u16* -- ) // calculated shift right signed ld d2ar,alu // d2ar -> var; pop alu // alu = u4 cpl // alu = -1 -u4 => 0..15 -> -1..-16 or $FFF0 // dtmp add srstab+16 // dtmp ld d0,alu // d0 -> srstab +16 -1 -u4 pop alu // alu = new TOP tst (d2ar) if bit15 ld cmd,d0 // jp ld sr,(d2ar),cy :1 // post else ld cmd,d0 // jp ld sr,(d2ar),nc :0 // post then if 1 srstab ld sr,sr , cy // a>>15 ld sr,sr , cy // a>>14 ld sr,sr , cy // a>>13 ld sr,sr , cy // a>>12 ld sr,sr , cy // a>>11 ld sr,sr , cy // a>>10 ld sr,sr , cy // a>>9 ld sr,sr , cy // a>>8 ld sr,sr , cy // a>>7 ld sr,sr , cy // a>>6 ld sr,sr , cy // a>>5 ld sr,sr , cy // a>>4 ld sr,sr , cy // a>>3 ld sr,sr , cy // a>>2 ld (d2ar),sr // a>>1 next_mc // a>>0 else ld sr,sr , nc // a>>15 ld sr,sr , nc // a>>14 ld sr,sr , nc // a>>13 ld sr,sr , nc // a>>12 ld sr,sr , nc // a>>11 ld sr,sr , nc // a>>10 ld sr,sr , nc // a>>9 ld sr,sr , nc // a>>8 ld sr,sr , nc // a>>7 ld sr,sr , nc // a>>6 ld sr,sr , nc // a>>5 ld sr,sr , nc // a>>4 ld sr,sr , nc // a>>3 ld sr,sr , nc // a>>2 ld (d2ar),sr // a>>1 next_mc // a>>0 then :SruPoke ( i4:n i16*:a -- ) ld a0,alu // a0: dest pop alu // alu: dist and $000F cpl // -1-n -1..-16 add srutab+1 // srtab+1-1-n = srtab-n dtmp ld cmd,alu // jp srtab-n pop alu :bit15 // new TOP if 1 ld sr,(a0) , nc :0 // a>>15 ld sr,(a0) , nc :0 // a>>14 ld sr,(a0) , nc :0 // a>>13 ld sr,(a0) , nc :0 // a>>12 ld sr,(a0) , nc :0 // a>>11 ld sr,(a0) , nc :0 // a>>10 ld sr,(a0) , nc :0 // a>>9 ld sr,(a0) , nc :0 // a>>8 ld sr,(a0) , nc :0 // a>>7 ld sr,(a0) , nc :0 // a>>6 ld sr,(a0) , nc :0 // a>>5 ld sr,(a0) , nc :0 // a>>4 ld sr,(a0) , nc :0 // a>>3 ld sr,(a0) , nc :0 // a>>2 ld sr,(a0) , nc :0 // a>>1 srutab next_mc // a>>0 else nop // a>>15 ld sr,sr , nc // a>>14 ld sr,sr , nc // a>>13 ld sr,sr , nc // a>>12 ld sr,sr , nc // a>>11 ld sr,sr , nc // a>>10 ld sr,sr , nc // a>>9 ld sr,sr , nc // a>>8 ld sr,sr , nc // a>>7 ld sr,sr , nc // a>>6 ld sr,sr , nc // a>>5 ld sr,sr , nc // a>>4 ld sr,sr , nc // a>>3 ld sr,sr , nc // a>>2 ld sr,sr , nc // a>>1 ld (a0),sr // a>>0 next_mc then :SlPoke ( i4:n i16*:a -- ) // calculated shift: a <<= n with 0<=n<=15 ld a0,alu pop alu and $000f // n 0..15 cpl // -1-n -1..-16 add sltab+1 // sltab+1-1-n = sltab-n dtmp ld cmd,alu // jp sltab-n ld alu,(a0) :bit15 // a add alu // a<<15 nodelay add alu // a<<14 nodelay add alu // a<<13 nodelay add alu // a<<12 nodelay add alu // a<<11 nodelay add alu // a<<10 nodelay add alu // a<<9 nodelay add alu // a<<8 nodelay add alu // a<<7 nodelay add alu // a<<6 nodelay add alu // a<<5 nodelay add alu // a<<4 nodelay add alu // a<<3 nodelay add alu // a<<2 nodelay add alu // a<<1 nodelay sltab ld (a0),alu // a<<0 pop alu next_mc // signed shift right: // :Srs ( i16:a i4:n -- i16 ) and $000F // dtmp cpl // 0..15 -> -1..-16 add srstab+16 // dtmp ld d0,alu pop alu ld alu,alu :bit15 if 1 ld cmd,d0 ld sr,alu,cy :1 else ld cmd,d0 ld sr,alu,nc :0 then if 1 srstab: ld sr,sr , cy // a>>15 ld sr,sr , cy // a>>14 ld sr,sr , cy // a>>13 ld sr,sr , cy // a>>12 ld sr,sr , cy // a>>11 ld sr,sr , cy // a>>10 ld sr,sr , cy // a>>9 ld sr,sr , cy // a>>8 ld sr,sr , cy // a>>7 ld sr,sr , cy // a>>6 ld sr,sr , cy // a>>5 ld sr,sr , cy // a>>4 ld sr,sr , cy // a>>3 ld sr,sr , cy // a>>2 ld alu,sr // a>>1 next_mc // a>>0 else ld sr,sr , nc // a>>15 ld sr,sr , nc // a>>14 ld sr,sr , nc // a>>13 ld sr,sr , nc // a>>12 ld sr,sr , nc // a>>11 ld sr,sr , nc // a>>10 ld sr,sr , nc // a>>9 ld sr,sr , nc // a>>8 ld sr,sr , nc // a>>7 ld sr,sr , nc // a>>6 ld sr,sr , nc // a>>5 ld sr,sr , nc // a>>4 ld sr,sr , nc // a>>3 ld sr,sr , nc // a>>2 ld alu,sr // a>>1 next_mc // a>>0 then :random__6uint16 ( -- u16 ) inc hp // push alu ld (hp),alu : rnd if 1 ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy else ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc then ld alu,sl next_mc :random__6uint16_6uint16 ( u16 -- u16 ) TODO // sl muss vorher genullt werden ld atmp,$ // * TODO jp TODO // * TODO ld d0,alu // d0 = max-wert cpl ld msbit,alu // req. bits-1 ld alu,r1 sub msbit ld d1,alu // d1 = ladder entry address ld cmd,d1 // jp to d1, code plane = rnd nop : rnd if 1 ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy : rnd ld sl,sl,cy else ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd ld sl,sl,nc : rnd r1: ld sl,sl,nc then ld alu,sl cmp d0 if cy ld cmd,d1 nop : rnd else next_mc then :IncrL ( i32* -- ) ld atmp,alu // atmp -> i32.hi inc atmp // atmp -> i32.lo xor alu add_c (atmp) ld (atmp--),alu : cy if 1 xor alu add_c (atmp) ld (atmp),alu then pop alu next_mc :BoolL ( i32 -- i16 ) pop dtmp or dtmp xor alu :z if 0 add_c alu // nz => 1 nodelay then // z => 0 next_mc :SwapBytes ( i16 -- i16 ) ld swap,alu ld alu,swap next_mc :Bit15 ( i16 -- i1 ) tst alu ld alu,ival :bit15 if 1 dw 1 else dw 0 then next_mc // ======================================================= // Characters // ======================================================= // Is Letter? // (z.Zt. ASCII only) // is_letter(c) = uchar((c|0x20)-'a')<='z'-'a'; // 2010-05-15 // :IsLetter ( u16:char -- i1 ) or $20 sub 'a' // dtmp cmp_nc 'z'-'a' // dtmp xor alu :cy if 0 add_c alu // => 1 nodelay then next_mc // Is binary digit? // is_bin_digit(c) = (c|1)=='1'; // 2010-05-15 // :IsBinDigit ( u16:char -- i1 ) or 1 ld dtmp,'1' // wg. delay equ dtmp xor alu :z if 1 add_c alu // => 1 nodelay then next_mc // is decimal digit? // is_dec_digit(c) = uchar(c-'0')<='9'-'0'; // 2010-05-15 // :IsDecDigit ( u16:char -- i1 ) sub '0' // dtmp cmp_nc '9'-'0' // dtmp xor alu :cy if 0 add_c alu // => 1 nodelay then next_mc // is hexadecimal digit? // is_hex_digit(c) = uchar(c-'0')<='9'-'0' || uchar((c|0x20)-'a') <= 'f'-'a'; // 2010-05-15 // :IsHexDigit ( u16:char -- i1 ) ld d2,alu // d2=char sub '0' // dtmp cmp_nc '9'-'0' // dtmp ld alu,d2 :cy // alu=char if 1 // cy => !cy => char>'9' => no dec. digit or $20 sub 'a' // dtmp cmp_nc 'f'-'a' // dtmp xor alu :cy if 0 add_c alu // => 1 nodelay then next_mc else // !cy => cy => char?'9' => dec. digit xor alu add_c alu // => 1 nodelay next_mc then // value of decimal digit: // char --> digit value: ['0'..'9'] ---> [0..9]; non-digits ---> [10..255] // digit_val(char c) { return uchar(c-'0'); } // 2010-05-15 // DecDigitValue := Subq+'0' ( u16:char -- u16 ) // value of base36 digit: // char --> digit value: ['0'..'9']['A'..'Z']['a'..'z'] ---> [0...35]; non-digits ---> [36++] // digit_value(c) = c<='9' ? uchar(c-'0') : int(uchar((c&~0x20)-'A'))+10; // 2010-05-15 // :DigitValue ( u16:char -- u16 ) cmp '9'+1 // dtmp jp !cy,Subq+'0' // !cy => cy => char<'9'+1 => char?'9' => rval > $FFC0 or $20 // to_lower sub 'a' // dtmp if !cy next_mc else jp Addq+10 then // --- file: "millicode_int.asm" --- #include "asm/millicode_float.asm" // +++ file: "millicode_float.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // Microcode for the K1-16/16 CPU // // 2012-04-08 // ======================================================= // millicode - Floating Point Arithmetics // ======================================================= // ======================================================= // Constant Values: // ======================================================= // Macro: instr float(MANTH,MANTL,EXP) psh alu,EXP,MANTH ld alu,MANTL next_mc end :pi_4__7float48 ( -- float ) float $C90F,$DAA2, $3FFF // pi/4 psh alu,$3FFF ,$C90F // * float ld alu,$DAA2 // * float next_mc // * float :inf_p__7float48 float $ffff, $ffff, $7ffff // +inf exp = $7fff, mant = $ffffffff psh alu,$7ffff ,$ffff // * float ld alu,$ffff // * float next_mc // * float :inf_m__7float48 inc hp // -inf exp = $Ffff, mant = $ffffffff ld (hp++),alu xorn alu ld (hp++),alu ld (hp),alu next_mc :NaN__7float48 inc hp // NaN exp = 0, mant = $0000FFFF ld (hp++),alu xor alu ld (hp++),alu ld (hp),alu xorn alu next_mc :zero__7float48 inc hp // 0.0 exp = 0, mant = 0 ld (hp++),alu xor alu ld (hp++),alu ld (hp),alu next_mc /* :log2_e ( -- float ) float $B8AA,$3B29, $4000 // 1.44269504088896340735992468100189214 log2(e) :log10_e( -- float ) float $DE5B,$D8A9,$3FFE // 0.434294481903251827651128918916605082 log10(e) :ln_2 ( -- float ) float $B172,$17F8, $3FFF // 0.693147180559945309417232121458176568 loge(2) :ln_10 ( -- float ) float $935D,$8DDE, $4001 // 2.30258509299404568401799145468436421 loge(10) :pi ( -- float ) float $C90F,$DAA2, $4001 // pi = 3.14159265358979323846264338327950288 :ec ( -- float ) float $ADF8,$5459, $4001 // ec = 2.71828182845904523536028747135266250 :one__7float48 float $8000,$0000,$4000 // 1.0 :two__7float48 float $8000,$0000,$4001 // 2.0 :e_m05 float $9B45,$97E3, $3FFF // e^-0.5 e_m1: float $BC5A,$B1B1, $3FFE // e^-1 e_m2: float $8A95,$551E, $3FFD // e^-2 e_m4: float $960A,$ADC1, $3FFA // e^-4 e_m8: float $AFE1,$0821, $3FF4 e_m16: float $F1AA,$DDD7, $3FE8 e_m32: float $E423,$27BB, $3FD1 e_m64: float $CB4E,$A399, $3FA3 e_m128: float $A175,$CF9D, $3F47 e_m256: float $CBAA,$CAB5, $3E8E e_m512: float $A208,$4F6E, $3D1D :e_05 float $D309,$4C71, $4000 // e^0.5 ec: float $ADF8,$5459, $4001 // e^1 = ec = 2.71828182845904523536028747135266250 e_2: float $EC73,$25C7, $4002 // e^2 e_4: float $DA64,$8171, $4005 // e^4 e_8: float $BA4F,$53EA, $400B e_16: float $8797,$5E85, $4017 e_32: float $8FA1,$FE62, $402E e_64: float $A12C,$C168, $405C e_128: float $CAF2,$A62F, $40B8 e_256: float $A0E3,$D441, $4171 e_512: float $CA3B,$2826, $42E2 :pi_m1 float $A2F9,$836E, $3FFE // 1/pi = 0.318309886183790671537767526745028724 :pi_2m1 float $A2F9,$836E, $3FFF // 2/pi = 0.636619772367581343075535053490057448 :pi_2 float $C90F,$DAA2, $4000 // pi/2 = 1.57079632679489661923132169163975144 :pi_x2 float $C90F,$DAA2, $4002 // 2*pi = 2*3.14159265358979323846264338327950288 :z_pi_m05 float $906E,$BA82, $4000 // 1.12837916709551257389615890312154517 2/sqrt(pi) :zwei_05 float $B504,$F334, $4000 // 1.41421356237309504880168872420969808 sqrt(2) :zwei_m05 float $B504,$F334, $3FFF // 0.707106781186547524400844362104849039 1/sqrt(2) */ // --- file: "millicode_float.asm" --- #include "asm/millicode_str.asm" // +++ file: "millicode_str.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // Microcode for the K1-16/16 CPU // // 2012-04-08 // ================================================================ // millicode - Strings and Arrays // ================================================================ // Immediate String Literal: // mc Istr+data.len // dm data // ld cmd,atmp // :Istr = $F00:0 ( -- str ) psh alu ld d0,cmd_lo // d0=len jsr alloc // d0=len, a1=ptr->data.len, alu=a0=handle ld atmp,p1 ld a0,d0 // a0=d0=len jp atmp // post ((first 'ld(a1++),d0' overwrites str.len with len)) do // copy text to string ld cmd,ip++ ld d0,ival :bit15 // d0=char // ((load d0=char and run through following chars up to 'ld cmd,atmp' => jump to p1)) p1 tst a0-- ld (a1++),d0 :z until 1 inc ip // skip over final 'ld cmd,atmp' next_mc // count(int16[]) // :Count ( str˘ -- u16:size ) ld d2ar,alu // d2ar=alu=handle ld d2ar,(d2ar) :z // d2ar=ptr if 0 ld alu,(d2ar) // alu=len next_mc else next_mc then cast_range_2_str := cast_range_2_str__8ucs2charAEC_6uint16_6uint16_8ucs2charAE ( char[?] -- str ) CatStr := catstr__8ucs2charAE_8ucs2charAE_8ucs2charAE ( str str -- str ) :CharStr ( char -- str ) ld d0,1 // size ld d1,alu // save char jsr alloc // alloc ld (++a1),d1 // store char next_mc // rval = alu = a0 = handle : SubStrc_r ( ucs2str˘, int16:a int16:e -- char[?] ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded // a = max(a,+0); mc Lget+255 mc Int8+0 mc Max mc Lset+255 // e = min(e,(int)s.count()); mc Dup mc Lget+253 mc Count mc Min mc Nip // if(e null <=> empty str ld (a1),alu // *var := handle next_mc then // test if array or struct is shared // null => false // :IsShared ( T[] -- bool ) tst alu if !z ld atmp,alu inc atmp tst (atmp) cmp (atmp) if z ld alu,0 else ld alu,1 then then next_mc #if 0 // -> misc.asm//skipping: // size == count(int16[]) // :Count ( str˘ -- u16:size ) Count: ld d2ar,alu // d2ar=alu=handle ld d2ar,(d2ar) :z // d2ar=ptr if 0 ld alu,(d2ar) // alu=len next_mc // post else next_mc then #endif // count(int32[]) // :Count2 ( int32[]˘ -- u16:count ) ld d2ar,alu // d2ar=alu=handle ld d2ar,(d2ar) :z // d2ar=ptr if 0 ld sr,(d2ar),nc ld alu,sr // alu=cnt next_mc // post else next_mc then // count(float48[]) // :Count3 ( float48[]˘ -- u16:count ) ld d2ar,alu // d2ar=alu=handle ld d2ar,(d2ar) :z // d2ar=ptr if 1 next_mc then ld alu,(d2ar) // alu=size Div3U: // alu = alu/3 cmp $100 // dtmp if !cy // !cy => cy => alu<$100 ld sr,$0180,nc // $c0 = 3<<6 else ld sr,$8000,cy // $c000 = 3<<14 then ld sl,0,nc // result do cmp sr // alu - 3< !cy => alu>=sr sub sr ld sl,sl,cy else ld sl,sl,nc then ld sr,sr,nc while !bit0 ld alu,sl next_mc /* :CatStr ( str str -- str ) login TODO // memcnt ld a1,alu // a1=handle2 ld dtmp,(hp) :z jp 1,Drop // string2=NULL => return string 1 ld a0,dtmp // a0=handle1 ld d2,a1 :z // d2=handle2 jp 1,Nip // string1=NULL => return string 2 // ld atmp,a0+1 // atmp->memcnt1 TODO jsr mem_append_handle // delete handle2 ld alu,d2 // alu = TOP = handle2 jp DropStr */ // ======================================================= // Create Strings: // ======================================================= #if 0 // -> misc.asm//skipping: // Immediate String Literal: // mc Istr+data.len // dm data // ld cmd,atmp // :Istr = $F00:0 ( -- str ) psh alu ld d0,cmd_lo // d0=len jsr alloc // d0=len, a1=ptr->data.len, alu=a0=handle ld atmp,p1 ld a0,d0 // a0=d0=len jp atmp // post ((first 'ld(a1++),d0' overwrites str.len with len)) do // copy text to string ld cmd,ip++ ld d0,ival :bit15 // d0=char // ((load d0=char and run through following chars up to 'ld cmd,atmp' => jump to p1)) p1 tst a0-- ld (a1++),d0 :z until 1 inc ip // skip over final 'ld cmd,atmp' next_mc #endif // helper für AppendStr: // :AllocTrackedVref ( T[]& T[] uint:n -- T[]& T[] ) ld d0,alu // size dec hp ld d1,(hp++) // d1 = tracked address -> var jsr alloc_wtv // allocate handle and data: // in: d0 = size // d1 = tracked address // out: alu = a0 = handle // d1 = updated address // a1 = memptr // mod: alu,sr,a0,a1 // pres:d0,d2 dec hp ld (hp++),d1 // updated vref back on stack ld atmp,d1 // atmp -> var ld dtmp,(atmp) // dtmp = oldstr ld (atmp),alu // var := newstr ld alu,dtmp // alu = oldstr jp DropStr // dispose oldstr :AppendCstr ( T[]˘ T[]& -- ) // speichere CatStr(zweiter,erster) in die vref zurück ld d2ar,(hp) // d2ar -> memptr ld atmp,d2ar+1 : z // atmp -> refcnt jp 1,AppendGl__8ucs2charAE_8ucs2charAEP_ // T[]˘ is null ld d2ar,(atmp) // d2ar = refcnt ld a0,d2ar+1 // a0 = refcnt+1 ld (atmp),a0 // *dtmp* // refcnt = refcnt+1 jp AppendGl__8ucs2charAE_8ucs2charAEP_ //:AppendStr ( T[] T[]& -- ) // speichere CatStr(zweiter,erster) in die vref zurück // TODO --> str.cc TODO ld atmp,$ // * TODO jp TODO // * TODO :AppendRange ( T[?] T[]& -- ) // speichere CatStr(zweiter,erster) in die vref zurück TODO ld atmp,$ // * TODO jp TODO // * TODO //:AppendRange ( T[?] T[]˘ -- ) // hänge ersten an den zweiten an // TODO //:AppendCstr ( T[]˘ T[]˘ -- ) // hänge ersten an den zweiten an // TODO //:AppendStr ( T[] T[]˘ -- ) // hänge ersten an den zweiten an // TODO str1 = 1 zstr = 0 Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded // mc args=0,Lget str1,Count,Ifnot3,Drop,DropStr,Ret, args==-2 // mc args=0,Lget zstr,Peek,Lget str1,CatStr,args==1 // TODO: mem_compact() !!! // mc Lget zstr,SwapWithVar,DropStr,Drop2_Next, args==-2 #if 0//skipping: ld a0,alu // a0 -> str1 tst (a0) // delay ld d2ar,(a0) // d2ar = str1 jp z,PokeCstr tst (hp) // delay pop d2 // d2 = str2 jp z,next_mc ld d2ar,(d2ar) // d2ar -> str1.len ld alu,(d2ar) // alu = len1 ld d2ar,d2 ld d2ar,(d2ar) // d2ar -> str2.len add (d2ar) // alu = len1+len2 ld d0,alu ld a0,(a0) // a0 = str1 dtmp jsr mem_grow_handle // a1->appended space d0-d2 pres. ld a0,d2 // str2 ld a0,(a0) // memptr2 -> str2.len dtmp ld alu,(a0++) pshr next_mc jp memcpy #endif /* Hänge String an String an */ //:AppendGlCstrRt ( T[]˘ T[]& -- ) // operator+= and retain items, reverted //AppendGlCstrRt__8ucs2charAEC_8ucs2charAEP_: // TODO :AppendGlStrRt ( T[] T[]& -- ) // operator+= and retain items, reverted TODO ld atmp,$ // * TODO jp TODO // * TODO :AppendGlRangeRt ( T[?] T[]& -- ) // operator+= and retain items, reverted TODO ld atmp,$ // * TODO jp TODO // * TODO /* append to string and retain items: */ //:AppendGlItemRt ( T T[]& -- ) // operator+= and retain items // TODO :CatStr__Rt ( T[] T[] -- T[] ) // operator + and retain items TODO ld atmp,$ // * TODO jp TODO // * TODO /* Hänge Zeichen an String an */ //AppendGlChar__8ucs2char_8ucs2charAEP_ //:AppendGlChar ( char str& -- ) // TODO :AppendF ( float float[]& -- ) TODO ld atmp,$ // * TODO jp TODO // * TODO :AppendL ( long long[]& -- ) TODO ld atmp,$ // * TODO jp TODO // * TODO //:AppendL ( long long[]˘ -- ) // TODO /* :nAppendChar ( char str˘ -- ) TODO//to be eliminated // alu -> strvar // (hp) = char ld a0,alu // a0 -> strvar ld d1,alu // d1 -> strvar *combine* ld d2ar,(a0) // d2ar -> memptr jp z, append_to_null // append to non-null string: ld d2ar,(d2ar) // d2ar -> data.size ld d2,(d2ar) // d2 = old size ld atmp,d2 inc atmp ld d0,atmp // d0 = new size jsr alloc_wtv // ( d0:size d1->strvar -- alu=a0=handle d1->strvar a1->data.size ) // pres:d0,d2 // alu = new handle // a0 = new handle // d1 -> strvar (updated) // a1 -> new data.size // d0 = new size // d2 = old size ld atmp,d1 // atmp -> strvar ld d1,(atmp) // d1 = old handle -> old memptr ld (atmp),alu // *strvar := new handle ld a0,d1 // a0 = old handle -> old memptr ld a0,(a0) // a0 = old memptr -> old data.len *dtmp* ld alu,(a0++) // a0 -> old data.data alu = old len inc a1 // a1 -> new data.data jsr memcpy // ( alu:n a0 a1 -- a0+=n a1+=n ) mod: alu,sr,a0,a1 pres:d0-d2 pop (a1) // store char *dtmp* ld alu,d1 // alu = old handle jp DropStr // drop old str append_to_null ld d0,1 // d0 = new strlen jsr alloc_wtv // ( d0:size d1->strvar -- alu=a0=handle d1->strvar a1->data.size ) // pres:d0,d2 // alu = new handle // d1 -> strvar (updated) // a1 -> new data.size ld atmp,d1 // atmp -> strvar ld (atmp),alu // *strvar := new handle inc a1 // a1 -> new data.data pop (a1),alu // store char *dtmp* next_mc */ //:Rol_AE ( int[?] -- ) // TODO :Rol_LAE ( long[?] -- ) TODO ld atmp,$ // * TODO jp TODO // * TODO :Rol_FAE ( float[?] -- ) TODO ld atmp,$ // * TODO jp TODO // * TODO :RangeAll ( T[]˘ -- T[?] ) ld atmp,alu // atmp -> memptr ld d2ar,(atmp) // d2ar -> array.len psh alu,0 // T[]˘, a=0 ld alu,(d2ar) // e=len next_mc :ResizeStr( str˘ len -- ) pop dtmp // handle ld a0,dtmp // a0 = handle ld d0,alu :z // d0 = new len jp 1,Drop // NULL handle can't be changed pshr Drop jp mem_resize_handle // in: a0=handle d0=size :GrowStr( str˘ len -- ) pop dtmp // handle ld a0,dtmp // a0 = handle ld d0,alu :z // d0 = new len jp 1,Drop // NULL handle can't be changed pshr Drop jp mem_grow_handle_cond // in: a0=handle d0=size :ShrinkStr( str˘ len -- ) pop dtmp // handle ld a0,dtmp ld d0,alu :z // new len jp 1,Drop // NULL handle can't be changed pshr Drop jp mem_shrink_handle_cond // in: a0=handle d0=size //:ShrinkStrArray ( T[][]˘ uint -- ) // TODO // compare strings for equality // 2010-05-11 // :Eq_CstrCstr ( str1˘ str2˘ -- i1 ) ld a0,alu // a0=handle2 pop alu :z // alu=handle1 if 1 ld a0,null // a0==0 => a0=ptr->null else ld a0,(a0) // a0=ptr2 dtmp then ld a1,alu // handle1 if z ld a1,null // a1==0 => a1=ptr->null else ld a1,(a1) // a1=ptr1 dtmp then // a0 -> bu1 // a1 -> bu2 m_cmpstr: ld atmp,(a0) // atmp=len1 dtmp // vergleich beider strings. // als erstes wird das length-word verglichen. do ld alu,(a0++) // alu=char2 equ (a1) // delay equ (a1++) // char2==char1? if !z // no xor alu // rval=0=no next_mc then tst atmp-- // counter until z xor alu add_c alu // => 1 = yes nodelay next_mc :Ne_CstrCstr ( str1˘ str2˘ -- i1 ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Eq_CstrCstr mc Not mc Ret // --- file: "millicode_str.asm" --- #include "asm/combicodes.asm" // +++ file: "combicodes.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // Microcode for the K1-16/16 CPU // // 2010-09-20 // ================================================================ // Combined Millicode + Opcodes // ================================================================ :srn // shift right a>>n return via d2 and $000F tst alu cpl :z // n -> -1-n if 1 ld cmd,d2 pop alu :bit15 else add sr8+8+1 // sr0+1+(-1-n) = sr0-n dtmp ld cmd,alu // jp srtab-n ld sr,(hp--),nc :bit15 then if 1 ld sr,sr , nc // a>>15 ld sr,sr , nc // a>>14 ld sr,sr , nc // a>>13 ld sr,sr , nc // a>>12 ld sr,sr , nc // a>>11 ld sr,sr , nc // a>>10 ld swap,sr :0 // a>>9 then if 1 sr8 ld sr,sr , nc // a>>8 ld sr,sr , nc // a>>7 ld sr,sr , nc // a>>6 ld sr,sr , nc // a>>5 ld sr,sr , nc // a>>4 ld sr,sr , nc // a>>3 ld sr,sr , nc // a>>2 ld cmd,d2 ld alu,sr :bit15 // a>>1 else // dm "1234567" ld alu,$00ff ld cmd,d2 and swap :bit15 then :sln // shift left a< -1-n if 1 ld cmd,d2 pop alu :bit15 else add sl8+8+1 // sl0+1+(-1-n) = sl0-n dtmp ld cmd,alu // jp sltab-n ld sl,(hp--),nc :bit15 then if 1 ld sl,sl , nc // a<<15 ld sl,sl , nc // a<<14 ld sl,sl , nc // a<<13 ld sl,sl , nc // a<<12 ld sl,sl , nc // a<<11 ld sl,sl , nc // a<<10 ld swap,sl :0 // a<<9 then if 1 sl8 ld sl,sl , nc // a<<8 ld sl,sl , nc // a<<7 ld sl,sl , nc // a<<6 ld sl,sl , nc // a<<5 ld sl,sl , nc // a<<4 ld sl,sl , nc // a<<3 ld sl,sl , nc // a<<2 ld cmd,d2 ld alu,sl :bit15 // a<<1 else // dm "1234567" ld alu,$ff00 ld cmd,d2 and swap :bit15 then :sl_n ( i16 i4 -- i16 ) ld d2,next_mc jp sln :sr_n ( i16 i4 -- i16 ) ld d2,next_mc jp srn // --- file: "combicodes.asm" --- #include "asm/opcodes.asm" // +++ file: "opcodes.asm" +++ /* Copyright (c) Günter Woigk 2009 - 2015 mailto:kio@little-bat.de This file is free software This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if signed_bool//skipping: instr return(FLAG,VALUE) ld cmd,(ip++) :FLAG if VALUE xorn alu :bit15 else xor alu :bit15 then // cond end #else // unsigned bool instr return(FLAG,VALUE) xor alu :FLAG if VALUE add_c alu // nodelay next_op // post else next_op then end #endif // OPCODE: nop // resume with next OPCODE in ram: // :NOP ( -- ) NEXT: ( -- ) next_op :SWAPWITHVAR ( int:Q int&:Z -- int:Z ) // swap data Q with contents of variable Z ld atmp,alu // atmp -> var Z ld alu,(atmp) // alu = Z pop (atmp) // var Z = Q dtmp next_op :MSBIT ( i16 -- i4 ) ldn alu ld msbit,alu ld alu,msbit next_op :ATI ( int[]˘ idx -- int& ) pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] next_op :ATIPEEK ( str˘ idx -- int ) pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] ld d2ar,alu ld alu,(d2ar) // value next_op :ATIPOKE ( int int[]˘ idx -- ) pop d2ar // str handle -> memptr add_c (d2ar) // ptr -> bu[idx] ld d2ar,alu pop (d2ar),alu // store value *dtmp* next_op :ATIPOKESTR ( str idx str[]˘ -- ) // Bytecode login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d2ar,alu // d2ar = handle -> memptr -> str[].cnt pop alu // idx add_c (d2ar) // alu = @str[].cnt+1+idx -> str[i] ld d2ar,alu // d2ar -> str[i] ld alu,(d2ar) // alu = str[i] jp POKESTR :COUNT ( str˘ -- i16 ) // Bytecode ld d2ar,alu ld d2ar,(d2ar) ld alu,(d2ar) next_op :TOR ( n -- ) // Bytecode pshr alu pop alu next_op :FROMR ( -- n ) // Bytecode psh alu popr alu next_op :IRPT ( selmask -- ) // Bytecode: trigger irpt routine di ld io_select,alu ld msbit,alu ld atmp,msbit // atmp = int_vector = 0 .. 15 pshr ip // dtmp ld d2ar,(atmp) // d2ar -> device sel mask ld ip,d2ar+1 // ip -> int_handler pop alu next_op // jump to int handler in ram post :OR1 % $100 ( i1 -- ) // Bytecode: pruning boolean OR tst alu if !z ld ip,ip+dis // skip 2nd operand else pop alu // drop i1 and execute 2nd operand for i1 then next_op :AND0 % $100 ( i1 -- ) // Bytecode: pruning boolean AND tst alu if z ld ip,ip+dis // skip 2nd operand else pop alu // drop i1 and execute 2nd operand for i1 then next_op // return from millicoded opcode: // NextOpcode := RET ( -- ) //// copy memory from str q to str z[j] //// limits copy count to str sizes //// but does not check indexes //// //:COPY_I2IJ ( qi zi zj n qstr˘ zstr[]˘ -- ) // Bytecode // login // TODO // memcnt // // pop d0,d1 // d0=qstr,d1=n // ld atmp,alu // zstr // ld alu,(atmp) // alu -> zstr.len // add_c (hp) // alu -> zstr[j] // ld (hp++),d1 // n back on stack // ld (hp),d0 // qstr back on stack //// jp COPY_I2I // //// copy memory from str q to str z //// limits copy count to str sizes //// but does not check indexes //// //COPY_I2I: ( qidx, zidx, cnt, str˘:q, str˘:z -- ) // Bytecode // login // TODO // memcnt // // Millicoded //qidx=4 //zidx=3 //cnt=2 //qstr=1 //zstr=0 // args=0 // // limit copy cnt: // mc Lget zstr,Count,Lget zidx,Sub, args==1 // z_max_cnt // mc Lget qstr,Count,Lget qidx,Sub, args==2 // z_max_cnt q_max_cnt // mc Min,Lget cnt,Min,Lset cnt, args==0 // // calc q and z ptr: // mc Lget zidx,AtIndex,Swap, args==0 // mc Lget qidx,AtIndex,Swap, args==0 // // copy, drop args & exit: // mc Lget cnt,NewMemCpy,Drop3_Next // args==-5 // //:COPY_IJ2I ( qi, qj, zi, n, qstr[]˘, zstr˘ -- ) // Bytecode // login // TODO // memcnt // // ld d0,alu // d0=zstr // pop d2ar,d1,d2 // d2ar=qstr[],d1=n,d2=zi // ld alu,(d2ar) // alu->qstr[].len // add_c (hp) // alu->qstr[j] // ld (hp++),d2 // zi // ld (hp++),d1 // n // ld (hp),alu // qstr // ld alu,d0 // zstr // jp COPY_I2I // //:COPY_IJ2IJ ( qi, qj, zi, zj, n, qstr[]˘, zstr[]˘ -- ) // Bytecode // login // TODO // memcnt // // ld atmp,alu // atmp=zstr[] // pop d2ar,d0,d1,d2 // d2ar=qstr[],d0=n,d1=zj,d2=zi // ld alu,(d2ar) // alu->qstr[].len // add_c (hp) // alu->qstr[j] // ld d2ar,alu // d2ar->qstr[j] // ld (hp++),d2 // zi // ld (hp++),d0 // n // ld (hp),(d2ar) // qstr dtmp // ld alu,(atmp) // alu->zstr[].cnt // add_c d1 // alu->zstr[j] // ld atmp,alu // ld alu,(atmp) // alu=zstr // jp COPY_I2I /* :ATIRESIZE ( size i str[]˘ -- ) // Bytecode login TODO // memcnt Millicoded mc Dup2,ToR,ToR mc Swap,AtIndexPeek mc Swap,ResizedStr mc FromR,FromR mc Swap,AtIndexPoke mc NextOpcode */ // resize string // :RESIZE ( size str* -- ) // Bytecode login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld a0,alu // a0->str ld alu,(a0) // alu=str_handle (delay) ld alu,(a0) // alu=str_handle if z // str==NULL ld d0,(hp) ld d0,(hp--) if z pop alu // TOP next_op else // str==NULL, new str.len>0 ld d2,a0 // d2->str (safe) jsr alloc // in:d0=size out:alu=a0=handle, a1->data.size ld a0,d2 ld (a0),alu next_op then else // str!=NULL ld d0,(hp) ld d0,(hp--) // d0=new size if z login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO ld (a0),0 // str:=NULL ld atmp,mem_free_ptr ld a0,alu // a0=alu=handle ld (a0),(atmp) // dtmp ld (atmp),alu pop alu next_op else ld a0,alu // a0=handle pop d0 // d0=new size jsr mem_resize_handle pop alu next_op then then :SWITCH ( i -- ) // Bytecode: SWITCH,N,LABELS[N] cmp (ip) if cy // cy => !cy => i?n => ootable => resume after table ld alu,(ip++) add_c ip ld ip,alu pop alu next_op // post else add_c ip ld atmp,alu // atmp->tbl[i] ld ip,(atmp) // ip = tbl[i] dtmp pop alu next_op // post then /* :RESIZE_STRBU ( n str[]˘ -- ) // Bytecode login TODO // memcnt Millicoded n = 1 strbu=0 args=0 mc Lget n,Lget strbu,Count,Eq,If,Drop2_Next, args==-2 args=0 mc Lget n,Lget strbu,Count,Ugt,BraIf1 gt, args==0 // newsize mem_free_ptr ld d2,(a0) // d2 -> last free memptr atmp ld a1,(d2ar) // a1->str[].len dtmp ld atmp,(a1++) // atmp=str[].len, a1->str[0] dtmp jp p do ld d2ar,(a1) // delay ld d2ar,(a1++) // d2ar -> str[i] if !z p ld (d2ar),d2 // add str to mem_free list ld d2,d2ar then tst atmp-- until z ld (a0),d2 // update mem_free_ptr pop alu next_op // post then //MULU0 := LDQ+0 falsch: muss sein: drop + ldq(0) MULU1 := NEXT MULU2 := SLI1 MULU4 := SLI2 MULU8 := SLI3 :MULU5 ld sl,alu,nc ld sl,sl,nc add sl next_op :MULU6 add alu // nodelay MULU3: ld sl,alu,nc add sl next_op :MULU7 ld sl,alu,nc add sl ld sl,sl,nc add sl next_op // signed multiplication // MUL: ( i16 i16 -- i16 ) // signed multiplication pop d0 // result pos or neg? xor d0 // alu.bit15 = result.sign xor d0 // alu.bit15 on data bus; restore alu ld a0,ival :bit15 // test result.sign if 1 dw NEG // resut<0: return to neg else dw NEXT then jp mul_d0 // signed division // :DIV ( i16:Q i16:D -- i16 ) // signed division ld d0,(hp) // result pos or neg? xor d0 // alu.bit15 = result.sign xor d0 // alu.bit15 on data bus; restore alu ld a0,ival :bit15 // test result.sign if 1 dw DROP_NEG // result<0: return to Drop + Neg else dw DROP then jp div_d0 // Q = Q/D*D + Q%D // Q%D = Q - Q/D*D => sign(D) irrelevant, sign(Q%D) = sign(Q) ! // :REM ( i16:Q i16:D -- i16:R ) // signed division remainder // D neg? ld atmp,alu dec atmp :bit15 if 1 // note: -a = ~(a-1) ldn atmp // D = -D then // Q neg? => result neg? ld d0,(hp) ld a0,ival :bit15 if 0 dw NIP // Q?0 => result?0 jp divu else dw NIP_NEG // Q<0 => result<0: return to neg ld dtmp,alu ld atmp,d0 dec atmp ldn atmp ld (hp),alu // Q = -Q ld alu,dtmp jp divu then /* MULU: -> millicode_int.asm DIVU: -> millicode_int.asm */ :REMU ( u16:x u16:y -- u16:r ) // r = x%y ld a0,NIP jp divu :FROMR_POKE_NEXT ( int -- ) // UP popr a0 // dtmp ld (a0),alu pop alu next_op // post :MULPOKE ( int int* -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap, Mul, FROMR_POKE_NEXT :DIVPOKE ( int int* -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap, Div, FROMR_POKE_NEXT :REMPOKE ( int int* -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc DupToRPeekSwap, Rem, FROMR_POKE_NEXT :SRUPOKE ( n int* -- ) // Bytecode Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc SruPoke, NextOpcode :SRSPOKE ( n int* -- ) // Bytecode Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded TODO ld atmp,$ // * TODO jp TODO // * TODO // mc SrsPoke, NextOpcode :SLPOKE ( n int* -- ) // Bytecode Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc SlPoke, NextOpcode :ANDPOKE ( int int* -- ) // Bytecode ld atmp,alu pop alu and (atmp) ld (atmp),alu pop alu next_op :ORPOKE ( int int* -- ) // Bytecode ld atmp,alu pop alu or (atmp) ld (atmp),alu pop alu next_op :XORPOKE ( int int* -- ) // Bytecode ld atmp,alu pop alu xor (atmp) ld (atmp),alu pop alu next_op :ADDPOKE ( int int* -- ) // Bytecode ld atmp,alu pop alu add (atmp) ld (atmp),alu pop alu next_op :SUBPOKE ( int int* -- ) // Bytecode ld atmp,alu ld alu,(atmp) sub (hp--) ld (atmp),alu pop alu next_op // =================================================================== // branching: // =================================================================== // 2010-05-11 :JP ( -- ) // JP nn ld ip,(ip) // dtmp next_op // 2010-05-11 :JP_Z ( i1 -- ) // JP if Z nn tst alu ld dtmp,(ip++) :z if 1 ld ip,dtmp pop alu next_op // post else pop alu next_op // post then // 2010-05-11 :JP_NZ ( i1 -- ) // JP if NZ nn tst alu ld dtmp,(ip++) :z if 0 ld ip,dtmp pop alu next_op // post else pop alu next_op // post then // 2010-05-11 :JSR ( -- ) // JSR nn ld dtmp,(ip++) ld d2,ip ld ip,dtmp pshr d2 next_op // post :CALLPROCPTR ( procaddr -- ) ld dtmp,alu pop alu jp dtmp // Call Struct or Array Destructor 'kill()': // Call kill() if handle != null and retain count == 1 // the kill() proc address follows after this opcode // :CALLKILL ( T -- T ) ld atmp,alu if !z inc atmp // --> ref_cnt ld d2ar,(atmp) ld atmp,d2ar-1 tst atmp if z ld dtmp,(ip++) ld d2,ip ld ip,dtmp pshr d2 next_op // post then then inc ip // skip kill() proc address next_op // 2010-05-13 HALT: ( -- ) // wait for interrupt set halt nop clr halt next_op // post // note: // wenn BRA_M = BRA_P-$100, dann ist: // BRA möglich für: BRA=BRA_P und dist = -256 .. +255 // // 2010-05-11 :BSR_M = $3E00:1 ( -- ) // BSR -$100+dis ld dtmp,ip-=dis pshr dtmp next_op // post // 2010-05-11 :BSR_P = $3F00:1 ( -- ) // BSR +dis ld dtmp,ip+=dis pshr dtmp next_op // post // 2010-05-11 :BRA_M = $3E00:0 ( -- ) // BRA -$100+dis ld ip,ip-dis next_op // 2010-05-11 :BRA_P = $3F00:0 ( -- ) // BRA +dis ld ip,ip+dis next_op // 2010-05-11 :BRAZ_M = $3C00:1 ( i1 -- ) // BRA if Z -$100+dis tst alu pop alu :z if 1 ld ip,ip-dis next_op else next_op then // 2010-05-11 :BRAZ_P = $3D00:1 ( i1 -- ) // BRA if Z +dis tst alu pop alu :z if 1 ld ip,ip+dis next_op else next_op then // 2010-05-11 :BRANZ_M = $3A00:1 ( i1 -- ) // BRA if NZ -$100+dis tst alu pop alu :z if 0 ld ip,ip-dis next_op else next_op then // 2010-05-11 :BRANZ_P = $3B00:1 ( i1 -- ) // BRA if NZ +dis tst alu pop alu :z if 0 ld ip,ip+dis next_op else next_op then #if 0//skipping: SKIP_cc = BRA+1 :cc #endif // OPCODE: return from procedure // drop top rstack value // and resume with next OPCODE in ram: // :RDROP_RET ( -- ) popr dtmp RET: ( -- ) // 2010-05-11 popr ip // dtmp next_op // =================================================================== // stack manipulation: // =================================================================== // 2010-05-11 :DUP ( i16 -- i16 i16 ) psh alu next_op // post // 2010-05-11 //:NIP ( i16:a i16:b -- i16:b ) // pop dtmp // next_op // post // 2010-05-11 :SWAP ( i16:a i16:b -- i16:b i16:a ) ld dtmp,(hp) ld (hp),alu ld alu,dtmp next_op // post // 2010-05-11 :OVER ( i16:a i16:b -- i16:a i16:b i16:a ) ld dtmp,(hp++) // a ld (hp),alu // b ld alu,dtmp // a next_op // post // 2010-05-11 :PEEK ( a16 -- i16 ) ld atmp,alu ld alu,(atmp) next_op // post // 2010-05-11 :POKE ( i16 a16 -- ) ld atmp,alu pop (atmp) // dtmp pop alu next_op // post // bytecode_18 = pick ( n? i -- n? n(i) ) with n(0) = i // 2010-05-11 //:PICK ( ? n2 n1 i -- ? n2 n1 ni ) // psh alu // hp -> i // cpl // alu = -1-i // add_c hp // alu = hp+1-1-i = hp-i // ld atmp,alu // ld alu,(atmp) // next_op // post // bytecode_24 = peek++ ( a:i16 -- n ) peek byte/word with post increment // 2010-05-11 :PEEKPP ( a16 -- i16 ) // peek and increment variable ld d2ar,alu // d2ar -> var ld alu,(d2ar) // alu = n ld atmp,alu // atmp = n inc atmp // atmp = n+1 ld (d2ar),atmp // (var) = n+1 dtmp next_op // post :PEEKMM ( a16 -- i16 ) ld d2ar,alu // d2ar -> var ld alu,(d2ar) // alu = n ld atmp,alu // atmp = n dec atmp // atmp = n-1 ld (d2ar),atmp // (var) = n-1 dtmp next_op // post :PPPEEK ( a16 -- i16 ) #if 0//skipping: ld d2ar,alu // d2ar -> var ld alu,(d2ar) // alu = n ld atmp,alu // atmp = n inc atmp // atmp = n+1 ld alu,atmp // alu = n+1 ld (d2ar),alu // (var) = n+1 next_op // post #else ld d2ar,alu // d2ar -> var xor alu add_c (d2ar) ld (d2ar),alu next_op // post #endif :MMPEEK ( a16 -- i16 ) ld d2ar,alu // d2ar -> var ld alu,(d2ar) // alu = n ld atmp,alu // atmp = n dec atmp // atmp = n-1 ld alu,atmp // alu = n-1 ld (d2ar),alu // (var) = n-1 next_op // post // ================================================ // push immediate numeric value // ================================================ // 2010-05-11 :IVAL ( -- i16 ) // load immediate value // psh alu // ld alu,(ip++) // next_op ld dtmp,alu , hp.oe,hp.clk,add1 // and ++hp ld alu,(ip++) ld (hp),dtmp next_op // post // 2010-05-11 :LDQ % $100 ( -- i8 ) // LD n // psh alu // ld alu,cmd_lo // next_op ld dtmp,alu , hp.oe,hp.clk,add1 // and ++hp ld alu,cmd_lo ld (hp),dtmp next_op // post // 2010-05-11 :LDNQ % $100 ( -- i8 ) // LD ~n (-1-n) load quick negative number (-1...-256) // psh alu // ldn cmd_lo // next_op ld dtmp,alu , hp.oe,hp.clk,add1 // and ++hp ldn cmd_lo ld (hp),dtmp next_op // post // ============================================================ // local variables: // ============================================================ // index is: ... n[254] n[255] top[256] // the TOP value cannot be picked with LVAR! ((=> use DUP)) // 2010-05-11 :LVAR % $100 ( -- a16 ) // address of local variable: HP-dis psh alu ld atmp,hp-dis ld alu,atmp next_op // post // 2010-05-11 :LGET % $100 ( -- i16 ) // get local var data psh alu ld atmp,hp-dis ld alu,(atmp) next_op // post // index is: ... n[254] n[255] n[256] data[257] // the TOP value cannot be stored with LPOKE! ((=> used NIP)) // // 2010-05-11 :LSET % $100 ( i16:data -- ) // store data in local var ld atmp,hp-dis ld (atmp),alu pop alu next_op // post :PSH_HP ( -- i16* ) psh alu ld alu,hp next_op // post // ============================================================ // global 'zero page' variables: // ============================================================ :GGET % $100 ( -- i16 ) // get global var data psh alu ld atmp,cmd_lo ld alu,(atmp) next_op // post :GSET % $100 ( i16:data -- ) // store data in global var ld atmp,cmd_lo ld (atmp),alu pop alu next_op // post GVAR := LDQ ( -- i16* ) // ================================================ // struct items // ================================================ :IVAR % $100 ( T{}˘ -- T& ) ld atmp,alu // atmp = handle ld d2ar,(atmp) // d2ar = ptr -> data.len ld atmp,d2ar+dis // atmp -> item-1 inc atmp // atmp -> item ld alu,atmp next_op :IGET % $100 ( T{}˘ -- int16 ) ld atmp,alu // atmp = handle ld d2ar,(atmp) // d2ar = ptr -> data.len ld atmp,d2ar+dis // atmp -> item-1 inc atmp // atmp -> item ld alu,(atmp) next_op :ISET % $100 ( int16 T{}˘ -- ) ld atmp,alu // atmp = handle ld d2ar,(atmp) // d2ar = ptr -> data.len ld atmp,d2ar+dis // atmp -> item-1 inc atmp // atmp -> item pop (atmp),alu // dtmp next_op // ================================================ // 16 bit Arithmetics // ================================================ :CASTwl2b ( uint16 -- uint8 ) and $00ff next_op :CASTwh2b ( uint16 -- uint8 ) ld swap,alu ld alu,$00ff and swap next_op :SWAPBYTES ( i16 -- i16 ) ld swap,alu ld alu,swap next_op // 16 bit immediate: // 2010-05-11 :SUBI ( i16 -- i16 ) // top -= nn sub (ip++) next_op // 2010-05-11 :ADDI ( i16 -- i16 ) // top += nn add (ip++) next_op // 2010-05-11 :ANDI ( i16 -- i16 ) // top &= nn and (ip++) next_op // 2010-05-11 :ORI ( i16 -- i16 ) // top |= nn or (ip++) next_op // 2010-05-11 :XORI ( i16 -- i16 ) // top ^= nn xor (ip++) next_op :MULI ( i16 -- i16 ) psh alu ld alu,(ip++) jp MUL :DIVI ( i16 -- i16 ) psh alu ld alu,(ip++) jp DIV :REMI ( i16 -- i16 ) psh alu ld alu,(ip++) jp REM :MULUI ( i16 -- i16 ) // unsigned multiply with immediate value psh alu ld alu,(ip++) jp MULU :DIVUI ( i16 -- i16 ) // unsigned divide by immediate value psh alu ld alu,(ip++) jp DIVU :REMUI ( i16 -- i16 ) // unsigned remainder with immediate value psh alu ld alu,(ip++) jp REMU :SRUI TODO ld atmp,$ // * TODO jp TODO // * TODO :UGEI ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :EQI ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :NEI ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :UGTI ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :ULEI ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :ULTI ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO // 8 bit immediate quick: // 2010-05-11 :ADDQ % $100 ( i16 -- i16 ) // ADD n add cmd_lo next_op // 2010-05-11 :SUBQ % $100 ( i16 -- i16 ) // SUB n sub cmd_lo next_op // 2010-05-11 :ANDQ % $100 ( i16 -- i16 ) // AND n and cmd_lo next_op // 2010-05-11 :ORQ % $100 ( i16 -- i16 ) // OR n or cmd_lo next_op // 2010-05-11 :XORQ % $100 ( i16 -- i16 ) // XOR n xor cmd_lo next_op :UGEQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :EQQ % $100 ( a -- f ) // cmd.lo = b cmp cmd_lo return z,1 xor alu :z // * return if 1 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return :NEQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :UGTQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :ULEQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :ULTQ % $100 ( a -- f ) // cmd.lo = b cmp cmd_lo // a-b ld alu,ival :cy if 0 dw 1 // !cy => cy => a-b<0 => b-a>0 => b>a => (a>=b) = true else dw 0 // false then // cond next_op // ld cmd,(ip++) :cy // if 0 // xorn alu :bit15 // !cy => cy => a-b<0 => b-a>0 => b>a => (a>=b) = true // else // xor alu :bit15 // false // then // cond :MULQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :DIVQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :REMQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :MULUQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO :DIVUQ % $100 ( a -- f ) // cmd.lo = b psh alu ld alu,cmd_lo jp DIVU :REMUQ % $100 ( a -- f ) // cmd.lo = b TODO ld atmp,$ // * TODO jp TODO // * TODO // non consts: // 2010-05-11 :ADD ( i16 i16 -- i16 ) add (hp--) next_op // 2010-05-11 :SUB ( i16:x i16:y -- i16 ) // x-y = -1-(y-x-1) sub_nc (hp--) cpl next_op // post // 2010-05-11 :AND ( i16 i16 -- i16 ) and (hp--) next_op // post // 2010-05-11 :OR ( i16 i16 -- i16 ) or (hp--) next_op // post // 2010-05-11 :XOR ( i16 i16 -- i16 ) xor (hp--) next_op // post :EQ( i16 i16 -- i1 ) equ (hp) // delay equ (hp--) return z,1 xor alu :z // * return if 1 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return :NE( i16 i16 -- i1 ) equ (hp) // delay equ (hp--) return z,0 xor alu :z // * return if 0 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return :UNSIGNED_COMPARES if 1 UGT: ( u16:a u16:b -- i1 ) cmp (hp--) // b-a else UGE: ( u16:a u16:b -- i1 ) cmp_nc (hp--) // b-a-1 then return cy,0 // !cy => cy => b-a<0 => a>b | a?b xor alu :cy // * return if 0 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return :UNSIGNED_COMPARES2 if 1 ULE: ( u16:a u16:b -- i1 ) // unsigned less or equal cmp (hp--) // b-a else ULT: ( u16:a u16:b -- i1 ) // unsigned less than cmp_nc (hp--) // b-a-1 then return cy,1 // cy => !cy => b?a | b>a xor alu :cy // * return if 1 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return :SIGNED_COMPARES if 1 GT: ( i16:a i16:b -- i1 ) // signed greater than ld dtmp,(hp--) OGT: sub dtmp // b-a else GE: ( i16:a i16:a -- i1 ) // signed greater or equal ld dtmp,(hp--) OGE: sub_nc dtmp // b-a-1 then if !ovfl // !ovfl: signed result b-a is valid tst alu // b-a return bit15,1 // b-a<0 => b a>b xor alu :bit15 // * return if 1 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return else // ovfl: implies: sign(a) != sign(b) tst dtmp // a return bit15,0 // a?0 => b<0 => a>b xor alu :bit15 // * return if 0 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return then :SIGNED_COMPARES2 if 1 LT: ( i16:a i16:b -- i1 ) // signed less than ld dtmp,(hp--) OLT: sub_nc dtmp // b-a-1 else LE: ( i16:a i16:a -- i1 ) // signed less or equal ld dtmp,(hp--) OLE: sub dtmp // b-a then if !ovfl // !ovfl: signed result b-a is valid tst alu // b-a return bit15,0 // b-a?0 => b?a => a?b xor alu :bit15 // * return if 0 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return else // ovfl: implies: sign(a) != sign(b) tst dtmp // a return bit15,1 // a<0 => b?0 => a?b xor alu :bit15 // * return if 1 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return then // 2010-05-11 :UMAX ( u16:a u16:b -- u16 ) // unsigned maximum cmp (hp) // b-a if !cy // !cy => cy => b-a<0 => b a>b => max(a,b) = a pop alu // a next_op // post else pop dtmp next_op // post then // 2010-05-11 :UMIN ( u16 u16 -- u16 ) // unsigned minimum cmp (hp) if cy // cy => !cy => b-a?0 => b?a => a?b => min(a,b) = a pop alu // a next_op // post else pop dtmp next_op // post then // 2010-05-12 :MAX ( i16:a i16:b -- i1 ) // signed maximum ld d2,alu // d2 = b ld dtmp,(hp--) // d3 = a sub dtmp // alu= b-a if !ovfl // signed result b-a is valid tst alu // b-a else // ovfl // implies: sign(a) != sign(b) tst d2 // b then ld cmd,(ip++) :bit15 if 0 // !ovfl: b-a?0 => b?a => a?b => return b ld alu,d2 :bit15 // ovfl: b?0 => a<0 => a?b => return b else ld alu,dtmp :bit15 then // cond // 2010-05-12 :MIN ( i16:a i16:b -- i1 ) // signed minimum ld d2,alu // d2 = b ld dtmp,(hp--) // d3 = a sub dtmp // alu= b-a if !ovfl // signed result b-a is valid tst alu // b-a else // ovfl // implies: sign(a) != sign(b) tst d2 // b then ld cmd,(ip++) :bit15 if 0 // !ovfl: b-a?0 => b?a => a?b => return a ld alu,dtmp :bit15 // ovfl: b?0 => a<0 => a?b => return a else ld alu,d2 :bit15 then // cond // 2010-05-11 :CPL ( i16 -- i16 ) // alu = ~alu cpl next_op // post :DROP_NEG ( int:a b -- int:-a ) pop d2ar ld atmp,d2ar-1 ld alu,atmp next_op // post :NIP_NEG ( a int:b -- int:-b ) dec hp // nip // jp NEG // 2010-05-11 NEG: ( i16 -- i16 ) // alu = -alu neg // atmp next_op // post // 2010-05-11 :BOOL ( i16 -- i1 ) // top = top ? -1 : 0 tst alu return z,0 xor alu :z // * return if 0 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return // 2010-05-11 :NOT ( i16 -- i1 ) tst alu return z,1 xor alu :z // * return if 1 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return // ============================================================ // shift left / right // ============================================================ // 2010-05-11 :SSL ( i16 -- i16 ) // unsigned single shift left: top = top << 1 ld sl,alu , nc ld alu,sl next_op // post // 2010-05-11 :SSR ( i16 -- i16 ) // unsigned single shift right: top = top >> 1 ld sr,alu , nc ld alu,sr next_op // post // 2010-05-12 :SL ( i16:n i4:m -- i16 ) // n << m with 0<=m<=15 and $000f // m 0..15 cpl // -1-m -1..-16 add SLI0+1 // SLI0+1-1-m = SLI0-m dtmp ld cmd,alu // jp SLI0-m pop alu :bit15 // n // 2010-05-11 if 1 SLI: ( i16 -- i16 ) // shift left immediate: top = top << (15..0) add alu // a<<15 nodelay add alu // a<<14 nodelay add alu // a<<13 nodelay add alu // a<<12 nodelay add alu // a<<11 nodelay add alu // a<<10 nodelay add alu // a<<9 nodelay ld swap,alu :0 // a<<8 add alu // a<<7 nodelay add alu // a<<6 nodelay add alu // a<<5 nodelay add alu // a<<4 nodelay add alu // a<<3 nodelay add alu // a<<2 nodelay add alu // a<<1 nodelay SLI0: next_op // a<<0 else dm "xxxxxxxx" // +8 ld alu,$ff00 and swap next_op // post then SLI1 := SLI0-1 ( int -- int ) SLI2 := SLI0-2 ( int -- int ) SLI3 := SLI0-3 ( int -- int ) // 2010-05-12 :SR ( i16:n i4:m -- i16 ) // n >> m with 0<=m<=15 and $000F cpl // -1-m -1..-16 add srtab+1 // SLI0+1-1-m = SLI0-m dtmp ld cmd,alu // jp SLI0-m ld sr,(hp) , nc :bit15 // n>>1 if 1 ld sr,sr , nc // a>>15 ld sr,sr , nc // a>>14 ld sr,sr , nc // a>>13 ld sr,sr , nc // a>>12 ld sr,sr , nc // a>>11 ld sr,sr , nc // a>>10 ld swap,sr :0 // a>>9 ld sr,sr , nc // a>>8 ld sr,sr , nc // a>>7 ld sr,sr , nc // a>>6 ld sr,sr , nc // a>>5 ld sr,sr , nc // a>>4 ld sr,sr , nc // a>>3 ld sr,sr , nc // a>>2 ld alu,sr :0 // a>>1 srtab pop alu // a>>0 next_op // post else dm "1234567" ld alu,$00ff //87 ld cmd,(ip++) //6 and swap , hp.oe,hp.clk,sub1 :bit15 //5 dm "4321" //4321 ld cmd,(ip++) // 5 ld alu,sr , hp.oe,hp.clk,sub1 :bit15 // 4 then :SRU ( u16:a i4:n -- u16 ) // calculated shift a = a>>n with 0<=n<=15 and $000F cpl // -1-n -1..-16 add srutab+1 // srtab+1-1-n = srtab-n dtmp ld cmd,alu // jp srtab-n pop alu :bit15 // a if 1 SRU15: ( u16 -- u16 ) // fixed shift right: a = a>>n with 0<=n<=15 ld sr,alu,nc :0 // a>>15 ld sr,alu,nc :0 // a>>14 ld sr,alu,nc :0 // a>>13 ld sr,alu,nc :0 // a>>12 ld sr,alu,nc :0 // a>>11 ld sr,alu,nc :0 // a>>10 ld sr,alu,nc :0 // a>>9 ld sr,alu,nc :0 // a>>8 ld sr,alu,nc :0 // a>>7 ld sr,alu,nc :0 // a>>6 ld sr,alu,nc :0 // a>>5 ld sr,alu,nc :0 // a>>4 ld sr,alu,nc :0 // a>>3 ld sr,alu,nc :0 // a>>2 ld sr,alu,nc :0 // a>>1 srutab next_op // a>>0 else nop // a>>15 ld sr,sr , nc // a>>14 ld sr,sr , nc // a>>13 ld sr,sr , nc // a>>12 ld sr,sr , nc // a>>11 ld sr,sr , nc // a>>10 ld sr,sr , nc // a>>9 ld sr,sr , nc // a>>8 ld sr,sr , nc // a>>7 ld sr,sr , nc // a>>6 ld sr,sr , nc // a>>5 ld sr,sr , nc // a>>4 ld sr,sr , nc // a>>3 ld sr,sr , nc // a>>2 ld sr,sr , nc // a>>1 ld alu,sr // a>>0 next_op then SRU0: = srutab ( int -- int ) // fixed shift right SRU1: = srutab-1 ( int -- int ) // single shift right // ============================================================ // other functions // ============================================================ // 2010-05-12 :RND1 ( -- i1 ) // one random bit psh alu return rnd,1 xor alu :rnd // * return if 1 // * return add_c alu // nodelay // * return next_op // post // * return else // * return next_op // * return then // * return // 2010-05-12 :RND ( -- i16 ) // 16 bit random number psh alu : rnd if 1 add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay add_c alu : rnd // nodelay ld cmd,(ip++) add_c alu :bit15 // nodelay else add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay add alu : rnd // nodelay ld cmd,(ip++) add alu :bit15 // nodelay then // ============================================================ // Characters // Is Uppercase? // (z.Zt. ASCII only) // is_uppercase(c) = uchar(c-'A')<='Z'-'A'; // // 2010-05-12 :IS_UPPERCASE ( u16:char -- i1 ) sub 'A' // dtmp cmp_nc 'Z'-'A' // dtmp ld cmd,(ip++) :cy if 0 xorn alu :bit15 // !cy => cy => char-A-1-(Z-A) < 0 => char-A ? Z-A => uppercase => true else xor alu :bit15 // cy => !cy => char-A-1 ? Z-A => char-1?Z => char>Z => not uppercase then // Is Letter? // (z.Zt. ASCII only) // is_letter(c) = uchar((c|0x20)-'a')<='z'-'a'; // // 2010-05-12 :IS_LETTER ( u16:char -- i1 ) or $20 jp IS_LOWERCASE // Is Lowercase? // (z.Zt. ASCII only) // is_lowercase(c) = uchar(c-'a')<='z'-'a'; // // 2010-05-12 :IS_LOWERCASE ( u16:char -- i1 ) sub 'a' // dtmp cmp_nc 'z'-'a' // dtmp ld cmd,(ip++) :cy if 0 xorn alu :bit15 // true else xor alu :bit15 // cy => !cy => char-a-1 ? z-a => char-1?z => char>z => not lowercase then // To Lowercase // (z.Zt. ASCII only) // to_lower(c) = uchar(c-'A')<='Z'-'A' ? c|0x20 : c; // // 2010-05-12 :TO_LOWER ( u16:char -- u16:char ) ld d2,alu // d2=char sub 'A' // dtmp cmp_nc 'Z'-'A' // dtmp if cy // cy => !cy => char-A-1 ? Z-A => char-1?Z => char>Z => !uppercase ld alu,d2 next_op // post else ld alu,$20 or d2 next_op // post then // To Uppercase // (z.Zt. ASCII only) // to_upper(c) = uchar(c-'a')<='z'-'a' ? c&~0x20 : c; // // 2010-05-12 :TO_UPPER ( u16:char -- u16:char ) ld d2,alu // d2=char sub 'a' // dtmp cmp_nc 'z'-'a' // dtmp if cy // cy => !cy => char-a-1 ? z-a => char-1?z => char>z => !lowercase => return as-is ld alu,d2 next_op // post else ld alu,~$20 // lowercase => and d2 // return to_upper next_op // post then // Is binary digit? // is_bin_digit(c) = (c|1)=='1'; // // 2010-05-12 :IS_BIN_DIGIT ( u16:char -- i1 ) or 1 ld dtmp,'1' // wg. delay equ dtmp ld cmd,(ip++) :z if 1 xorn alu :bit15 // true else xor alu :bit15 // no then // is octal digit? // is_oct_digit(c) = (c|7)=='7'; // // 2010-05-12 :IS_OCT_DIGIT ( u16:char -- i1 ) or 7 ld dtmp,'7' // wg. delay equ dtmp ld cmd,(ip++) :z if 1 xorn alu :bit15 // true else xor alu :bit15 // no then // is decimal digit? // is_dec_digit(c) = uchar(c-'0')<='9'-'0'; // // 2010-05-12 :IS_DEC_DIGIT ( u16:char -- i1 ) sub '0' // dtmp cmp_nc '9'-'0' // dtmp ld cmd,(ip++) :cy if 1 xor alu :bit15 // cy => !cy => char-'0'-1 ? '9'-'0' => char-1?'9' => char>'9' => no decdigit else xorn alu :bit15 // true then // is hexadecimal digit? // is_hex_digit(c) = uchar(c-'0')<='9'-'0' || uchar((c|0x20)-'a') <= 'f'-'a'; // // 2010-05-12 :IS_HEX_DIGIT ( u16:char -- i1 ) ld d2,alu // d2=char sub '0' // dtmp cmp_nc '9'-'0' // dtmp ld alu,d2 :cy // alu=char if 1 // cy => !cy => char>'9' => no dec. digit or $20 sub 'a' // dtmp cmp_nc 'f'-'a' // dtmp ld cmd,(ip++) :cy if 1 xor alu :bit15 // cy => !cy => c|20-a-1?f-a => c|20-1?f => c|20>f => no hex else xorn alu :bit15 // nc => yes then else // !cy => cy => char?'9' => dec. digit xorn alu // yes next_op // post then // value of decimal digit: // char --> digit value: ['0'..'9'] ---> [0..9]; non-digits ---> [10..255] // digit_val(char c) { return uchar(c-'0'); } // // 2010-05-12 DEC_DIGIT_VALUE := SUBQ+'0' ( u16:char -- u16 ) // sub '0' // dtmp // next_op // value of base36 digit: // char --> digit value: ['0'..'9']['A'..'Z']['a'..'z'] ---> [0...35]; non-digits ---> [36++] // digit_value(c) = c<='9' ? uchar(c-'0') : int(uchar((c&~0x20)-'A'))+10; // // 2010-05-12 :DIGIT_VALUE ( u16:char -- u16 ) cmp '9'+1 // dtmp jp !cy,SUBQ+'0' // !cy => cy => char<'9'+1 => char?'9' => rval > $FFC0 or $20 // to_lower sub 'a' // dtmp ld cmd,ival :cy if 0 dw NEXT :bit15 // !cy => cy => char<'a' => rval > $FFC0 else dw ADDQ+10 :bit15 // => legal 10 .. 36 or illegal >36 then // ============================================ // strings & arrays // ============================================ // 2010-05-11 // get string length: // disposes the handle // :STRLEN ( str -- len ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld a0,alu // a0=alu=handle ld d2ar,(a0) :z // d2ar -> len if 0 //del_handle: ld atmp,mem_free_ptr ld (a0),(atmp) // dtmp ld (atmp),alu ld alu,(d2ar) // alu=len next_op // post else next_op then // 2010-05-11 // get buffer length: // does not dispose the handle // :BUSIZE ( bu -- len ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d2ar,alu // d2ar=alu=handle ld d2ar,(d2ar) :z // d2ar=ptr if 0 ld alu,(d2ar) // alu=len next_op // post else next_op then // 2010-05-11 // compare two strings for equality: // :SAMECSTR ( str˘ str˘ -- i1 ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld a0,alu // a0=handle2 pop alu :z // alu=handle1 if 1 ld a0,null // a0==0 => a0=ptr->null else ld a0,(a0) // a0=ptr2 dtmp then ld a1,alu // handle1 if z ld a1,null // a1==0 => a1=ptr->null else ld a1,(a1) // a1=ptr1 dtmp then // a0 -> bu1 // a1 -> bu2 cmpstr: login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld atmp,(a0) // atmp=len1 dtmp // vergleich beider strings. // als erstes wird das length-word verglichen. do ld alu,(a0++) // alu=char2 equ (a1) // delay equ (a1++) // char2==char1? if !z // no xor alu // rval=0=no next_op // post then tst atmp-- // counter until z xorn alu // rval=-1=yes next_op // post // 2010-05-11 // compare strings for equality: // disposes the handle // :SAMESTR ( str1 str2 -- i1 ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d2ar,mem_free_ptr ld atmp,alu // atmp=alu=handle2 ld dtmp,(atmp) :z // dtmp=ptr2 if 0 ld a0,dtmp // a0=ptr2 // del handle: login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO ld (atmp),(d2ar) // dtmp ld (d2ar),alu else ld a0,null then pop alu ld atmp,alu // atmp=alu=handle1 ld dtmp,(atmp) :z // dtmp=ptr1 if 0 ld a1,dtmp // a1=ptr2 // del handle: login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO ld (atmp),(d2ar) // dtmp ld (d2ar),alu jp cmpstr else ld a1,null jp cmpstr then // ====================================================== // Strings: // >str = address of a string variable = ptr -> handle // str = handle = ptr -> temp mem ptr on temp mem heap // gstr = handle = ptr -> mem ptr #if 0//skipping: // 2010-05-11 // create new empty string: // STR: = LDQ ( -- str ) psh alu xor alu // len=0 => handle=NULL next_op // post #endif // 2010-05-11 // create new uncleared string with size: // NEWSTR: = ALLOC ( len -- str ) // 2010-05-11 // spacestr: // :CLEAREDSTR ( len filler -- str ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO pop d0 tst d0 // d0=len ld d1,alu , sp.oe,sp.clk,sub1 :z // d1=filler and --sp if 0 ld (sp),(ip++) // dtmp jp filled_str else inc hp // len=0 => handle=NULL next_op // post then // cleared buffer: // cleared with 0 // real handle even for size=0 // :CLEAREDBUFFER ( len -- str ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d0,alu, sp.clk,sp.oe,sub1 // size; --sp ld (sp),(ip++) // dtmp jp alloc // 2010-05-11 // str with immediate data in prg code: // :ISTR ( -- str ) psh alu ld d0,ip // d0=ptr ld alu,(ip++) // alu=cstr.len; ip->cstr.data add ip // alu->cstr.data+cstr.len ld ip,alu // ip->next_op jsr new_handle // a0=alu=handle ld (a0),d0 next_op // post // 2010-05-11 // duplicate string handle: // :DUPSTR ( str:bu -- str:bu str2 ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO psh alu // alu ld a1,alu :z // a1=handle1 if 0 jsr new_handle // a0=alu=handle ld (a0),(a1) // copy ptr1 dtmp next_op // post else next_op then #if 0//skipping: // 2010-05-11 // duplicate handle and data: // :COPYSTR ( str:bu -- str:bu str2 ) login TODO // memcnt psh alu // alu ld a0,alu :z // a0=handle1 if 0 ld d2ar,(a0) // d2ar=ptr1 ld d0,(d2ar) // d0=len1 jsr mem_assert_free // in:d0 ld d2ar,(a0) // d2ar=ptr1 ld d0,(d2ar) // d0=len1 pshr (ip++) // dtmp jp alloc_with_data else // copy empty string: next_op // ( NULL -- NULL NULL ) then #endif // 2010-05-11 // concatenate 2 strings // reuses one handle, drops the other // if one of both strings is NULL, then data is not copied! // :CATSTR ( str1 str2 -- str ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO ld a1,alu // a1=handle2 ld dtmp,(hp) :z if 0 ld a0,dtmp // a0=handle1 ld d2,a1 :z // d2=handle2 if 0 jsr mem_append_handle // delete handle2 ld a1,d2 ld d2ar,mem_free_ptr ld (a1),(d2ar) // dtmp ld (d2ar),d2 pop alu next_op // post else dec hp // string1=NULL => return string 2 next_op // post then else pop alu // string2=NULL => return string 1 next_op // post then // resize string // :RESIZESTR ( str size -- str ) // Not for Bytecode! login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld dtmp,(hp) ld a0,dtmp // a0=handle ld d0,alu :z // d0=new size if 0 jsr mem_resize_handle pop alu // alu=handle next_op // post else // str is NULL jsr alloc dec hp // nip NULL-handle next_op // post then // create substring // reuses the string handle // :LEFTSTR ( str len -- str ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d2ar,(hp) // delay ld d2ar,(hp) // handle ld a1,(d2ar) :z // a1=ptr dtmp if 0 cmp (a1) // len-str.len ld d0,alu :cy // d0=len if 0 // !cy => cy => len < str.len => substring jsr new_data_with_size // d0=len a1=ptr ld d2ar,(hp) // handle ld a0,(d2ar) // a0=qptr dtmp ld (d2ar),a1++ // *handle=ptr a1->zdata dtmp inc a0 // a0->qdata ld alu,d0 jsr memcpy then then pop alu // rval=handle next_op // post :RIGHTSTR ( str len -- str ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d2ar,(hp) // delay ld d2ar,(hp) // handle ld a1,(d2ar) :z // a1=ptr dtmp if 0 cmp (a1) // len-str.len ld d0,alu :cy // d0=len if 0 // !cy => cy => len2 < str1.len => return lhandle for copied data jsr new_data_with_size // d0=len a1=ptr pop d2ar // handle ld a0,(d2ar) // a0=qptr dtmp ld (d2ar),a1++ // *handle=ptr a1->zdata dtmp ld alu,(a0++) // alu=qlen, a0->qdata sub d0 // alu=qlen-len add a0 // alu->qdata+qlen-len ld a0,alu // a0->qdata+qlen-len ld alu,d0 // alu=len pshr DROP // pop alu + next_op jp memcpy // else // cy => !cy => len ? str.len => return self // pop alu // rval=handle // next_op // post then then pop alu // rval=handle next_op // post :MIDSTR ( str pos len -- str ) login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d0,alu // d0=zlen ld d1,(hp--) // d1=pos ld d2ar,(hp) // delay ld d2ar,(hp) // handle ld a0,(d2ar) :z // a0=ptr dtmp if 0 ld d2,(a0) // d2=qlen ld alu,d1 // alu=pos cmp d2 // pos-qlen if cy // cy => !cy => pos-qlen?0 => pos?qlen => return emptystr pop alu // alu=rval=handle ld a0,alu // a0=handle ld (a0),null next_op else // pos < qlen add d0 // alu=pos+zlen cmp d2 // pos+zlen-qlen if cy // cy => !cy => pos+zlen-qlen?0 => pos+zlen?qlen => zlen = qlen-pos ld alu,d2 // alu=qlen sub d1 // alu=qlen-pos=zlen ld d0,alu // d0=zlen then jsr new_data_with_size // in:d0 out:a1=ptr pop d2ar // d2ar=handle ld a0,(d2ar) // a0=qptr dtmp ld (d2ar),a1++ // *handle=ptr a1->zdata dtmp ld alu,a0 // alu=qptr add_c d1 // alu=qdata+pos ld a0,alu // a0->qdata+pos ld alu,d0 // alu=len pshr DROP // pop alu + next_op jp memcpy then then pop alu // rval=handle next_op // post :HEXSTR4 ( u16 -- str ) ld d0,4 // d0=digits jp hexstr :HEXSTR3 ( u16 -- str ) ld d0,3 // d0=digits jp hexstr :HEXSTR2 ( u16 -- str ) ld d0,2 // d0=digits jp hexstr :HEXSTR1 ( u16 -- str ) ld d0,1 // d0=digits jp hexstr :HEXSTR ( u16 digits -- str ) ld d0,1 sub d0 // alu=digits-1 => 0..3 and 3 // force legal add d0 // 1..4 ld d0,alu // d0=digits: 1..4 pop alu // jp hexstr hexstr: login ld io,alu,d_bits=10 // * login TODO // memcnt ld atmp,$ // * TODO jp TODO // * TODO ld d2,alu // d2=number jsr alloc // out:alu=a0=handle a1=ptr ld alu,a1 // alu=ptr add d0 // alu->zdata+len-1 ((last char)) ld a1,alu // a1->zdata.last_char ld sl,d2,nc if bit15 ld sr,sl,cy // sr=number else ld sr,sl,nc // sr=number then ld d1,10 // d1=10 ld d2,'A'-10 // d2='A'-10 do ld alu,sr and $0F cmp d1 // digit-10 if cy // cy => !cy => digit?10 add d2 // 'A'-10 else or '0' then ld (a1--),alu ld sr,sr,nc ld sr,sr,nc ld sr,sr,nc ld sr,sr,nc xorn alu // -1 add d0 // d0-1 ld d0,alu :z while 0 ld alu,a0 // rval=handle next_op // post // ======================================================= // IO Instructions // ======================================================= :EI( -- ) ei next_op // post :DI( -- ) di next_op // post :SELECT ( i16:sel_mask -- ) // DI and SELECT DEVICE di ld io_select,alu pop alu next_op // post :SELECTI ( -- ) // DI and SELECT DEVICE di ld io_select,(ip++) next_op // post :DESELECT ( -- ) ld io_select,$ffff ei next_op // post : INI % $100 ( -- n ) // cmd_lo = address ld ioaddr,cmd_lo psh alu ld alu,io_data next_op // post : IN ( a -- n ) ld ioaddr,alu ld alu,io_data next_op // post : INI2 % $100 ( -- n ) // cmd_lo = address ld ioaddr,cmd_lo psh alu clr clock2 ld alu,io_data set clock2 next_op // post : IN2 ( a -- n ) ld ioaddr,alu clr clock2 ld alu,io_data set clock2 next_op // post : INI4 % $100 ( -- n ) // cmd_lo = address ld ioaddr,cmd_lo psh alu clr clock4 ld alu,io_data set clock4 next_op // post : IN4 ( a -- n ) ld ioaddr,alu clr clock4 ld alu,io_data set clock4 next_op // post : INI8 % $100 ( -- n ) // cmd_lo = address ld ioaddr,cmd_lo psh alu clr clock2 clr clock4 ld alu,io_data set clock4 set clock2 next_op // post : IN8 ( a -- n ) ld ioaddr,alu clr clock2 clr clock4 ld alu,io_data set clock4 set clock2 next_op // post : OUTI % $100 ( n -- ) // cmd_lo = address ld ioaddr,cmd_lo ld io_data,alu ld io_dummy,alu pop alu next_op // post : OUT ( n a -- ) ld ioaddr,alu pop alu ld io_data,alu ld io_dummy,alu pop alu next_op // post : OUTI2 % $100 ( n -- ) // cmd_lo = address ld ioaddr,cmd_lo clr clock2 ld io_data,alu ld io_dummy,alu set clock2 pop alu next_op // post : OUT2 ( n a -- ) ld ioaddr,alu pop alu clr clock2 ld io_data,alu ld io_dummy,alu set clock2 pop alu next_op // post : OUTI4 % $100 ( n -- ) // cmd_lo = address ld ioaddr,cmd_lo clr clock4 ld io_data,alu ld io_dummy,alu set clock4 pop alu next_op // post : OUT4 ( n a -- ) ld ioaddr,alu pop alu clr clock4 ld io_data,alu ld io_dummy,alu set clock4 pop alu next_op // post : OUTI8 % $100 ( n -- ) // cmd_lo = address ld ioaddr,cmd_lo clr clock2 clr clock4 ld io_data,alu ld io_dummy,alu set clock4 set clock2 pop alu next_op // post : OUT8 ( n a -- ) ld ioaddr,alu pop alu clr clock2 clr clock4 ld io_data,alu ld io_dummy,alu set clock4 set clock2 pop alu next_op // post :BIN8 ( bu[]˘ i n a -- ) // in ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :BIN4 ( bu[]˘ i n a -- ) // in ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :BIN2 ( bu[]˘ i n a -- ) // in ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :BIN ( bu[]˘ i n a -- ) // in ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :BOUT8 ( bu[]˘ i n a -- ) // out ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :BOUT4 ( bu[]˘ i n a -- ) // out ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :BOUT2 ( bu[]˘ i n a -- ) // out ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :BOUT ( bu[]˘ i n a -- ) // out ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :FBOUT8 ( bu[]˘ i n a -- ) // out ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :FBOUT4 ( bu[]˘ i n a -- ) // out ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :FBOUT2 ( bu[]˘ i n a -- ) // out ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO :FBOUT ( bu[]˘ i n a -- ) // out ( bu[?] io_addr -- ) login ld io,alu,d_bits=10 // * login TODO ld atmp,$ // * TODO jp TODO // * TODO // multi-Drop: // DROP0-i3 -> drop i3 words // :DROP8 ( x x x x x x x x -- ) pop alu pop alu pop alu pop alu pop alu pop alu pop alu pop alu DROP0: next_op :DROP8_RET ( x x x x x x x x -- ) pop alu pop alu pop alu pop alu pop alu pop alu pop alu pop alu DROP0_RET: popr ip // dtmp next_op // multi-Nip: // NIP0-i3 -> nip i3 words over int16 // :NIP8 ( x x x x x x x x a -- a ) dec hp dec hp dec hp dec hp dec hp dec hp dec hp dec hp NIP0: next_op :NIP8_RET ( x x x x x x x x a -- a ) dec hp dec hp dec hp dec hp dec hp dec hp dec hp dec hp NIP0_RET: popr ip // dtmp next_op NIP := NIP0-1 ( a b -- b ) DROP := DROP0-1 ( x -- ) DROP2 := DROP0-2 ( x x -- ) DROP3 := DROP0-3 ( x x x -- ) DROP_RET := DROP0_RET-1 ( x -- ) DROP2_RET := DROP0_RET-2 ( x x -- ) DROP3_RET := DROP0_RET-3 ( x x x -- ) // --- file: "opcodes.asm" --- #include "stdc.cc" // +++ file: "stdc.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : hexstr__6uint16_8ucs2charAE ( uint16 -- ucs2str ) psh alu ld alu,4 jp hexstr__6uint16_6uint16_8ucs2charAE : hexstr__6uint16_6uint16_8ucs2charAE ( uint16, uint16 -- ucs2str ) /* digits=(digits-1)&3+1 str s=new str(digits) do{ while digits-- s[digits] = hexchar(number) number>>=4 } next_m s */ ld dtmp,1 sub dtmp and 3 add dtmp // alu = digits ld d0,alu // d0=digits jsr alloc // alu=a0=handle a1=memptr ld atmp,d0 // atmp = digits ld alu,d0 add a1 // alu -> last digit ld sl,(hp--),nc // pop sr ld a1,alu :bit15 // a1 -> last digit if 1 ld sr,sl,cy // pop sr ctd. else ld sr,sl,nc // pop sr ctd. then ld dtmp,9 jp p1 do ld alu,sr and $F cmp_nc dtmp // cmp 9 or ival :cy if 1 // cy => !cy => alu?10 dw $40 nop,alu.clk,dtmp.oe,sub // alu -= 'A'-$40-10 $4A..$4F -> 'A'..'F' else dw '0' // => '0'..'9' then ld (a1--),alu ld sr,sr,nc ld sr,sr,nc ld sr,sr,nc ld sr,sr,nc p1 tst atmp-- while !z ld alu,a0 // rval = str handle next_m next_mc // * next_m : numstr__5int16_8ucs2charAE ( int16 -- ucs2str ) Millicoded // Size: 19 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+0 mc Lt mc BraIf0+8 mc Istr+1 dm '-' ld cmd,atmp mc Lget+255 mc Neg mc numstr__6uint16_8ucs2charAE mc CatStrStr mc Bra+2 mc Dup mc numstr__6uint16_8ucs2charAE mc MNip0_Next-1 : numstr__6uint16_8ucs2charAE ( uint16 -- ucs2str ) Millicoded // Size: 30 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Log10 mc Addq+1 mc Dup mc Alloc mc Int8+48 mc Lget+253 mc Int8+10 mc Remu mc Add mc Lget+255 mc Lvar+253 mc mmPeek mc AtIndexPoke mc Int8+10 mc Lvar+253 mc DivuPoke mc Lget+254 mc BraIf1-14 mc Dup mc Retain mc ToR mc DropStr mc MDrop0-2 mc FromR mc Ret : abort__8ucs2charAE_ ( ucs2str ) Millicoded // Size: 20 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Istr+8 dm 10 dm 'A' dm 'b' dm 'o' dm 'r' dm 't' dm ':' dm ' ' ld cmd,atmp mc LogStr mc Dup mc LogCstr mc Abort mc DropStr mc Ret : PANIC__8ucs2charAE_ ( ucs2str ) Millicoded // Size: 20 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Istr+8 dm 10 dm 'P' dm 'a' dm 'n' dm 'i' dm 'c' dm ':' dm ' ' ld cmd,atmp mc LogStr mc Dup mc LogCstr mc Panic mc DropStr mc Ret : op__MOD__5int16_6uint16_5int16 ( int16, uint16 -- int16 ) Millicoded // Size: 19 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Int8+0 mc Lt mc BraIf0+6 mc Lget+255 mc Neg mc Lget+255 mc Remu mc Neg mc Bra+3 mc Lget+255 mc Lget+255 mc Remu mc Lset+255 mc MDrop0_Next-1 : op__GE__6uint16_5int16_4bool ( uint16, int16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+0 mc Lt mc Or1 mc Bra+3 mc Lget+255 mc Lget+255 mc Uge mc MNip0_Next-2 : op__GT__6uint16_5int16_4bool ( uint16, int16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+0 mc Lt mc Or1 mc Bra+3 mc Lget+255 mc Lget+255 mc Ugt mc MNip0_Next-2 : op__LE__6uint16_5int16_4bool ( uint16, int16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+0 mc Ge mc And0 mc Bra+3 mc Lget+255 mc Lget+255 mc Ule mc MNip0_Next-2 : op__LT__6uint16_5int16_4bool ( uint16, int16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+0 mc Ge mc And0 mc Bra+3 mc Lget+255 mc Lget+255 mc Ult mc MNip0_Next-2 : op__LE__5int16_6uint16_4bool ( int16, uint16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Int8+0 mc Lt mc Or1 mc Bra+3 mc Lget+255 mc Lget+255 mc Ule mc MNip0_Next-2 : op__LT__5int16_6uint16_4bool ( int16, uint16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Int8+0 mc Lt mc Or1 mc Bra+3 mc Lget+255 mc Lget+255 mc Ult mc MNip0_Next-2 : op__GT__5int16_6uint16_4bool ( int16, uint16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Int8+0 mc Ge mc And0 mc Bra+3 mc Lget+255 mc Lget+255 mc Ugt mc MNip0_Next-2 : op__GE__5int16_6uint16_4bool ( int16, uint16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Int8+0 mc Ge mc And0 mc Bra+3 mc Lget+255 mc Lget+255 mc Uge mc MNip0_Next-2 : op__EQ__5int16_6uint16_4bool ( int16, uint16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc Eq mc And0 mc Bra+3 mc Lget+255 mc Int8+0 mc Ge mc MNip0_Next-2 : op__NE__5int16_6uint16_4bool ( int16, uint16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc Ne mc Or1 mc Bra+3 mc Lget+255 mc Int8+0 mc Lt mc MNip0_Next-2 : op__EQ__6uint16_5int16_4bool ( uint16, int16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Lget+254 mc Eq mc And0 mc Bra+3 mc Dup mc Int8+0 mc Ge mc MNip0_Next-2 : op__NE__6uint16_5int16_4bool ( uint16, int16 -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Lget+254 mc Ne mc Or1 mc Bra+3 mc Dup mc Int8+0 mc Lt mc MNip0_Next-2 : hexchar__6uint16_5int16 ( uint16 -- int16 ) // n&=$F next_m n>9u ? 'A'-10+n : '0'+n and $F ld dtmp,9 cmp_nc dtmp or ival :cy if 1 // cy => !cy => alu?10 dw $40 nop,alu.clk,dtmp.oe,sub // alu += 'A'-$40-10: $4A..$4F -> 'A'..'F' else dw '0' // => '0'..'9' then next_m next_mc // * next_m : catstr__8ucs2charAE_8ucs2charAE_8ucs2charAE ( ucs2str, ucs2str -- ucs2str ) Millicoded // Size: 37 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Count mc Lget+255 mc Count mc Lget+255 mc Lget+255 mc Add mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+251 mc Int8+0 mc AtIndex mc Lget+252 mc TradMemCpy mc Dup mc Lget+253 mc AtIndex mc Lget+252 mc Int8+0 mc AtIndex mc Lget+253 mc TradMemCpy mc Dup mc Retain mc Lvar+251 mc SwapWithVar mc DropStr mc DropStr mc MDrop0-2 mc DropStr mc Ret // --- file: "stdc.asm" --- #include "long.cc" // +++ file: "long.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : abs__5int32_6uint32 ( int32 -- uint32 ) Millicoded // Size: 20 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lvar+255 mc Peek2 mc Int8+0 mc Int8+0 mc GeL mc BraIf0+3 mc Lvar+255 mc Peek2 mc Bra+3 mc Lvar+255 mc Peek2 mc NegL mc ToR2 mc MDrop0-2 mc FromR2 mc Ret : min__6uint32_6uint32_6uint32 ( uint32, uint32 -- uint32 ) Millicoded // Size: 18 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lvar+253 mc Peek2 mc Lvar+253 mc Peek2 mc LtUL mc BraIf0+3 mc Lvar+253 mc Peek2 mc Bra+2 mc Lvar+255 mc Peek2 mc Lvar+251 mc Poke2 mc MDrop0_Next-2 : random__6uint32 ( -- uint32 ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc random__6uint16 mc random__6uint16 mc Next : hexstr__6uint32_6uint16_8ucs2charAE ( uint32, uint16 -- ucs2str ) Millicoded // Size: 27 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Subq+1 mc Int8+7 mc And mc Addq+1 mc Nip mc Dup mc Int8+4 mc Ugt mc BraIf0+9 mc Lget+254 mc Lget+255 mc Subq+4 mc hexstr__6uint16_6uint16_8ucs2charAE mc Lget+254 mc Int8+4 mc hexstr__6uint16_6uint16_8ucs2charAE mc CatStrStr mc Bra+3 mc Lget+255 mc Lget+255 mc hexstr__6uint16_6uint16_8ucs2charAE mc MNip0_Next-3 : numstr__5int32_8ucs2charAE ( int32 -- ucs2str ) Millicoded // Size: 21 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Int8+0 mc Lt mc BraIf0+9 mc Istr+1 dm '-' ld cmd,atmp mc Lvar+254 mc Peek2 mc NegL mc numstr__6uint32_8ucs2charAE mc CatStrStr mc Bra+3 mc Lvar+255 mc Peek2 mc numstr__6uint32_8ucs2charAE mc MNip0_Next-2 : numstr__6uint32_8ucs2charAE ( uint32 -- ucs2str ) Millicoded // Size: 132 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc BraIf0+121 mc Int8+0 mc Int8+0 mc Int8+0 mc Int8+0 mc Lvar+251 mc Peek2 mc Int8+154 mc Int16+59 mc Int8+0 mc Int16+202 mc GeUL mc BraIf0+33 mc Int8+49 mc Lset+255 mc Int8+154 mc Int16+59 mc Int8+0 mc Int16+202 mc Lvar+249 mc SubPokeL mc Lvar+251 mc Peek2 mc Int8+154 mc Int16+59 mc Int8+0 mc Int16+202 mc GeUL mc BraIf0+4 mc Int8+1 mc Lvar+254 mc AddPoke mc Bra-18 mc Int8+10 mc Lset+253 mc Int8+10 mc Alloc mc Lvar+255 mc SwapWithVar mc DropStr mc Lget+255 mc Lget+255 mc Lvar+252 mc Peekpp mc AtIndexPoke mc Bra+29 mc Int8+9 mc Lset+253 mc Lvar+251 mc Peek2 mc Int8+245 mc Int16+5 mc Int8+0 mc Int16+225 mc LtUL mc BraIf0+14 mc Int8+1 mc Lvar+252 mc SubPoke mc Lvar+251 mc Peek2 mc Lvar+249 mc AddPokeL mc Lvar+251 mc Peek2 mc Int8+2 mc SlL mc Lvar+249 mc AddPokeL mc Bra-22 mc Lget+253 mc Alloc mc Lvar+255 mc SwapWithVar mc DropStr mc Lget+254 mc Lget+252 mc Ult mc BraIf0+36 mc Int8+48 mc Lset+255 mc Lvar+251 mc Peek2 mc Int8+245 mc Int16+5 mc Int8+0 mc Int16+225 mc GeUL mc BraIf0+10 mc Int8+1 mc Lvar+254 mc AddPoke mc Int8+245 mc Int16+5 mc Int8+0 mc Int16+225 mc Lvar+249 mc SubPokeL mc Bra-18 mc Lget+255 mc Lget+255 mc Lvar+252 mc Peekpp mc AtIndexPoke mc Lvar+251 mc Peek2 mc Lvar+249 mc AddPokeL mc Lvar+251 mc Peek2 mc Int8+2 mc SlL mc Lvar+249 mc AddPokeL mc Bra-40 mc Dup mc Retain mc ToR mc DropStr mc MDrop0-3 mc FromR mc Bra+4 mc Lvar+255 mc Addq+1 mc Peek mc numstr__6uint16_8ucs2charAE mc MNip0_Next-2 : new__5int16_5int32 ( int16 -- int32 ) tst alu psh ival :bit15 if 0 dw 0 else dw $ffff then next_m next_mc // * next_m : new__6uint16_6uint32 ( uint16 -- uint32 ) psh 0 next_m next_mc // * next_m : msbit__5int32_5int16 ( int32 -- int16 ) // next_m n.h ? msbit(n.h)+16 : msbit(n.l) tst (hp) // delay tst (hp) pop dtmp :z if 1 ldn alu ld msbit,alu ld alu,msbit next_m next_mc // * next_m else ldn dtmp ld msbit,alu ld alu,msbit or 16 next_m next_mc // * next_m then : mulu_16_32__6uint16_6uint16_6uint32 ( uint16, uint16 -- uint32 ) // ulong r,c // if a>b swap(a,b) // sort: a < b // c.l=b // do{ // while a // if a&1 r += c // a >>= 1 // c <<= 1 // } // next_m r ld d0,(hp) // d0 = a; alu = b cmp_nc d0 // b-a-1 if cy // cy => !cy => alu?d0+1 => swap ld d0,alu // d0 = alu ld alu,(hp) // alu = d0 then // alu = a ? d0 = b = c.l ld sl,0,nc // sl,d0 = c ld d1,sl ld d2,sl // d2.d1 = r ld sr,alu,nc // sr = a ld cmd,ival :bit0 if 1 dw a :bit15 else dw na :bit15 then do // while a != 0 ld sr,sr,nc // next bit if bit0 // if a&1 then r += c a ld alu,d0 add d1 ld d1,alu :cy if 1 ld alu,sl add_c d2 else ld alu,sl add d2 then ld d2,alu then // c <<= 1 na ld alu,d0 // alu = c.l add alu // nodelay ld d0,alu : cy // c.l <<= 1 if 1 ld sl,sl,cy // c.h <<= 1 + cy else ld sl,sl,nc then tst sr // a == 0? while !z // no => loop // result = d2.d1 ld (hp),d2 ld alu,d1 next_m next_mc // * next_m : mul10__6uint32_6uint32 ( uint32 -- uint32 ) add alu // nodelay if cy ld sl,(hp),cy else ld sl,(hp),nc // sl.alu = x*2 then ld d0,alu ld d1,sl // d1.d0 = x*2 add alu // nodelay if cy ld sl,sl,cy else ld sl,sl,nc // sl.alu = x*4 then add alu // nodelay if cy ld sl,sl,cy else ld sl,sl,nc // sl.alu = x*8 then add d0 ld d0,alu :cy if 1 ld alu,sl add_c d1 else ld alu,sl add d1 then ld (hp),alu ld alu,d0 next_m next_mc // * next_m : exp10l__6uint16_6uint32 ( uint16 -- uint32 ) // if x<=4 next_m exp10 uint(x) // next_m x<=6 ? x==5?100000:1000000 : x==7?10000000:x==8?100000000:1000000000 cmp 10 // dtmp if !cy // !cy => cy => x<10 add alu // nodelay add tab1 // dtmp inc hp // prepare psh ld cmd,alu ld (hp),ival :bit15 tab1 dm 0,0,0,0,0, 1e5>>16, 1e6>>16, 1e7>>16, 1e8>>16, 1e9>>16 add tab2-tab1 // dtmp ld cmd,alu ld alu,ival :bit15 tab2 dm 1,10,100,1e3,1e4, 1e5&$ffff, 1e6&$ffff, 1e7&$ffff, 1e8&$ffff, 1e9&$ffff else xor alu psh alu then next_m next_mc // * next_m : log10__6uint32_6uint16 ( uint32 -- uint16 ) // if x.h next_m x<1000000 ? x<10?1:2 : x<10000 ? x<1000?3:4 : 5 // else next_m log10(x.l) tst (hp) // delay pop d1 ld d0,alu :z // x = d1.d0 jp 1,Log10 // if x.h==0 next_m log10(x.l) instr lt_32(AH,AL,NN) ld alu,AH equ NN>>16 :z if 1 // a.h==n.h ? ld alu,AL // => compare a.l and n.l ld dtmp,NN&$ffff else ld alu,AH ld dtmp,NN>>16 then cmp dtmp // A-N: cy => !cy => A?N ld alu,d2 :cy // !cy => cy => A>16 :z // * lt_32 if 1 // a.h==n.h ? // * lt_32 ld alu,d0 // => compare a.l and n.l // * lt_32 ld dtmp,1e7 &$ffff // * lt_32 else // * lt_32 ld alu,d1 // * lt_32 ld dtmp,1e7 >>16 // * lt_32 then // * lt_32 cmp dtmp // A-N: cy => !cy => A?N // * lt_32 ld alu,d2 :cy // !cy => cy => A>16 :z // * lt_32 if 1 // a.h==n.h ? // * lt_32 ld alu,d0 // => compare a.l and n.l // * lt_32 ld dtmp,1e6 &$ffff // * lt_32 else // * lt_32 ld alu,d1 // * lt_32 ld dtmp,1e6 >>16 // * lt_32 then // * lt_32 cmp dtmp // A-N: cy => !cy => A?N // * lt_32 ld alu,d2 :cy // !cy => cy => A>16 :z // * lt_32 if 1 // a.h==n.h ? // * lt_32 ld alu,d0 // => compare a.l and n.l // * lt_32 ld dtmp,1e5 &$ffff // * lt_32 else // * lt_32 ld alu,d1 // * lt_32 ld dtmp,1e5 >>16 // * lt_32 then // * lt_32 cmp dtmp // A-N: cy => !cy => A?N // * lt_32 ld alu,d2 :cy // !cy => cy => A>16 :z // * lt_32 if 1 // a.h==n.h ? // * lt_32 ld alu,d0 // => compare a.l and n.l // * lt_32 ld dtmp,1e9 &$ffff // * lt_32 else // * lt_32 ld alu,d1 // * lt_32 ld dtmp,1e9 >>16 // * lt_32 then // * lt_32 cmp dtmp // A-N: cy => !cy => A?N // * lt_32 ld alu,d2 :cy // !cy => cy => A>16 :z // * lt_32 if 1 // a.h==n.h ? // * lt_32 ld alu,d0 // => compare a.l and n.l // * lt_32 ld dtmp,1e8 &$ffff // * lt_32 else // * lt_32 ld alu,d1 // * lt_32 ld dtmp,1e8 >>16 // * lt_32 then // * lt_32 cmp dtmp // A-N: cy => !cy => A?N // * lt_32 ld alu,d2 :cy // !cy => cy => A(int)b.h : a.l>b.l ld d2,alu // d2=b.l pop alu,d0,dtmp // a=dtmp.d0; b=alu.d2 equ dtmp // b.h==a.h? ld cmd,ival :z if 1 dw ougt :bit15 // => (uint)a.l>(uint)b.l else dw ogt :bit15 // !> (int)a.h>(int)b.h (( Gt() in millicode_int.asm )) then next_m next_mc // * next_m : op__GE__5int32_5int32_5int16 ( int32, int32 -- int16 ) // next_m a.h!=b.h ? (int)a.h>(int)b.h : a.l>=b.l ld d1,alu // d1=b.l pop alu,d0,dtmp // a=dtmp.d0; b=alu.d1 equ dtmp // b.h==a.h? ld cmd,ival :z if 1 dw ouge :bit15 // => (uint)a.l>=(uint)b.l else dw oge :bit15 // !> (int)a.h>=(int)b.h (( Ge() in millicode_int.asm )) then next_m next_mc // * next_m : op__LT__5int32_5int32_5int16 ( int32, int32 -- int16 ) // next_m a.h!=b.h ? (int)a.h<(int)b.h : a.l (uint)a.l<(uint)b.l else dw olt :bit15 // !> (int)a.h<(int)b.h (( Lt() in millicode_int.asm )) then next_m next_mc // * next_m : op__LE__5int32_5int32_5int16 ( int32, int32 -- int16 ) // next_m a.h!=b.h ? (int)a.h<(int)b.h : a.l<=b.l ld d2,alu // d2=b.l pop alu,d0,dtmp // a=dtmp.d0; b=alu.d2 equ dtmp // b.h==a.h? ld cmd,ival :z if 1 dw oule :bit15 // => (uint)a.l<=(uint)b.l else dw ole :bit15 // !> (int)a.h<=(int)b.h (( Le() in millicode_int.asm )) then next_m next_mc // * next_m : op__NE__5int32_5int32_5int16 ( int32, int32 -- int16 ) // next_m a.h!=b.h || a.l!=b.l pop d0,d1,d2 xor d1 xor alu :z if 0 add_c alu // => 1 = yes nodelay next_m next_mc // * next_m else ld alu,d0 equ d2 xor alu :z if 0 add_c alu // => 1 = yes nodelay then next_m next_mc // * next_m then : op__EQ__5int32_5int32_5int16 ( int32, int32 -- int16 ) // next_m a.h==b.h && a.l==b.l pop d0,d1,d2 xor d1 xor alu :z if 0 next_m // => 0 = no next_mc // * next_m else ld alu,d0 equ d2 xor alu :z if 1 add_c alu // => 1 = yes nodelay then next_m next_mc // * next_m then : op__CPL__4void_5int32_6uint32 ( void, int32 -- uint32 ) ld dtmp,alu ldn (hp) ld (hp),alu ldn dtmp next_m next_mc // * next_m : op__SUB__4void_5int32_5int32 ( void, int32 -- int32 ) ld atmp,alu dec atmp :z if 0 ldn (hp) // a.l!=0 => kein übertrag => a.h := ~a.h else //xor alu // a.l==0 => übertrag => a.h := -a.h sub_nc (hp) then ld (hp),alu ldn atmp next_m next_mc // * next_m : op__ADD__5int32_5int32_5int32 ( int32, int32 -- int32 ) // alu = b.l pop d1 // d1 = b.h add (hp--) // alu = b.l+a.l ld d2,alu :cy // d2 = b.l+a.l if 1 ld alu,(hp) // alu = a.h add_c d1 // alu = a.h+b.h+cy else ld alu,(hp) // alu = a.h add d1 // alu = a.h+b.h then ld (hp),alu // a.h+b.h ld alu,d2 // a.l+b.l next_m next_mc // * next_m : op__SUB__5int32_5int32_5int32 ( int32, int32 -- int32 ) // note: a-b = a+(~b)+1 cpl // alu = ~b.l pop d1 // d1 = b.h add_c (hp--) // alu = a.l + ~b.l + 1 ld d2,alu :cy if 1 ldn d1 // alu = ~b.h add_c (hp) // alu = a.h + ~b.h + 1 else ldn d1 // alu = ~b.h add (hp) // alu = a.h + ~b.h then ld (hp),alu // a.h+b.h ld alu,d2 // a.l+b.l next_m next_mc // * next_m : op__MUL__5int32_5int32_5int32 ( int32, int32 -- int32 ) Millicoded // Size: 51 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Int8+0 mc Int16+128 mc And mc BraIf0+21 mc Lget+255 mc Int8+0 mc Int16+128 mc And mc BraIf0+8 mc Lvar+253 mc Peek2 mc NegL mc Lvar+253 mc Peek2 mc NegL mc MulUL mc Bra+26 mc Lvar+253 mc Peek2 mc NegL mc Lvar+253 mc Peek2 mc MulUL mc NegL mc Bra+18 mc Lget+255 mc Int8+0 mc Int16+128 mc And mc BraIf0+8 mc Lvar+253 mc Peek2 mc Lvar+253 mc Peek2 mc NegL mc MulUL mc NegL mc Bra+5 mc Lvar+253 mc Peek2 mc Lvar+253 mc Peek2 mc MulUL mc Lvar+251 mc Poke2 mc MDrop0_Next-2 : op__DIV__5int32_5int32_5int32 ( int32, int32 -- int32 ) Millicoded // Size: 51 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Int8+0 mc Int16+128 mc And mc BraIf0+21 mc Lget+255 mc Int8+0 mc Int16+128 mc And mc BraIf0+8 mc Lvar+253 mc Peek2 mc NegL mc Lvar+253 mc Peek2 mc NegL mc DivUL mc Bra+26 mc Lvar+253 mc Peek2 mc NegL mc Lvar+253 mc Peek2 mc DivUL mc NegL mc Bra+18 mc Lget+255 mc Int8+0 mc Int16+128 mc And mc BraIf0+8 mc Lvar+253 mc Peek2 mc Lvar+253 mc Peek2 mc NegL mc DivUL mc NegL mc Bra+5 mc Lvar+253 mc Peek2 mc Lvar+253 mc Peek2 mc DivUL mc Lvar+251 mc Poke2 mc MDrop0_Next-2 : op__AND__5int32_5int32_5int32 ( int32, int32 -- int32 ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lvar+252 mc AndPoke mc Lvar+255 mc Addq+1 mc Peek mc Lvar+253 mc AndPoke mc MDrop0_Next-2 : op__OR__5int32_5int32_5int32 ( int32, int32 -- int32 ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lvar+252 mc OrPoke mc Lvar+255 mc Addq+1 mc Peek mc Lvar+253 mc OrPoke mc MDrop0_Next-2 : op__XOR__5int32_5int32_5int32 ( int32, int32 -- int32 ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lvar+252 mc XorPoke mc Lvar+255 mc Addq+1 mc Peek mc Lvar+253 mc XorPoke mc MDrop0_Next-2 : op__GT__6uint32_6uint32_5int16 ( uint32, uint32 -- int16 ) // next_m a.h!=b.h ? a.h>b.h : a.l>b.l ld d2,alu // d2=b.l pop alu,d0,dtmp // a=dtmp.d0; b=alu.d2 equ dtmp // b.h==a.h? if z // if a.h==b.h ougt: ld alu,d2 // then compare a.l with b.l else ld d0,dtmp // else compare a.h with b.h then cmp d0 xor alu :cy if 0 // !cy => cy => alu bb.h : a.l>=b.l ld d1,alu // d1=b.l pop alu,d0,dtmp // a=dtmp.d0; b=alu.d1 equ dtmp // b.h==a.h? if z // if a.h==b.h ouge: ld alu,d1 // then compare a.l with b.l else ld d0,dtmp then cmp_nc d0 xor alu :cy if 0 // !cy => cy => alu b?a add_c alu // nodelay then next_m next_mc // * next_m : op__LT__6uint32_6uint32_5int16 ( uint32, uint32 -- int16 ) // next_m a.h!=b.h ? a.h !cy => alu?d1+1 => b>a add_c alu // nodelay then next_m next_mc // * next_m : op__LE__6uint32_6uint32_5int16 ( uint32, uint32 -- int16 ) // next_m a.h!=b.h ? a.h !cy => alu?d1 => b?a add_c alu // nodelay then next_m next_mc // * next_m : op__MUL__6uint32_6uint32_6uint32 ( uint32, uint32 -- uint32 ) Millicoded // Size: 26 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc Lget+255 mc mulu_16_32__6uint16_6uint16_6uint32 mc Lget+251 mc BraIf0+5 mc Lget+251 mc Lget+253 mc Mulu mc Lvar+254 mc AddPoke mc Lget+253 mc BraIf0+5 mc Lget+252 mc Lget+252 mc Mulu mc Lvar+254 mc AddPoke mc Lvar+255 mc Peek2 mc Lvar+249 mc Poke2 mc MDrop0_Next-4 : op__DIV__6uint32_6uint32_6uint32 ( uint32, uint32 -- uint32 ) Millicoded // Size: 97 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Int8+0 mc Int8+0 mc Int8+0 mc Int8+0 mc Lvar+248 mc Peek2 mc Lvar+248 mc Peek2 mc GeUL mc BraIf0+77 mc Lget+250 mc Or1 mc Bra+1 mc Lget+251 mc BraIf0+66 mc Lvar+248 mc Peek2 mc msbit__5int32_5int16 mc Lvar+249 mc Peek2 mc msbit__5int32_5int16 mc Sub mc Nip mc Lvar+248 mc Peek2 mc Lget+254 mc SrUL mc Lvar+252 mc Poke2 mc Lvar+248 mc Peek2 mc Int8+32 mc Lget+253 mc Sub mc SlL mc Lvar+246 mc Poke2 mc Lvar+252 mc Peek2 mc Int8+1 mc SlL mc Lvar+250 mc Poke2 mc Lvar+254 mc Peek2 mc Lvar+248 mc Peek2 mc GeUL mc BraIf0+8 mc Int8+0 mc Int8+1 mc Lvar+250 mc AddPokeL mc Lvar+250 mc Peek2 mc Lvar+252 mc SubPokeL mc Lvar+254 mc Peek2 mc Int8+1 mc SlL mc Lvar+252 mc Poke2 mc Lget+248 mc Int8+0 mc Int16+128 mc And mc BraIf0+3 mc Int8+1 mc Lvar+254 mc AddPoke mc Lvar+248 mc Peek2 mc Int8+1 mc SlL mc Lvar+246 mc Poke2 mc PshHP mc Peekmm mc BraIf0+7 mc Bra-44 mc Int8+255 mc Int16+255 mc Int8+255 mc Int16+255 mc Lvar+250 mc Poke2 mc Lvar+252 mc Peek2 mc Lvar+246 mc Poke2 mc MDrop0_Next-7 : op__SR__6uint32_5int16_6uint32 ( uint32, int16 -- uint32 ) // if d & $10 { n.l=n.h n.h=0 } // d &= $F // if d // { // n.l = n.l>>d + n.h<<(16-d) // n.h = n.h>>d // } // next_m n pop d0 // d0 = n.l ld d1,(hp) // d1 = n.h tst_and $10 :z // d ? 16 ? if 0 // shift distance ? 16 => n.l = n.h>>d // n.h = 0 ld (hp++),0 // n.h = 0 ld (hp),d1 // n.l = n.h jp Sru else // shift distance < 16 // shift across word boundary: and $F ld atmp,alu jp p1 do ld sr,d1,nc ld d1,sr :bit0 if 1 ld sr,d0,cy else ld sr,d0,nc then ld d0,sr p1 tst atmp-- until z ld (hp),d1 // n.h back on stack ld alu,d0 // alu = top = n.l next_m next_mc // * next_m then : op__SL__6uint32_5int16_6uint32 ( uint32, int16 -- uint32 ) // if d & $10 { n.h=n.l n.l=0 } // d &= $F // if d // { // n.h = n.h<>(16-d) // n.l = n.l< n.h = n.l< n.l=0 jp sln else // shift distance < 16 // shift across word boundary: and $F ld atmp,alu jp p1 do ld sl,d0,nc ld d0,sl :bit15 if 1 ld sl,d1,cy else ld sl,d1,nc then ld d1,sl p1 tst atmp-- until z ld (hp),d1 // n.h back on stack ld alu,d0 // alu = top = n.l next_m next_mc // * next_m then : op__SUB__5int32_5int16_5int32 ( int32, int16 -- int32 ) tst alu,hp.clk,hp.oe,add1 ld (hp),ival :bit15 if 1 dw $FFFF else dw 0 then jp op__SUB__5int32_5int32_5int32 : op__ADD__5int32_5int16_5int32 ( int32, int16 -- int32 ) tst alu,hp.clk,hp.oe,add1 ld (hp),ival :bit15 if 1 dw $FFFF else dw 0 then jp op__ADD__5int32_5int32_5int32 : op__MUL__6uint32_6uint16_6uint32 ( uint32, uint16 -- uint32 ) Millicoded // Size: 19 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc mulu_16_32__6uint16_6uint16_6uint32 mc Lget+252 mc BraIf0+5 mc Lget+252 mc Lget+253 mc Mulu mc Lvar+254 mc AddPoke mc Lvar+255 mc Peek2 mc Lvar+250 mc Poke2 mc MDrop0_Next-3 : op__ADDGL__5int32_5int32P_ ( int32, int32& ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek2 mc Lvar+252 mc Peek2 mc AddL mc Lget+254 mc Poke2 mc MDrop0_Next-3 : op__SUBGL__5int32_5int32P_ ( int32, int32& ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek2 mc Lvar+252 mc Peek2 mc SubL mc Lget+254 mc Poke2 mc MDrop0_Next-3 : op__SLGL__5int16_6uint32P_ ( int16, uint32& ) Millicoded // Size: 11 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek2 mc Lget+253 mc SlL mc Lget+254 mc Poke2 mc MDrop0_Next-2 : op__SRGL__5int16_6uint32P_ ( int16, uint32& ) Millicoded // Size: 11 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek2 mc Lget+253 mc SrUL mc Lget+254 mc Poke2 mc MDrop0_Next-2 : peekpp__5int32P_5int32 ( int32& -- int32 ) Millicoded // Size: 19 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek2 mc Lget+254 mc Peek2 mc Int8+0 mc Int8+1 mc AddL mc Lget+252 mc Poke2 mc Lvar+255 mc Peek2 mc ToR2 mc MDrop0-3 mc FromR2 mc Ret // --- file: "long.asm" --- #include "str.cc" // +++ file: "str.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : implicit__str__kill__8ucs2charAEAE_8ucs2charAEAE ( str_AE -- str_AE ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ForAllItems mc Bra+2 mc Peek mc DropStr mc mmNextItem mc Bra-4 mc Ret : implicit__str__shrink__8ucs2charAEC_6uint16_ ( ucs2str˘, uint16 ) Millicoded // Size: 6 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc ShrinkStr mc Ret : copy__6uint16AEC_6uint16_6uint16AEC_6uint16_6uint16_ ( uint16[]˘, uint16, uint16[]˘, uint16, uint16 ) Millicoded // Size: 64 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+252 mc Count mc Lget+253 mc Count mc Lget+251 mc Lget+254 mc Ult mc And0 mc Bra+3 mc Lget+253 mc Lget+255 mc Ult mc BraIf0+46 mc Lget+254 mc Lget+254 mc Lget+249 mc Sub mc Lget+254 mc Lget+250 mc Sub mc Umin mc Umin mc Lget+251 mc Lget+251 mc AtIndex mc Lget+248 mc Lget+248 mc AtIndex mc Lget+254 mc TradMemCpy mc Lget+253 mc Lget+255 mc Ugt mc BraIf1+2 mc MDrop0-1 mc Bra+23 mc Dup mc Lvar+252 mc SubPoke mc Dup mc Lvar+249 mc AddPoke mc Lget+250 mc Lget+253 mc Eq mc BraIf0+2 mc Int8+0 mc Lset+250 mc Dup mc Lvar+251 mc AddPoke mc Lget+252 mc Lget+254 mc Eq mc BraIf0+2 mc Int8+0 mc Lset+252 mc MDrop0-1 mc Bra-46 mc MDrop0_Next-7 : copy_i16_to_i8__6uint16AEC_6uint16_6uint16AEC_6uint16_ ( uint16[]˘, uint16, uint16[]˘, uint16 ) Millicoded // Size: 37 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Count mc Lget+253 mc Sub mc Lget+254 mc Count mc Lget+254 mc Sub mc Sru15+15-1 mc Umin mc PshHP mc Peekmm mc BraIf0+19 mc Lget+252 mc Lget+252 mc AtIndexPeek mc Sru15+15-8 mc Lget+253 mc Lvar+253 mc Peekpp mc AtIndexPoke mc Lget+252 mc Lvar+252 mc Peekpp mc AtIndexPeek mc Int8+255 mc And mc Lget+253 mc Lvar+253 mc Peekpp mc AtIndexPoke mc Bra-22 mc MDrop0_Next-5 : copy_i8_to_i16__6uint16AEC_6uint16_6uint16AEC_6uint16_ ( uint16[]˘, uint16, uint16[]˘, uint16 ) Millicoded // Size: 35 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Count mc Lget+253 mc Sub mc Sru15+15-1 mc Lget+254 mc Count mc Lget+254 mc Sub mc Umin mc PshHP mc Peekmm mc BraIf0+17 mc Lget+252 mc Lvar+252 mc Peekpp mc AtIndexPeek mc Sli15+15-8 mc Lget+251 mc Lvar+251 mc Peekpp mc AtIndexPeek mc Int8+255 mc And mc Add mc Lget+253 mc Lvar+253 mc Peekpp mc AtIndexPoke mc Bra-20 mc MDrop0_Next-5 : midstr__8ucs2charAEC_5int16_5int16_8ucs2charATOE ( ucs2str˘, int16, int16 -- str_r ) Millicoded // Size: 14 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc Lget+254 mc Lget+253 mc Lget+253 mc Add mc SubStr mc ToR3 mc MDrop0-3 mc FromR3 mc Ret : midstr__8ucs2charAEC_5int16_8ucs2charATOE ( ucs2str˘, int16 -- str_r ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc Lget+253 mc Count mc SubStr mc ToR3 mc MDrop0-2 mc FromR3 mc Ret : leftstr__8ucs2charAEC_5int16_8ucs2charATOE ( ucs2str˘, int16 -- str_r ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Int8+0 mc Lget+254 mc SubStr mc ToR3 mc MDrop0-2 mc FromR3 mc Ret : rightstr__8ucs2charAEC_5int16_8ucs2charATOE ( ucs2str˘, int16 -- str_r ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+254 mc Count mc Lget+254 mc Sub mc Lget+253 mc Count mc SubStr mc ToR3 mc MDrop0-2 mc FromR3 mc Ret : catstr__8ucs2charAE_8ucs2charAEC_8ucs2charAE ( ucs2str, ucs2str˘ -- ucs2str ) Millicoded // Size: 35 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Count mc Lget+255 mc Count mc Lget+255 mc Lget+255 mc Add mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+251 mc Int8+0 mc AtIndex mc Lget+252 mc TradMemCpy mc Dup mc Lget+253 mc AtIndex mc Lget+252 mc Int8+0 mc AtIndex mc Lget+253 mc TradMemCpy mc Dup mc Retain mc Lvar+251 mc SwapWithVar mc DropStr mc DropStr mc MDrop0_Next-3 : catstr__8ucs2charAEC_8ucs2charAE_8ucs2charAE ( ucs2str˘, ucs2str -- ucs2str ) Millicoded // Size: 37 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Count mc Lget+255 mc Count mc Lget+255 mc Lget+255 mc Add mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+251 mc Int8+0 mc AtIndex mc Lget+252 mc TradMemCpy mc Dup mc Lget+253 mc AtIndex mc Lget+252 mc Int8+0 mc AtIndex mc Lget+253 mc TradMemCpy mc Dup mc Retain mc ToR mc DropStr mc MDrop0-2 mc DropStr mc MDrop0-1 mc FromR mc Ret : catstr__8ucs2charAEC_8ucs2charAEC_8ucs2charAE ( ucs2str˘, ucs2str˘ -- ucs2str ) Millicoded // Size: 35 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Count mc Lget+255 mc Count mc Lget+255 mc Lget+255 mc Add mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+251 mc Int8+0 mc AtIndex mc Lget+252 mc TradMemCpy mc Dup mc Lget+253 mc AtIndex mc Lget+252 mc Int8+0 mc AtIndex mc Lget+253 mc TradMemCpy mc Dup mc Retain mc ToR mc DropStr mc MDrop0-4 mc FromR mc Ret : catstr__8ucs2charAE_8ucs2charAEC_6uint16_6uint16_8ucs2charAE ( ucs2str, ucs2str˘, uint16, uint16 -- ucs2str ) Millicoded // Size: 38 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Count mc Lget+255 mc Add mc Lget+254 mc Sub mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+251 mc Int8+0 mc AtIndex mc Lget+250 mc Count mc TradMemCpy mc Dup mc Lget+251 mc Count mc AtIndex mc Lget+252 mc Lget+252 mc AtIndex mc Lget+253 mc Lget+251 mc Sub mc TradMemCpy mc Dup mc Retain mc Lvar+251 mc SwapWithVar mc DropStr mc DropStr mc MDrop0_Next-3 : catstr__8ucs2charAEC_6uint16_6uint16_8ucs2charAE_8ucs2charAE ( ucs2str˘, uint16, uint16, ucs2str -- ucs2str ) Millicoded // Size: 40 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Count mc Lget+254 mc Add mc Lget+253 mc Sub mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+251 mc Lget+251 mc AtIndex mc Lget+252 mc Lget+250 mc Sub mc TradMemCpy mc Dup mc Lget+253 mc Lget+251 mc Sub mc AtIndex mc Lget+254 mc Int8+0 mc AtIndex mc Lget+253 mc Count mc TradMemCpy mc Dup mc Retain mc ToR mc DropStr mc DropStr mc MDrop0-3 mc FromR mc Ret : catchar__8ucs2charAEC_6uint16_6uint16_8ucs2char_8ucs2charAE ( ucs2str˘, uint16, uint16, ucs2char -- ucs2str ) Millicoded // Size: 29 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc Lvar+254 mc SubPoke mc Lget+255 mc Addq+1 mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+251 mc Lget+251 mc AtIndex mc Lget+252 mc TradMemCpy mc Lget+255 mc Lget+255 mc Last mc Poke mc Dup mc Retain mc ToR mc DropStr mc MDrop0-4 mc FromR mc Ret : catchar__8ucs2charAEC_8ucs2char_8ucs2charAE ( ucs2str˘, ucs2char -- ucs2str ) Millicoded // Size: 28 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Count mc Dup mc Addq+1 mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+252 mc Int8+0 mc AtIndex mc Lget+253 mc TradMemCpy mc Lget+254 mc Lget+255 mc Last mc Poke mc Dup mc Retain mc ToR mc DropStr mc MDrop0-3 mc FromR mc Ret : catchar__8ucs2charAE_8ucs2char_8ucs2charAE ( ucs2str, ucs2char -- ucs2str ) Millicoded // Size: 11 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc catchar__8ucs2charAEC_8ucs2char_8ucs2charAE mc Lvar+254 mc SwapWithVar mc DropStr mc MDrop0_Next-1 : match__8ucs2charAEC_8ucs2charAEC_4bool ( ucs2str˘, ucs2str˘ -- bool ) Millicoded // Size: 116 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+42 mc Int8+0 mc find__8ucs2charAEC_8ucs2char_6uint16_6uint16 mc Dup mc Lget+255 mc Int8+255 mc Int16+255 mc Eq mc BraIf0+16 mc Lget+253 mc Count mc Lget+253 mc Count mc Eq mc And0 mc Bra+8 mc Lget+253 mc Int8+0 mc Lget+252 mc Int8+0 mc Lget+250 mc Count mc matches__8ucs2charAEC_5int16_8ucs2charAEC_5int16_5int16_4bool mc Bool mc Bra+85 mc Lget+253 mc Count mc Lget+254 mc Ult mc BraIf0+2 mc Int8+0 mc Bra+78 mc Lget+253 mc Int8+0 mc Lget+252 mc Int8+0 mc Lget+251 mc matches__8ucs2charAEC_5int16_8ucs2charAEC_5int16_5int16_4bool mc BraIf1+2 mc Int8+0 mc Bra+69 mc Lget+254 mc Int8+42 mc Lget+252 mc Count mc rfind__8ucs2charAEC_8ucs2char_6uint16_6uint16 mc Lget+252 mc Count mc Lget+252 mc Count mc Lget+254 mc Addq+1 mc Sub mc Sub mc Dup mc Lget+253 mc Lt mc BraIf0+3 mc Int8+0 mc MNip0-2 mc Bra+49 mc Lget+251 mc Lget+255 mc Lget+250 mc Lget+252 mc Addq+1 mc Lget+248 mc Count mc matches__8ucs2charAEC_5int16_8ucs2charAEC_5int16_5int16_4bool mc BraIf1+3 mc Int8+0 mc MNip0-2 mc Bra+37 mc Lget+253 mc Lget+254 mc Eq mc BraIf1+31 mc Lvar+253 mc Incr mc Lget+252 mc Int8+42 mc Lget+251 mc Find mc Lget+250 mc Lget+252 mc Lget+253 mc Lget+248 mc Lget+248 mc Lget+251 mc find__8ucs2charAEC_5int16_5int16_8ucs2charAEC_5int16_5int16_5int16 mc Lset+253 mc Lget+253 mc Int8+255 mc Int16+255 mc Eq mc BraIf0+3 mc Int8+0 mc MNip0-3 mc Bra+11 mc Dup mc Lget+251 mc Sub mc Lvar+252 mc AddPoke mc Dup mc Lset+252 mc MDrop0-1 mc Bra-35 mc Int8+1 mc MNip0-2 mc MNip0_Next-4 : find__8ucs2charAEC_8ucs2char_6uint16_6uint16 ( ucs2str˘, ucs2char, uint16 -- uint16 ) Millicoded // Size: 23 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Lget+253 mc Count mc Ult mc BraIf0+11 mc Lget+254 mc Lget+255 mc AtIndexPeek mc Lget+254 mc Eq mc BraIf0+2 mc Dup mc Bra+5 mc PshHP mc Incr mc Bra-16 mc Int8+255 mc Int16+255 mc MNip0_Next-3 : rfind__8ucs2charAEC_8ucs2char_6uint16_6uint16 ( ucs2str˘, ucs2char, uint16 -- uint16 ) Millicoded // Size: 23 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Lget+253 mc Count mc Ult mc BraIf0+11 mc Lget+254 mc Lget+255 mc AtIndexPeek mc Lget+254 mc Eq mc BraIf0+2 mc Dup mc Bra+5 mc PshHP mc Decr mc Bra-16 mc Int8+255 mc Int16+255 mc MNip0_Next-3 : eq__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool ( ucs2str˘, uint16, uint16, ucs2str˘, uint16, uint16 -- bool ) Millicoded // Size: 32 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Lget+251 mc Sub mc Lget+255 mc Lget+253 mc Sub mc Ne mc BraIf0+2 mc Int8+0 mc Bra+17 mc Lget+252 mc Lget+252 mc Ult mc BraIf0+12 mc Lget+251 mc Lvar+251 mc Peekpp mc AtIndexPeek mc Lget+253 mc Lvar+253 mc Peekpp mc AtIndexPeek mc Ne mc BraIf0-14 mc Int8+0 mc Bra+1 mc Int8+1 mc MNip0_Next-6 : eq__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_4bool ( ucs2str˘, uint16, uint16, ucs2str˘ -- bool ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Lget+253 mc Lget+253 mc SubStr mc Lget+253 mc RangeAll mc eq__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool mc MNip0_Next-4 : eq__8ucs2charAEC_8ucs2charAEC_6uint16_6uint16_4bool ( ucs2str˘, ucs2str˘, uint16, uint16 -- bool ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc RangeAll mc Lget+251 mc Lget+251 mc Lget+251 mc SubStr mc eq__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool mc MNip0_Next-4 : ne__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool ( ucs2str˘, uint16, uint16, ucs2str˘, uint16, uint16 -- bool ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc eq__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool mc Not mc Next : ne__8ucs2charAEC_8ucs2charATOE_4bool ( ucs2str˘, str_r -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Int8+0 mc Lget+251 mc Count mc SubStr mc Lvar+251 mc Peek3 mc ne__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool mc MNip0_Next-4 : ne__8ucs2charATOE_8ucs2charAEC_4bool ( str_r, ucs2str˘ -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lvar+253 mc Peek3 mc Lget+253 mc Int8+0 mc Lget+251 mc Count mc SubStr mc ne__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_4bool mc MNip0_Next-4 : AppendGl__8ucs2charAE_8ucs2charAEP_ ( ucs2str, ucs2str& ) Millicoded // Size: 38 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek mc Retain mc Dup mc Count mc Lget+253 mc Count mc Add mc AllocTrackedVref mc Lget+255 mc Peek mc Int8+0 mc AtIndex mc Lget+255 mc Int8+0 mc AtIndex mc Lget+254 mc Count mc TradMemCpy mc Lget+255 mc Peek mc Lget+255 mc Count mc AtIndex mc Lget+253 mc Int8+0 mc AtIndex mc Lget+252 mc Count mc TradMemCpy mc DropStr mc MDrop0-1 mc DropStr mc Ret : AppendGl__8ucs2charAEAEC_8ucs2charAEAEP_ ( str_AE˘, str_AE& ) Millicoded // Size: 52 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek mc Retain mc Dup mc Count mc Lget+253 mc Count mc Add mc AllocTrackedVref mc Lget+255 mc Peek mc Int8+0 mc AtIndex mc Lget+255 mc Int8+0 mc AtIndex mc Lget+254 mc Count mc TradMemCpy mc Lget+255 mc Peek mc Lget+255 mc Count mc AtIndex mc Lget+253 mc Int8+0 mc AtIndex mc Lget+252 mc Count mc TradMemCpy mc Lget+255 mc Peek mc Count mc PshHP mc Peekmm mc BraIf0+7 mc Lget+254 mc Peek mc Lget+255 mc AtIndexPeek mc Retain mc MDrop0-1 mc Bra-10 mc MDrop0-1 mc CallKill mc implicit__str__kill__8ucs2charAEAE_8ucs2charAEAE mc DropStr mc MDrop0_Next-2 : AppendGl__8ucs2charAE_8ucs2charAEAEP_ ( ucs2str, str_AE& ) Millicoded // Size: 46 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek mc Retain mc Dup mc Count mc Addq+1 mc AllocTrackedVref mc Lget+255 mc Peek mc Int8+0 mc AtIndex mc Lget+255 mc Int8+0 mc AtIndex mc Lget+254 mc Count mc TradMemCpy mc Lget+254 mc Retain mc Lget+254 mc Peek mc Last mc Poke mc Dup mc Count mc PshHP mc Peekmm mc BraIf0+7 mc Lget+254 mc Peek mc Lget+255 mc AtIndexPeek mc Retain mc MDrop0-1 mc Bra-10 mc MDrop0-1 mc CallKill mc implicit__str__kill__8ucs2charAEAE_8ucs2charAEAE mc DropStr mc MDrop0-1 mc DropStr mc Ret : AppendGl__8ucs2char_8ucs2charAEP_ ( ucs2char, ucs2str& ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Peek mc Retain mc Lget+254 mc CatStrChar mc Lget+255 mc SwapWithVar mc DropStr mc MDrop0_Next-2 : append__8ucs2charAEC_8ucs2char_ ( ucs2str˘, ucs2char ) // this.grow(this.count()+1); // this.last() = c; AppendChar: ( s c -- ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+254 mc Count mc Addq+1 mc GrowStr // mc Dup // mc Lget+254 // mc Last // mc Poke // mc MDrop0_Next+-2 mc Swap mc Last mc Poke mc Next : catstr__8ucs2charAE_8ucs2char_8ucs2charAE ( ucs2str, ucs2char -- ucs2str ) Millicoded // Size: 29 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Count mc Addq+1 mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+253 mc Int8+0 mc AtIndex mc Lget+252 mc Count mc TradMemCpy mc Lget+255 mc Lget+255 mc Lget+252 mc Count mc AtIndexPoke mc Dup mc Retain mc Lvar+253 mc SwapWithVar mc DropStr mc DropStr mc MDrop0_Next-1 : catstr__8ucs2charAEC_6uint16_6uint16_8ucs2charAEC_6uint16_6uint16_8ucs2charAE ( ucs2str˘, uint16, uint16, ucs2str˘, uint16, uint16 -- ucs2str ) Millicoded // Size: 37 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+252 mc Lvar+252 mc SubPoke mc Lget+255 mc Lvar+255 mc SubPoke mc Lget+253 mc Lget+255 mc Add mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+249 mc Lget+249 mc AtIndex mc Lget+250 mc TradMemCpy mc Dup mc Lget+251 mc AtIndex mc Lget+252 mc Lget+252 mc AtIndex mc Lget+253 mc TradMemCpy mc Dup mc Retain mc ToR mc DropStr mc MDrop0-6 mc FromR mc Ret : ShrinkStrArray__8ucs2charAEAEC_6uint16_ ( str_AE˘, uint16 ) Millicoded // Size: 24 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Count mc Lget+255 mc Lget+255 mc Ult mc BraIf0+13 mc Dup mc Lget+254 mc Ugt mc BraIf0+6 mc Lget+254 mc Lvar+255 mc mmPeek mc AtIndexPeek mc DropStr mc Bra-10 mc Lget+254 mc Lget+254 mc implicit__str__shrink__8ucs2charAEC_6uint16_ mc MDrop0_Next-3 : Rol_AE__6uint16AEC_6uint16_6uint16_ ( uint16[]˘, uint16, uint16 ) Millicoded // Size: 30 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Addq+1 mc Dup mc Lget+254 mc Ult mc BraIf0+19 mc Lget+253 mc Lget+253 mc AtIndexPeek mc Lget+252 mc Lget+252 mc AtIndex mc Lget+251 mc Lget+253 mc AtIndex mc Lget+252 mc Lget+252 mc Sub mc TradMemCpy mc Dup mc Lget+251 mc Lget+252 mc Subq+1 mc AtIndexPoke mc MDrop0-1 mc MDrop0_Next-4 : Ror_AE__6uint16AEC_6uint16_6uint16_ ( uint16[]˘, uint16, uint16 ) Millicoded // Size: 30 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Subq+1 mc Lget+254 mc Lget+255 mc Ult mc BraIf0+19 mc Lget+253 mc Lget+255 mc AtIndexPeek mc Lget+252 mc Lget+252 mc Addq+1 mc AtIndex mc Lget+251 mc Lget+251 mc AtIndex mc Lget+253 mc Lget+250 mc Sub mc TradRMemCpy mc Dup mc Lget+251 mc Lget+251 mc AtIndexPoke mc MDrop0-1 mc MDrop0_Next-4 : cast_range_2_str__8ucs2charAEC_6uint16_6uint16_8ucs2charAE ( ucs2str˘, uint16, uint16 -- ucs2str ) Millicoded // Size: 25 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Lget+254 mc Sub mc Alloc mc Dup mc Int8+0 mc AtIndex mc Lget+252 mc Lget+252 mc AtIndex mc Lget+253 mc Lget+251 mc Sub mc TradMemCpy mc Dup mc Retain mc ToR mc DropStr mc MDrop0-3 mc FromR mc Ret : matches__8ucs2char_8ucs2char_4bool ( ucs2char, ucs2char -- bool ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc Eq mc Or1 mc Bra+3 mc Dup mc Int8+63 mc Eq mc MNip0_Next-2 : matches__8ucs2charAEC_5int16_8ucs2charAEC_5int16_5int16_4bool ( ucs2str˘, int16, ucs2str˘, int16, int16 -- bool ) Millicoded // Size: 30 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc Lt mc BraIf0+18 mc Lget+252 mc Lvar+252 mc Peekpp mc AtIndexPeek mc Lget+253 mc Lvar+253 mc Peekpp mc AtIndexPeek mc Lget+255 mc Lget+255 mc Eq mc Or1 mc Bra+3 mc Dup mc Int8+63 mc Eq mc MNip0-2 mc BraIf1-22 mc Lget+255 mc Lget+255 mc Eq mc MNip0_Next-5 : find__8ucs2charAEC_5int16_5int16_8ucs2charAEC_5int16_5int16_5int16 ( ucs2str˘, int16, int16, ucs2str˘, int16, int16 -- int16 ) Millicoded // Size: 28 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Lget+254 mc Sub mc Lvar+252 mc SubPoke mc Lget+252 mc Lget+252 mc Le mc BraIf0+12 mc Lget+251 mc Lget+251 mc Lget+252 mc Lget+252 mc Lget+252 mc matches__8ucs2charAEC_5int16_8ucs2charAEC_5int16_5int16_4bool mc BraIf0+2 mc Lget+252 mc Bra+5 mc Lvar+252 mc Incr mc Bra-16 mc Int8+255 mc Int16+255 mc MNip0_Next-6 // --- file: "str.asm" --- #include "sort.cc" // +++ file: "sort.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : sort__5int16AEC_6uint16_6uint16_4boolB5int165int16D_ ( int16[]˘, uint16, uint16, bool(int16,int16) ) Millicoded // Size: 166 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc PushContext0 mc Int8+16 mc Alloc mc Int8+16 mc Alloc mc Int8+0 mc Lvar+252 mc Decr mc Lget+252 mc Lget+250 mc Sub mc Addq+1 mc Switch+4 mc Bra+17 mc Bra+16 mc Bra+11 mc Bra+1 mc Bra+25 mc Lget+251 mc Lget+250 mc Addq+2 mc sort__5int16AEC_6uint16_6uint16_4boolB5int165int16D___sort__6uint16_6uint16_ mc Lget+251 mc Addq+1 mc Lget+250 mc Addq+2 mc sort__5int16AEC_6uint16_6uint16_4boolB5int165int16D___sort__6uint16_6uint16_ mc Lget+251 mc Lget+250 mc Addq+1 mc sort__5int16AEC_6uint16_6uint16_4boolB5int165int16D___sort__6uint16_6uint16_ mc Dup mc BraIf0+123 mc Lget+254 mc Lvar+255 mc mmPeek mc AtIndexPeek mc Lset+251 mc Lget+255 mc Lget+255 mc AtIndexPeek mc Lset+252 mc Bra-35 mc Lget+251 mc Lget+251 mc Lget+249 mc Lget+249 mc sort__5int16AEC_6uint16_6uint16_4boolB5int165int16D___sort__6uint16_6uint16_ mc Lvar+249 mc Peekpp mc Lvar+249 mc Peekmm mc Lget+247 mc Lget+247 mc Uge mc BraIf1+55 mc Lget+247 mc Lget+254 mc Lget+247 mc CallMillicode mc BraIf0+18 mc Dup mc Lget+246 mc Lget+247 mc CallMillicode mc BraIf0+4 mc Lvar+247 mc Peekpp mc Lset+255 mc Bra+11 mc Lget+246 mc Lget+246 mc AtIndex mc Lget+245 mc Lvar+246 mc Peekmm mc AtIndex mc SwapVar mc Bra+2 mc Lvar+247 mc Incr mc Lget+247 mc Lget+247 mc Uge mc BraIf1+26 mc Dup mc Lget+247 mc Lget+247 mc CallMillicode mc BraIf0+18 mc Lget+248 mc Lget+254 mc Lget+247 mc CallMillicode mc BraIf0+4 mc Lvar+248 mc Peekmm mc Nip mc Bra-47 mc Lget+246 mc Lvar+246 mc Peekpp mc AtIndex mc Lget+245 mc Lget+246 mc AtIndex mc SwapVar mc Bra-56 mc Lvar+248 mc Decr mc Bra-59 mc Lget+247 mc Lget+254 mc Lget+247 mc CallMillicode mc BraIf0+3 mc Lvar+248 mc Decr mc Bra+2 mc Lvar+247 mc Incr mc Lget+248 mc Lget+252 mc Sub mc Lget+253 mc Lget+245 mc Sub mc Ugt mc BraIf0+14 mc Lget+253 mc Lget+249 mc Lget+250 mc AtIndexPoke mc Lget+248 mc Lget+250 mc Lvar+250 mc Peekpp mc AtIndexPoke mc Lget+248 mc Lset+247 mc Lget+254 mc Lset+248 mc Bra+11 mc Lget+247 mc Lget+249 mc Lget+250 mc AtIndexPoke mc Lget+254 mc Lget+250 mc Lvar+250 mc Peekpp mc AtIndexPoke mc Lget+253 mc Lset+247 mc MDrop0-4 mc Bra-148 mc MDrop0-1 mc DropStr mc DropStr mc MDrop0-4 mc PopContext0 mc Ret : sort__5int16AEC_6uint16_6uint16_4boolB5int165int16D___sort__6uint16_6uint16_ ( uint16, uint16 ) Millicoded // Size: 26 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc XLvar+124 mc Peek mc Lget+254 mc AtIndexPeek mc XLvar+124 mc Peek mc Lget+254 mc AtIndexPeek mc XLvar+127 mc Peek mc CallMillicode mc BraIf0+9 mc XLvar+124 mc Peek mc Lget+254 mc AtIndex mc XLvar+124 mc Peek mc Lget+254 mc AtIndex mc SwapVar mc MDrop0_Next-2 // --- file: "sort.asm" --- #if include_sio_driver_in_rom//skipping: #include "sio.cc" #endif #if include_floating_point//skipping: #include "float.cc" #endif // ______________________________________________________ // "Production" Microcode: #if !include_tests #include "i2c.cc" // +++ file: "i2c.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : i2cSendByte__6uint16_6uint16 ( uint16 -- uint16 ) Millicoded // Size: 25 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Sli15+15-8 mc i2cSendBit__5int16_5int16 mc i2cSendBit__5int16_5int16 mc i2cSendBit__5int16_5int16 mc i2cSendBit__5int16_5int16 mc i2cSendBit__5int16_5int16 mc i2cSendBit__5int16_5int16 mc i2cSendBit__5int16_5int16 mc i2cSendBit__5int16_5int16 mc Nip mc Int8+0 mc i2cReadBit__5int16_5int16 mc BraIf0+4 mc i2cSendEnd mc Int8+1 mc Nip mc Bra+2 mc Int8+0 mc Nip mc Ret : i2cReadByte__4bool_6uint16 ( bool -- uint16 ) Millicoded // Size: 21 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc i2cReadBit__5int16_5int16 mc i2cReadBit__5int16_5int16 mc i2cReadBit__5int16_5int16 mc i2cReadBit__5int16_5int16 mc i2cReadBit__5int16_5int16 mc i2cReadBit__5int16_5int16 mc i2cReadBit__5int16_5int16 mc i2cReadBit__5int16_5int16 mc Lget+255 mc BraIf0+3 mc i2cSendBit1 mc i2cSendEnd mc Bra+1 mc i2cSendBit0 mc Dup mc MNip0_Next-2 : i2cReadByte__6uint16 ( -- uint16 ) // logchar 'i' // ("i2c_RB "); // logchar '2' // logchar 'c' // logchar '_' // logchar 'R' // logchar 'B' // logchar ' ' psh alu xor alu jp i2cReadByte__4bool_6uint16 : i2cStartReading__6uint16 ( -- uint16 ) Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cSendStart mc Int8+161 mc i2cSendByte__6uint16_6uint16 mc Ret : i2cStartWritingAtAddress__6uint16_6uint16 ( uint16 -- uint16 ) Millicoded // Size: 30 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cSendStart mc Int8+160 mc i2cSendByte__6uint16_6uint16 mc BraIf0+12 mc i2cWaitEndWriting__6uint16 mc BraIf0+3 mc Int8+1 mc Nip mc Bra+16 mc i2cSendStart mc Int8+160 mc i2cSendByte__6uint16_6uint16 mc BraIf0+3 mc Int8+1 mc Nip mc Bra+9 mc Dup mc Sru15+15-8 mc i2cSendByte__6uint16_6uint16 mc Or1 mc Bra+3 mc Dup mc i2cSendByte__6uint16_6uint16 mc Bool mc Nip mc Ret : i2cStartReadingAtAddress__6uint16_6uint16 ( uint16 -- uint16 ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc i2cStartWritingAtAddress__6uint16_6uint16 mc BraIf0+3 mc Int8+1 mc Nip mc Bra+2 mc i2cStartReading__6uint16 mc Nip mc Ret : i2cWaitEndWriting__6uint16 ( -- uint16 ) Millicoded // Size: 17 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+100 mc i2cStartReading__6uint16 mc BraIf0+6 mc PshHP mc mmPeek mc BraIf0+3 mc Int8+100 mc BusyWait mc Bra-8 mc i2cSendEnd mc Dup mc Not mc MNip0_Next-1 : i2cReadData__6uint16AEC_ ( uint16[]˘ ) Millicoded // Size: 17 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Dup mc Lget+254 mc Count mc Ult mc BraIf0+6 mc i2cReadByte__6uint16 mc Lget+254 mc Lvar+254 mc Peekpp mc AtIndexPoke mc Bra-11 mc MDrop0_Next-2 : i2cReadData__6uint16_6uint16AEC_6uint16_6uint16_3Err ( uint16, uint16[]˘, uint16, uint16 -- Err ) Millicoded // Size: 24 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc i2cStartReadingAtAddress__6uint16_6uint16 mc BraIf0+2 mc Int8+3 mc Bra+14 mc Lget+255 mc Lget+255 mc Ult mc BraIf0+9 mc Lget+255 mc Lget+255 mc Eq mc i2cReadByte__4bool_6uint16 mc Lget+253 mc Lvar+253 mc Peekpp mc AtIndexPoke mc Bra-13 mc Int8+0 mc MNip0_Next-4 : i2cWriteData__6uint16_6uint16AEC_6uint16_6uint16_6uint16_3Err ( uint16, uint16[]˘, uint16, uint16, uint16 -- Err ) Millicoded // Size: 43 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc Lget+254 mc Ult mc BraIf0+33 mc Lget+252 mc i2cStartWritingAtAddress__6uint16_6uint16 mc BraIf0+2 mc Int8+3 mc Bra+29 mc Lget+255 mc Lget+253 mc Sub mc Lget+255 mc Lget+250 mc Lget+253 mc Subq+1 mc And mc Sub mc Umin mc Dup mc Lvar+250 mc AddPoke mc PshHP mc Peekmm mc BraIf0+9 mc Lget+252 mc Lvar+252 mc Peekpp mc AtIndexPeek mc i2cSendByte__6uint16_6uint16 mc BraIf0-9 mc Int8+2 mc MNip0-1 mc Bra+4 mc i2cSendEnd mc MDrop0-1 mc Bra-37 mc Int8+0 mc MNip0_Next-5 : i2cVerifyData__6uint16_6uint16AEC_6uint16_6uint16_3Err ( uint16, uint16[]˘, uint16, uint16 -- Err ) Millicoded // Size: 28 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc i2cStartReadingAtAddress__6uint16_6uint16 mc BraIf0+2 mc Int8+3 mc Bra+18 mc Lget+255 mc Lget+255 mc Ult mc BraIf0+13 mc Lget+254 mc Lvar+254 mc Peekpp mc AtIndexPeek mc Lget+254 mc Lget+254 mc Eq mc i2cReadByte__4bool_6uint16 mc Ne mc BraIf0-14 mc i2cSendEnd mc Int8+2 mc Bra+1 mc Int8+0 mc MNip0_Next-4 : i2cGetctl__11I2cDrvrDataC_6uint16_6uint16 ( I2cDrvrData˘, uint16 -- uint16 ) Millicoded // Size: 21 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+7 mc Eq mc BraIf0+4 mc Lget+255 mc ItemGet+1 mc Msbit mc Bra+8 mc Dup mc Int8+8 mc Eq mc BraIf0+3 mc Lget+255 mc ItemGet+2 mc Bra+1 mc Int8+0 mc MNip0_Next-2 : i2cSetctl__11I2cDrvrDataC_6uint16_6uint16_ ( I2cDrvrData˘, uint16, uint16 ) Millicoded // Size: 5 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc MDrop0_Next-3 : i2cWriteBlocks__11I2cDrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err ( I2cDrvrData˘, uint32, uint16[]˘, uint16, uint16 -- Err ) Millicoded // Size: 17 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+251 mc ItemGet+0 mc Select mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+247 mc ItemGet+1 mc i2cWriteData__6uint16_6uint16AEC_6uint16_6uint16_6uint16_3Err mc Deselect mc Dup mc MNip0_Next-7 : i2cReadBlocks__11I2cDrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err ( I2cDrvrData˘, uint32, uint16[]˘, uint16, uint16 -- Err ) Millicoded // Size: 15 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+251 mc ItemGet+0 mc Select mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+253 mc i2cReadData__6uint16_6uint16AEC_6uint16_6uint16_3Err mc Deselect mc Dup mc MNip0_Next-7 : i2cVerifyBlocks__11I2cDrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err ( I2cDrvrData˘, uint32, uint16[]˘, uint16, uint16 -- Err ) Millicoded // Size: 15 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+251 mc ItemGet+0 mc Select mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+253 mc i2cVerifyData__6uint16_6uint16AEC_6uint16_6uint16_3Err mc Deselect mc Dup mc MNip0_Next-7 : new__8ucs2charAEC_6uint16_14I2cBlockDevice ( ucs2str˘, uint16 -- I2cBlockDevice ) Millicoded // Size: 46 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Select mc i2c_log2eepromsize__6uint16 mc Dup mc Sru15+15-1 mc Subq+1 mc Deselect mc Lget+253 mc Int8+11 mc Int16+128 mc Int8+3 mc Alloc mc ToR mc Int8+1 mc Lget+253 mc Sl mc PeekR mc ItemSet+1 mc Int8+1 mc Lget+252 mc Lget+252 mc Sub mc Sl mc PeekR mc ItemSet+2 mc Lget+252 mc PeekR mc ItemSet+0 mc FromR mc DupToR mc Int8+i2cGetctl__11I2cDrvrDataC_6uint16_6uint16&$FF mc Int16+(i2cGetctl__11I2cDrvrDataC_6uint16_6uint16>>8)&$FF mc Int8+i2cSetctl__11I2cDrvrDataC_6uint16_6uint16_&$FF mc Int16+(i2cSetctl__11I2cDrvrDataC_6uint16_6uint16_>>8)&$FF mc Int8+i2cReadBlocks__11I2cDrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err&$FF mc Int16+(i2cReadBlocks__11I2cDrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err>>8)&$FF mc Int8+i2cWriteBlocks__11I2cDrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err&$FF mc Int16+(i2cWriteBlocks__11I2cDrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err>>8)&$FF mc new__8ucs2charAEC_6uint16_8DrvrDataC_6uint16B8DrvrDataC6uint16D_4voidB8DrvrDataC6uint166uint16D_3ErrB8DrvrDataC6uint326uint16AEC6uint166uint16D_3ErrB8DrvrDataC6uint326uint16AEC6uint166uint16D_11BlockDevice mc FromR mc DropStr mc MNip0_Next-4 : i2cD0C0 () ld dnop,io_i2c, i2c_data=0, i2c_clk=0 // Data:0 Clock:0 jp i2cDelay : i2cD1C0 () ld dnop,io_i2c, i2c_data=1, i2c_clk=0 // Data:1 Clock:0 jp i2cDelay : i2cD0C1 () ld dnop,io_i2c, i2c_data=0, i2c_clk=1 // Data:0 Clock:1 jp i2cDelay : i2cD1C1 () ld dnop,io_i2c, i2c_data=1, i2c_clk=1 // Data:1 Clock:1 jp i2cDelay : i2cD1C0AddBit__5int16_5int16 ( int16 -- int16 ) ld dtmp,io_i2c, i2c_data=1, i2c_clk=0 // Data:1 Clock:0 and read & append bit to alu tst dtmp if bit0 add_c alu // nodelay else add alu // nodelay then jp i2cDelay : i2cDelay () // io // 1 // jp // 2 clr clock4 // 1..4 nop // 4 set clock4 // 4 next_m // 3 next_mc // * next_m : i2cSendStart () Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cD1C1 mc i2cD0C1 mc i2cD0C0 mc Ret : i2cSendEnd () Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cD0C0 mc i2cD0C1 mc i2cD1C1 mc Ret : i2cSendBit1 () Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cD1C0 mc i2cD1C1 mc i2cD1C0 mc Ret : i2cSendBit0 () Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cD0C0 mc i2cD0C1 mc i2cD0C0 mc Ret : i2cSendBit__5int16_5int16 ( int16 -- int16 ) add alu // nodelay ld cmd,ival :bit15 if 1 dw i2cSendBit1 :bit15 else dw i2cSendBit0 :bit15 then : i2cReadBit__5int16_5int16 ( int16 -- int16 ) Millicoded // Size: 10 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cD1C0 mc i2cD1C1 mc Dup mc i2cD1C0AddBit__5int16_5int16 mc Nip mc Ret : i2c_log2eepromsize__6uint16 ( -- uint16 ) Millicoded // Size: 64 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+16 mc Alloc mc Int8+0 mc Lget+255 mc RangeAll mc i2cReadData__6uint16_6uint16AEC_6uint16_6uint16_3Err mc BraIf0+2 mc Int8+3 mc Bra+47 mc Int8+16 mc PshHP mc Peekmm mc And0 mc Bra+5 mc Lget+255 mc Lget+255 mc AtIndexPeek mc Int8+255 mc Eq mc BraIf1-10 mc Dup mc Int8+0 mc Lt mc BraIf0+14 mc Int8+254 mc Lget+254 mc Int8+0 mc AtIndexPoke mc Int8+0 mc Lget+254 mc Int8+0 mc Int8+1 mc Int8+16 mc i2cWriteData__6uint16_6uint16AEC_6uint16_6uint16_6uint16_3Err mc BraIf0+3 mc Int8+3 mc MNip0-1 mc Bra+18 mc Int8+14 mc Int8+1 mc Lget+255 mc Sl mc Lget+253 mc RangeAll mc i2cVerifyData__6uint16_6uint16AEC_6uint16_6uint16_3Err mc Int8+0 mc Eq mc BraIf0+5 mc PshHP mc mmPeek mc Int8+2 mc Ugt mc BraIf1-14 mc Dup mc Addq+1 mc MNip0-2 mc ToR mc DropStr mc FromR mc Ret // --- file: "i2c.asm" --- #include "dev.cc" // +++ file: "dev.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler ( BytecodeCompiler -- BytecodeCompiler ) Millicoded // Size: 35 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+0 mc DropStr mc Dup mc ItemGet+1 mc DropStr mc Dup mc ItemGet+2 mc DropStr mc Dup mc ItemGet+3 mc CallKill mc implicit__dev__kill__8ucs2charAEAE_8ucs2charAEAE mc DropStr mc Dup mc ItemGet+4 mc DropStr mc Dup mc ItemGet+7 mc DropStr mc Dup mc ItemGet+8 mc CallKill mc implicit__dev__kill__6uint16AEAE_6uint16AEAE mc DropStr mc Dup mc ItemGet+11 mc CallKill mc implicit__dev__kill__11bcc_procdefAE_11bcc_procdefAE mc DropStr mc Ret : implicit__dev__kill__8ucs2charAEAE_8ucs2charAEAE ( ucs2str[] -- ucs2str[] ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ForAllItems mc Bra+2 mc Peek mc DropStr mc mmNextItem mc Bra-4 mc Ret : implicit__dev__kill__6uint16AEAE_6uint16AEAE ( uint16[][] -- uint16[][] ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ForAllItems mc Bra+2 mc Peek mc DropStr mc mmNextItem mc Bra-4 mc Ret : implicit__dev__kill__11bcc_procdef_11bcc_procdef ( bcc_procdef -- bcc_procdef ) Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+1 mc DropStr mc Ret : implicit__dev__kill__11bcc_procdefAE_11bcc_procdefAE ( bcc_procdef[] -- bcc_procdef[] ) Millicoded // Size: 14 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ForAllItems mc Bra+4 mc Peek mc CallKill mc implicit__dev__kill__11bcc_procdef_11bcc_procdef mc DropStr mc mmNextItem mc Bra-6 mc Ret : implicit__dev__kill__4Node_4Node ( Node -- Node ) Millicoded // Size: 11 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+4 mc CallKill mc implicit__dev__kill__2FDAE_2FDAE mc DropStr mc implicit__dev__kill__2FD_2FD mc Ret : implicit__dev__kill__2FD_2FD ( FD -- FD ) Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+1 mc DropStr mc Ret : implicit__dev__kill__2FDAE_2FDAE ( FDs -- FDs ) Millicoded // Size: 14 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ForAllItems mc Bra+4 mc Peek mc CallKill mc implicit__dev__kill__2FD_2FD mc DropStr mc mmNextItem mc Bra-6 mc Ret : init_devices () Millicoded // Size: 144 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Istr+14 dm '[' dm 'i' dm 'n' dm 'i' dm 't' dm '_' dm 'd' dm 'e' dm 'v' dm 'i' dm 'c' dm 'e' dm 's' dm ']' ld cmd,atmp mc LogStr mc Int8+5 mc Alloc mc ToR mc Int8+0 mc PeekR mc ItemSet+0 mc Istr+0 ld cmd,atmp mc PeekR mc ItemSet+1 mc Int8+0 mc Alloc mc PeekR mc ItemSet+4 mc FromR mc Gset+root mc Int8+5 mc Alloc mc ToR mc Int8+0 mc PeekR mc ItemSet+0 mc Istr+3 dm 'd' dm 'e' dm 'v' ld cmd,atmp mc PeekR mc ItemSet+1 mc Int8+0 mc Alloc mc PeekR mc ItemSet+4 mc FromR mc Gget+root mc Lget+255 mc Retain mc Node__append__4NodeC_2FD_ mc Int8+1 mc Lget+255 mc Lget+255 mc Cpl mc init_device__4NodeC_6uint16_6uint16 mc Dup mc And0 mc Bra+3 mc Dup mc Int8+3 mc Ne mc BraIf0+18 mc Istr+8 dm ' ' dm 'e' dm 'r' dm 'r' dm 'o' dm 'r' dm ':' dm ' ' ld cmd,atmp mc Lget+255 mc numstr__6uint16_8ucs2charAE mc CatStrStr mc Istr+1 dm ' ' ld cmd,atmp mc CatStrStr mc LogStr mc Int8+1 mc Lvar+254 mc SlPoke mc Lget+255 mc BraIf1+2 mc MDrop0-1 mc Bra+2 mc MDrop0-1 mc Bra-38 mc SetIntMask mc Deselect mc Lget+255 mc find_stdio__4NodeC_ mc Istr+33 dm 10 dm 'S' dm 'T' dm 'O' dm 'P' dm 'P' dm 'E' dm 'D' dm ' ' dm 'a' dm 't' dm ' ' dm 'e' dm 'n' dm 'd' dm ' ' dm 'o' dm 'f' dm ' ' dm 'i' dm 'n' dm 'i' dm 't' dm '_' dm 'd' dm 'e' dm 'v' dm 'i' dm 'c' dm 'e' dm 's' dm '(' dm ')' ld cmd,atmp mc LogStr mc Todo mc MDrop0-1 mc CallKill mc implicit__dev__kill__4Node_4Node mc DropStr mc Ret : read_uint12__6uint16 ( -- uint16 ) Millicoded // Size: 18 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cReadByte__6uint16 mc Dup mc Int8+240 mc Ult mc BraIf0+2 mc Dup mc Bra+6 mc Dup mc Int8+15 mc And mc Sli15+15-8 mc i2cReadByte__6uint16 mc Add mc MNip0_Next-1 : read_block__6uint16AE ( -- uint16[] ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc read_uint12__6uint16 mc Dup mc Alloc mc Dup mc i2cReadData__6uint16AEC_ mc Dup mc Retain mc ToR mc DropStr mc MDrop0-1 mc FromR mc Ret : read_chunk__6uint16_6uint16AE ( uint16 -- uint16[] ) Millicoded // Size: 39 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc i2cReadByte__6uint16 mc read_block__6uint16AE mc Lget+255 mc Lget+253 mc Eq mc BraIf0+7 mc Dup mc Retain mc ToR mc DropStr mc MDrop0-1 mc FromR mc Bra+21 mc Lget+255 mc Int8+53 mc Uge mc And0 mc Bra+3 mc Lget+255 mc Int8+57 mc Ule mc Or1 mc Bra+3 mc Lget+255 mc Int8+69 mc Eq mc BraIf1+3 mc DropStr mc MDrop0-1 mc Bra+3 mc DropStr mc MDrop0-1 mc Bra-33 mc Int8+0 mc MNip0_Next-1 : init_device__4NodeC_6uint16_6uint16 ( Node˘, uint16 -- uint16 ) Millicoded // Size: 721 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc PushContext0 mc Dup mc Select mc Int8+0 mc i2cStartReadingAtAddress__6uint16_6uint16 mc BraIf0+3 mc Int8+3 mc Hi8+2 mc BraFar+193 mc Istr+13 dm '[' dm 'i' dm 'n' dm 'i' dm 't' dm '_' dm 'd' dm 'e' dm 'v' dm 'i' dm 'c' dm 'e' dm ':' ld cmd,atmp mc Lget+255 mc Msbit0 mc NumStr mc CatStrStr mc Istr+1 dm ']' ld cmd,atmp mc CatStrStr mc LogStr mc Int8+48 mc read_chunk__6uint16_6uint16AE mc Dup mc Not mc Or1 mc Bra+4 mc Dup mc Count mc Int8+8 mc Ne mc Or1 mc Bra+14 mc Dup mc Int8+0 mc Int8+4 mc SubStr mc Istr+4 dm 'K' dm '1' dm 'D' dm '1' ld cmd,atmp mc DupToR mc Ne_RangeCstr mc FromR mc DropStr mc BraIf0+6 mc Int8+101 mc ToR mc DropStr mc FromR mc Hi8+2 mc BraFar+136 mc Int8+49 mc read_chunk__6uint16_6uint16AE mc Dup mc Not mc Or1 mc Bra+4 mc Dup mc Count mc Int8+6 mc Ult mc BraIf0+7 mc Int8+102 mc ToR mc DropStr mc DropStr mc FromR mc Hi8+2 mc BraFar+118 mc Int8+50 mc read_chunk__6uint16_6uint16AE mc Dup mc BraIf1+8 mc Int8+103 mc ToR mc DropStr mc DropStr mc DropStr mc FromR mc Hi8+2 mc BraFar+106 mc Int8+51 mc read_chunk__6uint16_6uint16AE mc Dup mc BraIf1+9 mc Int8+104 mc ToR mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Hi8+2 mc BraFar+93 mc Int8+52 mc read_chunk__6uint16_6uint16AE mc Dup mc BraIf1+10 mc Int8+105 mc ToR mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Hi8+2 mc BraFar+79 mc Lget+253 mc Int8+0 mc AtIndexPeek mc Lget+252 mc Int8+1 mc AtIndexPeek mc Sli15+15-8 mc Add mc Lget+252 mc Int8+2 mc AtIndexPeek mc Lget+251 mc Int8+3 mc AtIndexPeek mc Lget+250 mc Int8+4 mc AtIndexPeek mc Lget+249 mc Int8+5 mc AtIndexPeek mc Int8+255 mc Int16+7 mc Lvar+251 mc AndPoke mc Lget+254 mc Addq+1 mc Dup mc Msbit mc Subq+3 mc Nip mc Int8+3 mc Lget+255 mc Umin mc Nip mc Int8+0 mc Lget+255 mc Umax mc Nip mc Lget+252 mc Int8+2 mc And mc Bool mc Int8+10 mc LogChar mc Lget+247 mc LogCstr mc Int8+58 mc LogChar mc Int8+9 mc LogChar mc Lget+248 mc LogCstr mc Int8+32 mc LogChar mc Lget+249 mc LogCstr mc Istr+8 dm ' ' dm '[' dm 's' dm 'p' dm 'e' dm 'e' dm 'd' dm ':' ld cmd,atmp mc LogStr mc Lget+255 mc LogNum mc Int8+93 mc LogChar mc Dup mc BraIf0+10 mc Istr+7 dm '[' dm 'b' dm 'u' dm 'r' dm 's' dm 't' dm ']' ld cmd,atmp mc LogStr mc Int8+65 mc read_chunk__6uint16_6uint16AE mc Dup mc BraIf1+12 mc Int8+106 mc ToR mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Hi8+1 mc BraFar+236 mc Int8+66 mc read_chunk__6uint16_6uint16AE mc Dup mc BraIf1+13 mc Int8+107 mc ToR mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Hi8+1 mc BraFar+219 mc Int8+12 mc Alloc mc Dup mc Lget+240 mc Lget+252 mc Lget+252 mc Lget+248 mc Lget+248 mc BytecodeCompiler__init__16BytecodeCompilerC_6uint16_6uint16AEC_6uint16AEC_6uint16_4bool_ mc Gget+gcode_ptr mc Gget+gcode_ptr mc i2cReadByte__6uint16 mc Int8+67 mc Ne mc BraIf0+17 mc Int8+108 mc ToR mc MDrop0-2 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Hi8+1 mc BraFar+187 mc read_uint12__6uint16 mc i2cReadByte__6uint16 mc i2cReadByte__6uint16 mc read_block__6uint16AE mc read_block__6uint16AE mc read_block__6uint16AE mc Int8+42 mc LogChar mc Lget+248 mc Lget+251 mc Lget+251 mc Lget+251 mc Lget+251 mc Retain mc Lget+251 mc BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16 mc Dup mc BraIf0+21 mc Dup mc ToR mc MDrop0-1 mc DropStr mc DropStr mc DropStr mc MDrop0-5 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Hi8+1 mc BraFar+148 mc Lget+251 mc Int8+8 mc Uge mc And0 mc Bra+3 mc Lget+251 mc Int8+31 mc Ule mc BraIf0+2 mc Gget+gcode_ptr mc Lset+249 mc Lget+251 mc BraIf1+6 mc MDrop0-1 mc DropStr mc DropStr mc DropStr mc MDrop0-3 mc Bra+6 mc MDrop0-1 mc DropStr mc DropStr mc DropStr mc MDrop0-3 mc Bra-85 mc Lget+254 mc ItemGet+11 mc Int8+8 mc AtIndexPeek mc Dup mc BraIf0+10 mc Lget+238 mc Msbit0 mc Lget+255 mc ItemGet+2 mc Lget+255 mc Poke mc Lget+237 mc Gvar+int_mask mc AndPoke mc MDrop0-1 mc Lget+253 mc ItemGet+11 mc Int8+0 mc AtIndexPeek mc Nip mc Dup mc ItemGet+2 mc Dup mc CallOpcode mc Lget+243 mc Int8+0 mc Int16+4 mc And mc And0 mc Bra+3 mc Gget+microsecs_per_int mc Int8+0 mc Eq mc BraIf0+43 mc Lget+252 mc ItemGet+11 mc Int8+1 mc AtIndexPeek mc Lset+255 mc Lget+255 mc BraIf0+36 mc Lget+255 mc ItemGet+2 mc Int8+16 mc Int16+39 mc Lget+255 mc CallOpcode mc Gset+microsecs_per_int mc Istr+16 dm '[' dm 't' dm 'i' dm 'm' dm 'e' dm 'r' dm ' ' dm 'p' dm 'e' dm 'r' dm 'i' dm 'o' dm 'd' dm ' ' dm '=' dm ' ' ld cmd,atmp mc Gget+microsecs_per_int mc NumStrU mc CatStrStr mc Istr+3 dm 181 dm 's' dm ']' ld cmd,atmp mc CatStrStr mc LogStr mc MDrop0-1 mc Lget+254 mc Gset+gcode_ptr mc Istr+12 dm '[' dm 'r' dm 'e' dm 's' dm 'i' dm 'd' dm 'e' dm 'n' dm 't' dm ' ' dm '=' dm ' ' ld cmd,atmp mc Gget+gcode_ptr mc Lget+251 mc Sub mc NumStr mc CatStrStr mc Istr+7 dm ' ' dm 'b' dm 'y' dm 't' dm 'e' dm 's' dm ']' ld cmd,atmp mc CatStrStr mc LogStr mc Int8+0 mc Lget+235 mc Lget+238 mc Retain mc Lget+254 mc numstr__6uint16_8ucs2charAE mc CatStrStr mc DupToR mc Node__find__4NodeC_8ucs2charAEC_2FDC mc FromR mc DropStr mc BraIf0+3 mc PshHP mc Incr mc Bra-14 mc Int8+10 mc init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P mc Int8+9 mc init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P mc Lget+255 mc And0 mc Bra+1 mc Dup mc BraIf1+16 mc Int8+109 mc ToR mc MDrop0-7 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Bra+229 mc Lget+240 mc Int8+4 mc And mc BraIf0+102 mc Int8+11 mc init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P mc Int8+12 mc init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P mc Int8+13 mc init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P mc Int8+14 mc init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P mc Lget+236 mc Int8+1 mc And mc And0 mc Bra+6 mc Lget+253 mc And0 mc Bra+2 mc Lget+254 mc Bool mc Not mc BraIf0+17 mc Int8+110 mc ToR mc MDrop0-8 mc MDrop0-3 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Bra+188 mc Lget+236 mc Int8+2 mc And mc And0 mc Bra+6 mc Lget+255 mc And0 mc Bra+2 mc Dup mc Bool mc Not mc BraIf0+17 mc Int8+111 mc ToR mc MDrop0-8 mc MDrop0-3 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Bra+159 mc Int8+0 mc Dup mc Lget+238 mc Ult mc BraIf0+29 mc Lget+232 mc Retain mc Lget+248 mc Lget+254 mc Add mc numstr__6uint16_8ucs2charAE mc CatStrStr mc Lget+243 mc ItemGet+9 mc Lget+254 mc Add mc Peek mc Lget+226 mc Lget+254 mc Lget+231 mc Lget+253 mc Lget+244 mc Lget+244 mc Lget+244 mc Lget+244 mc Lget+244 mc Lget+244 mc new__8ucs2charAEC_6uint16_8DrvrDataC_6uint16B8DrvrDataC6uint16D_4voidB8DrvrDataC6uint166uint16D_6uint16B8DrvrDataCD_6uint16B8DrvrDataC6uint16AEC6uint166uint16D_4voidB8DrvrDataC6uint16D_6uint16B8DrvrDataC6uint16AEC6uint166uint16D_12SerialDevice mc Node__append__4NodeC_2FD_ mc Lvar+254 mc Incr mc MDrop0-1 mc DropStr mc Bra-33 mc MDrop0-5 mc Bra+108 mc Lget+240 mc Int8+8 mc And mc BraIf0+88 mc Int8+15 mc init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P mc Int8+16 mc init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P mc Lget+238 mc Int8+1 mc And mc And0 mc Bra+2 mc Lget+255 mc Not mc BraIf0+17 mc Int8+112 mc ToR mc MDrop0-8 mc MDrop0-1 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Bra+90 mc Lget+238 mc Int8+2 mc And mc And0 mc Bra+2 mc Dup mc Not mc BraIf0+17 mc Int8+113 mc ToR mc MDrop0-8 mc MDrop0-1 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Bra+65 mc Int8+0 mc Dup mc Lget+240 mc Ult mc BraIf0+27 mc Lget+234 mc Retain mc Lget+250 mc Lget+254 mc Add mc numstr__6uint16_8ucs2charAE mc CatStrStr mc Lget+245 mc ItemGet+9 mc Lget+254 mc Add mc Peek mc Lget+228 mc Lget+254 mc Lget+233 mc Lget+253 mc Lget+246 mc Lget+246 mc Lget+246 mc Lget+246 mc new__8ucs2charAEC_6uint16_8DrvrDataC_6uint16B8DrvrDataC6uint16D_4voidB8DrvrDataC6uint166uint16D_3ErrB8DrvrDataC6uint326uint16AEC6uint166uint16D_3ErrB8DrvrDataC6uint326uint16AEC6uint166uint16D_11BlockDevice mc Node__append__4NodeC_2FD_ mc Lvar+254 mc Incr mc MDrop0-1 mc DropStr mc Bra-31 mc MDrop0-3 mc Bra+16 mc Int8+114 mc ToR mc MDrop0-7 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc Bra+15 mc Int8+0 mc ToR mc MDrop0-7 mc CallKill mc implicit__dev__kill__16BytecodeCompiler_16BytecodeCompiler mc DropStr mc DropStr mc DropStr mc MDrop0-7 mc DropStr mc DropStr mc DropStr mc DropStr mc DropStr mc FromR mc MNip0-2 mc PopContext0 mc Ret : init_device__4NodeC_6uint16_6uint16__procptr__6uint16_6uint16P ( uint16 -- uint16* ) Millicoded // Size: 19 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc XLvar+142 mc Peek mc ItemGet+11 mc Lget+255 mc AtIndexPeek mc BraIf0+7 mc XLvar+142 mc Peek mc ItemGet+11 mc Lget+255 mc AtIndexPeek mc ItemGet+2 mc Bra+1 mc Int8+0 mc MNip0_Next-1 : find_stdio__4NodeC_ ( Node˘ ) Millicoded // Size: 275 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Istr+13 dm 10 dm '[' dm 'f' dm 'i' dm 'n' dm 'd' dm '_' dm 's' dm 't' dm 'd' dm 'i' dm 'o' dm ']' ld cmd,atmp mc LogStr mc Int8+0 mc Int8+16 mc Alloc mc Int8+0 mc Lget+253 mc ItemGet+4 mc Count mc PshHP mc Peekmm mc BraIf0+33 mc Lget+252 mc ItemGet+4 mc Lget+255 mc AtIndexPeek mc Dup mc ItemGet+0 mc Int8+4 mc Eq mc And0 mc Bra+4 mc Dup mc ItemGet+4 mc Int8+16 mc And mc BraIf0+16 mc Dup mc ItemGet+4 mc Int8+1 mc And mc BraIf0+3 mc Dup mc Lvar+251 mc Append mc Dup mc ItemGet+4 mc Int8+2 mc And mc BraIf0+3 mc Dup mc Lvar+253 mc Append mc MDrop0-1 mc Bra-36 mc Istr+9 dm ' ' dm 'i' dm 'n' dm 'd' dm 'e' dm 'v' dm 's' dm ':' dm ' ' ld cmd,atmp mc LogStr mc Lget+253 mc Count mc LogNum mc Istr+10 dm ' ' dm 'o' dm 'u' dm 't' dm 'd' dm 'e' dm 'v' dm 's' dm ':' dm ' ' ld cmd,atmp mc LogStr mc Lget+255 mc Count mc LogNum mc Lget+255 mc Count mc Nip mc PshHP mc Peekmm mc BraIf0+50 mc Istr+33 dm 10 dm 10 dm 't' dm 'o' dm ' ' dm 's' dm 'e' dm 'l' dm 'e' dm 'c' dm 't' dm ' ' dm 't' dm 'e' dm 'r' dm 'm' dm 'i' dm 'n' dm 'a' dm 'l' dm ' ' dm 't' dm 'y' dm 'p' dm 'e' dm ' ' dm 39 dm '#' dm 39 dm ' ' dm '+' dm ' ' dm 39 ld cmd,atmp mc Lget+255 mc NumStrU mc CatStrStr mc Istr+2 dm 39 dm 10 ld cmd,atmp mc CatStrStr mc Lget+254 mc Lget+254 mc AtIndexPeek mc Lget+255 mc SerialDevice__writebytes__12SerialDeviceC_6uint16AEC_ mc DropStr mc Bra-53 mc Lget+253 mc Count mc Int8+0 mc Eq mc BraIf0+25 mc Istr+22 dm 'N' dm 'o' dm ' ' dm 'I' dm 'n' dm 'p' dm 'u' dm 't' dm ' ' dm 'D' dm 'e' dm 'v' dm 'i' dm 'c' dm 'e' dm ' ' dm 'F' dm 'o' dm 'u' dm 'n' dm 'd' dm '!' ld cmd,atmp mc PANIC__8ucs2charAE_ mc Istr+19 dm 10 dm 'W' dm 'a' dm 'i' dm 't' dm 'i' dm 'n' dm 'g' dm ' ' dm 'f' dm 'o' dm 'r' dm ' ' dm 'k' dm 'e' dm 'y' dm '.' dm '.' dm '.' ld cmd,atmp mc LogStr mc Int8+0 mc Lget+255 mc Int8+0 mc Eq mc BraIf0+6 mc Dup mc BraIf0+3 mc Int8+0 mc Nip mc Bra+1 mc Halt mc Lvar+255 mc ppPeek mc Lget+251 mc Count mc Remu mc Lset+255 mc Lget+252 mc Lget+254 mc AtIndexPeek mc Int8+4 mc Device__getctl__6DeviceC_6uint16_6uint16 mc BraIf0-22 mc Int8+1 mc Nip mc Lget+252 mc Lget+254 mc AtIndexPeek mc SerialDevice__readbyte__12SerialDeviceC_6uint16 mc Dup mc LogChar mc Lget+252 mc Lget+253 mc AtIndexPeek mc Int8+35 mc Eq mc BraIf0+25 mc Dup mc Subq+48 mc Dup mc Lget+251 mc Count mc Ult mc BraIf0+17 mc Lget+250 mc Lget+252 mc AtIndexPeek mc Retain mc Gset+stdin mc Lget+252 mc Lget+255 mc AtIndexPeek mc Retain mc Gset+stdout mc Lget+252 mc Lget+255 mc AtIndexPeek mc Retain mc Gset+stderr mc MDrop0-2 mc Bra+7 mc MDrop0-1 mc Dup mc Lget+251 mc Lget+252 mc AtIndexPoke mc MDrop0-1 mc Bra-67 mc MDrop0-2 mc DropStr mc DropStr mc DropStr mc MDrop0_Next-1 // --- file: "dev.asm" --- #include "FD.cc" // +++ file: "FD.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : implicit__FD__kill__8ucs2charAEAE_8ucs2charAEAE ( str_AE -- str_AE ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ForAllItems mc Bra+2 mc Peek mc DropStr mc mmNextItem mc Bra-4 mc Ret : implicit__FD__kill__2FD_2FD ( FD -- FD ) Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+1 mc DropStr mc Ret : implicit__FD__shrink__2FDAEC_6uint16_ ( FDs˘, uint16 ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup2 mc MidStr2 mc ForRange mc Bra+4 mc Peek_Clear mc CallKill mc implicit__FD__kill__2FD_2FD mc DropStr mc mmNextItem mc Bra-6 mc ShrinkStr mc Ret : FD__isrootdir__2FDC_4bool ( FD˘ -- bool ) Millicoded // Size: 24 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc And0 mc Bra+4 mc Dup mc ItemGet+0 mc Int8+1 mc Eq mc And0 mc Bra+3 mc Dup mc ItemGet+2 mc Bool mc And0 mc Bra+5 mc Dup mc ItemGet+2 mc ItemGet+0 mc Int8+0 mc Eq mc MNip0_Next-1 : FD__contains__2FDC_2FDC_4bool ( FD˘, FD˘ -- bool ) Millicoded // Size: 18 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc BraIf0+8 mc Dup mc Lget+254 mc Eq mc BraIf1+4 mc Dup mc ItemGet+2 mc Nip mc Bra-10 mc Dup mc Lget+254 mc Eq mc MNip0_Next-2 : FD__entries__2FDC_8ucs2charAEAE ( FD˘ -- str_AE ) Millicoded // Size: 24 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+0 mc Int8+1 mc Eq mc BraIf0+3 mc Dup mc FD__entries__2FDC_8ucs2charAEAE mc Bra+11 mc Dup mc ItemGet+0 mc Int8+0 mc Eq mc BraIf0+3 mc Dup mc Node__entries__4NodeC_8ucs2charAEAE mc Bra+3 mc Int8+6 mc Gset+errno mc Int8+0 mc MNip0_Next-1 : FD__find__2FDC_8ucs2charAEC_2FD ( FD˘, ucs2str˘ -- FD ) Millicoded // Size: 18 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc ItemGet+0 mc Int8+0 mc Eq mc BraIf0+5 mc Lget+255 mc Lget+255 mc Node__find__4NodeC_8ucs2charAEC_2FDC mc Retain mc Bra+3 mc Int8+6 mc Gset+errno mc Int8+0 mc MNip0_Next-2 : FD__getctl__2FDC_6uint16_6uint16 ( FD˘, uint16 -- uint16 ) Millicoded // Size: 21 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc ItemGet+0 mc Switch+5 mc Bra+5 mc Bra+10 mc Bra+9 mc Bra+4 mc Bra+3 mc Bra+6 mc Int8+0 mc Bra+5 mc Lget+255 mc Lget+255 mc Device__getctl__6DeviceC_6uint16_6uint16 mc Bra+1 mc Int8+0 mc MNip0_Next-2 : FD__setctl__2FDC_6uint16_6uint16_ ( FD˘, uint16, uint16 ) Millicoded // Size: 19 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc ItemGet+0 mc Switch+5 mc Bra+10 mc Bra+9 mc Bra+8 mc Bra+3 mc Bra+2 mc Bra+5 mc Bra+4 mc Lget+254 mc Lget+254 mc Lget+254 mc Device__setctl__6DeviceC_6uint16_6uint16_ mc MDrop0_Next-3 : FD__ioblocks__2FDC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ ( FD˘, uint32, uint16[]˘, uint16, uint16, bool, bool ) Millicoded // Size: 22 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+17 mc Gset+errno mc Lget+249 mc ItemGet+0 mc Subq+3 mc Switch+1 mc Bra+1 mc Bra+9 mc Lget+249 mc Lvar+249 mc Peek2 mc Lget+249 mc Lget+249 mc Lget+249 mc Lget+249 mc Lget+249 mc BlockDevice__ioblocks__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ mc MDrop0_Next-8 : FD__writeblocks8__2FDC_6uint32_6uint16AEC_6uint16_6uint16_ ( FD˘, uint32, uint16[]˘, uint16, uint16 ) // ioblocks(fd,startblock, data, a, e, no, yes); psh alu xor alu psh alu add_c alu // nodelay jp FD__ioblocks__2FDC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ : FD__readblocks8__2FDC_6uint32_6uint16AEC_6uint16_6uint16_ ( FD˘, uint32, uint16[]˘, uint16, uint16 ) // ioblocks(fd,startblock,data,a,e,no,no); psh alu xor alu psh alu jp FD__ioblocks__2FDC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ : FD__writeblocks16__2FDC_6uint32_6uint16AEC_6uint16_6uint16_ ( FD˘, uint32, uint16[]˘, uint16, uint16 ) // ioblocks(fd,startblock,data,a,e,yes,yes); psh alu ld alu,1 psh alu jp FD__ioblocks__2FDC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ : FD__readblocks16__2FDC_6uint32_6uint16AEC_6uint16_6uint16_ ( FD˘, uint32, uint16[]˘, uint16, uint16 ) // ioblocks(fd,startblock,data,a,e,yes,no); psh alu psh 1 xor alu jp FD__ioblocks__2FDC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ : FD__getavail__2FDC_6uint16 ( FD˘ -- uint16 ) Millicoded // Size: 15 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Dup mc SerialDevice__getavail__12SerialDeviceC_6uint16 mc Bra+1 mc Int8+0 mc MNip0_Next-1 : FD__getfree__2FDC_6uint16 ( FD˘ -- uint16 ) Millicoded // Size: 15 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Dup mc SerialDevice__getfree__12SerialDeviceC_6uint16 mc Bra+1 mc Int8+0 mc MNip0_Next-1 : FD__readbyte__2FDC_6uint16 ( FD˘ -- uint16 ) Millicoded // Size: 44 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Dup mc SerialDevice__readbyte__12SerialDeviceC_6uint16 mc Bra+30 mc Istr+9 dm 'n' dm 'o' dm 'd' dm 'e' dm 't' dm 'y' dm 'p' dm 'e' dm '(' ld cmd,atmp mc Lget+255 mc ItemGet+1 mc catstr__8ucs2charAE_8ucs2charAEC_8ucs2charAE mc Istr+2 dm ')' dm '=' ld cmd,atmp mc DupToR mc catstr__8ucs2charAE_8ucs2charAEC_8ucs2charAE mc Lget+255 mc ItemGet+0 mc NumStrU mc CatStrStr mc FromR mc DropStr mc abort__8ucs2charAE_ mc Int8+17 mc Gset+errno mc Int8+0 mc MNip0_Next-1 : FD__writebyte__2FDC_6uint16_ ( FD˘, uint16 ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+17 mc Gset+errno mc Lget+255 mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Lget+255 mc Lget+255 mc SerialDevice__writebyte__12SerialDeviceC_6uint16_ mc MDrop0_Next-2 : FD__read2bytes__2FDC_6uint32 ( FD˘ -- uint32 ) Millicoded // Size: 17 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+3 mc BraIf0+3 mc Dup mc FD__read__2FDC_6uint32 mc Bra+3 mc Dup mc FD__read__2FDC_6uint16 mc Cast_uL mc ToR2 mc MDrop0-1 mc FromR2 mc Ret : FD__write2bytes__2FDC_6uint32_ ( FD˘, uint32 ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc ItemGet+3 mc BraIf0+5 mc Lget+254 mc Lvar+254 mc Peek2 mc FD__write__2FDC_6uint32_ mc Bra+3 mc Lget+254 mc Lget+255 mc FD__write__2FDC_6uint16_ mc MDrop0_Next-3 : FD__readbytes__2FDC_6uint16AEC_ ( FD˘, uint16[]˘ ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+17 mc Gset+errno mc Lget+255 mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Lget+255 mc Lget+255 mc SerialDevice__readbytes__12SerialDeviceC_6uint16AEC_ mc MDrop0_Next-2 : FD__writebytes__2FDC_6uint16AEC_ ( FD˘, uint16[]˘ ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+17 mc Gset+errno mc Lget+255 mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Lget+255 mc Lget+255 mc SerialDevice__writebytes__12SerialDeviceC_6uint16AEC_ mc MDrop0_Next-2 : FD__readdata__2FDC_6uint16AEC_ ( FD˘, uint16[]˘ ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+17 mc Gset+errno mc Lget+255 mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Lget+255 mc Lget+255 mc SerialDevice__readdata__12SerialDeviceC_6uint16AEC_ mc MDrop0_Next-2 : FD__writedata__2FDC_6uint16AEC_ ( FD˘, uint16[]˘ ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+17 mc Gset+errno mc Lget+255 mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Lget+255 mc Lget+255 mc SerialDevice__writedata__12SerialDeviceC_6uint16AEC_ mc MDrop0_Next-2 : FD__read15__2FDC_6uint16 ( FD˘ -- uint16 ) Millicoded // Size: 24 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc FD__readbyte__2FDC_6uint16 mc Dup mc Int8+128 mc Ult mc Or1 mc Bra+2 mc Lget+255 mc ItemGet+3 mc BraIf0+2 mc Dup mc Bra+7 mc Dup mc Int8+127 mc And mc SwapBytes mc Lget+254 mc FD__readbyte__2FDC_6uint16 mc Or mc MNip0_Next-2 : FD__write15__2FDC_6uint16_ ( FD˘, uint16 ) Millicoded // Size: 26 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc clear_error mc Dup mc Int8+127 mc Ugt mc And0 mc Bra+3 mc Lget+255 mc ItemGet+3 mc Not mc BraIf0+6 mc Lget+255 mc Lget+255 mc SwapBytes mc Int8+128 mc Or mc FD__writebyte__2FDC_6uint16_ mc Gget+errno mc BraIf1+3 mc Lget+255 mc Lget+255 mc FD__writebyte__2FDC_6uint16_ mc MDrop0_Next-2 : FD__read__2FDC_6uint16 ( FD˘ -- uint16 ) Millicoded // Size: 20 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc FD__readbyte__2FDC_6uint16 mc Lget+255 mc ItemGet+3 mc Or1 mc Bra+1 mc Gget+errno mc BraIf0+2 mc Dup mc Bra+5 mc Dup mc SwapBytes mc Lget+254 mc FD__readbyte__2FDC_6uint16 mc Or mc MNip0_Next-2 : FD__write__2FDC_6uint16_ ( FD˘, uint16 ) Millicoded // Size: 18 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc clear_error mc Lget+255 mc ItemGet+3 mc BraIf1+4 mc Lget+255 mc Lget+255 mc SwapBytes mc FD__writebyte__2FDC_6uint16_ mc Gget+errno mc BraIf1+3 mc Lget+255 mc Lget+255 mc FD__writebyte__2FDC_6uint16_ mc MDrop0_Next-2 : FD__read24__2FDC_6uint32 ( FD˘ -- uint32 ) Millicoded // Size: 20 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Int8+0 mc Lget+254 mc FD__readbyte__2FDC_6uint16 mc Lset+255 mc Gget+errno mc BraIf1+3 mc Lget+254 mc FD__read__2FDC_6uint16 mc Nip mc Lvar+255 mc Peek2 mc ToR2 mc MDrop0-3 mc FromR2 mc Ret : FD__write24__2FDC_6uint32_ ( FD˘, uint32 ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc Lget+254 mc FD__writebyte__2FDC_6uint16_ mc Gget+errno mc BraIf1+3 mc Lget+254 mc Lget+255 mc FD__write__2FDC_6uint16_ mc MDrop0_Next-3 : FD__read__2FDC_6uint32 ( FD˘ -- uint32 ) Millicoded // Size: 20 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Int8+0 mc Lget+254 mc FD__read__2FDC_6uint16 mc Lset+255 mc Gget+errno mc BraIf1+3 mc Lget+254 mc FD__read__2FDC_6uint16 mc Nip mc Lvar+255 mc Peek2 mc ToR2 mc MDrop0-3 mc FromR2 mc Ret : FD__write__2FDC_6uint32_ ( FD˘, uint32 ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc Lget+254 mc FD__write__2FDC_6uint16_ mc Gget+errno mc BraIf1+3 mc Lget+254 mc Lget+255 mc FD__write__2FDC_6uint16_ mc MDrop0_Next-3 : FD__read__2FDC_7float48 ( FD˘ -- float48 ) Millicoded // Size: 23 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Int8+0 mc Int8+0 mc Lget+253 mc FD__read__2FDC_6uint16 mc Lset+254 mc Gget+errno mc BraIf1+5 mc Lget+253 mc FD__read__2FDC_6uint32 mc Lvar+252 mc Addq+1 mc Poke2 mc Lvar+254 mc Peek3 mc ToR3 mc MDrop0-4 mc FromR3 mc Ret : FD__write__2FDC_7float48_ ( FD˘, float48 ) Millicoded // Size: 15 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc Lget+253 mc FD__write__2FDC_6uint16_ mc Gget+errno mc BraIf1+5 mc Lget+253 mc Lvar+253 mc Addq+1 mc Peek2 mc FD__write__2FDC_6uint32_ mc MDrop0_Next-4 : FD__read__2FDC_8ucs2charAE ( FD˘ -- ucs2str ) Millicoded // Size: 19 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc FD__read15__2FDC_6uint16 mc Alloc mc Gget+errno mc BraIf1+3 mc Lget+255 mc Lget+255 mc FD__readbytes__2FDC_6uint16AEC_ mc Dup mc Retain mc ToR mc DropStr mc MDrop0-1 mc FromR mc Ret : FD__write__2FDC_8ucs2charAEC_ ( FD˘, ucs2str˘ ) Millicoded // Size: 14 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc Count mc FD__write15__2FDC_6uint16_ mc Gget+errno mc BraIf1+3 mc Lget+255 mc Lget+255 mc FD__writebytes__2FDC_6uint16AEC_ mc MDrop0_Next-2 : FD__getstr__2FDC_8ucs2charAE ( FD˘ -- ucs2str ) Millicoded // Size: 18 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+0 mc Subq+4 mc Switch+1 mc Bra+1 mc Bra+3 mc Dup mc SerialDevice__getstr__12SerialDeviceC_8ucs2charAE mc Bra+4 mc Int8+17 mc Gset+errno mc Istr+0 ld cmd,atmp mc MNip0_Next-1 : FD__putstr__2FDC_8ucs2charAE_ ( FD˘, ucs2str ) Millicoded // Size: 9 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc FD__writebytes__2FDC_6uint16AEC_ mc DropStr mc MDrop0_Next-1 : Node__entries__4NodeC_8ucs2charAEAE ( Node˘ -- str_AE ) Millicoded // Size: 33 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+4 mc Count mc Dup mc Alloc mc Lvar+255 mc Peekmm mc BraIf0+12 mc Lget+254 mc ItemGet+4 mc Lget+254 mc AtIndexPeek mc ItemGet+1 mc Retain mc Lget+255 mc Lget+253 mc AtIndex mc SwapWithVar mc DropStr mc Bra-15 mc Dup mc Retain mc ToR mc CallKill mc implicit__FD__kill__8ucs2charAEAE_8ucs2charAEAE mc DropStr mc MDrop0-2 mc FromR mc Ret : Node__find__4NodeC_8ucs2charAEC_2FDC ( Node˘, ucs2str˘ -- FD˘ ) Millicoded // Size: 24 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc ItemGet+4 mc Dup mc Count mc PshHP mc Peekmm mc BraIf0+11 mc Lget+255 mc Lget+255 mc AtIndexPeek mc ItemGet+1 mc Lget+253 mc Eq_CstrCstr mc BraIf0-10 mc Lget+255 mc Lget+255 mc AtIndexPeek mc Bra+1 mc Int8+0 mc MNip0_Next-4 : Node__append__4NodeC_2FD_ ( Node˘, FD ) Millicoded // Size: 16 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc ItemGet+4 mc Lget+255 mc Retain mc AppendChar mc Lget+255 mc Lget+255 mc ItemSet+2 mc CallKill mc implicit__FD__kill__2FD_2FD mc DropStr mc MDrop0_Next-1 : Node__remove__4NodeC_2FDC_ ( Node˘, FD˘ ) Millicoded // Size: 27 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc ItemGet+4 mc Dup mc Count mc Dup mc PshHP mc Peekmm mc BraIf0+14 mc Lget+254 mc Lget+255 mc AtIndexPeek mc Lget+252 mc Eq mc BraIf0-9 mc Lget+254 mc Lget+255 mc Lget+253 mc RolRange mc Lget+254 mc Lvar+254 mc mmPeek mc implicit__FD__shrink__2FDAEC_6uint16_ mc MDrop0_Next-5 // --- file: "FD.asm" --- #include "SerialDevice.cc" // +++ file: "SerialDevice.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : implicit__SerialDevice__shrink__6uint16AEC_6uint16_ ( uint16[]˘, uint16 ) Millicoded // Size: 6 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc ShrinkStr mc Ret : SerialDevice__getavail__12SerialDeviceC_6uint16 ( SerialDevice˘ -- uint16 ) // next_m this.getctl(ioctl_in_avail); psh alu ld alu,4 // ioctl_in_avail: in dev.h jp Device__getctl__6DeviceC_6uint16_6uint16 : SerialDevice__getfree__12SerialDeviceC_6uint16 ( SerialDevice˘ -- uint16 ) // next_m this.getctl(ioctl_out_free); psh alu ld alu,5 // ioctl_out_free: in dev.h jp Device__getctl__6DeviceC_6uint16_6uint16 : SerialDevice__readbyte__12SerialDeviceC_6uint16 ( SerialDevice˘ -- uint16 ) Millicoded // Size: 22 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+6 mc Dup mc ItemGet+5 mc Lget+255 mc ItemGet+8 mc CallMillicode mc Bra+5 mc Dup mc ItemGet+5 mc Lget+255 mc ItemGet+8 mc CallOpcode mc MNip0_Next-1 : SerialDevice__writebyte__12SerialDeviceC_6uint16_ ( SerialDevice˘, uint16 ) Millicoded // Size: 24 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+7 mc Lget+255 mc ItemGet+5 mc Lget+255 mc Lget+253 mc ItemGet+10 mc CallMillicode mc Bra+6 mc Lget+255 mc ItemGet+5 mc Lget+255 mc Lget+253 mc ItemGet+10 mc CallOpcode mc MDrop0_Next-2 : SerialDevice__readbytes__12SerialDeviceC_6uint16AEC_6uint16_6uint16_6uint16 ( SerialDevice˘, uint16[]˘, uint16, uint16 -- uint16 ) Millicoded // Size: 28 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+9 mc Lget+253 mc ItemGet+5 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+249 mc ItemGet+9 mc CallMillicode mc Bra+8 mc Lget+253 mc ItemGet+5 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+249 mc ItemGet+9 mc CallOpcode mc MNip0_Next-4 : SerialDevice__writebytes__12SerialDeviceC_6uint16AEC_6uint16_6uint16_6uint16 ( SerialDevice˘, uint16[]˘, uint16, uint16 -- uint16 ) Millicoded // Size: 28 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+253 mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+9 mc Lget+253 mc ItemGet+5 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+249 mc ItemGet+11 mc CallMillicode mc Bra+8 mc Lget+253 mc ItemGet+5 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+249 mc ItemGet+11 mc CallOpcode mc MNip0_Next-4 : SerialDevice__readbytes__12SerialDeviceC_6uint16AEC_ ( SerialDevice˘, uint16[]˘ ) Millicoded // Size: 45 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Lget+255 mc Count mc Lget+253 mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+13 mc Lget+253 mc ItemGet+5 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+251 mc Sub mc Lget+249 mc ItemGet+9 mc CallMillicode mc Lvar+254 mc AddPoke mc Bra+12 mc Lget+253 mc ItemGet+5 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+251 mc Sub mc Lget+249 mc ItemGet+9 mc CallOpcode mc Lvar+254 mc AddPoke mc Lget+255 mc Lget+255 mc Ult mc BraIf0+2 mc Halt mc Bra-37 mc MDrop0_Next-4 : SerialDevice__writebytes__12SerialDeviceC_6uint16AEC_ ( SerialDevice˘, uint16[]˘ ) Millicoded // Size: 45 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Lget+255 mc Count mc Lget+253 mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+13 mc Lget+253 mc ItemGet+5 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+251 mc Sub mc Lget+249 mc ItemGet+11 mc CallMillicode mc Lvar+254 mc AddPoke mc Bra+12 mc Lget+253 mc ItemGet+5 mc Lget+253 mc Lget+253 mc Lget+253 mc Lget+251 mc Sub mc Lget+249 mc ItemGet+11 mc CallOpcode mc Lvar+254 mc AddPoke mc Lget+255 mc Lget+255 mc Ult mc BraIf0+2 mc Halt mc Bra-37 mc MDrop0_Next-4 : SerialDevice__readdata__12SerialDeviceC_6uint16AEC_ ( SerialDevice˘, uint16[]˘ ) Millicoded // Size: 44 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc ItemGet+3 mc BraIf0+4 mc Lget+255 mc Lget+255 mc SerialDevice__readbytes__12SerialDeviceC_6uint16AEC_ mc Bra+32 mc Int8+64 mc Alloc mc Int8+0 mc Int8+0 mc Int8+32 mc Lget+252 mc Count mc Lget+253 mc Sub mc Umin mc Nip mc Dup mc BraIf0+17 mc Lvar+254 mc PeekNZ mc Lget+255 mc Sli15+15-1 mc implicit__SerialDevice__shrink__6uint16AEC_6uint16_ mc Lget+252 mc Lget+253 mc SerialDevice__readbytes__12SerialDeviceC_6uint16AEC_ mc Lget+254 mc Int8+0 mc Lget+251 mc Lget+252 mc copy_i8_to_i16__6uint16AEC_6uint16_6uint16AEC_6uint16_ mc Dup mc Lvar+254 mc AddPoke mc Bra-26 mc MDrop0-2 mc DropStr mc MDrop0_Next-2 : SerialDevice__writedata__12SerialDeviceC_6uint16AEC_ ( SerialDevice˘, uint16[]˘ ) Millicoded // Size: 44 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc ItemGet+3 mc BraIf0+4 mc Lget+255 mc Lget+255 mc SerialDevice__writebytes__12SerialDeviceC_6uint16AEC_ mc Bra+32 mc Int8+64 mc Alloc mc Int8+0 mc Int8+0 mc Int8+32 mc Lget+252 mc Count mc Lget+253 mc Sub mc Umin mc Nip mc Dup mc BraIf0+17 mc Lvar+254 mc PeekNZ mc Lget+255 mc Sli15+15-1 mc implicit__SerialDevice__shrink__6uint16AEC_6uint16_ mc Lget+253 mc Lget+254 mc Lget+252 mc Int8+0 mc copy_i16_to_i8__6uint16AEC_6uint16_6uint16AEC_6uint16_ mc Lget+252 mc Lget+253 mc SerialDevice__writebytes__12SerialDeviceC_6uint16AEC_ mc Dup mc Lvar+254 mc AddPoke mc Bra-26 mc MDrop0-2 mc DropStr mc MDrop0_Next-2 : SerialDevice__getstr__12SerialDeviceC_8ucs2charAE ( SerialDevice˘ -- ucs2str ) Millicoded // Size: 50 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+50 mc Int8+0 mc Lget+255 mc Alloc mc Int8+0 mc Lget+254 mc Lget+252 mc Eq mc BraIf0+7 mc Int8+50 mc Lvar+252 mc AddPoke mc Lvar+255 mc PeekNZ mc Lget+252 mc GrowStr mc Lget+252 mc SerialDevice__readbyte__12SerialDeviceC_6uint16 mc Nip mc Dup mc Int8+16 mc Ult mc And0 mc Bra+4 mc Dup mc Int8+17 mc Int16+52 mc And mc BraIf1+6 mc Dup mc Lget+254 mc Lvar+252 mc Peekpp mc AtIndexPoke mc Bra-30 mc Lget+255 mc Int8+0 mc Lget+252 mc SubStr mc Cast_RangeStr mc ToR mc MDrop0-1 mc DropStr mc MDrop0-3 mc FromR mc Ret : new__8ucs2charAEC_6uint16_8DrvrDataC_6uint16B8DrvrDataC6uint16D_4voidB8DrvrDataC6uint166uint16D_6uint16B8DrvrDataCD_6uint16B8DrvrDataC6uint16AEC6uint166uint16D_4voidB8DrvrDataC6uint16D_6uint16B8DrvrDataC6uint16AEC6uint166uint16D_12SerialDevice ( ucs2str˘, uint16, DrvrData˘, t_getctl, t_setctl, t_getc, t_gets, t_putc, t_gets -- SerialDevice ) Millicoded // Size: 48 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+12 mc Alloc mc ToR mc Int8+4 mc PeekR mc ItemSet+0 mc Lget+248 mc Retain mc PeekR mc ItemSet+1 mc Lget+249 mc Int8+32 mc And mc Int8+0 mc Ne mc PeekR mc ItemSet+3 mc Lget+249 mc PeekR mc ItemSet+4 mc Lget+250 mc PeekR mc ItemSet+5 mc Lget+251 mc PeekR mc ItemSet+6 mc Lget+252 mc PeekR mc ItemSet+7 mc Lget+253 mc PeekR mc ItemSet+8 mc Lget+254 mc PeekR mc ItemSet+9 mc Lget+255 mc PeekR mc ItemSet+10 mc Dup mc PeekR mc ItemSet+11 mc FromR mc MNip0-8 mc MNip0_Next-1 // --- file: "SerialDevice.asm" --- #include "Device.cc" // +++ file: "Device.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:39 : Device__getctl__6DeviceC_6uint16_6uint16 ( Device˘, uint16 -- uint16 ) Millicoded // Size: 28 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Lget+254 mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+8 mc Lget+254 mc ItemGet+5 mc Lget+254 mc Lget+252 mc ItemGet+6 mc CallMillicode mc Nip mc Bra+7 mc Lget+254 mc ItemGet+5 mc Lget+254 mc Lget+252 mc ItemGet+6 mc CallOpcode mc Nip mc Dup mc MNip0_Next-3 : Device__setctl__6DeviceC_6uint16_6uint16_ ( Device˘, uint16, uint16 ) Millicoded // Size: 26 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+254 mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+8 mc Lget+254 mc ItemGet+5 mc Lget+254 mc Lget+254 mc Lget+251 mc ItemGet+7 mc CallMillicode mc Bra+7 mc Lget+254 mc ItemGet+5 mc Lget+254 mc Lget+254 mc Lget+251 mc ItemGet+7 mc CallOpcode mc MDrop0_Next-3 // --- file: "Device.asm" --- #include "BlockDevice.cc" // +++ file: "BlockDevice.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:40 : BlockDevice__ioblocks__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ ( BlockDevice˘, uint32, uint16[]˘, uint16, uint16, bool, bool ) Millicoded // Size: 133 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc clear_error mc Lget+253 mc Lget+253 mc Eq mc BraIf1+123 mc Lget+255 mc Lget+248 mc ItemGet+3 mc Eq mc BraIf0+36 mc Dup mc BraIf0+3 mc Lget+249 mc ItemGet+12 mc Bra+2 mc Lget+249 mc ItemGet+11 mc Lget+248 mc ItemGet+4 mc Int8+0 mc Int16+128 mc And mc BraIf0+11 mc Lget+248 mc ItemGet+5 mc Lvar+248 mc Peek2 mc Lget+248 mc Lget+248 mc Lget+248 mc Lget+250 mc CallMillicode mc Gset+errno mc Bra+10 mc Lget+248 mc ItemGet+5 mc Lvar+248 mc Peek2 mc Lget+248 mc Lget+248 mc Lget+248 mc Lget+250 mc CallOpcode mc Gset+errno mc MDrop0-1 mc Bra+82 mc Int8+64 mc Lget+254 mc Sru mc Int8+1 mc Lget+247 mc ItemGet+8 mc Sl mc Umax mc Dup mc Lget+247 mc ItemGet+8 mc Sru mc Lget+253 mc BraIf0+3 mc Lget+255 mc Sli15+15-1 mc Bra+2 mc Lget+255 mc Sru15+15-1 mc Dup mc Alloc mc Lget+252 mc BraIf0+13 mc Lget+251 mc BraIf0+6 mc Lget+248 mc Lget+248 mc Lget+254 mc Int8+0 mc copy_i16_to_i8__6uint16AEC_6uint16_6uint16AEC_6uint16_ mc Bra+5 mc Lget+248 mc Lget+248 mc Lget+254 mc Int8+0 mc copy_i8_to_i16__6uint16AEC_6uint16_6uint16AEC_6uint16_ mc Lget+255 mc Lget+249 mc Lget+247 mc Sub mc Umin mc Lset+255 mc Lget+245 mc Lvar+245 mc Peek2 mc Lget+253 mc Int8+0 mc Lget+250 mc Lget+245 mc Lget+245 mc BlockDevice__ioblocks__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ mc Gget+errno mc BraIf1+27 mc Lget+252 mc BraIf1+13 mc Lget+251 mc BraIf0+6 mc Dup mc Int8+0 mc Lget+246 mc Lget+246 mc copy_i8_to_i16__6uint16AEC_6uint16_6uint16AEC_6uint16_ mc Bra+5 mc Dup mc Int8+0 mc Lget+246 mc Lget+246 mc copy_i16_to_i8__6uint16AEC_6uint16_6uint16AEC_6uint16_ mc Lget+253 mc Lvar+248 mc AddPoke mc Lget+249 mc Lget+249 mc Ult mc BraIf0+5 mc Lget+254 mc Cast_uL mc Lvar+244 mc AddPokeL mc Bra-59 mc DropStr mc MDrop0-3 mc MDrop0_Next-8 : BlockDevice__writeblocks8__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_ ( BlockDevice˘, uint32, uint16[]˘, uint16, uint16 ) // z.ioblocks(block,blocks,bu,idx,0/*small*/,1/*write*/); psh alu xor alu psh alu add_c alu // nodelay jp BlockDevice__ioblocks__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ : BlockDevice__readblocks8__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_ ( BlockDevice˘, uint32, uint16[]˘, uint16, uint16 ) // z.ioblocks(block,blocks,bu,idx,0/*small*/,0/*read*/); psh alu xor alu psh alu jp BlockDevice__ioblocks__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ : BlockDevice__writeblocks16__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_ ( BlockDevice˘, uint32, uint16[]˘, uint16, uint16 ) // z.ioblocks(block,blocks,bu,idx,1/*wide*/,1/*write*/); psh alu ld alu,1 psh alu jp BlockDevice__ioblocks__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ : BlockDevice__readblocks16__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_ ( BlockDevice˘, uint32, uint16[]˘, uint16, uint16 ) // z.ioblocks(block,blocks,bu,idx,1/*wide*/,0/*read*/); psh alu psh 1 xor alu jp BlockDevice__ioblocks__11BlockDeviceC_6uint32_6uint16AEC_6uint16_6uint16_4bool_4bool_ : new__8ucs2charAEC_6uint16_8DrvrDataC_6uint16B8DrvrDataC6uint16D_4voidB8DrvrDataC6uint166uint16D_3ErrB8DrvrDataC6uint326uint16AEC6uint166uint16D_3ErrB8DrvrDataC6uint326uint16AEC6uint166uint16D_11BlockDevice ( ucs2str˘, uint16, DrvrData˘, t_getctl, t_setctl, t_readblocks, t_readblocks -- BlockDevice ) Millicoded // Size: 88 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Int8+0 mc Int8+0 mc Lget+248 mc Int8+0 mc Int16+128 mc And mc BraIf0+16 mc Lget+249 mc Int8+7 mc Lget+248 mc CallMillicode mc Lset+254 mc Lget+249 mc Int8+9 mc Lget+248 mc CallMillicode mc Lget+248 mc Int8+8 mc Lget+247 mc CallMillicode mc Lvar+253 mc Poke2 mc Bra+15 mc Lget+249 mc Int8+7 mc Lget+248 mc CallOpcode mc Lset+254 mc Lget+249 mc Int8+9 mc Lget+248 mc CallOpcode mc Lget+248 mc Int8+8 mc Lget+247 mc CallOpcode mc Lvar+253 mc Poke2 mc Int8+13 mc Alloc mc ToR mc Int8+3 mc PeekR mc ItemSet+0 mc Lget+247 mc Retain mc PeekR mc ItemSet+1 mc Lget+248 mc Int8+32 mc And mc Bool mc PeekR mc ItemSet+3 mc Lget+248 mc PeekR mc ItemSet+4 mc Lget+249 mc PeekR mc ItemSet+5 mc Lget+250 mc PeekR mc ItemSet+6 mc Lget+251 mc PeekR mc ItemSet+7 mc Lget+254 mc PeekR mc ItemSet+8 mc Lvar+255 mc Peek2 mc PeekR mc Item+9 mc Poke2 mc Lget+252 mc PeekR mc ItemSet+11 mc Lget+253 mc PeekR mc ItemSet+12 mc FromR mc MNip0-8 mc MNip0_Next-2 : new__8ucs2charAEC_15NullBlockDevice ( ucs2str˘ -- NullBlockDevice ) Millicoded // Size: 18 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+11 mc Int16+128 mc Int8+0 mc Int8+null_getctl__8DrvrDataC_6uint16_6uint16&$FF mc Int16+(null_getctl__8DrvrDataC_6uint16_6uint16>>8)&$FF mc Int8+null_setctl__8DrvrDataC_6uint16_6uint16_&$FF mc Int16+(null_setctl__8DrvrDataC_6uint16_6uint16_>>8)&$FF mc Int8+null_io__8DrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err&$FF mc Int16+(null_io__8DrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err>>8)&$FF mc Int8+null_io__8DrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err&$FF mc Int16+(null_io__8DrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err>>8)&$FF mc new__8ucs2charAEC_6uint16_8DrvrDataC_6uint16B8DrvrDataC6uint16D_4voidB8DrvrDataC6uint166uint16D_3ErrB8DrvrDataC6uint326uint16AEC6uint166uint16D_3ErrB8DrvrDataC6uint326uint16AEC6uint166uint16D_11BlockDevice mc MNip0_Next-1 : null_getctl__8DrvrDataC_6uint16_6uint16 ( DrvrData˘, uint16 -- uint16 ) Millicoded // Size: 6 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc MNip0_Next-2 : null_setctl__8DrvrDataC_6uint16_6uint16_ ( DrvrData˘, uint16, uint16 ) Millicoded // Size: 5 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc MDrop0_Next-3 : null_io__8DrvrDataC_6uint32_6uint16AEC_6uint16_6uint16_3Err ( DrvrData˘, uint32, uint16[]˘, uint16, uint16 -- Err ) Millicoded // Size: 6 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc MNip0_Next-6 // --- file: "BlockDevice.asm" --- #if include_filesystem//skipping: #include "Block.cc" #include "File.cc" #include "Dir.cc" #endif #include "99_bottles_of_beer.cc" // +++ file: "99_bottles_of_beer.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:40 : bob__5int16_8ucs2charAE ( int16 -- ucs2str ) Millicoded // Size: 56 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+0 mc Gt mc BraIf0+3 mc Dup mc numstr__5int16_8ucs2charAE mc Bra+15 mc Dup mc BraIf0+2 mc Int8+78 mc Bra+1 mc Int8+110 mc CharStr mc Istr+6 dm 'o' dm ' ' dm 'm' dm 'o' dm 'r' dm 'e' ld cmd,atmp mc CatStrStr mc Istr+7 dm ' ' dm 'b' dm 'o' dm 'd' dm 'd' dm 'l' dm 'e' ld cmd,atmp mc CatStrStr mc Lget+255 mc Subq+1 mc BraIf0+4 mc Istr+1 dm 's' ld cmd,atmp mc Bra+2 mc Istr+0 ld cmd,atmp mc CatStrStr mc Istr+6 dm ' ' dm 'o' dm 'f' dm ' ' dm 248 dm 'l' ld cmd,atmp mc CatStrStr mc MNip0_Next-1 : bobo__5int16_8ucs2charAE ( int16 -- ucs2str ) Millicoded // Size: 22 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc bob__5int16_8ucs2charAE mc Istr+12 dm ' ' dm 'o' dm 'n' dm ' ' dm 't' dm 'h' dm 'e' dm ' ' dm 'w' dm 229 dm 'l' dm 'l' ld cmd,atmp mc CatStrStr mc MNip0_Next-1 : sing_99_bottles_of_beer__2FDC_5int16_ ( FD˘, int16 ) Millicoded // Size: 121 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Lget+255 mc Lget+254 mc Not mc Sub mc bobo__5int16_8ucs2charAE mc Istr+2 dm ',' dm ' ' ld cmd,atmp mc CatStrStr mc Lget+254 mc bob__5int16_8ucs2charAE mc CatStrStr mc Int8+46 mc CatStrChar mc Int8+10 mc CatStrChar mc FD__putstr__2FDC_8ucs2charAE_ mc Dup mc Int8+0 mc Gt mc BraIf0+48 mc Lget+255 mc Istr+33 dm 'T' dm 'a' dm 'k' dm 'e' dm ' ' dm 'o' dm 'n' dm 'e' dm ' ' dm 'd' dm 'o' dm 'w' dm 'n' dm ' ' dm 'a' dm 'n' dm 'd' dm ' ' dm 'p' dm 'a' dm 's' dm 's' dm ' ' dm 'i' dm 't' dm ' ' dm 'a' dm 'r' dm 'o' dm 'u' dm 'n' dm ',' dm ' ' ld cmd,atmp mc Lvar+254 mc mmPeek mc bobo__5int16_8ucs2charAE mc CatStrStr mc Istr+3 dm '.' dm 10 dm 10 ld cmd,atmp mc CatStrStr mc FD__putstr__2FDC_8ucs2charAE_ mc Bra-71 mc Lget+255 mc Istr+34 dm 'G' dm 'o' dm 't' dm 'o' dm ' ' dm 't' dm 'h' dm 'e' dm ' ' dm 's' dm 't' dm 'o' dm 'r' dm 'e' dm ' ' dm 'a' dm 'n' dm 'd' dm ' ' dm 'b' dm 'u' dm 'y' dm ' ' dm 's' dm 'o' dm 'm' dm 'e' dm ' ' dm 'm' dm 'o' dm 'r' dm 'e' dm ',' dm ' ' ld cmd,atmp mc Int8+99 mc bobo__5int16_8ucs2charAE mc CatStrStr mc Int8+46 mc CatStrChar mc Int8+10 mc CatStrChar mc FD__putstr__2FDC_8ucs2charAE_ mc MDrop0_Next-2 // --- file: "99_bottles_of_beer.asm" --- #include "bcc.cc" // +++ file: "bcc.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:40 : implicit__bcc__kill__6uint16AEAE_6uint16AEAE ( uint16[][] -- uint16[][] ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ForAllItems mc Bra+2 mc Peek mc DropStr mc mmNextItem mc Bra-4 mc Ret : BytecodeCompiler__init__16BytecodeCompilerC_6uint16_6uint16AEC_6uint16AEC_6uint16_4bool_ ( BytecodeCompiler˘, uint16, uint16[]˘, uint16[]˘, uint16, bool ) Millicoded // Size: 876 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+252 mc Lget+250 mc ItemSet+10 mc Int8+128 mc Alloc mc Lget+250 mc ItemSet+11 mc Lget+254 mc Retain mc Lget+250 mc ItemSet+7 mc Gget+gdata_ptr mc Lget+250 mc ItemSet+9 mc Lget+254 mc Count mc Gvar+gdata_ptr mc AddPoke mc Istr+78 dm LDQ dm IVAL dm ISTR dm ISTR dm SWAPBYTES dm CASTwl2b dm CASTwh2b dm CPL dm NOT dm MSBIT dm ADD dm SUB dm MULU dm DIVU dm REMU dm AND dm OR dm XOR dm SL dm SRU dm EQ dm NE dm ULT dm ULE dm UGT dm UGE dm UMIN dm LVAR dm GVAR dm IVAR dm ATI dm ATIPEEK dm ATIPOKE dm LGET dm LSET dm GGET dm GSET dm IGET dm ISET dm ADDPOKE dm SUBPOKE dm ANDPOKE dm ORPOKE dm PEEKPP dm MMPEEK dm LGET dm GGET dm IGET dm POKE dm NOT dm ALLOC dm ALLOC dm ALLOC dm COUNT dm COUNT dm COPY__6uint16AEC_6uint16_6uint16AEC_6uint16_6uint16_ dm COPY__6uint16AEC_6uint16_6uint16AEC_6uint16_6uint16_ dm DROPSTR dm IN dm OUT dm BIN dm BOUT dm I2C_READ_DATA__6uint16_6uint16AEC_6uint16_6uint16_6uint16 dm I2C_WRITE_DATA__6uint16_6uint16AEC_6uint16_6uint16_6uint16 dm SELECT dm DESELECT dm SYSTEMTIMER dm HALT dm SYSTIME__6uint16 dm BRA_P dm BRAZ_P dm BRANZ_P dm AND0 dm OR1 dm SWITCH dm JSR dm RET dm NOP ld cmd,atmp mc Lget+250 mc ItemSet+0 // info: start of array items mc Istr+6 dm 'i' dm 'v' dm 'a' dm 'l' dm '.' dm 'b' ld cmd,atmp mc Istr+4 dm 'i' dm 'v' dm 'a' dm 'l' ld cmd,atmp mc Istr+8 dm 'i' dm 'v' dm 'a' dm 'l' dm '.' dm 'b' dm '[' dm ']' ld cmd,atmp mc Istr+8 dm 'i' dm 'v' dm 'a' dm 'l' dm '.' dm 'w' dm '[' dm ']' ld cmd,atmp mc Istr+4 dm 's' dm 'w' dm 'a' dm 'p' ld cmd,atmp mc Istr+6 dm 'g' dm 'e' dm 't' dm '_' dm 'l' dm 'o' ld cmd,atmp mc Istr+6 dm 'g' dm 'e' dm 't' dm '_' dm 'h' dm 'i' ld cmd,atmp mc Istr+3 dm 'c' dm 'p' dm 'l' ld cmd,atmp mc Istr+3 dm 'n' dm 'o' dm 't' ld cmd,atmp mc Istr+5 dm 'm' dm 's' dm 'b' dm 'i' dm 't' ld cmd,atmp mc Istr+3 dm 'a' dm 'd' dm 'd' ld cmd,atmp mc Istr+3 dm 's' dm 'u' dm 'b' ld cmd,atmp mc Istr+3 dm 'm' dm 'u' dm 'l' ld cmd,atmp mc Istr+3 dm 'd' dm 'i' dm 'v' ld cmd,atmp mc Istr+3 dm 'r' dm 'e' dm 'm' ld cmd,atmp mc Istr+3 dm 'a' dm 'n' dm 'd' ld cmd,atmp mc Istr+2 dm 'o' dm 'r' ld cmd,atmp mc Istr+3 dm 'x' dm 'o' dm 'r' ld cmd,atmp mc Istr+2 dm 's' dm 'l' ld cmd,atmp mc Istr+2 dm 's' dm 'r' ld cmd,atmp mc Istr+2 dm 'e' dm 'q' ld cmd,atmp mc Istr+2 dm 'n' dm 'e' ld cmd,atmp mc Istr+2 dm 'l' dm 't' ld cmd,atmp mc Istr+2 dm 'l' dm 'e' ld cmd,atmp mc Istr+2 dm 'g' dm 't' ld cmd,atmp mc Istr+2 dm 'g' dm 'e' ld cmd,atmp mc Istr+3 dm 'm' dm 'i' dm 'n' ld cmd,atmp mc Istr+4 dm 'l' dm 'v' dm 'a' dm 'r' ld cmd,atmp mc Istr+4 dm 'g' dm 'v' dm 'a' dm 'r' ld cmd,atmp mc Istr+4 dm 'i' dm 'v' dm 'a' dm 'r' ld cmd,atmp mc Istr+3 dm 'a' dm 't' dm 'i' ld cmd,atmp mc Istr+6 dm 'a' dm 't' dm 'i' dm 'g' dm 'e' dm 't' ld cmd,atmp mc Istr+6 dm 'a' dm 't' dm 'i' dm 's' dm 'e' dm 't' ld cmd,atmp mc Istr+4 dm 'l' dm 'g' dm 'e' dm 't' ld cmd,atmp mc Istr+4 dm 'l' dm 's' dm 'e' dm 't' ld cmd,atmp mc Istr+4 dm 'g' dm 'g' dm 'e' dm 't' ld cmd,atmp mc Istr+4 dm 'g' dm 's' dm 'e' dm 't' ld cmd,atmp mc Istr+4 dm 'i' dm 'g' dm 'e' dm 't' ld cmd,atmp mc Istr+4 dm 'i' dm 's' dm 'e' dm 't' ld cmd,atmp mc Istr+5 dm 'a' dm 'd' dm 'd' dm 'g' dm 'l' ld cmd,atmp mc Istr+5 dm 's' dm 'u' dm 'b' dm 'g' dm 'l' ld cmd,atmp mc Istr+5 dm 'a' dm 'n' dm 'd' dm 'g' dm 'l' ld cmd,atmp mc Istr+4 dm 'o' dm 'r' dm 'g' dm 'l' ld cmd,atmp mc Istr+6 dm 'p' dm 'e' dm 'e' dm 'k' dm 'p' dm 'p' ld cmd,atmp mc Istr+6 dm 'm' dm 'm' dm 'p' dm 'e' dm 'e' dm 'k' ld cmd,atmp mc Istr+4 dm 'l' dm 'g' dm 'e' dm 't' ld cmd,atmp mc Istr+4 dm 'g' dm 'g' dm 'e' dm 't' ld cmd,atmp mc Istr+4 dm 'i' dm 'g' dm 'e' dm 't' ld cmd,atmp mc Istr+3 dm 's' dm 'e' dm 't' ld cmd,atmp mc Istr+3 dm 'n' dm 'o' dm 't' ld cmd,atmp mc Istr+5 dm 'a' dm 'l' dm 'l' dm 'o' dm 'c' ld cmd,atmp mc Istr+5 dm 'a' dm 'l' dm 'l' dm 'o' dm 'c' ld cmd,atmp mc Istr+7 dm 'a' dm 'l' dm 'l' dm 'o' dm 'c' dm '.' dm 'S' ld cmd,atmp mc Istr+5 dm 'c' dm 'o' dm 'u' dm 'n' dm 't' ld cmd,atmp mc Istr+5 dm 'c' dm 'o' dm 'u' dm 'n' dm 't' ld cmd,atmp mc Istr+9 dm 'c' dm 'o' dm 'p' dm 'y' dm 'A' dm 'i' dm 'A' dm 'i' dm 'n' ld cmd,atmp mc Istr+9 dm 'c' dm 'o' dm 'p' dm 'y' dm 'A' dm 'i' dm 'A' dm 'i' dm 'n' ld cmd,atmp mc Istr+7 dm 'd' dm 'i' dm 's' dm 'p' dm 'o' dm 's' dm 'e' ld cmd,atmp mc Istr+2 dm 'i' dm 'n' ld cmd,atmp mc Istr+3 dm 'o' dm 'u' dm 't' ld cmd,atmp mc Istr+3 dm 'b' dm 'i' dm 'n' ld cmd,atmp mc Istr+4 dm 'b' dm 'o' dm 'u' dm 't' ld cmd,atmp mc Istr+7 dm 'r' dm 'e' dm 'a' dm 'd' dm 'i' dm '2' dm 'c' ld cmd,atmp mc Istr+8 dm 'w' dm 'r' dm 'i' dm 't' dm 'e' dm 'i' dm '2' dm 'c' ld cmd,atmp mc Istr+2 dm 'd' dm 'i' ld cmd,atmp mc Istr+2 dm 'e' dm 'i' ld cmd,atmp mc Istr+5 dm 't' dm 'i' dm 'm' dm 'e' dm 'r' ld cmd,atmp mc Istr+4 dm 'w' dm 'a' dm 'i' dm 't' ld cmd,atmp mc Istr+7 dm 's' dm 'y' dm 's' dm 't' dm 'i' dm 'm' dm 'e' ld cmd,atmp mc Istr+2 dm 'j' dm 'p' ld cmd,atmp mc Istr+3 dm 'j' dm 'p' dm '0' ld cmd,atmp mc Istr+3 dm 'j' dm 'p' dm '1' ld cmd,atmp mc Istr+4 dm 'a' dm 'n' dm 'd' dm '0' ld cmd,atmp mc Istr+3 dm 'o' dm 'r' dm '1' ld cmd,atmp mc Istr+6 dm 's' dm 'w' dm 'i' dm 't' dm 'c' dm 'h' ld cmd,atmp mc Istr+4 dm 'c' dm 'a' dm 'l' dm 'l' ld cmd,atmp mc Istr+3 dm 'r' dm 'e' dm 't' ld cmd,atmp mc Istr+5 dm 'l' dm 'a' dm 'b' dm 'e' dm 'l' ld cmd,atmp // info: end of array items mc Int8+78 mc Alloc mc DupToR mc ForAllItems mc Bra+1 mc Poke mc mmNextItem mc Bra-3 mc FromR mc Lget+250 mc ItemSet+3 mc Istr+78 dm 1 dm 1 dm 1 dm 1 dm 0 dm 0 dm 0 dm 0 dm 0 dm 0 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm -1 dm 1 dm 1 dm 0 dm -1 dm -1 dm -3 dm 1 dm -1 dm 1 dm -1 dm 0 dm -2 dm -2 dm -2 dm -2 dm -2 dm 0 dm 0 dm 1 dm 1 dm 0 dm -2 dm 0 dm 0 dm 0 dm 1 dm 0 dm 0 dm -5 dm -5 dm -1 dm 0 dm -2 dm -4 dm -4 dm -3 dm -3 dm 0 dm 0 dm 0 dm 0 dm 1 dm 0 dm -1 dm -1 dm -1 dm -1 dm -1 dm 0 dm 0 dm 0 ld cmd,atmp mc Lget+250 mc ItemSet+4 mc Istr+16 dm ADDQ dm SUBQ dm MULUQ dm DIVUQ dm REMUQ dm ANDQ dm ORQ dm XORQ dm 0 dm 0 dm EQQ dm NEQ dm ULTQ dm ULEQ dm UGTQ dm UGEQ ld cmd,atmp mc Lget+250 mc ItemSet+2 mc Istr+16 dm ADDI dm SUBI dm MULUI dm DIVUI dm REMUI dm ANDI dm ORI dm XORI dm 0 dm 0 dm EQI dm NEI dm ULTI dm ULEI dm UGTI dm UGEI ld cmd,atmp mc Lget+250 mc ItemSet+1 mc Istr+4 dm IN dm IN2 dm IN4 dm IN8 ld cmd,atmp mc DupToR mc Lget+254 mc AtIndex mc FromR mc DropStr mc Peek mc Lget+250 mc ItemGet+0 mc Int8+58 mc AtIndexPoke mc Istr+4 dm OUT dm OUT2 dm OUT4 dm OUT8 ld cmd,atmp mc DupToR mc Lget+254 mc AtIndex mc FromR mc DropStr mc Peek mc Lget+250 mc ItemGet+0 mc Int8+59 mc AtIndexPoke mc Istr+4 dm BIN dm BIN2 dm BIN4 dm BIN8 ld cmd,atmp mc DupToR mc Lget+254 mc AtIndex mc FromR mc DropStr mc Peek mc Lget+250 mc ItemGet+0 mc Int8+60 mc AtIndexPoke mc Dup mc BraIf0+7 mc Istr+4 dm FBOUT dm FBOUT2 dm FBOUT4 dm FBOUT8 ld cmd,atmp mc Bra+6 mc Istr+4 dm BOUT dm BOUT2 dm BOUT4 dm BOUT8 ld cmd,atmp mc DupToR mc Lget+254 mc AtIndex mc FromR mc DropStr mc Peek mc Lget+250 mc ItemGet+0 mc Int8+61 mc AtIndexPoke mc Istr+4 dm INI dm INI2 dm INI4 dm INI8 ld cmd,atmp mc DupToR mc Lget+254 mc AtIndex mc FromR mc DropStr mc Peek mc Lget+250 mc ItemSet+5 mc Istr+4 dm OUTI dm OUTI2 dm OUTI4 dm OUTI8 ld cmd,atmp mc DupToR mc Lget+254 mc AtIndex mc FromR mc DropStr mc Peek mc Lget+250 mc ItemSet+6 mc Int8+0 mc Int8+0 mc Int8+0 mc Int8+0 mc Lget+253 mc Lget+248 mc Count mc Ult mc BraIf0+9 mc Lget+249 mc Lvar+252 mc Peekpp mc AtIndexPeek mc Lvar+252 mc AddPoke mc Lvar+255 mc Incr mc Bra-14 mc Lget+255 mc Alloc mc Lget+246 mc Item+8 mc SwapWithVar mc CallKill mc implicit__bcc__kill__6uint16AEAE_6uint16AEAE mc DropStr mc Dup mc Lget+254 mc Ult mc BraIf0+21 mc Lget+249 mc Lvar+253 mc Peekpp mc AtIndexPeek mc Lget+248 mc Lget+252 mc Lget+251 mc Lget+253 mc Add mc SubStr mc Cast_RangeStr mc Lget+245 mc ItemGet+8 mc Lvar+253 mc Peekpp mc AtIndexPoke mc Dup mc Lvar+252 mc AddPoke mc MDrop0-1 mc Bra-25 mc MDrop0-8 mc MDrop0_Next-2 : BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16 ( BytecodeCompiler˘, uint16, uint16, uint16[]˘, uint16[], uint16[]˘ -- uint16 ) Millicoded // Size: 674 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc PushContext0 mc Int8+3 mc Alloc mc ToR mc Lget+253 mc PeekR mc ItemSet+0 mc Lget+254 mc Retain mc PeekR mc ItemSet+1 mc Gget+gcode_ptr mc PeekR mc ItemSet+2 mc FromR mc Lget+250 mc ItemGet+11 mc Lget+250 mc AtIndexPoke mc Lget+251 mc ItemGet+11 mc Lget+251 mc AtIndexPeek mc Lget+253 mc Retain mc Lget+253 mc Retain mc CatStrStr mc Lvar+253 mc SwapWithVar mc DropStr mc Lget+253 mc Count mc Int8+0 mc Int16+1 mc Alloc mc Int8+0 mc Int16+1 mc Alloc mc Int8+0 mc Int16+1 mc Alloc mc Int8+0 mc Lget+246 mc Int8+8 mc Eq mc BraIf0+5 mc Int8+SELECTI&$FF mc Int16+(SELECTI>>8)&$FF mc Lget+244 mc ItemGet+10 mc BytecodeCompiler__store__6uint16_6uint16_ mc Int8+0 mc Int8+0 mc Int8+0 mc Lget+254 mc Lget+246 mc Count mc Ult mc BraIf1+2 mc Hi8+2 mc BraFar+25 mc BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____peeknextopcode__6uint16 mc Lset+255 mc Lvar+254 mc Incr mc Lget+247 mc Lvar+253 mc Peekpp mc AtIndexPeek mc Nip mc Lget+255 mc Switch+4 mc Bra+4 mc Bra+81 mc Bra+112 mc Bra+127 mc Bra+148 mc BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____peeknextopcode__6uint16 mc Lset+255 mc Lget+255 mc Subq+10 mc Int8+15 mc Ule mc BraIf0+35 mc Lvar+254 mc Incr mc Lget+255 mc Int8+18 mc Eq mc BraIf0+8 mc Int8+SLI0&$FF mc Int16+(SLI0>>8)&$FF mc Lget+255 mc Int8+15 mc And mc Sub mc BytecodeCompiler__store__6uint16_ mc Bra-44 mc Lget+255 mc Int8+19 mc Eq mc BraIf0+8 mc Int8+SRU0&$FF mc Int16+(SRU0>>8)&$FF mc Lget+255 mc Int8+15 mc And mc Sub mc BytecodeCompiler__store__6uint16_ mc Bra-56 mc Lget+242 mc ItemGet+2 mc Lget+254 mc Subq+10 mc AtIndexPeek mc Lget+255 mc Add mc BytecodeCompiler__store__6uint16_ mc Bra-65 mc Lget+255 mc Int8+58 mc Eq mc BraIf0+10 mc Lvar+254 mc Incr mc Lvar+249 mc Incr mc Lget+242 mc ItemGet+5 mc Lget+255 mc Add mc BytecodeCompiler__store__6uint16_ mc Bra-79 mc Lget+255 mc Int8+59 mc Eq mc BraIf0+10 mc Lvar+254 mc Incr mc Lvar+249 mc Decr mc Lget+242 mc ItemGet+6 mc Lget+255 mc Add mc BytecodeCompiler__store__6uint16_ mc Bra-93 mc Dup mc Int8+LDQ&$FF mc Int16+(LDQ>>8)&$FF mc Or mc BytecodeCompiler__store__6uint16_ mc Lvar+249 mc Incr mc Bra-101 mc Dup mc Sli15+15-8 mc Lget+246 mc Lvar+252 mc Peekpp mc AtIndexPeek mc Add mc Nip mc BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____peeknextopcode__6uint16 mc Lset+255 mc Lget+255 mc Subq+10 mc Int8+15 mc Ule mc BraIf0+10 mc Lvar+254 mc Incr mc Lget+242 mc ItemGet+1 mc Lget+254 mc Subq+10 mc AtIndexPeek mc Lget+255 mc BytecodeCompiler__store__6uint16_6uint16_ mc Bra-126 mc Int8+IVAL&$FF mc Int16+(IVAL>>8)&$FF mc Lget+255 mc BytecodeCompiler__store__6uint16_6uint16_ mc Lvar+249 mc Incr mc Bra-133 mc Int8+ISTR&$FF mc Int16+(ISTR>>8)&$FF mc Lget+255 mc BytecodeCompiler__store__6uint16_6uint16_ mc PshHP mc Peekmm mc BraIf0+6 mc Lget+247 mc Lvar+253 mc Peekpp mc AtIndexPeek mc BytecodeCompiler__store__6uint16_ mc Bra-9 mc Lvar+249 mc Incr mc Bra-149 mc Int8+ISTR&$FF mc Int16+(ISTR>>8)&$FF mc Lget+255 mc BytecodeCompiler__store__6uint16_6uint16_ mc PshHP mc Peekmm mc BraIf0+12 mc Lget+247 mc Lvar+253 mc Peekpp mc AtIndexPeek mc Sli15+15-8 mc Lget+246 mc Lvar+252 mc Peekpp mc AtIndexPeek mc Add mc BytecodeCompiler__store__6uint16_ mc Bra-15 mc Lvar+249 mc Incr mc Bra-171 mc Lget+255 mc Subq+69 mc Switch+9 mc Bra+9 mc Bra+38 mc Bra+48 mc Bra+58 mc Bra+57 mc Bra+75 mc Bra+102 mc Bra+123 mc Bra+169 mc Bra+191 mc Int8+JP&$FF mc Int16+(JP>>8)&$FF mc Int8+BRA_P&$FF mc Int16+(BRA_P>>8)&$FF mc BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____store_jp_or_bra__6uint16_6uint16_4bool mc BraIf0+3 mc Int8+201 mc Hi8+1 mc BraFar+155 mc BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____peeknextopcode__6uint16 mc Int8+77 mc Eq mc BraIf0+14 mc Lget+247 mc Lget+253 mc Addq+1 mc AtIndexPeek mc Nip mc Lget+251 mc Lget+255 mc AtIndexPeek mc BraIf0-206 mc Lget+251 mc Lget+255 mc AtIndexPeek mc Lset+249 mc Bra-211 mc Int8+202 mc Hi8+1 mc BraFar+134 mc Lvar+249 mc Decr mc Int8+JP_Z&$FF mc Int16+(JP_Z>>8)&$FF mc Int8+BRAZ_P&$FF mc Int16+(BRAZ_P>>8)&$FF mc BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____store_jp_or_bra__6uint16_6uint16_4bool mc BraIf0-222 mc Int8+203 mc Hi8+1 mc BraFar+123 mc Lvar+249 mc Decr mc Int8+JP_NZ&$FF mc Int16+(JP_NZ>>8)&$FF mc Int8+BRANZ_P&$FF mc Int16+(BRANZ_P>>8)&$FF mc BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____store_jp_or_bra__6uint16_6uint16_4bool mc BraIf0-233 mc Int8+203 mc Hi8+1 mc BraFar+112 mc Lget+249 mc Lget+250 mc Lget+254 mc AtIndexPoke mc Gget+gcode_ptr mc Lget+251 mc Lvar+251 mc Peekpp mc AtIndexPoke mc Lget+242 mc ItemGet+0 mc Lget+254 mc AtIndexPeek mc Lget+255 mc Add mc BytecodeCompiler__store__6uint16_ mc Lvar+249 mc Decr mc Bra-255 mc Int8+SWITCH&$FF mc Int16+(SWITCH>>8)&$FF mc Lget+255 mc BytecodeCompiler__store__6uint16_6uint16_ mc Lvar+249 mc Decr mc PshHP mc Peekmm mc BraIf1+2 mc Hi8+254 mc BraFar+246 mc Gget+gcode_ptr mc Lget+251 mc Lvar+251 mc Peekpp mc AtIndexPoke mc Lget+247 mc Lvar+253 mc Peekpp mc AtIndexPeek mc Lget+248 mc Lget+249 mc Lget+254 mc AtIndexPoke mc Dup mc BytecodeCompiler__store__6uint16_ mc MDrop0-1 mc Bra-22 mc Lget+242 mc ItemGet+11 mc Lget+255 mc AtIndexPeek mc Int8+JSR&$FF mc Int16+(JSR>>8)&$FF mc Lget+255 mc ItemGet+2 mc BytecodeCompiler__store__6uint16_6uint16_ mc Dup mc ItemGet+0 mc Int8+0 mc Ne mc Lget+255 mc ItemGet+1 mc Count mc Sub mc Lvar+247 mc AddPoke mc MDrop0-1 mc Hi8+254 mc BraFar+207 mc Lget+248 mc ItemGet+0 mc Int8+0 mc Eq mc BraIf0+24 mc Lget+249 mc Int8+8 mc Ugt mc BraIf0+7 mc Int8+DROP8&$FF mc Int16+(DROP8>>8)&$FF mc BytecodeCompiler__store__6uint16_ mc Int8+8 mc Lvar+248 mc SubPoke mc Bra-11 mc Lget+243 mc Int8+8 mc Eq mc BraIf0+3 mc Int8+DROP0_RETI&$FF mc Int16+(DROP0_RETI>>8)&$FF mc Bra+2 mc Int8+DROP0_RET&$FF mc Int16+(DROP0_RET>>8)&$FF mc Lget+248 mc Sub mc BytecodeCompiler__store__6uint16_ mc Bra+210 mc Lget+249 mc Int8+9 mc Ugt mc BraIf0+7 mc Int8+NIP8&$FF mc Int16+(NIP8>>8)&$FF mc BytecodeCompiler__store__6uint16_ mc Int8+8 mc Lvar+248 mc SubPoke mc Bra-11 mc Int8+NIP0_RET&$FF mc Int16+(NIP0_RET>>8)&$FF mc Lget+248 mc Subq+1 mc Sub mc BytecodeCompiler__store__6uint16_ mc Bra+192 mc Gget+gcode_ptr mc Lget+249 mc Lget+254 mc AtIndexPoke mc Lget+251 mc Lget+255 mc AtIndexPeek mc And0 mc Bra+5 mc Lget+249 mc Lget+250 mc Lget+254 mc AtIndexPeek mc Ne mc BraIf0+2 mc Int8+204 mc Bra+235 mc Lget+249 mc Lget+250 mc Lget+254 mc AtIndexPoke mc Hi8+254 mc BraFar+137 mc Lget+255 mc Subq+27 mc Switch+38 mc Bra+51 mc Bra+107 mc Bra+117 mc Bra+34 mc Bra+33 mc Bra+32 mc Bra+64 mc Bra+82 mc Bra+100 mc Bra+99 mc Bra+109 mc Bra+108 mc Bra+25 mc Bra+24 mc Bra+23 mc Bra+22 mc Bra+21 mc Bra+20 mc Bra+52 mc Bra+89 mc Bra+99 mc Bra+16 mc Bra+15 mc Bra+14 mc Bra+13 mc Bra+105 mc Bra+11 mc Bra+10 mc Bra+9 mc Bra+8 mc Bra+7 mc Bra+6 mc Bra+5 mc Bra+4 mc Bra+3 mc Bra+2 mc Bra+1 mc Bra+109 mc Lvar+254 mc Decr mc Lget+255 mc Int8+77 mc Ugt mc BraIf0+2 mc Int8+205 mc Bra+180 mc Lget+242 mc ItemGet+0 mc Lget+254 mc AtIndexPeek mc Nip mc Bra+104 mc Dup mc Lget+248 mc Subq+1 mc Eq mc BraIf0+3 mc Int8+PSH_HP&$FF mc Int16+(PSH_HP>>8)&$FF mc Bra+9 mc Int8+LVAR&$FF mc Int16+(LVAR>>8)&$FF mc Int8+1 mc Int16+1 mc Add mc Lget+255 mc Add mc Lget+248 mc Sub mc Nip mc Bra+85 mc Dup mc Lget+248 mc Subq+1 mc Eq mc BraIf0+3 mc Int8+DUP&$FF mc Int16+(DUP>>8)&$FF mc Bra+9 mc Int8+LGET&$FF mc Int16+(LGET>>8)&$FF mc Int8+1 mc Int16+1 mc Add mc Lget+255 mc Add mc Lget+248 mc Sub mc Nip mc Bra+66 mc Dup mc Lget+248 mc Subq+2 mc Eq mc BraIf0+3 mc Int8+NIP&$FF mc Int16+(NIP>>8)&$FF mc Bra+9 mc Int8+LSET&$FF mc Int16+(LSET>>8)&$FF mc Int8+2 mc Int16+1 mc Add mc Lget+255 mc Add mc Lget+248 mc Sub mc Nip mc Bra+47 mc Lget+242 mc ItemGet+0 mc Lget+254 mc AtIndexPeek mc Lget+241 mc ItemGet+9 mc Add mc Lget+255 mc Add mc Nip mc Bra+36 mc Lget+242 mc ItemGet+0 mc Lget+254 mc AtIndexPeek mc Lget+246 mc Lvar+252 mc Peekpp mc AtIndexPeek mc Add mc Nip mc Bra+25 mc Int8+LDQ&$FF mc Int16+(LDQ>>8)&$FF mc Lget+241 mc ItemGet+8 mc Lget+254 mc Subq+7 mc AtIndexPeek mc Count mc Add mc Int8+ALLOC&$FF mc Int16+(ALLOC>>8)&$FF mc BytecodeCompiler__store__6uint16_6uint16_ mc Lvar+249 mc Incr mc Hi8+253 mc BraFar+243 mc Lvar+254 mc Decr mc Int8+SELECTI&$FF mc Int16+(SELECTI>>8)&$FF mc Lget+241 mc ItemGet+10 mc BytecodeCompiler__store__6uint16_6uint16_ mc Hi8+253 mc BraFar+234 mc Dup mc BytecodeCompiler__store__6uint16_ mc Lget+242 mc ItemGet+4 mc Lget+254 mc AtIndexPeek mc Lvar+248 mc AddPoke mc Hi8+253 mc BraFar+224 mc Lget+255 mc Int8+76 mc Ne mc BraIf0+2 mc Int8+206 mc Bra+54 mc Lget+253 mc PshHP mc Peekmm mc BraIf0+48 mc Lget+251 mc Lget+255 mc AtIndexPeek mc Dup mc Peek mc Dup mc Sru15+15-8 mc Int8+0 mc Eq mc BraIf0+6 mc Lget+247 mc Lget+255 mc AtIndexPeek mc Lget+254 mc Poke mc Bra+30 mc Lget+247 mc Lget+255 mc Int8+255 mc And mc AtIndexPeek mc Lget+254 mc Addq+1 mc Sub mc Dup mc Int8+255 mc Gt mc Or1 mc Bra+4 mc Dup mc Int8+0 mc Int16+255 mc Lt mc BraIf0+3 mc Int8+207 mc MNip0-4 mc Bra+13 mc Lget+255 mc Int8+0 mc Int16+255 mc And mc Lget+255 mc Add mc Lget+253 mc Poke mc MDrop0-1 mc MDrop0-2 mc Bra-51 mc Int8+0 mc MNip0-1 mc ToR mc MDrop0-4 mc DropStr mc DropStr mc DropStr mc MDrop0-3 mc DropStr mc MDrop0-4 mc FromR mc PopContext0 mc Ret : BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____peeknextopcode__6uint16 ( -- uint16 ) Millicoded // Size: 25 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc XLvar+127 mc Peek mc XLvar+134 mc Peek mc AtIndexPeek mc Dup mc Int8+45 mc Uge mc BraIf0+3 mc Int8+15 mc Lvar+255 mc SubPoke mc Dup mc Int8+62 mc Uge mc BraIf0+3 mc Int8+4 mc Lvar+255 mc SubPoke mc Dup mc MNip0_Next-1 : BytecodeCompiler__compile__16BytecodeCompilerC_6uint16_6uint16_6uint16AEC_6uint16AE_6uint16AEC_6uint16____store_jp_or_bra__6uint16_6uint16_4bool ( uint16, uint16 -- bool ) Millicoded // Size: 64 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc XLvar+127 mc Peek mc Count mc XLvar+134 mc Peek mc Sub mc Int8+255 mc Ugt mc Or1 mc Bra+7 mc Gget+gcode_ptr mc XLvar+128 mc Peek mc ItemGet+2 mc Sub mc Int8+255 mc Gt mc BraIf0+5 mc Lget+255 mc XLvar+136 mc Peek mc BytecodeCompiler__store__6uint16_6uint16_ mc Bra+5 mc Dup mc XLvar+136 mc Peek mc Add mc BytecodeCompiler__store__6uint16_ mc Gget+gcode_ptr mc Int8+1 mc Sub mc XLvar+132 mc Peek mc XLvar+133 mc Peekpp mc AtIndexPoke mc XLvar+131 mc Peek mc XLvar+136 mc Peek mc AtIndexPeek mc Int8+0 mc Eq mc BraIf0+7 mc XLvar+129 mc Peek mc XLvar+131 mc Peek mc XLvar+136 mc Peek mc AtIndexPoke mc XLvar+129 mc Peek mc XLvar+131 mc Peek mc XLvar+136 mc Peek mc AtIndexPeek mc Ne mc MNip0_Next-2 : BytecodeCompiler__store__6uint16_ ( uint16 ) Millicoded // Size: 9 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Gvar+gcode_ptr mc Peekpp mc Poke mc MDrop0_Next-1 : BytecodeCompiler__store__6uint16_6uint16_ ( uint16, uint16 ) Millicoded // Size: 13 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Lget+255 mc Gvar+gcode_ptr mc Peekpp mc Poke mc Dup mc Gvar+gcode_ptr mc Peekpp mc Poke mc MDrop0_Next-2 : SYSTIME__6uint16 ( -- uint16 ) Millicoded // Size: 15 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Gvar+current_time mc Addq+1 mc Peek mc Sli15+15-10 mc Gvar+current_microsec mc Peek2 mc Int8+10 mc SrUL mc MNip0-1 mc Add mc RET : COPY__6uint16AEC_6uint16_6uint16AEC_6uint16_6uint16_ ( uint16[]˘, uint16, uint16[]˘, uint16, uint16 ) Millicoded ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc copy__6uint16AEC_6uint16_6uint16AEC_6uint16_6uint16_ mc RET : I2C_READ_DATA__6uint16_6uint16AEC_6uint16_6uint16_6uint16 ( uint16, uint16[]˘, uint16, uint16 -- uint16 ) TODO ld atmp,$ // * TODO jp TODO // * TODO // add (hp) // convert last parameter: cnt -> end_addr // Millicoded // mc i2cReadData__6uint16_6uint16AEC_6uint16_6uint16_6uint16 // mc RET : I2C_WRITE_DATA__6uint16_6uint16AEC_6uint16_6uint16_6uint16 ( uint16, uint16[]˘, uint16, uint16 -- uint16 ) TODO ld atmp,$ // * TODO jp TODO // * TODO // add (hp) // convert last parameter: cnt -> end_addr // Millicoded // mc i2cWriteData__6uint16_6uint16AEC_6uint16_6uint16_6uint16 // mc RET // --- file: "bcc.asm" --- #include "shell.cc" // +++ file: "shell.asm" +++ // K1-16/16 Microcode // 2015-12-22 16:10:40 : implicit__shell__kill__8ucs2charAEAE_8ucs2charAEAE ( ucs2str[] -- ucs2str[] ) Millicoded // Size: 12 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ForAllItems mc Bra+2 mc Peek mc DropStr mc mmNextItem mc Bra-4 mc Ret : implicit__shell__kill__2FD_2FD ( FD -- FD ) Millicoded // Size: 8 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+1 mc DropStr mc Ret : implicit__shell__kill__5Shell_5Shell ( Shell -- Shell ) Millicoded // Size: 25 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc ItemGet+0 mc CallKill mc implicit__shell__kill__2FD_2FD mc DropStr mc Dup mc ItemGet+1 mc CallKill mc implicit__shell__kill__2FD_2FD mc DropStr mc Dup mc ItemGet+2 mc CallKill mc implicit__shell__kill__2FD_2FD mc DropStr mc Dup mc ItemGet+3 mc CallKill mc implicit__shell__kill__2FD_2FD mc DropStr mc Ret : Shell__input__5ShellC_8ucs2charAEC_8ucs2charAE ( Shell˘, ucs2str˘ -- ucs2str ) Millicoded // Size: 262 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Int8+0 mc Int8+0 mc Istr+0 ld cmd,atmp mc Lvar+253 mc SwapWithVar mc DropStr mc Int8+0 mc Lset+255 mc Gget+stdout mc Int8+5 mc sing_99_bottles_of_beer__2FDC_5int16_ mc Gget+stdout mc Istr+2 dm 10 dm 13 ld cmd,atmp mc FD__putstr__2FDC_8ucs2charAE_ mc Gget+stdout mc Lget+252 mc FD__writebytes__2FDC_6uint16AEC_ mc Gget+stdout mc Int8+32 mc FD__writebyte__2FDC_6uint16_ mc Gget+stdin mc FD__getavail__2FDC_6uint16 mc BraIf1+3 mc Gget+stdout mc Int8+7 mc FD__writebyte__2FDC_6uint16_ mc Gget+stdin mc FD__readbyte__2FDC_6uint16 mc Nip mc Dup mc Subq+8 mc Switch+15 mc Bra+16 mc Bra+135 mc Bra+103 mc Bra+77 mc Bra+20 mc Bra+193 mc Bra+30 mc Bra+129 mc Bra+128 mc Bra+127 mc Bra+126 mc Bra+125 mc Bra+33 mc Bra+80 mc Bra+107 mc Bra+121 mc Bra+182 mc Lget+255 mc BraIf0-31 mc Gget+stdout mc Int8+8 mc FD__writebyte__2FDC_6uint16_ mc Lvar+255 mc Decr mc Bra-37 mc Lget+255 mc Lget+253 mc Count mc Ult mc BraIf0-42 mc Gget+stdout mc Lget+253 mc Lvar+253 mc Peekpp mc AtIndexPeek mc FD__writebyte__2FDC_6uint16_ mc Bra-49 mc Lget+255 mc Int8+0 mc Eq mc BraIf1-53 mc Gget+stdout mc Int8+8 mc FD__writebyte__2FDC_6uint16_ mc Lvar+255 mc Decr mc Lget+254 mc Int8+0 mc Lget+253 mc SubStr mc Lget+251 mc Lget+251 mc Addq+1 mc Int8+255 mc Int16+127 mc SubStr mc CatRangeRange mc Lvar+253 mc SwapWithVar mc DropStr mc Gget+stdout mc Int8+5 mc FD__writebyte__2FDC_6uint16_ mc Gget+stdout mc Lget+253 mc Lget+253 mc Int8+255 mc Int16+127 mc SubStr mc Cast_RangeStr mc DupToR mc FD__writebytes__2FDC_6uint16AEC_ mc FromR mc DropStr mc Gget+stdout mc Int8+32 mc FD__writebyte__2FDC_6uint16_ mc Gget+stdout mc Int8+6 mc FD__writebyte__2FDC_6uint16_ mc Bra-93 mc Lget+255 mc Lget+251 mc ItemGet+5 mc Uge mc BraIf0+8 mc Gget+stdout mc Int8+11 mc FD__writebyte__2FDC_6uint16_ mc Lget+252 mc ItemGet+5 mc Lvar+254 mc SubPoke mc Bra-106 mc Gget+stdout mc Int8+18 mc FD__writebyte__2FDC_6uint16_ mc Gget+stdout mc Lget+254 mc FD__writebyte__2FDC_6uint16_ mc Int8+0 mc Lset+255 mc Gget+stdout mc Int8+8 mc FD__writebyte__2FDC_6uint16_ mc Bra-118 mc Lget+255 mc Lget+251 mc ItemGet+5 mc Add mc Lget+253 mc Count mc Ule mc BraIf0+8 mc Gget+stdout mc Int8+10 mc FD__writebyte__2FDC_6uint16_ mc Lget+252 mc ItemGet+5 mc Lvar+254 mc AddPoke mc Bra-134 mc Gget+stdout mc Lget+253 mc Lget+253 mc Int8+255 mc Int16+127 mc SubStr mc Cast_RangeStr mc DupToR mc FD__writebytes__2FDC_6uint16AEC_ mc FromR mc DropStr mc Lget+254 mc Count mc Lset+255 mc Bra-149 mc Dup mc Int8+127 mc And mc Int8+32 mc Uge mc BraIf0+43 mc Gget+stdout mc Lget+255 mc FD__writebyte__2FDC_6uint16_ mc Lget+255 mc Lget+253 mc Count mc Ult mc BraIf0+17 mc Gget+stdout mc Int8+5 mc FD__writebyte__2FDC_6uint16_ mc Gget+stdout mc Lget+253 mc Lget+253 mc Int8+255 mc Int16+127 mc SubStr mc Cast_RangeStr mc DupToR mc FD__writebytes__2FDC_6uint16AEC_ mc FromR mc DropStr mc Gget+stdout mc Int8+6 mc FD__writebyte__2FDC_6uint16_ mc Lget+254 mc Int8+0 mc Lget+253 mc SubStr mc Lget+253 mc CatRangeChar mc Lget+253 mc Lget+253 mc Int8+255 mc Int16+127 mc SubStr mc CatStrRange mc Lvar+253 mc SwapWithVar mc DropStr mc Lvar+255 mc Incr mc Bra-198 mc Gget+stdout mc Istr+1 dm '{' ld cmd,atmp mc Lget+254 mc NumStrU mc CatStrStr mc Istr+1 dm '}' ld cmd,atmp mc CatStrStr mc FD__putstr__2FDC_8ucs2charAE_ mc Bra-211 mc Gget+stdout mc Lget+253 mc Lget+253 mc Int8+255 mc Int16+127 mc SubStr mc Cast_RangeStr mc DupToR mc FD__writebytes__2FDC_6uint16AEC_ mc FromR mc DropStr mc Gget+stdout mc Int8+32 mc FD__writebyte__2FDC_6uint16_ mc Lget+254 mc Retain mc ToR mc MDrop0-2 mc DropStr mc MDrop0-2 mc FromR mc Ret : Shell__breakIntoWords__8ucs2charAEC_8ucs2charAEAE ( ucs2str˘ -- ucs2str[] ) Millicoded // Size: 92 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+0 mc Alloc mc Lget+255 mc Count mc Int8+0 mc Int8+0 mc Lget+255 mc Lget+253 mc Ult mc And0 mc Bra+5 mc Lget+252 mc Lget+254 mc AtIndexPeek mc Int8+32 mc Ule mc BraIf0+3 mc Lvar+255 mc Incr mc Bra-14 mc Lget+255 mc Lget+253 mc Ult mc BraIf0+54 mc Lget+255 mc Nip mc Lget+252 mc Lget+255 mc AtIndexPeek mc Int8+34 mc Ne mc BraIf0+14 mc Dup mc Lget+253 mc Ult mc And0 mc Bra+5 mc Lget+252 mc Lget+255 mc AtIndexPeek mc Int8+32 mc Ugt mc BraIf0+17 mc PshHP mc Incr mc Bra-14 mc PshHP mc Incr mc Dup mc Lget+253 mc Ult mc And0 mc Bra+6 mc Lget+252 mc Lvar+255 mc Peekpp mc AtIndexPeek mc Int8+34 mc Ne mc BraIf1-12 mc Lvar+253 mc PeekNZ mc Lget+252 mc Count mc Addq+1 mc GrowStr mc Lget+252 mc Lget+254 mc Lget+254 mc SubStr mc Cast_RangeStr mc Lget+252 mc Last mc SwapWithVar mc DropStr mc Dup mc Lset+255 mc Bra-72 mc Lget+253 mc Retain mc ToR mc MDrop0-3 mc CallKill mc implicit__shell__kill__8ucs2charAEAE_8ucs2charAEAE mc DropStr mc MDrop0-1 mc FromR mc Ret : Shell__run__5ShellC_ ( Shell˘ ) Millicoded // Size: 53 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Gvar+current_time mc Peek2 mc numstr__6uint32_8ucs2charAE mc Istr+1 dm '>' ld cmd,atmp mc CatStrStr mc Lget+255 mc Lget+255 mc Shell__input__5ShellC_8ucs2charAEC_8ucs2charAE mc Gget+stdout mc Istr+3 dm '-' dm '-' dm '>' ld cmd,atmp mc FD__putstr__2FDC_8ucs2charAE_ mc Dup mc Shell__breakIntoWords__8ucs2charAEC_8ucs2charAEAE mc Int8+0 mc Dup mc Lget+254 mc Count mc Ult mc BraIf0+16 mc Dup mc BraIf0+7 mc Gget+stdout mc Istr+3 dm ' ' dm '+' dm ' ' ld cmd,atmp mc FD__putstr__2FDC_8ucs2charAE_ mc Gget+stdout mc Lget+254 mc Lvar+254 mc Peekpp mc AtIndexPeek mc FD__writebytes__2FDC_6uint16AEC_ mc Bra-21 mc MDrop0-1 mc CallKill mc implicit__shell__kill__8ucs2charAEAE_8ucs2charAEAE mc DropStr mc DropStr mc DropStr mc Bra-48 mc Ret : wait_ms__5int16_ ( int16 ) Millicoded // Size: 91 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Dup mc Int8+0 mc Lt mc BraIf1+82 mc Gvar+current_time mc Peek2 mc Lget+254 mc Int8+232 mc Int16+3 mc Divu mc Cast_uL mc AddL mc Gvar+current_microsec mc Peek2 mc Lget+252 mc Int8+232 mc Int16+3 mc Remu mc Int8+232 mc Int16+3 mc Mulu mc Cast_uL mc AddL mc Lvar+255 mc Peek2 mc Int8+15 mc Int8+64 mc Int16+66 mc GeUL mc BraIf0+7 mc Int8+15 mc Int8+64 mc Int16+66 mc Lvar+253 mc SubPokeL mc Lvar+253 mc IncrL mc Istr+6 dm ' ' dm 'w' dm 'h' dm 'e' dm 'n' dm '=' ld cmd,atmp mc Lvar+252 mc Peek2 mc NumStrUL mc CatStrStr mc Istr+1 dm '.' ld cmd,atmp mc CatStrStr mc Lvar+254 mc Peek2 mc NumStrUL mc CatStrStr mc Istr+1 dm ' ' ld cmd,atmp mc CatStrStr mc LogStr mc Gvar+current_time mc Peek2 mc Lvar+251 mc Peek2 mc LtUL mc BraIf0+2 mc Halt mc Bra-8 mc Gvar+current_time mc Peek2 mc Lvar+251 mc Peek2 mc EqL mc And0 mc Bra+5 mc Gvar+current_microsec mc Peek2 mc Lvar+253 mc Peek2 mc LtUL mc BraIf0+2 mc Halt mc Bra-15 mc MDrop0-4 mc MDrop0_Next-1 : new__2FD_2FD_2FD_2FD_5Shell ( FD, FD, FD, FD -- Shell ) Millicoded // Size: 136 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Int8+1 mc Int8+255 mc Lget+252 mc FD__getavail__2FDC_6uint16 mc BraIf0+4 mc Lget+252 mc FD__readbyte__2FDC_6uint16 mc MDrop0-1 mc Bra-7 mc Lget+252 mc Int8+30 mc FD__writebyte__2FDC_6uint16_ mc Int8+100 mc wait_ms__5int16_ mc Int8+0 mc Lget+251 mc FD__getavail__2FDC_6uint16 mc BraIf0+3 mc Lget+251 mc FD__readbyte__2FDC_6uint16 mc Nip mc Dup mc Int8+30 mc Eq mc BraIf0+65 mc Lget+251 mc FD__getstr__2FDC_8ucs2charAE mc DropStr mc Lget+251 mc FD__getstr__2FDC_8ucs2charAE mc Dup mc Int8+0 mc Int8+4 mc SubStr mc Cast_RangeStr mc DupToR mc Istr+4 dm 's' dm 's' dm 'z' dm '=' ld cmd,atmp mc DupToR mc Eq_CstrCstr mc FromR mc DropStr mc FromR mc DropStr mc BraIf0+40 mc Int8+4 mc Int8+0 mc Lset+252 mc Lget+255 mc Lvar+255 mc Peekpp mc AtIndexPeek mc Subq+48 mc Lset+254 mc Lget+254 mc Int8+9 mc Ule mc BraIf0+7 mc Lget+252 mc Int8+10 mc Mulu mc Lget+253 mc Add mc Lset+252 mc Bra-17 mc Int8+0 mc Lset+253 mc Lget+255 mc Lvar+255 mc Peekpp mc AtIndexPeek mc Subq+48 mc Lset+254 mc Lget+254 mc Int8+9 mc Ule mc BraIf0+7 mc Lget+253 mc Int8+10 mc Mulu mc Lget+253 mc Add mc Lset+253 mc Bra-17 mc MDrop0-1 mc DropStr mc Int8+6 mc Alloc mc ToR mc Lget+250 mc Retain mc PeekR mc ItemSet+0 mc Lget+251 mc Retain mc PeekR mc ItemSet+1 mc Lget+252 mc Retain mc PeekR mc ItemSet+2 mc Lget+253 mc Retain mc PeekR mc ItemSet+3 mc Lget+254 mc PeekR mc ItemSet+4 mc Lget+255 mc PeekR mc ItemSet+5 mc FromR mc ToR mc MDrop0-3 mc CallKill mc implicit__shell__kill__2FD_2FD mc DropStr mc CallKill mc implicit__shell__kill__2FD_2FD mc DropStr mc CallKill mc implicit__shell__kill__2FD_2FD mc DropStr mc CallKill mc implicit__shell__kill__2FD_2FD mc DropStr mc FromR mc Ret : run_shell () Millicoded // Size: 98 microcodes ld atmp,$+4 // * Millicoded jp millicoded // * Millicoded mc Istr+7 dm '[' dm 'S' dm 'H' dm 'E' dm 'L' dm 'L' dm ']' ld cmd,atmp mc LogStr mc Gget+stdout mc Istr+25 dm 10 dm 13 dm 'K' dm '1' dm '-' dm '1' dm '6' dm '/' dm '1' dm '6' dm ':' dm ' ' dm 'H' dm 'e' dm 'l' dm 'l' dm 'o' dm ' ' dm 'K' dm 'i' dm 'o' dm ' ' dm '!' dm 10 dm 13 ld cmd,atmp mc FD__putstr__2FDC_8ucs2charAE_ mc Gget+stdin mc Retain mc Gget+stdout mc Retain mc Gget+stderr mc Retain mc Gget+root mc Retain mc new__2FD_2FD_2FD_2FD_5Shell mc Gget+stdout mc Istr+14 dm 'T' dm 'e' dm 'r' dm 'm' dm 'i' dm 'n' dm 'a' dm 'l' dm ' ' dm 'r' dm 'o' dm 'w' dm 's' dm '=' ld cmd,atmp mc Lget+254 mc ItemGet+4 mc NumStrU mc CatStrStr mc Istr+6 dm ' ' dm 'c' dm 'o' dm 'l' dm 's' dm '=' ld cmd,atmp mc CatStrStr mc Lget+254 mc ItemGet+5 mc NumStrU mc CatStrStr mc Istr+2 dm 10 dm 13 ld cmd,atmp mc CatStrStr mc FD__putstr__2FDC_8ucs2charAE_ mc Dup mc Shell__run__5ShellC_ mc CallKill mc implicit__shell__kill__5Shell_5Shell mc DropStr mc Ret // --- file: "shell.asm" --- #endif // ______________________________________________________ // "Test" Microcode: #if include_tests//skipping: //#include "test/test_helper.cc" #if test_i2c//skipping: #include "test/Block.cc" #include "test/Device.cc" #include "test/BlockDevice.cc" #include "i2c.cc" #include "test/test_i2c.cc" #endif #if test_millicode//skipping: #include "test_millicode.asm" #endif #if test_long//skipping: #include "test/test_long.cc" #endif #if test_float//skipping: #include "test/test_float.cc" #endif #if test_misc//skipping: #include "test/test_misc.cc" #endif #endif // ====================================================== // RESET // ====================================================== // Reset entry condition: // ? $7FFF with 'cmddis=1' and 'cond=0' (for next instr) forced by INIT // ? $0000 is executed // : reset_7fff = $3FFF:1 clr reset // 'nop' ((cmd_dis version)) : reset = $0000 clr halt // don't halt cpu if no interrupt pending di // disable interrupt processing ((in "ld cmd,(ip++)" aka "next")) set clock4 // set full speed set clock2 // ((except if clock_predivider > 2)) // ====================================== // CPU Test // ====================================== clr led_red // see "exceptions.asm" for LED codes set led_yel set led_grn // -/yel/grn --> booting, cpu self test ld alu,1 do ld d0,alu ld a0,d0 ld d1,a0 ld a1,d1 ld d2,a1 ld atmp,d2 ld dtmp,atmp ld hp,dtmp ld sl,hp,cy ld sp,sl : bit15 if 0 ld sr,sp,nc else ld sr,sp,cy then ld ip,sr ld swap,ip ld swap,swap ld d2ar,swap equ d2ar TRAP !z if !z // * TRAP ld atmp,$ // * TRAP jp PANIC // * TRAP then // * TRAP add alu // nodelay until z // ====================================== // Test and Clear Ram // ====================================== Millicode ld ip,$+4 // * Millicode ld cmd,ival // * Millicode mc ClrLedGrn // -/yel/- --> booting, ram test mc Ramtest // --> alu = 0 // ====================================== // Init Global Data // ====================================== mc ClrLedYel // -/-/grn --> booting, initializing mc SetLedGrn // Initialize non-zero global data: // interrupt vectors: mc Int8+15, PopHP // int_vector[16] all 0x0000 note: hp points to last byte, empty heap = $ffff mc Ival $ffff // int_mask of installed devices // memory management: mc Ival mem_globs_end // gdata_ptr mc Ival $100 // gcode_ptr = start of space for new dicts mc Ival $4000 // hp_base = mem_size/4 mc Ival $8000 // sp_base = mem_size/2 mc Dup // mem_data_start := sp_base mc Dup // mem_data_end := sp_base mc Ival $FFFE // mem_ptr_start start of mem pointers = mem_end-2 mc Dup // mem_free_ptr start of linked list of free mem pointers = mem_end-2 mc Int8+0 // mem_end end of physical ram = mem_end: $0000 (TODO: eliminate?) // misc: mc Ival Ret // opcode Ret: return to millicode #if include_filesystem//skipping: mc Istr ".trash" // cstr ".trash" = trash file name #endif #if include_sio_driver_in_rom//skipping: mc Ival SIO_GETCTL_PROC mc Ival SIO_SETCTL_PROC mc Ival SIO_GETC_PROC mc Ival SIO_GETS_PROC mc Ival SIO_PUTC_PROC mc Ival SIO_PUTS_PROC mc Ival SIO_IRPT_PROC #endif // Initialize registers: // must be done before calling millicoded words mc Gget+hp_base,PopHP // reset hp note: also writes TOP value to ram mc Gget+sp_base,PopSP // reset sp #if include_floating_point//skipping: mc init_float // init globals in float.cc #endif mc ClrLedGrn // -/-/- "RUNNING" mc STOP2 // ======================================================= // Test Code // ======================================================= #if include_tests//skipping: #if test_millicode//skipping: mc TestMillicode #endif #if test_misc//skipping: mc TestMisc #endif #if test_i2c//skipping: mc TestI2C #endif #if test_long//skipping: mc TestLong #endif #if test_float//skipping: mc TestFloat #endif mc Istr "---OK!---", LogStr mc SetLedYel mc SetLedGrn mc STOP2 #endif // ======================================================= // Load and Init Device Drivers, Start Shell // ======================================================= #if !include_tests mc init_devices // init k1-bus devices in dev.cc mc ClrLedGrn // -/-/- --> running: all Leds off mc STOP2 mc run_shell mc reset #endif // --- file: "main.asm" ---