├── INTHEX.F ├── README.md ├── LEDF103.F ├── SDNOTES.TXT ├── SPI_SETUP.F ├── 72mhz.f ├── talkf105.txt ├── SD-CARD.f ├── KEYBOARD.F ├── TALKF105.F └── EFORTH.HEX /INTHEX.F: -------------------------------------------------------------------------------- 1 | \ Runs on STM32 2 | \ DUMPS INTEL HEX TO SERIAL OUT, A GOOD IDEA TO CAPTURE TO FILE ON PC 3 | \ used LOGHEX filename in TALKf105.F in fpc or similar serial loging program 4 | HEX 5 | VARIABLE ADDR-OFFSET 20000000 ADDR-OFFSET ! \ USED TO 0 BASE DUMP ADDRESS 6 | VARIABLE CS \ CHECK SUM FOR HEX LINE 7 | 8 | : .B ( VAL - ) \ EMITS A 2 CHARACTER HEX BYTE, LESS THEN 10 HEX HAS LEADING 0 9 | DUP <# # # #> TYPE \ ASSUME BASE SET TO HEX 10 | CS @ + CS ! ; 11 | 12 | \ REQUIRES SPACE CHAR FOR HANDSHAKE EACH LINE 13 | : HEX-LINE ( ADDR CNT - ADDR' ) \ DOES 10 HEX BYTES 14 | CR 15 | BEGIN KEY 20 = UNTIL 16 | 3A EMIT ( : ) 0 CS ! 17 | DUP .B \ COUNT 18 | OVER ADDR-OFFSET @ - 100 /MOD .B .B 19 | 0 .B \ TYPE OF RECORD 20 | 1- FOR 21 | DUP C@ .B 1+ 22 | NEXT 23 | CS @ NEGATE 0FF AND .B \ CHECK SUM 24 | KEY DROP ; \ HAND SHAKE 25 | 26 | : INTHEX ( ADDR COUNT - ) 27 | ." 020000040800F2" CR \ adds 08000000 to adresses 28 | HEX \ JUST IN CASE 29 | BEGIN 30 | DUP 31 | WHILE 32 | DUP >R 10 MIN 33 | HEX-LINE 34 | R> 10 - DUP 0 > AND \ NEXT COUNT 35 | REPEAT 36 | DROP DROP CR 37 | BEGIN KEY 20 = UNTIL 38 | ." :00000001FF" KEY DROP CR ; 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blue-EForth 2 | EForth for the Blue Pill with STM32F103 3 | 4 | While other Forths like MECRISP are available and have many significant features EForth is more easily stuffed in the smaller chips. 5 | This Forth was reconfigured from Dr Ting's STM3F407 Forth. Although, his original ran with '0' based addressing, I have not found a way to cause the F103 part to move its memory to 0. 6 | EForth runs in RAM but is loaded from FLASH. RAM is at 20000000H so be careful. A wrong address will cause an address fault. This will require a reset to fix. 7 | Not inerrupts are enabled but space is reserved for interrupts in the begining of FLASH. 8 | There is no boot loader needed. EFORTH is the boot loader. This code must be installed as a boot loader. 9 | It expects there to be a serial terminal connected to PA9 and PA10. It is 56K baud, 8 bit, Even parity. This was the same rate as I used for downloading. 10 | The code is in a .HEX file. 11 | I have not tried TURNKEY yet. 12 | Most terminal programs should work but one may need some changes to download source. 13 | I use a program that I wrote to boot load the FLASH, keyboard interface to EFORTH and source download Forth programs. It runs in Win32Forth, an open source Forth. 14 | 15 | TalkF105.f is win32forth code to FLASH the Blue Pill and as a terminal for EFORTH on the Blue Pill. 16 | TalkF105.TXT gives instructions to do FLASH the Blue Pill. 17 | See LogHex in the TALK program and INTHEX for the F103 to save an image of code on the F103. 18 | 19 | -------------------------------------------------------------------------------- /LEDF103.F: -------------------------------------------------------------------------------- 1 | \ F103 BLUE PILL BLINK PC13 2 | \ REFER TO STM PDF RM0008 FOR GPIO SETUPS 3 | HEX 4 | : BIT ( PIN# - BIT ) \ USED AS A GENERAL PORT MASK VALUE 5 | 1 SWAP LSHIFT ; 6 | 7 | : CONF ( PIN# - MASK OFFSET ) \ USED FOR MODE AND CONFIG 8 | 4 * 20 /MOD 9 | 4 * 10 | 0F ROT LSHIFT 11 | SWAP ; 12 | 13 | \ MODE MASK FIRST THEN MODIFIERS 14 | CCCCCCCC CONSTANT INMODE 15 | 33333333 CONSTANT OUT50 16 | 11111111 CONSTANT OUT10 17 | 22222222 CONSTANT OUT2 18 | 19 | \ CONFIG MODIFIERS 20 | \ INPUT MODIFIERS 21 | : ANALOG 0 AND ; 22 | : FLOAT 44444444 AND ; 23 | : UP/DN 88888888 AND ; 24 | 25 | \ OUTS TYPE MODIFIERS 26 | : ALT 88888888 OR ; 27 | : P/P ; 28 | : DRAIN 44444444 OR ; 29 | 30 | \ GPIO DATA PORTS OFFSETS 31 | 08 CONSTANT INPUT 32 | 10 CONSTANT S/R 33 | 0C CONSTANT OUTPUT 34 | 35 | EXAMPLE TO PLAY WITH GREEN LED 36 | DECIMAL 37 | 13 CONSTANT LED# 38 | LED# BIT CONSTANT LED \ PORT MASK 39 | OUT2 DRAIN LED# CONF PC+ MSK! 40 | 41 | 42 | \ MODE MASK FIRST THEN MODIFIERS 43 | \ CCCCCCCC CONSTANT INMODE 44 | \ 33333333 CONSTANT OUT50 45 | \ 11111111 CONSTANT OUT10 46 | \ 22222222 CONSTANT OUT2 47 | 48 | \ CONFIG MODIFIERS 49 | \ INPUT MODIFIERS 50 | \ : ANALOG 0 AND ; 51 | \ : FLOAT 44444444 AND ; 52 | \ : UP/DN 88888888 AND ; 53 | 54 | \ OUTS TYPE MODIFIERS 55 | \ : ALT 88888888 OR ; 56 | \ : P/P ; 57 | \ : DRAIN 44444444 OR ; 58 | 59 | \ GPIO DATA PORTS OFFSETS 60 | \ 08 CONSTANT INPUT 61 | \ 10 CONSTANT S/R 62 | \ 0C CONSTANT OUTPUT 63 | 64 | \ EXAMPLE TO PLAY WITH GREEN LED 65 | DECIMAL 66 | 13 CONSTANT LED# 67 | LED# BIT CONSTANT LED \ PORT MASK 68 | OUT2 DRAIN LED# CONF PC+ MSK! 69 | HEX 70 | 71 | : OFF LED 0 PC+ SET! ; 72 | : ON LED 0 PC+ CLR! ; 73 | 74 | -------------------------------------------------------------------------------- /SDNOTES.TXT: -------------------------------------------------------------------------------- 1 | FINDINGS ON THE sd CARD. 2 | 3 | This was a 2gig SD with fat32. I was able to read and write data to the SD card. It is still experimental. 4 | The are 3 basic inits used on these card. See: 5 | elm-chan.org/docs/mmc/mmc_e.html 6 | for other init sequences. This is excelent information on SD cards. 7 | Much of this was borrowed from JeeLabs Forth code on githib. It was mercrisp Forth that I modified to 8 | eforth.I found his code incorrect for the SPI init. I wrote mine from the STM apnote so should work 9 | with your STM32f103. 10 | I've not done much with it yet. I may create a large blank file on the PC and teat it as a number of block files. 11 | Maybe someone else will expand it to file access. 12 | 13 | It has 80H blocks for each cluster 14 | 2000H is the boot 15 | The first FAT is at 2006H the second copy is at 20F3 16 | The first file is at 2200H FAT=2 BASE 2100 17 | 21E0 HAS THE DIR 18 | 19 | EACH DISK SECTOR IS 5 SD SECTORS LONG 20 | EACH NIC SECTOR IS 5000H BITS LONG. THIS IS 0A00 BYTES 21 | THIS IS 5 SD SECTORS. THE NIC DISK IS 77 TRACKS WITH 2 SECTORS PER 22 | TRACK OR 9AH NIC SECTORS. 302H OR 770d SD SECTORS. 23 | THIS IS 394240 BYTES 24 | lOOKS LIKE 0DH CLUSTERS WITH 32k BYTES PER CLUSTER 25 | 26 | 27 | 28 | DO THE MATH AGAIN 29 | 30 | 1kX20 IS 5000H BITS 31 | 5000 8 / . 0A00H BYTES PER NIC SECTOR 32 | THAT IS 5 SD SECTORS OF 512 BYTES 400H 33 | WITH 32K BYTES PER CLUSTER OR 32D SECTORS 34 | AN ENTIRE NIC DISK IS BETWEEN 0C AND 0D CLUSTERS 35 | 0 1 2 3 4 5 6 7 8 9 A B C 36 | TIMES THE FIRST CLUSTER 37 | NOW, HOW MUCH PER CLUSTER 38 | IF I PUT 0C NIC SECTOR PER CLUSTER 39 | 40H SD SECTORS PER CLUSTER 40 | 40H 5 / IS 0C NIC80 SECTORS PER CLUSTER WITH 4 SD SECTOR LEFT 41 | 42 | 9A 5 / 0c REM 0A 43 | GET FIRST SECTOR NUMBER 44 | MULTIPLY BY 40 TO GET FIRST SECTOR NUMBER 45 | TO THIS WE ADD NIC SECTOR OFFSET IN SD SECTORS 46 | NIC SECTOR * 5 ADD IT TO THE FIRST SECTOR ON THE SD 47 | 48 | 49 | NEEDS 8 BYTE PORT WITH READ AND WRITE MAYBE A SERIAL CHIP IS 50 | EASIER TO DEAL WITH. 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /SPI_SETUP.F: -------------------------------------------------------------------------------- 1 | \ SPI SETUPS 2 | \ ADDAPTED FROM JEELABS/EMBELLO 3 | \ REFER TO STM PDF RM0008 FOR GPIO SETUPS 4 | HEX 5 | : BIT ( PIN# - BIT ) \ USED AS A GENERAL PORT MASK VALUE 6 | 1 SWAP LSHIFT ; 7 | 8 | : CONF ( PIN# - MASK OFFSET ) \ USED FOR MODE AND CONFIG 9 | 4 * 20 /MOD 10 | 4 * 11 | 0F ROT LSHIFT 12 | SWAP ; 13 | 14 | \ MODE MASK FIRST THEN MODIFIERS 15 | CCCCCCCC CONSTANT INMODE 16 | 33333333 CONSTANT OUT50 17 | 11111111 CONSTANT OUT10 18 | 22222222 CONSTANT OUT2 19 | 20 | \ CONFIG MODIFIERS 21 | \ INPUT MODIFIERS 22 | : ANALOG 0 AND ; 23 | : FLOAT 44444444 AND ; 24 | : UP/DN 88888888 AND ; 25 | 26 | \ OUTS TYPE MODIFIERS 27 | : ALT 88888888 OR ; 28 | : P/P ; 29 | : DRAIN 44444444 OR ; 30 | 31 | \ GPIO DATA PORTS OFFSETS 32 | 08 CONSTANT INPUT 33 | 10 CONSTANT S/R 34 | 0C CONSTANT OUTPUT 35 | 36 | \ ON Port A 37 | 4 CONSTANT SSEL# 38 | 5 CONSTANT SCLK# 39 | 6 CONSTANT MISO# 40 | 7 CONSTANT MOSI# 41 | 42 | SSEL# BIT CONSTANT SSEL 43 | SCLK# BIT CONSTANT SCLK 44 | MISO# BIT CONSTANT MISO 45 | MOSI# BIT CONSTANT MOSI 46 | 47 | 40013000 CONSTANT SPI1 48 | SPI1 0 + CONSTANT SPI1-CR1 49 | SPI1 4 + CONSTANT SPI1-CR2 50 | SPI1 8 + CONSTANT SPI1-SR 51 | SPI1 C + CONSTANT SPI1-DR 52 | 53 | : +SPI ( - ) SSEL 0 PA+ CLR! ; 54 | : -SPI ( - ) SSEL 0 PA+ SET! ; 55 | 56 | : SPI-INIT ( - ) 57 | OUT10 P/P SSEL# CONF PA+ MSK! 58 | OUT10 P/P ALT SCLK# CONF PA+ MSK! 59 | INMODE FLOAT MISO# CONF PA+ MSK! 60 | OUT10 P/P ALT MOSI# CONF PA+ MSK! 61 | 1000 DUP 40021018 ( RCC_APB2ENR ) MSK! \ ENABLE CLOCK 62 | 4 ( SSOE ) DUP SPI1-CR2 MSK! 63 | SPI1-SR @ DROP \ STOPS HANGES 64 | 50 SPI1-CR1 ! 65 | SPI1-SR @ DROP 66 | 54 SPI1-CR1 ! ; 67 | 68 | : SPI-CLK ( - ) 69 | SPI1-SR @ 1 AND 70 | IF SPI1-DR @ DROP THEN 71 | BEGIN 72 | SPI1-SR @ 2 AND 73 | UNTIL 74 | 0FF SPI1-DR ! ; 75 | 76 | : >SPI> ( C - C ) 77 | BEGIN 78 | SPI1-SR @ 2 AND 79 | UNTIL 80 | SPI1-DR ! 81 | BEGIN 82 | SPI1-SR @ 1 AND \ WAIT RESPONSE 83 | UNTIL SPI1-DR @ ; 84 | 85 | : SPI> ( - C ) 0 >SPI> ; 86 | : >SPI ( C - ) >SPI> DROP ; 87 | 88 | : SPI. ( - ) \ DISPLAY REGS 89 | CR ." CR1 " SPI1-CR1 @ . 90 | ." CR2 " SPI1-CR2 @ . 91 | ." SR " SPI1-SR @ . ; 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /72mhz.f: -------------------------------------------------------------------------------- 1 | 2 | 3 | \ : DELAY 4 | \ 10000 FOR NEXT ; 5 | 6 | \: BLINK \ FOR Gotek STM32F105 needs mods for f103 7 | \ \ GPIOA OUTPUT A0 8 | \ 6 40010800 ! 9 | \ 20 FOR 10 | \ 1 40010814 ! 11 | \ DELAY 12 | \ 1 40010810 ! 13 | \ DELAY 14 | \ NEXT ; 15 | 16 | \ My f103 EForth boots to 8MHz HSI 17 | \ Stepping the clock up to 72Mhz and dealing with 18 | \ the change of the USART1 frequency to keep at 56K 19 | \ Refer to RM0008 20 | 21 | \ RCC_CR OFFSET 0 22 | \ 22 22 22-1 1 11-00 23 | \ 98 76 54 9 8 76 10 24 | \ PP PP PP C W HH HH 25 | \ LL LL LL S S SS SS 26 | \ LL LL LL S E EE II 27 | \ 33 22 RO O B RO RO 28 | \ RO RO DN N Y DN DN 29 | \ DN DN Y P Y Y 30 | \ Y Y 31 | 32 | \ RCC_CFGR OFFSET 4 33 | \ 2 2211 11 11 111 100 0000 0000 34 | \ 2 1098 76 54 321 098 7654 3210 35 | \ O PPPP PP AA PPP PPP HHHH SSSS 36 | \ T LLLL LL DD PPP PPP PPPP WWWW 37 | \ G LLLL LL CC RRR RRR RRRR SS10 38 | \ F MMMM XS PP EEE EEE EEEE 10 39 | \ P UUUU TR RR 222 111 3210 40 | \ R LLLL PC EE 210 210 41 | \ E 3210 R 10 42 | \ E 43 | 44 | \ RCCCFGR2 OFFSET 2C 45 | \ 1 1111 1100 0000 0000 46 | \ 6 5432 1098 7654 3211 47 | \ P PPPP PPPP PPPP PPPP 48 | \ R LLLL LLLL RRRR RRRR 49 | \ E LLLL LLLL EEEE EEEE 50 | \ D 3333 2222 DDDD DDDD 51 | \ I MMMM MMMM IIII IIII 52 | \ V UUUU UUUU VVVV VVVV 53 | \ 1 LLLL LLLL 2222 1111 54 | \ S 3210 3210 3210 3210 55 | \ R 56 | \ C 57 | 58 | : 8MHZ ( - ) 59 | 0 40021004 ! \ reset state 8MHz 60 | 81 40021004 ! \ 61 | 10 40022000 ! \ reset condition 62 | 8F 0FFFF 40013808 msk! ; \ 56K baud 63 | 64 | 65 | : 72MHZ ( - ) \ Assumes reset at 8MHz HSI 66 | \ Also check that any interrupt driven output is stable while changing clocks 67 | BEGIN 68 | 40013800 @ 80 AND 69 | UNTIL \ WAIT FOR USART TXE 70 | 0506 0FFFF 40013808 MSK! \ KEEP 56k 71 | 45670123 40022004 ! 72 | CDEF89AB 40022004 ! \ UNLOCK FLASH 73 | 45670123 40022008 ! 74 | CDEF89AB 40022008 ! \ UNLOCK OPTIONS 75 | 32 40022000 ! \ SET 2 WAIT STATES FOR FLASH ACCESS 76 | \ DELAY NOT SURE WHY IT IS NEEDED MAYBE A ISB, DSB OR DMB INSTR IS NEEDED DSB? 77 | [ 8F5FF3BF , ] \ DMB INSTRUCTION 78 | \ ADDRESS 40021004 79 | \ VALUE MASK 80 | \ 01C0000 3C0000 72 PLL @ 9x 81 | \ 10000 10000 PLL SOURCE PRDIV1 82 | \ 8000 0C000 ADC PRE AT 12MHZ 83 | \ 100 700 APB1DIV 2/ 84 | 01D8100 03DC700 40021004 MSK! \ ABOVE COMMENT 85 | 86 | 01010000 DUP 40021000 MSK! \ START HSE AND PLL 87 | BEGIN 88 | 40021000 @ 2020000 AND 2020000 = 89 | UNTIL \ WAIT FOR HSE AND PLL RDY'S 90 | 0A 0F 40021004 MSK! \ SWITCH TO PLL 91 | ; \ SHOULD BE 72MHZ NOW 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /talkf105.txt: -------------------------------------------------------------------------------- 1 | 2 | TalkF105.f 3 | 4 | Source file that I load with Win32Forth on a PC. I use this 5 | program to bootstrap the EForth into the STM32 chip. It 6 | was originally written for the STM32F105 so you'll see 7 | F105 used in a lot of names. It works fine for the 8 | STM32F103 chip as well. This file was created for my own 9 | use and has a bunch of other things in it for my own use 10 | and debugging the loading and running of EForth. It is not very 11 | clean and only provided in case one doesn't have a method 12 | of loading the EForth.hex file. Please excuse the sloppy 13 | coding. 14 | If you wish to write you own loader, on another platform, 15 | please refer to the STM documentation, as I have. 16 | It communicates with the typical FTDI 5V/3.3V USB to serial. 17 | It could communicate with a normal serial as well but you'd 18 | need a level converter to 3.3V from RS232 levels. 19 | I connect 4 wires from the FTDI board to the Blue Pill (BP). 20 | GND to GND 21 | 5V to 5V (I suspect one could do 3.3V to 3.3V instead) 22 | FTDI TX to pin A9 of the BP 23 | FTDI RX to pin A10 of the BP 24 | configure the FTDI for 3.3V output signals 25 | 26 | To download the EForth into the BP 27 | 28 | 1. copy the *.hex file to EForth.hex (I use a fixed name here) 29 | 2. set the boot0 jumper to 1 on the BP and boot1 to 0 30 | 3. connect USB cable, FTDI and BP to the PC. 31 | 4. hit reset button on BP 32 | 5. from pc, 'SS (enter)' 33 | 6. If you've configured the serial port correctly, the BP 34 | should return "Ack". If not check to see that you are 35 | actually communicating with the serial. My FTDI board has 36 | a LED indicator. There is some setup of the FTDI on the PC 37 | to connect a serial channel to the USB but it was so long 38 | ago, I've forgotten it all. 39 | 7. from pc 'unProtRd (enter)' , it should reply "Ack" 40 | 8. hit reset button on BP ( it shouldn't need this but for 41 | some reason some chips do need a hard reset. 42 | 9. 'SS (enter)' again to get Ack 43 | 10. from pc 'unProtWr (enter)', should get Ack 44 | 11. hit reset switch, on BP again and 'SS' (enter)' 45 | 12. from PC, '0 1 2 3 4 5 6 7 8 9 EM (enter)' 46 | you should get Acks. This erases the flash ready to load 47 | EForth. The F103 is 1K blocks. 9 is the number of blocks 48 | 13. from pc 'DownLoad (enter)', A stream of Acks indicates 49 | it is loading the file EForth.hex 50 | 14. When done type 'TALK (enter)' then move the boot0 jumper 51 | to zero. Hit the reset button one more time and you should 52 | see the EForth sign on. Used upper case for EFORTH, as it 53 | is case sensitive. 54 | 15. To return to the PC use the 'esc' key. 55 | 16. to load a Forth source file to the BP, be at the PC and 56 | type 'loadf105 FileName (enter)' the source file should then 57 | load. Enjoy. 58 | 59 | I should note that it runs at 56K, even parity, 8 bits. The BP 60 | could run at 115K but the 8MHz RC clock is not always stable 61 | enough. I run EFORTH at the same rate so I don't need to 62 | re-initialize the serial connection. 63 | -------------------------------------------------------------------------------- /SD-CARD.f: -------------------------------------------------------------------------------- 1 | \ FROM JCW @ GETHUB EMBELLO/1608 FOR SD CARDS 2 | \ NEEDS SPI_SETUP.F LOADED FIRST 3 | 4 | \ NEEDS MS FROM TICK COMPARE(STRING) 5 | HEX 6 | : TUCK SWAP OVER ; 7 | : NIP SWAP DROP ; 8 | VARIABLE TEMP 9 | : COMPARE ( $A $B Z - FLAG ) \ NOT OPIMAL JUST WORKS 10 | 0 TEMP ! 11 | 1- 12 | FOR 13 | 2DUP C@ SWAP C@ - 14 | TEMP @ OR TEMP ! 15 | 1 1 D+ 16 | NEXT 17 | TEMP @ 0= ; 18 | 19 | 0E00E018 CONSTANT TICK 20 | 0FFFFFF TICK 4 - ! \ MAXIMUM COUNT 21 | 10005 TICK - 8 ! \ START TICK COUNTER 22 | : MS ( N - ) \ 72MHz /8 = 9HHz 23 | \ 1 MS = 9000d = 2328h 24 | 0 TICK ! 25 | 2328 * 26 | BEGIN 27 | TICK @ OVER > 28 | UNTIL DROP ; 29 | 30 | 31 | : SD-SLOW ( - ) 38 DUP SPI1-CR1 MSK! ; 32 | 33 | : SD-WAIT ( - ) BEGIN 0FF >SPI> ( DUP . ) 0FF = UNTIL ; 34 | 35 | : SD-CMD ( CMD ARG - u ) 36 | SWAP \ CR MIILIS . ." CMD" DUP . 37 | -SPI 2 US +SPI 38 | 0FF >SPI 39 | 40 OR >SPI 40 | DUP 18 RSHIFT >SPI 41 | DUP 10 RSHIFT >SPI 42 | DUP 8 RSHIFT >SPI 43 | >SPI 44 | 95 >SPI 45 | BEGIN 46 | 0FF >SPI> DUP 80 AND 47 | WHILE 48 | DROP 49 | REPEAT ; 50 | 51 | : SD-INIT ( - ) 52 | SPI-INIT SD-SLOW 09 FOR 0FF >SPI NEXT 53 | \ 0 TICKS ! 54 | BEGIN 55 | 0 0 SD-CMD \ CMD0 GO IDLE 56 | 01 = 57 | UNTIL 58 | BEGIN 59 | 10 MS ( NEEDS MS CODE ) 60 | 37 0 SD-CMD DROP SD-WAIT 61 | 29 0 CD-CMD 62 | 0= 63 | UNTIL 64 | SPI-INIT \ BACK TO NORMAL SPEED 65 | \ 3B 0 SD-CMD . SD-WAIT 66 | \ 8 1AA SD-CMD . SD-WAIT 67 | \ 10 200 SD-CMD . SD-WAIT 68 | ; 69 | 70 | 200 CREATE SD.BUF ALLOT 71 | 72 | : SD-COPY ( F N - ) 73 | SWAP 74 | BEGIN 75 | ( DUP . ) 0FE = NOT 76 | WHILE \ WAIT FOR CHANGE AND THEN NOT 0FE 77 | 0FF >SPI> 78 | REPEAT 79 | 1- DUP SD.BUF + SWAP 80 | FOR 81 | 0FF >SPI> 82 | OVER R@ - C! 83 | NEXT DROP 84 | 0FF DUP >SPI >SPI ; 85 | 86 | \ 0 1 2 3 4 5 6 7 8 9 A B C D E F CRC 87 | \ 002E00325B5A83A9FFFFFF80168000916616 KINGSTON 2GB 88 | \ 007F00325B5A83D3F6DBF819668000E7772B SANDISK 2GB 89 | 90 | : SD-SIZE ( - N ) 91 | 9 0 SD-CMD 10 SD-COPY 92 | \ HTTPS://WWW.AVRFREAKS.NET/FORM/HOW-DETERMINE-MMC-CARD-SIZE 93 | \ HTTPS://MEMBERS.SDCARD.ORG/DOWNLOADS/PLS/SIMPLIFIED_SPECS/ARCHIVE/PART1_301.PDF 94 | \ TODO BYTES 6 AND 8 MAY BE REVERSED... 95 | SD.BUF 6 + C@ 03 AND 0A LSHIFT 96 | SD.BUF 7 + C@ 2 LSHIFT OR 97 | SD.BUF 8 + C@ 6 RSHIFT OR ; 98 | 99 | : SD-READ ( PAGE - ) \ READ ONE 512-BYTE PAGE FROM SDCARD 100 | 9 LSHIFT 11 SWAP SD-CMD 200 SD-COPY ; 101 | 102 | : SD-WRITE ( PAGE - ) \ WRITE 512 103 | 9 LSHIFT 18 SWAP SD-CMD DROP 104 | 0FF >SPI 0FE >SPI 105 | \ 200 0 DO SD.BUF I + C@ >SPI LOOP 106 | 1FF SD.BUFF + 1FF 107 | FOR 108 | DUP R@ - C@ >SPI 109 | NEXT 110 | 0FF DUP >SPI >SPI SD-WAIT ; 111 | 112 | \ FAT ACCESS 113 | 0 VARIABLE SD.FAT \ BLOCK # OF FIRST FAT 114 | 0 VARIABLE SD.SPC \ SECTORS PER CLUSTER (64) 115 | 0 VARIABLE SD.ROOT \ BLK# OF FIRST ROOT SECTOR 116 | 0 VARIABLE SD.#ENT \ NUMBER OF ROOT ENTRIES 117 | 0 VARIABLE SD.DATA \ BLK OFFSET OF CLUSTER #2 118 | 119 | : SD-MOUNT ( - ) \ MOUNT A FAT16 VOLUME,EXTRACT THE KEY DISK INFO 120 | SD-INIT \ IN INTERFACE CARD 121 | 0 SD-READ \ READ BLOCK #0 122 | SD.BUF 1C6 + @ \ GET LOCATION OF BOOT SECTOR 123 | DUP 1+ SD.FAT ! \ START SECTOR OF FAT AREA 124 | DUP SD-READ \ READ BOOT RECORD 125 | SD.BUF 0D + C@ \ SECTORS/CLUSTER 126 | SD.SPC ! \ DEPENDS ON FORMATTED DISK SIZE 127 | SD.BUF 0E + H@ \ RESERVED SECTOR 128 | SD.BUF 10 + C@ \ NUMBER OF FAT COPIES 129 | SD.BUF 16 + H@ \ SECTOR/FAT 130 | * + + DUP SD.ROOT ! \ START SECTOR OF ROOT DIR 131 | SD.BUF 11 + H@ \ MAX ROOT ENTRIES 132 | DUP SD.#ENT ! \ SAVE FOR LATER 133 | 4 RSHIFT + SD.DATA ! ; \ START SECTOR OF DATA AREA 134 | 135 | : SD.MOUNT. ( - ) \ MOUNT AND SHOW SOME BASIC CARD INFO 136 | SD-MOUNT 137 | CR ." LABEL: " SD.BUF 2B + 0B TYPE SPACE 138 | ." FORMAT: " SD.BUF 36 + 8 TYPE SPACE 139 | ." CAPACITY: " SD.BUF 20 + @ . ; 140 | 141 | : DIRENT ( A - ) \ DISPLAY DIR ENTRY 142 | DUP C@ 80 AND 0= OVER 2+ C@ AND 143 | IF 144 | CR DUP 0B TYPE SPACE 145 | DUP 11 + C@ . SPACE 146 | DUP 1A + H@ . 147 | DUP 1C + @ . 148 | THEN ; 149 | 150 | VARIABLE CNT 151 | : CNT++ CNT @ DUP 1+ CNT ! ; 152 | 153 | : LS ( - ) \ DISPLAY ROOT DIR SKIPPING LFNs AND DELETED 154 | SD.BUF 200 + \ DON'T LIKE THIS?? 155 | \ SD#ENT @ 0 156 | \ DO 157 | \ I 0F AND 0= 158 | \ IF 159 | \ SD.ROOT @ I 4 RSHIFT + SD-READ 160 | \ 200 - 161 | \ THEN 162 | \ DIRENT 20 + 163 | \ LOOP DROP ; 164 | 0 CNT ! 165 | SD#ENT @ 1- 166 | FOR 167 | CNT++ 0F AND 0= 168 | IF 169 | SD.ROOT@ CNT @ 1- 4 RSHIFT + SD-READ 170 | 200 - 171 | THEN 172 | DIRENT 20 + 173 | NEXT DROP ; 174 | 175 | \ : FAT-FIND ( ADDR - U ) \ FIND ENTRY BY NAME, 176 | \ RETURN DATA CLUSTER, ELSE $FFFF 177 | \ SD.BUF 200 + ( ADDR BEND ) 178 | \ SD.#ENT @ 0 179 | \ DO 180 | \ I 0F AND 0= 181 | \ IF ( 10 DIR ENTRIES PER BUFF ) 182 | \ SD.ROOT @ i 4 RSHIFT + SD-READ ( READ NEXT ) 183 | \ 200 - 184 | \ THEN 185 | \ 2DUP 0B TUCK COMPARE 186 | \ IF 187 | \ NIP 1A + H@ 188 | \ UNLOOP 189 | \ EXIT 190 | \ THEN 191 | \ 20 + 192 | \ LOOP 2DROP 0FFFF ; 193 | 194 | : FAT-FIND ( FileName$ - FAT/FFFF ) \ FFFF FAILS 195 | \ ASSUME ROOT IS IN SD.BUF ( SD-MOUNT ) 196 | >R \ SAVE FILE NAME ADDRESS 197 | 0FFFF \ FAIL FLAG 198 | SD#ENT @ \ ENTRIES 199 | 20 * \ LAST ENTRY OFFSET +1 ENTRY 200 | 0 \ FIRST ENTRY 201 | BEGIN 202 | 2DUP - \ DONE WHEN ENTRY OFFSET = LAST OFFSET 203 | WHILE 204 | DUP 1E0 AND 0= \ 1E0 = ( 10 * 20 ) - 10 205 | IF \ RELOAD EVERY 16 ENTRIES 206 | SD.ROOT @ OVER ( 4 5 + ) 9 RSHIFT + SD-READ 207 | THEN 208 | DUP 1E0 AND SD.BUF + R@ 0B COMPARE ( FAIL LAST MATCH? ) 209 | IF 210 | >R 2DROP \ DROP FAIL-FLAG AND LAST ENTRY+1 211 | R> 1A + H@ \ FAT 212 | R> DROP EXIT \ DROP FILE NAME 213 | ELSE 214 | 20 + \ ENTRY SIZE 215 | THEN 216 | REPEAT 217 | 2DROP R> DROP ; \ FAIL FLAG ONLY 218 | 219 | 220 | : FAT-NEXT ( FAT - FAT ) \ RETURN NEXT FAT CLUSTER, OR $FFFx AT END 221 | \ TODO HARD-CODED FOR 64 SEC / 32 KB PER CLUSTER 222 | DUP 8 RSHIFT SD.FAT @ + SD-READ 223 | 0FF AND 2* SD.BUF + H@ ; 224 | 225 | : CHAIN. ( U - ) \ DISPLY THE CHAIN OF CLUSTERS 226 | BEGIN 227 | DUP . 228 | DUP 0F OR 0FFFF <> 229 | WHILE 230 | FAT-NEXT 231 | REPEAT DROP ; 232 | 233 | \ 128 CLUSTERS IS 8 MB WHEN CLUSTER SIZE IS 64 234 | 4 CONSTANT NFILES 235 | 81 2* NFILES * CREATE FAT.MAPS ALLOT \ MAPS OF 128 CLUSTERS MAX 236 | 237 | : FILE ( N - A ) \ CONVERT FILE 0,,3 TO A MAP ADDRESS INSIDE FAT.MAPS 238 | 81 2* * FAT.MAPS + ; 239 | 240 | : FAT-CHAIN ( U N - ) \ STORE CLUSTERS FOR USE AS FILE MAP N 241 | FILE 242 | BEGIN 243 | 2DUP ! 2+ * FAT.MAPS + ; 244 | 245 | : FAT-CHAIN ( U N - ) \ STORE CLUSTERS FOR USE AS FILE MAP N 246 | FILE 247 | BEGIN 248 | 2DUP ! 2+ 249 | OVER 0F OR 0FFFF <> 250 | WHILE 251 | SWAP FAT-NEXT SWAP 252 | REPEAT 2DROP ; 253 | 254 | : FAT-MAP ( N1 N2 - N ) \ MAP BLK N1 TO RAW BLK NUMBER USING FILE N2 MAP 255 | FILE 256 | OVER SD.SPC @ / 2* + H@ 257 | 2 - SD.SPC @ * SWAP SD.SPC @ 1 - AND + 258 | SD.DATA @ + ; 259 | 260 | -------------------------------------------------------------------------------- /KEYBOARD.F: -------------------------------------------------------------------------------- 1 | \ KEYBOARD.F RUN A PS2/AT KEYBOARD 2 | \ PB IS CHOSEN BECAUSE IT IS 5V TOLERENT 3 | \ PB-8 to PB-14 ARE PAR DATA 4 | \ PB-15 IS THE STROBE 5 | \ PB-6 IS KEYBOARD CLOCK 6 | \ PB-7 IS KEYBOARD DATA SIMPLEST DATA HANDLING 7 | \ 8 | HEX 9 | 10 | : BIT ( PIN# - BIT ) \ USED AS A GENERAL PORT MASK VALUE 11 | 1 SWAP LSHIFT ; 12 | 13 | : CONF ( PIN# - MASK OFFSET ) \ USED FOR MODE AND CONFIG 14 | 4 * 20 /MOD 15 | 4 * 16 | 0F ROT LSHIFT 17 | SWAP ; 18 | 19 | \ MODE MASK FIRST THEN MODIFIERS 20 | CCCCCCCC CONSTANT INMODE 21 | 33333333 CONSTANT OUT50 22 | 11111111 CONSTANT OUT10 23 | 22222222 CONSTANT OUT2 24 | 25 | \ CONFIG MODIFIERS 26 | \ INPUT MODIFIERS 27 | : ANALOG 0 AND ; 28 | : FLOAT 44444444 AND ; 29 | : UP/DN 88888888 AND ; 30 | 31 | \ OUTS TYPE MODIFIERS 32 | : ALT 88888888 OR ; 33 | : P/P ; 34 | : DRAIN 44444444 OR ; 35 | 36 | \ GPIO DATA PORTS OFFSETS 37 | 38 | 08 PB+ CONSTANT InB 39 | 0C PB+ CONSTANT OutB 40 | 41 | 7 CONSTANT Data# 42 | 0FF00 CONSTANT ParMsk \ PORT + STROBE MASK 43 | 8000 CONSTANT StrobeMsk 44 | VARIABLE Strobe \ NEED TO ADD CODE TO SET + OR - STROBE 45 | 46 | 0 PB+ CONSTANT PortB 47 | Data# BIT CONSTANT Data ( 10000000B ) 48 | : +Data ( - ) Data PortB SET! ; 49 | : -Data ( - ) Data PortB CLR! ; 50 | 6 CONSTANT Clk# 51 | Clk# BIT CONSTANT Clk 52 | : +Clk ( - ) Clk PortB SET! ; 53 | : -Clk ( - ) Clk PortB CLR! ; 54 | 55 | : SetPB 56 | OUT10 DRAIN Data# CONF PB+ MSK! 57 | OUT10 DRAIN Clk# CONF PB+ MSK! 58 | OUT10 DRAIN 0F CONF PB+ MSK! \ STROBE 59 | OUT10 DRAIN 0E CONF PB+ MSK! \ PARALLEL BITS 60 | OUT10 DRAIN 0D CONF PB+ MSK! 61 | OUT10 DRAIN 0C CONF PB+ MSK! 62 | OUT10 DRAIN 0B CONF PB+ MSK! 63 | OUT10 DRAIN 0A CONF PB+ MSK! 64 | OUT10 DRAIN 09 CONF PB+ MSK! 65 | OUT10 DRAIN 08 CONF PB+ MSK! ; 66 | 67 | CREATE Table 80 ALLOT 68 | Table 80 0 FILL 69 | : X SWAP Table + C! ; 70 | ( 0 TO 60H ) 71 | 0D 09 X 72 | 0E 60 X 73 | 15 71 X 74 | 16 31 X 75 | 1A 7A X 76 | 1B 73 X 77 | 1C 61 X 78 | 1D 77 X 79 | 1E 32 X 80 | 21 63 X 81 | 22 78 X 82 | 23 64 X 83 | 24 65 X 84 | 25 34 X 85 | 26 33 X 86 | 29 20 X 87 | 2A 76 X 88 | 2B 66 X 89 | 2C 74 X 90 | 2D 72 X 91 | 2E 35 X 92 | 31 6E X 93 | 32 62 X 94 | 33 68 X 95 | 34 67 X 96 | 35 79 X 97 | 36 36 X 98 | 3A 6D X 99 | 3B 6A X 100 | 3C 75 X 101 | 3D 37 X 102 | 3E 38 X 103 | 0E 60 X 104 | 4E 2D X 105 | 41 2C X 106 | 42 6B X 107 | 43 69 X 108 | 44 6F X 109 | 45 30 X 110 | 46 39 X 111 | 49 2E X 112 | 4A 2F X 113 | 4B 6C X 114 | 4C 3B X 115 | 4D 70 X 116 | 52 27 X 117 | 54 5B X 118 | 55 3D X 119 | 5A 0D X 120 | 5B 5D X 121 | 5D 5C X 122 | 66 08 X 123 | 76 1B X 124 | 125 | CREATE ShfTable 14 ALLOT 126 | : Z SWAP 2C - ShfTable + C! ; 127 | 2C 3C Z 128 | 2D 5F Z 129 | 2E 3E Z 130 | 2F 3F Z 131 | 30 29 Z 132 | 31 21 Z 133 | 32 40 Z 134 | 33 23 Z 135 | 34 24 Z 136 | 35 25 Z 137 | 36 5E Z 138 | 37 26 Z 139 | 38 2A Z 140 | 39 28 Z 141 | 3A 22 Z 142 | 3B 27 Z 143 | 3C 3C Z 144 | 3D 2B Z 145 | 3E 3E Z 146 | 3F 3F Z 147 | 148 | CREATE ShftTable2 6 ALLOT HERE ALIGNED CP ! 149 | 150 | : W SWAP 5B - ShftTable2 + C! ; 151 | 152 | 5B 7B W 153 | 5C 7C W 154 | 5D 7D W 155 | 5E 5E W 156 | 5F 5F W 157 | 60 7E W 158 | 159 | \ SPECIAL CASE SHIFT 60 7E 160 | \ CONTROL ARE 40 TO 5A INCLUSIVE AND 60 T0 7A 161 | 162 | 163 | \ SHIFT 12 59 164 | \ CNTRL L 14 R E0 14 165 | \ CAPS LOCK 58 166 | \ NUM 77 167 | \ BACK SPACE 66 168 | VARIABLE Parity 169 | 170 | 171 | : 40uS ( - ) 3 FOR 4 5 / DROP NEXT ; 172 | : Clk@ ( - BIT ) InB @ Clk AND ; 173 | : Data@ ( - BIT ) InB @ Data AND ; 174 | 175 | : Cycle 176 | BEGIN Clk@ UNTIL 177 | BEGIN Clk@ 0 = UNTIL ; 178 | 179 | : Bit@ ( - BIT ) 180 | Cycle Data@ ; 181 | 182 | : WaitStart 183 | +Data +Clk 184 | BEGIN 185 | Cycle 186 | Data@ 0 = 187 | UNTIL ; 188 | 189 | : GetByte ( - BYTE ) 190 | WaitStart 191 | 0 Parity ! 192 | 0 193 | 7 FOR 194 | 2/ Bit@ DUP Parity @ XOR Parity ! OR 195 | NEXT 196 | DUP DROP DUP DROP \ little delay 197 | Bit@ Parity @ XOR 0 = 198 | IF ." Parity Eror " THEN ; 199 | 200 | 201 | CREATE FIFO 80 ALLOT 202 | VARIABLE InFIFO 0 InFIFO ! 203 | VARIABLE OutFIFO 0 OutFIFO ! 204 | 205 | : FIFO! ( BYTE - ) 206 | InFIFO @ 1+ 207 | 7F AND DUP InFIFO ! 208 | FIFO + C! ; 209 | 210 | : GetKey ( - BYTE ) 211 | OutFIFO @ DUP InFIFO @ - 212 | IF \ IN FIFO 213 | DUP FIFO + C@ 214 | SWAP 1+ 7F AND OutFIFO ! 215 | ELSE \ NEED TO FETCH MORE 216 | DROP 217 | BEGIN 218 | GetByte 219 | Bit@ 0 = 220 | WHILE \ NOT STOP 221 | FIFO! 222 | REPEAT 223 | -Clk 224 | THEN ; 225 | 226 | : Bit! ( BYTE - BYTE/2 ) 227 | DUP 1 AND DUP \ DATA BIT BIT 228 | BEGIN Clk@ 0 = UNTIL 229 | IF +Data ELSE -Data THEN 230 | Parity @ XOR Parity ! 231 | 2/ 232 | BEGIN Clk@ UNTIL ; 233 | 234 | VARIABLE CNT 235 | 236 | : WaitIdle 237 | +Data +Clk 238 | BEGIN Clk@ 0 = Data@ 0 = OR 0 = UNTIL ; 239 | 240 | : Response ( - byte ) 241 | +Data 242 | GetByte 243 | Bit@ DROP ; 244 | 245 | : SendByte ( BYTE - ) 246 | WaitIdle 247 | 1 Parity ! 248 | +Clk BEGIN Clk@ UNTIL \ WAIT IDLE 249 | -Clk 40uS 40uS 40uS \ MAKE SURE KB KNOWS WE ARE IN CONTROL 250 | -Data 40uS \ START BIT 251 | +Clk 252 | BEGIN Clk@ UNTIL \ KB CLOCKS NOW 253 | 7 FOR 254 | Bit! 255 | NEXT DROP 256 | Parity @ Bit! DROP \ SEND PARITY 257 | 1 Bit! DROP ; 258 | 259 | : Command ( Cmd - ) 260 | SendByte 261 | Response 262 | FA - IF ." Cmd Fails " THEN ; 263 | 264 | : Watch 265 | 0 CNT ! 266 | InB @ C0 AND 267 | BEGIN 268 | DUP InB @ C0 AND - 269 | IF InB @ C0 AND 1 CNT +! THEN 270 | ?KEY CNT @ 30 = OR 271 | UNTIL 272 | CNT @ FOR . CR NEXT ; 273 | 274 | : Led ( N - ) 275 | ED Command Command ; 276 | \ SendByte 277 | \ Watch ; 278 | 279 | VARIABLE Shift 280 | VARIABLE CapLk 281 | VARIABLE Cntrl 282 | 12 CONSTANT LShft 283 | 59 CONSTANT RShft 284 | 14 CONSTANT LCntrl 285 | 28 CONSTANT RCntrl ( ARBITRARY VALUE DIFFERENT THAN LCNTRL ) 286 | 58 CONSTANT CapKey 287 | 288 | 289 | : 2ASCII ( BYTE - ) \ SEND BYTE TO PORT AS ASCII 290 | Table + C@ ; 291 | 292 | \ KEYBOARD HANDLING CODE HERE 293 | : DoCntrl ( Char - Char ) 294 | DUP 60 7B WITHIN \ CAN BE CONTROL 295 | IF 1F AND THEN ; 296 | 297 | : DoCapLk ( CHAR - CHAR ) \ ONLY FOR LETTER 298 | DUP 61 7B WITHIN \ LOWER CASE LETTER 299 | IF 5F AND THEN ; 300 | 301 | : DoShift ( CHAR - CHAR ) 302 | CapLk @ 0 = IF DoCapLk THEN 303 | DUP 2C 40 WITHIN \ SPECIAL CASE 304 | IF 2C - ShfTable + C@ THEN 305 | DUP 5B 61 WITHIN 306 | IF 5B - ShftTable2 + C@ THEN 307 | DUP 27 = 308 | IF DROP 22 THEN ; 309 | 310 | : F0Key ( - ) \ MOSTLY KEY RELEASES SO MOST IGNORED 311 | GetKey >R 312 | R@ E0 = 313 | IF \ ONLY RCNTRL FOR NOW 314 | GetKey 315 | DUP LCntrl = 316 | IF RCntrl NOT RCntrl Cntrl MSK! THEN 317 | DROP 318 | ELSE \ not E0 319 | R@ LShft = R@ RShft = OR 320 | IF R@ NOT R@ Shift MSK! THEN 321 | R@ LCntrl = 322 | IF R@ NOT R@ Cntrl MSK! THEN 323 | R@ CapKey = 324 | IF CapLk @ CapKey XOR DUP CapLk ! 325 | IF 4 ELSE 0 THEN Led THEN 326 | THEN R> DROP ; 327 | 328 | : E0Key ( - ) \ ONLY RCntrl 329 | GetKey DUP F0 = 330 | IF 331 | DROP 332 | GetKey LCntrl = \ actually right Cntrl 333 | IF RCntrl NOT RCntrl Cntrl MSK! THEN 334 | ELSE 335 | LCntrl = 336 | IF RCntrl DUP Cntrl MSK! THEN 337 | THEN ; 338 | 339 | : C, HERE C! 1 ALLOT ; 340 | CREATE EasterEgg 341 | 31 C, 32 C, 33 C, 34 C, 54 C, 48 C, HERE ALIGNED CP ! 342 | VARIABLE Egg 343 | 344 | : Par! ( Char - ) \ Output to parallel port 345 | DUP Egg @ EasterEgg + C@ = 346 | IF Egg @ 5 = 347 | IF 0 Egg ! QUIT ELSE 1 Egg +! THEN 348 | ELSE 349 | 0 Egg ! 350 | THEN 351 | 8 LSHIFT 352 | Strobe @ 0 = StrobeMsk AND OR 353 | DUP ParMsk OutB MSK! 354 | 14 FOR 40uS NEXT 355 | StrobeMsk XOR 356 | ParMsk OutB MSK! ; 357 | 358 | : DoText ( key - ) 359 | 2ASCII 360 | Cntrl @ 361 | IF DoCntrl 362 | ELSE 363 | Shift @ 364 | IF 365 | DoShift 366 | ELSE 367 | CapLk @ IF DoCapLk THEN 368 | THEN 369 | THEN 370 | DUP . Par! ; 371 | 372 | : DoKey ( - ) 373 | GetKey >R 374 | R@ F0 = 375 | IF F0Key 376 | ELSE 377 | R@ E0 = 378 | IF E0Key 379 | ELSE 380 | R@ LCntrl = IF R@ DUP Cntrl MSK! 381 | ELSE 382 | R@ LShft = R@ RShft = R@ CapKey = OR OR 383 | IF R@ CapKey = NOT 384 | IF R@ DUP Shift MSK! THEN 385 | ELSE R@ DoText THEN THEN THEN 386 | THEN 387 | R> DROP ; 388 | 389 | : Run 390 | BEGIN DoKey AGAIN ; 391 | 392 | : T 5 5 BEGIN DoKey ?KEY UNTIL GetKey . GetKey . ; 393 | 394 | : CLEAR +Clk +Data ; 395 | 396 | : Init ( FOR AUTO BOOT INCLUDE KEY PROCESSING ) 397 | ( CHECK DESIRED STROBE ) 0 Strobe ! 398 | ( CHECK STROBE POLARITY ) 399 | Strobe @ -1 XOR StrobeMsk OutB MSK! 400 | -Clk SetPB +Data 401 | ParMsk OutB SET! 402 | 0 Shift ! 0 CapLk ! 0 Cntrl ! 403 | 0 InFIFO ! 0 OutFIFO ! 404 | 0 Egg ! 405 | ; 406 | 407 | Init 408 | 409 | : DEBUG 410 | GetKey . ; 411 | 412 | : Q DEBUG DEBUG DEBUG ; 413 | 414 | 415 | -------------------------------------------------------------------------------- /TALKF105.F: -------------------------------------------------------------------------------- 1 | \ Serial communicator with the STM32F1xx series parts. 2 | \ One can use Talk to run the interactive eForth on the STM32. 3 | \ One can return to Win32Forth with the esc key. 4 | \ Source files can be compiled with LoadF105 ( - | Filename ) 5 | \ One can upload the entire RAM into a HEX file with LogHex ( - | FileName ) 6 | \ and INTHEX ( Addr Count - ) is run on STM32 client. 7 | \ Default serial is 56K odd partity. 8 | \ There is no boot loader transferred. eForth is directly loaded. 9 | \ Code is here to write to Flash from a Hex file. Use STM32 documents 10 | \ to determine which Flash blocks need to be first erased. 11 | 12 | \ serial used for stm32f105 boot loader 13 | 14 | \ Written by Andrew McKewan in Visual C++ 15 | \ Translated to Forth by Tom Zimmer 16 | \ January 3nd, 1997 tjz 17 | \ Updated to include changes from Skip Inskeep, as well as 18 | \ other changes. 19 | \ February 10th, 1997 by Tom Zimmer 20 | \ Updated with a couple of additional changes from Skip Inskeep. 21 | 22 | \ A Win32Forth example program that illustrates how to open COM1 for 23 | \ bi-directional communications and then allows a simple terminal 24 | \ program to communicate with whatever is connected at 9600 baud. 25 | 26 | \ define the object for the Device Control Block structure 27 | 28 | decimal 29 | 30 | :Object DCB R 100 | NULL \ no template 101 | NULL \ open file attributes 102 | OPEN_EXISTING \ creation distribution 103 | NULL \ no security attributes 104 | 0 \ exclusive access 105 | GENERIC_READ GENERIC_WRITE or \ desired access modes 106 | R> \ zstring filename 107 | Call CreateFile \ returns handle or -1 108 | dup -1 = \ if -1 then error 109 | Abort" Failed to open COM port!" 110 | ; \ -- chndl ;return handle to port 111 | 112 | \ ************************************************************ 113 | \ here is a list of valid parameters for ComSetup. Except for 114 | \ the ByteSize parameter, these are all windows constants. 115 | 116 | \ --- BuadRate CBR_110 CBR_300 CBR_600 117 | \ CBR_1200 CBR_2400 CBR_4800 118 | \ CBR_9600 CBR_14400 CBR_56000 119 | \ CBR_19200 CBR_38400 CBR_57600 120 | \ CBR_115200 CBR_128000 CBR_256000 121 | \ 122 | \ --- ByteSize 5, 6, 7, 8 123 | \ 124 | \ --- Parity NOPARITY ODDPARITY MARKPARITY 125 | \ EVENPARITY SPACEPARITY 126 | \ 127 | \ --- StopBits ONESTOPBIT TWOSTOPBITS ONE5STOPBITS 128 | \ 129 | \ ************************************************************ 130 | 131 | \ Setup the Communications state to the parameters specified 132 | 133 | : ComSetup { baud size parity stop cHndl -- } 134 | DCB.AddrOf 135 | cHndl 136 | Call GetCommState ?win-error 137 | 138 | baud Put: DCB.BaudRate 139 | size Put: DCB.ByteSize 140 | parity 0<> Put: DCB.fParity \ parity enabled flag 141 | parity Put: DCB.Parity 142 | stop Put: DCB.StopBits 143 | 144 | DCB.AddrOf 145 | cHndl 146 | Call SetCommState ?win-error ; 147 | 148 | : ComClose ( cHndl -- ) \ close com port if its open 149 | ?dup 150 | if Call CloseHandle drop 151 | then ; 152 | 153 | :Object COMSTAT ; 184 | 185 | \ Example: Simple terminal program 186 | 187 | 0 value Com1Hndl 188 | variable Com1key-val \ a place to save last key received 189 | 0 value Com1key-flg? \ have we already got a key? 190 | 191 | : Com1key? ( -- c1 ) \ get a key from serial port, don't wait long 192 | Com1key-flg? 0= 193 | if Com1key-val 1 Com1Hndl read-file \ -- len flag 194 | abort" Failed to read serial port" \ -- len 195 | to Com1key-flg? 196 | then Com1key-flg? ; 197 | 198 | : Com1key ( -- c1 ) \ must return a key 199 | begin Com1key? \ loop till we get one 200 | until 201 | Com1key-val c@ \ return the key 202 | 0 to Com1key-flg? ; \ clear the save buffer 203 | 204 | : Com1emit { char -- } \ write a character to the serial port 205 | &OF char 1 Com1Hndl write-file 206 | abort" Failed to write serial port" ; 207 | 208 | 0 value ?ComInit 209 | 210 | : do-Com1key ( c1 -- f1 ) \ process keys pressed on user keyboard 211 | dup k_ESC = \ was ESC pressed? 212 | if drop \ if so, discard c1 and shut down 213 | Com1Hndl ComClose \ close the com port 214 | \ 0 to Com1Hndl \ clear handle value 215 | 0 to ?ComInit 216 | ." Done" TRUE \ return TRUE, we are terminating 217 | else Com1emit FALSE \ else emit char and continue 218 | then ; 219 | 220 | 221 | : InitCom 222 | ?ComInit 0= if 223 | z" COM3" ComOpen to com1Hndl 224 | Reset: DCB 225 | False Put: DCB.fOutxCtsFlow \ no CTS control 226 | \ CBR_9600 227 | CBR_56000 228 | \ CBR_57600 229 | \ CBR_115200 230 | \ CBR_38400 231 | \ CBR_2400 232 | 8 EVENPARITY twoSTOPBITs com1Hndl ComSetup 233 | Com1Hndl comTimeOuts 234 | then -1 to ?ComInit ; 235 | 236 | 237 | : Com1talk ( -- ) \ simple terminal talker to the serial port 238 | cr ." Initializing Serial Port to: " 239 | cr ." COM1: baud=56000 parity=E data=8 stop=1" 240 | \ z" COM3" ComOpen to com1Hndl 241 | \ Reset: DCB 242 | \ FALSE Put: DCB.fOutxCtsFlow \ Don't pay attention to CTS 243 | \ CBR_9600 8 noPARITY TWOSTOPBIT com1Hndl ComSetup 244 | \ 245 | \ CBR_56000 8 EVENPARITY ONESTOPBIT com1Hndl ComSetup 246 | \ com1Hndl ComTimeouts 247 | InitCom 248 | cr ." Press ESC to stop talking." cr 249 | BEGIN key? 250 | if key do-Com1key ?EXIT 251 | then 252 | Com1key? 253 | if Com1key 254 | dup ( $0D = over ) $0A = \ or 255 | if 256 | drop cr 257 | else 258 | dup 8 = 259 | if 260 | drop getxy swap 1- swap gotoxy 261 | else 262 | emit 263 | then 264 | then 265 | then 266 | AGAIN ; 267 | 268 | : talk com1talk ; 269 | 270 | \ ******************************************************* 271 | \ boot loader code for F105 272 | \ Following are the words to program the stm32f105 273 | \ It expects to read an Intel Hex file that it will load into 274 | \ the flash on chip. No loader code is needed if you load eForth. 275 | \ refer to STM32 documents for Flash block sizes 276 | 277 | $79 value Ack 278 | $1F value Nack 279 | $7F value StartByte 280 | 0 value xcs \ xor sum to send. 281 | 282 | : Oops ( restart com connection if error ) Com1Hndl ComClose 0 to ?ComInit ; 283 | 284 | 0 value quiet 285 | 286 | : safekey ( - key ) \ doesn't hang if no key response. 287 | begin 288 | key? 289 | if ." No Response" 290 | quit 291 | else 292 | Com1Key? 293 | if Com1Key -1 else 0 then 294 | then 295 | until ; 296 | 297 | : Ack? ( - ) \ look for Ack or Nack 298 | safekey \ Com1Key 299 | dup Ack = 300 | if drop ." Ack" cr 301 | else dup Nack = 302 | if drop ." Nack" cr 303 | else ." ??" h. quit 304 | then 305 | then ; 306 | 307 | \ F105 is a STM32F105 308 | 309 | : cs+ ( byte - ) ( $FF xor ) xcs xor to xcs ; 310 | 311 | : StartF105 ( - ) \ tie boot pins and reset then do this 312 | \ checks to see if boot is listening 313 | InitCom 314 | 0 to xcs 315 | $7F Com1Emit 316 | begin 317 | key? if ." No Response" Oops -1 else 318 | Com1Key? 319 | if Ack? -1 else 0 then then 320 | until ; 321 | 322 | : ss startf105 ; 323 | 324 | : F105! ( Byte - ) \ low level word 325 | dup Com1Emit cs+ ; 326 | 327 | : F105CS! ( - ) \ Sends accumulated Check Sum low level 328 | xcs ( $ff xor ) Com1Emit 329 | Ack? 330 | 0 to xcs ; \ clears xcs for next 331 | 332 | 333 | : F105 ( Command - ) \ Send a command to F105 low level 334 | dup 335 | Com1Emit 336 | $0FF xor Com1Emit 337 | 0 to xcs 338 | Ack? ; \ Expects Ack for every CS ( CheckSum ) 339 | 340 | : GetF105 ( - ) \ report commands checks version see STM docs 341 | $00 F105 342 | SafeKey 1+ 0 do \ BootLoader Version plus command bytes 343 | SafeKey h. cr 344 | loop 345 | Ack? ; 346 | 347 | : UnProtRd ( - ) \ Allows reading 348 | $92 F105 349 | startf105 ; 350 | 351 | : ProtRd ( - ) \ blocks reading 352 | $82 F105 353 | startf105 ; 354 | 355 | 356 | create Buf $10005 allot \ up to 64K 357 | 358 | $8000000 value Flash 359 | 360 | : Addr ( addr - ) \ Send Address of 4 bytes low level 361 | 0 to xcs 362 | dup $18 rshift F105! \ MSB first 363 | dup $10 rshift $0FF and F105! 364 | dup $08 rshift $0FF and F105! 365 | $0FF and F105! \ LSB last 366 | F105cs! ; 367 | 368 | : (RdMem) ( Addr Count - ) \ Reads Flash into Buf 369 | $11 F105 370 | swap Addr 371 | dup 1 - F105 \ F105! F105CS! 372 | 0 do 373 | SafeKey i Buf + c! 374 | loop ; 375 | 376 | : .RdMem ( Addr Count - ) \ displays Flash 377 | dup >r 378 | (RdMem) 379 | r> 0 do i buf + c@ h. loop ; 380 | 381 | : .Inst ( Addr - ) \ Displays the 32 bit value in listing order 382 | 4 (RdMem) Buf 3 + c@ $1000000 * 383 | Buf 2 + c@ $10000 * 384 | Buf 1 + c@ $100 * 385 | Buf c@ + + + 386 | base @ >r hex u. r> base ! ; 387 | 388 | 389 | : GV ( - ) 390 | 1 F105 391 | 3 0 do 392 | SafeKey h. 393 | loop 394 | Ack? ; 395 | 396 | : xxx dup dup 397 | 4 mod dup if 4 swap - then + 398 | dup 1- . 399 | over . swap - . ; 400 | 401 | : WM ( WrAddr ByteCount - ) \ gets data from Buf 402 | \ careful count must be less than or equal to 255 403 | \ I intend to do blocks of 16 so OK 404 | \ Note: don't used for options. 405 | $31 F105 \ Write command 406 | swap Addr \ send the address 407 | dup \ actual bytes to write 408 | dup 4 mod dup if 4 swap - then + \ N+1 must be multiples of 4 409 | dup 1- F105! \ N to F105 410 | over 0 do \ real desired number of bytes 411 | i Buf + c@ F105! \ actual values desired 412 | loop 413 | swap - 0 414 | ?do 415 | $0FF F105! \ Pad with unprogrammed value 416 | loop \ could be as many as 4 but always at least 1 417 | F105CS! ; 418 | 419 | 420 | : EM ( 1rstPage#...LastPage# #Pages --- ) 421 | \ erase memory 2K pages ( 800H each ) 422 | $43 F105 \ Write command 423 | dup 1- F105! 424 | 0 ?do 425 | F105! 426 | loop 427 | F105cs! ; 428 | 429 | : UnProtWr ( - ) 430 | $73 F105 431 | startf105 ; \ Write command 432 | 433 | 434 | 0 value HexFile 435 | create FBuf $200 allot \ Big enough for Intel hex line. 436 | \ Hex file 17 bytes for first line to say 32 bit values 437 | \ 16 bytes will be 45 bytes of hex 438 | \ 1&2 bytes on line 439 | \ 3,4,5&6 address 440 | \ 7&8 byte type ( should be 0 ) 441 | \ data at 2d hex 442 | \ data starts at 9 443 | \ bytes on line 2* then checksum 0d 0a 444 | hex 445 | 446 | : OpenHex ( - | FileName ) 447 | s" eforth.hex" r/o open-file abort" Can find file" 448 | to HexFile ; 449 | 450 | : ConvHex ( Addr - Byte ) 451 | dup 1+ 452 | 2 0 do 453 | c@ dup $30 $3A within 454 | if $30 - 455 | else dup $41 $47 within 456 | if $37 - 457 | else ." Not number" quit 458 | then 459 | then 460 | swap 461 | loop swap $10 * + ; 462 | 463 | : GetCount ( - cnt ) \ reads counts from hex string at fbuf 464 | FBuf 1+ ConvHex ; 465 | 466 | 0 value Cnt 467 | 0 value rd2 468 | 469 | : ReadLine ( --- ) 470 | begin 471 | FBuf 1 HexFile read-file abort" can't read file1" drop 472 | FBuf c@ $3A = 473 | until 474 | FBuf 1+ 2 HexFile read-file abort" can't read file2" drop 475 | GetCount to cnt 476 | FBuf 3 + cnt 2* $0A + dup to rd2 HexFile read-file 477 | abort" can't read file3" drop 478 | ; 479 | 480 | : closeHex HexFile close-file drop ; 481 | 482 | : GetType ( - Type ) 483 | FBuf $7 + ConvHex ; 484 | 485 | : GetDestAddr ( - Addr ) \ Gets the destination address from hex string in FBuf 486 | FBuf 3 + 487 | 0 \ acumulator 488 | 2 0 do \ 4 bytes as address 489 | $100 * over ConvHex + 490 | swap 2 + swap 491 | loop swap drop ; 492 | 493 | : F>Buf ( Cnt - ) 494 | FBuf $9 + swap 495 | 0 do 496 | dup ConvHex i Buf + c! 497 | 2 + 498 | loop drop ; 499 | 500 | : download ( - ) 501 | hex 502 | OpenHex 503 | ReadLine \ flush first line set high address so ignore 504 | -1 to quiet 505 | $8000000 506 | begin 507 | dup $0FF and 0= if dup h. cr then 508 | ReadLine 509 | GetType 0= 510 | while 511 | cnt F>Buf dup 512 | Cnt WM 513 | \ Cnt 0 do i buf + c@ . loop cr drop 514 | Cnt + 515 | repeat h. 516 | 0 to quiet 517 | CloseHex ; 518 | 519 | : Verifyload ( - ) 520 | OpenHex 521 | ReadLine \ flush first line 522 | -1 to quiet 523 | $8000000 524 | begin 525 | dup $0FF and 0= if dup h. cr then 526 | ReadLine 527 | GetType 0= 528 | while 529 | cnt F>Buf buf dup cnt + cnt cmove 530 | dup 531 | cnt (rdmem) 532 | cnt 0 do i buf + dup cnt + 533 | c@ swap c@ - if ." error" h. quit then 534 | loop 535 | cnt + 536 | repeat h. 537 | 0 to quiet 538 | CloseHex ; 539 | 540 | 541 | create BBuf $4000 allot \ space for a binary 542 | 543 | 0 value BAddr 544 | 545 | : GetBinData 546 | OpenHex 547 | ReadLine \ ignore first line 548 | begin 549 | ReadLine GetType 0= 550 | while 551 | GetDestAddr to BAddr 552 | GetCount 0 \ two chars per byte 553 | ?do 554 | i 2* 9 + FBuf + ConvHex \ get a byte, two hex chars 555 | BAddr i + BBuf + c! 556 | loop 557 | repeat 558 | CloseHex ; 559 | 560 | : I@ ( Addr - ) 561 | base @ swap hex 562 | 3 + BBuf + dup c@ $1000000 * swap 563 | 1- dup c@ $10000 * swap 564 | 1- dup c@ $100 * swap 565 | 1- c@ + + + u. 566 | base ! ; 567 | 568 | 569 | 570 | \ reset board 571 | \ startf105 572 | \ unprotwr 573 | \ reset board 574 | \ 0 1 2 3 4 5 6 7 8 9 em erase flash 575 | \ unprotrd 576 | \ reset board 577 | \ .rdmem 578 | \ unprotwr 579 | \ 580 | 581 | 582 | 583 | \ ******************************************* 584 | \ cross loader to F105 Forth 585 | \ file words for loading to the F105 586 | \ LoadF105 is used to send a eForth source file to chips like 587 | \ STM32F105 and STM32F103, that have eForth on them. 588 | \ for blue pill 589 | \ black ground 590 | \ white +5v 591 | \ yellow A10 592 | \ green A9 593 | 0 value F105.4th \ handle for file 594 | \ I'll reuse FBuf as I've expansed it to 512 bytes 595 | 0 value FBufZ ( how much is in the buffer ) 596 | FBuf value FBufPntr 597 | FBuf value FbufEnd 598 | 599 | : OpenF105 ( - | fileName ) 600 | \ open a source file to load into the F105 601 | bl word count 602 | r/o open-file abort" Can find file" 603 | to F105.4th 604 | 0 to FBufZ 605 | FBuf to FBufPntr ; 606 | 607 | : CloseF105 608 | 0 to FbufZ 609 | F105.4th close-file drop 610 | Com1Hndl ComClose \ close the com port 611 | 0 to ?ComInit ; 612 | 613 | : RD2Buf ( - ) \ Reads up to 512 bytes into buffer 614 | FBuf $200 F105.4th read-file 615 | dup if Closef105 then 616 | abort" Can't Read File " 617 | to FBufZ 618 | FBuf to FBufPntr 619 | FBufZ Fbuf + TO FbufEnd ; 620 | 621 | : FByte ( - Char ) \ fetches a byte from the file 622 | \ Quits when file complete 623 | FBufZ 0= 624 | FbufEnd FbufPntr = or 625 | if \ either there is nothing in the file or we need to load again 626 | Rd2Buf 627 | FBufZ 0= 628 | if \ end of file 629 | CloseF105 TALK quit 630 | then 631 | then 632 | FBufPntr c@ 633 | 1 +TO FBufPntr ; 634 | 635 | : Delay ( - ) \ Don't know if I'll need delay yet 636 | ; 637 | 638 | 0 value LastByte 639 | 640 | : Echo? ( - Char ) \ Echo from board 641 | Begin 642 | Com1Key? 643 | Key? if CloseF105 quit then \ don't get stuck 644 | until 645 | Com1Key ; 646 | 647 | CREATE LineBuf $100 allot 648 | 0 value LineCnt 649 | 650 | : \\ ( Char - Char' ) 651 | \ looks to see if Char is a \. If so, it dump the rest of the line 652 | \ to the $0D Char and then pick up sending so we don't wait time 653 | \ with long comments that the F105Forth just ignores 654 | dup $5C = 655 | if \ was a \ so move to the end of line 656 | begin 657 | drop 658 | Fbyte dup $0D 659 | until 660 | then 661 | ; 662 | 663 | : LoadF105 ( - | FileName ) 664 | 0 to LineCnt 665 | InitCom 666 | OpenF105 \ Source file to F105 667 | begin 668 | FByte 669 | \ \\ \ ignore these comments to end of line 670 | dup Com1Emit \ send bytes out to board 671 | \ dup to LastByte \ for debug, don't need 672 | $0D = 673 | if 674 | FByte $0A - if ." CrLf mismatch" quit then 675 | begin 676 | Echo? dup $0A - \ Wait for $0D to handle cr to terminal 677 | while 678 | LineBuf LineCnt + c! 679 | 1 +to LineCnt 680 | \ emit \ might be 'ok' or warning or error so just echo 681 | Delay \ may need a delay here 682 | repeat drop 683 | LineCnt 0 ?do LineBuf I + c@ emit loop 684 | 0 to lineCnt 685 | cr 686 | else 687 | Echo? LineBuf LineCnt + c! \ normal Char handling 688 | 1 +to LineCnt 689 | then 690 | again ; 691 | 692 | : XEmit 693 | dup $0A = if drop cr else emit then ; 694 | 695 | \ ************************************************************* 696 | \ logging an intel hex file sent from outside chip, like stm32f105 697 | \ Use INTHEX ( Addr Count - ) to send out HEX. It uses handshake. 698 | 0 value Pntr 699 | \ 0 value LineCnt 700 | 0 VALUE TEST 701 | LINEBUF $100 + TO TEST 702 | 703 | HEX 704 | : WW 10000 0 DO 4 5 / DROP LOOP ; 705 | : WWW 100 0 DO WW LOOP ; 706 | 707 | 708 | : LogHex ( - | FileName ) 709 | bl word count \ hex file 710 | r/w create-file abort" Can create file" 711 | to HexFile 712 | InitCom 713 | 0 to LineCnt 714 | begin \ Entire file 715 | LineBuf to Pntr \ To store a line 716 | BEGIN 717 | WWW \ SEEM TO NEED SOME DELAY????????? 718 | $20 COM1EMIT \ $20 COM1EMIT 719 | COM1KEY? 720 | UNTIL 721 | begin \ ignore anything but a : as beginning of hex line 722 | Com1Key ascii : = 723 | until 724 | ascii : Pntr c! \ same to file 725 | begin \ hex line 726 | 1 +to Pntr 727 | PNTR TEST > IF ." TOO LONG " ABORT THEN 728 | Com1Key dup Pntr c! 729 | $0A = \ wait for end of line 730 | until \ .S CR 731 | LineBuf Pntr over - 1 + 2dup ( addr size ) 732 | TYPE \ good to watch the prgress 733 | HexFile write-file abort" Can't Write" \ write line to file 734 | LineBuf 1+ dup c@ $30 = swap 1+ c@ $30 = and \ 0 length hex line is last line 735 | until 736 | CloseHex 737 | $1B do-Com1key drop ; \ All Done 738 | 739 | 740 | 741 | \S 742 | 743 | : NL ( - | FileName ) \ not working yet 744 | 0 to LineCnt 745 | InitCom 746 | OpenF105 \ Source file to F105 747 | begin 748 | begin 749 | FByte dup LineBuf LineCnt + c! 750 | dup XEmit 751 | LineCnt 1+ $0FF min to LineCnt 752 | $0A = 753 | until 754 | LineCnt to LastByte 755 | -2 +to LineCnt 756 | LineBuf LineCnt Com1Hndl write-file 757 | abort" Failed to write serial port" 758 | begin 759 | Com1Key? 760 | if 761 | Com1Key dup 762 | $0A - 763 | if 764 | cr 765 | then 766 | else 0 767 | then 768 | $0A - 769 | while 770 | LineCnt LastByte - 771 | if 772 | 1 +to LineCnt 773 | LineBuf LineCnt Com1Emit 774 | then 775 | repeat 776 | 777 | 778 | 779 | 780 | 781 | $0D ComEmit 782 | Begin 783 | 784 | while 785 | com1key? 786 | if com1key XEmit drop ms@ then 787 | repeat drop 788 | again ; 789 | 790 | \S 791 | need to speed things up. Not sure what is taking so much time. 792 | need to handle reDef needs to pause and ask to continue? 793 | a name with ? is most likely an error. ask to continue 794 | 795 | 796 | 52 F8 4 FB 797 | : ++ 14 0 do + loop . ; 798 | 10 22 B0 00 04 43 4F 4C 44 00 00 00 45 F6 00 73 C2 F2 00 03 93 ++ 799 | 10 22 B0 00 04 43 4F 4C 44 00 00 00 4F F6 00 73 C2 F2 00 03 89 ++ 800 | 801 | 168 reduce the size transferred was 8000 to 4000 for now ** 802 | 178 not sure it math right here? 5000 is end of RAM for F103 803 | equates data stack 2000FE00 should be 20004E00 for F103 804 | TIB was 2000FE00 should be 20004E00 805 | RP0 was 2000FF00 should be 20004F00 806 | UP0 was 2000FF00 should be 20004F00 807 | HERE was 2000FC00 ?? should be end of dictionary 808 | 1D0 was 2000FE00 should be 20004E00 809 | check values at 1D4 t0 1F4 810 | check USART1 map for F103? 811 | 812 | 813 | 10 01 D0 00 00 4E 00 20 51 17 00 20 00 00 00 00 00 23 00 20 E6 ++ 814 | 815 | create buf1 $2400 allot 816 | create buf2 $2400 allot 817 | 818 | : upload ( NewBuf - ) 819 | >r $8000000 820 | begin 821 | dup $10 (rdmem) 822 | Buf over $8000000 - r@ + $10 cmove 823 | $10 + dup $8002300 = 824 | until r> 2drop ; 825 | 826 | : CompBufs 827 | $2300 0 do 828 | I Buf1 + c@ 829 | I Buf2 + c@ - 830 | if 831 | I . I Buf1 + c@ . I Buf2 + c@ . key $1B = if quit then 832 | then 833 | loop ; 834 | 835 | 836 | : CALLC ( TARGET HERE - INSTR ) 837 | - 4 - DUP 838 | 0C RSHIFT 7FF AND 839 | SWAP 0F LSHIFT OR 840 | F800F000 OR ; 841 | 842 | 843 | : UNCALL ( ADDR - ADDR' ) 844 | DUP @ F800F800 AND 845 | F800F000 = 846 | IF 847 | DUP . ." < " 848 | DUP @ 849 | DUP 15 LSHIFT 850 | 9 RSHIFT 851 | SWAP 852 | 0F RSHIFT FFE AND OR 853 | OVER + 4 + . 854 | ELSE 855 | DUP . DUP ? 856 | THEN 4 + ; 857 | 858 | 859 | -------------------------------------------------------------------------------- /EFORTH.HEX: -------------------------------------------------------------------------------- 1 | :020000040800F2 2 | :100000000000000051010008FFFFFFFFFFFFFFFF9E 3 | :10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 4 | :10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 5 | :10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 6 | :10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 7 | :10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 8 | :10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 9 | :10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 10 | :10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 11 | :10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 12 | :1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 13 | :1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 14 | :1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 15 | :1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 16 | :1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 17 | :1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 18 | :10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 19 | :10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF 20 | :10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF 21 | :10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF 22 | :10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF 23 | :1001500000F014F801F0AEFB00F002F8114800477F 24 | :100160004FF000604FF0005101F5A04291423CBFBA 25 | :1001700050F8043B41F8043BF8D370470A488169C2 26 | :1001800044F21C0741EA070181610848416841F4D3 27 | :1001900094614160064843F20C41818140F28F0135 28 | :1001A00001817047B9220020001002400008014080 29 | :1001B00000380140000000004D2200201000000027 30 | :1001C000000000000000000000000000000000002F 31 | :1001D000004E00205117002000000000B022002037 32 | :1001E0000023002000230020B02200200000000097 33 | :1001F0000000000000000000043F4B4559000000D3 34 | :1002000041F8045D0F4C268816F0200606D02579AB 35 | :1002100041F8045D18BF6FF0000570474FF000050E 36 | :1002200070470000F801002004454D4954000000CB 37 | :10023000044C268816F08006FBD0A58051F8045B9C 38 | :10024000704700000038014028020020034E4F5044 39 | :100250007047000041F8045D2EF0010E5EF8045B6B 40 | :100260004EF0010E704700004C0200200745584533 41 | :100270004355544545F0010451F8045B2047000004 42 | :100280001468240004D102F104020EF1040E704738 43 | :10029000A4F1010414605EF801EC4EF0010E704709 44 | :1002A0002C0051F8045B04D15EF801EC4EF0010E15 45 | :1002B00070470EF1040E70475EF801EC4EF0010E2F 46 | :1002C000704700006C0200200445584954000000AB 47 | :1002D00052F804FBC80200200121000051F8044B31 48 | :1002E0002C6051F8045B7047D802002001400000E8 49 | :1002F0002D687047EC0200200243210051F8044BA6 50 | :100300002C7051F8045B7047F8020020024821006D 51 | :1003100051F8044B2C8051F8045B70470C0300200B 52 | :10032000024840002D8870472003002004434C52AF 53 | :100330002100000005F11405FFF7D0BF2C030020B9 54 | :10034000045345542100000005F11005FFF7C6BF16 55 | :10035000400300200350412B154C254470470000FA 56 | :10036000540300200350422B124C254470470000D8 57 | :10037000640300200350432B0F4C254470470000BA 58 | :1003800074030020044D534B2100000051F8046B0E 59 | :1003900051F8047B06EA07072C686FEA060606EAAE 60 | :1003A000040444EA07042C6051F8045B7047000021 61 | :1003B00000080140000C01400010014084030020AF 62 | :1003C000024340002D787047C003002002523E00D7 63 | :1003D00041F8045D52F8045B70470000CC03002034 64 | :1003E0000252400041F8045D15687047E0030020A8 65 | :1003F000423E520042F8045D51F8045B7047000031 66 | :10040000F00300200353504041F8045D0D4670474F 67 | :10041000040400200444524F5000000051F8045BD3 68 | :1004200070470000140400200344555041F8045D57 69 | :10043000704700002804002004535741500000007A 70 | :100440000C680D602546704738040020044F56455F 71 | :100450005200000041F8045D4D6870474C040020D4 72 | :1004600002303C004FF0000404EB2505704700000B 73 | :100470006004002003414E4451F8044B05EA040592 74 | :100480007047000074040020024F520051F8044BE2 75 | :1004900045EA0405704700008804002003584F52C5 76 | :1004A00051F8044B85EA0405704700009C040020C5 77 | :1004B00003554D2B0C6864194FF0000545F10005FC 78 | :1004C0000C607047B004002006525348494654005F 79 | :1004D00051F8044B44FA05F570470000C8040020A9 80 | :1004E000064C53484946540051F8044B04FA05F5AC 81 | :1004F00070470000E0040020012B000051F8044B7D 82 | :1005000025447047F8040020012D000051F8044BE9 83 | :10051000C5EB04057047000008050020012A000013 84 | :1005200051F8044B04FB05F5704700001C05002042 85 | :1005300003554D2A0C68A5FB04670E603D467047C5 86 | :1005400030050020024D2A000C6885FB04670E6010 87 | :100550003D4670474405002002312B0005F101059E 88 | :10056000704700005805002002312D00A5F101055B 89 | :10057000704700006805002002322B0005F10205DB 90 | :10058000704700007805002002322D00A5F1020519 91 | :1005900070470000880500200543454C4C2B0000A7 92 | :1005A00005F1040570470000980500200543454CFF 93 | :1005B0004C2D0000A5F1040570470000AC0500209B 94 | :1005C00002424C0041F8045D4FF0200570470000E6 95 | :1005D000C00500200543454C4C5300004FEA8505FB 96 | :1005E00070470000D40500200543454C4C2F000007 97 | :1005F0004FEAA50570470000E805002002322A00F6 98 | :100600004FEA450570470000FC05002002322F002C 99 | :100610004FEA6505704700000C060020043F445572 100 | :10062000500000002C0018BF41F8045D7047000026 101 | :100630001C06002003524F540C680D604D684C603E 102 | :100640007047000034060020053244524F5000002D 103 | :1006500051F8045B51F8045B704700004806002025 104 | :1006600004324455500000000C6841F8045D41F824 105 | :10067000044D70476006002002442B0051F8044BE3 106 | :1006800051F8046B0F68E4190C6045EB06057047E0 107 | :1006900078060020034E4F546FEA050570470000AE 108 | :1006A00094060020064E454741544500C5F100051B 109 | :1006B00070470000A40600200341425315F0004F8C 110 | :1006C00018BF6D4270470000B8060020013D0000D1 111 | :1006D00051F8044BA5420CBF6FF000050025704790 112 | :1006E000CC06002002553C0051F8044BAC4234BF0C 113 | :1006F0006FF0000500257047E4060020013C000073 114 | :1007000051F8044BAC42B4BF6FF0000500257047B0 115 | :10071000FC060020013E000051F8044BAC42CCBF67 116 | :100720006FF000050025704714070020034D415865 117 | :1007300051F8044BAC42C8BF254670472C07002037 118 | :10074000034D494E51F8044BAC42B8BF25467047A3 119 | :1007500040070020022B210051F8044B2E6826444C 120 | :100760002E6051F8045B70475407002002322100CC 121 | :1007700051F8044B51F8046B45F8044B2E6051F8C6 122 | :10078000045B70476C070020023240006C6841F83F 123 | :10079000044D2D68704700008807002005434F5521 124 | :1007A0004E54000015F8014B41F8045D2546704792 125 | :1007B0009C07002007444E45474154450C68A8EB70 126 | :1007C0000808341B66EB05050C60704741F8045DB2 127 | :1007D000AEF1010552F804FB41F8045D5EF8015CDE 128 | :1007E00052F804FBB40700200527424F4F54000085 129 | :1007F00041F8045D03F1040570470000E80700209C 130 | :10080000044241534500000041F8045D03F108052E 131 | :100810007047000041F8045D03F10C0570470000CB 132 | :1008200000080020045350414E00000041F8045DD0 133 | :1008300003F110057047000024080020033E494ED4 134 | :1008400041F8045D03F11405704700003C080020E6 135 | :10085000042354494200000041F8045D03F11805E7 136 | :10086000704700005008002005274556414C000005 137 | :1008700041F8045D03F1200570470000680800207E 138 | :1008800003484C4441F8045D03F12405704700001F 139 | :100890008008002007434F4E5445585441F8045DEA 140 | :1008A00003F128057047000094080020024350001F 141 | :1008B00041F8045D03F12C0570470000AC080020EE 142 | :1008C000044C41535400000041F8045D03F1340529 143 | :1008D00070470000C00800200657495448494E00A0 144 | :1008E00042F804EDFFF7B6FDFFF710FEFFF782FDBB 145 | :1008F000FFF70CFEFFF76CFDFFF7F6FE52F804FB66 146 | :10090000D808002006554D2F4D4F44004FF00107E9 147 | :1009100051F8044B0E68B619644104D3A4EB0504E6 148 | :1009200006F1010604E0641B28BF761C00D22C44AB 149 | :10093000FF19F0D335460C60704700000409002011 150 | :10094000054D2F4D4F44000042F804EDFFF76EFDBA 151 | :10095000FFF788FDFFF76AFDFFF74CFDFFF7A0FCEE 152 | :1009600075090020FFF7A2FEFFF744FDFFF726FF01 153 | :10097000FFF72EFDFFF73EFDFFF758FDFFF772FD75 154 | :10098000FFF78EFC91090020FFF72CFDFFF7B6FD65 155 | :10099000FFF71EFDFFF7BAFFFFF71AFDFFF780FC18 156 | :1009A000B1090020FFF74CFDFFF780FEFFF748FD7F 157 | :1009B00052F804FB40090020042F4D4F4400000072 158 | :1009C00042F804EDFFF746FDFFF74CFDFFF738FD59 159 | :1009D000FFF7BAFF52F804FBB8090020034D4F445B 160 | :1009E00042F804EDFFF7ECFFFFF718FD52F804FBA7 161 | :1009F000DC090020012F000042F804EDFFF7E0FFC2 162 | :100A0000FFF71EFDFFF70AFD52F804FBF409002072 163 | :100A1000052A2F4D4F44000042F804EDFFF7EAFC91 164 | :100A2000FFF792FDFFF7D4FCFFF78EFF52F804FBAF 165 | :100A3000100A0020022A2F0042F804EDFFF7ECFF15 166 | :100A4000FFF7FEFCFFF7EAFC52F804FB340A002033 167 | :100A500007414C49474E45442400240005F1030555 168 | :100A60006FF0030405EA040570470000500A0020F7 169 | :100A7000053E43484152000042F804EDFFF7EAFB0F 170 | :100A80007F000000FFF7F8FCFFF7D0FCFFF79AFDAE 171 | :100A9000FFF7E0FB7F000000FFF722FFFFF7FCFD00 172 | :100AA000FFF7FEFBB50A0020FFF7B8FCFFF7D2FB0B 173 | :100AB0005F00000052F804FB700A00200544455016 174 | :100AC0005448000041F8045D44F60065C2F2000598 175 | :100AD000A5EB01054FEAA505A5F10105704700004A 176 | :100AE000BC0A0020045049434B00000042F804EDCA 177 | :100AF000FFF734FDFFF772FDFFF786FCFFF7FEFC02 178 | :100B0000FFF7F6FB52F804FBE40A002004484552C4 179 | :100B10004500000042F804EDFFF7CAFEFFF7E8FBCE 180 | :100B200052F804FB0C0B00200350414442F804ED42 181 | :100B3000FFF7F0FF05F1500552F804FB280B0020E9 182 | :100B40000354494241F8045DDD697047400B0020C1 183 | :100B50000840455845435554450000002C0051F8C5 184 | :100B6000045B246844F0010418BF2047704700006C 185 | :100B7000500B002005434D4F5645000051F8046BC3 186 | :100B800051F8047B03E017F8014B06F8014B2D00E8 187 | :100B900002D0A5F10105F6E751F8045B70470000AB 188 | :100BA000740B0020044D4F564500000025F003054E 189 | :100BB00051F8046B51F8047B03E057F8044B46F8F6 190 | :100BC000044B2D0002D0A5F10405F6E751F8045BB3 191 | :100BD00070470000A40B00200446494C4C00000064 192 | :100BE00051F8046B51F8047B00E02D4607F8015BD7 193 | :100BF000360002D0A6F10106F6E751F8045B704713 194 | :100C0000D80B0020055041434B24000042F804ED6E 195 | :100C1000FFF724FFFFF70AFCFFF7ECFBFFF71AFCD6 196 | :100C2000FFF76CFCFFF79AFCFFF714FBFCFFFFFFDC 197 | :100C3000FFF722FCFFF70EFB00000000FFF700FCAF 198 | :100C4000FFF74CFBFFF7CEFBFFF70EFDFFF756FB60 199 | :100C5000FFF784FCFFF7F4FBFFF790FFFFF7B8FB0B 200 | :100C600052F804FB040C0020054449474954000095 201 | :100C700042F804EDFFF7EEFA09000000FFF7EAFB87 202 | :100C8000FFF73EFD05F00705FFF738FC05F13005DD 203 | :100C900052F804FB680C0020074558545241435455 204 | :100CA00042F804EDFFF7D6FA00000000FFF7C8FB9A 205 | :100CB000FFF72CFEFFF7C4FBFFF7DAFF52F804FB47 206 | :100CC000980C0020023C230042F804EDFFF72EFFB1 207 | :100CD000FFF7D8FDFFF702FB52F804FBC40C00201D 208 | :100CE00004484F4C4400000042F804EDFFF7CAFDF1 209 | :100CF000FFF7FEFAFFF73AFCFFF798FBFFF7C2FD9C 210 | :100D0000FFF7ECFAFFF7FAFA52F804FBE00C0020C8 211 | :100D10000123000042F804EDFFF776FDFFF7E8FA43 212 | :100D2000FFF7BEFFFFF7E0FF52F804FB100D0020B5 213 | :100D30000223530042F804EDFFF7ECFFFFF776FBC8 214 | :100D4000FFF7AEFA4B0D0020F6E752F804FB000067 215 | :100D5000300D0020045349474E00000042F804EDD6 216 | :100D6000FFF780FBFFF79CFA790D0020FFF772FA7E 217 | :100D70002D000000FFF7B8FF52F804FB540D0020CF 218 | :100D800002233E0042F804EDFFF748FBFFF77AFD2F 219 | :100D9000FFF7AEFAFFF7CAFEFFF75CFBFFF7B6FB03 220 | :100DA00052F804FB42F804EDFFF740FBFFF722FB8B 221 | :100DB000FFF784FCFFF788FFFFF7BCFFFFF708FB96 222 | :100DC000FFF7CCFFFFF7DEFF52F804FB800D002099 223 | :100DD0000348455842F804EDFFF73CFA10000000C4 224 | :100DE000FFF712FDFFF77AFA52F804FBD00D00204E 225 | :100DF00007444543494D414C42F804EDFFF72AFAB8 226 | :100E00000A000000FFF700FDFFF768FA52F804FB44 227 | :100E1000F00D00200644494749543F0042F804EDD4 228 | :100E2000FFF7E8FAFFF716FA30000000FFF76EFB55 229 | :100E3000FFF710FA09000000FFF70CFBFFF760FC5A 230 | :100E4000FFF72EFA690E0020FFF704FA07000000F2 231 | :100E5000FFF75CFBFFF7EAFAFFF7FCF90A00000076 232 | :100E6000FFF74EFCFFF712FBFFF7E0FAFFF7B0FACF 233 | :100E7000FFF73AFC52F804FB140E0020074E554DC4 234 | :100E80004245523F42F804EDFFF7BEFCFFF730FA4F 235 | :100E9000FFF7B0FAFFF7DEF900000000FFF7DAFA1B 236 | :100EA000FFF780FCFFF7D6FAFFF78CFAFFF7D2F9CD 237 | :100EB0005F000000FFF70CFCFFF7F2F9D50E0020F1 238 | :100EC000FFF788FFFFF7BCFAFFF748FBFFF7B8FA18 239 | :100ED000FFF74CFBFFF7BEFAFFF774FAFFF7BAF91A 240 | :100EE0002D000000FFF7F4FBFFF784FAFFF7A8FAE4 241 | :100EF000FFF778FAFFF70AFBFFF7A2FAFFF772FA9B 242 | :100F0000FFF7FCFAFFF78EFBFFF7CAF9990F0020F5 243 | :100F1000FFF72CFBFFF76EFAFFF788FAFFF76AFA84 244 | :100F2000FFF750FAFFF770FCFFF7E2F9FFF776FFE3 245 | :100F3000FFF7B6F97D0F0020FFF782FAFFF764FC98 246 | :100F4000FFF7D6F9FFF7ECFAFFF7D8FAFFF740FA08 247 | :100F5000FFF704FBFFF794F9190F0020FFF742FA9F 248 | :100F6000FFF76EFAFFF75AFAFFF79AF9750F0020AC 249 | :100F7000FFF79CFBFFF764FA00F00CB8FFF728FAC4 250 | :100F8000FFF726FAFFF764FBFFF762FBFFF762F952 251 | :100F900000000000FFF74AFAFFF71AFAFFF758FBC4 252 | :100FA000FFF716FAFFF730FCFFF798F952F804FB49 253 | :100FB0007C0E0020034B455942F804EDFFF720F961 254 | :100FC000FFF76EF9BD0F002052F804FBB40F0020AC 255 | :100FD000055350414345000042F804EDFFF7F2FA93 256 | :100FE000FFF726F952F804FBD00F002006535041BA 257 | :100FF0004345530042F804EDFFF72CF900000000D0 258 | :10100000FFF796FBFFF7F6F900F002B8FFF7E4FFF1 259 | :10101000FFF736F90D10002052F804FBEC0F00200A 260 | :10102000045459504500000042F804EDFFF7E2F97E 261 | :1010300000F006B8FFF7B6FBFFF71EFDFFF7F8F864 262 | :10104000FFF71EF935100020FFF7E8F952F804FB0E 263 | :10105000201000200243520042F804EDFFF7FAF896 264 | :101060000D000000FFF7E4F8FFF7F4F80A000000B5 265 | :10107000FFF7DEF852F804FB42F804EDFFF7A8F999 266 | :10108000FFF7A6F9FFF772FAFFF7D0F9FFF78AFB2F 267 | :10109000FFF734FAFFF7E2FCFFF760FAFFF7AAF96F 268 | :1010A000FFF7CEF9FFF7A6F952F804FB42F804ED7A 269 | :1010B000FFF7E2FF52F804FB42F804EDFFF772FB82 270 | :1010C000FFF7B2FF52F804FB42F804EDFFF7D4FF3C 271 | :1010D000FFF7F2FF52F804FB54100020022E5200DA 272 | :1010E00042F804EDFFF786F9FFF75CFEFFF770F9B1 273 | :1010F000FFF7B0F9FFF70AFAFFF77CFFFFF794FF5D 274 | :1011000052F804FBDC10002003552E5242F804ED87 275 | :10111000FFF770F9FFF7D8FDFFF70CFEFFF732FE7F 276 | :10112000FFF756F9FFF796F9FFF7F0F9FFF762FFBF 277 | :10113000FFF77AFF52F804FB0811002002552E0039 278 | :1011400042F804EDFFF7C0FDFFF7F4FDFFF71AFECC 279 | :10115000FFF742FFFFF768FF52F804FB3C11002045 280 | :10116000012E000042F804EDFFF74EFBFFF7C0F838 281 | :10117000FFF770F80A000000FFF792F9FFF790F808 282 | :101180008D110020FFF7DCFF52F804FBFFF70AFE89 283 | :10119000FFF722FFFFF748FF52F804FB6011002021 284 | :1011A000013F000042F804EDFFF7A2F8FFF7DAFF75 285 | :1011B00052F804FB42F804EDFFF72CFBFFF78EF822 286 | :1011C000FFF748F9FFF716F9FFF730F9FFF768F86E 287 | :1011D000C3120020FFF7CAF9FFF71CFBFFF788F8DE 288 | :1011E000FFF7F0F9FFF774FAFFF75AF83D12002005 289 | :1011F000FFF700F9FFF7E6F9FFF72CF9FFF7E2F840 290 | :10120000FFF784F9FFF72EF9FFF746FAFFF748F8E2 291 | :1012100039120020FFF7A2F9FFF732F8F51100208C 292 | :10122000FFF7D6F8FFF7FAF8FFF714F80000000010 293 | :10123000FFF7FCF852F804FBFFF7CAF8FFF70AF9CA 294 | :10124000FFF7FEF8FFF7D6F8FFF7E4FAFFF750F8DC 295 | :10125000FFF700F9FFF7B6F8FFF758F9FFF7DAFAEA 296 | :10126000FFF746F8FFF7AEF9FFF732FAFFF718F885 297 | :1012700079120020FFF7F6F8FFF712F89712002016 298 | :10128000FFF76CF9FEF7FCFF49120020FFF7CEF8DC 299 | :10129000FFF7B0F809E0FFF79BF8FFF7BFF8FFF79B 300 | :1012A000C5F8FFF75BF9FFF7A5F8FFF7D3F8FFF7ED 301 | :1012B0002DF9FFF78DF8FFF78BF8FFF727F952F8B4 302 | :1012C00004FBFFF7C7F8FFF783F8FFF71FF952F8A1 303 | :1012D00004FB0000A01100200550415253450000BE 304 | :1012E00042F804EDFFF786F8FFF72CFCFFF7A8FAA9 305 | :1012F000FEF7FEFFFFF702F9FFF7AEFAFEF7F8FF81 306 | :10130000FFF79EFAFEF7F4FFFFF700F9FFF760F82A 307 | :10131000FFF750FFFFF794FAFFF71EFA52F804FBAD 308 | :10132000D8120020822E280042F804EDFEF792FF2A 309 | :1013300029000000FFF7D4FFFFF776FE52F804FB08 310 | :10134000241300208128000042F804EDFEF782FFFC 311 | :1013500029000000FFF7C4FFFFF77AF952F804FBF9 312 | :1013600044130020815C000042F804EDFFF774FA9A 313 | :10137000FEF7BEFFFFF764FAFEF7B0FF52F804FB7A 314 | :1013800064130020044348415200000042F804ED79 315 | :10139000FFF718F9FFF7A4FFFFF740F8FFF712F87F 316 | :1013A00052F804FB8413002004574F5244000000FD 317 | :1013B00042F804EDFFF794FFFFF7ACFBFFF7F0F8FE 318 | :1013C000FFF724FC52F804FBA813002005544F4BF0 319 | :1013D000454E000042F804EDFFF7F4F8FFF7E8FF90 320 | :1013E00052F804FBCC130020054E414D453E000051 321 | :1013F00042F804EDFFF7D6F9FEF72CFF1F000000BE 322 | :10140000FFF73AF8FFF77AF8FFF728FB52F804FBEA 323 | :10141000E81300200553414D453F000042F804ED1C 324 | :10142000FEF7E8FF00F022B8FFF714F8FEF7DAFF46 325 | :10143000FFF7D4F8FFF762F8FEF75AFFFFF70AF854 326 | :10144000FEF7D0FFFFF7CAF8FFF758F8FEF750FF96 327 | :10145000FFF75CF8FFF7E6F8FEF722FF6D140020B7 328 | :10146000FEF7B6FFFEF7DAFF52F804FBFEF708FFBF 329 | :1014700029140020FEF7EEFE0000000052F804FBE5 330 | :1014800042F804EDFEF7DCFFFEF7D0FFFEF79AFF0F 331 | :10149000FFF7AEF8FFF7BEF9FEF720FFFEF7C6FF35 332 | :1014A000FEF726FFFEF7A6FFFFF77AF8FEF7C8FF64 333 | :1014B000FEF7BCFFFEF7F4FE01150020FEF7B6FFB5 334 | :1014C000FEF716FFFEF7C6FE1FFFFFFFFEF7D4FF75 335 | :1014D000FEF788FFFEF7E4FFFEF7E2FEED140020C2 336 | :1014E000FFF768F8FEF704FFFFF7E2BFFFF758F8D1 337 | :1014F000FFF790F9FEF7FCFEFFF790FF00F00CB845 338 | :10150000FEF766FFFEF78AFFFEF79AFFFFF752F835 339 | :10151000FEF796FF52F804FBFEF7C2FE31150020DD 340 | :10152000FFF748F8FFF746F8FEF7E2FEFFF7C0BF07 341 | :10153000FEF74EFFFEF772FFFEF782FFFEF76EFF2B 342 | :10154000FFF738F8FEF772FFFFF752FFFEF778FF5C 343 | :1015500052F804FB14140020054E414D453F000095 344 | :1015600042F804EDFFF79AF9FEF7C2FEFFF788FF95 345 | :1015700052F804FB42F804EDFEF73CFFFEF76AFF69 346 | :10158000FEF726FFFEF75CFFFEF764FFFEF788FF1D 347 | :10159000FEF786FEBD150020FEF75CFE0800000089 348 | :1015A000FEF746FEFEF7E2FFFFF70CF8FEF740FEFF 349 | :1015B000FEF750FE08000000FEF73AFE52F804FB6A 350 | :1015C00042F804EDFEF732FFFEF732FEFEF742FF6F 351 | :1015D000FEF794FEFEF7C2FF52F804FB42F804ED5A 352 | :1015E000FEF724FFFEF736FE0D000000FEF758FF61 353 | :1015F000FEF756FE25160020FEF72CFE0800000020 354 | :10160000FEF74EFFFEF74CFE1D160020FEF7DAFF38 355 | :10161000FFF7D6FF52F804FB00000000FFF7AAFF17 356 | :1016200052F804FBFEF7FAFEFEF70AFFFEF7F6FE9D 357 | :10163000FEF7FCFE52F804FB581500200641434318 358 | :101640004550540042F804EDFEF704FFFEF756FF44 359 | :10165000FEF700FFFFF708F8FEF722FFFEF720FE77 360 | :1016600091160020FFF7A8FCFEF7E0FEFEF7AAFFA8 361 | :10167000FEF7F0FD7F000000FFF732F9FEF710FEE5 362 | :101680008B160020FFF79CFF01E0FFF7A7FFE1E7C3 363 | :10169000FEF7C4FEFEF7DEFEFEF738FF52F804FB4D 364 | :1016A0003C160020055155455259000042F804ED02 365 | :1016B000FFF748FAFEF7CEFD50000000FFF7C2FF2B 366 | :1016C000FFF7CAF8FEF70AFEFEF7A8FEFEF7C2FD16 367 | :1016D00000000000FFF7B4F8FEF700FE52F804FB2C 368 | :1016E000A41600200541424F5254000042F804ED78 369 | :1016F000FFF772FCFFF756F8FFF796FCFEF7AAFD1E 370 | :101700003F000000FEF794FDFFF7A6FC00F0B2F8E2 371 | :1017100000F0C0B842F804EDFEF7C2FD3517002016 372 | :10172000FFF7AAFCFFF73EF8FFF77EFCFFF794FCFB 373 | :1017300000F0B0B8FFF7A0FCFEF770FE52F804FB13 374 | :10174000E41600200A24494E544552505245540094 375 | :1017500042F804EDFFF704FFFEF764FFFEF7A0FD7B 376 | :1017600091170020FEF7C4FDFEF774FD4000000055 377 | :10177000FEF782FEFFF7CEFF0D20636F6D70696C80 378 | :1017800065206F6E6C790000FEF774FD52F804FB63 379 | :10179000FFF778FBFEF784FDA117002052F804FB49 380 | :1017A000FFF7A4BF44170020815B000042F804ED5E 381 | :1017B000FEF750FD51170020FFF75AF8FEF78EFD97 382 | :1017C00052F804FBA8170020032E4F4B42F804EDFB 383 | :1017D000FEF740FD51170020FFF74AF8FEF788FD9D 384 | :1017E000FEF776FFFEF75CFDF5170020FFF76CFCB7 385 | :1017F00003206F6BFFF730FC52F804FBC817002082 386 | :10180000063F535441434B0042F804EDFFF75AF9A9 387 | :10181000FEF728FEFFF77EFF0A20756E646572668C 388 | :101820006C6F770052F804FB001800200445564105 389 | :101830004C00000042F804EDFFF7CCFDFEF7F6FD8A 390 | :10184000FEF7C0FDFEF72CFD5D180020FFF710F835 391 | :10185000FFF784F9FFF7D8FFFFF7EEBFFEF7DEFDD5 392 | :10186000FFF7B4FF52F804FB2C1800200650524535 393 | :101870005345540042F804ED44F60061C2F2000101 394 | :1018800040F2000052F804FB6C1800200451554946 395 | :101890005400000042F804ED44F60072C2F2000267 396 | :1018A000FFF784FFFFF702FFFFF7C4FFFEF704FD19 397 | :1018B000A51800202148224C4460224C4460704707 398 | :1018C0001E48C46814F00104FBD170478C18002036 399 | :1018D0000C45524153455F534543544F520000005D 400 | :1018E00042F804ED15484FF00204046145F4003558 401 | :1018F0004FEA8525456144F042040461FFF7E0FFAB 402 | :1019000051F8045B52F804FB045B52F804FB00003E 403 | :10191000D01800200348492142F804EDFFF7D0FF1A 404 | :101920004FF001040461FEF7F3FCFFF7C9FF4FF02D 405 | :101930000004046152F804FB52F804FB002002404A 406 | :1019400023016745AB89EFCD141900200754555288 407 | :101950004E4B455942F804EDFEF77CFC004F002049 408 | :10196000FEF778FCD4010020FEF774FC4000000074 409 | :10197000FFF71CF9FEF76EFC00000020FEF76AFC82 410 | :1019800000000008FEF794FFFEF7B2FCFEF762FCD1 411 | :10199000FF4F0000FEF770FDFEF73AFEFEF72AFD4E 412 | :1019A000FEF758FDFEF7BEFCFEF754FDFFF7B4FF4F 413 | :1019B000FEF746FDFEF7E2FDFEF742FDFEF7DEFD17 414 | :1019C000FEF75EFCA0190020FEF742FE52F804FB71 415 | :1019D000A1190020FEF73CFE52F804FBFEF738FE8A 416 | :1019E00052F804FB4C1900200127000042F804EDD6 417 | :1019F000FFF7F0FCFFF7B4FDFEF752FC051A0020DC 418 | :101A000052F804FBFFF772BEE819002005414C4C68 419 | :101A10004F54000042F804EDFEF74AFFFEF79CFE2B 420 | :101A200052F804FB0C1A0020012C000042F804EDCF 421 | :101A3000FFF770F8FEF7FAFCFEF7B2FDFEF738FF8D 422 | :101A4000FEF74CFCFEF74AFC52F804FB281A002073 423 | :101A5000895B434F4D50494C455D000042F804ED11 424 | :101A6000FFF7C4FFFFF7E2FF52F804FB501A002013 425 | :101A700047434F4D50494C4542F804EDFEF7A8FC52 426 | :101A800025F00105FEF7D2FCFEF732FC00F0DAF992 427 | :101A9000FEF786FD45F00105FEF7ACFC52F804FBAD 428 | :101AA000701A0020874C49544552414C42F804EDCD 429 | :101AB000FFF7E2FF55020020FFF7B8FF52F804FBE2 430 | :101AC00042F804EDFEF7C6FBFCFFFFFFFEF7F0FE59 431 | :101AD000FEF742FEFEF7BEFB22000000FFF768FCA7 432 | :101AE000FEF760FEFEF70AFDFEF7B8FFFEF7E0FE28 433 | :101AF000FEF7F4FB52F804FBA41A002083464F5271 434 | :101B000042F804EDFFF7B8FFF5030020FFF702F8F5 435 | :101B100052F804FBFC1A002085424547494E00005C 436 | :101B200042F804EDFEF7F6FF52F804FB181B002004 437 | :101B3000844E45585400000042F804EDFFF79CFF26 438 | :101B400081020020FFF772FF52F804FB301B0020D7 439 | :101B500085554E54494C000042F804EDFFF78CFFC8 440 | :101B6000A1020020FFF762FF52F804FB501B002087 441 | :101B700085414741494E000042F804EDFFF77CFFE4 442 | :101B8000B9020020FFF752FF52F804FB701B00203F 443 | :101B90008249460042F804EDFFF76EFFA1020020E3 444 | :101BA000FEF7B8FFFEF756FB04000000FEF780FECC 445 | :101BB000FEF7D2FD52F804FB901B002085414845FA 446 | :101BC0004144000042F804EDFFF756FFB90200203F 447 | :101BD000FEF7A0FFFEF73EFB04000000FEF768FEE4 448 | :101BE000FEF7BAFD52F804FBBC1B0020865245509C 449 | :101BF0004541540042F804EDFFF7BEFFFEF78AFFAF 450 | :101C0000FEF71EFCFEF76AFB52F804FBEC1B0020FB 451 | :101C1000845448454E00000042F804EDFEF77AFF78 452 | :101C2000FEF70EFCFEF75AFB52F804FB101C0020D6 453 | :101C30008341465442F804EDFEF7F0FBFFF7C2FF84 454 | :101C4000FFF76EFFFEF7FCFB52F804FB301C002090 455 | :101C500084454C534500000042F804EDFFF7B2FF05 456 | :101C6000FEF7EEFBFFF7D8FF52F804FB501C0020F4 457 | :101C7000855748494C45000042F804EDFFF78AFFBC 458 | :101C8000FEF7DEFB52F804FB701C00208641424F39 459 | :101C90005254220042F804EDFFF7EEFE1517002023 460 | :101CA000FFF70EFF52F804FB8C1C00208224220058 461 | :101CB00042F804EDFFF7E0FEAD100020FFF700FF53 462 | :101CC00052F804FBAC1C0020822E220042F804EDE6 463 | :101CD000FFF7D2FEC9100020FFF7F2FE52F804FB16 464 | :101CE000C81C0020073F554E4951554542F804EDA8 465 | :101CF000FEF79CFBFFF734FCFEF7D2FA191D00201B 466 | :101D0000FFF7E2F90720726544656620FEF7A2FB43 467 | :101D1000FEF748FDFFF788F9FEF780FB52F804FB59 468 | :101D200042F804EDFEF782FBFEF74CFBFEF7B8FA33 469 | :101D3000691D0020FFF7DAFFFEF7C6FDFEF7D8FAAF 470 | :101D4000FFF774FEFEF772FBFEF7BEFDFEF7C6FA64 471 | :101D5000FEF728FDFEF7D2FBFEF780FEFEF7A8FD9A 472 | :101D6000FEF7BCFA52F804FBFFF7A0F907206E61FA 473 | :101D70006D653F20FFF7BABCE41C00200824434FE8 474 | :101D80004D50494C4500000042F804EDFFF7E8FBD8 475 | :101D9000FEF748FCFEF784FAC51D0020FEF7A8FAFE 476 | :101DA000FEF758FA80000000FEF766FBFEF778FAAF 477 | :101DB000BD1D0020FEF75EFA52F804FB00F042F869 478 | :101DC00052F804FBFFF75EF8FEF76AFAD91D00200F 479 | :101DD000FFF76CFE52F804FBFFF788BC7C1D002067 480 | :101DE000054F56455254000042F804EDFEF76CFDD5 481 | :101DF000FEF77EFAFEF752FDFEF770FA52F804FB8A 482 | :101E0000E01D0020C13B000042F804EDFEF722FA7D 483 | :101E100052F804FBFFF70AFEFFF7C8FCFFF7E4FFE8 484 | :101E200052F804FB041E0020015D000042F804ED9E 485 | :101E3000FEF710FA891D0020FEF71AFDFEF74EFA94 486 | :101E400052F804FB42F804ED25F00105FEF762FEAE 487 | :101E5000FEF75CFBA5F1040540F2FF702C464FEA4B 488 | :101E6000153505EA00054FEAC43445EA040545F096 489 | :101E7000784545F47045FFF7D9FD52F804FB0000A2 490 | :101E8000281E0020013A000042F804EDFFF7A2FAF4 491 | :101E9000FFF746FFFEF7DEF942F804EDFFF7C6FD57 492 | :101EA000FFF7C4FF52F804FB841E002009494D4D82 493 | :101EB000454449415445000042F804EDFEF7CAF993 494 | :101EC00080000000FEF700FDFEF712FAFEF710FAA0 495 | :101ED000FEF7DCFAFEF7F8FCFEF70AFAFEF7FEF969 496 | :101EE00052F804FBAC1E002008434F4E5354414EA1 497 | :101EF0005400000042F804EDFFF76CFAFFF710FF02 498 | :101F0000FFF772FFFEF7A6F942F804EDFFF78EFD2A 499 | :101F1000FEF7A0F9D9070020FFF794FFFFF786FD31 500 | :101F200052F804FBE81E0020064352454154450088 501 | :101F300042F804EDFFF74EFAFFF7F2FEFFF754FF09 502 | :101F4000FEF788F942F804EDFFF770FDFEF782F91D 503 | :101F5000CD070020FFF776FF52F804FB281F002072 504 | :101F6000085641524941424C4500000042F804EDF8 505 | :101F7000FFF7DEFFFEF76EF900000000FFF756FDE9 506 | :101F800052F804FB42F804EDFEF764FAFEF762F93A 507 | :101F900004000000FFF7BAF8FFF71EF8FEF72AFA70 508 | :101FA00000F00CB8FEF742FAFEF70CFAFEF752F911 509 | :101FB00003000000FFF7AAF8FEF7D0FAFEF760F979 510 | :101FC000A51F002052F804FB601F00200444554D5B 511 | :101FD0005000000042F804EDFEF716FCFEF788F909 512 | :101FE000FEF708FAFEF7F6FEFEF734F910000000DF 513 | :101FF000FEF702FDFEF7FEF900F014B8FFF72CF82B 514 | :10200000FEF728F910000000FEF72EFBFFF7BAFFDD 515 | :10201000FEF712FBFEF710FBFEF7DEFFFEF7DCFF1C 516 | :10202000FFF702F8FEF72CF9FD1F0020FEF7F6F986 517 | :10203000FEF7CEF9FEF7E8FBFEF750F952F804FB85 518 | :10204000CC1F0020022E530042F804EDFEF7C4FF1F 519 | :10205000FEF738FDFEF7CEF900F006B8FEF7C2F93C 520 | :10206000FEF744FDFFF77EF8FEF70AF95D20002039 521 | :10207000FEF7B2FF52F804FB44200020053E4E411B 522 | :102080004D45000042F804EDFEF7B4F9FEF706FCFA 523 | :10209000FEF72EF9FEF7CAF9FEF702F9C520002077 524 | :1020A000FEF7C4F9FFF7A4F9FEF79CF9FEF7F8F97B 525 | :1020B000FEF7F6F8C5200020FEF77CFAFEF718F9C7 526 | :1020C000FFF7E8BFFEF784F9FEF7A8F952F804FB22 527 | :1020D0007C200020032E494442F804EDFEF7A2FACA 528 | :1020E000FEF7DEF801210020FEF75CFBFEF7B2F8F8 529 | :1020F0001F000000FEF7C0F9FEF796FF52F804FB40 530 | :10210000FEF7E2FF09207B6E6F4E616D657D00007A 531 | :1021100052F804FBD42000200353454542F804ED57 532 | :10212000FFF764FCFEF798FFFEF794F81400000038 533 | :10213000FEF760F9FEF734FAFEF778F900F010F8D0 534 | :10214000FEF79EF835210020FEF768F952F804FBEF 535 | :1021500018210020094445434F4D50494C4500008B 536 | :1021600042F804EDFEF762F9FEF7C2F8FEF75EF9F9 537 | :10217000FEF770F800F800F8FEF77EF9FEF76AF84F 538 | :1021800000F000F8FEF7A4FAFEF78AF8E521002037 539 | :1021900040F6FE702C464FEA45554FEA65254FEA5A 540 | :1021A000D43404EA000445EA040500BFFEF752F9FE 541 | :1021B000FEF7A4F9FEF7F4F9FFF764FFFEF732FA31 542 | :1021C000FEF76EF8D9210020FEF706FFFFF784FF27 543 | :1021D000FEF724F952F804FBFEF78AF8FEF7B0FF89 544 | :1021E00052F804FBFEF7ACFFFEF718F952F804FBB7 545 | :1021F0005421002005574F524453000042F804ED8B 546 | :10220000FEF72AFFFEF74AFBFEF772F8FEF70AFA1E 547 | :10221000FEF746F831220020FEF708F9FEF7DCFE53 548 | :10222000FFF75AFFFEF7C6F9FEF762F8FFF7EEBFB9 549 | :1022300052F804FB42F804EDFEF70CF82107000009 550 | :1022400052F804FBF42100200248490042F804ED52 551 | :10225000FEF702FFFEF738FF0D73746D33326546EB 552 | :102260006F72746820760000FEF7CEFAFEF740F831 553 | :10227000FEF7B0FDFFF7DEFFFEF726FDFEF74AFD95 554 | :10228000FEF748FDFDF7E6FF2E000000FEF72CFDEF 555 | :10229000FEF750FDFEF776FDFEF7C6FEFEF7B4FA38 556 | :1022A000FEF71CF8FEF7D8FE52F804FB4822002087 557 | :1022B00004434F4C4400000044F60073C2F2000394 558 | :1022C0001A46A2F580714FF0000500BF42F804EDF8 559 | :1022D000FDF7C0FFB4010020FDF7BCFF004F002058 560 | :1022E000FDF7B8FF40000000FEF760FCFFF7C2FA00 561 | :1022F000FEF77EFAFEF732FCFFF776FDFFF7CABA6B 562 | :00000001FF 563 | --------------------------------------------------------------------------------