;--------------------------------------------------------------- ; ; Stand-alone Intel Hex file loader for the Sol-20. ; ; Execute by jumping to F000. ; ; Displays address information as the hex file loads. ; The video scroll time problem is avoided by first ; clearing the screen and displaying address information ; only every 16th hex file line. Intermediate pacifiers are ; displayed every 4th hex line. With a typical hex file ; format of 16 payload bytes per line, about 32K of memory ; can be loaded before a screen scroll takes place. This ; handles most any file that would be loaded this way. ; ; Rev Date By Desc ; 1.0 04/05/15 M Douglas Original ; ;--------------------------------------------------------------- F000 org 0f000h ; Equates C000 = SOLOS equ 0c000h ;base address of SOLOS/CUTER C019 = CONOUT equ SOLOS+019h ;console out C022 = SERIN equ SOLOS+022h ;input from psuedo port in A C004 = RETRN equ SOLOS+004h ;return to SOLOS entry 000B = CLRSCR equ 11 ;clear screen in SOLOS 000D = CR equ 13 000A = LF equ 10 ;------------------------------------------------------------ ; Display message to send the file, then loop receiving ; and storing the hex file. ;------------------------------------------------------------ F000 21BCF0 init lxi h,mSend ;send file message F003 CDB1F0 call dispMsg F006 0E00 mvi c,0 ;clear echo character flag F008 3E01 mvi a,1 ;init hex line counter F00A F5 push a ; maintained on the stack ; nxtLine - Look for new record F00B CD9CF0 nxtLine call getChar ;read next character F00E D63A sui ':' ;record marker? F010 C20BF0 jnz nxtLine ;no, keep looking ; Have start of new record. Save the byte count and load address. ; The load address is echoed to the screen every 16th hex file ; line so the user can see the file load progress. F013 57 mov d,a ;init checksum in D to zero F014 CD6FF0 call iByte ;input two hex digits (byte count) F017 7B mov a,e ;test for zero byte count F018 B7 ora a F019 CA55F0 jz done ;count of 0 means end ; echo address every 16th line read, pacifier every 4th F01C F1 pop a ;A = hex file line counter F01D 3D dcr a F01E C224F0 jnz not16 ;skip if not a 16th line F021 3E10 mvi a,16 ;restart 16 line count F023 0C inr c ;set echo flag F024 F5 not16 push a ;save line counter F025 E603 ani 03h ;4 line boundary? F027 C22FF0 jnz getAddr ;no F02A 062E mvi b,'.' ;yes, display pacifier F02C CD19C0 call CONOUT ; getAddr - read load address into HL F02F 43 getAddr mov b,e ;B = byte count on line F030 CD6FF0 call iByte ;get MSB of address F033 63 mov h,e ;H = address MSB F034 CD6FF0 call iByte ;get LSB of address F037 6B mov l,e ;L = address LSB F038 0E00 mvi c,0 ;clear echo flag F03A CD6FF0 call iByte ;ignore record type ; Receive the data bytes of the record and move to memory F03D CD6FF0 data call iByte ;read a data byte (2 hex digits) F040 73 mov m,e ;store in memory F041 23 inx h F042 05 dcr b F043 C23DF0 jnz data ; Validate checksum F046 CD6FF0 call iByte ;read and add checksum F049 CA0BF0 jz nxtLine ;checksum good ; error - error in data or checksum. Display error message ; and exit after flushing the rest of the file F04C 21D1F0 error lxi h,mError ;display error message F04F CDB1F0 call dispMsg F052 C35BF0 jmp flush ;flush remaining reception ; done - hex file loaded without error F055 21E5F0 done lxi h,mDone ;display "complete" message F058 CDB1F0 call dispMsg ; flush - eat characters until none received for 1/2 second ; so the rest of the file doesn't go to the monitor F05B 11A816 flush lxi d,5800 ;1/2 sec/(170*500ns) F05E 3E01 flLoop mvi a,1 ;read from serial port F060 CD22C0 call SERIN ;(136 cycles) F063 C25BF0 jnz flush ;(10) start over F066 1B dcx d ;(5) decrement timeout F067 7A mov a,d ;(5) F068 B3 ora e ;(4) F069 C25EF0 jnz flLoop ;(10) loop until zero F06C C304C0 jmp RETRN ;return to SOLOS ;----------------------------------------------------------- ; iByte - read two ascii hex bytes and return binary ; value in e. If a conversion error occurs, exit ; directly to error label above. ;----------------------------------------------------------- F06F CD9CF0 iByte call getChar ;get a character F072 CD8BF0 call asc2Bin F075 DA4CF0 jc error F078 87 add a ;put in msn, zero lsn F079 87 add a F07A 87 add a F07B 87 add a F07C 5F mov e,a ;save byte with MSN in E ; 2nd byte (LSN) F07D CD9CF0 call getChar ;get a character F080 CD8BF0 call asc2Bin F083 DA4CF0 jc error F086 83 add e ;combine msn and lsn F087 5F mov e,a ;save in E F088 82 add d ;add character to checksum F089 57 mov d,a F08A C9 ret ;------------------------------------------------------------- ; asc2Bin - ASCII hex digit to binary conversion. Digit ; passed in a, returned in a. Carry returned clear ; for valid conversion, carry set for error. ;------------------------------------------------------------- F08B D630 asc2Bin sui 30h ;'0' to 0 F08D D8 rc ;error - below zero F08E FE0A cpi 10 ;0-9 ? F090 DA9AF0 jc ascExit ;yes F093 D611 sui 11h ;A-F to 0-5 F095 D8 rc ;error - below A F096 C60A adi 10 ;convert back to A-F F098 FE10 cpi 16 ;too big? (carry clear if so) F09A 3F ascExit cmc ;complement carry F09B C9 ret ;------------------------------------------------------------- ; getChar - read a character from the the serial port ; and return it in a. The character is echoed if the ; echo flag in c is zero. ;------------------------------------------------------------- F09C 3E01 getChar mvi a,1 ;read from serial port F09E CD22C0 call SERIN F0A1 CA9CF0 jz getChar ;loop until character there F0A4 C5 push b ;save b F0A5 47 mov b,a ;save character in b F0A6 79 mov a,c ;echo flag asserted? F0A7 B7 ora a F0A8 CAAEF0 jz noEcho ;no F0AB CD19C0 call CONOUT ;echo the character (in b) F0AE 78 noEcho mov a,b ;a=character read F0AF C1 pop b ;restore b F0B0 C9 ret ;------------------------------------------------------------ ; dispMsg - display the null-terminated message passed in hl ;------------------------------------------------------------ F0B1 7E dispMsg mov a,m ;get the next message byte F0B2 B7 ora a ;null terminates F0B3 C8 rz F0B4 47 mov b,a ;b=character to display F0B5 CD19C0 call CONOUT ;display on console F0B8 23 inx h ;move to next byte F0B9 C3B1F0 jmp dispMsg ;------------------------------------------------------------ ; Messages ;------------------------------------------------------------ F0BC 0B53656E64mSend db CLRSCR,'Send Hex File Now: ',0 F0D1 0D0A0A4865mError db CR,LF,LF,'Hex File Error',CR,LF,0 F0E5 0D0A4C6F61mDone db CR,LF,'Load Complete',CR,LF,0 F0F7 end