📄 podule.html
字号:
<!doctype html public "-//W3C//DTD HTML 3.2//EN"><html><head><title>APCS</title><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /><meta http-equiv="content-language" content="en" /><meta name="resource-type" content="document"><meta name="copyright" content="This document copyright 2001 by Richard Murray. Use for non-profit and education purposes explicitly granted."><meta name="author" content="Richard Murray"><meta name="rating" content="general"></head><!-- /assembler/podule.html --><!-- --><!-- (C) Copyright 2001 Richard Murray --><!-- Designed by Richard Murray --><!-- rmurray@heyrick.co.uk --><!-- --><body bgcolor="#f0f0f0" text="#000000" link="#0022dd" vlink="#002288"><table border = "0" width="100%"> <tr> <td align=center width=100> <img src="arm3.gif" width=79 height=78 align = middle> </td> <td> <h1 align="center"><font color="#800080">Podule access</font></h1> </td> <td align=center width=100> <img src="arm3.gif" width=79 height=78 align = middle> </td></table><p> <p><h2>Introduction</h2>One of the main reasons for writing in assembler is interfacing with hardware.<p>A complete description is beyond the scope of this article. If you would like details (39 pagesof it, PostScript or DrawFiles), then you will find it at<a href="http://www.mirror.ac.uk/sites/ftp.acorn.co.uk/pub/documents/products/ExpSpec/">theAcorn ftp site mirror</a> <font color = "red" size = "-1">[EXTERNAL LINK]</font>.<br>Oddly, the Acorn ftp site at RISC OS Ltd doesn't appear to have these files.<p> <p><h2>I/O controllers</h2>The I/O controllers reside in the area &3000000 to &3400000. They are mapped in thefollowing way:<pre> Address: %000000110aabbcccaaaaaaaaaddddd00 Where: aa..aa is the device address in the memory map bb is the access type: %00 slow %01 medium %10 fast %11 synchronous ccc is the bank: 0 - IOC control registers 1 - Floppy disc controller (fast) 2 - Econet (sync) 3 - Serial port (sync) 4 - Expansion cards (slow/med/fast/sync) 5 - Harddisc (med) 5 - Printer (fast) 7 - Expansion cards (slow) ddd is an offset in the deviceThus, basically, the I/O memory map looks like: &3310000 Floppy disc controller &33A0000 Econet ADLC &33B0000 Serial port controller &3240000 Internal expansion cards (slow) &32C0000 Internal expansion cards (medium) &3340000 Internal expansion cards (fast) &33C0000 Internal expansion cards (sync) &32D0000 Harddisc interface &3350010 Printer Data &3270000 External expansion cards (slow) <i>THIS IS FOR THE ARCHIMEDES; THINGS ARE DIFFERENT ON THE RISCPC</i></pre><p> <p><h2>Messing with the parallel port</h2>The I/O area is not accessible in USR mode. For an example:<pre>>SYS "Parallel_HardwareAddress" TO addr%>P. ~addr% 30109E0>P. !addr%Internal error: abort on data transfer at &022B1254></pre>As BASIC runs in USR mode, it fails.<br>So we need a little bit of assembler to push us into SVC mode for the read/write.<pre> 10 DIM code% 128 20 P% = code% 30 [ OPT 2 40 SWI "Parallel_HardwareAddress" ; address is in R0 50 SWI "OS_EnterOS" ; go to SVC mode to access hardware! 60 MOV R2, #&FE 70 STRB R2, [R0, #0] ; write &FE to parallel port data register 80 LDRB R0, [R0, #0] ; load R0 with word pointed to by R0 90 TEQP PC, #0 100 MOV R0, R0 110 MOV PC, R14 120 ] 130 PRINT ~USR(code%)</pre>The result of this is <code>FE</code>.<p> <p>You can, from RISC OS, use:<br><code>SYS "Parallel_Op", 0 TO ,, status%</code><br>to read the value of the status bits.<p>With my printer (HP DeskJet 500, CC's TurboDriver cable), the results are:<ul> <li> When online, the status is 216 (not busy, not ack, SLCT, not error). <li> When swiched off, the status is 128 (not busy).</ul><p> <p>The same thing may be performed with direct hardware access:<pre> 10 DIM code% 128 20 P% = code% 30 [ OPT 2 40 SWI "Parallel_HardwareAddress" 50 SWI "OS_EnterOS" 80 LDRB R0, [R0, #4] 90 TEQP PC, #0 100 MOV R0, R0 110 MOV PC, R14 120 ] 130 PRINT USR(code%)</pre>Once you have the address of the parallel port cached, you don't need to look it up again. Soyou can reduce the call to the basics. Indeed, if you include this in SVC code (ie, some form ofdevice driver) you <i>could</i> reduce the call to jusy an LDRB (if the address is preloaded intoa register), instead of calling OS_ParallelOp each time around.<p>Obviously, such hardware poking is frowned upon, but it is sometimes necessary in the quest formaximum speed. D'you think any of the iomega Zip drivers use OS_ParallelOp? :-)<p>This will only work for devices using an ISA mapping. This means the A5000 (82C710), and theRiscPC/A7000 (37C665 see below). I would imagine the RiscStation and Mico, and (when it finallyturns up) the Omega would also all use off-the-shelf ISA combo chips instead of discretehardware.<br>What this does mean, however, is the software that does this <i>may</i> fail on the earlymachines like the A310 and the A3000. I don't have one running to check this. Caveat emptor.<p>For what it is worth, here are the addresses from the 37C665 datasheet:<pre> DATA port Base address + &00 LDRB Rx, [Rx, #0] STATUS port Base address + &01 LDRB Rx, [Rx, #4] CONTROL port Base address + &02 LDRB Rx, [Rx, #8] EPP ADDR port Base address + &03 LDRB Rx, [Rx, #12] EPP DATA port 0 Base address + &04 LDRB Rx, [Rx, #16] EPP DATA port 1 Base address + &05 LDRB Rx, [Rx, #20] EPP DATA port 2 Base address + &06 LDRB Rx, [Rx, #24] EPP DATA port 3 Base address + &07 LDRB Rx, [Rx, #28]</pre>Remember, the bottom two bits are zero, so all addresses are shifted. The LDRB shows this.<pre> PORT D0 D1 D2 D3 D4 D5 D6 D7 DATA ....bits 0-7 of the data to be sent to the printer.... STATUS TMOUT - - |ERR SLCT PE |ACK |BUSY CONTROL STROBE AUTOFD |INIT SLC IRQE PCD - - ERR ADDR PD0 PD1 PD2 PD3 PD5 PD5 PD6 AD7 EPP DATA ...PD0 to PD7 for all EPP DATA ports...</pre><p> <p><h2>Podule allocations</h2>The podules are located from &33C0000, incrementing each 16K, using 4K for each cycle type(slow, medium, fast, synchronous).<br>On a RiscPC, they are allocated slightly differently, but the base four podules are at the sameplaces in memory. The IOMD takes care of the IOC cycle types, and also provides the extendedaddressing space and DMA functions.<pre>SYS "Podule_ReturnNumber" TO podcnt%FOR podule% = 0 TO (podcnt%-1) SYS "XPodule_HardwareAddresses",,,, podule% TO baseaddress% ; err% IF (err% AND 1) THEN PRINT "Podule "+STR$(podule%)+" is empty" ELSE PRINT "Podule "+STR$(podule%)+" base &"+STR$~(baseaddress%) ENDIFNEXT</pre>The program above returns the address used for synchronous access. The podule identity stuff isalways accessed synchronous.<p>You can find out more about podules at the above link, or you can download the older<a href="http://www-stu.cai.cam.ac.uk/~atm26/riscos/docs/PodInfoR1.txt">A-series poduleinformation</a> (more out of date, but it is in text format) <font color = "red" size = "-1">[EXTERNAL LINK]</font>.<p>You might also enjoy a perusal of <a href="http://www.markettos.org.uk">Theo Markettos' website</a> <font color = "red" size = "-1">[EXTERNAL LINK]</font>.<p> <p><h2>HCCS Vision digitiser</h2>We can extend this program to detect a Vision digitiser. I will leave it to you to trace throughthe program.<pre>REM >visioncodeON ERROR PRINT REPORT$+" at "+STR$(ERL/10) : ENDPROCassemblevisionbase% = 0SYS "Podule_ReturnNumber" TO podcnt%FOR podule% = 0 TO (podcnt%-1) SYS "XPodule_HardwareAddresses",,,, podule% TO baseaddress% ; err% IF (err% AND 1) THEN PRINT "Podule "+STR$(podule%)+" not installed" ELSE PRINT "Podule "+STR$(podule%)+" base &"+STR$~(baseaddress%); B% = baseaddress% IF USR(find_podule%) = 1 THEN visionbase% = baseaddress% PRINT "...this is a Vision." ELSE PRINT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -