home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
packet
/
tnc_pk80.arc
/
TNC2BAEA.MAC
< prev
Wrap
Text File
|
1988-02-13
|
7KB
|
236 lines
; KISS-TNC-HEX-LOADER.MAC - KISS TNC Intel Hex Loader v0.2
; k3mc 8 Aug 86 v0.1
; 4 Oct 86 v0.2
; v0.2 correctly sets the SP for either 16k or 32k of RAM, and strips
; the parity bit from incoming chars.
; v0.2 re-orged to fit in AEA 1.1.2 code (27128) by JPD 2/13/88
; Memory available: 0069-0080 (with msb set in first byte to truncate signon)
; 3F5E-3F80 (copyright msg)
; 3FA0-3FFF (unused)
.z80
aseg
org 100h
RAM equ 8000h ;Where the 16k x 8 (or 32k x 8) of RAM begins
ENQ equ 5h
ACK equ 6h
NAK equ 15h
colon equ ':'
rr_eof equ 1 ;Record Type for End of File / begin execution
; SIO equates
SIO equ 0dch ;actually, only A5 is used for SIO -cs
A_dat equ SIO+0 ;Modem port
A_ctl equ SIO+1 ;Modem port
B_dat equ SIO+2 ;user serial port
B_ctl equ SIO+3 ;user serial port
RR0_RXR equ 1 ;Receiver Char Avail bit
RR0_TBE equ 4 ;TX Buffer Empty bit
;
; The general form of an Intel HEX record is as follows:
;
; :LLaaaaRRdddd..ddCC
;
; where LL is the number of bytes of data between RR and CC,
; not including RR or CC.
; aaaa is an address (see below),
; RR is a record type,
; dd are data bytes,
; and CC is a checksum, calculated as follows:
; CC = - ( LL + aaaa + RR + dd + dd + ... ( modulo 256 ) )
; That is, adding all the bytes LL to CC (inclusive), you should get zero.
;
; These are the record types needed:
; RR = 00 record type = data. aaaa is the load address for the data.
; RR = 01 record type = end of file.
; aaaa is the beginning execution address. LL is 00.
; :00aaaa01CC
; So, for example, if the start address is 8000, the last line of the file is
; :008000017F
;
; In this implementation, trailing checksums are ignored; you don't even have
; to include them.
;-----------------------------------------------------------------------------
.phase 0069h ;CHANGED FROM 4800H
defb 8DH ;CR with MSB set => end of string
start:
di ;for this test, NO INTERRUPTS!
; Figure out where top of stack is, set stack pointer.
; silly TNC-2 does not do complete address decoding for the RAMs if you are
; using only the two 8k x 8 chips. Hack to figure out top of memory so we can
; set stack pointer. This is REQUIRED by the KISS TNC.
ld a,55h ;one value
ld (0bfffh),a
ld a,0aah
ld (0ffffh),a ;other value
ld a,(0bfffh) ;get what should be 55h if 32k
cp 55h
ld sp,0 ;assume for the moment it is
jr z,stack_loaded ;if so, then we've found TOS
ld sp,0c000h ;else all we've got is two 8k x 8 RAMs
stack_loaded:
;init SIO for async
ld b,nb ;n bytes for init
ld c,B_ctl ;to B port
ld hl,binit ;with these bytes
otir ;NOW!
ld a,5
out (A_ctl),a ;Ready WR5
ld a,80h
out (A_ctl),a ;turn off STATUS LED
loop:
call getchar ;returns char into A reg
cp ENQ ;is it Control-E character?
jp z,ENQCHR ;yes, deal with it
cp colon
jr z,saw_colon ;Go into Intel Hex download mode
and 5fh ;UPPER CASE ONLY ADDED BY WA7MXZ
cp 'H' ; H for HOWIE of course
jp z,00EDH ;go get em' HOWIE
call putchar ;if neither, just echo it
jr loop
saw_colon:
call rdbyte
EX AF,AF' ;save in other register set for a sec
call rdbyte
ld h,a
call rdbyte
ld l,a
call rdbyte
cp rr_eof ;is it record type 1 (begin execution)?
jr nz,data_record ;no, it's just another data record
;else we give machine to downloaded program
jp (hl) ;and go do it!
data_record:
EX AF,AF' ;get length value back
ld b,a ;and ready loop index
load_loop:
call rdbyte
ld (hl),a
inc hl
djnz load_loop ;load 'em up!
; Note, we ignore checksums completely
find_colon:
call getchar
cp colon
jr nz,find_colon ;spin for a colon
jr saw_colon ;when we find colon, deal with next record
;*** Reads 2 characters from SIO, converts them to binary, and returns value
;*** into A reg. Disturbs no registers except AF.
rdbyte:
push bc
call getchar
call mk_binary
rlca
rlca
rlca
rlca
ld b,a ;save hi part
call getchar
call mk_binary
or b ;get hi + lo parts
pop bc ;be tidy
ret
.dephase
.phase 3F5EH ;>>>>>>>>>>>>>>>>RE-ORG TO FIT<<<<<<<<<<<<<<<<<<<<<<<<
ENQCHR:
ld hl,ENQ_string
ENQ_loop:
ld a,(hl)
or a
jp z,loop
call putchar
inc hl
jr ENQ_loop
;*** Convert the ASCII character into Binary character (src & dest is A reg)
;*** Set carry flag if illegal hex char.
mk_binary:
call makeUC ;if anybody uses lower case, it's OK
sub '0' ;convert ASCII -> binary (sorta)
ret c ;char < '0' => error
add a,('0'-'G') ;char > 'F' ?
ret c ;yes, illegal
add a,6 ;char = A-F ?
jp p,mk_b ;yes, jump
add a,7 ;char = ':'-'@'?
ret c ;yes, illegal
mk_b:
add a,10
or a ;clear carry => OK hex
ret
.dephase
.phase 3FA0H ;>>>>>>>>>>>RE-ORG TO FIT<<<<<<<<<<<<<<<
;*** If the character in A reg is lower case, this makes it upper case.
makeUC:
cp 'a'
ret c ;if less than an 'a' we're done
cp 'z'+1
ret nc ;if > than 'z', not a letter, so we're done
and 5fh ;else force to UPPER CASE
ret
;*** Get a char from user TTY (Port B), no interrupt mode. Return it in A reg.
getchar:
in a,(B_ctl)
and RR0_RXR
jr z,getchar ;wait for a character to be typed
in a,(B_dat)
and 7fh ;strip parity bit (Phil's suggestion)
ret
;*** Put a character to user TTY (Port B), no interrupts. Char is in A reg.
putchar:
push af ;we will need A
ploop:
in a,(B_ctl)
and RR0_TBE
jr z,ploop ;Wait for Transmitter buffer to become empty
pop af
out (B_dat),a
ret
binit: defb 1ah,0,14h,44h,3,0c3h,5,0eeh,11h,0 ;magic SIO inits
bi_end equ $
nb equ bi_end-binit ;Number of bytes in previous string
ENQ_string:
defb "KISS/Raw TNC Intel Hex Loader v0.2 for AEA 1.1.2",13,10,0
END START