; HDT code module, loaded and linked into RAM ; commented by Holger Veit 2013 ; The file was produced from HDT.CODE from a disk of the Don Maslin collection ; by a self-written IDA module. IDA is a software by Hexrays/Datarescue. ; ; This work is Creative Commons CC-BY-SA ; ; This is the RAM version of HDT. ; This is similar to the B4 ROM; it can reboot from onboard floppy. ; Processor: WD9000 ; Target assembler: P-Code Pseudo Assembler ; Note: this is no valid assembler and not intended to be ; converted back into machine code. ROMHDT:0000 ; Segment type: Pure code ROMHDT:0000 ; START OF SEGMENT ROMHDT:0000 .WPTR byte_5D4 ROMHDT:0002 .WORD $0000 ROMHDT:0004 aRomhdt .ASC 'ROMHDT ' ROMHDT:000C word_20C .WORD $0000 ROMHDT:000E .WORD $0000 ROMHDT:0010 .WORD $0000 ROMHDT:0012 ; ROMHDT:0012 ; segment global variables ROMHDT:0012 ; global1 char read from console ROMHDT:0012 ; global2 integer number read from console ROMHDT:0012 ; global3 flag hasnumber ROMHDT:0012 ; global4 address of console 0xfc10 ROMHDT:0012 ; global5 "current address" ROMHDT:0012 ; global6 address of HDT info area (0x22) ROMHDT:0012 ; global7-8 ROMHDT semaphore ROMHDT:0012 ; global9-16 hex conversion table ROMHDT:0012 ; global17-21 hex char set ROMHDT:0012 ; ROMHDT:0012 ;----------------------------- ROMHDT:0012 .CPTR loc_248 ; exitic ROMHDT:0014 reset_fd_dma .WORD $0000 ; # of words ROMHDT:0016 LOD 1,1 ; get FDC base address 0xfc34 ROMHDT:0019 LDCI $4153 ; select SD, drive 0 or 1 ROMHDT:0019 ; command step-in ROMHDT:001C LOD 1,2 ; boot unit (0 or 1) ROMHDT:001F ADI ; will result in select 0 or 1 (bit 0 or 1 set) ROMHDT:0020 STO ; send command ROMHDT:0021 loc_221 ROMHDT:0021 LOD 1,1 ; address 0xfc34 (FDC status) ROMHDT:0024 SIND 0 ; read status ROMHDT:0025 LNOT ROMHDT:0026 FJP loc_221 ; wait until drive is ready ROMHDT:0028 loc_228 ROMHDT:0028 LOD 1,1 ; address FDC command (0xfc34) ROMHDT:002B LDCI $41D0 ; terminate command (0xD0) ROMHDT:002E LOD 1,2 ; merge in unit ROMHDT:0031 ADI ROMHDT:0032 STO ; send it ROMHDT:0033 LOD 1,1 ; address DMA control (0xfc38) ROMHDT:0036 INC 4 ; | ROMHDT:0038 SLDC 0 ; clear, stop operation and disable all interrupts ROMHDT:0039 STO ; |----- ROMHDT:0039 ; ROMHDT:003A LOD 1,1 ; address 0xfc39 (DMA status) ROMHDT:003D INC 5 ; | ROMHDT:003F SLDC 0 ; clear, i.e. set interrupt flags to 0 ROMHDT:0040 STO ; |----- ROMHDT:0040 ; ROMHDT:0041 LOD 1,1 ; read FDC status (0xfc34) ROMHDT:0044 SIND 0 ; | ROMHDT:0045 LNOT ; loop until no longer busy ROMHDT:0046 FJP loc_228 ; |------ ROMHDT:0048 loc_248 ; done ROMHDT:0048 RPU 0 ROMHDT:004A ; procedure bootsetup(unit: integer, loadbase: memp); ROMHDT:004A ; ROMHDT:004A ;local stack frame ROMHDT:004A ; local1 temporary for address 0xfc34 ROMHDT:004A ; local2 unit number 0x0000 or 0x0100 ROMHDT:004A ; local3 dummy ROMHDT:004A ; local4 dummy ROMHDT:004A ; local5 dummy ROMHDT:004A ; argument6 loadbase ROMHDT:004A ; argument7 unit ROMHDT:004A .CPTR exitic_bootfd ; exitic ROMHDT:004C bootfd .WORD $0005 ; # of words ROMHDT:004E LDCI $100 ; for left shift of 8 bit ROMHDT:0051 SLDL 7 ; get unit ROMHDT:0052 SLDC 2 ; get low bit ROMHDT:0053 MODI ; | ROMHDT:0054 MPI ; shift 8 bit left (into high byte) ROMHDT:0055 STL 2 ; store as local2 ROMHDT:0055 ; ROMHDT:0057 LLA 1 ; store 0xfc34 in local1 ROMHDT:0059 LDCI $3CC ; | ROMHDT:005C NGI ; | ROMHDT:005D STO ; |------ ROMHDT:005E loc_25E ROMHDT:005E CPL 3 ; reset FDC and DMA ROMHDT:0060 CPL 3 ; reset FDC and DMA ROMHDT:0062 CPL 3 ; reset FDC and DMA ROMHDT:0062 ; (now it should be really done!) ROMHDT:0062 ; ROMHDT:0064 SLDL 1 ; address FDC 0xfc34 ROMHDT:0065 LDCI $410F ; command RESTORE with head load ROMHDT:0068 SLDL 2 ; merge in unit number ROMHDT:0069 ADI ; | ROMHDT:006A STO ; send command ROMHDT:006A ; |----- ROMHDT:006B loc_26B ROMHDT:006B SLDC 3 ; store 3*4 into temporary ROMHDT:006C SLDC 4 ; | waste some time ROMHDT:006D MPI ROMHDT:006E STL 7 ; |----- ROMHDT:006E ; ROMHDT:0070 SLDL 1 ; get FDC status (0xfc34) ROMHDT:0071 SIND 0 ROMHDT:0072 LNOT ROMHDT:0073 FJP loc_26B ; wait until not busy ROMHDT:0073 ; |------ ROMHDT:0073 ; ROMHDT:0075 SLDL 1 ; program DMA byte count = 0xf300 -> 0xd00 bytes ROMHDT:0076 INC 6 ; | ROMHDT:0078 SLDC 0 ; | ROMHDT:0079 STO ; | ROMHDT:007A SLDL 1 ; | ROMHDT:007B INC 7 ; | ROMHDT:007D SLDC $D ; | 0xf3 ROMHDT:007E NGI ; | ROMHDT:007F STO ; |----- ROMHDT:007F ; ROMHDT:0080 SLDL 1 ; program DMA address = 2*loadbase ROMHDT:0081 INC 8 ; | ROMHDT:0083 SLDL 6 ; | ROMHDT:0084 SLDL 6 ; | ROMHDT:0085 ADI ; | multiply by 2 ROMHDT:0086 STO ; | store low byte only ROMHDT:0087 SLDL 1 ; | ROMHDT:0088 INC 9 ; | ROMHDT:008A SLDL 6 ; | ROMHDT:008B SLDL 6 ; | ROMHDT:008C ADI ; | ROMHDT:008D LDCI $100 ; | shift 8 bit right ROMHDT:0090 DVI ; | ROMHDT:0091 STO ; |----- store into high byte ROMHDT:0091 ; ROMHDT:0092 SLDL 1 ; clear address extension 0xfc3e ROMHDT:0093 INC $A ; | ROMHDT:0095 SLDC 0 ; | ROMHDT:0096 STO ; |----- ROMHDT:0096 ; ROMHDT:0097 SLDL 1 ; clear DMA status (0xfc39) ROMHDT:0098 INC 5 ; | ROMHDT:009A SLDC 0 ; | ROMHDT:009B STO ; |------ ROMHDT:009B ; ROMHDT:009C SLDL 1 ; program DMA CTRLR for RUN, IOM=fdc-to-ram ROMHDT:009D INC 4 ; | ROMHDT:009F SLDC $11 ; | ROMHDT:00A0 STO ; |----- ROMHDT:00A0 ; ROMHDT:00A1 SLDL 1 ; program FDC sector = 1 ROMHDT:00A2 INC 2 ; | ROMHDT:00A4 SLDC 1 ; | ROMHDT:00A5 STO ; |------ ROMHDT:00A5 ; ROMHDT:00A6 SLDL 1 ; program FDC CMD = READ SECTOR ROMHDT:00A7 LDCI $4194 ; | ROMHDT:00AA SLDL 2 ; | merge in unit number ROMHDT:00AB ADI ; | ROMHDT:00AC STO ; |------ send command ROMHDT:00AD loc_2AD ROMHDT:00AD SLDL 1 ; address DMA status (0xfc39) ROMHDT:00AE SIND 5 ; | ROMHDT:00AF SLDC $A ; | read and mask bits TCZI and DINT ROMHDT:00B0 LAND ; | ROMHDT:00B1 SLDC 0 ; | ROMHDT:00B2 NEQI ; | ROMHDT:00B3 FJP loc_2AD ; | wait until completed or count zero ROMHDT:00B3 ; |------ ROMHDT:00B3 ; ROMHDT:00B5 SLDL 1 ; address DMA status (0xfc39) ROMHDT:00B6 SIND 5 ; | ROMHDT:00B7 SLDC 8 ; | check bit TCZI ROMHDT:00B8 LAND ; | ROMHDT:00B9 SLDC 0 ; | ROMHDT:00BA EQUI ; | ROMHDT:00BB FJP exitic_bootfd ; if finished, exit ROMHDT:00BD UJPL loc_25E ; retry boot ROMHDT:00C0 exitic_bootfd ROMHDT:00C0 RPU 7 ; exit from boot ROMHDT:00C2 ; procedure emit(ch: char); ROMHDT:00C2 ; write a char to console ROMHDT:00C2 .CPTR exitic_emit ; exitic ROMHDT:00C4 emit .WORD $0003 ; # of words ROMHDT:00C6 emitloop SLDO 4 ; load 0xfc12 (console status) ROMHDT:00C7 SIND 2 ; | ROMHDT:00C8 SLDC 1 ; mask bit transmitter buffer empty ROMHDT:00C9 LAND ; | ROMHDT:00CA SLDC 0 ; if bit==1 loop (transmitter busy) ROMHDT:00CB EQUI ; | ROMHDT:00CC FJP emitloop ; |------ ROMHDT:00CE SLDO 4 ; address 0xfc13 (xmit buffer) ROMHDT:00CF INC 3 ; | ROMHDT:00D1 LDCB $FF ; store 255-ord(ch) to xmit buffer ROMHDT:00D3 SLDL 4 ; (negative logic) ROMHDT:00D4 SBI ; | ROMHDT:00D5 STO ; |----- ROMHDT:00D6 exitic_emit ; return ROMHDT:00D6 RPU 4 ROMHDT:00D8 ; procedure inchar; ROMHDT:00D8 ; wait and read char from console ROMHDT:00D8 ; convert to upper case and ROMHDT:00D8 ; store in global1 ROMHDT:00D8 .CPTR exitic_inchar ; exitic ROMHDT:00DA inchar .WORD $0000 ; # of words ROMHDT:00DC sub_2DC ROMHDT:00DC SLDO 4 ; load 0xfc12 (console status) ROMHDT:00DD SIND 2 ; | ROMHDT:00DE SLDC 2 ; mask bit receiver buffer full ROMHDT:00DF LAND ; | ROMHDT:00E0 SLDC 0 ; if bit=1, loop ROMHDT:00E1 EQUI ; | ROMHDT:00E2 FJP sub_2DC ; |------ ROMHDT:00E4 LDCB $7F ; negate mask ROMHDT:00E6 SLDO 4 ; read 0xfc13 (recv buffer) ROMHDT:00E7 SIND 3 ; | ROMHDT:00E8 LDCB $7F ; mask 7 bits ROMHDT:00EA LAND ; | ROMHDT:00EB SBI ; negate char ROMHDT:00EC SRO 1 ; save in char buffer ROMHDT:00EE SLDO 1 ; get char ROMHDT:00EF LDCB 'a' ; is it lower case? ROMHDT:00F1 GEQI ; | ROMHDT:00F2 FJP loc_2FA ; |------ no, skip ROMHDT:00F4 SLDO 1 ; get char ROMHDT:00F5 LDCB $20 ; convert to upper case ROMHDT:00F7 SBI ; | ROMHDT:00F8 SRO 1 ; store ROMHDT:00FA loc_2FA ROMHDT:00FA SLDO 1 ; get char ROMHDT:00FB CPG 4 ; echo to terminal ROMHDT:00FD ROMHDT:00FD exitic_inchar ; exit ROMHDT:00FD RPU 0 ROMHDT:00FF .ALIGN ROMHDT:0100 ; procedure printhex(num: integer); ROMHDT:0100 ; ROMHDT:0100 ; local stack frame: ROMHDT:0100 ; local1 temporary for argument ROMHDT:0100 ; is variant record (integer, packed array(1..4) of 0..15) ROMHDT:0100 ; local2 dummy ROMHDT:0100 ; local3 dummy ROMHDT:0100 ; local4 dummy ROMHDT:0100 ; argument5 num to print ROMHDT:0100 .CPTR exitic_printhex ; exitic ROMHDT:0102 printhex .WORD $0004 ; # of words ROMHDT:0104 SLDL 5 ; get argument ROMHDT:0105 STL 1 ; save in local1 ROMHDT:0107 LAO 9 ; hex string ROMHDT:0109 LLA 1 ; get argument ROMHDT:010B SLDC 4 ; get array(4) ROMHDT:010C SLDC $C ; | ROMHDT:010D LDP ; |------ ROMHDT:010D ; ROMHDT:010E LDB ; index into hex table ROMHDT:010F CPG 4 ; emit char ROMHDT:0111 LAO 9 ; hex string ROMHDT:0113 LLA 1 ; get argument ROMHDT:0115 SLDC 4 ; get array(3) ROMHDT:0116 SLDC 8 ; | ROMHDT:0117 LDP ; |------ ROMHDT:0117 ; ROMHDT:0118 LDB ; index into hex table ROMHDT:0119 CPG 4 ; emit char ROMHDT:011B LAO 9 ; hex table ROMHDT:011D LLA 1 ; get argument ROMHDT:011F SLDC 4 ; array(2) ROMHDT:0120 SLDC 4 ; | ROMHDT:0121 LDP ; |------ ROMHDT:0121 ; ROMHDT:0122 LDB ; index into hex table ROMHDT:0123 CPG 4 ; emit char ROMHDT:0125 LAO 9 ; hex table ROMHDT:0127 LLA 1 ; get argument ROMHDT:0129 SLDC 4 ; as array(1) ROMHDT:012A SLDC 0 ; | ROMHDT:012B LDP ; |------ ROMHDT:012B ; ROMHDT:012C LDB ; index into hex table ROMHDT:012D CPG 4 ; emit char ROMHDT:012F exitic_printhex ; exit ROMHDT:012F RPU 5 ROMHDT:0131 .ALIGN ROMHDT:0132 .CPTR exitic_print_addr_val ; exitic ROMHDT:0134 print_addr_val .WORD $0000 ; # of words ROMHDT:0136 SLDO 5 ; get current address ROMHDT:0137 CPG 6 ; printhex ROMHDT:0139 LDCB '/' ; emit / ROMHDT:013B CPG 4 ; |------ ROMHDT:013B ; ROMHDT:013D SLDO 5 ; get current address ROMHDT:013E SIND 0 ; dereference ROMHDT:013F CPG 6 ; printhex ROMHDT:0141 LDCB ' ' ; emit space ROMHDT:0143 CPG 4 ; |------ ROMHDT:0145 exitic_print_addr_val ; exit ROMHDT:0145 RPU 0 ROMHDT:0147 .ALIGN ROMHDT:0148 ; function getnumber : integer; ROMHDT:0148 ; read characters until no more hex digit ROMHDT:0148 ; return complete number in global2 ROMHDT:0148 ; set flag hasnumber (global3) ROMHDT:0148 ; ROMHDT:0148 ; local stack frame ROMHDT:0148 ; local1 number buffer ROMHDT:0148 ; variant record (integer, packed array(1..4) of 0..15) ROMHDT:0148 ; local2 ROMHDT:0148 ; local3 ROMHDT:0148 ; local4 ROMHDT:0148 ; return value5 ROMHDT:0148 .CPTR exitic_getnumber ; exitic ROMHDT:014A getnumber .WORD $0004 ; # of words ROMHDT:014C SLDC 0 ; clear number collect buffer ROMHDT:014D STL 1 ; |------ ROMHDT:014F loc_34F ROMHDT:014F LLA 1 ; shift array(3) to array(4) ROMHDT:0151 SLDC 4 ; | ROMHDT:0152 SLDC $C ; | ROMHDT:0153 LLA 1 ; | ROMHDT:0155 SLDC 4 ; | ROMHDT:0156 SLDC 8 ; | ROMHDT:0157 LDP ; | ROMHDT:0158 STP ; |------ ROMHDT:0158 ; ROMHDT:0159 LLA 1 ; shift array(2) to array(3) ROMHDT:015B SLDC 4 ; | ROMHDT:015C SLDC 8 ; | ROMHDT:015D LLA 1 ; | ROMHDT:015F SLDC 4 ; | ROMHDT:0160 SLDC 4 ; | ROMHDT:0161 LDP ; | ROMHDT:0162 STP ; |------ ROMHDT:0162 ; ROMHDT:0163 LLA 1 ; shift array(1) to array(2) ROMHDT:0165 SLDC 4 ; | ROMHDT:0166 SLDC 4 ; | ROMHDT:0167 LLA 1 ; | ROMHDT:0169 SLDC 4 ; | ROMHDT:016A SLDC 0 ; | ROMHDT:016B LDP ; | ROMHDT:016C STP ; |------ ROMHDT:016C ; ROMHDT:016D SLDO 1 ; get char read ROMHDT:016E LDCB $39 ; is it > '9'? ROMHDT:0170 LEQI ; | ROMHDT:0171 FJP loc_37E ; yes, skip ROMHDT:0173 LLA 1 ; put ord(char)-ord('0') into array(1) ROMHDT:0175 SLDC 4 ; | ROMHDT:0176 SLDC 0 ; | ROMHDT:0177 SLDO 1 ; | ROMHDT:0178 LDCB '0' ; | ROMHDT:017A SBI ; | ROMHDT:017B STP ; |------ ROMHDT:017B ; ROMHDT:017C UJP loc_389 ; skip ROMHDT:017E loc_37E ROMHDT:017E LLA 1 ; put ord(char)-ord('A')+10 into array(1) ROMHDT:0180 SLDC 4 ; | ROMHDT:0181 SLDC 0 ; | ROMHDT:0182 SLDO 1 ; | ROMHDT:0183 LDCB 'A' ; | ROMHDT:0185 SBI ; | ROMHDT:0186 SLDC 10 ; | ROMHDT:0187 ADI ; | ROMHDT:0188 STP ; |------ ROMHDT:0189 loc_389 ROMHDT:0189 CPG 5 ; wait for another char ROMHDT:018B SLDO 1 ; loop until char not in ['0'..'9','A'..'F'] ROMHDT:018C LAO 17 ; | ROMHDT:018E LDM 5 ; | ROMHDT:0190 SLDC 5 ; | ROMHDT:0191 INN ; | ROMHDT:0192 LNOT ; | ROMHDT:0193 FJP loc_34F ; |------ ROMHDT:0193 ; ROMHDT:0195 SLDL 1 ; return number ROMHDT:0196 STL 5 ; |------ ROMHDT:0198 exitic_getnumber ; exit ROMHDT:0198 RPU 4 ROMHDT:019A .CPTR exitic_reboot ; exitic ROMHDT:019C reboot .WORD $0001 ; # of words ROMHDT:019E SLDO 3 ; was a number entered? (boot unit) ROMHDT:019F LNOT ; |------ ROMHDT:019F ; ROMHDT:01A0 FJP loc_3A5 ; yes, skip ROMHDT:01A2 SLDC 0 ; no: clear number buffer ROMHDT:01A3 SRO 2 ; |------ ROMHDT:01A5 loc_3A5 ROMHDT:01A5 SLDO 6 ; address of HDT info area ROMHDT:01A6 SLDO 2 ; boot unit ROMHDT:01A7 STO ; store in element0 ROMHDT:01A7 ; |------ ROMHDT:01A7 ; ROMHDT:01A8 LDCI $2000 ; store 0x2000 as local1 ROMHDT:01AB STL 1 ; |------ ROMHDT:01AB ; ROMHDT:01AD SLDO 2 ; get boot unit ROMHDT:01AE SLDL 1 ; get start address ROMHDT:01AF CPG 2 ; call bootsetup ROMHDT:01AF ; ROMHDT:01B1 SLDL 1 ; increment address by 8 ROMHDT:01B2 SLDC 8 ; | ROMHDT:01B3 ADI ; | ROMHDT:01B4 SRO 5 ; store into temporary global ROMHDT:01B4 ; |------ ROMHDT:01B6 SLDO 5 ; get address 0x2008 (TIB->SEGB) ROMHDT:01B7 SLDO 5 ; get SEGB value ROMHDT:01B8 SIND 0 ; | ROMHDT:01B9 SLDC $C ; add 12 (point to start of boot segment) ROMHDT:01BA ADI ; |------ ROMHDT:01BB STO ROMHDT:01BC LDCI -3 ; store loaded boot TIB as next RQ ROMHDT:01BF SLDL 1 ROMHDT:01C0 SPR ROMHDT:01C1 LAO 7 ; context switch to boot loader ROMHDT:01C3 WAIT ROMHDT:01C4 exitic_reboot ; probably not reached ROMHDT:01C4 RPU 1 ROMHDT:01C6 word_3C6 .WORD $0000 ; case low index ROMHDT:01C8 .WORD $0007 ; case low index ROMHDT:01CA .WORD $0002 ; case idx 0 loc_484 ROMHDT:01CC .WORD $0007 ; case idx 1 loc_489 ROMHDT:01CE .WORD $000c ; case idx 2 loc_48E ROMHDT:01D0 .WORD $0011 ; case idx 3 loc_493 ROMHDT:01D2 .WORD $0016 ; case idx 4 loc_498 ROMHDT:01D4 .WORD $001c ; case idx 5 loc_49E ROMHDT:01D6 .WORD $0022 ; case idx 6 loc_4A4 ROMHDT:01D8 .WORD $0028 ; case idx 7 loc_4AA ROMHDT:01DA a0123456789abcd .ASC '0123456789ABCDEF' ROMHDT:01EA hexset .WORD $0000 ROMHDT:01EC .WORD $0000 ROMHDT:01EE .WORD $0000 ROMHDT:01F0 .WORD $03ff ROMHDT:01F2 .WORD $007e ROMHDT:01F4 ; procedure init; ROMHDT:01F4 ; stack frame ROMHDT:01F4 ; local1 for timer0 high value ROMHDT:01F4 ; local2 for console CTRL1 reg ROMHDT:01F4 ; local3 coldstart flag ROMHDT:01F4 ; local4 temporary ROMHDT:01F4 .CPTR exitic_init ; exitic ROMHDT:01F6 init .WORD $0004 ; # of words ROMHDT:01F8 LAO 7 ; ROMHDT:01F8 ; initialize ROMHDT semaphore ROMHDT:01FA DUP1 ; | seminit(global7,0) ROMHDT:01FB SLDC 0 ; | ROMHDT:01FC STO ; | ROMHDT:01FD INC 1 ; | ROMHDT:01FF LDCN ; | ROMHDT:0200 STO ; |------ ROMHDT:0200 ; ROMHDT:0201 LDCI $3F0 ; store 0xfc10 in temporary ROMHDT:0204 NGI ; | ROMHDT:0205 STL 4 ; |------ ROMHDT:0205 ; ROMHDT:0207 SLDL 4 ; save address of console (0xfc10) in global4 ROMHDT:0208 SRO 4 ; |------ ROMHDT:0208 ; ROMHDT:020A SLDO 4 ; load 0xfc18 (system envirenment switch) ROMHDT:020B IND 8 ; | ROMHDT:020D LDCB $80 ; mask bit 7 (BOOT INTO HDT) ROMHDT:020F LAND ; | ROMHDT:0210 SLDC 0 ; | ROMHDT:0211 EQUI ; |------ ROMHDT:0211 ; ROMHDT:0212 FJP loc_429 ; if not zero skip ROMHDT:0214 LDCI -3 ; address RQ register for SPR ROMHDT:0217 LDCI $4000 ; |set 0x4000 or 0xc020 into RQ ROMHDT:021A LDCI $401 ; | ROMHDT:021D SLDO 4 ; |depending on bit 6 of SES ROMHDT:021E IND 8 ; | ROMHDT:0220 LDCB $20 ; | ROMHDT:0222 LAND ; | ROMHDT:0223 MPI ; | ROMHDT:0224 ADI ; | if bit5=1 then 0xc020 else 0x4000 ROMHDT:0225 SPR ; | set this into RQ register ROMHDT:0225 ; ROMHDT:0226 LAO 7 ; wait on HDT semaphore - context switch ROMHDT:0228 WAIT ; |------ ROMHDT:0229 loc_429 ROMHDT:0229 LDCB $22 ; HDT info area ROMHDT:022B SRO 6 ; save in global6 ROMHDT:022D SLDO 6 ; get element0 ROMHDT:022E SIND 0 ; | ROMHDT:022F SLDO 6 ; get element1 ROMHDT:0230 SIND 1 ; | ROMHDT:0231 ADI ; add both ROMHDT:0232 LDCI $4005 ROMHDT:0235 NGI ; compare with 0xbffb ROMHDT:0235 ; (is possibly the load address when loaded as a segment) ROMHDT:0236 EQUI ; | ROMHDT:0237 STL 3 ; store temp (true if warm start) ROMHDT:0239 SLDL 3 ; | ROMHDT:023A FJP loc_448 ; if this is a warm start then ROMHDT:023C LDCI $FFFE ; address SSV for SPR ROMHDT:023F SLDO 6 ; get SSV value from HDT info area elemet2 ROMHDT:0240 SIND 2 ; |------ ROMHDT:0240 ; ROMHDT:0241 SPR ; set new SEGB table ROMHDT:0242 LDCI -3 ; address RQ for SPR ROMHDT:0245 SLDO 6 ; get RQ value from HDT info area element3 ROMHDT:0246 SIND 3 ; | ROMHDT:0247 SPR ; set new RQ ROMHDT:0248 loc_448 ROMHDT:0248 SLDL 3 ; if not a linked module or sema count set ROMHDT:0249 LNOT ; | ROMHDT:024A SLDO 6 ; | ROMHDT:024B SIND 0 ; | ROMHDT:024C LOR ; |----- ROMHDT:024D FJPL loc_4F1 ; then ROMHDT:0250 LDCI $3E0 ; store 0xfc20 in temporary ROMHDT:0253 NGI ; | ROMHDT:0254 STL 4 ; |------ ROMHDT:0254 ; ROMHDT:0256 SLDL 4 ; address 0xfc24 (system status register) ROMHDT:0257 INC 4 ; | ROMHDT:0259 LDCB $80 ; enforce BUS RESET ROMHDT:025B STO ; |------ ROMHDT:025B ; ROMHDT:025C SLDL 4 ; address 0xfc24 (system status register) ROMHDT:025D INC 4 ; | ROMHDT:025F SLDC 1 ; clear BERR condition by writing a 1 ROMHDT:0260 STO ; |------ ROMHDT:0260 ; ROMHDT:0261 SLDL 4 ; program timer0 for 16bit binary mode 2 ROMHDT:0262 INC 3 ; | ROMHDT:0264 LDCB $34 ; | ROMHDT:0266 STO ; |------ ROMHDT:0266 ; ROMHDT:0267 SLDL 4 ; program timer1 for 16 bit binary mode 0 ROMHDT:0268 INC 3 ; | ROMHDT:026A LDCB $70 ; | ROMHDT:026C STO ; |------ ROMHDT:026C ; ROMHDT:026D SLDL 4 ; program timer2 for 16 bit binary mode 0 ROMHDT:026E INC 3 ; | ROMHDT:0270 LDCB $B0 ; | ROMHDT:0272 STO ; |------ ROMHDT:0272 ; ROMHDT:0273 SLDC 0 ; preload high value of baud rate counter (timer0) ROMHDT:0274 STL 1 ; |------ ROMHDT:0274 ; ROMHDT:0276 LDCB $58 ; preload default value for console CTRL1 ROMHDT:0276 ; normal mode, no break, 1 stop bit, clock mode 1 ROMHDT:0278 STL 2 ; |------ ROMHDT:0278 ; ROMHDT:027A SLDO 4 ; read system environment switch ROMHDT:027B IND 8 ; | ROMHDT:027D SLDC 7 ; mask out low 3 bits ROMHDT:027E LAND ; | ROMHDT:027F XJP word_3C6 ; case of low bits ROMHDT:0282 loc_482 ; | otherwise clause (compiler generated - not needed) ROMHDT:0282 UJP loc_4B7 ROMHDT:0284 loc_484 ROMHDT:0284 SLDL 4 ; case 0: ROMHDT:0284 ; | set low baudrate val for 19200 ROMHDT:0285 SLDC 2 ; | ROMHDT:0286 STO ; | ROMHDT:0287 UJP loc_4B7 ; |------ ROMHDT:0289 loc_489 ROMHDT:0289 SLDL 4 ; case 1: ROMHDT:0289 ; | set low baudrate val for 9600 ROMHDT:028A SLDC 4 ; | ROMHDT:028B STO ; | ROMHDT:028C UJP loc_4B7 ; |------ ROMHDT:028E loc_48E ROMHDT:028E SLDL 4 ; case 2: ROMHDT:028E ; | set low baudrate val for 4800 ROMHDT:028F SLDC 8 ; | ROMHDT:0290 STO ; | ROMHDT:0291 UJP loc_4B7 ; |------ ROMHDT:0293 loc_493 ROMHDT:0293 SLDL 4 ; case 3: ROMHDT:0293 ; | set low baudrate val for 2400 ROMHDT:0294 SLDC $10 ; | ROMHDT:0295 STO ; | ROMHDT:0296 UJP loc_4B7 ; |------ ROMHDT:0298 loc_498 ROMHDT:0298 SLDL 4 ; case 4: ROMHDT:0298 ; | set low baudrate val for 1200 ROMHDT:0299 LDCB $21 ; | ROMHDT:029B STO ; | ROMHDT:029C UJP loc_4B7 ; |------ ROMHDT:029E loc_49E ROMHDT:029E SLDL 4 ; case 5: ROMHDT:029E ; | set low baudrate val for 600 ROMHDT:029F LDCB $41 ; | ROMHDT:02A1 STO ; | ROMHDT:02A2 UJP loc_4B7 ; |------ ROMHDT:02A4 loc_4A4 ROMHDT:02A4 SLDL 4 ; case 6: ROMHDT:02A4 ; | set low baudrate val for 300 ROMHDT:02A5 LDCB $82 ; | ROMHDT:02A7 STO ; | ROMHDT:02A8 UJP loc_4B7 ; |------ ROMHDT:02AA loc_4AA ROMHDT:02AA SLDL 4 ; case 7: ROMHDT:02AA ; | set low baudrate val for 110 ROMHDT:02AB LDCB $5D ; | ROMHDT:02AD STO ; | ROMHDT:02AE SLDC 1 ; | fix high val for baudrate counter ROMHDT:02AF STL 1 ; | ROMHDT:02B1 LDCB $78 ; | set console CTRL1 as above, except 2 stop bits ROMHDT:02B3 STL 2 ; | ROMHDT:02B5 UJP loc_4B7 ; |------ ROMHDT:02B7 loc_4B7 ROMHDT:02B7 SLDL 4 ; set high value into baudrate counter ROMHDT:02B8 SLDL 1 ; | ROMHDT:02B9 STO ; |------ ROMHDT:02B9 ; ROMHDT:02BA SLDL 4 ; program timer1 with 0x0001 ROMHDT:02BB INC 1 ; | ROMHDT:02BD SLDC 1 ; | ROMHDT:02BE STO ; | ROMHDT:02BF SLDL 4 ; | ROMHDT:02C0 INC 1 ; | ROMHDT:02C2 SLDC 0 ; | ROMHDT:02C3 STO ; |------ ROMHDT:02C3 ; ROMHDT:02C4 SLDL 4 ; program timer 2 with 0x0001 ROMHDT:02C5 INC 2 ; | ROMHDT:02C7 SLDC 1 ; | ROMHDT:02C8 STO ; | ROMHDT:02C9 SLDL 4 ; | ROMHDT:02CA INC 2 ; | ROMHDT:02CC SLDC 0 ; | ROMHDT:02CD STO ; |------ ROMHDT:02CD ; ROMHDT:02CE SLDO 4 ; address 0xfc12 (DLE register) ROMHDT:02CF INC 2 ; |------ ROMHDT:02CF ; ROMHDT:02D1 SLDO 4 ; load 0xfc12 (status register) ROMHDT:02D2 SIND 2 ; |------ ROMHDT:02D2 ; ROMHDT:02D3 STO ; | clear DLE register ROMHDT:02D4 SLDO 4 ; load CTRL1 register 0xfc10 with 0x58/0x78 ROMHDT:02D5 SLDL 2 ; | ROMHDT:02D6 STO ; |------ ROMHDT:02D6 ; ROMHDT:02D7 SLDO 4 ; program CTRL2 register with async mode... ROMHDT:02D8 INC 1 ; | ROMHDT:02DA LDCB $FE ; | ROMHDT:02DC STO ; |------ ROMHDT:02DC ; ROMHDT:02DD SLDL 3 ; if not warm start, skip ROMHDT:02DE FJP loc_4E3 ; otherwise halt on HDT semaphore ROMHDT:02E0 LAO 7 ; | ROMHDT:02E2 WAIT ; |------ ROMHDT:02E3 loc_4E3 ROMHDT:02E3 SLDL 4 ; load 0xfc24 (system status register) ROMHDT:02E4 SIND 4 ; | ROMHDT:02E5 LDCB $80 ; mask out status of E13 jumper ROMHDT:02E7 LAND ; | ROMHDT:02E8 SLDC 0 ; | ROMHDT:02E9 EQUI ; |------ ROMHDT:02E9 ; ROMHDT:02EA FJP loc_4F1 ; if E13 is jumpered to 0 then ROMHDT:02EC SLDC 0 ; reset 'hasnumber' flag -> boot from Unit 0 ROMHDT:02ED SRO 3 ; |------ ROMHDT:02ED ; ROMHDT:02EF CPG 9 ; reboot from primary unit ROMHDT:02F1 loc_4F1 ROMHDT:02F1 LAO 9 ; setup hexcode conversion table ROMHDT:02F3 LCA a0123456789abcd ; | into global9-16 ROMHDT:02F6 MOV 8 ; |------ ROMHDT:02F6 ; ROMHDT:02F8 LAO 17 ; set HEX member set ['0'..'9','A'..'F'] ROMHDT:02FA LDC hexset,5 ; | into global17-21 ROMHDT:02FE SLDC 5 ; | ROMHDT:02FF ADJ 5 ; | ROMHDT:0301 STM 5 ; |------ ROMHDT:0303 exitic_init ; exit ROMHDT:0303 RPU 4 ROMHDT:0305 .ALIGN ROMHDT:0306 .CPTR exitic_mainloop ; exitic ROMHDT:0308 mainloop .WORD $0000 ; # of words ROMHDT:030A CPG $A ; call init ROMHDT:030C loc_50C ROMHDT:030C SLDC $D ; emit CR ROMHDT:030D CPG 4 ; |------ ROMHDT:030D ; ROMHDT:030F SLDC $A ; emit LF ROMHDT:0310 CPG 4 ; |------ ROMHDT:0310 ; ROMHDT:0312 LDCB '#' ; emit prompt ROMHDT:0314 CPG 4 ; |------ ROMHDT:0316 loc_516 ROMHDT:0316 SLDC 0 ; clear number store ROMHDT:0317 SRO 2 ; |------ ROMHDT:0317 ; ROMHDT:0319 SLDC 0 ; clear flag 'hasnumber' ROMHDT:031A SRO 3 ; |------ ROMHDT:031A ; ROMHDT:031C CPG 5 ; wait for char ROMHDT:031C ; ROMHDT:031E SLDO 1 ; if char in ['0'..'9','A'..'F'] then ROMHDT:031F LAO $11 ; | ROMHDT:0321 LDM 5 ; | ROMHDT:0323 SLDC 5 ; | ROMHDT:0324 INN ; | ROMHDT:0325 FJP loc_52F ; |----- ROMHDT:0327 SLDC 0 ; return value ROMHDT:0328 CPG 8 ; read a complete hex number ROMHDT:032A SRO 2 ; save in number store ROMHDT:032C SLDC 1 ; set flag 'hasnumber' ROMHDT:032D SRO 3 ; |------ ROMHDT:032F loc_52F ROMHDT:032F SLDO 1 ; get char ROMHDT:0330 LDCB 'R' ; is it 'R'? ROMHDT:0332 EQUI ; |------ ROMHDT:0332 ; ROMHDT:0333 FJP loc_537 ; no, skip ROMHDT:0335 CPG 9 ; call reboot ROMHDT:0337 loc_537 ROMHDT:0337 SLDO 1 ; get char ROMHDT:0338 LDCB 'P' ; is it 'P' ? ROMHDT:033A EQUI ; |------ ROMHDT:033A ; ROMHDT:033B FJP loc_540 ; no, skip ROMHDT:033D LAO 7 ; wait on HDT semaphore -> context switch ROMHDT:033F WAIT ROMHDT:0340 loc_540 ROMHDT:0340 SLDO 1 ; get char ROMHDT:0341 SLDC $D ; is it CR? ROMHDT:0342 EQUI ; |------ ROMHDT:0342 ; ROMHDT:0343 FJP loc_54E ; no, skip ROMHDT:0345 SLDO 3 ; has address? ROMHDT:0346 FJP loc_54B ; no, loop ROMHDT:0348 SLDO 5 ; get current address ROMHDT:0349 SLDO 2 ; get number ROMHDT:034A STO ; store number at address ROMHDT:034B loc_54B ROMHDT:034B UJPL loc_5BA ; loop ROMHDT:034E loc_54E ROMHDT:034E SLDO 1 ; get char ROMHDT:034F LDCB '/' ; is it slash? ROMHDT:0351 EQUI ; |------ ROMHDT:0352 FJP loc_565 ; no, skip ROMHDT:0354 SLDO 3 ; number entered? ROMHDT:0355 FJP loc_55A ; no, skip ROMHDT:0357 SLDO 2 ; save entered number into "current address" ROMHDT:0358 SRO 5 ; |----- ROMHDT:035A loc_55A ROMHDT:035A SLDO 5 ; get current address ROMHDT:035B SIND 0 ; load value from it ROMHDT:035C CPG 6 ; printhex ROMHDT:035E LDCB ' ' ; emit space ROMHDT:0360 CPG 4 ; |------ ROMHDT:0362 UJPL loc_516 ; loop to modify ROMHDT:0365 loc_565 ROMHDT:0365 SLDO 1 ; get char ROMHDT:0366 LDCB '@' ; is it @? ROMHDT:0368 EQUI ; |----- ROMHDT:0368 ; ROMHDT:0369 FJP loc_582 ; no, skip ROMHDT:036B SLDO 3 ; has a number? ROMHDT:036C FJP loc_573 ; no, skip ROMHDT:036E SLDO 2 ; load number ROMHDT:036F SRO 5 ; store as new location ROMHDT:0371 UJP loc_577 ; skip ROMHDT:0373 loc_573 ROMHDT:0373 SLDO 5 ; get current address ROMHDT:0374 SIND 0 ; dereference ROMHDT:0375 SRO 5 ; becomes new current address ROMHDT:0377 loc_577 ROMHDT:0377 SLDC $D ; emit CR ROMHDT:0378 CPG 4 ; |------ ROMHDT:0378 ; ROMHDT:037A SLDC $A ; emit LF ROMHDT:037B CPG 4 ; |------ ROMHDT:037B ; ROMHDT:037D CPG 7 ; print address and value ROMHDT:037F UJPL loc_516 ; loop ROMHDT:0382 loc_582 ROMHDT:0382 SLDO 1 ; get char ROMHDT:0383 SLDC $A ; is LF? ROMHDT:0384 EQUI ; |------ ROMHDT:0384 ; ROMHDT:0385 FJP loc_59A ; no, skip ROMHDT:0387 SLDO 3 ; has number? ROMHDT:0388 FJP loc_58D ; no, skip ROMHDT:038A SLDO 5 ; store number at current address ROMHDT:038B SLDO 2 ; | ROMHDT:038C STO ; |------ ROMHDT:038D loc_58D ROMHDT:038D SLDO 5 ; get current address ROMHDT:038E SLDC 1 ; increment ROMHDT:038F ADI ; |------ ROMHDT:038F ; ROMHDT:0390 SRO 5 ; store it back ROMHDT:0392 SLDC $D ; emit CR ROMHDT:0393 CPG 4 ; |------ ROMHDT:0393 ; Note: shouldn't it emit LF as well? ROMHDT:0393 ; ROMHDT:0395 CPG 7 ; print address and value ROMHDT:0397 UJPL loc_516 ; loop ROMHDT:039A loc_59A ROMHDT:039A SLDO 1 ; get char ROMHDT:039B LDCB '^' ; is it ^? ROMHDT:039D EQUI ; |------ ROMHDT:039E FJP loc_5B6 ; no, skip ROMHDT:03A0 SLDO 3 ; has a number? ROMHDT:03A1 FJP loc_5A6 ; no, skip ROMHDT:03A3 SLDO 5 ; store number at current address ROMHDT:03A4 SLDO 2 ; | ROMHDT:03A5 STO ; |------ ROMHDT:03A6 loc_5A6 ROMHDT:03A6 SLDO 5 ; get current address ROMHDT:03A7 SLDC 1 ; decrement ROMHDT:03A8 SBI ; |------ ROMHDT:03A8 ; ROMHDT:03A9 SRO 5 ; store it back ROMHDT:03AB SLDC $D ; emit CR ROMHDT:03AC CPG 4 ; |------ ROMHDT:03AE SLDC $A ; emit LF ROMHDT:03AF CPG 4 ; |------ ROMHDT:03B1 CPG 7 ; print address and number ROMHDT:03B3 UJPL loc_516 ; loop ROMHDT:03B6 loc_5B6 ROMHDT:03B6 LDCB '?' ; unknown command ROMHDT:03B8 CPG 4 ; emit ? ROMHDT:03BA loc_5BA ROMHDT:03BA SLDC 0 ; jump HDT input loop ROMHDT:03BB FJPL loc_50C ROMHDT:03BE exitic_mainloop ROMHDT:03BE RPU 1 ROMHDT:03C0 .WPTR init ; Entry proc# 10 ROMHDT:03C2 .WPTR reboot ; Entry proc# 9 ROMHDT:03C4 .WPTR getnumber ; Entry proc# 8 ROMHDT:03C6 .WPTR print_addr_val ; Entry proc# 7 ROMHDT:03C8 .WPTR printhex ; Entry proc# 6 ROMHDT:03CA .WPTR inchar ; Entry proc# 5 ROMHDT:03CC .WPTR emit ; Entry proc# 4 ROMHDT:03CE .WPTR init_fd_dma ; Entry proc# 3 ROMHDT:03D0 .WPTR bootfd ; Entry proc# 2 ROMHDT:03D2 .WPTR mainloop ; Entry proc# 1 ROMHDT:03D4 byte_5D4 .BYTE $80 ; Segment Number ROMHDT:03D5 .BYTE $0a ; # of procedures ROMHDT:03D6 .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; padding ROMHDT:03D6 .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ROMHDT:03D6 .BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ROMHDT:03D6 ; END OF SEGMENT