AORG >4000 4000 AA01 DATA >AA01 ; Version 1 4002 0000 DATA >0000 ; No programs 4004 4030 DATA >4030 ; reset list 4006 0000 DATA >0000 4008 4036 DATA >4036 ; DSR list 400A 0000 DATA >0000 400C 4064 DATA >4064 ; INT list 400E 0000 DATA >0000 4010 0460 B @>4A9A ; INT routine 4012 4A9A 4014 0460 B @>40DA ; Hexbus DSR routine 4016 40DA ; jump vector table (unused in ROM itself) ; 4018 4966 ; start hexbus transaction 401A 4994 ; send byte on hexbus 401C 4D5C ; test IRQ signal 401E 49CE ; read byte from hexbus 4020 4D7A ; end hexbus transaction 4022 4D98 ; pre-load R2,R3 with hexbus chip commands 4024 4D72 ; inhibit hexbus chip until next transaction 4026 4D82 ; test IRQ signal 4028 4E6C ; read nibble, strech out HSK 402A 4E58 ; reset HSK, read next nibble 402C 4DA2 ; test BAV asserted 402E 4DA8 ; test HSK asserted 4030 0000 DATA >0000 ; eol 4032 4098 DATA >4098 ; reset routine 4034 0000 DATA >0000 4036 4040 DATA >4040 ; -> next 4038 406A DATA >406A ; DSR routine address 403A 0552 BYTE 5, "RS232" 403C 5332 403E 3332 4040 404C DATA >404C ; -> next 4042 406A DATA >406A ; DSR routine address 4044 0752 BYTE 7, "RS232/1" 4046 5332 4048 3332 404A 2F31 404C 4058 DATA >4058 ; -> next 404E 4070 DATA >4070 ; DSR routine address 4050 0752 BYTE 7, "RS232/2" 4052 5332 4054 3332 4056 2F32 4058 0000 DATA >0000 ; eol 405A 4076 DATA >4076 ; DSR routine address 405C 0648 BYTE 6, "HEXBUS" 405E 4558 4060 4255 4062 5300 4064 0000 DATA >0000 ; eol 4066 4088 DATA >4088 ; INT routine 4068 0000 DATA >0000 ;============================================================================== ; Scratch-pad map: ; ; >834A opcode ; >834B flags | ; >834C-D data buffer | ; >834E record length |copy of pab ; >834F char count |(peripheral access block) ; >8350-1 record number | ; >8352 screen bias | ; >8353 name length | ; >8354-5 device name length ; >8356-7 end of device name ; >8358 status | ; >8359 device | ; >835A command |prep area for hexbus ; >835B unit |command messages ; >835C-D recno | ; >835E-F buflen | ; >8360-1 datalen | ; >8362-3 data / response length ; >8364-5 return addr save slot 1 ; >8366-7 return addr save slot 2 ; >8368-9 attributes (for OPEN) ; >836A-B ack rec size (for OPEN) ; >836C-D req rec size (for OPEN) ; R10 is a flag register during DSR calls. Flag bits are: ; ; >8000 - OPEN command was >80 (= OPEN and enable interrupts) ; >4000 - in poll mode ; >2000 - device is an auto-close device (RS232/Modem/Centronics) : >1000 - VERIFY switch on ; >0100 - INT was enabled? (appears set, but never read) ; >0002 - device is RS232/2 ; >0001 - device is RS232/1 ; R12 is increased by 2 during DSR calls, this to align the ; data read/writes ; Hexbus chip is fully wired to the 8 CRU I/O lines ; CS- is always 0, MS is always 0 ; ; CRU output bits After INCT R12 ; 0 - DSR ROM enable ; 1-4 - data out 0-3 - data out ; 5 - RS (0 = data, 1 = control) 4 - RS ; 6 - E (0 = write strobe) 5 - E ; 7 - INT enable 6 - INT enable ; CRU input bits ; 0 - INT asserted (from FF) -1 - INT asserted ; 1-4 - data in 0-3 - data in ; 5-6 - n/c 4-5 - n/c ; 7 - INT enable 6 - INT enable ;============================================================================== ; DSR entry points ; 406A 020A LI R10, >0001 ; R10 = 1 => RS232/1 406C 0001 406E 1004 JMP >4078 4070 020A LI R10, >0002 ; R10 = 2 => RS232/2 4072 0002 4074 1001 JMP >4078 4076 04CA CLR R10 ; R10 = 0 => HEXBUS 4078 8820 C @>A000, @>4000 ; DSR in HIMEM? 407A A000 407C 4000 407E 1602 JNE >4084 4080 0460 B @>A014 ; enter HIMEM routine 4082 A014 4084 0460 B @>4014 ; enter DSR ROM 4086 4014 4088 8820 C @>A000, @>4000 ; INT in HIMEM? 408A A000 408C 4000 408E 1602 JNE >4094 4090 0460 B @>A010 ; enter HIMEM routine 4092 A010 4094 0460 B @>4010 ; enter DSR ROM 4096 4010 ;============================================================================== ; Reset routine (issues a RESET command on the HEXBUS) ; 4098 05CC INCT R12 ; skip DSR enable bit 409A C1CB MOV R11, R7 ; save RT 409C 1E04 SBZ 4 ; select data reg (why?) 409E 1D05 SBO 5 ; clear strobe 40A0 31A0 LDCR @>4A52, 6 ; write reset command (>1C) 40A2 4A52 40A4 1D05 SBO 5 40A6 31A0 LDCR @>40D8, 6 ; write >0F to data reg 40A8 40D8 40AA 1D05 SBO 5 40AC 1E06 SBZ 6 ; clear & disable interrupts 40AE 02A4 STWP R4 ; fetch scratch ram address 40B0 0224 AI R4, >FF20 40B2 FF20 40B4 0208 LI R8, >0009 ; send 9 bytes 40B6 0009 40B8 0205 LI R5, >40CE ; timeout return address 40BA 40CE 40BC 0206 LI R6, >4C38 ; "RESET BUS" command 40BE 4C38 40C0 06A0 BL @>4966 ; start transaction 40C2 4966 40C4 D036 MOVB *R6+, R0 ; send bytes 40C6 06A0 BL @>4994 40C8 4994 40CA 0608 DEC R8 ; next 40CC 16FB JNE >40C4 ; until done 40CE 31A0 LDCR @>4A52, R6 ; write reset chip command 40D0 4A52 40D2 1D05 SBO 5 40D4 064C DECT R12 40D6 0457 B *R7 40D8 0F00 DATA >0F00 ;============================================================================== ; DSR routine ; 40DA 02A4 STWP R4 ; calc start of scratch RAM (>8300) 40DC 0224 AI R4, >FF20 40DE FF20 40E0 C90B MOV R11, @>0064(R4) ; save r11 in slot 1 40E2 0064 40E4 05CC INCT R12 40E6 1F06 TB 6 ; INT enabled? (i.e. in poll mode) 40E8 1602 JNE >40EE 40EA 026A ORI R10, >0100 ; yes -> set INT flag in R10 40EC 0100 40EE 06A0 BL @>476C ; write PAB address 40F0 476C 40F2 0000 DATA >0000 40F4 0205 LI R5, >000A ; copy PAB to scratchpad >834A 40F6 000A 40F8 C184 MOV R4, R6 40FA 0226 AI R6, >004A 40FC 004A 40FE DDAF MOVB @>FBFE(R15), *R6+ 4100 FBFE 4102 0605 DEC R5 4104 16FC JNE >40FE 4106 5920 SZCB @>4A8B, @>004B(R4) ; >E0 => clear status 4108 4A8B 410A 004B 410C 9920 CB @>411C, @>004A(R4) ; opcode = >80? (OPEN in interupt mode?) 410E 411C 4110 004A 4112 1605 JNE >411E ; no -> 4114 5920 SZCB @>411C, @>004A(R4) ; make normal OPEN 4116 411C 4118 004A 411A 026A ORI R10, >8000 ; add INT mode to R10 flag 411C 8000 411E 06CA SWPB R10 ; device string was HEXBUS? 4120 D28A MOVB R10, R10 4122 06CA SWPB R10 4124 163C JNE >419E ; no -> do RS232 code ; HEXBUS code ; 4126 9824 CB @>004A(R4), @>4A87 ; PAB command == >10 ? 4128 004A 412A 4A87 412C 1306 JEQ >413A ; yes -> 412E 9824 CB @>004A(R4), @>4A8A ; PAB command <= >09 ? 4130 004A 4132 4A8A 4134 1202 JLE >413A ; yes -> 4136 0460 B @>47B4 ; report error 4138 47B4 413A 06A0 BL @>41DC ; process option/device string 413C 41DC 413E C145 MOV R5, R5 ; was it a special option string? 4140 1301 JEQ >4144 ; no -> continue 4142 0455 B *R5 ; handle special string 4144 D024 MOVB @>0059(R4), R0 ; fetch device number 4146 0059 4148 0980 SRL R0, 8 414A 0280 CI R0, >0014 ; 20 <= device <= 27? (= RS232) 414C 0014 414E 1A11 JL >4172 ; no -> skip 4150 0280 CI R0, >001B 4152 001B 4154 120C JLE >416E ; yes -> set flag 4156 0280 CI R0, >0032 ; 50 <= device <= 57? (= Centronics) 4158 0032 415A 1A0B JL >4172 ; no -> skip 415C 0280 CI R0, >0039 415E 0039 4160 1206 JLE >416E ; yes -> set flag 4162 0280 CI R0, >0046 ; 70 <= device <= 77? (= Modem) 4164 0046 4166 1A05 JL >4172 4168 0280 CI R0, >004D 416A 004D 416C 1B02 JH >4172 ; no -> skip 416E E2A0 SOC @>4A90, R10 ; set auto-close flag (>2000) 4170 4A90 4172 D164 MOVB @>004A(R4), R5 ; fetch PAB opcode 4174 004A 4176 9805 CB R5, @>4A87 ; opcode == >10? (SVC REQ POLL) 4178 4A87 417A 1602 JNE >4180 ; no -> skip 417C 0460 B @>469A ; yes -> go process opcode >10 417E 469A 4180 0985 SRL R5, 8 ; else go to handling routine 4182 0A15 SLA R5, 1 ; for each specific PAB opcode 4184 C165 MOV @>418A(R5), R5 4186 418A 4188 0455 B *R5 ; PAB command codes (!= HEXBUS command codes) ; 418A 43B6 ; 0 = OPEN 418C 44CC ; 1 = CLOSE 418E 44F8 ; 2 = READ 4190 455E ; 3 = WRITE 4192 467A ; 4 = REWIND 4194 4608 ; 5 = LOAD 4196 4590 ; 6 = SAVE 4198 46A2 ; 7 = DELETE 419A 47B4 ; 8 = SCRATCH (reports error illegal opcode) 419C 46F0 ; 9 = STATUS ; RS232 code ; 419E 9824 CB @>004A(R4), @>4A87 ; is opcode >10? 41A0 004A 41A2 4A87 41A4 1304 JEQ >41AE ; yes -> ok 41A6 9824 CB @>004A(R4), @>4A4A ; is opcode >00 - >09 ? 41A8 004A 41AA 4A4A 41AC 1BC4 JH >4136 ; no -> error 41AE 06CA SWPB R10 ; get entry flags 41B0 980A CB R10, @>4A86 ; RS232/1? 41B2 4A86 41B4 06CA SWPB R10 41B6 1604 JNE >41C0 ; -> no 41B8 D920 MOVB @>4A99, @>0059(R4) ; set device no to 20 (RS232/1) 41BA 4A99 41BC 0059 41BE 1003 JMP >41C6 41C0 D920 MOVB @>4BE1, @>0059(R4) ; set device no to 21 (RS232/2) 41C2 4BE1 41C4 0059 41C6 C1A4 MOV @>0056(R4), R6 ; get ptr to device string end 41C8 0056 41CA D1E4 MOVB @>0053(R4), R7 ; get device string length 41CC 0053 41CE 0987 SRL R7, 8 41D0 61E4 S @>0054(R4), R7 ; subtract device name length 41D2 0054 41D4 1302 JEQ >41DA ; adjust & process rest of string as for "HEXBUS" 41D6 0607 DEC R7 41D8 0586 INC R6 41DA 10B4 JMP >4144 ; -> hexbus code path ; Process a switch option + device number string after the device name ; 41DC C90B MOV R11, @>0066(R4) ; save R11 in slot 2 41DE 0066 41E0 04C5 CLR R5 ; clear flag at >5B ?? 41E2 D905 MOVB R5, @>005B(R4) 41E4 005B 41E6 C064 MOV @>0056(R4), R1 ; write DSR name address 41E8 0056 41EA 06A0 BL @>4780 41EC 4780 41EE D024 MOVB @>0053(R4), R0 ; get DSR name length 41F0 0053 41F2 0980 SRL R0, 8 41F4 6024 S @>0054(R4), R0 ; subtract device DSR name length 41F6 0054 41F8 131D JEQ >4234 ; if no params, done 41FA 04C2 CLR R2 41FC D0AF MOVB @>FBFE(R15), R2 ; fetch char 41FE FBFE 4200 0600 DEC R0 ; if last one, error 4202 1318 JEQ >4234 4204 0282 CI R2, >2E00 ; is it a dot? 4206 2E00 4208 1615 JNE >4234 ; no -> error 420A D0AF MOVB @>FBFE(R15), R2 ; fetch char 420C FBFE 420E 0600 DEC R0 4210 0282 CI R2, >5A00 ; >'Z'? 4212 5A00 4214 1B0F JH >4234 ; yes -> error 4216 0282 CI R2, >4100 ; <'A'? 4218 4100 421A 1A02 JL >4220 ; yes, skip check for switch option 421C 06A0 BL @>428C ; fetch switch option 421E 428C 4220 06A0 BL @>437A ; fetch device number 4222 437A 4224 0283 CI R3, >00FF ; device number > 255? 4226 00FF 4228 1B05 JH >4234 ; yes -> error 422A 06C3 SWPB R3 ; store device no. in >59 422C D903 MOVB R3, @>0059(R4) 422E 0059 4230 04C2 CLR R2 ; clear char 4232 1002 JMP >4238 4234 0460 B @>47AE ; -> report bad attribute error 4236 47AE 4238 0280 CI R0, >0003 ; at least 3 chars more? 423A 0003 423C 111B JLT >4274 ; no -> skip LU check 423E D0EF MOVB @>FBFE(R15), R3 ; fetch two chars more 4240 FBFE 4242 06C3 SWPB R3 4244 D0EF MOVB @>FBFE(R15), R3 4246 FBFE 4248 0283 CI R3, >554C ; string 'LU' ? 424A 554C 424C 1613 JNE >4274 424E D0AF MOVB @>FBFE(R15), R2 ; fetch one char 4250 FBFE 4252 0282 CI R2, >3D00 4254 3D00 ; char is '=' ? 4256 160E JNE >4274 ; no -> skip rest 4258 0220 AI R0, >FFFD ; adjust char count 425A FFFD 425C 13EB JEQ >4234 ; nothing more? -> error 425E D0AF MOVB @>FBFE(R15), R2 ; fetch char 4260 FBFE 4262 0600 DEC R0 4264 06A0 BL @>437A ; fetch number 4266 437A 4268 0283 CI R3, >00FF ; number >255? 426A 00FF 426C 1BE3 JH >4234 ; yes -> error 426E 06C3 SWPB R3 4270 D903 MOVB R3, @>005B(R4) ; store LU number in HEXBUS PAB 4272 005B 4274 D1A4 MOVB @>0053(R4), R6 ; set R6 to point to remainder connection string (in VDP) 4276 0053 4278 0986 SRL R6, 8 ; R6 = total name length 427A 61A4 S @>0054(R4), R6 ; minus device name length 427C 0054 427E 6180 S R0, R6 ; minus remainder length 4280 A1A4 A @>0056(R4), R6 ; plus end address 4282 0056 4284 C1C0 MOV R0, R7 ; R7 is remainder legth 4286 C2E4 MOV @>0066(R4), R11 ; get return address from slot 2 4288 0066 428A 045B RT ; parse special switch option ; 428C C0C2 MOV R2, R3 ; build special option in R3 428E 06C3 SWPB R3 4290 D0EF MOVB @>FBFE(R15), R3 4292 FBFE 4294 0600 DEC R0 ; error if nothing more 4296 112F JLT >42F6 4298 0205 LI R5, >4350 ; load table - 2 429A 4350 429C 05C5 INCT R5 ; next entry 429E C1B5 MOV *R5+, R6 ; fetch 42A0 132A JEQ >42F6 ; if eot -> done 42A2 80C6 C R6, R3 ; option matches? 42A4 16FB JNE >429C ; no, keep scanning 42A6 0283 CI R3, >5254 ; option was 'TR'? If so, shortcut processing 42A8 5254 42AA 1604 JNE >42B4 ; no -> try others 42AC C000 MOV R0, R0 ; process TR: nothing after swith? 42AE 1623 JNE >42F6 ; no -> error 42B0 C155 MOV *R5, R5 ; fetch & jump to service routine 42B2 0455 B *R5 42B4 C155 MOV *R5, R5 ; fetch service routine vector 42B6 0283 CI R3, >4F46 ; option was 'FO'? 42B8 4F46 42BA 1612 JNE >42E0 ; no -> skip 42BC 0280 CI R0, >000A ; >=10 chars left? 42BE 000A 42C0 111A JLT >42F6 ; no -> error 42C2 0202 LI R2, >0005 ; does it make 'FORMAT NEDIA'? 42C4 0005 42C6 0206 LI R6, >436C 42C8 436C 42CA D0EF MOVB @>FBFE(R15), R3 ; fetch next 2 chars 42CC FBFE 42CE 06C3 SWPB R3 42D0 D0EF MOVB @>FBFE(R15), R3 42D2 FBFE 42D4 8D83 C R3, *R6+ ; still a match ? 42D6 160F JNE >42F6 ; no -> error 42D8 0602 DEC R2 ; more to check? 42DA 16F7 JNE >42CA ; -> yes 42DC 0220 AI R0, >FFF6 ; count -= 10 42DE FFF6 42E0 0640 DECT R0 ; adjust count with two more 42E2 1109 JLT >42F6 ; past end? -> error 42E4 04C2 CLR R2 ; fetch next char 42E6 D0AF MOVB @>FBFE(R15), R2 42E8 FBFE 42EA 0282 CI R2, >2E00 ; is it '.'? 42EC 2E00 42EE 1603 JNE >42F6 ; no -> error 42F0 D0AF MOVB @>FBFE(R15), R2 ; prefetch next char (first digit of device) 42F2 FBFE 42F4 045B RT ; done 42F6 0460 B @>4234 ; error 42F8 4234 ; FORMAT MEDIA switch ; 42FA 9824 CB @>004A(R4), @>4A86 ; PAB command >01? (CLOSE) 42FC 004A 42FE 4A86 4300 131C JEQ >433A ; no-op: update PAB & exit DSR 4302 9824 CB @>004A(R4), @>4A80 ; PAB command >00? (OPEN) 4304 004A 4306 4A80 4308 1302 JEQ >430E 430A 0460 B @>47B4 ; else -> illegal option error 430C 47B4 430E D920 MOVB @>4A7C, @>005A(R4) ; hexbus command >0D = FORMAT 4310 4A7C 4312 005A 4314 04E4 CLR @>005C(R4) ; recno = 0 4316 005C 4318 04E4 CLR @>005E(R4) ; buflen = 0 431A 005E 431C C907 MOV R7, @>0060(R4) ; datalen = option string length 431E 0060 4320 C046 MOV R6, R1 4322 06A0 BL @>47FE ; do hexbus transaction 4324 47FE 4326 0460 B @>47C0 ; timeout error (usually skipped) 4328 47C0 432A D024 MOVB @>004E(R4), R0 ; if record length was 0, set to 255 432C 004E 432E 1603 JNE >4336 4330 D920 MOVB @>4A97, @>004E(R4) 4332 4A97 4334 004E 4336 0460 B @>4482 ; update PAB and return 4338 4482 433A 0460 B @>47CE ; -> update PAB & exit DSR 433C 47CE ; VERIFY switch ; 433E 9824 CB @>004A(R4), @>42E0 ; is the PAB command >06 (SAVE)? 4340 004A 4342 42E0 4344 16E2 JNE >430A ; no -> illegal option error 4346 E2A0 SOC @>4A92, R10 ; set VERIFY flag (>1000) 4348 4A92 434A D060 MOVB @>4A85, R1 ; set mode = >48 (INPUT, FIXED) 434C 4A85 434E 0460 B @>4594 ; continue as for SAVE 4350 4594 ; special switch options table ; 4352 4F46 BYTE 'OF' ; 'FO' (start of 'FORMAT MEDIA') 4354 42FA DATA >42FA 4356 4143 BYTE 'AC' ; 'CA' 4358 4DAE DATA >4DAE 435A 4556 BYTE 'EV' ; 'VE' 435C 433E DATA >433E 435E 5254 BYTE 'RT' ; 'TR' 4360 4C42 DATA >4C42 4362 4252 BYTE >'BR' ; 'RB' 4364 4BEE DATA >4BEE 4366 4C53 BYTE 'LS' ; 'SL' 4368 4DEE DATA >$DEE 436A 0000 DATA >0000 436C 4D52 BYTE 'MR' ; 'RMAT MEDIA' 436E 5441 BYTE 'TA' 4370 4D20 BYTE 'M ' 4372 4445 BYTE 'DE' 4374 4149 BYTE 'AI' ; OPEN mode conversion table PAB -> HEXBUS ; 4376 C080 4378 4000 ; fetch device number from device string ; 437A 04C3 CLR R3 ; R3 is accumulator 437C C042 MOV R2, R1 ; check current char 437E 0281 CI R1, >3000 ; < "0"? 4380 3000 4382 1A17 JL >43B2 ; yes, error 4384 0281 CI R1, >3900 ; > "9"? 4386 3900 4388 1B14 JH >43B2 ; yes, error 438A 0981 SRL R1, 8 438C 0221 AI R1, >FFD0 ; calc digit value (minus >30) 438E FFD0 4390 C083 MOV R3, R2 ; R3 = R3 * 10 4392 38A0 MPY @>4A80, R2 4394 4A80 4396 C082 MOV R2, R2 ; overflow into 32 bits? 4398 160C JNE >43B2 ; yes -> error 439A A0C1 A R1, R3 ; R3 = R3 + digit 439C 180A JOC >43B2 ; overflow? -> error 439E C000 MOV R0, R0 ; last char in string? 43A0 1307 JEQ >43B0 ; yes _> done 43A2 04C1 CLR R1 ; fetch next char 43A4 D06F MOVB @>FBFE(R15), R1 43A6 FBFE 43A8 0600 DEC R0 43AA 0281 CI R1, >2E00 ; char = '.'? 43AC 2E00 43AE 16E7 JNE >437E ; no -> process next digit 43B0 045B RT 43B2 0460 B @>4234 ; -> bad attribute error 43B4 4234 ;============================================================================== ; DSR COMMANDS (OPEN/READ/WRITE/CLOSE/SAVE/LOAD/POLL) ; DSR command OPEN ; 43B6 22A0 COC @>411C, R10 ; OPEN in interrupt mode? 43B8 411C 43BA 130D JEQ >43D6 ; yes -> skip auto-close 43BC 22A0 COC @>4A90, R10 ; auto-close device? 43BE 4A90 43C0 160A JNE >43D6 ; no -> skip auto-close ; do auto-close ; 43C2 C906 MOV R6, @>0068(R4) ; save option string ptr/len 43C4 0068 43C6 C907 MOV R7, @>006A(R4) 43C8 006A 43CA 06A0 BL @>44F2 ; do auto-close before open 43CC 44F2 43CE C1A4 MOV @>0068(R4), R6 ; restore option string ptr/len 43D0 0068 43D2 C1E4 MOV @>006A(R4), R7 43D4 006A ; set requested record length ; 43D6 C024 MOV @>004E(R4), R0 ; get PAB reclen 43D8 004E 43DA 0980 SRL R0, 8 43DC 22A0 COC @>411C, R10 ; OPEN in interrupt mode? 43DE 411C 43E0 1602 JNE >43E6 ; -> no 43E2 0200 LI R0, >0050 ; set reclen to 80 43E4 0050 43E6 C900 MOV R0, @>006C(R4) ; set requested rec len 43E8 006C 43EA 160A JNE >4400 43EC D024 MOVB @>0059(R4), R0 ; set reclen to 255 for device 1-8 43EE 0059 ; = wafertape devices 43F0 1307 JEQ >4400 ; dev = 0? -> skip 43F2 9800 CB R0, @>4A8E ; dev > 8? 43F4 4A8E 43F6 1B04 JH >4400 ; yes -> skip 43F8 0200 LI R0, >00FF ; set req. reclen to 255 43FA 00FF 43FC C900 MOV R0, @>006C(R4) 43FE 006C ; convert PAB flags into HEXBUS attributes ; 4400 04C1 CLR R1 ; fetch PAB flags 4402 D064 MOVB @>004B(R4), R1 4404 004B 4406 C081 MOV R1, R2 4408 0241 ANDI R1, >0600 ; get mode & lookup hexbus mode 440A 0600 440C 0991 SRL R1, 9 440E D061 MOVB @>4376(R1), R1 4410 4376 4412 20A0 COC @>4A8C, R2 ; convert SEQUENTIAL / RELATIVE 4414 4A8C 4416 1602 JNE >441C 4418 B060 AB @>4A90, R1 441A 4A90 441C 20A0 COC @>4A8E, R2 ; convert DISPLAY / INTERNAL 441E 4A8E 4420 1602 JNE >4426 4422 B060 AB @>4A8E, R1 4424 4A8E 4426 20A0 COC @>4A92, R2 ; convert FIXED / VARIABLE 4428 4A92 442A 1302 JEQ >4430 442C B060 AB @>4A92, R1 442E 4A92 ; core of open, also used by SAVE/LOAD ; 4430 D901 MOVB R1, @>0068(R4) ; set open attributes 4432 0068 4434 D920 MOVB @>4A72, @>005A(R4) ; set command to open 4436 4A72 4438 005A 443A 04E4 CLR @>005C(R4) ; recno = 0 443C 005C 443E 0200 LI R0, >0004 ; buflen = 4 4440 0004 4442 C900 MOV R0, @>005E(R4) 4444 005E 4446 0227 AI R7, >0003 ; datalen = options len + 3 4448 0003 444A C907 MOV R7, @>0060(R4) 444C 0060 444E C046 MOV R6, R1 ; set options addr for send 4450 06A0 BL @>47FE ; send command 4452 47FE 4454 0460 B @>47C0 ; timout error 4456 47C0 4458 9920 CB @>4A80, @>004A(R4) ; PAB command was OPEN? 445A 4A80 445C 004A 445E 161C JNE >4498 ; no -> special return ; check OPEN reponse ; 4460 D024 MOVB @>0058(R4), R0 ; status OK? 4462 0058 4464 1644 JNE >44EE ; no -> report & return from DSR 4466 C024 MOV @>006C(R4), R0 ; req. rec size was 0 (ANY)? 4468 006C 446A 1305 JEQ >4476 ; -> yes 446C 8900 C R0, @>0068(R4) ; ack. rec size == req. rec size? 446E 0068 4470 1305 JEQ >447C ; yes -> 4472 0460 B @>47AE ; -> report bad attribute 4474 47AE 4476 D024 MOVB @>0068(R4), R0 ; size > 255 ? 4478 0068 447A 16FB JNE >4472 ; -> report bad attribute ; Update PAB in RAM and in VDP ; 447C D924 MOVB @>0069(R4), @>004E(R4) ; save ack. size in PAB 447E 0069 4480 004E 4482 06A0 BL @>476C ; write to VDP PAB at offset 4 4484 476C 4486 4004 DATA >4004 4488 DBE4 MOVB @>004E(R4), @>FFFE(R15) ; update VDP PAB rec size 448A 004E 448C FFFE 448E 22A0 COC @>411C, R10 ; was an OPEN with interrupt enable? 4490 411C 4492 162D JNE >44EE ; no -> finish DSR call 4494 0460 B @>44A4 ; yes -> enable service request & finish 4496 44A4 ; return from auto-close and auto-open ; 4498 C2E4 MOV @>0066(R4), R11 ; restore rtn addr from slot 2 449A 0066 449C 045B RT ; return ; perform auto-open ; 449E C90B MOV R11, @>0066(R4) ; save rtn addr to slot 2 44A0 0066 44A2 10C6 JMP >4430 ; -> do open routine ; enable service request ; 44A4 42A0 SZC @>411C, R10 ; clear OPEN with interrupt enable flag (for return) 44A6 411C 44A8 026A ORI R10, >4000 ; set poll mode flag 44AA 4000 44AC D920 MOVB @>4A7A, @>005A(R4) ; set hexbus command to >08 (enable svc req) 44AE 4A7A 44B0 005A 44B2 04E4 CLR @>005E(R4) ; buffer length = 0 44B4 005E 44B6 04E4 CLR @>0060(R4) ; data length = 0 44B8 0060 44BA 06A0 BL @>47FE ; send command 44BC 47FE 44BE 0460 B @>47C0 ; timeout error (usually skipped) 44C0 47C0 44C2 D024 MOVB @>0058(R4), R0 ; return status OK? 44C4 0058 44C6 1313 JEQ >44EE ; yes -> finish DSR call 44C8 0460 B @>45F4 44CA 45F4 ; DSR command CLOSE ; 44CC D920 MOVB @>4A73, @>005A(R4) ; set HEXBUS command = >01 (close) 44CE 4A73 44D0 005A 44D2 04E4 CLR @>005C(R4) ; set REC# = 0 44D4 005C 44D6 04E4 CLR @>005E(R4) ; set BUFLEN = 0 44D8 005E 44DA 04E4 CLR @>0060(R4) ; set LEN = 0 44DC 0060 44DE 06A0 BL @>47FE ; send command 44E0 47FE 44E2 0460 B @>47C0 ; timeout error (normally skipped) 44E4 47C0 44E6 9824 CB @>004A(R4), @>4A86 ; command = >01? 44E8 004A 44EA 4A86 44EC 16D5 JNE >4498 ; no -> special return 44EE 0460 B @>478A ; report status & return 44F0 478A 44F2 C90B MOV R11, @>0066(R4) ; save R11 in slot 2 44F4 0066 44F6 10EA JMP >44CC ; and do close ; DSR command READ ; 44F8 22A0 COC @>4A90, R10 ; auto-close device? 44FA 4A90 44FC 1602 JNE >4502 ; if yes, check break key (FCTN-4) 44FE 06A0 BL @>4A1A ; 4500 4A1A 4502 D920 MOVB @>4A75, @>005A(R4) ; set Hexbus command 2 (READ) 4504 4A75 4506 005A ; CATALOG read comes in here 4508 D920 MOVB @>4A80, @>004F(R4) ; set char count = 0 450A 4A80 450C 004F 450E D024 MOVB @>004E(R4), R0 ; fetch record length 4510 004E 4512 0980 SRL R0, 8 ; store as Hexbuf buf length 4514 C900 MOV R0, @>005E(R4) 4516 005E 4518 C924 MOV @>0050(R4), @>005C(R4) ; move record number 451A 0050 451C 005C 451E 04E4 CLR @>0060(R4) ; set LEN = 0 4520 0060 4522 C1E4 MOV @>004C(R4), R7 ; set up buffer ptr 4524 004C 4526 06A0 BL @>47FE ; do hexbus transaction 4528 47FE 452A 0460 B @>47C0 ; timeout error (usually skipped) 452C 47C0 452E D924 MOVB @>0063(R4), @>004F(R4) ; set char count received 4530 0063 4532 004F ; update recno & return ; 4534 D024 MOVB @>0058(R4), R0 ; hexbus status OK? 4536 0058 4538 1610 JNE >455A ; -> no, skip recno update 453A D024 MOVB @>004B(R4), R0 ; check PAB status 453C 004B 453E 2420 CZC @>4A92, R0 ; OK? 4540 4A92 4542 160B JNE >455A ; -> no, skip recno update 4544 06A0 BL @>476C ; setup VDP PAB+6 for write (recno) 4546 476C 4548 4006 DATA >4006 454A C024 MOV @>0050(R4), R0 ; set recno = recno + 1 454C 0050 454E 0580 INC R0 4550 DBC0 MOVB R0, @>FFFE(R15) 4552 FFFE 4554 06C0 SWPB R0 4556 DBC0 MOVB R0, @>FFFE(R15) 4558 FFFE 455A 0460 B @>478A ; report status & return 455C 478A ; DSR command WRITE ; 455E 22A0 COC @>4A90, R10 ; check for auto-close device 4560 4A90 4562 1602 JNE >4568 ; if yes, check break key (FCTN-4) 4564 06A0 BL @>4A1A 4566 4A1A 4568 D024 MOVB @>004F(R4), R0 ; fetch reclen 456A 004F 456C 0980 SRL R0, 8 456E C900 MOV R0, @>0060(R4) ; set DATA LEN to reclen 4570 0060 4572 04E4 CLR @>005E(R4) ; BUFLEN = 0 4574 005E 4576 C924 MOV @>0050(R4), @>005C(R4) ; move record number 4578 0050 457A 005C 457C D920 MOVB @>4A76, @>005A(R4) ; set hexbus command >04 (WRITE) 457E 4A76 4580 005A 4582 C064 MOV @>004C(R4), R1 ; set data buffer address 4584 004C 4586 06A0 BL @>47FE ; do hexbus transaction 4588 47FE 458A 0460 B @>47C0 ; timeout error (usually skipped) 458C 47C0 458E 10D2 JMP >4534 ; -> update recno, handle status & return ; DSR command SAVE ; 4590 D060 MOVB @>4A84, R1 ; mode (>88) = OUTPUT, FIXED 4592 4A84 ; VERIFY enters here with R1 set to >48 = INPUT, FIXED 4594 C924 MOV @>0050(R4), @>006C(R4) ; requested buffer = program len 4596 0050 4598 006C 459A 06A0 BL @>449E ; send OPEN command 459C 449E 459E D024 MOVB @>0058(R4), R0 ; status OK? 45A0 0058 45A2 1302 JEQ >45A8 ; -> yes 45A4 0460 B @>478A ; report status & return from DSR 45A6 478A 45A8 8924 C @>0068(R4), @>0050(R4) ; program length accepted? 45AA 0068 45AC 0050 45AE 1620 JNE >45F0 ; no -> memory full error 45B0 22A0 COC @>4A92, R10 ; is VERIFY flag set (>1000)? 45B2 4A92 45B4 1604 JNE >45BE ; -> no 45B6 D920 MOVB @>4A7B, @>005A(R4) ; set command >0C (VERIFY) 45B8 4A7B 45BA 005A 45BC 1003 JMP >45C4 45BE D920 MOVB @>4A76, @>005A(R4) ; set command >04 (WRITE) 45C0 4A76 45C2 005A 45C4 04E4 CLR @>005C(R4) ; recno = 0 45C6 005C 45C8 04E4 CLR @>005E(R4) ; buflen = 0 45CA 005E 45CC C924 MOV @>0050(R4), @>0060(R4) ; datalen = program len 45CE 0050 45D0 0060 45D2 C064 MOV @>004C(R4), R1 ; data start in VDP 45D4 004C 45D6 06A0 BL @>47FE ; do hexbus WRITE/VERIFY transaction 45D8 47FE 45DA 0460 B @>47C0 ; timeout (usually skipped) 45DC 47C0 45DE D024 MOVB @>0058(R4), R0 ; status OK? 45E0 0058 45E2 1608 JNE >45F4 ; -> no 45E4 06A0 BL @>44F2 ; do CLOSE 45E6 44F2 45E8 0460 B @>478A ; -> report hexbus status & return from DSR 45EA 478A 45EC 06A0 BL @>44F2 ; do CLOSE 45EE 44F2 45F0 0460 B @>47BA ; -> memory full error 45F2 47BA 45F4 D924 MOVB @>0058(R4), @>0068(R4) ; save hexbus status 45F6 0058 45F8 0068 45FA 06A0 BL @>44F2 ; do CLOSE 45FC 44F2 45FE D924 MOVB @>0068(R4), @>0058(R4) ; restore hexbus status 4600 0068 4602 0058 4604 0460 B @>478A ; -> report hexbus status & return from DSR 4606 478A ; DSR command LOAD ; 4608 04E4 CLR @>006C(R4) ; clear req. recsize 460A 006C 460C D060 MOVB @>4A85, R1 ; mode >48 (INPUT, FIXED) 460E 4A85 4610 06A0 BL @>449E ; do OPEN 4612 449E 4614 D024 MOVB @>0058(R4), R0 ; status OK? 4616 0058 4618 1302 JEQ >461E 461A 0460 B @>478A ; no -> report status & exit DSR 461C 478A 461E 8924 C @>0068(R4), @>0050(R4) ; file size > mem size? 4620 0068 4622 0050 4624 1BE3 JH >45EC ; yes -> close & report memory full 4626 D920 MOVB @>4A75, @>005A(R4) ; hexbus command = >03 (READ) 4628 4A75 462A 005A 462C 04E4 CLR @>005C(R4) ; recno = 0 462E 005C 4630 04E4 CLR @>0060(R4) ; data size = 0; 4632 0060 4634 C924 MOV @>0050(R4), @>005E(R4) ; buf size = memsize 4636 0050 4638 005E 463A C924 MOV @>004C(R4), @>006C(R4) ; req. rec size = data buffer 463C 004C 463E 006C 4640 04E4 CLR @>0050(R4) ; pgm size = 0 4642 0050 4644 C1E4 MOV @>006C(R4), R7 ; size - data buffer 4646 006C 4648 06A0 BL @>47FE ; perform READ 464A 47FE 464C 0460 B @>47C0 ; timeout error (usually skipped) 464E 47C0 4650 D024 MOVB @>0058(R4), R0 ; status OK? 4652 0058 4654 160A JNE >466A ; -> no 4656 A924 A @>0062(R4), @>0050(R4) ; pgm size += response size 4658 0062 465A 0050 465C 6924 S @>0062(R4), @>005E(R4) ; buf size -= response size 465E 0062 4660 005E 4662 A924 A @>0062(R4), @>006C(R4) ; req size += response size 4664 0062 4666 006C 4668 10ED JMP >4644 ; next chunk 466A 9824 CB @>0058(R4), @>4A79 ; status = >07 (EOF?) 466C 0058 466E 4A79 4670 16C1 JNE >45F4 4672 06A0 BL @>44F2 ; close, saving status 4674 44F2 4676 0460 B @>478A ; -> report status & exit DSR 4678 478A ; DSR command REWIND ; 467A D920 MOVB @>4A77, @>005A(R4) ; set command >05 (RESTORE) 467C 4A77 467E 005A 4680 C924 MOV @>0050(R4), @>005C(R4) ; set record number 4682 0050 4684 005C 4686 04E4 CLR @>005E(R4) ; buflen = 0 4688 005E 468A 04E4 CLR @>0060(R4) ; data len = 0 468C 0060 468E 06A0 BL @>47FE ; do hexbus transaction 4690 47FE 4692 0460 B @>47C0 ; timeout error (usually skipped) 4694 47C0 4696 0460 B @>478A ; report status & exit DSR 4698 478A ; DSR command >10 (SVC REQ POLL) ; 469A D920 MOVB @>4A7E, @>005A(R4) ; set hexbus command to >10 (SVC REQ POLL) 469C 4A7E 469E 005A 46A0 10EF JMP >4680 ; perform command & return ; DSR command DELETE ; 46A2 D920 MOVB @>4A74, @>005A(R4) ; command >02, DELETE OPEN FILE 46A4 4A74 46A6 005A 46A8 C907 MOV R7, @>0066(R4) ; save device string 46AA 0066 46AC C906 MOV R6, @>0068(R4) 46AE 0068 46B0 04E4 CLR @>005C(R4) ; recno = 0 46B2 005C 46B4 04E4 CLR @>005E(R4) ; buflen = 0 46B6 005E 46B8 04E4 CLR @>0060(R4) ; datalen = 0 46BA 0060 46BC 06A0 BL @>47FE ; do hexbus transaction 46BE 47FE 46C0 0460 B @>47C0 ; timeout error (usually skipped) 46C2 47C0 46C4 9824 CB @>0058(R4), @>4A89 ; status = >04 = file not open ? 46C6 0058 46C8 4A89 46CA 1302 JEQ >46D0 ; yes -> try normal delete 46CC 0460 B @>478A ; else -> report status & exit DSR 46CE 478A 46D0 D920 MOVB @>4A78, @>005A(R4) ; command >06, DELETE 46D2 4A78 46D4 005A 46D6 04E4 CLR @>005E(R4) ; buflen = 0 46D8 005E 46DA C924 MOV @>0066(R4), @>0060(R4) ; data len = device string len 46DC 0066 46DE 0060 46E0 C064 MOV @>0068(R4), R1 ; data location 46E2 0068 46E4 06A0 BL @>47FE ; do hexbus transaction 46E6 47FE 46E8 0460 B @>47C0 ; timeout error (usually skipped) 46EA 47C0 46EC 0460 B @>478A ; report status & exit DSR 46EE 478A ; DSR command STATUS ; 46F0 D920 MOVB @>4A79, @>005A(R4) ; hexbus get status command 46F2 4A79 46F4 005A 46F6 04E4 CLR @>005C(R4) ; recno = 0 46F8 005C 46FA 0200 LI R0, >0001 ; bufsize = 1 46FC 0001 46FE C900 MOV R0, @>005E(R4) 4700 005E 4702 04E4 CLR @>0060(R4) ; data len = 0 4704 0060 4706 C1E4 MOV @>0056(R4), R7 ; end of device name 4708 0056 470A 61E4 S @>0054(R4), R7 ; subtract device name len 470C 0054 470E 0227 AI R7, >FFFE ; include length byte 4710 FFFE 4712 C907 MOV R7, @>0066(R4) ; save ptr 4714 0066 4716 06A0 BL @>47FE ; do hexbus transaction 4718 47FE 471A 0460 B @>47C0 ; timeout error (usually skipped) 471C 47C0 471E D024 MOVB @>0058(R4), R0 ; status OK? 4720 0058 4722 1302 JEQ >4728 4724 0460 B @>478A ; no -> report status & exit DSR 4726 478A 4728 C064 MOV @>0066(R4), R1 ; set VDP read address to PAB status byte 472A 0066 472C 06A0 BL @>4780 472E 4780 4730 04C2 CLR R2 4732 D02F MOVB @>FBFE(R15), R0 ; fetch status 4734 FBFE 4736 0A10 SLA R0, 1 ; translate exist / not exists 4738 1702 JNC >473E 473A B0A0 AB @>4A86, R2 473C 4A86 473E 0A10 SLA R0, 1 ; translate fixed / variable 4740 1802 JOC >4746 4742 B0A0 AB @>4A89, R2 4744 4A89 4746 0A10 SLA R0, 1 ; translate protected / not protected 4748 1702 JNC >474E 474A B0A0 AB @>4A88, R2 474C 4A88 474E 0A10 SLA R0, 1 ; traslate display / internal 4750 0960 SRL R0, 6 4752 D000 MOVB R0, R0 4754 1305 JEQ >4760 4756 9020 CB @>4A86, R0 4758 4A86 475A 1602 JNE >4760 475C B0A0 AB @>4A87, R2 475E 4A87 4760 06A0 BL @>477C ; set VDP write address to PAB status byte 4762 477C 4764 DBC2 MOVB R2, @>FFFE(R15) ; update PAB status 4766 FFFE 4768 0460 B @>478A ; return from DSR 476A 478A ; write PAB address to VDP ; 476C C064 MOV @>0056(R4), R1 ; fetch DSRNAME pointer (at end) 476E 0056 4770 6064 S @>0054(R4), R1 ; subtract length 4772 0054 4774 0221 AI R1, >FFF6 ; go back 10 more (start of PAB) 4776 FFF6 4778 A07B A *R11+, R1 ; add offset from caller 477A 1002 JMP >4780 477C 0261 ORI R1, >4000 ; write address in R1 for writing 477E 4000 4780 06C1 SWPB R1 ; write addr in R1 to VDP 4782 D7C1 MOVB R1, *R15 4784 06C1 SWPB R1 4786 D7C1 MOVB R1, *R15 4788 045B RT ; report Hexbus status ; 478A D0A4 MOVB @>0058(R4), R2 ; fetch HEXBUS status 478C 0058 478E 0982 SRL R2, 8 4790 0282 CI R2, >001C ; in range >00 - >1C? 4792 001C 4794 1403 JHE >479C ; -> no 4796 D062 MOVB @>4A56(R2), R1 ; look up PAB error code in table 4798 4A56 479A 1017 JMP >47CA ; -> and report 479C 0282 CI R2, >0020 ; error >20 = media full error 479E 0020 47A0 130C JEQ >47BA ; -> map to memory full 47A2 0282 CI R2, >00FE ; error >FE = illegal slave mode 47A4 00FE 47A6 130F JEQ >47C6 ; -> map to device error ; everyting else defaults to file error ; report errors ; 47A8 0201 LI R1, >E000 ; set file error 47AA E000 47AC 100E JMP >47CA 47AE 0201 LI R1, >4000 ; set bad attribute error 47B0 4000 47B2 100B JMP >47CA 47B4 0201 LI R1, >6000 ; set illegal opcode error 47B6 6000 47B8 1008 JMP >47CA 47BA 0201 LI R1, >8000 ; set memory full error 47BC 8000 47BE 1005 JMP >47CA 47C0 D920 MOVB @>4A97, @>0058(R4) ; set HEXBUS status = >FF = bus timeout 47C2 4A97 47C4 0058 47C6 0201 LI R1, >C000 ; set device error 47C8 C000 ; update PAB in VDP ; 47CA F901 SOCB R1, @>004B(R4) ; set error code in PAB 47CC 004B 47CE 06A0 BL @>493A ; fetch INT enable status 47D0 493A 47D2 31A0 LDCR @>4A52, 6 ; reset hexbus chip 47D4 4A52 47D6 1D05 SBO 5 47D8 06A0 BL @>476C ; set VDP address to PAB 1 for writing 47DA 476C 47DC 4001 DATA >4001 47DE DBE4 MOVB @>004B(R4), @>FFFE(R15) ; update PAB status 47E0 004B 47E2 FFFE 47E4 06A0 BL @>476C ; set VDP address to PAB 5 for writing 47E6 476C 47E8 4005 DATA >4005 47EA DBE4 MOVB @>004F(R4), @>FFFE(R15) ; update PAB char count 47EC 004F 47EE FFFE ; exit DSR ; 47F0 05E4 INCT @>0064(R4) ; break from DSR loop 47F2 0064 47F4 024C ANDI R12, >FF00 ; clear R12 back to normal 47F6 FF00 47F8 C2E4 MOV @>0064(R4), R11 ; fetch DSR return from slot 1 47FA 0064 47FC 045B RT ; return from DSR ; do HEXBUS transaction ; - header at >8359 ; - send buffer at R1 (in VDP space) ; - rcv buffer at R7 (in VDP space) ; 47FE C14B MOV R11, R5 ; save return address = timeout address 4800 06A0 BL @>4966 ; start new transaction 4802 4966 4804 0241 ANDI R1, >3FFF ; limit buffer address 4806 3FFF 4808 06A0 BL @>4780 ; send address to VDP for reading 480A 4780 480C D024 MOVB @>0059(R4), R0 ; send device number 480E 0059 4810 06A0 BL @>4994 4812 4994 4814 D024 MOVB @>005A(R4), R0 ; send command code 4816 005A 4818 06A0 BL @>4994 481A 4994 481C D024 MOVB @>005B(R4), R0 ; send LU number 481E 005B 4820 06A0 BL @>4994 4822 4994 4824 D024 MOVB @>005D(R4), R0 ; send record number (low byte first) 4826 005D 4828 06A0 BL @>4994 482A 4994 482C D024 MOVB @>005C(R4), R0 482E 005C 4830 06A0 BL @>4994 4832 4994 4834 D024 MOVB @>005F(R4), R0 ; send buffer length (low byte first) 4836 005F 4838 06A0 BL @>4994 483A 4994 483C D024 MOVB @>005E(R4), R0 483E 005E 4840 06A0 BL @>4994 4842 4994 4844 C024 MOV @>0060(R4), R0 ; fetch current record size 4846 0060 4848 22A0 COC @>411C, R10 ; doing an "OPEN with interrupt enable"? 484A 411C 484C 1602 JNE >4852 ; no -> skip extra settings 484E 0220 AI R0, >000B ; add space for extra settings (".T=C.R=N.EC"). 4850 000B 4852 06C0 SWPB R0 ; send record size (low byte first) 4854 06A0 BL @>4994 4856 4994 4858 06C0 SWPB R0 485A 06A0 BL @>4994 485C 4994 485E C1A4 MOV @>0060(R4), R6 ; record size is 0? 4860 0060 4862 1323 JEQ >48AA ; yes -> skip data send 4864 D024 MOVB @>005A(R4), R0 ; command = OPEN? 4866 005A 4868 160F JNE >4888 ; no -> skip special open parameters 486A D024 MOVB @>006D(R4), R0 ; send offered recsize (low byte first) 486C 006D 486E 06A0 BL @>4994 4870 4994 4872 D024 MOVB @>006C(R4), R0 4874 006C 4876 06A0 BL @>4994 4878 4994 487A D024 MOVB @>0068(R4), R0 ; send attributes byte 487C 0068 487E 06A0 BL @>4994 4880 4994 4882 0226 AI R6, >FFFD ; adjust data size for the 3 bytes sent 4884 FFFD 4886 1306 JEQ >4894 ; skip sending params if none present 4888 D02F MOVB @>FBFE(R15), R0 ; fetch & send data byte 488A FBFE 488C 06A0 BL @>4994 488E 4994 4890 0606 DEC R6 ; done ? 4892 16FA JNE >4888 ; -> no 4894 22A0 COC @>411C, R10 ; doing an "OPEN with interrupt enable"? 4896 411C 4898 1608 JNE >48AA ; no -> skip sending extra connection params 489A 0206 LI R6, >4A3A ; send ".T=C.R=N.EC" 489C 4A3A 489E D036 MOVB *R6+, R0 ; fetch & send char 48A0 06A0 BL @>4994 48A2 4994 48A4 0286 CI R6, >4A45 ; until done 48A6 4A45 48A8 16FA JNE >489E 48AA C047 MOV R7, R1 ; set VDP write address 48AC 0241 ANDI R1, >3FFF 48AE 3FFF 48B0 06A0 BL @>477C 48B2 477C 48B4 06A0 BL @>49CE ; read response length (low byte first) 48B6 49CE 48B8 D900 MOVB R0, @>0063(R4) ; store at >8362 48BA 0063 48BC 06A0 BL @>49CE 48BE 49CE 48C0 D900 MOVB R0, @>0062(R4) 48C2 0062 48C4 C1A4 MOV @>0062(R4), R6 ; R6 = response length 48C6 0062 48C8 1322 JEQ >490E ; if none -> skip read 48CA 04C7 CLR R7 ; R7 = excess length = 0 48CC 8906 C R6, @>005E(R4) ; compare resp. len with buffer len 48CE 005E 48D0 1205 JLE >48DC ; fits? -> yes 48D2 61A4 S @>005E(R4), R6 ; set R7 to excess length 48D4 005E 48D6 C1C6 MOV R6, R7 48D8 C1A4 MOV @>005E(R4), R6 ; read buflen bytes 48DA 005E 48DC D024 MOVB @>005A(R4), R0 ; command = OPEN? 48DE 005A 48E0 1332 JEQ >4946 ; process special OPEN response 48E2 C186 MOV R6, R6 ; zero data length? 48E4 1306 JEQ >48F2 ; yes -> skip read 48E6 06A0 BL @>49CE ; read & store data bytes 48E8 49CE 48EA DBC0 MOVB R0, @>FFFE(R15) 48EC FFFE 48EE 0606 DEC R6 48F0 16FA JNE >48E6 48F2 C1C7 MOV R7, R7 ; excess length > 0? 48F4 130C JEQ >490E ; no -> normal return ; handle excess length response 48F6 0587 INC R7 ; read & drop excess bytes received 48F8 06A0 BL @>49CE 48FA 49CE 48FC 0607 DEC R7 48FE 16FC JNE >48F8 4900 D920 MOVB @>4A96, @>0058(R4) ; set error status >0C (buffer size error) 4902 4A96 4904 0058 4906 06A0 BL @>493A ; INT flag = INT enable flag (always off) 4908 493A 490A 0460 B @>47C6 ; -> return with 'device error' 490C 47C6 490E 06A0 BL @>49CE ; read & set status byte 4910 49CE 4912 D900 MOVB R0, @>0058(R4) 4914 0058 4916 22A0 COC @>4A94, R10 ; test poll mode flag 4918 4A94 491A 1607 JNE >492A ; not set? -> done ; re-enable interrupts if in poll mode & set INT flag 491C D024 MOVB @>0058(R4), R0 ; status OK? 491E 0058 4920 1604 JNE >492A ; no -> skip INT enable 4922 1D06 SBO 6 ; enable interrupts 4924 026A ORI R10, >0100 ; set INT flag 4926 0100 4928 1002 JMP >492E 492A 06A0 BL @>493A ; INT flag = INT enable flag (always off) 492C 493A 492E 31A0 LDCR @>4A52, 6 ; reset chip 4930 4A52 4932 1D05 SBO 5 4934 0225 AI R5, >0004 ; skip timeout error jump after call 4936 0004 4938 0455 B *R5 ; normal return ; Read INT Enable flag ; 493A 022C AI R12, >000C ; read CRU bit 6 = INT enable 493C 000C 493E 304A LDCR R10, 1 ; into INT flag (>0100) 4940 022C AI R12, >FFF4 4942 FFF4 4944 045B RT ; Read 4 byte OPEN response ; 4946 0208 LI R8, >0068 ; OPEN input buffer = >8368 4948 0068 494A A204 A R4, R8 494C C186 MOV R6, R6 ; check len != 0 494E 13D1 JEQ >48F2 4950 06A0 BL @>49CE ; read 4 bytes 4952 49CE 4954 DE00 MOVB R0, *R8+ 4956 0606 DEC R6 4958 16FB JNE >4950 495A C024 MOV @>0068(R4), R0 ; change endian on input length 495C 0068 495E 06C0 SWPB R0 4960 C900 MOV R0, @>0068(R4) 4962 0068 4964 10C6 JMP >48F2 ; continue with transaction ; prep for sending to HEXBUS ; 4966 0200 LI R0, >0800 ; wait for bus to become available 4968 0800 496A 1D04 SBO 4 ; select status/control 496C 3502 STCR R2, 4 ; read chip status 496E 24A0 CZC @>4A8C, R2 ; >0100, ignore HSK status 4970 4A8C 4972 1303 JEQ >497A ; enabled, BAV released -> continue 4974 0600 DEC R0 4976 16FA JNE >496C ; if no time out, try again 4978 0455 B *R5 ; take time out return 497A 1E06 SBZ 6 ; clear & disable INT line 497C 31A0 LDCR @>4A4E, 6 ; reset chip, >12 497E 4A4E 4980 1D05 SBO 5 4982 D0A0 MOVB @>4A48, R2 ; prepare R2 = >11 + >02 = >13 = assert HSK / clear IRQ 4984 4A48 4986 B0A0 AB @>4A54, R2 4988 4A54 498A D0E0 MOVB @>4A4C, R3 ; prepare R3 = >10 + >02 = >12 = release HSK 498C 4A4C 498E B0E0 AB @>4A54, R3 4990 4A54 4992 045B RT ; send byte to HEXBUS ; 4994 1D04 SBO 4 ; select status/control 4996 1F00 TB 0 ; test HSK high? (= nibble read by all) 4998 1603 JNE >49A0 ; yes -> go 499A 3183 LDCR R3, 6 ; reset our HSK latch 499C 1D05 SBO 5 499E 10FB JMP >4996 ; test again. 49A0 C040 MOV R0, R1 49A2 0241 ANDI R1, >0F00 ; write high nibble 49A4 0F00 49A6 3181 LDCR R1, 6 ; write data 49A8 1D05 SBO 5 49AA 3182 LDCR R2, 6 ; assert HSK 49AC 1D05 SBO 5 49AE 3183 LDCR R3, 6 ; release HSK 49B0 1D05 SBO 5 49B2 0B40 SRC R0, 4 ; move to next nibble 49B4 1F00 TB 0 ; wait for HSK high 49B6 13FE JEQ >49B4 49B8 C040 MOV R0, R1 ; write high nibble 49BA 0241 ANDI R1, >0F00 49BC 0F00 49BE 3181 LDCR R1, 6 ; write data 49C0 1D05 SBO 5 49C2 3182 LDCR R2, 6 ; assert HSK 49C4 1D05 SBO 5 49C6 3183 LDCR R3, 6 ; release HSK 49C8 1D05 SBO 5 49CA 0BC0 SRC R0, 12 49CC 045B RT ; read byte from HEXBUS ; 49CE 1D04 SBO 4 ; select status/control 49D0 0201 LI R1, >1000 ; timeout value 49D2 1000 49D4 1F02 TB 2 ; wait for IRQ 49D6 1302 JEQ >49DC 49D8 1F03 TB 3 49DA 1305 JEQ >49E6 ; IRQ -> fetch data 49DC 1F00 TB 0 ; test HSK 49DE 13FA JEQ >49D4 ; if asserted, wait 49E0 0601 DEC R1 ; timeout? 49E2 16F8 JNE >49D4 ; no -> wait some more 49E4 0455 B *R5 ; take timeout exit 49E6 3182 LDCR R2, 6 ; clear IRQ 49E8 1D05 SBO 5 49EA 1E04 SBZ 4 ; select data register 49EC 3500 STCR R0, 4 ; fetch nibble 49EE 3183 LDCR R3, 6 ; clear HSK latch 49F0 1D05 SBO 5 49F2 0B40 SRC R0, 4 ; save nibble 49F4 0201 LI R1, >1000 ; timeout value 49F6 1000 49F8 1F02 TB 2 ; wait for IRQ 49FA 1302 JEQ >4A00 49FC 1F03 TB 3 49FE 1305 JEQ >4A0A ; IRQ -> fetch data 4A00 1F00 TB 0 ; test HSK 4A02 13FA JEQ >49F8 ; if asserted, wait 4A04 0601 DEC R1 ; timeout? 4A06 16F8 JNE >49F8 ; no -> wait some more 4A08 0455 B *R5 ; take timeout exit 4A0A 3182 LDCR R2, R6 ; clear IRQ 4A0C 1D05 SBO 5 4A0E 1E04 SBZ 4 ; select data register 4A10 3500 STCR R0, 4 ; fetch upper nibble 4A12 3183 LDCR R3, 6 ; clear HSK latch 4A14 1D05 SBO 5 4A16 0BC0 SRC R0, 12 ; combine nibbles to byte 4A18 045B RT ; Test for CLEAR (= FCTN-4) pressed ; 4A1A C00C MOV R12, R0 ; test for CLEAR 4A1C 020C LI R12, >0024 ; select KBD row 0 4A1E 0024 4A20 30E0 LDCR @>4A80, 3 4A22 4A80 4A24 1FF5 TB -11 ; test FCTN key pressed 4A26 1307 JEQ >4A36 ; -> no 4A28 30E0 LDCR @>4A4A, 3 ; select KDB row 3 4A2A 4A4A 4A2C 1FF5 TB -11 ; test 4 key pressed 4A2E 1303 JEQ >4A36 ; -> no 4A30 C300 MOV R0, R12 4A32 0460 B @>47C6 ; exit DSR with "device error" 4A34 47C6 4A36 C300 MOV R0, R12 4A38 045B RT ; RS232 string ; 4A3A 2E54 BYTE '.T=C.R=N.EC' ; Extra connection options 4A3C 3D43 4A3E 2E52 4A40 3D4E 4A42 2E45 4A44 4300 ; Data constants ; 4A46 0000 4A48 1100 4A4A 0300 4A4C 1000 4A4E 1200 4A50 1400 4A52 1C00 4A54 0200 ; Table to translate Hexbus error >00 - >1C to PAB errors ; 4A56 0040 4A58 40E0 4A5A E0E0 4A5C C0A0 4A5E E020 4A60 E080 4A62 8060 4A64 6060 4A66 C040 4A68 4040 4A6A 4040 4A6C 4040 4A6E C0C0 4A70 C0C0 ; (Byte) constants table ; 4A72 0001 4A74 0203 4A76 0405 4A78 0607 4A7A 080C 4A7C 0D0E 4A7E 1000 4A80 000A 4A82 0001 4A84 8848 4A86 0110 4A88 4004 4A8A 09E0 4A8C 0100 4A8E 0800 4A90 2000 4A92 1000 4A94 4000 4A96 0CFF 4A98 3214 ;============================================================================== ; INT routine (only for RS232 unit) ; 4A9A 1F00 TB 0 ; is card INT line active? 4A9C 1301 JEQ >4AA0 ; 4A9E 045B RT ; not us 4AA0 1F07 TB 7 ; are interrupts enabled? 4AA2 1301 JEQ >4AA6 ; yes -> go process 4AA4 045B RT ; noise on FF, ignore ; fetch / test INT vector 4AA6 05CC INCT R12 ; realign base (as per DSR code) 4AA8 02A4 STWP R4 ; fetch scratch RAM base 4AAA 0224 AI R4, >FF20 4AAC FF20 4AAE C064 MOV @>0000(R4), R1 ; fetch circular buffer vector (>8300) 4AB0 0000 4AB2 1503 JGT >4ABA ; if TEII vector, handle as such 4AB4 1302 JEQ >4ABA 4AB6 0A21 SLA R1, 2 ; else jump to user vector 4AB8 0451 B *R1 ; clear INT latch 4ABA C200 MOV R0, R8 4ABC C1CB MOV R11, R7 ; save return 4ABE 1D04 SBO 4 ; select status register 4AC0 1F01 TB 1 ; BAV active? 4AC2 130C JEQ >4ADC ; yes -> process 4AC4 1E06 SBZ 6 ; clear INT latch 4AC6 1D06 SBO 6 ; enable interrupt circuit 4AC8 1FFF TB -1 ; INT line still active? 4ACA 1308 JEQ >4ADC ; yes -> process ; reset hexbus chip & return 4ACC 1D06 SBO 6 ; done, enable interrupt circuit 4ACE 31A0 LDCR @>4A52, R6 ; reset chip 4AD0 4A52 4AD2 1D05 SBO 5 4AD4 C008 MOV R8, R0 ; restore R0 4AD6 064C DECT R12 ; restore R12 4AD8 04C8 CLR R8 ; clear error flag 4ADA 0457 B *R7 ; return ; poll device 20 (RS232) and device 70 (Modem) 4ADC 020A LI R10, >0014 ; first try device 20 = RS232 4ADE 0014 ; poll device in R10 4AE0 0205 LI R5, >4BD2 ; timeout exit 4AE2 4BD2 4AE4 0206 LI R6, >4BE6 ; "service request poll" command 4AE6 4BE6 4AE8 06A0 BL @>4966 ; start new HEXBUS transaction 4AEA 4966 4AEC C00A MOV R10, R0 ; send device number 4AEE 06C0 SWPB R0 4AF0 06A0 BL @>4994 4AF2 4994 4AF4 D036 MOVB *R6+, R0 ; send rest of SRP command 4AF6 06A0 BL @>4994 4AF8 4994 4AFA 0286 CI R6, >4BEE 4AFC 4BEE 4AFE 16FA JNE >4AF4 ; read response length 4B00 06A0 BL @>49CE ; read first byte of response (length low) 4B02 49CE 4B04 C180 MOV R0, R6 4B06 06A0 BL @>49CE ; read 2nd byte (length high) 4B08 49CE 4B0A 06C6 SWPB R6 ; response length in R6 4B0C D180 MOVB R0, R6 4B0E C186 MOV R6, R6 ; if length = 0, skip read data part 4B10 1323 JEQ >4B58 ; read response data 4B12 06A0 BL @>49CE ; read next data byte 4B14 49CE 4B16 C064 MOV @>0000(R4), R1 ; check circular buffer vector 4B18 0000 4B1A 2060 COC @>4A94, R1 ; RAM or VDP buffer? 4B1C 4A94 4B1E 1337 JEQ >4B8E ; -> do RAM buffer routine ; circular buffer in VDP 4B20 D064 MOVB @>0004(R4), R1 ; fetch buffer write index 4B22 0004 4B24 B060 AB @>4A86, R1 ; index += 1 4B26 4A86 4B28 9901 CB R1, @>0002(R4) ; past end of buffer? 4B2A 0002 4B2C 1201 JLE >4B30 ; -> no 4B2E 04C1 CLR R1 ; go back to index 0 4B30 9901 CB R1, @>0003(R4) ; same as read index? 4B32 0003 4B34 1604 JNE >4B3E ; -> no 4B36 0200 LI R0, >FE00 ; set byte to >FE (overflow marker) 4B38 FE00 4B3A D064 MOVB @>0004(R4), R1 ; revert index to previous 4B3C 0004 4B3E D901 MOVB R1, @>0004(R4) ; update write index 4B40 0004 4B42 0981 SRL R1, 8 4B44 A064 A @>0000(R4), R1 ; combine into VDP pointer 4B46 0000 4B48 0241 ANDI R1, >3FFF ; set VDP write address 4B4A 3FFF 4B4C 06A0 BL @>477C 4B4E 477C 4B50 DBC0 MOVB R0, @>FFFE(R15) ; write the byte 4B52 FFFE 4B54 0606 DEC R6 ; and process next 4B56 16DD JNE >4B12 ; read response status byte 4B58 06A0 BL @>49CE ; read response status 4B5A 49CE 4B5C 9800 CB R0, @>4BE6 ; if status = >0A, it was not this device 4B5E 4BE6 4B60 1338 JEQ >4BD2 4B62 D000 MOVB R0, R0 ; if status = >00, we're done 4B64 1312 JEQ >4B8A ; for any other status set last byte to >FF 4B66 C064 MOV @>0000(R4), R1 ; check buffer location (VDP/RAM) 4B68 0000 4B6A 2060 COC @>4A94, R1 ; in RAM? 4B6C 4A94 4B6E 1327 JEQ >4BBE ; yes -> RAM routine 4B70 0200 LI R0, >FF00 ; load error marker 4B72 FF00 4B74 D064 MOVB @>0004(R4), R1 ; fetch DSR write offset 4B76 0004 4B78 0981 SRL R1, 8 4B7A A064 A @>0000(R4), R1 ; add buffer start 4B7C 0000 4B7E 0241 ANDI R1, >3FFF ; write address to VDP 4B80 3FFF 4B82 06A0 BL @>477C 4B84 477C 4B86 DBC0 MOVB R0, @>FFFE(R15) ; store >FF (error marker) byte 4B88 FFFE 4B8A 0460 B @>4ACC ; done, finish up 4B8C 4ACC ; circular buffer in RAM 4B8E 06C2 SWPB R2 ; save R2H in R2L (WHY?) 4B90 D080 MOVB R0, R2 ; save data byte 4B92 0A21 SLA R1, 2 ; get RAM buffer header ptr 4B94 0221 AI R1, >0006 ; R1 = ptr to DSR write index 4B96 0006 4B98 C011 MOV *R1, R0 ; fetch write index 4B9A 0221 AI R1, >FFFC ; move R1 ptr to buf size 4B9C FFFC 4B9E 0580 INC R0 ; inc write index 4BA0 8C40 C R0, *R1+ ; at end of buffer ? 4BA2 1201 JLE >4BA6 ; 4BA4 04C0 CLR R0 ; yes -> wrap to start 4BA6 8C40 C R0, *R1+ ; at read index? 4BA8 1603 JNE >4BB0 4BAA D0A0 MOVB @>4B38, R2 ; set previous byte to >FE (overflow) 4BAC 4B38 4BAE C011 MOV *R1, R0 ; restore write index 4BB0 C440 MOV R0, *R1 ; update write index 4BB2 0221 AI R1, >FFFA ; move R1 ptr to buffer base 4BB4 FFFA 4BB6 A011 A *R1, R0 ; store byte in buffer 4BB8 D402 MOVB R2, *R0 4BBA 06C2 SWPB R2 ; restore R2H 4BBC 10CB JMP >4B54 ; -> process next data byte ; mark error in RAM buffer 4BBE 0A21 SLA R1, 2 ; get buffer write offset 4BC0 0221 AI R1, >0006 4BC2 0006 4BC4 C011 MOV *R1, R0 4BC6 0221 AI R1, >FFFA ; R1 = buffer base address 4BC8 FFFA 4BCA A011 A *R1, R0 4BCC D420 MOVB @>4A97, *R0 ; set the >FF byte 4BCE 4A97 4BD0 10DC JMP >4B8A ; done, finish up ; more device to check? 4BD2 028A CI R10, >0014 ; was the device number 20? 4BD4 0014 4BD6 16D9 JNE >4B8A ; no -> done, finish up ; check next device 4BD8 31A0 LDCR @>4A52, 6 ; reset hexbus chip 4BDA 4A52 4BDC 1D05 SBO 5 4BDE 020A LI R10, >0046 ; next try device 70 = modem 4BE0 0046 4BE2 0460 B @>4AE0 ; and from the top 4BE4 4AE0 ; service request header data 4BE6 0A00 DATA >0A00 4BE8 0000 DATA >0000 4BEA 0000 DATA >0000 4BEC 0000 DATA >0000 ;============================================================================== ; CODE FOR SPECIAL SWITCHES (RB, CA, TR, SL) ; Do RB switch (Reset Bus) ; 4BEE D024 MOVB @>004A(R4), R0 ; fetch PAB command 4BF0 004A 4BF2 1307 JEQ >4C02 ; -> is OPEN 4BF4 9800 CB R0, @>4A86 ; is CLOSE? 4BF6 4A86 4BF8 131D JEQ >4C34 ; -> done 4BFA 0460 B @>47B4 ; -> illegal opcode 4BFC 47B4 4BFE 0460 B @>47AE ; -> bad attribute 4C00 47AE 4C02 D024 MOVB @>0059(R4), R0 ; device != 0 ? 4C04 0059 4C06 16FB JNE >4BFE ; -> bad attribute 4C08 C1C7 MOV R7, R7 ; other options ? 4C0A 16F9 JNE >4BFE ; -> bad attribute 4C0C 0208 LI R8, >0009 ; send RESET BUS command, 9 bytes long 4C0E 0009 4C10 0205 LI R5, >4C2A ; timeout routine 4C12 4C2A 4C14 0206 LI R6, >4C38 ; RESET command block 4C16 4C38 4C18 04E4 CLR @>0058(R4) ; clear status 4C1A 0058 4C1C 06A0 BL @>4966 ; start transaction 4C1E 4966 4C20 D036 MOVB *R6+, R0 ; write command to hexbus 4C22 06A0 BL @>4994 4C24 4994 4C26 0608 DEC R8 4C28 16FB JNE >4C20 4C2A 31A0 LDCR @>4A52, R6 ; reset chip 4C2C 4A52 4C2E 1D05 SBO 5 4C30 0460 B @>432A ; update status & exit DSR 4C32 432A 4C34 0460 B @>47CE ; -> update VDP PAB & exit 4C36 47CE 4C38 00FF DATA >00FF ; HEXBUS "RESET" command 4C3A 0000 DATA >0000 4C3C 0000 DATA >0000 4C3E 0000 DATA >0000 4C40 0000 DATA >0000 ;============================================================================== ; Do switch TR (direct HEXBUS transaction) ; 4C42 D024 MOVB @>004A(R4), R0 ; PAB command >=4 (not OPEN/CLOSE/READ/WRITE)? 4C44 004A 4C46 9800 CB R0, @>4A89 4C48 4A89 4C4A 14D7 JHE >4BFA ; yes -> illegal opcode 4C4C 9800 CB R0, @>4A86 ; opcode is CLOSE? 4C4E 4A86 4C50 13F1 JEQ >4C34 ; yes -> update PAB & exit 4C52 9800 CB R0, @>4ADC ; opcode is READ? 4C54 4ADC 4C56 132E JEQ >4CB4 ; yes -> do READ 4C58 9800 CB R0, @>4A4A ; opcode is WRITE? 4C5A 4A4A 4C5C 130D JEQ >4C78 ; yes -> do WRITE 4C5E 9824 CB @>004B(R4), @>4A87 ; PAB flags != FIXED/UPDATE/DISPLAY/SEQUENTIAL ? 4C60 004B 4C62 4A87 4C64 16CC JNE >4BFE ; yes -> bad attribute ; TR OPEN ; 4C66 D024 MOVB @>004E(R4), R0 ; get PAB record len 4C68 004E 4C6A 1303 JEQ >4C72 ; rec len 0 is OK 4C6C 9800 CB R0, @>4A8A ; rec len >=9 is OK 4C6E 4A8A 4C70 1AC6 JL >4BFE ; else -> bad attribute 4C72 04E4 CLR @>0058(R4) ; set hexbus status to OK 4C74 0058 4C76 10DC JMP >4C30 ; update status & exit DSR ; TR WRITE ; 4C78 D1E4 MOVB @>004F(R4), R7 ; get PAB char count in R7 4C7A 004F 4C7C 0987 SRL R7, 8 4C7E 0205 LI R5, >4CAC ; set timeout vector 4C80 4CAC 4C82 06A0 BL @>4966 ; start transaction 4C84 4966 4C86 C064 MOV @>004C(R4), R1 ; get PAB buffer address (in VDP) 4C88 004C 4C8A 06A0 BL @>4780 ; set VDP read address 4C8C 4780 4C8E D02F MOVB @>FBFE(R15), R0 ; fetch source byte 4C90 FBFE 4C92 06A0 BL @>4994 ; write byte 4C94 4994 4C96 0607 DEC R7 ; until all bytes written 4C98 16FA JNE >4C8E 4C9A 0201 LI R1, >0800 ; wait until slave starts to respond, with timout 4C9C 0800 4C9E 06A0 BL @>4D5C ; HSK/INT asserted? 4CA0 4D5C 4CA2 1306 JEQ >4CB0 ; -> yes, done 4CA4 1F00 TB 0 ; our last HSK still pending ? 4CA6 13F9 JEQ >4C9A ; wait unlimited 4CA8 0601 DEC R1 ; else wait with timout 4CAA 16F9 JNE >4C9E 4CAC 0460 B @>47C0 ; -> timeout error 4CAE 47C0 4CB0 0460 B @>47D8 ; update PAB in VDP & retuen from DSR 4CB2 47D8 ; TR READ ; 4CB4 1D04 SBO 4 ; select status register 4CB6 1F01 TB 1 ; BAV asserted? 4CB8 164B JNE >4D50 ; no -> device eror 4CBA 1F00 TB 0 ; HSK asserted? 4CBC 1649 JNE >4D50 ; no -> device error 4CBE 06A0 BL @>4982 ; set R2/R3 to HSK commands 4CC0 4982 4CC2 C064 MOV @>004C(R4), R1 ; fetch buffer address (in VDP) 4CC4 004C 4CC6 06A0 BL @>477C ; set VDP write address 4CC8 477C 4CCA 0205 LI R5, >4D4C ; set timout vector 4CCC 4D4C 4CCE C1E4 MOV @>004E(R4), R7 ; set buffer len in R7 4CD0 004E 4CD2 0987 SRL R7, 8 4CD4 0227 AI R7, >FFFD ; less 3 bytes overhead (2 len + 1 status) 4CD6 FFFD ; check for sufficient buffer size 4CD8 06A0 BL @>49CE ; read hexbus byte 4CDA 49CE 4CDC D900 MOVB R0, @>0063(R4) ; read response length (low byte first) 4CDE 0063 4CE0 DBC0 MOVB R0, @>FFFE(R15) ; include in buffer 4CE2 FFFE 4CE4 06A0 BL @>49CE ; read response length (high byte) 4CE6 49CE 4CE8 D900 MOVB R0, @>0062(R4) 4CEA 0062 4CEC DBC0 MOVB R0, @>FFFE(R15) ; include in buffer 4CEE FFFE 4CF0 C1A4 MOV @>0062(R4), R6 ; get reponse length 4CF2 0062 4CF4 81C6 C R6, R7 ; resp len <= buf len? 4CF6 1202 JLE >4CFC ; yes -> read full response 4CF8 6187 S R7, R6 ; R6 is ecxess length 4CFA 1002 JMP >4D00 4CFC C1C6 MOV R6, R7 ; reduce count in R7 4CFE 04C6 CLR R6 ; R6 is ecess length = 0 4D00 C1C7 MOV R7, R7 ; more to read? 4D02 1306 JEQ >4D10 ; -> no 4D04 06A0 BL @>49CE ; read byte 4D06 49CE 4D08 DBC0 MOVB R0, @>FFFE(R15) ; store in buffer 4D0A FFFE 4D0C 0607 DEC R7 ; until done 4D0E 16FA JNE >4D04 4D10 C186 MOV R6, R6 ; excess bytes? 4D12 130E JEQ >4D30 ; -> no ; read excess bytes & eport buffer overflow 4D14 06A0 BL @>49CE ; read excess byte 4D16 49CE 4D18 0606 DEC R6 ; until all read 4D1A 16FC JNE >4D14 4D1C 06A0 BL @>49CE ; read status byte 4D1E 49CE 4D20 0200 LI R0, >0C00 ; status is >0C (buffer size error) 4D22 0C00 4D24 D900 MOVB R0, @>0058(R4) ; set hexbus status 4D26 0058 4D28 DBC0 MOVB R0, @>FFFE(R15) ; and add to buffer 4D2A FFFE 4D2C 0460 B @>47BA ; -> report memory full & return 4D2E 47BA ; read status & return 4D30 06A0 BL @>49CE ; read & store status byte 4D32 49CE 4D34 D900 MOVB R0, @>0058(R4) 4D36 0058 4D38 DBC0 MOVB R0, @>FFFE(R15) ; also append to end of response 4D3A FFFE 4D3C D024 MOVB @>0063(R4), R0 ; get response length 4D3E 0063 4D40 0220 AI R0, >0300 ; add 3 for overhead bytes 4D42 0300 4D44 D900 MOVB R0, @>004F(R4) ; store in PAB char count 4D46 004F 4D48 0460 B @>47CE ; -> update PAB in VDP 4D4A 47CE 4D4C 0460 B @>47C0 ; -> timout error 4D4E 47C0 4D50 0200 LI R0, >1B00 ; set status >1B (hexbus timing error) 4D52 1B00 4D54 D900 MOVB R0, @>0058(R4) 4D56 0058 4D58 0460 B @>47C6 ; -> return with device error 4D5A 47C6 ;============================================================================== ; UTILITY SERVICE ROUTINES ; Test for INT / HSK LOW (EQ set = asserted) ; 4D5C 1D04 SBO 4 ; select status 4D5E 1F02 TB 2 ; test for 10XX status 4D60 1302 JEQ >4D66 4D62 1F03 TB 3 4D64 1304 JEQ >4D6E 4D66 8820 C @>411C, @>4A94 ; clear EQ bit 4D68 411C 4D6A 4A94 4D6C 045B RT 4D6E 8000 C R0, R0 ; set EQ bit 4D70 045B RT ; Inhibit IRQ for duration current transaction ; 4D72 31A0 LDCR @>4A50, 6 ; command >04 = inhibit until new BAV 4D74 4A50 4D76 1D05 SBO 5 4D78 045B RT 4D7A 31A0 LDCR @>4A52, 6 ; command >0C = disable hexbus chip 4D7C 4A52 4D7E 1D05 SBO 5 4D80 045B RT ; Test for INT / HSK LOW (EQ set = asserted) | WHY DUPLICATE ? ; 4D82 1D04 SBO 4 ; select status 4D84 1F02 TB 2 ; test for 10XX status 4D86 1604 JNE >4D90 4D88 1F03 TB 3 4D8A 1602 JNE >4D90 4D8C 8000 C R0, R0 ; set EQ bit 4D8E 045B RT 4D90 8820 C @>411C, @>4A94 ; clear EQ bit 4D92 411C 4D94 4A94 4D96 045B RT ; Load R2, R3 with hexbus chip commands ; 4D98 D0A0 MOVB @>4A48, R2 ; R2 = >11 = assert BAV + HSK 4D9A 4A48 4D9C D0E0 MOVB @>4A4C, R3 ; R3 = >10 = assert BAV, not HSK 4D9E 4A4C 4DA0 045B RT ; Test Hexbus control signals ; 4DA2 1D04 SBO 4 ; test BAV asserted (EQ set if so) 4DA4 1F01 TB 1 4DA6 045B RT 4DA8 1D04 SBO 4 ; test HSK asserted (EQ set if so) 4DAA 1F00 TB 0 4DAC 045B RT ;============================================================================== ; Do special switch CA (CATALOG) ; 4DAE D024 MOVB @>004A(R4), R0 ; get PAB command 4DB0 004A 4DB2 130A JEQ >4DC8 ; OPEN? -> yes 4DB4 9800 CB R0, @>4A86 ; CLOSE? 4DB6 4A86 4DB8 1305 JEQ >4DC4 ; -> yes, update PAB and return from DSR 4DBA 9800 CB R0, @>4ADC ; READ? 4DBC 4ADC 4DBE 1312 JEQ >4DE4 ; -> yes 4DC0 0460 B @>47B4 ; else -> illegal opcode 4DC2 47B4 4DC4 0460 B @>47CE ; -> update PAB and return from DSR 4DC6 47CE ; do OPEN 4DC8 9824 CB @>004B(R4), @>4A89 ; mode is DISPLAY, FIXED, INPUT, SEQUENTIAL? 4DCA 004B 4DCC 4A89 4DCE 1302 JEQ >4DD4 4DD0 0460 B @>4234 ; no -> report attribute error 4DD2 4234 4DD4 D024 MOVB @>004E(R4), R0 ; get record length 4DD6 004E 4DD8 13FB JEQ >4DD0 ; length = 0 -> attribute error 4DDA D920 MOVB @>4A80, @>0058(R4) ; hexbus status = >00 = OK 4DDC 4A80 4DDE 0058 4DE0 0460 B @>478A ; report status & return from DSR 4DE2 478A ; do READ 4DE4 D920 MOVB @>4A7D, @>005A(R4) ; set command >0E = CATALOG 4DE6 4A7D 4DE8 005A 4DEA 0460 B @>4508 ; proceed as with READ, increasing recno 4DEC 4508 ;============================================================================== ; Do SL switch (become slave) ; 4DEE D0A4 MOVB @>004A(R4), R2 ; get PAB command 4DF0 004A 4DF2 0982 SRL R2, 8 4DF4 0280 CI R0, >0003 ; BUG: should be R2 4DF6 0003 4DF8 1B04 JH >4E02 4DFA 0A12 SLA R2, 1 4DFC C062 MOV @>4E06(R2), R1 ; switch to routine 4DFE 4E06 4E00 0451 B *R1 4E02 0460 B @>47B4 ; -> illegal command 4E04 47B4 ; jump table ; 4E06 4E0E ; OPEN 4E08 4E50 ; CLOSE 4E0A 4E94 ; READ 4E0C 4F04 ; WRITE ; SL OPEN ; 4E0E D024 MOVB @>0059(R4), R0 ; fetch device no. 4E10 0059 4E12 0980 SRL R0, 8 4E14 0280 CI R0, >003C ; dev < 60? 4E16 003C 4E18 1ADB JL >4DD0 ; yes -> bad attribute error 4E1A 0280 CI R0, >0043 ; dev > 67? 4E1C 0043 4E1E 1BD8 JH >4DD0 ; yes -> bad attribute error 4E20 9824 CB @>004B(R4), @>4A87 ; mode is VARIABLE, DISPLAY? 4E22 004B 4E24 4A87 4E26 16D4 JNE >4DD0 ; no -> bad attribute error 4E28 D024 MOVB @>004E(R4), R0 ; rec size != 0? 4E2A 004E 4E2C 1604 JNE >4E36 ; yes, accept 4E2E D920 MOVB @>4A97, @>004E(R4) ; set rec size to 255 bytes 4E30 4A97 4E32 004E 4E34 1003 JMP >4E3C 4E36 9800 CB R0, @>4A8A ; size <= 9? 4E38 4A8A 4E3A 1ACA JL >4DD0 ; no -> attribute error ; 4E3C 06A0 BL @>476C ; update rec size in VDP PAB 4E3E 476C 4E40 4004 DATA >4004 4E42 DBE4 MOVB @>004E(R4), @>FFFE(R15) 4E44 004E 4E46 FFFE 4E48 06A0 BL @>4D72 ; inhibit IRQ during current transaction 4E4A 4D72 4E4C 0460 B @>47D8 ; -> update PAB and return from DSR 4E4E 47D8 ; SL CLOSE ; 4E50 06A0 BL @>4D7A ; disable hexbus chip 4E52 4D7A 4E54 0460 B @>47D8 ; -> update PAB and return from DSR 4E56 47D8 ; special read hexbus byte (later bytes, clears HSK as needed) ; 4E58 1D04 SBO 4 ; select status 4E5A 1F02 TB 2 ; IRQ asserted (i.e new nibble present?) 4E5C 1302 JEQ >4E62 ; 4E5E 1F03 TB 3 4E60 1305 JEQ >4E6C ; yes -> read nibble 4E62 3183 LDCR R3, 6 ; release HSK 4E64 1D05 SBO 5 4E66 1F01 TB 1 ; BAV still asserted? 4E68 13F8 JEQ >4E5A ; yes -> keep trying 4E6A 0455 B *R5 ; report bus error ; special read hexbus byte, leaving HSK asserted (first byte) ; 4E6C 3182 LDCR R2, 6 ; assert HSK, clear latch 4E6E 1D05 SBO 5 ; select data reg 4E70 1E04 SBZ 4 4E72 3500 STCR R0, 4 ; read nibble 4E74 3183 LDCR R3, 6 ; release HSK 4E76 1D05 SBO 5 4E78 0940 SRL R0, 4 ; save nibble ; 4E7A 1F02 TB 2 ; wait for next nibble 4E7C 1302 JEQ >4E82 4E7E 1F03 TB 3 4E80 1303 JEQ >4E88 4E82 1F01 TB 1 4E84 13FA JEQ >4E7A 4E86 0455 B *R5 ; 4E88 3182 LDCR R2, 6 ; assert HSK 4E8A 1D05 SBO 5 4E8C 1E04 SBZ 4 ; select data 4E8E 3500 STCR R0, 4 ; read nibble 4E90 0A40 SLA R0, 4 ; byte in R0H 4E92 045B RT ; SL READ ; 4E94 06A0 BL @>4D98 ; enable & prep R2, R3 4E96 4D98 4E98 C1A4 MOV @>004C(R4), R6 ; get PAB buffer address (in VDP) 4E9A 004C 4E9C D1E4 MOVB @>004E(R4), R7 ; get buffer len 4E9E 004E 4EA0 0987 SRL R7, 8 4EA2 D224 MOVB @>0059(R4), R8 ; get our device number 4EA4 0059 4EA6 0205 LI R5, >47C6 ; set device error vector 4EA8 47C6 4EAA C046 MOV R6, R1 ; set VDP write address to PAB buffer 4EAC 06A0 BL @>477C 4EAE 477C 4EB0 04C6 CLR R6 ; byte ctr = 0 4EB2 06A0 BL @>4D82 ; wait for transaction start 4EB4 4D82 4EB6 16FD JNE >4EB2 4EB8 06A0 BL @>4E6C ; read device byte 4EBA 4E6C 4EBC 9200 CB R0, R8 ; adressed to us? 4EBE 1303 JEQ >4EC6 ; -> yes 4EC0 06A0 BL @>4D72 4EC2 4D72 4EC4 10F6 JMP >4EB2 ; read msg header ; 4EC6 DBC0 MOVB R0, @>FFFE(R15) ; store header byte 4EC8 FFFE 4ECA 06C8 SWPB R8 ; R8 will contain last word (data size) 4ECC D200 MOVB R0, R8 4ECE 0586 INC R6 4ED0 0286 CI R6, >0009 ; end-of-header reached? 4ED2 0009 4ED4 1303 JEQ >4EDC ; yes -> do data 4ED6 06A0 BL @>4E58 ; get next byte 4ED8 4E58 4EDA 10F5 JMP >4EC6 ; and loop around ; check buffer size 4EDC C188 MOV R8, R6 ; calc data + hdr len 4EDE 0228 AI R8, >0009 4EE0 0009 4EE2 81C8 C R8, R7 ; too big for buffer? 4EE4 1B0D JH >4F00 ; yes -> report mem full ; read data body 4EE6 C186 MOV R6, R6 ; data len = 0? 4EE8 1306 JEQ >4EF6 ; yes -> skip data read 4EEA 06A0 BL @>4E58 ; get next byte 4EEC 4E58 4EEE DBC0 MOVB R0, @>FFFE(R15) ; store in buffer 4EF0 FFFE 4EF2 0606 DEC R6 ; and repeat for all data 4EF4 16FA JNE >4EEA ; wrap up 4EF6 06C8 SWPB R8 ; set PAB char count to entire byte count 4EF8 D908 MOVB R8, @>004F(R4) 4EFA 004F 4EFC 0460 B @>47D8 ; update PAB and return from DSR 4EFE 47D8 4F00 0460 B @>47BA ; -> memory full error & return 4F02 47BA ; SL WRITE ; 4F04 C1A4 MOV @>004C(R4), R6 ; get buffer address (in VDP) 4F06 004C 4F08 D1E4 MOVB @>004F(R4), R7 ; get buffer length 4F0A 004F 4F0C 0987 SRL R7, 8 4F0E 06A0 BL @>4D98 ; setup hexbus chip commands in R2, R3 4F10 4D98 4F12 1D04 SBO 4 ; select status 4F14 1F00 TB 0 ; HSK asserted? 4F16 160F JNE >4F36 ; no -> device error 4F18 1F01 TB 1 ; BAV asserted? 4F1A 160D JNE >4F36 ; no -> device error 4F1C C046 MOV R6, R1 ; setup VDP read address 4F1E 06A0 BL @>4780 4F20 4780 4F22 D02F MOVB @>FBFE(R15), R0 ; fetch byte 4F24 FBFE 4F26 06A0 BL @>4994 ; send to hexbus 4F28 4994 4F2A 0607 DEC R7 ; repeat for entire message 4F2C 16FA JNE >4F22 4F2E 06A0 BL @>4D72 ; ignore Hexbus until next transaction 4F30 4D72 4F32 0460 B @>47D8 ; -> update PAB & return from DSR 4F34 47D8 4F36 0460 B @>47C6 ; -> device error 4F38 47C6 ;============================================================================== 4F3A 0000 DATA >0000 4F3C 0000 DATA >0000 4F3E 0000 DATA >0000 4F40 0000 DATA >0000 4F42 0000 DATA >0000 4F44 0000 DATA >0000 4F46 0000 DATA >0000 4F48 0000 DATA >0000 4F4A 0000 DATA >0000 4F4C 0000 DATA >0000 4F4E 0000 DATA >0000 4F50 0000 DATA >0000 4F52 0000 DATA >0000 4F54 0000 DATA >0000 4F56 0000 DATA >0000 4F58 0000 DATA >0000 4F5A 0000 DATA >0000 4F5C 0000 DATA >0000 4F5E 0000 DATA >0000 4F60 0000 DATA >0000 4F62 0000 DATA >0000 4F64 0000 DATA >0000 4F66 0000 DATA >0000 4F68 0000 DATA >0000 4F6A 0000 DATA >0000 4F6C 0000 DATA >0000 4F6E 0000 DATA >0000 4F70 0000 DATA >0000 4F72 0000 DATA >0000 4F74 0000 DATA >0000 4F76 0000 DATA >0000 4F78 0000 DATA >0000 4F7A 0000 DATA >0000 4F7C 0000 DATA >0000 4F7E 0000 DATA >0000 4F80 0000 DATA >0000 4F82 0000 DATA >0000 4F84 0000 DATA >0000 4F86 0000 DATA >0000 4F88 0000 DATA >0000 4F8A 0000 DATA >0000 4F8C 0000 DATA >0000 4F8E 0000 DATA >0000 4F90 0000 DATA >0000 4F92 0000 DATA >0000 4F94 0000 DATA >0000 4F96 0000 DATA >0000 4F98 0000 DATA >0000 4F9A 0000 DATA >0000 4F9C 0000 DATA >0000 4F9E 0000 DATA >0000 4FA0 0000 DATA >0000 4FA2 0000 DATA >0000 4FA4 0000 DATA >0000 4FA6 0000 DATA >0000 4FA8 0000 DATA >0000 4FAA 0000 DATA >0000 4FAC 0000 DATA >0000 4FAE 0000 DATA >0000 4FB0 0000 DATA >0000 4FB2 0000 DATA >0000 4FB4 0000 DATA >0000 4FB6 0000 DATA >0000 4FB8 0000 DATA >0000 4FBA 0000 DATA >0000 4FBC 0000 DATA >0000 4FBE 0000 DATA >0000 4FC0 0000 DATA >0000 4FC2 0000 DATA >0000 4FC4 0000 DATA >0000 4FC6 0000 DATA >0000 4FC8 0000 DATA >0000 4FCA 0000 DATA >0000 4FCC 0000 DATA >0000 4FCE 0000 DATA >0000 4FD0 0000 DATA >0000 4FD2 0000 DATA >0000 4FD4 0000 DATA >0000 4FD6 0000 DATA >0000 4FD8 0000 DATA >0000 4FDA 0000 DATA >0000 4FDC 0000 DATA >0000 4FDE 0000 DATA >0000 4FE0 0000 DATA >0000 4FE2 0000 DATA >0000 4FE4 0000 DATA >0000 4FE6 0000 DATA >0000 4FE8 0000 DATA >0000 4FEA 0000 DATA >0000 4FEC 0000 DATA >0000 4FEE 0000 DATA >0000 4FF0 0000 DATA >0000 4FF2 0000 DATA >0000 4FF4 0000 DATA >0000 4FF6 0000 DATA >0000 4FF8 0000 DATA >0000 4FFA 0000 DATA >0000 4FFC 0000 DATA >0000 4FFE E488 DATA >E488 ; checksum