title 'Add bios8502 to CPM3.SYS file 2 June 85' maclib seqio lxi sp,stack call disp$sign$on FILE outfile,CPM,,CPM+,SYS,16*1024 FILE infile,CPM3,,CPM3,SYS,4*1024 FILE infile,BIOS8502,,1,HEX,1024 FILE infile,KEYS,,CXKYCODE,HEX,1024 lxi h,load$bios$msg call disp$loop call load$bios$8502 ; load hex file to buffer lxi h,load$key$msg call disp$loop call load$keys ; load hex file to buffer lxi h,add$vect$msg call disp$loop call add$vectors ; add the new vector pointers lxi h,inst$key$msg call disp$loop call insert$key$defs ; add FUNCTION KEYS and KEY definition lxi h,inst$cpm$msg call disp$loop call finish$rest ; transfer rest of system over lxi h,inst$bios$msg call disp$loop call add$bios$8502 ; save bios8502 to CP/M file lxi h,closing$msg call disp$loop finis CPM jmp 0 ; exit back to CP/M page load$bios$msg: db 'Loading 8502 BIOS .HEX file',cr,lf,0 load$key$msg: db 'Loading Key definition .HEX file',cr,lf,0 add$vect$msg: db 'Adding new vectors to CPM+.SYS',cr,lf,0 inst$key$msg: db 'Adding Key def. to CPM+.SYS',cr,lf,0 inst$cpm$msg: db 'Adding CPM3.SYS to CPM+.SYS',cr,lf,0 inst$bios$msg: db 'Adding BIOS8502 to CPM+.SYS',cr,lf,0 closing$msg: db 'Closing CPM+.SYS file',cr,lf,lf,lf,0 page ;; ;; ;; load$bios$8502: xra a sta file$num ; use bios8502 file for HEX input call read$header ; get BIOS8502 start adr mov a,l ; LSB should be zero ora a jnz adr$error push h mov a,h sta bios$addr cma mov h,a inr h ; two's comp of start adr lxi d,buffer$bios$8502 dad d shld bias pop h call finish$load hex$load: jc done$bios8502 ; done when carry set call load$record jmp hex$load done$bios$8502: lhld hex$addr ; get last address lxi d,buffer$bios$8502 mov a,l sub e mov l,a mov a,h sbb d mov h,a mov a,l ora a jz size$ok inr h size$ok: mov a,h sta bios$size cpi 4096/256 jnc size$error ret page load$keys: mvi a,-1 sta file$num ; use KEYS file for HEX input call read$header ; get KEYS start adr mov a,l ; LSB should be zero ora a jnz adr$error push h mov a,h sta keys$addr cma mov h,a inr h ; two's comp of start adr lxi d,buffer$keys dad d shld bias pop h call finish$load hex$load$keys: jc done$keys ; done when carry set call load$record jmp hex$load$keys done$keys: lhld hex$addr ; get last address dcx h dcx h ; two byte header for key def adr lxi d,buffer$keys mov a,l sub e mov l,a mov a,h sbb d mov h,a mov a,l ora a jz keys$size$ok inr h keys$size$ok: mov a,h sta keys$size cpi (1024/256)+1 jnc size$error ret page ;; ;; ;; add$vectors: mvi b,6 ; use first 6 bytes of old header get$1st: push b ; read in the header info GET CPM3 PUT CPM pop b dcr b jnz get$1st ; remove next six bytes from old header get CPM3 ; bios8502 top page # get CPM3 ; bios8502 # of blocks (256 bytes) get CPM3 ; KEYS bottom page # (function key adr) get CPM3 ; KEYS # of blocks (256 bytes) get CPM3 ; key definition adr (low) get CPM3 ; key definition adr (high) lda bios$size ; install load info into header mov b,a lda bios$addr add b put CPM ; bios8502 top page # mov a,b put CPM ; bios8502 # of (256 byte) blocks ; ; install MSG tbl and FUN tbl pointers ; lda keys$addr put CPM ; function key start adr (high only) lda keys$size put CPM ; KEYS # of (256 byte) blocks lhld buffer$keys mov a,l push h put CPM ; key definition adr (low) pop h mov a,h put CPM ; Key definition adr (high) ; ; only move 256 bytes total (128 bytes info, 128 message) ; mvi b,256-6-6 ; number of bytes left to move get$2nd: push b ; read in the header info GET CPM3 PUT CPM pop b dcr b jnz get$2nd ret page ;; ;; add FUNCTION KEYS and KEY definition ;; insert$key$defs: lxi h,buffer$keys+2 ; 1st two bytes point to the ; ..key definition insert$keys$loop: mvi c,0 ; save 256 bytes call save$loop lda keys$size dcr a sta keys$size jnz insert$keys$loop ret ;; ;; transfer rest of system over ;; finish$rest: get CPM3 ; save CPM3.SYS to CPM.SYS rz put CPM jmp finish$rest page ;; ;; ;; add$bios$8502: lda bios$size mov h,a mvi l,0 lxi d,buffer$bios$8502 xchg dad d ; HL=next free address DE=size mov a,d ; number of 256 byte blocks add a ; number of 128 byte blocks mov d,a ; save count in D save$next: lxi b,-128 dad b ; back up the pointer push h push d call save$128$bytes pop d pop h dcr d jnz save$next ret ; ; ; save$128$bytes: mvi c,128 save$loop mov a,m push h put CPM pop h inx h dcr c jnz save$loop ret page ; ; ; load$record: call read$header ; record adr in HL finish$load: xchg lda hex$count cpi 0+1 ; see if length=0 stc ; set END OF FILE rz ; null record marks the end lhld bias dad d shld hex$addr call read$byte ; this byte should be a zero ana a jnz hex$error hex$record$read: lda hex$count dcr a sta hex$count jz hex$record$done call read$byte lhld hex$addr mov m,a inx h shld hex$addr jmp hex$record$read hex$record$done: call read$byte lda hex$sum ana a ; clears carry (marks end of record) jnz hex$error ret read$header: xra a sta hex$sum call read$hex$byte ; get input character jz hex$error ; missing char is a problem cpi ':' jnz read$header call read$byte ; get record length inr a sta hex$count call read$byte ; get high address mov h,a push h call read$byte ; get low address pop h mov l,a ret read$byte: call read$hex$val ; get a hexadecimal value rlc rlc rlc rlc ; move to upper 4 bits push psw call read$hex$val ; get a hexadecimal value mov b,a pop psw ora b ; make a data byte from two hex digits mov b,a lda hex$sum ; add to sum add b sta hex$sum mov a,b ; return byte value ret read$hex$val: call get$upper ; force to upper case mov b,a sui '0' ; remove number bias jm hex$error cpi 9+1 ; return if a number rc sui 'A'-'0' ; remover extra if A to F jm hex$error adi 10 cpi 0fh+1 rc ; return if valid hex number (0-F) hex$error: lxi h,hex$mess jmp dsp$and$exit get$upper: call read$hex$byte jz hex$error cpi 'a' rc ani 5fh ret read$hex$byte: lda file$num ora a jz read$hex$fst get KEYS ret read$hex$fst: get BIOS8502 ret adr$error: lxi h,adr$mess jmp dsp$and$exit size$error: lxi h,size$mess dsp$and$exit: call disp$loop jmp 0 page disp$sign$on: lxi h,message disp$loop: mov a,m ora a rz inx h push h PUT CON pop h jmp disp$loop message: db cr,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf db ' This program will create a CPM+.SYS file from',cr,lf db ' The CPM3.SYS file (created by GENCPM) and',cr,lf db ' The 6502 BIOS File supplied in Intel HEX format',cr,lf db ' And CXKYCODE File supplied in Intel HEX format',cr,lf db ' (1st HEX address is FUNCTION table address)',cr,lf db ' (1st two bytes point to ASCII table)',cr,lf db lf,lf db ' The ROM boot code will load the CPM+.SYS file',cr,lf,lf db 0 hex$mess: db 'HEX file error - first record must be start adr and',cr,lf db ' last record must contain the last adr' db cr,lf db ' All other address must be between',cr,lf db ' the start and end adr',cr,lf db ' also HEX file must be ended with a NULL record',cr,lf,lf db ' and ' adr$mess: db 'Start address must be on a page boundary',cr,lf,lf db ' and ' size$mess: db 'File can NOT be larger than 4K',cr,lf,0 keys$size: ds 1 keys$addr: ds 1 bios$size: ds 1 bios$addr: ds 1 bias: ds 2 hex$count: ds 1 hex$addr: ds 2 hex$sum: ds 1 file$num: ds 1 buffer$bios$8502: ds 4096 buffer$keys: ds 1024+2 ds 60 stack: buffers equ stack end